@grame/faustwasm 0.8.2 → 0.9.1
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/create-node.js +15 -8
- package/assets/standalone/faustwasm/index.d.ts +40 -0
- package/assets/standalone/faustwasm/index.js +109 -30
- package/assets/standalone/faustwasm/index.js.map +2 -2
- package/assets/standalone/index-pwa.js +1 -1
- package/assets/standalone/service-worker.js +58 -5
- package/dist/cjs/index.d.ts +40 -0
- package/dist/cjs/index.js +109 -30
- package/dist/cjs/index.js.map +2 -2
- package/dist/cjs-bundle/index.d.ts +40 -0
- package/dist/cjs-bundle/index.js +109 -30
- package/dist/cjs-bundle/index.js.map +2 -2
- package/dist/esm/index.d.ts +40 -0
- package/dist/esm/index.js +109 -30
- package/dist/esm/index.js.map +2 -2
- package/dist/esm-bundle/index.d.ts +40 -0
- package/dist/esm-bundle/index.js +109 -30
- package/dist/esm-bundle/index.js.map +2 -2
- package/package.json +1 -1
- package/src/FaustAudioWorkletNode.ts +10 -0
- package/src/FaustAudioWorkletProcessor.ts +16 -0
- package/src/FaustOfflineProcessor.ts +2 -0
- package/src/FaustScriptProcessorNode.ts +2 -0
- package/src/FaustWebAudioDsp.ts +88 -0
- package/src/copyWebStandaloneAssets.js +14 -0
- package/test/faustlive-wasm/faustwasm/index.d.ts +40 -0
- package/test/faustlive-wasm/faustwasm/index.js +109 -30
- package/test/faustlive-wasm/faustwasm/index.js.map +2 -2
- package/test/midi.dsp +8 -1
|
@@ -80,15 +80,15 @@ const createFaustNode = async (audioContext, dspName = "template", voices = 0, s
|
|
|
80
80
|
}
|
|
81
81
|
|
|
82
82
|
/**
|
|
83
|
-
* Connects an audio input stream to a Faust
|
|
83
|
+
* Connects an audio input stream to a Faust WebAudio node.
|
|
84
84
|
*
|
|
85
85
|
* @param {AudioContext} audioContext - The Web Audio API AudioContext to which the Faust audio node is connected.
|
|
86
86
|
* @param {string} id - The ID of the audio input device to connect.
|
|
87
87
|
* @param {FaustNode} faustNode - The Faust audio node to which the audio input stream will be connected.
|
|
88
|
-
* @param {MediaStreamAudioSourceNode}
|
|
89
|
-
* @returns {Promise<MediaStreamAudioSourceNode>} - The audio input stream node connected to the Faust audio node.
|
|
88
|
+
* @param {MediaStreamAudioSourceNode} oldInputStreamNode - The old audio input stream node to be disconnected from the Faust audio node.
|
|
89
|
+
* @returns {Promise<MediaStreamAudioSourceNode>} - The new audio input stream node connected to the Faust audio node.
|
|
90
90
|
*/
|
|
91
|
-
async function connectToAudioInput(audioContext, id, faustNode,
|
|
91
|
+
async function connectToAudioInput(audioContext, id, faustNode, oldInputStreamNode) {
|
|
92
92
|
// Create an audio input stream node
|
|
93
93
|
const constraints = {
|
|
94
94
|
audio: {
|
|
@@ -101,14 +101,18 @@ async function connectToAudioInput(audioContext, id, faustNode, inputStreamNode)
|
|
|
101
101
|
// Get the audio input stream
|
|
102
102
|
const stream = await navigator.mediaDevices.getUserMedia(constraints);
|
|
103
103
|
if (stream) {
|
|
104
|
-
if (
|
|
105
|
-
|
|
106
|
-
|
|
104
|
+
if (oldInputStreamNode) oldInputStreamNode.disconnect();
|
|
105
|
+
const newInputStreamNode = audioContext.createMediaStreamSource(stream);
|
|
106
|
+
newInputStreamNode.connect(faustNode);
|
|
107
|
+
return newInputStreamNode;
|
|
108
|
+
} else {
|
|
109
|
+
return oldInputStreamNode;
|
|
107
110
|
}
|
|
108
|
-
return inputStreamNode;
|
|
109
111
|
};
|
|
110
112
|
|
|
111
113
|
/**
|
|
114
|
+
* Creates a Faust UI for a Faust audio node.
|
|
115
|
+
*
|
|
112
116
|
* @param {FaustAudioWorkletNode} faustNode
|
|
113
117
|
*/
|
|
114
118
|
async function createFaustUI(divFaustUI, faustNode) {
|
|
@@ -135,6 +139,9 @@ async function createFaustUI(divFaustUI, faustNode) {
|
|
|
135
139
|
faustUI.resize();
|
|
136
140
|
};
|
|
137
141
|
|
|
142
|
+
/**
|
|
143
|
+
* Request permission to use motion and orientation sensors.
|
|
144
|
+
*/
|
|
138
145
|
async function requestPermissions() {
|
|
139
146
|
|
|
140
147
|
// Explicitly request permission on iOS before calling startSensors()
|
|
@@ -618,6 +618,20 @@ export interface IFaustBaseWebAudioDsp {
|
|
|
618
618
|
* @param value - the MIDI controller value (0..16383)
|
|
619
619
|
*/
|
|
620
620
|
pitchWheel(chan: number, value: number): void;
|
|
621
|
+
/**
|
|
622
|
+
* Handle MIDI keyOn messages.
|
|
623
|
+
* @param channel
|
|
624
|
+
* @param pitch
|
|
625
|
+
* @param velocity
|
|
626
|
+
*/
|
|
627
|
+
keyOn(channel: number, pitch: number, velocity: number): void;
|
|
628
|
+
/**
|
|
629
|
+
* Handle MIDI keyOn messages.
|
|
630
|
+
* @param channel
|
|
631
|
+
* @param pitch
|
|
632
|
+
* @param velocity
|
|
633
|
+
*/
|
|
634
|
+
keyOff(channel: number, pitch: number, velocity: number): void;
|
|
621
635
|
/**
|
|
622
636
|
* Set parameter value.
|
|
623
637
|
*
|
|
@@ -767,6 +781,24 @@ export declare class FaustBaseWebAudioDsp implements IFaustBaseWebAudioDsp {
|
|
|
767
781
|
min: number;
|
|
768
782
|
max: number;
|
|
769
783
|
}[][];
|
|
784
|
+
protected fMidiKeyLabel: {
|
|
785
|
+
path: string;
|
|
786
|
+
chan: number;
|
|
787
|
+
min: number;
|
|
788
|
+
max: number;
|
|
789
|
+
}[][];
|
|
790
|
+
protected fMidiKeyOnLabel: {
|
|
791
|
+
path: string;
|
|
792
|
+
chan: number;
|
|
793
|
+
min: number;
|
|
794
|
+
max: number;
|
|
795
|
+
}[][];
|
|
796
|
+
protected fMidiKeyOffLabel: {
|
|
797
|
+
path: string;
|
|
798
|
+
chan: number;
|
|
799
|
+
min: number;
|
|
800
|
+
max: number;
|
|
801
|
+
}[][];
|
|
770
802
|
protected fPathTable: {
|
|
771
803
|
[address: string]: number;
|
|
772
804
|
};
|
|
@@ -826,6 +858,8 @@ export declare class FaustBaseWebAudioDsp implements IFaustBaseWebAudioDsp {
|
|
|
826
858
|
getNumOutputs(): number;
|
|
827
859
|
midiMessage(data: number[] | Uint8Array): void;
|
|
828
860
|
ctrlChange(channel: number, ctrl: number, value: number): void;
|
|
861
|
+
keyOn(channel: number, pitch: number, velocity: number): void;
|
|
862
|
+
keyOff(channel: number, pitch: number, velocity: number): void;
|
|
829
863
|
pitchWheel(channel: number, wheel: number): void;
|
|
830
864
|
setParamValue(path: string, value: number): void;
|
|
831
865
|
getParamValue(path: string): number;
|
|
@@ -1180,6 +1214,8 @@ export declare class FaustOfflineProcessor<Poly extends boolean = false> {
|
|
|
1180
1214
|
midiMessage(data: number[] | Uint8Array): void;
|
|
1181
1215
|
ctrlChange(chan: number, ctrl: number, value: number): void;
|
|
1182
1216
|
pitchWheel(chan: number, value: number): void;
|
|
1217
|
+
keyOn(channel: number, pitch: number, velocity: number): void;
|
|
1218
|
+
keyOff(channel: number, pitch: number, velocity: number): void;
|
|
1183
1219
|
setParamValue(path: string, value: number): void;
|
|
1184
1220
|
getParamValue(path: string): number;
|
|
1185
1221
|
getParams(): string[];
|
|
@@ -1374,6 +1410,8 @@ export declare class FaustAudioWorkletNode<Poly extends boolean = false> extends
|
|
|
1374
1410
|
midiMessage(data: number[] | Uint8Array): void;
|
|
1375
1411
|
ctrlChange(channel: number, ctrl: number, value: number): void;
|
|
1376
1412
|
pitchWheel(channel: number, wheel: number): void;
|
|
1413
|
+
keyOn(channel: number, pitch: number, velocity: number): void;
|
|
1414
|
+
keyOff(channel: number, pitch: number, velocity: number): void;
|
|
1377
1415
|
get hasAccInput(): boolean;
|
|
1378
1416
|
propagateAcc(accelerationIncludingGravity: NonNullable<DeviceMotionEvent["accelerationIncludingGravity"]>, invert?: boolean): void;
|
|
1379
1417
|
get hasGyrInput(): boolean;
|
|
@@ -1441,6 +1479,8 @@ export declare class FaustScriptProcessorNode<Poly extends boolean = false> exte
|
|
|
1441
1479
|
midiMessage(data: number[] | Uint8Array): void;
|
|
1442
1480
|
ctrlChange(chan: number, ctrl: number, value: number): void;
|
|
1443
1481
|
pitchWheel(chan: number, value: number): void;
|
|
1482
|
+
keyOn(channel: number, pitch: number, velocity: number): void;
|
|
1483
|
+
keyOff(channel: number, pitch: number, velocity: number): void;
|
|
1444
1484
|
setParamValue(path: string, value: number): void;
|
|
1445
1485
|
getParamValue(path: string): number;
|
|
1446
1486
|
getParams(): string[];
|
|
@@ -186,6 +186,14 @@ var getFaustAudioWorkletProcessor = (dependencies, faustData, register = true) =
|
|
|
186
186
|
this.pitchWheel(msg.data[0], msg.data[1]);
|
|
187
187
|
break;
|
|
188
188
|
}
|
|
189
|
+
case "keyOn": {
|
|
190
|
+
this.keyOn(msg.data[0], msg.data[1], msg.data[2]);
|
|
191
|
+
break;
|
|
192
|
+
}
|
|
193
|
+
case "keyOff": {
|
|
194
|
+
this.keyOff(msg.data[0], msg.data[1], msg.data[2]);
|
|
195
|
+
break;
|
|
196
|
+
}
|
|
189
197
|
case "param": {
|
|
190
198
|
this.setParamValue(msg.data.path, msg.data.value);
|
|
191
199
|
break;
|
|
@@ -232,6 +240,12 @@ var getFaustAudioWorkletProcessor = (dependencies, faustData, register = true) =
|
|
|
232
240
|
pitchWheel(channel, wheel) {
|
|
233
241
|
this.fDSPCode.pitchWheel(channel, wheel);
|
|
234
242
|
}
|
|
243
|
+
keyOn(channel, pitch, velocity) {
|
|
244
|
+
this.fDSPCode.keyOn(channel, pitch, velocity);
|
|
245
|
+
}
|
|
246
|
+
keyOff(channel, pitch, velocity) {
|
|
247
|
+
this.fDSPCode.keyOff(channel, pitch, velocity);
|
|
248
|
+
}
|
|
235
249
|
propagateAcc(accelerationIncludingGravity, invert = false) {
|
|
236
250
|
this.fDSPCode.propagateAcc(accelerationIncludingGravity, invert);
|
|
237
251
|
}
|
|
@@ -2112,6 +2126,10 @@ var FaustBaseWebAudioDsp = class _FaustBaseWebAudioDsp {
|
|
|
2112
2126
|
// MIDI handling
|
|
2113
2127
|
this.fPitchwheelLabel = [];
|
|
2114
2128
|
this.fCtrlLabel = new Array(128).fill(null).map(() => []);
|
|
2129
|
+
// array of MIDI key handlers; array index is the MIDI note number
|
|
2130
|
+
this.fMidiKeyLabel = new Array(128).fill(null).map(() => []);
|
|
2131
|
+
this.fMidiKeyOnLabel = new Array(128).fill(null).map(() => []);
|
|
2132
|
+
this.fMidiKeyOffLabel = new Array(128).fill(null).map(() => []);
|
|
2115
2133
|
this.fPathTable = {};
|
|
2116
2134
|
this.fUICallback = (item) => {
|
|
2117
2135
|
if (item.type === "hbargraph" || item.type === "vbargraph") {
|
|
@@ -2124,6 +2142,7 @@ var FaustBaseWebAudioDsp = class _FaustBaseWebAudioDsp {
|
|
|
2124
2142
|
if (!item.meta)
|
|
2125
2143
|
return;
|
|
2126
2144
|
item.meta.forEach((meta) => {
|
|
2145
|
+
var _a, _b, _c, _d, _e, _f;
|
|
2127
2146
|
const { midi, acc, gyr } = meta;
|
|
2128
2147
|
if (midi) {
|
|
2129
2148
|
const strMidi = midi.trim();
|
|
@@ -2137,10 +2156,25 @@ var FaustBaseWebAudioDsp = class _FaustBaseWebAudioDsp {
|
|
|
2137
2156
|
} else {
|
|
2138
2157
|
const matched2 = strMidi.match(/^ctrl\s(\d+)\s(\d+)/);
|
|
2139
2158
|
const matched1 = strMidi.match(/^ctrl\s(\d+)/);
|
|
2159
|
+
const matchedKey = strMidi.match(/^key\s+(\d+)(?:\s+(\d+))?$/);
|
|
2160
|
+
const matchedKeyOn = strMidi.match(/^keyon\s+(\d+)(?:\s+(\d+))?$/);
|
|
2161
|
+
const matchedKeyOff = strMidi.match(/^keyoff\s+(\d+)(?:\s+(\d+))?$/);
|
|
2140
2162
|
if (matched2) {
|
|
2141
2163
|
this.fCtrlLabel[parseInt(matched2[1])].push({ path: item.address, chan: parseInt(matched2[2]), min: item.min, max: item.max });
|
|
2142
2164
|
} else if (matched1) {
|
|
2143
2165
|
this.fCtrlLabel[parseInt(matched1[1])].push({ path: item.address, chan: 0, min: item.min, max: item.max });
|
|
2166
|
+
} else if (matchedKey) {
|
|
2167
|
+
const note = parseInt(matchedKey[1]);
|
|
2168
|
+
const channel = matchedKey[2] ? parseInt(matchedKey[2]) : 0;
|
|
2169
|
+
this.fMidiKeyLabel[note].push({ path: item.address, chan: channel, min: (_a = item.min) != null ? _a : 0, max: (_b = item.max) != null ? _b : 1 });
|
|
2170
|
+
} else if (matchedKeyOn) {
|
|
2171
|
+
const note = parseInt(matchedKeyOn[1]);
|
|
2172
|
+
const channel = matchedKeyOn[2] ? parseInt(matchedKeyOn[2]) : 0;
|
|
2173
|
+
this.fMidiKeyOnLabel[note].push({ path: item.address, chan: channel, min: (_c = item.min) != null ? _c : 0, max: (_d = item.max) != null ? _d : 1 });
|
|
2174
|
+
} else if (matchedKeyOff) {
|
|
2175
|
+
const note = parseInt(matchedKeyOff[1]);
|
|
2176
|
+
const channel = matchedKeyOff[2] ? parseInt(matchedKeyOff[2]) : 0;
|
|
2177
|
+
this.fMidiKeyOffLabel[note].push({ path: item.address, chan: channel, min: (_e = item.min) != null ? _e : 0, max: (_f = item.max) != null ? _f : 1 });
|
|
2144
2178
|
}
|
|
2145
2179
|
}
|
|
2146
2180
|
}
|
|
@@ -2402,6 +2436,15 @@ var FaustBaseWebAudioDsp = class _FaustBaseWebAudioDsp {
|
|
|
2402
2436
|
return this.ctrlChange(channel, data1, data2);
|
|
2403
2437
|
if (cmd === 14)
|
|
2404
2438
|
return this.pitchWheel(channel, data2 * 128 + data1);
|
|
2439
|
+
if (cmd === 9) {
|
|
2440
|
+
if (data2 > 0)
|
|
2441
|
+
return this.keyOn(channel, data1, data2);
|
|
2442
|
+
else
|
|
2443
|
+
return this.keyOff(channel, data1, data2);
|
|
2444
|
+
}
|
|
2445
|
+
if (cmd === 8) {
|
|
2446
|
+
return this.keyOff(channel, data1, data2);
|
|
2447
|
+
}
|
|
2405
2448
|
}
|
|
2406
2449
|
ctrlChange(channel, ctrl, value) {
|
|
2407
2450
|
if (this.fPlotHandler)
|
|
@@ -2417,6 +2460,46 @@ var FaustBaseWebAudioDsp = class _FaustBaseWebAudioDsp {
|
|
|
2417
2460
|
});
|
|
2418
2461
|
}
|
|
2419
2462
|
}
|
|
2463
|
+
keyOn(channel, pitch, velocity) {
|
|
2464
|
+
if (this.fPlotHandler)
|
|
2465
|
+
this.fCachedEvents.push({ type: "keyOn", data: [channel, pitch, velocity] });
|
|
2466
|
+
this.fMidiKeyOnLabel[pitch].forEach((key) => {
|
|
2467
|
+
const { path, chan } = key;
|
|
2468
|
+
if (chan === 0 || channel === chan - 1) {
|
|
2469
|
+
this.setParamValue(path, _FaustBaseWebAudioDsp.remap(velocity, 0, 127, key.min, key.max));
|
|
2470
|
+
if (this.fOutputHandler)
|
|
2471
|
+
this.fOutputHandler(path, this.getParamValue(path));
|
|
2472
|
+
}
|
|
2473
|
+
});
|
|
2474
|
+
this.fMidiKeyLabel[pitch].forEach((key) => {
|
|
2475
|
+
const { path, chan } = key;
|
|
2476
|
+
if (chan === 0 || channel === chan - 1) {
|
|
2477
|
+
this.setParamValue(path, _FaustBaseWebAudioDsp.remap(velocity, 0, 127, key.min, key.max));
|
|
2478
|
+
if (this.fOutputHandler)
|
|
2479
|
+
this.fOutputHandler(path, this.getParamValue(path));
|
|
2480
|
+
}
|
|
2481
|
+
});
|
|
2482
|
+
}
|
|
2483
|
+
keyOff(channel, pitch, velocity) {
|
|
2484
|
+
if (this.fPlotHandler)
|
|
2485
|
+
this.fCachedEvents.push({ type: "keyOff", data: [channel, pitch, velocity] });
|
|
2486
|
+
this.fMidiKeyOffLabel[pitch].forEach((key) => {
|
|
2487
|
+
const { path, chan } = key;
|
|
2488
|
+
if (chan === 0 || channel === chan - 1) {
|
|
2489
|
+
this.setParamValue(path, _FaustBaseWebAudioDsp.remap(velocity, 0, 127, key.min, key.max));
|
|
2490
|
+
if (this.fOutputHandler)
|
|
2491
|
+
this.fOutputHandler(path, this.getParamValue(path));
|
|
2492
|
+
}
|
|
2493
|
+
});
|
|
2494
|
+
this.fMidiKeyLabel[pitch].forEach((key) => {
|
|
2495
|
+
const { path, chan } = key;
|
|
2496
|
+
if (chan === 0 || channel === chan - 1) {
|
|
2497
|
+
this.setParamValue(path, 0);
|
|
2498
|
+
if (this.fOutputHandler)
|
|
2499
|
+
this.fOutputHandler(path, this.getParamValue(path));
|
|
2500
|
+
}
|
|
2501
|
+
});
|
|
2502
|
+
}
|
|
2420
2503
|
pitchWheel(channel, wheel) {
|
|
2421
2504
|
if (this.fPlotHandler)
|
|
2422
2505
|
this.fCachedEvents.push({ type: "pitchWheel", data: [channel, wheel] });
|
|
@@ -3053,6 +3136,12 @@ var FaustOfflineProcessor = class {
|
|
|
3053
3136
|
pitchWheel(chan, value) {
|
|
3054
3137
|
this.fDSPCode.pitchWheel(chan, value);
|
|
3055
3138
|
}
|
|
3139
|
+
keyOn(channel, pitch, velocity) {
|
|
3140
|
+
this.fDSPCode.keyOn(channel, pitch, velocity);
|
|
3141
|
+
}
|
|
3142
|
+
keyOff(channel, pitch, velocity) {
|
|
3143
|
+
this.fDSPCode.keyOff(channel, pitch, velocity);
|
|
3144
|
+
}
|
|
3056
3145
|
setParamValue(path, value) {
|
|
3057
3146
|
this.fDSPCode.setParamValue(path, value);
|
|
3058
3147
|
}
|
|
@@ -3989,6 +4078,10 @@ var FaustAudioWorkletNode = class extends (globalThis.AudioWorkletNode || null)
|
|
|
3989
4078
|
this.ctrlChange(channel, data1, data2);
|
|
3990
4079
|
else if (cmd === 14)
|
|
3991
4080
|
this.pitchWheel(channel, data2 * 128 + data1);
|
|
4081
|
+
if (cmd === 8 || cmd === 9 && data2 === 0)
|
|
4082
|
+
this.keyOff(channel, data1, data2);
|
|
4083
|
+
else if (cmd === 9)
|
|
4084
|
+
this.keyOn(channel, data1, data2);
|
|
3992
4085
|
else
|
|
3993
4086
|
this.port.postMessage({ type: "midi", data });
|
|
3994
4087
|
}
|
|
@@ -4000,6 +4093,14 @@ var FaustAudioWorkletNode = class extends (globalThis.AudioWorkletNode || null)
|
|
|
4000
4093
|
const e = { type: "pitchWheel", data: [channel, wheel] };
|
|
4001
4094
|
this.port.postMessage(e);
|
|
4002
4095
|
}
|
|
4096
|
+
keyOn(channel, pitch, velocity) {
|
|
4097
|
+
const e = { type: "keyOn", data: [channel, pitch, velocity] };
|
|
4098
|
+
this.port.postMessage(e);
|
|
4099
|
+
}
|
|
4100
|
+
keyOff(channel, pitch, velocity) {
|
|
4101
|
+
const e = { type: "keyOff", data: [channel, pitch, velocity] };
|
|
4102
|
+
this.port.postMessage(e);
|
|
4103
|
+
}
|
|
4003
4104
|
get hasAccInput() {
|
|
4004
4105
|
return __privateGet(this, _hasAccInput);
|
|
4005
4106
|
}
|
|
@@ -4163,42 +4264,14 @@ var FaustScriptProcessorNode = class extends (globalThis.ScriptProcessorNode ||
|
|
|
4163
4264
|
async startSensors() {
|
|
4164
4265
|
if (this.hasAccInput) {
|
|
4165
4266
|
if (window.DeviceMotionEvent) {
|
|
4166
|
-
|
|
4167
|
-
try {
|
|
4168
|
-
const response = await window.DeviceMotionEvent.requestPermission();
|
|
4169
|
-
if (response === "granted") {
|
|
4170
|
-
window.addEventListener("devicemotion", this.handleDeviceMotion, true);
|
|
4171
|
-
} else if (response === "denied") {
|
|
4172
|
-
alert("You have denied access to motion and orientation data. To enable it, go to Settings > Safari > Motion & Orientation Access.");
|
|
4173
|
-
throw new Error("Unable to access the accelerometer.");
|
|
4174
|
-
}
|
|
4175
|
-
} catch (error) {
|
|
4176
|
-
console.error(error);
|
|
4177
|
-
}
|
|
4178
|
-
} else {
|
|
4179
|
-
window.addEventListener("devicemotion", this.handleDeviceMotion, true);
|
|
4180
|
-
}
|
|
4267
|
+
window.addEventListener("devicemotion", this.handleDeviceMotion, true);
|
|
4181
4268
|
} else {
|
|
4182
4269
|
console.log("Cannot set the accelerometer handler.");
|
|
4183
4270
|
}
|
|
4184
4271
|
}
|
|
4185
4272
|
if (this.hasGyrInput) {
|
|
4186
4273
|
if (window.DeviceMotionEvent) {
|
|
4187
|
-
|
|
4188
|
-
try {
|
|
4189
|
-
const response = await window.DeviceOrientationEvent.requestPermission();
|
|
4190
|
-
if (response === "granted") {
|
|
4191
|
-
window.addEventListener("deviceorientation", this.handleDeviceOrientation, true);
|
|
4192
|
-
} else if (response === "denied") {
|
|
4193
|
-
alert("You have denied access to motion and orientation data. To enable it, go to Settings > Safari > Motion & Orientation Access.");
|
|
4194
|
-
throw new Error("Unable to access the gyroscope.");
|
|
4195
|
-
}
|
|
4196
|
-
} catch (error) {
|
|
4197
|
-
console.error(error);
|
|
4198
|
-
}
|
|
4199
|
-
} else {
|
|
4200
|
-
window.addEventListener("deviceorientation", this.handleDeviceOrientation, true);
|
|
4201
|
-
}
|
|
4274
|
+
window.addEventListener("deviceorientation", this.handleDeviceOrientation, true);
|
|
4202
4275
|
} else {
|
|
4203
4276
|
console.log("Cannot set the gyroscope handler.");
|
|
4204
4277
|
}
|
|
@@ -4251,6 +4324,12 @@ var FaustScriptProcessorNode = class extends (globalThis.ScriptProcessorNode ||
|
|
|
4251
4324
|
pitchWheel(chan, value) {
|
|
4252
4325
|
this.fDSPCode.pitchWheel(chan, value);
|
|
4253
4326
|
}
|
|
4327
|
+
keyOn(channel, pitch, velocity) {
|
|
4328
|
+
this.fDSPCode.keyOn(channel, pitch, velocity);
|
|
4329
|
+
}
|
|
4330
|
+
keyOff(channel, pitch, velocity) {
|
|
4331
|
+
this.fDSPCode.keyOff(channel, pitch, velocity);
|
|
4332
|
+
}
|
|
4254
4333
|
setParamValue(path, value) {
|
|
4255
4334
|
this.fDSPCode.setParamValue(path, value);
|
|
4256
4335
|
}
|