@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.
- package/README.md +1 -1
- package/assets/standalone/faust-ui/index.css +17 -0
- package/assets/standalone/faust-ui/index.css.map +1 -1
- package/assets/standalone/faust-ui/index.js +294 -47
- package/assets/standalone/faust-ui/index.js.map +1 -1
- package/assets/standalone/faustwasm/index.d.ts +145 -4
- package/assets/standalone/faustwasm/index.js +449 -73
- package/assets/standalone/faustwasm/index.js.map +3 -3
- package/assets/standalone/index-poly.js +9 -6
- package/assets/standalone/index.js +9 -6
- package/dist/cjs/index.d.ts +145 -4
- package/dist/cjs/index.js +449 -73
- package/dist/cjs/index.js.map +3 -3
- package/dist/cjs-bundle/index.d.ts +145 -4
- package/dist/cjs-bundle/index.js +550 -174
- package/dist/cjs-bundle/index.js.map +3 -3
- package/dist/esm/index.d.ts +145 -4
- package/dist/esm/index.js +449 -73
- package/dist/esm/index.js.map +3 -3
- package/dist/esm-bundle/index.d.ts +145 -4
- package/dist/esm-bundle/index.js +550 -174
- package/dist/esm-bundle/index.js.map +3 -3
- package/libfaust-wasm/libfaust-wasm.data +0 -0
- package/libfaust-wasm/libfaust-wasm.js +1 -1
- package/libfaust-wasm/libfaust-wasm.wasm +0 -0
- package/package.json +2 -2
- package/src/FaustAudioWorkletProcessor.ts +16 -3
- package/src/FaustDspGenerator.ts +18 -3
- package/src/FaustWasmInstantiator.ts +62 -26
- package/src/FaustWebAudioDsp.ts +682 -51
- package/src/faust2wasmFiles.js +6 -4
- package/test/faustlive-wasm/faust-ui/index.css +17 -0
- package/test/faustlive-wasm/faust-ui/index.css.map +1 -1
- package/test/faustlive-wasm/faust-ui/index.js +294 -47
- package/test/faustlive-wasm/faust-ui/index.js.map +1 -1
- package/test/faustlive-wasm/faustwasm/index.d.ts +145 -4
- package/test/faustlive-wasm/faustwasm/index.js +449 -73
- package/test/faustlive-wasm/faustwasm/index.js.map +3 -3
- package/TODO.md +0 -5
- package/test/tp0.dsp +0 -17
- package/test/tp0.dsp.json +0 -30
- 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
|
|
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
|
|
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
|
|
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.
|
|
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
|
|
1868
|
-
|
|
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
|
|
1872
|
-
|
|
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.
|
|
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.
|
|
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.
|
|
1947
|
-
this.
|
|
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.
|
|
2126
|
-
const $audioInputs = this.fAudioOutputs + this.getNumOutputs() * this.
|
|
2127
|
-
const $audioOutputs = $audioInputs + this.getNumInputs() * this.fBufferSize * this.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
2339
|
-
this.fAudioMixing = this.fAudioOutputs + this.getNumOutputs() * this.
|
|
2340
|
-
this.fAudioMixingHalf = this.fAudioMixing + this.getNumOutputs() * this.
|
|
2341
|
-
const $audioInputs = this.fAudioMixingHalf + this.getNumOutputs() * this.
|
|
2342
|
-
const $audioOutputs = $audioInputs + this.getNumInputs() * this.fBufferSize * this.
|
|
2343
|
-
const $audioMixing = $audioOutputs + this.getNumOutputs() * this.fBufferSize * this.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
2359
|
-
HEAP32[(this.fAudioMixing >> 2) + chan] = $audioMixing + this.fBufferSize * this.
|
|
2360
|
-
HEAP32[(this.fAudioMixingHalf >> 2) + chan] = $audioMixing + this.fBufferSize * this.
|
|
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.
|
|
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.
|
|
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 = [],
|
|
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(
|
|
3052
|
+
const outputs = new Array(this.fDSPCode.getNumOutputs()).fill(null).map(() => new Float32Array(length2));
|
|
2682
3053
|
this.fDSPCode.start();
|
|
2683
|
-
while (l <
|
|
2684
|
-
const sliceLength = Math.min(
|
|
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
|
|
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 =
|
|
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(
|
|
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 <
|
|
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 <
|
|
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
|
|
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(
|
|
3414
|
+
const ab = new AB(length2 * Float32Array.BYTES_PER_ELEMENT);
|
|
3044
3415
|
channelData[ch] = new Float32Array(ab);
|
|
3045
3416
|
}
|
|
3046
|
-
this.readPCM(reader, channelData,
|
|
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,
|
|
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 <
|
|
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 (
|
|
3853
|
+
if (this.factory) {
|
|
3854
|
+
this.name = name;
|
|
3855
|
+
return this;
|
|
3856
|
+
} else {
|
|
3483
3857
|
return null;
|
|
3484
|
-
|
|
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);
|