@grame/faustwasm 0.0.67 → 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 (42) 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 +145 -4
  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 +145 -4
  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 +145 -4
  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 +145 -4
  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 +145 -4
  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/test/faustlive-wasm/faust-ui/index.css +17 -0
  33. package/test/faustlive-wasm/faust-ui/index.css.map +1 -1
  34. package/test/faustlive-wasm/faust-ui/index.js +294 -47
  35. package/test/faustlive-wasm/faust-ui/index.js.map +1 -1
  36. package/test/faustlive-wasm/faustwasm/index.d.ts +145 -4
  37. package/test/faustlive-wasm/faustwasm/index.js +449 -73
  38. package/test/faustlive-wasm/faustwasm/index.js.map +3 -3
  39. package/TODO.md +0 -5
  40. package/test/tp0.dsp +0 -17
  41. package/test/tp0.dsp.json +0 -30
  42. package/test/tp0_local.dsp +0 -5
@@ -1060,6 +1060,10 @@ var getFaustAudioWorkletProcessor = (dependencies, faustData, register = true) =
1060
1060
  const { factory, sampleSize } = options.processorOptions;
1061
1061
  const instance = FaustWasmInstantiator2.createSyncMonoDSPInstance(factory);
1062
1062
  this.fDSPCode = new FaustMonoWebAudioDsp2(instance, sampleRate, sampleSize, 128);
1063
+ if (this.fDSPCode.hasSoundfiles()) {
1064
+ console.error("FaustAudioWorkletProcessor: Soundfile support is not implemented yet, switch to ScriptProcessorNode for now");
1065
+ return;
1066
+ }
1063
1067
  this.fDSPCode.setOutputParamHandler((path, value) => this.port.postMessage({ path, value, type: "param" }));
1064
1068
  this.fDSPCode.start();
1065
1069
  }
@@ -1085,6 +1089,10 @@ var getFaustAudioWorkletProcessor = (dependencies, faustData, register = true) =
1085
1089
  const { voiceFactory, mixerModule, voices, effectFactory, sampleSize } = options.processorOptions;
1086
1090
  const instance = FaustWasmInstantiator2.createSyncPolyDSPInstance(voiceFactory, mixerModule, voices, effectFactory);
1087
1091
  this.fDSPCode = new FaustPolyWebAudioDsp3(instance, sampleRate, sampleSize, 128);
1092
+ if (this.fDSPCode.hasSoundfiles()) {
1093
+ console.error("FaustAudioWorkletProcessor: Soundfile support is not implemented yet, switch to ScriptProcessorNode for now");
1094
+ return;
1095
+ }
1088
1096
  this.port.onmessage = (e) => this.handleMessageAux(e);
1089
1097
  this.fDSPCode.setOutputParamHandler((path, value) => this.port.postMessage({ path, value, type: "param" }));
1090
1098
  this.fDSPCode.start();
@@ -1793,7 +1801,7 @@ var FaustWasmInstantiator = class {
1793
1801
  }
1794
1802
  };
1795
1803
  }
1796
- static createWasmMemory(voicesIn, sampleSize, dspMeta, effectMeta, bufferSize) {
1804
+ static createWasmMemoryPoly(voicesIn, sampleSize, dspMeta, effectMeta, bufferSize) {
1797
1805
  const voices = Math.max(4, voicesIn);
1798
1806
  const ptrSize = sampleSize;
1799
1807
  const pow2limit = (x) => {
@@ -1808,19 +1816,29 @@ var FaustWasmInstantiator = class {
1808
1816
  effectSize + dspMeta.size * voices + (dspMeta.inputs + dspMeta.outputs * 2) * (ptrSize + bufferSize * sampleSize)
1809
1817
  ) / 65536;
1810
1818
  memorySize = Math.max(2, memorySize);
1811
- return new WebAssembly.Memory({ initial: memorySize, maximum: memorySize });
1819
+ return new WebAssembly.Memory({ initial: memorySize });
1820
+ }
1821
+ static createWasmMemoryMono(sampleSize, dspMeta, bufferSize) {
1822
+ const ptrSize = sampleSize;
1823
+ const memorySize = (dspMeta.size + (dspMeta.inputs + dspMeta.outputs) * (ptrSize + bufferSize * sampleSize)) / 65536;
1824
+ return new WebAssembly.Memory({ initial: memorySize * 2 });
1812
1825
  }
1813
- static createMonoDSPInstanceAux(instance, json) {
1826
+ static createMonoDSPInstanceAux(instance, json, mem = null) {
1814
1827
  const functions = instance.exports;
1815
1828
  const api = new FaustDspInstance(functions);
1816
- const memory = instance.exports.memory;
1829
+ const memory = mem ? mem : instance.exports.memory;
1817
1830
  return { memory, api, json };
1818
1831
  }
1819
- static createMemoryAux(voices, voiceFactory, effectFactory) {
1832
+ static createMemoryMono(monoFactory) {
1833
+ const monoMeta = JSON.parse(monoFactory.json);
1834
+ const sampleSize = monoMeta.compile_options.match("-double") ? 8 : 4;
1835
+ return this.createWasmMemoryMono(sampleSize, monoMeta, 8192);
1836
+ }
1837
+ static createMemoryPoly(voices, voiceFactory, effectFactory) {
1820
1838
  const voiceMeta = JSON.parse(voiceFactory.json);
1821
1839
  const effectMeta = effectFactory && effectFactory.json ? JSON.parse(effectFactory.json) : null;
1822
1840
  const sampleSize = voiceMeta.compile_options.match("-double") ? 8 : 4;
1823
- return this.createWasmMemory(voices, sampleSize, voiceMeta, effectMeta, 8192);
1841
+ return this.createWasmMemoryPoly(voices, sampleSize, voiceMeta, effectMeta, 8192);
1824
1842
  }
1825
1843
  static createMixerAux(mixerModule, memory) {
1826
1844
  const mixerImport = {
@@ -1864,15 +1882,35 @@ var FaustWasmInstantiator = class {
1864
1882
  }
1865
1883
  }
1866
1884
  static async createAsyncMonoDSPInstance(factory) {
1867
- const instance = await WebAssembly.instantiate(factory.module, this.createWasmImport());
1868
- return this.createMonoDSPInstanceAux(instance, factory.json);
1885
+ const parsedJson = JSON.parse(factory.json);
1886
+ if (Array.isArray(parsedJson.ui) && parsedJson.ui.some((group) => {
1887
+ var _a;
1888
+ return (_a = group.items) == null ? void 0 : _a.some((item) => item.type === "soundfile");
1889
+ })) {
1890
+ const memory = this.createMemoryMono(factory);
1891
+ const instance = await WebAssembly.instantiate(factory.module, this.createWasmImport(memory));
1892
+ return this.createMonoDSPInstanceAux(instance, factory.json, memory);
1893
+ } else {
1894
+ const instance = await WebAssembly.instantiate(factory.module, this.createWasmImport());
1895
+ return this.createMonoDSPInstanceAux(instance, factory.json);
1896
+ }
1869
1897
  }
1870
1898
  static createSyncMonoDSPInstance(factory) {
1871
- const instance = new WebAssembly.Instance(factory.module, this.createWasmImport());
1872
- return this.createMonoDSPInstanceAux(instance, factory.json);
1899
+ const parsedJson = JSON.parse(factory.json);
1900
+ if (Array.isArray(parsedJson.ui) && parsedJson.ui.some((group) => {
1901
+ var _a;
1902
+ return (_a = group.items) == null ? void 0 : _a.some((item) => item.type === "soundfile");
1903
+ })) {
1904
+ const memory = this.createMemoryMono(factory);
1905
+ const instance = new WebAssembly.Instance(factory.module, this.createWasmImport(memory));
1906
+ return this.createMonoDSPInstanceAux(instance, factory.json, memory);
1907
+ } else {
1908
+ const instance = new WebAssembly.Instance(factory.module, this.createWasmImport());
1909
+ return this.createMonoDSPInstanceAux(instance, factory.json);
1910
+ }
1873
1911
  }
1874
1912
  static async createAsyncPolyDSPInstance(voiceFactory, mixerModule, voices, effectFactory) {
1875
- const memory = this.createMemoryAux(voices, voiceFactory, effectFactory);
1913
+ const memory = this.createMemoryPoly(voices, voiceFactory, effectFactory);
1876
1914
  const voiceInstance = await WebAssembly.instantiate(voiceFactory.module, this.createWasmImport(memory));
1877
1915
  const voiceFunctions = voiceInstance.exports;
1878
1916
  const voiceAPI = new FaustDspInstance(voiceFunctions);
@@ -1901,7 +1939,7 @@ var FaustWasmInstantiator = class {
1901
1939
  }
1902
1940
  }
1903
1941
  static createSyncPolyDSPInstance(voiceFactory, mixerModule, voices, effectFactory) {
1904
- const memory = this.createMemoryAux(voices, voiceFactory, effectFactory);
1942
+ const memory = this.createMemoryPoly(voices, voiceFactory, effectFactory);
1905
1943
  const voiceInstance = new WebAssembly.Instance(voiceFactory.module, this.createWasmImport(memory));
1906
1944
  const voiceFunctions = voiceInstance.exports;
1907
1945
  const voiceAPI = new FaustDspInstance(voiceFunctions);
@@ -1933,6 +1971,264 @@ var FaustWasmInstantiator = class {
1933
1971
  var FaustWasmInstantiator_default = FaustWasmInstantiator;
1934
1972
 
1935
1973
  // src/FaustWebAudioDsp.ts
1974
+ var WasmAllocator = class {
1975
+ constructor(memory, offset) {
1976
+ this.memory = memory;
1977
+ this.allocatedBytes = offset;
1978
+ }
1979
+ alloc(sizeInBytes) {
1980
+ const currentOffset = this.allocatedBytes;
1981
+ const newOffset = currentOffset + sizeInBytes;
1982
+ const totalMemoryBytes = this.memory.buffer.byteLength;
1983
+ if (newOffset > totalMemoryBytes) {
1984
+ const neededPages = Math.ceil((newOffset - totalMemoryBytes) / 65536);
1985
+ console.log(`GROW: ${neededPages} pages`);
1986
+ this.memory.grow(neededPages);
1987
+ }
1988
+ this.allocatedBytes = newOffset;
1989
+ return currentOffset;
1990
+ }
1991
+ getBuffer() {
1992
+ return this.memory.buffer;
1993
+ }
1994
+ getInt32Array() {
1995
+ return new Int32Array(this.memory.buffer);
1996
+ }
1997
+ getFloat32Array() {
1998
+ return new Float32Array(this.memory.buffer);
1999
+ }
2000
+ getFloat64Array() {
2001
+ return new Float64Array(this.memory.buffer);
2002
+ }
2003
+ };
2004
+ var MAX_SOUNDFILE_PARTS = 256;
2005
+ var MAX_CHAN = 64;
2006
+ var BUFFER_SIZE = 1024;
2007
+ var SAMPLE_RATE = 44100;
2008
+ var intSize = 4;
2009
+ var Soundfile = class {
2010
+ constructor(allocator, ptrSize, sampleSize, curChan, length2, maxChan, totalParts) {
2011
+ this.fSampleSize = sampleSize;
2012
+ this.fPtrSize = ptrSize;
2013
+ this.fAllocator = allocator;
2014
+ this.fPtr = allocator.alloc(4 * ptrSize);
2015
+ this.fLength = allocator.alloc(MAX_SOUNDFILE_PARTS * intSize);
2016
+ this.fSR = allocator.alloc(MAX_SOUNDFILE_PARTS * intSize);
2017
+ this.fOffset = allocator.alloc(MAX_SOUNDFILE_PARTS * intSize);
2018
+ this.fBuffers = this.allocBuffers(curChan, length2, maxChan);
2019
+ const HEAP32 = this.fAllocator.getInt32Array();
2020
+ HEAP32[this.fPtr >> 2] = this.fBuffers;
2021
+ HEAP32[this.fPtr + ptrSize >> 2] = this.fLength;
2022
+ HEAP32[this.fPtr + 2 * ptrSize >> 2] = this.fSR;
2023
+ HEAP32[this.fPtr + 3 * ptrSize >> 2] = this.fOffset;
2024
+ for (let chan = 0; chan < curChan; chan++) {
2025
+ const buffer = HEAP32[(this.fBuffers >> 2) + chan];
2026
+ console.log(`allocBuffers AFTER: ${chan} - ${buffer}`);
2027
+ }
2028
+ }
2029
+ allocBuffers(curChan, length2, maxChan) {
2030
+ const buffers = this.fAllocator.alloc(maxChan * this.fPtrSize);
2031
+ console.log(`allocBuffers buffers: ${buffers}`);
2032
+ for (let chan = 0; chan < curChan; chan++) {
2033
+ const buffer = this.fAllocator.alloc(length2 * this.fSampleSize);
2034
+ const HEAP32 = this.fAllocator.getInt32Array();
2035
+ HEAP32[(buffers >> 2) + chan] = buffer;
2036
+ }
2037
+ return buffers;
2038
+ }
2039
+ shareBuffers(curChan, maxChan) {
2040
+ const HEAP32 = this.fAllocator.getInt32Array();
2041
+ for (let chan = curChan; chan < maxChan; chan++) {
2042
+ HEAP32[(this.fBuffers >> 2) + chan] = HEAP32[(this.fBuffers >> 2) + chan % curChan];
2043
+ }
2044
+ }
2045
+ copyToOut(part, maxChannels, offset, buffer) {
2046
+ const HEAP32 = this.fAllocator.getInt32Array();
2047
+ HEAP32[(this.fLength >> 2) + part] = buffer.length;
2048
+ HEAP32[(this.fSR >> 2) + part] = buffer.sampleRate;
2049
+ HEAP32[(this.fOffset >> 2) + part] = offset;
2050
+ if (this.fSampleSize === 8) {
2051
+ this.copyToOutReal64(maxChannels, offset, buffer);
2052
+ } else {
2053
+ this.copyToOutReal32(maxChannels, offset, buffer);
2054
+ }
2055
+ }
2056
+ copyToOutReal32(maxChannels, offset, buffer) {
2057
+ const HEAP32 = this.fAllocator.getInt32Array();
2058
+ const HEAPF = this.fAllocator.getFloat32Array();
2059
+ for (let chan = 0; chan < buffer.numberOfChannels; chan++) {
2060
+ const input = buffer.getChannelData(chan);
2061
+ const output = HEAP32[(this.fBuffers >> 2) + chan];
2062
+ const outputReal = HEAPF.subarray(
2063
+ output + offset * this.fSampleSize >> Math.log2(this.fSampleSize),
2064
+ output + (offset + input.length) * this.fSampleSize >> Math.log2(this.fSampleSize)
2065
+ );
2066
+ for (let sample = 0; sample < input.length; sample++) {
2067
+ outputReal[sample] = input[sample];
2068
+ }
2069
+ }
2070
+ }
2071
+ copyToOutReal64(maxChannels, offset, buffer) {
2072
+ const HEAP32 = this.fAllocator.getInt32Array();
2073
+ const HEAPF = this.fAllocator.getFloat64Array();
2074
+ for (let chan = 0; chan < buffer.numberOfChannels; chan++) {
2075
+ const input = buffer.getChannelData(chan);
2076
+ const output = HEAP32[(this.fBuffers >> 2) + chan];
2077
+ const outputReal = HEAPF.subarray(
2078
+ output + offset * this.fSampleSize >> Math.log2(this.fSampleSize),
2079
+ output + (offset + input.length) * this.fSampleSize >> Math.log2(this.fSampleSize)
2080
+ );
2081
+ for (let sample = 0; sample < input.length; sample++) {
2082
+ outputReal[sample] = input[sample];
2083
+ }
2084
+ }
2085
+ }
2086
+ emptyFile(part, offset) {
2087
+ const HEAP32 = this.fAllocator.getInt32Array();
2088
+ HEAP32[(this.fLength >> 2) + part] = BUFFER_SIZE;
2089
+ HEAP32[(this.fSR >> 2) + part] = SAMPLE_RATE;
2090
+ HEAP32[(this.fOffset >> 2) + part] = offset;
2091
+ return offset + BUFFER_SIZE;
2092
+ }
2093
+ displayMemory(where = "", mem = false) {
2094
+ console.log("Soundfile memory: " + where);
2095
+ console.log(`fPtr: ${this.fPtr}`);
2096
+ console.log(`fBuffers: ${this.fBuffers}`);
2097
+ console.log(`fLength: ${this.fLength}`);
2098
+ console.log(`fSR: ${this.fSR}`);
2099
+ console.log(`fOffset: ${this.fOffset}`);
2100
+ const HEAP32 = this.fAllocator.getInt32Array();
2101
+ if (mem)
2102
+ console.log(`HEAP32: ${HEAP32}`);
2103
+ console.log(`HEAP32[this.fPtr >> 2]: ${HEAP32[this.fPtr >> 2]}`);
2104
+ console.log(`HEAP32[(this.fPtr + ptrSize) >> 2]: ${HEAP32[this.fPtr + this.fPtrSize >> 2]}`);
2105
+ console.log(`HEAP32[(this.fPtr + 2 * ptrSize) >> 2]: ${HEAP32[this.fPtr + 2 * this.fPtrSize >> 2]}`);
2106
+ console.log(`HEAP32[(this.fPtr + 3 * ptrSize) >> 2]: ${HEAP32[this.fPtr + 3 * this.fPtrSize >> 2]}`);
2107
+ }
2108
+ getPtr() {
2109
+ return this.fPtr;
2110
+ }
2111
+ getHEAP32() {
2112
+ return this.fAllocator.getInt32Array();
2113
+ }
2114
+ getHEAPFloat32() {
2115
+ return this.fAllocator.getFloat32Array();
2116
+ }
2117
+ getHEAPFloat64() {
2118
+ return this.fAllocator.getFloat64Array();
2119
+ }
2120
+ };
2121
+ var SoundfileReader = class {
2122
+ constructor(allocator, context, ptrSize, sampleSize) {
2123
+ this.fAllocator = allocator;
2124
+ this.fPtrSize = ptrSize;
2125
+ this.fSampleSize = sampleSize;
2126
+ this.fContext = context;
2127
+ this.fAudioBuffers = [];
2128
+ }
2129
+ async checkFile(directories, fileName) {
2130
+ async function checkFileExists(url) {
2131
+ try {
2132
+ console.log(`"checkFileExists" url: ${url}`);
2133
+ const response = await fetch(url, { method: "HEAD" });
2134
+ return response.ok;
2135
+ } catch (error) {
2136
+ console.error("Fetch error:", error);
2137
+ return false;
2138
+ }
2139
+ }
2140
+ if (await checkFileExists(fileName)) {
2141
+ return fileName;
2142
+ } else {
2143
+ for (let i = 0; i < directories.length; i++) {
2144
+ const pathName = directories[i] + "/" + fileName;
2145
+ if (await checkFileExists(pathName)) {
2146
+ return pathName;
2147
+ }
2148
+ }
2149
+ return "";
2150
+ }
2151
+ }
2152
+ async checkFiles(directories, fileNameList) {
2153
+ const pathNameList = [];
2154
+ for (let i = 0; i < fileNameList.length; i++) {
2155
+ const pathName = await this.checkFile(directories, fileNameList[i]);
2156
+ console.log(`checkFiles pathName: ${pathName}`);
2157
+ pathNameList.push(pathName === "" ? "__empty_sound__" : pathName);
2158
+ }
2159
+ return pathNameList;
2160
+ }
2161
+ async getParamsFile(pathName) {
2162
+ console.log(`Loading sound file from ${pathName}`);
2163
+ const item = this.fAudioBuffers.find((element) => element.pathName === pathName);
2164
+ if (item) {
2165
+ console.log(`getItemByPathName FOUND`);
2166
+ return { channels: item.audioBuffer.numberOfChannels, length: item.audioBuffer.length };
2167
+ } else {
2168
+ const response = await fetch(pathName);
2169
+ if (!response.ok) {
2170
+ console.log(`Failed to load sound file from ${pathName}: ${response.statusText}`);
2171
+ return { channels: 1, length: BUFFER_SIZE };
2172
+ } else {
2173
+ const arrayBuffer = await response.arrayBuffer();
2174
+ const audioBuffer = await this.fContext.decodeAudioData(arrayBuffer);
2175
+ const { numberOfChannels, length: length2 } = audioBuffer;
2176
+ this.fAudioBuffers.push({ pathName, audioBuffer });
2177
+ return { channels: numberOfChannels, length: length2 };
2178
+ }
2179
+ }
2180
+ }
2181
+ readFile(soundfile, pathName, part, offset, maxChan) {
2182
+ const item = this.fAudioBuffers.find((entry) => entry.pathName === pathName);
2183
+ if (item) {
2184
+ soundfile.copyToOut(part, maxChan, offset, item.audioBuffer);
2185
+ return offset + item.audioBuffer.length;
2186
+ } else {
2187
+ console.error(`Failed to access sound file from ${pathName}`);
2188
+ return offset + BUFFER_SIZE;
2189
+ }
2190
+ }
2191
+ async createSoundfile(pathNameList, maxChan, isDouble) {
2192
+ try {
2193
+ let curChan = 1;
2194
+ let totalLength = 0;
2195
+ for (const pathName of pathNameList) {
2196
+ let chan = 0, len = 0;
2197
+ if (pathName === "__empty_sound__") {
2198
+ length = BUFFER_SIZE;
2199
+ chan = 1;
2200
+ } else {
2201
+ const { channels, length: length2 } = await this.getParamsFile(pathName);
2202
+ chan = channels;
2203
+ len = length2;
2204
+ }
2205
+ curChan = Math.max(curChan, chan);
2206
+ totalLength += len;
2207
+ }
2208
+ totalLength += (MAX_SOUNDFILE_PARTS - pathNameList.length) * BUFFER_SIZE;
2209
+ let soundfile = new Soundfile(this.fAllocator, this.fPtrSize, this.fSampleSize, curChan, totalLength, maxChan, pathNameList.length);
2210
+ let offset = 0;
2211
+ for (let part = 0; part < pathNameList.length; part++) {
2212
+ if (pathNameList[part] === "__empty_sound__") {
2213
+ offset = soundfile.emptyFile(part, offset);
2214
+ } else {
2215
+ offset = await this.readFile(soundfile, pathNameList[part], part, offset, maxChan);
2216
+ }
2217
+ }
2218
+ for (let part = pathNameList.length; part < MAX_SOUNDFILE_PARTS; part++) {
2219
+ offset = soundfile.emptyFile(part, offset);
2220
+ }
2221
+ soundfile.shareBuffers(curChan, maxChan);
2222
+ return soundfile;
2223
+ } catch (error) {
2224
+ console.error("Failed to create soundfile:", error);
2225
+ return null;
2226
+ }
2227
+ }
2228
+ getHEAP32() {
2229
+ return this.fAllocator.getInt32Array();
2230
+ }
2231
+ };
1936
2232
  var FaustBaseWebAudioDsp = class {
1937
2233
  constructor(sampleSize, bufferSize) {
1938
2234
  this.fOutputHandler = null;
@@ -1943,17 +2239,19 @@ var FaustBaseWebAudioDsp = class {
1943
2239
  this.fBufferSize = bufferSize;
1944
2240
  this.fInChannels = [];
1945
2241
  this.fOutChannels = [];
1946
- this.gPtrSize = sampleSize;
1947
- this.gSampleSize = sampleSize;
2242
+ this.fPtrSize = sampleSize;
2243
+ this.fSampleSize = sampleSize;
1948
2244
  this.fOutputsTimer = 5;
1949
2245
  this.fInputsItems = [];
1950
2246
  this.fOutputsItems = [];
1951
2247
  this.fDescriptor = [];
2248
+ this.fSoundfiles = [];
1952
2249
  this.fPitchwheelLabel = [];
1953
2250
  this.fCtrlLabel = new Array(128).fill(null).map(() => []);
1954
2251
  this.fPathTable = {};
1955
2252
  this.fProcessing = false;
1956
2253
  this.fDestroyed = false;
2254
+ this.fFirstCall = true;
1957
2255
  this.fUICallback = (item) => {
1958
2256
  if (item.type === "hbargraph" || item.type === "vbargraph") {
1959
2257
  this.fOutputsItems.push(item.address);
@@ -1978,6 +2276,8 @@ var FaustBaseWebAudioDsp = class {
1978
2276
  this.fCtrlLabel[parseInt(matched[1])].push({ path: item.address, min: item.min, max: item.max });
1979
2277
  }
1980
2278
  });
2279
+ } else if (item.type === "soundfile") {
2280
+ this.fSoundfiles.push({ name: item.label, url: item.url, basePtr: -1 });
1981
2281
  }
1982
2282
  };
1983
2283
  }
@@ -2002,6 +2302,46 @@ var FaustBaseWebAudioDsp = class {
2002
2302
  callback(item);
2003
2303
  }
2004
2304
  }
2305
+ static splitNames(input) {
2306
+ let trimmed = input.replace(/^\{|\}$/g, "");
2307
+ return trimmed.split(";").map((str) => str.length <= 2 ? "" : str.substring(1, str.length - 1));
2308
+ }
2309
+ async loadSoundfile(sfReader, sfOffset, name, url) {
2310
+ console.log(`Soundfile ${name} paths: ${url}`);
2311
+ const sfDirectories = ["", ".", "http://127.0.0.1:8000"];
2312
+ console.log(`sfDirectories ${sfDirectories}`);
2313
+ const sfPathNames = await sfReader.checkFiles(sfDirectories, FaustBaseWebAudioDsp.splitNames(url));
2314
+ console.log(`Soundfile ${name} paths: ${sfPathNames}`);
2315
+ const item = this.fSoundfiles.find((element) => element.url === url);
2316
+ if (item) {
2317
+ if (item.basePtr !== -1) {
2318
+ const HEAP32 = sfReader.getHEAP32();
2319
+ console.log(`Soundfile ${name} loaded at ${item.basePtr} in wasm memory with sfOffset ${sfOffset}`);
2320
+ console.log(`Soundfile CACHE ${url}}`);
2321
+ HEAP32[sfOffset >> 2] = item.basePtr;
2322
+ } else {
2323
+ const soundfile = await sfReader.createSoundfile(sfPathNames, MAX_CHAN, this.fSampleSize === 8);
2324
+ if (soundfile) {
2325
+ const HEAP32 = soundfile.getHEAP32();
2326
+ item.basePtr = soundfile.getPtr();
2327
+ console.log(`Soundfile ${name} loaded at ${item.basePtr} in wasm memory with sfOffset ${sfOffset}`);
2328
+ HEAP32[sfOffset >> 2] = item.basePtr;
2329
+ } else {
2330
+ console.log(`Soundfile ${name} for ${url} cannot be created !}`);
2331
+ }
2332
+ }
2333
+ } else {
2334
+ console.log(`Soundfile with ${url} cannot be found !}`);
2335
+ }
2336
+ }
2337
+ async initSoundfileMemory(allocator, sfReader, baseDSP) {
2338
+ let sfOffset = baseDSP;
2339
+ for (const { name, url } of this.fSoundfiles) {
2340
+ await this.loadSoundfile(sfReader, sfOffset, name, url);
2341
+ sfOffset += this.fPtrSize;
2342
+ }
2343
+ ;
2344
+ }
2005
2345
  updateOutputs() {
2006
2346
  if (this.fOutputsItems.length > 0 && this.fOutputHandler && this.fOutputsTimer-- === 0) {
2007
2347
  this.fOutputsTimer = 5;
@@ -2096,6 +2436,9 @@ var FaustBaseWebAudioDsp = class {
2096
2436
  getDescriptors() {
2097
2437
  return this.fDescriptor;
2098
2438
  }
2439
+ hasSoundfiles() {
2440
+ return this.fSoundfiles.length > 0;
2441
+ }
2099
2442
  start() {
2100
2443
  this.fProcessing = true;
2101
2444
  }
@@ -2115,51 +2458,64 @@ var FaustMonoWebAudioDsp = class extends FaustBaseWebAudioDsp {
2115
2458
  this.fInstance = instance;
2116
2459
  this.fJSONDsp = JSON.parse(this.fInstance.json);
2117
2460
  FaustBaseWebAudioDsp.parseUI(this.fJSONDsp.ui, this.fUICallback);
2118
- this.initMemory();
2461
+ this.fEndMemory = this.initMemory();
2119
2462
  this.fInstance.api.init(this.fDSP, sampleRate);
2120
2463
  }
2464
+ async init(context) {
2465
+ if (this.fSoundfiles.length > 0 && context) {
2466
+ const allocator = new WasmAllocator(this.fInstance.memory, this.fEndMemory);
2467
+ const sfReader = new SoundfileReader(allocator, context, this.fPtrSize, this.fSampleSize);
2468
+ await this.initSoundfileMemory(allocator, sfReader, this.fDSP);
2469
+ }
2470
+ }
2121
2471
  initMemory() {
2122
2472
  this.fDSP = 0;
2123
2473
  const $audio = this.fJSONDsp.size;
2124
2474
  this.fAudioInputs = $audio;
2125
- this.fAudioOutputs = this.fAudioInputs + this.getNumInputs() * this.gPtrSize;
2126
- const $audioInputs = this.fAudioOutputs + this.getNumOutputs() * this.gPtrSize;
2127
- const $audioOutputs = $audioInputs + this.getNumInputs() * this.fBufferSize * this.gSampleSize;
2475
+ this.fAudioOutputs = this.fAudioInputs + this.getNumInputs() * this.fPtrSize;
2476
+ const $audioInputs = this.fAudioOutputs + this.getNumOutputs() * this.fPtrSize;
2477
+ const $audioOutputs = $audioInputs + this.getNumInputs() * this.fBufferSize * this.fSampleSize;
2478
+ const endMemory = $audioOutputs + this.getNumOutputs() * this.fBufferSize * this.fSampleSize;
2128
2479
  const HEAP = this.fInstance.memory.buffer;
2129
2480
  const HEAP32 = new Int32Array(HEAP);
2130
- const HEAPF = this.gSampleSize === 4 ? new Float32Array(HEAP) : new Float64Array(HEAP);
2481
+ const HEAPF = this.fSampleSize === 4 ? new Float32Array(HEAP) : new Float64Array(HEAP);
2131
2482
  if (this.getNumInputs() > 0) {
2132
2483
  for (let chan = 0; chan < this.getNumInputs(); chan++) {
2133
- HEAP32[(this.fAudioInputs >> 2) + chan] = $audioInputs + this.fBufferSize * this.gSampleSize * chan;
2484
+ HEAP32[(this.fAudioInputs >> 2) + chan] = $audioInputs + this.fBufferSize * this.fSampleSize * chan;
2134
2485
  }
2135
- const dspInChans = HEAP32.subarray(this.fAudioInputs >> 2, this.fAudioInputs + this.getNumInputs() * this.gPtrSize >> 2);
2486
+ const dspInChans = HEAP32.subarray(this.fAudioInputs >> 2, this.fAudioInputs + this.getNumInputs() * this.fPtrSize >> 2);
2136
2487
  for (let chan = 0; chan < this.getNumInputs(); chan++) {
2137
- this.fInChannels[chan] = HEAPF.subarray(dspInChans[chan] >> Math.log2(this.gSampleSize), dspInChans[chan] + this.fBufferSize * this.gSampleSize >> Math.log2(this.gSampleSize));
2488
+ this.fInChannels[chan] = HEAPF.subarray(dspInChans[chan] >> Math.log2(this.fSampleSize), dspInChans[chan] + this.fBufferSize * this.fSampleSize >> Math.log2(this.fSampleSize));
2138
2489
  }
2139
2490
  }
2140
2491
  if (this.getNumOutputs() > 0) {
2141
2492
  for (let chan = 0; chan < this.getNumOutputs(); chan++) {
2142
- HEAP32[(this.fAudioOutputs >> 2) + chan] = $audioOutputs + this.fBufferSize * this.gSampleSize * chan;
2493
+ HEAP32[(this.fAudioOutputs >> 2) + chan] = $audioOutputs + this.fBufferSize * this.fSampleSize * chan;
2143
2494
  }
2144
- const dspOutChans = HEAP32.subarray(this.fAudioOutputs >> 2, this.fAudioOutputs + this.getNumOutputs() * this.gPtrSize >> 2);
2495
+ const dspOutChans = HEAP32.subarray(this.fAudioOutputs >> 2, this.fAudioOutputs + this.getNumOutputs() * this.fPtrSize >> 2);
2145
2496
  for (let chan = 0; chan < this.getNumOutputs(); chan++) {
2146
- this.fOutChannels[chan] = HEAPF.subarray(dspOutChans[chan] >> Math.log2(this.gSampleSize), dspOutChans[chan] + this.fBufferSize * this.gSampleSize >> Math.log2(this.gSampleSize));
2497
+ this.fOutChannels[chan] = HEAPF.subarray(dspOutChans[chan] >> Math.log2(this.fSampleSize), dspOutChans[chan] + this.fBufferSize * this.fSampleSize >> Math.log2(this.fSampleSize));
2147
2498
  }
2148
2499
  }
2500
+ return endMemory;
2149
2501
  }
2150
2502
  toString() {
2151
2503
  return `============== Mono Memory layout ==============
2152
- this.fBufferSize: ${this.fBufferSize}
2153
- this.fJSONDsp.size: ${this.fJSONDsp.size}
2154
- this.fAudioInputs: ${this.fAudioInputs}
2155
- this.fAudioOutputs: ${this.fAudioOutputs}
2156
- this.fDSP: ${this.fDSP}`;
2504
+ this.fBufferSize: ${this.fBufferSize}
2505
+ this.fJSONDsp.size: ${this.fJSONDsp.size}
2506
+ this.fAudioInputs: ${this.fAudioInputs}
2507
+ this.fAudioOutputs: ${this.fAudioOutputs}
2508
+ this.fDSP: ${this.fDSP}`;
2157
2509
  }
2158
2510
  compute(input, output) {
2159
2511
  if (this.fDestroyed)
2160
2512
  return false;
2161
2513
  if (!this.fProcessing)
2162
2514
  return true;
2515
+ if (this.fFirstCall) {
2516
+ this.initMemory();
2517
+ this.fFirstCall = false;
2518
+ }
2163
2519
  if (typeof input === "function") {
2164
2520
  input(this.fInChannels);
2165
2521
  } else {
@@ -2317,7 +2673,7 @@ var FaustPolyWebAudioDsp = class extends FaustBaseWebAudioDsp {
2317
2673
  FaustBaseWebAudioDsp.parseUI(this.fJSONDsp.ui, this.fUICallback);
2318
2674
  if (this.fJSONEffect)
2319
2675
  FaustBaseWebAudioDsp.parseUI(this.fJSONEffect.ui, this.fUICallback);
2320
- this.initMemory();
2676
+ this.fEndMemory = this.initMemory();
2321
2677
  this.fVoiceTable = [];
2322
2678
  for (let voice = 0; voice < this.fInstance.voices; voice++) {
2323
2679
  this.fVoiceTable.push(new FaustWebAudioDspVoice(
@@ -2331,48 +2687,59 @@ var FaustPolyWebAudioDsp = class extends FaustBaseWebAudioDsp {
2331
2687
  if (this.fInstance.effectAPI)
2332
2688
  this.fInstance.effectAPI.init(this.fEffect, sampleRate);
2333
2689
  }
2690
+ async init(context) {
2691
+ if (this.fSoundfiles.length > 0 && context) {
2692
+ const allocator = new WasmAllocator(this.fInstance.memory, this.fEndMemory);
2693
+ const sfReader = new SoundfileReader(allocator, context, this.fPtrSize, this.fSampleSize);
2694
+ for (let voice = 0; voice < this.fInstance.voices; voice++) {
2695
+ await this.initSoundfileMemory(allocator, sfReader, this.fJSONDsp.size * voice);
2696
+ }
2697
+ }
2698
+ }
2334
2699
  initMemory() {
2335
2700
  this.fEffect = this.fJSONDsp.size * this.fInstance.voices;
2336
2701
  const $audio = this.fEffect + (this.fJSONEffect ? this.fJSONEffect.size : 0);
2337
2702
  this.fAudioInputs = $audio;
2338
- this.fAudioOutputs = this.fAudioInputs + this.getNumInputs() * this.gPtrSize;
2339
- this.fAudioMixing = this.fAudioOutputs + this.getNumOutputs() * this.gPtrSize;
2340
- this.fAudioMixingHalf = this.fAudioMixing + this.getNumOutputs() * this.gPtrSize;
2341
- const $audioInputs = this.fAudioMixingHalf + this.getNumOutputs() * this.gPtrSize;
2342
- const $audioOutputs = $audioInputs + this.getNumInputs() * this.fBufferSize * this.gSampleSize;
2343
- const $audioMixing = $audioOutputs + this.getNumOutputs() * this.fBufferSize * this.gSampleSize;
2703
+ this.fAudioOutputs = this.fAudioInputs + this.getNumInputs() * this.fPtrSize;
2704
+ this.fAudioMixing = this.fAudioOutputs + this.getNumOutputs() * this.fPtrSize;
2705
+ this.fAudioMixingHalf = this.fAudioMixing + this.getNumOutputs() * this.fPtrSize;
2706
+ const $audioInputs = this.fAudioMixingHalf + this.getNumOutputs() * this.fPtrSize;
2707
+ const $audioOutputs = $audioInputs + this.getNumInputs() * this.fBufferSize * this.fSampleSize;
2708
+ const $audioMixing = $audioOutputs + this.getNumOutputs() * this.fBufferSize * this.fSampleSize;
2709
+ const endMemory = $audioMixing + this.getNumOutputs() * this.fBufferSize * this.fSampleSize;
2344
2710
  const HEAP = this.fInstance.memory.buffer;
2345
2711
  const HEAP32 = new Int32Array(HEAP);
2346
- const HEAPF = this.gSampleSize === 4 ? new Float32Array(HEAP) : new Float64Array(HEAP);
2712
+ const HEAPF = this.fSampleSize === 4 ? new Float32Array(HEAP) : new Float64Array(HEAP);
2347
2713
  if (this.getNumInputs() > 0) {
2348
2714
  for (let chan = 0; chan < this.getNumInputs(); chan++) {
2349
- HEAP32[(this.fAudioInputs >> 2) + chan] = $audioInputs + this.fBufferSize * this.gSampleSize * chan;
2715
+ HEAP32[(this.fAudioInputs >> 2) + chan] = $audioInputs + this.fBufferSize * this.fSampleSize * chan;
2350
2716
  }
2351
- const dspInChans = HEAP32.subarray(this.fAudioInputs >> 2, this.fAudioInputs + this.getNumInputs() * this.gPtrSize >> 2);
2717
+ const dspInChans = HEAP32.subarray(this.fAudioInputs >> 2, this.fAudioInputs + this.getNumInputs() * this.fPtrSize >> 2);
2352
2718
  for (let chan = 0; chan < this.getNumInputs(); chan++) {
2353
- this.fInChannels[chan] = HEAPF.subarray(dspInChans[chan] >> Math.log2(this.gSampleSize), dspInChans[chan] + this.fBufferSize * this.gSampleSize >> Math.log2(this.gSampleSize));
2719
+ this.fInChannels[chan] = HEAPF.subarray(dspInChans[chan] >> Math.log2(this.fSampleSize), dspInChans[chan] + this.fBufferSize * this.fSampleSize >> Math.log2(this.fSampleSize));
2354
2720
  }
2355
2721
  }
2356
2722
  if (this.getNumOutputs() > 0) {
2357
2723
  for (let chan = 0; chan < this.getNumOutputs(); chan++) {
2358
- HEAP32[(this.fAudioOutputs >> 2) + chan] = $audioOutputs + this.fBufferSize * this.gSampleSize * chan;
2359
- HEAP32[(this.fAudioMixing >> 2) + chan] = $audioMixing + this.fBufferSize * this.gSampleSize * chan;
2360
- HEAP32[(this.fAudioMixingHalf >> 2) + chan] = $audioMixing + this.fBufferSize * this.gSampleSize * chan + this.fBufferSize / 2 * this.gSampleSize;
2724
+ HEAP32[(this.fAudioOutputs >> 2) + chan] = $audioOutputs + this.fBufferSize * this.fSampleSize * chan;
2725
+ HEAP32[(this.fAudioMixing >> 2) + chan] = $audioMixing + this.fBufferSize * this.fSampleSize * chan;
2726
+ HEAP32[(this.fAudioMixingHalf >> 2) + chan] = $audioMixing + this.fBufferSize * this.fSampleSize * chan + this.fBufferSize / 2 * this.fSampleSize;
2361
2727
  }
2362
- const dspOutChans = HEAP32.subarray(this.fAudioOutputs >> 2, this.fAudioOutputs + this.getNumOutputs() * this.gPtrSize >> 2);
2728
+ const dspOutChans = HEAP32.subarray(this.fAudioOutputs >> 2, this.fAudioOutputs + this.getNumOutputs() * this.fPtrSize >> 2);
2363
2729
  for (let chan = 0; chan < this.getNumOutputs(); chan++) {
2364
- this.fOutChannels[chan] = HEAPF.subarray(dspOutChans[chan] >> Math.log2(this.gSampleSize), dspOutChans[chan] + this.fBufferSize * this.gSampleSize >> Math.log2(this.gSampleSize));
2730
+ this.fOutChannels[chan] = HEAPF.subarray(dspOutChans[chan] >> Math.log2(this.fSampleSize), dspOutChans[chan] + this.fBufferSize * this.fSampleSize >> Math.log2(this.fSampleSize));
2365
2731
  }
2366
2732
  }
2733
+ return endMemory;
2367
2734
  }
2368
2735
  toString() {
2369
2736
  return `============== Poly Memory layout ==============
2370
- this.fBufferSize: ${this.fBufferSize}
2371
- this.fJSONDsp.size: ${this.fJSONDsp.size}
2372
- this.fAudioInputs: ${this.fAudioInputs}
2373
- this.fAudioOutputs: ${this.fAudioOutputs}
2374
- this.fAudioMixing: ${this.fAudioMixing}
2375
- this.fAudioMixingHalf: ${this.fAudioMixingHalf}`;
2737
+ this.fBufferSize: ${this.fBufferSize}
2738
+ this.fJSONDsp.size: ${this.fJSONDsp.size}
2739
+ this.fAudioInputs: ${this.fAudioInputs}
2740
+ this.fAudioOutputs: ${this.fAudioOutputs}
2741
+ this.fAudioMixing: ${this.fAudioMixing}
2742
+ this.fAudioMixingHalf: ${this.fAudioMixingHalf}`;
2376
2743
  }
2377
2744
  allocVoice(voice, type) {
2378
2745
  this.fVoiceTable[voice].fDate++;
@@ -2426,6 +2793,10 @@ this.fAudioMixingHalf: ${this.fAudioMixingHalf}`;
2426
2793
  compute(input, output) {
2427
2794
  if (this.fDestroyed)
2428
2795
  return false;
2796
+ if (this.fFirstCall) {
2797
+ this.initMemory();
2798
+ this.fFirstCall = false;
2799
+ }
2429
2800
  if (!this.fProcessing)
2430
2801
  return true;
2431
2802
  if (this.getNumInputs() > 0 && (!input || !input[0] || input[0].length === 0)) {
@@ -2676,12 +3047,12 @@ var FaustOfflineProcessor = class {
2676
3047
  destroy() {
2677
3048
  this.fDSPCode.destroy();
2678
3049
  }
2679
- render(inputs = [], length = this.fBufferSize, onUpdate) {
3050
+ render(inputs = [], length2 = this.fBufferSize, onUpdate) {
2680
3051
  let l = 0;
2681
- const outputs = new Array(this.fDSPCode.getNumOutputs()).fill(null).map(() => new Float32Array(length));
3052
+ const outputs = new Array(this.fDSPCode.getNumOutputs()).fill(null).map(() => new Float32Array(length2));
2682
3053
  this.fDSPCode.start();
2683
- while (l < length) {
2684
- const sliceLength = Math.min(length - l, this.fBufferSize);
3054
+ while (l < length2) {
3055
+ const sliceLength = Math.min(length2 - l, this.fBufferSize);
2685
3056
  for (let i = 0; i < this.fDSPCode.getNumInputs(); i++) {
2686
3057
  let input;
2687
3058
  if (inputs[i]) {
@@ -2814,11 +3185,11 @@ var LibFaust_default = LibFaust;
2814
3185
  var WavEncoder = class {
2815
3186
  static encode(audioBuffer, options) {
2816
3187
  const numberOfChannels = audioBuffer.length;
2817
- const length = audioBuffer[0].length;
3188
+ const length2 = audioBuffer[0].length;
2818
3189
  const { shared, float } = options;
2819
3190
  const bitDepth = float ? 32 : options.bitDepth | 0 || 16;
2820
3191
  const byteDepth = bitDepth >> 3;
2821
- const byteLength = length * numberOfChannels * byteDepth;
3192
+ const byteLength = length2 * numberOfChannels * byteDepth;
2822
3193
  const AB = shared ? globalThis.SharedArrayBuffer || globalThis.ArrayBuffer : globalThis.ArrayBuffer;
2823
3194
  const ab = new AB((44 + byteLength) * Uint8Array.BYTES_PER_ELEMENT);
2824
3195
  const dataView = new DataView(ab);
@@ -2829,7 +3200,7 @@ var WavEncoder = class {
2829
3200
  numberOfChannels,
2830
3201
  sampleRate: options.sampleRate,
2831
3202
  symmetric: !!options.symmetric,
2832
- length,
3203
+ length: length2,
2833
3204
  bitDepth,
2834
3205
  byteDepth
2835
3206
  };
@@ -2838,7 +3209,7 @@ var WavEncoder = class {
2838
3209
  return ab;
2839
3210
  }
2840
3211
  static writeHeader(writer, format) {
2841
- const { formatId, sampleRate, bitDepth, numberOfChannels, length, byteDepth } = format;
3212
+ const { formatId, sampleRate, bitDepth, numberOfChannels, length: length2, byteDepth } = format;
2842
3213
  writer.string("RIFF");
2843
3214
  writer.uint32(writer.dataView.byteLength - 8);
2844
3215
  writer.string("WAVE");
@@ -2851,11 +3222,11 @@ var WavEncoder = class {
2851
3222
  writer.uint16(numberOfChannels * byteDepth);
2852
3223
  writer.uint16(bitDepth);
2853
3224
  writer.string("data");
2854
- writer.uint32(length * numberOfChannels * byteDepth);
3225
+ writer.uint32(length2 * numberOfChannels * byteDepth);
2855
3226
  return writer.pos;
2856
3227
  }
2857
3228
  static writeData(writer, audioBuffer, format) {
2858
- const { bitDepth, float, length, numberOfChannels, symmetric } = format;
3229
+ const { bitDepth, float, length: length2, numberOfChannels, symmetric } = format;
2859
3230
  if (bitDepth === 32 && float) {
2860
3231
  const { dataView, pos } = writer;
2861
3232
  const ab = dataView.buffer;
@@ -2866,7 +3237,7 @@ var WavEncoder = class {
2866
3237
  }
2867
3238
  for (let ch = 0; ch < numberOfChannels; ch++) {
2868
3239
  const channel = audioBuffer[ch];
2869
- for (let i = 0; i < length; i++) {
3240
+ for (let i = 0; i < length2; i++) {
2870
3241
  f32View[i * numberOfChannels + ch] = channel[i];
2871
3242
  }
2872
3243
  }
@@ -2878,7 +3249,7 @@ var WavEncoder = class {
2878
3249
  throw new TypeError("Not supported bit depth: " + bitDepth);
2879
3250
  }
2880
3251
  const write = writer[methodName].bind(writer);
2881
- for (let i = 0; i < length; i++) {
3252
+ for (let i = 0; i < length2; i++) {
2882
3253
  for (let j = 0; j < numberOfChannels; j++) {
2883
3254
  write(audioBuffer[j][i]);
2884
3255
  }
@@ -3034,24 +3405,24 @@ var WavDecoder = class {
3034
3405
  }
3035
3406
  static decodeData(reader, chunkSizeIn, format, options) {
3036
3407
  const chunkSize = Math.min(chunkSizeIn, reader.remain());
3037
- const length = Math.floor(chunkSize / format.blockSize);
3408
+ const length2 = Math.floor(chunkSize / format.blockSize);
3038
3409
  const numberOfChannels = format.numberOfChannels;
3039
3410
  const sampleRate = format.sampleRate;
3040
3411
  const channelData = new Array(numberOfChannels);
3041
3412
  for (let ch = 0; ch < numberOfChannels; ch++) {
3042
3413
  const AB = options.shared ? globalThis.SharedArrayBuffer || globalThis.ArrayBuffer : globalThis.ArrayBuffer;
3043
- const ab = new AB(length * Float32Array.BYTES_PER_ELEMENT);
3414
+ const ab = new AB(length2 * Float32Array.BYTES_PER_ELEMENT);
3044
3415
  channelData[ch] = new Float32Array(ab);
3045
3416
  }
3046
- this.readPCM(reader, channelData, length, format, options);
3417
+ this.readPCM(reader, channelData, length2, format, options);
3047
3418
  return {
3048
3419
  numberOfChannels,
3049
- length,
3420
+ length: length2,
3050
3421
  sampleRate,
3051
3422
  channelData
3052
3423
  };
3053
3424
  }
3054
- static readPCM(reader, channelData, length, format, options) {
3425
+ static readPCM(reader, channelData, length2, format, options) {
3055
3426
  const bitDepth = format.bitDepth;
3056
3427
  const decoderOption = format.float ? "f" : options.symmetric ? "s" : "";
3057
3428
  const methodName = "pcm" + bitDepth + decoderOption;
@@ -3060,7 +3431,7 @@ var WavDecoder = class {
3060
3431
  }
3061
3432
  const read = reader[methodName].bind(reader);
3062
3433
  const numberOfChannels = format.numberOfChannels;
3063
- for (let i = 0; i < length; i++) {
3434
+ for (let i = 0; i < length2; i++) {
3064
3435
  for (let ch = 0; ch < numberOfChannels; ch++) {
3065
3436
  channelData[ch][i] = read();
3066
3437
  }
@@ -3479,10 +3850,12 @@ var _FaustMonoDspGenerator = class {
3479
3850
  }
3480
3851
  async compile(compiler, name, code, args) {
3481
3852
  this.factory = await compiler.createMonoDSPFactory(name, code, args);
3482
- if (!this.factory)
3853
+ if (this.factory) {
3854
+ this.name = name;
3855
+ return this;
3856
+ } else {
3483
3857
  return null;
3484
- this.name = name;
3485
- return this;
3858
+ }
3486
3859
  }
3487
3860
  async createNode(context, name = this.name, factory = this.factory, sp = false, bufferSize = 1024, processorName = (factory == null ? void 0 : factory.shaKey) || name) {
3488
3861
  var _a, _b;
@@ -3493,6 +3866,7 @@ var _FaustMonoDspGenerator = class {
3493
3866
  if (sp) {
3494
3867
  const instance = await FaustWasmInstantiator_default.createAsyncMonoDSPInstance(factory);
3495
3868
  const monoDsp = new FaustMonoWebAudioDsp(instance, context.sampleRate, sampleSize, bufferSize);
3869
+ await monoDsp.init(context);
3496
3870
  const sp2 = context.createScriptProcessor(bufferSize, monoDsp.getNumInputs(), monoDsp.getNumOutputs());
3497
3871
  Object.setPrototypeOf(sp2, FaustMonoScriptProcessorNode.prototype);
3498
3872
  sp2.init(monoDsp);
@@ -3630,6 +4004,7 @@ const dependencies = {
3630
4004
  const instance = await FaustWasmInstantiator_default.createAsyncMonoDSPInstance(factory);
3631
4005
  const sampleSize = meta.compile_options.match("-double") ? 8 : 4;
3632
4006
  const monoDsp = new FaustMonoWebAudioDsp(instance, sampleRate, sampleSize, bufferSize);
4007
+ await monoDsp.init(null);
3633
4008
  return new FaustMonoOfflineProcessor(monoDsp, bufferSize);
3634
4009
  }
3635
4010
  getMeta() {
@@ -3727,6 +4102,7 @@ var _FaustPolyDspGenerator = class {
3727
4102
  if (sp) {
3728
4103
  const instance = await FaustWasmInstantiator_default.createAsyncPolyDSPInstance(voiceFactory, mixerModule, voices, effectFactory || void 0);
3729
4104
  const polyDsp = new FaustPolyWebAudioDsp(instance, context.sampleRate, sampleSize, bufferSize);
4105
+ await polyDsp.init(context);
3730
4106
  const sp2 = context.createScriptProcessor(bufferSize, polyDsp.getNumInputs(), polyDsp.getNumOutputs());
3731
4107
  Object.setPrototypeOf(sp2, FaustPolyScriptProcessorNode.prototype);
3732
4108
  sp2.init(polyDsp);