@weasel-js/audio 1.9.2 → 1.9.4

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
@@ -30,6 +30,11 @@ Browsers start an `AudioContext` suspended until a user gesture. The engine
30
30
  resumes on the first gesture automatically; `play()` before that drops the voice
31
31
  with a dev warning rather than queueing it.
32
32
 
33
+ `onDone` is called when a voice's source ends: it played out, or was stopped,
34
+ faded or stolen. A voice that never played calls `onDrop(reason)` instead, with
35
+ `'locked'`, `'disposed'`, `'stopped'`, `'unready'`, `'failed'` or `'stale'`, so
36
+ code chaining one sound after another hears about both.
37
+
33
38
  ## Notes and patterns
34
39
 
35
40
  `playNote` plays a synthesized voice — an `OscillatorNode` under an ADSR
@@ -124,7 +129,7 @@ bed.stop(800);
124
129
  ```
125
130
 
126
131
  It is a voice like the others: a `VoiceHandle`, the bus's inserts and voice
127
- pool, `cancelKey`, `onDone`, position and pan. What does not carry over:
132
+ pool, `cancelKey`, `onDone`, `onDrop`, position and pan. What does not carry over:
128
133
 
129
134
  - **No `when`.** The element starts once it has buffered enough; the start is
130
135
  not sample-accurate and cannot be booked ahead on the audio clock.
package/dist/index.d.ts CHANGED
@@ -59,6 +59,7 @@ interface InsertSlot {
59
59
  /** Position in the chain, or -1 once removed. */
60
60
  index(): number;
61
61
  }
62
+ /** Where `InsertChain.add` puts an effect, and whether it starts bypassed. */
62
63
  interface InsertAddOptions {
63
64
  /** Default: the end of the chain. Clamped. */
64
65
  index?: number;
@@ -76,6 +77,7 @@ interface InsertChain {
76
77
  clear(): void;
77
78
  settled(): Promise<void>;
78
79
  }
80
+ /** Options for an insert chain: its crossfade length, and the timers it schedules with. */
79
81
  interface InsertChainOptions extends Partial<Timers> {
80
82
  /** Crossfade length for every edit, in ms. Default 15. */
81
83
  fadeMs?: number;
@@ -186,12 +188,15 @@ interface Envelope {
186
188
  /** Default 30. */
187
189
  release?: number;
188
190
  }
191
+ /** An envelope with every default filled in and every value in range. */
189
192
  type ResolvedEnvelope = Required<Envelope>;
193
+ /** One breakpoint of an envelope's curve: a level at a time. */
190
194
  interface EnvelopePoint {
191
195
  /** ms from the note's start. */
192
196
  at: number;
193
197
  value: number;
194
198
  }
199
+ /** Fill an envelope's defaults, clamping times to zero or more and `sustain` to 0..1. */
195
200
  declare function resolveEnvelope(env?: Envelope): ResolvedEnvelope;
196
201
  /** The level `t` ms after the start. With `gate`, the release begins that many
197
202
  * ms in, from whatever level the envelope had reached. */
@@ -214,6 +219,7 @@ declare function midiToFrequency(midi: number): number;
214
219
  /** MIDI number of a scientific pitch name: C4 is 60. Accepts any run of `#`
215
220
  * or `b` after the letter. */
216
221
  declare function noteToMidi(name: string): number;
222
+ /** A pitch in hertz. Throws on a note name it cannot read, and on a frequency that is not positive and finite. */
217
223
  declare function toFrequency(pitch: Pitch): number;
218
224
 
219
225
  /** Which voice a full pool evicts: the earliest started, or the lowest gain. */
@@ -279,8 +285,24 @@ interface PlayOptions {
279
285
  when?: number;
280
286
  /** `stopKey(key)` stops every voice sharing this key. */
281
287
  cancelKey?: string;
288
+ /** The voice's source ended: it played out, or was stopped, faded, released
289
+ * or stolen after it started. */
282
290
  onDone?: () => void;
291
+ /** The voice never got a source, so `onDone` will not be called. Called
292
+ * after `play()` has returned, never from inside it. */
293
+ onDrop?: (reason: VoiceDropReason) => void;
283
294
  }
295
+ /**
296
+ * Why a voice never played:
297
+ *
298
+ * - `locked` — the context was not running when it was played.
299
+ * - `disposed` — the engine was disposed, before the play or while it waited.
300
+ * - `stopped` — stopped, released or `stopKey`ed before it came due.
301
+ * - `unready` — its sound was not loaded in this engine when it came due.
302
+ * - `failed` — its node threw as it started.
303
+ * - `stale` — it came due while the context was suspended.
304
+ */
305
+ type VoiceDropReason = 'locked' | 'disposed' | 'stopped' | 'unready' | 'failed' | 'stale';
284
306
  /** Controls for one voice from `play()`. Safe to keep past the voice's end:
285
307
  * every setter is then a no-op and `isPlaying()` is false. */
286
308
  interface VoiceHandle {
@@ -493,6 +515,7 @@ interface AudioEngine {
493
515
  */
494
516
  declare function createAudioEngine(opts?: AudioEngineOptions): AudioEngine;
495
517
 
518
+ /** Options for `createFilterEffect`. Unset ones keep the node's defaults. */
496
519
  interface FilterEffectOptions {
497
520
  /** Default 'lowpass'. */
498
521
  type?: BiquadFilterType;
@@ -502,6 +525,7 @@ interface FilterEffectOptions {
502
525
  /** dB, for the shelf and peaking types. */
503
526
  gain?: number;
504
527
  }
528
+ /** A filter insert, with its `BiquadFilterNode` exposed. */
505
529
  interface FilterEffect extends InsertEffect {
506
530
  readonly filter: BiquadFilterNode;
507
531
  }
@@ -514,6 +538,7 @@ interface WetDryMix {
514
538
  mix(): number;
515
539
  setMix(mix: number, rampMs?: number): void;
516
540
  }
541
+ /** Options for `createReverbEffect`. */
517
542
  interface ReverbEffectOptions {
518
543
  /** The room: an impulse response, loaded or synthesized like any buffer. */
519
544
  impulse: AudioBuffer;
@@ -522,11 +547,13 @@ interface ReverbEffectOptions {
522
547
  /** Scale the impulse to a consistent level. Default true, the node's own. */
523
548
  normalize?: boolean;
524
549
  }
550
+ /** A reverb insert, with its `ConvolverNode` exposed. */
525
551
  interface ReverbEffect extends InsertEffect, WetDryMix {
526
552
  readonly convolver: ConvolverNode;
527
553
  }
528
554
  /** Convolution reverb from an impulse buffer, with a wet/dry mix. */
529
555
  declare function createReverbEffect(ctx: BaseAudioContext, opts: ReverbEffectOptions): ReverbEffect;
556
+ /** Options for `createDelayEffect`. */
530
557
  interface DelayEffectOptions {
531
558
  /** ms. Default 250. */
532
559
  time?: number;
@@ -538,6 +565,7 @@ interface DelayEffectOptions {
538
565
  * of 1000 and `time`. */
539
566
  maxTime?: number;
540
567
  }
568
+ /** A feedback delay insert, with its `DelayNode` exposed. Ramps are ms. */
541
569
  interface DelayEffect extends InsertEffect, WetDryMix {
542
570
  readonly delay: DelayNode;
543
571
  setTime(ms: number, rampMs?: number): void;
@@ -549,6 +577,7 @@ interface DelayEffect extends InsertEffect, WetDryMix {
549
577
  /** A feedback delay with a wet/dry mix. Ramping `setTime` bends the pitch of
550
578
  * the repeats while it moves, as a tape delay does. */
551
579
  declare function createDelayEffect(ctx: BaseAudioContext, opts?: DelayEffectOptions): DelayEffect;
580
+ /** Options for `createCompressorEffect`. Unset ones keep the node's defaults. */
552
581
  interface CompressorEffectOptions {
553
582
  /** dB. */
554
583
  threshold?: number;
@@ -562,6 +591,7 @@ interface CompressorEffectOptions {
562
591
  /** Linear gain after the compressor, to win back the level it takes. Default 1. */
563
592
  makeup?: number;
564
593
  }
594
+ /** A compressor insert, with its `DynamicsCompressorNode` and makeup `GainNode` exposed. */
565
595
  interface CompressorEffect extends InsertEffect {
566
596
  readonly compressor: DynamicsCompressorNode;
567
597
  readonly makeup: GainNode;
@@ -650,6 +680,7 @@ interface PatternHit extends Omit<PlayOptions, 'when'> {
650
680
  step: number;
651
681
  sound: SoundHandle;
652
682
  }
683
+ /** Anything a pattern plays on a step. */
653
684
  type PatternEvent = PatternNote | PatternNoise | PatternHit;
654
685
  /** Options for `createPatternPlayer`. */
655
686
  interface PatternPlayerOptions {
@@ -727,4 +758,4 @@ declare const partialPresets: {
727
758
  };
728
759
  };
729
760
 
730
- export { type Acquisition, type AnalyserTap, type AnalyserTapOptions, type AudioEngine, type AudioEngineOptions, type BusGraph, type BusGraphOptions, type BusHandle, type CompressorEffect, type CompressorEffectOptions, type DelayEffect, type DelayEffectOptions, type Envelope, type EnvelopePoint, type FilterEffect, type FilterEffectOptions, type Glide, type Inharmonic, type InsertAddOptions, type InsertChain, type InsertChainOptions, type InsertEffect, type InsertSlot, type NoiseColor, type NoiseOptions, type NoisePatch, type NoteOptions, type PatternEvent, type PatternHit, type PatternNoise, type PatternNote, type PatternPlayer, type PatternPlayerOptions, type Pitch, type PlayOptions, type ResolvedEnvelope, type ReverbEffect, type ReverbEffectOptions, type Scheduler, type SchedulerOptions, type SoundCache, type SoundHandle, type SpatialOptions, type StealPolicy, type StreamOptions, type SynthPartial, type SynthPatch, type TickTimer, type Vec2, type VoiceFilter, type VoiceHandle, type VoicePool, type VoicePoolOptions, type VoiceRecord, type Waveform, type WetDryMix, createAnalyserTap, createAudioEngine, createBusGraph, createCompressorEffect, createDelayEffect, createFilterEffect, createPatternPlayer, createReverbEffect, createScheduler, createSoundCache, createTickTimer, createVoicePool, envelopeLevel, envelopePoints, midiToFrequency, noiseSamples, noteToMidi, partialPresets, resolveEnvelope, spatialize, toFrequency };
761
+ export { type Acquisition, type AnalyserTap, type AnalyserTapOptions, type AudioEngine, type AudioEngineOptions, type BusGraph, type BusGraphOptions, type BusHandle, type CompressorEffect, type CompressorEffectOptions, type DelayEffect, type DelayEffectOptions, type Envelope, type EnvelopePoint, type FilterEffect, type FilterEffectOptions, type Glide, type Inharmonic, type InsertAddOptions, type InsertChain, type InsertChainOptions, type InsertEffect, type InsertSlot, type NoiseColor, type NoiseOptions, type NoisePatch, type NoteOptions, type PatternEvent, type PatternHit, type PatternNoise, type PatternNote, type PatternPlayer, type PatternPlayerOptions, type Pitch, type PlayOptions, type ResolvedEnvelope, type ReverbEffect, type ReverbEffectOptions, type Scheduler, type SchedulerOptions, type SoundCache, type SoundHandle, type SpatialOptions, type StealPolicy, type StreamOptions, type SynthPartial, type SynthPatch, type TickTimer, type Vec2, type VoiceDropReason, type VoiceFilter, type VoiceHandle, type VoicePool, type VoicePoolOptions, type VoiceRecord, type Waveform, type WetDryMix, createAnalyserTap, createAudioEngine, createBusGraph, createCompressorEffect, createDelayEffect, createFilterEffect, createPatternPlayer, createReverbEffect, createScheduler, createSoundCache, createTickTimer, createVoicePool, envelopeLevel, envelopePoints, midiToFrequency, noiseSamples, noteToMidi, partialPresets, resolveEnvelope, spatialize, toFrequency };
package/dist/index.js CHANGED
@@ -121,6 +121,7 @@ function createInsertChain(ctx, head, tail, opts = {}) {
121
121
  const live = [];
122
122
  const links = [];
123
123
  let busy = false;
124
+ let leaving = null;
124
125
  let cancel = null;
125
126
  let disposed = false;
126
127
  let waiters = [];
@@ -219,9 +220,11 @@ function createInsertChain(ctx, head, tail, opts = {}) {
219
220
  const from = find(outOf(s), inOf(next));
220
221
  const direct = link(outOf(prev), inOf(next), 0);
221
222
  live.splice(i, 1);
223
+ leaving = s;
222
224
  writeParam(ctx, from.gain.gain, 0, ms);
223
225
  writeParam(ctx, direct.gain.gain, 1, ms);
224
226
  return () => {
227
+ leaving = null;
225
228
  unlink(into);
226
229
  unlink(from);
227
230
  if (s.removed) {
@@ -277,6 +280,10 @@ function createInsertChain(ctx, head, tail, opts = {}) {
277
280
  if (at < 0) return;
278
281
  order.splice(at, 1);
279
282
  s.removed = true;
283
+ if (!live.includes(s) && leaving !== s) {
284
+ destroy(s);
285
+ s.effect.dispose?.();
286
+ }
280
287
  pump();
281
288
  },
282
289
  index: () => order.indexOf(s)
@@ -312,6 +319,9 @@ function createInsertChain(ctx, head, tail, opts = {}) {
312
319
  disposed = true;
313
320
  cancel?.();
314
321
  cancel = null;
322
+ const done = waiters;
323
+ waiters = [];
324
+ for (const w of done) w();
315
325
  }
316
326
  };
317
327
  }
@@ -795,6 +805,40 @@ var partialPresets = {
795
805
  }
796
806
  };
797
807
 
808
+ // src/voiceDrops.ts
809
+ var reportDrop = (onDrop, reason) => {
810
+ if (onDrop) queueMicrotask(() => onDrop(reason));
811
+ };
812
+ function createDropWarnings() {
813
+ let warnedLocked = false;
814
+ let warnedDisposed = false;
815
+ let warnedUnknownSound = false;
816
+ return {
817
+ locked() {
818
+ if (warnedLocked) return;
819
+ warnedLocked = true;
820
+ console.warn(
821
+ "@weasel-js/audio: play() before the AudioContext was unlocked \u2014 the voice was dropped. Browsers require a user gesture; call engine.unlock() from one, or wait for the automatic gesture listener."
822
+ );
823
+ },
824
+ disposed() {
825
+ if (warnedDisposed) return;
826
+ warnedDisposed = true;
827
+ console.warn("@weasel-js/audio: play() after dispose() \u2014 the voice was dropped.");
828
+ },
829
+ unknownSound(id) {
830
+ if (warnedUnknownSound) return;
831
+ warnedUnknownSound = true;
832
+ console.warn(
833
+ `@weasel-js/audio: play() was handed sound "${id}", which this engine never loaded \u2014 the voice was dropped. A handle belongs to the engine that produced it.`
834
+ );
835
+ },
836
+ rearmLocked() {
837
+ warnedLocked = false;
838
+ }
839
+ };
840
+ }
841
+
798
842
  // src/voicePool.ts
799
843
  function createVoicePool(opts) {
800
844
  if (!(opts.limit >= 1)) {
@@ -924,50 +968,30 @@ function createAudioEngine(opts = {}) {
924
968
  chain.gain.connect(bus);
925
969
  return chain;
926
970
  };
927
- let warnedLocked = false;
928
- const warnLocked = () => {
929
- if (warnedLocked) return;
930
- warnedLocked = true;
931
- console.warn(
932
- "@weasel-js/audio: play() before the AudioContext was unlocked \u2014 the voice was dropped. Browsers require a user gesture; call engine.unlock() from one, or wait for the automatic gesture listener."
933
- );
934
- };
935
- let warnedDisposed = false;
936
- const warnDisposed = () => {
937
- if (warnedDisposed) return;
938
- warnedDisposed = true;
939
- console.warn("@weasel-js/audio: play() after dispose() \u2014 the voice was dropped.");
940
- };
941
- let warnedUnknownSound = false;
942
- const warnUnknownSound = (id) => {
943
- if (warnedUnknownSound) return;
944
- warnedUnknownSound = true;
945
- console.warn(
946
- `@weasel-js/audio: play() was handed sound "${id}", which this engine never loaded \u2014 the voice was dropped. A handle belongs to the engine that produced it.`
947
- );
948
- };
949
- const gestures = ["pointerdown", "keydown", "touchstart"];
971
+ const warn = createDropWarnings();
972
+ const gestures = ["pointerdown", "pointerup", "touchend", "click", "keydown"];
950
973
  const onGesture = () => {
951
- void engine.unlock();
974
+ void engine.unlock().catch(() => void 0);
952
975
  };
953
976
  const armGestures = () => {
954
977
  if (typeof window === "undefined") return;
955
- for (const g of gestures) window.addEventListener(g, onGesture, { once: true, passive: true });
978
+ for (const g of gestures) window.addEventListener(g, onGesture, { passive: true });
956
979
  };
957
980
  const disarmGestures = () => {
958
981
  if (typeof window === "undefined") return;
959
982
  for (const g of gestures) window.removeEventListener(g, onGesture);
960
983
  };
961
- armGestures();
984
+ if (ctx.state !== "running") armGestures();
962
985
  const onStateChange = () => {
963
986
  if (disposed) return;
964
987
  if (ctx.state === "running") {
988
+ disarmGestures();
965
989
  if (suspendedSince) staleFloor = now();
966
990
  suspendedSince = false;
967
991
  return;
968
992
  }
969
993
  suspendedSince = true;
970
- warnedLocked = false;
994
+ warn.rearmLocked();
971
995
  armGestures();
972
996
  };
973
997
  ctx.addEventListener("statechange", onStateChange);
@@ -980,13 +1004,17 @@ function createAudioEngine(opts = {}) {
980
1004
  const s = spatialize(voice.position, listener, spatialOpts);
981
1005
  voice.spatialGain = s.gain;
982
1006
  voice.chain.panner.pan.value = s.pan;
983
- writeParam(ctx, voice.chain.gain.gain, voice.baseGain * s.gain);
1007
+ if (!voice.fading) {
1008
+ const left = (voice.rampEnd - ctx.currentTime) * 1e3;
1009
+ writeParam(ctx, voice.chain.gain.gain, voice.baseGain * s.gain, left > 0 ? left : void 0);
1010
+ }
984
1011
  poolGain(voice);
985
1012
  };
986
- const teardown = (voice) => {
1013
+ const teardown = (voice, reason = "stopped") => {
987
1014
  voice.cancelled = true;
988
1015
  if (!voice.playing && voice.source === null) return;
989
1016
  voice.playing = false;
1017
+ if (voice.source === null) reportDrop(voice.onDrop, reason);
990
1018
  if (voice.source) {
991
1019
  try {
992
1020
  voice.source.stop();
@@ -1010,6 +1038,9 @@ function createAudioEngine(opts = {}) {
1010
1038
  voice.slots.pool.release(voice.slot, voice.token);
1011
1039
  }
1012
1040
  };
1041
+ const stopVoices = (reason) => {
1042
+ for (const voice of [...live.values()]) teardown(voice, reason);
1043
+ };
1013
1044
  const dropped = (id) => ({
1014
1045
  id,
1015
1046
  stop: () => {
@@ -1031,11 +1062,13 @@ function createAudioEngine(opts = {}) {
1031
1062
  const launch = (common, starter) => {
1032
1063
  const id = nextVoiceId++;
1033
1064
  if (disposed) {
1034
- warnDisposed();
1065
+ warn.disposed();
1066
+ reportDrop(common.onDrop, "disposed");
1035
1067
  return dropped(id);
1036
1068
  }
1037
1069
  if (ctx.state !== "running") {
1038
- warnLocked();
1070
+ warn.locked();
1071
+ reportDrop(common.onDrop, "locked");
1039
1072
  return dropped(id);
1040
1073
  }
1041
1074
  const busName = common.bus ?? busNames[0];
@@ -1050,6 +1083,7 @@ function createAudioEngine(opts = {}) {
1050
1083
  slot: null,
1051
1084
  token: 0,
1052
1085
  key: common.cancelKey,
1086
+ onDrop: common.onDrop,
1053
1087
  source: null,
1054
1088
  env: null,
1055
1089
  retune: null,
@@ -1062,17 +1096,19 @@ function createAudioEngine(opts = {}) {
1062
1096
  detune: common.detune ?? 0,
1063
1097
  position: common.position,
1064
1098
  playing: true,
1065
- cancelled: false
1099
+ cancelled: false,
1100
+ fading: false,
1101
+ rampEnd: 0
1066
1102
  };
1067
1103
  live.set(id, voice);
1068
1104
  scheduler.schedule(when, (scheduledWhen) => {
1069
1105
  if (voice.cancelled) return;
1070
1106
  if (bookedAt < staleFloor && scheduledWhen < staleFloor) {
1071
- teardown(voice);
1107
+ teardown(voice, "stale");
1072
1108
  return;
1073
1109
  }
1074
1110
  if (!starter.ready()) {
1075
- teardown(voice);
1111
+ teardown(voice, "unready");
1076
1112
  return;
1077
1113
  }
1078
1114
  const acquired = slots.pool.acquire({
@@ -1086,7 +1122,15 @@ function createAudioEngine(opts = {}) {
1086
1122
  const victim = slots.byToken.get(acquired.stolen);
1087
1123
  if (victim) teardown(victim);
1088
1124
  }
1089
- const source = starter.start(voice, scheduledWhen);
1125
+ let source;
1126
+ try {
1127
+ source = starter.start(voice, scheduledWhen);
1128
+ } catch (err) {
1129
+ voice.chain?.gain.disconnect();
1130
+ voice.chain = null;
1131
+ teardown(voice, "failed");
1132
+ throw err;
1133
+ }
1090
1134
  source.onended = () => {
1091
1135
  teardown(voice);
1092
1136
  common.onDone?.();
@@ -1098,6 +1142,7 @@ function createAudioEngine(opts = {}) {
1098
1142
  stop(fadeMs) {
1099
1143
  if (fadeMs && fadeMs > 0 && voice.source && voice.chain && !voice.cancelled) {
1100
1144
  voice.cancelled = true;
1145
+ voice.fading = true;
1101
1146
  writeParam(ctx, voice.chain.gain.gain, 0, fadeMs);
1102
1147
  try {
1103
1148
  voice.source.stop(ctx.currentTime + fadeMs / 1e3);
@@ -1119,7 +1164,8 @@ function createAudioEngine(opts = {}) {
1119
1164
  },
1120
1165
  setGain(value, rampMs) {
1121
1166
  voice.baseGain = value;
1122
- if (!voice.chain) return;
1167
+ if (!voice.chain || voice.fading) return;
1168
+ voice.rampEnd = rampMs && rampMs > 0 ? ctx.currentTime + rampMs / 1e3 : 0;
1123
1169
  writeParam(ctx, voice.chain.gain.gain, value * voice.spatialGain, rampMs);
1124
1170
  poolGain(voice);
1125
1171
  },
@@ -1245,7 +1291,7 @@ function createAudioEngine(opts = {}) {
1245
1291
  return launch(playOpts, {
1246
1292
  ready() {
1247
1293
  if (sounds.buffer(sound)) return true;
1248
- warnUnknownSound(sound.id);
1294
+ warn.unknownSound(sound.id);
1249
1295
  return false;
1250
1296
  },
1251
1297
  start(voice, when) {
@@ -1362,9 +1408,7 @@ function createAudioEngine(opts = {}) {
1362
1408
  if (voice.key === key) teardown(voice);
1363
1409
  }
1364
1410
  },
1365
- stopAll() {
1366
- for (const voice of [...live.values()]) teardown(voice);
1367
- },
1411
+ stopAll: () => stopVoices("stopped"),
1368
1412
  bus: graph.bus,
1369
1413
  busNames: graph.names,
1370
1414
  activeVoices(bus) {
@@ -1392,7 +1436,7 @@ function createAudioEngine(opts = {}) {
1392
1436
  dispose() {
1393
1437
  if (disposed) return;
1394
1438
  disposed = true;
1395
- engine.stopAll();
1439
+ stopVoices("disposed");
1396
1440
  idleChains.length = 0;
1397
1441
  scheduler.stop();
1398
1442
  scheduler.clear();
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/analyser.ts","../src/audioTime.ts","../src/param.ts","../src/inserts.ts","../src/buses.ts","../src/scheduler.ts","../src/soundCache.ts","../src/spatialize.ts","../src/tickTimer.ts","../src/envelope.ts","../src/pitch.ts","../src/synthVoice.ts","../src/voicePool.ts","../src/createAudioEngine.ts","../src/effects.ts","../src/patternPlayer.ts"],"names":["i","prev","next","slot"],"mappings":"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","file":"index.js","sourcesContent":["/** Options for `createAnalyserTap` and `AudioEngine.analyser`. */\nexport interface AnalyserTapOptions {\n /** Power of two, 32..32768. Default 2048. */\n fftSize?: number;\n}\n\n/** An `AnalyserNode` attached to a point in the graph, with readers for its\n * spectrum, waveform and level. Each call reads the current window. */\nexport interface AnalyserTap {\n /** The underlying node, exposed for disposal assertions and advanced wiring. */\n node: AnalyserNode;\n /** Frequency data, sized `node.frequencyBinCount` when no array is given. */\n frequencies(out?: Uint8Array<ArrayBuffer>): Uint8Array<ArrayBuffer>;\n /** Time-domain data, sized `node.fftSize` when no array is given — twice the\n * frequency bin count, which is the whole window rather than half of it. */\n waveform(out?: Uint8Array<ArrayBuffer>): Uint8Array<ArrayBuffer>;\n /** RMS amplitude over the whole time-domain window, 0..1. */\n level(): number;\n /** `n` averaged frequency bands normalized to 0..1 — the ergonomic form for\n * driving a shader uniform, a vertex color, or a pose. `out`, when given,\n * must be exactly `n` long. */\n bands(n: number, out?: Float32Array<ArrayBuffer>): Float32Array<ArrayBuffer>;\n /** Detach from the tapped node. Idempotent. */\n dispose(): void;\n}\n\n/** Attach a new `AnalyserNode` to `source`. The tap only listens, adding no\n * path to the destination; `dispose()` detaches it. */\nexport function createAnalyserTap(\n ctx: AudioContext,\n source: AudioNode,\n opts: AnalyserTapOptions = {},\n): AnalyserTap {\n const node = ctx.createAnalyser();\n node.fftSize = opts.fftSize ?? 2048;\n source.connect(node);\n let attached = true;\n\n // `node` is public surface, so `fftSize` can change under the tap. Time-domain\n // data is sized by `fftSize`; frequency data by half of it.\n let freqScratch = new Uint8Array(0);\n let timeScratch = new Uint8Array(0);\n const freqBuf = (): Uint8Array<ArrayBuffer> => {\n if (freqScratch.length !== node.frequencyBinCount) {\n freqScratch = new Uint8Array(node.frequencyBinCount);\n }\n return freqScratch;\n };\n const timeBuf = (): Uint8Array<ArrayBuffer> => {\n if (timeScratch.length !== node.fftSize) timeScratch = new Uint8Array(node.fftSize);\n return timeScratch;\n };\n\n return {\n node,\n frequencies(out) {\n const target = out ?? new Uint8Array(node.frequencyBinCount);\n node.getByteFrequencyData(target);\n return target;\n },\n waveform(out) {\n const target = out ?? new Uint8Array(node.fftSize);\n node.getByteTimeDomainData(target);\n return target;\n },\n level() {\n const buf = timeBuf();\n node.getByteTimeDomainData(buf);\n let sum = 0;\n for (let i = 0; i < buf.length; i += 1) {\n // Time-domain bytes center on 128; subtract to get a signed sample.\n const v = (buf[i] - 128) / 128;\n sum += v * v;\n }\n return Math.sqrt(sum / buf.length);\n },\n bands(n, out) {\n if (!Number.isInteger(n) || n < 1) {\n throw new Error('@weasel-js/audio: bands(n) requires a positive integer');\n }\n // Unlike the byte readers, a short `out` here would return fewer bands\n // than asked for with nothing to distinguish it from a correct result.\n if (out && out.length !== n) {\n throw new Error(\n `@weasel-js/audio: bands(${n}, out) requires an out array of length ${n}, got ${out.length}`,\n );\n }\n const buf = freqBuf();\n node.getByteFrequencyData(buf);\n const target = out ?? new Float32Array(n);\n const per = buf.length / n;\n for (let b = 0; b < n; b += 1) {\n const lo = Math.floor(b * per);\n const hi = Math.max(lo + 1, Math.floor((b + 1) * per));\n let sum = 0;\n for (let i = lo; i < hi; i += 1) sum += buf[i];\n target[b] = sum / (hi - lo) / 255;\n }\n return target;\n },\n // `node.disconnect()` would cut the analyser's outgoing edges, and it has\n // none: the edge that keeps it alive is the source's.\n dispose() {\n if (!attached) return;\n attached = false;\n source.disconnect(node);\n },\n };\n}\n","/** A one-shot timer pair, as `AudioEngineOptions.setTimer` takes it. */\nexport interface Timers {\n setTimer(cb: () => void, ms: number): unknown;\n clearTimer(handle: unknown): void;\n}\n\nexport const defaultTimers: Timers = {\n setTimer: (cb, ms) => setTimeout(cb, ms),\n clearTimer: (h) => clearTimeout(h as ReturnType<typeof setTimeout>),\n};\n\n/**\n * Run `cb` once the audio clock reaches `at` (seconds), or at once when the\n * context is not running — a stopped clock never arrives, and nothing is heard\n * meanwhile. The timer alone is not enough: it runs on wall time, and a ramp\n * cut short by an early timer is the click it was scheduled to avoid.\n * Returns a cancel function.\n */\nexport function atAudioTime(\n ctx: BaseAudioContext,\n timers: Timers,\n at: number,\n cb: () => void,\n): () => void {\n let handle: unknown = null;\n let live = true;\n const check = (): void => {\n handle = null;\n if (!live) return;\n const left = at - ctx.currentTime;\n if (ctx.state === 'running' && left > 1e-6) {\n handle = timers.setTimer(check, Math.max(1, left * 1000));\n return;\n }\n live = false;\n cb();\n };\n check();\n return () => {\n live = false;\n if (handle !== null) timers.clearTimer(handle);\n handle = null;\n };\n}\n","/**\n * Every gain write in the package goes through here.\n *\n * Two traps, both silent: a bare `param.value = x` sits *behind* any scheduled\n * ramp, which keeps running and wins; and a ramp with no anchor interpolates\n * from the previous scheduled endpoint rather than from the value the param\n * holds now, so a second ramp jumps before it moves.\n */\nexport function writeParam(\n ctx: BaseAudioContext,\n param: AudioParam,\n value: number,\n rampMs?: number,\n): void {\n const now = ctx.currentTime;\n param.cancelScheduledValues(now);\n if (rampMs && rampMs > 0) {\n param.setValueAtTime(param.value, now);\n param.linearRampToValueAtTime(value, now + rampMs / 1000);\n } else {\n param.setValueAtTime(value, now);\n }\n}\n","import { atAudioTime, defaultTimers, type Timers } from './audioTime';\nimport { writeParam } from './param';\n\n/**\n * Anything with an input and an output node can sit in an insert slot: one of\n * the built-ins (`createFilterEffect` and the rest), or a pair of nodes of your\n * own — `{ input: shaper, output: shaper }` for a single node. Several nodes\n * between the two are fine too. An effect goes in one slot, once.\n */\nexport interface InsertEffect {\n readonly input: AudioNode;\n readonly output: AudioNode;\n /** Called once the effect has left the graph after `remove()` or `clear()`. */\n dispose?(): void;\n}\n\n/** One effect's place in a bus's insert chain. Every edit is click-free: a\n * bypass crossfades the slot's wet and dry, and a structural edit crossfades\n * the old route into the new one. */\nexport interface InsertSlot {\n readonly effect: InsertEffect;\n /** Route around the effect (`true`) or back through it. */\n bypass(on: boolean): void;\n bypassed(): boolean;\n /** Clamped to the chain. */\n moveTo(index: number): void;\n /** Take the effect out, then call its `dispose`. Idempotent. */\n remove(): void;\n /** Position in the chain, or -1 once removed. */\n index(): number;\n}\n\nexport interface InsertAddOptions {\n /** Default: the end of the chain. Clamped. */\n index?: number;\n /** Add it routed around, for a later `bypass(false)`. Default false. */\n bypassed?: boolean;\n}\n\n/**\n * A bus's ordered insert effects, between where voices connect and the bus's\n * fader. `slots()` is the chain as edited; the audio graph follows one\n * crossfade at a time, and `settled()` resolves once it has caught up.\n */\nexport interface InsertChain {\n add(effect: InsertEffect, opts?: InsertAddOptions): InsertSlot;\n slots(): InsertSlot[];\n clear(): void;\n settled(): Promise<void>;\n}\n\nexport interface InsertChainOptions extends Partial<Timers> {\n /** Crossfade length for every edit, in ms. Default 15. */\n fadeMs?: number;\n}\n\n/** A chain and the switch that cancels its transition in flight. */\nexport interface OwnedInsertChain {\n chain: InsertChain;\n dispose(): void;\n}\n\ninterface Slot {\n handle: InsertSlot;\n effect: InsertEffect;\n bypassed: boolean;\n removed: boolean;\n /** Built on first splice-in, kept across a move, torn down on removal. */\n nodes: { in: GainNode; out: GainNode; dry: GainNode; wet: GainNode } | null;\n}\n\n/** A gain between two consecutive points of the chain — the thing that fades\n * when a route changes. */\ninterface Link { from: AudioNode; to: AudioNode; gain: GainNode }\n\ntype Step =\n | { kind: 'out'; slot: Slot }\n | { kind: 'in'; slot: Slot; at: number };\n\n/**\n * Build an insert chain from `head` to `tail`, which start wired straight\n * through.\n *\n * A structural edit never swaps a connection instantly. A splice-in builds the\n * route through the new slot beside the old one and crossfades the two into\n * `next`; a splice-out does the reverse, so the effect's tail fades rather than\n * cuts. A move is a splice-out followed by a splice-in, never one rewire:\n * crossfading two orders at once would wire `b → c` and `c → b` together, and\n * Web Audio mutes a cycle with no delay in it.\n */\nexport function createInsertChain(\n ctx: BaseAudioContext,\n head: AudioNode,\n tail: AudioNode,\n opts: InsertChainOptions = {},\n): OwnedInsertChain {\n const fadeMs = opts.fadeMs ?? 15;\n const timers: Timers = {\n setTimer: opts.setTimer ?? defaultTimers.setTimer,\n clearTimer: opts.clearTimer ?? defaultTimers.clearTimer,\n };\n const used = new WeakSet<InsertEffect>();\n const order: Slot[] = [];\n /** The slots the audio graph routes through, in graph order. */\n const live: Slot[] = [];\n const links: Link[] = [];\n let busy = false;\n let cancel: (() => void) | null = null;\n let disposed = false;\n let waiters: (() => void)[] = [];\n\n const fade = (): number => (ctx.state === 'running' ? fadeMs : 0);\n\n const link = (from: AudioNode, to: AudioNode, gain: number): Link => {\n const g = ctx.createGain();\n // `.value` first, so `writeParam` anchors a ramp at it rather than at 1.\n g.gain.value = gain;\n writeParam(ctx, g.gain, gain);\n from.connect(g);\n g.connect(to);\n const l = { from, to, gain: g };\n links.push(l);\n return l;\n };\n\n const unlink = (l: Link): void => {\n l.from.disconnect(l.gain);\n l.gain.disconnect();\n links.splice(links.indexOf(l), 1);\n };\n\n const find = (from: AudioNode, to: AudioNode): Link =>\n links.find((l) => l.from === from && l.to === to)!;\n\n const inOf = (s: Slot | null): AudioNode => (s ? s.nodes!.in : tail);\n const outOf = (s: Slot | null): AudioNode => (s ? s.nodes!.out : head);\n\n const setBypass = (s: Slot, ms: number): void => {\n if (!s.nodes) return;\n writeParam(ctx, s.nodes.wet.gain, s.bypassed ? 0 : 1, ms);\n writeParam(ctx, s.nodes.dry.gain, s.bypassed ? 1 : 0, ms);\n };\n\n const build = (s: Slot): void => {\n if (s.nodes) return;\n const n = {\n in: ctx.createGain(), out: ctx.createGain(), dry: ctx.createGain(), wet: ctx.createGain(),\n };\n n.in.connect(s.effect.input);\n s.effect.output.connect(n.wet);\n n.wet.connect(n.out);\n n.in.connect(n.dry);\n n.dry.connect(n.out);\n s.nodes = n;\n n.wet.gain.value = s.bypassed ? 0 : 1;\n n.dry.gain.value = s.bypassed ? 1 : 0;\n setBypass(s, 0);\n };\n\n const destroy = (s: Slot): void => {\n const n = s.nodes;\n if (!n) return;\n // Targeted, not bare: the effect's nodes are the consumer's, and may be\n // wired to things besides this slot.\n n.in.disconnect();\n try { s.effect.output.disconnect(n.wet); } catch { /* already cut */ }\n n.wet.disconnect();\n n.dry.disconnect();\n n.out.disconnect();\n s.nodes = null;\n };\n\n const plan = (): Step | null => {\n const stale = live.find((s) => s.removed);\n if (stale) return { kind: 'out', slot: stale };\n const wanted = order.filter((s) => live.includes(s));\n for (let i = 0; i < wanted.length; i += 1) {\n // Out now, back in at its place on a later step.\n if (live[i] !== wanted[i]) return { kind: 'out', slot: wanted[i] };\n }\n const i = order.findIndex((s) => !live.includes(s));\n if (i < 0) return null;\n let at = 0;\n for (let j = i - 1; j >= 0; j -= 1) {\n const k = live.indexOf(order[j]);\n if (k >= 0) { at = k + 1; break; }\n }\n return { kind: 'in', slot: order[i], at };\n };\n\n /** Start `step`'s crossfade and return what finishes it. */\n const begin = (step: Step, ms: number): (() => void) => {\n const s = step.slot;\n if (step.kind === 'in') {\n build(s);\n const prev = live[step.at - 1] ?? null;\n const next = live[step.at] ?? null;\n const old = find(outOf(prev), inOf(next));\n link(outOf(prev), inOf(s), 1);\n const incoming = link(outOf(s), inOf(next), 0);\n live.splice(step.at, 0, s);\n writeParam(ctx, old.gain.gain, 0, ms);\n writeParam(ctx, incoming.gain.gain, 1, ms);\n return () => unlink(old);\n }\n const i = live.indexOf(s);\n const prev = live[i - 1] ?? null;\n const next = live[i + 1] ?? null;\n const into = find(outOf(prev), inOf(s));\n const from = find(outOf(s), inOf(next));\n const direct = link(outOf(prev), inOf(next), 0);\n live.splice(i, 1);\n writeParam(ctx, from.gain.gain, 0, ms);\n writeParam(ctx, direct.gain.gain, 1, ms);\n return () => {\n unlink(into);\n unlink(from);\n if (s.removed) {\n destroy(s);\n s.effect.dispose?.();\n }\n };\n };\n\n const pump = (): void => {\n while (!busy && !disposed) {\n const step = plan();\n if (!step) {\n const done = waiters;\n waiters = [];\n for (const w of done) w();\n return;\n }\n const ms = fade();\n const finish = begin(step, ms);\n if (ms === 0) {\n finish();\n continue;\n }\n busy = true;\n cancel = atAudioTime(ctx, timers, ctx.currentTime + ms / 1000, () => {\n cancel = null;\n busy = false;\n finish();\n pump();\n });\n }\n };\n\n link(head, tail, 1);\n\n const slotOf = (effect: InsertEffect, bypassed: boolean): Slot => {\n const s: Slot = { effect, bypassed, removed: false, nodes: null, handle: null as never };\n s.handle = {\n effect,\n bypass(on) {\n if (s.bypassed === on) return;\n s.bypassed = on;\n setBypass(s, fade());\n },\n bypassed: () => s.bypassed,\n moveTo(index) {\n const from = order.indexOf(s);\n if (from < 0) return;\n order.splice(from, 1);\n order.splice(Math.max(0, Math.min(index, order.length)), 0, s);\n pump();\n },\n remove() {\n const at = order.indexOf(s);\n if (at < 0) return;\n order.splice(at, 1);\n s.removed = true;\n pump();\n },\n index: () => order.indexOf(s),\n };\n return s;\n };\n\n const chain: InsertChain = {\n add(effect, addOpts = {}) {\n if (used.has(effect)) {\n throw new Error('@weasel-js/audio: that effect is already in an insert slot');\n }\n used.add(effect);\n const s = slotOf(effect, addOpts.bypassed ?? false);\n const index = addOpts.index ?? order.length;\n order.splice(Math.max(0, Math.min(index, order.length)), 0, s);\n pump();\n return s.handle;\n },\n slots: () => order.map((s) => s.handle),\n clear() {\n for (const s of [...order]) s.handle.remove();\n },\n settled() {\n if (!busy && plan() === null) return Promise.resolve();\n return new Promise((resolve) => { waiters.push(resolve); });\n },\n };\n return {\n chain,\n dispose() {\n disposed = true;\n cancel?.();\n cancel = null;\n },\n };\n}\n","import {\n createInsertChain, type InsertChain, type InsertChainOptions, type OwnedInsertChain,\n} from './inserts';\nimport { writeParam } from './param';\n\n/** Controls for one named bus. `rampMs` slews a gain change over that many\n * ms instead of stepping it. */\nexport interface BusHandle {\n setGain(value: number, rampMs?: number): void;\n mute(on: boolean): void;\n solo(on: boolean): void;\n /** The bus's own gain, as last set — not what a mute or solo is imposing. */\n gain(): number;\n /** The mute flag as set, independent of any solo. */\n muted(): boolean;\n /** The solo flag as set; whether it silences anything is a graph-wide answer. */\n soloed(): boolean;\n /** Whether the bus is being heard: unmuted, and soloed if any bus is soloed.\n * Not derivable from `muted()` and `soloed()` alone. */\n audible(): boolean;\n /** Effects between where the bus's voices connect and its fader. */\n readonly inserts: InsertChain;\n}\n\n/** The mix graph built by `createBusGraph`. `input(name)` is where a voice\n * connects; it runs through the bus's inserts to `node(name)`, the fader,\n * which feeds `master`, which feeds the destination. Unknown bus names throw. */\nexport interface BusGraph {\n master: GainNode;\n input(name: string): GainNode;\n node(name: string): GainNode;\n bus(name: string): BusHandle;\n names(): string[];\n /** Cancel every insert transition in flight. The nodes stay wired. */\n dispose(): void;\n}\n\n/** Options for `createBusGraph`: the insert chains' crossfade and timer. */\nexport type BusGraphOptions = InsertChainOptions;\n\ninterface BusState {\n input: GainNode;\n node: GainNode;\n inserts: OwnedInsertChain;\n gain: number;\n muted: boolean;\n soloed: boolean;\n}\n\n/**\n * The mix graph: one `GainNode` per named bus, all routed to a master that\n * routes to the destination.\n *\n * Gain, mute and solo are three inputs to one output value rather than three\n * things that write the node directly — otherwise unmuting restores the wrong\n * value whenever a solo changed it in between. All three write through\n * `writeParam`, so `rampMs` survives instead of being overwritten by the\n * recomputation that follows it.\n */\nexport function createBusGraph(\n ctx: AudioContext,\n names: string[],\n opts: BusGraphOptions = {},\n): BusGraph {\n const master = ctx.createGain();\n master.connect(ctx.destination);\n\n const states = new Map<string, BusState>();\n for (const name of names) {\n const input = ctx.createGain();\n const node = ctx.createGain();\n node.connect(master);\n const inserts = createInsertChain(ctx, input, node, opts);\n states.set(name, { input, node, inserts, gain: 1, muted: false, soloed: false });\n }\n\n const anySoloed = (): boolean => {\n for (const s of states.values()) if (s.soloed) return true;\n return false;\n };\n\n const audibleUnder = (s: BusState, soloing: boolean): boolean =>\n !s.muted && (!soloing || s.soloed);\n\n // `ramp` names the one bus whose own value changed, so a solo does not slew\n // every other bus at whatever rate that bus was last set with.\n const apply = (ramp?: { bus: BusState; ms: number }): void => {\n const soloing = anySoloed();\n for (const s of states.values()) {\n const value = audibleUnder(s, soloing) ? s.gain : 0;\n writeParam(ctx, s.node.gain, value, ramp?.bus === s ? ramp.ms : undefined);\n }\n };\n\n const get = (name: string): BusState => {\n const s = states.get(name);\n if (!s) throw new Error(`@weasel-js/audio: unknown bus \"${name}\"`);\n return s;\n };\n\n return {\n master,\n input: (name) => get(name).input,\n node: (name) => get(name).node,\n names: () => [...states.keys()],\n dispose() {\n for (const s of states.values()) s.inserts.dispose();\n },\n bus(name) {\n const s = get(name);\n return {\n setGain(value, rampMs) {\n s.gain = value;\n apply(rampMs && rampMs > 0 ? { bus: s, ms: rampMs } : undefined);\n },\n mute(on) { s.muted = on; apply(); },\n solo(on) { s.soloed = on; apply(); },\n gain: () => s.gain,\n muted: () => s.muted,\n soloed: () => s.soloed,\n audible: () => audibleUnder(s, anySoloed()),\n inserts: s.inserts.chain,\n };\n },\n };\n}\n","/** Clock and timer for `createScheduler`. */\nexport interface SchedulerOptions {\n /** Engine time in ms. Backed by `AudioContext.currentTime * 1000` in production. */\n now: () => number;\n /** One-shot: it fires once and the pass re-arms it. `setInterval` here would\n * leave every previous timer running. */\n setTimer: (cb: () => void, ms: number) => unknown;\n clearTimer: (handle: unknown) => void;\n /** How far ahead to book events, in ms. Default 100. */\n lookahead?: number;\n /** Time between passes, in ms. Default 25. */\n interval?: number;\n}\n\ninterface Entry {\n when: number;\n fire: (when: number) => void;\n key?: string;\n}\n\n/** A queue of callbacks keyed to engine time. See `createScheduler`. */\nexport interface Scheduler {\n start(): void;\n /** Stop the timer. The queue survives; `clear()` empties it. */\n stop(): void;\n /** Book `fire` for engine time `when`, receiving `when` so it can hand the\n * true time to `source.start()` rather than \"now\". It runs on the first\n * pass whose lookahead window reaches it — or, when the window already\n * covers it and the scheduler is running, at the end of the current task,\n * in time order with everything else then due. */\n schedule(when: number, fire: (when: number) => void, key?: string): void;\n /** Drop queued events with this key. A pass takes its whole batch out of the\n * queue before firing any of it, so a callback cannot cancel a sibling that\n * came due alongside it. */\n cancelKey(key: string): void;\n /** Drop every queued event. Without this, a stop/start cycle fires\n * everything that came due meanwhile in one burst on the first pass. */\n clear(): void;\n pending(): number;\n}\n\n/**\n * Lookahead scheduler. Each pass fires everything due within `lookahead` ms,\n * in time order, handing each callback its own scheduled time. An event\n * scheduled inside that window does not wait up to `interval` for the next\n * pass: the end of the current task fires what is due then.\n *\n * It runs on its own timer rather than on an animation frame, which stops\n * entirely when nothing is animating. The timer is one-shot: the pass re-arms\n * it at the end, so passes cannot overlap. A main-thread `setTimeout` is clamped\n * to a second in a hidden tab, which the lookahead cannot cover; the engine\n * passes `createTickTimer` instead.\n */\nexport function createScheduler(opts: SchedulerOptions): Scheduler {\n const lookahead = opts.lookahead ?? 100;\n const interval = opts.interval ?? 25;\n let queue: Entry[] = [];\n let running = false;\n let handle: unknown = null;\n\n let flushQueued = false;\n\n const fireDue = (): void => {\n const horizon = opts.now() + lookahead;\n const due: Entry[] = [];\n const rest: Entry[] = [];\n for (const entry of queue) (entry.when <= horizon ? due : rest).push(entry);\n queue = rest;\n due.sort((a, b) => a.when - b.when);\n for (const entry of due) {\n try {\n entry.fire(entry.when);\n } catch (err) {\n console.error('@weasel-js/audio scheduler: callback threw', err);\n }\n }\n };\n\n const pass = (): void => {\n fireDue();\n if (running) handle = opts.setTimer(pass, interval);\n };\n\n // A microtask rather than firing inside `schedule()`: everything booked in\n // one task is fired as one batch, sorted by time, exactly as a pass would.\n const flush = (): void => {\n flushQueued = false;\n if (running) fireDue();\n };\n\n return {\n start() {\n if (running) return;\n running = true;\n handle = opts.setTimer(pass, interval);\n },\n stop() {\n if (!running) return;\n running = false;\n opts.clearTimer(handle);\n handle = null;\n },\n schedule(when, fire, key) {\n queue.push({ when, fire, key });\n if (running && !flushQueued && when <= opts.now() + lookahead) {\n flushQueued = true;\n queueMicrotask(flush);\n }\n },\n cancelKey(key) {\n queue = queue.filter((e) => e.key !== key);\n },\n clear() {\n queue = [];\n },\n pending: () => queue.length,\n };\n}\n","/** Opaque reference to a decoded sound. Mirrors `TextureHandle` in core. */\nexport interface SoundHandle { readonly id: string }\n\n/** Decoded buffers behind opaque `SoundHandle`s. Nothing is ever evicted. */\nexport interface SoundCache {\n load(url: string): Promise<SoundHandle>;\n loadAll(urls: Record<string, string>): Promise<Record<string, SoundHandle>>;\n decode(bytes: ArrayBuffer): Promise<SoundHandle>;\n /** Take ownership of a buffer the caller already has — a procedural synth,\n * an OfflineAudioContext render, a recording. Synchronous; nothing to decode. */\n register(buffer: AudioBuffer): SoundHandle;\n buffer(handle: SoundHandle): AudioBuffer | null;\n}\n\n/** Create a cache that decodes through `ctx`. `load` fetches with `fetchFn`,\n * returns the existing handle for a url already loaded, and shares one fetch\n * between concurrent loads of it; a failed load is not cached. */\nexport function createSoundCache(\n ctx: AudioContext,\n fetchFn: typeof fetch = fetch,\n): SoundCache {\n let counter = 0;\n const buffers = new Map<string, AudioBuffer>();\n const byUrl = new Map<string, SoundHandle>();\n // In-flight loads, so two concurrent `load` calls for one url share a fetch.\n const inflight = new Map<string, Promise<SoundHandle>>();\n\n const store = (buffer: AudioBuffer): SoundHandle => {\n const id = `snd_${++counter}`;\n buffers.set(id, buffer);\n return { id };\n };\n\n const cache: SoundCache = {\n async load(url) {\n const existing = byUrl.get(url);\n if (existing) return existing;\n const pending = inflight.get(url);\n if (pending) return pending;\n\n const task = (async () => {\n const res = await fetchFn(url);\n if (!res.ok) throw new Error(`@weasel-js/audio: failed to load ${url} (${res.status})`);\n const bytes = await res.arrayBuffer();\n const buffer = await ctx.decodeAudioData(bytes);\n const handle = store(buffer);\n byUrl.set(url, handle);\n return handle;\n })();\n\n inflight.set(url, task);\n try {\n return await task;\n } finally {\n // Always clear: a failed load must not be cached, or a retry can never\n // succeed for the lifetime of the page.\n inflight.delete(url);\n }\n },\n async loadAll(urls) {\n const names = Object.keys(urls);\n const handles = await Promise.all(names.map((n) => cache.load(urls[n])));\n return Object.fromEntries(names.map((n, i) => [n, handles[i]]));\n },\n async decode(bytes) {\n return store(await ctx.decodeAudioData(bytes));\n },\n register: (buffer) => store(buffer),\n buffer: (handle) => buffers.get(handle.id) ?? null,\n };\n return cache;\n}\n","/** A 2D world position, in the consumer's own units. */\nexport interface Vec2 { x: number; y: number }\n\n/** Distance and pan model for `spatialize`, in the same units as the\n * positions. */\nexport interface SpatialOptions {\n /** Distance within which gain stays at 1. Default 1. The inverse model needs\n * this above 0: at 0 it cliffs gain from 1 to 0 at any nonzero distance. */\n refDistance?: number;\n /** Distance at which linear rolloff reaches 0. Ignored by inverse. Default\n * 10000. At or below `refDistance` it gives the same 1-to-0 cliff, there. */\n maxDistance?: number;\n /** Default 'inverse' — the natural-sounding one. */\n rolloff?: 'inverse' | 'linear';\n /** How sharply gain falls. Default 1. */\n rolloffFactor?: number;\n /** Horizontal distance mapping to full left/right. Default 500. */\n panWidth?: number;\n}\n\n/**\n * Map a source position to a gain and a stereo pan, relative to the listener.\n *\n * Pure — no Web Audio, no state. This is the whole spatial model.\n */\nexport function spatialize(\n source: Vec2,\n listener: Vec2,\n opts: SpatialOptions = {},\n): { gain: number; pan: number } {\n const refDistance = opts.refDistance ?? 1;\n const maxDistance = opts.maxDistance ?? 10000;\n const rolloff = opts.rolloff ?? 'inverse';\n const rolloffFactor = opts.rolloffFactor ?? 1;\n const panWidth = opts.panWidth ?? 500;\n\n const dx = source.x - listener.x;\n const dy = source.y - listener.y;\n const distance = Math.hypot(dx, dy);\n\n let gain: number;\n if (distance <= refDistance) {\n gain = 1;\n } else if (rolloff === 'linear') {\n const span = maxDistance - refDistance;\n gain = span <= 0 ? 0 : 1 - rolloffFactor * ((distance - refDistance) / span);\n } else {\n gain = refDistance / (refDistance + rolloffFactor * (distance - refDistance));\n }\n gain = Math.min(1, Math.max(0, gain));\n\n const pan = panWidth <= 0 ? 0 : Math.min(1, Math.max(-1, dx / panWidth));\n\n return { gain, pan };\n}\n","/** Runs in the worker. A message with `ms` books timer `id`; one without clears\n * it. Each timer posts its id back once, when it elapses. */\nconst WORKER_SOURCE = `const timers = new Map();\nself.onmessage = (e) => {\n const id = e.data.id;\n clearTimeout(timers.get(id));\n timers.delete(id);\n if (e.data.ms === undefined) return;\n timers.set(id, setTimeout(() => {\n timers.delete(id);\n self.postMessage(id);\n }, e.data.ms));\n};\n`;\n\n/** The timer pair `createTickTimer` returns, shaped for `SchedulerOptions`. */\nexport interface TickTimer {\n /** One-shot, as `createScheduler` expects. */\n setTimer(cb: () => void, ms: number): unknown;\n clearTimer(handle: unknown): void;\n /** Terminate the worker and drop every pending timer. */\n dispose(): void;\n}\n\ninterface Pending {\n cb: () => void;\n ms: number;\n fallback?: ReturnType<typeof setTimeout>;\n}\n\nfunction spawn(): { worker: Worker; url: string } | null {\n if (\n typeof Worker !== 'function' ||\n typeof Blob !== 'function' ||\n typeof URL === 'undefined' ||\n typeof URL.createObjectURL !== 'function'\n ) {\n return null;\n }\n let url: string | undefined;\n try {\n url = URL.createObjectURL(new Blob([WORKER_SOURCE], { type: 'text/javascript' }));\n return { worker: new Worker(url), url };\n } catch {\n if (url !== undefined) URL.revokeObjectURL(url);\n return null;\n }\n}\n\n/**\n * A timer for the scheduler's pass that is not held to the main thread's\n * hidden-tab clamp: each delay runs inside a dedicated Worker, which posts back\n * when it elapses. Falls back to `setTimeout` when no worker can be made — no\n * `Worker` global, a constructor that throws, or a worker that fails to load,\n * which is how a CSP refusal can arrive.\n */\nexport function createTickTimer(): TickTimer {\n let nextId = 1;\n const pending = new Map<number, Pending>();\n let spawned = spawn();\n\n const fire = (id: number): void => {\n const p = pending.get(id);\n if (!p) return;\n pending.delete(id);\n p.cb();\n };\n const arm = (id: number, p: Pending): void => {\n p.fallback = setTimeout(() => fire(id), p.ms);\n };\n const release = (): void => {\n if (!spawned) return;\n spawned.worker.terminate();\n URL.revokeObjectURL(spawned.url);\n spawned = null;\n };\n\n if (spawned) {\n spawned.worker.addEventListener('message', (e: MessageEvent) => fire(e.data as number));\n spawned.worker.addEventListener('error', () => {\n if (!spawned) return;\n release();\n // Anything posted to a worker that never loaded is lost with it.\n for (const [id, p] of pending) arm(id, p);\n });\n }\n\n return {\n setTimer(cb, ms) {\n const id = nextId++;\n const p: Pending = { cb, ms };\n pending.set(id, p);\n if (spawned) spawned.worker.postMessage({ id, ms });\n else arm(id, p);\n return id;\n },\n clearTimer(handle) {\n const id = handle as number;\n const p = pending.get(id);\n if (!p) return;\n pending.delete(id);\n if (p.fallback !== undefined) clearTimeout(p.fallback);\n else spawned?.worker.postMessage({ id });\n },\n dispose() {\n for (const p of pending.values()) {\n if (p.fallback !== undefined) clearTimeout(p.fallback);\n }\n pending.clear();\n release();\n },\n };\n}\n","/** An ADSR envelope. Times are ms; `sustain` is a level, 0..1, of the peak. */\nexport interface Envelope {\n /** Default 5 — long enough that the onset does not click. */\n attack?: number;\n /** Default 0. */\n decay?: number;\n /** Default 1. */\n sustain?: number;\n /** Default 30. */\n release?: number;\n}\n\nexport type ResolvedEnvelope = Required<Envelope>;\n\nexport interface EnvelopePoint {\n /** ms from the note's start. */\n at: number;\n value: number;\n}\n\nexport function resolveEnvelope(env: Envelope = {}): ResolvedEnvelope {\n return {\n attack: Math.max(0, env.attack ?? 5),\n decay: Math.max(0, env.decay ?? 0),\n sustain: Math.min(1, Math.max(0, env.sustain ?? 1)),\n release: Math.max(0, env.release ?? 30),\n };\n}\n\nconst heldLevel = (e: ResolvedEnvelope, t: number): number => {\n if (t < e.attack) return t / e.attack;\n if (t < e.attack + e.decay) return 1 - ((1 - e.sustain) * (t - e.attack)) / e.decay;\n return e.sustain;\n};\n\n/** The level `t` ms after the start. With `gate`, the release begins that many\n * ms in, from whatever level the envelope had reached. */\nexport function envelopeLevel(e: ResolvedEnvelope, t: number, gate?: number): number {\n if (gate === undefined || t <= gate) return heldLevel(e, t);\n if (e.release === 0) return 0;\n return Math.max(0, heldLevel(e, gate) * (1 - (t - gate) / e.release));\n}\n\n/**\n * Breakpoints joined by linear ramps. Without `gate` they end at the sustain,\n * held until something releases the note; with it they end at zero, `gate +\n * release` ms in.\n */\nexport function envelopePoints(e: ResolvedEnvelope, gate?: number): EnvelopePoint[] {\n const end = gate ?? Infinity;\n const points: EnvelopePoint[] = [{ at: 0, value: e.attack > 0 ? 0 : 1 }];\n for (const at of [e.attack, e.attack + e.decay]) {\n if (at <= points[points.length - 1].at) continue;\n if (at >= end) break;\n points.push({ at, value: heldLevel(e, at) });\n }\n if (gate === undefined) return points;\n if (gate > points[points.length - 1].at) points.push({ at: gate, value: heldLevel(e, gate) });\n points.push({ at: gate + e.release, value: 0 });\n return points;\n}\n","/** A pitch: hertz as a number, a scientific pitch name (`'A4'`, `'C#3'`,\n * `'Bb2'`), or a MIDI note number wrapped as `{ midi }` so it cannot be read\n * as hertz. */\nexport type Pitch = number | string | { midi: number };\n\n/** Equal temperament, A4 = MIDI 69 = 440 Hz. Fractional notes are cents. */\nexport function midiToFrequency(midi: number): number {\n return 440 * 2 ** ((midi - 69) / 12);\n}\n\nconst LETTERS: Record<string, number> = { c: 0, d: 2, e: 4, f: 5, g: 7, a: 9, b: 11 };\n\n/** MIDI number of a scientific pitch name: C4 is 60. Accepts any run of `#`\n * or `b` after the letter. */\nexport function noteToMidi(name: string): number {\n const m = /^([A-Ga-g])([#b]*)(-?\\d+)$/.exec(name.trim());\n if (!m) throw new Error(`@weasel-js/audio: cannot read \"${name}\" as a note name`);\n let semitone = LETTERS[m[1].toLowerCase()];\n for (const acc of m[2]) semitone += acc === '#' ? 1 : -1;\n return (Number(m[3]) + 1) * 12 + semitone;\n}\n\nexport function toFrequency(pitch: Pitch): number {\n const hz = typeof pitch === 'number' ? pitch\n : typeof pitch === 'string' ? midiToFrequency(noteToMidi(pitch))\n : midiToFrequency(pitch.midi);\n if (!(hz > 0) || !Number.isFinite(hz)) {\n throw new RangeError(`@weasel-js/audio: a pitch must be a positive frequency, got ${hz}`);\n }\n return hz;\n}\n","import { envelopeLevel, envelopePoints, resolveEnvelope, type ResolvedEnvelope } from './envelope';\nimport type { Inharmonic, NoiseColor, SynthPartial, VoiceFilter, Waveform } from './types';\n\n/** Seconds of noise in each cached loop: long enough that the repeat is not\n * heard as a pitch. */\nconst NOISE_SECONDS = 2;\n/** Every color is scaled to this RMS, so changing color does not change level. */\nconst NOISE_RMS = 0.25;\n\nconst noiseCache = new WeakMap<BaseAudioContext, Map<NoiseColor, AudioBuffer>>();\n\n/** Samples of `color` noise, seeded so every context gets the same loop. The\n * end is pulled onto the start, so the loop point does not click. */\nexport function noiseSamples(color: NoiseColor, length: number): Float32Array {\n const out = new Float32Array(length);\n let s = 0x9e3779b9;\n const white = (): number => {\n s = (Math.imul(s, 1664525) + 1013904223) >>> 0;\n return (s / 0x100000000) * 2 - 1;\n };\n if (color === 'white') {\n for (let i = 0; i < length; i += 1) out[i] = white();\n } else if (color === 'pink') {\n // Paul Kellet's refined filter: within 0.05 dB of -3 dB/octave above 9 Hz.\n let b0 = 0, b1 = 0, b2 = 0, b3 = 0, b4 = 0, b5 = 0, b6 = 0;\n for (let i = 0; i < length; i += 1) {\n const w = white();\n b0 = 0.99886 * b0 + w * 0.0555179;\n b1 = 0.99332 * b1 + w * 0.0750759;\n b2 = 0.969 * b2 + w * 0.153852;\n b3 = 0.8665 * b3 + w * 0.3104856;\n b4 = 0.55 * b4 + w * 0.5329522;\n b5 = -0.7616 * b5 - w * 0.016898;\n out[i] = b0 + b1 + b2 + b3 + b4 + b5 + b6 + w * 0.5362;\n b6 = w * 0.115926;\n }\n } else {\n // A leaky integrator: -6 dB/octave down to a few Hz, without wandering off.\n let y = 0;\n for (let i = 0; i < length; i += 1) {\n y = (y + 0.02 * white()) / 1.02;\n out[i] = y;\n }\n }\n const step = (out[length - 1] - out[0]) / Math.max(1, length - 1);\n let mean = 0;\n for (let i = 0; i < length; i += 1) {\n out[i] -= step * i;\n mean += out[i];\n }\n mean /= length;\n let sq = 0;\n for (let i = 0; i < length; i += 1) {\n out[i] -= mean;\n sq += out[i] * out[i];\n }\n const scale = sq > 0 ? NOISE_RMS / Math.sqrt(sq / length) : 0;\n for (let i = 0; i < length; i += 1) out[i] *= scale;\n return out;\n}\n\n/** One looping noise buffer per color per context, made on first use. */\nexport function noiseBuffer(ctx: BaseAudioContext, color: NoiseColor): AudioBuffer {\n let byColor = noiseCache.get(ctx);\n if (!byColor) {\n byColor = new Map();\n noiseCache.set(ctx, byColor);\n }\n let buffer = byColor.get(color);\n if (!buffer) {\n const length = Math.round(ctx.sampleRate * NOISE_SECONDS);\n buffer = ctx.createBuffer(1, length, ctx.sampleRate);\n buffer.getChannelData(0).set(noiseSamples(color, length));\n byColor.set(color, buffer);\n }\n return buffer;\n}\n\nexport const isInharmonic = (wave: Waveform): wave is Inharmonic =>\n typeof wave === 'object' && !Array.isArray(wave);\n\n/** Partials with their levels normalized to sum to 1, checked where the note\n * was written rather than when it comes due. */\nexport function resolvePartials(wave: Inharmonic): (SynthPartial & { gain: number })[] {\n if (wave.partials.length === 0) {\n throw new RangeError('@weasel-js/audio: an inharmonic wave needs at least one partial');\n }\n let total = 0;\n for (const p of wave.partials) {\n if (!(p.ratio > 0) || !Number.isFinite(p.ratio)) {\n throw new RangeError(`@weasel-js/audio: partial ratio must be a positive number, got ${p.ratio}`);\n }\n if (p.decay !== undefined && !(p.decay > 0)) {\n throw new RangeError(`@weasel-js/audio: partial decay must be a positive number of ms, got ${p.decay}`);\n }\n total += Math.abs(p.gain ?? 1);\n }\n return wave.partials.map((p) => ({\n ratio: p.ratio,\n gain: total > 0 ? (p.gain ?? 1) / total : 0,\n decay: p.decay,\n }));\n}\n\n/** An envelope written onto a param from `t0` (seconds), mapped through `map`,\n * and the note-off that releases it from wherever it has got to. */\nexport function envelopeOnParam(\n param: AudioParam,\n env: ResolvedEnvelope,\n gate: number | undefined,\n t0: number,\n map: (level: number) => number,\n): { release(at: number): void } {\n const [first, ...rest] = envelopePoints(env, gate);\n param.setValueAtTime(map(first.value), t0);\n for (const p of rest) param.linearRampToValueAtTime(map(p.value), t0 + p.at / 1000);\n return {\n release(at) {\n const elapsed = Math.max(0, (at - t0) * 1000);\n param.cancelScheduledValues(at);\n param.setValueAtTime(map(envelopeLevel(env, elapsed)), at);\n param.linearRampToValueAtTime(map(0), at + env.release / 1000);\n },\n };\n}\n\n/** A voice filter's node, scheduled from `t0`, with its envelope's release. */\nexport function voiceFilter(\n ctx: BaseAudioContext,\n spec: VoiceFilter,\n gate: number | undefined,\n t0: number,\n): { node: BiquadFilterNode; release(at: number): void } {\n const node = ctx.createBiquadFilter();\n node.type = spec.type ?? 'lowpass';\n node.Q.setValueAtTime(spec.Q ?? 1, t0);\n if (spec.gain !== undefined) node.gain.setValueAtTime(spec.gain, t0);\n const amount = spec.amount ?? 0;\n if (!spec.envelope || amount === 0) {\n node.frequency.setValueAtTime(spec.frequency, t0);\n return { node, release: () => {} };\n }\n const cutoff = envelopeOnParam(\n node.frequency, resolveEnvelope(spec.envelope), gate, t0, (v) => spec.frequency + amount * v,\n );\n return { node, release: cutoff.release };\n}\n\n/**\n * Ready-made inharmonic waves. The ratios are the textbook modes of each\n * object; the levels and decays are a starting point to spread and adjust.\n */\nexport const partialPresets = {\n /** A church bell's hum, prime, tierce, quint and nominal, and above. */\n bell: {\n partials: [\n { ratio: 0.5, gain: 0.6, decay: 1800 },\n { ratio: 1, gain: 1, decay: 1200 },\n { ratio: 1.183, gain: 0.7, decay: 900 },\n { ratio: 1.506, gain: 0.4, decay: 700 },\n { ratio: 2, gain: 0.8, decay: 600 },\n { ratio: 2.514, gain: 0.3, decay: 400 },\n { ratio: 2.662, gain: 0.25, decay: 350 },\n { ratio: 3.011, gain: 0.2, decay: 300 },\n ],\n },\n /** A tuned bar: its overtones sit near 4 and 10 times the fundamental and die fast. */\n marimba: {\n partials: [\n { ratio: 1, gain: 1, decay: 350 },\n { ratio: 3.984, gain: 0.35, decay: 90 },\n { ratio: 9.95, gain: 0.12, decay: 30 },\n ],\n },\n /** Struck sheet metal: modes nowhere near the harmonic series. */\n metal: {\n partials: [\n { ratio: 1, gain: 1, decay: 160 },\n { ratio: 1.71, gain: 0.53, decay: 120 },\n { ratio: 2.43, gain: 0.36, decay: 94 },\n { ratio: 3.19, gain: 0.27, decay: 78 },\n { ratio: 4.61, gain: 0.22, decay: 66 },\n { ratio: 5.87, gain: 0.18, decay: 58 },\n ],\n },\n} satisfies Record<string, Inharmonic>;\n","/** Which voice a full pool evicts: the earliest started, or the lowest gain. */\nexport type StealPolicy = 'oldest' | 'quietest';\n\n/** Options for `createVoicePool`. */\nexport interface VoicePoolOptions {\n /** Maximum concurrent voices, at least 1. Beyond this, `acquire` steals. */\n limit: number;\n /** Default 'oldest'. */\n steal?: StealPolicy;\n}\n\n/** What the pool knows about a voice, for choosing one to steal. */\nexport interface VoiceRecord {\n /** Engine time the voice started, in ms. */\n startedAt: number;\n /** Current gain, consulted by the 'quietest' steal policy. */\n gain: number;\n}\n\n/** The result of `VoicePool.acquire`. */\nexport interface Acquisition {\n slot: number;\n /** Identifies this voice, not its slot: a stolen slot is reissued at once,\n * so `release` and `setGain` take the token and ignore a stale one. */\n token: number;\n /** Token of the voice evicted to make room, or null. The caller is\n * responsible for actually stopping that voice's nodes. */\n stolen: number | null;\n}\n\n/** Slot accounting for concurrent voices. See `createVoicePool`. */\nexport interface VoicePool {\n acquire(record: VoiceRecord): Acquisition;\n release(slot: number, token: number): void;\n setGain(slot: number, token: number, gain: number): void;\n active(): number;\n}\n\n/**\n * Slot bookkeeping for concurrent voices, with a steal policy for when the\n * limit is reached.\n *\n * This is pure accounting — it owns no audio nodes. The engine reuses its\n * `GainNode`/`StereoPannerNode` chains separately, and mints a fresh\n * `AudioBufferSourceNode` per play, because a source node is single-use by\n * specification and cannot be restarted once stopped.\n */\nexport function createVoicePool(opts: VoicePoolOptions): VoicePool {\n if (!(opts.limit >= 1)) {\n throw new RangeError(`@weasel-js/audio: voice pool limit must be at least 1, got ${opts.limit}`);\n }\n const steal = opts.steal ?? 'oldest';\n const live = new Map<number, VoiceRecord & { token: number }>();\n const free: number[] = [];\n let nextSlot = 0;\n let nextToken = 1;\n\n const victim = (): number => {\n let worst = -1;\n let worstScore = Infinity;\n for (const [slot, rec] of live) {\n const score = steal === 'quietest' ? rec.gain : rec.startedAt;\n if (score < worstScore) { worstScore = score; worst = slot; }\n }\n return worst;\n };\n\n return {\n acquire(record) {\n const token = nextToken++;\n if (live.size < opts.limit) {\n const slot = free.length > 0 ? free.pop()! : nextSlot++;\n live.set(slot, { ...record, token });\n return { slot, token, stolen: null };\n }\n const slot = victim();\n const stolen = live.get(slot)!.token;\n // Re-inserting moves the slot to the back of the iteration order, so\n // voices tied on score take turns being the victim.\n live.delete(slot);\n live.set(slot, { ...record, token });\n return { slot, token, stolen };\n },\n release(slot, token) {\n if (live.get(slot)?.token !== token) return;\n live.delete(slot);\n free.push(slot);\n },\n setGain(slot, token, gain) {\n const rec = live.get(slot);\n if (rec?.token === token) rec.gain = gain;\n },\n active: () => live.size,\n };\n}\n","import { createAnalyserTap, type AnalyserTap, type AnalyserTapOptions } from './analyser';\nimport { atAudioTime, defaultTimers, type Timers } from './audioTime';\nimport { createBusGraph, type BusHandle } from './buses';\nimport { writeParam } from './param';\nimport { createScheduler } from './scheduler';\nimport { createSoundCache, type SoundHandle } from './soundCache';\nimport { spatialize, type SpatialOptions, type Vec2 } from './spatialize';\nimport { createTickTimer } from './tickTimer';\nimport { resolveEnvelope, type Envelope } from './envelope';\nimport { toFrequency } from './pitch';\nimport {\n envelopeOnParam, isInharmonic, noiseBuffer, resolvePartials, voiceFilter,\n} from './synthVoice';\nimport type {\n AudioEngineOptions, Inharmonic, NoiseOptions, NoteOptions, PlayOptions, StreamOptions,\n VoiceFilter, VoiceHandle, Waveform,\n} from './types';\nimport { createVoicePool, type VoicePool } from './voicePool';\n\n/** A sound engine: named mix buses, a per-bus voice pool, lookahead\n * scheduling and 2D spatialization over one `AudioContext`. Times are engine\n * ms (`now()`). */\nexport interface AudioEngine {\n /** The engine's `AudioContext` — the one passed as `options.context`, or the\n * one the engine created. Use it for `createBuffer`, for analysis, or for a\n * node graph of your own alongside the engine's.\n *\n * `dispose()` closes a context the engine created, and every call on a\n * closed context throws; a context you passed in is left open, because it is\n * yours to close. The reference stays valid either way — read `state()`\n * rather than assuming. */\n readonly context: AudioContext;\n state(): AudioContextState;\n unlock(): Promise<void>;\n /** Engine time in ms. */\n now(): number;\n load(url: string): Promise<SoundHandle>;\n loadAll(urls: Record<string, string>): Promise<Record<string, SoundHandle>>;\n decode(bytes: ArrayBuffer): Promise<SoundHandle>;\n /** Play a buffer the consumer already holds — a synth, an offline render, a\n * recording. `load` and `decode` both assume encoded bytes. */\n register(buffer: AudioBuffer): SoundHandle;\n play(sound: SoundHandle, opts?: PlayOptions): VoiceHandle;\n /** Play a synthesized note: an oscillator with harmonic partials, or summed\n * sines at any ratios, under an ADSR envelope and an optional filter. It is a voice like any other — same handle, same bus pool\n * and stealing, same `cancelKey`. */\n playNote(note: NoteOptions): VoiceHandle;\n /** Play noise — white, pink or brown, from a looping buffer made once per\n * context — under an envelope and an optional filter with its own cutoff\n * envelope. A voice like `playNote`'s in every other respect. */\n playNoise(noise: NoiseOptions): VoiceHandle;\n /** Stream long audio — music, ambience — from a media element or a URL\n * through a `MediaElementAudioSourceNode`, instead of decoding it whole. It\n * is a voice on a bus like any other, with the exceptions `StreamOptions`\n * lists. An element has one playhead, so streaming one that is already\n * streaming stops the earlier voice. */\n stream(media: HTMLMediaElement | string, opts?: StreamOptions): VoiceHandle;\n /** Book a callback against the audio clock through the engine's lookahead\n * scheduler; it receives its own `when` to hand on to `play` or `playNote`.\n * `stopKey(key)` cancels it. One that came due during a suspension fires\n * late on resume, with its original `when`, so compare against `now()`. */\n schedule(when: number, fire: (when: number) => void, key?: string): void;\n stopKey(key: string): void;\n stopAll(): void;\n bus(name: string): BusHandle;\n /** The configured bus names, in order. The first is `play()`'s default. */\n busNames(): string[];\n /** Voices currently sounding, on one bus or on all of them. A voice booked\n * for a future `when` is not counted until it starts. */\n activeVoices(bus?: string): number;\n analyser(busName?: string, opts?: AnalyserTapOptions): AnalyserTap;\n setListener(p: Vec2, opts?: SpatialOptions): void;\n dispose(): void;\n}\n\n/** A voice pool and its token index. Tokens restart at 1 in every pool, so the\n * index has to be per pool — keyed by bus name, a shared pool would look a\n * steal victim up under the wrong name and silently never tear it down. */\ninterface Slots {\n pool: VoicePool;\n byToken: Map<number, LiveVoice>;\n}\n\n/** What `play` and `playNote` share apart from the node they make. */\ntype VoiceOptions = Omit<PlayOptions, 'loop'>;\n\n/** What a voice plays through: a scheduled source node, or a stand-in with\n * the same end-of-life contract — `onended` fires asynchronously, once. */\ntype SourceLike = Pick<AudioScheduledSourceNode, 'onended' | 'stop' | 'disconnect'>;\n\n/** Several sources stopped together, as one: the first carries `onended`. */\nconst sourceGroup = (nodes: AudioScheduledSourceNode[]): SourceLike => ({\n get onended() { return nodes[0].onended; },\n set onended(fn) { nodes[0].onended = fn; },\n stop(when?: number) {\n for (const n of nodes) {\n try { n.stop(when); } catch { /* not started, or already stopped */ }\n }\n },\n disconnect() { for (const n of nodes) n.disconnect(); },\n});\n\ninterface Starter {\n /** False drops the voice when it comes due. */\n ready(): boolean;\n start(voice: LiveVoice, when: number): SourceLike;\n}\n\ninterface Chain {\n gain: GainNode;\n panner: StereoPannerNode;\n}\n\ninterface LiveVoice {\n id: number;\n slots: Slots;\n /** Null until the scheduler fires it: a voice booked seconds out must not\n * hold a slot, and must not be an eviction candidate, while silent. */\n slot: number | null;\n token: number;\n key?: string;\n source: SourceLike | null;\n /** A synth voice's envelope gain, between its sources and the chain. */\n env: GainNode | null;\n /** Writes `rate` and `detune` to the node, once there is one. */\n retune: (() => void) | null;\n /** A synth voice's note-off. Null for a buffer voice, and until it starts. */\n release: (() => void) | null;\n releasing: boolean;\n /** Null once torn down, when the chain goes back to be reused: a handle\n * that outlives its voice must not write to another voice's nodes. */\n chain: Chain | null;\n baseGain: number;\n spatialGain: number;\n rate: number;\n detune: number;\n /** Kept so `setListener` can re-spatialize a voice that is already playing. */\n position?: Vec2;\n playing: boolean;\n cancelled: boolean;\n}\n\n/**\n * Create an engine. Browsers start the context suspended: `play()` before it\n * is unlocked drops the voice with a warning. The engine resumes it on the\n * first pointer, key or touch gesture, or call `unlock()` from one. Call\n * `dispose()` when done.\n */\nexport function createAudioEngine(opts: AudioEngineOptions = {}): AudioEngine {\n const ctx = opts.context ?? new AudioContext();\n // A context the engine made is a context the engine closes; a consumer's is\n // theirs to keep.\n const ownsContext = opts.context === undefined;\n const random = opts.random ?? Math.random;\n const busNames = opts.buses ?? ['sfx', 'music', 'ui'];\n if (busNames.length === 0) {\n throw new Error('@weasel-js/audio: an engine needs at least one bus');\n }\n const sounds = createSoundCache(ctx, opts.fetchFn);\n // One pool PER BUS, not one global pool: the spec's limit is per-bus, and a\n // shared pool lets a burst of one-shots on `sfx` steal the music bed.\n const slotsByBus = new Map<string, Slots>();\n for (const name of busNames) {\n slotsByBus.set(name, {\n pool: createVoicePool({ limit: opts.voiceLimit ?? 32, steal: opts.steal }),\n byToken: new Map(),\n });\n }\n const slotsFor = (bus: string): Slots => {\n const s = slotsByBus.get(bus);\n if (!s) throw new Error(`@weasel-js/audio: unknown bus \"${bus}\"`);\n return s;\n };\n\n const now = (): number => ctx.currentTime * 1000;\n const tickTimer = opts.setTimer === undefined && opts.clearTimer === undefined\n ? createTickTimer()\n : null;\n const timers: Timers = {\n setTimer: tickTimer?.setTimer ?? opts.setTimer ?? defaultTimers.setTimer,\n clearTimer: tickTimer?.clearTimer ?? opts.clearTimer ?? defaultTimers.clearTimer,\n };\n const scheduler = createScheduler({\n now,\n // One-shot, not repeating: the scheduler re-arms at the end of every pass,\n // so an interval would leave the previous one running and double the live\n // timer count per tick.\n setTimer: timers.setTimer,\n clearTimer: timers.clearTimer,\n lookahead: opts.lookahead,\n interval: opts.tickInterval,\n });\n scheduler.start();\n const graph = createBusGraph(ctx, busNames, { ...timers, fadeMs: opts.insertFadeMs });\n\n let listener: Vec2 = { x: 0, y: 0 };\n let spatialOpts: SpatialOptions = {};\n let nextVoiceId = 1;\n let disposed = false;\n let suspendedSince = false;\n /** Engine time before which a queued entry is stale — set on resume, so a\n * suspension does not end in one pass that fires its whole backlog. */\n let staleFloor = -Infinity;\n const live = new Map<number, LiveVoice>();\n const taps = new Set<AnalyserTap>();\n\n // An idle chain is kept off its bus: still wired to the destination, it costs\n // the audio thread every render quantum whether or not anything sounds.\n const idleChains: Chain[] = [];\n const idleChainLimit = (opts.voiceLimit ?? 32) * busNames.length;\n const takeChain = (bus: AudioNode, gain: number, pan: number): Chain => {\n let chain = idleChains.pop();\n if (!chain) {\n chain = { gain: ctx.createGain(), panner: ctx.createStereoPanner() };\n chain.panner.connect(chain.gain);\n }\n // Not a bare `.value`: a reused gain can still hold the last voice's fade.\n writeParam(ctx, chain.gain.gain, gain);\n chain.panner.pan.value = pan;\n chain.gain.connect(bus);\n return chain;\n };\n\n let warnedLocked = false;\n const warnLocked = (): void => {\n if (warnedLocked) return;\n warnedLocked = true;\n console.warn(\n '@weasel-js/audio: play() before the AudioContext was unlocked — the voice was dropped. ' +\n 'Browsers require a user gesture; call engine.unlock() from one, or wait for the ' +\n 'automatic gesture listener.',\n );\n };\n\n let warnedDisposed = false;\n const warnDisposed = (): void => {\n if (warnedDisposed) return;\n warnedDisposed = true;\n console.warn('@weasel-js/audio: play() after dispose() — the voice was dropped.');\n };\n\n let warnedUnknownSound = false;\n const warnUnknownSound = (id: string): void => {\n if (warnedUnknownSound) return;\n warnedUnknownSound = true;\n console.warn(\n `@weasel-js/audio: play() was handed sound \"${id}\", which this engine never loaded — ` +\n 'the voice was dropped. A handle belongs to the engine that produced it.',\n );\n };\n\n // Resume on the first user gesture, then stop listening.\n const gestures = ['pointerdown', 'keydown', 'touchstart'] as const;\n const onGesture = (): void => { void engine.unlock(); };\n const armGestures = (): void => {\n if (typeof window === 'undefined') return;\n for (const g of gestures) window.addEventListener(g, onGesture, { once: true, passive: true });\n };\n const disarmGestures = (): void => {\n if (typeof window === 'undefined') return;\n for (const g of gestures) window.removeEventListener(g, onGesture);\n };\n armGestures();\n\n // A browser suspends the context when the tab goes away, and the one-shot\n // gesture listeners are long consumed by then. Without this the engine is\n // permanently silent afterwards, with no diagnostic — the drop warning is a\n // once-per-engine latch.\n const onStateChange = (): void => {\n if (disposed) return;\n if (ctx.state === 'running') {\n if (suspendedSince) staleFloor = now();\n suspendedSince = false;\n return;\n }\n suspendedSince = true;\n warnedLocked = false;\n armGestures();\n };\n ctx.addEventListener('statechange', onStateChange);\n\n const poolGain = (voice: LiveVoice): void => {\n if (voice.slot === null) return;\n voice.slots.pool.setGain(voice.slot, voice.token, voice.baseGain * voice.spatialGain);\n };\n\n const applySpatial = (voice: LiveVoice): void => {\n if (!voice.position || !voice.chain) return;\n const s = spatialize(voice.position, listener, spatialOpts);\n voice.spatialGain = s.gain;\n voice.chain.panner.pan.value = s.pan;\n writeParam(ctx, voice.chain.gain.gain, voice.baseGain * s.gain);\n poolGain(voice);\n };\n\n const teardown = (voice: LiveVoice): void => {\n // First, and never at a call site: teardown is what makes a voice dead, and\n // a queued callback that outlives it must find it cancelled. The steal path\n // has no other place to set this.\n voice.cancelled = true;\n if (!voice.playing && voice.source === null) return;\n voice.playing = false;\n if (voice.source) {\n try { voice.source.stop(); } catch { /* already stopped */ }\n voice.source.disconnect();\n }\n voice.source = null;\n voice.retune = null;\n voice.release = null;\n voice.env?.disconnect();\n voice.env = null;\n if (voice.chain) {\n voice.chain.gain.disconnect();\n if (idleChains.length < idleChainLimit) idleChains.push(voice.chain);\n voice.chain = null;\n }\n live.delete(voice.id);\n if (voice.slot !== null) {\n voice.slots.byToken.delete(voice.token);\n // Safe on the steal path too: the pool has already reissued this slot\n // under a new token, and it ignores a release carrying the old one.\n voice.slots.pool.release(voice.slot, voice.token);\n }\n };\n\n const dropped = (id: number): VoiceHandle => ({\n id,\n stop: () => {}, release: () => {}, setGain: () => {}, setRate: () => {}, setDetune: () => {},\n setPan: () => {}, setPosition: () => {}, isPlaying: () => false,\n });\n\n /**\n * Everything a voice does apart from making its node: the lock and dispose\n * checks, the chain, the booking, the stale-backlog check, the slot and any\n * steal, and the handle. `starter.start` builds the node, connects it into\n * `voice.chain.panner` and starts it at the time it is handed.\n */\n const launch = (common: VoiceOptions, starter: Starter): VoiceHandle => {\n const id = nextVoiceId++;\n\n if (disposed) {\n warnDisposed();\n return dropped(id);\n }\n if (ctx.state !== 'running') {\n warnLocked();\n return dropped(id);\n }\n\n const busName = common.bus ?? busNames[0];\n const slots = slotsFor(busName);\n const bookedAt = now();\n const when = common.when ?? bookedAt;\n const baseGain = common.gain ?? 1;\n\n const spatial = common.position\n ? spatialize(common.position, listener, spatialOpts)\n : { gain: 1, pan: common.pan ?? 0 };\n\n const voice: LiveVoice = {\n id, slots, slot: null, token: 0, key: common.cancelKey,\n source: null, env: null, retune: null, release: null, releasing: false,\n chain: takeChain(graph.input(busName), baseGain * spatial.gain, spatial.pan),\n baseGain, spatialGain: spatial.gain,\n rate: common.rate ?? 1, detune: common.detune ?? 0,\n position: common.position,\n playing: true, cancelled: false,\n };\n live.set(id, voice);\n\n scheduler.schedule(when, (scheduledWhen) => {\n if (voice.cancelled) return;\n // Came due while the context was suspended: starting it now would play\n // a backlog at once, which is what dropping a locked play avoids. A voice\n // played since the resume is no backlog, however early its `when`.\n if (bookedAt < staleFloor && scheduledWhen < staleFloor) {\n teardown(voice);\n return;\n }\n if (!starter.ready()) {\n teardown(voice);\n return;\n }\n\n // The slot is taken here, not at booking time. A voice booked a bar out\n // would otherwise hold one while silent — and, its `startedAt` being in\n // the future, be the last thing the 'oldest' policy evicts, so booking\n // a bar of events would evict everything currently audible.\n const acquired = slots.pool.acquire({\n startedAt: scheduledWhen,\n gain: voice.baseGain * voice.spatialGain,\n });\n voice.slot = acquired.slot;\n voice.token = acquired.token;\n slots.byToken.set(acquired.token, voice);\n if (acquired.stolen !== null) {\n const victim = slots.byToken.get(acquired.stolen);\n if (victim) teardown(victim);\n }\n\n const source = starter.start(voice, scheduledWhen);\n source.onended = () => { teardown(voice); common.onDone?.(); };\n voice.source = source;\n }, common.cancelKey);\n\n return {\n id,\n stop(fadeMs) {\n if (fadeMs && fadeMs > 0 && voice.source && voice.chain && !voice.cancelled) {\n // Cancelled but not torn down: the fade is what ends this voice, and\n // stopping the source now would cut the ramp scheduled a line above\n // it — which is the click `fadeMs` exists to avoid. `onended` does\n // the bookkeeping when the fade reaches the end.\n voice.cancelled = true;\n writeParam(ctx, voice.chain.gain.gain, 0, fadeMs);\n try { voice.source.stop(ctx.currentTime + fadeMs / 1000); } catch { /* ended */ }\n return;\n }\n teardown(voice);\n },\n release() {\n if (voice.releasing) return;\n if (voice.release && voice.source && !voice.cancelled) {\n // Like a fade: `onended` tears the voice down once the release is out.\n voice.releasing = true;\n voice.cancelled = true;\n voice.release();\n return;\n }\n teardown(voice);\n },\n setGain(value, rampMs) {\n voice.baseGain = value;\n if (!voice.chain) return;\n writeParam(ctx, voice.chain.gain.gain, value * voice.spatialGain, rampMs);\n poolGain(voice);\n },\n setRate(value) {\n voice.rate = value;\n voice.retune?.();\n },\n setDetune(cents) {\n voice.detune = cents;\n voice.retune?.();\n },\n setPan(value) {\n voice.position = undefined;\n if (voice.chain) voice.chain.panner.pan.value = value;\n },\n setPosition(p) {\n voice.position = p;\n applySpatial(voice);\n },\n isPlaying: () => voice.playing,\n };\n };\n\n /**\n * What every synth voice shares once its sources exist: sources → optional\n * filter → envelope gain → the voice's chain, the envelopes on both, the stop\n * at the end of the release, and the note-off. `make` builds and starts the\n * sources at `t0`, connected into the node it is handed.\n */\n const synthStart = (\n voice: LiveVoice,\n whenMs: number,\n patch: { envelope?: Envelope; filter?: VoiceFilter; duration?: number },\n make: (t0: number, into: AudioNode) => { nodes: AudioScheduledSourceNode[]; retune: () => void },\n ): SourceLike => {\n const t0 = whenMs / 1000;\n const env = resolveEnvelope(patch.envelope);\n const gate = patch.duration;\n // Its own gain, not the chain's: `setGain` and a fade cancel whatever is\n // scheduled on the chain's gain, and would take the envelope with it.\n const shaper = ctx.createGain();\n const amp = envelopeOnParam(shaper.gain, env, gate, t0, (v) => v);\n const filter = patch.filter ? voiceFilter(ctx, patch.filter, gate, t0) : null;\n filter?.node.connect(shaper);\n shaper.connect(voice.chain!.panner);\n voice.env = shaper;\n\n const { nodes, retune } = make(t0, filter?.node ?? shaper);\n voice.retune = retune;\n retune();\n const stopAll = (at: number): void => { for (const n of nodes) n.stop(at); };\n voice.release = () => {\n const at = ctx.currentTime;\n // Already past its gate: the release is running and the stop is booked.\n if (gate !== undefined && at * 1000 - whenMs >= gate) return;\n amp.release(at);\n filter?.release(at);\n stopAll(at + env.release / 1000);\n };\n if (gate !== undefined) stopAll(t0 + (gate + env.release) / 1000);\n return nodes.length === 1 ? nodes[0] : sourceGroup(nodes);\n };\n\n const waves = new Map<string, PeriodicWave>();\n const applyWave = (osc: OscillatorNode, wave: Exclude<Waveform, Inharmonic>): void => {\n if (typeof wave === 'string') {\n osc.type = wave;\n return;\n }\n const key = wave.join(',');\n let periodic = waves.get(key);\n if (!periodic) {\n // Sine terms only: partial k sits at imag[k], and index 0 is the DC term.\n const imag = new Float32Array(wave.length + 1);\n imag.set(wave, 1);\n periodic = ctx.createPeriodicWave(new Float32Array(wave.length + 1), imag);\n waves.set(key, periodic);\n }\n osc.setPeriodicWave(periodic);\n };\n\n // An element can be routed into a graph once, ever: the node is kept for the\n // element's lifetime and handed from voice to voice.\n const mediaSources = new WeakMap<HTMLMediaElement, MediaElementAudioSourceNode>();\n const streaming = new WeakMap<HTMLMediaElement, VoiceHandle>();\n\n const openMedia = (url: string, crossOrigin: StreamOptions['crossOrigin']): HTMLMediaElement => {\n const el = new Audio();\n if (crossOrigin !== undefined) el.crossOrigin = crossOrigin;\n el.preload = 'auto';\n el.src = url;\n return el;\n };\n\n /** A media element's playback as a voice source: `stop(when)` pauses once\n * the audio clock reaches `when`, and the element ending ends the voice. */\n const mediaSource = (el: HTMLMediaElement, node: AudioNode, into: AudioNode): SourceLike => {\n let ended = false;\n let cancelWait: (() => void) | null = null;\n const finish = (): void => {\n if (ended) return;\n ended = true;\n cancelWait?.();\n el.pause();\n el.removeEventListener('ended', finish);\n el.removeEventListener('error', finish);\n // Queued, as a source node's `onended` is: the engine may be inside the\n // teardown that called `stop()`.\n queueMicrotask(() => (shim.onended as (() => void) | null)?.());\n };\n const shim: SourceLike = {\n onended: null,\n stop(when?: number) {\n if (ended) return;\n cancelWait?.();\n cancelWait = when !== undefined && when > ctx.currentTime\n ? atAudioTime(ctx, timers, when, finish)\n : null;\n if (!cancelWait) finish();\n },\n disconnect() {\n try { node.disconnect(into); } catch { /* not wired */ }\n },\n };\n el.addEventListener('ended', finish);\n el.addEventListener('error', finish);\n el.play().catch((err: unknown) => {\n if (ended) return;\n console.warn(`@weasel-js/audio: a stream would not start — ${String(err)}`);\n finish();\n });\n return shim;\n };\n\n const engine: AudioEngine = {\n context: ctx,\n state: () => ctx.state,\n async unlock() {\n if (disposed) return;\n if (ctx.state !== 'running') await ctx.resume();\n },\n now,\n load: sounds.load,\n loadAll: sounds.loadAll,\n decode: sounds.decode,\n register: sounds.register,\n\n play(sound, playOpts = {}) {\n return launch(playOpts, {\n ready() {\n if (sounds.buffer(sound)) return true;\n warnUnknownSound(sound.id);\n return false;\n },\n start(voice, when) {\n // A fresh source per play: AudioBufferSourceNode is single-use by\n // specification and cannot be restarted once stopped.\n const source = ctx.createBufferSource();\n source.buffer = sounds.buffer(sound)!;\n source.loop = playOpts.loop ?? false;\n voice.retune = () => {\n source.playbackRate.value = voice.rate;\n source.detune.value = voice.detune;\n };\n voice.retune();\n // Still live when this runs, so the voice still holds its chain.\n source.connect(voice.chain!.panner);\n source.start(when / 1000);\n return source;\n },\n });\n },\n\n playNote(note) {\n // Resolved at the call rather than when it comes due, so a bad pitch or\n // partial throws where it was written.\n const from = toFrequency(note.pitch);\n const glideTo = note.glide ? toFrequency(note.glide.to) : undefined;\n const wave = note.wave ?? 'sine';\n const partials = isInharmonic(wave) ? resolvePartials(wave) : null;\n return launch(note, {\n ready: () => true,\n start: (voice, whenMs) => synthStart(voice, whenMs, note, (t0, into) => {\n const tone = (ratio: number): OscillatorNode => {\n const osc = ctx.createOscillator();\n osc.frequency.setValueAtTime(from * ratio, t0);\n if (glideTo !== undefined) {\n const end = t0 + (note.glide!.ms ?? note.duration ?? 100) / 1000;\n if (note.glide!.curve === 'linear') osc.frequency.linearRampToValueAtTime(glideTo * ratio, end);\n else osc.frequency.exponentialRampToValueAtTime(glideTo * ratio, end);\n }\n return osc;\n };\n let oscs: OscillatorNode[];\n if (partials) {\n // Sines summed by hand: a PeriodicWave can only hold whole-number partials.\n oscs = partials.map((p) => {\n const osc = tone(p.ratio);\n const level = ctx.createGain();\n level.gain.setValueAtTime(p.gain, t0);\n if (p.decay !== undefined) level.gain.setTargetAtTime(0, t0, p.decay / 1000);\n osc.connect(level);\n level.connect(into);\n return osc;\n });\n } else {\n const osc = tone(1);\n applyWave(osc, wave as Exclude<Waveform, Inharmonic>);\n osc.connect(into);\n oscs = [osc];\n }\n for (const osc of oscs) osc.start(t0);\n return {\n nodes: oscs,\n retune: () => {\n for (const osc of oscs) osc.detune.value = voice.detune + 1200 * Math.log2(voice.rate);\n },\n };\n }),\n });\n },\n\n playNoise(noise) {\n return launch(noise, {\n ready: () => true,\n start: (voice, whenMs) => synthStart(voice, whenMs, noise, (t0, into) => {\n const source = ctx.createBufferSource();\n source.buffer = noiseBuffer(ctx, noise.noise);\n source.loop = true;\n source.connect(into);\n // A random point in the loop, so two hits in a row are not the same hit.\n source.start(t0, random() * source.buffer.duration);\n return {\n nodes: [source],\n retune: () => {\n source.playbackRate.value = voice.rate;\n source.detune.value = voice.detune;\n },\n };\n }),\n });\n },\n\n stream(media, streamOpts = {}) {\n const el = typeof media === 'string' ? openMedia(media, streamOpts.crossOrigin) : media;\n streaming.get(el)?.stop();\n const handle = launch(streamOpts, {\n ready: () => true,\n start(voice) {\n let node = mediaSources.get(el);\n if (!node) {\n node = ctx.createMediaElementSource(el);\n mediaSources.set(el, node);\n }\n el.loop = streamOpts.loop ?? false;\n if (streamOpts.offset !== undefined) el.currentTime = streamOpts.offset / 1000;\n voice.retune = () => { el.playbackRate = voice.rate; };\n voice.retune();\n const into = voice.chain!.panner;\n node.connect(into);\n return mediaSource(el, node, into);\n },\n });\n streaming.set(el, handle);\n return handle;\n },\n\n schedule(when, fire, key) {\n if (disposed) return;\n scheduler.schedule(when, fire, key);\n },\n\n stopKey(key) {\n scheduler.cancelKey(key);\n for (const voice of [...live.values()]) {\n if (voice.key === key) teardown(voice);\n }\n },\n stopAll() {\n for (const voice of [...live.values()]) teardown(voice);\n },\n bus: graph.bus,\n busNames: graph.names,\n activeVoices(bus) {\n if (bus !== undefined) return slotsFor(bus).pool.active();\n let total = 0;\n for (const s of slotsByBus.values()) total += s.pool.active();\n return total;\n },\n analyser(busName, tapOpts) {\n // Every tap is one more live FFT on the graph. They are tracked so\n // `dispose()` detaches them; a consumer calling this per frame still\n // wants to keep one tap rather than mint one.\n const tap = createAnalyserTap(ctx, busName ? graph.node(busName) : graph.master, tapOpts);\n taps.add(tap);\n return {\n ...tap,\n dispose() {\n taps.delete(tap);\n tap.dispose();\n },\n };\n },\n setListener(p, o) {\n listener = p;\n if (o) spatialOpts = o;\n for (const voice of live.values()) applySpatial(voice);\n },\n dispose() {\n if (disposed) return;\n disposed = true;\n engine.stopAll();\n idleChains.length = 0;\n scheduler.stop();\n scheduler.clear();\n tickTimer?.dispose();\n for (const tap of [...taps]) tap.dispose();\n taps.clear();\n disarmGestures();\n ctx.removeEventListener('statechange', onStateChange);\n graph.dispose();\n graph.master.disconnect();\n if (ownsContext) void ctx.close().catch(() => undefined);\n },\n };\n\n return engine;\n}\n","import type { InsertEffect } from './inserts';\nimport { writeParam } from './param';\n\n// Built-in insert effects. Each exposes its Web Audio nodes for anything its\n// options do not cover; times are ms, as everywhere else in the package.\n\nexport interface FilterEffectOptions {\n /** Default 'lowpass'. */\n type?: BiquadFilterType;\n /** Hz. Default 350, the node's own. */\n frequency?: number;\n Q?: number;\n /** dB, for the shelf and peaking types. */\n gain?: number;\n}\n\nexport interface FilterEffect extends InsertEffect {\n readonly filter: BiquadFilterNode;\n}\n\n/** A `BiquadFilterNode`. Write its params through `filter` to sweep it. */\nexport function createFilterEffect(ctx: BaseAudioContext, opts: FilterEffectOptions = {}): FilterEffect {\n const filter = ctx.createBiquadFilter();\n filter.type = opts.type ?? 'lowpass';\n if (opts.frequency !== undefined) writeParam(ctx, filter.frequency, opts.frequency);\n if (opts.Q !== undefined) writeParam(ctx, filter.Q, opts.Q);\n if (opts.gain !== undefined) writeParam(ctx, filter.gain, opts.gain);\n return { input: filter, output: filter, filter };\n}\n\n/** A wet/dry mix around an effect, for the effects whose output replaces\n * rather than colors the signal. */\nexport interface WetDryMix {\n /** 0 is all dry, 1 all wet. */\n mix(): number;\n setMix(mix: number, rampMs?: number): void;\n}\n\nconst checkMix = (mix: number): number => {\n if (!(mix >= 0 && mix <= 1)) throw new RangeError(`@weasel-js/audio: mix ${mix} is outside 0..1`);\n return mix;\n};\n\n/** `input → dry → output` beside `input → wetIn … wetOut → wet → output`.\n * The dry route is wired first. */\nfunction wetDry(\n ctx: BaseAudioContext,\n wetIn: AudioNode,\n wetOut: AudioNode,\n initial: number,\n): WetDryMix & { input: GainNode; output: GainNode } {\n const input = ctx.createGain();\n const output = ctx.createGain();\n const dry = ctx.createGain();\n const wet = ctx.createGain();\n input.connect(dry);\n dry.connect(output);\n input.connect(wetIn);\n wetOut.connect(wet);\n wet.connect(output);\n let mix = checkMix(initial);\n const write = (rampMs?: number): void => {\n writeParam(ctx, dry.gain, 1 - mix, rampMs);\n writeParam(ctx, wet.gain, mix, rampMs);\n };\n write();\n return {\n input, output,\n mix: () => mix,\n setMix(value, rampMs) {\n mix = checkMix(value);\n write(rampMs);\n },\n };\n}\n\nexport interface ReverbEffectOptions {\n /** The room: an impulse response, loaded or synthesized like any buffer. */\n impulse: AudioBuffer;\n /** Default 0.3. */\n mix?: number;\n /** Scale the impulse to a consistent level. Default true, the node's own. */\n normalize?: boolean;\n}\n\nexport interface ReverbEffect extends InsertEffect, WetDryMix {\n readonly convolver: ConvolverNode;\n}\n\n/** Convolution reverb from an impulse buffer, with a wet/dry mix. */\nexport function createReverbEffect(ctx: BaseAudioContext, opts: ReverbEffectOptions): ReverbEffect {\n const convolver = ctx.createConvolver();\n // Before the buffer: the node reads `normalize` when the buffer is set.\n convolver.normalize = opts.normalize ?? true;\n convolver.buffer = opts.impulse;\n const m = wetDry(ctx, convolver, convolver, opts.mix ?? 0.3);\n return { input: m.input, output: m.output, convolver, mix: m.mix, setMix: m.setMix };\n}\n\nexport interface DelayEffectOptions {\n /** ms. Default 250. */\n time?: number;\n /** How much of each repeat feeds the next, -1..1 exclusive. Default 0.35. */\n feedback?: number;\n /** Default 0.35. */\n mix?: number;\n /** The longest `time` the line can be set to later, ms. Default the larger\n * of 1000 and `time`. */\n maxTime?: number;\n}\n\nexport interface DelayEffect extends InsertEffect, WetDryMix {\n readonly delay: DelayNode;\n setTime(ms: number, rampMs?: number): void;\n feedback(): number;\n setFeedback(value: number, rampMs?: number): void;\n /** Break the feedback loop. Called for you when the slot is removed. */\n dispose(): void;\n}\n\nconst checkFeedback = (value: number): number => {\n if (!(value > -1 && value < 1)) {\n throw new RangeError(`@weasel-js/audio: feedback ${value} must be inside -1..1, or the repeats grow`);\n }\n return value;\n};\n\n/** A feedback delay with a wet/dry mix. Ramping `setTime` bends the pitch of\n * the repeats while it moves, as a tape delay does. */\nexport function createDelayEffect(ctx: BaseAudioContext, opts: DelayEffectOptions = {}): DelayEffect {\n const time = opts.time ?? 250;\n const maxTime = opts.maxTime ?? Math.max(1000, time);\n let fb = checkFeedback(opts.feedback ?? 0.35);\n const delay = ctx.createDelay(maxTime / 1000);\n const loop = ctx.createGain();\n const m = wetDry(ctx, delay, delay, opts.mix ?? 0.35);\n delay.connect(loop);\n loop.connect(delay);\n writeParam(ctx, delay.delayTime, time / 1000);\n writeParam(ctx, loop.gain, fb);\n return {\n input: m.input, output: m.output, delay, mix: m.mix, setMix: m.setMix,\n setTime(ms, rampMs) {\n if (!(ms >= 0 && ms <= maxTime)) {\n throw new RangeError(`@weasel-js/audio: delay time ${ms} is outside 0..${maxTime} ms`);\n }\n writeParam(ctx, delay.delayTime, ms / 1000, rampMs);\n },\n feedback: () => fb,\n setFeedback(value, rampMs) {\n fb = checkFeedback(value);\n writeParam(ctx, loop.gain, fb, rampMs);\n },\n dispose() {\n delay.disconnect();\n loop.disconnect();\n },\n };\n}\n\nexport interface CompressorEffectOptions {\n /** dB. */\n threshold?: number;\n /** dB. */\n knee?: number;\n ratio?: number;\n /** ms. */\n attack?: number;\n /** ms. */\n release?: number;\n /** Linear gain after the compressor, to win back the level it takes. Default 1. */\n makeup?: number;\n}\n\nexport interface CompressorEffect extends InsertEffect {\n readonly compressor: DynamicsCompressorNode;\n readonly makeup: GainNode;\n}\n\n/** A `DynamicsCompressorNode` into a makeup gain. Unset options keep the\n * node's defaults. */\nexport function createCompressorEffect(\n ctx: BaseAudioContext,\n opts: CompressorEffectOptions = {},\n): CompressorEffect {\n const compressor = ctx.createDynamicsCompressor();\n const makeup = ctx.createGain();\n compressor.connect(makeup);\n const set = (param: AudioParam, value: number | undefined): void => {\n if (value !== undefined) writeParam(ctx, param, value);\n };\n set(compressor.threshold, opts.threshold);\n set(compressor.knee, opts.knee);\n set(compressor.ratio, opts.ratio);\n set(compressor.attack, opts.attack === undefined ? undefined : opts.attack / 1000);\n set(compressor.release, opts.release === undefined ? undefined : opts.release / 1000);\n set(makeup.gain, opts.makeup ?? 1);\n return { input: compressor, output: makeup, compressor, makeup };\n}\n","import type { AudioEngine } from './createAudioEngine';\nimport type { SoundHandle } from './soundCache';\nimport type { NoiseOptions, NoteOptions, PlayOptions, VoiceHandle } from './types';\n\n/** A synth note on a step. `length` is its gate in steps, default 1. */\nexport interface PatternNote extends Omit<NoteOptions, 'when' | 'duration'> {\n step: number;\n length?: number;\n}\n\n/** Noise on a step: a hi-hat, a snare's rattle. `length` is its gate in steps,\n * default 1. */\nexport interface PatternNoise extends Omit<NoiseOptions, 'when' | 'duration'> {\n step: number;\n length?: number;\n}\n\n/** A buffer played on a step: a drum hit, a sample. */\nexport interface PatternHit extends Omit<PlayOptions, 'when'> {\n step: number;\n sound: SoundHandle;\n}\n\nexport type PatternEvent = PatternNote | PatternNoise | PatternHit;\n\n/** Options for `createPatternPlayer`. */\nexport interface PatternPlayerOptions {\n /** Beats per minute. */\n tempo: number;\n /** Steps per beat. Default 4, so a step is a sixteenth note in 4/4. */\n stepsPerBeat?: number;\n events?: readonly PatternEvent[];\n /** Steps in one pass. Default: through the last event, rounded up to a whole\n * beat. */\n length?: number;\n /** Default true. */\n loop?: boolean;\n /** Called as each step is booked — up to a lookahead ahead of it sounding —\n * with its index in the pattern and its engine time in ms. */\n onStep?: (step: number, when: number) => void;\n}\n\n/** A running sequence of steps. See `createPatternPlayer`. */\nexport interface PatternPlayer {\n /** Start from step 0 at engine time `when`, default now. No-op while playing. */\n start(when?: number): void;\n /** Book nothing further, and release every voice the player started. */\n stop(): void;\n playing(): boolean;\n tempo(): number;\n /** Takes effect from the next step not yet booked. */\n setTempo(bpm: number): void;\n /** Takes effect from the next step not yet booked. */\n setEvents(events: readonly PatternEvent[], length?: number): void;\n}\n\nlet nextPlayer = 1;\n\nconst checkTempo = (bpm: number): void => {\n if (!(bpm > 0) || !Number.isFinite(bpm)) {\n throw new RangeError(`@weasel-js/audio: tempo must be a positive number of bpm, got ${bpm}`);\n }\n};\n\n/**\n * A step sequencer over `engine`. Each step is one `engine.schedule` booking;\n * when it fires, it books that step's events at the step's exact time and then\n * books the step after it. So nothing is booked further ahead than the\n * scheduler's lookahead, which is what lets a tempo change or new events land\n * on the very next step.\n *\n * A step that fires more than a step late — a stalled timer, a suspended\n * context — skips to the next step still ahead of the clock, keeping phase,\n * rather than playing the missed ones at once.\n */\nexport function createPatternPlayer(engine: AudioEngine, opts: PatternPlayerOptions): PatternPlayer {\n checkTempo(opts.tempo);\n const stepsPerBeat = opts.stepsPerBeat ?? 4;\n const loop = opts.loop ?? true;\n const key = `\\u0000pattern:${nextPlayer++}`;\n\n let bpm = opts.tempo;\n let length = 1;\n let byStep = new Map<number, PatternEvent[]>();\n const setEvents = (events: readonly PatternEvent[], len?: number): void => {\n byStep = new Map();\n let last = -1;\n for (const e of events) {\n const list = byStep.get(e.step);\n if (list) list.push(e);\n else byStep.set(e.step, [e]);\n last = Math.max(last, e.step);\n }\n length = len ?? Math.max(1, Math.ceil((last + 1) / stepsPerBeat)) * stepsPerBeat;\n };\n setEvents(opts.events ?? [], opts.length);\n\n let running = false;\n /** Steps booked since `start`, not wrapped. */\n let count = 0;\n let lastAt: number | null = null;\n let nextAt = 0;\n const voices = new Set<VoiceHandle>();\n\n const stepMs = (): number => 60_000 / bpm / stepsPerBeat;\n\n const book = (): void => { engine.schedule(nextAt, fire, key); };\n\n const fire = (scheduled: number): void => {\n if (!running) return;\n let when = scheduled;\n const behind = engine.now() - when;\n if (behind > stepMs()) {\n const skip = Math.ceil(behind / stepMs());\n count += skip;\n when += skip * stepMs();\n }\n if (!loop && count >= length) {\n running = false;\n return;\n }\n const step = count % length;\n for (const v of voices) if (!v.isPlaying()) voices.delete(v);\n for (const e of byStep.get(step) ?? []) {\n if ('sound' in e) {\n const { step: _s, sound, ...play } = e;\n voices.add(engine.play(sound, { ...play, when }));\n } else if ('noise' in e) {\n const { step: _s, length: steps = 1, ...noise } = e;\n voices.add(engine.playNoise({ ...noise, when, duration: steps * stepMs() }));\n } else {\n const { step: _s, length: steps = 1, ...note } = e;\n voices.add(engine.playNote({ ...note, when, duration: steps * stepMs() }));\n }\n }\n opts.onStep?.(step, when);\n count += 1;\n lastAt = when;\n nextAt = when + stepMs();\n book();\n };\n\n return {\n start(when) {\n if (running) return;\n running = true;\n count = 0;\n lastAt = null;\n nextAt = when ?? engine.now();\n book();\n },\n stop() {\n if (!running) return;\n running = false;\n engine.stopKey(key);\n for (const v of voices) v.release();\n voices.clear();\n },\n playing: () => running,\n tempo: () => bpm,\n setTempo(next) {\n checkTempo(next);\n bpm = next;\n if (!running || lastAt === null) return;\n engine.stopKey(key);\n nextAt = Math.max(lastAt + stepMs(), engine.now());\n book();\n },\n setEvents,\n };\n}\n"]}
1
+ {"version":3,"sources":["../src/analyser.ts","../src/audioTime.ts","../src/param.ts","../src/inserts.ts","../src/buses.ts","../src/scheduler.ts","../src/soundCache.ts","../src/spatialize.ts","../src/tickTimer.ts","../src/envelope.ts","../src/pitch.ts","../src/synthVoice.ts","../src/voiceDrops.ts","../src/voicePool.ts","../src/createAudioEngine.ts","../src/effects.ts","../src/patternPlayer.ts"],"names":["i","prev","next","slot"],"mappings":"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","file":"index.js","sourcesContent":["/** Options for `createAnalyserTap` and `AudioEngine.analyser`. */\nexport interface AnalyserTapOptions {\n /** Power of two, 32..32768. Default 2048. */\n fftSize?: number;\n}\n\n/** An `AnalyserNode` attached to a point in the graph, with readers for its\n * spectrum, waveform and level. Each call reads the current window. */\nexport interface AnalyserTap {\n /** The underlying node, exposed for disposal assertions and advanced wiring. */\n node: AnalyserNode;\n /** Frequency data, sized `node.frequencyBinCount` when no array is given. */\n frequencies(out?: Uint8Array<ArrayBuffer>): Uint8Array<ArrayBuffer>;\n /** Time-domain data, sized `node.fftSize` when no array is given — twice the\n * frequency bin count, which is the whole window rather than half of it. */\n waveform(out?: Uint8Array<ArrayBuffer>): Uint8Array<ArrayBuffer>;\n /** RMS amplitude over the whole time-domain window, 0..1. */\n level(): number;\n /** `n` averaged frequency bands normalized to 0..1 — the ergonomic form for\n * driving a shader uniform, a vertex color, or a pose. `out`, when given,\n * must be exactly `n` long. */\n bands(n: number, out?: Float32Array<ArrayBuffer>): Float32Array<ArrayBuffer>;\n /** Detach from the tapped node. Idempotent. */\n dispose(): void;\n}\n\n/** Attach a new `AnalyserNode` to `source`. The tap only listens, adding no\n * path to the destination; `dispose()` detaches it. */\nexport function createAnalyserTap(\n ctx: AudioContext,\n source: AudioNode,\n opts: AnalyserTapOptions = {},\n): AnalyserTap {\n const node = ctx.createAnalyser();\n node.fftSize = opts.fftSize ?? 2048;\n source.connect(node);\n let attached = true;\n\n // `node` is public surface, so `fftSize` can change under the tap. Time-domain\n // data is sized by `fftSize`; frequency data by half of it.\n let freqScratch = new Uint8Array(0);\n let timeScratch = new Uint8Array(0);\n const freqBuf = (): Uint8Array<ArrayBuffer> => {\n if (freqScratch.length !== node.frequencyBinCount) {\n freqScratch = new Uint8Array(node.frequencyBinCount);\n }\n return freqScratch;\n };\n const timeBuf = (): Uint8Array<ArrayBuffer> => {\n if (timeScratch.length !== node.fftSize) timeScratch = new Uint8Array(node.fftSize);\n return timeScratch;\n };\n\n return {\n node,\n frequencies(out) {\n const target = out ?? new Uint8Array(node.frequencyBinCount);\n node.getByteFrequencyData(target);\n return target;\n },\n waveform(out) {\n const target = out ?? new Uint8Array(node.fftSize);\n node.getByteTimeDomainData(target);\n return target;\n },\n level() {\n const buf = timeBuf();\n node.getByteTimeDomainData(buf);\n let sum = 0;\n for (let i = 0; i < buf.length; i += 1) {\n // Time-domain bytes center on 128; subtract to get a signed sample.\n const v = (buf[i] - 128) / 128;\n sum += v * v;\n }\n return Math.sqrt(sum / buf.length);\n },\n bands(n, out) {\n if (!Number.isInteger(n) || n < 1) {\n throw new Error('@weasel-js/audio: bands(n) requires a positive integer');\n }\n // Unlike the byte readers, a short `out` here would return fewer bands\n // than asked for with nothing to distinguish it from a correct result.\n if (out && out.length !== n) {\n throw new Error(\n `@weasel-js/audio: bands(${n}, out) requires an out array of length ${n}, got ${out.length}`,\n );\n }\n const buf = freqBuf();\n node.getByteFrequencyData(buf);\n const target = out ?? new Float32Array(n);\n const per = buf.length / n;\n for (let b = 0; b < n; b += 1) {\n const lo = Math.floor(b * per);\n const hi = Math.max(lo + 1, Math.floor((b + 1) * per));\n let sum = 0;\n for (let i = lo; i < hi; i += 1) sum += buf[i];\n target[b] = sum / (hi - lo) / 255;\n }\n return target;\n },\n // `node.disconnect()` would cut the analyser's outgoing edges, and it has\n // none: the edge that keeps it alive is the source's.\n dispose() {\n if (!attached) return;\n attached = false;\n source.disconnect(node);\n },\n };\n}\n","/** A one-shot timer pair, as `AudioEngineOptions.setTimer` takes it. */\nexport interface Timers {\n setTimer(cb: () => void, ms: number): unknown;\n clearTimer(handle: unknown): void;\n}\n\nexport const defaultTimers: Timers = {\n setTimer: (cb, ms) => setTimeout(cb, ms),\n clearTimer: (h) => clearTimeout(h as ReturnType<typeof setTimeout>),\n};\n\n/**\n * Run `cb` once the audio clock reaches `at` (seconds), or at once when the\n * context is not running — a stopped clock never arrives, and nothing is heard\n * meanwhile. The timer alone is not enough: it runs on wall time, and a ramp\n * cut short by an early timer is the click it was scheduled to avoid.\n * Returns a cancel function.\n */\nexport function atAudioTime(\n ctx: BaseAudioContext,\n timers: Timers,\n at: number,\n cb: () => void,\n): () => void {\n let handle: unknown = null;\n let live = true;\n const check = (): void => {\n handle = null;\n if (!live) return;\n const left = at - ctx.currentTime;\n if (ctx.state === 'running' && left > 1e-6) {\n handle = timers.setTimer(check, Math.max(1, left * 1000));\n return;\n }\n live = false;\n cb();\n };\n check();\n return () => {\n live = false;\n if (handle !== null) timers.clearTimer(handle);\n handle = null;\n };\n}\n","/**\n * Every gain write in the package goes through here.\n *\n * Two traps, both silent: a bare `param.value = x` sits *behind* any scheduled\n * ramp, which keeps running and wins; and a ramp with no anchor interpolates\n * from the previous scheduled endpoint rather than from the value the param\n * holds now, so a second ramp jumps before it moves.\n */\nexport function writeParam(\n ctx: BaseAudioContext,\n param: AudioParam,\n value: number,\n rampMs?: number,\n): void {\n const now = ctx.currentTime;\n param.cancelScheduledValues(now);\n if (rampMs && rampMs > 0) {\n param.setValueAtTime(param.value, now);\n param.linearRampToValueAtTime(value, now + rampMs / 1000);\n } else {\n param.setValueAtTime(value, now);\n }\n}\n","import { atAudioTime, defaultTimers, type Timers } from './audioTime';\nimport { writeParam } from './param';\n\n/**\n * Anything with an input and an output node can sit in an insert slot: one of\n * the built-ins (`createFilterEffect` and the rest), or a pair of nodes of your\n * own — `{ input: shaper, output: shaper }` for a single node. Several nodes\n * between the two are fine too. An effect goes in one slot, once.\n */\nexport interface InsertEffect {\n readonly input: AudioNode;\n readonly output: AudioNode;\n /** Called once the effect has left the graph after `remove()` or `clear()`. */\n dispose?(): void;\n}\n\n/** One effect's place in a bus's insert chain. Every edit is click-free: a\n * bypass crossfades the slot's wet and dry, and a structural edit crossfades\n * the old route into the new one. */\nexport interface InsertSlot {\n readonly effect: InsertEffect;\n /** Route around the effect (`true`) or back through it. */\n bypass(on: boolean): void;\n bypassed(): boolean;\n /** Clamped to the chain. */\n moveTo(index: number): void;\n /** Take the effect out, then call its `dispose`. Idempotent. */\n remove(): void;\n /** Position in the chain, or -1 once removed. */\n index(): number;\n}\n\n/** Where `InsertChain.add` puts an effect, and whether it starts bypassed. */\nexport interface InsertAddOptions {\n /** Default: the end of the chain. Clamped. */\n index?: number;\n /** Add it routed around, for a later `bypass(false)`. Default false. */\n bypassed?: boolean;\n}\n\n/**\n * A bus's ordered insert effects, between where voices connect and the bus's\n * fader. `slots()` is the chain as edited; the audio graph follows one\n * crossfade at a time, and `settled()` resolves once it has caught up.\n */\nexport interface InsertChain {\n add(effect: InsertEffect, opts?: InsertAddOptions): InsertSlot;\n slots(): InsertSlot[];\n clear(): void;\n settled(): Promise<void>;\n}\n\n/** Options for an insert chain: its crossfade length, and the timers it schedules with. */\nexport interface InsertChainOptions extends Partial<Timers> {\n /** Crossfade length for every edit, in ms. Default 15. */\n fadeMs?: number;\n}\n\n/** A chain and the switch that cancels its transition in flight. */\nexport interface OwnedInsertChain {\n chain: InsertChain;\n dispose(): void;\n}\n\ninterface Slot {\n handle: InsertSlot;\n effect: InsertEffect;\n bypassed: boolean;\n removed: boolean;\n /** Built on first splice-in, kept across a move, torn down on removal. */\n nodes: { in: GainNode; out: GainNode; dry: GainNode; wet: GainNode } | null;\n}\n\n/** A gain between two consecutive points of the chain — the thing that fades\n * when a route changes. */\ninterface Link { from: AudioNode; to: AudioNode; gain: GainNode }\n\ntype Step =\n | { kind: 'out'; slot: Slot }\n | { kind: 'in'; slot: Slot; at: number };\n\n/**\n * Build an insert chain from `head` to `tail`, which start wired straight\n * through.\n *\n * A structural edit never swaps a connection instantly. A splice-in builds the\n * route through the new slot beside the old one and crossfades the two into\n * `next`; a splice-out does the reverse, so the effect's tail fades rather than\n * cuts. A move is a splice-out followed by a splice-in, never one rewire:\n * crossfading two orders at once would wire `b → c` and `c → b` together, and\n * Web Audio mutes a cycle with no delay in it.\n */\nexport function createInsertChain(\n ctx: BaseAudioContext,\n head: AudioNode,\n tail: AudioNode,\n opts: InsertChainOptions = {},\n): OwnedInsertChain {\n const fadeMs = opts.fadeMs ?? 15;\n const timers: Timers = {\n setTimer: opts.setTimer ?? defaultTimers.setTimer,\n clearTimer: opts.clearTimer ?? defaultTimers.clearTimer,\n };\n const used = new WeakSet<InsertEffect>();\n const order: Slot[] = [];\n /** The slots the audio graph routes through, in graph order. */\n const live: Slot[] = [];\n const links: Link[] = [];\n let busy = false;\n /** The slot a crossfade in flight is taking out of the graph, whose finish disposes it if removed. */\n let leaving: Slot | null = null;\n let cancel: (() => void) | null = null;\n let disposed = false;\n let waiters: (() => void)[] = [];\n\n const fade = (): number => (ctx.state === 'running' ? fadeMs : 0);\n\n const link = (from: AudioNode, to: AudioNode, gain: number): Link => {\n const g = ctx.createGain();\n // `.value` first, so `writeParam` anchors a ramp at it rather than at 1.\n g.gain.value = gain;\n writeParam(ctx, g.gain, gain);\n from.connect(g);\n g.connect(to);\n const l = { from, to, gain: g };\n links.push(l);\n return l;\n };\n\n const unlink = (l: Link): void => {\n l.from.disconnect(l.gain);\n l.gain.disconnect();\n links.splice(links.indexOf(l), 1);\n };\n\n const find = (from: AudioNode, to: AudioNode): Link =>\n links.find((l) => l.from === from && l.to === to)!;\n\n const inOf = (s: Slot | null): AudioNode => (s ? s.nodes!.in : tail);\n const outOf = (s: Slot | null): AudioNode => (s ? s.nodes!.out : head);\n\n const setBypass = (s: Slot, ms: number): void => {\n if (!s.nodes) return;\n writeParam(ctx, s.nodes.wet.gain, s.bypassed ? 0 : 1, ms);\n writeParam(ctx, s.nodes.dry.gain, s.bypassed ? 1 : 0, ms);\n };\n\n const build = (s: Slot): void => {\n if (s.nodes) return;\n const n = {\n in: ctx.createGain(), out: ctx.createGain(), dry: ctx.createGain(), wet: ctx.createGain(),\n };\n n.in.connect(s.effect.input);\n s.effect.output.connect(n.wet);\n n.wet.connect(n.out);\n n.in.connect(n.dry);\n n.dry.connect(n.out);\n s.nodes = n;\n n.wet.gain.value = s.bypassed ? 0 : 1;\n n.dry.gain.value = s.bypassed ? 1 : 0;\n setBypass(s, 0);\n };\n\n const destroy = (s: Slot): void => {\n const n = s.nodes;\n if (!n) return;\n // Targeted, not bare: the effect's nodes are the consumer's, and may be\n // wired to things besides this slot.\n n.in.disconnect();\n try { s.effect.output.disconnect(n.wet); } catch { /* already cut */ }\n n.wet.disconnect();\n n.dry.disconnect();\n n.out.disconnect();\n s.nodes = null;\n };\n\n const plan = (): Step | null => {\n const stale = live.find((s) => s.removed);\n if (stale) return { kind: 'out', slot: stale };\n const wanted = order.filter((s) => live.includes(s));\n for (let i = 0; i < wanted.length; i += 1) {\n // Out now, back in at its place on a later step.\n if (live[i] !== wanted[i]) return { kind: 'out', slot: wanted[i] };\n }\n const i = order.findIndex((s) => !live.includes(s));\n if (i < 0) return null;\n let at = 0;\n for (let j = i - 1; j >= 0; j -= 1) {\n const k = live.indexOf(order[j]);\n if (k >= 0) { at = k + 1; break; }\n }\n return { kind: 'in', slot: order[i], at };\n };\n\n /** Start `step`'s crossfade and return what finishes it. */\n const begin = (step: Step, ms: number): (() => void) => {\n const s = step.slot;\n if (step.kind === 'in') {\n build(s);\n const prev = live[step.at - 1] ?? null;\n const next = live[step.at] ?? null;\n const old = find(outOf(prev), inOf(next));\n link(outOf(prev), inOf(s), 1);\n const incoming = link(outOf(s), inOf(next), 0);\n live.splice(step.at, 0, s);\n writeParam(ctx, old.gain.gain, 0, ms);\n writeParam(ctx, incoming.gain.gain, 1, ms);\n return () => unlink(old);\n }\n const i = live.indexOf(s);\n const prev = live[i - 1] ?? null;\n const next = live[i + 1] ?? null;\n const into = find(outOf(prev), inOf(s));\n const from = find(outOf(s), inOf(next));\n const direct = link(outOf(prev), inOf(next), 0);\n live.splice(i, 1);\n leaving = s;\n writeParam(ctx, from.gain.gain, 0, ms);\n writeParam(ctx, direct.gain.gain, 1, ms);\n return () => {\n leaving = null;\n unlink(into);\n unlink(from);\n if (s.removed) {\n destroy(s);\n s.effect.dispose?.();\n }\n };\n };\n\n const pump = (): void => {\n while (!busy && !disposed) {\n const step = plan();\n if (!step) {\n const done = waiters;\n waiters = [];\n for (const w of done) w();\n return;\n }\n const ms = fade();\n const finish = begin(step, ms);\n if (ms === 0) {\n finish();\n continue;\n }\n busy = true;\n cancel = atAudioTime(ctx, timers, ctx.currentTime + ms / 1000, () => {\n cancel = null;\n busy = false;\n finish();\n pump();\n });\n }\n };\n\n link(head, tail, 1);\n\n const slotOf = (effect: InsertEffect, bypassed: boolean): Slot => {\n const s: Slot = { effect, bypassed, removed: false, nodes: null, handle: null as never };\n s.handle = {\n effect,\n bypass(on) {\n if (s.bypassed === on) return;\n s.bypassed = on;\n setBypass(s, fade());\n },\n bypassed: () => s.bypassed,\n moveTo(index) {\n const from = order.indexOf(s);\n if (from < 0) return;\n order.splice(from, 1);\n order.splice(Math.max(0, Math.min(index, order.length)), 0, s);\n pump();\n },\n remove() {\n const at = order.indexOf(s);\n if (at < 0) return;\n order.splice(at, 1);\n s.removed = true;\n // `plan` only finds a removed slot in the graph; one that is out of it has no later step to dispose it.\n if (!live.includes(s) && leaving !== s) {\n destroy(s);\n s.effect.dispose?.();\n }\n pump();\n },\n index: () => order.indexOf(s),\n };\n return s;\n };\n\n const chain: InsertChain = {\n add(effect, addOpts = {}) {\n if (used.has(effect)) {\n throw new Error('@weasel-js/audio: that effect is already in an insert slot');\n }\n used.add(effect);\n const s = slotOf(effect, addOpts.bypassed ?? false);\n const index = addOpts.index ?? order.length;\n order.splice(Math.max(0, Math.min(index, order.length)), 0, s);\n pump();\n return s.handle;\n },\n slots: () => order.map((s) => s.handle),\n clear() {\n for (const s of [...order]) s.handle.remove();\n },\n settled() {\n if (!busy && plan() === null) return Promise.resolve();\n return new Promise((resolve) => { waiters.push(resolve); });\n },\n };\n return {\n chain,\n dispose() {\n disposed = true;\n cancel?.();\n cancel = null;\n const done = waiters;\n waiters = [];\n for (const w of done) w();\n },\n };\n}\n","import {\n createInsertChain, type InsertChain, type InsertChainOptions, type OwnedInsertChain,\n} from './inserts';\nimport { writeParam } from './param';\n\n/** Controls for one named bus. `rampMs` slews a gain change over that many\n * ms instead of stepping it. */\nexport interface BusHandle {\n setGain(value: number, rampMs?: number): void;\n mute(on: boolean): void;\n solo(on: boolean): void;\n /** The bus's own gain, as last set — not what a mute or solo is imposing. */\n gain(): number;\n /** The mute flag as set, independent of any solo. */\n muted(): boolean;\n /** The solo flag as set; whether it silences anything is a graph-wide answer. */\n soloed(): boolean;\n /** Whether the bus is being heard: unmuted, and soloed if any bus is soloed.\n * Not derivable from `muted()` and `soloed()` alone. */\n audible(): boolean;\n /** Effects between where the bus's voices connect and its fader. */\n readonly inserts: InsertChain;\n}\n\n/** The mix graph built by `createBusGraph`. `input(name)` is where a voice\n * connects; it runs through the bus's inserts to `node(name)`, the fader,\n * which feeds `master`, which feeds the destination. Unknown bus names throw. */\nexport interface BusGraph {\n master: GainNode;\n input(name: string): GainNode;\n node(name: string): GainNode;\n bus(name: string): BusHandle;\n names(): string[];\n /** Cancel every insert transition in flight. The nodes stay wired. */\n dispose(): void;\n}\n\n/** Options for `createBusGraph`: the insert chains' crossfade and timer. */\nexport type BusGraphOptions = InsertChainOptions;\n\ninterface BusState {\n input: GainNode;\n node: GainNode;\n inserts: OwnedInsertChain;\n gain: number;\n muted: boolean;\n soloed: boolean;\n}\n\n/**\n * The mix graph: one `GainNode` per named bus, all routed to a master that\n * routes to the destination.\n *\n * Gain, mute and solo are three inputs to one output value rather than three\n * things that write the node directly — otherwise unmuting restores the wrong\n * value whenever a solo changed it in between. All three write through\n * `writeParam`, so `rampMs` survives instead of being overwritten by the\n * recomputation that follows it.\n */\nexport function createBusGraph(\n ctx: AudioContext,\n names: string[],\n opts: BusGraphOptions = {},\n): BusGraph {\n const master = ctx.createGain();\n master.connect(ctx.destination);\n\n const states = new Map<string, BusState>();\n for (const name of names) {\n const input = ctx.createGain();\n const node = ctx.createGain();\n node.connect(master);\n const inserts = createInsertChain(ctx, input, node, opts);\n states.set(name, { input, node, inserts, gain: 1, muted: false, soloed: false });\n }\n\n const anySoloed = (): boolean => {\n for (const s of states.values()) if (s.soloed) return true;\n return false;\n };\n\n const audibleUnder = (s: BusState, soloing: boolean): boolean =>\n !s.muted && (!soloing || s.soloed);\n\n // `ramp` names the one bus whose own value changed, so a solo does not slew\n // every other bus at whatever rate that bus was last set with.\n const apply = (ramp?: { bus: BusState; ms: number }): void => {\n const soloing = anySoloed();\n for (const s of states.values()) {\n const value = audibleUnder(s, soloing) ? s.gain : 0;\n writeParam(ctx, s.node.gain, value, ramp?.bus === s ? ramp.ms : undefined);\n }\n };\n\n const get = (name: string): BusState => {\n const s = states.get(name);\n if (!s) throw new Error(`@weasel-js/audio: unknown bus \"${name}\"`);\n return s;\n };\n\n return {\n master,\n input: (name) => get(name).input,\n node: (name) => get(name).node,\n names: () => [...states.keys()],\n dispose() {\n for (const s of states.values()) s.inserts.dispose();\n },\n bus(name) {\n const s = get(name);\n return {\n setGain(value, rampMs) {\n s.gain = value;\n apply(rampMs && rampMs > 0 ? { bus: s, ms: rampMs } : undefined);\n },\n mute(on) { s.muted = on; apply(); },\n solo(on) { s.soloed = on; apply(); },\n gain: () => s.gain,\n muted: () => s.muted,\n soloed: () => s.soloed,\n audible: () => audibleUnder(s, anySoloed()),\n inserts: s.inserts.chain,\n };\n },\n };\n}\n","/** Clock and timer for `createScheduler`. */\nexport interface SchedulerOptions {\n /** Engine time in ms. Backed by `AudioContext.currentTime * 1000` in production. */\n now: () => number;\n /** One-shot: it fires once and the pass re-arms it. `setInterval` here would\n * leave every previous timer running. */\n setTimer: (cb: () => void, ms: number) => unknown;\n clearTimer: (handle: unknown) => void;\n /** How far ahead to book events, in ms. Default 100. */\n lookahead?: number;\n /** Time between passes, in ms. Default 25. */\n interval?: number;\n}\n\ninterface Entry {\n when: number;\n fire: (when: number) => void;\n key?: string;\n}\n\n/** A queue of callbacks keyed to engine time. See `createScheduler`. */\nexport interface Scheduler {\n start(): void;\n /** Stop the timer. The queue survives; `clear()` empties it. */\n stop(): void;\n /** Book `fire` for engine time `when`, receiving `when` so it can hand the\n * true time to `source.start()` rather than \"now\". It runs on the first\n * pass whose lookahead window reaches it — or, when the window already\n * covers it and the scheduler is running, at the end of the current task,\n * in time order with everything else then due. */\n schedule(when: number, fire: (when: number) => void, key?: string): void;\n /** Drop queued events with this key. A pass takes its whole batch out of the\n * queue before firing any of it, so a callback cannot cancel a sibling that\n * came due alongside it. */\n cancelKey(key: string): void;\n /** Drop every queued event. Without this, a stop/start cycle fires\n * everything that came due meanwhile in one burst on the first pass. */\n clear(): void;\n pending(): number;\n}\n\n/**\n * Lookahead scheduler. Each pass fires everything due within `lookahead` ms,\n * in time order, handing each callback its own scheduled time. An event\n * scheduled inside that window does not wait up to `interval` for the next\n * pass: the end of the current task fires what is due then.\n *\n * It runs on its own timer rather than on an animation frame, which stops\n * entirely when nothing is animating. The timer is one-shot: the pass re-arms\n * it at the end, so passes cannot overlap. A main-thread `setTimeout` is clamped\n * to a second in a hidden tab, which the lookahead cannot cover; the engine\n * passes `createTickTimer` instead.\n */\nexport function createScheduler(opts: SchedulerOptions): Scheduler {\n const lookahead = opts.lookahead ?? 100;\n const interval = opts.interval ?? 25;\n let queue: Entry[] = [];\n let running = false;\n let handle: unknown = null;\n\n let flushQueued = false;\n\n const fireDue = (): void => {\n const horizon = opts.now() + lookahead;\n const due: Entry[] = [];\n const rest: Entry[] = [];\n for (const entry of queue) (entry.when <= horizon ? due : rest).push(entry);\n queue = rest;\n due.sort((a, b) => a.when - b.when);\n for (const entry of due) {\n try {\n entry.fire(entry.when);\n } catch (err) {\n console.error('@weasel-js/audio scheduler: callback threw', err);\n }\n }\n };\n\n const pass = (): void => {\n fireDue();\n if (running) handle = opts.setTimer(pass, interval);\n };\n\n // A microtask rather than firing inside `schedule()`: everything booked in\n // one task is fired as one batch, sorted by time, exactly as a pass would.\n const flush = (): void => {\n flushQueued = false;\n if (running) fireDue();\n };\n\n return {\n start() {\n if (running) return;\n running = true;\n handle = opts.setTimer(pass, interval);\n },\n stop() {\n if (!running) return;\n running = false;\n opts.clearTimer(handle);\n handle = null;\n },\n schedule(when, fire, key) {\n queue.push({ when, fire, key });\n if (running && !flushQueued && when <= opts.now() + lookahead) {\n flushQueued = true;\n queueMicrotask(flush);\n }\n },\n cancelKey(key) {\n queue = queue.filter((e) => e.key !== key);\n },\n clear() {\n queue = [];\n },\n pending: () => queue.length,\n };\n}\n","/** Opaque reference to a decoded sound. Mirrors `TextureHandle` in core. */\nexport interface SoundHandle { readonly id: string }\n\n/** Decoded buffers behind opaque `SoundHandle`s. Nothing is ever evicted. */\nexport interface SoundCache {\n load(url: string): Promise<SoundHandle>;\n loadAll(urls: Record<string, string>): Promise<Record<string, SoundHandle>>;\n decode(bytes: ArrayBuffer): Promise<SoundHandle>;\n /** Take ownership of a buffer the caller already has — a procedural synth,\n * an OfflineAudioContext render, a recording. Synchronous; nothing to decode. */\n register(buffer: AudioBuffer): SoundHandle;\n buffer(handle: SoundHandle): AudioBuffer | null;\n}\n\n/** Create a cache that decodes through `ctx`. `load` fetches with `fetchFn`,\n * returns the existing handle for a url already loaded, and shares one fetch\n * between concurrent loads of it; a failed load is not cached. */\nexport function createSoundCache(\n ctx: AudioContext,\n fetchFn: typeof fetch = fetch,\n): SoundCache {\n let counter = 0;\n const buffers = new Map<string, AudioBuffer>();\n const byUrl = new Map<string, SoundHandle>();\n // In-flight loads, so two concurrent `load` calls for one url share a fetch.\n const inflight = new Map<string, Promise<SoundHandle>>();\n\n const store = (buffer: AudioBuffer): SoundHandle => {\n const id = `snd_${++counter}`;\n buffers.set(id, buffer);\n return { id };\n };\n\n const cache: SoundCache = {\n async load(url) {\n const existing = byUrl.get(url);\n if (existing) return existing;\n const pending = inflight.get(url);\n if (pending) return pending;\n\n const task = (async () => {\n const res = await fetchFn(url);\n if (!res.ok) throw new Error(`@weasel-js/audio: failed to load ${url} (${res.status})`);\n const bytes = await res.arrayBuffer();\n const buffer = await ctx.decodeAudioData(bytes);\n const handle = store(buffer);\n byUrl.set(url, handle);\n return handle;\n })();\n\n inflight.set(url, task);\n try {\n return await task;\n } finally {\n // Always clear: a failed load must not be cached, or a retry can never\n // succeed for the lifetime of the page.\n inflight.delete(url);\n }\n },\n async loadAll(urls) {\n const names = Object.keys(urls);\n const handles = await Promise.all(names.map((n) => cache.load(urls[n])));\n return Object.fromEntries(names.map((n, i) => [n, handles[i]]));\n },\n async decode(bytes) {\n return store(await ctx.decodeAudioData(bytes));\n },\n register: (buffer) => store(buffer),\n buffer: (handle) => buffers.get(handle.id) ?? null,\n };\n return cache;\n}\n","/** A 2D world position, in the consumer's own units. */\nexport interface Vec2 { x: number; y: number }\n\n/** Distance and pan model for `spatialize`, in the same units as the\n * positions. */\nexport interface SpatialOptions {\n /** Distance within which gain stays at 1. Default 1. The inverse model needs\n * this above 0: at 0 it cliffs gain from 1 to 0 at any nonzero distance. */\n refDistance?: number;\n /** Distance at which linear rolloff reaches 0. Ignored by inverse. Default\n * 10000. At or below `refDistance` it gives the same 1-to-0 cliff, there. */\n maxDistance?: number;\n /** Default 'inverse' — the natural-sounding one. */\n rolloff?: 'inverse' | 'linear';\n /** How sharply gain falls. Default 1. */\n rolloffFactor?: number;\n /** Horizontal distance mapping to full left/right. Default 500. */\n panWidth?: number;\n}\n\n/**\n * Map a source position to a gain and a stereo pan, relative to the listener.\n *\n * Pure — no Web Audio, no state. This is the whole spatial model.\n */\nexport function spatialize(\n source: Vec2,\n listener: Vec2,\n opts: SpatialOptions = {},\n): { gain: number; pan: number } {\n const refDistance = opts.refDistance ?? 1;\n const maxDistance = opts.maxDistance ?? 10000;\n const rolloff = opts.rolloff ?? 'inverse';\n const rolloffFactor = opts.rolloffFactor ?? 1;\n const panWidth = opts.panWidth ?? 500;\n\n const dx = source.x - listener.x;\n const dy = source.y - listener.y;\n const distance = Math.hypot(dx, dy);\n\n let gain: number;\n if (distance <= refDistance) {\n gain = 1;\n } else if (rolloff === 'linear') {\n const span = maxDistance - refDistance;\n gain = span <= 0 ? 0 : 1 - rolloffFactor * ((distance - refDistance) / span);\n } else {\n gain = refDistance / (refDistance + rolloffFactor * (distance - refDistance));\n }\n gain = Math.min(1, Math.max(0, gain));\n\n const pan = panWidth <= 0 ? 0 : Math.min(1, Math.max(-1, dx / panWidth));\n\n return { gain, pan };\n}\n","/** Runs in the worker. A message with `ms` books timer `id`; one without clears\n * it. Each timer posts its id back once, when it elapses. */\nconst WORKER_SOURCE = `const timers = new Map();\nself.onmessage = (e) => {\n const id = e.data.id;\n clearTimeout(timers.get(id));\n timers.delete(id);\n if (e.data.ms === undefined) return;\n timers.set(id, setTimeout(() => {\n timers.delete(id);\n self.postMessage(id);\n }, e.data.ms));\n};\n`;\n\n/** The timer pair `createTickTimer` returns, shaped for `SchedulerOptions`. */\nexport interface TickTimer {\n /** One-shot, as `createScheduler` expects. */\n setTimer(cb: () => void, ms: number): unknown;\n clearTimer(handle: unknown): void;\n /** Terminate the worker and drop every pending timer. */\n dispose(): void;\n}\n\ninterface Pending {\n cb: () => void;\n ms: number;\n fallback?: ReturnType<typeof setTimeout>;\n}\n\nfunction spawn(): { worker: Worker; url: string } | null {\n if (\n typeof Worker !== 'function' ||\n typeof Blob !== 'function' ||\n typeof URL === 'undefined' ||\n typeof URL.createObjectURL !== 'function'\n ) {\n return null;\n }\n let url: string | undefined;\n try {\n url = URL.createObjectURL(new Blob([WORKER_SOURCE], { type: 'text/javascript' }));\n return { worker: new Worker(url), url };\n } catch {\n if (url !== undefined) URL.revokeObjectURL(url);\n return null;\n }\n}\n\n/**\n * A timer for the scheduler's pass that is not held to the main thread's\n * hidden-tab clamp: each delay runs inside a dedicated Worker, which posts back\n * when it elapses. Falls back to `setTimeout` when no worker can be made — no\n * `Worker` global, a constructor that throws, or a worker that fails to load,\n * which is how a CSP refusal can arrive.\n */\nexport function createTickTimer(): TickTimer {\n let nextId = 1;\n const pending = new Map<number, Pending>();\n let spawned = spawn();\n\n const fire = (id: number): void => {\n const p = pending.get(id);\n if (!p) return;\n pending.delete(id);\n p.cb();\n };\n const arm = (id: number, p: Pending): void => {\n p.fallback = setTimeout(() => fire(id), p.ms);\n };\n const release = (): void => {\n if (!spawned) return;\n spawned.worker.terminate();\n URL.revokeObjectURL(spawned.url);\n spawned = null;\n };\n\n if (spawned) {\n spawned.worker.addEventListener('message', (e: MessageEvent) => fire(e.data as number));\n spawned.worker.addEventListener('error', () => {\n if (!spawned) return;\n release();\n // Anything posted to a worker that never loaded is lost with it.\n for (const [id, p] of pending) arm(id, p);\n });\n }\n\n return {\n setTimer(cb, ms) {\n const id = nextId++;\n const p: Pending = { cb, ms };\n pending.set(id, p);\n if (spawned) spawned.worker.postMessage({ id, ms });\n else arm(id, p);\n return id;\n },\n clearTimer(handle) {\n const id = handle as number;\n const p = pending.get(id);\n if (!p) return;\n pending.delete(id);\n if (p.fallback !== undefined) clearTimeout(p.fallback);\n else spawned?.worker.postMessage({ id });\n },\n dispose() {\n for (const p of pending.values()) {\n if (p.fallback !== undefined) clearTimeout(p.fallback);\n }\n pending.clear();\n release();\n },\n };\n}\n","/** An ADSR envelope. Times are ms; `sustain` is a level, 0..1, of the peak. */\nexport interface Envelope {\n /** Default 5 — long enough that the onset does not click. */\n attack?: number;\n /** Default 0. */\n decay?: number;\n /** Default 1. */\n sustain?: number;\n /** Default 30. */\n release?: number;\n}\n\n/** An envelope with every default filled in and every value in range. */\nexport type ResolvedEnvelope = Required<Envelope>;\n\n/** One breakpoint of an envelope's curve: a level at a time. */\nexport interface EnvelopePoint {\n /** ms from the note's start. */\n at: number;\n value: number;\n}\n\n/** Fill an envelope's defaults, clamping times to zero or more and `sustain` to 0..1. */\nexport function resolveEnvelope(env: Envelope = {}): ResolvedEnvelope {\n return {\n attack: Math.max(0, env.attack ?? 5),\n decay: Math.max(0, env.decay ?? 0),\n sustain: Math.min(1, Math.max(0, env.sustain ?? 1)),\n release: Math.max(0, env.release ?? 30),\n };\n}\n\nconst heldLevel = (e: ResolvedEnvelope, t: number): number => {\n if (t < e.attack) return t / e.attack;\n if (t < e.attack + e.decay) return 1 - ((1 - e.sustain) * (t - e.attack)) / e.decay;\n return e.sustain;\n};\n\n/** The level `t` ms after the start. With `gate`, the release begins that many\n * ms in, from whatever level the envelope had reached. */\nexport function envelopeLevel(e: ResolvedEnvelope, t: number, gate?: number): number {\n if (gate === undefined || t <= gate) return heldLevel(e, t);\n if (e.release === 0) return 0;\n return Math.max(0, heldLevel(e, gate) * (1 - (t - gate) / e.release));\n}\n\n/**\n * Breakpoints joined by linear ramps. Without `gate` they end at the sustain,\n * held until something releases the note; with it they end at zero, `gate +\n * release` ms in.\n */\nexport function envelopePoints(e: ResolvedEnvelope, gate?: number): EnvelopePoint[] {\n const end = gate ?? Infinity;\n const points: EnvelopePoint[] = [{ at: 0, value: e.attack > 0 ? 0 : 1 }];\n for (const at of [e.attack, e.attack + e.decay]) {\n if (at <= points[points.length - 1].at) continue;\n if (at >= end) break;\n points.push({ at, value: heldLevel(e, at) });\n }\n if (gate === undefined) return points;\n if (gate > points[points.length - 1].at) points.push({ at: gate, value: heldLevel(e, gate) });\n points.push({ at: gate + e.release, value: 0 });\n return points;\n}\n","/** A pitch: hertz as a number, a scientific pitch name (`'A4'`, `'C#3'`,\n * `'Bb2'`), or a MIDI note number wrapped as `{ midi }` so it cannot be read\n * as hertz. */\nexport type Pitch = number | string | { midi: number };\n\n/** Equal temperament, A4 = MIDI 69 = 440 Hz. Fractional notes are cents. */\nexport function midiToFrequency(midi: number): number {\n return 440 * 2 ** ((midi - 69) / 12);\n}\n\nconst LETTERS: Record<string, number> = { c: 0, d: 2, e: 4, f: 5, g: 7, a: 9, b: 11 };\n\n/** MIDI number of a scientific pitch name: C4 is 60. Accepts any run of `#`\n * or `b` after the letter. */\nexport function noteToMidi(name: string): number {\n const m = /^([A-Ga-g])([#b]*)(-?\\d+)$/.exec(name.trim());\n if (!m) throw new Error(`@weasel-js/audio: cannot read \"${name}\" as a note name`);\n let semitone = LETTERS[m[1].toLowerCase()];\n for (const acc of m[2]) semitone += acc === '#' ? 1 : -1;\n return (Number(m[3]) + 1) * 12 + semitone;\n}\n\n/** A pitch in hertz. Throws on a note name it cannot read, and on a frequency that is not positive and finite. */\nexport function toFrequency(pitch: Pitch): number {\n const hz = typeof pitch === 'number' ? pitch\n : typeof pitch === 'string' ? midiToFrequency(noteToMidi(pitch))\n : midiToFrequency(pitch.midi);\n if (!(hz > 0) || !Number.isFinite(hz)) {\n throw new RangeError(`@weasel-js/audio: a pitch must be a positive frequency, got ${hz}`);\n }\n return hz;\n}\n","import { envelopeLevel, envelopePoints, resolveEnvelope, type ResolvedEnvelope } from './envelope';\nimport type { Inharmonic, NoiseColor, SynthPartial, VoiceFilter, Waveform } from './types';\n\n/** Seconds of noise in each cached loop: long enough that the repeat is not\n * heard as a pitch. */\nconst NOISE_SECONDS = 2;\n/** Every color is scaled to this RMS, so changing color does not change level. */\nconst NOISE_RMS = 0.25;\n\nconst noiseCache = new WeakMap<BaseAudioContext, Map<NoiseColor, AudioBuffer>>();\n\n/** Samples of `color` noise, seeded so every context gets the same loop. The\n * end is pulled onto the start, so the loop point does not click. */\nexport function noiseSamples(color: NoiseColor, length: number): Float32Array {\n const out = new Float32Array(length);\n let s = 0x9e3779b9;\n const white = (): number => {\n s = (Math.imul(s, 1664525) + 1013904223) >>> 0;\n return (s / 0x100000000) * 2 - 1;\n };\n if (color === 'white') {\n for (let i = 0; i < length; i += 1) out[i] = white();\n } else if (color === 'pink') {\n // Paul Kellet's refined filter: within 0.05 dB of -3 dB/octave above 9 Hz.\n let b0 = 0, b1 = 0, b2 = 0, b3 = 0, b4 = 0, b5 = 0, b6 = 0;\n for (let i = 0; i < length; i += 1) {\n const w = white();\n b0 = 0.99886 * b0 + w * 0.0555179;\n b1 = 0.99332 * b1 + w * 0.0750759;\n b2 = 0.969 * b2 + w * 0.153852;\n b3 = 0.8665 * b3 + w * 0.3104856;\n b4 = 0.55 * b4 + w * 0.5329522;\n b5 = -0.7616 * b5 - w * 0.016898;\n out[i] = b0 + b1 + b2 + b3 + b4 + b5 + b6 + w * 0.5362;\n b6 = w * 0.115926;\n }\n } else {\n // A leaky integrator: -6 dB/octave down to a few Hz, without wandering off.\n let y = 0;\n for (let i = 0; i < length; i += 1) {\n y = (y + 0.02 * white()) / 1.02;\n out[i] = y;\n }\n }\n const step = (out[length - 1] - out[0]) / Math.max(1, length - 1);\n let mean = 0;\n for (let i = 0; i < length; i += 1) {\n out[i] -= step * i;\n mean += out[i];\n }\n mean /= length;\n let sq = 0;\n for (let i = 0; i < length; i += 1) {\n out[i] -= mean;\n sq += out[i] * out[i];\n }\n const scale = sq > 0 ? NOISE_RMS / Math.sqrt(sq / length) : 0;\n for (let i = 0; i < length; i += 1) out[i] *= scale;\n return out;\n}\n\n/** One looping noise buffer per color per context, made on first use. */\nexport function noiseBuffer(ctx: BaseAudioContext, color: NoiseColor): AudioBuffer {\n let byColor = noiseCache.get(ctx);\n if (!byColor) {\n byColor = new Map();\n noiseCache.set(ctx, byColor);\n }\n let buffer = byColor.get(color);\n if (!buffer) {\n const length = Math.round(ctx.sampleRate * NOISE_SECONDS);\n buffer = ctx.createBuffer(1, length, ctx.sampleRate);\n buffer.getChannelData(0).set(noiseSamples(color, length));\n byColor.set(color, buffer);\n }\n return buffer;\n}\n\nexport const isInharmonic = (wave: Waveform): wave is Inharmonic =>\n typeof wave === 'object' && !Array.isArray(wave);\n\n/** Partials with their levels normalized to sum to 1, checked where the note\n * was written rather than when it comes due. */\nexport function resolvePartials(wave: Inharmonic): (SynthPartial & { gain: number })[] {\n if (wave.partials.length === 0) {\n throw new RangeError('@weasel-js/audio: an inharmonic wave needs at least one partial');\n }\n let total = 0;\n for (const p of wave.partials) {\n if (!(p.ratio > 0) || !Number.isFinite(p.ratio)) {\n throw new RangeError(`@weasel-js/audio: partial ratio must be a positive number, got ${p.ratio}`);\n }\n if (p.decay !== undefined && !(p.decay > 0)) {\n throw new RangeError(`@weasel-js/audio: partial decay must be a positive number of ms, got ${p.decay}`);\n }\n total += Math.abs(p.gain ?? 1);\n }\n return wave.partials.map((p) => ({\n ratio: p.ratio,\n gain: total > 0 ? (p.gain ?? 1) / total : 0,\n decay: p.decay,\n }));\n}\n\n/** An envelope written onto a param from `t0` (seconds), mapped through `map`,\n * and the note-off that releases it from wherever it has got to. */\nexport function envelopeOnParam(\n param: AudioParam,\n env: ResolvedEnvelope,\n gate: number | undefined,\n t0: number,\n map: (level: number) => number,\n): { release(at: number): void } {\n const [first, ...rest] = envelopePoints(env, gate);\n param.setValueAtTime(map(first.value), t0);\n for (const p of rest) param.linearRampToValueAtTime(map(p.value), t0 + p.at / 1000);\n return {\n release(at) {\n const elapsed = Math.max(0, (at - t0) * 1000);\n param.cancelScheduledValues(at);\n param.setValueAtTime(map(envelopeLevel(env, elapsed)), at);\n param.linearRampToValueAtTime(map(0), at + env.release / 1000);\n },\n };\n}\n\n/** A voice filter's node, scheduled from `t0`, with its envelope's release. */\nexport function voiceFilter(\n ctx: BaseAudioContext,\n spec: VoiceFilter,\n gate: number | undefined,\n t0: number,\n): { node: BiquadFilterNode; release(at: number): void } {\n const node = ctx.createBiquadFilter();\n node.type = spec.type ?? 'lowpass';\n node.Q.setValueAtTime(spec.Q ?? 1, t0);\n if (spec.gain !== undefined) node.gain.setValueAtTime(spec.gain, t0);\n const amount = spec.amount ?? 0;\n if (!spec.envelope || amount === 0) {\n node.frequency.setValueAtTime(spec.frequency, t0);\n return { node, release: () => {} };\n }\n const cutoff = envelopeOnParam(\n node.frequency, resolveEnvelope(spec.envelope), gate, t0, (v) => spec.frequency + amount * v,\n );\n return { node, release: cutoff.release };\n}\n\n/**\n * Ready-made inharmonic waves. The ratios are the textbook modes of each\n * object; the levels and decays are a starting point to spread and adjust.\n */\nexport const partialPresets = {\n /** A church bell's hum, prime, tierce, quint and nominal, and above. */\n bell: {\n partials: [\n { ratio: 0.5, gain: 0.6, decay: 1800 },\n { ratio: 1, gain: 1, decay: 1200 },\n { ratio: 1.183, gain: 0.7, decay: 900 },\n { ratio: 1.506, gain: 0.4, decay: 700 },\n { ratio: 2, gain: 0.8, decay: 600 },\n { ratio: 2.514, gain: 0.3, decay: 400 },\n { ratio: 2.662, gain: 0.25, decay: 350 },\n { ratio: 3.011, gain: 0.2, decay: 300 },\n ],\n },\n /** A tuned bar: its overtones sit near 4 and 10 times the fundamental and die fast. */\n marimba: {\n partials: [\n { ratio: 1, gain: 1, decay: 350 },\n { ratio: 3.984, gain: 0.35, decay: 90 },\n { ratio: 9.95, gain: 0.12, decay: 30 },\n ],\n },\n /** Struck sheet metal: modes nowhere near the harmonic series. */\n metal: {\n partials: [\n { ratio: 1, gain: 1, decay: 160 },\n { ratio: 1.71, gain: 0.53, decay: 120 },\n { ratio: 2.43, gain: 0.36, decay: 94 },\n { ratio: 3.19, gain: 0.27, decay: 78 },\n { ratio: 4.61, gain: 0.22, decay: 66 },\n { ratio: 5.87, gain: 0.18, decay: 58 },\n ],\n },\n} satisfies Record<string, Inharmonic>;\n","import type { VoiceDropReason } from './types';\n\n/** Tell a voice's owner it never played. Queued, as a source's `onended` is:\n * a play dropped on the spot would otherwise call back before `play()` has\n * returned the handle. */\nexport const reportDrop = (\n onDrop: ((reason: VoiceDropReason) => void) | undefined,\n reason: VoiceDropReason,\n): void => {\n if (onDrop) queueMicrotask(() => onDrop(reason));\n};\n\n/** The console warnings for a dropped play, each given once per engine. */\nexport interface DropWarnings {\n locked(): void;\n disposed(): void;\n unknownSound(id: string): void;\n /** Let `locked` warn again, after the context suspended a second time. */\n rearmLocked(): void;\n}\n\nexport function createDropWarnings(): DropWarnings {\n let warnedLocked = false;\n let warnedDisposed = false;\n let warnedUnknownSound = false;\n return {\n locked() {\n if (warnedLocked) return;\n warnedLocked = true;\n console.warn(\n '@weasel-js/audio: play() before the AudioContext was unlocked — the voice was dropped. ' +\n 'Browsers require a user gesture; call engine.unlock() from one, or wait for the ' +\n 'automatic gesture listener.',\n );\n },\n disposed() {\n if (warnedDisposed) return;\n warnedDisposed = true;\n console.warn('@weasel-js/audio: play() after dispose() — the voice was dropped.');\n },\n unknownSound(id) {\n if (warnedUnknownSound) return;\n warnedUnknownSound = true;\n console.warn(\n `@weasel-js/audio: play() was handed sound \"${id}\", which this engine never loaded — ` +\n 'the voice was dropped. A handle belongs to the engine that produced it.',\n );\n },\n rearmLocked() { warnedLocked = false; },\n };\n}\n","/** Which voice a full pool evicts: the earliest started, or the lowest gain. */\nexport type StealPolicy = 'oldest' | 'quietest';\n\n/** Options for `createVoicePool`. */\nexport interface VoicePoolOptions {\n /** Maximum concurrent voices, at least 1. Beyond this, `acquire` steals. */\n limit: number;\n /** Default 'oldest'. */\n steal?: StealPolicy;\n}\n\n/** What the pool knows about a voice, for choosing one to steal. */\nexport interface VoiceRecord {\n /** Engine time the voice started, in ms. */\n startedAt: number;\n /** Current gain, consulted by the 'quietest' steal policy. */\n gain: number;\n}\n\n/** The result of `VoicePool.acquire`. */\nexport interface Acquisition {\n slot: number;\n /** Identifies this voice, not its slot: a stolen slot is reissued at once,\n * so `release` and `setGain` take the token and ignore a stale one. */\n token: number;\n /** Token of the voice evicted to make room, or null. The caller is\n * responsible for actually stopping that voice's nodes. */\n stolen: number | null;\n}\n\n/** Slot accounting for concurrent voices. See `createVoicePool`. */\nexport interface VoicePool {\n acquire(record: VoiceRecord): Acquisition;\n release(slot: number, token: number): void;\n setGain(slot: number, token: number, gain: number): void;\n active(): number;\n}\n\n/**\n * Slot bookkeeping for concurrent voices, with a steal policy for when the\n * limit is reached.\n *\n * This is pure accounting — it owns no audio nodes. The engine reuses its\n * `GainNode`/`StereoPannerNode` chains separately, and mints a fresh\n * `AudioBufferSourceNode` per play, because a source node is single-use by\n * specification and cannot be restarted once stopped.\n */\nexport function createVoicePool(opts: VoicePoolOptions): VoicePool {\n if (!(opts.limit >= 1)) {\n throw new RangeError(`@weasel-js/audio: voice pool limit must be at least 1, got ${opts.limit}`);\n }\n const steal = opts.steal ?? 'oldest';\n const live = new Map<number, VoiceRecord & { token: number }>();\n const free: number[] = [];\n let nextSlot = 0;\n let nextToken = 1;\n\n const victim = (): number => {\n let worst = -1;\n let worstScore = Infinity;\n for (const [slot, rec] of live) {\n const score = steal === 'quietest' ? rec.gain : rec.startedAt;\n if (score < worstScore) { worstScore = score; worst = slot; }\n }\n return worst;\n };\n\n return {\n acquire(record) {\n const token = nextToken++;\n if (live.size < opts.limit) {\n const slot = free.length > 0 ? free.pop()! : nextSlot++;\n live.set(slot, { ...record, token });\n return { slot, token, stolen: null };\n }\n const slot = victim();\n const stolen = live.get(slot)!.token;\n // Re-inserting moves the slot to the back of the iteration order, so\n // voices tied on score take turns being the victim.\n live.delete(slot);\n live.set(slot, { ...record, token });\n return { slot, token, stolen };\n },\n release(slot, token) {\n if (live.get(slot)?.token !== token) return;\n live.delete(slot);\n free.push(slot);\n },\n setGain(slot, token, gain) {\n const rec = live.get(slot);\n if (rec?.token === token) rec.gain = gain;\n },\n active: () => live.size,\n };\n}\n","import { createAnalyserTap, type AnalyserTap, type AnalyserTapOptions } from './analyser';\nimport { atAudioTime, defaultTimers, type Timers } from './audioTime';\nimport { createBusGraph, type BusHandle } from './buses';\nimport { writeParam } from './param';\nimport { createScheduler } from './scheduler';\nimport { createSoundCache, type SoundHandle } from './soundCache';\nimport { spatialize, type SpatialOptions, type Vec2 } from './spatialize';\nimport { createTickTimer } from './tickTimer';\nimport { resolveEnvelope, type Envelope } from './envelope';\nimport { toFrequency } from './pitch';\nimport {\n envelopeOnParam, isInharmonic, noiseBuffer, resolvePartials, voiceFilter,\n} from './synthVoice';\nimport type {\n AudioEngineOptions, Inharmonic, NoiseOptions, NoteOptions, PlayOptions, StreamOptions,\n VoiceDropReason, VoiceFilter, VoiceHandle, Waveform,\n} from './types';\nimport { createDropWarnings, reportDrop } from './voiceDrops';\nimport { createVoicePool, type VoicePool } from './voicePool';\n\n/** A sound engine: named mix buses, a per-bus voice pool, lookahead\n * scheduling and 2D spatialization over one `AudioContext`. Times are engine\n * ms (`now()`). */\nexport interface AudioEngine {\n /** The engine's `AudioContext` — the one passed as `options.context`, or the\n * one the engine created. Use it for `createBuffer`, for analysis, or for a\n * node graph of your own alongside the engine's.\n *\n * `dispose()` closes a context the engine created, and every call on a\n * closed context throws; a context you passed in is left open, because it is\n * yours to close. The reference stays valid either way — read `state()`\n * rather than assuming. */\n readonly context: AudioContext;\n state(): AudioContextState;\n unlock(): Promise<void>;\n /** Engine time in ms. */\n now(): number;\n load(url: string): Promise<SoundHandle>;\n loadAll(urls: Record<string, string>): Promise<Record<string, SoundHandle>>;\n decode(bytes: ArrayBuffer): Promise<SoundHandle>;\n /** Play a buffer the consumer already holds — a synth, an offline render, a\n * recording. `load` and `decode` both assume encoded bytes. */\n register(buffer: AudioBuffer): SoundHandle;\n play(sound: SoundHandle, opts?: PlayOptions): VoiceHandle;\n /** Play a synthesized note: an oscillator with harmonic partials, or summed\n * sines at any ratios, under an ADSR envelope and an optional filter. It is a voice like any other — same handle, same bus pool\n * and stealing, same `cancelKey`. */\n playNote(note: NoteOptions): VoiceHandle;\n /** Play noise — white, pink or brown, from a looping buffer made once per\n * context — under an envelope and an optional filter with its own cutoff\n * envelope. A voice like `playNote`'s in every other respect. */\n playNoise(noise: NoiseOptions): VoiceHandle;\n /** Stream long audio — music, ambience — from a media element or a URL\n * through a `MediaElementAudioSourceNode`, instead of decoding it whole. It\n * is a voice on a bus like any other, with the exceptions `StreamOptions`\n * lists. An element has one playhead, so streaming one that is already\n * streaming stops the earlier voice. */\n stream(media: HTMLMediaElement | string, opts?: StreamOptions): VoiceHandle;\n /** Book a callback against the audio clock through the engine's lookahead\n * scheduler; it receives its own `when` to hand on to `play` or `playNote`.\n * `stopKey(key)` cancels it. One that came due during a suspension fires\n * late on resume, with its original `when`, so compare against `now()`. */\n schedule(when: number, fire: (when: number) => void, key?: string): void;\n stopKey(key: string): void;\n stopAll(): void;\n bus(name: string): BusHandle;\n /** The configured bus names, in order. The first is `play()`'s default. */\n busNames(): string[];\n /** Voices currently sounding, on one bus or on all of them. A voice booked\n * for a future `when` is not counted until it starts. */\n activeVoices(bus?: string): number;\n analyser(busName?: string, opts?: AnalyserTapOptions): AnalyserTap;\n setListener(p: Vec2, opts?: SpatialOptions): void;\n dispose(): void;\n}\n\n/** A voice pool and its token index. Tokens restart at 1 in every pool, so the\n * index has to be per pool — keyed by bus name, a shared pool would look a\n * steal victim up under the wrong name and silently never tear it down. */\ninterface Slots {\n pool: VoicePool;\n byToken: Map<number, LiveVoice>;\n}\n\n/** What `play` and `playNote` share apart from the node they make. */\ntype VoiceOptions = Omit<PlayOptions, 'loop'>;\n\n/** What a voice plays through: a scheduled source node, or a stand-in with\n * the same end-of-life contract — `onended` fires asynchronously, once. */\ntype SourceLike = Pick<AudioScheduledSourceNode, 'onended' | 'stop' | 'disconnect'>;\n\n/** Several sources stopped together, as one: the first carries `onended`. */\nconst sourceGroup = (nodes: AudioScheduledSourceNode[]): SourceLike => ({\n get onended() { return nodes[0].onended; },\n set onended(fn) { nodes[0].onended = fn; },\n stop(when?: number) {\n for (const n of nodes) {\n try { n.stop(when); } catch { /* not started, or already stopped */ }\n }\n },\n disconnect() { for (const n of nodes) n.disconnect(); },\n});\n\ninterface Starter {\n /** False drops the voice when it comes due. */\n ready(): boolean;\n start(voice: LiveVoice, when: number): SourceLike;\n}\n\ninterface Chain {\n gain: GainNode;\n panner: StereoPannerNode;\n}\n\ninterface LiveVoice {\n id: number;\n slots: Slots;\n /** Null until the scheduler fires it: a voice booked seconds out must not\n * hold a slot, and must not be an eviction candidate, while silent. */\n slot: number | null;\n token: number;\n key?: string;\n onDrop?: (reason: VoiceDropReason) => void;\n source: SourceLike | null;\n /** A synth voice's envelope gain, between its sources and the chain. */\n env: GainNode | null;\n /** Writes `rate` and `detune` to the node, once there is one. */\n retune: (() => void) | null;\n /** A synth voice's note-off. Null for a buffer voice, and until it starts. */\n release: (() => void) | null;\n releasing: boolean;\n /** Null once torn down, when the chain goes back to be reused: a handle\n * that outlives its voice must not write to another voice's nodes. */\n chain: Chain | null;\n baseGain: number;\n spatialGain: number;\n rate: number;\n detune: number;\n /** Kept so `setListener` can re-spatialize a voice that is already playing. */\n position?: Vec2;\n playing: boolean;\n cancelled: boolean;\n /** `stop(fadeMs)` owns the chain gain from here until the source ends. */\n fading: boolean;\n /** Context time a `setGain` ramp on the chain gain ends at; 0 when none was asked for. */\n rampEnd: number;\n}\n\n/**\n * Create an engine. Browsers start the context suspended: `play()` before it\n * is unlocked drops the voice with a warning. The engine resumes it on the\n * first pointer, key or touch gesture, or call `unlock()` from one. Call\n * `dispose()` when done.\n */\nexport function createAudioEngine(opts: AudioEngineOptions = {}): AudioEngine {\n const ctx = opts.context ?? new AudioContext();\n // A context the engine made is a context the engine closes; a consumer's is\n // theirs to keep.\n const ownsContext = opts.context === undefined;\n const random = opts.random ?? Math.random;\n const busNames = opts.buses ?? ['sfx', 'music', 'ui'];\n if (busNames.length === 0) {\n throw new Error('@weasel-js/audio: an engine needs at least one bus');\n }\n const sounds = createSoundCache(ctx, opts.fetchFn);\n // One pool PER BUS, not one global pool: the spec's limit is per-bus, and a\n // shared pool lets a burst of one-shots on `sfx` steal the music bed.\n const slotsByBus = new Map<string, Slots>();\n for (const name of busNames) {\n slotsByBus.set(name, {\n pool: createVoicePool({ limit: opts.voiceLimit ?? 32, steal: opts.steal }),\n byToken: new Map(),\n });\n }\n const slotsFor = (bus: string): Slots => {\n const s = slotsByBus.get(bus);\n if (!s) throw new Error(`@weasel-js/audio: unknown bus \"${bus}\"`);\n return s;\n };\n\n const now = (): number => ctx.currentTime * 1000;\n const tickTimer = opts.setTimer === undefined && opts.clearTimer === undefined\n ? createTickTimer()\n : null;\n const timers: Timers = {\n setTimer: tickTimer?.setTimer ?? opts.setTimer ?? defaultTimers.setTimer,\n clearTimer: tickTimer?.clearTimer ?? opts.clearTimer ?? defaultTimers.clearTimer,\n };\n const scheduler = createScheduler({\n now,\n // One-shot, not repeating: the scheduler re-arms at the end of every pass,\n // so an interval would leave the previous one running and double the live\n // timer count per tick.\n setTimer: timers.setTimer,\n clearTimer: timers.clearTimer,\n lookahead: opts.lookahead,\n interval: opts.tickInterval,\n });\n scheduler.start();\n const graph = createBusGraph(ctx, busNames, { ...timers, fadeMs: opts.insertFadeMs });\n\n let listener: Vec2 = { x: 0, y: 0 };\n let spatialOpts: SpatialOptions = {};\n let nextVoiceId = 1;\n let disposed = false;\n let suspendedSince = false;\n /** Engine time before which a queued entry is stale — set on resume, so a\n * suspension does not end in one pass that fires its whole backlog. */\n let staleFloor = -Infinity;\n const live = new Map<number, LiveVoice>();\n const taps = new Set<AnalyserTap>();\n\n // An idle chain is kept off its bus: still wired to the destination, it costs\n // the audio thread every render quantum whether or not anything sounds.\n const idleChains: Chain[] = [];\n const idleChainLimit = (opts.voiceLimit ?? 32) * busNames.length;\n const takeChain = (bus: AudioNode, gain: number, pan: number): Chain => {\n let chain = idleChains.pop();\n if (!chain) {\n chain = { gain: ctx.createGain(), panner: ctx.createStereoPanner() };\n chain.panner.connect(chain.gain);\n }\n // Not a bare `.value`: a reused gain can still hold the last voice's fade.\n writeParam(ctx, chain.gain.gain, gain);\n chain.panner.pan.value = pan;\n chain.gain.connect(bus);\n return chain;\n };\n\n const warn = createDropWarnings();\n\n // Resume on a user gesture, and keep listening until one takes. On touch a\n // tap grants activation at pointerup, touchend and click, not at pointerdown\n // or touchstart, so the first events of a first tap resume nothing.\n const gestures = ['pointerdown', 'pointerup', 'touchend', 'click', 'keydown'] as const;\n const onGesture = (): void => { void engine.unlock().catch(() => undefined); };\n const armGestures = (): void => {\n if (typeof window === 'undefined') return;\n for (const g of gestures) window.addEventListener(g, onGesture, { passive: true });\n };\n const disarmGestures = (): void => {\n if (typeof window === 'undefined') return;\n for (const g of gestures) window.removeEventListener(g, onGesture);\n };\n if (ctx.state !== 'running') armGestures();\n\n // A browser suspends the context when the tab goes away, and the gesture\n // listeners are long removed by then. Without this the engine is\n // permanently silent afterwards, with no diagnostic — the drop warning is a\n // once-per-engine latch.\n const onStateChange = (): void => {\n if (disposed) return;\n if (ctx.state === 'running') {\n disarmGestures();\n if (suspendedSince) staleFloor = now();\n suspendedSince = false;\n return;\n }\n suspendedSince = true;\n warn.rearmLocked();\n armGestures();\n };\n ctx.addEventListener('statechange', onStateChange);\n\n const poolGain = (voice: LiveVoice): void => {\n if (voice.slot === null) return;\n voice.slots.pool.setGain(voice.slot, voice.token, voice.baseGain * voice.spatialGain);\n };\n\n const applySpatial = (voice: LiveVoice): void => {\n if (!voice.position || !voice.chain) return;\n const s = spatialize(voice.position, listener, spatialOpts);\n voice.spatialGain = s.gain;\n voice.chain.panner.pan.value = s.pan;\n if (!voice.fading) {\n // writeParam cancels what is scheduled, so a ramp still running is rescheduled to the same end.\n const left = (voice.rampEnd - ctx.currentTime) * 1000;\n writeParam(ctx, voice.chain.gain.gain, voice.baseGain * s.gain, left > 0 ? left : undefined);\n }\n poolGain(voice);\n };\n\n const teardown = (voice: LiveVoice, reason: VoiceDropReason = 'stopped'): void => {\n // First, and never at a call site: teardown is what makes a voice dead, and\n // a queued callback that outlives it must find it cancelled. The steal path\n // has no other place to set this.\n voice.cancelled = true;\n if (!voice.playing && voice.source === null) return;\n voice.playing = false;\n if (voice.source === null) reportDrop(voice.onDrop, reason);\n if (voice.source) {\n try { voice.source.stop(); } catch { /* already stopped */ }\n voice.source.disconnect();\n }\n voice.source = null;\n voice.retune = null;\n voice.release = null;\n voice.env?.disconnect();\n voice.env = null;\n if (voice.chain) {\n voice.chain.gain.disconnect();\n if (idleChains.length < idleChainLimit) idleChains.push(voice.chain);\n voice.chain = null;\n }\n live.delete(voice.id);\n if (voice.slot !== null) {\n voice.slots.byToken.delete(voice.token);\n // Safe on the steal path too: the pool has already reissued this slot\n // under a new token, and it ignores a release carrying the old one.\n voice.slots.pool.release(voice.slot, voice.token);\n }\n };\n\n const stopVoices = (reason: VoiceDropReason): void => {\n for (const voice of [...live.values()]) teardown(voice, reason);\n };\n\n const dropped = (id: number): VoiceHandle => ({\n id,\n stop: () => {}, release: () => {}, setGain: () => {}, setRate: () => {}, setDetune: () => {},\n setPan: () => {}, setPosition: () => {}, isPlaying: () => false,\n });\n\n /**\n * Everything a voice does apart from making its node: the lock and dispose\n * checks, the chain, the booking, the stale-backlog check, the slot and any\n * steal, and the handle. `starter.start` builds the node, connects it into\n * `voice.chain.panner` and starts it at the time it is handed.\n */\n const launch = (common: VoiceOptions, starter: Starter): VoiceHandle => {\n const id = nextVoiceId++;\n\n if (disposed) {\n warn.disposed();\n reportDrop(common.onDrop, 'disposed');\n return dropped(id);\n }\n if (ctx.state !== 'running') {\n warn.locked();\n reportDrop(common.onDrop, 'locked');\n return dropped(id);\n }\n\n const busName = common.bus ?? busNames[0];\n const slots = slotsFor(busName);\n const bookedAt = now();\n const when = common.when ?? bookedAt;\n const baseGain = common.gain ?? 1;\n\n const spatial = common.position\n ? spatialize(common.position, listener, spatialOpts)\n : { gain: 1, pan: common.pan ?? 0 };\n\n const voice: LiveVoice = {\n id, slots, slot: null, token: 0, key: common.cancelKey, onDrop: common.onDrop,\n source: null, env: null, retune: null, release: null, releasing: false,\n chain: takeChain(graph.input(busName), baseGain * spatial.gain, spatial.pan),\n baseGain, spatialGain: spatial.gain,\n rate: common.rate ?? 1, detune: common.detune ?? 0,\n position: common.position,\n playing: true, cancelled: false, fading: false, rampEnd: 0,\n };\n live.set(id, voice);\n\n scheduler.schedule(when, (scheduledWhen) => {\n if (voice.cancelled) return;\n // Came due while the context was suspended: starting it now would play\n // a backlog at once, which is what dropping a locked play avoids. A voice\n // played since the resume is no backlog, however early its `when`.\n if (bookedAt < staleFloor && scheduledWhen < staleFloor) {\n teardown(voice, 'stale');\n return;\n }\n if (!starter.ready()) {\n teardown(voice, 'unready');\n return;\n }\n\n // The slot is taken here, not at booking time. A voice booked a bar out\n // would otherwise hold one while silent — and, its `startedAt` being in\n // the future, be the last thing the 'oldest' policy evicts, so booking\n // a bar of events would evict everything currently audible.\n const acquired = slots.pool.acquire({\n startedAt: scheduledWhen,\n gain: voice.baseGain * voice.spatialGain,\n });\n voice.slot = acquired.slot;\n voice.token = acquired.token;\n slots.byToken.set(acquired.token, voice);\n if (acquired.stolen !== null) {\n const victim = slots.byToken.get(acquired.stolen);\n if (victim) teardown(victim);\n }\n\n let source: SourceLike;\n try {\n source = starter.start(voice, scheduledWhen);\n } catch (err) {\n // Not back to the idle chains: whatever the starter built before it threw is still wired into this one.\n voice.chain?.gain.disconnect();\n voice.chain = null;\n teardown(voice, 'failed');\n throw err;\n }\n source.onended = () => { teardown(voice); common.onDone?.(); };\n voice.source = source;\n }, common.cancelKey);\n\n return {\n id,\n stop(fadeMs) {\n if (fadeMs && fadeMs > 0 && voice.source && voice.chain && !voice.cancelled) {\n // Cancelled but not torn down: the fade is what ends this voice, and\n // stopping the source now would cut the ramp scheduled a line above\n // it — which is the click `fadeMs` exists to avoid. `onended` does\n // the bookkeeping when the fade reaches the end.\n voice.cancelled = true;\n voice.fading = true;\n writeParam(ctx, voice.chain.gain.gain, 0, fadeMs);\n try { voice.source.stop(ctx.currentTime + fadeMs / 1000); } catch { /* ended */ }\n return;\n }\n teardown(voice);\n },\n release() {\n if (voice.releasing) return;\n if (voice.release && voice.source && !voice.cancelled) {\n // Like a fade: `onended` tears the voice down once the release is out.\n voice.releasing = true;\n voice.cancelled = true;\n voice.release();\n return;\n }\n teardown(voice);\n },\n setGain(value, rampMs) {\n voice.baseGain = value;\n if (!voice.chain || voice.fading) return;\n voice.rampEnd = rampMs && rampMs > 0 ? ctx.currentTime + rampMs / 1000 : 0;\n writeParam(ctx, voice.chain.gain.gain, value * voice.spatialGain, rampMs);\n poolGain(voice);\n },\n setRate(value) {\n voice.rate = value;\n voice.retune?.();\n },\n setDetune(cents) {\n voice.detune = cents;\n voice.retune?.();\n },\n setPan(value) {\n voice.position = undefined;\n if (voice.chain) voice.chain.panner.pan.value = value;\n },\n setPosition(p) {\n voice.position = p;\n applySpatial(voice);\n },\n isPlaying: () => voice.playing,\n };\n };\n\n /**\n * What every synth voice shares once its sources exist: sources → optional\n * filter → envelope gain → the voice's chain, the envelopes on both, the stop\n * at the end of the release, and the note-off. `make` builds and starts the\n * sources at `t0`, connected into the node it is handed.\n */\n const synthStart = (\n voice: LiveVoice,\n whenMs: number,\n patch: { envelope?: Envelope; filter?: VoiceFilter; duration?: number },\n make: (t0: number, into: AudioNode) => { nodes: AudioScheduledSourceNode[]; retune: () => void },\n ): SourceLike => {\n const t0 = whenMs / 1000;\n const env = resolveEnvelope(patch.envelope);\n const gate = patch.duration;\n // Its own gain, not the chain's: `setGain` and a fade cancel whatever is\n // scheduled on the chain's gain, and would take the envelope with it.\n const shaper = ctx.createGain();\n const amp = envelopeOnParam(shaper.gain, env, gate, t0, (v) => v);\n const filter = patch.filter ? voiceFilter(ctx, patch.filter, gate, t0) : null;\n filter?.node.connect(shaper);\n shaper.connect(voice.chain!.panner);\n voice.env = shaper;\n\n const { nodes, retune } = make(t0, filter?.node ?? shaper);\n voice.retune = retune;\n retune();\n const stopAll = (at: number): void => { for (const n of nodes) n.stop(at); };\n voice.release = () => {\n const at = ctx.currentTime;\n // Already past its gate: the release is running and the stop is booked.\n if (gate !== undefined && at * 1000 - whenMs >= gate) return;\n amp.release(at);\n filter?.release(at);\n stopAll(at + env.release / 1000);\n };\n if (gate !== undefined) stopAll(t0 + (gate + env.release) / 1000);\n return nodes.length === 1 ? nodes[0] : sourceGroup(nodes);\n };\n\n const waves = new Map<string, PeriodicWave>();\n const applyWave = (osc: OscillatorNode, wave: Exclude<Waveform, Inharmonic>): void => {\n if (typeof wave === 'string') {\n osc.type = wave;\n return;\n }\n const key = wave.join(',');\n let periodic = waves.get(key);\n if (!periodic) {\n // Sine terms only: partial k sits at imag[k], and index 0 is the DC term.\n const imag = new Float32Array(wave.length + 1);\n imag.set(wave, 1);\n periodic = ctx.createPeriodicWave(new Float32Array(wave.length + 1), imag);\n waves.set(key, periodic);\n }\n osc.setPeriodicWave(periodic);\n };\n\n // An element can be routed into a graph once, ever: the node is kept for the\n // element's lifetime and handed from voice to voice.\n const mediaSources = new WeakMap<HTMLMediaElement, MediaElementAudioSourceNode>();\n const streaming = new WeakMap<HTMLMediaElement, VoiceHandle>();\n\n const openMedia = (url: string, crossOrigin: StreamOptions['crossOrigin']): HTMLMediaElement => {\n const el = new Audio();\n if (crossOrigin !== undefined) el.crossOrigin = crossOrigin;\n el.preload = 'auto';\n el.src = url;\n return el;\n };\n\n /** A media element's playback as a voice source: `stop(when)` pauses once\n * the audio clock reaches `when`, and the element ending ends the voice. */\n const mediaSource = (el: HTMLMediaElement, node: AudioNode, into: AudioNode): SourceLike => {\n let ended = false;\n let cancelWait: (() => void) | null = null;\n const finish = (): void => {\n if (ended) return;\n ended = true;\n cancelWait?.();\n el.pause();\n el.removeEventListener('ended', finish);\n el.removeEventListener('error', finish);\n // Queued, as a source node's `onended` is: the engine may be inside the\n // teardown that called `stop()`.\n queueMicrotask(() => (shim.onended as (() => void) | null)?.());\n };\n const shim: SourceLike = {\n onended: null,\n stop(when?: number) {\n if (ended) return;\n cancelWait?.();\n cancelWait = when !== undefined && when > ctx.currentTime\n ? atAudioTime(ctx, timers, when, finish)\n : null;\n if (!cancelWait) finish();\n },\n disconnect() {\n try { node.disconnect(into); } catch { /* not wired */ }\n },\n };\n el.addEventListener('ended', finish);\n el.addEventListener('error', finish);\n el.play().catch((err: unknown) => {\n if (ended) return;\n console.warn(`@weasel-js/audio: a stream would not start — ${String(err)}`);\n finish();\n });\n return shim;\n };\n\n const engine: AudioEngine = {\n context: ctx,\n state: () => ctx.state,\n async unlock() {\n if (disposed) return;\n if (ctx.state !== 'running') await ctx.resume();\n },\n now,\n load: sounds.load,\n loadAll: sounds.loadAll,\n decode: sounds.decode,\n register: sounds.register,\n\n play(sound, playOpts = {}) {\n return launch(playOpts, {\n ready() {\n if (sounds.buffer(sound)) return true;\n warn.unknownSound(sound.id);\n return false;\n },\n start(voice, when) {\n // A fresh source per play: AudioBufferSourceNode is single-use by\n // specification and cannot be restarted once stopped.\n const source = ctx.createBufferSource();\n source.buffer = sounds.buffer(sound)!;\n source.loop = playOpts.loop ?? false;\n voice.retune = () => {\n source.playbackRate.value = voice.rate;\n source.detune.value = voice.detune;\n };\n voice.retune();\n // Still live when this runs, so the voice still holds its chain.\n source.connect(voice.chain!.panner);\n source.start(when / 1000);\n return source;\n },\n });\n },\n\n playNote(note) {\n // Resolved at the call rather than when it comes due, so a bad pitch or\n // partial throws where it was written.\n const from = toFrequency(note.pitch);\n const glideTo = note.glide ? toFrequency(note.glide.to) : undefined;\n const wave = note.wave ?? 'sine';\n const partials = isInharmonic(wave) ? resolvePartials(wave) : null;\n return launch(note, {\n ready: () => true,\n start: (voice, whenMs) => synthStart(voice, whenMs, note, (t0, into) => {\n const tone = (ratio: number): OscillatorNode => {\n const osc = ctx.createOscillator();\n osc.frequency.setValueAtTime(from * ratio, t0);\n if (glideTo !== undefined) {\n const end = t0 + (note.glide!.ms ?? note.duration ?? 100) / 1000;\n if (note.glide!.curve === 'linear') osc.frequency.linearRampToValueAtTime(glideTo * ratio, end);\n else osc.frequency.exponentialRampToValueAtTime(glideTo * ratio, end);\n }\n return osc;\n };\n let oscs: OscillatorNode[];\n if (partials) {\n // Sines summed by hand: a PeriodicWave can only hold whole-number partials.\n oscs = partials.map((p) => {\n const osc = tone(p.ratio);\n const level = ctx.createGain();\n level.gain.setValueAtTime(p.gain, t0);\n if (p.decay !== undefined) level.gain.setTargetAtTime(0, t0, p.decay / 1000);\n osc.connect(level);\n level.connect(into);\n return osc;\n });\n } else {\n const osc = tone(1);\n applyWave(osc, wave as Exclude<Waveform, Inharmonic>);\n osc.connect(into);\n oscs = [osc];\n }\n for (const osc of oscs) osc.start(t0);\n return {\n nodes: oscs,\n retune: () => {\n for (const osc of oscs) osc.detune.value = voice.detune + 1200 * Math.log2(voice.rate);\n },\n };\n }),\n });\n },\n\n playNoise(noise) {\n return launch(noise, {\n ready: () => true,\n start: (voice, whenMs) => synthStart(voice, whenMs, noise, (t0, into) => {\n const source = ctx.createBufferSource();\n source.buffer = noiseBuffer(ctx, noise.noise);\n source.loop = true;\n source.connect(into);\n // A random point in the loop, so two hits in a row are not the same hit.\n source.start(t0, random() * source.buffer.duration);\n return {\n nodes: [source],\n retune: () => {\n source.playbackRate.value = voice.rate;\n source.detune.value = voice.detune;\n },\n };\n }),\n });\n },\n\n stream(media, streamOpts = {}) {\n const el = typeof media === 'string' ? openMedia(media, streamOpts.crossOrigin) : media;\n streaming.get(el)?.stop();\n const handle = launch(streamOpts, {\n ready: () => true,\n start(voice) {\n let node = mediaSources.get(el);\n if (!node) {\n node = ctx.createMediaElementSource(el);\n mediaSources.set(el, node);\n }\n el.loop = streamOpts.loop ?? false;\n if (streamOpts.offset !== undefined) el.currentTime = streamOpts.offset / 1000;\n voice.retune = () => { el.playbackRate = voice.rate; };\n voice.retune();\n const into = voice.chain!.panner;\n node.connect(into);\n return mediaSource(el, node, into);\n },\n });\n streaming.set(el, handle);\n return handle;\n },\n\n schedule(when, fire, key) {\n if (disposed) return;\n scheduler.schedule(when, fire, key);\n },\n\n stopKey(key) {\n scheduler.cancelKey(key);\n for (const voice of [...live.values()]) {\n if (voice.key === key) teardown(voice);\n }\n },\n stopAll: () => stopVoices('stopped'),\n bus: graph.bus,\n busNames: graph.names,\n activeVoices(bus) {\n if (bus !== undefined) return slotsFor(bus).pool.active();\n let total = 0;\n for (const s of slotsByBus.values()) total += s.pool.active();\n return total;\n },\n analyser(busName, tapOpts) {\n // Every tap is one more live FFT on the graph. They are tracked so\n // `dispose()` detaches them; a consumer calling this per frame still\n // wants to keep one tap rather than mint one.\n const tap = createAnalyserTap(ctx, busName ? graph.node(busName) : graph.master, tapOpts);\n taps.add(tap);\n return {\n ...tap,\n dispose() {\n taps.delete(tap);\n tap.dispose();\n },\n };\n },\n setListener(p, o) {\n listener = p;\n if (o) spatialOpts = o;\n for (const voice of live.values()) applySpatial(voice);\n },\n dispose() {\n if (disposed) return;\n disposed = true;\n stopVoices('disposed');\n idleChains.length = 0;\n scheduler.stop();\n scheduler.clear();\n tickTimer?.dispose();\n for (const tap of [...taps]) tap.dispose();\n taps.clear();\n disarmGestures();\n ctx.removeEventListener('statechange', onStateChange);\n graph.dispose();\n graph.master.disconnect();\n if (ownsContext) void ctx.close().catch(() => undefined);\n },\n };\n\n return engine;\n}\n","import type { InsertEffect } from './inserts';\nimport { writeParam } from './param';\n\n// Built-in insert effects. Each exposes its Web Audio nodes for anything its\n// options do not cover; times are ms, as everywhere else in the package.\n\n/** Options for `createFilterEffect`. Unset ones keep the node's defaults. */\nexport interface FilterEffectOptions {\n /** Default 'lowpass'. */\n type?: BiquadFilterType;\n /** Hz. Default 350, the node's own. */\n frequency?: number;\n Q?: number;\n /** dB, for the shelf and peaking types. */\n gain?: number;\n}\n\n/** A filter insert, with its `BiquadFilterNode` exposed. */\nexport interface FilterEffect extends InsertEffect {\n readonly filter: BiquadFilterNode;\n}\n\n/** A `BiquadFilterNode`. Write its params through `filter` to sweep it. */\nexport function createFilterEffect(ctx: BaseAudioContext, opts: FilterEffectOptions = {}): FilterEffect {\n const filter = ctx.createBiquadFilter();\n filter.type = opts.type ?? 'lowpass';\n if (opts.frequency !== undefined) writeParam(ctx, filter.frequency, opts.frequency);\n if (opts.Q !== undefined) writeParam(ctx, filter.Q, opts.Q);\n if (opts.gain !== undefined) writeParam(ctx, filter.gain, opts.gain);\n return { input: filter, output: filter, filter };\n}\n\n/** A wet/dry mix around an effect, for the effects whose output replaces\n * rather than colors the signal. */\nexport interface WetDryMix {\n /** 0 is all dry, 1 all wet. */\n mix(): number;\n setMix(mix: number, rampMs?: number): void;\n}\n\nconst checkMix = (mix: number): number => {\n if (!(mix >= 0 && mix <= 1)) throw new RangeError(`@weasel-js/audio: mix ${mix} is outside 0..1`);\n return mix;\n};\n\n/** `input → dry → output` beside `input → wetIn … wetOut → wet → output`.\n * The dry route is wired first. */\nfunction wetDry(\n ctx: BaseAudioContext,\n wetIn: AudioNode,\n wetOut: AudioNode,\n initial: number,\n): WetDryMix & { input: GainNode; output: GainNode } {\n const input = ctx.createGain();\n const output = ctx.createGain();\n const dry = ctx.createGain();\n const wet = ctx.createGain();\n input.connect(dry);\n dry.connect(output);\n input.connect(wetIn);\n wetOut.connect(wet);\n wet.connect(output);\n let mix = checkMix(initial);\n const write = (rampMs?: number): void => {\n writeParam(ctx, dry.gain, 1 - mix, rampMs);\n writeParam(ctx, wet.gain, mix, rampMs);\n };\n write();\n return {\n input, output,\n mix: () => mix,\n setMix(value, rampMs) {\n mix = checkMix(value);\n write(rampMs);\n },\n };\n}\n\n/** Options for `createReverbEffect`. */\nexport interface ReverbEffectOptions {\n /** The room: an impulse response, loaded or synthesized like any buffer. */\n impulse: AudioBuffer;\n /** Default 0.3. */\n mix?: number;\n /** Scale the impulse to a consistent level. Default true, the node's own. */\n normalize?: boolean;\n}\n\n/** A reverb insert, with its `ConvolverNode` exposed. */\nexport interface ReverbEffect extends InsertEffect, WetDryMix {\n readonly convolver: ConvolverNode;\n}\n\n/** Convolution reverb from an impulse buffer, with a wet/dry mix. */\nexport function createReverbEffect(ctx: BaseAudioContext, opts: ReverbEffectOptions): ReverbEffect {\n const convolver = ctx.createConvolver();\n // Before the buffer: the node reads `normalize` when the buffer is set.\n convolver.normalize = opts.normalize ?? true;\n convolver.buffer = opts.impulse;\n const m = wetDry(ctx, convolver, convolver, opts.mix ?? 0.3);\n return { input: m.input, output: m.output, convolver, mix: m.mix, setMix: m.setMix };\n}\n\n/** Options for `createDelayEffect`. */\nexport interface DelayEffectOptions {\n /** ms. Default 250. */\n time?: number;\n /** How much of each repeat feeds the next, -1..1 exclusive. Default 0.35. */\n feedback?: number;\n /** Default 0.35. */\n mix?: number;\n /** The longest `time` the line can be set to later, ms. Default the larger\n * of 1000 and `time`. */\n maxTime?: number;\n}\n\n/** A feedback delay insert, with its `DelayNode` exposed. Ramps are ms. */\nexport interface DelayEffect extends InsertEffect, WetDryMix {\n readonly delay: DelayNode;\n setTime(ms: number, rampMs?: number): void;\n feedback(): number;\n setFeedback(value: number, rampMs?: number): void;\n /** Break the feedback loop. Called for you when the slot is removed. */\n dispose(): void;\n}\n\nconst checkFeedback = (value: number): number => {\n if (!(value > -1 && value < 1)) {\n throw new RangeError(`@weasel-js/audio: feedback ${value} must be inside -1..1, or the repeats grow`);\n }\n return value;\n};\n\n/** A feedback delay with a wet/dry mix. Ramping `setTime` bends the pitch of\n * the repeats while it moves, as a tape delay does. */\nexport function createDelayEffect(ctx: BaseAudioContext, opts: DelayEffectOptions = {}): DelayEffect {\n const time = opts.time ?? 250;\n const maxTime = opts.maxTime ?? Math.max(1000, time);\n let fb = checkFeedback(opts.feedback ?? 0.35);\n const delay = ctx.createDelay(maxTime / 1000);\n const loop = ctx.createGain();\n const m = wetDry(ctx, delay, delay, opts.mix ?? 0.35);\n delay.connect(loop);\n loop.connect(delay);\n writeParam(ctx, delay.delayTime, time / 1000);\n writeParam(ctx, loop.gain, fb);\n return {\n input: m.input, output: m.output, delay, mix: m.mix, setMix: m.setMix,\n setTime(ms, rampMs) {\n if (!(ms >= 0 && ms <= maxTime)) {\n throw new RangeError(`@weasel-js/audio: delay time ${ms} is outside 0..${maxTime} ms`);\n }\n writeParam(ctx, delay.delayTime, ms / 1000, rampMs);\n },\n feedback: () => fb,\n setFeedback(value, rampMs) {\n fb = checkFeedback(value);\n writeParam(ctx, loop.gain, fb, rampMs);\n },\n dispose() {\n delay.disconnect();\n loop.disconnect();\n },\n };\n}\n\n/** Options for `createCompressorEffect`. Unset ones keep the node's defaults. */\nexport interface CompressorEffectOptions {\n /** dB. */\n threshold?: number;\n /** dB. */\n knee?: number;\n ratio?: number;\n /** ms. */\n attack?: number;\n /** ms. */\n release?: number;\n /** Linear gain after the compressor, to win back the level it takes. Default 1. */\n makeup?: number;\n}\n\n/** A compressor insert, with its `DynamicsCompressorNode` and makeup `GainNode` exposed. */\nexport interface CompressorEffect extends InsertEffect {\n readonly compressor: DynamicsCompressorNode;\n readonly makeup: GainNode;\n}\n\n/** A `DynamicsCompressorNode` into a makeup gain. Unset options keep the\n * node's defaults. */\nexport function createCompressorEffect(\n ctx: BaseAudioContext,\n opts: CompressorEffectOptions = {},\n): CompressorEffect {\n const compressor = ctx.createDynamicsCompressor();\n const makeup = ctx.createGain();\n compressor.connect(makeup);\n const set = (param: AudioParam, value: number | undefined): void => {\n if (value !== undefined) writeParam(ctx, param, value);\n };\n set(compressor.threshold, opts.threshold);\n set(compressor.knee, opts.knee);\n set(compressor.ratio, opts.ratio);\n set(compressor.attack, opts.attack === undefined ? undefined : opts.attack / 1000);\n set(compressor.release, opts.release === undefined ? undefined : opts.release / 1000);\n set(makeup.gain, opts.makeup ?? 1);\n return { input: compressor, output: makeup, compressor, makeup };\n}\n","import type { AudioEngine } from './createAudioEngine';\nimport type { SoundHandle } from './soundCache';\nimport type { NoiseOptions, NoteOptions, PlayOptions, VoiceHandle } from './types';\n\n/** A synth note on a step. `length` is its gate in steps, default 1. */\nexport interface PatternNote extends Omit<NoteOptions, 'when' | 'duration'> {\n step: number;\n length?: number;\n}\n\n/** Noise on a step: a hi-hat, a snare's rattle. `length` is its gate in steps,\n * default 1. */\nexport interface PatternNoise extends Omit<NoiseOptions, 'when' | 'duration'> {\n step: number;\n length?: number;\n}\n\n/** A buffer played on a step: a drum hit, a sample. */\nexport interface PatternHit extends Omit<PlayOptions, 'when'> {\n step: number;\n sound: SoundHandle;\n}\n\n/** Anything a pattern plays on a step. */\nexport type PatternEvent = PatternNote | PatternNoise | PatternHit;\n\n/** Options for `createPatternPlayer`. */\nexport interface PatternPlayerOptions {\n /** Beats per minute. */\n tempo: number;\n /** Steps per beat. Default 4, so a step is a sixteenth note in 4/4. */\n stepsPerBeat?: number;\n events?: readonly PatternEvent[];\n /** Steps in one pass. Default: through the last event, rounded up to a whole\n * beat. */\n length?: number;\n /** Default true. */\n loop?: boolean;\n /** Called as each step is booked — up to a lookahead ahead of it sounding —\n * with its index in the pattern and its engine time in ms. */\n onStep?: (step: number, when: number) => void;\n}\n\n/** A running sequence of steps. See `createPatternPlayer`. */\nexport interface PatternPlayer {\n /** Start from step 0 at engine time `when`, default now. No-op while playing. */\n start(when?: number): void;\n /** Book nothing further, and release every voice the player started. */\n stop(): void;\n playing(): boolean;\n tempo(): number;\n /** Takes effect from the next step not yet booked. */\n setTempo(bpm: number): void;\n /** Takes effect from the next step not yet booked. */\n setEvents(events: readonly PatternEvent[], length?: number): void;\n}\n\nlet nextPlayer = 1;\n\nconst checkTempo = (bpm: number): void => {\n if (!(bpm > 0) || !Number.isFinite(bpm)) {\n throw new RangeError(`@weasel-js/audio: tempo must be a positive number of bpm, got ${bpm}`);\n }\n};\n\n/**\n * A step sequencer over `engine`. Each step is one `engine.schedule` booking;\n * when it fires, it books that step's events at the step's exact time and then\n * books the step after it. So nothing is booked further ahead than the\n * scheduler's lookahead, which is what lets a tempo change or new events land\n * on the very next step.\n *\n * A step that fires more than a step late — a stalled timer, a suspended\n * context — skips to the next step still ahead of the clock, keeping phase,\n * rather than playing the missed ones at once.\n */\nexport function createPatternPlayer(engine: AudioEngine, opts: PatternPlayerOptions): PatternPlayer {\n checkTempo(opts.tempo);\n const stepsPerBeat = opts.stepsPerBeat ?? 4;\n const loop = opts.loop ?? true;\n const key = `\\u0000pattern:${nextPlayer++}`;\n\n let bpm = opts.tempo;\n let length = 1;\n let byStep = new Map<number, PatternEvent[]>();\n const setEvents = (events: readonly PatternEvent[], len?: number): void => {\n byStep = new Map();\n let last = -1;\n for (const e of events) {\n const list = byStep.get(e.step);\n if (list) list.push(e);\n else byStep.set(e.step, [e]);\n last = Math.max(last, e.step);\n }\n length = len ?? Math.max(1, Math.ceil((last + 1) / stepsPerBeat)) * stepsPerBeat;\n };\n setEvents(opts.events ?? [], opts.length);\n\n let running = false;\n /** Steps booked since `start`, not wrapped. */\n let count = 0;\n let lastAt: number | null = null;\n let nextAt = 0;\n const voices = new Set<VoiceHandle>();\n\n const stepMs = (): number => 60_000 / bpm / stepsPerBeat;\n\n const book = (): void => { engine.schedule(nextAt, fire, key); };\n\n const fire = (scheduled: number): void => {\n if (!running) return;\n let when = scheduled;\n const behind = engine.now() - when;\n if (behind > stepMs()) {\n const skip = Math.ceil(behind / stepMs());\n count += skip;\n when += skip * stepMs();\n }\n if (!loop && count >= length) {\n running = false;\n return;\n }\n const step = count % length;\n for (const v of voices) if (!v.isPlaying()) voices.delete(v);\n for (const e of byStep.get(step) ?? []) {\n if ('sound' in e) {\n const { step: _s, sound, ...play } = e;\n voices.add(engine.play(sound, { ...play, when }));\n } else if ('noise' in e) {\n const { step: _s, length: steps = 1, ...noise } = e;\n voices.add(engine.playNoise({ ...noise, when, duration: steps * stepMs() }));\n } else {\n const { step: _s, length: steps = 1, ...note } = e;\n voices.add(engine.playNote({ ...note, when, duration: steps * stepMs() }));\n }\n }\n opts.onStep?.(step, when);\n count += 1;\n lastAt = when;\n nextAt = when + stepMs();\n book();\n };\n\n return {\n start(when) {\n if (running) return;\n running = true;\n count = 0;\n lastAt = null;\n nextAt = when ?? engine.now();\n book();\n },\n stop() {\n if (!running) return;\n running = false;\n engine.stopKey(key);\n for (const v of voices) v.release();\n voices.clear();\n },\n playing: () => running,\n tempo: () => bpm,\n setTempo(next) {\n checkTempo(next);\n bpm = next;\n if (!running || lastAt === null) return;\n engine.stopKey(key);\n nextAt = Math.max(lastAt + stepMs(), engine.now());\n book();\n },\n setEvents,\n };\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@weasel-js/audio",
3
- "version": "1.9.2",
3
+ "version": "1.9.4",
4
4
  "description": "Web Audio engine for 2D scenes: voices, buses, lookahead scheduling, spatialization and analysis. No weasel dependencies.",
5
5
  "license": "MIT",
6
6
  "type": "module",