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