@grame/faustwasm 0.8.2 → 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.
- 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/create-node.js +177 -0
- package/test/midi/dsp-meta.json +133 -0
- package/test/midi/dsp-module.wasm +0 -0
- package/test/midi/faust-ui/index.css +442 -0
- package/test/midi/faust-ui/index.css.map +1 -0
- package/test/midi/faust-ui/index.d.ts +1 -0
- package/test/midi/faust-ui/index.js +3729 -0
- package/test/midi/faust-ui/index.js.map +1 -0
- package/test/midi/faustwasm/index.d.ts +1680 -0
- package/test/midi/faustwasm/index.js +4884 -0
- package/test/midi/faustwasm/index.js.map +7 -0
- package/test/midi/icon.png +0 -0
- package/test/midi/index.html +76 -0
- package/test/midi/index.js +183 -0
- package/test/midi/manifest.json +17 -0
- package/test/midi/service-worker.js +165 -0
- package/test/midi.dsp +8 -1
- package/test/organ1/create-node.js +177 -0
- package/test/organ1/dsp-meta.json +126 -0
- package/test/organ1/dsp-module.wasm +0 -0
- package/test/organ1/faust-ui/index.css +442 -0
- package/test/organ1/faust-ui/index.css.map +1 -0
- package/test/organ1/faust-ui/index.d.ts +1 -0
- package/test/organ1/faust-ui/index.js +3729 -0
- package/test/organ1/faust-ui/index.js.map +1 -0
- package/test/organ1/faustwasm/index.d.ts +1656 -0
- package/test/organ1/faustwasm/index.js +4783 -0
- package/test/organ1/faustwasm/index.js.map +7 -0
- package/test/organ1/icon.png +0 -0
- package/test/organ1/index.html +76 -0
- package/test/organ1/index.js +203 -0
- package/test/organ1/manifest.json +17 -0
- package/test/organ1/service-worker.js +181 -0
|
@@ -5,8 +5,15 @@ const FAUST_DSP_VOICES = 0;
|
|
|
5
5
|
// Set to true if the DSP has an effect
|
|
6
6
|
const FAUST_DSP_HAS_EFFECT = false;
|
|
7
7
|
|
|
8
|
-
const CACHE_NAME = "
|
|
8
|
+
const CACHE_NAME = "FAUST_DSP_NAME_VERSION_DATE"; // Cache name with versioning
|
|
9
9
|
|
|
10
|
+
/**
|
|
11
|
+
* List of essential resources required for the **Mono DSP** version of the application.
|
|
12
|
+
*
|
|
13
|
+
* - These files are cached to enable offline functionality and improve loading speed.
|
|
14
|
+
* - Includes the main HTML, JavaScript, and CSS files required for the app.
|
|
15
|
+
* - Contains Faust-related files needed for DSP processing.
|
|
16
|
+
*/
|
|
10
17
|
const MONO_RESOURCES = [
|
|
11
18
|
"./index.html",
|
|
12
19
|
"./index.js",
|
|
@@ -18,11 +25,23 @@ const MONO_RESOURCES = [
|
|
|
18
25
|
"./dsp-meta.json"
|
|
19
26
|
];
|
|
20
27
|
|
|
28
|
+
/**
|
|
29
|
+
* List of resources for the **Polyphonic DSP** version of the application.
|
|
30
|
+
*
|
|
31
|
+
* - Extends the mono resource list by adding a **mixer module**.
|
|
32
|
+
* - The mixer module is required to handle multiple simultaneous voices used in a polyphonic instrument.
|
|
33
|
+
*/
|
|
21
34
|
const POLY_RESOURCES = [
|
|
22
35
|
...MONO_RESOURCES,
|
|
23
36
|
"./mixer-module.wasm",
|
|
24
37
|
];
|
|
25
38
|
|
|
39
|
+
/**
|
|
40
|
+
* List of resources for the **Polyphonic DSP with Effects** version.
|
|
41
|
+
*
|
|
42
|
+
* - Extends the polyphonic resource list by adding an **effect module**.
|
|
43
|
+
* - The effect module allows applying audio effects to the polyphonic instrument.
|
|
44
|
+
*/
|
|
26
45
|
const POLY_EFFECT_RESOURCES = [
|
|
27
46
|
...POLY_RESOURCES,
|
|
28
47
|
"./effect-module.wasm",
|
|
@@ -33,13 +52,16 @@ const POLY_EFFECT_RESOURCES = [
|
|
|
33
52
|
const serviceWorkerGlobalScope = self;
|
|
34
53
|
|
|
35
54
|
/**
|
|
36
|
-
* Install the service worker and
|
|
55
|
+
* Install the service worker, cache essential resources, and prepare for immediate activation.
|
|
56
|
+
*
|
|
57
|
+
* - Opens the cache and stores required assets based on the app's configuration.
|
|
58
|
+
* - Ensures resources are preloaded for offline access.
|
|
37
59
|
*/
|
|
38
60
|
serviceWorkerGlobalScope.addEventListener("install", (event) => {
|
|
39
61
|
console.log("Service worker installed");
|
|
40
62
|
event.waitUntil((async () => {
|
|
41
63
|
const cache = await caches.open(CACHE_NAME);
|
|
42
|
-
const resources = (FAUST_DSP_VOICES && FAUST_DSP_HAS_EFFECT) ? POLY_EFFECT_RESOURCES : FAUST_DSP_VOICES ? POLY_RESOURCES : MONO_RESOURCES;
|
|
64
|
+
const resources = (FAUST_DSP_VOICES && FAUST_DSP_HAS_EFFECT) ? POLY_EFFECT_RESOURCES : (FAUST_DSP_VOICES ? POLY_RESOURCES : MONO_RESOURCES);
|
|
43
65
|
try {
|
|
44
66
|
return cache.addAll(resources);
|
|
45
67
|
} catch (error) {
|
|
@@ -48,6 +70,16 @@ serviceWorkerGlobalScope.addEventListener("install", (event) => {
|
|
|
48
70
|
})());
|
|
49
71
|
});
|
|
50
72
|
|
|
73
|
+
/**
|
|
74
|
+
* Handles the activation of the Service Worker.
|
|
75
|
+
*
|
|
76
|
+
* - Claims control over all clients immediately, bypassing the default behavior that
|
|
77
|
+
* requires a page reload before the new service worker takes effect.
|
|
78
|
+
* - Once claimed, it finds all active window clients and reloads them to ensure they are
|
|
79
|
+
* controlled by the latest version of the service worker.
|
|
80
|
+
* - This approach ensures that updates to the service worker take effect immediately
|
|
81
|
+
* across all open pages, preventing potential inconsistencies.
|
|
82
|
+
*/
|
|
51
83
|
serviceWorkerGlobalScope.addEventListener("activate", (event) => {
|
|
52
84
|
console.log("Service worker activated");
|
|
53
85
|
event.waitUntil(
|
|
@@ -61,7 +93,20 @@ serviceWorkerGlobalScope.addEventListener("activate", (event) => {
|
|
|
61
93
|
);
|
|
62
94
|
});
|
|
63
95
|
|
|
64
|
-
/**
|
|
96
|
+
/**
|
|
97
|
+
* Adjusts response headers to enforce Cross-Origin Opener Policy (COOP) and Cross-Origin Embedder Policy (COEP).
|
|
98
|
+
*
|
|
99
|
+
* - Ensures that the response is served with `Cross-Origin-Opener-Policy: same-origin`
|
|
100
|
+
* and `Cross-Origin-Embedder-Policy: require-corp`.
|
|
101
|
+
* - Required for enabling **cross-origin isolated** environments in web applications.
|
|
102
|
+
* - Necessary for features like **SharedArrayBuffer**, WebAssembly threads, and
|
|
103
|
+
* high-performance APIs that require isolation.
|
|
104
|
+
* - Creates a new `Response` object with the modified headers while preserving
|
|
105
|
+
* the original response body and status.
|
|
106
|
+
*
|
|
107
|
+
* @param {Response} response - The original HTTP response object.
|
|
108
|
+
* @returns {Response} A new response with updated security headers.
|
|
109
|
+
*/
|
|
65
110
|
const getCrossOriginIsolatedResponse = (response) => {
|
|
66
111
|
// Modify headers to include COOP & COEP
|
|
67
112
|
const headers = new Headers(response.headers);
|
|
@@ -79,7 +124,15 @@ const getCrossOriginIsolatedResponse = (response) => {
|
|
|
79
124
|
};
|
|
80
125
|
|
|
81
126
|
/**
|
|
82
|
-
*
|
|
127
|
+
* Intercepts fetch requests and enforces COOP and COEP headers for security.
|
|
128
|
+
*
|
|
129
|
+
* - Checks if the requested resource is available in the cache:
|
|
130
|
+
* - If found, returns a cached response with `Cross-Origin-Opener-Policy` and `Cross-Origin-Embedder-Policy` headers.
|
|
131
|
+
* - If not found, fetches the resource from the network, applies COOP/COEP headers, and caches the response (for GET requests).
|
|
132
|
+
* - Ensures cross-origin isolation, required for APIs like `SharedArrayBuffer` and WebAssembly threading.
|
|
133
|
+
* - Handles network errors gracefully by returning a 503 "Service Unavailable" response when needed.
|
|
134
|
+
*
|
|
135
|
+
* @param {FetchEvent} event - The fetch event triggered by the browser.
|
|
83
136
|
*/
|
|
84
137
|
serviceWorkerGlobalScope.addEventListener("fetch", (event) => {
|
|
85
138
|
|
package/dist/cjs/index.d.ts
CHANGED
|
@@ -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[];
|
package/dist/cjs/index.js
CHANGED
|
@@ -216,6 +216,14 @@ export default ${(_b = jsCode.match(jsCodeHead)) == null ? void 0 : _b[1]};
|
|
|
216
216
|
this.pitchWheel(msg.data[0], msg.data[1]);
|
|
217
217
|
break;
|
|
218
218
|
}
|
|
219
|
+
case "keyOn": {
|
|
220
|
+
this.keyOn(msg.data[0], msg.data[1], msg.data[2]);
|
|
221
|
+
break;
|
|
222
|
+
}
|
|
223
|
+
case "keyOff": {
|
|
224
|
+
this.keyOff(msg.data[0], msg.data[1], msg.data[2]);
|
|
225
|
+
break;
|
|
226
|
+
}
|
|
219
227
|
case "param": {
|
|
220
228
|
this.setParamValue(msg.data.path, msg.data.value);
|
|
221
229
|
break;
|
|
@@ -262,6 +270,12 @@ export default ${(_b = jsCode.match(jsCodeHead)) == null ? void 0 : _b[1]};
|
|
|
262
270
|
pitchWheel(channel, wheel) {
|
|
263
271
|
this.fDSPCode.pitchWheel(channel, wheel);
|
|
264
272
|
}
|
|
273
|
+
keyOn(channel, pitch, velocity) {
|
|
274
|
+
this.fDSPCode.keyOn(channel, pitch, velocity);
|
|
275
|
+
}
|
|
276
|
+
keyOff(channel, pitch, velocity) {
|
|
277
|
+
this.fDSPCode.keyOff(channel, pitch, velocity);
|
|
278
|
+
}
|
|
265
279
|
propagateAcc(accelerationIncludingGravity, invert = false) {
|
|
266
280
|
this.fDSPCode.propagateAcc(accelerationIncludingGravity, invert);
|
|
267
281
|
}
|
|
@@ -2142,6 +2156,10 @@ export default ${(_b = jsCode.match(jsCodeHead)) == null ? void 0 : _b[1]};
|
|
|
2142
2156
|
// MIDI handling
|
|
2143
2157
|
this.fPitchwheelLabel = [];
|
|
2144
2158
|
this.fCtrlLabel = new Array(128).fill(null).map(() => []);
|
|
2159
|
+
// array of MIDI key handlers; array index is the MIDI note number
|
|
2160
|
+
this.fMidiKeyLabel = new Array(128).fill(null).map(() => []);
|
|
2161
|
+
this.fMidiKeyOnLabel = new Array(128).fill(null).map(() => []);
|
|
2162
|
+
this.fMidiKeyOffLabel = new Array(128).fill(null).map(() => []);
|
|
2145
2163
|
this.fPathTable = {};
|
|
2146
2164
|
this.fUICallback = (item) => {
|
|
2147
2165
|
if (item.type === "hbargraph" || item.type === "vbargraph") {
|
|
@@ -2154,6 +2172,7 @@ export default ${(_b = jsCode.match(jsCodeHead)) == null ? void 0 : _b[1]};
|
|
|
2154
2172
|
if (!item.meta)
|
|
2155
2173
|
return;
|
|
2156
2174
|
item.meta.forEach((meta) => {
|
|
2175
|
+
var _a, _b, _c, _d, _e, _f;
|
|
2157
2176
|
const { midi, acc, gyr } = meta;
|
|
2158
2177
|
if (midi) {
|
|
2159
2178
|
const strMidi = midi.trim();
|
|
@@ -2167,10 +2186,25 @@ export default ${(_b = jsCode.match(jsCodeHead)) == null ? void 0 : _b[1]};
|
|
|
2167
2186
|
} else {
|
|
2168
2187
|
const matched2 = strMidi.match(/^ctrl\s(\d+)\s(\d+)/);
|
|
2169
2188
|
const matched1 = strMidi.match(/^ctrl\s(\d+)/);
|
|
2189
|
+
const matchedKey = strMidi.match(/^key\s+(\d+)(?:\s+(\d+))?$/);
|
|
2190
|
+
const matchedKeyOn = strMidi.match(/^keyon\s+(\d+)(?:\s+(\d+))?$/);
|
|
2191
|
+
const matchedKeyOff = strMidi.match(/^keyoff\s+(\d+)(?:\s+(\d+))?$/);
|
|
2170
2192
|
if (matched2) {
|
|
2171
2193
|
this.fCtrlLabel[parseInt(matched2[1])].push({ path: item.address, chan: parseInt(matched2[2]), min: item.min, max: item.max });
|
|
2172
2194
|
} else if (matched1) {
|
|
2173
2195
|
this.fCtrlLabel[parseInt(matched1[1])].push({ path: item.address, chan: 0, min: item.min, max: item.max });
|
|
2196
|
+
} else if (matchedKey) {
|
|
2197
|
+
const note = parseInt(matchedKey[1]);
|
|
2198
|
+
const channel = matchedKey[2] ? parseInt(matchedKey[2]) : 0;
|
|
2199
|
+
this.fMidiKeyLabel[note].push({ path: item.address, chan: channel, min: (_a = item.min) != null ? _a : 0, max: (_b = item.max) != null ? _b : 1 });
|
|
2200
|
+
} else if (matchedKeyOn) {
|
|
2201
|
+
const note = parseInt(matchedKeyOn[1]);
|
|
2202
|
+
const channel = matchedKeyOn[2] ? parseInt(matchedKeyOn[2]) : 0;
|
|
2203
|
+
this.fMidiKeyOnLabel[note].push({ path: item.address, chan: channel, min: (_c = item.min) != null ? _c : 0, max: (_d = item.max) != null ? _d : 1 });
|
|
2204
|
+
} else if (matchedKeyOff) {
|
|
2205
|
+
const note = parseInt(matchedKeyOff[1]);
|
|
2206
|
+
const channel = matchedKeyOff[2] ? parseInt(matchedKeyOff[2]) : 0;
|
|
2207
|
+
this.fMidiKeyOffLabel[note].push({ path: item.address, chan: channel, min: (_e = item.min) != null ? _e : 0, max: (_f = item.max) != null ? _f : 1 });
|
|
2174
2208
|
}
|
|
2175
2209
|
}
|
|
2176
2210
|
}
|
|
@@ -2432,6 +2466,15 @@ export default ${(_b = jsCode.match(jsCodeHead)) == null ? void 0 : _b[1]};
|
|
|
2432
2466
|
return this.ctrlChange(channel, data1, data2);
|
|
2433
2467
|
if (cmd === 14)
|
|
2434
2468
|
return this.pitchWheel(channel, data2 * 128 + data1);
|
|
2469
|
+
if (cmd === 9) {
|
|
2470
|
+
if (data2 > 0)
|
|
2471
|
+
return this.keyOn(channel, data1, data2);
|
|
2472
|
+
else
|
|
2473
|
+
return this.keyOff(channel, data1, data2);
|
|
2474
|
+
}
|
|
2475
|
+
if (cmd === 8) {
|
|
2476
|
+
return this.keyOff(channel, data1, data2);
|
|
2477
|
+
}
|
|
2435
2478
|
}
|
|
2436
2479
|
ctrlChange(channel, ctrl, value) {
|
|
2437
2480
|
if (this.fPlotHandler)
|
|
@@ -2447,6 +2490,46 @@ export default ${(_b = jsCode.match(jsCodeHead)) == null ? void 0 : _b[1]};
|
|
|
2447
2490
|
});
|
|
2448
2491
|
}
|
|
2449
2492
|
}
|
|
2493
|
+
keyOn(channel, pitch, velocity) {
|
|
2494
|
+
if (this.fPlotHandler)
|
|
2495
|
+
this.fCachedEvents.push({ type: "keyOn", data: [channel, pitch, velocity] });
|
|
2496
|
+
this.fMidiKeyOnLabel[pitch].forEach((key) => {
|
|
2497
|
+
const { path, chan } = key;
|
|
2498
|
+
if (chan === 0 || channel === chan - 1) {
|
|
2499
|
+
this.setParamValue(path, _FaustBaseWebAudioDsp.remap(velocity, 0, 127, key.min, key.max));
|
|
2500
|
+
if (this.fOutputHandler)
|
|
2501
|
+
this.fOutputHandler(path, this.getParamValue(path));
|
|
2502
|
+
}
|
|
2503
|
+
});
|
|
2504
|
+
this.fMidiKeyLabel[pitch].forEach((key) => {
|
|
2505
|
+
const { path, chan } = key;
|
|
2506
|
+
if (chan === 0 || channel === chan - 1) {
|
|
2507
|
+
this.setParamValue(path, _FaustBaseWebAudioDsp.remap(velocity, 0, 127, key.min, key.max));
|
|
2508
|
+
if (this.fOutputHandler)
|
|
2509
|
+
this.fOutputHandler(path, this.getParamValue(path));
|
|
2510
|
+
}
|
|
2511
|
+
});
|
|
2512
|
+
}
|
|
2513
|
+
keyOff(channel, pitch, velocity) {
|
|
2514
|
+
if (this.fPlotHandler)
|
|
2515
|
+
this.fCachedEvents.push({ type: "keyOff", data: [channel, pitch, velocity] });
|
|
2516
|
+
this.fMidiKeyOffLabel[pitch].forEach((key) => {
|
|
2517
|
+
const { path, chan } = key;
|
|
2518
|
+
if (chan === 0 || channel === chan - 1) {
|
|
2519
|
+
this.setParamValue(path, _FaustBaseWebAudioDsp.remap(velocity, 0, 127, key.min, key.max));
|
|
2520
|
+
if (this.fOutputHandler)
|
|
2521
|
+
this.fOutputHandler(path, this.getParamValue(path));
|
|
2522
|
+
}
|
|
2523
|
+
});
|
|
2524
|
+
this.fMidiKeyLabel[pitch].forEach((key) => {
|
|
2525
|
+
const { path, chan } = key;
|
|
2526
|
+
if (chan === 0 || channel === chan - 1) {
|
|
2527
|
+
this.setParamValue(path, 0);
|
|
2528
|
+
if (this.fOutputHandler)
|
|
2529
|
+
this.fOutputHandler(path, this.getParamValue(path));
|
|
2530
|
+
}
|
|
2531
|
+
});
|
|
2532
|
+
}
|
|
2450
2533
|
pitchWheel(channel, wheel) {
|
|
2451
2534
|
if (this.fPlotHandler)
|
|
2452
2535
|
this.fCachedEvents.push({ type: "pitchWheel", data: [channel, wheel] });
|
|
@@ -3083,6 +3166,12 @@ export default ${(_b = jsCode.match(jsCodeHead)) == null ? void 0 : _b[1]};
|
|
|
3083
3166
|
pitchWheel(chan, value) {
|
|
3084
3167
|
this.fDSPCode.pitchWheel(chan, value);
|
|
3085
3168
|
}
|
|
3169
|
+
keyOn(channel, pitch, velocity) {
|
|
3170
|
+
this.fDSPCode.keyOn(channel, pitch, velocity);
|
|
3171
|
+
}
|
|
3172
|
+
keyOff(channel, pitch, velocity) {
|
|
3173
|
+
this.fDSPCode.keyOff(channel, pitch, velocity);
|
|
3174
|
+
}
|
|
3086
3175
|
setParamValue(path, value) {
|
|
3087
3176
|
this.fDSPCode.setParamValue(path, value);
|
|
3088
3177
|
}
|
|
@@ -4019,6 +4108,10 @@ export default ${(_b = jsCode.match(jsCodeHead)) == null ? void 0 : _b[1]};
|
|
|
4019
4108
|
this.ctrlChange(channel, data1, data2);
|
|
4020
4109
|
else if (cmd === 14)
|
|
4021
4110
|
this.pitchWheel(channel, data2 * 128 + data1);
|
|
4111
|
+
if (cmd === 8 || cmd === 9 && data2 === 0)
|
|
4112
|
+
this.keyOff(channel, data1, data2);
|
|
4113
|
+
else if (cmd === 9)
|
|
4114
|
+
this.keyOn(channel, data1, data2);
|
|
4022
4115
|
else
|
|
4023
4116
|
this.port.postMessage({ type: "midi", data });
|
|
4024
4117
|
}
|
|
@@ -4030,6 +4123,14 @@ export default ${(_b = jsCode.match(jsCodeHead)) == null ? void 0 : _b[1]};
|
|
|
4030
4123
|
const e = { type: "pitchWheel", data: [channel, wheel] };
|
|
4031
4124
|
this.port.postMessage(e);
|
|
4032
4125
|
}
|
|
4126
|
+
keyOn(channel, pitch, velocity) {
|
|
4127
|
+
const e = { type: "keyOn", data: [channel, pitch, velocity] };
|
|
4128
|
+
this.port.postMessage(e);
|
|
4129
|
+
}
|
|
4130
|
+
keyOff(channel, pitch, velocity) {
|
|
4131
|
+
const e = { type: "keyOff", data: [channel, pitch, velocity] };
|
|
4132
|
+
this.port.postMessage(e);
|
|
4133
|
+
}
|
|
4033
4134
|
get hasAccInput() {
|
|
4034
4135
|
return __privateGet(this, _hasAccInput);
|
|
4035
4136
|
}
|
|
@@ -4193,42 +4294,14 @@ export default ${(_b = jsCode.match(jsCodeHead)) == null ? void 0 : _b[1]};
|
|
|
4193
4294
|
async startSensors() {
|
|
4194
4295
|
if (this.hasAccInput) {
|
|
4195
4296
|
if (window.DeviceMotionEvent) {
|
|
4196
|
-
|
|
4197
|
-
try {
|
|
4198
|
-
const response = await window.DeviceMotionEvent.requestPermission();
|
|
4199
|
-
if (response === "granted") {
|
|
4200
|
-
window.addEventListener("devicemotion", this.handleDeviceMotion, true);
|
|
4201
|
-
} else if (response === "denied") {
|
|
4202
|
-
alert("You have denied access to motion and orientation data. To enable it, go to Settings > Safari > Motion & Orientation Access.");
|
|
4203
|
-
throw new Error("Unable to access the accelerometer.");
|
|
4204
|
-
}
|
|
4205
|
-
} catch (error) {
|
|
4206
|
-
console.error(error);
|
|
4207
|
-
}
|
|
4208
|
-
} else {
|
|
4209
|
-
window.addEventListener("devicemotion", this.handleDeviceMotion, true);
|
|
4210
|
-
}
|
|
4297
|
+
window.addEventListener("devicemotion", this.handleDeviceMotion, true);
|
|
4211
4298
|
} else {
|
|
4212
4299
|
console.log("Cannot set the accelerometer handler.");
|
|
4213
4300
|
}
|
|
4214
4301
|
}
|
|
4215
4302
|
if (this.hasGyrInput) {
|
|
4216
4303
|
if (window.DeviceMotionEvent) {
|
|
4217
|
-
|
|
4218
|
-
try {
|
|
4219
|
-
const response = await window.DeviceOrientationEvent.requestPermission();
|
|
4220
|
-
if (response === "granted") {
|
|
4221
|
-
window.addEventListener("deviceorientation", this.handleDeviceOrientation, true);
|
|
4222
|
-
} else if (response === "denied") {
|
|
4223
|
-
alert("You have denied access to motion and orientation data. To enable it, go to Settings > Safari > Motion & Orientation Access.");
|
|
4224
|
-
throw new Error("Unable to access the gyroscope.");
|
|
4225
|
-
}
|
|
4226
|
-
} catch (error) {
|
|
4227
|
-
console.error(error);
|
|
4228
|
-
}
|
|
4229
|
-
} else {
|
|
4230
|
-
window.addEventListener("deviceorientation", this.handleDeviceOrientation, true);
|
|
4231
|
-
}
|
|
4304
|
+
window.addEventListener("deviceorientation", this.handleDeviceOrientation, true);
|
|
4232
4305
|
} else {
|
|
4233
4306
|
console.log("Cannot set the gyroscope handler.");
|
|
4234
4307
|
}
|
|
@@ -4281,6 +4354,12 @@ export default ${(_b = jsCode.match(jsCodeHead)) == null ? void 0 : _b[1]};
|
|
|
4281
4354
|
pitchWheel(chan, value) {
|
|
4282
4355
|
this.fDSPCode.pitchWheel(chan, value);
|
|
4283
4356
|
}
|
|
4357
|
+
keyOn(channel, pitch, velocity) {
|
|
4358
|
+
this.fDSPCode.keyOn(channel, pitch, velocity);
|
|
4359
|
+
}
|
|
4360
|
+
keyOff(channel, pitch, velocity) {
|
|
4361
|
+
this.fDSPCode.keyOff(channel, pitch, velocity);
|
|
4362
|
+
}
|
|
4284
4363
|
setParamValue(path, value) {
|
|
4285
4364
|
this.fDSPCode.setParamValue(path, value);
|
|
4286
4365
|
}
|