@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.
@@ -1,3 +1,22 @@
1
+ var __accessCheck = (obj, member, msg) => {
2
+ if (!member.has(obj))
3
+ throw TypeError("Cannot " + msg);
4
+ };
5
+ var __privateGet = (obj, member, getter) => {
6
+ __accessCheck(obj, member, "read from private field");
7
+ return getter ? getter.call(obj) : member.get(obj);
8
+ };
9
+ var __privateAdd = (obj, member, value) => {
10
+ if (member.has(obj))
11
+ throw TypeError("Cannot add the same private member more than once");
12
+ member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
13
+ };
14
+ var __privateSet = (obj, member, value, setter) => {
15
+ __accessCheck(obj, member, "write to private field");
16
+ setter ? setter.call(obj, value) : member.set(obj, value);
17
+ return value;
18
+ };
19
+
1
20
  // src/instantiateFaustModuleFromFile.ts
2
21
  var instantiateFaustModuleFromFile = async (jsFile, dataFile = jsFile.replace(/c?js$/, "data"), wasmFile = jsFile.replace(/c?js$/, "wasm")) => {
3
22
  var _a, _b;
@@ -118,18 +137,30 @@ var getFaustAudioWorkletProcessor = (dependencies, faustData, register = true) =
118
137
  handleMessageAux(e) {
119
138
  const msg = e.data;
120
139
  switch (msg.type) {
121
- case "midi":
140
+ case "acc": {
141
+ this.propagateAcc(msg.data);
142
+ break;
143
+ }
144
+ case "gyr": {
145
+ this.propagateGyr(msg.data);
146
+ break;
147
+ }
148
+ case "midi": {
122
149
  this.midiMessage(msg.data);
123
150
  break;
124
- case "ctrlChange":
151
+ }
152
+ case "ctrlChange": {
125
153
  this.ctrlChange(msg.data[0], msg.data[1], msg.data[2]);
126
154
  break;
127
- case "pitchWheel":
155
+ }
156
+ case "pitchWheel": {
128
157
  this.pitchWheel(msg.data[0], msg.data[1]);
129
158
  break;
130
- case "param":
159
+ }
160
+ case "param": {
131
161
  this.setParamValue(msg.data.path, msg.data.value);
132
162
  break;
163
+ }
133
164
  case "setPlotHandler": {
134
165
  if (msg.data) {
135
166
  this.fDSPCode.setPlotHandler((output, index, events) => this.port.postMessage({ type: "plot", value: output, index, events }));
@@ -168,6 +199,12 @@ var getFaustAudioWorkletProcessor = (dependencies, faustData, register = true) =
168
199
  pitchWheel(channel, wheel) {
169
200
  this.fDSPCode.pitchWheel(channel, wheel);
170
201
  }
202
+ propagateAcc(accelerationIncludingGravity) {
203
+ this.fDSPCode.propagateAcc(accelerationIncludingGravity);
204
+ }
205
+ propagateGyr(event) {
206
+ this.fDSPCode.propagateGyr(event);
207
+ }
171
208
  }
172
209
  class FaustMonoAudioWorkletProcessor extends FaustAudioWorkletProcessor {
173
210
  constructor(options) {
@@ -1483,6 +1520,270 @@ var FaustWasmInstantiator = class {
1483
1520
  };
1484
1521
  var FaustWasmInstantiator_default = FaustWasmInstantiator;
1485
1522
 
1523
+ // src/FaustSensors.ts
1524
+ var FaustSensors = class _FaustSensors {
1525
+ /**
1526
+ * Function to convert a number to an axis type
1527
+ *
1528
+ * @param value number
1529
+ * @returns axis type
1530
+ */
1531
+ static convertToAxis(value) {
1532
+ switch (value) {
1533
+ case 0:
1534
+ return 0 /* x */;
1535
+ case 1:
1536
+ return 1 /* y */;
1537
+ case 2:
1538
+ return 2 /* z */;
1539
+ default:
1540
+ console.error("Error: Axis not found value: " + value);
1541
+ return 0 /* x */;
1542
+ }
1543
+ }
1544
+ /**
1545
+ * Function to convert a number to a curve type
1546
+ *
1547
+ * @param value number
1548
+ * @returns curve type
1549
+ */
1550
+ static convertToCurve(value) {
1551
+ switch (value) {
1552
+ case 0:
1553
+ return 0 /* Up */;
1554
+ case 1:
1555
+ return 1 /* Down */;
1556
+ case 2:
1557
+ return 2 /* UpDown */;
1558
+ case 3:
1559
+ return 3 /* DownUp */;
1560
+ default:
1561
+ console.error("Error: Curve not found value: " + value);
1562
+ return 0 /* Up */;
1563
+ }
1564
+ }
1565
+ static get Range() {
1566
+ if (!this._Range) {
1567
+ this._Range = class {
1568
+ constructor(x, y) {
1569
+ this.fLo = Math.min(x, y);
1570
+ this.fHi = Math.max(x, y);
1571
+ }
1572
+ clip(x) {
1573
+ if (x < this.fLo)
1574
+ return this.fLo;
1575
+ if (x > this.fHi)
1576
+ return this.fHi;
1577
+ return x;
1578
+ }
1579
+ };
1580
+ }
1581
+ return this._Range;
1582
+ }
1583
+ /**
1584
+ * Interpolator class
1585
+ */
1586
+ static get Interpolator() {
1587
+ if (!this._Interpolator) {
1588
+ this._Interpolator = class {
1589
+ constructor(lo, hi, v1, v2) {
1590
+ this.fRange = new _FaustSensors.Range(lo, hi);
1591
+ if (hi !== lo) {
1592
+ this.fCoef = (v2 - v1) / (hi - lo);
1593
+ this.fOffset = v1 - lo * this.fCoef;
1594
+ } else {
1595
+ this.fCoef = 0;
1596
+ this.fOffset = (v1 + v2) / 2;
1597
+ }
1598
+ }
1599
+ returnMappedValue(v) {
1600
+ var x = this.fRange.clip(v);
1601
+ return this.fOffset + x * this.fCoef;
1602
+ }
1603
+ getLowHigh(amin, amax) {
1604
+ return { amin: this.fRange.fLo, amax: this.fRange.fHi };
1605
+ }
1606
+ };
1607
+ }
1608
+ return this._Interpolator;
1609
+ }
1610
+ /**
1611
+ * Interpolator3pt class, combine two interpolators
1612
+ */
1613
+ static get Interpolator3pt() {
1614
+ if (!this._Interpolator3pt) {
1615
+ this._Interpolator3pt = class {
1616
+ constructor(lo, mid, hi, v1, vMid, v2) {
1617
+ this.fSegment1 = new _FaustSensors.Interpolator(lo, mid, v1, vMid);
1618
+ this.fSegment2 = new _FaustSensors.Interpolator(mid, hi, vMid, v2);
1619
+ this.fMid = mid;
1620
+ }
1621
+ returnMappedValue(x) {
1622
+ return x < this.fMid ? this.fSegment1.returnMappedValue(x) : this.fSegment2.returnMappedValue(x);
1623
+ }
1624
+ getMappingValues(amin, amid, amax) {
1625
+ var lowHighSegment1 = this.fSegment1.getLowHigh(amin, amid);
1626
+ var lowHighSegment2 = this.fSegment2.getLowHigh(amid, amax);
1627
+ return { amin: lowHighSegment1.amin, amid: lowHighSegment2.amin, amax: lowHighSegment2.amax };
1628
+ }
1629
+ };
1630
+ }
1631
+ return this._Interpolator3pt;
1632
+ }
1633
+ /**
1634
+ * UpConverter class, convert accelerometer value to Faust value
1635
+ */
1636
+ static get UpConverter() {
1637
+ if (!this._UpConverter) {
1638
+ this._UpConverter = class {
1639
+ constructor(amin, amid, amax, fmin, fmid, fmax) {
1640
+ this.fActive = true;
1641
+ this.fA2F = new _FaustSensors.Interpolator3pt(amin, amid, amax, fmin, fmid, fmax);
1642
+ this.fF2A = new _FaustSensors.Interpolator3pt(fmin, fmid, fmax, amin, amid, amax);
1643
+ }
1644
+ uiToFaust(x) {
1645
+ return this.fA2F.returnMappedValue(x);
1646
+ }
1647
+ faustToUi(x) {
1648
+ return this.fF2A.returnMappedValue(x);
1649
+ }
1650
+ setMappingValues(amin, amid, amax, min, init, max) {
1651
+ this.fA2F = new _FaustSensors.Interpolator3pt(amin, amid, amax, min, init, max);
1652
+ this.fF2A = new _FaustSensors.Interpolator3pt(min, init, max, amin, amid, amax);
1653
+ }
1654
+ getMappingValues(amin, amid, amax) {
1655
+ return this.fA2F.getMappingValues(amin, amid, amax);
1656
+ }
1657
+ setActive(onOff) {
1658
+ this.fActive = onOff;
1659
+ }
1660
+ getActive() {
1661
+ return this.fActive;
1662
+ }
1663
+ };
1664
+ }
1665
+ return this._UpConverter;
1666
+ }
1667
+ /**
1668
+ * DownConverter class, convert accelerometer value to Faust value
1669
+ */
1670
+ static get DownConverter() {
1671
+ if (!this._DownConverter) {
1672
+ this._DownConverter = class {
1673
+ constructor(amin, amid, amax, fmin, fmid, fmax) {
1674
+ this.fActive = true;
1675
+ this.fA2F = new _FaustSensors.Interpolator3pt(amin, amid, amax, fmax, fmid, fmin);
1676
+ this.fF2A = new _FaustSensors.Interpolator3pt(fmin, fmid, fmax, amax, amid, amin);
1677
+ }
1678
+ uiToFaust(x) {
1679
+ return this.fA2F.returnMappedValue(x);
1680
+ }
1681
+ faustToUi(x) {
1682
+ return this.fF2A.returnMappedValue(x);
1683
+ }
1684
+ setMappingValues(amin, amid, amax, min, init, max) {
1685
+ this.fA2F = new _FaustSensors.Interpolator3pt(amin, amid, amax, max, init, min);
1686
+ this.fF2A = new _FaustSensors.Interpolator3pt(min, init, max, amax, amid, amin);
1687
+ }
1688
+ getMappingValues(amin, amid, amax) {
1689
+ return this.fA2F.getMappingValues(amin, amid, amax);
1690
+ }
1691
+ setActive(onOff) {
1692
+ this.fActive = onOff;
1693
+ }
1694
+ getActive() {
1695
+ return this.fActive;
1696
+ }
1697
+ };
1698
+ }
1699
+ return this._DownConverter;
1700
+ }
1701
+ /**
1702
+ * UpDownConverter class, convert accelerometer value to Faust value
1703
+ */
1704
+ static get UpDownConverter() {
1705
+ if (!this._UpDownConverter) {
1706
+ this._UpDownConverter = class {
1707
+ constructor(amin, amid, amax, fmin, fmid, fmax) {
1708
+ this.fActive = true;
1709
+ this.fA2F = new _FaustSensors.Interpolator3pt(amin, amid, amax, fmin, fmax, fmin);
1710
+ this.fF2A = new _FaustSensors.Interpolator(fmin, fmax, amin, amax);
1711
+ }
1712
+ uiToFaust(x) {
1713
+ return this.fA2F.returnMappedValue(x);
1714
+ }
1715
+ faustToUi(x) {
1716
+ return this.fF2A.returnMappedValue(x);
1717
+ }
1718
+ setMappingValues(amin, amid, amax, min, init, max) {
1719
+ this.fA2F = new _FaustSensors.Interpolator3pt(amin, amid, amax, min, max, min);
1720
+ this.fF2A = new _FaustSensors.Interpolator(min, max, amin, amax);
1721
+ }
1722
+ getMappingValues(amin, amid, amax) {
1723
+ return this.fA2F.getMappingValues(amin, amid, amax);
1724
+ }
1725
+ setActive(onOff) {
1726
+ this.fActive = onOff;
1727
+ }
1728
+ getActive() {
1729
+ return this.fActive;
1730
+ }
1731
+ };
1732
+ }
1733
+ return this._UpDownConverter;
1734
+ }
1735
+ static get DownUpConverter() {
1736
+ if (!this._DownUpConverter) {
1737
+ this._DownUpConverter = class {
1738
+ constructor(amin, amid, amax, fmin, fmid, fmax) {
1739
+ this.fActive = true;
1740
+ this.fA2F = new _FaustSensors.Interpolator3pt(amin, amid, amax, fmax, fmin, fmax);
1741
+ this.fF2A = new _FaustSensors.Interpolator(fmin, fmax, amin, amax);
1742
+ }
1743
+ uiToFaust(x) {
1744
+ return this.fA2F.returnMappedValue(x);
1745
+ }
1746
+ faustToUi(x) {
1747
+ return this.fF2A.returnMappedValue(x);
1748
+ }
1749
+ setMappingValues(amin, amid, amax, min, init, max) {
1750
+ this.fA2F = new _FaustSensors.Interpolator3pt(amin, amid, amax, max, min, max);
1751
+ this.fF2A = new _FaustSensors.Interpolator(min, max, amin, amax);
1752
+ }
1753
+ getMappingValues(amin, amid, amax) {
1754
+ return this.fA2F.getMappingValues(amin, amid, amax);
1755
+ }
1756
+ setActive(onOff) {
1757
+ this.fActive = onOff;
1758
+ }
1759
+ getActive() {
1760
+ return this.fActive;
1761
+ }
1762
+ };
1763
+ }
1764
+ return this._DownUpConverter;
1765
+ }
1766
+ /**
1767
+ * Public function to build the accelerometer handler
1768
+ *
1769
+ * @returns `UpdatableValueConverter` built for the given curve
1770
+ */
1771
+ static buildHandler(curve, amin, amid, amax, min, init, max) {
1772
+ switch (curve) {
1773
+ case 0 /* Up */:
1774
+ return new _FaustSensors.UpConverter(amin, amid, amax, min, init, max);
1775
+ case 1 /* Down */:
1776
+ return new _FaustSensors.DownConverter(amin, amid, amax, min, init, max);
1777
+ case 2 /* UpDown */:
1778
+ return new _FaustSensors.UpDownConverter(amin, amid, amax, min, init, max);
1779
+ case 3 /* DownUp */:
1780
+ return new _FaustSensors.DownUpConverter(amin, amid, amax, min, init, max);
1781
+ default:
1782
+ return new _FaustSensors.UpConverter(amin, amid, amax, min, init, max);
1783
+ }
1784
+ }
1785
+ };
1786
+
1486
1787
  // src/FaustWebAudioDsp.ts
1487
1788
  var WasmAllocator = class {
1488
1789
  constructor(memory, offset) {
@@ -1735,17 +2036,25 @@ var FaustBaseWebAudioDsp = class _FaustBaseWebAudioDsp {
1735
2036
  if (!item.meta)
1736
2037
  return;
1737
2038
  item.meta.forEach((meta) => {
1738
- const { midi } = meta;
1739
- if (!midi)
1740
- return;
1741
- const strMidi = midi.trim();
1742
- if (strMidi === "pitchwheel") {
1743
- this.fPitchwheelLabel.push({ path: item.address, min: item.min, max: item.max });
1744
- } else {
1745
- const matched = strMidi.match(/^ctrl\s(\d+)/);
1746
- if (!matched)
1747
- return;
1748
- this.fCtrlLabel[parseInt(matched[1])].push({ path: item.address, min: item.min, max: item.max });
2039
+ const { midi, acc, gyr } = meta;
2040
+ if (midi) {
2041
+ const strMidi = midi.trim();
2042
+ if (strMidi === "pitchwheel") {
2043
+ this.fPitchwheelLabel.push({ path: item.address, min: item.min, max: item.max });
2044
+ } else {
2045
+ const matched = strMidi.match(/^ctrl\s(\d+)/);
2046
+ if (matched) {
2047
+ this.fCtrlLabel[parseInt(matched[1])].push({ path: item.address, min: item.min, max: item.max });
2048
+ }
2049
+ }
2050
+ }
2051
+ if (acc) {
2052
+ const numAcc = acc.trim().split(" ").map(Number);
2053
+ this.setupAccHandler(item.address, FaustSensors.convertToAxis(numAcc[0]), FaustSensors.convertToCurve(numAcc[1]), numAcc[2], numAcc[3], numAcc[4], item.min, item.init, item.max);
2054
+ }
2055
+ if (gyr) {
2056
+ const numAcc = gyr.trim().split(" ").map(Number);
2057
+ this.setupGyrHandler(item.address, FaustSensors.convertToAxis(numAcc[0]), FaustSensors.convertToCurve(numAcc[1]), numAcc[2], numAcc[3], numAcc[4], item.min, item.init, item.max);
1749
2058
  }
1750
2059
  });
1751
2060
  } else if (item.type === "soundfile") {
@@ -1760,6 +2069,8 @@ var FaustBaseWebAudioDsp = class _FaustBaseWebAudioDsp {
1760
2069
  this.fPtrSize = sampleSize;
1761
2070
  this.fSampleSize = sampleSize;
1762
2071
  this.fSoundfileBuffers = soundfiles;
2072
+ this.fAcc = { x: [], y: [], z: [] };
2073
+ this.fGyr = { x: [], y: [], z: [] };
1763
2074
  }
1764
2075
  // Tools
1765
2076
  static remap(v, mn0, mx0, mn1, mx1) {
@@ -1789,6 +2100,60 @@ var FaustBaseWebAudioDsp = class _FaustBaseWebAudioDsp {
1789
2100
  let trimmed = input.replace(/^\{|\}$/g, "");
1790
2101
  return trimmed.split(";").map((str) => str.length <= 2 ? "" : str.substring(1, str.length - 1));
1791
2102
  }
2103
+ get hasAccInput() {
2104
+ return this.fAcc.x.length + this.fAcc.y.length + this.fAcc.z.length > 0;
2105
+ }
2106
+ propagateAcc(accelerationIncludingGravity) {
2107
+ const { x, y, z } = accelerationIncludingGravity;
2108
+ if (x !== null)
2109
+ this.fAcc.x.forEach((handler) => handler(x));
2110
+ if (y !== null)
2111
+ this.fAcc.y.forEach((handler) => handler(y));
2112
+ if (z !== null)
2113
+ this.fAcc.z.forEach((handler) => handler(z));
2114
+ }
2115
+ get hasGyrInput() {
2116
+ return this.fGyr.x.length + this.fGyr.y.length + this.fGyr.z.length > 0;
2117
+ }
2118
+ propagateGyr(event) {
2119
+ const { alpha, beta, gamma } = event;
2120
+ if (alpha !== null)
2121
+ this.fGyr.x.forEach((handler) => handler(alpha));
2122
+ if (beta !== null)
2123
+ this.fGyr.y.forEach((handler) => handler(beta));
2124
+ if (gamma !== null)
2125
+ this.fGyr.z.forEach((handler) => handler(gamma));
2126
+ }
2127
+ /** Build the accelerometer handler */
2128
+ setupAccHandler(path, axis, curve, amin, amid, amax, min, init, max) {
2129
+ const handler = FaustSensors.buildHandler(curve, amin, amid, amax, min, init, max);
2130
+ switch (axis) {
2131
+ case 0 /* x */:
2132
+ this.fAcc.x.push((val) => this.setParamValue(path, handler.uiToFaust(val)));
2133
+ break;
2134
+ case 1 /* y */:
2135
+ this.fAcc.y.push((val) => this.setParamValue(path, handler.uiToFaust(val)));
2136
+ break;
2137
+ case 2 /* z */:
2138
+ this.fAcc.z.push((val) => this.setParamValue(path, handler.uiToFaust(val)));
2139
+ break;
2140
+ }
2141
+ }
2142
+ /** Build the gyroscope handler */
2143
+ setupGyrHandler(path, axis, curve, amin, amid, amax, min, init, max) {
2144
+ const handler = FaustSensors.buildHandler(curve, amin, amid, amax, min, init, max);
2145
+ switch (axis) {
2146
+ case 0 /* x */:
2147
+ this.fGyr.x.push((val) => this.setParamValue(path, handler.uiToFaust(val)));
2148
+ break;
2149
+ case 1 /* y */:
2150
+ this.fGyr.y.push((val) => this.setParamValue(path, handler.uiToFaust(val)));
2151
+ break;
2152
+ case 2 /* z */:
2153
+ this.fGyr.z.push((val) => this.setParamValue(path, handler.uiToFaust(val)));
2154
+ break;
2155
+ }
2156
+ }
1792
2157
  static extractUrlsFromMeta(dspMeta) {
1793
2158
  const soundfilesEntry = dspMeta.meta.find((entry) => entry.soundfiles !== void 0);
1794
2159
  if (soundfilesEntry) {
@@ -2602,6 +2967,18 @@ var FaustOfflineProcessor = class {
2602
2967
  destroy() {
2603
2968
  this.fDSPCode.destroy();
2604
2969
  }
2970
+ get hasAccInput() {
2971
+ return this.fDSPCode.hasAccInput;
2972
+ }
2973
+ propagateAcc(accelerationIncludingGravity) {
2974
+ this.fDSPCode.propagateAcc(accelerationIncludingGravity);
2975
+ }
2976
+ get hasGyrInput() {
2977
+ return this.fDSPCode.hasGyrInput;
2978
+ }
2979
+ propagateGyr(event) {
2980
+ this.fDSPCode.propagateGyr(event);
2981
+ }
2605
2982
  /**
2606
2983
  * Render frames in an array.
2607
2984
  *
@@ -3221,6 +3598,7 @@ var SoundfileReader = class {
3221
3598
  var SoundfileReader_default = SoundfileReader;
3222
3599
 
3223
3600
  // src/FaustAudioWorkletNode.ts
3601
+ var _hasAccInput, _hasGyrInput;
3224
3602
  var FaustAudioWorkletNode = class extends (globalThis.AudioWorkletNode || null) {
3225
3603
  constructor(context, name, factory, options, nodeOptions = {}) {
3226
3604
  const JSONObj = JSON.parse(factory.json);
@@ -3234,6 +3612,8 @@ var FaustAudioWorkletNode = class extends (globalThis.AudioWorkletNode || null)
3234
3612
  processorOptions: options,
3235
3613
  ...nodeOptions
3236
3614
  });
3615
+ __privateAdd(this, _hasAccInput, false);
3616
+ __privateAdd(this, _hasGyrInput, false);
3237
3617
  this.fJSONDsp = JSONObj;
3238
3618
  this.fJSON = factory.json;
3239
3619
  this.fOutputHandler = null;
@@ -3245,6 +3625,15 @@ var FaustAudioWorkletNode = class extends (globalThis.AudioWorkletNode || null)
3245
3625
  if (item.type === "vslider" || item.type === "hslider" || item.type === "button" || item.type === "checkbox" || item.type === "nentry") {
3246
3626
  this.fInputsItems.push(item.address);
3247
3627
  this.fDescriptor.push(item);
3628
+ if (!item.meta)
3629
+ return;
3630
+ item.meta.forEach((meta) => {
3631
+ const { midi, acc, gyr } = meta;
3632
+ if (acc)
3633
+ __privateSet(this, _hasAccInput, true);
3634
+ if (gyr)
3635
+ __privateSet(this, _hasGyrInput, true);
3636
+ });
3248
3637
  }
3249
3638
  };
3250
3639
  FaustBaseWebAudioDsp.parseUI(this.fJSONDsp.ui, this.fUICallback);
@@ -3257,6 +3646,54 @@ var FaustAudioWorkletNode = class extends (globalThis.AudioWorkletNode || null)
3257
3646
  };
3258
3647
  }
3259
3648
  // Public API
3649
+ /** Setup accelerometer and gyroscope handlers */
3650
+ async listenMotion() {
3651
+ if (this.hasAccInput) {
3652
+ const handleDeviceMotion = ({ accelerationIncludingGravity }) => {
3653
+ if (!accelerationIncludingGravity)
3654
+ return;
3655
+ const { x, y, z } = accelerationIncludingGravity;
3656
+ this.propagateAcc({ x, y, z });
3657
+ };
3658
+ if (window.DeviceMotionEvent) {
3659
+ if (typeof window.DeviceMotionEvent.requestPermission === "function") {
3660
+ try {
3661
+ const response = await window.DeviceMotionEvent.requestPermission();
3662
+ if (response !== "granted")
3663
+ throw new Error("Unable to access the accelerometer.");
3664
+ window.addEventListener("devicemotion", handleDeviceMotion, true);
3665
+ } catch (error) {
3666
+ console.error(error);
3667
+ }
3668
+ } else {
3669
+ window.addEventListener("devicemotion", handleDeviceMotion, true);
3670
+ }
3671
+ } else {
3672
+ console.log("Cannot set the accelerometer handler.");
3673
+ }
3674
+ }
3675
+ if (this.hasGyrInput) {
3676
+ const handleDeviceOrientation = ({ alpha, beta, gamma }) => {
3677
+ this.propagateGyr({ alpha, beta, gamma });
3678
+ };
3679
+ if (window.DeviceMotionEvent) {
3680
+ if (typeof window.DeviceOrientationEvent.requestPermission === "function") {
3681
+ try {
3682
+ const response = await window.DeviceOrientationEvent.requestPermission();
3683
+ if (response !== "granted")
3684
+ throw new Error("Unable to access the gyroscope.");
3685
+ window.addEventListener("deviceorientation", handleDeviceOrientation, true);
3686
+ } catch (error) {
3687
+ console.error(error);
3688
+ }
3689
+ } else {
3690
+ window.addEventListener("deviceorientation", handleDeviceOrientation, true);
3691
+ }
3692
+ } else {
3693
+ console.log("Cannot set the gyroscope handler.");
3694
+ }
3695
+ }
3696
+ }
3260
3697
  setOutputParamHandler(handler) {
3261
3698
  this.fOutputHandler = handler;
3262
3699
  }
@@ -3315,6 +3752,24 @@ var FaustAudioWorkletNode = class extends (globalThis.AudioWorkletNode || null)
3315
3752
  const e = { type: "pitchWheel", data: [channel, wheel] };
3316
3753
  this.port.postMessage(e);
3317
3754
  }
3755
+ get hasAccInput() {
3756
+ return __privateGet(this, _hasAccInput);
3757
+ }
3758
+ propagateAcc(accelerationIncludingGravity) {
3759
+ if (!accelerationIncludingGravity)
3760
+ return;
3761
+ const e = { type: "acc", data: accelerationIncludingGravity };
3762
+ this.port.postMessage(e);
3763
+ }
3764
+ get hasGyrInput() {
3765
+ return __privateGet(this, _hasGyrInput);
3766
+ }
3767
+ propagateGyr(event) {
3768
+ if (!event)
3769
+ return;
3770
+ const e = { type: "gyr", data: event };
3771
+ this.port.postMessage(e);
3772
+ }
3318
3773
  setParamValue(path, value) {
3319
3774
  const e = { type: "param", data: { path, value } };
3320
3775
  this.port.postMessage(e);
@@ -3352,6 +3807,8 @@ var FaustAudioWorkletNode = class extends (globalThis.AudioWorkletNode || null)
3352
3807
  this.port.close();
3353
3808
  }
3354
3809
  };
3810
+ _hasAccInput = new WeakMap();
3811
+ _hasGyrInput = new WeakMap();
3355
3812
  var FaustMonoAudioWorkletNode = class extends FaustAudioWorkletNode {
3356
3813
  constructor(context, name, factory, sampleSize, nodeOptions = {}) {
3357
3814
  super(context, name, factory, { name, factory, sampleSize }, nodeOptions);
@@ -3447,6 +3904,54 @@ var FaustScriptProcessorNode = class extends (globalThis.ScriptProcessorNode ||
3447
3904
  this.start();
3448
3905
  }
3449
3906
  // Public API
3907
+ /** Setup accelerometer and gyroscope handlers */
3908
+ async listenMotion() {
3909
+ if (this.hasAccInput) {
3910
+ const handleDeviceMotion = ({ accelerationIncludingGravity }) => {
3911
+ if (!accelerationIncludingGravity)
3912
+ return;
3913
+ const { x, y, z } = accelerationIncludingGravity;
3914
+ this.propagateAcc({ x, y, z });
3915
+ };
3916
+ if (window.DeviceMotionEvent) {
3917
+ if (typeof window.DeviceMotionEvent.requestPermission === "function") {
3918
+ try {
3919
+ const response = await window.DeviceMotionEvent.requestPermission();
3920
+ if (response !== "granted")
3921
+ throw new Error("Unable to access the accelerometer.");
3922
+ window.addEventListener("devicemotion", handleDeviceMotion, true);
3923
+ } catch (error) {
3924
+ console.error(error);
3925
+ }
3926
+ } else {
3927
+ window.addEventListener("devicemotion", handleDeviceMotion, true);
3928
+ }
3929
+ } else {
3930
+ console.log("Cannot set the accelerometer handler.");
3931
+ }
3932
+ }
3933
+ if (this.hasGyrInput) {
3934
+ const handleDeviceOrientation = ({ alpha, beta, gamma }) => {
3935
+ this.propagateGyr({ alpha, beta, gamma });
3936
+ };
3937
+ if (window.DeviceMotionEvent) {
3938
+ if (typeof window.DeviceOrientationEvent.requestPermission === "function") {
3939
+ try {
3940
+ const response = await window.DeviceOrientationEvent.requestPermission();
3941
+ if (response !== "granted")
3942
+ throw new Error("Unable to access the gyroscope.");
3943
+ window.addEventListener("deviceorientation", handleDeviceOrientation, true);
3944
+ } catch (error) {
3945
+ console.error(error);
3946
+ }
3947
+ } else {
3948
+ window.addEventListener("deviceorientation", handleDeviceOrientation, true);
3949
+ }
3950
+ } else {
3951
+ console.log("Cannot set the gyroscope handler.");
3952
+ }
3953
+ }
3954
+ }
3450
3955
  compute(input, output) {
3451
3956
  return this.fDSPCode.compute(input, output);
3452
3957
  }
@@ -3515,6 +4020,18 @@ var FaustScriptProcessorNode = class extends (globalThis.ScriptProcessorNode ||
3515
4020
  destroy() {
3516
4021
  this.fDSPCode.destroy();
3517
4022
  }
4023
+ get hasAccInput() {
4024
+ return this.fDSPCode.hasAccInput;
4025
+ }
4026
+ propagateAcc(accelerationIncludingGravity) {
4027
+ this.fDSPCode.propagateAcc(accelerationIncludingGravity);
4028
+ }
4029
+ get hasGyrInput() {
4030
+ return this.fDSPCode.hasGyrInput;
4031
+ }
4032
+ propagateGyr(event) {
4033
+ this.fDSPCode.propagateGyr(event);
4034
+ }
3518
4035
  };
3519
4036
  var FaustMonoScriptProcessorNode = class extends FaustScriptProcessorNode {
3520
4037
  };
@@ -3598,6 +4115,8 @@ var ${Soundfile.name} = ${Soundfile.toString()}
3598
4115
  var Soundfile = ${Soundfile.name};
3599
4116
  var ${WasmAllocator.name} = ${WasmAllocator.toString()}
3600
4117
  var WasmAllocator = ${WasmAllocator.name};
4118
+ var ${FaustSensors.name} = ${FaustSensors.toString()}
4119
+ var FaustSensors = ${FaustSensors.name};
3601
4120
  // Put them in dependencies
3602
4121
  const dependencies = {
3603
4122
  FaustBaseWebAudioDsp,
@@ -3650,6 +4169,8 @@ var ${Soundfile.name} = ${Soundfile.toString()}
3650
4169
  var Soundfile = ${Soundfile.name};
3651
4170
  var ${WasmAllocator.name} = ${WasmAllocator.toString()}
3652
4171
  var WasmAllocator = ${WasmAllocator.name};
4172
+ var ${FaustSensors.name} = ${FaustSensors.toString()}
4173
+ var FaustSensors = ${FaustSensors.name};
3653
4174
  var FFTUtils = ${fftUtils.toString()}
3654
4175
  // Put them in dependencies
3655
4176
  const dependencies = {
@@ -3877,6 +4398,8 @@ var ${Soundfile.name} = ${Soundfile.toString()}
3877
4398
  var Soundfile = ${Soundfile.name};
3878
4399
  var ${WasmAllocator.name} = ${WasmAllocator.toString()}
3879
4400
  var WasmAllocator = ${WasmAllocator.name};
4401
+ var ${FaustSensors.name} = ${FaustSensors.toString()}
4402
+ var FaustSensors = ${FaustSensors.name};
3880
4403
  // Put them in dependencies
3881
4404
  const dependencies = {
3882
4405
  FaustBaseWebAudioDsp,