smplr 0.4.2 → 0.5.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/README.md +39 -3
- package/dist/index.d.ts +9 -7
- package/dist/index.js +25 -12
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +23 -11
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -126,6 +126,22 @@ const now = context.currentTime;
|
|
|
126
126
|
});
|
|
127
127
|
```
|
|
128
128
|
|
|
129
|
+
### onEnded event
|
|
130
|
+
|
|
131
|
+
You can add a `onEnded` callback that will be invoked when the note ends:
|
|
132
|
+
|
|
133
|
+
```js
|
|
134
|
+
piano.start({
|
|
135
|
+
note: "C4",
|
|
136
|
+
duration: 1,
|
|
137
|
+
onEnded: () => {
|
|
138
|
+
// will be called after 1 second
|
|
139
|
+
},
|
|
140
|
+
});
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
The callback will receive as parameter the same object you pass to the `start` function;
|
|
144
|
+
|
|
129
145
|
### Change volume
|
|
130
146
|
|
|
131
147
|
`setVolume` uses a scale where 0 means no volume, and 127 is max volume without amplification:
|
|
@@ -178,16 +194,36 @@ A Soundfont player. By default it loads audio from Benjamin Gleitzman's package
|
|
|
178
194
|
[pre-rendered sound fonts](https://github.com/gleitz/midi-js-soundfonts).
|
|
179
195
|
|
|
180
196
|
```js
|
|
181
|
-
import { Soundfont,
|
|
197
|
+
import { Soundfont, getSoundfontNames } from "smplr";
|
|
182
198
|
|
|
183
199
|
const marimba = new Soundfont(new AudioContext(), { instrument: "marimba" });
|
|
184
200
|
marimba.start({ note: "C4" });
|
|
185
201
|
```
|
|
186
202
|
|
|
187
|
-
Use `getSoundfontInstrumentNames` to get all available instrument names.
|
|
188
|
-
|
|
189
203
|
It's intended to be a modern replacement of [soundfont-player](https://github.com/danigb/soundfont-player)
|
|
190
204
|
|
|
205
|
+
#### Soundfont instruments and kits
|
|
206
|
+
|
|
207
|
+
Use `getSoundfontNames` to get all available instrument names.
|
|
208
|
+
|
|
209
|
+
Two kits are available: `MusyngKit` or `FluidR3_GM`. The first is used by default: it sounds better but it weights more.
|
|
210
|
+
|
|
211
|
+
```js
|
|
212
|
+
const marimba = new Soundfont(context, {
|
|
213
|
+
instrument: "clavinet",
|
|
214
|
+
kit: "FluidR3_GM", // "MusyngKit" is used by default if not specified
|
|
215
|
+
});
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
Alternatively, you can pass your custom url as the instrument. In that case, the `kit` is ignored:
|
|
219
|
+
|
|
220
|
+
```js
|
|
221
|
+
const marimba = new Soundfont(context, {
|
|
222
|
+
instrument:
|
|
223
|
+
"https://gleitz.github.io/midi-js-soundfonts/MusyngKite/marimba-mp3.js",
|
|
224
|
+
});
|
|
225
|
+
```
|
|
226
|
+
|
|
191
227
|
### Piano
|
|
192
228
|
|
|
193
229
|
A sampled acoustic piano. It uses Steinway samples with 4 velocity layers from
|
package/dist/index.d.ts
CHANGED
|
@@ -48,14 +48,15 @@ type SamplerConfig = {
|
|
|
48
48
|
noteToSample: (note: SamplerNote, buffers: AudioBuffers, config: SamplerConfig) => [string | number, number];
|
|
49
49
|
};
|
|
50
50
|
type SamplerNote = {
|
|
51
|
+
decayTime?: number;
|
|
52
|
+
detune?: number;
|
|
53
|
+
duration?: number;
|
|
54
|
+
lpfCutoffHz?: number;
|
|
51
55
|
note: string | number;
|
|
56
|
+
onEnded?: (note: SamplerNote | string | number) => void;
|
|
52
57
|
stopId?: string | number;
|
|
53
58
|
time?: number;
|
|
54
|
-
duration?: number;
|
|
55
|
-
decayTime?: number;
|
|
56
|
-
detune?: number;
|
|
57
59
|
velocity?: number;
|
|
58
|
-
lpfCutoffHz?: number;
|
|
59
60
|
};
|
|
60
61
|
/**
|
|
61
62
|
* A Sampler instrument
|
|
@@ -214,7 +215,7 @@ declare class Reverb {
|
|
|
214
215
|
}
|
|
215
216
|
|
|
216
217
|
type SoundfontConfig = {
|
|
217
|
-
kit: "FluidR3_GM" | "MusyngKite";
|
|
218
|
+
kit: "FluidR3_GM" | "MusyngKite" | string;
|
|
218
219
|
instrument: string;
|
|
219
220
|
destination: AudioNode;
|
|
220
221
|
detune: number;
|
|
@@ -229,7 +230,8 @@ declare class Soundfont extends Sampler {
|
|
|
229
230
|
instrument: string;
|
|
230
231
|
});
|
|
231
232
|
}
|
|
232
|
-
declare function
|
|
233
|
+
declare function getSoundfontKits(): string[];
|
|
234
|
+
declare function getSoundfontNames(): string[];
|
|
233
235
|
|
|
234
236
|
/**
|
|
235
237
|
* Splendid Grand Piano options
|
|
@@ -258,4 +260,4 @@ declare const LAYERS: ({
|
|
|
258
260
|
cutoff?: undefined;
|
|
259
261
|
})[];
|
|
260
262
|
|
|
261
|
-
export { DrumMachine, DrumMachineConfig, ElectricPiano, LAYERS, Mallet, NAME_TO_PATH, Reverb, Sampler, SamplerAudioLoader, SamplerConfig, SamplerNote, Soundfont, SoundfontConfig, SplendidGrandPiano, SplendidGrandPianoConfig, getDrumMachineNames, getElectricPianoNames, getMalletNames,
|
|
263
|
+
export { DrumMachine, DrumMachineConfig, ElectricPiano, LAYERS, Mallet, NAME_TO_PATH, Reverb, Sampler, SamplerAudioLoader, SamplerConfig, SamplerNote, Soundfont, SoundfontConfig, SplendidGrandPiano, SplendidGrandPianoConfig, getDrumMachineNames, getElectricPianoNames, getMalletNames, getSoundfontKits, getSoundfontNames };
|
package/dist/index.js
CHANGED
|
@@ -87,7 +87,8 @@ __export(src_exports, {
|
|
|
87
87
|
getDrumMachineNames: () => getDrumMachineNames,
|
|
88
88
|
getElectricPianoNames: () => getElectricPianoNames,
|
|
89
89
|
getMalletNames: () => getMalletNames,
|
|
90
|
-
|
|
90
|
+
getSoundfontKits: () => getSoundfontKits,
|
|
91
|
+
getSoundfontNames: () => getSoundfontNames
|
|
91
92
|
});
|
|
92
93
|
module.exports = __toCommonJS(src_exports);
|
|
93
94
|
|
|
@@ -317,7 +318,7 @@ function startSample(sample) {
|
|
|
317
318
|
const volume = context.createGain();
|
|
318
319
|
volume.gain.value = (_b = sample == null ? void 0 : sample.gain) != null ? _b : 1;
|
|
319
320
|
const [decay, startDecay] = createDecayEnvelope(context, sample.decayTime);
|
|
320
|
-
|
|
321
|
+
const cleanup = unsubscribeAll([
|
|
321
322
|
connectSerial([source, lpf, volume, decay, sample.destination]),
|
|
322
323
|
(_c = sample.stop) == null ? void 0 : _c.call(sample, (sampleStop) => {
|
|
323
324
|
if (sampleStop === void 0 || sampleStop.stopId === void 0 || sampleStop.stopId === sample.stopId) {
|
|
@@ -325,6 +326,11 @@ function startSample(sample) {
|
|
|
325
326
|
}
|
|
326
327
|
})
|
|
327
328
|
]);
|
|
329
|
+
source.onended = () => {
|
|
330
|
+
var _a2;
|
|
331
|
+
cleanup();
|
|
332
|
+
(_a2 = sample.onEnded) == null ? void 0 : _a2.call(sample);
|
|
333
|
+
};
|
|
328
334
|
const startAt = sample.time || context.currentTime;
|
|
329
335
|
source.start(startAt);
|
|
330
336
|
function stop(time) {
|
|
@@ -402,6 +408,7 @@ var Sampler = class {
|
|
|
402
408
|
console.warn(`Sample not found: '${sample}'`);
|
|
403
409
|
return () => void 0;
|
|
404
410
|
}
|
|
411
|
+
const onEnded = _note.onEnded;
|
|
405
412
|
return startSample({
|
|
406
413
|
buffer,
|
|
407
414
|
destination: __privateGet(this, _output).input,
|
|
@@ -412,7 +419,8 @@ var Sampler = class {
|
|
|
412
419
|
detune: detune + ((_a = _note.detune) != null ? _a : __privateGet(this, _config).detune),
|
|
413
420
|
gain: __privateGet(this, _config).volumeToGain((_b = _note.velocity) != null ? _b : __privateGet(this, _config).velocity),
|
|
414
421
|
stop: __privateGet(this, _stop).subscribe,
|
|
415
|
-
stopId: (_c = _note.stopId) != null ? _c : _note.note
|
|
422
|
+
stopId: (_c = _note.stopId) != null ? _c : _note.note,
|
|
423
|
+
onEnded: onEnded ? () => onEnded(note) : void 0
|
|
416
424
|
});
|
|
417
425
|
}
|
|
418
426
|
stop(note) {
|
|
@@ -686,6 +694,7 @@ var SfzSampler = class {
|
|
|
686
694
|
console.warn(`Sample not found: ${region.sample}`);
|
|
687
695
|
return () => void 0;
|
|
688
696
|
}
|
|
697
|
+
const onEnded = _note.onEnded;
|
|
689
698
|
return startSample({
|
|
690
699
|
buffer,
|
|
691
700
|
destination,
|
|
@@ -695,7 +704,8 @@ var SfzSampler = class {
|
|
|
695
704
|
time: _note.time,
|
|
696
705
|
duration: _note.duration,
|
|
697
706
|
stop: __privateGet(this, _stop2).subscribe,
|
|
698
|
-
stopId: (_f = _note.stopId) != null ? _f : _note.note
|
|
707
|
+
stopId: (_f = _note.stopId) != null ? _f : _note.note,
|
|
708
|
+
onEnded: onEnded ? () => onEnded(note) : void 0
|
|
699
709
|
});
|
|
700
710
|
});
|
|
701
711
|
return (time) => stopAll.forEach((stop) => stop(time));
|
|
@@ -908,15 +918,14 @@ _output3 = new WeakMap();
|
|
|
908
918
|
// src/soundfont/soundfont.ts
|
|
909
919
|
var Soundfont = class extends Sampler {
|
|
910
920
|
constructor(context, options) {
|
|
911
|
-
var _a, _b;
|
|
912
|
-
const url = options.instrument.startsWith("http") ? options.instrument : gleitzKitUrl(options.instrument, options.kit);
|
|
913
|
-
console.log("!!! URL", { url });
|
|
921
|
+
var _a, _b, _c;
|
|
922
|
+
const url = options.instrument.startsWith("http") ? options.instrument : gleitzKitUrl(options.instrument, (_a = options.kit) != null ? _a : "MusyngKite");
|
|
914
923
|
super(context, {
|
|
915
924
|
destination: options.destination,
|
|
916
925
|
detune: options.detune,
|
|
917
926
|
volume: options.volume,
|
|
918
927
|
velocity: options.velocity,
|
|
919
|
-
decayTime: (
|
|
928
|
+
decayTime: (_b = options.decayTime) != null ? _b : 0.5,
|
|
920
929
|
lpfCutoffHz: options.lpfCutoffHz,
|
|
921
930
|
buffers: soundfontLoader(url),
|
|
922
931
|
noteToSample: (note, buffers, config) => {
|
|
@@ -924,7 +933,7 @@ var Soundfont = class extends Sampler {
|
|
|
924
933
|
return midi === void 0 ? ["", 0] : findNearestMidi(midi, buffers);
|
|
925
934
|
}
|
|
926
935
|
});
|
|
927
|
-
const extraGain = (
|
|
936
|
+
const extraGain = (_c = options.extraGain) != null ? _c : 5;
|
|
928
937
|
const gain = new GainNode(context, { gain: extraGain });
|
|
929
938
|
this.output.addInsert(gain);
|
|
930
939
|
}
|
|
@@ -968,12 +977,15 @@ function base64ToArrayBuffer(base64) {
|
|
|
968
977
|
}
|
|
969
978
|
return bytes.buffer;
|
|
970
979
|
}
|
|
971
|
-
function gleitzKitUrl(name, kit
|
|
980
|
+
function gleitzKitUrl(name, kit) {
|
|
972
981
|
var _a;
|
|
973
982
|
const format = (_a = findFirstSupportedFormat(["ogg", "mp3"])) != null ? _a : "mp3";
|
|
974
983
|
return `https://gleitz.github.io/midi-js-soundfonts/${kit}/${name}-${format}.js`;
|
|
975
984
|
}
|
|
976
|
-
function
|
|
985
|
+
function getSoundfontKits() {
|
|
986
|
+
return ["MusyngKite", "FluidR3_GM"];
|
|
987
|
+
}
|
|
988
|
+
function getSoundfontNames() {
|
|
977
989
|
return [
|
|
978
990
|
"accordion",
|
|
979
991
|
"acoustic_bass",
|
|
@@ -1512,6 +1524,7 @@ var LAYERS = [
|
|
|
1512
1524
|
getDrumMachineNames,
|
|
1513
1525
|
getElectricPianoNames,
|
|
1514
1526
|
getMalletNames,
|
|
1515
|
-
|
|
1527
|
+
getSoundfontKits,
|
|
1528
|
+
getSoundfontNames
|
|
1516
1529
|
});
|
|
1517
1530
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/sampler/load-audio.ts","../src/sampler/connect.ts","../src/sampler/midi.ts","../src/sampler/signals.ts","../src/sampler/channel.ts","../src/sampler/start-sample.ts","../src/sampler/sampler.ts","../src/drum-machine/dm-instrument.ts","../src/drum-machine/drum-machine.ts","../src/sfz/sfz-load.ts","../src/sfz/sfz-regions.ts","../src/sfz/sfz-sampler.ts","../src/tremolo.ts","../src/electric-piano.ts","../src/mallet.ts","../src/reverb/processor.min.ts","../src/reverb/reverb.ts","../src/soundfont/soundfont.ts","../src/splendid-grand-piano.ts"],"sourcesContent":["export * from \"./drum-machine/drum-machine\";\nexport * from \"./electric-piano\";\nexport * from \"./mallet\";\nexport * from \"./reverb/reverb\";\nexport * from \"./sampler/sampler\";\nexport * from \"./soundfont/soundfont\";\nexport * from \"./splendid-grand-piano\";\n","export type AudioBuffers = Record<string | number, AudioBuffer | undefined>;\n\nexport async function loadAudioBuffer(\n context: BaseAudioContext,\n url: string\n): Promise<AudioBuffer | undefined> {\n url = url.replace(/#/g, \"%23\").replace(/([^:]\\/)\\/+/g, \"$1\");\n const response = await fetch(url);\n if (response.status !== 200) {\n console.warn(\n \"Error loading buffer. Invalid status: \",\n response.status,\n url\n );\n return;\n }\n try {\n const audioData = await response.arrayBuffer();\n const buffer = await context.decodeAudioData(audioData);\n return buffer;\n } catch (error) {\n console.warn(\"Error loading buffer\", error, url);\n }\n}\n\nexport function findFirstSupportedFormat(formats: string[]): string | null {\n if (typeof document === \"undefined\") return null;\n\n const audio = document.createElement(\"audio\");\n for (let i = 0; i < formats.length; i++) {\n const format = formats[i];\n const canPlay = audio.canPlayType(`audio/${format}`);\n if (canPlay === \"probably\" || canPlay === \"maybe\") {\n return format;\n }\n // check Safari for aac format\n if (format === \"m4a\") {\n const canPlay = audio.canPlayType(`audio/aac`);\n if (canPlay === \"probably\" || canPlay === \"maybe\") {\n return format;\n }\n }\n }\n return null;\n}\n","export type AudioInsert = {\n input: AudioNode;\n output: AudioNode;\n};\n\nexport function connectSerial(nodes: (AudioNode | AudioInsert | undefined)[]) {\n const _nodes = nodes.filter((x): x is AudioNode | AudioInsert => !!x);\n _nodes.reduce((a, b) => {\n const left = \"output\" in a ? a.output : a;\n const right = \"input\" in b ? b.input : b;\n left.connect(right);\n return b;\n });\n\n return () => {\n _nodes.reduce((a, b) => {\n const left = \"output\" in a ? a.output : a;\n const right = \"input\" in b ? b.input : b;\n left.disconnect(right);\n return b;\n });\n };\n}\n\nexport function connectAudioBus(\n node: AudioNode,\n destination: AudioNode,\n gain: number\n) {\n const mix = node.context.createGain();\n mix.gain.value = gain;\n node.connect(mix);\n mix.connect(destination);\n\n return () => {\n node.disconnect(mix);\n mix.disconnect(destination);\n };\n}\n","function noteNameToMidi(note: string): number | undefined {\n const REGEX = /^([a-gA-G]?)(#{1,}|b{1,}|)(-?\\d+)$/;\n const m = REGEX.exec(note);\n if (!m) return;\n const letter = m[1].toUpperCase();\n if (!letter) return;\n\n const acc = m[2];\n const alt = acc[0] === \"b\" ? -acc.length : acc.length;\n const oct = m[3] ? +m[3] : 4;\n\n const step = (letter.charCodeAt(0) + 3) % 7;\n return [0, 2, 4, 5, 7, 9, 11][step] + alt + 12 * (oct + 1);\n}\n\nexport function toMidi(note: string | number | undefined): number | undefined {\n return note === undefined\n ? undefined\n : typeof note === \"number\"\n ? note\n : noteNameToMidi(note);\n}\n\n/// This is how the MIDI association converts midi velocity [0..127] into gain [0..1]\n/// @see https://www.midi.org/specifications/file-format-specifications/dls-downloadable-sounds/dls-level-1\nexport function midiVelToGain(vel: number) {\n return (vel * vel) / 16129; // 16129 = 127 * 127\n}\nexport function findNearestMidi(\n midi: number,\n isAvailable: Record<string | number, unknown>\n): [number, number] {\n let i = 0;\n while (isAvailable[midi + i] === undefined && i < 128) {\n if (i > 0) i = -i;\n else i = -i + 1;\n }\n\n return i === 127 ? [midi, 0] : [midi + i, -i * 100];\n}\n","/**\n * A function to unsubscribe from an event or control\n */\nexport type Unsubscribe = () => void;\n/**\n * A function that listener to event or control changes\n */\nexport type Listener<T> = (value: T) => void;\n/**\n * A function to subscribe an trigger or control events\n */\nexport type Subscribe<T> = (listener: Listener<T>) => Unsubscribe;\n\n/**\n * A trigger is a subscribable event\n */\nexport type Trigger<T> = {\n subscribe: Subscribe<T>;\n trigger: (event: T) => void;\n};\n\n/**\n * A control is a subscribable value\n */\nexport type Control<T> = {\n subscribe: Subscribe<T>;\n set: (value: T) => void;\n get: () => T;\n};\n\n/**\n * Create a control signal\n * @param initialValue\n * @returns Control\n */\nexport function createControl<T>(initialValue: T): Control<T> {\n let current = initialValue;\n const listeners = new Set<Listener<T>>();\n\n function subscribe(listener: Listener<T>) {\n listeners.add(listener);\n listener(current);\n return () => {\n listeners.delete(listener);\n };\n }\n\n function set(value: T) {\n current = value;\n listeners.forEach((listener) => listener(current));\n }\n\n function get(): T {\n return current;\n }\n return { subscribe, set, get };\n}\n\nexport function createTrigger<T>(): Trigger<T> {\n const listeners = new Set<Listener<T>>();\n\n function subscribe(listener: Listener<T>) {\n listeners.add(listener);\n return () => {\n listeners.delete(listener);\n };\n }\n\n function trigger(value: T) {\n listeners.forEach((listener) => listener(value));\n }\n\n return { subscribe, trigger };\n}\n\nexport function unsubscribeAll(unsubscribe: Array<Unsubscribe | undefined>) {\n let done = false;\n return () => {\n if (done) return;\n done = true;\n unsubscribe.forEach((cb) => cb?.());\n };\n}\n","import { AudioInsert, connectSerial } from \"./connect\";\nimport { midiVelToGain } from \"./midi\";\nimport { createControl } from \"./signals\";\n\ntype ChannelOptions = {\n destination: AudioNode;\n volume: number;\n volumeToGain: (volume: number) => number;\n};\n\ntype Send = {\n name: string;\n mix: GainNode;\n disconnect: () => void;\n};\n\n/**\n * @private\n */\nexport class Channel {\n public readonly setVolume: (vol: number) => void;\n public readonly input: AudioNode;\n\n #volume: GainNode;\n #sends?: Send[];\n #inserts?: (AudioNode | AudioInsert)[];\n #disconnect: () => void;\n #unsubscribe: () => void;\n #options: Readonly<ChannelOptions>;\n\n constructor(\n public readonly context: AudioContext,\n options: Partial<ChannelOptions>\n ) {\n this.#options = Object.freeze({\n destination: context.destination,\n volume: 100,\n volumeToGain: midiVelToGain,\n ...options,\n });\n\n this.input = new GainNode(this.context);\n this.#volume = new GainNode(this.context);\n\n this.#disconnect = connectSerial([\n this.input,\n this.#volume,\n this.#options.destination,\n ]);\n\n const volume = createControl(options.volume ?? 100);\n this.setVolume = volume.set;\n const volumeToGain = options.volumeToGain ?? midiVelToGain;\n this.#unsubscribe = volume.subscribe((volume) => {\n this.#volume.gain.value = volumeToGain(volume);\n });\n }\n\n addInsert(effect: AudioNode | AudioInsert) {\n this.#inserts ??= [];\n this.#inserts.push(effect);\n this.#disconnect();\n this.#disconnect = connectSerial([\n this.input,\n ...this.#inserts,\n this.#volume,\n this.#options.destination,\n ]);\n }\n\n addEffect(\n name: string,\n effect: AudioNode | { input: AudioNode },\n mixValue: number\n ) {\n const mix = new GainNode(this.context);\n mix.gain.value = mixValue;\n const input = \"input\" in effect ? effect.input : effect;\n const disconnect = connectSerial([this.#volume, mix, input]);\n\n this.#sends ??= [];\n this.#sends.push({ name, mix, disconnect });\n }\n\n sendEffect(name: string, mix: number) {\n const send = this.#sends?.find((send) => send.name === name);\n if (send) {\n send.mix.gain.value = mix;\n } else {\n console.warn(\"Send bus not found: \" + name);\n }\n }\n\n disconnect() {\n this.#disconnect();\n this.#unsubscribe();\n this.#sends?.forEach((send) => send.disconnect());\n this.#sends = undefined;\n }\n}\n","import { connectSerial } from \"./connect\";\nimport { toMidi } from \"./midi\";\nimport { Subscribe, unsubscribeAll } from \"./signals\";\n\nexport type StopSample = {\n stopId?: string | number;\n time?: number;\n};\n\nexport type SampleOptions = {\n decayTime?: number;\n detune?: number;\n gain?: number;\n};\n\ntype SampleNote = {\n midi?: number;\n note?: string;\n};\n\nexport type StartSample = {\n stopId?: string | number;\n buffer: AudioBuffer;\n destination: AudioNode;\n time?: number;\n duration?: number;\n decayTime?: number;\n detune?: number;\n gain?: number;\n lpfCutoffHz?: number;\n stop?: Subscribe<StopSample | undefined>;\n};\n\nexport function getSampleNote<T extends SampleNote>(\n note: number | string | T\n): T {\n if (typeof note === \"number\") {\n return { midi: note } as T;\n } else if (typeof note === \"string\") {\n return { note, midi: toMidi(note) } as T;\n } else {\n return { midi: note.midi ?? toMidi(note.note), ...note };\n }\n}\n\nexport function startSample(sample: StartSample) {\n const context = sample.destination.context;\n // Buffer source\n const source = context.createBufferSource();\n source.buffer = sample.buffer;\n source.detune.value = sample?.detune ?? 0;\n\n // Low pass filter\n const lpf = sample.lpfCutoffHz\n ? new BiquadFilterNode(context, {\n type: \"lowpass\",\n frequency: sample.lpfCutoffHz,\n })\n : undefined;\n\n // Sample volume\n const volume = context.createGain();\n volume.gain.value = sample?.gain ?? 1.0;\n\n // Release decay\n const [decay, startDecay] = createDecayEnvelope(context, sample.decayTime);\n\n source.onended = unsubscribeAll([\n connectSerial([source, lpf, volume, decay, sample.destination]),\n sample.stop?.((sampleStop) => {\n if (\n sampleStop === undefined ||\n sampleStop.stopId === undefined ||\n sampleStop.stopId === sample.stopId\n ) {\n stop(sampleStop?.time);\n }\n }),\n ]);\n\n const startAt = sample.time || context.currentTime;\n source.start(startAt);\n\n function stop(time?: number) {\n time ??= context.currentTime;\n if (time <= startAt) {\n source.stop(time);\n } else {\n const stopAt = startDecay(time);\n source.stop(stopAt);\n }\n }\n\n if (sample.duration !== undefined) {\n stop(startAt + sample.duration);\n }\n\n return stop;\n}\n\nfunction createDecayEnvelope(\n context: BaseAudioContext,\n envelopeTime = 0.2\n): [AudioNode, (time: number) => number] {\n let stopAt = 0;\n const envelope = new GainNode(context, { gain: 1.0 });\n\n function start(time: number): number {\n if (stopAt) return stopAt;\n envelope.gain.cancelScheduledValues(time);\n const envelopeAt = time || context.currentTime;\n stopAt = envelopeAt + envelopeTime;\n envelope.gain.setValueAtTime(1.0, envelopeAt);\n envelope.gain.linearRampToValueAtTime(0, stopAt);\n\n return stopAt;\n }\n\n return [envelope, start];\n}\n","import { Channel } from \"./channel\";\nimport { AudioBuffers, loadAudioBuffer } from \"./load-audio\";\nimport { midiVelToGain } from \"./midi\";\nimport { createTrigger, Trigger } from \"./signals\";\nimport { startSample, StopSample } from \"./start-sample\";\n\n/**\n * A function that downloads audio\n */\nexport type SamplerAudioLoader = (\n context: AudioContext,\n buffers: AudioBuffers\n) => Promise<void>;\n\nexport type SamplerConfig = {\n detune: number;\n volume: number;\n velocity: number;\n decayTime?: number;\n lpfCutoffHz?: number;\n destination: AudioNode;\n\n buffers: Record<string | number, string | AudioBuffers> | SamplerAudioLoader;\n volumeToGain: (volume: number) => number;\n noteToSample: (\n note: SamplerNote,\n buffers: AudioBuffers,\n config: SamplerConfig\n ) => [string | number, number];\n};\n\nexport type SamplerNote = {\n note: string | number;\n stopId?: string | number;\n time?: number;\n duration?: number;\n decayTime?: number;\n detune?: number;\n velocity?: number;\n lpfCutoffHz?: number;\n};\n\n/**\n * A Sampler instrument\n *\n * @private\n */\nexport class Sampler {\n public readonly output: Omit<Channel, \"input\">;\n public readonly buffers: AudioBuffers;\n #config: SamplerConfig;\n #stop: Trigger<StopSample | undefined>;\n #load: Promise<void>;\n #output: Channel;\n\n public constructor(\n public readonly context: AudioContext,\n options: Partial<SamplerConfig>\n ) {\n this.#config = {\n destination: options.destination ?? context.destination,\n detune: 0,\n volume: options.volume ?? 100,\n velocity: options.velocity ?? 100,\n buffers: options.buffers ?? {},\n volumeToGain: options.volumeToGain ?? midiVelToGain,\n noteToSample:\n options.noteToSample ?? ((note) => [note.note.toString(), 0]),\n };\n this.buffers = {};\n this.#stop = createTrigger();\n const loader =\n typeof this.#config.buffers === \"function\"\n ? this.#config.buffers\n : createAudioBuffersLoader(this.#config.buffers);\n this.#load = loader(context, this.buffers);\n this.#output = new Channel(context, this.#config);\n this.output = this.#output;\n }\n\n async loaded(): Promise<this> {\n await this.#load;\n return this;\n }\n\n start(note: SamplerNote | string | number) {\n const _note: SamplerNote = typeof note === \"object\" ? note : { note: note };\n const [sample, detune] = this.#config.noteToSample(\n _note,\n this.buffers,\n this.#config\n );\n const buffer = this.buffers[sample];\n if (!buffer) {\n console.warn(`Sample not found: '${sample}'`);\n return () => undefined;\n }\n return startSample({\n buffer,\n destination: this.#output.input,\n\n time: _note.time,\n duration: _note.duration,\n\n decayTime: _note.decayTime,\n lpfCutoffHz: _note.lpfCutoffHz,\n detune: detune + (_note.detune ?? this.#config.detune),\n gain: this.#config.volumeToGain(_note.velocity ?? this.#config.velocity),\n\n stop: this.#stop.subscribe,\n stopId: _note.stopId ?? _note.note,\n });\n }\n\n stop(note?: StopSample | string | number) {\n const note_ = typeof note === \"object\" ? note : { stopId: note };\n this.#stop.trigger(note_);\n }\n}\n\nfunction createAudioBuffersLoader(\n source: Record<string | number, string | AudioBuffers>\n): SamplerAudioLoader {\n return async (context, buffers) => {\n await Promise.all([\n Object.keys(source).map(async (key) => {\n const value = source[key];\n if (value instanceof AudioBuffer) {\n buffers[key] = value;\n } else if (typeof value === \"string\") {\n const buffer = await loadAudioBuffer(context, value);\n if (buffer) buffers[key] = buffer;\n }\n }),\n ]);\n };\n}\n","export type DrumMachineInstrument = {\n baseUrl: string;\n name: string;\n samples: string[];\n sampleNames: string[];\n nameToSample: Record<string, string | undefined>;\n sampleNameVariations: Record<string, string[]>;\n};\nexport const EMPTY_INSTRUMENT: DrumMachineInstrument = {\n baseUrl: \"\",\n name: \"\",\n samples: [],\n sampleNames: [],\n nameToSample: {},\n sampleNameVariations: {},\n};\n\nexport async function fetchDrumMachineInstrument(\n url: string\n): Promise<DrumMachineInstrument> {\n const res = await fetch(url);\n const json = await res.json();\n // need to fix json\n json.baseUrl = url.replace(\"/dm.json\", \"\");\n json.sampleNames = [];\n json.nameToSample = {};\n json.sampleNameVariations = {};\n for (const sampleSrc of json.samples) {\n const sample =\n sampleSrc.indexOf(\"/\") !== -1 ? sampleSrc : sampleSrc.replace(\"-\", \"/\");\n json.nameToSample[sample] = sample;\n const [base, variation] = sample.split(\"/\");\n if (!json.sampleNames.includes(base)) {\n json.sampleNames.push(base);\n }\n json.nameToSample[base] ??= sample;\n json.sampleNameVariations[base] ??= [];\n if (variation) {\n json.sampleNameVariations[base].push(`${base}/${variation}`);\n }\n }\n\n return json;\n}\n","import {\n findFirstSupportedFormat,\n loadAudioBuffer,\n} from \"../sampler/load-audio\";\nimport { Sampler, SamplerAudioLoader } from \"../sampler/sampler\";\nimport {\n DrumMachineInstrument,\n EMPTY_INSTRUMENT,\n fetchDrumMachineInstrument,\n} from \"./dm-instrument\";\n\nexport function getDrumMachineNames() {\n return Object.keys(INSTRUMENTS);\n}\n\nconst INSTRUMENTS: Record<string, string> = {\n \"TR-808\": \"https://danigb.github.io/samples/drum-machines/TR-808/dm.json\",\n \"Casio-RZ1\":\n \"https://danigb.github.io/samples/drum-machines/Casio-RZ1/dm.json\",\n \"LM-2\": \"https://danigb.github.io/samples/drum-machines/LM-2/dm.json\",\n \"MFB-512\": \"https://danigb.github.io/samples/drum-machines/MFB-512/dm.json\",\n \"Roland CR-8000\":\n \"https://danigb.github.io/samples/drum-machines/Roland-CR-8000/dm.json\",\n};\n\nexport type DrumMachineConfig = {\n instrument: string;\n destination: AudioNode;\n\n detune: number;\n volume: number;\n velocity: number;\n decayTime?: number;\n lpfCutoffHz?: number;\n};\n\nexport class DrumMachine extends Sampler {\n #instrument = EMPTY_INSTRUMENT;\n public constructor(\n context: AudioContext,\n options: Partial<DrumMachineConfig>\n ) {\n const url = INSTRUMENTS[options.instrument ?? \"TR-808\"];\n if (!url) throw new Error(\"Invalid instrument: \" + options.instrument);\n const instrument = fetchDrumMachineInstrument(url);\n\n super(context, {\n ...options,\n buffers: drumMachineLoader(instrument),\n noteToSample: (note, buffers, config) => {\n const sample = this.#instrument.nameToSample[note.note];\n return [sample ?? \"\", 0];\n },\n });\n instrument.then((instrument) => {\n this.#instrument = instrument;\n });\n }\n\n get sampleNames(): string[] {\n return this.#instrument.sampleNames;\n }\n\n getVariations(name: string): string[] {\n return this.#instrument.sampleNameVariations[name] ?? [];\n }\n}\n\nfunction drumMachineLoader(\n instrument: Promise<DrumMachineInstrument>\n): SamplerAudioLoader {\n const format = findFirstSupportedFormat([\"ogg\", \"m4a\"]) ?? \"ogg\";\n return async (context, buffers) => {\n const dm = await instrument;\n await Promise.all(\n dm.samples.map(async (sample) => {\n const url = `${dm.baseUrl}/${sample}.${format}`;\n const sampleName =\n sample.indexOf(\"/\") !== -1 ? sample : sample.replace(\"-\", \"/\");\n const buffer = await loadAudioBuffer(context, url);\n if (buffer) buffers[sampleName] = buffer;\n })\n );\n };\n}\n","import {\n AudioBuffers,\n findFirstSupportedFormat,\n loadAudioBuffer,\n} from \"../sampler/load-audio\";\nimport { SfzInstrument } from \"./sfz-kits\";\nimport { Websfz, WebsfzGroup } from \"./websfz\";\n\nexport async function loadSfzBuffers(\n context: AudioContext,\n buffers: AudioBuffers,\n websfz: Websfz\n) {\n websfz.groups.forEach((group) => {\n const urls = getWebsfzGroupUrls(websfz, group);\n return loadAudioBuffers(context, buffers, urls);\n });\n}\n\nexport async function loadSfzInstrument(\n instrument: string | Websfz | SfzInstrument\n): Promise<Websfz> {\n const isWebsfz = (inst: any): inst is Websfz => \"global\" in inst;\n const isSfzInstrument = (inst: any): inst is SfzInstrument =>\n \"websfzUrl\" in inst;\n\n if (typeof instrument === \"string\") {\n return fetchWebSfz(instrument);\n } else if (isWebsfz(instrument)) {\n return instrument;\n } else if (isSfzInstrument(instrument)) {\n const websfz = await fetchWebSfz(instrument.websfzUrl);\n websfz.meta ??= {};\n if (instrument.name) websfz.meta.name = instrument.name;\n if (instrument.baseUrl) websfz.meta.baseUrl = instrument.baseUrl;\n if (instrument.formats) websfz.meta.formats = instrument.formats;\n return websfz;\n } else {\n throw new Error(\"Invalid instrument: \" + JSON.stringify(instrument));\n }\n}\n\n// @private\nasync function loadAudioBuffers(\n context: AudioContext,\n buffers: AudioBuffers,\n urls: Record<string, string>\n) {\n await Promise.all(\n Object.keys(urls).map(async (sampleId) => {\n if (buffers[sampleId]) return;\n\n const buffer = await loadAudioBuffer(context, urls[sampleId]);\n if (buffer) buffers[sampleId] = buffer;\n return buffers;\n })\n );\n}\n\n// @private\nasync function fetchWebSfz(url: string): Promise<Websfz> {\n try {\n const response = await fetch(url);\n const json = await response.json();\n return json as Websfz;\n } catch (error) {\n console.warn(`Can't load SFZ file ${url}`, error);\n throw new Error(`Can't load SFZ file ${url}`);\n }\n}\n\n// @private\nexport function getWebsfzGroupUrls(websfz: Websfz, group: WebsfzGroup) {\n const urls: Record<string, string> = {};\n const baseUrl = websfz.meta.baseUrl ?? \"\";\n const format = findFirstSupportedFormat(websfz.meta.formats ?? []) ?? \"ogg\";\n\n const prefix = websfz.global[\"default_path\"] ?? \"\";\n\n if (!group) return urls;\n\n return group.regions.reduce((urls, region) => {\n if (region.sample) {\n urls[region.sample] = `${baseUrl}/${prefix}${region.sample}.${format}`;\n }\n return urls;\n }, urls);\n}\n","import { Websfz, WebsfzGroup, WebsfzRegion } from \"./websfz\";\n\nfunction checkRange(value?: number, low?: number, hi?: number) {\n const isAboveLow = low === undefined || (value !== undefined && value >= low);\n const isBelowHi = hi === undefined || (value !== undefined && value <= hi);\n return isAboveLow && isBelowHi;\n}\n\nexport function findRegions(\n websfz: Websfz,\n note: { midi?: number; velocity?: number; cc64?: number }\n): [WebsfzGroup, WebsfzRegion][] {\n const regions: [WebsfzGroup, WebsfzRegion][] = [];\n for (const group of websfz.groups) {\n if (\n checkRange(note.midi, group.lokey, group.hikey) &&\n checkRange(note.velocity, group.lovel, group.hivel) &&\n checkRange(note.cc64, group.locc64, group.hicc64)\n ) {\n for (const region of group.regions) {\n if (\n checkRange(note.midi, region.lokey, region.hikey) &&\n checkRange(note.velocity, region.lovel, region.hivel) &&\n checkRange(note.cc64, group.locc64, group.hicc64)\n ) {\n regions.push([group, region]);\n }\n }\n }\n }\n return regions;\n}\n","import { Channel } from \"../sampler/channel\";\nimport { AudioBuffers } from \"../sampler/load-audio\";\nimport { midiVelToGain, toMidi } from \"../sampler/midi\";\nimport { SamplerNote } from \"../sampler/sampler\";\nimport { createTrigger, Trigger } from \"../sampler/signals\";\nimport { startSample, StopSample } from \"../sampler/start-sample\";\nimport { SfzInstrument } from \"./sfz-kits\";\nimport { loadSfzBuffers, loadSfzInstrument } from \"./sfz-load\";\nimport { findRegions } from \"./sfz-regions\";\nimport { Websfz } from \"./websfz\";\n\n/**\n * Splendid Grand Piano options\n */\nexport type SfzSamplerConfig = {\n instrument: SfzInstrument | Websfz | string;\n destination: AudioNode;\n volume: number;\n velocity: number;\n detune: number;\n decayTime: number;\n lpfCutoffHz?: number;\n};\n\nconst EMPTY_WEBSFZ: Websfz = Object.freeze({\n meta: {},\n global: {},\n groups: [],\n});\n\nexport class SfzSampler {\n public readonly output: Omit<Channel, \"input\">;\n public readonly buffers: AudioBuffers;\n #websfz: Websfz;\n #config: SfzSamplerConfig;\n #stop: Trigger<StopSample | undefined>;\n #load: Promise<void>;\n #output: Channel;\n\n constructor(\n public readonly context: AudioContext,\n options: Partial<SfzSamplerConfig> & Pick<SfzSamplerConfig, \"instrument\">\n ) {\n this.#config = {\n instrument: options.instrument,\n destination: options.destination ?? context.destination,\n detune: 0,\n volume: options.volume ?? 100,\n velocity: options.velocity ?? 100,\n decayTime: 0.3,\n };\n this.buffers = {};\n this.#stop = createTrigger();\n\n this.#websfz = EMPTY_WEBSFZ;\n this.#load = loadSfzInstrument(options.instrument).then((result) => {\n this.#websfz = Object.freeze(result);\n return loadSfzBuffers(context, this.buffers, this.#websfz);\n });\n this.#output = new Channel(context, this.#config);\n this.output = this.#output;\n }\n async loaded(): Promise<this> {\n await this.#load;\n return this;\n }\n\n start(note: SamplerNote | string | number) {\n const _note: SamplerNote = typeof note === \"object\" ? note : { note: note };\n const midi = toMidi(_note.note);\n if (midi === undefined) return () => undefined;\n\n const velocity = _note.velocity ?? this.#config.velocity;\n const regions = findRegions(this.#websfz, { midi, velocity });\n\n const stopAll = regions.map(([group, region]) => {\n let target = region.pitch_keycenter ?? region.key ?? midi;\n const detune = (midi - target) * 100;\n\n const destination = (this.output as Channel).input;\n\n let buffer = this.buffers[region.sample];\n if (!buffer) {\n console.warn(`Sample not found: ${region.sample}`);\n return () => undefined;\n }\n\n return startSample({\n buffer,\n destination,\n decayTime: _note.decayTime ?? this.#config.decayTime,\n detune: detune + (_note.detune ?? this.#config.detune),\n gain: midiVelToGain(_note.velocity ?? this.#config.velocity),\n time: _note.time,\n duration: _note.duration,\n stop: this.#stop.subscribe,\n stopId: _note.stopId ?? _note.note,\n });\n });\n return (time?: number) => stopAll.forEach((stop) => stop(time));\n }\n\n stop(note?: StopSample | string | number) {\n const note_ = typeof note === \"object\" ? note : { stopId: note };\n this.#stop.trigger(note_);\n }\n\n disconnect() {\n this.stop();\n this.#output.disconnect();\n }\n}\n","import { AudioInsert } from \"./sampler/connect\";\nimport { Subscribe } from \"./sampler/signals\";\n\n// @private\nexport function createTremolo(\n context: AudioContext,\n depth: Subscribe<number>\n): AudioInsert {\n const input = new GainNode(context);\n const output = new GainNode(context);\n\n // force mono sources to be stereo\n input.channelCount = 2;\n input.channelCountMode = \"explicit\";\n\n const splitter = new ChannelSplitterNode(context, { numberOfOutputs: 2 });\n const ampL = new GainNode(context);\n const ampR = new GainNode(context);\n const merger = new ChannelMergerNode(context, { numberOfInputs: 2 });\n\n const lfoL = new OscillatorNode(context, {\n type: \"sine\",\n frequency: 1,\n });\n lfoL.start();\n const lfoLAmp = new GainNode(context);\n const lfoR = new OscillatorNode(context, {\n type: \"sine\",\n frequency: 1.1,\n });\n lfoR.start();\n const lfoRAmp = new GainNode(context);\n\n input.connect(splitter);\n splitter.connect(ampL, 0);\n splitter.connect(ampR, 1);\n ampL.connect(merger, 0, 0);\n ampR.connect(merger, 0, 1);\n lfoL.connect(lfoLAmp);\n lfoLAmp.connect(ampL.gain);\n lfoR.connect(lfoRAmp);\n lfoRAmp.connect(ampR.gain);\n merger.connect(output);\n\n const unsubscribe = depth((depth) => {\n lfoLAmp.gain.value = depth;\n lfoRAmp.gain.value = depth;\n });\n\n input.disconnect = () => {\n unsubscribe();\n lfoL.stop();\n lfoR.stop();\n input.disconnect(splitter);\n splitter.disconnect(ampL, 0);\n splitter.disconnect(ampR, 1);\n ampL.disconnect(merger, 0, 0);\n ampR.disconnect(merger, 0, 1);\n lfoL.disconnect(ampL);\n lfoR.disconnect(ampR);\n merger.disconnect(output);\n };\n\n return { input, output };\n}\n","import { midiVelToGain } from \"./sampler/midi\";\nimport { createControl } from \"./sampler/signals\";\nimport { SfzSampler, SfzSamplerConfig } from \"./sfz/sfz-sampler\";\nimport { createTremolo } from \"./tremolo\";\n\nexport function getElectricPianoNames() {\n return Object.keys(INSTRUMENTS);\n}\n\nconst INSTRUMENTS: Record<string, string> = {\n CP80: \"https://danigb.github.io/samples/gs-e-pianos/CP80/cp80.websfz.json\",\n PianetT:\n \"https://danigb.github.io/samples/gs-e-pianos/Pianet T/pianet-t.websfz.json\",\n WurlitzerEP200:\n \"https://danigb.github.io/samples/gs-e-pianos/Wurlitzer EP200/wurlitzer-ep200.websfz.json\",\n TX81Z:\n \"https://danigb.github.io/samples/vcsl/TX81Z/tx81z-fm-piano.websfz.json\",\n};\n\nexport class ElectricPiano extends SfzSampler {\n public readonly tremolo: Readonly<{ level: (value: number) => void }>;\n constructor(\n context: AudioContext,\n options: Partial<SfzSamplerConfig> & { instrument: string }\n ) {\n super(context, {\n ...options,\n instrument: INSTRUMENTS[options.instrument] ?? options.instrument,\n });\n const depth = createControl(0);\n this.tremolo = {\n level: (level) => depth.set(midiVelToGain(level)),\n };\n const tremolo = createTremolo(context, depth.subscribe);\n this.output.addInsert(tremolo);\n }\n}\n","import { SfzInstrument } from \"./sfz/sfz-kits\";\nimport { SfzSampler, SfzSamplerConfig } from \"./sfz/sfz-sampler\";\n\nexport function getMalletNames() {\n return Object.keys(NAME_TO_PATH) as MalletName[];\n}\n\nexport class Mallet extends SfzSampler {\n constructor(\n context: AudioContext,\n options: Partial<SfzSamplerConfig> & { instrument: string }\n ) {\n const instrument = getMallet(options.instrument);\n super(context, {\n ...options,\n instrument,\n });\n }\n}\n\nfunction getMallet(name: MalletName | string): SfzInstrument {\n if (!NAME_TO_PATH[name]) throw Error(`Mallet instrument \"${name}\" not valid`);\n return {\n name: name,\n websfzUrl: BASE_URL + NAME_TO_PATH[name] + EXT,\n };\n}\nconst BASE_URL = \"https://danigb.github.io/samples/vcsl/\";\nconst EXT = \".websfz.json\";\n\ntype MalletName = keyof typeof NAME_TO_PATH;\n\nexport const NAME_TO_PATH: Record<string, string | undefined> = {\n \"Balafon - Hard Mallet\": \"Struck Idiophones/balafon-hard-mallet\",\n \"Balafon - Keyswitch\": \"Struck Idiophones/balafon-keyswitch\",\n \"Balafon - Soft Mallet\": \"Struck Idiophones/balafon-soft-mallet\",\n \"Balafon - Traditional Mallet\":\n \"Struck Idiophones/balafon-traditional-mallet\",\n \"Tubular Bells 1\": \"Struck Idiophones/tubular-bells-1\",\n \"Tubular Bells 2\": \"Struck Idiophones/tubular-bells-2\",\n \"Vibraphone - Hard Mallets\": \"Struck Idiophones/vibraphone-hard-mallets\",\n \"Vibraphone - Keyswitch\": \"Struck Idiophones/vibraphone-keyswitch\",\n \"Vibraphone - Soft Mallets\": \"Struck Idiophones/vibraphone-soft-mallets\",\n \"Xylophone - Hard Mallets\": \"Struck Idiophones/xylophone-hard-mallets\",\n \"Xylophone - Keyswitch\": \"Struck Idiophones/xylophone-keyswitch\",\n \"Xylophone - Medium Mallets\": \"Struck Idiophones/xylophone-medium-mallets\",\n \"Xylophone - Soft Mallets\": \"Struck Idiophones/xylophone-soft-mallets\",\n} as const;\n","export const PROCESSOR = `\"use strict\";(()=>{var f=class extends AudioWorkletProcessor{_pDLength;_preDelay;_pDWrite;_lp1;_lp2;_lp3;_excPhase;_taps;_Delays;sampleRate;static get parameterDescriptors(){return[[\"preDelay\",0,0,sampleRate-1,\"k-rate\"],[\"bandwidth\",.9999,0,1,\"k-rate\"],[\"inputDiffusion1\",.75,0,1,\"k-rate\"],[\"inputDiffusion2\",.625,0,1,\"k-rate\"],[\"decay\",.5,0,1,\"k-rate\"],[\"decayDiffusion1\",.7,0,.999999,\"k-rate\"],[\"decayDiffusion2\",.5,0,.999999,\"k-rate\"],[\"damping\",.005,0,1,\"k-rate\"],[\"excursionRate\",.5,0,2,\"k-rate\"],[\"excursionDepth\",.7,0,2,\"k-rate\"],[\"wet\",1,0,1,\"k-rate\"],[\"dry\",0,0,1,\"k-rate\"]].map(e=>new Object({name:e[0],defaultValue:e[1],minValue:e[2],maxValue:e[3],automationRate:e[4]}))}constructor(e){super(),this.sampleRate=sampleRate,this._Delays=[],this._pDLength=sampleRate+(128-sampleRate%128),this._preDelay=new Float32Array(this._pDLength),this._pDWrite=0,this._lp1=0,this._lp2=0,this._lp3=0,this._excPhase=0,[.004771345,.003595309,.012734787,.009307483,.022579886,.149625349,.060481839,.1249958,.030509727,.141695508,.089244313,.106280031].forEach(a=>this.makeDelay(a,sampleRate)),this._taps=Int16Array.from([.008937872,.099929438,.064278754,.067067639,.066866033,.006283391,.035818689,.011861161,.121870905,.041262054,.08981553,.070931756,.011256342,.004065724],a=>Math.round(a*sampleRate))}makeDelay(e,a){let t=Math.round(e*a),s=2**Math.ceil(Math.log2(t));this._Delays.push([new Float32Array(s),t-1,0,s-1])}writeDelay(e,a){return this._Delays[e][0][this._Delays[e][1]]=a}readDelay(e){return this._Delays[e][0][this._Delays[e][2]]}readDelayAt(e,a){let t=this._Delays[e];return t[0][t[2]+a&t[3]]}readDelayCAt(e,a){let t=this._Delays[e],s=a-~~a,d=~~a+t[2]-1,r=t[3],D=t[0][d++&r],l=t[0][d++&r],h=t[0][d++&r],y=t[0][d&r],u=(3*(l-h)-D+y)/2,m=2*h+D-(5*l+y)/2,c=(h-D)/2;return((u*s+m)*s+c)*s+l}process(e,a,t){let s=~~t.preDelay[0],d=t.bandwidth[0],r=t.inputDiffusion1[0],D=t.inputDiffusion2[0],l=t.decay[0],h=t.decayDiffusion1[0],y=t.decayDiffusion2[0],u=1-t.damping[0],m=t.excursionRate[0]/sampleRate,c=t.excursionDepth[0]*sampleRate/1e3,w=t.wet[0]*.6,A=t.dry[0];if(e[0].length==2)for(let i=127;i>=0;i--)this._preDelay[this._pDWrite+i]=(e[0][0][i]+e[0][1][i])*.5,a[0][0][i]=e[0][0][i]*A,a[0][1][i]=e[0][1][i]*A;else if(e[0].length>0){this._preDelay.set(e[0][0],this._pDWrite);for(let i=127;i>=0;i--)a[0][0][i]=a[0][1][i]=e[0][0][i]*A}else this._preDelay.set(new Float32Array(128),this._pDWrite);let o=0;for(;o<128;){let i=0,b=0;this._lp1+=d*(this._preDelay[(this._pDLength+this._pDWrite-s+o)%this._pDLength]-this._lp1);let p=this.writeDelay(0,this._lp1-r*this.readDelay(0));p=this.writeDelay(1,r*(p-this.readDelay(1))+this.readDelay(0)),p=this.writeDelay(2,r*p+this.readDelay(1)-D*this.readDelay(2)),p=this.writeDelay(3,D*(p-this.readDelay(3))+this.readDelay(2));let k=D*p+this.readDelay(3),g=c*(1+Math.cos(this._excPhase*6.28)),x=c*(1+Math.sin(this._excPhase*6.2847)),_=this.writeDelay(4,k+l*this.readDelay(11)+h*this.readDelayCAt(4,g));this.writeDelay(5,this.readDelayCAt(4,g)-h*_),this._lp2+=u*(this.readDelay(5)-this._lp2),_=this.writeDelay(6,l*this._lp2-y*this.readDelay(6)),this.writeDelay(7,this.readDelay(6)+y*_),_=this.writeDelay(8,k+l*this.readDelay(7)+h*this.readDelayCAt(8,x)),this.writeDelay(9,this.readDelayCAt(8,x)-h*_),this._lp3+=u*(this.readDelay(9)-this._lp3),_=this.writeDelay(10,l*this._lp3-y*this.readDelay(10)),this.writeDelay(11,this.readDelay(10)+y*_),i=this.readDelayAt(9,this._taps[0])+this.readDelayAt(9,this._taps[1])-this.readDelayAt(10,this._taps[2])+this.readDelayAt(11,this._taps[3])-this.readDelayAt(5,this._taps[4])-this.readDelayAt(6,this._taps[5])-this.readDelayAt(7,this._taps[6]),b=this.readDelayAt(5,this._taps[7])+this.readDelayAt(5,this._taps[8])-this.readDelayAt(6,this._taps[9])+this.readDelayAt(7,this._taps[10])-this.readDelayAt(9,this._taps[11])-this.readDelayAt(10,this._taps[12])-this.readDelayAt(11,this._taps[13]),a[0][0][o]+=i*w,a[0][1][o]+=b*w,this._excPhase+=m,o++;for(let R=0,n=this._Delays[0];R<this._Delays.length;n=this._Delays[++R])n[1]=n[1]+1&n[3],n[2]=n[2]+1&n[3]}return this._pDWrite=(this._pDWrite+128)%this._pDLength,!0}};registerProcessor(\"DattorroReverb\",f);})();`;\n","import { PROCESSOR } from \"./processor.min\";\n\nconst PARAMS = [\n \"preDelay\",\n \"bandwidth\",\n \"inputDiffusion1\",\n \"inputDiffusion2\",\n \"decay\",\n \"decayDiffusion1\",\n \"decayDiffusion2\",\n \"damping\",\n \"excursionRate\",\n \"excursionDepth\",\n \"wet\",\n \"dry\",\n] as const;\n\nconst init = new WeakMap<AudioContext, Promise<void>>();\n\nasync function createDattorroReverbEffect(context: AudioContext) {\n let ready = init.get(context);\n if (!ready) {\n const blob = new Blob([PROCESSOR], { type: \"application/javascript\" });\n const url = URL.createObjectURL(blob);\n ready = context.audioWorklet.addModule(url);\n init.set(context, ready);\n }\n await ready;\n\n const reverb = new AudioWorkletNode(context, \"DattorroReverb\", {\n outputChannelCount: [2],\n });\n return reverb;\n}\n\nexport class Reverb {\n #effect: AudioWorkletNode | undefined;\n #ready: Promise<this>;\n public readonly input: AudioNode;\n #output: AudioNode;\n\n constructor(context: AudioContext) {\n this.input = context.createGain();\n this.#output = context.destination;\n this.#ready = createDattorroReverbEffect(context).then((reverb) => {\n this.input.connect(reverb);\n reverb.connect(this.#output);\n this.#effect = reverb;\n return this;\n });\n }\n\n get paramNames() {\n return PARAMS;\n }\n\n getParam(name: (typeof PARAMS)[number]): AudioParam | undefined {\n return this.#effect?.parameters.get(\"preDelay\");\n }\n\n get isReady(): boolean {\n return this.#effect !== undefined;\n }\n\n ready(): Promise<this> {\n return this.#ready;\n }\n\n connect(output: AudioNode) {\n if (this.#effect) {\n this.#effect.disconnect(this.#output);\n this.#effect.connect(output);\n }\n this.#output = output;\n }\n}\n","import { findFirstSupportedFormat } from \"../sampler/load-audio\";\nimport { findNearestMidi, toMidi } from \"../sampler/midi\";\nimport { Sampler, SamplerAudioLoader } from \"../sampler/sampler\";\n\nexport type SoundfontConfig = {\n kit: \"FluidR3_GM\" | \"MusyngKite\";\n instrument: string;\n\n destination: AudioNode;\n\n detune: number;\n volume: number;\n velocity: number;\n decayTime?: number;\n lpfCutoffHz?: number;\n extraGain?: number;\n};\n\nexport class Soundfont extends Sampler {\n constructor(\n context: AudioContext,\n options: Partial<SoundfontConfig> & { instrument: string }\n ) {\n const url = options.instrument.startsWith(\"http\")\n ? options.instrument\n : gleitzKitUrl(options.instrument, options.kit);\n console.log(\"!!! URL\", { url });\n super(context, {\n destination: options.destination,\n\n detune: options.detune,\n volume: options.volume,\n velocity: options.velocity,\n decayTime: options.decayTime ?? 0.5,\n lpfCutoffHz: options.lpfCutoffHz,\n buffers: soundfontLoader(url),\n noteToSample: (note, buffers, config) => {\n let midi = toMidi(note.note);\n return midi === undefined ? [\"\", 0] : findNearestMidi(midi, buffers);\n },\n });\n\n // This is to compensate the low volume of the original samples\n const extraGain = options.extraGain ?? 5;\n const gain = new GainNode(context, { gain: extraGain });\n this.output.addInsert(gain);\n }\n}\n\nfunction soundfontLoader(url: string): SamplerAudioLoader {\n return async (context, buffers) => {\n const sourceFile = await (await fetch(url)).text();\n const json = midiJsToJson(sourceFile);\n\n const noteNames = Object.keys(json);\n await Promise.all(\n noteNames.map(async (noteName) => {\n const midi = toMidi(noteName);\n if (!midi) return;\n const audioData = base64ToArrayBuffer(\n removeBase64Prefix(json[noteName])\n );\n const buffer = await context.decodeAudioData(audioData);\n buffers[midi] = buffer;\n })\n );\n };\n}\n\n// convert a MIDI.js javascript soundfont file to json\nfunction midiJsToJson(source: string) {\n const header = source.indexOf(\"MIDI.Soundfont.\");\n if (header < 0) throw Error(\"Invalid MIDI.js Soundfont format\");\n const start = source.indexOf(\"=\", header) + 2;\n const end = source.lastIndexOf(\",\");\n return JSON.parse(source.slice(start, end) + \"}\");\n}\n\nfunction removeBase64Prefix(audioBase64: string) {\n return audioBase64.slice(audioBase64.indexOf(\",\") + 1);\n}\n\nfunction base64ToArrayBuffer(base64: string) {\n const decoded = window.atob(base64);\n const len = decoded.length;\n const bytes = new Uint8Array(len);\n for (let i = 0; i < len; i++) {\n bytes[i] = decoded.charCodeAt(i);\n }\n return bytes.buffer;\n}\n\nfunction gleitzKitUrl(\n name: string,\n kit: \"FluidR3_GM\" | \"MusyngKite\" = \"MusyngKite\"\n) {\n const format = findFirstSupportedFormat([\"ogg\", \"mp3\"]) ?? \"mp3\";\n return `https://gleitz.github.io/midi-js-soundfonts/${kit}/${name}-${format}.js`;\n}\n\nexport function getSoundfontInstrumentNames() {\n return [\n \"accordion\",\n \"acoustic_bass\",\n \"acoustic_grand_piano\",\n \"acoustic_guitar_nylon\",\n \"acoustic_guitar_steel\",\n \"agogo\",\n \"alto_sax\",\n \"applause\",\n \"bagpipe\",\n \"banjo\",\n \"baritone_sax\",\n \"bassoon\",\n \"bird_tweet\",\n \"blown_bottle\",\n \"brass_section\",\n \"breath_noise\",\n \"bright_acoustic_piano\",\n \"celesta\",\n \"cello\",\n \"choir_aahs\",\n \"church_organ\",\n \"clarinet\",\n \"clavinet\",\n \"contrabass\",\n \"distortion_guitar\",\n \"drawbar_organ\",\n \"dulcimer\",\n \"electric_bass_finger\",\n \"electric_bass_pick\",\n \"electric_grand_piano\",\n \"electric_guitar_clean\",\n \"electric_guitar_jazz\",\n \"electric_guitar_muted\",\n \"electric_piano_1\",\n \"electric_piano_2\",\n \"english_horn\",\n \"fiddle\",\n \"flute\",\n \"french_horn\",\n \"fretless_bass\",\n \"fx_1_rain\",\n \"fx_2_soundtrack\",\n \"fx_3_crystal\",\n \"fx_4_atmosphere\",\n \"fx_5_brightness\",\n \"fx_6_goblins\",\n \"fx_7_echoes\",\n \"fx_8_scifi\",\n \"glockenspiel\",\n \"guitar_fret_noise\",\n \"guitar_harmonics\",\n \"gunshot\",\n \"harmonica\",\n \"harpsichord\",\n \"helicopter\",\n \"honkytonk_piano\",\n \"kalimba\",\n \"koto\",\n \"lead_1_square\",\n \"lead_2_sawtooth\",\n \"lead_3_calliope\",\n \"lead_4_chiff\",\n \"lead_5_charang\",\n \"lead_6_voice\",\n \"lead_7_fifths\",\n \"lead_8_bass__lead\",\n \"marimba\",\n \"melodic_tom\",\n \"music_box\",\n \"muted_trumpet\",\n \"oboe\",\n \"ocarina\",\n \"orchestra_hit\",\n \"orchestral_harp\",\n \"overdriven_guitar\",\n \"pad_1_new_age\",\n \"pad_2_warm\",\n \"pad_3_polysynth\",\n \"pad_4_choir\",\n \"pad_5_bowed\",\n \"pad_6_metallic\",\n \"pad_7_halo\",\n \"pad_8_sweep\",\n \"pan_flute\",\n \"percussive_organ\",\n \"piccolo\",\n \"pizzicato_strings\",\n \"recorder\",\n \"reed_organ\",\n \"reverse_cymbal\",\n \"rock_organ\",\n \"seashore\",\n \"shakuhachi\",\n \"shamisen\",\n \"shanai\",\n \"sitar\",\n \"slap_bass_1\",\n \"slap_bass_2\",\n \"soprano_sax\",\n \"steel_drums\",\n \"string_ensemble_1\",\n \"string_ensemble_2\",\n \"synth_bass_1\",\n \"synth_bass_2\",\n \"synth_brass_1\",\n \"synth_brass_2\",\n \"synth_choir\",\n \"synth_drum\",\n \"synth_strings_1\",\n \"synth_strings_2\",\n \"taiko_drum\",\n \"tango_accordion\",\n \"telephone_ring\",\n \"tenor_sax\",\n \"timpani\",\n \"tinkle_bell\",\n \"tremolo_strings\",\n \"trombone\",\n \"trumpet\",\n \"tuba\",\n \"tubular_bells\",\n \"vibraphone\",\n \"viola\",\n \"violin\",\n \"voice_oohs\",\n \"whistle\",\n \"woodblock\",\n \"xylophone\",\n ];\n}\n","import {\n AudioBuffers,\n findFirstSupportedFormat,\n loadAudioBuffer,\n} from \"./sampler/load-audio\";\nimport { toMidi } from \"./sampler/midi\";\nimport { Sampler, SamplerAudioLoader } from \"./sampler/sampler\";\n\n/**\n * Splendid Grand Piano options\n */\nexport type SplendidGrandPianoConfig = {\n baseUrl: string;\n destination: AudioNode;\n\n detune: number;\n volume: number;\n velocity: number;\n decayTime?: number;\n lpfCutoffHz?: number;\n};\n\nconst BASE_URL = \"https://danigb.github.io/samples/splendid-grand-piano\";\n\nexport class SplendidGrandPiano extends Sampler {\n constructor(\n context: AudioContext,\n options: Partial<SplendidGrandPianoConfig>\n ) {\n super(context, {\n destination: options.destination,\n\n detune: options.detune,\n volume: options.volume,\n velocity: options.velocity,\n decayTime: options.decayTime ?? 0.5,\n lpfCutoffHz: options.lpfCutoffHz,\n\n buffers: splendidGrandPianoLoader(options.baseUrl ?? BASE_URL),\n\n noteToSample: (note, buffers, config) => {\n const midi = toMidi(note.note);\n if (!midi) return [note.note, 0];\n\n const vel = note.velocity ?? config.velocity;\n const layerIdx = LAYERS.findIndex(\n (layer) => vel >= layer.vel_range[0] && vel <= layer.vel_range[1]\n );\n const layer = LAYERS[layerIdx];\n if (!layer) return [\"\", 0];\n\n return findNearestMidiInLayer(layer.name, midi, buffers);\n },\n });\n }\n}\n\nfunction findNearestMidiInLayer(\n prefix: string,\n midi: number,\n buffers: AudioBuffers\n): [string, number] {\n let i = 0;\n while (buffers[prefix + (midi + i)] === undefined && i < 128) {\n if (i > 0) i = -i;\n else i = -i + 1;\n }\n\n return i === 127 ? [prefix + midi, 0] : [prefix + (midi + i), -i * 100];\n}\n\nfunction splendidGrandPianoLoader(baseUrl: string): SamplerAudioLoader {\n const format = findFirstSupportedFormat([\"ogg\", \"m4a\"]) ?? \"ogg\";\n return async (context: AudioContext, buffers: AudioBuffers) => {\n for (const layer of LAYERS) {\n await Promise.all(\n layer.samples.map(async ([midi, name]) => {\n const url = `${baseUrl}/${name}.${format}`;\n const buffer = await loadAudioBuffer(context, url);\n if (buffer) buffers[layer.name + midi] = buffer;\n })\n );\n }\n };\n}\n\nexport const LAYERS = [\n {\n name: \"PPP\",\n vel_range: [1, 40],\n cutoff: 1000,\n samples: [\n [23, \"PP-B-1\"],\n [27, \"PP-D#0\"],\n [29, \"PP-F0\"],\n [31, \"PP-G0\"],\n [33, \"PP-A0\"],\n [35, \"PP-B0\"],\n [37, \"PP-C#1\"],\n [38, \"PP-D1\"],\n [40, \"PP-E1\"],\n [41, \"PP-F1\"],\n [43, \"PP-G1\"],\n [45, \"PP-A1\"],\n [47, \"PP-B1\"],\n [48, \"PP-C2\"],\n [50, \"PP-D2\"],\n [52, \"PP-E2\"],\n [53, \"PP-F2\"],\n [55, \"PP-G2\"],\n [56, \"PP-G#2\"],\n [57, \"PP-A2\"],\n [58, \"PP-A#2\"],\n [59, \"PP-B2\"],\n [60, \"PP-C3\"],\n [62, \"PP-D3\"],\n [64, \"PP-E3\"],\n [65, \"PP-F3\"],\n [67, \"PP-G3\"],\n [69, \"PP-A3\"],\n [71, \"PP-B3\"],\n [72, \"PP-C4\"],\n [74, \"PP-D4\"],\n [76, \"PP-E4\"],\n [77, \"PP-F4\"],\n [79, \"PP-G4\"],\n [80, \"PP-G#4\"],\n [81, \"PP-A4\"],\n [82, \"PP-A#4\"],\n [83, \"PP-B4\"],\n [85, \"PP-C#5\"],\n [86, \"PP-D5\"],\n [87, \"PP-D#5\"],\n [89, \"PP-F5\"],\n [90, \"PP-F#5\"],\n [91, \"PP-G5\"],\n [92, \"PP-G#5\"],\n [93, \"PP-A5\"],\n [94, \"PP-A#5\"],\n [95, \"PP-B5\"],\n [96, \"PP-C6\"],\n [97, \"PP-C#6\"],\n [98, \"PP-D6\"],\n [99, \"PP-D#6\"],\n [100, \"PP-E6\"],\n [101, \"PP-F6\"],\n [102, \"PP-F#6\"],\n [103, \"PP-G6\"],\n [104, \"PP-G#6\"],\n [105, \"PP-A6\"],\n [106, \"PP-A#6\"],\n [107, \"PP-B6\"],\n [108, \"PP-C7\"],\n ],\n },\n {\n name: \"PP\",\n vel_range: [41, 67],\n samples: [\n [23, \"PP-B-1\"],\n [27, \"PP-D#0\"],\n [29, \"PP-F0\"],\n [31, \"PP-G0\"],\n [33, \"PP-A0\"],\n [35, \"PP-B0\"],\n [37, \"PP-C#1\"],\n [38, \"PP-D1\"],\n [40, \"PP-E1\"],\n [41, \"PP-F1\"],\n [43, \"PP-G1\"],\n [45, \"PP-A1\"],\n [47, \"PP-B1\"],\n [48, \"PP-C2\"],\n [50, \"PP-D2\"],\n [52, \"PP-E2\"],\n [53, \"PP-F2\"],\n [55, \"PP-G2\"],\n [56, \"PP-G#2\"],\n [57, \"PP-A2\"],\n [58, \"PP-A#2\"],\n [59, \"PP-B2\"],\n [60, \"PP-C3\"],\n [62, \"PP-D3\"],\n [64, \"PP-E3\"],\n [65, \"PP-F3\"],\n [67, \"PP-G3\"],\n [69, \"PP-A3\"],\n [71, \"PP-B3\"],\n [72, \"PP-C4\"],\n [74, \"PP-D4\"],\n [76, \"PP-E4\"],\n [77, \"PP-F4\"],\n [79, \"PP-G4\"],\n [80, \"PP-G#4\"],\n [81, \"PP-A4\"],\n [82, \"PP-A#4\"],\n [83, \"PP-B4\"],\n [85, \"PP-C#5\"],\n [86, \"PP-D5\"],\n [87, \"PP-D#5\"],\n [89, \"PP-F5\"],\n [90, \"PP-F#5\"],\n [91, \"PP-G5\"],\n [92, \"PP-G#5\"],\n [93, \"PP-A5\"],\n [94, \"PP-A#5\"],\n [95, \"PP-B5\"],\n [96, \"PP-C6\"],\n [97, \"PP-C#6\"],\n [98, \"PP-D6\"],\n [99, \"PP-D#6\"],\n [100, \"PP-E6\"],\n [101, \"PP-F6\"],\n [102, \"PP-F#6\"],\n [103, \"PP-G6\"],\n [104, \"PP-G#6\"],\n [105, \"PP-A6\"],\n [106, \"PP-A#6\"],\n [107, \"PP-B6\"],\n [108, \"PP-C7\"],\n ],\n },\n {\n name: \"MP\",\n vel_range: [68, 84],\n samples: [\n [23, \"Mp-B-1\"],\n [27, \"Mp-D#0\"],\n [29, \"Mp-F0\"],\n [31, \"Mp-G0\"],\n [33, \"Mp-A0\"],\n [35, \"Mp-B0\"],\n [37, \"Mp-C#1\"],\n [38, \"Mp-D1\"],\n [40, \"Mp-E1\"],\n [41, \"Mp-F1\"],\n [43, \"Mp-G1\"],\n [45, \"Mp-A1\"],\n [47, \"Mp-B1\"],\n [48, \"Mp-C2\"],\n [50, \"Mp-D2\"],\n [52, \"Mp-E2\"],\n [53, \"Mp-F2\"],\n [55, \"Mp-G2\"],\n [56, \"Mp-G#2\"],\n [57, \"Mp-A2\"],\n [58, \"Mp-A#2\"],\n [59, \"Mp-B2\"],\n [60, \"Mp-C3\"],\n [62, \"Mp-D3\"],\n [64, \"Mp-E3\"],\n [65, \"Mp-F3\"],\n [67, \"Mp-G3\"],\n [69, \"Mp-A3\"],\n [71, \"Mp-B3\"],\n [72, \"Mp-C4\"],\n [74, \"Mp-D4\"],\n [76, \"Mp-E4\"],\n [77, \"Mp-F4\"],\n [79, \"Mp-G4\"],\n [80, \"Mp-G#4\"],\n [81, \"Mp-A4\"],\n [82, \"Mp-A#4\"],\n [83, \"Mp-B4\"],\n [85, \"Mp-C#5\"],\n [86, \"Mp-D5\"],\n [87, \"Mp-D#5\"],\n [88, \"Mp-E5\"],\n [89, \"Mp-F5\"],\n [90, \"Mp-F#5\"],\n [91, \"Mp-G5\"],\n [92, \"Mp-G#5\"],\n [93, \"Mp-A5\"],\n [94, \"Mp-A#5\"],\n [95, \"Mp-B5\"],\n [96, \"Mp-C6\"],\n [97, \"Mp-C#6\"],\n [98, \"Mp-D6\"],\n [99, \"Mp-D#6\"],\n [100, \"PP-E6\"],\n [101, \"Mp-F6\"],\n [102, \"Mp-F#6\"],\n [103, \"Mp-G6\"],\n [104, \"Mp-G#6\"],\n [105, \"Mp-A6\"],\n [106, \"Mp-A#6\"],\n [107, \"PP-B6\"],\n [108, \"PP-C7\"],\n ],\n },\n {\n name: \"MF\",\n vel_range: [85, 100],\n samples: [\n [23, \"Mf-B-1\"],\n [27, \"Mf-D#0\"],\n [29, \"Mf-F0\"],\n [31, \"Mf-G0\"],\n [33, \"Mf-A0\"],\n [35, \"Mf-B0\"],\n [37, \"Mf-C#1\"],\n [38, \"Mf-D1\"],\n [40, \"Mf-E1\"],\n [41, \"Mf-F1\"],\n [43, \"Mf-G1\"],\n [45, \"Mf-A1\"],\n [47, \"Mf-B1\"],\n [48, \"Mf-C2\"],\n [50, \"Mf-D2\"],\n [52, \"Mf-E2\"],\n [53, \"Mf-F2\"],\n [55, \"Mf-G2\"],\n [56, \"Mf-G#2\"],\n [57, \"Mf-A2\"],\n [58, \"Mf-A#2\"],\n [59, \"Mf-B2\"],\n [60, \"Mf-C3\"],\n [62, \"Mf-D3\"],\n [64, \"Mf-E3\"],\n [65, \"Mf-F3\"],\n [67, \"Mf-G3\"],\n [69, \"Mf-A3\"],\n [71, \"Mf-B3\"],\n [72, \"Mf-C4\"],\n [74, \"Mf-D4\"],\n [76, \"Mf-E4\"],\n [77, \"Mf-F4\"],\n [79, \"Mf-G4\"],\n [80, \"Mf-G#4\"],\n [81, \"Mf-A4\"],\n [82, \"Mf-A#4\"],\n [83, \"Mf-B4\"],\n [85, \"Mf-C#5\"],\n [86, \"Mf-D5\"],\n [87, \"Mf-D#5\"],\n [88, \"Mf-E5\"],\n [89, \"Mf-F5\"],\n [90, \"Mf-F#5\"],\n [91, \"Mf-G5\"],\n [92, \"Mf-G#5\"],\n [93, \"Mf-A5\"],\n [94, \"Mf-A#5\"],\n [95, \"Mf-B5\"],\n [96, \"Mf-C6\"],\n [97, \"Mf-C#6\"],\n [98, \"Mf-D6\"],\n [99, \"Mf-D#6\"],\n [100, \"Mf-E6\"],\n [101, \"Mf-F6\"],\n [102, \"Mf-F#6\"],\n [103, \"Mf-G6\"],\n [104, \"Mf-G#6\"],\n [105, \"Mf-A6\"],\n [106, \"Mf-A#6\"],\n [107, \"Mf-B6\"],\n [108, \"PP-C7\"],\n ],\n },\n {\n name: \"FF\",\n vel_range: [101, 127],\n samples: [\n [23, \"FF-B-1\"],\n [27, \"FF-D#0\"],\n [29, \"FF-F0\"],\n [31, \"FF-G0\"],\n [33, \"FF-A0\"],\n [35, \"FF-B0\"],\n [37, \"FF-C#1\"],\n [38, \"FF-D1\"],\n [40, \"FF-E1\"],\n [41, \"FF-F1\"],\n [43, \"FF-G1\"],\n [45, \"FF-A1\"],\n [47, \"FF-B1\"],\n [48, \"FF-C2\"],\n [50, \"FF-D2\"],\n [52, \"FF-E2\"],\n [53, \"FF-F2\"],\n [55, \"FF-G2\"],\n [56, \"FF-G#2\"],\n [57, \"FF-A2\"],\n [58, \"FF-A#2\"],\n [59, \"FF-B2\"],\n [60, \"FF-C3\"],\n [62, \"FF-D3\"],\n [64, \"FF-E3\"],\n [65, \"FF-F3\"],\n [67, \"FF-G3\"],\n [69, \"FF-A3\"],\n [71, \"FF-B3\"],\n [72, \"FF-C4\"],\n [74, \"FF-D4\"],\n [76, \"FF-E4\"],\n [77, \"FF-F4\"],\n [79, \"FF-G4\"],\n [80, \"FF-G#4\"],\n [81, \"FF-A4\"],\n [82, \"FF-A#4\"],\n [83, \"FF-B4\"],\n [85, \"FF-C#5\"],\n [86, \"FF-D5\"],\n [88, \"FF-E5\"],\n [89, \"FF-F5\"],\n [91, \"FF-G5\"],\n [93, \"FF-A5\"],\n [95, \"Mf-B5\"],\n [96, \"Mf-C6\"],\n [97, \"Mf-C#6\"],\n [98, \"Mf-D6\"],\n [99, \"Mf-D#6\"],\n [100, \"Mf-E6\"],\n [102, \"Mf-F#6\"],\n [103, \"Mf-G6\"],\n [104, \"Mf-G#6\"],\n [105, \"Mf-A6\"],\n [106, \"Mf-A#6\"],\n [107, \"Mf-B6\"],\n [108, \"Mf-C7\"],\n ],\n },\n];\n"],"mappings":"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AA,MACb,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,QAAQ;AAAA,MACb,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,QAAQ;AAAA,MACb,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,QAAQ;AAAA,MACb,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,QAAQ;AAAA,MACb,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,QAAQ;AAAA,MACb,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,QAAQ;AAAA,MACb,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,QAAQ;AAAA,MACb,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,QAAQ;AAAA,MACb,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,QAAQ;AAAA,MACb,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,QAAQ;AAAA,MACb,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,QAAQ;AA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","names":["canPlay","volume","send","instrument","urls","_config","_stop","_load","_output","_a","depth","INSTRUMENTS","_output","BASE_URL","_a","layer"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/sampler/load-audio.ts","../src/sampler/connect.ts","../src/sampler/midi.ts","../src/sampler/signals.ts","../src/sampler/channel.ts","../src/sampler/start-sample.ts","../src/sampler/sampler.ts","../src/drum-machine/dm-instrument.ts","../src/drum-machine/drum-machine.ts","../src/sfz/sfz-load.ts","../src/sfz/sfz-regions.ts","../src/sfz/sfz-sampler.ts","../src/tremolo.ts","../src/electric-piano.ts","../src/mallet.ts","../src/reverb/processor.min.ts","../src/reverb/reverb.ts","../src/soundfont/soundfont.ts","../src/splendid-grand-piano.ts"],"sourcesContent":["export * from \"./drum-machine/drum-machine\";\nexport * from \"./electric-piano\";\nexport * from \"./mallet\";\nexport * from \"./reverb/reverb\";\nexport * from \"./sampler/sampler\";\nexport * from \"./soundfont/soundfont\";\nexport * from \"./splendid-grand-piano\";\n","export type AudioBuffers = Record<string | number, AudioBuffer | undefined>;\n\nexport async function loadAudioBuffer(\n context: BaseAudioContext,\n url: string\n): Promise<AudioBuffer | undefined> {\n url = url.replace(/#/g, \"%23\").replace(/([^:]\\/)\\/+/g, \"$1\");\n const response = await fetch(url);\n if (response.status !== 200) {\n console.warn(\n \"Error loading buffer. Invalid status: \",\n response.status,\n url\n );\n return;\n }\n try {\n const audioData = await response.arrayBuffer();\n const buffer = await context.decodeAudioData(audioData);\n return buffer;\n } catch (error) {\n console.warn(\"Error loading buffer\", error, url);\n }\n}\n\nexport function findFirstSupportedFormat(formats: string[]): string | null {\n if (typeof document === \"undefined\") return null;\n\n const audio = document.createElement(\"audio\");\n for (let i = 0; i < formats.length; i++) {\n const format = formats[i];\n const canPlay = audio.canPlayType(`audio/${format}`);\n if (canPlay === \"probably\" || canPlay === \"maybe\") {\n return format;\n }\n // check Safari for aac format\n if (format === \"m4a\") {\n const canPlay = audio.canPlayType(`audio/aac`);\n if (canPlay === \"probably\" || canPlay === \"maybe\") {\n return format;\n }\n }\n }\n return null;\n}\n","export type AudioInsert = {\n input: AudioNode;\n output: AudioNode;\n};\n\nexport function connectSerial(nodes: (AudioNode | AudioInsert | undefined)[]) {\n const _nodes = nodes.filter((x): x is AudioNode | AudioInsert => !!x);\n _nodes.reduce((a, b) => {\n const left = \"output\" in a ? a.output : a;\n const right = \"input\" in b ? b.input : b;\n left.connect(right);\n return b;\n });\n\n return () => {\n _nodes.reduce((a, b) => {\n const left = \"output\" in a ? a.output : a;\n const right = \"input\" in b ? b.input : b;\n left.disconnect(right);\n return b;\n });\n };\n}\n\nexport function connectAudioBus(\n node: AudioNode,\n destination: AudioNode,\n gain: number\n) {\n const mix = node.context.createGain();\n mix.gain.value = gain;\n node.connect(mix);\n mix.connect(destination);\n\n return () => {\n node.disconnect(mix);\n mix.disconnect(destination);\n };\n}\n","function noteNameToMidi(note: string): number | undefined {\n const REGEX = /^([a-gA-G]?)(#{1,}|b{1,}|)(-?\\d+)$/;\n const m = REGEX.exec(note);\n if (!m) return;\n const letter = m[1].toUpperCase();\n if (!letter) return;\n\n const acc = m[2];\n const alt = acc[0] === \"b\" ? -acc.length : acc.length;\n const oct = m[3] ? +m[3] : 4;\n\n const step = (letter.charCodeAt(0) + 3) % 7;\n return [0, 2, 4, 5, 7, 9, 11][step] + alt + 12 * (oct + 1);\n}\n\nexport function toMidi(note: string | number | undefined): number | undefined {\n return note === undefined\n ? undefined\n : typeof note === \"number\"\n ? note\n : noteNameToMidi(note);\n}\n\n/// This is how the MIDI association converts midi velocity [0..127] into gain [0..1]\n/// @see https://www.midi.org/specifications/file-format-specifications/dls-downloadable-sounds/dls-level-1\nexport function midiVelToGain(vel: number) {\n return (vel * vel) / 16129; // 16129 = 127 * 127\n}\nexport function findNearestMidi(\n midi: number,\n isAvailable: Record<string | number, unknown>\n): [number, number] {\n let i = 0;\n while (isAvailable[midi + i] === undefined && i < 128) {\n if (i > 0) i = -i;\n else i = -i + 1;\n }\n\n return i === 127 ? [midi, 0] : [midi + i, -i * 100];\n}\n","/**\n * A function to unsubscribe from an event or control\n */\nexport type Unsubscribe = () => void;\n/**\n * A function that listener to event or control changes\n */\nexport type Listener<T> = (value: T) => void;\n/**\n * A function to subscribe an trigger or control events\n */\nexport type Subscribe<T> = (listener: Listener<T>) => Unsubscribe;\n\n/**\n * A trigger is a subscribable event\n */\nexport type Trigger<T> = {\n subscribe: Subscribe<T>;\n trigger: (event: T) => void;\n};\n\n/**\n * A control is a subscribable value\n */\nexport type Control<T> = {\n subscribe: Subscribe<T>;\n set: (value: T) => void;\n get: () => T;\n};\n\n/**\n * Create a control signal\n * @param initialValue\n * @returns Control\n */\nexport function createControl<T>(initialValue: T): Control<T> {\n let current = initialValue;\n const listeners = new Set<Listener<T>>();\n\n function subscribe(listener: Listener<T>) {\n listeners.add(listener);\n listener(current);\n return () => {\n listeners.delete(listener);\n };\n }\n\n function set(value: T) {\n current = value;\n listeners.forEach((listener) => listener(current));\n }\n\n function get(): T {\n return current;\n }\n return { subscribe, set, get };\n}\n\nexport function createTrigger<T>(): Trigger<T> {\n const listeners = new Set<Listener<T>>();\n\n function subscribe(listener: Listener<T>) {\n listeners.add(listener);\n return () => {\n listeners.delete(listener);\n };\n }\n\n function trigger(value: T) {\n listeners.forEach((listener) => listener(value));\n }\n\n return { subscribe, trigger };\n}\n\nexport function unsubscribeAll(unsubscribe: Array<Unsubscribe | undefined>) {\n let done = false;\n return () => {\n if (done) return;\n done = true;\n unsubscribe.forEach((cb) => cb?.());\n };\n}\n","import { AudioInsert, connectSerial } from \"./connect\";\nimport { midiVelToGain } from \"./midi\";\nimport { createControl } from \"./signals\";\n\ntype ChannelOptions = {\n destination: AudioNode;\n volume: number;\n volumeToGain: (volume: number) => number;\n};\n\ntype Send = {\n name: string;\n mix: GainNode;\n disconnect: () => void;\n};\n\n/**\n * @private\n */\nexport class Channel {\n public readonly setVolume: (vol: number) => void;\n public readonly input: AudioNode;\n\n #volume: GainNode;\n #sends?: Send[];\n #inserts?: (AudioNode | AudioInsert)[];\n #disconnect: () => void;\n #unsubscribe: () => void;\n #options: Readonly<ChannelOptions>;\n\n constructor(\n public readonly context: AudioContext,\n options: Partial<ChannelOptions>\n ) {\n this.#options = Object.freeze({\n destination: context.destination,\n volume: 100,\n volumeToGain: midiVelToGain,\n ...options,\n });\n\n this.input = new GainNode(this.context);\n this.#volume = new GainNode(this.context);\n\n this.#disconnect = connectSerial([\n this.input,\n this.#volume,\n this.#options.destination,\n ]);\n\n const volume = createControl(options.volume ?? 100);\n this.setVolume = volume.set;\n const volumeToGain = options.volumeToGain ?? midiVelToGain;\n this.#unsubscribe = volume.subscribe((volume) => {\n this.#volume.gain.value = volumeToGain(volume);\n });\n }\n\n addInsert(effect: AudioNode | AudioInsert) {\n this.#inserts ??= [];\n this.#inserts.push(effect);\n this.#disconnect();\n this.#disconnect = connectSerial([\n this.input,\n ...this.#inserts,\n this.#volume,\n this.#options.destination,\n ]);\n }\n\n addEffect(\n name: string,\n effect: AudioNode | { input: AudioNode },\n mixValue: number\n ) {\n const mix = new GainNode(this.context);\n mix.gain.value = mixValue;\n const input = \"input\" in effect ? effect.input : effect;\n const disconnect = connectSerial([this.#volume, mix, input]);\n\n this.#sends ??= [];\n this.#sends.push({ name, mix, disconnect });\n }\n\n sendEffect(name: string, mix: number) {\n const send = this.#sends?.find((send) => send.name === name);\n if (send) {\n send.mix.gain.value = mix;\n } else {\n console.warn(\"Send bus not found: \" + name);\n }\n }\n\n disconnect() {\n this.#disconnect();\n this.#unsubscribe();\n this.#sends?.forEach((send) => send.disconnect());\n this.#sends = undefined;\n }\n}\n","import { connectSerial } from \"./connect\";\nimport { toMidi } from \"./midi\";\nimport { Subscribe, unsubscribeAll } from \"./signals\";\n\nexport type StopSample = {\n stopId?: string | number;\n time?: number;\n};\n\nexport type SampleOptions = {\n decayTime?: number;\n detune?: number;\n gain?: number;\n};\n\ntype SampleNote = {\n midi?: number;\n note?: string;\n};\n\nexport type StartSample = {\n buffer: AudioBuffer;\n decayTime?: number;\n destination: AudioNode;\n detune?: number;\n duration?: number;\n gain?: number;\n lpfCutoffHz?: number;\n onEnded?: () => void;\n stop?: Subscribe<StopSample | undefined>;\n stopId?: string | number;\n time?: number;\n};\n\nexport function getSampleNote<T extends SampleNote>(\n note: number | string | T\n): T {\n if (typeof note === \"number\") {\n return { midi: note } as T;\n } else if (typeof note === \"string\") {\n return { note, midi: toMidi(note) } as T;\n } else {\n return { midi: note.midi ?? toMidi(note.note), ...note };\n }\n}\n\nexport function startSample(sample: StartSample) {\n const context = sample.destination.context;\n // Buffer source\n const source = context.createBufferSource();\n source.buffer = sample.buffer;\n source.detune.value = sample?.detune ?? 0;\n\n // Low pass filter\n const lpf = sample.lpfCutoffHz\n ? new BiquadFilterNode(context, {\n type: \"lowpass\",\n frequency: sample.lpfCutoffHz,\n })\n : undefined;\n\n // Sample volume\n const volume = context.createGain();\n volume.gain.value = sample?.gain ?? 1.0;\n\n // Release decay\n const [decay, startDecay] = createDecayEnvelope(context, sample.decayTime);\n\n const cleanup = unsubscribeAll([\n connectSerial([source, lpf, volume, decay, sample.destination]),\n sample.stop?.((sampleStop) => {\n if (\n sampleStop === undefined ||\n sampleStop.stopId === undefined ||\n sampleStop.stopId === sample.stopId\n ) {\n stop(sampleStop?.time);\n }\n }),\n ]);\n source.onended = () => {\n cleanup();\n sample.onEnded?.();\n };\n\n const startAt = sample.time || context.currentTime;\n source.start(startAt);\n\n function stop(time?: number) {\n time ??= context.currentTime;\n if (time <= startAt) {\n source.stop(time);\n } else {\n const stopAt = startDecay(time);\n source.stop(stopAt);\n }\n }\n\n if (sample.duration !== undefined) {\n stop(startAt + sample.duration);\n }\n\n return stop;\n}\n\nfunction createDecayEnvelope(\n context: BaseAudioContext,\n envelopeTime = 0.2\n): [AudioNode, (time: number) => number] {\n let stopAt = 0;\n const envelope = new GainNode(context, { gain: 1.0 });\n\n function start(time: number): number {\n if (stopAt) return stopAt;\n envelope.gain.cancelScheduledValues(time);\n const envelopeAt = time || context.currentTime;\n stopAt = envelopeAt + envelopeTime;\n envelope.gain.setValueAtTime(1.0, envelopeAt);\n envelope.gain.linearRampToValueAtTime(0, stopAt);\n\n return stopAt;\n }\n\n return [envelope, start];\n}\n","import { Channel } from \"./channel\";\nimport { AudioBuffers, loadAudioBuffer } from \"./load-audio\";\nimport { midiVelToGain } from \"./midi\";\nimport { createTrigger, Trigger } from \"./signals\";\nimport { startSample, StopSample } from \"./start-sample\";\n\n/**\n * A function that downloads audio\n */\nexport type SamplerAudioLoader = (\n context: AudioContext,\n buffers: AudioBuffers\n) => Promise<void>;\n\nexport type SamplerConfig = {\n detune: number;\n volume: number;\n velocity: number;\n decayTime?: number;\n lpfCutoffHz?: number;\n destination: AudioNode;\n\n buffers: Record<string | number, string | AudioBuffers> | SamplerAudioLoader;\n volumeToGain: (volume: number) => number;\n noteToSample: (\n note: SamplerNote,\n buffers: AudioBuffers,\n config: SamplerConfig\n ) => [string | number, number];\n};\n\nexport type SamplerNote = {\n decayTime?: number;\n detune?: number;\n duration?: number;\n lpfCutoffHz?: number;\n note: string | number;\n onEnded?: (note: SamplerNote | string | number) => void;\n stopId?: string | number;\n time?: number;\n velocity?: number;\n};\n\n/**\n * A Sampler instrument\n *\n * @private\n */\nexport class Sampler {\n public readonly output: Omit<Channel, \"input\">;\n public readonly buffers: AudioBuffers;\n #config: SamplerConfig;\n #stop: Trigger<StopSample | undefined>;\n #load: Promise<void>;\n #output: Channel;\n\n public constructor(\n public readonly context: AudioContext,\n options: Partial<SamplerConfig>\n ) {\n this.#config = {\n destination: options.destination ?? context.destination,\n detune: 0,\n volume: options.volume ?? 100,\n velocity: options.velocity ?? 100,\n buffers: options.buffers ?? {},\n volumeToGain: options.volumeToGain ?? midiVelToGain,\n noteToSample:\n options.noteToSample ?? ((note) => [note.note.toString(), 0]),\n };\n this.buffers = {};\n this.#stop = createTrigger();\n const loader =\n typeof this.#config.buffers === \"function\"\n ? this.#config.buffers\n : createAudioBuffersLoader(this.#config.buffers);\n this.#load = loader(context, this.buffers);\n this.#output = new Channel(context, this.#config);\n this.output = this.#output;\n }\n\n async loaded(): Promise<this> {\n await this.#load;\n return this;\n }\n\n start(note: SamplerNote | string | number) {\n const _note: SamplerNote = typeof note === \"object\" ? note : { note: note };\n const [sample, detune] = this.#config.noteToSample(\n _note,\n this.buffers,\n this.#config\n );\n const buffer = this.buffers[sample];\n if (!buffer) {\n console.warn(`Sample not found: '${sample}'`);\n return () => undefined;\n }\n const onEnded = _note.onEnded;\n return startSample({\n buffer,\n destination: this.#output.input,\n\n time: _note.time,\n duration: _note.duration,\n\n decayTime: _note.decayTime,\n lpfCutoffHz: _note.lpfCutoffHz,\n detune: detune + (_note.detune ?? this.#config.detune),\n gain: this.#config.volumeToGain(_note.velocity ?? this.#config.velocity),\n\n stop: this.#stop.subscribe,\n stopId: _note.stopId ?? _note.note,\n onEnded: onEnded ? () => onEnded(note) : undefined,\n });\n }\n\n stop(note?: StopSample | string | number) {\n const note_ = typeof note === \"object\" ? note : { stopId: note };\n this.#stop.trigger(note_);\n }\n}\n\nfunction createAudioBuffersLoader(\n source: Record<string | number, string | AudioBuffers>\n): SamplerAudioLoader {\n return async (context, buffers) => {\n await Promise.all([\n Object.keys(source).map(async (key) => {\n const value = source[key];\n if (value instanceof AudioBuffer) {\n buffers[key] = value;\n } else if (typeof value === \"string\") {\n const buffer = await loadAudioBuffer(context, value);\n if (buffer) buffers[key] = buffer;\n }\n }),\n ]);\n };\n}\n","export type DrumMachineInstrument = {\n baseUrl: string;\n name: string;\n samples: string[];\n sampleNames: string[];\n nameToSample: Record<string, string | undefined>;\n sampleNameVariations: Record<string, string[]>;\n};\nexport const EMPTY_INSTRUMENT: DrumMachineInstrument = {\n baseUrl: \"\",\n name: \"\",\n samples: [],\n sampleNames: [],\n nameToSample: {},\n sampleNameVariations: {},\n};\n\nexport async function fetchDrumMachineInstrument(\n url: string\n): Promise<DrumMachineInstrument> {\n const res = await fetch(url);\n const json = await res.json();\n // need to fix json\n json.baseUrl = url.replace(\"/dm.json\", \"\");\n json.sampleNames = [];\n json.nameToSample = {};\n json.sampleNameVariations = {};\n for (const sampleSrc of json.samples) {\n const sample =\n sampleSrc.indexOf(\"/\") !== -1 ? sampleSrc : sampleSrc.replace(\"-\", \"/\");\n json.nameToSample[sample] = sample;\n const [base, variation] = sample.split(\"/\");\n if (!json.sampleNames.includes(base)) {\n json.sampleNames.push(base);\n }\n json.nameToSample[base] ??= sample;\n json.sampleNameVariations[base] ??= [];\n if (variation) {\n json.sampleNameVariations[base].push(`${base}/${variation}`);\n }\n }\n\n return json;\n}\n","import {\n findFirstSupportedFormat,\n loadAudioBuffer,\n} from \"../sampler/load-audio\";\nimport { Sampler, SamplerAudioLoader } from \"../sampler/sampler\";\nimport {\n DrumMachineInstrument,\n EMPTY_INSTRUMENT,\n fetchDrumMachineInstrument,\n} from \"./dm-instrument\";\n\nexport function getDrumMachineNames() {\n return Object.keys(INSTRUMENTS);\n}\n\nconst INSTRUMENTS: Record<string, string> = {\n \"TR-808\": \"https://danigb.github.io/samples/drum-machines/TR-808/dm.json\",\n \"Casio-RZ1\":\n \"https://danigb.github.io/samples/drum-machines/Casio-RZ1/dm.json\",\n \"LM-2\": \"https://danigb.github.io/samples/drum-machines/LM-2/dm.json\",\n \"MFB-512\": \"https://danigb.github.io/samples/drum-machines/MFB-512/dm.json\",\n \"Roland CR-8000\":\n \"https://danigb.github.io/samples/drum-machines/Roland-CR-8000/dm.json\",\n};\n\nexport type DrumMachineConfig = {\n instrument: string;\n destination: AudioNode;\n\n detune: number;\n volume: number;\n velocity: number;\n decayTime?: number;\n lpfCutoffHz?: number;\n};\n\nexport class DrumMachine extends Sampler {\n #instrument = EMPTY_INSTRUMENT;\n public constructor(\n context: AudioContext,\n options: Partial<DrumMachineConfig>\n ) {\n const url = INSTRUMENTS[options.instrument ?? \"TR-808\"];\n if (!url) throw new Error(\"Invalid instrument: \" + options.instrument);\n const instrument = fetchDrumMachineInstrument(url);\n\n super(context, {\n ...options,\n buffers: drumMachineLoader(instrument),\n noteToSample: (note, buffers, config) => {\n const sample = this.#instrument.nameToSample[note.note];\n return [sample ?? \"\", 0];\n },\n });\n instrument.then((instrument) => {\n this.#instrument = instrument;\n });\n }\n\n get sampleNames(): string[] {\n return this.#instrument.sampleNames;\n }\n\n getVariations(name: string): string[] {\n return this.#instrument.sampleNameVariations[name] ?? [];\n }\n}\n\nfunction drumMachineLoader(\n instrument: Promise<DrumMachineInstrument>\n): SamplerAudioLoader {\n const format = findFirstSupportedFormat([\"ogg\", \"m4a\"]) ?? \"ogg\";\n return async (context, buffers) => {\n const dm = await instrument;\n await Promise.all(\n dm.samples.map(async (sample) => {\n const url = `${dm.baseUrl}/${sample}.${format}`;\n const sampleName =\n sample.indexOf(\"/\") !== -1 ? sample : sample.replace(\"-\", \"/\");\n const buffer = await loadAudioBuffer(context, url);\n if (buffer) buffers[sampleName] = buffer;\n })\n );\n };\n}\n","import {\n AudioBuffers,\n findFirstSupportedFormat,\n loadAudioBuffer,\n} from \"../sampler/load-audio\";\nimport { SfzInstrument } from \"./sfz-kits\";\nimport { Websfz, WebsfzGroup } from \"./websfz\";\n\nexport async function loadSfzBuffers(\n context: AudioContext,\n buffers: AudioBuffers,\n websfz: Websfz\n) {\n websfz.groups.forEach((group) => {\n const urls = getWebsfzGroupUrls(websfz, group);\n return loadAudioBuffers(context, buffers, urls);\n });\n}\n\nexport async function loadSfzInstrument(\n instrument: string | Websfz | SfzInstrument\n): Promise<Websfz> {\n const isWebsfz = (inst: any): inst is Websfz => \"global\" in inst;\n const isSfzInstrument = (inst: any): inst is SfzInstrument =>\n \"websfzUrl\" in inst;\n\n if (typeof instrument === \"string\") {\n return fetchWebSfz(instrument);\n } else if (isWebsfz(instrument)) {\n return instrument;\n } else if (isSfzInstrument(instrument)) {\n const websfz = await fetchWebSfz(instrument.websfzUrl);\n websfz.meta ??= {};\n if (instrument.name) websfz.meta.name = instrument.name;\n if (instrument.baseUrl) websfz.meta.baseUrl = instrument.baseUrl;\n if (instrument.formats) websfz.meta.formats = instrument.formats;\n return websfz;\n } else {\n throw new Error(\"Invalid instrument: \" + JSON.stringify(instrument));\n }\n}\n\n// @private\nasync function loadAudioBuffers(\n context: AudioContext,\n buffers: AudioBuffers,\n urls: Record<string, string>\n) {\n await Promise.all(\n Object.keys(urls).map(async (sampleId) => {\n if (buffers[sampleId]) return;\n\n const buffer = await loadAudioBuffer(context, urls[sampleId]);\n if (buffer) buffers[sampleId] = buffer;\n return buffers;\n })\n );\n}\n\n// @private\nasync function fetchWebSfz(url: string): Promise<Websfz> {\n try {\n const response = await fetch(url);\n const json = await response.json();\n return json as Websfz;\n } catch (error) {\n console.warn(`Can't load SFZ file ${url}`, error);\n throw new Error(`Can't load SFZ file ${url}`);\n }\n}\n\n// @private\nexport function getWebsfzGroupUrls(websfz: Websfz, group: WebsfzGroup) {\n const urls: Record<string, string> = {};\n const baseUrl = websfz.meta.baseUrl ?? \"\";\n const format = findFirstSupportedFormat(websfz.meta.formats ?? []) ?? \"ogg\";\n\n const prefix = websfz.global[\"default_path\"] ?? \"\";\n\n if (!group) return urls;\n\n return group.regions.reduce((urls, region) => {\n if (region.sample) {\n urls[region.sample] = `${baseUrl}/${prefix}${region.sample}.${format}`;\n }\n return urls;\n }, urls);\n}\n","import { Websfz, WebsfzGroup, WebsfzRegion } from \"./websfz\";\n\nfunction checkRange(value?: number, low?: number, hi?: number) {\n const isAboveLow = low === undefined || (value !== undefined && value >= low);\n const isBelowHi = hi === undefined || (value !== undefined && value <= hi);\n return isAboveLow && isBelowHi;\n}\n\nexport function findRegions(\n websfz: Websfz,\n note: { midi?: number; velocity?: number; cc64?: number }\n): [WebsfzGroup, WebsfzRegion][] {\n const regions: [WebsfzGroup, WebsfzRegion][] = [];\n for (const group of websfz.groups) {\n if (\n checkRange(note.midi, group.lokey, group.hikey) &&\n checkRange(note.velocity, group.lovel, group.hivel) &&\n checkRange(note.cc64, group.locc64, group.hicc64)\n ) {\n for (const region of group.regions) {\n if (\n checkRange(note.midi, region.lokey, region.hikey) &&\n checkRange(note.velocity, region.lovel, region.hivel) &&\n checkRange(note.cc64, group.locc64, group.hicc64)\n ) {\n regions.push([group, region]);\n }\n }\n }\n }\n return regions;\n}\n","import { Channel } from \"../sampler/channel\";\nimport { AudioBuffers } from \"../sampler/load-audio\";\nimport { midiVelToGain, toMidi } from \"../sampler/midi\";\nimport { SamplerNote } from \"../sampler/sampler\";\nimport { createTrigger, Trigger } from \"../sampler/signals\";\nimport { startSample, StopSample } from \"../sampler/start-sample\";\nimport { SfzInstrument } from \"./sfz-kits\";\nimport { loadSfzBuffers, loadSfzInstrument } from \"./sfz-load\";\nimport { findRegions } from \"./sfz-regions\";\nimport { Websfz } from \"./websfz\";\n\n/**\n * Splendid Grand Piano options\n */\nexport type SfzSamplerConfig = {\n instrument: SfzInstrument | Websfz | string;\n destination: AudioNode;\n volume: number;\n velocity: number;\n detune: number;\n decayTime: number;\n lpfCutoffHz?: number;\n};\n\nconst EMPTY_WEBSFZ: Websfz = Object.freeze({\n meta: {},\n global: {},\n groups: [],\n});\n\nexport class SfzSampler {\n public readonly output: Omit<Channel, \"input\">;\n public readonly buffers: AudioBuffers;\n #websfz: Websfz;\n #config: SfzSamplerConfig;\n #stop: Trigger<StopSample | undefined>;\n #load: Promise<void>;\n #output: Channel;\n\n constructor(\n public readonly context: AudioContext,\n options: Partial<SfzSamplerConfig> & Pick<SfzSamplerConfig, \"instrument\">\n ) {\n this.#config = {\n instrument: options.instrument,\n destination: options.destination ?? context.destination,\n detune: 0,\n volume: options.volume ?? 100,\n velocity: options.velocity ?? 100,\n decayTime: 0.3,\n };\n this.buffers = {};\n this.#stop = createTrigger();\n\n this.#websfz = EMPTY_WEBSFZ;\n this.#load = loadSfzInstrument(options.instrument).then((result) => {\n this.#websfz = Object.freeze(result);\n return loadSfzBuffers(context, this.buffers, this.#websfz);\n });\n this.#output = new Channel(context, this.#config);\n this.output = this.#output;\n }\n async loaded(): Promise<this> {\n await this.#load;\n return this;\n }\n\n start(note: SamplerNote | string | number) {\n const _note: SamplerNote = typeof note === \"object\" ? note : { note: note };\n const midi = toMidi(_note.note);\n if (midi === undefined) return () => undefined;\n\n const velocity = _note.velocity ?? this.#config.velocity;\n const regions = findRegions(this.#websfz, { midi, velocity });\n\n const stopAll = regions.map(([group, region]) => {\n let target = region.pitch_keycenter ?? region.key ?? midi;\n const detune = (midi - target) * 100;\n\n const destination = (this.output as Channel).input;\n\n let buffer = this.buffers[region.sample];\n if (!buffer) {\n console.warn(`Sample not found: ${region.sample}`);\n return () => undefined;\n }\n\n const onEnded = _note.onEnded;\n\n return startSample({\n buffer,\n destination,\n decayTime: _note.decayTime ?? this.#config.decayTime,\n detune: detune + (_note.detune ?? this.#config.detune),\n gain: midiVelToGain(_note.velocity ?? this.#config.velocity),\n time: _note.time,\n duration: _note.duration,\n stop: this.#stop.subscribe,\n stopId: _note.stopId ?? _note.note,\n onEnded: onEnded ? () => onEnded(note) : undefined,\n });\n });\n return (time?: number) => stopAll.forEach((stop) => stop(time));\n }\n\n stop(note?: StopSample | string | number) {\n const note_ = typeof note === \"object\" ? note : { stopId: note };\n this.#stop.trigger(note_);\n }\n\n disconnect() {\n this.stop();\n this.#output.disconnect();\n }\n}\n","import { AudioInsert } from \"./sampler/connect\";\nimport { Subscribe } from \"./sampler/signals\";\n\n// @private\nexport function createTremolo(\n context: AudioContext,\n depth: Subscribe<number>\n): AudioInsert {\n const input = new GainNode(context);\n const output = new GainNode(context);\n\n // force mono sources to be stereo\n input.channelCount = 2;\n input.channelCountMode = \"explicit\";\n\n const splitter = new ChannelSplitterNode(context, { numberOfOutputs: 2 });\n const ampL = new GainNode(context);\n const ampR = new GainNode(context);\n const merger = new ChannelMergerNode(context, { numberOfInputs: 2 });\n\n const lfoL = new OscillatorNode(context, {\n type: \"sine\",\n frequency: 1,\n });\n lfoL.start();\n const lfoLAmp = new GainNode(context);\n const lfoR = new OscillatorNode(context, {\n type: \"sine\",\n frequency: 1.1,\n });\n lfoR.start();\n const lfoRAmp = new GainNode(context);\n\n input.connect(splitter);\n splitter.connect(ampL, 0);\n splitter.connect(ampR, 1);\n ampL.connect(merger, 0, 0);\n ampR.connect(merger, 0, 1);\n lfoL.connect(lfoLAmp);\n lfoLAmp.connect(ampL.gain);\n lfoR.connect(lfoRAmp);\n lfoRAmp.connect(ampR.gain);\n merger.connect(output);\n\n const unsubscribe = depth((depth) => {\n lfoLAmp.gain.value = depth;\n lfoRAmp.gain.value = depth;\n });\n\n input.disconnect = () => {\n unsubscribe();\n lfoL.stop();\n lfoR.stop();\n input.disconnect(splitter);\n splitter.disconnect(ampL, 0);\n splitter.disconnect(ampR, 1);\n ampL.disconnect(merger, 0, 0);\n ampR.disconnect(merger, 0, 1);\n lfoL.disconnect(ampL);\n lfoR.disconnect(ampR);\n merger.disconnect(output);\n };\n\n return { input, output };\n}\n","import { midiVelToGain } from \"./sampler/midi\";\nimport { createControl } from \"./sampler/signals\";\nimport { SfzSampler, SfzSamplerConfig } from \"./sfz/sfz-sampler\";\nimport { createTremolo } from \"./tremolo\";\n\nexport function getElectricPianoNames() {\n return Object.keys(INSTRUMENTS);\n}\n\nconst INSTRUMENTS: Record<string, string> = {\n CP80: \"https://danigb.github.io/samples/gs-e-pianos/CP80/cp80.websfz.json\",\n PianetT:\n \"https://danigb.github.io/samples/gs-e-pianos/Pianet T/pianet-t.websfz.json\",\n WurlitzerEP200:\n \"https://danigb.github.io/samples/gs-e-pianos/Wurlitzer EP200/wurlitzer-ep200.websfz.json\",\n TX81Z:\n \"https://danigb.github.io/samples/vcsl/TX81Z/tx81z-fm-piano.websfz.json\",\n};\n\nexport class ElectricPiano extends SfzSampler {\n public readonly tremolo: Readonly<{ level: (value: number) => void }>;\n constructor(\n context: AudioContext,\n options: Partial<SfzSamplerConfig> & { instrument: string }\n ) {\n super(context, {\n ...options,\n instrument: INSTRUMENTS[options.instrument] ?? options.instrument,\n });\n const depth = createControl(0);\n this.tremolo = {\n level: (level) => depth.set(midiVelToGain(level)),\n };\n const tremolo = createTremolo(context, depth.subscribe);\n this.output.addInsert(tremolo);\n }\n}\n","import { SfzInstrument } from \"./sfz/sfz-kits\";\nimport { SfzSampler, SfzSamplerConfig } from \"./sfz/sfz-sampler\";\n\nexport function getMalletNames() {\n return Object.keys(NAME_TO_PATH) as MalletName[];\n}\n\nexport class Mallet extends SfzSampler {\n constructor(\n context: AudioContext,\n options: Partial<SfzSamplerConfig> & { instrument: string }\n ) {\n const instrument = getMallet(options.instrument);\n super(context, {\n ...options,\n instrument,\n });\n }\n}\n\nfunction getMallet(name: MalletName | string): SfzInstrument {\n if (!NAME_TO_PATH[name]) throw Error(`Mallet instrument \"${name}\" not valid`);\n return {\n name: name,\n websfzUrl: BASE_URL + NAME_TO_PATH[name] + EXT,\n };\n}\nconst BASE_URL = \"https://danigb.github.io/samples/vcsl/\";\nconst EXT = \".websfz.json\";\n\ntype MalletName = keyof typeof NAME_TO_PATH;\n\nexport const NAME_TO_PATH: Record<string, string | undefined> = {\n \"Balafon - Hard Mallet\": \"Struck Idiophones/balafon-hard-mallet\",\n \"Balafon - Keyswitch\": \"Struck Idiophones/balafon-keyswitch\",\n \"Balafon - Soft Mallet\": \"Struck Idiophones/balafon-soft-mallet\",\n \"Balafon - Traditional Mallet\":\n \"Struck Idiophones/balafon-traditional-mallet\",\n \"Tubular Bells 1\": \"Struck Idiophones/tubular-bells-1\",\n \"Tubular Bells 2\": \"Struck Idiophones/tubular-bells-2\",\n \"Vibraphone - Hard Mallets\": \"Struck Idiophones/vibraphone-hard-mallets\",\n \"Vibraphone - Keyswitch\": \"Struck Idiophones/vibraphone-keyswitch\",\n \"Vibraphone - Soft Mallets\": \"Struck Idiophones/vibraphone-soft-mallets\",\n \"Xylophone - Hard Mallets\": \"Struck Idiophones/xylophone-hard-mallets\",\n \"Xylophone - Keyswitch\": \"Struck Idiophones/xylophone-keyswitch\",\n \"Xylophone - Medium Mallets\": \"Struck Idiophones/xylophone-medium-mallets\",\n \"Xylophone - Soft Mallets\": \"Struck Idiophones/xylophone-soft-mallets\",\n} as const;\n","export const PROCESSOR = `\"use strict\";(()=>{var f=class extends AudioWorkletProcessor{_pDLength;_preDelay;_pDWrite;_lp1;_lp2;_lp3;_excPhase;_taps;_Delays;sampleRate;static get parameterDescriptors(){return[[\"preDelay\",0,0,sampleRate-1,\"k-rate\"],[\"bandwidth\",.9999,0,1,\"k-rate\"],[\"inputDiffusion1\",.75,0,1,\"k-rate\"],[\"inputDiffusion2\",.625,0,1,\"k-rate\"],[\"decay\",.5,0,1,\"k-rate\"],[\"decayDiffusion1\",.7,0,.999999,\"k-rate\"],[\"decayDiffusion2\",.5,0,.999999,\"k-rate\"],[\"damping\",.005,0,1,\"k-rate\"],[\"excursionRate\",.5,0,2,\"k-rate\"],[\"excursionDepth\",.7,0,2,\"k-rate\"],[\"wet\",1,0,1,\"k-rate\"],[\"dry\",0,0,1,\"k-rate\"]].map(e=>new Object({name:e[0],defaultValue:e[1],minValue:e[2],maxValue:e[3],automationRate:e[4]}))}constructor(e){super(),this.sampleRate=sampleRate,this._Delays=[],this._pDLength=sampleRate+(128-sampleRate%128),this._preDelay=new Float32Array(this._pDLength),this._pDWrite=0,this._lp1=0,this._lp2=0,this._lp3=0,this._excPhase=0,[.004771345,.003595309,.012734787,.009307483,.022579886,.149625349,.060481839,.1249958,.030509727,.141695508,.089244313,.106280031].forEach(a=>this.makeDelay(a,sampleRate)),this._taps=Int16Array.from([.008937872,.099929438,.064278754,.067067639,.066866033,.006283391,.035818689,.011861161,.121870905,.041262054,.08981553,.070931756,.011256342,.004065724],a=>Math.round(a*sampleRate))}makeDelay(e,a){let t=Math.round(e*a),s=2**Math.ceil(Math.log2(t));this._Delays.push([new Float32Array(s),t-1,0,s-1])}writeDelay(e,a){return this._Delays[e][0][this._Delays[e][1]]=a}readDelay(e){return this._Delays[e][0][this._Delays[e][2]]}readDelayAt(e,a){let t=this._Delays[e];return t[0][t[2]+a&t[3]]}readDelayCAt(e,a){let t=this._Delays[e],s=a-~~a,d=~~a+t[2]-1,r=t[3],D=t[0][d++&r],l=t[0][d++&r],h=t[0][d++&r],y=t[0][d&r],u=(3*(l-h)-D+y)/2,m=2*h+D-(5*l+y)/2,c=(h-D)/2;return((u*s+m)*s+c)*s+l}process(e,a,t){let s=~~t.preDelay[0],d=t.bandwidth[0],r=t.inputDiffusion1[0],D=t.inputDiffusion2[0],l=t.decay[0],h=t.decayDiffusion1[0],y=t.decayDiffusion2[0],u=1-t.damping[0],m=t.excursionRate[0]/sampleRate,c=t.excursionDepth[0]*sampleRate/1e3,w=t.wet[0]*.6,A=t.dry[0];if(e[0].length==2)for(let i=127;i>=0;i--)this._preDelay[this._pDWrite+i]=(e[0][0][i]+e[0][1][i])*.5,a[0][0][i]=e[0][0][i]*A,a[0][1][i]=e[0][1][i]*A;else if(e[0].length>0){this._preDelay.set(e[0][0],this._pDWrite);for(let i=127;i>=0;i--)a[0][0][i]=a[0][1][i]=e[0][0][i]*A}else this._preDelay.set(new Float32Array(128),this._pDWrite);let o=0;for(;o<128;){let i=0,b=0;this._lp1+=d*(this._preDelay[(this._pDLength+this._pDWrite-s+o)%this._pDLength]-this._lp1);let p=this.writeDelay(0,this._lp1-r*this.readDelay(0));p=this.writeDelay(1,r*(p-this.readDelay(1))+this.readDelay(0)),p=this.writeDelay(2,r*p+this.readDelay(1)-D*this.readDelay(2)),p=this.writeDelay(3,D*(p-this.readDelay(3))+this.readDelay(2));let k=D*p+this.readDelay(3),g=c*(1+Math.cos(this._excPhase*6.28)),x=c*(1+Math.sin(this._excPhase*6.2847)),_=this.writeDelay(4,k+l*this.readDelay(11)+h*this.readDelayCAt(4,g));this.writeDelay(5,this.readDelayCAt(4,g)-h*_),this._lp2+=u*(this.readDelay(5)-this._lp2),_=this.writeDelay(6,l*this._lp2-y*this.readDelay(6)),this.writeDelay(7,this.readDelay(6)+y*_),_=this.writeDelay(8,k+l*this.readDelay(7)+h*this.readDelayCAt(8,x)),this.writeDelay(9,this.readDelayCAt(8,x)-h*_),this._lp3+=u*(this.readDelay(9)-this._lp3),_=this.writeDelay(10,l*this._lp3-y*this.readDelay(10)),this.writeDelay(11,this.readDelay(10)+y*_),i=this.readDelayAt(9,this._taps[0])+this.readDelayAt(9,this._taps[1])-this.readDelayAt(10,this._taps[2])+this.readDelayAt(11,this._taps[3])-this.readDelayAt(5,this._taps[4])-this.readDelayAt(6,this._taps[5])-this.readDelayAt(7,this._taps[6]),b=this.readDelayAt(5,this._taps[7])+this.readDelayAt(5,this._taps[8])-this.readDelayAt(6,this._taps[9])+this.readDelayAt(7,this._taps[10])-this.readDelayAt(9,this._taps[11])-this.readDelayAt(10,this._taps[12])-this.readDelayAt(11,this._taps[13]),a[0][0][o]+=i*w,a[0][1][o]+=b*w,this._excPhase+=m,o++;for(let R=0,n=this._Delays[0];R<this._Delays.length;n=this._Delays[++R])n[1]=n[1]+1&n[3],n[2]=n[2]+1&n[3]}return this._pDWrite=(this._pDWrite+128)%this._pDLength,!0}};registerProcessor(\"DattorroReverb\",f);})();`;\n","import { PROCESSOR } from \"./processor.min\";\n\nconst PARAMS = [\n \"preDelay\",\n \"bandwidth\",\n \"inputDiffusion1\",\n \"inputDiffusion2\",\n \"decay\",\n \"decayDiffusion1\",\n \"decayDiffusion2\",\n \"damping\",\n \"excursionRate\",\n \"excursionDepth\",\n \"wet\",\n \"dry\",\n] as const;\n\nconst init = new WeakMap<AudioContext, Promise<void>>();\n\nasync function createDattorroReverbEffect(context: AudioContext) {\n let ready = init.get(context);\n if (!ready) {\n const blob = new Blob([PROCESSOR], { type: \"application/javascript\" });\n const url = URL.createObjectURL(blob);\n ready = context.audioWorklet.addModule(url);\n init.set(context, ready);\n }\n await ready;\n\n const reverb = new AudioWorkletNode(context, \"DattorroReverb\", {\n outputChannelCount: [2],\n });\n return reverb;\n}\n\nexport class Reverb {\n #effect: AudioWorkletNode | undefined;\n #ready: Promise<this>;\n public readonly input: AudioNode;\n #output: AudioNode;\n\n constructor(context: AudioContext) {\n this.input = context.createGain();\n this.#output = context.destination;\n this.#ready = createDattorroReverbEffect(context).then((reverb) => {\n this.input.connect(reverb);\n reverb.connect(this.#output);\n this.#effect = reverb;\n return this;\n });\n }\n\n get paramNames() {\n return PARAMS;\n }\n\n getParam(name: (typeof PARAMS)[number]): AudioParam | undefined {\n return this.#effect?.parameters.get(\"preDelay\");\n }\n\n get isReady(): boolean {\n return this.#effect !== undefined;\n }\n\n ready(): Promise<this> {\n return this.#ready;\n }\n\n connect(output: AudioNode) {\n if (this.#effect) {\n this.#effect.disconnect(this.#output);\n this.#effect.connect(output);\n }\n this.#output = output;\n }\n}\n","import { findFirstSupportedFormat } from \"../sampler/load-audio\";\nimport { findNearestMidi, toMidi } from \"../sampler/midi\";\nimport { Sampler, SamplerAudioLoader } from \"../sampler/sampler\";\n\nexport type SoundfontConfig = {\n kit: \"FluidR3_GM\" | \"MusyngKite\" | string;\n instrument: string;\n\n destination: AudioNode;\n\n detune: number;\n volume: number;\n velocity: number;\n decayTime?: number;\n lpfCutoffHz?: number;\n extraGain?: number;\n};\n\nexport class Soundfont extends Sampler {\n constructor(\n context: AudioContext,\n options: Partial<SoundfontConfig> & { instrument: string }\n ) {\n const url = options.instrument.startsWith(\"http\")\n ? options.instrument\n : gleitzKitUrl(options.instrument, options.kit ?? \"MusyngKite\");\n super(context, {\n destination: options.destination,\n\n detune: options.detune,\n volume: options.volume,\n velocity: options.velocity,\n decayTime: options.decayTime ?? 0.5,\n lpfCutoffHz: options.lpfCutoffHz,\n buffers: soundfontLoader(url),\n noteToSample: (note, buffers, config) => {\n let midi = toMidi(note.note);\n return midi === undefined ? [\"\", 0] : findNearestMidi(midi, buffers);\n },\n });\n\n // This is to compensate the low volume of the original samples\n const extraGain = options.extraGain ?? 5;\n const gain = new GainNode(context, { gain: extraGain });\n this.output.addInsert(gain);\n }\n}\n\nfunction soundfontLoader(url: string): SamplerAudioLoader {\n return async (context, buffers) => {\n const sourceFile = await (await fetch(url)).text();\n const json = midiJsToJson(sourceFile);\n\n const noteNames = Object.keys(json);\n await Promise.all(\n noteNames.map(async (noteName) => {\n const midi = toMidi(noteName);\n if (!midi) return;\n const audioData = base64ToArrayBuffer(\n removeBase64Prefix(json[noteName])\n );\n const buffer = await context.decodeAudioData(audioData);\n buffers[midi] = buffer;\n })\n );\n };\n}\n\n// convert a MIDI.js javascript soundfont file to json\nfunction midiJsToJson(source: string) {\n const header = source.indexOf(\"MIDI.Soundfont.\");\n if (header < 0) throw Error(\"Invalid MIDI.js Soundfont format\");\n const start = source.indexOf(\"=\", header) + 2;\n const end = source.lastIndexOf(\",\");\n return JSON.parse(source.slice(start, end) + \"}\");\n}\n\nfunction removeBase64Prefix(audioBase64: string) {\n return audioBase64.slice(audioBase64.indexOf(\",\") + 1);\n}\n\nfunction base64ToArrayBuffer(base64: string) {\n const decoded = window.atob(base64);\n const len = decoded.length;\n const bytes = new Uint8Array(len);\n for (let i = 0; i < len; i++) {\n bytes[i] = decoded.charCodeAt(i);\n }\n return bytes.buffer;\n}\n\nfunction gleitzKitUrl(name: string, kit: string) {\n const format = findFirstSupportedFormat([\"ogg\", \"mp3\"]) ?? \"mp3\";\n return `https://gleitz.github.io/midi-js-soundfonts/${kit}/${name}-${format}.js`;\n}\n\nexport function getSoundfontKits() {\n return [\"MusyngKite\", \"FluidR3_GM\"];\n}\n\nexport function getSoundfontNames() {\n return [\n \"accordion\",\n \"acoustic_bass\",\n \"acoustic_grand_piano\",\n \"acoustic_guitar_nylon\",\n \"acoustic_guitar_steel\",\n \"agogo\",\n \"alto_sax\",\n \"applause\",\n \"bagpipe\",\n \"banjo\",\n \"baritone_sax\",\n \"bassoon\",\n \"bird_tweet\",\n \"blown_bottle\",\n \"brass_section\",\n \"breath_noise\",\n \"bright_acoustic_piano\",\n \"celesta\",\n \"cello\",\n \"choir_aahs\",\n \"church_organ\",\n \"clarinet\",\n \"clavinet\",\n \"contrabass\",\n \"distortion_guitar\",\n \"drawbar_organ\",\n \"dulcimer\",\n \"electric_bass_finger\",\n \"electric_bass_pick\",\n \"electric_grand_piano\",\n \"electric_guitar_clean\",\n \"electric_guitar_jazz\",\n \"electric_guitar_muted\",\n \"electric_piano_1\",\n \"electric_piano_2\",\n \"english_horn\",\n \"fiddle\",\n \"flute\",\n \"french_horn\",\n \"fretless_bass\",\n \"fx_1_rain\",\n \"fx_2_soundtrack\",\n \"fx_3_crystal\",\n \"fx_4_atmosphere\",\n \"fx_5_brightness\",\n \"fx_6_goblins\",\n \"fx_7_echoes\",\n \"fx_8_scifi\",\n \"glockenspiel\",\n \"guitar_fret_noise\",\n \"guitar_harmonics\",\n \"gunshot\",\n \"harmonica\",\n \"harpsichord\",\n \"helicopter\",\n \"honkytonk_piano\",\n \"kalimba\",\n \"koto\",\n \"lead_1_square\",\n \"lead_2_sawtooth\",\n \"lead_3_calliope\",\n \"lead_4_chiff\",\n \"lead_5_charang\",\n \"lead_6_voice\",\n \"lead_7_fifths\",\n \"lead_8_bass__lead\",\n \"marimba\",\n \"melodic_tom\",\n \"music_box\",\n \"muted_trumpet\",\n \"oboe\",\n \"ocarina\",\n \"orchestra_hit\",\n \"orchestral_harp\",\n \"overdriven_guitar\",\n \"pad_1_new_age\",\n \"pad_2_warm\",\n \"pad_3_polysynth\",\n \"pad_4_choir\",\n \"pad_5_bowed\",\n \"pad_6_metallic\",\n \"pad_7_halo\",\n \"pad_8_sweep\",\n \"pan_flute\",\n \"percussive_organ\",\n \"piccolo\",\n \"pizzicato_strings\",\n \"recorder\",\n \"reed_organ\",\n \"reverse_cymbal\",\n \"rock_organ\",\n \"seashore\",\n \"shakuhachi\",\n \"shamisen\",\n \"shanai\",\n \"sitar\",\n \"slap_bass_1\",\n \"slap_bass_2\",\n \"soprano_sax\",\n \"steel_drums\",\n \"string_ensemble_1\",\n \"string_ensemble_2\",\n \"synth_bass_1\",\n \"synth_bass_2\",\n \"synth_brass_1\",\n \"synth_brass_2\",\n \"synth_choir\",\n \"synth_drum\",\n \"synth_strings_1\",\n \"synth_strings_2\",\n \"taiko_drum\",\n \"tango_accordion\",\n \"telephone_ring\",\n \"tenor_sax\",\n \"timpani\",\n \"tinkle_bell\",\n \"tremolo_strings\",\n \"trombone\",\n \"trumpet\",\n \"tuba\",\n \"tubular_bells\",\n \"vibraphone\",\n \"viola\",\n \"violin\",\n \"voice_oohs\",\n \"whistle\",\n \"woodblock\",\n \"xylophone\",\n ];\n}\n","import {\n AudioBuffers,\n findFirstSupportedFormat,\n loadAudioBuffer,\n} from \"./sampler/load-audio\";\nimport { toMidi } from \"./sampler/midi\";\nimport { Sampler, SamplerAudioLoader } from \"./sampler/sampler\";\n\n/**\n * Splendid Grand Piano options\n */\nexport type SplendidGrandPianoConfig = {\n baseUrl: string;\n destination: AudioNode;\n\n detune: number;\n volume: number;\n velocity: number;\n decayTime?: number;\n lpfCutoffHz?: number;\n};\n\nconst BASE_URL = \"https://danigb.github.io/samples/splendid-grand-piano\";\n\nexport class SplendidGrandPiano extends Sampler {\n constructor(\n context: AudioContext,\n options: Partial<SplendidGrandPianoConfig>\n ) {\n super(context, {\n destination: options.destination,\n\n detune: options.detune,\n volume: options.volume,\n velocity: options.velocity,\n decayTime: options.decayTime ?? 0.5,\n lpfCutoffHz: options.lpfCutoffHz,\n\n buffers: splendidGrandPianoLoader(options.baseUrl ?? BASE_URL),\n\n noteToSample: (note, buffers, config) => {\n const midi = toMidi(note.note);\n if (!midi) return [note.note, 0];\n\n const vel = note.velocity ?? config.velocity;\n const layerIdx = LAYERS.findIndex(\n (layer) => vel >= layer.vel_range[0] && vel <= layer.vel_range[1]\n );\n const layer = LAYERS[layerIdx];\n if (!layer) return [\"\", 0];\n\n return findNearestMidiInLayer(layer.name, midi, buffers);\n },\n });\n }\n}\n\nfunction findNearestMidiInLayer(\n prefix: string,\n midi: number,\n buffers: AudioBuffers\n): [string, number] {\n let i = 0;\n while (buffers[prefix + (midi + i)] === undefined && i < 128) {\n if (i > 0) i = -i;\n else i = -i + 1;\n }\n\n return i === 127 ? [prefix + midi, 0] : [prefix + (midi + i), -i * 100];\n}\n\nfunction splendidGrandPianoLoader(baseUrl: string): SamplerAudioLoader {\n const format = findFirstSupportedFormat([\"ogg\", \"m4a\"]) ?? \"ogg\";\n return async (context: AudioContext, buffers: AudioBuffers) => {\n for (const layer of LAYERS) {\n await Promise.all(\n layer.samples.map(async ([midi, name]) => {\n const url = `${baseUrl}/${name}.${format}`;\n const buffer = await loadAudioBuffer(context, url);\n if (buffer) buffers[layer.name + midi] = buffer;\n })\n );\n }\n };\n}\n\nexport const LAYERS = [\n {\n name: \"PPP\",\n vel_range: [1, 40],\n cutoff: 1000,\n samples: [\n [23, \"PP-B-1\"],\n [27, \"PP-D#0\"],\n [29, \"PP-F0\"],\n [31, \"PP-G0\"],\n [33, \"PP-A0\"],\n [35, \"PP-B0\"],\n [37, \"PP-C#1\"],\n [38, \"PP-D1\"],\n [40, \"PP-E1\"],\n [41, \"PP-F1\"],\n [43, \"PP-G1\"],\n [45, \"PP-A1\"],\n [47, \"PP-B1\"],\n [48, \"PP-C2\"],\n [50, \"PP-D2\"],\n [52, \"PP-E2\"],\n [53, \"PP-F2\"],\n [55, \"PP-G2\"],\n [56, \"PP-G#2\"],\n [57, \"PP-A2\"],\n [58, \"PP-A#2\"],\n [59, \"PP-B2\"],\n [60, \"PP-C3\"],\n [62, \"PP-D3\"],\n [64, \"PP-E3\"],\n [65, \"PP-F3\"],\n [67, \"PP-G3\"],\n [69, \"PP-A3\"],\n [71, \"PP-B3\"],\n [72, \"PP-C4\"],\n [74, \"PP-D4\"],\n [76, \"PP-E4\"],\n [77, \"PP-F4\"],\n [79, \"PP-G4\"],\n [80, \"PP-G#4\"],\n [81, \"PP-A4\"],\n [82, \"PP-A#4\"],\n [83, \"PP-B4\"],\n [85, \"PP-C#5\"],\n [86, \"PP-D5\"],\n [87, \"PP-D#5\"],\n [89, \"PP-F5\"],\n [90, \"PP-F#5\"],\n [91, \"PP-G5\"],\n [92, \"PP-G#5\"],\n [93, \"PP-A5\"],\n [94, \"PP-A#5\"],\n [95, \"PP-B5\"],\n [96, \"PP-C6\"],\n [97, \"PP-C#6\"],\n [98, \"PP-D6\"],\n [99, \"PP-D#6\"],\n [100, \"PP-E6\"],\n [101, \"PP-F6\"],\n [102, \"PP-F#6\"],\n [103, \"PP-G6\"],\n [104, \"PP-G#6\"],\n [105, \"PP-A6\"],\n [106, \"PP-A#6\"],\n [107, \"PP-B6\"],\n [108, \"PP-C7\"],\n ],\n },\n {\n name: \"PP\",\n vel_range: [41, 67],\n samples: [\n [23, \"PP-B-1\"],\n [27, \"PP-D#0\"],\n [29, \"PP-F0\"],\n [31, \"PP-G0\"],\n [33, \"PP-A0\"],\n [35, \"PP-B0\"],\n [37, \"PP-C#1\"],\n [38, \"PP-D1\"],\n [40, \"PP-E1\"],\n [41, \"PP-F1\"],\n [43, \"PP-G1\"],\n [45, \"PP-A1\"],\n [47, \"PP-B1\"],\n [48, \"PP-C2\"],\n [50, \"PP-D2\"],\n [52, \"PP-E2\"],\n [53, \"PP-F2\"],\n [55, \"PP-G2\"],\n [56, \"PP-G#2\"],\n [57, \"PP-A2\"],\n [58, \"PP-A#2\"],\n [59, \"PP-B2\"],\n [60, \"PP-C3\"],\n [62, \"PP-D3\"],\n [64, \"PP-E3\"],\n [65, \"PP-F3\"],\n [67, \"PP-G3\"],\n [69, \"PP-A3\"],\n [71, \"PP-B3\"],\n [72, \"PP-C4\"],\n [74, \"PP-D4\"],\n [76, \"PP-E4\"],\n [77, \"PP-F4\"],\n [79, \"PP-G4\"],\n [80, \"PP-G#4\"],\n [81, \"PP-A4\"],\n [82, \"PP-A#4\"],\n [83, \"PP-B4\"],\n [85, \"PP-C#5\"],\n [86, \"PP-D5\"],\n [87, \"PP-D#5\"],\n [89, \"PP-F5\"],\n [90, \"PP-F#5\"],\n [91, \"PP-G5\"],\n [92, \"PP-G#5\"],\n [93, \"PP-A5\"],\n [94, \"PP-A#5\"],\n [95, \"PP-B5\"],\n [96, \"PP-C6\"],\n [97, \"PP-C#6\"],\n [98, \"PP-D6\"],\n [99, \"PP-D#6\"],\n [100, \"PP-E6\"],\n [101, \"PP-F6\"],\n [102, \"PP-F#6\"],\n [103, \"PP-G6\"],\n [104, \"PP-G#6\"],\n [105, \"PP-A6\"],\n [106, \"PP-A#6\"],\n [107, \"PP-B6\"],\n [108, \"PP-C7\"],\n ],\n },\n {\n name: \"MP\",\n vel_range: [68, 84],\n samples: [\n [23, \"Mp-B-1\"],\n [27, \"Mp-D#0\"],\n [29, \"Mp-F0\"],\n [31, \"Mp-G0\"],\n [33, \"Mp-A0\"],\n [35, \"Mp-B0\"],\n [37, \"Mp-C#1\"],\n [38, \"Mp-D1\"],\n [40, \"Mp-E1\"],\n [41, \"Mp-F1\"],\n [43, \"Mp-G1\"],\n [45, \"Mp-A1\"],\n [47, \"Mp-B1\"],\n [48, \"Mp-C2\"],\n [50, \"Mp-D2\"],\n [52, \"Mp-E2\"],\n [53, \"Mp-F2\"],\n [55, \"Mp-G2\"],\n [56, \"Mp-G#2\"],\n [57, \"Mp-A2\"],\n [58, \"Mp-A#2\"],\n [59, \"Mp-B2\"],\n [60, \"Mp-C3\"],\n [62, \"Mp-D3\"],\n [64, \"Mp-E3\"],\n [65, \"Mp-F3\"],\n [67, \"Mp-G3\"],\n [69, \"Mp-A3\"],\n [71, \"Mp-B3\"],\n [72, \"Mp-C4\"],\n [74, \"Mp-D4\"],\n [76, \"Mp-E4\"],\n [77, \"Mp-F4\"],\n [79, \"Mp-G4\"],\n [80, \"Mp-G#4\"],\n [81, \"Mp-A4\"],\n [82, \"Mp-A#4\"],\n [83, \"Mp-B4\"],\n [85, \"Mp-C#5\"],\n [86, \"Mp-D5\"],\n [87, \"Mp-D#5\"],\n [88, \"Mp-E5\"],\n [89, \"Mp-F5\"],\n [90, \"Mp-F#5\"],\n [91, \"Mp-G5\"],\n [92, \"Mp-G#5\"],\n [93, \"Mp-A5\"],\n [94, \"Mp-A#5\"],\n [95, \"Mp-B5\"],\n [96, \"Mp-C6\"],\n [97, \"Mp-C#6\"],\n [98, \"Mp-D6\"],\n [99, \"Mp-D#6\"],\n [100, \"PP-E6\"],\n [101, \"Mp-F6\"],\n [102, \"Mp-F#6\"],\n [103, \"Mp-G6\"],\n [104, \"Mp-G#6\"],\n [105, \"Mp-A6\"],\n [106, \"Mp-A#6\"],\n [107, \"PP-B6\"],\n [108, \"PP-C7\"],\n ],\n },\n {\n name: \"MF\",\n vel_range: [85, 100],\n samples: [\n [23, \"Mf-B-1\"],\n [27, \"Mf-D#0\"],\n [29, \"Mf-F0\"],\n [31, \"Mf-G0\"],\n [33, \"Mf-A0\"],\n [35, \"Mf-B0\"],\n [37, \"Mf-C#1\"],\n [38, \"Mf-D1\"],\n [40, \"Mf-E1\"],\n [41, \"Mf-F1\"],\n [43, \"Mf-G1\"],\n [45, \"Mf-A1\"],\n [47, \"Mf-B1\"],\n [48, \"Mf-C2\"],\n [50, \"Mf-D2\"],\n [52, \"Mf-E2\"],\n [53, \"Mf-F2\"],\n [55, \"Mf-G2\"],\n [56, \"Mf-G#2\"],\n [57, \"Mf-A2\"],\n [58, \"Mf-A#2\"],\n [59, \"Mf-B2\"],\n [60, \"Mf-C3\"],\n [62, \"Mf-D3\"],\n [64, \"Mf-E3\"],\n [65, \"Mf-F3\"],\n [67, \"Mf-G3\"],\n [69, \"Mf-A3\"],\n [71, \"Mf-B3\"],\n [72, \"Mf-C4\"],\n [74, \"Mf-D4\"],\n [76, \"Mf-E4\"],\n [77, \"Mf-F4\"],\n [79, \"Mf-G4\"],\n [80, \"Mf-G#4\"],\n [81, \"Mf-A4\"],\n [82, \"Mf-A#4\"],\n [83, \"Mf-B4\"],\n [85, \"Mf-C#5\"],\n [86, \"Mf-D5\"],\n [87, \"Mf-D#5\"],\n [88, \"Mf-E5\"],\n [89, \"Mf-F5\"],\n [90, \"Mf-F#5\"],\n [91, \"Mf-G5\"],\n [92, \"Mf-G#5\"],\n [93, \"Mf-A5\"],\n [94, \"Mf-A#5\"],\n [95, \"Mf-B5\"],\n [96, \"Mf-C6\"],\n [97, \"Mf-C#6\"],\n [98, \"Mf-D6\"],\n [99, \"Mf-D#6\"],\n [100, \"Mf-E6\"],\n [101, \"Mf-F6\"],\n [102, \"Mf-F#6\"],\n [103, \"Mf-G6\"],\n [104, \"Mf-G#6\"],\n [105, \"Mf-A6\"],\n [106, \"Mf-A#6\"],\n [107, \"Mf-B6\"],\n [108, \"PP-C7\"],\n ],\n },\n {\n name: \"FF\",\n vel_range: [101, 127],\n samples: [\n [23, \"FF-B-1\"],\n [27, \"FF-D#0\"],\n [29, \"FF-F0\"],\n [31, \"FF-G0\"],\n [33, \"FF-A0\"],\n [35, \"FF-B0\"],\n [37, \"FF-C#1\"],\n [38, \"FF-D1\"],\n [40, \"FF-E1\"],\n [41, \"FF-F1\"],\n [43, \"FF-G1\"],\n [45, \"FF-A1\"],\n [47, \"FF-B1\"],\n [48, \"FF-C2\"],\n [50, \"FF-D2\"],\n [52, \"FF-E2\"],\n [53, \"FF-F2\"],\n [55, \"FF-G2\"],\n [56, \"FF-G#2\"],\n [57, \"FF-A2\"],\n [58, \"FF-A#2\"],\n [59, \"FF-B2\"],\n [60, \"FF-C3\"],\n [62, \"FF-D3\"],\n [64, \"FF-E3\"],\n [65, \"FF-F3\"],\n [67, \"FF-G3\"],\n [69, \"FF-A3\"],\n [71, \"FF-B3\"],\n [72, \"FF-C4\"],\n [74, \"FF-D4\"],\n [76, \"FF-E4\"],\n [77, \"FF-F4\"],\n [79, \"FF-G4\"],\n [80, \"FF-G#4\"],\n [81, \"FF-A4\"],\n [82, \"FF-A#4\"],\n [83, \"FF-B4\"],\n [85, \"FF-C#5\"],\n [86, \"FF-D5\"],\n [88, \"FF-E5\"],\n [89, \"FF-F5\"],\n [91, \"FF-G5\"],\n [93, \"FF-A5\"],\n [95, \"Mf-B5\"],\n [96, \"Mf-C6\"],\n [97, \"Mf-C#6\"],\n [98, \"Mf-D6\"],\n [99, \"Mf-D#6\"],\n [100, \"Mf-E6\"],\n [102, \"Mf-F#6\"],\n [103, \"Mf-G6\"],\n [104, \"Mf-G#6\"],\n [105, \"Mf-A6\"],\n [106, \"Mf-A#6\"],\n [107, \"Mf-B6\"],\n [108, \"Mf-C7\"],\n ],\n },\n];\n"],"mappings":"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MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,QAAQ;AAAA,MACb,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,QAAQ;AAAA,MACb,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,QAAQ;AAAA,MACb,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,QAAQ;AAAA,MACb,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,QAAQ;AAAA,MACb,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,QAAQ;AAAA,MACb,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,QAAQ;AAAA,MACb,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,QAAQ;AAAA,MACb,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,QAAQ;AAAA,MACb,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,QAAQ;AAAA,MACb,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,QAAQ;AAAA,MACb,CAAC,KAAK,OAAO;AAAA,MACb,CAAC,KAAK,OAAO;AAAA,MACb,CAAC,KAAK,QAAQ;AAAA,MACd,CAAC,KAAK,OAAO;AAAA,MACb,CAAC,KAAK,QAAQ;AAAA,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CZ,CAAC,IAAI,QAAQ;AAAA,MACb,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,QAAQ;AAAA,MACb,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,QAAQ;AAAA,MACb,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,QAAQ;AAAA,MACb,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,QAAQ;AAAA,MACb,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,QAAQ;AAAA,MACb,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,QAAQ;AAAA,MACb,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,QAAQ;AAAA,MACb,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,QAAQ;AAAA,MACb,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,QAAQ;AAAA,MACb,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,QAAQ;AAAA,MACb,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,QAAQ;AAAA,MACb,CAAC,KAAK,OAAO;AAAA,MACb,CAAC,KAAK,OAAO;AAAA,MACb,CAAC,KAAK,QAAQ;AAAA,MACd,CAAC,KAAK,OAAO;AAAA,MACb,CAAC,KAAK,QAAQ;AAAA,MACd,CAAC,KAAK,OAAO;AAAA,MACb,CAAC,KAAK,QAAQ;AAAA,MACd,CAAC,KAAK,OAAO;AAAA,MACb,CAAC,KAAK,OAAO;AAAA,IACf;AAAA,EACF;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,WAAW,CAAC,KAAK,GAAG;AAAA,IACpB,SAAS;AAAA,MACP,CAAC,IAAI,QAAQ;AAAA,MACb,CAAC,IAAI,QAAQ;AAAA,MACb,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,QAAQ;AAAA,MACb,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,QAAQ;AAAA,MACb,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,QAAQ;AAAA,MACb,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,QAAQ;AAAA,MACb,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,QAAQ;AAAA,MACb,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,QAAQ;AAAA,MACb,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,QAAQ;AAAA,MACb,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,QAAQ;AAAA,MACb,CAAC,KAAK,OAAO;AAAA,MACb,CAAC,KAAK,QAAQ;AAAA,MACd,CAAC,KAAK,OAAO;AAAA,MACb,CAAC,KAAK,QAAQ;AAAA,MACd,CAAC,KAAK,OAAO;AAAA,MACb,CAAC,KAAK,QAAQ;AAAA,MACd,CAAC,KAAK,OAAO;AAAA,MACb,CAAC,KAAK,OAAO;AAAA,IACf;AAAA,EACF;AACF;","names":["canPlay","volume","send","_a","instrument","urls","_config","_stop","_load","_output","_a","depth","INSTRUMENTS","_output","BASE_URL","_a","layer"]}
|
package/dist/index.mjs
CHANGED
|
@@ -282,7 +282,7 @@ function startSample(sample) {
|
|
|
282
282
|
const volume = context.createGain();
|
|
283
283
|
volume.gain.value = (_b = sample == null ? void 0 : sample.gain) != null ? _b : 1;
|
|
284
284
|
const [decay, startDecay] = createDecayEnvelope(context, sample.decayTime);
|
|
285
|
-
|
|
285
|
+
const cleanup = unsubscribeAll([
|
|
286
286
|
connectSerial([source, lpf, volume, decay, sample.destination]),
|
|
287
287
|
(_c = sample.stop) == null ? void 0 : _c.call(sample, (sampleStop) => {
|
|
288
288
|
if (sampleStop === void 0 || sampleStop.stopId === void 0 || sampleStop.stopId === sample.stopId) {
|
|
@@ -290,6 +290,11 @@ function startSample(sample) {
|
|
|
290
290
|
}
|
|
291
291
|
})
|
|
292
292
|
]);
|
|
293
|
+
source.onended = () => {
|
|
294
|
+
var _a2;
|
|
295
|
+
cleanup();
|
|
296
|
+
(_a2 = sample.onEnded) == null ? void 0 : _a2.call(sample);
|
|
297
|
+
};
|
|
293
298
|
const startAt = sample.time || context.currentTime;
|
|
294
299
|
source.start(startAt);
|
|
295
300
|
function stop(time) {
|
|
@@ -367,6 +372,7 @@ var Sampler = class {
|
|
|
367
372
|
console.warn(`Sample not found: '${sample}'`);
|
|
368
373
|
return () => void 0;
|
|
369
374
|
}
|
|
375
|
+
const onEnded = _note.onEnded;
|
|
370
376
|
return startSample({
|
|
371
377
|
buffer,
|
|
372
378
|
destination: __privateGet(this, _output).input,
|
|
@@ -377,7 +383,8 @@ var Sampler = class {
|
|
|
377
383
|
detune: detune + ((_a = _note.detune) != null ? _a : __privateGet(this, _config).detune),
|
|
378
384
|
gain: __privateGet(this, _config).volumeToGain((_b = _note.velocity) != null ? _b : __privateGet(this, _config).velocity),
|
|
379
385
|
stop: __privateGet(this, _stop).subscribe,
|
|
380
|
-
stopId: (_c = _note.stopId) != null ? _c : _note.note
|
|
386
|
+
stopId: (_c = _note.stopId) != null ? _c : _note.note,
|
|
387
|
+
onEnded: onEnded ? () => onEnded(note) : void 0
|
|
381
388
|
});
|
|
382
389
|
}
|
|
383
390
|
stop(note) {
|
|
@@ -651,6 +658,7 @@ var SfzSampler = class {
|
|
|
651
658
|
console.warn(`Sample not found: ${region.sample}`);
|
|
652
659
|
return () => void 0;
|
|
653
660
|
}
|
|
661
|
+
const onEnded = _note.onEnded;
|
|
654
662
|
return startSample({
|
|
655
663
|
buffer,
|
|
656
664
|
destination,
|
|
@@ -660,7 +668,8 @@ var SfzSampler = class {
|
|
|
660
668
|
time: _note.time,
|
|
661
669
|
duration: _note.duration,
|
|
662
670
|
stop: __privateGet(this, _stop2).subscribe,
|
|
663
|
-
stopId: (_f = _note.stopId) != null ? _f : _note.note
|
|
671
|
+
stopId: (_f = _note.stopId) != null ? _f : _note.note,
|
|
672
|
+
onEnded: onEnded ? () => onEnded(note) : void 0
|
|
664
673
|
});
|
|
665
674
|
});
|
|
666
675
|
return (time) => stopAll.forEach((stop) => stop(time));
|
|
@@ -873,15 +882,14 @@ _output3 = new WeakMap();
|
|
|
873
882
|
// src/soundfont/soundfont.ts
|
|
874
883
|
var Soundfont = class extends Sampler {
|
|
875
884
|
constructor(context, options) {
|
|
876
|
-
var _a, _b;
|
|
877
|
-
const url = options.instrument.startsWith("http") ? options.instrument : gleitzKitUrl(options.instrument, options.kit);
|
|
878
|
-
console.log("!!! URL", { url });
|
|
885
|
+
var _a, _b, _c;
|
|
886
|
+
const url = options.instrument.startsWith("http") ? options.instrument : gleitzKitUrl(options.instrument, (_a = options.kit) != null ? _a : "MusyngKite");
|
|
879
887
|
super(context, {
|
|
880
888
|
destination: options.destination,
|
|
881
889
|
detune: options.detune,
|
|
882
890
|
volume: options.volume,
|
|
883
891
|
velocity: options.velocity,
|
|
884
|
-
decayTime: (
|
|
892
|
+
decayTime: (_b = options.decayTime) != null ? _b : 0.5,
|
|
885
893
|
lpfCutoffHz: options.lpfCutoffHz,
|
|
886
894
|
buffers: soundfontLoader(url),
|
|
887
895
|
noteToSample: (note, buffers, config) => {
|
|
@@ -889,7 +897,7 @@ var Soundfont = class extends Sampler {
|
|
|
889
897
|
return midi === void 0 ? ["", 0] : findNearestMidi(midi, buffers);
|
|
890
898
|
}
|
|
891
899
|
});
|
|
892
|
-
const extraGain = (
|
|
900
|
+
const extraGain = (_c = options.extraGain) != null ? _c : 5;
|
|
893
901
|
const gain = new GainNode(context, { gain: extraGain });
|
|
894
902
|
this.output.addInsert(gain);
|
|
895
903
|
}
|
|
@@ -933,12 +941,15 @@ function base64ToArrayBuffer(base64) {
|
|
|
933
941
|
}
|
|
934
942
|
return bytes.buffer;
|
|
935
943
|
}
|
|
936
|
-
function gleitzKitUrl(name, kit
|
|
944
|
+
function gleitzKitUrl(name, kit) {
|
|
937
945
|
var _a;
|
|
938
946
|
const format = (_a = findFirstSupportedFormat(["ogg", "mp3"])) != null ? _a : "mp3";
|
|
939
947
|
return `https://gleitz.github.io/midi-js-soundfonts/${kit}/${name}-${format}.js`;
|
|
940
948
|
}
|
|
941
|
-
function
|
|
949
|
+
function getSoundfontKits() {
|
|
950
|
+
return ["MusyngKite", "FluidR3_GM"];
|
|
951
|
+
}
|
|
952
|
+
function getSoundfontNames() {
|
|
942
953
|
return [
|
|
943
954
|
"accordion",
|
|
944
955
|
"acoustic_bass",
|
|
@@ -1476,6 +1487,7 @@ export {
|
|
|
1476
1487
|
getDrumMachineNames,
|
|
1477
1488
|
getElectricPianoNames,
|
|
1478
1489
|
getMalletNames,
|
|
1479
|
-
|
|
1490
|
+
getSoundfontKits,
|
|
1491
|
+
getSoundfontNames
|
|
1480
1492
|
};
|
|
1481
1493
|
//# sourceMappingURL=index.mjs.map
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/sampler/load-audio.ts","../src/sampler/connect.ts","../src/sampler/midi.ts","../src/sampler/signals.ts","../src/sampler/channel.ts","../src/sampler/start-sample.ts","../src/sampler/sampler.ts","../src/drum-machine/dm-instrument.ts","../src/drum-machine/drum-machine.ts","../src/sfz/sfz-load.ts","../src/sfz/sfz-regions.ts","../src/sfz/sfz-sampler.ts","../src/tremolo.ts","../src/electric-piano.ts","../src/mallet.ts","../src/reverb/processor.min.ts","../src/reverb/reverb.ts","../src/soundfont/soundfont.ts","../src/splendid-grand-piano.ts"],"sourcesContent":["export type AudioBuffers = Record<string | number, AudioBuffer | undefined>;\n\nexport async function loadAudioBuffer(\n context: BaseAudioContext,\n url: string\n): Promise<AudioBuffer | undefined> {\n url = url.replace(/#/g, \"%23\").replace(/([^:]\\/)\\/+/g, \"$1\");\n const response = await fetch(url);\n if (response.status !== 200) {\n console.warn(\n \"Error loading buffer. Invalid status: \",\n response.status,\n url\n );\n return;\n }\n try {\n const audioData = await response.arrayBuffer();\n const buffer = await context.decodeAudioData(audioData);\n return buffer;\n } catch (error) {\n console.warn(\"Error loading buffer\", error, url);\n }\n}\n\nexport function findFirstSupportedFormat(formats: string[]): string | null {\n if (typeof document === \"undefined\") return null;\n\n const audio = document.createElement(\"audio\");\n for (let i = 0; i < formats.length; i++) {\n const format = formats[i];\n const canPlay = audio.canPlayType(`audio/${format}`);\n if (canPlay === \"probably\" || canPlay === \"maybe\") {\n return format;\n }\n // check Safari for aac format\n if (format === \"m4a\") {\n const canPlay = audio.canPlayType(`audio/aac`);\n if (canPlay === \"probably\" || canPlay === \"maybe\") {\n return format;\n }\n }\n }\n return null;\n}\n","export type AudioInsert = {\n input: AudioNode;\n output: AudioNode;\n};\n\nexport function connectSerial(nodes: (AudioNode | AudioInsert | undefined)[]) {\n const _nodes = nodes.filter((x): x is AudioNode | AudioInsert => !!x);\n _nodes.reduce((a, b) => {\n const left = \"output\" in a ? a.output : a;\n const right = \"input\" in b ? b.input : b;\n left.connect(right);\n return b;\n });\n\n return () => {\n _nodes.reduce((a, b) => {\n const left = \"output\" in a ? a.output : a;\n const right = \"input\" in b ? b.input : b;\n left.disconnect(right);\n return b;\n });\n };\n}\n\nexport function connectAudioBus(\n node: AudioNode,\n destination: AudioNode,\n gain: number\n) {\n const mix = node.context.createGain();\n mix.gain.value = gain;\n node.connect(mix);\n mix.connect(destination);\n\n return () => {\n node.disconnect(mix);\n mix.disconnect(destination);\n };\n}\n","function noteNameToMidi(note: string): number | undefined {\n const REGEX = /^([a-gA-G]?)(#{1,}|b{1,}|)(-?\\d+)$/;\n const m = REGEX.exec(note);\n if (!m) return;\n const letter = m[1].toUpperCase();\n if (!letter) return;\n\n const acc = m[2];\n const alt = acc[0] === \"b\" ? -acc.length : acc.length;\n const oct = m[3] ? +m[3] : 4;\n\n const step = (letter.charCodeAt(0) + 3) % 7;\n return [0, 2, 4, 5, 7, 9, 11][step] + alt + 12 * (oct + 1);\n}\n\nexport function toMidi(note: string | number | undefined): number | undefined {\n return note === undefined\n ? undefined\n : typeof note === \"number\"\n ? note\n : noteNameToMidi(note);\n}\n\n/// This is how the MIDI association converts midi velocity [0..127] into gain [0..1]\n/// @see https://www.midi.org/specifications/file-format-specifications/dls-downloadable-sounds/dls-level-1\nexport function midiVelToGain(vel: number) {\n return (vel * vel) / 16129; // 16129 = 127 * 127\n}\nexport function findNearestMidi(\n midi: number,\n isAvailable: Record<string | number, unknown>\n): [number, number] {\n let i = 0;\n while (isAvailable[midi + i] === undefined && i < 128) {\n if (i > 0) i = -i;\n else i = -i + 1;\n }\n\n return i === 127 ? [midi, 0] : [midi + i, -i * 100];\n}\n","/**\n * A function to unsubscribe from an event or control\n */\nexport type Unsubscribe = () => void;\n/**\n * A function that listener to event or control changes\n */\nexport type Listener<T> = (value: T) => void;\n/**\n * A function to subscribe an trigger or control events\n */\nexport type Subscribe<T> = (listener: Listener<T>) => Unsubscribe;\n\n/**\n * A trigger is a subscribable event\n */\nexport type Trigger<T> = {\n subscribe: Subscribe<T>;\n trigger: (event: T) => void;\n};\n\n/**\n * A control is a subscribable value\n */\nexport type Control<T> = {\n subscribe: Subscribe<T>;\n set: (value: T) => void;\n get: () => T;\n};\n\n/**\n * Create a control signal\n * @param initialValue\n * @returns Control\n */\nexport function createControl<T>(initialValue: T): Control<T> {\n let current = initialValue;\n const listeners = new Set<Listener<T>>();\n\n function subscribe(listener: Listener<T>) {\n listeners.add(listener);\n listener(current);\n return () => {\n listeners.delete(listener);\n };\n }\n\n function set(value: T) {\n current = value;\n listeners.forEach((listener) => listener(current));\n }\n\n function get(): T {\n return current;\n }\n return { subscribe, set, get };\n}\n\nexport function createTrigger<T>(): Trigger<T> {\n const listeners = new Set<Listener<T>>();\n\n function subscribe(listener: Listener<T>) {\n listeners.add(listener);\n return () => {\n listeners.delete(listener);\n };\n }\n\n function trigger(value: T) {\n listeners.forEach((listener) => listener(value));\n }\n\n return { subscribe, trigger };\n}\n\nexport function unsubscribeAll(unsubscribe: Array<Unsubscribe | undefined>) {\n let done = false;\n return () => {\n if (done) return;\n done = true;\n unsubscribe.forEach((cb) => cb?.());\n };\n}\n","import { AudioInsert, connectSerial } from \"./connect\";\nimport { midiVelToGain } from \"./midi\";\nimport { createControl } from \"./signals\";\n\ntype ChannelOptions = {\n destination: AudioNode;\n volume: number;\n volumeToGain: (volume: number) => number;\n};\n\ntype Send = {\n name: string;\n mix: GainNode;\n disconnect: () => void;\n};\n\n/**\n * @private\n */\nexport class Channel {\n public readonly setVolume: (vol: number) => void;\n public readonly input: AudioNode;\n\n #volume: GainNode;\n #sends?: Send[];\n #inserts?: (AudioNode | AudioInsert)[];\n #disconnect: () => void;\n #unsubscribe: () => void;\n #options: Readonly<ChannelOptions>;\n\n constructor(\n public readonly context: AudioContext,\n options: Partial<ChannelOptions>\n ) {\n this.#options = Object.freeze({\n destination: context.destination,\n volume: 100,\n volumeToGain: midiVelToGain,\n ...options,\n });\n\n this.input = new GainNode(this.context);\n this.#volume = new GainNode(this.context);\n\n this.#disconnect = connectSerial([\n this.input,\n this.#volume,\n this.#options.destination,\n ]);\n\n const volume = createControl(options.volume ?? 100);\n this.setVolume = volume.set;\n const volumeToGain = options.volumeToGain ?? midiVelToGain;\n this.#unsubscribe = volume.subscribe((volume) => {\n this.#volume.gain.value = volumeToGain(volume);\n });\n }\n\n addInsert(effect: AudioNode | AudioInsert) {\n this.#inserts ??= [];\n this.#inserts.push(effect);\n this.#disconnect();\n this.#disconnect = connectSerial([\n this.input,\n ...this.#inserts,\n this.#volume,\n this.#options.destination,\n ]);\n }\n\n addEffect(\n name: string,\n effect: AudioNode | { input: AudioNode },\n mixValue: number\n ) {\n const mix = new GainNode(this.context);\n mix.gain.value = mixValue;\n const input = \"input\" in effect ? effect.input : effect;\n const disconnect = connectSerial([this.#volume, mix, input]);\n\n this.#sends ??= [];\n this.#sends.push({ name, mix, disconnect });\n }\n\n sendEffect(name: string, mix: number) {\n const send = this.#sends?.find((send) => send.name === name);\n if (send) {\n send.mix.gain.value = mix;\n } else {\n console.warn(\"Send bus not found: \" + name);\n }\n }\n\n disconnect() {\n this.#disconnect();\n this.#unsubscribe();\n this.#sends?.forEach((send) => send.disconnect());\n this.#sends = undefined;\n }\n}\n","import { connectSerial } from \"./connect\";\nimport { toMidi } from \"./midi\";\nimport { Subscribe, unsubscribeAll } from \"./signals\";\n\nexport type StopSample = {\n stopId?: string | number;\n time?: number;\n};\n\nexport type SampleOptions = {\n decayTime?: number;\n detune?: number;\n gain?: number;\n};\n\ntype SampleNote = {\n midi?: number;\n note?: string;\n};\n\nexport type StartSample = {\n stopId?: string | number;\n buffer: AudioBuffer;\n destination: AudioNode;\n time?: number;\n duration?: number;\n decayTime?: number;\n detune?: number;\n gain?: number;\n lpfCutoffHz?: number;\n stop?: Subscribe<StopSample | undefined>;\n};\n\nexport function getSampleNote<T extends SampleNote>(\n note: number | string | T\n): T {\n if (typeof note === \"number\") {\n return { midi: note } as T;\n } else if (typeof note === \"string\") {\n return { note, midi: toMidi(note) } as T;\n } else {\n return { midi: note.midi ?? toMidi(note.note), ...note };\n }\n}\n\nexport function startSample(sample: StartSample) {\n const context = sample.destination.context;\n // Buffer source\n const source = context.createBufferSource();\n source.buffer = sample.buffer;\n source.detune.value = sample?.detune ?? 0;\n\n // Low pass filter\n const lpf = sample.lpfCutoffHz\n ? new BiquadFilterNode(context, {\n type: \"lowpass\",\n frequency: sample.lpfCutoffHz,\n })\n : undefined;\n\n // Sample volume\n const volume = context.createGain();\n volume.gain.value = sample?.gain ?? 1.0;\n\n // Release decay\n const [decay, startDecay] = createDecayEnvelope(context, sample.decayTime);\n\n source.onended = unsubscribeAll([\n connectSerial([source, lpf, volume, decay, sample.destination]),\n sample.stop?.((sampleStop) => {\n if (\n sampleStop === undefined ||\n sampleStop.stopId === undefined ||\n sampleStop.stopId === sample.stopId\n ) {\n stop(sampleStop?.time);\n }\n }),\n ]);\n\n const startAt = sample.time || context.currentTime;\n source.start(startAt);\n\n function stop(time?: number) {\n time ??= context.currentTime;\n if (time <= startAt) {\n source.stop(time);\n } else {\n const stopAt = startDecay(time);\n source.stop(stopAt);\n }\n }\n\n if (sample.duration !== undefined) {\n stop(startAt + sample.duration);\n }\n\n return stop;\n}\n\nfunction createDecayEnvelope(\n context: BaseAudioContext,\n envelopeTime = 0.2\n): [AudioNode, (time: number) => number] {\n let stopAt = 0;\n const envelope = new GainNode(context, { gain: 1.0 });\n\n function start(time: number): number {\n if (stopAt) return stopAt;\n envelope.gain.cancelScheduledValues(time);\n const envelopeAt = time || context.currentTime;\n stopAt = envelopeAt + envelopeTime;\n envelope.gain.setValueAtTime(1.0, envelopeAt);\n envelope.gain.linearRampToValueAtTime(0, stopAt);\n\n return stopAt;\n }\n\n return [envelope, start];\n}\n","import { Channel } from \"./channel\";\nimport { AudioBuffers, loadAudioBuffer } from \"./load-audio\";\nimport { midiVelToGain } from \"./midi\";\nimport { createTrigger, Trigger } from \"./signals\";\nimport { startSample, StopSample } from \"./start-sample\";\n\n/**\n * A function that downloads audio\n */\nexport type SamplerAudioLoader = (\n context: AudioContext,\n buffers: AudioBuffers\n) => Promise<void>;\n\nexport type SamplerConfig = {\n detune: number;\n volume: number;\n velocity: number;\n decayTime?: number;\n lpfCutoffHz?: number;\n destination: AudioNode;\n\n buffers: Record<string | number, string | AudioBuffers> | SamplerAudioLoader;\n volumeToGain: (volume: number) => number;\n noteToSample: (\n note: SamplerNote,\n buffers: AudioBuffers,\n config: SamplerConfig\n ) => [string | number, number];\n};\n\nexport type SamplerNote = {\n note: string | number;\n stopId?: string | number;\n time?: number;\n duration?: number;\n decayTime?: number;\n detune?: number;\n velocity?: number;\n lpfCutoffHz?: number;\n};\n\n/**\n * A Sampler instrument\n *\n * @private\n */\nexport class Sampler {\n public readonly output: Omit<Channel, \"input\">;\n public readonly buffers: AudioBuffers;\n #config: SamplerConfig;\n #stop: Trigger<StopSample | undefined>;\n #load: Promise<void>;\n #output: Channel;\n\n public constructor(\n public readonly context: AudioContext,\n options: Partial<SamplerConfig>\n ) {\n this.#config = {\n destination: options.destination ?? context.destination,\n detune: 0,\n volume: options.volume ?? 100,\n velocity: options.velocity ?? 100,\n buffers: options.buffers ?? {},\n volumeToGain: options.volumeToGain ?? midiVelToGain,\n noteToSample:\n options.noteToSample ?? ((note) => [note.note.toString(), 0]),\n };\n this.buffers = {};\n this.#stop = createTrigger();\n const loader =\n typeof this.#config.buffers === \"function\"\n ? this.#config.buffers\n : createAudioBuffersLoader(this.#config.buffers);\n this.#load = loader(context, this.buffers);\n this.#output = new Channel(context, this.#config);\n this.output = this.#output;\n }\n\n async loaded(): Promise<this> {\n await this.#load;\n return this;\n }\n\n start(note: SamplerNote | string | number) {\n const _note: SamplerNote = typeof note === \"object\" ? note : { note: note };\n const [sample, detune] = this.#config.noteToSample(\n _note,\n this.buffers,\n this.#config\n );\n const buffer = this.buffers[sample];\n if (!buffer) {\n console.warn(`Sample not found: '${sample}'`);\n return () => undefined;\n }\n return startSample({\n buffer,\n destination: this.#output.input,\n\n time: _note.time,\n duration: _note.duration,\n\n decayTime: _note.decayTime,\n lpfCutoffHz: _note.lpfCutoffHz,\n detune: detune + (_note.detune ?? this.#config.detune),\n gain: this.#config.volumeToGain(_note.velocity ?? this.#config.velocity),\n\n stop: this.#stop.subscribe,\n stopId: _note.stopId ?? _note.note,\n });\n }\n\n stop(note?: StopSample | string | number) {\n const note_ = typeof note === \"object\" ? note : { stopId: note };\n this.#stop.trigger(note_);\n }\n}\n\nfunction createAudioBuffersLoader(\n source: Record<string | number, string | AudioBuffers>\n): SamplerAudioLoader {\n return async (context, buffers) => {\n await Promise.all([\n Object.keys(source).map(async (key) => {\n const value = source[key];\n if (value instanceof AudioBuffer) {\n buffers[key] = value;\n } else if (typeof value === \"string\") {\n const buffer = await loadAudioBuffer(context, value);\n if (buffer) buffers[key] = buffer;\n }\n }),\n ]);\n };\n}\n","export type DrumMachineInstrument = {\n baseUrl: string;\n name: string;\n samples: string[];\n sampleNames: string[];\n nameToSample: Record<string, string | undefined>;\n sampleNameVariations: Record<string, string[]>;\n};\nexport const EMPTY_INSTRUMENT: DrumMachineInstrument = {\n baseUrl: \"\",\n name: \"\",\n samples: [],\n sampleNames: [],\n nameToSample: {},\n sampleNameVariations: {},\n};\n\nexport async function fetchDrumMachineInstrument(\n url: string\n): Promise<DrumMachineInstrument> {\n const res = await fetch(url);\n const json = await res.json();\n // need to fix json\n json.baseUrl = url.replace(\"/dm.json\", \"\");\n json.sampleNames = [];\n json.nameToSample = {};\n json.sampleNameVariations = {};\n for (const sampleSrc of json.samples) {\n const sample =\n sampleSrc.indexOf(\"/\") !== -1 ? sampleSrc : sampleSrc.replace(\"-\", \"/\");\n json.nameToSample[sample] = sample;\n const [base, variation] = sample.split(\"/\");\n if (!json.sampleNames.includes(base)) {\n json.sampleNames.push(base);\n }\n json.nameToSample[base] ??= sample;\n json.sampleNameVariations[base] ??= [];\n if (variation) {\n json.sampleNameVariations[base].push(`${base}/${variation}`);\n }\n }\n\n return json;\n}\n","import {\n findFirstSupportedFormat,\n loadAudioBuffer,\n} from \"../sampler/load-audio\";\nimport { Sampler, SamplerAudioLoader } from \"../sampler/sampler\";\nimport {\n DrumMachineInstrument,\n EMPTY_INSTRUMENT,\n fetchDrumMachineInstrument,\n} from \"./dm-instrument\";\n\nexport function getDrumMachineNames() {\n return Object.keys(INSTRUMENTS);\n}\n\nconst INSTRUMENTS: Record<string, string> = {\n \"TR-808\": \"https://danigb.github.io/samples/drum-machines/TR-808/dm.json\",\n \"Casio-RZ1\":\n \"https://danigb.github.io/samples/drum-machines/Casio-RZ1/dm.json\",\n \"LM-2\": \"https://danigb.github.io/samples/drum-machines/LM-2/dm.json\",\n \"MFB-512\": \"https://danigb.github.io/samples/drum-machines/MFB-512/dm.json\",\n \"Roland CR-8000\":\n \"https://danigb.github.io/samples/drum-machines/Roland-CR-8000/dm.json\",\n};\n\nexport type DrumMachineConfig = {\n instrument: string;\n destination: AudioNode;\n\n detune: number;\n volume: number;\n velocity: number;\n decayTime?: number;\n lpfCutoffHz?: number;\n};\n\nexport class DrumMachine extends Sampler {\n #instrument = EMPTY_INSTRUMENT;\n public constructor(\n context: AudioContext,\n options: Partial<DrumMachineConfig>\n ) {\n const url = INSTRUMENTS[options.instrument ?? \"TR-808\"];\n if (!url) throw new Error(\"Invalid instrument: \" + options.instrument);\n const instrument = fetchDrumMachineInstrument(url);\n\n super(context, {\n ...options,\n buffers: drumMachineLoader(instrument),\n noteToSample: (note, buffers, config) => {\n const sample = this.#instrument.nameToSample[note.note];\n return [sample ?? \"\", 0];\n },\n });\n instrument.then((instrument) => {\n this.#instrument = instrument;\n });\n }\n\n get sampleNames(): string[] {\n return this.#instrument.sampleNames;\n }\n\n getVariations(name: string): string[] {\n return this.#instrument.sampleNameVariations[name] ?? [];\n }\n}\n\nfunction drumMachineLoader(\n instrument: Promise<DrumMachineInstrument>\n): SamplerAudioLoader {\n const format = findFirstSupportedFormat([\"ogg\", \"m4a\"]) ?? \"ogg\";\n return async (context, buffers) => {\n const dm = await instrument;\n await Promise.all(\n dm.samples.map(async (sample) => {\n const url = `${dm.baseUrl}/${sample}.${format}`;\n const sampleName =\n sample.indexOf(\"/\") !== -1 ? sample : sample.replace(\"-\", \"/\");\n const buffer = await loadAudioBuffer(context, url);\n if (buffer) buffers[sampleName] = buffer;\n })\n );\n };\n}\n","import {\n AudioBuffers,\n findFirstSupportedFormat,\n loadAudioBuffer,\n} from \"../sampler/load-audio\";\nimport { SfzInstrument } from \"./sfz-kits\";\nimport { Websfz, WebsfzGroup } from \"./websfz\";\n\nexport async function loadSfzBuffers(\n context: AudioContext,\n buffers: AudioBuffers,\n websfz: Websfz\n) {\n websfz.groups.forEach((group) => {\n const urls = getWebsfzGroupUrls(websfz, group);\n return loadAudioBuffers(context, buffers, urls);\n });\n}\n\nexport async function loadSfzInstrument(\n instrument: string | Websfz | SfzInstrument\n): Promise<Websfz> {\n const isWebsfz = (inst: any): inst is Websfz => \"global\" in inst;\n const isSfzInstrument = (inst: any): inst is SfzInstrument =>\n \"websfzUrl\" in inst;\n\n if (typeof instrument === \"string\") {\n return fetchWebSfz(instrument);\n } else if (isWebsfz(instrument)) {\n return instrument;\n } else if (isSfzInstrument(instrument)) {\n const websfz = await fetchWebSfz(instrument.websfzUrl);\n websfz.meta ??= {};\n if (instrument.name) websfz.meta.name = instrument.name;\n if (instrument.baseUrl) websfz.meta.baseUrl = instrument.baseUrl;\n if (instrument.formats) websfz.meta.formats = instrument.formats;\n return websfz;\n } else {\n throw new Error(\"Invalid instrument: \" + JSON.stringify(instrument));\n }\n}\n\n// @private\nasync function loadAudioBuffers(\n context: AudioContext,\n buffers: AudioBuffers,\n urls: Record<string, string>\n) {\n await Promise.all(\n Object.keys(urls).map(async (sampleId) => {\n if (buffers[sampleId]) return;\n\n const buffer = await loadAudioBuffer(context, urls[sampleId]);\n if (buffer) buffers[sampleId] = buffer;\n return buffers;\n })\n );\n}\n\n// @private\nasync function fetchWebSfz(url: string): Promise<Websfz> {\n try {\n const response = await fetch(url);\n const json = await response.json();\n return json as Websfz;\n } catch (error) {\n console.warn(`Can't load SFZ file ${url}`, error);\n throw new Error(`Can't load SFZ file ${url}`);\n }\n}\n\n// @private\nexport function getWebsfzGroupUrls(websfz: Websfz, group: WebsfzGroup) {\n const urls: Record<string, string> = {};\n const baseUrl = websfz.meta.baseUrl ?? \"\";\n const format = findFirstSupportedFormat(websfz.meta.formats ?? []) ?? \"ogg\";\n\n const prefix = websfz.global[\"default_path\"] ?? \"\";\n\n if (!group) return urls;\n\n return group.regions.reduce((urls, region) => {\n if (region.sample) {\n urls[region.sample] = `${baseUrl}/${prefix}${region.sample}.${format}`;\n }\n return urls;\n }, urls);\n}\n","import { Websfz, WebsfzGroup, WebsfzRegion } from \"./websfz\";\n\nfunction checkRange(value?: number, low?: number, hi?: number) {\n const isAboveLow = low === undefined || (value !== undefined && value >= low);\n const isBelowHi = hi === undefined || (value !== undefined && value <= hi);\n return isAboveLow && isBelowHi;\n}\n\nexport function findRegions(\n websfz: Websfz,\n note: { midi?: number; velocity?: number; cc64?: number }\n): [WebsfzGroup, WebsfzRegion][] {\n const regions: [WebsfzGroup, WebsfzRegion][] = [];\n for (const group of websfz.groups) {\n if (\n checkRange(note.midi, group.lokey, group.hikey) &&\n checkRange(note.velocity, group.lovel, group.hivel) &&\n checkRange(note.cc64, group.locc64, group.hicc64)\n ) {\n for (const region of group.regions) {\n if (\n checkRange(note.midi, region.lokey, region.hikey) &&\n checkRange(note.velocity, region.lovel, region.hivel) &&\n checkRange(note.cc64, group.locc64, group.hicc64)\n ) {\n regions.push([group, region]);\n }\n }\n }\n }\n return regions;\n}\n","import { Channel } from \"../sampler/channel\";\nimport { AudioBuffers } from \"../sampler/load-audio\";\nimport { midiVelToGain, toMidi } from \"../sampler/midi\";\nimport { SamplerNote } from \"../sampler/sampler\";\nimport { createTrigger, Trigger } from \"../sampler/signals\";\nimport { startSample, StopSample } from \"../sampler/start-sample\";\nimport { SfzInstrument } from \"./sfz-kits\";\nimport { loadSfzBuffers, loadSfzInstrument } from \"./sfz-load\";\nimport { findRegions } from \"./sfz-regions\";\nimport { Websfz } from \"./websfz\";\n\n/**\n * Splendid Grand Piano options\n */\nexport type SfzSamplerConfig = {\n instrument: SfzInstrument | Websfz | string;\n destination: AudioNode;\n volume: number;\n velocity: number;\n detune: number;\n decayTime: number;\n lpfCutoffHz?: number;\n};\n\nconst EMPTY_WEBSFZ: Websfz = Object.freeze({\n meta: {},\n global: {},\n groups: [],\n});\n\nexport class SfzSampler {\n public readonly output: Omit<Channel, \"input\">;\n public readonly buffers: AudioBuffers;\n #websfz: Websfz;\n #config: SfzSamplerConfig;\n #stop: Trigger<StopSample | undefined>;\n #load: Promise<void>;\n #output: Channel;\n\n constructor(\n public readonly context: AudioContext,\n options: Partial<SfzSamplerConfig> & Pick<SfzSamplerConfig, \"instrument\">\n ) {\n this.#config = {\n instrument: options.instrument,\n destination: options.destination ?? context.destination,\n detune: 0,\n volume: options.volume ?? 100,\n velocity: options.velocity ?? 100,\n decayTime: 0.3,\n };\n this.buffers = {};\n this.#stop = createTrigger();\n\n this.#websfz = EMPTY_WEBSFZ;\n this.#load = loadSfzInstrument(options.instrument).then((result) => {\n this.#websfz = Object.freeze(result);\n return loadSfzBuffers(context, this.buffers, this.#websfz);\n });\n this.#output = new Channel(context, this.#config);\n this.output = this.#output;\n }\n async loaded(): Promise<this> {\n await this.#load;\n return this;\n }\n\n start(note: SamplerNote | string | number) {\n const _note: SamplerNote = typeof note === \"object\" ? note : { note: note };\n const midi = toMidi(_note.note);\n if (midi === undefined) return () => undefined;\n\n const velocity = _note.velocity ?? this.#config.velocity;\n const regions = findRegions(this.#websfz, { midi, velocity });\n\n const stopAll = regions.map(([group, region]) => {\n let target = region.pitch_keycenter ?? region.key ?? midi;\n const detune = (midi - target) * 100;\n\n const destination = (this.output as Channel).input;\n\n let buffer = this.buffers[region.sample];\n if (!buffer) {\n console.warn(`Sample not found: ${region.sample}`);\n return () => undefined;\n }\n\n return startSample({\n buffer,\n destination,\n decayTime: _note.decayTime ?? this.#config.decayTime,\n detune: detune + (_note.detune ?? this.#config.detune),\n gain: midiVelToGain(_note.velocity ?? this.#config.velocity),\n time: _note.time,\n duration: _note.duration,\n stop: this.#stop.subscribe,\n stopId: _note.stopId ?? _note.note,\n });\n });\n return (time?: number) => stopAll.forEach((stop) => stop(time));\n }\n\n stop(note?: StopSample | string | number) {\n const note_ = typeof note === \"object\" ? note : { stopId: note };\n this.#stop.trigger(note_);\n }\n\n disconnect() {\n this.stop();\n this.#output.disconnect();\n }\n}\n","import { AudioInsert } from \"./sampler/connect\";\nimport { Subscribe } from \"./sampler/signals\";\n\n// @private\nexport function createTremolo(\n context: AudioContext,\n depth: Subscribe<number>\n): AudioInsert {\n const input = new GainNode(context);\n const output = new GainNode(context);\n\n // force mono sources to be stereo\n input.channelCount = 2;\n input.channelCountMode = \"explicit\";\n\n const splitter = new ChannelSplitterNode(context, { numberOfOutputs: 2 });\n const ampL = new GainNode(context);\n const ampR = new GainNode(context);\n const merger = new ChannelMergerNode(context, { numberOfInputs: 2 });\n\n const lfoL = new OscillatorNode(context, {\n type: \"sine\",\n frequency: 1,\n });\n lfoL.start();\n const lfoLAmp = new GainNode(context);\n const lfoR = new OscillatorNode(context, {\n type: \"sine\",\n frequency: 1.1,\n });\n lfoR.start();\n const lfoRAmp = new GainNode(context);\n\n input.connect(splitter);\n splitter.connect(ampL, 0);\n splitter.connect(ampR, 1);\n ampL.connect(merger, 0, 0);\n ampR.connect(merger, 0, 1);\n lfoL.connect(lfoLAmp);\n lfoLAmp.connect(ampL.gain);\n lfoR.connect(lfoRAmp);\n lfoRAmp.connect(ampR.gain);\n merger.connect(output);\n\n const unsubscribe = depth((depth) => {\n lfoLAmp.gain.value = depth;\n lfoRAmp.gain.value = depth;\n });\n\n input.disconnect = () => {\n unsubscribe();\n lfoL.stop();\n lfoR.stop();\n input.disconnect(splitter);\n splitter.disconnect(ampL, 0);\n splitter.disconnect(ampR, 1);\n ampL.disconnect(merger, 0, 0);\n ampR.disconnect(merger, 0, 1);\n lfoL.disconnect(ampL);\n lfoR.disconnect(ampR);\n merger.disconnect(output);\n };\n\n return { input, output };\n}\n","import { midiVelToGain } from \"./sampler/midi\";\nimport { createControl } from \"./sampler/signals\";\nimport { SfzSampler, SfzSamplerConfig } from \"./sfz/sfz-sampler\";\nimport { createTremolo } from \"./tremolo\";\n\nexport function getElectricPianoNames() {\n return Object.keys(INSTRUMENTS);\n}\n\nconst INSTRUMENTS: Record<string, string> = {\n CP80: \"https://danigb.github.io/samples/gs-e-pianos/CP80/cp80.websfz.json\",\n PianetT:\n \"https://danigb.github.io/samples/gs-e-pianos/Pianet T/pianet-t.websfz.json\",\n WurlitzerEP200:\n \"https://danigb.github.io/samples/gs-e-pianos/Wurlitzer EP200/wurlitzer-ep200.websfz.json\",\n TX81Z:\n \"https://danigb.github.io/samples/vcsl/TX81Z/tx81z-fm-piano.websfz.json\",\n};\n\nexport class ElectricPiano extends SfzSampler {\n public readonly tremolo: Readonly<{ level: (value: number) => void }>;\n constructor(\n context: AudioContext,\n options: Partial<SfzSamplerConfig> & { instrument: string }\n ) {\n super(context, {\n ...options,\n instrument: INSTRUMENTS[options.instrument] ?? options.instrument,\n });\n const depth = createControl(0);\n this.tremolo = {\n level: (level) => depth.set(midiVelToGain(level)),\n };\n const tremolo = createTremolo(context, depth.subscribe);\n this.output.addInsert(tremolo);\n }\n}\n","import { SfzInstrument } from \"./sfz/sfz-kits\";\nimport { SfzSampler, SfzSamplerConfig } from \"./sfz/sfz-sampler\";\n\nexport function getMalletNames() {\n return Object.keys(NAME_TO_PATH) as MalletName[];\n}\n\nexport class Mallet extends SfzSampler {\n constructor(\n context: AudioContext,\n options: Partial<SfzSamplerConfig> & { instrument: string }\n ) {\n const instrument = getMallet(options.instrument);\n super(context, {\n ...options,\n instrument,\n });\n }\n}\n\nfunction getMallet(name: MalletName | string): SfzInstrument {\n if (!NAME_TO_PATH[name]) throw Error(`Mallet instrument \"${name}\" not valid`);\n return {\n name: name,\n websfzUrl: BASE_URL + NAME_TO_PATH[name] + EXT,\n };\n}\nconst BASE_URL = \"https://danigb.github.io/samples/vcsl/\";\nconst EXT = \".websfz.json\";\n\ntype MalletName = keyof typeof NAME_TO_PATH;\n\nexport const NAME_TO_PATH: Record<string, string | undefined> = {\n \"Balafon - Hard Mallet\": \"Struck Idiophones/balafon-hard-mallet\",\n \"Balafon - Keyswitch\": \"Struck Idiophones/balafon-keyswitch\",\n \"Balafon - Soft Mallet\": \"Struck Idiophones/balafon-soft-mallet\",\n \"Balafon - Traditional Mallet\":\n \"Struck Idiophones/balafon-traditional-mallet\",\n \"Tubular Bells 1\": \"Struck Idiophones/tubular-bells-1\",\n \"Tubular Bells 2\": \"Struck Idiophones/tubular-bells-2\",\n \"Vibraphone - Hard Mallets\": \"Struck Idiophones/vibraphone-hard-mallets\",\n \"Vibraphone - Keyswitch\": \"Struck Idiophones/vibraphone-keyswitch\",\n \"Vibraphone - Soft Mallets\": \"Struck Idiophones/vibraphone-soft-mallets\",\n \"Xylophone - Hard Mallets\": \"Struck Idiophones/xylophone-hard-mallets\",\n \"Xylophone - Keyswitch\": \"Struck Idiophones/xylophone-keyswitch\",\n \"Xylophone - Medium Mallets\": \"Struck Idiophones/xylophone-medium-mallets\",\n \"Xylophone - Soft Mallets\": \"Struck Idiophones/xylophone-soft-mallets\",\n} as const;\n","export const PROCESSOR = `\"use strict\";(()=>{var f=class extends AudioWorkletProcessor{_pDLength;_preDelay;_pDWrite;_lp1;_lp2;_lp3;_excPhase;_taps;_Delays;sampleRate;static get parameterDescriptors(){return[[\"preDelay\",0,0,sampleRate-1,\"k-rate\"],[\"bandwidth\",.9999,0,1,\"k-rate\"],[\"inputDiffusion1\",.75,0,1,\"k-rate\"],[\"inputDiffusion2\",.625,0,1,\"k-rate\"],[\"decay\",.5,0,1,\"k-rate\"],[\"decayDiffusion1\",.7,0,.999999,\"k-rate\"],[\"decayDiffusion2\",.5,0,.999999,\"k-rate\"],[\"damping\",.005,0,1,\"k-rate\"],[\"excursionRate\",.5,0,2,\"k-rate\"],[\"excursionDepth\",.7,0,2,\"k-rate\"],[\"wet\",1,0,1,\"k-rate\"],[\"dry\",0,0,1,\"k-rate\"]].map(e=>new Object({name:e[0],defaultValue:e[1],minValue:e[2],maxValue:e[3],automationRate:e[4]}))}constructor(e){super(),this.sampleRate=sampleRate,this._Delays=[],this._pDLength=sampleRate+(128-sampleRate%128),this._preDelay=new Float32Array(this._pDLength),this._pDWrite=0,this._lp1=0,this._lp2=0,this._lp3=0,this._excPhase=0,[.004771345,.003595309,.012734787,.009307483,.022579886,.149625349,.060481839,.1249958,.030509727,.141695508,.089244313,.106280031].forEach(a=>this.makeDelay(a,sampleRate)),this._taps=Int16Array.from([.008937872,.099929438,.064278754,.067067639,.066866033,.006283391,.035818689,.011861161,.121870905,.041262054,.08981553,.070931756,.011256342,.004065724],a=>Math.round(a*sampleRate))}makeDelay(e,a){let t=Math.round(e*a),s=2**Math.ceil(Math.log2(t));this._Delays.push([new Float32Array(s),t-1,0,s-1])}writeDelay(e,a){return this._Delays[e][0][this._Delays[e][1]]=a}readDelay(e){return this._Delays[e][0][this._Delays[e][2]]}readDelayAt(e,a){let t=this._Delays[e];return t[0][t[2]+a&t[3]]}readDelayCAt(e,a){let t=this._Delays[e],s=a-~~a,d=~~a+t[2]-1,r=t[3],D=t[0][d++&r],l=t[0][d++&r],h=t[0][d++&r],y=t[0][d&r],u=(3*(l-h)-D+y)/2,m=2*h+D-(5*l+y)/2,c=(h-D)/2;return((u*s+m)*s+c)*s+l}process(e,a,t){let s=~~t.preDelay[0],d=t.bandwidth[0],r=t.inputDiffusion1[0],D=t.inputDiffusion2[0],l=t.decay[0],h=t.decayDiffusion1[0],y=t.decayDiffusion2[0],u=1-t.damping[0],m=t.excursionRate[0]/sampleRate,c=t.excursionDepth[0]*sampleRate/1e3,w=t.wet[0]*.6,A=t.dry[0];if(e[0].length==2)for(let i=127;i>=0;i--)this._preDelay[this._pDWrite+i]=(e[0][0][i]+e[0][1][i])*.5,a[0][0][i]=e[0][0][i]*A,a[0][1][i]=e[0][1][i]*A;else if(e[0].length>0){this._preDelay.set(e[0][0],this._pDWrite);for(let i=127;i>=0;i--)a[0][0][i]=a[0][1][i]=e[0][0][i]*A}else this._preDelay.set(new Float32Array(128),this._pDWrite);let o=0;for(;o<128;){let i=0,b=0;this._lp1+=d*(this._preDelay[(this._pDLength+this._pDWrite-s+o)%this._pDLength]-this._lp1);let p=this.writeDelay(0,this._lp1-r*this.readDelay(0));p=this.writeDelay(1,r*(p-this.readDelay(1))+this.readDelay(0)),p=this.writeDelay(2,r*p+this.readDelay(1)-D*this.readDelay(2)),p=this.writeDelay(3,D*(p-this.readDelay(3))+this.readDelay(2));let k=D*p+this.readDelay(3),g=c*(1+Math.cos(this._excPhase*6.28)),x=c*(1+Math.sin(this._excPhase*6.2847)),_=this.writeDelay(4,k+l*this.readDelay(11)+h*this.readDelayCAt(4,g));this.writeDelay(5,this.readDelayCAt(4,g)-h*_),this._lp2+=u*(this.readDelay(5)-this._lp2),_=this.writeDelay(6,l*this._lp2-y*this.readDelay(6)),this.writeDelay(7,this.readDelay(6)+y*_),_=this.writeDelay(8,k+l*this.readDelay(7)+h*this.readDelayCAt(8,x)),this.writeDelay(9,this.readDelayCAt(8,x)-h*_),this._lp3+=u*(this.readDelay(9)-this._lp3),_=this.writeDelay(10,l*this._lp3-y*this.readDelay(10)),this.writeDelay(11,this.readDelay(10)+y*_),i=this.readDelayAt(9,this._taps[0])+this.readDelayAt(9,this._taps[1])-this.readDelayAt(10,this._taps[2])+this.readDelayAt(11,this._taps[3])-this.readDelayAt(5,this._taps[4])-this.readDelayAt(6,this._taps[5])-this.readDelayAt(7,this._taps[6]),b=this.readDelayAt(5,this._taps[7])+this.readDelayAt(5,this._taps[8])-this.readDelayAt(6,this._taps[9])+this.readDelayAt(7,this._taps[10])-this.readDelayAt(9,this._taps[11])-this.readDelayAt(10,this._taps[12])-this.readDelayAt(11,this._taps[13]),a[0][0][o]+=i*w,a[0][1][o]+=b*w,this._excPhase+=m,o++;for(let R=0,n=this._Delays[0];R<this._Delays.length;n=this._Delays[++R])n[1]=n[1]+1&n[3],n[2]=n[2]+1&n[3]}return this._pDWrite=(this._pDWrite+128)%this._pDLength,!0}};registerProcessor(\"DattorroReverb\",f);})();`;\n","import { PROCESSOR } from \"./processor.min\";\n\nconst PARAMS = [\n \"preDelay\",\n \"bandwidth\",\n \"inputDiffusion1\",\n \"inputDiffusion2\",\n \"decay\",\n \"decayDiffusion1\",\n \"decayDiffusion2\",\n \"damping\",\n \"excursionRate\",\n \"excursionDepth\",\n \"wet\",\n \"dry\",\n] as const;\n\nconst init = new WeakMap<AudioContext, Promise<void>>();\n\nasync function createDattorroReverbEffect(context: AudioContext) {\n let ready = init.get(context);\n if (!ready) {\n const blob = new Blob([PROCESSOR], { type: \"application/javascript\" });\n const url = URL.createObjectURL(blob);\n ready = context.audioWorklet.addModule(url);\n init.set(context, ready);\n }\n await ready;\n\n const reverb = new AudioWorkletNode(context, \"DattorroReverb\", {\n outputChannelCount: [2],\n });\n return reverb;\n}\n\nexport class Reverb {\n #effect: AudioWorkletNode | undefined;\n #ready: Promise<this>;\n public readonly input: AudioNode;\n #output: AudioNode;\n\n constructor(context: AudioContext) {\n this.input = context.createGain();\n this.#output = context.destination;\n this.#ready = createDattorroReverbEffect(context).then((reverb) => {\n this.input.connect(reverb);\n reverb.connect(this.#output);\n this.#effect = reverb;\n return this;\n });\n }\n\n get paramNames() {\n return PARAMS;\n }\n\n getParam(name: (typeof PARAMS)[number]): AudioParam | undefined {\n return this.#effect?.parameters.get(\"preDelay\");\n }\n\n get isReady(): boolean {\n return this.#effect !== undefined;\n }\n\n ready(): Promise<this> {\n return this.#ready;\n }\n\n connect(output: AudioNode) {\n if (this.#effect) {\n this.#effect.disconnect(this.#output);\n this.#effect.connect(output);\n }\n this.#output = output;\n }\n}\n","import { findFirstSupportedFormat } from \"../sampler/load-audio\";\nimport { findNearestMidi, toMidi } from \"../sampler/midi\";\nimport { Sampler, SamplerAudioLoader } from \"../sampler/sampler\";\n\nexport type SoundfontConfig = {\n kit: \"FluidR3_GM\" | \"MusyngKite\";\n instrument: string;\n\n destination: AudioNode;\n\n detune: number;\n volume: number;\n velocity: number;\n decayTime?: number;\n lpfCutoffHz?: number;\n extraGain?: number;\n};\n\nexport class Soundfont extends Sampler {\n constructor(\n context: AudioContext,\n options: Partial<SoundfontConfig> & { instrument: string }\n ) {\n const url = options.instrument.startsWith(\"http\")\n ? options.instrument\n : gleitzKitUrl(options.instrument, options.kit);\n console.log(\"!!! URL\", { url });\n super(context, {\n destination: options.destination,\n\n detune: options.detune,\n volume: options.volume,\n velocity: options.velocity,\n decayTime: options.decayTime ?? 0.5,\n lpfCutoffHz: options.lpfCutoffHz,\n buffers: soundfontLoader(url),\n noteToSample: (note, buffers, config) => {\n let midi = toMidi(note.note);\n return midi === undefined ? [\"\", 0] : findNearestMidi(midi, buffers);\n },\n });\n\n // This is to compensate the low volume of the original samples\n const extraGain = options.extraGain ?? 5;\n const gain = new GainNode(context, { gain: extraGain });\n this.output.addInsert(gain);\n }\n}\n\nfunction soundfontLoader(url: string): SamplerAudioLoader {\n return async (context, buffers) => {\n const sourceFile = await (await fetch(url)).text();\n const json = midiJsToJson(sourceFile);\n\n const noteNames = Object.keys(json);\n await Promise.all(\n noteNames.map(async (noteName) => {\n const midi = toMidi(noteName);\n if (!midi) return;\n const audioData = base64ToArrayBuffer(\n removeBase64Prefix(json[noteName])\n );\n const buffer = await context.decodeAudioData(audioData);\n buffers[midi] = buffer;\n })\n );\n };\n}\n\n// convert a MIDI.js javascript soundfont file to json\nfunction midiJsToJson(source: string) {\n const header = source.indexOf(\"MIDI.Soundfont.\");\n if (header < 0) throw Error(\"Invalid MIDI.js Soundfont format\");\n const start = source.indexOf(\"=\", header) + 2;\n const end = source.lastIndexOf(\",\");\n return JSON.parse(source.slice(start, end) + \"}\");\n}\n\nfunction removeBase64Prefix(audioBase64: string) {\n return audioBase64.slice(audioBase64.indexOf(\",\") + 1);\n}\n\nfunction base64ToArrayBuffer(base64: string) {\n const decoded = window.atob(base64);\n const len = decoded.length;\n const bytes = new Uint8Array(len);\n for (let i = 0; i < len; i++) {\n bytes[i] = decoded.charCodeAt(i);\n }\n return bytes.buffer;\n}\n\nfunction gleitzKitUrl(\n name: string,\n kit: \"FluidR3_GM\" | \"MusyngKite\" = \"MusyngKite\"\n) {\n const format = findFirstSupportedFormat([\"ogg\", \"mp3\"]) ?? \"mp3\";\n return `https://gleitz.github.io/midi-js-soundfonts/${kit}/${name}-${format}.js`;\n}\n\nexport function getSoundfontInstrumentNames() {\n return [\n \"accordion\",\n \"acoustic_bass\",\n \"acoustic_grand_piano\",\n \"acoustic_guitar_nylon\",\n \"acoustic_guitar_steel\",\n \"agogo\",\n \"alto_sax\",\n \"applause\",\n \"bagpipe\",\n \"banjo\",\n \"baritone_sax\",\n \"bassoon\",\n \"bird_tweet\",\n \"blown_bottle\",\n \"brass_section\",\n \"breath_noise\",\n \"bright_acoustic_piano\",\n \"celesta\",\n \"cello\",\n \"choir_aahs\",\n \"church_organ\",\n \"clarinet\",\n \"clavinet\",\n \"contrabass\",\n \"distortion_guitar\",\n \"drawbar_organ\",\n \"dulcimer\",\n \"electric_bass_finger\",\n \"electric_bass_pick\",\n \"electric_grand_piano\",\n \"electric_guitar_clean\",\n \"electric_guitar_jazz\",\n \"electric_guitar_muted\",\n \"electric_piano_1\",\n \"electric_piano_2\",\n \"english_horn\",\n \"fiddle\",\n \"flute\",\n \"french_horn\",\n \"fretless_bass\",\n \"fx_1_rain\",\n \"fx_2_soundtrack\",\n \"fx_3_crystal\",\n \"fx_4_atmosphere\",\n \"fx_5_brightness\",\n \"fx_6_goblins\",\n \"fx_7_echoes\",\n \"fx_8_scifi\",\n \"glockenspiel\",\n \"guitar_fret_noise\",\n \"guitar_harmonics\",\n \"gunshot\",\n \"harmonica\",\n \"harpsichord\",\n \"helicopter\",\n \"honkytonk_piano\",\n \"kalimba\",\n \"koto\",\n \"lead_1_square\",\n \"lead_2_sawtooth\",\n \"lead_3_calliope\",\n \"lead_4_chiff\",\n \"lead_5_charang\",\n \"lead_6_voice\",\n \"lead_7_fifths\",\n \"lead_8_bass__lead\",\n \"marimba\",\n \"melodic_tom\",\n \"music_box\",\n \"muted_trumpet\",\n \"oboe\",\n \"ocarina\",\n \"orchestra_hit\",\n \"orchestral_harp\",\n \"overdriven_guitar\",\n \"pad_1_new_age\",\n \"pad_2_warm\",\n \"pad_3_polysynth\",\n \"pad_4_choir\",\n \"pad_5_bowed\",\n \"pad_6_metallic\",\n \"pad_7_halo\",\n \"pad_8_sweep\",\n \"pan_flute\",\n \"percussive_organ\",\n \"piccolo\",\n \"pizzicato_strings\",\n \"recorder\",\n \"reed_organ\",\n \"reverse_cymbal\",\n \"rock_organ\",\n \"seashore\",\n \"shakuhachi\",\n \"shamisen\",\n \"shanai\",\n \"sitar\",\n \"slap_bass_1\",\n \"slap_bass_2\",\n \"soprano_sax\",\n \"steel_drums\",\n \"string_ensemble_1\",\n \"string_ensemble_2\",\n \"synth_bass_1\",\n \"synth_bass_2\",\n \"synth_brass_1\",\n \"synth_brass_2\",\n \"synth_choir\",\n \"synth_drum\",\n \"synth_strings_1\",\n \"synth_strings_2\",\n \"taiko_drum\",\n \"tango_accordion\",\n \"telephone_ring\",\n \"tenor_sax\",\n \"timpani\",\n \"tinkle_bell\",\n \"tremolo_strings\",\n \"trombone\",\n \"trumpet\",\n \"tuba\",\n \"tubular_bells\",\n \"vibraphone\",\n \"viola\",\n \"violin\",\n \"voice_oohs\",\n \"whistle\",\n \"woodblock\",\n \"xylophone\",\n ];\n}\n","import {\n AudioBuffers,\n findFirstSupportedFormat,\n loadAudioBuffer,\n} from \"./sampler/load-audio\";\nimport { toMidi } from \"./sampler/midi\";\nimport { Sampler, SamplerAudioLoader } from \"./sampler/sampler\";\n\n/**\n * Splendid Grand Piano options\n */\nexport type SplendidGrandPianoConfig = {\n baseUrl: string;\n destination: AudioNode;\n\n detune: number;\n volume: number;\n velocity: number;\n decayTime?: number;\n lpfCutoffHz?: number;\n};\n\nconst BASE_URL = \"https://danigb.github.io/samples/splendid-grand-piano\";\n\nexport class SplendidGrandPiano extends Sampler {\n constructor(\n context: AudioContext,\n options: Partial<SplendidGrandPianoConfig>\n ) {\n super(context, {\n destination: options.destination,\n\n detune: options.detune,\n volume: options.volume,\n velocity: options.velocity,\n decayTime: options.decayTime ?? 0.5,\n lpfCutoffHz: options.lpfCutoffHz,\n\n buffers: splendidGrandPianoLoader(options.baseUrl ?? BASE_URL),\n\n noteToSample: (note, buffers, config) => {\n const midi = toMidi(note.note);\n if (!midi) return [note.note, 0];\n\n const vel = note.velocity ?? config.velocity;\n const layerIdx = LAYERS.findIndex(\n (layer) => vel >= layer.vel_range[0] && vel <= layer.vel_range[1]\n );\n const layer = LAYERS[layerIdx];\n if (!layer) return [\"\", 0];\n\n return findNearestMidiInLayer(layer.name, midi, buffers);\n },\n });\n }\n}\n\nfunction findNearestMidiInLayer(\n prefix: string,\n midi: number,\n buffers: AudioBuffers\n): [string, number] {\n let i = 0;\n while (buffers[prefix + (midi + i)] === undefined && i < 128) {\n if (i > 0) i = -i;\n else i = -i + 1;\n }\n\n return i === 127 ? [prefix + midi, 0] : [prefix + (midi + i), -i * 100];\n}\n\nfunction splendidGrandPianoLoader(baseUrl: string): SamplerAudioLoader {\n const format = findFirstSupportedFormat([\"ogg\", \"m4a\"]) ?? \"ogg\";\n return async (context: AudioContext, buffers: AudioBuffers) => {\n for (const layer of LAYERS) {\n await Promise.all(\n layer.samples.map(async ([midi, name]) => {\n const url = `${baseUrl}/${name}.${format}`;\n const buffer = await loadAudioBuffer(context, url);\n if (buffer) buffers[layer.name + midi] = buffer;\n })\n );\n }\n };\n}\n\nexport const LAYERS = [\n {\n name: \"PPP\",\n vel_range: [1, 40],\n cutoff: 1000,\n samples: [\n [23, \"PP-B-1\"],\n [27, \"PP-D#0\"],\n [29, \"PP-F0\"],\n [31, \"PP-G0\"],\n [33, \"PP-A0\"],\n [35, \"PP-B0\"],\n [37, \"PP-C#1\"],\n [38, \"PP-D1\"],\n [40, \"PP-E1\"],\n [41, \"PP-F1\"],\n [43, \"PP-G1\"],\n [45, \"PP-A1\"],\n [47, \"PP-B1\"],\n [48, \"PP-C2\"],\n [50, \"PP-D2\"],\n [52, \"PP-E2\"],\n [53, \"PP-F2\"],\n [55, \"PP-G2\"],\n [56, \"PP-G#2\"],\n [57, \"PP-A2\"],\n [58, \"PP-A#2\"],\n [59, \"PP-B2\"],\n [60, \"PP-C3\"],\n [62, \"PP-D3\"],\n [64, \"PP-E3\"],\n [65, \"PP-F3\"],\n [67, \"PP-G3\"],\n [69, \"PP-A3\"],\n [71, \"PP-B3\"],\n [72, \"PP-C4\"],\n [74, \"PP-D4\"],\n [76, \"PP-E4\"],\n [77, \"PP-F4\"],\n [79, \"PP-G4\"],\n [80, \"PP-G#4\"],\n [81, \"PP-A4\"],\n [82, \"PP-A#4\"],\n [83, \"PP-B4\"],\n [85, \"PP-C#5\"],\n [86, \"PP-D5\"],\n [87, \"PP-D#5\"],\n [89, \"PP-F5\"],\n [90, \"PP-F#5\"],\n [91, \"PP-G5\"],\n [92, \"PP-G#5\"],\n [93, \"PP-A5\"],\n [94, \"PP-A#5\"],\n [95, \"PP-B5\"],\n [96, \"PP-C6\"],\n [97, \"PP-C#6\"],\n [98, \"PP-D6\"],\n [99, \"PP-D#6\"],\n [100, \"PP-E6\"],\n [101, \"PP-F6\"],\n [102, \"PP-F#6\"],\n [103, \"PP-G6\"],\n [104, \"PP-G#6\"],\n [105, \"PP-A6\"],\n [106, \"PP-A#6\"],\n [107, \"PP-B6\"],\n [108, \"PP-C7\"],\n ],\n },\n {\n name: \"PP\",\n vel_range: [41, 67],\n samples: [\n [23, \"PP-B-1\"],\n [27, \"PP-D#0\"],\n [29, \"PP-F0\"],\n [31, \"PP-G0\"],\n [33, \"PP-A0\"],\n [35, \"PP-B0\"],\n [37, \"PP-C#1\"],\n [38, \"PP-D1\"],\n [40, \"PP-E1\"],\n [41, \"PP-F1\"],\n [43, \"PP-G1\"],\n [45, \"PP-A1\"],\n [47, \"PP-B1\"],\n [48, \"PP-C2\"],\n [50, \"PP-D2\"],\n [52, \"PP-E2\"],\n [53, \"PP-F2\"],\n [55, \"PP-G2\"],\n [56, \"PP-G#2\"],\n [57, \"PP-A2\"],\n [58, \"PP-A#2\"],\n [59, \"PP-B2\"],\n [60, \"PP-C3\"],\n [62, \"PP-D3\"],\n [64, \"PP-E3\"],\n [65, \"PP-F3\"],\n [67, \"PP-G3\"],\n [69, \"PP-A3\"],\n [71, \"PP-B3\"],\n [72, \"PP-C4\"],\n [74, \"PP-D4\"],\n [76, \"PP-E4\"],\n [77, \"PP-F4\"],\n [79, \"PP-G4\"],\n [80, \"PP-G#4\"],\n [81, \"PP-A4\"],\n [82, \"PP-A#4\"],\n [83, \"PP-B4\"],\n [85, \"PP-C#5\"],\n [86, \"PP-D5\"],\n [87, \"PP-D#5\"],\n [89, \"PP-F5\"],\n [90, \"PP-F#5\"],\n [91, \"PP-G5\"],\n [92, \"PP-G#5\"],\n [93, \"PP-A5\"],\n [94, \"PP-A#5\"],\n [95, \"PP-B5\"],\n [96, \"PP-C6\"],\n [97, \"PP-C#6\"],\n [98, \"PP-D6\"],\n [99, \"PP-D#6\"],\n [100, \"PP-E6\"],\n [101, \"PP-F6\"],\n [102, \"PP-F#6\"],\n [103, \"PP-G6\"],\n [104, \"PP-G#6\"],\n [105, \"PP-A6\"],\n [106, \"PP-A#6\"],\n [107, \"PP-B6\"],\n [108, \"PP-C7\"],\n ],\n },\n {\n name: \"MP\",\n vel_range: [68, 84],\n samples: [\n [23, \"Mp-B-1\"],\n [27, \"Mp-D#0\"],\n [29, \"Mp-F0\"],\n [31, \"Mp-G0\"],\n [33, \"Mp-A0\"],\n [35, \"Mp-B0\"],\n [37, \"Mp-C#1\"],\n [38, \"Mp-D1\"],\n [40, \"Mp-E1\"],\n [41, \"Mp-F1\"],\n [43, \"Mp-G1\"],\n [45, \"Mp-A1\"],\n [47, \"Mp-B1\"],\n [48, \"Mp-C2\"],\n [50, \"Mp-D2\"],\n [52, \"Mp-E2\"],\n [53, \"Mp-F2\"],\n [55, \"Mp-G2\"],\n [56, \"Mp-G#2\"],\n [57, \"Mp-A2\"],\n [58, \"Mp-A#2\"],\n [59, \"Mp-B2\"],\n [60, \"Mp-C3\"],\n [62, \"Mp-D3\"],\n [64, \"Mp-E3\"],\n [65, \"Mp-F3\"],\n [67, \"Mp-G3\"],\n [69, \"Mp-A3\"],\n [71, \"Mp-B3\"],\n [72, \"Mp-C4\"],\n [74, \"Mp-D4\"],\n [76, \"Mp-E4\"],\n [77, \"Mp-F4\"],\n [79, \"Mp-G4\"],\n [80, \"Mp-G#4\"],\n [81, \"Mp-A4\"],\n [82, \"Mp-A#4\"],\n [83, \"Mp-B4\"],\n [85, \"Mp-C#5\"],\n [86, \"Mp-D5\"],\n [87, \"Mp-D#5\"],\n [88, \"Mp-E5\"],\n [89, \"Mp-F5\"],\n [90, \"Mp-F#5\"],\n [91, \"Mp-G5\"],\n [92, \"Mp-G#5\"],\n [93, \"Mp-A5\"],\n [94, \"Mp-A#5\"],\n [95, \"Mp-B5\"],\n [96, \"Mp-C6\"],\n [97, \"Mp-C#6\"],\n [98, \"Mp-D6\"],\n [99, \"Mp-D#6\"],\n [100, \"PP-E6\"],\n [101, \"Mp-F6\"],\n [102, \"Mp-F#6\"],\n [103, \"Mp-G6\"],\n [104, \"Mp-G#6\"],\n [105, \"Mp-A6\"],\n [106, \"Mp-A#6\"],\n [107, \"PP-B6\"],\n [108, \"PP-C7\"],\n ],\n },\n {\n name: \"MF\",\n vel_range: [85, 100],\n samples: [\n [23, \"Mf-B-1\"],\n [27, \"Mf-D#0\"],\n [29, \"Mf-F0\"],\n [31, \"Mf-G0\"],\n [33, \"Mf-A0\"],\n [35, \"Mf-B0\"],\n [37, \"Mf-C#1\"],\n [38, \"Mf-D1\"],\n [40, \"Mf-E1\"],\n [41, \"Mf-F1\"],\n [43, \"Mf-G1\"],\n [45, \"Mf-A1\"],\n [47, \"Mf-B1\"],\n [48, \"Mf-C2\"],\n [50, \"Mf-D2\"],\n [52, \"Mf-E2\"],\n [53, \"Mf-F2\"],\n [55, \"Mf-G2\"],\n [56, \"Mf-G#2\"],\n [57, \"Mf-A2\"],\n [58, \"Mf-A#2\"],\n [59, \"Mf-B2\"],\n [60, \"Mf-C3\"],\n [62, \"Mf-D3\"],\n [64, \"Mf-E3\"],\n [65, \"Mf-F3\"],\n [67, \"Mf-G3\"],\n [69, \"Mf-A3\"],\n [71, \"Mf-B3\"],\n [72, \"Mf-C4\"],\n [74, \"Mf-D4\"],\n [76, \"Mf-E4\"],\n [77, \"Mf-F4\"],\n [79, \"Mf-G4\"],\n [80, \"Mf-G#4\"],\n [81, \"Mf-A4\"],\n [82, \"Mf-A#4\"],\n [83, \"Mf-B4\"],\n [85, \"Mf-C#5\"],\n [86, \"Mf-D5\"],\n [87, \"Mf-D#5\"],\n [88, \"Mf-E5\"],\n [89, \"Mf-F5\"],\n [90, \"Mf-F#5\"],\n [91, \"Mf-G5\"],\n [92, \"Mf-G#5\"],\n [93, \"Mf-A5\"],\n [94, \"Mf-A#5\"],\n [95, \"Mf-B5\"],\n [96, \"Mf-C6\"],\n [97, \"Mf-C#6\"],\n [98, \"Mf-D6\"],\n [99, \"Mf-D#6\"],\n [100, \"Mf-E6\"],\n [101, \"Mf-F6\"],\n [102, \"Mf-F#6\"],\n [103, \"Mf-G6\"],\n [104, \"Mf-G#6\"],\n [105, \"Mf-A6\"],\n [106, \"Mf-A#6\"],\n [107, \"Mf-B6\"],\n [108, \"PP-C7\"],\n ],\n },\n {\n name: \"FF\",\n vel_range: [101, 127],\n samples: [\n [23, \"FF-B-1\"],\n [27, \"FF-D#0\"],\n [29, \"FF-F0\"],\n [31, \"FF-G0\"],\n [33, \"FF-A0\"],\n [35, \"FF-B0\"],\n [37, \"FF-C#1\"],\n [38, \"FF-D1\"],\n [40, \"FF-E1\"],\n [41, \"FF-F1\"],\n [43, \"FF-G1\"],\n [45, \"FF-A1\"],\n [47, \"FF-B1\"],\n [48, \"FF-C2\"],\n [50, \"FF-D2\"],\n [52, \"FF-E2\"],\n [53, \"FF-F2\"],\n [55, \"FF-G2\"],\n [56, \"FF-G#2\"],\n [57, \"FF-A2\"],\n [58, \"FF-A#2\"],\n [59, \"FF-B2\"],\n [60, \"FF-C3\"],\n [62, \"FF-D3\"],\n [64, \"FF-E3\"],\n [65, \"FF-F3\"],\n [67, \"FF-G3\"],\n [69, \"FF-A3\"],\n [71, \"FF-B3\"],\n [72, \"FF-C4\"],\n [74, \"FF-D4\"],\n [76, \"FF-E4\"],\n [77, \"FF-F4\"],\n [79, \"FF-G4\"],\n [80, \"FF-G#4\"],\n [81, \"FF-A4\"],\n [82, \"FF-A#4\"],\n [83, \"FF-B4\"],\n [85, \"FF-C#5\"],\n [86, \"FF-D5\"],\n [88, \"FF-E5\"],\n [89, \"FF-F5\"],\n [91, \"FF-G5\"],\n [93, \"FF-A5\"],\n [95, \"Mf-B5\"],\n [96, \"Mf-C6\"],\n [97, \"Mf-C#6\"],\n [98, \"Mf-D6\"],\n [99, \"Mf-D#6\"],\n [100, \"Mf-E6\"],\n [102, \"Mf-F#6\"],\n [103, \"Mf-G6\"],\n [104, \"Mf-G#6\"],\n [105, \"Mf-A6\"],\n [106, \"Mf-A#6\"],\n [107, \"Mf-B6\"],\n [108, \"Mf-C7\"],\n ],\n },\n];\n"],"mappings":"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MACZ,CAAC,IAAI,QAAQ;AAAA,MACb,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,QAAQ;AAAA,MACb,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,QAAQ;AAAA,MACb,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,QAAQ;AAAA,MACb,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,QAAQ;AAAA,MACb,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,QAAQ;AAAA,MACb,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,QAAQ;AAAA,MACb,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,QAAQ;AAAA,MACb,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,QAAQ;AAAA,MACb,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,QAAQ;AAAA,MACb,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,QAAQ;AAAA,MACb,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,QAAQ;AAAA,MACb,CAAC,KAAK,OAAO;AAAA,MACb,CAAC,KAAK,OAAO;AAAA,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","names":["canPlay","volume","send","instrument","urls","_config","_stop","_load","_output","_a","depth","INSTRUMENTS","_output","BASE_URL","_a","layer"]}
|
|
1
|
+
{"version":3,"sources":["../src/sampler/load-audio.ts","../src/sampler/connect.ts","../src/sampler/midi.ts","../src/sampler/signals.ts","../src/sampler/channel.ts","../src/sampler/start-sample.ts","../src/sampler/sampler.ts","../src/drum-machine/dm-instrument.ts","../src/drum-machine/drum-machine.ts","../src/sfz/sfz-load.ts","../src/sfz/sfz-regions.ts","../src/sfz/sfz-sampler.ts","../src/tremolo.ts","../src/electric-piano.ts","../src/mallet.ts","../src/reverb/processor.min.ts","../src/reverb/reverb.ts","../src/soundfont/soundfont.ts","../src/splendid-grand-piano.ts"],"sourcesContent":["export type AudioBuffers = Record<string | number, AudioBuffer | undefined>;\n\nexport async function loadAudioBuffer(\n context: BaseAudioContext,\n url: string\n): Promise<AudioBuffer | undefined> {\n url = url.replace(/#/g, \"%23\").replace(/([^:]\\/)\\/+/g, \"$1\");\n const response = await fetch(url);\n if (response.status !== 200) {\n console.warn(\n \"Error loading buffer. Invalid status: \",\n response.status,\n url\n );\n return;\n }\n try {\n const audioData = await response.arrayBuffer();\n const buffer = await context.decodeAudioData(audioData);\n return buffer;\n } catch (error) {\n console.warn(\"Error loading buffer\", error, url);\n }\n}\n\nexport function findFirstSupportedFormat(formats: string[]): string | null {\n if (typeof document === \"undefined\") return null;\n\n const audio = document.createElement(\"audio\");\n for (let i = 0; i < formats.length; i++) {\n const format = formats[i];\n const canPlay = audio.canPlayType(`audio/${format}`);\n if (canPlay === \"probably\" || canPlay === \"maybe\") {\n return format;\n }\n // check Safari for aac format\n if (format === \"m4a\") {\n const canPlay = audio.canPlayType(`audio/aac`);\n if (canPlay === \"probably\" || canPlay === \"maybe\") {\n return format;\n }\n }\n }\n return null;\n}\n","export type AudioInsert = {\n input: AudioNode;\n output: AudioNode;\n};\n\nexport function connectSerial(nodes: (AudioNode | AudioInsert | undefined)[]) {\n const _nodes = nodes.filter((x): x is AudioNode | AudioInsert => !!x);\n _nodes.reduce((a, b) => {\n const left = \"output\" in a ? a.output : a;\n const right = \"input\" in b ? b.input : b;\n left.connect(right);\n return b;\n });\n\n return () => {\n _nodes.reduce((a, b) => {\n const left = \"output\" in a ? a.output : a;\n const right = \"input\" in b ? b.input : b;\n left.disconnect(right);\n return b;\n });\n };\n}\n\nexport function connectAudioBus(\n node: AudioNode,\n destination: AudioNode,\n gain: number\n) {\n const mix = node.context.createGain();\n mix.gain.value = gain;\n node.connect(mix);\n mix.connect(destination);\n\n return () => {\n node.disconnect(mix);\n mix.disconnect(destination);\n };\n}\n","function noteNameToMidi(note: string): number | undefined {\n const REGEX = /^([a-gA-G]?)(#{1,}|b{1,}|)(-?\\d+)$/;\n const m = REGEX.exec(note);\n if (!m) return;\n const letter = m[1].toUpperCase();\n if (!letter) return;\n\n const acc = m[2];\n const alt = acc[0] === \"b\" ? -acc.length : acc.length;\n const oct = m[3] ? +m[3] : 4;\n\n const step = (letter.charCodeAt(0) + 3) % 7;\n return [0, 2, 4, 5, 7, 9, 11][step] + alt + 12 * (oct + 1);\n}\n\nexport function toMidi(note: string | number | undefined): number | undefined {\n return note === undefined\n ? undefined\n : typeof note === \"number\"\n ? note\n : noteNameToMidi(note);\n}\n\n/// This is how the MIDI association converts midi velocity [0..127] into gain [0..1]\n/// @see https://www.midi.org/specifications/file-format-specifications/dls-downloadable-sounds/dls-level-1\nexport function midiVelToGain(vel: number) {\n return (vel * vel) / 16129; // 16129 = 127 * 127\n}\nexport function findNearestMidi(\n midi: number,\n isAvailable: Record<string | number, unknown>\n): [number, number] {\n let i = 0;\n while (isAvailable[midi + i] === undefined && i < 128) {\n if (i > 0) i = -i;\n else i = -i + 1;\n }\n\n return i === 127 ? [midi, 0] : [midi + i, -i * 100];\n}\n","/**\n * A function to unsubscribe from an event or control\n */\nexport type Unsubscribe = () => void;\n/**\n * A function that listener to event or control changes\n */\nexport type Listener<T> = (value: T) => void;\n/**\n * A function to subscribe an trigger or control events\n */\nexport type Subscribe<T> = (listener: Listener<T>) => Unsubscribe;\n\n/**\n * A trigger is a subscribable event\n */\nexport type Trigger<T> = {\n subscribe: Subscribe<T>;\n trigger: (event: T) => void;\n};\n\n/**\n * A control is a subscribable value\n */\nexport type Control<T> = {\n subscribe: Subscribe<T>;\n set: (value: T) => void;\n get: () => T;\n};\n\n/**\n * Create a control signal\n * @param initialValue\n * @returns Control\n */\nexport function createControl<T>(initialValue: T): Control<T> {\n let current = initialValue;\n const listeners = new Set<Listener<T>>();\n\n function subscribe(listener: Listener<T>) {\n listeners.add(listener);\n listener(current);\n return () => {\n listeners.delete(listener);\n };\n }\n\n function set(value: T) {\n current = value;\n listeners.forEach((listener) => listener(current));\n }\n\n function get(): T {\n return current;\n }\n return { subscribe, set, get };\n}\n\nexport function createTrigger<T>(): Trigger<T> {\n const listeners = new Set<Listener<T>>();\n\n function subscribe(listener: Listener<T>) {\n listeners.add(listener);\n return () => {\n listeners.delete(listener);\n };\n }\n\n function trigger(value: T) {\n listeners.forEach((listener) => listener(value));\n }\n\n return { subscribe, trigger };\n}\n\nexport function unsubscribeAll(unsubscribe: Array<Unsubscribe | undefined>) {\n let done = false;\n return () => {\n if (done) return;\n done = true;\n unsubscribe.forEach((cb) => cb?.());\n };\n}\n","import { AudioInsert, connectSerial } from \"./connect\";\nimport { midiVelToGain } from \"./midi\";\nimport { createControl } from \"./signals\";\n\ntype ChannelOptions = {\n destination: AudioNode;\n volume: number;\n volumeToGain: (volume: number) => number;\n};\n\ntype Send = {\n name: string;\n mix: GainNode;\n disconnect: () => void;\n};\n\n/**\n * @private\n */\nexport class Channel {\n public readonly setVolume: (vol: number) => void;\n public readonly input: AudioNode;\n\n #volume: GainNode;\n #sends?: Send[];\n #inserts?: (AudioNode | AudioInsert)[];\n #disconnect: () => void;\n #unsubscribe: () => void;\n #options: Readonly<ChannelOptions>;\n\n constructor(\n public readonly context: AudioContext,\n options: Partial<ChannelOptions>\n ) {\n this.#options = Object.freeze({\n destination: context.destination,\n volume: 100,\n volumeToGain: midiVelToGain,\n ...options,\n });\n\n this.input = new GainNode(this.context);\n this.#volume = new GainNode(this.context);\n\n this.#disconnect = connectSerial([\n this.input,\n this.#volume,\n this.#options.destination,\n ]);\n\n const volume = createControl(options.volume ?? 100);\n this.setVolume = volume.set;\n const volumeToGain = options.volumeToGain ?? midiVelToGain;\n this.#unsubscribe = volume.subscribe((volume) => {\n this.#volume.gain.value = volumeToGain(volume);\n });\n }\n\n addInsert(effect: AudioNode | AudioInsert) {\n this.#inserts ??= [];\n this.#inserts.push(effect);\n this.#disconnect();\n this.#disconnect = connectSerial([\n this.input,\n ...this.#inserts,\n this.#volume,\n this.#options.destination,\n ]);\n }\n\n addEffect(\n name: string,\n effect: AudioNode | { input: AudioNode },\n mixValue: number\n ) {\n const mix = new GainNode(this.context);\n mix.gain.value = mixValue;\n const input = \"input\" in effect ? effect.input : effect;\n const disconnect = connectSerial([this.#volume, mix, input]);\n\n this.#sends ??= [];\n this.#sends.push({ name, mix, disconnect });\n }\n\n sendEffect(name: string, mix: number) {\n const send = this.#sends?.find((send) => send.name === name);\n if (send) {\n send.mix.gain.value = mix;\n } else {\n console.warn(\"Send bus not found: \" + name);\n }\n }\n\n disconnect() {\n this.#disconnect();\n this.#unsubscribe();\n this.#sends?.forEach((send) => send.disconnect());\n this.#sends = undefined;\n }\n}\n","import { connectSerial } from \"./connect\";\nimport { toMidi } from \"./midi\";\nimport { Subscribe, unsubscribeAll } from \"./signals\";\n\nexport type StopSample = {\n stopId?: string | number;\n time?: number;\n};\n\nexport type SampleOptions = {\n decayTime?: number;\n detune?: number;\n gain?: number;\n};\n\ntype SampleNote = {\n midi?: number;\n note?: string;\n};\n\nexport type StartSample = {\n buffer: AudioBuffer;\n decayTime?: number;\n destination: AudioNode;\n detune?: number;\n duration?: number;\n gain?: number;\n lpfCutoffHz?: number;\n onEnded?: () => void;\n stop?: Subscribe<StopSample | undefined>;\n stopId?: string | number;\n time?: number;\n};\n\nexport function getSampleNote<T extends SampleNote>(\n note: number | string | T\n): T {\n if (typeof note === \"number\") {\n return { midi: note } as T;\n } else if (typeof note === \"string\") {\n return { note, midi: toMidi(note) } as T;\n } else {\n return { midi: note.midi ?? toMidi(note.note), ...note };\n }\n}\n\nexport function startSample(sample: StartSample) {\n const context = sample.destination.context;\n // Buffer source\n const source = context.createBufferSource();\n source.buffer = sample.buffer;\n source.detune.value = sample?.detune ?? 0;\n\n // Low pass filter\n const lpf = sample.lpfCutoffHz\n ? new BiquadFilterNode(context, {\n type: \"lowpass\",\n frequency: sample.lpfCutoffHz,\n })\n : undefined;\n\n // Sample volume\n const volume = context.createGain();\n volume.gain.value = sample?.gain ?? 1.0;\n\n // Release decay\n const [decay, startDecay] = createDecayEnvelope(context, sample.decayTime);\n\n const cleanup = unsubscribeAll([\n connectSerial([source, lpf, volume, decay, sample.destination]),\n sample.stop?.((sampleStop) => {\n if (\n sampleStop === undefined ||\n sampleStop.stopId === undefined ||\n sampleStop.stopId === sample.stopId\n ) {\n stop(sampleStop?.time);\n }\n }),\n ]);\n source.onended = () => {\n cleanup();\n sample.onEnded?.();\n };\n\n const startAt = sample.time || context.currentTime;\n source.start(startAt);\n\n function stop(time?: number) {\n time ??= context.currentTime;\n if (time <= startAt) {\n source.stop(time);\n } else {\n const stopAt = startDecay(time);\n source.stop(stopAt);\n }\n }\n\n if (sample.duration !== undefined) {\n stop(startAt + sample.duration);\n }\n\n return stop;\n}\n\nfunction createDecayEnvelope(\n context: BaseAudioContext,\n envelopeTime = 0.2\n): [AudioNode, (time: number) => number] {\n let stopAt = 0;\n const envelope = new GainNode(context, { gain: 1.0 });\n\n function start(time: number): number {\n if (stopAt) return stopAt;\n envelope.gain.cancelScheduledValues(time);\n const envelopeAt = time || context.currentTime;\n stopAt = envelopeAt + envelopeTime;\n envelope.gain.setValueAtTime(1.0, envelopeAt);\n envelope.gain.linearRampToValueAtTime(0, stopAt);\n\n return stopAt;\n }\n\n return [envelope, start];\n}\n","import { Channel } from \"./channel\";\nimport { AudioBuffers, loadAudioBuffer } from \"./load-audio\";\nimport { midiVelToGain } from \"./midi\";\nimport { createTrigger, Trigger } from \"./signals\";\nimport { startSample, StopSample } from \"./start-sample\";\n\n/**\n * A function that downloads audio\n */\nexport type SamplerAudioLoader = (\n context: AudioContext,\n buffers: AudioBuffers\n) => Promise<void>;\n\nexport type SamplerConfig = {\n detune: number;\n volume: number;\n velocity: number;\n decayTime?: number;\n lpfCutoffHz?: number;\n destination: AudioNode;\n\n buffers: Record<string | number, string | AudioBuffers> | SamplerAudioLoader;\n volumeToGain: (volume: number) => number;\n noteToSample: (\n note: SamplerNote,\n buffers: AudioBuffers,\n config: SamplerConfig\n ) => [string | number, number];\n};\n\nexport type SamplerNote = {\n decayTime?: number;\n detune?: number;\n duration?: number;\n lpfCutoffHz?: number;\n note: string | number;\n onEnded?: (note: SamplerNote | string | number) => void;\n stopId?: string | number;\n time?: number;\n velocity?: number;\n};\n\n/**\n * A Sampler instrument\n *\n * @private\n */\nexport class Sampler {\n public readonly output: Omit<Channel, \"input\">;\n public readonly buffers: AudioBuffers;\n #config: SamplerConfig;\n #stop: Trigger<StopSample | undefined>;\n #load: Promise<void>;\n #output: Channel;\n\n public constructor(\n public readonly context: AudioContext,\n options: Partial<SamplerConfig>\n ) {\n this.#config = {\n destination: options.destination ?? context.destination,\n detune: 0,\n volume: options.volume ?? 100,\n velocity: options.velocity ?? 100,\n buffers: options.buffers ?? {},\n volumeToGain: options.volumeToGain ?? midiVelToGain,\n noteToSample:\n options.noteToSample ?? ((note) => [note.note.toString(), 0]),\n };\n this.buffers = {};\n this.#stop = createTrigger();\n const loader =\n typeof this.#config.buffers === \"function\"\n ? this.#config.buffers\n : createAudioBuffersLoader(this.#config.buffers);\n this.#load = loader(context, this.buffers);\n this.#output = new Channel(context, this.#config);\n this.output = this.#output;\n }\n\n async loaded(): Promise<this> {\n await this.#load;\n return this;\n }\n\n start(note: SamplerNote | string | number) {\n const _note: SamplerNote = typeof note === \"object\" ? note : { note: note };\n const [sample, detune] = this.#config.noteToSample(\n _note,\n this.buffers,\n this.#config\n );\n const buffer = this.buffers[sample];\n if (!buffer) {\n console.warn(`Sample not found: '${sample}'`);\n return () => undefined;\n }\n const onEnded = _note.onEnded;\n return startSample({\n buffer,\n destination: this.#output.input,\n\n time: _note.time,\n duration: _note.duration,\n\n decayTime: _note.decayTime,\n lpfCutoffHz: _note.lpfCutoffHz,\n detune: detune + (_note.detune ?? this.#config.detune),\n gain: this.#config.volumeToGain(_note.velocity ?? this.#config.velocity),\n\n stop: this.#stop.subscribe,\n stopId: _note.stopId ?? _note.note,\n onEnded: onEnded ? () => onEnded(note) : undefined,\n });\n }\n\n stop(note?: StopSample | string | number) {\n const note_ = typeof note === \"object\" ? note : { stopId: note };\n this.#stop.trigger(note_);\n }\n}\n\nfunction createAudioBuffersLoader(\n source: Record<string | number, string | AudioBuffers>\n): SamplerAudioLoader {\n return async (context, buffers) => {\n await Promise.all([\n Object.keys(source).map(async (key) => {\n const value = source[key];\n if (value instanceof AudioBuffer) {\n buffers[key] = value;\n } else if (typeof value === \"string\") {\n const buffer = await loadAudioBuffer(context, value);\n if (buffer) buffers[key] = buffer;\n }\n }),\n ]);\n };\n}\n","export type DrumMachineInstrument = {\n baseUrl: string;\n name: string;\n samples: string[];\n sampleNames: string[];\n nameToSample: Record<string, string | undefined>;\n sampleNameVariations: Record<string, string[]>;\n};\nexport const EMPTY_INSTRUMENT: DrumMachineInstrument = {\n baseUrl: \"\",\n name: \"\",\n samples: [],\n sampleNames: [],\n nameToSample: {},\n sampleNameVariations: {},\n};\n\nexport async function fetchDrumMachineInstrument(\n url: string\n): Promise<DrumMachineInstrument> {\n const res = await fetch(url);\n const json = await res.json();\n // need to fix json\n json.baseUrl = url.replace(\"/dm.json\", \"\");\n json.sampleNames = [];\n json.nameToSample = {};\n json.sampleNameVariations = {};\n for (const sampleSrc of json.samples) {\n const sample =\n sampleSrc.indexOf(\"/\") !== -1 ? sampleSrc : sampleSrc.replace(\"-\", \"/\");\n json.nameToSample[sample] = sample;\n const [base, variation] = sample.split(\"/\");\n if (!json.sampleNames.includes(base)) {\n json.sampleNames.push(base);\n }\n json.nameToSample[base] ??= sample;\n json.sampleNameVariations[base] ??= [];\n if (variation) {\n json.sampleNameVariations[base].push(`${base}/${variation}`);\n }\n }\n\n return json;\n}\n","import {\n findFirstSupportedFormat,\n loadAudioBuffer,\n} from \"../sampler/load-audio\";\nimport { Sampler, SamplerAudioLoader } from \"../sampler/sampler\";\nimport {\n DrumMachineInstrument,\n EMPTY_INSTRUMENT,\n fetchDrumMachineInstrument,\n} from \"./dm-instrument\";\n\nexport function getDrumMachineNames() {\n return Object.keys(INSTRUMENTS);\n}\n\nconst INSTRUMENTS: Record<string, string> = {\n \"TR-808\": \"https://danigb.github.io/samples/drum-machines/TR-808/dm.json\",\n \"Casio-RZ1\":\n \"https://danigb.github.io/samples/drum-machines/Casio-RZ1/dm.json\",\n \"LM-2\": \"https://danigb.github.io/samples/drum-machines/LM-2/dm.json\",\n \"MFB-512\": \"https://danigb.github.io/samples/drum-machines/MFB-512/dm.json\",\n \"Roland CR-8000\":\n \"https://danigb.github.io/samples/drum-machines/Roland-CR-8000/dm.json\",\n};\n\nexport type DrumMachineConfig = {\n instrument: string;\n destination: AudioNode;\n\n detune: number;\n volume: number;\n velocity: number;\n decayTime?: number;\n lpfCutoffHz?: number;\n};\n\nexport class DrumMachine extends Sampler {\n #instrument = EMPTY_INSTRUMENT;\n public constructor(\n context: AudioContext,\n options: Partial<DrumMachineConfig>\n ) {\n const url = INSTRUMENTS[options.instrument ?? \"TR-808\"];\n if (!url) throw new Error(\"Invalid instrument: \" + options.instrument);\n const instrument = fetchDrumMachineInstrument(url);\n\n super(context, {\n ...options,\n buffers: drumMachineLoader(instrument),\n noteToSample: (note, buffers, config) => {\n const sample = this.#instrument.nameToSample[note.note];\n return [sample ?? \"\", 0];\n },\n });\n instrument.then((instrument) => {\n this.#instrument = instrument;\n });\n }\n\n get sampleNames(): string[] {\n return this.#instrument.sampleNames;\n }\n\n getVariations(name: string): string[] {\n return this.#instrument.sampleNameVariations[name] ?? [];\n }\n}\n\nfunction drumMachineLoader(\n instrument: Promise<DrumMachineInstrument>\n): SamplerAudioLoader {\n const format = findFirstSupportedFormat([\"ogg\", \"m4a\"]) ?? \"ogg\";\n return async (context, buffers) => {\n const dm = await instrument;\n await Promise.all(\n dm.samples.map(async (sample) => {\n const url = `${dm.baseUrl}/${sample}.${format}`;\n const sampleName =\n sample.indexOf(\"/\") !== -1 ? sample : sample.replace(\"-\", \"/\");\n const buffer = await loadAudioBuffer(context, url);\n if (buffer) buffers[sampleName] = buffer;\n })\n );\n };\n}\n","import {\n AudioBuffers,\n findFirstSupportedFormat,\n loadAudioBuffer,\n} from \"../sampler/load-audio\";\nimport { SfzInstrument } from \"./sfz-kits\";\nimport { Websfz, WebsfzGroup } from \"./websfz\";\n\nexport async function loadSfzBuffers(\n context: AudioContext,\n buffers: AudioBuffers,\n websfz: Websfz\n) {\n websfz.groups.forEach((group) => {\n const urls = getWebsfzGroupUrls(websfz, group);\n return loadAudioBuffers(context, buffers, urls);\n });\n}\n\nexport async function loadSfzInstrument(\n instrument: string | Websfz | SfzInstrument\n): Promise<Websfz> {\n const isWebsfz = (inst: any): inst is Websfz => \"global\" in inst;\n const isSfzInstrument = (inst: any): inst is SfzInstrument =>\n \"websfzUrl\" in inst;\n\n if (typeof instrument === \"string\") {\n return fetchWebSfz(instrument);\n } else if (isWebsfz(instrument)) {\n return instrument;\n } else if (isSfzInstrument(instrument)) {\n const websfz = await fetchWebSfz(instrument.websfzUrl);\n websfz.meta ??= {};\n if (instrument.name) websfz.meta.name = instrument.name;\n if (instrument.baseUrl) websfz.meta.baseUrl = instrument.baseUrl;\n if (instrument.formats) websfz.meta.formats = instrument.formats;\n return websfz;\n } else {\n throw new Error(\"Invalid instrument: \" + JSON.stringify(instrument));\n }\n}\n\n// @private\nasync function loadAudioBuffers(\n context: AudioContext,\n buffers: AudioBuffers,\n urls: Record<string, string>\n) {\n await Promise.all(\n Object.keys(urls).map(async (sampleId) => {\n if (buffers[sampleId]) return;\n\n const buffer = await loadAudioBuffer(context, urls[sampleId]);\n if (buffer) buffers[sampleId] = buffer;\n return buffers;\n })\n );\n}\n\n// @private\nasync function fetchWebSfz(url: string): Promise<Websfz> {\n try {\n const response = await fetch(url);\n const json = await response.json();\n return json as Websfz;\n } catch (error) {\n console.warn(`Can't load SFZ file ${url}`, error);\n throw new Error(`Can't load SFZ file ${url}`);\n }\n}\n\n// @private\nexport function getWebsfzGroupUrls(websfz: Websfz, group: WebsfzGroup) {\n const urls: Record<string, string> = {};\n const baseUrl = websfz.meta.baseUrl ?? \"\";\n const format = findFirstSupportedFormat(websfz.meta.formats ?? []) ?? \"ogg\";\n\n const prefix = websfz.global[\"default_path\"] ?? \"\";\n\n if (!group) return urls;\n\n return group.regions.reduce((urls, region) => {\n if (region.sample) {\n urls[region.sample] = `${baseUrl}/${prefix}${region.sample}.${format}`;\n }\n return urls;\n }, urls);\n}\n","import { Websfz, WebsfzGroup, WebsfzRegion } from \"./websfz\";\n\nfunction checkRange(value?: number, low?: number, hi?: number) {\n const isAboveLow = low === undefined || (value !== undefined && value >= low);\n const isBelowHi = hi === undefined || (value !== undefined && value <= hi);\n return isAboveLow && isBelowHi;\n}\n\nexport function findRegions(\n websfz: Websfz,\n note: { midi?: number; velocity?: number; cc64?: number }\n): [WebsfzGroup, WebsfzRegion][] {\n const regions: [WebsfzGroup, WebsfzRegion][] = [];\n for (const group of websfz.groups) {\n if (\n checkRange(note.midi, group.lokey, group.hikey) &&\n checkRange(note.velocity, group.lovel, group.hivel) &&\n checkRange(note.cc64, group.locc64, group.hicc64)\n ) {\n for (const region of group.regions) {\n if (\n checkRange(note.midi, region.lokey, region.hikey) &&\n checkRange(note.velocity, region.lovel, region.hivel) &&\n checkRange(note.cc64, group.locc64, group.hicc64)\n ) {\n regions.push([group, region]);\n }\n }\n }\n }\n return regions;\n}\n","import { Channel } from \"../sampler/channel\";\nimport { AudioBuffers } from \"../sampler/load-audio\";\nimport { midiVelToGain, toMidi } from \"../sampler/midi\";\nimport { SamplerNote } from \"../sampler/sampler\";\nimport { createTrigger, Trigger } from \"../sampler/signals\";\nimport { startSample, StopSample } from \"../sampler/start-sample\";\nimport { SfzInstrument } from \"./sfz-kits\";\nimport { loadSfzBuffers, loadSfzInstrument } from \"./sfz-load\";\nimport { findRegions } from \"./sfz-regions\";\nimport { Websfz } from \"./websfz\";\n\n/**\n * Splendid Grand Piano options\n */\nexport type SfzSamplerConfig = {\n instrument: SfzInstrument | Websfz | string;\n destination: AudioNode;\n volume: number;\n velocity: number;\n detune: number;\n decayTime: number;\n lpfCutoffHz?: number;\n};\n\nconst EMPTY_WEBSFZ: Websfz = Object.freeze({\n meta: {},\n global: {},\n groups: [],\n});\n\nexport class SfzSampler {\n public readonly output: Omit<Channel, \"input\">;\n public readonly buffers: AudioBuffers;\n #websfz: Websfz;\n #config: SfzSamplerConfig;\n #stop: Trigger<StopSample | undefined>;\n #load: Promise<void>;\n #output: Channel;\n\n constructor(\n public readonly context: AudioContext,\n options: Partial<SfzSamplerConfig> & Pick<SfzSamplerConfig, \"instrument\">\n ) {\n this.#config = {\n instrument: options.instrument,\n destination: options.destination ?? context.destination,\n detune: 0,\n volume: options.volume ?? 100,\n velocity: options.velocity ?? 100,\n decayTime: 0.3,\n };\n this.buffers = {};\n this.#stop = createTrigger();\n\n this.#websfz = EMPTY_WEBSFZ;\n this.#load = loadSfzInstrument(options.instrument).then((result) => {\n this.#websfz = Object.freeze(result);\n return loadSfzBuffers(context, this.buffers, this.#websfz);\n });\n this.#output = new Channel(context, this.#config);\n this.output = this.#output;\n }\n async loaded(): Promise<this> {\n await this.#load;\n return this;\n }\n\n start(note: SamplerNote | string | number) {\n const _note: SamplerNote = typeof note === \"object\" ? note : { note: note };\n const midi = toMidi(_note.note);\n if (midi === undefined) return () => undefined;\n\n const velocity = _note.velocity ?? this.#config.velocity;\n const regions = findRegions(this.#websfz, { midi, velocity });\n\n const stopAll = regions.map(([group, region]) => {\n let target = region.pitch_keycenter ?? region.key ?? midi;\n const detune = (midi - target) * 100;\n\n const destination = (this.output as Channel).input;\n\n let buffer = this.buffers[region.sample];\n if (!buffer) {\n console.warn(`Sample not found: ${region.sample}`);\n return () => undefined;\n }\n\n const onEnded = _note.onEnded;\n\n return startSample({\n buffer,\n destination,\n decayTime: _note.decayTime ?? this.#config.decayTime,\n detune: detune + (_note.detune ?? this.#config.detune),\n gain: midiVelToGain(_note.velocity ?? this.#config.velocity),\n time: _note.time,\n duration: _note.duration,\n stop: this.#stop.subscribe,\n stopId: _note.stopId ?? _note.note,\n onEnded: onEnded ? () => onEnded(note) : undefined,\n });\n });\n return (time?: number) => stopAll.forEach((stop) => stop(time));\n }\n\n stop(note?: StopSample | string | number) {\n const note_ = typeof note === \"object\" ? note : { stopId: note };\n this.#stop.trigger(note_);\n }\n\n disconnect() {\n this.stop();\n this.#output.disconnect();\n }\n}\n","import { AudioInsert } from \"./sampler/connect\";\nimport { Subscribe } from \"./sampler/signals\";\n\n// @private\nexport function createTremolo(\n context: AudioContext,\n depth: Subscribe<number>\n): AudioInsert {\n const input = new GainNode(context);\n const output = new GainNode(context);\n\n // force mono sources to be stereo\n input.channelCount = 2;\n input.channelCountMode = \"explicit\";\n\n const splitter = new ChannelSplitterNode(context, { numberOfOutputs: 2 });\n const ampL = new GainNode(context);\n const ampR = new GainNode(context);\n const merger = new ChannelMergerNode(context, { numberOfInputs: 2 });\n\n const lfoL = new OscillatorNode(context, {\n type: \"sine\",\n frequency: 1,\n });\n lfoL.start();\n const lfoLAmp = new GainNode(context);\n const lfoR = new OscillatorNode(context, {\n type: \"sine\",\n frequency: 1.1,\n });\n lfoR.start();\n const lfoRAmp = new GainNode(context);\n\n input.connect(splitter);\n splitter.connect(ampL, 0);\n splitter.connect(ampR, 1);\n ampL.connect(merger, 0, 0);\n ampR.connect(merger, 0, 1);\n lfoL.connect(lfoLAmp);\n lfoLAmp.connect(ampL.gain);\n lfoR.connect(lfoRAmp);\n lfoRAmp.connect(ampR.gain);\n merger.connect(output);\n\n const unsubscribe = depth((depth) => {\n lfoLAmp.gain.value = depth;\n lfoRAmp.gain.value = depth;\n });\n\n input.disconnect = () => {\n unsubscribe();\n lfoL.stop();\n lfoR.stop();\n input.disconnect(splitter);\n splitter.disconnect(ampL, 0);\n splitter.disconnect(ampR, 1);\n ampL.disconnect(merger, 0, 0);\n ampR.disconnect(merger, 0, 1);\n lfoL.disconnect(ampL);\n lfoR.disconnect(ampR);\n merger.disconnect(output);\n };\n\n return { input, output };\n}\n","import { midiVelToGain } from \"./sampler/midi\";\nimport { createControl } from \"./sampler/signals\";\nimport { SfzSampler, SfzSamplerConfig } from \"./sfz/sfz-sampler\";\nimport { createTremolo } from \"./tremolo\";\n\nexport function getElectricPianoNames() {\n return Object.keys(INSTRUMENTS);\n}\n\nconst INSTRUMENTS: Record<string, string> = {\n CP80: \"https://danigb.github.io/samples/gs-e-pianos/CP80/cp80.websfz.json\",\n PianetT:\n \"https://danigb.github.io/samples/gs-e-pianos/Pianet T/pianet-t.websfz.json\",\n WurlitzerEP200:\n \"https://danigb.github.io/samples/gs-e-pianos/Wurlitzer EP200/wurlitzer-ep200.websfz.json\",\n TX81Z:\n \"https://danigb.github.io/samples/vcsl/TX81Z/tx81z-fm-piano.websfz.json\",\n};\n\nexport class ElectricPiano extends SfzSampler {\n public readonly tremolo: Readonly<{ level: (value: number) => void }>;\n constructor(\n context: AudioContext,\n options: Partial<SfzSamplerConfig> & { instrument: string }\n ) {\n super(context, {\n ...options,\n instrument: INSTRUMENTS[options.instrument] ?? options.instrument,\n });\n const depth = createControl(0);\n this.tremolo = {\n level: (level) => depth.set(midiVelToGain(level)),\n };\n const tremolo = createTremolo(context, depth.subscribe);\n this.output.addInsert(tremolo);\n }\n}\n","import { SfzInstrument } from \"./sfz/sfz-kits\";\nimport { SfzSampler, SfzSamplerConfig } from \"./sfz/sfz-sampler\";\n\nexport function getMalletNames() {\n return Object.keys(NAME_TO_PATH) as MalletName[];\n}\n\nexport class Mallet extends SfzSampler {\n constructor(\n context: AudioContext,\n options: Partial<SfzSamplerConfig> & { instrument: string }\n ) {\n const instrument = getMallet(options.instrument);\n super(context, {\n ...options,\n instrument,\n });\n }\n}\n\nfunction getMallet(name: MalletName | string): SfzInstrument {\n if (!NAME_TO_PATH[name]) throw Error(`Mallet instrument \"${name}\" not valid`);\n return {\n name: name,\n websfzUrl: BASE_URL + NAME_TO_PATH[name] + EXT,\n };\n}\nconst BASE_URL = \"https://danigb.github.io/samples/vcsl/\";\nconst EXT = \".websfz.json\";\n\ntype MalletName = keyof typeof NAME_TO_PATH;\n\nexport const NAME_TO_PATH: Record<string, string | undefined> = {\n \"Balafon - Hard Mallet\": \"Struck Idiophones/balafon-hard-mallet\",\n \"Balafon - Keyswitch\": \"Struck Idiophones/balafon-keyswitch\",\n \"Balafon - Soft Mallet\": \"Struck Idiophones/balafon-soft-mallet\",\n \"Balafon - Traditional Mallet\":\n \"Struck Idiophones/balafon-traditional-mallet\",\n \"Tubular Bells 1\": \"Struck Idiophones/tubular-bells-1\",\n \"Tubular Bells 2\": \"Struck Idiophones/tubular-bells-2\",\n \"Vibraphone - Hard Mallets\": \"Struck Idiophones/vibraphone-hard-mallets\",\n \"Vibraphone - Keyswitch\": \"Struck Idiophones/vibraphone-keyswitch\",\n \"Vibraphone - Soft Mallets\": \"Struck Idiophones/vibraphone-soft-mallets\",\n \"Xylophone - Hard Mallets\": \"Struck Idiophones/xylophone-hard-mallets\",\n \"Xylophone - Keyswitch\": \"Struck Idiophones/xylophone-keyswitch\",\n \"Xylophone - Medium Mallets\": \"Struck Idiophones/xylophone-medium-mallets\",\n \"Xylophone - Soft Mallets\": \"Struck Idiophones/xylophone-soft-mallets\",\n} as const;\n","export const PROCESSOR = `\"use strict\";(()=>{var f=class extends AudioWorkletProcessor{_pDLength;_preDelay;_pDWrite;_lp1;_lp2;_lp3;_excPhase;_taps;_Delays;sampleRate;static get parameterDescriptors(){return[[\"preDelay\",0,0,sampleRate-1,\"k-rate\"],[\"bandwidth\",.9999,0,1,\"k-rate\"],[\"inputDiffusion1\",.75,0,1,\"k-rate\"],[\"inputDiffusion2\",.625,0,1,\"k-rate\"],[\"decay\",.5,0,1,\"k-rate\"],[\"decayDiffusion1\",.7,0,.999999,\"k-rate\"],[\"decayDiffusion2\",.5,0,.999999,\"k-rate\"],[\"damping\",.005,0,1,\"k-rate\"],[\"excursionRate\",.5,0,2,\"k-rate\"],[\"excursionDepth\",.7,0,2,\"k-rate\"],[\"wet\",1,0,1,\"k-rate\"],[\"dry\",0,0,1,\"k-rate\"]].map(e=>new Object({name:e[0],defaultValue:e[1],minValue:e[2],maxValue:e[3],automationRate:e[4]}))}constructor(e){super(),this.sampleRate=sampleRate,this._Delays=[],this._pDLength=sampleRate+(128-sampleRate%128),this._preDelay=new Float32Array(this._pDLength),this._pDWrite=0,this._lp1=0,this._lp2=0,this._lp3=0,this._excPhase=0,[.004771345,.003595309,.012734787,.009307483,.022579886,.149625349,.060481839,.1249958,.030509727,.141695508,.089244313,.106280031].forEach(a=>this.makeDelay(a,sampleRate)),this._taps=Int16Array.from([.008937872,.099929438,.064278754,.067067639,.066866033,.006283391,.035818689,.011861161,.121870905,.041262054,.08981553,.070931756,.011256342,.004065724],a=>Math.round(a*sampleRate))}makeDelay(e,a){let t=Math.round(e*a),s=2**Math.ceil(Math.log2(t));this._Delays.push([new Float32Array(s),t-1,0,s-1])}writeDelay(e,a){return this._Delays[e][0][this._Delays[e][1]]=a}readDelay(e){return this._Delays[e][0][this._Delays[e][2]]}readDelayAt(e,a){let t=this._Delays[e];return t[0][t[2]+a&t[3]]}readDelayCAt(e,a){let t=this._Delays[e],s=a-~~a,d=~~a+t[2]-1,r=t[3],D=t[0][d++&r],l=t[0][d++&r],h=t[0][d++&r],y=t[0][d&r],u=(3*(l-h)-D+y)/2,m=2*h+D-(5*l+y)/2,c=(h-D)/2;return((u*s+m)*s+c)*s+l}process(e,a,t){let s=~~t.preDelay[0],d=t.bandwidth[0],r=t.inputDiffusion1[0],D=t.inputDiffusion2[0],l=t.decay[0],h=t.decayDiffusion1[0],y=t.decayDiffusion2[0],u=1-t.damping[0],m=t.excursionRate[0]/sampleRate,c=t.excursionDepth[0]*sampleRate/1e3,w=t.wet[0]*.6,A=t.dry[0];if(e[0].length==2)for(let i=127;i>=0;i--)this._preDelay[this._pDWrite+i]=(e[0][0][i]+e[0][1][i])*.5,a[0][0][i]=e[0][0][i]*A,a[0][1][i]=e[0][1][i]*A;else if(e[0].length>0){this._preDelay.set(e[0][0],this._pDWrite);for(let i=127;i>=0;i--)a[0][0][i]=a[0][1][i]=e[0][0][i]*A}else this._preDelay.set(new Float32Array(128),this._pDWrite);let o=0;for(;o<128;){let i=0,b=0;this._lp1+=d*(this._preDelay[(this._pDLength+this._pDWrite-s+o)%this._pDLength]-this._lp1);let p=this.writeDelay(0,this._lp1-r*this.readDelay(0));p=this.writeDelay(1,r*(p-this.readDelay(1))+this.readDelay(0)),p=this.writeDelay(2,r*p+this.readDelay(1)-D*this.readDelay(2)),p=this.writeDelay(3,D*(p-this.readDelay(3))+this.readDelay(2));let k=D*p+this.readDelay(3),g=c*(1+Math.cos(this._excPhase*6.28)),x=c*(1+Math.sin(this._excPhase*6.2847)),_=this.writeDelay(4,k+l*this.readDelay(11)+h*this.readDelayCAt(4,g));this.writeDelay(5,this.readDelayCAt(4,g)-h*_),this._lp2+=u*(this.readDelay(5)-this._lp2),_=this.writeDelay(6,l*this._lp2-y*this.readDelay(6)),this.writeDelay(7,this.readDelay(6)+y*_),_=this.writeDelay(8,k+l*this.readDelay(7)+h*this.readDelayCAt(8,x)),this.writeDelay(9,this.readDelayCAt(8,x)-h*_),this._lp3+=u*(this.readDelay(9)-this._lp3),_=this.writeDelay(10,l*this._lp3-y*this.readDelay(10)),this.writeDelay(11,this.readDelay(10)+y*_),i=this.readDelayAt(9,this._taps[0])+this.readDelayAt(9,this._taps[1])-this.readDelayAt(10,this._taps[2])+this.readDelayAt(11,this._taps[3])-this.readDelayAt(5,this._taps[4])-this.readDelayAt(6,this._taps[5])-this.readDelayAt(7,this._taps[6]),b=this.readDelayAt(5,this._taps[7])+this.readDelayAt(5,this._taps[8])-this.readDelayAt(6,this._taps[9])+this.readDelayAt(7,this._taps[10])-this.readDelayAt(9,this._taps[11])-this.readDelayAt(10,this._taps[12])-this.readDelayAt(11,this._taps[13]),a[0][0][o]+=i*w,a[0][1][o]+=b*w,this._excPhase+=m,o++;for(let R=0,n=this._Delays[0];R<this._Delays.length;n=this._Delays[++R])n[1]=n[1]+1&n[3],n[2]=n[2]+1&n[3]}return this._pDWrite=(this._pDWrite+128)%this._pDLength,!0}};registerProcessor(\"DattorroReverb\",f);})();`;\n","import { PROCESSOR } from \"./processor.min\";\n\nconst PARAMS = [\n \"preDelay\",\n \"bandwidth\",\n \"inputDiffusion1\",\n \"inputDiffusion2\",\n \"decay\",\n \"decayDiffusion1\",\n \"decayDiffusion2\",\n \"damping\",\n \"excursionRate\",\n \"excursionDepth\",\n \"wet\",\n \"dry\",\n] as const;\n\nconst init = new WeakMap<AudioContext, Promise<void>>();\n\nasync function createDattorroReverbEffect(context: AudioContext) {\n let ready = init.get(context);\n if (!ready) {\n const blob = new Blob([PROCESSOR], { type: \"application/javascript\" });\n const url = URL.createObjectURL(blob);\n ready = context.audioWorklet.addModule(url);\n init.set(context, ready);\n }\n await ready;\n\n const reverb = new AudioWorkletNode(context, \"DattorroReverb\", {\n outputChannelCount: [2],\n });\n return reverb;\n}\n\nexport class Reverb {\n #effect: AudioWorkletNode | undefined;\n #ready: Promise<this>;\n public readonly input: AudioNode;\n #output: AudioNode;\n\n constructor(context: AudioContext) {\n this.input = context.createGain();\n this.#output = context.destination;\n this.#ready = createDattorroReverbEffect(context).then((reverb) => {\n this.input.connect(reverb);\n reverb.connect(this.#output);\n this.#effect = reverb;\n return this;\n });\n }\n\n get paramNames() {\n return PARAMS;\n }\n\n getParam(name: (typeof PARAMS)[number]): AudioParam | undefined {\n return this.#effect?.parameters.get(\"preDelay\");\n }\n\n get isReady(): boolean {\n return this.#effect !== undefined;\n }\n\n ready(): Promise<this> {\n return this.#ready;\n }\n\n connect(output: AudioNode) {\n if (this.#effect) {\n this.#effect.disconnect(this.#output);\n this.#effect.connect(output);\n }\n this.#output = output;\n }\n}\n","import { findFirstSupportedFormat } from \"../sampler/load-audio\";\nimport { findNearestMidi, toMidi } from \"../sampler/midi\";\nimport { Sampler, SamplerAudioLoader } from \"../sampler/sampler\";\n\nexport type SoundfontConfig = {\n kit: \"FluidR3_GM\" | \"MusyngKite\" | string;\n instrument: string;\n\n destination: AudioNode;\n\n detune: number;\n volume: number;\n velocity: number;\n decayTime?: number;\n lpfCutoffHz?: number;\n extraGain?: number;\n};\n\nexport class Soundfont extends Sampler {\n constructor(\n context: AudioContext,\n options: Partial<SoundfontConfig> & { instrument: string }\n ) {\n const url = options.instrument.startsWith(\"http\")\n ? options.instrument\n : gleitzKitUrl(options.instrument, options.kit ?? \"MusyngKite\");\n super(context, {\n destination: options.destination,\n\n detune: options.detune,\n volume: options.volume,\n velocity: options.velocity,\n decayTime: options.decayTime ?? 0.5,\n lpfCutoffHz: options.lpfCutoffHz,\n buffers: soundfontLoader(url),\n noteToSample: (note, buffers, config) => {\n let midi = toMidi(note.note);\n return midi === undefined ? [\"\", 0] : findNearestMidi(midi, buffers);\n },\n });\n\n // This is to compensate the low volume of the original samples\n const extraGain = options.extraGain ?? 5;\n const gain = new GainNode(context, { gain: extraGain });\n this.output.addInsert(gain);\n }\n}\n\nfunction soundfontLoader(url: string): SamplerAudioLoader {\n return async (context, buffers) => {\n const sourceFile = await (await fetch(url)).text();\n const json = midiJsToJson(sourceFile);\n\n const noteNames = Object.keys(json);\n await Promise.all(\n noteNames.map(async (noteName) => {\n const midi = toMidi(noteName);\n if (!midi) return;\n const audioData = base64ToArrayBuffer(\n removeBase64Prefix(json[noteName])\n );\n const buffer = await context.decodeAudioData(audioData);\n buffers[midi] = buffer;\n })\n );\n };\n}\n\n// convert a MIDI.js javascript soundfont file to json\nfunction midiJsToJson(source: string) {\n const header = source.indexOf(\"MIDI.Soundfont.\");\n if (header < 0) throw Error(\"Invalid MIDI.js Soundfont format\");\n const start = source.indexOf(\"=\", header) + 2;\n const end = source.lastIndexOf(\",\");\n return JSON.parse(source.slice(start, end) + \"}\");\n}\n\nfunction removeBase64Prefix(audioBase64: string) {\n return audioBase64.slice(audioBase64.indexOf(\",\") + 1);\n}\n\nfunction base64ToArrayBuffer(base64: string) {\n const decoded = window.atob(base64);\n const len = decoded.length;\n const bytes = new Uint8Array(len);\n for (let i = 0; i < len; i++) {\n bytes[i] = decoded.charCodeAt(i);\n }\n return bytes.buffer;\n}\n\nfunction gleitzKitUrl(name: string, kit: string) {\n const format = findFirstSupportedFormat([\"ogg\", \"mp3\"]) ?? \"mp3\";\n return `https://gleitz.github.io/midi-js-soundfonts/${kit}/${name}-${format}.js`;\n}\n\nexport function getSoundfontKits() {\n return [\"MusyngKite\", \"FluidR3_GM\"];\n}\n\nexport function getSoundfontNames() {\n return [\n \"accordion\",\n \"acoustic_bass\",\n \"acoustic_grand_piano\",\n \"acoustic_guitar_nylon\",\n \"acoustic_guitar_steel\",\n \"agogo\",\n \"alto_sax\",\n \"applause\",\n \"bagpipe\",\n \"banjo\",\n \"baritone_sax\",\n \"bassoon\",\n \"bird_tweet\",\n \"blown_bottle\",\n \"brass_section\",\n \"breath_noise\",\n \"bright_acoustic_piano\",\n \"celesta\",\n \"cello\",\n \"choir_aahs\",\n \"church_organ\",\n \"clarinet\",\n \"clavinet\",\n \"contrabass\",\n \"distortion_guitar\",\n \"drawbar_organ\",\n \"dulcimer\",\n \"electric_bass_finger\",\n \"electric_bass_pick\",\n \"electric_grand_piano\",\n \"electric_guitar_clean\",\n \"electric_guitar_jazz\",\n \"electric_guitar_muted\",\n \"electric_piano_1\",\n \"electric_piano_2\",\n \"english_horn\",\n \"fiddle\",\n \"flute\",\n \"french_horn\",\n \"fretless_bass\",\n \"fx_1_rain\",\n \"fx_2_soundtrack\",\n \"fx_3_crystal\",\n \"fx_4_atmosphere\",\n \"fx_5_brightness\",\n \"fx_6_goblins\",\n \"fx_7_echoes\",\n \"fx_8_scifi\",\n \"glockenspiel\",\n \"guitar_fret_noise\",\n \"guitar_harmonics\",\n \"gunshot\",\n \"harmonica\",\n \"harpsichord\",\n \"helicopter\",\n \"honkytonk_piano\",\n \"kalimba\",\n \"koto\",\n \"lead_1_square\",\n \"lead_2_sawtooth\",\n \"lead_3_calliope\",\n \"lead_4_chiff\",\n \"lead_5_charang\",\n \"lead_6_voice\",\n \"lead_7_fifths\",\n \"lead_8_bass__lead\",\n \"marimba\",\n \"melodic_tom\",\n \"music_box\",\n \"muted_trumpet\",\n \"oboe\",\n \"ocarina\",\n \"orchestra_hit\",\n \"orchestral_harp\",\n \"overdriven_guitar\",\n \"pad_1_new_age\",\n \"pad_2_warm\",\n \"pad_3_polysynth\",\n \"pad_4_choir\",\n \"pad_5_bowed\",\n \"pad_6_metallic\",\n \"pad_7_halo\",\n \"pad_8_sweep\",\n \"pan_flute\",\n \"percussive_organ\",\n \"piccolo\",\n \"pizzicato_strings\",\n \"recorder\",\n \"reed_organ\",\n \"reverse_cymbal\",\n \"rock_organ\",\n \"seashore\",\n \"shakuhachi\",\n \"shamisen\",\n \"shanai\",\n \"sitar\",\n \"slap_bass_1\",\n \"slap_bass_2\",\n \"soprano_sax\",\n \"steel_drums\",\n \"string_ensemble_1\",\n \"string_ensemble_2\",\n \"synth_bass_1\",\n \"synth_bass_2\",\n \"synth_brass_1\",\n \"synth_brass_2\",\n \"synth_choir\",\n \"synth_drum\",\n \"synth_strings_1\",\n \"synth_strings_2\",\n \"taiko_drum\",\n \"tango_accordion\",\n \"telephone_ring\",\n \"tenor_sax\",\n \"timpani\",\n \"tinkle_bell\",\n \"tremolo_strings\",\n \"trombone\",\n \"trumpet\",\n \"tuba\",\n \"tubular_bells\",\n \"vibraphone\",\n \"viola\",\n \"violin\",\n \"voice_oohs\",\n \"whistle\",\n \"woodblock\",\n \"xylophone\",\n ];\n}\n","import {\n AudioBuffers,\n findFirstSupportedFormat,\n loadAudioBuffer,\n} from \"./sampler/load-audio\";\nimport { toMidi } from \"./sampler/midi\";\nimport { Sampler, SamplerAudioLoader } from \"./sampler/sampler\";\n\n/**\n * Splendid Grand Piano options\n */\nexport type SplendidGrandPianoConfig = {\n baseUrl: string;\n destination: AudioNode;\n\n detune: number;\n volume: number;\n velocity: number;\n decayTime?: number;\n lpfCutoffHz?: number;\n};\n\nconst BASE_URL = \"https://danigb.github.io/samples/splendid-grand-piano\";\n\nexport class SplendidGrandPiano extends Sampler {\n constructor(\n context: AudioContext,\n options: Partial<SplendidGrandPianoConfig>\n ) {\n super(context, {\n destination: options.destination,\n\n detune: options.detune,\n volume: options.volume,\n velocity: options.velocity,\n decayTime: options.decayTime ?? 0.5,\n lpfCutoffHz: options.lpfCutoffHz,\n\n buffers: splendidGrandPianoLoader(options.baseUrl ?? BASE_URL),\n\n noteToSample: (note, buffers, config) => {\n const midi = toMidi(note.note);\n if (!midi) return [note.note, 0];\n\n const vel = note.velocity ?? config.velocity;\n const layerIdx = LAYERS.findIndex(\n (layer) => vel >= layer.vel_range[0] && vel <= layer.vel_range[1]\n );\n const layer = LAYERS[layerIdx];\n if (!layer) return [\"\", 0];\n\n return findNearestMidiInLayer(layer.name, midi, buffers);\n },\n });\n }\n}\n\nfunction findNearestMidiInLayer(\n prefix: string,\n midi: number,\n buffers: AudioBuffers\n): [string, number] {\n let i = 0;\n while (buffers[prefix + (midi + i)] === undefined && i < 128) {\n if (i > 0) i = -i;\n else i = -i + 1;\n }\n\n return i === 127 ? [prefix + midi, 0] : [prefix + (midi + i), -i * 100];\n}\n\nfunction splendidGrandPianoLoader(baseUrl: string): SamplerAudioLoader {\n const format = findFirstSupportedFormat([\"ogg\", \"m4a\"]) ?? \"ogg\";\n return async (context: AudioContext, buffers: AudioBuffers) => {\n for (const layer of LAYERS) {\n await Promise.all(\n layer.samples.map(async ([midi, name]) => {\n const url = `${baseUrl}/${name}.${format}`;\n const buffer = await loadAudioBuffer(context, url);\n if (buffer) buffers[layer.name + midi] = buffer;\n })\n );\n }\n };\n}\n\nexport const LAYERS = [\n {\n name: \"PPP\",\n vel_range: [1, 40],\n cutoff: 1000,\n samples: [\n [23, \"PP-B-1\"],\n [27, \"PP-D#0\"],\n [29, \"PP-F0\"],\n [31, \"PP-G0\"],\n [33, \"PP-A0\"],\n [35, \"PP-B0\"],\n [37, \"PP-C#1\"],\n [38, \"PP-D1\"],\n [40, \"PP-E1\"],\n [41, \"PP-F1\"],\n [43, \"PP-G1\"],\n [45, \"PP-A1\"],\n [47, \"PP-B1\"],\n [48, \"PP-C2\"],\n [50, \"PP-D2\"],\n [52, \"PP-E2\"],\n [53, \"PP-F2\"],\n [55, \"PP-G2\"],\n [56, \"PP-G#2\"],\n [57, \"PP-A2\"],\n [58, \"PP-A#2\"],\n [59, \"PP-B2\"],\n [60, \"PP-C3\"],\n [62, \"PP-D3\"],\n [64, \"PP-E3\"],\n [65, \"PP-F3\"],\n [67, \"PP-G3\"],\n [69, \"PP-A3\"],\n [71, \"PP-B3\"],\n [72, \"PP-C4\"],\n [74, \"PP-D4\"],\n [76, \"PP-E4\"],\n [77, \"PP-F4\"],\n [79, \"PP-G4\"],\n [80, \"PP-G#4\"],\n [81, \"PP-A4\"],\n [82, \"PP-A#4\"],\n [83, \"PP-B4\"],\n [85, \"PP-C#5\"],\n [86, \"PP-D5\"],\n [87, \"PP-D#5\"],\n [89, \"PP-F5\"],\n [90, \"PP-F#5\"],\n [91, \"PP-G5\"],\n [92, \"PP-G#5\"],\n [93, \"PP-A5\"],\n [94, \"PP-A#5\"],\n [95, \"PP-B5\"],\n [96, \"PP-C6\"],\n [97, \"PP-C#6\"],\n [98, \"PP-D6\"],\n [99, \"PP-D#6\"],\n [100, \"PP-E6\"],\n [101, \"PP-F6\"],\n [102, \"PP-F#6\"],\n [103, \"PP-G6\"],\n [104, \"PP-G#6\"],\n [105, \"PP-A6\"],\n [106, \"PP-A#6\"],\n [107, \"PP-B6\"],\n [108, \"PP-C7\"],\n ],\n },\n {\n name: \"PP\",\n vel_range: [41, 67],\n samples: [\n [23, \"PP-B-1\"],\n [27, \"PP-D#0\"],\n [29, \"PP-F0\"],\n [31, \"PP-G0\"],\n [33, \"PP-A0\"],\n [35, \"PP-B0\"],\n [37, \"PP-C#1\"],\n [38, \"PP-D1\"],\n [40, \"PP-E1\"],\n [41, \"PP-F1\"],\n [43, \"PP-G1\"],\n [45, \"PP-A1\"],\n [47, \"PP-B1\"],\n [48, \"PP-C2\"],\n [50, \"PP-D2\"],\n [52, \"PP-E2\"],\n [53, \"PP-F2\"],\n [55, \"PP-G2\"],\n [56, \"PP-G#2\"],\n [57, \"PP-A2\"],\n [58, \"PP-A#2\"],\n [59, \"PP-B2\"],\n [60, \"PP-C3\"],\n [62, \"PP-D3\"],\n [64, \"PP-E3\"],\n [65, \"PP-F3\"],\n [67, \"PP-G3\"],\n [69, \"PP-A3\"],\n [71, \"PP-B3\"],\n [72, \"PP-C4\"],\n [74, \"PP-D4\"],\n [76, \"PP-E4\"],\n [77, \"PP-F4\"],\n [79, \"PP-G4\"],\n [80, \"PP-G#4\"],\n [81, \"PP-A4\"],\n [82, \"PP-A#4\"],\n [83, \"PP-B4\"],\n [85, \"PP-C#5\"],\n [86, \"PP-D5\"],\n [87, \"PP-D#5\"],\n [89, \"PP-F5\"],\n [90, \"PP-F#5\"],\n [91, \"PP-G5\"],\n [92, \"PP-G#5\"],\n [93, \"PP-A5\"],\n [94, \"PP-A#5\"],\n [95, \"PP-B5\"],\n [96, \"PP-C6\"],\n [97, \"PP-C#6\"],\n [98, \"PP-D6\"],\n [99, \"PP-D#6\"],\n [100, \"PP-E6\"],\n [101, \"PP-F6\"],\n [102, \"PP-F#6\"],\n [103, \"PP-G6\"],\n [104, \"PP-G#6\"],\n [105, \"PP-A6\"],\n [106, \"PP-A#6\"],\n [107, \"PP-B6\"],\n [108, \"PP-C7\"],\n ],\n },\n {\n name: \"MP\",\n vel_range: [68, 84],\n samples: [\n [23, \"Mp-B-1\"],\n [27, \"Mp-D#0\"],\n [29, \"Mp-F0\"],\n [31, \"Mp-G0\"],\n [33, \"Mp-A0\"],\n [35, \"Mp-B0\"],\n [37, \"Mp-C#1\"],\n [38, \"Mp-D1\"],\n [40, \"Mp-E1\"],\n [41, \"Mp-F1\"],\n [43, \"Mp-G1\"],\n [45, \"Mp-A1\"],\n [47, \"Mp-B1\"],\n [48, \"Mp-C2\"],\n [50, \"Mp-D2\"],\n [52, \"Mp-E2\"],\n [53, \"Mp-F2\"],\n [55, \"Mp-G2\"],\n [56, \"Mp-G#2\"],\n [57, \"Mp-A2\"],\n [58, \"Mp-A#2\"],\n [59, \"Mp-B2\"],\n [60, \"Mp-C3\"],\n [62, \"Mp-D3\"],\n [64, \"Mp-E3\"],\n [65, \"Mp-F3\"],\n [67, \"Mp-G3\"],\n [69, \"Mp-A3\"],\n [71, \"Mp-B3\"],\n [72, \"Mp-C4\"],\n [74, \"Mp-D4\"],\n [76, \"Mp-E4\"],\n [77, \"Mp-F4\"],\n [79, \"Mp-G4\"],\n [80, \"Mp-G#4\"],\n [81, \"Mp-A4\"],\n [82, \"Mp-A#4\"],\n [83, \"Mp-B4\"],\n [85, \"Mp-C#5\"],\n [86, \"Mp-D5\"],\n [87, \"Mp-D#5\"],\n [88, \"Mp-E5\"],\n [89, \"Mp-F5\"],\n [90, \"Mp-F#5\"],\n [91, \"Mp-G5\"],\n [92, \"Mp-G#5\"],\n [93, \"Mp-A5\"],\n [94, \"Mp-A#5\"],\n [95, \"Mp-B5\"],\n [96, \"Mp-C6\"],\n [97, \"Mp-C#6\"],\n [98, \"Mp-D6\"],\n [99, \"Mp-D#6\"],\n [100, \"PP-E6\"],\n [101, \"Mp-F6\"],\n [102, \"Mp-F#6\"],\n [103, \"Mp-G6\"],\n [104, \"Mp-G#6\"],\n [105, \"Mp-A6\"],\n [106, \"Mp-A#6\"],\n [107, \"PP-B6\"],\n [108, \"PP-C7\"],\n ],\n },\n {\n name: \"MF\",\n vel_range: [85, 100],\n samples: [\n [23, \"Mf-B-1\"],\n [27, \"Mf-D#0\"],\n [29, \"Mf-F0\"],\n [31, \"Mf-G0\"],\n [33, \"Mf-A0\"],\n [35, \"Mf-B0\"],\n [37, \"Mf-C#1\"],\n [38, \"Mf-D1\"],\n [40, \"Mf-E1\"],\n [41, \"Mf-F1\"],\n [43, \"Mf-G1\"],\n [45, \"Mf-A1\"],\n [47, \"Mf-B1\"],\n [48, \"Mf-C2\"],\n [50, \"Mf-D2\"],\n [52, \"Mf-E2\"],\n [53, \"Mf-F2\"],\n [55, \"Mf-G2\"],\n [56, \"Mf-G#2\"],\n [57, \"Mf-A2\"],\n [58, \"Mf-A#2\"],\n [59, \"Mf-B2\"],\n [60, \"Mf-C3\"],\n [62, \"Mf-D3\"],\n [64, \"Mf-E3\"],\n [65, \"Mf-F3\"],\n [67, \"Mf-G3\"],\n [69, \"Mf-A3\"],\n [71, \"Mf-B3\"],\n [72, \"Mf-C4\"],\n [74, \"Mf-D4\"],\n [76, \"Mf-E4\"],\n [77, \"Mf-F4\"],\n [79, \"Mf-G4\"],\n [80, \"Mf-G#4\"],\n [81, \"Mf-A4\"],\n [82, \"Mf-A#4\"],\n [83, \"Mf-B4\"],\n [85, \"Mf-C#5\"],\n [86, \"Mf-D5\"],\n [87, \"Mf-D#5\"],\n [88, \"Mf-E5\"],\n [89, \"Mf-F5\"],\n [90, \"Mf-F#5\"],\n [91, \"Mf-G5\"],\n [92, \"Mf-G#5\"],\n [93, \"Mf-A5\"],\n [94, \"Mf-A#5\"],\n [95, \"Mf-B5\"],\n [96, \"Mf-C6\"],\n [97, \"Mf-C#6\"],\n [98, \"Mf-D6\"],\n [99, \"Mf-D#6\"],\n [100, \"Mf-E6\"],\n [101, \"Mf-F6\"],\n [102, \"Mf-F#6\"],\n [103, \"Mf-G6\"],\n [104, \"Mf-G#6\"],\n [105, \"Mf-A6\"],\n [106, \"Mf-A#6\"],\n [107, \"Mf-B6\"],\n [108, \"PP-C7\"],\n ],\n },\n {\n name: \"FF\",\n vel_range: [101, 127],\n samples: [\n [23, \"FF-B-1\"],\n [27, \"FF-D#0\"],\n [29, \"FF-F0\"],\n [31, \"FF-G0\"],\n [33, \"FF-A0\"],\n [35, \"FF-B0\"],\n [37, \"FF-C#1\"],\n [38, \"FF-D1\"],\n [40, \"FF-E1\"],\n [41, \"FF-F1\"],\n [43, \"FF-G1\"],\n [45, \"FF-A1\"],\n [47, \"FF-B1\"],\n [48, \"FF-C2\"],\n [50, \"FF-D2\"],\n [52, \"FF-E2\"],\n [53, \"FF-F2\"],\n [55, \"FF-G2\"],\n [56, \"FF-G#2\"],\n [57, \"FF-A2\"],\n [58, \"FF-A#2\"],\n [59, \"FF-B2\"],\n [60, \"FF-C3\"],\n [62, \"FF-D3\"],\n [64, \"FF-E3\"],\n [65, \"FF-F3\"],\n [67, \"FF-G3\"],\n [69, \"FF-A3\"],\n [71, \"FF-B3\"],\n [72, \"FF-C4\"],\n [74, \"FF-D4\"],\n [76, \"FF-E4\"],\n [77, \"FF-F4\"],\n [79, \"FF-G4\"],\n [80, \"FF-G#4\"],\n [81, \"FF-A4\"],\n [82, \"FF-A#4\"],\n [83, \"FF-B4\"],\n [85, \"FF-C#5\"],\n [86, \"FF-D5\"],\n [88, \"FF-E5\"],\n [89, \"FF-F5\"],\n [91, \"FF-G5\"],\n [93, \"FF-A5\"],\n [95, \"Mf-B5\"],\n [96, \"Mf-C6\"],\n [97, \"Mf-C#6\"],\n [98, \"Mf-D6\"],\n [99, \"Mf-D#6\"],\n [100, \"Mf-E6\"],\n [102, \"Mf-F#6\"],\n [103, \"Mf-G6\"],\n [104, \"Mf-G#6\"],\n [105, \"Mf-A6\"],\n [106, \"Mf-A#6\"],\n [107, \"Mf-B6\"],\n [108, \"Mf-C7\"],\n ],\n },\n];\n"],"mappings":"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IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,QAAQ;AAAA,MACb,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,QAAQ;AAAA,MACb,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,QAAQ;AAAA,MACb,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,QAAQ;AAAA,MACb,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,QAAQ;AAAA,MACb,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,QAAQ;AAAA,MACb,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,QAAQ;AAAA,MACb,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,QAAQ;AAAA,MACb,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,QAAQ;AAAA,MACb,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,QAAQ;AAAA,MACb,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,QAAQ;AAAA,MACb,CAAC,KAAK,OAAO;AAAA,MACb,CAAC,KAAK,OAAO;AAAA,MACb,CAAC,KAAK,QAAQ;AAAA,MACd,CAAC,KAAK,OAAO;AAAA,MACb,CAAC,KAAK,QAAQ;AAAA,MACd,CAAC,KAAK,OAAO;AAAA,MACb,CAAC,KAAK,QAAQ;AAAA,MACd,CAAC,KAAK,OAAO;AAAA,MACb,CAAC,KAAK,OAAO;AAAA,IACf;AAAA,EACF;AAAA,EACA;AAAA,IACE,MAAM;AAAA,IACN,WAAW,CAAC,KAAK,GAAG;AAAA,IACpB,SAAS;AAAA,MACP,CAAC,IAAI,QAAQ;AAAA,MACb,CAAC,IAAI,QAAQ;AAAA,MACb,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,QAAQ;AAAA,MACb,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,QAAQ;AAAA,MACb,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,QAAQ;AAAA,MACb,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,QAAQ;AAAA,MACb,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,QAAQ;AAAA,MACb,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,QAAQ;AAAA,MACb,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,QAAQ;AAAA,MACb,CAAC,IAAI,OAAO;AAAA,MACZ,CAAC,IAAI,QAAQ;AAAA,MACb,CAAC,KAAK,OAAO;AAAA,MACb,CAAC,KAAK,QAAQ;AAAA,MACd,CAAC,KAAK,OAAO;AAAA,MACb,CAAC,KAAK,QAAQ;AAAA,MACd,CAAC,KAAK,OAAO;AAAA,MACb,CAAC,KAAK,QAAQ;AAAA,MACd,CAAC,KAAK,OAAO;AAAA,MACb,CAAC,KAAK,OAAO;AAAA,IACf;AAAA,EACF;AACF;","names":["canPlay","volume","send","_a","instrument","urls","_config","_stop","_load","_output","_a","depth","INSTRUMENTS","_output","BASE_URL","_a","layer"]}
|