@songram/songram-daw-engine 3.1.0 → 3.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +1 -0
- package/dist/index.js +680 -678
- package/dist/index.js.map +1 -1
- package/package.json +10 -3
package/dist/index.js
CHANGED
|
@@ -6,17 +6,17 @@ function et(a) {
|
|
|
6
6
|
const {
|
|
7
7
|
audioBuffer: t,
|
|
8
8
|
startSample: e,
|
|
9
|
-
offsetSamples:
|
|
10
|
-
gain:
|
|
9
|
+
offsetSamples: i = 0,
|
|
10
|
+
gain: n = 1,
|
|
11
11
|
name: r,
|
|
12
12
|
color: s,
|
|
13
13
|
fadeIn: c,
|
|
14
|
-
fadeOut:
|
|
15
|
-
waveformData:
|
|
14
|
+
fadeOut: l,
|
|
15
|
+
waveformData: u,
|
|
16
16
|
midiNotes: o,
|
|
17
17
|
midiChannel: h,
|
|
18
18
|
midiProgram: f
|
|
19
|
-
} = a, d = t?.sampleRate ?? a.sampleRate ??
|
|
19
|
+
} = a, d = t?.sampleRate ?? a.sampleRate ?? u?.sample_rate, g = t?.length ?? a.sourceDurationSamples ?? (u && d ? Math.ceil(u.duration * d) : void 0);
|
|
20
20
|
if (d === void 0)
|
|
21
21
|
throw new Error(
|
|
22
22
|
"createClip: sampleRate is required when audioBuffer is not provided (can use waveformData.sample_rate)"
|
|
@@ -25,8 +25,8 @@ function et(a) {
|
|
|
25
25
|
throw new Error(
|
|
26
26
|
"createClip: sourceDurationSamples is required when audioBuffer is not provided (can use waveformData.duration)"
|
|
27
27
|
);
|
|
28
|
-
t &&
|
|
29
|
-
`Sample rate mismatch: audioBuffer (${t.sampleRate}) vs waveformData (${
|
|
28
|
+
t && u && t.sampleRate !== u.sample_rate && console.warn(
|
|
29
|
+
`Sample rate mismatch: audioBuffer (${t.sampleRate}) vs waveformData (${u.sample_rate}). Using audioBuffer sample rate. Waveform visualization may be slightly off.`
|
|
30
30
|
);
|
|
31
31
|
const b = a.durationSamples ?? g;
|
|
32
32
|
return {
|
|
@@ -34,15 +34,15 @@ function et(a) {
|
|
|
34
34
|
audioBuffer: t,
|
|
35
35
|
startSample: e,
|
|
36
36
|
durationSamples: b,
|
|
37
|
-
offsetSamples:
|
|
37
|
+
offsetSamples: i,
|
|
38
38
|
sampleRate: d,
|
|
39
39
|
sourceDurationSamples: g,
|
|
40
|
-
gain:
|
|
40
|
+
gain: n,
|
|
41
41
|
name: r,
|
|
42
42
|
color: s,
|
|
43
43
|
fadeIn: c,
|
|
44
|
-
fadeOut:
|
|
45
|
-
waveformData:
|
|
44
|
+
fadeOut: l,
|
|
45
|
+
waveformData: u,
|
|
46
46
|
midiNotes: o,
|
|
47
47
|
midiChannel: h,
|
|
48
48
|
midiProgram: f
|
|
@@ -52,43 +52,43 @@ function Ke(a) {
|
|
|
52
52
|
const {
|
|
53
53
|
audioBuffer: t,
|
|
54
54
|
startTime: e,
|
|
55
|
-
offset:
|
|
56
|
-
gain:
|
|
55
|
+
offset: i = 0,
|
|
56
|
+
gain: n = 1,
|
|
57
57
|
name: r,
|
|
58
58
|
color: s,
|
|
59
59
|
fadeIn: c,
|
|
60
|
-
fadeOut:
|
|
61
|
-
waveformData:
|
|
60
|
+
fadeOut: l,
|
|
61
|
+
waveformData: u,
|
|
62
62
|
midiNotes: o,
|
|
63
63
|
midiChannel: h,
|
|
64
64
|
midiProgram: f
|
|
65
|
-
} = a, d = t?.sampleRate ?? a.sampleRate ??
|
|
65
|
+
} = a, d = t?.sampleRate ?? a.sampleRate ?? u?.sample_rate;
|
|
66
66
|
if (d === void 0)
|
|
67
67
|
throw new Error(
|
|
68
68
|
"createClipFromSeconds: sampleRate is required when audioBuffer is not provided (can use waveformData.sample_rate)"
|
|
69
69
|
);
|
|
70
|
-
const g = t?.duration ?? a.sourceDuration ??
|
|
70
|
+
const g = t?.duration ?? a.sourceDuration ?? u?.duration;
|
|
71
71
|
if (g === void 0)
|
|
72
72
|
throw new Error(
|
|
73
73
|
"createClipFromSeconds: sourceDuration is required when audioBuffer is not provided (can use waveformData.duration)"
|
|
74
74
|
);
|
|
75
|
-
t &&
|
|
76
|
-
`Sample rate mismatch: audioBuffer (${t.sampleRate}) vs waveformData (${
|
|
75
|
+
t && u && t.sampleRate !== u.sample_rate && console.warn(
|
|
76
|
+
`Sample rate mismatch: audioBuffer (${t.sampleRate}) vs waveformData (${u.sample_rate}). Using audioBuffer sample rate. Waveform visualization may be slightly off.`
|
|
77
77
|
);
|
|
78
78
|
const b = a.duration ?? g;
|
|
79
79
|
return et({
|
|
80
80
|
audioBuffer: t,
|
|
81
81
|
startSample: Math.round(e * d),
|
|
82
82
|
durationSamples: Math.round(b * d),
|
|
83
|
-
offsetSamples: Math.round(
|
|
83
|
+
offsetSamples: Math.round(i * d),
|
|
84
84
|
sampleRate: d,
|
|
85
85
|
sourceDurationSamples: Math.ceil(g * d),
|
|
86
|
-
gain:
|
|
86
|
+
gain: n,
|
|
87
87
|
name: r,
|
|
88
88
|
color: s,
|
|
89
89
|
fadeIn: c,
|
|
90
|
-
fadeOut:
|
|
91
|
-
waveformData:
|
|
90
|
+
fadeOut: l,
|
|
91
|
+
waveformData: u,
|
|
92
92
|
midiNotes: o,
|
|
93
93
|
midiChannel: h,
|
|
94
94
|
midiProgram: f
|
|
@@ -98,37 +98,37 @@ function Xe(a) {
|
|
|
98
98
|
const {
|
|
99
99
|
name: t,
|
|
100
100
|
clips: e = [],
|
|
101
|
-
muted:
|
|
102
|
-
soloed:
|
|
101
|
+
muted: i = !1,
|
|
102
|
+
soloed: n = !1,
|
|
103
103
|
volume: r = 1,
|
|
104
104
|
pan: s = 0,
|
|
105
105
|
color: c,
|
|
106
|
-
height:
|
|
107
|
-
spectrogramConfig:
|
|
106
|
+
height: l,
|
|
107
|
+
spectrogramConfig: u,
|
|
108
108
|
spectrogramColorMap: o
|
|
109
109
|
} = a;
|
|
110
110
|
return {
|
|
111
111
|
id: Vt(),
|
|
112
112
|
name: t,
|
|
113
113
|
clips: e,
|
|
114
|
-
muted:
|
|
115
|
-
soloed:
|
|
114
|
+
muted: i,
|
|
115
|
+
soloed: n,
|
|
116
116
|
volume: r,
|
|
117
117
|
pan: s,
|
|
118
118
|
color: c,
|
|
119
|
-
height:
|
|
120
|
-
spectrogramConfig:
|
|
119
|
+
height: l,
|
|
120
|
+
spectrogramConfig: u,
|
|
121
121
|
spectrogramColorMap: o
|
|
122
122
|
};
|
|
123
123
|
}
|
|
124
124
|
function Ze(a, t = 44100, e) {
|
|
125
|
-
const
|
|
126
|
-
const c = s.clips.reduce((
|
|
125
|
+
const n = a.reduce((r, s) => {
|
|
126
|
+
const c = s.clips.reduce((l, u) => Math.max(l, u.startSample + u.durationSamples), 0);
|
|
127
127
|
return Math.max(r, c);
|
|
128
128
|
}, 0) / t;
|
|
129
129
|
return {
|
|
130
130
|
tracks: a,
|
|
131
|
-
duration:
|
|
131
|
+
duration: n,
|
|
132
132
|
sampleRate: t,
|
|
133
133
|
name: e?.name,
|
|
134
134
|
tempo: e?.tempo,
|
|
@@ -139,20 +139,20 @@ function Vt() {
|
|
|
139
139
|
return `${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
|
|
140
140
|
}
|
|
141
141
|
function Qe(a, t, e) {
|
|
142
|
-
return a.clips.filter((
|
|
143
|
-
const
|
|
144
|
-
return
|
|
142
|
+
return a.clips.filter((i) => {
|
|
143
|
+
const n = i.startSample + i.durationSamples;
|
|
144
|
+
return i.startSample < e && n > t;
|
|
145
145
|
});
|
|
146
146
|
}
|
|
147
147
|
function Ye(a, t) {
|
|
148
148
|
return a.clips.filter((e) => {
|
|
149
|
-
const
|
|
150
|
-
return t >= e.startSample && t <
|
|
149
|
+
const i = e.startSample + e.durationSamples;
|
|
150
|
+
return t >= e.startSample && t < i;
|
|
151
151
|
});
|
|
152
152
|
}
|
|
153
153
|
function tr(a, t) {
|
|
154
|
-
const e = a.startSample + a.durationSamples,
|
|
155
|
-
return a.startSample <
|
|
154
|
+
const e = a.startSample + a.durationSamples, i = t.startSample + t.durationSamples;
|
|
155
|
+
return a.startSample < i && e > t.startSample;
|
|
156
156
|
}
|
|
157
157
|
function rt(a) {
|
|
158
158
|
return [...a].sort((t, e) => t.startSample - e.startSample);
|
|
@@ -160,12 +160,12 @@ function rt(a) {
|
|
|
160
160
|
function er(a) {
|
|
161
161
|
if (a.clips.length === 0) return [];
|
|
162
162
|
const t = rt(a.clips), e = [];
|
|
163
|
-
for (let
|
|
164
|
-
const
|
|
165
|
-
r >
|
|
166
|
-
startSample:
|
|
163
|
+
for (let i = 0; i < t.length - 1; i++) {
|
|
164
|
+
const n = t[i].startSample + t[i].durationSamples, r = t[i + 1].startSample;
|
|
165
|
+
r > n && e.push({
|
|
166
|
+
startSample: n,
|
|
167
167
|
endSample: r,
|
|
168
|
-
durationSamples: r -
|
|
168
|
+
durationSamples: r - n
|
|
169
169
|
});
|
|
170
170
|
}
|
|
171
171
|
return e;
|
|
@@ -198,17 +198,17 @@ function Qt(a, t = R) {
|
|
|
198
198
|
const [e] = a;
|
|
199
199
|
return e * Lt(a, t);
|
|
200
200
|
}
|
|
201
|
-
function cr(a, t, e,
|
|
202
|
-
return Math.round(a * 60 * e / (t *
|
|
201
|
+
function cr(a, t, e, i = R) {
|
|
202
|
+
return Math.round(a * 60 * e / (t * i));
|
|
203
203
|
}
|
|
204
|
-
function ur(a, t, e,
|
|
205
|
-
return Math.round(a *
|
|
204
|
+
function ur(a, t, e, i = R) {
|
|
205
|
+
return Math.round(a * i * t / (60 * e));
|
|
206
206
|
}
|
|
207
207
|
function lr(a, t) {
|
|
208
208
|
return Math.round(a / t) * t;
|
|
209
209
|
}
|
|
210
210
|
function hr(a, t, e = R) {
|
|
211
|
-
const
|
|
211
|
+
const i = Qt(t, e), n = Lt(t, e), r = Math.floor(a / i) + 1, s = Math.floor(a % i / n) + 1;
|
|
212
212
|
return s === 1 ? `${r}` : `${r}.${s}`;
|
|
213
213
|
}
|
|
214
214
|
const j = -100;
|
|
@@ -238,29 +238,29 @@ function mt(a) {
|
|
|
238
238
|
function mr(a, t, e) {
|
|
239
239
|
return Math.floor((a + t) / e) - Math.floor(a / e);
|
|
240
240
|
}
|
|
241
|
-
function te(a, t, e,
|
|
242
|
-
let
|
|
241
|
+
function te(a, t, e, i) {
|
|
242
|
+
let n = t;
|
|
243
243
|
const r = -a.startSample;
|
|
244
|
-
if (
|
|
245
|
-
const s = e[
|
|
246
|
-
|
|
244
|
+
if (n = Math.max(n, r), i > 0) {
|
|
245
|
+
const s = e[i - 1], l = s.startSample + s.durationSamples - a.startSample;
|
|
246
|
+
n = Math.max(n, l);
|
|
247
247
|
}
|
|
248
|
-
if (
|
|
249
|
-
const c = e[
|
|
250
|
-
|
|
248
|
+
if (i < e.length - 1) {
|
|
249
|
+
const c = e[i + 1].startSample - (a.startSample + a.durationSamples);
|
|
250
|
+
n = Math.min(n, c);
|
|
251
251
|
}
|
|
252
|
-
return
|
|
252
|
+
return n;
|
|
253
253
|
}
|
|
254
|
-
function ee(a, t, e,
|
|
254
|
+
function ee(a, t, e, i, n, r) {
|
|
255
255
|
let s = t;
|
|
256
256
|
if (e === "left") {
|
|
257
|
-
if (s = Math.max(s, -a.startSample), s = Math.max(s, -a.offsetSamples),
|
|
258
|
-
const c = n
|
|
259
|
-
s = Math.max(s,
|
|
257
|
+
if (s = Math.max(s, -a.startSample), s = Math.max(s, -a.offsetSamples), n > 0) {
|
|
258
|
+
const c = i[n - 1], l = c.startSample + c.durationSamples;
|
|
259
|
+
s = Math.max(s, l - a.startSample);
|
|
260
260
|
}
|
|
261
261
|
s = Math.min(s, a.durationSamples - r);
|
|
262
|
-
} else if (s = Math.max(s, r - a.durationSamples), s = Math.min(s, a.sourceDurationSamples - a.offsetSamples - a.durationSamples),
|
|
263
|
-
const c = n
|
|
262
|
+
} else if (s = Math.max(s, r - a.durationSamples), s = Math.min(s, a.sourceDurationSamples - a.offsetSamples - a.durationSamples), n < i.length - 1) {
|
|
263
|
+
const c = i[n + 1];
|
|
264
264
|
s = Math.min(s, c.startSample - a.startSample - a.durationSamples);
|
|
265
265
|
}
|
|
266
266
|
return s;
|
|
@@ -269,21 +269,21 @@ function pr(a, t) {
|
|
|
269
269
|
return Math.floor(a / t) * t;
|
|
270
270
|
}
|
|
271
271
|
function re(a, t) {
|
|
272
|
-
const e = t - a.startSample,
|
|
272
|
+
const e = t - a.startSample, i = a.durationSamples - e, n = a.name ? `${a.name} (1)` : void 0, r = a.name ? `${a.name} (2)` : void 0, s = et({
|
|
273
273
|
startSample: a.startSample,
|
|
274
274
|
durationSamples: e,
|
|
275
275
|
offsetSamples: a.offsetSamples,
|
|
276
276
|
sampleRate: a.sampleRate,
|
|
277
277
|
sourceDurationSamples: a.sourceDurationSamples,
|
|
278
278
|
gain: a.gain,
|
|
279
|
-
name:
|
|
279
|
+
name: n,
|
|
280
280
|
color: a.color,
|
|
281
281
|
fadeIn: a.fadeIn,
|
|
282
282
|
audioBuffer: a.audioBuffer,
|
|
283
283
|
waveformData: a.waveformData
|
|
284
284
|
}), c = et({
|
|
285
285
|
startSample: t,
|
|
286
|
-
durationSamples:
|
|
286
|
+
durationSamples: i,
|
|
287
287
|
offsetSamples: a.offsetSamples + e,
|
|
288
288
|
sampleRate: a.sampleRate,
|
|
289
289
|
sourceDurationSamples: a.sourceDurationSamples,
|
|
@@ -297,24 +297,24 @@ function re(a, t) {
|
|
|
297
297
|
return { left: s, right: c };
|
|
298
298
|
}
|
|
299
299
|
function ne(a, t, e) {
|
|
300
|
-
const
|
|
301
|
-
if (t <= a.startSample || t >=
|
|
300
|
+
const i = a.startSample + a.durationSamples;
|
|
301
|
+
if (t <= a.startSample || t >= i)
|
|
302
302
|
return !1;
|
|
303
|
-
const
|
|
304
|
-
return
|
|
303
|
+
const n = t - a.startSample, r = i - t;
|
|
304
|
+
return n >= e && r >= e;
|
|
305
305
|
}
|
|
306
306
|
function gr(a, t, e = 1.5) {
|
|
307
|
-
const
|
|
307
|
+
const i = t * e;
|
|
308
308
|
return {
|
|
309
|
-
visibleStart: Math.max(0, a -
|
|
310
|
-
visibleEnd: a + t +
|
|
309
|
+
visibleStart: Math.max(0, a - i),
|
|
310
|
+
visibleEnd: a + t + i
|
|
311
311
|
};
|
|
312
312
|
}
|
|
313
|
-
function yr(a, t, e,
|
|
314
|
-
const
|
|
315
|
-
for (let s = 0; s <
|
|
316
|
-
const c = s * t,
|
|
317
|
-
c +
|
|
313
|
+
function yr(a, t, e, i) {
|
|
314
|
+
const n = Math.ceil(a / t), r = [];
|
|
315
|
+
for (let s = 0; s < n; s++) {
|
|
316
|
+
const c = s * t, l = Math.min(a - c, t);
|
|
317
|
+
c + l <= e || c >= i || r.push(s);
|
|
318
318
|
}
|
|
319
319
|
return r;
|
|
320
320
|
}
|
|
@@ -324,24 +324,24 @@ function vr(a, t, e = 100) {
|
|
|
324
324
|
function K(a) {
|
|
325
325
|
let t = 0;
|
|
326
326
|
for (const e of a)
|
|
327
|
-
for (const
|
|
328
|
-
const r = (
|
|
327
|
+
for (const i of e.clips) {
|
|
328
|
+
const r = (i.startSample + i.durationSamples) / i.sampleRate;
|
|
329
329
|
t = Math.max(t, r);
|
|
330
330
|
}
|
|
331
331
|
return t;
|
|
332
332
|
}
|
|
333
333
|
function ae(a, t) {
|
|
334
334
|
if (t.length === 0) return 0;
|
|
335
|
-
let e = 0,
|
|
336
|
-
for (let
|
|
337
|
-
const r = Math.abs(t[
|
|
338
|
-
r <
|
|
335
|
+
let e = 0, i = Math.abs(t[0] - a);
|
|
336
|
+
for (let n = 1; n < t.length; n++) {
|
|
337
|
+
const r = Math.abs(t[n] - a);
|
|
338
|
+
r < i && (i = r, e = n);
|
|
339
339
|
}
|
|
340
340
|
return e;
|
|
341
341
|
}
|
|
342
|
-
function br(a, t, e,
|
|
343
|
-
const
|
|
344
|
-
return Math.max(0,
|
|
342
|
+
function br(a, t, e, i, n, r = 0) {
|
|
343
|
+
const u = (e + i / 2 - r) * a / n * n / t + r - i / 2;
|
|
344
|
+
return Math.max(0, u);
|
|
345
345
|
}
|
|
346
346
|
function pt(a, t) {
|
|
347
347
|
return Math.max(0, Math.min(a, t));
|
|
@@ -351,12 +351,12 @@ class ce {
|
|
|
351
351
|
constructor(t = {}) {
|
|
352
352
|
if (this._tracks = [], this._currentTime = 0, this._playStartPosition = 0, this._isPlaying = !1, this._selectedTrackId = null, this._selectionStart = 0, this._selectionEnd = 0, this._masterVolume = 1, this._loopStart = 0, this._loopEnd = 0, this._isLoopEnabled = !1, this._tracksVersion = 0, this._animFrameId = null, this._disposed = !1, this._listeners = /* @__PURE__ */ new Map(), this._sampleRate = t.sampleRate ?? ie, this._zoomLevels = [...t.zoomLevels ?? oe], this._adapter = t.adapter ?? null, this._zoomLevels.length === 0)
|
|
353
353
|
throw new Error("PlaylistEngine: zoomLevels must not be empty");
|
|
354
|
-
const e = t.samplesPerPixel ?? se,
|
|
355
|
-
if (
|
|
354
|
+
const e = t.samplesPerPixel ?? se, i = this._zoomLevels.indexOf(e);
|
|
355
|
+
if (i === -1)
|
|
356
356
|
throw new Error(
|
|
357
357
|
`PlaylistEngine: samplesPerPixel ${e} is not in zoomLevels [${this._zoomLevels.join(", ")}]. Either pass a samplesPerPixel value that exists in zoomLevels, or include ${e} in your zoomLevels array.`
|
|
358
358
|
);
|
|
359
|
-
this._zoomIndex =
|
|
359
|
+
this._zoomIndex = i;
|
|
360
360
|
}
|
|
361
361
|
// ---------------------------------------------------------------------------
|
|
362
362
|
// State snapshot
|
|
@@ -400,59 +400,59 @@ class ce {
|
|
|
400
400
|
// ---------------------------------------------------------------------------
|
|
401
401
|
// Clip Editing (delegates to operations/)
|
|
402
402
|
// ---------------------------------------------------------------------------
|
|
403
|
-
moveClip(t, e,
|
|
404
|
-
const
|
|
405
|
-
if (!
|
|
403
|
+
moveClip(t, e, i) {
|
|
404
|
+
const n = this._tracks.find((o) => o.id === t);
|
|
405
|
+
if (!n) {
|
|
406
406
|
console.warn(`[songram-daw/engine] moveClip: track "${t}" not found`);
|
|
407
407
|
return;
|
|
408
408
|
}
|
|
409
|
-
const r =
|
|
409
|
+
const r = n.clips.findIndex((o) => o.id === e);
|
|
410
410
|
if (r === -1) {
|
|
411
411
|
console.warn(
|
|
412
412
|
`[songram-daw/engine] moveClip: clip "${e}" not found in track "${t}"`
|
|
413
413
|
);
|
|
414
414
|
return;
|
|
415
415
|
}
|
|
416
|
-
const s =
|
|
417
|
-
|
|
416
|
+
const s = n.clips[r], c = rt(n.clips), l = c.findIndex((o) => o.id === e), u = te(s, i, c, l);
|
|
417
|
+
u !== 0 && (this._tracks = this._tracks.map((o) => {
|
|
418
418
|
if (o.id !== t) return o;
|
|
419
419
|
const h = o.clips.map(
|
|
420
420
|
(f, d) => d === r ? {
|
|
421
421
|
...f,
|
|
422
|
-
startSample: Math.floor(f.startSample +
|
|
422
|
+
startSample: Math.floor(f.startSample + u)
|
|
423
423
|
} : f
|
|
424
424
|
);
|
|
425
425
|
return { ...o, clips: h };
|
|
426
426
|
}), this._tracksVersion++, this._adapter?.setTracks(this._tracks), this._emitStateChange());
|
|
427
427
|
}
|
|
428
|
-
splitClip(t, e,
|
|
429
|
-
const
|
|
430
|
-
if (!
|
|
428
|
+
splitClip(t, e, i) {
|
|
429
|
+
const n = this._tracks.find((o) => o.id === t);
|
|
430
|
+
if (!n) {
|
|
431
431
|
console.warn(`[songram-daw/engine] splitClip: track "${t}" not found`);
|
|
432
432
|
return;
|
|
433
433
|
}
|
|
434
|
-
const r =
|
|
434
|
+
const r = n.clips.findIndex((o) => o.id === e);
|
|
435
435
|
if (r === -1) {
|
|
436
436
|
console.warn(
|
|
437
437
|
`[songram-daw/engine] splitClip: clip "${e}" not found in track "${t}"`
|
|
438
438
|
);
|
|
439
439
|
return;
|
|
440
440
|
}
|
|
441
|
-
const s =
|
|
442
|
-
if (!ne(s,
|
|
441
|
+
const s = n.clips[r], c = Math.floor(gt * this._sampleRate);
|
|
442
|
+
if (!ne(s, i, c)) {
|
|
443
443
|
console.warn(
|
|
444
|
-
`[songram-daw/engine] splitClip: cannot split clip "${e}" at sample ${
|
|
444
|
+
`[songram-daw/engine] splitClip: cannot split clip "${e}" at sample ${i} (clip range: ${s.startSample}–${s.startSample + s.durationSamples}, minDuration: ${c})`
|
|
445
445
|
);
|
|
446
446
|
return;
|
|
447
447
|
}
|
|
448
|
-
const { left:
|
|
448
|
+
const { left: l, right: u } = re(s, i);
|
|
449
449
|
this._tracks = this._tracks.map((o) => {
|
|
450
450
|
if (o.id !== t) return o;
|
|
451
451
|
const h = [...o.clips];
|
|
452
|
-
return h.splice(r, 1,
|
|
452
|
+
return h.splice(r, 1, l, u), { ...o, clips: h };
|
|
453
453
|
}), this._tracksVersion++, this._adapter?.setTracks(this._tracks), this._emitStateChange();
|
|
454
454
|
}
|
|
455
|
-
trimClip(t, e,
|
|
455
|
+
trimClip(t, e, i, n) {
|
|
456
456
|
const r = this._tracks.find((f) => f.id === t);
|
|
457
457
|
if (!r) {
|
|
458
458
|
console.warn(`[songram-daw/engine] trimClip: track "${t}" not found`);
|
|
@@ -465,17 +465,17 @@ class ce {
|
|
|
465
465
|
);
|
|
466
466
|
return;
|
|
467
467
|
}
|
|
468
|
-
const c = r.clips[s],
|
|
468
|
+
const c = r.clips[s], l = rt(r.clips), u = l.findIndex((f) => f.id === e), o = Math.floor(gt * this._sampleRate), h = ee(
|
|
469
469
|
c,
|
|
470
|
-
i,
|
|
471
470
|
n,
|
|
472
|
-
|
|
471
|
+
i,
|
|
473
472
|
l,
|
|
473
|
+
u,
|
|
474
474
|
o
|
|
475
475
|
);
|
|
476
476
|
h !== 0 && (this._tracks = this._tracks.map((f) => {
|
|
477
477
|
if (f.id !== t) return f;
|
|
478
|
-
const d = f.clips.map((g, b) => b !== s ? g :
|
|
478
|
+
const d = f.clips.map((g, b) => b !== s ? g : i === "left" ? {
|
|
479
479
|
...g,
|
|
480
480
|
startSample: g.startSample + h,
|
|
481
481
|
offsetSamples: g.offsetSamples + h,
|
|
@@ -491,7 +491,7 @@ class ce {
|
|
|
491
491
|
this._adapter && await this._adapter.init();
|
|
492
492
|
}
|
|
493
493
|
play(t, e) {
|
|
494
|
-
const
|
|
494
|
+
const i = this._currentTime, n = this._playStartPosition;
|
|
495
495
|
if (t !== void 0) {
|
|
496
496
|
const r = K(this._tracks);
|
|
497
497
|
this._currentTime = pt(t, r);
|
|
@@ -506,7 +506,7 @@ class ce {
|
|
|
506
506
|
try {
|
|
507
507
|
this._adapter.play(this._currentTime, e);
|
|
508
508
|
} catch (r) {
|
|
509
|
-
throw this._currentTime =
|
|
509
|
+
throw this._currentTime = i, this._playStartPosition = n, r;
|
|
510
510
|
}
|
|
511
511
|
}
|
|
512
512
|
this._isPlaying = !0, this._startTimeUpdateLoop(), this._emit("play"), this._emitStateChange();
|
|
@@ -531,12 +531,12 @@ class ce {
|
|
|
531
531
|
// Selection & Loop
|
|
532
532
|
// ---------------------------------------------------------------------------
|
|
533
533
|
setSelection(t, e) {
|
|
534
|
-
const
|
|
535
|
-
|
|
534
|
+
const i = Math.min(t, e), n = Math.max(t, e);
|
|
535
|
+
i === this._selectionStart && n === this._selectionEnd || (this._selectionStart = i, this._selectionEnd = n, this._emitStateChange());
|
|
536
536
|
}
|
|
537
537
|
setLoopRegion(t, e) {
|
|
538
|
-
const
|
|
539
|
-
|
|
538
|
+
const i = Math.min(t, e), n = Math.max(t, e);
|
|
539
|
+
i === this._loopStart && n === this._loopEnd || (this._loopStart = i, this._loopEnd = n, this._adapter?.setLoop(
|
|
540
540
|
this._isLoopEnabled && this._isBeforeLoopEnd(),
|
|
541
541
|
this._loopStart,
|
|
542
542
|
this._loopEnd
|
|
@@ -549,20 +549,20 @@ class ce {
|
|
|
549
549
|
// Per-Track Audio (delegates to adapter)
|
|
550
550
|
// ---------------------------------------------------------------------------
|
|
551
551
|
setTrackVolume(t, e) {
|
|
552
|
-
const
|
|
553
|
-
|
|
552
|
+
const i = this._tracks.find((n) => n.id === t);
|
|
553
|
+
i && (i.volume = e), this._adapter?.setTrackVolume(t, e);
|
|
554
554
|
}
|
|
555
555
|
setTrackMute(t, e) {
|
|
556
|
-
const
|
|
557
|
-
|
|
556
|
+
const i = this._tracks.find((n) => n.id === t);
|
|
557
|
+
i && (i.muted = e), this._adapter?.setTrackMute(t, e);
|
|
558
558
|
}
|
|
559
559
|
setTrackSolo(t, e) {
|
|
560
|
-
const
|
|
561
|
-
|
|
560
|
+
const i = this._tracks.find((n) => n.id === t);
|
|
561
|
+
i && (i.soloed = e), this._adapter?.setTrackSolo(t, e);
|
|
562
562
|
}
|
|
563
563
|
setTrackPan(t, e) {
|
|
564
|
-
const
|
|
565
|
-
|
|
564
|
+
const i = this._tracks.find((n) => n.id === t);
|
|
565
|
+
i && (i.pan = e), this._adapter?.setTrackPan(t, e);
|
|
566
566
|
}
|
|
567
567
|
// ---------------------------------------------------------------------------
|
|
568
568
|
// Zoom
|
|
@@ -604,11 +604,11 @@ class ce {
|
|
|
604
604
|
// Private helpers
|
|
605
605
|
// ---------------------------------------------------------------------------
|
|
606
606
|
_emit(t, ...e) {
|
|
607
|
-
const
|
|
608
|
-
if (
|
|
609
|
-
for (const
|
|
607
|
+
const i = this._listeners.get(t);
|
|
608
|
+
if (i)
|
|
609
|
+
for (const n of i)
|
|
610
610
|
try {
|
|
611
|
-
|
|
611
|
+
n(...e);
|
|
612
612
|
} catch (r) {
|
|
613
613
|
console.warn("[songram-daw/engine] Error in event listener:", r);
|
|
614
614
|
}
|
|
@@ -647,34 +647,34 @@ function ct(a) {
|
|
|
647
647
|
)), t;
|
|
648
648
|
}
|
|
649
649
|
function vt(a, t) {
|
|
650
|
-
const e = new Float32Array(a),
|
|
651
|
-
for (let
|
|
652
|
-
const r =
|
|
653
|
-
e[
|
|
650
|
+
const e = new Float32Array(a), i = a - 1;
|
|
651
|
+
for (let n = 0; n < a; n++) {
|
|
652
|
+
const r = n / i;
|
|
653
|
+
e[n] = t ? r : 1 - r;
|
|
654
654
|
}
|
|
655
655
|
return e;
|
|
656
656
|
}
|
|
657
657
|
function ue(a, t) {
|
|
658
|
-
const e = new Float32Array(a),
|
|
659
|
-
for (let
|
|
660
|
-
const r =
|
|
658
|
+
const e = new Float32Array(a), i = a - 1;
|
|
659
|
+
for (let n = 0; n < a; n++) {
|
|
660
|
+
const r = n / i, s = t ? n : a - 1 - n;
|
|
661
661
|
e[s] = Math.exp(2 * r - 1) / Math.E;
|
|
662
662
|
}
|
|
663
663
|
return e;
|
|
664
664
|
}
|
|
665
665
|
function le(a, t) {
|
|
666
|
-
const e = new Float32Array(a),
|
|
667
|
-
for (let
|
|
668
|
-
e[
|
|
666
|
+
const e = new Float32Array(a), i = t ? Math.PI / 2 : -Math.PI / 2;
|
|
667
|
+
for (let n = 0; n < a; n++)
|
|
668
|
+
e[n] = Math.sin(Math.PI * n / a - i) / 2 + 0.5;
|
|
669
669
|
return e;
|
|
670
670
|
}
|
|
671
671
|
function he(a, t, e = 10) {
|
|
672
|
-
const
|
|
673
|
-
for (let
|
|
674
|
-
const r = t ?
|
|
675
|
-
|
|
672
|
+
const i = new Float32Array(a);
|
|
673
|
+
for (let n = 0; n < a; n++) {
|
|
674
|
+
const r = t ? n : a - 1 - n, s = n / a;
|
|
675
|
+
i[r] = Math.log(1 + e * s) / Math.log(1 + e);
|
|
676
676
|
}
|
|
677
|
-
return
|
|
677
|
+
return i;
|
|
678
678
|
}
|
|
679
679
|
function Rt(a, t, e) {
|
|
680
680
|
switch (a) {
|
|
@@ -690,29 +690,29 @@ function Rt(a, t, e) {
|
|
|
690
690
|
return vt(t, e);
|
|
691
691
|
}
|
|
692
692
|
}
|
|
693
|
-
function bt(a, t, e,
|
|
693
|
+
function bt(a, t, e, i = "linear", n = 0, r = 1) {
|
|
694
694
|
if (!(e <= 0))
|
|
695
|
-
if (
|
|
696
|
-
a.setValueAtTime(
|
|
697
|
-
else if (
|
|
698
|
-
a.setValueAtTime(Math.max(
|
|
695
|
+
if (i === "linear")
|
|
696
|
+
a.setValueAtTime(n, t), a.linearRampToValueAtTime(r, t + e);
|
|
697
|
+
else if (i === "exponential")
|
|
698
|
+
a.setValueAtTime(Math.max(n, 1e-3), t), a.exponentialRampToValueAtTime(Math.max(r, 1e-3), t + e);
|
|
699
699
|
else {
|
|
700
|
-
const s = Rt(
|
|
701
|
-
for (let
|
|
702
|
-
c[
|
|
700
|
+
const s = Rt(i, 1e4, !0), c = new Float32Array(s.length), l = r - n;
|
|
701
|
+
for (let u = 0; u < s.length; u++)
|
|
702
|
+
c[u] = n + s[u] * l;
|
|
703
703
|
a.setValueCurveAtTime(c, t, e);
|
|
704
704
|
}
|
|
705
705
|
}
|
|
706
|
-
function kt(a, t, e,
|
|
706
|
+
function kt(a, t, e, i = "linear", n = 1, r = 0) {
|
|
707
707
|
if (!(e <= 0))
|
|
708
|
-
if (
|
|
709
|
-
a.setValueAtTime(
|
|
710
|
-
else if (
|
|
711
|
-
a.setValueAtTime(Math.max(
|
|
708
|
+
if (i === "linear")
|
|
709
|
+
a.setValueAtTime(n, t), a.linearRampToValueAtTime(r, t + e);
|
|
710
|
+
else if (i === "exponential")
|
|
711
|
+
a.setValueAtTime(Math.max(n, 1e-3), t), a.exponentialRampToValueAtTime(Math.max(r, 1e-3), t + e);
|
|
712
712
|
else {
|
|
713
|
-
const s = Rt(
|
|
714
|
-
for (let
|
|
715
|
-
c[
|
|
713
|
+
const s = Rt(i, 1e4, !1), c = new Float32Array(s.length), l = n - r;
|
|
714
|
+
for (let u = 0; u < s.length; u++)
|
|
715
|
+
c[u] = r + s[u] * l;
|
|
716
716
|
a.setValueCurveAtTime(c, t, e);
|
|
717
717
|
}
|
|
718
718
|
}
|
|
@@ -725,7 +725,7 @@ class de {
|
|
|
725
725
|
c && (this.effectsCleanup = c);
|
|
726
726
|
} else
|
|
727
727
|
this.muteGain.connect(e);
|
|
728
|
-
const
|
|
728
|
+
const i = t.clips || (t.buffer ? [
|
|
729
729
|
{
|
|
730
730
|
buffer: t.buffer,
|
|
731
731
|
startTime: 0,
|
|
@@ -735,29 +735,29 @@ class de {
|
|
|
735
735
|
fadeOut: t.track.fadeOut,
|
|
736
736
|
gain: 1
|
|
737
737
|
}
|
|
738
|
-
] : []),
|
|
739
|
-
this.scheduledClips =
|
|
740
|
-
const
|
|
741
|
-
|
|
742
|
-
const
|
|
743
|
-
|
|
744
|
-
},
|
|
745
|
-
return { clipInfo: c, fadeGainNode:
|
|
738
|
+
] : []), n = I(), r = F().rawContext, s = this.volumeNode.input.input;
|
|
739
|
+
this.scheduledClips = i.map((c) => {
|
|
740
|
+
const l = r.createGain();
|
|
741
|
+
l.gain.value = c.gain, l.connect(s);
|
|
742
|
+
const u = this.track.startTime + c.startTime, o = n.schedule((h) => {
|
|
743
|
+
u < this._scheduleGuardOffset || this.startClipSource(c, l, h);
|
|
744
|
+
}, u);
|
|
745
|
+
return { clipInfo: c, fadeGainNode: l, scheduleId: o };
|
|
746
746
|
});
|
|
747
747
|
}
|
|
748
748
|
/**
|
|
749
749
|
* Create and start an AudioBufferSourceNode for a clip.
|
|
750
750
|
* Sources are one-shot: each play or loop iteration creates a fresh one.
|
|
751
751
|
*/
|
|
752
|
-
startClipSource(t, e,
|
|
752
|
+
startClipSource(t, e, i, n, r) {
|
|
753
753
|
const c = F().rawContext.createBufferSource();
|
|
754
754
|
c.buffer = t.buffer, c.connect(e);
|
|
755
|
-
const
|
|
755
|
+
const l = n ?? t.offset, u = r ?? t.duration;
|
|
756
756
|
try {
|
|
757
|
-
c.start(
|
|
757
|
+
c.start(i, l, u);
|
|
758
758
|
} catch (o) {
|
|
759
759
|
console.warn(
|
|
760
|
-
`[songram-daw] Failed to start source on track "${this.id}" (time=${
|
|
760
|
+
`[songram-daw] Failed to start source on track "${this.id}" (time=${i}, offset=${l}, duration=${u}):`,
|
|
761
761
|
o
|
|
762
762
|
), c.disconnect();
|
|
763
763
|
return;
|
|
@@ -783,16 +783,16 @@ class de {
|
|
|
783
783
|
* schedule callbacks at exact Transport position (e.g., loopStart).
|
|
784
784
|
*/
|
|
785
785
|
startMidClipSources(t, e) {
|
|
786
|
-
for (const { clipInfo:
|
|
787
|
-
const r = this.track.startTime +
|
|
786
|
+
for (const { clipInfo: i, fadeGainNode: n } of this.scheduledClips) {
|
|
787
|
+
const r = this.track.startTime + i.startTime, s = r + i.duration;
|
|
788
788
|
if (r < t && s > t) {
|
|
789
|
-
const c = t - r,
|
|
789
|
+
const c = t - r, l = i.offset + c, u = i.duration - c;
|
|
790
790
|
this.startClipSource(
|
|
791
|
-
n,
|
|
792
791
|
i,
|
|
792
|
+
n,
|
|
793
793
|
e,
|
|
794
|
-
|
|
795
|
-
|
|
794
|
+
l,
|
|
795
|
+
u
|
|
796
796
|
);
|
|
797
797
|
}
|
|
798
798
|
}
|
|
@@ -815,53 +815,53 @@ class de {
|
|
|
815
815
|
* Schedule fade envelopes for a clip at the given AudioContext time.
|
|
816
816
|
* Uses native GainNode.gain (AudioParam) directly — no _param workaround needed.
|
|
817
817
|
*/
|
|
818
|
-
scheduleFades(t, e,
|
|
819
|
-
const { clipInfo:
|
|
818
|
+
scheduleFades(t, e, i = 0) {
|
|
819
|
+
const { clipInfo: n, fadeGainNode: r } = t, s = r.gain;
|
|
820
820
|
s.cancelScheduledValues(0);
|
|
821
|
-
const c =
|
|
822
|
-
if (
|
|
823
|
-
const
|
|
821
|
+
const c = i - n.offset;
|
|
822
|
+
if (n.fadeIn && c < n.fadeIn.duration) {
|
|
823
|
+
const l = n.fadeIn.duration;
|
|
824
824
|
if (c <= 0)
|
|
825
825
|
bt(
|
|
826
826
|
s,
|
|
827
827
|
e,
|
|
828
|
-
|
|
829
|
-
|
|
828
|
+
l,
|
|
829
|
+
n.fadeIn.type || "linear",
|
|
830
830
|
0,
|
|
831
|
-
|
|
831
|
+
n.gain
|
|
832
832
|
);
|
|
833
833
|
else {
|
|
834
|
-
const
|
|
834
|
+
const u = l - c, o = c / l, h = n.gain * o;
|
|
835
835
|
bt(
|
|
836
836
|
s,
|
|
837
837
|
e,
|
|
838
|
-
|
|
839
|
-
|
|
838
|
+
u,
|
|
839
|
+
n.fadeIn.type || "linear",
|
|
840
840
|
h,
|
|
841
|
-
|
|
841
|
+
n.gain
|
|
842
842
|
);
|
|
843
843
|
}
|
|
844
844
|
} else
|
|
845
|
-
s.setValueAtTime(
|
|
846
|
-
if (
|
|
847
|
-
const
|
|
848
|
-
if (
|
|
849
|
-
const o = e +
|
|
845
|
+
s.setValueAtTime(n.gain, e);
|
|
846
|
+
if (n.fadeOut) {
|
|
847
|
+
const u = n.duration - n.fadeOut.duration - c;
|
|
848
|
+
if (u > 0) {
|
|
849
|
+
const o = e + u;
|
|
850
850
|
kt(
|
|
851
851
|
s,
|
|
852
852
|
o,
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
853
|
+
n.fadeOut.duration,
|
|
854
|
+
n.fadeOut.type || "linear",
|
|
855
|
+
n.gain,
|
|
856
856
|
0
|
|
857
857
|
);
|
|
858
|
-
} else if (
|
|
859
|
-
const o = -
|
|
858
|
+
} else if (u > -n.fadeOut.duration) {
|
|
859
|
+
const o = -u, h = n.fadeOut.duration - o, f = o / n.fadeOut.duration, d = n.gain * (1 - f);
|
|
860
860
|
kt(
|
|
861
861
|
s,
|
|
862
862
|
e,
|
|
863
863
|
h,
|
|
864
|
-
|
|
864
|
+
n.fadeOut.type || "linear",
|
|
865
865
|
d,
|
|
866
866
|
0
|
|
867
867
|
);
|
|
@@ -873,15 +873,15 @@ class de {
|
|
|
873
873
|
* Called before Transport.start() to schedule fades at correct AudioContext times.
|
|
874
874
|
*/
|
|
875
875
|
prepareFades(t, e) {
|
|
876
|
-
this.scheduledClips.forEach((
|
|
877
|
-
const
|
|
876
|
+
this.scheduledClips.forEach((i) => {
|
|
877
|
+
const n = this.track.startTime + i.clipInfo.startTime, r = n + i.clipInfo.duration;
|
|
878
878
|
if (!(e >= r))
|
|
879
|
-
if (e >=
|
|
880
|
-
const s = e -
|
|
881
|
-
this.scheduleFades(
|
|
879
|
+
if (e >= n) {
|
|
880
|
+
const s = e - n + i.clipInfo.offset;
|
|
881
|
+
this.scheduleFades(i, t, s);
|
|
882
882
|
} else {
|
|
883
|
-
const s =
|
|
884
|
-
this.scheduleFades(
|
|
883
|
+
const s = n - e;
|
|
884
|
+
this.scheduleFades(i, t + s, i.clipInfo.offset);
|
|
885
885
|
}
|
|
886
886
|
});
|
|
887
887
|
}
|
|
@@ -891,8 +891,8 @@ class de {
|
|
|
891
891
|
*/
|
|
892
892
|
cancelFades() {
|
|
893
893
|
this.scheduledClips.forEach(({ fadeGainNode: t, clipInfo: e }) => {
|
|
894
|
-
const
|
|
895
|
-
|
|
894
|
+
const i = t.gain;
|
|
895
|
+
i.cancelScheduledValues(0), i.setValueAtTime(e.gain, 0);
|
|
896
896
|
});
|
|
897
897
|
}
|
|
898
898
|
gainToDb(t) {
|
|
@@ -920,21 +920,21 @@ class de {
|
|
|
920
920
|
} catch (e) {
|
|
921
921
|
console.warn(`[songram-daw] Error during track "${this.id}" effects cleanup:`, e);
|
|
922
922
|
}
|
|
923
|
-
this.stopAllSources(), this.scheduledClips.forEach((e,
|
|
923
|
+
this.stopAllSources(), this.scheduledClips.forEach((e, i) => {
|
|
924
924
|
try {
|
|
925
925
|
t.clear(e.scheduleId);
|
|
926
|
-
} catch (
|
|
926
|
+
} catch (n) {
|
|
927
927
|
console.warn(
|
|
928
|
-
`[songram-daw] Error clearing schedule ${
|
|
929
|
-
|
|
928
|
+
`[songram-daw] Error clearing schedule ${i} on track "${this.id}":`,
|
|
929
|
+
n
|
|
930
930
|
);
|
|
931
931
|
}
|
|
932
932
|
try {
|
|
933
933
|
e.fadeGainNode.disconnect();
|
|
934
|
-
} catch (
|
|
934
|
+
} catch (n) {
|
|
935
935
|
console.warn(
|
|
936
|
-
`[songram-daw] Error disconnecting fadeGain ${
|
|
937
|
-
|
|
936
|
+
`[songram-daw] Error disconnecting fadeGain ${i} on track "${this.id}":`,
|
|
937
|
+
n
|
|
938
938
|
);
|
|
939
939
|
}
|
|
940
940
|
});
|
|
@@ -977,7 +977,9 @@ function fe(a) {
|
|
|
977
977
|
}
|
|
978
978
|
class me {
|
|
979
979
|
constructor(t) {
|
|
980
|
-
this.
|
|
980
|
+
this._debugNoteCount = 0, this.track = t.track;
|
|
981
|
+
const e = t.clips.reduce((n, r) => n + r.notes.length, 0);
|
|
982
|
+
console.log(`[songram-daw:MidiToneTrack] Creating track "${t.track.id}" with ${t.clips.length} clips, ${e} total notes`), this.volumeNode = new W(this.gainToDb(t.track.gain)), this.panNode = new st(t.track.stereoPan), this.muteGain = new ot(t.track.muted ? 0 : 1), this.volumeNode.chain(this.panNode, this.muteGain), this.synth = new G(jt, t.synthOptions), this.synth.connect(this.volumeNode), this.kickSynth = new G($, {
|
|
981
983
|
voice: $,
|
|
982
984
|
options: {
|
|
983
985
|
pitchDecay: 0.05,
|
|
@@ -1004,64 +1006,64 @@ class me {
|
|
|
1004
1006
|
envelope: { attack: 1e-3, decay: 0.3, sustain: 0, release: 0.1 }
|
|
1005
1007
|
}
|
|
1006
1008
|
}), this.kickSynth.connect(this.volumeNode), this.snareSynth.connect(this.volumeNode), this.cymbalSynth.connect(this.volumeNode), this.tomSynth.connect(this.volumeNode);
|
|
1007
|
-
const
|
|
1009
|
+
const i = t.destination || J();
|
|
1008
1010
|
if (t.effects) {
|
|
1009
|
-
const n = t.effects(this.muteGain,
|
|
1011
|
+
const n = t.effects(this.muteGain, i, !1);
|
|
1010
1012
|
n && (this.effectsCleanup = n);
|
|
1011
1013
|
} else
|
|
1012
|
-
this.muteGain.connect(
|
|
1014
|
+
this.muteGain.connect(i);
|
|
1013
1015
|
this.scheduledClips = t.clips.map((n) => {
|
|
1014
|
-
const
|
|
1015
|
-
const
|
|
1016
|
-
return u.time < n.offset + n.duration &&
|
|
1017
|
-
}),
|
|
1018
|
-
const
|
|
1016
|
+
const r = n.notes.filter((u) => {
|
|
1017
|
+
const o = u.time + u.duration;
|
|
1018
|
+
return u.time < n.offset + n.duration && o > n.offset;
|
|
1019
|
+
}), s = this.track.startTime + n.startTime, c = r.map((u) => {
|
|
1020
|
+
const o = u.time - n.offset, h = Math.max(0, o), f = Math.min(
|
|
1019
1021
|
u.duration - Math.max(0, n.offset - u.time),
|
|
1020
|
-
n.duration -
|
|
1022
|
+
n.duration - h
|
|
1021
1023
|
);
|
|
1022
1024
|
return {
|
|
1023
|
-
time:
|
|
1025
|
+
time: s + h,
|
|
1024
1026
|
note: u.name,
|
|
1025
1027
|
midi: u.midi,
|
|
1026
|
-
duration: Math.max(0,
|
|
1028
|
+
duration: Math.max(0, f),
|
|
1027
1029
|
velocity: u.velocity,
|
|
1028
1030
|
channel: u.channel
|
|
1029
1031
|
};
|
|
1030
|
-
}),
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1032
|
+
}), l = new Bt((u, o) => {
|
|
1033
|
+
o.duration > 0 && this.triggerNote(
|
|
1034
|
+
o.midi,
|
|
1035
|
+
o.note,
|
|
1036
|
+
o.duration,
|
|
1035
1037
|
u,
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
+
o.velocity,
|
|
1039
|
+
o.channel
|
|
1038
1040
|
);
|
|
1039
|
-
},
|
|
1040
|
-
return
|
|
1041
|
+
}, c);
|
|
1042
|
+
return l.start(0), { clipInfo: n, part: l };
|
|
1041
1043
|
});
|
|
1042
1044
|
}
|
|
1043
1045
|
/**
|
|
1044
1046
|
* Trigger a note using the appropriate synth.
|
|
1045
1047
|
* Routes per-note: channel 9 → percussion synths, others → melodic PolySynth.
|
|
1046
1048
|
*/
|
|
1047
|
-
triggerNote(t, e,
|
|
1048
|
-
if (s === 9)
|
|
1049
|
+
triggerNote(t, e, i, n, r, s) {
|
|
1050
|
+
if (this._debugNoteCount || (this._debugNoteCount = 0), this._debugNoteCount < 5 && (console.log(`[songram-daw:MidiToneTrack] Triggering note ${e} (MIDI ${t}), vel=${r.toFixed(2)}, dur=${i.toFixed(3)}s, ch=${s ?? "none"}`), this._debugNoteCount++), s === 9)
|
|
1049
1051
|
switch (fe(t)) {
|
|
1050
1052
|
case "kick":
|
|
1051
|
-
this.kickSynth.triggerAttackRelease("C1",
|
|
1053
|
+
this.kickSynth.triggerAttackRelease("C1", i, n, r);
|
|
1052
1054
|
break;
|
|
1053
1055
|
case "snare":
|
|
1054
1056
|
try {
|
|
1055
|
-
this.snareSynth.triggerAttackRelease(
|
|
1056
|
-
} catch (
|
|
1057
|
+
this.snareSynth.triggerAttackRelease(i, n, r);
|
|
1058
|
+
} catch (l) {
|
|
1057
1059
|
console.warn(
|
|
1058
1060
|
"[songram-daw] Snare overlap — previous hit still decaying, skipped:",
|
|
1059
|
-
|
|
1061
|
+
l
|
|
1060
1062
|
);
|
|
1061
1063
|
}
|
|
1062
1064
|
break;
|
|
1063
1065
|
case "tom": {
|
|
1064
|
-
const
|
|
1066
|
+
const l = {
|
|
1065
1067
|
41: "G1",
|
|
1066
1068
|
43: "A1",
|
|
1067
1069
|
45: "C2",
|
|
@@ -1070,19 +1072,19 @@ class me {
|
|
|
1070
1072
|
50: "G2"
|
|
1071
1073
|
};
|
|
1072
1074
|
this.tomSynth.triggerAttackRelease(
|
|
1073
|
-
|
|
1074
|
-
n,
|
|
1075
|
+
l[t] || "C2",
|
|
1075
1076
|
i,
|
|
1077
|
+
n,
|
|
1076
1078
|
r
|
|
1077
1079
|
);
|
|
1078
1080
|
break;
|
|
1079
1081
|
}
|
|
1080
1082
|
case "cymbal":
|
|
1081
|
-
this.cymbalSynth.triggerAttackRelease("C4",
|
|
1083
|
+
this.cymbalSynth.triggerAttackRelease("C4", i, n, r);
|
|
1082
1084
|
break;
|
|
1083
1085
|
}
|
|
1084
1086
|
else
|
|
1085
|
-
this.synth.triggerAttackRelease(e,
|
|
1087
|
+
this.synth.triggerAttackRelease(e, i, n, r);
|
|
1086
1088
|
}
|
|
1087
1089
|
gainToDb(t) {
|
|
1088
1090
|
return 20 * Math.log10(t);
|
|
@@ -1098,13 +1100,13 @@ class me {
|
|
|
1098
1100
|
* We trigger them with their remaining duration.
|
|
1099
1101
|
*/
|
|
1100
1102
|
startMidClipSources(t, e) {
|
|
1101
|
-
for (const { clipInfo:
|
|
1102
|
-
const
|
|
1103
|
-
if (
|
|
1104
|
-
for (const s of
|
|
1105
|
-
const c = s.time -
|
|
1106
|
-
if (
|
|
1107
|
-
const o =
|
|
1103
|
+
for (const { clipInfo: i } of this.scheduledClips) {
|
|
1104
|
+
const n = this.track.startTime + i.startTime, r = n + i.duration;
|
|
1105
|
+
if (n < t && r > t)
|
|
1106
|
+
for (const s of i.notes) {
|
|
1107
|
+
const c = s.time - i.offset, l = n + Math.max(0, c), u = l + s.duration;
|
|
1108
|
+
if (l < t && u > t) {
|
|
1109
|
+
const o = u - t;
|
|
1108
1110
|
try {
|
|
1109
1111
|
this.triggerNote(
|
|
1110
1112
|
s.midi,
|
|
@@ -1169,13 +1171,13 @@ class me {
|
|
|
1169
1171
|
e
|
|
1170
1172
|
);
|
|
1171
1173
|
}
|
|
1172
|
-
this.stopAllSources(), this.scheduledClips.forEach(({ part: e },
|
|
1174
|
+
this.stopAllSources(), this.scheduledClips.forEach(({ part: e }, i) => {
|
|
1173
1175
|
try {
|
|
1174
1176
|
e.dispose();
|
|
1175
|
-
} catch (
|
|
1177
|
+
} catch (n) {
|
|
1176
1178
|
console.warn(
|
|
1177
|
-
`[songram-daw] Error disposing Part ${
|
|
1178
|
-
|
|
1179
|
+
`[songram-daw] Error disposing Part ${i} on MIDI track "${this.id}":`,
|
|
1180
|
+
n
|
|
1179
1181
|
);
|
|
1180
1182
|
}
|
|
1181
1183
|
});
|
|
@@ -1189,8 +1191,8 @@ class me {
|
|
|
1189
1191
|
for (const e of t)
|
|
1190
1192
|
try {
|
|
1191
1193
|
e?.dispose();
|
|
1192
|
-
} catch (
|
|
1193
|
-
console.warn(`[songram-daw] Error disposing synth on MIDI track "${this.id}":`,
|
|
1194
|
+
} catch (i) {
|
|
1195
|
+
console.warn(`[songram-daw] Error disposing synth on MIDI track "${this.id}":`, i);
|
|
1194
1196
|
}
|
|
1195
1197
|
try {
|
|
1196
1198
|
this.volumeNode.dispose();
|
|
@@ -1231,31 +1233,31 @@ const L = class L {
|
|
|
1231
1233
|
this.activeSources = /* @__PURE__ */ new Set(), this.track = t.track, this.soundFontCache = t.soundFontCache, this.programNumber = t.programNumber ?? 0, this.bankNumber = t.isPercussion ? 128 : 0, this.volumeNode = new W(this.gainToDb(t.track.gain)), this.panNode = new st(t.track.stereoPan), this.muteGain = new ot(t.track.muted ? 0 : 1), this.volumeNode.chain(this.panNode, this.muteGain);
|
|
1232
1234
|
const e = t.destination || J();
|
|
1233
1235
|
if (t.effects) {
|
|
1234
|
-
const
|
|
1235
|
-
|
|
1236
|
+
const i = t.effects(this.muteGain, e, !1);
|
|
1237
|
+
i && (this.effectsCleanup = i);
|
|
1236
1238
|
} else
|
|
1237
1239
|
this.muteGain.connect(e);
|
|
1238
|
-
this.scheduledClips = t.clips.map((
|
|
1239
|
-
const
|
|
1240
|
-
const
|
|
1241
|
-
return
|
|
1242
|
-
}), r = this.track.startTime +
|
|
1243
|
-
const
|
|
1244
|
-
|
|
1245
|
-
|
|
1240
|
+
this.scheduledClips = t.clips.map((i) => {
|
|
1241
|
+
const n = i.notes.filter((l) => {
|
|
1242
|
+
const u = l.time + l.duration;
|
|
1243
|
+
return l.time < i.offset + i.duration && u > i.offset;
|
|
1244
|
+
}), r = this.track.startTime + i.startTime, s = n.map((l) => {
|
|
1245
|
+
const u = l.time - i.offset, o = Math.max(0, u), h = Math.min(
|
|
1246
|
+
l.duration - Math.max(0, i.offset - l.time),
|
|
1247
|
+
i.duration - o
|
|
1246
1248
|
);
|
|
1247
1249
|
return {
|
|
1248
1250
|
time: r + o,
|
|
1249
|
-
note:
|
|
1250
|
-
midi:
|
|
1251
|
+
note: l.name,
|
|
1252
|
+
midi: l.midi,
|
|
1251
1253
|
duration: Math.max(0, h),
|
|
1252
|
-
velocity:
|
|
1253
|
-
channel:
|
|
1254
|
+
velocity: l.velocity,
|
|
1255
|
+
channel: l.channel
|
|
1254
1256
|
};
|
|
1255
|
-
}), c = new Bt((
|
|
1256
|
-
|
|
1257
|
+
}), c = new Bt((l, u) => {
|
|
1258
|
+
u.duration > 0 && this.triggerNote(u.midi, u.duration, l, u.velocity, u.channel);
|
|
1257
1259
|
}, s);
|
|
1258
|
-
return c.start(0), { clipInfo:
|
|
1260
|
+
return c.start(0), { clipInfo: i, part: c };
|
|
1259
1261
|
});
|
|
1260
1262
|
}
|
|
1261
1263
|
/**
|
|
@@ -1263,27 +1265,27 @@ const L = class L {
|
|
|
1263
1265
|
*
|
|
1264
1266
|
* Per-note routing: channel 9 → bank 128 (drums), others → bank 0 with programNumber.
|
|
1265
1267
|
*/
|
|
1266
|
-
triggerNote(t, e,
|
|
1267
|
-
const s = r === 9 ? 128 : this.bankNumber, c = r === 9 ? 0 : this.programNumber,
|
|
1268
|
-
if (!
|
|
1268
|
+
triggerNote(t, e, i, n, r) {
|
|
1269
|
+
const s = r === 9 ? 128 : this.bankNumber, c = r === 9 ? 0 : this.programNumber, l = this.soundFontCache.getAudioBuffer(t, s, c);
|
|
1270
|
+
if (!l) {
|
|
1269
1271
|
L._missingSampleWarned || (console.warn(
|
|
1270
1272
|
`[songram-daw] SoundFont sample not found for MIDI note ${t} (bank ${s}, preset ${c}). Subsequent missing samples will be silent.`
|
|
1271
1273
|
), L._missingSampleWarned = !0);
|
|
1272
1274
|
return;
|
|
1273
1275
|
}
|
|
1274
|
-
const
|
|
1275
|
-
o.buffer =
|
|
1276
|
-
const h =
|
|
1277
|
-
g.gain.setValueAtTime(0,
|
|
1278
|
-
const S =
|
|
1279
|
-
g.gain.linearRampToValueAtTime(p, S + m), g.gain.setValueAtTime(p,
|
|
1276
|
+
const u = F().rawContext, o = u.createBufferSource();
|
|
1277
|
+
o.buffer = l.buffer, o.playbackRate.value = l.playbackRate, (l.loopMode === 1 || l.loopMode === 3) && (o.loop = !0, o.loopStart = l.loopStart, o.loopEnd = l.loopEnd);
|
|
1278
|
+
const h = l.buffer.duration / l.playbackRate, f = l.loopMode === 0 ? Math.max(e, h) : e, d = n * n, g = u.createGain(), { attackVolEnv: b, holdVolEnv: y, decayVolEnv: m, sustainVolEnv: v, releaseVolEnv: k } = l, p = d * v;
|
|
1279
|
+
g.gain.setValueAtTime(0, i), g.gain.linearRampToValueAtTime(d, i + b), y > 1e-3 && g.gain.setValueAtTime(d, i + b + y);
|
|
1280
|
+
const S = i + b + y;
|
|
1281
|
+
g.gain.linearRampToValueAtTime(p, S + m), g.gain.setValueAtTime(p, i + f), g.gain.linearRampToValueAtTime(0, i + f + k), o.connect(g), g.connect(this.volumeNode.input.input), this.activeSources.add(o), o.onended = () => {
|
|
1280
1282
|
this.activeSources.delete(o);
|
|
1281
1283
|
try {
|
|
1282
1284
|
g.disconnect();
|
|
1283
1285
|
} catch (w) {
|
|
1284
1286
|
console.warn("[songram-daw] GainNode already disconnected:", w);
|
|
1285
1287
|
}
|
|
1286
|
-
}, o.start(
|
|
1288
|
+
}, o.start(i), o.stop(i + f + k);
|
|
1287
1289
|
}
|
|
1288
1290
|
gainToDb(t) {
|
|
1289
1291
|
return 20 * Math.log10(t);
|
|
@@ -1297,13 +1299,13 @@ const L = class L {
|
|
|
1297
1299
|
* Start notes that should already be sounding at the current transport offset.
|
|
1298
1300
|
*/
|
|
1299
1301
|
startMidClipSources(t, e) {
|
|
1300
|
-
for (const { clipInfo:
|
|
1301
|
-
const
|
|
1302
|
-
if (
|
|
1303
|
-
for (const s of
|
|
1304
|
-
const c = s.time -
|
|
1305
|
-
if (
|
|
1306
|
-
const o =
|
|
1302
|
+
for (const { clipInfo: i } of this.scheduledClips) {
|
|
1303
|
+
const n = this.track.startTime + i.startTime, r = n + i.duration;
|
|
1304
|
+
if (n < t && r > t)
|
|
1305
|
+
for (const s of i.notes) {
|
|
1306
|
+
const c = s.time - i.offset, l = n + Math.max(0, c), u = l + s.duration;
|
|
1307
|
+
if (l < t && u > t) {
|
|
1308
|
+
const o = u - t;
|
|
1307
1309
|
try {
|
|
1308
1310
|
this.triggerNote(
|
|
1309
1311
|
s.midi,
|
|
@@ -1367,10 +1369,10 @@ const L = class L {
|
|
|
1367
1369
|
this.stopAllSources(), this.scheduledClips.forEach(({ part: t }, e) => {
|
|
1368
1370
|
try {
|
|
1369
1371
|
t.dispose();
|
|
1370
|
-
} catch (
|
|
1372
|
+
} catch (i) {
|
|
1371
1373
|
console.warn(
|
|
1372
1374
|
`[songram-daw] Error disposing Part ${e} on SoundFont track "${this.id}":`,
|
|
1373
|
-
|
|
1375
|
+
i
|
|
1374
1376
|
);
|
|
1375
1377
|
}
|
|
1376
1378
|
});
|
|
@@ -1447,22 +1449,22 @@ class pe {
|
|
|
1447
1449
|
const e = {
|
|
1448
1450
|
...t,
|
|
1449
1451
|
destination: this.masterVolume
|
|
1450
|
-
},
|
|
1451
|
-
return this.tracks.set(
|
|
1452
|
+
}, i = new de(e);
|
|
1453
|
+
return this.tracks.set(i.id, i), this.manualMuteState.set(i.id, t.track.muted ?? !1), t.track.soloed && this.soloedTracks.add(i.id), i;
|
|
1452
1454
|
}
|
|
1453
1455
|
addMidiTrack(t) {
|
|
1454
1456
|
const e = {
|
|
1455
1457
|
...t,
|
|
1456
1458
|
destination: this.masterVolume
|
|
1457
|
-
},
|
|
1458
|
-
return this.tracks.set(
|
|
1459
|
+
}, i = new me(e);
|
|
1460
|
+
return this.tracks.set(i.id, i), this.manualMuteState.set(i.id, t.track.muted ?? !1), t.track.soloed && this.soloedTracks.add(i.id), i;
|
|
1459
1461
|
}
|
|
1460
1462
|
addSoundFontTrack(t) {
|
|
1461
1463
|
const e = {
|
|
1462
1464
|
...t,
|
|
1463
1465
|
destination: this.masterVolume
|
|
1464
|
-
},
|
|
1465
|
-
return this.tracks.set(
|
|
1466
|
+
}, i = new nt(e);
|
|
1467
|
+
return this.tracks.set(i.id, i), this.manualMuteState.set(i.id, t.track.muted ?? !1), t.track.soloed && this.soloedTracks.add(i.id), i;
|
|
1466
1468
|
}
|
|
1467
1469
|
/**
|
|
1468
1470
|
* Apply solo muting after all tracks have been added.
|
|
@@ -1478,28 +1480,28 @@ class pe {
|
|
|
1478
1480
|
getTrack(t) {
|
|
1479
1481
|
return this.tracks.get(t);
|
|
1480
1482
|
}
|
|
1481
|
-
play(t, e,
|
|
1483
|
+
play(t, e, i) {
|
|
1482
1484
|
if (!this.isInitialized)
|
|
1483
1485
|
throw new Error("[songram-daw] TonePlayout not initialized. Call init() first.");
|
|
1484
|
-
const
|
|
1486
|
+
const n = t ?? tt(), r = I();
|
|
1485
1487
|
this.clearCompletionEvent();
|
|
1486
1488
|
const s = e ?? 0;
|
|
1487
1489
|
this.tracks.forEach((c) => {
|
|
1488
|
-
c.cancelFades(), c.prepareFades(
|
|
1489
|
-
}),
|
|
1490
|
+
c.cancelFades(), c.prepareFades(n, s);
|
|
1491
|
+
}), i !== void 0 && (this._completionEventId = r.scheduleOnce(() => {
|
|
1490
1492
|
this._completionEventId = null;
|
|
1491
1493
|
try {
|
|
1492
1494
|
this.onPlaybackCompleteCallback?.();
|
|
1493
1495
|
} catch (c) {
|
|
1494
1496
|
console.warn("[songram-daw] Error in playback completion callback:", c);
|
|
1495
1497
|
}
|
|
1496
|
-
}, s +
|
|
1498
|
+
}, s + i));
|
|
1497
1499
|
try {
|
|
1498
|
-
r.state !== "stopped" && r.stop(), this.tracks.forEach((c) => c.stopAllSources()), r.loopStart = this._loopStart, r.loopEnd = this._loopEnd, r.loop = this._loopEnabled, this.tracks.forEach((c) => c.setScheduleGuardOffset(s)), e !== void 0 ? r.start(
|
|
1499
|
-
c.startMidClipSources(s,
|
|
1500
|
+
r.state !== "stopped" && r.stop(), this.tracks.forEach((c) => c.stopAllSources()), r.loopStart = this._loopStart, r.loopEnd = this._loopEnd, r.loop = this._loopEnabled, this.tracks.forEach((c) => c.setScheduleGuardOffset(s)), e !== void 0 ? r.start(n, e) : r.start(n), r._clock._lastUpdate = n, this.tracks.forEach((c) => {
|
|
1501
|
+
c.startMidClipSources(s, n);
|
|
1500
1502
|
});
|
|
1501
1503
|
} catch (c) {
|
|
1502
|
-
throw this.clearCompletionEvent(), this.tracks.forEach((
|
|
1504
|
+
throw this.clearCompletionEvent(), this.tracks.forEach((l) => l.cancelFades()), console.warn(
|
|
1503
1505
|
"[songram-daw] Transport.start() failed. Audio playback could not begin.",
|
|
1504
1506
|
c
|
|
1505
1507
|
), c;
|
|
@@ -1532,14 +1534,14 @@ class pe {
|
|
|
1532
1534
|
this.tracks.forEach((e) => {
|
|
1533
1535
|
try {
|
|
1534
1536
|
e.stopAllSources();
|
|
1535
|
-
} catch (
|
|
1536
|
-
console.warn(`[songram-daw] Error stopping sources for track "${e.id}":`,
|
|
1537
|
+
} catch (i) {
|
|
1538
|
+
console.warn(`[songram-daw] Error stopping sources for track "${e.id}":`, i);
|
|
1537
1539
|
}
|
|
1538
1540
|
}), this.tracks.forEach((e) => {
|
|
1539
1541
|
try {
|
|
1540
1542
|
e.cancelFades();
|
|
1541
|
-
} catch (
|
|
1542
|
-
console.warn(`[songram-daw] Error canceling fades for track "${e.id}":`,
|
|
1543
|
+
} catch (i) {
|
|
1544
|
+
console.warn(`[songram-daw] Error canceling fades for track "${e.id}":`, i);
|
|
1543
1545
|
}
|
|
1544
1546
|
}), this.clearCompletionEvent();
|
|
1545
1547
|
}
|
|
@@ -1547,34 +1549,34 @@ class pe {
|
|
|
1547
1549
|
this.masterVolume.volume.value = this.gainToDb(t);
|
|
1548
1550
|
}
|
|
1549
1551
|
setSolo(t, e) {
|
|
1550
|
-
const
|
|
1551
|
-
|
|
1552
|
+
const i = this.tracks.get(t);
|
|
1553
|
+
i && (i.setSolo(e), e ? this.soloedTracks.add(t) : this.soloedTracks.delete(t), this.updateSoloMuting());
|
|
1552
1554
|
}
|
|
1553
1555
|
updateSoloMuting() {
|
|
1554
1556
|
const t = this.soloedTracks.size > 0;
|
|
1555
|
-
this.tracks.forEach((e,
|
|
1557
|
+
this.tracks.forEach((e, i) => {
|
|
1556
1558
|
if (t)
|
|
1557
|
-
if (!this.soloedTracks.has(
|
|
1559
|
+
if (!this.soloedTracks.has(i))
|
|
1558
1560
|
e.setMute(!0);
|
|
1559
1561
|
else {
|
|
1560
|
-
const
|
|
1561
|
-
e.setMute(
|
|
1562
|
+
const n = this.manualMuteState.get(i) ?? !1;
|
|
1563
|
+
e.setMute(n);
|
|
1562
1564
|
}
|
|
1563
1565
|
else {
|
|
1564
|
-
const
|
|
1565
|
-
e.setMute(
|
|
1566
|
+
const n = this.manualMuteState.get(i) ?? !1;
|
|
1567
|
+
e.setMute(n);
|
|
1566
1568
|
}
|
|
1567
1569
|
});
|
|
1568
1570
|
}
|
|
1569
1571
|
setMute(t, e) {
|
|
1570
|
-
const
|
|
1571
|
-
|
|
1572
|
+
const i = this.tracks.get(t);
|
|
1573
|
+
i && (this.manualMuteState.set(t, e), i.setMute(e));
|
|
1572
1574
|
}
|
|
1573
|
-
setLoop(t, e,
|
|
1574
|
-
this._loopEnabled = t, this._loopStart = e, this._loopEnd =
|
|
1575
|
-
const
|
|
1575
|
+
setLoop(t, e, i) {
|
|
1576
|
+
this._loopEnabled = t, this._loopStart = e, this._loopEnd = i;
|
|
1577
|
+
const n = I();
|
|
1576
1578
|
try {
|
|
1577
|
-
|
|
1579
|
+
n.loopStart = e, n.loopEnd = i, n.loop = t;
|
|
1578
1580
|
} catch (r) {
|
|
1579
1581
|
console.warn("[songram-daw] Error configuring Transport loop:", r);
|
|
1580
1582
|
return;
|
|
@@ -1591,7 +1593,7 @@ class pe {
|
|
|
1591
1593
|
);
|
|
1592
1594
|
}
|
|
1593
1595
|
});
|
|
1594
|
-
},
|
|
1596
|
+
}, n.on("loop", this._loopHandler)) : !t && this._loopHandler && (n.off("loop", this._loopHandler), this._loopHandler = null);
|
|
1595
1597
|
}
|
|
1596
1598
|
getCurrentTime() {
|
|
1597
1599
|
return I().seconds;
|
|
@@ -1647,13 +1649,13 @@ function ye(a) {
|
|
|
1647
1649
|
return t;
|
|
1648
1650
|
}
|
|
1649
1651
|
function ve(a) {
|
|
1650
|
-
const { midiNote: t, overrideRootKey: e, originalPitch:
|
|
1651
|
-
return Math.pow(2,
|
|
1652
|
+
const { midiNote: t, overrideRootKey: e, originalPitch: i, coarseTune: n, fineTune: r, pitchCorrection: s } = a, l = t - (e !== void 0 ? e : i !== 255 ? i : 60) + n + (r + s) / 100;
|
|
1653
|
+
return Math.pow(2, l / 12);
|
|
1652
1654
|
}
|
|
1653
1655
|
function be(a) {
|
|
1654
|
-
const { generators: t, header: e } = a,
|
|
1656
|
+
const { generators: t, header: e } = a, i = _(t, T.SampleModes) ?? 0, n = e.startLoop + (_(t, T.StartLoopAddrsOffset) ?? 0) + (_(t, T.StartLoopAddrsCoarseOffset) ?? 0) * 32768, r = e.endLoop + (_(t, T.EndLoopAddrsOffset) ?? 0) + (_(t, T.EndLoopAddrsCoarseOffset) ?? 0) * 32768, s = n / e.sampleRate, c = r / e.sampleRate, l = z(
|
|
1655
1657
|
_(t, T.AttackVolEnv) ?? -12e3
|
|
1656
|
-
),
|
|
1658
|
+
), u = z(
|
|
1657
1659
|
_(t, T.HoldVolEnv) ?? -12e3
|
|
1658
1660
|
), o = z(
|
|
1659
1661
|
_(t, T.DecayVolEnv) ?? -12e3
|
|
@@ -1662,11 +1664,11 @@ function be(a) {
|
|
|
1662
1664
|
ge
|
|
1663
1665
|
), f = _(t, T.SustainVolEnv) ?? 0, d = Math.pow(10, -f / 200);
|
|
1664
1666
|
return {
|
|
1665
|
-
loopMode:
|
|
1667
|
+
loopMode: i,
|
|
1666
1668
|
loopStart: s,
|
|
1667
1669
|
loopEnd: c,
|
|
1668
|
-
attackVolEnv:
|
|
1669
|
-
holdVolEnv:
|
|
1670
|
+
attackVolEnv: l,
|
|
1671
|
+
holdVolEnv: u,
|
|
1670
1672
|
decayVolEnv: o,
|
|
1671
1673
|
sustainVolEnv: d,
|
|
1672
1674
|
releaseVolEnv: h
|
|
@@ -1685,12 +1687,12 @@ class kr {
|
|
|
1685
1687
|
* Load and parse an SF2 file from a URL.
|
|
1686
1688
|
*/
|
|
1687
1689
|
async load(t, e) {
|
|
1688
|
-
const
|
|
1689
|
-
if (!
|
|
1690
|
-
throw new Error(`Failed to fetch SoundFont ${t}: ${
|
|
1691
|
-
const
|
|
1690
|
+
const i = await fetch(t, { signal: e });
|
|
1691
|
+
if (!i.ok)
|
|
1692
|
+
throw new Error(`Failed to fetch SoundFont ${t}: ${i.statusText}`);
|
|
1693
|
+
const n = await i.arrayBuffer();
|
|
1692
1694
|
try {
|
|
1693
|
-
this.sf2 = new ht(new Uint8Array(
|
|
1695
|
+
this.sf2 = new ht(new Uint8Array(n));
|
|
1694
1696
|
} catch (r) {
|
|
1695
1697
|
throw new Error(
|
|
1696
1698
|
`Failed to parse SoundFont ${t}: ${r instanceof Error ? r.message : String(r)}`
|
|
@@ -1720,33 +1722,33 @@ class kr {
|
|
|
1720
1722
|
* @param presetNumber - GM program number (0-127)
|
|
1721
1723
|
* @returns SoundFontSample or null if no sample found for this note
|
|
1722
1724
|
*/
|
|
1723
|
-
getAudioBuffer(t, e = 0,
|
|
1725
|
+
getAudioBuffer(t, e = 0, i = 0) {
|
|
1724
1726
|
if (!this.sf2) return null;
|
|
1725
|
-
const
|
|
1726
|
-
if (!
|
|
1727
|
-
const r =
|
|
1727
|
+
const n = this.sf2.getKeyData(t, e, i);
|
|
1728
|
+
if (!n) return null;
|
|
1729
|
+
const r = n.sample, s = this.sf2.samples.indexOf(r);
|
|
1728
1730
|
let c = this.audioBufferCache.get(s);
|
|
1729
1731
|
c || (c = this.int16ToAudioBuffer(r.data, r.header.sampleRate), this.audioBufferCache.set(s, c));
|
|
1730
|
-
const
|
|
1732
|
+
const l = ve({
|
|
1731
1733
|
midiNote: t,
|
|
1732
|
-
overrideRootKey: _(
|
|
1734
|
+
overrideRootKey: _(n.generators, T.OverridingRootKey),
|
|
1733
1735
|
originalPitch: r.header.originalPitch,
|
|
1734
|
-
coarseTune: _(
|
|
1735
|
-
fineTune: _(
|
|
1736
|
+
coarseTune: _(n.generators, T.CoarseTune) ?? 0,
|
|
1737
|
+
fineTune: _(n.generators, T.FineTune) ?? 0,
|
|
1736
1738
|
pitchCorrection: r.header.pitchCorrection ?? 0
|
|
1737
|
-
}),
|
|
1738
|
-
generators:
|
|
1739
|
-
header:
|
|
1739
|
+
}), u = be({
|
|
1740
|
+
generators: n.generators,
|
|
1741
|
+
header: n.sample.header
|
|
1740
1742
|
});
|
|
1741
|
-
return { buffer: c, playbackRate:
|
|
1743
|
+
return { buffer: c, playbackRate: l, ...u };
|
|
1742
1744
|
}
|
|
1743
1745
|
/**
|
|
1744
1746
|
* Convert Int16Array sample data to an AudioBuffer.
|
|
1745
1747
|
* Uses the extracted int16ToFloat32 for the conversion, then copies into an AudioBuffer.
|
|
1746
1748
|
*/
|
|
1747
1749
|
int16ToAudioBuffer(t, e) {
|
|
1748
|
-
const
|
|
1749
|
-
return
|
|
1750
|
+
const i = ye(t), n = this.context.createBuffer(1, i.length, e);
|
|
1751
|
+
return n.getChannelData(0).set(i), n;
|
|
1750
1752
|
}
|
|
1751
1753
|
/**
|
|
1752
1754
|
* Clear all cached AudioBuffers and release the parsed SF2.
|
|
@@ -1781,10 +1783,10 @@ function Ir(a) {
|
|
|
1781
1783
|
return V.get(a);
|
|
1782
1784
|
const e = F().createMediaStreamSource(a);
|
|
1783
1785
|
V.set(a, e);
|
|
1784
|
-
const
|
|
1785
|
-
e.disconnect(), V.delete(a), at.delete(a), a.removeEventListener("ended",
|
|
1786
|
+
const i = () => {
|
|
1787
|
+
e.disconnect(), V.delete(a), at.delete(a), a.removeEventListener("ended", i), a.removeEventListener("inactive", i);
|
|
1786
1788
|
};
|
|
1787
|
-
return at.set(a,
|
|
1789
|
+
return at.set(a, i), a.addEventListener("ended", i), a.addEventListener("inactive", i), e;
|
|
1788
1790
|
}
|
|
1789
1791
|
function xr(a) {
|
|
1790
1792
|
const t = at.get(a);
|
|
@@ -1794,8 +1796,8 @@ function Mr(a) {
|
|
|
1794
1796
|
return V.has(a);
|
|
1795
1797
|
}
|
|
1796
1798
|
function ke(a) {
|
|
1797
|
-
let t = null, e = !1,
|
|
1798
|
-
function
|
|
1799
|
+
let t = null, e = !1, i = 0, n = !1, r = 0, s = 0, c = !1;
|
|
1800
|
+
function l(o, h) {
|
|
1799
1801
|
const f = h.clips.filter((g) => g.audioBuffer && !g.midiNotes), d = h.clips.filter((g) => g.midiNotes && g.midiNotes.length > 0);
|
|
1800
1802
|
if (f.length > 0) {
|
|
1801
1803
|
const g = Math.min(...f.map(q)), b = Math.max(...f.map(dt)), y = {
|
|
@@ -1858,7 +1860,7 @@ function ke(a) {
|
|
|
1858
1860
|
});
|
|
1859
1861
|
}
|
|
1860
1862
|
}
|
|
1861
|
-
function
|
|
1863
|
+
function u(o) {
|
|
1862
1864
|
if (t) {
|
|
1863
1865
|
try {
|
|
1864
1866
|
t.dispose();
|
|
@@ -1867,8 +1869,8 @@ function ke(a) {
|
|
|
1867
1869
|
}
|
|
1868
1870
|
t = null;
|
|
1869
1871
|
}
|
|
1870
|
-
|
|
1871
|
-
const h =
|
|
1872
|
+
i++;
|
|
1873
|
+
const h = i;
|
|
1872
1874
|
t = new pe({
|
|
1873
1875
|
effects: a?.effects
|
|
1874
1876
|
}), c && t.init().catch((f) => {
|
|
@@ -1878,9 +1880,9 @@ function ke(a) {
|
|
|
1878
1880
|
), c = !1;
|
|
1879
1881
|
});
|
|
1880
1882
|
for (const f of o)
|
|
1881
|
-
|
|
1882
|
-
t.applyInitialSoloState(), t.setLoop(
|
|
1883
|
-
h ===
|
|
1883
|
+
l(t, f);
|
|
1884
|
+
t.applyInitialSoloState(), t.setLoop(n, r, s), t.setOnPlaybackComplete(() => {
|
|
1885
|
+
h === i && (e = !1);
|
|
1884
1886
|
});
|
|
1885
1887
|
}
|
|
1886
1888
|
return {
|
|
@@ -1888,14 +1890,14 @@ function ke(a) {
|
|
|
1888
1890
|
t && (await t.init(), c = !0);
|
|
1889
1891
|
},
|
|
1890
1892
|
setTracks(o) {
|
|
1891
|
-
|
|
1893
|
+
u(o);
|
|
1892
1894
|
},
|
|
1893
1895
|
addTrack(o) {
|
|
1894
1896
|
if (!t)
|
|
1895
1897
|
throw new Error(
|
|
1896
1898
|
"[songram-daw] adapter.addTrack() called but no playout exists. Call setTracks() first to initialize the playout."
|
|
1897
1899
|
);
|
|
1898
|
-
|
|
1900
|
+
l(t, o), t.applyInitialSoloState();
|
|
1899
1901
|
},
|
|
1900
1902
|
play(o, h) {
|
|
1901
1903
|
if (!t) {
|
|
@@ -1938,7 +1940,7 @@ function ke(a) {
|
|
|
1938
1940
|
t?.getTrack(o)?.setPan(h);
|
|
1939
1941
|
},
|
|
1940
1942
|
setLoop(o, h, f) {
|
|
1941
|
-
|
|
1943
|
+
n = o, r = h, s = f, t?.setLoop(o, h, f);
|
|
1942
1944
|
},
|
|
1943
1945
|
dispose() {
|
|
1944
1946
|
try {
|
|
@@ -1954,22 +1956,22 @@ function Se(a) {
|
|
|
1954
1956
|
if (Object.prototype.hasOwnProperty.call(a, "__esModule")) return a;
|
|
1955
1957
|
var t = a.default;
|
|
1956
1958
|
if (typeof t == "function") {
|
|
1957
|
-
var e = function
|
|
1958
|
-
var
|
|
1959
|
+
var e = function i() {
|
|
1960
|
+
var n = !1;
|
|
1959
1961
|
try {
|
|
1960
|
-
|
|
1962
|
+
n = this instanceof i;
|
|
1961
1963
|
} catch {
|
|
1962
1964
|
}
|
|
1963
|
-
return
|
|
1965
|
+
return n ? Reflect.construct(t, arguments, this.constructor) : t.apply(this, arguments);
|
|
1964
1966
|
};
|
|
1965
1967
|
e.prototype = t.prototype;
|
|
1966
1968
|
} else e = {};
|
|
1967
|
-
return Object.defineProperty(e, "__esModule", { value: !0 }), Object.keys(a).forEach(function(
|
|
1968
|
-
var
|
|
1969
|
-
Object.defineProperty(e,
|
|
1969
|
+
return Object.defineProperty(e, "__esModule", { value: !0 }), Object.keys(a).forEach(function(i) {
|
|
1970
|
+
var n = Object.getOwnPropertyDescriptor(a, i);
|
|
1971
|
+
Object.defineProperty(e, i, n.get ? n : {
|
|
1970
1972
|
enumerable: !0,
|
|
1971
1973
|
get: function() {
|
|
1972
|
-
return a[
|
|
1974
|
+
return a[i];
|
|
1973
1975
|
}
|
|
1974
1976
|
});
|
|
1975
1977
|
}), e;
|
|
@@ -1978,37 +1980,37 @@ var M = {}, H = {}, X, St;
|
|
|
1978
1980
|
function we() {
|
|
1979
1981
|
if (St) return X;
|
|
1980
1982
|
St = 1;
|
|
1981
|
-
function a(
|
|
1982
|
-
var r = new n
|
|
1983
|
+
function a(n) {
|
|
1984
|
+
var r = new i(n), s = r.readChunk();
|
|
1983
1985
|
if (s.id != "MThd")
|
|
1984
1986
|
throw "Bad MIDI file. Expected 'MHdr', got: '" + s.id + "'";
|
|
1985
|
-
for (var c = t(s.data),
|
|
1987
|
+
for (var c = t(s.data), l = [], u = 0; !r.eof() && u < c.numTracks; u++) {
|
|
1986
1988
|
var o = r.readChunk();
|
|
1987
1989
|
if (o.id != "MTrk")
|
|
1988
1990
|
throw "Bad MIDI file. Expected 'MTrk', got: '" + o.id + "'";
|
|
1989
1991
|
var h = e(o.data);
|
|
1990
|
-
|
|
1992
|
+
l.push(h);
|
|
1991
1993
|
}
|
|
1992
1994
|
return {
|
|
1993
1995
|
header: c,
|
|
1994
|
-
tracks:
|
|
1996
|
+
tracks: l
|
|
1995
1997
|
};
|
|
1996
1998
|
}
|
|
1997
|
-
function t(
|
|
1998
|
-
var r = new n
|
|
1999
|
+
function t(n) {
|
|
2000
|
+
var r = new i(n), s = r.readUInt16(), c = r.readUInt16(), l = {
|
|
1999
2001
|
format: s,
|
|
2000
2002
|
numTracks: c
|
|
2001
|
-
},
|
|
2002
|
-
return
|
|
2003
|
+
}, u = r.readUInt16();
|
|
2004
|
+
return u & 32768 ? (l.framesPerSecond = 256 - (u >> 8), l.ticksPerFrame = u & 255) : l.ticksPerBeat = u, l;
|
|
2003
2005
|
}
|
|
2004
|
-
function e(
|
|
2005
|
-
for (var r = new n
|
|
2006
|
-
var c =
|
|
2006
|
+
function e(n) {
|
|
2007
|
+
for (var r = new i(n), s = []; !r.eof(); ) {
|
|
2008
|
+
var c = u();
|
|
2007
2009
|
s.push(c);
|
|
2008
2010
|
}
|
|
2009
2011
|
return s;
|
|
2010
|
-
var
|
|
2011
|
-
function
|
|
2012
|
+
var l;
|
|
2013
|
+
function u() {
|
|
2012
2014
|
var o = {};
|
|
2013
2015
|
o.deltaTime = r.readVarInt();
|
|
2014
2016
|
var h = r.readUInt8();
|
|
@@ -2074,11 +2076,11 @@ function we() {
|
|
|
2074
2076
|
else {
|
|
2075
2077
|
var y;
|
|
2076
2078
|
if ((h & 128) === 0) {
|
|
2077
|
-
if (
|
|
2079
|
+
if (l === null)
|
|
2078
2080
|
throw "Running status byte encountered before status byte";
|
|
2079
|
-
y = h, h =
|
|
2081
|
+
y = h, h = l, o.running = !0;
|
|
2080
2082
|
} else
|
|
2081
|
-
y = r.readUInt8(),
|
|
2083
|
+
y = r.readUInt8(), l = h;
|
|
2082
2084
|
var m = h >> 4;
|
|
2083
2085
|
switch (o.channel = h & 15, m) {
|
|
2084
2086
|
case 8:
|
|
@@ -2102,51 +2104,51 @@ function we() {
|
|
|
2102
2104
|
}
|
|
2103
2105
|
}
|
|
2104
2106
|
}
|
|
2105
|
-
function n
|
|
2106
|
-
this.buffer =
|
|
2107
|
+
function i(n) {
|
|
2108
|
+
this.buffer = n, this.bufferLen = this.buffer.length, this.pos = 0;
|
|
2107
2109
|
}
|
|
2108
|
-
return
|
|
2110
|
+
return i.prototype.eof = function() {
|
|
2109
2111
|
return this.pos >= this.bufferLen;
|
|
2110
|
-
},
|
|
2111
|
-
var
|
|
2112
|
-
return this.pos += 1,
|
|
2113
|
-
},
|
|
2114
|
-
var
|
|
2115
|
-
return
|
|
2116
|
-
},
|
|
2117
|
-
var
|
|
2118
|
-
return (
|
|
2119
|
-
},
|
|
2120
|
-
var
|
|
2121
|
-
return
|
|
2122
|
-
},
|
|
2123
|
-
var
|
|
2124
|
-
return (
|
|
2125
|
-
},
|
|
2126
|
-
var
|
|
2127
|
-
return
|
|
2128
|
-
},
|
|
2129
|
-
var
|
|
2130
|
-
return (
|
|
2131
|
-
},
|
|
2132
|
-
var r = this.buffer.slice(this.pos, this.pos +
|
|
2133
|
-
return this.pos +=
|
|
2134
|
-
},
|
|
2135
|
-
var r = this.readBytes(
|
|
2112
|
+
}, i.prototype.readUInt8 = function() {
|
|
2113
|
+
var n = this.buffer[this.pos];
|
|
2114
|
+
return this.pos += 1, n;
|
|
2115
|
+
}, i.prototype.readInt8 = function() {
|
|
2116
|
+
var n = this.readUInt8();
|
|
2117
|
+
return n & 128 ? n - 256 : n;
|
|
2118
|
+
}, i.prototype.readUInt16 = function() {
|
|
2119
|
+
var n = this.readUInt8(), r = this.readUInt8();
|
|
2120
|
+
return (n << 8) + r;
|
|
2121
|
+
}, i.prototype.readInt16 = function() {
|
|
2122
|
+
var n = this.readUInt16();
|
|
2123
|
+
return n & 32768 ? n - 65536 : n;
|
|
2124
|
+
}, i.prototype.readUInt24 = function() {
|
|
2125
|
+
var n = this.readUInt8(), r = this.readUInt8(), s = this.readUInt8();
|
|
2126
|
+
return (n << 16) + (r << 8) + s;
|
|
2127
|
+
}, i.prototype.readInt24 = function() {
|
|
2128
|
+
var n = this.readUInt24();
|
|
2129
|
+
return n & 8388608 ? n - 16777216 : n;
|
|
2130
|
+
}, i.prototype.readUInt32 = function() {
|
|
2131
|
+
var n = this.readUInt8(), r = this.readUInt8(), s = this.readUInt8(), c = this.readUInt8();
|
|
2132
|
+
return (n << 24) + (r << 16) + (s << 8) + c;
|
|
2133
|
+
}, i.prototype.readBytes = function(n) {
|
|
2134
|
+
var r = this.buffer.slice(this.pos, this.pos + n);
|
|
2135
|
+
return this.pos += n, r;
|
|
2136
|
+
}, i.prototype.readString = function(n) {
|
|
2137
|
+
var r = this.readBytes(n);
|
|
2136
2138
|
return String.fromCharCode.apply(null, r);
|
|
2137
|
-
},
|
|
2138
|
-
for (var
|
|
2139
|
+
}, i.prototype.readVarInt = function() {
|
|
2140
|
+
for (var n = 0; !this.eof(); ) {
|
|
2139
2141
|
var r = this.readUInt8();
|
|
2140
2142
|
if (r & 128)
|
|
2141
|
-
|
|
2143
|
+
n += r & 127, n <<= 7;
|
|
2142
2144
|
else
|
|
2143
|
-
return
|
|
2145
|
+
return n + r;
|
|
2144
2146
|
}
|
|
2145
|
-
return
|
|
2146
|
-
},
|
|
2147
|
-
var
|
|
2147
|
+
return n;
|
|
2148
|
+
}, i.prototype.readChunk = function() {
|
|
2149
|
+
var n = this.readString(4), r = this.readUInt32(), s = this.readBytes(r);
|
|
2148
2150
|
return {
|
|
2149
|
-
id:
|
|
2151
|
+
id: n,
|
|
2150
2152
|
length: r,
|
|
2151
2153
|
data: s
|
|
2152
2154
|
};
|
|
@@ -2160,26 +2162,26 @@ function Te() {
|
|
|
2160
2162
|
if (typeof r != "object")
|
|
2161
2163
|
throw "Invalid MIDI data";
|
|
2162
2164
|
s = s || {};
|
|
2163
|
-
var c = r.header || {},
|
|
2164
|
-
for (t(h, c, o),
|
|
2165
|
-
e(h, u
|
|
2165
|
+
var c = r.header || {}, l = r.tracks || [], u, o = l.length, h = new n();
|
|
2166
|
+
for (t(h, c, o), u = 0; u < o; u++)
|
|
2167
|
+
e(h, l[u], s);
|
|
2166
2168
|
return h.buffer;
|
|
2167
2169
|
}
|
|
2168
2170
|
function t(r, s, c) {
|
|
2169
|
-
var
|
|
2170
|
-
s.timeDivision ?
|
|
2171
|
-
var o = new
|
|
2172
|
-
o.writeUInt16(
|
|
2171
|
+
var l = s.format == null ? 1 : s.format, u = 128;
|
|
2172
|
+
s.timeDivision ? u = s.timeDivision : s.ticksPerFrame && s.framesPerSecond ? u = -(s.framesPerSecond & 255) << 8 | s.ticksPerFrame & 255 : s.ticksPerBeat && (u = s.ticksPerBeat & 32767);
|
|
2173
|
+
var o = new n();
|
|
2174
|
+
o.writeUInt16(l), o.writeUInt16(c), o.writeUInt16(u), r.writeChunk("MThd", o.buffer);
|
|
2173
2175
|
}
|
|
2174
2176
|
function e(r, s, c) {
|
|
2175
|
-
var
|
|
2176
|
-
for (
|
|
2177
|
-
(c.running === !1 || !c.running && !s[
|
|
2178
|
-
r.writeChunk("MTrk",
|
|
2179
|
-
}
|
|
2180
|
-
function
|
|
2181
|
-
var
|
|
2182
|
-
switch (r.writeVarInt(o),
|
|
2177
|
+
var l = new n(), u, o = s.length, h = null;
|
|
2178
|
+
for (u = 0; u < o; u++)
|
|
2179
|
+
(c.running === !1 || !c.running && !s[u].running) && (h = null), h = i(l, s[u], h, c.useByte9ForNoteOff);
|
|
2180
|
+
r.writeChunk("MTrk", l.buffer);
|
|
2181
|
+
}
|
|
2182
|
+
function i(r, s, c, l) {
|
|
2183
|
+
var u = s.type, o = s.deltaTime, h = s.text || "", f = s.data || [], d = null;
|
|
2184
|
+
switch (r.writeVarInt(o), u) {
|
|
2183
2185
|
// meta events
|
|
2184
2186
|
case "sequenceNumber":
|
|
2185
2187
|
r.writeUInt8(255), r.writeUInt8(0), r.writeVarInt(2), r.writeUInt16(s.number);
|
|
@@ -2245,7 +2247,7 @@ function Te() {
|
|
|
2245
2247
|
break;
|
|
2246
2248
|
// channel events
|
|
2247
2249
|
case "noteOff":
|
|
2248
|
-
var m =
|
|
2250
|
+
var m = l !== !1 && s.byte9 || l && s.velocity == 0 ? 144 : 128;
|
|
2249
2251
|
d = m | s.channel, d !== c && r.writeUInt8(d), r.writeUInt8(s.noteNumber), r.writeUInt8(s.velocity);
|
|
2250
2252
|
break;
|
|
2251
2253
|
case "noteOn":
|
|
@@ -2269,44 +2271,44 @@ function Te() {
|
|
|
2269
2271
|
r.writeUInt8(k), r.writeUInt8(p);
|
|
2270
2272
|
break;
|
|
2271
2273
|
default:
|
|
2272
|
-
throw "Unrecognized event type: " +
|
|
2274
|
+
throw "Unrecognized event type: " + u;
|
|
2273
2275
|
}
|
|
2274
2276
|
return d;
|
|
2275
2277
|
}
|
|
2276
|
-
function
|
|
2278
|
+
function n() {
|
|
2277
2279
|
this.buffer = [];
|
|
2278
2280
|
}
|
|
2279
|
-
return
|
|
2281
|
+
return n.prototype.writeUInt8 = function(r) {
|
|
2280
2282
|
this.buffer.push(r & 255);
|
|
2281
|
-
},
|
|
2283
|
+
}, n.prototype.writeInt8 = n.prototype.writeUInt8, n.prototype.writeUInt16 = function(r) {
|
|
2282
2284
|
var s = r >> 8 & 255, c = r & 255;
|
|
2283
2285
|
this.writeUInt8(s), this.writeUInt8(c);
|
|
2284
|
-
},
|
|
2285
|
-
var s = r >> 16 & 255, c = r >> 8 & 255,
|
|
2286
|
-
this.writeUInt8(s), this.writeUInt8(c), this.writeUInt8(
|
|
2287
|
-
},
|
|
2288
|
-
var s = r >> 24 & 255, c = r >> 16 & 255,
|
|
2289
|
-
this.writeUInt8(s), this.writeUInt8(c), this.writeUInt8(
|
|
2290
|
-
},
|
|
2286
|
+
}, n.prototype.writeInt16 = n.prototype.writeUInt16, n.prototype.writeUInt24 = function(r) {
|
|
2287
|
+
var s = r >> 16 & 255, c = r >> 8 & 255, l = r & 255;
|
|
2288
|
+
this.writeUInt8(s), this.writeUInt8(c), this.writeUInt8(l);
|
|
2289
|
+
}, n.prototype.writeInt24 = n.prototype.writeUInt24, n.prototype.writeUInt32 = function(r) {
|
|
2290
|
+
var s = r >> 24 & 255, c = r >> 16 & 255, l = r >> 8 & 255, u = r & 255;
|
|
2291
|
+
this.writeUInt8(s), this.writeUInt8(c), this.writeUInt8(l), this.writeUInt8(u);
|
|
2292
|
+
}, n.prototype.writeInt32 = n.prototype.writeUInt32, n.prototype.writeBytes = function(r) {
|
|
2291
2293
|
this.buffer = this.buffer.concat(Array.prototype.slice.call(r, 0));
|
|
2292
|
-
},
|
|
2293
|
-
var s, c = r.length,
|
|
2294
|
+
}, n.prototype.writeString = function(r) {
|
|
2295
|
+
var s, c = r.length, l = [];
|
|
2294
2296
|
for (s = 0; s < c; s++)
|
|
2295
|
-
|
|
2296
|
-
this.writeBytes(
|
|
2297
|
-
},
|
|
2297
|
+
l.push(r.codePointAt(s));
|
|
2298
|
+
this.writeBytes(l);
|
|
2299
|
+
}, n.prototype.writeVarInt = function(r) {
|
|
2298
2300
|
if (r < 0) throw "Cannot write negative variable-length integer";
|
|
2299
2301
|
if (r <= 127)
|
|
2300
2302
|
this.writeUInt8(r);
|
|
2301
2303
|
else {
|
|
2302
2304
|
var s = r, c = [];
|
|
2303
2305
|
for (c.push(s & 127), s >>= 7; s; ) {
|
|
2304
|
-
var
|
|
2305
|
-
c.push(
|
|
2306
|
+
var l = s & 127 | 128;
|
|
2307
|
+
c.push(l), s >>= 7;
|
|
2306
2308
|
}
|
|
2307
2309
|
this.writeBytes(c.reverse());
|
|
2308
2310
|
}
|
|
2309
|
-
},
|
|
2311
|
+
}, n.prototype.writeChunk = function(r, s) {
|
|
2310
2312
|
this.writeString(r), this.writeUInt32(s.length), this.writeBytes(s);
|
|
2311
2313
|
}, Z = a, Z;
|
|
2312
2314
|
}
|
|
@@ -2318,34 +2320,34 @@ var Q = {}, E = {}, _t;
|
|
|
2318
2320
|
function $t() {
|
|
2319
2321
|
if (_t) return E;
|
|
2320
2322
|
_t = 1, Object.defineProperty(E, "__esModule", { value: !0 }), E.insert = E.search = void 0;
|
|
2321
|
-
function a(e,
|
|
2322
|
-
|
|
2323
|
+
function a(e, i, n) {
|
|
2324
|
+
n === void 0 && (n = "ticks");
|
|
2323
2325
|
var r = 0, s = e.length, c = s;
|
|
2324
|
-
if (s > 0 && e[s - 1][
|
|
2326
|
+
if (s > 0 && e[s - 1][n] <= i)
|
|
2325
2327
|
return s - 1;
|
|
2326
2328
|
for (; r < c; ) {
|
|
2327
|
-
var
|
|
2328
|
-
if (
|
|
2329
|
-
for (var h =
|
|
2329
|
+
var l = Math.floor(r + (c - r) / 2), u = e[l], o = e[l + 1];
|
|
2330
|
+
if (u[n] === i) {
|
|
2331
|
+
for (var h = l; h < e.length; h++) {
|
|
2330
2332
|
var f = e[h];
|
|
2331
|
-
f[
|
|
2333
|
+
f[n] === i && (l = h);
|
|
2332
2334
|
}
|
|
2333
|
-
return
|
|
2335
|
+
return l;
|
|
2334
2336
|
} else {
|
|
2335
|
-
if (
|
|
2336
|
-
return
|
|
2337
|
-
|
|
2337
|
+
if (u[n] < i && o[n] > i)
|
|
2338
|
+
return l;
|
|
2339
|
+
u[n] > i ? c = l : u[n] < i && (r = l + 1);
|
|
2338
2340
|
}
|
|
2339
2341
|
}
|
|
2340
2342
|
return -1;
|
|
2341
2343
|
}
|
|
2342
2344
|
E.search = a;
|
|
2343
|
-
function t(e,
|
|
2344
|
-
if (
|
|
2345
|
-
var r = a(e, n
|
|
2346
|
-
e.splice(r + 1, 0,
|
|
2345
|
+
function t(e, i, n) {
|
|
2346
|
+
if (n === void 0 && (n = "ticks"), e.length) {
|
|
2347
|
+
var r = a(e, i[n], n);
|
|
2348
|
+
e.splice(r + 1, 0, i);
|
|
2347
2349
|
} else
|
|
2348
|
-
e.push(
|
|
2350
|
+
e.push(i);
|
|
2349
2351
|
}
|
|
2350
2352
|
return E.insert = t, E;
|
|
2351
2353
|
}
|
|
@@ -2371,70 +2373,70 @@ function it() {
|
|
|
2371
2373
|
"F#",
|
|
2372
2374
|
"C#"
|
|
2373
2375
|
];
|
|
2374
|
-
var
|
|
2376
|
+
var i = (
|
|
2375
2377
|
/** @class */
|
|
2376
2378
|
(function() {
|
|
2377
|
-
function
|
|
2379
|
+
function n(r) {
|
|
2378
2380
|
var s = this;
|
|
2379
2381
|
if (this.tempos = [], this.timeSignatures = [], this.keySignatures = [], this.meta = [], this.name = "", e.set(this, 480), r) {
|
|
2380
|
-
e.set(this, r.header.ticksPerBeat), r.tracks.forEach(function(
|
|
2381
|
-
|
|
2382
|
-
|
|
2383
|
-
ticks:
|
|
2382
|
+
e.set(this, r.header.ticksPerBeat), r.tracks.forEach(function(l) {
|
|
2383
|
+
l.forEach(function(u) {
|
|
2384
|
+
u.meta && (u.type === "timeSignature" ? s.timeSignatures.push({
|
|
2385
|
+
ticks: u.absoluteTime,
|
|
2384
2386
|
timeSignature: [
|
|
2385
|
-
|
|
2386
|
-
|
|
2387
|
+
u.numerator,
|
|
2388
|
+
u.denominator
|
|
2387
2389
|
]
|
|
2388
|
-
}) :
|
|
2389
|
-
bpm: 6e7 /
|
|
2390
|
-
ticks:
|
|
2391
|
-
}) :
|
|
2392
|
-
key: a.keySignatureKeys[
|
|
2393
|
-
scale:
|
|
2394
|
-
ticks:
|
|
2390
|
+
}) : u.type === "setTempo" ? s.tempos.push({
|
|
2391
|
+
bpm: 6e7 / u.microsecondsPerBeat,
|
|
2392
|
+
ticks: u.absoluteTime
|
|
2393
|
+
}) : u.type === "keySignature" && s.keySignatures.push({
|
|
2394
|
+
key: a.keySignatureKeys[u.key + 7],
|
|
2395
|
+
scale: u.scale === 0 ? "major" : "minor",
|
|
2396
|
+
ticks: u.absoluteTime
|
|
2395
2397
|
}));
|
|
2396
2398
|
});
|
|
2397
2399
|
});
|
|
2398
2400
|
var c = 0;
|
|
2399
|
-
r.tracks[0].forEach(function(
|
|
2400
|
-
c +=
|
|
2401
|
-
text:
|
|
2401
|
+
r.tracks[0].forEach(function(l) {
|
|
2402
|
+
c += l.deltaTime, l.meta && (l.type === "trackName" ? s.name = l.text : (l.type === "text" || l.type === "cuePoint" || l.type === "marker" || l.type === "lyrics") && s.meta.push({
|
|
2403
|
+
text: l.text,
|
|
2402
2404
|
ticks: c,
|
|
2403
|
-
type:
|
|
2405
|
+
type: l.type
|
|
2404
2406
|
}));
|
|
2405
2407
|
}), this.update();
|
|
2406
2408
|
}
|
|
2407
2409
|
}
|
|
2408
|
-
return
|
|
2410
|
+
return n.prototype.update = function() {
|
|
2409
2411
|
var r = this, s = 0, c = 0;
|
|
2410
|
-
this.tempos.sort(function(
|
|
2411
|
-
return
|
|
2412
|
-
}), this.tempos.forEach(function(
|
|
2413
|
-
var o =
|
|
2414
|
-
|
|
2415
|
-
}), this.timeSignatures.sort(function(
|
|
2416
|
-
return
|
|
2417
|
-
}), this.timeSignatures.forEach(function(
|
|
2418
|
-
var o =
|
|
2419
|
-
o.measures = o.measures || 0,
|
|
2412
|
+
this.tempos.sort(function(l, u) {
|
|
2413
|
+
return l.ticks - u.ticks;
|
|
2414
|
+
}), this.tempos.forEach(function(l, u) {
|
|
2415
|
+
var o = u > 0 ? r.tempos[u - 1].bpm : r.tempos[0].bpm, h = l.ticks / r.ppq - c, f = 60 / o * h;
|
|
2416
|
+
l.time = f + s, s = l.time, c += h;
|
|
2417
|
+
}), this.timeSignatures.sort(function(l, u) {
|
|
2418
|
+
return l.ticks - u.ticks;
|
|
2419
|
+
}), this.timeSignatures.forEach(function(l, u) {
|
|
2420
|
+
var o = u > 0 ? r.timeSignatures[u - 1] : r.timeSignatures[0], h = (l.ticks - o.ticks) / r.ppq, f = h / o.timeSignature[0] / (o.timeSignature[1] / 4);
|
|
2421
|
+
o.measures = o.measures || 0, l.measures = f + o.measures;
|
|
2420
2422
|
});
|
|
2421
|
-
},
|
|
2423
|
+
}, n.prototype.ticksToSeconds = function(r) {
|
|
2422
2424
|
var s = (0, t.search)(this.tempos, r);
|
|
2423
2425
|
if (s !== -1) {
|
|
2424
|
-
var c = this.tempos[s],
|
|
2425
|
-
return
|
|
2426
|
+
var c = this.tempos[s], l = c.time, u = (r - c.ticks) / this.ppq;
|
|
2427
|
+
return l + 60 / c.bpm * u;
|
|
2426
2428
|
} else {
|
|
2427
2429
|
var o = r / this.ppq;
|
|
2428
2430
|
return 60 / 120 * o;
|
|
2429
2431
|
}
|
|
2430
|
-
},
|
|
2432
|
+
}, n.prototype.ticksToMeasures = function(r) {
|
|
2431
2433
|
var s = (0, t.search)(this.timeSignatures, r);
|
|
2432
2434
|
if (s !== -1) {
|
|
2433
|
-
var c = this.timeSignatures[s],
|
|
2434
|
-
return c.measures +
|
|
2435
|
+
var c = this.timeSignatures[s], l = (r - c.ticks) / this.ppq;
|
|
2436
|
+
return c.measures + l / (c.timeSignature[0] / c.timeSignature[1]) / 4;
|
|
2435
2437
|
} else
|
|
2436
2438
|
return r / this.ppq / 4;
|
|
2437
|
-
}, Object.defineProperty(
|
|
2439
|
+
}, Object.defineProperty(n.prototype, "ppq", {
|
|
2438
2440
|
/**
|
|
2439
2441
|
* The number of ticks per quarter note.
|
|
2440
2442
|
*/
|
|
@@ -2443,16 +2445,16 @@ function it() {
|
|
|
2443
2445
|
},
|
|
2444
2446
|
enumerable: !1,
|
|
2445
2447
|
configurable: !0
|
|
2446
|
-
}),
|
|
2448
|
+
}), n.prototype.secondsToTicks = function(r) {
|
|
2447
2449
|
var s = (0, t.search)(this.tempos, r, "time");
|
|
2448
2450
|
if (s !== -1) {
|
|
2449
|
-
var c = this.tempos[s],
|
|
2451
|
+
var c = this.tempos[s], l = c.time, u = r - l, o = u / (60 / c.bpm);
|
|
2450
2452
|
return Math.round(c.ticks + o * this.ppq);
|
|
2451
2453
|
} else {
|
|
2452
2454
|
var h = r / 0.5;
|
|
2453
2455
|
return Math.round(h * this.ppq);
|
|
2454
2456
|
}
|
|
2455
|
-
},
|
|
2457
|
+
}, n.prototype.toJSON = function() {
|
|
2456
2458
|
return {
|
|
2457
2459
|
keySignatures: this.keySignatures,
|
|
2458
2460
|
meta: this.meta,
|
|
@@ -2466,7 +2468,7 @@ function it() {
|
|
|
2466
2468
|
}),
|
|
2467
2469
|
timeSignatures: this.timeSignatures
|
|
2468
2470
|
};
|
|
2469
|
-
},
|
|
2471
|
+
}, n.prototype.fromJSON = function(r) {
|
|
2470
2472
|
this.name = r.name, this.tempos = r.tempos.map(function(s) {
|
|
2471
2473
|
return Object.assign({}, s);
|
|
2472
2474
|
}), this.timeSignatures = r.timeSignatures.map(function(s) {
|
|
@@ -2476,17 +2478,17 @@ function it() {
|
|
|
2476
2478
|
}), this.meta = r.meta.map(function(s) {
|
|
2477
2479
|
return Object.assign({}, s);
|
|
2478
2480
|
}), e.set(this, r.ppq), this.update();
|
|
2479
|
-
},
|
|
2481
|
+
}, n.prototype.setTempo = function(r) {
|
|
2480
2482
|
this.tempos = [
|
|
2481
2483
|
{
|
|
2482
2484
|
bpm: r,
|
|
2483
2485
|
ticks: 0
|
|
2484
2486
|
}
|
|
2485
2487
|
], this.update();
|
|
2486
|
-
},
|
|
2488
|
+
}, n;
|
|
2487
2489
|
})()
|
|
2488
2490
|
);
|
|
2489
|
-
a.Header =
|
|
2491
|
+
a.Header = i;
|
|
2490
2492
|
})(Q)), Q;
|
|
2491
2493
|
}
|
|
2492
2494
|
var U = {}, Y = {}, It;
|
|
@@ -2506,16 +2508,16 @@ function qt() {
|
|
|
2506
2508
|
67: "softPedal",
|
|
2507
2509
|
68: "legatoFootswitch",
|
|
2508
2510
|
84: "portamentoControl"
|
|
2509
|
-
}, a.controlChangeIds = Object.keys(a.controlChangeNames).reduce(function(
|
|
2510
|
-
return
|
|
2511
|
+
}, a.controlChangeIds = Object.keys(a.controlChangeNames).reduce(function(n, r) {
|
|
2512
|
+
return n[a.controlChangeNames[r]] = r, n;
|
|
2511
2513
|
}, {});
|
|
2512
|
-
var t = /* @__PURE__ */ new WeakMap(), e = /* @__PURE__ */ new WeakMap(),
|
|
2514
|
+
var t = /* @__PURE__ */ new WeakMap(), e = /* @__PURE__ */ new WeakMap(), i = (
|
|
2513
2515
|
/** @class */
|
|
2514
2516
|
(function() {
|
|
2515
|
-
function
|
|
2517
|
+
function n(r, s) {
|
|
2516
2518
|
t.set(this, s), e.set(this, r.controllerType), this.ticks = r.absoluteTime, this.value = r.value;
|
|
2517
2519
|
}
|
|
2518
|
-
return Object.defineProperty(
|
|
2520
|
+
return Object.defineProperty(n.prototype, "number", {
|
|
2519
2521
|
/**
|
|
2520
2522
|
* The controller number
|
|
2521
2523
|
*/
|
|
@@ -2524,7 +2526,7 @@ function qt() {
|
|
|
2524
2526
|
},
|
|
2525
2527
|
enumerable: !1,
|
|
2526
2528
|
configurable: !0
|
|
2527
|
-
}), Object.defineProperty(
|
|
2529
|
+
}), Object.defineProperty(n.prototype, "name", {
|
|
2528
2530
|
/**
|
|
2529
2531
|
* return the common name of the control number if it exists
|
|
2530
2532
|
*/
|
|
@@ -2533,7 +2535,7 @@ function qt() {
|
|
|
2533
2535
|
},
|
|
2534
2536
|
enumerable: !1,
|
|
2535
2537
|
configurable: !0
|
|
2536
|
-
}), Object.defineProperty(
|
|
2538
|
+
}), Object.defineProperty(n.prototype, "time", {
|
|
2537
2539
|
/**
|
|
2538
2540
|
* The time of the event in seconds
|
|
2539
2541
|
*/
|
|
@@ -2547,17 +2549,17 @@ function qt() {
|
|
|
2547
2549
|
},
|
|
2548
2550
|
enumerable: !1,
|
|
2549
2551
|
configurable: !0
|
|
2550
|
-
}),
|
|
2552
|
+
}), n.prototype.toJSON = function() {
|
|
2551
2553
|
return {
|
|
2552
2554
|
number: this.number,
|
|
2553
2555
|
ticks: this.ticks,
|
|
2554
2556
|
time: this.time,
|
|
2555
2557
|
value: this.value
|
|
2556
2558
|
};
|
|
2557
|
-
},
|
|
2559
|
+
}, n;
|
|
2558
2560
|
})()
|
|
2559
2561
|
);
|
|
2560
|
-
a.ControlChange =
|
|
2562
|
+
a.ControlChange = i;
|
|
2561
2563
|
})(Y)), Y;
|
|
2562
2564
|
}
|
|
2563
2565
|
var O = {}, xt;
|
|
@@ -2568,15 +2570,15 @@ function _e() {
|
|
|
2568
2570
|
function t() {
|
|
2569
2571
|
return new Proxy({}, {
|
|
2570
2572
|
// tslint:disable-next-line: typedef
|
|
2571
|
-
get: function(e,
|
|
2572
|
-
if (e[
|
|
2573
|
-
return e[
|
|
2574
|
-
if (a.controlChangeIds.hasOwnProperty(
|
|
2575
|
-
return e[a.controlChangeIds[
|
|
2573
|
+
get: function(e, i) {
|
|
2574
|
+
if (e[i])
|
|
2575
|
+
return e[i];
|
|
2576
|
+
if (a.controlChangeIds.hasOwnProperty(i))
|
|
2577
|
+
return e[a.controlChangeIds[i]];
|
|
2576
2578
|
},
|
|
2577
2579
|
// tslint:disable-next-line: typedef
|
|
2578
|
-
set: function(e,
|
|
2579
|
-
return a.controlChangeIds.hasOwnProperty(
|
|
2580
|
+
set: function(e, i, n) {
|
|
2581
|
+
return a.controlChangeIds.hasOwnProperty(i) ? e[a.controlChangeIds[i]] = n : e[i] = n, !0;
|
|
2580
2582
|
}
|
|
2581
2583
|
});
|
|
2582
2584
|
}
|
|
@@ -2589,20 +2591,20 @@ function Ce() {
|
|
|
2589
2591
|
var a = /* @__PURE__ */ new WeakMap(), t = (
|
|
2590
2592
|
/** @class */
|
|
2591
2593
|
(function() {
|
|
2592
|
-
function e(
|
|
2593
|
-
a.set(this,
|
|
2594
|
+
function e(i, n) {
|
|
2595
|
+
a.set(this, n), this.ticks = i.absoluteTime, this.value = i.value;
|
|
2594
2596
|
}
|
|
2595
2597
|
return Object.defineProperty(e.prototype, "time", {
|
|
2596
2598
|
/**
|
|
2597
2599
|
* The time of the event in seconds
|
|
2598
2600
|
*/
|
|
2599
2601
|
get: function() {
|
|
2600
|
-
var n = a.get(this);
|
|
2601
|
-
return n.ticksToSeconds(this.ticks);
|
|
2602
|
-
},
|
|
2603
|
-
set: function(n) {
|
|
2604
2602
|
var i = a.get(this);
|
|
2605
|
-
|
|
2603
|
+
return i.ticksToSeconds(this.ticks);
|
|
2604
|
+
},
|
|
2605
|
+
set: function(i) {
|
|
2606
|
+
var n = a.get(this);
|
|
2607
|
+
this.ticks = n.secondsToTicks(i);
|
|
2606
2608
|
},
|
|
2607
2609
|
enumerable: !1,
|
|
2608
2610
|
configurable: !0
|
|
@@ -2784,28 +2786,28 @@ function xe() {
|
|
|
2784
2786
|
var a = Ie(), t = /* @__PURE__ */ new WeakMap(), e = (
|
|
2785
2787
|
/** @class */
|
|
2786
2788
|
(function() {
|
|
2787
|
-
function n
|
|
2788
|
-
if (this.number = 0, t.set(this, r), this.number = 0,
|
|
2789
|
-
var s =
|
|
2789
|
+
function i(n, r) {
|
|
2790
|
+
if (this.number = 0, t.set(this, r), this.number = 0, n) {
|
|
2791
|
+
var s = n.find(function(c) {
|
|
2790
2792
|
return c.type === "programChange";
|
|
2791
2793
|
});
|
|
2792
2794
|
s && (this.number = s.programNumber);
|
|
2793
2795
|
}
|
|
2794
2796
|
}
|
|
2795
|
-
return Object.defineProperty(
|
|
2797
|
+
return Object.defineProperty(i.prototype, "name", {
|
|
2796
2798
|
/**
|
|
2797
2799
|
* The common name of the instrument.
|
|
2798
2800
|
*/
|
|
2799
2801
|
get: function() {
|
|
2800
2802
|
return this.percussion ? a.DrumKitByPatchID[this.number] : a.instrumentByPatchID[this.number];
|
|
2801
2803
|
},
|
|
2802
|
-
set: function(
|
|
2803
|
-
var r = a.instrumentByPatchID.indexOf(
|
|
2804
|
+
set: function(n) {
|
|
2805
|
+
var r = a.instrumentByPatchID.indexOf(n);
|
|
2804
2806
|
r !== -1 && (this.number = r);
|
|
2805
2807
|
},
|
|
2806
2808
|
enumerable: !1,
|
|
2807
2809
|
configurable: !0
|
|
2808
|
-
}), Object.defineProperty(
|
|
2810
|
+
}), Object.defineProperty(i.prototype, "family", {
|
|
2809
2811
|
/**
|
|
2810
2812
|
* The instrument family, e.g. "piano".
|
|
2811
2813
|
*/
|
|
@@ -2814,25 +2816,25 @@ function xe() {
|
|
|
2814
2816
|
},
|
|
2815
2817
|
enumerable: !1,
|
|
2816
2818
|
configurable: !0
|
|
2817
|
-
}), Object.defineProperty(
|
|
2819
|
+
}), Object.defineProperty(i.prototype, "percussion", {
|
|
2818
2820
|
/**
|
|
2819
2821
|
* If the instrument is a percussion instrument.
|
|
2820
2822
|
*/
|
|
2821
2823
|
get: function() {
|
|
2822
|
-
var
|
|
2823
|
-
return
|
|
2824
|
+
var n = t.get(this);
|
|
2825
|
+
return n.channel === 9;
|
|
2824
2826
|
},
|
|
2825
2827
|
enumerable: !1,
|
|
2826
2828
|
configurable: !0
|
|
2827
|
-
}),
|
|
2829
|
+
}), i.prototype.toJSON = function() {
|
|
2828
2830
|
return {
|
|
2829
2831
|
family: this.family,
|
|
2830
2832
|
number: this.number,
|
|
2831
2833
|
name: this.name
|
|
2832
2834
|
};
|
|
2833
|
-
},
|
|
2834
|
-
this.number =
|
|
2835
|
-
},
|
|
2835
|
+
}, i.prototype.fromJSON = function(n) {
|
|
2836
|
+
this.number = n.number;
|
|
2837
|
+
}, i;
|
|
2836
2838
|
})()
|
|
2837
2839
|
);
|
|
2838
2840
|
return D.Instrument = e, D;
|
|
@@ -2846,14 +2848,14 @@ function Me() {
|
|
|
2846
2848
|
return t(s) + c.toString();
|
|
2847
2849
|
}
|
|
2848
2850
|
function t(s) {
|
|
2849
|
-
var c = ["C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"],
|
|
2850
|
-
return c[
|
|
2851
|
+
var c = ["C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"], l = s % 12;
|
|
2852
|
+
return c[l];
|
|
2851
2853
|
}
|
|
2852
2854
|
function e(s) {
|
|
2853
2855
|
var c = ["C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"];
|
|
2854
2856
|
return c.indexOf(s);
|
|
2855
2857
|
}
|
|
2856
|
-
var
|
|
2858
|
+
var i = /* @__PURE__ */ (function() {
|
|
2857
2859
|
var s = /^([a-g]{1}(?:b|#|x|bb)?)(-?[0-9]+)/i, c = {
|
|
2858
2860
|
// tslint:disable-next-line: object-literal-sort-keys
|
|
2859
2861
|
cbb: -2,
|
|
@@ -2892,15 +2894,15 @@ function Me() {
|
|
|
2892
2894
|
"b#": 12,
|
|
2893
2895
|
bx: 13
|
|
2894
2896
|
};
|
|
2895
|
-
return function(
|
|
2896
|
-
var
|
|
2897
|
+
return function(l) {
|
|
2898
|
+
var u = s.exec(l), o = u[1], h = u[2], f = c[o.toLowerCase()];
|
|
2897
2899
|
return f + (parseInt(h, 10) + 1) * 12;
|
|
2898
2900
|
};
|
|
2899
|
-
})(),
|
|
2901
|
+
})(), n = /* @__PURE__ */ new WeakMap(), r = (
|
|
2900
2902
|
/** @class */
|
|
2901
2903
|
(function() {
|
|
2902
|
-
function s(c,
|
|
2903
|
-
|
|
2904
|
+
function s(c, l, u) {
|
|
2905
|
+
n.set(this, u), this.midi = c.midi, this.velocity = c.velocity, this.noteOffVelocity = l.velocity, this.ticks = c.ticks, this.durationTicks = l.ticks - c.ticks;
|
|
2904
2906
|
}
|
|
2905
2907
|
return Object.defineProperty(s.prototype, "name", {
|
|
2906
2908
|
/**
|
|
@@ -2910,7 +2912,7 @@ function Me() {
|
|
|
2910
2912
|
return a(this.midi);
|
|
2911
2913
|
},
|
|
2912
2914
|
set: function(c) {
|
|
2913
|
-
this.midi =
|
|
2915
|
+
this.midi = i(c);
|
|
2914
2916
|
},
|
|
2915
2917
|
enumerable: !1,
|
|
2916
2918
|
configurable: !0
|
|
@@ -2922,8 +2924,8 @@ function Me() {
|
|
|
2922
2924
|
return Math.floor(this.midi / 12) - 1;
|
|
2923
2925
|
},
|
|
2924
2926
|
set: function(c) {
|
|
2925
|
-
var
|
|
2926
|
-
this.midi +=
|
|
2927
|
+
var l = c - this.octave;
|
|
2928
|
+
this.midi += l * 12;
|
|
2927
2929
|
},
|
|
2928
2930
|
enumerable: !1,
|
|
2929
2931
|
configurable: !0
|
|
@@ -2944,12 +2946,12 @@ function Me() {
|
|
|
2944
2946
|
* The duration of the segment in seconds.
|
|
2945
2947
|
*/
|
|
2946
2948
|
get: function() {
|
|
2947
|
-
var c =
|
|
2949
|
+
var c = n.get(this);
|
|
2948
2950
|
return c.ticksToSeconds(this.ticks + this.durationTicks) - c.ticksToSeconds(this.ticks);
|
|
2949
2951
|
},
|
|
2950
2952
|
set: function(c) {
|
|
2951
|
-
var
|
|
2952
|
-
this.durationTicks =
|
|
2953
|
+
var l = n.get(this), u = l.secondsToTicks(this.time + c);
|
|
2954
|
+
this.durationTicks = u - this.ticks;
|
|
2953
2955
|
},
|
|
2954
2956
|
enumerable: !1,
|
|
2955
2957
|
configurable: !0
|
|
@@ -2958,12 +2960,12 @@ function Me() {
|
|
|
2958
2960
|
* The time of the event in seconds.
|
|
2959
2961
|
*/
|
|
2960
2962
|
get: function() {
|
|
2961
|
-
var c =
|
|
2963
|
+
var c = n.get(this);
|
|
2962
2964
|
return c.ticksToSeconds(this.ticks);
|
|
2963
2965
|
},
|
|
2964
2966
|
set: function(c) {
|
|
2965
|
-
var
|
|
2966
|
-
this.ticks =
|
|
2967
|
+
var l = n.get(this);
|
|
2968
|
+
this.ticks = l.secondsToTicks(c);
|
|
2967
2969
|
},
|
|
2968
2970
|
enumerable: !1,
|
|
2969
2971
|
configurable: !0
|
|
@@ -2974,7 +2976,7 @@ function Me() {
|
|
|
2974
2976
|
* @readonly
|
|
2975
2977
|
*/
|
|
2976
2978
|
get: function() {
|
|
2977
|
-
var c =
|
|
2979
|
+
var c = n.get(this);
|
|
2978
2980
|
return c.ticksToMeasures(this.ticks);
|
|
2979
2981
|
},
|
|
2980
2982
|
enumerable: !1,
|
|
@@ -2998,21 +3000,21 @@ var Nt;
|
|
|
2998
3000
|
function Ut() {
|
|
2999
3001
|
if (Nt) return U;
|
|
3000
3002
|
Nt = 1, Object.defineProperty(U, "__esModule", { value: !0 }), U.Track = void 0;
|
|
3001
|
-
var a = $t(), t = qt(), e = _e(),
|
|
3003
|
+
var a = $t(), t = qt(), e = _e(), i = Ce(), n = xe(), r = Me(), s = /* @__PURE__ */ new WeakMap(), c = (
|
|
3002
3004
|
/** @class */
|
|
3003
3005
|
(function() {
|
|
3004
|
-
function u
|
|
3006
|
+
function l(u, o) {
|
|
3005
3007
|
var h = this;
|
|
3006
|
-
if (this.name = "", this.notes = [], this.controlChanges = (0, e.createControlChanges)(), this.pitchBends = [], s.set(this, o),
|
|
3007
|
-
var f =
|
|
3008
|
+
if (this.name = "", this.notes = [], this.controlChanges = (0, e.createControlChanges)(), this.pitchBends = [], s.set(this, o), u) {
|
|
3009
|
+
var f = u.find(function(p) {
|
|
3008
3010
|
return p.type === "trackName";
|
|
3009
3011
|
});
|
|
3010
3012
|
this.name = f ? f.text : "";
|
|
3011
3013
|
}
|
|
3012
|
-
if (this.instrument = new
|
|
3013
|
-
for (var d =
|
|
3014
|
+
if (this.instrument = new n.Instrument(u, this), this.channel = 0, u) {
|
|
3015
|
+
for (var d = u.filter(function(p) {
|
|
3014
3016
|
return p.type === "noteOn";
|
|
3015
|
-
}), g =
|
|
3017
|
+
}), g = u.filter(function(p) {
|
|
3016
3018
|
return p.type === "noteOff";
|
|
3017
3019
|
}), b = function() {
|
|
3018
3020
|
var p = d.shift();
|
|
@@ -3032,7 +3034,7 @@ function Ut() {
|
|
|
3032
3034
|
}
|
|
3033
3035
|
}, y = this; d.length; )
|
|
3034
3036
|
b();
|
|
3035
|
-
var m =
|
|
3037
|
+
var m = u.filter(function(p) {
|
|
3036
3038
|
return p.type === "controller";
|
|
3037
3039
|
});
|
|
3038
3040
|
m.forEach(function(p) {
|
|
@@ -3042,7 +3044,7 @@ function Ut() {
|
|
|
3042
3044
|
value: p.value / 127
|
|
3043
3045
|
});
|
|
3044
3046
|
});
|
|
3045
|
-
var v =
|
|
3047
|
+
var v = u.filter(function(p) {
|
|
3046
3048
|
return p.type === "pitchBend";
|
|
3047
3049
|
});
|
|
3048
3050
|
v.forEach(function(p) {
|
|
@@ -3052,13 +3054,13 @@ function Ut() {
|
|
|
3052
3054
|
value: p.value / Math.pow(2, 13)
|
|
3053
3055
|
});
|
|
3054
3056
|
});
|
|
3055
|
-
var k =
|
|
3057
|
+
var k = u.find(function(p) {
|
|
3056
3058
|
return p.type === "endOfTrack";
|
|
3057
3059
|
});
|
|
3058
3060
|
this.endOfTrackTicks = k !== void 0 ? k.absoluteTime : void 0;
|
|
3059
3061
|
}
|
|
3060
3062
|
}
|
|
3061
|
-
return
|
|
3063
|
+
return l.prototype.addNote = function(u) {
|
|
3062
3064
|
var o = s.get(this), h = new r.Note({
|
|
3063
3065
|
midi: 0,
|
|
3064
3066
|
ticks: 0,
|
|
@@ -3067,57 +3069,57 @@ function Ut() {
|
|
|
3067
3069
|
ticks: 0,
|
|
3068
3070
|
velocity: 0
|
|
3069
3071
|
}, o);
|
|
3070
|
-
return Object.assign(h,
|
|
3071
|
-
},
|
|
3072
|
+
return Object.assign(h, u), (0, a.insert)(this.notes, h, "ticks"), this;
|
|
3073
|
+
}, l.prototype.addCC = function(u) {
|
|
3072
3074
|
var o = s.get(this), h = new t.ControlChange({
|
|
3073
|
-
controllerType:
|
|
3075
|
+
controllerType: u.number
|
|
3074
3076
|
}, o);
|
|
3075
|
-
return delete
|
|
3076
|
-
},
|
|
3077
|
-
var o = s.get(this), h = new
|
|
3078
|
-
return Object.assign(h,
|
|
3079
|
-
}, Object.defineProperty(
|
|
3077
|
+
return delete u.number, Object.assign(h, u), Array.isArray(this.controlChanges[h.number]) || (this.controlChanges[h.number] = []), (0, a.insert)(this.controlChanges[h.number], h, "ticks"), this;
|
|
3078
|
+
}, l.prototype.addPitchBend = function(u) {
|
|
3079
|
+
var o = s.get(this), h = new i.PitchBend({}, o);
|
|
3080
|
+
return Object.assign(h, u), (0, a.insert)(this.pitchBends, h, "ticks"), this;
|
|
3081
|
+
}, Object.defineProperty(l.prototype, "duration", {
|
|
3080
3082
|
/**
|
|
3081
3083
|
* The end time of the last event in the track.
|
|
3082
3084
|
*/
|
|
3083
3085
|
get: function() {
|
|
3084
3086
|
if (!this.notes.length)
|
|
3085
3087
|
return 0;
|
|
3086
|
-
for (var
|
|
3088
|
+
for (var u = this.notes[this.notes.length - 1].time + this.notes[this.notes.length - 1].duration, o = 0; o < this.notes.length - 1; o++) {
|
|
3087
3089
|
var h = this.notes[o].time + this.notes[o].duration;
|
|
3088
|
-
|
|
3090
|
+
u < h && (u = h);
|
|
3089
3091
|
}
|
|
3090
|
-
return
|
|
3092
|
+
return u;
|
|
3091
3093
|
},
|
|
3092
3094
|
enumerable: !1,
|
|
3093
3095
|
configurable: !0
|
|
3094
|
-
}), Object.defineProperty(
|
|
3096
|
+
}), Object.defineProperty(l.prototype, "durationTicks", {
|
|
3095
3097
|
/**
|
|
3096
3098
|
* The end time of the last event in the track in ticks.
|
|
3097
3099
|
*/
|
|
3098
3100
|
get: function() {
|
|
3099
3101
|
if (!this.notes.length)
|
|
3100
3102
|
return 0;
|
|
3101
|
-
for (var
|
|
3103
|
+
for (var u = this.notes[this.notes.length - 1].ticks + this.notes[this.notes.length - 1].durationTicks, o = 0; o < this.notes.length - 1; o++) {
|
|
3102
3104
|
var h = this.notes[o].ticks + this.notes[o].durationTicks;
|
|
3103
|
-
|
|
3105
|
+
u < h && (u = h);
|
|
3104
3106
|
}
|
|
3105
|
-
return
|
|
3107
|
+
return u;
|
|
3106
3108
|
},
|
|
3107
3109
|
enumerable: !1,
|
|
3108
3110
|
configurable: !0
|
|
3109
|
-
}),
|
|
3111
|
+
}), l.prototype.fromJSON = function(u) {
|
|
3110
3112
|
var o = this;
|
|
3111
|
-
this.name =
|
|
3112
|
-
for (var h in
|
|
3113
|
-
|
|
3113
|
+
this.name = u.name, this.channel = u.channel, this.instrument = new n.Instrument(void 0, this), this.instrument.fromJSON(u.instrument), u.endOfTrackTicks !== void 0 && (this.endOfTrackTicks = u.endOfTrackTicks);
|
|
3114
|
+
for (var h in u.controlChanges)
|
|
3115
|
+
u.controlChanges[h] && u.controlChanges[h].forEach(function(f) {
|
|
3114
3116
|
o.addCC({
|
|
3115
3117
|
number: f.number,
|
|
3116
3118
|
ticks: f.ticks,
|
|
3117
3119
|
value: f.value
|
|
3118
3120
|
});
|
|
3119
3121
|
});
|
|
3120
|
-
|
|
3122
|
+
u.notes.forEach(function(f) {
|
|
3121
3123
|
o.addNote({
|
|
3122
3124
|
durationTicks: f.durationTicks,
|
|
3123
3125
|
midi: f.midi,
|
|
@@ -3125,14 +3127,14 @@ function Ut() {
|
|
|
3125
3127
|
velocity: f.velocity
|
|
3126
3128
|
});
|
|
3127
3129
|
});
|
|
3128
|
-
},
|
|
3129
|
-
for (var
|
|
3130
|
-
this.controlChanges.hasOwnProperty(o) && (
|
|
3130
|
+
}, l.prototype.toJSON = function() {
|
|
3131
|
+
for (var u = {}, o = 0; o < 127; o++)
|
|
3132
|
+
this.controlChanges.hasOwnProperty(o) && (u[o] = this.controlChanges[o].map(function(f) {
|
|
3131
3133
|
return f.toJSON();
|
|
3132
3134
|
}));
|
|
3133
3135
|
var h = {
|
|
3134
3136
|
channel: this.channel,
|
|
3135
|
-
controlChanges:
|
|
3137
|
+
controlChanges: u,
|
|
3136
3138
|
pitchBends: this.pitchBends.map(function(f) {
|
|
3137
3139
|
return f.toJSON();
|
|
3138
3140
|
}),
|
|
@@ -3143,7 +3145,7 @@ function Ut() {
|
|
|
3143
3145
|
})
|
|
3144
3146
|
};
|
|
3145
3147
|
return this.endOfTrackTicks !== void 0 && (h.endOfTrackTicks = this.endOfTrackTicks), h;
|
|
3146
|
-
},
|
|
3148
|
+
}, l;
|
|
3147
3149
|
})()
|
|
3148
3150
|
);
|
|
3149
3151
|
return U.Track = c, U;
|
|
@@ -3155,8 +3157,8 @@ function Ee(a) {
|
|
|
3155
3157
|
}
|
|
3156
3158
|
function zt(a, t) {
|
|
3157
3159
|
for (var e = 0; e < a.length; e++) {
|
|
3158
|
-
var
|
|
3159
|
-
Array.isArray(
|
|
3160
|
+
var i = a[e];
|
|
3161
|
+
Array.isArray(i) ? zt(i, t) : t.push(i);
|
|
3160
3162
|
}
|
|
3161
3163
|
}
|
|
3162
3164
|
const Pe = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
|
|
@@ -3173,8 +3175,8 @@ function Ne() {
|
|
|
3173
3175
|
return m.concat(w || Array.prototype.slice.call(v));
|
|
3174
3176
|
};
|
|
3175
3177
|
Object.defineProperty(P, "__esModule", { value: !0 }), P.encode = void 0;
|
|
3176
|
-
var t = Gt(), e = it(),
|
|
3177
|
-
function
|
|
3178
|
+
var t = Gt(), e = it(), i = Fe;
|
|
3179
|
+
function n(m, v) {
|
|
3178
3180
|
return [
|
|
3179
3181
|
{
|
|
3180
3182
|
absoluteTime: m.ticks,
|
|
@@ -3195,8 +3197,8 @@ function Ne() {
|
|
|
3195
3197
|
];
|
|
3196
3198
|
}
|
|
3197
3199
|
function r(m) {
|
|
3198
|
-
return (0,
|
|
3199
|
-
return
|
|
3200
|
+
return (0, i.flatten)(m.notes.map(function(v) {
|
|
3201
|
+
return n(v, m.channel);
|
|
3200
3202
|
}));
|
|
3201
3203
|
}
|
|
3202
3204
|
function s(m, v) {
|
|
@@ -3216,7 +3218,7 @@ function Ne() {
|
|
|
3216
3218
|
});
|
|
3217
3219
|
return v;
|
|
3218
3220
|
}
|
|
3219
|
-
function
|
|
3221
|
+
function l(m, v) {
|
|
3220
3222
|
return {
|
|
3221
3223
|
absoluteTime: m.ticks,
|
|
3222
3224
|
channel: v,
|
|
@@ -3225,10 +3227,10 @@ function Ne() {
|
|
|
3225
3227
|
value: m.value
|
|
3226
3228
|
};
|
|
3227
3229
|
}
|
|
3228
|
-
function
|
|
3230
|
+
function u(m) {
|
|
3229
3231
|
var v = [];
|
|
3230
3232
|
return m.pitchBends.forEach(function(k) {
|
|
3231
|
-
v.push(
|
|
3233
|
+
v.push(l(k, m.channel));
|
|
3232
3234
|
}), v;
|
|
3233
3235
|
}
|
|
3234
3236
|
function o(m) {
|
|
@@ -3322,7 +3324,7 @@ function Ne() {
|
|
|
3322
3324
|
h(k.name),
|
|
3323
3325
|
// the instrument
|
|
3324
3326
|
o(k)
|
|
3325
|
-
], r(k), !0), c(k), !0),
|
|
3327
|
+
], r(k), !0), c(k), !0), u(k), !0);
|
|
3326
3328
|
}), !0)
|
|
3327
3329
|
};
|
|
3328
3330
|
return v.tracks = v.tracks.map(function(k) {
|
|
@@ -3431,21 +3433,21 @@ function Ue() {
|
|
|
3431
3433
|
}
|
|
3432
3434
|
};
|
|
3433
3435
|
Object.defineProperty(a, "__esModule", { value: !0 }), a.Header = a.Track = a.Midi = void 0;
|
|
3434
|
-
var
|
|
3436
|
+
var i = Gt(), n = it(), r = Ut(), s = Ne(), c = (
|
|
3435
3437
|
/** @class */
|
|
3436
3438
|
(function() {
|
|
3437
3439
|
function h(f) {
|
|
3438
3440
|
var d = this, g = null;
|
|
3439
3441
|
if (f) {
|
|
3440
3442
|
var b = f instanceof ArrayBuffer ? new Uint8Array(f) : f;
|
|
3441
|
-
g = (0,
|
|
3443
|
+
g = (0, i.parseMidi)(b), g.tracks.forEach(function(y) {
|
|
3442
3444
|
var m = 0;
|
|
3443
3445
|
y.forEach(function(v) {
|
|
3444
3446
|
m += v.deltaTime, v.absoluteTime = m;
|
|
3445
3447
|
});
|
|
3446
3448
|
}), g.tracks = o(g.tracks);
|
|
3447
3449
|
}
|
|
3448
|
-
this.header = new
|
|
3450
|
+
this.header = new n.Header(g), this.tracks = [], f && (this.tracks = g.tracks.map(function(y) {
|
|
3449
3451
|
return new r.Track(y, d.header);
|
|
3450
3452
|
}), g.header.format === 1 && this.tracks[0].duration === 0 && this.tracks.shift());
|
|
3451
3453
|
}
|
|
@@ -3515,7 +3517,7 @@ function Ue() {
|
|
|
3515
3517
|
};
|
|
3516
3518
|
}, h.prototype.fromJSON = function(f) {
|
|
3517
3519
|
var d = this;
|
|
3518
|
-
this.header = new
|
|
3520
|
+
this.header = new n.Header(), this.header.fromJSON(f.header), this.tracks = f.tracks.map(function(g) {
|
|
3519
3521
|
var b = new r.Track(void 0, d.header);
|
|
3520
3522
|
return b.fromJSON(g), b;
|
|
3521
3523
|
});
|
|
@@ -3526,13 +3528,13 @@ function Ue() {
|
|
|
3526
3528
|
})()
|
|
3527
3529
|
);
|
|
3528
3530
|
a.Midi = c;
|
|
3529
|
-
var
|
|
3531
|
+
var l = Ut();
|
|
3530
3532
|
Object.defineProperty(a, "Track", { enumerable: !0, get: function() {
|
|
3531
|
-
return
|
|
3533
|
+
return l.Track;
|
|
3532
3534
|
} });
|
|
3533
|
-
var
|
|
3535
|
+
var u = it();
|
|
3534
3536
|
Object.defineProperty(a, "Header", { enumerable: !0, get: function() {
|
|
3535
|
-
return
|
|
3537
|
+
return u.Header;
|
|
3536
3538
|
} });
|
|
3537
3539
|
function o(h) {
|
|
3538
3540
|
for (var f = [], d = 0; d < h.length; d++)
|
|
@@ -3700,11 +3702,11 @@ function Dt(a) {
|
|
|
3700
3702
|
return Ae[a] ?? `Program ${a}`;
|
|
3701
3703
|
}
|
|
3702
3704
|
function De(a, t = {}) {
|
|
3703
|
-
const { flatten: e = !1 } = t,
|
|
3704
|
-
for (const h of
|
|
3705
|
+
const { flatten: e = !1 } = t, i = new Oe.Midi(a), n = i.header.tempos[0]?.bpm ?? 120, r = i.header.timeSignatures[0], s = r ? [r.timeSignature[0], r.timeSignature[1]] : [4, 4], c = i.name || "Untitled", l = /* @__PURE__ */ new Map();
|
|
3706
|
+
for (const h of i.tracks) {
|
|
3705
3707
|
const f = h.channel, d = h.instrument.number, g = h.name || Dt(d);
|
|
3706
|
-
|
|
3707
|
-
const b =
|
|
3708
|
+
l.has(f) || l.set(f, { notes: [], programNumber: d, name: g });
|
|
3709
|
+
const b = l.get(f);
|
|
3708
3710
|
h.name && !b.name.startsWith(h.name) && (b.name = h.name);
|
|
3709
3711
|
for (const y of h.notes)
|
|
3710
3712
|
b.notes.push({
|
|
@@ -3716,33 +3718,33 @@ function De(a, t = {}) {
|
|
|
3716
3718
|
channel: f
|
|
3717
3719
|
});
|
|
3718
3720
|
}
|
|
3719
|
-
let
|
|
3720
|
-
if (
|
|
3721
|
+
let u = 0;
|
|
3722
|
+
if (l.forEach(({ notes: h }) => {
|
|
3721
3723
|
for (const f of h) {
|
|
3722
3724
|
const d = f.time + f.duration;
|
|
3723
|
-
d >
|
|
3725
|
+
d > u && (u = d);
|
|
3724
3726
|
}
|
|
3725
3727
|
}), e) {
|
|
3726
3728
|
const h = [];
|
|
3727
|
-
return
|
|
3729
|
+
return l.forEach(({ notes: f }) => {
|
|
3728
3730
|
h.push(...f);
|
|
3729
3731
|
}), h.sort((f, d) => f.time - d.time), {
|
|
3730
3732
|
tracks: [{
|
|
3731
3733
|
name: c,
|
|
3732
3734
|
notes: h,
|
|
3733
|
-
duration:
|
|
3735
|
+
duration: u,
|
|
3734
3736
|
channel: 0,
|
|
3735
3737
|
instrument: "Mixed",
|
|
3736
3738
|
programNumber: 0
|
|
3737
3739
|
}],
|
|
3738
|
-
duration:
|
|
3740
|
+
duration: u,
|
|
3739
3741
|
name: c,
|
|
3740
|
-
bpm:
|
|
3742
|
+
bpm: n,
|
|
3741
3743
|
timeSignature: s
|
|
3742
3744
|
};
|
|
3743
3745
|
}
|
|
3744
3746
|
const o = [];
|
|
3745
|
-
return
|
|
3747
|
+
return l.forEach(({ notes: h, programNumber: f, name: d }, g) => {
|
|
3746
3748
|
if (h.length === 0) return;
|
|
3747
3749
|
h.sort((y, m) => y.time - m.time);
|
|
3748
3750
|
let b = 0;
|
|
@@ -3760,18 +3762,18 @@ function De(a, t = {}) {
|
|
|
3760
3762
|
});
|
|
3761
3763
|
}), {
|
|
3762
3764
|
tracks: o,
|
|
3763
|
-
duration:
|
|
3765
|
+
duration: u,
|
|
3764
3766
|
name: c,
|
|
3765
|
-
bpm:
|
|
3767
|
+
bpm: n,
|
|
3766
3768
|
timeSignature: s
|
|
3767
3769
|
};
|
|
3768
3770
|
}
|
|
3769
3771
|
async function Er(a, t = {}, e) {
|
|
3770
|
-
const
|
|
3771
|
-
if (!
|
|
3772
|
-
throw new Error(`Failed to fetch MIDI file: ${
|
|
3773
|
-
const
|
|
3774
|
-
return De(
|
|
3772
|
+
const i = await fetch(a, { signal: e });
|
|
3773
|
+
if (!i.ok)
|
|
3774
|
+
throw new Error(`Failed to fetch MIDI file: ${i.status} ${i.statusText}`);
|
|
3775
|
+
const n = await i.arrayBuffer();
|
|
3776
|
+
return De(n, t);
|
|
3775
3777
|
}
|
|
3776
3778
|
function Pr(a) {
|
|
3777
3779
|
const t = ["C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"], e = Math.floor(a / 12) - 1;
|
|
@@ -3780,9 +3782,9 @@ function Pr(a) {
|
|
|
3780
3782
|
function Fr(a) {
|
|
3781
3783
|
const t = a.match(/^([A-Ga-g])([#b]?)(-?\d+)$/);
|
|
3782
3784
|
if (!t) throw new Error(`Invalid note name: ${a}`);
|
|
3783
|
-
const [, e,
|
|
3785
|
+
const [, e, i, n] = t;
|
|
3784
3786
|
let s = { C: 0, D: 2, E: 4, F: 5, G: 7, A: 9, B: 11 }[e.toUpperCase()];
|
|
3785
|
-
return
|
|
3787
|
+
return i === "#" && (s += 1), i === "b" && (s -= 1), (parseInt(n, 10) + 1) * 12 + s;
|
|
3786
3788
|
}
|
|
3787
3789
|
const Nr = {
|
|
3788
3790
|
NOTE_OFF: 8,
|
|
@@ -3807,10 +3809,10 @@ const Nr = {
|
|
|
3807
3809
|
ALL_NOTES_OFF: 123
|
|
3808
3810
|
};
|
|
3809
3811
|
function Be(a, t) {
|
|
3810
|
-
const e = a[0],
|
|
3812
|
+
const e = a[0], i = e >> 4 & 15, n = e & 15;
|
|
3811
3813
|
return {
|
|
3812
|
-
command:
|
|
3813
|
-
channel:
|
|
3814
|
+
command: i,
|
|
3815
|
+
channel: n,
|
|
3814
3816
|
data1: a[1] ?? 0,
|
|
3815
3817
|
data2: a[2] ?? 0,
|
|
3816
3818
|
raw: a,
|
|
@@ -3888,10 +3890,10 @@ class Or {
|
|
|
3888
3890
|
if (!this.access) return !1;
|
|
3889
3891
|
this.disconnectInput();
|
|
3890
3892
|
const e = this.access.inputs.get(t);
|
|
3891
|
-
return e ? (this.activeInputId = t, e.onmidimessage = (
|
|
3892
|
-
if (!
|
|
3893
|
-
const
|
|
3894
|
-
this.messageCallbacks.forEach((r) => r(
|
|
3893
|
+
return e ? (this.activeInputId = t, e.onmidimessage = (i) => {
|
|
3894
|
+
if (!i.data) return;
|
|
3895
|
+
const n = Be(i.data, i.timeStamp);
|
|
3896
|
+
this.messageCallbacks.forEach((r) => r(n));
|
|
3895
3897
|
}, console.log(`[MIDI] Connected to input: ${e.name}`), !0) : (console.warn(`[MIDI] Input device not found: ${t}`), !1);
|
|
3896
3898
|
}
|
|
3897
3899
|
/**
|
|
@@ -3932,8 +3934,8 @@ class Or {
|
|
|
3932
3934
|
*/
|
|
3933
3935
|
sendMessage(t, e) {
|
|
3934
3936
|
if (!this.access) return !1;
|
|
3935
|
-
const
|
|
3936
|
-
return
|
|
3937
|
+
const i = this.access.outputs.get(t);
|
|
3938
|
+
return i ? (i.send(e), !0) : !1;
|
|
3937
3939
|
}
|
|
3938
3940
|
/**
|
|
3939
3941
|
* Clean up resources
|
|
@@ -4001,11 +4003,11 @@ class ze {
|
|
|
4001
4003
|
constructor(t = {}) {
|
|
4002
4004
|
this.events = new $e(), this.plugins = new qe({
|
|
4003
4005
|
events: this.events,
|
|
4004
|
-
requestAssistant: (c,
|
|
4005
|
-
this.events.emit("assistant:request", { assistantId: c, action:
|
|
4006
|
+
requestAssistant: (c, l, u) => {
|
|
4007
|
+
this.events.emit("assistant:request", { assistantId: c, action: l, payload: u });
|
|
4006
4008
|
}
|
|
4007
4009
|
}), this.transport = {
|
|
4008
|
-
play: (c,
|
|
4010
|
+
play: (c, l) => this.playlist.play(c, l),
|
|
4009
4011
|
pause: () => this.playlist.pause(),
|
|
4010
4012
|
stop: () => this.playlist.stop(),
|
|
4011
4013
|
seek: (c) => {
|
|
@@ -4016,7 +4018,7 @@ class ze {
|
|
|
4016
4018
|
set: (c) => {
|
|
4017
4019
|
this.playlist.setTracks(c), this.events.emit(
|
|
4018
4020
|
"tracks:set",
|
|
4019
|
-
c.map((
|
|
4021
|
+
c.map((l) => l.id)
|
|
4020
4022
|
);
|
|
4021
4023
|
},
|
|
4022
4024
|
add: (c) => {
|
|
@@ -4039,11 +4041,11 @@ class ze {
|
|
|
4039
4041
|
}, this.handleStop = () => {
|
|
4040
4042
|
this.events.emit("stop");
|
|
4041
4043
|
};
|
|
4042
|
-
const { adapter: e, audio:
|
|
4044
|
+
const { adapter: e, audio: i, plugins: n = [], ...r } = t, s = e ?? ke(i);
|
|
4043
4045
|
this.playlist = new ce({
|
|
4044
4046
|
...r,
|
|
4045
4047
|
adapter: s
|
|
4046
|
-
}), this.initialPlugins =
|
|
4048
|
+
}), this.initialPlugins = n, this.playlist.on("statechange", this.handleStateChange), this.playlist.on("timeupdate", this.handleTimeUpdate), this.playlist.on("play", this.handlePlay), this.playlist.on("pause", this.handlePause), this.playlist.on("stop", this.handleStop);
|
|
4047
4049
|
}
|
|
4048
4050
|
async init() {
|
|
4049
4051
|
await this.playlist.init();
|