scratch0-5 / plugins /ADPCMCodecPlugin.js
soiz1's picture
Upload folder using huggingface_hub
8f3f8db verified
/* Smalltalk from Squeak4.5 with VMMaker 4.13.6 translated as JS source on 3 November 2014 1:52:20 pm */
/* Automatically generated by
JSPluginCodeGenerator VMMakerJS-bf.15 uuid: fd4e10f2-3773-4e80-8bb5-c4b471a014e5
from
ADPCMCodecPlugin VMMaker-bf.353 uuid: 8ae25e7e-8d2c-451e-8277-598b30e9c002
*/
(function ADPCMCodecPlugin() {
"use strict";
var VM_PROXY_MAJOR = 1;
var VM_PROXY_MINOR = 11;
/*** Functions ***/
function CLASSOF(obj) { return typeof obj === "number" ? interpreterProxy.classSmallInteger() : obj.sqClass }
function SIZEOF(obj) { return obj.pointers ? obj.pointers.length : obj.words ? obj.words.length : obj.bytes ? obj.bytes.length : 0 }
function BYTESIZEOF(obj) { return obj.bytes ? obj.bytes.length : obj.words ? obj.words.length * 4 : 0 }
function DIV(a, b) { return Math.floor(a / b) | 0; } // integer division
function MOD(a, b) { return a - DIV(a, b) * b | 0; } // signed modulus
function SHL(a, b) { return b > 31 ? 0 : a << b; } // fix JS shift
function SHR(a, b) { return b > 31 ? 0 : a >>> b; } // fix JS shift
function SHIFT(a, b) { return b < 0 ? (b < -31 ? 0 : a >>> (0-b) ) : (b > 31 ? 0 : a << b); }
/*** Variables ***/
var bitPosition = 0;
var byteIndex = 0;
var currentByte = 0;
var encodedBytes = null;
var interpreterProxy = null;
var moduleName = "ADPCMCodecPlugin 3 November 2014 (e)";
var stepSizeTable = null;
/* Note: This is coded so that plugins can be run from Squeak. */
function getInterpreter() {
return interpreterProxy;
}
/* Note: This is hardcoded so it can be run from Squeak.
The module name is used for validating a module *after*
it is loaded to check if it does really contain the module
we're thinking it contains. This is important! */
function getModuleName() {
return moduleName;
}
function halt() {
;
}
/* Answer the best index to use for the difference between the given samples. */
/* Details: Scan stepSizeTable for the first entry >= the absolute value of the difference between sample values. Since indexes are zero-based, the index used during decoding will be the one in the following stepSizeTable entry. Since the index field of a Flash frame header is only six bits, the maximum index value is 63. */
/* Note: Since there does not appear to be any documentation of how Flash actually computes the indices used in its frame headers, this algorithm was guessed by reverse-engineering the Flash ADPCM decoder. */
function indexForDeltaFromto(thisSample, nextSample) {
var bestIndex;
var diff;
var j;
diff = nextSample - thisSample;
if (diff < 0) {
diff = 0 - diff;
}
bestIndex = 63;
for (j = 1; j <= 62; j++) {
if (bestIndex === 63) {
if (stepSizeTable[j - 1] >= diff) {
bestIndex = j;
}
}
}
return bestIndex;
}
function msg(s) {
console.log(moduleName + ": " + s);
}
/* Answer the next n bits of my bit stream as an unsigned integer. */
function nextBits(n) {
var remaining;
var result;
var shift;
result = 0;
remaining = n;
while(true) {
shift = remaining - bitPosition;
if (shift > 0) {
/* consumed currentByte buffer; fetch next byte */
result += SHL(currentByte, shift);
remaining -= bitPosition;
currentByte = encodedBytes[((++byteIndex)) - 1];
bitPosition = 8;
} else {
/* still some bits left in currentByte buffer */
result += SHR(currentByte, (0 - shift));
/* mask out the consumed bits: */
bitPosition -= remaining;
currentByte = currentByte & (SHR(255, (8 - bitPosition)));
return result;
}
}
}
/* Write the next n bits to my bit stream. */
function nextBitsput(n, anInteger) {
var bitsAvailable;
var buf;
var bufBits;
var shift;
buf = anInteger;
bufBits = n;
while(true) {
bitsAvailable = 8 - bitPosition;
/* either left or right shift */
/* append high bits of buf to end of currentByte: */
shift = bitsAvailable - bufBits;
if (shift < 0) {
/* currentByte buffer filled; output it */
currentByte += SHR(buf, (0 - shift));
encodedBytes[((++byteIndex)) - 1] = currentByte;
bitPosition = 0;
/* clear saved high bits of buf: */
currentByte = 0;
buf = buf & ((SHL(1, (0 - shift))) - 1);
bufBits -= bitsAvailable;
} else {
/* still some bits available in currentByte buffer */
currentByte += SHL(buf, shift);
bitPosition += bufBits;
return self;
}
}
}
function primitiveDecodeMono() {
var rcvr;
var count;
var bit;
var delta;
var i;
var predictedDelta;
var step;
var bitsPerSample;
var deltaSignMask;
var deltaValueHighBit;
var deltaValueMask;
var frameSizeMask;
var index;
var indexTable;
var predicted;
var sampleIndex;
var samples;
rcvr = interpreterProxy.stackValue(1);
count = interpreterProxy.stackIntegerValue(0);
predicted = interpreterProxy.fetchIntegerofObject(0, rcvr);
index = interpreterProxy.fetchIntegerofObject(1, rcvr);
deltaSignMask = interpreterProxy.fetchIntegerofObject(2, rcvr);
deltaValueMask = interpreterProxy.fetchIntegerofObject(3, rcvr);
deltaValueHighBit = interpreterProxy.fetchIntegerofObject(4, rcvr);
frameSizeMask = interpreterProxy.fetchIntegerofObject(5, rcvr);
currentByte = interpreterProxy.fetchIntegerofObject(6, rcvr);
bitPosition = interpreterProxy.fetchIntegerofObject(7, rcvr);
byteIndex = interpreterProxy.fetchIntegerofObject(8, rcvr);
encodedBytes = interpreterProxy.fetchBytesofObject(9, rcvr);
samples = interpreterProxy.fetchInt16ArrayofObject(10, rcvr);
sampleIndex = interpreterProxy.fetchIntegerofObject(12, rcvr);
bitsPerSample = interpreterProxy.fetchIntegerofObject(13, rcvr);
stepSizeTable = interpreterProxy.fetchInt16ArrayofObject(14, rcvr);
indexTable = interpreterProxy.fetchInt16ArrayofObject(15, rcvr);
if (interpreterProxy.failed()) {
return null;
}
for (i = 1; i <= count; i++) {
if ((i & frameSizeMask) === 1) {
/* start of frame; read frame header */
predicted = nextBits(16);
if (predicted > 32767) {
predicted -= 65536;
}
index = nextBits(6);
samples[((++sampleIndex)) - 1] = predicted;
} else {
delta = nextBits(bitsPerSample);
step = stepSizeTable[index];
predictedDelta = 0;
bit = deltaValueHighBit;
while (bit > 0) {
if ((delta & bit) > 0) {
predictedDelta += step;
}
step = step >>> 1;
bit = bit >>> 1;
}
predictedDelta += step;
if ((delta & deltaSignMask) > 0) {
predicted -= predictedDelta;
} else {
predicted += predictedDelta;
}
if (predicted > 32767) {
predicted = 32767;
} else {
if (predicted < -32768) {
predicted = -32768;
}
}
index += indexTable[delta & deltaValueMask];
if (index < 0) {
index = 0;
} else {
if (index > 88) {
index = 88;
}
}
samples[((++sampleIndex)) - 1] = predicted;
}
}
if (interpreterProxy.failed()) {
return null;
}
interpreterProxy.storeIntegerofObjectwithValue(0, rcvr, predicted);
interpreterProxy.storeIntegerofObjectwithValue(1, rcvr, index);
interpreterProxy.storeIntegerofObjectwithValue(6, rcvr, currentByte);
interpreterProxy.storeIntegerofObjectwithValue(7, rcvr, bitPosition);
interpreterProxy.storeIntegerofObjectwithValue(8, rcvr, byteIndex);
interpreterProxy.storeIntegerofObjectwithValue(12, rcvr, sampleIndex);
interpreterProxy.pop(1);
}
function primitiveDecodeStereo() {
var rcvr;
var count;
var bit;
var deltaLeft;
var deltaRight;
var i;
var indexLeft;
var indexRight;
var predictedDeltaLeft;
var predictedDeltaRight;
var predictedLeft;
var predictedRight;
var stepLeft;
var stepRight;
var bitsPerSample;
var deltaSignMask;
var deltaValueHighBit;
var deltaValueMask;
var frameSizeMask;
var index;
var indexTable;
var predicted;
var rightSamples;
var sampleIndex;
var samples;
/* make local copies of decoder state variables */
rcvr = interpreterProxy.stackValue(1);
count = interpreterProxy.stackIntegerValue(0);
predicted = interpreterProxy.fetchInt16ArrayofObject(0, rcvr);
index = interpreterProxy.fetchInt16ArrayofObject(1, rcvr);
deltaSignMask = interpreterProxy.fetchIntegerofObject(2, rcvr);
deltaValueMask = interpreterProxy.fetchIntegerofObject(3, rcvr);
deltaValueHighBit = interpreterProxy.fetchIntegerofObject(4, rcvr);
frameSizeMask = interpreterProxy.fetchIntegerofObject(5, rcvr);
currentByte = interpreterProxy.fetchIntegerofObject(6, rcvr);
bitPosition = interpreterProxy.fetchIntegerofObject(7, rcvr);
byteIndex = interpreterProxy.fetchIntegerofObject(8, rcvr);
encodedBytes = interpreterProxy.fetchBytesofObject(9, rcvr);
samples = interpreterProxy.fetchInt16ArrayofObject(10, rcvr);
rightSamples = interpreterProxy.fetchInt16ArrayofObject(11, rcvr);
sampleIndex = interpreterProxy.fetchIntegerofObject(12, rcvr);
bitsPerSample = interpreterProxy.fetchIntegerofObject(13, rcvr);
stepSizeTable = interpreterProxy.fetchInt16ArrayofObject(14, rcvr);
indexTable = interpreterProxy.fetchInt16ArrayofObject(15, rcvr);
if (interpreterProxy.failed()) {
return null;
}
predictedLeft = predicted[1 - 1];
predictedRight = predicted[2 - 1];
indexLeft = index[1 - 1];
indexRight = index[2 - 1];
for (i = 1; i <= count; i++) {
if ((i & frameSizeMask) === 1) {
/* start of frame; read frame header */
predictedLeft = nextBits(16);
indexLeft = nextBits(6);
predictedRight = nextBits(16);
indexRight = nextBits(6);
if (predictedLeft > 32767) {
predictedLeft -= 65536;
}
if (predictedRight > 32767) {
predictedRight -= 65536;
}
samples[((++sampleIndex)) - 1] = predictedLeft;
rightSamples[sampleIndex - 1] = predictedRight;
} else {
deltaLeft = nextBits(bitsPerSample);
deltaRight = nextBits(bitsPerSample);
stepLeft = stepSizeTable[indexLeft];
stepRight = stepSizeTable[indexRight];
predictedDeltaLeft = (predictedDeltaRight = 0);
bit = deltaValueHighBit;
while (bit > 0) {
if ((deltaLeft & bit) > 0) {
predictedDeltaLeft += stepLeft;
}
if ((deltaRight & bit) > 0) {
predictedDeltaRight += stepRight;
}
stepLeft = stepLeft >>> 1;
stepRight = stepRight >>> 1;
bit = bit >>> 1;
}
predictedDeltaLeft += stepLeft;
predictedDeltaRight += stepRight;
if ((deltaLeft & deltaSignMask) > 0) {
predictedLeft -= predictedDeltaLeft;
} else {
predictedLeft += predictedDeltaLeft;
}
if ((deltaRight & deltaSignMask) > 0) {
predictedRight -= predictedDeltaRight;
} else {
predictedRight += predictedDeltaRight;
}
if (predictedLeft > 32767) {
predictedLeft = 32767;
} else {
if (predictedLeft < -32768) {
predictedLeft = -32768;
}
}
if (predictedRight > 32767) {
predictedRight = 32767;
} else {
if (predictedRight < -32768) {
predictedRight = -32768;
}
}
indexLeft += indexTable[deltaLeft & deltaValueMask];
if (indexLeft < 0) {
indexLeft = 0;
} else {
if (indexLeft > 88) {
indexLeft = 88;
}
}
indexRight += indexTable[deltaRight & deltaValueMask];
if (indexRight < 0) {
indexRight = 0;
} else {
if (indexRight > 88) {
indexRight = 88;
}
}
samples[((++sampleIndex)) - 1] = predictedLeft;
rightSamples[sampleIndex - 1] = predictedRight;
}
}
predicted[1 - 1] = predictedLeft;
predicted[2 - 1] = predictedRight;
index[1 - 1] = indexLeft;
index[2 - 1] = indexRight;
if (interpreterProxy.failed()) {
return null;
}
interpreterProxy.storeIntegerofObjectwithValue(6, rcvr, currentByte);
interpreterProxy.storeIntegerofObjectwithValue(7, rcvr, bitPosition);
interpreterProxy.storeIntegerofObjectwithValue(8, rcvr, byteIndex);
interpreterProxy.storeIntegerofObjectwithValue(12, rcvr, sampleIndex);
interpreterProxy.pop(1);
}
function primitiveEncodeMono() {
var rcvr;
var count;
var bit;
var delta;
var diff;
var i;
var p;
var predictedDelta;
var sign;
var step;
var bitsPerSample;
var deltaSignMask;
var deltaValueHighBit;
var frameSizeMask;
var index;
var indexTable;
var predicted;
var sampleIndex;
var samples;
rcvr = interpreterProxy.stackValue(1);
count = interpreterProxy.stackIntegerValue(0);
predicted = interpreterProxy.fetchIntegerofObject(0, rcvr);
index = interpreterProxy.fetchIntegerofObject(1, rcvr);
deltaSignMask = interpreterProxy.fetchIntegerofObject(2, rcvr);
deltaValueHighBit = interpreterProxy.fetchIntegerofObject(4, rcvr);
frameSizeMask = interpreterProxy.fetchIntegerofObject(5, rcvr);
currentByte = interpreterProxy.fetchIntegerofObject(6, rcvr);
bitPosition = interpreterProxy.fetchIntegerofObject(7, rcvr);
byteIndex = interpreterProxy.fetchIntegerofObject(8, rcvr);
encodedBytes = interpreterProxy.fetchBytesofObject(9, rcvr);
samples = interpreterProxy.fetchInt16ArrayofObject(10, rcvr);
sampleIndex = interpreterProxy.fetchIntegerofObject(12, rcvr);
bitsPerSample = interpreterProxy.fetchIntegerofObject(13, rcvr);
stepSizeTable = interpreterProxy.fetchInt16ArrayofObject(14, rcvr);
indexTable = interpreterProxy.fetchInt16ArrayofObject(15, rcvr);
if (interpreterProxy.failed()) {
return null;
}
step = stepSizeTable[1 - 1];
for (i = 1; i <= count; i++) {
if ((i & frameSizeMask) === 1) {
predicted = samples[((++sampleIndex)) - 1];
if (((p = predicted)) < 0) {
p += 65536;
}
nextBitsput(16, p);
if (i < count) {
index = indexForDeltaFromto(predicted, samples[sampleIndex]);
}
nextBitsput(6, index);
} else {
/* compute sign and magnitude of difference from the predicted sample */
sign = 0;
diff = samples[((++sampleIndex)) - 1] - predicted;
if (diff < 0) {
sign = deltaSignMask;
diff = 0 - diff;
}
delta = 0;
predictedDelta = 0;
bit = deltaValueHighBit;
while (bit > 0) {
if (diff >= step) {
delta += bit;
predictedDelta += step;
diff -= step;
}
step = step >>> 1;
bit = bit >>> 1;
}
/* compute and clamp new prediction */
predictedDelta += step;
if (sign > 0) {
predicted -= predictedDelta;
} else {
predicted += predictedDelta;
}
if (predicted > 32767) {
predicted = 32767;
} else {
if (predicted < -32768) {
predicted = -32768;
}
}
index += indexTable[delta];
if (index < 0) {
index = 0;
} else {
if (index > 88) {
index = 88;
}
}
/* output encoded, signed delta */
step = stepSizeTable[index];
nextBitsput(bitsPerSample, sign | delta);
}
}
if (bitPosition > 0) {
/* flush the last output byte, if necessary */
encodedBytes[((++byteIndex)) - 1] = currentByte;
}
if (interpreterProxy.failed()) {
return null;
}
interpreterProxy.storeIntegerofObjectwithValue(0, rcvr, predicted);
interpreterProxy.storeIntegerofObjectwithValue(1, rcvr, index);
interpreterProxy.storeIntegerofObjectwithValue(6, rcvr, currentByte);
interpreterProxy.storeIntegerofObjectwithValue(7, rcvr, bitPosition);
interpreterProxy.storeIntegerofObjectwithValue(8, rcvr, byteIndex);
interpreterProxy.storeIntegerofObjectwithValue(12, rcvr, sampleIndex);
interpreterProxy.pop(1);
}
/* not yet implemented */
function primitiveEncodeStereo() {
var rcvr;
var count;
rcvr = interpreterProxy.stackValue(1);
count = interpreterProxy.stackIntegerValue(0);
currentByte = interpreterProxy.fetchIntegerofObject(6, rcvr);
bitPosition = interpreterProxy.fetchIntegerofObject(7, rcvr);
byteIndex = interpreterProxy.fetchIntegerofObject(8, rcvr);
encodedBytes = interpreterProxy.fetchIntegerofObject(9, rcvr);
stepSizeTable = interpreterProxy.fetchIntegerofObject(14, rcvr);
if (interpreterProxy.failed()) {
return null;
}
success(false);
if (interpreterProxy.failed()) {
return null;
}
interpreterProxy.storeIntegerofObjectwithValue(6, rcvr, currentByte);
interpreterProxy.storeIntegerofObjectwithValue(7, rcvr, bitPosition);
interpreterProxy.storeIntegerofObjectwithValue(8, rcvr, byteIndex);
interpreterProxy.pop(1);
}
/* Note: This is coded so that is can be run from Squeak. */
function setInterpreter(anInterpreter) {
var ok;
interpreterProxy = anInterpreter;
ok = interpreterProxy.majorVersion() == VM_PROXY_MAJOR;
if (ok === false) {
return false;
}
ok = interpreterProxy.minorVersion() >= VM_PROXY_MINOR;
return ok;
}
function registerPlugin() {
if (typeof Squeak === "object" && Squeak.registerExternalModule) {
Squeak.registerExternalModule("ADPCMCodecPlugin", {
primitiveDecodeStereo: primitiveDecodeStereo,
primitiveEncodeStereo: primitiveEncodeStereo,
setInterpreter: setInterpreter,
primitiveEncodeMono: primitiveEncodeMono,
primitiveDecodeMono: primitiveDecodeMono,
getModuleName: getModuleName,
});
} else self.setTimeout(registerPlugin, 100);
}
registerPlugin();
})(); // Register module/plugin