midiwire 0.13.1 → 0.13.2

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.
@@ -221,7 +221,7 @@ class y extends g {
221
221
  super(e, "MIDI_CONNECTION_ERROR"), this.name = "MIDIConnectionError";
222
222
  }
223
223
  }
224
- class U extends g {
224
+ class p extends g {
225
225
  constructor(e, i, n) {
226
226
  super(e, "MIDI_DEVICE_ERROR"), this.name = "MIDIDeviceError", this.deviceType = i, this.deviceId = n;
227
227
  }
@@ -406,7 +406,7 @@ class w {
406
406
  e ? this.events.delete(e) : this.events.clear();
407
407
  }
408
408
  }
409
- const p = {
409
+ const L = {
410
410
  DEVICE_CHANGE: "device-change",
411
411
  IN_DEV_CONNECTED: "in-dev-connected",
412
412
  IN_DEV_DISCONNECTED: "in-dev-disconnected",
@@ -454,7 +454,7 @@ class Q extends w {
454
454
  sysex: this.options.sysex
455
455
  }), this.midiAccess.onstatechange = (e) => {
456
456
  const i = e.port, n = e.port.state;
457
- this.emit(p.DEVICE_CHANGE, {
457
+ this.emit(L.DEVICE_CHANGE, {
458
458
  port: i,
459
459
  state: n,
460
460
  type: i.type,
@@ -463,7 +463,7 @@ class Q extends w {
463
463
  name: i.name,
464
464
  manufacturer: i.manufacturer || "Unknown"
465
465
  }
466
- }), n === "disconnected" ? i.type === "input" ? (this.emit(p.IN_DEV_DISCONNECTED, { device: i }), this.input && this.input.id === i.id && (this.input = null)) : i.type === "output" && (this.emit(p.OUT_DEV_DISCONNECTED, { device: i }), this.output && this.output.id === i.id && (this.output = null)) : n === "connected" && (i.type === "input" ? this.emit(p.IN_DEV_CONNECTED, { device: i }) : i.type === "output" && this.emit(p.OUT_DEV_CONNECTED, { device: i }));
466
+ }), n === "disconnected" ? i.type === "input" ? (this.emit(L.IN_DEV_DISCONNECTED, { device: i }), this.input && this.input.id === i.id && (this.input = null)) : i.type === "output" && (this.emit(L.OUT_DEV_DISCONNECTED, { device: i }), this.output && this.output.id === i.id && (this.output = null)) : n === "connected" && (i.type === "input" ? this.emit(L.IN_DEV_CONNECTED, { device: i }) : i.type === "output" && this.emit(L.OUT_DEV_CONNECTED, { device: i }));
467
467
  };
468
468
  } catch (e) {
469
469
  throw e.name === "SecurityError" ? new F("MIDI access denied. SysEx requires user permission.", "denied") : new F(`Failed to get MIDI access: ${e.message}`, "failed");
@@ -498,20 +498,20 @@ class Q extends w {
498
498
  throw new y("MIDI access not initialized. Call requestAccess() first.");
499
499
  const i = Array.from(this.midiAccess.outputs.values());
500
500
  if (i.length === 0)
501
- throw new U("No MIDI output devices available", "output");
501
+ throw new p("No MIDI output devices available", "output");
502
502
  if (e === void 0) {
503
503
  this.output = i[0];
504
504
  return;
505
505
  }
506
506
  if (typeof e == "number") {
507
507
  if (e < 0 || e >= i.length)
508
- throw new U(`Output index ${e} out of range (0-${i.length - 1})`, "output", e);
508
+ throw new p(`Output index ${e} out of range (0-${i.length - 1})`, "output", e);
509
509
  this.output = i[e];
510
510
  return;
511
511
  }
512
512
  if (this.output = i.find((n) => n.name === e || n.id === e), !this.output) {
513
513
  const n = i.map((s) => s.name).join(", ");
514
- throw new U(`MIDI output "${e}" not found. Available: ${n}`, "output", e);
514
+ throw new p(`MIDI output "${e}" not found. Available: ${n}`, "output", e);
515
515
  }
516
516
  }
517
517
  /**
@@ -530,16 +530,16 @@ class Q extends w {
530
530
  throw new m("onMessage callback must be a function", "callback");
531
531
  const n = Array.from(this.midiAccess.inputs.values());
532
532
  if (n.length === 0)
533
- throw new U("No MIDI input devices available", "input");
533
+ throw new p("No MIDI input devices available", "input");
534
534
  if (this.input && (this.input.onmidimessage = null), e === void 0)
535
535
  this.input = n[0];
536
536
  else if (typeof e == "number") {
537
537
  if (e < 0 || e >= n.length)
538
- throw new U(`Input index ${e} out of range (0-${n.length - 1})`, "input", e);
538
+ throw new p(`Input index ${e} out of range (0-${n.length - 1})`, "input", e);
539
539
  this.input = n[e];
540
540
  } else if (this.input = n.find((s) => s.name === e || s.id === e), !this.input) {
541
541
  const s = n.map((r) => r.name).join(", ");
542
- throw new U(`MIDI input "${e}" not found. Available: ${s}`, "input", e);
542
+ throw new p(`MIDI input "${e}" not found. Available: ${s}`, "input", e);
543
543
  }
544
544
  this.input.onmidimessage = (s) => {
545
545
  i(s);
@@ -806,7 +806,7 @@ class J extends w {
806
806
  try {
807
807
  this.connection = new Q({
808
808
  sysex: this.options.sysex
809
- }), await this.connection.requestAccess(), this.connection.on(p.DEVICE_CHANGE, async ({ state: e, type: i, device: n }) => {
809
+ }), await this.connection.requestAccess(), this.connection.on(L.DEVICE_CHANGE, async ({ state: e, type: i, device: n }) => {
810
810
  try {
811
811
  if (e === "connected")
812
812
  i === "output" ? this.emit(P.DEV_OUT_CONNECTED, n) : i === "input" && this.emit(P.DEV_IN_CONNECTED, n);
@@ -1340,17 +1340,17 @@ class J extends w {
1340
1340
  this._sendCC(d, V, H), this._sendCC(T, B, H);
1341
1341
  };
1342
1342
  let I = null;
1343
- const L = S > 0 ? (G) => {
1343
+ const U = S > 0 ? (G) => {
1344
1344
  I && clearTimeout(I), I = setTimeout(() => {
1345
1345
  f(G), I = null;
1346
1346
  }, S);
1347
1347
  } : f;
1348
- return e.addEventListener("input", L), e.addEventListener("change", L), {
1348
+ return e.addEventListener("input", U), e.addEventListener("change", U), {
1349
1349
  element: e,
1350
1350
  config: u,
1351
1351
  handler: f,
1352
1352
  destroy: () => {
1353
- I && clearTimeout(I), e.removeEventListener("input", L), e.removeEventListener("change", L);
1353
+ I && clearTimeout(I), e.removeEventListener("input", U), e.removeEventListener("change", U);
1354
1354
  }
1355
1355
  };
1356
1356
  }
@@ -2660,9 +2660,7 @@ const t = class t {
2660
2660
  */
2661
2661
  _unpackOperatorFrequency(e, i, n, s) {
2662
2662
  const r = e[n + t.PACKED_OP_MODE_FREQ] & t.MASK_7BIT;
2663
- i[s + t.UNPACKED_OP_MODE] = r & t.MASK_1BIT, i[s + t.UNPACKED_OP_FREQ_COARSE] = r >> 1 & t.MASK_5BIT;
2664
- const E = e[n + t.PACKED_OP_DETUNE_FINE] & t.MASK_7BIT;
2665
- i[s + t.UNPACKED_OP_OSC_DETUNE] = E & t.MASK_3BIT, i[s + t.UNPACKED_OP_FREQ_FINE] = E >> 3 & t.MASK_4BIT;
2663
+ i[s + t.UNPACKED_OP_MODE] = r & t.MASK_1BIT, i[s + t.UNPACKED_OP_FREQ_COARSE] = r >> 1 & t.MASK_5BIT, i[s + t.UNPACKED_OP_FREQ_FINE] = e[n + t.PACKED_OP_DETUNE_FINE] & t.MASK_7BIT;
2666
2664
  }
2667
2665
  /**
2668
2666
  * Unpack pitch envelope generator parameters
@@ -2754,9 +2752,7 @@ const t = class t {
2754
2752
  */
2755
2753
  static _packOperatorFrequency(e, i, n, s) {
2756
2754
  const r = e[n + t.UNPACKED_OP_MODE] & t.MASK_1BIT, E = e[n + t.UNPACKED_OP_FREQ_COARSE] & t.MASK_5BIT;
2757
- i[s + t.PACKED_OP_MODE_FREQ] = r | E << 1;
2758
- const o = e[n + t.UNPACKED_OP_OSC_DETUNE] & t.MASK_3BIT, l = e[n + t.UNPACKED_OP_FREQ_FINE] & t.MASK_4BIT;
2759
- i[s + t.PACKED_OP_DETUNE_FINE] = o | l << 3;
2755
+ i[s + t.PACKED_OP_MODE_FREQ] = r | E << 1, i[s + t.PACKED_OP_DETUNE_FINE] = e[n + t.UNPACKED_OP_FREQ_FINE] & t.MASK_7BIT;
2760
2756
  }
2761
2757
  /**
2762
2758
  * Pack pitch envelope generator parameters
@@ -2793,7 +2789,7 @@ const t = class t {
2793
2789
  const i = new Uint8Array(t.UNPACKED_SIZE);
2794
2790
  for (let r = 0; r < t.NUM_OPERATORS; r++) {
2795
2791
  const E = r * t.UNPACKED_OP_SIZE;
2796
- i[E + t.UNPACKED_OP_EG_RATE_1] = t.DEFAULT_EG_RATE, i[E + t.UNPACKED_OP_EG_RATE_2] = t.DEFAULT_EG_RATE, i[E + t.UNPACKED_OP_EG_RATE_3] = t.DEFAULT_EG_RATE, i[E + t.UNPACKED_OP_EG_RATE_4] = t.DEFAULT_EG_RATE, i[E + t.UNPACKED_OP_EG_LEVEL_1] = t.DEFAULT_EG_LEVEL_MAX, i[E + t.UNPACKED_OP_EG_LEVEL_2] = t.DEFAULT_EG_LEVEL_MAX, i[E + t.UNPACKED_OP_EG_LEVEL_3] = t.DEFAULT_EG_LEVEL_MAX, i[E + t.UNPACKED_OP_EG_LEVEL_4] = t.DEFAULT_EG_LEVEL_MIN, i[E + t.UNPACKED_OP_BREAK_POINT] = t.DEFAULT_BREAK_POINT, i[E + t.UNPACKED_OP_L_SCALE_DEPTH] = 0, i[E + t.UNPACKED_OP_R_SCALE_DEPTH] = 0, i[E + t.UNPACKED_OP_L_CURVE] = 0, i[E + t.UNPACKED_OP_R_CURVE] = 0, i[E + t.UNPACKED_OP_RATE_SCALING] = 0, i[E + t.UNPACKED_OP_DETUNE] = t.DEFAULT_DETUNE, i[E + t.UNPACKED_OP_AMP_MOD_SENS] = 0, i[E + t.UNPACKED_OP_KEY_VEL_SENS] = 0, i[E + t.UNPACKED_OP_OUTPUT_LEVEL] = t.DEFAULT_OUTPUT_LEVEL, i[E + t.UNPACKED_OP_MODE] = 0, i[E + t.UNPACKED_OP_FREQ_COARSE] = t.DEFAULT_FREQ_COARSE, i[E + t.UNPACKED_OP_OSC_DETUNE] = 0, i[E + t.UNPACKED_OP_FREQ_FINE] = 0;
2792
+ i[E + t.UNPACKED_OP_EG_RATE_1] = t.DEFAULT_EG_RATE, i[E + t.UNPACKED_OP_EG_RATE_2] = t.DEFAULT_EG_RATE, i[E + t.UNPACKED_OP_EG_RATE_3] = t.DEFAULT_EG_RATE, i[E + t.UNPACKED_OP_EG_RATE_4] = t.DEFAULT_EG_RATE, i[E + t.UNPACKED_OP_EG_LEVEL_1] = t.DEFAULT_EG_LEVEL_MAX, i[E + t.UNPACKED_OP_EG_LEVEL_2] = t.DEFAULT_EG_LEVEL_MAX, i[E + t.UNPACKED_OP_EG_LEVEL_3] = t.DEFAULT_EG_LEVEL_MAX, i[E + t.UNPACKED_OP_EG_LEVEL_4] = t.DEFAULT_EG_LEVEL_MIN, i[E + t.UNPACKED_OP_BREAK_POINT] = t.DEFAULT_BREAK_POINT, i[E + t.UNPACKED_OP_L_SCALE_DEPTH] = 0, i[E + t.UNPACKED_OP_R_SCALE_DEPTH] = 0, i[E + t.UNPACKED_OP_L_CURVE] = 0, i[E + t.UNPACKED_OP_R_CURVE] = 0, i[E + t.UNPACKED_OP_RATE_SCALING] = 0, i[E + t.UNPACKED_OP_DETUNE] = t.DEFAULT_DETUNE, i[E + t.UNPACKED_OP_AMP_MOD_SENS] = 0, i[E + t.UNPACKED_OP_KEY_VEL_SENS] = 0, i[E + t.UNPACKED_OP_OUTPUT_LEVEL] = t.DEFAULT_OUTPUT_LEVEL, i[E + t.UNPACKED_OP_MODE] = 0, i[E + t.UNPACKED_OP_FREQ_COARSE] = t.DEFAULT_FREQ_COARSE, i[E + t.UNPACKED_OP_FREQ_FINE] = 0;
2797
2793
  }
2798
2794
  i[t.UNPACKED_PITCH_EG_RATE_1] = t.DEFAULT_EG_RATE, i[t.UNPACKED_PITCH_EG_RATE_2] = t.DEFAULT_EG_RATE, i[t.UNPACKED_PITCH_EG_RATE_3] = t.DEFAULT_EG_RATE, i[t.UNPACKED_PITCH_EG_RATE_4] = t.DEFAULT_EG_RATE, i[t.UNPACKED_PITCH_EG_LEVEL_1] = t.DEFAULT_PITCH_EG_LEVEL, i[t.UNPACKED_PITCH_EG_LEVEL_2] = t.DEFAULT_PITCH_EG_LEVEL, i[t.UNPACKED_PITCH_EG_LEVEL_3] = t.DEFAULT_PITCH_EG_LEVEL, i[t.UNPACKED_PITCH_EG_LEVEL_4] = t.DEFAULT_PITCH_EG_LEVEL, i[t.UNPACKED_ALGORITHM] = t.DEFAULT_ALGORITHM, i[t.UNPACKED_FEEDBACK] = t.DEFAULT_FEEDBACK, i[t.UNPACKED_OSC_SYNC] = t.DEFAULT_OSC_SYNC, i[t.UNPACKED_LFO_SPEED] = t.DEFAULT_LFO_SPEED, i[t.UNPACKED_LFO_DELAY] = 0, i[t.UNPACKED_LFO_PM_DEPTH] = 0, i[t.UNPACKED_LFO_AM_DEPTH] = 0, i[t.UNPACKED_LFO_KEY_SYNC] = t.DEFAULT_LFO_KEY_SYNC, i[t.UNPACKED_LFO_WAVE] = 0, i[t.UNPACKED_LFO_PM_SENS] = t.DEFAULT_LFO_PM_SENS, i[t.UNPACKED_AMP_MOD_SENS] = 0, i[t.UNPACKED_TRANSPOSE] = t.TRANSPOSE_CENTER, i[t.UNPACKED_EG_BIAS_SENS] = 0;
2799
2795
  const n = "Init Voice";
@@ -2840,7 +2836,7 @@ const t = class t {
2840
2836
  const N = (t.NUM_OPERATORS - 1 - h) * t.UNPACKED_OP_SIZE;
2841
2837
  u[N + t.UNPACKED_OP_EG_RATE_1] = o[a++], u[N + t.UNPACKED_OP_EG_RATE_2] = o[a++], u[N + t.UNPACKED_OP_EG_RATE_3] = o[a++], u[N + t.UNPACKED_OP_EG_RATE_4] = o[a++], u[N + t.UNPACKED_OP_EG_LEVEL_1] = o[a++], u[N + t.UNPACKED_OP_EG_LEVEL_2] = o[a++], u[N + t.UNPACKED_OP_EG_LEVEL_3] = o[a++], u[N + t.UNPACKED_OP_EG_LEVEL_4] = o[a++], u[N + t.UNPACKED_OP_BREAK_POINT] = o[a++], u[N + t.UNPACKED_OP_L_SCALE_DEPTH] = o[a++], u[N + t.UNPACKED_OP_R_SCALE_DEPTH] = o[a++], u[N + t.UNPACKED_OP_L_CURVE] = o[a++], u[N + t.UNPACKED_OP_R_CURVE] = o[a++], u[N + t.UNPACKED_OP_RATE_SCALING] = o[a++], u[N + t.UNPACKED_OP_DETUNE] = o[a++];
2842
2838
  const d = o[a++];
2843
- u[N + t.UNPACKED_OP_AMP_MOD_SENS] = d & t.MASK_2BIT, u[N + t.UNPACKED_OP_KEY_VEL_SENS] = d >> 2 & t.MASK_3BIT, u[N + t.UNPACKED_OP_OUTPUT_LEVEL] = o[a++], u[N + t.UNPACKED_OP_MODE] = o[a++], u[N + t.UNPACKED_OP_FREQ_COARSE] = o[a++], u[N + t.UNPACKED_OP_FREQ_FINE] = o[a++], u[N + t.UNPACKED_OP_OSC_DETUNE] = o[a++];
2839
+ u[N + t.UNPACKED_OP_AMP_MOD_SENS] = d & t.MASK_2BIT, u[N + t.UNPACKED_OP_KEY_VEL_SENS] = d >> 2 & t.MASK_3BIT, u[N + t.UNPACKED_OP_OUTPUT_LEVEL] = o[a++], u[N + t.UNPACKED_OP_MODE] = o[a++], u[N + t.UNPACKED_OP_FREQ_COARSE] = o[a++], u[N + t.UNPACKED_OP_FREQ_FINE] = o[a++], a++;
2844
2840
  }
2845
2841
  u[t.UNPACKED_PITCH_EG_RATE_1] = o[a++], u[t.UNPACKED_PITCH_EG_RATE_2] = o[a++], u[t.UNPACKED_PITCH_EG_RATE_3] = o[a++], u[t.UNPACKED_PITCH_EG_RATE_4] = o[a++], u[t.UNPACKED_PITCH_EG_LEVEL_1] = o[a++], u[t.UNPACKED_PITCH_EG_LEVEL_2] = o[a++], u[t.UNPACKED_PITCH_EG_LEVEL_3] = o[a++], u[t.UNPACKED_PITCH_EG_LEVEL_4] = o[a++], u[t.UNPACKED_ALGORITHM] = o[a++], u[t.UNPACKED_FEEDBACK] = o[a++], u[t.UNPACKED_OSC_SYNC] = o[a++], u[t.UNPACKED_LFO_SPEED] = o[a++], u[t.UNPACKED_LFO_DELAY] = o[a++], u[t.UNPACKED_LFO_PM_DEPTH] = o[a++], u[t.UNPACKED_LFO_AM_DEPTH] = o[a++], u[t.UNPACKED_LFO_KEY_SYNC] = o[a++], u[t.UNPACKED_LFO_WAVE] = o[a++], u[t.UNPACKED_LFO_PM_SENS] = o[a++], u[t.UNPACKED_TRANSPOSE] = o[a++];
2846
2842
  for (let h = 0; h < t.NAME_LENGTH; h++)
@@ -2889,7 +2885,7 @@ const t = class t {
2889
2885
  const S = (t.NUM_OPERATORS - 1 - l) * t.UNPACKED_OP_SIZE;
2890
2886
  r[S + t.UNPACKED_OP_EG_RATE_1] = s[E++], r[S + t.UNPACKED_OP_EG_RATE_2] = s[E++], r[S + t.UNPACKED_OP_EG_RATE_3] = s[E++], r[S + t.UNPACKED_OP_EG_RATE_4] = s[E++], r[S + t.UNPACKED_OP_EG_LEVEL_1] = s[E++], r[S + t.UNPACKED_OP_EG_LEVEL_2] = s[E++], r[S + t.UNPACKED_OP_EG_LEVEL_3] = s[E++], r[S + t.UNPACKED_OP_EG_LEVEL_4] = s[E++], r[S + t.UNPACKED_OP_BREAK_POINT] = s[E++], r[S + t.UNPACKED_OP_L_SCALE_DEPTH] = s[E++], r[S + t.UNPACKED_OP_R_SCALE_DEPTH] = s[E++], r[S + t.UNPACKED_OP_L_CURVE] = s[E++], r[S + t.UNPACKED_OP_R_CURVE] = s[E++], r[S + t.UNPACKED_OP_RATE_SCALING] = s[E++], r[S + t.UNPACKED_OP_DETUNE] = s[E++];
2891
2887
  const u = s[E++];
2892
- r[S + t.UNPACKED_OP_AMP_MOD_SENS] = u & t.MASK_2BIT, r[S + t.UNPACKED_OP_KEY_VEL_SENS] = u >> 2 & t.MASK_3BIT, r[S + t.UNPACKED_OP_OUTPUT_LEVEL] = s[E++], r[S + t.UNPACKED_OP_MODE] = s[E++], r[S + t.UNPACKED_OP_FREQ_COARSE] = s[E++], r[S + t.UNPACKED_OP_FREQ_FINE] = s[E++], r[S + t.UNPACKED_OP_OSC_DETUNE] = s[E++];
2888
+ r[S + t.UNPACKED_OP_AMP_MOD_SENS] = u & t.MASK_2BIT, r[S + t.UNPACKED_OP_KEY_VEL_SENS] = u >> 2 & t.MASK_3BIT, r[S + t.UNPACKED_OP_OUTPUT_LEVEL] = s[E++], r[S + t.UNPACKED_OP_MODE] = s[E++], r[S + t.UNPACKED_OP_FREQ_COARSE] = s[E++], r[S + t.UNPACKED_OP_FREQ_FINE] = s[E++], E++;
2893
2889
  }
2894
2890
  r[t.UNPACKED_PITCH_EG_RATE_1] = s[E++], r[t.UNPACKED_PITCH_EG_RATE_2] = s[E++], r[t.UNPACKED_PITCH_EG_RATE_3] = s[E++], r[t.UNPACKED_PITCH_EG_RATE_4] = s[E++], r[t.UNPACKED_PITCH_EG_LEVEL_1] = s[E++], r[t.UNPACKED_PITCH_EG_LEVEL_2] = s[E++], r[t.UNPACKED_PITCH_EG_LEVEL_3] = s[E++], r[t.UNPACKED_PITCH_EG_LEVEL_4] = s[E++], r[t.UNPACKED_ALGORITHM] = s[E++], r[t.UNPACKED_FEEDBACK] = s[E++], r[t.UNPACKED_OSC_SYNC] = s[E++], r[t.UNPACKED_LFO_SPEED] = s[E++], r[t.UNPACKED_LFO_DELAY] = s[E++], r[t.UNPACKED_LFO_PM_DEPTH] = s[E++], r[t.UNPACKED_LFO_AM_DEPTH] = s[E++], r[t.UNPACKED_LFO_KEY_SYNC] = s[E++], r[t.UNPACKED_LFO_WAVE] = s[E++], r[t.UNPACKED_LFO_PM_SENS] = s[E++], r[t.UNPACKED_TRANSPOSE] = s[E++];
2895
2891
  for (let l = 0; l < t.NAME_LENGTH; l++)
@@ -3002,8 +2998,8 @@ const t = class t {
3002
2998
  0,
3003
2999
  7
3004
3000
  );
3005
- const d = Number(A.osc?.detune) || 0;
3006
- s(h + t.UNPACKED_OP_DETUNE, d + 7, `operators[${a}].osc.detune`, 0, 14), s(
3001
+ const d = Number(A.osc?.detune) || 0, T = Math.max(-7, Math.min(7, d));
3002
+ s(h + t.UNPACKED_OP_DETUNE, T + 7, `operators[${a}].osc.detune`, 0, 14), s(
3007
3003
  h + t.UNPACKED_OP_AMP_MOD_SENS,
3008
3004
  A.output?.ampModSens || 0,
3009
3005
  `operators[${a}].output.ampModSens`,
@@ -3016,8 +3012,8 @@ const t = class t {
3016
3012
  0,
3017
3013
  99
3018
3014
  );
3019
- const T = A.osc?.freq?.mode?.toUpperCase() === "FIXED" ? 1 : 0, f = Number(A.osc?.freq?.coarse) || 0, I = Number(A.osc?.freq?.fine) || 0;
3020
- n[h + t.UNPACKED_OP_MODE] = T, s(h + t.UNPACKED_OP_FREQ_COARSE, f, `operators[${a}].osc.freq.coarse`, 0, 31), s(h + t.UNPACKED_OP_FREQ_FINE, I, `operators[${a}].osc.freq.fine`, 0, 99), s(
3015
+ const f = A.osc?.freq?.mode?.toUpperCase() === "FIXED" ? 1 : 0, I = Number(A.osc?.freq?.coarse) || 0, U = Number(A.osc?.freq?.fine) || 0;
3016
+ n[h + t.UNPACKED_OP_MODE] = f, s(h + t.UNPACKED_OP_FREQ_COARSE, I, `operators[${a}].osc.freq.coarse`, 0, 31), s(h + t.UNPACKED_OP_FREQ_FINE, U, `operators[${a}].osc.freq.fine`, 0, 99), s(
3021
3017
  h + t.UNPACKED_OP_KEY_VEL_SENS,
3022
3018
  A.key?.velocity || 0,
3023
3019
  `operators[${a}].key.velocity`,
@@ -3056,7 +3052,7 @@ const t = class t {
3056
3052
  const E = r * t.UNPACKED_OP_SIZE;
3057
3053
  i[n++] = e[E + t.UNPACKED_OP_EG_RATE_1], i[n++] = e[E + t.UNPACKED_OP_EG_RATE_2], i[n++] = e[E + t.UNPACKED_OP_EG_RATE_3], i[n++] = e[E + t.UNPACKED_OP_EG_RATE_4], i[n++] = e[E + t.UNPACKED_OP_EG_LEVEL_1], i[n++] = e[E + t.UNPACKED_OP_EG_LEVEL_2], i[n++] = e[E + t.UNPACKED_OP_EG_LEVEL_3], i[n++] = e[E + t.UNPACKED_OP_EG_LEVEL_4], i[n++] = e[E + t.UNPACKED_OP_BREAK_POINT], i[n++] = e[E + t.UNPACKED_OP_L_SCALE_DEPTH], i[n++] = e[E + t.UNPACKED_OP_R_SCALE_DEPTH], i[n++] = e[E + t.UNPACKED_OP_L_CURVE], i[n++] = e[E + t.UNPACKED_OP_R_CURVE], i[n++] = e[E + t.UNPACKED_OP_RATE_SCALING], i[n++] = e[E + t.UNPACKED_OP_DETUNE];
3058
3054
  const o = e[E + t.UNPACKED_OP_AMP_MOD_SENS] & t.MASK_2BIT, l = e[E + t.UNPACKED_OP_KEY_VEL_SENS] & t.MASK_3BIT;
3059
- i[n++] = o | l << 2, i[n++] = e[E + t.UNPACKED_OP_OUTPUT_LEVEL], i[n++] = e[E + t.UNPACKED_OP_MODE], i[n++] = e[E + t.UNPACKED_OP_FREQ_COARSE], i[n++] = e[E + t.UNPACKED_OP_OSC_DETUNE], i[n++] = e[E + t.UNPACKED_OP_FREQ_FINE];
3055
+ i[n++] = o | l << 2, i[n++] = e[E + t.UNPACKED_OP_OUTPUT_LEVEL], i[n++] = e[E + t.UNPACKED_OP_MODE], i[n++] = e[E + t.UNPACKED_OP_FREQ_COARSE], i[n++] = e[E + t.UNPACKED_OP_FREQ_FINE], i[n++] = 0;
3060
3056
  }
3061
3057
  i[n++] = e[t.UNPACKED_PITCH_EG_RATE_1], i[n++] = e[t.UNPACKED_PITCH_EG_RATE_2], i[n++] = e[t.UNPACKED_PITCH_EG_RATE_3], i[n++] = e[t.UNPACKED_PITCH_EG_RATE_4], i[n++] = e[t.UNPACKED_PITCH_EG_LEVEL_1], i[n++] = e[t.UNPACKED_PITCH_EG_LEVEL_2], i[n++] = e[t.UNPACKED_PITCH_EG_LEVEL_3], i[n++] = e[t.UNPACKED_PITCH_EG_LEVEL_4], i[n++] = e[t.UNPACKED_ALGORITHM], i[n++] = e[t.UNPACKED_FEEDBACK], i[n++] = e[t.UNPACKED_OSC_SYNC], i[n++] = e[t.UNPACKED_LFO_SPEED], i[n++] = e[t.UNPACKED_LFO_DELAY], i[n++] = e[t.UNPACKED_LFO_PM_DEPTH], i[n++] = e[t.UNPACKED_LFO_AM_DEPTH], i[n++] = e[t.UNPACKED_LFO_KEY_SYNC], i[n++] = e[t.UNPACKED_LFO_WAVE], i[n++] = e[t.UNPACKED_LFO_PM_SENS], i[n++] = e[t.UNPACKED_TRANSPOSE];
3062
3058
  for (let r = 0; r < t.NAME_LENGTH; r++)
@@ -3081,7 +3077,8 @@ const t = class t {
3081
3077
  i.push({
3082
3078
  id: E + 1,
3083
3079
  osc: {
3084
- detune: e[o + t.UNPACKED_OP_OSC_DETUNE],
3080
+ detune: e[o + t.UNPACKED_OP_DETUNE] - 7,
3081
+ // Convert 0-14 to -7 to +7
3085
3082
  freq: {
3086
3083
  coarse: e[o + t.UNPACKED_OP_FREQ_COARSE],
3087
3084
  fine: e[o + t.UNPACKED_OP_FREQ_FINE],
@@ -3168,7 +3165,7 @@ _(t, "PACKED_OP_EG_RATE_1", 0), _(t, "PACKED_OP_EG_RATE_2", 1), _(t, "PACKED_OP_
3168
3165
  _(t, "PACKED_OP_RATE_SCALING", 12), // RS and DET packed
3169
3166
  _(t, "PACKED_OP_MOD_SENS", 13), // AMS and KVS packed
3170
3167
  _(t, "PACKED_OP_OUTPUT_LEVEL", 14), _(t, "PACKED_OP_MODE_FREQ", 15), // Mode and Freq Coarse packed
3171
- _(t, "PACKED_OP_DETUNE_FINE", 16), // OSC Detune and Freq Fine packed
3168
+ _(t, "PACKED_OP_DETUNE_FINE", 16), // Freq Fine (full 7-bit value, range 0-99)
3172
3169
  // Packed voice offsets (after 6 operators = bytes 102+)
3173
3170
  _(t, "PACKED_PITCH_EG_RATE_1", 102), _(t, "PACKED_PITCH_EG_RATE_2", 103), _(t, "PACKED_PITCH_EG_RATE_3", 104), _(t, "PACKED_PITCH_EG_RATE_4", 105), _(t, "PACKED_PITCH_EG_LEVEL_1", 106), _(t, "PACKED_PITCH_EG_LEVEL_2", 107), _(t, "PACKED_PITCH_EG_LEVEL_3", 108), _(t, "PACKED_PITCH_EG_LEVEL_4", 109), _(t, "OFFSET_ALGORITHM", 110), _(t, "OFFSET_FEEDBACK", 111), // Also contains OSC Sync
3174
3171
  _(t, "OFFSET_LFO_SPEED", 112), _(t, "OFFSET_LFO_DELAY", 113), _(t, "OFFSET_LFO_PM_DEPTH", 114), _(t, "OFFSET_LFO_AM_DEPTH", 115), _(t, "OFFSET_LFO_SYNC_WAVE", 116), // LFO sync, wave, and PM sensitivity packed
@@ -3182,7 +3179,7 @@ _(t, "UNPACKED_SIZE", 169), // Total unpacked size (159 params + 10 name)
3182
3179
  _(t, "UNPACKED_OP_SIZE", 23), // 23 bytes per operator in unpacked format
3183
3180
  // Unpacked operator parameter offsets (within each 23-byte operator block)
3184
3181
  _(t, "UNPACKED_OP_EG_RATE_1", 0), _(t, "UNPACKED_OP_EG_RATE_2", 1), _(t, "UNPACKED_OP_EG_RATE_3", 2), _(t, "UNPACKED_OP_EG_RATE_4", 3), _(t, "UNPACKED_OP_EG_LEVEL_1", 4), _(t, "UNPACKED_OP_EG_LEVEL_2", 5), _(t, "UNPACKED_OP_EG_LEVEL_3", 6), _(t, "UNPACKED_OP_EG_LEVEL_4", 7), _(t, "UNPACKED_OP_BREAK_POINT", 8), _(t, "UNPACKED_OP_L_SCALE_DEPTH", 9), _(t, "UNPACKED_OP_R_SCALE_DEPTH", 10), _(t, "UNPACKED_OP_L_CURVE", 11), _(t, "UNPACKED_OP_R_CURVE", 12), _(t, "UNPACKED_OP_RATE_SCALING", 13), _(t, "UNPACKED_OP_DETUNE", 14), _(t, "UNPACKED_OP_AMP_MOD_SENS", 15), _(t, "UNPACKED_OP_OUTPUT_LEVEL", 16), _(t, "UNPACKED_OP_MODE", 17), // Mode (0=ratio, 1=fixed)
3185
- _(t, "UNPACKED_OP_KEY_VEL_SENS", 18), _(t, "UNPACKED_OP_FREQ_COARSE", 19), _(t, "UNPACKED_OP_OSC_DETUNE", 20), _(t, "UNPACKED_OP_FREQ_FINE", 21), // Unpacked pitch EG offsets (after 6 operators = index 138+)
3182
+ _(t, "UNPACKED_OP_KEY_VEL_SENS", 18), _(t, "UNPACKED_OP_FREQ_COARSE", 19), _(t, "UNPACKED_OP_FREQ_FINE", 21), // Unpacked pitch EG offsets (after 6 operators = index 138+)
3186
3183
  _(t, "UNPACKED_PITCH_EG_RATE_1", 138), _(t, "UNPACKED_PITCH_EG_RATE_2", 139), _(t, "UNPACKED_PITCH_EG_RATE_3", 140), _(t, "UNPACKED_PITCH_EG_RATE_4", 141), _(t, "UNPACKED_PITCH_EG_LEVEL_1", 142), _(t, "UNPACKED_PITCH_EG_LEVEL_2", 143), _(t, "UNPACKED_PITCH_EG_LEVEL_3", 144), _(t, "UNPACKED_PITCH_EG_LEVEL_4", 145), // Unpacked global parameters (after pitch EG = index 146+)
3187
3184
  _(t, "UNPACKED_ALGORITHM", 146), _(t, "UNPACKED_FEEDBACK", 147), _(t, "UNPACKED_OSC_SYNC", 148), _(t, "UNPACKED_LFO_SPEED", 149), _(t, "UNPACKED_LFO_DELAY", 150), _(t, "UNPACKED_LFO_PM_DEPTH", 151), _(t, "UNPACKED_LFO_AM_DEPTH", 152), _(t, "UNPACKED_LFO_KEY_SYNC", 153), _(t, "UNPACKED_LFO_WAVE", 154), _(t, "UNPACKED_LFO_PM_SENS", 155), _(t, "UNPACKED_AMP_MOD_SENS", 156), _(t, "UNPACKED_TRANSPOSE", 157), _(t, "UNPACKED_EG_BIAS_SENS", 158), _(t, "UNPACKED_NAME_START", 159), // VCED (single voice SysEx) format - for DX7 single patch dumps
3188
3185
  _(t, "VCED_SIZE", 163), // Total VCED sysex size (6 header + 155 data + 1 checksum + 1 end)
@@ -3618,8 +3615,8 @@ function Tt() {
3618
3615
  return typeof navigator < "u" && typeof navigator.requestMIDIAccess == "function";
3619
3616
  }
3620
3617
  export {
3621
- p as CONN,
3622
- p as CONNECTION_EVENTS,
3618
+ L as CONN,
3619
+ L as CONNECTION_EVENTS,
3623
3620
  P as CONTROLLER_EVENTS,
3624
3621
  P as CTRL,
3625
3622
  M as DX7Bank,
@@ -3633,7 +3630,7 @@ export {
3633
3630
  Q as MIDIConnection,
3634
3631
  y as MIDIConnectionError,
3635
3632
  J as MIDIController,
3636
- U as MIDIDeviceError,
3633
+ p as MIDIDeviceError,
3637
3634
  k as MIDIDeviceManager,
3638
3635
  g as MIDIError,
3639
3636
  m as MIDIValidationError,
@@ -1 +1 @@
1
- (function(l,I){typeof exports=="object"&&typeof module<"u"?I(exports):typeof define=="function"&&define.amd?define(["exports"],I):(l=typeof globalThis<"u"?globalThis:l||self,I(l.MIDIControls={}))})(this,(function(l){"use strict";var dt=Object.defineProperty;var Tt=(l,I,K)=>I in l?dt(l,I,{enumerable:!0,configurable:!0,writable:!0,value:K}):l[I]=K;var _=(l,I,K)=>Tt(l,typeof I!="symbol"?I+"":I,K);class I{constructor(e,i="[data-midi-cc]"){this.controller=e,this.selector=i,this.observer=null}bindAll(){document.querySelectorAll(this.selector==="[data-midi-cc]"?"[data-midi-cc], [data-midi-msb][data-midi-lsb]":this.selector).forEach(i=>{if(i.hasAttribute("data-midi-bound"))return;const n=this._parseAttributes(i);n&&(this.controller.bind(i,n),i.setAttribute("data-midi-bound","true"))})}enableAutoBinding(){if(this.observer)return;const e=this.selector==="[data-midi-cc]"?"[data-midi-cc], [data-midi-msb][data-midi-lsb]":this.selector;this.observer=new MutationObserver(i=>{i.forEach(n=>{n.addedNodes.forEach(s=>{if(s.nodeType===Node.ELEMENT_NODE){if(s.matches?.(e)){const r=this._parseAttributes(s);r&&!s.hasAttribute("data-midi-bound")&&(this.controller.bind(s,r),s.setAttribute("data-midi-bound","true"))}s.querySelectorAll&&s.querySelectorAll(e).forEach(E=>{if(!E.hasAttribute("data-midi-bound")){const o=this._parseAttributes(E);o&&(this.controller.bind(E,o),E.setAttribute("data-midi-bound","true"))}})}}),n.removedNodes.forEach(s=>{s.nodeType===Node.ELEMENT_NODE&&(s.hasAttribute?.("data-midi-bound")&&this.controller.unbind(s),s.querySelectorAll&&s.querySelectorAll("[data-midi-bound]").forEach(E=>{this.controller.unbind(E)}))})})}),this.observer.observe(document.body,{childList:!0,subtree:!0})}disableAutoBinding(){this.observer&&(this.observer.disconnect(),this.observer=null)}_parseAttributes(e){const i=parseInt(e.dataset.midiMsb,10),n=parseInt(e.dataset.midiLsb,10);if(!Number.isNaN(i)&&!Number.isNaN(n)&&i>=0&&i<=127&&n>=0&&n<=127){const r=parseInt(e.dataset.midiCc,10);return!Number.isNaN(r)&&r>=0&&r<=127&&console.warn(`Element has both 7-bit (data-midi-cc="${r}") and 14-bit (data-midi-msb="${i}" data-midi-lsb="${n}") CC attributes. 14-bit takes precedence.`,e),{msb:i,lsb:n,is14Bit:!0,channel:parseInt(e.dataset.midiChannel,10)||void 0,min:parseFloat(e.getAttribute("min"))||0,max:parseFloat(e.getAttribute("max"))||127,invert:e.dataset.midiInvert==="true",label:e.dataset.midiLabel}}const s=parseInt(e.dataset.midiCc,10);return!Number.isNaN(s)&&s>=0&&s<=127?{cc:s,channel:parseInt(e.dataset.midiChannel,10)||void 0,min:parseFloat(e.getAttribute("min"))||0,max:parseFloat(e.getAttribute("max"))||127,invert:e.dataset.midiInvert==="true",label:e.dataset.midiLabel}:((e.dataset.midiCc!==void 0||e.dataset.midiMsb!==void 0&&e.dataset.midiLsb!==void 0)&&console.warn("Invalid MIDI configuration on element:",e),null)}destroy(){this.disableAutoBinding()}}class K extends Error{constructor(e,i){super(e),this.name="MIDIError",this.code=i,Error.captureStackTrace&&Error.captureStackTrace(this,this.constructor)}}class F extends K{constructor(e,i){super(e,"MIDI_ACCESS_ERROR"),this.name="MIDIAccessError",this.reason=i}}class y extends K{constructor(e){super(e,"MIDI_CONNECTION_ERROR"),this.name="MIDIConnectionError"}}class R extends K{constructor(e,i,n){super(e,"MIDI_DEVICE_ERROR"),this.name="MIDIDeviceError",this.deviceType=i,this.deviceId=n}}class M extends K{constructor(e,i){super(e,"MIDI_VALIDATION_ERROR"),this.name="MIDIValidationError",this.validationType=i}}class H extends Error{constructor(e,i){super(e),this.name="DX7Error",this.code=i,Error.captureStackTrace&&Error.captureStackTrace(this,this.constructor)}}class g extends H{constructor(e,i,n){super(e,"DX7_PARSE_ERROR"),this.name="DX7ParseError",this.parseType=i,this.offset=n}}class d extends H{constructor(e,i,n){super(e,"DX7_VALIDATION_ERROR"),this.name="DX7ValidationError",this.validationType=i,this.value=n}}function O(c,e,i){return Math.max(e,Math.min(i,c))}function w(c,e,i,n=!1){const s=(c-e)/(i-e),E=(n?1-s:s)*127;return O(Math.round(E),0,127)}function J(c,e,i,n=!1){let s=O(c,0,127)/127;return n&&(s=1-s),e+s*(i-e)}function k(c){const e={C:0,"C#":1,DB:1,D:2,"D#":3,EB:3,E:4,F:5,"F#":6,GB:6,G:7,"G#":8,AB:8,A:9,"A#":10,BB:10,B:11},i=c.match(/^([A-G][#b]?)(-?\d+)$/i);if(!i)throw new M(`Invalid note name: ${c}`,"note",c);const[,n,s]=i,r=e[n.toUpperCase()];if(r===void 0)throw new M(`Invalid note: ${n}`,"note",n);const E=(parseInt(s,10)+1)*12+r;return O(E,0,127)}function j(c,e=!1){const s=e?["C","Db","D","Eb","E","F","Gb","G","Ab","A","Bb","B"]:["C","C#","D","D#","E","F","F#","G","G#","A","A#","B"],r=Math.floor(c/12)-1;return`${s[c%12]}${r}`}function X(c){const e=69+12*Math.log2(c/440);return O(Math.round(e),0,127)}function tt(c){return 440*2**((c-69)/12)}function et(c){return{0:"Bank Select",1:"Modulation",2:"Breath Controller",4:"Foot Controller",5:"Portamento Time",7:"Volume",8:"Balance",10:"Pan",11:"Expression",64:"Sustain Pedal",65:"Portamento",66:"Sostenuto",67:"Soft Pedal",68:"Legato",71:"Resonance",72:"Release Time",73:"Attack Time",74:"Cutoff",75:"Decay Time",76:"Vibrato Rate",77:"Vibrato Depth",78:"Vibrato Delay",84:"Portamento Control",91:"Reverb",92:"Tremolo",93:"Chorus",94:"Detune",95:"Phaser",120:"All Sound Off",121:"Reset All Controllers",123:"All Notes Off"}[c]||`CC ${c}`}function B(c){const e=O(Math.round(c),0,16383);return{msb:e>>7&127,lsb:e&127}}function Y(c,e){return O(c,0,127)<<7|O(e,0,127)}function x(c,e,i,n=!1){const s=(c-e)/(i-e),E=(n?1-s:s)*16383;return B(E)}function it(c,e,i,n,s=!1){let E=Y(c,e)/16383;return s&&(E=1-E),i+E*(n-i)}class v{constructor(){this.events=new Map}on(e,i){return this.events.has(e)||this.events.set(e,[]),this.events.get(e).push(i),()=>this.off(e,i)}once(e,i){const n=(...s)=>{i(...s),this.off(e,n)};this.on(e,n)}off(e,i){if(!this.events.has(e))return;const n=this.events.get(e),s=n.indexOf(i);s>-1&&n.splice(s,1),n.length===0&&this.events.delete(e)}emit(e,i){if(!this.events.has(e))return;[...this.events.get(e)].forEach(s=>{try{s(i)}catch(r){console.error(`Error in event handler for "${e}":`,r)}})}removeAllListeners(e){e?this.events.delete(e):this.events.clear()}}const p={DEVICE_CHANGE:"device-change",IN_DEV_CONNECTED:"in-dev-connected",IN_DEV_DISCONNECTED:"in-dev-disconnected",OUT_DEV_CONNECTED:"out-dev-connected",OUT_DEV_DISCONNECTED:"out-dev-disconnected"};class $ extends v{constructor(e={}){super(),this.options={sysex:!1,...e},this.midiAccess=null,this.output=null,this.input=null}async requestAccess(){if(!navigator.requestMIDIAccess)throw new F("Web MIDI API is not supported in this browser","unsupported");try{this.midiAccess=await navigator.requestMIDIAccess({sysex:this.options.sysex}),this.midiAccess.onstatechange=e=>{const i=e.port,n=e.port.state;this.emit(p.DEVICE_CHANGE,{port:i,state:n,type:i.type,device:{id:i.id,name:i.name,manufacturer:i.manufacturer||"Unknown"}}),n==="disconnected"?i.type==="input"?(this.emit(p.IN_DEV_DISCONNECTED,{device:i}),this.input&&this.input.id===i.id&&(this.input=null)):i.type==="output"&&(this.emit(p.OUT_DEV_DISCONNECTED,{device:i}),this.output&&this.output.id===i.id&&(this.output=null)):n==="connected"&&(i.type==="input"?this.emit(p.IN_DEV_CONNECTED,{device:i}):i.type==="output"&&this.emit(p.OUT_DEV_CONNECTED,{device:i}))}}catch(e){throw e.name==="SecurityError"?new F("MIDI access denied. SysEx requires user permission.","denied"):new F(`Failed to get MIDI access: ${e.message}`,"failed")}}async connect(e){if(!this.midiAccess)throw new y("MIDI access not initialized. Call requestAccess() first.");const i=Array.from(this.midiAccess.outputs.values());if(i.length===0)throw new R("No MIDI output devices available","output");if(e===void 0){this.output=i[0];return}if(typeof e=="number"){if(e<0||e>=i.length)throw new R(`Output index ${e} out of range (0-${i.length-1})`,"output",e);this.output=i[e];return}if(this.output=i.find(n=>n.name===e||n.id===e),!this.output){const n=i.map(s=>s.name).join(", ");throw new R(`MIDI output "${e}" not found. Available: ${n}`,"output",e)}}async connectInput(e,i){if(!this.midiAccess)throw new y("MIDI access not initialized. Call requestAccess() first.");if(typeof i!="function")throw new M("onMessage callback must be a function","callback");const n=Array.from(this.midiAccess.inputs.values());if(n.length===0)throw new R("No MIDI input devices available","input");if(this.input&&(this.input.onmidimessage=null),e===void 0)this.input=n[0];else if(typeof e=="number"){if(e<0||e>=n.length)throw new R(`Input index ${e} out of range (0-${n.length-1})`,"input",e);this.input=n[e]}else if(this.input=n.find(s=>s.name===e||s.id===e),!this.input){const s=n.map(r=>r.name).join(", ");throw new R(`MIDI input "${e}" not found. Available: ${s}`,"input",e)}this.input.onmidimessage=s=>{i(s)}}disconnectOutput(){this.output=null}disconnectInput(){this.input&&(this.input.onmidimessage=null,this.input=null)}disconnect(){this.disconnectOutput(),this.disconnectInput()}isConnected(){return this.output!==null}getCurrentOutput(){return this.output?{id:this.output.id,name:this.output.name,manufacturer:this.output.manufacturer||"Unknown"}:null}getCurrentInput(){return this.input?{id:this.input.id,name:this.input.name,manufacturer:this.input.manufacturer||"Unknown"}:null}getOutputs(){if(!this.midiAccess)return[];const e=[];return this.midiAccess.outputs.forEach(i=>{i.state==="connected"&&e.push({id:i.id,name:i.name,manufacturer:i.manufacturer||"Unknown"})}),e}getInputs(){if(!this.midiAccess)return[];const e=[];return this.midiAccess.inputs.forEach(i=>{i.state==="connected"&&e.push({id:i.id,name:i.name,manufacturer:i.manufacturer||"Unknown"})}),e}send(e,i=null){if(!this.output){console.warn("No MIDI output connected. Call connect() first.");return}try{const n=new Uint8Array(e);i===null?this.output.send(n):this.output.send(n,i)}catch(n){console.error("Failed to send MIDI message:",n)}}sendSysEx(e,i=!1){if(!this.options.sysex){console.warn("SysEx not enabled. Initialize with sysex: true");return}let n;i?n=[240,...e,247]:n=e,this.send(n)}}const A={READY:"ready",ERROR:"error",DESTROYED:"destroyed",DEV_OUT_CONNECTED:"dev-out-connected",DEV_OUT_DISCONNECTED:"dev-out-disconnected",DEV_IN_CONNECTED:"dev-in-connected",DEV_IN_DISCONNECTED:"dev-in-disconnected",CH_CC_SEND:"ch-cc-send",CH_CC_RECV:"ch-cc-recv",CH_NOTE_ON_SEND:"ch-note-on-send",CH_NOTE_ON_RECV:"ch-note-on-recv",CH_NOTE_OFF_SEND:"ch-note-off-send",CH_NOTE_OFF_RECV:"ch-note-off-recv",CH_PC_SEND:"ch-pc-send",CH_PC_RECV:"ch-pc-recv",CH_PITCH_BEND_SEND:"ch-pitch-bend-send",CH_PITCH_BEND_RECV:"ch-pitch-bend-recv",CH_MONO_PRESS_SEND:"ch-mono-press-send",CH_MONO_PRESS_RECV:"ch-mono-press-recv",CH_POLY_PRESS_SEND:"ch-poly-press-send",CH_POLY_PRESS_RECV:"ch-poly-press-recv",CH_ALL_SOUNDS_OFF_SEND:"ch-all-sounds-off-send",CH_RESET_CONTROLLERS_SEND:"ch-reset-controllers-send",CH_LOCAL_CONTROL_SEND:"ch-local-control-send",CH_ALL_NOTES_OFF_SEND:"ch-all-notes-off-send",CH_OMNI_OFF_SEND:"ch-omni-off-send",CH_OMNI_ON_SEND:"ch-omni-on-send",CH_MONO_ON_SEND:"ch-mono-on-send",CH_POLY_ON_SEND:"ch-poly-on-send",SYS_EX_SEND:"sys-ex-send",SYS_EX_RECV:"sys-ex-recv",SYS_CLOCK_RECV:"sys-clock-recv",SYS_START_RECV:"sys-start-recv",SYS_CONTINUE_RECV:"sys-continue-recv",SYS_STOP_RECV:"sys-stop-recv",SYS_MTC_RECV:"sys-mtc-recv",SYS_SONG_POS_RECV:"sys-song-pos-recv",SYS_SONG_SEL_RECV:"sys-song-sel-recv",SYS_TUNE_REQ_RECV:"sys-tune-req-recv",SYS_ACT_SENSE_RECV:"sys-act-sense-recv",SYS_RESET_RECV:"sys-reset-recv",MIDI_RAW:"midi-raw",PATCH_SAVED:"patch-saved",PATCH_LOADED:"patch-loaded",PATCH_DELETED:"patch-deleted"};class Z extends v{constructor(e={}){super(),this.options={inputChannel:1,outputChannel:1,autoConnect:!0,sysex:!1,...e},this.connection=null,this.bindings=new Map,this.state={controlChange:new Map,programChange:new Map,pitchBend:new Map,monoPressure:new Map,polyPressure:new Map},this.initialized=!1,this._initNamespaces()}async init(){if(this.initialized){console.warn("MIDI Controller already initialized");return}try{this.connection=new $({sysex:this.options.sysex}),await this.connection.requestAccess(),this.connection.on(p.DEVICE_CHANGE,async({state:e,type:i,device:n})=>{try{if(e==="connected")i==="output"?this.emit(A.DEV_OUT_CONNECTED,n):i==="input"&&this.emit(A.DEV_IN_CONNECTED,n);else if(e==="disconnected"){if(i==="output"&&n){const s=this.connection.getCurrentOutput();s&&s.id===n.id?await this._disconnectOutput():this.emit(A.DEV_OUT_DISCONNECTED,n)}if(i==="input"&&n){const s=this.connection.getCurrentInput();s&&s.id===n.id?await this._disconnectInput():this.emit(A.DEV_IN_DISCONNECTED,n)}}}catch(s){console.error("Error in device change handler:",s),this.emit(A.ERROR,s)}}),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(A.READY,this),this.options.onReady?.(this)}catch(e){throw this.emit(A.ERROR,e),this.options.onError?.(e),e}}_initNamespaces(){this.device={connect:this._connect.bind(this),disconnect:this._disconnect.bind(this),connectInput:this._connectInput.bind(this),disconnectInput:this._disconnectInput.bind(this),connectOutput:this._connectOutput.bind(this),disconnectOutput:this._disconnectOutput.bind(this),getCurrentOutput:this._getCurrentOutput.bind(this),getCurrentInput:this._getCurrentInput.bind(this),getOutputs:this._getOutputs.bind(this),getInputs:this._getInputs.bind(this)},this.channel={sendNoteOn:this._sendNoteOn.bind(this),sendNoteOff:this._sendNoteOff.bind(this),sendCC:this._sendCC.bind(this),getCC:this._getCC.bind(this),sendPC:this._sendPC.bind(this),getPC:this._getPC.bind(this),sendPitchBend:this._sendPitchBend.bind(this),getPitchBend:this._getPitchBend.bind(this),sendMonoPressure:this._sendMonoPressure.bind(this),getMonoPressure:this._getMonoPressure.bind(this),sendPolyPressure:this._sendPolyPressure.bind(this),getPolyPressure:this._getPolyPressure.bind(this),allSoundsOff:this._allSoundsOff.bind(this),resetControllers:this._resetControllers.bind(this),localControl:this._localControl.bind(this),allNotesOff:this._allNotesOff.bind(this),omniOff:this._omniOff.bind(this),omniOn:this._omniOn.bind(this),monoOn:this._monoOn.bind(this),polyOn:this._polyOn.bind(this)},this.system={sendEx:function(e,i=!1){return this._sendSysEx(e,i)}.bind(this),sendClock:this._sendClock.bind(this),start:this._sendStart.bind(this),continue:this._sendContinue.bind(this),stop:this._sendStop.bind(this),sendMTC:this._sendMTC.bind(this),sendSongPosition:this._sendSongPosition.bind(this),sendSongSelect:this._sendSongSelect.bind(this),sendTuneRequest:this._sendTuneRequest.bind(this),sendActiveSensing:this._sendActiveSensing.bind(this),sendSystemReset:this._sendSystemReset.bind(this)},this.patch={get:this._getPatch.bind(this),set:this._setPatch.bind(this),save:this._savePatch.bind(this),load:this._loadPatch.bind(this),delete:this._deletePatch.bind(this),list:this._listPatches.bind(this)}}bind(e,i,n={}){if(!e)return console.warn("Cannot bind: element is null or undefined"),()=>{};const s=this._createBinding(e,i,n);return this.bindings.set(e,s),this.initialized&&this.connection?.isConnected()&&s.handler({target:e}),()=>this.unbind(e)}_createBinding(e,i,n={}){const{min:s=parseFloat(e.getAttribute("min"))||0,max:r=parseFloat(e.getAttribute("max"))||127,channel:E,invert:o=!1,onInput:h=void 0}=i,{debounce:N=0}=n,u={...i,min:s,max:r,invert:o,onInput:h};if(E!==void 0&&(u.channel=E),i.is14Bit){const{msb:T,lsb:f}=i,U=V=>{const W=parseFloat(V.target.value);if(Number.isNaN(W))return;const{msb:Dt,lsb:Ot}=x(W,s,r,o),Q=E||this.options.outputChannel;this._sendCC(T,Dt,Q),this._sendCC(f,Ot,Q)};let L=null;const b=N>0?V=>{L&&clearTimeout(L),L=setTimeout(()=>{U(V),L=null},N)}:U;return e.addEventListener("input",b),e.addEventListener("change",b),{element:e,config:u,handler:U,destroy:()=>{L&&clearTimeout(L),e.removeEventListener("input",b),e.removeEventListener("change",b)}}}const{cc:a}=i,C=T=>{const f=parseFloat(T.target.value);if(Number.isNaN(f))return;const U=w(f,s,r,o),L=E===void 0?this.options.outputChannel:E;this._sendCC(a,U,L)};let S=null;const D=N>0?T=>{S&&clearTimeout(S),S=setTimeout(()=>{C(T),S=null},N)}:C;return e.addEventListener("input",D),e.addEventListener("change",D),{element:e,config:u,handler:C,destroy:()=>{S&&clearTimeout(S),e.removeEventListener("input",D),e.removeEventListener("change",D)}}}unbind(e){const i=this.bindings.get(e);i&&(i.destroy(),this.bindings.delete(e))}async destroy(){for(const e of this.bindings.values())e.destroy();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(A.DESTROYED),this.removeAllListeners()}async _connect(e){e?await this.connection.connect(e):this.options.output!==void 0?await this.connection.connect(this.options.output):this.options.autoConnect&&await this.connection.connect()}async _disconnect(){this.connection.disconnect()}async _connectInput(e){await this.connection.connectInput(e,i=>{this._handleMIDIMessage(i)}),this.emit(A.DEV_IN_CONNECTED,this.connection.getCurrentInput())}async _disconnectInput(){const e=this.connection.getCurrentInput();this.connection.disconnectInput(),this.emit(A.DEV_IN_DISCONNECTED,e)}async _connectOutput(e){await this.connection.connect(e),this.emit(A.DEV_OUT_CONNECTED,this.connection.getCurrentOutput())}async _disconnectOutput(){const e=this.connection.getCurrentOutput();this.connection.disconnectOutput(),this.emit(A.DEV_OUT_DISCONNECTED,e)}_getCurrentOutput(){return this.connection?.getCurrentOutput()||null}_getCurrentInput(){return this.connection?.getCurrentInput()||null}_getOutputs(){return this.connection?.getOutputs()||[]}_getInputs(){return this.connection?.getInputs()||[]}send(e){if(!this.initialized){console.warn("MIDI not initialized. Call init() first.");return}this.connection.send(e)}_sendNoteOn(e,i=64,n=this.options.outputChannel){if(!this.initialized)return;e=O(Math.round(e),0,127),i=O(Math.round(i),0,127),n=O(Math.round(n),1,16);const s=144+(n-1);this.connection.send([s,e,i]),this.emit(A.CH_NOTE_ON_SEND,{note:e,velocity:i,channel:n})}_sendNoteOff(e,i=this.options.outputChannel,n=0){if(!this.initialized)return;e=O(Math.round(e),0,127),n=O(Math.round(n),0,127),i=O(Math.round(i),1,16);const s=144+(i-1);this.connection.send([s,e,n]),this.emit(A.CH_NOTE_OFF_SEND,{note:e,channel:i,velocity:n})}_sendCC(e,i,n=this.options.outputChannel){if(!this.initialized){console.warn("MIDI not initialized. Call init() first.");return}e=O(Math.round(e),0,127),i=O(Math.round(i),0,127),n=O(Math.round(n),1,16);const s=176+(n-1);this.connection.send([s,e,i]);const r=`${n}:${e}`;this.state.controlChange.set(r,i),this.emit(A.CH_CC_SEND,{cc:e,value:i,channel:n})}_sendPC(e,i=this.options.outputChannel){if(!this.initialized)return;e=O(Math.round(e),0,127),i=O(Math.round(i),1,16);const n=192+(i-1);this.connection.send([n,e]),this.state.programChange.set(i.toString(),e),this.emit(A.CH_PC_SEND,{program:e,channel:i})}_getPC(e=this.options.inputChannel){return this.state.programChange.get(e.toString())}_getCC(e,i=this.options.inputChannel){const n=`${i}:${e}`;return this.state.controlChange.get(n)}_sendPitchBend(e,i=this.options.outputChannel){if(!this.initialized)return;e=O(Math.round(e),0,16383),i=O(Math.round(i),1,16);const n=224+(i-1),s=e&127,r=e>>7&127;this.connection.send([n,s,r]),this.state.pitchBend.set(i.toString(),e),this.emit(A.CH_PITCH_BEND_SEND,{value:e,channel:i})}_getPitchBend(e=this.options.inputChannel){return this.state.pitchBend.get(e.toString())}_sendMonoPressure(e,i=this.options.outputChannel){if(!this.initialized)return;e=O(Math.round(e),0,127),i=O(Math.round(i),1,16);const n=208+(i-1);this.connection.send([n,e]),this.state.monoPressure.set(i.toString(),e),this.emit(A.CH_MONO_PRESS_SEND,{pressure:e,channel:i})}_getMonoPressure(e=this.options.inputChannel){return this.state.monoPressure.get(e.toString())}_sendPolyPressure(e,i,n=this.options.outputChannel){if(!this.initialized)return;e=O(Math.round(e),0,127),i=O(Math.round(i),0,127),n=O(Math.round(n),1,16);const s=160+(n-1);this.connection.send([s,e,i]);const r=`${n}:${e}`;this.state.polyPressure.set(r,i),this.emit(A.CH_POLY_PRESS_SEND,{note:e,pressure:i,channel:n})}_getPolyPressure(e,i=this.options.inputChannel){const n=`${i}:${e}`;return this.state.polyPressure.get(n)}_allSoundsOff(e){if(!this.initialized){console.warn("MIDI not initialized. Call init() first.");return}if(e!==void 0){e=O(Math.round(e),1,16);const i=176+(e-1);this.connection.send([i,120,0]),this.emit(A.CH_ALL_SOUNDS_OFF_SEND,{channel:e})}else{for(let i=1;i<=16;i++){const n=176+(i-1);this.connection.send([n,120,0])}this.emit(A.CH_ALL_SOUNDS_OFF_SEND,{channel:null})}}_resetControllers(e){if(!this.initialized){console.warn("MIDI not initialized. Call init() first.");return}if(e!==void 0){e=O(Math.round(e),1,16);const i=176+(e-1);this.connection.send([i,121,0]),this.emit(A.CH_RESET_CONTROLLERS_SEND,{channel:e})}else{for(let i=1;i<=16;i++){const n=176+(i-1);this.connection.send([n,121,0])}this.emit(A.CH_RESET_CONTROLLERS_SEND,{channel:null})}}_localControl(e,i){if(!this.initialized){console.warn("MIDI not initialized. Call init() first.");return}const n=e?127:0;if(i!==void 0){i=O(Math.round(i),1,16);const s=176+(i-1);this.connection.send([s,122,n]),this.emit(A.CH_LOCAL_CONTROL_SEND,{enabled:e,channel:i})}else{for(let s=1;s<=16;s++){const r=176+(s-1);this.connection.send([r,122,n])}this.emit(A.CH_LOCAL_CONTROL_SEND,{enabled:e,channel:null})}}_allNotesOff(e){if(!this.initialized){console.warn("MIDI not initialized. Call init() first.");return}if(e!==void 0){e=O(Math.round(e),1,16);const i=176+(e-1);this.connection.send([i,123,0]),this.emit(A.CH_ALL_NOTES_OFF_SEND,{channel:e})}else{for(let i=1;i<=16;i++){const n=176+(i-1);this.connection.send([n,123,0])}this.emit(A.CH_ALL_NOTES_OFF_SEND,{channel:null})}}_omniOff(e){if(!this.initialized){console.warn("MIDI not initialized. Call init() first.");return}if(e!==void 0){e=O(Math.round(e),1,16);const i=176+(e-1);this.connection.send([i,124,0]),this.emit(A.CH_OMNI_OFF_SEND,{channel:e})}else{for(let i=1;i<=16;i++){const n=176+(i-1);this.connection.send([n,124,0])}this.emit(A.CH_OMNI_OFF_SEND,{channel:null})}}_omniOn(e){if(!this.initialized){console.warn("MIDI not initialized. Call init() first.");return}if(e!==void 0){e=O(Math.round(e),1,16);const i=176+(e-1);this.connection.send([i,125,0]),this.emit(A.CH_OMNI_ON_SEND,{channel:e})}else{for(let i=1;i<=16;i++){const n=176+(i-1);this.connection.send([n,125,0])}this.emit(A.CH_OMNI_ON_SEND,{channel:null})}}_monoOn(e=1,i){if(!this.initialized){console.warn("MIDI not initialized. Call init() first.");return}if(e=Math.max(0,Math.min(16,Math.round(e))),i!==void 0){i=O(Math.round(i),1,16);const n=176+(i-1);this.connection.send([n,126,e]),this.emit(A.CH_MONO_ON_SEND,{channels:e,channel:i})}else{for(let n=1;n<=16;n++){const s=176+(n-1);this.connection.send([s,126,e])}this.emit(A.CH_MONO_ON_SEND,{channels:e,channel:null})}}_polyOn(e){if(!this.initialized){console.warn("MIDI not initialized. Call init() first.");return}if(e!==void 0){e=O(Math.round(e),1,16);const i=176+(e-1);this.connection.send([i,127,0]),this.emit(A.CH_POLY_ON_SEND,{channel:e})}else{for(let i=1;i<=16;i++){const n=176+(i-1);this.connection.send([n,127,0])}this.emit(A.CH_POLY_ON_SEND,{channel:null})}}_sendSysEx(e,i=!1){if(!this.initialized){console.warn("MIDI not initialized. Call init() first.");return}if(!this.options.sysex){console.warn("SysEx not enabled. Initialize with sysex: true");return}this.connection.sendSysEx(e,i),this.emit(A.SYS_EX_SEND,{data:e,includeWrapper:i})}_sendClock(){if(!this.initialized){console.warn("MIDI not initialized. Call init() first.");return}this.connection.send([248])}_sendStart(){if(!this.initialized){console.warn("MIDI not initialized. Call init() first.");return}this.connection.send([250])}_sendContinue(){if(!this.initialized){console.warn("MIDI not initialized. Call init() first.");return}this.connection.send([251])}_sendStop(){if(!this.initialized){console.warn("MIDI not initialized. Call init() first.");return}this.connection.send([252])}_sendMTC(e){if(!this.initialized){console.warn("MIDI not initialized. Call init() first.");return}e=O(Math.round(e),0,127),this.connection.send([241,e])}_sendSongPosition(e){if(!this.initialized){console.warn("MIDI not initialized. Call init() first.");return}e=O(Math.round(e),0,16383);const i=e&127,n=e>>7&127;this.connection.send([242,i,n])}_sendSongSelect(e){if(!this.initialized){console.warn("MIDI not initialized. Call init() first.");return}e=O(Math.round(e),0,127),this.connection.send([243,e])}_sendTuneRequest(){if(!this.initialized){console.warn("MIDI not initialized. Call init() first.");return}this.connection.send([246])}_sendActiveSensing(){if(!this.initialized){console.warn("MIDI not initialized. Call init() first.");return}this.connection.send([254])}_sendSystemReset(){if(!this.initialized){console.warn("MIDI not initialized. Call init() first.");return}this.connection.send([255])}_handleMIDIMessage(e){const[i,n,s]=e.data,r=i&240,E=(i&15)+1;if(i===248){this.emit(A.SYS_CLOCK_RECV,{timestamp:e.midiwire});return}if(i===250){this.emit(A.SYS_START_RECV,{timestamp:e.midiwire});return}if(i===251){this.emit(A.SYS_CONTINUE_RECV,{timestamp:e.midiwire});return}if(i===252){this.emit(A.SYS_STOP_RECV,{timestamp:e.midiwire});return}if(i===254){this.emit(A.SYS_ACT_SENSE_RECV,{timestamp:e.midiwire});return}if(i===255){this.emit(A.SYS_RESET_RECV,{timestamp:e.midiwire});return}if(i===240){this.emit(A.SYS_EX_RECV,{data:Array.from(e.data),timestamp:e.midiwire});return}if(i===241){this.emit(A.SYS_MTC_RECV,{data:n,timestamp:e.midiwire});return}if(i===242){const o=n+(s<<7);this.emit(A.SYS_SONG_POS_RECV,{position:o,timestamp:e.midiwire});return}if(i===243){this.emit(A.SYS_SONG_SEL_RECV,{song:n,timestamp:e.midiwire});return}if(i===246){this.emit(A.SYS_TUNE_REQ_RECV,{timestamp:e.midiwire});return}if(i===247){this.emit(A.MIDI_RAW,{status:i,data:[n,s],channel:E,timestamp:e.midiwire});return}if(r===176){const o=`${E}:${n}`;this.state.controlChange.set(o,s),this.emit(A.CH_CC_RECV,{cc:n,value:s,channel:E});return}if(r===192){this.state.programChange.set(E.toString(),n),this.emit(A.CH_PC_RECV,{program:n,channel:E});return}if(r===224){const o=n+(s<<7);this.state.pitchBend.set(E.toString(),o),this.emit(A.CH_PITCH_BEND_RECV,{value:o,channel:E});return}if(r===208){this.state.monoPressure.set(E.toString(),n),this.emit(A.CH_MONO_PRESS_RECV,{pressure:n,channel:E});return}if(r===160){const o=`${E}:${n}`;this.state.polyPressure.set(o,s),this.emit(A.CH_POLY_PRESS_RECV,{note:n,pressure:s,channel:E});return}if(r===144&&s>0){this.emit(A.CH_NOTE_ON_RECV,{note:n,velocity:s,channel:E});return}if(r===128||r===144&&s===0){this.emit(A.CH_NOTE_OFF_RECV,{note:n,channel:E});return}this.emit(A.MIDI_RAW,{status:i,data:[n,s],channel:E,timestamp:e.midiwire})}_getPatch(e="Unnamed Patch"){const i={name:e,device:this._getCurrentOutput()?.name||null,timestamp:new Date().toISOString(),version:"1.0",channels:{},settings:{}};for(const[n,s]of this.state.controlChange.entries()){const[r,E]=n.split(":").map(Number);i.channels[r]||(i.channels[r]={ccs:{},notes:{}}),i.channels[r].ccs[E]=s}for(const[n,s]of this.state.programChange.entries()){const r=parseInt(n,10);i.channels[r]||(i.channels[r]={ccs:{},notes:{}}),i.channels[r].program=s}for(const[n,s]of this.state.pitchBend.entries()){const r=parseInt(n,10);i.channels[r]||(i.channels[r]={ccs:{},notes:{}}),i.channels[r].pitchBend=s}for(const[n,s]of this.state.monoPressure.entries()){const r=parseInt(n,10);i.channels[r]||(i.channels[r]={ccs:{},notes:{}}),i.channels[r].monoPressure=s}for(const[n,s]of this.state.polyPressure.entries()){const[r,E]=n.split(":").map(Number),o=parseInt(r,10);i.channels[o]||(i.channels[o]={ccs:{},notes:{}}),i.channels[o].polyPressure||(i.channels[o].polyPressure={}),i.channels[o].polyPressure[E]=s}for(const[n,s]of this.bindings.entries()){const{config:r}=s;if(r.cc){const E=`cc${r.cc}`;i.settings[E]={min:r.min,max:r.max,invert:r.invert||!1,is14Bit:r.is14Bit||!1,label:n.getAttribute?.("data-midi-label")||null,elementId:n.id||null}}}return i}async _setPatch(e){if(!e||!e.channels)throw new M("Invalid patch format","patch");const i=e.version||"1.0";i==="1.0"?await this._applyPatchV1(e):(console.warn(`Unknown patch version: ${i}. Attempting to apply as v1.0`),await this._applyPatchV1(e)),this.emit(A.PATCH_LOADED,{patch:e})}async _applyPatchV1(e){for(const[i,n]of Object.entries(e.channels)){const s=parseInt(i,10);if(n.ccs)for(const[r,E]of Object.entries(n.ccs)){const o=parseInt(r,10);this._sendCC(o,E,s)}if(n.program!==void 0&&this._sendPC(n.program,s),n.pitchBend!==void 0&&this._sendPitchBend(n.pitchBend,s),n.monoPressure!==void 0&&this._sendMonoPressure(n.monoPressure,s),n.polyPressure)for(const[r,E]of Object.entries(n.polyPressure)){const o=parseInt(r,10);this._sendPolyPressure(o,E,s)}if(n.notes)for(const[r,E]of Object.entries(n.notes)){const o=parseInt(r,10);E>0?this._sendNoteOn(o,E,s):this._sendNoteOff(o,s)}}if(e.settings)for(const[i,n]of Object.entries(e.settings))for(const[s,r]of this.bindings.entries())r.config.cc?.toString()===i.replace("cc","")&&(s.min!==void 0&&n.min!==void 0&&(s.min=String(n.min)),s.max!==void 0&&n.max!==void 0&&(s.max=String(n.max)));for(const[i,n]of this.bindings.entries()){const{config:s}=n;if(s.cc!==void 0){const r=s.channel||this.options.inputChannel,E=e.channels[r];if(E?.ccs){const o=E.ccs[s.cc];if(o!==void 0){const h=s.min!==void 0?s.min:parseFloat(i.getAttribute?.("min"))||0,N=s.max!==void 0?s.max:parseFloat(i.getAttribute?.("max"))||127,u=s.invert||!1;let a;u?a=N-o/127*(N-h):a=h+o/127*(N-h),s.onInput&&typeof s.onInput=="function"?s.onInput(a):(i.value=a,i.dispatchEvent(new Event("input",{bubbles:!0})))}}}}}_savePatch(e,i=null){const n=i||this._getPatch(e),s=`midiwire_patch_${e}`;try{return localStorage.setItem(s,JSON.stringify(n)),this.emit(A.PATCH_SAVED,{name:e,patch:n}),s}catch(r){throw console.error("Failed to save patch:",r),r}}_loadPatch(e){const i=`midiwire_patch_${e}`;try{const n=localStorage.getItem(i);if(!n)return null;const s=JSON.parse(n);return this.emit(A.PATCH_LOADED,{name:e,patch:s}),s}catch(n){return console.error("Failed to load patch:",n),null}}_deletePatch(e){const i=`midiwire_patch_${e}`;try{return localStorage.removeItem(i),this.emit(A.PATCH_DELETED,{name:e}),!0}catch(n){return console.error("Failed to delete patch:",n),!1}}_listPatches(){const e=[];try{for(let i=0;i<localStorage.length;i++){const n=localStorage.key(i);if(n?.startsWith("midiwire_patch_")){const s=n.replace("midiwire_patch_",""),r=this._loadPatch(s);r&&e.push({name:s,patch:r})}}}catch(i){console.error("Failed to list patches:",i)}return e.sort((i,n)=>i.name.localeCompare(n.name))}}class z{constructor(e={}){this.midi=e.midiController||null,this.onStatusUpdate=e.onStatusUpdate||(()=>{}),this.onConnectionUpdate=e.onConnectionUpdate||(()=>{}),this.channel=e.channel||1,this.currentOutput=null,this.currentInput=null,this.isConnecting=!1}async setupSelectors(e={},i={}){if(!this.midi)throw new Error("MIDI controller not initialized. Pass midiController in constructor options.");const{output:n,input:s,channel:r}=e,E=this._resolveSelector(n),o=this._resolveSelector(s),h=this._resolveSelector(r);if(this._setupDeviceChangeListeners({output:E,input:o},i.onDeviceListChange),E){await this._populateOutputDeviceList(E);const N=i.onConnect?async(a,C)=>i.onConnect({midi:a,device:C,type:"output"}):void 0,u=i.onDisconnect?async a=>i.onDisconnect({midi:a,type:"output"}):void 0;this._connectOutputDeviceSelection(E,N,u)}if(o){await this._populateInputDeviceList(o);const N=i.onConnect?async(a,C)=>i.onConnect({midi:a,device:C,type:"input"}):void 0,u=i.onDisconnect?async a=>i.onDisconnect({midi:a,type:"input"}):void 0;this._connectInputDeviceSelection(o,N,u)}return h&&this._connectChannelSelection(h,"output"),this.midi}updateStatus(e,i=""){this.onStatusUpdate(e,i)}updateConnectionStatus(){this.onConnectionUpdate(this.currentOutput,this.currentInput,this.midi)}_setupDeviceChangeListeners(e={},i){!this.midi||this._listenersInitialized||(this._listenersInitialized=!0,this.midi.on(A.DEV_OUT_CONNECTED,async n=>{this.updateStatus(`Output device connected: ${n?.name||"Unknown"}`,"connected"),e.output&&await this._populateOutputDeviceList(e.output),i&&i()}),this.midi.on(A.DEV_OUT_DISCONNECTED,async n=>{this.updateStatus(`Output device disconnected: ${n?.name||"Unknown"}`,"error"),this.currentOutput&&n?.name===this.currentOutput.name&&(this.currentOutput=null,this.updateConnectionStatus(),e.output&&(e.output.value="")),e.output&&await this._populateOutputDeviceList(e.output),i&&i()}),this.midi.on(A.DEV_IN_CONNECTED,async n=>{this.updateStatus(`Input device connected: ${n?.name||"Unknown"}`,"connected"),e.input&&await this._populateInputDeviceList(e.input),i&&i()}),this.midi.on(A.DEV_IN_DISCONNECTED,async n=>{this.updateStatus(`Input device disconnected: ${n?.name||"Unknown"}`,"error"),e.input&&(e.input.value="",await this._populateInputDeviceList(e.input)),i&&i()}))}_resolveSelector(e){if(typeof e=="string"){const i=document.querySelector(e);return i||console.warn(`MIDIDeviceManager: Selector "${e}" not found`),i}return e||null}_getOutputDevices(){return this.midi?this.midi.device.getOutputs():[]}_getInputDevices(){return this.midi?this.midi.device.getInputs():[]}_connectOutputDeviceSelection(e,i,n){!e||!this.midi||e.addEventListener("change",async s=>{if(this.isConnecting)return;this.isConnecting=!0;const r=s.target.value;if(!r){this.currentOutput&&this.midi&&(await this.midi.device.disconnectOutput(),this.currentOutput=null,this.updateStatus("Output device disconnected",""),this.updateConnectionStatus()),this.isConnecting=!1,n&&await n(this.midi);return}try{if(await this.midi.device.connectOutput(parseInt(r,10)),this.currentOutput=this.midi.device.getCurrentOutput(),this.currentOutput){const o=this.midi.device.getOutputs().findIndex(h=>h.id===this.currentOutput.id);o!==-1&&(e.value=o.toString())}this.updateConnectionStatus(),i&&await i(this.midi,this.currentOutput)}catch(E){this.updateStatus(`Output connection failed: ${E.message}`,"error")}finally{this.isConnecting=!1}})}_connectInputDeviceSelection(e,i,n){!e||!this.midi||e.addEventListener("change",async s=>{const r=s.target.value;if(!r){this.midi&&(await this.midi.device.disconnectInput(),this.updateStatus("Input device disconnected",""),this.updateConnectionStatus()),n&&await n(this.midi);return}if(!this.isConnecting){this.isConnecting=!0;try{await this.midi.device.connectInput(parseInt(r,10));const E=this.midi.device.getCurrentInput();this.updateConnectionStatus(),i&&await i(this.midi,E)}catch(E){this.updateStatus(`Input connection failed: ${E.message}`,"error")}finally{this.isConnecting=!1}}})}_populateDeviceList(e,i,n,s,r){if(i.length>0){if(e.innerHTML='<option value="">Select a device</option>'+i.map((E,o)=>`<option value="${o}">${E.name}</option>`).join(""),n){const E=i.findIndex(o=>o.name===n.name);E!==-1?e.value=E.toString():(e.value="",r&&(this.currentOutput=null,this.updateConnectionStatus()))}else e.value="";e.disabled=!1,r&&!this.currentOutput&&this.updateStatus("Select a device")}else e.innerHTML='<option value="">No devices connected</option>',e.disabled=!0,r&&this.updateStatus("No devices connected","error");s&&s()}async _populateOutputDeviceList(e,i){if(!e||!this.midi)return;const n=this._getOutputDevices();this._populateDeviceList(e,n,this.currentOutput,i,!0)}async _populateInputDeviceList(e,i){if(!e||!this.midi)return;const n=this._getInputDevices(),s=this.midi.device.getCurrentInput();this._populateDeviceList(e,n,s,i,!1)}_connectChannelSelection(e,i){if(!e||!this.midi)return;const n=i==="input"?"inputChannel":"outputChannel";e.addEventListener("change",s=>{this.midi&&(this.midi.options[n]=parseInt(s.target.value,10),this.updateConnectionStatus())})}}const t=class t{constructor(e,i=0){if(e.length!==t.PACKED_SIZE)throw new d(`Invalid voice data length: expected ${t.PACKED_SIZE} bytes, got ${e.length}`,"length",e.length);this.index=i,this.data=new Uint8Array(e),this.name=this._extractName(),this._unpackedCache=null}_extractName(){const e=this.data.subarray(t.PACKED_NAME_START,t.PACKED_NAME_START+t.NAME_LENGTH);return Array.from(e).map(n=>{let s=n&t.MASK_7BIT;return s===t.CHAR_YEN&&(s=t.CHAR_REPLACEMENT_Y),s===t.CHAR_ARROW_RIGHT&&(s=t.CHAR_REPLACEMENT_GT),s===t.CHAR_ARROW_LEFT&&(s=t.CHAR_REPLACEMENT_LT),(s<t.CHAR_MIN_PRINTABLE||s>t.CHAR_MAX_PRINTABLE)&&(s=t.CHAR_SPACE),String.fromCharCode(s)}).join("").trim()}getParameter(e){if(e<0||e>=t.PACKED_SIZE)throw new d(`Parameter offset out of range: ${e} (must be 0-${t.PACKED_SIZE-1})`,"offset",e);return this.data[e]&t.MASK_7BIT}getUnpackedParameter(e){if(e<0||e>=t.UNPACKED_SIZE)throw new d(`Unpacked parameter offset out of range: ${e} (must be 0-${t.UNPACKED_SIZE-1})`,"offset",e);return this._unpackedCache||(this._unpackedCache=this.unpack()),this._unpackedCache[e]&t.MASK_7BIT}setParameter(e,i){if(e<0||e>=t.PACKED_SIZE)throw new d(`Parameter offset out of range: ${e} (must be 0-${t.PACKED_SIZE-1})`,"offset",e);this.data[e]=i&t.MASK_7BIT,this._unpackedCache=null,e>=t.PACKED_NAME_START&&e<t.PACKED_NAME_START+t.NAME_LENGTH&&(this.name=this._extractName())}unpack(){const e=this.data,i=new Uint8Array(t.UNPACKED_SIZE);return this._unpackOperators(e,i),this._unpackPitchEG(e,i),this._unpackGlobalParams(e,i),this._unpackName(e,i),i}_unpackOperators(e,i){for(let n=0;n<t.NUM_OPERATORS;n++){const s=(t.NUM_OPERATORS-1-n)*t.PACKED_OP_SIZE,r=n*t.UNPACKED_OP_SIZE;this._unpackOperator(e,i,s,r)}}_unpackOperator(e,i,n,s){this._unpackOperatorEG(e,i,n,s),this._unpackOperatorScaling(e,i,n,s),this._unpackOperatorPackedParams(e,i,n,s),this._unpackOperatorFrequency(e,i,n,s)}_unpackOperatorEG(e,i,n,s){i[s+t.UNPACKED_OP_EG_RATE_1]=e[n+t.PACKED_OP_EG_RATE_1]&t.MASK_7BIT,i[s+t.UNPACKED_OP_EG_RATE_2]=e[n+t.PACKED_OP_EG_RATE_2]&t.MASK_7BIT,i[s+t.UNPACKED_OP_EG_RATE_3]=e[n+t.PACKED_OP_EG_RATE_3]&t.MASK_7BIT,i[s+t.UNPACKED_OP_EG_RATE_4]=e[n+t.PACKED_OP_EG_RATE_4]&t.MASK_7BIT,i[s+t.UNPACKED_OP_EG_LEVEL_1]=e[n+t.PACKED_OP_EG_LEVEL_1]&t.MASK_7BIT,i[s+t.UNPACKED_OP_EG_LEVEL_2]=e[n+t.PACKED_OP_EG_LEVEL_2]&t.MASK_7BIT,i[s+t.UNPACKED_OP_EG_LEVEL_3]=e[n+t.PACKED_OP_EG_LEVEL_3]&t.MASK_7BIT,i[s+t.UNPACKED_OP_EG_LEVEL_4]=e[n+t.PACKED_OP_EG_LEVEL_4]&t.MASK_7BIT}_unpackOperatorScaling(e,i,n,s){i[s+t.UNPACKED_OP_BREAK_POINT]=e[n+t.PACKED_OP_BREAK_POINT]&t.MASK_7BIT,i[s+t.UNPACKED_OP_L_SCALE_DEPTH]=e[n+t.PACKED_OP_L_SCALE_DEPTH]&t.MASK_7BIT,i[s+t.UNPACKED_OP_R_SCALE_DEPTH]=e[n+t.PACKED_OP_R_SCALE_DEPTH]&t.MASK_7BIT}_unpackOperatorPackedParams(e,i,n,s){const r=e[n+t.PACKED_OP_CURVES]&t.MASK_7BIT;i[s+t.UNPACKED_OP_L_CURVE]=r&t.MASK_2BIT,i[s+t.UNPACKED_OP_R_CURVE]=r>>2&t.MASK_2BIT;const E=e[n+t.PACKED_OP_RATE_SCALING]&t.MASK_7BIT;i[s+t.UNPACKED_OP_RATE_SCALING]=E&t.MASK_3BIT,i[s+t.UNPACKED_OP_DETUNE]=E>>3&t.MASK_4BIT;const o=e[n+t.PACKED_OP_MOD_SENS]&t.MASK_7BIT;i[s+t.UNPACKED_OP_AMP_MOD_SENS]=o&t.MASK_2BIT,i[s+t.UNPACKED_OP_KEY_VEL_SENS]=o>>2&t.MASK_3BIT,i[s+t.UNPACKED_OP_OUTPUT_LEVEL]=e[n+t.PACKED_OP_OUTPUT_LEVEL]&t.MASK_7BIT}_unpackOperatorFrequency(e,i,n,s){const r=e[n+t.PACKED_OP_MODE_FREQ]&t.MASK_7BIT;i[s+t.UNPACKED_OP_MODE]=r&t.MASK_1BIT,i[s+t.UNPACKED_OP_FREQ_COARSE]=r>>1&t.MASK_5BIT;const E=e[n+t.PACKED_OP_DETUNE_FINE]&t.MASK_7BIT;i[s+t.UNPACKED_OP_OSC_DETUNE]=E&t.MASK_3BIT,i[s+t.UNPACKED_OP_FREQ_FINE]=E>>3&t.MASK_4BIT}_unpackPitchEG(e,i){i[t.UNPACKED_PITCH_EG_RATE_1]=e[t.PACKED_PITCH_EG_RATE_1]&t.MASK_7BIT,i[t.UNPACKED_PITCH_EG_RATE_2]=e[t.PACKED_PITCH_EG_RATE_2]&t.MASK_7BIT,i[t.UNPACKED_PITCH_EG_RATE_3]=e[t.PACKED_PITCH_EG_RATE_3]&t.MASK_7BIT,i[t.UNPACKED_PITCH_EG_RATE_4]=e[t.PACKED_PITCH_EG_RATE_4]&t.MASK_7BIT,i[t.UNPACKED_PITCH_EG_LEVEL_1]=e[t.PACKED_PITCH_EG_LEVEL_1]&t.MASK_7BIT,i[t.UNPACKED_PITCH_EG_LEVEL_2]=e[t.PACKED_PITCH_EG_LEVEL_2]&t.MASK_7BIT,i[t.UNPACKED_PITCH_EG_LEVEL_3]=e[t.PACKED_PITCH_EG_LEVEL_3]&t.MASK_7BIT,i[t.UNPACKED_PITCH_EG_LEVEL_4]=e[t.PACKED_PITCH_EG_LEVEL_4]&t.MASK_7BIT}_unpackGlobalParams(e,i){i[t.UNPACKED_ALGORITHM]=e[t.OFFSET_ALGORITHM]&t.MASK_5BIT;const n=e[t.OFFSET_FEEDBACK]&t.MASK_7BIT;i[t.UNPACKED_FEEDBACK]=n&t.MASK_3BIT,i[t.UNPACKED_OSC_SYNC]=n>>3&t.MASK_1BIT,i[t.UNPACKED_LFO_SPEED]=e[t.OFFSET_LFO_SPEED]&t.MASK_7BIT,i[t.UNPACKED_LFO_DELAY]=e[t.OFFSET_LFO_DELAY]&t.MASK_7BIT,i[t.UNPACKED_LFO_PM_DEPTH]=e[t.OFFSET_LFO_PM_DEPTH]&t.MASK_7BIT,i[t.UNPACKED_LFO_AM_DEPTH]=e[t.OFFSET_LFO_AM_DEPTH]&t.MASK_7BIT;const s=e[t.OFFSET_LFO_SYNC_WAVE]&t.MASK_7BIT;i[t.UNPACKED_LFO_KEY_SYNC]=s&t.MASK_1BIT,i[t.UNPACKED_LFO_WAVE]=s>>1&t.MASK_3BIT,i[t.UNPACKED_LFO_PM_SENS]=s>>4&t.MASK_3BIT,i[t.UNPACKED_AMP_MOD_SENS]=e[t.OFFSET_AMP_MOD_SENS]&t.MASK_7BIT,i[t.UNPACKED_TRANSPOSE]=e[t.OFFSET_TRANSPOSE]&t.MASK_7BIT,i[t.UNPACKED_EG_BIAS_SENS]=e[t.OFFSET_EG_BIAS_SENS]&t.MASK_7BIT}_unpackName(e,i){for(let n=0;n<t.NAME_LENGTH;n++)i[t.UNPACKED_NAME_START+n]=e[t.PACKED_NAME_START+n]&t.MASK_7BIT}static pack(e){if(e.length!==t.UNPACKED_SIZE)throw new d(`Invalid unpacked data length: expected ${t.UNPACKED_SIZE} bytes, got ${e.length}`,"length",e.length);const i=new Uint8Array(t.PACKED_SIZE);return t._packOperators(e,i),t._packPitchEG(e,i),t._packGlobalParams(e,i),t._packName(e,i),i}static _packOperators(e,i){for(let n=0;n<t.NUM_OPERATORS;n++){const s=n*t.UNPACKED_OP_SIZE,r=(t.NUM_OPERATORS-1-n)*t.PACKED_OP_SIZE;t._packOperator(e,i,s,r)}}static _packOperator(e,i,n,s){t._packOperatorEG(e,i,n,s),t._packOperatorScaling(e,i,n,s),t._packOperatorPackedParams(e,i,n,s),t._packOperatorFrequency(e,i,n,s)}static _packOperatorEG(e,i,n,s){i[s+t.PACKED_OP_EG_RATE_1]=e[n+t.UNPACKED_OP_EG_RATE_1],i[s+t.PACKED_OP_EG_RATE_2]=e[n+t.UNPACKED_OP_EG_RATE_2],i[s+t.PACKED_OP_EG_RATE_3]=e[n+t.UNPACKED_OP_EG_RATE_3],i[s+t.PACKED_OP_EG_RATE_4]=e[n+t.UNPACKED_OP_EG_RATE_4],i[s+t.PACKED_OP_EG_LEVEL_1]=e[n+t.UNPACKED_OP_EG_LEVEL_1],i[s+t.PACKED_OP_EG_LEVEL_2]=e[n+t.UNPACKED_OP_EG_LEVEL_2],i[s+t.PACKED_OP_EG_LEVEL_3]=e[n+t.UNPACKED_OP_EG_LEVEL_3],i[s+t.PACKED_OP_EG_LEVEL_4]=e[n+t.UNPACKED_OP_EG_LEVEL_4]}static _packOperatorScaling(e,i,n,s){i[s+t.PACKED_OP_BREAK_POINT]=e[n+t.UNPACKED_OP_BREAK_POINT],i[s+t.PACKED_OP_L_SCALE_DEPTH]=e[n+t.UNPACKED_OP_L_SCALE_DEPTH],i[s+t.PACKED_OP_R_SCALE_DEPTH]=e[n+t.UNPACKED_OP_R_SCALE_DEPTH]}static _packOperatorPackedParams(e,i,n,s){const r=e[n+t.UNPACKED_OP_L_CURVE]&t.MASK_2BIT,E=e[n+t.UNPACKED_OP_R_CURVE]&t.MASK_2BIT;i[s+t.PACKED_OP_CURVES]=r|E<<2;const o=e[n+t.UNPACKED_OP_RATE_SCALING]&t.MASK_3BIT,h=e[n+t.UNPACKED_OP_DETUNE]&t.MASK_4BIT;i[s+t.PACKED_OP_RATE_SCALING]=o|h<<3;const N=e[n+t.UNPACKED_OP_AMP_MOD_SENS]&t.MASK_2BIT,u=e[n+t.UNPACKED_OP_KEY_VEL_SENS]&t.MASK_3BIT;i[s+t.PACKED_OP_MOD_SENS]=N|u<<2,i[s+t.PACKED_OP_OUTPUT_LEVEL]=e[n+t.UNPACKED_OP_OUTPUT_LEVEL]}static _packOperatorFrequency(e,i,n,s){const r=e[n+t.UNPACKED_OP_MODE]&t.MASK_1BIT,E=e[n+t.UNPACKED_OP_FREQ_COARSE]&t.MASK_5BIT;i[s+t.PACKED_OP_MODE_FREQ]=r|E<<1;const o=e[n+t.UNPACKED_OP_OSC_DETUNE]&t.MASK_3BIT,h=e[n+t.UNPACKED_OP_FREQ_FINE]&t.MASK_4BIT;i[s+t.PACKED_OP_DETUNE_FINE]=o|h<<3}static _packPitchEG(e,i){i[t.PACKED_PITCH_EG_RATE_1]=e[t.UNPACKED_PITCH_EG_RATE_1],i[t.PACKED_PITCH_EG_RATE_2]=e[t.UNPACKED_PITCH_EG_RATE_2],i[t.PACKED_PITCH_EG_RATE_3]=e[t.UNPACKED_PITCH_EG_RATE_3],i[t.PACKED_PITCH_EG_RATE_4]=e[t.UNPACKED_PITCH_EG_RATE_4],i[t.PACKED_PITCH_EG_LEVEL_1]=e[t.UNPACKED_PITCH_EG_LEVEL_1],i[t.PACKED_PITCH_EG_LEVEL_2]=e[t.UNPACKED_PITCH_EG_LEVEL_2],i[t.PACKED_PITCH_EG_LEVEL_3]=e[t.UNPACKED_PITCH_EG_LEVEL_3],i[t.PACKED_PITCH_EG_LEVEL_4]=e[t.UNPACKED_PITCH_EG_LEVEL_4]}static _packGlobalParams(e,i){i[t.OFFSET_ALGORITHM]=e[t.UNPACKED_ALGORITHM];const n=e[t.UNPACKED_FEEDBACK]&t.MASK_3BIT,s=e[t.UNPACKED_OSC_SYNC]&t.MASK_1BIT;i[t.OFFSET_FEEDBACK]=n|s<<3,i[t.OFFSET_LFO_SPEED]=e[t.UNPACKED_LFO_SPEED],i[t.OFFSET_LFO_DELAY]=e[t.UNPACKED_LFO_DELAY],i[t.OFFSET_LFO_PM_DEPTH]=e[t.UNPACKED_LFO_PM_DEPTH],i[t.OFFSET_LFO_AM_DEPTH]=e[t.UNPACKED_LFO_AM_DEPTH];const r=e[t.UNPACKED_LFO_KEY_SYNC]&t.MASK_1BIT,E=e[t.UNPACKED_LFO_WAVE]&t.MASK_3BIT,o=e[t.UNPACKED_LFO_PM_SENS]&t.MASK_3BIT;i[t.OFFSET_LFO_SYNC_WAVE]=r|E<<1|o<<4,i[t.OFFSET_AMP_MOD_SENS]=e[t.UNPACKED_AMP_MOD_SENS],i[t.OFFSET_TRANSPOSE]=e[t.UNPACKED_TRANSPOSE],i[t.OFFSET_EG_BIAS_SENS]=e[t.UNPACKED_EG_BIAS_SENS]}static _packName(e,i){for(let n=0;n<t.NAME_LENGTH;n++)i[t.PACKED_NAME_START+n]=e[t.UNPACKED_NAME_START+n]}static createDefault(e=0){const i=new Uint8Array(t.UNPACKED_SIZE);for(let r=0;r<t.NUM_OPERATORS;r++){const E=r*t.UNPACKED_OP_SIZE;i[E+t.UNPACKED_OP_EG_RATE_1]=t.DEFAULT_EG_RATE,i[E+t.UNPACKED_OP_EG_RATE_2]=t.DEFAULT_EG_RATE,i[E+t.UNPACKED_OP_EG_RATE_3]=t.DEFAULT_EG_RATE,i[E+t.UNPACKED_OP_EG_RATE_4]=t.DEFAULT_EG_RATE,i[E+t.UNPACKED_OP_EG_LEVEL_1]=t.DEFAULT_EG_LEVEL_MAX,i[E+t.UNPACKED_OP_EG_LEVEL_2]=t.DEFAULT_EG_LEVEL_MAX,i[E+t.UNPACKED_OP_EG_LEVEL_3]=t.DEFAULT_EG_LEVEL_MAX,i[E+t.UNPACKED_OP_EG_LEVEL_4]=t.DEFAULT_EG_LEVEL_MIN,i[E+t.UNPACKED_OP_BREAK_POINT]=t.DEFAULT_BREAK_POINT,i[E+t.UNPACKED_OP_L_SCALE_DEPTH]=0,i[E+t.UNPACKED_OP_R_SCALE_DEPTH]=0,i[E+t.UNPACKED_OP_L_CURVE]=0,i[E+t.UNPACKED_OP_R_CURVE]=0,i[E+t.UNPACKED_OP_RATE_SCALING]=0,i[E+t.UNPACKED_OP_DETUNE]=t.DEFAULT_DETUNE,i[E+t.UNPACKED_OP_AMP_MOD_SENS]=0,i[E+t.UNPACKED_OP_KEY_VEL_SENS]=0,i[E+t.UNPACKED_OP_OUTPUT_LEVEL]=t.DEFAULT_OUTPUT_LEVEL,i[E+t.UNPACKED_OP_MODE]=0,i[E+t.UNPACKED_OP_FREQ_COARSE]=t.DEFAULT_FREQ_COARSE,i[E+t.UNPACKED_OP_OSC_DETUNE]=0,i[E+t.UNPACKED_OP_FREQ_FINE]=0}i[t.UNPACKED_PITCH_EG_RATE_1]=t.DEFAULT_EG_RATE,i[t.UNPACKED_PITCH_EG_RATE_2]=t.DEFAULT_EG_RATE,i[t.UNPACKED_PITCH_EG_RATE_3]=t.DEFAULT_EG_RATE,i[t.UNPACKED_PITCH_EG_RATE_4]=t.DEFAULT_EG_RATE,i[t.UNPACKED_PITCH_EG_LEVEL_1]=t.DEFAULT_PITCH_EG_LEVEL,i[t.UNPACKED_PITCH_EG_LEVEL_2]=t.DEFAULT_PITCH_EG_LEVEL,i[t.UNPACKED_PITCH_EG_LEVEL_3]=t.DEFAULT_PITCH_EG_LEVEL,i[t.UNPACKED_PITCH_EG_LEVEL_4]=t.DEFAULT_PITCH_EG_LEVEL,i[t.UNPACKED_ALGORITHM]=t.DEFAULT_ALGORITHM,i[t.UNPACKED_FEEDBACK]=t.DEFAULT_FEEDBACK,i[t.UNPACKED_OSC_SYNC]=t.DEFAULT_OSC_SYNC,i[t.UNPACKED_LFO_SPEED]=t.DEFAULT_LFO_SPEED,i[t.UNPACKED_LFO_DELAY]=0,i[t.UNPACKED_LFO_PM_DEPTH]=0,i[t.UNPACKED_LFO_AM_DEPTH]=0,i[t.UNPACKED_LFO_KEY_SYNC]=t.DEFAULT_LFO_KEY_SYNC,i[t.UNPACKED_LFO_WAVE]=0,i[t.UNPACKED_LFO_PM_SENS]=t.DEFAULT_LFO_PM_SENS,i[t.UNPACKED_AMP_MOD_SENS]=0,i[t.UNPACKED_TRANSPOSE]=t.TRANSPOSE_CENTER,i[t.UNPACKED_EG_BIAS_SENS]=0;const n="Init Voice";for(let r=0;r<t.NAME_LENGTH;r++)i[t.UNPACKED_NAME_START+r]=r<n.length?n.charCodeAt(r):t.CHAR_SPACE;const s=t.pack(i);return new t(s,e)}static fromUnpacked(e,i=0){const n=t.pack(e);return new t(n,i)}static async fromFile(e){return new Promise((i,n)=>{const s=new FileReader;s.onload=r=>{try{const E=new Uint8Array(r.target.result);if(E[0]!==t.VCED_SYSEX_START||E[1]!==t.VCED_YAMAHA_ID||E[2]!==t.VCED_SUB_STATUS||E[3]!==t.VCED_FORMAT_SINGLE||E[4]!==t.VCED_BYTE_COUNT_MSB||E[5]!==t.VCED_BYTE_COUNT_LSB)throw new g("Invalid VCED header","header",0);const o=E.subarray(t.VCED_HEADER_SIZE,t.VCED_HEADER_SIZE+t.VCED_DATA_SIZE),h=E[t.VCED_HEADER_SIZE+t.VCED_DATA_SIZE],N=G._calculateChecksum(o,t.VCED_DATA_SIZE);h!==N&&console.warn(`DX7 VCED checksum mismatch (expected ${N.toString(16)}, got ${h.toString(16)}). This is common with vintage SysEx files.`);const u=new Uint8Array(t.UNPACKED_SIZE);let a=0;for(let S=0;S<t.NUM_OPERATORS;S++){const D=(t.NUM_OPERATORS-1-S)*t.UNPACKED_OP_SIZE;u[D+t.UNPACKED_OP_EG_RATE_1]=o[a++],u[D+t.UNPACKED_OP_EG_RATE_2]=o[a++],u[D+t.UNPACKED_OP_EG_RATE_3]=o[a++],u[D+t.UNPACKED_OP_EG_RATE_4]=o[a++],u[D+t.UNPACKED_OP_EG_LEVEL_1]=o[a++],u[D+t.UNPACKED_OP_EG_LEVEL_2]=o[a++],u[D+t.UNPACKED_OP_EG_LEVEL_3]=o[a++],u[D+t.UNPACKED_OP_EG_LEVEL_4]=o[a++],u[D+t.UNPACKED_OP_BREAK_POINT]=o[a++],u[D+t.UNPACKED_OP_L_SCALE_DEPTH]=o[a++],u[D+t.UNPACKED_OP_R_SCALE_DEPTH]=o[a++],u[D+t.UNPACKED_OP_L_CURVE]=o[a++],u[D+t.UNPACKED_OP_R_CURVE]=o[a++],u[D+t.UNPACKED_OP_RATE_SCALING]=o[a++],u[D+t.UNPACKED_OP_DETUNE]=o[a++];const T=o[a++];u[D+t.UNPACKED_OP_AMP_MOD_SENS]=T&t.MASK_2BIT,u[D+t.UNPACKED_OP_KEY_VEL_SENS]=T>>2&t.MASK_3BIT,u[D+t.UNPACKED_OP_OUTPUT_LEVEL]=o[a++],u[D+t.UNPACKED_OP_MODE]=o[a++],u[D+t.UNPACKED_OP_FREQ_COARSE]=o[a++],u[D+t.UNPACKED_OP_FREQ_FINE]=o[a++],u[D+t.UNPACKED_OP_OSC_DETUNE]=o[a++]}u[t.UNPACKED_PITCH_EG_RATE_1]=o[a++],u[t.UNPACKED_PITCH_EG_RATE_2]=o[a++],u[t.UNPACKED_PITCH_EG_RATE_3]=o[a++],u[t.UNPACKED_PITCH_EG_RATE_4]=o[a++],u[t.UNPACKED_PITCH_EG_LEVEL_1]=o[a++],u[t.UNPACKED_PITCH_EG_LEVEL_2]=o[a++],u[t.UNPACKED_PITCH_EG_LEVEL_3]=o[a++],u[t.UNPACKED_PITCH_EG_LEVEL_4]=o[a++],u[t.UNPACKED_ALGORITHM]=o[a++],u[t.UNPACKED_FEEDBACK]=o[a++],u[t.UNPACKED_OSC_SYNC]=o[a++],u[t.UNPACKED_LFO_SPEED]=o[a++],u[t.UNPACKED_LFO_DELAY]=o[a++],u[t.UNPACKED_LFO_PM_DEPTH]=o[a++],u[t.UNPACKED_LFO_AM_DEPTH]=o[a++],u[t.UNPACKED_LFO_KEY_SYNC]=o[a++],u[t.UNPACKED_LFO_WAVE]=o[a++],u[t.UNPACKED_LFO_PM_SENS]=o[a++],u[t.UNPACKED_TRANSPOSE]=o[a++];for(let S=0;S<t.NAME_LENGTH;S++)u[t.UNPACKED_NAME_START+S]=o[a++];const C=t.pack(u);i(new t(C,0))}catch(E){n(E)}},s.onerror=()=>n(new Error("Failed to read file")),s.readAsArrayBuffer(e)})}static fromSysEx(e,i=0){const n=e instanceof Uint8Array?e:new Uint8Array(e);let s;if(n[0]===t.VCED_SYSEX_START){if(n[0]!==t.VCED_SYSEX_START||n[1]!==t.VCED_YAMAHA_ID||n[2]!==t.VCED_SUB_STATUS||n[3]!==t.VCED_FORMAT_SINGLE||n[4]!==t.VCED_BYTE_COUNT_MSB||n[5]!==t.VCED_BYTE_COUNT_LSB)throw new g("Invalid VCED header","header",0);s=n.subarray(t.VCED_HEADER_SIZE,t.VCED_HEADER_SIZE+t.VCED_DATA_SIZE)}else if(n.length===t.PACKED_SIZE)s=n;else throw new d(`Invalid data length: expected ${t.PACKED_SIZE} or ${t.VCED_SIZE} bytes, got ${n.length}`,"length",n.length);if(s.length!==t.VCED_DATA_SIZE&&s.length!==t.PACKED_SIZE)throw new d(`Invalid voice data length: expected ${t.VCED_DATA_SIZE} or ${t.PACKED_SIZE} bytes, got ${s.length}`,"length",s.length);if(s.length===t.VCED_DATA_SIZE){const r=new Uint8Array(t.UNPACKED_SIZE);let E=0;for(let h=0;h<t.NUM_OPERATORS;h++){const N=(t.NUM_OPERATORS-1-h)*t.UNPACKED_OP_SIZE;r[N+t.UNPACKED_OP_EG_RATE_1]=s[E++],r[N+t.UNPACKED_OP_EG_RATE_2]=s[E++],r[N+t.UNPACKED_OP_EG_RATE_3]=s[E++],r[N+t.UNPACKED_OP_EG_RATE_4]=s[E++],r[N+t.UNPACKED_OP_EG_LEVEL_1]=s[E++],r[N+t.UNPACKED_OP_EG_LEVEL_2]=s[E++],r[N+t.UNPACKED_OP_EG_LEVEL_3]=s[E++],r[N+t.UNPACKED_OP_EG_LEVEL_4]=s[E++],r[N+t.UNPACKED_OP_BREAK_POINT]=s[E++],r[N+t.UNPACKED_OP_L_SCALE_DEPTH]=s[E++],r[N+t.UNPACKED_OP_R_SCALE_DEPTH]=s[E++],r[N+t.UNPACKED_OP_L_CURVE]=s[E++],r[N+t.UNPACKED_OP_R_CURVE]=s[E++],r[N+t.UNPACKED_OP_RATE_SCALING]=s[E++],r[N+t.UNPACKED_OP_DETUNE]=s[E++];const u=s[E++];r[N+t.UNPACKED_OP_AMP_MOD_SENS]=u&t.MASK_2BIT,r[N+t.UNPACKED_OP_KEY_VEL_SENS]=u>>2&t.MASK_3BIT,r[N+t.UNPACKED_OP_OUTPUT_LEVEL]=s[E++],r[N+t.UNPACKED_OP_MODE]=s[E++],r[N+t.UNPACKED_OP_FREQ_COARSE]=s[E++],r[N+t.UNPACKED_OP_FREQ_FINE]=s[E++],r[N+t.UNPACKED_OP_OSC_DETUNE]=s[E++]}r[t.UNPACKED_PITCH_EG_RATE_1]=s[E++],r[t.UNPACKED_PITCH_EG_RATE_2]=s[E++],r[t.UNPACKED_PITCH_EG_RATE_3]=s[E++],r[t.UNPACKED_PITCH_EG_RATE_4]=s[E++],r[t.UNPACKED_PITCH_EG_LEVEL_1]=s[E++],r[t.UNPACKED_PITCH_EG_LEVEL_2]=s[E++],r[t.UNPACKED_PITCH_EG_LEVEL_3]=s[E++],r[t.UNPACKED_PITCH_EG_LEVEL_4]=s[E++],r[t.UNPACKED_ALGORITHM]=s[E++],r[t.UNPACKED_FEEDBACK]=s[E++],r[t.UNPACKED_OSC_SYNC]=s[E++],r[t.UNPACKED_LFO_SPEED]=s[E++],r[t.UNPACKED_LFO_DELAY]=s[E++],r[t.UNPACKED_LFO_PM_DEPTH]=s[E++],r[t.UNPACKED_LFO_AM_DEPTH]=s[E++],r[t.UNPACKED_LFO_KEY_SYNC]=s[E++],r[t.UNPACKED_LFO_WAVE]=s[E++],r[t.UNPACKED_LFO_PM_SENS]=s[E++],r[t.UNPACKED_TRANSPOSE]=s[E++];for(let h=0;h<t.NAME_LENGTH;h++)r[t.UNPACKED_NAME_START+h]=s[E++];const o=t.pack(r);return new t(o,i)}return new t(s,i)}static fromJSON(e,i=0){if(!e||typeof e!="object")throw new d("Invalid JSON: expected object","json",e);const n=new Uint8Array(t.UNPACKED_SIZE),s=(a,C,S,D=0,T=127)=>{if(C==null)throw new d(`Missing required parameter: ${S}`,S,C);const f=Number(C);if(Number.isNaN(f))throw new d(`Invalid parameter value for ${S}: ${C}`,S,C);if(f<D||f>T)throw new d(`Parameter ${S} out of range: ${f} (must be ${D}-${T})`,S,f);n[a]=Math.floor(f)},r=a=>{const C={"-LN":0,"-EX":1,"+EX":2,"+LN":3};return C[a]!==void 0?C[a]:0},E=a=>{const C={TRIANGLE:0,"SAW DOWN":1,"SAW UP":2,SQUARE:3,SINE:4,"SAMPLE & HOLD":5};return C[a]!==void 0?C[a]:0},o=a=>{if(!a||typeof a!="string")return 60;const C=a.trim().match(/^([A-G]#?)(-?\d+)$/);if(!C)return 60;const[,S,D]=C,T=parseInt(D,10),U={C:0,"C#":1,D:2,"D#":3,E:4,F:5,"F#":6,G:7,"G#":8,A:9,"A#":10,B:11}[S.toUpperCase()];return U===void 0?60:(T-t.MIDI_OCTAVE_OFFSET)*12+U};if(!Array.isArray(e.operators))throw new d("Invalid operators array: expected array","operators",e.operators);for(let a=0;a<e.operators.length;a++){const C=e.operators[a];if(!C||typeof C!="object")throw new d(`Invalid operator data at index ${a}`,`operators[${a}]`,C);if(!C.eg||!Array.isArray(C.eg.rates)||C.eg.rates.length!==4)throw new d(`Invalid EG rates for operator ${a}`,`operators[${a}].eg.rates`,C.eg?.rates);if(!C.eg||!Array.isArray(C.eg.levels)||C.eg.levels.length!==4)throw new d(`Invalid EG levels for operator ${a}`,`operators[${a}].eg.levels`,C.eg?.levels)}if(e.operators.length!==t.NUM_OPERATORS)throw new d(`Invalid operators array: expected ${t.NUM_OPERATORS} operators`,"operators",e.operators);for(let a=0;a<t.NUM_OPERATORS;a++){const C=e.operators[a],S=a*t.UNPACKED_OP_SIZE;if(!C.eg||!Array.isArray(C.eg.rates)||C.eg.rates.length!==4)throw new d(`Invalid EG rates for operator ${a}`,`operators[${a}].eg.rates`,C.eg?.rates);if(s(S+t.UNPACKED_OP_EG_RATE_1,C.eg.rates[0],`operators[${a}].eg.rates[0]`,0,99),s(S+t.UNPACKED_OP_EG_RATE_2,C.eg.rates[1],`operators[${a}].eg.rates[1]`,0,99),s(S+t.UNPACKED_OP_EG_RATE_3,C.eg.rates[2],`operators[${a}].eg.rates[2]`,0,99),s(S+t.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)throw new d(`Invalid EG levels for operator ${a}`,`operators[${a}].eg.levels`,C.eg?.levels);s(S+t.UNPACKED_OP_EG_LEVEL_1,C.eg.levels[0],`operators[${a}].eg.levels[0]`,0,99),s(S+t.UNPACKED_OP_EG_LEVEL_2,C.eg.levels[1],`operators[${a}].eg.levels[1]`,0,99),s(S+t.UNPACKED_OP_EG_LEVEL_3,C.eg.levels[2],`operators[${a}].eg.levels[2]`,0,99),s(S+t.UNPACKED_OP_EG_LEVEL_4,C.eg.levels[3],`operators[${a}].eg.levels[3]`,0,99);const D=o(C.key?.breakPoint)-t.MIDI_BREAK_POINT_OFFSET;s(S+t.UNPACKED_OP_BREAK_POINT,D,`operators[${a}].key.breakPoint`,0,127),s(S+t.UNPACKED_OP_L_SCALE_DEPTH,C.scale?.left?.depth||0,`operators[${a}].scale.left.depth`,0,99),s(S+t.UNPACKED_OP_R_SCALE_DEPTH,C.scale?.right?.depth||0,`operators[${a}].scale.right.depth`,0,99),n[S+t.UNPACKED_OP_L_CURVE]=r(C.scale?.left?.curve||"-LN"),n[S+t.UNPACKED_OP_R_CURVE]=r(C.scale?.right?.curve||"-LN"),s(S+t.UNPACKED_OP_RATE_SCALING,C.key?.scaling||0,`operators[${a}].key.scaling`,0,7);const T=Number(C.osc?.detune)||0;s(S+t.UNPACKED_OP_DETUNE,T+7,`operators[${a}].osc.detune`,0,14),s(S+t.UNPACKED_OP_AMP_MOD_SENS,C.output?.ampModSens||0,`operators[${a}].output.ampModSens`,0,3),s(S+t.UNPACKED_OP_OUTPUT_LEVEL,C.output?.level||0,`operators[${a}].output.level`,0,99);const f=C.osc?.freq?.mode?.toUpperCase()==="FIXED"?1:0,U=Number(C.osc?.freq?.coarse)||0,L=Number(C.osc?.freq?.fine)||0;n[S+t.UNPACKED_OP_MODE]=f,s(S+t.UNPACKED_OP_FREQ_COARSE,U,`operators[${a}].osc.freq.coarse`,0,31),s(S+t.UNPACKED_OP_FREQ_FINE,L,`operators[${a}].osc.freq.fine`,0,99),s(S+t.UNPACKED_OP_KEY_VEL_SENS,C.key?.velocity||0,`operators[${a}].key.velocity`,0,7)}if(!e.pitchEG||!Array.isArray(e.pitchEG.rates)||e.pitchEG.rates.length!==4)throw new d("Invalid pitch EG rates","pitchEG.rates",e.pitchEG?.rates);if(!e.pitchEG||!Array.isArray(e.pitchEG.levels)||e.pitchEG.levels.length!==4)throw new d("Invalid pitch EG levels","pitchEG.levels",e.pitchEG?.levels);if(s(t.UNPACKED_PITCH_EG_RATE_1,e.pitchEG.rates[0],"pitchEG.rates[0]",0,99),s(t.UNPACKED_PITCH_EG_RATE_2,e.pitchEG.rates[1],"pitchEG.rates[1]",0,99),s(t.UNPACKED_PITCH_EG_RATE_3,e.pitchEG.rates[2],"pitchEG.rates[2]",0,99),s(t.UNPACKED_PITCH_EG_RATE_4,e.pitchEG.rates[3],"pitchEG.rates[3]",0,99),s(t.UNPACKED_PITCH_EG_LEVEL_1,e.pitchEG.levels[0],"pitchEG.levels[0]",0,99),s(t.UNPACKED_PITCH_EG_LEVEL_2,e.pitchEG.levels[1],"pitchEG.levels[1]",0,99),s(t.UNPACKED_PITCH_EG_LEVEL_3,e.pitchEG.levels[2],"pitchEG.levels[2]",0,99),s(t.UNPACKED_PITCH_EG_LEVEL_4,e.pitchEG.levels[3],"pitchEG.levels[3]",0,99),!e.lfo||typeof e.lfo!="object")throw new d("Invalid LFO data","lfo",e.lfo);if(s(t.UNPACKED_LFO_SPEED,e.lfo.speed,"lfo.speed",0,99),s(t.UNPACKED_LFO_DELAY,e.lfo.delay,"lfo.delay",0,99),s(t.UNPACKED_LFO_PM_DEPTH,e.lfo.pmDepth,"lfo.pmDepth",0,99),s(t.UNPACKED_LFO_AM_DEPTH,e.lfo.amDepth,"lfo.amDepth",0,99),n[t.UNPACKED_LFO_KEY_SYNC]=e.lfo.keySync?1:0,n[t.UNPACKED_LFO_WAVE]=E(e.lfo.wave),!e.global||typeof e.global!="object")throw new d("Invalid global data","global",e.global);const h=Number(e.global.algorithm)||1;s(t.UNPACKED_ALGORITHM,h-1,"global.algorithm",0,31),s(t.UNPACKED_FEEDBACK,e.global.feedback,"global.feedback",0,7),n[t.UNPACKED_OSC_SYNC]=e.global.oscKeySync?1:0,s(t.UNPACKED_LFO_PM_SENS,e.global.pitchModSens,"global.pitchModSens",0,7);const N=Number(e.global.transpose)||0;s(t.UNPACKED_TRANSPOSE,N+t.TRANSPOSE_CENTER,"global.transpose",0,127),s(t.UNPACKED_AMP_MOD_SENS,e.global.ampModSens||0,"global.ampModSens",0,3),s(t.UNPACKED_EG_BIAS_SENS,e.global.egBiasSens||0,"global.egBiasSens",0,7);const u=e.name||"";for(let a=0;a<t.NAME_LENGTH;a++)n[t.UNPACKED_NAME_START+a]=a<u.length?u.charCodeAt(a):t.CHAR_SPACE;return t.fromUnpacked(n,i)}toSysEx(){const e=this.unpack(),i=new Uint8Array(t.VCED_SIZE);let n=0;i[n++]=t.VCED_SYSEX_START,i[n++]=t.VCED_YAMAHA_ID,i[n++]=t.VCED_SUB_STATUS,i[n++]=t.VCED_FORMAT_SINGLE,i[n++]=t.VCED_BYTE_COUNT_MSB,i[n++]=t.VCED_BYTE_COUNT_LSB;for(let r=t.NUM_OPERATORS-1;r>=0;r--){const E=r*t.UNPACKED_OP_SIZE;i[n++]=e[E+t.UNPACKED_OP_EG_RATE_1],i[n++]=e[E+t.UNPACKED_OP_EG_RATE_2],i[n++]=e[E+t.UNPACKED_OP_EG_RATE_3],i[n++]=e[E+t.UNPACKED_OP_EG_RATE_4],i[n++]=e[E+t.UNPACKED_OP_EG_LEVEL_1],i[n++]=e[E+t.UNPACKED_OP_EG_LEVEL_2],i[n++]=e[E+t.UNPACKED_OP_EG_LEVEL_3],i[n++]=e[E+t.UNPACKED_OP_EG_LEVEL_4],i[n++]=e[E+t.UNPACKED_OP_BREAK_POINT],i[n++]=e[E+t.UNPACKED_OP_L_SCALE_DEPTH],i[n++]=e[E+t.UNPACKED_OP_R_SCALE_DEPTH],i[n++]=e[E+t.UNPACKED_OP_L_CURVE],i[n++]=e[E+t.UNPACKED_OP_R_CURVE],i[n++]=e[E+t.UNPACKED_OP_RATE_SCALING],i[n++]=e[E+t.UNPACKED_OP_DETUNE];const o=e[E+t.UNPACKED_OP_AMP_MOD_SENS]&t.MASK_2BIT,h=e[E+t.UNPACKED_OP_KEY_VEL_SENS]&t.MASK_3BIT;i[n++]=o|h<<2,i[n++]=e[E+t.UNPACKED_OP_OUTPUT_LEVEL],i[n++]=e[E+t.UNPACKED_OP_MODE],i[n++]=e[E+t.UNPACKED_OP_FREQ_COARSE],i[n++]=e[E+t.UNPACKED_OP_OSC_DETUNE],i[n++]=e[E+t.UNPACKED_OP_FREQ_FINE]}i[n++]=e[t.UNPACKED_PITCH_EG_RATE_1],i[n++]=e[t.UNPACKED_PITCH_EG_RATE_2],i[n++]=e[t.UNPACKED_PITCH_EG_RATE_3],i[n++]=e[t.UNPACKED_PITCH_EG_RATE_4],i[n++]=e[t.UNPACKED_PITCH_EG_LEVEL_1],i[n++]=e[t.UNPACKED_PITCH_EG_LEVEL_2],i[n++]=e[t.UNPACKED_PITCH_EG_LEVEL_3],i[n++]=e[t.UNPACKED_PITCH_EG_LEVEL_4],i[n++]=e[t.UNPACKED_ALGORITHM],i[n++]=e[t.UNPACKED_FEEDBACK],i[n++]=e[t.UNPACKED_OSC_SYNC],i[n++]=e[t.UNPACKED_LFO_SPEED],i[n++]=e[t.UNPACKED_LFO_DELAY],i[n++]=e[t.UNPACKED_LFO_PM_DEPTH],i[n++]=e[t.UNPACKED_LFO_AM_DEPTH],i[n++]=e[t.UNPACKED_LFO_KEY_SYNC],i[n++]=e[t.UNPACKED_LFO_WAVE],i[n++]=e[t.UNPACKED_LFO_PM_SENS],i[n++]=e[t.UNPACKED_TRANSPOSE];for(let r=0;r<t.NAME_LENGTH;r++)i[n++]=e[t.UNPACKED_NAME_START+r];const s=i.subarray(t.VCED_HEADER_SIZE,t.VCED_HEADER_SIZE+t.VCED_DATA_SIZE);return i[n++]=G._calculateChecksum(s,t.VCED_DATA_SIZE),i[n++]=t.VCED_SYSEX_END,i}toJSON(){const e=this.unpack(),i=[],n=E=>["-LN","-EX","+EX","+LN"][E]||"UNKNOWN",s=E=>["TRIANGLE","SAW DOWN","SAW UP","SQUARE","SINE","SAMPLE & HOLD"][E]||"UNKNOWN",r=E=>{const o=["C","C#","D","D#","E","F","F#","G","G#","A","A#","B"],h=Math.floor(E/12)+t.MIDI_OCTAVE_OFFSET;return`${o[E%12]}${h}`};for(let E=0;E<t.NUM_OPERATORS;E++){const o=E*t.UNPACKED_OP_SIZE,h=e[o+t.UNPACKED_OP_MODE]===0?"RATIO":"FIXED";i.push({id:E+1,osc:{detune:e[o+t.UNPACKED_OP_OSC_DETUNE],freq:{coarse:e[o+t.UNPACKED_OP_FREQ_COARSE],fine:e[o+t.UNPACKED_OP_FREQ_FINE],mode:h}},eg:{rates:[e[o+t.UNPACKED_OP_EG_RATE_1],e[o+t.UNPACKED_OP_EG_RATE_2],e[o+t.UNPACKED_OP_EG_RATE_3],e[o+t.UNPACKED_OP_EG_RATE_4]],levels:[e[o+t.UNPACKED_OP_EG_LEVEL_1],e[o+t.UNPACKED_OP_EG_LEVEL_2],e[o+t.UNPACKED_OP_EG_LEVEL_3],e[o+t.UNPACKED_OP_EG_LEVEL_4]]},key:{velocity:e[o+t.UNPACKED_OP_KEY_VEL_SENS],scaling:e[o+t.UNPACKED_OP_RATE_SCALING],breakPoint:r(e[o+t.UNPACKED_OP_BREAK_POINT]+t.MIDI_BREAK_POINT_OFFSET)},output:{level:e[o+t.UNPACKED_OP_OUTPUT_LEVEL],ampModSens:e[o+t.UNPACKED_OP_AMP_MOD_SENS]},scale:{left:{depth:e[o+t.UNPACKED_OP_L_SCALE_DEPTH],curve:n(e[o+t.UNPACKED_OP_L_CURVE])},right:{depth:e[o+t.UNPACKED_OP_R_SCALE_DEPTH],curve:n(e[o+t.UNPACKED_OP_R_CURVE])}}})}return{name:this.name||"(Empty)",operators:i,pitchEG:{rates:[e[t.UNPACKED_PITCH_EG_RATE_1],e[t.UNPACKED_PITCH_EG_RATE_2],e[t.UNPACKED_PITCH_EG_RATE_3],e[t.UNPACKED_PITCH_EG_RATE_4]],levels:[e[t.UNPACKED_PITCH_EG_LEVEL_1],e[t.UNPACKED_PITCH_EG_LEVEL_2],e[t.UNPACKED_PITCH_EG_LEVEL_3],e[t.UNPACKED_PITCH_EG_LEVEL_4]]},lfo:{speed:e[t.UNPACKED_LFO_SPEED],delay:e[t.UNPACKED_LFO_DELAY],pmDepth:e[t.UNPACKED_LFO_PM_DEPTH],amDepth:e[t.UNPACKED_LFO_AM_DEPTH],keySync:e[t.UNPACKED_LFO_KEY_SYNC]===1,wave:s(e[t.UNPACKED_LFO_WAVE])},global:{algorithm:e[t.UNPACKED_ALGORITHM]+1,feedback:e[t.UNPACKED_FEEDBACK],oscKeySync:e[t.UNPACKED_OSC_SYNC]===1,pitchModSens:e[t.UNPACKED_LFO_PM_SENS],transpose:e[t.UNPACKED_TRANSPOSE]-t.TRANSPOSE_CENTER}}}};_(t,"PACKED_SIZE",128),_(t,"PACKED_OP_SIZE",17),_(t,"NUM_OPERATORS",6),_(t,"PACKED_OP_EG_RATE_1",0),_(t,"PACKED_OP_EG_RATE_2",1),_(t,"PACKED_OP_EG_RATE_3",2),_(t,"PACKED_OP_EG_RATE_4",3),_(t,"PACKED_OP_EG_LEVEL_1",4),_(t,"PACKED_OP_EG_LEVEL_2",5),_(t,"PACKED_OP_EG_LEVEL_3",6),_(t,"PACKED_OP_EG_LEVEL_4",7),_(t,"PACKED_OP_BREAK_POINT",8),_(t,"PACKED_OP_L_SCALE_DEPTH",9),_(t,"PACKED_OP_R_SCALE_DEPTH",10),_(t,"PACKED_OP_CURVES",11),_(t,"PACKED_OP_RATE_SCALING",12),_(t,"PACKED_OP_MOD_SENS",13),_(t,"PACKED_OP_OUTPUT_LEVEL",14),_(t,"PACKED_OP_MODE_FREQ",15),_(t,"PACKED_OP_DETUNE_FINE",16),_(t,"PACKED_PITCH_EG_RATE_1",102),_(t,"PACKED_PITCH_EG_RATE_2",103),_(t,"PACKED_PITCH_EG_RATE_3",104),_(t,"PACKED_PITCH_EG_RATE_4",105),_(t,"PACKED_PITCH_EG_LEVEL_1",106),_(t,"PACKED_PITCH_EG_LEVEL_2",107),_(t,"PACKED_PITCH_EG_LEVEL_3",108),_(t,"PACKED_PITCH_EG_LEVEL_4",109),_(t,"OFFSET_ALGORITHM",110),_(t,"OFFSET_FEEDBACK",111),_(t,"OFFSET_LFO_SPEED",112),_(t,"OFFSET_LFO_DELAY",113),_(t,"OFFSET_LFO_PM_DEPTH",114),_(t,"OFFSET_LFO_AM_DEPTH",115),_(t,"OFFSET_LFO_SYNC_WAVE",116),_(t,"OFFSET_TRANSPOSE",117),_(t,"OFFSET_AMP_MOD_SENS",118),_(t,"OFFSET_EG_BIAS_SENS",119),_(t,"PACKED_NAME_START",118),_(t,"NAME_LENGTH",10),_(t,"UNPACKED_SIZE",169),_(t,"UNPACKED_OP_SIZE",23),_(t,"UNPACKED_OP_EG_RATE_1",0),_(t,"UNPACKED_OP_EG_RATE_2",1),_(t,"UNPACKED_OP_EG_RATE_3",2),_(t,"UNPACKED_OP_EG_RATE_4",3),_(t,"UNPACKED_OP_EG_LEVEL_1",4),_(t,"UNPACKED_OP_EG_LEVEL_2",5),_(t,"UNPACKED_OP_EG_LEVEL_3",6),_(t,"UNPACKED_OP_EG_LEVEL_4",7),_(t,"UNPACKED_OP_BREAK_POINT",8),_(t,"UNPACKED_OP_L_SCALE_DEPTH",9),_(t,"UNPACKED_OP_R_SCALE_DEPTH",10),_(t,"UNPACKED_OP_L_CURVE",11),_(t,"UNPACKED_OP_R_CURVE",12),_(t,"UNPACKED_OP_RATE_SCALING",13),_(t,"UNPACKED_OP_DETUNE",14),_(t,"UNPACKED_OP_AMP_MOD_SENS",15),_(t,"UNPACKED_OP_OUTPUT_LEVEL",16),_(t,"UNPACKED_OP_MODE",17),_(t,"UNPACKED_OP_KEY_VEL_SENS",18),_(t,"UNPACKED_OP_FREQ_COARSE",19),_(t,"UNPACKED_OP_OSC_DETUNE",20),_(t,"UNPACKED_OP_FREQ_FINE",21),_(t,"UNPACKED_PITCH_EG_RATE_1",138),_(t,"UNPACKED_PITCH_EG_RATE_2",139),_(t,"UNPACKED_PITCH_EG_RATE_3",140),_(t,"UNPACKED_PITCH_EG_RATE_4",141),_(t,"UNPACKED_PITCH_EG_LEVEL_1",142),_(t,"UNPACKED_PITCH_EG_LEVEL_2",143),_(t,"UNPACKED_PITCH_EG_LEVEL_3",144),_(t,"UNPACKED_PITCH_EG_LEVEL_4",145),_(t,"UNPACKED_ALGORITHM",146),_(t,"UNPACKED_FEEDBACK",147),_(t,"UNPACKED_OSC_SYNC",148),_(t,"UNPACKED_LFO_SPEED",149),_(t,"UNPACKED_LFO_DELAY",150),_(t,"UNPACKED_LFO_PM_DEPTH",151),_(t,"UNPACKED_LFO_AM_DEPTH",152),_(t,"UNPACKED_LFO_KEY_SYNC",153),_(t,"UNPACKED_LFO_WAVE",154),_(t,"UNPACKED_LFO_PM_SENS",155),_(t,"UNPACKED_AMP_MOD_SENS",156),_(t,"UNPACKED_TRANSPOSE",157),_(t,"UNPACKED_EG_BIAS_SENS",158),_(t,"UNPACKED_NAME_START",159),_(t,"VCED_SIZE",163),_(t,"VCED_HEADER_SIZE",6),_(t,"VCED_DATA_SIZE",155),_(t,"VCED_SYSEX_START",240),_(t,"VCED_YAMAHA_ID",67),_(t,"VCED_SUB_STATUS",0),_(t,"VCED_FORMAT_SINGLE",0),_(t,"VCED_BYTE_COUNT_MSB",1),_(t,"VCED_BYTE_COUNT_LSB",27),_(t,"VCED_SYSEX_END",247),_(t,"MASK_7BIT",127),_(t,"MASK_2BIT",3),_(t,"MASK_3BIT",7),_(t,"MASK_4BIT",15),_(t,"MASK_5BIT",31),_(t,"MASK_1BIT",1),_(t,"TRANSPOSE_CENTER",24),_(t,"CHAR_YEN",92),_(t,"CHAR_ARROW_RIGHT",126),_(t,"CHAR_ARROW_LEFT",127),_(t,"CHAR_REPLACEMENT_Y",89),_(t,"CHAR_REPLACEMENT_GT",62),_(t,"CHAR_REPLACEMENT_LT",60),_(t,"CHAR_SPACE",32),_(t,"CHAR_MIN_PRINTABLE",32),_(t,"CHAR_MAX_PRINTABLE",126),_(t,"DEFAULT_EG_RATE",99),_(t,"DEFAULT_EG_LEVEL_MAX",99),_(t,"DEFAULT_EG_LEVEL_MIN",0),_(t,"DEFAULT_BREAK_POINT",0),_(t,"DEFAULT_OUTPUT_LEVEL",99),_(t,"DEFAULT_PITCH_EG_LEVEL",50),_(t,"DEFAULT_LFO_SPEED",35),_(t,"DEFAULT_LFO_PM_SENS",3),_(t,"DEFAULT_DETUNE",7),_(t,"DEFAULT_FREQ_COARSE",1),_(t,"DEFAULT_ALGORITHM",0),_(t,"DEFAULT_FEEDBACK",0),_(t,"DEFAULT_OSC_SYNC",1),_(t,"DEFAULT_LFO_KEY_SYNC",1),_(t,"MIDI_OCTAVE_OFFSET",-2),_(t,"MIDI_BREAK_POINT_OFFSET",21);let m=t;const P=class P{constructor(e,i=""){if(this.voices=new Array(P.NUM_VOICES),this.name=i,e)this._load(e);else for(let n=0;n<P.NUM_VOICES;n++)this.voices[n]=m.createDefault(n)}static _calculateChecksum(e,i){let n=0;for(let s=0;s<i;s++)n+=e[s];return P.CHECKSUM_MODULO-n%P.CHECKSUM_MODULO&P.MASK_7BIT}_load(e){const i=e instanceof Uint8Array?e:new Uint8Array(e);let n,s=0;if(i[0]===P.SYSEX_START){const E=i.subarray(0,P.SYSEX_HEADER_SIZE),o=P.SYSEX_HEADER;for(let h=0;h<P.SYSEX_HEADER_SIZE;h++)if(E[h]!==o[h])throw new g(`Invalid SysEx header at position ${h}: expected ${o[h].toString(16)}, got ${E[h].toString(16)}`,"header",h);n=i.subarray(P.SYSEX_HEADER_SIZE,P.SYSEX_HEADER_SIZE+P.VOICE_DATA_SIZE),s=P.SYSEX_HEADER_SIZE}else if(i.length===P.VOICE_DATA_SIZE)n=i;else throw new d(`Invalid data length: expected ${P.VOICE_DATA_SIZE} or ${P.SYSEX_SIZE} bytes, got ${i.length}`,"length",i.length);if(n.length!==P.VOICE_DATA_SIZE)throw new d(`Invalid voice data length: expected ${P.VOICE_DATA_SIZE} bytes, got ${n.length}`,"length",n.length);const r=P.SYSEX_HEADER_SIZE+P.VOICE_DATA_SIZE;if(s>0&&i.length>=r+1){const E=i[r],o=P._calculateChecksum(n,P.VOICE_DATA_SIZE);E!==o&&console.warn(`DX7 checksum mismatch (expected ${o.toString(16)}, got ${E.toString(16)}). This is common with vintage SysEx files and the data is likely still valid.`)}this.voices=new Array(P.NUM_VOICES);for(let E=0;E<P.NUM_VOICES;E++){const o=E*P.VOICE_SIZE,h=n.subarray(o,o+P.VOICE_SIZE);this.voices[E]=new m(h,E)}}replaceVoice(e,i){if(e<0||e>=P.NUM_VOICES)throw new d(`Invalid voice index: ${e}`,"index",e);const n=new Uint8Array(i.data);this.voices[e]=new m(n,e)}addVoice(e){for(let i=0;i<this.voices.length;i++){const n=this.voices[i];if(n.name===""||n.name==="Init Voice")return this.replaceVoice(i,e),i}return-1}getVoices(){return this.voices}getVoice(e){return e<0||e>=this.voices.length?null:this.voices[e]}getVoiceNames(){return this.voices.map(e=>e.name)}findVoiceByName(e){const i=e.toLowerCase();return this.voices.find(n=>n.name.toLowerCase().includes(i))||null}static async fromFile(e){return new Promise((i,n)=>{const s=new FileReader;s.onload=async r=>{try{const E=e.name||"",o=new Uint8Array(r.target.result);if(o[0]===P.SYSEX_START&&o[3]===m.VCED_FORMAT_SINGLE)n(new g("This is a single voice file. Use DX7Voice.fromFile() instead.","format",3));else{const h=E.replace(/\.[^/.]+$/,""),N=new P(r.target.result,h);i(N)}}catch(E){n(E)}},s.onerror=()=>n(new Error("Failed to read file")),s.readAsArrayBuffer(e)})}static fromSysEx(e,i=""){return new P(e,i)}static fromJSON(e){if(!e||typeof e!="object")throw new d("Invalid JSON: expected object","json",e);const i=new P;if(i.name=e.name||"",!Array.isArray(e.voices))throw new d("Invalid voices array","voices",e.voices);e.voices.length!==P.NUM_VOICES&&console.warn(`Bank JSON has ${e.voices.length} voices, expected ${P.NUM_VOICES}. Missing voices will be filled with defaults.`);const n=Math.min(e.voices.length,P.NUM_VOICES);for(let s=0;s<n;s++){const r=e.voices[s];if(!r||typeof r!="object"){console.warn(`Invalid voice data at index ${s}, using default voice`);continue}try{const{index:E,...o}=r,h=m.fromJSON(o,s);i.replaceVoice(s,h)}catch(E){console.warn(`Failed to load voice at index ${s}: ${E.message}, using default voice`)}}return i}toSysEx(){const e=new Uint8Array(P.SYSEX_SIZE);let i=0;P.SYSEX_HEADER.forEach(s=>{e[i++]=s});for(const s of this.voices)for(let r=0;r<P.VOICE_SIZE;r++)e[i++]=s.data[r];const n=e.subarray(P.SYSEX_HEADER_SIZE,P.SYSEX_HEADER_SIZE+P.VOICE_DATA_SIZE);return e[i++]=P._calculateChecksum(n,P.VOICE_DATA_SIZE),e[i++]=P.SYSEX_END,e}toJSON(){const e=this.voices.map((i,n)=>{const s=i.toJSON();return{index:n+1,...s}});return{version:"1.0",name:this.name||"",voices:e}}};_(P,"SYSEX_START",240),_(P,"SYSEX_END",247),_(P,"SYSEX_YAMAHA_ID",67),_(P,"SYSEX_SUB_STATUS",0),_(P,"SYSEX_FORMAT_32_VOICES",9),_(P,"SYSEX_BYTE_COUNT_MSB",32),_(P,"SYSEX_BYTE_COUNT_LSB",0),_(P,"SYSEX_HEADER",[P.SYSEX_START,P.SYSEX_YAMAHA_ID,P.SYSEX_SUB_STATUS,P.SYSEX_FORMAT_32_VOICES,P.SYSEX_BYTE_COUNT_MSB,P.SYSEX_BYTE_COUNT_LSB]),_(P,"SYSEX_HEADER_SIZE",6),_(P,"VOICE_DATA_SIZE",4096),_(P,"SYSEX_SIZE",4104),_(P,"VOICE_SIZE",128),_(P,"NUM_VOICES",32),_(P,"CHECKSUM_MODULO",128),_(P,"MASK_7BIT",127);let G=P;function nt(c){return c[0]!==240||c[c.length-1]!==247?null:{manufacturerId:c[1],payload:c.slice(2,-1),raw:c}}function st(c,e){return[240,c,...e,247]}function Et(c){return c.length>=2&&c[0]===240&&c[c.length-1]===247}function rt(c){const e=[];for(let i=0;i<c.length;i+=7){const n=c.slice(i,i+7);let s=0;const r=[];for(let E=0;E<n.length;E++){const o=n[E];o&128&&(s|=1<<E),r.push(o&127)}e.push(s,...r)}return e}function ot(c){const e=[];for(let i=0;i<c.length;i+=8){const n=c[i],s=Math.min(7,c.length-i-1);for(let r=0;r<s;r++){let E=c[i+1+r];n&1<<r&&(E|=128),e.push(E)}}return e}function _t(c){return Number.isInteger(c)&&c>=1&&c<=16}function at(c){return Number.isInteger(c)&&c>=0&&c<=127}function ct(c){return Number.isInteger(c)&&c>=0&&c<=31}function Ct(c){return Number.isInteger(c)&&c>=0&&c<=127}function At(c){return Number.isInteger(c)&&c>=0&&c<=127}function Pt(c){return Number.isInteger(c)&&c>=0&&c<=127}function ut(c){return Number.isInteger(c)&&c>=0&&c<=127}function lt(c){return Number.isInteger(c)&&c>=0&&c<=16383}function ht(c,e){return Number.isInteger(c)&&c>=0&&c<=127&&Number.isInteger(e)&&e>=0&&e<=127}async function St(c={}){const{onStatusUpdate:e,onConnectionUpdate:i,inputChannel:n=1,outputChannel:s=1,output:r,sysex:E,onReady:o,onError:h,selector:N,watchDOM:u,...a}=c,S=await q({autoConnect:!1,sysex:E,inputChannel:n,outputChannel:s,selector:N||"[data-midi-cc]",watchDOM:u,onError:h,...a}),D=new z({midiController:S,onStatusUpdate:e||(()=>{}),onConnectionUpdate:i||(()=>{}),channel:s});if(r)try{await S.device.connectOutput(r),D.currentOutput=S.device.getCurrentOutput(),D.updateConnectionStatus()}catch(T){h?h(T):console.error("Failed to connect to MIDI device:",T.message)}return o&&o(S,D),D}async function q(c={}){const e=new Z(c);await e.init();const i=c.selector||"[data-midi-cc]";{const n=new I(e,i);n.bindAll(),c.watchDOM&&n.enableAutoBinding(),e._binder=n}return e}function Nt(){return typeof navigator<"u"&&typeof navigator.requestMIDIAccess=="function"}l.CONN=p,l.CONNECTION_EVENTS=p,l.CONTROLLER_EVENTS=A,l.CTRL=A,l.DX7Bank=G,l.DX7Error=H,l.DX7ParseError=g,l.DX7ValidationError=d,l.DX7Voice=m,l.DataAttributeBinder=I,l.EventEmitter=v,l.MIDIAccessError=F,l.MIDIConnection=$,l.MIDIConnectionError=y,l.MIDIController=Z,l.MIDIDeviceError=R,l.MIDIDeviceManager=z,l.MIDIError=K,l.MIDIValidationError=M,l.clamp=O,l.createMIDIController=q,l.createMIDIDeviceManager=St,l.createSysEx=st,l.decode14BitValue=Y,l.decode7Bit=ot,l.denormalize14BitValue=it,l.denormalizeValue=J,l.encode14BitValue=B,l.encode7Bit=rt,l.frequencyToNote=X,l.getCCName=et,l.isMIDISupported=Nt,l.isSysEx=Et,l.isValid14BitCC=ct,l.isValidCC=at,l.isValidChannel=_t,l.isValidMIDIValue=Ct,l.isValidNote=At,l.isValidPitchBend=lt,l.isValidPitchBendBytes=ht,l.isValidProgramChange=ut,l.isValidVelocity=Pt,l.normalize14BitValue=x,l.normalizeValue=w,l.noteNameToNumber=k,l.noteNumberToName=j,l.noteToFrequency=tt,l.parseSysEx=nt,Object.defineProperty(l,Symbol.toStringTag,{value:"Module"})}));
1
+ (function(l,I){typeof exports=="object"&&typeof module<"u"?I(exports):typeof define=="function"&&define.amd?define(["exports"],I):(l=typeof globalThis<"u"?globalThis:l||self,I(l.MIDIControls={}))})(this,(function(l){"use strict";var dt=Object.defineProperty;var Tt=(l,I,K)=>I in l?dt(l,I,{enumerable:!0,configurable:!0,writable:!0,value:K}):l[I]=K;var _=(l,I,K)=>Tt(l,typeof I!="symbol"?I+"":I,K);class I{constructor(e,i="[data-midi-cc]"){this.controller=e,this.selector=i,this.observer=null}bindAll(){document.querySelectorAll(this.selector==="[data-midi-cc]"?"[data-midi-cc], [data-midi-msb][data-midi-lsb]":this.selector).forEach(i=>{if(i.hasAttribute("data-midi-bound"))return;const n=this._parseAttributes(i);n&&(this.controller.bind(i,n),i.setAttribute("data-midi-bound","true"))})}enableAutoBinding(){if(this.observer)return;const e=this.selector==="[data-midi-cc]"?"[data-midi-cc], [data-midi-msb][data-midi-lsb]":this.selector;this.observer=new MutationObserver(i=>{i.forEach(n=>{n.addedNodes.forEach(s=>{if(s.nodeType===Node.ELEMENT_NODE){if(s.matches?.(e)){const r=this._parseAttributes(s);r&&!s.hasAttribute("data-midi-bound")&&(this.controller.bind(s,r),s.setAttribute("data-midi-bound","true"))}s.querySelectorAll&&s.querySelectorAll(e).forEach(E=>{if(!E.hasAttribute("data-midi-bound")){const o=this._parseAttributes(E);o&&(this.controller.bind(E,o),E.setAttribute("data-midi-bound","true"))}})}}),n.removedNodes.forEach(s=>{s.nodeType===Node.ELEMENT_NODE&&(s.hasAttribute?.("data-midi-bound")&&this.controller.unbind(s),s.querySelectorAll&&s.querySelectorAll("[data-midi-bound]").forEach(E=>{this.controller.unbind(E)}))})})}),this.observer.observe(document.body,{childList:!0,subtree:!0})}disableAutoBinding(){this.observer&&(this.observer.disconnect(),this.observer=null)}_parseAttributes(e){const i=parseInt(e.dataset.midiMsb,10),n=parseInt(e.dataset.midiLsb,10);if(!Number.isNaN(i)&&!Number.isNaN(n)&&i>=0&&i<=127&&n>=0&&n<=127){const r=parseInt(e.dataset.midiCc,10);return!Number.isNaN(r)&&r>=0&&r<=127&&console.warn(`Element has both 7-bit (data-midi-cc="${r}") and 14-bit (data-midi-msb="${i}" data-midi-lsb="${n}") CC attributes. 14-bit takes precedence.`,e),{msb:i,lsb:n,is14Bit:!0,channel:parseInt(e.dataset.midiChannel,10)||void 0,min:parseFloat(e.getAttribute("min"))||0,max:parseFloat(e.getAttribute("max"))||127,invert:e.dataset.midiInvert==="true",label:e.dataset.midiLabel}}const s=parseInt(e.dataset.midiCc,10);return!Number.isNaN(s)&&s>=0&&s<=127?{cc:s,channel:parseInt(e.dataset.midiChannel,10)||void 0,min:parseFloat(e.getAttribute("min"))||0,max:parseFloat(e.getAttribute("max"))||127,invert:e.dataset.midiInvert==="true",label:e.dataset.midiLabel}:((e.dataset.midiCc!==void 0||e.dataset.midiMsb!==void 0&&e.dataset.midiLsb!==void 0)&&console.warn("Invalid MIDI configuration on element:",e),null)}destroy(){this.disableAutoBinding()}}class K extends Error{constructor(e,i){super(e),this.name="MIDIError",this.code=i,Error.captureStackTrace&&Error.captureStackTrace(this,this.constructor)}}class b extends K{constructor(e,i){super(e,"MIDI_ACCESS_ERROR"),this.name="MIDIAccessError",this.reason=i}}class y extends K{constructor(e){super(e,"MIDI_CONNECTION_ERROR"),this.name="MIDIConnectionError"}}class R extends K{constructor(e,i,n){super(e,"MIDI_DEVICE_ERROR"),this.name="MIDIDeviceError",this.deviceType=i,this.deviceId=n}}class g extends K{constructor(e,i){super(e,"MIDI_VALIDATION_ERROR"),this.name="MIDIValidationError",this.validationType=i}}class H extends Error{constructor(e,i){super(e),this.name="DX7Error",this.code=i,Error.captureStackTrace&&Error.captureStackTrace(this,this.constructor)}}class G extends H{constructor(e,i,n){super(e,"DX7_PARSE_ERROR"),this.name="DX7ParseError",this.parseType=i,this.offset=n}}class d extends H{constructor(e,i,n){super(e,"DX7_VALIDATION_ERROR"),this.name="DX7ValidationError",this.validationType=i,this.value=n}}function O(c,e,i){return Math.max(e,Math.min(i,c))}function w(c,e,i,n=!1){const s=(c-e)/(i-e),E=(n?1-s:s)*127;return O(Math.round(E),0,127)}function J(c,e,i,n=!1){let s=O(c,0,127)/127;return n&&(s=1-s),e+s*(i-e)}function k(c){const e={C:0,"C#":1,DB:1,D:2,"D#":3,EB:3,E:4,F:5,"F#":6,GB:6,G:7,"G#":8,AB:8,A:9,"A#":10,BB:10,B:11},i=c.match(/^([A-G][#b]?)(-?\d+)$/i);if(!i)throw new g(`Invalid note name: ${c}`,"note",c);const[,n,s]=i,r=e[n.toUpperCase()];if(r===void 0)throw new g(`Invalid note: ${n}`,"note",n);const E=(parseInt(s,10)+1)*12+r;return O(E,0,127)}function j(c,e=!1){const s=e?["C","Db","D","Eb","E","F","Gb","G","Ab","A","Bb","B"]:["C","C#","D","D#","E","F","F#","G","G#","A","A#","B"],r=Math.floor(c/12)-1;return`${s[c%12]}${r}`}function X(c){const e=69+12*Math.log2(c/440);return O(Math.round(e),0,127)}function tt(c){return 440*2**((c-69)/12)}function et(c){return{0:"Bank Select",1:"Modulation",2:"Breath Controller",4:"Foot Controller",5:"Portamento Time",7:"Volume",8:"Balance",10:"Pan",11:"Expression",64:"Sustain Pedal",65:"Portamento",66:"Sostenuto",67:"Soft Pedal",68:"Legato",71:"Resonance",72:"Release Time",73:"Attack Time",74:"Cutoff",75:"Decay Time",76:"Vibrato Rate",77:"Vibrato Depth",78:"Vibrato Delay",84:"Portamento Control",91:"Reverb",92:"Tremolo",93:"Chorus",94:"Detune",95:"Phaser",120:"All Sound Off",121:"Reset All Controllers",123:"All Notes Off"}[c]||`CC ${c}`}function B(c){const e=O(Math.round(c),0,16383);return{msb:e>>7&127,lsb:e&127}}function Y(c,e){return O(c,0,127)<<7|O(e,0,127)}function x(c,e,i,n=!1){const s=(c-e)/(i-e),E=(n?1-s:s)*16383;return B(E)}function it(c,e,i,n,s=!1){let E=Y(c,e)/16383;return s&&(E=1-E),i+E*(n-i)}class v{constructor(){this.events=new Map}on(e,i){return this.events.has(e)||this.events.set(e,[]),this.events.get(e).push(i),()=>this.off(e,i)}once(e,i){const n=(...s)=>{i(...s),this.off(e,n)};this.on(e,n)}off(e,i){if(!this.events.has(e))return;const n=this.events.get(e),s=n.indexOf(i);s>-1&&n.splice(s,1),n.length===0&&this.events.delete(e)}emit(e,i){if(!this.events.has(e))return;[...this.events.get(e)].forEach(s=>{try{s(i)}catch(r){console.error(`Error in event handler for "${e}":`,r)}})}removeAllListeners(e){e?this.events.delete(e):this.events.clear()}}const p={DEVICE_CHANGE:"device-change",IN_DEV_CONNECTED:"in-dev-connected",IN_DEV_DISCONNECTED:"in-dev-disconnected",OUT_DEV_CONNECTED:"out-dev-connected",OUT_DEV_DISCONNECTED:"out-dev-disconnected"};class $ extends v{constructor(e={}){super(),this.options={sysex:!1,...e},this.midiAccess=null,this.output=null,this.input=null}async requestAccess(){if(!navigator.requestMIDIAccess)throw new b("Web MIDI API is not supported in this browser","unsupported");try{this.midiAccess=await navigator.requestMIDIAccess({sysex:this.options.sysex}),this.midiAccess.onstatechange=e=>{const i=e.port,n=e.port.state;this.emit(p.DEVICE_CHANGE,{port:i,state:n,type:i.type,device:{id:i.id,name:i.name,manufacturer:i.manufacturer||"Unknown"}}),n==="disconnected"?i.type==="input"?(this.emit(p.IN_DEV_DISCONNECTED,{device:i}),this.input&&this.input.id===i.id&&(this.input=null)):i.type==="output"&&(this.emit(p.OUT_DEV_DISCONNECTED,{device:i}),this.output&&this.output.id===i.id&&(this.output=null)):n==="connected"&&(i.type==="input"?this.emit(p.IN_DEV_CONNECTED,{device:i}):i.type==="output"&&this.emit(p.OUT_DEV_CONNECTED,{device:i}))}}catch(e){throw e.name==="SecurityError"?new b("MIDI access denied. SysEx requires user permission.","denied"):new b(`Failed to get MIDI access: ${e.message}`,"failed")}}async connect(e){if(!this.midiAccess)throw new y("MIDI access not initialized. Call requestAccess() first.");const i=Array.from(this.midiAccess.outputs.values());if(i.length===0)throw new R("No MIDI output devices available","output");if(e===void 0){this.output=i[0];return}if(typeof e=="number"){if(e<0||e>=i.length)throw new R(`Output index ${e} out of range (0-${i.length-1})`,"output",e);this.output=i[e];return}if(this.output=i.find(n=>n.name===e||n.id===e),!this.output){const n=i.map(s=>s.name).join(", ");throw new R(`MIDI output "${e}" not found. Available: ${n}`,"output",e)}}async connectInput(e,i){if(!this.midiAccess)throw new y("MIDI access not initialized. Call requestAccess() first.");if(typeof i!="function")throw new g("onMessage callback must be a function","callback");const n=Array.from(this.midiAccess.inputs.values());if(n.length===0)throw new R("No MIDI input devices available","input");if(this.input&&(this.input.onmidimessage=null),e===void 0)this.input=n[0];else if(typeof e=="number"){if(e<0||e>=n.length)throw new R(`Input index ${e} out of range (0-${n.length-1})`,"input",e);this.input=n[e]}else if(this.input=n.find(s=>s.name===e||s.id===e),!this.input){const s=n.map(r=>r.name).join(", ");throw new R(`MIDI input "${e}" not found. Available: ${s}`,"input",e)}this.input.onmidimessage=s=>{i(s)}}disconnectOutput(){this.output=null}disconnectInput(){this.input&&(this.input.onmidimessage=null,this.input=null)}disconnect(){this.disconnectOutput(),this.disconnectInput()}isConnected(){return this.output!==null}getCurrentOutput(){return this.output?{id:this.output.id,name:this.output.name,manufacturer:this.output.manufacturer||"Unknown"}:null}getCurrentInput(){return this.input?{id:this.input.id,name:this.input.name,manufacturer:this.input.manufacturer||"Unknown"}:null}getOutputs(){if(!this.midiAccess)return[];const e=[];return this.midiAccess.outputs.forEach(i=>{i.state==="connected"&&e.push({id:i.id,name:i.name,manufacturer:i.manufacturer||"Unknown"})}),e}getInputs(){if(!this.midiAccess)return[];const e=[];return this.midiAccess.inputs.forEach(i=>{i.state==="connected"&&e.push({id:i.id,name:i.name,manufacturer:i.manufacturer||"Unknown"})}),e}send(e,i=null){if(!this.output){console.warn("No MIDI output connected. Call connect() first.");return}try{const n=new Uint8Array(e);i===null?this.output.send(n):this.output.send(n,i)}catch(n){console.error("Failed to send MIDI message:",n)}}sendSysEx(e,i=!1){if(!this.options.sysex){console.warn("SysEx not enabled. Initialize with sysex: true");return}let n;i?n=[240,...e,247]:n=e,this.send(n)}}const C={READY:"ready",ERROR:"error",DESTROYED:"destroyed",DEV_OUT_CONNECTED:"dev-out-connected",DEV_OUT_DISCONNECTED:"dev-out-disconnected",DEV_IN_CONNECTED:"dev-in-connected",DEV_IN_DISCONNECTED:"dev-in-disconnected",CH_CC_SEND:"ch-cc-send",CH_CC_RECV:"ch-cc-recv",CH_NOTE_ON_SEND:"ch-note-on-send",CH_NOTE_ON_RECV:"ch-note-on-recv",CH_NOTE_OFF_SEND:"ch-note-off-send",CH_NOTE_OFF_RECV:"ch-note-off-recv",CH_PC_SEND:"ch-pc-send",CH_PC_RECV:"ch-pc-recv",CH_PITCH_BEND_SEND:"ch-pitch-bend-send",CH_PITCH_BEND_RECV:"ch-pitch-bend-recv",CH_MONO_PRESS_SEND:"ch-mono-press-send",CH_MONO_PRESS_RECV:"ch-mono-press-recv",CH_POLY_PRESS_SEND:"ch-poly-press-send",CH_POLY_PRESS_RECV:"ch-poly-press-recv",CH_ALL_SOUNDS_OFF_SEND:"ch-all-sounds-off-send",CH_RESET_CONTROLLERS_SEND:"ch-reset-controllers-send",CH_LOCAL_CONTROL_SEND:"ch-local-control-send",CH_ALL_NOTES_OFF_SEND:"ch-all-notes-off-send",CH_OMNI_OFF_SEND:"ch-omni-off-send",CH_OMNI_ON_SEND:"ch-omni-on-send",CH_MONO_ON_SEND:"ch-mono-on-send",CH_POLY_ON_SEND:"ch-poly-on-send",SYS_EX_SEND:"sys-ex-send",SYS_EX_RECV:"sys-ex-recv",SYS_CLOCK_RECV:"sys-clock-recv",SYS_START_RECV:"sys-start-recv",SYS_CONTINUE_RECV:"sys-continue-recv",SYS_STOP_RECV:"sys-stop-recv",SYS_MTC_RECV:"sys-mtc-recv",SYS_SONG_POS_RECV:"sys-song-pos-recv",SYS_SONG_SEL_RECV:"sys-song-sel-recv",SYS_TUNE_REQ_RECV:"sys-tune-req-recv",SYS_ACT_SENSE_RECV:"sys-act-sense-recv",SYS_RESET_RECV:"sys-reset-recv",MIDI_RAW:"midi-raw",PATCH_SAVED:"patch-saved",PATCH_LOADED:"patch-loaded",PATCH_DELETED:"patch-deleted"};class Z extends v{constructor(e={}){super(),this.options={inputChannel:1,outputChannel:1,autoConnect:!0,sysex:!1,...e},this.connection=null,this.bindings=new Map,this.state={controlChange:new Map,programChange:new Map,pitchBend:new Map,monoPressure:new Map,polyPressure:new Map},this.initialized=!1,this._initNamespaces()}async init(){if(this.initialized){console.warn("MIDI Controller already initialized");return}try{this.connection=new $({sysex:this.options.sysex}),await this.connection.requestAccess(),this.connection.on(p.DEVICE_CHANGE,async({state:e,type:i,device:n})=>{try{if(e==="connected")i==="output"?this.emit(C.DEV_OUT_CONNECTED,n):i==="input"&&this.emit(C.DEV_IN_CONNECTED,n);else if(e==="disconnected"){if(i==="output"&&n){const s=this.connection.getCurrentOutput();s&&s.id===n.id?await this._disconnectOutput():this.emit(C.DEV_OUT_DISCONNECTED,n)}if(i==="input"&&n){const s=this.connection.getCurrentInput();s&&s.id===n.id?await this._disconnectInput():this.emit(C.DEV_IN_DISCONNECTED,n)}}}catch(s){console.error("Error in device change handler:",s),this.emit(C.ERROR,s)}}),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(C.READY,this),this.options.onReady?.(this)}catch(e){throw this.emit(C.ERROR,e),this.options.onError?.(e),e}}_initNamespaces(){this.device={connect:this._connect.bind(this),disconnect:this._disconnect.bind(this),connectInput:this._connectInput.bind(this),disconnectInput:this._disconnectInput.bind(this),connectOutput:this._connectOutput.bind(this),disconnectOutput:this._disconnectOutput.bind(this),getCurrentOutput:this._getCurrentOutput.bind(this),getCurrentInput:this._getCurrentInput.bind(this),getOutputs:this._getOutputs.bind(this),getInputs:this._getInputs.bind(this)},this.channel={sendNoteOn:this._sendNoteOn.bind(this),sendNoteOff:this._sendNoteOff.bind(this),sendCC:this._sendCC.bind(this),getCC:this._getCC.bind(this),sendPC:this._sendPC.bind(this),getPC:this._getPC.bind(this),sendPitchBend:this._sendPitchBend.bind(this),getPitchBend:this._getPitchBend.bind(this),sendMonoPressure:this._sendMonoPressure.bind(this),getMonoPressure:this._getMonoPressure.bind(this),sendPolyPressure:this._sendPolyPressure.bind(this),getPolyPressure:this._getPolyPressure.bind(this),allSoundsOff:this._allSoundsOff.bind(this),resetControllers:this._resetControllers.bind(this),localControl:this._localControl.bind(this),allNotesOff:this._allNotesOff.bind(this),omniOff:this._omniOff.bind(this),omniOn:this._omniOn.bind(this),monoOn:this._monoOn.bind(this),polyOn:this._polyOn.bind(this)},this.system={sendEx:function(e,i=!1){return this._sendSysEx(e,i)}.bind(this),sendClock:this._sendClock.bind(this),start:this._sendStart.bind(this),continue:this._sendContinue.bind(this),stop:this._sendStop.bind(this),sendMTC:this._sendMTC.bind(this),sendSongPosition:this._sendSongPosition.bind(this),sendSongSelect:this._sendSongSelect.bind(this),sendTuneRequest:this._sendTuneRequest.bind(this),sendActiveSensing:this._sendActiveSensing.bind(this),sendSystemReset:this._sendSystemReset.bind(this)},this.patch={get:this._getPatch.bind(this),set:this._setPatch.bind(this),save:this._savePatch.bind(this),load:this._loadPatch.bind(this),delete:this._deletePatch.bind(this),list:this._listPatches.bind(this)}}bind(e,i,n={}){if(!e)return console.warn("Cannot bind: element is null or undefined"),()=>{};const s=this._createBinding(e,i,n);return this.bindings.set(e,s),this.initialized&&this.connection?.isConnected()&&s.handler({target:e}),()=>this.unbind(e)}_createBinding(e,i,n={}){const{min:s=parseFloat(e.getAttribute("min"))||0,max:r=parseFloat(e.getAttribute("max"))||127,channel:E,invert:o=!1,onInput:h=void 0}=i,{debounce:N=0}=n,u={...i,min:s,max:r,invert:o,onInput:h};if(E!==void 0&&(u.channel=E),i.is14Bit){const{msb:T,lsb:f}=i,U=V=>{const W=parseFloat(V.target.value);if(Number.isNaN(W))return;const{msb:Dt,lsb:Ot}=x(W,s,r,o),Q=E||this.options.outputChannel;this._sendCC(T,Dt,Q),this._sendCC(f,Ot,Q)};let L=null;const M=N>0?V=>{L&&clearTimeout(L),L=setTimeout(()=>{U(V),L=null},N)}:U;return e.addEventListener("input",M),e.addEventListener("change",M),{element:e,config:u,handler:U,destroy:()=>{L&&clearTimeout(L),e.removeEventListener("input",M),e.removeEventListener("change",M)}}}const{cc:a}=i,A=T=>{const f=parseFloat(T.target.value);if(Number.isNaN(f))return;const U=w(f,s,r,o),L=E===void 0?this.options.outputChannel:E;this._sendCC(a,U,L)};let S=null;const D=N>0?T=>{S&&clearTimeout(S),S=setTimeout(()=>{A(T),S=null},N)}:A;return e.addEventListener("input",D),e.addEventListener("change",D),{element:e,config:u,handler:A,destroy:()=>{S&&clearTimeout(S),e.removeEventListener("input",D),e.removeEventListener("change",D)}}}unbind(e){const i=this.bindings.get(e);i&&(i.destroy(),this.bindings.delete(e))}async destroy(){for(const e of this.bindings.values())e.destroy();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(C.DESTROYED),this.removeAllListeners()}async _connect(e){e?await this.connection.connect(e):this.options.output!==void 0?await this.connection.connect(this.options.output):this.options.autoConnect&&await this.connection.connect()}async _disconnect(){this.connection.disconnect()}async _connectInput(e){await this.connection.connectInput(e,i=>{this._handleMIDIMessage(i)}),this.emit(C.DEV_IN_CONNECTED,this.connection.getCurrentInput())}async _disconnectInput(){const e=this.connection.getCurrentInput();this.connection.disconnectInput(),this.emit(C.DEV_IN_DISCONNECTED,e)}async _connectOutput(e){await this.connection.connect(e),this.emit(C.DEV_OUT_CONNECTED,this.connection.getCurrentOutput())}async _disconnectOutput(){const e=this.connection.getCurrentOutput();this.connection.disconnectOutput(),this.emit(C.DEV_OUT_DISCONNECTED,e)}_getCurrentOutput(){return this.connection?.getCurrentOutput()||null}_getCurrentInput(){return this.connection?.getCurrentInput()||null}_getOutputs(){return this.connection?.getOutputs()||[]}_getInputs(){return this.connection?.getInputs()||[]}send(e){if(!this.initialized){console.warn("MIDI not initialized. Call init() first.");return}this.connection.send(e)}_sendNoteOn(e,i=64,n=this.options.outputChannel){if(!this.initialized)return;e=O(Math.round(e),0,127),i=O(Math.round(i),0,127),n=O(Math.round(n),1,16);const s=144+(n-1);this.connection.send([s,e,i]),this.emit(C.CH_NOTE_ON_SEND,{note:e,velocity:i,channel:n})}_sendNoteOff(e,i=this.options.outputChannel,n=0){if(!this.initialized)return;e=O(Math.round(e),0,127),n=O(Math.round(n),0,127),i=O(Math.round(i),1,16);const s=144+(i-1);this.connection.send([s,e,n]),this.emit(C.CH_NOTE_OFF_SEND,{note:e,channel:i,velocity:n})}_sendCC(e,i,n=this.options.outputChannel){if(!this.initialized){console.warn("MIDI not initialized. Call init() first.");return}e=O(Math.round(e),0,127),i=O(Math.round(i),0,127),n=O(Math.round(n),1,16);const s=176+(n-1);this.connection.send([s,e,i]);const r=`${n}:${e}`;this.state.controlChange.set(r,i),this.emit(C.CH_CC_SEND,{cc:e,value:i,channel:n})}_sendPC(e,i=this.options.outputChannel){if(!this.initialized)return;e=O(Math.round(e),0,127),i=O(Math.round(i),1,16);const n=192+(i-1);this.connection.send([n,e]),this.state.programChange.set(i.toString(),e),this.emit(C.CH_PC_SEND,{program:e,channel:i})}_getPC(e=this.options.inputChannel){return this.state.programChange.get(e.toString())}_getCC(e,i=this.options.inputChannel){const n=`${i}:${e}`;return this.state.controlChange.get(n)}_sendPitchBend(e,i=this.options.outputChannel){if(!this.initialized)return;e=O(Math.round(e),0,16383),i=O(Math.round(i),1,16);const n=224+(i-1),s=e&127,r=e>>7&127;this.connection.send([n,s,r]),this.state.pitchBend.set(i.toString(),e),this.emit(C.CH_PITCH_BEND_SEND,{value:e,channel:i})}_getPitchBend(e=this.options.inputChannel){return this.state.pitchBend.get(e.toString())}_sendMonoPressure(e,i=this.options.outputChannel){if(!this.initialized)return;e=O(Math.round(e),0,127),i=O(Math.round(i),1,16);const n=208+(i-1);this.connection.send([n,e]),this.state.monoPressure.set(i.toString(),e),this.emit(C.CH_MONO_PRESS_SEND,{pressure:e,channel:i})}_getMonoPressure(e=this.options.inputChannel){return this.state.monoPressure.get(e.toString())}_sendPolyPressure(e,i,n=this.options.outputChannel){if(!this.initialized)return;e=O(Math.round(e),0,127),i=O(Math.round(i),0,127),n=O(Math.round(n),1,16);const s=160+(n-1);this.connection.send([s,e,i]);const r=`${n}:${e}`;this.state.polyPressure.set(r,i),this.emit(C.CH_POLY_PRESS_SEND,{note:e,pressure:i,channel:n})}_getPolyPressure(e,i=this.options.inputChannel){const n=`${i}:${e}`;return this.state.polyPressure.get(n)}_allSoundsOff(e){if(!this.initialized){console.warn("MIDI not initialized. Call init() first.");return}if(e!==void 0){e=O(Math.round(e),1,16);const i=176+(e-1);this.connection.send([i,120,0]),this.emit(C.CH_ALL_SOUNDS_OFF_SEND,{channel:e})}else{for(let i=1;i<=16;i++){const n=176+(i-1);this.connection.send([n,120,0])}this.emit(C.CH_ALL_SOUNDS_OFF_SEND,{channel:null})}}_resetControllers(e){if(!this.initialized){console.warn("MIDI not initialized. Call init() first.");return}if(e!==void 0){e=O(Math.round(e),1,16);const i=176+(e-1);this.connection.send([i,121,0]),this.emit(C.CH_RESET_CONTROLLERS_SEND,{channel:e})}else{for(let i=1;i<=16;i++){const n=176+(i-1);this.connection.send([n,121,0])}this.emit(C.CH_RESET_CONTROLLERS_SEND,{channel:null})}}_localControl(e,i){if(!this.initialized){console.warn("MIDI not initialized. Call init() first.");return}const n=e?127:0;if(i!==void 0){i=O(Math.round(i),1,16);const s=176+(i-1);this.connection.send([s,122,n]),this.emit(C.CH_LOCAL_CONTROL_SEND,{enabled:e,channel:i})}else{for(let s=1;s<=16;s++){const r=176+(s-1);this.connection.send([r,122,n])}this.emit(C.CH_LOCAL_CONTROL_SEND,{enabled:e,channel:null})}}_allNotesOff(e){if(!this.initialized){console.warn("MIDI not initialized. Call init() first.");return}if(e!==void 0){e=O(Math.round(e),1,16);const i=176+(e-1);this.connection.send([i,123,0]),this.emit(C.CH_ALL_NOTES_OFF_SEND,{channel:e})}else{for(let i=1;i<=16;i++){const n=176+(i-1);this.connection.send([n,123,0])}this.emit(C.CH_ALL_NOTES_OFF_SEND,{channel:null})}}_omniOff(e){if(!this.initialized){console.warn("MIDI not initialized. Call init() first.");return}if(e!==void 0){e=O(Math.round(e),1,16);const i=176+(e-1);this.connection.send([i,124,0]),this.emit(C.CH_OMNI_OFF_SEND,{channel:e})}else{for(let i=1;i<=16;i++){const n=176+(i-1);this.connection.send([n,124,0])}this.emit(C.CH_OMNI_OFF_SEND,{channel:null})}}_omniOn(e){if(!this.initialized){console.warn("MIDI not initialized. Call init() first.");return}if(e!==void 0){e=O(Math.round(e),1,16);const i=176+(e-1);this.connection.send([i,125,0]),this.emit(C.CH_OMNI_ON_SEND,{channel:e})}else{for(let i=1;i<=16;i++){const n=176+(i-1);this.connection.send([n,125,0])}this.emit(C.CH_OMNI_ON_SEND,{channel:null})}}_monoOn(e=1,i){if(!this.initialized){console.warn("MIDI not initialized. Call init() first.");return}if(e=Math.max(0,Math.min(16,Math.round(e))),i!==void 0){i=O(Math.round(i),1,16);const n=176+(i-1);this.connection.send([n,126,e]),this.emit(C.CH_MONO_ON_SEND,{channels:e,channel:i})}else{for(let n=1;n<=16;n++){const s=176+(n-1);this.connection.send([s,126,e])}this.emit(C.CH_MONO_ON_SEND,{channels:e,channel:null})}}_polyOn(e){if(!this.initialized){console.warn("MIDI not initialized. Call init() first.");return}if(e!==void 0){e=O(Math.round(e),1,16);const i=176+(e-1);this.connection.send([i,127,0]),this.emit(C.CH_POLY_ON_SEND,{channel:e})}else{for(let i=1;i<=16;i++){const n=176+(i-1);this.connection.send([n,127,0])}this.emit(C.CH_POLY_ON_SEND,{channel:null})}}_sendSysEx(e,i=!1){if(!this.initialized){console.warn("MIDI not initialized. Call init() first.");return}if(!this.options.sysex){console.warn("SysEx not enabled. Initialize with sysex: true");return}this.connection.sendSysEx(e,i),this.emit(C.SYS_EX_SEND,{data:e,includeWrapper:i})}_sendClock(){if(!this.initialized){console.warn("MIDI not initialized. Call init() first.");return}this.connection.send([248])}_sendStart(){if(!this.initialized){console.warn("MIDI not initialized. Call init() first.");return}this.connection.send([250])}_sendContinue(){if(!this.initialized){console.warn("MIDI not initialized. Call init() first.");return}this.connection.send([251])}_sendStop(){if(!this.initialized){console.warn("MIDI not initialized. Call init() first.");return}this.connection.send([252])}_sendMTC(e){if(!this.initialized){console.warn("MIDI not initialized. Call init() first.");return}e=O(Math.round(e),0,127),this.connection.send([241,e])}_sendSongPosition(e){if(!this.initialized){console.warn("MIDI not initialized. Call init() first.");return}e=O(Math.round(e),0,16383);const i=e&127,n=e>>7&127;this.connection.send([242,i,n])}_sendSongSelect(e){if(!this.initialized){console.warn("MIDI not initialized. Call init() first.");return}e=O(Math.round(e),0,127),this.connection.send([243,e])}_sendTuneRequest(){if(!this.initialized){console.warn("MIDI not initialized. Call init() first.");return}this.connection.send([246])}_sendActiveSensing(){if(!this.initialized){console.warn("MIDI not initialized. Call init() first.");return}this.connection.send([254])}_sendSystemReset(){if(!this.initialized){console.warn("MIDI not initialized. Call init() first.");return}this.connection.send([255])}_handleMIDIMessage(e){const[i,n,s]=e.data,r=i&240,E=(i&15)+1;if(i===248){this.emit(C.SYS_CLOCK_RECV,{timestamp:e.midiwire});return}if(i===250){this.emit(C.SYS_START_RECV,{timestamp:e.midiwire});return}if(i===251){this.emit(C.SYS_CONTINUE_RECV,{timestamp:e.midiwire});return}if(i===252){this.emit(C.SYS_STOP_RECV,{timestamp:e.midiwire});return}if(i===254){this.emit(C.SYS_ACT_SENSE_RECV,{timestamp:e.midiwire});return}if(i===255){this.emit(C.SYS_RESET_RECV,{timestamp:e.midiwire});return}if(i===240){this.emit(C.SYS_EX_RECV,{data:Array.from(e.data),timestamp:e.midiwire});return}if(i===241){this.emit(C.SYS_MTC_RECV,{data:n,timestamp:e.midiwire});return}if(i===242){const o=n+(s<<7);this.emit(C.SYS_SONG_POS_RECV,{position:o,timestamp:e.midiwire});return}if(i===243){this.emit(C.SYS_SONG_SEL_RECV,{song:n,timestamp:e.midiwire});return}if(i===246){this.emit(C.SYS_TUNE_REQ_RECV,{timestamp:e.midiwire});return}if(i===247){this.emit(C.MIDI_RAW,{status:i,data:[n,s],channel:E,timestamp:e.midiwire});return}if(r===176){const o=`${E}:${n}`;this.state.controlChange.set(o,s),this.emit(C.CH_CC_RECV,{cc:n,value:s,channel:E});return}if(r===192){this.state.programChange.set(E.toString(),n),this.emit(C.CH_PC_RECV,{program:n,channel:E});return}if(r===224){const o=n+(s<<7);this.state.pitchBend.set(E.toString(),o),this.emit(C.CH_PITCH_BEND_RECV,{value:o,channel:E});return}if(r===208){this.state.monoPressure.set(E.toString(),n),this.emit(C.CH_MONO_PRESS_RECV,{pressure:n,channel:E});return}if(r===160){const o=`${E}:${n}`;this.state.polyPressure.set(o,s),this.emit(C.CH_POLY_PRESS_RECV,{note:n,pressure:s,channel:E});return}if(r===144&&s>0){this.emit(C.CH_NOTE_ON_RECV,{note:n,velocity:s,channel:E});return}if(r===128||r===144&&s===0){this.emit(C.CH_NOTE_OFF_RECV,{note:n,channel:E});return}this.emit(C.MIDI_RAW,{status:i,data:[n,s],channel:E,timestamp:e.midiwire})}_getPatch(e="Unnamed Patch"){const i={name:e,device:this._getCurrentOutput()?.name||null,timestamp:new Date().toISOString(),version:"1.0",channels:{},settings:{}};for(const[n,s]of this.state.controlChange.entries()){const[r,E]=n.split(":").map(Number);i.channels[r]||(i.channels[r]={ccs:{},notes:{}}),i.channels[r].ccs[E]=s}for(const[n,s]of this.state.programChange.entries()){const r=parseInt(n,10);i.channels[r]||(i.channels[r]={ccs:{},notes:{}}),i.channels[r].program=s}for(const[n,s]of this.state.pitchBend.entries()){const r=parseInt(n,10);i.channels[r]||(i.channels[r]={ccs:{},notes:{}}),i.channels[r].pitchBend=s}for(const[n,s]of this.state.monoPressure.entries()){const r=parseInt(n,10);i.channels[r]||(i.channels[r]={ccs:{},notes:{}}),i.channels[r].monoPressure=s}for(const[n,s]of this.state.polyPressure.entries()){const[r,E]=n.split(":").map(Number),o=parseInt(r,10);i.channels[o]||(i.channels[o]={ccs:{},notes:{}}),i.channels[o].polyPressure||(i.channels[o].polyPressure={}),i.channels[o].polyPressure[E]=s}for(const[n,s]of this.bindings.entries()){const{config:r}=s;if(r.cc){const E=`cc${r.cc}`;i.settings[E]={min:r.min,max:r.max,invert:r.invert||!1,is14Bit:r.is14Bit||!1,label:n.getAttribute?.("data-midi-label")||null,elementId:n.id||null}}}return i}async _setPatch(e){if(!e||!e.channels)throw new g("Invalid patch format","patch");const i=e.version||"1.0";i==="1.0"?await this._applyPatchV1(e):(console.warn(`Unknown patch version: ${i}. Attempting to apply as v1.0`),await this._applyPatchV1(e)),this.emit(C.PATCH_LOADED,{patch:e})}async _applyPatchV1(e){for(const[i,n]of Object.entries(e.channels)){const s=parseInt(i,10);if(n.ccs)for(const[r,E]of Object.entries(n.ccs)){const o=parseInt(r,10);this._sendCC(o,E,s)}if(n.program!==void 0&&this._sendPC(n.program,s),n.pitchBend!==void 0&&this._sendPitchBend(n.pitchBend,s),n.monoPressure!==void 0&&this._sendMonoPressure(n.monoPressure,s),n.polyPressure)for(const[r,E]of Object.entries(n.polyPressure)){const o=parseInt(r,10);this._sendPolyPressure(o,E,s)}if(n.notes)for(const[r,E]of Object.entries(n.notes)){const o=parseInt(r,10);E>0?this._sendNoteOn(o,E,s):this._sendNoteOff(o,s)}}if(e.settings)for(const[i,n]of Object.entries(e.settings))for(const[s,r]of this.bindings.entries())r.config.cc?.toString()===i.replace("cc","")&&(s.min!==void 0&&n.min!==void 0&&(s.min=String(n.min)),s.max!==void 0&&n.max!==void 0&&(s.max=String(n.max)));for(const[i,n]of this.bindings.entries()){const{config:s}=n;if(s.cc!==void 0){const r=s.channel||this.options.inputChannel,E=e.channels[r];if(E?.ccs){const o=E.ccs[s.cc];if(o!==void 0){const h=s.min!==void 0?s.min:parseFloat(i.getAttribute?.("min"))||0,N=s.max!==void 0?s.max:parseFloat(i.getAttribute?.("max"))||127,u=s.invert||!1;let a;u?a=N-o/127*(N-h):a=h+o/127*(N-h),s.onInput&&typeof s.onInput=="function"?s.onInput(a):(i.value=a,i.dispatchEvent(new Event("input",{bubbles:!0})))}}}}}_savePatch(e,i=null){const n=i||this._getPatch(e),s=`midiwire_patch_${e}`;try{return localStorage.setItem(s,JSON.stringify(n)),this.emit(C.PATCH_SAVED,{name:e,patch:n}),s}catch(r){throw console.error("Failed to save patch:",r),r}}_loadPatch(e){const i=`midiwire_patch_${e}`;try{const n=localStorage.getItem(i);if(!n)return null;const s=JSON.parse(n);return this.emit(C.PATCH_LOADED,{name:e,patch:s}),s}catch(n){return console.error("Failed to load patch:",n),null}}_deletePatch(e){const i=`midiwire_patch_${e}`;try{return localStorage.removeItem(i),this.emit(C.PATCH_DELETED,{name:e}),!0}catch(n){return console.error("Failed to delete patch:",n),!1}}_listPatches(){const e=[];try{for(let i=0;i<localStorage.length;i++){const n=localStorage.key(i);if(n?.startsWith("midiwire_patch_")){const s=n.replace("midiwire_patch_",""),r=this._loadPatch(s);r&&e.push({name:s,patch:r})}}}catch(i){console.error("Failed to list patches:",i)}return e.sort((i,n)=>i.name.localeCompare(n.name))}}class z{constructor(e={}){this.midi=e.midiController||null,this.onStatusUpdate=e.onStatusUpdate||(()=>{}),this.onConnectionUpdate=e.onConnectionUpdate||(()=>{}),this.channel=e.channel||1,this.currentOutput=null,this.currentInput=null,this.isConnecting=!1}async setupSelectors(e={},i={}){if(!this.midi)throw new Error("MIDI controller not initialized. Pass midiController in constructor options.");const{output:n,input:s,channel:r}=e,E=this._resolveSelector(n),o=this._resolveSelector(s),h=this._resolveSelector(r);if(this._setupDeviceChangeListeners({output:E,input:o},i.onDeviceListChange),E){await this._populateOutputDeviceList(E);const N=i.onConnect?async(a,A)=>i.onConnect({midi:a,device:A,type:"output"}):void 0,u=i.onDisconnect?async a=>i.onDisconnect({midi:a,type:"output"}):void 0;this._connectOutputDeviceSelection(E,N,u)}if(o){await this._populateInputDeviceList(o);const N=i.onConnect?async(a,A)=>i.onConnect({midi:a,device:A,type:"input"}):void 0,u=i.onDisconnect?async a=>i.onDisconnect({midi:a,type:"input"}):void 0;this._connectInputDeviceSelection(o,N,u)}return h&&this._connectChannelSelection(h,"output"),this.midi}updateStatus(e,i=""){this.onStatusUpdate(e,i)}updateConnectionStatus(){this.onConnectionUpdate(this.currentOutput,this.currentInput,this.midi)}_setupDeviceChangeListeners(e={},i){!this.midi||this._listenersInitialized||(this._listenersInitialized=!0,this.midi.on(C.DEV_OUT_CONNECTED,async n=>{this.updateStatus(`Output device connected: ${n?.name||"Unknown"}`,"connected"),e.output&&await this._populateOutputDeviceList(e.output),i&&i()}),this.midi.on(C.DEV_OUT_DISCONNECTED,async n=>{this.updateStatus(`Output device disconnected: ${n?.name||"Unknown"}`,"error"),this.currentOutput&&n?.name===this.currentOutput.name&&(this.currentOutput=null,this.updateConnectionStatus(),e.output&&(e.output.value="")),e.output&&await this._populateOutputDeviceList(e.output),i&&i()}),this.midi.on(C.DEV_IN_CONNECTED,async n=>{this.updateStatus(`Input device connected: ${n?.name||"Unknown"}`,"connected"),e.input&&await this._populateInputDeviceList(e.input),i&&i()}),this.midi.on(C.DEV_IN_DISCONNECTED,async n=>{this.updateStatus(`Input device disconnected: ${n?.name||"Unknown"}`,"error"),e.input&&(e.input.value="",await this._populateInputDeviceList(e.input)),i&&i()}))}_resolveSelector(e){if(typeof e=="string"){const i=document.querySelector(e);return i||console.warn(`MIDIDeviceManager: Selector "${e}" not found`),i}return e||null}_getOutputDevices(){return this.midi?this.midi.device.getOutputs():[]}_getInputDevices(){return this.midi?this.midi.device.getInputs():[]}_connectOutputDeviceSelection(e,i,n){!e||!this.midi||e.addEventListener("change",async s=>{if(this.isConnecting)return;this.isConnecting=!0;const r=s.target.value;if(!r){this.currentOutput&&this.midi&&(await this.midi.device.disconnectOutput(),this.currentOutput=null,this.updateStatus("Output device disconnected",""),this.updateConnectionStatus()),this.isConnecting=!1,n&&await n(this.midi);return}try{if(await this.midi.device.connectOutput(parseInt(r,10)),this.currentOutput=this.midi.device.getCurrentOutput(),this.currentOutput){const o=this.midi.device.getOutputs().findIndex(h=>h.id===this.currentOutput.id);o!==-1&&(e.value=o.toString())}this.updateConnectionStatus(),i&&await i(this.midi,this.currentOutput)}catch(E){this.updateStatus(`Output connection failed: ${E.message}`,"error")}finally{this.isConnecting=!1}})}_connectInputDeviceSelection(e,i,n){!e||!this.midi||e.addEventListener("change",async s=>{const r=s.target.value;if(!r){this.midi&&(await this.midi.device.disconnectInput(),this.updateStatus("Input device disconnected",""),this.updateConnectionStatus()),n&&await n(this.midi);return}if(!this.isConnecting){this.isConnecting=!0;try{await this.midi.device.connectInput(parseInt(r,10));const E=this.midi.device.getCurrentInput();this.updateConnectionStatus(),i&&await i(this.midi,E)}catch(E){this.updateStatus(`Input connection failed: ${E.message}`,"error")}finally{this.isConnecting=!1}}})}_populateDeviceList(e,i,n,s,r){if(i.length>0){if(e.innerHTML='<option value="">Select a device</option>'+i.map((E,o)=>`<option value="${o}">${E.name}</option>`).join(""),n){const E=i.findIndex(o=>o.name===n.name);E!==-1?e.value=E.toString():(e.value="",r&&(this.currentOutput=null,this.updateConnectionStatus()))}else e.value="";e.disabled=!1,r&&!this.currentOutput&&this.updateStatus("Select a device")}else e.innerHTML='<option value="">No devices connected</option>',e.disabled=!0,r&&this.updateStatus("No devices connected","error");s&&s()}async _populateOutputDeviceList(e,i){if(!e||!this.midi)return;const n=this._getOutputDevices();this._populateDeviceList(e,n,this.currentOutput,i,!0)}async _populateInputDeviceList(e,i){if(!e||!this.midi)return;const n=this._getInputDevices(),s=this.midi.device.getCurrentInput();this._populateDeviceList(e,n,s,i,!1)}_connectChannelSelection(e,i){if(!e||!this.midi)return;const n=i==="input"?"inputChannel":"outputChannel";e.addEventListener("change",s=>{this.midi&&(this.midi.options[n]=parseInt(s.target.value,10),this.updateConnectionStatus())})}}const t=class t{constructor(e,i=0){if(e.length!==t.PACKED_SIZE)throw new d(`Invalid voice data length: expected ${t.PACKED_SIZE} bytes, got ${e.length}`,"length",e.length);this.index=i,this.data=new Uint8Array(e),this.name=this._extractName(),this._unpackedCache=null}_extractName(){const e=this.data.subarray(t.PACKED_NAME_START,t.PACKED_NAME_START+t.NAME_LENGTH);return Array.from(e).map(n=>{let s=n&t.MASK_7BIT;return s===t.CHAR_YEN&&(s=t.CHAR_REPLACEMENT_Y),s===t.CHAR_ARROW_RIGHT&&(s=t.CHAR_REPLACEMENT_GT),s===t.CHAR_ARROW_LEFT&&(s=t.CHAR_REPLACEMENT_LT),(s<t.CHAR_MIN_PRINTABLE||s>t.CHAR_MAX_PRINTABLE)&&(s=t.CHAR_SPACE),String.fromCharCode(s)}).join("").trim()}getParameter(e){if(e<0||e>=t.PACKED_SIZE)throw new d(`Parameter offset out of range: ${e} (must be 0-${t.PACKED_SIZE-1})`,"offset",e);return this.data[e]&t.MASK_7BIT}getUnpackedParameter(e){if(e<0||e>=t.UNPACKED_SIZE)throw new d(`Unpacked parameter offset out of range: ${e} (must be 0-${t.UNPACKED_SIZE-1})`,"offset",e);return this._unpackedCache||(this._unpackedCache=this.unpack()),this._unpackedCache[e]&t.MASK_7BIT}setParameter(e,i){if(e<0||e>=t.PACKED_SIZE)throw new d(`Parameter offset out of range: ${e} (must be 0-${t.PACKED_SIZE-1})`,"offset",e);this.data[e]=i&t.MASK_7BIT,this._unpackedCache=null,e>=t.PACKED_NAME_START&&e<t.PACKED_NAME_START+t.NAME_LENGTH&&(this.name=this._extractName())}unpack(){const e=this.data,i=new Uint8Array(t.UNPACKED_SIZE);return this._unpackOperators(e,i),this._unpackPitchEG(e,i),this._unpackGlobalParams(e,i),this._unpackName(e,i),i}_unpackOperators(e,i){for(let n=0;n<t.NUM_OPERATORS;n++){const s=(t.NUM_OPERATORS-1-n)*t.PACKED_OP_SIZE,r=n*t.UNPACKED_OP_SIZE;this._unpackOperator(e,i,s,r)}}_unpackOperator(e,i,n,s){this._unpackOperatorEG(e,i,n,s),this._unpackOperatorScaling(e,i,n,s),this._unpackOperatorPackedParams(e,i,n,s),this._unpackOperatorFrequency(e,i,n,s)}_unpackOperatorEG(e,i,n,s){i[s+t.UNPACKED_OP_EG_RATE_1]=e[n+t.PACKED_OP_EG_RATE_1]&t.MASK_7BIT,i[s+t.UNPACKED_OP_EG_RATE_2]=e[n+t.PACKED_OP_EG_RATE_2]&t.MASK_7BIT,i[s+t.UNPACKED_OP_EG_RATE_3]=e[n+t.PACKED_OP_EG_RATE_3]&t.MASK_7BIT,i[s+t.UNPACKED_OP_EG_RATE_4]=e[n+t.PACKED_OP_EG_RATE_4]&t.MASK_7BIT,i[s+t.UNPACKED_OP_EG_LEVEL_1]=e[n+t.PACKED_OP_EG_LEVEL_1]&t.MASK_7BIT,i[s+t.UNPACKED_OP_EG_LEVEL_2]=e[n+t.PACKED_OP_EG_LEVEL_2]&t.MASK_7BIT,i[s+t.UNPACKED_OP_EG_LEVEL_3]=e[n+t.PACKED_OP_EG_LEVEL_3]&t.MASK_7BIT,i[s+t.UNPACKED_OP_EG_LEVEL_4]=e[n+t.PACKED_OP_EG_LEVEL_4]&t.MASK_7BIT}_unpackOperatorScaling(e,i,n,s){i[s+t.UNPACKED_OP_BREAK_POINT]=e[n+t.PACKED_OP_BREAK_POINT]&t.MASK_7BIT,i[s+t.UNPACKED_OP_L_SCALE_DEPTH]=e[n+t.PACKED_OP_L_SCALE_DEPTH]&t.MASK_7BIT,i[s+t.UNPACKED_OP_R_SCALE_DEPTH]=e[n+t.PACKED_OP_R_SCALE_DEPTH]&t.MASK_7BIT}_unpackOperatorPackedParams(e,i,n,s){const r=e[n+t.PACKED_OP_CURVES]&t.MASK_7BIT;i[s+t.UNPACKED_OP_L_CURVE]=r&t.MASK_2BIT,i[s+t.UNPACKED_OP_R_CURVE]=r>>2&t.MASK_2BIT;const E=e[n+t.PACKED_OP_RATE_SCALING]&t.MASK_7BIT;i[s+t.UNPACKED_OP_RATE_SCALING]=E&t.MASK_3BIT,i[s+t.UNPACKED_OP_DETUNE]=E>>3&t.MASK_4BIT;const o=e[n+t.PACKED_OP_MOD_SENS]&t.MASK_7BIT;i[s+t.UNPACKED_OP_AMP_MOD_SENS]=o&t.MASK_2BIT,i[s+t.UNPACKED_OP_KEY_VEL_SENS]=o>>2&t.MASK_3BIT,i[s+t.UNPACKED_OP_OUTPUT_LEVEL]=e[n+t.PACKED_OP_OUTPUT_LEVEL]&t.MASK_7BIT}_unpackOperatorFrequency(e,i,n,s){const r=e[n+t.PACKED_OP_MODE_FREQ]&t.MASK_7BIT;i[s+t.UNPACKED_OP_MODE]=r&t.MASK_1BIT,i[s+t.UNPACKED_OP_FREQ_COARSE]=r>>1&t.MASK_5BIT,i[s+t.UNPACKED_OP_FREQ_FINE]=e[n+t.PACKED_OP_DETUNE_FINE]&t.MASK_7BIT}_unpackPitchEG(e,i){i[t.UNPACKED_PITCH_EG_RATE_1]=e[t.PACKED_PITCH_EG_RATE_1]&t.MASK_7BIT,i[t.UNPACKED_PITCH_EG_RATE_2]=e[t.PACKED_PITCH_EG_RATE_2]&t.MASK_7BIT,i[t.UNPACKED_PITCH_EG_RATE_3]=e[t.PACKED_PITCH_EG_RATE_3]&t.MASK_7BIT,i[t.UNPACKED_PITCH_EG_RATE_4]=e[t.PACKED_PITCH_EG_RATE_4]&t.MASK_7BIT,i[t.UNPACKED_PITCH_EG_LEVEL_1]=e[t.PACKED_PITCH_EG_LEVEL_1]&t.MASK_7BIT,i[t.UNPACKED_PITCH_EG_LEVEL_2]=e[t.PACKED_PITCH_EG_LEVEL_2]&t.MASK_7BIT,i[t.UNPACKED_PITCH_EG_LEVEL_3]=e[t.PACKED_PITCH_EG_LEVEL_3]&t.MASK_7BIT,i[t.UNPACKED_PITCH_EG_LEVEL_4]=e[t.PACKED_PITCH_EG_LEVEL_4]&t.MASK_7BIT}_unpackGlobalParams(e,i){i[t.UNPACKED_ALGORITHM]=e[t.OFFSET_ALGORITHM]&t.MASK_5BIT;const n=e[t.OFFSET_FEEDBACK]&t.MASK_7BIT;i[t.UNPACKED_FEEDBACK]=n&t.MASK_3BIT,i[t.UNPACKED_OSC_SYNC]=n>>3&t.MASK_1BIT,i[t.UNPACKED_LFO_SPEED]=e[t.OFFSET_LFO_SPEED]&t.MASK_7BIT,i[t.UNPACKED_LFO_DELAY]=e[t.OFFSET_LFO_DELAY]&t.MASK_7BIT,i[t.UNPACKED_LFO_PM_DEPTH]=e[t.OFFSET_LFO_PM_DEPTH]&t.MASK_7BIT,i[t.UNPACKED_LFO_AM_DEPTH]=e[t.OFFSET_LFO_AM_DEPTH]&t.MASK_7BIT;const s=e[t.OFFSET_LFO_SYNC_WAVE]&t.MASK_7BIT;i[t.UNPACKED_LFO_KEY_SYNC]=s&t.MASK_1BIT,i[t.UNPACKED_LFO_WAVE]=s>>1&t.MASK_3BIT,i[t.UNPACKED_LFO_PM_SENS]=s>>4&t.MASK_3BIT,i[t.UNPACKED_AMP_MOD_SENS]=e[t.OFFSET_AMP_MOD_SENS]&t.MASK_7BIT,i[t.UNPACKED_TRANSPOSE]=e[t.OFFSET_TRANSPOSE]&t.MASK_7BIT,i[t.UNPACKED_EG_BIAS_SENS]=e[t.OFFSET_EG_BIAS_SENS]&t.MASK_7BIT}_unpackName(e,i){for(let n=0;n<t.NAME_LENGTH;n++)i[t.UNPACKED_NAME_START+n]=e[t.PACKED_NAME_START+n]&t.MASK_7BIT}static pack(e){if(e.length!==t.UNPACKED_SIZE)throw new d(`Invalid unpacked data length: expected ${t.UNPACKED_SIZE} bytes, got ${e.length}`,"length",e.length);const i=new Uint8Array(t.PACKED_SIZE);return t._packOperators(e,i),t._packPitchEG(e,i),t._packGlobalParams(e,i),t._packName(e,i),i}static _packOperators(e,i){for(let n=0;n<t.NUM_OPERATORS;n++){const s=n*t.UNPACKED_OP_SIZE,r=(t.NUM_OPERATORS-1-n)*t.PACKED_OP_SIZE;t._packOperator(e,i,s,r)}}static _packOperator(e,i,n,s){t._packOperatorEG(e,i,n,s),t._packOperatorScaling(e,i,n,s),t._packOperatorPackedParams(e,i,n,s),t._packOperatorFrequency(e,i,n,s)}static _packOperatorEG(e,i,n,s){i[s+t.PACKED_OP_EG_RATE_1]=e[n+t.UNPACKED_OP_EG_RATE_1],i[s+t.PACKED_OP_EG_RATE_2]=e[n+t.UNPACKED_OP_EG_RATE_2],i[s+t.PACKED_OP_EG_RATE_3]=e[n+t.UNPACKED_OP_EG_RATE_3],i[s+t.PACKED_OP_EG_RATE_4]=e[n+t.UNPACKED_OP_EG_RATE_4],i[s+t.PACKED_OP_EG_LEVEL_1]=e[n+t.UNPACKED_OP_EG_LEVEL_1],i[s+t.PACKED_OP_EG_LEVEL_2]=e[n+t.UNPACKED_OP_EG_LEVEL_2],i[s+t.PACKED_OP_EG_LEVEL_3]=e[n+t.UNPACKED_OP_EG_LEVEL_3],i[s+t.PACKED_OP_EG_LEVEL_4]=e[n+t.UNPACKED_OP_EG_LEVEL_4]}static _packOperatorScaling(e,i,n,s){i[s+t.PACKED_OP_BREAK_POINT]=e[n+t.UNPACKED_OP_BREAK_POINT],i[s+t.PACKED_OP_L_SCALE_DEPTH]=e[n+t.UNPACKED_OP_L_SCALE_DEPTH],i[s+t.PACKED_OP_R_SCALE_DEPTH]=e[n+t.UNPACKED_OP_R_SCALE_DEPTH]}static _packOperatorPackedParams(e,i,n,s){const r=e[n+t.UNPACKED_OP_L_CURVE]&t.MASK_2BIT,E=e[n+t.UNPACKED_OP_R_CURVE]&t.MASK_2BIT;i[s+t.PACKED_OP_CURVES]=r|E<<2;const o=e[n+t.UNPACKED_OP_RATE_SCALING]&t.MASK_3BIT,h=e[n+t.UNPACKED_OP_DETUNE]&t.MASK_4BIT;i[s+t.PACKED_OP_RATE_SCALING]=o|h<<3;const N=e[n+t.UNPACKED_OP_AMP_MOD_SENS]&t.MASK_2BIT,u=e[n+t.UNPACKED_OP_KEY_VEL_SENS]&t.MASK_3BIT;i[s+t.PACKED_OP_MOD_SENS]=N|u<<2,i[s+t.PACKED_OP_OUTPUT_LEVEL]=e[n+t.UNPACKED_OP_OUTPUT_LEVEL]}static _packOperatorFrequency(e,i,n,s){const r=e[n+t.UNPACKED_OP_MODE]&t.MASK_1BIT,E=e[n+t.UNPACKED_OP_FREQ_COARSE]&t.MASK_5BIT;i[s+t.PACKED_OP_MODE_FREQ]=r|E<<1,i[s+t.PACKED_OP_DETUNE_FINE]=e[n+t.UNPACKED_OP_FREQ_FINE]&t.MASK_7BIT}static _packPitchEG(e,i){i[t.PACKED_PITCH_EG_RATE_1]=e[t.UNPACKED_PITCH_EG_RATE_1],i[t.PACKED_PITCH_EG_RATE_2]=e[t.UNPACKED_PITCH_EG_RATE_2],i[t.PACKED_PITCH_EG_RATE_3]=e[t.UNPACKED_PITCH_EG_RATE_3],i[t.PACKED_PITCH_EG_RATE_4]=e[t.UNPACKED_PITCH_EG_RATE_4],i[t.PACKED_PITCH_EG_LEVEL_1]=e[t.UNPACKED_PITCH_EG_LEVEL_1],i[t.PACKED_PITCH_EG_LEVEL_2]=e[t.UNPACKED_PITCH_EG_LEVEL_2],i[t.PACKED_PITCH_EG_LEVEL_3]=e[t.UNPACKED_PITCH_EG_LEVEL_3],i[t.PACKED_PITCH_EG_LEVEL_4]=e[t.UNPACKED_PITCH_EG_LEVEL_4]}static _packGlobalParams(e,i){i[t.OFFSET_ALGORITHM]=e[t.UNPACKED_ALGORITHM];const n=e[t.UNPACKED_FEEDBACK]&t.MASK_3BIT,s=e[t.UNPACKED_OSC_SYNC]&t.MASK_1BIT;i[t.OFFSET_FEEDBACK]=n|s<<3,i[t.OFFSET_LFO_SPEED]=e[t.UNPACKED_LFO_SPEED],i[t.OFFSET_LFO_DELAY]=e[t.UNPACKED_LFO_DELAY],i[t.OFFSET_LFO_PM_DEPTH]=e[t.UNPACKED_LFO_PM_DEPTH],i[t.OFFSET_LFO_AM_DEPTH]=e[t.UNPACKED_LFO_AM_DEPTH];const r=e[t.UNPACKED_LFO_KEY_SYNC]&t.MASK_1BIT,E=e[t.UNPACKED_LFO_WAVE]&t.MASK_3BIT,o=e[t.UNPACKED_LFO_PM_SENS]&t.MASK_3BIT;i[t.OFFSET_LFO_SYNC_WAVE]=r|E<<1|o<<4,i[t.OFFSET_AMP_MOD_SENS]=e[t.UNPACKED_AMP_MOD_SENS],i[t.OFFSET_TRANSPOSE]=e[t.UNPACKED_TRANSPOSE],i[t.OFFSET_EG_BIAS_SENS]=e[t.UNPACKED_EG_BIAS_SENS]}static _packName(e,i){for(let n=0;n<t.NAME_LENGTH;n++)i[t.PACKED_NAME_START+n]=e[t.UNPACKED_NAME_START+n]}static createDefault(e=0){const i=new Uint8Array(t.UNPACKED_SIZE);for(let r=0;r<t.NUM_OPERATORS;r++){const E=r*t.UNPACKED_OP_SIZE;i[E+t.UNPACKED_OP_EG_RATE_1]=t.DEFAULT_EG_RATE,i[E+t.UNPACKED_OP_EG_RATE_2]=t.DEFAULT_EG_RATE,i[E+t.UNPACKED_OP_EG_RATE_3]=t.DEFAULT_EG_RATE,i[E+t.UNPACKED_OP_EG_RATE_4]=t.DEFAULT_EG_RATE,i[E+t.UNPACKED_OP_EG_LEVEL_1]=t.DEFAULT_EG_LEVEL_MAX,i[E+t.UNPACKED_OP_EG_LEVEL_2]=t.DEFAULT_EG_LEVEL_MAX,i[E+t.UNPACKED_OP_EG_LEVEL_3]=t.DEFAULT_EG_LEVEL_MAX,i[E+t.UNPACKED_OP_EG_LEVEL_4]=t.DEFAULT_EG_LEVEL_MIN,i[E+t.UNPACKED_OP_BREAK_POINT]=t.DEFAULT_BREAK_POINT,i[E+t.UNPACKED_OP_L_SCALE_DEPTH]=0,i[E+t.UNPACKED_OP_R_SCALE_DEPTH]=0,i[E+t.UNPACKED_OP_L_CURVE]=0,i[E+t.UNPACKED_OP_R_CURVE]=0,i[E+t.UNPACKED_OP_RATE_SCALING]=0,i[E+t.UNPACKED_OP_DETUNE]=t.DEFAULT_DETUNE,i[E+t.UNPACKED_OP_AMP_MOD_SENS]=0,i[E+t.UNPACKED_OP_KEY_VEL_SENS]=0,i[E+t.UNPACKED_OP_OUTPUT_LEVEL]=t.DEFAULT_OUTPUT_LEVEL,i[E+t.UNPACKED_OP_MODE]=0,i[E+t.UNPACKED_OP_FREQ_COARSE]=t.DEFAULT_FREQ_COARSE,i[E+t.UNPACKED_OP_FREQ_FINE]=0}i[t.UNPACKED_PITCH_EG_RATE_1]=t.DEFAULT_EG_RATE,i[t.UNPACKED_PITCH_EG_RATE_2]=t.DEFAULT_EG_RATE,i[t.UNPACKED_PITCH_EG_RATE_3]=t.DEFAULT_EG_RATE,i[t.UNPACKED_PITCH_EG_RATE_4]=t.DEFAULT_EG_RATE,i[t.UNPACKED_PITCH_EG_LEVEL_1]=t.DEFAULT_PITCH_EG_LEVEL,i[t.UNPACKED_PITCH_EG_LEVEL_2]=t.DEFAULT_PITCH_EG_LEVEL,i[t.UNPACKED_PITCH_EG_LEVEL_3]=t.DEFAULT_PITCH_EG_LEVEL,i[t.UNPACKED_PITCH_EG_LEVEL_4]=t.DEFAULT_PITCH_EG_LEVEL,i[t.UNPACKED_ALGORITHM]=t.DEFAULT_ALGORITHM,i[t.UNPACKED_FEEDBACK]=t.DEFAULT_FEEDBACK,i[t.UNPACKED_OSC_SYNC]=t.DEFAULT_OSC_SYNC,i[t.UNPACKED_LFO_SPEED]=t.DEFAULT_LFO_SPEED,i[t.UNPACKED_LFO_DELAY]=0,i[t.UNPACKED_LFO_PM_DEPTH]=0,i[t.UNPACKED_LFO_AM_DEPTH]=0,i[t.UNPACKED_LFO_KEY_SYNC]=t.DEFAULT_LFO_KEY_SYNC,i[t.UNPACKED_LFO_WAVE]=0,i[t.UNPACKED_LFO_PM_SENS]=t.DEFAULT_LFO_PM_SENS,i[t.UNPACKED_AMP_MOD_SENS]=0,i[t.UNPACKED_TRANSPOSE]=t.TRANSPOSE_CENTER,i[t.UNPACKED_EG_BIAS_SENS]=0;const n="Init Voice";for(let r=0;r<t.NAME_LENGTH;r++)i[t.UNPACKED_NAME_START+r]=r<n.length?n.charCodeAt(r):t.CHAR_SPACE;const s=t.pack(i);return new t(s,e)}static fromUnpacked(e,i=0){const n=t.pack(e);return new t(n,i)}static async fromFile(e){return new Promise((i,n)=>{const s=new FileReader;s.onload=r=>{try{const E=new Uint8Array(r.target.result);if(E[0]!==t.VCED_SYSEX_START||E[1]!==t.VCED_YAMAHA_ID||E[2]!==t.VCED_SUB_STATUS||E[3]!==t.VCED_FORMAT_SINGLE||E[4]!==t.VCED_BYTE_COUNT_MSB||E[5]!==t.VCED_BYTE_COUNT_LSB)throw new G("Invalid VCED header","header",0);const o=E.subarray(t.VCED_HEADER_SIZE,t.VCED_HEADER_SIZE+t.VCED_DATA_SIZE),h=E[t.VCED_HEADER_SIZE+t.VCED_DATA_SIZE],N=F._calculateChecksum(o,t.VCED_DATA_SIZE);h!==N&&console.warn(`DX7 VCED checksum mismatch (expected ${N.toString(16)}, got ${h.toString(16)}). This is common with vintage SysEx files.`);const u=new Uint8Array(t.UNPACKED_SIZE);let a=0;for(let S=0;S<t.NUM_OPERATORS;S++){const D=(t.NUM_OPERATORS-1-S)*t.UNPACKED_OP_SIZE;u[D+t.UNPACKED_OP_EG_RATE_1]=o[a++],u[D+t.UNPACKED_OP_EG_RATE_2]=o[a++],u[D+t.UNPACKED_OP_EG_RATE_3]=o[a++],u[D+t.UNPACKED_OP_EG_RATE_4]=o[a++],u[D+t.UNPACKED_OP_EG_LEVEL_1]=o[a++],u[D+t.UNPACKED_OP_EG_LEVEL_2]=o[a++],u[D+t.UNPACKED_OP_EG_LEVEL_3]=o[a++],u[D+t.UNPACKED_OP_EG_LEVEL_4]=o[a++],u[D+t.UNPACKED_OP_BREAK_POINT]=o[a++],u[D+t.UNPACKED_OP_L_SCALE_DEPTH]=o[a++],u[D+t.UNPACKED_OP_R_SCALE_DEPTH]=o[a++],u[D+t.UNPACKED_OP_L_CURVE]=o[a++],u[D+t.UNPACKED_OP_R_CURVE]=o[a++],u[D+t.UNPACKED_OP_RATE_SCALING]=o[a++],u[D+t.UNPACKED_OP_DETUNE]=o[a++];const T=o[a++];u[D+t.UNPACKED_OP_AMP_MOD_SENS]=T&t.MASK_2BIT,u[D+t.UNPACKED_OP_KEY_VEL_SENS]=T>>2&t.MASK_3BIT,u[D+t.UNPACKED_OP_OUTPUT_LEVEL]=o[a++],u[D+t.UNPACKED_OP_MODE]=o[a++],u[D+t.UNPACKED_OP_FREQ_COARSE]=o[a++],u[D+t.UNPACKED_OP_FREQ_FINE]=o[a++],a++}u[t.UNPACKED_PITCH_EG_RATE_1]=o[a++],u[t.UNPACKED_PITCH_EG_RATE_2]=o[a++],u[t.UNPACKED_PITCH_EG_RATE_3]=o[a++],u[t.UNPACKED_PITCH_EG_RATE_4]=o[a++],u[t.UNPACKED_PITCH_EG_LEVEL_1]=o[a++],u[t.UNPACKED_PITCH_EG_LEVEL_2]=o[a++],u[t.UNPACKED_PITCH_EG_LEVEL_3]=o[a++],u[t.UNPACKED_PITCH_EG_LEVEL_4]=o[a++],u[t.UNPACKED_ALGORITHM]=o[a++],u[t.UNPACKED_FEEDBACK]=o[a++],u[t.UNPACKED_OSC_SYNC]=o[a++],u[t.UNPACKED_LFO_SPEED]=o[a++],u[t.UNPACKED_LFO_DELAY]=o[a++],u[t.UNPACKED_LFO_PM_DEPTH]=o[a++],u[t.UNPACKED_LFO_AM_DEPTH]=o[a++],u[t.UNPACKED_LFO_KEY_SYNC]=o[a++],u[t.UNPACKED_LFO_WAVE]=o[a++],u[t.UNPACKED_LFO_PM_SENS]=o[a++],u[t.UNPACKED_TRANSPOSE]=o[a++];for(let S=0;S<t.NAME_LENGTH;S++)u[t.UNPACKED_NAME_START+S]=o[a++];const A=t.pack(u);i(new t(A,0))}catch(E){n(E)}},s.onerror=()=>n(new Error("Failed to read file")),s.readAsArrayBuffer(e)})}static fromSysEx(e,i=0){const n=e instanceof Uint8Array?e:new Uint8Array(e);let s;if(n[0]===t.VCED_SYSEX_START){if(n[0]!==t.VCED_SYSEX_START||n[1]!==t.VCED_YAMAHA_ID||n[2]!==t.VCED_SUB_STATUS||n[3]!==t.VCED_FORMAT_SINGLE||n[4]!==t.VCED_BYTE_COUNT_MSB||n[5]!==t.VCED_BYTE_COUNT_LSB)throw new G("Invalid VCED header","header",0);s=n.subarray(t.VCED_HEADER_SIZE,t.VCED_HEADER_SIZE+t.VCED_DATA_SIZE)}else if(n.length===t.PACKED_SIZE)s=n;else throw new d(`Invalid data length: expected ${t.PACKED_SIZE} or ${t.VCED_SIZE} bytes, got ${n.length}`,"length",n.length);if(s.length!==t.VCED_DATA_SIZE&&s.length!==t.PACKED_SIZE)throw new d(`Invalid voice data length: expected ${t.VCED_DATA_SIZE} or ${t.PACKED_SIZE} bytes, got ${s.length}`,"length",s.length);if(s.length===t.VCED_DATA_SIZE){const r=new Uint8Array(t.UNPACKED_SIZE);let E=0;for(let h=0;h<t.NUM_OPERATORS;h++){const N=(t.NUM_OPERATORS-1-h)*t.UNPACKED_OP_SIZE;r[N+t.UNPACKED_OP_EG_RATE_1]=s[E++],r[N+t.UNPACKED_OP_EG_RATE_2]=s[E++],r[N+t.UNPACKED_OP_EG_RATE_3]=s[E++],r[N+t.UNPACKED_OP_EG_RATE_4]=s[E++],r[N+t.UNPACKED_OP_EG_LEVEL_1]=s[E++],r[N+t.UNPACKED_OP_EG_LEVEL_2]=s[E++],r[N+t.UNPACKED_OP_EG_LEVEL_3]=s[E++],r[N+t.UNPACKED_OP_EG_LEVEL_4]=s[E++],r[N+t.UNPACKED_OP_BREAK_POINT]=s[E++],r[N+t.UNPACKED_OP_L_SCALE_DEPTH]=s[E++],r[N+t.UNPACKED_OP_R_SCALE_DEPTH]=s[E++],r[N+t.UNPACKED_OP_L_CURVE]=s[E++],r[N+t.UNPACKED_OP_R_CURVE]=s[E++],r[N+t.UNPACKED_OP_RATE_SCALING]=s[E++],r[N+t.UNPACKED_OP_DETUNE]=s[E++];const u=s[E++];r[N+t.UNPACKED_OP_AMP_MOD_SENS]=u&t.MASK_2BIT,r[N+t.UNPACKED_OP_KEY_VEL_SENS]=u>>2&t.MASK_3BIT,r[N+t.UNPACKED_OP_OUTPUT_LEVEL]=s[E++],r[N+t.UNPACKED_OP_MODE]=s[E++],r[N+t.UNPACKED_OP_FREQ_COARSE]=s[E++],r[N+t.UNPACKED_OP_FREQ_FINE]=s[E++],E++}r[t.UNPACKED_PITCH_EG_RATE_1]=s[E++],r[t.UNPACKED_PITCH_EG_RATE_2]=s[E++],r[t.UNPACKED_PITCH_EG_RATE_3]=s[E++],r[t.UNPACKED_PITCH_EG_RATE_4]=s[E++],r[t.UNPACKED_PITCH_EG_LEVEL_1]=s[E++],r[t.UNPACKED_PITCH_EG_LEVEL_2]=s[E++],r[t.UNPACKED_PITCH_EG_LEVEL_3]=s[E++],r[t.UNPACKED_PITCH_EG_LEVEL_4]=s[E++],r[t.UNPACKED_ALGORITHM]=s[E++],r[t.UNPACKED_FEEDBACK]=s[E++],r[t.UNPACKED_OSC_SYNC]=s[E++],r[t.UNPACKED_LFO_SPEED]=s[E++],r[t.UNPACKED_LFO_DELAY]=s[E++],r[t.UNPACKED_LFO_PM_DEPTH]=s[E++],r[t.UNPACKED_LFO_AM_DEPTH]=s[E++],r[t.UNPACKED_LFO_KEY_SYNC]=s[E++],r[t.UNPACKED_LFO_WAVE]=s[E++],r[t.UNPACKED_LFO_PM_SENS]=s[E++],r[t.UNPACKED_TRANSPOSE]=s[E++];for(let h=0;h<t.NAME_LENGTH;h++)r[t.UNPACKED_NAME_START+h]=s[E++];const o=t.pack(r);return new t(o,i)}return new t(s,i)}static fromJSON(e,i=0){if(!e||typeof e!="object")throw new d("Invalid JSON: expected object","json",e);const n=new Uint8Array(t.UNPACKED_SIZE),s=(a,A,S,D=0,T=127)=>{if(A==null)throw new d(`Missing required parameter: ${S}`,S,A);const f=Number(A);if(Number.isNaN(f))throw new d(`Invalid parameter value for ${S}: ${A}`,S,A);if(f<D||f>T)throw new d(`Parameter ${S} out of range: ${f} (must be ${D}-${T})`,S,f);n[a]=Math.floor(f)},r=a=>{const A={"-LN":0,"-EX":1,"+EX":2,"+LN":3};return A[a]!==void 0?A[a]:0},E=a=>{const A={TRIANGLE:0,"SAW DOWN":1,"SAW UP":2,SQUARE:3,SINE:4,"SAMPLE & HOLD":5};return A[a]!==void 0?A[a]:0},o=a=>{if(!a||typeof a!="string")return 60;const A=a.trim().match(/^([A-G]#?)(-?\d+)$/);if(!A)return 60;const[,S,D]=A,T=parseInt(D,10),U={C:0,"C#":1,D:2,"D#":3,E:4,F:5,"F#":6,G:7,"G#":8,A:9,"A#":10,B:11}[S.toUpperCase()];return U===void 0?60:(T-t.MIDI_OCTAVE_OFFSET)*12+U};if(!Array.isArray(e.operators))throw new d("Invalid operators array: expected array","operators",e.operators);for(let a=0;a<e.operators.length;a++){const A=e.operators[a];if(!A||typeof A!="object")throw new d(`Invalid operator data at index ${a}`,`operators[${a}]`,A);if(!A.eg||!Array.isArray(A.eg.rates)||A.eg.rates.length!==4)throw new d(`Invalid EG rates for operator ${a}`,`operators[${a}].eg.rates`,A.eg?.rates);if(!A.eg||!Array.isArray(A.eg.levels)||A.eg.levels.length!==4)throw new d(`Invalid EG levels for operator ${a}`,`operators[${a}].eg.levels`,A.eg?.levels)}if(e.operators.length!==t.NUM_OPERATORS)throw new d(`Invalid operators array: expected ${t.NUM_OPERATORS} operators`,"operators",e.operators);for(let a=0;a<t.NUM_OPERATORS;a++){const A=e.operators[a],S=a*t.UNPACKED_OP_SIZE;if(!A.eg||!Array.isArray(A.eg.rates)||A.eg.rates.length!==4)throw new d(`Invalid EG rates for operator ${a}`,`operators[${a}].eg.rates`,A.eg?.rates);if(s(S+t.UNPACKED_OP_EG_RATE_1,A.eg.rates[0],`operators[${a}].eg.rates[0]`,0,99),s(S+t.UNPACKED_OP_EG_RATE_2,A.eg.rates[1],`operators[${a}].eg.rates[1]`,0,99),s(S+t.UNPACKED_OP_EG_RATE_3,A.eg.rates[2],`operators[${a}].eg.rates[2]`,0,99),s(S+t.UNPACKED_OP_EG_RATE_4,A.eg.rates[3],`operators[${a}].eg.rates[3]`,0,99),!A.eg||!Array.isArray(A.eg.levels)||A.eg.levels.length!==4)throw new d(`Invalid EG levels for operator ${a}`,`operators[${a}].eg.levels`,A.eg?.levels);s(S+t.UNPACKED_OP_EG_LEVEL_1,A.eg.levels[0],`operators[${a}].eg.levels[0]`,0,99),s(S+t.UNPACKED_OP_EG_LEVEL_2,A.eg.levels[1],`operators[${a}].eg.levels[1]`,0,99),s(S+t.UNPACKED_OP_EG_LEVEL_3,A.eg.levels[2],`operators[${a}].eg.levels[2]`,0,99),s(S+t.UNPACKED_OP_EG_LEVEL_4,A.eg.levels[3],`operators[${a}].eg.levels[3]`,0,99);const D=o(A.key?.breakPoint)-t.MIDI_BREAK_POINT_OFFSET;s(S+t.UNPACKED_OP_BREAK_POINT,D,`operators[${a}].key.breakPoint`,0,127),s(S+t.UNPACKED_OP_L_SCALE_DEPTH,A.scale?.left?.depth||0,`operators[${a}].scale.left.depth`,0,99),s(S+t.UNPACKED_OP_R_SCALE_DEPTH,A.scale?.right?.depth||0,`operators[${a}].scale.right.depth`,0,99),n[S+t.UNPACKED_OP_L_CURVE]=r(A.scale?.left?.curve||"-LN"),n[S+t.UNPACKED_OP_R_CURVE]=r(A.scale?.right?.curve||"-LN"),s(S+t.UNPACKED_OP_RATE_SCALING,A.key?.scaling||0,`operators[${a}].key.scaling`,0,7);const T=Number(A.osc?.detune)||0,f=Math.max(-7,Math.min(7,T));s(S+t.UNPACKED_OP_DETUNE,f+7,`operators[${a}].osc.detune`,0,14),s(S+t.UNPACKED_OP_AMP_MOD_SENS,A.output?.ampModSens||0,`operators[${a}].output.ampModSens`,0,3),s(S+t.UNPACKED_OP_OUTPUT_LEVEL,A.output?.level||0,`operators[${a}].output.level`,0,99);const U=A.osc?.freq?.mode?.toUpperCase()==="FIXED"?1:0,L=Number(A.osc?.freq?.coarse)||0,M=Number(A.osc?.freq?.fine)||0;n[S+t.UNPACKED_OP_MODE]=U,s(S+t.UNPACKED_OP_FREQ_COARSE,L,`operators[${a}].osc.freq.coarse`,0,31),s(S+t.UNPACKED_OP_FREQ_FINE,M,`operators[${a}].osc.freq.fine`,0,99),s(S+t.UNPACKED_OP_KEY_VEL_SENS,A.key?.velocity||0,`operators[${a}].key.velocity`,0,7)}if(!e.pitchEG||!Array.isArray(e.pitchEG.rates)||e.pitchEG.rates.length!==4)throw new d("Invalid pitch EG rates","pitchEG.rates",e.pitchEG?.rates);if(!e.pitchEG||!Array.isArray(e.pitchEG.levels)||e.pitchEG.levels.length!==4)throw new d("Invalid pitch EG levels","pitchEG.levels",e.pitchEG?.levels);if(s(t.UNPACKED_PITCH_EG_RATE_1,e.pitchEG.rates[0],"pitchEG.rates[0]",0,99),s(t.UNPACKED_PITCH_EG_RATE_2,e.pitchEG.rates[1],"pitchEG.rates[1]",0,99),s(t.UNPACKED_PITCH_EG_RATE_3,e.pitchEG.rates[2],"pitchEG.rates[2]",0,99),s(t.UNPACKED_PITCH_EG_RATE_4,e.pitchEG.rates[3],"pitchEG.rates[3]",0,99),s(t.UNPACKED_PITCH_EG_LEVEL_1,e.pitchEG.levels[0],"pitchEG.levels[0]",0,99),s(t.UNPACKED_PITCH_EG_LEVEL_2,e.pitchEG.levels[1],"pitchEG.levels[1]",0,99),s(t.UNPACKED_PITCH_EG_LEVEL_3,e.pitchEG.levels[2],"pitchEG.levels[2]",0,99),s(t.UNPACKED_PITCH_EG_LEVEL_4,e.pitchEG.levels[3],"pitchEG.levels[3]",0,99),!e.lfo||typeof e.lfo!="object")throw new d("Invalid LFO data","lfo",e.lfo);if(s(t.UNPACKED_LFO_SPEED,e.lfo.speed,"lfo.speed",0,99),s(t.UNPACKED_LFO_DELAY,e.lfo.delay,"lfo.delay",0,99),s(t.UNPACKED_LFO_PM_DEPTH,e.lfo.pmDepth,"lfo.pmDepth",0,99),s(t.UNPACKED_LFO_AM_DEPTH,e.lfo.amDepth,"lfo.amDepth",0,99),n[t.UNPACKED_LFO_KEY_SYNC]=e.lfo.keySync?1:0,n[t.UNPACKED_LFO_WAVE]=E(e.lfo.wave),!e.global||typeof e.global!="object")throw new d("Invalid global data","global",e.global);const h=Number(e.global.algorithm)||1;s(t.UNPACKED_ALGORITHM,h-1,"global.algorithm",0,31),s(t.UNPACKED_FEEDBACK,e.global.feedback,"global.feedback",0,7),n[t.UNPACKED_OSC_SYNC]=e.global.oscKeySync?1:0,s(t.UNPACKED_LFO_PM_SENS,e.global.pitchModSens,"global.pitchModSens",0,7);const N=Number(e.global.transpose)||0;s(t.UNPACKED_TRANSPOSE,N+t.TRANSPOSE_CENTER,"global.transpose",0,127),s(t.UNPACKED_AMP_MOD_SENS,e.global.ampModSens||0,"global.ampModSens",0,3),s(t.UNPACKED_EG_BIAS_SENS,e.global.egBiasSens||0,"global.egBiasSens",0,7);const u=e.name||"";for(let a=0;a<t.NAME_LENGTH;a++)n[t.UNPACKED_NAME_START+a]=a<u.length?u.charCodeAt(a):t.CHAR_SPACE;return t.fromUnpacked(n,i)}toSysEx(){const e=this.unpack(),i=new Uint8Array(t.VCED_SIZE);let n=0;i[n++]=t.VCED_SYSEX_START,i[n++]=t.VCED_YAMAHA_ID,i[n++]=t.VCED_SUB_STATUS,i[n++]=t.VCED_FORMAT_SINGLE,i[n++]=t.VCED_BYTE_COUNT_MSB,i[n++]=t.VCED_BYTE_COUNT_LSB;for(let r=t.NUM_OPERATORS-1;r>=0;r--){const E=r*t.UNPACKED_OP_SIZE;i[n++]=e[E+t.UNPACKED_OP_EG_RATE_1],i[n++]=e[E+t.UNPACKED_OP_EG_RATE_2],i[n++]=e[E+t.UNPACKED_OP_EG_RATE_3],i[n++]=e[E+t.UNPACKED_OP_EG_RATE_4],i[n++]=e[E+t.UNPACKED_OP_EG_LEVEL_1],i[n++]=e[E+t.UNPACKED_OP_EG_LEVEL_2],i[n++]=e[E+t.UNPACKED_OP_EG_LEVEL_3],i[n++]=e[E+t.UNPACKED_OP_EG_LEVEL_4],i[n++]=e[E+t.UNPACKED_OP_BREAK_POINT],i[n++]=e[E+t.UNPACKED_OP_L_SCALE_DEPTH],i[n++]=e[E+t.UNPACKED_OP_R_SCALE_DEPTH],i[n++]=e[E+t.UNPACKED_OP_L_CURVE],i[n++]=e[E+t.UNPACKED_OP_R_CURVE],i[n++]=e[E+t.UNPACKED_OP_RATE_SCALING],i[n++]=e[E+t.UNPACKED_OP_DETUNE];const o=e[E+t.UNPACKED_OP_AMP_MOD_SENS]&t.MASK_2BIT,h=e[E+t.UNPACKED_OP_KEY_VEL_SENS]&t.MASK_3BIT;i[n++]=o|h<<2,i[n++]=e[E+t.UNPACKED_OP_OUTPUT_LEVEL],i[n++]=e[E+t.UNPACKED_OP_MODE],i[n++]=e[E+t.UNPACKED_OP_FREQ_COARSE],i[n++]=e[E+t.UNPACKED_OP_FREQ_FINE],i[n++]=0}i[n++]=e[t.UNPACKED_PITCH_EG_RATE_1],i[n++]=e[t.UNPACKED_PITCH_EG_RATE_2],i[n++]=e[t.UNPACKED_PITCH_EG_RATE_3],i[n++]=e[t.UNPACKED_PITCH_EG_RATE_4],i[n++]=e[t.UNPACKED_PITCH_EG_LEVEL_1],i[n++]=e[t.UNPACKED_PITCH_EG_LEVEL_2],i[n++]=e[t.UNPACKED_PITCH_EG_LEVEL_3],i[n++]=e[t.UNPACKED_PITCH_EG_LEVEL_4],i[n++]=e[t.UNPACKED_ALGORITHM],i[n++]=e[t.UNPACKED_FEEDBACK],i[n++]=e[t.UNPACKED_OSC_SYNC],i[n++]=e[t.UNPACKED_LFO_SPEED],i[n++]=e[t.UNPACKED_LFO_DELAY],i[n++]=e[t.UNPACKED_LFO_PM_DEPTH],i[n++]=e[t.UNPACKED_LFO_AM_DEPTH],i[n++]=e[t.UNPACKED_LFO_KEY_SYNC],i[n++]=e[t.UNPACKED_LFO_WAVE],i[n++]=e[t.UNPACKED_LFO_PM_SENS],i[n++]=e[t.UNPACKED_TRANSPOSE];for(let r=0;r<t.NAME_LENGTH;r++)i[n++]=e[t.UNPACKED_NAME_START+r];const s=i.subarray(t.VCED_HEADER_SIZE,t.VCED_HEADER_SIZE+t.VCED_DATA_SIZE);return i[n++]=F._calculateChecksum(s,t.VCED_DATA_SIZE),i[n++]=t.VCED_SYSEX_END,i}toJSON(){const e=this.unpack(),i=[],n=E=>["-LN","-EX","+EX","+LN"][E]||"UNKNOWN",s=E=>["TRIANGLE","SAW DOWN","SAW UP","SQUARE","SINE","SAMPLE & HOLD"][E]||"UNKNOWN",r=E=>{const o=["C","C#","D","D#","E","F","F#","G","G#","A","A#","B"],h=Math.floor(E/12)+t.MIDI_OCTAVE_OFFSET;return`${o[E%12]}${h}`};for(let E=0;E<t.NUM_OPERATORS;E++){const o=E*t.UNPACKED_OP_SIZE,h=e[o+t.UNPACKED_OP_MODE]===0?"RATIO":"FIXED";i.push({id:E+1,osc:{detune:e[o+t.UNPACKED_OP_DETUNE]-7,freq:{coarse:e[o+t.UNPACKED_OP_FREQ_COARSE],fine:e[o+t.UNPACKED_OP_FREQ_FINE],mode:h}},eg:{rates:[e[o+t.UNPACKED_OP_EG_RATE_1],e[o+t.UNPACKED_OP_EG_RATE_2],e[o+t.UNPACKED_OP_EG_RATE_3],e[o+t.UNPACKED_OP_EG_RATE_4]],levels:[e[o+t.UNPACKED_OP_EG_LEVEL_1],e[o+t.UNPACKED_OP_EG_LEVEL_2],e[o+t.UNPACKED_OP_EG_LEVEL_3],e[o+t.UNPACKED_OP_EG_LEVEL_4]]},key:{velocity:e[o+t.UNPACKED_OP_KEY_VEL_SENS],scaling:e[o+t.UNPACKED_OP_RATE_SCALING],breakPoint:r(e[o+t.UNPACKED_OP_BREAK_POINT]+t.MIDI_BREAK_POINT_OFFSET)},output:{level:e[o+t.UNPACKED_OP_OUTPUT_LEVEL],ampModSens:e[o+t.UNPACKED_OP_AMP_MOD_SENS]},scale:{left:{depth:e[o+t.UNPACKED_OP_L_SCALE_DEPTH],curve:n(e[o+t.UNPACKED_OP_L_CURVE])},right:{depth:e[o+t.UNPACKED_OP_R_SCALE_DEPTH],curve:n(e[o+t.UNPACKED_OP_R_CURVE])}}})}return{name:this.name||"(Empty)",operators:i,pitchEG:{rates:[e[t.UNPACKED_PITCH_EG_RATE_1],e[t.UNPACKED_PITCH_EG_RATE_2],e[t.UNPACKED_PITCH_EG_RATE_3],e[t.UNPACKED_PITCH_EG_RATE_4]],levels:[e[t.UNPACKED_PITCH_EG_LEVEL_1],e[t.UNPACKED_PITCH_EG_LEVEL_2],e[t.UNPACKED_PITCH_EG_LEVEL_3],e[t.UNPACKED_PITCH_EG_LEVEL_4]]},lfo:{speed:e[t.UNPACKED_LFO_SPEED],delay:e[t.UNPACKED_LFO_DELAY],pmDepth:e[t.UNPACKED_LFO_PM_DEPTH],amDepth:e[t.UNPACKED_LFO_AM_DEPTH],keySync:e[t.UNPACKED_LFO_KEY_SYNC]===1,wave:s(e[t.UNPACKED_LFO_WAVE])},global:{algorithm:e[t.UNPACKED_ALGORITHM]+1,feedback:e[t.UNPACKED_FEEDBACK],oscKeySync:e[t.UNPACKED_OSC_SYNC]===1,pitchModSens:e[t.UNPACKED_LFO_PM_SENS],transpose:e[t.UNPACKED_TRANSPOSE]-t.TRANSPOSE_CENTER}}}};_(t,"PACKED_SIZE",128),_(t,"PACKED_OP_SIZE",17),_(t,"NUM_OPERATORS",6),_(t,"PACKED_OP_EG_RATE_1",0),_(t,"PACKED_OP_EG_RATE_2",1),_(t,"PACKED_OP_EG_RATE_3",2),_(t,"PACKED_OP_EG_RATE_4",3),_(t,"PACKED_OP_EG_LEVEL_1",4),_(t,"PACKED_OP_EG_LEVEL_2",5),_(t,"PACKED_OP_EG_LEVEL_3",6),_(t,"PACKED_OP_EG_LEVEL_4",7),_(t,"PACKED_OP_BREAK_POINT",8),_(t,"PACKED_OP_L_SCALE_DEPTH",9),_(t,"PACKED_OP_R_SCALE_DEPTH",10),_(t,"PACKED_OP_CURVES",11),_(t,"PACKED_OP_RATE_SCALING",12),_(t,"PACKED_OP_MOD_SENS",13),_(t,"PACKED_OP_OUTPUT_LEVEL",14),_(t,"PACKED_OP_MODE_FREQ",15),_(t,"PACKED_OP_DETUNE_FINE",16),_(t,"PACKED_PITCH_EG_RATE_1",102),_(t,"PACKED_PITCH_EG_RATE_2",103),_(t,"PACKED_PITCH_EG_RATE_3",104),_(t,"PACKED_PITCH_EG_RATE_4",105),_(t,"PACKED_PITCH_EG_LEVEL_1",106),_(t,"PACKED_PITCH_EG_LEVEL_2",107),_(t,"PACKED_PITCH_EG_LEVEL_3",108),_(t,"PACKED_PITCH_EG_LEVEL_4",109),_(t,"OFFSET_ALGORITHM",110),_(t,"OFFSET_FEEDBACK",111),_(t,"OFFSET_LFO_SPEED",112),_(t,"OFFSET_LFO_DELAY",113),_(t,"OFFSET_LFO_PM_DEPTH",114),_(t,"OFFSET_LFO_AM_DEPTH",115),_(t,"OFFSET_LFO_SYNC_WAVE",116),_(t,"OFFSET_TRANSPOSE",117),_(t,"OFFSET_AMP_MOD_SENS",118),_(t,"OFFSET_EG_BIAS_SENS",119),_(t,"PACKED_NAME_START",118),_(t,"NAME_LENGTH",10),_(t,"UNPACKED_SIZE",169),_(t,"UNPACKED_OP_SIZE",23),_(t,"UNPACKED_OP_EG_RATE_1",0),_(t,"UNPACKED_OP_EG_RATE_2",1),_(t,"UNPACKED_OP_EG_RATE_3",2),_(t,"UNPACKED_OP_EG_RATE_4",3),_(t,"UNPACKED_OP_EG_LEVEL_1",4),_(t,"UNPACKED_OP_EG_LEVEL_2",5),_(t,"UNPACKED_OP_EG_LEVEL_3",6),_(t,"UNPACKED_OP_EG_LEVEL_4",7),_(t,"UNPACKED_OP_BREAK_POINT",8),_(t,"UNPACKED_OP_L_SCALE_DEPTH",9),_(t,"UNPACKED_OP_R_SCALE_DEPTH",10),_(t,"UNPACKED_OP_L_CURVE",11),_(t,"UNPACKED_OP_R_CURVE",12),_(t,"UNPACKED_OP_RATE_SCALING",13),_(t,"UNPACKED_OP_DETUNE",14),_(t,"UNPACKED_OP_AMP_MOD_SENS",15),_(t,"UNPACKED_OP_OUTPUT_LEVEL",16),_(t,"UNPACKED_OP_MODE",17),_(t,"UNPACKED_OP_KEY_VEL_SENS",18),_(t,"UNPACKED_OP_FREQ_COARSE",19),_(t,"UNPACKED_OP_FREQ_FINE",21),_(t,"UNPACKED_PITCH_EG_RATE_1",138),_(t,"UNPACKED_PITCH_EG_RATE_2",139),_(t,"UNPACKED_PITCH_EG_RATE_3",140),_(t,"UNPACKED_PITCH_EG_RATE_4",141),_(t,"UNPACKED_PITCH_EG_LEVEL_1",142),_(t,"UNPACKED_PITCH_EG_LEVEL_2",143),_(t,"UNPACKED_PITCH_EG_LEVEL_3",144),_(t,"UNPACKED_PITCH_EG_LEVEL_4",145),_(t,"UNPACKED_ALGORITHM",146),_(t,"UNPACKED_FEEDBACK",147),_(t,"UNPACKED_OSC_SYNC",148),_(t,"UNPACKED_LFO_SPEED",149),_(t,"UNPACKED_LFO_DELAY",150),_(t,"UNPACKED_LFO_PM_DEPTH",151),_(t,"UNPACKED_LFO_AM_DEPTH",152),_(t,"UNPACKED_LFO_KEY_SYNC",153),_(t,"UNPACKED_LFO_WAVE",154),_(t,"UNPACKED_LFO_PM_SENS",155),_(t,"UNPACKED_AMP_MOD_SENS",156),_(t,"UNPACKED_TRANSPOSE",157),_(t,"UNPACKED_EG_BIAS_SENS",158),_(t,"UNPACKED_NAME_START",159),_(t,"VCED_SIZE",163),_(t,"VCED_HEADER_SIZE",6),_(t,"VCED_DATA_SIZE",155),_(t,"VCED_SYSEX_START",240),_(t,"VCED_YAMAHA_ID",67),_(t,"VCED_SUB_STATUS",0),_(t,"VCED_FORMAT_SINGLE",0),_(t,"VCED_BYTE_COUNT_MSB",1),_(t,"VCED_BYTE_COUNT_LSB",27),_(t,"VCED_SYSEX_END",247),_(t,"MASK_7BIT",127),_(t,"MASK_2BIT",3),_(t,"MASK_3BIT",7),_(t,"MASK_4BIT",15),_(t,"MASK_5BIT",31),_(t,"MASK_1BIT",1),_(t,"TRANSPOSE_CENTER",24),_(t,"CHAR_YEN",92),_(t,"CHAR_ARROW_RIGHT",126),_(t,"CHAR_ARROW_LEFT",127),_(t,"CHAR_REPLACEMENT_Y",89),_(t,"CHAR_REPLACEMENT_GT",62),_(t,"CHAR_REPLACEMENT_LT",60),_(t,"CHAR_SPACE",32),_(t,"CHAR_MIN_PRINTABLE",32),_(t,"CHAR_MAX_PRINTABLE",126),_(t,"DEFAULT_EG_RATE",99),_(t,"DEFAULT_EG_LEVEL_MAX",99),_(t,"DEFAULT_EG_LEVEL_MIN",0),_(t,"DEFAULT_BREAK_POINT",0),_(t,"DEFAULT_OUTPUT_LEVEL",99),_(t,"DEFAULT_PITCH_EG_LEVEL",50),_(t,"DEFAULT_LFO_SPEED",35),_(t,"DEFAULT_LFO_PM_SENS",3),_(t,"DEFAULT_DETUNE",7),_(t,"DEFAULT_FREQ_COARSE",1),_(t,"DEFAULT_ALGORITHM",0),_(t,"DEFAULT_FEEDBACK",0),_(t,"DEFAULT_OSC_SYNC",1),_(t,"DEFAULT_LFO_KEY_SYNC",1),_(t,"MIDI_OCTAVE_OFFSET",-2),_(t,"MIDI_BREAK_POINT_OFFSET",21);let m=t;const P=class P{constructor(e,i=""){if(this.voices=new Array(P.NUM_VOICES),this.name=i,e)this._load(e);else for(let n=0;n<P.NUM_VOICES;n++)this.voices[n]=m.createDefault(n)}static _calculateChecksum(e,i){let n=0;for(let s=0;s<i;s++)n+=e[s];return P.CHECKSUM_MODULO-n%P.CHECKSUM_MODULO&P.MASK_7BIT}_load(e){const i=e instanceof Uint8Array?e:new Uint8Array(e);let n,s=0;if(i[0]===P.SYSEX_START){const E=i.subarray(0,P.SYSEX_HEADER_SIZE),o=P.SYSEX_HEADER;for(let h=0;h<P.SYSEX_HEADER_SIZE;h++)if(E[h]!==o[h])throw new G(`Invalid SysEx header at position ${h}: expected ${o[h].toString(16)}, got ${E[h].toString(16)}`,"header",h);n=i.subarray(P.SYSEX_HEADER_SIZE,P.SYSEX_HEADER_SIZE+P.VOICE_DATA_SIZE),s=P.SYSEX_HEADER_SIZE}else if(i.length===P.VOICE_DATA_SIZE)n=i;else throw new d(`Invalid data length: expected ${P.VOICE_DATA_SIZE} or ${P.SYSEX_SIZE} bytes, got ${i.length}`,"length",i.length);if(n.length!==P.VOICE_DATA_SIZE)throw new d(`Invalid voice data length: expected ${P.VOICE_DATA_SIZE} bytes, got ${n.length}`,"length",n.length);const r=P.SYSEX_HEADER_SIZE+P.VOICE_DATA_SIZE;if(s>0&&i.length>=r+1){const E=i[r],o=P._calculateChecksum(n,P.VOICE_DATA_SIZE);E!==o&&console.warn(`DX7 checksum mismatch (expected ${o.toString(16)}, got ${E.toString(16)}). This is common with vintage SysEx files and the data is likely still valid.`)}this.voices=new Array(P.NUM_VOICES);for(let E=0;E<P.NUM_VOICES;E++){const o=E*P.VOICE_SIZE,h=n.subarray(o,o+P.VOICE_SIZE);this.voices[E]=new m(h,E)}}replaceVoice(e,i){if(e<0||e>=P.NUM_VOICES)throw new d(`Invalid voice index: ${e}`,"index",e);const n=new Uint8Array(i.data);this.voices[e]=new m(n,e)}addVoice(e){for(let i=0;i<this.voices.length;i++){const n=this.voices[i];if(n.name===""||n.name==="Init Voice")return this.replaceVoice(i,e),i}return-1}getVoices(){return this.voices}getVoice(e){return e<0||e>=this.voices.length?null:this.voices[e]}getVoiceNames(){return this.voices.map(e=>e.name)}findVoiceByName(e){const i=e.toLowerCase();return this.voices.find(n=>n.name.toLowerCase().includes(i))||null}static async fromFile(e){return new Promise((i,n)=>{const s=new FileReader;s.onload=async r=>{try{const E=e.name||"",o=new Uint8Array(r.target.result);if(o[0]===P.SYSEX_START&&o[3]===m.VCED_FORMAT_SINGLE)n(new G("This is a single voice file. Use DX7Voice.fromFile() instead.","format",3));else{const h=E.replace(/\.[^/.]+$/,""),N=new P(r.target.result,h);i(N)}}catch(E){n(E)}},s.onerror=()=>n(new Error("Failed to read file")),s.readAsArrayBuffer(e)})}static fromSysEx(e,i=""){return new P(e,i)}static fromJSON(e){if(!e||typeof e!="object")throw new d("Invalid JSON: expected object","json",e);const i=new P;if(i.name=e.name||"",!Array.isArray(e.voices))throw new d("Invalid voices array","voices",e.voices);e.voices.length!==P.NUM_VOICES&&console.warn(`Bank JSON has ${e.voices.length} voices, expected ${P.NUM_VOICES}. Missing voices will be filled with defaults.`);const n=Math.min(e.voices.length,P.NUM_VOICES);for(let s=0;s<n;s++){const r=e.voices[s];if(!r||typeof r!="object"){console.warn(`Invalid voice data at index ${s}, using default voice`);continue}try{const{index:E,...o}=r,h=m.fromJSON(o,s);i.replaceVoice(s,h)}catch(E){console.warn(`Failed to load voice at index ${s}: ${E.message}, using default voice`)}}return i}toSysEx(){const e=new Uint8Array(P.SYSEX_SIZE);let i=0;P.SYSEX_HEADER.forEach(s=>{e[i++]=s});for(const s of this.voices)for(let r=0;r<P.VOICE_SIZE;r++)e[i++]=s.data[r];const n=e.subarray(P.SYSEX_HEADER_SIZE,P.SYSEX_HEADER_SIZE+P.VOICE_DATA_SIZE);return e[i++]=P._calculateChecksum(n,P.VOICE_DATA_SIZE),e[i++]=P.SYSEX_END,e}toJSON(){const e=this.voices.map((i,n)=>{const s=i.toJSON();return{index:n+1,...s}});return{version:"1.0",name:this.name||"",voices:e}}};_(P,"SYSEX_START",240),_(P,"SYSEX_END",247),_(P,"SYSEX_YAMAHA_ID",67),_(P,"SYSEX_SUB_STATUS",0),_(P,"SYSEX_FORMAT_32_VOICES",9),_(P,"SYSEX_BYTE_COUNT_MSB",32),_(P,"SYSEX_BYTE_COUNT_LSB",0),_(P,"SYSEX_HEADER",[P.SYSEX_START,P.SYSEX_YAMAHA_ID,P.SYSEX_SUB_STATUS,P.SYSEX_FORMAT_32_VOICES,P.SYSEX_BYTE_COUNT_MSB,P.SYSEX_BYTE_COUNT_LSB]),_(P,"SYSEX_HEADER_SIZE",6),_(P,"VOICE_DATA_SIZE",4096),_(P,"SYSEX_SIZE",4104),_(P,"VOICE_SIZE",128),_(P,"NUM_VOICES",32),_(P,"CHECKSUM_MODULO",128),_(P,"MASK_7BIT",127);let F=P;function nt(c){return c[0]!==240||c[c.length-1]!==247?null:{manufacturerId:c[1],payload:c.slice(2,-1),raw:c}}function st(c,e){return[240,c,...e,247]}function Et(c){return c.length>=2&&c[0]===240&&c[c.length-1]===247}function rt(c){const e=[];for(let i=0;i<c.length;i+=7){const n=c.slice(i,i+7);let s=0;const r=[];for(let E=0;E<n.length;E++){const o=n[E];o&128&&(s|=1<<E),r.push(o&127)}e.push(s,...r)}return e}function ot(c){const e=[];for(let i=0;i<c.length;i+=8){const n=c[i],s=Math.min(7,c.length-i-1);for(let r=0;r<s;r++){let E=c[i+1+r];n&1<<r&&(E|=128),e.push(E)}}return e}function _t(c){return Number.isInteger(c)&&c>=1&&c<=16}function at(c){return Number.isInteger(c)&&c>=0&&c<=127}function ct(c){return Number.isInteger(c)&&c>=0&&c<=31}function At(c){return Number.isInteger(c)&&c>=0&&c<=127}function Ct(c){return Number.isInteger(c)&&c>=0&&c<=127}function Pt(c){return Number.isInteger(c)&&c>=0&&c<=127}function ut(c){return Number.isInteger(c)&&c>=0&&c<=127}function lt(c){return Number.isInteger(c)&&c>=0&&c<=16383}function ht(c,e){return Number.isInteger(c)&&c>=0&&c<=127&&Number.isInteger(e)&&e>=0&&e<=127}async function St(c={}){const{onStatusUpdate:e,onConnectionUpdate:i,inputChannel:n=1,outputChannel:s=1,output:r,sysex:E,onReady:o,onError:h,selector:N,watchDOM:u,...a}=c,S=await q({autoConnect:!1,sysex:E,inputChannel:n,outputChannel:s,selector:N||"[data-midi-cc]",watchDOM:u,onError:h,...a}),D=new z({midiController:S,onStatusUpdate:e||(()=>{}),onConnectionUpdate:i||(()=>{}),channel:s});if(r)try{await S.device.connectOutput(r),D.currentOutput=S.device.getCurrentOutput(),D.updateConnectionStatus()}catch(T){h?h(T):console.error("Failed to connect to MIDI device:",T.message)}return o&&o(S,D),D}async function q(c={}){const e=new Z(c);await e.init();const i=c.selector||"[data-midi-cc]";{const n=new I(e,i);n.bindAll(),c.watchDOM&&n.enableAutoBinding(),e._binder=n}return e}function Nt(){return typeof navigator<"u"&&typeof navigator.requestMIDIAccess=="function"}l.CONN=p,l.CONNECTION_EVENTS=p,l.CONTROLLER_EVENTS=C,l.CTRL=C,l.DX7Bank=F,l.DX7Error=H,l.DX7ParseError=G,l.DX7ValidationError=d,l.DX7Voice=m,l.DataAttributeBinder=I,l.EventEmitter=v,l.MIDIAccessError=b,l.MIDIConnection=$,l.MIDIConnectionError=y,l.MIDIController=Z,l.MIDIDeviceError=R,l.MIDIDeviceManager=z,l.MIDIError=K,l.MIDIValidationError=g,l.clamp=O,l.createMIDIController=q,l.createMIDIDeviceManager=St,l.createSysEx=st,l.decode14BitValue=Y,l.decode7Bit=ot,l.denormalize14BitValue=it,l.denormalizeValue=J,l.encode14BitValue=B,l.encode7Bit=rt,l.frequencyToNote=X,l.getCCName=et,l.isMIDISupported=Nt,l.isSysEx=Et,l.isValid14BitCC=ct,l.isValidCC=at,l.isValidChannel=_t,l.isValidMIDIValue=At,l.isValidNote=Ct,l.isValidPitchBend=lt,l.isValidPitchBendBytes=ht,l.isValidProgramChange=ut,l.isValidVelocity=Pt,l.normalize14BitValue=x,l.normalizeValue=w,l.noteNameToNumber=k,l.noteNumberToName=j,l.noteToFrequency=tt,l.parseSysEx=nt,Object.defineProperty(l,Symbol.toStringTag,{value:"Module"})}));
@@ -147,7 +147,6 @@ export class DX7Voice {
147
147
  static UNPACKED_OP_MODE: number;
148
148
  static UNPACKED_OP_KEY_VEL_SENS: number;
149
149
  static UNPACKED_OP_FREQ_COARSE: number;
150
- static UNPACKED_OP_OSC_DETUNE: number;
151
150
  static UNPACKED_OP_FREQ_FINE: number;
152
151
  static UNPACKED_PITCH_EG_RATE_1: number;
153
152
  static UNPACKED_PITCH_EG_RATE_2: number;
@@ -1 +1 @@
1
- {"version":3,"file":"DX7Voice.d.ts","sourceRoot":"","sources":["../../../src/utils/dx7/DX7Voice.js"],"names":[],"mappings":"AAwBA;;;;;;;;;;GAUG;AAEH;;;;;;;;;GASG;AAEH;;;;;;;;;;GAUG;AAEH;;;;;;GAMG;AAEH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8CG;AACH;IAGE,2BAAwB;IACxB,8BAA0B;IAC1B,6BAAwB;IAGxB,mCAA8B;IAC9B,mCAA8B;IAC9B,mCAA8B;IAC9B,mCAA8B;IAC9B,oCAA+B;IAC/B,oCAA+B;IAC/B,oCAA+B;IAC/B,oCAA+B;IAC/B,qCAAgC;IAChC,uCAAkC;IAClC,uCAAmC;IACnC,gCAA4B;IAC5B,sCAAkC;IAClC,kCAA8B;IAC9B,sCAAkC;IAClC,mCAA+B;IAC/B,qCAAiC;IAGjC,sCAAmC;IACnC,sCAAmC;IACnC,sCAAmC;IACnC,sCAAmC;IACnC,uCAAoC;IACpC,uCAAoC;IACpC,uCAAoC;IACpC,uCAAoC;IACpC,gCAA6B;IAC7B,+BAA4B;IAC5B,gCAA6B;IAC7B,gCAA6B;IAC7B,mCAAgC;IAChC,mCAAgC;IAChC,oCAAiC;IACjC,gCAA6B;IAC7B,mCAAgC;IAChC,mCAAgC;IAOhC,iCAA8B;IAC9B,2BAAuB;IAGvB,6BAA0B;IAC1B,gCAA4B;IAG5B,qCAAgC;IAChC,qCAAgC;IAChC,qCAAgC;IAChC,qCAAgC;IAChC,sCAAiC;IACjC,sCAAiC;IACjC,sCAAiC;IACjC,sCAAiC;IACjC,uCAAkC;IAClC,yCAAoC;IACpC,yCAAqC;IACrC,mCAA+B;IAC/B,mCAA+B;IAC/B,wCAAoC;IACpC,kCAA8B;IAC9B,wCAAoC;IACpC,wCAAoC;IACpC,gCAA4B;IAC5B,wCAAoC;IACpC,uCAAmC;IACnC,sCAAkC;IAClC,qCAAiC;IAGjC,wCAAqC;IACrC,wCAAqC;IACrC,wCAAqC;IACrC,wCAAqC;IACrC,yCAAsC;IACtC,yCAAsC;IACtC,yCAAsC;IACtC,yCAAsC;IAGtC,kCAA+B;IAC/B,iCAA8B;IAC9B,iCAA8B;IAC9B,kCAA+B;IAC/B,kCAA+B;IAC/B,qCAAkC;IAClC,qCAAkC;IAClC,qCAAkC;IAClC,iCAA8B;IAC9B,oCAAiC;IACjC,qCAAkC;IAClC,kCAA+B;IAC/B,qCAAkC;IAClC,mCAAgC;IAGhC,yBAAsB;IACtB,gCAA2B;IAC3B,8BAA2B;IAG3B,gCAA8B;IAC9B,8BAA4B;IAC5B,+BAA6B;IAC7B,kCAAgC;IAChC,mCAAiC;IACjC,mCAAiC;IACjC,8BAA4B;IAG5B,yBAAuB;IACvB,yBAAuB;IACvB,yBAAuB;IACvB,yBAAuB;IACvB,yBAAuB;IACvB,yBAAuB;IAGvB,gCAA4B;IAG5B,wBAAoB;IACpB,gCAA6B;IAC7B,+BAA4B;IAC5B,kCAA8B;IAC9B,mCAA+B;IAC/B,mCAA+B;IAC/B,0BAAsB;IACtB,kCAA8B;IAC9B,kCAA+B;IAG/B,+BAA2B;IAC3B,oCAAgC;IAChC,oCAA+B;IAC/B,mCAA8B;IAC9B,oCAAgC;IAChC,sCAAkC;IAClC,iCAA6B;IAC7B,mCAA8B;IAC9B,8BAAyB;IACzB,mCAA8B;IAC9B,iCAA4B;IAC5B,gCAA2B;IAC3B,gCAA2B;IAC3B,oCAA+B;IAG/B,kCAA8B;IAC9B,uCAAmC;IA8QnC;;;;OAIG;IACH,sBAHW,KAAK,CAAC,MAAM,CAAC,GAAC,UAAU,GACtB,UAAU,CAmBtB;IAED;;;OAGG;IACH,8BAQC;IAED;;;OAGG;IACH,6BAKC;IAED;;;OAGG;IACH,+BAYC;IAED;;;OAGG;IACH,oCAIC;IAED;;;OAGG;IACH,yCAkBC;IAED;;;OAGG;IACH,sCAUC;IAED;;;OAGG;IACH,4BAUC;IAED;;;OAGG;IACH,iCAsBC;IAED;;;OAGG;IACH,yBAIC;IAED;;;;OAIG;IACH,6BAHW,MAAM,GACJ,QAAQ,CA2EpB;IAED;;;;;OAKG;IACH,8BAJW,KAAK,CAAC,MAAM,CAAC,GAAC,UAAU,UACxB,MAAM,GACJ,QAAQ,CAKpB;IAED;;;;;;OAMG;IACH,sBALW,IAAI,GAAC,IAAI,GACP,OAAO,CAAC,QAAQ,CAAC,CAiH7B;IAED;;;;;;;OAOG;IACH,uBANW,KAAK,CAAC,MAAM,CAAC,GAAC,WAAW,GAAC,UAAU,UACpC,MAAM,GACJ,QAAQ,CAwHpB;IAED;;;;;;OAMG;IACH,sBALW,YAAY,UACZ,MAAM,GACJ,QAAQ,CA8QpB;IAxhCD;;;;;OAKG;IACH,kBAJW,KAAK,CAAC,MAAM,CAAC,GAAC,UAAU,UACxB,MAAM,EAgBhB;IAJC,cAAkB;IAClB,8BAAgC;IAChC,aAA+B;IAC/B,4CAA0B;IAG5B;;;OAGG;IACH,qBAYC;IAED;;;;;OAKG;IACH,qBAJW,MAAM,GACJ,MAAM,CAYlB;IAED;;;;;OAKG;IACH,6BAJW,MAAM,GACJ,MAAM,CAiBlB;IAED;;;;OAIG;IACH,qBAHW,MAAM,SACN,MAAM,QAkBhB;IAED;;;;OAIG;IACH,UAFa,UAAU,CAYtB;IAED;;;OAGG;IACH,yBAQC;IAED;;;OAGG;IACH,wBAKC;IAED;;;OAGG;IACH,0BAYC;IAED;;;OAGG;IACH,+BAMC;IAED;;;OAGG;IACH,oCAmBC;IAED;;;OAGG;IACH,iCAUC;IAED;;;OAGG;IACH,uBAUC;IAED;;;OAGG;IACH,4BAsBC;IAED;;;OAGG;IACH,oBAIC;IAgxBD;;;;;OAKG;IACH,WAFa,UAAU,CAsFtB;IAED;;;OAGG;IACH,UAFa,MAAM,CA4GlB;CACF"}
1
+ {"version":3,"file":"DX7Voice.d.ts","sourceRoot":"","sources":["../../../src/utils/dx7/DX7Voice.js"],"names":[],"mappings":"AAwBA;;;;;;;;;;GAUG;AAEH;;;;;;;;;GASG;AAEH;;;;;;;;;;GAUG;AAEH;;;;;;GAMG;AAEH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8CG;AACH;IAGE,2BAAwB;IACxB,8BAA0B;IAC1B,6BAAwB;IAGxB,mCAA8B;IAC9B,mCAA8B;IAC9B,mCAA8B;IAC9B,mCAA8B;IAC9B,oCAA+B;IAC/B,oCAA+B;IAC/B,oCAA+B;IAC/B,oCAA+B;IAC/B,qCAAgC;IAChC,uCAAkC;IAClC,uCAAmC;IACnC,gCAA4B;IAC5B,sCAAkC;IAClC,kCAA8B;IAC9B,sCAAkC;IAClC,mCAA+B;IAC/B,qCAAiC;IAGjC,sCAAmC;IACnC,sCAAmC;IACnC,sCAAmC;IACnC,sCAAmC;IACnC,uCAAoC;IACpC,uCAAoC;IACpC,uCAAoC;IACpC,uCAAoC;IACpC,gCAA6B;IAC7B,+BAA4B;IAC5B,gCAA6B;IAC7B,gCAA6B;IAC7B,mCAAgC;IAChC,mCAAgC;IAChC,oCAAiC;IACjC,gCAA6B;IAC7B,mCAAgC;IAChC,mCAAgC;IAOhC,iCAA8B;IAC9B,2BAAuB;IAGvB,6BAA0B;IAC1B,gCAA4B;IAG5B,qCAAgC;IAChC,qCAAgC;IAChC,qCAAgC;IAChC,qCAAgC;IAChC,sCAAiC;IACjC,sCAAiC;IACjC,sCAAiC;IACjC,sCAAiC;IACjC,uCAAkC;IAClC,yCAAoC;IACpC,yCAAqC;IACrC,mCAA+B;IAC/B,mCAA+B;IAC/B,wCAAoC;IACpC,kCAA8B;IAC9B,wCAAoC;IACpC,wCAAoC;IACpC,gCAA4B;IAC5B,wCAAoC;IACpC,uCAAmC;IACnC,qCAAiC;IAGjC,wCAAqC;IACrC,wCAAqC;IACrC,wCAAqC;IACrC,wCAAqC;IACrC,yCAAsC;IACtC,yCAAsC;IACtC,yCAAsC;IACtC,yCAAsC;IAGtC,kCAA+B;IAC/B,iCAA8B;IAC9B,iCAA8B;IAC9B,kCAA+B;IAC/B,kCAA+B;IAC/B,qCAAkC;IAClC,qCAAkC;IAClC,qCAAkC;IAClC,iCAA8B;IAC9B,oCAAiC;IACjC,qCAAkC;IAClC,kCAA+B;IAC/B,qCAAkC;IAClC,mCAAgC;IAGhC,yBAAsB;IACtB,gCAA2B;IAC3B,8BAA2B;IAG3B,gCAA8B;IAC9B,8BAA4B;IAC5B,+BAA6B;IAC7B,kCAAgC;IAChC,mCAAiC;IACjC,mCAAiC;IACjC,8BAA4B;IAG5B,yBAAuB;IACvB,yBAAuB;IACvB,yBAAuB;IACvB,yBAAuB;IACvB,yBAAuB;IACvB,yBAAuB;IAGvB,gCAA4B;IAG5B,wBAAoB;IACpB,gCAA6B;IAC7B,+BAA4B;IAC5B,kCAA8B;IAC9B,mCAA+B;IAC/B,mCAA+B;IAC/B,0BAAsB;IACtB,kCAA8B;IAC9B,kCAA+B;IAG/B,+BAA2B;IAC3B,oCAAgC;IAChC,oCAA+B;IAC/B,mCAA8B;IAC9B,oCAAgC;IAChC,sCAAkC;IAClC,iCAA6B;IAC7B,mCAA8B;IAC9B,8BAAyB;IACzB,mCAA8B;IAC9B,iCAA4B;IAC5B,gCAA2B;IAC3B,gCAA2B;IAC3B,oCAA+B;IAG/B,kCAA8B;IAC9B,uCAAmC;IA4QnC;;;;OAIG;IACH,sBAHW,KAAK,CAAC,MAAM,CAAC,GAAC,UAAU,GACtB,UAAU,CAmBtB;IAED;;;OAGG;IACH,8BAQC;IAED;;;OAGG;IACH,6BAKC;IAED;;;OAGG;IACH,+BAYC;IAED;;;OAGG;IACH,oCAIC;IAED;;;OAGG;IACH,yCAkBC;IAED;;;OAGG;IACH,sCAQC;IAED;;;OAGG;IACH,4BAUC;IAED;;;OAGG;IACH,iCAsBC;IAED;;;OAGG;IACH,yBAIC;IAED;;;;OAIG;IACH,6BAHW,MAAM,GACJ,QAAQ,CA0EpB;IAED;;;;;OAKG;IACH,8BAJW,KAAK,CAAC,MAAM,CAAC,GAAC,UAAU,UACxB,MAAM,GACJ,QAAQ,CAKpB;IAED;;;;;;OAMG;IACH,sBALW,IAAI,GAAC,IAAI,GACP,OAAO,CAAC,QAAQ,CAAC,CAgH7B;IAED;;;;;;;OAOG;IACH,uBANW,KAAK,CAAC,MAAM,CAAC,GAAC,WAAW,GAAC,UAAU,UACpC,MAAM,GACJ,QAAQ,CAuHpB;IAED;;;;;;OAMG;IACH,sBALW,YAAY,UACZ,MAAM,GACJ,QAAQ,CAgRpB;IAnhCD;;;;;OAKG;IACH,kBAJW,KAAK,CAAC,MAAM,CAAC,GAAC,UAAU,UACxB,MAAM,EAgBhB;IAJC,cAAkB;IAClB,8BAAgC;IAChC,aAA+B;IAC/B,4CAA0B;IAG5B;;;OAGG;IACH,qBAYC;IAED;;;;;OAKG;IACH,qBAJW,MAAM,GACJ,MAAM,CAYlB;IAED;;;;;OAKG;IACH,6BAJW,MAAM,GACJ,MAAM,CAiBlB;IAED;;;;OAIG;IACH,qBAHW,MAAM,SACN,MAAM,QAkBhB;IAED;;;;OAIG;IACH,UAFa,UAAU,CAYtB;IAED;;;OAGG;IACH,yBAQC;IAED;;;OAGG;IACH,wBAKC;IAED;;;OAGG;IACH,0BAYC;IAED;;;OAGG;IACH,+BAMC;IAED;;;OAGG;IACH,oCAmBC;IAED;;;OAGG;IACH,iCAQC;IAED;;;OAGG;IACH,uBAUC;IAED;;;OAGG;IACH,4BAsBC;IAED;;;OAGG;IACH,oBAIC;IA6wBD;;;;;OAKG;IACH,WAFa,UAAU,CAqFtB;IAED;;;OAGG;IACH,UAFa,MAAM,CA4GlB;CACF"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "midiwire",
3
- "version": "0.13.1",
3
+ "version": "0.13.2",
4
4
  "description": "Declarative JavaScript library for browser-based MIDI control",
5
5
  "type": "module",
6
6
  "main": "./dist/midiwire.umd.js",
@@ -136,7 +136,7 @@ export class DX7Voice {
136
136
  static PACKED_OP_MOD_SENS = 13 // AMS and KVS packed
137
137
  static PACKED_OP_OUTPUT_LEVEL = 14
138
138
  static PACKED_OP_MODE_FREQ = 15 // Mode and Freq Coarse packed
139
- static PACKED_OP_DETUNE_FINE = 16 // OSC Detune and Freq Fine packed
139
+ static PACKED_OP_DETUNE_FINE = 16 // Freq Fine (full 7-bit value, range 0-99)
140
140
 
141
141
  // Packed voice offsets (after 6 operators = bytes 102+)
142
142
  static PACKED_PITCH_EG_RATE_1 = 102
@@ -191,7 +191,6 @@ export class DX7Voice {
191
191
  static UNPACKED_OP_MODE = 17 // Mode (0=ratio, 1=fixed)
192
192
  static UNPACKED_OP_KEY_VEL_SENS = 18
193
193
  static UNPACKED_OP_FREQ_COARSE = 19
194
- static UNPACKED_OP_OSC_DETUNE = 20
195
194
  static UNPACKED_OP_FREQ_FINE = 21
196
195
 
197
196
  // Unpacked pitch EG offsets (after 6 operators = index 138+)
@@ -484,10 +483,8 @@ export class DX7Voice {
484
483
  unpacked[dst + DX7Voice.UNPACKED_OP_MODE] = modeFreq & DX7Voice.MASK_1BIT
485
484
  unpacked[dst + DX7Voice.UNPACKED_OP_FREQ_COARSE] = (modeFreq >> 1) & DX7Voice.MASK_5BIT
486
485
 
487
- // OSC detune and frequency fine (bits 0-2 = OSC DET, bits 3-6 = FREQ FINE)
488
- const detuneFine = packed[src + DX7Voice.PACKED_OP_DETUNE_FINE] & DX7Voice.MASK_7BIT
489
- unpacked[dst + DX7Voice.UNPACKED_OP_OSC_DETUNE] = detuneFine & DX7Voice.MASK_3BIT
490
- unpacked[dst + DX7Voice.UNPACKED_OP_FREQ_FINE] = (detuneFine >> 3) & DX7Voice.MASK_4BIT
486
+ // Freq Fine is stored as a full 7-bit value in byte 16 (range 0-99)
487
+ unpacked[dst + DX7Voice.UNPACKED_OP_FREQ_FINE] = packed[src + DX7Voice.PACKED_OP_DETUNE_FINE] & DX7Voice.MASK_7BIT
491
488
  }
492
489
 
493
490
  /**
@@ -655,10 +652,8 @@ export class DX7Voice {
655
652
  const freq = unpacked[src + DX7Voice.UNPACKED_OP_FREQ_COARSE] & DX7Voice.MASK_5BIT
656
653
  packed[dst + DX7Voice.PACKED_OP_MODE_FREQ] = mode | (freq << 1)
657
654
 
658
- // Combine OSC detune and frequency fine
659
- const oscDetune = unpacked[src + DX7Voice.UNPACKED_OP_OSC_DETUNE] & DX7Voice.MASK_3BIT
660
- const freqFine = unpacked[src + DX7Voice.UNPACKED_OP_FREQ_FINE] & DX7Voice.MASK_4BIT
661
- packed[dst + DX7Voice.PACKED_OP_DETUNE_FINE] = oscDetune | (freqFine << 3)
655
+ // Freq Fine is stored as a full 7-bit value in byte 16 (range 0-99)
656
+ packed[dst + DX7Voice.PACKED_OP_DETUNE_FINE] = unpacked[src + DX7Voice.UNPACKED_OP_FREQ_FINE] & DX7Voice.MASK_7BIT
662
657
  }
663
658
 
664
659
  /**
@@ -755,7 +750,6 @@ export class DX7Voice {
755
750
  // Oscillator parameters
756
751
  unpacked[opOffset + DX7Voice.UNPACKED_OP_MODE] = 0 // Ratio mode
757
752
  unpacked[opOffset + DX7Voice.UNPACKED_OP_FREQ_COARSE] = DX7Voice.DEFAULT_FREQ_COARSE
758
- unpacked[opOffset + DX7Voice.UNPACKED_OP_OSC_DETUNE] = 0
759
753
  unpacked[opOffset + DX7Voice.UNPACKED_OP_FREQ_FINE] = 0
760
754
  }
761
755
 
@@ -879,9 +873,8 @@ export class DX7Voice {
879
873
  unpacked[dst + DX7Voice.UNPACKED_OP_OUTPUT_LEVEL] = voiceData[offset++]
880
874
  unpacked[dst + DX7Voice.UNPACKED_OP_MODE] = voiceData[offset++]
881
875
  unpacked[dst + DX7Voice.UNPACKED_OP_FREQ_COARSE] = voiceData[offset++]
882
- // FREQ_FINE and OSC_DETUNE order swapped from unpacked format
883
876
  unpacked[dst + DX7Voice.UNPACKED_OP_FREQ_FINE] = voiceData[offset++]
884
- unpacked[dst + DX7Voice.UNPACKED_OP_OSC_DETUNE] = voiceData[offset++]
877
+ offset++ // consume unused 21st VCED operator byte
885
878
  }
886
879
 
887
880
  // Pitch EG: 8 bytes
@@ -1008,9 +1001,8 @@ export class DX7Voice {
1008
1001
  unpacked[dst + DX7Voice.UNPACKED_OP_OUTPUT_LEVEL] = voiceData[offset++]
1009
1002
  unpacked[dst + DX7Voice.UNPACKED_OP_MODE] = voiceData[offset++]
1010
1003
  unpacked[dst + DX7Voice.UNPACKED_OP_FREQ_COARSE] = voiceData[offset++]
1011
- // FREQ_FINE and OSC_DETUNE order swapped from unpacked format
1012
1004
  unpacked[dst + DX7Voice.UNPACKED_OP_FREQ_FINE] = voiceData[offset++]
1013
- unpacked[dst + DX7Voice.UNPACKED_OP_OSC_DETUNE] = voiceData[offset++]
1005
+ offset++ // consume unused 21st VCED operator byte
1014
1006
  }
1015
1007
 
1016
1008
  // Pitch EG: 8 bytes
@@ -1219,9 +1211,11 @@ export class DX7Voice {
1219
1211
  7,
1220
1212
  )
1221
1213
 
1222
- // Detune (-7 to +7, stored as 0-14)
1214
+ // Detune (-7 to +7, stored as 0-14 where 7 = center/no detune)
1223
1215
  const detune = Number(opData.osc?.detune) || 0
1224
- setParam(opOffset + DX7Voice.UNPACKED_OP_DETUNE, detune + 7, `operators[${op}].osc.detune`, 0, 14)
1216
+ // Clamp to valid range -7 to +7, then add 7 to get stored value 0-14
1217
+ const clampedDetune = Math.max(-7, Math.min(7, detune))
1218
+ setParam(opOffset + DX7Voice.UNPACKED_OP_DETUNE, clampedDetune + 7, `operators[${op}].osc.detune`, 0, 14)
1225
1219
 
1226
1220
  // Amp mod sensitivity (0-3)
1227
1221
  setParam(
@@ -1350,7 +1344,7 @@ export class DX7Voice {
1350
1344
  for (let op = DX7Voice.NUM_OPERATORS - 1; op >= 0; op--) {
1351
1345
  const src = op * DX7Voice.UNPACKED_OP_SIZE
1352
1346
 
1353
- // Copy 21 bytes per operator, skipping bytes 18 and 22 in our format
1347
+ // Copy 21 bytes per operator (VCED format has 21 bytes, our unpacked has 23)
1354
1348
  result[offset++] = unpacked[src + DX7Voice.UNPACKED_OP_EG_RATE_1]
1355
1349
  result[offset++] = unpacked[src + DX7Voice.UNPACKED_OP_EG_RATE_2]
1356
1350
  result[offset++] = unpacked[src + DX7Voice.UNPACKED_OP_EG_RATE_3]
@@ -1373,9 +1367,8 @@ export class DX7Voice {
1373
1367
  result[offset++] = unpacked[src + DX7Voice.UNPACKED_OP_OUTPUT_LEVEL]
1374
1368
  result[offset++] = unpacked[src + DX7Voice.UNPACKED_OP_MODE]
1375
1369
  result[offset++] = unpacked[src + DX7Voice.UNPACKED_OP_FREQ_COARSE]
1376
- // VCED has OSC_DETUNE before FREQ_FINE (opposite of unpacked format)
1377
- result[offset++] = unpacked[src + DX7Voice.UNPACKED_OP_OSC_DETUNE]
1378
1370
  result[offset++] = unpacked[src + DX7Voice.UNPACKED_OP_FREQ_FINE]
1371
+ result[offset++] = 0 // unused 21st VCED operator byte (padding)
1379
1372
  }
1380
1373
 
1381
1374
  // Pitch EG: 8 bytes (Rates 1-4, Levels 1-4)
@@ -1450,7 +1443,7 @@ export class DX7Voice {
1450
1443
  operators.push({
1451
1444
  id: op + 1,
1452
1445
  osc: {
1453
- detune: unpacked[opOffset + DX7Voice.UNPACKED_OP_OSC_DETUNE],
1446
+ detune: unpacked[opOffset + DX7Voice.UNPACKED_OP_DETUNE] - 7, // Convert 0-14 to -7 to +7
1454
1447
  freq: {
1455
1448
  coarse: unpacked[opOffset + DX7Voice.UNPACKED_OP_FREQ_COARSE],
1456
1449
  fine: unpacked[opOffset + DX7Voice.UNPACKED_OP_FREQ_FINE],
@@ -363,7 +363,13 @@ describe("DX7Voice", () => {
363
363
  const reconstructedUnpacked = bass1reconstructed.unpack()
364
364
 
365
365
  for (let i = 0; i < DX7Voice.UNPACKED_SIZE; i++) {
366
- expect(reconstructedUnpacked[i]).toBe(originalUnpacked[i])
366
+ // Index 20 is now an unused zeroed byte (was UNPACKED_OP_OSC_DETUNE)
367
+ // Detune now goes to index 14 (UNPACKED_OP_DETUNE) from packed byte 12
368
+ if (i === 20) {
369
+ expect(reconstructedUnpacked[i]).toBe(0) // Unused byte is zeroed
370
+ } else {
371
+ expect(reconstructedUnpacked[i]).toBe(originalUnpacked[i])
372
+ }
367
373
  }
368
374
 
369
375
  expect(bass1reconstructed.name).toBe(bass1original.name)
@@ -467,7 +473,13 @@ describe("DX7Voice", () => {
467
473
  const reconstructedUnpacked = reconstructed.unpack()
468
474
 
469
475
  for (let i = 0; i < DX7Voice.UNPACKED_SIZE; i++) {
470
- expect(reconstructedUnpacked[i]).toBe(originalUnpacked[i])
476
+ // Index 20 is now an unused zeroed byte (was UNPACKED_OP_OSC_DETUNE)
477
+ // Detune now goes to index 14 (UNPACKED_OP_DETUNE) from packed byte 12
478
+ if (i === 20) {
479
+ expect(reconstructedUnpacked[i]).toBe(0) // Unused byte is zeroed
480
+ } else {
481
+ expect(reconstructedUnpacked[i]).toBe(originalUnpacked[i])
482
+ }
471
483
  }
472
484
  })
473
485
 
@@ -1112,25 +1124,23 @@ describe("DX7Voice", () => {
1112
1124
  const unpacked = new Uint8Array(DX7Voice.UNPACKED_SIZE)
1113
1125
 
1114
1126
  // Detune/Fine byte: bits 0-2 = OSC DET, bits 3-6 = FREQ FINE
1115
- packed[101] = 0b01011101 // Detune=5 (101), Fine=11 (1011)
1127
+ packed[101] = 93 // Freq Fine = 93 (full 7-bit value)
1116
1128
 
1117
1129
  voice._unpackOperatorFrequency(packed, unpacked, 85, 0)
1118
1130
 
1119
- expect(unpacked[20]).toBe(5) // OSC Detune (3 bits)
1120
- expect(unpacked[21]).toBe(11) // Fine freq (4 bits)
1131
+ expect(unpacked[21]).toBe(93) // Fine freq (7 bits, full range 0-99)
1121
1132
  })
1122
1133
 
1123
- it("should handle maximum detune and fine frequency", () => {
1134
+ it("should handle maximum fine frequency", () => {
1124
1135
  const packed = new Uint8Array(DX7Voice.PACKED_SIZE)
1125
1136
  const unpacked = new Uint8Array(DX7Voice.UNPACKED_SIZE)
1126
1137
 
1127
- // Max Detune=7 (111), Max Fine=15 (1111)
1128
- packed[101] = 0b01111111
1138
+ // Max Fine=99 (0x63 = 01100011)
1139
+ packed[101] = 99
1129
1140
 
1130
1141
  voice._unpackOperatorFrequency(packed, unpacked, 85, 0)
1131
1142
 
1132
- expect(unpacked[20]).toBe(7) // OSC Detune max (3 bits)
1133
- expect(unpacked[21]).toBe(15) // Fine freq max (4 bits)
1143
+ expect(unpacked[21]).toBe(99) // Fine freq max (7 bits, full range 0-99)
1134
1144
  })
1135
1145
  })
1136
1146
 
@@ -1474,16 +1484,15 @@ describe("DX7Voice", () => {
1474
1484
  expect(packed[100]).toBe(0b00001011) // Mode=1, Coarse=5
1475
1485
  })
1476
1486
 
1477
- it("should correctly combine OSC detune and fine frequency", () => {
1487
+ it("should correctly write fine frequency as 7-bit value", () => {
1478
1488
  const unpacked = new Uint8Array(DX7Voice.UNPACKED_SIZE)
1479
1489
  const packed = new Uint8Array(DX7Voice.PACKED_SIZE)
1480
1490
 
1481
- unpacked[20] = 5 // OSC Detune
1482
- unpacked[21] = 11 // Fine freq
1491
+ unpacked[21] = 93 // Fine freq (7-bit value)
1483
1492
 
1484
1493
  DX7Voice._packOperatorFrequency(unpacked, packed, 0, 85)
1485
1494
 
1486
- expect(packed[101]).toBe(0b01011101) // Detune=5, Fine=11
1495
+ expect(packed[101]).toBe(93) // Fine freq written directly as 7-bit value
1487
1496
  })
1488
1497
  })
1489
1498