/* 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