@grame/faustwasm 0.0.67 → 0.1.1

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 +146 -4
  7. package/assets/standalone/faustwasm/index.js +460 -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 +146 -4
  12. package/dist/cjs/index.js +460 -73
  13. package/dist/cjs/index.js.map +3 -3
  14. package/dist/cjs-bundle/index.d.ts +146 -4
  15. package/dist/cjs-bundle/index.js +561 -174
  16. package/dist/cjs-bundle/index.js.map +3 -3
  17. package/dist/esm/index.d.ts +146 -4
  18. package/dist/esm/index.js +460 -73
  19. package/dist/esm/index.js.map +3 -3
  20. package/dist/esm-bundle/index.d.ts +146 -4
  21. package/dist/esm-bundle/index.js +561 -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 +696 -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 +146 -4
  37. package/test/faustlive-wasm/faustwasm/index.js +460 -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,57 @@ 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
+ extractURLsFromJSON() {
2310
+ const soundfilesEntry = this.fJSONDsp.meta.find((entry) => entry.soundfiles !== void 0);
2311
+ if (soundfilesEntry) {
2312
+ return soundfilesEntry.soundfiles.split(";").filter((url) => url !== "");
2313
+ } else {
2314
+ return [];
2315
+ }
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
+ const sfReaderURLs = this.extractURLsFromJSON();
2321
+ console.log(`sfReaderURLs ${sfReaderURLs}`);
2322
+ sfDirectories.push(...sfReaderURLs);
2323
+ console.log(`sfDirectories ${sfDirectories}`);
2324
+ const sfPathNames = await sfReader.checkFiles(sfDirectories, FaustBaseWebAudioDsp.splitNames(url));
2325
+ console.log(`Soundfile ${name} paths: ${sfPathNames}`);
2326
+ const item = this.fSoundfiles.find((element) => element.url === url);
2327
+ if (item) {
2328
+ if (item.basePtr !== -1) {
2329
+ const HEAP32 = sfReader.getHEAP32();
2330
+ console.log(`Soundfile ${name} loaded at ${item.basePtr} in wasm memory with sfOffset ${sfOffset}`);
2331
+ console.log(`Soundfile CACHE ${url}}`);
2332
+ HEAP32[sfOffset >> 2] = item.basePtr;
2333
+ } else {
2334
+ const soundfile = await sfReader.createSoundfile(sfPathNames, MAX_CHAN, this.fSampleSize === 8);
2335
+ if (soundfile) {
2336
+ const HEAP32 = soundfile.getHEAP32();
2337
+ item.basePtr = soundfile.getPtr();
2338
+ console.log(`Soundfile ${name} loaded at ${item.basePtr} in wasm memory with sfOffset ${sfOffset}`);
2339
+ HEAP32[sfOffset >> 2] = item.basePtr;
2340
+ } else {
2341
+ console.log(`Soundfile ${name} for ${url} cannot be created !}`);
2342
+ }
2343
+ }
2344
+ } else {
2345
+ console.log(`Soundfile with ${url} cannot be found !}`);
2346
+ }
2347
+ }
2348
+ async initSoundfileMemory(allocator, sfReader, baseDSP) {
2349
+ let sfOffset = baseDSP;
2350
+ for (const { name, url } of this.fSoundfiles) {
2351
+ await this.loadSoundfile(sfReader, sfOffset, name, url);
2352
+ sfOffset += this.fPtrSize;
2353
+ }
2354
+ ;
2355
+ }
2005
2356
  updateOutputs() {
2006
2357
  if (this.fOutputsItems.length > 0 && this.fOutputHandler && this.fOutputsTimer-- === 0) {
2007
2358
  this.fOutputsTimer = 5;
@@ -2096,6 +2447,9 @@ var FaustBaseWebAudioDsp = class {
2096
2447
  getDescriptors() {
2097
2448
  return this.fDescriptor;
2098
2449
  }
2450
+ hasSoundfiles() {
2451
+ return this.fSoundfiles.length > 0;
2452
+ }
2099
2453
  start() {
2100
2454
  this.fProcessing = true;
2101
2455
  }
@@ -2115,51 +2469,64 @@ var FaustMonoWebAudioDsp = class extends FaustBaseWebAudioDsp {
2115
2469
  this.fInstance = instance;
2116
2470
  this.fJSONDsp = JSON.parse(this.fInstance.json);
2117
2471
  FaustBaseWebAudioDsp.parseUI(this.fJSONDsp.ui, this.fUICallback);
2118
- this.initMemory();
2472
+ this.fEndMemory = this.initMemory();
2119
2473
  this.fInstance.api.init(this.fDSP, sampleRate);
2120
2474
  }
2475
+ async init(context) {
2476
+ if (this.fSoundfiles.length > 0 && context) {
2477
+ const allocator = new WasmAllocator(this.fInstance.memory, this.fEndMemory);
2478
+ const sfReader = new SoundfileReader(allocator, context, this.fPtrSize, this.fSampleSize);
2479
+ await this.initSoundfileMemory(allocator, sfReader, this.fDSP);
2480
+ }
2481
+ }
2121
2482
  initMemory() {
2122
2483
  this.fDSP = 0;
2123
2484
  const $audio = this.fJSONDsp.size;
2124
2485
  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;
2486
+ this.fAudioOutputs = this.fAudioInputs + this.getNumInputs() * this.fPtrSize;
2487
+ const $audioInputs = this.fAudioOutputs + this.getNumOutputs() * this.fPtrSize;
2488
+ const $audioOutputs = $audioInputs + this.getNumInputs() * this.fBufferSize * this.fSampleSize;
2489
+ const endMemory = $audioOutputs + this.getNumOutputs() * this.fBufferSize * this.fSampleSize;
2128
2490
  const HEAP = this.fInstance.memory.buffer;
2129
2491
  const HEAP32 = new Int32Array(HEAP);
2130
- const HEAPF = this.gSampleSize === 4 ? new Float32Array(HEAP) : new Float64Array(HEAP);
2492
+ const HEAPF = this.fSampleSize === 4 ? new Float32Array(HEAP) : new Float64Array(HEAP);
2131
2493
  if (this.getNumInputs() > 0) {
2132
2494
  for (let chan = 0; chan < this.getNumInputs(); chan++) {
2133
- HEAP32[(this.fAudioInputs >> 2) + chan] = $audioInputs + this.fBufferSize * this.gSampleSize * chan;
2495
+ HEAP32[(this.fAudioInputs >> 2) + chan] = $audioInputs + this.fBufferSize * this.fSampleSize * chan;
2134
2496
  }
2135
- const dspInChans = HEAP32.subarray(this.fAudioInputs >> 2, this.fAudioInputs + this.getNumInputs() * this.gPtrSize >> 2);
2497
+ const dspInChans = HEAP32.subarray(this.fAudioInputs >> 2, this.fAudioInputs + this.getNumInputs() * this.fPtrSize >> 2);
2136
2498
  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));
2499
+ this.fInChannels[chan] = HEAPF.subarray(dspInChans[chan] >> Math.log2(this.fSampleSize), dspInChans[chan] + this.fBufferSize * this.fSampleSize >> Math.log2(this.fSampleSize));
2138
2500
  }
2139
2501
  }
2140
2502
  if (this.getNumOutputs() > 0) {
2141
2503
  for (let chan = 0; chan < this.getNumOutputs(); chan++) {
2142
- HEAP32[(this.fAudioOutputs >> 2) + chan] = $audioOutputs + this.fBufferSize * this.gSampleSize * chan;
2504
+ HEAP32[(this.fAudioOutputs >> 2) + chan] = $audioOutputs + this.fBufferSize * this.fSampleSize * chan;
2143
2505
  }
2144
- const dspOutChans = HEAP32.subarray(this.fAudioOutputs >> 2, this.fAudioOutputs + this.getNumOutputs() * this.gPtrSize >> 2);
2506
+ const dspOutChans = HEAP32.subarray(this.fAudioOutputs >> 2, this.fAudioOutputs + this.getNumOutputs() * this.fPtrSize >> 2);
2145
2507
  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));
2508
+ this.fOutChannels[chan] = HEAPF.subarray(dspOutChans[chan] >> Math.log2(this.fSampleSize), dspOutChans[chan] + this.fBufferSize * this.fSampleSize >> Math.log2(this.fSampleSize));
2147
2509
  }
2148
2510
  }
2511
+ return endMemory;
2149
2512
  }
2150
2513
  toString() {
2151
2514
  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}`;
2515
+ this.fBufferSize: ${this.fBufferSize}
2516
+ this.fJSONDsp.size: ${this.fJSONDsp.size}
2517
+ this.fAudioInputs: ${this.fAudioInputs}
2518
+ this.fAudioOutputs: ${this.fAudioOutputs}
2519
+ this.fDSP: ${this.fDSP}`;
2157
2520
  }
2158
2521
  compute(input, output) {
2159
2522
  if (this.fDestroyed)
2160
2523
  return false;
2161
2524
  if (!this.fProcessing)
2162
2525
  return true;
2526
+ if (this.fFirstCall) {
2527
+ this.initMemory();
2528
+ this.fFirstCall = false;
2529
+ }
2163
2530
  if (typeof input === "function") {
2164
2531
  input(this.fInChannels);
2165
2532
  } else {
@@ -2317,7 +2684,7 @@ var FaustPolyWebAudioDsp = class extends FaustBaseWebAudioDsp {
2317
2684
  FaustBaseWebAudioDsp.parseUI(this.fJSONDsp.ui, this.fUICallback);
2318
2685
  if (this.fJSONEffect)
2319
2686
  FaustBaseWebAudioDsp.parseUI(this.fJSONEffect.ui, this.fUICallback);
2320
- this.initMemory();
2687
+ this.fEndMemory = this.initMemory();
2321
2688
  this.fVoiceTable = [];
2322
2689
  for (let voice = 0; voice < this.fInstance.voices; voice++) {
2323
2690
  this.fVoiceTable.push(new FaustWebAudioDspVoice(
@@ -2331,48 +2698,59 @@ var FaustPolyWebAudioDsp = class extends FaustBaseWebAudioDsp {
2331
2698
  if (this.fInstance.effectAPI)
2332
2699
  this.fInstance.effectAPI.init(this.fEffect, sampleRate);
2333
2700
  }
2701
+ async init(context) {
2702
+ if (this.fSoundfiles.length > 0 && context) {
2703
+ const allocator = new WasmAllocator(this.fInstance.memory, this.fEndMemory);
2704
+ const sfReader = new SoundfileReader(allocator, context, this.fPtrSize, this.fSampleSize);
2705
+ for (let voice = 0; voice < this.fInstance.voices; voice++) {
2706
+ await this.initSoundfileMemory(allocator, sfReader, this.fJSONDsp.size * voice);
2707
+ }
2708
+ }
2709
+ }
2334
2710
  initMemory() {
2335
2711
  this.fEffect = this.fJSONDsp.size * this.fInstance.voices;
2336
2712
  const $audio = this.fEffect + (this.fJSONEffect ? this.fJSONEffect.size : 0);
2337
2713
  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;
2714
+ this.fAudioOutputs = this.fAudioInputs + this.getNumInputs() * this.fPtrSize;
2715
+ this.fAudioMixing = this.fAudioOutputs + this.getNumOutputs() * this.fPtrSize;
2716
+ this.fAudioMixingHalf = this.fAudioMixing + this.getNumOutputs() * this.fPtrSize;
2717
+ const $audioInputs = this.fAudioMixingHalf + this.getNumOutputs() * this.fPtrSize;
2718
+ const $audioOutputs = $audioInputs + this.getNumInputs() * this.fBufferSize * this.fSampleSize;
2719
+ const $audioMixing = $audioOutputs + this.getNumOutputs() * this.fBufferSize * this.fSampleSize;
2720
+ const endMemory = $audioMixing + this.getNumOutputs() * this.fBufferSize * this.fSampleSize;
2344
2721
  const HEAP = this.fInstance.memory.buffer;
2345
2722
  const HEAP32 = new Int32Array(HEAP);
2346
- const HEAPF = this.gSampleSize === 4 ? new Float32Array(HEAP) : new Float64Array(HEAP);
2723
+ const HEAPF = this.fSampleSize === 4 ? new Float32Array(HEAP) : new Float64Array(HEAP);
2347
2724
  if (this.getNumInputs() > 0) {
2348
2725
  for (let chan = 0; chan < this.getNumInputs(); chan++) {
2349
- HEAP32[(this.fAudioInputs >> 2) + chan] = $audioInputs + this.fBufferSize * this.gSampleSize * chan;
2726
+ HEAP32[(this.fAudioInputs >> 2) + chan] = $audioInputs + this.fBufferSize * this.fSampleSize * chan;
2350
2727
  }
2351
- const dspInChans = HEAP32.subarray(this.fAudioInputs >> 2, this.fAudioInputs + this.getNumInputs() * this.gPtrSize >> 2);
2728
+ const dspInChans = HEAP32.subarray(this.fAudioInputs >> 2, this.fAudioInputs + this.getNumInputs() * this.fPtrSize >> 2);
2352
2729
  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));
2730
+ this.fInChannels[chan] = HEAPF.subarray(dspInChans[chan] >> Math.log2(this.fSampleSize), dspInChans[chan] + this.fBufferSize * this.fSampleSize >> Math.log2(this.fSampleSize));
2354
2731
  }
2355
2732
  }
2356
2733
  if (this.getNumOutputs() > 0) {
2357
2734
  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;
2735
+ HEAP32[(this.fAudioOutputs >> 2) + chan] = $audioOutputs + this.fBufferSize * this.fSampleSize * chan;
2736
+ HEAP32[(this.fAudioMixing >> 2) + chan] = $audioMixing + this.fBufferSize * this.fSampleSize * chan;
2737
+ HEAP32[(this.fAudioMixingHalf >> 2) + chan] = $audioMixing + this.fBufferSize * this.fSampleSize * chan + this.fBufferSize / 2 * this.fSampleSize;
2361
2738
  }
2362
- const dspOutChans = HEAP32.subarray(this.fAudioOutputs >> 2, this.fAudioOutputs + this.getNumOutputs() * this.gPtrSize >> 2);
2739
+ const dspOutChans = HEAP32.subarray(this.fAudioOutputs >> 2, this.fAudioOutputs + this.getNumOutputs() * this.fPtrSize >> 2);
2363
2740
  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));
2741
+ this.fOutChannels[chan] = HEAPF.subarray(dspOutChans[chan] >> Math.log2(this.fSampleSize), dspOutChans[chan] + this.fBufferSize * this.fSampleSize >> Math.log2(this.fSampleSize));
2365
2742
  }
2366
2743
  }
2744
+ return endMemory;
2367
2745
  }
2368
2746
  toString() {
2369
2747
  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}`;
2748
+ this.fBufferSize: ${this.fBufferSize}
2749
+ this.fJSONDsp.size: ${this.fJSONDsp.size}
2750
+ this.fAudioInputs: ${this.fAudioInputs}
2751
+ this.fAudioOutputs: ${this.fAudioOutputs}
2752
+ this.fAudioMixing: ${this.fAudioMixing}
2753
+ this.fAudioMixingHalf: ${this.fAudioMixingHalf}`;
2376
2754
  }
2377
2755
  allocVoice(voice, type) {
2378
2756
  this.fVoiceTable[voice].fDate++;
@@ -2426,6 +2804,10 @@ this.fAudioMixingHalf: ${this.fAudioMixingHalf}`;
2426
2804
  compute(input, output) {
2427
2805
  if (this.fDestroyed)
2428
2806
  return false;
2807
+ if (this.fFirstCall) {
2808
+ this.initMemory();
2809
+ this.fFirstCall = false;
2810
+ }
2429
2811
  if (!this.fProcessing)
2430
2812
  return true;
2431
2813
  if (this.getNumInputs() > 0 && (!input || !input[0] || input[0].length === 0)) {
@@ -2676,12 +3058,12 @@ var FaustOfflineProcessor = class {
2676
3058
  destroy() {
2677
3059
  this.fDSPCode.destroy();
2678
3060
  }
2679
- render(inputs = [], length = this.fBufferSize, onUpdate) {
3061
+ render(inputs = [], length2 = this.fBufferSize, onUpdate) {
2680
3062
  let l = 0;
2681
- const outputs = new Array(this.fDSPCode.getNumOutputs()).fill(null).map(() => new Float32Array(length));
3063
+ const outputs = new Array(this.fDSPCode.getNumOutputs()).fill(null).map(() => new Float32Array(length2));
2682
3064
  this.fDSPCode.start();
2683
- while (l < length) {
2684
- const sliceLength = Math.min(length - l, this.fBufferSize);
3065
+ while (l < length2) {
3066
+ const sliceLength = Math.min(length2 - l, this.fBufferSize);
2685
3067
  for (let i = 0; i < this.fDSPCode.getNumInputs(); i++) {
2686
3068
  let input;
2687
3069
  if (inputs[i]) {
@@ -2814,11 +3196,11 @@ var LibFaust_default = LibFaust;
2814
3196
  var WavEncoder = class {
2815
3197
  static encode(audioBuffer, options) {
2816
3198
  const numberOfChannels = audioBuffer.length;
2817
- const length = audioBuffer[0].length;
3199
+ const length2 = audioBuffer[0].length;
2818
3200
  const { shared, float } = options;
2819
3201
  const bitDepth = float ? 32 : options.bitDepth | 0 || 16;
2820
3202
  const byteDepth = bitDepth >> 3;
2821
- const byteLength = length * numberOfChannels * byteDepth;
3203
+ const byteLength = length2 * numberOfChannels * byteDepth;
2822
3204
  const AB = shared ? globalThis.SharedArrayBuffer || globalThis.ArrayBuffer : globalThis.ArrayBuffer;
2823
3205
  const ab = new AB((44 + byteLength) * Uint8Array.BYTES_PER_ELEMENT);
2824
3206
  const dataView = new DataView(ab);
@@ -2829,7 +3211,7 @@ var WavEncoder = class {
2829
3211
  numberOfChannels,
2830
3212
  sampleRate: options.sampleRate,
2831
3213
  symmetric: !!options.symmetric,
2832
- length,
3214
+ length: length2,
2833
3215
  bitDepth,
2834
3216
  byteDepth
2835
3217
  };
@@ -2838,7 +3220,7 @@ var WavEncoder = class {
2838
3220
  return ab;
2839
3221
  }
2840
3222
  static writeHeader(writer, format) {
2841
- const { formatId, sampleRate, bitDepth, numberOfChannels, length, byteDepth } = format;
3223
+ const { formatId, sampleRate, bitDepth, numberOfChannels, length: length2, byteDepth } = format;
2842
3224
  writer.string("RIFF");
2843
3225
  writer.uint32(writer.dataView.byteLength - 8);
2844
3226
  writer.string("WAVE");
@@ -2851,11 +3233,11 @@ var WavEncoder = class {
2851
3233
  writer.uint16(numberOfChannels * byteDepth);
2852
3234
  writer.uint16(bitDepth);
2853
3235
  writer.string("data");
2854
- writer.uint32(length * numberOfChannels * byteDepth);
3236
+ writer.uint32(length2 * numberOfChannels * byteDepth);
2855
3237
  return writer.pos;
2856
3238
  }
2857
3239
  static writeData(writer, audioBuffer, format) {
2858
- const { bitDepth, float, length, numberOfChannels, symmetric } = format;
3240
+ const { bitDepth, float, length: length2, numberOfChannels, symmetric } = format;
2859
3241
  if (bitDepth === 32 && float) {
2860
3242
  const { dataView, pos } = writer;
2861
3243
  const ab = dataView.buffer;
@@ -2866,7 +3248,7 @@ var WavEncoder = class {
2866
3248
  }
2867
3249
  for (let ch = 0; ch < numberOfChannels; ch++) {
2868
3250
  const channel = audioBuffer[ch];
2869
- for (let i = 0; i < length; i++) {
3251
+ for (let i = 0; i < length2; i++) {
2870
3252
  f32View[i * numberOfChannels + ch] = channel[i];
2871
3253
  }
2872
3254
  }
@@ -2878,7 +3260,7 @@ var WavEncoder = class {
2878
3260
  throw new TypeError("Not supported bit depth: " + bitDepth);
2879
3261
  }
2880
3262
  const write = writer[methodName].bind(writer);
2881
- for (let i = 0; i < length; i++) {
3263
+ for (let i = 0; i < length2; i++) {
2882
3264
  for (let j = 0; j < numberOfChannels; j++) {
2883
3265
  write(audioBuffer[j][i]);
2884
3266
  }
@@ -3034,24 +3416,24 @@ var WavDecoder = class {
3034
3416
  }
3035
3417
  static decodeData(reader, chunkSizeIn, format, options) {
3036
3418
  const chunkSize = Math.min(chunkSizeIn, reader.remain());
3037
- const length = Math.floor(chunkSize / format.blockSize);
3419
+ const length2 = Math.floor(chunkSize / format.blockSize);
3038
3420
  const numberOfChannels = format.numberOfChannels;
3039
3421
  const sampleRate = format.sampleRate;
3040
3422
  const channelData = new Array(numberOfChannels);
3041
3423
  for (let ch = 0; ch < numberOfChannels; ch++) {
3042
3424
  const AB = options.shared ? globalThis.SharedArrayBuffer || globalThis.ArrayBuffer : globalThis.ArrayBuffer;
3043
- const ab = new AB(length * Float32Array.BYTES_PER_ELEMENT);
3425
+ const ab = new AB(length2 * Float32Array.BYTES_PER_ELEMENT);
3044
3426
  channelData[ch] = new Float32Array(ab);
3045
3427
  }
3046
- this.readPCM(reader, channelData, length, format, options);
3428
+ this.readPCM(reader, channelData, length2, format, options);
3047
3429
  return {
3048
3430
  numberOfChannels,
3049
- length,
3431
+ length: length2,
3050
3432
  sampleRate,
3051
3433
  channelData
3052
3434
  };
3053
3435
  }
3054
- static readPCM(reader, channelData, length, format, options) {
3436
+ static readPCM(reader, channelData, length2, format, options) {
3055
3437
  const bitDepth = format.bitDepth;
3056
3438
  const decoderOption = format.float ? "f" : options.symmetric ? "s" : "";
3057
3439
  const methodName = "pcm" + bitDepth + decoderOption;
@@ -3060,7 +3442,7 @@ var WavDecoder = class {
3060
3442
  }
3061
3443
  const read = reader[methodName].bind(reader);
3062
3444
  const numberOfChannels = format.numberOfChannels;
3063
- for (let i = 0; i < length; i++) {
3445
+ for (let i = 0; i < length2; i++) {
3064
3446
  for (let ch = 0; ch < numberOfChannels; ch++) {
3065
3447
  channelData[ch][i] = read();
3066
3448
  }
@@ -3479,10 +3861,12 @@ var _FaustMonoDspGenerator = class {
3479
3861
  }
3480
3862
  async compile(compiler, name, code, args) {
3481
3863
  this.factory = await compiler.createMonoDSPFactory(name, code, args);
3482
- if (!this.factory)
3864
+ if (this.factory) {
3865
+ this.name = name;
3866
+ return this;
3867
+ } else {
3483
3868
  return null;
3484
- this.name = name;
3485
- return this;
3869
+ }
3486
3870
  }
3487
3871
  async createNode(context, name = this.name, factory = this.factory, sp = false, bufferSize = 1024, processorName = (factory == null ? void 0 : factory.shaKey) || name) {
3488
3872
  var _a, _b;
@@ -3493,6 +3877,7 @@ var _FaustMonoDspGenerator = class {
3493
3877
  if (sp) {
3494
3878
  const instance = await FaustWasmInstantiator_default.createAsyncMonoDSPInstance(factory);
3495
3879
  const monoDsp = new FaustMonoWebAudioDsp(instance, context.sampleRate, sampleSize, bufferSize);
3880
+ await monoDsp.init(context);
3496
3881
  const sp2 = context.createScriptProcessor(bufferSize, monoDsp.getNumInputs(), monoDsp.getNumOutputs());
3497
3882
  Object.setPrototypeOf(sp2, FaustMonoScriptProcessorNode.prototype);
3498
3883
  sp2.init(monoDsp);
@@ -3630,6 +4015,7 @@ const dependencies = {
3630
4015
  const instance = await FaustWasmInstantiator_default.createAsyncMonoDSPInstance(factory);
3631
4016
  const sampleSize = meta.compile_options.match("-double") ? 8 : 4;
3632
4017
  const monoDsp = new FaustMonoWebAudioDsp(instance, sampleRate, sampleSize, bufferSize);
4018
+ await monoDsp.init(null);
3633
4019
  return new FaustMonoOfflineProcessor(monoDsp, bufferSize);
3634
4020
  }
3635
4021
  getMeta() {
@@ -3727,6 +4113,7 @@ var _FaustPolyDspGenerator = class {
3727
4113
  if (sp) {
3728
4114
  const instance = await FaustWasmInstantiator_default.createAsyncPolyDSPInstance(voiceFactory, mixerModule, voices, effectFactory || void 0);
3729
4115
  const polyDsp = new FaustPolyWebAudioDsp(instance, context.sampleRate, sampleSize, bufferSize);
4116
+ await polyDsp.init(context);
3730
4117
  const sp2 = context.createScriptProcessor(bufferSize, polyDsp.getNumInputs(), polyDsp.getNumOutputs());
3731
4118
  Object.setPrototypeOf(sp2, FaustPolyScriptProcessorNode.prototype);
3732
4119
  sp2.init(polyDsp);