@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.
- 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 +146 -4
- package/assets/standalone/faustwasm/index.js +460 -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 +146 -4
- package/dist/cjs/index.js +460 -73
- package/dist/cjs/index.js.map +3 -3
- package/dist/cjs-bundle/index.d.ts +146 -4
- package/dist/cjs-bundle/index.js +561 -174
- package/dist/cjs-bundle/index.js.map +3 -3
- package/dist/esm/index.d.ts +146 -4
- package/dist/esm/index.js +460 -73
- package/dist/esm/index.js.map +3 -3
- package/dist/esm-bundle/index.d.ts +146 -4
- package/dist/esm-bundle/index.js +561 -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 +696 -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 +146 -4
- package/test/faustlive-wasm/faustwasm/index.js +460 -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,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.
|
|
2126
|
-
const $audioInputs = this.fAudioOutputs + this.getNumOutputs() * this.
|
|
2127
|
-
const $audioOutputs = $audioInputs + this.getNumInputs() * this.fBufferSize * this.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
2359
|
-
HEAP32[(this.fAudioMixing >> 2) + chan] = $audioMixing + this.fBufferSize * this.
|
|
2360
|
-
HEAP32[(this.fAudioMixingHalf >> 2) + chan] = $audioMixing + this.fBufferSize * this.
|
|
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.
|
|
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.
|
|
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 = [],
|
|
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(
|
|
3063
|
+
const outputs = new Array(this.fDSPCode.getNumOutputs()).fill(null).map(() => new Float32Array(length2));
|
|
2682
3064
|
this.fDSPCode.start();
|
|
2683
|
-
while (l <
|
|
2684
|
-
const sliceLength = Math.min(
|
|
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
|
|
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 =
|
|
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(
|
|
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 <
|
|
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 <
|
|
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
|
|
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(
|
|
3425
|
+
const ab = new AB(length2 * Float32Array.BYTES_PER_ELEMENT);
|
|
3044
3426
|
channelData[ch] = new Float32Array(ab);
|
|
3045
3427
|
}
|
|
3046
|
-
this.readPCM(reader, channelData,
|
|
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,
|
|
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 <
|
|
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 (
|
|
3864
|
+
if (this.factory) {
|
|
3865
|
+
this.name = name;
|
|
3866
|
+
return this;
|
|
3867
|
+
} else {
|
|
3483
3868
|
return null;
|
|
3484
|
-
|
|
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);
|