scratch0-5 / plugins /FFTPlugin.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
FFTPlugin VMMaker-bf.353 uuid: 8ae25e7e-8d2c-451e-8277-598b30e9c002
*/
(function FFTPlugin() {
"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 fftSize = 0;
var imagData = null;
var imagDataSize = 0;
var interpreterProxy = null;
var moduleName = "FFTPlugin 3 November 2014 (e)";
var nu = 0;
var permTable = null;
var permTableSize = 0;
var realData = null;
var realDataSize = 0;
var sinTable = null;
var sinTableSize = 0;
/* Return the first indexable word of oop which is assumed to be variableWordSubclass */
function checkedFloatPtrOf(oop) {
interpreterProxy.success(interpreterProxy.isWords(oop));
if (interpreterProxy.failed()) {
return 0;
}
return oop.wordsAsFloat32Array();
}
/* Return the first indexable word of oop which is assumed to be variableWordSubclass */
function checkedWordPtrOf(oop) {
interpreterProxy.success(interpreterProxy.isWords(oop));
return oop.words;
}
/* 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() {
;
}
function loadFFTFrom(fftOop) {
var oop;
interpreterProxy.success(SIZEOF(fftOop) >= 6);
if (interpreterProxy.failed()) {
return false;
}
nu = interpreterProxy.fetchIntegerofObject(0, fftOop);
fftSize = interpreterProxy.fetchIntegerofObject(1, fftOop);
oop = interpreterProxy.fetchPointerofObject(2, fftOop);
sinTableSize = SIZEOF(oop);
sinTable = checkedFloatPtrOf(oop);
oop = interpreterProxy.fetchPointerofObject(3, fftOop);
permTableSize = SIZEOF(oop);
permTable = checkedWordPtrOf(oop);
oop = interpreterProxy.fetchPointerofObject(4, fftOop);
realDataSize = SIZEOF(oop);
realData = checkedFloatPtrOf(oop);
oop = interpreterProxy.fetchPointerofObject(5, fftOop);
imagDataSize = SIZEOF(oop);
/* Check assumptions about sizes */
imagData = checkedFloatPtrOf(oop);
interpreterProxy.success((((((SHL(1, nu)) === fftSize) && (((fftSize >> 2) + 1) === sinTableSize)) && (fftSize === realDataSize)) && (fftSize === imagDataSize)) && (realDataSize === imagDataSize));
return interpreterProxy.failed() === false;
}
function permuteData() {
var a;
var b;
var end;
var i;
var tmp;
i = 0;
end = permTableSize;
while (i < end) {
a = permTable[i] - 1;
b = permTable[i + 1] - 1;
if (!((a < realDataSize) && (b < realDataSize))) {
return interpreterProxy.success(false);
}
tmp = realData[a];
realData[a] = realData[b];
realData[b] = tmp;
tmp = imagData[a];
imagData[a] = imagData[b];
imagData[b] = tmp;
i += 2;
}
}
function primitiveFFTPermuteData() {
var rcvr;
rcvr = interpreterProxy.stackObjectValue(0);
if (!loadFFTFrom(rcvr)) {
return null;
}
permuteData();
if (interpreterProxy.failed()) {
/* permuteData went wrong. Do the permutation again -- this will restore the original order */
permuteData();
}
}
function primitiveFFTScaleData() {
var rcvr;
rcvr = interpreterProxy.stackObjectValue(0);
if (!loadFFTFrom(rcvr)) {
return null;
}
scaleData();
}
function primitiveFFTTransformData() {
var forward;
var rcvr;
forward = interpreterProxy.booleanValueOf(interpreterProxy.stackValue(0));
rcvr = interpreterProxy.stackObjectValue(1);
if (!loadFFTFrom(rcvr)) {
return null;
}
transformData(forward);
if (!interpreterProxy.failed()) {
interpreterProxy.pop(1);
}
}
/* Scale all elements by 1/n when doing inverse */
function scaleData() {
var i;
var realN;
if (fftSize <= 1) {
return null;
}
realN = (1.0 / fftSize);
for (i = 0; i <= (fftSize - 1); i++) {
realData[i] = (realData[i] * realN);
imagData[i] = (imagData[i] * realN);
}
}
/* 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 transformData(forward) {
permuteData();
if (interpreterProxy.failed()) {
/* permuteData went wrong. Do the permutation again -- this will restore the original order */
permuteData();
return null;
}
transformForward(forward);
if (!forward) {
scaleData();
}
}
function transformForward(forward) {
var fftScale;
var fftSize2;
var fftSize4;
var i;
var ii;
var imagT;
var imagU;
var ip;
var j;
var lev;
var lev1;
var level;
var realT;
var realU;
var theta;
fftSize2 = fftSize >> 1;
fftSize4 = fftSize >> 2;
for (level = 1; level <= nu; level++) {
lev = SHL(1, level);
lev1 = lev >> 1;
fftScale = DIV(fftSize, lev);
for (j = 1; j <= lev1; j++) {
/* pi * (j-1) / lev1 mapped onto 0..n/2 */
theta = (j - 1) * fftScale;
if (theta < fftSize4) {
/* Compute U, the complex multiplier for each level */
realU = sinTable[(sinTableSize - theta) - 1];
imagU = sinTable[theta];
} else {
realU = 0.0 - sinTable[theta - fftSize4];
imagU = sinTable[fftSize2 - theta];
}
if (!forward) {
imagU = 0.0 - imagU;
}
i = j;
while (i <= fftSize) {
ip = (i + lev1) - 1;
ii = i - 1;
realT = (realData[ip] * realU) - (imagData[ip] * imagU);
imagT = (realData[ip] * imagU) + (imagData[ip] * realU);
realData[ip] = (realData[ii] - realT);
imagData[ip] = (imagData[ii] - imagT);
realData[ii] = (realData[ii] + realT);
imagData[ii] = (imagData[ii] + imagT);
i += lev;
}
}
}
}
function registerPlugin() {
if (typeof Squeak === "object" && Squeak.registerExternalModule) {
Squeak.registerExternalModule("FFTPlugin", {
primitiveFFTTransformData: primitiveFFTTransformData,
setInterpreter: setInterpreter,
primitiveFFTPermuteData: primitiveFFTPermuteData,
primitiveFFTScaleData: primitiveFFTScaleData,
getModuleName: getModuleName,
});
} else self.setTimeout(registerPlugin, 100);
}
registerPlugin();
})(); // Register module/plugin