UNPKG

mdx-m3-viewer

Version:

A browser WebGL model viewer. Mainly focused on models of the games Warcraft 3 and Starcraft 2.

114 lines 4.1 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const binarystream_1 = require("../../common/binarystream"); const MAX_ADPCM_CHANNEL_COUNT = 2; const INITIAL_ADPCM_STEP_INDEX = 0x2C; const NextStepTable = new Int32Array([ -1, 0, -1, 4, -1, 2, -1, 6, -1, 1, -1, 5, -1, 3, -1, 7, -1, 1, -1, 5, -1, 3, -1, 7, -1, 2, -1, 4, -1, 6, -1, 8, ]); const StepSizeTable = new Int32Array([ 7, 8, 9, 10, 11, 12, 13, 14, 16, 17, 19, 21, 23, 25, 28, 31, 34, 37, 41, 45, 50, 55, 60, 66, 73, 80, 88, 97, 107, 118, 130, 143, 157, 173, 190, 209, 230, 253, 279, 307, 337, 371, 408, 449, 494, 544, 598, 658, 724, 796, 876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066, 2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358, 5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899, 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767, ]); function GetNextStepIndex(StepIndex, EncodedSample) { StepIndex = StepIndex + NextStepTable[EncodedSample & 0x1F]; if (StepIndex < 0) { StepIndex = 0; } else if (StepIndex > 88) { StepIndex = 88; } return StepIndex; } function UpdatePredictedSample(PredictedSample, EncodedSample, Difference) { if (EncodedSample & 0x40) { PredictedSample -= Difference; if (PredictedSample <= -32768) { PredictedSample = -32768; } } else { PredictedSample += Difference; if (PredictedSample >= 32767) { PredictedSample = 32767; } } return PredictedSample; } function DecodeSample(PredictedSample, EncodedSample, StepSize, Difference) { if (EncodedSample & 0x01) { Difference += (StepSize >> 0); } if (EncodedSample & 0x02) { Difference += (StepSize >> 1); } if (EncodedSample & 0x04) { Difference += (StepSize >> 2); } if (EncodedSample & 0x08) { Difference += (StepSize >> 3); } if (EncodedSample & 0x10) { Difference += (StepSize >> 4); } if (EncodedSample & 0x20) { Difference += (StepSize >> 5); } return UpdatePredictedSample(PredictedSample, EncodedSample, Difference); } function DecompressADPCM(pvInBuffer, ChannelCount) { const is = new binarystream_1.default(pvInBuffer); const os = []; let EncodedSample; const PredictedSamples = new Uint16Array(MAX_ADPCM_CHANNEL_COUNT); const StepIndexes = new Uint16Array([INITIAL_ADPCM_STEP_INDEX, INITIAL_ADPCM_STEP_INDEX]); let ChannelIndex; is.readUint8(); const BitShift = is.readUint8(); for (let i = 0; i < ChannelCount; i++) { const InitialSample = is.readUint16(); PredictedSamples[i] = InitialSample; os.push(InitialSample); } ChannelIndex = ChannelCount - 1; while (is.remaining) { EncodedSample = is.readUint8(); ChannelIndex = (ChannelIndex + 1) % ChannelCount; if (EncodedSample == 0x80) { if (StepIndexes[ChannelIndex] != 0) { StepIndexes[ChannelIndex]--; } os.push(PredictedSamples[ChannelIndex]); } else if (EncodedSample == 0x81) { StepIndexes[ChannelIndex] += 8; if (StepIndexes[ChannelIndex] > 0x58) { StepIndexes[ChannelIndex] = 0x58; } ChannelIndex = (ChannelIndex + 1) % ChannelCount; } else { const StepIndex = StepIndexes[ChannelIndex]; const StepSize = StepSizeTable[StepIndex]; PredictedSamples[ChannelIndex] = DecodeSample(PredictedSamples[ChannelIndex], EncodedSample, StepSize, StepSize >> BitShift); os.push(PredictedSamples[ChannelIndex]); StepIndexes[ChannelIndex] = GetNextStepIndex(StepIndex, EncodedSample); } } return new Uint8Array(new Uint16Array(os).buffer); } exports.default = DecompressADPCM; //# sourceMappingURL=adpcm.js.map