smplr 0.8.1 → 0.10.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
@@ -280,7 +280,7 @@ Bear in mind that currently that feature produces click on lot of instruments.
280
280
 
281
281
  ### Piano
282
282
 
283
- A sampled acoustic piano. It uses Steinway samples with 4 velocity layers from
283
+ A sampled acoustic piano. It uses Steinway samples with 4 velocity groups from
284
284
  [SplendidGrandPiano](https://github.com/sfzinstruments/SplendidGrandPiano)
285
285
 
286
286
  ```js
@@ -364,6 +364,38 @@ drums.getVariations("kick").forEach((variation, index) => {
364
364
  });
365
365
  ```
366
366
 
367
+ ### Smolken double bass
368
+
369
+ ```js
370
+ import { Smolken, getSmolkenNames } from "smplr";
371
+
372
+ const instruments = getSmolkenNames(); // => Arco, Pizzicato & Switched
373
+
374
+ // Create an instrument
375
+ const context = new AudioContext();
376
+ const doubleBass = await new Smolken(context, { instrument: "Arco" }).load;
377
+ ```
378
+
379
+ ### Versilian
380
+
381
+ Versilian is a sample capable of using the [Versilian Community Sample Library](https://github.com/sgossner/VCSL).
382
+
383
+ ⚠️ Not all features are implemented. Some instruments may sound incorrect ⚠️
384
+
385
+ ```js
386
+ import { Versilian, getVersilianInstruments } from "smplr";
387
+
388
+ // getVersilianInstruments returns a Promise
389
+ const instrumentNames = await getVersilianInstruments();
390
+
391
+ const context = new AudioContext();
392
+ const sampler = new Versilian(context, { instrument: instrumentNAmes[0] });
393
+ ```
394
+
367
395
  ## License
368
396
 
369
397
  MIT License
398
+
399
+ ```
400
+
401
+ ```
package/dist/index.d.ts CHANGED
@@ -85,6 +85,7 @@ type SampleOptions = {
85
85
  loop?: boolean;
86
86
  loopStart?: number;
87
87
  loopEnd?: number;
88
+ gainOffset?: number;
88
89
  };
89
90
  type SampleStart = {
90
91
  name?: string;
@@ -94,16 +95,92 @@ type SampleStart = {
94
95
  stopId?: string | number;
95
96
  time?: number;
96
97
  } & SampleOptions;
98
+ /**
99
+ * Heavily inspired by SFZ format
100
+ */
97
101
  type SampleRegion = {
98
102
  sampleName: string;
99
- sampleCenter: number;
100
- rangeMidi?: [number, number];
101
- rangeVol?: [number, number];
102
- offsetVol?: number;
103
- offsetDetune?: number;
103
+ /**
104
+ * This specifies the MIDI key number that corresponds to the sample's original pitch
105
+ */
106
+ midiPitch: number;
107
+ /**
108
+ * This defines the lowest MIDI key number that will trigger this sample.
109
+ */
110
+ midiLow?: number;
111
+ /**
112
+ * This specifies the highest MIDI key number that will trigger this sample.
113
+ */
114
+ midiHigh?: number;
115
+ velLow?: number;
116
+ /**
117
+ * This determines the highest MIDI velocity at which this sample will be triggered.
118
+ */
119
+ velHigh?: number;
120
+ /**
121
+ * These define the pitch bend range for the samples in this group. The values are given in cents
122
+ */
123
+ bendUp?: number;
124
+ bendDown?: number;
125
+ /**
126
+ * Velocity-based amplitude scaling. [Vel, Gain] tells the sampler to play the sample
127
+ * at volume Gain when the note's velocity is Vel
128
+ */
129
+ ampVelCurve?: [number, number];
130
+ /**
131
+ * Amplitude envelope release time in seconds.
132
+ * Stored here for convenience (flatness) but needs to be
133
+ * copied inside sample options before playback
134
+ */
135
+ ampRelease?: number;
136
+ /**
137
+ * Attack time in seconds. Currently not implemented
138
+ *
139
+ * @see http://sfzformat.com/opcodes/amp_attack.html
140
+ */
141
+ ampAttack?: number;
142
+ /**
143
+ * seqLength defines how many samples are in the sequence.
144
+ * When using the seqPosition and seqLength , you can set up round-robin
145
+ * or sequential sample playback.
146
+ */
147
+ seqLength?: number;
148
+ /**
149
+ * Determine the position of this particular sample within the sequence
150
+ * 1 means first element of the sequence (not zero based!)
151
+ */
152
+ seqPosition?: number;
153
+ /**
154
+ * This assigns the group to a specific number.
155
+ * Group numbers can be used in combination with groupOffBy to implement
156
+ * exclusive groups, where playing one sample can stop another sample from playing.
157
+ */
158
+ group?: number;
159
+ /**
160
+ * Triggering a sample in this region will stop (or "turn off") any samples
161
+ * currently playing in the specified group number
162
+ */
163
+ groupOffBy?: number;
164
+ /**
165
+ * Start offset (in samples). Not implemented (yet)
166
+ */
167
+ offset?: number;
168
+ /**
169
+ * Adjust the playback pitch of a sample (in semitones)
170
+ */
171
+ tune?: number;
172
+ /**
173
+ * The volume opcode in SFZ defines the default playback volume for a given region.
174
+ * It specifies an adjustment to the sample's original amplitude.
175
+ * The unit for the volume opcode is decibels (dB).
176
+ */
177
+ volume?: number;
178
+ /**
179
+ * sample options for this particular region
180
+ */
104
181
  sample?: Partial<SampleOptions>;
105
182
  };
106
- type SampleLayer = {
183
+ type RegionGroup = {
107
184
  regions: SampleRegion[];
108
185
  sample: Partial<SampleOptions>;
109
186
  };
@@ -232,11 +309,35 @@ declare class ElectricPiano extends SfzSampler {
232
309
  });
233
310
  }
234
311
 
312
+ declare function getVersilianInstruments(): Promise<string[]>;
313
+ declare function VcslInstrumentLoader(instrument: string, buffers: AudioBuffers, group: RegionGroup): (context: BaseAudioContext, storage: Storage) => Promise<void[]>;
314
+ type VersilianConfig = {
315
+ instrument: string;
316
+ storage: Storage;
317
+ };
318
+ type VersilianOptions = Partial<VersilianConfig & SampleOptions & ChannelOptions>;
319
+ /**
320
+ * Versilian
321
+ *
322
+ * The Versilian Community Sample Library is an open CC0 general-purpose sample library created by Versilian Studios LLC
323
+ * for the purpose of introducing a set of quality, publicly available samples suitable for use in software and media of all kinds.
324
+ */
325
+ declare class Versilian implements InternalPlayer {
326
+ private readonly player;
327
+ readonly load: Promise<this>;
328
+ private config;
329
+ constructor(context: BaseAudioContext, options?: VersilianOptions);
330
+ get output(): OutputChannel;
331
+ get buffers(): AudioBuffers;
332
+ get context(): BaseAudioContext;
333
+ start(sample: SampleStart | string | number): (time?: number | undefined) => void;
334
+ stop(sample?: SampleStop | string | number): void;
335
+ disconnect(): void;
336
+ }
337
+
235
338
  declare function getMalletNames(): string[];
236
- declare class Mallet extends SfzSampler {
237
- constructor(context: AudioContext, options: Partial<SfzSamplerConfig> & {
238
- instrument: string;
239
- });
339
+ declare class Mallet extends Versilian {
340
+ constructor(context: AudioContext, options: VersilianOptions);
240
341
  }
241
342
  declare const NAME_TO_PATH: Record<string, string | undefined>;
242
343
 
@@ -250,7 +351,7 @@ declare class Mellotron implements InternalPlayer {
250
351
  readonly context: BaseAudioContext;
251
352
  private readonly config;
252
353
  private readonly player;
253
- private readonly layer;
354
+ private readonly group;
254
355
  readonly load: Promise<this>;
255
356
  constructor(context: BaseAudioContext, options: MellotronOptions);
256
357
  get buffers(): AudioBuffers;
@@ -301,6 +402,27 @@ declare class Sampler {
301
402
  disconnect(): void;
302
403
  }
303
404
 
405
+ declare function getSmolkenNames(): string[];
406
+ type SmolkenConfig = {
407
+ instrument: string;
408
+ storage: Storage;
409
+ };
410
+ type SmolkenOptions = Partial<SmolkenConfig & SampleOptions & ChannelOptions>;
411
+ declare class Smolken implements InternalPlayer {
412
+ private readonly player;
413
+ private readonly group;
414
+ readonly load: Promise<this>;
415
+ private config;
416
+ private seqNum;
417
+ constructor(context: BaseAudioContext, options?: SmolkenOptions);
418
+ get output(): OutputChannel;
419
+ get buffers(): AudioBuffers;
420
+ get context(): BaseAudioContext;
421
+ start(sample: SampleStart | string | number): (time?: number) => void;
422
+ stop(sample?: SampleStop | string | number): void;
423
+ disconnect(): void;
424
+ }
425
+
304
426
  declare function getSoundfontKits(): string[];
305
427
  declare function getSoundfontNames(): string[];
306
428
  type SoundfontConfig = {
@@ -319,7 +441,7 @@ declare class Soundfont {
319
441
  readonly config: Readonly<SoundfontConfig>;
320
442
  private readonly player;
321
443
  readonly load: Promise<this>;
322
- readonly layer: SampleLayer;
444
+ readonly group: RegionGroup;
323
445
  constructor(context: AudioContext, options: SoundfontOptions);
324
446
  get output(): OutputChannel;
325
447
  get hasLoops(): boolean;
@@ -367,4 +489,4 @@ declare const LAYERS: ({
367
489
  cutoff?: undefined;
368
490
  })[];
369
491
 
370
- export { CacheStorage, DrumMachine, DrumMachineConfig, ElectricPiano, HttpStorage, LAYERS, Mallet, Mellotron, MellotronConfig, MellotronOptions, NAME_TO_PATH, Reverb, Sampler, SamplerConfig, Soundfont, SoundfontOptions, SplendidGrandPiano, SplendidGrandPianoConfig, Storage, StorageResponse, getDrumMachineNames, getElectricPianoNames, getMalletNames, getMellotronNames, getSoundfontKits, getSoundfontNames };
492
+ export { CacheStorage, DrumMachine, DrumMachineConfig, ElectricPiano, HttpStorage, LAYERS, Mallet, Mellotron, MellotronConfig, MellotronOptions, NAME_TO_PATH, Reverb, Sampler, SamplerConfig, Smolken, SmolkenConfig, SmolkenOptions, Soundfont, SoundfontOptions, SplendidGrandPiano, SplendidGrandPianoConfig, Storage, StorageResponse, VcslInstrumentLoader, Versilian, VersilianConfig, VersilianOptions, getDrumMachineNames, getElectricPianoNames, getMalletNames, getMellotronNames, getSmolkenNames, getSoundfontKits, getSoundfontNames, getVersilianInstruments };