audio-mixer-ui 0.5.1 → 0.5.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.
- package/dist/audio-mixer-ui.js +581 -502
- package/dist/audio-mixer-ui.umd.cjs +9 -9
- package/package.json +1 -1
package/dist/audio-mixer-ui.js
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import { ref as x, watch as v, unref as r, onScopeDispose as UU, readonly as yl, mergeModels as il, useCssVars as $, computed as
|
|
1
|
+
import { ref as x, watch as v, unref as r, onScopeDispose as UU, readonly as yl, mergeModels as il, useCssVars as $, computed as G, useTemplateRef as O, useModel as _, createElementBlock as Y, openBlock as X, normalizeClass as L, createElementVNode as h, createCommentVNode as f, Fragment as al, renderList as Sl, normalizeStyle as Il, renderSlot as Vl, toDisplayString as K, onUnmounted as cl, watchEffect as El, onMounted as el, createVNode as C, withCtx as D, createTextVNode as ol, withDirectives as vl, withKeys as FU, vModelText as Kl, withModifiers as kl, createBlock as nl } from "vue";
|
|
2
2
|
import { defineStore as sl } from "pinia";
|
|
3
3
|
var gl = function() {
|
|
4
4
|
if (typeof Map < "u")
|
|
5
5
|
return Map;
|
|
6
6
|
function d(l, U) {
|
|
7
7
|
var F = -1;
|
|
8
|
-
return l.some(function(Z,
|
|
9
|
-
return Z[0] === U ? (F =
|
|
8
|
+
return l.some(function(Z, Q) {
|
|
9
|
+
return Z[0] === U ? (F = Q, !0) : !1;
|
|
10
10
|
}), F;
|
|
11
11
|
}
|
|
12
12
|
return (
|
|
@@ -39,14 +39,14 @@ var gl = function() {
|
|
|
39
39
|
this.__entries__.splice(0);
|
|
40
40
|
}, l.prototype.forEach = function(U, F) {
|
|
41
41
|
F === void 0 && (F = null);
|
|
42
|
-
for (var Z = 0,
|
|
43
|
-
var
|
|
44
|
-
U.call(F,
|
|
42
|
+
for (var Z = 0, Q = this.__entries__; Z < Q.length; Z++) {
|
|
43
|
+
var V = Q[Z];
|
|
44
|
+
U.call(F, V[1], V[0]);
|
|
45
45
|
}
|
|
46
46
|
}, l;
|
|
47
47
|
}()
|
|
48
48
|
);
|
|
49
|
-
}(),
|
|
49
|
+
}(), ul = typeof window < "u" && typeof document < "u" && window.document === document, ml = function() {
|
|
50
50
|
return typeof global < "u" && global.Math === Math ? global : typeof self < "u" && self.Math === Math ? self : typeof window < "u" && window.Math === Math ? window : Function("return this")();
|
|
51
51
|
}(), dU = function() {
|
|
52
52
|
return typeof requestAnimationFrame == "function" ? requestAnimationFrame.bind(ml) : function(d) {
|
|
@@ -57,11 +57,11 @@ var gl = function() {
|
|
|
57
57
|
}(), ZU = 2;
|
|
58
58
|
function QU(d, l) {
|
|
59
59
|
var U = !1, F = !1, Z = 0;
|
|
60
|
-
function
|
|
60
|
+
function Q() {
|
|
61
61
|
U && (U = !1, d()), F && t();
|
|
62
62
|
}
|
|
63
|
-
function
|
|
64
|
-
dU(
|
|
63
|
+
function V() {
|
|
64
|
+
dU(Q);
|
|
65
65
|
}
|
|
66
66
|
function t() {
|
|
67
67
|
var R = Date.now();
|
|
@@ -70,7 +70,7 @@ function QU(d, l) {
|
|
|
70
70
|
return;
|
|
71
71
|
F = !0;
|
|
72
72
|
} else
|
|
73
|
-
U = !0, F = !1, setTimeout(
|
|
73
|
+
U = !0, F = !1, setTimeout(V, l);
|
|
74
74
|
Z = R;
|
|
75
75
|
}
|
|
76
76
|
return t;
|
|
@@ -97,17 +97,17 @@ var VU = 20, tU = ["top", "right", "bottom", "left", "width", "height", "size",
|
|
|
97
97
|
return U.broadcastActive();
|
|
98
98
|
}), l.length > 0;
|
|
99
99
|
}, d.prototype.connect_ = function() {
|
|
100
|
-
!
|
|
100
|
+
!ul || this.connected_ || (document.addEventListener("transitionend", this.onTransitionEnd_), window.addEventListener("resize", this.refresh), RU ? (this.mutationsObserver_ = new MutationObserver(this.refresh), this.mutationsObserver_.observe(document, {
|
|
101
101
|
attributes: !0,
|
|
102
102
|
childList: !0,
|
|
103
103
|
characterData: !0,
|
|
104
104
|
subtree: !0
|
|
105
105
|
})) : (document.addEventListener("DOMSubtreeModified", this.refresh), this.mutationEventsAdded_ = !0), this.connected_ = !0);
|
|
106
106
|
}, d.prototype.disconnect_ = function() {
|
|
107
|
-
!
|
|
107
|
+
!ul || !this.connected_ || (document.removeEventListener("transitionend", this.onTransitionEnd_), window.removeEventListener("resize", this.refresh), this.mutationsObserver_ && this.mutationsObserver_.disconnect(), this.mutationEventsAdded_ && document.removeEventListener("DOMSubtreeModified", this.refresh), this.mutationsObserver_ = null, this.mutationEventsAdded_ = !1, this.connected_ = !1);
|
|
108
108
|
}, d.prototype.onTransitionEnd_ = function(l) {
|
|
109
|
-
var U = l.propertyName, F = U === void 0 ? "" : U, Z = tU.some(function(
|
|
110
|
-
return !!~F.indexOf(
|
|
109
|
+
var U = l.propertyName, F = U === void 0 ? "" : U, Z = tU.some(function(Q) {
|
|
110
|
+
return !!~F.indexOf(Q);
|
|
111
111
|
});
|
|
112
112
|
Z && this.refresh();
|
|
113
113
|
}, d.getInstance = function() {
|
|
@@ -136,14 +136,14 @@ function Tl(d) {
|
|
|
136
136
|
for (var l = [], U = 1; U < arguments.length; U++)
|
|
137
137
|
l[U - 1] = arguments[U];
|
|
138
138
|
return l.reduce(function(F, Z) {
|
|
139
|
-
var
|
|
140
|
-
return F + Wl(
|
|
139
|
+
var Q = d["border-" + Z + "-width"];
|
|
140
|
+
return F + Wl(Q);
|
|
141
141
|
}, 0);
|
|
142
142
|
}
|
|
143
143
|
function nU(d) {
|
|
144
144
|
for (var l = ["top", "right", "bottom", "left"], U = {}, F = 0, Z = l; F < Z.length; F++) {
|
|
145
|
-
var
|
|
146
|
-
U[
|
|
145
|
+
var Q = Z[F], V = d["padding-" + Q];
|
|
146
|
+
U[Q] = Wl(V);
|
|
147
147
|
}
|
|
148
148
|
return U;
|
|
149
149
|
}
|
|
@@ -155,9 +155,9 @@ function WU(d) {
|
|
|
155
155
|
var l = d.clientWidth, U = d.clientHeight;
|
|
156
156
|
if (!l && !U)
|
|
157
157
|
return Dl;
|
|
158
|
-
var F = dl(d).getComputedStyle(d), Z = nU(F),
|
|
159
|
-
if (F.boxSizing === "border-box" && (Math.round(t +
|
|
160
|
-
var a = Math.round(t +
|
|
158
|
+
var F = dl(d).getComputedStyle(d), Z = nU(F), Q = Z.left + Z.right, V = Z.top + Z.bottom, t = Wl(F.width), R = Wl(F.height);
|
|
159
|
+
if (F.boxSizing === "border-box" && (Math.round(t + Q) !== l && (t -= Tl(F, "left", "right") + Q), Math.round(R + V) !== U && (R -= Tl(F, "top", "bottom") + V)), !cU(d)) {
|
|
160
|
+
var a = Math.round(t + Q) - l, n = Math.round(R + V) - U;
|
|
161
161
|
Math.abs(a) !== 1 && (t -= a), Math.abs(n) !== 1 && (R -= n);
|
|
162
162
|
}
|
|
163
163
|
return hl(Z.left, Z.top, t, R);
|
|
@@ -173,11 +173,11 @@ function cU(d) {
|
|
|
173
173
|
return d === dl(d).document.documentElement;
|
|
174
174
|
}
|
|
175
175
|
function eU(d) {
|
|
176
|
-
return
|
|
176
|
+
return ul ? bU(d) ? mU(d) : WU(d) : Dl;
|
|
177
177
|
}
|
|
178
178
|
function sU(d) {
|
|
179
|
-
var l = d.x, U = d.y, F = d.width, Z = d.height,
|
|
180
|
-
return Hl(
|
|
179
|
+
var l = d.x, U = d.y, F = d.width, Z = d.height, Q = typeof DOMRectReadOnly < "u" ? DOMRectReadOnly : Object, V = Object.create(Q.prototype);
|
|
180
|
+
return Hl(V, {
|
|
181
181
|
x: l,
|
|
182
182
|
y: U,
|
|
183
183
|
width: F,
|
|
@@ -186,7 +186,7 @@ function sU(d) {
|
|
|
186
186
|
right: l + F,
|
|
187
187
|
bottom: Z + U,
|
|
188
188
|
left: l
|
|
189
|
-
}),
|
|
189
|
+
}), V;
|
|
190
190
|
}
|
|
191
191
|
function hl(d, l, U, F) {
|
|
192
192
|
return { x: d, y: l, width: U, height: F };
|
|
@@ -284,7 +284,7 @@ var hU = (
|
|
|
284
284
|
return (l = jl.get(this))[d].apply(l, arguments);
|
|
285
285
|
};
|
|
286
286
|
});
|
|
287
|
-
var
|
|
287
|
+
var uU = function() {
|
|
288
288
|
return typeof ml.ResizeObserver < "u" ? ml.ResizeObserver : Pl;
|
|
289
289
|
}();
|
|
290
290
|
function ll(d) {
|
|
@@ -295,13 +295,13 @@ function ll(d) {
|
|
|
295
295
|
};
|
|
296
296
|
return v(() => r(d), () => {
|
|
297
297
|
Z();
|
|
298
|
-
const
|
|
299
|
-
if (!
|
|
300
|
-
F = new
|
|
298
|
+
const V = r(d);
|
|
299
|
+
if (!V) return;
|
|
300
|
+
F = new uU((R) => {
|
|
301
301
|
const a = R[0];
|
|
302
302
|
a && (l.value = a.contentRect.width, U.value = a.contentRect.height);
|
|
303
|
-
}), F.observe(
|
|
304
|
-
const t =
|
|
303
|
+
}), F.observe(V);
|
|
304
|
+
const t = V.getBoundingClientRect();
|
|
305
305
|
l.value = t.width, U.value = t.height;
|
|
306
306
|
}, { immediate: !0 }), UU(Z), {
|
|
307
307
|
width: yl(l),
|
|
@@ -313,7 +313,7 @@ const g = (d, l) => {
|
|
|
313
313
|
for (const [F, Z] of l)
|
|
314
314
|
U[F] = Z;
|
|
315
315
|
return U;
|
|
316
|
-
},
|
|
316
|
+
}, GU = {
|
|
317
317
|
key: 0,
|
|
318
318
|
class: "level"
|
|
319
319
|
}, iU = {
|
|
@@ -335,12 +335,12 @@ const g = (d, l) => {
|
|
|
335
335
|
setup(d) {
|
|
336
336
|
$((i) => ({
|
|
337
337
|
"083f3e45": c.value,
|
|
338
|
-
d4833630:
|
|
338
|
+
d4833630: W.value,
|
|
339
339
|
d6eaa016: J.value,
|
|
340
340
|
12894835: s.value,
|
|
341
341
|
"3e9a6a44": N.value
|
|
342
342
|
}));
|
|
343
|
-
const l = d, U = O("root"), { width: F, height: Z } = ll(U),
|
|
343
|
+
const l = d, U = O("root"), { width: F, height: Z } = ll(U), Q = G(() => Math.min(F.value, Z.value)), V = G(() => Math.max(F.value, Z.value)), t = G(() => F.value > Z.value), R = G(() => t.value ? "h-slide" : "v-slide"), a = _(d, "value"), n = G(() => Q.value * 0.8), m = G(() => Q.value * l.thumbLength * 0.8), W = G(() => (t.value ? m : n).value + "px"), c = G(() => (t.value ? n : m).value + "px"), s = G(() => Q.value * 0.1 + "px"), N = G(() => (V.value - m.value) * (a.value - l.min) / (l.max - l.min) + "px"), J = G(() => t.value ? "90deg" : "0deg"), p = x(!1), M = x(0), y = (i) => {
|
|
344
344
|
if (!U.value) return a.value;
|
|
345
345
|
const z = U.value.getBoundingClientRect(), P = i.touches ? i.touches[0].clientX : i.clientX, B = i.touches ? i.touches[0].clientY : i.clientY;
|
|
346
346
|
let S;
|
|
@@ -353,7 +353,7 @@ const g = (d, l) => {
|
|
|
353
353
|
}
|
|
354
354
|
const T = l.min + S * (l.max - l.min);
|
|
355
355
|
return l.step > 0 ? Math.round(T / l.step) * l.step : T;
|
|
356
|
-
},
|
|
356
|
+
}, u = (i) => {
|
|
357
357
|
i.preventDefault(), p.value = !0, M.value = a.value, a.value = y(i), U.value && U.value.setPointerCapture && U.value.setPointerCapture(i.pointerId), document.addEventListener("mousemove", k), document.addEventListener("mouseup", E);
|
|
358
358
|
}, k = (i) => {
|
|
359
359
|
p.value && (i.preventDefault(), a.value = y(i));
|
|
@@ -377,12 +377,12 @@ const g = (d, l) => {
|
|
|
377
377
|
class: L(R.value),
|
|
378
378
|
ref_key: "root",
|
|
379
379
|
ref: U,
|
|
380
|
-
onMousedown:
|
|
380
|
+
onMousedown: u,
|
|
381
381
|
onTouchstart: H,
|
|
382
382
|
style: { userSelect: "none", touchAction: "none" }
|
|
383
383
|
}, [
|
|
384
384
|
z[0] || (z[0] = h("div", { class: "track" }, null, -1)),
|
|
385
|
-
d.showLevel ? (X(), Y("div",
|
|
385
|
+
d.showLevel ? (X(), Y("div", GU, [
|
|
386
386
|
(X(), Y(al, null, Sl(10, (P) => h("div", {
|
|
387
387
|
class: L(["led", "led" + P])
|
|
388
388
|
}, [
|
|
@@ -407,16 +407,16 @@ const g = (d, l) => {
|
|
|
407
407
|
},
|
|
408
408
|
setup(d) {
|
|
409
409
|
$((t) => ({
|
|
410
|
-
"5fddb56d":
|
|
410
|
+
"5fddb56d": V.value
|
|
411
411
|
}));
|
|
412
|
-
const l = O("el"), { width: U, height: F } = ll(l), Z =
|
|
412
|
+
const l = O("el"), { width: U, height: F } = ll(l), Z = G(() => Math.min(U.value, F.value)), Q = G(() => U.value > F.value ? "h-text" : "v-text"), V = G(() => Z.value * 3 / 4 + "px");
|
|
413
413
|
return (t, R) => (X(), Y("div", {
|
|
414
414
|
ref_key: "el",
|
|
415
415
|
ref: l,
|
|
416
416
|
class: "outer"
|
|
417
417
|
}, [
|
|
418
418
|
h("div", {
|
|
419
|
-
class: L({ [
|
|
419
|
+
class: L({ [Q.value]: !0, [d.align]: !0 })
|
|
420
420
|
}, [
|
|
421
421
|
Vl(t.$slots, "default", {}, void 0, !0)
|
|
422
422
|
], 2)
|
|
@@ -432,7 +432,7 @@ const g = (d, l) => {
|
|
|
432
432
|
},
|
|
433
433
|
emits: ["update:mute", "update:solo"],
|
|
434
434
|
setup(d) {
|
|
435
|
-
const l = _(d, "mute"), U = _(d, "solo"), F = O("outer"), { width: Z, height:
|
|
435
|
+
const l = _(d, "mute"), U = _(d, "solo"), F = O("outer"), { width: Z, height: Q } = ll(F), V = G(() => Z.value > Q.value * 1.9);
|
|
436
436
|
function t() {
|
|
437
437
|
l.value = !l.value, U.value = !1;
|
|
438
438
|
}
|
|
@@ -451,7 +451,7 @@ const g = (d, l) => {
|
|
|
451
451
|
h("div", {
|
|
452
452
|
class: "s-label",
|
|
453
453
|
onClick: R
|
|
454
|
-
}, K(
|
|
454
|
+
}, K(V.value ? "SOLO" : "S"), 1),
|
|
455
455
|
h("div", {
|
|
456
456
|
class: L(["mute", { on: l.value }]),
|
|
457
457
|
onClick: t
|
|
@@ -459,10 +459,10 @@ const g = (d, l) => {
|
|
|
459
459
|
h("div", {
|
|
460
460
|
class: "m-label",
|
|
461
461
|
onClick: t
|
|
462
|
-
}, K(
|
|
462
|
+
}, K(V.value ? "MUTE" : "M"), 1)
|
|
463
463
|
], 512));
|
|
464
464
|
}
|
|
465
|
-
}, XU = /* @__PURE__ */ g(oU, [["__scopeId", "data-v-143eade0"]]),
|
|
465
|
+
}, XU = /* @__PURE__ */ g(oU, [["__scopeId", "data-v-143eade0"]]), Gl = {
|
|
466
466
|
// Enable development UI features (animations, random data, etc.)
|
|
467
467
|
enabled: !1,
|
|
468
468
|
// Specific feature flags
|
|
@@ -474,7 +474,7 @@ const g = (d, l) => {
|
|
|
474
474
|
// Enable other debug/dev features as needed
|
|
475
475
|
debugMode: !1
|
|
476
476
|
}
|
|
477
|
-
}, kF = () =>
|
|
477
|
+
}, kF = () => Gl.enabled, Ol = (d) => Gl.enabled && Gl.features[d], Ul = sl("audioState", {
|
|
478
478
|
state: () => ({
|
|
479
479
|
// Playback state
|
|
480
480
|
isPlaying: !1,
|
|
@@ -883,14 +883,14 @@ class Nl {
|
|
|
883
883
|
console.warn("Metronome buffer not available");
|
|
884
884
|
return;
|
|
885
885
|
}
|
|
886
|
-
const
|
|
887
|
-
|
|
888
|
-
const
|
|
889
|
-
|
|
886
|
+
const Q = this.audioContext.createBufferSource();
|
|
887
|
+
Q.buffer = Z;
|
|
888
|
+
const V = this.audioContext.createGain();
|
|
889
|
+
V.gain.value = F, Q.connect(V);
|
|
890
890
|
const t = this.getMetronomeOutput();
|
|
891
|
-
t ?
|
|
891
|
+
t ? V.connect(t) : V.connect(this.audioContext.destination);
|
|
892
892
|
const R = Math.max(l, this.audioContext.currentTime);
|
|
893
|
-
|
|
893
|
+
Q.start(R);
|
|
894
894
|
} catch (Z) {
|
|
895
895
|
console.warn("Buffer metronome playback failed:", Z);
|
|
896
896
|
}
|
|
@@ -917,11 +917,11 @@ class Nl {
|
|
|
917
917
|
]), [F, Z] = await Promise.all([
|
|
918
918
|
l.arrayBuffer(),
|
|
919
919
|
U.arrayBuffer()
|
|
920
|
-
]), [
|
|
920
|
+
]), [Q, V] = await Promise.all([
|
|
921
921
|
this.audioContext.decodeAudioData(F),
|
|
922
922
|
this.audioContext.decodeAudioData(Z)
|
|
923
923
|
]);
|
|
924
|
-
this.regularTickBuffer =
|
|
924
|
+
this.regularTickBuffer = Q, this.accentTickBuffer = V;
|
|
925
925
|
return;
|
|
926
926
|
}
|
|
927
927
|
} catch (l) {
|
|
@@ -1014,20 +1014,20 @@ class pl {
|
|
|
1014
1014
|
*/
|
|
1015
1015
|
playNote(l, U, F, Z) {
|
|
1016
1016
|
this._validateActive();
|
|
1017
|
-
const
|
|
1017
|
+
const Q = this.engine.audioContext.currentTime, V = `${this.partId}_${l}_${U}_${Date.now()}`;
|
|
1018
1018
|
let t = l, R = Z;
|
|
1019
|
-
if (l <
|
|
1020
|
-
const c =
|
|
1021
|
-
t =
|
|
1019
|
+
if (l < Q) {
|
|
1020
|
+
const c = Q - l;
|
|
1021
|
+
t = Q, R = Math.max(0, Z - c);
|
|
1022
1022
|
}
|
|
1023
1023
|
if (R <= 0)
|
|
1024
|
-
return
|
|
1025
|
-
const a = Math.max(0, (t -
|
|
1026
|
-
this.noteOn(U, F), this.scheduledEvents.delete(`${
|
|
1027
|
-
}, a), m = a + R * 1e3,
|
|
1028
|
-
this.noteOff(U), this.scheduledEvents.delete(`${
|
|
1024
|
+
return V;
|
|
1025
|
+
const a = Math.max(0, (t - Q) * 1e3), n = setTimeout(() => {
|
|
1026
|
+
this.noteOn(U, F), this.scheduledEvents.delete(`${V}_on`);
|
|
1027
|
+
}, a), m = a + R * 1e3, W = setTimeout(() => {
|
|
1028
|
+
this.noteOff(U), this.scheduledEvents.delete(`${V}_off`);
|
|
1029
1029
|
}, m);
|
|
1030
|
-
return this.scheduledEvents.set(`${
|
|
1030
|
+
return this.scheduledEvents.set(`${V}_on`, n), this.scheduledEvents.set(`${V}_off`, W), V;
|
|
1031
1031
|
}
|
|
1032
1032
|
/**
|
|
1033
1033
|
* Play a preview note (for pitch reference before singing)
|
|
@@ -1040,10 +1040,10 @@ class pl {
|
|
|
1040
1040
|
*/
|
|
1041
1041
|
playPreviewNote(l, U = {}) {
|
|
1042
1042
|
this._validateActive();
|
|
1043
|
-
const F = U.startTime ?? this.engine.audioContext.currentTime + 0.01, Z = U.duration ?? 0.5,
|
|
1044
|
-
let
|
|
1045
|
-
U.instrument !== void 0 && (
|
|
1046
|
-
this.isDestroyed || this.setInstrument(
|
|
1043
|
+
const F = U.startTime ?? this.engine.audioContext.currentTime + 0.01, Z = U.duration ?? 0.5, Q = U.velocity ?? 100;
|
|
1044
|
+
let V = null;
|
|
1045
|
+
U.instrument !== void 0 && (V = this.getInstrument(), this.setInstrument(U.instrument)), this.playNote(F, l, Q, Z), V !== null && setTimeout(() => {
|
|
1046
|
+
this.isDestroyed || this.setInstrument(V);
|
|
1047
1047
|
}, (Z + 0.1) * 1e3);
|
|
1048
1048
|
}
|
|
1049
1049
|
/**
|
|
@@ -1390,10 +1390,10 @@ class kU extends pl {
|
|
|
1390
1390
|
*/
|
|
1391
1391
|
playNote(l, U, F, Z) {
|
|
1392
1392
|
this._validateActive();
|
|
1393
|
-
const
|
|
1394
|
-
if (
|
|
1393
|
+
const Q = `${this.partId}_${l}_${U}_${Date.now()}`, V = this.engine._getSynthesizer();
|
|
1394
|
+
if (V && V.post) {
|
|
1395
1395
|
const t = Math.round(F * this.currentVolume);
|
|
1396
|
-
|
|
1396
|
+
V.post({
|
|
1397
1397
|
channelNumber: this.midiChannel,
|
|
1398
1398
|
type: "midiMessage",
|
|
1399
1399
|
data: {
|
|
@@ -1405,7 +1405,7 @@ class kU extends pl {
|
|
|
1405
1405
|
// SpessaSynth will schedule this precisely!
|
|
1406
1406
|
}
|
|
1407
1407
|
}
|
|
1408
|
-
}),
|
|
1408
|
+
}), V.post({
|
|
1409
1409
|
channelNumber: this.midiChannel,
|
|
1410
1410
|
type: "midiMessage",
|
|
1411
1411
|
data: {
|
|
@@ -1420,7 +1420,7 @@ class kU extends pl {
|
|
|
1420
1420
|
});
|
|
1421
1421
|
} else
|
|
1422
1422
|
return super.playNote(l, U, F, Z);
|
|
1423
|
-
return
|
|
1423
|
+
return Q;
|
|
1424
1424
|
}
|
|
1425
1425
|
/**
|
|
1426
1426
|
* Override allNotesOff to use SpessaSynth messaging system
|
|
@@ -1591,21 +1591,21 @@ class rU extends Nl {
|
|
|
1591
1591
|
const F = U.headers.get("content-length"), Z = F ? parseInt(F, 10) : null;
|
|
1592
1592
|
if (!Z || !U.body)
|
|
1593
1593
|
return await U.arrayBuffer();
|
|
1594
|
-
const
|
|
1595
|
-
let
|
|
1594
|
+
const Q = U.body.getReader();
|
|
1595
|
+
let V = 0;
|
|
1596
1596
|
const t = [];
|
|
1597
1597
|
for (; ; ) {
|
|
1598
|
-
const { done: n, value: m } = await
|
|
1598
|
+
const { done: n, value: m } = await Q.read();
|
|
1599
1599
|
if (n) break;
|
|
1600
|
-
t.push(m),
|
|
1601
|
-
const
|
|
1600
|
+
t.push(m), V += m.length;
|
|
1601
|
+
const W = V / Z, c = Math.round(W * 100);
|
|
1602
1602
|
this._emitProgress(
|
|
1603
1603
|
"loading-soundfont",
|
|
1604
|
-
`Downloading soundfont: ${c}% (${Math.round(
|
|
1605
|
-
|
|
1604
|
+
`Downloading soundfont: ${c}% (${Math.round(V / 1024)} KB / ${Math.round(Z / 1024)} KB)`,
|
|
1605
|
+
W
|
|
1606
1606
|
);
|
|
1607
1607
|
}
|
|
1608
|
-
const R = new Uint8Array(
|
|
1608
|
+
const R = new Uint8Array(V);
|
|
1609
1609
|
let a = 0;
|
|
1610
1610
|
for (const n of t)
|
|
1611
1611
|
R.set(n, a), a += n.length;
|
|
@@ -1653,15 +1653,15 @@ class rU extends Nl {
|
|
|
1653
1653
|
*/
|
|
1654
1654
|
async playMetronomeTick(l, U, F) {
|
|
1655
1655
|
try {
|
|
1656
|
-
const Z = this.getMetronomeChannel(),
|
|
1657
|
-
if (!Z || !
|
|
1656
|
+
const Z = this.getMetronomeChannel(), Q = this._getSynthesizer();
|
|
1657
|
+
if (!Z || !Q)
|
|
1658
1658
|
return super.playMetronomeTick(l, U, F);
|
|
1659
|
-
const
|
|
1660
|
-
|
|
1661
|
-
channelNumber:
|
|
1659
|
+
const V = 15, t = U ? 86 : 60, R = Math.round(Math.min(127, Math.max(0, F * (U ? 127 : 100)))), a = this.audioContext.currentTime, n = Math.max(l, a), m = n - a;
|
|
1660
|
+
Q.post ? (Q.post({
|
|
1661
|
+
channelNumber: V,
|
|
1662
1662
|
type: "midiMessage",
|
|
1663
1663
|
data: {
|
|
1664
|
-
messageData: [144 |
|
|
1664
|
+
messageData: [144 | V, t, R],
|
|
1665
1665
|
channelOffset: 0,
|
|
1666
1666
|
force: !1,
|
|
1667
1667
|
options: {
|
|
@@ -1669,11 +1669,11 @@ class rU extends Nl {
|
|
|
1669
1669
|
// Sample-accurate metronome timing!
|
|
1670
1670
|
}
|
|
1671
1671
|
}
|
|
1672
|
-
}),
|
|
1673
|
-
channelNumber:
|
|
1672
|
+
}), Q.post({
|
|
1673
|
+
channelNumber: V,
|
|
1674
1674
|
type: "midiMessage",
|
|
1675
1675
|
data: {
|
|
1676
|
-
messageData: [128 |
|
|
1676
|
+
messageData: [128 | V, t, 0],
|
|
1677
1677
|
channelOffset: 0,
|
|
1678
1678
|
force: !1,
|
|
1679
1679
|
options: {
|
|
@@ -1681,11 +1681,11 @@ class rU extends Nl {
|
|
|
1681
1681
|
// Precise tick duration!
|
|
1682
1682
|
}
|
|
1683
1683
|
}
|
|
1684
|
-
})) : m <= 0.01 ? (
|
|
1685
|
-
|
|
1684
|
+
})) : m <= 0.01 ? (Q.noteOn && Q.noteOn(V, t, R), setTimeout(() => {
|
|
1685
|
+
Q.noteOff && Q.noteOff(V, t);
|
|
1686
1686
|
}, 100)) : setTimeout(() => {
|
|
1687
|
-
|
|
1688
|
-
|
|
1687
|
+
Q.noteOn && Q.noteOn(V, t, R), setTimeout(() => {
|
|
1688
|
+
Q.noteOff && Q.noteOff(V, t);
|
|
1689
1689
|
}, 100);
|
|
1690
1690
|
}, m * 1e3);
|
|
1691
1691
|
} catch (Z) {
|
|
@@ -1768,19 +1768,19 @@ class LU {
|
|
|
1768
1768
|
* Parses URL query parameters (track, prog) from legacy format
|
|
1769
1769
|
* @private
|
|
1770
1770
|
* @param {Array} legacyParts - Array of part objects with url, name, volume
|
|
1771
|
-
* @returns {Object} Parts object with
|
|
1771
|
+
* @returns {Object} Parts object with channel and instrument
|
|
1772
1772
|
*/
|
|
1773
1773
|
_convertLegacyParts(l) {
|
|
1774
1774
|
const U = {};
|
|
1775
1775
|
for (const F of l) {
|
|
1776
1776
|
if (!F.name || !F.url)
|
|
1777
1777
|
continue;
|
|
1778
|
-
const Z = F.name.toLowerCase(),
|
|
1779
|
-
if (
|
|
1780
|
-
const t = parseInt(
|
|
1781
|
-
t !== 0 && (
|
|
1778
|
+
const Z = F.name.toLowerCase(), Q = this._parseUrlParams(F.url), V = {};
|
|
1779
|
+
if (Q.track !== void 0 && (V.channel = parseInt(Q.track, 10)), Q.prog !== void 0) {
|
|
1780
|
+
const t = parseInt(Q.prog, 10);
|
|
1781
|
+
t !== 0 && (V.instrument = t);
|
|
1782
1782
|
}
|
|
1783
|
-
|
|
1783
|
+
V.channel !== void 0 && (U[Z] = V);
|
|
1784
1784
|
}
|
|
1785
1785
|
return U;
|
|
1786
1786
|
}
|
|
@@ -1795,9 +1795,9 @@ class LU {
|
|
|
1795
1795
|
if (F === -1)
|
|
1796
1796
|
return U;
|
|
1797
1797
|
const Z = l.substring(F + 1).split("&");
|
|
1798
|
-
for (const
|
|
1799
|
-
const [
|
|
1800
|
-
|
|
1798
|
+
for (const Q of Z) {
|
|
1799
|
+
const [V, t] = Q.split("=");
|
|
1800
|
+
V && t !== void 0 && (U[V] = t);
|
|
1801
1801
|
}
|
|
1802
1802
|
return U;
|
|
1803
1803
|
}
|
|
@@ -1809,16 +1809,16 @@ class LU {
|
|
|
1809
1809
|
const U = new Uint8Array(l);
|
|
1810
1810
|
if (!(U[0] === 77 && U[1] === 84 && U[2] === 104 && U[3] === 100))
|
|
1811
1811
|
throw new Error("Not a valid MIDI file");
|
|
1812
|
-
const F = this._bytesToNumber(U.slice(4, 8)), Z = this._bytesToNumber(U.slice(8, 10)),
|
|
1812
|
+
const F = this._bytesToNumber(U.slice(4, 8)), Z = this._bytesToNumber(U.slice(8, 10)), Q = this._bytesToNumber(U.slice(10, 12)), V = this._bytesToNumber(U.slice(12, 14)), t = V & 32768 ? null : V, R = {
|
|
1813
1813
|
format: Z,
|
|
1814
1814
|
ticksPerBeat: t,
|
|
1815
1815
|
tracks: [],
|
|
1816
1816
|
duration: 0
|
|
1817
1817
|
};
|
|
1818
1818
|
let a = 8 + F;
|
|
1819
|
-
for (let n = 0; n <
|
|
1819
|
+
for (let n = 0; n < Q; n++)
|
|
1820
1820
|
if (U[a] === 77 && U[a + 1] === 84 && U[a + 2] === 114 && U[a + 3] === 107) {
|
|
1821
|
-
const m = this._bytesToNumber(U.slice(a + 4, a + 8)),
|
|
1821
|
+
const m = this._bytesToNumber(U.slice(a + 4, a + 8)), W = U.slice(a + 8, a + 8 + m), c = this._parseTrack(W);
|
|
1822
1822
|
R.tracks.push(c), a += 8 + m;
|
|
1823
1823
|
} else
|
|
1824
1824
|
throw new Error(`Invalid track header at position ${a}`);
|
|
@@ -1836,20 +1836,20 @@ class LU {
|
|
|
1836
1836
|
events: [],
|
|
1837
1837
|
duration: 0
|
|
1838
1838
|
};
|
|
1839
|
-
let F = 0, Z = 0,
|
|
1839
|
+
let F = 0, Z = 0, Q = null;
|
|
1840
1840
|
for (; F < l.length; ) {
|
|
1841
|
-
let
|
|
1841
|
+
let V = 0, t = 0;
|
|
1842
1842
|
do
|
|
1843
|
-
t = l[F++],
|
|
1843
|
+
t = l[F++], V = V << 7 | t & 127;
|
|
1844
1844
|
while (t & 128);
|
|
1845
|
-
Z +=
|
|
1845
|
+
Z += V, t = l[F++];
|
|
1846
1846
|
let R = t;
|
|
1847
1847
|
if (t & 128)
|
|
1848
|
-
|
|
1848
|
+
Q = R;
|
|
1849
1849
|
else {
|
|
1850
|
-
if (
|
|
1850
|
+
if (Q === null)
|
|
1851
1851
|
throw new Error("Running status byte encountered before status byte");
|
|
1852
|
-
R =
|
|
1852
|
+
R = Q, F--;
|
|
1853
1853
|
}
|
|
1854
1854
|
if (R === 255) {
|
|
1855
1855
|
const a = l[F++], n = this._readVariableLengthValue(l, F);
|
|
@@ -1873,7 +1873,7 @@ class LU {
|
|
|
1873
1873
|
});
|
|
1874
1874
|
break;
|
|
1875
1875
|
case 81:
|
|
1876
|
-
const
|
|
1876
|
+
const W = this._bytesToNumber(m), c = Math.round(6e7 / W);
|
|
1877
1877
|
U.events.push({
|
|
1878
1878
|
type: "tempo",
|
|
1879
1879
|
bpm: c,
|
|
@@ -1977,13 +1977,13 @@ class LU {
|
|
|
1977
1977
|
ticksPerBeat: l.ticksPerBeat
|
|
1978
1978
|
};
|
|
1979
1979
|
l.tracks.forEach((F, Z) => {
|
|
1980
|
-
if (F.name && !U.title && (U.title = F.name), F.events.filter((
|
|
1981
|
-
const
|
|
1982
|
-
(
|
|
1980
|
+
if (F.name && !U.title && (U.title = F.name), F.events.filter((Q) => Q.type === "text").forEach((Q) => {
|
|
1981
|
+
const V = Q.text.toLowerCase();
|
|
1982
|
+
(V.includes("compos") || V.includes("by")) && !U.composer && (U.composer = Q.text);
|
|
1983
1983
|
}), F.name) {
|
|
1984
|
-
const
|
|
1985
|
-
for (const
|
|
1986
|
-
if (
|
|
1984
|
+
const Q = F.name.toLowerCase();
|
|
1985
|
+
for (const V of this.partNames)
|
|
1986
|
+
if (Q.includes(V)) {
|
|
1987
1987
|
U.partNames.push({
|
|
1988
1988
|
index: Z,
|
|
1989
1989
|
name: F.name
|
|
@@ -2013,24 +2013,24 @@ class LU {
|
|
|
2013
2013
|
m.type === "noteOff" && m.tick > Z && (Z = m.tick);
|
|
2014
2014
|
});
|
|
2015
2015
|
}), Z === 0 && (Z = U * 8);
|
|
2016
|
-
const
|
|
2016
|
+
const Q = [], V = F.filter((n) => n.type === "timeSignature").sort((n, m) => n.tick - m.tick);
|
|
2017
2017
|
let t = { numerator: 4, denominator: 4 }, R = 0, a = 0;
|
|
2018
2018
|
for (; R < Z; ) {
|
|
2019
|
-
for (; a <
|
|
2020
|
-
t =
|
|
2019
|
+
for (; a < V.length && V[a].tick <= R; )
|
|
2020
|
+
t = V[a], a++;
|
|
2021
2021
|
let n;
|
|
2022
2022
|
n = R + U * 4 * t.numerator / t.denominator;
|
|
2023
|
-
const m = t.numerator,
|
|
2023
|
+
const m = t.numerator, W = [], c = U * (4 / t.denominator);
|
|
2024
2024
|
for (let s = 0; s < m; s++) {
|
|
2025
2025
|
const N = R + s * c, J = this._ticksToTime(N, l);
|
|
2026
|
-
|
|
2026
|
+
W.push(J);
|
|
2027
2027
|
}
|
|
2028
|
-
|
|
2028
|
+
Q.push({
|
|
2029
2029
|
sig: [t.numerator, t.denominator],
|
|
2030
|
-
beats:
|
|
2030
|
+
beats: W
|
|
2031
2031
|
}), R = n;
|
|
2032
2032
|
}
|
|
2033
|
-
this.parsedData.barStructure =
|
|
2033
|
+
this.parsedData.barStructure = Q;
|
|
2034
2034
|
}
|
|
2035
2035
|
/**
|
|
2036
2036
|
* Extract notes for each voice part
|
|
@@ -2039,71 +2039,156 @@ class LU {
|
|
|
2039
2039
|
_extractParts(l) {
|
|
2040
2040
|
const U = {}, F = l.ticksPerBeat;
|
|
2041
2041
|
if (this.metadataOverrides.parts)
|
|
2042
|
-
for (const [Z,
|
|
2043
|
-
if (
|
|
2044
|
-
|
|
2045
|
-
|
|
2046
|
-
|
|
2047
|
-
|
|
2048
|
-
|
|
2049
|
-
|
|
2050
|
-
|
|
2042
|
+
for (const [Z, Q] of Object.entries(this.metadataOverrides.parts)) {
|
|
2043
|
+
if (Q.channel !== void 0 && Q.channel !== null) {
|
|
2044
|
+
if (Q.channel === 15) {
|
|
2045
|
+
console.error(`Part "${Z}" uses channel 15 which is reserved for metronome. Skipping.`);
|
|
2046
|
+
continue;
|
|
2047
|
+
}
|
|
2048
|
+
if (Q.channel === 9 && console.warn(`Part "${Z}" uses channel 9 (drums/percussion). This may not be appropriate for vocal parts.`), Q.channel < 0 || Q.channel > 15) {
|
|
2049
|
+
console.error(`Part "${Z}" has invalid channel ${Q.channel}. MIDI channels must be 0-15. Skipping.`);
|
|
2050
|
+
continue;
|
|
2051
|
+
}
|
|
2051
2052
|
}
|
|
2052
|
-
if (!Q)
|
|
2053
|
+
if (Q.channel === void 0 && !Q.trackIndex && Q.trackIndex !== 0 && !Q.trackName)
|
|
2053
2054
|
continue;
|
|
2054
|
-
|
|
2055
|
-
|
|
2055
|
+
let V;
|
|
2056
|
+
if (Q.channel !== void 0 && Q.channel !== null) {
|
|
2057
|
+
if (V = this._extractPartDataByChannel(Q.channel, l, F), !V || V.notes.length === 0) {
|
|
2058
|
+
console.warn(`Part "${Z}" specified channel ${Q.channel} but no notes found on that channel. Skipping.`);
|
|
2059
|
+
continue;
|
|
2060
|
+
}
|
|
2061
|
+
} else if (Q.trackIndex !== void 0 && Q.trackIndex !== null) {
|
|
2062
|
+
const t = Q.trackIndex;
|
|
2063
|
+
if (t >= 0 && t < l.tracks.length) {
|
|
2064
|
+
const R = l.tracks[t];
|
|
2065
|
+
V = this._extractPartDataFromTrack(R, t, l, F);
|
|
2066
|
+
} else {
|
|
2067
|
+
console.warn(`Part "${Z}" specified trackIndex ${t} but track not found. Skipping.`);
|
|
2068
|
+
continue;
|
|
2069
|
+
}
|
|
2070
|
+
} else if (Q.trackName) {
|
|
2071
|
+
const t = l.tracks.findIndex((R) => R.name === Q.trackName);
|
|
2072
|
+
if (t !== -1) {
|
|
2073
|
+
const R = l.tracks[t];
|
|
2074
|
+
V = this._extractPartDataFromTrack(R, t, l, F);
|
|
2075
|
+
} else {
|
|
2076
|
+
console.warn(`Part "${Z}" specified trackName "${Q.trackName}" but track not found. Skipping.`);
|
|
2077
|
+
continue;
|
|
2078
|
+
}
|
|
2079
|
+
}
|
|
2080
|
+
V && (Q.instrument !== void 0 && Q.instrument !== null && (V.defaultInstrument = this._resolveInstrument(Q.instrument)), U[Z] = V);
|
|
2056
2081
|
}
|
|
2057
2082
|
else
|
|
2058
|
-
l.tracks.forEach((Z,
|
|
2083
|
+
l.tracks.forEach((Z, Q) => {
|
|
2059
2084
|
if (!Z.notes.length) return;
|
|
2060
|
-
let
|
|
2085
|
+
let V = null;
|
|
2061
2086
|
if (Z.name) {
|
|
2062
2087
|
const a = Z.name.toLowerCase();
|
|
2063
2088
|
for (const n of this.partNames)
|
|
2064
2089
|
if (n.length === 1) {
|
|
2065
2090
|
if (a === n) {
|
|
2066
|
-
|
|
2091
|
+
V = n;
|
|
2067
2092
|
break;
|
|
2068
2093
|
}
|
|
2069
2094
|
} else if (a.includes(n)) {
|
|
2070
|
-
|
|
2095
|
+
V = n;
|
|
2071
2096
|
break;
|
|
2072
2097
|
}
|
|
2073
2098
|
}
|
|
2074
|
-
|
|
2075
|
-
let t =
|
|
2099
|
+
V || (V = Z.name || `Track ${Q + 1}`), V === "s" && (V = "soprano"), V === "a" && (V = "alto"), V === "t" && (V = "tenor"), V === "b" && (V = "bass");
|
|
2100
|
+
let t = V, R = 2;
|
|
2076
2101
|
for (; U[t]; )
|
|
2077
|
-
t = `${
|
|
2078
|
-
|
|
2102
|
+
t = `${V} ${R}`, R++;
|
|
2103
|
+
V = t, U[V] = this._extractPartDataFromTrack(Z, Q, l, F);
|
|
2079
2104
|
});
|
|
2080
2105
|
this.parsedData.parts = U;
|
|
2081
2106
|
}
|
|
2107
|
+
/**
|
|
2108
|
+
* Extract part data by MIDI channel (merges notes from all tracks using this channel)
|
|
2109
|
+
* @private
|
|
2110
|
+
*/
|
|
2111
|
+
_extractPartDataByChannel(l, U, F) {
|
|
2112
|
+
const Z = [], Q = [], V = [], t = [];
|
|
2113
|
+
U.tracks.forEach((a, n) => {
|
|
2114
|
+
const m = {};
|
|
2115
|
+
a.notes.forEach((W) => {
|
|
2116
|
+
if (W.channel === l) {
|
|
2117
|
+
if (W.type === "noteOn")
|
|
2118
|
+
m[W.noteNumber] = {
|
|
2119
|
+
tick: W.tick,
|
|
2120
|
+
velocity: W.velocity
|
|
2121
|
+
};
|
|
2122
|
+
else if (W.type === "noteOff" && m[W.noteNumber]) {
|
|
2123
|
+
const c = m[W.noteNumber], s = W.tick - c.tick;
|
|
2124
|
+
Z.push({
|
|
2125
|
+
pitch: W.noteNumber,
|
|
2126
|
+
name: this._midiNoteToName(W.noteNumber),
|
|
2127
|
+
startTick: c.tick,
|
|
2128
|
+
endTick: W.tick,
|
|
2129
|
+
duration: s,
|
|
2130
|
+
startTime: this._ticksToTime(c.tick, U),
|
|
2131
|
+
endTime: this._ticksToTime(W.tick, U),
|
|
2132
|
+
velocity: c.velocity,
|
|
2133
|
+
channel: l,
|
|
2134
|
+
sourceTrackIndex: n
|
|
2135
|
+
}), delete m[W.noteNumber];
|
|
2136
|
+
}
|
|
2137
|
+
}
|
|
2138
|
+
}), a.lyrics.forEach((W) => {
|
|
2139
|
+
Q.push({
|
|
2140
|
+
text: W.text,
|
|
2141
|
+
tick: W.tick,
|
|
2142
|
+
time: W.tick / F
|
|
2143
|
+
});
|
|
2144
|
+
}), a.events.filter((W) => W.type === "programChange" && W.channel === l).forEach((W) => {
|
|
2145
|
+
V.push({
|
|
2146
|
+
programNumber: W.programNumber,
|
|
2147
|
+
tick: W.tick,
|
|
2148
|
+
time: this._ticksToTime(W.tick, U),
|
|
2149
|
+
sourceTrackIndex: n
|
|
2150
|
+
});
|
|
2151
|
+
}), a.notes.some((W) => W.channel === l) && t.push(n);
|
|
2152
|
+
}), Z.sort((a, n) => a.startTick - n.startTick), Q.sort((a, n) => a.tick - n.tick), V.sort((a, n) => a.tick - n.tick);
|
|
2153
|
+
const R = V.length > 0 ? V[0].programNumber : 0;
|
|
2154
|
+
return {
|
|
2155
|
+
notes: Z,
|
|
2156
|
+
lyrics: Q,
|
|
2157
|
+
channel: l,
|
|
2158
|
+
trackIndices: t,
|
|
2159
|
+
// All track indices that contributed
|
|
2160
|
+
programChanges: V,
|
|
2161
|
+
defaultInstrument: R
|
|
2162
|
+
};
|
|
2163
|
+
}
|
|
2082
2164
|
/**
|
|
2083
2165
|
* Extract part data from a MIDI track
|
|
2084
2166
|
* @private
|
|
2085
2167
|
*/
|
|
2086
2168
|
_extractPartDataFromTrack(l, U, F, Z) {
|
|
2087
|
-
const
|
|
2169
|
+
const Q = [], V = {};
|
|
2088
2170
|
l.notes.forEach((n) => {
|
|
2089
2171
|
if (n.type === "noteOn")
|
|
2090
|
-
|
|
2172
|
+
V[n.noteNumber] = {
|
|
2091
2173
|
tick: n.tick,
|
|
2092
|
-
velocity: n.velocity
|
|
2174
|
+
velocity: n.velocity,
|
|
2175
|
+
channel: n.channel
|
|
2093
2176
|
};
|
|
2094
|
-
else if (n.type === "noteOff" &&
|
|
2095
|
-
const m =
|
|
2096
|
-
|
|
2177
|
+
else if (n.type === "noteOff" && V[n.noteNumber]) {
|
|
2178
|
+
const m = V[n.noteNumber], W = n.tick - m.tick;
|
|
2179
|
+
Q.push({
|
|
2097
2180
|
pitch: n.noteNumber,
|
|
2098
2181
|
name: this._midiNoteToName(n.noteNumber),
|
|
2099
2182
|
startTick: m.tick,
|
|
2100
2183
|
endTick: n.tick,
|
|
2101
|
-
duration:
|
|
2184
|
+
duration: W,
|
|
2102
2185
|
// Convert ticks to actual time considering tempo changes
|
|
2103
2186
|
startTime: this._ticksToTime(m.tick, F),
|
|
2104
2187
|
endTime: this._ticksToTime(n.tick, F),
|
|
2105
|
-
velocity: m.velocity
|
|
2106
|
-
|
|
2188
|
+
velocity: m.velocity,
|
|
2189
|
+
channel: m.channel,
|
|
2190
|
+
sourceTrackIndex: U
|
|
2191
|
+
}), delete V[n.noteNumber];
|
|
2107
2192
|
}
|
|
2108
2193
|
});
|
|
2109
2194
|
const t = l.lyrics.map((n) => ({
|
|
@@ -2112,14 +2197,14 @@ class LU {
|
|
|
2112
2197
|
time: n.tick / Z
|
|
2113
2198
|
// Time in quarter notes
|
|
2114
2199
|
}));
|
|
2115
|
-
|
|
2200
|
+
Q.sort((n, m) => n.startTick - m.startTick);
|
|
2116
2201
|
const R = l.events.filter((n) => n.type === "programChange").map((n) => ({
|
|
2117
2202
|
programNumber: n.programNumber,
|
|
2118
2203
|
tick: n.tick,
|
|
2119
2204
|
time: this._ticksToTime(n.tick, F)
|
|
2120
2205
|
})).sort((n, m) => n.tick - m.tick), a = R.length > 0 ? R[0].programNumber : 0;
|
|
2121
2206
|
return {
|
|
2122
|
-
notes:
|
|
2207
|
+
notes: Q,
|
|
2123
2208
|
lyrics: t,
|
|
2124
2209
|
trackIndex: U,
|
|
2125
2210
|
programChanges: R,
|
|
@@ -2181,11 +2266,11 @@ class LU {
|
|
|
2181
2266
|
* @private
|
|
2182
2267
|
*/
|
|
2183
2268
|
_readVariableLengthValue(l, U) {
|
|
2184
|
-
let F = 0, Z,
|
|
2269
|
+
let F = 0, Z, Q = 0;
|
|
2185
2270
|
do
|
|
2186
|
-
Z = l[U +
|
|
2271
|
+
Z = l[U + Q++], F = F << 7 | Z & 127;
|
|
2187
2272
|
while (Z & 128);
|
|
2188
|
-
return { value: F, bytesRead:
|
|
2273
|
+
return { value: F, bytesRead: Q };
|
|
2189
2274
|
}
|
|
2190
2275
|
/**
|
|
2191
2276
|
* Convert ticks to time in seconds considering tempo changes within bars
|
|
@@ -2198,20 +2283,20 @@ class LU {
|
|
|
2198
2283
|
a.type === "tempo" && Z.push(a);
|
|
2199
2284
|
});
|
|
2200
2285
|
}), Z.sort((R, a) => R.tick - a.tick);
|
|
2201
|
-
let
|
|
2286
|
+
let Q = 0, V = 0, t = 120;
|
|
2202
2287
|
for (const R of Z) {
|
|
2203
2288
|
if (R.tick > l) break;
|
|
2204
|
-
if (R.tick >
|
|
2205
|
-
const a = (R.tick -
|
|
2206
|
-
|
|
2289
|
+
if (R.tick > V) {
|
|
2290
|
+
const a = (R.tick - V) / F * (60 / t);
|
|
2291
|
+
Q += a, V = R.tick;
|
|
2207
2292
|
}
|
|
2208
2293
|
t = R.bpm;
|
|
2209
2294
|
}
|
|
2210
|
-
if (l >
|
|
2211
|
-
const R = (l -
|
|
2212
|
-
|
|
2295
|
+
if (l > V) {
|
|
2296
|
+
const R = (l - V) / F * (60 / t);
|
|
2297
|
+
Q += R;
|
|
2213
2298
|
}
|
|
2214
|
-
return
|
|
2299
|
+
return Q;
|
|
2215
2300
|
}
|
|
2216
2301
|
}
|
|
2217
2302
|
class CU {
|
|
@@ -2239,18 +2324,18 @@ class CU {
|
|
|
2239
2324
|
*/
|
|
2240
2325
|
generateBarOrder(l, U) {
|
|
2241
2326
|
const F = [], Z = {};
|
|
2242
|
-
for (const
|
|
2243
|
-
const
|
|
2244
|
-
if (!
|
|
2245
|
-
throw new Error(`Invalid section index: ${
|
|
2246
|
-
const t =
|
|
2327
|
+
for (const Q of U) {
|
|
2328
|
+
const V = l[Q.section];
|
|
2329
|
+
if (!V)
|
|
2330
|
+
throw new Error(`Invalid section index: ${Q.section}`);
|
|
2331
|
+
const t = Q.section;
|
|
2247
2332
|
Z[t] || (Z[t] = 0), Z[t]++;
|
|
2248
|
-
const R = Z[t], a =
|
|
2249
|
-
for (let
|
|
2250
|
-
this._shouldPlayBar(
|
|
2251
|
-
barNumber:
|
|
2333
|
+
const R = Z[t], a = Q.from !== void 0 ? Q.from : this._getSectionStartBar(l, Q.section), n = Q.to !== void 0 ? Q.to : V.to, m = Q.as || 1;
|
|
2334
|
+
for (let W = a; W <= n; W++)
|
|
2335
|
+
this._shouldPlayBar(V, W, m) && F.push({
|
|
2336
|
+
barNumber: W,
|
|
2252
2337
|
repeat: R,
|
|
2253
|
-
sectionIndex:
|
|
2338
|
+
sectionIndex: Q.section,
|
|
2254
2339
|
voltaTime: m
|
|
2255
2340
|
});
|
|
2256
2341
|
}
|
|
@@ -2264,13 +2349,13 @@ class CU {
|
|
|
2264
2349
|
*/
|
|
2265
2350
|
generateBarOrderFromLegacyBars(l, U) {
|
|
2266
2351
|
const F = [];
|
|
2267
|
-
let Z = 1,
|
|
2352
|
+
let Z = 1, Q = 0, V;
|
|
2268
2353
|
for (const t of l) {
|
|
2269
|
-
t.from !== void 0 && (Z = t.from === -1 ? 0 : t.from,
|
|
2354
|
+
t.from !== void 0 && (Z = t.from === -1 ? 0 : t.from, Q = 0), t.timeSig !== void 0 && (V = t.timeSig);
|
|
2270
2355
|
const R = t.repeat || 1;
|
|
2271
2356
|
let a = t.beats;
|
|
2272
2357
|
for (; a > 0; ) {
|
|
2273
|
-
const n = (
|
|
2358
|
+
const n = (V !== void 0 ? V : this._getBeatsPerBar(Z, U)) - Q;
|
|
2274
2359
|
a >= n ? (F.push({
|
|
2275
2360
|
barNumber: Z,
|
|
2276
2361
|
repeat: R,
|
|
@@ -2278,10 +2363,10 @@ class CU {
|
|
|
2278
2363
|
// Legacy format doesn't have sections
|
|
2279
2364
|
voltaTime: 1
|
|
2280
2365
|
// Legacy format doesn't have voltas
|
|
2281
|
-
}), a -= n,
|
|
2366
|
+
}), a -= n, Q = 0, Z === 0 ? Z = 1 : Z++) : (Q += a, a = 0);
|
|
2282
2367
|
}
|
|
2283
2368
|
}
|
|
2284
|
-
return
|
|
2369
|
+
return Q > 0 && F.push({
|
|
2285
2370
|
barNumber: Z,
|
|
2286
2371
|
repeat: 1,
|
|
2287
2372
|
sectionIndex: 0,
|
|
@@ -2315,8 +2400,8 @@ class CU {
|
|
|
2315
2400
|
let Z;
|
|
2316
2401
|
if (F ? Z = l : Z = l - 1, Z < 0 || Z >= U.length)
|
|
2317
2402
|
return 4;
|
|
2318
|
-
const
|
|
2319
|
-
return
|
|
2403
|
+
const Q = U[Z];
|
|
2404
|
+
return Q.sig ? Q.sig[0] : 4;
|
|
2320
2405
|
}
|
|
2321
2406
|
/**
|
|
2322
2407
|
* Generate beat table from bar order and MIDI bar structure
|
|
@@ -2327,20 +2412,20 @@ class CU {
|
|
|
2327
2412
|
*/
|
|
2328
2413
|
generateBeatTable(l, U) {
|
|
2329
2414
|
const F = [], Z = {};
|
|
2330
|
-
let
|
|
2415
|
+
let Q = 0, V = 0;
|
|
2331
2416
|
const t = [...U];
|
|
2332
|
-
for (;
|
|
2333
|
-
const R = l[
|
|
2417
|
+
for (; V < l.length && Q < t.length; ) {
|
|
2418
|
+
const R = l[V], a = R.barNumber;
|
|
2334
2419
|
if (Z[a] === void 0) {
|
|
2335
|
-
const c = t[
|
|
2420
|
+
const c = t[Q];
|
|
2336
2421
|
if (!c || !c.sig)
|
|
2337
|
-
throw new Error(`Invalid MIDI bar structure at index ${
|
|
2422
|
+
throw new Error(`Invalid MIDI bar structure at index ${Q}`);
|
|
2338
2423
|
Z[a] = c.sig[0];
|
|
2339
2424
|
}
|
|
2340
2425
|
const n = Z[a];
|
|
2341
|
-
let m = t[
|
|
2342
|
-
for (;
|
|
2343
|
-
const c = t[
|
|
2426
|
+
let m = t[Q], W = m.sig[0];
|
|
2427
|
+
for (; W < n && Q + 1 < t.length; ) {
|
|
2428
|
+
const c = t[Q + 1], s = [
|
|
2344
2429
|
m.sig[0] + c.sig[0],
|
|
2345
2430
|
// Total beats
|
|
2346
2431
|
m.sig[1]
|
|
@@ -2352,31 +2437,31 @@ class CU {
|
|
|
2352
2437
|
m = {
|
|
2353
2438
|
sig: s,
|
|
2354
2439
|
beats: N
|
|
2355
|
-
}, t[
|
|
2440
|
+
}, t[Q] = m, t.splice(Q + 1, 1), W = s[0];
|
|
2356
2441
|
}
|
|
2357
|
-
if (
|
|
2358
|
-
const c = n, s =
|
|
2442
|
+
if (W > n) {
|
|
2443
|
+
const c = n, s = W - n, N = m.beats ? m.beats.slice(0, c) : [], J = m.beats ? m.beats.slice(c) : [], p = {
|
|
2359
2444
|
sig: [c, m.sig[1]],
|
|
2360
2445
|
beats: N
|
|
2361
2446
|
}, M = {
|
|
2362
2447
|
sig: [s, m.sig[1]],
|
|
2363
2448
|
beats: J
|
|
2364
2449
|
};
|
|
2365
|
-
t[
|
|
2450
|
+
t[Q] = p, t.splice(Q + 1, 0, M), m = p;
|
|
2366
2451
|
}
|
|
2367
|
-
this._generateBeatsForBar(F, R, m, n),
|
|
2452
|
+
this._generateBeatsForBar(F, R, m, n), Q++, V++;
|
|
2368
2453
|
}
|
|
2369
|
-
if (
|
|
2454
|
+
if (V < l.length) {
|
|
2370
2455
|
const R = F.length > 0 ? F[F.length - 1] : null;
|
|
2371
2456
|
let a = 0.5;
|
|
2372
2457
|
if (F.length >= 2) {
|
|
2373
|
-
const m = Math.min(8, F.length),
|
|
2374
|
-
a = (F[F.length - 1].time -
|
|
2458
|
+
const m = Math.min(8, F.length), W = F[F.length - m];
|
|
2459
|
+
a = (F[F.length - 1].time - W.time) / (m - 1);
|
|
2375
2460
|
}
|
|
2376
2461
|
let n = R ? R.time + a : 0;
|
|
2377
|
-
for (;
|
|
2378
|
-
const m = l[
|
|
2379
|
-
Z[
|
|
2462
|
+
for (; V < l.length; ) {
|
|
2463
|
+
const m = l[V], W = m.barNumber, c = Z[W] !== void 0 ? Z[W] : 4;
|
|
2464
|
+
Z[W] === void 0 && (Z[W] = c);
|
|
2380
2465
|
const s = [];
|
|
2381
2466
|
for (let J = 0; J < c; J++)
|
|
2382
2467
|
s.push(n), n += a;
|
|
@@ -2385,7 +2470,7 @@ class CU {
|
|
|
2385
2470
|
// Default to quarter notes
|
|
2386
2471
|
beats: s
|
|
2387
2472
|
};
|
|
2388
|
-
this._generateBeatsForBar(F, m, N, c),
|
|
2473
|
+
this._generateBeatsForBar(F, m, N, c), V++;
|
|
2389
2474
|
}
|
|
2390
2475
|
}
|
|
2391
2476
|
return F;
|
|
@@ -2395,13 +2480,13 @@ class CU {
|
|
|
2395
2480
|
* @private
|
|
2396
2481
|
*/
|
|
2397
2482
|
_generateBeatsForBar(l, U, F, Z) {
|
|
2398
|
-
const { beats:
|
|
2399
|
-
if (!
|
|
2483
|
+
const { beats: Q } = F;
|
|
2484
|
+
if (!Q || !Array.isArray(Q))
|
|
2400
2485
|
throw new Error(`Invalid MIDI bar: missing beats array. Got: ${JSON.stringify(F)}`);
|
|
2401
|
-
const
|
|
2486
|
+
const V = Q.slice(0, Z);
|
|
2402
2487
|
for (let t = 1; t <= Z; t++) {
|
|
2403
2488
|
const R = {
|
|
2404
|
-
time:
|
|
2489
|
+
time: V[t - 1],
|
|
2405
2490
|
repeat: U.repeat,
|
|
2406
2491
|
bar: U.barNumber,
|
|
2407
2492
|
beat: t,
|
|
@@ -2440,8 +2525,8 @@ class Jl {
|
|
|
2440
2525
|
if (!U)
|
|
2441
2526
|
throw new Error("Parsed MIDI data is required");
|
|
2442
2527
|
this.audioEngine = l, this._audioEngineReady = !!(l && l.isInitialized), this.instrumentMap = F || {}, this.parsedData = U, this._isPlaying = !1, this._currentTime = 0, this._totalDuration = 0, this.playbackSpeed = 1, this.partChannels = /* @__PURE__ */ new Map(), this.partOutputs = /* @__PURE__ */ new Map(), this.playbackStartTime = 0, this.lookAheadTime = 0.05, this.scheduleInterval = null, this.partNotePointers = /* @__PURE__ */ new Map(), this.partProgramPointers = /* @__PURE__ */ new Map(), this.eventBus = Xl(), this.beatMapper = new CU(), this.beats = [], this.structureMetadata = Z, this._calculateTotalDuration();
|
|
2443
|
-
const
|
|
2444
|
-
this.beats = this.beatMapper.mapBeats(U,
|
|
2528
|
+
const Q = Z || this._createDefaultStructureMetadata();
|
|
2529
|
+
this.beats = this.beatMapper.mapBeats(U, Q), this._audioEngineReady && (this._setupPartChannels(), this._resetNotePointers(), this._resetProgramPointers());
|
|
2445
2530
|
}
|
|
2446
2531
|
// ========================================
|
|
2447
2532
|
// PUBLIC API - Initialization Methods
|
|
@@ -2625,11 +2710,11 @@ class Jl {
|
|
|
2625
2710
|
*/
|
|
2626
2711
|
getAllNextNotes(l) {
|
|
2627
2712
|
const U = l ?? this.getCurrentTime(), F = {};
|
|
2628
|
-
for (const [Z,
|
|
2629
|
-
const
|
|
2630
|
-
F[Z] =
|
|
2631
|
-
pitch:
|
|
2632
|
-
startTime:
|
|
2713
|
+
for (const [Z, Q] of Object.entries(this.parsedData.parts)) {
|
|
2714
|
+
const V = Q.notes.find((t) => t.startTime >= U);
|
|
2715
|
+
F[Z] = V ? {
|
|
2716
|
+
pitch: V.pitch,
|
|
2717
|
+
startTime: V.startTime
|
|
2633
2718
|
} : null;
|
|
2634
2719
|
}
|
|
2635
2720
|
return F;
|
|
@@ -2670,17 +2755,17 @@ class Jl {
|
|
|
2670
2755
|
Object.keys(this.parsedData.parts).forEach((l) => {
|
|
2671
2756
|
const U = this.parsedData.parts[l], F = this.instrumentMap[l] || {}, Z = F.instrument !== void 0 ? F.instrument : U.defaultInstrument !== void 0 ? U.defaultInstrument : 0;
|
|
2672
2757
|
try {
|
|
2673
|
-
const
|
|
2758
|
+
const Q = this.audioEngine.createChannel(l, {
|
|
2674
2759
|
instrument: Z,
|
|
2675
2760
|
initialVolume: F.volume || 1
|
|
2676
2761
|
});
|
|
2677
|
-
this.partChannels.set(l,
|
|
2678
|
-
const
|
|
2679
|
-
|
|
2680
|
-
const t =
|
|
2681
|
-
t && t.connect(
|
|
2682
|
-
} catch (
|
|
2683
|
-
console.error(`Failed to create channel for part '${l}':`,
|
|
2762
|
+
this.partChannels.set(l, Q);
|
|
2763
|
+
const V = this.audioEngine.audioContext.createGain();
|
|
2764
|
+
V.gain.value = 1;
|
|
2765
|
+
const t = Q.getOutputNode();
|
|
2766
|
+
t && t.connect(V), this.partOutputs.set(l, V);
|
|
2767
|
+
} catch (Q) {
|
|
2768
|
+
console.error(`Failed to create channel for part '${l}':`, Q), this._emitEvent("error", Q);
|
|
2684
2769
|
}
|
|
2685
2770
|
});
|
|
2686
2771
|
}
|
|
@@ -2712,33 +2797,33 @@ class Jl {
|
|
|
2712
2797
|
if (!this._isPlaying) return;
|
|
2713
2798
|
const l = (this.audioEngine.audioContext.currentTime - this.playbackStartTime) * this.playbackSpeed, U = l + this.lookAheadTime;
|
|
2714
2799
|
for (const [F, Z] of this.partChannels) {
|
|
2715
|
-
const
|
|
2716
|
-
if (
|
|
2717
|
-
if (
|
|
2718
|
-
let
|
|
2719
|
-
const t =
|
|
2720
|
-
for (;
|
|
2721
|
-
|
|
2722
|
-
for (;
|
|
2723
|
-
const R = t[
|
|
2724
|
-
Z.setInstrument(R.programNumber),
|
|
2800
|
+
const Q = this.parsedData.parts[F];
|
|
2801
|
+
if (Q) {
|
|
2802
|
+
if (Q.programChanges && Q.programChanges.length > 0) {
|
|
2803
|
+
let V = this.partProgramPointers.get(F) || 0;
|
|
2804
|
+
const t = Q.programChanges;
|
|
2805
|
+
for (; V < t.length && t[V].time < l; )
|
|
2806
|
+
V++;
|
|
2807
|
+
for (; V < t.length && t[V].time <= U; ) {
|
|
2808
|
+
const R = t[V];
|
|
2809
|
+
Z.setInstrument(R.programNumber), V++;
|
|
2725
2810
|
}
|
|
2726
|
-
this.partProgramPointers.set(F,
|
|
2811
|
+
this.partProgramPointers.set(F, V);
|
|
2727
2812
|
}
|
|
2728
|
-
if (
|
|
2729
|
-
let
|
|
2730
|
-
const t =
|
|
2731
|
-
for (;
|
|
2732
|
-
|
|
2733
|
-
for (;
|
|
2734
|
-
const R = t[
|
|
2813
|
+
if (Q.notes) {
|
|
2814
|
+
let V = this.partNotePointers.get(F) || 0;
|
|
2815
|
+
const t = Q.notes;
|
|
2816
|
+
for (; V < t.length && t[V].endTime < l; )
|
|
2817
|
+
V++;
|
|
2818
|
+
for (; V < t.length && t[V].startTime <= U; ) {
|
|
2819
|
+
const R = t[V];
|
|
2735
2820
|
if (R.endTime - R.startTime >= 0.01) {
|
|
2736
2821
|
const a = this.playbackStartTime + R.startTime / this.playbackSpeed, n = (R.endTime - R.startTime) / this.playbackSpeed;
|
|
2737
2822
|
Z.playNote(a, R.pitch, R.velocity, n);
|
|
2738
2823
|
}
|
|
2739
|
-
|
|
2824
|
+
V++;
|
|
2740
2825
|
}
|
|
2741
|
-
this.partNotePointers.set(F,
|
|
2826
|
+
this.partNotePointers.set(F, V);
|
|
2742
2827
|
}
|
|
2743
2828
|
}
|
|
2744
2829
|
}
|
|
@@ -2771,10 +2856,10 @@ class Jl {
|
|
|
2771
2856
|
this.partProgramPointers.set(U, 0);
|
|
2772
2857
|
continue;
|
|
2773
2858
|
}
|
|
2774
|
-
let
|
|
2775
|
-
for (;
|
|
2776
|
-
|
|
2777
|
-
F.setInstrument(
|
|
2859
|
+
let Q = 0, V = Z.defaultInstrument;
|
|
2860
|
+
for (; Q < Z.programChanges.length && Z.programChanges[Q].time <= l; )
|
|
2861
|
+
V = Z.programChanges[Q].programNumber, Q++;
|
|
2862
|
+
F.setInstrument(V), this.partProgramPointers.set(U, Q);
|
|
2778
2863
|
}
|
|
2779
2864
|
}
|
|
2780
2865
|
/**
|
|
@@ -3225,15 +3310,15 @@ class xU {
|
|
|
3225
3310
|
throw new Error("Audio engine not ready. Call setAudioEngine() first.");
|
|
3226
3311
|
if (this.isCalibrating)
|
|
3227
3312
|
throw new Error("Calibration already in progress");
|
|
3228
|
-
const U = l.measurements || 5, F = l.sampleIntervalMs || 10, Z = l.threshold || 0.01,
|
|
3313
|
+
const U = l.measurements || 5, F = l.sampleIntervalMs || 10, Z = l.threshold || 0.01, Q = l.timeout || 3e3, V = l.silent !== void 0 ? l.silent : !0, t = l.updateBaseline !== void 0 ? l.updateBaseline : !0;
|
|
3229
3314
|
this.isCalibrating = !0;
|
|
3230
3315
|
try {
|
|
3231
|
-
|
|
3316
|
+
V && await this._setupSilentCalibration();
|
|
3232
3317
|
const R = await this._performLatencyMeasurement(
|
|
3233
3318
|
U,
|
|
3234
3319
|
F,
|
|
3235
3320
|
Z,
|
|
3236
|
-
|
|
3321
|
+
Q
|
|
3237
3322
|
);
|
|
3238
3323
|
this.measuredLatencyMs = R, t && await this._updateBaselineLatency(R);
|
|
3239
3324
|
const a = this.hasLatencyDrift();
|
|
@@ -3249,7 +3334,7 @@ class xU {
|
|
|
3249
3334
|
driftMs: R - this.baselineLatencyMs
|
|
3250
3335
|
})), R;
|
|
3251
3336
|
} finally {
|
|
3252
|
-
|
|
3337
|
+
V && this._teardownSilentCalibration(), this.isCalibrating = !1;
|
|
3253
3338
|
}
|
|
3254
3339
|
}
|
|
3255
3340
|
/**
|
|
@@ -3342,16 +3427,16 @@ class xU {
|
|
|
3342
3427
|
previewNextNotes(l = {}) {
|
|
3343
3428
|
if (!this.midiPlayer)
|
|
3344
3429
|
throw new Error("No MIDI data loaded");
|
|
3345
|
-
const U = l.delayBetweenParts ?? 0.3, F = l.duration ?? 0.5, Z = l.velocity ?? 100,
|
|
3430
|
+
const U = l.delayBetweenParts ?? 0.3, F = l.duration ?? 0.5, Z = l.velocity ?? 100, Q = this.midiPlayer.getAllNextNotes(), V = l.partOrder ?? this.getPartNames();
|
|
3346
3431
|
let t = this.audioEngine.audioContext.currentTime + 0.01;
|
|
3347
3432
|
const R = [];
|
|
3348
|
-
for (const a of
|
|
3349
|
-
const n =
|
|
3433
|
+
for (const a of V) {
|
|
3434
|
+
const n = Q[a];
|
|
3350
3435
|
if (!n) continue;
|
|
3351
3436
|
const m = this.midiPlayer.getPartChannel(a);
|
|
3352
3437
|
if (!m) continue;
|
|
3353
|
-
const
|
|
3354
|
-
|
|
3438
|
+
const W = this.midiPlayer.getPartOutput(a);
|
|
3439
|
+
W && W.gain.value === 0 || (m.playPreviewNote(n.pitch, {
|
|
3355
3440
|
startTime: t,
|
|
3356
3441
|
duration: F,
|
|
3357
3442
|
velocity: Z,
|
|
@@ -3483,17 +3568,17 @@ class xU {
|
|
|
3483
3568
|
startBeat: { bar: 1, beat: 1, timeSig: 4 }
|
|
3484
3569
|
};
|
|
3485
3570
|
const l = this.midiPlayer.beats, U = this.frozenTime, F = this.leadInConfig.bars;
|
|
3486
|
-
let Z = l.length - 1,
|
|
3571
|
+
let Z = l.length - 1, Q = 0.5;
|
|
3487
3572
|
for (; l[Z].time > U; ) Z--;
|
|
3488
|
-
const
|
|
3489
|
-
t ?
|
|
3490
|
-
const R = this.midiPlayer && this.midiPlayer.playbackSpeed || 1, a =
|
|
3573
|
+
const V = l[Z], t = l[Z + 1];
|
|
3574
|
+
t ? Q = t.time - V.time : Z > 0 && (Q = V.time - l[Z - 1].time);
|
|
3575
|
+
const R = this.midiPlayer && this.midiPlayer.playbackSpeed || 1, a = Q / R, n = V.timeSig === 1, m = n && t ? t.timeSig : V.timeSig, W = n ? m - 1 : V.beat > 1 ? V.beat - 1 : 0, c = F * m + W;
|
|
3491
3576
|
return {
|
|
3492
3577
|
totalBeats: c,
|
|
3493
3578
|
duration: c * a,
|
|
3494
3579
|
beatSequence: this._generateBeatSequence(c, a, m),
|
|
3495
3580
|
beatsPerBar: m,
|
|
3496
|
-
startBeat:
|
|
3581
|
+
startBeat: V
|
|
3497
3582
|
};
|
|
3498
3583
|
}
|
|
3499
3584
|
/**
|
|
@@ -3506,14 +3591,14 @@ class xU {
|
|
|
3506
3591
|
*/
|
|
3507
3592
|
_generateBeatSequence(l, U, F) {
|
|
3508
3593
|
const Z = [];
|
|
3509
|
-
for (let
|
|
3510
|
-
const
|
|
3594
|
+
for (let Q = 0; Q < l; Q++) {
|
|
3595
|
+
const V = Q % F + 1;
|
|
3511
3596
|
Z.push({
|
|
3512
|
-
beat:
|
|
3513
|
-
isAccent:
|
|
3514
|
-
time:
|
|
3597
|
+
beat: V,
|
|
3598
|
+
isAccent: V === 1,
|
|
3599
|
+
time: Q * U,
|
|
3515
3600
|
// Relative time from start of lead-in playback
|
|
3516
|
-
absoluteTime: this.leadInStartTime +
|
|
3601
|
+
absoluteTime: this.leadInStartTime + Q * U
|
|
3517
3602
|
// Absolute time (includes startup delay)
|
|
3518
3603
|
});
|
|
3519
3604
|
}
|
|
@@ -3530,18 +3615,18 @@ class xU {
|
|
|
3530
3615
|
this.leadInStartTime = this.audioEngine.audioContext.currentTime, this.leadInInterval = setInterval(() => {
|
|
3531
3616
|
const Z = this.audioEngine.audioContext.currentTime - this.leadInStartTime;
|
|
3532
3617
|
for (this.leadInProgress = Math.min(1, Z / this.leadInData.duration); this.leadInBeatIndex < U.length; ) {
|
|
3533
|
-
const
|
|
3534
|
-
if (
|
|
3618
|
+
const Q = U[this.leadInBeatIndex], V = Q.time - Z;
|
|
3619
|
+
if (V > 0.05)
|
|
3535
3620
|
break;
|
|
3536
|
-
if (!this.leadInScheduledBeats.has(this.leadInBeatIndex) &&
|
|
3537
|
-
const t =
|
|
3621
|
+
if (!this.leadInScheduledBeats.has(this.leadInBeatIndex) && V >= -0.05 && V <= 0.05) {
|
|
3622
|
+
const t = V <= 0 ? this.audioEngine.audioContext.currentTime + 0.01 : (
|
|
3538
3623
|
// Add small offset for immediate beats
|
|
3539
|
-
this.audioEngine.audioContext.currentTime +
|
|
3624
|
+
this.audioEngine.audioContext.currentTime + V
|
|
3540
3625
|
);
|
|
3541
|
-
this._scheduleTickAtTime(t,
|
|
3626
|
+
this._scheduleTickAtTime(t, Q.isAccent);
|
|
3542
3627
|
const R = {
|
|
3543
3628
|
bar: Math.floor(this.leadInBeatIndex / this.leadInData.beatsPerBar) + 1,
|
|
3544
|
-
beat:
|
|
3629
|
+
beat: Q.beat,
|
|
3545
3630
|
repeat: 1,
|
|
3546
3631
|
time: this.frozenTime,
|
|
3547
3632
|
isLeadIn: !0
|
|
@@ -3590,8 +3675,8 @@ class xU {
|
|
|
3590
3675
|
if (this.state === "playing")
|
|
3591
3676
|
try {
|
|
3592
3677
|
this.midiPlayer.play(), l && this._startMetronome();
|
|
3593
|
-
} catch (
|
|
3594
|
-
this.state = "stopped", this._emitEvent("error",
|
|
3678
|
+
} catch (Q) {
|
|
3679
|
+
this.state = "stopped", this._emitEvent("error", Q);
|
|
3595
3680
|
}
|
|
3596
3681
|
};
|
|
3597
3682
|
F ? Z() : setTimeout(Z, this.startupConfig.delayMs), this.timeUpdateInterval || this._startTimeUpdateLoop();
|
|
@@ -3634,13 +3719,13 @@ class xU {
|
|
|
3634
3719
|
if (!U || U.length === 0)
|
|
3635
3720
|
return;
|
|
3636
3721
|
const F = this.midiPlayer.getCurrentTime(), Z = 0.1;
|
|
3637
|
-
for (let
|
|
3638
|
-
const
|
|
3722
|
+
for (let Q = this.nextBeatIndex; Q < U.length; Q++) {
|
|
3723
|
+
const V = U[Q], t = this.midiPlayer.playbackSpeed || 1, R = l + (V.time - F) / t;
|
|
3639
3724
|
if (R > this.audioEngine.audioContext.currentTime + Z)
|
|
3640
3725
|
break;
|
|
3641
3726
|
if (R >= this.audioEngine.audioContext.currentTime - 0.01) {
|
|
3642
|
-
const a = Math.max(R, this.audioEngine.audioContext.currentTime + 1e-3), n =
|
|
3643
|
-
this._scheduleTickAtTime(a, n), this.nextBeatIndex =
|
|
3727
|
+
const a = Math.max(R, this.audioEngine.audioContext.currentTime + 1e-3), n = V.isDownbeat || V.beat === 1;
|
|
3728
|
+
this._scheduleTickAtTime(a, n), this.nextBeatIndex = Q + 1;
|
|
3644
3729
|
}
|
|
3645
3730
|
}
|
|
3646
3731
|
}
|
|
@@ -3657,11 +3742,11 @@ class xU {
|
|
|
3657
3742
|
this.nextBeatIndex++;
|
|
3658
3743
|
const F = l + 0.15;
|
|
3659
3744
|
for (; this.nextBeatIndex < U.length; ) {
|
|
3660
|
-
const Z = U[this.nextBeatIndex],
|
|
3745
|
+
const Z = U[this.nextBeatIndex], Q = Z.time - l;
|
|
3661
3746
|
if (Z.time > F)
|
|
3662
3747
|
break;
|
|
3663
|
-
if (
|
|
3664
|
-
const
|
|
3748
|
+
if (Q >= -0.025 && Q <= 0.15) {
|
|
3749
|
+
const V = this.audioEngine.audioContext.currentTime + 5e-3, t = this.audioEngine.audioContext.currentTime + Math.max(Q, 5e-3), R = Math.max(V, t), a = Z.beat === 1;
|
|
3665
3750
|
this._scheduleTickAtTime(R, a);
|
|
3666
3751
|
}
|
|
3667
3752
|
this.nextBeatIndex++;
|
|
@@ -3860,10 +3945,10 @@ class xU {
|
|
|
3860
3945
|
trumpet: { instrument: "trumpet", volume: 0.7 }
|
|
3861
3946
|
};
|
|
3862
3947
|
return Object.keys(l).forEach((Z) => {
|
|
3863
|
-
const
|
|
3948
|
+
const Q = Z.toLowerCase(), V = F[Q] || F.piano;
|
|
3864
3949
|
U[Z] = {
|
|
3865
|
-
instrument:
|
|
3866
|
-
volume:
|
|
3950
|
+
instrument: V.instrument,
|
|
3951
|
+
volume: V.volume
|
|
3867
3952
|
};
|
|
3868
3953
|
}), U;
|
|
3869
3954
|
}
|
|
@@ -3884,17 +3969,17 @@ class xU {
|
|
|
3884
3969
|
const U = this.audioEngine.getMetronomeAnalyser();
|
|
3885
3970
|
if (!U)
|
|
3886
3971
|
throw new Error("Metronome analyser not available for signal capture");
|
|
3887
|
-
const F = l.sampleIntervalMs || 2, Z = l.captureDurationMs || 1500,
|
|
3888
|
-
await this.audioEngine.playMetronomeTick(
|
|
3889
|
-
const
|
|
3972
|
+
const F = l.sampleIntervalMs || 2, Z = l.captureDurationMs || 1500, Q = this.audioEngine.audioContext.currentTime + 0.1;
|
|
3973
|
+
await this.audioEngine.playMetronomeTick(Q, !0, 1);
|
|
3974
|
+
const V = await this._captureAnalyserTimeSeries(
|
|
3890
3975
|
U,
|
|
3891
|
-
|
|
3976
|
+
Q,
|
|
3892
3977
|
F,
|
|
3893
3978
|
Z
|
|
3894
3979
|
);
|
|
3895
3980
|
return {
|
|
3896
|
-
scheduledTime:
|
|
3897
|
-
samples:
|
|
3981
|
+
scheduledTime: Q,
|
|
3982
|
+
samples: V,
|
|
3898
3983
|
sampleIntervalMs: F,
|
|
3899
3984
|
captureDurationMs: Z
|
|
3900
3985
|
};
|
|
@@ -3909,17 +3994,17 @@ class xU {
|
|
|
3909
3994
|
* @private
|
|
3910
3995
|
*/
|
|
3911
3996
|
async _performLatencyMeasurement(l, U, F, Z) {
|
|
3912
|
-
const
|
|
3913
|
-
if (!
|
|
3997
|
+
const Q = this.audioEngine.getMetronomeAnalyser();
|
|
3998
|
+
if (!Q)
|
|
3914
3999
|
throw new Error("Metronome analyser not available for latency measurement");
|
|
3915
|
-
const
|
|
4000
|
+
const V = this.audioEngine.audioContext, t = [];
|
|
3916
4001
|
console.log(`Starting calibration: ${l} measurements, ${U}ms sampling, ${F} threshold`);
|
|
3917
4002
|
for (let m = 0; m < l; m++) {
|
|
3918
|
-
const
|
|
3919
|
-
await this.audioEngine.playMetronomeTick(
|
|
4003
|
+
const W = V.currentTime + 0.15;
|
|
4004
|
+
await this.audioEngine.playMetronomeTick(W, !0, 1);
|
|
3920
4005
|
const c = await this._detectOnsetByThreshold(
|
|
3921
|
-
|
|
3922
|
-
|
|
4006
|
+
Q,
|
|
4007
|
+
W,
|
|
3923
4008
|
U,
|
|
3924
4009
|
F,
|
|
3925
4010
|
Z
|
|
@@ -3935,7 +4020,7 @@ class xU {
|
|
|
3935
4020
|
throw new Error(`Failed to detect any metronome onsets. Try lowering threshold (current: ${F}) or check audio routing.`);
|
|
3936
4021
|
let R = t;
|
|
3937
4022
|
if (t.length >= 5) {
|
|
3938
|
-
const m = [...t].sort((
|
|
4023
|
+
const m = [...t].sort((W, c) => W - c);
|
|
3939
4024
|
R = m.slice(
|
|
3940
4025
|
Math.floor(m.length * 0.2),
|
|
3941
4026
|
// Remove bottom 20%
|
|
@@ -3943,8 +4028,8 @@ class xU {
|
|
|
3943
4028
|
// Remove top 20%
|
|
3944
4029
|
), console.log(`Discarded ${t.length - R.length} outliers`);
|
|
3945
4030
|
}
|
|
3946
|
-
const a = R.reduce((m,
|
|
3947
|
-
R.reduce((m,
|
|
4031
|
+
const a = R.reduce((m, W) => m + W, 0) / R.length, n = Math.sqrt(
|
|
4032
|
+
R.reduce((m, W) => m + Math.pow(W - a, 2), 0) / R.length
|
|
3948
4033
|
);
|
|
3949
4034
|
return console.log(`Average latency: ${a.toFixed(1)}ms ± ${n.toFixed(1)}ms (n=${R.length})`), Math.round(a);
|
|
3950
4035
|
}
|
|
@@ -3959,14 +4044,14 @@ class xU {
|
|
|
3959
4044
|
* @returns {Promise<Object|null>} Detection result {latencyMs, rms, peak} or null if timeout
|
|
3960
4045
|
* @private
|
|
3961
4046
|
*/
|
|
3962
|
-
async _detectOnsetByThreshold(l, U, F, Z,
|
|
3963
|
-
const
|
|
4047
|
+
async _detectOnsetByThreshold(l, U, F, Z, Q) {
|
|
4048
|
+
const V = this.audioEngine.audioContext, t = l.fftSize, R = new Float32Array(t), a = Math.max(0, (U - V.currentTime) * 1e3 - 20);
|
|
3964
4049
|
await new Promise((m) => setTimeout(m, a));
|
|
3965
4050
|
const n = performance.now();
|
|
3966
4051
|
return new Promise((m) => {
|
|
3967
|
-
const
|
|
3968
|
-
if (performance.now() - n >
|
|
3969
|
-
clearInterval(
|
|
4052
|
+
const W = setInterval(() => {
|
|
4053
|
+
if (performance.now() - n > Q) {
|
|
4054
|
+
clearInterval(W), m(null);
|
|
3970
4055
|
return;
|
|
3971
4056
|
}
|
|
3972
4057
|
l.getFloatTimeDomainData(R);
|
|
@@ -3977,8 +4062,8 @@ class xU {
|
|
|
3977
4062
|
}
|
|
3978
4063
|
const N = Math.sqrt(c / t);
|
|
3979
4064
|
if (N >= Z) {
|
|
3980
|
-
clearInterval(
|
|
3981
|
-
const J =
|
|
4065
|
+
clearInterval(W);
|
|
4066
|
+
const J = V.currentTime, p = (J - U) * 1e3;
|
|
3982
4067
|
m({
|
|
3983
4068
|
latencyMs: p,
|
|
3984
4069
|
rms: N,
|
|
@@ -3999,20 +4084,20 @@ class xU {
|
|
|
3999
4084
|
* @private
|
|
4000
4085
|
*/
|
|
4001
4086
|
async _captureAnalyserTimeSeries(l, U, F, Z) {
|
|
4002
|
-
const
|
|
4087
|
+
const Q = this.audioEngine.audioContext, V = l.fftSize, t = new Float32Array(V), R = [], a = performance.now(), n = Math.max(0, (U - Q.currentTime) * 1e3 - 20);
|
|
4003
4088
|
return await new Promise((m) => setTimeout(m, n)), new Promise((m) => {
|
|
4004
|
-
const
|
|
4089
|
+
const W = setInterval(() => {
|
|
4005
4090
|
if (performance.now() - a - n >= Z) {
|
|
4006
|
-
clearInterval(
|
|
4091
|
+
clearInterval(W), m(R);
|
|
4007
4092
|
return;
|
|
4008
4093
|
}
|
|
4009
4094
|
l.getFloatTimeDomainData(t);
|
|
4010
4095
|
let c = 0, s = 0;
|
|
4011
|
-
for (let p = 0; p <
|
|
4096
|
+
for (let p = 0; p < V; p++) {
|
|
4012
4097
|
const M = Math.abs(t[p]);
|
|
4013
4098
|
c += t[p] * t[p], M > s && (s = M);
|
|
4014
4099
|
}
|
|
4015
|
-
const N = Math.sqrt(c /
|
|
4100
|
+
const N = Math.sqrt(c / V), J = Q.currentTime;
|
|
4016
4101
|
R.push({
|
|
4017
4102
|
time: J,
|
|
4018
4103
|
relativeTime: (J - U) * 1e3,
|
|
@@ -4049,8 +4134,8 @@ class MU {
|
|
|
4049
4134
|
try {
|
|
4050
4135
|
await this.audioEngine.initialize(Z), console.log(`Loaded soundfont: ${Z}`), U = !0;
|
|
4051
4136
|
break;
|
|
4052
|
-
} catch (
|
|
4053
|
-
console.warn(`Failed to load soundfont ${Z}:`,
|
|
4137
|
+
} catch (Q) {
|
|
4138
|
+
console.warn(`Failed to load soundfont ${Z}:`, Q.message), F = Q;
|
|
4054
4139
|
}
|
|
4055
4140
|
if (!U) {
|
|
4056
4141
|
const Z = "No soundfont could be loaded";
|
|
@@ -4140,8 +4225,8 @@ class MU {
|
|
|
4140
4225
|
F.gain.value = 1;
|
|
4141
4226
|
const Z = this.audioContext.createAnalyser();
|
|
4142
4227
|
Z.fftSize = 256, Z.smoothingTimeConstant = 0.3, U.connect(F), F.connect(Z), Z.connect(this.masterGain);
|
|
4143
|
-
const
|
|
4144
|
-
this.partGainNodes.set(
|
|
4228
|
+
const Q = this.sanitizePartName(l);
|
|
4229
|
+
this.partGainNodes.set(Q, F), this.partAnalyserNodes.set(Q, Z), console.log(`Audio routing established for part: ${l}`);
|
|
4145
4230
|
}
|
|
4146
4231
|
}
|
|
4147
4232
|
// Set up metronome audio routing (separate from parts)
|
|
@@ -4189,8 +4274,8 @@ class MU {
|
|
|
4189
4274
|
setupPlaybackManagerEventDelegation() {
|
|
4190
4275
|
this.playbackManager.on("timeupdate", ({ audioTime: l, leadInProgress: U }) => {
|
|
4191
4276
|
this.currentTime = l, this.eventBus.emit("timeChanged", { currentTime: l, leadInProgress: U });
|
|
4192
|
-
}), this.playbackManager.on("beatAudible", ({ bar: l, beat: U, isLeadIn: F, repeat: Z, time:
|
|
4193
|
-
this.eventBus.emit("barChanged", { bar: l, beat: U, repeat: Z, time:
|
|
4277
|
+
}), this.playbackManager.on("beatAudible", ({ bar: l, beat: U, isLeadIn: F, repeat: Z, time: Q }) => {
|
|
4278
|
+
this.eventBus.emit("barChanged", { bar: l, beat: U, repeat: Z, time: Q, isLeadIn: F });
|
|
4194
4279
|
}), this.playbackManager.on("leadInStarted", ({ totalBeats: l, duration: U, bars: F }) => {
|
|
4195
4280
|
this.eventBus.emit("leadInStarted", { bars: F, totalBeats: l, duration: U });
|
|
4196
4281
|
}), this.playbackManager.on("leadInEnded", () => {
|
|
@@ -4315,7 +4400,7 @@ class MU {
|
|
|
4315
4400
|
// Helper method to determine if a part should be effectively muted
|
|
4316
4401
|
isPartEffectivelyMuted(l) {
|
|
4317
4402
|
const U = this.sanitizePartName(l), F = this.parts.get(U);
|
|
4318
|
-
return !F || F.muted ? !0 : Array.from(this.parts.values()).some((
|
|
4403
|
+
return !F || F.muted ? !0 : Array.from(this.parts.values()).some((Q) => Q.solo) && !F.solo;
|
|
4319
4404
|
}
|
|
4320
4405
|
// Update audio state for a specific part
|
|
4321
4406
|
updatePartAudioState(l) {
|
|
@@ -4339,14 +4424,14 @@ class MU {
|
|
|
4339
4424
|
if (!F)
|
|
4340
4425
|
return 0;
|
|
4341
4426
|
try {
|
|
4342
|
-
const Z = F.frequencyBinCount,
|
|
4343
|
-
F.getByteFrequencyData(
|
|
4344
|
-
let
|
|
4427
|
+
const Z = F.frequencyBinCount, Q = new Uint8Array(Z);
|
|
4428
|
+
F.getByteFrequencyData(Q);
|
|
4429
|
+
let V = 0;
|
|
4345
4430
|
for (let R = 0; R < Z; R++) {
|
|
4346
|
-
const a =
|
|
4347
|
-
|
|
4431
|
+
const a = Q[R] / 255;
|
|
4432
|
+
V += a * a;
|
|
4348
4433
|
}
|
|
4349
|
-
const t = Math.sqrt(
|
|
4434
|
+
const t = Math.sqrt(V / Z);
|
|
4350
4435
|
return Math.min(1, Math.pow(t * 2, 0.7));
|
|
4351
4436
|
} catch (Z) {
|
|
4352
4437
|
return console.warn(`Failed to get level for part ${l}:`, Z), 0;
|
|
@@ -4428,72 +4513,66 @@ class MU {
|
|
|
4428
4513
|
}
|
|
4429
4514
|
const e = new MU();
|
|
4430
4515
|
function Rl() {
|
|
4431
|
-
const d = Ul(), l = tl(), U = NU(), F = ({ currentTime:
|
|
4432
|
-
d.setCurrentTime(
|
|
4433
|
-
}, Z = ({ isPlaying:
|
|
4434
|
-
d.setPlaybackState(
|
|
4435
|
-
},
|
|
4436
|
-
|
|
4437
|
-
},
|
|
4438
|
-
d.setPlaybackSpeed(
|
|
4439
|
-
}, t = ({ volume:
|
|
4440
|
-
d.setMasterVolume(
|
|
4441
|
-
}, R = ({ partName:
|
|
4442
|
-
d.setPartVolume(
|
|
4443
|
-
}, a = ({ partName:
|
|
4444
|
-
d.setPartMuted(
|
|
4445
|
-
}, n = ({ partName:
|
|
4446
|
-
d.setPartSolo(
|
|
4447
|
-
}, m = ({ bars:
|
|
4448
|
-
d.setLeadInActive(!0,
|
|
4449
|
-
},
|
|
4516
|
+
const d = Ul(), l = tl(), U = NU(), F = ({ currentTime: b }) => {
|
|
4517
|
+
d.setCurrentTime(b);
|
|
4518
|
+
}, Z = ({ isPlaying: b }) => {
|
|
4519
|
+
d.setPlaybackState(b), U.setTransportState(b ? "playing" : "stopped");
|
|
4520
|
+
}, Q = (b) => {
|
|
4521
|
+
b && (d.isLeadInActive ? b.isLeadIn && b.beat !== void 0 && d.setCurrentBar(null, b.beat, null) : (d.setCurrentBar(b.bar, b.beat, b.repeat), U.updateLastBarPosition(b.bar)));
|
|
4522
|
+
}, V = ({ speed: b }) => {
|
|
4523
|
+
d.setPlaybackSpeed(b);
|
|
4524
|
+
}, t = ({ volume: b }) => {
|
|
4525
|
+
d.setMasterVolume(b);
|
|
4526
|
+
}, R = ({ partName: b, volume: o }) => {
|
|
4527
|
+
d.setPartVolume(b, o);
|
|
4528
|
+
}, a = ({ partName: b, muted: o }) => {
|
|
4529
|
+
d.setPartMuted(b, o);
|
|
4530
|
+
}, n = ({ partName: b, solo: o }) => {
|
|
4531
|
+
d.setPartSolo(b, o);
|
|
4532
|
+
}, m = ({ bars: b }) => {
|
|
4533
|
+
d.setLeadInActive(!0, b);
|
|
4534
|
+
}, W = () => {
|
|
4450
4535
|
d.setLeadInActive(!1);
|
|
4451
4536
|
}, c = () => {
|
|
4452
4537
|
d.setStartingNotesActive(!0);
|
|
4453
4538
|
}, s = () => {
|
|
4454
4539
|
d.setStartingNotesActive(!1);
|
|
4455
|
-
}, N = ({ mark:
|
|
4456
|
-
U.updateLastPracticeMarkUsed(
|
|
4457
|
-
}, J = ({ parts:
|
|
4458
|
-
d.initializeParts(
|
|
4459
|
-
}, p = ({ finalTime:
|
|
4460
|
-
d.setPlaybackState(!1), U.setTransportState("stopped"), console.log(`Song ended at time: ${
|
|
4461
|
-
}, M = ({ duration:
|
|
4462
|
-
console.log("Updating total duration in store to:",
|
|
4463
|
-
}, y = ({ beats:
|
|
4464
|
-
console.log(`Updating music data store with ${
|
|
4465
|
-
},
|
|
4466
|
-
e.on("timeChanged", F), e.on("playbackStateChanged", Z), e.on("barChanged",
|
|
4540
|
+
}, N = ({ mark: b }) => {
|
|
4541
|
+
U.updateLastPracticeMarkUsed(b);
|
|
4542
|
+
}, J = ({ parts: b }) => {
|
|
4543
|
+
d.initializeParts(b), l.setParts(b);
|
|
4544
|
+
}, p = ({ finalTime: b }) => {
|
|
4545
|
+
d.setPlaybackState(!1), U.setTransportState("stopped"), console.log(`Song ended at time: ${b}`);
|
|
4546
|
+
}, M = ({ duration: b }) => {
|
|
4547
|
+
console.log("Updating total duration in store to:", b), l.setTotalDuration(b);
|
|
4548
|
+
}, y = ({ beats: b, practiceMarks: o, maxBar: q }) => {
|
|
4549
|
+
console.log(`Updating music data store with ${b.length} beats and ${Object.keys(o).length} practice marks`), l.updateBeats(b), l.practiceMarks = o, l.maxBar = q;
|
|
4550
|
+
}, u = () => {
|
|
4551
|
+
e.on("timeChanged", F), e.on("playbackStateChanged", Z), e.on("barChanged", Q), e.on("speedChanged", V), e.on("masterVolumeChanged", t), e.on("partVolumeChanged", R), e.on("partMutedChanged", a), e.on("partSoloChanged", n), e.on("leadInStarted", m), e.on("leadInCompleted", W), e.on("startingNotesStarted", c), e.on("startingNotesCompleted", s), e.on("practiceMarkChanged", N), e.on("initialized", J), e.on("songEnded", p), e.on("durationUpdated", M), e.on("musicDataExtracted", y);
|
|
4467
4552
|
}, k = () => {
|
|
4468
|
-
e.off("timeChanged", F), e.off("playbackStateChanged", Z), e.off("barChanged",
|
|
4553
|
+
e.off("timeChanged", F), e.off("playbackStateChanged", Z), e.off("barChanged", Q), e.off("speedChanged", V), e.off("masterVolumeChanged", t), e.off("partVolumeChanged", R), e.off("partMutedChanged", a), e.off("partSoloChanged", n), e.off("leadInStarted", m), e.off("leadInCompleted", W), e.off("startingNotesStarted", c), e.off("startingNotesCompleted", s), e.off("practiceMarkChanged", N), e.off("initialized", J), e.off("songEnded", p), e.off("durationUpdated", M), e.off("musicDataExtracted", y);
|
|
4469
4554
|
};
|
|
4470
4555
|
(() => {
|
|
4471
4556
|
El(() => {
|
|
4472
|
-
const
|
|
4557
|
+
const b = d.masterVolume;
|
|
4473
4558
|
try {
|
|
4474
|
-
e.getMasterVolume() !==
|
|
4559
|
+
e.getMasterVolume() !== b && e.setMasterVolume(b);
|
|
4475
4560
|
} catch (o) {
|
|
4476
4561
|
console.warn("Master volume sync skipped during initialization:", o.message);
|
|
4477
4562
|
}
|
|
4478
4563
|
}), El(() => {
|
|
4479
|
-
const
|
|
4564
|
+
const b = d.metronomeVolume;
|
|
4480
4565
|
try {
|
|
4481
|
-
e.getMetronomeVolume() !==
|
|
4566
|
+
e.getMetronomeVolume() !== b && e.setMetronomeVolume(b);
|
|
4482
4567
|
} catch (o) {
|
|
4483
4568
|
console.warn("Metronome volume sync skipped during initialization:", o.message);
|
|
4484
4569
|
}
|
|
4485
4570
|
});
|
|
4486
4571
|
})();
|
|
4487
|
-
const H = async (
|
|
4572
|
+
const H = async (b) => {
|
|
4488
4573
|
try {
|
|
4489
|
-
if (d.setLoaded(!1),
|
|
4490
|
-
|
|
4491
|
-
else if (await e.initialize({
|
|
4492
|
-
beats: W.beats,
|
|
4493
|
-
practiceMarks: W.marks || W.practiceMarks,
|
|
4494
|
-
parts: W.parts
|
|
4495
|
-
}), W.beats && W.beats.length > 0) {
|
|
4496
|
-
const o = W.beats[0];
|
|
4574
|
+
if (d.setLoaded(!1), u(), l.loadMusicData(b), await e.initialize(b), !b.midiData && b.beats && b.beats.length > 0) {
|
|
4575
|
+
const o = b.beats[0];
|
|
4497
4576
|
d.setCurrentBar(o.bar, o.beat, o.repeat), e.setTime(o.time);
|
|
4498
4577
|
}
|
|
4499
4578
|
e.updateToggleStates(d.metronomeEnabled, d.leadInEnabled), d.setLoaded(!0);
|
|
@@ -4506,37 +4585,37 @@ function Rl() {
|
|
|
4506
4585
|
e.stop();
|
|
4507
4586
|
}, Zl = () => {
|
|
4508
4587
|
e.pause();
|
|
4509
|
-
}, i = (
|
|
4510
|
-
e.setTime(
|
|
4511
|
-
}, z = (
|
|
4512
|
-
e.setBar(
|
|
4513
|
-
}, P = (
|
|
4514
|
-
e.goToPracticeMark(
|
|
4515
|
-
}, B = (
|
|
4516
|
-
e.setPlaybackSpeed(
|
|
4517
|
-
}, S = (
|
|
4518
|
-
e.setMasterVolume(
|
|
4519
|
-
}, T = (
|
|
4520
|
-
e.setPartVolume(
|
|
4521
|
-
}, I = (
|
|
4522
|
-
e.setPartMuted(
|
|
4523
|
-
}, w = (
|
|
4524
|
-
e.setPartSolo(
|
|
4525
|
-
}, Ql = (
|
|
4526
|
-
e.playLeadIn(
|
|
4588
|
+
}, i = (b) => {
|
|
4589
|
+
e.setTime(b);
|
|
4590
|
+
}, z = (b, o = 0) => {
|
|
4591
|
+
e.setBar(b, o);
|
|
4592
|
+
}, P = (b) => {
|
|
4593
|
+
e.goToPracticeMark(b);
|
|
4594
|
+
}, B = (b) => {
|
|
4595
|
+
e.setPlaybackSpeed(b);
|
|
4596
|
+
}, S = (b) => {
|
|
4597
|
+
e.setMasterVolume(b);
|
|
4598
|
+
}, T = (b, o) => {
|
|
4599
|
+
e.setPartVolume(b, o);
|
|
4600
|
+
}, I = (b, o) => {
|
|
4601
|
+
e.setPartMuted(b, o);
|
|
4602
|
+
}, w = (b, o) => {
|
|
4603
|
+
e.setPartSolo(b, o);
|
|
4604
|
+
}, Ql = (b = 1) => {
|
|
4605
|
+
e.playLeadIn(b);
|
|
4527
4606
|
}, Bl = () => {
|
|
4528
4607
|
e.playStartingNotes();
|
|
4529
|
-
}, Yl = (
|
|
4530
|
-
o && U.leadInEnabled ? (z(
|
|
4531
|
-
}, _l = (
|
|
4532
|
-
const q = l.getBarForMark(
|
|
4608
|
+
}, Yl = (b, o = !0, q = 0) => {
|
|
4609
|
+
o && U.leadInEnabled ? (z(b, q), Ql(U.leadInBars)) : (z(b, q), A());
|
|
4610
|
+
}, _l = (b, o = !0) => {
|
|
4611
|
+
const q = l.getBarForMark(b);
|
|
4533
4612
|
q && Yl(q, o);
|
|
4534
4613
|
}, $l = () => {
|
|
4535
|
-
const
|
|
4536
|
-
return d.setMetronomeEnabled(
|
|
4614
|
+
const b = !d.metronomeEnabled;
|
|
4615
|
+
return d.setMetronomeEnabled(b), e.setMetronomeEnabled(b), b;
|
|
4537
4616
|
}, lU = () => {
|
|
4538
|
-
const
|
|
4539
|
-
return d.setLeadInEnabled(
|
|
4617
|
+
const b = !d.leadInEnabled;
|
|
4618
|
+
return d.setLeadInEnabled(b), e.updateToggleStates(d.metronomeEnabled, b), b;
|
|
4540
4619
|
};
|
|
4541
4620
|
return cl(() => {
|
|
4542
4621
|
k();
|
|
@@ -4558,15 +4637,15 @@ function Rl() {
|
|
|
4558
4637
|
setPartVolume: T,
|
|
4559
4638
|
setPartMuted: I,
|
|
4560
4639
|
setPartSolo: w,
|
|
4561
|
-
getPartLevel: (
|
|
4640
|
+
getPartLevel: (b) => e.getPartLevel(b),
|
|
4562
4641
|
// Special features
|
|
4563
4642
|
playLeadIn: Ql,
|
|
4564
4643
|
playStartingNotes: Bl,
|
|
4565
4644
|
// Feature toggles
|
|
4566
4645
|
toggleMetronome: $l,
|
|
4567
4646
|
toggleLeadIn: lU,
|
|
4568
|
-
setMetronomeEnabled: (
|
|
4569
|
-
d.setMetronomeEnabled(
|
|
4647
|
+
setMetronomeEnabled: (b) => {
|
|
4648
|
+
d.setMetronomeEnabled(b), e.setMetronomeEnabled(b);
|
|
4570
4649
|
},
|
|
4571
4650
|
// Complex operations
|
|
4572
4651
|
playFromBar: Yl,
|
|
@@ -4606,43 +4685,43 @@ const zU = {
|
|
|
4606
4685
|
}));
|
|
4607
4686
|
const l = d;
|
|
4608
4687
|
Ul();
|
|
4609
|
-
const U = Rl(), F = _(d, "volume"), Z = _(d, "mute"),
|
|
4688
|
+
const U = Rl(), F = _(d, "volume"), Z = _(d, "mute"), Q = _(d, "solo");
|
|
4610
4689
|
v(F, (c) => {
|
|
4611
4690
|
U.setPartVolume(l.name, c);
|
|
4612
4691
|
}), v(Z, (c) => {
|
|
4613
4692
|
U.setPartMuted(l.name, c);
|
|
4614
|
-
}), v(
|
|
4693
|
+
}), v(Q, (c) => {
|
|
4615
4694
|
U.setPartSolo(l.name, c);
|
|
4616
4695
|
});
|
|
4617
|
-
const
|
|
4696
|
+
const V = O("el"), { width: t, height: R } = ll(V), a = G(() => Math.min(t.value, R.value) + "px"), n = G(
|
|
4618
4697
|
() => t.value > R.value ? "mobile" : t.value < 60 ? "tablet" : "desktop"
|
|
4619
4698
|
);
|
|
4620
4699
|
let m = null;
|
|
4621
|
-
const
|
|
4700
|
+
const W = x(0);
|
|
4622
4701
|
return el(() => {
|
|
4623
4702
|
m = setInterval(() => {
|
|
4624
4703
|
if (Z.value)
|
|
4625
|
-
|
|
4704
|
+
W.value = 0;
|
|
4626
4705
|
else
|
|
4627
4706
|
try {
|
|
4628
|
-
|
|
4707
|
+
W.value = U.getPartLevel(l.name);
|
|
4629
4708
|
} catch {
|
|
4630
|
-
Ol("randomLevelIndicators") ?
|
|
4709
|
+
Ol("randomLevelIndicators") ? W.value = Math.random() * F.value : W.value = 0;
|
|
4631
4710
|
}
|
|
4632
4711
|
}, 16);
|
|
4633
4712
|
}), cl(() => {
|
|
4634
4713
|
m && (clearInterval(m), m = null);
|
|
4635
4714
|
}), (c, s) => (X(), Y("div", {
|
|
4636
4715
|
ref_key: "el",
|
|
4637
|
-
ref:
|
|
4716
|
+
ref: V,
|
|
4638
4717
|
class: L([n.value, "part"])
|
|
4639
4718
|
}, [
|
|
4640
4719
|
C(XU, {
|
|
4641
4720
|
class: "tri",
|
|
4642
4721
|
mute: Z.value,
|
|
4643
4722
|
"onUpdate:mute": s[0] || (s[0] = (N) => Z.value = N),
|
|
4644
|
-
solo:
|
|
4645
|
-
"onUpdate:solo": s[1] || (s[1] = (N) =>
|
|
4723
|
+
solo: Q.value,
|
|
4724
|
+
"onUpdate:solo": s[1] || (s[1] = (N) => Q.value = N)
|
|
4646
4725
|
}, null, 8, ["mute", "solo"]),
|
|
4647
4726
|
C(wl, {
|
|
4648
4727
|
align: "left",
|
|
@@ -4654,7 +4733,7 @@ const zU = {
|
|
|
4654
4733
|
_: 1
|
|
4655
4734
|
}),
|
|
4656
4735
|
C(bl, {
|
|
4657
|
-
level:
|
|
4736
|
+
level: W.value,
|
|
4658
4737
|
"show-level": !0,
|
|
4659
4738
|
class: "vol",
|
|
4660
4739
|
value: F.value,
|
|
@@ -4672,29 +4751,29 @@ const zU = {
|
|
|
4672
4751
|
b117cda6: p.value,
|
|
4673
4752
|
"7cd7b1c8": M.value
|
|
4674
4753
|
}));
|
|
4675
|
-
const l = O("el"), U = O("rpt"), { width: F, height: Z } = ll(l),
|
|
4754
|
+
const l = O("el"), U = O("rpt"), { width: F, height: Z } = ll(l), Q = tl(), V = Ul(), t = Rl(), R = x("1"), a = x("A"), n = x(0), m = x(2), W = x(!1), c = x(!1), s = x(!1), N = x(!0);
|
|
4676
4755
|
let J = null;
|
|
4677
4756
|
v(() => {
|
|
4678
4757
|
var B;
|
|
4679
|
-
return ((B =
|
|
4758
|
+
return ((B = Q.beats) == null ? void 0 : B.length) > 0;
|
|
4680
4759
|
}, (B) => {
|
|
4681
|
-
console.log(B), B && !
|
|
4682
|
-
}), v(() =>
|
|
4683
|
-
m.value =
|
|
4760
|
+
console.log(B), B && !W.value && (R.value = V.currentBar.toString(), n.value = V.currentRepeat, m.value = Q.getRepeatCountForBar(V.currentBar), k(V.currentBar), W.value = !0);
|
|
4761
|
+
}), v(() => V.currentBar, (B) => {
|
|
4762
|
+
m.value = Q.getRepeatCountForBar(B);
|
|
4684
4763
|
}), v(R, () => {
|
|
4685
4764
|
R.value = R.value.replace(/\D/g, ""), R.value.length > 3 && (R.value = R.value.slice(0, 3));
|
|
4686
|
-
}), v(() =>
|
|
4765
|
+
}), v(() => V.currentBar, (B) => {
|
|
4687
4766
|
R.value = B.toString(), k(B);
|
|
4688
|
-
}), v(() =>
|
|
4767
|
+
}), v(() => V.currentBeat, () => {
|
|
4689
4768
|
N.value = !0, setTimeout(() => {
|
|
4690
4769
|
N.value = !1;
|
|
4691
4770
|
}, 50);
|
|
4692
4771
|
}), v(c, () => {
|
|
4693
4772
|
c.value && P();
|
|
4694
4773
|
});
|
|
4695
|
-
const p =
|
|
4774
|
+
const p = G(() => Math.min(Z.value / 2.25, F.value / 4.5) + "px"), M = G(() => Math.min(F.value / 15, Z.value / 6.4) + "px"), y = G(() => Object.keys(Q.practiceMarks).sort()), u = G(() => y.value.length > 0);
|
|
4696
4775
|
function k(B) {
|
|
4697
|
-
const S = Object.keys(
|
|
4776
|
+
const S = Object.keys(Q.practiceMarks).filter((T) => Q.practiceMarks[T] <= B).sort((T, I) => Q.practiceMarks[I] - Q.practiceMarks[T]);
|
|
4698
4777
|
S.length > 0 && (a.value = S[0]);
|
|
4699
4778
|
}
|
|
4700
4779
|
function E() {
|
|
@@ -4708,13 +4787,13 @@ const zU = {
|
|
|
4708
4787
|
S && S.stopPropagation(), a.value = B, c.value = !1, t.goToPracticeMark(B);
|
|
4709
4788
|
}
|
|
4710
4789
|
function j() {
|
|
4711
|
-
m.value > 1 && (s.value = !0),
|
|
4790
|
+
m.value > 1 && (s.value = !0), V.currentRepeat < m.value && t.setBar(V.currentBar, V.currentRepeat + 1);
|
|
4712
4791
|
}
|
|
4713
4792
|
function Zl() {
|
|
4714
|
-
m.value > 1 && (s.value = !0),
|
|
4793
|
+
m.value > 1 && (s.value = !0), V.currentRepeat > 1 && t.setBar(V.currentBar, V.currentRepeat - 1);
|
|
4715
4794
|
}
|
|
4716
4795
|
function i(B) {
|
|
4717
|
-
|
|
4796
|
+
u.value && (B.stopPropagation(), s.value = !1, c.value = !c.value);
|
|
4718
4797
|
}
|
|
4719
4798
|
function z(B) {
|
|
4720
4799
|
var S, T;
|
|
@@ -4732,8 +4811,8 @@ const zU = {
|
|
|
4732
4811
|
}
|
|
4733
4812
|
return el(() => {
|
|
4734
4813
|
document.addEventListener("click", z), Ol("beatAnimation") && (J = setInterval(() => {
|
|
4735
|
-
const B =
|
|
4736
|
-
|
|
4814
|
+
const B = V.currentBeat % Q.timeSignature + 1;
|
|
4815
|
+
V.setCurrentBar(V.currentBar, B, V.currentRepeat);
|
|
4737
4816
|
}, 800));
|
|
4738
4817
|
}), cl(() => {
|
|
4739
4818
|
document.removeEventListener("click", z), J && (clearInterval(J), J = null);
|
|
@@ -4744,10 +4823,10 @@ const zU = {
|
|
|
4744
4823
|
}, [
|
|
4745
4824
|
S[6] || (S[6] = h("div", { class: "frame" }, null, -1)),
|
|
4746
4825
|
h("div", {
|
|
4747
|
-
class: L(["mark-input", { empty: !a.value, edit: c.value, disabled: !
|
|
4826
|
+
class: L(["mark-input", { empty: !a.value, edit: c.value, disabled: !u.value }]),
|
|
4748
4827
|
onClick: i
|
|
4749
4828
|
}, [
|
|
4750
|
-
h("div", vU, K(
|
|
4829
|
+
h("div", vU, K(u.value ? a.value : "-"), 1)
|
|
4751
4830
|
], 2),
|
|
4752
4831
|
S[7] || (S[7] = h("div", { class: "mark-title" }, "Mark", -1)),
|
|
4753
4832
|
c.value ? f("", !0) : (X(), Y(al, { key: 0 }, [
|
|
@@ -4768,16 +4847,16 @@ const zU = {
|
|
|
4768
4847
|
ref: U,
|
|
4769
4848
|
class: L(["rpt-input", { edit: s.value, available: m.value > 1 }])
|
|
4770
4849
|
}, [
|
|
4771
|
-
h("div", KU, K(r(
|
|
4850
|
+
h("div", KU, K(r(V).currentRepeat || "-"), 1),
|
|
4772
4851
|
(X(), Y("svg", {
|
|
4773
|
-
class: L(["inc", { disabled: r(
|
|
4852
|
+
class: L(["inc", { disabled: r(V).currentRepeat >= m.value }]),
|
|
4774
4853
|
viewBox: "0 -100 100 100",
|
|
4775
4854
|
onClick: kl(j, ["prevent"])
|
|
4776
4855
|
}, S[1] || (S[1] = [
|
|
4777
4856
|
h("path", { d: "m10-20 40-60 40 60H10Z" }, null, -1)
|
|
4778
4857
|
]), 2)),
|
|
4779
4858
|
(X(), Y("svg", {
|
|
4780
|
-
class: L(["dec", { disabled: r(
|
|
4859
|
+
class: L(["dec", { disabled: r(V).currentRepeat <= 1 }]),
|
|
4781
4860
|
viewBox: "0 -100 100 100",
|
|
4782
4861
|
onClick: kl(Zl, ["prevent"])
|
|
4783
4862
|
}, S[2] || (S[2] = [
|
|
@@ -4786,7 +4865,7 @@ const zU = {
|
|
|
4786
4865
|
], 2),
|
|
4787
4866
|
S[4] || (S[4] = h("div", { class: "rpt-title" }, "Rpt", -1)),
|
|
4788
4867
|
h("div", gU, [
|
|
4789
|
-
h("div", HU, K(r(
|
|
4868
|
+
h("div", HU, K(r(V).currentBeat), 1)
|
|
4790
4869
|
]),
|
|
4791
4870
|
S[5] || (S[5] = h("div", { class: "beat-title" }, "Beat", -1))
|
|
4792
4871
|
], 64)),
|
|
@@ -4874,17 +4953,17 @@ const zU = {
|
|
|
4874
4953
|
"30d64f7d": t.value,
|
|
4875
4954
|
b8fbe65e: d.focusColor
|
|
4876
4955
|
}));
|
|
4877
|
-
const l = d, U = O("el"), { width: F, height: Z } = ll(U),
|
|
4878
|
-
v(
|
|
4879
|
-
const n = l.transformSliderToDisplay(
|
|
4880
|
-
|
|
4881
|
-
}), v(
|
|
4882
|
-
|
|
4956
|
+
const l = d, U = O("el"), { width: F, height: Z } = ll(U), Q = _(d, "value"), V = x(l.formatValue(l.transformSliderToDisplay(Q.value)));
|
|
4957
|
+
v(Q, () => {
|
|
4958
|
+
const n = l.transformSliderToDisplay(Q.value);
|
|
4959
|
+
V.value = l.formatValue(n);
|
|
4960
|
+
}), v(V, () => {
|
|
4961
|
+
V.value = l.validateInput(V.value), l.maxChars && V.value.length > l.maxChars && (V.value = V.value.slice(0, l.maxChars));
|
|
4883
4962
|
});
|
|
4884
|
-
const t =
|
|
4963
|
+
const t = G(() => Math.min(Z.value / 2.25, F.value / 2.2) + "px"), R = G(() => Math.min(F.value / 3, Z.value / 6.4) + "px");
|
|
4885
4964
|
function a() {
|
|
4886
|
-
const n = l.parseValue(
|
|
4887
|
-
|
|
4965
|
+
const n = l.parseValue(V.value), m = l.transformDisplayToSlider(n);
|
|
4966
|
+
Q.value = Math.min(Math.max(m, l.sliderMin), l.sliderMax);
|
|
4888
4967
|
}
|
|
4889
4968
|
return (n, m) => (X(), Y("div", {
|
|
4890
4969
|
class: "outer",
|
|
@@ -4895,18 +4974,18 @@ const zU = {
|
|
|
4895
4974
|
vl(h("input", {
|
|
4896
4975
|
type: "text",
|
|
4897
4976
|
class: "input",
|
|
4898
|
-
"onUpdate:modelValue": m[0] || (m[0] = (
|
|
4977
|
+
"onUpdate:modelValue": m[0] || (m[0] = (W) => V.value = W),
|
|
4899
4978
|
inputmode: "decimal",
|
|
4900
4979
|
pattern: "\\d*",
|
|
4901
4980
|
onChange: a
|
|
4902
4981
|
}, null, 544), [
|
|
4903
|
-
[Kl,
|
|
4982
|
+
[Kl, V.value]
|
|
4904
4983
|
]),
|
|
4905
4984
|
h("div", fU, K(d.title), 1),
|
|
4906
4985
|
C(bl, {
|
|
4907
4986
|
class: "slider",
|
|
4908
|
-
value:
|
|
4909
|
-
"onUpdate:value": m[1] || (m[1] = (
|
|
4987
|
+
value: Q.value,
|
|
4988
|
+
"onUpdate:value": m[1] || (m[1] = (W) => Q.value = W),
|
|
4910
4989
|
"thumb-length": d.thumbLength,
|
|
4911
4990
|
max: d.sliderMax,
|
|
4912
4991
|
min: d.sliderMin
|
|
@@ -4916,13 +4995,13 @@ const zU = {
|
|
|
4916
4995
|
}, ql = /* @__PURE__ */ g(AU, [["__scopeId", "data-v-79c7a539"]]), qU = {
|
|
4917
4996
|
__name: "SpeedInput",
|
|
4918
4997
|
setup(d) {
|
|
4919
|
-
const l = Ul(), U = Rl(), F =
|
|
4998
|
+
const l = Ul(), U = Rl(), F = G({
|
|
4920
4999
|
get: () => Math.log2(l.playbackSpeed) * 0.5 + 0.5,
|
|
4921
5000
|
set: (a) => {
|
|
4922
5001
|
const n = Math.pow(2, a * 2 - 1);
|
|
4923
5002
|
U.setPlaybackSpeed(n);
|
|
4924
5003
|
}
|
|
4925
|
-
}), Z = (a) => Math.floor(Math.pow(2, a * 2 - 1) * 100 + 0.5) + "",
|
|
5004
|
+
}), Z = (a) => Math.floor(Math.pow(2, a * 2 - 1) * 100 + 0.5) + "", Q = (a) => parseFloat(a), V = (a) => a.replace(/\D/g, ""), t = (a) => a, R = (a) => {
|
|
4926
5005
|
const n = Math.log2(a / 100) * 0.5 + 0.5;
|
|
4927
5006
|
return Math.min(Math.max(n, 0), 1);
|
|
4928
5007
|
};
|
|
@@ -4933,8 +5012,8 @@ const zU = {
|
|
|
4933
5012
|
color: "#336",
|
|
4934
5013
|
"text-color": "#aad",
|
|
4935
5014
|
"format-value": Z,
|
|
4936
|
-
"parse-value":
|
|
4937
|
-
"validate-input":
|
|
5015
|
+
"parse-value": Q,
|
|
5016
|
+
"validate-input": V,
|
|
4938
5017
|
"transform-slider-to-display": t,
|
|
4939
5018
|
"transform-display-to-slider": R,
|
|
4940
5019
|
"thumb-length": 2,
|
|
@@ -4944,7 +5023,7 @@ const zU = {
|
|
|
4944
5023
|
}, _U = {
|
|
4945
5024
|
__name: "TimeInput",
|
|
4946
5025
|
setup(d) {
|
|
4947
|
-
const l = Ul(), U = tl(), F = Rl(), Z = (a) => a.toFixed(1),
|
|
5026
|
+
const l = Ul(), U = tl(), F = Rl(), Z = (a) => a.toFixed(1), Q = (a) => parseFloat(a), V = (a) => a.replace(/[^0-9.]/g, ""), t = (a) => a, R = (a) => a;
|
|
4948
5027
|
return (a, n) => (X(), nl(ql, {
|
|
4949
5028
|
value: r(l).currentTime,
|
|
4950
5029
|
"onUpdate:value": [
|
|
@@ -4959,8 +5038,8 @@ const zU = {
|
|
|
4959
5038
|
"slider-max": r(U).totalDuration,
|
|
4960
5039
|
"slider-min": 0,
|
|
4961
5040
|
"format-value": Z,
|
|
4962
|
-
"parse-value":
|
|
4963
|
-
"validate-input":
|
|
5041
|
+
"parse-value": Q,
|
|
5042
|
+
"validate-input": V,
|
|
4964
5043
|
"transform-slider-to-display": t,
|
|
4965
5044
|
"transform-display-to-slider": R,
|
|
4966
5045
|
"thumb-length": 2
|
|
@@ -4970,7 +5049,7 @@ const zU = {
|
|
|
4970
5049
|
__name: "AudioButton",
|
|
4971
5050
|
setup(d) {
|
|
4972
5051
|
const l = x(!1), U = () => l.value = !0, F = () => l.value = !1;
|
|
4973
|
-
return (Z,
|
|
5052
|
+
return (Z, Q) => (X(), Y("div", {
|
|
4974
5053
|
class: L(["button-outer", { down: l.value }]),
|
|
4975
5054
|
onPointerdown: U,
|
|
4976
5055
|
onPointerup: F,
|
|
@@ -4991,22 +5070,22 @@ const zU = {
|
|
|
4991
5070
|
function Z() {
|
|
4992
5071
|
U.isPlaying ? F.stop() : F.play();
|
|
4993
5072
|
}
|
|
4994
|
-
function
|
|
4995
|
-
const y = U.currentTime,
|
|
5073
|
+
function Q() {
|
|
5074
|
+
const y = U.currentTime, u = l.beats.filter((E) => E.beat === 1).sort((E, H) => E.time - H.time);
|
|
4996
5075
|
let k = null;
|
|
4997
|
-
for (let E =
|
|
4998
|
-
if (
|
|
4999
|
-
k =
|
|
5076
|
+
for (let E = u.length - 1; E >= 0; E--)
|
|
5077
|
+
if (u[E].time < y) {
|
|
5078
|
+
k = u[E];
|
|
5000
5079
|
break;
|
|
5001
5080
|
}
|
|
5002
5081
|
k && F.setBar(k.bar, k.repeat);
|
|
5003
5082
|
}
|
|
5004
|
-
function
|
|
5005
|
-
const y = U.currentTime,
|
|
5083
|
+
function V() {
|
|
5084
|
+
const y = U.currentTime, u = l.beats.filter((E) => E.beat === 1).sort((E, H) => E.time - H.time);
|
|
5006
5085
|
let k = null;
|
|
5007
|
-
for (let E = 0; E <
|
|
5008
|
-
if (
|
|
5009
|
-
k =
|
|
5086
|
+
for (let E = 0; E < u.length; E++)
|
|
5087
|
+
if (u[E].time > y) {
|
|
5088
|
+
k = u[E];
|
|
5010
5089
|
break;
|
|
5011
5090
|
}
|
|
5012
5091
|
k && F.setBar(k.bar, k.repeat);
|
|
@@ -5014,8 +5093,8 @@ const zU = {
|
|
|
5014
5093
|
function t() {
|
|
5015
5094
|
F.playStartingNotes();
|
|
5016
5095
|
}
|
|
5017
|
-
const R =
|
|
5018
|
-
function
|
|
5096
|
+
const R = G(() => U.metronomeEnabled), a = G(() => U.leadInEnabled), n = x(!1), m = x(null);
|
|
5097
|
+
function W() {
|
|
5019
5098
|
n.value = !n.value, n.value && F.audioEngine.initializeAudioSystem().catch((y) => {
|
|
5020
5099
|
console.warn("Audio system pre-initialization failed:", y);
|
|
5021
5100
|
});
|
|
@@ -5037,14 +5116,14 @@ const zU = {
|
|
|
5037
5116
|
function J() {
|
|
5038
5117
|
F.toggleLeadIn();
|
|
5039
5118
|
}
|
|
5040
|
-
const p =
|
|
5119
|
+
const p = G({
|
|
5041
5120
|
get: () => U.masterVolume,
|
|
5042
5121
|
set: (y) => U.setMasterVolume(y)
|
|
5043
|
-
}), M =
|
|
5122
|
+
}), M = G({
|
|
5044
5123
|
get: () => U.metronomeVolume,
|
|
5045
5124
|
set: (y) => U.setMetronomeVolume(y)
|
|
5046
5125
|
});
|
|
5047
|
-
return (y,
|
|
5126
|
+
return (y, u) => (X(), Y("div", UF, [
|
|
5048
5127
|
h("div", FF, [
|
|
5049
5128
|
C(wl, {
|
|
5050
5129
|
class: "text",
|
|
@@ -5063,8 +5142,8 @@ const zU = {
|
|
|
5063
5142
|
(X(), Y("svg", {
|
|
5064
5143
|
class: "menu",
|
|
5065
5144
|
viewBox: "0 -960 960 960",
|
|
5066
|
-
onClick:
|
|
5067
|
-
},
|
|
5145
|
+
onClick: W
|
|
5146
|
+
}, u[2] || (u[2] = [
|
|
5068
5147
|
h("path", { d: "M120-240v-80h720v80H120Zm0-200v-80h720v80H120Zm0-200v-80h720v80H120Z" }, null, -1)
|
|
5069
5148
|
]))),
|
|
5070
5149
|
n.value && y.$slots.menu ? (X(), Y("div", {
|
|
@@ -5080,25 +5159,25 @@ const zU = {
|
|
|
5080
5159
|
class: "main",
|
|
5081
5160
|
colour: "red",
|
|
5082
5161
|
value: p.value,
|
|
5083
|
-
"onUpdate:value":
|
|
5162
|
+
"onUpdate:value": u[0] || (u[0] = (k) => p.value = k)
|
|
5084
5163
|
}, null, 8, ["value"]),
|
|
5085
5164
|
C(bl, {
|
|
5086
5165
|
class: "tick",
|
|
5087
5166
|
colour: "blue",
|
|
5088
5167
|
value: M.value,
|
|
5089
|
-
"onUpdate:value":
|
|
5168
|
+
"onUpdate:value": u[1] || (u[1] = (k) => M.value = k)
|
|
5090
5169
|
}, null, 8, ["value"]),
|
|
5091
|
-
|
|
5092
|
-
|
|
5170
|
+
u[8] || (u[8] = h("div", { class: "main-t" }, "Main", -1)),
|
|
5171
|
+
u[9] || (u[9] = h("div", { class: "tick-t" }, "Tick", -1)),
|
|
5093
5172
|
C(OU, { class: "bar" }),
|
|
5094
5173
|
C(_U, { class: "time" }),
|
|
5095
5174
|
C(qU, { class: "speed" }),
|
|
5096
5175
|
h("div", dF, [
|
|
5097
5176
|
C(Fl, {
|
|
5098
5177
|
class: "button",
|
|
5099
|
-
onClick:
|
|
5178
|
+
onClick: Q
|
|
5100
5179
|
}, {
|
|
5101
|
-
default: D(() =>
|
|
5180
|
+
default: D(() => u[3] || (u[3] = [
|
|
5102
5181
|
h("svg", {
|
|
5103
5182
|
class: "icon",
|
|
5104
5183
|
viewBox: "0 0 48 48"
|
|
@@ -5124,9 +5203,9 @@ const zU = {
|
|
|
5124
5203
|
}),
|
|
5125
5204
|
C(Fl, {
|
|
5126
5205
|
class: "button",
|
|
5127
|
-
onClick:
|
|
5206
|
+
onClick: V
|
|
5128
5207
|
}, {
|
|
5129
|
-
default: D(() =>
|
|
5208
|
+
default: D(() => u[4] || (u[4] = [
|
|
5130
5209
|
h("svg", {
|
|
5131
5210
|
class: "icon",
|
|
5132
5211
|
viewBox: "0 0 48 48"
|
|
@@ -5145,7 +5224,7 @@ const zU = {
|
|
|
5145
5224
|
(X(), Y("svg", {
|
|
5146
5225
|
class: L(["icon", R.value ? "on" : "off"]),
|
|
5147
5226
|
viewBox: "-128 -128 768 768"
|
|
5148
|
-
},
|
|
5227
|
+
}, u[5] || (u[5] = [
|
|
5149
5228
|
h("path", { d: "m 463.84136,154.89339 c -6.42,-6.42 -16.83,-6.42 -23.251,0 -71.31197,70.35135 -136.61146,132.25426 -208.741,199.7 h -105.82 c 23.35495,-140.1063 67.13099,-217.59716 120.727,-318.357996 0.86,-0.803 2.209,-0.801 3.067,-10e-4 20.50653,37.383983 48.51152,88.812606 72.26194,147.190756 1.186,9.002 12.2214,17.4338 23.3242,11.71391 9.002,-1.186 11.1594,-12.2324 9.9724,-21.2344 -21.69905,-53.89113 -30.43965,-85.078342 -83.11454,-161.702266 -13.446,-12.55299965 -34.508,-12.55699965 -47.954,10e-4 C 126.80877,149.30021 96.099465,324.74626 77.091365,474.25139 c -2.829,21.473 13.907,40.535 35.543995,40.535 h 271.311 c 21.661,0 38.373,-19.087 35.544,-40.535 -8.26237,-52.34207 -14.88466,-100.7074 -24.7871,-157.02622 -6.40949,-11.78839 -8.3911,-14.9907 -17.4031,-13.8037 -9.002,1.186 -13.59751,8.0528 -12.41051,17.0548 l 5.66371,34.11712 h -83.159 c 64.35441,-63.86663 129.29308,-130.29894 176.448,-176.449 6.42,-6.42 6.42,-16.83 -10e-4,-23.251 z m -88.956,232.582 12.004,91.074 c 0.112,0.846 -0.148,1.701 -0.708,2.341 -0.566,0.645 -1.38,1.014 -2.235,1.014 h -271.311 c -0.855,0 -1.668,-0.369 -2.231,-1.011 -0.564,-0.643 -0.824,-1.499 -0.712,-2.347 l 12.003,-91.072 h 253.19 z" }, null, -1)
|
|
5150
5229
|
]), 2))
|
|
5151
5230
|
]),
|
|
@@ -5159,7 +5238,7 @@ const zU = {
|
|
|
5159
5238
|
(X(), Y("svg", {
|
|
5160
5239
|
class: L(["icon", a.value ? "on" : "off"]),
|
|
5161
5240
|
viewBox: "-2 -2 28 28"
|
|
5162
|
-
},
|
|
5241
|
+
}, u[6] || (u[6] = [
|
|
5163
5242
|
h("path", { d: "m 8.9838564,1.5166215 v 2 h 5.9999996 v -2 z m 2.9999996,3 c -4.9699996,0 -8.9999996,4.0299999 -8.9999996,8.9999995 0,4.97 4.02,9 8.9999996,9 4.98,0 9,-4.03 9,-9 0,-2.12 -0.740703,-4.0693745 -1.970703,-5.6093745 l 1.419922,-1.421875 c -0.43,-0.51 -0.900156,-0.9882031 -1.410156,-1.4082031 l -1.419922,1.4199219 c -1.55,-1.24 -3.499141,-1.9804688 -5.619141,-1.9804688 z m -1.789062,4.7480469 6,4.4999996 -6,4.5 z" }, null, -1)
|
|
5164
5243
|
]), 2))
|
|
5165
5244
|
]),
|
|
@@ -5169,7 +5248,7 @@ const zU = {
|
|
|
5169
5248
|
class: "button",
|
|
5170
5249
|
onClick: t
|
|
5171
5250
|
}, {
|
|
5172
|
-
default: D(() =>
|
|
5251
|
+
default: D(() => u[7] || (u[7] = [
|
|
5173
5252
|
h("svg", {
|
|
5174
5253
|
class: "icon",
|
|
5175
5254
|
viewBox: "0 -960 960 960"
|
|
@@ -5217,8 +5296,8 @@ const zU = {
|
|
|
5217
5296
|
}
|
|
5218
5297
|
},
|
|
5219
5298
|
setup(d) {
|
|
5220
|
-
const l = d, U =
|
|
5221
|
-
return (
|
|
5299
|
+
const l = d, U = G(() => l.progress !== null), F = G(() => l.progress === null ? 0 : Math.max(0, Math.min(100, l.progress * 100))), Z = G(() => l.hasError ? l.errorMessage : l.message);
|
|
5300
|
+
return (Q, V) => (X(), Y("div", RF, [
|
|
5222
5301
|
U.value ? (X(), Y("div", aF, [
|
|
5223
5302
|
h("div", {
|
|
5224
5303
|
class: "progress-fill",
|
|
@@ -5296,7 +5375,7 @@ const zU = {
|
|
|
5296
5375
|
}), cF = { class: "container" }, eF = { class: "panel" }, sF = {
|
|
5297
5376
|
key: 0,
|
|
5298
5377
|
class: "blur"
|
|
5299
|
-
}, rl = 40, Ll = 40, Cl = 100, hF = 50, xl = 400, Ml = 570, zl = 570, BF = 350, JF = 330,
|
|
5378
|
+
}, rl = 40, Ll = 40, Cl = 100, hF = 50, xl = 400, Ml = 570, zl = 570, BF = 350, JF = 330, uF = 360, GF = 360, iF = {
|
|
5300
5379
|
__name: "MixerLayout",
|
|
5301
5380
|
props: {
|
|
5302
5381
|
/** Whether to show initialization progress (default: true) */
|
|
@@ -5306,7 +5385,7 @@ const zU = {
|
|
|
5306
5385
|
}
|
|
5307
5386
|
},
|
|
5308
5387
|
setup(d) {
|
|
5309
|
-
$((
|
|
5388
|
+
$((W) => ({
|
|
5310
5389
|
"53ffcc08": a.value,
|
|
5311
5390
|
"53f8f922": n.value,
|
|
5312
5391
|
"2b0b3d37": m.value
|
|
@@ -5315,21 +5394,21 @@ const zU = {
|
|
|
5315
5394
|
el(() => {
|
|
5316
5395
|
Z.initializeListeners();
|
|
5317
5396
|
});
|
|
5318
|
-
const
|
|
5319
|
-
const
|
|
5320
|
-
return
|
|
5321
|
-
}), a =
|
|
5397
|
+
const Q = O("container"), { width: V } = ll(Q), t = G(() => F.isLoaded), R = G(() => {
|
|
5398
|
+
const W = V.value, c = U.parts.length;
|
|
5399
|
+
return W < 640 || W < rl * c + xl ? 0 : W < Ll * c + Ml ? 1 : W < Cl * c + zl ? 2 : 3;
|
|
5400
|
+
}), a = G(() => {
|
|
5322
5401
|
switch (R.value) {
|
|
5323
5402
|
case 0:
|
|
5324
5403
|
return `${BF}px ` + `${hF}px `.repeat(U.parts.length);
|
|
5325
5404
|
case 1:
|
|
5326
5405
|
return `${JF}px`;
|
|
5327
5406
|
case 2:
|
|
5328
|
-
return `${GF}px`;
|
|
5329
|
-
default:
|
|
5330
5407
|
return `${uF}px`;
|
|
5408
|
+
default:
|
|
5409
|
+
return `${GF}px`;
|
|
5331
5410
|
}
|
|
5332
|
-
}), n =
|
|
5411
|
+
}), n = G(() => {
|
|
5333
5412
|
switch (R.value) {
|
|
5334
5413
|
case 0:
|
|
5335
5414
|
return "100vw";
|
|
@@ -5340,14 +5419,14 @@ const zU = {
|
|
|
5340
5419
|
default:
|
|
5341
5420
|
return `${Cl}px `.repeat(U.parts.length) + `${zl}px`;
|
|
5342
5421
|
}
|
|
5343
|
-
}), m =
|
|
5344
|
-
const
|
|
5345
|
-
return R.value > 0 ? '"' +
|
|
5422
|
+
}), m = G(() => {
|
|
5423
|
+
const W = [...U.parts.keys()];
|
|
5424
|
+
return R.value > 0 ? '"' + W.map((c) => "part" + c).join(" ") + ' controls"' : '"controls" ' + W.map((c) => '"part' + c + '"').join(" ");
|
|
5346
5425
|
});
|
|
5347
|
-
return (
|
|
5426
|
+
return (W, c) => (X(), Y("div", {
|
|
5348
5427
|
class: "outer",
|
|
5349
5428
|
ref_key: "container",
|
|
5350
|
-
ref:
|
|
5429
|
+
ref: Q
|
|
5351
5430
|
}, [
|
|
5352
5431
|
h("div", cF, [
|
|
5353
5432
|
h("div", eF, [
|
|
@@ -5369,7 +5448,7 @@ const zU = {
|
|
|
5369
5448
|
class: "controls"
|
|
5370
5449
|
}, {
|
|
5371
5450
|
menu: D(() => [
|
|
5372
|
-
Vl(
|
|
5451
|
+
Vl(W.$slots, "menu", {}, void 0, !0)
|
|
5373
5452
|
]),
|
|
5374
5453
|
_: 3
|
|
5375
5454
|
}, 8, ["title"]),
|
|
@@ -5568,7 +5647,7 @@ export {
|
|
|
5568
5647
|
bl as AudioSlider,
|
|
5569
5648
|
OU as BarInput,
|
|
5570
5649
|
ql as BaseNumericInput,
|
|
5571
|
-
|
|
5650
|
+
Gl as DEV_MODE,
|
|
5572
5651
|
YF as DummyAudioEngine,
|
|
5573
5652
|
WF as InitializationProgress,
|
|
5574
5653
|
tF as MixerControls,
|