@grame/faustwasm 0.2.2 → 0.3.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.
@@ -0,0 +1,370 @@
1
+ export interface AccParams {
2
+ isEnabled: boolean;
3
+ acc: string;
4
+ address: string;
5
+ min: number;
6
+ max: number;
7
+ init: number;
8
+ label: string;
9
+ }
10
+
11
+ /** Enum describing the axis of the accelerometer or gyroscope */
12
+ export enum Axis { x, y, z }
13
+
14
+ /** Enum describing the curve of the accelerometer */
15
+ export enum Curve { Up, Down, UpDown, DownUp }
16
+
17
+ /** Object describing value off accelerometer metadata values */
18
+ class AccMeta {
19
+ axis: Axis;
20
+ curve: Curve;
21
+ amin: number;
22
+ amid: number;
23
+ amax: number;
24
+ }
25
+
26
+ interface Range {
27
+ fLo: number;
28
+ fHi: number;
29
+ clip(x: number): number;
30
+ }
31
+
32
+ interface InterpolateObject {
33
+ amin: number;
34
+ amax: number;
35
+ }
36
+ interface Interpolator {
37
+ fRange: Range;
38
+ fCoef: number;
39
+ fOffset: number;
40
+ returnMappedValue(v: number): number;
41
+ getLowHigh(amin: number, amax: number): InterpolateObject;
42
+ }
43
+
44
+ interface InterpolateObject3pt {
45
+ amin: number;
46
+ amid: number;
47
+ amax: number;
48
+ }
49
+ interface Interpolator3pt {
50
+ fSegment1: Interpolator;
51
+ fSegment2: Interpolator;
52
+ fMid: number;
53
+ returnMappedValue(v: number): number;
54
+ getMappingValues(amin: number, amid: number, amax: number): InterpolateObject3pt;
55
+ }
56
+
57
+ /**
58
+ * ValueConverter interface
59
+ */
60
+ interface ValueConverter {
61
+ uiToFaust(x: number): number;
62
+ faustToUi(x: number): number;
63
+ }
64
+
65
+ /**
66
+ * UpdatableValueConverter interface
67
+ */
68
+ export interface UpdatableValueConverter extends ValueConverter {
69
+ fActive: boolean;
70
+
71
+ setMappingValues(amin: number, amid: number, amax: number, min: number, init: number, max: number): void;
72
+ getMappingValues(amin: number, amid: number, amax: number): InterpolateObject3pt;
73
+
74
+ setActive(onOff: boolean): void;
75
+ getActive(): boolean;
76
+ }
77
+
78
+
79
+
80
+ export default class FaustSensors {
81
+ /**
82
+ * Function to convert a number to an axis type
83
+ *
84
+ * @param value number
85
+ * @returns axis type
86
+ */
87
+ static convertToAxis(value: number): Axis {
88
+ switch (value) {
89
+ case 0:
90
+ return Axis.x;
91
+ case 1:
92
+ return Axis.y;
93
+ case 2:
94
+ return Axis.z;
95
+ default:
96
+ console.error("Error: Axis not found value: " + value);
97
+ return Axis.x;
98
+ }
99
+ }
100
+ /**
101
+ * Function to convert a number to a curve type
102
+ *
103
+ * @param value number
104
+ * @returns curve type
105
+ */
106
+ static convertToCurve(value: number): Curve {
107
+ switch (value) {
108
+ case 0:
109
+ return Curve.Up;
110
+ case 1:
111
+ return Curve.Down;
112
+ case 2:
113
+ return Curve.UpDown;
114
+ case 3:
115
+ return Curve.DownUp;
116
+ default:
117
+ console.error("Error: Curve not found value: " + value);
118
+ return Curve.Up;
119
+ }
120
+ }
121
+
122
+ // Converter objects use to map acc and Faust value
123
+ static _Range: new (x: number, y: number) => Range;
124
+ static get Range() {
125
+ if (!this._Range) {
126
+ this._Range = class {
127
+ fLo: number;
128
+ fHi: number;
129
+
130
+ constructor(x: number, y: number) {
131
+ this.fLo = Math.min(x, y);
132
+ this.fHi = Math.max(x, y);
133
+ }
134
+
135
+ clip(x: number): number {
136
+ if (x < this.fLo) return this.fLo;
137
+ if (x > this.fHi) return this.fHi;
138
+ return x;
139
+ }
140
+ };
141
+ }
142
+ return this._Range;
143
+ }
144
+
145
+ static _Interpolator: new (lo: number, hi: number, v1: number, v2: number) => Interpolator;
146
+ /**
147
+ * Interpolator class
148
+ */
149
+ static get Interpolator() {
150
+ if (!this._Interpolator) {
151
+ this._Interpolator = class {
152
+ fRange: Range;
153
+ fCoef: number;
154
+ fOffset: number;
155
+
156
+ constructor(lo: number, hi: number, v1: number, v2: number) {
157
+ this.fRange = new FaustSensors.Range(lo, hi);
158
+ if (hi !== lo) {
159
+ // regular case
160
+ this.fCoef = (v2 - v1) / (hi - lo);
161
+ this.fOffset = v1 - lo * this.fCoef;
162
+ } else {
163
+ // degenerate case, avoids division by zero
164
+ this.fCoef = 0;
165
+ this.fOffset = (v1 + v2) / 2;
166
+ }
167
+ }
168
+ returnMappedValue(v: number): number {
169
+ var x = this.fRange.clip(v);
170
+ return this.fOffset + x * this.fCoef;
171
+ }
172
+ getLowHigh(amin: number, amax: number): InterpolateObject {
173
+ return { amin: this.fRange.fLo, amax: this.fRange.fHi };
174
+ }
175
+ };
176
+ }
177
+ return this._Interpolator;
178
+ }
179
+
180
+ static _Interpolator3pt: new (lo: number, mid: number, hi: number, v1: number, vMid: number, v2: number) => Interpolator3pt;
181
+ /**
182
+ * Interpolator3pt class, combine two interpolators
183
+ */
184
+ static get Interpolator3pt() {
185
+ if (!this._Interpolator3pt) {
186
+ this._Interpolator3pt = class {
187
+
188
+ fSegment1: Interpolator;
189
+ fSegment2: Interpolator;
190
+ fMid: number;
191
+
192
+ constructor(lo: number, mid: number, hi: number, v1: number, vMid: number, v2: number) {
193
+ this.fSegment1 = new FaustSensors.Interpolator(lo, mid, v1, vMid);
194
+ this.fSegment2 = new FaustSensors.Interpolator(mid, hi, vMid, v2);
195
+ this.fMid = mid;
196
+ }
197
+ returnMappedValue(x: number): number {
198
+ return (x < this.fMid) ? this.fSegment1.returnMappedValue(x) : this.fSegment2.returnMappedValue(x);
199
+ }
200
+
201
+ getMappingValues(amin: number, amid: number, amax: number): InterpolateObject3pt {
202
+ var lowHighSegment1 = this.fSegment1.getLowHigh(amin, amid);
203
+ var lowHighSegment2 = this.fSegment2.getLowHigh(amid, amax);
204
+ return { amin: lowHighSegment1.amin, amid: lowHighSegment2.amin, amax: lowHighSegment2.amax };
205
+ }
206
+ }
207
+
208
+ }
209
+ return this._Interpolator3pt;
210
+ }
211
+ static _UpConverter: new (amin: number, amid: number, amax: number, fmin: number, fmid: number, fmax: number) => UpdatableValueConverter;
212
+ /**
213
+ * UpConverter class, convert accelerometer value to Faust value
214
+ */
215
+ static get UpConverter() {
216
+ if (!this._UpConverter) {
217
+ this._UpConverter = class implements UpdatableValueConverter {
218
+
219
+ fA2F: Interpolator3pt;
220
+ fF2A: Interpolator3pt;
221
+ fActive: boolean = true;
222
+
223
+ constructor(amin: number, amid: number, amax: number, fmin: number, fmid: number, fmax: number) {
224
+ this.fA2F = new FaustSensors.Interpolator3pt(amin, amid, amax, fmin, fmid, fmax);
225
+ this.fF2A = new FaustSensors.Interpolator3pt(fmin, fmid, fmax, amin, amid, amax);
226
+ }
227
+
228
+ uiToFaust(x: number) { return this.fA2F.returnMappedValue(x) }
229
+ faustToUi(x: number) { return this.fF2A.returnMappedValue(x) }
230
+
231
+ setMappingValues(amin: number, amid: number, amax: number, min: number, init: number, max: number): void {
232
+ this.fA2F = new FaustSensors.Interpolator3pt(amin, amid, amax, min, init, max);
233
+ this.fF2A = new FaustSensors.Interpolator3pt(min, init, max, amin, amid, amax);
234
+ }
235
+
236
+ getMappingValues(amin: number, amid: number, amax: number): InterpolateObject3pt {
237
+ return this.fA2F.getMappingValues(amin, amid, amax);
238
+ }
239
+
240
+ setActive(onOff: boolean): void { this.fActive = onOff }
241
+ getActive(): boolean { return this.fActive }
242
+ }
243
+
244
+ }
245
+ return this._UpConverter;
246
+ }
247
+ static _DownConverter: new (amin: number, amid: number, amax: number, fmin: number, fmid: number, fmax: number) => UpdatableValueConverter;
248
+ /**
249
+ * DownConverter class, convert accelerometer value to Faust value
250
+ */
251
+ static get DownConverter() {
252
+ if (!this._DownConverter) {
253
+ this._DownConverter = class implements UpdatableValueConverter {
254
+
255
+ fA2F: Interpolator3pt;
256
+ fF2A: Interpolator3pt;
257
+ fActive: boolean = true;
258
+
259
+ constructor(amin: number, amid: number, amax: number, fmin: number, fmid: number, fmax: number) {
260
+ this.fA2F = new FaustSensors.Interpolator3pt(amin, amid, amax, fmax, fmid, fmin);
261
+ this.fF2A = new FaustSensors.Interpolator3pt(fmin, fmid, fmax, amax, amid, amin);
262
+ }
263
+
264
+ uiToFaust(x: number) { return this.fA2F.returnMappedValue(x) }
265
+ faustToUi(x: number) { return this.fF2A.returnMappedValue(x) }
266
+
267
+ setMappingValues(amin: number, amid: number, amax: number, min: number, init: number, max: number): void {
268
+ this.fA2F = new FaustSensors.Interpolator3pt(amin, amid, amax, max, init, min);
269
+ this.fF2A = new FaustSensors.Interpolator3pt(min, init, max, amax, amid, amin);
270
+ }
271
+ getMappingValues(amin: number, amid: number, amax: number): InterpolateObject3pt {
272
+ return this.fA2F.getMappingValues(amin, amid, amax);
273
+ }
274
+
275
+ setActive(onOff: boolean): void { this.fActive = onOff }
276
+ getActive(): boolean { return this.fActive }
277
+ }
278
+
279
+ }
280
+ return this._DownConverter;
281
+ }
282
+ static _UpDownConverter: new (amin: number, amid: number, amax: number, fmin: number, fmid: number, fmax: number) => UpdatableValueConverter;
283
+ /**
284
+ * UpDownConverter class, convert accelerometer value to Faust value
285
+ */
286
+ static get UpDownConverter() {
287
+ if (!this._UpDownConverter) {
288
+ this._UpDownConverter = class implements UpdatableValueConverter {
289
+
290
+ fA2F: Interpolator3pt;
291
+ fF2A: Interpolator;
292
+ fActive: boolean = true;
293
+
294
+ constructor(amin: number, amid: number, amax: number, fmin: number, fmid: number, fmax: number) {
295
+ this.fA2F = new FaustSensors.Interpolator3pt(amin, amid, amax, fmin, fmax, fmin);
296
+ this.fF2A = new FaustSensors.Interpolator(fmin, fmax, amin, amax);
297
+ }
298
+
299
+ uiToFaust(x: number) { return this.fA2F.returnMappedValue(x) }
300
+ faustToUi(x: number) { return this.fF2A.returnMappedValue(x) }
301
+
302
+ setMappingValues(amin: number, amid: number, amax: number, min: number, init: number, max: number): void {
303
+ this.fA2F = new FaustSensors.Interpolator3pt(amin, amid, amax, min, max, min);
304
+ this.fF2A = new FaustSensors.Interpolator(min, max, amin, amax);
305
+ }
306
+ getMappingValues(amin: number, amid: number, amax: number): InterpolateObject3pt {
307
+ return this.fA2F.getMappingValues(amin, amid, amax);
308
+ }
309
+
310
+ setActive(onOff: boolean): void { this.fActive = onOff }
311
+ getActive(): boolean { return this.fActive }
312
+ }
313
+
314
+ }
315
+ return this._UpDownConverter;
316
+ }
317
+ /**
318
+ * DownUpConverter class, convert accelerometer value to Faust value
319
+ */
320
+ static _DownUpConverter: new (amin: number, amid: number, amax: number, fmin: number, fmid: number, fmax: number) => UpdatableValueConverter;
321
+ static get DownUpConverter() {
322
+ if (!this._DownUpConverter) {
323
+ this._DownUpConverter = class implements UpdatableValueConverter {
324
+
325
+ fA2F: Interpolator3pt;
326
+ fF2A: Interpolator;
327
+ fActive: boolean = true;
328
+
329
+ constructor(amin: number, amid: number, amax: number, fmin: number, fmid: number, fmax: number) {
330
+ this.fA2F = new FaustSensors.Interpolator3pt(amin, amid, amax, fmax, fmin, fmax);
331
+ this.fF2A = new FaustSensors.Interpolator(fmin, fmax, amin, amax);
332
+ }
333
+
334
+ uiToFaust(x: number) { return this.fA2F.returnMappedValue(x) }
335
+ faustToUi(x: number) { return this.fF2A.returnMappedValue(x) }
336
+
337
+ setMappingValues(amin: number, amid: number, amax: number, min: number, init: number, max: number): void {
338
+ this.fA2F = new FaustSensors.Interpolator3pt(amin, amid, amax, max, min, max);
339
+ this.fF2A = new FaustSensors.Interpolator(min, max, amin, amax);
340
+ }
341
+ getMappingValues(amin: number, amid: number, amax: number): InterpolateObject3pt {
342
+ return this.fA2F.getMappingValues(amin, amid, amax);
343
+ }
344
+
345
+ setActive(onOff: boolean): void { this.fActive = onOff }
346
+ getActive(): boolean { return this.fActive }
347
+ }
348
+ }
349
+ return this._DownUpConverter;
350
+ }
351
+ /**
352
+ * Public function to build the accelerometer handler
353
+ *
354
+ * @returns `UpdatableValueConverter` built for the given curve
355
+ */
356
+ static buildHandler(curve: Curve, amin: number, amid: number, amax: number, min: number, init: number, max: number): UpdatableValueConverter {
357
+ switch (curve) {
358
+ case Curve.Up:
359
+ return new FaustSensors.UpConverter(amin, amid, amax, min, init, max);
360
+ case Curve.Down:
361
+ return new FaustSensors.DownConverter(amin, amid, amax, min, init, max);
362
+ case Curve.UpDown:
363
+ return new FaustSensors.UpDownConverter(amin, amid, amax, min, init, max);
364
+ case Curve.DownUp:
365
+ return new FaustSensors.DownUpConverter(amin, amid, amax, min, init, max);
366
+ default:
367
+ return new FaustSensors.UpConverter(amin, amid, amax, min, init, max);
368
+ }
369
+ }
370
+ }
@@ -1,5 +1,6 @@
1
1
  import type { FaustMonoDspInstance, FaustPolyDspInstance, IFaustDspInstance } from "./FaustDspInstance";
2
2
  import type { AudioData, FaustDspMeta, FaustUIDescriptor, FaustUIGroup, FaustUIInputItem, FaustUIItem, LooseFaustDspFactory } from "./types";
3
+ import FaustSensors, { Axis, Curve, UpdatableValueConverter } from "./FaustSensors";
3
4
 
4
5
  // Public API
5
6
  export type OutputParamHandler = (path: string, value: number) => void;
@@ -10,6 +11,16 @@ export type MetadataHandler = (key: string, value: string) => void;
10
11
  // Implementation API
11
12
  export type UIHandler = (item: FaustUIItem) => void;
12
13
 
14
+ // Accelerometer or gyroscope handler
15
+ export type SensorEventHandler = (val: number) => void;
16
+
17
+ // Define a type for the accelerometer or gyroscope handlers
18
+ export type SensorEventHandlers = {
19
+ x: SensorEventHandler[];
20
+ y: SensorEventHandler[];
21
+ z: SensorEventHandler[];
22
+ };
23
+
13
24
  /** Definition of the AudioBufferItem type */
14
25
  export interface AudioBufferItem {
15
26
  pathName: string;
@@ -134,16 +145,16 @@ export class WasmAllocator {
134
145
  export class Soundfile {
135
146
  /** Maximum number of soundfile parts. */
136
147
  static get MAX_SOUNDFILE_PARTS() { return 256; }
137
-
148
+
138
149
  /** Maximum number of channels. */
139
150
  static get MAX_CHAN() { return 64; }
140
-
151
+
141
152
  /** Maximum buffer size in frames. */
142
153
  static get BUFFER_SIZE() { return 1024; }
143
-
154
+
144
155
  /** Default sample rate. */
145
156
  static get SAMPLE_RATE() { return 44100; }
146
-
157
+
147
158
  /** Pointer to the soundfile structure in wasm memory */
148
159
  private readonly fPtr: number;
149
160
  private readonly fBuffers: number;
@@ -332,10 +343,10 @@ export class Soundfile {
332
343
  }
333
344
 
334
345
  /**
335
- * DSP implementation: mimic the C++ 'dsp' class:
346
+ * DSP implementation that mimic the C++ 'dsp' class:
336
347
  * - adding MIDI control: metadata are decoded and incoming MIDI messages will control the associated controllers
337
348
  * - an output handler can be set to treat produced output controllers (like 'bargraph')
338
- * - regular controllers are handled using setParamValue/getParamValue
349
+ * - regular controllers are handled using setParamValue/getParamValue and getParams methods
339
350
  */
340
351
  export interface IFaustBaseWebAudioDsp {
341
352
  /**
@@ -464,13 +475,6 @@ export interface IFaustBaseWebAudioDsp {
464
475
  */
465
476
  getMeta(): FaustDspMeta;
466
477
 
467
- /**
468
- * Get DSP JSON description with its UI and metadata.
469
- *
470
- * @return the DSP JSON description
471
- */
472
- getJSON(): string;
473
-
474
478
  /**
475
479
  * Get DSP UI description.
476
480
  *
@@ -485,6 +489,13 @@ export interface IFaustBaseWebAudioDsp {
485
489
  */
486
490
  getDescriptors(): FaustUIInputItem[];
487
491
 
492
+ /**
493
+ * Get DSP JSON description with its UI and metadata.
494
+ *
495
+ * @return the DSP JSON description
496
+ */
497
+ getJSON(): string;
498
+
488
499
  /**
489
500
  * Start the DSP.
490
501
  */
@@ -499,6 +510,16 @@ export interface IFaustBaseWebAudioDsp {
499
510
  * Destroy the DSP.
500
511
  */
501
512
  destroy(): void;
513
+
514
+ /** Indicating if the DSP handles the accelerometer */
515
+ readonly hasAccInput: boolean;
516
+ /** Accelerometer handling */
517
+ propagateAcc(accelerationIncludingGravity: NonNullable<DeviceMotionEvent["accelerationIncludingGravity"]>): void;
518
+
519
+ /** Indicating if the DSP handles the gyroscope */
520
+ readonly hasGyrInput: boolean;
521
+ /** Gyroscope handling */
522
+ propagateGyr(event: Pick<DeviceOrientationEvent, "alpha" | "beta" | "gamma">): void;
502
523
  }
503
524
 
504
525
  export interface IFaustMonoWebAudioDsp extends IFaustBaseWebAudioDsp { }
@@ -557,6 +578,10 @@ export class FaustBaseWebAudioDsp implements IFaustBaseWebAudioDsp {
557
578
  /** Keep the end of memory offset before soundfiles */
558
579
  protected fEndMemory: number;
559
580
 
581
+ // Accelerometer handling
582
+ protected fAcc: SensorEventHandlers; // array of accelerometer handlers on x,y,y axes, to be called with DeviceMotionEvent
583
+ protected fGyr: SensorEventHandlers; // array of gyroscope handlers on alpha,beta,gama axes, to be called with DeviceMotionEvent
584
+
560
585
  // Buffers in wasm memory
561
586
  protected fAudioInputs!: number;
562
587
  protected fAudioOutputs!: number;
@@ -579,18 +604,30 @@ export class FaustBaseWebAudioDsp implements IFaustBaseWebAudioDsp {
579
604
  this.fInputsItems.push(item.address);
580
605
  this.fPathTable[item.address] = item.index;
581
606
  this.fDescriptor.push(item);
582
- // Parse 'midi' metadata
583
607
  if (!item.meta) return;
584
608
  item.meta.forEach((meta) => {
585
- const { midi } = meta;
586
- if (!midi) return;
587
- const strMidi = midi.trim();
588
- if (strMidi === "pitchwheel") {
589
- this.fPitchwheelLabel.push({ path: item.address, min: item.min as number, max: item.max as number });
590
- } else {
591
- const matched = strMidi.match(/^ctrl\s(\d+)/);
592
- if (!matched) return;
593
- this.fCtrlLabel[parseInt(matched[1])].push({ path: item.address, min: item.min as number, max: item.max as number });
609
+ const { midi, acc, gyr } = meta;
610
+ // Parse 'midi' metadata
611
+ if (midi) {
612
+ const strMidi = midi.trim();
613
+ if (strMidi === "pitchwheel") {
614
+ this.fPitchwheelLabel.push({ path: item.address, min: item.min as number, max: item.max as number });
615
+ } else {
616
+ const matched = strMidi.match(/^ctrl\s(\d+)/);
617
+ if (matched) {
618
+ this.fCtrlLabel[parseInt(matched[1])].push({ path: item.address, min: item.min as number, max: item.max as number });
619
+ }
620
+ }
621
+ }
622
+ // Parse 'acc' metadata
623
+ if (acc) {
624
+ const numAcc: number[] = acc.trim().split(" ").map(Number);
625
+ this.setupAccHandler(item.address, FaustSensors.convertToAxis(numAcc[0]), FaustSensors.convertToCurve(numAcc[1]), numAcc[2], numAcc[3], numAcc[4], item.min as number, item.init as number, item.max as number);
626
+ }
627
+ // Parse 'gyr' metadata
628
+ if (gyr) {
629
+ const numAcc: number[] = gyr.trim().split(" ").map(Number);
630
+ this.setupGyrHandler(item.address, FaustSensors.convertToAxis(numAcc[0]), FaustSensors.convertToCurve(numAcc[1]), numAcc[2], numAcc[3], numAcc[4], item.min as number, item.init as number, item.max as number);
594
631
  }
595
632
  });
596
633
  } else if (item.type === "soundfile") {
@@ -610,6 +647,8 @@ export class FaustBaseWebAudioDsp implements IFaustBaseWebAudioDsp {
610
647
  this.fPtrSize = sampleSize; // Done on wast/wasm backend side
611
648
  this.fSampleSize = sampleSize;
612
649
  this.fSoundfileBuffers = soundfiles;
650
+ this.fAcc = { x: [], y: [], z: [] };
651
+ this.fGyr = { x: [], y: [], z: [] };
613
652
  }
614
653
 
615
654
  // Tools
@@ -647,6 +686,65 @@ export class FaustBaseWebAudioDsp implements IFaustBaseWebAudioDsp {
647
686
  return trimmed.split(";").map(str => str.length <= 2 ? '' : str.substring(1, str.length - 1));
648
687
  }
649
688
 
689
+ get hasAccInput() { return this.fAcc.x.length + this.fAcc.y.length + this.fAcc.z.length > 0; }
690
+ propagateAcc(accelerationIncludingGravity: NonNullable<DeviceMotionEvent["accelerationIncludingGravity"]>) {
691
+
692
+ // Get accelerometervalues
693
+ const { x, y, z } = accelerationIncludingGravity;
694
+
695
+ // Call the accelerometer handlers
696
+ if (x !== null) this.fAcc.x.forEach(handler => handler(x));
697
+ if (y !== null) this.fAcc.y.forEach(handler => handler(y));
698
+ if (z !== null) this.fAcc.z.forEach(handler => handler(z));
699
+ }
700
+
701
+ get hasGyrInput() { return this.fGyr.x.length + this.fGyr.y.length + this.fGyr.z.length > 0; }
702
+ propagateGyr(event: Pick<DeviceOrientationEvent, "alpha" | "beta" | "gamma">) {
703
+
704
+ // Get gyroscope values
705
+ const { alpha, beta, gamma } = event;
706
+
707
+ // Call the gyroscope handlers
708
+ if (alpha !== null) this.fGyr.x.forEach(handler => handler(alpha));
709
+ if (beta !== null) this.fGyr.y.forEach(handler => handler(beta));
710
+ if (gamma !== null) this.fGyr.z.forEach(handler => handler(gamma));
711
+ }
712
+
713
+ /** Build the accelerometer handler */
714
+ private setupAccHandler(path: string, axis: Axis, curve: Curve, amin: number, amid: number, amax: number, min: number, init: number, max: number) {
715
+
716
+ const handler: UpdatableValueConverter = FaustSensors.buildHandler(curve, amin, amid, amax, min, init, max);
717
+ switch (axis) {
718
+ case Axis.x:
719
+ this.fAcc.x.push((val) => this.setParamValue(path, handler.uiToFaust(val)));
720
+ break;
721
+ case Axis.y:
722
+ this.fAcc.y.push((val) => this.setParamValue(path, handler.uiToFaust(val)));
723
+ break;
724
+ case Axis.z:
725
+ this.fAcc.z.push((val) => this.setParamValue(path, handler.uiToFaust(val)));
726
+ break;
727
+ }
728
+ }
729
+
730
+ /** Build the gyroscope handler */
731
+ private setupGyrHandler(path: string, axis: Axis, curve: Curve, amin: number, amid: number, amax: number, min: number, init: number, max: number) {
732
+
733
+ const handler: UpdatableValueConverter = FaustSensors.buildHandler(curve, amin, amid, amax, min, init, max);
734
+ switch (axis) {
735
+ case Axis.x:
736
+ this.fGyr.x.push((val) => this.setParamValue(path, handler.uiToFaust(val)));
737
+ break;
738
+ case Axis.y:
739
+ this.fGyr.y.push((val) => this.setParamValue(path, handler.uiToFaust(val)));
740
+ break;
741
+ case Axis.z:
742
+ this.fGyr.z.push((val) => this.setParamValue(path, handler.uiToFaust(val)));
743
+ break;
744
+ }
745
+ }
746
+
747
+
650
748
  static extractUrlsFromMeta(dspMeta: FaustDspMeta): string[] {
651
749
  // Find the entry with the "soundfiles" key
652
750
  const soundfilesEntry = dspMeta.meta.find(entry => entry.soundfiles !== undefined);
@@ -911,6 +1009,7 @@ export class FaustMonoWebAudioDsp extends FaustBaseWebAudioDsp implements IFaust
911
1009
  // Init soundfiles memory
912
1010
  this.initSoundfileMemory(allocator, this.fDSP);
913
1011
  }
1012
+
914
1013
  }
915
1014
 
916
1015
  private initMemory(): number {