@weasel-js/audio 1.6.1 → 1.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/analyser.ts","../src/param.ts","../src/buses.ts","../src/scheduler.ts","../src/soundCache.ts","../src/spatialize.ts","../src/tickTimer.ts","../src/voicePool.ts","../src/createAudioEngine.ts"],"names":["slot"],"mappings":"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","file":"index.js","sourcesContent":["export interface AnalyserTapOptions {\n /** Power of two, 32..32768. Default 2048. */\n fftSize?: number;\n}\n\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\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","/**\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 { writeParam } from './param';\n\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}\n\nexport interface BusGraph {\n master: GainNode;\n node(name: string): GainNode;\n bus(name: string): BusHandle;\n names(): string[];\n}\n\ninterface BusState { node: GainNode; gain: number; muted: boolean; soloed: boolean }\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(ctx: AudioContext, names: string[]): 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 node = ctx.createGain();\n node.connect(master);\n states.set(name, { node, 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 node: (name) => get(name).node,\n names: () => [...states.keys()],\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 };\n },\n };\n}\n","export 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\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\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\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","export interface Vec2 { x: number; y: number }\n\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\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","export type StealPolicy = 'oldest' | 'quietest';\n\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\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\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\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 { 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 type { AudioEngineOptions, PlayOptions, VoiceHandle } from './types';\nimport { createVoicePool, type VoicePool } from './voicePool';\n\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 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\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: AudioBufferSourceNode | null;\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\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 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 graph = createBusGraph(ctx, busNames);\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 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: tickTimer?.setTimer ?? opts.setTimer ?? ((cb, ms) => setTimeout(cb, ms)),\n clearTimer: tickTimer?.clearTimer\n ?? opts.clearTimer\n ?? ((h) => clearTimeout(h as ReturnType<typeof setTimeout>)),\n lookahead: opts.lookahead,\n interval: opts.tickInterval,\n });\n scheduler.start();\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 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: () => {}, setGain: () => {}, setRate: () => {}, setDetune: () => {},\n setPan: () => {}, setPosition: () => {}, isPlaying: () => false,\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 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 = playOpts.bus ?? busNames[0];\n const slots = slotsFor(busName);\n const bookedAt = now();\n const when = playOpts.when ?? bookedAt;\n const baseGain = playOpts.gain ?? 1;\n\n const spatial = playOpts.position\n ? spatialize(playOpts.position, listener, spatialOpts)\n : { gain: 1, pan: playOpts.pan ?? 0 };\n\n const voice: LiveVoice = {\n id, slots, slot: null, token: 0, key: playOpts.cancelKey,\n source: null,\n chain: takeChain(graph.node(busName), baseGain * spatial.gain, spatial.pan),\n baseGain, spatialGain: spatial.gain,\n rate: playOpts.rate ?? 1, detune: playOpts.detune ?? 0,\n position: playOpts.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 const buffer = sounds.buffer(sound);\n if (!buffer) {\n warnUnknownSound(sound.id);\n teardown(voice);\n return;\n }\n\n // The slot is taken here, not at play() 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 // 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 = buffer;\n source.loop = playOpts.loop ?? false;\n source.playbackRate.value = voice.rate;\n source.detune.value = voice.detune;\n // Still live past the check above, so the voice still holds its chain.\n source.connect(voice.chain!.panner);\n source.onended = () => { teardown(voice); playOpts.onDone?.(); };\n voice.source = source;\n source.start(scheduledWhen / 1000);\n }, playOpts.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 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 if (voice.source) voice.source.playbackRate.value = value;\n },\n setDetune(cents) {\n voice.detune = cents;\n if (voice.source) voice.source.detune.value = cents;\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 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.master.disconnect();\n if (ownsContext) void ctx.close().catch(() => undefined);\n },\n };\n\n return engine;\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/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 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, Math.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"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@weasel-js/audio",
3
- "version": "1.6.1",
3
+ "version": "1.7.1",
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",