@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
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,57 @@ 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
+ extractURLsFromJSON() {
2318
+ const soundfilesEntry = this.fJSONDsp.meta.find((entry) => entry.soundfiles !== void 0);
2319
+ if (soundfilesEntry) {
2320
+ return soundfilesEntry.soundfiles.split(";").filter((url) => url !== "");
2321
+ } else {
2322
+ return [];
2323
+ }
2324
+ }
2325
+ async loadSoundfile(sfReader, sfOffset, name, url) {
2326
+ console.log(`Soundfile ${name} paths: ${url}`);
2327
+ const sfDirectories = ["", ".", "http://127.0.0.1:8000"];
2328
+ const sfReaderURLs = this.extractURLsFromJSON();
2329
+ console.log(`sfReaderURLs ${sfReaderURLs}`);
2330
+ sfDirectories.push(...sfReaderURLs);
2331
+ console.log(`sfDirectories ${sfDirectories}`);
2332
+ const sfPathNames = await sfReader.checkFiles(sfDirectories, FaustBaseWebAudioDsp.splitNames(url));
2333
+ console.log(`Soundfile ${name} paths: ${sfPathNames}`);
2334
+ const item = this.fSoundfiles.find((element) => element.url === url);
2335
+ if (item) {
2336
+ if (item.basePtr !== -1) {
2337
+ const HEAP32 = sfReader.getHEAP32();
2338
+ console.log(`Soundfile ${name} loaded at ${item.basePtr} in wasm memory with sfOffset ${sfOffset}`);
2339
+ console.log(`Soundfile CACHE ${url}}`);
2340
+ HEAP32[sfOffset >> 2] = item.basePtr;
2341
+ } else {
2342
+ const soundfile = await sfReader.createSoundfile(sfPathNames, MAX_CHAN, this.fSampleSize === 8);
2343
+ if (soundfile) {
2344
+ const HEAP32 = soundfile.getHEAP32();
2345
+ item.basePtr = soundfile.getPtr();
2346
+ console.log(`Soundfile ${name} loaded at ${item.basePtr} in wasm memory with sfOffset ${sfOffset}`);
2347
+ HEAP32[sfOffset >> 2] = item.basePtr;
2348
+ } else {
2349
+ console.log(`Soundfile ${name} for ${url} cannot be created !}`);
2350
+ }
2351
+ }
2352
+ } else {
2353
+ console.log(`Soundfile with ${url} cannot be found !}`);
2354
+ }
2355
+ }
2356
+ async initSoundfileMemory(allocator, sfReader, baseDSP) {
2357
+ let sfOffset = baseDSP;
2358
+ for (const { name, url } of this.fSoundfiles) {
2359
+ await this.loadSoundfile(sfReader, sfOffset, name, url);
2360
+ sfOffset += this.fPtrSize;
2361
+ }
2362
+ ;
2363
+ }
2013
2364
  updateOutputs() {
2014
2365
  if (this.fOutputsItems.length > 0 && this.fOutputHandler && this.fOutputsTimer-- === 0) {
2015
2366
  this.fOutputsTimer = 5;
@@ -2104,6 +2455,9 @@ export default ${(_b = jsCode.match(jsCodeHead)) == null ? void 0 : _b[1]};
2104
2455
  getDescriptors() {
2105
2456
  return this.fDescriptor;
2106
2457
  }
2458
+ hasSoundfiles() {
2459
+ return this.fSoundfiles.length > 0;
2460
+ }
2107
2461
  start() {
2108
2462
  this.fProcessing = true;
2109
2463
  }
@@ -2123,51 +2477,64 @@ export default ${(_b = jsCode.match(jsCodeHead)) == null ? void 0 : _b[1]};
2123
2477
  this.fInstance = instance;
2124
2478
  this.fJSONDsp = JSON.parse(this.fInstance.json);
2125
2479
  FaustBaseWebAudioDsp.parseUI(this.fJSONDsp.ui, this.fUICallback);
2126
- this.initMemory();
2480
+ this.fEndMemory = this.initMemory();
2127
2481
  this.fInstance.api.init(this.fDSP, sampleRate);
2128
2482
  }
2483
+ async init(context) {
2484
+ if (this.fSoundfiles.length > 0 && context) {
2485
+ const allocator = new WasmAllocator(this.fInstance.memory, this.fEndMemory);
2486
+ const sfReader = new SoundfileReader(allocator, context, this.fPtrSize, this.fSampleSize);
2487
+ await this.initSoundfileMemory(allocator, sfReader, this.fDSP);
2488
+ }
2489
+ }
2129
2490
  initMemory() {
2130
2491
  this.fDSP = 0;
2131
2492
  const $audio = this.fJSONDsp.size;
2132
2493
  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;
2494
+ this.fAudioOutputs = this.fAudioInputs + this.getNumInputs() * this.fPtrSize;
2495
+ const $audioInputs = this.fAudioOutputs + this.getNumOutputs() * this.fPtrSize;
2496
+ const $audioOutputs = $audioInputs + this.getNumInputs() * this.fBufferSize * this.fSampleSize;
2497
+ const endMemory = $audioOutputs + this.getNumOutputs() * this.fBufferSize * this.fSampleSize;
2136
2498
  const HEAP = this.fInstance.memory.buffer;
2137
2499
  const HEAP32 = new Int32Array(HEAP);
2138
- const HEAPF = this.gSampleSize === 4 ? new Float32Array(HEAP) : new Float64Array(HEAP);
2500
+ const HEAPF = this.fSampleSize === 4 ? new Float32Array(HEAP) : new Float64Array(HEAP);
2139
2501
  if (this.getNumInputs() > 0) {
2140
2502
  for (let chan = 0; chan < this.getNumInputs(); chan++) {
2141
- HEAP32[(this.fAudioInputs >> 2) + chan] = $audioInputs + this.fBufferSize * this.gSampleSize * chan;
2503
+ HEAP32[(this.fAudioInputs >> 2) + chan] = $audioInputs + this.fBufferSize * this.fSampleSize * chan;
2142
2504
  }
2143
- const dspInChans = HEAP32.subarray(this.fAudioInputs >> 2, this.fAudioInputs + this.getNumInputs() * this.gPtrSize >> 2);
2505
+ const dspInChans = HEAP32.subarray(this.fAudioInputs >> 2, this.fAudioInputs + this.getNumInputs() * this.fPtrSize >> 2);
2144
2506
  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));
2507
+ this.fInChannels[chan] = HEAPF.subarray(dspInChans[chan] >> Math.log2(this.fSampleSize), dspInChans[chan] + this.fBufferSize * this.fSampleSize >> Math.log2(this.fSampleSize));
2146
2508
  }
2147
2509
  }
2148
2510
  if (this.getNumOutputs() > 0) {
2149
2511
  for (let chan = 0; chan < this.getNumOutputs(); chan++) {
2150
- HEAP32[(this.fAudioOutputs >> 2) + chan] = $audioOutputs + this.fBufferSize * this.gSampleSize * chan;
2512
+ HEAP32[(this.fAudioOutputs >> 2) + chan] = $audioOutputs + this.fBufferSize * this.fSampleSize * chan;
2151
2513
  }
2152
- const dspOutChans = HEAP32.subarray(this.fAudioOutputs >> 2, this.fAudioOutputs + this.getNumOutputs() * this.gPtrSize >> 2);
2514
+ const dspOutChans = HEAP32.subarray(this.fAudioOutputs >> 2, this.fAudioOutputs + this.getNumOutputs() * this.fPtrSize >> 2);
2153
2515
  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));
2516
+ this.fOutChannels[chan] = HEAPF.subarray(dspOutChans[chan] >> Math.log2(this.fSampleSize), dspOutChans[chan] + this.fBufferSize * this.fSampleSize >> Math.log2(this.fSampleSize));
2155
2517
  }
2156
2518
  }
2519
+ return endMemory;
2157
2520
  }
2158
2521
  toString() {
2159
2522
  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}`;
2523
+ this.fBufferSize: ${this.fBufferSize}
2524
+ this.fJSONDsp.size: ${this.fJSONDsp.size}
2525
+ this.fAudioInputs: ${this.fAudioInputs}
2526
+ this.fAudioOutputs: ${this.fAudioOutputs}
2527
+ this.fDSP: ${this.fDSP}`;
2165
2528
  }
2166
2529
  compute(input, output) {
2167
2530
  if (this.fDestroyed)
2168
2531
  return false;
2169
2532
  if (!this.fProcessing)
2170
2533
  return true;
2534
+ if (this.fFirstCall) {
2535
+ this.initMemory();
2536
+ this.fFirstCall = false;
2537
+ }
2171
2538
  if (typeof input === "function") {
2172
2539
  input(this.fInChannels);
2173
2540
  } else {
@@ -2325,7 +2692,7 @@ this.fDSP: ${this.fDSP}`;
2325
2692
  FaustBaseWebAudioDsp.parseUI(this.fJSONDsp.ui, this.fUICallback);
2326
2693
  if (this.fJSONEffect)
2327
2694
  FaustBaseWebAudioDsp.parseUI(this.fJSONEffect.ui, this.fUICallback);
2328
- this.initMemory();
2695
+ this.fEndMemory = this.initMemory();
2329
2696
  this.fVoiceTable = [];
2330
2697
  for (let voice = 0; voice < this.fInstance.voices; voice++) {
2331
2698
  this.fVoiceTable.push(new FaustWebAudioDspVoice(
@@ -2339,48 +2706,59 @@ this.fDSP: ${this.fDSP}`;
2339
2706
  if (this.fInstance.effectAPI)
2340
2707
  this.fInstance.effectAPI.init(this.fEffect, sampleRate);
2341
2708
  }
2709
+ async init(context) {
2710
+ if (this.fSoundfiles.length > 0 && context) {
2711
+ const allocator = new WasmAllocator(this.fInstance.memory, this.fEndMemory);
2712
+ const sfReader = new SoundfileReader(allocator, context, this.fPtrSize, this.fSampleSize);
2713
+ for (let voice = 0; voice < this.fInstance.voices; voice++) {
2714
+ await this.initSoundfileMemory(allocator, sfReader, this.fJSONDsp.size * voice);
2715
+ }
2716
+ }
2717
+ }
2342
2718
  initMemory() {
2343
2719
  this.fEffect = this.fJSONDsp.size * this.fInstance.voices;
2344
2720
  const $audio = this.fEffect + (this.fJSONEffect ? this.fJSONEffect.size : 0);
2345
2721
  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;
2722
+ this.fAudioOutputs = this.fAudioInputs + this.getNumInputs() * this.fPtrSize;
2723
+ this.fAudioMixing = this.fAudioOutputs + this.getNumOutputs() * this.fPtrSize;
2724
+ this.fAudioMixingHalf = this.fAudioMixing + this.getNumOutputs() * this.fPtrSize;
2725
+ const $audioInputs = this.fAudioMixingHalf + this.getNumOutputs() * this.fPtrSize;
2726
+ const $audioOutputs = $audioInputs + this.getNumInputs() * this.fBufferSize * this.fSampleSize;
2727
+ const $audioMixing = $audioOutputs + this.getNumOutputs() * this.fBufferSize * this.fSampleSize;
2728
+ const endMemory = $audioMixing + this.getNumOutputs() * this.fBufferSize * this.fSampleSize;
2352
2729
  const HEAP = this.fInstance.memory.buffer;
2353
2730
  const HEAP32 = new Int32Array(HEAP);
2354
- const HEAPF = this.gSampleSize === 4 ? new Float32Array(HEAP) : new Float64Array(HEAP);
2731
+ const HEAPF = this.fSampleSize === 4 ? new Float32Array(HEAP) : new Float64Array(HEAP);
2355
2732
  if (this.getNumInputs() > 0) {
2356
2733
  for (let chan = 0; chan < this.getNumInputs(); chan++) {
2357
- HEAP32[(this.fAudioInputs >> 2) + chan] = $audioInputs + this.fBufferSize * this.gSampleSize * chan;
2734
+ HEAP32[(this.fAudioInputs >> 2) + chan] = $audioInputs + this.fBufferSize * this.fSampleSize * chan;
2358
2735
  }
2359
- const dspInChans = HEAP32.subarray(this.fAudioInputs >> 2, this.fAudioInputs + this.getNumInputs() * this.gPtrSize >> 2);
2736
+ const dspInChans = HEAP32.subarray(this.fAudioInputs >> 2, this.fAudioInputs + this.getNumInputs() * this.fPtrSize >> 2);
2360
2737
  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));
2738
+ this.fInChannels[chan] = HEAPF.subarray(dspInChans[chan] >> Math.log2(this.fSampleSize), dspInChans[chan] + this.fBufferSize * this.fSampleSize >> Math.log2(this.fSampleSize));
2362
2739
  }
2363
2740
  }
2364
2741
  if (this.getNumOutputs() > 0) {
2365
2742
  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;
2743
+ HEAP32[(this.fAudioOutputs >> 2) + chan] = $audioOutputs + this.fBufferSize * this.fSampleSize * chan;
2744
+ HEAP32[(this.fAudioMixing >> 2) + chan] = $audioMixing + this.fBufferSize * this.fSampleSize * chan;
2745
+ HEAP32[(this.fAudioMixingHalf >> 2) + chan] = $audioMixing + this.fBufferSize * this.fSampleSize * chan + this.fBufferSize / 2 * this.fSampleSize;
2369
2746
  }
2370
- const dspOutChans = HEAP32.subarray(this.fAudioOutputs >> 2, this.fAudioOutputs + this.getNumOutputs() * this.gPtrSize >> 2);
2747
+ const dspOutChans = HEAP32.subarray(this.fAudioOutputs >> 2, this.fAudioOutputs + this.getNumOutputs() * this.fPtrSize >> 2);
2371
2748
  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));
2749
+ this.fOutChannels[chan] = HEAPF.subarray(dspOutChans[chan] >> Math.log2(this.fSampleSize), dspOutChans[chan] + this.fBufferSize * this.fSampleSize >> Math.log2(this.fSampleSize));
2373
2750
  }
2374
2751
  }
2752
+ return endMemory;
2375
2753
  }
2376
2754
  toString() {
2377
2755
  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}`;
2756
+ this.fBufferSize: ${this.fBufferSize}
2757
+ this.fJSONDsp.size: ${this.fJSONDsp.size}
2758
+ this.fAudioInputs: ${this.fAudioInputs}
2759
+ this.fAudioOutputs: ${this.fAudioOutputs}
2760
+ this.fAudioMixing: ${this.fAudioMixing}
2761
+ this.fAudioMixingHalf: ${this.fAudioMixingHalf}`;
2384
2762
  }
2385
2763
  allocVoice(voice, type) {
2386
2764
  this.fVoiceTable[voice].fDate++;
@@ -2434,6 +2812,10 @@ this.fAudioMixingHalf: ${this.fAudioMixingHalf}`;
2434
2812
  compute(input, output) {
2435
2813
  if (this.fDestroyed)
2436
2814
  return false;
2815
+ if (this.fFirstCall) {
2816
+ this.initMemory();
2817
+ this.fFirstCall = false;
2818
+ }
2437
2819
  if (!this.fProcessing)
2438
2820
  return true;
2439
2821
  if (this.getNumInputs() > 0 && (!input || !input[0] || input[0].length === 0)) {
@@ -2684,12 +3066,12 @@ this.fAudioMixingHalf: ${this.fAudioMixingHalf}`;
2684
3066
  destroy() {
2685
3067
  this.fDSPCode.destroy();
2686
3068
  }
2687
- render(inputs = [], length = this.fBufferSize, onUpdate) {
3069
+ render(inputs = [], length2 = this.fBufferSize, onUpdate) {
2688
3070
  let l = 0;
2689
- const outputs = new Array(this.fDSPCode.getNumOutputs()).fill(null).map(() => new Float32Array(length));
3071
+ const outputs = new Array(this.fDSPCode.getNumOutputs()).fill(null).map(() => new Float32Array(length2));
2690
3072
  this.fDSPCode.start();
2691
- while (l < length) {
2692
- const sliceLength = Math.min(length - l, this.fBufferSize);
3073
+ while (l < length2) {
3074
+ const sliceLength = Math.min(length2 - l, this.fBufferSize);
2693
3075
  for (let i = 0; i < this.fDSPCode.getNumInputs(); i++) {
2694
3076
  let input;
2695
3077
  if (inputs[i]) {
@@ -2822,11 +3204,11 @@ this.fAudioMixingHalf: ${this.fAudioMixingHalf}`;
2822
3204
  var WavEncoder = class {
2823
3205
  static encode(audioBuffer, options) {
2824
3206
  const numberOfChannels = audioBuffer.length;
2825
- const length = audioBuffer[0].length;
3207
+ const length2 = audioBuffer[0].length;
2826
3208
  const { shared, float } = options;
2827
3209
  const bitDepth = float ? 32 : options.bitDepth | 0 || 16;
2828
3210
  const byteDepth = bitDepth >> 3;
2829
- const byteLength = length * numberOfChannels * byteDepth;
3211
+ const byteLength = length2 * numberOfChannels * byteDepth;
2830
3212
  const AB = shared ? globalThis.SharedArrayBuffer || globalThis.ArrayBuffer : globalThis.ArrayBuffer;
2831
3213
  const ab = new AB((44 + byteLength) * Uint8Array.BYTES_PER_ELEMENT);
2832
3214
  const dataView = new DataView(ab);
@@ -2837,7 +3219,7 @@ this.fAudioMixingHalf: ${this.fAudioMixingHalf}`;
2837
3219
  numberOfChannels,
2838
3220
  sampleRate: options.sampleRate,
2839
3221
  symmetric: !!options.symmetric,
2840
- length,
3222
+ length: length2,
2841
3223
  bitDepth,
2842
3224
  byteDepth
2843
3225
  };
@@ -2846,7 +3228,7 @@ this.fAudioMixingHalf: ${this.fAudioMixingHalf}`;
2846
3228
  return ab;
2847
3229
  }
2848
3230
  static writeHeader(writer, format) {
2849
- const { formatId, sampleRate, bitDepth, numberOfChannels, length, byteDepth } = format;
3231
+ const { formatId, sampleRate, bitDepth, numberOfChannels, length: length2, byteDepth } = format;
2850
3232
  writer.string("RIFF");
2851
3233
  writer.uint32(writer.dataView.byteLength - 8);
2852
3234
  writer.string("WAVE");
@@ -2859,11 +3241,11 @@ this.fAudioMixingHalf: ${this.fAudioMixingHalf}`;
2859
3241
  writer.uint16(numberOfChannels * byteDepth);
2860
3242
  writer.uint16(bitDepth);
2861
3243
  writer.string("data");
2862
- writer.uint32(length * numberOfChannels * byteDepth);
3244
+ writer.uint32(length2 * numberOfChannels * byteDepth);
2863
3245
  return writer.pos;
2864
3246
  }
2865
3247
  static writeData(writer, audioBuffer, format) {
2866
- const { bitDepth, float, length, numberOfChannels, symmetric } = format;
3248
+ const { bitDepth, float, length: length2, numberOfChannels, symmetric } = format;
2867
3249
  if (bitDepth === 32 && float) {
2868
3250
  const { dataView, pos } = writer;
2869
3251
  const ab = dataView.buffer;
@@ -2874,7 +3256,7 @@ this.fAudioMixingHalf: ${this.fAudioMixingHalf}`;
2874
3256
  }
2875
3257
  for (let ch = 0; ch < numberOfChannels; ch++) {
2876
3258
  const channel = audioBuffer[ch];
2877
- for (let i = 0; i < length; i++) {
3259
+ for (let i = 0; i < length2; i++) {
2878
3260
  f32View[i * numberOfChannels + ch] = channel[i];
2879
3261
  }
2880
3262
  }
@@ -2886,7 +3268,7 @@ this.fAudioMixingHalf: ${this.fAudioMixingHalf}`;
2886
3268
  throw new TypeError("Not supported bit depth: " + bitDepth);
2887
3269
  }
2888
3270
  const write = writer[methodName].bind(writer);
2889
- for (let i = 0; i < length; i++) {
3271
+ for (let i = 0; i < length2; i++) {
2890
3272
  for (let j = 0; j < numberOfChannels; j++) {
2891
3273
  write(audioBuffer[j][i]);
2892
3274
  }
@@ -3042,24 +3424,24 @@ this.fAudioMixingHalf: ${this.fAudioMixingHalf}`;
3042
3424
  }
3043
3425
  static decodeData(reader, chunkSizeIn, format, options) {
3044
3426
  const chunkSize = Math.min(chunkSizeIn, reader.remain());
3045
- const length = Math.floor(chunkSize / format.blockSize);
3427
+ const length2 = Math.floor(chunkSize / format.blockSize);
3046
3428
  const numberOfChannels = format.numberOfChannels;
3047
3429
  const sampleRate = format.sampleRate;
3048
3430
  const channelData = new Array(numberOfChannels);
3049
3431
  for (let ch = 0; ch < numberOfChannels; ch++) {
3050
3432
  const AB = options.shared ? globalThis.SharedArrayBuffer || globalThis.ArrayBuffer : globalThis.ArrayBuffer;
3051
- const ab = new AB(length * Float32Array.BYTES_PER_ELEMENT);
3433
+ const ab = new AB(length2 * Float32Array.BYTES_PER_ELEMENT);
3052
3434
  channelData[ch] = new Float32Array(ab);
3053
3435
  }
3054
- this.readPCM(reader, channelData, length, format, options);
3436
+ this.readPCM(reader, channelData, length2, format, options);
3055
3437
  return {
3056
3438
  numberOfChannels,
3057
- length,
3439
+ length: length2,
3058
3440
  sampleRate,
3059
3441
  channelData
3060
3442
  };
3061
3443
  }
3062
- static readPCM(reader, channelData, length, format, options) {
3444
+ static readPCM(reader, channelData, length2, format, options) {
3063
3445
  const bitDepth = format.bitDepth;
3064
3446
  const decoderOption = format.float ? "f" : options.symmetric ? "s" : "";
3065
3447
  const methodName = "pcm" + bitDepth + decoderOption;
@@ -3068,7 +3450,7 @@ this.fAudioMixingHalf: ${this.fAudioMixingHalf}`;
3068
3450
  }
3069
3451
  const read = reader[methodName].bind(reader);
3070
3452
  const numberOfChannels = format.numberOfChannels;
3071
- for (let i = 0; i < length; i++) {
3453
+ for (let i = 0; i < length2; i++) {
3072
3454
  for (let ch = 0; ch < numberOfChannels; ch++) {
3073
3455
  channelData[ch][i] = read();
3074
3456
  }
@@ -3487,10 +3869,12 @@ this.fAudioMixingHalf: ${this.fAudioMixingHalf}`;
3487
3869
  }
3488
3870
  async compile(compiler, name, code, args) {
3489
3871
  this.factory = await compiler.createMonoDSPFactory(name, code, args);
3490
- if (!this.factory)
3872
+ if (this.factory) {
3873
+ this.name = name;
3874
+ return this;
3875
+ } else {
3491
3876
  return null;
3492
- this.name = name;
3493
- return this;
3877
+ }
3494
3878
  }
3495
3879
  async createNode(context, name = this.name, factory = this.factory, sp = false, bufferSize = 1024, processorName = (factory == null ? void 0 : factory.shaKey) || name) {
3496
3880
  var _a, _b;
@@ -3501,6 +3885,7 @@ this.fAudioMixingHalf: ${this.fAudioMixingHalf}`;
3501
3885
  if (sp) {
3502
3886
  const instance = await FaustWasmInstantiator_default.createAsyncMonoDSPInstance(factory);
3503
3887
  const monoDsp = new FaustMonoWebAudioDsp(instance, context.sampleRate, sampleSize, bufferSize);
3888
+ await monoDsp.init(context);
3504
3889
  const sp2 = context.createScriptProcessor(bufferSize, monoDsp.getNumInputs(), monoDsp.getNumOutputs());
3505
3890
  Object.setPrototypeOf(sp2, FaustMonoScriptProcessorNode.prototype);
3506
3891
  sp2.init(monoDsp);
@@ -3638,6 +4023,7 @@ const dependencies = {
3638
4023
  const instance = await FaustWasmInstantiator_default.createAsyncMonoDSPInstance(factory);
3639
4024
  const sampleSize = meta.compile_options.match("-double") ? 8 : 4;
3640
4025
  const monoDsp = new FaustMonoWebAudioDsp(instance, sampleRate, sampleSize, bufferSize);
4026
+ await monoDsp.init(null);
3641
4027
  return new FaustMonoOfflineProcessor(monoDsp, bufferSize);
3642
4028
  }
3643
4029
  getMeta() {
@@ -3735,6 +4121,7 @@ const dependencies = {
3735
4121
  if (sp) {
3736
4122
  const instance = await FaustWasmInstantiator_default.createAsyncPolyDSPInstance(voiceFactory, mixerModule, voices, effectFactory || void 0);
3737
4123
  const polyDsp = new FaustPolyWebAudioDsp(instance, context.sampleRate, sampleSize, bufferSize);
4124
+ await polyDsp.init(context);
3738
4125
  const sp2 = context.createScriptProcessor(bufferSize, polyDsp.getNumInputs(), polyDsp.getNumOutputs());
3739
4126
  Object.setPrototypeOf(sp2, FaustPolyScriptProcessorNode.prototype);
3740
4127
  sp2.init(polyDsp);