@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
package/dist/cjs/index.js
CHANGED
|
@@ -1068,6 +1068,10 @@ export default ${(_b = jsCode.match(jsCodeHead)) == null ? void 0 : _b[1]};
|
|
|
1068
1068
|
const { factory, sampleSize } = options.processorOptions;
|
|
1069
1069
|
const instance = FaustWasmInstantiator2.createSyncMonoDSPInstance(factory);
|
|
1070
1070
|
this.fDSPCode = new FaustMonoWebAudioDsp2(instance, sampleRate, sampleSize, 128);
|
|
1071
|
+
if (this.fDSPCode.hasSoundfiles()) {
|
|
1072
|
+
console.error("FaustAudioWorkletProcessor: Soundfile support is not implemented yet, switch to ScriptProcessorNode for now");
|
|
1073
|
+
return;
|
|
1074
|
+
}
|
|
1071
1075
|
this.fDSPCode.setOutputParamHandler((path, value) => this.port.postMessage({ path, value, type: "param" }));
|
|
1072
1076
|
this.fDSPCode.start();
|
|
1073
1077
|
}
|
|
@@ -1093,6 +1097,10 @@ export default ${(_b = jsCode.match(jsCodeHead)) == null ? void 0 : _b[1]};
|
|
|
1093
1097
|
const { voiceFactory, mixerModule, voices, effectFactory, sampleSize } = options.processorOptions;
|
|
1094
1098
|
const instance = FaustWasmInstantiator2.createSyncPolyDSPInstance(voiceFactory, mixerModule, voices, effectFactory);
|
|
1095
1099
|
this.fDSPCode = new FaustPolyWebAudioDsp3(instance, sampleRate, sampleSize, 128);
|
|
1100
|
+
if (this.fDSPCode.hasSoundfiles()) {
|
|
1101
|
+
console.error("FaustAudioWorkletProcessor: Soundfile support is not implemented yet, switch to ScriptProcessorNode for now");
|
|
1102
|
+
return;
|
|
1103
|
+
}
|
|
1096
1104
|
this.port.onmessage = (e) => this.handleMessageAux(e);
|
|
1097
1105
|
this.fDSPCode.setOutputParamHandler((path, value) => this.port.postMessage({ path, value, type: "param" }));
|
|
1098
1106
|
this.fDSPCode.start();
|
|
@@ -1801,7 +1809,7 @@ export default ${(_b = jsCode.match(jsCodeHead)) == null ? void 0 : _b[1]};
|
|
|
1801
1809
|
}
|
|
1802
1810
|
};
|
|
1803
1811
|
}
|
|
1804
|
-
static
|
|
1812
|
+
static createWasmMemoryPoly(voicesIn, sampleSize, dspMeta, effectMeta, bufferSize) {
|
|
1805
1813
|
const voices = Math.max(4, voicesIn);
|
|
1806
1814
|
const ptrSize = sampleSize;
|
|
1807
1815
|
const pow2limit = (x) => {
|
|
@@ -1816,19 +1824,29 @@ export default ${(_b = jsCode.match(jsCodeHead)) == null ? void 0 : _b[1]};
|
|
|
1816
1824
|
effectSize + dspMeta.size * voices + (dspMeta.inputs + dspMeta.outputs * 2) * (ptrSize + bufferSize * sampleSize)
|
|
1817
1825
|
) / 65536;
|
|
1818
1826
|
memorySize = Math.max(2, memorySize);
|
|
1819
|
-
return new WebAssembly.Memory({ initial: memorySize
|
|
1827
|
+
return new WebAssembly.Memory({ initial: memorySize });
|
|
1828
|
+
}
|
|
1829
|
+
static createWasmMemoryMono(sampleSize, dspMeta, bufferSize) {
|
|
1830
|
+
const ptrSize = sampleSize;
|
|
1831
|
+
const memorySize = (dspMeta.size + (dspMeta.inputs + dspMeta.outputs) * (ptrSize + bufferSize * sampleSize)) / 65536;
|
|
1832
|
+
return new WebAssembly.Memory({ initial: memorySize * 2 });
|
|
1820
1833
|
}
|
|
1821
|
-
static createMonoDSPInstanceAux(instance, json) {
|
|
1834
|
+
static createMonoDSPInstanceAux(instance, json, mem = null) {
|
|
1822
1835
|
const functions = instance.exports;
|
|
1823
1836
|
const api = new FaustDspInstance(functions);
|
|
1824
|
-
const memory = instance.exports.memory;
|
|
1837
|
+
const memory = mem ? mem : instance.exports.memory;
|
|
1825
1838
|
return { memory, api, json };
|
|
1826
1839
|
}
|
|
1827
|
-
static
|
|
1840
|
+
static createMemoryMono(monoFactory) {
|
|
1841
|
+
const monoMeta = JSON.parse(monoFactory.json);
|
|
1842
|
+
const sampleSize = monoMeta.compile_options.match("-double") ? 8 : 4;
|
|
1843
|
+
return this.createWasmMemoryMono(sampleSize, monoMeta, 8192);
|
|
1844
|
+
}
|
|
1845
|
+
static createMemoryPoly(voices, voiceFactory, effectFactory) {
|
|
1828
1846
|
const voiceMeta = JSON.parse(voiceFactory.json);
|
|
1829
1847
|
const effectMeta = effectFactory && effectFactory.json ? JSON.parse(effectFactory.json) : null;
|
|
1830
1848
|
const sampleSize = voiceMeta.compile_options.match("-double") ? 8 : 4;
|
|
1831
|
-
return this.
|
|
1849
|
+
return this.createWasmMemoryPoly(voices, sampleSize, voiceMeta, effectMeta, 8192);
|
|
1832
1850
|
}
|
|
1833
1851
|
static createMixerAux(mixerModule, memory) {
|
|
1834
1852
|
const mixerImport = {
|
|
@@ -1872,15 +1890,35 @@ export default ${(_b = jsCode.match(jsCodeHead)) == null ? void 0 : _b[1]};
|
|
|
1872
1890
|
}
|
|
1873
1891
|
}
|
|
1874
1892
|
static async createAsyncMonoDSPInstance(factory) {
|
|
1875
|
-
const
|
|
1876
|
-
|
|
1893
|
+
const parsedJson = JSON.parse(factory.json);
|
|
1894
|
+
if (Array.isArray(parsedJson.ui) && parsedJson.ui.some((group) => {
|
|
1895
|
+
var _a;
|
|
1896
|
+
return (_a = group.items) == null ? void 0 : _a.some((item) => item.type === "soundfile");
|
|
1897
|
+
})) {
|
|
1898
|
+
const memory = this.createMemoryMono(factory);
|
|
1899
|
+
const instance = await WebAssembly.instantiate(factory.module, this.createWasmImport(memory));
|
|
1900
|
+
return this.createMonoDSPInstanceAux(instance, factory.json, memory);
|
|
1901
|
+
} else {
|
|
1902
|
+
const instance = await WebAssembly.instantiate(factory.module, this.createWasmImport());
|
|
1903
|
+
return this.createMonoDSPInstanceAux(instance, factory.json);
|
|
1904
|
+
}
|
|
1877
1905
|
}
|
|
1878
1906
|
static createSyncMonoDSPInstance(factory) {
|
|
1879
|
-
const
|
|
1880
|
-
|
|
1907
|
+
const parsedJson = JSON.parse(factory.json);
|
|
1908
|
+
if (Array.isArray(parsedJson.ui) && parsedJson.ui.some((group) => {
|
|
1909
|
+
var _a;
|
|
1910
|
+
return (_a = group.items) == null ? void 0 : _a.some((item) => item.type === "soundfile");
|
|
1911
|
+
})) {
|
|
1912
|
+
const memory = this.createMemoryMono(factory);
|
|
1913
|
+
const instance = new WebAssembly.Instance(factory.module, this.createWasmImport(memory));
|
|
1914
|
+
return this.createMonoDSPInstanceAux(instance, factory.json, memory);
|
|
1915
|
+
} else {
|
|
1916
|
+
const instance = new WebAssembly.Instance(factory.module, this.createWasmImport());
|
|
1917
|
+
return this.createMonoDSPInstanceAux(instance, factory.json);
|
|
1918
|
+
}
|
|
1881
1919
|
}
|
|
1882
1920
|
static async createAsyncPolyDSPInstance(voiceFactory, mixerModule, voices, effectFactory) {
|
|
1883
|
-
const memory = this.
|
|
1921
|
+
const memory = this.createMemoryPoly(voices, voiceFactory, effectFactory);
|
|
1884
1922
|
const voiceInstance = await WebAssembly.instantiate(voiceFactory.module, this.createWasmImport(memory));
|
|
1885
1923
|
const voiceFunctions = voiceInstance.exports;
|
|
1886
1924
|
const voiceAPI = new FaustDspInstance(voiceFunctions);
|
|
@@ -1909,7 +1947,7 @@ export default ${(_b = jsCode.match(jsCodeHead)) == null ? void 0 : _b[1]};
|
|
|
1909
1947
|
}
|
|
1910
1948
|
}
|
|
1911
1949
|
static createSyncPolyDSPInstance(voiceFactory, mixerModule, voices, effectFactory) {
|
|
1912
|
-
const memory = this.
|
|
1950
|
+
const memory = this.createMemoryPoly(voices, voiceFactory, effectFactory);
|
|
1913
1951
|
const voiceInstance = new WebAssembly.Instance(voiceFactory.module, this.createWasmImport(memory));
|
|
1914
1952
|
const voiceFunctions = voiceInstance.exports;
|
|
1915
1953
|
const voiceAPI = new FaustDspInstance(voiceFunctions);
|
|
@@ -1941,6 +1979,264 @@ export default ${(_b = jsCode.match(jsCodeHead)) == null ? void 0 : _b[1]};
|
|
|
1941
1979
|
var FaustWasmInstantiator_default = FaustWasmInstantiator;
|
|
1942
1980
|
|
|
1943
1981
|
// src/FaustWebAudioDsp.ts
|
|
1982
|
+
var WasmAllocator = class {
|
|
1983
|
+
constructor(memory, offset) {
|
|
1984
|
+
this.memory = memory;
|
|
1985
|
+
this.allocatedBytes = offset;
|
|
1986
|
+
}
|
|
1987
|
+
alloc(sizeInBytes) {
|
|
1988
|
+
const currentOffset = this.allocatedBytes;
|
|
1989
|
+
const newOffset = currentOffset + sizeInBytes;
|
|
1990
|
+
const totalMemoryBytes = this.memory.buffer.byteLength;
|
|
1991
|
+
if (newOffset > totalMemoryBytes) {
|
|
1992
|
+
const neededPages = Math.ceil((newOffset - totalMemoryBytes) / 65536);
|
|
1993
|
+
console.log(`GROW: ${neededPages} pages`);
|
|
1994
|
+
this.memory.grow(neededPages);
|
|
1995
|
+
}
|
|
1996
|
+
this.allocatedBytes = newOffset;
|
|
1997
|
+
return currentOffset;
|
|
1998
|
+
}
|
|
1999
|
+
getBuffer() {
|
|
2000
|
+
return this.memory.buffer;
|
|
2001
|
+
}
|
|
2002
|
+
getInt32Array() {
|
|
2003
|
+
return new Int32Array(this.memory.buffer);
|
|
2004
|
+
}
|
|
2005
|
+
getFloat32Array() {
|
|
2006
|
+
return new Float32Array(this.memory.buffer);
|
|
2007
|
+
}
|
|
2008
|
+
getFloat64Array() {
|
|
2009
|
+
return new Float64Array(this.memory.buffer);
|
|
2010
|
+
}
|
|
2011
|
+
};
|
|
2012
|
+
var MAX_SOUNDFILE_PARTS = 256;
|
|
2013
|
+
var MAX_CHAN = 64;
|
|
2014
|
+
var BUFFER_SIZE = 1024;
|
|
2015
|
+
var SAMPLE_RATE = 44100;
|
|
2016
|
+
var intSize = 4;
|
|
2017
|
+
var Soundfile = class {
|
|
2018
|
+
constructor(allocator, ptrSize, sampleSize, curChan, length2, maxChan, totalParts) {
|
|
2019
|
+
this.fSampleSize = sampleSize;
|
|
2020
|
+
this.fPtrSize = ptrSize;
|
|
2021
|
+
this.fAllocator = allocator;
|
|
2022
|
+
this.fPtr = allocator.alloc(4 * ptrSize);
|
|
2023
|
+
this.fLength = allocator.alloc(MAX_SOUNDFILE_PARTS * intSize);
|
|
2024
|
+
this.fSR = allocator.alloc(MAX_SOUNDFILE_PARTS * intSize);
|
|
2025
|
+
this.fOffset = allocator.alloc(MAX_SOUNDFILE_PARTS * intSize);
|
|
2026
|
+
this.fBuffers = this.allocBuffers(curChan, length2, maxChan);
|
|
2027
|
+
const HEAP32 = this.fAllocator.getInt32Array();
|
|
2028
|
+
HEAP32[this.fPtr >> 2] = this.fBuffers;
|
|
2029
|
+
HEAP32[this.fPtr + ptrSize >> 2] = this.fLength;
|
|
2030
|
+
HEAP32[this.fPtr + 2 * ptrSize >> 2] = this.fSR;
|
|
2031
|
+
HEAP32[this.fPtr + 3 * ptrSize >> 2] = this.fOffset;
|
|
2032
|
+
for (let chan = 0; chan < curChan; chan++) {
|
|
2033
|
+
const buffer = HEAP32[(this.fBuffers >> 2) + chan];
|
|
2034
|
+
console.log(`allocBuffers AFTER: ${chan} - ${buffer}`);
|
|
2035
|
+
}
|
|
2036
|
+
}
|
|
2037
|
+
allocBuffers(curChan, length2, maxChan) {
|
|
2038
|
+
const buffers = this.fAllocator.alloc(maxChan * this.fPtrSize);
|
|
2039
|
+
console.log(`allocBuffers buffers: ${buffers}`);
|
|
2040
|
+
for (let chan = 0; chan < curChan; chan++) {
|
|
2041
|
+
const buffer = this.fAllocator.alloc(length2 * this.fSampleSize);
|
|
2042
|
+
const HEAP32 = this.fAllocator.getInt32Array();
|
|
2043
|
+
HEAP32[(buffers >> 2) + chan] = buffer;
|
|
2044
|
+
}
|
|
2045
|
+
return buffers;
|
|
2046
|
+
}
|
|
2047
|
+
shareBuffers(curChan, maxChan) {
|
|
2048
|
+
const HEAP32 = this.fAllocator.getInt32Array();
|
|
2049
|
+
for (let chan = curChan; chan < maxChan; chan++) {
|
|
2050
|
+
HEAP32[(this.fBuffers >> 2) + chan] = HEAP32[(this.fBuffers >> 2) + chan % curChan];
|
|
2051
|
+
}
|
|
2052
|
+
}
|
|
2053
|
+
copyToOut(part, maxChannels, offset, buffer) {
|
|
2054
|
+
const HEAP32 = this.fAllocator.getInt32Array();
|
|
2055
|
+
HEAP32[(this.fLength >> 2) + part] = buffer.length;
|
|
2056
|
+
HEAP32[(this.fSR >> 2) + part] = buffer.sampleRate;
|
|
2057
|
+
HEAP32[(this.fOffset >> 2) + part] = offset;
|
|
2058
|
+
if (this.fSampleSize === 8) {
|
|
2059
|
+
this.copyToOutReal64(maxChannels, offset, buffer);
|
|
2060
|
+
} else {
|
|
2061
|
+
this.copyToOutReal32(maxChannels, offset, buffer);
|
|
2062
|
+
}
|
|
2063
|
+
}
|
|
2064
|
+
copyToOutReal32(maxChannels, offset, buffer) {
|
|
2065
|
+
const HEAP32 = this.fAllocator.getInt32Array();
|
|
2066
|
+
const HEAPF = this.fAllocator.getFloat32Array();
|
|
2067
|
+
for (let chan = 0; chan < buffer.numberOfChannels; chan++) {
|
|
2068
|
+
const input = buffer.getChannelData(chan);
|
|
2069
|
+
const output = HEAP32[(this.fBuffers >> 2) + chan];
|
|
2070
|
+
const outputReal = HEAPF.subarray(
|
|
2071
|
+
output + offset * this.fSampleSize >> Math.log2(this.fSampleSize),
|
|
2072
|
+
output + (offset + input.length) * this.fSampleSize >> Math.log2(this.fSampleSize)
|
|
2073
|
+
);
|
|
2074
|
+
for (let sample = 0; sample < input.length; sample++) {
|
|
2075
|
+
outputReal[sample] = input[sample];
|
|
2076
|
+
}
|
|
2077
|
+
}
|
|
2078
|
+
}
|
|
2079
|
+
copyToOutReal64(maxChannels, offset, buffer) {
|
|
2080
|
+
const HEAP32 = this.fAllocator.getInt32Array();
|
|
2081
|
+
const HEAPF = this.fAllocator.getFloat64Array();
|
|
2082
|
+
for (let chan = 0; chan < buffer.numberOfChannels; chan++) {
|
|
2083
|
+
const input = buffer.getChannelData(chan);
|
|
2084
|
+
const output = HEAP32[(this.fBuffers >> 2) + chan];
|
|
2085
|
+
const outputReal = HEAPF.subarray(
|
|
2086
|
+
output + offset * this.fSampleSize >> Math.log2(this.fSampleSize),
|
|
2087
|
+
output + (offset + input.length) * this.fSampleSize >> Math.log2(this.fSampleSize)
|
|
2088
|
+
);
|
|
2089
|
+
for (let sample = 0; sample < input.length; sample++) {
|
|
2090
|
+
outputReal[sample] = input[sample];
|
|
2091
|
+
}
|
|
2092
|
+
}
|
|
2093
|
+
}
|
|
2094
|
+
emptyFile(part, offset) {
|
|
2095
|
+
const HEAP32 = this.fAllocator.getInt32Array();
|
|
2096
|
+
HEAP32[(this.fLength >> 2) + part] = BUFFER_SIZE;
|
|
2097
|
+
HEAP32[(this.fSR >> 2) + part] = SAMPLE_RATE;
|
|
2098
|
+
HEAP32[(this.fOffset >> 2) + part] = offset;
|
|
2099
|
+
return offset + BUFFER_SIZE;
|
|
2100
|
+
}
|
|
2101
|
+
displayMemory(where = "", mem = false) {
|
|
2102
|
+
console.log("Soundfile memory: " + where);
|
|
2103
|
+
console.log(`fPtr: ${this.fPtr}`);
|
|
2104
|
+
console.log(`fBuffers: ${this.fBuffers}`);
|
|
2105
|
+
console.log(`fLength: ${this.fLength}`);
|
|
2106
|
+
console.log(`fSR: ${this.fSR}`);
|
|
2107
|
+
console.log(`fOffset: ${this.fOffset}`);
|
|
2108
|
+
const HEAP32 = this.fAllocator.getInt32Array();
|
|
2109
|
+
if (mem)
|
|
2110
|
+
console.log(`HEAP32: ${HEAP32}`);
|
|
2111
|
+
console.log(`HEAP32[this.fPtr >> 2]: ${HEAP32[this.fPtr >> 2]}`);
|
|
2112
|
+
console.log(`HEAP32[(this.fPtr + ptrSize) >> 2]: ${HEAP32[this.fPtr + this.fPtrSize >> 2]}`);
|
|
2113
|
+
console.log(`HEAP32[(this.fPtr + 2 * ptrSize) >> 2]: ${HEAP32[this.fPtr + 2 * this.fPtrSize >> 2]}`);
|
|
2114
|
+
console.log(`HEAP32[(this.fPtr + 3 * ptrSize) >> 2]: ${HEAP32[this.fPtr + 3 * this.fPtrSize >> 2]}`);
|
|
2115
|
+
}
|
|
2116
|
+
getPtr() {
|
|
2117
|
+
return this.fPtr;
|
|
2118
|
+
}
|
|
2119
|
+
getHEAP32() {
|
|
2120
|
+
return this.fAllocator.getInt32Array();
|
|
2121
|
+
}
|
|
2122
|
+
getHEAPFloat32() {
|
|
2123
|
+
return this.fAllocator.getFloat32Array();
|
|
2124
|
+
}
|
|
2125
|
+
getHEAPFloat64() {
|
|
2126
|
+
return this.fAllocator.getFloat64Array();
|
|
2127
|
+
}
|
|
2128
|
+
};
|
|
2129
|
+
var SoundfileReader = class {
|
|
2130
|
+
constructor(allocator, context, ptrSize, sampleSize) {
|
|
2131
|
+
this.fAllocator = allocator;
|
|
2132
|
+
this.fPtrSize = ptrSize;
|
|
2133
|
+
this.fSampleSize = sampleSize;
|
|
2134
|
+
this.fContext = context;
|
|
2135
|
+
this.fAudioBuffers = [];
|
|
2136
|
+
}
|
|
2137
|
+
async checkFile(directories, fileName) {
|
|
2138
|
+
async function checkFileExists(url) {
|
|
2139
|
+
try {
|
|
2140
|
+
console.log(`"checkFileExists" url: ${url}`);
|
|
2141
|
+
const response = await fetch(url, { method: "HEAD" });
|
|
2142
|
+
return response.ok;
|
|
2143
|
+
} catch (error) {
|
|
2144
|
+
console.error("Fetch error:", error);
|
|
2145
|
+
return false;
|
|
2146
|
+
}
|
|
2147
|
+
}
|
|
2148
|
+
if (await checkFileExists(fileName)) {
|
|
2149
|
+
return fileName;
|
|
2150
|
+
} else {
|
|
2151
|
+
for (let i = 0; i < directories.length; i++) {
|
|
2152
|
+
const pathName = directories[i] + "/" + fileName;
|
|
2153
|
+
if (await checkFileExists(pathName)) {
|
|
2154
|
+
return pathName;
|
|
2155
|
+
}
|
|
2156
|
+
}
|
|
2157
|
+
return "";
|
|
2158
|
+
}
|
|
2159
|
+
}
|
|
2160
|
+
async checkFiles(directories, fileNameList) {
|
|
2161
|
+
const pathNameList = [];
|
|
2162
|
+
for (let i = 0; i < fileNameList.length; i++) {
|
|
2163
|
+
const pathName = await this.checkFile(directories, fileNameList[i]);
|
|
2164
|
+
console.log(`checkFiles pathName: ${pathName}`);
|
|
2165
|
+
pathNameList.push(pathName === "" ? "__empty_sound__" : pathName);
|
|
2166
|
+
}
|
|
2167
|
+
return pathNameList;
|
|
2168
|
+
}
|
|
2169
|
+
async getParamsFile(pathName) {
|
|
2170
|
+
console.log(`Loading sound file from ${pathName}`);
|
|
2171
|
+
const item = this.fAudioBuffers.find((element) => element.pathName === pathName);
|
|
2172
|
+
if (item) {
|
|
2173
|
+
console.log(`getItemByPathName FOUND`);
|
|
2174
|
+
return { channels: item.audioBuffer.numberOfChannels, length: item.audioBuffer.length };
|
|
2175
|
+
} else {
|
|
2176
|
+
const response = await fetch(pathName);
|
|
2177
|
+
if (!response.ok) {
|
|
2178
|
+
console.log(`Failed to load sound file from ${pathName}: ${response.statusText}`);
|
|
2179
|
+
return { channels: 1, length: BUFFER_SIZE };
|
|
2180
|
+
} else {
|
|
2181
|
+
const arrayBuffer = await response.arrayBuffer();
|
|
2182
|
+
const audioBuffer = await this.fContext.decodeAudioData(arrayBuffer);
|
|
2183
|
+
const { numberOfChannels, length: length2 } = audioBuffer;
|
|
2184
|
+
this.fAudioBuffers.push({ pathName, audioBuffer });
|
|
2185
|
+
return { channels: numberOfChannels, length: length2 };
|
|
2186
|
+
}
|
|
2187
|
+
}
|
|
2188
|
+
}
|
|
2189
|
+
readFile(soundfile, pathName, part, offset, maxChan) {
|
|
2190
|
+
const item = this.fAudioBuffers.find((entry) => entry.pathName === pathName);
|
|
2191
|
+
if (item) {
|
|
2192
|
+
soundfile.copyToOut(part, maxChan, offset, item.audioBuffer);
|
|
2193
|
+
return offset + item.audioBuffer.length;
|
|
2194
|
+
} else {
|
|
2195
|
+
console.error(`Failed to access sound file from ${pathName}`);
|
|
2196
|
+
return offset + BUFFER_SIZE;
|
|
2197
|
+
}
|
|
2198
|
+
}
|
|
2199
|
+
async createSoundfile(pathNameList, maxChan, isDouble) {
|
|
2200
|
+
try {
|
|
2201
|
+
let curChan = 1;
|
|
2202
|
+
let totalLength = 0;
|
|
2203
|
+
for (const pathName of pathNameList) {
|
|
2204
|
+
let chan = 0, len = 0;
|
|
2205
|
+
if (pathName === "__empty_sound__") {
|
|
2206
|
+
length = BUFFER_SIZE;
|
|
2207
|
+
chan = 1;
|
|
2208
|
+
} else {
|
|
2209
|
+
const { channels, length: length2 } = await this.getParamsFile(pathName);
|
|
2210
|
+
chan = channels;
|
|
2211
|
+
len = length2;
|
|
2212
|
+
}
|
|
2213
|
+
curChan = Math.max(curChan, chan);
|
|
2214
|
+
totalLength += len;
|
|
2215
|
+
}
|
|
2216
|
+
totalLength += (MAX_SOUNDFILE_PARTS - pathNameList.length) * BUFFER_SIZE;
|
|
2217
|
+
let soundfile = new Soundfile(this.fAllocator, this.fPtrSize, this.fSampleSize, curChan, totalLength, maxChan, pathNameList.length);
|
|
2218
|
+
let offset = 0;
|
|
2219
|
+
for (let part = 0; part < pathNameList.length; part++) {
|
|
2220
|
+
if (pathNameList[part] === "__empty_sound__") {
|
|
2221
|
+
offset = soundfile.emptyFile(part, offset);
|
|
2222
|
+
} else {
|
|
2223
|
+
offset = await this.readFile(soundfile, pathNameList[part], part, offset, maxChan);
|
|
2224
|
+
}
|
|
2225
|
+
}
|
|
2226
|
+
for (let part = pathNameList.length; part < MAX_SOUNDFILE_PARTS; part++) {
|
|
2227
|
+
offset = soundfile.emptyFile(part, offset);
|
|
2228
|
+
}
|
|
2229
|
+
soundfile.shareBuffers(curChan, maxChan);
|
|
2230
|
+
return soundfile;
|
|
2231
|
+
} catch (error) {
|
|
2232
|
+
console.error("Failed to create soundfile:", error);
|
|
2233
|
+
return null;
|
|
2234
|
+
}
|
|
2235
|
+
}
|
|
2236
|
+
getHEAP32() {
|
|
2237
|
+
return this.fAllocator.getInt32Array();
|
|
2238
|
+
}
|
|
2239
|
+
};
|
|
1944
2240
|
var FaustBaseWebAudioDsp = class {
|
|
1945
2241
|
constructor(sampleSize, bufferSize) {
|
|
1946
2242
|
this.fOutputHandler = null;
|
|
@@ -1951,17 +2247,19 @@ export default ${(_b = jsCode.match(jsCodeHead)) == null ? void 0 : _b[1]};
|
|
|
1951
2247
|
this.fBufferSize = bufferSize;
|
|
1952
2248
|
this.fInChannels = [];
|
|
1953
2249
|
this.fOutChannels = [];
|
|
1954
|
-
this.
|
|
1955
|
-
this.
|
|
2250
|
+
this.fPtrSize = sampleSize;
|
|
2251
|
+
this.fSampleSize = sampleSize;
|
|
1956
2252
|
this.fOutputsTimer = 5;
|
|
1957
2253
|
this.fInputsItems = [];
|
|
1958
2254
|
this.fOutputsItems = [];
|
|
1959
2255
|
this.fDescriptor = [];
|
|
2256
|
+
this.fSoundfiles = [];
|
|
1960
2257
|
this.fPitchwheelLabel = [];
|
|
1961
2258
|
this.fCtrlLabel = new Array(128).fill(null).map(() => []);
|
|
1962
2259
|
this.fPathTable = {};
|
|
1963
2260
|
this.fProcessing = false;
|
|
1964
2261
|
this.fDestroyed = false;
|
|
2262
|
+
this.fFirstCall = true;
|
|
1965
2263
|
this.fUICallback = (item) => {
|
|
1966
2264
|
if (item.type === "hbargraph" || item.type === "vbargraph") {
|
|
1967
2265
|
this.fOutputsItems.push(item.address);
|
|
@@ -1986,6 +2284,8 @@ export default ${(_b = jsCode.match(jsCodeHead)) == null ? void 0 : _b[1]};
|
|
|
1986
2284
|
this.fCtrlLabel[parseInt(matched[1])].push({ path: item.address, min: item.min, max: item.max });
|
|
1987
2285
|
}
|
|
1988
2286
|
});
|
|
2287
|
+
} else if (item.type === "soundfile") {
|
|
2288
|
+
this.fSoundfiles.push({ name: item.label, url: item.url, basePtr: -1 });
|
|
1989
2289
|
}
|
|
1990
2290
|
};
|
|
1991
2291
|
}
|
|
@@ -2010,6 +2310,46 @@ export default ${(_b = jsCode.match(jsCodeHead)) == null ? void 0 : _b[1]};
|
|
|
2010
2310
|
callback(item);
|
|
2011
2311
|
}
|
|
2012
2312
|
}
|
|
2313
|
+
static splitNames(input) {
|
|
2314
|
+
let trimmed = input.replace(/^\{|\}$/g, "");
|
|
2315
|
+
return trimmed.split(";").map((str) => str.length <= 2 ? "" : str.substring(1, str.length - 1));
|
|
2316
|
+
}
|
|
2317
|
+
async loadSoundfile(sfReader, sfOffset, name, url) {
|
|
2318
|
+
console.log(`Soundfile ${name} paths: ${url}`);
|
|
2319
|
+
const sfDirectories = ["", ".", "http://127.0.0.1:8000"];
|
|
2320
|
+
console.log(`sfDirectories ${sfDirectories}`);
|
|
2321
|
+
const sfPathNames = await sfReader.checkFiles(sfDirectories, FaustBaseWebAudioDsp.splitNames(url));
|
|
2322
|
+
console.log(`Soundfile ${name} paths: ${sfPathNames}`);
|
|
2323
|
+
const item = this.fSoundfiles.find((element) => element.url === url);
|
|
2324
|
+
if (item) {
|
|
2325
|
+
if (item.basePtr !== -1) {
|
|
2326
|
+
const HEAP32 = sfReader.getHEAP32();
|
|
2327
|
+
console.log(`Soundfile ${name} loaded at ${item.basePtr} in wasm memory with sfOffset ${sfOffset}`);
|
|
2328
|
+
console.log(`Soundfile CACHE ${url}}`);
|
|
2329
|
+
HEAP32[sfOffset >> 2] = item.basePtr;
|
|
2330
|
+
} else {
|
|
2331
|
+
const soundfile = await sfReader.createSoundfile(sfPathNames, MAX_CHAN, this.fSampleSize === 8);
|
|
2332
|
+
if (soundfile) {
|
|
2333
|
+
const HEAP32 = soundfile.getHEAP32();
|
|
2334
|
+
item.basePtr = soundfile.getPtr();
|
|
2335
|
+
console.log(`Soundfile ${name} loaded at ${item.basePtr} in wasm memory with sfOffset ${sfOffset}`);
|
|
2336
|
+
HEAP32[sfOffset >> 2] = item.basePtr;
|
|
2337
|
+
} else {
|
|
2338
|
+
console.log(`Soundfile ${name} for ${url} cannot be created !}`);
|
|
2339
|
+
}
|
|
2340
|
+
}
|
|
2341
|
+
} else {
|
|
2342
|
+
console.log(`Soundfile with ${url} cannot be found !}`);
|
|
2343
|
+
}
|
|
2344
|
+
}
|
|
2345
|
+
async initSoundfileMemory(allocator, sfReader, baseDSP) {
|
|
2346
|
+
let sfOffset = baseDSP;
|
|
2347
|
+
for (const { name, url } of this.fSoundfiles) {
|
|
2348
|
+
await this.loadSoundfile(sfReader, sfOffset, name, url);
|
|
2349
|
+
sfOffset += this.fPtrSize;
|
|
2350
|
+
}
|
|
2351
|
+
;
|
|
2352
|
+
}
|
|
2013
2353
|
updateOutputs() {
|
|
2014
2354
|
if (this.fOutputsItems.length > 0 && this.fOutputHandler && this.fOutputsTimer-- === 0) {
|
|
2015
2355
|
this.fOutputsTimer = 5;
|
|
@@ -2104,6 +2444,9 @@ export default ${(_b = jsCode.match(jsCodeHead)) == null ? void 0 : _b[1]};
|
|
|
2104
2444
|
getDescriptors() {
|
|
2105
2445
|
return this.fDescriptor;
|
|
2106
2446
|
}
|
|
2447
|
+
hasSoundfiles() {
|
|
2448
|
+
return this.fSoundfiles.length > 0;
|
|
2449
|
+
}
|
|
2107
2450
|
start() {
|
|
2108
2451
|
this.fProcessing = true;
|
|
2109
2452
|
}
|
|
@@ -2123,51 +2466,64 @@ export default ${(_b = jsCode.match(jsCodeHead)) == null ? void 0 : _b[1]};
|
|
|
2123
2466
|
this.fInstance = instance;
|
|
2124
2467
|
this.fJSONDsp = JSON.parse(this.fInstance.json);
|
|
2125
2468
|
FaustBaseWebAudioDsp.parseUI(this.fJSONDsp.ui, this.fUICallback);
|
|
2126
|
-
this.initMemory();
|
|
2469
|
+
this.fEndMemory = this.initMemory();
|
|
2127
2470
|
this.fInstance.api.init(this.fDSP, sampleRate);
|
|
2128
2471
|
}
|
|
2472
|
+
async init(context) {
|
|
2473
|
+
if (this.fSoundfiles.length > 0 && context) {
|
|
2474
|
+
const allocator = new WasmAllocator(this.fInstance.memory, this.fEndMemory);
|
|
2475
|
+
const sfReader = new SoundfileReader(allocator, context, this.fPtrSize, this.fSampleSize);
|
|
2476
|
+
await this.initSoundfileMemory(allocator, sfReader, this.fDSP);
|
|
2477
|
+
}
|
|
2478
|
+
}
|
|
2129
2479
|
initMemory() {
|
|
2130
2480
|
this.fDSP = 0;
|
|
2131
2481
|
const $audio = this.fJSONDsp.size;
|
|
2132
2482
|
this.fAudioInputs = $audio;
|
|
2133
|
-
this.fAudioOutputs = this.fAudioInputs + this.getNumInputs() * this.
|
|
2134
|
-
const $audioInputs = this.fAudioOutputs + this.getNumOutputs() * this.
|
|
2135
|
-
const $audioOutputs = $audioInputs + this.getNumInputs() * this.fBufferSize * this.
|
|
2483
|
+
this.fAudioOutputs = this.fAudioInputs + this.getNumInputs() * this.fPtrSize;
|
|
2484
|
+
const $audioInputs = this.fAudioOutputs + this.getNumOutputs() * this.fPtrSize;
|
|
2485
|
+
const $audioOutputs = $audioInputs + this.getNumInputs() * this.fBufferSize * this.fSampleSize;
|
|
2486
|
+
const endMemory = $audioOutputs + this.getNumOutputs() * this.fBufferSize * this.fSampleSize;
|
|
2136
2487
|
const HEAP = this.fInstance.memory.buffer;
|
|
2137
2488
|
const HEAP32 = new Int32Array(HEAP);
|
|
2138
|
-
const HEAPF = this.
|
|
2489
|
+
const HEAPF = this.fSampleSize === 4 ? new Float32Array(HEAP) : new Float64Array(HEAP);
|
|
2139
2490
|
if (this.getNumInputs() > 0) {
|
|
2140
2491
|
for (let chan = 0; chan < this.getNumInputs(); chan++) {
|
|
2141
|
-
HEAP32[(this.fAudioInputs >> 2) + chan] = $audioInputs + this.fBufferSize * this.
|
|
2492
|
+
HEAP32[(this.fAudioInputs >> 2) + chan] = $audioInputs + this.fBufferSize * this.fSampleSize * chan;
|
|
2142
2493
|
}
|
|
2143
|
-
const dspInChans = HEAP32.subarray(this.fAudioInputs >> 2, this.fAudioInputs + this.getNumInputs() * this.
|
|
2494
|
+
const dspInChans = HEAP32.subarray(this.fAudioInputs >> 2, this.fAudioInputs + this.getNumInputs() * this.fPtrSize >> 2);
|
|
2144
2495
|
for (let chan = 0; chan < this.getNumInputs(); chan++) {
|
|
2145
|
-
this.fInChannels[chan] = HEAPF.subarray(dspInChans[chan] >> Math.log2(this.
|
|
2496
|
+
this.fInChannels[chan] = HEAPF.subarray(dspInChans[chan] >> Math.log2(this.fSampleSize), dspInChans[chan] + this.fBufferSize * this.fSampleSize >> Math.log2(this.fSampleSize));
|
|
2146
2497
|
}
|
|
2147
2498
|
}
|
|
2148
2499
|
if (this.getNumOutputs() > 0) {
|
|
2149
2500
|
for (let chan = 0; chan < this.getNumOutputs(); chan++) {
|
|
2150
|
-
HEAP32[(this.fAudioOutputs >> 2) + chan] = $audioOutputs + this.fBufferSize * this.
|
|
2501
|
+
HEAP32[(this.fAudioOutputs >> 2) + chan] = $audioOutputs + this.fBufferSize * this.fSampleSize * chan;
|
|
2151
2502
|
}
|
|
2152
|
-
const dspOutChans = HEAP32.subarray(this.fAudioOutputs >> 2, this.fAudioOutputs + this.getNumOutputs() * this.
|
|
2503
|
+
const dspOutChans = HEAP32.subarray(this.fAudioOutputs >> 2, this.fAudioOutputs + this.getNumOutputs() * this.fPtrSize >> 2);
|
|
2153
2504
|
for (let chan = 0; chan < this.getNumOutputs(); chan++) {
|
|
2154
|
-
this.fOutChannels[chan] = HEAPF.subarray(dspOutChans[chan] >> Math.log2(this.
|
|
2505
|
+
this.fOutChannels[chan] = HEAPF.subarray(dspOutChans[chan] >> Math.log2(this.fSampleSize), dspOutChans[chan] + this.fBufferSize * this.fSampleSize >> Math.log2(this.fSampleSize));
|
|
2155
2506
|
}
|
|
2156
2507
|
}
|
|
2508
|
+
return endMemory;
|
|
2157
2509
|
}
|
|
2158
2510
|
toString() {
|
|
2159
2511
|
return `============== Mono Memory layout ==============
|
|
2160
|
-
this.fBufferSize: ${this.fBufferSize}
|
|
2161
|
-
this.fJSONDsp.size: ${this.fJSONDsp.size}
|
|
2162
|
-
this.fAudioInputs: ${this.fAudioInputs}
|
|
2163
|
-
this.fAudioOutputs: ${this.fAudioOutputs}
|
|
2164
|
-
this.fDSP: ${this.fDSP}`;
|
|
2512
|
+
this.fBufferSize: ${this.fBufferSize}
|
|
2513
|
+
this.fJSONDsp.size: ${this.fJSONDsp.size}
|
|
2514
|
+
this.fAudioInputs: ${this.fAudioInputs}
|
|
2515
|
+
this.fAudioOutputs: ${this.fAudioOutputs}
|
|
2516
|
+
this.fDSP: ${this.fDSP}`;
|
|
2165
2517
|
}
|
|
2166
2518
|
compute(input, output) {
|
|
2167
2519
|
if (this.fDestroyed)
|
|
2168
2520
|
return false;
|
|
2169
2521
|
if (!this.fProcessing)
|
|
2170
2522
|
return true;
|
|
2523
|
+
if (this.fFirstCall) {
|
|
2524
|
+
this.initMemory();
|
|
2525
|
+
this.fFirstCall = false;
|
|
2526
|
+
}
|
|
2171
2527
|
if (typeof input === "function") {
|
|
2172
2528
|
input(this.fInChannels);
|
|
2173
2529
|
} else {
|
|
@@ -2325,7 +2681,7 @@ this.fDSP: ${this.fDSP}`;
|
|
|
2325
2681
|
FaustBaseWebAudioDsp.parseUI(this.fJSONDsp.ui, this.fUICallback);
|
|
2326
2682
|
if (this.fJSONEffect)
|
|
2327
2683
|
FaustBaseWebAudioDsp.parseUI(this.fJSONEffect.ui, this.fUICallback);
|
|
2328
|
-
this.initMemory();
|
|
2684
|
+
this.fEndMemory = this.initMemory();
|
|
2329
2685
|
this.fVoiceTable = [];
|
|
2330
2686
|
for (let voice = 0; voice < this.fInstance.voices; voice++) {
|
|
2331
2687
|
this.fVoiceTable.push(new FaustWebAudioDspVoice(
|
|
@@ -2339,48 +2695,59 @@ this.fDSP: ${this.fDSP}`;
|
|
|
2339
2695
|
if (this.fInstance.effectAPI)
|
|
2340
2696
|
this.fInstance.effectAPI.init(this.fEffect, sampleRate);
|
|
2341
2697
|
}
|
|
2698
|
+
async init(context) {
|
|
2699
|
+
if (this.fSoundfiles.length > 0 && context) {
|
|
2700
|
+
const allocator = new WasmAllocator(this.fInstance.memory, this.fEndMemory);
|
|
2701
|
+
const sfReader = new SoundfileReader(allocator, context, this.fPtrSize, this.fSampleSize);
|
|
2702
|
+
for (let voice = 0; voice < this.fInstance.voices; voice++) {
|
|
2703
|
+
await this.initSoundfileMemory(allocator, sfReader, this.fJSONDsp.size * voice);
|
|
2704
|
+
}
|
|
2705
|
+
}
|
|
2706
|
+
}
|
|
2342
2707
|
initMemory() {
|
|
2343
2708
|
this.fEffect = this.fJSONDsp.size * this.fInstance.voices;
|
|
2344
2709
|
const $audio = this.fEffect + (this.fJSONEffect ? this.fJSONEffect.size : 0);
|
|
2345
2710
|
this.fAudioInputs = $audio;
|
|
2346
|
-
this.fAudioOutputs = this.fAudioInputs + this.getNumInputs() * this.
|
|
2347
|
-
this.fAudioMixing = this.fAudioOutputs + this.getNumOutputs() * this.
|
|
2348
|
-
this.fAudioMixingHalf = this.fAudioMixing + this.getNumOutputs() * this.
|
|
2349
|
-
const $audioInputs = this.fAudioMixingHalf + this.getNumOutputs() * this.
|
|
2350
|
-
const $audioOutputs = $audioInputs + this.getNumInputs() * this.fBufferSize * this.
|
|
2351
|
-
const $audioMixing = $audioOutputs + this.getNumOutputs() * this.fBufferSize * this.
|
|
2711
|
+
this.fAudioOutputs = this.fAudioInputs + this.getNumInputs() * this.fPtrSize;
|
|
2712
|
+
this.fAudioMixing = this.fAudioOutputs + this.getNumOutputs() * this.fPtrSize;
|
|
2713
|
+
this.fAudioMixingHalf = this.fAudioMixing + this.getNumOutputs() * this.fPtrSize;
|
|
2714
|
+
const $audioInputs = this.fAudioMixingHalf + this.getNumOutputs() * this.fPtrSize;
|
|
2715
|
+
const $audioOutputs = $audioInputs + this.getNumInputs() * this.fBufferSize * this.fSampleSize;
|
|
2716
|
+
const $audioMixing = $audioOutputs + this.getNumOutputs() * this.fBufferSize * this.fSampleSize;
|
|
2717
|
+
const endMemory = $audioMixing + this.getNumOutputs() * this.fBufferSize * this.fSampleSize;
|
|
2352
2718
|
const HEAP = this.fInstance.memory.buffer;
|
|
2353
2719
|
const HEAP32 = new Int32Array(HEAP);
|
|
2354
|
-
const HEAPF = this.
|
|
2720
|
+
const HEAPF = this.fSampleSize === 4 ? new Float32Array(HEAP) : new Float64Array(HEAP);
|
|
2355
2721
|
if (this.getNumInputs() > 0) {
|
|
2356
2722
|
for (let chan = 0; chan < this.getNumInputs(); chan++) {
|
|
2357
|
-
HEAP32[(this.fAudioInputs >> 2) + chan] = $audioInputs + this.fBufferSize * this.
|
|
2723
|
+
HEAP32[(this.fAudioInputs >> 2) + chan] = $audioInputs + this.fBufferSize * this.fSampleSize * chan;
|
|
2358
2724
|
}
|
|
2359
|
-
const dspInChans = HEAP32.subarray(this.fAudioInputs >> 2, this.fAudioInputs + this.getNumInputs() * this.
|
|
2725
|
+
const dspInChans = HEAP32.subarray(this.fAudioInputs >> 2, this.fAudioInputs + this.getNumInputs() * this.fPtrSize >> 2);
|
|
2360
2726
|
for (let chan = 0; chan < this.getNumInputs(); chan++) {
|
|
2361
|
-
this.fInChannels[chan] = HEAPF.subarray(dspInChans[chan] >> Math.log2(this.
|
|
2727
|
+
this.fInChannels[chan] = HEAPF.subarray(dspInChans[chan] >> Math.log2(this.fSampleSize), dspInChans[chan] + this.fBufferSize * this.fSampleSize >> Math.log2(this.fSampleSize));
|
|
2362
2728
|
}
|
|
2363
2729
|
}
|
|
2364
2730
|
if (this.getNumOutputs() > 0) {
|
|
2365
2731
|
for (let chan = 0; chan < this.getNumOutputs(); chan++) {
|
|
2366
|
-
HEAP32[(this.fAudioOutputs >> 2) + chan] = $audioOutputs + this.fBufferSize * this.
|
|
2367
|
-
HEAP32[(this.fAudioMixing >> 2) + chan] = $audioMixing + this.fBufferSize * this.
|
|
2368
|
-
HEAP32[(this.fAudioMixingHalf >> 2) + chan] = $audioMixing + this.fBufferSize * this.
|
|
2732
|
+
HEAP32[(this.fAudioOutputs >> 2) + chan] = $audioOutputs + this.fBufferSize * this.fSampleSize * chan;
|
|
2733
|
+
HEAP32[(this.fAudioMixing >> 2) + chan] = $audioMixing + this.fBufferSize * this.fSampleSize * chan;
|
|
2734
|
+
HEAP32[(this.fAudioMixingHalf >> 2) + chan] = $audioMixing + this.fBufferSize * this.fSampleSize * chan + this.fBufferSize / 2 * this.fSampleSize;
|
|
2369
2735
|
}
|
|
2370
|
-
const dspOutChans = HEAP32.subarray(this.fAudioOutputs >> 2, this.fAudioOutputs + this.getNumOutputs() * this.
|
|
2736
|
+
const dspOutChans = HEAP32.subarray(this.fAudioOutputs >> 2, this.fAudioOutputs + this.getNumOutputs() * this.fPtrSize >> 2);
|
|
2371
2737
|
for (let chan = 0; chan < this.getNumOutputs(); chan++) {
|
|
2372
|
-
this.fOutChannels[chan] = HEAPF.subarray(dspOutChans[chan] >> Math.log2(this.
|
|
2738
|
+
this.fOutChannels[chan] = HEAPF.subarray(dspOutChans[chan] >> Math.log2(this.fSampleSize), dspOutChans[chan] + this.fBufferSize * this.fSampleSize >> Math.log2(this.fSampleSize));
|
|
2373
2739
|
}
|
|
2374
2740
|
}
|
|
2741
|
+
return endMemory;
|
|
2375
2742
|
}
|
|
2376
2743
|
toString() {
|
|
2377
2744
|
return `============== Poly Memory layout ==============
|
|
2378
|
-
this.fBufferSize: ${this.fBufferSize}
|
|
2379
|
-
this.fJSONDsp.size: ${this.fJSONDsp.size}
|
|
2380
|
-
this.fAudioInputs: ${this.fAudioInputs}
|
|
2381
|
-
this.fAudioOutputs: ${this.fAudioOutputs}
|
|
2382
|
-
this.fAudioMixing: ${this.fAudioMixing}
|
|
2383
|
-
this.fAudioMixingHalf: ${this.fAudioMixingHalf}`;
|
|
2745
|
+
this.fBufferSize: ${this.fBufferSize}
|
|
2746
|
+
this.fJSONDsp.size: ${this.fJSONDsp.size}
|
|
2747
|
+
this.fAudioInputs: ${this.fAudioInputs}
|
|
2748
|
+
this.fAudioOutputs: ${this.fAudioOutputs}
|
|
2749
|
+
this.fAudioMixing: ${this.fAudioMixing}
|
|
2750
|
+
this.fAudioMixingHalf: ${this.fAudioMixingHalf}`;
|
|
2384
2751
|
}
|
|
2385
2752
|
allocVoice(voice, type) {
|
|
2386
2753
|
this.fVoiceTable[voice].fDate++;
|
|
@@ -2434,6 +2801,10 @@ this.fAudioMixingHalf: ${this.fAudioMixingHalf}`;
|
|
|
2434
2801
|
compute(input, output) {
|
|
2435
2802
|
if (this.fDestroyed)
|
|
2436
2803
|
return false;
|
|
2804
|
+
if (this.fFirstCall) {
|
|
2805
|
+
this.initMemory();
|
|
2806
|
+
this.fFirstCall = false;
|
|
2807
|
+
}
|
|
2437
2808
|
if (!this.fProcessing)
|
|
2438
2809
|
return true;
|
|
2439
2810
|
if (this.getNumInputs() > 0 && (!input || !input[0] || input[0].length === 0)) {
|
|
@@ -2684,12 +3055,12 @@ this.fAudioMixingHalf: ${this.fAudioMixingHalf}`;
|
|
|
2684
3055
|
destroy() {
|
|
2685
3056
|
this.fDSPCode.destroy();
|
|
2686
3057
|
}
|
|
2687
|
-
render(inputs = [],
|
|
3058
|
+
render(inputs = [], length2 = this.fBufferSize, onUpdate) {
|
|
2688
3059
|
let l = 0;
|
|
2689
|
-
const outputs = new Array(this.fDSPCode.getNumOutputs()).fill(null).map(() => new Float32Array(
|
|
3060
|
+
const outputs = new Array(this.fDSPCode.getNumOutputs()).fill(null).map(() => new Float32Array(length2));
|
|
2690
3061
|
this.fDSPCode.start();
|
|
2691
|
-
while (l <
|
|
2692
|
-
const sliceLength = Math.min(
|
|
3062
|
+
while (l < length2) {
|
|
3063
|
+
const sliceLength = Math.min(length2 - l, this.fBufferSize);
|
|
2693
3064
|
for (let i = 0; i < this.fDSPCode.getNumInputs(); i++) {
|
|
2694
3065
|
let input;
|
|
2695
3066
|
if (inputs[i]) {
|
|
@@ -2822,11 +3193,11 @@ this.fAudioMixingHalf: ${this.fAudioMixingHalf}`;
|
|
|
2822
3193
|
var WavEncoder = class {
|
|
2823
3194
|
static encode(audioBuffer, options) {
|
|
2824
3195
|
const numberOfChannels = audioBuffer.length;
|
|
2825
|
-
const
|
|
3196
|
+
const length2 = audioBuffer[0].length;
|
|
2826
3197
|
const { shared, float } = options;
|
|
2827
3198
|
const bitDepth = float ? 32 : options.bitDepth | 0 || 16;
|
|
2828
3199
|
const byteDepth = bitDepth >> 3;
|
|
2829
|
-
const byteLength =
|
|
3200
|
+
const byteLength = length2 * numberOfChannels * byteDepth;
|
|
2830
3201
|
const AB = shared ? globalThis.SharedArrayBuffer || globalThis.ArrayBuffer : globalThis.ArrayBuffer;
|
|
2831
3202
|
const ab = new AB((44 + byteLength) * Uint8Array.BYTES_PER_ELEMENT);
|
|
2832
3203
|
const dataView = new DataView(ab);
|
|
@@ -2837,7 +3208,7 @@ this.fAudioMixingHalf: ${this.fAudioMixingHalf}`;
|
|
|
2837
3208
|
numberOfChannels,
|
|
2838
3209
|
sampleRate: options.sampleRate,
|
|
2839
3210
|
symmetric: !!options.symmetric,
|
|
2840
|
-
length,
|
|
3211
|
+
length: length2,
|
|
2841
3212
|
bitDepth,
|
|
2842
3213
|
byteDepth
|
|
2843
3214
|
};
|
|
@@ -2846,7 +3217,7 @@ this.fAudioMixingHalf: ${this.fAudioMixingHalf}`;
|
|
|
2846
3217
|
return ab;
|
|
2847
3218
|
}
|
|
2848
3219
|
static writeHeader(writer, format) {
|
|
2849
|
-
const { formatId, sampleRate, bitDepth, numberOfChannels, length, byteDepth } = format;
|
|
3220
|
+
const { formatId, sampleRate, bitDepth, numberOfChannels, length: length2, byteDepth } = format;
|
|
2850
3221
|
writer.string("RIFF");
|
|
2851
3222
|
writer.uint32(writer.dataView.byteLength - 8);
|
|
2852
3223
|
writer.string("WAVE");
|
|
@@ -2859,11 +3230,11 @@ this.fAudioMixingHalf: ${this.fAudioMixingHalf}`;
|
|
|
2859
3230
|
writer.uint16(numberOfChannels * byteDepth);
|
|
2860
3231
|
writer.uint16(bitDepth);
|
|
2861
3232
|
writer.string("data");
|
|
2862
|
-
writer.uint32(
|
|
3233
|
+
writer.uint32(length2 * numberOfChannels * byteDepth);
|
|
2863
3234
|
return writer.pos;
|
|
2864
3235
|
}
|
|
2865
3236
|
static writeData(writer, audioBuffer, format) {
|
|
2866
|
-
const { bitDepth, float, length, numberOfChannels, symmetric } = format;
|
|
3237
|
+
const { bitDepth, float, length: length2, numberOfChannels, symmetric } = format;
|
|
2867
3238
|
if (bitDepth === 32 && float) {
|
|
2868
3239
|
const { dataView, pos } = writer;
|
|
2869
3240
|
const ab = dataView.buffer;
|
|
@@ -2874,7 +3245,7 @@ this.fAudioMixingHalf: ${this.fAudioMixingHalf}`;
|
|
|
2874
3245
|
}
|
|
2875
3246
|
for (let ch = 0; ch < numberOfChannels; ch++) {
|
|
2876
3247
|
const channel = audioBuffer[ch];
|
|
2877
|
-
for (let i = 0; i <
|
|
3248
|
+
for (let i = 0; i < length2; i++) {
|
|
2878
3249
|
f32View[i * numberOfChannels + ch] = channel[i];
|
|
2879
3250
|
}
|
|
2880
3251
|
}
|
|
@@ -2886,7 +3257,7 @@ this.fAudioMixingHalf: ${this.fAudioMixingHalf}`;
|
|
|
2886
3257
|
throw new TypeError("Not supported bit depth: " + bitDepth);
|
|
2887
3258
|
}
|
|
2888
3259
|
const write = writer[methodName].bind(writer);
|
|
2889
|
-
for (let i = 0; i <
|
|
3260
|
+
for (let i = 0; i < length2; i++) {
|
|
2890
3261
|
for (let j = 0; j < numberOfChannels; j++) {
|
|
2891
3262
|
write(audioBuffer[j][i]);
|
|
2892
3263
|
}
|
|
@@ -3042,24 +3413,24 @@ this.fAudioMixingHalf: ${this.fAudioMixingHalf}`;
|
|
|
3042
3413
|
}
|
|
3043
3414
|
static decodeData(reader, chunkSizeIn, format, options) {
|
|
3044
3415
|
const chunkSize = Math.min(chunkSizeIn, reader.remain());
|
|
3045
|
-
const
|
|
3416
|
+
const length2 = Math.floor(chunkSize / format.blockSize);
|
|
3046
3417
|
const numberOfChannels = format.numberOfChannels;
|
|
3047
3418
|
const sampleRate = format.sampleRate;
|
|
3048
3419
|
const channelData = new Array(numberOfChannels);
|
|
3049
3420
|
for (let ch = 0; ch < numberOfChannels; ch++) {
|
|
3050
3421
|
const AB = options.shared ? globalThis.SharedArrayBuffer || globalThis.ArrayBuffer : globalThis.ArrayBuffer;
|
|
3051
|
-
const ab = new AB(
|
|
3422
|
+
const ab = new AB(length2 * Float32Array.BYTES_PER_ELEMENT);
|
|
3052
3423
|
channelData[ch] = new Float32Array(ab);
|
|
3053
3424
|
}
|
|
3054
|
-
this.readPCM(reader, channelData,
|
|
3425
|
+
this.readPCM(reader, channelData, length2, format, options);
|
|
3055
3426
|
return {
|
|
3056
3427
|
numberOfChannels,
|
|
3057
|
-
length,
|
|
3428
|
+
length: length2,
|
|
3058
3429
|
sampleRate,
|
|
3059
3430
|
channelData
|
|
3060
3431
|
};
|
|
3061
3432
|
}
|
|
3062
|
-
static readPCM(reader, channelData,
|
|
3433
|
+
static readPCM(reader, channelData, length2, format, options) {
|
|
3063
3434
|
const bitDepth = format.bitDepth;
|
|
3064
3435
|
const decoderOption = format.float ? "f" : options.symmetric ? "s" : "";
|
|
3065
3436
|
const methodName = "pcm" + bitDepth + decoderOption;
|
|
@@ -3068,7 +3439,7 @@ this.fAudioMixingHalf: ${this.fAudioMixingHalf}`;
|
|
|
3068
3439
|
}
|
|
3069
3440
|
const read = reader[methodName].bind(reader);
|
|
3070
3441
|
const numberOfChannels = format.numberOfChannels;
|
|
3071
|
-
for (let i = 0; i <
|
|
3442
|
+
for (let i = 0; i < length2; i++) {
|
|
3072
3443
|
for (let ch = 0; ch < numberOfChannels; ch++) {
|
|
3073
3444
|
channelData[ch][i] = read();
|
|
3074
3445
|
}
|
|
@@ -3487,10 +3858,12 @@ this.fAudioMixingHalf: ${this.fAudioMixingHalf}`;
|
|
|
3487
3858
|
}
|
|
3488
3859
|
async compile(compiler, name, code, args) {
|
|
3489
3860
|
this.factory = await compiler.createMonoDSPFactory(name, code, args);
|
|
3490
|
-
if (
|
|
3861
|
+
if (this.factory) {
|
|
3862
|
+
this.name = name;
|
|
3863
|
+
return this;
|
|
3864
|
+
} else {
|
|
3491
3865
|
return null;
|
|
3492
|
-
|
|
3493
|
-
return this;
|
|
3866
|
+
}
|
|
3494
3867
|
}
|
|
3495
3868
|
async createNode(context, name = this.name, factory = this.factory, sp = false, bufferSize = 1024, processorName = (factory == null ? void 0 : factory.shaKey) || name) {
|
|
3496
3869
|
var _a, _b;
|
|
@@ -3501,6 +3874,7 @@ this.fAudioMixingHalf: ${this.fAudioMixingHalf}`;
|
|
|
3501
3874
|
if (sp) {
|
|
3502
3875
|
const instance = await FaustWasmInstantiator_default.createAsyncMonoDSPInstance(factory);
|
|
3503
3876
|
const monoDsp = new FaustMonoWebAudioDsp(instance, context.sampleRate, sampleSize, bufferSize);
|
|
3877
|
+
await monoDsp.init(context);
|
|
3504
3878
|
const sp2 = context.createScriptProcessor(bufferSize, monoDsp.getNumInputs(), monoDsp.getNumOutputs());
|
|
3505
3879
|
Object.setPrototypeOf(sp2, FaustMonoScriptProcessorNode.prototype);
|
|
3506
3880
|
sp2.init(monoDsp);
|
|
@@ -3638,6 +4012,7 @@ const dependencies = {
|
|
|
3638
4012
|
const instance = await FaustWasmInstantiator_default.createAsyncMonoDSPInstance(factory);
|
|
3639
4013
|
const sampleSize = meta.compile_options.match("-double") ? 8 : 4;
|
|
3640
4014
|
const monoDsp = new FaustMonoWebAudioDsp(instance, sampleRate, sampleSize, bufferSize);
|
|
4015
|
+
await monoDsp.init(null);
|
|
3641
4016
|
return new FaustMonoOfflineProcessor(monoDsp, bufferSize);
|
|
3642
4017
|
}
|
|
3643
4018
|
getMeta() {
|
|
@@ -3735,6 +4110,7 @@ const dependencies = {
|
|
|
3735
4110
|
if (sp) {
|
|
3736
4111
|
const instance = await FaustWasmInstantiator_default.createAsyncPolyDSPInstance(voiceFactory, mixerModule, voices, effectFactory || void 0);
|
|
3737
4112
|
const polyDsp = new FaustPolyWebAudioDsp(instance, context.sampleRate, sampleSize, bufferSize);
|
|
4113
|
+
await polyDsp.init(context);
|
|
3738
4114
|
const sp2 = context.createScriptProcessor(bufferSize, polyDsp.getNumInputs(), polyDsp.getNumOutputs());
|
|
3739
4115
|
Object.setPrototypeOf(sp2, FaustPolyScriptProcessorNode.prototype);
|
|
3740
4116
|
sp2.init(polyDsp);
|