@grame/faustwasm 0.8.0 → 0.9.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 (67) hide show
  1. package/assets/standalone/create-node.js +46 -9
  2. package/assets/standalone/faust-ui/index.js +2 -2
  3. package/assets/standalone/faust-ui/index.js.map +1 -1
  4. package/assets/standalone/faustwasm/index.d.ts +42 -2
  5. package/assets/standalone/faustwasm/index.js +117 -66
  6. package/assets/standalone/faustwasm/index.js.map +2 -2
  7. package/assets/standalone/index-pwa.js +125 -90
  8. package/assets/standalone/index-template.js +43 -22
  9. package/assets/standalone/index.js +36 -19
  10. package/assets/standalone/service-worker.js +58 -5
  11. package/dist/cjs/index.d.ts +42 -2
  12. package/dist/cjs/index.js +117 -66
  13. package/dist/cjs/index.js.map +2 -2
  14. package/dist/cjs-bundle/index.d.ts +42 -2
  15. package/dist/cjs-bundle/index.js +117 -66
  16. package/dist/cjs-bundle/index.js.map +2 -2
  17. package/dist/esm/index.d.ts +42 -2
  18. package/dist/esm/index.js +117 -66
  19. package/dist/esm/index.js.map +2 -2
  20. package/dist/esm-bundle/index.d.ts +42 -2
  21. package/dist/esm-bundle/index.js +117 -66
  22. package/dist/esm-bundle/index.js.map +2 -2
  23. package/package.json +2 -2
  24. package/src/FaustAudioWorkletNode.ts +14 -30
  25. package/src/FaustAudioWorkletProcessor.ts +16 -0
  26. package/src/FaustOfflineProcessor.ts +2 -0
  27. package/src/FaustScriptProcessorNode.ts +6 -30
  28. package/src/FaustWebAudioDsp.ts +88 -0
  29. package/src/copyWebStandaloneAssets.js +14 -0
  30. package/test/faustlive-wasm/faust-ui/index.js +2 -2
  31. package/test/faustlive-wasm/faust-ui/index.js.map +1 -1
  32. package/test/faustlive-wasm/faustwasm/index.d.ts +42 -2
  33. package/test/faustlive-wasm/faustwasm/index.js +117 -66
  34. package/test/faustlive-wasm/faustwasm/index.js.map +2 -2
  35. package/test/midi/create-node.js +177 -0
  36. package/test/midi/dsp-meta.json +133 -0
  37. package/test/midi/dsp-module.wasm +0 -0
  38. package/test/midi/faust-ui/index.css +442 -0
  39. package/test/midi/faust-ui/index.css.map +1 -0
  40. package/test/midi/faust-ui/index.d.ts +1 -0
  41. package/test/midi/faust-ui/index.js +3729 -0
  42. package/test/midi/faust-ui/index.js.map +1 -0
  43. package/test/midi/faustwasm/index.d.ts +1680 -0
  44. package/test/midi/faustwasm/index.js +4884 -0
  45. package/test/midi/faustwasm/index.js.map +7 -0
  46. package/test/midi/icon.png +0 -0
  47. package/test/midi/index.html +76 -0
  48. package/test/midi/index.js +183 -0
  49. package/test/midi/manifest.json +17 -0
  50. package/test/midi/service-worker.js +165 -0
  51. package/test/midi.dsp +8 -1
  52. package/test/organ1/create-node.js +177 -0
  53. package/test/organ1/dsp-meta.json +126 -0
  54. package/test/organ1/dsp-module.wasm +0 -0
  55. package/test/organ1/faust-ui/index.css +442 -0
  56. package/test/organ1/faust-ui/index.css.map +1 -0
  57. package/test/organ1/faust-ui/index.d.ts +1 -0
  58. package/test/organ1/faust-ui/index.js +3729 -0
  59. package/test/organ1/faust-ui/index.js.map +1 -0
  60. package/test/organ1/faustwasm/index.d.ts +1656 -0
  61. package/test/organ1/faustwasm/index.js +4783 -0
  62. package/test/organ1/faustwasm/index.js.map +7 -0
  63. package/test/organ1/icon.png +0 -0
  64. package/test/organ1/index.html +76 -0
  65. package/test/organ1/index.js +203 -0
  66. package/test/organ1/manifest.json +17 -0
  67. package/test/organ1/service-worker.js +181 -0
@@ -625,6 +625,20 @@ export interface IFaustBaseWebAudioDsp {
625
625
  * @param value - the MIDI controller value (0..16383)
626
626
  */
627
627
  pitchWheel(chan: number, value: number): void;
628
+ /**
629
+ * Handle MIDI keyOn messages.
630
+ * @param channel
631
+ * @param pitch
632
+ * @param velocity
633
+ */
634
+ keyOn(channel: number, pitch: number, velocity: number): void;
635
+ /**
636
+ * Handle MIDI keyOn messages.
637
+ * @param channel
638
+ * @param pitch
639
+ * @param velocity
640
+ */
641
+ keyOff(channel: number, pitch: number, velocity: number): void;
628
642
  /**
629
643
  * Set parameter value.
630
644
  *
@@ -774,6 +788,24 @@ export declare class FaustBaseWebAudioDsp implements IFaustBaseWebAudioDsp {
774
788
  min: number;
775
789
  max: number;
776
790
  }[][];
791
+ protected fMidiKeyLabel: {
792
+ path: string;
793
+ chan: number;
794
+ min: number;
795
+ max: number;
796
+ }[][];
797
+ protected fMidiKeyOnLabel: {
798
+ path: string;
799
+ chan: number;
800
+ min: number;
801
+ max: number;
802
+ }[][];
803
+ protected fMidiKeyOffLabel: {
804
+ path: string;
805
+ chan: number;
806
+ min: number;
807
+ max: number;
808
+ }[][];
777
809
  protected fPathTable: {
778
810
  [address: string]: number;
779
811
  };
@@ -833,6 +865,8 @@ export declare class FaustBaseWebAudioDsp implements IFaustBaseWebAudioDsp {
833
865
  getNumOutputs(): number;
834
866
  midiMessage(data: number[] | Uint8Array): void;
835
867
  ctrlChange(channel: number, ctrl: number, value: number): void;
868
+ keyOn(channel: number, pitch: number, velocity: number): void;
869
+ keyOff(channel: number, pitch: number, velocity: number): void;
836
870
  pitchWheel(channel: number, wheel: number): void;
837
871
  setParamValue(path: string, value: number): void;
838
872
  getParamValue(path: string): number;
@@ -842,11 +876,11 @@ export declare class FaustBaseWebAudioDsp implements IFaustBaseWebAudioDsp {
842
876
  getUI(): FaustUIDescriptor;
843
877
  getDescriptors(): FaustUIInputItem[];
844
878
  hasSoundfiles(): boolean;
879
+ startSensors(): void;
880
+ stopSensors(): void;
845
881
  start(): void;
846
882
  stop(): void;
847
883
  destroy(): void;
848
- startSensors(): void;
849
- stopSensors(): void;
850
884
  }
851
885
  export declare class FaustMonoWebAudioDsp extends FaustBaseWebAudioDsp implements IFaustMonoWebAudioDsp {
852
886
  private fInstance;
@@ -1187,6 +1221,8 @@ export declare class FaustOfflineProcessor<Poly extends boolean = false> {
1187
1221
  midiMessage(data: number[] | Uint8Array): void;
1188
1222
  ctrlChange(chan: number, ctrl: number, value: number): void;
1189
1223
  pitchWheel(chan: number, value: number): void;
1224
+ keyOn(channel: number, pitch: number, velocity: number): void;
1225
+ keyOff(channel: number, pitch: number, velocity: number): void;
1190
1226
  setParamValue(path: string, value: number): void;
1191
1227
  getParamValue(path: string): number;
1192
1228
  getParams(): string[];
@@ -1381,6 +1417,8 @@ export declare class FaustAudioWorkletNode<Poly extends boolean = false> extends
1381
1417
  midiMessage(data: number[] | Uint8Array): void;
1382
1418
  ctrlChange(channel: number, ctrl: number, value: number): void;
1383
1419
  pitchWheel(channel: number, wheel: number): void;
1420
+ keyOn(channel: number, pitch: number, velocity: number): void;
1421
+ keyOff(channel: number, pitch: number, velocity: number): void;
1384
1422
  get hasAccInput(): boolean;
1385
1423
  propagateAcc(accelerationIncludingGravity: NonNullable<DeviceMotionEvent["accelerationIncludingGravity"]>, invert?: boolean): void;
1386
1424
  get hasGyrInput(): boolean;
@@ -1448,6 +1486,8 @@ export declare class FaustScriptProcessorNode<Poly extends boolean = false> exte
1448
1486
  midiMessage(data: number[] | Uint8Array): void;
1449
1487
  ctrlChange(chan: number, ctrl: number, value: number): void;
1450
1488
  pitchWheel(chan: number, value: number): void;
1489
+ keyOn(channel: number, pitch: number, velocity: number): void;
1490
+ keyOff(channel: number, pitch: number, velocity: number): void;
1451
1491
  setParamValue(path: string, value: number): void;
1452
1492
  getParamValue(path: string): number;
1453
1493
  getParams(): string[];
@@ -6233,6 +6233,14 @@ export default ${(_b = jsCode.match(jsCodeHead)) == null ? void 0 : _b[1]};
6233
6233
  this.pitchWheel(msg.data[0], msg.data[1]);
6234
6234
  break;
6235
6235
  }
6236
+ case "keyOn": {
6237
+ this.keyOn(msg.data[0], msg.data[1], msg.data[2]);
6238
+ break;
6239
+ }
6240
+ case "keyOff": {
6241
+ this.keyOff(msg.data[0], msg.data[1], msg.data[2]);
6242
+ break;
6243
+ }
6236
6244
  case "param": {
6237
6245
  this.setParamValue(msg.data.path, msg.data.value);
6238
6246
  break;
@@ -6279,6 +6287,12 @@ export default ${(_b = jsCode.match(jsCodeHead)) == null ? void 0 : _b[1]};
6279
6287
  pitchWheel(channel, wheel) {
6280
6288
  this.fDSPCode.pitchWheel(channel, wheel);
6281
6289
  }
6290
+ keyOn(channel, pitch, velocity) {
6291
+ this.fDSPCode.keyOn(channel, pitch, velocity);
6292
+ }
6293
+ keyOff(channel, pitch, velocity) {
6294
+ this.fDSPCode.keyOff(channel, pitch, velocity);
6295
+ }
6282
6296
  propagateAcc(accelerationIncludingGravity, invert = false) {
6283
6297
  this.fDSPCode.propagateAcc(accelerationIncludingGravity, invert);
6284
6298
  }
@@ -8159,6 +8173,10 @@ export default ${(_b = jsCode.match(jsCodeHead)) == null ? void 0 : _b[1]};
8159
8173
  // MIDI handling
8160
8174
  this.fPitchwheelLabel = [];
8161
8175
  this.fCtrlLabel = new Array(128).fill(null).map(() => []);
8176
+ // array of MIDI key handlers; array index is the MIDI note number
8177
+ this.fMidiKeyLabel = new Array(128).fill(null).map(() => []);
8178
+ this.fMidiKeyOnLabel = new Array(128).fill(null).map(() => []);
8179
+ this.fMidiKeyOffLabel = new Array(128).fill(null).map(() => []);
8162
8180
  this.fPathTable = {};
8163
8181
  this.fUICallback = (item) => {
8164
8182
  if (item.type === "hbargraph" || item.type === "vbargraph") {
@@ -8171,6 +8189,7 @@ export default ${(_b = jsCode.match(jsCodeHead)) == null ? void 0 : _b[1]};
8171
8189
  if (!item.meta)
8172
8190
  return;
8173
8191
  item.meta.forEach((meta) => {
8192
+ var _a, _b, _c, _d, _e, _f;
8174
8193
  const { midi, acc, gyr } = meta;
8175
8194
  if (midi) {
8176
8195
  const strMidi = midi.trim();
@@ -8184,10 +8203,25 @@ export default ${(_b = jsCode.match(jsCodeHead)) == null ? void 0 : _b[1]};
8184
8203
  } else {
8185
8204
  const matched2 = strMidi.match(/^ctrl\s(\d+)\s(\d+)/);
8186
8205
  const matched1 = strMidi.match(/^ctrl\s(\d+)/);
8206
+ const matchedKey = strMidi.match(/^key\s+(\d+)(?:\s+(\d+))?$/);
8207
+ const matchedKeyOn = strMidi.match(/^keyon\s+(\d+)(?:\s+(\d+))?$/);
8208
+ const matchedKeyOff = strMidi.match(/^keyoff\s+(\d+)(?:\s+(\d+))?$/);
8187
8209
  if (matched2) {
8188
8210
  this.fCtrlLabel[parseInt(matched2[1])].push({ path: item.address, chan: parseInt(matched2[2]), min: item.min, max: item.max });
8189
8211
  } else if (matched1) {
8190
8212
  this.fCtrlLabel[parseInt(matched1[1])].push({ path: item.address, chan: 0, min: item.min, max: item.max });
8213
+ } else if (matchedKey) {
8214
+ const note = parseInt(matchedKey[1]);
8215
+ const channel = matchedKey[2] ? parseInt(matchedKey[2]) : 0;
8216
+ this.fMidiKeyLabel[note].push({ path: item.address, chan: channel, min: (_a = item.min) != null ? _a : 0, max: (_b = item.max) != null ? _b : 1 });
8217
+ } else if (matchedKeyOn) {
8218
+ const note = parseInt(matchedKeyOn[1]);
8219
+ const channel = matchedKeyOn[2] ? parseInt(matchedKeyOn[2]) : 0;
8220
+ this.fMidiKeyOnLabel[note].push({ path: item.address, chan: channel, min: (_c = item.min) != null ? _c : 0, max: (_d = item.max) != null ? _d : 1 });
8221
+ } else if (matchedKeyOff) {
8222
+ const note = parseInt(matchedKeyOff[1]);
8223
+ const channel = matchedKeyOff[2] ? parseInt(matchedKeyOff[2]) : 0;
8224
+ this.fMidiKeyOffLabel[note].push({ path: item.address, chan: channel, min: (_e = item.min) != null ? _e : 0, max: (_f = item.max) != null ? _f : 1 });
8191
8225
  }
8192
8226
  }
8193
8227
  }
@@ -8449,6 +8483,15 @@ export default ${(_b = jsCode.match(jsCodeHead)) == null ? void 0 : _b[1]};
8449
8483
  return this.ctrlChange(channel, data1, data2);
8450
8484
  if (cmd === 14)
8451
8485
  return this.pitchWheel(channel, data2 * 128 + data1);
8486
+ if (cmd === 9) {
8487
+ if (data2 > 0)
8488
+ return this.keyOn(channel, data1, data2);
8489
+ else
8490
+ return this.keyOff(channel, data1, data2);
8491
+ }
8492
+ if (cmd === 8) {
8493
+ return this.keyOff(channel, data1, data2);
8494
+ }
8452
8495
  }
8453
8496
  ctrlChange(channel, ctrl, value) {
8454
8497
  if (this.fPlotHandler)
@@ -8464,6 +8507,46 @@ export default ${(_b = jsCode.match(jsCodeHead)) == null ? void 0 : _b[1]};
8464
8507
  });
8465
8508
  }
8466
8509
  }
8510
+ keyOn(channel, pitch, velocity) {
8511
+ if (this.fPlotHandler)
8512
+ this.fCachedEvents.push({ type: "keyOn", data: [channel, pitch, velocity] });
8513
+ this.fMidiKeyOnLabel[pitch].forEach((key) => {
8514
+ const { path, chan } = key;
8515
+ if (chan === 0 || channel === chan - 1) {
8516
+ this.setParamValue(path, _FaustBaseWebAudioDsp.remap(velocity, 0, 127, key.min, key.max));
8517
+ if (this.fOutputHandler)
8518
+ this.fOutputHandler(path, this.getParamValue(path));
8519
+ }
8520
+ });
8521
+ this.fMidiKeyLabel[pitch].forEach((key) => {
8522
+ const { path, chan } = key;
8523
+ if (chan === 0 || channel === chan - 1) {
8524
+ this.setParamValue(path, _FaustBaseWebAudioDsp.remap(velocity, 0, 127, key.min, key.max));
8525
+ if (this.fOutputHandler)
8526
+ this.fOutputHandler(path, this.getParamValue(path));
8527
+ }
8528
+ });
8529
+ }
8530
+ keyOff(channel, pitch, velocity) {
8531
+ if (this.fPlotHandler)
8532
+ this.fCachedEvents.push({ type: "keyOff", data: [channel, pitch, velocity] });
8533
+ this.fMidiKeyOffLabel[pitch].forEach((key) => {
8534
+ const { path, chan } = key;
8535
+ if (chan === 0 || channel === chan - 1) {
8536
+ this.setParamValue(path, _FaustBaseWebAudioDsp.remap(velocity, 0, 127, key.min, key.max));
8537
+ if (this.fOutputHandler)
8538
+ this.fOutputHandler(path, this.getParamValue(path));
8539
+ }
8540
+ });
8541
+ this.fMidiKeyLabel[pitch].forEach((key) => {
8542
+ const { path, chan } = key;
8543
+ if (chan === 0 || channel === chan - 1) {
8544
+ this.setParamValue(path, 0);
8545
+ if (this.fOutputHandler)
8546
+ this.fOutputHandler(path, this.getParamValue(path));
8547
+ }
8548
+ });
8549
+ }
8467
8550
  pitchWheel(channel, wheel) {
8468
8551
  if (this.fPlotHandler)
8469
8552
  this.fCachedEvents.push({ type: "pitchWheel", data: [channel, wheel] });
@@ -8499,6 +8582,12 @@ export default ${(_b = jsCode.match(jsCodeHead)) == null ? void 0 : _b[1]};
8499
8582
  hasSoundfiles() {
8500
8583
  return this.fSoundfiles.length > 0;
8501
8584
  }
8585
+ startSensors() {
8586
+ this.startSensors();
8587
+ }
8588
+ stopSensors() {
8589
+ this.stopSensors();
8590
+ }
8502
8591
  start() {
8503
8592
  this.fProcessing = true;
8504
8593
  }
@@ -8511,12 +8600,6 @@ export default ${(_b = jsCode.match(jsCodeHead)) == null ? void 0 : _b[1]};
8511
8600
  this.fComputeHandler = null;
8512
8601
  this.fPlotHandler = null;
8513
8602
  }
8514
- startSensors() {
8515
- this.startSensors();
8516
- }
8517
- stopSensors() {
8518
- this.stopSensors();
8519
- }
8520
8603
  };
8521
8604
  var FaustMonoWebAudioDsp = class extends FaustBaseWebAudioDsp {
8522
8605
  constructor(instance, sampleRate, sampleSize, bufferSize, soundfiles) {
@@ -9100,6 +9183,12 @@ export default ${(_b = jsCode.match(jsCodeHead)) == null ? void 0 : _b[1]};
9100
9183
  pitchWheel(chan, value) {
9101
9184
  this.fDSPCode.pitchWheel(chan, value);
9102
9185
  }
9186
+ keyOn(channel, pitch, velocity) {
9187
+ this.fDSPCode.keyOn(channel, pitch, velocity);
9188
+ }
9189
+ keyOff(channel, pitch, velocity) {
9190
+ this.fDSPCode.keyOff(channel, pitch, velocity);
9191
+ }
9103
9192
  setParamValue(path, value) {
9104
9193
  this.fDSPCode.setParamValue(path, value);
9105
9194
  }
@@ -9965,42 +10054,14 @@ export default ${(_b = jsCode.match(jsCodeHead)) == null ? void 0 : _b[1]};
9965
10054
  async startSensors() {
9966
10055
  if (this.hasAccInput) {
9967
10056
  if (window.DeviceMotionEvent) {
9968
- if (typeof window.DeviceMotionEvent.requestPermission === "function") {
9969
- try {
9970
- const response = await window.DeviceMotionEvent.requestPermission();
9971
- if (response === "granted") {
9972
- window.addEventListener("devicemotion", this.handleDeviceMotion, true);
9973
- } else if (response === "denied") {
9974
- alert("You have denied access to motion and orientation data. To enable it, go to Settings > Safari > Motion & Orientation Access.");
9975
- throw new Error("Unable to access the accelerometer.");
9976
- }
9977
- } catch (error) {
9978
- console.error(error);
9979
- }
9980
- } else {
9981
- window.addEventListener("devicemotion", this.handleDeviceMotion, true);
9982
- }
10057
+ window.addEventListener("devicemotion", this.handleDeviceMotion, true);
9983
10058
  } else {
9984
10059
  console.log("Cannot set the accelerometer handler.");
9985
10060
  }
9986
10061
  }
9987
10062
  if (this.hasGyrInput) {
9988
10063
  if (window.DeviceMotionEvent) {
9989
- if (typeof window.DeviceOrientationEvent.requestPermission === "function") {
9990
- try {
9991
- const response = await window.DeviceOrientationEvent.requestPermission();
9992
- if (response === "granted") {
9993
- window.addEventListener("deviceorientation", this.handleDeviceOrientation, true);
9994
- } else if (response === "denied") {
9995
- alert("You have denied access to motion and orientation data. To enable it, go to Settings > Safari > Motion & Orientation Access.");
9996
- throw new Error("Unable to access the gyroscope.");
9997
- }
9998
- } catch (error) {
9999
- console.error(error);
10000
- }
10001
- } else {
10002
- window.addEventListener("deviceorientation", this.handleDeviceOrientation, true);
10003
- }
10064
+ window.addEventListener("deviceorientation", this.handleDeviceOrientation, true);
10004
10065
  } else {
10005
10066
  console.log("Cannot set the gyroscope handler.");
10006
10067
  }
@@ -10064,6 +10125,10 @@ export default ${(_b = jsCode.match(jsCodeHead)) == null ? void 0 : _b[1]};
10064
10125
  this.ctrlChange(channel, data1, data2);
10065
10126
  else if (cmd === 14)
10066
10127
  this.pitchWheel(channel, data2 * 128 + data1);
10128
+ if (cmd === 8 || cmd === 9 && data2 === 0)
10129
+ this.keyOff(channel, data1, data2);
10130
+ else if (cmd === 9)
10131
+ this.keyOn(channel, data1, data2);
10067
10132
  else
10068
10133
  this.port.postMessage({ type: "midi", data });
10069
10134
  }
@@ -10075,6 +10140,14 @@ export default ${(_b = jsCode.match(jsCodeHead)) == null ? void 0 : _b[1]};
10075
10140
  const e = { type: "pitchWheel", data: [channel, wheel] };
10076
10141
  this.port.postMessage(e);
10077
10142
  }
10143
+ keyOn(channel, pitch, velocity) {
10144
+ const e = { type: "keyOn", data: [channel, pitch, velocity] };
10145
+ this.port.postMessage(e);
10146
+ }
10147
+ keyOff(channel, pitch, velocity) {
10148
+ const e = { type: "keyOff", data: [channel, pitch, velocity] };
10149
+ this.port.postMessage(e);
10150
+ }
10078
10151
  get hasAccInput() {
10079
10152
  return __privateGet(this, _hasAccInput);
10080
10153
  }
@@ -10238,42 +10311,14 @@ export default ${(_b = jsCode.match(jsCodeHead)) == null ? void 0 : _b[1]};
10238
10311
  async startSensors() {
10239
10312
  if (this.hasAccInput) {
10240
10313
  if (window.DeviceMotionEvent) {
10241
- if (typeof window.DeviceMotionEvent.requestPermission === "function") {
10242
- try {
10243
- const response = await window.DeviceMotionEvent.requestPermission();
10244
- if (response === "granted") {
10245
- window.addEventListener("devicemotion", this.handleDeviceMotion, true);
10246
- } else if (response === "denied") {
10247
- alert("You have denied access to motion and orientation data. To enable it, go to Settings > Safari > Motion & Orientation Access.");
10248
- throw new Error("Unable to access the accelerometer.");
10249
- }
10250
- } catch (error) {
10251
- console.error(error);
10252
- }
10253
- } else {
10254
- window.addEventListener("devicemotion", this.handleDeviceMotion, true);
10255
- }
10314
+ window.addEventListener("devicemotion", this.handleDeviceMotion, true);
10256
10315
  } else {
10257
10316
  console.log("Cannot set the accelerometer handler.");
10258
10317
  }
10259
10318
  }
10260
10319
  if (this.hasGyrInput) {
10261
10320
  if (window.DeviceMotionEvent) {
10262
- if (typeof window.DeviceOrientationEvent.requestPermission === "function") {
10263
- try {
10264
- const response = await window.DeviceOrientationEvent.requestPermission();
10265
- if (response === "granted") {
10266
- window.addEventListener("deviceorientation", this.handleDeviceOrientation, true);
10267
- } else if (response === "denied") {
10268
- alert("You have denied access to motion and orientation data. To enable it, go to Settings > Safari > Motion & Orientation Access.");
10269
- throw new Error("Unable to access the gyroscope.");
10270
- }
10271
- } catch (error) {
10272
- console.error(error);
10273
- }
10274
- } else {
10275
- window.addEventListener("deviceorientation", this.handleDeviceOrientation, true);
10276
- }
10321
+ window.addEventListener("deviceorientation", this.handleDeviceOrientation, true);
10277
10322
  } else {
10278
10323
  console.log("Cannot set the gyroscope handler.");
10279
10324
  }
@@ -10326,6 +10371,12 @@ export default ${(_b = jsCode.match(jsCodeHead)) == null ? void 0 : _b[1]};
10326
10371
  pitchWheel(chan, value) {
10327
10372
  this.fDSPCode.pitchWheel(chan, value);
10328
10373
  }
10374
+ keyOn(channel, pitch, velocity) {
10375
+ this.fDSPCode.keyOn(channel, pitch, velocity);
10376
+ }
10377
+ keyOff(channel, pitch, velocity) {
10378
+ this.fDSPCode.keyOff(channel, pitch, velocity);
10379
+ }
10329
10380
  setParamValue(path, value) {
10330
10381
  this.fDSPCode.setParamValue(path, value);
10331
10382
  }