@grame/faustwasm 0.12.2 → 0.13.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/.prettierrc +5 -0
- package/README.md +21 -3
- package/assets/standalone/faustwasm/index.d.ts +38 -16
- package/assets/standalone/faustwasm/index.js +1574 -404
- package/assets/standalone/faustwasm/index.js.map +2 -2
- package/dist/cjs/index.d.ts +38 -16
- package/dist/cjs/index.js +1573 -404
- package/dist/cjs/index.js.map +2 -2
- package/dist/cjs-bundle/index.d.ts +38 -16
- package/dist/cjs-bundle/index.js +1576 -406
- package/dist/cjs-bundle/index.js.map +2 -2
- package/dist/esm/index.d.ts +38 -16
- package/dist/esm/index.js +1574 -404
- package/dist/esm/index.js.map +2 -2
- package/dist/esm-bundle/index.d.ts +38 -16
- package/dist/esm-bundle/index.js +1576 -406
- package/dist/esm-bundle/index.js.map +2 -2
- package/eslint.config.js +11 -0
- package/package.json +57 -51
- package/sound.cpp +163 -0
- package/sound.dsp +4 -0
- package/sound.json +1 -0
- package/sound.wasm +0 -0
- package/src/FaustAudioWorkletCommunicator.ts +150 -143
- package/src/FaustAudioWorkletNode.ts +173 -75
- package/src/FaustAudioWorkletProcessor.ts +218 -90
- package/src/FaustCmajor.ts +9 -3
- package/src/FaustCompiler.ts +112 -35
- package/src/FaustDspGenerator.ts +561 -117
- package/src/FaustDspInstance.ts +58 -24
- package/src/FaustFFTAudioWorkletProcessor.ts +822 -612
- package/src/FaustOfflineProcessor.ts +187 -56
- package/src/FaustScriptProcessorNode.ts +156 -49
- package/src/FaustSensors.ts +426 -96
- package/src/FaustSvgDiagrams.ts +18 -5
- package/src/FaustWasmInstantiator.ts +224 -70
- package/src/FaustWebAudioDsp.ts +1060 -349
- package/src/LibFaust.ts +13 -4
- package/src/SoundfileReader.ts +175 -131
- package/src/WavDecoder.ts +42 -20
- package/src/WavEncoder.ts +35 -21
- package/src/copyWebStandaloneAssets.d.ts +20 -5
- package/src/copyWebStandaloneAssets.js +203 -75
- package/src/exports-bundle.ts +5 -5
- package/src/exports.ts +24 -24
- package/src/faust2CmajorFiles.d.ts +7 -3
- package/src/faust2cmajorFiles.js +10 -8
- package/src/faust2svgFiles.d.ts +7 -3
- package/src/faust2svgFiles.js +9 -7
- package/src/faust2wasmFiles.d.ts +10 -5
- package/src/faust2wasmFiles.js +34 -17
- package/src/faust2wavFiles.d.ts +12 -3
- package/src/faust2wavFiles.js +25 -12
- package/src/index-bundle-iife.ts +2 -2
- package/src/index-bundle.ts +1 -1
- package/src/index.ts +1 -1
- package/src/instantiateFaustModule.ts +43 -36
- package/src/instantiateFaustModuleFromFile.ts +30 -14
- package/src/types.ts +101 -25
- package/test/faustlive-wasm/faustwasm/index.d.ts +38 -16
- package/test/faustlive-wasm/faustwasm/index.js +1574 -404
- package/test/faustlive-wasm/faustwasm/index.js.map +2 -2
- package/test/web/create-faust-node.html +53 -0
- package/test/web/create-faust-node.js +186 -0
- package/test/organ/create-node.js +0 -252
- package/test/organ/dsp-meta.json +0 -131
- package/test/organ/dsp-module.wasm +0 -0
- package/test/organ/faust-pwa.js +0 -344
- package/test/organ/faust-ui/index.css +0 -442
- package/test/organ/faust-ui/index.css.map +0 -1
- package/test/organ/faust-ui/index.d.ts +0 -1
- package/test/organ/faust-ui/index.js +0 -3756
- package/test/organ/faust-ui/index.js.map +0 -1
- package/test/organ/faustwasm/index.d.ts +0 -1705
- package/test/organ/faustwasm/index.js +0 -4773
- package/test/organ/faustwasm/index.js.map +0 -7
- package/test/organ/icon.png +0 -0
- package/test/organ/index.html +0 -76
- package/test/organ/index.js +0 -69
- package/test/organ/manifest.json +0 -17
- package/test/organ/service-worker.js +0 -165
|
@@ -18,7 +18,9 @@ var instantiateFaustModuleFromFile = async (jsFile, dataFile = jsFile.replace(/c
|
|
|
18
18
|
jsCode = `${jsCode}
|
|
19
19
|
export default ${(_a = jsCode.match(jsCodeHead)) == null ? void 0 : _a[1]};
|
|
20
20
|
`;
|
|
21
|
-
const jsFileMod = URL.createObjectURL(
|
|
21
|
+
const jsFileMod = URL.createObjectURL(
|
|
22
|
+
new Blob([jsCode], { type: "text/javascript" })
|
|
23
|
+
);
|
|
22
24
|
FaustModule = (await import(
|
|
23
25
|
/* webpackIgnore: true */
|
|
24
26
|
jsFileMod
|
|
@@ -72,21 +74,32 @@ var getFaustAudioWorkletProcessor = (dependencies, faustData, register = true) =
|
|
|
72
74
|
FaustWasmInstantiator: FaustWasmInstantiator2,
|
|
73
75
|
FaustAudioWorkletProcessorCommunicator: FaustAudioWorkletProcessorCommunicator2
|
|
74
76
|
} = dependencies;
|
|
75
|
-
const {
|
|
76
|
-
processorName,
|
|
77
|
-
dspName,
|
|
78
|
-
dspMeta,
|
|
79
|
-
effectMeta,
|
|
80
|
-
poly
|
|
81
|
-
} = faustData;
|
|
77
|
+
const { processorName, dspName, dspMeta, effectMeta, poly } = faustData;
|
|
82
78
|
const analysePolyParameters = (item) => {
|
|
83
|
-
const polyKeywords = [
|
|
79
|
+
const polyKeywords = [
|
|
80
|
+
"/gate",
|
|
81
|
+
"/freq",
|
|
82
|
+
"/gain",
|
|
83
|
+
"/key",
|
|
84
|
+
"/vel",
|
|
85
|
+
"/velocity"
|
|
86
|
+
];
|
|
84
87
|
const isPolyReserved = "address" in item && !!polyKeywords.find((k) => item.address.endsWith(k));
|
|
85
88
|
if (poly && isPolyReserved) return null;
|
|
86
89
|
if (item.type === "vslider" || item.type === "hslider" || item.type === "nentry") {
|
|
87
|
-
return {
|
|
90
|
+
return {
|
|
91
|
+
name: item.address,
|
|
92
|
+
defaultValue: item.init || 0,
|
|
93
|
+
minValue: item.min || 0,
|
|
94
|
+
maxValue: item.max || 0
|
|
95
|
+
};
|
|
88
96
|
} else if (item.type === "button" || item.type === "checkbox") {
|
|
89
|
-
return {
|
|
97
|
+
return {
|
|
98
|
+
name: item.address,
|
|
99
|
+
defaultValue: item.init || 0,
|
|
100
|
+
minValue: 0,
|
|
101
|
+
maxValue: 1
|
|
102
|
+
};
|
|
90
103
|
}
|
|
91
104
|
return null;
|
|
92
105
|
};
|
|
@@ -94,7 +107,9 @@ var getFaustAudioWorkletProcessor = (dependencies, faustData, register = true) =
|
|
|
94
107
|
constructor(options) {
|
|
95
108
|
super(options);
|
|
96
109
|
this.paramValuesCache = {};
|
|
97
|
-
this.fCommunicator = new FaustAudioWorkletProcessorCommunicator2(
|
|
110
|
+
this.fCommunicator = new FaustAudioWorkletProcessorCommunicator2(
|
|
111
|
+
this.port
|
|
112
|
+
);
|
|
98
113
|
const { parameterDescriptors } = this.constructor;
|
|
99
114
|
parameterDescriptors.forEach((pd) => {
|
|
100
115
|
this.paramValuesCache[pd.name] = pd.defaultValue || 0;
|
|
@@ -110,7 +125,8 @@ var getFaustAudioWorkletProcessor = (dependencies, faustData, register = true) =
|
|
|
110
125
|
if (param) params.push(param);
|
|
111
126
|
};
|
|
112
127
|
FaustBaseWebAudioDsp2.parseUI(dspMeta.ui, callback);
|
|
113
|
-
if (effectMeta)
|
|
128
|
+
if (effectMeta)
|
|
129
|
+
FaustBaseWebAudioDsp2.parseUI(effectMeta.ui, callback);
|
|
114
130
|
return params;
|
|
115
131
|
}
|
|
116
132
|
setupWamEventHandler() {
|
|
@@ -118,12 +134,15 @@ var getFaustAudioWorkletProcessor = (dependencies, faustData, register = true) =
|
|
|
118
134
|
if (!this.wamInfo) return;
|
|
119
135
|
const { moduleId, instanceId } = this.wamInfo;
|
|
120
136
|
const { webAudioModules } = globalThis;
|
|
121
|
-
const ModuleScope = webAudioModules.getModuleScope(
|
|
137
|
+
const ModuleScope = webAudioModules.getModuleScope(
|
|
138
|
+
moduleId
|
|
139
|
+
);
|
|
122
140
|
const paramMgrProcessor = (_a = ModuleScope == null ? void 0 : ModuleScope.paramMgrProcessors) == null ? void 0 : _a[instanceId];
|
|
123
141
|
if (!paramMgrProcessor) return;
|
|
124
142
|
if (paramMgrProcessor.handleEvent) return;
|
|
125
143
|
paramMgrProcessor.handleEvent = (event) => {
|
|
126
|
-
if (event.type === "wam-midi")
|
|
144
|
+
if (event.type === "wam-midi")
|
|
145
|
+
this.midiMessage(event.data.bytes);
|
|
127
146
|
};
|
|
128
147
|
}
|
|
129
148
|
process(inputs, outputs, parameters) {
|
|
@@ -183,7 +202,14 @@ var getFaustAudioWorkletProcessor = (dependencies, faustData, register = true) =
|
|
|
183
202
|
// Plot handler set on demand
|
|
184
203
|
case "setPlotHandler": {
|
|
185
204
|
if (msg.data) {
|
|
186
|
-
this.fDSPCode.setPlotHandler(
|
|
205
|
+
this.fDSPCode.setPlotHandler(
|
|
206
|
+
(output, index, events) => this.port.postMessage({
|
|
207
|
+
type: "plot",
|
|
208
|
+
value: output,
|
|
209
|
+
index,
|
|
210
|
+
events
|
|
211
|
+
})
|
|
212
|
+
);
|
|
187
213
|
} else {
|
|
188
214
|
this.fDSPCode.setPlotHandler(null);
|
|
189
215
|
}
|
|
@@ -245,10 +271,18 @@ var getFaustAudioWorkletProcessor = (dependencies, faustData, register = true) =
|
|
|
245
271
|
const { FaustMonoWebAudioDsp: FaustMonoWebAudioDsp2 } = dependencies;
|
|
246
272
|
const { factory, sampleSize } = options.processorOptions;
|
|
247
273
|
const instance = FaustWasmInstantiator2.createSyncMonoDSPInstance(factory);
|
|
248
|
-
this.fDSPCode = new FaustMonoWebAudioDsp2(
|
|
274
|
+
this.fDSPCode = new FaustMonoWebAudioDsp2(
|
|
275
|
+
instance,
|
|
276
|
+
sampleRate,
|
|
277
|
+
sampleSize,
|
|
278
|
+
128,
|
|
279
|
+
factory.soundfiles
|
|
280
|
+
);
|
|
249
281
|
this.port.addEventListener("message", this.handleMessageAux);
|
|
250
282
|
this.port.start();
|
|
251
|
-
this.fDSPCode.setOutputParamHandler(
|
|
283
|
+
this.fDSPCode.setOutputParamHandler(
|
|
284
|
+
(path, value) => this.port.postMessage({ path, value, type: "param" })
|
|
285
|
+
);
|
|
252
286
|
this.fDSPCode.start();
|
|
253
287
|
}
|
|
254
288
|
}
|
|
@@ -270,13 +304,35 @@ var getFaustAudioWorkletProcessor = (dependencies, faustData, register = true) =
|
|
|
270
304
|
}
|
|
271
305
|
};
|
|
272
306
|
const { FaustPolyWebAudioDsp: FaustPolyWebAudioDsp3 } = dependencies;
|
|
273
|
-
const {
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
307
|
+
const {
|
|
308
|
+
voiceFactory,
|
|
309
|
+
mixerModule,
|
|
310
|
+
voices,
|
|
311
|
+
effectFactory,
|
|
312
|
+
sampleSize
|
|
313
|
+
} = options.processorOptions;
|
|
314
|
+
const instance = FaustWasmInstantiator2.createSyncPolyDSPInstance(
|
|
315
|
+
voiceFactory,
|
|
316
|
+
mixerModule,
|
|
317
|
+
voices,
|
|
318
|
+
effectFactory
|
|
319
|
+
);
|
|
320
|
+
const soundfiles = {
|
|
321
|
+
...effectFactory == null ? void 0 : effectFactory.soundfiles,
|
|
322
|
+
...voiceFactory.soundfiles
|
|
323
|
+
};
|
|
324
|
+
this.fDSPCode = new FaustPolyWebAudioDsp3(
|
|
325
|
+
instance,
|
|
326
|
+
sampleRate,
|
|
327
|
+
sampleSize,
|
|
328
|
+
128,
|
|
329
|
+
soundfiles
|
|
330
|
+
);
|
|
277
331
|
this.port.addEventListener("message", this.handleMessageAux);
|
|
278
332
|
this.port.start();
|
|
279
|
-
this.fDSPCode.setOutputParamHandler(
|
|
333
|
+
this.fDSPCode.setOutputParamHandler(
|
|
334
|
+
(path, value) => this.port.postMessage({ path, value, type: "param" })
|
|
335
|
+
);
|
|
280
336
|
this.fDSPCode.start();
|
|
281
337
|
}
|
|
282
338
|
midiMessage(data) {
|
|
@@ -284,7 +340,8 @@ var getFaustAudioWorkletProcessor = (dependencies, faustData, register = true) =
|
|
|
284
340
|
const channel = data[0] & 15;
|
|
285
341
|
const data1 = data[1];
|
|
286
342
|
const data2 = data[2];
|
|
287
|
-
if (cmd === 8 || cmd === 9 && data2 === 0)
|
|
343
|
+
if (cmd === 8 || cmd === 9 && data2 === 0)
|
|
344
|
+
this.keyOff(channel, data1, data2);
|
|
288
345
|
else if (cmd === 9) this.keyOn(channel, data1, data2);
|
|
289
346
|
else super.midiMessage(data);
|
|
290
347
|
}
|
|
@@ -302,7 +359,10 @@ var getFaustAudioWorkletProcessor = (dependencies, faustData, register = true) =
|
|
|
302
359
|
const Processor = poly ? FaustPolyAudioWorkletProcessor : FaustMonoAudioWorkletProcessor;
|
|
303
360
|
if (register) {
|
|
304
361
|
try {
|
|
305
|
-
registerProcessor(
|
|
362
|
+
registerProcessor(
|
|
363
|
+
processorName || dspName || (poly ? "mydsp_poly" : "mydsp"),
|
|
364
|
+
Processor
|
|
365
|
+
);
|
|
306
366
|
} catch (error) {
|
|
307
367
|
console.warn(error);
|
|
308
368
|
}
|
|
@@ -321,19 +381,8 @@ var getFaustFFTAudioWorkletProcessor = (dependencies, faustData, register = true
|
|
|
321
381
|
FaustAudioWorkletProcessorCommunicator: FaustAudioWorkletProcessorCommunicator2,
|
|
322
382
|
FFTUtils
|
|
323
383
|
} = dependencies;
|
|
324
|
-
const {
|
|
325
|
-
|
|
326
|
-
dspName,
|
|
327
|
-
dspMeta,
|
|
328
|
-
fftOptions
|
|
329
|
-
} = faustData;
|
|
330
|
-
const {
|
|
331
|
-
windowFunctions,
|
|
332
|
-
getFFT,
|
|
333
|
-
fftToSignal,
|
|
334
|
-
signalToFFT,
|
|
335
|
-
signalToNoFFT
|
|
336
|
-
} = FFTUtils;
|
|
384
|
+
const { processorName, dspName, dspMeta, fftOptions } = faustData;
|
|
385
|
+
const { windowFunctions, getFFT, fftToSignal, signalToFFT, signalToNoFFT } = FFTUtils;
|
|
337
386
|
const ceil = (x, to) => Math.abs(to) < 1 ? Math.ceil(x * (1 / to)) / (1 / to) : Math.ceil(x / to) * to;
|
|
338
387
|
const mod = (x, y) => (x % y + y) % y;
|
|
339
388
|
const apply = (array, windowFunction) => {
|
|
@@ -341,7 +390,13 @@ var getFaustFFTAudioWorkletProcessor = (dependencies, faustData, register = true
|
|
|
341
390
|
array[i] *= windowFunction(i, array.length);
|
|
342
391
|
}
|
|
343
392
|
};
|
|
344
|
-
const fftParamKeywords = [
|
|
393
|
+
const fftParamKeywords = [
|
|
394
|
+
"/fftSize",
|
|
395
|
+
"/fftHopSize",
|
|
396
|
+
"/fftOverlap",
|
|
397
|
+
"/windowFunction",
|
|
398
|
+
"/noIFFT"
|
|
399
|
+
];
|
|
345
400
|
const setTypedArray = (to, from, offsetTo = 0, offsetFrom = 0) => {
|
|
346
401
|
const toLength = to.length;
|
|
347
402
|
const fromLength = from.length;
|
|
@@ -350,7 +405,11 @@ var getFaustFFTAudioWorkletProcessor = (dependencies, faustData, register = true
|
|
|
350
405
|
let $to = mod(offsetTo, toLength) || 0;
|
|
351
406
|
let $from = mod(offsetFrom, fromLength) || 0;
|
|
352
407
|
while (spilled < spillLength) {
|
|
353
|
-
const $spillLength = Math.min(
|
|
408
|
+
const $spillLength = Math.min(
|
|
409
|
+
spillLength - spilled,
|
|
410
|
+
toLength - $to,
|
|
411
|
+
fromLength - $from
|
|
412
|
+
);
|
|
354
413
|
const $fromEnd = $from + $spillLength;
|
|
355
414
|
if ($from === 0 && $fromEnd === fromLength) to.set(from, $to);
|
|
356
415
|
else to.set(from.subarray($from, $fromEnd), $to);
|
|
@@ -364,9 +423,19 @@ var getFaustFFTAudioWorkletProcessor = (dependencies, faustData, register = true
|
|
|
364
423
|
const isFFTReserved = "address" in item && !!fftParamKeywords.find((k) => item.address.endsWith(k));
|
|
365
424
|
if (isFFTReserved) return null;
|
|
366
425
|
if (item.type === "vslider" || item.type === "hslider" || item.type === "nentry") {
|
|
367
|
-
return {
|
|
426
|
+
return {
|
|
427
|
+
name: item.address,
|
|
428
|
+
defaultValue: item.init || 0,
|
|
429
|
+
minValue: item.min || 0,
|
|
430
|
+
maxValue: item.max || 0
|
|
431
|
+
};
|
|
368
432
|
} else if (item.type === "button" || item.type === "checkbox") {
|
|
369
|
-
return {
|
|
433
|
+
return {
|
|
434
|
+
name: item.address,
|
|
435
|
+
defaultValue: item.init || 0,
|
|
436
|
+
minValue: 0,
|
|
437
|
+
maxValue: 1
|
|
438
|
+
};
|
|
370
439
|
}
|
|
371
440
|
return null;
|
|
372
441
|
};
|
|
@@ -453,7 +522,9 @@ var getFaustFFTAudioWorkletProcessor = (dependencies, faustData, register = true
|
|
|
453
522
|
};
|
|
454
523
|
this.port.addEventListener("message", this.handleMessageAux);
|
|
455
524
|
this.port.start();
|
|
456
|
-
this.communicator = new FaustAudioWorkletProcessorCommunicator2(
|
|
525
|
+
this.communicator = new FaustAudioWorkletProcessorCommunicator2(
|
|
526
|
+
this.port
|
|
527
|
+
);
|
|
457
528
|
const { parameterDescriptors } = this.constructor;
|
|
458
529
|
parameterDescriptors.forEach((pd) => {
|
|
459
530
|
this.paramValuesCache[pd.name] = pd.defaultValue || 0;
|
|
@@ -515,35 +586,55 @@ var getFaustFFTAudioWorkletProcessor = (dependencies, faustData, register = true
|
|
|
515
586
|
if (!this.wamInfo) return;
|
|
516
587
|
const { moduleId, instanceId } = this.wamInfo;
|
|
517
588
|
const { webAudioModules } = globalThis;
|
|
518
|
-
const ModuleScope = webAudioModules.getModuleScope(
|
|
589
|
+
const ModuleScope = webAudioModules.getModuleScope(
|
|
590
|
+
moduleId
|
|
591
|
+
);
|
|
519
592
|
const paramMgrProcessor = (_a = ModuleScope == null ? void 0 : ModuleScope.paramMgrProcessors) == null ? void 0 : _a[instanceId];
|
|
520
593
|
if (!paramMgrProcessor) return;
|
|
521
594
|
if (paramMgrProcessor.handleEvent) return;
|
|
522
595
|
paramMgrProcessor.handleEvent = (event) => {
|
|
523
|
-
if (event.type === "wam-midi")
|
|
596
|
+
if (event.type === "wam-midi")
|
|
597
|
+
this.midiMessage(event.data.bytes);
|
|
524
598
|
};
|
|
525
599
|
}
|
|
526
600
|
processFFT() {
|
|
527
601
|
let samplesForFFT = mod(this.$inputWrite - this.$inputRead, this.fftBufferSize) || this.fftBufferSize;
|
|
528
602
|
while (samplesForFFT >= this.fftSize) {
|
|
529
603
|
let fftProcessorOutputs = [];
|
|
530
|
-
this.fDSPCode.compute(
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
604
|
+
this.fDSPCode.compute(
|
|
605
|
+
(inputs) => {
|
|
606
|
+
for (let i = 0; i < Math.min(
|
|
607
|
+
this.fftInput.length,
|
|
608
|
+
Math.ceil(inputs.length / 3)
|
|
609
|
+
); i++) {
|
|
610
|
+
const ffted = this.rfft.forward((fftBuffer) => {
|
|
611
|
+
setTypedArray(
|
|
612
|
+
fftBuffer,
|
|
613
|
+
this.fftInput[i],
|
|
614
|
+
0,
|
|
615
|
+
this.$inputRead
|
|
616
|
+
);
|
|
617
|
+
for (let j = 0; j < fftBuffer.length; j++) {
|
|
618
|
+
fftBuffer[j] *= this.window[j];
|
|
619
|
+
}
|
|
620
|
+
});
|
|
621
|
+
fftToSignal(
|
|
622
|
+
ffted,
|
|
623
|
+
inputs[i * 3],
|
|
624
|
+
inputs[i * 3 + 1],
|
|
625
|
+
inputs[i * 3 + 2]
|
|
626
|
+
);
|
|
627
|
+
}
|
|
628
|
+
for (let i = this.fftInput.length * 3; i < inputs.length; i++) {
|
|
629
|
+
if (i % 3 === 2)
|
|
630
|
+
inputs[i].forEach((v, j) => inputs[i][j] = j);
|
|
631
|
+
else inputs[i].fill(0);
|
|
632
|
+
}
|
|
633
|
+
},
|
|
634
|
+
(outputs) => {
|
|
635
|
+
fftProcessorOutputs = outputs;
|
|
543
636
|
}
|
|
544
|
-
|
|
545
|
-
fftProcessorOutputs = outputs;
|
|
546
|
-
});
|
|
637
|
+
);
|
|
547
638
|
this.$inputRead += this.fftHopSize;
|
|
548
639
|
this.$inputRead %= this.fftBufferSize;
|
|
549
640
|
samplesForFFT -= this.fftHopSize;
|
|
@@ -551,10 +642,18 @@ var getFaustFFTAudioWorkletProcessor = (dependencies, faustData, register = true
|
|
|
551
642
|
let iffted;
|
|
552
643
|
if (this.noIFFT) {
|
|
553
644
|
iffted = this.noIFFTBuffer;
|
|
554
|
-
signalToNoFFT(
|
|
645
|
+
signalToNoFFT(
|
|
646
|
+
fftProcessorOutputs[i * 2] || this.fftProcessorZeros,
|
|
647
|
+
fftProcessorOutputs[i * 2 + 1] || this.fftProcessorZeros,
|
|
648
|
+
iffted
|
|
649
|
+
);
|
|
555
650
|
} else {
|
|
556
651
|
iffted = this.rfft.inverse((ifftBuffer) => {
|
|
557
|
-
signalToFFT(
|
|
652
|
+
signalToFFT(
|
|
653
|
+
fftProcessorOutputs[i * 2] || this.fftProcessorZeros,
|
|
654
|
+
fftProcessorOutputs[i * 2 + 1] || this.fftProcessorZeros,
|
|
655
|
+
ifftBuffer
|
|
656
|
+
);
|
|
558
657
|
});
|
|
559
658
|
}
|
|
560
659
|
for (let j = 0; j < iffted.length; j++) {
|
|
@@ -564,12 +663,14 @@ var getFaustFFTAudioWorkletProcessor = (dependencies, faustData, register = true
|
|
|
564
663
|
for (let j = 0; j < iffted.length - this.fftHopSize; j++) {
|
|
565
664
|
$ = mod(this.$outputWrite + j, this.fftBufferSize);
|
|
566
665
|
this.fftOutput[i][$] += iffted[j];
|
|
567
|
-
if (i === 0)
|
|
666
|
+
if (i === 0)
|
|
667
|
+
this.windowSumSquare[$] += this.noIFFT ? this.window[j] : this.window[j] ** 2;
|
|
568
668
|
}
|
|
569
669
|
for (let j = iffted.length - this.fftHopSize; j < iffted.length; j++) {
|
|
570
670
|
$ = mod(this.$outputWrite + j, this.fftBufferSize);
|
|
571
671
|
this.fftOutput[i][$] = iffted[j];
|
|
572
|
-
if (i === 0)
|
|
672
|
+
if (i === 0)
|
|
673
|
+
this.windowSumSquare[$] = this.noIFFT ? this.window[j] : this.window[j] ** 2;
|
|
573
674
|
}
|
|
574
675
|
}
|
|
575
676
|
this.$outputWrite += this.fftHopSize;
|
|
@@ -585,10 +686,18 @@ var getFaustFFTAudioWorkletProcessor = (dependencies, faustData, register = true
|
|
|
585
686
|
const outputChannels = (output == null ? void 0 : output.length) || 0;
|
|
586
687
|
const bufferSize = (input == null ? void 0 : input.length) ? Math.max(...input.map((c) => c.length)) || 128 : 128;
|
|
587
688
|
this.noIFFT = !!parameters.noIFFT[0];
|
|
588
|
-
this.resetFFT(
|
|
689
|
+
this.resetFFT(
|
|
690
|
+
~~parameters.fftSize[0],
|
|
691
|
+
~~parameters.fftOverlap[0],
|
|
692
|
+
~~parameters.windowFunction[0],
|
|
693
|
+
inputChannels,
|
|
694
|
+
outputChannels,
|
|
695
|
+
bufferSize
|
|
696
|
+
);
|
|
589
697
|
if (!this.fDSPCode) return true;
|
|
590
698
|
for (const path in parameters) {
|
|
591
|
-
if (
|
|
699
|
+
if (fftParamKeywords.find((k) => `/${path}`.endsWith(k)))
|
|
700
|
+
continue;
|
|
592
701
|
const [paramValue] = parameters[path];
|
|
593
702
|
if (paramValue !== this.paramValuesCache[path]) {
|
|
594
703
|
this.setParamValue(path, paramValue);
|
|
@@ -614,7 +723,11 @@ var getFaustFFTAudioWorkletProcessor = (dependencies, faustData, register = true
|
|
|
614
723
|
for (let i = 0; i < input.length; i++) {
|
|
615
724
|
const inputWindow = this.fftInput[i];
|
|
616
725
|
const channel = input[i].length ? input[i] : new Float32Array(bufferSize);
|
|
617
|
-
$inputWrite = setTypedArray(
|
|
726
|
+
$inputWrite = setTypedArray(
|
|
727
|
+
inputWindow,
|
|
728
|
+
channel,
|
|
729
|
+
this.$inputWrite
|
|
730
|
+
);
|
|
618
731
|
}
|
|
619
732
|
this.$inputWrite = $inputWrite;
|
|
620
733
|
} else {
|
|
@@ -623,7 +736,12 @@ var getFaustFFTAudioWorkletProcessor = (dependencies, faustData, register = true
|
|
|
623
736
|
}
|
|
624
737
|
this.processFFT();
|
|
625
738
|
for (let i = 0; i < output.length; i++) {
|
|
626
|
-
setTypedArray(
|
|
739
|
+
setTypedArray(
|
|
740
|
+
output[i],
|
|
741
|
+
this.fftOutput[i],
|
|
742
|
+
0,
|
|
743
|
+
this.$outputRead
|
|
744
|
+
);
|
|
627
745
|
let div = 0;
|
|
628
746
|
for (let j = 0; j < bufferSize; j++) {
|
|
629
747
|
div = this.windowSumSquare[mod(this.$outputRead + j, this.fftBufferSize)];
|
|
@@ -633,7 +751,12 @@ var getFaustFFTAudioWorkletProcessor = (dependencies, faustData, register = true
|
|
|
633
751
|
this.$outputRead += bufferSize;
|
|
634
752
|
this.$outputRead %= this.fftBufferSize;
|
|
635
753
|
if (this.fPlotHandler) {
|
|
636
|
-
this.port.postMessage({
|
|
754
|
+
this.port.postMessage({
|
|
755
|
+
type: "plot",
|
|
756
|
+
value: output,
|
|
757
|
+
index: this.fBufferNum++,
|
|
758
|
+
events: this.fCachedEvents
|
|
759
|
+
});
|
|
637
760
|
this.fCachedEvents = [];
|
|
638
761
|
}
|
|
639
762
|
return true;
|
|
@@ -681,8 +804,15 @@ var getFaustFFTAudioWorkletProcessor = (dependencies, faustData, register = true
|
|
|
681
804
|
this.$inputRead = 0;
|
|
682
805
|
this.$outputWrite = 0;
|
|
683
806
|
this.$outputRead = -latency;
|
|
684
|
-
this.fftBufferSize = Math.max(
|
|
685
|
-
|
|
807
|
+
this.fftBufferSize = Math.max(
|
|
808
|
+
fftSize * 2 - this.fftHopSize,
|
|
809
|
+
bufferSize * 2
|
|
810
|
+
);
|
|
811
|
+
if (!fftSizeChanged && this.fftHopSizeParam)
|
|
812
|
+
(_a = this.fDSPCode) == null ? void 0 : _a.setParamValue(
|
|
813
|
+
this.fftHopSizeParam,
|
|
814
|
+
this.fftHopSize
|
|
815
|
+
);
|
|
686
816
|
}
|
|
687
817
|
if (fftSizeChanged) {
|
|
688
818
|
(_b = this.rfft) == null ? void 0 : _b.dispose();
|
|
@@ -718,7 +848,9 @@ var getFaustFFTAudioWorkletProcessor = (dependencies, faustData, register = true
|
|
|
718
848
|
}
|
|
719
849
|
if (this.fftOutput.length < outputChannels) {
|
|
720
850
|
for (let i = this.fftOutput.length; i < outputChannels; i++) {
|
|
721
|
-
this.fftOutput[i] = new Float32Array(
|
|
851
|
+
this.fftOutput[i] = new Float32Array(
|
|
852
|
+
this.fftBufferSize
|
|
853
|
+
);
|
|
722
854
|
}
|
|
723
855
|
}
|
|
724
856
|
}
|
|
@@ -727,20 +859,38 @@ var getFaustFFTAudioWorkletProcessor = (dependencies, faustData, register = true
|
|
|
727
859
|
var _a, _b;
|
|
728
860
|
(_a = this.fDSPCode) == null ? void 0 : _a.stop();
|
|
729
861
|
(_b = this.fDSPCode) == null ? void 0 : _b.destroy();
|
|
730
|
-
this.fDSPCode = new FaustMonoWebAudioDsp2(
|
|
731
|
-
|
|
862
|
+
this.fDSPCode = new FaustMonoWebAudioDsp2(
|
|
863
|
+
this.dspInstance,
|
|
864
|
+
sampleRate,
|
|
865
|
+
this.sampleSize,
|
|
866
|
+
this.fftProcessorBufferSize,
|
|
867
|
+
this.soundfiles
|
|
868
|
+
);
|
|
869
|
+
this.fDSPCode.setOutputParamHandler(
|
|
870
|
+
(path, value) => this.port.postMessage({ path, value, type: "param" })
|
|
871
|
+
);
|
|
732
872
|
this.fDSPCode.setPlotHandler(this.fPlotHandler);
|
|
733
873
|
const params = this.fDSPCode.getParams();
|
|
734
874
|
this.fDSPCode.start();
|
|
735
875
|
for (const path in this.paramValuesCache) {
|
|
736
|
-
if (
|
|
876
|
+
if (fftParamKeywords.find((k) => `/${path}`.endsWith(k)))
|
|
877
|
+
continue;
|
|
737
878
|
this.fDSPCode.setParamValue(path, this.paramValuesCache[path]);
|
|
738
879
|
}
|
|
739
880
|
const fftSizeParam = params.find((s) => s.endsWith("/fftSize"));
|
|
740
|
-
if (fftSizeParam)
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
881
|
+
if (fftSizeParam)
|
|
882
|
+
this.fDSPCode.setParamValue(fftSizeParam, this.fftSize);
|
|
883
|
+
this.fftHopSizeParam = params.find(
|
|
884
|
+
(s) => s.endsWith("/fftHopSize")
|
|
885
|
+
);
|
|
886
|
+
if (this.fftHopSizeParam)
|
|
887
|
+
this.fDSPCode.setParamValue(
|
|
888
|
+
this.fftHopSizeParam,
|
|
889
|
+
this.fftHopSize
|
|
890
|
+
);
|
|
891
|
+
this.fftProcessorZeros = new Float32Array(
|
|
892
|
+
this.fftProcessorBufferSize
|
|
893
|
+
);
|
|
744
894
|
}
|
|
745
895
|
destroy() {
|
|
746
896
|
var _a, _b, _c;
|
|
@@ -753,7 +903,10 @@ var getFaustFFTAudioWorkletProcessor = (dependencies, faustData, register = true
|
|
|
753
903
|
const Processor = FaustFFTAudioWorkletProcessor;
|
|
754
904
|
if (register) {
|
|
755
905
|
try {
|
|
756
|
-
registerProcessor(
|
|
906
|
+
registerProcessor(
|
|
907
|
+
processorName || dspName || "myfftdsp",
|
|
908
|
+
Processor
|
|
909
|
+
);
|
|
757
910
|
} catch (error) {
|
|
758
911
|
console.warn(error);
|
|
759
912
|
}
|
|
@@ -1162,7 +1315,11 @@ var _FaustCompiler = class _FaustCompiler {
|
|
|
1162
1315
|
const table = {};
|
|
1163
1316
|
this.gFactories.forEach((factory, shaKey) => {
|
|
1164
1317
|
const { code, json, poly } = factory;
|
|
1165
|
-
table[shaKey] = {
|
|
1318
|
+
table[shaKey] = {
|
|
1319
|
+
code: btoa(ab2str(code)),
|
|
1320
|
+
json: JSON.parse(json),
|
|
1321
|
+
poly
|
|
1322
|
+
};
|
|
1166
1323
|
});
|
|
1167
1324
|
return table;
|
|
1168
1325
|
}
|
|
@@ -1181,7 +1338,19 @@ var _FaustCompiler = class _FaustCompiler {
|
|
|
1181
1338
|
const factory = table[shaKey];
|
|
1182
1339
|
const { code, json, poly } = factory;
|
|
1183
1340
|
const ab = str2ab(atob(code));
|
|
1184
|
-
awaited.push(
|
|
1341
|
+
awaited.push(
|
|
1342
|
+
WebAssembly.compile(ab).then(
|
|
1343
|
+
(module) => this.gFactories.set(shaKey, {
|
|
1344
|
+
shaKey,
|
|
1345
|
+
cfactory: 0,
|
|
1346
|
+
code: ab,
|
|
1347
|
+
module,
|
|
1348
|
+
json: JSON.stringify(json),
|
|
1349
|
+
poly,
|
|
1350
|
+
soundfiles: {}
|
|
1351
|
+
})
|
|
1352
|
+
)
|
|
1353
|
+
);
|
|
1185
1354
|
}
|
|
1186
1355
|
return Promise.all(awaited);
|
|
1187
1356
|
}
|
|
@@ -1208,16 +1377,31 @@ var _FaustCompiler = class _FaustCompiler {
|
|
|
1208
1377
|
if (_FaustCompiler.gFactories.size > 10) {
|
|
1209
1378
|
_FaustCompiler.gFactories.clear();
|
|
1210
1379
|
}
|
|
1211
|
-
|
|
1380
|
+
const shaKey = await sha256(
|
|
1381
|
+
name + code + args + (poly ? "poly" : "mono")
|
|
1382
|
+
);
|
|
1212
1383
|
if (_FaustCompiler.gFactories.has(shaKey)) {
|
|
1213
1384
|
return _FaustCompiler.gFactories.get(shaKey) || null;
|
|
1214
1385
|
} else {
|
|
1215
1386
|
try {
|
|
1216
|
-
const faustDspWasm = this.fLibFaust.createDSPFactory(
|
|
1387
|
+
const faustDspWasm = this.fLibFaust.createDSPFactory(
|
|
1388
|
+
name,
|
|
1389
|
+
code,
|
|
1390
|
+
args,
|
|
1391
|
+
!poly
|
|
1392
|
+
);
|
|
1217
1393
|
const ui8Code = this.intVec2intArray(faustDspWasm.data);
|
|
1218
1394
|
faustDspWasm.data.delete();
|
|
1219
1395
|
const module = await WebAssembly.compile(ui8Code);
|
|
1220
|
-
const factory = {
|
|
1396
|
+
const factory = {
|
|
1397
|
+
shaKey,
|
|
1398
|
+
cfactory: faustDspWasm.cfactory,
|
|
1399
|
+
code: ui8Code,
|
|
1400
|
+
module,
|
|
1401
|
+
json: faustDspWasm.json,
|
|
1402
|
+
poly,
|
|
1403
|
+
soundfiles: {}
|
|
1404
|
+
};
|
|
1221
1405
|
this.deleteDSPFactory(factory);
|
|
1222
1406
|
_FaustCompiler.gFactories.set(shaKey, factory);
|
|
1223
1407
|
return factory;
|
|
@@ -1271,18 +1455,28 @@ var _FaustCompiler = class _FaustCompiler {
|
|
|
1271
1455
|
async getAsyncInternalMixerModule(isDouble = false) {
|
|
1272
1456
|
const bufferKey = isDouble ? "mixer64Buffer" : "mixer32Buffer";
|
|
1273
1457
|
const moduleKey = isDouble ? "mixer64Module" : "mixer32Module";
|
|
1274
|
-
if (this[moduleKey])
|
|
1458
|
+
if (this[moduleKey])
|
|
1459
|
+
return {
|
|
1460
|
+
mixerBuffer: this[bufferKey],
|
|
1461
|
+
mixerModule: this[moduleKey]
|
|
1462
|
+
};
|
|
1275
1463
|
const path = isDouble ? "/usr/rsrc/mixer64.wasm" : "/usr/rsrc/mixer32.wasm";
|
|
1276
1464
|
const mixerBuffer = this.fs().readFile(path, { encoding: "binary" });
|
|
1277
1465
|
this[bufferKey] = mixerBuffer;
|
|
1278
|
-
const mixerModule = await WebAssembly.compile(
|
|
1466
|
+
const mixerModule = await WebAssembly.compile(
|
|
1467
|
+
new Uint8Array(mixerBuffer)
|
|
1468
|
+
);
|
|
1279
1469
|
this[moduleKey] = mixerModule;
|
|
1280
1470
|
return { mixerBuffer, mixerModule };
|
|
1281
1471
|
}
|
|
1282
1472
|
getSyncInternalMixerModule(isDouble = false) {
|
|
1283
1473
|
const bufferKey = isDouble ? "mixer64Buffer" : "mixer32Buffer";
|
|
1284
1474
|
const moduleKey = isDouble ? "mixer64Module" : "mixer32Module";
|
|
1285
|
-
if (this[moduleKey])
|
|
1475
|
+
if (this[moduleKey])
|
|
1476
|
+
return {
|
|
1477
|
+
mixerBuffer: this[bufferKey],
|
|
1478
|
+
mixerModule: this[moduleKey]
|
|
1479
|
+
};
|
|
1286
1480
|
const path = isDouble ? "/usr/rsrc/mixer64.wasm" : "/usr/rsrc/mixer32.wasm";
|
|
1287
1481
|
const mixerBuffer = this.fs().readFile(path, { encoding: "binary" });
|
|
1288
1482
|
this[bufferKey] = mixerBuffer;
|
|
@@ -1419,7 +1613,8 @@ var FaustWasmInstantiator = class {
|
|
|
1419
1613
|
};
|
|
1420
1614
|
const effectSize = effectMeta ? effectMeta.size : 0;
|
|
1421
1615
|
let memorySize = pow2limit(
|
|
1422
|
-
effectSize + dspMeta.size * voices + (dspMeta.inputs + dspMeta.outputs * 2) *
|
|
1616
|
+
effectSize + dspMeta.size * voices + (dspMeta.inputs + dspMeta.outputs * 2) * // + 2 for effect
|
|
1617
|
+
(ptrSize + bufferSize * sampleSize)
|
|
1423
1618
|
) / 65536;
|
|
1424
1619
|
memorySize = Math.max(2, memorySize);
|
|
1425
1620
|
return new WebAssembly.Memory({ initial: memorySize });
|
|
@@ -1444,14 +1639,23 @@ var FaustWasmInstantiator = class {
|
|
|
1444
1639
|
const voiceMeta = JSON.parse(voiceFactory.json);
|
|
1445
1640
|
const effectMeta = effectFactory && effectFactory.json ? JSON.parse(effectFactory.json) : null;
|
|
1446
1641
|
const sampleSize = voiceMeta.compile_options.match("-double") ? 8 : 4;
|
|
1447
|
-
return this.createWasmMemoryPoly(
|
|
1642
|
+
return this.createWasmMemoryPoly(
|
|
1643
|
+
voices,
|
|
1644
|
+
sampleSize,
|
|
1645
|
+
voiceMeta,
|
|
1646
|
+
effectMeta,
|
|
1647
|
+
8192
|
|
1648
|
+
);
|
|
1448
1649
|
}
|
|
1449
1650
|
static createMixerAux(mixerModule, memory) {
|
|
1450
1651
|
const mixerImport = {
|
|
1451
1652
|
imports: { print: console.log },
|
|
1452
1653
|
memory: { memory }
|
|
1453
1654
|
};
|
|
1454
|
-
const mixerInstance = new WebAssembly.Instance(
|
|
1655
|
+
const mixerInstance = new WebAssembly.Instance(
|
|
1656
|
+
mixerModule,
|
|
1657
|
+
mixerImport
|
|
1658
|
+
);
|
|
1455
1659
|
const mixerFunctions = mixerInstance.exports;
|
|
1456
1660
|
return mixerFunctions;
|
|
1457
1661
|
}
|
|
@@ -1459,7 +1663,9 @@ var FaustWasmInstantiator = class {
|
|
|
1459
1663
|
static async loadDSPFactory(wasmPath, jsonPath) {
|
|
1460
1664
|
const wasmFile = await fetch(wasmPath);
|
|
1461
1665
|
if (!wasmFile.ok) {
|
|
1462
|
-
throw new Error(
|
|
1666
|
+
throw new Error(
|
|
1667
|
+
`=> exception raised while running loadDSPFactory, file not found: ${wasmPath}`
|
|
1668
|
+
);
|
|
1463
1669
|
}
|
|
1464
1670
|
try {
|
|
1465
1671
|
const wasmBuffer = await wasmFile.arrayBuffer();
|
|
@@ -1469,7 +1675,13 @@ var FaustWasmInstantiator = class {
|
|
|
1469
1675
|
const meta = JSON.parse(json);
|
|
1470
1676
|
const cOptions = meta.compile_options;
|
|
1471
1677
|
const poly = cOptions.indexOf("wasm-e") !== -1;
|
|
1472
|
-
return {
|
|
1678
|
+
return {
|
|
1679
|
+
cfactory: 0,
|
|
1680
|
+
code: new Uint8Array(wasmBuffer),
|
|
1681
|
+
module,
|
|
1682
|
+
json,
|
|
1683
|
+
poly
|
|
1684
|
+
};
|
|
1473
1685
|
} catch (e) {
|
|
1474
1686
|
throw e;
|
|
1475
1687
|
}
|
|
@@ -1478,7 +1690,9 @@ var FaustWasmInstantiator = class {
|
|
|
1478
1690
|
try {
|
|
1479
1691
|
let mixerBuffer = null;
|
|
1480
1692
|
if (fs) {
|
|
1481
|
-
mixerBuffer = new Uint8Array(
|
|
1693
|
+
mixerBuffer = new Uint8Array(
|
|
1694
|
+
fs.readFile(mixerPath, { encoding: "binary" })
|
|
1695
|
+
);
|
|
1482
1696
|
} else {
|
|
1483
1697
|
const mixerFile = await fetch(mixerPath);
|
|
1484
1698
|
mixerBuffer = await mixerFile.arrayBuffer();
|
|
@@ -1493,10 +1707,20 @@ var FaustWasmInstantiator = class {
|
|
|
1493
1707
|
const isDetected = pattern.test(factory.json);
|
|
1494
1708
|
if (isDetected) {
|
|
1495
1709
|
const memory = this.createMemoryMono(factory);
|
|
1496
|
-
const instance = await WebAssembly.instantiate(
|
|
1497
|
-
|
|
1710
|
+
const instance = await WebAssembly.instantiate(
|
|
1711
|
+
factory.module,
|
|
1712
|
+
this.createWasmImport(memory)
|
|
1713
|
+
);
|
|
1714
|
+
return this.createMonoDSPInstanceAux(
|
|
1715
|
+
instance,
|
|
1716
|
+
factory.json,
|
|
1717
|
+
memory
|
|
1718
|
+
);
|
|
1498
1719
|
} else {
|
|
1499
|
-
const instance = await WebAssembly.instantiate(
|
|
1720
|
+
const instance = await WebAssembly.instantiate(
|
|
1721
|
+
factory.module,
|
|
1722
|
+
this.createWasmImport()
|
|
1723
|
+
);
|
|
1500
1724
|
return this.createMonoDSPInstanceAux(instance, factory.json);
|
|
1501
1725
|
}
|
|
1502
1726
|
}
|
|
@@ -1505,21 +1729,41 @@ var FaustWasmInstantiator = class {
|
|
|
1505
1729
|
const isDetected = pattern.test(factory.json);
|
|
1506
1730
|
if (isDetected) {
|
|
1507
1731
|
const memory = this.createMemoryMono(factory);
|
|
1508
|
-
const instance = new WebAssembly.Instance(
|
|
1509
|
-
|
|
1732
|
+
const instance = new WebAssembly.Instance(
|
|
1733
|
+
factory.module,
|
|
1734
|
+
this.createWasmImport(memory)
|
|
1735
|
+
);
|
|
1736
|
+
return this.createMonoDSPInstanceAux(
|
|
1737
|
+
instance,
|
|
1738
|
+
factory.json,
|
|
1739
|
+
memory
|
|
1740
|
+
);
|
|
1510
1741
|
} else {
|
|
1511
|
-
const instance = new WebAssembly.Instance(
|
|
1742
|
+
const instance = new WebAssembly.Instance(
|
|
1743
|
+
factory.module,
|
|
1744
|
+
this.createWasmImport()
|
|
1745
|
+
);
|
|
1512
1746
|
return this.createMonoDSPInstanceAux(instance, factory.json);
|
|
1513
1747
|
}
|
|
1514
1748
|
}
|
|
1515
1749
|
static async createAsyncPolyDSPInstance(voiceFactory, mixerModule, voices, effectFactory) {
|
|
1516
|
-
const memory = this.createMemoryPoly(
|
|
1517
|
-
|
|
1750
|
+
const memory = this.createMemoryPoly(
|
|
1751
|
+
voices,
|
|
1752
|
+
voiceFactory,
|
|
1753
|
+
effectFactory
|
|
1754
|
+
);
|
|
1755
|
+
const voiceInstance = await WebAssembly.instantiate(
|
|
1756
|
+
voiceFactory.module,
|
|
1757
|
+
this.createWasmImport(memory)
|
|
1758
|
+
);
|
|
1518
1759
|
const voiceFunctions = voiceInstance.exports;
|
|
1519
1760
|
const voiceAPI = new FaustDspInstance(voiceFunctions);
|
|
1520
1761
|
const mixerAPI = this.createMixerAux(mixerModule, memory);
|
|
1521
1762
|
if (effectFactory) {
|
|
1522
|
-
const effectInstance = await WebAssembly.instantiate(
|
|
1763
|
+
const effectInstance = await WebAssembly.instantiate(
|
|
1764
|
+
effectFactory.module,
|
|
1765
|
+
this.createWasmImport(memory)
|
|
1766
|
+
);
|
|
1523
1767
|
const effectFunctions = effectInstance.exports;
|
|
1524
1768
|
const effectAPI = new FaustDspInstance(effectFunctions);
|
|
1525
1769
|
return {
|
|
@@ -1542,13 +1786,23 @@ var FaustWasmInstantiator = class {
|
|
|
1542
1786
|
}
|
|
1543
1787
|
}
|
|
1544
1788
|
static createSyncPolyDSPInstance(voiceFactory, mixerModule, voices, effectFactory) {
|
|
1545
|
-
const memory = this.createMemoryPoly(
|
|
1546
|
-
|
|
1789
|
+
const memory = this.createMemoryPoly(
|
|
1790
|
+
voices,
|
|
1791
|
+
voiceFactory,
|
|
1792
|
+
effectFactory
|
|
1793
|
+
);
|
|
1794
|
+
const voiceInstance = new WebAssembly.Instance(
|
|
1795
|
+
voiceFactory.module,
|
|
1796
|
+
this.createWasmImport(memory)
|
|
1797
|
+
);
|
|
1547
1798
|
const voiceFunctions = voiceInstance.exports;
|
|
1548
1799
|
const voiceAPI = new FaustDspInstance(voiceFunctions);
|
|
1549
1800
|
const mixerAPI = this.createMixerAux(mixerModule, memory);
|
|
1550
1801
|
if (effectFactory) {
|
|
1551
|
-
const effectInstance = new WebAssembly.Instance(
|
|
1802
|
+
const effectInstance = new WebAssembly.Instance(
|
|
1803
|
+
effectFactory.module,
|
|
1804
|
+
this.createWasmImport(memory)
|
|
1805
|
+
);
|
|
1552
1806
|
const effectFunctions = effectInstance.exports;
|
|
1553
1807
|
const effectAPI = new FaustDspInstance(effectFunctions);
|
|
1554
1808
|
return {
|
|
@@ -1577,7 +1831,7 @@ var FaustWasmInstantiator_default = FaustWasmInstantiator;
|
|
|
1577
1831
|
var FaustSensors = class _FaustSensors {
|
|
1578
1832
|
/**
|
|
1579
1833
|
* Function to convert a number to an axis type
|
|
1580
|
-
*
|
|
1834
|
+
*
|
|
1581
1835
|
* @param value number
|
|
1582
1836
|
* @returns axis type
|
|
1583
1837
|
*/
|
|
@@ -1596,7 +1850,7 @@ var FaustSensors = class _FaustSensors {
|
|
|
1596
1850
|
}
|
|
1597
1851
|
/**
|
|
1598
1852
|
* Function to convert a number to a curve type
|
|
1599
|
-
*
|
|
1853
|
+
*
|
|
1600
1854
|
* @param value number
|
|
1601
1855
|
* @returns curve type
|
|
1602
1856
|
*/
|
|
@@ -1648,7 +1902,7 @@ var FaustSensors = class _FaustSensors {
|
|
|
1648
1902
|
}
|
|
1649
1903
|
}
|
|
1650
1904
|
returnMappedValue(v) {
|
|
1651
|
-
|
|
1905
|
+
const x = this.fRange.clip(v);
|
|
1652
1906
|
return this.fOffset + x * this.fCoef;
|
|
1653
1907
|
}
|
|
1654
1908
|
getLowHigh(amin, amax) {
|
|
@@ -1665,17 +1919,37 @@ var FaustSensors = class _FaustSensors {
|
|
|
1665
1919
|
if (!this._Interpolator3pt) {
|
|
1666
1920
|
this._Interpolator3pt = class {
|
|
1667
1921
|
constructor(lo, mid, hi, v1, vMid, v2) {
|
|
1668
|
-
this.fSegment1 = new _FaustSensors.Interpolator(
|
|
1669
|
-
|
|
1922
|
+
this.fSegment1 = new _FaustSensors.Interpolator(
|
|
1923
|
+
lo,
|
|
1924
|
+
mid,
|
|
1925
|
+
v1,
|
|
1926
|
+
vMid
|
|
1927
|
+
);
|
|
1928
|
+
this.fSegment2 = new _FaustSensors.Interpolator(
|
|
1929
|
+
mid,
|
|
1930
|
+
hi,
|
|
1931
|
+
vMid,
|
|
1932
|
+
v2
|
|
1933
|
+
);
|
|
1670
1934
|
this.fMid = mid;
|
|
1671
1935
|
}
|
|
1672
1936
|
returnMappedValue(x) {
|
|
1673
1937
|
return x < this.fMid ? this.fSegment1.returnMappedValue(x) : this.fSegment2.returnMappedValue(x);
|
|
1674
1938
|
}
|
|
1675
1939
|
getMappingValues(amin, amid, amax) {
|
|
1676
|
-
|
|
1677
|
-
|
|
1678
|
-
|
|
1940
|
+
const lowHighSegment1 = this.fSegment1.getLowHigh(
|
|
1941
|
+
amin,
|
|
1942
|
+
amid
|
|
1943
|
+
);
|
|
1944
|
+
const lowHighSegment2 = this.fSegment2.getLowHigh(
|
|
1945
|
+
amid,
|
|
1946
|
+
amax
|
|
1947
|
+
);
|
|
1948
|
+
return {
|
|
1949
|
+
amin: lowHighSegment1.amin,
|
|
1950
|
+
amid: lowHighSegment2.amin,
|
|
1951
|
+
amax: lowHighSegment2.amax
|
|
1952
|
+
};
|
|
1679
1953
|
}
|
|
1680
1954
|
};
|
|
1681
1955
|
}
|
|
@@ -1689,8 +1963,22 @@ var FaustSensors = class _FaustSensors {
|
|
|
1689
1963
|
this._UpConverter = class {
|
|
1690
1964
|
constructor(amin, amid, amax, fmin, fmid, fmax) {
|
|
1691
1965
|
this.fActive = true;
|
|
1692
|
-
this.fA2F = new _FaustSensors.Interpolator3pt(
|
|
1693
|
-
|
|
1966
|
+
this.fA2F = new _FaustSensors.Interpolator3pt(
|
|
1967
|
+
amin,
|
|
1968
|
+
amid,
|
|
1969
|
+
amax,
|
|
1970
|
+
fmin,
|
|
1971
|
+
fmid,
|
|
1972
|
+
fmax
|
|
1973
|
+
);
|
|
1974
|
+
this.fF2A = new _FaustSensors.Interpolator3pt(
|
|
1975
|
+
fmin,
|
|
1976
|
+
fmid,
|
|
1977
|
+
fmax,
|
|
1978
|
+
amin,
|
|
1979
|
+
amid,
|
|
1980
|
+
amax
|
|
1981
|
+
);
|
|
1694
1982
|
}
|
|
1695
1983
|
uiToFaust(x) {
|
|
1696
1984
|
return this.fA2F.returnMappedValue(x);
|
|
@@ -1699,8 +1987,22 @@ var FaustSensors = class _FaustSensors {
|
|
|
1699
1987
|
return this.fF2A.returnMappedValue(x);
|
|
1700
1988
|
}
|
|
1701
1989
|
setMappingValues(amin, amid, amax, min, init, max) {
|
|
1702
|
-
this.fA2F = new _FaustSensors.Interpolator3pt(
|
|
1703
|
-
|
|
1990
|
+
this.fA2F = new _FaustSensors.Interpolator3pt(
|
|
1991
|
+
amin,
|
|
1992
|
+
amid,
|
|
1993
|
+
amax,
|
|
1994
|
+
min,
|
|
1995
|
+
init,
|
|
1996
|
+
max
|
|
1997
|
+
);
|
|
1998
|
+
this.fF2A = new _FaustSensors.Interpolator3pt(
|
|
1999
|
+
min,
|
|
2000
|
+
init,
|
|
2001
|
+
max,
|
|
2002
|
+
amin,
|
|
2003
|
+
amid,
|
|
2004
|
+
amax
|
|
2005
|
+
);
|
|
1704
2006
|
}
|
|
1705
2007
|
getMappingValues(amin, amid, amax) {
|
|
1706
2008
|
return this.fA2F.getMappingValues(amin, amid, amax);
|
|
@@ -1723,8 +2025,22 @@ var FaustSensors = class _FaustSensors {
|
|
|
1723
2025
|
this._DownConverter = class {
|
|
1724
2026
|
constructor(amin, amid, amax, fmin, fmid, fmax) {
|
|
1725
2027
|
this.fActive = true;
|
|
1726
|
-
this.fA2F = new _FaustSensors.Interpolator3pt(
|
|
1727
|
-
|
|
2028
|
+
this.fA2F = new _FaustSensors.Interpolator3pt(
|
|
2029
|
+
amin,
|
|
2030
|
+
amid,
|
|
2031
|
+
amax,
|
|
2032
|
+
fmax,
|
|
2033
|
+
fmid,
|
|
2034
|
+
fmin
|
|
2035
|
+
);
|
|
2036
|
+
this.fF2A = new _FaustSensors.Interpolator3pt(
|
|
2037
|
+
fmin,
|
|
2038
|
+
fmid,
|
|
2039
|
+
fmax,
|
|
2040
|
+
amax,
|
|
2041
|
+
amid,
|
|
2042
|
+
amin
|
|
2043
|
+
);
|
|
1728
2044
|
}
|
|
1729
2045
|
uiToFaust(x) {
|
|
1730
2046
|
return this.fA2F.returnMappedValue(x);
|
|
@@ -1733,8 +2049,22 @@ var FaustSensors = class _FaustSensors {
|
|
|
1733
2049
|
return this.fF2A.returnMappedValue(x);
|
|
1734
2050
|
}
|
|
1735
2051
|
setMappingValues(amin, amid, amax, min, init, max) {
|
|
1736
|
-
this.fA2F = new _FaustSensors.Interpolator3pt(
|
|
1737
|
-
|
|
2052
|
+
this.fA2F = new _FaustSensors.Interpolator3pt(
|
|
2053
|
+
amin,
|
|
2054
|
+
amid,
|
|
2055
|
+
amax,
|
|
2056
|
+
max,
|
|
2057
|
+
init,
|
|
2058
|
+
min
|
|
2059
|
+
);
|
|
2060
|
+
this.fF2A = new _FaustSensors.Interpolator3pt(
|
|
2061
|
+
min,
|
|
2062
|
+
init,
|
|
2063
|
+
max,
|
|
2064
|
+
amax,
|
|
2065
|
+
amid,
|
|
2066
|
+
amin
|
|
2067
|
+
);
|
|
1738
2068
|
}
|
|
1739
2069
|
getMappingValues(amin, amid, amax) {
|
|
1740
2070
|
return this.fA2F.getMappingValues(amin, amid, amax);
|
|
@@ -1757,8 +2087,20 @@ var FaustSensors = class _FaustSensors {
|
|
|
1757
2087
|
this._UpDownConverter = class {
|
|
1758
2088
|
constructor(amin, amid, amax, fmin, fmid, fmax) {
|
|
1759
2089
|
this.fActive = true;
|
|
1760
|
-
this.fA2F = new _FaustSensors.Interpolator3pt(
|
|
1761
|
-
|
|
2090
|
+
this.fA2F = new _FaustSensors.Interpolator3pt(
|
|
2091
|
+
amin,
|
|
2092
|
+
amid,
|
|
2093
|
+
amax,
|
|
2094
|
+
fmin,
|
|
2095
|
+
fmax,
|
|
2096
|
+
fmin
|
|
2097
|
+
);
|
|
2098
|
+
this.fF2A = new _FaustSensors.Interpolator(
|
|
2099
|
+
fmin,
|
|
2100
|
+
fmax,
|
|
2101
|
+
amin,
|
|
2102
|
+
amax
|
|
2103
|
+
);
|
|
1762
2104
|
}
|
|
1763
2105
|
uiToFaust(x) {
|
|
1764
2106
|
return this.fA2F.returnMappedValue(x);
|
|
@@ -1767,8 +2109,20 @@ var FaustSensors = class _FaustSensors {
|
|
|
1767
2109
|
return this.fF2A.returnMappedValue(x);
|
|
1768
2110
|
}
|
|
1769
2111
|
setMappingValues(amin, amid, amax, min, init, max) {
|
|
1770
|
-
this.fA2F = new _FaustSensors.Interpolator3pt(
|
|
1771
|
-
|
|
2112
|
+
this.fA2F = new _FaustSensors.Interpolator3pt(
|
|
2113
|
+
amin,
|
|
2114
|
+
amid,
|
|
2115
|
+
amax,
|
|
2116
|
+
min,
|
|
2117
|
+
max,
|
|
2118
|
+
min
|
|
2119
|
+
);
|
|
2120
|
+
this.fF2A = new _FaustSensors.Interpolator(
|
|
2121
|
+
min,
|
|
2122
|
+
max,
|
|
2123
|
+
amin,
|
|
2124
|
+
amax
|
|
2125
|
+
);
|
|
1772
2126
|
}
|
|
1773
2127
|
getMappingValues(amin, amid, amax) {
|
|
1774
2128
|
return this.fA2F.getMappingValues(amin, amid, amax);
|
|
@@ -1788,8 +2142,20 @@ var FaustSensors = class _FaustSensors {
|
|
|
1788
2142
|
this._DownUpConverter = class {
|
|
1789
2143
|
constructor(amin, amid, amax, fmin, fmid, fmax) {
|
|
1790
2144
|
this.fActive = true;
|
|
1791
|
-
this.fA2F = new _FaustSensors.Interpolator3pt(
|
|
1792
|
-
|
|
2145
|
+
this.fA2F = new _FaustSensors.Interpolator3pt(
|
|
2146
|
+
amin,
|
|
2147
|
+
amid,
|
|
2148
|
+
amax,
|
|
2149
|
+
fmax,
|
|
2150
|
+
fmin,
|
|
2151
|
+
fmax
|
|
2152
|
+
);
|
|
2153
|
+
this.fF2A = new _FaustSensors.Interpolator(
|
|
2154
|
+
fmin,
|
|
2155
|
+
fmax,
|
|
2156
|
+
amin,
|
|
2157
|
+
amax
|
|
2158
|
+
);
|
|
1793
2159
|
}
|
|
1794
2160
|
uiToFaust(x) {
|
|
1795
2161
|
return this.fA2F.returnMappedValue(x);
|
|
@@ -1798,8 +2164,20 @@ var FaustSensors = class _FaustSensors {
|
|
|
1798
2164
|
return this.fF2A.returnMappedValue(x);
|
|
1799
2165
|
}
|
|
1800
2166
|
setMappingValues(amin, amid, amax, min, init, max) {
|
|
1801
|
-
this.fA2F = new _FaustSensors.Interpolator3pt(
|
|
1802
|
-
|
|
2167
|
+
this.fA2F = new _FaustSensors.Interpolator3pt(
|
|
2168
|
+
amin,
|
|
2169
|
+
amid,
|
|
2170
|
+
amax,
|
|
2171
|
+
max,
|
|
2172
|
+
min,
|
|
2173
|
+
max
|
|
2174
|
+
);
|
|
2175
|
+
this.fF2A = new _FaustSensors.Interpolator(
|
|
2176
|
+
min,
|
|
2177
|
+
max,
|
|
2178
|
+
amin,
|
|
2179
|
+
amax
|
|
2180
|
+
);
|
|
1803
2181
|
}
|
|
1804
2182
|
getMappingValues(amin, amid, amax) {
|
|
1805
2183
|
return this.fA2F.getMappingValues(amin, amid, amax);
|
|
@@ -1822,15 +2200,50 @@ var FaustSensors = class _FaustSensors {
|
|
|
1822
2200
|
static buildHandler(curve, amin, amid, amax, min, init, max) {
|
|
1823
2201
|
switch (curve) {
|
|
1824
2202
|
case 0 /* Up */:
|
|
1825
|
-
return new _FaustSensors.UpConverter(
|
|
2203
|
+
return new _FaustSensors.UpConverter(
|
|
2204
|
+
amin,
|
|
2205
|
+
amid,
|
|
2206
|
+
amax,
|
|
2207
|
+
min,
|
|
2208
|
+
init,
|
|
2209
|
+
max
|
|
2210
|
+
);
|
|
1826
2211
|
case 1 /* Down */:
|
|
1827
|
-
return new _FaustSensors.DownConverter(
|
|
2212
|
+
return new _FaustSensors.DownConverter(
|
|
2213
|
+
amin,
|
|
2214
|
+
amid,
|
|
2215
|
+
amax,
|
|
2216
|
+
min,
|
|
2217
|
+
init,
|
|
2218
|
+
max
|
|
2219
|
+
);
|
|
1828
2220
|
case 2 /* UpDown */:
|
|
1829
|
-
return new _FaustSensors.UpDownConverter(
|
|
2221
|
+
return new _FaustSensors.UpDownConverter(
|
|
2222
|
+
amin,
|
|
2223
|
+
amid,
|
|
2224
|
+
amax,
|
|
2225
|
+
min,
|
|
2226
|
+
init,
|
|
2227
|
+
max
|
|
2228
|
+
);
|
|
1830
2229
|
case 3 /* DownUp */:
|
|
1831
|
-
return new _FaustSensors.DownUpConverter(
|
|
2230
|
+
return new _FaustSensors.DownUpConverter(
|
|
2231
|
+
amin,
|
|
2232
|
+
amid,
|
|
2233
|
+
amax,
|
|
2234
|
+
min,
|
|
2235
|
+
init,
|
|
2236
|
+
max
|
|
2237
|
+
);
|
|
1832
2238
|
default:
|
|
1833
|
-
return new _FaustSensors.UpConverter(
|
|
2239
|
+
return new _FaustSensors.UpConverter(
|
|
2240
|
+
amin,
|
|
2241
|
+
amid,
|
|
2242
|
+
amax,
|
|
2243
|
+
min,
|
|
2244
|
+
init,
|
|
2245
|
+
max
|
|
2246
|
+
);
|
|
1834
2247
|
}
|
|
1835
2248
|
}
|
|
1836
2249
|
};
|
|
@@ -1845,7 +2258,7 @@ var WasmAllocator = class {
|
|
|
1845
2258
|
* Allocates a block of memory of the specified size, returning the pointer to the
|
|
1846
2259
|
* beginning of the block. The block is allocated at the current offset and the
|
|
1847
2260
|
* offset is incremented by the size of the block.
|
|
1848
|
-
*
|
|
2261
|
+
*
|
|
1849
2262
|
* @param sizeInBytes The size of the block to allocate in bytes.
|
|
1850
2263
|
* @returns The offset (pointer) to the beginning of the allocated block.
|
|
1851
2264
|
*/
|
|
@@ -1854,7 +2267,9 @@ var WasmAllocator = class {
|
|
|
1854
2267
|
const newOffset = currentOffset + sizeInBytes;
|
|
1855
2268
|
const totalMemoryBytes = this.memory.buffer.byteLength;
|
|
1856
2269
|
if (newOffset > totalMemoryBytes) {
|
|
1857
|
-
const neededPages = Math.ceil(
|
|
2270
|
+
const neededPages = Math.ceil(
|
|
2271
|
+
(newOffset - totalMemoryBytes) / 65536
|
|
2272
|
+
);
|
|
1858
2273
|
console.log(`GROW: ${neededPages} pages`);
|
|
1859
2274
|
this.memory.grow(neededPages);
|
|
1860
2275
|
}
|
|
@@ -1863,7 +2278,7 @@ var WasmAllocator = class {
|
|
|
1863
2278
|
}
|
|
1864
2279
|
/**
|
|
1865
2280
|
* Returns the underlying buffer object.
|
|
1866
|
-
*
|
|
2281
|
+
*
|
|
1867
2282
|
* @returns The buffer object.
|
|
1868
2283
|
*/
|
|
1869
2284
|
getBuffer() {
|
|
@@ -1871,7 +2286,7 @@ var WasmAllocator = class {
|
|
|
1871
2286
|
}
|
|
1872
2287
|
/**
|
|
1873
2288
|
* Returns the Int32 view of the underlying buffer object.
|
|
1874
|
-
*
|
|
2289
|
+
*
|
|
1875
2290
|
* @returns The view of the memory buffer as Int32Array.
|
|
1876
2291
|
*/
|
|
1877
2292
|
getInt32Array() {
|
|
@@ -1879,7 +2294,7 @@ var WasmAllocator = class {
|
|
|
1879
2294
|
}
|
|
1880
2295
|
/**
|
|
1881
2296
|
* Returns the Int64 view of the underlying buffer object.
|
|
1882
|
-
*
|
|
2297
|
+
*
|
|
1883
2298
|
* @returns The view of the memory buffer as BigInt64Array.
|
|
1884
2299
|
*/
|
|
1885
2300
|
getInt64Array() {
|
|
@@ -1887,7 +2302,7 @@ var WasmAllocator = class {
|
|
|
1887
2302
|
}
|
|
1888
2303
|
/**
|
|
1889
2304
|
* Returns the Float32 view of the underlying buffer object.
|
|
1890
|
-
*
|
|
2305
|
+
*
|
|
1891
2306
|
* @returns The view of the memory buffer as Float32Array.
|
|
1892
2307
|
*/
|
|
1893
2308
|
getFloat32Array() {
|
|
@@ -1895,7 +2310,7 @@ var WasmAllocator = class {
|
|
|
1895
2310
|
}
|
|
1896
2311
|
/**
|
|
1897
2312
|
* Returns the Float64 view of the underlying buffer object..
|
|
1898
|
-
*
|
|
2313
|
+
*
|
|
1899
2314
|
* @returns The view of the memory buffer as Float64Array.
|
|
1900
2315
|
*/
|
|
1901
2316
|
getFloat64Array() {
|
|
@@ -1924,11 +2339,19 @@ var Soundfile = class _Soundfile {
|
|
|
1924
2339
|
this.fIntSize = this.fSampleSize;
|
|
1925
2340
|
this.fPtrSize = 4;
|
|
1926
2341
|
this.fAllocator = allocator;
|
|
1927
|
-
console.log(
|
|
2342
|
+
console.log(
|
|
2343
|
+
`Soundfile constructor: curChan: ${curChan}, length: ${length}, maxChan: ${maxChan}, totalParts: ${totalParts}`
|
|
2344
|
+
);
|
|
1928
2345
|
this.fPtr = allocator.alloc(4 * this.fPtrSize);
|
|
1929
|
-
this.fLength = allocator.alloc(
|
|
1930
|
-
|
|
1931
|
-
|
|
2346
|
+
this.fLength = allocator.alloc(
|
|
2347
|
+
_Soundfile.MAX_SOUNDFILE_PARTS * this.fIntSize
|
|
2348
|
+
);
|
|
2349
|
+
this.fSR = allocator.alloc(
|
|
2350
|
+
_Soundfile.MAX_SOUNDFILE_PARTS * this.fIntSize
|
|
2351
|
+
);
|
|
2352
|
+
this.fOffset = allocator.alloc(
|
|
2353
|
+
_Soundfile.MAX_SOUNDFILE_PARTS * this.fIntSize
|
|
2354
|
+
);
|
|
1932
2355
|
this.fBuffers = this.allocBuffers(curChan, length, maxChan);
|
|
1933
2356
|
const HEAP32 = this.fAllocator.getInt32Array();
|
|
1934
2357
|
HEAP32[this.fPtr >> 2] = this.fBuffers;
|
|
@@ -1944,7 +2367,9 @@ var Soundfile = class _Soundfile {
|
|
|
1944
2367
|
const buffers = this.fAllocator.alloc(maxChan * this.fPtrSize);
|
|
1945
2368
|
console.log(`allocBuffers buffers: ${buffers}`);
|
|
1946
2369
|
for (let chan = 0; chan < curChan; chan++) {
|
|
1947
|
-
const buffer = this.fAllocator.alloc(
|
|
2370
|
+
const buffer = this.fAllocator.alloc(
|
|
2371
|
+
length * this.fSampleSize
|
|
2372
|
+
);
|
|
1948
2373
|
const HEAP32 = this.fAllocator.getInt32Array();
|
|
1949
2374
|
HEAP32[(buffers >> 2) + chan] = buffer;
|
|
1950
2375
|
}
|
|
@@ -1964,11 +2389,17 @@ var Soundfile = class _Soundfile {
|
|
|
1964
2389
|
HEAP32[(this.fOffset >> Math.log2(this.fIntSize)) + part] = offset;
|
|
1965
2390
|
} else {
|
|
1966
2391
|
const HEAP64 = this.fAllocator.getInt64Array();
|
|
1967
|
-
HEAP64[(this.fLength >> Math.log2(this.fIntSize)) + part] = BigInt(
|
|
1968
|
-
|
|
2392
|
+
HEAP64[(this.fLength >> Math.log2(this.fIntSize)) + part] = BigInt(
|
|
2393
|
+
audioData.audioBuffer[0].length
|
|
2394
|
+
);
|
|
2395
|
+
HEAP64[(this.fSR >> Math.log2(this.fIntSize)) + part] = BigInt(
|
|
2396
|
+
audioData.sampleRate
|
|
2397
|
+
);
|
|
1969
2398
|
HEAP64[(this.fOffset >> Math.log2(this.fIntSize)) + part] = BigInt(offset);
|
|
1970
2399
|
}
|
|
1971
|
-
console.log(
|
|
2400
|
+
console.log(
|
|
2401
|
+
`copyToOut: part: ${part}, maxChannels: ${maxChannels}, offset: ${offset}, buffer: ${audioData}`
|
|
2402
|
+
);
|
|
1972
2403
|
if (this.fSampleSize === 8) {
|
|
1973
2404
|
this.copyToOutReal64(maxChannels, offset, audioData);
|
|
1974
2405
|
} else {
|
|
@@ -1983,7 +2414,9 @@ var Soundfile = class _Soundfile {
|
|
|
1983
2414
|
const output = HEAP32[(this.fBuffers >> 2) + chan];
|
|
1984
2415
|
const begin = output + offset * this.fSampleSize >> Math.log2(this.fSampleSize);
|
|
1985
2416
|
const end = output + (offset + input.length) * this.fSampleSize >> Math.log2(this.fSampleSize);
|
|
1986
|
-
console.log(
|
|
2417
|
+
console.log(
|
|
2418
|
+
`copyToOutReal32 begin: ${begin}, end: ${end}, delta: ${end - begin}`
|
|
2419
|
+
);
|
|
1987
2420
|
const outputReal = HEAPF.subarray(
|
|
1988
2421
|
output + offset * this.fSampleSize >> Math.log2(this.fSampleSize),
|
|
1989
2422
|
output + (offset + input.length) * this.fSampleSize >> Math.log2(this.fSampleSize)
|
|
@@ -2001,7 +2434,9 @@ var Soundfile = class _Soundfile {
|
|
|
2001
2434
|
const output = HEAP32[(this.fBuffers >> 2) + chan];
|
|
2002
2435
|
const begin = output + offset * this.fSampleSize >> Math.log2(this.fSampleSize);
|
|
2003
2436
|
const end = output + (offset + input.length) * this.fSampleSize >> Math.log2(this.fSampleSize);
|
|
2004
|
-
console.log(
|
|
2437
|
+
console.log(
|
|
2438
|
+
`copyToOutReal64 begin: ${begin}, end: ${end}, delta: ${end - begin}`
|
|
2439
|
+
);
|
|
2005
2440
|
const outputReal = HEAPF.subarray(
|
|
2006
2441
|
output + offset * this.fSampleSize >> Math.log2(this.fSampleSize),
|
|
2007
2442
|
output + (offset + input.length) * this.fSampleSize >> Math.log2(this.fSampleSize)
|
|
@@ -2019,8 +2454,12 @@ var Soundfile = class _Soundfile {
|
|
|
2019
2454
|
HEAP32[(this.fOffset >> Math.log2(this.fIntSize)) + part] = offset;
|
|
2020
2455
|
} else {
|
|
2021
2456
|
const HEAP64 = this.fAllocator.getInt64Array();
|
|
2022
|
-
HEAP64[(this.fLength >> Math.log2(this.fIntSize)) + part] = BigInt(
|
|
2023
|
-
|
|
2457
|
+
HEAP64[(this.fLength >> Math.log2(this.fIntSize)) + part] = BigInt(
|
|
2458
|
+
_Soundfile.BUFFER_SIZE
|
|
2459
|
+
);
|
|
2460
|
+
HEAP64[(this.fSR >> Math.log2(this.fIntSize)) + part] = BigInt(
|
|
2461
|
+
_Soundfile.SAMPLE_RATE
|
|
2462
|
+
);
|
|
2024
2463
|
HEAP64[(this.fOffset >> Math.log2(this.fIntSize)) + part] = BigInt(offset);
|
|
2025
2464
|
}
|
|
2026
2465
|
return offset + _Soundfile.BUFFER_SIZE;
|
|
@@ -2035,9 +2474,15 @@ var Soundfile = class _Soundfile {
|
|
|
2035
2474
|
const HEAP32 = this.fAllocator.getInt32Array();
|
|
2036
2475
|
if (mem) console.log(`HEAP32: ${HEAP32}`);
|
|
2037
2476
|
console.log(`HEAP32[this.fPtr >> 2]: ${HEAP32[this.fPtr >> 2]}`);
|
|
2038
|
-
console.log(
|
|
2039
|
-
|
|
2040
|
-
|
|
2477
|
+
console.log(
|
|
2478
|
+
`HEAP32[(this.fPtr + ptrSize) >> 2]: ${HEAP32[this.fPtr + this.fPtrSize >> 2]}`
|
|
2479
|
+
);
|
|
2480
|
+
console.log(
|
|
2481
|
+
`HEAP32[(this.fPtr + 2 * ptrSize) >> 2]: ${HEAP32[this.fPtr + 2 * this.fPtrSize >> 2]}`
|
|
2482
|
+
);
|
|
2483
|
+
console.log(
|
|
2484
|
+
`HEAP32[(this.fPtr + 3 * ptrSize) >> 2]: ${HEAP32[this.fPtr + 3 * this.fPtrSize >> 2]}`
|
|
2485
|
+
);
|
|
2041
2486
|
}
|
|
2042
2487
|
// Return the pointer to the soundfile structure in wasm memory
|
|
2043
2488
|
getPtr() {
|
|
@@ -2096,46 +2541,112 @@ var FaustBaseWebAudioDsp = class _FaustBaseWebAudioDsp {
|
|
|
2096
2541
|
if (strMidi === "pitchwheel") {
|
|
2097
2542
|
const matched = strMidi.match(/^pitchwheel\s(\d+)/);
|
|
2098
2543
|
if (matched) {
|
|
2099
|
-
this.fPitchwheelLabel.push({
|
|
2544
|
+
this.fPitchwheelLabel.push({
|
|
2545
|
+
path: item.address,
|
|
2546
|
+
chan: parseInt(matched[1]),
|
|
2547
|
+
min: item.min,
|
|
2548
|
+
max: item.max
|
|
2549
|
+
});
|
|
2100
2550
|
} else {
|
|
2101
|
-
this.fPitchwheelLabel.push({
|
|
2551
|
+
this.fPitchwheelLabel.push({
|
|
2552
|
+
path: item.address,
|
|
2553
|
+
chan: 0,
|
|
2554
|
+
min: item.min,
|
|
2555
|
+
max: item.max
|
|
2556
|
+
});
|
|
2102
2557
|
}
|
|
2103
2558
|
} else {
|
|
2104
2559
|
const matched2 = strMidi.match(/^ctrl\s(\d+)\s(\d+)/);
|
|
2105
2560
|
const matched1 = strMidi.match(/^ctrl\s(\d+)/);
|
|
2106
|
-
const matchedKey = strMidi.match(
|
|
2107
|
-
|
|
2108
|
-
|
|
2561
|
+
const matchedKey = strMidi.match(
|
|
2562
|
+
/^key\s+(\d+)(?:\s+(\d+))?$/
|
|
2563
|
+
);
|
|
2564
|
+
const matchedKeyOn = strMidi.match(
|
|
2565
|
+
/^keyon\s+(\d+)(?:\s+(\d+))?$/
|
|
2566
|
+
);
|
|
2567
|
+
const matchedKeyOff = strMidi.match(
|
|
2568
|
+
/^keyoff\s+(\d+)(?:\s+(\d+))?$/
|
|
2569
|
+
);
|
|
2109
2570
|
if (matched2) {
|
|
2110
|
-
this.fCtrlLabel[parseInt(matched2[1])].push({
|
|
2571
|
+
this.fCtrlLabel[parseInt(matched2[1])].push({
|
|
2572
|
+
path: item.address,
|
|
2573
|
+
chan: parseInt(matched2[2]),
|
|
2574
|
+
min: item.min,
|
|
2575
|
+
max: item.max
|
|
2576
|
+
});
|
|
2111
2577
|
} else if (matched1) {
|
|
2112
|
-
this.fCtrlLabel[parseInt(matched1[1])].push({
|
|
2578
|
+
this.fCtrlLabel[parseInt(matched1[1])].push({
|
|
2579
|
+
path: item.address,
|
|
2580
|
+
chan: 0,
|
|
2581
|
+
min: item.min,
|
|
2582
|
+
max: item.max
|
|
2583
|
+
});
|
|
2113
2584
|
} else if (matchedKey) {
|
|
2114
2585
|
const note = parseInt(matchedKey[1]);
|
|
2115
2586
|
const channel = matchedKey[2] ? parseInt(matchedKey[2]) : 0;
|
|
2116
|
-
this.fMidiKeyLabel[note].push({
|
|
2587
|
+
this.fMidiKeyLabel[note].push({
|
|
2588
|
+
path: item.address,
|
|
2589
|
+
chan: channel,
|
|
2590
|
+
min: (_a = item.min) != null ? _a : 0,
|
|
2591
|
+
max: (_b = item.max) != null ? _b : 1
|
|
2592
|
+
});
|
|
2117
2593
|
} else if (matchedKeyOn) {
|
|
2118
2594
|
const note = parseInt(matchedKeyOn[1]);
|
|
2119
2595
|
const channel = matchedKeyOn[2] ? parseInt(matchedKeyOn[2]) : 0;
|
|
2120
|
-
this.fMidiKeyOnLabel[note].push({
|
|
2596
|
+
this.fMidiKeyOnLabel[note].push({
|
|
2597
|
+
path: item.address,
|
|
2598
|
+
chan: channel,
|
|
2599
|
+
min: (_c = item.min) != null ? _c : 0,
|
|
2600
|
+
max: (_d = item.max) != null ? _d : 1
|
|
2601
|
+
});
|
|
2121
2602
|
} else if (matchedKeyOff) {
|
|
2122
2603
|
const note = parseInt(matchedKeyOff[1]);
|
|
2123
2604
|
const channel = matchedKeyOff[2] ? parseInt(matchedKeyOff[2]) : 0;
|
|
2124
|
-
this.fMidiKeyOffLabel[note].push({
|
|
2605
|
+
this.fMidiKeyOffLabel[note].push({
|
|
2606
|
+
path: item.address,
|
|
2607
|
+
chan: channel,
|
|
2608
|
+
min: (_e = item.min) != null ? _e : 0,
|
|
2609
|
+
max: (_f = item.max) != null ? _f : 1
|
|
2610
|
+
});
|
|
2125
2611
|
}
|
|
2126
2612
|
}
|
|
2127
2613
|
}
|
|
2128
2614
|
if (acc) {
|
|
2129
2615
|
const numAcc = acc.trim().split(" ").map(Number);
|
|
2130
|
-
this.setupAccHandler(
|
|
2616
|
+
this.setupAccHandler(
|
|
2617
|
+
item.address,
|
|
2618
|
+
FaustSensors.convertToAxis(numAcc[0]),
|
|
2619
|
+
FaustSensors.convertToCurve(numAcc[1]),
|
|
2620
|
+
numAcc[2],
|
|
2621
|
+
numAcc[3],
|
|
2622
|
+
numAcc[4],
|
|
2623
|
+
item.min,
|
|
2624
|
+
item.init,
|
|
2625
|
+
item.max
|
|
2626
|
+
);
|
|
2131
2627
|
}
|
|
2132
2628
|
if (gyr) {
|
|
2133
2629
|
const numAcc = gyr.trim().split(" ").map(Number);
|
|
2134
|
-
this.setupGyrHandler(
|
|
2630
|
+
this.setupGyrHandler(
|
|
2631
|
+
item.address,
|
|
2632
|
+
FaustSensors.convertToAxis(numAcc[0]),
|
|
2633
|
+
FaustSensors.convertToCurve(numAcc[1]),
|
|
2634
|
+
numAcc[2],
|
|
2635
|
+
numAcc[3],
|
|
2636
|
+
numAcc[4],
|
|
2637
|
+
item.min,
|
|
2638
|
+
item.init,
|
|
2639
|
+
item.max
|
|
2640
|
+
);
|
|
2135
2641
|
}
|
|
2136
2642
|
});
|
|
2137
2643
|
} else if (item.type === "soundfile") {
|
|
2138
|
-
this.fSoundfiles.push({
|
|
2644
|
+
this.fSoundfiles.push({
|
|
2645
|
+
name: item.label,
|
|
2646
|
+
url: item.url,
|
|
2647
|
+
index: item.index,
|
|
2648
|
+
basePtr: -1
|
|
2649
|
+
});
|
|
2139
2650
|
}
|
|
2140
2651
|
};
|
|
2141
2652
|
// Audio callback
|
|
@@ -2174,8 +2685,10 @@ var FaustBaseWebAudioDsp = class _FaustBaseWebAudioDsp {
|
|
|
2174
2685
|
}
|
|
2175
2686
|
/** Split the soundfile names and return an array of names */
|
|
2176
2687
|
static splitSoundfileNames(input) {
|
|
2177
|
-
|
|
2178
|
-
return trimmed.split(";").map(
|
|
2688
|
+
const trimmed = input.replace(/^\{|\}$/g, "");
|
|
2689
|
+
return trimmed.split(";").map(
|
|
2690
|
+
(str) => str.length <= 2 ? "" : str.substring(1, str.length - 1)
|
|
2691
|
+
);
|
|
2179
2692
|
}
|
|
2180
2693
|
get hasAccInput() {
|
|
2181
2694
|
return this.fAcc.x.length + this.fAcc.y.length + this.fAcc.z.length > 0;
|
|
@@ -2203,36 +2716,66 @@ var FaustBaseWebAudioDsp = class _FaustBaseWebAudioDsp {
|
|
|
2203
2716
|
}
|
|
2204
2717
|
/** Build the accelerometer handler */
|
|
2205
2718
|
setupAccHandler(path, axis, curve, amin, amid, amax, min, init, max) {
|
|
2206
|
-
const handler = FaustSensors.buildHandler(
|
|
2719
|
+
const handler = FaustSensors.buildHandler(
|
|
2720
|
+
curve,
|
|
2721
|
+
amin,
|
|
2722
|
+
amid,
|
|
2723
|
+
amax,
|
|
2724
|
+
min,
|
|
2725
|
+
init,
|
|
2726
|
+
max
|
|
2727
|
+
);
|
|
2207
2728
|
switch (axis) {
|
|
2208
2729
|
case 0 /* x */:
|
|
2209
|
-
this.fAcc.x.push(
|
|
2730
|
+
this.fAcc.x.push(
|
|
2731
|
+
(val) => this.setParamValue(path, handler.uiToFaust(val))
|
|
2732
|
+
);
|
|
2210
2733
|
break;
|
|
2211
2734
|
case 1 /* y */:
|
|
2212
|
-
this.fAcc.y.push(
|
|
2735
|
+
this.fAcc.y.push(
|
|
2736
|
+
(val) => this.setParamValue(path, handler.uiToFaust(val))
|
|
2737
|
+
);
|
|
2213
2738
|
break;
|
|
2214
2739
|
case 2 /* z */:
|
|
2215
|
-
this.fAcc.z.push(
|
|
2740
|
+
this.fAcc.z.push(
|
|
2741
|
+
(val) => this.setParamValue(path, handler.uiToFaust(val))
|
|
2742
|
+
);
|
|
2216
2743
|
break;
|
|
2217
2744
|
}
|
|
2218
2745
|
}
|
|
2219
2746
|
/** Build the gyroscope handler */
|
|
2220
2747
|
setupGyrHandler(path, axis, curve, amin, amid, amax, min, init, max) {
|
|
2221
|
-
const handler = FaustSensors.buildHandler(
|
|
2748
|
+
const handler = FaustSensors.buildHandler(
|
|
2749
|
+
curve,
|
|
2750
|
+
amin,
|
|
2751
|
+
amid,
|
|
2752
|
+
amax,
|
|
2753
|
+
min,
|
|
2754
|
+
init,
|
|
2755
|
+
max
|
|
2756
|
+
);
|
|
2222
2757
|
switch (axis) {
|
|
2223
2758
|
case 0 /* x */:
|
|
2224
|
-
this.fGyr.x.push(
|
|
2759
|
+
this.fGyr.x.push(
|
|
2760
|
+
(val) => this.setParamValue(path, handler.uiToFaust(val))
|
|
2761
|
+
);
|
|
2225
2762
|
break;
|
|
2226
2763
|
case 1 /* y */:
|
|
2227
|
-
this.fGyr.y.push(
|
|
2764
|
+
this.fGyr.y.push(
|
|
2765
|
+
(val) => this.setParamValue(path, handler.uiToFaust(val))
|
|
2766
|
+
);
|
|
2228
2767
|
break;
|
|
2229
2768
|
case 2 /* z */:
|
|
2230
|
-
this.fGyr.z.push(
|
|
2769
|
+
this.fGyr.z.push(
|
|
2770
|
+
(val) => this.setParamValue(path, handler.uiToFaust(val))
|
|
2771
|
+
);
|
|
2231
2772
|
break;
|
|
2232
2773
|
}
|
|
2233
2774
|
}
|
|
2234
2775
|
static extractUrlsFromMeta(dspMeta) {
|
|
2235
|
-
const soundfilesEntry = dspMeta.meta.find(
|
|
2776
|
+
const soundfilesEntry = dspMeta.meta.find(
|
|
2777
|
+
(entry) => entry.soundfiles !== void 0
|
|
2778
|
+
);
|
|
2236
2779
|
if (soundfilesEntry) {
|
|
2237
2780
|
return soundfilesEntry.soundfiles.split(";").filter((url) => url !== "");
|
|
2238
2781
|
} else {
|
|
@@ -2242,9 +2785,9 @@ var FaustBaseWebAudioDsp = class _FaustBaseWebAudioDsp {
|
|
|
2242
2785
|
/**
|
|
2243
2786
|
* Load a soundfile possibly containing several parts in the DSP struct.
|
|
2244
2787
|
* Soundfile pointers are located at 'index' offset, to be read in the JSON file.
|
|
2245
|
-
* The DSP struct is located at baseDSP in the wasm memory,
|
|
2788
|
+
* The DSP struct is located at baseDSP in the wasm memory,
|
|
2246
2789
|
* either a monophonic DSP, or a voice in a polyphonic context.
|
|
2247
|
-
*
|
|
2790
|
+
*
|
|
2248
2791
|
* @param allocator : the wasm memory allocator
|
|
2249
2792
|
* @param baseDSP : the base DSP in the wasm memory
|
|
2250
2793
|
* @param name : the name of the soundfile
|
|
@@ -2257,17 +2800,27 @@ var FaustBaseWebAudioDsp = class _FaustBaseWebAudioDsp {
|
|
|
2257
2800
|
if (!item) throw new Error(`Soundfile with ${url} cannot be found !}`);
|
|
2258
2801
|
if (item.basePtr !== -1) {
|
|
2259
2802
|
const HEAP32 = allocator.getInt32Array();
|
|
2260
|
-
console.log(
|
|
2803
|
+
console.log(
|
|
2804
|
+
`Soundfile CACHE ${url}} : ${name} loaded at ${item.basePtr} in wasm memory with index ${item.index}`
|
|
2805
|
+
);
|
|
2261
2806
|
HEAP32[baseDSP + item.index >> 2] = item.basePtr;
|
|
2262
2807
|
} else {
|
|
2263
|
-
const soundfile = this.createSoundfile(
|
|
2808
|
+
const soundfile = this.createSoundfile(
|
|
2809
|
+
allocator,
|
|
2810
|
+
soundfileIds,
|
|
2811
|
+
this.fSoundfileBuffers
|
|
2812
|
+
);
|
|
2264
2813
|
if (soundfile) {
|
|
2265
2814
|
const HEAP32 = soundfile.getHEAP32();
|
|
2266
2815
|
item.basePtr = soundfile.getPtr();
|
|
2267
|
-
console.log(
|
|
2816
|
+
console.log(
|
|
2817
|
+
`Soundfile ${name} loaded at ${item.basePtr} in wasm memory with index ${item.index}`
|
|
2818
|
+
);
|
|
2268
2819
|
HEAP32[baseDSP + item.index >> 2] = item.basePtr;
|
|
2269
2820
|
} else {
|
|
2270
|
-
console.log(
|
|
2821
|
+
console.log(
|
|
2822
|
+
`Soundfile ${name} for ${url} cannot be created !}`
|
|
2823
|
+
);
|
|
2271
2824
|
}
|
|
2272
2825
|
}
|
|
2273
2826
|
}
|
|
@@ -2289,7 +2842,14 @@ var FaustBaseWebAudioDsp = class _FaustBaseWebAudioDsp {
|
|
|
2289
2842
|
totalLength += len;
|
|
2290
2843
|
}
|
|
2291
2844
|
totalLength += (Soundfile.MAX_SOUNDFILE_PARTS - soundfileIdList.length) * Soundfile.BUFFER_SIZE;
|
|
2292
|
-
const soundfile = new Soundfile(
|
|
2845
|
+
const soundfile = new Soundfile(
|
|
2846
|
+
allocator,
|
|
2847
|
+
this.fSampleSize,
|
|
2848
|
+
curChan,
|
|
2849
|
+
totalLength,
|
|
2850
|
+
maxChan,
|
|
2851
|
+
soundfileIdList.length
|
|
2852
|
+
);
|
|
2293
2853
|
let offset = 0;
|
|
2294
2854
|
for (let part = 0; part < soundfileIdList.length; part++) {
|
|
2295
2855
|
const soundfileId = soundfileIdList[part];
|
|
@@ -2307,31 +2867,34 @@ var FaustBaseWebAudioDsp = class _FaustBaseWebAudioDsp {
|
|
|
2307
2867
|
soundfile.shareBuffers(curChan, maxChan);
|
|
2308
2868
|
return soundfile;
|
|
2309
2869
|
}
|
|
2310
|
-
/**
|
|
2870
|
+
/**
|
|
2311
2871
|
* Init soundfiles memory.
|
|
2312
|
-
*
|
|
2872
|
+
*
|
|
2313
2873
|
* @param allocator : the wasm memory allocator
|
|
2314
2874
|
* @param baseDSP : the DSP struct (either a monophonic DSP of polyphonic voice) base DSP in the wasm memory
|
|
2315
|
-
|
|
2875
|
+
*/
|
|
2316
2876
|
initSoundfileMemory(allocator, baseDSP) {
|
|
2317
2877
|
for (const { name, url } of this.fSoundfiles) {
|
|
2318
2878
|
this.loadSoundfile(allocator, baseDSP, name, url);
|
|
2319
2879
|
}
|
|
2320
|
-
;
|
|
2321
2880
|
}
|
|
2322
2881
|
updateOutputs() {
|
|
2323
2882
|
if (this.fOutputsItems.length > 0 && this.fOutputHandler && this.fOutputsTimer-- === 0) {
|
|
2324
2883
|
this.fOutputsTimer = 5;
|
|
2325
|
-
this.fOutputsItems.forEach(
|
|
2326
|
-
|
|
2327
|
-
|
|
2328
|
-
|
|
2884
|
+
this.fOutputsItems.forEach(
|
|
2885
|
+
(item) => {
|
|
2886
|
+
var _a;
|
|
2887
|
+
return (_a = this.fOutputHandler) == null ? void 0 : _a.call(this, item, this.getParamValue(item));
|
|
2888
|
+
}
|
|
2889
|
+
);
|
|
2329
2890
|
}
|
|
2330
2891
|
}
|
|
2331
2892
|
// Public API
|
|
2332
2893
|
metadata(handler) {
|
|
2333
2894
|
if (this.fJSONDsp.meta) {
|
|
2334
|
-
this.fJSONDsp.meta.forEach(
|
|
2895
|
+
this.fJSONDsp.meta.forEach(
|
|
2896
|
+
(meta) => handler(Object.keys(meta)[0], meta[Object.keys(meta)[0]])
|
|
2897
|
+
);
|
|
2335
2898
|
}
|
|
2336
2899
|
}
|
|
2337
2900
|
compute(input, output) {
|
|
@@ -2377,68 +2940,127 @@ var FaustBaseWebAudioDsp = class _FaustBaseWebAudioDsp {
|
|
|
2377
2940
|
if (cmd === 11) return this.ctrlChange(channel, data1, data2);
|
|
2378
2941
|
if (cmd === 14) return this.pitchWheel(channel, data2 * 128 + data1);
|
|
2379
2942
|
if (cmd === 9) {
|
|
2380
|
-
if (data2 > 0)
|
|
2381
|
-
|
|
2382
|
-
else
|
|
2383
|
-
return this.keyOff(channel, data1, data2);
|
|
2943
|
+
if (data2 > 0) return this.keyOn(channel, data1, data2);
|
|
2944
|
+
else return this.keyOff(channel, data1, data2);
|
|
2384
2945
|
}
|
|
2385
2946
|
if (cmd === 8) {
|
|
2386
2947
|
return this.keyOff(channel, data1, data2);
|
|
2387
2948
|
}
|
|
2388
2949
|
}
|
|
2389
2950
|
ctrlChange(channel, ctrl, value) {
|
|
2390
|
-
if (this.fPlotHandler)
|
|
2951
|
+
if (this.fPlotHandler)
|
|
2952
|
+
this.fCachedEvents.push({
|
|
2953
|
+
type: "ctrlChange",
|
|
2954
|
+
data: [channel, ctrl, value]
|
|
2955
|
+
});
|
|
2391
2956
|
if (this.fCtrlLabel[ctrl].length) {
|
|
2392
2957
|
this.fCtrlLabel[ctrl].forEach((ctrl2) => {
|
|
2393
2958
|
const { path, chan } = ctrl2;
|
|
2394
2959
|
if (chan === 0 || channel === chan - 1) {
|
|
2395
|
-
this.setParamValue(
|
|
2396
|
-
|
|
2960
|
+
this.setParamValue(
|
|
2961
|
+
path,
|
|
2962
|
+
_FaustBaseWebAudioDsp.remap(
|
|
2963
|
+
value,
|
|
2964
|
+
0,
|
|
2965
|
+
127,
|
|
2966
|
+
ctrl2.min,
|
|
2967
|
+
ctrl2.max
|
|
2968
|
+
)
|
|
2969
|
+
);
|
|
2970
|
+
if (this.fOutputHandler)
|
|
2971
|
+
this.fOutputHandler(path, this.getParamValue(path));
|
|
2397
2972
|
}
|
|
2398
2973
|
});
|
|
2399
2974
|
}
|
|
2400
2975
|
}
|
|
2401
2976
|
keyOn(channel, pitch, velocity) {
|
|
2402
|
-
if (this.fPlotHandler)
|
|
2977
|
+
if (this.fPlotHandler)
|
|
2978
|
+
this.fCachedEvents.push({
|
|
2979
|
+
type: "keyOn",
|
|
2980
|
+
data: [channel, pitch, velocity]
|
|
2981
|
+
});
|
|
2403
2982
|
this.fMidiKeyOnLabel[pitch].forEach((key) => {
|
|
2404
2983
|
const { path, chan } = key;
|
|
2405
2984
|
if (chan === 0 || channel === chan - 1) {
|
|
2406
|
-
this.setParamValue(
|
|
2407
|
-
|
|
2985
|
+
this.setParamValue(
|
|
2986
|
+
path,
|
|
2987
|
+
_FaustBaseWebAudioDsp.remap(
|
|
2988
|
+
velocity,
|
|
2989
|
+
0,
|
|
2990
|
+
127,
|
|
2991
|
+
key.min,
|
|
2992
|
+
key.max
|
|
2993
|
+
)
|
|
2994
|
+
);
|
|
2995
|
+
if (this.fOutputHandler)
|
|
2996
|
+
this.fOutputHandler(path, this.getParamValue(path));
|
|
2408
2997
|
}
|
|
2409
2998
|
});
|
|
2410
2999
|
this.fMidiKeyLabel[pitch].forEach((key) => {
|
|
2411
3000
|
const { path, chan } = key;
|
|
2412
3001
|
if (chan === 0 || channel === chan - 1) {
|
|
2413
|
-
this.setParamValue(
|
|
2414
|
-
|
|
3002
|
+
this.setParamValue(
|
|
3003
|
+
path,
|
|
3004
|
+
_FaustBaseWebAudioDsp.remap(
|
|
3005
|
+
velocity,
|
|
3006
|
+
0,
|
|
3007
|
+
127,
|
|
3008
|
+
key.min,
|
|
3009
|
+
key.max
|
|
3010
|
+
)
|
|
3011
|
+
);
|
|
3012
|
+
if (this.fOutputHandler)
|
|
3013
|
+
this.fOutputHandler(path, this.getParamValue(path));
|
|
2415
3014
|
}
|
|
2416
3015
|
});
|
|
2417
3016
|
}
|
|
2418
3017
|
keyOff(channel, pitch, velocity) {
|
|
2419
|
-
if (this.fPlotHandler)
|
|
3018
|
+
if (this.fPlotHandler)
|
|
3019
|
+
this.fCachedEvents.push({
|
|
3020
|
+
type: "keyOff",
|
|
3021
|
+
data: [channel, pitch, velocity]
|
|
3022
|
+
});
|
|
2420
3023
|
this.fMidiKeyOffLabel[pitch].forEach((key) => {
|
|
2421
3024
|
const { path, chan } = key;
|
|
2422
3025
|
if (chan === 0 || channel === chan - 1) {
|
|
2423
|
-
this.setParamValue(
|
|
2424
|
-
|
|
3026
|
+
this.setParamValue(
|
|
3027
|
+
path,
|
|
3028
|
+
_FaustBaseWebAudioDsp.remap(
|
|
3029
|
+
velocity,
|
|
3030
|
+
0,
|
|
3031
|
+
127,
|
|
3032
|
+
key.min,
|
|
3033
|
+
key.max
|
|
3034
|
+
)
|
|
3035
|
+
);
|
|
3036
|
+
if (this.fOutputHandler)
|
|
3037
|
+
this.fOutputHandler(path, this.getParamValue(path));
|
|
2425
3038
|
}
|
|
2426
3039
|
});
|
|
2427
3040
|
this.fMidiKeyLabel[pitch].forEach((key) => {
|
|
2428
3041
|
const { path, chan } = key;
|
|
2429
3042
|
if (chan === 0 || channel === chan - 1) {
|
|
2430
3043
|
this.setParamValue(path, 0);
|
|
2431
|
-
if (this.fOutputHandler)
|
|
3044
|
+
if (this.fOutputHandler)
|
|
3045
|
+
this.fOutputHandler(path, this.getParamValue(path));
|
|
2432
3046
|
}
|
|
2433
3047
|
});
|
|
2434
3048
|
}
|
|
2435
3049
|
pitchWheel(channel, wheel) {
|
|
2436
|
-
if (this.fPlotHandler)
|
|
3050
|
+
if (this.fPlotHandler)
|
|
3051
|
+
this.fCachedEvents.push({
|
|
3052
|
+
type: "pitchWheel",
|
|
3053
|
+
data: [channel, wheel]
|
|
3054
|
+
});
|
|
2437
3055
|
this.fPitchwheelLabel.forEach((pw) => {
|
|
2438
3056
|
const { path, chan } = pw;
|
|
2439
3057
|
if (chan === 0 || channel === chan - 1) {
|
|
2440
|
-
this.setParamValue(
|
|
2441
|
-
|
|
3058
|
+
this.setParamValue(
|
|
3059
|
+
path,
|
|
3060
|
+
_FaustBaseWebAudioDsp.remap(wheel, 0, 16383, pw.min, pw.max)
|
|
3061
|
+
);
|
|
3062
|
+
if (this.fOutputHandler)
|
|
3063
|
+
this.fOutputHandler(path, this.getParamValue(path));
|
|
2442
3064
|
}
|
|
2443
3065
|
});
|
|
2444
3066
|
}
|
|
@@ -2494,7 +3116,10 @@ var FaustMonoWebAudioDsp = class extends FaustBaseWebAudioDsp {
|
|
|
2494
3116
|
this.fEndMemory = this.initMemory();
|
|
2495
3117
|
this.fInstance.api.init(this.fDSP, sampleRate);
|
|
2496
3118
|
if (this.fSoundfiles.length > 0) {
|
|
2497
|
-
const allocator = new WasmAllocator(
|
|
3119
|
+
const allocator = new WasmAllocator(
|
|
3120
|
+
this.fInstance.memory,
|
|
3121
|
+
this.fEndMemory
|
|
3122
|
+
);
|
|
2498
3123
|
this.initSoundfileMemory(allocator, this.fDSP);
|
|
2499
3124
|
}
|
|
2500
3125
|
}
|
|
@@ -2513,18 +3138,30 @@ var FaustMonoWebAudioDsp = class extends FaustBaseWebAudioDsp {
|
|
|
2513
3138
|
for (let chan = 0; chan < this.getNumInputs(); chan++) {
|
|
2514
3139
|
HEAP32[(this.fAudioInputs >> 2) + chan] = $audioInputs + this.fBufferSize * this.fSampleSize * chan;
|
|
2515
3140
|
}
|
|
2516
|
-
const dspInChans = HEAP32.subarray(
|
|
3141
|
+
const dspInChans = HEAP32.subarray(
|
|
3142
|
+
this.fAudioInputs >> 2,
|
|
3143
|
+
this.fAudioInputs + this.getNumInputs() * this.fPtrSize >> 2
|
|
3144
|
+
);
|
|
2517
3145
|
for (let chan = 0; chan < this.getNumInputs(); chan++) {
|
|
2518
|
-
this.fInChannels[chan] = HEAPF.subarray(
|
|
3146
|
+
this.fInChannels[chan] = HEAPF.subarray(
|
|
3147
|
+
dspInChans[chan] >> Math.log2(this.fSampleSize),
|
|
3148
|
+
dspInChans[chan] + this.fBufferSize * this.fSampleSize >> Math.log2(this.fSampleSize)
|
|
3149
|
+
);
|
|
2519
3150
|
}
|
|
2520
3151
|
}
|
|
2521
3152
|
if (this.getNumOutputs() > 0) {
|
|
2522
3153
|
for (let chan = 0; chan < this.getNumOutputs(); chan++) {
|
|
2523
3154
|
HEAP32[(this.fAudioOutputs >> 2) + chan] = $audioOutputs + this.fBufferSize * this.fSampleSize * chan;
|
|
2524
3155
|
}
|
|
2525
|
-
const dspOutChans = HEAP32.subarray(
|
|
3156
|
+
const dspOutChans = HEAP32.subarray(
|
|
3157
|
+
this.fAudioOutputs >> 2,
|
|
3158
|
+
this.fAudioOutputs + this.getNumOutputs() * this.fPtrSize >> 2
|
|
3159
|
+
);
|
|
2526
3160
|
for (let chan = 0; chan < this.getNumOutputs(); chan++) {
|
|
2527
|
-
this.fOutChannels[chan] = HEAPF.subarray(
|
|
3161
|
+
this.fOutChannels[chan] = HEAPF.subarray(
|
|
3162
|
+
dspOutChans[chan] >> Math.log2(this.fSampleSize),
|
|
3163
|
+
dspOutChans[chan] + this.fBufferSize * this.fSampleSize >> Math.log2(this.fSampleSize)
|
|
3164
|
+
);
|
|
2528
3165
|
}
|
|
2529
3166
|
}
|
|
2530
3167
|
return endMemory;
|
|
@@ -2562,7 +3199,12 @@ var FaustMonoWebAudioDsp = class extends FaustBaseWebAudioDsp {
|
|
|
2562
3199
|
}
|
|
2563
3200
|
}
|
|
2564
3201
|
if (this.fComputeHandler) this.fComputeHandler(this.fBufferSize);
|
|
2565
|
-
this.fInstance.api.compute(
|
|
3202
|
+
this.fInstance.api.compute(
|
|
3203
|
+
this.fDSP,
|
|
3204
|
+
this.fBufferSize,
|
|
3205
|
+
this.fAudioInputs,
|
|
3206
|
+
this.fAudioOutputs
|
|
3207
|
+
);
|
|
2566
3208
|
this.updateOutputs();
|
|
2567
3209
|
let forPlot = this.fOutChannels;
|
|
2568
3210
|
if (typeof output === "function") {
|
|
@@ -2575,7 +3217,11 @@ var FaustMonoWebAudioDsp = class extends FaustBaseWebAudioDsp {
|
|
|
2575
3217
|
forPlot = output;
|
|
2576
3218
|
}
|
|
2577
3219
|
if (this.fPlotHandler) {
|
|
2578
|
-
this.fPlotHandler(
|
|
3220
|
+
this.fPlotHandler(
|
|
3221
|
+
forPlot,
|
|
3222
|
+
this.fBufferNum++,
|
|
3223
|
+
this.fCachedEvents.length ? this.fCachedEvents : void 0
|
|
3224
|
+
);
|
|
2579
3225
|
this.fCachedEvents = [];
|
|
2580
3226
|
}
|
|
2581
3227
|
return true;
|
|
@@ -2590,11 +3236,19 @@ var FaustMonoWebAudioDsp = class extends FaustBaseWebAudioDsp {
|
|
|
2590
3236
|
return this.fInstance.api.getNumOutputs(this.fDSP);
|
|
2591
3237
|
}
|
|
2592
3238
|
setParamValue(path, value) {
|
|
2593
|
-
if (this.fPlotHandler)
|
|
2594
|
-
|
|
3239
|
+
if (this.fPlotHandler)
|
|
3240
|
+
this.fCachedEvents.push({ type: "param", data: { path, value } });
|
|
3241
|
+
this.fInstance.api.setParamValue(
|
|
3242
|
+
this.fDSP,
|
|
3243
|
+
this.fPathTable[path],
|
|
3244
|
+
value
|
|
3245
|
+
);
|
|
2595
3246
|
}
|
|
2596
3247
|
getParamValue(path) {
|
|
2597
|
-
return this.fInstance.api.getParamValue(
|
|
3248
|
+
return this.fInstance.api.getParamValue(
|
|
3249
|
+
this.fDSP,
|
|
3250
|
+
this.fPathTable[path]
|
|
3251
|
+
);
|
|
2598
3252
|
}
|
|
2599
3253
|
getMeta() {
|
|
2600
3254
|
return this.fJSONDsp;
|
|
@@ -2675,16 +3329,36 @@ var FaustWebAudioDspVoice = class _FaustWebAudioDspVoice {
|
|
|
2675
3329
|
this.fNextNote = pitch;
|
|
2676
3330
|
this.fNextVel = velocity;
|
|
2677
3331
|
} else {
|
|
2678
|
-
this.fFreqLabel.forEach(
|
|
2679
|
-
|
|
2680
|
-
|
|
2681
|
-
|
|
2682
|
-
|
|
3332
|
+
this.fFreqLabel.forEach(
|
|
3333
|
+
(index) => this.fAPI.setParamValue(
|
|
3334
|
+
this.fDSP,
|
|
3335
|
+
index,
|
|
3336
|
+
_FaustWebAudioDspVoice.midiToFreq(pitch)
|
|
3337
|
+
)
|
|
3338
|
+
);
|
|
3339
|
+
this.fGateLabel.forEach(
|
|
3340
|
+
(index) => this.fAPI.setParamValue(this.fDSP, index, 1)
|
|
3341
|
+
);
|
|
3342
|
+
this.fGainLabel.forEach(
|
|
3343
|
+
(index) => this.fAPI.setParamValue(
|
|
3344
|
+
this.fDSP,
|
|
3345
|
+
index,
|
|
3346
|
+
_FaustWebAudioDspVoice.normalizeVelocity(velocity)
|
|
3347
|
+
)
|
|
3348
|
+
);
|
|
3349
|
+
this.fKeyLabel.forEach(
|
|
3350
|
+
(index) => this.fAPI.setParamValue(this.fDSP, index, pitch)
|
|
3351
|
+
);
|
|
3352
|
+
this.fVelLabel.forEach(
|
|
3353
|
+
(index) => this.fAPI.setParamValue(this.fDSP, index, velocity)
|
|
3354
|
+
);
|
|
2683
3355
|
this.fCurNote = pitch;
|
|
2684
3356
|
}
|
|
2685
3357
|
}
|
|
2686
3358
|
keyOff(hard = false) {
|
|
2687
|
-
this.fGateLabel.forEach(
|
|
3359
|
+
this.fGateLabel.forEach(
|
|
3360
|
+
(index) => this.fAPI.setParamValue(this.fDSP, index, 0)
|
|
3361
|
+
);
|
|
2688
3362
|
if (hard) {
|
|
2689
3363
|
this.fCurNote = _FaustWebAudioDspVoice.kFreeVoice;
|
|
2690
3364
|
} else {
|
|
@@ -2692,8 +3366,10 @@ var FaustWebAudioDspVoice = class _FaustWebAudioDspVoice {
|
|
|
2692
3366
|
}
|
|
2693
3367
|
}
|
|
2694
3368
|
computeLegato(bufferSize, $inputs, $outputZero, $outputsHalf) {
|
|
2695
|
-
|
|
2696
|
-
this.fGateLabel.forEach(
|
|
3369
|
+
const size = bufferSize / 2;
|
|
3370
|
+
this.fGateLabel.forEach(
|
|
3371
|
+
(index) => this.fAPI.setParamValue(this.fDSP, index, 0)
|
|
3372
|
+
);
|
|
2697
3373
|
this.fAPI.compute(this.fDSP, size, $inputs, $outputZero);
|
|
2698
3374
|
this.keyOn(this.fNextNote, this.fNextVel);
|
|
2699
3375
|
this.fAPI.compute(this.fDSP, size, $inputs, $outputsHalf);
|
|
@@ -2716,21 +3392,28 @@ var FaustPolyWebAudioDsp = class _FaustPolyWebAudioDsp extends FaustBaseWebAudio
|
|
|
2716
3392
|
this.fJSONDsp = JSON.parse(this.fInstance.voiceJSON);
|
|
2717
3393
|
this.fJSONEffect = this.fInstance.effectAPI && this.fInstance.effectJSON ? JSON.parse(this.fInstance.effectJSON) : null;
|
|
2718
3394
|
FaustBaseWebAudioDsp.parseUI(this.fJSONDsp.ui, this.fUICallback);
|
|
2719
|
-
if (this.fJSONEffect)
|
|
3395
|
+
if (this.fJSONEffect)
|
|
3396
|
+
FaustBaseWebAudioDsp.parseUI(this.fJSONEffect.ui, this.fUICallback);
|
|
2720
3397
|
this.fEndMemory = this.initMemory();
|
|
2721
3398
|
this.fVoiceTable = [];
|
|
2722
3399
|
for (let voice = 0; voice < this.fInstance.voices; voice++) {
|
|
2723
|
-
this.fVoiceTable.push(
|
|
2724
|
-
|
|
2725
|
-
|
|
2726
|
-
|
|
2727
|
-
|
|
2728
|
-
|
|
2729
|
-
|
|
2730
|
-
|
|
2731
|
-
|
|
3400
|
+
this.fVoiceTable.push(
|
|
3401
|
+
new FaustWebAudioDspVoice(
|
|
3402
|
+
this.fJSONDsp.size * voice,
|
|
3403
|
+
this.fInstance.voiceAPI,
|
|
3404
|
+
this.fInputsItems,
|
|
3405
|
+
this.fPathTable,
|
|
3406
|
+
sampleRate
|
|
3407
|
+
)
|
|
3408
|
+
);
|
|
3409
|
+
}
|
|
3410
|
+
if (this.fInstance.effectAPI)
|
|
3411
|
+
this.fInstance.effectAPI.init(this.fEffect, sampleRate);
|
|
2732
3412
|
if (this.fSoundfiles.length > 0) {
|
|
2733
|
-
const allocator = new WasmAllocator(
|
|
3413
|
+
const allocator = new WasmAllocator(
|
|
3414
|
+
this.fInstance.memory,
|
|
3415
|
+
this.fEndMemory
|
|
3416
|
+
);
|
|
2734
3417
|
for (let voice = 0; voice < this.fInstance.voices; voice++) {
|
|
2735
3418
|
this.initSoundfileMemory(allocator, this.fJSONDsp.size * voice);
|
|
2736
3419
|
}
|
|
@@ -2754,9 +3437,15 @@ var FaustPolyWebAudioDsp = class _FaustPolyWebAudioDsp extends FaustBaseWebAudio
|
|
|
2754
3437
|
for (let chan = 0; chan < this.getNumInputs(); chan++) {
|
|
2755
3438
|
HEAP32[(this.fAudioInputs >> 2) + chan] = $audioInputs + this.fBufferSize * this.fSampleSize * chan;
|
|
2756
3439
|
}
|
|
2757
|
-
const dspInChans = HEAP32.subarray(
|
|
3440
|
+
const dspInChans = HEAP32.subarray(
|
|
3441
|
+
this.fAudioInputs >> 2,
|
|
3442
|
+
this.fAudioInputs + this.getNumInputs() * this.fPtrSize >> 2
|
|
3443
|
+
);
|
|
2758
3444
|
for (let chan = 0; chan < this.getNumInputs(); chan++) {
|
|
2759
|
-
this.fInChannels[chan] = HEAPF.subarray(
|
|
3445
|
+
this.fInChannels[chan] = HEAPF.subarray(
|
|
3446
|
+
dspInChans[chan] >> Math.log2(this.fSampleSize),
|
|
3447
|
+
dspInChans[chan] + this.fBufferSize * this.fSampleSize >> Math.log2(this.fSampleSize)
|
|
3448
|
+
);
|
|
2760
3449
|
}
|
|
2761
3450
|
}
|
|
2762
3451
|
if (this.getNumOutputs() > 0) {
|
|
@@ -2765,9 +3454,15 @@ var FaustPolyWebAudioDsp = class _FaustPolyWebAudioDsp extends FaustBaseWebAudio
|
|
|
2765
3454
|
HEAP32[(this.fAudioMixing >> 2) + chan] = $audioMixing + this.fBufferSize * this.fSampleSize * chan;
|
|
2766
3455
|
HEAP32[(this.fAudioMixingHalf >> 2) + chan] = $audioMixing + this.fBufferSize * this.fSampleSize * chan + this.fBufferSize / 2 * this.fSampleSize;
|
|
2767
3456
|
}
|
|
2768
|
-
const dspOutChans = HEAP32.subarray(
|
|
3457
|
+
const dspOutChans = HEAP32.subarray(
|
|
3458
|
+
this.fAudioOutputs >> 2,
|
|
3459
|
+
this.fAudioOutputs + this.getNumOutputs() * this.fPtrSize >> 2
|
|
3460
|
+
);
|
|
2769
3461
|
for (let chan = 0; chan < this.getNumOutputs(); chan++) {
|
|
2770
|
-
this.fOutChannels[chan] = HEAPF.subarray(
|
|
3462
|
+
this.fOutChannels[chan] = HEAPF.subarray(
|
|
3463
|
+
dspOutChans[chan] >> Math.log2(this.fSampleSize),
|
|
3464
|
+
dspOutChans[chan] + this.fBufferSize * this.fSampleSize >> Math.log2(this.fSampleSize)
|
|
3465
|
+
);
|
|
2771
3466
|
}
|
|
2772
3467
|
}
|
|
2773
3468
|
return endMemory;
|
|
@@ -2790,8 +3485,8 @@ var FaustPolyWebAudioDsp = class _FaustPolyWebAudioDsp extends FaustBaseWebAudio
|
|
|
2790
3485
|
let voicePlaying = FaustWebAudioDspVoice.kNoVoice;
|
|
2791
3486
|
let oldestDatePlaying = Number.MAX_VALUE;
|
|
2792
3487
|
for (let i = 0; i < this.fInstance.voices; i++) {
|
|
2793
|
-
|
|
2794
|
-
|
|
3488
|
+
const curNote = this.fVoiceTable[i].fCurNote;
|
|
3489
|
+
const nextNote = this.fVoiceTable[i].fNextNote;
|
|
2795
3490
|
if (curNote === pitch || curNote === FaustWebAudioDspVoice.kLegatoVoice && nextNote === pitch) {
|
|
2796
3491
|
if (this.fVoiceTable[i].fDate < oldestDatePlaying) {
|
|
2797
3492
|
oldestDatePlaying = this.fVoiceTable[i].fDate;
|
|
@@ -2804,7 +3499,10 @@ var FaustPolyWebAudioDsp = class _FaustPolyWebAudioDsp extends FaustBaseWebAudio
|
|
|
2804
3499
|
getFreeVoice() {
|
|
2805
3500
|
for (let voice = 0; voice < this.fInstance.voices; voice++) {
|
|
2806
3501
|
if (this.fVoiceTable[voice].fCurNote === FaustWebAudioDspVoice.kFreeVoice) {
|
|
2807
|
-
return this.allocVoice(
|
|
3502
|
+
return this.allocVoice(
|
|
3503
|
+
voice,
|
|
3504
|
+
FaustWebAudioDspVoice.kActiveVoice
|
|
3505
|
+
);
|
|
2808
3506
|
}
|
|
2809
3507
|
}
|
|
2810
3508
|
let voiceRelease = FaustWebAudioDspVoice.kNoVoice;
|
|
@@ -2823,12 +3521,22 @@ var FaustPolyWebAudioDsp = class _FaustPolyWebAudioDsp extends FaustBaseWebAudio
|
|
|
2823
3521
|
}
|
|
2824
3522
|
}
|
|
2825
3523
|
if (oldestDateRelease !== Number.MAX_VALUE) {
|
|
2826
|
-
console.log(
|
|
2827
|
-
|
|
3524
|
+
console.log(
|
|
3525
|
+
`Steal release voice : voice_date = ${this.fVoiceTable[voiceRelease].fDate} voice = ${voiceRelease}`
|
|
3526
|
+
);
|
|
3527
|
+
return this.allocVoice(
|
|
3528
|
+
voiceRelease,
|
|
3529
|
+
FaustWebAudioDspVoice.kLegatoVoice
|
|
3530
|
+
);
|
|
2828
3531
|
}
|
|
2829
3532
|
if (oldestDatePlaying !== Number.MAX_VALUE) {
|
|
2830
|
-
console.log(
|
|
2831
|
-
|
|
3533
|
+
console.log(
|
|
3534
|
+
`Steal playing voice : voice_date = ${this.fVoiceTable[voicePlaying].fDate} voice = ${voicePlaying}`
|
|
3535
|
+
);
|
|
3536
|
+
return this.allocVoice(
|
|
3537
|
+
voicePlaying,
|
|
3538
|
+
FaustWebAudioDspVoice.kLegatoVoice
|
|
3539
|
+
);
|
|
2832
3540
|
}
|
|
2833
3541
|
return FaustWebAudioDspVoice.kNoVoice;
|
|
2834
3542
|
}
|
|
@@ -2853,21 +3561,54 @@ var FaustPolyWebAudioDsp = class _FaustPolyWebAudioDsp extends FaustBaseWebAudio
|
|
|
2853
3561
|
}
|
|
2854
3562
|
}
|
|
2855
3563
|
if (this.fComputeHandler) this.fComputeHandler(this.fBufferSize);
|
|
2856
|
-
this.fInstance.mixerAPI.clearOutput(
|
|
3564
|
+
this.fInstance.mixerAPI.clearOutput(
|
|
3565
|
+
this.fBufferSize,
|
|
3566
|
+
this.getNumOutputs(),
|
|
3567
|
+
this.fAudioOutputs
|
|
3568
|
+
);
|
|
2857
3569
|
this.fVoiceTable.forEach((voice) => {
|
|
2858
3570
|
if (voice.fCurNote === FaustWebAudioDspVoice.kLegatoVoice) {
|
|
2859
|
-
voice.computeLegato(
|
|
2860
|
-
|
|
2861
|
-
|
|
3571
|
+
voice.computeLegato(
|
|
3572
|
+
this.fBufferSize,
|
|
3573
|
+
this.fAudioInputs,
|
|
3574
|
+
this.fAudioMixing,
|
|
3575
|
+
this.fAudioMixingHalf
|
|
3576
|
+
);
|
|
3577
|
+
this.fInstance.mixerAPI.fadeOut(
|
|
3578
|
+
this.fBufferSize / 2,
|
|
3579
|
+
this.getNumOutputs(),
|
|
3580
|
+
this.fAudioMixing
|
|
3581
|
+
);
|
|
3582
|
+
voice.fLevel = this.fInstance.mixerAPI.mixCheckVoice(
|
|
3583
|
+
this.fBufferSize,
|
|
3584
|
+
this.getNumOutputs(),
|
|
3585
|
+
this.fAudioMixing,
|
|
3586
|
+
this.fAudioOutputs
|
|
3587
|
+
);
|
|
2862
3588
|
} else if (voice.fCurNote !== FaustWebAudioDspVoice.kFreeVoice) {
|
|
2863
|
-
voice.compute(
|
|
2864
|
-
|
|
3589
|
+
voice.compute(
|
|
3590
|
+
this.fBufferSize,
|
|
3591
|
+
this.fAudioInputs,
|
|
3592
|
+
this.fAudioMixing
|
|
3593
|
+
);
|
|
3594
|
+
voice.fLevel = this.fInstance.mixerAPI.mixCheckVoice(
|
|
3595
|
+
this.fBufferSize,
|
|
3596
|
+
this.getNumOutputs(),
|
|
3597
|
+
this.fAudioMixing,
|
|
3598
|
+
this.fAudioOutputs
|
|
3599
|
+
);
|
|
2865
3600
|
if (voice.fCurNote == FaustWebAudioDspVoice.kReleaseVoice && voice.fLevel < FaustWebAudioDspVoice.VOICE_STOP_LEVEL) {
|
|
2866
3601
|
voice.fCurNote = FaustWebAudioDspVoice.kFreeVoice;
|
|
2867
3602
|
}
|
|
2868
3603
|
}
|
|
2869
3604
|
});
|
|
2870
|
-
if (this.fInstance.effectAPI)
|
|
3605
|
+
if (this.fInstance.effectAPI)
|
|
3606
|
+
this.fInstance.effectAPI.compute(
|
|
3607
|
+
this.fEffect,
|
|
3608
|
+
this.fBufferSize,
|
|
3609
|
+
this.fAudioOutputs,
|
|
3610
|
+
this.fAudioOutputs
|
|
3611
|
+
);
|
|
2871
3612
|
this.updateOutputs();
|
|
2872
3613
|
if (output !== void 0) {
|
|
2873
3614
|
for (let chan = 0; chan < Math.min(this.getNumOutputs(), output.length); chan++) {
|
|
@@ -2875,7 +3616,11 @@ var FaustPolyWebAudioDsp = class _FaustPolyWebAudioDsp extends FaustBaseWebAudio
|
|
|
2875
3616
|
output[chan].set(dspOutput);
|
|
2876
3617
|
}
|
|
2877
3618
|
if (this.fPlotHandler) {
|
|
2878
|
-
this.fPlotHandler(
|
|
3619
|
+
this.fPlotHandler(
|
|
3620
|
+
output,
|
|
3621
|
+
this.fBufferNum++,
|
|
3622
|
+
this.fCachedEvents.length ? this.fCachedEvents : void 0
|
|
3623
|
+
);
|
|
2879
3624
|
this.fCachedEvents = [];
|
|
2880
3625
|
}
|
|
2881
3626
|
}
|
|
@@ -2900,16 +3645,26 @@ var FaustPolyWebAudioDsp = class _FaustPolyWebAudioDsp extends FaustBaseWebAudio
|
|
|
2900
3645
|
}
|
|
2901
3646
|
}
|
|
2902
3647
|
setParamValue(path, value) {
|
|
2903
|
-
if (this.fPlotHandler)
|
|
3648
|
+
if (this.fPlotHandler)
|
|
3649
|
+
this.fCachedEvents.push({ type: "param", data: { path, value } });
|
|
2904
3650
|
if (this.fJSONEffect && _FaustPolyWebAudioDsp.findPath(this.fJSONEffect.ui, path) && this.fInstance.effectAPI) {
|
|
2905
|
-
this.fInstance.effectAPI.setParamValue(
|
|
3651
|
+
this.fInstance.effectAPI.setParamValue(
|
|
3652
|
+
this.fEffect,
|
|
3653
|
+
this.fPathTable[path],
|
|
3654
|
+
value
|
|
3655
|
+
);
|
|
2906
3656
|
} else {
|
|
2907
|
-
this.fVoiceTable.forEach(
|
|
3657
|
+
this.fVoiceTable.forEach(
|
|
3658
|
+
(voice) => voice.setParamValue(this.fPathTable[path], value)
|
|
3659
|
+
);
|
|
2908
3660
|
}
|
|
2909
3661
|
}
|
|
2910
3662
|
getParamValue(path) {
|
|
2911
3663
|
if (this.fJSONEffect && _FaustPolyWebAudioDsp.findPath(this.fJSONEffect.ui, path) && this.fInstance.effectAPI) {
|
|
2912
|
-
return this.fInstance.effectAPI.getParamValue(
|
|
3664
|
+
return this.fInstance.effectAPI.getParamValue(
|
|
3665
|
+
this.fEffect,
|
|
3666
|
+
this.fPathTable[path]
|
|
3667
|
+
);
|
|
2913
3668
|
} else {
|
|
2914
3669
|
return this.fVoiceTable[0].getParamValue(this.fPathTable[path]);
|
|
2915
3670
|
}
|
|
@@ -2919,22 +3674,24 @@ var FaustPolyWebAudioDsp = class _FaustPolyWebAudioDsp extends FaustBaseWebAudio
|
|
|
2919
3674
|
const e = this.fJSONEffect;
|
|
2920
3675
|
const r = { ...o };
|
|
2921
3676
|
if (e) {
|
|
2922
|
-
r.ui = [
|
|
2923
|
-
|
|
2924
|
-
|
|
2925
|
-
|
|
2926
|
-
|
|
2927
|
-
|
|
2928
|
-
|
|
2929
|
-
|
|
3677
|
+
r.ui = [
|
|
3678
|
+
{
|
|
3679
|
+
type: "tgroup",
|
|
3680
|
+
label: "Sequencer",
|
|
3681
|
+
items: [
|
|
3682
|
+
{ type: "vgroup", label: "Instrument", items: o.ui },
|
|
3683
|
+
{ type: "vgroup", label: "Effect", items: e.ui }
|
|
3684
|
+
]
|
|
3685
|
+
}
|
|
3686
|
+
];
|
|
2930
3687
|
} else {
|
|
2931
|
-
r.ui = [
|
|
2932
|
-
|
|
2933
|
-
|
|
2934
|
-
|
|
2935
|
-
{ type: "vgroup", label: "Voices", items: o.ui }
|
|
2936
|
-
|
|
2937
|
-
|
|
3688
|
+
r.ui = [
|
|
3689
|
+
{
|
|
3690
|
+
type: "tgroup",
|
|
3691
|
+
label: "Polyphonic",
|
|
3692
|
+
items: [{ type: "vgroup", label: "Voices", items: o.ui }]
|
|
3693
|
+
}
|
|
3694
|
+
];
|
|
2938
3695
|
}
|
|
2939
3696
|
return r;
|
|
2940
3697
|
}
|
|
@@ -2952,7 +3709,8 @@ var FaustPolyWebAudioDsp = class _FaustPolyWebAudioDsp extends FaustBaseWebAudio
|
|
|
2952
3709
|
const channel = data[0] & 15;
|
|
2953
3710
|
const data1 = data[1];
|
|
2954
3711
|
const data2 = data[2];
|
|
2955
|
-
if (cmd === 8 || cmd === 9 && data2 === 0)
|
|
3712
|
+
if (cmd === 8 || cmd === 9 && data2 === 0)
|
|
3713
|
+
return this.keyOff(channel, data1, data2);
|
|
2956
3714
|
else if (cmd === 9) return this.keyOn(channel, data1, data2);
|
|
2957
3715
|
else super.midiMessage(data);
|
|
2958
3716
|
}
|
|
@@ -2964,12 +3722,24 @@ var FaustPolyWebAudioDsp = class _FaustPolyWebAudioDsp extends FaustBaseWebAudio
|
|
|
2964
3722
|
}
|
|
2965
3723
|
}
|
|
2966
3724
|
keyOn(channel, pitch, velocity) {
|
|
2967
|
-
if (this.fPlotHandler)
|
|
3725
|
+
if (this.fPlotHandler)
|
|
3726
|
+
this.fCachedEvents.push({
|
|
3727
|
+
type: "keyOn",
|
|
3728
|
+
data: [channel, pitch, velocity]
|
|
3729
|
+
});
|
|
2968
3730
|
const voice = this.getFreeVoice();
|
|
2969
|
-
this.fVoiceTable[voice].keyOn(
|
|
3731
|
+
this.fVoiceTable[voice].keyOn(
|
|
3732
|
+
pitch,
|
|
3733
|
+
velocity,
|
|
3734
|
+
this.fVoiceTable[voice].fCurNote == FaustWebAudioDspVoice.kLegatoVoice
|
|
3735
|
+
);
|
|
2970
3736
|
}
|
|
2971
3737
|
keyOff(channel, pitch, velocity) {
|
|
2972
|
-
if (this.fPlotHandler)
|
|
3738
|
+
if (this.fPlotHandler)
|
|
3739
|
+
this.fCachedEvents.push({
|
|
3740
|
+
type: "keyOff",
|
|
3741
|
+
data: [channel, pitch, velocity]
|
|
3742
|
+
});
|
|
2973
3743
|
const voice = this.getPlayingVoice(pitch);
|
|
2974
3744
|
if (voice !== FaustWebAudioDspVoice.kNoVoice) {
|
|
2975
3745
|
this.fVoiceTable[voice].keyOff();
|
|
@@ -2996,13 +3766,30 @@ var FaustOfflineProcessor = class {
|
|
|
2996
3766
|
const params = [];
|
|
2997
3767
|
const callback = (item) => {
|
|
2998
3768
|
let param = null;
|
|
2999
|
-
const polyKeywords = [
|
|
3769
|
+
const polyKeywords = [
|
|
3770
|
+
"/gate",
|
|
3771
|
+
"/freq",
|
|
3772
|
+
"/gain",
|
|
3773
|
+
"/key",
|
|
3774
|
+
"/vel",
|
|
3775
|
+
"/velocity"
|
|
3776
|
+
];
|
|
3000
3777
|
const isPolyReserved = "address" in item && !!polyKeywords.find((k) => item.address.endsWith(k));
|
|
3001
3778
|
if (this.fDSPCode instanceof FaustMonoWebAudioDsp || !isPolyReserved) {
|
|
3002
3779
|
if (item.type === "vslider" || item.type === "hslider" || item.type === "nentry") {
|
|
3003
|
-
param = {
|
|
3780
|
+
param = {
|
|
3781
|
+
name: item.address,
|
|
3782
|
+
defaultValue: item.init || 0,
|
|
3783
|
+
minValue: item.min || 0,
|
|
3784
|
+
maxValue: item.max || 0
|
|
3785
|
+
};
|
|
3004
3786
|
} else if (item.type === "button" || item.type === "checkbox") {
|
|
3005
|
-
param = {
|
|
3787
|
+
param = {
|
|
3788
|
+
name: item.address,
|
|
3789
|
+
defaultValue: item.init || 0,
|
|
3790
|
+
minValue: 0,
|
|
3791
|
+
maxValue: 1
|
|
3792
|
+
};
|
|
3006
3793
|
}
|
|
3007
3794
|
}
|
|
3008
3795
|
if (param) params.push(param);
|
|
@@ -3175,11 +3962,19 @@ var FaustSvgDiagrams = class {
|
|
|
3175
3962
|
files2.filter((file) => file !== "." && file !== "..").forEach((file) => fs.unlink(`/${name}-svg/${file}`));
|
|
3176
3963
|
} catch {
|
|
3177
3964
|
}
|
|
3178
|
-
const success = this.compiler.generateAuxFiles(
|
|
3965
|
+
const success = this.compiler.generateAuxFiles(
|
|
3966
|
+
name,
|
|
3967
|
+
code,
|
|
3968
|
+
`-lang wasm -o binary -svg ${args}`
|
|
3969
|
+
);
|
|
3179
3970
|
if (!success) throw new Error(this.compiler.getErrorMessage());
|
|
3180
3971
|
const svgs = {};
|
|
3181
3972
|
const files = fs.readdir(`/${name}-svg/`);
|
|
3182
|
-
files.filter((file) => file !== "." && file !== "..").forEach(
|
|
3973
|
+
files.filter((file) => file !== "." && file !== "..").forEach(
|
|
3974
|
+
(file) => svgs[file] = fs.readFile(`/${name}-svg/${file}`, {
|
|
3975
|
+
encoding: "utf8"
|
|
3976
|
+
})
|
|
3977
|
+
);
|
|
3183
3978
|
return svgs;
|
|
3184
3979
|
}
|
|
3185
3980
|
};
|
|
@@ -3192,7 +3987,11 @@ var FaustCmajor = class {
|
|
|
3192
3987
|
}
|
|
3193
3988
|
compile(name, code, args) {
|
|
3194
3989
|
const fs = this.fCompiler.fs();
|
|
3195
|
-
const success = this.fCompiler.generateAuxFiles(
|
|
3990
|
+
const success = this.fCompiler.generateAuxFiles(
|
|
3991
|
+
name,
|
|
3992
|
+
code,
|
|
3993
|
+
`-lang cmajor-hybrid -cn ${name} -o ${name}.cmajor`
|
|
3994
|
+
);
|
|
3196
3995
|
return success ? fs.readFile(`${name}.cmajor`, { encoding: "utf8" }) : "";
|
|
3197
3996
|
}
|
|
3198
3997
|
};
|
|
@@ -3215,7 +4014,12 @@ var LibFaust = class {
|
|
|
3215
4014
|
return this.fCompiler.version();
|
|
3216
4015
|
}
|
|
3217
4016
|
createDSPFactory(name, code, args, useInternalMemory) {
|
|
3218
|
-
return this.fCompiler.createDSPFactory(
|
|
4017
|
+
return this.fCompiler.createDSPFactory(
|
|
4018
|
+
name,
|
|
4019
|
+
code,
|
|
4020
|
+
args,
|
|
4021
|
+
useInternalMemory
|
|
4022
|
+
);
|
|
3219
4023
|
}
|
|
3220
4024
|
deleteDSPFactory(cFactory) {
|
|
3221
4025
|
return this.fCompiler.deleteDSPFactory(cFactory);
|
|
@@ -3272,7 +4076,14 @@ var WavEncoder = class {
|
|
|
3272
4076
|
return ab;
|
|
3273
4077
|
}
|
|
3274
4078
|
static writeHeader(writer, format) {
|
|
3275
|
-
const {
|
|
4079
|
+
const {
|
|
4080
|
+
formatId,
|
|
4081
|
+
sampleRate,
|
|
4082
|
+
bitDepth,
|
|
4083
|
+
numberOfChannels,
|
|
4084
|
+
length,
|
|
4085
|
+
byteDepth
|
|
4086
|
+
} = format;
|
|
3276
4087
|
writer.string("RIFF");
|
|
3277
4088
|
writer.uint32(writer.dataView.byteLength - 8);
|
|
3278
4089
|
writer.string("WAVE");
|
|
@@ -3311,7 +4122,9 @@ var WavEncoder = class {
|
|
|
3311
4122
|
if (!writer[methodName]) {
|
|
3312
4123
|
throw new TypeError("Not supported bit depth: " + bitDepth);
|
|
3313
4124
|
}
|
|
3314
|
-
const write = writer[methodName].bind(
|
|
4125
|
+
const write = writer[methodName].bind(
|
|
4126
|
+
writer
|
|
4127
|
+
);
|
|
3315
4128
|
for (let i = 0; i < length; i++) {
|
|
3316
4129
|
for (let j = 0; j < numberOfChannels; j++) {
|
|
3317
4130
|
write(audioBuffer[j][i]);
|
|
@@ -3446,7 +4259,12 @@ var WavDecoder = class {
|
|
|
3446
4259
|
if (chunkType === "fmt ") {
|
|
3447
4260
|
format = this.decodeFormat(reader, chunkSize);
|
|
3448
4261
|
} else if (chunkType === "data") {
|
|
3449
|
-
audioData = this.decodeData(
|
|
4262
|
+
audioData = this.decodeData(
|
|
4263
|
+
reader,
|
|
4264
|
+
chunkSize,
|
|
4265
|
+
format,
|
|
4266
|
+
options || {}
|
|
4267
|
+
);
|
|
3450
4268
|
} else {
|
|
3451
4269
|
reader.skip(chunkSize);
|
|
3452
4270
|
}
|
|
@@ -3459,8 +4277,10 @@ var WavDecoder = class {
|
|
|
3459
4277
|
3: "lpcm"
|
|
3460
4278
|
};
|
|
3461
4279
|
const formatId = reader.uint16();
|
|
3462
|
-
if (!
|
|
3463
|
-
throw new TypeError(
|
|
4280
|
+
if (!Object.prototype.hasOwnProperty.call(formats, formatId)) {
|
|
4281
|
+
throw new TypeError(
|
|
4282
|
+
"Unsupported format in WAV file: 0x" + formatId.toString(16)
|
|
4283
|
+
);
|
|
3464
4284
|
}
|
|
3465
4285
|
const format = {
|
|
3466
4286
|
formatId,
|
|
@@ -3612,7 +4432,11 @@ var WavDecoder_default = WavDecoder;
|
|
|
3612
4432
|
var SoundfileReader = class {
|
|
3613
4433
|
// Set the fallback paths
|
|
3614
4434
|
static get fallbackPaths() {
|
|
3615
|
-
return [
|
|
4435
|
+
return [
|
|
4436
|
+
location.href,
|
|
4437
|
+
this.getParentUrl(location.href),
|
|
4438
|
+
location.origin
|
|
4439
|
+
];
|
|
3616
4440
|
}
|
|
3617
4441
|
/**
|
|
3618
4442
|
* Extract the parent URL from an URL.
|
|
@@ -3624,7 +4448,7 @@ var SoundfileReader = class {
|
|
|
3624
4448
|
}
|
|
3625
4449
|
/**
|
|
3626
4450
|
* Convert an audio buffer to audio data.
|
|
3627
|
-
*
|
|
4451
|
+
*
|
|
3628
4452
|
* @param audioBuffer : the audio buffer to convert
|
|
3629
4453
|
* @returns : the audio data
|
|
3630
4454
|
*/
|
|
@@ -3637,7 +4461,7 @@ var SoundfileReader = class {
|
|
|
3637
4461
|
}
|
|
3638
4462
|
/**
|
|
3639
4463
|
* Extract the URLs from the metadata.
|
|
3640
|
-
*
|
|
4464
|
+
*
|
|
3641
4465
|
* @param dspMeta : the metadata
|
|
3642
4466
|
* @returns : the URLs
|
|
3643
4467
|
*/
|
|
@@ -3654,7 +4478,7 @@ var SoundfileReader = class {
|
|
|
3654
4478
|
}
|
|
3655
4479
|
/**
|
|
3656
4480
|
* Check if the file exists.
|
|
3657
|
-
*
|
|
4481
|
+
*
|
|
3658
4482
|
* @param url : the url of the file to check
|
|
3659
4483
|
* @returns : true if the file exists, otherwise false
|
|
3660
4484
|
*/
|
|
@@ -3671,7 +4495,7 @@ var SoundfileReader = class {
|
|
|
3671
4495
|
}
|
|
3672
4496
|
/**
|
|
3673
4497
|
* Fetch the soundfile.
|
|
3674
|
-
*
|
|
4498
|
+
*
|
|
3675
4499
|
* @param url : the url of the soundfile
|
|
3676
4500
|
* @param audioCtx : the audio context
|
|
3677
4501
|
* @returns : the audio data
|
|
@@ -3679,14 +4503,17 @@ var SoundfileReader = class {
|
|
|
3679
4503
|
static async fetchSoundfile(url, audioCtx) {
|
|
3680
4504
|
console.log(`Loading sound file from ${url}`);
|
|
3681
4505
|
const response = await fetch(url);
|
|
3682
|
-
if (!response.ok)
|
|
4506
|
+
if (!response.ok)
|
|
4507
|
+
throw new Error(
|
|
4508
|
+
`Failed to load sound file from ${url}: ${response.statusText}`
|
|
4509
|
+
);
|
|
3683
4510
|
const arrayBuffer = await response.arrayBuffer();
|
|
3684
4511
|
const audioBuffer = await audioCtx.decodeAudioData(arrayBuffer);
|
|
3685
4512
|
return this.toAudioData(audioBuffer);
|
|
3686
4513
|
}
|
|
3687
4514
|
/**
|
|
3688
4515
|
* Load the soundfile.
|
|
3689
|
-
*
|
|
4516
|
+
*
|
|
3690
4517
|
* @param filename : the filename
|
|
3691
4518
|
* @param metaUrls : the metadata URLs
|
|
3692
4519
|
* @param soundfiles : the soundfiles
|
|
@@ -3694,15 +4521,28 @@ var SoundfileReader = class {
|
|
|
3694
4521
|
*/
|
|
3695
4522
|
static async loadSoundfile(filename, metaUrls, soundfiles, audioCtx) {
|
|
3696
4523
|
if (soundfiles == null ? void 0 : soundfiles[filename]) return;
|
|
3697
|
-
const urlsToCheck = [
|
|
3698
|
-
|
|
4524
|
+
const urlsToCheck = [
|
|
4525
|
+
filename,
|
|
4526
|
+
...[...metaUrls, ...this.fallbackPaths].map(
|
|
4527
|
+
(path) => new URL(filename, path.endsWith("/") ? path : `${path}/`).href
|
|
4528
|
+
)
|
|
4529
|
+
];
|
|
4530
|
+
const checkResults = await Promise.all(
|
|
4531
|
+
urlsToCheck.map((url) => this.checkFileExists(url))
|
|
4532
|
+
);
|
|
3699
4533
|
const successIndex = checkResults.findIndex((r) => !!r);
|
|
3700
|
-
if (successIndex === -1)
|
|
3701
|
-
|
|
4534
|
+
if (successIndex === -1)
|
|
4535
|
+
throw new Error(
|
|
4536
|
+
`Failed to load sound file ${filename}, all check failed.`
|
|
4537
|
+
);
|
|
4538
|
+
soundfiles[filename] = await this.fetchSoundfile(
|
|
4539
|
+
urlsToCheck[successIndex],
|
|
4540
|
+
audioCtx
|
|
4541
|
+
);
|
|
3702
4542
|
}
|
|
3703
4543
|
/**
|
|
3704
4544
|
* Load the soundfiles, public API.
|
|
3705
|
-
*
|
|
4545
|
+
*
|
|
3706
4546
|
* @param dspMeta : the metadata
|
|
3707
4547
|
* @param soundfilesIn : the soundfiles
|
|
3708
4548
|
* @param audioCtx : the audio context
|
|
@@ -3743,7 +4583,6 @@ var FaustAudioWorkletCommunicator = class {
|
|
|
3743
4583
|
this.uin8NewGyrData = new Uint8ClampedArray(ab, ptr, 1);
|
|
3744
4584
|
ptr += Uint8ClampedArray.BYTES_PER_ELEMENT;
|
|
3745
4585
|
ptr += Uint8ClampedArray.BYTES_PER_ELEMENT;
|
|
3746
|
-
;
|
|
3747
4586
|
this.f32Acc = new Float32Array(ab, ptr, 3);
|
|
3748
4587
|
ptr += 3 * Float32Array.BYTES_PER_ELEMENT;
|
|
3749
4588
|
this.f32Gyr = new Float32Array(ab, ptr, 3);
|
|
@@ -3783,7 +4622,11 @@ var FaustAudioWorkletCommunicator = class {
|
|
|
3783
4622
|
const [x, y, z] = this.f32Acc;
|
|
3784
4623
|
return { x, y, z, invert };
|
|
3785
4624
|
}
|
|
3786
|
-
setGyr({
|
|
4625
|
+
setGyr({
|
|
4626
|
+
alpha,
|
|
4627
|
+
beta,
|
|
4628
|
+
gamma
|
|
4629
|
+
}) {
|
|
3787
4630
|
if (!this.supportSharedArrayBuffer) {
|
|
3788
4631
|
const e = { type: "gyr", data: { alpha, beta, gamma } };
|
|
3789
4632
|
this.port.postMessage(e);
|
|
@@ -3871,13 +4714,19 @@ var FaustAudioWorkletNode = class extends (globalThis.AudioWorkletNode || null)
|
|
|
3871
4714
|
}
|
|
3872
4715
|
};
|
|
3873
4716
|
// Accelerometer and gyroscope handlers
|
|
3874
|
-
this.handleDeviceMotion = ({
|
|
4717
|
+
this.handleDeviceMotion = ({
|
|
4718
|
+
accelerationIncludingGravity
|
|
4719
|
+
}) => {
|
|
3875
4720
|
const isAndroid = /Android/i.test(navigator.userAgent);
|
|
3876
4721
|
if (!accelerationIncludingGravity) return;
|
|
3877
4722
|
const { x, y, z } = accelerationIncludingGravity;
|
|
3878
4723
|
this.propagateAcc({ x, y, z }, isAndroid);
|
|
3879
4724
|
};
|
|
3880
|
-
this.handleDeviceOrientation = ({
|
|
4725
|
+
this.handleDeviceOrientation = ({
|
|
4726
|
+
alpha,
|
|
4727
|
+
beta,
|
|
4728
|
+
gamma
|
|
4729
|
+
}) => {
|
|
3881
4730
|
this.propagateGyr({ alpha, beta, gamma });
|
|
3882
4731
|
};
|
|
3883
4732
|
this.fJSONDsp = JSONObj;
|
|
@@ -3909,14 +4758,22 @@ var FaustAudioWorkletNode = class extends (globalThis.AudioWorkletNode || null)
|
|
|
3909
4758
|
async startSensors() {
|
|
3910
4759
|
if (this.hasAccInput) {
|
|
3911
4760
|
if (window.DeviceMotionEvent) {
|
|
3912
|
-
window.addEventListener(
|
|
4761
|
+
window.addEventListener(
|
|
4762
|
+
"devicemotion",
|
|
4763
|
+
this.handleDeviceMotion,
|
|
4764
|
+
true
|
|
4765
|
+
);
|
|
3913
4766
|
} else {
|
|
3914
4767
|
console.log("Cannot set the accelerometer handler.");
|
|
3915
4768
|
}
|
|
3916
4769
|
}
|
|
3917
4770
|
if (this.hasGyrInput) {
|
|
3918
4771
|
if (window.DeviceMotionEvent) {
|
|
3919
|
-
window.addEventListener(
|
|
4772
|
+
window.addEventListener(
|
|
4773
|
+
"deviceorientation",
|
|
4774
|
+
this.handleDeviceOrientation,
|
|
4775
|
+
true
|
|
4776
|
+
);
|
|
3920
4777
|
} else {
|
|
3921
4778
|
console.log("Cannot set the gyroscope handler.");
|
|
3922
4779
|
}
|
|
@@ -3924,10 +4781,18 @@ var FaustAudioWorkletNode = class extends (globalThis.AudioWorkletNode || null)
|
|
|
3924
4781
|
}
|
|
3925
4782
|
stopSensors() {
|
|
3926
4783
|
if (this.hasAccInput) {
|
|
3927
|
-
window.removeEventListener(
|
|
4784
|
+
window.removeEventListener(
|
|
4785
|
+
"devicemotion",
|
|
4786
|
+
this.handleDeviceMotion,
|
|
4787
|
+
true
|
|
4788
|
+
);
|
|
3928
4789
|
}
|
|
3929
4790
|
if (this.hasGyrInput) {
|
|
3930
|
-
window.removeEventListener(
|
|
4791
|
+
window.removeEventListener(
|
|
4792
|
+
"deviceorientation",
|
|
4793
|
+
this.handleDeviceOrientation,
|
|
4794
|
+
true
|
|
4795
|
+
);
|
|
3931
4796
|
}
|
|
3932
4797
|
}
|
|
3933
4798
|
setOutputParamHandler(handler) {
|
|
@@ -3975,7 +4840,9 @@ var FaustAudioWorkletNode = class extends (globalThis.AudioWorkletNode || null)
|
|
|
3975
4840
|
}
|
|
3976
4841
|
metadata(handler) {
|
|
3977
4842
|
if (this.fJSONDsp.meta) {
|
|
3978
|
-
this.fJSONDsp.meta.forEach(
|
|
4843
|
+
this.fJSONDsp.meta.forEach(
|
|
4844
|
+
(meta) => handler(Object.keys(meta)[0], meta[Object.keys(meta)[0]])
|
|
4845
|
+
);
|
|
3979
4846
|
}
|
|
3980
4847
|
}
|
|
3981
4848
|
midiMessage(data) {
|
|
@@ -3985,7 +4852,8 @@ var FaustAudioWorkletNode = class extends (globalThis.AudioWorkletNode || null)
|
|
|
3985
4852
|
const data2 = data[2];
|
|
3986
4853
|
if (cmd === 11) this.ctrlChange(channel, data1, data2);
|
|
3987
4854
|
else if (cmd === 14) this.pitchWheel(channel, data2 * 128 + data1);
|
|
3988
|
-
if (cmd === 8 || cmd === 9 && data2 === 0)
|
|
4855
|
+
if (cmd === 8 || cmd === 9 && data2 === 0)
|
|
4856
|
+
this.keyOff(channel, data1, data2);
|
|
3989
4857
|
else if (cmd === 9) this.keyOn(channel, data1, data2);
|
|
3990
4858
|
else this.port.postMessage({ type: "midi", data });
|
|
3991
4859
|
}
|
|
@@ -4019,7 +4887,11 @@ var FaustAudioWorkletNode = class extends (globalThis.AudioWorkletNode || null)
|
|
|
4019
4887
|
propagateGyr(event) {
|
|
4020
4888
|
if (!event) return;
|
|
4021
4889
|
const { alpha, beta, gamma } = event;
|
|
4022
|
-
this.fCommunicator.setGyr({
|
|
4890
|
+
this.fCommunicator.setGyr({
|
|
4891
|
+
alpha,
|
|
4892
|
+
beta,
|
|
4893
|
+
gamma
|
|
4894
|
+
});
|
|
4023
4895
|
}
|
|
4024
4896
|
setParamValue(path, value) {
|
|
4025
4897
|
const e = { type: "param", data: { path, value } };
|
|
@@ -4061,7 +4933,12 @@ _hasAccInput = new WeakMap();
|
|
|
4061
4933
|
_hasGyrInput = new WeakMap();
|
|
4062
4934
|
var FaustMonoAudioWorkletNode = class extends FaustAudioWorkletNode {
|
|
4063
4935
|
constructor(context, options) {
|
|
4064
|
-
super(
|
|
4936
|
+
super(
|
|
4937
|
+
context,
|
|
4938
|
+
options.processorOptions.name,
|
|
4939
|
+
options.processorOptions.factory,
|
|
4940
|
+
options
|
|
4941
|
+
);
|
|
4065
4942
|
this.onprocessorerror = (e) => {
|
|
4066
4943
|
throw e;
|
|
4067
4944
|
};
|
|
@@ -4101,22 +4978,24 @@ var FaustPolyAudioWorkletNode = class extends FaustAudioWorkletNode {
|
|
|
4101
4978
|
const e = this.fJSONEffect;
|
|
4102
4979
|
const r = { ...o };
|
|
4103
4980
|
if (e) {
|
|
4104
|
-
r.ui = [
|
|
4105
|
-
|
|
4106
|
-
|
|
4107
|
-
|
|
4108
|
-
|
|
4109
|
-
|
|
4110
|
-
|
|
4111
|
-
|
|
4981
|
+
r.ui = [
|
|
4982
|
+
{
|
|
4983
|
+
type: "tgroup",
|
|
4984
|
+
label: "Sequencer",
|
|
4985
|
+
items: [
|
|
4986
|
+
{ type: "vgroup", label: "Instrument", items: o.ui },
|
|
4987
|
+
{ type: "vgroup", label: "Effect", items: e.ui }
|
|
4988
|
+
]
|
|
4989
|
+
}
|
|
4990
|
+
];
|
|
4112
4991
|
} else {
|
|
4113
|
-
r.ui = [
|
|
4114
|
-
|
|
4115
|
-
|
|
4116
|
-
|
|
4117
|
-
{ type: "vgroup", label: "Voices", items: o.ui }
|
|
4118
|
-
|
|
4119
|
-
|
|
4992
|
+
r.ui = [
|
|
4993
|
+
{
|
|
4994
|
+
type: "tgroup",
|
|
4995
|
+
label: "Polyphonic",
|
|
4996
|
+
items: [{ type: "vgroup", label: "Voices", items: o.ui }]
|
|
4997
|
+
}
|
|
4998
|
+
];
|
|
4120
4999
|
}
|
|
4121
5000
|
return r;
|
|
4122
5001
|
}
|
|
@@ -4139,13 +5018,19 @@ var FaustScriptProcessorNode = class extends (globalThis.ScriptProcessorNode ||
|
|
|
4139
5018
|
this.fDSPCode = instance;
|
|
4140
5019
|
this.fInputs = new Array(this.fDSPCode.getNumInputs());
|
|
4141
5020
|
this.fOutputs = new Array(this.fDSPCode.getNumOutputs());
|
|
4142
|
-
this.handleDeviceMotion = ({
|
|
5021
|
+
this.handleDeviceMotion = ({
|
|
5022
|
+
accelerationIncludingGravity
|
|
5023
|
+
}) => {
|
|
4143
5024
|
const isAndroid = /Android/i.test(navigator.userAgent);
|
|
4144
5025
|
if (!accelerationIncludingGravity) return;
|
|
4145
5026
|
const { x, y, z } = accelerationIncludingGravity;
|
|
4146
5027
|
this.propagateAcc({ x, y, z }, isAndroid);
|
|
4147
5028
|
};
|
|
4148
|
-
this.handleDeviceOrientation = ({
|
|
5029
|
+
this.handleDeviceOrientation = ({
|
|
5030
|
+
alpha,
|
|
5031
|
+
beta,
|
|
5032
|
+
gamma
|
|
5033
|
+
}) => {
|
|
4149
5034
|
this.propagateGyr({ alpha, beta, gamma });
|
|
4150
5035
|
};
|
|
4151
5036
|
this.onaudioprocess = (e) => {
|
|
@@ -4164,14 +5049,22 @@ var FaustScriptProcessorNode = class extends (globalThis.ScriptProcessorNode ||
|
|
|
4164
5049
|
async startSensors() {
|
|
4165
5050
|
if (this.hasAccInput) {
|
|
4166
5051
|
if (window.DeviceMotionEvent) {
|
|
4167
|
-
window.addEventListener(
|
|
5052
|
+
window.addEventListener(
|
|
5053
|
+
"devicemotion",
|
|
5054
|
+
this.handleDeviceMotion,
|
|
5055
|
+
true
|
|
5056
|
+
);
|
|
4168
5057
|
} else {
|
|
4169
5058
|
console.log("Cannot set the accelerometer handler.");
|
|
4170
5059
|
}
|
|
4171
5060
|
}
|
|
4172
5061
|
if (this.hasGyrInput) {
|
|
4173
5062
|
if (window.DeviceMotionEvent) {
|
|
4174
|
-
window.addEventListener(
|
|
5063
|
+
window.addEventListener(
|
|
5064
|
+
"deviceorientation",
|
|
5065
|
+
this.handleDeviceOrientation,
|
|
5066
|
+
true
|
|
5067
|
+
);
|
|
4175
5068
|
} else {
|
|
4176
5069
|
console.log("Cannot set the gyroscope handler.");
|
|
4177
5070
|
}
|
|
@@ -4180,10 +5073,18 @@ var FaustScriptProcessorNode = class extends (globalThis.ScriptProcessorNode ||
|
|
|
4180
5073
|
/** Stop accelerometer and gyroscope handlers */
|
|
4181
5074
|
stopSensors() {
|
|
4182
5075
|
if (this.hasAccInput) {
|
|
4183
|
-
window.removeEventListener(
|
|
5076
|
+
window.removeEventListener(
|
|
5077
|
+
"devicemotion",
|
|
5078
|
+
this.handleDeviceMotion,
|
|
5079
|
+
true
|
|
5080
|
+
);
|
|
4184
5081
|
}
|
|
4185
5082
|
if (this.hasGyrInput) {
|
|
4186
|
-
window.removeEventListener(
|
|
5083
|
+
window.removeEventListener(
|
|
5084
|
+
"deviceorientation",
|
|
5085
|
+
this.handleDeviceOrientation,
|
|
5086
|
+
true
|
|
5087
|
+
);
|
|
4187
5088
|
}
|
|
4188
5089
|
}
|
|
4189
5090
|
compute(input, output) {
|
|
@@ -4305,13 +5206,19 @@ var _FaustMonoDspGenerator = class _FaustMonoDspGenerator {
|
|
|
4305
5206
|
}
|
|
4306
5207
|
}
|
|
4307
5208
|
addSoundfiles(soundfileMap) {
|
|
4308
|
-
if (!this.factory)
|
|
5209
|
+
if (!this.factory)
|
|
5210
|
+
throw new Error(
|
|
5211
|
+
"Code is not compiled, please define the factory or call `await this.compile()` first."
|
|
5212
|
+
);
|
|
4309
5213
|
for (const id in soundfileMap) {
|
|
4310
5214
|
this.factory.soundfiles[id] = soundfileMap[id];
|
|
4311
5215
|
}
|
|
4312
5216
|
}
|
|
4313
5217
|
getSoundfileList() {
|
|
4314
|
-
if (!this.factory)
|
|
5218
|
+
if (!this.factory)
|
|
5219
|
+
throw new Error(
|
|
5220
|
+
"Code is not compiled, please define the factory or call `await this.compile()` first."
|
|
5221
|
+
);
|
|
4315
5222
|
const meta = JSON.parse(this.factory.json);
|
|
4316
5223
|
const map = SoundfileReader_default.findSoundfilesFromMeta(meta);
|
|
4317
5224
|
if (!map) return [];
|
|
@@ -4319,19 +5226,40 @@ var _FaustMonoDspGenerator = class _FaustMonoDspGenerator {
|
|
|
4319
5226
|
}
|
|
4320
5227
|
async createNode(context, name = this.name, factory = this.factory, sp = false, bufferSize = 1024, processorName = (factory == null ? void 0 : factory.shaKey) || name, processorOptions = {}) {
|
|
4321
5228
|
var _a, _b;
|
|
4322
|
-
if (!factory)
|
|
5229
|
+
if (!factory)
|
|
5230
|
+
throw new Error(
|
|
5231
|
+
"Code is not compiled, please define the factory or call `await this.compile()` first."
|
|
5232
|
+
);
|
|
4323
5233
|
const meta = JSON.parse(factory.json);
|
|
4324
5234
|
const sampleSize = meta.compile_options.match("-double") ? 8 : 4;
|
|
4325
|
-
factory.soundfiles = await SoundfileReader_default.loadSoundfiles(
|
|
5235
|
+
factory.soundfiles = await SoundfileReader_default.loadSoundfiles(
|
|
5236
|
+
meta,
|
|
5237
|
+
factory.soundfiles || {},
|
|
5238
|
+
context
|
|
5239
|
+
);
|
|
4326
5240
|
if (sp) {
|
|
4327
5241
|
const instance = await FaustWasmInstantiator_default.createAsyncMonoDSPInstance(factory);
|
|
4328
|
-
const monoDsp = new FaustMonoWebAudioDsp(
|
|
4329
|
-
|
|
5242
|
+
const monoDsp = new FaustMonoWebAudioDsp(
|
|
5243
|
+
instance,
|
|
5244
|
+
context.sampleRate,
|
|
5245
|
+
sampleSize,
|
|
5246
|
+
bufferSize,
|
|
5247
|
+
factory.soundfiles
|
|
5248
|
+
);
|
|
5249
|
+
const sp2 = context.createScriptProcessor(
|
|
5250
|
+
bufferSize,
|
|
5251
|
+
monoDsp.getNumInputs(),
|
|
5252
|
+
monoDsp.getNumOutputs()
|
|
5253
|
+
);
|
|
4330
5254
|
Object.setPrototypeOf(sp2, FaustMonoScriptProcessorNode.prototype);
|
|
4331
5255
|
sp2.init(monoDsp);
|
|
4332
5256
|
return sp2;
|
|
4333
5257
|
} else {
|
|
4334
|
-
if (!_FaustMonoDspGenerator.gWorkletProcessors.has(context))
|
|
5258
|
+
if (!_FaustMonoDspGenerator.gWorkletProcessors.has(context))
|
|
5259
|
+
_FaustMonoDspGenerator.gWorkletProcessors.set(
|
|
5260
|
+
context,
|
|
5261
|
+
/* @__PURE__ */ new Set()
|
|
5262
|
+
);
|
|
4335
5263
|
if (!((_a = _FaustMonoDspGenerator.gWorkletProcessors.get(context)) == null ? void 0 : _a.has(processorName))) {
|
|
4336
5264
|
try {
|
|
4337
5265
|
const processorCode = `
|
|
@@ -4371,24 +5299,41 @@ const dependencies = {
|
|
|
4371
5299
|
// Generate the actual AudioWorkletProcessor code
|
|
4372
5300
|
(${FaustAudioWorkletProcessor_default.toString()})(dependencies, faustData);
|
|
4373
5301
|
`;
|
|
4374
|
-
const url = URL.createObjectURL(
|
|
5302
|
+
const url = URL.createObjectURL(
|
|
5303
|
+
new Blob([processorCode], { type: "text/javascript" })
|
|
5304
|
+
);
|
|
4375
5305
|
await context.audioWorklet.addModule(url);
|
|
4376
5306
|
(_b = _FaustMonoDspGenerator.gWorkletProcessors.get(context)) == null ? void 0 : _b.add(processorName);
|
|
4377
5307
|
} catch (e) {
|
|
4378
5308
|
throw e;
|
|
4379
5309
|
}
|
|
4380
5310
|
}
|
|
4381
|
-
const node = new FaustMonoAudioWorkletNode(context, {
|
|
5311
|
+
const node = new FaustMonoAudioWorkletNode(context, {
|
|
5312
|
+
processorOptions: {
|
|
5313
|
+
name: processorName,
|
|
5314
|
+
factory,
|
|
5315
|
+
sampleSize,
|
|
5316
|
+
...processorOptions
|
|
5317
|
+
}
|
|
5318
|
+
});
|
|
4382
5319
|
return node;
|
|
4383
5320
|
}
|
|
4384
5321
|
}
|
|
4385
5322
|
async createFFTNode(context, fftUtils, name = this.name, factory = this.factory, fftOptions = {}, processorName = (factory == null ? void 0 : factory.shaKey) ? `${factory.shaKey}_fft` : name, processorOptions = {}) {
|
|
4386
5323
|
var _a, _b;
|
|
4387
|
-
if (!factory)
|
|
5324
|
+
if (!factory)
|
|
5325
|
+
throw new Error(
|
|
5326
|
+
"Code is not compiled, please define the factory or call `await this.compile()` first."
|
|
5327
|
+
);
|
|
4388
5328
|
const meta = JSON.parse(factory.json);
|
|
4389
5329
|
const sampleSize = meta.compile_options.match("-double") ? 8 : 4;
|
|
4390
|
-
factory.soundfiles = await SoundfileReader_default.loadSoundfiles(
|
|
4391
|
-
|
|
5330
|
+
factory.soundfiles = await SoundfileReader_default.loadSoundfiles(
|
|
5331
|
+
meta,
|
|
5332
|
+
factory.soundfiles || {},
|
|
5333
|
+
context
|
|
5334
|
+
);
|
|
5335
|
+
if (!_FaustMonoDspGenerator.gWorkletProcessors.has(context))
|
|
5336
|
+
_FaustMonoDspGenerator.gWorkletProcessors.set(context, /* @__PURE__ */ new Set());
|
|
4392
5337
|
if (!((_a = _FaustMonoDspGenerator.gWorkletProcessors.get(context)) == null ? void 0 : _a.has(processorName))) {
|
|
4393
5338
|
try {
|
|
4394
5339
|
const processorCode = `
|
|
@@ -4430,14 +5375,25 @@ const dependencies = {
|
|
|
4430
5375
|
// Generate the actual AudioWorkletProcessor code
|
|
4431
5376
|
(${FaustFFTAudioWorkletProcessor_default.toString()})(dependencies, faustData);
|
|
4432
5377
|
`;
|
|
4433
|
-
const url = URL.createObjectURL(
|
|
5378
|
+
const url = URL.createObjectURL(
|
|
5379
|
+
new Blob([processorCode], { type: "text/javascript" })
|
|
5380
|
+
);
|
|
4434
5381
|
await context.audioWorklet.addModule(url);
|
|
4435
5382
|
(_b = _FaustMonoDspGenerator.gWorkletProcessors.get(context)) == null ? void 0 : _b.add(processorName);
|
|
4436
5383
|
} catch (e) {
|
|
4437
5384
|
throw e;
|
|
4438
5385
|
}
|
|
4439
5386
|
}
|
|
4440
|
-
const node = new FaustMonoAudioWorkletNode(context, {
|
|
5387
|
+
const node = new FaustMonoAudioWorkletNode(context, {
|
|
5388
|
+
channelCount: Math.max(1, Math.ceil(meta.inputs / 3)),
|
|
5389
|
+
outputChannelCount: [Math.ceil(meta.outputs / 2)],
|
|
5390
|
+
processorOptions: {
|
|
5391
|
+
name: processorName,
|
|
5392
|
+
factory,
|
|
5393
|
+
sampleSize,
|
|
5394
|
+
...processorOptions
|
|
5395
|
+
}
|
|
5396
|
+
});
|
|
4441
5397
|
if (fftOptions.fftSize) {
|
|
4442
5398
|
const param = node.parameters.get("fftSize");
|
|
4443
5399
|
if (param) param.value = fftOptions.fftSize;
|
|
@@ -4457,7 +5413,10 @@ const dependencies = {
|
|
|
4457
5413
|
return node;
|
|
4458
5414
|
}
|
|
4459
5415
|
async createAudioWorkletProcessor(name = this.name, factory = this.factory, processorName = (factory == null ? void 0 : factory.shaKey) || name) {
|
|
4460
|
-
if (!factory)
|
|
5416
|
+
if (!factory)
|
|
5417
|
+
throw new Error(
|
|
5418
|
+
"Code is not compiled, please define the factory or call `await this.compile()` first."
|
|
5419
|
+
);
|
|
4461
5420
|
const meta = JSON.parse(factory.json);
|
|
4462
5421
|
const dependencies = {
|
|
4463
5422
|
FaustBaseWebAudioDsp,
|
|
@@ -4474,19 +5433,36 @@ const dependencies = {
|
|
|
4474
5433
|
dspMeta: meta,
|
|
4475
5434
|
poly: false
|
|
4476
5435
|
};
|
|
4477
|
-
const Processor = FaustAudioWorkletProcessor_default(
|
|
5436
|
+
const Processor = FaustAudioWorkletProcessor_default(
|
|
5437
|
+
dependencies,
|
|
5438
|
+
faustData
|
|
5439
|
+
);
|
|
4478
5440
|
return Processor;
|
|
4479
5441
|
} catch (e) {
|
|
4480
5442
|
throw e;
|
|
4481
5443
|
}
|
|
4482
5444
|
}
|
|
4483
5445
|
async createOfflineProcessor(sampleRate, bufferSize, factory = this.factory, context) {
|
|
4484
|
-
if (!factory)
|
|
5446
|
+
if (!factory)
|
|
5447
|
+
throw new Error(
|
|
5448
|
+
"Code is not compiled, please define the factory or call `await this.compile()` first."
|
|
5449
|
+
);
|
|
4485
5450
|
const meta = JSON.parse(factory.json);
|
|
4486
5451
|
const instance = await FaustWasmInstantiator_default.createAsyncMonoDSPInstance(factory);
|
|
4487
5452
|
const sampleSize = meta.compile_options.match("-double") ? 8 : 4;
|
|
4488
|
-
if (context)
|
|
4489
|
-
|
|
5453
|
+
if (context)
|
|
5454
|
+
factory.soundfiles = await SoundfileReader_default.loadSoundfiles(
|
|
5455
|
+
meta,
|
|
5456
|
+
factory.soundfiles || {},
|
|
5457
|
+
context
|
|
5458
|
+
);
|
|
5459
|
+
const monoDsp = new FaustMonoWebAudioDsp(
|
|
5460
|
+
instance,
|
|
5461
|
+
sampleRate,
|
|
5462
|
+
sampleSize,
|
|
5463
|
+
bufferSize,
|
|
5464
|
+
factory.soundfiles
|
|
5465
|
+
);
|
|
4490
5466
|
return new FaustMonoOfflineProcessor(monoDsp, bufferSize);
|
|
4491
5467
|
}
|
|
4492
5468
|
getMeta() {
|
|
@@ -4512,7 +5488,11 @@ var _FaustPolyDspGenerator = class _FaustPolyDspGenerator {
|
|
|
4512
5488
|
};
|
|
4513
5489
|
process = dsp_code.effect;`) {
|
|
4514
5490
|
try {
|
|
4515
|
-
this.effectFactory = await compiler.createPolyDSPFactory(
|
|
5491
|
+
this.effectFactory = await compiler.createPolyDSPFactory(
|
|
5492
|
+
name,
|
|
5493
|
+
effectCodeAux,
|
|
5494
|
+
args
|
|
5495
|
+
);
|
|
4516
5496
|
if (this.effectFactory) {
|
|
4517
5497
|
const effectJSON = JSON.parse(this.effectFactory.json);
|
|
4518
5498
|
const dspCode = `// Voice output is forced to 2, when DSP is stereo or effect has 2 ins or 2 outs,
|
|
@@ -4552,16 +5532,28 @@ dsp_code = environment{
|
|
|
4552
5532
|
};
|
|
4553
5533
|
process = adaptorIns(dsp_code.process) : dsp_code.effect : adaptorOuts;
|
|
4554
5534
|
`;
|
|
4555
|
-
this.voiceFactory = await compiler.createPolyDSPFactory(
|
|
5535
|
+
this.voiceFactory = await compiler.createPolyDSPFactory(
|
|
5536
|
+
name,
|
|
5537
|
+
dspCode,
|
|
5538
|
+
args
|
|
5539
|
+
);
|
|
4556
5540
|
try {
|
|
4557
|
-
this.effectFactory = await compiler.createPolyDSPFactory(
|
|
5541
|
+
this.effectFactory = await compiler.createPolyDSPFactory(
|
|
5542
|
+
name,
|
|
5543
|
+
effectCode,
|
|
5544
|
+
args + " -inpl"
|
|
5545
|
+
);
|
|
4558
5546
|
} catch (e) {
|
|
4559
5547
|
console.warn(e);
|
|
4560
5548
|
}
|
|
4561
5549
|
}
|
|
4562
5550
|
} catch (e) {
|
|
4563
5551
|
console.warn(e);
|
|
4564
|
-
this.voiceFactory = await compiler.createPolyDSPFactory(
|
|
5552
|
+
this.voiceFactory = await compiler.createPolyDSPFactory(
|
|
5553
|
+
name,
|
|
5554
|
+
dspCodeAux,
|
|
5555
|
+
args
|
|
5556
|
+
);
|
|
4565
5557
|
}
|
|
4566
5558
|
if (this.voiceFactory) {
|
|
4567
5559
|
this.name = name;
|
|
@@ -4576,13 +5568,19 @@ process = adaptorIns(dsp_code.process) : dsp_code.effect : adaptorOuts;
|
|
|
4576
5568
|
}
|
|
4577
5569
|
}
|
|
4578
5570
|
addSoundfiles(soundfileMap) {
|
|
4579
|
-
if (!this.voiceFactory)
|
|
5571
|
+
if (!this.voiceFactory)
|
|
5572
|
+
throw new Error(
|
|
5573
|
+
"Code is not compiled, please define the factory or call `await this.compile()` first."
|
|
5574
|
+
);
|
|
4580
5575
|
for (const id in soundfileMap) {
|
|
4581
5576
|
this.voiceFactory.soundfiles[id] = soundfileMap[id];
|
|
4582
5577
|
}
|
|
4583
5578
|
}
|
|
4584
5579
|
getSoundfileList() {
|
|
4585
|
-
if (!this.voiceFactory)
|
|
5580
|
+
if (!this.voiceFactory)
|
|
5581
|
+
throw new Error(
|
|
5582
|
+
"Code is not compiled, please define the factory or call `await this.compile()` first."
|
|
5583
|
+
);
|
|
4586
5584
|
const meta = JSON.parse(this.voiceFactory.json);
|
|
4587
5585
|
const map = SoundfileReader_default.findSoundfilesFromMeta(meta);
|
|
4588
5586
|
if (!map) return [];
|
|
@@ -4593,22 +5591,56 @@ process = adaptorIns(dsp_code.process) : dsp_code.effect : adaptorOuts;
|
|
|
4593
5591
|
}
|
|
4594
5592
|
async createNode(context, voices, name = this.name, voiceFactory = this.voiceFactory, mixerModule = this.mixerModule, effectFactory = this.effectFactory, sp = false, bufferSize = 1024, processorName = ((voiceFactory == null ? void 0 : voiceFactory.shaKey) || "") + ((effectFactory == null ? void 0 : effectFactory.shaKey) || "") || `${name}_poly`, processorOptions = {}) {
|
|
4595
5593
|
var _a, _b;
|
|
4596
|
-
if (!voiceFactory)
|
|
5594
|
+
if (!voiceFactory)
|
|
5595
|
+
throw new Error(
|
|
5596
|
+
"Code is not compiled, please define the factory or call `await this.compile()` first."
|
|
5597
|
+
);
|
|
4597
5598
|
const voiceMeta = JSON.parse(voiceFactory.json);
|
|
4598
5599
|
const effectMeta = effectFactory ? JSON.parse(effectFactory.json) : void 0;
|
|
4599
5600
|
const sampleSize = voiceMeta.compile_options.match("-double") ? 8 : 4;
|
|
4600
|
-
voiceFactory.soundfiles = await SoundfileReader_default.loadSoundfiles(
|
|
4601
|
-
|
|
5601
|
+
voiceFactory.soundfiles = await SoundfileReader_default.loadSoundfiles(
|
|
5602
|
+
voiceMeta,
|
|
5603
|
+
voiceFactory.soundfiles || {},
|
|
5604
|
+
context
|
|
5605
|
+
);
|
|
5606
|
+
if (effectFactory)
|
|
5607
|
+
effectFactory.soundfiles = await SoundfileReader_default.loadSoundfiles(
|
|
5608
|
+
effectMeta,
|
|
5609
|
+
effectFactory.soundfiles || {},
|
|
5610
|
+
context
|
|
5611
|
+
);
|
|
4602
5612
|
if (sp) {
|
|
4603
|
-
const instance = await FaustWasmInstantiator_default.createAsyncPolyDSPInstance(
|
|
4604
|
-
|
|
4605
|
-
|
|
4606
|
-
|
|
5613
|
+
const instance = await FaustWasmInstantiator_default.createAsyncPolyDSPInstance(
|
|
5614
|
+
voiceFactory,
|
|
5615
|
+
mixerModule,
|
|
5616
|
+
voices,
|
|
5617
|
+
effectFactory || void 0
|
|
5618
|
+
);
|
|
5619
|
+
const soundfiles = {
|
|
5620
|
+
...effectFactory == null ? void 0 : effectFactory.soundfiles,
|
|
5621
|
+
...voiceFactory.soundfiles
|
|
5622
|
+
};
|
|
5623
|
+
const polyDsp = new FaustPolyWebAudioDsp(
|
|
5624
|
+
instance,
|
|
5625
|
+
context.sampleRate,
|
|
5626
|
+
sampleSize,
|
|
5627
|
+
bufferSize,
|
|
5628
|
+
soundfiles
|
|
5629
|
+
);
|
|
5630
|
+
const sp2 = context.createScriptProcessor(
|
|
5631
|
+
bufferSize,
|
|
5632
|
+
polyDsp.getNumInputs(),
|
|
5633
|
+
polyDsp.getNumOutputs()
|
|
5634
|
+
);
|
|
4607
5635
|
Object.setPrototypeOf(sp2, FaustPolyScriptProcessorNode.prototype);
|
|
4608
5636
|
sp2.init(polyDsp);
|
|
4609
5637
|
return sp2;
|
|
4610
5638
|
} else {
|
|
4611
|
-
if (!_FaustPolyDspGenerator.gWorkletProcessors.has(context))
|
|
5639
|
+
if (!_FaustPolyDspGenerator.gWorkletProcessors.has(context))
|
|
5640
|
+
_FaustPolyDspGenerator.gWorkletProcessors.set(
|
|
5641
|
+
context,
|
|
5642
|
+
/* @__PURE__ */ new Set()
|
|
5643
|
+
);
|
|
4612
5644
|
if (!((_a = _FaustPolyDspGenerator.gWorkletProcessors.get(context)) == null ? void 0 : _a.has(processorName))) {
|
|
4613
5645
|
try {
|
|
4614
5646
|
const processorCode = `
|
|
@@ -4651,19 +5683,34 @@ const dependencies = {
|
|
|
4651
5683
|
// Generate the actual AudioWorkletProcessor code
|
|
4652
5684
|
(${FaustAudioWorkletProcessor_default.toString()})(dependencies, faustData);
|
|
4653
5685
|
`;
|
|
4654
|
-
const url = URL.createObjectURL(
|
|
5686
|
+
const url = URL.createObjectURL(
|
|
5687
|
+
new Blob([processorCode], { type: "text/javascript" })
|
|
5688
|
+
);
|
|
4655
5689
|
await context.audioWorklet.addModule(url);
|
|
4656
5690
|
(_b = _FaustPolyDspGenerator.gWorkletProcessors.get(context)) == null ? void 0 : _b.add(processorName);
|
|
4657
5691
|
} catch (e) {
|
|
4658
5692
|
throw e;
|
|
4659
5693
|
}
|
|
4660
5694
|
}
|
|
4661
|
-
const node = new FaustPolyAudioWorkletNode(context, {
|
|
5695
|
+
const node = new FaustPolyAudioWorkletNode(context, {
|
|
5696
|
+
processorOptions: {
|
|
5697
|
+
name: processorName,
|
|
5698
|
+
voiceFactory,
|
|
5699
|
+
mixerModule,
|
|
5700
|
+
voices,
|
|
5701
|
+
sampleSize,
|
|
5702
|
+
effectFactory: effectFactory || void 0,
|
|
5703
|
+
...processorOptions
|
|
5704
|
+
}
|
|
5705
|
+
});
|
|
4662
5706
|
return node;
|
|
4663
5707
|
}
|
|
4664
5708
|
}
|
|
4665
5709
|
async createAudioWorkletProcessor(name = this.name, voiceFactory = this.voiceFactory, effectFactory = this.effectFactory, processorName = ((voiceFactory == null ? void 0 : voiceFactory.shaKey) || "") + ((effectFactory == null ? void 0 : effectFactory.shaKey) || "") || `${name}_poly`) {
|
|
4666
|
-
if (!voiceFactory)
|
|
5710
|
+
if (!voiceFactory)
|
|
5711
|
+
throw new Error(
|
|
5712
|
+
"Code is not compiled, please define the factory or call `await this.compile()` first."
|
|
5713
|
+
);
|
|
4667
5714
|
const voiceMeta = JSON.parse(voiceFactory.json);
|
|
4668
5715
|
const effectMeta = effectFactory ? JSON.parse(effectFactory.json) : void 0;
|
|
4669
5716
|
const sampleSize = voiceMeta.compile_options.match("-double") ? 8 : 4;
|
|
@@ -4683,24 +5730,53 @@ const dependencies = {
|
|
|
4683
5730
|
poly: true,
|
|
4684
5731
|
effectMeta
|
|
4685
5732
|
};
|
|
4686
|
-
const Processor = FaustAudioWorkletProcessor_default(
|
|
5733
|
+
const Processor = FaustAudioWorkletProcessor_default(
|
|
5734
|
+
dependencies,
|
|
5735
|
+
faustData
|
|
5736
|
+
);
|
|
4687
5737
|
return Processor;
|
|
4688
5738
|
} catch (e) {
|
|
4689
5739
|
throw e;
|
|
4690
5740
|
}
|
|
4691
5741
|
}
|
|
4692
5742
|
async createOfflineProcessor(sampleRate, bufferSize, voices, voiceFactory = this.voiceFactory, mixerModule = this.mixerModule, effectFactory = this.effectFactory, context) {
|
|
4693
|
-
if (!voiceFactory)
|
|
5743
|
+
if (!voiceFactory)
|
|
5744
|
+
throw new Error(
|
|
5745
|
+
"Code is not compiled, please define the factory or call `await this.compile()` first."
|
|
5746
|
+
);
|
|
4694
5747
|
const voiceMeta = JSON.parse(voiceFactory.json);
|
|
4695
5748
|
const effectMeta = effectFactory ? JSON.parse(effectFactory.json) : void 0;
|
|
4696
|
-
const instance = await FaustWasmInstantiator_default.createAsyncPolyDSPInstance(
|
|
5749
|
+
const instance = await FaustWasmInstantiator_default.createAsyncPolyDSPInstance(
|
|
5750
|
+
voiceFactory,
|
|
5751
|
+
mixerModule,
|
|
5752
|
+
voices,
|
|
5753
|
+
effectFactory || void 0
|
|
5754
|
+
);
|
|
4697
5755
|
const sampleSize = voiceMeta.compile_options.match("-double") ? 8 : 4;
|
|
4698
5756
|
if (context) {
|
|
4699
|
-
voiceFactory.soundfiles = await SoundfileReader_default.loadSoundfiles(
|
|
4700
|
-
|
|
4701
|
-
|
|
4702
|
-
|
|
4703
|
-
|
|
5757
|
+
voiceFactory.soundfiles = await SoundfileReader_default.loadSoundfiles(
|
|
5758
|
+
voiceMeta,
|
|
5759
|
+
voiceFactory.soundfiles || {},
|
|
5760
|
+
context
|
|
5761
|
+
);
|
|
5762
|
+
if (effectFactory)
|
|
5763
|
+
effectFactory.soundfiles = await SoundfileReader_default.loadSoundfiles(
|
|
5764
|
+
effectMeta,
|
|
5765
|
+
effectFactory.soundfiles || {},
|
|
5766
|
+
context
|
|
5767
|
+
);
|
|
5768
|
+
}
|
|
5769
|
+
const soundfiles = {
|
|
5770
|
+
...effectFactory == null ? void 0 : effectFactory.soundfiles,
|
|
5771
|
+
...voiceFactory.soundfiles
|
|
5772
|
+
};
|
|
5773
|
+
const polyDsp = new FaustPolyWebAudioDsp(
|
|
5774
|
+
instance,
|
|
5775
|
+
sampleRate,
|
|
5776
|
+
sampleSize,
|
|
5777
|
+
bufferSize,
|
|
5778
|
+
soundfiles
|
|
5779
|
+
);
|
|
4704
5780
|
return new FaustPolyOfflineProcessor(polyDsp, bufferSize);
|
|
4705
5781
|
}
|
|
4706
5782
|
getMeta() {
|
|
@@ -4708,22 +5784,24 @@ const dependencies = {
|
|
|
4708
5784
|
const e = this.effectFactory ? JSON.parse(this.effectFactory.json) : null;
|
|
4709
5785
|
const r = { ...o };
|
|
4710
5786
|
if (e) {
|
|
4711
|
-
r.ui = [
|
|
4712
|
-
|
|
4713
|
-
|
|
4714
|
-
|
|
4715
|
-
|
|
4716
|
-
|
|
4717
|
-
|
|
4718
|
-
|
|
5787
|
+
r.ui = [
|
|
5788
|
+
{
|
|
5789
|
+
type: "tgroup",
|
|
5790
|
+
label: "Sequencer",
|
|
5791
|
+
items: [
|
|
5792
|
+
{ type: "vgroup", label: "Instrument", items: o.ui },
|
|
5793
|
+
{ type: "vgroup", label: "Effect", items: e.ui }
|
|
5794
|
+
]
|
|
5795
|
+
}
|
|
5796
|
+
];
|
|
4719
5797
|
} else {
|
|
4720
|
-
r.ui = [
|
|
4721
|
-
|
|
4722
|
-
|
|
4723
|
-
|
|
4724
|
-
{ type: "vgroup", label: "Voices", items: o.ui }
|
|
4725
|
-
|
|
4726
|
-
|
|
5798
|
+
r.ui = [
|
|
5799
|
+
{
|
|
5800
|
+
type: "tgroup",
|
|
5801
|
+
label: "Polyphonic",
|
|
5802
|
+
items: [{ type: "vgroup", label: "Voices", items: o.ui }]
|
|
5803
|
+
}
|
|
5804
|
+
];
|
|
4727
5805
|
}
|
|
4728
5806
|
return r;
|
|
4729
5807
|
}
|
|
@@ -4737,11 +5815,103 @@ const dependencies = {
|
|
|
4737
5815
|
// Set of all created WorkletProcessors, each of them has to be unique
|
|
4738
5816
|
_FaustPolyDspGenerator.gWorkletProcessors = /* @__PURE__ */ new Map();
|
|
4739
5817
|
var FaustPolyDspGenerator = _FaustPolyDspGenerator;
|
|
5818
|
+
var _FaustDspGenerator = class _FaustDspGenerator {
|
|
5819
|
+
// Analyze the metadata of a Faust JSON file and extract the [midi:on] and [nvoices:n] options
|
|
5820
|
+
extractMidiAndNvoices(jsonData) {
|
|
5821
|
+
const optionsMetadata = jsonData.meta.find((meta) => meta.options);
|
|
5822
|
+
if (optionsMetadata && optionsMetadata.options) {
|
|
5823
|
+
const options = optionsMetadata.options;
|
|
5824
|
+
const midiRegex = /\[midi:(on|off)\]/;
|
|
5825
|
+
const nvoicesRegex = /\[nvoices:(\d+)\]/;
|
|
5826
|
+
const midiMatch = options.match(midiRegex);
|
|
5827
|
+
const nvoicesMatch = options.match(nvoicesRegex);
|
|
5828
|
+
const midi = midiMatch ? midiMatch[1] === "on" : false;
|
|
5829
|
+
const nvoices = nvoicesMatch ? parseInt(nvoicesMatch[1], 10) : -1;
|
|
5830
|
+
return { midi, nvoices };
|
|
5831
|
+
} else {
|
|
5832
|
+
return { midi: false, nvoices: -1 };
|
|
5833
|
+
}
|
|
5834
|
+
}
|
|
5835
|
+
/**
|
|
5836
|
+
* Compile DSP code, inspect metadata for [nvoices:] (and optionally [midi:on]), and build either a mono
|
|
5837
|
+
* or poly WebAudio node (ScriptProcessor or AudioWorklet depending on `sp`). Compilation uses a shared,
|
|
5838
|
+
* lazily-created libfaust instance to avoid repeatedly instantiating the WASM compiler.
|
|
5839
|
+
*/
|
|
5840
|
+
async createFaustNode(context, name, code, sp, bufferSize) {
|
|
5841
|
+
const getCompiler = async () => {
|
|
5842
|
+
if (!_FaustDspGenerator.compilerPromise) {
|
|
5843
|
+
const baseURL = (typeof document !== "undefined" ? "src" in (document.currentScript || {}) ? document.currentScript.src : document.baseURI : void 0) || (typeof window !== "undefined" ? window.location.href : void 0);
|
|
5844
|
+
if (!baseURL)
|
|
5845
|
+
throw new Error("Cannot resolve libfaust-wasm location.");
|
|
5846
|
+
const jsURL = new URL(
|
|
5847
|
+
"../libfaust-wasm/libfaust-wasm.js",
|
|
5848
|
+
baseURL
|
|
5849
|
+
).href;
|
|
5850
|
+
const dataURL = jsURL.replace(/c?js$/, "data");
|
|
5851
|
+
const wasmURL = jsURL.replace(/c?js$/, "wasm");
|
|
5852
|
+
_FaustDspGenerator.compilerPromise = instantiateFaustModuleFromFile_default(
|
|
5853
|
+
jsURL,
|
|
5854
|
+
dataURL,
|
|
5855
|
+
wasmURL
|
|
5856
|
+
).then((module) => new FaustCompiler_default(new LibFaust_default(module)));
|
|
5857
|
+
}
|
|
5858
|
+
return _FaustDspGenerator.compilerPromise;
|
|
5859
|
+
};
|
|
5860
|
+
const args = "-ftz 2";
|
|
5861
|
+
try {
|
|
5862
|
+
const compiler = await getCompiler();
|
|
5863
|
+
const monoGenerator = new FaustMonoDspGenerator();
|
|
5864
|
+
const compiledMono = await monoGenerator.compile(
|
|
5865
|
+
compiler,
|
|
5866
|
+
name,
|
|
5867
|
+
code,
|
|
5868
|
+
args
|
|
5869
|
+
);
|
|
5870
|
+
if (!compiledMono) return null;
|
|
5871
|
+
const { nvoices } = this.extractMidiAndNvoices(
|
|
5872
|
+
monoGenerator.getMeta()
|
|
5873
|
+
);
|
|
5874
|
+
if (nvoices > 0) {
|
|
5875
|
+
const polyGenerator = new FaustPolyDspGenerator();
|
|
5876
|
+
const compiledPoly = await polyGenerator.compile(
|
|
5877
|
+
compiler,
|
|
5878
|
+
name,
|
|
5879
|
+
code,
|
|
5880
|
+
args
|
|
5881
|
+
);
|
|
5882
|
+
if (!compiledPoly) return null;
|
|
5883
|
+
return await polyGenerator.createNode(
|
|
5884
|
+
context,
|
|
5885
|
+
nvoices,
|
|
5886
|
+
name,
|
|
5887
|
+
void 0,
|
|
5888
|
+
void 0,
|
|
5889
|
+
void 0,
|
|
5890
|
+
sp,
|
|
5891
|
+
bufferSize
|
|
5892
|
+
);
|
|
5893
|
+
}
|
|
5894
|
+
return await monoGenerator.createNode(
|
|
5895
|
+
context,
|
|
5896
|
+
name,
|
|
5897
|
+
void 0,
|
|
5898
|
+
sp,
|
|
5899
|
+
bufferSize
|
|
5900
|
+
);
|
|
5901
|
+
} catch (e) {
|
|
5902
|
+
console.error(e);
|
|
5903
|
+
return null;
|
|
5904
|
+
}
|
|
5905
|
+
}
|
|
5906
|
+
};
|
|
5907
|
+
_FaustDspGenerator.compilerPromise = null;
|
|
5908
|
+
var FaustDspGenerator = _FaustDspGenerator;
|
|
4740
5909
|
export {
|
|
4741
5910
|
FaustAudioWorkletNode,
|
|
4742
5911
|
FaustBaseWebAudioDsp,
|
|
4743
5912
|
FaustCmajor_default as FaustCmajor,
|
|
4744
5913
|
FaustCompiler_default as FaustCompiler,
|
|
5914
|
+
FaustDspGenerator,
|
|
4745
5915
|
FaustDspInstance,
|
|
4746
5916
|
FaustMonoAudioWorkletNode,
|
|
4747
5917
|
FaustMonoDspGenerator,
|