@grame/faustwasm 0.2.3 → 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.
- package/assets/standalone/faustwasm/index.d.ts +41 -0
- package/assets/standalone/faustwasm/index.js +538 -15
- package/assets/standalone/faustwasm/index.js.map +3 -3
- package/assets/standalone/index.js +17 -11
- package/dist/cjs/index.d.ts +41 -0
- package/dist/cjs/index.js +537 -15
- package/dist/cjs/index.js.map +3 -3
- package/dist/cjs-bundle/index.d.ts +41 -0
- package/dist/cjs-bundle/index.js +537 -15
- package/dist/cjs-bundle/index.js.map +3 -3
- package/dist/esm/index.d.ts +41 -0
- package/dist/esm/index.js +538 -15
- package/dist/esm/index.js.map +3 -3
- package/dist/esm-bundle/index.d.ts +41 -0
- package/dist/esm-bundle/index.js +537 -15
- package/dist/esm-bundle/index.js.map +3 -3
- package/package.json +1 -1
- package/src/FaustAudioWorkletNode.ts +73 -0
- package/src/FaustAudioWorkletProcessor.ts +33 -4
- package/src/FaustDspGenerator.ts +14 -2
- package/src/FaustOfflineProcessor.ts +10 -0
- package/src/FaustScriptProcessorNode.ts +61 -1
- package/src/FaustSensors.ts +370 -0
- package/src/FaustWebAudioDsp.ts +109 -10
- package/test/faustlive-wasm/faustwasm/index.d.ts +41 -0
- package/test/faustlive-wasm/faustwasm/index.js +538 -15
- package/test/faustlive-wasm/faustwasm/index.js.map +3 -3
- package/test/faustlive-wasm/index.js +2 -0
- package/test/osc.dsp +4 -2
- package/LIB.dsp +0 -1
|
@@ -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
|
+
}
|
package/src/FaustWebAudioDsp.ts
CHANGED
|
@@ -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;
|
|
@@ -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
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
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 {
|
|
@@ -376,6 +376,12 @@ export type PlotHandler = (plotted: Float32Array[] | Float64Array[], index: numb
|
|
|
376
376
|
}[]) => void;
|
|
377
377
|
export type MetadataHandler = (key: string, value: string) => void;
|
|
378
378
|
export type UIHandler = (item: FaustUIItem) => void;
|
|
379
|
+
export type SensorEventHandler = (val: number) => void;
|
|
380
|
+
export type SensorEventHandlers = {
|
|
381
|
+
x: SensorEventHandler[];
|
|
382
|
+
y: SensorEventHandler[];
|
|
383
|
+
z: SensorEventHandler[];
|
|
384
|
+
};
|
|
379
385
|
/** Definition of the AudioBufferItem type */
|
|
380
386
|
export interface AudioBufferItem {
|
|
381
387
|
pathName: string;
|
|
@@ -626,6 +632,14 @@ export interface IFaustBaseWebAudioDsp {
|
|
|
626
632
|
* Destroy the DSP.
|
|
627
633
|
*/
|
|
628
634
|
destroy(): void;
|
|
635
|
+
/** Indicating if the DSP handles the accelerometer */
|
|
636
|
+
readonly hasAccInput: boolean;
|
|
637
|
+
/** Accelerometer handling */
|
|
638
|
+
propagateAcc(accelerationIncludingGravity: NonNullable<DeviceMotionEvent["accelerationIncludingGravity"]>): 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;
|
|
629
643
|
}
|
|
630
644
|
export interface IFaustMonoWebAudioDsp extends IFaustBaseWebAudioDsp {
|
|
631
645
|
}
|
|
@@ -676,6 +690,8 @@ export declare class FaustBaseWebAudioDsp implements IFaustBaseWebAudioDsp {
|
|
|
676
690
|
protected fSoundfileBuffers: LooseFaustDspFactory["soundfiles"];
|
|
677
691
|
/** Keep the end of memory offset before soundfiles */
|
|
678
692
|
protected fEndMemory: number;
|
|
693
|
+
protected fAcc: SensorEventHandlers;
|
|
694
|
+
protected fGyr: SensorEventHandlers;
|
|
679
695
|
protected fAudioInputs: number;
|
|
680
696
|
protected fAudioOutputs: number;
|
|
681
697
|
protected fBufferSize: number;
|
|
@@ -707,6 +723,14 @@ export declare class FaustBaseWebAudioDsp implements IFaustBaseWebAudioDsp {
|
|
|
707
723
|
static parseItem(item: FaustUIItem, callback: (item: FaustUIItem) => any): void;
|
|
708
724
|
/** Split the soundfile names and return an array of names */
|
|
709
725
|
static splitSoundfileNames(input: string): string[];
|
|
726
|
+
get hasAccInput(): boolean;
|
|
727
|
+
propagateAcc(accelerationIncludingGravity: NonNullable<DeviceMotionEvent["accelerationIncludingGravity"]>): void;
|
|
728
|
+
get hasGyrInput(): boolean;
|
|
729
|
+
propagateGyr(event: Pick<DeviceOrientationEvent, "alpha" | "beta" | "gamma">): void;
|
|
730
|
+
/** Build the accelerometer handler */
|
|
731
|
+
private setupAccHandler;
|
|
732
|
+
/** Build the gyroscope handler */
|
|
733
|
+
private setupGyrHandler;
|
|
710
734
|
static extractUrlsFromMeta(dspMeta: FaustDspMeta): string[];
|
|
711
735
|
/**
|
|
712
736
|
* Load a soundfile possibly containing several parts in the DSP struct.
|
|
@@ -1098,6 +1122,10 @@ export declare class FaustOfflineProcessor<Poly extends boolean = false> {
|
|
|
1098
1122
|
start(): void;
|
|
1099
1123
|
stop(): void;
|
|
1100
1124
|
destroy(): void;
|
|
1125
|
+
get hasAccInput(): boolean;
|
|
1126
|
+
propagateAcc(accelerationIncludingGravity: NonNullable<DeviceMotionEvent["accelerationIncludingGravity"]>): void;
|
|
1127
|
+
get hasGyrInput(): boolean;
|
|
1128
|
+
propagateGyr(event: Pick<DeviceOrientationEvent, "alpha" | "beta" | "gamma">): void;
|
|
1101
1129
|
/**
|
|
1102
1130
|
* Render frames in an array.
|
|
1103
1131
|
*
|
|
@@ -1239,6 +1267,7 @@ declare const FaustAudioWorkletNode_base: {
|
|
|
1239
1267
|
* Base class for Monophonic and Polyphonic AudioWorkletNode
|
|
1240
1268
|
*/
|
|
1241
1269
|
export declare class FaustAudioWorkletNode<Poly extends boolean = false> extends FaustAudioWorkletNode_base {
|
|
1270
|
+
#private;
|
|
1242
1271
|
protected fJSONDsp: FaustDspMeta;
|
|
1243
1272
|
protected fJSON: string;
|
|
1244
1273
|
protected fInputsItems: string[];
|
|
@@ -1248,6 +1277,8 @@ export declare class FaustAudioWorkletNode<Poly extends boolean = false> extends
|
|
|
1248
1277
|
protected fUICallback: UIHandler;
|
|
1249
1278
|
protected fDescriptor: FaustUIInputItem[];
|
|
1250
1279
|
constructor(context: BaseAudioContext, name: string, factory: LooseFaustDspFactory, options: FaustAudioWorkletNodeOptions<Poly>["processorOptions"], nodeOptions?: Partial<FaustAudioWorkletNodeOptions>);
|
|
1280
|
+
/** Setup accelerometer and gyroscope handlers */
|
|
1281
|
+
listenMotion(): Promise<void>;
|
|
1251
1282
|
setOutputParamHandler(handler: OutputParamHandler | null): void;
|
|
1252
1283
|
getOutputParamHandler(): OutputParamHandler | null;
|
|
1253
1284
|
setComputeHandler(handler: ComputeHandler | null): void;
|
|
@@ -1261,6 +1292,10 @@ export declare class FaustAudioWorkletNode<Poly extends boolean = false> extends
|
|
|
1261
1292
|
midiMessage(data: number[] | Uint8Array): void;
|
|
1262
1293
|
ctrlChange(channel: number, ctrl: number, value: number): void;
|
|
1263
1294
|
pitchWheel(channel: number, wheel: number): void;
|
|
1295
|
+
get hasAccInput(): boolean;
|
|
1296
|
+
propagateAcc(accelerationIncludingGravity: NonNullable<DeviceMotionEvent["accelerationIncludingGravity"]>): void;
|
|
1297
|
+
get hasGyrInput(): boolean;
|
|
1298
|
+
propagateGyr(event: Pick<DeviceOrientationEvent, "alpha" | "beta" | "gamma">): void;
|
|
1264
1299
|
setParamValue(path: string, value: number): void;
|
|
1265
1300
|
getParamValue(path: string): number;
|
|
1266
1301
|
getParams(): string[];
|
|
@@ -1305,6 +1340,8 @@ export declare class FaustScriptProcessorNode<Poly extends boolean = false> exte
|
|
|
1305
1340
|
protected fInputs: Float32Array[];
|
|
1306
1341
|
protected fOutputs: Float32Array[];
|
|
1307
1342
|
init(instance: Poly extends true ? FaustPolyWebAudioDsp : FaustMonoWebAudioDsp): void;
|
|
1343
|
+
/** Setup accelerometer and gyroscope handlers */
|
|
1344
|
+
listenMotion(): Promise<void>;
|
|
1308
1345
|
compute(input: Float32Array[], output: Float32Array[]): boolean;
|
|
1309
1346
|
setOutputParamHandler(handler: OutputParamHandler): void;
|
|
1310
1347
|
getOutputParamHandler(): OutputParamHandler | null;
|
|
@@ -1328,6 +1365,10 @@ export declare class FaustScriptProcessorNode<Poly extends boolean = false> exte
|
|
|
1328
1365
|
start(): void;
|
|
1329
1366
|
stop(): void;
|
|
1330
1367
|
destroy(): void;
|
|
1368
|
+
get hasAccInput(): boolean;
|
|
1369
|
+
propagateAcc(accelerationIncludingGravity: NonNullable<DeviceMotionEvent["accelerationIncludingGravity"]>): void;
|
|
1370
|
+
get hasGyrInput(): boolean;
|
|
1371
|
+
propagateGyr(event: Pick<DeviceOrientationEvent, "alpha" | "beta" | "gamma">): void;
|
|
1331
1372
|
}
|
|
1332
1373
|
export declare class FaustMonoScriptProcessorNode extends FaustScriptProcessorNode<false> implements IFaustMonoWebAudioDsp {
|
|
1333
1374
|
}
|