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
JavaScript
;
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