midiwire 0.11.1 → 0.11.3
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/dist/midiwire.es.js
CHANGED
|
@@ -53,8 +53,8 @@ class w {
|
|
|
53
53
|
this.selector === "[data-midi-cc]" ? "[data-midi-cc], [data-midi-msb][data-midi-lsb]" : this.selector
|
|
54
54
|
).forEach((s) => {
|
|
55
55
|
if (s.hasAttribute("data-midi-bound")) return;
|
|
56
|
-
const
|
|
57
|
-
|
|
56
|
+
const E = this._parseAttributes(s);
|
|
57
|
+
E && (this.controller.bind(s, E), s.setAttribute("data-midi-bound", "true"));
|
|
58
58
|
});
|
|
59
59
|
}
|
|
60
60
|
/**
|
|
@@ -82,22 +82,22 @@ class w {
|
|
|
82
82
|
if (this.observer) return;
|
|
83
83
|
const t = this.selector === "[data-midi-cc]" ? "[data-midi-cc], [data-midi-msb][data-midi-lsb]" : this.selector;
|
|
84
84
|
this.observer = new MutationObserver((s) => {
|
|
85
|
-
s.forEach((
|
|
86
|
-
|
|
87
|
-
if (
|
|
88
|
-
if (
|
|
89
|
-
const _ = this._parseAttributes(
|
|
90
|
-
_ && !
|
|
85
|
+
s.forEach((E) => {
|
|
86
|
+
E.addedNodes.forEach((e) => {
|
|
87
|
+
if (e.nodeType === Node.ELEMENT_NODE) {
|
|
88
|
+
if (e.matches?.(t)) {
|
|
89
|
+
const _ = this._parseAttributes(e);
|
|
90
|
+
_ && !e.hasAttribute("data-midi-bound") && (this.controller.bind(e, _), e.setAttribute("data-midi-bound", "true"));
|
|
91
91
|
}
|
|
92
|
-
|
|
92
|
+
e.querySelectorAll && e.querySelectorAll(t).forEach((i) => {
|
|
93
93
|
if (!i.hasAttribute("data-midi-bound")) {
|
|
94
94
|
const r = this._parseAttributes(i);
|
|
95
95
|
r && (this.controller.bind(i, r), i.setAttribute("data-midi-bound", "true"));
|
|
96
96
|
}
|
|
97
97
|
});
|
|
98
98
|
}
|
|
99
|
-
}),
|
|
100
|
-
|
|
99
|
+
}), E.removedNodes.forEach((e) => {
|
|
100
|
+
e.nodeType === Node.ELEMENT_NODE && (e.hasAttribute?.("data-midi-bound") && this.controller.unbind(e), e.querySelectorAll && e.querySelectorAll("[data-midi-bound]").forEach((i) => {
|
|
101
101
|
this.controller.unbind(i);
|
|
102
102
|
}));
|
|
103
103
|
});
|
|
@@ -150,15 +150,15 @@ class w {
|
|
|
150
150
|
* // Returns: { msb: 74, lsb: 75, is14Bit: true, min: 0, max: 16383 }
|
|
151
151
|
*/
|
|
152
152
|
_parseAttributes(t) {
|
|
153
|
-
const s = parseInt(t.dataset.midiMsb, 10),
|
|
154
|
-
if (!Number.isNaN(s) && !Number.isNaN(
|
|
153
|
+
const s = parseInt(t.dataset.midiMsb, 10), E = parseInt(t.dataset.midiLsb, 10);
|
|
154
|
+
if (!Number.isNaN(s) && !Number.isNaN(E) && s >= 0 && s <= 127 && E >= 0 && E <= 127) {
|
|
155
155
|
const _ = parseInt(t.dataset.midiCc, 10);
|
|
156
156
|
return !Number.isNaN(_) && _ >= 0 && _ <= 127 && console.warn(
|
|
157
|
-
`Element has both 7-bit (data-midi-cc="${_}") and 14-bit (data-midi-msb="${s}" data-midi-lsb="${
|
|
157
|
+
`Element has both 7-bit (data-midi-cc="${_}") and 14-bit (data-midi-msb="${s}" data-midi-lsb="${E}") CC attributes. 14-bit takes precedence.`,
|
|
158
158
|
t
|
|
159
159
|
), {
|
|
160
160
|
msb: s,
|
|
161
|
-
lsb:
|
|
161
|
+
lsb: E,
|
|
162
162
|
is14Bit: !0,
|
|
163
163
|
channel: parseInt(t.dataset.midiChannel, 10) || void 0,
|
|
164
164
|
min: parseFloat(t.getAttribute("min")) || 0,
|
|
@@ -167,9 +167,9 @@ class w {
|
|
|
167
167
|
label: t.dataset.midiLabel
|
|
168
168
|
};
|
|
169
169
|
}
|
|
170
|
-
const
|
|
171
|
-
return !Number.isNaN(
|
|
172
|
-
cc:
|
|
170
|
+
const e = parseInt(t.dataset.midiCc, 10);
|
|
171
|
+
return !Number.isNaN(e) && e >= 0 && e <= 127 ? {
|
|
172
|
+
cc: e,
|
|
173
173
|
channel: parseInt(t.dataset.midiChannel, 10) || void 0,
|
|
174
174
|
min: parseFloat(t.getAttribute("min")) || 0,
|
|
175
175
|
max: parseFloat(t.getAttribute("max")) || 127,
|
|
@@ -219,8 +219,8 @@ class F extends R {
|
|
|
219
219
|
}
|
|
220
220
|
}
|
|
221
221
|
class K extends R {
|
|
222
|
-
constructor(t, s,
|
|
223
|
-
super(t, "MIDI_DEVICE_ERROR"), this.name = "MIDIDeviceError", this.deviceType = s, this.deviceId =
|
|
222
|
+
constructor(t, s, E) {
|
|
223
|
+
super(t, "MIDI_DEVICE_ERROR"), this.name = "MIDIDeviceError", this.deviceType = s, this.deviceId = E;
|
|
224
224
|
}
|
|
225
225
|
}
|
|
226
226
|
class L extends R {
|
|
@@ -234,27 +234,27 @@ class b extends Error {
|
|
|
234
234
|
}
|
|
235
235
|
}
|
|
236
236
|
class m extends b {
|
|
237
|
-
constructor(t, s,
|
|
238
|
-
super(t, "DX7_PARSE_ERROR"), this.name = "DX7ParseError", this.parseType = s, this.offset =
|
|
237
|
+
constructor(t, s, E) {
|
|
238
|
+
super(t, "DX7_PARSE_ERROR"), this.name = "DX7ParseError", this.parseType = s, this.offset = E;
|
|
239
239
|
}
|
|
240
240
|
}
|
|
241
241
|
class c extends b {
|
|
242
|
-
constructor(t, s,
|
|
243
|
-
super(t, "DX7_VALIDATION_ERROR"), this.name = "DX7ValidationError", this.validationType = s, this.value =
|
|
242
|
+
constructor(t, s, E) {
|
|
243
|
+
super(t, "DX7_VALIDATION_ERROR"), this.name = "DX7ValidationError", this.validationType = s, this.value = E;
|
|
244
244
|
}
|
|
245
245
|
}
|
|
246
|
-
function O(
|
|
247
|
-
return Math.max(t, Math.min(s,
|
|
246
|
+
function O(A, t, s) {
|
|
247
|
+
return Math.max(t, Math.min(s, A));
|
|
248
248
|
}
|
|
249
|
-
function x(
|
|
250
|
-
const
|
|
249
|
+
function x(A, t, s, E = !1) {
|
|
250
|
+
const e = (A - t) / (s - t), i = (E ? 1 - e : e) * 127;
|
|
251
251
|
return O(Math.round(i), 0, 127);
|
|
252
252
|
}
|
|
253
|
-
function Q(
|
|
254
|
-
let
|
|
255
|
-
return
|
|
253
|
+
function Q(A, t, s, E = !1) {
|
|
254
|
+
let e = O(A, 0, 127) / 127;
|
|
255
|
+
return E && (e = 1 - e), t + e * (s - t);
|
|
256
256
|
}
|
|
257
|
-
function J(
|
|
257
|
+
function J(A) {
|
|
258
258
|
const t = {
|
|
259
259
|
C: 0,
|
|
260
260
|
"C#": 1,
|
|
@@ -273,27 +273,27 @@ function J(o) {
|
|
|
273
273
|
"A#": 10,
|
|
274
274
|
BB: 10,
|
|
275
275
|
B: 11
|
|
276
|
-
}, s =
|
|
276
|
+
}, s = A.match(/^([A-G][#b]?)(-?\d+)$/i);
|
|
277
277
|
if (!s)
|
|
278
|
-
throw new L(`Invalid note name: ${
|
|
279
|
-
const [,
|
|
278
|
+
throw new L(`Invalid note name: ${A}`, "note", A);
|
|
279
|
+
const [, E, e] = s, _ = t[E.toUpperCase()];
|
|
280
280
|
if (_ === void 0)
|
|
281
|
-
throw new L(`Invalid note: ${
|
|
282
|
-
const i = (parseInt(
|
|
281
|
+
throw new L(`Invalid note: ${E}`, "note", E);
|
|
282
|
+
const i = (parseInt(e, 10) + 1) * 12 + _;
|
|
283
283
|
return O(i, 0, 127);
|
|
284
284
|
}
|
|
285
|
-
function j(
|
|
286
|
-
const
|
|
287
|
-
return `${
|
|
285
|
+
function j(A, t = !1) {
|
|
286
|
+
const e = t ? ["C", "Db", "D", "Eb", "E", "F", "Gb", "G", "Ab", "A", "Bb", "B"] : ["C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"], _ = Math.floor(A / 12) - 1;
|
|
287
|
+
return `${e[A % 12]}${_}`;
|
|
288
288
|
}
|
|
289
|
-
function k(
|
|
290
|
-
const t = 69 + 12 * Math.log2(
|
|
289
|
+
function k(A) {
|
|
290
|
+
const t = 69 + 12 * Math.log2(A / 440);
|
|
291
291
|
return O(Math.round(t), 0, 127);
|
|
292
292
|
}
|
|
293
|
-
function V(
|
|
294
|
-
return 440 * 2 ** ((
|
|
293
|
+
function V(A) {
|
|
294
|
+
return 440 * 2 ** ((A - 69) / 12);
|
|
295
295
|
}
|
|
296
|
-
function X(
|
|
296
|
+
function X(A) {
|
|
297
297
|
return {
|
|
298
298
|
0: "Bank Select",
|
|
299
299
|
1: "Modulation",
|
|
@@ -326,25 +326,25 @@ function X(o) {
|
|
|
326
326
|
120: "All Sound Off",
|
|
327
327
|
121: "Reset All Controllers",
|
|
328
328
|
123: "All Notes Off"
|
|
329
|
-
}[
|
|
329
|
+
}[A] || `CC ${A}`;
|
|
330
330
|
}
|
|
331
|
-
function B(
|
|
332
|
-
const t = O(Math.round(
|
|
331
|
+
function B(A) {
|
|
332
|
+
const t = O(Math.round(A), 0, 16383);
|
|
333
333
|
return {
|
|
334
334
|
msb: t >> 7 & 127,
|
|
335
335
|
lsb: t & 127
|
|
336
336
|
};
|
|
337
337
|
}
|
|
338
|
-
function Y(
|
|
339
|
-
return O(
|
|
338
|
+
function Y(A, t) {
|
|
339
|
+
return O(A, 0, 127) << 7 | O(t, 0, 127);
|
|
340
340
|
}
|
|
341
|
-
function $(
|
|
342
|
-
const
|
|
341
|
+
function $(A, t, s, E = !1) {
|
|
342
|
+
const e = (A - t) / (s - t), i = (E ? 1 - e : e) * 16383;
|
|
343
343
|
return B(i);
|
|
344
344
|
}
|
|
345
|
-
function tt(
|
|
346
|
-
let i = Y(
|
|
347
|
-
return
|
|
345
|
+
function tt(A, t, s, E, e = !1) {
|
|
346
|
+
let i = Y(A, t) / 16383;
|
|
347
|
+
return e && (i = 1 - i), s + i * (E - s);
|
|
348
348
|
}
|
|
349
349
|
class H {
|
|
350
350
|
constructor() {
|
|
@@ -365,10 +365,10 @@ class H {
|
|
|
365
365
|
* @param {Function} handler - Event handler function
|
|
366
366
|
*/
|
|
367
367
|
once(t, s) {
|
|
368
|
-
const
|
|
369
|
-
s(...
|
|
368
|
+
const E = (...e) => {
|
|
369
|
+
s(...e), this.off(t, E);
|
|
370
370
|
};
|
|
371
|
-
this.on(t,
|
|
371
|
+
this.on(t, E);
|
|
372
372
|
}
|
|
373
373
|
/**
|
|
374
374
|
* Remove an event listener
|
|
@@ -377,8 +377,8 @@ class H {
|
|
|
377
377
|
*/
|
|
378
378
|
off(t, s) {
|
|
379
379
|
if (!this.events.has(t)) return;
|
|
380
|
-
const
|
|
381
|
-
|
|
380
|
+
const E = this.events.get(t), e = E.indexOf(s);
|
|
381
|
+
e > -1 && E.splice(e, 1), E.length === 0 && this.events.delete(t);
|
|
382
382
|
}
|
|
383
383
|
/**
|
|
384
384
|
* Emit an event
|
|
@@ -387,9 +387,9 @@ class H {
|
|
|
387
387
|
*/
|
|
388
388
|
emit(t, s) {
|
|
389
389
|
if (!this.events.has(t)) return;
|
|
390
|
-
[...this.events.get(t)].forEach((
|
|
390
|
+
[...this.events.get(t)].forEach((e) => {
|
|
391
391
|
try {
|
|
392
|
-
|
|
392
|
+
e(s);
|
|
393
393
|
} catch (_) {
|
|
394
394
|
console.error(`Error in event handler for "${t}":`, _);
|
|
395
395
|
}
|
|
@@ -450,17 +450,17 @@ class Z extends H {
|
|
|
450
450
|
this.midiAccess = await navigator.requestMIDIAccess({
|
|
451
451
|
sysex: this.options.sysex
|
|
452
452
|
}), this.midiAccess.onstatechange = (t) => {
|
|
453
|
-
const s = t.port,
|
|
453
|
+
const s = t.port, E = t.port.state;
|
|
454
454
|
this.emit(U.DEVICE_CHANGE, {
|
|
455
455
|
port: s,
|
|
456
|
-
state:
|
|
456
|
+
state: E,
|
|
457
457
|
type: s.type,
|
|
458
458
|
device: {
|
|
459
459
|
id: s.id,
|
|
460
460
|
name: s.name,
|
|
461
461
|
manufacturer: s.manufacturer || "Unknown"
|
|
462
462
|
}
|
|
463
|
-
}),
|
|
463
|
+
}), E === "disconnected" ? s.type === "input" ? (this.emit(U.IN_DEV_DISCONNECTED, { device: s }), this.input && this.input.id === s.id && (this.input = null)) : s.type === "output" && (this.emit(U.OUT_DEV_DISCONNECTED, { device: s }), this.output && this.output.id === s.id && (this.output = null)) : E === "connected" && (s.type === "input" ? this.emit(U.IN_DEV_CONNECTED, { device: s }) : s.type === "output" && this.emit(U.OUT_DEV_CONNECTED, { device: s }));
|
|
464
464
|
};
|
|
465
465
|
} catch (t) {
|
|
466
466
|
throw t.name === "SecurityError" ? new g("MIDI access denied. SysEx requires user permission.", "denied") : new g(`Failed to get MIDI access: ${t.message}`, "failed");
|
|
@@ -506,9 +506,9 @@ class Z extends H {
|
|
|
506
506
|
this.output = s[t];
|
|
507
507
|
return;
|
|
508
508
|
}
|
|
509
|
-
if (this.output = s.find((
|
|
510
|
-
const
|
|
511
|
-
throw new K(`MIDI output "${t}" not found. Available: ${
|
|
509
|
+
if (this.output = s.find((E) => E.name === t || E.id === t), !this.output) {
|
|
510
|
+
const E = s.map((e) => e.name).join(", ");
|
|
511
|
+
throw new K(`MIDI output "${t}" not found. Available: ${E}`, "output", t);
|
|
512
512
|
}
|
|
513
513
|
}
|
|
514
514
|
/**
|
|
@@ -525,21 +525,21 @@ class Z extends H {
|
|
|
525
525
|
throw new F("MIDI access not initialized. Call requestAccess() first.");
|
|
526
526
|
if (typeof s != "function")
|
|
527
527
|
throw new L("onMessage callback must be a function", "callback");
|
|
528
|
-
const
|
|
529
|
-
if (
|
|
528
|
+
const E = Array.from(this.midiAccess.inputs.values());
|
|
529
|
+
if (E.length === 0)
|
|
530
530
|
throw new K("No MIDI input devices available", "input");
|
|
531
531
|
if (this.input && (this.input.onmidimessage = null), t === void 0)
|
|
532
|
-
this.input =
|
|
532
|
+
this.input = E[0];
|
|
533
533
|
else if (typeof t == "number") {
|
|
534
|
-
if (t < 0 || t >=
|
|
535
|
-
throw new K(`Input index ${t} out of range (0-${
|
|
536
|
-
this.input =
|
|
537
|
-
} else if (this.input =
|
|
538
|
-
const
|
|
539
|
-
throw new K(`MIDI input "${t}" not found. Available: ${
|
|
540
|
-
}
|
|
541
|
-
this.input.onmidimessage = (
|
|
542
|
-
s(
|
|
534
|
+
if (t < 0 || t >= E.length)
|
|
535
|
+
throw new K(`Input index ${t} out of range (0-${E.length - 1})`, "input", t);
|
|
536
|
+
this.input = E[t];
|
|
537
|
+
} else if (this.input = E.find((e) => e.name === t || e.id === t), !this.input) {
|
|
538
|
+
const e = E.map((_) => _.name).join(", ");
|
|
539
|
+
throw new K(`MIDI input "${t}" not found. Available: ${e}`, "input", t);
|
|
540
|
+
}
|
|
541
|
+
this.input.onmidimessage = (e) => {
|
|
542
|
+
s(e);
|
|
543
543
|
};
|
|
544
544
|
}
|
|
545
545
|
/**
|
|
@@ -645,10 +645,10 @@ class Z extends H {
|
|
|
645
645
|
return;
|
|
646
646
|
}
|
|
647
647
|
try {
|
|
648
|
-
const
|
|
649
|
-
s === null ? this.output.send(
|
|
650
|
-
} catch (
|
|
651
|
-
console.error("Failed to send MIDI message:",
|
|
648
|
+
const E = new Uint8Array(t);
|
|
649
|
+
s === null ? this.output.send(E) : this.output.send(E, s);
|
|
650
|
+
} catch (E) {
|
|
651
|
+
console.error("Failed to send MIDI message:", E);
|
|
652
652
|
}
|
|
653
653
|
}
|
|
654
654
|
/**
|
|
@@ -671,11 +671,11 @@ class Z extends H {
|
|
|
671
671
|
console.warn("SysEx not enabled. Initialize with sysex: true");
|
|
672
672
|
return;
|
|
673
673
|
}
|
|
674
|
-
let
|
|
675
|
-
s ?
|
|
674
|
+
let E;
|
|
675
|
+
s ? E = [240, ...t, 247] : E = t, this.send(E);
|
|
676
676
|
}
|
|
677
677
|
}
|
|
678
|
-
const
|
|
678
|
+
const o = {
|
|
679
679
|
// Core controller events
|
|
680
680
|
READY: "ready",
|
|
681
681
|
ERROR: "error",
|
|
@@ -803,26 +803,26 @@ class z extends H {
|
|
|
803
803
|
try {
|
|
804
804
|
this.connection = new Z({
|
|
805
805
|
sysex: this.options.sysex
|
|
806
|
-
}), await this.connection.requestAccess(), this.connection.on(U.DEVICE_CHANGE, async ({ state: t, type: s, device:
|
|
806
|
+
}), await this.connection.requestAccess(), this.connection.on(U.DEVICE_CHANGE, async ({ state: t, type: s, device: E }) => {
|
|
807
807
|
try {
|
|
808
808
|
if (t === "connected")
|
|
809
|
-
s === "output" ? this.emit(
|
|
809
|
+
s === "output" ? this.emit(o.DEV_OUT_CONNECTED, E) : s === "input" && this.emit(o.DEV_IN_CONNECTED, E);
|
|
810
810
|
else if (t === "disconnected") {
|
|
811
|
-
if (s === "output" &&
|
|
812
|
-
const
|
|
813
|
-
|
|
811
|
+
if (s === "output" && E) {
|
|
812
|
+
const e = this.connection.getCurrentOutput();
|
|
813
|
+
e && e.id === E.id ? await this._disconnectOutput() : this.emit(o.DEV_OUT_DISCONNECTED, E);
|
|
814
814
|
}
|
|
815
|
-
if (s === "input" &&
|
|
816
|
-
const
|
|
817
|
-
|
|
815
|
+
if (s === "input" && E) {
|
|
816
|
+
const e = this.connection.getCurrentInput();
|
|
817
|
+
e && e.id === E.id ? await this._disconnectInput() : this.emit(o.DEV_IN_DISCONNECTED, E);
|
|
818
818
|
}
|
|
819
819
|
}
|
|
820
|
-
} catch (
|
|
821
|
-
console.error("Error in device change handler:",
|
|
820
|
+
} catch (e) {
|
|
821
|
+
console.error("Error in device change handler:", e), this.emit(o.ERROR, e);
|
|
822
822
|
}
|
|
823
|
-
}), this.options.autoConnect && await this.connection.connect(this.options.output), this.options.input !== void 0 && await this._connectInput(this.options.input), this.initialized = !0, this.emit(
|
|
823
|
+
}), this.options.autoConnect && await this.connection.connect(this.options.output), this.options.input !== void 0 && await this._connectInput(this.options.input), this.initialized = !0, this.emit(o.READY, this), this.options.onReady?.(this);
|
|
824
824
|
} catch (t) {
|
|
825
|
-
throw this.emit(
|
|
825
|
+
throw this.emit(o.ERROR, t), this.options.onError?.(t), t;
|
|
826
826
|
}
|
|
827
827
|
}
|
|
828
828
|
/**
|
|
@@ -1300,12 +1300,12 @@ class z extends H {
|
|
|
1300
1300
|
* }
|
|
1301
1301
|
* });
|
|
1302
1302
|
*/
|
|
1303
|
-
bind(t, s,
|
|
1303
|
+
bind(t, s, E = {}) {
|
|
1304
1304
|
if (!t)
|
|
1305
1305
|
return console.warn("Cannot bind: element is null or undefined"), () => {
|
|
1306
1306
|
};
|
|
1307
|
-
const
|
|
1308
|
-
return this.bindings.set(t,
|
|
1307
|
+
const e = this._createBinding(t, s, E);
|
|
1308
|
+
return this.bindings.set(t, e), this.initialized && this.connection?.isConnected() && e.handler({ target: t }), () => this.unbind(t);
|
|
1309
1309
|
}
|
|
1310
1310
|
/**
|
|
1311
1311
|
* Create a binding between an element and MIDI CC
|
|
@@ -1315,16 +1315,16 @@ class z extends H {
|
|
|
1315
1315
|
* @param {Object} options - Additional binding options
|
|
1316
1316
|
* @returns {Object} Binding object with element, config, handler, and destroy function
|
|
1317
1317
|
*/
|
|
1318
|
-
_createBinding(t, s,
|
|
1318
|
+
_createBinding(t, s, E = {}) {
|
|
1319
1319
|
const {
|
|
1320
|
-
min:
|
|
1320
|
+
min: e = parseFloat(t.getAttribute("min")) || 0,
|
|
1321
1321
|
max: _ = parseFloat(t.getAttribute("max")) || 127,
|
|
1322
1322
|
channel: i,
|
|
1323
1323
|
invert: r = !1,
|
|
1324
1324
|
onInput: u = void 0
|
|
1325
|
-
} = s, { debounce: S = 0 } =
|
|
1325
|
+
} = s, { debounce: S = 0 } = E, P = {
|
|
1326
1326
|
...s,
|
|
1327
|
-
min:
|
|
1327
|
+
min: e,
|
|
1328
1328
|
max: _,
|
|
1329
1329
|
invert: r,
|
|
1330
1330
|
onInput: u
|
|
@@ -1333,7 +1333,7 @@ class z extends H {
|
|
|
1333
1333
|
const { msb: d, lsb: T } = s, f = (M) => {
|
|
1334
1334
|
const D = parseFloat(M.target.value);
|
|
1335
1335
|
if (Number.isNaN(D)) return;
|
|
1336
|
-
const { msb: y, lsb: v } = $(D,
|
|
1336
|
+
const { msb: y, lsb: v } = $(D, e, _, r), G = i || this.options.outputChannel;
|
|
1337
1337
|
this._sendCC(d, y, G), this._sendCC(T, v, G);
|
|
1338
1338
|
};
|
|
1339
1339
|
let I = null;
|
|
@@ -1351,22 +1351,22 @@ class z extends H {
|
|
|
1351
1351
|
}
|
|
1352
1352
|
};
|
|
1353
1353
|
}
|
|
1354
|
-
const { cc: a } = s,
|
|
1354
|
+
const { cc: a } = s, C = (d) => {
|
|
1355
1355
|
const T = parseFloat(d.target.value);
|
|
1356
1356
|
if (Number.isNaN(T)) return;
|
|
1357
|
-
const f = x(T,
|
|
1357
|
+
const f = x(T, e, _, r), I = i === void 0 ? this.options.outputChannel : i;
|
|
1358
1358
|
this._sendCC(a, f, I);
|
|
1359
1359
|
};
|
|
1360
1360
|
let h = null;
|
|
1361
1361
|
const N = S > 0 ? (d) => {
|
|
1362
1362
|
h && clearTimeout(h), h = setTimeout(() => {
|
|
1363
|
-
|
|
1363
|
+
C(d), h = null;
|
|
1364
1364
|
}, S);
|
|
1365
|
-
} :
|
|
1365
|
+
} : C;
|
|
1366
1366
|
return t.addEventListener("input", N), t.addEventListener("change", N), {
|
|
1367
1367
|
element: t,
|
|
1368
1368
|
config: P,
|
|
1369
|
-
handler:
|
|
1369
|
+
handler: C,
|
|
1370
1370
|
destroy: () => {
|
|
1371
1371
|
h && clearTimeout(h), t.removeEventListener("input", N), t.removeEventListener("change", N);
|
|
1372
1372
|
}
|
|
@@ -1387,7 +1387,7 @@ class z extends H {
|
|
|
1387
1387
|
async destroy() {
|
|
1388
1388
|
for (const t of this.bindings.values())
|
|
1389
1389
|
t.destroy();
|
|
1390
|
-
this.bindings.clear(), this.state.controlChange.clear(), this.state.programChange.clear(), this.state.pitchBend.clear(), this.state.monoPressure.clear(), this.state.polyPressure.clear(), await this._disconnect(), this.initialized = !1, this.emit(
|
|
1390
|
+
this.bindings.clear(), this.state.controlChange.clear(), this.state.programChange.clear(), this.state.pitchBend.clear(), this.state.monoPressure.clear(), this.state.polyPressure.clear(), await this._disconnect(), this.initialized = !1, this.emit(o.DESTROYED), this.removeAllListeners();
|
|
1391
1391
|
}
|
|
1392
1392
|
/**
|
|
1393
1393
|
* Connect to MIDI output device
|
|
@@ -1415,7 +1415,7 @@ class z extends H {
|
|
|
1415
1415
|
async _connectInput(t) {
|
|
1416
1416
|
await this.connection.connectInput(t, (s) => {
|
|
1417
1417
|
this._handleMIDIMessage(s);
|
|
1418
|
-
}), this.emit(
|
|
1418
|
+
}), this.emit(o.DEV_IN_CONNECTED, this.connection.getCurrentInput());
|
|
1419
1419
|
}
|
|
1420
1420
|
/**
|
|
1421
1421
|
* Disconnect from MIDI input device
|
|
@@ -1424,7 +1424,7 @@ class z extends H {
|
|
|
1424
1424
|
*/
|
|
1425
1425
|
async _disconnectInput() {
|
|
1426
1426
|
const t = this.connection.getCurrentInput();
|
|
1427
|
-
this.connection.disconnectInput(), this.emit(
|
|
1427
|
+
this.connection.disconnectInput(), this.emit(o.DEV_IN_DISCONNECTED, t);
|
|
1428
1428
|
}
|
|
1429
1429
|
/**
|
|
1430
1430
|
* Connect to MIDI output device
|
|
@@ -1433,7 +1433,7 @@ class z extends H {
|
|
|
1433
1433
|
* @returns {Promise<void>}
|
|
1434
1434
|
*/
|
|
1435
1435
|
async _connectOutput(t) {
|
|
1436
|
-
await this.connection.connect(t), this.emit(
|
|
1436
|
+
await this.connection.connect(t), this.emit(o.DEV_OUT_CONNECTED, this.connection.getCurrentOutput());
|
|
1437
1437
|
}
|
|
1438
1438
|
/**
|
|
1439
1439
|
* Disconnect from MIDI output device
|
|
@@ -1442,7 +1442,7 @@ class z extends H {
|
|
|
1442
1442
|
*/
|
|
1443
1443
|
async _disconnectOutput() {
|
|
1444
1444
|
const t = this.connection.getCurrentOutput();
|
|
1445
|
-
this.connection.disconnectOutput(), this.emit(
|
|
1445
|
+
this.connection.disconnectOutput(), this.emit(o.DEV_OUT_DISCONNECTED, t);
|
|
1446
1446
|
}
|
|
1447
1447
|
/**
|
|
1448
1448
|
* Get current output device information
|
|
@@ -1495,11 +1495,11 @@ class z extends H {
|
|
|
1495
1495
|
* @param {number} channel - MIDI channel (1-16, default outputChannel)
|
|
1496
1496
|
* @returns {void}
|
|
1497
1497
|
*/
|
|
1498
|
-
_sendNoteOn(t, s = 64,
|
|
1498
|
+
_sendNoteOn(t, s = 64, E = this.options.outputChannel) {
|
|
1499
1499
|
if (!this.initialized) return;
|
|
1500
|
-
t = O(Math.round(t), 0, 127), s = O(Math.round(s), 0, 127),
|
|
1501
|
-
const
|
|
1502
|
-
this.connection.send([
|
|
1500
|
+
t = O(Math.round(t), 0, 127), s = O(Math.round(s), 0, 127), E = O(Math.round(E), 1, 16);
|
|
1501
|
+
const e = 144 + (E - 1);
|
|
1502
|
+
this.connection.send([e, t, s]), this.emit(o.CH_NOTE_ON_SEND, { note: t, velocity: s, channel: E });
|
|
1503
1503
|
}
|
|
1504
1504
|
/**
|
|
1505
1505
|
* Send Note Off message
|
|
@@ -1509,11 +1509,11 @@ class z extends H {
|
|
|
1509
1509
|
* @param {number} velocity - Release velocity (0-127, default 0)
|
|
1510
1510
|
* @returns {void}
|
|
1511
1511
|
*/
|
|
1512
|
-
_sendNoteOff(t, s = this.options.outputChannel,
|
|
1512
|
+
_sendNoteOff(t, s = this.options.outputChannel, E = 0) {
|
|
1513
1513
|
if (!this.initialized) return;
|
|
1514
|
-
t = O(Math.round(t), 0, 127),
|
|
1515
|
-
const
|
|
1516
|
-
this.connection.send([
|
|
1514
|
+
t = O(Math.round(t), 0, 127), E = O(Math.round(E), 0, 127), s = O(Math.round(s), 1, 16);
|
|
1515
|
+
const e = 144 + (s - 1);
|
|
1516
|
+
this.connection.send([e, t, E]), this.emit(o.CH_NOTE_OFF_SEND, { note: t, channel: s, velocity: E });
|
|
1517
1517
|
}
|
|
1518
1518
|
/**
|
|
1519
1519
|
* Send Control Change message
|
|
@@ -1523,16 +1523,16 @@ class z extends H {
|
|
|
1523
1523
|
* @param {number} channel - MIDI channel (1-16, default outputChannel)
|
|
1524
1524
|
* @returns {void}
|
|
1525
1525
|
*/
|
|
1526
|
-
_sendCC(t, s,
|
|
1526
|
+
_sendCC(t, s, E = this.options.outputChannel) {
|
|
1527
1527
|
if (!this.initialized) {
|
|
1528
1528
|
console.warn("MIDI not initialized. Call init() first.");
|
|
1529
1529
|
return;
|
|
1530
1530
|
}
|
|
1531
|
-
t = O(Math.round(t), 0, 127), s = O(Math.round(s), 0, 127),
|
|
1532
|
-
const
|
|
1533
|
-
this.connection.send([
|
|
1534
|
-
const _ = `${
|
|
1535
|
-
this.state.controlChange.set(_, s), this.emit(
|
|
1531
|
+
t = O(Math.round(t), 0, 127), s = O(Math.round(s), 0, 127), E = O(Math.round(E), 1, 16);
|
|
1532
|
+
const e = 176 + (E - 1);
|
|
1533
|
+
this.connection.send([e, t, s]);
|
|
1534
|
+
const _ = `${E}:${t}`;
|
|
1535
|
+
this.state.controlChange.set(_, s), this.emit(o.CH_CC_SEND, { cc: t, value: s, channel: E });
|
|
1536
1536
|
}
|
|
1537
1537
|
/**
|
|
1538
1538
|
* Send Program Change message
|
|
@@ -1544,8 +1544,8 @@ class z extends H {
|
|
|
1544
1544
|
_sendPC(t, s = this.options.outputChannel) {
|
|
1545
1545
|
if (!this.initialized) return;
|
|
1546
1546
|
t = O(Math.round(t), 0, 127), s = O(Math.round(s), 1, 16);
|
|
1547
|
-
const
|
|
1548
|
-
this.connection.send([
|
|
1547
|
+
const E = 192 + (s - 1);
|
|
1548
|
+
this.connection.send([E, t]), this.state.programChange.set(s.toString(), t), this.emit(o.CH_PC_SEND, { program: t, channel: s });
|
|
1549
1549
|
}
|
|
1550
1550
|
/**
|
|
1551
1551
|
* Get current Program Change value for channel
|
|
@@ -1564,8 +1564,8 @@ class z extends H {
|
|
|
1564
1564
|
* @returns {number|undefined} CC value or undefined if not set
|
|
1565
1565
|
*/
|
|
1566
1566
|
_getCC(t, s = this.options.inputChannel) {
|
|
1567
|
-
const
|
|
1568
|
-
return this.state.controlChange.get(
|
|
1567
|
+
const E = `${s}:${t}`;
|
|
1568
|
+
return this.state.controlChange.get(E);
|
|
1569
1569
|
}
|
|
1570
1570
|
/**
|
|
1571
1571
|
* Send Pitch Bend message on specified channel
|
|
@@ -1577,8 +1577,8 @@ class z extends H {
|
|
|
1577
1577
|
_sendPitchBend(t, s = this.options.outputChannel) {
|
|
1578
1578
|
if (!this.initialized) return;
|
|
1579
1579
|
t = O(Math.round(t), 0, 16383), s = O(Math.round(s), 1, 16);
|
|
1580
|
-
const
|
|
1581
|
-
this.connection.send([
|
|
1580
|
+
const E = 224 + (s - 1), e = t & 127, _ = t >> 7 & 127;
|
|
1581
|
+
this.connection.send([E, e, _]), this.state.pitchBend.set(s.toString(), t), this.emit(o.CH_PITCH_BEND_SEND, { value: t, channel: s });
|
|
1582
1582
|
}
|
|
1583
1583
|
/**
|
|
1584
1584
|
* Get current Pitch Bend value for a channel
|
|
@@ -1599,8 +1599,8 @@ class z extends H {
|
|
|
1599
1599
|
_sendMonoPressure(t, s = this.options.outputChannel) {
|
|
1600
1600
|
if (!this.initialized) return;
|
|
1601
1601
|
t = O(Math.round(t), 0, 127), s = O(Math.round(s), 1, 16);
|
|
1602
|
-
const
|
|
1603
|
-
this.connection.send([
|
|
1602
|
+
const E = 208 + (s - 1);
|
|
1603
|
+
this.connection.send([E, t]), this.state.monoPressure.set(s.toString(), t), this.emit(o.CH_MONO_PRESS_SEND, { pressure: t, channel: s });
|
|
1604
1604
|
}
|
|
1605
1605
|
/**
|
|
1606
1606
|
* Get current Channel Pressure (Aftertouch) value for a channel
|
|
@@ -1619,13 +1619,13 @@ class z extends H {
|
|
|
1619
1619
|
* @param {number} channel - MIDI channel (1-16, default outputChannel)
|
|
1620
1620
|
* @returns {void}
|
|
1621
1621
|
*/
|
|
1622
|
-
_sendPolyPressure(t, s,
|
|
1622
|
+
_sendPolyPressure(t, s, E = this.options.outputChannel) {
|
|
1623
1623
|
if (!this.initialized) return;
|
|
1624
|
-
t = O(Math.round(t), 0, 127), s = O(Math.round(s), 0, 127),
|
|
1625
|
-
const
|
|
1626
|
-
this.connection.send([
|
|
1627
|
-
const _ = `${
|
|
1628
|
-
this.state.polyPressure.set(_, s), this.emit(
|
|
1624
|
+
t = O(Math.round(t), 0, 127), s = O(Math.round(s), 0, 127), E = O(Math.round(E), 1, 16);
|
|
1625
|
+
const e = 160 + (E - 1);
|
|
1626
|
+
this.connection.send([e, t, s]);
|
|
1627
|
+
const _ = `${E}:${t}`;
|
|
1628
|
+
this.state.polyPressure.set(_, s), this.emit(o.CH_POLY_PRESS_SEND, { note: t, pressure: s, channel: E });
|
|
1629
1629
|
}
|
|
1630
1630
|
/**
|
|
1631
1631
|
* Get current Polyphonic Pressure (Aftertouch) value for a specific note on a channel
|
|
@@ -1635,8 +1635,8 @@ class z extends H {
|
|
|
1635
1635
|
* @returns {number|undefined} Pressure value (0-127) or undefined if not set
|
|
1636
1636
|
*/
|
|
1637
1637
|
_getPolyPressure(t, s = this.options.inputChannel) {
|
|
1638
|
-
const
|
|
1639
|
-
return this.state.polyPressure.get(
|
|
1638
|
+
const E = `${s}:${t}`;
|
|
1639
|
+
return this.state.polyPressure.get(E);
|
|
1640
1640
|
}
|
|
1641
1641
|
/**
|
|
1642
1642
|
* @private
|
|
@@ -1649,13 +1649,13 @@ class z extends H {
|
|
|
1649
1649
|
if (t !== void 0) {
|
|
1650
1650
|
t = O(Math.round(t), 1, 16);
|
|
1651
1651
|
const s = 176 + (t - 1);
|
|
1652
|
-
this.connection.send([s, 120, 0]), this.emit(
|
|
1652
|
+
this.connection.send([s, 120, 0]), this.emit(o.CH_ALL_SOUNDS_OFF_SEND, { channel: t });
|
|
1653
1653
|
} else {
|
|
1654
1654
|
for (let s = 1; s <= 16; s++) {
|
|
1655
|
-
const
|
|
1656
|
-
this.connection.send([
|
|
1655
|
+
const E = 176 + (s - 1);
|
|
1656
|
+
this.connection.send([E, 120, 0]);
|
|
1657
1657
|
}
|
|
1658
|
-
this.emit(
|
|
1658
|
+
this.emit(o.CH_ALL_SOUNDS_OFF_SEND, { channel: null });
|
|
1659
1659
|
}
|
|
1660
1660
|
}
|
|
1661
1661
|
/**
|
|
@@ -1669,13 +1669,13 @@ class z extends H {
|
|
|
1669
1669
|
if (t !== void 0) {
|
|
1670
1670
|
t = O(Math.round(t), 1, 16);
|
|
1671
1671
|
const s = 176 + (t - 1);
|
|
1672
|
-
this.connection.send([s, 121, 0]), this.emit(
|
|
1672
|
+
this.connection.send([s, 121, 0]), this.emit(o.CH_RESET_CONTROLLERS_SEND, { channel: t });
|
|
1673
1673
|
} else {
|
|
1674
1674
|
for (let s = 1; s <= 16; s++) {
|
|
1675
|
-
const
|
|
1676
|
-
this.connection.send([
|
|
1675
|
+
const E = 176 + (s - 1);
|
|
1676
|
+
this.connection.send([E, 121, 0]);
|
|
1677
1677
|
}
|
|
1678
|
-
this.emit(
|
|
1678
|
+
this.emit(o.CH_RESET_CONTROLLERS_SEND, { channel: null });
|
|
1679
1679
|
}
|
|
1680
1680
|
}
|
|
1681
1681
|
/**
|
|
@@ -1686,17 +1686,17 @@ class z extends H {
|
|
|
1686
1686
|
console.warn("MIDI not initialized. Call init() first.");
|
|
1687
1687
|
return;
|
|
1688
1688
|
}
|
|
1689
|
-
const
|
|
1689
|
+
const E = t ? 127 : 0;
|
|
1690
1690
|
if (s !== void 0) {
|
|
1691
1691
|
s = O(Math.round(s), 1, 16);
|
|
1692
|
-
const
|
|
1693
|
-
this.connection.send([
|
|
1692
|
+
const e = 176 + (s - 1);
|
|
1693
|
+
this.connection.send([e, 122, E]), this.emit(o.CH_LOCAL_CONTROL_SEND, { enabled: t, channel: s });
|
|
1694
1694
|
} else {
|
|
1695
|
-
for (let
|
|
1696
|
-
const _ = 176 + (
|
|
1697
|
-
this.connection.send([_, 122,
|
|
1695
|
+
for (let e = 1; e <= 16; e++) {
|
|
1696
|
+
const _ = 176 + (e - 1);
|
|
1697
|
+
this.connection.send([_, 122, E]);
|
|
1698
1698
|
}
|
|
1699
|
-
this.emit(
|
|
1699
|
+
this.emit(o.CH_LOCAL_CONTROL_SEND, { enabled: t, channel: null });
|
|
1700
1700
|
}
|
|
1701
1701
|
}
|
|
1702
1702
|
/**
|
|
@@ -1710,13 +1710,13 @@ class z extends H {
|
|
|
1710
1710
|
if (t !== void 0) {
|
|
1711
1711
|
t = O(Math.round(t), 1, 16);
|
|
1712
1712
|
const s = 176 + (t - 1);
|
|
1713
|
-
this.connection.send([s, 123, 0]), this.emit(
|
|
1713
|
+
this.connection.send([s, 123, 0]), this.emit(o.CH_ALL_NOTES_OFF_SEND, { channel: t });
|
|
1714
1714
|
} else {
|
|
1715
1715
|
for (let s = 1; s <= 16; s++) {
|
|
1716
|
-
const
|
|
1717
|
-
this.connection.send([
|
|
1716
|
+
const E = 176 + (s - 1);
|
|
1717
|
+
this.connection.send([E, 123, 0]);
|
|
1718
1718
|
}
|
|
1719
|
-
this.emit(
|
|
1719
|
+
this.emit(o.CH_ALL_NOTES_OFF_SEND, { channel: null });
|
|
1720
1720
|
}
|
|
1721
1721
|
}
|
|
1722
1722
|
/**
|
|
@@ -1730,13 +1730,13 @@ class z extends H {
|
|
|
1730
1730
|
if (t !== void 0) {
|
|
1731
1731
|
t = O(Math.round(t), 1, 16);
|
|
1732
1732
|
const s = 176 + (t - 1);
|
|
1733
|
-
this.connection.send([s, 124, 0]), this.emit(
|
|
1733
|
+
this.connection.send([s, 124, 0]), this.emit(o.CH_OMNI_OFF_SEND, { channel: t });
|
|
1734
1734
|
} else {
|
|
1735
1735
|
for (let s = 1; s <= 16; s++) {
|
|
1736
|
-
const
|
|
1737
|
-
this.connection.send([
|
|
1736
|
+
const E = 176 + (s - 1);
|
|
1737
|
+
this.connection.send([E, 124, 0]);
|
|
1738
1738
|
}
|
|
1739
|
-
this.emit(
|
|
1739
|
+
this.emit(o.CH_OMNI_OFF_SEND, { channel: null });
|
|
1740
1740
|
}
|
|
1741
1741
|
}
|
|
1742
1742
|
/**
|
|
@@ -1750,13 +1750,13 @@ class z extends H {
|
|
|
1750
1750
|
if (t !== void 0) {
|
|
1751
1751
|
t = O(Math.round(t), 1, 16);
|
|
1752
1752
|
const s = 176 + (t - 1);
|
|
1753
|
-
this.connection.send([s, 125, 0]), this.emit(
|
|
1753
|
+
this.connection.send([s, 125, 0]), this.emit(o.CH_OMNI_ON_SEND, { channel: t });
|
|
1754
1754
|
} else {
|
|
1755
1755
|
for (let s = 1; s <= 16; s++) {
|
|
1756
|
-
const
|
|
1757
|
-
this.connection.send([
|
|
1756
|
+
const E = 176 + (s - 1);
|
|
1757
|
+
this.connection.send([E, 125, 0]);
|
|
1758
1758
|
}
|
|
1759
|
-
this.emit(
|
|
1759
|
+
this.emit(o.CH_OMNI_ON_SEND, { channel: null });
|
|
1760
1760
|
}
|
|
1761
1761
|
}
|
|
1762
1762
|
/**
|
|
@@ -1769,14 +1769,14 @@ class z extends H {
|
|
|
1769
1769
|
}
|
|
1770
1770
|
if (t = Math.max(0, Math.min(16, Math.round(t))), s !== void 0) {
|
|
1771
1771
|
s = O(Math.round(s), 1, 16);
|
|
1772
|
-
const
|
|
1773
|
-
this.connection.send([
|
|
1772
|
+
const E = 176 + (s - 1);
|
|
1773
|
+
this.connection.send([E, 126, t]), this.emit(o.CH_MONO_ON_SEND, { channels: t, channel: s });
|
|
1774
1774
|
} else {
|
|
1775
|
-
for (let
|
|
1776
|
-
const
|
|
1777
|
-
this.connection.send([
|
|
1775
|
+
for (let E = 1; E <= 16; E++) {
|
|
1776
|
+
const e = 176 + (E - 1);
|
|
1777
|
+
this.connection.send([e, 126, t]);
|
|
1778
1778
|
}
|
|
1779
|
-
this.emit(
|
|
1779
|
+
this.emit(o.CH_MONO_ON_SEND, { channels: t, channel: null });
|
|
1780
1780
|
}
|
|
1781
1781
|
}
|
|
1782
1782
|
/**
|
|
@@ -1790,13 +1790,13 @@ class z extends H {
|
|
|
1790
1790
|
if (t !== void 0) {
|
|
1791
1791
|
t = O(Math.round(t), 1, 16);
|
|
1792
1792
|
const s = 176 + (t - 1);
|
|
1793
|
-
this.connection.send([s, 127, 0]), this.emit(
|
|
1793
|
+
this.connection.send([s, 127, 0]), this.emit(o.CH_POLY_ON_SEND, { channel: t });
|
|
1794
1794
|
} else {
|
|
1795
1795
|
for (let s = 1; s <= 16; s++) {
|
|
1796
|
-
const
|
|
1797
|
-
this.connection.send([
|
|
1796
|
+
const E = 176 + (s - 1);
|
|
1797
|
+
this.connection.send([E, 127, 0]);
|
|
1798
1798
|
}
|
|
1799
|
-
this.emit(
|
|
1799
|
+
this.emit(o.CH_POLY_ON_SEND, { channel: null });
|
|
1800
1800
|
}
|
|
1801
1801
|
}
|
|
1802
1802
|
/**
|
|
@@ -1818,7 +1818,7 @@ class z extends H {
|
|
|
1818
1818
|
console.warn("SysEx not enabled. Initialize with sysex: true");
|
|
1819
1819
|
return;
|
|
1820
1820
|
}
|
|
1821
|
-
this.connection.sendSysEx(t, s), this.emit(
|
|
1821
|
+
this.connection.sendSysEx(t, s), this.emit(o.SYS_EX_SEND, { data: t, includeWrapper: s });
|
|
1822
1822
|
}
|
|
1823
1823
|
/**
|
|
1824
1824
|
* Send MIDI Timing Clock message (System Real-Time)
|
|
@@ -1893,8 +1893,8 @@ class z extends H {
|
|
|
1893
1893
|
return;
|
|
1894
1894
|
}
|
|
1895
1895
|
t = O(Math.round(t), 0, 16383);
|
|
1896
|
-
const s = t & 127,
|
|
1897
|
-
this.connection.send([242, s,
|
|
1896
|
+
const s = t & 127, E = t >> 7 & 127;
|
|
1897
|
+
this.connection.send([242, s, E]);
|
|
1898
1898
|
}
|
|
1899
1899
|
/**
|
|
1900
1900
|
* Send Song Select message (System Common)
|
|
@@ -1954,145 +1954,145 @@ class z extends H {
|
|
|
1954
1954
|
* @returns {void}
|
|
1955
1955
|
*/
|
|
1956
1956
|
_handleMIDIMessage(t) {
|
|
1957
|
-
const [s,
|
|
1957
|
+
const [s, E, e] = t.data, _ = s & 240, i = (s & 15) + 1;
|
|
1958
1958
|
if (s === 248) {
|
|
1959
|
-
this.emit(
|
|
1959
|
+
this.emit(o.SYS_CLOCK_RECV, {
|
|
1960
1960
|
timestamp: t.midiwire
|
|
1961
1961
|
});
|
|
1962
1962
|
return;
|
|
1963
1963
|
}
|
|
1964
1964
|
if (s === 250) {
|
|
1965
|
-
this.emit(
|
|
1965
|
+
this.emit(o.SYS_START_RECV, {
|
|
1966
1966
|
timestamp: t.midiwire
|
|
1967
1967
|
});
|
|
1968
1968
|
return;
|
|
1969
1969
|
}
|
|
1970
1970
|
if (s === 251) {
|
|
1971
|
-
this.emit(
|
|
1971
|
+
this.emit(o.SYS_CONTINUE_RECV, {
|
|
1972
1972
|
timestamp: t.midiwire
|
|
1973
1973
|
});
|
|
1974
1974
|
return;
|
|
1975
1975
|
}
|
|
1976
1976
|
if (s === 252) {
|
|
1977
|
-
this.emit(
|
|
1977
|
+
this.emit(o.SYS_STOP_RECV, {
|
|
1978
1978
|
timestamp: t.midiwire
|
|
1979
1979
|
});
|
|
1980
1980
|
return;
|
|
1981
1981
|
}
|
|
1982
1982
|
if (s === 254) {
|
|
1983
|
-
this.emit(
|
|
1983
|
+
this.emit(o.SYS_ACT_SENSE_RECV, {
|
|
1984
1984
|
timestamp: t.midiwire
|
|
1985
1985
|
});
|
|
1986
1986
|
return;
|
|
1987
1987
|
}
|
|
1988
1988
|
if (s === 255) {
|
|
1989
|
-
this.emit(
|
|
1989
|
+
this.emit(o.SYS_RESET_RECV, {
|
|
1990
1990
|
timestamp: t.midiwire
|
|
1991
1991
|
});
|
|
1992
1992
|
return;
|
|
1993
1993
|
}
|
|
1994
1994
|
if (s === 240) {
|
|
1995
|
-
this.emit(
|
|
1995
|
+
this.emit(o.SYS_EX_RECV, {
|
|
1996
1996
|
data: Array.from(t.data),
|
|
1997
1997
|
timestamp: t.midiwire
|
|
1998
1998
|
});
|
|
1999
1999
|
return;
|
|
2000
2000
|
}
|
|
2001
2001
|
if (s === 241) {
|
|
2002
|
-
this.emit(
|
|
2003
|
-
data:
|
|
2002
|
+
this.emit(o.SYS_MTC_RECV, {
|
|
2003
|
+
data: E,
|
|
2004
2004
|
timestamp: t.midiwire
|
|
2005
2005
|
});
|
|
2006
2006
|
return;
|
|
2007
2007
|
}
|
|
2008
2008
|
if (s === 242) {
|
|
2009
|
-
const r =
|
|
2010
|
-
this.emit(
|
|
2009
|
+
const r = E + (e << 7);
|
|
2010
|
+
this.emit(o.SYS_SONG_POS_RECV, {
|
|
2011
2011
|
position: r,
|
|
2012
2012
|
timestamp: t.midiwire
|
|
2013
2013
|
});
|
|
2014
2014
|
return;
|
|
2015
2015
|
}
|
|
2016
2016
|
if (s === 243) {
|
|
2017
|
-
this.emit(
|
|
2018
|
-
song:
|
|
2017
|
+
this.emit(o.SYS_SONG_SEL_RECV, {
|
|
2018
|
+
song: E,
|
|
2019
2019
|
timestamp: t.midiwire
|
|
2020
2020
|
});
|
|
2021
2021
|
return;
|
|
2022
2022
|
}
|
|
2023
2023
|
if (s === 246) {
|
|
2024
|
-
this.emit(
|
|
2024
|
+
this.emit(o.SYS_TUNE_REQ_RECV, {
|
|
2025
2025
|
timestamp: t.midiwire
|
|
2026
2026
|
});
|
|
2027
2027
|
return;
|
|
2028
2028
|
}
|
|
2029
2029
|
if (s === 247) {
|
|
2030
|
-
this.emit(
|
|
2030
|
+
this.emit(o.MIDI_RAW, {
|
|
2031
2031
|
status: s,
|
|
2032
|
-
data: [
|
|
2032
|
+
data: [E, e],
|
|
2033
2033
|
channel: i,
|
|
2034
2034
|
timestamp: t.midiwire
|
|
2035
2035
|
});
|
|
2036
2036
|
return;
|
|
2037
2037
|
}
|
|
2038
2038
|
if (_ === 176) {
|
|
2039
|
-
const r = `${i}:${
|
|
2040
|
-
this.state.controlChange.set(r,
|
|
2041
|
-
cc:
|
|
2042
|
-
value:
|
|
2039
|
+
const r = `${i}:${E}`;
|
|
2040
|
+
this.state.controlChange.set(r, e), this.emit(o.CH_CC_RECV, {
|
|
2041
|
+
cc: E,
|
|
2042
|
+
value: e,
|
|
2043
2043
|
channel: i
|
|
2044
2044
|
});
|
|
2045
2045
|
return;
|
|
2046
2046
|
}
|
|
2047
2047
|
if (_ === 192) {
|
|
2048
|
-
this.state.programChange.set(i.toString(),
|
|
2049
|
-
program:
|
|
2048
|
+
this.state.programChange.set(i.toString(), E), this.emit(o.CH_PC_RECV, {
|
|
2049
|
+
program: E,
|
|
2050
2050
|
channel: i
|
|
2051
2051
|
});
|
|
2052
2052
|
return;
|
|
2053
2053
|
}
|
|
2054
2054
|
if (_ === 224) {
|
|
2055
|
-
const r =
|
|
2056
|
-
this.state.pitchBend.set(i.toString(), r), this.emit(
|
|
2055
|
+
const r = E + (e << 7);
|
|
2056
|
+
this.state.pitchBend.set(i.toString(), r), this.emit(o.CH_PITCH_BEND_RECV, {
|
|
2057
2057
|
value: r,
|
|
2058
2058
|
channel: i
|
|
2059
2059
|
});
|
|
2060
2060
|
return;
|
|
2061
2061
|
}
|
|
2062
2062
|
if (_ === 208) {
|
|
2063
|
-
this.state.monoPressure.set(i.toString(),
|
|
2064
|
-
pressure:
|
|
2063
|
+
this.state.monoPressure.set(i.toString(), E), this.emit(o.CH_MONO_PRESS_RECV, {
|
|
2064
|
+
pressure: E,
|
|
2065
2065
|
channel: i
|
|
2066
2066
|
});
|
|
2067
2067
|
return;
|
|
2068
2068
|
}
|
|
2069
2069
|
if (_ === 160) {
|
|
2070
|
-
const r = `${i}:${
|
|
2071
|
-
this.state.polyPressure.set(r,
|
|
2072
|
-
note:
|
|
2073
|
-
pressure:
|
|
2070
|
+
const r = `${i}:${E}`;
|
|
2071
|
+
this.state.polyPressure.set(r, e), this.emit(o.CH_POLY_PRESS_RECV, {
|
|
2072
|
+
note: E,
|
|
2073
|
+
pressure: e,
|
|
2074
2074
|
channel: i
|
|
2075
2075
|
});
|
|
2076
2076
|
return;
|
|
2077
2077
|
}
|
|
2078
|
-
if (_ === 144 &&
|
|
2079
|
-
this.emit(
|
|
2080
|
-
note:
|
|
2081
|
-
velocity:
|
|
2078
|
+
if (_ === 144 && e > 0) {
|
|
2079
|
+
this.emit(o.CH_NOTE_ON_RECV, {
|
|
2080
|
+
note: E,
|
|
2081
|
+
velocity: e,
|
|
2082
2082
|
channel: i
|
|
2083
2083
|
});
|
|
2084
2084
|
return;
|
|
2085
2085
|
}
|
|
2086
|
-
if (_ === 128 || _ === 144 &&
|
|
2087
|
-
this.emit(
|
|
2088
|
-
note:
|
|
2086
|
+
if (_ === 128 || _ === 144 && e === 0) {
|
|
2087
|
+
this.emit(o.CH_NOTE_OFF_RECV, {
|
|
2088
|
+
note: E,
|
|
2089
2089
|
channel: i
|
|
2090
2090
|
});
|
|
2091
2091
|
return;
|
|
2092
2092
|
}
|
|
2093
|
-
this.emit(
|
|
2093
|
+
this.emit(o.MIDI_RAW, {
|
|
2094
2094
|
status: s,
|
|
2095
|
-
data: [
|
|
2095
|
+
data: [E, e],
|
|
2096
2096
|
channel: i,
|
|
2097
2097
|
timestamp: t.midiwire
|
|
2098
2098
|
});
|
|
@@ -2112,28 +2112,28 @@ class z extends H {
|
|
|
2112
2112
|
channels: {},
|
|
2113
2113
|
settings: {}
|
|
2114
2114
|
};
|
|
2115
|
-
for (const [
|
|
2116
|
-
const [_, i] =
|
|
2117
|
-
s.channels[_] || (s.channels[_] = { ccs: {}, notes: {} }), s.channels[_].ccs[i] =
|
|
2115
|
+
for (const [E, e] of this.state.controlChange.entries()) {
|
|
2116
|
+
const [_, i] = E.split(":").map(Number);
|
|
2117
|
+
s.channels[_] || (s.channels[_] = { ccs: {}, notes: {} }), s.channels[_].ccs[i] = e;
|
|
2118
2118
|
}
|
|
2119
|
-
for (const [
|
|
2120
|
-
const _ = parseInt(
|
|
2121
|
-
s.channels[_] || (s.channels[_] = { ccs: {}, notes: {} }), s.channels[_].program =
|
|
2119
|
+
for (const [E, e] of this.state.programChange.entries()) {
|
|
2120
|
+
const _ = parseInt(E, 10);
|
|
2121
|
+
s.channels[_] || (s.channels[_] = { ccs: {}, notes: {} }), s.channels[_].program = e;
|
|
2122
2122
|
}
|
|
2123
|
-
for (const [
|
|
2124
|
-
const _ = parseInt(
|
|
2125
|
-
s.channels[_] || (s.channels[_] = { ccs: {}, notes: {} }), s.channels[_].pitchBend =
|
|
2123
|
+
for (const [E, e] of this.state.pitchBend.entries()) {
|
|
2124
|
+
const _ = parseInt(E, 10);
|
|
2125
|
+
s.channels[_] || (s.channels[_] = { ccs: {}, notes: {} }), s.channels[_].pitchBend = e;
|
|
2126
2126
|
}
|
|
2127
|
-
for (const [
|
|
2128
|
-
const _ = parseInt(
|
|
2129
|
-
s.channels[_] || (s.channels[_] = { ccs: {}, notes: {} }), s.channels[_].monoPressure =
|
|
2127
|
+
for (const [E, e] of this.state.monoPressure.entries()) {
|
|
2128
|
+
const _ = parseInt(E, 10);
|
|
2129
|
+
s.channels[_] || (s.channels[_] = { ccs: {}, notes: {} }), s.channels[_].monoPressure = e;
|
|
2130
2130
|
}
|
|
2131
|
-
for (const [
|
|
2132
|
-
const [_, i] =
|
|
2133
|
-
s.channels[r] || (s.channels[r] = { ccs: {}, notes: {} }), s.channels[r].polyPressure || (s.channels[r].polyPressure = {}), s.channels[r].polyPressure[i] =
|
|
2131
|
+
for (const [E, e] of this.state.polyPressure.entries()) {
|
|
2132
|
+
const [_, i] = E.split(":").map(Number), r = parseInt(_, 10);
|
|
2133
|
+
s.channels[r] || (s.channels[r] = { ccs: {}, notes: {} }), s.channels[r].polyPressure || (s.channels[r].polyPressure = {}), s.channels[r].polyPressure[i] = e;
|
|
2134
2134
|
}
|
|
2135
|
-
for (const [
|
|
2136
|
-
const { config: _ } =
|
|
2135
|
+
for (const [E, e] of this.bindings.entries()) {
|
|
2136
|
+
const { config: _ } = e;
|
|
2137
2137
|
if (_.cc) {
|
|
2138
2138
|
const i = `cc${_.cc}`;
|
|
2139
2139
|
s.settings[i] = {
|
|
@@ -2141,8 +2141,8 @@ class z extends H {
|
|
|
2141
2141
|
max: _.max,
|
|
2142
2142
|
invert: _.invert || !1,
|
|
2143
2143
|
is14Bit: _.is14Bit || !1,
|
|
2144
|
-
label:
|
|
2145
|
-
elementId:
|
|
2144
|
+
label: E.getAttribute?.("data-midi-label") || null,
|
|
2145
|
+
elementId: E.id || null
|
|
2146
2146
|
};
|
|
2147
2147
|
}
|
|
2148
2148
|
}
|
|
@@ -2159,7 +2159,7 @@ class z extends H {
|
|
|
2159
2159
|
if (!t || !t.channels)
|
|
2160
2160
|
throw new L("Invalid patch format", "patch");
|
|
2161
2161
|
const s = t.version || "1.0";
|
|
2162
|
-
s === "1.0" ? await this._applyPatchV1(t) : (console.warn(`Unknown patch version: ${s}. Attempting to apply as v1.0`), await this._applyPatchV1(t)), this.emit(
|
|
2162
|
+
s === "1.0" ? await this._applyPatchV1(t) : (console.warn(`Unknown patch version: ${s}. Attempting to apply as v1.0`), await this._applyPatchV1(t)), this.emit(o.PATCH_LOADED, { patch: t });
|
|
2163
2163
|
}
|
|
2164
2164
|
/**
|
|
2165
2165
|
* Apply patch data for version 1.0 format
|
|
@@ -2168,38 +2168,38 @@ class z extends H {
|
|
|
2168
2168
|
* @returns {Promise<void>}
|
|
2169
2169
|
*/
|
|
2170
2170
|
async _applyPatchV1(t) {
|
|
2171
|
-
for (const [s,
|
|
2172
|
-
const
|
|
2173
|
-
if (
|
|
2174
|
-
for (const [_, i] of Object.entries(
|
|
2171
|
+
for (const [s, E] of Object.entries(t.channels)) {
|
|
2172
|
+
const e = parseInt(s, 10);
|
|
2173
|
+
if (E.ccs)
|
|
2174
|
+
for (const [_, i] of Object.entries(E.ccs)) {
|
|
2175
2175
|
const r = parseInt(_, 10);
|
|
2176
|
-
this._sendCC(r, i,
|
|
2176
|
+
this._sendCC(r, i, e);
|
|
2177
2177
|
}
|
|
2178
|
-
if (
|
|
2179
|
-
for (const [_, i] of Object.entries(
|
|
2178
|
+
if (E.program !== void 0 && this._sendPC(E.program, e), E.pitchBend !== void 0 && this._sendPitchBend(E.pitchBend, e), E.monoPressure !== void 0 && this._sendMonoPressure(E.monoPressure, e), E.polyPressure)
|
|
2179
|
+
for (const [_, i] of Object.entries(E.polyPressure)) {
|
|
2180
2180
|
const r = parseInt(_, 10);
|
|
2181
|
-
this._sendPolyPressure(r, i,
|
|
2181
|
+
this._sendPolyPressure(r, i, e);
|
|
2182
2182
|
}
|
|
2183
|
-
if (
|
|
2184
|
-
for (const [_, i] of Object.entries(
|
|
2183
|
+
if (E.notes)
|
|
2184
|
+
for (const [_, i] of Object.entries(E.notes)) {
|
|
2185
2185
|
const r = parseInt(_, 10);
|
|
2186
|
-
i > 0 ? this._sendNoteOn(r, i,
|
|
2186
|
+
i > 0 ? this._sendNoteOn(r, i, e) : this._sendNoteOff(r, e);
|
|
2187
2187
|
}
|
|
2188
2188
|
}
|
|
2189
2189
|
if (t.settings)
|
|
2190
|
-
for (const [s,
|
|
2191
|
-
for (const [
|
|
2192
|
-
_.config.cc?.toString() === s.replace("cc", "") && (
|
|
2193
|
-
for (const [s,
|
|
2194
|
-
const { config:
|
|
2195
|
-
if (
|
|
2196
|
-
const _ =
|
|
2190
|
+
for (const [s, E] of Object.entries(t.settings))
|
|
2191
|
+
for (const [e, _] of this.bindings.entries())
|
|
2192
|
+
_.config.cc?.toString() === s.replace("cc", "") && (e.min !== void 0 && E.min !== void 0 && (e.min = String(E.min)), e.max !== void 0 && E.max !== void 0 && (e.max = String(E.max)));
|
|
2193
|
+
for (const [s, E] of this.bindings.entries()) {
|
|
2194
|
+
const { config: e } = E;
|
|
2195
|
+
if (e.cc !== void 0) {
|
|
2196
|
+
const _ = e.channel || this.options.inputChannel, i = t.channels[_];
|
|
2197
2197
|
if (i?.ccs) {
|
|
2198
|
-
const r = i.ccs[
|
|
2198
|
+
const r = i.ccs[e.cc];
|
|
2199
2199
|
if (r !== void 0) {
|
|
2200
|
-
const u =
|
|
2200
|
+
const u = e.min !== void 0 ? e.min : parseFloat(s.getAttribute?.("min")) || 0, S = e.max !== void 0 ? e.max : parseFloat(s.getAttribute?.("max")) || 127, P = e.invert || !1;
|
|
2201
2201
|
let a;
|
|
2202
|
-
P ? a = S - r / 127 * (S - u) : a = u + r / 127 * (S - u),
|
|
2202
|
+
P ? a = S - r / 127 * (S - u) : a = u + r / 127 * (S - u), e.onInput && typeof e.onInput == "function" ? e.onInput(a) : (s.value = a, s.dispatchEvent(new Event("input", { bubbles: !0 })));
|
|
2203
2203
|
}
|
|
2204
2204
|
}
|
|
2205
2205
|
}
|
|
@@ -2213,9 +2213,9 @@ class z extends H {
|
|
|
2213
2213
|
* @returns {string} Storage key used
|
|
2214
2214
|
*/
|
|
2215
2215
|
_savePatch(t, s = null) {
|
|
2216
|
-
const
|
|
2216
|
+
const E = s || this._getPatch(t), e = `midiwire_patch_${t}`;
|
|
2217
2217
|
try {
|
|
2218
|
-
return localStorage.setItem(
|
|
2218
|
+
return localStorage.setItem(e, JSON.stringify(E)), this.emit(o.PATCH_SAVED, { name: t, patch: E }), e;
|
|
2219
2219
|
} catch (_) {
|
|
2220
2220
|
throw console.error("Failed to save patch:", _), _;
|
|
2221
2221
|
}
|
|
@@ -2229,13 +2229,13 @@ class z extends H {
|
|
|
2229
2229
|
_loadPatch(t) {
|
|
2230
2230
|
const s = `midiwire_patch_${t}`;
|
|
2231
2231
|
try {
|
|
2232
|
-
const
|
|
2233
|
-
if (!
|
|
2232
|
+
const E = localStorage.getItem(s);
|
|
2233
|
+
if (!E)
|
|
2234
2234
|
return null;
|
|
2235
|
-
const
|
|
2236
|
-
return this.emit(
|
|
2237
|
-
} catch (
|
|
2238
|
-
return console.error("Failed to load patch:",
|
|
2235
|
+
const e = JSON.parse(E);
|
|
2236
|
+
return this.emit(o.PATCH_LOADED, { name: t, patch: e }), e;
|
|
2237
|
+
} catch (E) {
|
|
2238
|
+
return console.error("Failed to load patch:", E), null;
|
|
2239
2239
|
}
|
|
2240
2240
|
}
|
|
2241
2241
|
/**
|
|
@@ -2247,9 +2247,9 @@ class z extends H {
|
|
|
2247
2247
|
_deletePatch(t) {
|
|
2248
2248
|
const s = `midiwire_patch_${t}`;
|
|
2249
2249
|
try {
|
|
2250
|
-
return localStorage.removeItem(s), this.emit(
|
|
2251
|
-
} catch (
|
|
2252
|
-
return console.error("Failed to delete patch:",
|
|
2250
|
+
return localStorage.removeItem(s), this.emit(o.PATCH_DELETED, { name: t }), !0;
|
|
2251
|
+
} catch (E) {
|
|
2252
|
+
return console.error("Failed to delete patch:", E), !1;
|
|
2253
2253
|
}
|
|
2254
2254
|
}
|
|
2255
2255
|
/**
|
|
@@ -2261,16 +2261,16 @@ class z extends H {
|
|
|
2261
2261
|
const t = [];
|
|
2262
2262
|
try {
|
|
2263
2263
|
for (let s = 0; s < localStorage.length; s++) {
|
|
2264
|
-
const
|
|
2265
|
-
if (
|
|
2266
|
-
const
|
|
2267
|
-
_ && t.push({ name:
|
|
2264
|
+
const E = localStorage.key(s);
|
|
2265
|
+
if (E?.startsWith("midiwire_patch_")) {
|
|
2266
|
+
const e = E.replace("midiwire_patch_", ""), _ = this._loadPatch(e);
|
|
2267
|
+
_ && t.push({ name: e, patch: _ });
|
|
2268
2268
|
}
|
|
2269
2269
|
}
|
|
2270
2270
|
} catch (s) {
|
|
2271
2271
|
console.error("Failed to list patches:", s);
|
|
2272
2272
|
}
|
|
2273
|
-
return t.sort((s,
|
|
2273
|
+
return t.sort((s, E) => s.name.localeCompare(E.name));
|
|
2274
2274
|
}
|
|
2275
2275
|
}
|
|
2276
2276
|
class q {
|
|
@@ -2304,15 +2304,15 @@ class q {
|
|
|
2304
2304
|
async setupSelectors(t = {}, s = {}) {
|
|
2305
2305
|
if (!this.midi)
|
|
2306
2306
|
throw new Error("MIDI controller not initialized. Pass midiController in constructor options.");
|
|
2307
|
-
const { output:
|
|
2307
|
+
const { output: E, input: e, channel: _ } = t, i = this._resolveSelector(E), r = this._resolveSelector(e), u = this._resolveSelector(_);
|
|
2308
2308
|
if (this._setupDeviceChangeListeners({ output: i, input: r }, s.onDeviceListChange), i) {
|
|
2309
2309
|
await this._populateOutputDeviceList(i);
|
|
2310
|
-
const S = s.onConnect ? async (a,
|
|
2310
|
+
const S = s.onConnect ? async (a, C) => s.onConnect({ midi: a, device: C, type: "output" }) : void 0, P = s.onDisconnect ? async (a) => s.onDisconnect({ midi: a, type: "output" }) : void 0;
|
|
2311
2311
|
this._connectOutputDeviceSelection(i, S, P);
|
|
2312
2312
|
}
|
|
2313
2313
|
if (r) {
|
|
2314
2314
|
await this._populateInputDeviceList(r);
|
|
2315
|
-
const S = s.onConnect ? async (a,
|
|
2315
|
+
const S = s.onConnect ? async (a, C) => s.onConnect({ midi: a, device: C, type: "input" }) : void 0, P = s.onDisconnect ? async (a) => s.onDisconnect({ midi: a, type: "input" }) : void 0;
|
|
2316
2316
|
this._connectInputDeviceSelection(r, S, P);
|
|
2317
2317
|
}
|
|
2318
2318
|
return u && this._connectChannelSelection(u, "output"), this.midi;
|
|
@@ -2349,14 +2349,14 @@ class q {
|
|
|
2349
2349
|
* @param {Function} [onDeviceListChange] - Callback when device list changes
|
|
2350
2350
|
*/
|
|
2351
2351
|
_setupDeviceChangeListeners(t = {}, s) {
|
|
2352
|
-
!this.midi || this._listenersInitialized || (this._listenersInitialized = !0, this.midi.on(
|
|
2353
|
-
this.updateStatus(`Output device connected: ${
|
|
2354
|
-
}), this.midi.on(
|
|
2355
|
-
this.updateStatus(`Output device disconnected: ${
|
|
2356
|
-
}), this.midi.on(
|
|
2357
|
-
this.updateStatus(`Input device connected: ${
|
|
2358
|
-
}), this.midi.on(
|
|
2359
|
-
this.updateStatus(`Input device disconnected: ${
|
|
2352
|
+
!this.midi || this._listenersInitialized || (this._listenersInitialized = !0, this.midi.on(o.DEV_OUT_CONNECTED, async (E) => {
|
|
2353
|
+
this.updateStatus(`Output device connected: ${E?.name || "Unknown"}`, "connected"), t.output && await this._populateOutputDeviceList(t.output), s && s();
|
|
2354
|
+
}), this.midi.on(o.DEV_OUT_DISCONNECTED, async (E) => {
|
|
2355
|
+
this.updateStatus(`Output device disconnected: ${E?.name || "Unknown"}`, "error"), this.currentOutput && E?.name === this.currentOutput.name && (this.currentOutput = null, this.updateConnectionStatus(), t.output && (t.output.value = "")), t.output && await this._populateOutputDeviceList(t.output), s && s();
|
|
2356
|
+
}), this.midi.on(o.DEV_IN_CONNECTED, async (E) => {
|
|
2357
|
+
this.updateStatus(`Input device connected: ${E?.name || "Unknown"}`, "connected"), t.input && await this._populateInputDeviceList(t.input), s && s();
|
|
2358
|
+
}), this.midi.on(o.DEV_IN_DISCONNECTED, async (E) => {
|
|
2359
|
+
this.updateStatus(`Input device disconnected: ${E?.name || "Unknown"}`, "error"), t.input && (t.input.value = "", await this._populateInputDeviceList(t.input)), s && s();
|
|
2360
2360
|
}));
|
|
2361
2361
|
}
|
|
2362
2362
|
/**
|
|
@@ -2397,13 +2397,13 @@ class q {
|
|
|
2397
2397
|
* @param {Function} [onDisconnect] - Callback when device is disconnected (midi: MIDIController)
|
|
2398
2398
|
* @returns {void}
|
|
2399
2399
|
*/
|
|
2400
|
-
_connectOutputDeviceSelection(t, s,
|
|
2401
|
-
!t || !this.midi || t.addEventListener("change", async (
|
|
2400
|
+
_connectOutputDeviceSelection(t, s, E) {
|
|
2401
|
+
!t || !this.midi || t.addEventListener("change", async (e) => {
|
|
2402
2402
|
if (this.isConnecting) return;
|
|
2403
2403
|
this.isConnecting = !0;
|
|
2404
|
-
const _ =
|
|
2404
|
+
const _ = e.target.value;
|
|
2405
2405
|
if (!_) {
|
|
2406
|
-
this.currentOutput && this.midi && (await this.midi.device.disconnectOutput(), this.currentOutput = null, this.updateStatus("Output device disconnected", ""), this.updateConnectionStatus()), this.isConnecting = !1,
|
|
2406
|
+
this.currentOutput && this.midi && (await this.midi.device.disconnectOutput(), this.currentOutput = null, this.updateStatus("Output device disconnected", ""), this.updateConnectionStatus()), this.isConnecting = !1, E && await E(this.midi);
|
|
2407
2407
|
return;
|
|
2408
2408
|
}
|
|
2409
2409
|
try {
|
|
@@ -2428,11 +2428,11 @@ class q {
|
|
|
2428
2428
|
* @param {Function} [onDisconnect] - Callback when device is disconnected (midi: MIDIController)
|
|
2429
2429
|
* @returns {void}
|
|
2430
2430
|
*/
|
|
2431
|
-
_connectInputDeviceSelection(t, s,
|
|
2432
|
-
!t || !this.midi || t.addEventListener("change", async (
|
|
2433
|
-
const _ =
|
|
2431
|
+
_connectInputDeviceSelection(t, s, E) {
|
|
2432
|
+
!t || !this.midi || t.addEventListener("change", async (e) => {
|
|
2433
|
+
const _ = e.target.value;
|
|
2434
2434
|
if (!_) {
|
|
2435
|
-
this.midi && (await this.midi.device.disconnectInput(), this.updateStatus("Input device disconnected", ""), this.updateConnectionStatus()),
|
|
2435
|
+
this.midi && (await this.midi.device.disconnectInput(), this.updateStatus("Input device disconnected", ""), this.updateConnectionStatus()), E && await E(this.midi);
|
|
2436
2436
|
return;
|
|
2437
2437
|
}
|
|
2438
2438
|
if (!this.isConnecting) {
|
|
@@ -2459,17 +2459,17 @@ class q {
|
|
|
2459
2459
|
* @param {boolean} isOutput - Whether these are output devices
|
|
2460
2460
|
* @returns {void}
|
|
2461
2461
|
*/
|
|
2462
|
-
_populateDeviceList(t, s,
|
|
2462
|
+
_populateDeviceList(t, s, E, e, _) {
|
|
2463
2463
|
if (s.length > 0) {
|
|
2464
|
-
if (t.innerHTML = '<option value="">Select a device</option>' + s.map((i, r) => `<option value="${r}">${i.name}</option>`).join(""),
|
|
2465
|
-
const i = s.findIndex((r) => r.name ===
|
|
2464
|
+
if (t.innerHTML = '<option value="">Select a device</option>' + s.map((i, r) => `<option value="${r}">${i.name}</option>`).join(""), E) {
|
|
2465
|
+
const i = s.findIndex((r) => r.name === E.name);
|
|
2466
2466
|
i !== -1 ? t.value = i.toString() : (t.value = "", _ && (this.currentOutput = null, this.updateConnectionStatus()));
|
|
2467
2467
|
} else
|
|
2468
2468
|
t.value = "";
|
|
2469
2469
|
t.disabled = !1, _ && !this.currentOutput && this.updateStatus("Select a device");
|
|
2470
2470
|
} else
|
|
2471
2471
|
t.innerHTML = '<option value="">No devices connected</option>', t.disabled = !0, _ && this.updateStatus("No devices connected", "error");
|
|
2472
|
-
|
|
2472
|
+
e && e();
|
|
2473
2473
|
}
|
|
2474
2474
|
/**
|
|
2475
2475
|
* Populate a select element with available MIDI output devices. Automatically
|
|
@@ -2482,8 +2482,8 @@ class q {
|
|
|
2482
2482
|
*/
|
|
2483
2483
|
async _populateOutputDeviceList(t, s) {
|
|
2484
2484
|
if (!t || !this.midi) return;
|
|
2485
|
-
const
|
|
2486
|
-
this._populateDeviceList(t,
|
|
2485
|
+
const E = this._getOutputDevices();
|
|
2486
|
+
this._populateDeviceList(t, E, this.currentOutput, s, !0);
|
|
2487
2487
|
}
|
|
2488
2488
|
/**
|
|
2489
2489
|
* Populate a select element with available MIDI input devices. Automatically
|
|
@@ -2496,8 +2496,8 @@ class q {
|
|
|
2496
2496
|
*/
|
|
2497
2497
|
async _populateInputDeviceList(t, s) {
|
|
2498
2498
|
if (!t || !this.midi) return;
|
|
2499
|
-
const
|
|
2500
|
-
this._populateDeviceList(t,
|
|
2499
|
+
const E = this._getInputDevices(), e = this.midi.device.getCurrentInput();
|
|
2500
|
+
this._populateDeviceList(t, E, e, s, !1);
|
|
2501
2501
|
}
|
|
2502
2502
|
/**
|
|
2503
2503
|
* Connect channel selection events to automatically update the MIDI channel when
|
|
@@ -2521,9 +2521,9 @@ class q {
|
|
|
2521
2521
|
*/
|
|
2522
2522
|
_connectChannelSelection(t, s) {
|
|
2523
2523
|
if (!t || !this.midi) return;
|
|
2524
|
-
const
|
|
2525
|
-
t.addEventListener("change", (
|
|
2526
|
-
this.midi && (this.midi.options[
|
|
2524
|
+
const E = s === "input" ? "inputChannel" : "outputChannel";
|
|
2525
|
+
t.addEventListener("change", (e) => {
|
|
2526
|
+
this.midi && (this.midi.options[E] = parseInt(e.target.value, 10), this.updateConnectionStatus());
|
|
2527
2527
|
});
|
|
2528
2528
|
}
|
|
2529
2529
|
}
|
|
@@ -2703,8 +2703,13 @@ class n {
|
|
|
2703
2703
|
static DEFAULT_PITCH_EG_LEVEL = 50;
|
|
2704
2704
|
static DEFAULT_LFO_SPEED = 35;
|
|
2705
2705
|
static DEFAULT_LFO_PM_SENS = 3;
|
|
2706
|
+
static DEFAULT_DETUNE = 7;
|
|
2707
|
+
// Detune center (actual detune = value - 7)
|
|
2708
|
+
static DEFAULT_FREQ_COARSE = 1;
|
|
2706
2709
|
static DEFAULT_ALGORITHM = 0;
|
|
2707
2710
|
static DEFAULT_FEEDBACK = 0;
|
|
2711
|
+
static DEFAULT_OSC_SYNC = 1;
|
|
2712
|
+
static DEFAULT_LFO_KEY_SYNC = 1;
|
|
2708
2713
|
// MIDI notes
|
|
2709
2714
|
static MIDI_OCTAVE_OFFSET = -2;
|
|
2710
2715
|
// For displaying MIDI notes (MIDI 0 = C-2)
|
|
@@ -2731,9 +2736,9 @@ class n {
|
|
|
2731
2736
|
*/
|
|
2732
2737
|
_extractName() {
|
|
2733
2738
|
const t = this.data.subarray(n.PACKED_NAME_START, n.PACKED_NAME_START + n.NAME_LENGTH);
|
|
2734
|
-
return Array.from(t).map((
|
|
2735
|
-
let
|
|
2736
|
-
return
|
|
2739
|
+
return Array.from(t).map((E) => {
|
|
2740
|
+
let e = E & n.MASK_7BIT;
|
|
2741
|
+
return e === n.CHAR_YEN && (e = n.CHAR_REPLACEMENT_Y), e === n.CHAR_ARROW_RIGHT && (e = n.CHAR_REPLACEMENT_GT), e === n.CHAR_ARROW_LEFT && (e = n.CHAR_REPLACEMENT_LT), (e < n.CHAR_MIN_PRINTABLE || e > n.CHAR_MAX_PRINTABLE) && (e = n.CHAR_SPACE), String.fromCharCode(e);
|
|
2737
2742
|
}).join("").trim();
|
|
2738
2743
|
}
|
|
2739
2744
|
/**
|
|
@@ -2794,53 +2799,53 @@ class n {
|
|
|
2794
2799
|
* @private
|
|
2795
2800
|
*/
|
|
2796
2801
|
_unpackOperators(t, s) {
|
|
2797
|
-
for (let
|
|
2798
|
-
const
|
|
2799
|
-
this._unpackOperator(t, s,
|
|
2802
|
+
for (let E = 0; E < n.NUM_OPERATORS; E++) {
|
|
2803
|
+
const e = (n.NUM_OPERATORS - 1 - E) * n.PACKED_OP_SIZE, _ = E * n.UNPACKED_OP_SIZE;
|
|
2804
|
+
this._unpackOperator(t, s, e, _);
|
|
2800
2805
|
}
|
|
2801
2806
|
}
|
|
2802
2807
|
/**
|
|
2803
2808
|
* Unpack a single operator's parameters
|
|
2804
2809
|
* @private
|
|
2805
2810
|
*/
|
|
2806
|
-
_unpackOperator(t, s,
|
|
2807
|
-
this._unpackOperatorEG(t, s,
|
|
2811
|
+
_unpackOperator(t, s, E, e) {
|
|
2812
|
+
this._unpackOperatorEG(t, s, E, e), this._unpackOperatorScaling(t, s, E, e), this._unpackOperatorPackedParams(t, s, E, e), this._unpackOperatorFrequency(t, s, E, e);
|
|
2808
2813
|
}
|
|
2809
2814
|
/**
|
|
2810
2815
|
* Unpack operator EG rates and levels
|
|
2811
2816
|
* @private
|
|
2812
2817
|
*/
|
|
2813
|
-
_unpackOperatorEG(t, s,
|
|
2814
|
-
s[
|
|
2818
|
+
_unpackOperatorEG(t, s, E, e) {
|
|
2819
|
+
s[e + n.UNPACKED_OP_EG_RATE_1] = t[E + n.PACKED_OP_EG_RATE_1] & n.MASK_7BIT, s[e + n.UNPACKED_OP_EG_RATE_2] = t[E + n.PACKED_OP_EG_RATE_2] & n.MASK_7BIT, s[e + n.UNPACKED_OP_EG_RATE_3] = t[E + n.PACKED_OP_EG_RATE_3] & n.MASK_7BIT, s[e + n.UNPACKED_OP_EG_RATE_4] = t[E + n.PACKED_OP_EG_RATE_4] & n.MASK_7BIT, s[e + n.UNPACKED_OP_EG_LEVEL_1] = t[E + n.PACKED_OP_EG_LEVEL_1] & n.MASK_7BIT, s[e + n.UNPACKED_OP_EG_LEVEL_2] = t[E + n.PACKED_OP_EG_LEVEL_2] & n.MASK_7BIT, s[e + n.UNPACKED_OP_EG_LEVEL_3] = t[E + n.PACKED_OP_EG_LEVEL_3] & n.MASK_7BIT, s[e + n.UNPACKED_OP_EG_LEVEL_4] = t[E + n.PACKED_OP_EG_LEVEL_4] & n.MASK_7BIT;
|
|
2815
2820
|
}
|
|
2816
2821
|
/**
|
|
2817
2822
|
* Unpack operator keyboard scaling parameters
|
|
2818
2823
|
* @private
|
|
2819
2824
|
*/
|
|
2820
|
-
_unpackOperatorScaling(t, s,
|
|
2821
|
-
s[
|
|
2825
|
+
_unpackOperatorScaling(t, s, E, e) {
|
|
2826
|
+
s[e + n.UNPACKED_OP_BREAK_POINT] = t[E + n.PACKED_OP_BREAK_POINT] & n.MASK_7BIT, s[e + n.UNPACKED_OP_L_SCALE_DEPTH] = t[E + n.PACKED_OP_L_SCALE_DEPTH] & n.MASK_7BIT, s[e + n.UNPACKED_OP_R_SCALE_DEPTH] = t[E + n.PACKED_OP_R_SCALE_DEPTH] & n.MASK_7BIT;
|
|
2822
2827
|
}
|
|
2823
2828
|
/**
|
|
2824
2829
|
* Unpack operator bit-packed parameters (curves, rate scaling, mod sens)
|
|
2825
2830
|
* @private
|
|
2826
2831
|
*/
|
|
2827
|
-
_unpackOperatorPackedParams(t, s,
|
|
2828
|
-
const _ = t[
|
|
2829
|
-
s[
|
|
2830
|
-
const i = t[
|
|
2831
|
-
s[
|
|
2832
|
-
const r = t[
|
|
2833
|
-
s[
|
|
2832
|
+
_unpackOperatorPackedParams(t, s, E, e) {
|
|
2833
|
+
const _ = t[E + n.PACKED_OP_CURVES] & n.MASK_7BIT;
|
|
2834
|
+
s[e + n.UNPACKED_OP_L_CURVE] = _ & n.MASK_2BIT, s[e + n.UNPACKED_OP_R_CURVE] = _ >> 2 & n.MASK_2BIT;
|
|
2835
|
+
const i = t[E + n.PACKED_OP_RATE_SCALING] & n.MASK_7BIT;
|
|
2836
|
+
s[e + n.UNPACKED_OP_RATE_SCALING] = i & n.MASK_3BIT, s[e + n.UNPACKED_OP_DETUNE] = i >> 3 & n.MASK_4BIT;
|
|
2837
|
+
const r = t[E + n.PACKED_OP_MOD_SENS] & n.MASK_7BIT;
|
|
2838
|
+
s[e + n.UNPACKED_OP_AMP_MOD_SENS] = r & n.MASK_2BIT, s[e + n.UNPACKED_OP_KEY_VEL_SENS] = r >> 2 & n.MASK_3BIT, s[e + n.UNPACKED_OP_OUTPUT_LEVEL] = t[E + n.PACKED_OP_OUTPUT_LEVEL] & n.MASK_7BIT;
|
|
2834
2839
|
}
|
|
2835
2840
|
/**
|
|
2836
2841
|
* Unpack operator frequency parameters
|
|
2837
2842
|
* @private
|
|
2838
2843
|
*/
|
|
2839
|
-
_unpackOperatorFrequency(t, s,
|
|
2840
|
-
const _ = t[
|
|
2841
|
-
s[
|
|
2842
|
-
const i = t[
|
|
2843
|
-
s[
|
|
2844
|
+
_unpackOperatorFrequency(t, s, E, e) {
|
|
2845
|
+
const _ = t[E + n.PACKED_OP_MODE_FREQ] & n.MASK_7BIT;
|
|
2846
|
+
s[e + n.UNPACKED_OP_MODE] = _ & n.MASK_1BIT, s[e + n.UNPACKED_OP_FREQ_COARSE] = _ >> 1 & n.MASK_5BIT;
|
|
2847
|
+
const i = t[E + n.PACKED_OP_DETUNE_FINE] & n.MASK_7BIT;
|
|
2848
|
+
s[e + n.UNPACKED_OP_OSC_DETUNE] = i & n.MASK_3BIT, s[e + n.UNPACKED_OP_FREQ_FINE] = i >> 3 & n.MASK_4BIT;
|
|
2844
2849
|
}
|
|
2845
2850
|
/**
|
|
2846
2851
|
* Unpack pitch envelope generator parameters
|
|
@@ -2855,18 +2860,18 @@ class n {
|
|
|
2855
2860
|
*/
|
|
2856
2861
|
_unpackGlobalParams(t, s) {
|
|
2857
2862
|
s[n.UNPACKED_ALGORITHM] = t[n.OFFSET_ALGORITHM] & n.MASK_5BIT;
|
|
2858
|
-
const
|
|
2859
|
-
s[n.UNPACKED_FEEDBACK] =
|
|
2860
|
-
const
|
|
2861
|
-
s[n.UNPACKED_LFO_KEY_SYNC] =
|
|
2863
|
+
const E = t[n.OFFSET_FEEDBACK] & n.MASK_7BIT;
|
|
2864
|
+
s[n.UNPACKED_FEEDBACK] = E & n.MASK_3BIT, s[n.UNPACKED_OSC_SYNC] = E >> 3 & n.MASK_1BIT, s[n.UNPACKED_LFO_SPEED] = t[n.OFFSET_LFO_SPEED] & n.MASK_7BIT, s[n.UNPACKED_LFO_DELAY] = t[n.OFFSET_LFO_DELAY] & n.MASK_7BIT, s[n.UNPACKED_LFO_PM_DEPTH] = t[n.OFFSET_LFO_PM_DEPTH] & n.MASK_7BIT, s[n.UNPACKED_LFO_AM_DEPTH] = t[n.OFFSET_LFO_AM_DEPTH] & n.MASK_7BIT;
|
|
2865
|
+
const e = t[n.OFFSET_LFO_SYNC_WAVE] & n.MASK_7BIT;
|
|
2866
|
+
s[n.UNPACKED_LFO_KEY_SYNC] = e & n.MASK_1BIT, s[n.UNPACKED_LFO_WAVE] = e >> 1 & n.MASK_3BIT, s[n.UNPACKED_LFO_PM_SENS] = e >> 4 & n.MASK_3BIT, s[n.UNPACKED_AMP_MOD_SENS] = t[n.OFFSET_AMP_MOD_SENS] & n.MASK_7BIT, s[n.UNPACKED_TRANSPOSE] = t[n.OFFSET_TRANSPOSE] & n.MASK_7BIT, s[n.UNPACKED_EG_BIAS_SENS] = t[n.OFFSET_EG_BIAS_SENS] & n.MASK_7BIT;
|
|
2862
2867
|
}
|
|
2863
2868
|
/**
|
|
2864
2869
|
* Copy voice name from packed to unpacked format
|
|
2865
2870
|
* @private
|
|
2866
2871
|
*/
|
|
2867
2872
|
_unpackName(t, s) {
|
|
2868
|
-
for (let
|
|
2869
|
-
s[n.UNPACKED_NAME_START +
|
|
2873
|
+
for (let E = 0; E < n.NAME_LENGTH; E++)
|
|
2874
|
+
s[n.UNPACKED_NAME_START + E] = t[n.PACKED_NAME_START + E] & n.MASK_7BIT;
|
|
2870
2875
|
}
|
|
2871
2876
|
/**
|
|
2872
2877
|
* Pack 169-byte unpacked data to 128-byte format
|
|
@@ -2888,53 +2893,53 @@ class n {
|
|
|
2888
2893
|
* @private
|
|
2889
2894
|
*/
|
|
2890
2895
|
static _packOperators(t, s) {
|
|
2891
|
-
for (let
|
|
2892
|
-
const
|
|
2893
|
-
n._packOperator(t, s,
|
|
2896
|
+
for (let E = 0; E < n.NUM_OPERATORS; E++) {
|
|
2897
|
+
const e = E * n.UNPACKED_OP_SIZE, _ = (n.NUM_OPERATORS - 1 - E) * n.PACKED_OP_SIZE;
|
|
2898
|
+
n._packOperator(t, s, e, _);
|
|
2894
2899
|
}
|
|
2895
2900
|
}
|
|
2896
2901
|
/**
|
|
2897
2902
|
* Pack a single operator's parameters
|
|
2898
2903
|
* @private
|
|
2899
2904
|
*/
|
|
2900
|
-
static _packOperator(t, s,
|
|
2901
|
-
n._packOperatorEG(t, s,
|
|
2905
|
+
static _packOperator(t, s, E, e) {
|
|
2906
|
+
n._packOperatorEG(t, s, E, e), n._packOperatorScaling(t, s, E, e), n._packOperatorPackedParams(t, s, E, e), n._packOperatorFrequency(t, s, E, e);
|
|
2902
2907
|
}
|
|
2903
2908
|
/**
|
|
2904
2909
|
* Pack operator EG rates and levels
|
|
2905
2910
|
* @private
|
|
2906
2911
|
*/
|
|
2907
|
-
static _packOperatorEG(t, s,
|
|
2908
|
-
s[
|
|
2912
|
+
static _packOperatorEG(t, s, E, e) {
|
|
2913
|
+
s[e + n.PACKED_OP_EG_RATE_1] = t[E + n.UNPACKED_OP_EG_RATE_1], s[e + n.PACKED_OP_EG_RATE_2] = t[E + n.UNPACKED_OP_EG_RATE_2], s[e + n.PACKED_OP_EG_RATE_3] = t[E + n.UNPACKED_OP_EG_RATE_3], s[e + n.PACKED_OP_EG_RATE_4] = t[E + n.UNPACKED_OP_EG_RATE_4], s[e + n.PACKED_OP_EG_LEVEL_1] = t[E + n.UNPACKED_OP_EG_LEVEL_1], s[e + n.PACKED_OP_EG_LEVEL_2] = t[E + n.UNPACKED_OP_EG_LEVEL_2], s[e + n.PACKED_OP_EG_LEVEL_3] = t[E + n.UNPACKED_OP_EG_LEVEL_3], s[e + n.PACKED_OP_EG_LEVEL_4] = t[E + n.UNPACKED_OP_EG_LEVEL_4];
|
|
2909
2914
|
}
|
|
2910
2915
|
/**
|
|
2911
2916
|
* Pack operator keyboard scaling parameters
|
|
2912
2917
|
* @private
|
|
2913
2918
|
*/
|
|
2914
|
-
static _packOperatorScaling(t, s,
|
|
2915
|
-
s[
|
|
2919
|
+
static _packOperatorScaling(t, s, E, e) {
|
|
2920
|
+
s[e + n.PACKED_OP_BREAK_POINT] = t[E + n.UNPACKED_OP_BREAK_POINT], s[e + n.PACKED_OP_L_SCALE_DEPTH] = t[E + n.UNPACKED_OP_L_SCALE_DEPTH], s[e + n.PACKED_OP_R_SCALE_DEPTH] = t[E + n.UNPACKED_OP_R_SCALE_DEPTH];
|
|
2916
2921
|
}
|
|
2917
2922
|
/**
|
|
2918
2923
|
* Pack operator bit-packed parameters
|
|
2919
2924
|
* @private
|
|
2920
2925
|
*/
|
|
2921
|
-
static _packOperatorPackedParams(t, s,
|
|
2922
|
-
const _ = t[
|
|
2923
|
-
s[
|
|
2924
|
-
const r = t[
|
|
2925
|
-
s[
|
|
2926
|
-
const S = t[
|
|
2927
|
-
s[
|
|
2926
|
+
static _packOperatorPackedParams(t, s, E, e) {
|
|
2927
|
+
const _ = t[E + n.UNPACKED_OP_L_CURVE] & n.MASK_2BIT, i = t[E + n.UNPACKED_OP_R_CURVE] & n.MASK_2BIT;
|
|
2928
|
+
s[e + n.PACKED_OP_CURVES] = _ | i << 2;
|
|
2929
|
+
const r = t[E + n.UNPACKED_OP_RATE_SCALING] & n.MASK_3BIT, u = t[E + n.UNPACKED_OP_DETUNE] & n.MASK_4BIT;
|
|
2930
|
+
s[e + n.PACKED_OP_RATE_SCALING] = r | u << 3;
|
|
2931
|
+
const S = t[E + n.UNPACKED_OP_AMP_MOD_SENS] & n.MASK_2BIT, P = t[E + n.UNPACKED_OP_KEY_VEL_SENS] & n.MASK_3BIT;
|
|
2932
|
+
s[e + n.PACKED_OP_MOD_SENS] = S | P << 2, s[e + n.PACKED_OP_OUTPUT_LEVEL] = t[E + n.UNPACKED_OP_OUTPUT_LEVEL];
|
|
2928
2933
|
}
|
|
2929
2934
|
/**
|
|
2930
2935
|
* Pack operator frequency parameters
|
|
2931
2936
|
* @private
|
|
2932
2937
|
*/
|
|
2933
|
-
static _packOperatorFrequency(t, s,
|
|
2934
|
-
const _ = t[
|
|
2935
|
-
s[
|
|
2936
|
-
const r = t[
|
|
2937
|
-
s[
|
|
2938
|
+
static _packOperatorFrequency(t, s, E, e) {
|
|
2939
|
+
const _ = t[E + n.UNPACKED_OP_MODE] & n.MASK_1BIT, i = t[E + n.UNPACKED_OP_FREQ_COARSE] & n.MASK_5BIT;
|
|
2940
|
+
s[e + n.PACKED_OP_MODE_FREQ] = _ | i << 1;
|
|
2941
|
+
const r = t[E + n.UNPACKED_OP_OSC_DETUNE] & n.MASK_3BIT, u = t[E + n.UNPACKED_OP_FREQ_FINE] & n.MASK_4BIT;
|
|
2942
|
+
s[e + n.PACKED_OP_DETUNE_FINE] = r | u << 3;
|
|
2938
2943
|
}
|
|
2939
2944
|
/**
|
|
2940
2945
|
* Pack pitch envelope generator parameters
|
|
@@ -2949,8 +2954,8 @@ class n {
|
|
|
2949
2954
|
*/
|
|
2950
2955
|
static _packGlobalParams(t, s) {
|
|
2951
2956
|
s[n.OFFSET_ALGORITHM] = t[n.UNPACKED_ALGORITHM];
|
|
2952
|
-
const
|
|
2953
|
-
s[n.OFFSET_FEEDBACK] =
|
|
2957
|
+
const E = t[n.UNPACKED_FEEDBACK] & n.MASK_3BIT, e = t[n.UNPACKED_OSC_SYNC] & n.MASK_1BIT;
|
|
2958
|
+
s[n.OFFSET_FEEDBACK] = E | e << 3, s[n.OFFSET_LFO_SPEED] = t[n.UNPACKED_LFO_SPEED], s[n.OFFSET_LFO_DELAY] = t[n.UNPACKED_LFO_DELAY], s[n.OFFSET_LFO_PM_DEPTH] = t[n.UNPACKED_LFO_PM_DEPTH], s[n.OFFSET_LFO_AM_DEPTH] = t[n.UNPACKED_LFO_AM_DEPTH];
|
|
2954
2959
|
const _ = t[n.UNPACKED_LFO_KEY_SYNC] & n.MASK_1BIT, i = t[n.UNPACKED_LFO_WAVE] & n.MASK_3BIT, r = t[n.UNPACKED_LFO_PM_SENS] & n.MASK_3BIT;
|
|
2955
2960
|
s[n.OFFSET_LFO_SYNC_WAVE] = _ | i << 1 | r << 4, s[n.OFFSET_AMP_MOD_SENS] = t[n.UNPACKED_AMP_MOD_SENS], s[n.OFFSET_TRANSPOSE] = t[n.UNPACKED_TRANSPOSE], s[n.OFFSET_EG_BIAS_SENS] = t[n.UNPACKED_EG_BIAS_SENS];
|
|
2956
2961
|
}
|
|
@@ -2959,8 +2964,8 @@ class n {
|
|
|
2959
2964
|
* @private
|
|
2960
2965
|
*/
|
|
2961
2966
|
static _packName(t, s) {
|
|
2962
|
-
for (let
|
|
2963
|
-
s[n.PACKED_NAME_START +
|
|
2967
|
+
for (let E = 0; E < n.NAME_LENGTH; E++)
|
|
2968
|
+
s[n.PACKED_NAME_START + E] = t[n.UNPACKED_NAME_START + E];
|
|
2964
2969
|
}
|
|
2965
2970
|
/**
|
|
2966
2971
|
* Create a default/empty voice
|
|
@@ -2971,14 +2976,14 @@ class n {
|
|
|
2971
2976
|
const s = new Uint8Array(n.UNPACKED_SIZE);
|
|
2972
2977
|
for (let _ = 0; _ < n.NUM_OPERATORS; _++) {
|
|
2973
2978
|
const i = _ * n.UNPACKED_OP_SIZE;
|
|
2974
|
-
s[i + n.UNPACKED_OP_EG_RATE_1] = n.DEFAULT_EG_RATE, s[i + n.UNPACKED_OP_EG_RATE_2] = n.DEFAULT_EG_RATE, s[i + n.UNPACKED_OP_EG_RATE_3] = n.DEFAULT_EG_RATE, s[i + n.UNPACKED_OP_EG_RATE_4] = n.DEFAULT_EG_RATE, s[i + n.UNPACKED_OP_EG_LEVEL_1] = n.DEFAULT_EG_LEVEL_MAX, s[i + n.UNPACKED_OP_EG_LEVEL_2] = n.DEFAULT_EG_LEVEL_MAX, s[i + n.UNPACKED_OP_EG_LEVEL_3] = n.DEFAULT_EG_LEVEL_MAX, s[i + n.UNPACKED_OP_EG_LEVEL_4] = n.DEFAULT_EG_LEVEL_MIN, s[i + n.UNPACKED_OP_BREAK_POINT] = n.DEFAULT_BREAK_POINT, s[i + n.UNPACKED_OP_L_SCALE_DEPTH] = 0, s[i + n.UNPACKED_OP_R_SCALE_DEPTH] = 0, s[i + n.UNPACKED_OP_L_CURVE] = 0, s[i + n.UNPACKED_OP_R_CURVE] = 0, s[i + n.UNPACKED_OP_RATE_SCALING] = 0, s[i + n.UNPACKED_OP_DETUNE] =
|
|
2979
|
+
s[i + n.UNPACKED_OP_EG_RATE_1] = n.DEFAULT_EG_RATE, s[i + n.UNPACKED_OP_EG_RATE_2] = n.DEFAULT_EG_RATE, s[i + n.UNPACKED_OP_EG_RATE_3] = n.DEFAULT_EG_RATE, s[i + n.UNPACKED_OP_EG_RATE_4] = n.DEFAULT_EG_RATE, s[i + n.UNPACKED_OP_EG_LEVEL_1] = n.DEFAULT_EG_LEVEL_MAX, s[i + n.UNPACKED_OP_EG_LEVEL_2] = n.DEFAULT_EG_LEVEL_MAX, s[i + n.UNPACKED_OP_EG_LEVEL_3] = n.DEFAULT_EG_LEVEL_MAX, s[i + n.UNPACKED_OP_EG_LEVEL_4] = n.DEFAULT_EG_LEVEL_MIN, s[i + n.UNPACKED_OP_BREAK_POINT] = n.DEFAULT_BREAK_POINT, s[i + n.UNPACKED_OP_L_SCALE_DEPTH] = 0, s[i + n.UNPACKED_OP_R_SCALE_DEPTH] = 0, s[i + n.UNPACKED_OP_L_CURVE] = 0, s[i + n.UNPACKED_OP_R_CURVE] = 0, s[i + n.UNPACKED_OP_RATE_SCALING] = 0, s[i + n.UNPACKED_OP_DETUNE] = n.DEFAULT_DETUNE, s[i + n.UNPACKED_OP_AMP_MOD_SENS] = 0, s[i + n.UNPACKED_OP_KEY_VEL_SENS] = 0, s[i + n.UNPACKED_OP_OUTPUT_LEVEL] = n.DEFAULT_OUTPUT_LEVEL, s[i + n.UNPACKED_OP_MODE] = 0, s[i + n.UNPACKED_OP_FREQ_COARSE] = n.DEFAULT_FREQ_COARSE, s[i + n.UNPACKED_OP_OSC_DETUNE] = 0, s[i + n.UNPACKED_OP_FREQ_FINE] = 0;
|
|
2975
2980
|
}
|
|
2976
|
-
s[n.UNPACKED_PITCH_EG_RATE_1] = n.DEFAULT_EG_RATE, s[n.UNPACKED_PITCH_EG_RATE_2] = n.DEFAULT_EG_RATE, s[n.UNPACKED_PITCH_EG_RATE_3] = n.DEFAULT_EG_RATE, s[n.UNPACKED_PITCH_EG_RATE_4] = n.DEFAULT_EG_RATE, s[n.UNPACKED_PITCH_EG_LEVEL_1] = n.DEFAULT_PITCH_EG_LEVEL, s[n.UNPACKED_PITCH_EG_LEVEL_2] = n.DEFAULT_PITCH_EG_LEVEL, s[n.UNPACKED_PITCH_EG_LEVEL_3] = n.DEFAULT_PITCH_EG_LEVEL, s[n.UNPACKED_PITCH_EG_LEVEL_4] = n.DEFAULT_PITCH_EG_LEVEL, s[n.UNPACKED_ALGORITHM] = n.DEFAULT_ALGORITHM, s[n.UNPACKED_FEEDBACK] = n.DEFAULT_FEEDBACK, s[n.UNPACKED_OSC_SYNC] =
|
|
2977
|
-
const
|
|
2981
|
+
s[n.UNPACKED_PITCH_EG_RATE_1] = n.DEFAULT_EG_RATE, s[n.UNPACKED_PITCH_EG_RATE_2] = n.DEFAULT_EG_RATE, s[n.UNPACKED_PITCH_EG_RATE_3] = n.DEFAULT_EG_RATE, s[n.UNPACKED_PITCH_EG_RATE_4] = n.DEFAULT_EG_RATE, s[n.UNPACKED_PITCH_EG_LEVEL_1] = n.DEFAULT_PITCH_EG_LEVEL, s[n.UNPACKED_PITCH_EG_LEVEL_2] = n.DEFAULT_PITCH_EG_LEVEL, s[n.UNPACKED_PITCH_EG_LEVEL_3] = n.DEFAULT_PITCH_EG_LEVEL, s[n.UNPACKED_PITCH_EG_LEVEL_4] = n.DEFAULT_PITCH_EG_LEVEL, s[n.UNPACKED_ALGORITHM] = n.DEFAULT_ALGORITHM, s[n.UNPACKED_FEEDBACK] = n.DEFAULT_FEEDBACK, s[n.UNPACKED_OSC_SYNC] = n.DEFAULT_OSC_SYNC, s[n.UNPACKED_LFO_SPEED] = n.DEFAULT_LFO_SPEED, s[n.UNPACKED_LFO_DELAY] = 0, s[n.UNPACKED_LFO_PM_DEPTH] = 0, s[n.UNPACKED_LFO_AM_DEPTH] = 0, s[n.UNPACKED_LFO_KEY_SYNC] = n.DEFAULT_LFO_KEY_SYNC, s[n.UNPACKED_LFO_WAVE] = 0, s[n.UNPACKED_LFO_PM_SENS] = n.DEFAULT_LFO_PM_SENS, s[n.UNPACKED_AMP_MOD_SENS] = 0, s[n.UNPACKED_TRANSPOSE] = n.TRANSPOSE_CENTER, s[n.UNPACKED_EG_BIAS_SENS] = 0;
|
|
2982
|
+
const E = "Init Voice";
|
|
2978
2983
|
for (let _ = 0; _ < n.NAME_LENGTH; _++)
|
|
2979
|
-
s[n.UNPACKED_NAME_START + _] = _ <
|
|
2980
|
-
const
|
|
2981
|
-
return new n(
|
|
2984
|
+
s[n.UNPACKED_NAME_START + _] = _ < E.length ? E.charCodeAt(_) : n.CHAR_SPACE;
|
|
2985
|
+
const e = n.pack(s);
|
|
2986
|
+
return new n(e, t);
|
|
2982
2987
|
}
|
|
2983
2988
|
/**
|
|
2984
2989
|
* Create a voice from unpacked 169-byte data
|
|
@@ -2987,8 +2992,8 @@ class n {
|
|
|
2987
2992
|
* @returns {DX7Voice}
|
|
2988
2993
|
*/
|
|
2989
2994
|
static fromUnpacked(t, s = 0) {
|
|
2990
|
-
const
|
|
2991
|
-
return new n(
|
|
2995
|
+
const E = n.pack(t);
|
|
2996
|
+
return new n(E, s);
|
|
2992
2997
|
}
|
|
2993
2998
|
/**
|
|
2994
2999
|
* Load a DX7 voice from a single voice SYX file
|
|
@@ -2998,9 +3003,9 @@ class n {
|
|
|
2998
3003
|
* @throws {Error} If file cannot be read (FileReader error)
|
|
2999
3004
|
*/
|
|
3000
3005
|
static async fromFile(t) {
|
|
3001
|
-
return new Promise((s,
|
|
3002
|
-
const
|
|
3003
|
-
|
|
3006
|
+
return new Promise((s, E) => {
|
|
3007
|
+
const e = new FileReader();
|
|
3008
|
+
e.onload = (_) => {
|
|
3004
3009
|
try {
|
|
3005
3010
|
const i = new Uint8Array(_.target.result);
|
|
3006
3011
|
if (i[0] !== n.VCED_SYSEX_START || i[1] !== n.VCED_YAMAHA_ID || i[2] !== n.VCED_SUB_STATUS || i[3] !== n.VCED_FORMAT_SINGLE || i[4] !== n.VCED_BYTE_COUNT_MSB || i[5] !== n.VCED_BYTE_COUNT_LSB)
|
|
@@ -3023,12 +3028,12 @@ class n {
|
|
|
3023
3028
|
P[n.UNPACKED_PITCH_EG_RATE_1] = r[a++], P[n.UNPACKED_PITCH_EG_RATE_2] = r[a++], P[n.UNPACKED_PITCH_EG_RATE_3] = r[a++], P[n.UNPACKED_PITCH_EG_RATE_4] = r[a++], P[n.UNPACKED_PITCH_EG_LEVEL_1] = r[a++], P[n.UNPACKED_PITCH_EG_LEVEL_2] = r[a++], P[n.UNPACKED_PITCH_EG_LEVEL_3] = r[a++], P[n.UNPACKED_PITCH_EG_LEVEL_4] = r[a++], P[n.UNPACKED_ALGORITHM] = r[a++], P[n.UNPACKED_FEEDBACK] = r[a++], P[n.UNPACKED_OSC_SYNC] = r[a++], P[n.UNPACKED_LFO_SPEED] = r[a++], P[n.UNPACKED_LFO_DELAY] = r[a++], P[n.UNPACKED_LFO_PM_DEPTH] = r[a++], P[n.UNPACKED_LFO_AM_DEPTH] = r[a++], P[n.UNPACKED_LFO_KEY_SYNC] = r[a++], P[n.UNPACKED_LFO_WAVE] = r[a++], P[n.UNPACKED_LFO_PM_SENS] = r[a++], P[n.UNPACKED_TRANSPOSE] = r[a++];
|
|
3024
3029
|
for (let h = 0; h < n.NAME_LENGTH; h++)
|
|
3025
3030
|
P[n.UNPACKED_NAME_START + h] = r[a++];
|
|
3026
|
-
const
|
|
3027
|
-
s(new n(
|
|
3031
|
+
const C = n.pack(P);
|
|
3032
|
+
s(new n(C, 0));
|
|
3028
3033
|
} catch (i) {
|
|
3029
|
-
|
|
3034
|
+
E(i);
|
|
3030
3035
|
}
|
|
3031
|
-
},
|
|
3036
|
+
}, e.onerror = () => E(new Error("Failed to read file")), e.readAsArrayBuffer(t);
|
|
3032
3037
|
});
|
|
3033
3038
|
}
|
|
3034
3039
|
/**
|
|
@@ -3040,42 +3045,42 @@ class n {
|
|
|
3040
3045
|
* @throws {DX7ValidationError} If data length is invalid
|
|
3041
3046
|
*/
|
|
3042
3047
|
static fromSysEx(t, s = 0) {
|
|
3043
|
-
const
|
|
3044
|
-
let
|
|
3045
|
-
if (
|
|
3046
|
-
if (
|
|
3048
|
+
const E = t instanceof Uint8Array ? t : new Uint8Array(t);
|
|
3049
|
+
let e;
|
|
3050
|
+
if (E[0] === n.VCED_SYSEX_START) {
|
|
3051
|
+
if (E[0] !== n.VCED_SYSEX_START || E[1] !== n.VCED_YAMAHA_ID || E[2] !== n.VCED_SUB_STATUS || E[3] !== n.VCED_FORMAT_SINGLE || E[4] !== n.VCED_BYTE_COUNT_MSB || E[5] !== n.VCED_BYTE_COUNT_LSB)
|
|
3047
3052
|
throw new m("Invalid VCED header", "header", 0);
|
|
3048
|
-
|
|
3049
|
-
} else if (
|
|
3050
|
-
|
|
3053
|
+
e = E.subarray(n.VCED_HEADER_SIZE, n.VCED_HEADER_SIZE + n.VCED_DATA_SIZE);
|
|
3054
|
+
} else if (E.length === n.PACKED_SIZE)
|
|
3055
|
+
e = E;
|
|
3051
3056
|
else
|
|
3052
3057
|
throw new c(
|
|
3053
|
-
`Invalid data length: expected ${n.PACKED_SIZE} or ${n.VCED_SIZE} bytes, got ${
|
|
3058
|
+
`Invalid data length: expected ${n.PACKED_SIZE} or ${n.VCED_SIZE} bytes, got ${E.length}`,
|
|
3054
3059
|
"length",
|
|
3055
|
-
|
|
3060
|
+
E.length
|
|
3056
3061
|
);
|
|
3057
|
-
if (
|
|
3062
|
+
if (e.length !== n.VCED_DATA_SIZE && e.length !== n.PACKED_SIZE)
|
|
3058
3063
|
throw new c(
|
|
3059
|
-
`Invalid voice data length: expected ${n.VCED_DATA_SIZE} or ${n.PACKED_SIZE} bytes, got ${
|
|
3064
|
+
`Invalid voice data length: expected ${n.VCED_DATA_SIZE} or ${n.PACKED_SIZE} bytes, got ${e.length}`,
|
|
3060
3065
|
"length",
|
|
3061
|
-
|
|
3066
|
+
e.length
|
|
3062
3067
|
);
|
|
3063
|
-
if (
|
|
3068
|
+
if (e.length === n.VCED_DATA_SIZE) {
|
|
3064
3069
|
const _ = new Uint8Array(n.UNPACKED_SIZE);
|
|
3065
3070
|
let i = 0;
|
|
3066
3071
|
for (let u = 0; u < n.NUM_OPERATORS; u++) {
|
|
3067
3072
|
const S = (n.NUM_OPERATORS - 1 - u) * n.UNPACKED_OP_SIZE;
|
|
3068
|
-
_[S + n.UNPACKED_OP_EG_RATE_1] =
|
|
3069
|
-
const P =
|
|
3070
|
-
_[S + n.UNPACKED_OP_AMP_MOD_SENS] = P & n.MASK_2BIT, _[S + n.UNPACKED_OP_KEY_VEL_SENS] = P >> 2 & n.MASK_3BIT, _[S + n.UNPACKED_OP_OUTPUT_LEVEL] =
|
|
3073
|
+
_[S + n.UNPACKED_OP_EG_RATE_1] = e[i++], _[S + n.UNPACKED_OP_EG_RATE_2] = e[i++], _[S + n.UNPACKED_OP_EG_RATE_3] = e[i++], _[S + n.UNPACKED_OP_EG_RATE_4] = e[i++], _[S + n.UNPACKED_OP_EG_LEVEL_1] = e[i++], _[S + n.UNPACKED_OP_EG_LEVEL_2] = e[i++], _[S + n.UNPACKED_OP_EG_LEVEL_3] = e[i++], _[S + n.UNPACKED_OP_EG_LEVEL_4] = e[i++], _[S + n.UNPACKED_OP_BREAK_POINT] = e[i++], _[S + n.UNPACKED_OP_L_SCALE_DEPTH] = e[i++], _[S + n.UNPACKED_OP_R_SCALE_DEPTH] = e[i++], _[S + n.UNPACKED_OP_L_CURVE] = e[i++], _[S + n.UNPACKED_OP_R_CURVE] = e[i++], _[S + n.UNPACKED_OP_RATE_SCALING] = e[i++], _[S + n.UNPACKED_OP_DETUNE] = e[i++];
|
|
3074
|
+
const P = e[i++];
|
|
3075
|
+
_[S + n.UNPACKED_OP_AMP_MOD_SENS] = P & n.MASK_2BIT, _[S + n.UNPACKED_OP_KEY_VEL_SENS] = P >> 2 & n.MASK_3BIT, _[S + n.UNPACKED_OP_OUTPUT_LEVEL] = e[i++], _[S + n.UNPACKED_OP_MODE] = e[i++], _[S + n.UNPACKED_OP_FREQ_COARSE] = e[i++], _[S + n.UNPACKED_OP_FREQ_FINE] = e[i++], _[S + n.UNPACKED_OP_OSC_DETUNE] = e[i++];
|
|
3071
3076
|
}
|
|
3072
|
-
_[n.UNPACKED_PITCH_EG_RATE_1] =
|
|
3077
|
+
_[n.UNPACKED_PITCH_EG_RATE_1] = e[i++], _[n.UNPACKED_PITCH_EG_RATE_2] = e[i++], _[n.UNPACKED_PITCH_EG_RATE_3] = e[i++], _[n.UNPACKED_PITCH_EG_RATE_4] = e[i++], _[n.UNPACKED_PITCH_EG_LEVEL_1] = e[i++], _[n.UNPACKED_PITCH_EG_LEVEL_2] = e[i++], _[n.UNPACKED_PITCH_EG_LEVEL_3] = e[i++], _[n.UNPACKED_PITCH_EG_LEVEL_4] = e[i++], _[n.UNPACKED_ALGORITHM] = e[i++], _[n.UNPACKED_FEEDBACK] = e[i++], _[n.UNPACKED_OSC_SYNC] = e[i++], _[n.UNPACKED_LFO_SPEED] = e[i++], _[n.UNPACKED_LFO_DELAY] = e[i++], _[n.UNPACKED_LFO_PM_DEPTH] = e[i++], _[n.UNPACKED_LFO_AM_DEPTH] = e[i++], _[n.UNPACKED_LFO_KEY_SYNC] = e[i++], _[n.UNPACKED_LFO_WAVE] = e[i++], _[n.UNPACKED_LFO_PM_SENS] = e[i++], _[n.UNPACKED_TRANSPOSE] = e[i++];
|
|
3073
3078
|
for (let u = 0; u < n.NAME_LENGTH; u++)
|
|
3074
|
-
_[n.UNPACKED_NAME_START + u] =
|
|
3079
|
+
_[n.UNPACKED_NAME_START + u] = e[i++];
|
|
3075
3080
|
const r = n.pack(_);
|
|
3076
3081
|
return new n(r, s);
|
|
3077
3082
|
}
|
|
3078
|
-
return new n(
|
|
3083
|
+
return new n(e, s);
|
|
3079
3084
|
}
|
|
3080
3085
|
/**
|
|
3081
3086
|
* Create a DX7Voice from a JSON object
|
|
@@ -3087,24 +3092,24 @@ class n {
|
|
|
3087
3092
|
static fromJSON(t, s = 0) {
|
|
3088
3093
|
if (!t || typeof t != "object")
|
|
3089
3094
|
throw new c("Invalid JSON: expected object", "json", t);
|
|
3090
|
-
const
|
|
3091
|
-
if (
|
|
3092
|
-
throw new c(`Missing required parameter: ${h}`, h,
|
|
3093
|
-
const T = Number(
|
|
3095
|
+
const E = new Uint8Array(n.UNPACKED_SIZE), e = (a, C, h, N = 0, d = 127) => {
|
|
3096
|
+
if (C == null)
|
|
3097
|
+
throw new c(`Missing required parameter: ${h}`, h, C);
|
|
3098
|
+
const T = Number(C);
|
|
3094
3099
|
if (Number.isNaN(T))
|
|
3095
|
-
throw new c(`Invalid parameter value for ${h}: ${
|
|
3100
|
+
throw new c(`Invalid parameter value for ${h}: ${C}`, h, C);
|
|
3096
3101
|
if (T < N || T > d)
|
|
3097
3102
|
throw new c(
|
|
3098
3103
|
`Parameter ${h} out of range: ${T} (must be ${N}-${d})`,
|
|
3099
3104
|
h,
|
|
3100
3105
|
T
|
|
3101
3106
|
);
|
|
3102
|
-
|
|
3107
|
+
E[a] = Math.floor(T);
|
|
3103
3108
|
}, _ = (a) => {
|
|
3104
|
-
const
|
|
3105
|
-
return
|
|
3109
|
+
const C = { "-LN": 0, "-EX": 1, "+EX": 2, "+LN": 3 };
|
|
3110
|
+
return C[a] !== void 0 ? C[a] : 0;
|
|
3106
3111
|
}, i = (a) => {
|
|
3107
|
-
const
|
|
3112
|
+
const C = {
|
|
3108
3113
|
TRIANGLE: 0,
|
|
3109
3114
|
"SAW DOWN": 1,
|
|
3110
3115
|
"SAW UP": 2,
|
|
@@ -3112,31 +3117,31 @@ class n {
|
|
|
3112
3117
|
SINE: 4,
|
|
3113
3118
|
"SAMPLE & HOLD": 5
|
|
3114
3119
|
};
|
|
3115
|
-
return
|
|
3120
|
+
return C[a] !== void 0 ? C[a] : 0;
|
|
3116
3121
|
}, r = (a) => {
|
|
3117
3122
|
if (!a || typeof a != "string") return 60;
|
|
3118
|
-
const
|
|
3119
|
-
if (!
|
|
3120
|
-
const [, h, N] =
|
|
3123
|
+
const C = a.trim().match(/^([A-G]#?)(-?\d+)$/);
|
|
3124
|
+
if (!C) return 60;
|
|
3125
|
+
const [, h, N] = C, d = parseInt(N, 10), f = { C: 0, "C#": 1, D: 2, "D#": 3, E: 4, F: 5, "F#": 6, G: 7, "G#": 8, A: 9, "A#": 10, B: 11 }[h.toUpperCase()];
|
|
3121
3126
|
return f === void 0 ? 60 : (d - n.MIDI_OCTAVE_OFFSET) * 12 + f;
|
|
3122
3127
|
};
|
|
3123
3128
|
if (!Array.isArray(t.operators))
|
|
3124
3129
|
throw new c("Invalid operators array: expected array", "operators", t.operators);
|
|
3125
3130
|
for (let a = 0; a < t.operators.length; a++) {
|
|
3126
|
-
const
|
|
3127
|
-
if (!
|
|
3128
|
-
throw new c(`Invalid operator data at index ${a}`, `operators[${a}]`,
|
|
3129
|
-
if (!
|
|
3131
|
+
const C = t.operators[a];
|
|
3132
|
+
if (!C || typeof C != "object")
|
|
3133
|
+
throw new c(`Invalid operator data at index ${a}`, `operators[${a}]`, C);
|
|
3134
|
+
if (!C.eg || !Array.isArray(C.eg.rates) || C.eg.rates.length !== 4)
|
|
3130
3135
|
throw new c(
|
|
3131
3136
|
`Invalid EG rates for operator ${a}`,
|
|
3132
3137
|
`operators[${a}].eg.rates`,
|
|
3133
|
-
|
|
3138
|
+
C.eg?.rates
|
|
3134
3139
|
);
|
|
3135
|
-
if (!
|
|
3140
|
+
if (!C.eg || !Array.isArray(C.eg.levels) || C.eg.levels.length !== 4)
|
|
3136
3141
|
throw new c(
|
|
3137
3142
|
`Invalid EG levels for operator ${a}`,
|
|
3138
3143
|
`operators[${a}].eg.levels`,
|
|
3139
|
-
|
|
3144
|
+
C.eg?.levels
|
|
3140
3145
|
);
|
|
3141
3146
|
}
|
|
3142
3147
|
if (t.operators.length !== n.NUM_OPERATORS)
|
|
@@ -3146,58 +3151,58 @@ class n {
|
|
|
3146
3151
|
t.operators
|
|
3147
3152
|
);
|
|
3148
3153
|
for (let a = 0; a < n.NUM_OPERATORS; a++) {
|
|
3149
|
-
const
|
|
3150
|
-
if (!
|
|
3154
|
+
const C = t.operators[a], h = a * n.UNPACKED_OP_SIZE;
|
|
3155
|
+
if (!C.eg || !Array.isArray(C.eg.rates) || C.eg.rates.length !== 4)
|
|
3151
3156
|
throw new c(
|
|
3152
3157
|
`Invalid EG rates for operator ${a}`,
|
|
3153
3158
|
`operators[${a}].eg.rates`,
|
|
3154
|
-
|
|
3159
|
+
C.eg?.rates
|
|
3155
3160
|
);
|
|
3156
|
-
if (
|
|
3161
|
+
if (e(h + n.UNPACKED_OP_EG_RATE_1, C.eg.rates[0], `operators[${a}].eg.rates[0]`, 0, 99), e(h + n.UNPACKED_OP_EG_RATE_2, C.eg.rates[1], `operators[${a}].eg.rates[1]`, 0, 99), e(h + n.UNPACKED_OP_EG_RATE_3, C.eg.rates[2], `operators[${a}].eg.rates[2]`, 0, 99), e(h + n.UNPACKED_OP_EG_RATE_4, C.eg.rates[3], `operators[${a}].eg.rates[3]`, 0, 99), !C.eg || !Array.isArray(C.eg.levels) || C.eg.levels.length !== 4)
|
|
3157
3162
|
throw new c(
|
|
3158
3163
|
`Invalid EG levels for operator ${a}`,
|
|
3159
3164
|
`operators[${a}].eg.levels`,
|
|
3160
|
-
|
|
3165
|
+
C.eg?.levels
|
|
3161
3166
|
);
|
|
3162
|
-
|
|
3163
|
-
const N = r(
|
|
3164
|
-
|
|
3167
|
+
e(h + n.UNPACKED_OP_EG_LEVEL_1, C.eg.levels[0], `operators[${a}].eg.levels[0]`, 0, 99), e(h + n.UNPACKED_OP_EG_LEVEL_2, C.eg.levels[1], `operators[${a}].eg.levels[1]`, 0, 99), e(h + n.UNPACKED_OP_EG_LEVEL_3, C.eg.levels[2], `operators[${a}].eg.levels[2]`, 0, 99), e(h + n.UNPACKED_OP_EG_LEVEL_4, C.eg.levels[3], `operators[${a}].eg.levels[3]`, 0, 99);
|
|
3168
|
+
const N = r(C.key?.breakPoint) - n.MIDI_BREAK_POINT_OFFSET;
|
|
3169
|
+
e(h + n.UNPACKED_OP_BREAK_POINT, N, `operators[${a}].key.breakPoint`, 0, 127), e(
|
|
3165
3170
|
h + n.UNPACKED_OP_L_SCALE_DEPTH,
|
|
3166
|
-
|
|
3171
|
+
C.scale?.left?.depth || 0,
|
|
3167
3172
|
`operators[${a}].scale.left.depth`,
|
|
3168
3173
|
0,
|
|
3169
3174
|
99
|
|
3170
|
-
),
|
|
3175
|
+
), e(
|
|
3171
3176
|
h + n.UNPACKED_OP_R_SCALE_DEPTH,
|
|
3172
|
-
|
|
3177
|
+
C.scale?.right?.depth || 0,
|
|
3173
3178
|
`operators[${a}].scale.right.depth`,
|
|
3174
3179
|
0,
|
|
3175
3180
|
99
|
|
3176
|
-
),
|
|
3181
|
+
), E[h + n.UNPACKED_OP_L_CURVE] = _(C.scale?.left?.curve || "-LN"), E[h + n.UNPACKED_OP_R_CURVE] = _(C.scale?.right?.curve || "-LN"), e(
|
|
3177
3182
|
h + n.UNPACKED_OP_RATE_SCALING,
|
|
3178
|
-
|
|
3183
|
+
C.key?.scaling || 0,
|
|
3179
3184
|
`operators[${a}].key.scaling`,
|
|
3180
3185
|
0,
|
|
3181
3186
|
7
|
|
3182
3187
|
);
|
|
3183
|
-
const d = Number(
|
|
3184
|
-
|
|
3188
|
+
const d = Number(C.osc?.detune) || 0;
|
|
3189
|
+
e(h + n.UNPACKED_OP_DETUNE, d + 7, `operators[${a}].osc.detune`, 0, 14), e(
|
|
3185
3190
|
h + n.UNPACKED_OP_AMP_MOD_SENS,
|
|
3186
|
-
|
|
3191
|
+
C.output?.ampModSens || 0,
|
|
3187
3192
|
`operators[${a}].output.ampModSens`,
|
|
3188
3193
|
0,
|
|
3189
3194
|
3
|
|
3190
|
-
),
|
|
3195
|
+
), e(
|
|
3191
3196
|
h + n.UNPACKED_OP_OUTPUT_LEVEL,
|
|
3192
|
-
|
|
3197
|
+
C.output?.level || 0,
|
|
3193
3198
|
`operators[${a}].output.level`,
|
|
3194
3199
|
0,
|
|
3195
3200
|
99
|
|
3196
3201
|
);
|
|
3197
|
-
const T =
|
|
3198
|
-
|
|
3202
|
+
const T = C.osc?.freq?.mode?.toUpperCase() === "FIXED" ? 1 : 0, f = Number(C.osc?.freq?.coarse) || 0, I = Number(C.osc?.freq?.fine) || 0;
|
|
3203
|
+
E[h + n.UNPACKED_OP_MODE] = T, e(h + n.UNPACKED_OP_FREQ_COARSE, f, `operators[${a}].osc.freq.coarse`, 0, 31), e(h + n.UNPACKED_OP_FREQ_FINE, I, `operators[${a}].osc.freq.fine`, 0, 15), e(
|
|
3199
3204
|
h + n.UNPACKED_OP_KEY_VEL_SENS,
|
|
3200
|
-
|
|
3205
|
+
C.key?.velocity || 0,
|
|
3201
3206
|
`operators[${a}].key.velocity`,
|
|
3202
3207
|
0,
|
|
3203
3208
|
7
|
|
@@ -3207,18 +3212,18 @@ class n {
|
|
|
3207
3212
|
throw new c("Invalid pitch EG rates", "pitchEG.rates", t.pitchEG?.rates);
|
|
3208
3213
|
if (!t.pitchEG || !Array.isArray(t.pitchEG.levels) || t.pitchEG.levels.length !== 4)
|
|
3209
3214
|
throw new c("Invalid pitch EG levels", "pitchEG.levels", t.pitchEG?.levels);
|
|
3210
|
-
if (
|
|
3215
|
+
if (e(n.UNPACKED_PITCH_EG_RATE_1, t.pitchEG.rates[0], "pitchEG.rates[0]", 0, 99), e(n.UNPACKED_PITCH_EG_RATE_2, t.pitchEG.rates[1], "pitchEG.rates[1]", 0, 99), e(n.UNPACKED_PITCH_EG_RATE_3, t.pitchEG.rates[2], "pitchEG.rates[2]", 0, 99), e(n.UNPACKED_PITCH_EG_RATE_4, t.pitchEG.rates[3], "pitchEG.rates[3]", 0, 99), e(n.UNPACKED_PITCH_EG_LEVEL_1, t.pitchEG.levels[0], "pitchEG.levels[0]", 0, 99), e(n.UNPACKED_PITCH_EG_LEVEL_2, t.pitchEG.levels[1], "pitchEG.levels[1]", 0, 99), e(n.UNPACKED_PITCH_EG_LEVEL_3, t.pitchEG.levels[2], "pitchEG.levels[2]", 0, 99), e(n.UNPACKED_PITCH_EG_LEVEL_4, t.pitchEG.levels[3], "pitchEG.levels[3]", 0, 99), !t.lfo || typeof t.lfo != "object")
|
|
3211
3216
|
throw new c("Invalid LFO data", "lfo", t.lfo);
|
|
3212
|
-
if (
|
|
3217
|
+
if (e(n.UNPACKED_LFO_SPEED, t.lfo.speed, "lfo.speed", 0, 99), e(n.UNPACKED_LFO_DELAY, t.lfo.delay, "lfo.delay", 0, 99), e(n.UNPACKED_LFO_PM_DEPTH, t.lfo.pmDepth, "lfo.pmDepth", 0, 99), e(n.UNPACKED_LFO_AM_DEPTH, t.lfo.amDepth, "lfo.amDepth", 0, 99), E[n.UNPACKED_LFO_KEY_SYNC] = t.lfo.keySync ? 1 : 0, E[n.UNPACKED_LFO_WAVE] = i(t.lfo.wave), !t.global || typeof t.global != "object")
|
|
3213
3218
|
throw new c("Invalid global data", "global", t.global);
|
|
3214
3219
|
const u = Number(t.global.algorithm) || 1;
|
|
3215
|
-
|
|
3220
|
+
e(n.UNPACKED_ALGORITHM, u - 1, "global.algorithm", 0, 31), e(n.UNPACKED_FEEDBACK, t.global.feedback, "global.feedback", 0, 7), E[n.UNPACKED_OSC_SYNC] = t.global.oscKeySync ? 1 : 0, e(n.UNPACKED_LFO_PM_SENS, t.global.pitchModSens, "global.pitchModSens", 0, 7);
|
|
3216
3221
|
const S = Number(t.global.transpose) || 0;
|
|
3217
|
-
|
|
3222
|
+
e(n.UNPACKED_TRANSPOSE, S + n.TRANSPOSE_CENTER, "global.transpose", 0, 127), e(n.UNPACKED_AMP_MOD_SENS, t.global.ampModSens || 0, "global.ampModSens", 0, 3), e(n.UNPACKED_EG_BIAS_SENS, t.global.egBiasSens || 0, "global.egBiasSens", 0, 7);
|
|
3218
3223
|
const P = t.name || "";
|
|
3219
3224
|
for (let a = 0; a < n.NAME_LENGTH; a++)
|
|
3220
|
-
|
|
3221
|
-
return n.fromUnpacked(
|
|
3225
|
+
E[n.UNPACKED_NAME_START + a] = a < P.length ? P.charCodeAt(a) : n.CHAR_SPACE;
|
|
3226
|
+
return n.fromUnpacked(E, s);
|
|
3222
3227
|
}
|
|
3223
3228
|
/**
|
|
3224
3229
|
* Export voice to DX7 single voice SysEx format (VCED format)
|
|
@@ -3228,29 +3233,29 @@ class n {
|
|
|
3228
3233
|
*/
|
|
3229
3234
|
toSysEx() {
|
|
3230
3235
|
const t = this.unpack(), s = new Uint8Array(n.VCED_SIZE);
|
|
3231
|
-
let
|
|
3232
|
-
s[
|
|
3236
|
+
let E = 0;
|
|
3237
|
+
s[E++] = n.VCED_SYSEX_START, s[E++] = n.VCED_YAMAHA_ID, s[E++] = n.VCED_SUB_STATUS, s[E++] = n.VCED_FORMAT_SINGLE, s[E++] = n.VCED_BYTE_COUNT_MSB, s[E++] = n.VCED_BYTE_COUNT_LSB;
|
|
3233
3238
|
for (let _ = n.NUM_OPERATORS - 1; _ >= 0; _--) {
|
|
3234
3239
|
const i = _ * n.UNPACKED_OP_SIZE;
|
|
3235
|
-
s[
|
|
3240
|
+
s[E++] = t[i + n.UNPACKED_OP_EG_RATE_1], s[E++] = t[i + n.UNPACKED_OP_EG_RATE_2], s[E++] = t[i + n.UNPACKED_OP_EG_RATE_3], s[E++] = t[i + n.UNPACKED_OP_EG_RATE_4], s[E++] = t[i + n.UNPACKED_OP_EG_LEVEL_1], s[E++] = t[i + n.UNPACKED_OP_EG_LEVEL_2], s[E++] = t[i + n.UNPACKED_OP_EG_LEVEL_3], s[E++] = t[i + n.UNPACKED_OP_EG_LEVEL_4], s[E++] = t[i + n.UNPACKED_OP_BREAK_POINT], s[E++] = t[i + n.UNPACKED_OP_L_SCALE_DEPTH], s[E++] = t[i + n.UNPACKED_OP_R_SCALE_DEPTH], s[E++] = t[i + n.UNPACKED_OP_L_CURVE], s[E++] = t[i + n.UNPACKED_OP_R_CURVE], s[E++] = t[i + n.UNPACKED_OP_RATE_SCALING], s[E++] = t[i + n.UNPACKED_OP_DETUNE];
|
|
3236
3241
|
const r = t[i + n.UNPACKED_OP_AMP_MOD_SENS] & n.MASK_2BIT, u = t[i + n.UNPACKED_OP_KEY_VEL_SENS] & n.MASK_3BIT;
|
|
3237
|
-
s[
|
|
3242
|
+
s[E++] = r | u << 2, s[E++] = t[i + n.UNPACKED_OP_OUTPUT_LEVEL], s[E++] = t[i + n.UNPACKED_OP_MODE], s[E++] = t[i + n.UNPACKED_OP_FREQ_COARSE], s[E++] = t[i + n.UNPACKED_OP_OSC_DETUNE], s[E++] = t[i + n.UNPACKED_OP_FREQ_FINE];
|
|
3238
3243
|
}
|
|
3239
|
-
s[
|
|
3244
|
+
s[E++] = t[n.UNPACKED_PITCH_EG_RATE_1], s[E++] = t[n.UNPACKED_PITCH_EG_RATE_2], s[E++] = t[n.UNPACKED_PITCH_EG_RATE_3], s[E++] = t[n.UNPACKED_PITCH_EG_RATE_4], s[E++] = t[n.UNPACKED_PITCH_EG_LEVEL_1], s[E++] = t[n.UNPACKED_PITCH_EG_LEVEL_2], s[E++] = t[n.UNPACKED_PITCH_EG_LEVEL_3], s[E++] = t[n.UNPACKED_PITCH_EG_LEVEL_4], s[E++] = t[n.UNPACKED_ALGORITHM], s[E++] = t[n.UNPACKED_FEEDBACK], s[E++] = t[n.UNPACKED_OSC_SYNC], s[E++] = t[n.UNPACKED_LFO_SPEED], s[E++] = t[n.UNPACKED_LFO_DELAY], s[E++] = t[n.UNPACKED_LFO_PM_DEPTH], s[E++] = t[n.UNPACKED_LFO_AM_DEPTH], s[E++] = t[n.UNPACKED_LFO_KEY_SYNC], s[E++] = t[n.UNPACKED_LFO_WAVE], s[E++] = t[n.UNPACKED_LFO_PM_SENS], s[E++] = t[n.UNPACKED_TRANSPOSE];
|
|
3240
3245
|
for (let _ = 0; _ < n.NAME_LENGTH; _++)
|
|
3241
|
-
s[
|
|
3242
|
-
const
|
|
3246
|
+
s[E++] = t[n.UNPACKED_NAME_START + _];
|
|
3247
|
+
const e = s.subarray(
|
|
3243
3248
|
n.VCED_HEADER_SIZE,
|
|
3244
3249
|
n.VCED_HEADER_SIZE + n.VCED_DATA_SIZE
|
|
3245
3250
|
);
|
|
3246
|
-
return s[
|
|
3251
|
+
return s[E++] = l._calculateChecksum(e, n.VCED_DATA_SIZE), s[E++] = n.VCED_SYSEX_END, s;
|
|
3247
3252
|
}
|
|
3248
3253
|
/**
|
|
3249
3254
|
* Convert voice to JSON format
|
|
3250
3255
|
* @returns {object} Voice data in JSON format
|
|
3251
3256
|
*/
|
|
3252
3257
|
toJSON() {
|
|
3253
|
-
const t = this.unpack(), s = [],
|
|
3258
|
+
const t = this.unpack(), s = [], E = (i) => ["-LN", "-EX", "+EX", "+LN"][i] || "UNKNOWN", e = (i) => ["TRIANGLE", "SAW DOWN", "SAW UP", "SQUARE", "SINE", "SAMPLE & HOLD"][i] || "UNKNOWN", _ = (i) => {
|
|
3254
3259
|
const r = ["C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"], u = Math.floor(i / 12) + n.MIDI_OCTAVE_OFFSET;
|
|
3255
3260
|
return `${r[i % 12]}${u}`;
|
|
3256
3261
|
};
|
|
@@ -3294,11 +3299,11 @@ class n {
|
|
|
3294
3299
|
scale: {
|
|
3295
3300
|
left: {
|
|
3296
3301
|
depth: t[r + n.UNPACKED_OP_L_SCALE_DEPTH],
|
|
3297
|
-
curve:
|
|
3302
|
+
curve: E(t[r + n.UNPACKED_OP_L_CURVE])
|
|
3298
3303
|
},
|
|
3299
3304
|
right: {
|
|
3300
3305
|
depth: t[r + n.UNPACKED_OP_R_SCALE_DEPTH],
|
|
3301
|
-
curve:
|
|
3306
|
+
curve: E(t[r + n.UNPACKED_OP_R_CURVE])
|
|
3302
3307
|
}
|
|
3303
3308
|
}
|
|
3304
3309
|
});
|
|
@@ -3326,7 +3331,7 @@ class n {
|
|
|
3326
3331
|
pmDepth: t[n.UNPACKED_LFO_PM_DEPTH],
|
|
3327
3332
|
amDepth: t[n.UNPACKED_LFO_AM_DEPTH],
|
|
3328
3333
|
keySync: t[n.UNPACKED_LFO_KEY_SYNC] === 1,
|
|
3329
|
-
wave:
|
|
3334
|
+
wave: e(t[n.UNPACKED_LFO_WAVE])
|
|
3330
3335
|
},
|
|
3331
3336
|
global: {
|
|
3332
3337
|
algorithm: t[n.UNPACKED_ALGORITHM] + 1,
|
|
@@ -3395,8 +3400,8 @@ class l {
|
|
|
3395
3400
|
if (this.voices = new Array(l.NUM_VOICES), this.name = s, t)
|
|
3396
3401
|
this._load(t);
|
|
3397
3402
|
else
|
|
3398
|
-
for (let
|
|
3399
|
-
this.voices[
|
|
3403
|
+
for (let E = 0; E < l.NUM_VOICES; E++)
|
|
3404
|
+
this.voices[E] = n.createDefault(E);
|
|
3400
3405
|
}
|
|
3401
3406
|
/**
|
|
3402
3407
|
* Calculate DX7 SysEx checksum
|
|
@@ -3406,10 +3411,10 @@ class l {
|
|
|
3406
3411
|
* @returns {number} Checksum byte
|
|
3407
3412
|
*/
|
|
3408
3413
|
static _calculateChecksum(t, s) {
|
|
3409
|
-
let
|
|
3410
|
-
for (let
|
|
3411
|
-
|
|
3412
|
-
return l.CHECKSUM_MODULO -
|
|
3414
|
+
let E = 0;
|
|
3415
|
+
for (let e = 0; e < s; e++)
|
|
3416
|
+
E += t[e];
|
|
3417
|
+
return l.CHECKSUM_MODULO - E % l.CHECKSUM_MODULO & l.MASK_7BIT;
|
|
3413
3418
|
}
|
|
3414
3419
|
/**
|
|
3415
3420
|
* Load and validate bank data
|
|
@@ -3418,7 +3423,7 @@ class l {
|
|
|
3418
3423
|
*/
|
|
3419
3424
|
_load(t) {
|
|
3420
3425
|
const s = t instanceof Uint8Array ? t : new Uint8Array(t);
|
|
3421
|
-
let
|
|
3426
|
+
let E, e = 0;
|
|
3422
3427
|
if (s[0] === l.SYSEX_START) {
|
|
3423
3428
|
const i = s.subarray(0, l.SYSEX_HEADER_SIZE), r = l.SYSEX_HEADER;
|
|
3424
3429
|
for (let u = 0; u < l.SYSEX_HEADER_SIZE; u++)
|
|
@@ -3428,31 +3433,31 @@ class l {
|
|
|
3428
3433
|
"header",
|
|
3429
3434
|
u
|
|
3430
3435
|
);
|
|
3431
|
-
|
|
3436
|
+
E = s.subarray(l.SYSEX_HEADER_SIZE, l.SYSEX_HEADER_SIZE + l.VOICE_DATA_SIZE), e = l.SYSEX_HEADER_SIZE;
|
|
3432
3437
|
} else if (s.length === l.VOICE_DATA_SIZE)
|
|
3433
|
-
|
|
3438
|
+
E = s;
|
|
3434
3439
|
else
|
|
3435
3440
|
throw new c(
|
|
3436
3441
|
`Invalid data length: expected ${l.VOICE_DATA_SIZE} or ${l.SYSEX_SIZE} bytes, got ${s.length}`,
|
|
3437
3442
|
"length",
|
|
3438
3443
|
s.length
|
|
3439
3444
|
);
|
|
3440
|
-
if (
|
|
3445
|
+
if (E.length !== l.VOICE_DATA_SIZE)
|
|
3441
3446
|
throw new c(
|
|
3442
|
-
`Invalid voice data length: expected ${l.VOICE_DATA_SIZE} bytes, got ${
|
|
3447
|
+
`Invalid voice data length: expected ${l.VOICE_DATA_SIZE} bytes, got ${E.length}`,
|
|
3443
3448
|
"length",
|
|
3444
|
-
|
|
3449
|
+
E.length
|
|
3445
3450
|
);
|
|
3446
3451
|
const _ = l.SYSEX_HEADER_SIZE + l.VOICE_DATA_SIZE;
|
|
3447
|
-
if (
|
|
3448
|
-
const i = s[_], r = l._calculateChecksum(
|
|
3452
|
+
if (e > 0 && s.length >= _ + 1) {
|
|
3453
|
+
const i = s[_], r = l._calculateChecksum(E, l.VOICE_DATA_SIZE);
|
|
3449
3454
|
i !== r && console.warn(
|
|
3450
3455
|
`DX7 checksum mismatch (expected ${r.toString(16)}, got ${i.toString(16)}). This is common with vintage SysEx files and the data is likely still valid.`
|
|
3451
3456
|
);
|
|
3452
3457
|
}
|
|
3453
3458
|
this.voices = new Array(l.NUM_VOICES);
|
|
3454
3459
|
for (let i = 0; i < l.NUM_VOICES; i++) {
|
|
3455
|
-
const r = i * l.VOICE_SIZE, u =
|
|
3460
|
+
const r = i * l.VOICE_SIZE, u = E.subarray(r, r + l.VOICE_SIZE);
|
|
3456
3461
|
this.voices[i] = new n(u, i);
|
|
3457
3462
|
}
|
|
3458
3463
|
}
|
|
@@ -3482,8 +3487,8 @@ class l {
|
|
|
3482
3487
|
replaceVoice(t, s) {
|
|
3483
3488
|
if (t < 0 || t >= l.NUM_VOICES)
|
|
3484
3489
|
throw new c(`Invalid voice index: ${t}`, "index", t);
|
|
3485
|
-
const
|
|
3486
|
-
this.voices[t] = new n(
|
|
3490
|
+
const E = new Uint8Array(s.data);
|
|
3491
|
+
this.voices[t] = new n(E, t);
|
|
3487
3492
|
}
|
|
3488
3493
|
/**
|
|
3489
3494
|
* Add a voice to the first empty slot
|
|
@@ -3492,8 +3497,8 @@ class l {
|
|
|
3492
3497
|
*/
|
|
3493
3498
|
addVoice(t) {
|
|
3494
3499
|
for (let s = 0; s < this.voices.length; s++) {
|
|
3495
|
-
const
|
|
3496
|
-
if (
|
|
3500
|
+
const E = this.voices[s];
|
|
3501
|
+
if (E.name === "" || E.name === "Init Voice")
|
|
3497
3502
|
return this.replaceVoice(s, t), s;
|
|
3498
3503
|
}
|
|
3499
3504
|
return -1;
|
|
@@ -3527,7 +3532,7 @@ class l {
|
|
|
3527
3532
|
*/
|
|
3528
3533
|
findVoiceByName(t) {
|
|
3529
3534
|
const s = t.toLowerCase();
|
|
3530
|
-
return this.voices.find((
|
|
3535
|
+
return this.voices.find((E) => E.name.toLowerCase().includes(s)) || null;
|
|
3531
3536
|
}
|
|
3532
3537
|
/**
|
|
3533
3538
|
* Load a DX7 bank from a file
|
|
@@ -3538,21 +3543,21 @@ class l {
|
|
|
3538
3543
|
* @throws {Error} If file cannot be read (FileReader error)
|
|
3539
3544
|
*/
|
|
3540
3545
|
static async fromFile(t) {
|
|
3541
|
-
return new Promise((s,
|
|
3542
|
-
const
|
|
3543
|
-
|
|
3546
|
+
return new Promise((s, E) => {
|
|
3547
|
+
const e = new FileReader();
|
|
3548
|
+
e.onload = async (_) => {
|
|
3544
3549
|
try {
|
|
3545
3550
|
const i = t.name || "", r = new Uint8Array(_.target.result);
|
|
3546
3551
|
if (r[0] === l.SYSEX_START && r[3] === n.VCED_FORMAT_SINGLE)
|
|
3547
|
-
|
|
3552
|
+
E(new m("This is a single voice file. Use DX7Voice.fromFile() instead.", "format", 3));
|
|
3548
3553
|
else {
|
|
3549
3554
|
const u = i.replace(/\.[^/.]+$/, ""), S = new l(_.target.result, u);
|
|
3550
3555
|
s(S);
|
|
3551
3556
|
}
|
|
3552
3557
|
} catch (i) {
|
|
3553
|
-
|
|
3558
|
+
E(i);
|
|
3554
3559
|
}
|
|
3555
|
-
},
|
|
3560
|
+
}, e.onerror = () => E(new Error("Failed to read file")), e.readAsArrayBuffer(t);
|
|
3556
3561
|
});
|
|
3557
3562
|
}
|
|
3558
3563
|
/**
|
|
@@ -3581,18 +3586,18 @@ class l {
|
|
|
3581
3586
|
t.voices.length !== l.NUM_VOICES && console.warn(
|
|
3582
3587
|
`Bank JSON has ${t.voices.length} voices, expected ${l.NUM_VOICES}. Missing voices will be filled with defaults.`
|
|
3583
3588
|
);
|
|
3584
|
-
const
|
|
3585
|
-
for (let
|
|
3586
|
-
const _ = t.voices[
|
|
3589
|
+
const E = Math.min(t.voices.length, l.NUM_VOICES);
|
|
3590
|
+
for (let e = 0; e < E; e++) {
|
|
3591
|
+
const _ = t.voices[e];
|
|
3587
3592
|
if (!_ || typeof _ != "object") {
|
|
3588
|
-
console.warn(`Invalid voice data at index ${
|
|
3593
|
+
console.warn(`Invalid voice data at index ${e}, using default voice`);
|
|
3589
3594
|
continue;
|
|
3590
3595
|
}
|
|
3591
3596
|
try {
|
|
3592
|
-
const { index: i, ...r } = _, u = n.fromJSON(r,
|
|
3593
|
-
s.replaceVoice(
|
|
3597
|
+
const { index: i, ...r } = _, u = n.fromJSON(r, e);
|
|
3598
|
+
s.replaceVoice(e, u);
|
|
3594
3599
|
} catch (i) {
|
|
3595
|
-
console.warn(`Failed to load voice at index ${
|
|
3600
|
+
console.warn(`Failed to load voice at index ${e}: ${i.message}, using default voice`);
|
|
3596
3601
|
}
|
|
3597
3602
|
}
|
|
3598
3603
|
return s;
|
|
@@ -3604,25 +3609,25 @@ class l {
|
|
|
3604
3609
|
toSysEx() {
|
|
3605
3610
|
const t = new Uint8Array(l.SYSEX_SIZE);
|
|
3606
3611
|
let s = 0;
|
|
3607
|
-
l.SYSEX_HEADER.forEach((
|
|
3608
|
-
t[s++] =
|
|
3612
|
+
l.SYSEX_HEADER.forEach((e) => {
|
|
3613
|
+
t[s++] = e;
|
|
3609
3614
|
});
|
|
3610
|
-
for (const
|
|
3615
|
+
for (const e of this.voices)
|
|
3611
3616
|
for (let _ = 0; _ < l.VOICE_SIZE; _++)
|
|
3612
|
-
t[s++] =
|
|
3613
|
-
const
|
|
3614
|
-
return t[s++] = l._calculateChecksum(
|
|
3617
|
+
t[s++] = e.data[_];
|
|
3618
|
+
const E = t.subarray(l.SYSEX_HEADER_SIZE, l.SYSEX_HEADER_SIZE + l.VOICE_DATA_SIZE);
|
|
3619
|
+
return t[s++] = l._calculateChecksum(E, l.VOICE_DATA_SIZE), t[s++] = l.SYSEX_END, t;
|
|
3615
3620
|
}
|
|
3616
3621
|
/**
|
|
3617
3622
|
* Convert bank to JSON format
|
|
3618
3623
|
* @returns {object} Bank data in JSON format
|
|
3619
3624
|
*/
|
|
3620
3625
|
toJSON() {
|
|
3621
|
-
const t = this.voices.map((s,
|
|
3622
|
-
const
|
|
3626
|
+
const t = this.voices.map((s, E) => {
|
|
3627
|
+
const e = s.toJSON();
|
|
3623
3628
|
return {
|
|
3624
|
-
index:
|
|
3625
|
-
...
|
|
3629
|
+
index: E + 1,
|
|
3630
|
+
...e
|
|
3626
3631
|
};
|
|
3627
3632
|
});
|
|
3628
3633
|
return {
|
|
@@ -3632,77 +3637,77 @@ class l {
|
|
|
3632
3637
|
};
|
|
3633
3638
|
}
|
|
3634
3639
|
}
|
|
3635
|
-
function nt(
|
|
3636
|
-
return
|
|
3637
|
-
manufacturerId:
|
|
3638
|
-
payload:
|
|
3639
|
-
raw:
|
|
3640
|
+
function nt(A) {
|
|
3641
|
+
return A[0] !== 240 || A[A.length - 1] !== 247 ? null : {
|
|
3642
|
+
manufacturerId: A[1],
|
|
3643
|
+
payload: A.slice(2, -1),
|
|
3644
|
+
raw: A
|
|
3640
3645
|
};
|
|
3641
3646
|
}
|
|
3642
|
-
function st(
|
|
3643
|
-
return [240,
|
|
3647
|
+
function st(A, t) {
|
|
3648
|
+
return [240, A, ...t, 247];
|
|
3644
3649
|
}
|
|
3645
|
-
function
|
|
3646
|
-
return
|
|
3650
|
+
function Et(A) {
|
|
3651
|
+
return A.length >= 2 && A[0] === 240 && A[A.length - 1] === 247;
|
|
3647
3652
|
}
|
|
3648
|
-
function
|
|
3653
|
+
function et(A) {
|
|
3649
3654
|
const t = [];
|
|
3650
|
-
for (let s = 0; s <
|
|
3651
|
-
const
|
|
3652
|
-
let
|
|
3655
|
+
for (let s = 0; s < A.length; s += 7) {
|
|
3656
|
+
const E = A.slice(s, s + 7);
|
|
3657
|
+
let e = 0;
|
|
3653
3658
|
const _ = [];
|
|
3654
|
-
for (let i = 0; i <
|
|
3655
|
-
const r =
|
|
3656
|
-
r & 128 && (
|
|
3659
|
+
for (let i = 0; i < E.length; i++) {
|
|
3660
|
+
const r = E[i];
|
|
3661
|
+
r & 128 && (e |= 1 << i), _.push(r & 127);
|
|
3657
3662
|
}
|
|
3658
|
-
t.push(
|
|
3663
|
+
t.push(e, ..._);
|
|
3659
3664
|
}
|
|
3660
3665
|
return t;
|
|
3661
3666
|
}
|
|
3662
|
-
function it(
|
|
3667
|
+
function it(A) {
|
|
3663
3668
|
const t = [];
|
|
3664
|
-
for (let s = 0; s <
|
|
3665
|
-
const
|
|
3666
|
-
for (let _ = 0; _ <
|
|
3667
|
-
let i =
|
|
3668
|
-
|
|
3669
|
+
for (let s = 0; s < A.length; s += 8) {
|
|
3670
|
+
const E = A[s], e = Math.min(7, A.length - s - 1);
|
|
3671
|
+
for (let _ = 0; _ < e; _++) {
|
|
3672
|
+
let i = A[s + 1 + _];
|
|
3673
|
+
E & 1 << _ && (i |= 128), t.push(i);
|
|
3669
3674
|
}
|
|
3670
3675
|
}
|
|
3671
3676
|
return t;
|
|
3672
3677
|
}
|
|
3673
|
-
function _t(
|
|
3674
|
-
return Number.isInteger(
|
|
3678
|
+
function _t(A) {
|
|
3679
|
+
return Number.isInteger(A) && A >= 1 && A <= 16;
|
|
3675
3680
|
}
|
|
3676
|
-
function rt(
|
|
3677
|
-
return Number.isInteger(
|
|
3681
|
+
function rt(A) {
|
|
3682
|
+
return Number.isInteger(A) && A >= 0 && A <= 127;
|
|
3678
3683
|
}
|
|
3679
|
-
function at(
|
|
3680
|
-
return Number.isInteger(
|
|
3684
|
+
function at(A) {
|
|
3685
|
+
return Number.isInteger(A) && A >= 0 && A <= 31;
|
|
3681
3686
|
}
|
|
3682
|
-
function
|
|
3683
|
-
return Number.isInteger(
|
|
3687
|
+
function At(A) {
|
|
3688
|
+
return Number.isInteger(A) && A >= 0 && A <= 127;
|
|
3684
3689
|
}
|
|
3685
|
-
function
|
|
3686
|
-
return Number.isInteger(
|
|
3690
|
+
function Ct(A) {
|
|
3691
|
+
return Number.isInteger(A) && A >= 0 && A <= 127;
|
|
3687
3692
|
}
|
|
3688
|
-
function
|
|
3689
|
-
return Number.isInteger(
|
|
3693
|
+
function ot(A) {
|
|
3694
|
+
return Number.isInteger(A) && A >= 0 && A <= 127;
|
|
3690
3695
|
}
|
|
3691
|
-
function Pt(
|
|
3692
|
-
return Number.isInteger(
|
|
3696
|
+
function Pt(A) {
|
|
3697
|
+
return Number.isInteger(A) && A >= 0 && A <= 127;
|
|
3693
3698
|
}
|
|
3694
|
-
function ut(
|
|
3695
|
-
return Number.isInteger(
|
|
3699
|
+
function ut(A) {
|
|
3700
|
+
return Number.isInteger(A) && A >= 0 && A <= 16383;
|
|
3696
3701
|
}
|
|
3697
|
-
function lt(
|
|
3698
|
-
return Number.isInteger(
|
|
3702
|
+
function lt(A, t) {
|
|
3703
|
+
return Number.isInteger(A) && A >= 0 && A <= 127 && Number.isInteger(t) && t >= 0 && t <= 127;
|
|
3699
3704
|
}
|
|
3700
|
-
async function ht(
|
|
3705
|
+
async function ht(A = {}) {
|
|
3701
3706
|
const {
|
|
3702
3707
|
onStatusUpdate: t,
|
|
3703
3708
|
onConnectionUpdate: s,
|
|
3704
|
-
inputChannel:
|
|
3705
|
-
outputChannel:
|
|
3709
|
+
inputChannel: E = 1,
|
|
3710
|
+
outputChannel: e = 1,
|
|
3706
3711
|
output: _,
|
|
3707
3712
|
sysex: i,
|
|
3708
3713
|
onReady: r,
|
|
@@ -3710,11 +3715,11 @@ async function ht(o = {}) {
|
|
|
3710
3715
|
selector: S,
|
|
3711
3716
|
watchDOM: P,
|
|
3712
3717
|
...a
|
|
3713
|
-
} =
|
|
3718
|
+
} = A, h = await W({
|
|
3714
3719
|
autoConnect: !1,
|
|
3715
3720
|
sysex: i,
|
|
3716
|
-
inputChannel:
|
|
3717
|
-
outputChannel:
|
|
3721
|
+
inputChannel: E,
|
|
3722
|
+
outputChannel: e,
|
|
3718
3723
|
selector: S || "[data-midi-cc]",
|
|
3719
3724
|
watchDOM: P,
|
|
3720
3725
|
onError: u,
|
|
@@ -3725,7 +3730,7 @@ async function ht(o = {}) {
|
|
|
3725
3730
|
}),
|
|
3726
3731
|
onConnectionUpdate: s || (() => {
|
|
3727
3732
|
}),
|
|
3728
|
-
channel:
|
|
3733
|
+
channel: e
|
|
3729
3734
|
});
|
|
3730
3735
|
if (_)
|
|
3731
3736
|
try {
|
|
@@ -3735,21 +3740,21 @@ async function ht(o = {}) {
|
|
|
3735
3740
|
}
|
|
3736
3741
|
return r && r(h, N), N;
|
|
3737
3742
|
}
|
|
3738
|
-
async function W(
|
|
3739
|
-
const t = new z(
|
|
3743
|
+
async function W(A = {}) {
|
|
3744
|
+
const t = new z(A);
|
|
3740
3745
|
await t.init();
|
|
3741
|
-
const s =
|
|
3746
|
+
const s = A.selector || "[data-midi-cc]";
|
|
3742
3747
|
{
|
|
3743
|
-
const
|
|
3744
|
-
|
|
3748
|
+
const E = new w(t, s);
|
|
3749
|
+
E.bindAll(), A.watchDOM && E.enableAutoBinding(), t._binder = E;
|
|
3745
3750
|
}
|
|
3746
3751
|
return t;
|
|
3747
3752
|
}
|
|
3748
3753
|
export {
|
|
3749
3754
|
U as CONN,
|
|
3750
3755
|
U as CONNECTION_EVENTS,
|
|
3751
|
-
|
|
3752
|
-
|
|
3756
|
+
o as CONTROLLER_EVENTS,
|
|
3757
|
+
o as CTRL,
|
|
3753
3758
|
l as DX7Bank,
|
|
3754
3759
|
b as DX7Error,
|
|
3755
3760
|
m as DX7ParseError,
|
|
@@ -3774,19 +3779,19 @@ export {
|
|
|
3774
3779
|
tt as denormalize14BitValue,
|
|
3775
3780
|
Q as denormalizeValue,
|
|
3776
3781
|
B as encode14BitValue,
|
|
3777
|
-
|
|
3782
|
+
et as encode7Bit,
|
|
3778
3783
|
k as frequencyToNote,
|
|
3779
3784
|
X as getCCName,
|
|
3780
|
-
|
|
3785
|
+
Et as isSysEx,
|
|
3781
3786
|
at as isValid14BitCC,
|
|
3782
3787
|
rt as isValidCC,
|
|
3783
3788
|
_t as isValidChannel,
|
|
3784
|
-
|
|
3785
|
-
|
|
3789
|
+
At as isValidMIDIValue,
|
|
3790
|
+
Ct as isValidNote,
|
|
3786
3791
|
ut as isValidPitchBend,
|
|
3787
3792
|
lt as isValidPitchBendBytes,
|
|
3788
3793
|
Pt as isValidProgramChange,
|
|
3789
|
-
|
|
3794
|
+
ot as isValidVelocity,
|
|
3790
3795
|
$ as normalize14BitValue,
|
|
3791
3796
|
x as normalizeValue,
|
|
3792
3797
|
J as noteNameToNumber,
|