pepperscore 0.2.0 → 0.4.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/CHANGELOG.md +74 -0
- package/LICENSE +26 -12
- package/README.md +127 -9
- package/dist/THIRD_PARTY_NOTICES.txt +1222 -0
- package/dist/assets/{import.worker-D0XfuAHu.js → import.worker-Rop-z7az.js} +2 -2
- package/dist/assets/verovio.worker-DQm-ikdG.js +7 -0
- package/dist/audio.d.ts +24 -0
- package/dist/audio.js +198 -0
- package/dist/audio.js.map +1 -0
- package/dist/components/InstrumentChooser.d.ts +17 -0
- package/dist/components/OctaveTool.d.ts +21 -0
- package/dist/components/PepperScore.d.ts +96 -1
- package/dist/index.d.ts +3 -2
- package/dist/index.js +3738 -3382
- package/dist/index.js.map +1 -1
- package/dist/instruments.d.ts +2 -0
- package/dist/instruments.js +2 -0
- package/dist/lib/chrome.d.ts +10 -2
- package/dist/lib/file-state.d.ts +45 -5
- package/dist/lib/header-controls.d.ts +7 -3
- package/dist/lib/hit-test.d.ts +18 -0
- package/dist/lib/instrument-model.d.ts +80 -0
- package/dist/lib/instrument-switch-state.d.ts +169 -0
- package/dist/lib/instrument-view.d.ts +92 -0
- package/dist/lib/instruments.d.ts +82 -0
- package/dist/lib/metronome.d.ts +33 -0
- package/dist/lib/notation/document.d.ts +11 -1
- package/dist/lib/notation/mei-spelling.d.ts +9 -1
- package/dist/lib/notation/mei-tab.d.ts +58 -0
- package/dist/lib/notation/mei-view.d.ts +8 -0
- package/dist/lib/playback/timeline.d.ts +4 -1
- package/dist/lib/prefs.d.ts +67 -0
- package/dist/lib/range-fit-core.d.ts +26 -0
- package/dist/lib/render.d.ts +36 -1
- package/dist/lib/score.d.ts +23 -1
- package/dist/lib/sound-players.d.ts +9 -1
- package/dist/lib/tab/fret-assign.d.ts +53 -0
- package/dist/lib/tab/tab-parts.d.ts +64 -0
- package/dist/lib/transpose.d.ts +3 -2
- package/dist/lib/verovio-protocol.d.ts +15 -0
- package/dist/lib/verovio-runtime.d.ts +9 -1
- package/dist/range-fit-core-B1rMWdI4.js +468 -0
- package/dist/range-fit-core-B1rMWdI4.js.map +1 -0
- package/dist/runtime-files.d.ts +15 -0
- package/dist/{sf2-player-CRlOJDhD.js → sf2-player-oWC6yrUH.js} +28 -6
- package/dist/sf2-player-oWC6yrUH.js.map +1 -0
- package/dist/sound-players-DdLBBZaR.js +1172 -0
- package/dist/sound-players-DdLBBZaR.js.map +1 -0
- package/dist/style.css +1 -1
- package/dist/verovio/LICENSE +858 -0
- package/dist/verovio/verovio-module.mjs +0 -0
- package/dist/verovio/verovio.mjs +397 -0
- package/package.json +14 -2
- package/dist/assets/verovio.worker-DkHQmOsT.js +0 -19034
- package/dist/sf2-player-CRlOJDhD.js.map +0 -1
|
@@ -0,0 +1,468 @@
|
|
|
1
|
+
//#region src/lib/instrument-model.ts
|
|
2
|
+
var e = [
|
|
3
|
+
"piano",
|
|
4
|
+
"guitar",
|
|
5
|
+
"bassguitar",
|
|
6
|
+
"double-bass",
|
|
7
|
+
"drum-kit",
|
|
8
|
+
"alto-saxophone",
|
|
9
|
+
"tenor-saxophone",
|
|
10
|
+
"bari-saxophone",
|
|
11
|
+
"flute",
|
|
12
|
+
"clarinet",
|
|
13
|
+
"trumpet",
|
|
14
|
+
"trombone",
|
|
15
|
+
"violin",
|
|
16
|
+
"viola",
|
|
17
|
+
"cello",
|
|
18
|
+
"microphone"
|
|
19
|
+
], t = [
|
|
20
|
+
"beginner",
|
|
21
|
+
"intermediate",
|
|
22
|
+
"advanced"
|
|
23
|
+
], n = (e, t, n) => Object.freeze({
|
|
24
|
+
beginner: Object.freeze({
|
|
25
|
+
low: e[0],
|
|
26
|
+
high: e[1]
|
|
27
|
+
}),
|
|
28
|
+
intermediate: Object.freeze({
|
|
29
|
+
low: t[0],
|
|
30
|
+
high: t[1]
|
|
31
|
+
}),
|
|
32
|
+
advanced: Object.freeze({
|
|
33
|
+
low: n[0],
|
|
34
|
+
high: n[1]
|
|
35
|
+
})
|
|
36
|
+
}), r = Object.freeze({
|
|
37
|
+
semitones: 0,
|
|
38
|
+
diatonic: 0
|
|
39
|
+
}), i = Object.freeze({
|
|
40
|
+
semitones: 12,
|
|
41
|
+
diatonic: 7
|
|
42
|
+
}), a = Object.freeze({
|
|
43
|
+
semitones: 2,
|
|
44
|
+
diatonic: 1
|
|
45
|
+
}), o = {
|
|
46
|
+
piano: {
|
|
47
|
+
id: "piano",
|
|
48
|
+
label: "Piano",
|
|
49
|
+
gmProgram: 1,
|
|
50
|
+
clef: "treble",
|
|
51
|
+
transposition: r,
|
|
52
|
+
ranges: n([21, 108], [21, 108], [21, 108])
|
|
53
|
+
},
|
|
54
|
+
guitar: {
|
|
55
|
+
id: "guitar",
|
|
56
|
+
label: "Guitar",
|
|
57
|
+
gmProgram: 25,
|
|
58
|
+
clef: "treble",
|
|
59
|
+
transposition: i,
|
|
60
|
+
ranges: n([40, 64], [40, 76], [40, 88])
|
|
61
|
+
},
|
|
62
|
+
bassguitar: {
|
|
63
|
+
id: "bassguitar",
|
|
64
|
+
label: "Bass Guitar",
|
|
65
|
+
gmProgram: 34,
|
|
66
|
+
clef: "bass",
|
|
67
|
+
transposition: i,
|
|
68
|
+
ranges: n([28, 48], [28, 55], [28, 60])
|
|
69
|
+
},
|
|
70
|
+
"double-bass": {
|
|
71
|
+
id: "double-bass",
|
|
72
|
+
label: "Double Bass",
|
|
73
|
+
gmProgram: 33,
|
|
74
|
+
clef: "bass",
|
|
75
|
+
transposition: i,
|
|
76
|
+
ranges: n([28, 48], [28, 55], [28, 64])
|
|
77
|
+
},
|
|
78
|
+
"drum-kit": {
|
|
79
|
+
id: "drum-kit",
|
|
80
|
+
label: "Drum Kit",
|
|
81
|
+
gmProgram: 1,
|
|
82
|
+
clef: "percussion",
|
|
83
|
+
transposition: r
|
|
84
|
+
},
|
|
85
|
+
"alto-saxophone": {
|
|
86
|
+
id: "alto-saxophone",
|
|
87
|
+
label: "Alto Saxophone",
|
|
88
|
+
short: "Alto Sax",
|
|
89
|
+
gmProgram: 66,
|
|
90
|
+
clef: "treble",
|
|
91
|
+
transposition: {
|
|
92
|
+
semitones: 9,
|
|
93
|
+
diatonic: 5
|
|
94
|
+
},
|
|
95
|
+
ranges: n([49, 69], [49, 77], [49, 81])
|
|
96
|
+
},
|
|
97
|
+
"tenor-saxophone": {
|
|
98
|
+
id: "tenor-saxophone",
|
|
99
|
+
label: "Tenor Saxophone",
|
|
100
|
+
short: "Tenor Sax",
|
|
101
|
+
gmProgram: 67,
|
|
102
|
+
clef: "treble",
|
|
103
|
+
transposition: {
|
|
104
|
+
semitones: 14,
|
|
105
|
+
diatonic: 8
|
|
106
|
+
},
|
|
107
|
+
ranges: n([44, 64], [44, 72], [44, 76])
|
|
108
|
+
},
|
|
109
|
+
"bari-saxophone": {
|
|
110
|
+
id: "bari-saxophone",
|
|
111
|
+
label: "Baritone Saxophone",
|
|
112
|
+
short: "Bari Sax",
|
|
113
|
+
gmProgram: 68,
|
|
114
|
+
clef: "treble",
|
|
115
|
+
transposition: {
|
|
116
|
+
semitones: 21,
|
|
117
|
+
diatonic: 12
|
|
118
|
+
},
|
|
119
|
+
ranges: n([37, 57], [37, 65], [36, 69])
|
|
120
|
+
},
|
|
121
|
+
flute: {
|
|
122
|
+
id: "flute",
|
|
123
|
+
label: "Flute",
|
|
124
|
+
gmProgram: 74,
|
|
125
|
+
clef: "treble",
|
|
126
|
+
transposition: r,
|
|
127
|
+
ranges: n([60, 84], [60, 91], [59, 96])
|
|
128
|
+
},
|
|
129
|
+
clarinet: {
|
|
130
|
+
id: "clarinet",
|
|
131
|
+
label: "Clarinet",
|
|
132
|
+
gmProgram: 72,
|
|
133
|
+
clef: "treble",
|
|
134
|
+
transposition: a,
|
|
135
|
+
ranges: n([50, 74], [50, 82], [50, 91])
|
|
136
|
+
},
|
|
137
|
+
trumpet: {
|
|
138
|
+
id: "trumpet",
|
|
139
|
+
label: "Trumpet",
|
|
140
|
+
gmProgram: 57,
|
|
141
|
+
clef: "treble",
|
|
142
|
+
transposition: a,
|
|
143
|
+
ranges: n([55, 72], [54, 79], [52, 86])
|
|
144
|
+
},
|
|
145
|
+
trombone: {
|
|
146
|
+
id: "trombone",
|
|
147
|
+
label: "Trombone",
|
|
148
|
+
gmProgram: 58,
|
|
149
|
+
clef: "bass",
|
|
150
|
+
transposition: r,
|
|
151
|
+
ranges: n([46, 65], [40, 70], [34, 77])
|
|
152
|
+
},
|
|
153
|
+
violin: {
|
|
154
|
+
id: "violin",
|
|
155
|
+
label: "Violin",
|
|
156
|
+
gmProgram: 41,
|
|
157
|
+
clef: "treble",
|
|
158
|
+
transposition: r,
|
|
159
|
+
ranges: n([55, 81], [55, 91], [55, 105])
|
|
160
|
+
},
|
|
161
|
+
viola: {
|
|
162
|
+
id: "viola",
|
|
163
|
+
label: "Viola",
|
|
164
|
+
gmProgram: 42,
|
|
165
|
+
clef: "alto",
|
|
166
|
+
transposition: r,
|
|
167
|
+
ranges: n([48, 76], [48, 84], [48, 96])
|
|
168
|
+
},
|
|
169
|
+
cello: {
|
|
170
|
+
id: "cello",
|
|
171
|
+
label: "Cello",
|
|
172
|
+
gmProgram: 43,
|
|
173
|
+
clef: "bass",
|
|
174
|
+
transposition: r,
|
|
175
|
+
ranges: n([36, 64], [36, 76], [36, 88])
|
|
176
|
+
},
|
|
177
|
+
microphone: {
|
|
178
|
+
id: "microphone",
|
|
179
|
+
label: "Voice",
|
|
180
|
+
gmProgram: 54,
|
|
181
|
+
clef: "treble",
|
|
182
|
+
transposition: r,
|
|
183
|
+
ranges: n([48, 72], [45, 76], [40, 81])
|
|
184
|
+
}
|
|
185
|
+
};
|
|
186
|
+
for (let e of Object.values(o)) Object.freeze(e.transposition), Object.freeze(e);
|
|
187
|
+
var s = Object.freeze(o), c = (e) => s[e].short ?? s[e].label, l = [
|
|
188
|
+
[
|
|
189
|
+
1,
|
|
190
|
+
24,
|
|
191
|
+
"piano"
|
|
192
|
+
],
|
|
193
|
+
[
|
|
194
|
+
25,
|
|
195
|
+
32,
|
|
196
|
+
"guitar"
|
|
197
|
+
],
|
|
198
|
+
[
|
|
199
|
+
33,
|
|
200
|
+
33,
|
|
201
|
+
"double-bass"
|
|
202
|
+
],
|
|
203
|
+
[
|
|
204
|
+
34,
|
|
205
|
+
40,
|
|
206
|
+
"bassguitar"
|
|
207
|
+
],
|
|
208
|
+
[
|
|
209
|
+
41,
|
|
210
|
+
41,
|
|
211
|
+
"violin"
|
|
212
|
+
],
|
|
213
|
+
[
|
|
214
|
+
42,
|
|
215
|
+
42,
|
|
216
|
+
"viola"
|
|
217
|
+
],
|
|
218
|
+
[
|
|
219
|
+
43,
|
|
220
|
+
43,
|
|
221
|
+
"cello"
|
|
222
|
+
],
|
|
223
|
+
[
|
|
224
|
+
44,
|
|
225
|
+
44,
|
|
226
|
+
"double-bass"
|
|
227
|
+
],
|
|
228
|
+
[
|
|
229
|
+
45,
|
|
230
|
+
52,
|
|
231
|
+
"violin"
|
|
232
|
+
],
|
|
233
|
+
[
|
|
234
|
+
53,
|
|
235
|
+
55,
|
|
236
|
+
"microphone"
|
|
237
|
+
],
|
|
238
|
+
[
|
|
239
|
+
57,
|
|
240
|
+
57,
|
|
241
|
+
"trumpet"
|
|
242
|
+
],
|
|
243
|
+
[
|
|
244
|
+
58,
|
|
245
|
+
59,
|
|
246
|
+
"trombone"
|
|
247
|
+
],
|
|
248
|
+
[
|
|
249
|
+
60,
|
|
250
|
+
60,
|
|
251
|
+
"trumpet"
|
|
252
|
+
],
|
|
253
|
+
[
|
|
254
|
+
61,
|
|
255
|
+
61,
|
|
256
|
+
"trombone"
|
|
257
|
+
],
|
|
258
|
+
[
|
|
259
|
+
62,
|
|
260
|
+
64,
|
|
261
|
+
"trumpet"
|
|
262
|
+
],
|
|
263
|
+
[
|
|
264
|
+
65,
|
|
265
|
+
66,
|
|
266
|
+
"alto-saxophone"
|
|
267
|
+
],
|
|
268
|
+
[
|
|
269
|
+
67,
|
|
270
|
+
67,
|
|
271
|
+
"tenor-saxophone"
|
|
272
|
+
],
|
|
273
|
+
[
|
|
274
|
+
68,
|
|
275
|
+
68,
|
|
276
|
+
"bari-saxophone"
|
|
277
|
+
],
|
|
278
|
+
[
|
|
279
|
+
69,
|
|
280
|
+
72,
|
|
281
|
+
"clarinet"
|
|
282
|
+
],
|
|
283
|
+
[
|
|
284
|
+
73,
|
|
285
|
+
80,
|
|
286
|
+
"flute"
|
|
287
|
+
]
|
|
288
|
+
];
|
|
289
|
+
function u(e) {
|
|
290
|
+
return s[l.find(([t, n]) => e >= t && e <= n)?.[2] ?? "piano"];
|
|
291
|
+
}
|
|
292
|
+
var d = [
|
|
293
|
+
"C",
|
|
294
|
+
"D",
|
|
295
|
+
"E",
|
|
296
|
+
"F",
|
|
297
|
+
"G",
|
|
298
|
+
"A",
|
|
299
|
+
"B"
|
|
300
|
+
], f = [
|
|
301
|
+
"F",
|
|
302
|
+
"C",
|
|
303
|
+
"G",
|
|
304
|
+
"D",
|
|
305
|
+
"A",
|
|
306
|
+
"E",
|
|
307
|
+
"B"
|
|
308
|
+
], p = {
|
|
309
|
+
C: 0,
|
|
310
|
+
D: 2,
|
|
311
|
+
E: 4,
|
|
312
|
+
F: 5,
|
|
313
|
+
G: 7,
|
|
314
|
+
A: 9,
|
|
315
|
+
B: 11
|
|
316
|
+
}, m = (e) => (e.octave + 1) * 12 + p[e.step] + e.alter;
|
|
317
|
+
function h(e, t) {
|
|
318
|
+
return t > 0 ? +(f.indexOf(e) < t) : t < 0 && f.length - 1 - f.indexOf(e) < -t ? -1 : 0;
|
|
319
|
+
}
|
|
320
|
+
function g(e, t, n) {
|
|
321
|
+
let r = [];
|
|
322
|
+
for (let t of d) for (let n = Math.floor(e / 12) - 2; n <= Math.floor(e / 12); n++) {
|
|
323
|
+
let i = e - m({
|
|
324
|
+
step: t,
|
|
325
|
+
octave: n,
|
|
326
|
+
alter: 0
|
|
327
|
+
});
|
|
328
|
+
i >= -2 && i <= 2 && r.push({
|
|
329
|
+
step: t,
|
|
330
|
+
octave: n,
|
|
331
|
+
alter: i
|
|
332
|
+
});
|
|
333
|
+
}
|
|
334
|
+
let i = n >= 0 ? 1 : -1, a = (e) => e.alter === h(e.step, t) ? 0 : e.alter === 0 ? 1 : e.alter === i ? 2 : e.alter === -i ? 3 : 4;
|
|
335
|
+
return r.sort((e, t) => a(e) - a(t))[0];
|
|
336
|
+
}
|
|
337
|
+
function _(e, t) {
|
|
338
|
+
return m(e) - t.semitones;
|
|
339
|
+
}
|
|
340
|
+
function v(e, t, n) {
|
|
341
|
+
return g(e + t.semitones, n, n < 0 ? -1 : 1);
|
|
342
|
+
}
|
|
343
|
+
function y(e, t, n) {
|
|
344
|
+
let r = e.octave * 7 + d.indexOf(e.step) + t.diatonic, i = Math.floor(r / 7), a = d[r - i * 7], o = m(e) + t.semitones, s = o - m({
|
|
345
|
+
step: a,
|
|
346
|
+
octave: i,
|
|
347
|
+
alter: 0
|
|
348
|
+
});
|
|
349
|
+
return Math.abs(s) <= 2 ? {
|
|
350
|
+
pitch: {
|
|
351
|
+
step: a,
|
|
352
|
+
octave: i,
|
|
353
|
+
alter: s
|
|
354
|
+
},
|
|
355
|
+
respelled: !1
|
|
356
|
+
} : {
|
|
357
|
+
pitch: v(o, {
|
|
358
|
+
semitones: 0,
|
|
359
|
+
diatonic: 0
|
|
360
|
+
}, n),
|
|
361
|
+
respelled: !0
|
|
362
|
+
};
|
|
363
|
+
}
|
|
364
|
+
var b = (e, t) => y(e, t, 0).pitch;
|
|
365
|
+
function x(e, t) {
|
|
366
|
+
let n = (7 * t.semitones % 12 + 12) % 12;
|
|
367
|
+
n > 6 && (n -= 12);
|
|
368
|
+
let r = e + n;
|
|
369
|
+
return r > 7 ? r - 12 : r < -7 ? r + 12 : r;
|
|
370
|
+
}
|
|
371
|
+
var S = Object.freeze([
|
|
372
|
+
"alto-saxophone",
|
|
373
|
+
"tenor-saxophone",
|
|
374
|
+
"bari-saxophone",
|
|
375
|
+
"trumpet",
|
|
376
|
+
"trombone",
|
|
377
|
+
"flute",
|
|
378
|
+
"clarinet",
|
|
379
|
+
"violin",
|
|
380
|
+
"viola",
|
|
381
|
+
"cello",
|
|
382
|
+
"double-bass"
|
|
383
|
+
]);
|
|
384
|
+
//#endregion
|
|
385
|
+
//#region src/lib/range-fit-core.ts
|
|
386
|
+
function C(e, t) {
|
|
387
|
+
let n = /* @__PURE__ */ new Map();
|
|
388
|
+
e.forEach((e, t) => e.forEach((e) => n.set(e, t)));
|
|
389
|
+
let r = e.map((e, t) => t), i = (e) => r[e] === e ? e : r[e] = i(r[e]);
|
|
390
|
+
for (let [e, a] of t) {
|
|
391
|
+
let t = n.get(e), o = n.get(a);
|
|
392
|
+
if (t === void 0 || o === void 0) continue;
|
|
393
|
+
let [s, c] = [i(t), i(o)];
|
|
394
|
+
s !== c && (r[Math.max(s, c)] = Math.min(s, c));
|
|
395
|
+
}
|
|
396
|
+
let a = /* @__PURE__ */ new Map();
|
|
397
|
+
return e.forEach((e, t) => {
|
|
398
|
+
let n = i(t);
|
|
399
|
+
a.set(n, [...a.get(n) ?? [], ...e]);
|
|
400
|
+
}), [...a.values()];
|
|
401
|
+
}
|
|
402
|
+
function w(e, t) {
|
|
403
|
+
let n = /* @__PURE__ */ new Map(), r = (e) => {
|
|
404
|
+
let t = e;
|
|
405
|
+
for (; n.has(t);) t = n.get(t);
|
|
406
|
+
return t;
|
|
407
|
+
}, i = [], a = /* @__PURE__ */ new Set(), o = (e) => {
|
|
408
|
+
a.has(e) || (a.add(e), i.push(e));
|
|
409
|
+
};
|
|
410
|
+
for (let [t, i] of e) {
|
|
411
|
+
o(t), o(i);
|
|
412
|
+
let [e, a] = [r(t), r(i)];
|
|
413
|
+
e !== a && n.set(a, e);
|
|
414
|
+
}
|
|
415
|
+
let s = /* @__PURE__ */ new Map();
|
|
416
|
+
for (let e of i) {
|
|
417
|
+
let t = r(e);
|
|
418
|
+
s.set(t, [...s.get(t) ?? [], e]);
|
|
419
|
+
}
|
|
420
|
+
if (t) {
|
|
421
|
+
let e = new Map(t.map((e, t) => [e, t]));
|
|
422
|
+
for (let t of s.values()) t.sort((t, n) => (e.get(t) ?? Infinity) - (e.get(n) ?? Infinity));
|
|
423
|
+
}
|
|
424
|
+
return (e) => a.has(e) ? s.get(r(e)) : [e];
|
|
425
|
+
}
|
|
426
|
+
function T(e, t, n) {
|
|
427
|
+
let r = {}, i = [], a = [];
|
|
428
|
+
for (let t of e) for (let e of t) r[e.id] = 0;
|
|
429
|
+
if (!n || !t) return {
|
|
430
|
+
shifts: r,
|
|
431
|
+
bothWays: i,
|
|
432
|
+
stillOut: a
|
|
433
|
+
};
|
|
434
|
+
let o = (e) => ({
|
|
435
|
+
below: e.some((e) => e < t.low),
|
|
436
|
+
above: e.some((e) => e > t.high)
|
|
437
|
+
});
|
|
438
|
+
for (let t of e) {
|
|
439
|
+
let e = t.flatMap((e) => e.midi), n = t.map((e) => e.id), { below: s, above: c } = o(e);
|
|
440
|
+
if (s && c) {
|
|
441
|
+
i.push(n);
|
|
442
|
+
continue;
|
|
443
|
+
}
|
|
444
|
+
if (!s && !c) continue;
|
|
445
|
+
let l = s ? 12 : -12;
|
|
446
|
+
for (let e of n) r[e] = l;
|
|
447
|
+
let u = o(e.map((e) => e + l));
|
|
448
|
+
(u.below || u.above) && a.push(n);
|
|
449
|
+
}
|
|
450
|
+
return {
|
|
451
|
+
shifts: r,
|
|
452
|
+
bothWays: i,
|
|
453
|
+
stillOut: a
|
|
454
|
+
};
|
|
455
|
+
}
|
|
456
|
+
function E(e, t, n) {
|
|
457
|
+
let r = { ...e };
|
|
458
|
+
for (let e of Object.keys(t)) {
|
|
459
|
+
if (t[e] === void 0) continue;
|
|
460
|
+
let i = n(e), a = i.find((e) => t[e] !== void 0);
|
|
461
|
+
for (let e of i) r[e] = t[a];
|
|
462
|
+
}
|
|
463
|
+
return r;
|
|
464
|
+
}
|
|
465
|
+
//#endregion
|
|
466
|
+
export { x as _, S as a, t as c, h as d, m as f, y as g, b as h, w as i, u as l, _ as m, C as n, s as o, g as p, T as r, e as s, E as t, c as u, v };
|
|
467
|
+
|
|
468
|
+
//# sourceMappingURL=range-fit-core-B1rMWdI4.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"range-fit-core-B1rMWdI4.js","names":["INSTRUMENT_IDS","LEVELS","ranges","beginner","intermediate","advanced","CONCERT","OCTAVE","B_FLAT","INSTRUMENT_TABLE","info","INSTRUMENTS","instrumentName","id","GM_BLOCKS","instrumentFor","low","high","gmProgram","STEPS","SHARP_ORDER","SEMITONES","pitchMidi","p","keyAlter","fifths","step","spellMidi","candidates","octave","target","alter","single","direction","rank","a","b","spelledSoundingMidi","pitch","transposition","writtenPitch","soundingMidi","keyFifths","transposePitchSpelled","index","transposePitch","writtenKeyFifths","shift","concertFifths","EMBED_INSTRUMENTS","joinRuns","runOf","run","i","parent","runs","root","from","to","ties","ra","rb","merged","r","tieChainOf","appearance","seen","note","groups","order","chain","x","y","planShifts","shifts","bothWays","stillOut","phrase","phrases","autoRange","range","outside","midis","m","ids","below","above","after","applyOverrides","out","overrides","chainOf","owner"],"sources":["../src/lib/instrument-model.ts","../src/lib/range-fit-core.ts"],"sourcesContent":["/** The instrument model shared by the reader, the embeds and the editor (`pepperscore/instruments`); framework-free. */\n\n/** The viewer's instrument ids. */\nexport const INSTRUMENT_IDS = [\n 'piano', 'guitar', 'bassguitar', 'double-bass', 'drum-kit', 'alto-saxophone', 'tenor-saxophone', 'bari-saxophone',\n 'flute', 'clarinet', 'trumpet', 'trombone', 'violin', 'viola', 'cello', 'microphone',\n] as const;\nexport const LEVELS = ['beginner', 'intermediate', 'advanced'] as const;\n\nexport type InstrumentId = typeof INSTRUMENT_IDS[number];\nexport type RangeLevel = typeof LEVELS[number];\n/** An instrument a pitched part can be switched to: any but the drum kit (unpitched). */\nexport type SwitchInstrumentId = Exclude<InstrumentId, 'drum-kit'>;\nexport type Transposition = { semitones: number; diatonic: number };\nexport type InstrumentClef = 'treble' | 'bass' | 'alto' | 'tenor' | 'percussion' | 'treble8vb';\nexport type SpelledPitch = { step: 'A' | 'B' | 'C' | 'D' | 'E' | 'F' | 'G'; octave: number; alter: number };\nexport type InstrumentInfo = {\n id: InstrumentId;\n label: string;\n /** The name the editor's controls and status line use when shorter than `label` (\"Alto Sax\"). */\n short?: string;\n /** 1-based GM program (the viewer's voice program); the drum kit plays on channel 10, not a program. */\n gmProgram: number;\n clef: InstrumentClef;\n /** Written minus sounding. */\n transposition: Transposition;\n /** Playable range per level in sounding MIDI, inclusive; absent for unpitched instruments. */\n ranges?: Record<RangeLevel, { low: number; high: number }>;\n};\n\ntype Span = [number, number];\nconst ranges = (beginner: Span, intermediate: Span, advanced: Span): InstrumentInfo['ranges'] => Object.freeze({\n beginner: Object.freeze({ low: beginner[0], high: beginner[1] }),\n intermediate: Object.freeze({ low: intermediate[0], high: intermediate[1] }),\n advanced: Object.freeze({ low: advanced[0], high: advanced[1] }),\n});\nconst CONCERT: Transposition = Object.freeze({ semitones: 0, diatonic: 0 });\nconst OCTAVE: Transposition = Object.freeze({ semitones: 12, diatonic: 7 });\nconst B_FLAT: Transposition = Object.freeze({ semitones: 2, diatonic: 1 });\n\nconst INSTRUMENT_TABLE: Record<InstrumentId, InstrumentInfo> = {\n piano: { id: 'piano', label: 'Piano', gmProgram: 1, clef: 'treble', transposition: CONCERT, ranges: ranges([21, 108], [21, 108], [21, 108]) },\n guitar: { id: 'guitar', label: 'Guitar', gmProgram: 25, clef: 'treble', transposition: OCTAVE, ranges: ranges([40, 64], [40, 76], [40, 88]) },\n bassguitar: { id: 'bassguitar', label: 'Bass Guitar', gmProgram: 34, clef: 'bass', transposition: OCTAVE, ranges: ranges([28, 48], [28, 55], [28, 60]) },\n 'double-bass': { id: 'double-bass', label: 'Double Bass', gmProgram: 33, clef: 'bass', transposition: OCTAVE, ranges: ranges([28, 48], [28, 55], [28, 64]) },\n 'drum-kit': { id: 'drum-kit', label: 'Drum Kit', gmProgram: 1, clef: 'percussion', transposition: CONCERT },\n 'alto-saxophone': { id: 'alto-saxophone', label: 'Alto Saxophone', short: 'Alto Sax', gmProgram: 66, clef: 'treble', transposition: { semitones: 9, diatonic: 5 }, ranges: ranges([49, 69], [49, 77], [49, 81]) },\n 'tenor-saxophone': { id: 'tenor-saxophone', label: 'Tenor Saxophone', short: 'Tenor Sax', gmProgram: 67, clef: 'treble', transposition: { semitones: 14, diatonic: 8 }, ranges: ranges([44, 64], [44, 72], [44, 76]) },\n 'bari-saxophone': { id: 'bari-saxophone', label: 'Baritone Saxophone', short: 'Bari Sax', gmProgram: 68, clef: 'treble', transposition: { semitones: 21, diatonic: 12 }, ranges: ranges([37, 57], [37, 65], [36, 69]) },\n flute: { id: 'flute', label: 'Flute', gmProgram: 74, clef: 'treble', transposition: CONCERT, ranges: ranges([60, 84], [60, 91], [59, 96]) },\n clarinet: { id: 'clarinet', label: 'Clarinet', gmProgram: 72, clef: 'treble', transposition: B_FLAT, ranges: ranges([50, 74], [50, 82], [50, 91]) },\n trumpet: { id: 'trumpet', label: 'Trumpet', gmProgram: 57, clef: 'treble', transposition: B_FLAT, ranges: ranges([55, 72], [54, 79], [52, 86]) },\n trombone: { id: 'trombone', label: 'Trombone', gmProgram: 58, clef: 'bass', transposition: CONCERT, ranges: ranges([46, 65], [40, 70], [34, 77]) },\n violin: { id: 'violin', label: 'Violin', gmProgram: 41, clef: 'treble', transposition: CONCERT, ranges: ranges([55, 81], [55, 91], [55, 105]) },\n viola: { id: 'viola', label: 'Viola', gmProgram: 42, clef: 'alto', transposition: CONCERT, ranges: ranges([48, 76], [48, 84], [48, 96]) },\n cello: { id: 'cello', label: 'Cello', gmProgram: 43, clef: 'bass', transposition: CONCERT, ranges: ranges([36, 64], [36, 76], [36, 88]) },\n microphone: { id: 'microphone', label: 'Voice', gmProgram: 54, clef: 'treble', transposition: CONCERT, ranges: ranges([48, 72], [45, 76], [40, 81]) },\n};\nfor (const info of Object.values(INSTRUMENT_TABLE)) { Object.freeze(info.transposition); Object.freeze(info); }\n/** The model's instruments by id (frozen). */\nexport const INSTRUMENTS: Readonly<Record<InstrumentId, Readonly<InstrumentInfo>>> = Object.freeze(INSTRUMENT_TABLE);\n\n/** The instrument's short name for controls and the status line (`short`, else `label`). */\nexport const instrumentName = (id: InstrumentId): string => INSTRUMENTS[id].short ?? INSTRUMENTS[id].label;\n\n/**\n * GM program blocks (1-based, inclusive) and the instrument nearest each, after the viewer's\n * GM manifest; programs outside every block (synths, ethnic, effects) fall back to piano.\n */\nconst GM_BLOCKS: [number, number, InstrumentId][] = [\n [1, 24, 'piano'], [25, 32, 'guitar'], [33, 33, 'double-bass'], [34, 40, 'bassguitar'],\n [41, 41, 'violin'], [42, 42, 'viola'], [43, 43, 'cello'], [44, 44, 'double-bass'], [45, 52, 'violin'],\n [53, 55, 'microphone'], [57, 57, 'trumpet'], [58, 59, 'trombone'], [60, 60, 'trumpet'], [61, 61, 'trombone'], [62, 64, 'trumpet'],\n [65, 66, 'alto-saxophone'], [67, 67, 'tenor-saxophone'], [68, 68, 'bari-saxophone'], [69, 72, 'clarinet'], [73, 80, 'flute'],\n];\n\n/** The instrument nearest a 1-based GM program; piano when none is near. */\nexport function instrumentFor(gmProgram: number): Readonly<InstrumentInfo> {\n const block = GM_BLOCKS.find(([low, high]) => gmProgram >= low && gmProgram <= high);\n return INSTRUMENTS[block?.[2] ?? 'piano'];\n}\n\nconst STEPS = ['C', 'D', 'E', 'F', 'G', 'A', 'B'] as const;\nconst SHARP_ORDER = ['F', 'C', 'G', 'D', 'A', 'E', 'B'];\nconst SEMITONES: Record<SpelledPitch['step'], number> = { C: 0, D: 2, E: 4, F: 5, G: 7, A: 9, B: 11 };\n\n/** The MIDI number of a pitch (C4 = 60). */\nexport const pitchMidi = (p: SpelledPitch): number => (p.octave + 1) * 12 + SEMITONES[p.step] + p.alter;\n\n/** The alteration the key signature (`fifths`) gives `step`. */\nexport function keyAlter(step: SpelledPitch['step'], fifths: number): number {\n if (fifths > 0) return SHARP_ORDER.indexOf(step) < fifths ? 1 : 0;\n if (fifths < 0) return SHARP_ORDER.length - 1 - SHARP_ORDER.indexOf(step) < -fifths ? -1 : 0;\n return 0;\n}\n\n/**\n * The spelling of MIDI note `target`: the key signature's (`fifths`) spelling if it has one, else the\n * natural, else a sharp going up (`direction` >= 0) or a flat going down, else the other single\n * accidental, else a double.\n */\nexport function spellMidi(target: number, fifths: number, direction: number): SpelledPitch | undefined {\n const candidates: SpelledPitch[] = [];\n for (const step of STEPS) {\n for (let octave = Math.floor(target / 12) - 2; octave <= Math.floor(target / 12); octave++) {\n const alter = target - pitchMidi({ step, octave, alter: 0 });\n if (alter >= -2 && alter <= 2) candidates.push({ step, octave, alter });\n }\n }\n const single = direction >= 0 ? 1 : -1;\n const rank = (p: SpelledPitch) => (p.alter === keyAlter(p.step, fifths) ? 0 : p.alter === 0 ? 1 : p.alter === single ? 2 : p.alter === -single ? 3 : 4);\n return candidates.sort((a, b) => rank(a) - rank(b))[0];\n}\n\n/** The sounding MIDI number of a written pitch on an instrument with `transposition` (written minus sounding). */\nexport function spelledSoundingMidi(pitch: SpelledPitch, transposition: { semitones: number }): number {\n return pitchMidi(pitch) - transposition.semitones;\n}\n\n/**\n * The written pitch of sounding MIDI `soundingMidi` for an instrument with `transposition`, spelled for the\n * written key `keyFifths`: the key's own accidentals first, then naturals, then sharps for chromatic notes in\n * sharp keys and C major, flats in flat keys. Only `semitones` is used: a MIDI number carries no spelling to\n * move by the diatonic interval.\n */\nexport function writtenPitch(soundingMidi: number, transposition: Transposition, keyFifths: number): SpelledPitch {\n const target = soundingMidi + transposition.semitones;\n // Every MIDI number has a natural or single-accidental spelling, so spellMidi always finds one.\n return spellMidi(target, keyFifths, keyFifths < 0 ? -1 : 1)!;\n}\n\n/**\n * `pitch` moved by `t`, keeping its spelling: the step moves by `diatonic` (carrying the octave) and the alter\n * is whatever makes the MIDI number move by `semitones`. When that alter would pass a double accidental the\n * note is respelled with `writtenPitch` for the key `keyFifths` and `respelled` is true.\n */\nexport function transposePitchSpelled(pitch: SpelledPitch, t: Transposition, keyFifths: number): { pitch: SpelledPitch; respelled: boolean } {\n const index = pitch.octave * 7 + STEPS.indexOf(pitch.step) + t.diatonic;\n const octave = Math.floor(index / 7);\n const step = STEPS[index - octave * 7];\n const target = pitchMidi(pitch) + t.semitones;\n const alter = target - pitchMidi({ step, octave, alter: 0 });\n if (Math.abs(alter) <= 2) return { pitch: { step, octave, alter }, respelled: false };\n return { pitch: writtenPitch(target, { semitones: 0, diatonic: 0 }, keyFifths), respelled: true };\n}\n\n/** `pitch` moved by `t`, keeping its spelling (see `transposePitchSpelled`; the fallback spells for C major). */\nexport const transposePitch = (pitch: SpelledPitch, t: Transposition): SpelledPitch => transposePitchSpelled(pitch, t, 0).pitch;\n\n/**\n * The written key (fifths) of music in concert key `concertFifths` shown with `transposition` (written minus\n * sounding): the transposition as fifths, `(7 * semitones) mod 12` normalised to -6..6, added and wrapped\n * back into -7..7. Alto sax (+9 semitones) is +3 fifths; a B-flat instrument +2.\n */\nexport function writtenKeyFifths(concertFifths: number, transposition: Transposition): number {\n let shift = (((7 * transposition.semitones) % 12) + 12) % 12;\n if (shift > 6) shift -= 12;\n const fifths = concertFifths + shift;\n return fifths > 7 ? fifths - 12 : fifths < -7 ? fifths + 12 : fifths;\n}\n\n/** The instruments the embeds offer, in switch order (frozen). */\nexport const EMBED_INSTRUMENTS: readonly InstrumentId[] = Object.freeze([\n 'alto-saxophone', 'tenor-saxophone', 'bari-saxophone', 'trumpet', 'trombone', 'flute', 'clarinet', 'violin', 'viola', 'cello', 'double-bass',\n] as const);\n","// Schema-free range-fit rules shared by the editor and the reader: both build phrases and ties from their\n// own score model and hand them here as plain event ids and MIDI numbers.\n\nexport type Shift = 0 | 12 | -12;\n/** One event (note or chord): its notes' judged MIDI (sounding plus interval). */\nexport type FitEvent = { id: string; midi: number[] };\n\n/** Merges runs of event ids that a tie links (`[from, to]`), keeping the first run's position. */\nexport function joinRuns(runs: string[][], ties: [string, string][]): string[][] {\n const runOf = new Map<string, number>();\n runs.forEach((run, i) => run.forEach((id) => runOf.set(id, i)));\n const parent = runs.map((_, i) => i);\n const root = (i: number): number => (parent[i] === i ? i : (parent[i] = root(parent[i])));\n for (const [from, to] of ties) {\n const a = runOf.get(from), b = runOf.get(to);\n if (a === undefined || b === undefined) continue;\n const [ra, rb] = [root(a), root(b)];\n if (ra !== rb) parent[Math.max(ra, rb)] = Math.min(ra, rb);\n }\n const merged = new Map<number, string[]>();\n runs.forEach((run, i) => {\n const r = root(i);\n merged.set(r, [...(merged.get(r) ?? []), ...run]);\n });\n return [...merged.values()];\n}\n\n/** The ordered chain of events the ties link around `id` (itself alone when untied), in `order` (event order) when given, else by first appearance in the ties. */\nexport function tieChainOf(ties: [string, string][], order?: string[]): (id: string) => string[] {\n const parent = new Map<string, string>();\n const root = (id: string): string => { let r = id; while (parent.has(r)) r = parent.get(r)!; return r; };\n const appearance: string[] = [];\n const seen = new Set<string>();\n const note = (id: string) => { if (!seen.has(id)) { seen.add(id); appearance.push(id); } };\n for (const [from, to] of ties) {\n note(from); note(to);\n const [a, b] = [root(from), root(to)];\n if (a !== b) parent.set(b, a);\n }\n const groups = new Map<string, string[]>();\n for (const id of appearance) {\n const r = root(id);\n groups.set(r, [...(groups.get(r) ?? []), id]);\n }\n if (order) {\n const rank = new Map(order.map((id, i) => [id, i]));\n for (const chain of groups.values()) chain.sort((x, y) => (rank.get(x) ?? Infinity) - (rank.get(y) ?? Infinity));\n }\n return (id) => (seen.has(id) ? groups.get(root(id))! : [id]);\n}\n\nexport type ShiftPlan = { shifts: Record<string, Shift>; bothWays: string[][]; stillOut: string[][] };\n\n/**\n * Plans an octave per phrase: any note below the range moves every event up, above moves it down, both\n * leaves the phrase (listed in `bothWays`); a phrase still out after its move keeps it (listed in\n * `stillOut`). A chord is out when any of its notes is. No range or `autoRange` off plans no shifts.\n */\nexport function planShifts(phrases: FitEvent[][], range: { low: number; high: number } | undefined, autoRange: boolean): ShiftPlan {\n const shifts: Record<string, Shift> = {};\n const bothWays: string[][] = [];\n const stillOut: string[][] = [];\n for (const phrase of phrases) for (const e of phrase) shifts[e.id] = 0;\n if (!autoRange || !range) return { shifts, bothWays, stillOut };\n const outside = (midis: number[]) => ({ below: midis.some((m) => m < range.low), above: midis.some((m) => m > range.high) });\n for (const phrase of phrases) {\n const midis = phrase.flatMap((e) => e.midi);\n const ids = phrase.map((e) => e.id);\n const { below, above } = outside(midis);\n if (below && above) { bothWays.push(ids); continue; }\n if (!below && !above) continue;\n const shift: Shift = below ? 12 : -12;\n for (const id of ids) shifts[id] = shift;\n const after = outside(midis.map((m) => m + shift));\n if (after.below || after.above) stillOut.push(ids);\n }\n return { shifts, bothWays, stillOut };\n}\n\n/** Sets single events from the user's overrides, each extended along its tie chain (the first override on a chain wins); overrides beat planned shifts. */\nexport function applyOverrides(shifts: Record<string, Shift>, overrides: Record<string, Shift>, chainOf: (id: string) => string[]): Record<string, Shift> {\n const out = { ...shifts };\n for (const id of Object.keys(overrides)) {\n if (overrides[id] === undefined) continue;\n const chain = chainOf(id);\n const owner = chain.find((e) => overrides[e] !== undefined)!;\n for (const e of chain) out[e] = overrides[owner];\n }\n return out;\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Files pepperscore loads at runtime instead of bundling them: Verovio (LGPL-3.0-or-later, kept as upstream's own
|
|
3
|
+
* separately replaceable files) and the third-party notices. The build (vite.config.ts) writes them to dist/verovio/
|
|
4
|
+
* and dist/THIRD_PARTY_NOTICES.txt.
|
|
5
|
+
*
|
|
6
|
+
* Keep this file at the root of src/: its code lands in dist/index.js, so `./` is dist/. The library build must not
|
|
7
|
+
* resolve these URLs (`@vite-ignore`; lib mode would inline the files as data URLs); its runtime-files plugin then
|
|
8
|
+
* turns them back into plain `new URL('./…', import.meta.url)` in dist/index.js, the pattern host bundlers (Vite,
|
|
9
|
+
* Astro) recognise to copy the files as assets. scripts/finalize-dist.mjs fails the build if they do not survive.
|
|
10
|
+
*/
|
|
11
|
+
import type { VerovioFiles } from './lib/verovio-protocol';
|
|
12
|
+
/** The Verovio files shipped with pepperscore. */
|
|
13
|
+
export declare const bundledVerovioFiles: () => VerovioFiles;
|
|
14
|
+
/** The third-party notices shipped with pepperscore (linked from the drawer's Licences entry). */
|
|
15
|
+
export declare const thirdPartyNoticesUrl: () => string;
|
|
@@ -52,15 +52,37 @@ async function a(e, { url: n, drums: a, program: o, preset: s, destination: c })
|
|
|
52
52
|
} catch (e) {
|
|
53
53
|
throw g.dispose(), h.disconnect(), e;
|
|
54
54
|
}
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
55
|
+
f && (h.gain.value = 1 / Math.sqrt(Math.max(1, ...Array.from({ length: 128 }, (e, t) => p.zones.filter((e) => e.keyRange.lo <= t && t <= e.keyRange.hi).length))));
|
|
56
|
+
let _ = /* @__PURE__ */ new Map(), v = 0, y = () => {
|
|
57
|
+
for (let e of [..._.keys()]) e();
|
|
58
|
+
_.clear(), g.stop();
|
|
59
|
+
}, b = new Set(p.zones.flatMap(({ keyRange: { lo: e, hi: t } = {
|
|
60
|
+
lo: 0,
|
|
61
|
+
hi: 127
|
|
62
|
+
} }) => Array.from({ length: Math.max(0, t - e + 1) }, (t, n) => e + n)));
|
|
63
|
+
return {
|
|
64
|
+
start: ({ note: t, time: n, duration: r, velocity: i }) => {
|
|
65
|
+
let a = e.currentTime;
|
|
66
|
+
for (let [e, t] of _) t < a && _.delete(e);
|
|
67
|
+
let o = g.start({
|
|
68
|
+
note: t,
|
|
69
|
+
time: n,
|
|
70
|
+
duration: r,
|
|
71
|
+
velocity: i,
|
|
72
|
+
stopId: `n${v++}`
|
|
73
|
+
}), s = () => {
|
|
74
|
+
_.delete(s), o();
|
|
75
|
+
};
|
|
76
|
+
return _.set(s, Math.max(n, a) + r + 2), s;
|
|
77
|
+
},
|
|
78
|
+
stop: y,
|
|
58
79
|
dispose: () => {
|
|
59
|
-
g.dispose(), h.disconnect();
|
|
60
|
-
}
|
|
80
|
+
y(), g.dispose(), h.disconnect();
|
|
81
|
+
},
|
|
82
|
+
covers: (e) => b.has(e)
|
|
61
83
|
};
|
|
62
84
|
}
|
|
63
85
|
//#endregion
|
|
64
86
|
export { a as loadSf2Player };
|
|
65
87
|
|
|
66
|
-
//# sourceMappingURL=sf2-player-
|
|
88
|
+
//# sourceMappingURL=sf2-player-oWC6yrUH.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sf2-player-oWC6yrUH.js","names":["soundfonts","parsedSoundfont","cached","url","response","buffer","soundfont2","LAYERED","layeredInstrument","zones","preset","presetZone","lo","zone","hi","layer","findPreset","presets","item","drums","program","loadSf2Player","smplrInstrument","soundfont","match","instrument","Sf2Sampler","sf2InstrumentToPreset","options","ctx","smplr","json","buffers","output","context","destination","sampler","error","note","pending","nextId","stopAll","stop","covered","i","now","end","handle","time","duration"],"sources":["../src/lib/sf2-player.ts"],"sourcesContent":["import type { Instrument, InstrumentZone, Preset, SoundFont2 } from 'soundfont2';\nimport type { AudioPlayer } from './sound-players';\n\nconst soundfonts = new Map<string, Promise<SoundFont2>>();\n\n/**\n * Each SF2 is downloaded and parsed once per URL. Every program, part and instance builds its player from the same\n * parsed soundfont (read-only here), so disposing one player never touches data another is using.\n */\nfunction parsedSoundfont(url: string): Promise<SoundFont2> {\n let cached = soundfonts.get(url);\n if (!cached) {\n cached = Promise.all([\n fetch(url).then(response => {\n if (!response.ok) throw new Error(`Could not load the soundfont (${response.status}).`);\n return response.arrayBuffer();\n }),\n import('soundfont2'),\n ]).then(([buffer, { default: soundfont2 }]) => new soundfont2.SoundFont2(new Uint8Array(buffer)));\n cached.catch(() => soundfonts.delete(url));\n soundfonts.set(url, cached);\n }\n return cached;\n}\n\n/** Name of the synthetic instrument that layers every instrument zone of the chosen preset. */\nconst LAYERED = '\\u0000pepperscore-preset';\n\n/**\n * smplr's Soundfont2 plays one SF2 instrument, but a GM preset often layers several (TimGM6mb's Standard kit is\n * Standard0 + Standard1, its strings stack six). This merges them into one instrument, clipped to each preset zone's key\n * range; smplr then sounds every region that matches a note. Sample names get a layer prefix because smplr keys its\n * buffers by name. Velocity ranges, pan and attenuation are not applied (smplr's SF2 conversion ignores them).\n */\nfunction layeredInstrument(preset: Preset): Instrument {\n const zones = preset.zones.flatMap((presetZone, layer) => (presetZone.instrument?.zones ?? []).flatMap((zone): InstrumentZone[] => {\n const lo = Math.max(zone.keyRange?.lo ?? 0, presetZone.keyRange?.lo ?? 0);\n const hi = Math.min(zone.keyRange?.hi ?? 127, presetZone.keyRange?.hi ?? 127);\n if (!zone.sample || lo > hi) return [];\n return [{ ...zone, keyRange: { lo, hi }, sample: { ...zone.sample, header: { ...zone.sample.header, name: `${layer}:${zone.sample.header.name}` } } }];\n }));\n return { header: { name: LAYERED, bagIndex: -1 }, zones };\n}\n\n/** The GM preset: bank 128 preset 0 (Standard kit) for drums, else bank 0 preset `program - 1`; or a preset named `preset`. */\nconst findPreset = (presets: Preset[], drums: boolean, program = 1, preset?: string) =>\n presets.find(item => preset ? item.header.name === preset : drums ? item.header.bank === 128 && item.header.preset === 0 : item.header.bank === 0 && item.header.preset === program - 1);\n\nexport type Sf2Options = { url: string; drums: boolean; program?: number; preset?: string; destination: AudioNode };\n\n/** A player for one preset of an SF2. `preset` names an SF2 preset, or failing that a single SF2 instrument. */\nexport async function loadSf2Player(context: AudioContext, { url, drums, program, preset, destination }: Sf2Options): Promise<AudioPlayer> {\n const [{ Instrument: smplrInstrument, sf2InstrumentToPreset }, soundfont] = await Promise.all([import('smplr'), parsedSoundfont(url)]);\n const match = findPreset(soundfont.presets, drums, program, preset);\n const instrument = match ? layeredInstrument(match) : preset ? soundfont.instruments.find(item => item.header.name === preset) : undefined;\n if (!instrument) throw new Error(preset ? `The soundfont has no preset or instrument named \"${preset}\".` : drums ? 'The soundfont has no standard drum kit.' : `The soundfont has no instrument for GM program ${program}.`);\n // smplr's own Soundfont2 fetches and parses the file per sampler; this plugin only turns the shared instrument into samples.\n const Sf2Sampler = smplrInstrument<{ instrument: Instrument }>((ctx, options, smplr) => {\n const { json, buffers } = sf2InstrumentToPreset(options.instrument, ctx);\n return smplr.loadInstrument(json, buffers);\n });\n const output = context.createGain();\n output.connect(destination);\n const sampler = Sf2Sampler(context, { instrument, destination: output });\n try { await sampler.ready; } catch (error) { sampler.dispose(); output.disconnect(); throw error; }\n // Stacked layers add up: scale by 1/sqrt(the most regions any one note sounds) so the preset sits near single-layer\n // ones. A global approximation: notes with fewer layers are scaled by the same amount.\n if (match) output.gain.value = 1 / Math.sqrt(Math.max(1, ...Array.from({ length: 128 }, (_, note) => instrument.zones.filter(zone => zone.keyRange!.lo <= note && note <= zone.keyRange!.hi).length)));\n // smplr queues a note more than its 200 ms lookahead ahead in its own scheduler, and its argument-less stop() only\n // stops sounding voices: queued notes would still play after a stop. So every start keeps its own stop handle (with a\n // unique stopId, since smplr's handle stops every voice sharing the id, which defaults to the pitch), and stop() calls\n // them all. Handles are dropped once their note has ended.\n const pending = new Map<() => void, number>();\n let nextId = 0;\n const release = 2; // seconds after a note's end before its handle is forgotten (covers smplr's release tail)\n const stopAll = () => { for (const stop of [...pending.keys()]) stop(); pending.clear(); sampler.stop(); };\n // Notes some zone sounds (a zone without a key range covers every key).\n const covered = new Set(instrument.zones.flatMap(({ keyRange: { lo, hi } = { lo: 0, hi: 127 } }) => Array.from({ length: Math.max(0, hi - lo + 1) }, (_, i) => lo + i)));\n return {\n start: ({ note, time, duration, velocity }) => {\n const now = context.currentTime;\n for (const [stop, end] of pending) if (end < now) pending.delete(stop);\n const handle = sampler.start({ note, time, duration, velocity, stopId: `n${nextId++}` });\n const stop = () => { pending.delete(stop); handle(); };\n pending.set(stop, Math.max(time, now) + duration + release);\n return stop;\n },\n stop: stopAll,\n dispose: () => { stopAll(); sampler.dispose(); output.disconnect(); },\n covers: note => covered.has(note),\n };\n}\n"],"mappings":";AAGA,IAAMA,oBAAa,IAAI,IAAiC;AAMxD,SAASC,EAAgB,GAAkC;CACzD,IAAIC,IAASF,EAAW,IAAIG,CAAG;CAY/B,OAXKD,MACH,IAAS,QAAQ,IAAI,CACnB,MAAMC,CAAG,CAAC,CAAC,MAAK,MAAY;EAC1B,IAAI,CAACC,EAAS,IAAI,MAAU,MAAM,iCAAiCA,EAAS,OAAO,GAAG;EACtF,OAAOA,EAAS,YAAY;CAC9B,CAAC,GACD,OAAO,aACT,CAAC,CAAC,CAAC,MAAM,CAACC,GAAQ,EAAE,SAASC,SAAkB,IAAIA,EAAW,WAAW,IAAI,WAAWD,CAAM,CAAC,CAAC,GAChGH,EAAO,YAAYF,EAAW,OAAOG,CAAG,CAAC,GACzCH,EAAW,IAAIG,GAAKD,CAAM,IAErBA;AACT;AAGA,IAAMK,IAAU;AAQhB,SAASC,EAAkB,GAA4B;CACrD,IAAMC,IAAQC,EAAO,MAAM,SAAS,GAAY,OAAWC,EAAW,YAAY,SAAS,CAAC,EAAA,CAAG,SAAS,MAA2B;EACjI,IAAMC,IAAK,KAAK,IAAIC,EAAK,UAAU,MAAM,GAAGF,EAAW,UAAU,MAAM,CAAC,GAClEG,IAAK,KAAK,IAAID,EAAK,UAAU,MAAM,KAAKF,EAAW,UAAU,MAAM,GAAG;EAE5E,OADI,CAACE,EAAK,UAAUD,IAAKE,IAAW,CAAC,IAC9B,CAAC;GAAE,GAAGD;GAAM,UAAU;IAAE;IAAI;GAAG;GAAG,QAAQ;IAAE,GAAGA,EAAK;IAAQ,QAAQ;KAAE,GAAGA,EAAK,OAAO;KAAQ,MAAM,GAAGE,EAAM,GAAGF,EAAK,OAAO,OAAO;IAAO;GAAE;EAAE,CAAC;CACvJ,CAAC,CAAC;CACF,OAAO;EAAE,QAAQ;GAAE,MAAMN;GAAS,UAAU;EAAG;EAAG;CAAM;AAC1D;AAGA,IAAMS,KAAc,GAAmB,GAAgB,IAAU,GAAG,MAClEC,EAAQ,MAAK,MAAQP,IAASQ,EAAK,OAAO,SAASR,IAASS,IAAQD,EAAK,OAAO,SAAS,OAAOA,EAAK,OAAO,WAAW,IAAIA,EAAK,OAAO,SAAS,KAAKA,EAAK,OAAO,WAAWE,IAAU,CAAC;AAKzL,eAAsBC,EAAc,GAAuB,EAAE,QAAK,UAAO,YAAS,WAAQ,kBAAiD;CACzI,IAAM,CAAC,EAAE,YAAYC,GAAiB,4BAAyBC,KAAa,MAAM,QAAQ,IAAI,CAAC,OAAO,UAAUtB,EAAgBE,CAAG,CAAC,CAAC,GAC/HqB,IAAQR,EAAWO,EAAU,SAASJ,GAAOC,GAASV,CAAM,GAC5De,IAAaD,IAAQhB,EAAkBgB,CAAK,IAAId,IAASa,EAAU,YAAY,MAAK,MAAQL,EAAK,OAAO,SAASR,CAAM,IAAI,KAAA;CACjI,IAAI,CAACe,GAAY,MAAU,MAAMf,IAAS,oDAAoDA,EAAO,MAAMS,IAAQ,4CAA4C,kDAAkDC,EAAQ,EAAE;CAE3N,IAAMM,IAAaJ,GAA6C,GAAK,GAAS,MAAU;EACtF,IAAM,EAAE,SAAM,eAAYK,EAAsBC,EAAQ,YAAYC,CAAG;EACvE,OAAOC,EAAM,eAAeC,GAAMC,CAAO;CAC3C,CAAC,GACKC,IAASC,EAAQ,WAAW;CAClC,EAAO,QAAQC,CAAW;CAC1B,IAAMC,IAAUV,EAAWQ,GAAS;EAAE;EAAY,aAAaD;CAAO,CAAC;CACvE,IAAI;EAAE,MAAMG,EAAQ;CAAO,SAASC,GAAO;EAA0C,MAAxCD,EAAQ,QAAQ,GAAGH,EAAO,WAAW,GAASI;CAAO;CAGlG,AAAIb,MAAO,EAAO,KAAK,QAAQ,IAAI,KAAK,KAAK,KAAK,IAAI,GAAG,GAAG,MAAM,KAAK,EAAE,QAAQ,IAAI,IAAI,GAAG,MAASC,EAAW,MAAM,QAAO,MAAQZ,EAAK,SAAU,MAAMyB,KAAQA,KAAQzB,EAAK,SAAU,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC;CAKrM,IAAM0B,oBAAU,IAAI,IAAwB,GACxCC,IAAS,GAEPC,UAAgB;EAAE,KAAK,IAAMC,KAAQ,CAAC,GAAGH,EAAQ,KAAK,CAAC,GAAG,EAAK;EAAoB,AAAjBA,EAAQ,MAAM,GAAGH,EAAQ,KAAK;CAAG,GAEnGO,IAAU,IAAI,IAAIlB,EAAW,MAAM,SAAS,EAAE,UAAU,EAAE,OAAI,UAAO;EAAE,IAAI;EAAG,IAAI;CAAI,QAAQ,MAAM,KAAK,EAAE,QAAQ,KAAK,IAAI,GAAGX,IAAKF,IAAK,CAAC,EAAE,IAAI,GAAG,MAAMA,IAAKgC,CAAC,CAAC,CAAC;CACvK,OAAO;EACL,QAAQ,EAAE,SAAM,SAAM,aAAU,kBAAe;GAC7C,IAAMC,IAAMX,EAAQ;GACpB,KAAK,IAAM,CAACQ,GAAMI,MAAQP,GAAS,AAAIO,IAAMD,KAAKN,EAAQ,OAAOG,CAAI;GACrE,IAAMK,IAASX,EAAQ,MAAM;IAAE;IAAM;IAAM;IAAU;IAAU,QAAQ,IAAI;GAAW,CAAC,GACjFM,UAAa;IAAwB,AAAtBH,EAAQ,OAAOG,CAAI,GAAGK,EAAO;GAAG;GAErD,OADAR,EAAQ,IAAIG,GAAM,KAAK,IAAIM,GAAMH,CAAG,IAAII,IAAW,CAAO,GACnDP;EACT;EACA,MAAMD;EACN,eAAe;GAAgC,AAA9BA,EAAQ,GAAGL,EAAQ,QAAQ,GAAGH,EAAO,WAAW;EAAG;EACpE,SAAQ,MAAQU,EAAQ,IAAIL,CAAI;CAClC;AACF"}
|