@grame/faustwasm 0.7.9 → 0.8.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.
Files changed (34) hide show
  1. package/README.md +2 -2
  2. package/assets/standalone/faustwasm/index.d.ts +76 -9
  3. package/assets/standalone/faustwasm/index.js +270 -77
  4. package/assets/standalone/faustwasm/index.js.map +4 -4
  5. package/assets/standalone/index-pwa.js +7 -8
  6. package/assets/standalone/index-template.js +2 -2
  7. package/assets/standalone/index.js +59 -61
  8. package/assets/standalone/service-worker.js +47 -8
  9. package/dist/cjs/index.d.ts +76 -9
  10. package/dist/cjs/index.js +270 -77
  11. package/dist/cjs/index.js.map +4 -4
  12. package/dist/cjs-bundle/index.d.ts +76 -9
  13. package/dist/cjs-bundle/index.js +271 -78
  14. package/dist/cjs-bundle/index.js.map +4 -4
  15. package/dist/esm/index.d.ts +76 -9
  16. package/dist/esm/index.js +270 -77
  17. package/dist/esm/index.js.map +4 -4
  18. package/dist/esm-bundle/index.d.ts +76 -9
  19. package/dist/esm-bundle/index.js +271 -78
  20. package/dist/esm-bundle/index.js.map +4 -4
  21. package/libfaust-wasm/libfaust-wasm.wasm +0 -0
  22. package/package.json +1 -1
  23. package/src/FaustAudioWorkletCommunicator.ts +143 -0
  24. package/src/FaustAudioWorkletNode.ts +23 -12
  25. package/src/FaustAudioWorkletProcessor.ts +34 -15
  26. package/src/FaustDspGenerator.ts +20 -2
  27. package/src/FaustFFTAudioWorkletProcessor.ts +31 -2
  28. package/src/FaustOfflineProcessor.ts +6 -0
  29. package/src/FaustScriptProcessorNode.ts +4 -1
  30. package/src/FaustWebAudioDsp.ts +38 -10
  31. package/test/faustlive-wasm/faustwasm/index.d.ts +76 -9
  32. package/test/faustlive-wasm/faustwasm/index.js +270 -77
  33. package/test/faustlive-wasm/faustwasm/index.js.map +4 -4
  34. package/assets/standalone/coi-serviceworker.js +0 -146
package/README.md CHANGED
@@ -6,7 +6,7 @@ The library offers functionality for compiling Faust DSP code into WebAssembly,
6
6
 
7
7
  Synthesizer and effect mono nodes, as well as [polyphonic](https://faustdoc.grame.fr/manual/midi/#midi-polyphony-support) poly nodes can be created. MIDI support is activated as soon as [MIDI metadata](https://faustdoc.grame.fr/manual/midi/#configuring-midi-in-faust) are used in the DSP code for mono nodes, and always in polyphonic mode.
8
8
 
9
- [Sensors](https://faustdoc.grame.fr/manual/syntax/#sensors-control-metadatas) (accelerometer and gyroscope) are supported, as well as the [Progressive Web Application](https://en.wikipedia.org/wiki/Progressive_web_app) model.
9
+ [Sensors](https://faustdoc.grame.fr/manual/syntax/#sensors-control-metadatas) (accelerometer and gyroscope) metadata are supported, as well as the [Progressive Web Application](https://en.wikipedia.org/wiki/Progressive_web_app) model.
10
10
 
11
11
  ## Usage
12
12
 
@@ -309,7 +309,7 @@ This level takes a Faust Wasm instance to build an audio node. [AudioWorklet](ht
309
309
 
310
310
  **Warning**: AudioWorklet is a recent technology and may not be supported by all the browsers. Check the [compatibility](https://developer.mozilla.org/fr/docs/Web/API/AudioWorklet) chart.
311
311
 
312
- The audio node API documentation can be [accessed here](https://github.com/search?q=repo%3Agrame-cncm%2Ffaustwasm%20IFaustBaseWebAudioDsp&type=code).
312
+ The base audio node API documentation is documented in the [IFaustBaseWebAudioDsp](https://github.com/search?q=repo%3Agrame-cncm%2Ffaustwasm%20IFaustBaseWebAudioDsp&type=code) interface. The [IFaustPolyWebAudioDsp](https://github.com/search?q=repo%3Agrame-cncm%2Ffaustwasm%20IFaustPolyWebAudioDsp&type=code) interface documents the polyphonic extension.
313
313
 
314
314
  Note that ScriptProcessor is marked as [deprecated](https://developer.mozilla.org/en-US/docs/Web/API/ScriptProcessorNode) but it's the only audio architecture available in older Safari versions. Both monophonic (generators, effects...) or polyphonic (instruments) nodes can be created. It is described in `FaustScriptProcessorNode.ts` file.
315
315
 
@@ -230,6 +230,49 @@ interface AudioData$1 {
230
230
  * @param wasmFile path to `libfaust-wasm.wasm`
231
231
  */
232
232
  export declare const instantiateFaustModuleFromFile: (jsFile: string, dataFile?: string, wasmFile?: string) => Promise<FaustModule>;
233
+ declare class FaustAudioWorkletCommunicator {
234
+ protected readonly port: MessagePort;
235
+ protected readonly supportSharedArrayBuffer: boolean;
236
+ protected readonly byteLength: number;
237
+ protected uin8Invert: Uint8ClampedArray;
238
+ protected uin8NewAccData: Uint8ClampedArray;
239
+ protected uin8NewGyrData: Uint8ClampedArray;
240
+ protected f32Acc: Float32Array;
241
+ protected f32Gyr: Float32Array;
242
+ constructor(port: MessagePort);
243
+ initializeBuffer(ab: SharedArrayBuffer | ArrayBuffer): void;
244
+ setNewAccDataAvailable(value: boolean): void;
245
+ getNewAccDataAvailable(): boolean;
246
+ setNewGyrDataAvailable(value: boolean): void;
247
+ getNewGyrDataAvailable(): boolean;
248
+ setAcc({ x, y, z }: {
249
+ x: number;
250
+ y: number;
251
+ z: number;
252
+ }, invert?: boolean): void;
253
+ getAcc(): {
254
+ x: number;
255
+ y: number;
256
+ z: number;
257
+ invert: boolean;
258
+ } | undefined;
259
+ setGyr({ alpha, beta, gamma }: {
260
+ alpha: number;
261
+ beta: number;
262
+ gamma: number;
263
+ }): void;
264
+ getGyr(): {
265
+ alpha: number;
266
+ beta: number;
267
+ gamma: number;
268
+ } | undefined;
269
+ }
270
+ declare class FaustAudioWorkletNodeCommunicator extends FaustAudioWorkletCommunicator {
271
+ constructor(port: MessagePort);
272
+ }
273
+ declare class FaustAudioWorkletProcessorCommunicator extends FaustAudioWorkletCommunicator {
274
+ constructor(port: MessagePort);
275
+ }
233
276
  /**
234
277
  * The Faust wasm instance interface.
235
278
  */
@@ -620,6 +663,29 @@ export interface IFaustBaseWebAudioDsp {
620
663
  * @return the DSP JSON description
621
664
  */
622
665
  getJSON(): string;
666
+ /**
667
+ * Start accelerometer and gyroscope handlers.
668
+ */
669
+ startSensors(): void;
670
+ /**
671
+ * Stop accelerometer and gyroscope handlers.
672
+ */
673
+ stopSensors(): void;
674
+ /** Indicating if the DSP handles the accelerometer */
675
+ readonly hasAccInput: boolean;
676
+ /**
677
+ * Accelerometer handling.
678
+ * accelerationIncludingGravity: DeviceMotionEvent["accelerationIncludingGravity"]
679
+ * invert: boolean
680
+ */
681
+ propagateAcc(accelerationIncludingGravity: NonNullable<DeviceMotionEvent["accelerationIncludingGravity"]>, invert: boolean): void;
682
+ /** Indicating if the DSP handles the gyroscope */
683
+ readonly hasGyrInput: boolean;
684
+ /**
685
+ * Gyroscope handling.
686
+ * event: Pick<DeviceOrientationEvent, "alpha" | "beta" | "gamma">
687
+ */
688
+ propagateGyr(event: Pick<DeviceOrientationEvent, "alpha" | "beta" | "gamma">): void;
623
689
  /**
624
690
  * Start the DSP audio processing.
625
691
  */
@@ -632,14 +698,6 @@ export interface IFaustBaseWebAudioDsp {
632
698
  * Destroy the DSP.
633
699
  */
634
700
  destroy(): void;
635
- /** Indicating if the DSP handles the accelerometer */
636
- readonly hasAccInput: boolean;
637
- /** Accelerometer handling */
638
- propagateAcc(accelerationIncludingGravity: NonNullable<DeviceMotionEvent["accelerationIncludingGravity"]>, invert: boolean): void;
639
- /** Indicating if the DSP handles the gyroscope */
640
- readonly hasGyrInput: boolean;
641
- /** Gyroscope handling */
642
- propagateGyr(event: Pick<DeviceOrientationEvent, "alpha" | "beta" | "gamma">): void;
643
701
  }
644
702
  export interface IFaustMonoWebAudioDsp extends IFaustBaseWebAudioDsp {
645
703
  }
@@ -780,6 +838,8 @@ export declare class FaustBaseWebAudioDsp implements IFaustBaseWebAudioDsp {
780
838
  start(): void;
781
839
  stop(): void;
782
840
  destroy(): void;
841
+ startSensors(): void;
842
+ stopSensors(): void;
783
843
  }
784
844
  export declare class FaustMonoWebAudioDsp extends FaustBaseWebAudioDsp implements IFaustMonoWebAudioDsp {
785
845
  private fInstance;
@@ -876,6 +936,7 @@ export interface FaustAudioWorkletProcessorDependencies<Poly extends boolean = f
876
936
  FaustPolyWebAudioDsp: Poly extends true ? typeof FaustPolyWebAudioDsp : undefined;
877
937
  FaustWebAudioDspVoice: Poly extends true ? typeof FaustWebAudioDspVoice : undefined;
878
938
  FaustWasmInstantiator: typeof FaustWasmInstantiator;
939
+ FaustAudioWorkletProcessorCommunicator: typeof FaustAudioWorkletProcessorCommunicator;
879
940
  }
880
941
  export interface FaustAudioWorkletNodeOptions<Poly extends boolean = false> extends AudioWorkletNodeOptions {
881
942
  processorOptions: Poly extends true ? FaustPolyAudioWorkletProcessorOptions : FaustMonoAudioWorkletProcessorOptions;
@@ -926,6 +987,7 @@ export interface FaustFFTAudioWorkletProcessorDependencies {
926
987
  FaustBaseWebAudioDsp: typeof FaustBaseWebAudioDsp;
927
988
  FaustMonoWebAudioDsp: typeof FaustMonoWebAudioDsp;
928
989
  FaustWasmInstantiator: typeof FaustWasmInstantiator;
990
+ FaustAudioWorkletProcessorCommunicator: typeof FaustAudioWorkletProcessorCommunicator;
929
991
  FFTUtils: typeof FFTUtils;
930
992
  }
931
993
  export interface FaustFFTAudioWorkletNodeOptions extends AudioWorkletNodeOptions {
@@ -1132,6 +1194,8 @@ export declare class FaustOfflineProcessor<Poly extends boolean = false> {
1132
1194
  propagateAcc(accelerationIncludingGravity: NonNullable<DeviceMotionEvent["accelerationIncludingGravity"]>, invert?: boolean): void;
1133
1195
  get hasGyrInput(): boolean;
1134
1196
  propagateGyr(event: Pick<DeviceOrientationEvent, "alpha" | "beta" | "gamma">): void;
1197
+ startSensors(): void;
1198
+ stopSensors(): void;
1135
1199
  /**
1136
1200
  * Render frames in an array.
1137
1201
  *
@@ -1288,7 +1352,9 @@ export declare class FaustAudioWorkletNode<Poly extends boolean = false> extends
1288
1352
  protected fPlotHandler: PlotHandler | null;
1289
1353
  protected fUICallback: UIHandler;
1290
1354
  protected fDescriptor: FaustUIInputItem[];
1355
+ protected fCommunicator: FaustAudioWorkletNodeCommunicator;
1291
1356
  constructor(context: BaseAudioContext, name: string, factory: LooseFaustDspFactory, options?: Partial<FaustAudioWorkletNodeOptions<Poly>>);
1357
+ protected handleMessageAux: (e: MessageEvent) => void;
1292
1358
  private handleDeviceMotion;
1293
1359
  private handleDeviceOrientation;
1294
1360
  /** Setup accelerometer and gyroscope handlers */
@@ -1358,8 +1424,9 @@ export declare class FaustScriptProcessorNode<Poly extends boolean = false> exte
1358
1424
  protected handleDeviceMotion: any;
1359
1425
  protected handleDeviceOrientation: any;
1360
1426
  init(instance: Poly extends true ? FaustPolyWebAudioDsp : FaustMonoWebAudioDsp): void;
1361
- /** Setup accelerometer and gyroscope handlers */
1427
+ /** Start accelerometer and gyroscope handlers */
1362
1428
  startSensors(): Promise<void>;
1429
+ /** Stop accelerometer and gyroscope handlers */
1363
1430
  stopSensors(): void;
1364
1431
  compute(input: Float32Array[], output: Float32Array[]): boolean;
1365
1432
  setOutputParamHandler(handler: OutputParamHandler): void;
@@ -81,7 +81,8 @@ var getFaustAudioWorkletProcessor = (dependencies, faustData, register = true) =
81
81
  const { registerProcessor, AudioWorkletProcessor, sampleRate } = globalThis;
82
82
  const {
83
83
  FaustBaseWebAudioDsp: FaustBaseWebAudioDsp2,
84
- FaustWasmInstantiator: FaustWasmInstantiator2
84
+ FaustWasmInstantiator: FaustWasmInstantiator2,
85
+ FaustAudioWorkletProcessorCommunicator: FaustAudioWorkletProcessorCommunicator2
85
86
  } = dependencies;
86
87
  const {
87
88
  processorName,
@@ -106,7 +107,7 @@ var getFaustAudioWorkletProcessor = (dependencies, faustData, register = true) =
106
107
  constructor(options) {
107
108
  super(options);
108
109
  this.paramValuesCache = {};
109
- this.port.onmessage = (e) => this.handleMessageAux(e);
110
+ this.fCommunicator = new FaustAudioWorkletProcessorCommunicator2(this.port);
110
111
  const { parameterDescriptors } = this.constructor;
111
112
  parameterDescriptors.forEach((pd) => {
112
113
  this.paramValuesCache[pd.name] = pd.defaultValue || 0;
@@ -153,19 +154,26 @@ var getFaustAudioWorkletProcessor = (dependencies, faustData, register = true) =
153
154
  this.paramValuesCache[path] = paramValue;
154
155
  }
155
156
  }
157
+ if (this.fCommunicator.getNewAccDataAvailable()) {
158
+ const acc = this.fCommunicator.getAcc();
159
+ if (acc) {
160
+ this.fCommunicator.setNewAccDataAvailable(false);
161
+ const { invert, ...data } = acc;
162
+ this.propagateAcc(data, invert);
163
+ }
164
+ }
165
+ if (this.fCommunicator.getNewGyrDataAvailable()) {
166
+ const gyr = this.fCommunicator.getGyr();
167
+ if (gyr) {
168
+ this.fCommunicator.setNewGyrDataAvailable(false);
169
+ this.propagateGyr(gyr);
170
+ }
171
+ }
156
172
  return this.fDSPCode.compute(inputs[0], outputs[0]);
157
173
  }
158
174
  handleMessageAux(e) {
159
175
  const msg = e.data;
160
176
  switch (msg.type) {
161
- case "acc": {
162
- this.propagateAcc(msg.data, msg.invert);
163
- break;
164
- }
165
- case "gyr": {
166
- this.propagateGyr(msg.data);
167
- break;
168
- }
169
177
  case "midi": {
170
178
  this.midiMessage(msg.data);
171
179
  break;
@@ -234,10 +242,15 @@ var getFaustAudioWorkletProcessor = (dependencies, faustData, register = true) =
234
242
  class FaustMonoAudioWorkletProcessor extends FaustAudioWorkletProcessor {
235
243
  constructor(options) {
236
244
  super(options);
245
+ this.handleMessageAux = (e) => {
246
+ super.handleMessageAux(e);
247
+ };
237
248
  const { FaustMonoWebAudioDsp: FaustMonoWebAudioDsp2 } = dependencies;
238
249
  const { factory, sampleSize } = options.processorOptions;
239
250
  const instance = FaustWasmInstantiator2.createSyncMonoDSPInstance(factory);
240
251
  this.fDSPCode = new FaustMonoWebAudioDsp2(instance, sampleRate, sampleSize, 128, factory.soundfiles);
252
+ this.port.addEventListener("message", this.handleMessageAux);
253
+ this.port.start();
241
254
  this.fDSPCode.setOutputParamHandler((path, value) => this.port.postMessage({ path, value, type: "param" }));
242
255
  this.fDSPCode.start();
243
256
  }
@@ -264,7 +277,8 @@ var getFaustAudioWorkletProcessor = (dependencies, faustData, register = true) =
264
277
  const instance = FaustWasmInstantiator2.createSyncPolyDSPInstance(voiceFactory, mixerModule, voices, effectFactory);
265
278
  const soundfiles = { ...effectFactory == null ? void 0 : effectFactory.soundfiles, ...voiceFactory.soundfiles };
266
279
  this.fDSPCode = new FaustPolyWebAudioDsp3(instance, sampleRate, sampleSize, 128, soundfiles);
267
- this.port.onmessage = (e) => this.handleMessageAux(e);
280
+ this.port.addEventListener("message", this.handleMessageAux);
281
+ this.port.start();
268
282
  this.fDSPCode.setOutputParamHandler((path, value) => this.port.postMessage({ path, value, type: "param" }));
269
283
  this.fDSPCode.start();
270
284
  }
@@ -310,6 +324,7 @@ var getFaustFFTAudioWorkletProcessor = (dependencies, faustData, register = true
310
324
  FaustBaseWebAudioDsp: FaustBaseWebAudioDsp2,
311
325
  FaustWasmInstantiator: FaustWasmInstantiator2,
312
326
  FaustMonoWebAudioDsp: FaustMonoWebAudioDsp2,
327
+ FaustAudioWorkletProcessorCommunicator: FaustAudioWorkletProcessorCommunicator2,
313
328
  FFTUtils
314
329
  } = dependencies;
315
330
  const {
@@ -393,7 +408,58 @@ var getFaustFFTAudioWorkletProcessor = (dependencies, faustData, register = true
393
408
  this.fBufferNum = 0;
394
409
  this.soundfiles = {};
395
410
  this.windowFunction = null;
396
- this.port.onmessage = (e) => this.handleMessageAux(e);
411
+ this.handleMessageAux = (e) => {
412
+ var _a, _b, _c;
413
+ const msg = e.data;
414
+ switch (msg.type) {
415
+ case "midi":
416
+ this.midiMessage(msg.data);
417
+ break;
418
+ case "ctrlChange":
419
+ this.ctrlChange(msg.data[0], msg.data[1], msg.data[2]);
420
+ break;
421
+ case "pitchWheel":
422
+ this.pitchWheel(msg.data[0], msg.data[1]);
423
+ break;
424
+ case "param":
425
+ this.setParamValue(msg.data.path, msg.data.value);
426
+ break;
427
+ case "setPlotHandler": {
428
+ if (msg.data) {
429
+ this.fPlotHandler = (output, index, events) => {
430
+ if (events)
431
+ this.fCachedEvents.push(...events);
432
+ };
433
+ } else {
434
+ this.fPlotHandler = null;
435
+ }
436
+ (_a = this.fDSPCode) == null ? void 0 : _a.setPlotHandler(this.fPlotHandler);
437
+ break;
438
+ }
439
+ case "setupWamEventHandler": {
440
+ this.setupWamEventHandler();
441
+ break;
442
+ }
443
+ case "start": {
444
+ (_b = this.fDSPCode) == null ? void 0 : _b.start();
445
+ break;
446
+ }
447
+ case "stop": {
448
+ (_c = this.fDSPCode) == null ? void 0 : _c.stop();
449
+ break;
450
+ }
451
+ case "destroy": {
452
+ this.port.close();
453
+ this.destroy();
454
+ break;
455
+ }
456
+ default:
457
+ break;
458
+ }
459
+ };
460
+ this.port.addEventListener("message", this.handleMessageAux);
461
+ this.port.start();
462
+ this.communicator = new FaustAudioWorkletProcessorCommunicator2(this.port);
397
463
  const { parameterDescriptors } = this.constructor;
398
464
  parameterDescriptors.forEach((pd) => {
399
465
  this.paramValuesCache[pd.name] = pd.defaultValue || 0;
@@ -549,6 +615,21 @@ var getFaustFFTAudioWorkletProcessor = (dependencies, faustData, register = true
549
615
  this.paramValuesCache[path] = paramValue;
550
616
  }
551
617
  }
618
+ if (this.communicator.getNewAccDataAvailable()) {
619
+ const acc = this.communicator.getAcc();
620
+ if (acc) {
621
+ this.communicator.setNewAccDataAvailable(false);
622
+ const { invert, ...data } = acc;
623
+ this.propagateAcc(data, invert);
624
+ }
625
+ }
626
+ if (this.communicator.getNewGyrDataAvailable()) {
627
+ const gyr = this.communicator.getGyr();
628
+ if (gyr) {
629
+ this.communicator.setNewGyrDataAvailable(false);
630
+ this.propagateGyr(gyr);
631
+ }
632
+ }
552
633
  if (input == null ? void 0 : input.length) {
553
634
  let $inputWrite = 0;
554
635
  for (let i = 0; i < input.length; i++) {
@@ -578,55 +659,6 @@ var getFaustFFTAudioWorkletProcessor = (dependencies, faustData, register = true
578
659
  }
579
660
  return true;
580
661
  }
581
- handleMessageAux(e) {
582
- var _a, _b, _c;
583
- const msg = e.data;
584
- switch (msg.type) {
585
- case "midi":
586
- this.midiMessage(msg.data);
587
- break;
588
- case "ctrlChange":
589
- this.ctrlChange(msg.data[0], msg.data[1], msg.data[2]);
590
- break;
591
- case "pitchWheel":
592
- this.pitchWheel(msg.data[0], msg.data[1]);
593
- break;
594
- case "param":
595
- this.setParamValue(msg.data.path, msg.data.value);
596
- break;
597
- case "setPlotHandler": {
598
- if (msg.data) {
599
- this.fPlotHandler = (output, index, events) => {
600
- if (events)
601
- this.fCachedEvents.push(...events);
602
- };
603
- } else {
604
- this.fPlotHandler = null;
605
- }
606
- (_a = this.fDSPCode) == null ? void 0 : _a.setPlotHandler(this.fPlotHandler);
607
- break;
608
- }
609
- case "setupWamEventHandler": {
610
- this.setupWamEventHandler();
611
- break;
612
- }
613
- case "start": {
614
- (_b = this.fDSPCode) == null ? void 0 : _b.start();
615
- break;
616
- }
617
- case "stop": {
618
- (_c = this.fDSPCode) == null ? void 0 : _c.stop();
619
- break;
620
- }
621
- case "destroy": {
622
- this.port.close();
623
- this.destroy();
624
- break;
625
- }
626
- default:
627
- break;
628
- }
629
- }
630
662
  setParamValue(path, value) {
631
663
  var _a;
632
664
  (_a = this.fDSPCode) == null ? void 0 : _a.setParamValue(path, value);
@@ -644,6 +676,12 @@ var getFaustFFTAudioWorkletProcessor = (dependencies, faustData, register = true
644
676
  var _a;
645
677
  (_a = this.fDSPCode) == null ? void 0 : _a.pitchWheel(channel, wheel);
646
678
  }
679
+ propagateAcc(accelerationIncludingGravity, invert = false) {
680
+ this.fDSPCode.propagateAcc(accelerationIncludingGravity, invert);
681
+ }
682
+ propagateGyr(event) {
683
+ this.fDSPCode.propagateGyr(event);
684
+ }
647
685
  resetFFT(sizeIn, overlapIn, windowFunctionIn, inputChannels, outputChannels, bufferSize) {
648
686
  var _a, _b;
649
687
  const fftSize = ~~ceil(Math.max(2, sizeIn || 1024), 2);
@@ -2426,6 +2464,12 @@ var FaustBaseWebAudioDsp = class _FaustBaseWebAudioDsp {
2426
2464
  this.fComputeHandler = null;
2427
2465
  this.fPlotHandler = null;
2428
2466
  }
2467
+ startSensors() {
2468
+ this.startSensors();
2469
+ }
2470
+ stopSensors() {
2471
+ this.stopSensors();
2472
+ }
2429
2473
  };
2430
2474
  var FaustMonoWebAudioDsp = class extends FaustBaseWebAudioDsp {
2431
2475
  constructor(instance, sampleRate, sampleSize, bufferSize, soundfiles) {
@@ -3051,6 +3095,10 @@ var FaustOfflineProcessor = class {
3051
3095
  propagateGyr(event) {
3052
3096
  this.fDSPCode.propagateGyr(event);
3053
3097
  }
3098
+ startSensors() {
3099
+ }
3100
+ stopSensors() {
3101
+ }
3054
3102
  /**
3055
3103
  * Render frames in an array.
3056
3104
  *
@@ -3679,6 +3727,130 @@ var SoundfileReader = class {
3679
3727
  };
3680
3728
  var SoundfileReader_default = SoundfileReader;
3681
3729
 
3730
+ // src/FaustAudioWorkletCommunicator.ts
3731
+ var FaustAudioWorkletCommunicator = class {
3732
+ constructor(port) {
3733
+ this.port = port;
3734
+ this.supportSharedArrayBuffer = !!globalThis.SharedArrayBuffer;
3735
+ this.byteLength = 4 * Uint8Array.BYTES_PER_ELEMENT + 3 * Float32Array.BYTES_PER_ELEMENT + 3 * Float32Array.BYTES_PER_ELEMENT;
3736
+ }
3737
+ initializeBuffer(ab) {
3738
+ let ptr = 0;
3739
+ this.uin8Invert = new Uint8ClampedArray(ab, ptr, 1);
3740
+ ptr += Uint8ClampedArray.BYTES_PER_ELEMENT;
3741
+ this.uin8NewAccData = new Uint8ClampedArray(ab, ptr, 1);
3742
+ ptr += Uint8ClampedArray.BYTES_PER_ELEMENT;
3743
+ this.uin8NewGyrData = new Uint8ClampedArray(ab, ptr, 1);
3744
+ ptr += Uint8ClampedArray.BYTES_PER_ELEMENT;
3745
+ ptr += Uint8ClampedArray.BYTES_PER_ELEMENT;
3746
+ ;
3747
+ this.f32Acc = new Float32Array(ab, ptr, 3);
3748
+ ptr += 3 * Float32Array.BYTES_PER_ELEMENT;
3749
+ this.f32Gyr = new Float32Array(ab, ptr, 3);
3750
+ ptr += 3 * Float32Array.BYTES_PER_ELEMENT;
3751
+ }
3752
+ setNewAccDataAvailable(value) {
3753
+ if (!this.uin8NewAccData)
3754
+ return;
3755
+ this.uin8NewAccData[0] = +value;
3756
+ }
3757
+ getNewAccDataAvailable() {
3758
+ var _a;
3759
+ return !!((_a = this.uin8NewAccData) == null ? void 0 : _a[0]);
3760
+ }
3761
+ setNewGyrDataAvailable(value) {
3762
+ if (!this.uin8NewGyrData)
3763
+ return;
3764
+ this.uin8NewGyrData[0] = +value;
3765
+ }
3766
+ getNewGyrDataAvailable() {
3767
+ var _a;
3768
+ return !!((_a = this.uin8NewGyrData) == null ? void 0 : _a[0]);
3769
+ }
3770
+ setAcc({ x, y, z }, invert = false) {
3771
+ if (!this.supportSharedArrayBuffer) {
3772
+ const e = { type: "acc", data: { x, y, z }, invert };
3773
+ this.port.postMessage(e);
3774
+ }
3775
+ if (!this.uin8NewAccData)
3776
+ return;
3777
+ this.uin8Invert[0] = +invert;
3778
+ this.f32Acc[0] = x;
3779
+ this.f32Acc[1] = y;
3780
+ this.f32Acc[2] = z;
3781
+ this.uin8NewAccData[0] = 1;
3782
+ }
3783
+ getAcc() {
3784
+ if (!this.uin8NewAccData)
3785
+ return;
3786
+ const invert = !!this.uin8Invert[0];
3787
+ const [x, y, z] = this.f32Acc;
3788
+ return { x, y, z, invert };
3789
+ }
3790
+ setGyr({ alpha, beta, gamma }) {
3791
+ if (!this.supportSharedArrayBuffer) {
3792
+ const e = { type: "gyr", data: { alpha, beta, gamma } };
3793
+ this.port.postMessage(e);
3794
+ }
3795
+ if (!this.uin8NewGyrData)
3796
+ return;
3797
+ this.f32Gyr[0] = alpha;
3798
+ this.f32Gyr[1] = beta;
3799
+ this.f32Gyr[2] = gamma;
3800
+ this.uin8NewGyrData[0] = 1;
3801
+ }
3802
+ getGyr() {
3803
+ if (!this.uin8NewGyrData)
3804
+ return;
3805
+ const [alpha, beta, gamma] = this.f32Gyr;
3806
+ return { alpha, beta, gamma };
3807
+ }
3808
+ };
3809
+ var FaustAudioWorkletNodeCommunicator = class extends FaustAudioWorkletCommunicator {
3810
+ constructor(port) {
3811
+ super(port);
3812
+ if (this.supportSharedArrayBuffer) {
3813
+ const sab = new SharedArrayBuffer(this.byteLength);
3814
+ this.initializeBuffer(sab);
3815
+ this.port.postMessage({ type: "initSab", sab });
3816
+ } else {
3817
+ const ab = new ArrayBuffer(this.byteLength);
3818
+ this.initializeBuffer(ab);
3819
+ }
3820
+ }
3821
+ };
3822
+ var FaustAudioWorkletProcessorCommunicator = class extends FaustAudioWorkletCommunicator {
3823
+ constructor(port) {
3824
+ super(port);
3825
+ if (this.supportSharedArrayBuffer) {
3826
+ this.port.addEventListener("message", (event) => {
3827
+ const { data } = event;
3828
+ if (data.type === "initSab") {
3829
+ this.initializeBuffer(data.sab);
3830
+ }
3831
+ });
3832
+ } else {
3833
+ const ab = new ArrayBuffer(this.byteLength);
3834
+ this.initializeBuffer(ab);
3835
+ this.port.addEventListener("message", (event) => {
3836
+ const msg = event.data;
3837
+ switch (msg.type) {
3838
+ case "acc": {
3839
+ this.setAcc(msg.data, msg.invert);
3840
+ break;
3841
+ }
3842
+ case "gyr": {
3843
+ this.setGyr(msg.data);
3844
+ break;
3845
+ }
3846
+ default:
3847
+ break;
3848
+ }
3849
+ });
3850
+ }
3851
+ }
3852
+ };
3853
+
3682
3854
  // src/FaustAudioWorkletNode.ts
3683
3855
  var _hasAccInput, _hasGyrInput;
3684
3856
  var FaustAudioWorkletNode = class extends (globalThis.AudioWorkletNode || null) {
@@ -3696,7 +3868,13 @@ var FaustAudioWorkletNode = class extends (globalThis.AudioWorkletNode || null)
3696
3868
  });
3697
3869
  __privateAdd(this, _hasAccInput, false);
3698
3870
  __privateAdd(this, _hasGyrInput, false);
3699
- // Public API
3871
+ this.handleMessageAux = (e) => {
3872
+ if (e.data.type === "param" && this.fOutputHandler) {
3873
+ this.fOutputHandler(e.data.path, e.data.value);
3874
+ } else if (e.data.type === "plot" && this.fPlotHandler) {
3875
+ this.fPlotHandler(e.data.value, e.data.index, e.data.events);
3876
+ }
3877
+ };
3700
3878
  // Accelerometer and gyroscope handlers
3701
3879
  this.handleDeviceMotion = ({ accelerationIncludingGravity }) => {
3702
3880
  const isAndroid = /Android/i.test(navigator.userAgent);
@@ -3731,14 +3909,11 @@ var FaustAudioWorkletNode = class extends (globalThis.AudioWorkletNode || null)
3731
3909
  }
3732
3910
  };
3733
3911
  FaustBaseWebAudioDsp.parseUI(this.fJSONDsp.ui, this.fUICallback);
3734
- this.port.onmessage = (e) => {
3735
- if (e.data.type === "param" && this.fOutputHandler) {
3736
- this.fOutputHandler(e.data.path, e.data.value);
3737
- } else if (e.data.type === "plot" && this.fPlotHandler) {
3738
- this.fPlotHandler(e.data.value, e.data.index, e.data.events);
3739
- }
3740
- };
3912
+ this.fCommunicator = new FaustAudioWorkletNodeCommunicator(this.port);
3913
+ this.port.addEventListener("message", this.handleMessageAux);
3914
+ this.port.start();
3741
3915
  }
3916
+ // Public API
3742
3917
  /** Setup accelerometer and gyroscope handlers */
3743
3918
  async startSensors() {
3744
3919
  if (this.hasAccInput) {
@@ -3859,8 +4034,8 @@ var FaustAudioWorkletNode = class extends (globalThis.AudioWorkletNode || null)
3859
4034
  propagateAcc(accelerationIncludingGravity, invert = false) {
3860
4035
  if (!accelerationIncludingGravity)
3861
4036
  return;
3862
- const e = { type: "acc", data: accelerationIncludingGravity, invert };
3863
- this.port.postMessage(e);
4037
+ const { x, y, z } = accelerationIncludingGravity;
4038
+ this.fCommunicator.setAcc({ x, y, z }, invert);
3864
4039
  }
3865
4040
  get hasGyrInput() {
3866
4041
  return __privateGet(this, _hasGyrInput);
@@ -3868,8 +4043,8 @@ var FaustAudioWorkletNode = class extends (globalThis.AudioWorkletNode || null)
3868
4043
  propagateGyr(event) {
3869
4044
  if (!event)
3870
4045
  return;
3871
- const e = { type: "gyr", data: event };
3872
- this.port.postMessage(e);
4046
+ const { alpha, beta, gamma } = event;
4047
+ this.fCommunicator.setGyr({ alpha, beta, gamma });
3873
4048
  }
3874
4049
  setParamValue(path, value) {
3875
4050
  const e = { type: "param", data: { path, value } };
@@ -4012,7 +4187,7 @@ var FaustScriptProcessorNode = class extends (globalThis.ScriptProcessorNode ||
4012
4187
  this.start();
4013
4188
  }
4014
4189
  // Public API
4015
- /** Setup accelerometer and gyroscope handlers */
4190
+ /** Start accelerometer and gyroscope handlers */
4016
4191
  async startSensors() {
4017
4192
  if (this.hasAccInput) {
4018
4193
  if (window.DeviceMotionEvent) {
@@ -4057,6 +4232,7 @@ var FaustScriptProcessorNode = class extends (globalThis.ScriptProcessorNode ||
4057
4232
  }
4058
4233
  }
4059
4234
  }
4235
+ /** Stop accelerometer and gyroscope handlers */
4060
4236
  stopSensors() {
4061
4237
  if (this.hasAccInput) {
4062
4238
  window.removeEventListener("devicemotion", this.handleDeviceMotion, true);
@@ -4230,11 +4406,16 @@ var ${WasmAllocator.name} = ${WasmAllocator.toString()}
4230
4406
  var WasmAllocator = ${WasmAllocator.name};
4231
4407
  var ${FaustSensors.name} = ${FaustSensors.toString()}
4232
4408
  var FaustSensors = ${FaustSensors.name};
4409
+ var ${FaustAudioWorkletCommunicator.name} = ${FaustAudioWorkletCommunicator.toString()}
4410
+ var FaustAudioWorkletCommunicator = ${FaustAudioWorkletCommunicator.name};
4411
+ var ${FaustAudioWorkletProcessorCommunicator.name} = ${FaustAudioWorkletProcessorCommunicator.toString()}
4412
+ var FaustAudioWorkletProcessorCommunicator = ${FaustAudioWorkletProcessorCommunicator.name};
4233
4413
  // Put them in dependencies
4234
4414
  const dependencies = {
4235
4415
  FaustBaseWebAudioDsp,
4236
4416
  FaustMonoWebAudioDsp,
4237
- FaustWasmInstantiator
4417
+ FaustWasmInstantiator,
4418
+ FaustAudioWorkletProcessorCommunicator
4238
4419
  };
4239
4420
  // Generate the actual AudioWorkletProcessor code
4240
4421
  (${FaustAudioWorkletProcessor_default.toString()})(dependencies, faustData);
@@ -4284,12 +4465,17 @@ var ${WasmAllocator.name} = ${WasmAllocator.toString()}
4284
4465
  var WasmAllocator = ${WasmAllocator.name};
4285
4466
  var ${FaustSensors.name} = ${FaustSensors.toString()}
4286
4467
  var FaustSensors = ${FaustSensors.name};
4468
+ var ${FaustAudioWorkletCommunicator.name} = ${FaustAudioWorkletCommunicator.toString()}
4469
+ var FaustAudioWorkletCommunicator = ${FaustAudioWorkletCommunicator.name};
4470
+ var ${FaustAudioWorkletProcessorCommunicator.name} = ${FaustAudioWorkletProcessorCommunicator.toString()}
4471
+ var FaustAudioWorkletProcessorCommunicator = ${FaustAudioWorkletProcessorCommunicator.name};
4287
4472
  var FFTUtils = ${fftUtils.toString()}
4288
4473
  // Put them in dependencies
4289
4474
  const dependencies = {
4290
4475
  FaustBaseWebAudioDsp,
4291
4476
  FaustMonoWebAudioDsp,
4292
4477
  FaustWasmInstantiator,
4478
+ FaustAudioWorkletProcessorCommunicator,
4293
4479
  FFTUtils
4294
4480
  };
4295
4481
  // Generate the actual AudioWorkletProcessor code
@@ -4333,6 +4519,7 @@ const dependencies = {
4333
4519
  FaustBaseWebAudioDsp,
4334
4520
  FaustMonoWebAudioDsp,
4335
4521
  FaustWasmInstantiator: FaustWasmInstantiator_default,
4522
+ FaustAudioWorkletProcessorCommunicator,
4336
4523
  FaustPolyWebAudioDsp: void 0,
4337
4524
  FaustWebAudioDspVoice: void 0
4338
4525
  };
@@ -4513,11 +4700,16 @@ var ${WasmAllocator.name} = ${WasmAllocator.toString()}
4513
4700
  var WasmAllocator = ${WasmAllocator.name};
4514
4701
  var ${FaustSensors.name} = ${FaustSensors.toString()}
4515
4702
  var FaustSensors = ${FaustSensors.name};
4703
+ var ${FaustAudioWorkletCommunicator.name} = ${FaustAudioWorkletCommunicator.toString()}
4704
+ var FaustAudioWorkletCommunicator = ${FaustAudioWorkletCommunicator.name};
4705
+ var ${FaustAudioWorkletProcessorCommunicator.name} = ${FaustAudioWorkletProcessorCommunicator.toString()}
4706
+ var FaustAudioWorkletProcessorCommunicator = ${FaustAudioWorkletProcessorCommunicator.name};
4516
4707
  // Put them in dependencies
4517
4708
  const dependencies = {
4518
4709
  FaustBaseWebAudioDsp,
4519
4710
  FaustPolyWebAudioDsp,
4520
- FaustWasmInstantiator
4711
+ FaustWasmInstantiator,
4712
+ FaustAudioWorkletProcessorCommunicator
4521
4713
  };
4522
4714
  // Generate the actual AudioWorkletProcessor code
4523
4715
  (${FaustAudioWorkletProcessor_default.toString()})(dependencies, faustData);
@@ -4545,7 +4737,8 @@ const dependencies = {
4545
4737
  FaustMonoWebAudioDsp: void 0,
4546
4738
  FaustWasmInstantiator: FaustWasmInstantiator_default,
4547
4739
  FaustPolyWebAudioDsp,
4548
- FaustWebAudioDspVoice
4740
+ FaustWebAudioDspVoice,
4741
+ FaustAudioWorkletProcessorCommunicator
4549
4742
  };
4550
4743
  const faustData = {
4551
4744
  processorName,