@grame/faustwasm 0.0.66 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. package/README.md +1 -1
  2. package/assets/standalone/faust-ui/index.css +17 -0
  3. package/assets/standalone/faust-ui/index.css.map +1 -1
  4. package/assets/standalone/faust-ui/index.js +294 -47
  5. package/assets/standalone/faust-ui/index.js.map +1 -1
  6. package/assets/standalone/faustwasm/index.d.ts +149 -6
  7. package/assets/standalone/faustwasm/index.js +449 -73
  8. package/assets/standalone/faustwasm/index.js.map +3 -3
  9. package/assets/standalone/index-poly.js +9 -6
  10. package/assets/standalone/index.js +9 -6
  11. package/dist/cjs/index.d.ts +149 -6
  12. package/dist/cjs/index.js +449 -73
  13. package/dist/cjs/index.js.map +3 -3
  14. package/dist/cjs-bundle/index.d.ts +149 -6
  15. package/dist/cjs-bundle/index.js +550 -174
  16. package/dist/cjs-bundle/index.js.map +3 -3
  17. package/dist/esm/index.d.ts +149 -6
  18. package/dist/esm/index.js +449 -73
  19. package/dist/esm/index.js.map +3 -3
  20. package/dist/esm-bundle/index.d.ts +149 -6
  21. package/dist/esm-bundle/index.js +550 -174
  22. package/dist/esm-bundle/index.js.map +3 -3
  23. package/libfaust-wasm/libfaust-wasm.data +0 -0
  24. package/libfaust-wasm/libfaust-wasm.js +1 -1
  25. package/libfaust-wasm/libfaust-wasm.wasm +0 -0
  26. package/package.json +2 -2
  27. package/src/FaustAudioWorkletProcessor.ts +16 -3
  28. package/src/FaustDspGenerator.ts +18 -3
  29. package/src/FaustWasmInstantiator.ts +62 -26
  30. package/src/FaustWebAudioDsp.ts +682 -51
  31. package/src/faust2wasmFiles.js +6 -4
  32. package/src/types.ts +5 -4
  33. package/test/faustlive-wasm/faust-ui/index.css +17 -0
  34. package/test/faustlive-wasm/faust-ui/index.css.map +1 -1
  35. package/test/faustlive-wasm/faust-ui/index.js +294 -47
  36. package/test/faustlive-wasm/faust-ui/index.js.map +1 -1
  37. package/test/faustlive-wasm/faustwasm/index.d.ts +149 -6
  38. package/test/faustlive-wasm/faustwasm/index.js +449 -73
  39. package/test/faustlive-wasm/faustwasm/index.js.map +3 -3
package/dist/cjs/index.js CHANGED
@@ -1068,6 +1068,10 @@ export default ${(_b = jsCode.match(jsCodeHead)) == null ? void 0 : _b[1]};
1068
1068
  const { factory, sampleSize } = options.processorOptions;
1069
1069
  const instance = FaustWasmInstantiator2.createSyncMonoDSPInstance(factory);
1070
1070
  this.fDSPCode = new FaustMonoWebAudioDsp2(instance, sampleRate, sampleSize, 128);
1071
+ if (this.fDSPCode.hasSoundfiles()) {
1072
+ console.error("FaustAudioWorkletProcessor: Soundfile support is not implemented yet, switch to ScriptProcessorNode for now");
1073
+ return;
1074
+ }
1071
1075
  this.fDSPCode.setOutputParamHandler((path, value) => this.port.postMessage({ path, value, type: "param" }));
1072
1076
  this.fDSPCode.start();
1073
1077
  }
@@ -1093,6 +1097,10 @@ export default ${(_b = jsCode.match(jsCodeHead)) == null ? void 0 : _b[1]};
1093
1097
  const { voiceFactory, mixerModule, voices, effectFactory, sampleSize } = options.processorOptions;
1094
1098
  const instance = FaustWasmInstantiator2.createSyncPolyDSPInstance(voiceFactory, mixerModule, voices, effectFactory);
1095
1099
  this.fDSPCode = new FaustPolyWebAudioDsp3(instance, sampleRate, sampleSize, 128);
1100
+ if (this.fDSPCode.hasSoundfiles()) {
1101
+ console.error("FaustAudioWorkletProcessor: Soundfile support is not implemented yet, switch to ScriptProcessorNode for now");
1102
+ return;
1103
+ }
1096
1104
  this.port.onmessage = (e) => this.handleMessageAux(e);
1097
1105
  this.fDSPCode.setOutputParamHandler((path, value) => this.port.postMessage({ path, value, type: "param" }));
1098
1106
  this.fDSPCode.start();
@@ -1801,7 +1809,7 @@ export default ${(_b = jsCode.match(jsCodeHead)) == null ? void 0 : _b[1]};
1801
1809
  }
1802
1810
  };
1803
1811
  }
1804
- static createWasmMemory(voicesIn, sampleSize, dspMeta, effectMeta, bufferSize) {
1812
+ static createWasmMemoryPoly(voicesIn, sampleSize, dspMeta, effectMeta, bufferSize) {
1805
1813
  const voices = Math.max(4, voicesIn);
1806
1814
  const ptrSize = sampleSize;
1807
1815
  const pow2limit = (x) => {
@@ -1816,19 +1824,29 @@ export default ${(_b = jsCode.match(jsCodeHead)) == null ? void 0 : _b[1]};
1816
1824
  effectSize + dspMeta.size * voices + (dspMeta.inputs + dspMeta.outputs * 2) * (ptrSize + bufferSize * sampleSize)
1817
1825
  ) / 65536;
1818
1826
  memorySize = Math.max(2, memorySize);
1819
- return new WebAssembly.Memory({ initial: memorySize, maximum: memorySize });
1827
+ return new WebAssembly.Memory({ initial: memorySize });
1828
+ }
1829
+ static createWasmMemoryMono(sampleSize, dspMeta, bufferSize) {
1830
+ const ptrSize = sampleSize;
1831
+ const memorySize = (dspMeta.size + (dspMeta.inputs + dspMeta.outputs) * (ptrSize + bufferSize * sampleSize)) / 65536;
1832
+ return new WebAssembly.Memory({ initial: memorySize * 2 });
1820
1833
  }
1821
- static createMonoDSPInstanceAux(instance, json) {
1834
+ static createMonoDSPInstanceAux(instance, json, mem = null) {
1822
1835
  const functions = instance.exports;
1823
1836
  const api = new FaustDspInstance(functions);
1824
- const memory = instance.exports.memory;
1837
+ const memory = mem ? mem : instance.exports.memory;
1825
1838
  return { memory, api, json };
1826
1839
  }
1827
- static createMemoryAux(voices, voiceFactory, effectFactory) {
1840
+ static createMemoryMono(monoFactory) {
1841
+ const monoMeta = JSON.parse(monoFactory.json);
1842
+ const sampleSize = monoMeta.compile_options.match("-double") ? 8 : 4;
1843
+ return this.createWasmMemoryMono(sampleSize, monoMeta, 8192);
1844
+ }
1845
+ static createMemoryPoly(voices, voiceFactory, effectFactory) {
1828
1846
  const voiceMeta = JSON.parse(voiceFactory.json);
1829
1847
  const effectMeta = effectFactory && effectFactory.json ? JSON.parse(effectFactory.json) : null;
1830
1848
  const sampleSize = voiceMeta.compile_options.match("-double") ? 8 : 4;
1831
- return this.createWasmMemory(voices, sampleSize, voiceMeta, effectMeta, 8192);
1849
+ return this.createWasmMemoryPoly(voices, sampleSize, voiceMeta, effectMeta, 8192);
1832
1850
  }
1833
1851
  static createMixerAux(mixerModule, memory) {
1834
1852
  const mixerImport = {
@@ -1872,15 +1890,35 @@ export default ${(_b = jsCode.match(jsCodeHead)) == null ? void 0 : _b[1]};
1872
1890
  }
1873
1891
  }
1874
1892
  static async createAsyncMonoDSPInstance(factory) {
1875
- const instance = await WebAssembly.instantiate(factory.module, this.createWasmImport());
1876
- return this.createMonoDSPInstanceAux(instance, factory.json);
1893
+ const parsedJson = JSON.parse(factory.json);
1894
+ if (Array.isArray(parsedJson.ui) && parsedJson.ui.some((group) => {
1895
+ var _a;
1896
+ return (_a = group.items) == null ? void 0 : _a.some((item) => item.type === "soundfile");
1897
+ })) {
1898
+ const memory = this.createMemoryMono(factory);
1899
+ const instance = await WebAssembly.instantiate(factory.module, this.createWasmImport(memory));
1900
+ return this.createMonoDSPInstanceAux(instance, factory.json, memory);
1901
+ } else {
1902
+ const instance = await WebAssembly.instantiate(factory.module, this.createWasmImport());
1903
+ return this.createMonoDSPInstanceAux(instance, factory.json);
1904
+ }
1877
1905
  }
1878
1906
  static createSyncMonoDSPInstance(factory) {
1879
- const instance = new WebAssembly.Instance(factory.module, this.createWasmImport());
1880
- return this.createMonoDSPInstanceAux(instance, factory.json);
1907
+ const parsedJson = JSON.parse(factory.json);
1908
+ if (Array.isArray(parsedJson.ui) && parsedJson.ui.some((group) => {
1909
+ var _a;
1910
+ return (_a = group.items) == null ? void 0 : _a.some((item) => item.type === "soundfile");
1911
+ })) {
1912
+ const memory = this.createMemoryMono(factory);
1913
+ const instance = new WebAssembly.Instance(factory.module, this.createWasmImport(memory));
1914
+ return this.createMonoDSPInstanceAux(instance, factory.json, memory);
1915
+ } else {
1916
+ const instance = new WebAssembly.Instance(factory.module, this.createWasmImport());
1917
+ return this.createMonoDSPInstanceAux(instance, factory.json);
1918
+ }
1881
1919
  }
1882
1920
  static async createAsyncPolyDSPInstance(voiceFactory, mixerModule, voices, effectFactory) {
1883
- const memory = this.createMemoryAux(voices, voiceFactory, effectFactory);
1921
+ const memory = this.createMemoryPoly(voices, voiceFactory, effectFactory);
1884
1922
  const voiceInstance = await WebAssembly.instantiate(voiceFactory.module, this.createWasmImport(memory));
1885
1923
  const voiceFunctions = voiceInstance.exports;
1886
1924
  const voiceAPI = new FaustDspInstance(voiceFunctions);
@@ -1909,7 +1947,7 @@ export default ${(_b = jsCode.match(jsCodeHead)) == null ? void 0 : _b[1]};
1909
1947
  }
1910
1948
  }
1911
1949
  static createSyncPolyDSPInstance(voiceFactory, mixerModule, voices, effectFactory) {
1912
- const memory = this.createMemoryAux(voices, voiceFactory, effectFactory);
1950
+ const memory = this.createMemoryPoly(voices, voiceFactory, effectFactory);
1913
1951
  const voiceInstance = new WebAssembly.Instance(voiceFactory.module, this.createWasmImport(memory));
1914
1952
  const voiceFunctions = voiceInstance.exports;
1915
1953
  const voiceAPI = new FaustDspInstance(voiceFunctions);
@@ -1941,6 +1979,264 @@ export default ${(_b = jsCode.match(jsCodeHead)) == null ? void 0 : _b[1]};
1941
1979
  var FaustWasmInstantiator_default = FaustWasmInstantiator;
1942
1980
 
1943
1981
  // src/FaustWebAudioDsp.ts
1982
+ var WasmAllocator = class {
1983
+ constructor(memory, offset) {
1984
+ this.memory = memory;
1985
+ this.allocatedBytes = offset;
1986
+ }
1987
+ alloc(sizeInBytes) {
1988
+ const currentOffset = this.allocatedBytes;
1989
+ const newOffset = currentOffset + sizeInBytes;
1990
+ const totalMemoryBytes = this.memory.buffer.byteLength;
1991
+ if (newOffset > totalMemoryBytes) {
1992
+ const neededPages = Math.ceil((newOffset - totalMemoryBytes) / 65536);
1993
+ console.log(`GROW: ${neededPages} pages`);
1994
+ this.memory.grow(neededPages);
1995
+ }
1996
+ this.allocatedBytes = newOffset;
1997
+ return currentOffset;
1998
+ }
1999
+ getBuffer() {
2000
+ return this.memory.buffer;
2001
+ }
2002
+ getInt32Array() {
2003
+ return new Int32Array(this.memory.buffer);
2004
+ }
2005
+ getFloat32Array() {
2006
+ return new Float32Array(this.memory.buffer);
2007
+ }
2008
+ getFloat64Array() {
2009
+ return new Float64Array(this.memory.buffer);
2010
+ }
2011
+ };
2012
+ var MAX_SOUNDFILE_PARTS = 256;
2013
+ var MAX_CHAN = 64;
2014
+ var BUFFER_SIZE = 1024;
2015
+ var SAMPLE_RATE = 44100;
2016
+ var intSize = 4;
2017
+ var Soundfile = class {
2018
+ constructor(allocator, ptrSize, sampleSize, curChan, length2, maxChan, totalParts) {
2019
+ this.fSampleSize = sampleSize;
2020
+ this.fPtrSize = ptrSize;
2021
+ this.fAllocator = allocator;
2022
+ this.fPtr = allocator.alloc(4 * ptrSize);
2023
+ this.fLength = allocator.alloc(MAX_SOUNDFILE_PARTS * intSize);
2024
+ this.fSR = allocator.alloc(MAX_SOUNDFILE_PARTS * intSize);
2025
+ this.fOffset = allocator.alloc(MAX_SOUNDFILE_PARTS * intSize);
2026
+ this.fBuffers = this.allocBuffers(curChan, length2, maxChan);
2027
+ const HEAP32 = this.fAllocator.getInt32Array();
2028
+ HEAP32[this.fPtr >> 2] = this.fBuffers;
2029
+ HEAP32[this.fPtr + ptrSize >> 2] = this.fLength;
2030
+ HEAP32[this.fPtr + 2 * ptrSize >> 2] = this.fSR;
2031
+ HEAP32[this.fPtr + 3 * ptrSize >> 2] = this.fOffset;
2032
+ for (let chan = 0; chan < curChan; chan++) {
2033
+ const buffer = HEAP32[(this.fBuffers >> 2) + chan];
2034
+ console.log(`allocBuffers AFTER: ${chan} - ${buffer}`);
2035
+ }
2036
+ }
2037
+ allocBuffers(curChan, length2, maxChan) {
2038
+ const buffers = this.fAllocator.alloc(maxChan * this.fPtrSize);
2039
+ console.log(`allocBuffers buffers: ${buffers}`);
2040
+ for (let chan = 0; chan < curChan; chan++) {
2041
+ const buffer = this.fAllocator.alloc(length2 * this.fSampleSize);
2042
+ const HEAP32 = this.fAllocator.getInt32Array();
2043
+ HEAP32[(buffers >> 2) + chan] = buffer;
2044
+ }
2045
+ return buffers;
2046
+ }
2047
+ shareBuffers(curChan, maxChan) {
2048
+ const HEAP32 = this.fAllocator.getInt32Array();
2049
+ for (let chan = curChan; chan < maxChan; chan++) {
2050
+ HEAP32[(this.fBuffers >> 2) + chan] = HEAP32[(this.fBuffers >> 2) + chan % curChan];
2051
+ }
2052
+ }
2053
+ copyToOut(part, maxChannels, offset, buffer) {
2054
+ const HEAP32 = this.fAllocator.getInt32Array();
2055
+ HEAP32[(this.fLength >> 2) + part] = buffer.length;
2056
+ HEAP32[(this.fSR >> 2) + part] = buffer.sampleRate;
2057
+ HEAP32[(this.fOffset >> 2) + part] = offset;
2058
+ if (this.fSampleSize === 8) {
2059
+ this.copyToOutReal64(maxChannels, offset, buffer);
2060
+ } else {
2061
+ this.copyToOutReal32(maxChannels, offset, buffer);
2062
+ }
2063
+ }
2064
+ copyToOutReal32(maxChannels, offset, buffer) {
2065
+ const HEAP32 = this.fAllocator.getInt32Array();
2066
+ const HEAPF = this.fAllocator.getFloat32Array();
2067
+ for (let chan = 0; chan < buffer.numberOfChannels; chan++) {
2068
+ const input = buffer.getChannelData(chan);
2069
+ const output = HEAP32[(this.fBuffers >> 2) + chan];
2070
+ const outputReal = HEAPF.subarray(
2071
+ output + offset * this.fSampleSize >> Math.log2(this.fSampleSize),
2072
+ output + (offset + input.length) * this.fSampleSize >> Math.log2(this.fSampleSize)
2073
+ );
2074
+ for (let sample = 0; sample < input.length; sample++) {
2075
+ outputReal[sample] = input[sample];
2076
+ }
2077
+ }
2078
+ }
2079
+ copyToOutReal64(maxChannels, offset, buffer) {
2080
+ const HEAP32 = this.fAllocator.getInt32Array();
2081
+ const HEAPF = this.fAllocator.getFloat64Array();
2082
+ for (let chan = 0; chan < buffer.numberOfChannels; chan++) {
2083
+ const input = buffer.getChannelData(chan);
2084
+ const output = HEAP32[(this.fBuffers >> 2) + chan];
2085
+ const outputReal = HEAPF.subarray(
2086
+ output + offset * this.fSampleSize >> Math.log2(this.fSampleSize),
2087
+ output + (offset + input.length) * this.fSampleSize >> Math.log2(this.fSampleSize)
2088
+ );
2089
+ for (let sample = 0; sample < input.length; sample++) {
2090
+ outputReal[sample] = input[sample];
2091
+ }
2092
+ }
2093
+ }
2094
+ emptyFile(part, offset) {
2095
+ const HEAP32 = this.fAllocator.getInt32Array();
2096
+ HEAP32[(this.fLength >> 2) + part] = BUFFER_SIZE;
2097
+ HEAP32[(this.fSR >> 2) + part] = SAMPLE_RATE;
2098
+ HEAP32[(this.fOffset >> 2) + part] = offset;
2099
+ return offset + BUFFER_SIZE;
2100
+ }
2101
+ displayMemory(where = "", mem = false) {
2102
+ console.log("Soundfile memory: " + where);
2103
+ console.log(`fPtr: ${this.fPtr}`);
2104
+ console.log(`fBuffers: ${this.fBuffers}`);
2105
+ console.log(`fLength: ${this.fLength}`);
2106
+ console.log(`fSR: ${this.fSR}`);
2107
+ console.log(`fOffset: ${this.fOffset}`);
2108
+ const HEAP32 = this.fAllocator.getInt32Array();
2109
+ if (mem)
2110
+ console.log(`HEAP32: ${HEAP32}`);
2111
+ console.log(`HEAP32[this.fPtr >> 2]: ${HEAP32[this.fPtr >> 2]}`);
2112
+ console.log(`HEAP32[(this.fPtr + ptrSize) >> 2]: ${HEAP32[this.fPtr + this.fPtrSize >> 2]}`);
2113
+ console.log(`HEAP32[(this.fPtr + 2 * ptrSize) >> 2]: ${HEAP32[this.fPtr + 2 * this.fPtrSize >> 2]}`);
2114
+ console.log(`HEAP32[(this.fPtr + 3 * ptrSize) >> 2]: ${HEAP32[this.fPtr + 3 * this.fPtrSize >> 2]}`);
2115
+ }
2116
+ getPtr() {
2117
+ return this.fPtr;
2118
+ }
2119
+ getHEAP32() {
2120
+ return this.fAllocator.getInt32Array();
2121
+ }
2122
+ getHEAPFloat32() {
2123
+ return this.fAllocator.getFloat32Array();
2124
+ }
2125
+ getHEAPFloat64() {
2126
+ return this.fAllocator.getFloat64Array();
2127
+ }
2128
+ };
2129
+ var SoundfileReader = class {
2130
+ constructor(allocator, context, ptrSize, sampleSize) {
2131
+ this.fAllocator = allocator;
2132
+ this.fPtrSize = ptrSize;
2133
+ this.fSampleSize = sampleSize;
2134
+ this.fContext = context;
2135
+ this.fAudioBuffers = [];
2136
+ }
2137
+ async checkFile(directories, fileName) {
2138
+ async function checkFileExists(url) {
2139
+ try {
2140
+ console.log(`"checkFileExists" url: ${url}`);
2141
+ const response = await fetch(url, { method: "HEAD" });
2142
+ return response.ok;
2143
+ } catch (error) {
2144
+ console.error("Fetch error:", error);
2145
+ return false;
2146
+ }
2147
+ }
2148
+ if (await checkFileExists(fileName)) {
2149
+ return fileName;
2150
+ } else {
2151
+ for (let i = 0; i < directories.length; i++) {
2152
+ const pathName = directories[i] + "/" + fileName;
2153
+ if (await checkFileExists(pathName)) {
2154
+ return pathName;
2155
+ }
2156
+ }
2157
+ return "";
2158
+ }
2159
+ }
2160
+ async checkFiles(directories, fileNameList) {
2161
+ const pathNameList = [];
2162
+ for (let i = 0; i < fileNameList.length; i++) {
2163
+ const pathName = await this.checkFile(directories, fileNameList[i]);
2164
+ console.log(`checkFiles pathName: ${pathName}`);
2165
+ pathNameList.push(pathName === "" ? "__empty_sound__" : pathName);
2166
+ }
2167
+ return pathNameList;
2168
+ }
2169
+ async getParamsFile(pathName) {
2170
+ console.log(`Loading sound file from ${pathName}`);
2171
+ const item = this.fAudioBuffers.find((element) => element.pathName === pathName);
2172
+ if (item) {
2173
+ console.log(`getItemByPathName FOUND`);
2174
+ return { channels: item.audioBuffer.numberOfChannels, length: item.audioBuffer.length };
2175
+ } else {
2176
+ const response = await fetch(pathName);
2177
+ if (!response.ok) {
2178
+ console.log(`Failed to load sound file from ${pathName}: ${response.statusText}`);
2179
+ return { channels: 1, length: BUFFER_SIZE };
2180
+ } else {
2181
+ const arrayBuffer = await response.arrayBuffer();
2182
+ const audioBuffer = await this.fContext.decodeAudioData(arrayBuffer);
2183
+ const { numberOfChannels, length: length2 } = audioBuffer;
2184
+ this.fAudioBuffers.push({ pathName, audioBuffer });
2185
+ return { channels: numberOfChannels, length: length2 };
2186
+ }
2187
+ }
2188
+ }
2189
+ readFile(soundfile, pathName, part, offset, maxChan) {
2190
+ const item = this.fAudioBuffers.find((entry) => entry.pathName === pathName);
2191
+ if (item) {
2192
+ soundfile.copyToOut(part, maxChan, offset, item.audioBuffer);
2193
+ return offset + item.audioBuffer.length;
2194
+ } else {
2195
+ console.error(`Failed to access sound file from ${pathName}`);
2196
+ return offset + BUFFER_SIZE;
2197
+ }
2198
+ }
2199
+ async createSoundfile(pathNameList, maxChan, isDouble) {
2200
+ try {
2201
+ let curChan = 1;
2202
+ let totalLength = 0;
2203
+ for (const pathName of pathNameList) {
2204
+ let chan = 0, len = 0;
2205
+ if (pathName === "__empty_sound__") {
2206
+ length = BUFFER_SIZE;
2207
+ chan = 1;
2208
+ } else {
2209
+ const { channels, length: length2 } = await this.getParamsFile(pathName);
2210
+ chan = channels;
2211
+ len = length2;
2212
+ }
2213
+ curChan = Math.max(curChan, chan);
2214
+ totalLength += len;
2215
+ }
2216
+ totalLength += (MAX_SOUNDFILE_PARTS - pathNameList.length) * BUFFER_SIZE;
2217
+ let soundfile = new Soundfile(this.fAllocator, this.fPtrSize, this.fSampleSize, curChan, totalLength, maxChan, pathNameList.length);
2218
+ let offset = 0;
2219
+ for (let part = 0; part < pathNameList.length; part++) {
2220
+ if (pathNameList[part] === "__empty_sound__") {
2221
+ offset = soundfile.emptyFile(part, offset);
2222
+ } else {
2223
+ offset = await this.readFile(soundfile, pathNameList[part], part, offset, maxChan);
2224
+ }
2225
+ }
2226
+ for (let part = pathNameList.length; part < MAX_SOUNDFILE_PARTS; part++) {
2227
+ offset = soundfile.emptyFile(part, offset);
2228
+ }
2229
+ soundfile.shareBuffers(curChan, maxChan);
2230
+ return soundfile;
2231
+ } catch (error) {
2232
+ console.error("Failed to create soundfile:", error);
2233
+ return null;
2234
+ }
2235
+ }
2236
+ getHEAP32() {
2237
+ return this.fAllocator.getInt32Array();
2238
+ }
2239
+ };
1944
2240
  var FaustBaseWebAudioDsp = class {
1945
2241
  constructor(sampleSize, bufferSize) {
1946
2242
  this.fOutputHandler = null;
@@ -1951,17 +2247,19 @@ export default ${(_b = jsCode.match(jsCodeHead)) == null ? void 0 : _b[1]};
1951
2247
  this.fBufferSize = bufferSize;
1952
2248
  this.fInChannels = [];
1953
2249
  this.fOutChannels = [];
1954
- this.gPtrSize = sampleSize;
1955
- this.gSampleSize = sampleSize;
2250
+ this.fPtrSize = sampleSize;
2251
+ this.fSampleSize = sampleSize;
1956
2252
  this.fOutputsTimer = 5;
1957
2253
  this.fInputsItems = [];
1958
2254
  this.fOutputsItems = [];
1959
2255
  this.fDescriptor = [];
2256
+ this.fSoundfiles = [];
1960
2257
  this.fPitchwheelLabel = [];
1961
2258
  this.fCtrlLabel = new Array(128).fill(null).map(() => []);
1962
2259
  this.fPathTable = {};
1963
2260
  this.fProcessing = false;
1964
2261
  this.fDestroyed = false;
2262
+ this.fFirstCall = true;
1965
2263
  this.fUICallback = (item) => {
1966
2264
  if (item.type === "hbargraph" || item.type === "vbargraph") {
1967
2265
  this.fOutputsItems.push(item.address);
@@ -1986,6 +2284,8 @@ export default ${(_b = jsCode.match(jsCodeHead)) == null ? void 0 : _b[1]};
1986
2284
  this.fCtrlLabel[parseInt(matched[1])].push({ path: item.address, min: item.min, max: item.max });
1987
2285
  }
1988
2286
  });
2287
+ } else if (item.type === "soundfile") {
2288
+ this.fSoundfiles.push({ name: item.label, url: item.url, basePtr: -1 });
1989
2289
  }
1990
2290
  };
1991
2291
  }
@@ -2010,6 +2310,46 @@ export default ${(_b = jsCode.match(jsCodeHead)) == null ? void 0 : _b[1]};
2010
2310
  callback(item);
2011
2311
  }
2012
2312
  }
2313
+ static splitNames(input) {
2314
+ let trimmed = input.replace(/^\{|\}$/g, "");
2315
+ return trimmed.split(";").map((str) => str.length <= 2 ? "" : str.substring(1, str.length - 1));
2316
+ }
2317
+ async loadSoundfile(sfReader, sfOffset, name, url) {
2318
+ console.log(`Soundfile ${name} paths: ${url}`);
2319
+ const sfDirectories = ["", ".", "http://127.0.0.1:8000"];
2320
+ console.log(`sfDirectories ${sfDirectories}`);
2321
+ const sfPathNames = await sfReader.checkFiles(sfDirectories, FaustBaseWebAudioDsp.splitNames(url));
2322
+ console.log(`Soundfile ${name} paths: ${sfPathNames}`);
2323
+ const item = this.fSoundfiles.find((element) => element.url === url);
2324
+ if (item) {
2325
+ if (item.basePtr !== -1) {
2326
+ const HEAP32 = sfReader.getHEAP32();
2327
+ console.log(`Soundfile ${name} loaded at ${item.basePtr} in wasm memory with sfOffset ${sfOffset}`);
2328
+ console.log(`Soundfile CACHE ${url}}`);
2329
+ HEAP32[sfOffset >> 2] = item.basePtr;
2330
+ } else {
2331
+ const soundfile = await sfReader.createSoundfile(sfPathNames, MAX_CHAN, this.fSampleSize === 8);
2332
+ if (soundfile) {
2333
+ const HEAP32 = soundfile.getHEAP32();
2334
+ item.basePtr = soundfile.getPtr();
2335
+ console.log(`Soundfile ${name} loaded at ${item.basePtr} in wasm memory with sfOffset ${sfOffset}`);
2336
+ HEAP32[sfOffset >> 2] = item.basePtr;
2337
+ } else {
2338
+ console.log(`Soundfile ${name} for ${url} cannot be created !}`);
2339
+ }
2340
+ }
2341
+ } else {
2342
+ console.log(`Soundfile with ${url} cannot be found !}`);
2343
+ }
2344
+ }
2345
+ async initSoundfileMemory(allocator, sfReader, baseDSP) {
2346
+ let sfOffset = baseDSP;
2347
+ for (const { name, url } of this.fSoundfiles) {
2348
+ await this.loadSoundfile(sfReader, sfOffset, name, url);
2349
+ sfOffset += this.fPtrSize;
2350
+ }
2351
+ ;
2352
+ }
2013
2353
  updateOutputs() {
2014
2354
  if (this.fOutputsItems.length > 0 && this.fOutputHandler && this.fOutputsTimer-- === 0) {
2015
2355
  this.fOutputsTimer = 5;
@@ -2104,6 +2444,9 @@ export default ${(_b = jsCode.match(jsCodeHead)) == null ? void 0 : _b[1]};
2104
2444
  getDescriptors() {
2105
2445
  return this.fDescriptor;
2106
2446
  }
2447
+ hasSoundfiles() {
2448
+ return this.fSoundfiles.length > 0;
2449
+ }
2107
2450
  start() {
2108
2451
  this.fProcessing = true;
2109
2452
  }
@@ -2123,51 +2466,64 @@ export default ${(_b = jsCode.match(jsCodeHead)) == null ? void 0 : _b[1]};
2123
2466
  this.fInstance = instance;
2124
2467
  this.fJSONDsp = JSON.parse(this.fInstance.json);
2125
2468
  FaustBaseWebAudioDsp.parseUI(this.fJSONDsp.ui, this.fUICallback);
2126
- this.initMemory();
2469
+ this.fEndMemory = this.initMemory();
2127
2470
  this.fInstance.api.init(this.fDSP, sampleRate);
2128
2471
  }
2472
+ async init(context) {
2473
+ if (this.fSoundfiles.length > 0 && context) {
2474
+ const allocator = new WasmAllocator(this.fInstance.memory, this.fEndMemory);
2475
+ const sfReader = new SoundfileReader(allocator, context, this.fPtrSize, this.fSampleSize);
2476
+ await this.initSoundfileMemory(allocator, sfReader, this.fDSP);
2477
+ }
2478
+ }
2129
2479
  initMemory() {
2130
2480
  this.fDSP = 0;
2131
2481
  const $audio = this.fJSONDsp.size;
2132
2482
  this.fAudioInputs = $audio;
2133
- this.fAudioOutputs = this.fAudioInputs + this.getNumInputs() * this.gPtrSize;
2134
- const $audioInputs = this.fAudioOutputs + this.getNumOutputs() * this.gPtrSize;
2135
- const $audioOutputs = $audioInputs + this.getNumInputs() * this.fBufferSize * this.gSampleSize;
2483
+ this.fAudioOutputs = this.fAudioInputs + this.getNumInputs() * this.fPtrSize;
2484
+ const $audioInputs = this.fAudioOutputs + this.getNumOutputs() * this.fPtrSize;
2485
+ const $audioOutputs = $audioInputs + this.getNumInputs() * this.fBufferSize * this.fSampleSize;
2486
+ const endMemory = $audioOutputs + this.getNumOutputs() * this.fBufferSize * this.fSampleSize;
2136
2487
  const HEAP = this.fInstance.memory.buffer;
2137
2488
  const HEAP32 = new Int32Array(HEAP);
2138
- const HEAPF = this.gSampleSize === 4 ? new Float32Array(HEAP) : new Float64Array(HEAP);
2489
+ const HEAPF = this.fSampleSize === 4 ? new Float32Array(HEAP) : new Float64Array(HEAP);
2139
2490
  if (this.getNumInputs() > 0) {
2140
2491
  for (let chan = 0; chan < this.getNumInputs(); chan++) {
2141
- HEAP32[(this.fAudioInputs >> 2) + chan] = $audioInputs + this.fBufferSize * this.gSampleSize * chan;
2492
+ HEAP32[(this.fAudioInputs >> 2) + chan] = $audioInputs + this.fBufferSize * this.fSampleSize * chan;
2142
2493
  }
2143
- const dspInChans = HEAP32.subarray(this.fAudioInputs >> 2, this.fAudioInputs + this.getNumInputs() * this.gPtrSize >> 2);
2494
+ const dspInChans = HEAP32.subarray(this.fAudioInputs >> 2, this.fAudioInputs + this.getNumInputs() * this.fPtrSize >> 2);
2144
2495
  for (let chan = 0; chan < this.getNumInputs(); chan++) {
2145
- this.fInChannels[chan] = HEAPF.subarray(dspInChans[chan] >> Math.log2(this.gSampleSize), dspInChans[chan] + this.fBufferSize * this.gSampleSize >> Math.log2(this.gSampleSize));
2496
+ this.fInChannels[chan] = HEAPF.subarray(dspInChans[chan] >> Math.log2(this.fSampleSize), dspInChans[chan] + this.fBufferSize * this.fSampleSize >> Math.log2(this.fSampleSize));
2146
2497
  }
2147
2498
  }
2148
2499
  if (this.getNumOutputs() > 0) {
2149
2500
  for (let chan = 0; chan < this.getNumOutputs(); chan++) {
2150
- HEAP32[(this.fAudioOutputs >> 2) + chan] = $audioOutputs + this.fBufferSize * this.gSampleSize * chan;
2501
+ HEAP32[(this.fAudioOutputs >> 2) + chan] = $audioOutputs + this.fBufferSize * this.fSampleSize * chan;
2151
2502
  }
2152
- const dspOutChans = HEAP32.subarray(this.fAudioOutputs >> 2, this.fAudioOutputs + this.getNumOutputs() * this.gPtrSize >> 2);
2503
+ const dspOutChans = HEAP32.subarray(this.fAudioOutputs >> 2, this.fAudioOutputs + this.getNumOutputs() * this.fPtrSize >> 2);
2153
2504
  for (let chan = 0; chan < this.getNumOutputs(); chan++) {
2154
- this.fOutChannels[chan] = HEAPF.subarray(dspOutChans[chan] >> Math.log2(this.gSampleSize), dspOutChans[chan] + this.fBufferSize * this.gSampleSize >> Math.log2(this.gSampleSize));
2505
+ this.fOutChannels[chan] = HEAPF.subarray(dspOutChans[chan] >> Math.log2(this.fSampleSize), dspOutChans[chan] + this.fBufferSize * this.fSampleSize >> Math.log2(this.fSampleSize));
2155
2506
  }
2156
2507
  }
2508
+ return endMemory;
2157
2509
  }
2158
2510
  toString() {
2159
2511
  return `============== Mono Memory layout ==============
2160
- this.fBufferSize: ${this.fBufferSize}
2161
- this.fJSONDsp.size: ${this.fJSONDsp.size}
2162
- this.fAudioInputs: ${this.fAudioInputs}
2163
- this.fAudioOutputs: ${this.fAudioOutputs}
2164
- this.fDSP: ${this.fDSP}`;
2512
+ this.fBufferSize: ${this.fBufferSize}
2513
+ this.fJSONDsp.size: ${this.fJSONDsp.size}
2514
+ this.fAudioInputs: ${this.fAudioInputs}
2515
+ this.fAudioOutputs: ${this.fAudioOutputs}
2516
+ this.fDSP: ${this.fDSP}`;
2165
2517
  }
2166
2518
  compute(input, output) {
2167
2519
  if (this.fDestroyed)
2168
2520
  return false;
2169
2521
  if (!this.fProcessing)
2170
2522
  return true;
2523
+ if (this.fFirstCall) {
2524
+ this.initMemory();
2525
+ this.fFirstCall = false;
2526
+ }
2171
2527
  if (typeof input === "function") {
2172
2528
  input(this.fInChannels);
2173
2529
  } else {
@@ -2325,7 +2681,7 @@ this.fDSP: ${this.fDSP}`;
2325
2681
  FaustBaseWebAudioDsp.parseUI(this.fJSONDsp.ui, this.fUICallback);
2326
2682
  if (this.fJSONEffect)
2327
2683
  FaustBaseWebAudioDsp.parseUI(this.fJSONEffect.ui, this.fUICallback);
2328
- this.initMemory();
2684
+ this.fEndMemory = this.initMemory();
2329
2685
  this.fVoiceTable = [];
2330
2686
  for (let voice = 0; voice < this.fInstance.voices; voice++) {
2331
2687
  this.fVoiceTable.push(new FaustWebAudioDspVoice(
@@ -2339,48 +2695,59 @@ this.fDSP: ${this.fDSP}`;
2339
2695
  if (this.fInstance.effectAPI)
2340
2696
  this.fInstance.effectAPI.init(this.fEffect, sampleRate);
2341
2697
  }
2698
+ async init(context) {
2699
+ if (this.fSoundfiles.length > 0 && context) {
2700
+ const allocator = new WasmAllocator(this.fInstance.memory, this.fEndMemory);
2701
+ const sfReader = new SoundfileReader(allocator, context, this.fPtrSize, this.fSampleSize);
2702
+ for (let voice = 0; voice < this.fInstance.voices; voice++) {
2703
+ await this.initSoundfileMemory(allocator, sfReader, this.fJSONDsp.size * voice);
2704
+ }
2705
+ }
2706
+ }
2342
2707
  initMemory() {
2343
2708
  this.fEffect = this.fJSONDsp.size * this.fInstance.voices;
2344
2709
  const $audio = this.fEffect + (this.fJSONEffect ? this.fJSONEffect.size : 0);
2345
2710
  this.fAudioInputs = $audio;
2346
- this.fAudioOutputs = this.fAudioInputs + this.getNumInputs() * this.gPtrSize;
2347
- this.fAudioMixing = this.fAudioOutputs + this.getNumOutputs() * this.gPtrSize;
2348
- this.fAudioMixingHalf = this.fAudioMixing + this.getNumOutputs() * this.gPtrSize;
2349
- const $audioInputs = this.fAudioMixingHalf + this.getNumOutputs() * this.gPtrSize;
2350
- const $audioOutputs = $audioInputs + this.getNumInputs() * this.fBufferSize * this.gSampleSize;
2351
- const $audioMixing = $audioOutputs + this.getNumOutputs() * this.fBufferSize * this.gSampleSize;
2711
+ this.fAudioOutputs = this.fAudioInputs + this.getNumInputs() * this.fPtrSize;
2712
+ this.fAudioMixing = this.fAudioOutputs + this.getNumOutputs() * this.fPtrSize;
2713
+ this.fAudioMixingHalf = this.fAudioMixing + this.getNumOutputs() * this.fPtrSize;
2714
+ const $audioInputs = this.fAudioMixingHalf + this.getNumOutputs() * this.fPtrSize;
2715
+ const $audioOutputs = $audioInputs + this.getNumInputs() * this.fBufferSize * this.fSampleSize;
2716
+ const $audioMixing = $audioOutputs + this.getNumOutputs() * this.fBufferSize * this.fSampleSize;
2717
+ const endMemory = $audioMixing + this.getNumOutputs() * this.fBufferSize * this.fSampleSize;
2352
2718
  const HEAP = this.fInstance.memory.buffer;
2353
2719
  const HEAP32 = new Int32Array(HEAP);
2354
- const HEAPF = this.gSampleSize === 4 ? new Float32Array(HEAP) : new Float64Array(HEAP);
2720
+ const HEAPF = this.fSampleSize === 4 ? new Float32Array(HEAP) : new Float64Array(HEAP);
2355
2721
  if (this.getNumInputs() > 0) {
2356
2722
  for (let chan = 0; chan < this.getNumInputs(); chan++) {
2357
- HEAP32[(this.fAudioInputs >> 2) + chan] = $audioInputs + this.fBufferSize * this.gSampleSize * chan;
2723
+ HEAP32[(this.fAudioInputs >> 2) + chan] = $audioInputs + this.fBufferSize * this.fSampleSize * chan;
2358
2724
  }
2359
- const dspInChans = HEAP32.subarray(this.fAudioInputs >> 2, this.fAudioInputs + this.getNumInputs() * this.gPtrSize >> 2);
2725
+ const dspInChans = HEAP32.subarray(this.fAudioInputs >> 2, this.fAudioInputs + this.getNumInputs() * this.fPtrSize >> 2);
2360
2726
  for (let chan = 0; chan < this.getNumInputs(); chan++) {
2361
- this.fInChannels[chan] = HEAPF.subarray(dspInChans[chan] >> Math.log2(this.gSampleSize), dspInChans[chan] + this.fBufferSize * this.gSampleSize >> Math.log2(this.gSampleSize));
2727
+ this.fInChannels[chan] = HEAPF.subarray(dspInChans[chan] >> Math.log2(this.fSampleSize), dspInChans[chan] + this.fBufferSize * this.fSampleSize >> Math.log2(this.fSampleSize));
2362
2728
  }
2363
2729
  }
2364
2730
  if (this.getNumOutputs() > 0) {
2365
2731
  for (let chan = 0; chan < this.getNumOutputs(); chan++) {
2366
- HEAP32[(this.fAudioOutputs >> 2) + chan] = $audioOutputs + this.fBufferSize * this.gSampleSize * chan;
2367
- HEAP32[(this.fAudioMixing >> 2) + chan] = $audioMixing + this.fBufferSize * this.gSampleSize * chan;
2368
- HEAP32[(this.fAudioMixingHalf >> 2) + chan] = $audioMixing + this.fBufferSize * this.gSampleSize * chan + this.fBufferSize / 2 * this.gSampleSize;
2732
+ HEAP32[(this.fAudioOutputs >> 2) + chan] = $audioOutputs + this.fBufferSize * this.fSampleSize * chan;
2733
+ HEAP32[(this.fAudioMixing >> 2) + chan] = $audioMixing + this.fBufferSize * this.fSampleSize * chan;
2734
+ HEAP32[(this.fAudioMixingHalf >> 2) + chan] = $audioMixing + this.fBufferSize * this.fSampleSize * chan + this.fBufferSize / 2 * this.fSampleSize;
2369
2735
  }
2370
- const dspOutChans = HEAP32.subarray(this.fAudioOutputs >> 2, this.fAudioOutputs + this.getNumOutputs() * this.gPtrSize >> 2);
2736
+ const dspOutChans = HEAP32.subarray(this.fAudioOutputs >> 2, this.fAudioOutputs + this.getNumOutputs() * this.fPtrSize >> 2);
2371
2737
  for (let chan = 0; chan < this.getNumOutputs(); chan++) {
2372
- this.fOutChannels[chan] = HEAPF.subarray(dspOutChans[chan] >> Math.log2(this.gSampleSize), dspOutChans[chan] + this.fBufferSize * this.gSampleSize >> Math.log2(this.gSampleSize));
2738
+ this.fOutChannels[chan] = HEAPF.subarray(dspOutChans[chan] >> Math.log2(this.fSampleSize), dspOutChans[chan] + this.fBufferSize * this.fSampleSize >> Math.log2(this.fSampleSize));
2373
2739
  }
2374
2740
  }
2741
+ return endMemory;
2375
2742
  }
2376
2743
  toString() {
2377
2744
  return `============== Poly Memory layout ==============
2378
- this.fBufferSize: ${this.fBufferSize}
2379
- this.fJSONDsp.size: ${this.fJSONDsp.size}
2380
- this.fAudioInputs: ${this.fAudioInputs}
2381
- this.fAudioOutputs: ${this.fAudioOutputs}
2382
- this.fAudioMixing: ${this.fAudioMixing}
2383
- this.fAudioMixingHalf: ${this.fAudioMixingHalf}`;
2745
+ this.fBufferSize: ${this.fBufferSize}
2746
+ this.fJSONDsp.size: ${this.fJSONDsp.size}
2747
+ this.fAudioInputs: ${this.fAudioInputs}
2748
+ this.fAudioOutputs: ${this.fAudioOutputs}
2749
+ this.fAudioMixing: ${this.fAudioMixing}
2750
+ this.fAudioMixingHalf: ${this.fAudioMixingHalf}`;
2384
2751
  }
2385
2752
  allocVoice(voice, type) {
2386
2753
  this.fVoiceTable[voice].fDate++;
@@ -2434,6 +2801,10 @@ this.fAudioMixingHalf: ${this.fAudioMixingHalf}`;
2434
2801
  compute(input, output) {
2435
2802
  if (this.fDestroyed)
2436
2803
  return false;
2804
+ if (this.fFirstCall) {
2805
+ this.initMemory();
2806
+ this.fFirstCall = false;
2807
+ }
2437
2808
  if (!this.fProcessing)
2438
2809
  return true;
2439
2810
  if (this.getNumInputs() > 0 && (!input || !input[0] || input[0].length === 0)) {
@@ -2684,12 +3055,12 @@ this.fAudioMixingHalf: ${this.fAudioMixingHalf}`;
2684
3055
  destroy() {
2685
3056
  this.fDSPCode.destroy();
2686
3057
  }
2687
- render(inputs = [], length = this.fBufferSize, onUpdate) {
3058
+ render(inputs = [], length2 = this.fBufferSize, onUpdate) {
2688
3059
  let l = 0;
2689
- const outputs = new Array(this.fDSPCode.getNumOutputs()).fill(null).map(() => new Float32Array(length));
3060
+ const outputs = new Array(this.fDSPCode.getNumOutputs()).fill(null).map(() => new Float32Array(length2));
2690
3061
  this.fDSPCode.start();
2691
- while (l < length) {
2692
- const sliceLength = Math.min(length - l, this.fBufferSize);
3062
+ while (l < length2) {
3063
+ const sliceLength = Math.min(length2 - l, this.fBufferSize);
2693
3064
  for (let i = 0; i < this.fDSPCode.getNumInputs(); i++) {
2694
3065
  let input;
2695
3066
  if (inputs[i]) {
@@ -2822,11 +3193,11 @@ this.fAudioMixingHalf: ${this.fAudioMixingHalf}`;
2822
3193
  var WavEncoder = class {
2823
3194
  static encode(audioBuffer, options) {
2824
3195
  const numberOfChannels = audioBuffer.length;
2825
- const length = audioBuffer[0].length;
3196
+ const length2 = audioBuffer[0].length;
2826
3197
  const { shared, float } = options;
2827
3198
  const bitDepth = float ? 32 : options.bitDepth | 0 || 16;
2828
3199
  const byteDepth = bitDepth >> 3;
2829
- const byteLength = length * numberOfChannels * byteDepth;
3200
+ const byteLength = length2 * numberOfChannels * byteDepth;
2830
3201
  const AB = shared ? globalThis.SharedArrayBuffer || globalThis.ArrayBuffer : globalThis.ArrayBuffer;
2831
3202
  const ab = new AB((44 + byteLength) * Uint8Array.BYTES_PER_ELEMENT);
2832
3203
  const dataView = new DataView(ab);
@@ -2837,7 +3208,7 @@ this.fAudioMixingHalf: ${this.fAudioMixingHalf}`;
2837
3208
  numberOfChannels,
2838
3209
  sampleRate: options.sampleRate,
2839
3210
  symmetric: !!options.symmetric,
2840
- length,
3211
+ length: length2,
2841
3212
  bitDepth,
2842
3213
  byteDepth
2843
3214
  };
@@ -2846,7 +3217,7 @@ this.fAudioMixingHalf: ${this.fAudioMixingHalf}`;
2846
3217
  return ab;
2847
3218
  }
2848
3219
  static writeHeader(writer, format) {
2849
- const { formatId, sampleRate, bitDepth, numberOfChannels, length, byteDepth } = format;
3220
+ const { formatId, sampleRate, bitDepth, numberOfChannels, length: length2, byteDepth } = format;
2850
3221
  writer.string("RIFF");
2851
3222
  writer.uint32(writer.dataView.byteLength - 8);
2852
3223
  writer.string("WAVE");
@@ -2859,11 +3230,11 @@ this.fAudioMixingHalf: ${this.fAudioMixingHalf}`;
2859
3230
  writer.uint16(numberOfChannels * byteDepth);
2860
3231
  writer.uint16(bitDepth);
2861
3232
  writer.string("data");
2862
- writer.uint32(length * numberOfChannels * byteDepth);
3233
+ writer.uint32(length2 * numberOfChannels * byteDepth);
2863
3234
  return writer.pos;
2864
3235
  }
2865
3236
  static writeData(writer, audioBuffer, format) {
2866
- const { bitDepth, float, length, numberOfChannels, symmetric } = format;
3237
+ const { bitDepth, float, length: length2, numberOfChannels, symmetric } = format;
2867
3238
  if (bitDepth === 32 && float) {
2868
3239
  const { dataView, pos } = writer;
2869
3240
  const ab = dataView.buffer;
@@ -2874,7 +3245,7 @@ this.fAudioMixingHalf: ${this.fAudioMixingHalf}`;
2874
3245
  }
2875
3246
  for (let ch = 0; ch < numberOfChannels; ch++) {
2876
3247
  const channel = audioBuffer[ch];
2877
- for (let i = 0; i < length; i++) {
3248
+ for (let i = 0; i < length2; i++) {
2878
3249
  f32View[i * numberOfChannels + ch] = channel[i];
2879
3250
  }
2880
3251
  }
@@ -2886,7 +3257,7 @@ this.fAudioMixingHalf: ${this.fAudioMixingHalf}`;
2886
3257
  throw new TypeError("Not supported bit depth: " + bitDepth);
2887
3258
  }
2888
3259
  const write = writer[methodName].bind(writer);
2889
- for (let i = 0; i < length; i++) {
3260
+ for (let i = 0; i < length2; i++) {
2890
3261
  for (let j = 0; j < numberOfChannels; j++) {
2891
3262
  write(audioBuffer[j][i]);
2892
3263
  }
@@ -3042,24 +3413,24 @@ this.fAudioMixingHalf: ${this.fAudioMixingHalf}`;
3042
3413
  }
3043
3414
  static decodeData(reader, chunkSizeIn, format, options) {
3044
3415
  const chunkSize = Math.min(chunkSizeIn, reader.remain());
3045
- const length = Math.floor(chunkSize / format.blockSize);
3416
+ const length2 = Math.floor(chunkSize / format.blockSize);
3046
3417
  const numberOfChannels = format.numberOfChannels;
3047
3418
  const sampleRate = format.sampleRate;
3048
3419
  const channelData = new Array(numberOfChannels);
3049
3420
  for (let ch = 0; ch < numberOfChannels; ch++) {
3050
3421
  const AB = options.shared ? globalThis.SharedArrayBuffer || globalThis.ArrayBuffer : globalThis.ArrayBuffer;
3051
- const ab = new AB(length * Float32Array.BYTES_PER_ELEMENT);
3422
+ const ab = new AB(length2 * Float32Array.BYTES_PER_ELEMENT);
3052
3423
  channelData[ch] = new Float32Array(ab);
3053
3424
  }
3054
- this.readPCM(reader, channelData, length, format, options);
3425
+ this.readPCM(reader, channelData, length2, format, options);
3055
3426
  return {
3056
3427
  numberOfChannels,
3057
- length,
3428
+ length: length2,
3058
3429
  sampleRate,
3059
3430
  channelData
3060
3431
  };
3061
3432
  }
3062
- static readPCM(reader, channelData, length, format, options) {
3433
+ static readPCM(reader, channelData, length2, format, options) {
3063
3434
  const bitDepth = format.bitDepth;
3064
3435
  const decoderOption = format.float ? "f" : options.symmetric ? "s" : "";
3065
3436
  const methodName = "pcm" + bitDepth + decoderOption;
@@ -3068,7 +3439,7 @@ this.fAudioMixingHalf: ${this.fAudioMixingHalf}`;
3068
3439
  }
3069
3440
  const read = reader[methodName].bind(reader);
3070
3441
  const numberOfChannels = format.numberOfChannels;
3071
- for (let i = 0; i < length; i++) {
3442
+ for (let i = 0; i < length2; i++) {
3072
3443
  for (let ch = 0; ch < numberOfChannels; ch++) {
3073
3444
  channelData[ch][i] = read();
3074
3445
  }
@@ -3487,10 +3858,12 @@ this.fAudioMixingHalf: ${this.fAudioMixingHalf}`;
3487
3858
  }
3488
3859
  async compile(compiler, name, code, args) {
3489
3860
  this.factory = await compiler.createMonoDSPFactory(name, code, args);
3490
- if (!this.factory)
3861
+ if (this.factory) {
3862
+ this.name = name;
3863
+ return this;
3864
+ } else {
3491
3865
  return null;
3492
- this.name = name;
3493
- return this;
3866
+ }
3494
3867
  }
3495
3868
  async createNode(context, name = this.name, factory = this.factory, sp = false, bufferSize = 1024, processorName = (factory == null ? void 0 : factory.shaKey) || name) {
3496
3869
  var _a, _b;
@@ -3501,6 +3874,7 @@ this.fAudioMixingHalf: ${this.fAudioMixingHalf}`;
3501
3874
  if (sp) {
3502
3875
  const instance = await FaustWasmInstantiator_default.createAsyncMonoDSPInstance(factory);
3503
3876
  const monoDsp = new FaustMonoWebAudioDsp(instance, context.sampleRate, sampleSize, bufferSize);
3877
+ await monoDsp.init(context);
3504
3878
  const sp2 = context.createScriptProcessor(bufferSize, monoDsp.getNumInputs(), monoDsp.getNumOutputs());
3505
3879
  Object.setPrototypeOf(sp2, FaustMonoScriptProcessorNode.prototype);
3506
3880
  sp2.init(monoDsp);
@@ -3638,6 +4012,7 @@ const dependencies = {
3638
4012
  const instance = await FaustWasmInstantiator_default.createAsyncMonoDSPInstance(factory);
3639
4013
  const sampleSize = meta.compile_options.match("-double") ? 8 : 4;
3640
4014
  const monoDsp = new FaustMonoWebAudioDsp(instance, sampleRate, sampleSize, bufferSize);
4015
+ await monoDsp.init(null);
3641
4016
  return new FaustMonoOfflineProcessor(monoDsp, bufferSize);
3642
4017
  }
3643
4018
  getMeta() {
@@ -3735,6 +4110,7 @@ const dependencies = {
3735
4110
  if (sp) {
3736
4111
  const instance = await FaustWasmInstantiator_default.createAsyncPolyDSPInstance(voiceFactory, mixerModule, voices, effectFactory || void 0);
3737
4112
  const polyDsp = new FaustPolyWebAudioDsp(instance, context.sampleRate, sampleSize, bufferSize);
4113
+ await polyDsp.init(context);
3738
4114
  const sp2 = context.createScriptProcessor(bufferSize, polyDsp.getNumInputs(), polyDsp.getNumOutputs());
3739
4115
  Object.setPrototypeOf(sp2, FaustPolyScriptProcessorNode.prototype);
3740
4116
  sp2.init(polyDsp);