smplr 0.25.0 → 0.26.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/dist/index.mjs CHANGED
@@ -318,7 +318,7 @@ function pickPlaybackParams(obj) {
318
318
  return result;
319
319
  }
320
320
  function resolveParams(defaults, group, region, midi, velocity, overrides) {
321
- var _a, _b, _c, _d, _e;
321
+ var _a, _b, _c, _d, _e, _f;
322
322
  const merged = __spreadValues(__spreadValues(__spreadValues(__spreadValues({}, PARAM_DEFAULTS), defaults), pickPlaybackParams(group)), pickPlaybackParams(region));
323
323
  const pitch = (_b = (_a = region.pitch) != null ? _a : region.key) != null ? _b : midi;
324
324
  const semitones = midi - pitch;
@@ -337,7 +337,7 @@ function resolveParams(defaults, group, region, midi, velocity, overrides) {
337
337
  loopEnd: merged.loopEnd,
338
338
  ampVelCurve: region.ampVelCurve,
339
339
  loopAuto: region.loopAuto,
340
- reverse: overrides == null ? void 0 : overrides.reverse
340
+ reverse: (_f = overrides == null ? void 0 : overrides.reverse) != null ? _f : merged.reverse
341
341
  };
342
342
  }
343
343
 
@@ -515,14 +515,6 @@ var SampleLoaderImpl = class {
515
515
  __privateSet(this, _context, context);
516
516
  __privateSet(this, _storage, (_a = options == null ? void 0 : options.storage) != null ? _a : HttpStorage);
517
517
  }
518
- /**
519
- * Load all samples referenced in `json`. Returns a Map of sample name →
520
- * AudioBuffer. Progress is reported via `onProgress` callback or via
521
- * options object.
522
- *
523
- * - `buffers` in options: pre-loaded buffers — skips fetch for these names.
524
- * - All samples load in parallel. Failed samples are silently omitted.
525
- */
526
518
  load(json, onProgressOrOptions) {
527
519
  return __async(this, null, function* () {
528
520
  var _a, _b;
@@ -642,14 +634,6 @@ var SchedulerImpl = class {
642
634
  __privateSet(this, _intervalMs, (_b = options == null ? void 0 : options.intervalMs) != null ? _b : INTERVAL_MS_DEFAULT);
643
635
  __privateSet(this, _queue, new SortedQueue((a, b) => a.time - b.time));
644
636
  }
645
- /**
646
- * Schedule a callback for a NoteEvent.
647
- *
648
- * - If the event's time falls within the lookahead window (or has no time), the
649
- * callback is called synchronously and a no-op StopFn is returned.
650
- * - Otherwise the event is queued, the interval is started if needed, and a StopFn
651
- * is returned that removes the event from the queue before it is dispatched.
652
- */
653
637
  schedule(event, callback) {
654
638
  var _a;
655
639
  const now = __privateGet(this, _context2).currentTime;
@@ -665,10 +649,6 @@ var SchedulerImpl = class {
665
649
  __privateGet(this, _queue).removeAll((q) => q === item);
666
650
  };
667
651
  }
668
- /**
669
- * Clear all queued (not-yet-dispatched) events and stop the interval.
670
- * Does not affect voices that are already playing.
671
- */
672
652
  stop() {
673
653
  __privateGet(this, _queue).clear();
674
654
  if (__privateGet(this, _intervalId) !== void 0) {
@@ -941,10 +921,12 @@ var SmplrImpl = class {
941
921
  __privateSet(this, _voices2, new VoiceManager());
942
922
  this.loader = (_c = options == null ? void 0 : options.loader) != null ? _c : SampleLoader(context, { storage: options == null ? void 0 : options.storage });
943
923
  if (json) {
944
- this.ready = this.loader.load(json, (loaded, total) => {
945
- var _a2;
946
- __privateSet(this, _loadProgress, { loaded, total });
947
- (_a2 = __privateGet(this, _onLoadProgress)) == null ? void 0 : _a2.call(this, { loaded, total });
924
+ this.ready = this.loader.load(json, {
925
+ onProgress: (loaded, total) => {
926
+ var _a2;
927
+ __privateSet(this, _loadProgress, { loaded, total });
928
+ (_a2 = __privateGet(this, _onLoadProgress)) == null ? void 0 : _a2.call(this, { loaded, total });
929
+ }
948
930
  }).then((buffers) => {
949
931
  __privateSet(this, _buffers, buffers);
950
932
  });
@@ -2503,6 +2485,7 @@ var SequencerImpl = class {
2503
2485
  this._clock.stop();
2504
2486
  this._stopLoop();
2505
2487
  this._endScheduled = false;
2488
+ for (const stopFn of this._activeVoices.values()) stopFn();
2506
2489
  this._activeVoices.clear();
2507
2490
  this._emitStateChange("stopped");
2508
2491
  return this;
@@ -3140,8 +3123,10 @@ function createTremolo(context, depth) {
3140
3123
  splitter.disconnect(ampR, 1);
3141
3124
  ampL.disconnect(merger, 0, 0);
3142
3125
  ampR.disconnect(merger, 0, 1);
3143
- lfoL.disconnect(ampL);
3144
- lfoR.disconnect(ampR);
3126
+ lfoL.disconnect(lfoLAmp);
3127
+ lfoLAmp.disconnect(ampL.gain);
3128
+ lfoR.disconnect(lfoRAmp);
3129
+ lfoRAmp.disconnect(ampR.gain);
3145
3130
  merger.disconnect(output);
3146
3131
  };
3147
3132
  return { input, output };
@@ -3212,15 +3197,11 @@ var ElectricPiano = Instrument(
3212
3197
 
3213
3198
  // src/versilian.ts
3214
3199
  var VCSL_BASE_URL = "https://smpldsnds.github.io/sgossner-vcsl";
3215
- var instruments = [];
3200
+ var instrumentsPromise;
3216
3201
  function getVersilianInstruments() {
3217
- return __async(this, null, function* () {
3218
- if (instruments.length) return instruments;
3219
- instruments = yield fetch(VCSL_BASE_URL + "/sfz_files.json").then(
3220
- (res) => res.json()
3221
- );
3222
- return instruments;
3223
- });
3202
+ return instrumentsPromise != null ? instrumentsPromise : instrumentsPromise = fetch(
3203
+ VCSL_BASE_URL + "/sfz_files.json"
3204
+ ).then((res) => res.json());
3224
3205
  }
3225
3206
  var Versilian = Instrument(
3226
3207
  (ctx, options = {}, smplr) => loadVersilianInstrument(smplr, options)
@@ -3352,7 +3333,7 @@ function mellotronToPreset(sampleNames, config) {
3352
3333
  for (const sampleName of sampleNames) {
3353
3334
  if (config.variation && !sampleName.includes(config.variation)) continue;
3354
3335
  const midi = toMidi((_a = sampleName.split(" ")[0]) != null ? _a : "");
3355
- if (!midi) continue;
3336
+ if (midi === void 0) continue;
3356
3337
  entries.push([midi, sampleName]);
3357
3338
  }
3358
3339
  const spread = spreadKeyRanges(entries);
@@ -3437,7 +3418,7 @@ var ReverbImpl = class {
3437
3418
  }
3438
3419
  getParam(name) {
3439
3420
  var _a;
3440
- return (_a = __privateGet(this, _effect)) == null ? void 0 : _a.parameters.get("preDelay");
3421
+ return (_a = __privateGet(this, _effect)) == null ? void 0 : _a.parameters.get(name);
3441
3422
  }
3442
3423
  get isReady() {
3443
3424
  return __privateGet(this, _effect) !== void 0;
@@ -3764,10 +3745,9 @@ function fetchSoundfontLoopData(url, sampleRate = 44100) {
3764
3745
  const loopData = {};
3765
3746
  Object.keys(raw).forEach((key) => {
3766
3747
  const midi = toMidi(key);
3767
- if (midi) {
3768
- const offsets = raw[key];
3769
- loopData[midi] = [offsets[0] / sampleRate, offsets[1] / sampleRate];
3770
- }
3748
+ if (midi === void 0) return;
3749
+ const offsets = raw[key];
3750
+ loopData[midi] = [offsets[0] / sampleRate, offsets[1] / sampleRate];
3771
3751
  });
3772
3752
  return loopData;
3773
3753
  } catch (err) {
@@ -3812,7 +3792,7 @@ function decodeSoundfontFile(context, config) {
3812
3792
  yield Promise.all(
3813
3793
  noteNames.map((noteName) => __async(null, null, function* () {
3814
3794
  const midi = toMidi(noteName);
3815
- if (!midi) return;
3795
+ if (midi === void 0) return;
3816
3796
  try {
3817
3797
  const audioData = base64ToArrayBuffer(
3818
3798
  removeBase64Prefix(json[noteName])