smplr 0.18.1 → 0.20.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 +78 -0
- package/dist/index.d.mts +256 -16
- package/dist/index.d.ts +256 -16
- package/dist/index.js +237 -19
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +229 -18
- package/dist/index.mjs.map +1 -1
- package/package.json +6 -6
package/README.md
CHANGED
|
@@ -522,6 +522,84 @@ const seq = new Sequencer(context, {
|
|
|
522
522
|
|
|
523
523
|
---
|
|
524
524
|
|
|
525
|
+
## Export Audio
|
|
526
|
+
|
|
527
|
+
Render audio offline (faster than real-time) and export it as a WAV file. Uses `OfflineAudioContext` under the hood.
|
|
528
|
+
|
|
529
|
+
```js
|
|
530
|
+
import { renderOffline } from "smplr";
|
|
531
|
+
|
|
532
|
+
const result = await renderOffline(async (context) => {
|
|
533
|
+
const piano = await new SplendidGrandPiano(context).load;
|
|
534
|
+
piano.start({ note: "C4", time: 0, duration: 1 });
|
|
535
|
+
piano.start({ note: "E4", time: 0.5, duration: 1 });
|
|
536
|
+
});
|
|
537
|
+
|
|
538
|
+
result.downloadWav("export.wav");
|
|
539
|
+
```
|
|
540
|
+
|
|
541
|
+
#### Options
|
|
542
|
+
|
|
543
|
+
```js
|
|
544
|
+
const result = await renderOffline(callback, {
|
|
545
|
+
duration: 10, // Total duration in seconds (auto-detected if omitted)
|
|
546
|
+
sampleRate: 48000, // Sample rate (default: 48000)
|
|
547
|
+
channels: 2, // Number of channels (default: 2)
|
|
548
|
+
});
|
|
549
|
+
```
|
|
550
|
+
|
|
551
|
+
When `duration` is omitted, a 60-second buffer is used and trailing silence is automatically trimmed. Pass an explicit `duration` for longer renders or to preserve trailing silence.
|
|
552
|
+
|
|
553
|
+
#### RenderResult
|
|
554
|
+
|
|
555
|
+
`renderOffline` returns a `RenderResult` object:
|
|
556
|
+
|
|
557
|
+
- `result.audioBuffer` — the raw `AudioBuffer`
|
|
558
|
+
- `result.toWav()` — encode as 32-bit float WAV `Blob` (lossless)
|
|
559
|
+
- `result.toWav16()` — encode as 16-bit integer WAV `Blob` (smaller file)
|
|
560
|
+
- `result.downloadWav(filename?)` — download as 32-bit WAV
|
|
561
|
+
- `result.downloadWav16(filename?)` — download as 16-bit WAV
|
|
562
|
+
- `result.duration` — actual duration in seconds
|
|
563
|
+
- `result.sampleRate` — sample rate used
|
|
564
|
+
|
|
565
|
+
WAV encoding is lazy — it only happens when you call `toWav()` or `toWav16()`.
|
|
566
|
+
|
|
567
|
+
#### Buffer reuse
|
|
568
|
+
|
|
569
|
+
If you already have an instrument loaded, pass the same `SampleLoader` to avoid re-fetching samples:
|
|
570
|
+
|
|
571
|
+
```js
|
|
572
|
+
import { SplendidGrandPiano, SampleLoader, renderOffline } from "smplr";
|
|
573
|
+
|
|
574
|
+
const loader = new SampleLoader(audioContext);
|
|
575
|
+
const piano = new SplendidGrandPiano(audioContext, { loader });
|
|
576
|
+
await piano.load;
|
|
577
|
+
|
|
578
|
+
// Offline render reuses cached buffers — no re-fetch
|
|
579
|
+
const result = await renderOffline(async (context) => {
|
|
580
|
+
const offlinePiano = await new SplendidGrandPiano(context, { loader }).load;
|
|
581
|
+
offlinePiano.start({ note: "C4", time: 0, duration: 1 });
|
|
582
|
+
});
|
|
583
|
+
```
|
|
584
|
+
|
|
585
|
+
#### Bug reports
|
|
586
|
+
|
|
587
|
+
Use offline rendering to generate reproducible audio files for issue reports. No install needed — just open your browser's DevTools console on any page and paste:
|
|
588
|
+
|
|
589
|
+
```js
|
|
590
|
+
const { renderOffline, SplendidGrandPiano } = await import("https://esm.sh/smplr");
|
|
591
|
+
|
|
592
|
+
const result = await renderOffline(async (context) => {
|
|
593
|
+
const piano = await new SplendidGrandPiano(context).load;
|
|
594
|
+
piano.start({ note: "C4", time: 0, duration: 2 });
|
|
595
|
+
});
|
|
596
|
+
result.downloadWav16("bug-report.wav");
|
|
597
|
+
```
|
|
598
|
+
|
|
599
|
+
This will download a WAV file you can attach to your issue or pull request.
|
|
600
|
+
|
|
601
|
+
---
|
|
602
|
+
|
|
525
603
|
## Instruments
|
|
526
604
|
|
|
527
605
|
### Sampler
|
package/dist/index.d.mts
CHANGED
|
@@ -7,6 +7,7 @@ type ChannelConfig = {
|
|
|
7
7
|
destination: AudioNode;
|
|
8
8
|
volume: number;
|
|
9
9
|
volumeToGain: (volume: number) => number;
|
|
10
|
+
pan?: number;
|
|
10
11
|
};
|
|
11
12
|
type OutputChannel = Omit<Channel, "input">;
|
|
12
13
|
/**
|
|
@@ -19,6 +20,8 @@ declare class Channel {
|
|
|
19
20
|
readonly setVolume: (vol: number) => void;
|
|
20
21
|
readonly input: AudioNode;
|
|
21
22
|
constructor(context: BaseAudioContext, options?: Partial<ChannelConfig>);
|
|
23
|
+
get pan(): number;
|
|
24
|
+
set pan(value: number);
|
|
22
25
|
addInsert(effect: AudioNode | AudioInsert): void;
|
|
23
26
|
addEffect(name: string, effect: AudioNode | {
|
|
24
27
|
input: AudioNode;
|
|
@@ -58,6 +61,7 @@ type PlaybackParams = {
|
|
|
58
61
|
loop?: boolean;
|
|
59
62
|
loopStart?: number;
|
|
60
63
|
loopEnd?: number;
|
|
64
|
+
reverse?: boolean;
|
|
61
65
|
};
|
|
62
66
|
/**
|
|
63
67
|
* An individual sample region. Maps a sample to a range of notes and velocities.
|
|
@@ -122,7 +126,7 @@ type SmplrJson = {
|
|
|
122
126
|
/**
|
|
123
127
|
* A note event passed to Smplr.start(). Can be a full object, a note name, or a MIDI number.
|
|
124
128
|
*/
|
|
125
|
-
type NoteEvent
|
|
129
|
+
type NoteEvent = {
|
|
126
130
|
note: string | number;
|
|
127
131
|
velocity?: number;
|
|
128
132
|
time?: number;
|
|
@@ -132,8 +136,9 @@ type NoteEvent$1 = {
|
|
|
132
136
|
loop?: boolean;
|
|
133
137
|
ampRelease?: number;
|
|
134
138
|
stopId?: string | number;
|
|
135
|
-
onStart?: (event: NoteEvent
|
|
136
|
-
onEnded?: (event: NoteEvent
|
|
139
|
+
onStart?: (event: NoteEvent) => void;
|
|
140
|
+
onEnded?: (event: NoteEvent) => void;
|
|
141
|
+
reverse?: boolean;
|
|
137
142
|
} | string | number;
|
|
138
143
|
/**
|
|
139
144
|
* Target for Smplr.stop(). Can be a full object, a stopId, or a MIDI number.
|
|
@@ -153,6 +158,166 @@ type LoadProgress = {
|
|
|
153
158
|
loaded: number;
|
|
154
159
|
total: number;
|
|
155
160
|
};
|
|
161
|
+
/**
|
|
162
|
+
* Fully resolved playback parameters for a single Voice.
|
|
163
|
+
* Output of resolveParams() — all fields are required, no optionals except ampVelCurve/loopAuto.
|
|
164
|
+
*/
|
|
165
|
+
type VoiceParams = {
|
|
166
|
+
detune: number;
|
|
167
|
+
velocity: number;
|
|
168
|
+
volume: number;
|
|
169
|
+
ampRelease: number;
|
|
170
|
+
ampAttack: number;
|
|
171
|
+
lpfCutoffHz: number;
|
|
172
|
+
offset: number;
|
|
173
|
+
loop: boolean;
|
|
174
|
+
loopStart: number;
|
|
175
|
+
loopEnd: number;
|
|
176
|
+
ampVelCurve?: [number, number];
|
|
177
|
+
/** If set, loop points are computed from buffer.duration at play time. */
|
|
178
|
+
loopAuto?: {
|
|
179
|
+
startRatio: number;
|
|
180
|
+
endRatio: number;
|
|
181
|
+
};
|
|
182
|
+
reverse?: boolean;
|
|
183
|
+
};
|
|
184
|
+
|
|
185
|
+
/**
|
|
186
|
+
* Loads and caches AudioBuffers for all samples referenced in a SmplrJson.
|
|
187
|
+
*
|
|
188
|
+
* The cache is keyed by resolved URL, so the same audio file is never fetched
|
|
189
|
+
* or decoded twice. Multiple Smplr instances can share one SampleLoader by
|
|
190
|
+
* passing it via SmplrOptions.loader.
|
|
191
|
+
*/
|
|
192
|
+
declare class SampleLoader {
|
|
193
|
+
#private;
|
|
194
|
+
constructor(context: BaseAudioContext, options?: {
|
|
195
|
+
storage?: Storage;
|
|
196
|
+
});
|
|
197
|
+
/**
|
|
198
|
+
* Load all samples referenced in `json`. Returns a Map of sample name →
|
|
199
|
+
* AudioBuffer. Progress is reported via `onProgress` callback or via
|
|
200
|
+
* options object.
|
|
201
|
+
*
|
|
202
|
+
* - `buffers` in options: pre-loaded buffers — skips fetch for these names.
|
|
203
|
+
* - All samples load in parallel. Failed samples are silently omitted.
|
|
204
|
+
*/
|
|
205
|
+
load(json: SmplrJson, onProgressOrOptions?: ((loaded: number, total: number) => void) | {
|
|
206
|
+
buffers?: Map<string, AudioBuffer>;
|
|
207
|
+
onProgress?: (loaded: number, total: number) => void;
|
|
208
|
+
}): Promise<Map<string, AudioBuffer>>;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
/**
|
|
212
|
+
* Standalone scheduler. Dispatches NoteEvents immediately when they fall within the
|
|
213
|
+
* lookahead window, or queues them for future dispatch via a self-managing interval.
|
|
214
|
+
*
|
|
215
|
+
* Multiple Smplr instances can share a single Scheduler for coordinated timing.
|
|
216
|
+
*/
|
|
217
|
+
declare class Scheduler {
|
|
218
|
+
#private;
|
|
219
|
+
constructor(context: BaseAudioContext, options?: {
|
|
220
|
+
lookaheadMs?: number;
|
|
221
|
+
intervalMs?: number;
|
|
222
|
+
});
|
|
223
|
+
/**
|
|
224
|
+
* Schedule a callback for a NoteEvent.
|
|
225
|
+
*
|
|
226
|
+
* - If the event's time falls within the lookahead window (or has no time), the
|
|
227
|
+
* callback is called synchronously and a no-op StopFn is returned.
|
|
228
|
+
* - Otherwise the event is queued, the interval is started if needed, and a StopFn
|
|
229
|
+
* is returned that removes the event from the queue before it is dispatched.
|
|
230
|
+
*/
|
|
231
|
+
schedule(event: NoteEvent, callback: (event: NoteEvent) => void): StopFn;
|
|
232
|
+
/**
|
|
233
|
+
* Clear all queued (not-yet-dispatched) events and stop the interval.
|
|
234
|
+
* Does not affect voices that are already playing.
|
|
235
|
+
*/
|
|
236
|
+
stop(): void;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
type SmplrOptions = {
|
|
240
|
+
/** Custom storage backend for sample fetching (e.g. CacheStorage). */
|
|
241
|
+
storage?: Storage;
|
|
242
|
+
/** Destination audio node. Defaults to context.destination. */
|
|
243
|
+
destination?: AudioNode;
|
|
244
|
+
/** Master volume (0–127 MIDI scale). Defaults to 100. */
|
|
245
|
+
volume?: number;
|
|
246
|
+
/** Custom volume-to-gain mapping function. Defaults to midiVelToGain. */
|
|
247
|
+
volumeToGain?: (volume: number) => number;
|
|
248
|
+
/** Stereo pan position (-1 = full left, 0 = centre, +1 = full right). Defaults to 0. */
|
|
249
|
+
pan?: number;
|
|
250
|
+
/** Default note velocity when not specified in NoteEvent (0–127). Defaults to 100. */
|
|
251
|
+
velocity?: number;
|
|
252
|
+
/** Shared SampleLoader instance. If omitted, a private one is created. */
|
|
253
|
+
loader?: SampleLoader;
|
|
254
|
+
/** Shared Scheduler instance. If omitted, a private one is created. */
|
|
255
|
+
scheduler?: Scheduler;
|
|
256
|
+
/** Called after each buffer is loaded (or served from cache). */
|
|
257
|
+
onLoadProgress?: (progress: LoadProgress) => void;
|
|
258
|
+
/** Called when a note is dispatched to the audio engine (slightly before playback). */
|
|
259
|
+
onStart?: (event: NoteEvent) => void;
|
|
260
|
+
/** Called when each voice's audio node ends. */
|
|
261
|
+
onEnded?: (event: NoteEvent) => void;
|
|
262
|
+
};
|
|
263
|
+
/**
|
|
264
|
+
* The main sampler class. Loads samples described by a SmplrJson descriptor,
|
|
265
|
+
* matches notes to regions, and plays them through a Channel.
|
|
266
|
+
*
|
|
267
|
+
* Multiple Smplr instances can share a SampleLoader (shared cache) and/or a
|
|
268
|
+
* Scheduler (coordinated timing) by passing them via SmplrOptions.
|
|
269
|
+
*
|
|
270
|
+
* Pattern A — json provided at construction:
|
|
271
|
+
* `new Smplr(context, json, options?)`
|
|
272
|
+
*
|
|
273
|
+
* Pattern B — json loaded later via loadInstrument():
|
|
274
|
+
* `new Smplr(context, options?)` then `smplr.loadInstrument(json)`
|
|
275
|
+
*/
|
|
276
|
+
declare class Smplr {
|
|
277
|
+
#private;
|
|
278
|
+
/** Resolves with `this` once all sample buffers are loaded. */
|
|
279
|
+
readonly load: Promise<Smplr>;
|
|
280
|
+
/** The AudioContext (or OfflineAudioContext) passed to the constructor. */
|
|
281
|
+
readonly context: BaseAudioContext;
|
|
282
|
+
constructor(context: BaseAudioContext, json: SmplrJson, options?: SmplrOptions);
|
|
283
|
+
constructor(context: BaseAudioContext, options?: SmplrOptions);
|
|
284
|
+
/**
|
|
285
|
+
* Load (or replace) the instrument descriptor. Creates a new RegionMatcher
|
|
286
|
+
* and fetches all sample buffers. Pre-loaded buffers (e.g. base64-decoded)
|
|
287
|
+
* can be passed via the `buffers` parameter — those skip the fetch step.
|
|
288
|
+
*
|
|
289
|
+
* Returns a Promise that resolves when all samples are ready.
|
|
290
|
+
*/
|
|
291
|
+
loadInstrument(json: SmplrJson, buffers?: Map<string, AudioBuffer>): Promise<void>;
|
|
292
|
+
/** Current loading progress snapshot. `total` is known before loading starts. */
|
|
293
|
+
get loadProgress(): LoadProgress;
|
|
294
|
+
/** The output channel — use to add effects, adjust volume, or route audio. */
|
|
295
|
+
get output(): OutputChannel;
|
|
296
|
+
/**
|
|
297
|
+
* Set a MIDI CC value. Affects region matching for groups/regions that have
|
|
298
|
+
* ccRange constraints (e.g. CC64 sustain pedal).
|
|
299
|
+
*/
|
|
300
|
+
setCC(cc: number, value: number): void;
|
|
301
|
+
/**
|
|
302
|
+
* Start playing a note. Returns a StopFn that cancels the note if it hasn't
|
|
303
|
+
* played yet, or stops the resulting voices if it has.
|
|
304
|
+
*/
|
|
305
|
+
start(event: NoteEvent): StopFn;
|
|
306
|
+
/**
|
|
307
|
+
* Stop voices.
|
|
308
|
+
*
|
|
309
|
+
* - No argument → stop all active voices
|
|
310
|
+
* - String or number → stop all voices with that stopId
|
|
311
|
+
* - `{ stopId }` → stop voices with that stopId, optionally at a future time
|
|
312
|
+
* - `{ time }` (no stopId) → stop all voices at a future time
|
|
313
|
+
*/
|
|
314
|
+
stop(target?: StopTarget): void;
|
|
315
|
+
/**
|
|
316
|
+
* Stop all voices, disconnect the output channel, and stop the scheduler.
|
|
317
|
+
* The instance should not be used after this call.
|
|
318
|
+
*/
|
|
319
|
+
disconnect(): void;
|
|
320
|
+
}
|
|
156
321
|
|
|
157
322
|
/**
|
|
158
323
|
* Given a list of [midi, sampleName] pairs, return one entry per sample with
|
|
@@ -188,6 +353,7 @@ type DrumMachineConfig = {
|
|
|
188
353
|
type DrumMachineOptions = Partial<DrumMachineConfig & {
|
|
189
354
|
destination?: AudioNode;
|
|
190
355
|
volume?: number;
|
|
356
|
+
pan?: number;
|
|
191
357
|
velocity?: number;
|
|
192
358
|
onLoadProgress?: (progress: LoadProgress) => void;
|
|
193
359
|
}>;
|
|
@@ -199,7 +365,7 @@ declare class DrumMachine {
|
|
|
199
365
|
getSampleNames(): string[];
|
|
200
366
|
getGroupNames(): string[];
|
|
201
367
|
getSampleNamesForGroup(groupName: string): string[];
|
|
202
|
-
start(sample: NoteEvent
|
|
368
|
+
start(sample: NoteEvent): StopFn;
|
|
203
369
|
stop(sample?: StopTarget): void;
|
|
204
370
|
disconnect(): void;
|
|
205
371
|
/** @deprecated */
|
|
@@ -218,6 +384,73 @@ declare class DrumMachine {
|
|
|
218
384
|
*/
|
|
219
385
|
declare function drumMachineToSmplrJson(instrument: DrumMachineInstrument): SmplrJson;
|
|
220
386
|
|
|
387
|
+
/**
|
|
388
|
+
* The result of an offline render. Provides the raw AudioBuffer and
|
|
389
|
+
* lazy WAV encoding / download convenience methods.
|
|
390
|
+
*/
|
|
391
|
+
declare class RenderResult {
|
|
392
|
+
#private;
|
|
393
|
+
readonly audioBuffer: AudioBuffer;
|
|
394
|
+
readonly duration: number;
|
|
395
|
+
readonly sampleRate: number;
|
|
396
|
+
constructor(audioBuffer: AudioBuffer);
|
|
397
|
+
/** Encode as 32-bit float WAV. Cached after first call. */
|
|
398
|
+
toWav(): Blob;
|
|
399
|
+
/** Encode as 16-bit integer WAV. Cached after first call. */
|
|
400
|
+
toWav16(): Blob;
|
|
401
|
+
/** Download as 32-bit float WAV file. */
|
|
402
|
+
downloadWav(filename?: string): void;
|
|
403
|
+
/** Download as 16-bit integer WAV file. */
|
|
404
|
+
downloadWav16(filename?: string): void;
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
interface RenderOfflineOptions {
|
|
408
|
+
/** Total duration in seconds. When omitted, uses 60s max and trims trailing silence. */
|
|
409
|
+
duration?: number;
|
|
410
|
+
/** Sample rate. Default: 48000. */
|
|
411
|
+
sampleRate?: number;
|
|
412
|
+
/** Number of output channels. Default: 2 (stereo). */
|
|
413
|
+
channels?: number;
|
|
414
|
+
}
|
|
415
|
+
/**
|
|
416
|
+
* Render audio offline using an OfflineAudioContext.
|
|
417
|
+
*
|
|
418
|
+
* The callback receives an OfflineAudioContext. Create instruments,
|
|
419
|
+
* schedule notes using absolute times (starting from 0), then return.
|
|
420
|
+
* The audio is rendered as fast as possible (not real-time).
|
|
421
|
+
*
|
|
422
|
+
* Returns a RenderResult with the rendered AudioBuffer and
|
|
423
|
+
* convenience methods for WAV encoding and download.
|
|
424
|
+
*
|
|
425
|
+
* @example
|
|
426
|
+
* ```ts
|
|
427
|
+
* const result = await renderOffline(async (context) => {
|
|
428
|
+
* const piano = await new SplendidGrandPiano(context).load;
|
|
429
|
+
* piano.start({ note: "C4", time: 0, duration: 1 });
|
|
430
|
+
* });
|
|
431
|
+
* result.downloadWav("export.wav");
|
|
432
|
+
* ```
|
|
433
|
+
*/
|
|
434
|
+
declare function renderOffline(callback: (context: OfflineAudioContext) => Promise<void>, options?: RenderOfflineOptions): Promise<RenderResult>;
|
|
435
|
+
|
|
436
|
+
/**
|
|
437
|
+
* Encode an AudioBuffer as a WAV file Blob.
|
|
438
|
+
*
|
|
439
|
+
* Supports 32-bit float (lossless) and 16-bit integer (CD quality) formats.
|
|
440
|
+
*/
|
|
441
|
+
/** Encode AudioBuffer as 32-bit float WAV. */
|
|
442
|
+
declare function audioBufferToWav(buffer: AudioBuffer): Blob;
|
|
443
|
+
/** Encode AudioBuffer as 16-bit integer WAV. */
|
|
444
|
+
declare function audioBufferToWav16(buffer: AudioBuffer): Blob;
|
|
445
|
+
|
|
446
|
+
/**
|
|
447
|
+
* Trim trailing silence from an AudioBuffer.
|
|
448
|
+
*
|
|
449
|
+
* Scans all channels from the end to find the last sample above the threshold,
|
|
450
|
+
* then returns a new AudioBuffer trimmed to that length.
|
|
451
|
+
*/
|
|
452
|
+
declare function trimSilence(buffer: AudioBuffer): AudioBuffer;
|
|
453
|
+
|
|
221
454
|
/**
|
|
222
455
|
* TransportClock
|
|
223
456
|
*
|
|
@@ -246,6 +479,8 @@ type SequencerNote = {
|
|
|
246
479
|
/** Note duration: ticks, "4n", "8n", etc. Omit for a one-shot trigger. */
|
|
247
480
|
duration?: string | number;
|
|
248
481
|
velocity?: number;
|
|
482
|
+
/** Probability (0–100) that this note fires on each pass. Default 100 (always). */
|
|
483
|
+
chance?: number;
|
|
249
484
|
};
|
|
250
485
|
/**
|
|
251
486
|
* Any instrument the Sequencer can drive.
|
|
@@ -264,7 +499,7 @@ type SequencerInstrument = {
|
|
|
264
499
|
}): unknown;
|
|
265
500
|
};
|
|
266
501
|
/** Emitted with "noteOn" and "noteOff" events. */
|
|
267
|
-
type
|
|
502
|
+
type SequencerNoteEvent = {
|
|
268
503
|
noteId: string | number;
|
|
269
504
|
trackIndex: number;
|
|
270
505
|
noteIndex: number;
|
|
@@ -286,12 +521,15 @@ type SequencerOptions = {
|
|
|
286
521
|
timingMs?: number;
|
|
287
522
|
velocity?: number;
|
|
288
523
|
};
|
|
524
|
+
/** Emit a "step" event at this interval. Accepts musical notation or ticks: "16n", "8n", ticks, etc. */
|
|
525
|
+
stepSize?: string | number;
|
|
289
526
|
};
|
|
290
527
|
declare class Sequencer {
|
|
291
528
|
private readonly _context;
|
|
292
529
|
private readonly _clock;
|
|
293
530
|
private readonly _ppq;
|
|
294
531
|
private _timeSignature;
|
|
532
|
+
private _stepTicks;
|
|
295
533
|
private _tracks;
|
|
296
534
|
private _repeatEvents;
|
|
297
535
|
private _listeners;
|
|
@@ -377,8 +615,9 @@ declare class Sequencer {
|
|
|
377
615
|
* | "loop" | |
|
|
378
616
|
* | "beat" | (beat: number, time: number) |
|
|
379
617
|
* | "bar" | (bar: number, time: number) |
|
|
380
|
-
* | "
|
|
381
|
-
* | "
|
|
618
|
+
* | "step" | (stepIndex: number, time: number) |
|
|
619
|
+
* | "noteOn" | (event: SequencerNoteEvent) |
|
|
620
|
+
* | "noteOff" | (event: SequencerNoteEvent) |
|
|
382
621
|
*/
|
|
383
622
|
on(event: string, callback: (...args: any[]) => void): this;
|
|
384
623
|
off(event: string, callback: (...args: any[]) => void): this;
|
|
@@ -386,6 +625,7 @@ declare class Sequencer {
|
|
|
386
625
|
private _stopLoop;
|
|
387
626
|
private _flush;
|
|
388
627
|
private _scheduleWindow;
|
|
628
|
+
private _emitStepsInWindow;
|
|
389
629
|
private _emitBeatsInWindow;
|
|
390
630
|
private _emit;
|
|
391
631
|
/** Emit both the specific state event ("start"/"pause"/"stop") and the unified "statechange" event. */
|
|
@@ -424,7 +664,7 @@ declare class ElectricPiano {
|
|
|
424
664
|
});
|
|
425
665
|
get output(): OutputChannel;
|
|
426
666
|
get loadProgress(): LoadProgress;
|
|
427
|
-
start(sample: NoteEvent
|
|
667
|
+
start(sample: NoteEvent | string | number): StopFn;
|
|
428
668
|
stop(target?: StopTarget): void;
|
|
429
669
|
disconnect(): void;
|
|
430
670
|
}
|
|
@@ -453,7 +693,7 @@ declare class Versilian {
|
|
|
453
693
|
constructor(context: BaseAudioContext, options?: VersilianOptions);
|
|
454
694
|
get output(): OutputChannel;
|
|
455
695
|
get loadProgress(): LoadProgress;
|
|
456
|
-
start(sample: NoteEvent
|
|
696
|
+
start(sample: NoteEvent | string | number): StopFn;
|
|
457
697
|
stop(target?: StopTarget): void;
|
|
458
698
|
disconnect(): void;
|
|
459
699
|
}
|
|
@@ -484,7 +724,7 @@ declare class Mellotron {
|
|
|
484
724
|
constructor(context: BaseAudioContext, options?: MellotronOptions);
|
|
485
725
|
get output(): OutputChannel;
|
|
486
726
|
get loadProgress(): LoadProgress;
|
|
487
|
-
start(sample: NoteEvent
|
|
727
|
+
start(sample: NoteEvent | string | number): StopFn;
|
|
488
728
|
stop(target?: StopTarget): void;
|
|
489
729
|
disconnect(): void;
|
|
490
730
|
}
|
|
@@ -542,7 +782,7 @@ declare class Sampler {
|
|
|
542
782
|
constructor(context: AudioContext, options?: Partial<SamplerConfig>);
|
|
543
783
|
loaded(): Promise<this>;
|
|
544
784
|
get output(): OutputChannel;
|
|
545
|
-
start(sample: NoteEvent
|
|
785
|
+
start(sample: NoteEvent | string | number): StopFn;
|
|
546
786
|
stop(sample?: StopTarget | string | number): void;
|
|
547
787
|
disconnect(): void;
|
|
548
788
|
}
|
|
@@ -582,7 +822,7 @@ declare class Smolken {
|
|
|
582
822
|
constructor(context: BaseAudioContext, options?: SmolkenOptions);
|
|
583
823
|
get output(): OutputChannel;
|
|
584
824
|
get loadProgress(): LoadProgress;
|
|
585
|
-
start(sample: NoteEvent
|
|
825
|
+
start(sample: NoteEvent | string | number): StopFn;
|
|
586
826
|
stop(target?: StopTarget): void;
|
|
587
827
|
disconnect(): void;
|
|
588
828
|
}
|
|
@@ -616,7 +856,7 @@ declare class Soundfont {
|
|
|
616
856
|
get output(): OutputChannel;
|
|
617
857
|
loaded(): Promise<this>;
|
|
618
858
|
disconnect(): void;
|
|
619
|
-
start(sample: NoteEvent
|
|
859
|
+
start(sample: NoteEvent | string | number): StopFn;
|
|
620
860
|
stop(sample?: StopTarget | string | number): void;
|
|
621
861
|
}
|
|
622
862
|
/**
|
|
@@ -675,7 +915,7 @@ declare class Soundfont2Sampler {
|
|
|
675
915
|
get instrumentNames(): string[];
|
|
676
916
|
get output(): OutputChannel;
|
|
677
917
|
loadInstrument(instrumentName: string): Promise<void> | undefined;
|
|
678
|
-
start(sample: NoteEvent
|
|
918
|
+
start(sample: NoteEvent | string | number): StopFn;
|
|
679
919
|
stop(sample?: StopTarget | string | number): void;
|
|
680
920
|
disconnect(): void;
|
|
681
921
|
}
|
|
@@ -715,7 +955,7 @@ declare class SplendidGrandPiano {
|
|
|
715
955
|
get loadProgress(): LoadProgress;
|
|
716
956
|
/** @deprecated Use `load` instead. */
|
|
717
957
|
loaded(): Promise<this>;
|
|
718
|
-
start(event: NoteEvent
|
|
958
|
+
start(event: NoteEvent): StopFn;
|
|
719
959
|
stop(target?: StopTarget): void;
|
|
720
960
|
disconnect(): void;
|
|
721
961
|
}
|
|
@@ -744,4 +984,4 @@ declare const LAYERS: ({
|
|
|
744
984
|
cutoff?: undefined;
|
|
745
985
|
})[];
|
|
746
986
|
|
|
747
|
-
export { CacheStorage, DrumMachine, type DrumMachineOptions, ElectricPiano, type ElectricPianoOptions, HttpStorage, LAYERS, Mallet, Mellotron, type MellotronConfig, type MellotronOptions, NAME_TO_PATH, type NoteEvent, Reverb, Sampler, type SamplerConfig, Sequencer, type SequencerInstrument, type SequencerNote, type SequencerOptions, Smolken, type SmolkenConfig, type SmolkenOptions, Soundfont, type Soundfont2Options, Soundfont2Sampler, type SoundfontOptions, SplendidGrandPiano, type SplendidGrandPianoConfig, type Storage, type StorageResponse, Versilian, type VersilianConfig, type VersilianOptions, drumMachineToSmplrJson, getDrumMachineNames, getElectricPianoNames, getMalletNames, getMellotronNames, getSmolkenNames, getSoundfontKits, getSoundfontNames, getVersilianInstruments, mellotronToSmplrJson, pianoToSmplrJson, samplerToSmplrJson, sf2InstrumentToSmplrJson, soundfontToSmplrJson, spreadKeyRanges };
|
|
987
|
+
export { CacheStorage, DrumMachine, type DrumMachineOptions, ElectricPiano, type ElectricPianoOptions, HttpStorage, 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, Smplr, type SmplrGroup, type SmplrJson, type SmplrOptions, type SmplrRegion, type SmplrSamples, Soundfont, type Soundfont2Options, Soundfont2Sampler, type SoundfontOptions, SplendidGrandPiano, type SplendidGrandPianoConfig, type SpreadResult, type StopFn, type StopTarget, type Storage, type StorageResponse, Versilian, type VersilianConfig, type VersilianOptions, type VoiceParams, audioBufferToWav, audioBufferToWav16, drumMachineToSmplrJson, getDrumMachineNames, getElectricPianoNames, getMalletNames, getMellotronNames, getSmolkenNames, getSoundfontKits, getSoundfontNames, getVersilianInstruments, mellotronToSmplrJson, pianoToSmplrJson, renderOffline, samplerToSmplrJson, sf2InstrumentToSmplrJson, soundfontToSmplrJson, spreadKeyRanges, trimSilence };
|