smplr 0.22.0 → 0.24.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 +182 -29
- package/dist/index.d.mts +274 -60
- package/dist/index.d.ts +274 -60
- package/dist/index.js +398 -152
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +391 -146
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -35,6 +35,23 @@ declare class Channel {
|
|
|
35
35
|
disconnect(): void;
|
|
36
36
|
}
|
|
37
37
|
|
|
38
|
+
/**
|
|
39
|
+
* Wrap a class so it is callable both as `X(...)` (preferred) and as
|
|
40
|
+
* `new X(...)` (kept for compatibility with pre-1.0 examples). Returns
|
|
41
|
+
* a value with both call and construct signatures.
|
|
42
|
+
*
|
|
43
|
+
* Used by the auxiliary exports (`Sequencer`, `Reverb`, `CacheStorage`,
|
|
44
|
+
* `Scheduler`, `SampleLoader`) to match the dual signature already shipped
|
|
45
|
+
* by `InstrumentFactory`. Instrument factories themselves use the richer
|
|
46
|
+
* `Instrument()` builder instead, which owns option-splitting and the
|
|
47
|
+
* ready-promise lifecycle.
|
|
48
|
+
*/
|
|
49
|
+
type Constructable<A extends unknown[], R> = {
|
|
50
|
+
(...args: A): R;
|
|
51
|
+
/** @deprecated Call as a function: `X(...)` instead of `new X(...)`. */
|
|
52
|
+
new (...args: A): R;
|
|
53
|
+
};
|
|
54
|
+
|
|
38
55
|
type StorageResponse = {
|
|
39
56
|
readonly status: number;
|
|
40
57
|
arrayBuffer(): Promise<ArrayBuffer>;
|
|
@@ -45,11 +62,13 @@ type Storage = {
|
|
|
45
62
|
fetch: (url: string) => Promise<StorageResponse>;
|
|
46
63
|
};
|
|
47
64
|
declare const HttpStorage: Storage;
|
|
48
|
-
declare class
|
|
65
|
+
declare class CacheStorageImpl implements Storage {
|
|
49
66
|
#private;
|
|
50
67
|
constructor(name?: string);
|
|
51
68
|
fetch(url: string): Promise<StorageResponse>;
|
|
52
69
|
}
|
|
70
|
+
declare const CacheStorage: Constructable<[name?: string | undefined], CacheStorageImpl>;
|
|
71
|
+
type CacheStorage = ReturnType<typeof CacheStorage>;
|
|
53
72
|
|
|
54
73
|
/**
|
|
55
74
|
* Inheritable playback parameters. Can appear at global defaults, group, or region level.
|
|
@@ -114,7 +133,7 @@ type SmplrSamples = {
|
|
|
114
133
|
/**
|
|
115
134
|
* The top-level smplr.json descriptor. Passed to the Smplr constructor.
|
|
116
135
|
*/
|
|
117
|
-
type
|
|
136
|
+
type SmplrPreset = {
|
|
118
137
|
/** Schema version. Omit for the current format. Reserved for future migrations. */
|
|
119
138
|
smplr?: "1.0";
|
|
120
139
|
meta?: {
|
|
@@ -190,13 +209,13 @@ type VoiceParams = {
|
|
|
190
209
|
};
|
|
191
210
|
|
|
192
211
|
/**
|
|
193
|
-
* Loads and caches AudioBuffers for all samples referenced in a
|
|
212
|
+
* Loads and caches AudioBuffers for all samples referenced in a SmplrPreset.
|
|
194
213
|
*
|
|
195
214
|
* The cache is keyed by resolved URL, so the same audio file is never fetched
|
|
196
215
|
* or decoded twice. Multiple Smplr instances can share one SampleLoader by
|
|
197
216
|
* passing it via SmplrOptions.loader.
|
|
198
217
|
*/
|
|
199
|
-
declare class
|
|
218
|
+
declare class SampleLoaderImpl {
|
|
200
219
|
#private;
|
|
201
220
|
constructor(context: BaseAudioContext, options?: {
|
|
202
221
|
storage?: Storage;
|
|
@@ -209,11 +228,15 @@ declare class SampleLoader {
|
|
|
209
228
|
* - `buffers` in options: pre-loaded buffers — skips fetch for these names.
|
|
210
229
|
* - All samples load in parallel. Failed samples are silently omitted.
|
|
211
230
|
*/
|
|
212
|
-
load(json:
|
|
231
|
+
load(json: SmplrPreset, onProgressOrOptions?: ((loaded: number, total: number) => void) | {
|
|
213
232
|
buffers?: Map<string, AudioBuffer>;
|
|
214
233
|
onProgress?: (loaded: number, total: number) => void;
|
|
215
234
|
}): Promise<Map<string, AudioBuffer>>;
|
|
216
235
|
}
|
|
236
|
+
declare const SampleLoader: Constructable<[context: BaseAudioContext, options?: {
|
|
237
|
+
storage?: Storage;
|
|
238
|
+
} | undefined], SampleLoaderImpl>;
|
|
239
|
+
type SampleLoader = ReturnType<typeof SampleLoader>;
|
|
217
240
|
|
|
218
241
|
/**
|
|
219
242
|
* Standalone scheduler. Dispatches NoteEvents immediately when they fall within the
|
|
@@ -221,7 +244,7 @@ declare class SampleLoader {
|
|
|
221
244
|
*
|
|
222
245
|
* Multiple Smplr instances can share a single Scheduler for coordinated timing.
|
|
223
246
|
*/
|
|
224
|
-
declare class
|
|
247
|
+
declare class SchedulerImpl {
|
|
225
248
|
#private;
|
|
226
249
|
constructor(context: BaseAudioContext, options?: {
|
|
227
250
|
lookaheadMs?: number;
|
|
@@ -242,6 +265,11 @@ declare class Scheduler {
|
|
|
242
265
|
*/
|
|
243
266
|
stop(): void;
|
|
244
267
|
}
|
|
268
|
+
declare const Scheduler: Constructable<[context: BaseAudioContext, options?: {
|
|
269
|
+
lookaheadMs?: number;
|
|
270
|
+
intervalMs?: number;
|
|
271
|
+
} | undefined], SchedulerImpl>;
|
|
272
|
+
type Scheduler = ReturnType<typeof Scheduler>;
|
|
245
273
|
|
|
246
274
|
type SmplrOptions = {
|
|
247
275
|
/** Custom storage backend for sample fetching (e.g. CacheStorage). */
|
|
@@ -299,6 +327,19 @@ interface Smplr {
|
|
|
299
327
|
* not been set (matches MIDI's "undefined controller defaults to 0" convention).
|
|
300
328
|
*/
|
|
301
329
|
getCC(cc: number): number;
|
|
330
|
+
/**
|
|
331
|
+
* Set the cents detune applied to every future note. Mutates the instrument's
|
|
332
|
+
* playback defaults in place; takes effect on notes scheduled after the call.
|
|
333
|
+
* In-flight notes are unaffected.
|
|
334
|
+
*/
|
|
335
|
+
setDetune(cents: number): void;
|
|
336
|
+
/**
|
|
337
|
+
* Set whether every future note plays its sample reversed. Mutates the
|
|
338
|
+
* instrument's playback defaults in place. The reversed-buffer cache is
|
|
339
|
+
* populated lazily on demand; no cache invalidation is needed in either
|
|
340
|
+
* direction.
|
|
341
|
+
*/
|
|
342
|
+
setReverse(reverse: boolean): void;
|
|
302
343
|
/**
|
|
303
344
|
* Stop all voices, dispose the output channel, and stop the scheduler.
|
|
304
345
|
* The instance must not be used after this call — subsequent `start`/`stop`/
|
|
@@ -324,7 +365,7 @@ interface PluginSmplr extends Smplr {
|
|
|
324
365
|
*
|
|
325
366
|
* Resolves when all samples are ready.
|
|
326
367
|
*/
|
|
327
|
-
loadInstrument(json:
|
|
368
|
+
loadInstrument(json: SmplrPreset, buffers?: Map<string, AudioBuffer>): Promise<void>;
|
|
328
369
|
}
|
|
329
370
|
/**
|
|
330
371
|
* Permitted return shapes for an {@link SmplrPlugin}:
|
|
@@ -429,13 +470,13 @@ declare const DrumMachine: InstrumentFactory<Partial<DrumMachineConfig & {
|
|
|
429
470
|
/** Instance type returned by the {@link DrumMachine} factory. */
|
|
430
471
|
type DrumMachine = ReturnType<typeof DrumMachine>;
|
|
431
472
|
/**
|
|
432
|
-
* Convert a DrumMachineInstrument to a
|
|
473
|
+
* Convert a DrumMachineInstrument to a SmplrPreset descriptor.
|
|
433
474
|
*
|
|
434
475
|
* Each sample gets a sequential MIDI number starting at 36 (GM drum map base).
|
|
435
476
|
* Aliases are created for both the full sample name ("kick/1") and the group
|
|
436
477
|
* name ("kick") so both forms work with Smplr.start({ note: "kick" }).
|
|
437
478
|
*/
|
|
438
|
-
declare function
|
|
479
|
+
declare function drumMachineToPreset(instrument: DrumMachineInstrument): SmplrPreset;
|
|
439
480
|
|
|
440
481
|
/**
|
|
441
482
|
* The result of an offline render. Provides the raw AudioBuffer and
|
|
@@ -534,6 +575,19 @@ type SequencerNote = {
|
|
|
534
575
|
velocity?: number;
|
|
535
576
|
/** Probability (0–100) that this note fires on each pass. Default 100 (always). */
|
|
536
577
|
chance?: number;
|
|
578
|
+
/**
|
|
579
|
+
* Expand into N evenly-spaced sub-notes over `duration`. Requires `duration`;
|
|
580
|
+
* silently ignored if `duration` is omitted. Default 1 (no ratchet). When >1,
|
|
581
|
+
* each sub-note's `noteId` is suffixed with `#0`, `#1`, … so individual
|
|
582
|
+
* ratchet voices can be stopped via `stopNote("id#0")`.
|
|
583
|
+
*/
|
|
584
|
+
ratchet?: number;
|
|
585
|
+
/**
|
|
586
|
+
* Multiplicative velocity decay per ratchet step: each step's velocity is
|
|
587
|
+
* scaled by `(1 - decay) ** step_index`. 0 = constant, 1 = silence by last
|
|
588
|
+
* step. Default 0.
|
|
589
|
+
*/
|
|
590
|
+
ratchetVelocityDecay?: number;
|
|
537
591
|
};
|
|
538
592
|
/**
|
|
539
593
|
* Any instrument the Sequencer can drive.
|
|
@@ -558,10 +612,20 @@ type SequencerNoteEvent = {
|
|
|
558
612
|
noteIndex: number;
|
|
559
613
|
note: SequencerNote;
|
|
560
614
|
};
|
|
615
|
+
/**
|
|
616
|
+
* Time signature as a `{ numerator, denominator }` pair (e.g. `{ numerator: 7, denominator: 8 }`
|
|
617
|
+
* for 7/8). The numerator counts beats per bar; the denominator defines the
|
|
618
|
+
* note value of one beat (4 = quarter note, 8 = eighth note, …).
|
|
619
|
+
*/
|
|
620
|
+
type TimeSignature = {
|
|
621
|
+
numerator: number;
|
|
622
|
+
denominator: number;
|
|
623
|
+
};
|
|
561
624
|
type SequencerOptions = {
|
|
562
625
|
bpm?: number;
|
|
563
626
|
ppq?: number;
|
|
564
|
-
|
|
627
|
+
/** Time signature. Accepts `4` (interpreted as 4/4) or `{ numerator, denominator }`. */
|
|
628
|
+
timeSignature?: number | TimeSignature;
|
|
565
629
|
loop?: boolean;
|
|
566
630
|
loopStart?: string | number;
|
|
567
631
|
loopEnd?: string | number;
|
|
@@ -577,35 +641,128 @@ type SequencerOptions = {
|
|
|
577
641
|
/** Emit a "step" event at this interval. Accepts musical notation or ticks: "16n", "8n", ticks, etc. */
|
|
578
642
|
stepSize?: string | number;
|
|
579
643
|
};
|
|
580
|
-
|
|
644
|
+
/**
|
|
645
|
+
* Per-track options accepted by {@link Sequencer.addTrack} and
|
|
646
|
+
* {@link Sequencer.setPatterns}.
|
|
647
|
+
*/
|
|
648
|
+
type AddTrackOptions = {
|
|
649
|
+
/**
|
|
650
|
+
* Stable track id. Required to address this track via
|
|
651
|
+
* {@link Sequencer.setTrackVolume}, {@link Sequencer.muteTrack},
|
|
652
|
+
* {@link Sequencer.soloTrack}, etc.
|
|
653
|
+
*/
|
|
654
|
+
id?: string;
|
|
655
|
+
/** Per-track humanize. Overrides {@link SequencerOptions.humanize} when set. */
|
|
656
|
+
humanize?: {
|
|
657
|
+
timingMs?: number;
|
|
658
|
+
velocity?: number;
|
|
659
|
+
};
|
|
660
|
+
/** Multiplicative velocity scalar in [0, 1+]. Default 1. */
|
|
661
|
+
volume?: number;
|
|
662
|
+
/** When true, this track does not dispatch any notes. Default false. */
|
|
663
|
+
muted?: boolean;
|
|
664
|
+
/**
|
|
665
|
+
* When true, only soloed tracks dispatch notes. If any track in the pattern
|
|
666
|
+
* is soloed, every non-soloed track is silenced. Default false.
|
|
667
|
+
*/
|
|
668
|
+
solo?: boolean;
|
|
669
|
+
};
|
|
670
|
+
/**
|
|
671
|
+
* Public shape for one pattern accepted by {@link Sequencer.setPatterns}.
|
|
672
|
+
*/
|
|
673
|
+
type PatternInput = {
|
|
674
|
+
tracks: Array<{
|
|
675
|
+
instrument: SequencerInstrument;
|
|
676
|
+
notes: SequencerNote[];
|
|
677
|
+
} & AddTrackOptions>;
|
|
678
|
+
/**
|
|
679
|
+
* Pattern length override in ticks or musical time. Defaults to the longest
|
|
680
|
+
* track in this pattern.
|
|
681
|
+
*/
|
|
682
|
+
loopEnd?: string | number;
|
|
683
|
+
};
|
|
684
|
+
declare class SequencerImpl {
|
|
581
685
|
private readonly _context;
|
|
582
686
|
private readonly _clock;
|
|
583
687
|
private readonly _ppq;
|
|
584
688
|
private _timeSignature;
|
|
585
689
|
private _stepTicks;
|
|
586
|
-
|
|
690
|
+
/**
|
|
691
|
+
* Patterns. Always at least one (the implicit default pattern). Replaced
|
|
692
|
+
* atomically by {@link setPatterns}.
|
|
693
|
+
*/
|
|
694
|
+
private _patterns;
|
|
695
|
+
/** Indices into {@link _patterns} defining playback order. */
|
|
696
|
+
private _chainOrder;
|
|
697
|
+
/** Current position within {@link _chainOrder}. */
|
|
698
|
+
private _chainIndex;
|
|
699
|
+
/**
|
|
700
|
+
* True once {@link setPatterns} has been called. After this point,
|
|
701
|
+
* `addTrack` / `removeTrack` / `clearTracks` throw because the chain shape
|
|
702
|
+
* is owned by the patterns array.
|
|
703
|
+
*/
|
|
704
|
+
private _patternsExplicit;
|
|
587
705
|
private _repeatEvents;
|
|
588
706
|
private _listeners;
|
|
589
707
|
private _loop;
|
|
590
708
|
private _loopStartTick;
|
|
591
|
-
/** null = default to _totalTicks */
|
|
592
|
-
private _loopEndOverride;
|
|
593
709
|
private _lookaheadSec;
|
|
594
710
|
private _intervalMs;
|
|
595
711
|
private _humanize;
|
|
596
712
|
private _intervalId;
|
|
597
713
|
/** AudioContext time high-water mark: notes up to here have been scheduled. */
|
|
598
714
|
private _scheduledThrough;
|
|
599
|
-
/** Computed from track notes; the tick where the last note ends. */
|
|
600
|
-
private _totalTicks;
|
|
601
715
|
/** Guards against scheduling the auto-stop setTimeout more than once. */
|
|
602
716
|
private _endScheduled;
|
|
603
717
|
/** Active voices keyed by noteId, so individual notes can be stopped. */
|
|
604
718
|
private _activeVoices;
|
|
605
719
|
constructor(context: BaseAudioContext, options?: SequencerOptions);
|
|
606
|
-
|
|
720
|
+
/**
|
|
721
|
+
* Add a track to the (implicit, default) pattern. Throws after
|
|
722
|
+
* {@link setPatterns} has been called — use {@link setPatterns} to mutate
|
|
723
|
+
* the chain.
|
|
724
|
+
*/
|
|
725
|
+
addTrack(instrument: SequencerInstrument, notes: SequencerNote[], options?: AddTrackOptions): this;
|
|
607
726
|
removeTrack(instrument: SequencerInstrument): this;
|
|
608
727
|
clearTracks(): this;
|
|
728
|
+
/**
|
|
729
|
+
* Replace the sequencer's patterns. Each pattern owns its own tracks and
|
|
730
|
+
* optional `loopEnd`. After this call, `addTrack` / `removeTrack` /
|
|
731
|
+
* `clearTracks` throw — the chain is owned by the patterns array.
|
|
732
|
+
*
|
|
733
|
+
* `chainOrder` is reset to `[0, 1, …, patterns.length - 1]`.
|
|
734
|
+
*/
|
|
735
|
+
setPatterns(patterns: PatternInput[]): this;
|
|
736
|
+
/** Current chain order: indices into the patterns array, in playback order. */
|
|
737
|
+
get chainOrder(): number[];
|
|
738
|
+
/**
|
|
739
|
+
* Set a new chain order. Each entry must be a valid pattern index.
|
|
740
|
+
* Throws if `order` is empty or contains an out-of-range index.
|
|
741
|
+
*/
|
|
742
|
+
set chainOrder(order: number[]);
|
|
743
|
+
/**
|
|
744
|
+
* Set a track's multiplicative volume scalar. Affects every note dispatched
|
|
745
|
+
* by the track from the next flush onwards. No-op if no track has the
|
|
746
|
+
* given id. Search is scoped to the currently-playing pattern.
|
|
747
|
+
*/
|
|
748
|
+
setTrackVolume(id: string, volume: number): this;
|
|
749
|
+
/** Mute a track by id. No-op if no track has the given id. */
|
|
750
|
+
muteTrack(id: string): this;
|
|
751
|
+
/** Unmute a track by id. No-op if no track has the given id. */
|
|
752
|
+
unmuteTrack(id: string): this;
|
|
753
|
+
/** Solo a track by id. While any track is soloed, non-soloed tracks are silenced. */
|
|
754
|
+
soloTrack(id: string): this;
|
|
755
|
+
/** Remove the solo flag from a track. */
|
|
756
|
+
unsoloTrack(id: string): this;
|
|
757
|
+
/**
|
|
758
|
+
* Locate a track by id, scoped to the currently-playing pattern.
|
|
759
|
+
*/
|
|
760
|
+
private _findTrack;
|
|
761
|
+
private _setTrackFlag;
|
|
762
|
+
private _buildTrack;
|
|
763
|
+
private _currentPattern;
|
|
764
|
+
private _assertImplicitPattern;
|
|
765
|
+
private _computePatternTotalTicks;
|
|
609
766
|
get state(): TransportState;
|
|
610
767
|
/**
|
|
611
768
|
* Start playback from `offsetTick`, or resume from pause if no offset given.
|
|
@@ -625,8 +782,8 @@ declare class Sequencer {
|
|
|
625
782
|
togglePlayPause(): this;
|
|
626
783
|
get bpm(): number;
|
|
627
784
|
set bpm(value: number);
|
|
628
|
-
get timeSignature():
|
|
629
|
-
set timeSignature(value: number);
|
|
785
|
+
get timeSignature(): TimeSignature;
|
|
786
|
+
set timeSignature(value: number | TimeSignature);
|
|
630
787
|
/** Current transport position as "bar:beat:tick" (1-indexed). */
|
|
631
788
|
get position(): string;
|
|
632
789
|
/**
|
|
@@ -639,7 +796,10 @@ declare class Sequencer {
|
|
|
639
796
|
/** Loop start in ticks. */
|
|
640
797
|
get loopStart(): number;
|
|
641
798
|
set loopStart(value: string | number);
|
|
642
|
-
/**
|
|
799
|
+
/**
|
|
800
|
+
* Loop end in ticks for the currently-playing pattern. Defaults to the end
|
|
801
|
+
* of the pattern's longest track.
|
|
802
|
+
*/
|
|
643
803
|
get loopEnd(): number;
|
|
644
804
|
set loopEnd(value: string | number);
|
|
645
805
|
/**
|
|
@@ -658,19 +818,20 @@ declare class Sequencer {
|
|
|
658
818
|
/**
|
|
659
819
|
* Listen to a sequencer event.
|
|
660
820
|
*
|
|
661
|
-
* | Event
|
|
662
|
-
*
|
|
663
|
-
* | "statechange"
|
|
664
|
-
* | "start"
|
|
665
|
-
* | "stop"
|
|
666
|
-
* | "pause"
|
|
667
|
-
* | "end"
|
|
668
|
-
* | "loop"
|
|
669
|
-
* | "
|
|
670
|
-
* | "
|
|
671
|
-
* | "
|
|
672
|
-
* | "
|
|
673
|
-
* | "
|
|
821
|
+
* | Event | Args |
|
|
822
|
+
* |-----------------|---------------------------------------------------|
|
|
823
|
+
* | "statechange" | (state: "playing" \| "paused" \| "stopped") |
|
|
824
|
+
* | "start" | |
|
|
825
|
+
* | "stop" | |
|
|
826
|
+
* | "pause" | |
|
|
827
|
+
* | "end" | |
|
|
828
|
+
* | "loop" | |
|
|
829
|
+
* | "patternChange" | (patternIndex: number, time: number) |
|
|
830
|
+
* | "beat" | (beat: number, time: number) |
|
|
831
|
+
* | "bar" | (bar: number, time: number) |
|
|
832
|
+
* | "step" | (stepIndex: number, time: number) |
|
|
833
|
+
* | "noteOn" | (event: SequencerNoteEvent) |
|
|
834
|
+
* | "noteOff" | (event: SequencerNoteEvent) |
|
|
674
835
|
*/
|
|
675
836
|
on(event: string, callback: (...args: any[]) => void): this;
|
|
676
837
|
off(event: string, callback: (...args: any[]) => void): this;
|
|
@@ -683,8 +844,6 @@ declare class Sequencer {
|
|
|
683
844
|
private _emit;
|
|
684
845
|
/** Emit both the specific state event ("start"/"pause"/"stop") and the unified "statechange" event. */
|
|
685
846
|
private _emitStateChange;
|
|
686
|
-
/** Recompute _totalTicks from all track notes (at + duration). */
|
|
687
|
-
private _recomputeTotalTicks;
|
|
688
847
|
/** Format a raw tick count as "bar:beat:tick" (all 1-indexed). */
|
|
689
848
|
private _tickToPosition;
|
|
690
849
|
/**
|
|
@@ -693,6 +852,8 @@ declare class Sequencer {
|
|
|
693
852
|
*/
|
|
694
853
|
private _resetRepeatEvents;
|
|
695
854
|
}
|
|
855
|
+
declare const Sequencer: Constructable<[context: BaseAudioContext, options?: SequencerOptions | undefined], SequencerImpl>;
|
|
856
|
+
type Sequencer = ReturnType<typeof Sequencer>;
|
|
696
857
|
|
|
697
858
|
declare function getElectricPianoNames(): string[];
|
|
698
859
|
type ElectricPianoOptions = Partial<{
|
|
@@ -700,6 +861,8 @@ type ElectricPianoOptions = Partial<{
|
|
|
700
861
|
storage: Storage;
|
|
701
862
|
destination: AudioNode;
|
|
702
863
|
volume: number;
|
|
864
|
+
/** Stereo pan position (-1 = full left, 0 = centre, +1 = full right). */
|
|
865
|
+
pan: number;
|
|
703
866
|
velocity: number;
|
|
704
867
|
onLoadProgress: (progress: LoadProgress) => void;
|
|
705
868
|
/** Audio formats to try, in order of preference. Defaults to ["ogg", "m4a"]. */
|
|
@@ -710,6 +873,8 @@ declare const ElectricPiano: InstrumentFactory<Partial<{
|
|
|
710
873
|
storage: Storage;
|
|
711
874
|
destination: AudioNode;
|
|
712
875
|
volume: number;
|
|
876
|
+
/** Stereo pan position (-1 = full left, 0 = centre, +1 = full right). */
|
|
877
|
+
pan: number;
|
|
713
878
|
velocity: number;
|
|
714
879
|
onLoadProgress: (progress: LoadProgress) => void;
|
|
715
880
|
/** Audio formats to try, in order of preference. Defaults to ["ogg", "m4a"]. */
|
|
@@ -732,6 +897,8 @@ type VersilianConfig = {
|
|
|
732
897
|
type VersilianOptions = Partial<VersilianConfig & {
|
|
733
898
|
destination?: AudioNode;
|
|
734
899
|
volume?: number;
|
|
900
|
+
/** Stereo pan position (-1 = full left, 0 = centre, +1 = full right). */
|
|
901
|
+
pan?: number;
|
|
735
902
|
velocity?: number;
|
|
736
903
|
onLoadProgress?: (progress: LoadProgress) => void;
|
|
737
904
|
}>;
|
|
@@ -744,6 +911,8 @@ type VersilianOptions = Partial<VersilianConfig & {
|
|
|
744
911
|
declare const Versilian: InstrumentFactory<Partial<VersilianConfig & {
|
|
745
912
|
destination?: AudioNode;
|
|
746
913
|
volume?: number;
|
|
914
|
+
/** Stereo pan position (-1 = full left, 0 = centre, +1 = full right). */
|
|
915
|
+
pan?: number;
|
|
747
916
|
velocity?: number;
|
|
748
917
|
onLoadProgress?: (progress: LoadProgress) => void;
|
|
749
918
|
}>, {}>;
|
|
@@ -760,6 +929,7 @@ declare function getMalletNames(): string[];
|
|
|
760
929
|
declare const Mallet: InstrumentFactory<Partial<VersilianConfig & {
|
|
761
930
|
destination?: AudioNode;
|
|
762
931
|
volume?: number;
|
|
932
|
+
pan?: number;
|
|
763
933
|
velocity?: number;
|
|
764
934
|
onLoadProgress?: (progress: LoadProgress) => void;
|
|
765
935
|
}>, {}>;
|
|
@@ -775,6 +945,8 @@ type MellotronConfig = {
|
|
|
775
945
|
type MellotronOptions = Partial<MellotronConfig & {
|
|
776
946
|
destination?: AudioNode;
|
|
777
947
|
volume?: number;
|
|
948
|
+
/** Stereo pan position (-1 = full left, 0 = centre, +1 = full right). */
|
|
949
|
+
pan?: number;
|
|
778
950
|
velocity?: number;
|
|
779
951
|
decayTime?: number;
|
|
780
952
|
onLoadProgress?: (progress: LoadProgress) => void;
|
|
@@ -782,6 +954,8 @@ type MellotronOptions = Partial<MellotronConfig & {
|
|
|
782
954
|
declare const Mellotron: InstrumentFactory<Partial<MellotronConfig & {
|
|
783
955
|
destination?: AudioNode;
|
|
784
956
|
volume?: number;
|
|
957
|
+
/** Stereo pan position (-1 = full left, 0 = centre, +1 = full right). */
|
|
958
|
+
pan?: number;
|
|
785
959
|
velocity?: number;
|
|
786
960
|
decayTime?: number;
|
|
787
961
|
onLoadProgress?: (progress: LoadProgress) => void;
|
|
@@ -793,17 +967,17 @@ type MellotronJsonConfig = {
|
|
|
793
967
|
variation?: string;
|
|
794
968
|
};
|
|
795
969
|
/**
|
|
796
|
-
* Convert a Mellotron files.json sample list to
|
|
970
|
+
* Convert a Mellotron files.json sample list to SmplrPreset.
|
|
797
971
|
*
|
|
798
972
|
* - Filters by variation string if provided.
|
|
799
973
|
* - Extracts MIDI from the first word of each sample name.
|
|
800
974
|
* - Uses spreadKeyRanges so nearby notes pitch-shift to the nearest sample.
|
|
801
975
|
* - All regions get loopAuto to produce tape-loop playback.
|
|
802
976
|
*/
|
|
803
|
-
declare function
|
|
977
|
+
declare function mellotronToPreset(sampleNames: string[], config: MellotronJsonConfig): SmplrPreset;
|
|
804
978
|
|
|
805
979
|
declare const PARAMS: readonly ["preDelay", "bandwidth", "inputDiffusion1", "inputDiffusion2", "decay", "decayDiffusion1", "decayDiffusion2", "damping", "excursionRate", "excursionDepth", "wet", "dry"];
|
|
806
|
-
declare class
|
|
980
|
+
declare class ReverbImpl {
|
|
807
981
|
#private;
|
|
808
982
|
readonly input: AudioNode;
|
|
809
983
|
constructor(context: AudioContext);
|
|
@@ -813,6 +987,8 @@ declare class Reverb {
|
|
|
813
987
|
ready(): Promise<this>;
|
|
814
988
|
connect(output: AudioNode): void;
|
|
815
989
|
}
|
|
990
|
+
declare const Reverb: Constructable<[context: AudioContext], ReverbImpl>;
|
|
991
|
+
type Reverb = ReturnType<typeof Reverb>;
|
|
816
992
|
|
|
817
993
|
type AudioBuffers = Record<string | number, AudioBuffer | undefined>;
|
|
818
994
|
/**
|
|
@@ -820,26 +996,41 @@ type AudioBuffers = Record<string | number, AudioBuffer | undefined>;
|
|
|
820
996
|
*/
|
|
821
997
|
type AudioBuffersLoader = (context: BaseAudioContext, buffers: AudioBuffers) => Promise<void>;
|
|
822
998
|
|
|
823
|
-
type
|
|
999
|
+
type SamplerBase = {
|
|
824
1000
|
storage?: Storage;
|
|
825
|
-
detune
|
|
826
|
-
volume
|
|
827
|
-
|
|
1001
|
+
detune?: number;
|
|
1002
|
+
volume?: number;
|
|
1003
|
+
pan?: number;
|
|
1004
|
+
velocity?: number;
|
|
828
1005
|
decayTime?: number;
|
|
829
1006
|
lpfCutoffHz?: number;
|
|
830
|
-
destination
|
|
831
|
-
|
|
832
|
-
volumeToGain: (volume: number) => number;
|
|
1007
|
+
destination?: AudioNode;
|
|
1008
|
+
volumeToGain?: (volume: number) => number;
|
|
833
1009
|
onLoadProgress?: (progress: LoadProgress) => void;
|
|
834
1010
|
};
|
|
1011
|
+
type SamplerBuffers = Record<string | number, string | AudioBuffer | AudioBuffers> | AudioBuffersLoader;
|
|
1012
|
+
type SamplerBuffersInput = {
|
|
1013
|
+
buffers?: SamplerBuffers;
|
|
1014
|
+
preset?: never;
|
|
1015
|
+
};
|
|
1016
|
+
type SamplerPresetInput = {
|
|
1017
|
+
preset: SmplrPreset;
|
|
1018
|
+
buffers?: never;
|
|
1019
|
+
};
|
|
1020
|
+
type SamplerConfig = SamplerBase & (SamplerBuffersInput | SamplerPresetInput);
|
|
1021
|
+
/** Input accepted by {@link Sampler.reload}: a `SmplrPreset` schema or a flat buffers record/loader. */
|
|
1022
|
+
type SamplerReloadInput = SmplrPreset | SamplerBuffers;
|
|
1023
|
+
type SamplerExtras = {
|
|
1024
|
+
reload: (input: SamplerReloadInput) => Promise<void>;
|
|
1025
|
+
};
|
|
835
1026
|
type SamplerJsonOptions = Pick<SamplerConfig, "decayTime" | "lpfCutoffHz" | "detune">;
|
|
836
1027
|
type InternalConvertResult = {
|
|
837
|
-
json:
|
|
1028
|
+
json: SmplrPreset;
|
|
838
1029
|
urlMap: Record<string, string>;
|
|
839
1030
|
preloaded: Map<string, AudioBuffer>;
|
|
840
1031
|
};
|
|
841
1032
|
/**
|
|
842
|
-
* Convert a flat source Record to
|
|
1033
|
+
* Convert a flat source Record to SmplrPreset + separated URL map + pre-loaded buffers.
|
|
843
1034
|
*
|
|
844
1035
|
* - Keys that are valid MIDI names/numbers → MIDI-mapped regions.
|
|
845
1036
|
* If ALL keys are MIDI-parseable, spread key ranges (pitch-shifting).
|
|
@@ -848,11 +1039,18 @@ type InternalConvertResult = {
|
|
|
848
1039
|
* - AudioBuffer values → pre-loaded map (no fetch).
|
|
849
1040
|
* - String URL values → urlMap (fetched asynchronously by caller).
|
|
850
1041
|
*/
|
|
851
|
-
declare function
|
|
1042
|
+
declare function samplerToPreset(source: Record<string | number, string | AudioBuffer>, options?: Partial<SamplerJsonOptions>): InternalConvertResult;
|
|
852
1043
|
/**
|
|
853
|
-
* A Sampler instrument.
|
|
1044
|
+
* A Sampler instrument. Accepts either a flat record of samples
|
|
1045
|
+
* (`{ buffers: { C4: "url" } }`) or a full `SmplrPreset`
|
|
1046
|
+
* (`{ preset: { samples, groups, ... } }`) for advanced use cases including
|
|
1047
|
+
* per-region pitch/velocity/round-robin control.
|
|
1048
|
+
*
|
|
1049
|
+
* Use `sampler.reload(input)` to swap content at runtime. `reload` accepts
|
|
1050
|
+
* either shape (flat record or `SmplrPreset`), regardless of which mode was
|
|
1051
|
+
* used at construction.
|
|
854
1052
|
*/
|
|
855
|
-
declare const Sampler: InstrumentFactory<
|
|
1053
|
+
declare const Sampler: InstrumentFactory<SamplerConfig, SamplerExtras>;
|
|
856
1054
|
/** Instance type returned by the {@link Sampler} factory. */
|
|
857
1055
|
type Sampler = ReturnType<typeof Sampler>;
|
|
858
1056
|
|
|
@@ -864,12 +1062,16 @@ type SmolkenConfig = {
|
|
|
864
1062
|
type SmolkenOptions = Partial<SmolkenConfig & {
|
|
865
1063
|
destination?: AudioNode;
|
|
866
1064
|
volume?: number;
|
|
1065
|
+
/** Stereo pan position (-1 = full left, 0 = centre, +1 = full right). */
|
|
1066
|
+
pan?: number;
|
|
867
1067
|
velocity?: number;
|
|
868
1068
|
onLoadProgress?: (progress: LoadProgress) => void;
|
|
869
1069
|
}>;
|
|
870
1070
|
declare const Smolken: InstrumentFactory<Partial<SmolkenConfig & {
|
|
871
1071
|
destination?: AudioNode;
|
|
872
1072
|
volume?: number;
|
|
1073
|
+
/** Stereo pan position (-1 = full left, 0 = centre, +1 = full right). */
|
|
1074
|
+
pan?: number;
|
|
873
1075
|
velocity?: number;
|
|
874
1076
|
onLoadProgress?: (progress: LoadProgress) => void;
|
|
875
1077
|
}>, {}>;
|
|
@@ -892,22 +1094,26 @@ type SoundfontConfig = {
|
|
|
892
1094
|
type SoundfontOptions = Partial<SoundfontConfig & {
|
|
893
1095
|
destination?: AudioNode;
|
|
894
1096
|
volume?: number;
|
|
1097
|
+
/** Stereo pan position (-1 = full left, 0 = centre, +1 = full right). */
|
|
1098
|
+
pan?: number;
|
|
895
1099
|
velocity?: number;
|
|
896
1100
|
onLoadProgress?: (progress: LoadProgress) => void;
|
|
897
1101
|
}>;
|
|
898
1102
|
declare const Soundfont: InstrumentFactory<Partial<SoundfontConfig & {
|
|
899
1103
|
destination?: AudioNode;
|
|
900
1104
|
volume?: number;
|
|
1105
|
+
/** Stereo pan position (-1 = full left, 0 = centre, +1 = full right). */
|
|
1106
|
+
pan?: number;
|
|
901
1107
|
velocity?: number;
|
|
902
1108
|
onLoadProgress?: (progress: LoadProgress) => void;
|
|
903
1109
|
}>, {}>;
|
|
904
1110
|
/** Instance type returned by the {@link Soundfont} factory. */
|
|
905
1111
|
type Soundfont = ReturnType<typeof Soundfont>;
|
|
906
1112
|
/**
|
|
907
|
-
* Convert a list of note names (with optional loop data) to
|
|
1113
|
+
* Convert a list of note names (with optional loop data) to SmplrPreset.
|
|
908
1114
|
* Uses spreadKeyRanges so notes between recorded pitches pitch-shift correctly.
|
|
909
1115
|
*/
|
|
910
|
-
declare function
|
|
1116
|
+
declare function soundfontToPreset(noteNames: string[], loopData?: LoopData): SmplrPreset;
|
|
911
1117
|
|
|
912
1118
|
type Sf2 = {
|
|
913
1119
|
instruments: Sf2Instrument[];
|
|
@@ -943,19 +1149,25 @@ type Soundfont2Options = {
|
|
|
943
1149
|
createSoundfont: (data: Uint8Array) => Sf2;
|
|
944
1150
|
destination?: AudioNode;
|
|
945
1151
|
volume?: number;
|
|
1152
|
+
/** Stereo pan position (-1 = full left, 0 = centre, +1 = full right). */
|
|
1153
|
+
pan?: number;
|
|
946
1154
|
velocity?: number;
|
|
947
1155
|
};
|
|
948
|
-
declare function
|
|
949
|
-
json:
|
|
1156
|
+
declare function sf2InstrumentToPreset(sf2Instrument: Sf2Instrument, context: BaseAudioContext): {
|
|
1157
|
+
json: SmplrPreset;
|
|
950
1158
|
buffers: Map<string, AudioBuffer>;
|
|
951
1159
|
};
|
|
952
1160
|
type Soundfont2SamplerExtras = {
|
|
953
1161
|
readonly instrumentNames: string[];
|
|
954
1162
|
loadInstrument(instrumentName: string): Promise<void> | undefined;
|
|
955
1163
|
};
|
|
1164
|
+
declare const Soundfont2: InstrumentFactory<Soundfont2Options, Soundfont2SamplerExtras>;
|
|
1165
|
+
/** Instance type returned by the {@link Soundfont2} factory. */
|
|
1166
|
+
type Soundfont2 = ReturnType<typeof Soundfont2>;
|
|
1167
|
+
/** @deprecated Use `Soundfont2` instead. */
|
|
956
1168
|
declare const Soundfont2Sampler: InstrumentFactory<Soundfont2Options, Soundfont2SamplerExtras>;
|
|
957
|
-
/**
|
|
958
|
-
type Soundfont2Sampler =
|
|
1169
|
+
/** @deprecated Use `Soundfont2` instead. */
|
|
1170
|
+
type Soundfont2Sampler = Soundfont2;
|
|
959
1171
|
|
|
960
1172
|
/**
|
|
961
1173
|
* Configuration options for SplendidGrandPiano.
|
|
@@ -967,12 +1179,14 @@ type SplendidGrandPianoConfig = {
|
|
|
967
1179
|
detune: number;
|
|
968
1180
|
/** Default velocity (0–127) when not specified per note. */
|
|
969
1181
|
velocity: number;
|
|
970
|
-
/** Release time in seconds. Maps to
|
|
1182
|
+
/** Release time in seconds. Maps to SmplrPreset defaults.ampRelease. */
|
|
971
1183
|
decayTime: number;
|
|
972
1184
|
/** Destination audio node. Defaults to context.destination. */
|
|
973
1185
|
destination?: AudioNode;
|
|
974
1186
|
/** Master volume (0–127 MIDI scale). */
|
|
975
1187
|
volume?: number;
|
|
1188
|
+
/** Stereo pan position (-1 = full left, 0 = centre, +1 = full right). */
|
|
1189
|
+
pan?: number;
|
|
976
1190
|
/** Called after each buffer is loaded or served from cache. */
|
|
977
1191
|
onLoadProgress?: (progress: LoadProgress) => void;
|
|
978
1192
|
/** Audio formats to try, in order of preference. Defaults to ["ogg", "m4a"]. */
|
|
@@ -988,7 +1202,7 @@ declare const SplendidGrandPiano: InstrumentFactory<Partial<SplendidGrandPianoCo
|
|
|
988
1202
|
type SplendidGrandPiano = ReturnType<typeof SplendidGrandPiano>;
|
|
989
1203
|
type PianoJsonOptions = Pick<SplendidGrandPianoConfig, "baseUrl" | "detune" | "decayTime" | "notesToLoad" | "formats">;
|
|
990
1204
|
/**
|
|
991
|
-
* Convert the LAYERS array and user options into a
|
|
1205
|
+
* Convert the LAYERS array and user options into a SmplrPreset descriptor.
|
|
992
1206
|
*
|
|
993
1207
|
* Each layer becomes a SmplrGroup with its velRange. If `notesToLoad` is
|
|
994
1208
|
* specified, layers and samples are filtered accordingly. The PPP layer
|
|
@@ -997,7 +1211,7 @@ type PianoJsonOptions = Pick<SplendidGrandPianoConfig, "baseUrl" | "detune" | "d
|
|
|
997
1211
|
* `spreadKeyRanges` is used to pre-compute which key range each sample
|
|
998
1212
|
* covers, replacing the old on-the-fly `findNearestMidiInLayer` logic.
|
|
999
1213
|
*/
|
|
1000
|
-
declare function
|
|
1214
|
+
declare function pianoToPreset(options: PianoJsonOptions): SmplrPreset;
|
|
1001
1215
|
declare const LAYERS: ({
|
|
1002
1216
|
name: string;
|
|
1003
1217
|
vel_range: number[];
|
|
@@ -1010,4 +1224,4 @@ declare const LAYERS: ({
|
|
|
1010
1224
|
cutoff?: undefined;
|
|
1011
1225
|
})[];
|
|
1012
1226
|
|
|
1013
|
-
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
|
|
1227
|
+
export { type AddTrackOptions, CacheStorage, DrumMachine, type DrumMachineOptions, ElectricPiano, type ElectricPianoOptions, HttpStorage, Instrument, LAYERS, type LoadProgress, Mallet, Mellotron, type MellotronConfig, type MellotronOptions, NAME_TO_PATH, type NoteEvent, type PatternInput, 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, Soundfont2, type Soundfont2Options, Soundfont2Sampler, type SoundfontOptions, SplendidGrandPiano, type SplendidGrandPianoConfig, type StopFn, type StopTarget, type Storage, type StorageResponse, type TimeSignature, 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 };
|