smplr 0.21.0 → 0.23.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 +85 -6
- package/dist/index.d.mts +92 -49
- package/dist/index.d.ts +92 -49
- package/dist/index.js +128 -62
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +122 -55
- package/dist/index.mjs.map +1 -1
- package/package.json +8 -8
package/README.md
CHANGED
|
@@ -57,7 +57,7 @@ wav.downloadWav("arpeggio.wav");
|
|
|
57
57
|
|
|
58
58
|
See demo: https://danigb.github.io/smplr/
|
|
59
59
|
|
|
60
|
-
`smplr` is approaching 1.0. The 0.
|
|
60
|
+
`smplr` is approaching 1.0. The 0.22.0 release lands the final batch of pre-1.0 API work — every documented `new X(ctx, opts)` keeps working, and the documented surface is intended to ship unchanged into 1.0. The formal stability commitment lands once the narrow `loader`/`scheduler` public interfaces sibling ticket is in (see [CHANGELOG](https://github.com/danigb/smplr/blob/main/CHANGELOG.md)).
|
|
61
61
|
|
|
62
62
|
> **Upgrading from an earlier 0.x?** No code changes are required — every documented `new X(ctx, opts)` keeps working. New code should drop the `new` (`X(ctx, opts)`) and prefer `await x.ready` over `await x.load`.
|
|
63
63
|
|
|
@@ -254,7 +254,7 @@ Or stop the specified one. The argument is a `stopId` — by default the same va
|
|
|
254
254
|
|
|
255
255
|
```js
|
|
256
256
|
piano.stop("C4"); // stop the note(s) started with `note: "C4"`
|
|
257
|
-
piano.stop(60);
|
|
257
|
+
piano.stop(60); // stop the note(s) started with `note: 60`
|
|
258
258
|
```
|
|
259
259
|
|
|
260
260
|
#### Schedule notes
|
|
@@ -291,14 +291,42 @@ If `loop` is true but `loopStart` or `loopEnd` are not specified, 0 and total du
|
|
|
291
291
|
|
|
292
292
|
#### Change volume
|
|
293
293
|
|
|
294
|
-
Instrument `output` attribute represents the main output of the instrument. `output.
|
|
294
|
+
Instrument `output` attribute represents the main output of the instrument. The `output.volume` getter/setter accepts a number where 0 means no volume, and 127 is max volume without amplification:
|
|
295
295
|
|
|
296
296
|
```js
|
|
297
|
-
piano.output.
|
|
297
|
+
piano.output.volume = 80;
|
|
298
|
+
piano.output.volume; // => 80
|
|
298
299
|
```
|
|
299
300
|
|
|
301
|
+
`output.setVolume(n)` is kept as a deprecated alias and continues to work.
|
|
302
|
+
|
|
300
303
|
⚠️ `volume` is global to the instrument, but `velocity` is specific for each note.
|
|
301
304
|
|
|
305
|
+
#### MIDI CC
|
|
306
|
+
|
|
307
|
+
Set and read MIDI Control Change values on the instrument:
|
|
308
|
+
|
|
309
|
+
```js
|
|
310
|
+
piano.setCC(64, 127); // sustain pedal on
|
|
311
|
+
piano.getCC(64); // => 127
|
|
312
|
+
piano.setCC(64, 0); // sustain pedal off
|
|
313
|
+
```
|
|
314
|
+
|
|
315
|
+
Unset CCs default to `0` (matches MIDI's "undefined controller defaults to 0" convention).
|
|
316
|
+
|
|
317
|
+
#### Disposing
|
|
318
|
+
|
|
319
|
+
When you're done with an instrument, call `dispose()` to stop all voices, tear down the audio graph, and stop the scheduler. The instance must not be used after this call.
|
|
320
|
+
|
|
321
|
+
```js
|
|
322
|
+
useEffect(() => {
|
|
323
|
+
const piano = SplendidGrandPiano(context);
|
|
324
|
+
return () => piano.dispose();
|
|
325
|
+
}, []);
|
|
326
|
+
```
|
|
327
|
+
|
|
328
|
+
`disconnect()` is kept as a deprecated alias and continues to work.
|
|
329
|
+
|
|
302
330
|
#### Events
|
|
303
331
|
|
|
304
332
|
Two events are supported `onStart` and `onEnded`. Both callbacks will receive as parameter started note.
|
|
@@ -345,12 +373,14 @@ const piano = SplendidGrandPiano(context, { volume });
|
|
|
345
373
|
piano.output.addEffect("reverb", reverb, 0.2);
|
|
346
374
|
```
|
|
347
375
|
|
|
348
|
-
To change the mix level, use `output.
|
|
376
|
+
To change the mix level, use `output.setEffectMix(name, mix)`:
|
|
349
377
|
|
|
350
378
|
```js
|
|
351
|
-
piano.output.
|
|
379
|
+
piano.output.setEffectMix("reverb", 0.5);
|
|
352
380
|
```
|
|
353
381
|
|
|
382
|
+
`output.sendEffect(name, mix)` is kept as a deprecated alias and continues to work.
|
|
383
|
+
|
|
354
384
|
### Cache requests
|
|
355
385
|
|
|
356
386
|
The default sample sets are hosted on GitHub Pages, which rate-limits requests per second. That can be a problem, especially in a development environment with hot reload (most React frameworks).
|
|
@@ -643,10 +673,28 @@ This will download a WAV file you can attach to your issue or pull request.
|
|
|
643
673
|
|
|
644
674
|
## Instruments
|
|
645
675
|
|
|
676
|
+
### Available instruments
|
|
677
|
+
|
|
678
|
+
Each instrument family exposes a synchronous helper that returns the names you can pass to its factory:
|
|
679
|
+
|
|
680
|
+
| Factory | Names helper |
|
|
681
|
+
| --------------- | ---------------------------------------------- |
|
|
682
|
+
| `Soundfont` | `getSoundfontNames(): string[]` |
|
|
683
|
+
| `ElectricPiano` | `getElectricPianoNames(): string[]` |
|
|
684
|
+
| `Mallet` | `getMalletNames(): string[]` |
|
|
685
|
+
| `Mellotron` | `getMellotronNames(): string[]` |
|
|
686
|
+
| `DrumMachine` | `getDrumMachineNames(): string[]` |
|
|
687
|
+
| `Smolken` | `getSmolkenNames(): string[]` |
|
|
688
|
+
| `Versilian` | `getVersilianInstruments(): Promise<string[]>` |
|
|
689
|
+
|
|
690
|
+
`getVersilianInstruments` is async because the catalog is fetched from the network on first call (cached thereafter).
|
|
691
|
+
|
|
646
692
|
### Sampler
|
|
647
693
|
|
|
648
694
|
An audio buffer sampler. Pass a `buffers` object with the files to be load:
|
|
649
695
|
|
|
696
|
+
#### Buffers mode
|
|
697
|
+
|
|
650
698
|
```js
|
|
651
699
|
import { Sampler } from "smplr";
|
|
652
700
|
|
|
@@ -663,6 +711,37 @@ And then use the name of the buffer as note name:
|
|
|
663
711
|
sampler.start({ note: "kick" });
|
|
664
712
|
```
|
|
665
713
|
|
|
714
|
+
#### Advanced mode
|
|
715
|
+
|
|
716
|
+
For advanced use cases (per-region pitch/velocity/round-robin, SFZ-like multi-sample instruments, runtime swaps), pass a `SmplrPreset` directly:
|
|
717
|
+
|
|
718
|
+
```ts
|
|
719
|
+
import { Sampler, type SmplrPreset } from "smplr";
|
|
720
|
+
|
|
721
|
+
const kitA: SmplrPreset = {
|
|
722
|
+
samples: { baseUrl: "https://cdn.example.com/", formats: ["ogg"] },
|
|
723
|
+
groups: [
|
|
724
|
+
{
|
|
725
|
+
regions: [
|
|
726
|
+
{ sample: "kick", keyRange: [60, 60], pitch: 60 },
|
|
727
|
+
{ sample: "snare", keyRange: [62, 62], pitch: 62 },
|
|
728
|
+
],
|
|
729
|
+
},
|
|
730
|
+
],
|
|
731
|
+
};
|
|
732
|
+
|
|
733
|
+
const sampler = Sampler(new AudioContext(), { preset: kitA });
|
|
734
|
+
await sampler.ready;
|
|
735
|
+
sampler.start({ note: 60 });
|
|
736
|
+
|
|
737
|
+
// Swap content at runtime
|
|
738
|
+
await sampler.reload(kitB);
|
|
739
|
+
```
|
|
740
|
+
|
|
741
|
+
The full `SmplrPreset` schema is documented in [SMPLR_PRESET.md](./SMPLR_PRESET.md). Note: `buffers` and `preset` are mutually exclusive on construction — pass exactly one.
|
|
742
|
+
|
|
743
|
+
`sampler.reload(input)` accepts either shape (flat buffers record or full `SmplrPreset`), regardless of which mode was used at construction.
|
|
744
|
+
|
|
666
745
|
### Soundfont
|
|
667
746
|
|
|
668
747
|
A Soundfont player. By default it loads audio from Benjamin Gleitzman's package of
|
package/dist/index.d.mts
CHANGED
|
@@ -17,15 +17,20 @@ type OutputChannel = Omit<Channel, "input">;
|
|
|
17
17
|
declare class Channel {
|
|
18
18
|
#private;
|
|
19
19
|
readonly context: BaseAudioContext;
|
|
20
|
+
/** @deprecated Use `output.volume = n` instead. */
|
|
20
21
|
readonly setVolume: (vol: number) => void;
|
|
21
22
|
readonly input: AudioNode;
|
|
22
23
|
constructor(context: BaseAudioContext, options?: Partial<ChannelConfig>);
|
|
24
|
+
get volume(): number;
|
|
25
|
+
set volume(value: number);
|
|
23
26
|
get pan(): number;
|
|
24
27
|
set pan(value: number);
|
|
25
28
|
addInsert(effect: AudioNode | AudioInsert): void;
|
|
26
29
|
addEffect(name: string, effect: AudioNode | {
|
|
27
30
|
input: AudioNode;
|
|
28
31
|
}, mixValue: number): void;
|
|
32
|
+
setEffectMix(name: string, mix: number): void;
|
|
33
|
+
/** @deprecated Use `setEffectMix(name, mix)` instead. */
|
|
29
34
|
sendEffect(name: string, mix: number): void;
|
|
30
35
|
disconnect(): void;
|
|
31
36
|
}
|
|
@@ -109,7 +114,9 @@ type SmplrSamples = {
|
|
|
109
114
|
/**
|
|
110
115
|
* The top-level smplr.json descriptor. Passed to the Smplr constructor.
|
|
111
116
|
*/
|
|
112
|
-
type
|
|
117
|
+
type SmplrPreset = {
|
|
118
|
+
/** Schema version. Omit for the current format. Reserved for future migrations. */
|
|
119
|
+
smplr?: "1.0";
|
|
113
120
|
meta?: {
|
|
114
121
|
name?: string;
|
|
115
122
|
description?: string;
|
|
@@ -183,7 +190,7 @@ type VoiceParams = {
|
|
|
183
190
|
};
|
|
184
191
|
|
|
185
192
|
/**
|
|
186
|
-
* Loads and caches AudioBuffers for all samples referenced in a
|
|
193
|
+
* Loads and caches AudioBuffers for all samples referenced in a SmplrPreset.
|
|
187
194
|
*
|
|
188
195
|
* The cache is keyed by resolved URL, so the same audio file is never fetched
|
|
189
196
|
* or decoded twice. Multiple Smplr instances can share one SampleLoader by
|
|
@@ -202,7 +209,7 @@ declare class SampleLoader {
|
|
|
202
209
|
* - `buffers` in options: pre-loaded buffers — skips fetch for these names.
|
|
203
210
|
* - All samples load in parallel. Failed samples are silently omitted.
|
|
204
211
|
*/
|
|
205
|
-
load(json:
|
|
212
|
+
load(json: SmplrPreset, onProgressOrOptions?: ((loaded: number, total: number) => void) | {
|
|
206
213
|
buffers?: Map<string, AudioBuffer>;
|
|
207
214
|
onProgress?: (loaded: number, total: number) => void;
|
|
208
215
|
}): Promise<Map<string, AudioBuffer>>;
|
|
@@ -287,6 +294,19 @@ interface Smplr {
|
|
|
287
294
|
start(event: NoteEvent): StopFn;
|
|
288
295
|
stop(target?: StopTarget): void;
|
|
289
296
|
setCC(cc: number, value: number): void;
|
|
297
|
+
/**
|
|
298
|
+
* Read the latest value set via `setCC`. Returns `0` for any CC that has
|
|
299
|
+
* not been set (matches MIDI's "undefined controller defaults to 0" convention).
|
|
300
|
+
*/
|
|
301
|
+
getCC(cc: number): number;
|
|
302
|
+
/**
|
|
303
|
+
* Stop all voices, dispose the output channel, and stop the scheduler.
|
|
304
|
+
* The instance must not be used after this call — subsequent `start`/`stop`/
|
|
305
|
+
* `setCC`/`getCC`/`setControlValue`/`loadInstrument` calls throw. Subsequent
|
|
306
|
+
* `dispose()` calls are no-ops.
|
|
307
|
+
*/
|
|
308
|
+
dispose(): void;
|
|
309
|
+
/** @deprecated Use `dispose()` instead. */
|
|
290
310
|
disconnect(): void;
|
|
291
311
|
}
|
|
292
312
|
/**
|
|
@@ -304,7 +324,7 @@ interface PluginSmplr extends Smplr {
|
|
|
304
324
|
*
|
|
305
325
|
* Resolves when all samples are ready.
|
|
306
326
|
*/
|
|
307
|
-
loadInstrument(json:
|
|
327
|
+
loadInstrument(json: SmplrPreset, buffers?: Map<string, AudioBuffer>): Promise<void>;
|
|
308
328
|
}
|
|
309
329
|
/**
|
|
310
330
|
* Permitted return shapes for an {@link SmplrPlugin}:
|
|
@@ -406,14 +426,16 @@ declare const DrumMachine: InstrumentFactory<Partial<DrumMachineConfig & {
|
|
|
406
426
|
velocity?: number;
|
|
407
427
|
onLoadProgress?: (progress: LoadProgress) => void;
|
|
408
428
|
}>, DrumMachineExtras>;
|
|
429
|
+
/** Instance type returned by the {@link DrumMachine} factory. */
|
|
430
|
+
type DrumMachine = ReturnType<typeof DrumMachine>;
|
|
409
431
|
/**
|
|
410
|
-
* Convert a DrumMachineInstrument to a
|
|
432
|
+
* Convert a DrumMachineInstrument to a SmplrPreset descriptor.
|
|
411
433
|
*
|
|
412
434
|
* Each sample gets a sequential MIDI number starting at 36 (GM drum map base).
|
|
413
435
|
* Aliases are created for both the full sample name ("kick/1") and the group
|
|
414
436
|
* name ("kick") so both forms work with Smplr.start({ note: "kick" }).
|
|
415
437
|
*/
|
|
416
|
-
declare function
|
|
438
|
+
declare function drumMachineToPreset(instrument: DrumMachineInstrument): SmplrPreset;
|
|
417
439
|
|
|
418
440
|
/**
|
|
419
441
|
* The result of an offline render. Provides the raw AudioBuffer and
|
|
@@ -482,22 +504,6 @@ declare function audioBufferToWav16(buffer: AudioBuffer): Blob;
|
|
|
482
504
|
*/
|
|
483
505
|
declare function trimSilence(buffer: AudioBuffer): AudioBuffer;
|
|
484
506
|
|
|
485
|
-
/**
|
|
486
|
-
* Given a list of [midi, sampleName] pairs, return one entry per sample with
|
|
487
|
-
* a keyRange that covers all MIDI notes closer to that sample than to any
|
|
488
|
-
* neighbour. The first sample extends down to 0; the last extends up to 127.
|
|
489
|
-
*
|
|
490
|
-
* The boundary between two adjacent samples A and B (A < B) is placed at
|
|
491
|
-
* `floor((A + B) / 2)`, matching the behaviour of the old `findNearestMidiInLayer`
|
|
492
|
-
* which always resolved ties in favour of the lower sample.
|
|
493
|
-
*/
|
|
494
|
-
type SpreadResult = {
|
|
495
|
-
keyRange: [number, number];
|
|
496
|
-
pitch: number;
|
|
497
|
-
sample: string;
|
|
498
|
-
};
|
|
499
|
-
declare function spreadKeyRanges(samples: [number, string][]): SpreadResult[];
|
|
500
|
-
|
|
501
507
|
/**
|
|
502
508
|
* TransportClock
|
|
503
509
|
*
|
|
@@ -715,6 +721,8 @@ declare const ElectricPiano: InstrumentFactory<Partial<{
|
|
|
715
721
|
level: (value: number) => void;
|
|
716
722
|
}>;
|
|
717
723
|
}>;
|
|
724
|
+
/** Instance type returned by the {@link ElectricPiano} factory. */
|
|
725
|
+
type ElectricPiano = ReturnType<typeof ElectricPiano>;
|
|
718
726
|
|
|
719
727
|
declare function getVersilianInstruments(): Promise<string[]>;
|
|
720
728
|
type VersilianConfig = {
|
|
@@ -739,6 +747,8 @@ declare const Versilian: InstrumentFactory<Partial<VersilianConfig & {
|
|
|
739
747
|
velocity?: number;
|
|
740
748
|
onLoadProgress?: (progress: LoadProgress) => void;
|
|
741
749
|
}>, {}>;
|
|
750
|
+
/** Instance type returned by the {@link Versilian} factory. */
|
|
751
|
+
type Versilian = ReturnType<typeof Versilian>;
|
|
742
752
|
/**
|
|
743
753
|
* Fetch the SFZ for a VCSL instrument and load it into `smplr`. Shared by
|
|
744
754
|
* the {@link Versilian} and {@link Mallet} factories — not exported from the
|
|
@@ -746,14 +756,15 @@ declare const Versilian: InstrumentFactory<Partial<VersilianConfig & {
|
|
|
746
756
|
*/
|
|
747
757
|
declare function loadVersilianInstrument(smplr: PluginSmplr, options: VersilianOptions): Promise<void>;
|
|
748
758
|
|
|
749
|
-
declare function getMalletNames():
|
|
759
|
+
declare function getMalletNames(): string[];
|
|
750
760
|
declare const Mallet: InstrumentFactory<Partial<VersilianConfig & {
|
|
751
761
|
destination?: AudioNode;
|
|
752
762
|
volume?: number;
|
|
753
763
|
velocity?: number;
|
|
754
764
|
onLoadProgress?: (progress: LoadProgress) => void;
|
|
755
765
|
}>, {}>;
|
|
756
|
-
type
|
|
766
|
+
/** Instance type returned by the {@link Mallet} factory. */
|
|
767
|
+
type Mallet = ReturnType<typeof Mallet>;
|
|
757
768
|
declare const NAME_TO_PATH: Record<string, string | undefined>;
|
|
758
769
|
|
|
759
770
|
declare function getMellotronNames(): string[];
|
|
@@ -775,19 +786,21 @@ declare const Mellotron: InstrumentFactory<Partial<MellotronConfig & {
|
|
|
775
786
|
decayTime?: number;
|
|
776
787
|
onLoadProgress?: (progress: LoadProgress) => void;
|
|
777
788
|
}>, {}>;
|
|
789
|
+
/** Instance type returned by the {@link Mellotron} factory. */
|
|
790
|
+
type Mellotron = ReturnType<typeof Mellotron>;
|
|
778
791
|
type MellotronJsonConfig = {
|
|
779
792
|
instrument: string;
|
|
780
793
|
variation?: string;
|
|
781
794
|
};
|
|
782
795
|
/**
|
|
783
|
-
* Convert a Mellotron files.json sample list to
|
|
796
|
+
* Convert a Mellotron files.json sample list to SmplrPreset.
|
|
784
797
|
*
|
|
785
798
|
* - Filters by variation string if provided.
|
|
786
799
|
* - Extracts MIDI from the first word of each sample name.
|
|
787
800
|
* - Uses spreadKeyRanges so nearby notes pitch-shift to the nearest sample.
|
|
788
801
|
* - All regions get loopAuto to produce tape-loop playback.
|
|
789
802
|
*/
|
|
790
|
-
declare function
|
|
803
|
+
declare function mellotronToPreset(sampleNames: string[], config: MellotronJsonConfig): SmplrPreset;
|
|
791
804
|
|
|
792
805
|
declare const PARAMS: readonly ["preDelay", "bandwidth", "inputDiffusion1", "inputDiffusion2", "decay", "decayDiffusion1", "decayDiffusion2", "damping", "excursionRate", "excursionDepth", "wet", "dry"];
|
|
793
806
|
declare class Reverb {
|
|
@@ -807,30 +820,40 @@ type AudioBuffers = Record<string | number, AudioBuffer | undefined>;
|
|
|
807
820
|
*/
|
|
808
821
|
type AudioBuffersLoader = (context: BaseAudioContext, buffers: AudioBuffers) => Promise<void>;
|
|
809
822
|
|
|
810
|
-
type
|
|
823
|
+
type SamplerBase = {
|
|
811
824
|
storage?: Storage;
|
|
812
|
-
detune
|
|
813
|
-
volume
|
|
814
|
-
velocity
|
|
825
|
+
detune?: number;
|
|
826
|
+
volume?: number;
|
|
827
|
+
velocity?: number;
|
|
815
828
|
decayTime?: number;
|
|
816
829
|
lpfCutoffHz?: number;
|
|
817
|
-
destination
|
|
818
|
-
|
|
819
|
-
volumeToGain: (volume: number) => number;
|
|
830
|
+
destination?: AudioNode;
|
|
831
|
+
volumeToGain?: (volume: number) => number;
|
|
820
832
|
onLoadProgress?: (progress: LoadProgress) => void;
|
|
821
833
|
};
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
834
|
+
type SamplerBuffers = Record<string | number, string | AudioBuffer | AudioBuffers> | AudioBuffersLoader;
|
|
835
|
+
type SamplerBuffersInput = {
|
|
836
|
+
buffers?: SamplerBuffers;
|
|
837
|
+
preset?: never;
|
|
838
|
+
};
|
|
839
|
+
type SamplerPresetInput = {
|
|
840
|
+
preset: SmplrPreset;
|
|
841
|
+
buffers?: never;
|
|
842
|
+
};
|
|
843
|
+
type SamplerConfig = SamplerBase & (SamplerBuffersInput | SamplerPresetInput);
|
|
844
|
+
/** Input accepted by {@link Sampler.reload}: a `SmplrPreset` schema or a flat buffers record/loader. */
|
|
845
|
+
type SamplerReloadInput = SmplrPreset | SamplerBuffers;
|
|
846
|
+
type SamplerExtras = {
|
|
847
|
+
reload: (input: SamplerReloadInput) => Promise<void>;
|
|
848
|
+
};
|
|
826
849
|
type SamplerJsonOptions = Pick<SamplerConfig, "decayTime" | "lpfCutoffHz" | "detune">;
|
|
827
850
|
type InternalConvertResult = {
|
|
828
|
-
json:
|
|
851
|
+
json: SmplrPreset;
|
|
829
852
|
urlMap: Record<string, string>;
|
|
830
853
|
preloaded: Map<string, AudioBuffer>;
|
|
831
854
|
};
|
|
832
855
|
/**
|
|
833
|
-
* Convert a flat source Record to
|
|
856
|
+
* Convert a flat source Record to SmplrPreset + separated URL map + pre-loaded buffers.
|
|
834
857
|
*
|
|
835
858
|
* - Keys that are valid MIDI names/numbers → MIDI-mapped regions.
|
|
836
859
|
* If ALL keys are MIDI-parseable, spread key ranges (pitch-shifting).
|
|
@@ -839,7 +862,20 @@ type InternalConvertResult = {
|
|
|
839
862
|
* - AudioBuffer values → pre-loaded map (no fetch).
|
|
840
863
|
* - String URL values → urlMap (fetched asynchronously by caller).
|
|
841
864
|
*/
|
|
842
|
-
declare function
|
|
865
|
+
declare function samplerToPreset(source: Record<string | number, string | AudioBuffer>, options?: Partial<SamplerJsonOptions>): InternalConvertResult;
|
|
866
|
+
/**
|
|
867
|
+
* A Sampler instrument. Accepts either a flat record of samples
|
|
868
|
+
* (`{ buffers: { C4: "url" } }`) or a full `SmplrPreset`
|
|
869
|
+
* (`{ preset: { samples, groups, ... } }`) for advanced use cases including
|
|
870
|
+
* per-region pitch/velocity/round-robin control.
|
|
871
|
+
*
|
|
872
|
+
* Use `sampler.reload(input)` to swap content at runtime. `reload` accepts
|
|
873
|
+
* either shape (flat record or `SmplrPreset`), regardless of which mode was
|
|
874
|
+
* used at construction.
|
|
875
|
+
*/
|
|
876
|
+
declare const Sampler: InstrumentFactory<SamplerConfig, SamplerExtras>;
|
|
877
|
+
/** Instance type returned by the {@link Sampler} factory. */
|
|
878
|
+
type Sampler = ReturnType<typeof Sampler>;
|
|
843
879
|
|
|
844
880
|
declare function getSmolkenNames(): string[];
|
|
845
881
|
type SmolkenConfig = {
|
|
@@ -858,6 +894,8 @@ declare const Smolken: InstrumentFactory<Partial<SmolkenConfig & {
|
|
|
858
894
|
velocity?: number;
|
|
859
895
|
onLoadProgress?: (progress: LoadProgress) => void;
|
|
860
896
|
}>, {}>;
|
|
897
|
+
/** Instance type returned by the {@link Smolken} factory. */
|
|
898
|
+
type Smolken = ReturnType<typeof Smolken>;
|
|
861
899
|
|
|
862
900
|
type LoopData = Record<number, [number, number]>;
|
|
863
901
|
|
|
@@ -884,11 +922,13 @@ declare const Soundfont: InstrumentFactory<Partial<SoundfontConfig & {
|
|
|
884
922
|
velocity?: number;
|
|
885
923
|
onLoadProgress?: (progress: LoadProgress) => void;
|
|
886
924
|
}>, {}>;
|
|
925
|
+
/** Instance type returned by the {@link Soundfont} factory. */
|
|
926
|
+
type Soundfont = ReturnType<typeof Soundfont>;
|
|
887
927
|
/**
|
|
888
|
-
* Convert a list of note names (with optional loop data) to
|
|
928
|
+
* Convert a list of note names (with optional loop data) to SmplrPreset.
|
|
889
929
|
* Uses spreadKeyRanges so notes between recorded pitches pitch-shift correctly.
|
|
890
930
|
*/
|
|
891
|
-
declare function
|
|
931
|
+
declare function soundfontToPreset(noteNames: string[], loopData?: LoopData): SmplrPreset;
|
|
892
932
|
|
|
893
933
|
type Sf2 = {
|
|
894
934
|
instruments: Sf2Instrument[];
|
|
@@ -926,8 +966,8 @@ type Soundfont2Options = {
|
|
|
926
966
|
volume?: number;
|
|
927
967
|
velocity?: number;
|
|
928
968
|
};
|
|
929
|
-
declare function
|
|
930
|
-
json:
|
|
969
|
+
declare function sf2InstrumentToPreset(sf2Instrument: Sf2Instrument, context: BaseAudioContext): {
|
|
970
|
+
json: SmplrPreset;
|
|
931
971
|
buffers: Map<string, AudioBuffer>;
|
|
932
972
|
};
|
|
933
973
|
type Soundfont2SamplerExtras = {
|
|
@@ -935,6 +975,8 @@ type Soundfont2SamplerExtras = {
|
|
|
935
975
|
loadInstrument(instrumentName: string): Promise<void> | undefined;
|
|
936
976
|
};
|
|
937
977
|
declare const Soundfont2Sampler: InstrumentFactory<Soundfont2Options, Soundfont2SamplerExtras>;
|
|
978
|
+
/** Instance type returned by the {@link Soundfont2Sampler} factory. */
|
|
979
|
+
type Soundfont2Sampler = ReturnType<typeof Soundfont2Sampler>;
|
|
938
980
|
|
|
939
981
|
/**
|
|
940
982
|
* Configuration options for SplendidGrandPiano.
|
|
@@ -946,7 +988,7 @@ type SplendidGrandPianoConfig = {
|
|
|
946
988
|
detune: number;
|
|
947
989
|
/** Default velocity (0–127) when not specified per note. */
|
|
948
990
|
velocity: number;
|
|
949
|
-
/** Release time in seconds. Maps to
|
|
991
|
+
/** Release time in seconds. Maps to SmplrPreset defaults.ampRelease. */
|
|
950
992
|
decayTime: number;
|
|
951
993
|
/** Destination audio node. Defaults to context.destination. */
|
|
952
994
|
destination?: AudioNode;
|
|
@@ -963,9 +1005,11 @@ type SplendidGrandPianoConfig = {
|
|
|
963
1005
|
};
|
|
964
1006
|
};
|
|
965
1007
|
declare const SplendidGrandPiano: InstrumentFactory<Partial<SplendidGrandPianoConfig>, {}>;
|
|
1008
|
+
/** Instance type returned by the {@link SplendidGrandPiano} factory. */
|
|
1009
|
+
type SplendidGrandPiano = ReturnType<typeof SplendidGrandPiano>;
|
|
966
1010
|
type PianoJsonOptions = Pick<SplendidGrandPianoConfig, "baseUrl" | "detune" | "decayTime" | "notesToLoad" | "formats">;
|
|
967
1011
|
/**
|
|
968
|
-
* Convert the LAYERS array and user options into a
|
|
1012
|
+
* Convert the LAYERS array and user options into a SmplrPreset descriptor.
|
|
969
1013
|
*
|
|
970
1014
|
* Each layer becomes a SmplrGroup with its velRange. If `notesToLoad` is
|
|
971
1015
|
* specified, layers and samples are filtered accordingly. The PPP layer
|
|
@@ -974,8 +1018,7 @@ type PianoJsonOptions = Pick<SplendidGrandPianoConfig, "baseUrl" | "detune" | "d
|
|
|
974
1018
|
* `spreadKeyRanges` is used to pre-compute which key range each sample
|
|
975
1019
|
* covers, replacing the old on-the-fly `findNearestMidiInLayer` logic.
|
|
976
1020
|
*/
|
|
977
|
-
declare function
|
|
978
|
-
|
|
1021
|
+
declare function pianoToPreset(options: PianoJsonOptions): SmplrPreset;
|
|
979
1022
|
declare const LAYERS: ({
|
|
980
1023
|
name: string;
|
|
981
1024
|
vel_range: number[];
|
|
@@ -988,4 +1031,4 @@ declare const LAYERS: ({
|
|
|
988
1031
|
cutoff?: undefined;
|
|
989
1032
|
})[];
|
|
990
1033
|
|
|
991
|
-
export { CacheStorage, DrumMachine, type DrumMachineOptions, ElectricPiano, type ElectricPianoOptions, HttpStorage, Instrument, LAYERS, type LoadProgress, Mallet, Mellotron, type MellotronConfig, type MellotronOptions, NAME_TO_PATH, type NoteEvent, type PlaybackParams, type RenderOfflineOptions, RenderResult, Reverb, SampleLoader, Sampler, type SamplerConfig, Scheduler, Sequencer, type SequencerInstrument, type SequencerNote, type SequencerNoteEvent, type SequencerOptions, Smolken, type SmolkenConfig, type SmolkenOptions, type Smplr, type SmplrGroup, type
|
|
1034
|
+
export { CacheStorage, DrumMachine, type DrumMachineOptions, ElectricPiano, type ElectricPianoOptions, HttpStorage, Instrument, LAYERS, type LoadProgress, Mallet, Mellotron, type MellotronConfig, type MellotronOptions, NAME_TO_PATH, type NoteEvent, type PlaybackParams, type RenderOfflineOptions, RenderResult, Reverb, SampleLoader, Sampler, type SamplerConfig, type SamplerReloadInput, Scheduler, Sequencer, type SequencerInstrument, type SequencerNote, type SequencerNoteEvent, type SequencerOptions, Smolken, type SmolkenConfig, type SmolkenOptions, type Smplr, type SmplrGroup, type SmplrOptions, type SmplrPlugin, type SmplrPreset, type SmplrRegion, type SmplrSamples, Soundfont, type Soundfont2Options, Soundfont2Sampler, type SoundfontOptions, SplendidGrandPiano, type SplendidGrandPianoConfig, type StopFn, type StopTarget, type Storage, type StorageResponse, Versilian, type VersilianConfig, type VersilianOptions, type VoiceParams, audioBufferToWav, audioBufferToWav16, drumMachineToPreset, getDrumMachineNames, getElectricPianoNames, getMalletNames, getMellotronNames, getSmolkenNames, getSoundfontKits, getSoundfontNames, getVersilianInstruments, loadVersilianInstrument, mellotronToPreset, pianoToPreset, renderOffline, samplerToPreset, sf2InstrumentToPreset, soundfontToPreset, trimSilence };
|