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 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, getSoundfontInstrumentNames } from "smplr";
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 getSoundfontInstrumentNames(): string[];
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, getSoundfontInstrumentNames };
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
- getSoundfontInstrumentNames: () => getSoundfontInstrumentNames
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
- source.onended = unsubscribeAll([
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: (_a = options.decayTime) != null ? _a : 0.5,
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 = (_b = options.extraGain) != null ? _b : 5;
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 = "MusyngKite") {
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 getSoundfontInstrumentNames() {
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
- getSoundfontInstrumentNames
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":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACEA,SAAsB,gBACpB,SACA,KACkC;AAAA;AAClC,UAAM,IAAI,QAAQ,MAAM,KAAK,EAAE,QAAQ,gBAAgB,IAAI;AAC3D,UAAM,WAAW,MAAM,MAAM,GAAG;AAChC,QAAI,SAAS,WAAW,KAAK;AAC3B,cAAQ;AAAA,QACN;AAAA,QACA,SAAS;AAAA,QACT;AAAA,MACF;AACA;AAAA,IACF;AACA,QAAI;AACF,YAAM,YAAY,MAAM,SAAS,YAAY;AAC7C,YAAM,SAAS,MAAM,QAAQ,gBAAgB,SAAS;AACtD,aAAO;AAAA,IACT,SAAS,OAAP;AACA,cAAQ,KAAK,wBAAwB,OAAO,GAAG;AAAA,IACjD;AAAA,EACF;AAAA;AAEO,SAAS,yBAAyB,SAAkC;AACzE,MAAI,OAAO,aAAa;AAAa,WAAO;AAE5C,QAAM,QAAQ,SAAS,cAAc,OAAO;AAC5C,WAAS,IAAI,GAAG,IAAI,QAAQ,QAAQ,KAAK;AACvC,UAAM,SAAS,QAAQ,CAAC;AACxB,UAAM,UAAU,MAAM,YAAY,SAAS,QAAQ;AACnD,QAAI,YAAY,cAAc,YAAY,SAAS;AACjD,aAAO;AAAA,IACT;AAEA,QAAI,WAAW,OAAO;AACpB,YAAMA,WAAU,MAAM,YAAY,WAAW;AAC7C,UAAIA,aAAY,cAAcA,aAAY,SAAS;AACjD,eAAO;AAAA,MACT;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;;;ACvCO,SAAS,cAAc,OAAgD;AAC5E,QAAM,SAAS,MAAM,OAAO,CAAC,MAAoC,CAAC,CAAC,CAAC;AACpE,SAAO,OAAO,CAAC,GAAG,MAAM;AACtB,UAAM,OAAO,YAAY,IAAI,EAAE,SAAS;AACxC,UAAM,QAAQ,WAAW,IAAI,EAAE,QAAQ;AACvC,SAAK,QAAQ,KAAK;AAClB,WAAO;AAAA,EACT,CAAC;AAED,SAAO,MAAM;AACX,WAAO,OAAO,CAAC,GAAG,MAAM;AACtB,YAAM,OAAO,YAAY,IAAI,EAAE,SAAS;AACxC,YAAM,QAAQ,WAAW,IAAI,EAAE,QAAQ;AACvC,WAAK,WAAW,KAAK;AACrB,aAAO;AAAA,IACT,CAAC;AAAA,EACH;AACF;;;ACtBA,SAAS,eAAe,MAAkC;AACxD,QAAM,QAAQ;AACd,QAAM,IAAI,MAAM,KAAK,IAAI;AACzB,MAAI,CAAC;AAAG;AACR,QAAM,SAAS,EAAE,CAAC,EAAE,YAAY;AAChC,MAAI,CAAC;AAAQ;AAEb,QAAM,MAAM,EAAE,CAAC;AACf,QAAM,MAAM,IAAI,CAAC,MAAM,MAAM,CAAC,IAAI,SAAS,IAAI;AAC/C,QAAM,MAAM,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI;AAE3B,QAAM,QAAQ,OAAO,WAAW,CAAC,IAAI,KAAK;AAC1C,SAAO,CAAC,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,EAAE,EAAE,IAAI,IAAI,MAAM,MAAM,MAAM;AAC1D;AAEO,SAAS,OAAO,MAAuD;AAC5E,SAAO,SAAS,SACZ,SACA,OAAO,SAAS,WAChB,OACA,eAAe,IAAI;AACzB;AAIO,SAAS,cAAc,KAAa;AACzC,SAAQ,MAAM,MAAO;AACvB;AACO,SAAS,gBACd,MACA,aACkB;AAClB,MAAI,IAAI;AACR,SAAO,YAAY,OAAO,CAAC,MAAM,UAAa,IAAI,KAAK;AACrD,QAAI,IAAI;AAAG,UAAI,CAAC;AAAA;AACX,UAAI,CAAC,IAAI;AAAA,EAChB;AAEA,SAAO,MAAM,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,GAAG,CAAC,IAAI,GAAG;AACpD;;;ACJO,SAAS,cAAiB,cAA6B;AAC5D,MAAI,UAAU;AACd,QAAM,YAAY,oBAAI,IAAiB;AAEvC,WAAS,UAAU,UAAuB;AACxC,cAAU,IAAI,QAAQ;AACtB,aAAS,OAAO;AAChB,WAAO,MAAM;AACX,gBAAU,OAAO,QAAQ;AAAA,IAC3B;AAAA,EACF;AAEA,WAAS,IAAI,OAAU;AACrB,cAAU;AACV,cAAU,QAAQ,CAAC,aAAa,SAAS,OAAO,CAAC;AAAA,EACnD;AAEA,WAAS,MAAS;AAChB,WAAO;AAAA,EACT;AACA,SAAO,EAAE,WAAW,KAAK,IAAI;AAC/B;AAEO,SAAS,gBAA+B;AAC7C,QAAM,YAAY,oBAAI,IAAiB;AAEvC,WAAS,UAAU,UAAuB;AACxC,cAAU,IAAI,QAAQ;AACtB,WAAO,MAAM;AACX,gBAAU,OAAO,QAAQ;AAAA,IAC3B;AAAA,EACF;AAEA,WAAS,QAAQ,OAAU;AACzB,cAAU,QAAQ,CAAC,aAAa,SAAS,KAAK,CAAC;AAAA,EACjD;AAEA,SAAO,EAAE,WAAW,QAAQ;AAC9B;AAEO,SAAS,eAAe,aAA6C;AAC1E,MAAI,OAAO;AACX,SAAO,MAAM;AACX,QAAI;AAAM;AACV,WAAO;AACP,gBAAY,QAAQ,CAAC,OAAO,0BAAM;AAAA,EACpC;AACF;;;AClFA;AAmBO,IAAM,UAAN,MAAc;AAAA,EAWnB,YACkB,SAChB,SACA;AAFgB;AARlB;AACA;AACA;AACA;AACA;AACA;AA5BF;AAkCI,uBAAK,UAAW,OAAO,OAAO;AAAA,MAC5B,aAAa,QAAQ;AAAA,MACrB,QAAQ;AAAA,MACR,cAAc;AAAA,OACX,QACJ;AAED,SAAK,QAAQ,IAAI,SAAS,KAAK,OAAO;AACtC,uBAAK,SAAU,IAAI,SAAS,KAAK,OAAO;AAExC,uBAAK,aAAc,cAAc;AAAA,MAC/B,KAAK;AAAA,MACL,mBAAK;AAAA,MACL,mBAAK,UAAS;AAAA,IAChB,CAAC;AAED,UAAM,SAAS,eAAc,aAAQ,WAAR,YAAkB,GAAG;AAClD,SAAK,YAAY,OAAO;AACxB,UAAM,gBAAe,aAAQ,iBAAR,YAAwB;AAC7C,uBAAK,cAAe,OAAO,UAAU,CAACC,YAAW;AAC/C,yBAAK,SAAQ,KAAK,QAAQ,aAAaA,OAAM;AAAA,IAC/C,CAAC;AAAA,EACH;AAAA,EAEA,UAAU,QAAiC;AA1D7C;AA2DI,6BAAK,cAAL,+BAAK,UAAa,CAAC;AACnB,uBAAK,UAAS,KAAK,MAAM;AACzB,uBAAK,aAAL;AACA,uBAAK,aAAc,cAAc;AAAA,MAC/B,KAAK;AAAA,MACL,GAAG,mBAAK;AAAA,MACR,mBAAK;AAAA,MACL,mBAAK,UAAS;AAAA,IAChB,CAAC;AAAA,EACH;AAAA,EAEA,UACE,MACA,QACA,UACA;AA1EJ;AA2EI,UAAM,MAAM,IAAI,SAAS,KAAK,OAAO;AACrC,QAAI,KAAK,QAAQ;AACjB,UAAM,QAAQ,WAAW,SAAS,OAAO,QAAQ;AACjD,UAAM,aAAa,cAAc,CAAC,mBAAK,UAAS,KAAK,KAAK,CAAC;AAE3D,6BAAK,YAAL,+BAAK,QAAW,CAAC;AACjB,uBAAK,QAAO,KAAK,EAAE,MAAM,KAAK,WAAW,CAAC;AAAA,EAC5C;AAAA,EAEA,WAAW,MAAc,KAAa;AApFxC;AAqFI,UAAM,QAAO,wBAAK,YAAL,mBAAa,KAAK,CAACC,UAASA,MAAK,SAAS;AACvD,QAAI,MAAM;AACR,WAAK,IAAI,KAAK,QAAQ;AAAA,IACxB,OAAO;AACL,cAAQ,KAAK,yBAAyB,IAAI;AAAA,IAC5C;AAAA,EACF;AAAA,EAEA,aAAa;AA7Ff;AA8FI,uBAAK,aAAL;AACA,uBAAK,cAAL;AACA,6BAAK,YAAL,mBAAa,QAAQ,CAAC,SAAS,KAAK,WAAW;AAC/C,uBAAK,QAAS;AAAA,EAChB;AACF;AA5EE;AACA;AACA;AACA;AACA;AACA;;;ACkBK,SAAS,YAAY,QAAqB;AA9CjD;AA+CE,QAAM,UAAU,OAAO,YAAY;AAEnC,QAAM,SAAS,QAAQ,mBAAmB;AAC1C,SAAO,SAAS,OAAO;AACvB,SAAO,OAAO,SAAQ,sCAAQ,WAAR,YAAkB;AAGxC,QAAM,MAAM,OAAO,cACf,IAAI,iBAAiB,SAAS;AAAA,IAC5B,MAAM;AAAA,IACN,WAAW,OAAO;AAAA,EACpB,CAAC,IACD;AAGJ,QAAM,SAAS,QAAQ,WAAW;AAClC,SAAO,KAAK,SAAQ,sCAAQ,SAAR,YAAgB;AAGpC,QAAM,CAAC,OAAO,UAAU,IAAI,oBAAoB,SAAS,OAAO,SAAS;AAEzE,QAAM,UAAU,eAAe;AAAA,IAC7B,cAAc,CAAC,QAAQ,KAAK,QAAQ,OAAO,OAAO,WAAW,CAAC;AAAA,KAC9D,YAAO,SAAP,gCAAc,CAAC,eAAe;AAC5B,UACE,eAAe,UACf,WAAW,WAAW,UACtB,WAAW,WAAW,OAAO,QAC7B;AACA,aAAK,yCAAY,IAAI;AAAA,MACvB;AAAA,IACF;AAAA,EACF,CAAC;AACD,SAAO,UAAU,MAAM;AAhFzB,QAAAC;AAiFI,YAAQ;AACR,KAAAA,MAAA,OAAO,YAAP,gBAAAA,IAAA;AAAA,EACF;AAEA,QAAM,UAAU,OAAO,QAAQ,QAAQ;AACvC,SAAO,MAAM,OAAO;AAEpB,WAAS,KAAK,MAAe;AAC3B,iCAAS,QAAQ;AACjB,QAAI,QAAQ,SAAS;AACnB,aAAO,KAAK,IAAI;AAAA,IAClB,OAAO;AACL,YAAM,SAAS,WAAW,IAAI;AAC9B,aAAO,KAAK,MAAM;AAAA,IACpB;AAAA,EACF;AAEA,MAAI,OAAO,aAAa,QAAW;AACjC,SAAK,UAAU,OAAO,QAAQ;AAAA,EAChC;AAEA,SAAO;AACT;AAEA,SAAS,oBACP,SACA,eAAe,KACwB;AACvC,MAAI,SAAS;AACb,QAAM,WAAW,IAAI,SAAS,SAAS,EAAE,MAAM,EAAI,CAAC;AAEpD,WAAS,MAAM,MAAsB;AACnC,QAAI;AAAQ,aAAO;AACnB,aAAS,KAAK,sBAAsB,IAAI;AACxC,UAAM,aAAa,QAAQ,QAAQ;AACnC,aAAS,aAAa;AACtB,aAAS,KAAK,eAAe,GAAK,UAAU;AAC5C,aAAS,KAAK,wBAAwB,GAAG,MAAM;AAE/C,WAAO;AAAA,EACT;AAEA,SAAO,CAAC,UAAU,KAAK;AACzB;;;AC5HA;AAgDO,IAAM,UAAN,MAAc;AAAA,EAQZ,YACW,SAChB,SACA;AAFgB;AANlB;AACA;AACA;AACA;AAtDF;AA4DI,uBAAK,SAAU;AAAA,MACb,cAAa,aAAQ,gBAAR,YAAuB,QAAQ;AAAA,MAC5C,QAAQ;AAAA,MACR,SAAQ,aAAQ,WAAR,YAAkB;AAAA,MAC1B,WAAU,aAAQ,aAAR,YAAoB;AAAA,MAC9B,UAAS,aAAQ,YAAR,YAAmB,CAAC;AAAA,MAC7B,eAAc,aAAQ,iBAAR,YAAwB;AAAA,MACtC,eACE,aAAQ,iBAAR,YAAyB,CAAC,SAAS,CAAC,KAAK,KAAK,SAAS,GAAG,CAAC;AAAA,IAC/D;AACA,SAAK,UAAU,CAAC;AAChB,uBAAK,OAAQ,cAAc;AAC3B,UAAM,SACJ,OAAO,mBAAK,SAAQ,YAAY,aAC5B,mBAAK,SAAQ,UACb,yBAAyB,mBAAK,SAAQ,OAAO;AACnD,uBAAK,OAAQ,OAAO,SAAS,KAAK,OAAO;AACzC,uBAAK,SAAU,IAAI,QAAQ,SAAS,mBAAK,QAAO;AAChD,SAAK,SAAS,mBAAK;AAAA,EACrB;AAAA,EAEM,SAAwB;AAAA;AAC5B,YAAM,mBAAK;AACX,aAAO;AAAA,IACT;AAAA;AAAA,EAEA,MAAM,MAAqC;AAtF7C;AAuFI,UAAM,QAAqB,OAAO,SAAS,WAAW,OAAO,EAAE,KAAW;AAC1E,UAAM,CAAC,QAAQ,MAAM,IAAI,mBAAK,SAAQ;AAAA,MACpC;AAAA,MACA,KAAK;AAAA,MACL,mBAAK;AAAA,IACP;AACA,UAAM,SAAS,KAAK,QAAQ,MAAM;AAClC,QAAI,CAAC,QAAQ;AACX,cAAQ,KAAK,sBAAsB,SAAS;AAC5C,aAAO,MAAM;AAAA,IACf;AACA,UAAM,UAAU,MAAM;AACtB,WAAO,YAAY;AAAA,MACjB;AAAA,MACA,aAAa,mBAAK,SAAQ;AAAA,MAE1B,MAAM,MAAM;AAAA,MACZ,UAAU,MAAM;AAAA,MAEhB,WAAW,MAAM;AAAA,MACjB,aAAa,MAAM;AAAA,MACnB,QAAQ,WAAU,WAAM,WAAN,YAAgB,mBAAK,SAAQ;AAAA,MAC/C,MAAM,mBAAK,SAAQ,cAAa,WAAM,aAAN,YAAkB,mBAAK,SAAQ,QAAQ;AAAA,MAEvE,MAAM,mBAAK,OAAM;AAAA,MACjB,SAAQ,WAAM,WAAN,YAAgB,MAAM;AAAA,MAC9B,SAAS,UAAU,MAAM,QAAQ,IAAI,IAAI;AAAA,IAC3C,CAAC;AAAA,EACH;AAAA,EAEA,KAAK,MAAqC;AACxC,UAAM,QAAQ,OAAO,SAAS,WAAW,OAAO,EAAE,QAAQ,KAAK;AAC/D,uBAAK,OAAM,QAAQ,KAAK;AAAA,EAC1B;AACF;AAtEE;AACA;AACA;AACA;AAqEF,SAAS,yBACP,QACoB;AACpB,SAAO,CAAO,SAAS,YAAY;AACjC,UAAM,QAAQ,IAAI;AAAA,MAChB,OAAO,KAAK,MAAM,EAAE,IAAI,CAAO,QAAQ;AACrC,cAAM,QAAQ,OAAO,GAAG;AACxB,YAAI,iBAAiB,aAAa;AAChC,kBAAQ,GAAG,IAAI;AAAA,QACjB,WAAW,OAAO,UAAU,UAAU;AACpC,gBAAM,SAAS,MAAM,gBAAgB,SAAS,KAAK;AACnD,cAAI;AAAQ,oBAAQ,GAAG,IAAI;AAAA,QAC7B;AAAA,MACF,EAAC;AAAA,IACH,CAAC;AAAA,EACH;AACF;;;ACnIO,IAAM,mBAA0C;AAAA,EACrD,SAAS;AAAA,EACT,MAAM;AAAA,EACN,SAAS,CAAC;AAAA,EACV,aAAa,CAAC;AAAA,EACd,cAAc,CAAC;AAAA,EACf,sBAAsB,CAAC;AACzB;AAEA,SAAsB,2BACpB,KACgC;AAAA;AAnBlC;AAoBE,UAAM,MAAM,MAAM,MAAM,GAAG;AAC3B,UAAM,OAAO,MAAM,IAAI,KAAK;AAE5B,SAAK,UAAU,IAAI,QAAQ,YAAY,EAAE;AACzC,SAAK,cAAc,CAAC;AACpB,SAAK,eAAe,CAAC;AACrB,SAAK,uBAAuB,CAAC;AAC7B,eAAW,aAAa,KAAK,SAAS;AACpC,YAAM,SACJ,UAAU,QAAQ,GAAG,MAAM,KAAK,YAAY,UAAU,QAAQ,KAAK,GAAG;AACxE,WAAK,aAAa,MAAM,IAAI;AAC5B,YAAM,CAAC,MAAM,SAAS,IAAI,OAAO,MAAM,GAAG;AAC1C,UAAI,CAAC,KAAK,YAAY,SAAS,IAAI,GAAG;AACpC,aAAK,YAAY,KAAK,IAAI;AAAA,MAC5B;AACA,uBAAK,cAAL,iCAA4B;AAC5B,uBAAK,sBAAL,iCAAoC,CAAC;AACrC,UAAI,WAAW;AACb,aAAK,qBAAqB,IAAI,EAAE,KAAK,GAAG,QAAQ,WAAW;AAAA,MAC7D;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAAA;;;AChCO,SAAS,sBAAsB;AACpC,SAAO,OAAO,KAAK,WAAW;AAChC;AAEA,IAAM,cAAsC;AAAA,EAC1C,UAAU;AAAA,EACV,aACE;AAAA,EACF,QAAQ;AAAA,EACR,WAAW;AAAA,EACX,kBACE;AACJ;AAvBA;AAoCO,IAAM,cAAN,cAA0B,QAAQ;AAAA,EAEhC,YACL,SACA,SACA;AAzCJ;AA0CI,UAAM,MAAM,aAAY,aAAQ,eAAR,YAAsB,QAAQ;AACtD,QAAI,CAAC;AAAK,YAAM,IAAI,MAAM,yBAAyB,QAAQ,UAAU;AACrE,UAAM,aAAa,2BAA2B,GAAG;AAEjD,UAAM,SAAS,iCACV,UADU;AAAA,MAEb,SAAS,kBAAkB,UAAU;AAAA,MACrC,cAAc,CAAC,MAAM,SAAS,WAAW;AACvC,cAAM,SAAS,mBAAK,aAAY,aAAa,KAAK,IAAI;AACtD,eAAO,CAAC,0BAAU,IAAI,CAAC;AAAA,MACzB;AAAA,IACF,EAAC;AAhBH,oCAAc;AAiBZ,eAAW,KAAK,CAACC,gBAAe;AAC9B,yBAAK,aAAcA;AAAA,IACrB,CAAC;AAAA,EACH;AAAA,EAEA,IAAI,cAAwB;AAC1B,WAAO,mBAAK,aAAY;AAAA,EAC1B;AAAA,EAEA,cAAc,MAAwB;AA/DxC;AAgEI,YAAO,wBAAK,aAAY,qBAAqB,IAAI,MAA1C,YAA+C,CAAC;AAAA,EACzD;AACF;AA7BE;AA+BF,SAAS,kBACP,YACoB;AAtEtB;AAuEE,QAAM,UAAS,8BAAyB,CAAC,OAAO,KAAK,CAAC,MAAvC,YAA4C;AAC3D,SAAO,CAAO,SAAS,YAAY;AACjC,UAAM,KAAK,MAAM;AACjB,UAAM,QAAQ;AAAA,MACZ,GAAG,QAAQ,IAAI,CAAO,WAAW;AAC/B,cAAM,MAAM,GAAG,GAAG,WAAW,UAAU;AACvC,cAAM,aACJ,OAAO,QAAQ,GAAG,MAAM,KAAK,SAAS,OAAO,QAAQ,KAAK,GAAG;AAC/D,cAAM,SAAS,MAAM,gBAAgB,SAAS,GAAG;AACjD,YAAI;AAAQ,kBAAQ,UAAU,IAAI;AAAA,MACpC,EAAC;AAAA,IACH;AAAA,EACF;AACF;;;AC5EA,SAAsB,eACpB,SACA,SACA,QACA;AAAA;AACA,WAAO,OAAO,QAAQ,CAAC,UAAU;AAC/B,YAAM,OAAO,mBAAmB,QAAQ,KAAK;AAC7C,aAAO,iBAAiB,SAAS,SAAS,IAAI;AAAA,IAChD,CAAC;AAAA,EACH;AAAA;AAEA,SAAsB,kBACpB,YACiB;AAAA;AArBnB;AAsBE,UAAM,WAAW,CAAC,SAA8B,YAAY;AAC5D,UAAM,kBAAkB,CAAC,SACvB,eAAe;AAEjB,QAAI,OAAO,eAAe,UAAU;AAClC,aAAO,YAAY,UAAU;AAAA,IAC/B,WAAW,SAAS,UAAU,GAAG;AAC/B,aAAO;AAAA,IACT,WAAW,gBAAgB,UAAU,GAAG;AACtC,YAAM,SAAS,MAAM,YAAY,WAAW,SAAS;AACrD,mBAAO,SAAP,mBAAO,OAAS,CAAC;AACjB,UAAI,WAAW;AAAM,eAAO,KAAK,OAAO,WAAW;AACnD,UAAI,WAAW;AAAS,eAAO,KAAK,UAAU,WAAW;AACzD,UAAI,WAAW;AAAS,eAAO,KAAK,UAAU,WAAW;AACzD,aAAO;AAAA,IACT,OAAO;AACL,YAAM,IAAI,MAAM,yBAAyB,KAAK,UAAU,UAAU,CAAC;AAAA,IACrE;AAAA,EACF;AAAA;AAGA,SAAe,iBACb,SACA,SACA,MACA;AAAA;AACA,UAAM,QAAQ;AAAA,MACZ,OAAO,KAAK,IAAI,EAAE,IAAI,CAAO,aAAa;AACxC,YAAI,QAAQ,QAAQ;AAAG;AAEvB,cAAM,SAAS,MAAM,gBAAgB,SAAS,KAAK,QAAQ,CAAC;AAC5D,YAAI;AAAQ,kBAAQ,QAAQ,IAAI;AAChC,eAAO;AAAA,MACT,EAAC;AAAA,IACH;AAAA,EACF;AAAA;AAGA,SAAe,YAAY,KAA8B;AAAA;AACvD,QAAI;AACF,YAAM,WAAW,MAAM,MAAM,GAAG;AAChC,YAAM,OAAO,MAAM,SAAS,KAAK;AACjC,aAAO;AAAA,IACT,SAAS,OAAP;AACA,cAAQ,KAAK,uBAAuB,OAAO,KAAK;AAChD,YAAM,IAAI,MAAM,uBAAuB,KAAK;AAAA,IAC9C;AAAA,EACF;AAAA;AAGO,SAAS,mBAAmB,QAAgB,OAAoB;AAxEvE;AAyEE,QAAM,OAA+B,CAAC;AACtC,QAAM,WAAU,YAAO,KAAK,YAAZ,YAAuB;AACvC,QAAM,UAAS,+BAAyB,YAAO,KAAK,YAAZ,YAAuB,CAAC,CAAC,MAAlD,YAAuD;AAEtE,QAAM,UAAS,YAAO,OAAO,cAAc,MAA5B,YAAiC;AAEhD,MAAI,CAAC;AAAO,WAAO;AAEnB,SAAO,MAAM,QAAQ,OAAO,CAACC,OAAM,WAAW;AAC5C,QAAI,OAAO,QAAQ;AACjB,MAAAA,MAAK,OAAO,MAAM,IAAI,GAAG,WAAW,SAAS,OAAO,UAAU;AAAA,IAChE;AACA,WAAOA;AAAA,EACT,GAAG,IAAI;AACT;;;ACrFA,SAAS,WAAW,OAAgB,KAAc,IAAa;AAC7D,QAAM,aAAa,QAAQ,UAAc,UAAU,UAAa,SAAS;AACzE,QAAM,YAAY,OAAO,UAAc,UAAU,UAAa,SAAS;AACvE,SAAO,cAAc;AACvB;AAEO,SAAS,YACd,QACA,MAC+B;AAC/B,QAAM,UAAyC,CAAC;AAChD,aAAW,SAAS,OAAO,QAAQ;AACjC,QACE,WAAW,KAAK,MAAM,MAAM,OAAO,MAAM,KAAK,KAC9C,WAAW,KAAK,UAAU,MAAM,OAAO,MAAM,KAAK,KAClD,WAAW,KAAK,MAAM,MAAM,QAAQ,MAAM,MAAM,GAChD;AACA,iBAAW,UAAU,MAAM,SAAS;AAClC,YACE,WAAW,KAAK,MAAM,OAAO,OAAO,OAAO,KAAK,KAChD,WAAW,KAAK,UAAU,OAAO,OAAO,OAAO,KAAK,KACpD,WAAW,KAAK,MAAM,MAAM,QAAQ,MAAM,MAAM,GAChD;AACA,kBAAQ,KAAK,CAAC,OAAO,MAAM,CAAC;AAAA,QAC9B;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;;;ACPA,IAAM,eAAuB,OAAO,OAAO;AAAA,EACzC,MAAM,CAAC;AAAA,EACP,QAAQ,CAAC;AAAA,EACT,QAAQ,CAAC;AACX,CAAC;AA5BD,aAAAC,UAAAC,QAAAC,QAAAC;AA8BO,IAAM,aAAN,MAAiB;AAAA,EAStB,YACkB,SAChB,SACA;AAFgB;AAPlB;AACA,uBAAAH,UAAA;AACA,uBAAAC,QAAA;AACA,uBAAAC,QAAA;AACA,uBAAAC,UAAA;AArCF;AA2CI,uBAAKH,UAAU;AAAA,MACb,YAAY,QAAQ;AAAA,MACpB,cAAa,aAAQ,gBAAR,YAAuB,QAAQ;AAAA,MAC5C,QAAQ;AAAA,MACR,SAAQ,aAAQ,WAAR,YAAkB;AAAA,MAC1B,WAAU,aAAQ,aAAR,YAAoB;AAAA,MAC9B,WAAW;AAAA,IACb;AACA,SAAK,UAAU,CAAC;AAChB,uBAAKC,QAAQ,cAAc;AAE3B,uBAAK,SAAU;AACf,uBAAKC,QAAQ,kBAAkB,QAAQ,UAAU,EAAE,KAAK,CAAC,WAAW;AAClE,yBAAK,SAAU,OAAO,OAAO,MAAM;AACnC,aAAO,eAAe,SAAS,KAAK,SAAS,mBAAK,QAAO;AAAA,IAC3D,CAAC;AACD,uBAAKC,UAAU,IAAI,QAAQ,SAAS,mBAAKH,SAAO;AAChD,SAAK,SAAS,mBAAKG;AAAA,EACrB;AAAA,EACM,SAAwB;AAAA;AAC5B,YAAM,mBAAKD;AACX,aAAO;AAAA,IACT;AAAA;AAAA,EAEA,MAAM,MAAqC;AAnE7C;AAoEI,UAAM,QAAqB,OAAO,SAAS,WAAW,OAAO,EAAE,KAAW;AAC1E,UAAM,OAAO,OAAO,MAAM,IAAI;AAC9B,QAAI,SAAS;AAAW,aAAO,MAAM;AAErC,UAAM,YAAW,WAAM,aAAN,YAAkB,mBAAKF,UAAQ;AAChD,UAAM,UAAU,YAAY,mBAAK,UAAS,EAAE,MAAM,SAAS,CAAC;AAE5D,UAAM,UAAU,QAAQ,IAAI,CAAC,CAAC,OAAO,MAAM,MAAM;AA3ErD,UAAAI,KAAA;AA4EM,UAAI,UAAS,MAAAA,MAAA,OAAO,oBAAP,OAAAA,MAA0B,OAAO,QAAjC,YAAwC;AACrD,YAAM,UAAU,OAAO,UAAU;AAEjC,YAAM,cAAe,KAAK,OAAmB;AAE7C,UAAI,SAAS,KAAK,QAAQ,OAAO,MAAM;AACvC,UAAI,CAAC,QAAQ;AACX,gBAAQ,KAAK,qBAAqB,OAAO,QAAQ;AACjD,eAAO,MAAM;AAAA,MACf;AAEA,YAAM,UAAU,MAAM;AAEtB,aAAO,YAAY;AAAA,QACjB;AAAA,QACA;AAAA,QACA,YAAW,WAAM,cAAN,YAAmB,mBAAKJ,UAAQ;AAAA,QAC3C,QAAQ,WAAU,WAAM,WAAN,YAAgB,mBAAKA,UAAQ;AAAA,QAC/C,MAAM,eAAc,WAAM,aAAN,YAAkB,mBAAKA,UAAQ,QAAQ;AAAA,QAC3D,MAAM,MAAM;AAAA,QACZ,UAAU,MAAM;AAAA,QAChB,MAAM,mBAAKC,QAAM;AAAA,QACjB,SAAQ,WAAM,WAAN,YAAgB,MAAM;AAAA,QAC9B,SAAS,UAAU,MAAM,QAAQ,IAAI,IAAI;AAAA,MAC3C,CAAC;AAAA,IACH,CAAC;AACD,WAAO,CAAC,SAAkB,QAAQ,QAAQ,CAAC,SAAS,KAAK,IAAI,CAAC;AAAA,EAChE;AAAA,EAEA,KAAK,MAAqC;AACxC,UAAM,QAAQ,OAAO,SAAS,WAAW,OAAO,EAAE,QAAQ,KAAK;AAC/D,uBAAKA,QAAM,QAAQ,KAAK;AAAA,EAC1B;AAAA,EAEA,aAAa;AACX,SAAK,KAAK;AACV,uBAAKE,UAAQ,WAAW;AAAA,EAC1B;AACF;AAjFE;AACAH,WAAA;AACAC,SAAA;AACAC,SAAA;AACAC,WAAA;;;ACjCK,SAAS,cACd,SACA,OACa;AACb,QAAM,QAAQ,IAAI,SAAS,OAAO;AAClC,QAAM,SAAS,IAAI,SAAS,OAAO;AAGnC,QAAM,eAAe;AACrB,QAAM,mBAAmB;AAEzB,QAAM,WAAW,IAAI,oBAAoB,SAAS,EAAE,iBAAiB,EAAE,CAAC;AACxE,QAAM,OAAO,IAAI,SAAS,OAAO;AACjC,QAAM,OAAO,IAAI,SAAS,OAAO;AACjC,QAAM,SAAS,IAAI,kBAAkB,SAAS,EAAE,gBAAgB,EAAE,CAAC;AAEnE,QAAM,OAAO,IAAI,eAAe,SAAS;AAAA,IACvC,MAAM;AAAA,IACN,WAAW;AAAA,EACb,CAAC;AACD,OAAK,MAAM;AACX,QAAM,UAAU,IAAI,SAAS,OAAO;AACpC,QAAM,OAAO,IAAI,eAAe,SAAS;AAAA,IACvC,MAAM;AAAA,IACN,WAAW;AAAA,EACb,CAAC;AACD,OAAK,MAAM;AACX,QAAM,UAAU,IAAI,SAAS,OAAO;AAEpC,QAAM,QAAQ,QAAQ;AACtB,WAAS,QAAQ,MAAM,CAAC;AACxB,WAAS,QAAQ,MAAM,CAAC;AACxB,OAAK,QAAQ,QAAQ,GAAG,CAAC;AACzB,OAAK,QAAQ,QAAQ,GAAG,CAAC;AACzB,OAAK,QAAQ,OAAO;AACpB,UAAQ,QAAQ,KAAK,IAAI;AACzB,OAAK,QAAQ,OAAO;AACpB,UAAQ,QAAQ,KAAK,IAAI;AACzB,SAAO,QAAQ,MAAM;AAErB,QAAM,cAAc,MAAM,CAACE,WAAU;AACnC,YAAQ,KAAK,QAAQA;AACrB,YAAQ,KAAK,QAAQA;AAAA,EACvB,CAAC;AAED,QAAM,aAAa,MAAM;AACvB,gBAAY;AACZ,SAAK,KAAK;AACV,SAAK,KAAK;AACV,UAAM,WAAW,QAAQ;AACzB,aAAS,WAAW,MAAM,CAAC;AAC3B,aAAS,WAAW,MAAM,CAAC;AAC3B,SAAK,WAAW,QAAQ,GAAG,CAAC;AAC5B,SAAK,WAAW,QAAQ,GAAG,CAAC;AAC5B,SAAK,WAAW,IAAI;AACpB,SAAK,WAAW,IAAI;AACpB,WAAO,WAAW,MAAM;AAAA,EAC1B;AAEA,SAAO,EAAE,OAAO,OAAO;AACzB;;;AC3DO,SAAS,wBAAwB;AACtC,SAAO,OAAO,KAAKC,YAAW;AAChC;AAEA,IAAMA,eAAsC;AAAA,EAC1C,MAAM;AAAA,EACN,SACE;AAAA,EACF,gBACE;AAAA,EACF,OACE;AACJ;AAEO,IAAM,gBAAN,cAA4B,WAAW;AAAA,EAE5C,YACE,SACA,SACA;AAxBJ;AAyBI,UAAM,SAAS,iCACV,UADU;AAAA,MAEb,aAAY,KAAAA,aAAY,QAAQ,UAAU,MAA9B,YAAmC,QAAQ;AAAA,IACzD,EAAC;AACD,UAAM,QAAQ,cAAc,CAAC;AAC7B,SAAK,UAAU;AAAA,MACb,OAAO,CAAC,UAAU,MAAM,IAAI,cAAc,KAAK,CAAC;AAAA,IAClD;AACA,UAAM,UAAU,cAAc,SAAS,MAAM,SAAS;AACtD,SAAK,OAAO,UAAU,OAAO;AAAA,EAC/B;AACF;;;ACjCO,SAAS,iBAAiB;AAC/B,SAAO,OAAO,KAAK,YAAY;AACjC;AAEO,IAAM,SAAN,cAAqB,WAAW;AAAA,EACrC,YACE,SACA,SACA;AACA,UAAM,aAAa,UAAU,QAAQ,UAAU;AAC/C,UAAM,SAAS,iCACV,UADU;AAAA,MAEb;AAAA,IACF,EAAC;AAAA,EACH;AACF;AAEA,SAAS,UAAU,MAA0C;AAC3D,MAAI,CAAC,aAAa,IAAI;AAAG,UAAM,MAAM,sBAAsB,iBAAiB;AAC5E,SAAO;AAAA,IACL;AAAA,IACA,WAAW,WAAW,aAAa,IAAI,IAAI;AAAA,EAC7C;AACF;AACA,IAAM,WAAW;AACjB,IAAM,MAAM;AAIL,IAAM,eAAmD;AAAA,EAC9D,yBAAyB;AAAA,EACzB,uBAAuB;AAAA,EACvB,yBAAyB;AAAA,EACzB,gCACE;AAAA,EACF,mBAAmB;AAAA,EACnB,mBAAmB;AAAA,EACnB,6BAA6B;AAAA,EAC7B,0BAA0B;AAAA,EAC1B,6BAA6B;AAAA,EAC7B,4BAA4B;AAAA,EAC5B,yBAAyB;AAAA,EACzB,8BAA8B;AAAA,EAC9B,4BAA4B;AAC9B;;;AC/CO,IAAM,YAAY;;;ACEzB,IAAM,SAAS;AAAA,EACb;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEA,IAAM,OAAO,oBAAI,QAAqC;AAEtD,SAAe,2BAA2B,SAAuB;AAAA;AAC/D,QAAI,QAAQ,KAAK,IAAI,OAAO;AAC5B,QAAI,CAAC,OAAO;AACV,YAAM,OAAO,IAAI,KAAK,CAAC,SAAS,GAAG,EAAE,MAAM,yBAAyB,CAAC;AACrE,YAAM,MAAM,IAAI,gBAAgB,IAAI;AACpC,cAAQ,QAAQ,aAAa,UAAU,GAAG;AAC1C,WAAK,IAAI,SAAS,KAAK;AAAA,IACzB;AACA,UAAM;AAEN,UAAM,SAAS,IAAI,iBAAiB,SAAS,kBAAkB;AAAA,MAC7D,oBAAoB,CAAC,CAAC;AAAA,IACxB,CAAC;AACD,WAAO;AAAA,EACT;AAAA;AAjCA,qBAAAC;AAmCO,IAAM,SAAN,MAAa;AAAA,EAMlB,YAAY,SAAuB;AALnC;AACA;AAEA,uBAAAA,UAAA;AAGE,SAAK,QAAQ,QAAQ,WAAW;AAChC,uBAAKA,UAAU,QAAQ;AACvB,uBAAK,QAAS,2BAA2B,OAAO,EAAE,KAAK,CAAC,WAAW;AACjE,WAAK,MAAM,QAAQ,MAAM;AACzB,aAAO,QAAQ,mBAAKA,SAAO;AAC3B,yBAAK,SAAU;AACf,aAAO;AAAA,IACT,CAAC;AAAA,EACH;AAAA,EAEA,IAAI,aAAa;AACf,WAAO;AAAA,EACT;AAAA,EAEA,SAAS,MAAuD;AAxDlE;AAyDI,YAAO,wBAAK,aAAL,mBAAc,WAAW,IAAI;AAAA,EACtC;AAAA,EAEA,IAAI,UAAmB;AACrB,WAAO,mBAAK,aAAY;AAAA,EAC1B;AAAA,EAEA,QAAuB;AACrB,WAAO,mBAAK;AAAA,EACd;AAAA,EAEA,QAAQ,QAAmB;AACzB,QAAI,mBAAK,UAAS;AAChB,yBAAK,SAAQ,WAAW,mBAAKA,SAAO;AACpC,yBAAK,SAAQ,QAAQ,MAAM;AAAA,IAC7B;AACA,uBAAKA,UAAU;AAAA,EACjB;AACF;AAvCE;AACA;AAEAA,WAAA;;;ACrBK,IAAM,YAAN,cAAwB,QAAQ;AAAA,EACrC,YACE,SACA,SACA;AAtBJ;AAuBI,UAAM,MAAM,QAAQ,WAAW,WAAW,MAAM,IAC5C,QAAQ,aACR,aAAa,QAAQ,aAAY,aAAQ,QAAR,YAAe,YAAY;AAChE,UAAM,SAAS;AAAA,MACb,aAAa,QAAQ;AAAA,MAErB,QAAQ,QAAQ;AAAA,MAChB,QAAQ,QAAQ;AAAA,MAChB,UAAU,QAAQ;AAAA,MAClB,YAAW,aAAQ,cAAR,YAAqB;AAAA,MAChC,aAAa,QAAQ;AAAA,MACrB,SAAS,gBAAgB,GAAG;AAAA,MAC5B,cAAc,CAAC,MAAM,SAAS,WAAW;AACvC,YAAI,OAAO,OAAO,KAAK,IAAI;AAC3B,eAAO,SAAS,SAAY,CAAC,IAAI,CAAC,IAAI,gBAAgB,MAAM,OAAO;AAAA,MACrE;AAAA,IACF,CAAC;AAGD,UAAM,aAAY,aAAQ,cAAR,YAAqB;AACvC,UAAM,OAAO,IAAI,SAAS,SAAS,EAAE,MAAM,UAAU,CAAC;AACtD,SAAK,OAAO,UAAU,IAAI;AAAA,EAC5B;AACF;AAEA,SAAS,gBAAgB,KAAiC;AACxD,SAAO,CAAO,SAAS,YAAY;AACjC,UAAM,aAAa,OAAO,MAAM,MAAM,GAAG,GAAG,KAAK;AACjD,UAAM,OAAO,aAAa,UAAU;AAEpC,UAAM,YAAY,OAAO,KAAK,IAAI;AAClC,UAAM,QAAQ;AAAA,MACZ,UAAU,IAAI,CAAO,aAAa;AAChC,cAAM,OAAO,OAAO,QAAQ;AAC5B,YAAI,CAAC;AAAM;AACX,cAAM,YAAY;AAAA,UAChB,mBAAmB,KAAK,QAAQ,CAAC;AAAA,QACnC;AACA,cAAM,SAAS,MAAM,QAAQ,gBAAgB,SAAS;AACtD,gBAAQ,IAAI,IAAI;AAAA,MAClB,EAAC;AAAA,IACH;AAAA,EACF;AACF;AAGA,SAAS,aAAa,QAAgB;AACpC,QAAM,SAAS,OAAO,QAAQ,iBAAiB;AAC/C,MAAI,SAAS;AAAG,UAAM,MAAM,kCAAkC;AAC9D,QAAM,QAAQ,OAAO,QAAQ,KAAK,MAAM,IAAI;AAC5C,QAAM,MAAM,OAAO,YAAY,GAAG;AAClC,SAAO,KAAK,MAAM,OAAO,MAAM,OAAO,GAAG,IAAI,GAAG;AAClD;AAEA,SAAS,mBAAmB,aAAqB;AAC/C,SAAO,YAAY,MAAM,YAAY,QAAQ,GAAG,IAAI,CAAC;AACvD;AAEA,SAAS,oBAAoB,QAAgB;AAC3C,QAAM,UAAU,OAAO,KAAK,MAAM;AAClC,QAAM,MAAM,QAAQ;AACpB,QAAM,QAAQ,IAAI,WAAW,GAAG;AAChC,WAAS,IAAI,GAAG,IAAI,KAAK,KAAK;AAC5B,UAAM,CAAC,IAAI,QAAQ,WAAW,CAAC;AAAA,EACjC;AACA,SAAO,MAAM;AACf;AAEA,SAAS,aAAa,MAAc,KAAa;AA3FjD;AA4FE,QAAM,UAAS,8BAAyB,CAAC,OAAO,KAAK,CAAC,MAAvC,YAA4C;AAC3D,SAAO,+CAA+C,OAAO,QAAQ;AACvE;AAEO,SAAS,mBAAmB;AACjC,SAAO,CAAC,cAAc,YAAY;AACpC;AAEO,SAAS,oBAAoB;AAClC,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;;;ACjNA,IAAMC,YAAW;AAEV,IAAM,qBAAN,cAAiC,QAAQ;AAAA,EAC9C,YACE,SACA,SACA;AA5BJ;AA6BI,UAAM,SAAS;AAAA,MACb,aAAa,QAAQ;AAAA,MAErB,QAAQ,QAAQ;AAAA,MAChB,QAAQ,QAAQ;AAAA,MAChB,UAAU,QAAQ;AAAA,MAClB,YAAW,aAAQ,cAAR,YAAqB;AAAA,MAChC,aAAa,QAAQ;AAAA,MAErB,SAAS,0BAAyB,aAAQ,YAAR,YAAmBA,SAAQ;AAAA,MAE7D,cAAc,CAAC,MAAM,SAAS,WAAW;AAxC/C,YAAAC;AAyCQ,cAAM,OAAO,OAAO,KAAK,IAAI;AAC7B,YAAI,CAAC;AAAM,iBAAO,CAAC,KAAK,MAAM,CAAC;AAE/B,cAAM,OAAMA,MAAA,KAAK,aAAL,OAAAA,MAAiB,OAAO;AACpC,cAAM,WAAW,OAAO;AAAA,UACtB,CAACC,WAAU,OAAOA,OAAM,UAAU,CAAC,KAAK,OAAOA,OAAM,UAAU,CAAC;AAAA,QAClE;AACA,cAAM,QAAQ,OAAO,QAAQ;AAC7B,YAAI,CAAC;AAAO,iBAAO,CAAC,IAAI,CAAC;AAEzB,eAAO,uBAAuB,MAAM,MAAM,MAAM,OAAO;AAAA,MACzD;AAAA,IACF,CAAC;AAAA,EACH;AACF;AAEA,SAAS,uBACP,QACA,MACA,SACkB;AAClB,MAAI,IAAI;AACR,SAAO,QAAQ,UAAU,OAAO,EAAE,MAAM,UAAa,IAAI,KAAK;AAC5D,QAAI,IAAI;AAAG,UAAI,CAAC;AAAA;AACX,UAAI,CAAC,IAAI;AAAA,EAChB;AAEA,SAAO,MAAM,MAAM,CAAC,SAAS,MAAM,CAAC,IAAI,CAAC,UAAU,OAAO,IAAI,CAAC,IAAI,GAAG;AACxE;AAEA,SAAS,yBAAyB,SAAqC;AAvEvE;AAwEE,QAAM,UAAS,8BAAyB,CAAC,OAAO,KAAK,CAAC,MAAvC,YAA4C;AAC3D,SAAO,CAAO,SAAuB,YAA0B;AAC7D,eAAW,SAAS,QAAQ;AAC1B,YAAM,QAAQ;AAAA,QACZ,MAAM,QAAQ,IAAI,CAAO,OAAiB,eAAjB,KAAiB,WAAjB,CAAC,MAAM,IAAI,GAAM;AACxC,gBAAM,MAAM,GAAG,WAAW,QAAQ;AAClC,gBAAM,SAAS,MAAM,gBAAgB,SAAS,GAAG;AACjD,cAAI;AAAQ,oBAAQ,MAAM,OAAO,IAAI,IAAI;AAAA,QAC3C,EAAC;AAAA,MACH;AAAA,IACF;AAAA,EACF;AACF;AAEO,IAAM,SAAS;AAAA,EACpB;AAAA,IACE,MAAM;AAAA,IACN,WAAW,CAAC,GAAG,EAAE;AAAA,IACjB,QAAQ;AAAA,IACR,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,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
- source.onended = unsubscribeAll([
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: (_a = options.decayTime) != null ? _a : 0.5,
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 = (_b = options.extraGain) != null ? _b : 5;
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 = "MusyngKite") {
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 getSoundfontInstrumentNames() {
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
- getSoundfontInstrumentNames
1490
+ getSoundfontKits,
1491
+ getSoundfontNames
1480
1492
  };
1481
1493
  //# sourceMappingURL=index.mjs.map
@@ -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":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEA,SAAsB,gBACpB,SACA,KACkC;AAAA;AAClC,UAAM,IAAI,QAAQ,MAAM,KAAK,EAAE,QAAQ,gBAAgB,IAAI;AAC3D,UAAM,WAAW,MAAM,MAAM,GAAG;AAChC,QAAI,SAAS,WAAW,KAAK;AAC3B,cAAQ;AAAA,QACN;AAAA,QACA,SAAS;AAAA,QACT;AAAA,MACF;AACA;AAAA,IACF;AACA,QAAI;AACF,YAAM,YAAY,MAAM,SAAS,YAAY;AAC7C,YAAM,SAAS,MAAM,QAAQ,gBAAgB,SAAS;AACtD,aAAO;AAAA,IACT,SAAS,OAAP;AACA,cAAQ,KAAK,wBAAwB,OAAO,GAAG;AAAA,IACjD;AAAA,EACF;AAAA;AAEO,SAAS,yBAAyB,SAAkC;AACzE,MAAI,OAAO,aAAa;AAAa,WAAO;AAE5C,QAAM,QAAQ,SAAS,cAAc,OAAO;AAC5C,WAAS,IAAI,GAAG,IAAI,QAAQ,QAAQ,KAAK;AACvC,UAAM,SAAS,QAAQ,CAAC;AACxB,UAAM,UAAU,MAAM,YAAY,SAAS,QAAQ;AACnD,QAAI,YAAY,cAAc,YAAY,SAAS;AACjD,aAAO;AAAA,IACT;AAEA,QAAI,WAAW,OAAO;AACpB,YAAMA,WAAU,MAAM,YAAY,WAAW;AAC7C,UAAIA,aAAY,cAAcA,aAAY,SAAS;AACjD,eAAO;AAAA,MACT;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;;;ACvCO,SAAS,cAAc,OAAgD;AAC5E,QAAM,SAAS,MAAM,OAAO,CAAC,MAAoC,CAAC,CAAC,CAAC;AACpE,SAAO,OAAO,CAAC,GAAG,MAAM;AACtB,UAAM,OAAO,YAAY,IAAI,EAAE,SAAS;AACxC,UAAM,QAAQ,WAAW,IAAI,EAAE,QAAQ;AACvC,SAAK,QAAQ,KAAK;AAClB,WAAO;AAAA,EACT,CAAC;AAED,SAAO,MAAM;AACX,WAAO,OAAO,CAAC,GAAG,MAAM;AACtB,YAAM,OAAO,YAAY,IAAI,EAAE,SAAS;AACxC,YAAM,QAAQ,WAAW,IAAI,EAAE,QAAQ;AACvC,WAAK,WAAW,KAAK;AACrB,aAAO;AAAA,IACT,CAAC;AAAA,EACH;AACF;;;ACtBA,SAAS,eAAe,MAAkC;AACxD,QAAM,QAAQ;AACd,QAAM,IAAI,MAAM,KAAK,IAAI;AACzB,MAAI,CAAC;AAAG;AACR,QAAM,SAAS,EAAE,CAAC,EAAE,YAAY;AAChC,MAAI,CAAC;AAAQ;AAEb,QAAM,MAAM,EAAE,CAAC;AACf,QAAM,MAAM,IAAI,CAAC,MAAM,MAAM,CAAC,IAAI,SAAS,IAAI;AAC/C,QAAM,MAAM,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI;AAE3B,QAAM,QAAQ,OAAO,WAAW,CAAC,IAAI,KAAK;AAC1C,SAAO,CAAC,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,EAAE,EAAE,IAAI,IAAI,MAAM,MAAM,MAAM;AAC1D;AAEO,SAAS,OAAO,MAAuD;AAC5E,SAAO,SAAS,SACZ,SACA,OAAO,SAAS,WAChB,OACA,eAAe,IAAI;AACzB;AAIO,SAAS,cAAc,KAAa;AACzC,SAAQ,MAAM,MAAO;AACvB;AACO,SAAS,gBACd,MACA,aACkB;AAClB,MAAI,IAAI;AACR,SAAO,YAAY,OAAO,CAAC,MAAM,UAAa,IAAI,KAAK;AACrD,QAAI,IAAI;AAAG,UAAI,CAAC;AAAA;AACX,UAAI,CAAC,IAAI;AAAA,EAChB;AAEA,SAAO,MAAM,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,GAAG,CAAC,IAAI,GAAG;AACpD;;;ACJO,SAAS,cAAiB,cAA6B;AAC5D,MAAI,UAAU;AACd,QAAM,YAAY,oBAAI,IAAiB;AAEvC,WAAS,UAAU,UAAuB;AACxC,cAAU,IAAI,QAAQ;AACtB,aAAS,OAAO;AAChB,WAAO,MAAM;AACX,gBAAU,OAAO,QAAQ;AAAA,IAC3B;AAAA,EACF;AAEA,WAAS,IAAI,OAAU;AACrB,cAAU;AACV,cAAU,QAAQ,CAAC,aAAa,SAAS,OAAO,CAAC;AAAA,EACnD;AAEA,WAAS,MAAS;AAChB,WAAO;AAAA,EACT;AACA,SAAO,EAAE,WAAW,KAAK,IAAI;AAC/B;AAEO,SAAS,gBAA+B;AAC7C,QAAM,YAAY,oBAAI,IAAiB;AAEvC,WAAS,UAAU,UAAuB;AACxC,cAAU,IAAI,QAAQ;AACtB,WAAO,MAAM;AACX,gBAAU,OAAO,QAAQ;AAAA,IAC3B;AAAA,EACF;AAEA,WAAS,QAAQ,OAAU;AACzB,cAAU,QAAQ,CAAC,aAAa,SAAS,KAAK,CAAC;AAAA,EACjD;AAEA,SAAO,EAAE,WAAW,QAAQ;AAC9B;AAEO,SAAS,eAAe,aAA6C;AAC1E,MAAI,OAAO;AACX,SAAO,MAAM;AACX,QAAI;AAAM;AACV,WAAO;AACP,gBAAY,QAAQ,CAAC,OAAO,0BAAM;AAAA,EACpC;AACF;;;AClFA;AAmBO,IAAM,UAAN,MAAc;AAAA,EAWnB,YACkB,SAChB,SACA;AAFgB;AARlB;AACA;AACA;AACA;AACA;AACA;AA5BF;AAkCI,uBAAK,UAAW,OAAO,OAAO;AAAA,MAC5B,aAAa,QAAQ;AAAA,MACrB,QAAQ;AAAA,MACR,cAAc;AAAA,OACX,QACJ;AAED,SAAK,QAAQ,IAAI,SAAS,KAAK,OAAO;AACtC,uBAAK,SAAU,IAAI,SAAS,KAAK,OAAO;AAExC,uBAAK,aAAc,cAAc;AAAA,MAC/B,KAAK;AAAA,MACL,mBAAK;AAAA,MACL,mBAAK,UAAS;AAAA,IAChB,CAAC;AAED,UAAM,SAAS,eAAc,aAAQ,WAAR,YAAkB,GAAG;AAClD,SAAK,YAAY,OAAO;AACxB,UAAM,gBAAe,aAAQ,iBAAR,YAAwB;AAC7C,uBAAK,cAAe,OAAO,UAAU,CAACC,YAAW;AAC/C,yBAAK,SAAQ,KAAK,QAAQ,aAAaA,OAAM;AAAA,IAC/C,CAAC;AAAA,EACH;AAAA,EAEA,UAAU,QAAiC;AA1D7C;AA2DI,6BAAK,cAAL,+BAAK,UAAa,CAAC;AACnB,uBAAK,UAAS,KAAK,MAAM;AACzB,uBAAK,aAAL;AACA,uBAAK,aAAc,cAAc;AAAA,MAC/B,KAAK;AAAA,MACL,GAAG,mBAAK;AAAA,MACR,mBAAK;AAAA,MACL,mBAAK,UAAS;AAAA,IAChB,CAAC;AAAA,EACH;AAAA,EAEA,UACE,MACA,QACA,UACA;AA1EJ;AA2EI,UAAM,MAAM,IAAI,SAAS,KAAK,OAAO;AACrC,QAAI,KAAK,QAAQ;AACjB,UAAM,QAAQ,WAAW,SAAS,OAAO,QAAQ;AACjD,UAAM,aAAa,cAAc,CAAC,mBAAK,UAAS,KAAK,KAAK,CAAC;AAE3D,6BAAK,YAAL,+BAAK,QAAW,CAAC;AACjB,uBAAK,QAAO,KAAK,EAAE,MAAM,KAAK,WAAW,CAAC;AAAA,EAC5C;AAAA,EAEA,WAAW,MAAc,KAAa;AApFxC;AAqFI,UAAM,QAAO,wBAAK,YAAL,mBAAa,KAAK,CAACC,UAASA,MAAK,SAAS;AACvD,QAAI,MAAM;AACR,WAAK,IAAI,KAAK,QAAQ;AAAA,IACxB,OAAO;AACL,cAAQ,KAAK,yBAAyB,IAAI;AAAA,IAC5C;AAAA,EACF;AAAA,EAEA,aAAa;AA7Ff;AA8FI,uBAAK,aAAL;AACA,uBAAK,cAAL;AACA,6BAAK,YAAL,mBAAa,QAAQ,CAAC,SAAS,KAAK,WAAW;AAC/C,uBAAK,QAAS;AAAA,EAChB;AACF;AA5EE;AACA;AACA;AACA;AACA;AACA;;;ACiBK,SAAS,YAAY,QAAqB;AA7CjD;AA8CE,QAAM,UAAU,OAAO,YAAY;AAEnC,QAAM,SAAS,QAAQ,mBAAmB;AAC1C,SAAO,SAAS,OAAO;AACvB,SAAO,OAAO,SAAQ,sCAAQ,WAAR,YAAkB;AAGxC,QAAM,MAAM,OAAO,cACf,IAAI,iBAAiB,SAAS;AAAA,IAC5B,MAAM;AAAA,IACN,WAAW,OAAO;AAAA,EACpB,CAAC,IACD;AAGJ,QAAM,SAAS,QAAQ,WAAW;AAClC,SAAO,KAAK,SAAQ,sCAAQ,SAAR,YAAgB;AAGpC,QAAM,CAAC,OAAO,UAAU,IAAI,oBAAoB,SAAS,OAAO,SAAS;AAEzE,SAAO,UAAU,eAAe;AAAA,IAC9B,cAAc,CAAC,QAAQ,KAAK,QAAQ,OAAO,OAAO,WAAW,CAAC;AAAA,KAC9D,YAAO,SAAP,gCAAc,CAAC,eAAe;AAC5B,UACE,eAAe,UACf,WAAW,WAAW,UACtB,WAAW,WAAW,OAAO,QAC7B;AACA,aAAK,yCAAY,IAAI;AAAA,MACvB;AAAA,IACF;AAAA,EACF,CAAC;AAED,QAAM,UAAU,OAAO,QAAQ,QAAQ;AACvC,SAAO,MAAM,OAAO;AAEpB,WAAS,KAAK,MAAe;AAC3B,iCAAS,QAAQ;AACjB,QAAI,QAAQ,SAAS;AACnB,aAAO,KAAK,IAAI;AAAA,IAClB,OAAO;AACL,YAAM,SAAS,WAAW,IAAI;AAC9B,aAAO,KAAK,MAAM;AAAA,IACpB;AAAA,EACF;AAEA,MAAI,OAAO,aAAa,QAAW;AACjC,SAAK,UAAU,OAAO,QAAQ;AAAA,EAChC;AAEA,SAAO;AACT;AAEA,SAAS,oBACP,SACA,eAAe,KACwB;AACvC,MAAI,SAAS;AACb,QAAM,WAAW,IAAI,SAAS,SAAS,EAAE,MAAM,EAAI,CAAC;AAEpD,WAAS,MAAM,MAAsB;AACnC,QAAI;AAAQ,aAAO;AACnB,aAAS,KAAK,sBAAsB,IAAI;AACxC,UAAM,aAAa,QAAQ,QAAQ;AACnC,aAAS,aAAa;AACtB,aAAS,KAAK,eAAe,GAAK,UAAU;AAC5C,aAAS,KAAK,wBAAwB,GAAG,MAAM;AAE/C,WAAO;AAAA,EACT;AAEA,SAAO,CAAC,UAAU,KAAK;AACzB;;;ACvHA;AA+CO,IAAM,UAAN,MAAc;AAAA,EAQZ,YACW,SAChB,SACA;AAFgB;AANlB;AACA;AACA;AACA;AArDF;AA2DI,uBAAK,SAAU;AAAA,MACb,cAAa,aAAQ,gBAAR,YAAuB,QAAQ;AAAA,MAC5C,QAAQ;AAAA,MACR,SAAQ,aAAQ,WAAR,YAAkB;AAAA,MAC1B,WAAU,aAAQ,aAAR,YAAoB;AAAA,MAC9B,UAAS,aAAQ,YAAR,YAAmB,CAAC;AAAA,MAC7B,eAAc,aAAQ,iBAAR,YAAwB;AAAA,MACtC,eACE,aAAQ,iBAAR,YAAyB,CAAC,SAAS,CAAC,KAAK,KAAK,SAAS,GAAG,CAAC;AAAA,IAC/D;AACA,SAAK,UAAU,CAAC;AAChB,uBAAK,OAAQ,cAAc;AAC3B,UAAM,SACJ,OAAO,mBAAK,SAAQ,YAAY,aAC5B,mBAAK,SAAQ,UACb,yBAAyB,mBAAK,SAAQ,OAAO;AACnD,uBAAK,OAAQ,OAAO,SAAS,KAAK,OAAO;AACzC,uBAAK,SAAU,IAAI,QAAQ,SAAS,mBAAK,QAAO;AAChD,SAAK,SAAS,mBAAK;AAAA,EACrB;AAAA,EAEM,SAAwB;AAAA;AAC5B,YAAM,mBAAK;AACX,aAAO;AAAA,IACT;AAAA;AAAA,EAEA,MAAM,MAAqC;AArF7C;AAsFI,UAAM,QAAqB,OAAO,SAAS,WAAW,OAAO,EAAE,KAAW;AAC1E,UAAM,CAAC,QAAQ,MAAM,IAAI,mBAAK,SAAQ;AAAA,MACpC;AAAA,MACA,KAAK;AAAA,MACL,mBAAK;AAAA,IACP;AACA,UAAM,SAAS,KAAK,QAAQ,MAAM;AAClC,QAAI,CAAC,QAAQ;AACX,cAAQ,KAAK,sBAAsB,SAAS;AAC5C,aAAO,MAAM;AAAA,IACf;AACA,WAAO,YAAY;AAAA,MACjB;AAAA,MACA,aAAa,mBAAK,SAAQ;AAAA,MAE1B,MAAM,MAAM;AAAA,MACZ,UAAU,MAAM;AAAA,MAEhB,WAAW,MAAM;AAAA,MACjB,aAAa,MAAM;AAAA,MACnB,QAAQ,WAAU,WAAM,WAAN,YAAgB,mBAAK,SAAQ;AAAA,MAC/C,MAAM,mBAAK,SAAQ,cAAa,WAAM,aAAN,YAAkB,mBAAK,SAAQ,QAAQ;AAAA,MAEvE,MAAM,mBAAK,OAAM;AAAA,MACjB,SAAQ,WAAM,WAAN,YAAgB,MAAM;AAAA,IAChC,CAAC;AAAA,EACH;AAAA,EAEA,KAAK,MAAqC;AACxC,UAAM,QAAQ,OAAO,SAAS,WAAW,OAAO,EAAE,QAAQ,KAAK;AAC/D,uBAAK,OAAM,QAAQ,KAAK;AAAA,EAC1B;AACF;AApEE;AACA;AACA;AACA;AAmEF,SAAS,yBACP,QACoB;AACpB,SAAO,CAAO,SAAS,YAAY;AACjC,UAAM,QAAQ,IAAI;AAAA,MAChB,OAAO,KAAK,MAAM,EAAE,IAAI,CAAO,QAAQ;AACrC,cAAM,QAAQ,OAAO,GAAG;AACxB,YAAI,iBAAiB,aAAa;AAChC,kBAAQ,GAAG,IAAI;AAAA,QACjB,WAAW,OAAO,UAAU,UAAU;AACpC,gBAAM,SAAS,MAAM,gBAAgB,SAAS,KAAK;AACnD,cAAI;AAAQ,oBAAQ,GAAG,IAAI;AAAA,QAC7B;AAAA,MACF,EAAC;AAAA,IACH,CAAC;AAAA,EACH;AACF;;;AChIO,IAAM,mBAA0C;AAAA,EACrD,SAAS;AAAA,EACT,MAAM;AAAA,EACN,SAAS,CAAC;AAAA,EACV,aAAa,CAAC;AAAA,EACd,cAAc,CAAC;AAAA,EACf,sBAAsB,CAAC;AACzB;AAEA,SAAsB,2BACpB,KACgC;AAAA;AAnBlC;AAoBE,UAAM,MAAM,MAAM,MAAM,GAAG;AAC3B,UAAM,OAAO,MAAM,IAAI,KAAK;AAE5B,SAAK,UAAU,IAAI,QAAQ,YAAY,EAAE;AACzC,SAAK,cAAc,CAAC;AACpB,SAAK,eAAe,CAAC;AACrB,SAAK,uBAAuB,CAAC;AAC7B,eAAW,aAAa,KAAK,SAAS;AACpC,YAAM,SACJ,UAAU,QAAQ,GAAG,MAAM,KAAK,YAAY,UAAU,QAAQ,KAAK,GAAG;AACxE,WAAK,aAAa,MAAM,IAAI;AAC5B,YAAM,CAAC,MAAM,SAAS,IAAI,OAAO,MAAM,GAAG;AAC1C,UAAI,CAAC,KAAK,YAAY,SAAS,IAAI,GAAG;AACpC,aAAK,YAAY,KAAK,IAAI;AAAA,MAC5B;AACA,uBAAK,cAAL,iCAA4B;AAC5B,uBAAK,sBAAL,iCAAoC,CAAC;AACrC,UAAI,WAAW;AACb,aAAK,qBAAqB,IAAI,EAAE,KAAK,GAAG,QAAQ,WAAW;AAAA,MAC7D;AAAA,IACF;AAEA,WAAO;AAAA,EACT;AAAA;;;AChCO,SAAS,sBAAsB;AACpC,SAAO,OAAO,KAAK,WAAW;AAChC;AAEA,IAAM,cAAsC;AAAA,EAC1C,UAAU;AAAA,EACV,aACE;AAAA,EACF,QAAQ;AAAA,EACR,WAAW;AAAA,EACX,kBACE;AACJ;AAvBA;AAoCO,IAAM,cAAN,cAA0B,QAAQ;AAAA,EAEhC,YACL,SACA,SACA;AAzCJ;AA0CI,UAAM,MAAM,aAAY,aAAQ,eAAR,YAAsB,QAAQ;AACtD,QAAI,CAAC;AAAK,YAAM,IAAI,MAAM,yBAAyB,QAAQ,UAAU;AACrE,UAAM,aAAa,2BAA2B,GAAG;AAEjD,UAAM,SAAS,iCACV,UADU;AAAA,MAEb,SAAS,kBAAkB,UAAU;AAAA,MACrC,cAAc,CAAC,MAAM,SAAS,WAAW;AACvC,cAAM,SAAS,mBAAK,aAAY,aAAa,KAAK,IAAI;AACtD,eAAO,CAAC,0BAAU,IAAI,CAAC;AAAA,MACzB;AAAA,IACF,EAAC;AAhBH,oCAAc;AAiBZ,eAAW,KAAK,CAACC,gBAAe;AAC9B,yBAAK,aAAcA;AAAA,IACrB,CAAC;AAAA,EACH;AAAA,EAEA,IAAI,cAAwB;AAC1B,WAAO,mBAAK,aAAY;AAAA,EAC1B;AAAA,EAEA,cAAc,MAAwB;AA/DxC;AAgEI,YAAO,wBAAK,aAAY,qBAAqB,IAAI,MAA1C,YAA+C,CAAC;AAAA,EACzD;AACF;AA7BE;AA+BF,SAAS,kBACP,YACoB;AAtEtB;AAuEE,QAAM,UAAS,8BAAyB,CAAC,OAAO,KAAK,CAAC,MAAvC,YAA4C;AAC3D,SAAO,CAAO,SAAS,YAAY;AACjC,UAAM,KAAK,MAAM;AACjB,UAAM,QAAQ;AAAA,MACZ,GAAG,QAAQ,IAAI,CAAO,WAAW;AAC/B,cAAM,MAAM,GAAG,GAAG,WAAW,UAAU;AACvC,cAAM,aACJ,OAAO,QAAQ,GAAG,MAAM,KAAK,SAAS,OAAO,QAAQ,KAAK,GAAG;AAC/D,cAAM,SAAS,MAAM,gBAAgB,SAAS,GAAG;AACjD,YAAI;AAAQ,kBAAQ,UAAU,IAAI;AAAA,MACpC,EAAC;AAAA,IACH;AAAA,EACF;AACF;;;AC5EA,SAAsB,eACpB,SACA,SACA,QACA;AAAA;AACA,WAAO,OAAO,QAAQ,CAAC,UAAU;AAC/B,YAAM,OAAO,mBAAmB,QAAQ,KAAK;AAC7C,aAAO,iBAAiB,SAAS,SAAS,IAAI;AAAA,IAChD,CAAC;AAAA,EACH;AAAA;AAEA,SAAsB,kBACpB,YACiB;AAAA;AArBnB;AAsBE,UAAM,WAAW,CAAC,SAA8B,YAAY;AAC5D,UAAM,kBAAkB,CAAC,SACvB,eAAe;AAEjB,QAAI,OAAO,eAAe,UAAU;AAClC,aAAO,YAAY,UAAU;AAAA,IAC/B,WAAW,SAAS,UAAU,GAAG;AAC/B,aAAO;AAAA,IACT,WAAW,gBAAgB,UAAU,GAAG;AACtC,YAAM,SAAS,MAAM,YAAY,WAAW,SAAS;AACrD,mBAAO,SAAP,mBAAO,OAAS,CAAC;AACjB,UAAI,WAAW;AAAM,eAAO,KAAK,OAAO,WAAW;AACnD,UAAI,WAAW;AAAS,eAAO,KAAK,UAAU,WAAW;AACzD,UAAI,WAAW;AAAS,eAAO,KAAK,UAAU,WAAW;AACzD,aAAO;AAAA,IACT,OAAO;AACL,YAAM,IAAI,MAAM,yBAAyB,KAAK,UAAU,UAAU,CAAC;AAAA,IACrE;AAAA,EACF;AAAA;AAGA,SAAe,iBACb,SACA,SACA,MACA;AAAA;AACA,UAAM,QAAQ;AAAA,MACZ,OAAO,KAAK,IAAI,EAAE,IAAI,CAAO,aAAa;AACxC,YAAI,QAAQ,QAAQ;AAAG;AAEvB,cAAM,SAAS,MAAM,gBAAgB,SAAS,KAAK,QAAQ,CAAC;AAC5D,YAAI;AAAQ,kBAAQ,QAAQ,IAAI;AAChC,eAAO;AAAA,MACT,EAAC;AAAA,IACH;AAAA,EACF;AAAA;AAGA,SAAe,YAAY,KAA8B;AAAA;AACvD,QAAI;AACF,YAAM,WAAW,MAAM,MAAM,GAAG;AAChC,YAAM,OAAO,MAAM,SAAS,KAAK;AACjC,aAAO;AAAA,IACT,SAAS,OAAP;AACA,cAAQ,KAAK,uBAAuB,OAAO,KAAK;AAChD,YAAM,IAAI,MAAM,uBAAuB,KAAK;AAAA,IAC9C;AAAA,EACF;AAAA;AAGO,SAAS,mBAAmB,QAAgB,OAAoB;AAxEvE;AAyEE,QAAM,OAA+B,CAAC;AACtC,QAAM,WAAU,YAAO,KAAK,YAAZ,YAAuB;AACvC,QAAM,UAAS,+BAAyB,YAAO,KAAK,YAAZ,YAAuB,CAAC,CAAC,MAAlD,YAAuD;AAEtE,QAAM,UAAS,YAAO,OAAO,cAAc,MAA5B,YAAiC;AAEhD,MAAI,CAAC;AAAO,WAAO;AAEnB,SAAO,MAAM,QAAQ,OAAO,CAACC,OAAM,WAAW;AAC5C,QAAI,OAAO,QAAQ;AACjB,MAAAA,MAAK,OAAO,MAAM,IAAI,GAAG,WAAW,SAAS,OAAO,UAAU;AAAA,IAChE;AACA,WAAOA;AAAA,EACT,GAAG,IAAI;AACT;;;ACrFA,SAAS,WAAW,OAAgB,KAAc,IAAa;AAC7D,QAAM,aAAa,QAAQ,UAAc,UAAU,UAAa,SAAS;AACzE,QAAM,YAAY,OAAO,UAAc,UAAU,UAAa,SAAS;AACvE,SAAO,cAAc;AACvB;AAEO,SAAS,YACd,QACA,MAC+B;AAC/B,QAAM,UAAyC,CAAC;AAChD,aAAW,SAAS,OAAO,QAAQ;AACjC,QACE,WAAW,KAAK,MAAM,MAAM,OAAO,MAAM,KAAK,KAC9C,WAAW,KAAK,UAAU,MAAM,OAAO,MAAM,KAAK,KAClD,WAAW,KAAK,MAAM,MAAM,QAAQ,MAAM,MAAM,GAChD;AACA,iBAAW,UAAU,MAAM,SAAS;AAClC,YACE,WAAW,KAAK,MAAM,OAAO,OAAO,OAAO,KAAK,KAChD,WAAW,KAAK,UAAU,OAAO,OAAO,OAAO,KAAK,KACpD,WAAW,KAAK,MAAM,MAAM,QAAQ,MAAM,MAAM,GAChD;AACA,kBAAQ,KAAK,CAAC,OAAO,MAAM,CAAC;AAAA,QAC9B;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;;;ACPA,IAAM,eAAuB,OAAO,OAAO;AAAA,EACzC,MAAM,CAAC;AAAA,EACP,QAAQ,CAAC;AAAA,EACT,QAAQ,CAAC;AACX,CAAC;AA5BD,aAAAC,UAAAC,QAAAC,QAAAC;AA8BO,IAAM,aAAN,MAAiB;AAAA,EAStB,YACkB,SAChB,SACA;AAFgB;AAPlB;AACA,uBAAAH,UAAA;AACA,uBAAAC,QAAA;AACA,uBAAAC,QAAA;AACA,uBAAAC,UAAA;AArCF;AA2CI,uBAAKH,UAAU;AAAA,MACb,YAAY,QAAQ;AAAA,MACpB,cAAa,aAAQ,gBAAR,YAAuB,QAAQ;AAAA,MAC5C,QAAQ;AAAA,MACR,SAAQ,aAAQ,WAAR,YAAkB;AAAA,MAC1B,WAAU,aAAQ,aAAR,YAAoB;AAAA,MAC9B,WAAW;AAAA,IACb;AACA,SAAK,UAAU,CAAC;AAChB,uBAAKC,QAAQ,cAAc;AAE3B,uBAAK,SAAU;AACf,uBAAKC,QAAQ,kBAAkB,QAAQ,UAAU,EAAE,KAAK,CAAC,WAAW;AAClE,yBAAK,SAAU,OAAO,OAAO,MAAM;AACnC,aAAO,eAAe,SAAS,KAAK,SAAS,mBAAK,QAAO;AAAA,IAC3D,CAAC;AACD,uBAAKC,UAAU,IAAI,QAAQ,SAAS,mBAAKH,SAAO;AAChD,SAAK,SAAS,mBAAKG;AAAA,EACrB;AAAA,EACM,SAAwB;AAAA;AAC5B,YAAM,mBAAKD;AACX,aAAO;AAAA,IACT;AAAA;AAAA,EAEA,MAAM,MAAqC;AAnE7C;AAoEI,UAAM,QAAqB,OAAO,SAAS,WAAW,OAAO,EAAE,KAAW;AAC1E,UAAM,OAAO,OAAO,MAAM,IAAI;AAC9B,QAAI,SAAS;AAAW,aAAO,MAAM;AAErC,UAAM,YAAW,WAAM,aAAN,YAAkB,mBAAKF,UAAQ;AAChD,UAAM,UAAU,YAAY,mBAAK,UAAS,EAAE,MAAM,SAAS,CAAC;AAE5D,UAAM,UAAU,QAAQ,IAAI,CAAC,CAAC,OAAO,MAAM,MAAM;AA3ErD,UAAAI,KAAA;AA4EM,UAAI,UAAS,MAAAA,MAAA,OAAO,oBAAP,OAAAA,MAA0B,OAAO,QAAjC,YAAwC;AACrD,YAAM,UAAU,OAAO,UAAU;AAEjC,YAAM,cAAe,KAAK,OAAmB;AAE7C,UAAI,SAAS,KAAK,QAAQ,OAAO,MAAM;AACvC,UAAI,CAAC,QAAQ;AACX,gBAAQ,KAAK,qBAAqB,OAAO,QAAQ;AACjD,eAAO,MAAM;AAAA,MACf;AAEA,aAAO,YAAY;AAAA,QACjB;AAAA,QACA;AAAA,QACA,YAAW,WAAM,cAAN,YAAmB,mBAAKJ,UAAQ;AAAA,QAC3C,QAAQ,WAAU,WAAM,WAAN,YAAgB,mBAAKA,UAAQ;AAAA,QAC/C,MAAM,eAAc,WAAM,aAAN,YAAkB,mBAAKA,UAAQ,QAAQ;AAAA,QAC3D,MAAM,MAAM;AAAA,QACZ,UAAU,MAAM;AAAA,QAChB,MAAM,mBAAKC,QAAM;AAAA,QACjB,SAAQ,WAAM,WAAN,YAAgB,MAAM;AAAA,MAChC,CAAC;AAAA,IACH,CAAC;AACD,WAAO,CAAC,SAAkB,QAAQ,QAAQ,CAAC,SAAS,KAAK,IAAI,CAAC;AAAA,EAChE;AAAA,EAEA,KAAK,MAAqC;AACxC,UAAM,QAAQ,OAAO,SAAS,WAAW,OAAO,EAAE,QAAQ,KAAK;AAC/D,uBAAKA,QAAM,QAAQ,KAAK;AAAA,EAC1B;AAAA,EAEA,aAAa;AACX,SAAK,KAAK;AACV,uBAAKE,UAAQ,WAAW;AAAA,EAC1B;AACF;AA9EE;AACAH,WAAA;AACAC,SAAA;AACAC,SAAA;AACAC,WAAA;;;ACjCK,SAAS,cACd,SACA,OACa;AACb,QAAM,QAAQ,IAAI,SAAS,OAAO;AAClC,QAAM,SAAS,IAAI,SAAS,OAAO;AAGnC,QAAM,eAAe;AACrB,QAAM,mBAAmB;AAEzB,QAAM,WAAW,IAAI,oBAAoB,SAAS,EAAE,iBAAiB,EAAE,CAAC;AACxE,QAAM,OAAO,IAAI,SAAS,OAAO;AACjC,QAAM,OAAO,IAAI,SAAS,OAAO;AACjC,QAAM,SAAS,IAAI,kBAAkB,SAAS,EAAE,gBAAgB,EAAE,CAAC;AAEnE,QAAM,OAAO,IAAI,eAAe,SAAS;AAAA,IACvC,MAAM;AAAA,IACN,WAAW;AAAA,EACb,CAAC;AACD,OAAK,MAAM;AACX,QAAM,UAAU,IAAI,SAAS,OAAO;AACpC,QAAM,OAAO,IAAI,eAAe,SAAS;AAAA,IACvC,MAAM;AAAA,IACN,WAAW;AAAA,EACb,CAAC;AACD,OAAK,MAAM;AACX,QAAM,UAAU,IAAI,SAAS,OAAO;AAEpC,QAAM,QAAQ,QAAQ;AACtB,WAAS,QAAQ,MAAM,CAAC;AACxB,WAAS,QAAQ,MAAM,CAAC;AACxB,OAAK,QAAQ,QAAQ,GAAG,CAAC;AACzB,OAAK,QAAQ,QAAQ,GAAG,CAAC;AACzB,OAAK,QAAQ,OAAO;AACpB,UAAQ,QAAQ,KAAK,IAAI;AACzB,OAAK,QAAQ,OAAO;AACpB,UAAQ,QAAQ,KAAK,IAAI;AACzB,SAAO,QAAQ,MAAM;AAErB,QAAM,cAAc,MAAM,CAACE,WAAU;AACnC,YAAQ,KAAK,QAAQA;AACrB,YAAQ,KAAK,QAAQA;AAAA,EACvB,CAAC;AAED,QAAM,aAAa,MAAM;AACvB,gBAAY;AACZ,SAAK,KAAK;AACV,SAAK,KAAK;AACV,UAAM,WAAW,QAAQ;AACzB,aAAS,WAAW,MAAM,CAAC;AAC3B,aAAS,WAAW,MAAM,CAAC;AAC3B,SAAK,WAAW,QAAQ,GAAG,CAAC;AAC5B,SAAK,WAAW,QAAQ,GAAG,CAAC;AAC5B,SAAK,WAAW,IAAI;AACpB,SAAK,WAAW,IAAI;AACpB,WAAO,WAAW,MAAM;AAAA,EAC1B;AAEA,SAAO,EAAE,OAAO,OAAO;AACzB;;;AC3DO,SAAS,wBAAwB;AACtC,SAAO,OAAO,KAAKC,YAAW;AAChC;AAEA,IAAMA,eAAsC;AAAA,EAC1C,MAAM;AAAA,EACN,SACE;AAAA,EACF,gBACE;AAAA,EACF,OACE;AACJ;AAEO,IAAM,gBAAN,cAA4B,WAAW;AAAA,EAE5C,YACE,SACA,SACA;AAxBJ;AAyBI,UAAM,SAAS,iCACV,UADU;AAAA,MAEb,aAAY,KAAAA,aAAY,QAAQ,UAAU,MAA9B,YAAmC,QAAQ;AAAA,IACzD,EAAC;AACD,UAAM,QAAQ,cAAc,CAAC;AAC7B,SAAK,UAAU;AAAA,MACb,OAAO,CAAC,UAAU,MAAM,IAAI,cAAc,KAAK,CAAC;AAAA,IAClD;AACA,UAAM,UAAU,cAAc,SAAS,MAAM,SAAS;AACtD,SAAK,OAAO,UAAU,OAAO;AAAA,EAC/B;AACF;;;ACjCO,SAAS,iBAAiB;AAC/B,SAAO,OAAO,KAAK,YAAY;AACjC;AAEO,IAAM,SAAN,cAAqB,WAAW;AAAA,EACrC,YACE,SACA,SACA;AACA,UAAM,aAAa,UAAU,QAAQ,UAAU;AAC/C,UAAM,SAAS,iCACV,UADU;AAAA,MAEb;AAAA,IACF,EAAC;AAAA,EACH;AACF;AAEA,SAAS,UAAU,MAA0C;AAC3D,MAAI,CAAC,aAAa,IAAI;AAAG,UAAM,MAAM,sBAAsB,iBAAiB;AAC5E,SAAO;AAAA,IACL;AAAA,IACA,WAAW,WAAW,aAAa,IAAI,IAAI;AAAA,EAC7C;AACF;AACA,IAAM,WAAW;AACjB,IAAM,MAAM;AAIL,IAAM,eAAmD;AAAA,EAC9D,yBAAyB;AAAA,EACzB,uBAAuB;AAAA,EACvB,yBAAyB;AAAA,EACzB,gCACE;AAAA,EACF,mBAAmB;AAAA,EACnB,mBAAmB;AAAA,EACnB,6BAA6B;AAAA,EAC7B,0BAA0B;AAAA,EAC1B,6BAA6B;AAAA,EAC7B,4BAA4B;AAAA,EAC5B,yBAAyB;AAAA,EACzB,8BAA8B;AAAA,EAC9B,4BAA4B;AAC9B;;;AC/CO,IAAM,YAAY;;;ACEzB,IAAM,SAAS;AAAA,EACb;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEA,IAAM,OAAO,oBAAI,QAAqC;AAEtD,SAAe,2BAA2B,SAAuB;AAAA;AAC/D,QAAI,QAAQ,KAAK,IAAI,OAAO;AAC5B,QAAI,CAAC,OAAO;AACV,YAAM,OAAO,IAAI,KAAK,CAAC,SAAS,GAAG,EAAE,MAAM,yBAAyB,CAAC;AACrE,YAAM,MAAM,IAAI,gBAAgB,IAAI;AACpC,cAAQ,QAAQ,aAAa,UAAU,GAAG;AAC1C,WAAK,IAAI,SAAS,KAAK;AAAA,IACzB;AACA,UAAM;AAEN,UAAM,SAAS,IAAI,iBAAiB,SAAS,kBAAkB;AAAA,MAC7D,oBAAoB,CAAC,CAAC;AAAA,IACxB,CAAC;AACD,WAAO;AAAA,EACT;AAAA;AAjCA,qBAAAC;AAmCO,IAAM,SAAN,MAAa;AAAA,EAMlB,YAAY,SAAuB;AALnC;AACA;AAEA,uBAAAA,UAAA;AAGE,SAAK,QAAQ,QAAQ,WAAW;AAChC,uBAAKA,UAAU,QAAQ;AACvB,uBAAK,QAAS,2BAA2B,OAAO,EAAE,KAAK,CAAC,WAAW;AACjE,WAAK,MAAM,QAAQ,MAAM;AACzB,aAAO,QAAQ,mBAAKA,SAAO;AAC3B,yBAAK,SAAU;AACf,aAAO;AAAA,IACT,CAAC;AAAA,EACH;AAAA,EAEA,IAAI,aAAa;AACf,WAAO;AAAA,EACT;AAAA,EAEA,SAAS,MAAuD;AAxDlE;AAyDI,YAAO,wBAAK,aAAL,mBAAc,WAAW,IAAI;AAAA,EACtC;AAAA,EAEA,IAAI,UAAmB;AACrB,WAAO,mBAAK,aAAY;AAAA,EAC1B;AAAA,EAEA,QAAuB;AACrB,WAAO,mBAAK;AAAA,EACd;AAAA,EAEA,QAAQ,QAAmB;AACzB,QAAI,mBAAK,UAAS;AAChB,yBAAK,SAAQ,WAAW,mBAAKA,SAAO;AACpC,yBAAK,SAAQ,QAAQ,MAAM;AAAA,IAC7B;AACA,uBAAKA,UAAU;AAAA,EACjB;AACF;AAvCE;AACA;AAEAA,WAAA;;;ACrBK,IAAM,YAAN,cAAwB,QAAQ;AAAA,EACrC,YACE,SACA,SACA;AAtBJ;AAuBI,UAAM,MAAM,QAAQ,WAAW,WAAW,MAAM,IAC5C,QAAQ,aACR,aAAa,QAAQ,YAAY,QAAQ,GAAG;AAChD,YAAQ,IAAI,WAAW,EAAE,IAAI,CAAC;AAC9B,UAAM,SAAS;AAAA,MACb,aAAa,QAAQ;AAAA,MAErB,QAAQ,QAAQ;AAAA,MAChB,QAAQ,QAAQ;AAAA,MAChB,UAAU,QAAQ;AAAA,MAClB,YAAW,aAAQ,cAAR,YAAqB;AAAA,MAChC,aAAa,QAAQ;AAAA,MACrB,SAAS,gBAAgB,GAAG;AAAA,MAC5B,cAAc,CAAC,MAAM,SAAS,WAAW;AACvC,YAAI,OAAO,OAAO,KAAK,IAAI;AAC3B,eAAO,SAAS,SAAY,CAAC,IAAI,CAAC,IAAI,gBAAgB,MAAM,OAAO;AAAA,MACrE;AAAA,IACF,CAAC;AAGD,UAAM,aAAY,aAAQ,cAAR,YAAqB;AACvC,UAAM,OAAO,IAAI,SAAS,SAAS,EAAE,MAAM,UAAU,CAAC;AACtD,SAAK,OAAO,UAAU,IAAI;AAAA,EAC5B;AACF;AAEA,SAAS,gBAAgB,KAAiC;AACxD,SAAO,CAAO,SAAS,YAAY;AACjC,UAAM,aAAa,OAAO,MAAM,MAAM,GAAG,GAAG,KAAK;AACjD,UAAM,OAAO,aAAa,UAAU;AAEpC,UAAM,YAAY,OAAO,KAAK,IAAI;AAClC,UAAM,QAAQ;AAAA,MACZ,UAAU,IAAI,CAAO,aAAa;AAChC,cAAM,OAAO,OAAO,QAAQ;AAC5B,YAAI,CAAC;AAAM;AACX,cAAM,YAAY;AAAA,UAChB,mBAAmB,KAAK,QAAQ,CAAC;AAAA,QACnC;AACA,cAAM,SAAS,MAAM,QAAQ,gBAAgB,SAAS;AACtD,gBAAQ,IAAI,IAAI;AAAA,MAClB,EAAC;AAAA,IACH;AAAA,EACF;AACF;AAGA,SAAS,aAAa,QAAgB;AACpC,QAAM,SAAS,OAAO,QAAQ,iBAAiB;AAC/C,MAAI,SAAS;AAAG,UAAM,MAAM,kCAAkC;AAC9D,QAAM,QAAQ,OAAO,QAAQ,KAAK,MAAM,IAAI;AAC5C,QAAM,MAAM,OAAO,YAAY,GAAG;AAClC,SAAO,KAAK,MAAM,OAAO,MAAM,OAAO,GAAG,IAAI,GAAG;AAClD;AAEA,SAAS,mBAAmB,aAAqB;AAC/C,SAAO,YAAY,MAAM,YAAY,QAAQ,GAAG,IAAI,CAAC;AACvD;AAEA,SAAS,oBAAoB,QAAgB;AAC3C,QAAM,UAAU,OAAO,KAAK,MAAM;AAClC,QAAM,MAAM,QAAQ;AACpB,QAAM,QAAQ,IAAI,WAAW,GAAG;AAChC,WAAS,IAAI,GAAG,IAAI,KAAK,KAAK;AAC5B,UAAM,CAAC,IAAI,QAAQ,WAAW,CAAC;AAAA,EACjC;AACA,SAAO,MAAM;AACf;AAEA,SAAS,aACP,MACA,MAAmC,cACnC;AA/FF;AAgGE,QAAM,UAAS,8BAAyB,CAAC,OAAO,KAAK,CAAC,MAAvC,YAA4C;AAC3D,SAAO,+CAA+C,OAAO,QAAQ;AACvE;AAEO,SAAS,8BAA8B;AAC5C,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;;;ACjNA,IAAMC,YAAW;AAEV,IAAM,qBAAN,cAAiC,QAAQ;AAAA,EAC9C,YACE,SACA,SACA;AA5BJ;AA6BI,UAAM,SAAS;AAAA,MACb,aAAa,QAAQ;AAAA,MAErB,QAAQ,QAAQ;AAAA,MAChB,QAAQ,QAAQ;AAAA,MAChB,UAAU,QAAQ;AAAA,MAClB,YAAW,aAAQ,cAAR,YAAqB;AAAA,MAChC,aAAa,QAAQ;AAAA,MAErB,SAAS,0BAAyB,aAAQ,YAAR,YAAmBA,SAAQ;AAAA,MAE7D,cAAc,CAAC,MAAM,SAAS,WAAW;AAxC/C,YAAAC;AAyCQ,cAAM,OAAO,OAAO,KAAK,IAAI;AAC7B,YAAI,CAAC;AAAM,iBAAO,CAAC,KAAK,MAAM,CAAC;AAE/B,cAAM,OAAMA,MAAA,KAAK,aAAL,OAAAA,MAAiB,OAAO;AACpC,cAAM,WAAW,OAAO;AAAA,UACtB,CAACC,WAAU,OAAOA,OAAM,UAAU,CAAC,KAAK,OAAOA,OAAM,UAAU,CAAC;AAAA,QAClE;AACA,cAAM,QAAQ,OAAO,QAAQ;AAC7B,YAAI,CAAC;AAAO,iBAAO,CAAC,IAAI,CAAC;AAEzB,eAAO,uBAAuB,MAAM,MAAM,MAAM,OAAO;AAAA,MACzD;AAAA,IACF,CAAC;AAAA,EACH;AACF;AAEA,SAAS,uBACP,QACA,MACA,SACkB;AAClB,MAAI,IAAI;AACR,SAAO,QAAQ,UAAU,OAAO,EAAE,MAAM,UAAa,IAAI,KAAK;AAC5D,QAAI,IAAI;AAAG,UAAI,CAAC;AAAA;AACX,UAAI,CAAC,IAAI;AAAA,EAChB;AAEA,SAAO,MAAM,MAAM,CAAC,SAAS,MAAM,CAAC,IAAI,CAAC,UAAU,OAAO,IAAI,CAAC,IAAI,GAAG;AACxE;AAEA,SAAS,yBAAyB,SAAqC;AAvEvE;AAwEE,QAAM,UAAS,8BAAyB,CAAC,OAAO,KAAK,CAAC,MAAvC,YAA4C;AAC3D,SAAO,CAAO,SAAuB,YAA0B;AAC7D,eAAW,SAAS,QAAQ;AAC1B,YAAM,QAAQ;AAAA,QACZ,MAAM,QAAQ,IAAI,CAAO,OAAiB,eAAjB,KAAiB,WAAjB,CAAC,MAAM,IAAI,GAAM;AACxC,gBAAM,MAAM,GAAG,WAAW,QAAQ;AAClC,gBAAM,SAAS,MAAM,gBAAgB,SAAS,GAAG;AACjD,cAAI;AAAQ,oBAAQ,MAAM,OAAO,IAAI,IAAI;AAAA,QAC3C,EAAC;AAAA,MACH;AAAA,IACF;AAAA,EACF;AACF;AAEO,IAAM,SAAS;AAAA,EACpB;AAAA,IACE,MAAM;AAAA,IACN,WAAW,CAAC,GAAG,EAAE;AAAA,IACjB,QAAQ;AAAA,IACR,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,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,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,IAAI,EAAE;AAAA,IAClB,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,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,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,IAAI,EAAE;AAAA,IAClB,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,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,IAAI,GAAG;AAAA,IACnB,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,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","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"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "smplr",
3
- "version": "0.4.2",
3
+ "version": "0.5.0",
4
4
  "homepage": "https://github.com/danigb/smplr#readme",
5
5
  "description": "A Sampled collection of instruments",
6
6
  "main": "dist/index.js",