@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
|
@@ -1,13 +1,28 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
import {
|
|
2
|
+
OutputParamHandler,
|
|
3
|
+
ComputeHandler,
|
|
4
|
+
PlotHandler,
|
|
5
|
+
UIHandler,
|
|
6
|
+
MetadataHandler,
|
|
7
|
+
FaustBaseWebAudioDsp,
|
|
8
|
+
IFaustMonoWebAudioDsp,
|
|
9
|
+
IFaustPolyWebAudioDsp
|
|
10
|
+
} from './FaustWebAudioDsp';
|
|
11
|
+
import type { FaustAudioWorkletNodeOptions } from './FaustAudioWorkletProcessor';
|
|
12
|
+
import type {
|
|
13
|
+
LooseFaustDspFactory,
|
|
14
|
+
FaustDspMeta,
|
|
15
|
+
FaustUIInputItem,
|
|
16
|
+
FaustUIItem
|
|
17
|
+
} from './types';
|
|
18
|
+
import { FaustAudioWorkletNodeCommunicator } from './FaustAudioWorkletCommunicator';
|
|
5
19
|
|
|
6
20
|
/**
|
|
7
21
|
* Base class for Monophonic and Polyphonic AudioWorkletNode
|
|
8
22
|
*/
|
|
9
|
-
export class FaustAudioWorkletNode<
|
|
10
|
-
|
|
23
|
+
export class FaustAudioWorkletNode<
|
|
24
|
+
Poly extends boolean = false
|
|
25
|
+
> extends (globalThis.AudioWorkletNode || null) {
|
|
11
26
|
protected fJSONDsp: FaustDspMeta;
|
|
12
27
|
protected fJSON: string;
|
|
13
28
|
protected fInputsItems: string[];
|
|
@@ -20,8 +35,12 @@ export class FaustAudioWorkletNode<Poly extends boolean = false> extends (global
|
|
|
20
35
|
#hasAccInput = false;
|
|
21
36
|
#hasGyrInput = false;
|
|
22
37
|
|
|
23
|
-
constructor(
|
|
24
|
-
|
|
38
|
+
constructor(
|
|
39
|
+
context: BaseAudioContext,
|
|
40
|
+
name: string,
|
|
41
|
+
factory: LooseFaustDspFactory,
|
|
42
|
+
options: Partial<FaustAudioWorkletNodeOptions<Poly>> = {}
|
|
43
|
+
) {
|
|
25
44
|
// Create JSON object
|
|
26
45
|
const JSONObj: FaustDspMeta = JSON.parse(factory.json);
|
|
27
46
|
|
|
@@ -31,8 +50,8 @@ export class FaustAudioWorkletNode<Poly extends boolean = false> extends (global
|
|
|
31
50
|
numberOfOutputs: JSONObj.outputs > 0 ? 1 : 0,
|
|
32
51
|
channelCount: Math.max(1, JSONObj.inputs),
|
|
33
52
|
outputChannelCount: [JSONObj.outputs],
|
|
34
|
-
channelCountMode:
|
|
35
|
-
channelInterpretation:
|
|
53
|
+
channelCountMode: 'explicit',
|
|
54
|
+
channelInterpretation: 'speakers',
|
|
36
55
|
processorOptions: options.processorOptions,
|
|
37
56
|
...options
|
|
38
57
|
});
|
|
@@ -47,7 +66,13 @@ export class FaustAudioWorkletNode<Poly extends boolean = false> extends (global
|
|
|
47
66
|
// Parse UI
|
|
48
67
|
this.fInputsItems = [];
|
|
49
68
|
this.fUICallback = (item: FaustUIItem) => {
|
|
50
|
-
if (
|
|
69
|
+
if (
|
|
70
|
+
item.type === 'vslider' ||
|
|
71
|
+
item.type === 'hslider' ||
|
|
72
|
+
item.type === 'button' ||
|
|
73
|
+
item.type === 'checkbox' ||
|
|
74
|
+
item.type === 'nentry'
|
|
75
|
+
) {
|
|
51
76
|
// Keep inputs adresses
|
|
52
77
|
this.fInputsItems.push(item.address);
|
|
53
78
|
this.fDescriptor.push(item);
|
|
@@ -58,34 +83,40 @@ export class FaustAudioWorkletNode<Poly extends boolean = false> extends (global
|
|
|
58
83
|
if (gyr) this.#hasGyrInput = true;
|
|
59
84
|
});
|
|
60
85
|
}
|
|
61
|
-
}
|
|
86
|
+
};
|
|
62
87
|
|
|
63
88
|
FaustBaseWebAudioDsp.parseUI(this.fJSONDsp.ui, this.fUICallback);
|
|
64
89
|
|
|
65
90
|
this.fCommunicator = new FaustAudioWorkletNodeCommunicator(this.port);
|
|
66
91
|
|
|
67
92
|
// Patch it with additional functions
|
|
68
|
-
this.port.addEventListener(
|
|
93
|
+
this.port.addEventListener('message', this.handleMessageAux);
|
|
69
94
|
this.port.start();
|
|
70
95
|
}
|
|
71
96
|
|
|
72
97
|
protected handleMessageAux = (e: MessageEvent) => {
|
|
73
|
-
if (e.data.type ===
|
|
98
|
+
if (e.data.type === 'param' && this.fOutputHandler) {
|
|
74
99
|
this.fOutputHandler(e.data.path, e.data.value);
|
|
75
|
-
} else if (e.data.type ===
|
|
100
|
+
} else if (e.data.type === 'plot' && this.fPlotHandler) {
|
|
76
101
|
this.fPlotHandler(e.data.value, e.data.index, e.data.events);
|
|
77
102
|
}
|
|
78
103
|
};
|
|
79
104
|
|
|
80
105
|
// Accelerometer and gyroscope handlers
|
|
81
|
-
private handleDeviceMotion = ({
|
|
106
|
+
private handleDeviceMotion = ({
|
|
107
|
+
accelerationIncludingGravity
|
|
108
|
+
}: DeviceMotionEvent) => {
|
|
82
109
|
const isAndroid: boolean = /Android/i.test(navigator.userAgent);
|
|
83
110
|
if (!accelerationIncludingGravity) return;
|
|
84
111
|
const { x, y, z } = accelerationIncludingGravity;
|
|
85
112
|
this.propagateAcc({ x, y, z }, isAndroid);
|
|
86
113
|
};
|
|
87
114
|
|
|
88
|
-
private handleDeviceOrientation = ({
|
|
115
|
+
private handleDeviceOrientation = ({
|
|
116
|
+
alpha,
|
|
117
|
+
beta,
|
|
118
|
+
gamma
|
|
119
|
+
}: DeviceOrientationEvent) => {
|
|
89
120
|
this.propagateGyr({ alpha, beta, gamma });
|
|
90
121
|
};
|
|
91
122
|
|
|
@@ -96,29 +127,45 @@ export class FaustAudioWorkletNode<Poly extends boolean = false> extends (global
|
|
|
96
127
|
if (this.hasAccInput) {
|
|
97
128
|
if (window.DeviceMotionEvent) {
|
|
98
129
|
// iOS 13+ requires a user gesture to enable DeviceMotionEvent, to be done in the main thread
|
|
99
|
-
window.addEventListener(
|
|
130
|
+
window.addEventListener(
|
|
131
|
+
'devicemotion',
|
|
132
|
+
this.handleDeviceMotion,
|
|
133
|
+
true
|
|
134
|
+
);
|
|
100
135
|
} else {
|
|
101
136
|
// Browser doesn't support DeviceMotionEvent
|
|
102
|
-
console.log(
|
|
137
|
+
console.log('Cannot set the accelerometer handler.');
|
|
103
138
|
}
|
|
104
139
|
}
|
|
105
140
|
if (this.hasGyrInput) {
|
|
106
141
|
if (window.DeviceMotionEvent) {
|
|
107
142
|
// iOS 13+ requires a user gesture to enable DeviceMotionEvent, to be done in the main thread
|
|
108
|
-
window.addEventListener(
|
|
143
|
+
window.addEventListener(
|
|
144
|
+
'deviceorientation',
|
|
145
|
+
this.handleDeviceOrientation,
|
|
146
|
+
true
|
|
147
|
+
);
|
|
109
148
|
} else {
|
|
110
149
|
// Browser doesn't support DeviceMotionEvent
|
|
111
|
-
console.log(
|
|
150
|
+
console.log('Cannot set the gyroscope handler.');
|
|
112
151
|
}
|
|
113
152
|
}
|
|
114
153
|
}
|
|
115
154
|
|
|
116
155
|
stopSensors() {
|
|
117
156
|
if (this.hasAccInput) {
|
|
118
|
-
window.removeEventListener(
|
|
157
|
+
window.removeEventListener(
|
|
158
|
+
'devicemotion',
|
|
159
|
+
this.handleDeviceMotion,
|
|
160
|
+
true
|
|
161
|
+
);
|
|
119
162
|
}
|
|
120
163
|
if (this.hasGyrInput) {
|
|
121
|
-
window.removeEventListener(
|
|
164
|
+
window.removeEventListener(
|
|
165
|
+
'deviceorientation',
|
|
166
|
+
this.handleDeviceOrientation,
|
|
167
|
+
true
|
|
168
|
+
);
|
|
122
169
|
}
|
|
123
170
|
}
|
|
124
171
|
|
|
@@ -132,7 +179,7 @@ export class FaustAudioWorkletNode<Poly extends boolean = false> extends (global
|
|
|
132
179
|
if (this.fOutputHandler) {
|
|
133
180
|
this.fOutputHandler(path, value);
|
|
134
181
|
} else {
|
|
135
|
-
console.warn(
|
|
182
|
+
console.warn('No OutputParamHandler set for this Faust node.');
|
|
136
183
|
}
|
|
137
184
|
}
|
|
138
185
|
|
|
@@ -147,9 +194,9 @@ export class FaustAudioWorkletNode<Poly extends boolean = false> extends (global
|
|
|
147
194
|
this.fPlotHandler = handler;
|
|
148
195
|
// Set PlotHandler on processor side
|
|
149
196
|
if (this.fPlotHandler) {
|
|
150
|
-
this.port.postMessage({ type:
|
|
197
|
+
this.port.postMessage({ type: 'setPlotHandler', data: true });
|
|
151
198
|
} else {
|
|
152
|
-
this.port.postMessage({ type:
|
|
199
|
+
this.port.postMessage({ type: 'setPlotHandler', data: false });
|
|
153
200
|
}
|
|
154
201
|
}
|
|
155
202
|
getPlotHandler(): PlotHandler | null {
|
|
@@ -157,7 +204,7 @@ export class FaustAudioWorkletNode<Poly extends boolean = false> extends (global
|
|
|
157
204
|
}
|
|
158
205
|
|
|
159
206
|
setupWamEventHandler() {
|
|
160
|
-
this.port.postMessage({ type:
|
|
207
|
+
this.port.postMessage({ type: 'setupWamEventHandler' });
|
|
161
208
|
}
|
|
162
209
|
|
|
163
210
|
getNumInputs() {
|
|
@@ -174,7 +221,9 @@ export class FaustAudioWorkletNode<Poly extends boolean = false> extends (global
|
|
|
174
221
|
|
|
175
222
|
metadata(handler: MetadataHandler) {
|
|
176
223
|
if (this.fJSONDsp.meta) {
|
|
177
|
-
this.fJSONDsp.meta.forEach(
|
|
224
|
+
this.fJSONDsp.meta.forEach((meta) =>
|
|
225
|
+
handler(Object.keys(meta)[0], meta[Object.keys(meta)[0]])
|
|
226
|
+
);
|
|
178
227
|
}
|
|
179
228
|
}
|
|
180
229
|
|
|
@@ -185,74 +234,99 @@ export class FaustAudioWorkletNode<Poly extends boolean = false> extends (global
|
|
|
185
234
|
const data2 = data[2];
|
|
186
235
|
if (cmd === 11) this.ctrlChange(channel, data1, data2);
|
|
187
236
|
else if (cmd === 14) this.pitchWheel(channel, data2 * 128.0 + data1);
|
|
188
|
-
if (cmd === 8 || (cmd === 9 && data2 === 0))
|
|
237
|
+
if (cmd === 8 || (cmd === 9 && data2 === 0))
|
|
238
|
+
this.keyOff(channel, data1, data2);
|
|
189
239
|
else if (cmd === 9) this.keyOn(channel, data1, data2);
|
|
190
|
-
else this.port.postMessage({ type:
|
|
240
|
+
else this.port.postMessage({ type: 'midi', data: data });
|
|
191
241
|
}
|
|
192
242
|
|
|
193
243
|
ctrlChange(channel: number, ctrl: number, value: number) {
|
|
194
|
-
const e = { type:
|
|
244
|
+
const e = { type: 'ctrlChange', data: [channel, ctrl, value] };
|
|
195
245
|
this.port.postMessage(e);
|
|
196
246
|
}
|
|
197
247
|
pitchWheel(channel: number, wheel: number) {
|
|
198
|
-
const e = { type:
|
|
248
|
+
const e = { type: 'pitchWheel', data: [channel, wheel] };
|
|
199
249
|
this.port.postMessage(e);
|
|
200
250
|
}
|
|
201
251
|
keyOn(channel: number, pitch: number, velocity: number) {
|
|
202
|
-
const e = { type:
|
|
252
|
+
const e = { type: 'keyOn', data: [channel, pitch, velocity] };
|
|
203
253
|
this.port.postMessage(e);
|
|
204
254
|
}
|
|
205
255
|
keyOff(channel: number, pitch: number, velocity: number) {
|
|
206
|
-
const e = { type:
|
|
256
|
+
const e = { type: 'keyOff', data: [channel, pitch, velocity] };
|
|
207
257
|
this.port.postMessage(e);
|
|
208
258
|
}
|
|
209
259
|
|
|
210
|
-
get hasAccInput() {
|
|
260
|
+
get hasAccInput() {
|
|
261
|
+
return this.#hasAccInput;
|
|
262
|
+
}
|
|
211
263
|
|
|
212
|
-
propagateAcc(
|
|
264
|
+
propagateAcc(
|
|
265
|
+
accelerationIncludingGravity: NonNullable<
|
|
266
|
+
DeviceMotionEvent['accelerationIncludingGravity']
|
|
267
|
+
>,
|
|
268
|
+
invert: boolean = false
|
|
269
|
+
) {
|
|
213
270
|
if (!accelerationIncludingGravity) return;
|
|
214
271
|
const { x, y, z } = accelerationIncludingGravity;
|
|
215
272
|
this.fCommunicator.setAcc({ x: x!, y: y!, z: z! }, invert);
|
|
216
273
|
}
|
|
217
274
|
|
|
218
|
-
get hasGyrInput() {
|
|
275
|
+
get hasGyrInput() {
|
|
276
|
+
return this.#hasGyrInput;
|
|
277
|
+
}
|
|
219
278
|
|
|
220
|
-
propagateGyr(
|
|
279
|
+
propagateGyr(
|
|
280
|
+
event: Pick<DeviceOrientationEvent, 'alpha' | 'beta' | 'gamma'>
|
|
281
|
+
) {
|
|
221
282
|
if (!event) return;
|
|
222
283
|
const { alpha, beta, gamma } = event;
|
|
223
|
-
this.fCommunicator.setGyr({
|
|
284
|
+
this.fCommunicator.setGyr({
|
|
285
|
+
alpha: alpha!,
|
|
286
|
+
beta: beta!,
|
|
287
|
+
gamma: gamma!
|
|
288
|
+
});
|
|
224
289
|
}
|
|
225
290
|
|
|
226
291
|
setParamValue(path: string, value: number) {
|
|
227
|
-
const e = { type:
|
|
292
|
+
const e = { type: 'param', data: { path, value } };
|
|
228
293
|
this.port.postMessage(e);
|
|
229
294
|
// Set value on AudioParam (but this is not used on Processor side for now)
|
|
230
295
|
const param = this.parameters.get(path);
|
|
231
296
|
if (param) param.setValueAtTime(value, this.context.currentTime);
|
|
232
|
-
|
|
233
297
|
}
|
|
234
298
|
getParamValue(path: string) {
|
|
235
299
|
// Get value of AudioParam
|
|
236
300
|
const param = this.parameters.get(path);
|
|
237
|
-
return
|
|
301
|
+
return param ? param.value : 0;
|
|
238
302
|
}
|
|
239
303
|
|
|
240
|
-
getParams() {
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
304
|
+
getParams() {
|
|
305
|
+
return this.fInputsItems;
|
|
306
|
+
}
|
|
307
|
+
getMeta() {
|
|
308
|
+
return this.fJSONDsp;
|
|
309
|
+
}
|
|
310
|
+
getJSON() {
|
|
311
|
+
return JSON.stringify(this.getMeta());
|
|
312
|
+
}
|
|
313
|
+
getUI() {
|
|
314
|
+
return this.fJSONDsp.ui;
|
|
315
|
+
}
|
|
316
|
+
getDescriptors() {
|
|
317
|
+
return this.fDescriptor;
|
|
318
|
+
}
|
|
245
319
|
|
|
246
320
|
start() {
|
|
247
|
-
this.port.postMessage({ type:
|
|
321
|
+
this.port.postMessage({ type: 'start' });
|
|
248
322
|
}
|
|
249
323
|
|
|
250
324
|
stop() {
|
|
251
|
-
this.port.postMessage({ type:
|
|
325
|
+
this.port.postMessage({ type: 'stop' });
|
|
252
326
|
}
|
|
253
327
|
|
|
254
328
|
destroy() {
|
|
255
|
-
this.port.postMessage({ type:
|
|
329
|
+
this.port.postMessage({ type: 'destroy' });
|
|
256
330
|
this.port.close();
|
|
257
331
|
}
|
|
258
332
|
}
|
|
@@ -260,32 +334,48 @@ export class FaustAudioWorkletNode<Poly extends boolean = false> extends (global
|
|
|
260
334
|
/**
|
|
261
335
|
* Monophonic AudioWorkletNode
|
|
262
336
|
*/
|
|
263
|
-
export class FaustMonoAudioWorkletNode
|
|
264
|
-
|
|
337
|
+
export class FaustMonoAudioWorkletNode
|
|
338
|
+
extends FaustAudioWorkletNode<false>
|
|
339
|
+
implements IFaustMonoWebAudioDsp
|
|
340
|
+
{
|
|
265
341
|
onprocessorerror = (e: Event) => {
|
|
266
342
|
// console.error("Error from " + this.fJSONDsp.name + " FaustMonoAudioWorkletNode");
|
|
267
343
|
throw e;
|
|
268
|
-
}
|
|
344
|
+
};
|
|
269
345
|
|
|
270
|
-
constructor(
|
|
271
|
-
|
|
346
|
+
constructor(
|
|
347
|
+
context: BaseAudioContext,
|
|
348
|
+
options: Partial<FaustAudioWorkletNodeOptions<false>> &
|
|
349
|
+
Pick<FaustAudioWorkletNodeOptions<false>, 'processorOptions'>
|
|
350
|
+
) {
|
|
351
|
+
super(
|
|
352
|
+
context,
|
|
353
|
+
options.processorOptions.name,
|
|
354
|
+
options.processorOptions.factory,
|
|
355
|
+
options
|
|
356
|
+
);
|
|
272
357
|
}
|
|
273
358
|
}
|
|
274
359
|
|
|
275
360
|
/**
|
|
276
361
|
* Polyphonic AudioWorkletNode
|
|
277
362
|
*/
|
|
278
|
-
export class FaustPolyAudioWorkletNode
|
|
279
|
-
|
|
363
|
+
export class FaustPolyAudioWorkletNode
|
|
364
|
+
extends FaustAudioWorkletNode<true>
|
|
365
|
+
implements IFaustPolyWebAudioDsp
|
|
366
|
+
{
|
|
280
367
|
private fJSONEffect: FaustDspMeta | null;
|
|
281
368
|
|
|
282
369
|
onprocessorerror = (e: Event) => {
|
|
283
370
|
// console.error("Error from " + this.fJSONDsp.name + " FaustPolyAudioWorkletNode");
|
|
284
371
|
throw e;
|
|
285
|
-
}
|
|
286
|
-
|
|
287
|
-
constructor(context: BaseAudioContext, options: Partial<FaustAudioWorkletNodeOptions<true>> & Pick<FaustAudioWorkletNodeOptions<true>, "processorOptions">) {
|
|
372
|
+
};
|
|
288
373
|
|
|
374
|
+
constructor(
|
|
375
|
+
context: BaseAudioContext,
|
|
376
|
+
options: Partial<FaustAudioWorkletNodeOptions<true>> &
|
|
377
|
+
Pick<FaustAudioWorkletNodeOptions<true>, 'processorOptions'>
|
|
378
|
+
) {
|
|
289
379
|
super(
|
|
290
380
|
context,
|
|
291
381
|
options.processorOptions.name,
|
|
@@ -293,7 +383,9 @@ export class FaustPolyAudioWorkletNode extends FaustAudioWorkletNode<true> imple
|
|
|
293
383
|
options
|
|
294
384
|
);
|
|
295
385
|
|
|
296
|
-
this.fJSONEffect = options.processorOptions.effectFactory
|
|
386
|
+
this.fJSONEffect = options.processorOptions.effectFactory
|
|
387
|
+
? JSON.parse(options.processorOptions.effectFactory.json)
|
|
388
|
+
: null;
|
|
297
389
|
|
|
298
390
|
if (this.fJSONEffect) {
|
|
299
391
|
FaustBaseWebAudioDsp.parseUI(this.fJSONEffect.ui, this.fUICallback);
|
|
@@ -302,17 +394,17 @@ export class FaustPolyAudioWorkletNode extends FaustAudioWorkletNode<true> imple
|
|
|
302
394
|
|
|
303
395
|
// Public API
|
|
304
396
|
keyOn(channel: number, pitch: number, velocity: number) {
|
|
305
|
-
const e = { type:
|
|
397
|
+
const e = { type: 'keyOn', data: [channel, pitch, velocity] };
|
|
306
398
|
this.port.postMessage(e);
|
|
307
399
|
}
|
|
308
400
|
|
|
309
401
|
keyOff(channel: number, pitch: number, velocity: number) {
|
|
310
|
-
const e = { type:
|
|
402
|
+
const e = { type: 'keyOff', data: [channel, pitch, velocity] };
|
|
311
403
|
this.port.postMessage(e);
|
|
312
404
|
}
|
|
313
405
|
|
|
314
406
|
allNotesOff(hard: boolean) {
|
|
315
|
-
const e = { type:
|
|
407
|
+
const e = { type: 'ctrlChange', data: [0, 123, 0] };
|
|
316
408
|
this.port.postMessage(e);
|
|
317
409
|
}
|
|
318
410
|
|
|
@@ -321,18 +413,24 @@ export class FaustPolyAudioWorkletNode extends FaustAudioWorkletNode<true> imple
|
|
|
321
413
|
const e = this.fJSONEffect;
|
|
322
414
|
const r = { ...o };
|
|
323
415
|
if (e) {
|
|
324
|
-
r.ui = [
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
416
|
+
r.ui = [
|
|
417
|
+
{
|
|
418
|
+
type: 'tgroup',
|
|
419
|
+
label: 'Sequencer',
|
|
420
|
+
items: [
|
|
421
|
+
{ type: 'vgroup', label: 'Instrument', items: o.ui },
|
|
422
|
+
{ type: 'vgroup', label: 'Effect', items: e.ui }
|
|
423
|
+
]
|
|
424
|
+
}
|
|
425
|
+
];
|
|
330
426
|
} else {
|
|
331
|
-
r.ui = [
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
427
|
+
r.ui = [
|
|
428
|
+
{
|
|
429
|
+
type: 'tgroup',
|
|
430
|
+
label: 'Polyphonic',
|
|
431
|
+
items: [{ type: 'vgroup', label: 'Voices', items: o.ui }]
|
|
432
|
+
}
|
|
433
|
+
];
|
|
336
434
|
}
|
|
337
435
|
return r as FaustDspMeta;
|
|
338
436
|
}
|