smplr 0.11.3 → 0.12.1

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
@@ -371,6 +371,30 @@ const piano = new SplendidGrandPiano(new AudioContext());
371
371
  piano.start({ note: "C4" });
372
372
  ```
373
373
 
374
+ #### SplendidGrandPiano constructor
375
+
376
+ The second argument of the constructor accepts the following options:
377
+
378
+ - `baseUrl`:
379
+ - `detune`: global detune in cents (0 if not specified)
380
+ - `velocity`: default velocity (100 if not specified)
381
+ - `volume`: default volume (100 if not specified)
382
+ - `decayTime`: default decay time (0.5 seconds)
383
+ - `notesToLoad`: an object with the following shape: `{ notes: number[], velocityRange: [number, number]}` to specify a subset of notes to load
384
+
385
+ Example:
386
+
387
+ ```ts
388
+ const piano = new SplendidGrandPiano(context, {
389
+ detune: -20,
390
+ volume: 80,
391
+ notesToLoad: {
392
+ notes: [60],
393
+ velocityRange: [1, 127],
394
+ },
395
+ });
396
+ ```
397
+
374
398
  ### Electric Piano
375
399
 
376
400
  A sampled electric pianos. Samples from https://github.com/sfzinstruments/GregSullivan.E-Pianos
package/dist/index.d.mts CHANGED
@@ -469,6 +469,10 @@ type SplendidGrandPianoConfig = {
469
469
  detune: number;
470
470
  velocity: number;
471
471
  decayTime: number;
472
+ notesToLoad?: {
473
+ notes: number[];
474
+ velocityRange: [number, number];
475
+ };
472
476
  } & Partial<DefaultPlayerConfig>;
473
477
  declare class SplendidGrandPiano {
474
478
  #private;
package/dist/index.d.ts CHANGED
@@ -469,6 +469,10 @@ type SplendidGrandPianoConfig = {
469
469
  detune: number;
470
470
  velocity: number;
471
471
  decayTime: number;
472
+ notesToLoad?: {
473
+ notes: number[];
474
+ velocityRange: [number, number];
475
+ };
472
476
  } & Partial<DefaultPlayerConfig>;
473
477
  declare class SplendidGrandPiano {
474
478
  #private;
package/dist/index.js CHANGED
@@ -1006,20 +1006,18 @@ function createTremolo(context, depth) {
1006
1006
  const output = context.createGain();
1007
1007
  input.channelCount = 2;
1008
1008
  input.channelCountMode = "explicit";
1009
- const splitter = new ChannelSplitterNode(context, { numberOfOutputs: 2 });
1009
+ const splitter = context.createChannelSplitter(2);
1010
1010
  const ampL = context.createGain();
1011
1011
  const ampR = context.createGain();
1012
- const merger = new ChannelMergerNode(context, { numberOfInputs: 2 });
1013
- const lfoL = new OscillatorNode(context, {
1014
- type: "sine",
1015
- frequency: 1
1016
- });
1012
+ const merger = context.createChannelMerger(2);
1013
+ const lfoL = context.createOscillator();
1014
+ lfoL.type = "sine";
1015
+ lfoL.frequency.value = 1;
1017
1016
  lfoL.start();
1018
1017
  const lfoLAmp = context.createGain();
1019
- const lfoR = new OscillatorNode(context, {
1020
- type: "sine",
1021
- frequency: 1.1
1022
- });
1018
+ const lfoR = context.createOscillator();
1019
+ lfoR.type = "sine";
1020
+ lfoR.frequency.value = 1.1;
1023
1021
  lfoR.start();
1024
1022
  const lfoRAmp = context.createGain();
1025
1023
  input.connect(splitter);
@@ -2161,7 +2159,8 @@ var SplendidGrandPiano = class {
2161
2159
  this.player = new DefaultPlayer(context, this.options);
2162
2160
  const loader = splendidGrandPianoLoader(
2163
2161
  this.options.baseUrl,
2164
- this.options.storage
2162
+ this.options.storage,
2163
+ this.options.notesToLoad
2165
2164
  );
2166
2165
  this.load = loader(context, this.player.buffers).then(() => this);
2167
2166
  }
@@ -2217,13 +2216,17 @@ function findNearestMidiInLayer(prefix, midi, buffers) {
2217
2216
  }
2218
2217
  return i === 127 ? [prefix + midi, midi, 0] : [prefix + (midi + i), midi, -i * 100];
2219
2218
  }
2220
- function splendidGrandPianoLoader(baseUrl, storage) {
2219
+ function splendidGrandPianoLoader(baseUrl, storage, notesToLoad) {
2221
2220
  var _a;
2222
2221
  const format = (_a = findFirstSupportedFormat(["ogg", "m4a"])) != null ? _a : "ogg";
2222
+ let layers = notesToLoad ? LAYERS.filter(
2223
+ (layer) => layer.vel_range[0] <= notesToLoad.velocityRange[1] && layer.vel_range[1] >= notesToLoad.velocityRange[0]
2224
+ ) : LAYERS;
2223
2225
  return (context, buffers) => __async(this, null, function* () {
2224
- for (const layer of LAYERS) {
2226
+ for (const layer of layers) {
2227
+ const samples = notesToLoad ? layer.samples.filter((sample) => notesToLoad.notes.includes(sample[0])) : layer.samples;
2225
2228
  yield Promise.all(
2226
- layer.samples.map((_0) => __async(this, [_0], function* ([midi, name]) {
2229
+ samples.map((_0) => __async(this, [_0], function* ([midi, name]) {
2227
2230
  const url = `${baseUrl}/${name}.${format}`;
2228
2231
  const buffer = yield loadAudioBuffer(context, url, storage);
2229
2232
  if (buffer)