@libraz/libsonare 1.4.0 → 1.4.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.
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/codes.ts","../src/errors.ts","../src/module_state.ts","../src/mixer.ts","../src/realtime_voice_changer.ts","../src/realtime_engine.ts","../src/index.ts","../src/worklet/protocol.ts","../src/worklet/guards.ts","../src/worklet/messages.ts","../src/worklet.ts"],"sourcesContent":["import type { AutomationCurve, MeterTap, PanLaw, PanMode, SendTiming } from './public_types';\n\nexport function automationCurveCode(curve: AutomationCurve): number {\n switch (curve) {\n case 'linear':\n return 0;\n case 'exponential':\n return 1;\n case 'hold':\n return 2;\n case 's-curve':\n return 3;\n default:\n throw new Error(`Invalid automation curve: ${curve}`);\n }\n}\n\nexport function panLawCode(panLaw: PanLaw | number): number {\n if (typeof panLaw === 'number') {\n return panLaw;\n }\n switch (panLaw) {\n case 'const4.5dB':\n return 1;\n case 'const6dB':\n return 2;\n case 'linear0dB':\n return 3;\n default:\n return 0;\n }\n}\n\nexport function panModeCode(panMode: PanMode | number): number {\n if (typeof panMode === 'number') {\n return panMode;\n }\n switch (panMode) {\n case 'stereoPan':\n case 'stereo-pan':\n return 1;\n case 'dualPan':\n case 'dual-pan':\n return 2;\n default:\n return 0;\n }\n}\n\nexport function meterTapCode(tap: MeterTap | number): number {\n return tap === 'preFader' || tap === 0 ? 0 : 1;\n}\n\nexport function sendTimingCode(timing: SendTiming | number): number {\n // Mirrors SonareSendTiming: post-fader is 0 (so an omitted/zeroed value is\n // post-fader), pre-fader is 1. A raw number is passed through as the C ABI int.\n if (typeof timing === 'number') {\n return timing;\n }\n return timing === 'preFader' ? 1 : 0;\n}\n","/**\n * Numeric error codes carried by a {@link SonareError}. Mirrors the C ABI\n * `SonareError` enum (and the Node / Python surfaces), so the same failure\n * reports the same numeric code on every binding.\n */\nexport enum ErrorCode {\n Ok = 0,\n FileNotFound = 1,\n InvalidFormat = 2,\n DecodeFailed = 3,\n InvalidParameter = 4,\n OutOfMemory = 5,\n NotSupported = 6,\n InvalidState = 7,\n Unknown = 99,\n}\n\n/**\n * Error thrown by libsonare on a native (C++) failure. Carries a numeric\n * {@link ErrorCode} `code` plus its canonical `codeName`, so callers can branch\n * on the cause instead of matching message text.\n */\nexport class SonareError extends Error {\n /** Numeric error code, equal to an {@link ErrorCode} value. */\n readonly code: number;\n /** Canonical name of `code`, e.g. `'InvalidParameter'`. */\n readonly codeName: string;\n\n constructor(code: number, codeName: string, message: string) {\n super(message);\n this.name = 'SonareError';\n this.code = code;\n this.codeName = codeName;\n }\n}\n\n/** Type guard: whether a caught value is a libsonare {@link SonareError}. */\nexport function isSonareError(value: unknown): value is SonareError {\n return (\n value instanceof Error &&\n (value as { name?: unknown }).name === 'SonareError' &&\n typeof (value as { code?: unknown }).code === 'number'\n );\n}\n","import { ErrorCode, SonareError } from './errors';\nimport type { SonareModule } from './sonare.js';\n\nlet wrappedModule: SonareModule | null = null;\n\n/**\n * Shape of the structured info the native `sonareExceptionInfo(ptr)` returns.\n */\ninterface NativeExceptionInfo {\n code: number;\n codeName: string;\n message: string;\n}\n\n/**\n * Recover the native exception-object pointer from a value thrown across the\n * WASM boundary. emscripten surfaces a C++ throw in two shapes depending on the\n * toolchain/exception mode:\n * - a raw pointer number (older / classic surfacing), or\n * - a `CppException` object exposing the pointer as `excPtr` (emscripten with\n * `-fexceptions`).\n * Returns null when the thrown value is neither (a genuine JS error), so the\n * caller rethrows it unchanged.\n */\nfunction nativeExceptionPtr(error: unknown): number | null {\n if (typeof error === 'number') {\n return error;\n }\n if (error !== null && typeof error === 'object') {\n const ptr = (error as { excPtr?: unknown }).excPtr;\n if (typeof ptr === 'number') {\n return ptr;\n }\n }\n return null;\n}\n\n/**\n * Turn a thrown native exception pointer into a {@link SonareError}. The bound\n * `sonareExceptionInfo` decodes the pointer back into { code, codeName,\n * message }.\n */\nfunction makeSonareError(raw: SonareModule, thrown: number): SonareError {\n let code: number = ErrorCode.Unknown;\n let codeName = 'Unknown';\n let message = `libsonare native exception (${thrown})`;\n try {\n const info = (\n raw as unknown as { sonareExceptionInfo?: (ptr: number) => NativeExceptionInfo }\n ).sonareExceptionInfo?.(thrown);\n if (info) {\n code = info.code ?? code;\n codeName = info.codeName ?? codeName;\n message = info.message || message;\n }\n } catch {\n // Fall back to the generic message if decoding fails.\n }\n return new SonareError(code, codeName, message);\n}\n\n/**\n * Wrap the embind module so a native C++ exception (which surfaces as a raw\n * pointer number or a `CppException` carrying one) is rethrown as a\n * {@link SonareError}. Only function-valued\n * members are wrapped, and the wrapper is cached per member so repeated access\n * stays cheap; non-function members (typed-array heap views, etc.) pass through\n * unchanged. The dedicated realtime `sonare-rt` module is separate and is not\n * affected by this wrapper.\n */\nfunction wrapModuleErrors(raw: SonareModule): SonareModule {\n const cache = new Map<PropertyKey, unknown>();\n const objectCache = new WeakMap<object, unknown>();\n const convert = (error: unknown): never => {\n const ptr = nativeExceptionPtr(error);\n if (ptr !== null) {\n throw makeSonareError(raw, ptr);\n }\n throw error;\n };\n\n const wrapNativeObject = (value: unknown): unknown => {\n if (value === null || typeof value !== 'object') {\n return value;\n }\n if (ArrayBuffer.isView(value) || value instanceof ArrayBuffer || value instanceof Promise) {\n return value;\n }\n const objectValue = value as object;\n const cached = objectCache.get(objectValue);\n if (cached) {\n return cached;\n }\n const methodCache = new Map<PropertyKey, unknown>();\n const wrapped = new Proxy(objectValue, {\n get(target, prop, receiver) {\n const member = Reflect.get(target, prop, receiver);\n if (typeof member !== 'function') {\n return member;\n }\n const cachedMethod = methodCache.get(prop);\n if (cachedMethod) {\n return cachedMethod;\n }\n const method = member as (...a: unknown[]) => unknown;\n const wrappedMethod = (...args: unknown[]) => {\n try {\n return wrapNativeObject(Reflect.apply(method, target, args));\n } catch (error) {\n return convert(error);\n }\n };\n methodCache.set(prop, wrappedMethod);\n return wrappedMethod;\n },\n });\n objectCache.set(objectValue, wrapped);\n return wrapped;\n };\n\n const wrapFunction = (value: (...a: unknown[]) => unknown): unknown => {\n const fnCache = new Map<PropertyKey, unknown>();\n return new Proxy(value, {\n get(target, prop, receiver) {\n const member = Reflect.get(target, prop, receiver);\n if (typeof member !== 'function') {\n return member;\n }\n const cachedMember = fnCache.get(prop);\n if (cachedMember) {\n return cachedMember;\n }\n const fn = member as (...a: unknown[]) => unknown;\n const wrappedMember = (...args: unknown[]) => {\n try {\n return wrapNativeObject(Reflect.apply(fn, target, args));\n } catch (error) {\n return convert(error);\n }\n };\n fnCache.set(prop, wrappedMember);\n return wrappedMember;\n },\n apply(t, thisArg, args) {\n try {\n return wrapNativeObject(Reflect.apply(t, thisArg, args as unknown[]));\n } catch (error) {\n return convert(error);\n }\n },\n construct(t, args, newTarget) {\n try {\n return wrapNativeObject(Reflect.construct(t, args as unknown[], newTarget));\n } catch (error) {\n return convert(error) as object;\n }\n },\n });\n };\n\n return new Proxy(raw, {\n get(target, prop, receiver) {\n const value = Reflect.get(target, prop, receiver);\n if (typeof value !== 'function') {\n return value;\n }\n const cached = cache.get(prop);\n if (cached) {\n return cached;\n }\n // Wrap as a Proxy (not a plain function) so embind class constructors\n // invoked via `new module.Foo(...)` keep their `[[Construct]]` behaviour\n // and prototype while still converting thrown native pointers.\n const wrapped = wrapFunction(value as (...a: unknown[]) => unknown);\n cache.set(prop, wrapped);\n return wrapped;\n },\n }) as SonareModule;\n}\n\nexport function setSonareModule(module: SonareModule): void {\n wrappedModule = wrapModuleErrors(module);\n}\n\nexport function getSonareModule(): SonareModule {\n if (!wrappedModule) {\n throw new Error('Module not initialized. Call init() first.');\n }\n return wrappedModule;\n}\n","import {\n automationCurveCode,\n meterTapCode,\n panLawCode,\n panModeCode,\n sendTimingCode,\n} from './codes';\nimport { getSonareModule } from './module_state';\nimport type {\n AutomationCurve,\n GoniometerPoint,\n MeterTap,\n MixerProcessResult,\n MixMeterSnapshot,\n PanLaw,\n PanMode,\n SendTiming,\n SurroundPan,\n} from './public_types';\n\nexport interface MixerRealtimeBuffer {\n leftInputs: Float32Array[];\n rightInputs: Float32Array[];\n outLeft: Float32Array;\n outRight: Float32Array;\n process: (numSamples?: number) => void;\n}\n\n// ============================================================================\n// Mixer Class (scene-based persistent mixer)\n// ============================================================================\n\n/**\n * Persistent, scene-based stereo mixer.\n *\n * Build one from a scene JSON string (e.g. {@link mixingScenePresetJson} or a\n * hand-authored scene), then feed per-strip stereo blocks through\n * {@link processStereo} to get the routed stereo master. Strips, sends, buses,\n * and inserts are described entirely by the scene; the routing graph is\n * compiled lazily on the first {@link processStereo} call (or eagerly via\n * {@link compile}).\n *\n * Call {@link delete} (or use a `try/finally`) to release the underlying WASM\n * object — the embind handle is not garbage-collected automatically.\n *\n * @example\n * ```typescript\n * const mixer = Mixer.fromSceneJson(mixingScenePresetJson('basicStereo'), 48000, 512);\n * try {\n * const out = mixer.processStereo([stripL], [stripR]);\n * } finally {\n * mixer.delete();\n * }\n * ```\n */\nexport class Mixer {\n private mixer: import('./sonare.js').WasmMixer;\n\n private constructor(mixer: import('./sonare.js').WasmMixer) {\n this.mixer = mixer;\n }\n\n /**\n * Build a mixer from a scene JSON string.\n *\n * @param json - Scene JSON (strips, buses, sends, connections, inserts)\n * @param sampleRate - Sample rate in Hz (default: 48000)\n * @param blockSize - Maximum block size per {@link processStereo} call (default: 512)\n */\n static fromSceneJson(json: string, sampleRate = 48000, blockSize = 512): Mixer {\n const module = getSonareModule();\n return new Mixer(module.createMixerFromSceneJson(json, sampleRate, blockSize));\n }\n\n /** Rebuild and compile the routing graph from the current scene topology. */\n compile(): void {\n this.mixer.compile();\n }\n\n /**\n * Non-fatal warnings captured when this mixer was built from scene JSON: one\n * entry per channel-strip insert that was handed param keys it does not read\n * (a likely typo, or a key meant for a different processor). The scene still\n * loaded; these keys simply took no effect. Empty when every key was consumed.\n * Use {@link masteringInsertParamNames} to discover the keys an insert accepts.\n */\n sceneWarnings(): string[] {\n return this.mixer.sceneWarnings();\n }\n\n /**\n * Mix one block of per-strip stereo audio into the stereo master.\n *\n * @param leftChannels - `leftChannels[i]` is the left channel of strip `i`\n * @param rightChannels - `rightChannels[i]` is the right channel of strip `i`\n * @returns Mixed stereo master (`left`, `right`, `sampleRate`)\n */\n processStereo(leftChannels: Float32Array[], rightChannels: Float32Array[]): MixerProcessResult {\n if (leftChannels.length !== rightChannels.length) {\n throw new Error('leftChannels and rightChannels must have the same length.');\n }\n return this.mixer.processStereo(leftChannels, rightChannels);\n }\n\n /**\n * Mix one block into caller-owned output arrays.\n *\n * This avoids allocating the result object and result `Float32Array`s. It is\n * intended for realtime bridges such as AudioWorklet; the input channel count\n * must match the scene strip count and all arrays must have the same length.\n */\n processStereoInto(\n leftChannels: Float32Array[],\n rightChannels: Float32Array[],\n outLeft: Float32Array,\n outRight: Float32Array,\n ): void {\n if (leftChannels.length !== rightChannels.length) {\n throw new Error('leftChannels and rightChannels must have the same length.');\n }\n if (outLeft.length !== outRight.length) {\n throw new Error('outLeft and outRight must have the same length.');\n }\n this.mixer.processStereoInto(leftChannels, rightChannels, outLeft, outRight);\n }\n\n /**\n * Create reusable WASM-heap input/output views for realtime-style processing.\n *\n * Fill `leftInputs[i]` / `rightInputs[i]`, call `process()`, then read\n * `outLeft` / `outRight`. The views are owned by this mixer and become invalid\n * after {@link delete}.\n */\n createRealtimeBuffer(): MixerRealtimeBuffer {\n const stripCount = this.stripCount();\n let leftInputs: Float32Array[] = [];\n let rightInputs: Float32Array[] = [];\n let outLeft = this.mixer.outputLeftView();\n let outRight = this.mixer.outputRightView();\n const acquire = (): void => {\n leftInputs = [];\n rightInputs = [];\n for (let index = 0; index < stripCount; index++) {\n leftInputs.push(this.mixer.inputLeftView(index));\n rightInputs.push(this.mixer.inputRightView(index));\n }\n outLeft = this.mixer.outputLeftView();\n outRight = this.mixer.outputRightView();\n };\n acquire();\n // The cached heap views can detach if WASM linear memory grows (the embind\n // module is built ALLOW_MEMORY_GROWTH). Re-acquire them if detached\n // (byteLength === 0) before use, mirroring the worklet RT path.\n const reacquireIfDetached = (): void => {\n if (outLeft.byteLength === 0 || (leftInputs[0]?.byteLength ?? 1) === 0) {\n acquire();\n }\n };\n return {\n get leftInputs(): Float32Array[] {\n reacquireIfDetached();\n return leftInputs;\n },\n get rightInputs(): Float32Array[] {\n reacquireIfDetached();\n return rightInputs;\n },\n get outLeft(): Float32Array {\n reacquireIfDetached();\n return outLeft;\n },\n get outRight(): Float32Array {\n reacquireIfDetached();\n return outRight;\n },\n process: (numSamples = outLeft.length) => {\n reacquireIfDetached();\n this.mixer.processPreparedStereo(numSamples);\n },\n };\n }\n\n /** Number of strips in the mixer (e.g. strips loaded from the scene). */\n stripCount(): number {\n return this.mixer.stripCount();\n }\n\n /**\n * Schedule sample-accurate insert-parameter automation on a strip's insert.\n *\n * @param stripIndex - Strip index in `[0, stripCount())`\n * @param insertIndex - Index into the strip's combined insert sequence\n * (`[pre-inserts... post-inserts...]`)\n * @param paramId - Processor-specific parameter id\n * @param samplePos - Absolute samples from the start of processing (the mixer\n * advances an internal position from 0 on the first {@link processStereo}\n * call; recompiling resets it to 0)\n * @param value - Target parameter value\n * @param curve - Interpolation curve (default: `'linear'`)\n * @throws If the strip index is out of range or the schedule call fails\n * (unknown curve, out-of-range insert index, or full event lane)\n */\n scheduleInsertAutomation(\n stripIndex: number,\n insertIndex: number,\n paramId: number,\n samplePos: number,\n value: number,\n curve: AutomationCurve = 'linear',\n ): void {\n this.mixer.scheduleInsertAutomation(\n stripIndex,\n insertIndex,\n paramId,\n samplePos,\n value,\n automationCurveCode(curve),\n );\n }\n\n /**\n * Resolve a strip's index in `[0, stripCount())` from its scene id, or `null`\n * when no strip with that id exists (matches the Node binding's `number | null`).\n */\n stripById(id: string): number | null {\n const index = this.mixer.stripById(id);\n return index < 0 ? null : index;\n }\n\n /**\n * Add a bus to the mixer topology. `role` is one of `'master'`, `'aux'`, or\n * `'submix'` (defaults to `'aux'`). Marks the routing graph dirty; call\n * {@link compile} (or {@link processStereo}) to rebuild.\n */\n addBus(id: string, role = 'aux'): void {\n this.mixer.addBus(id, role);\n }\n\n /** Remove a bus by id. Marks the routing graph dirty. */\n removeBus(id: string): void {\n this.mixer.removeBus(id);\n }\n\n /** Number of buses in the mixer topology. */\n busCount(): number {\n return this.mixer.busCount();\n }\n\n /**\n * Add a VCA group with the given gain offset (dB). `members` is a list of\n * strip ids governed by the group (may be empty).\n */\n addVcaGroup(id: string, gainDb = 0.0, members: string[] = []): void {\n this.mixer.addVcaGroup(id, gainDb, members);\n }\n\n /** Set an existing VCA group's gain in dB. */\n setVcaGroupGainDb(id: string, gainDb: number): void {\n this.mixer.setVcaGroupGainDb(id, gainDb);\n }\n\n /** Remove a VCA group by id. */\n removeVcaGroup(id: string): void {\n this.mixer.removeVcaGroup(id);\n }\n\n /** Number of VCA groups in the mixer topology. */\n vcaGroupCount(): number {\n return this.mixer.vcaGroupCount();\n }\n\n /** Set the strip's input trim in dB. */\n setInputTrimDb(stripIndex: number, db: number): void {\n this.mixer.setInputTrimDb(stripIndex, db);\n }\n\n /** Set the strip's fader level in dB. */\n setFaderDb(stripIndex: number, db: number): void {\n this.mixer.setFaderDb(stripIndex, db);\n }\n\n /**\n * Set the strip's pan position.\n *\n * @param stripIndex - Strip index in `[0, stripCount())`\n * @param pan - Pan position in `[-1, 1]`\n * @param panMode - Optional pan mode. When omitted the strip's current pan\n * mode is kept (passes `SONARE_PAN_MODE_KEEP`), so a plain pan nudge does\n * not reset a scene-defined `'stereoPan'` / `'dualPan'` mode back to\n * balance. Pass `'balance'` (or `0`) explicitly to force balance mode.\n */\n setPan(stripIndex: number, pan: number, panMode?: PanMode | number): void {\n // SONARE_PAN_MODE_KEEP (-1) = keep the strip's current pan mode.\n const mode = panMode === undefined ? -1 : panModeCode(panMode);\n this.mixer.setPan(stripIndex, pan, mode);\n }\n\n /** Set the strip's stereo width. */\n setWidth(stripIndex: number, width: number): void {\n this.mixer.setWidth(stripIndex, width);\n }\n\n /** Set the strip's mute state. */\n setMuted(stripIndex: number, muted: boolean): void {\n this.mixer.setMuted(stripIndex, muted);\n }\n\n /**\n * Set a strip's solo state. Takes effect on the next process without a\n * graph recompile.\n */\n setSoloed(stripIndex: number, soloed: boolean): void {\n this.mixer.setSoloed(stripIndex, soloed);\n }\n\n /**\n * Mark a strip solo-safe so it is never implied-muted by another strip's\n * solo. Takes effect on the next process without a graph recompile.\n */\n setSoloSafe(stripIndex: number, soloSafe: boolean): void {\n this.mixer.setSoloSafe(stripIndex, soloSafe);\n }\n\n /** Invert the polarity of the left and/or right channel of a strip. */\n setPolarityInvert(stripIndex: number, invertLeft: boolean, invertRight: boolean): void {\n this.mixer.setPolarityInvert(stripIndex, invertLeft, invertRight);\n }\n\n /** Set the strip's pan law. */\n setPanLaw(stripIndex: number, panLaw: PanLaw | number): void {\n this.mixer.setPanLaw(stripIndex, panLawCode(panLaw));\n }\n\n /**\n * Set a per-strip channel delay in samples. This changes the strip's reported\n * latency; recompile to re-run latency compensation.\n */\n setChannelDelaySamples(stripIndex: number, delaySamples: number): void {\n this.mixer.setChannelDelaySamples(stripIndex, delaySamples);\n }\n\n /** Set the strip's live VCA gain offset in dB (not persisted to the scene). */\n setVcaOffsetDb(stripIndex: number, offsetDb: number): void {\n this.mixer.setVcaOffsetDb(stripIndex, offsetDb);\n }\n\n /** Set independent left/right pan positions (dual-pan mode). */\n setDualPan(stripIndex: number, leftPan: number, rightPan: number): void {\n this.mixer.setDualPan(stripIndex, leftPan, rightPan);\n }\n\n /**\n * Set the strip's surround pan position, used when it feeds a >2-channel bus.\n * Stored on the scene; inert until the surround DSP path applies it.\n */\n setSurroundPan(stripIndex: number, pan: SurroundPan): void {\n this.mixer.setSurroundPan(stripIndex, pan);\n }\n\n /**\n * Add a send to a strip after construction.\n *\n * @param stripIndex - Strip index in `[0, stripCount())`\n * @param id - Send id\n * @param destinationBusId - Destination bus id\n * @param sendDb - Initial send level in dB\n * @param timing - `'preFader'` or `'postFader'` (default: `'postFader'`)\n * @returns The new send's index\n */\n addSend(\n stripIndex: number,\n id: string,\n destinationBusId: string,\n sendDb = 0.0,\n timing: SendTiming | number = 'postFader',\n ): number {\n return this.mixer.addSend(stripIndex, id, destinationBusId, sendDb, sendTimingCode(timing));\n }\n\n /** Set the send level (in dB) for an existing send by index. */\n setSendDb(stripIndex: number, sendIndex: number, sendDb: number): void {\n this.mixer.setSendDb(stripIndex, sendIndex, sendDb);\n }\n\n /**\n * Remove an existing send from a strip by index.\n *\n * Sends are addressed in add order. After removal, sends with a higher index\n * than `sendIndex` shift down by one. Recompile (or process) before reading\n * results so the routing graph rebuilds.\n *\n * @param stripIndex - Strip index in `[0, stripCount())`\n * @param sendIndex - Send index in add order\n */\n removeSend(stripIndex: number, sendIndex: number): void {\n this.mixer.removeSend(stripIndex, sendIndex);\n }\n\n /**\n * Read a strip's meter snapshot at the given tap point.\n *\n * @param stripIndex - Strip index in `[0, stripCount())`\n * @param tap - `'preFader'` or `'postFader'` (default: `'postFader'`)\n */\n meterTap(stripIndex: number, tap: MeterTap = 'postFader'): MixMeterSnapshot {\n return this.mixer.meterTap(stripIndex, meterTapCode(tap));\n }\n\n /**\n * Read a strip's meter snapshot.\n *\n * With no `tap` argument this reads the strip's own (post-fader) meter,\n * matching the Node/Python tap-less `stripMeter` contract. Pass an optional\n * `tap` (`'preFader'` / `'postFader'`) to read the tap-selectable snapshot\n * instead — the same backing call as {@link meterTap}.\n *\n * @param stripIndex - Strip index in `[0, stripCount())`\n * @param tap - Optional tap point (`'preFader'` / `'postFader'`); when omitted\n * the tap-less post-fader strip meter is read.\n */\n stripMeter(stripIndex: number, tap?: MeterTap | number): MixMeterSnapshot {\n if (tap === undefined) {\n return this.mixer.stripMeter(stripIndex);\n }\n return this.mixer.meterTap(stripIndex, meterTapCode(tap));\n }\n\n /**\n * Schedule sample-accurate fader automation on a strip.\n *\n * @param stripIndex - Strip index in `[0, stripCount())`\n * @param samplePos - Absolute samples from the start of processing\n * @param faderDb - Target fader level in dB\n * @param curve - Interpolation curve (default: `'linear'`)\n */\n scheduleFaderAutomation(\n stripIndex: number,\n samplePos: number,\n faderDb: number,\n curve: AutomationCurve = 'linear',\n ): void {\n this.mixer.scheduleFaderAutomation(stripIndex, samplePos, faderDb, automationCurveCode(curve));\n }\n\n /**\n * Schedule sample-accurate pan automation on a strip.\n *\n * @param stripIndex - Strip index in `[0, stripCount())`\n * @param samplePos - Absolute samples from the start of processing\n * @param pan - Target pan position\n * @param curve - Interpolation curve (default: `'linear'`)\n */\n schedulePanAutomation(\n stripIndex: number,\n samplePos: number,\n pan: number,\n curve: AutomationCurve = 'linear',\n ): void {\n this.mixer.schedulePanAutomation(stripIndex, samplePos, pan, automationCurveCode(curve));\n }\n\n /**\n * Schedule sample-accurate width automation on a strip.\n *\n * @param stripIndex - Strip index in `[0, stripCount())`\n * @param samplePos - Absolute samples from the start of processing\n * @param width - Target stereo width\n * @param curve - Interpolation curve (default: `'linear'`)\n */\n scheduleWidthAutomation(\n stripIndex: number,\n samplePos: number,\n width: number,\n curve: AutomationCurve = 'linear',\n ): void {\n this.mixer.scheduleWidthAutomation(stripIndex, samplePos, width, automationCurveCode(curve));\n }\n\n /**\n * Schedule sample-accurate send-level automation on a strip's send.\n *\n * @param stripIndex - Strip index in `[0, stripCount())`\n * @param sendIndex - Send index in the strip's add order\n * @param samplePos - Absolute samples from the start of processing\n * @param db - Target send level in dB\n * @param curve - Interpolation curve (default: `'linear'`)\n */\n scheduleSendAutomation(\n stripIndex: number,\n sendIndex: number,\n samplePos: number,\n db: number,\n curve: AutomationCurve = 'linear',\n ): void {\n this.mixer.scheduleSendAutomation(\n stripIndex,\n sendIndex,\n samplePos,\n db,\n automationCurveCode(curve),\n );\n }\n\n /**\n * Read up to `maxPoints` of a strip's most recent goniometer samples\n * (oldest to newest).\n */\n readGoniometerLatest(stripIndex: number, maxPoints: number): GoniometerPoint[] {\n return this.mixer.readGoniometerLatest(stripIndex, maxPoints);\n }\n\n /** Serialize the current scene (strips, buses, sends, connections) to JSON. */\n toSceneJson(): string {\n return this.mixer.toSceneJson();\n }\n\n /**\n * Maximum processor tail length (samples) in the compiled mixer graph. Lazily\n * compiles the routing graph if the topology is dirty.\n */\n tailSamples(): number {\n return this.mixer.tailSamples();\n }\n\n /**\n * Drain delayed / tail audio by processing a zero-input block of `numSamples`\n * frames after the host stops feeding strip inputs. Returns the mixed stereo\n * master (`left`, `right`, `sampleRate`).\n */\n drainTailStereo(numSamples: number): MixerProcessResult {\n return this.mixer.drainTailStereo(numSamples);\n }\n\n /** Release the underlying WASM object. Safe to call only once. */\n delete(): void {\n this.mixer.delete();\n }\n\n /** Alias for {@link delete}, provided for cross-binding (Node) compatibility. */\n destroy(): void {\n this.delete();\n }\n}\n","import { getSonareModule } from './module_state';\nimport type { RealtimeVoiceChangerConfigInput, VoicePresetId } from './public_types';\n\n/**\n * Zero-copy realtime buffer pair for {@link RealtimeVoiceChanger} mono\n * processing. The `input` / `output` `Float32Array`s are typed-memory views\n * onto the WASM heap — write samples into `input`, call `process()`, then\n * read from `output`. The views are owned by the {@link RealtimeVoiceChanger}\n * and remain valid until `delete()` is called on it.\n */\nexport interface RealtimeVoiceChangerMonoBuffer {\n input: Float32Array;\n output: Float32Array;\n process: () => void;\n}\n\n/**\n * Zero-copy realtime buffer pair for {@link RealtimeVoiceChanger} interleaved\n * multi-channel processing. Layout is L0,R0,L1,R1,... for stereo. The views\n * are owned by the {@link RealtimeVoiceChanger}.\n */\nexport interface RealtimeVoiceChangerInterleavedBuffer {\n input: Float32Array;\n output: Float32Array;\n channels: number;\n process: () => void;\n}\n\n/**\n * Zero-copy realtime buffer for {@link RealtimeVoiceChanger} planar stereo\n * processing. Each entry in `channels` is a heap-backed `Float32Array` for one\n * channel (matching AudioWorklet's native layout). Process happens in place:\n * write samples into each channel view, call `process()`, then read back from\n * the same views.\n */\nexport interface RealtimeVoiceChangerPlanarBuffer {\n channels: Float32Array[];\n process: () => void;\n}\n\n// ============================================================================\n// RealtimeVoiceChanger Class\n// ============================================================================\n\nexport class RealtimeVoiceChanger {\n private changer: import('./sonare.js').WasmRealtimeVoiceChanger;\n\n constructor(config: RealtimeVoiceChangerConfigInput = 'neutral-monitor') {\n const module = getSonareModule();\n this.changer = module.createRealtimeVoiceChanger(config as Record<string, unknown> | string);\n }\n\n prepare(sampleRate: number, maxBlockSize = 128, channels = 1): void {\n this.changer.prepare(sampleRate, maxBlockSize, channels);\n }\n\n reset(): void {\n this.changer.reset();\n }\n\n setConfig(config: RealtimeVoiceChangerConfigInput): void {\n this.changer.setConfig(config as Record<string, unknown> | string);\n }\n\n configJson(): string {\n return this.changer.configJson();\n }\n\n latencySamples(): number {\n return this.changer.latencySamples();\n }\n\n processMono(samples: Float32Array): Float32Array {\n return this.changer.processMono(samples);\n }\n\n processMonoInto(samples: Float32Array, output: Float32Array): void {\n this.changer.processMonoInto(samples, output);\n }\n\n processInterleaved(samples: Float32Array, channels: number): Float32Array {\n return this.changer.processInterleaved(samples, channels);\n }\n\n processInterleavedInto(samples: Float32Array, channels: number, output: Float32Array): void {\n this.changer.processInterleavedInto(samples, channels, output);\n }\n\n /**\n * Acquire a typed-memory view onto the WASM heap for mono input.\n *\n * Write your input samples into the returned `Float32Array` directly (e.g.\n * via `input.set(source)`); no copy crosses the JS↔C++ bridge until\n * {@link processPreparedMono} is called. The view is owned by this\n * RealtimeVoiceChanger and becomes invalid after {@link delete}; it may\n * also be invalidated if you later call this method with a larger\n * `numSamples` value (the underlying buffer may be reallocated).\n */\n getMonoInputBuffer(numSamples: number): Float32Array {\n return this.changer.getMonoInputBuffer(numSamples);\n }\n\n /** Mono output view counterpart to {@link getMonoInputBuffer}. */\n getMonoOutputBuffer(numSamples: number): Float32Array {\n return this.changer.getMonoOutputBuffer(numSamples);\n }\n\n /**\n * Process the previously-acquired mono input buffer in place. The output\n * appears in the buffer returned by {@link getMonoOutputBuffer}. No JS↔C++\n * sample-level crossings happen on this call — it just hands control to\n * the underlying DSP on already-on-heap data.\n */\n processPreparedMono(numSamples: number): void {\n this.changer.processPreparedMono(numSamples);\n }\n\n /** Interleaved input view (layout L0,R0,L1,R1,...). */\n getInterleavedInputBuffer(numFrames: number, numChannels: number): Float32Array {\n return this.changer.getInterleavedInputBuffer(numFrames, numChannels);\n }\n\n /** Interleaved output view counterpart. */\n getInterleavedOutputBuffer(numFrames: number, numChannels: number): Float32Array {\n return this.changer.getInterleavedOutputBuffer(numFrames, numChannels);\n }\n\n /**\n * Process the previously-acquired interleaved buffer in place. Output\n * appears in the buffer returned by {@link getInterleavedOutputBuffer}.\n */\n processPreparedInterleaved(numFrames: number, numChannels: number): void {\n this.changer.processPreparedInterleaved(numFrames, numChannels);\n }\n\n /**\n * Planar-channel input/output view (one Float32Array per channel). Matches\n * AudioWorklet's native layout; processing happens in place.\n */\n getPlanarChannelBuffer(channel: number, numFrames: number): Float32Array {\n return this.changer.getPlanarChannelBuffer(channel, numFrames);\n }\n\n /**\n * Process the previously-acquired planar channel buffers in place. Each\n * channel must have been obtained from {@link getPlanarChannelBuffer}\n * with the same `numFrames`. Output replaces input in the same buffers.\n */\n processPreparedPlanar(numFrames: number): void {\n this.changer.processPreparedPlanar(numFrames);\n }\n\n /**\n * Convenience factory for the mono zero-copy path: returns the input/output\n * heap views plus a `process()` thunk wired to the same `numSamples`. The\n * views are reused across calls and become invalid after {@link delete}.\n */\n createRealtimeMonoBuffer(numSamples: number): RealtimeVoiceChangerMonoBuffer {\n let input = this.getMonoInputBuffer(numSamples);\n let output = this.getMonoOutputBuffer(numSamples);\n // The cached heap views can detach if WASM linear memory grows (the embind\n // module is built ALLOW_MEMORY_GROWTH). Re-acquire them if detached\n // (byteLength === 0) before use, mirroring the worklet RT path. In the\n // common no-growth case this is a cheap branch with no allocation.\n const reacquireIfDetached = (): void => {\n if (input.byteLength === 0 || output.byteLength === 0) {\n input = this.getMonoInputBuffer(numSamples);\n output = this.getMonoOutputBuffer(numSamples);\n }\n };\n return {\n get input(): Float32Array {\n reacquireIfDetached();\n return input;\n },\n get output(): Float32Array {\n reacquireIfDetached();\n return output;\n },\n process: () => {\n reacquireIfDetached();\n this.processPreparedMono(numSamples);\n },\n };\n }\n\n /** Same as {@link createRealtimeMonoBuffer} but for interleaved I/O. */\n createRealtimeInterleavedBuffer(\n numFrames: number,\n numChannels: number,\n ): RealtimeVoiceChangerInterleavedBuffer {\n let input = this.getInterleavedInputBuffer(numFrames, numChannels);\n let output = this.getInterleavedOutputBuffer(numFrames, numChannels);\n // Re-acquire detached views after WASM memory growth (see\n // createRealtimeMonoBuffer for rationale).\n const reacquireIfDetached = (): void => {\n if (input.byteLength === 0 || output.byteLength === 0) {\n input = this.getInterleavedInputBuffer(numFrames, numChannels);\n output = this.getInterleavedOutputBuffer(numFrames, numChannels);\n }\n };\n return {\n get input(): Float32Array {\n reacquireIfDetached();\n return input;\n },\n get output(): Float32Array {\n reacquireIfDetached();\n return output;\n },\n channels: numChannels,\n process: () => {\n reacquireIfDetached();\n this.processPreparedInterleaved(numFrames, numChannels);\n },\n };\n }\n\n /**\n * Convenience factory for the planar zero-copy path. Acquires one\n * heap-backed Float32Array per channel and returns a `process()` thunk\n * wired to the same `numFrames`. Buffers are reused across calls and\n * become invalid after {@link delete}.\n */\n createRealtimePlanarBuffer(\n numFrames: number,\n numChannels: number,\n ): RealtimeVoiceChangerPlanarBuffer {\n let channels: Float32Array[] = [];\n const acquire = (): void => {\n channels = [];\n for (let ch = 0; ch < numChannels; ch++) {\n channels.push(this.getPlanarChannelBuffer(ch, numFrames));\n }\n };\n acquire();\n // Re-acquire detached views after WASM memory growth (see\n // createRealtimeMonoBuffer for rationale).\n const reacquireIfDetached = (): void => {\n if ((channels[0]?.byteLength ?? 0) === 0) {\n acquire();\n }\n };\n return {\n get channels(): Float32Array[] {\n reacquireIfDetached();\n return channels;\n },\n process: () => {\n reacquireIfDetached();\n this.processPreparedPlanar(numFrames);\n },\n };\n }\n\n delete(): void {\n this.changer.delete();\n }\n}\n\nexport function realtimeVoiceChangerPresetNames(): VoicePresetId[] {\n return getSonareModule().realtimeVoiceChangerPresetNames() as VoicePresetId[];\n}\n\nexport function realtimeVoiceChangerPresetJson(name: VoicePresetId): string {\n return getSonareModule().realtimeVoiceChangerPresetJson(name);\n}\n\nexport function validateRealtimeVoiceChangerPresetJson(json: string): {\n ok: boolean;\n normalizedJson?: string;\n error?: string;\n} {\n return getSonareModule().validateRealtimeVoiceChangerPresetJson(json);\n}\n","import { panLawCode, panModeCode, sendTimingCode } from './codes';\nimport { ErrorCode, SonareError } from './errors';\nimport { getSonareModule } from './module_state';\nimport type { SynthPatch } from './project';\nimport type { EqBand, PanLaw, PanMode, SendTiming } from './public_types';\nimport type {\n WasmClipPageRequest,\n WasmEngineAutomationPoint,\n WasmEngineBounceOptions,\n WasmEngineBounceResult,\n WasmEngineCaptureStatus,\n WasmEngineClip,\n WasmEngineFreezeOptions,\n WasmEngineFreezeResult,\n WasmEngineGraphSpec,\n WasmEngineMarker,\n WasmEngineMeterTelemetry,\n WasmEngineMeterTelemetryWide,\n WasmEngineMetronomeConfig,\n WasmEngineParameterInfo,\n WasmEngineProcessWithMonitorResult,\n WasmEngineScopeTelemetry,\n WasmEngineTelemetry,\n WasmEngineTempoSegment,\n WasmEngineTimeSignatureSegment,\n WasmEngineTransportState,\n WasmRealtimeEngine,\n} from './sonare.js';\n\nexport type EngineClip = WasmEngineClip;\nexport type ClipPageRequest = WasmClipPageRequest;\nexport type EngineParameterInfo = WasmEngineParameterInfo;\nexport type EngineAutomationPoint = WasmEngineAutomationPoint;\nexport type EngineMarker = WasmEngineMarker;\nexport type EngineMetronomeConfig = WasmEngineMetronomeConfig;\nexport type EngineGraphSpec = WasmEngineGraphSpec;\nexport type EngineCaptureStatus = WasmEngineCaptureStatus;\nexport type EngineBounceOptions = WasmEngineBounceOptions;\nexport type EngineBounceResult = WasmEngineBounceResult;\nexport type EngineFreezeOptions = WasmEngineFreezeOptions;\nexport type EngineFreezeResult = WasmEngineFreezeResult;\nexport type EngineTelemetry = WasmEngineTelemetry;\nexport type EngineMeterTelemetry = WasmEngineMeterTelemetry;\nexport type EngineMeterTelemetryWide = WasmEngineMeterTelemetryWide;\nexport type EngineScopeTelemetry = WasmEngineScopeTelemetry;\nexport type EngineTransportState = WasmEngineTransportState;\nexport type EngineTempoSegment = WasmEngineTempoSegment;\nexport type EngineTimeSignatureSegment = WasmEngineTimeSignatureSegment;\n\nexport interface EngineTrackSend {\n busId: number;\n levelDb?: number;\n enabled?: boolean;\n /**\n * Pre/post-fader tap point. Defaults to post-fader when omitted, matching the\n * historical lane-send behavior and the scene-JSON default.\n */\n sendTiming?: SendTiming | number;\n}\n\nexport interface EngineTrackLane {\n trackId: number;\n sends?: EngineTrackSend[];\n /**\n * Bus the lane's post-fader output sums into instead of the master mix\n * (group/folder routing); 0 or absent keeps the lane on the master mix.\n */\n outputBusId?: number;\n /**\n * Input channel layout of the source feeding this lane (`SonareChannelLayout`:\n * 0 mono, 1 stereo, 2 5.1, 3 7.1). Absent defaults to stereo. Stored but inert\n * until the surround DSP path lands.\n */\n sourceChannelLayout?: number;\n}\n\nexport interface EngineBus {\n busId: number;\n gainDb?: number;\n /**\n * Channel layout of the bus (`SonareChannelLayout`: 0 mono, 1 stereo, 2 5.1,\n * 3 7.1). A surround layout makes this a surround group bus: lanes routed to\n * it are surround-panned and it sums into the master plane-by-plane. Defaults\n * to stereo.\n */\n channelLayout?: number;\n}\n\nexport interface EngineMidiEvent {\n renderFrame: number;\n word0?: number;\n word1?: number;\n word2?: number;\n word3?: number;\n wordCount?: number;\n group?: number;\n sysexHandle?: number;\n data0?: number;\n data1?: number;\n}\n\nexport interface EngineMidiClipSchedule {\n id?: number;\n trackId?: number;\n destinationId?: number;\n startSample?: number;\n startPpq?: number;\n lengthSamples?: number;\n loop?: boolean;\n loopLengthSamples?: number;\n events: EngineMidiEvent[];\n}\n\nexport const EXPECTED_ENGINE_ABI_VERSION = 3;\n\n/** Options for {@link RealtimeEngine.bindMidiCc}. All fields are optional. */\nexport interface MidiCcBindOptions {\n /** Lower end of the mapped parameter range. Default `0`. */\n minValue?: number;\n /** Upper end of the mapped parameter range. Default `1`. */\n maxValue?: number;\n}\n\nexport interface EngineCapabilities {\n engineAbiVersion: number;\n expectedEngineAbiVersion: number;\n abiCompatible: boolean;\n sharedArrayBuffer: boolean;\n atomics: boolean;\n audioWorklet: boolean;\n mode: 'sab' | 'postMessage';\n}\n\nexport function engineCapabilities(): EngineCapabilities {\n const abiVersion = getSonareModule().engineAbiVersion();\n const sharedArrayBuffer = typeof globalThis.SharedArrayBuffer === 'function';\n const atomics = typeof globalThis.Atomics === 'object';\n const audioWorklet =\n typeof AudioWorkletNode !== 'undefined' ||\n typeof (globalThis as typeof globalThis & { AudioWorkletProcessor?: unknown })\n .AudioWorkletProcessor !== 'undefined';\n return {\n engineAbiVersion: abiVersion,\n expectedEngineAbiVersion: EXPECTED_ENGINE_ABI_VERSION,\n abiCompatible: abiVersion === EXPECTED_ENGINE_ABI_VERSION,\n sharedArrayBuffer,\n atomics,\n audioWorklet,\n mode: sharedArrayBuffer && atomics ? 'sab' : 'postMessage',\n };\n}\n\nexport class RealtimeEngine {\n private native: WasmRealtimeEngine;\n\n constructor(\n sampleRate = 48000,\n maxBlockSize = 128,\n commandCapacity = 1024,\n telemetryCapacity = 1024,\n ) {\n const module = getSonareModule();\n const capabilities = engineCapabilities();\n if (!capabilities.abiCompatible) {\n throw new Error(\n `Engine ABI mismatch: wasm=${capabilities.engineAbiVersion}, expected=${capabilities.expectedEngineAbiVersion}`,\n );\n }\n this.native = new module.RealtimeEngine(\n sampleRate,\n maxBlockSize,\n commandCapacity,\n telemetryCapacity,\n );\n }\n\n prepare(\n sampleRate: number,\n maxBlockSize: number,\n commandCapacity = 1024,\n telemetryCapacity = 1024,\n ): void {\n this.native.prepare(sampleRate, maxBlockSize, commandCapacity, telemetryCapacity);\n }\n\n /** Queue a sample-accurate parameter change (engine kSetParam). */\n setParameter(paramId: number, value: number, renderFrame = -1): void {\n this.native.setParameter(paramId, value, renderFrame);\n }\n\n /** Queue a smoothed parameter change (engine kSetParamSmoothed). */\n setParameterSmoothed(paramId: number, value: number, renderFrame = -1): void {\n this.native.setParameterSmoothed(paramId, value, renderFrame);\n }\n\n setSoloMute(laneIndex: number, solo: boolean, mute: boolean, renderFrame = -1): void {\n this.native.setSoloMute(laneIndex, solo, mute, renderFrame);\n }\n\n setMidiClips(clips: readonly EngineMidiClipSchedule[]): void {\n this.native.setMidiClips(clips);\n }\n\n setBuiltinInstrument(\n config: { destinationId?: number } & Record<string, unknown> = {},\n destinationId = config.destinationId ?? 0,\n ): void {\n this.native.setBuiltinInstrument(destinationId, config);\n }\n\n /**\n * Bind the patch-driven NativeSynth to a realtime MIDI destination. `patch`\n * is a {@link SynthPatch} or a preset-name string (`'saw-lead'` /\n * `'va:saw-lead'`; see {@link synthPresetNames}), resolving exactly like\n * {@link Project.bounceWithSynthInstrument}. Live note/CC commands and\n * scheduled MIDI clips routed to that destination render through the synth.\n * Unknown preset names throw. An object patch's `destinationId` is a JS\n * binding convenience, not part of the NativeSynth patch itself.\n */\n setSynthInstrument(\n patch: SynthPatch | string = {},\n destinationId = (typeof patch === 'object' ? patch.destinationId : undefined) ?? 0,\n ): void {\n this.native.setSynthInstrument(destinationId, patch);\n }\n\n /**\n * Load (parse) SoundFont 2 bytes into the engine so SF2 instruments can be\n * bound with {@link setSf2Instrument}. The host fetches the `.sf2` and\n * passes the raw bytes; they are copied into linear memory for the call and\n * not referenced afterwards. Replaces any previously loaded SoundFont.\n */\n loadSoundFont(data: Uint8Array): void {\n this.native.loadSoundFont(data);\n }\n\n /**\n * Bind a GS-compatible SoundFont player to a realtime MIDI destination, fed\n * by the engine's loaded SoundFont ({@link loadSoundFont}). Live note/CC\n * commands and scheduled MIDI clips routed to that destination render\n * through the player (16 MIDI channels, channel 10 drums, GS NRPN part\n * edits, GS/GM SysEx resets). Without a loaded SoundFont — or for programs\n * the SoundFont does not cover — notes play through the built-in\n * synthesizer GM fallback bank (the data-free floor).\n */\n setSf2Instrument(\n config: { destinationId?: number; gain?: number; polyphony?: number } = {},\n destinationId = config.destinationId ?? 0,\n ): void {\n this.native.setSf2Instrument(destinationId, config);\n }\n\n clearMidiInstrument(destinationId = 0): void {\n this.native.clearMidiInstrument(destinationId);\n }\n\n midiInstrumentCount(): number {\n return this.native.midiInstrumentCount();\n }\n\n /**\n * Bind a live MIDI CC to an engine automation parameter. The MIDI event still\n * reaches the destination instrument; when bound, its 7-bit value is also\n * mapped into [minValue, maxValue] for `paramId`.\n */\n bindMidiCc(\n channel: number,\n controller: number,\n paramId: number,\n options: MidiCcBindOptions = {},\n ): void {\n this.native.bindMidiCc(\n channel,\n controller,\n paramId,\n options.minValue ?? 0,\n options.maxValue ?? 1,\n );\n }\n\n clearMidiCcBindings(): void {\n this.native.clearMidiCcBindings();\n }\n\n midiCcBindingCount(): number {\n return this.native.midiCcBindingCount();\n }\n\n /** Install/replace a live non-destructive MIDI-FX insert for one destination. */\n setMidiFx(destinationId: number, configJson: string): void {\n this.native.setMidiFx(destinationId, configJson);\n }\n\n clearMidiFx(destinationId = 0): void {\n this.native.clearMidiFx(destinationId);\n }\n\n /** Enable the engine-owned live MIDI input source for a destination. */\n setMidiInputSource(destinationId = 0): void {\n this.native.setMidiInputSource(destinationId);\n }\n\n clearMidiInputSource(): void {\n this.native.clearMidiInputSource();\n }\n\n midiInputPendingCount(): number {\n return this.native.midiInputPendingCount();\n }\n\n pushMidiInputNoteOn(\n group: number,\n channel: number,\n note: number,\n velocity: number,\n portTimeSamples = 0,\n ): void {\n this.native.pushMidiInputNoteOn(group, channel, note, velocity, portTimeSamples);\n }\n\n pushMidiInputNoteOff(\n group: number,\n channel: number,\n note: number,\n velocity = 0,\n portTimeSamples = 0,\n ): void {\n this.native.pushMidiInputNoteOff(group, channel, note, velocity, portTimeSamples);\n }\n\n pushMidiInputCc(\n group: number,\n channel: number,\n controller: number,\n value: number,\n portTimeSamples = 0,\n ): void {\n this.native.pushMidiInputCc(group, channel, controller, value, portTimeSamples);\n }\n\n pushMidiNoteOn(\n destinationId: number,\n group: number,\n channel: number,\n note: number,\n velocity: number,\n renderFrame = -1,\n ): void {\n this.native.pushMidiNoteOn(destinationId, group, channel, note, velocity, renderFrame);\n }\n\n pushMidiNoteOff(\n destinationId: number,\n group: number,\n channel: number,\n note: number,\n velocity = 0,\n renderFrame = -1,\n ): void {\n this.native.pushMidiNoteOff(destinationId, group, channel, note, velocity, renderFrame);\n }\n\n /**\n * Queue an immediate (live) MIDI control change to a MIDI destination\n * (engine kMidiCcImmediate). `group`/`channel` are 0..15; `controller`/`value`\n * are 7-bit (0..127). `renderFrame` is the frame to fire at, or -1 for\n * immediate. Mirrors the Node/Python/C-ABI `pushMidiCc`.\n */\n pushMidiCc(\n destinationId: number,\n group: number,\n channel: number,\n controller: number,\n value: number,\n renderFrame = -1,\n ): void {\n this.native.pushMidiCc(destinationId, group, channel, controller, value, renderFrame);\n }\n\n /**\n * Queue a MIDI panic (all-notes-off) releasing every sounding note at\n * `renderFrame` (-1 = immediate). Mirrors the C-ABI `pushMidiPanic`.\n */\n pushMidiPanic(renderFrame = -1): void {\n this.native.pushMidiPanic(renderFrame);\n }\n\n /**\n * Remove all registered parameters (and their automation lanes). Control-thread\n * only; not realtime-safe. Mirrors the C-ABI `clearParameters`.\n */\n clearParameters(): void {\n this.native.clearParameters();\n }\n\n /** Read back the current transport state snapshot. */\n getTransportState(): EngineTransportState {\n return this.native.getTransportState();\n }\n\n play(renderFrame = -1): void {\n this.native.play(renderFrame);\n }\n\n stop(renderFrame = -1): void {\n this.native.stop(renderFrame);\n }\n\n seekSample(timelineSample: number, renderFrame = -1): void {\n this.native.seekSample(timelineSample, renderFrame);\n }\n\n /**\n * Snaps every in-flight parameter ramp (engine-level smoothed params, mixer\n * lane fader/pan/gate, bus gains) to its target value. Offline renders call\n * this after a priming process() block so the first audible block renders at\n * settled values instead of ramping in from defaults.\n */\n settleParameters(): void {\n this.native.settleParameters();\n }\n\n seekPpq(ppq: number, renderFrame = -1): void {\n this.native.seekPpq(ppq, renderFrame);\n }\n\n setTempo(bpm: number): void {\n this.native.setTempo(bpm);\n }\n\n setTempoSegments(segments: readonly EngineTempoSegment[]): void {\n this.native.setTempoSegments([...segments]);\n }\n\n setTimeSignature(numerator: number, denominator: number): void {\n this.native.setTimeSignature(numerator, denominator);\n }\n\n setTimeSignatureSegments(segments: readonly EngineTimeSignatureSegment[]): void {\n this.native.setTimeSignatureSegments([...segments]);\n }\n\n sampleAtPpq(ppq: number): number {\n return Number(this.native.sampleAtPpq(ppq));\n }\n\n setLoop(startPpq: number, endPpq: number, enabled = true): void {\n this.native.setLoop(startPpq, endPpq, enabled);\n }\n\n addParameter(info: EngineParameterInfo): void {\n this.native.addParameter(info);\n }\n\n parameterCount(): number {\n return this.native.parameterCount();\n }\n\n parameterInfoByIndex(index: number): EngineParameterInfo {\n return this.native.parameterInfoByIndex(index);\n }\n\n parameterInfo(id: number): EngineParameterInfo {\n return this.native.parameterInfo(id);\n }\n\n setAutomationLane(paramId: number, points: EngineAutomationPoint[]): void {\n this.native.setAutomationLane(paramId, points);\n }\n\n automationLaneCount(): number {\n return this.native.automationLaneCount();\n }\n\n setMarkers(markers: EngineMarker[]): void {\n this.native.setMarkers(markers);\n }\n\n markerCount(): number {\n return this.native.markerCount();\n }\n\n markerByIndex(index: number): EngineMarker {\n return this.native.markerByIndex(index);\n }\n\n marker(id: number): EngineMarker {\n return this.native.marker(id);\n }\n\n seekMarker(markerId: number, renderFrame = -1): void {\n this.native.seekMarker(markerId, renderFrame);\n }\n\n setLoopFromMarkers(startMarkerId: number, endMarkerId: number): void {\n this.native.setLoopFromMarkers(startMarkerId, endMarkerId);\n }\n\n setMetronome(config: EngineMetronomeConfig): void {\n this.native.setMetronome(config);\n }\n\n metronome(): Required<EngineMetronomeConfig> {\n return this.native.metronome();\n }\n\n countInEndSample(startSample: number, bars: number): number {\n return Number(this.native.countInEndSample(startSample, bars));\n }\n\n setGraph(spec: EngineGraphSpec): void {\n this.native.setGraph(spec);\n }\n\n graphNodeCount(): number {\n return this.native.graphNodeCount();\n }\n\n graphConnectionCount(): number {\n return this.native.graphConnectionCount();\n }\n\n setClips(clips: EngineClip[]): void {\n this.native.setClips(\n clips.map((clip) => ({\n ...clip,\n pageProvider:\n typeof clip.pageProvider === 'object' && clip.pageProvider !== null\n ? clip.pageProvider.id\n : clip.pageProvider,\n })),\n );\n }\n\n clipCount(): number {\n return this.native.clipCount();\n }\n\n setTrackLanes(lanes: Array<number | EngineTrackLane>): void {\n this.native.setTrackLanes(\n lanes.map((lane) => {\n if (typeof lane === 'number') {\n return { trackId: lane };\n }\n if (!lane.sends) {\n return lane;\n }\n // Normalize each send's pre/post tap point to the integer the native\n // layer reads (defaults to post-fader when omitted).\n return {\n ...lane,\n sends: lane.sends.map((send) => ({\n ...send,\n // Post-fader (0) is the default for an omitted sendTiming.\n sendTiming: send.sendTiming === undefined ? 0 : sendTimingCode(send.sendTiming),\n })),\n };\n }),\n );\n }\n\n /**\n * Keys one insert of a lane strip from another lane's post-strip audio\n * (ducking/sidechainRouter inserts). sourceTrackId 0 removes the binding.\n */\n setLaneSidechain(trackId: number, insertIndex: number, sourceTrackId: number): void {\n this.native.setLaneSidechain(trackId, insertIndex, sourceTrackId);\n }\n\n setTrackBuses(buses: EngineBus[]): void {\n this.native.setTrackBuses(buses);\n }\n\n setBusStripJson(busId: number, sceneJson: string): void {\n try {\n JSON.parse(sceneJson);\n } catch (error) {\n const message = error instanceof Error ? error.message : 'invalid bus strip JSON';\n throw new SonareError(ErrorCode.InvalidFormat, 'InvalidFormat', message);\n }\n this.native.setBusStripJson(busId, sceneJson);\n }\n\n setTrackStripJson(trackId: number, sceneJson: string): void {\n try {\n JSON.parse(sceneJson);\n } catch (error) {\n const message = error instanceof Error ? error.message : 'invalid track strip JSON';\n throw new SonareError(ErrorCode.InvalidFormat, 'InvalidFormat', message);\n }\n this.native.setTrackStripJson(trackId, sceneJson);\n }\n\n setTrackStripEqBand(trackId: number, bandIndex: number, band: EqBand | string): void {\n this.native.setTrackStripEqBandJson(\n trackId,\n bandIndex,\n typeof band === 'string' ? band : JSON.stringify(band),\n );\n }\n\n setTrackStripEqBandJson(trackId: number, bandIndex: number, bandJson: string): void {\n this.native.setTrackStripEqBandJson(trackId, bandIndex, bandJson);\n }\n\n setTrackStripInsertBypassed(\n trackId: number,\n insertIndex: number,\n bypassed: boolean,\n resetOnBypass = false,\n ): void {\n this.native.setTrackStripInsertBypassed(trackId, insertIndex, bypassed, resetOnBypass);\n }\n\n setMasterStripJson(sceneJson: string): void {\n try {\n JSON.parse(sceneJson);\n } catch (error) {\n const message = error instanceof Error ? error.message : 'invalid master strip JSON';\n throw new SonareError(ErrorCode.InvalidFormat, 'InvalidFormat', message);\n }\n this.native.setMasterStripJson(sceneJson);\n }\n\n setMasterStripEqBand(bandIndex: number, band: EqBand | string): void {\n this.native.setMasterStripEqBandJson(\n bandIndex,\n typeof band === 'string' ? band : JSON.stringify(band),\n );\n }\n\n setMasterStripEqBandJson(bandIndex: number, bandJson: string): void {\n this.native.setMasterStripEqBandJson(bandIndex, bandJson);\n }\n\n setMasterStripInsertBypassed(\n insertIndex: number,\n bypassed: boolean,\n resetOnBypass = false,\n ): void {\n this.native.setMasterStripInsertBypassed(insertIndex, bypassed, resetOnBypass);\n }\n\n /**\n * Changes one track-strip insert parameter in realtime, addressed by the\n * processor's JSON-key parameter name (see {@link masteringInsertParamInfo}).\n * Applied at the next block head via the engine command queue; safe during\n * playback. Throws if the track, insert, or name is unknown, the param is not\n * realtime-safe, or the command queue is full.\n */\n setTrackStripInsertParamByName(\n trackId: number,\n insertIndex: number,\n paramName: string,\n value: number,\n ): void {\n this.native.setTrackStripInsertParamByName(trackId, insertIndex, paramName, value);\n }\n\n /** Master-strip counterpart of {@link setTrackStripInsertParamByName}. */\n setMasterStripInsertParamByName(insertIndex: number, paramName: string, value: number): void {\n this.native.setMasterStripInsertParamByName(insertIndex, paramName, value);\n }\n\n /** Sets a track lane strip's pan position in realtime (glitch-free). */\n setTrackStripPan(trackId: number, pan: number): void {\n this.native.setTrackStripPan(trackId, pan);\n }\n\n /** Sets a track lane strip's pan law in realtime. */\n setTrackStripPanLaw(trackId: number, panLaw: PanLaw | number): void {\n this.native.setTrackStripPanLaw(trackId, panLawCode(panLaw));\n }\n\n /** Sets a track lane strip's pan mode in realtime. */\n setTrackStripPanMode(trackId: number, panMode: PanMode | number): void {\n this.native.setTrackStripPanMode(trackId, panModeCode(panMode));\n }\n\n /** Sets a track lane strip's dual-pan left/right positions in realtime. */\n setTrackStripDualPan(trackId: number, leftPan: number, rightPan: number): void {\n this.native.setTrackStripDualPan(trackId, leftPan, rightPan);\n }\n\n /**\n * Sets a track lane strip's inter-channel alignment delay (whole samples).\n * Adjusts strip latency, so PDC and reported graph latency are refreshed.\n */\n setTrackStripChannelDelaySamples(trackId: number, delaySamples: number): void {\n this.native.setTrackStripChannelDelaySamples(trackId, delaySamples);\n }\n\n createClipPageProvider(\n numChannels: number,\n numSamples: number,\n pageFrames: number,\n ): ClipPageProvider {\n const id = this.native.createClipPageProvider(numChannels, numSamples, pageFrames);\n return new ClipPageProvider(this, id);\n }\n\n supplyClipPage(providerId: number, pageIndex: number, channels: Float32Array[]): void {\n this.native.supplyClipPage(providerId, pageIndex, channels);\n }\n\n clearClipPage(providerId: number, pageIndex: number): void {\n this.native.clearClipPage(providerId, pageIndex);\n }\n\n destroyClipPageProvider(providerId: number): void {\n this.native.destroyClipPageProvider(providerId);\n }\n\n popClipPageRequest(): ClipPageRequest | null {\n return this.native.popClipPageRequest();\n }\n\n setCaptureBuffer(numChannels: number, capacityFrames: number): void {\n this.native.setCaptureBuffer(numChannels, capacityFrames);\n }\n\n armCapture(armed = true): void {\n this.native.armCapture(armed);\n }\n\n setCapturePunch(startSample: number, endSample: number, enabled = true): void {\n this.native.setCapturePunch(startSample, endSample, enabled);\n }\n\n setCaptureSource(source: EngineCaptureStatus['source']): void {\n this.native.setCaptureSource(source);\n }\n\n setRecordOffsetSamples(offsetSamples: number): void {\n this.native.setRecordOffsetSamples(offsetSamples);\n }\n\n setInputMonitor(enabled: boolean, gain = 1): void {\n this.native.setInputMonitor(enabled, gain);\n }\n\n resetCapture(): void {\n this.native.resetCapture();\n }\n\n captureStatus(): EngineCaptureStatus {\n return this.native.captureStatus();\n }\n\n capturedAudio(): Float32Array[] {\n return this.native.capturedAudio();\n }\n\n process(channels: Float32Array[]): Float32Array[] {\n return this.native.process(channels);\n }\n\n /**\n * Allocates persistent per-channel WASM-heap scratch for the zero-copy\n * `getChannelBuffer` / `processPrepared` realtime path. Call once (off the\n * audio thread) before driving `processPrepared` from an AudioWorklet so the\n * render callback never allocates on the C++/JS heap.\n */\n prepareChannels(numChannels: number, maxFrames: number): void {\n this.native.prepareChannels(numChannels, maxFrames);\n }\n\n /**\n * Returns a Float32Array view onto the persistent WASM-heap scratch for one\n * channel (valid for up to `numFrames`). Fill it, call `processPrepared`, then\n * read the same view back. Re-acquire after WASM memory growth.\n */\n getChannelBuffer(channel: number, numFrames: number): Float32Array {\n return this.native.getChannelBuffer(channel, numFrames);\n }\n\n /**\n * Runs the engine in place over the prepared per-channel scratch buffers.\n * Allocation-free: safe to call on the AudioWorklet render thread after\n * `prepareChannels`.\n */\n processPrepared(numFrames: number): void {\n this.native.processPrepared(numFrames);\n }\n\n processWithMonitor(channels: Float32Array[]): WasmEngineProcessWithMonitorResult {\n return this.native.processWithMonitor(channels);\n }\n\n renderOffline(channels: Float32Array[], blockSize = 128): Float32Array[] {\n return this.native.renderOffline(channels, blockSize);\n }\n\n bounceOffline(options: EngineBounceOptions): EngineBounceResult {\n return this.native.bounceOffline(options);\n }\n\n freezeOffline(options: EngineFreezeOptions): EngineFreezeResult {\n return this.native.freezeOffline(options);\n }\n\n drainTelemetry(maxRecords = 1024): EngineTelemetry[] {\n return this.native.drainTelemetry(maxRecords);\n }\n\n drainMeterTelemetry(maxRecords = 1024): EngineMeterTelemetry[] {\n return this.native.drainMeterTelemetry(maxRecords);\n }\n\n /**\n * Drains pending meter telemetry as per-plane (wide) records for a surround\n * target. Use this for a surround mix target; {@link drainMeterTelemetry}\n * stays the stereo fast path. The two share one queue — call only one per\n * target. The live AudioWorklet path owns the queue via the stereo drain, so\n * this wide drain is for an offline (non-worklet) engine instance; per-plane\n * surround meters are not delivered over the live worklet meter ring.\n */\n drainMeterTelemetryWide(maxRecords = 1024): EngineMeterTelemetryWide[] {\n return this.native.drainMeterTelemetryWide(maxRecords);\n }\n\n /**\n * Enables per-target spectrum + vectorscope capture. @param intervalFrames is\n * the minimum render-frame gap between snapshots (0 disables). @param bandCount\n * is the FFT band resolution (1..64); changing it re-prepares the tap. Returns\n * the band count actually applied.\n */\n configureScopeTelemetry(intervalFrames: number, bandCount: number): number {\n return this.native.configureScopeTelemetry(intervalFrames, bandCount);\n }\n\n /** Drains pending spectrum + vectorscope snapshots (per mix target). */\n drainScopeTelemetry(maxRecords = 1024): EngineScopeTelemetry[] {\n return this.native.drainScopeTelemetry(maxRecords);\n }\n\n destroy(): void {\n this.native.delete();\n }\n}\n\nexport class ClipPageProvider {\n private disposed = false;\n\n constructor(\n private readonly engine: RealtimeEngine,\n readonly id: number,\n ) {}\n\n supply(pageIndex: number, channels: Float32Array[]): void {\n if (this.disposed) {\n throw new Error('ClipPageProvider is destroyed');\n }\n this.engine.supplyClipPage(this.id, pageIndex, channels);\n }\n\n clear(pageIndex: number): void {\n if (this.disposed) {\n return;\n }\n this.engine.clearClipPage(this.id, pageIndex);\n }\n\n destroy(): void {\n if (this.disposed) {\n return;\n }\n this.disposed = true;\n this.engine.destroyClipPageProvider(this.id);\n }\n}\n","/**\n * sonare - Audio Analysis Library\n *\n * @example\n * ```typescript\n * import { init, detectBpm, detectKey, analyze } from '@libraz/libsonare';\n *\n * await init();\n *\n * // Detect BPM from audio samples\n * const bpm = detectBpm(samples, sampleRate);\n *\n * // Detect musical key\n * const key = detectKey(samples, sampleRate);\n *\n * // Full analysis\n * const result = analyze(samples, sampleRate);\n * ```\n */\n\nimport { setSonareModule } from './module_state';\nimport type { RealtimeVoiceChangerPodConfig, VoicePresetId } from './public_types';\nimport type {\n SonareModule,\n WasmDecomposeResult,\n WasmHpssWithResidualResult,\n WasmMatrix2dResult,\n} from './sonare.js';\n\nexport type { BrowserAudioDecodeOptions } from './audio';\nexport { Audio } from './audio';\nexport type {\n CompressorDetector,\n CompressorOptions,\n DeclickOptions,\n DeclipOptions,\n DecrackleMode,\n DecrackleOptions,\n DehumOptions,\n DenoiseClassicalMode,\n DenoiseClassicalNoiseEstimator,\n DenoiseClassicalOptions,\n DereverbClassicalOptions,\n DynamicsResult,\n GateOptions,\n MasteringChannelPolicy,\n MasteringInsertParamInfo,\n MasteringProcessorCatalogEntry,\n TransientShaperOptions,\n TrimSilenceMode,\n TrimSilenceOptions,\n VoiceChangeOptions,\n VoiceChangeRealtimeOptions,\n} from './effects_mastering';\nexport {\n harmonic,\n hpss,\n masterAudio,\n masterAudioStereo,\n masterAudioStereoWithProgress,\n masterAudioWithProgress,\n mastering,\n masteringAssistantSuggest,\n masteringAudioProfile,\n masteringChain,\n masteringChainStereo,\n masteringChainStereoWithProgress,\n masteringChainWithProgress,\n masteringDynamicsCompressor,\n masteringDynamicsGate,\n masteringDynamicsTransientShaper,\n masteringInsertNames,\n masteringInsertParamInfo,\n masteringInsertParamNames,\n masteringPairAnalysisNames,\n masteringPairAnalyze,\n masteringPairProcess,\n masteringPairProcessorNames,\n masteringPresetNames,\n masteringProcess,\n masteringProcessorCatalog,\n masteringProcessorNames,\n masteringProcessStereo,\n masteringRepairDeclick,\n masteringRepairDeclip,\n masteringRepairDecrackle,\n masteringRepairDehum,\n masteringRepairDenoiseClassical,\n masteringRepairDereverbClassical,\n masteringRepairTrimSilence,\n masteringStereoAnalysisNames,\n masteringStereoAnalyze,\n masteringStreamingPreview,\n mixingScenePresetJson,\n mixingScenePresetNames,\n mixStereo,\n normalize,\n noteStretch,\n percussive,\n pitchCorrectToMidi,\n pitchCorrectToMidiTimevarying,\n pitchShift,\n spectralEdit,\n timeStretch,\n voiceChange,\n voiceChangeRealtime,\n} from './effects_mastering';\nexport { ErrorCode, isSonareError, SonareError } from './errors';\nexport type { MelodyOptions } from './feature_music';\nexport {\n amplitudeToDb,\n analyzeMelody,\n analyzeSections,\n bassChroma,\n chroma,\n chromaCens,\n cqt,\n cyclicTempogram,\n dbToAmplitude,\n dbToPower,\n decompose,\n decomposeWithInit,\n deemphasis,\n ebur128LoudnessRange,\n estimateTuning,\n fixFrames,\n fixLength,\n fourierTempogram,\n frameSignal,\n framesToSamples,\n framesToTime,\n hpssWithResidual,\n hybridCqt,\n hzToMel,\n hzToMidi,\n hzToNote,\n lufs,\n lufsInterleaved,\n melSpectrogram,\n melToAudio,\n melToHz,\n melToStft,\n mfcc,\n mfccToAudio,\n mfccToMel,\n midiToHz,\n momentaryLufs,\n nnFilter,\n nnlsChroma,\n noteToHz,\n onsetEnvelope,\n onsetStrengthMulti,\n padCenter,\n pcen,\n peakPick,\n phaseVocoder,\n pitchPyin,\n pitchTuning,\n pitchYin,\n plp,\n polyFeatures,\n powerToDb,\n preemphasis,\n pseudoCqt,\n remix,\n resample,\n rmsEnergy,\n samplesToFrames,\n shortTermLufs,\n spectralBandwidth,\n spectralCentroid,\n spectralContrast,\n spectralFlatness,\n spectralRolloff,\n splitSilence,\n stft,\n stftDb,\n tempogram,\n tempogramRatio,\n timeToFrames,\n tonnetz,\n trim,\n trimSilence,\n vectorNormalize,\n vqt,\n zeroCrossingRate,\n zeroCrossings,\n} from './features';\nexport type { BindMicrophoneInputOptions, MicrophoneInputBinding } from './live_audio';\nexport { bindMicrophoneInput } from './live_audio';\nexport type {\n ClippingRegion,\n ClippingReport,\n DynamicRangeReport,\n MeteringDetectClippingOptions,\n MeteringDynamicRangeOptions,\n PhaseScopeReport,\n SpectrumOptions,\n SpectrumReport,\n VectorscopeReport,\n WaveformPeakPyramidOptions,\n WaveformPeaksOptions,\n WaveformPeaksReport,\n} from './metering';\nexport {\n meteringCrestFactorDb,\n meteringDcOffset,\n meteringDetectClipping,\n meteringDynamicRange,\n meteringPeakDb,\n meteringPhaseScope,\n meteringPhaseScopeDecimated,\n meteringRmsDb,\n meteringSpectrum,\n meteringSpectrumFrame,\n meteringStereoCorrelation,\n meteringStereoWidth,\n meteringTruePeakDb,\n meteringVectorscope,\n meteringVectorscopeDecimated,\n waveformPeakPyramid,\n waveformPeaks,\n} from './metering';\nexport type {\n OpfsClipPageProviderBinding,\n OpfsClipPageProviderOptions,\n} from './opfs_clip_pages';\nexport {\n createOpfsClipPageProvider,\n createOpfsClipPageWorker,\n opfsClipPageWorkerSource,\n} from './opfs_clip_pages';\nexport type {\n BuiltinSynthBinding,\n BuiltinSynthConfig,\n BuiltinSynthWaveform,\n MidiCcLearnOptions,\n ProjectAssistSidecar,\n ProjectAutomationCurve,\n ProjectAutomationLaneDesc,\n ProjectAutomationPoint,\n ProjectBounceOptions,\n ProjectChordSymbol,\n ProjectClipCompSegment,\n ProjectClipDesc,\n ProjectClipFade,\n ProjectClipTake,\n ProjectCompileResult,\n ProjectFadeCurve,\n ProjectKeySegment,\n ProjectLoopMode,\n ProjectLoopRecordingDesc,\n ProjectLoopRecordingResult,\n ProjectMarker,\n ProjectMidiClipResult,\n ProjectMidiEvent,\n ProjectNotePairValidation,\n ProjectTrackDesc,\n ProjectTrackKind,\n ProjectWarpAnchor,\n ProjectWarpMapDesc,\n Sf2InstrumentConfig,\n Sf2ProgramStatus,\n SourceBackend,\n SynthBodyType,\n SynthEngineMode,\n SynthEnumTables,\n SynthFilterModel,\n SynthFilterOutput,\n SynthModDestination,\n SynthModRouting,\n SynthModSource,\n SynthOscWaveform,\n SynthPatch,\n} from './project';\nexport {\n EXPECTED_PROJECT_ABI_VERSION,\n MarkerKind,\n Project,\n projectAbiVersion,\n SYNTH_BODY_TYPES,\n SYNTH_ENGINE_MODES,\n SYNTH_FILTER_MODELS,\n SYNTH_FILTER_OUTPUTS,\n SYNTH_MOD_DESTINATIONS,\n SYNTH_MOD_SOURCES,\n SYNTH_OSC_WAVEFORMS,\n synthEnumTables,\n synthPresetNames,\n synthPresetPatch,\n} from './project';\nexport type {\n AcousticOptions,\n AcousticResult,\n AnalysisResult,\n AnalyzeBpmOptions,\n AnalyzeDynamicsOptions,\n AnalyzeRhythmOptions,\n AnalyzeSectionsOptions,\n AnalyzeTimbreOptions,\n AutomationCurve,\n Beat,\n Chord,\n ChordAnalysisResult,\n ChordDetectionOptions,\n ChromaResult,\n CqtResult,\n Dynamics,\n EqBand,\n EqBandPhase,\n EqBandType,\n EqCoeffMode,\n EqMatchOptions,\n EqSpectrumSnapshot,\n EqStereoPlacement,\n GoniometerPoint,\n HpssResult,\n Key,\n KeyCandidate,\n KeyDetectionOptions,\n KeyProfileName,\n LufsResult,\n MasteringChainConfig,\n MasteringChainResult,\n MasteringOptions,\n MasteringPreset,\n MasteringProcessorParams,\n MasteringResult,\n MasteringStereoChainResult,\n MasteringStereoResult,\n MelodyPoint,\n MelodyResult,\n MelPowerResult,\n MelSpectrogramResult,\n MeterTap,\n MfccResult,\n MixerProcessResult,\n MixMeterSnapshot,\n MixOptions,\n MixResult,\n NoteStretchOptions,\n PairAnalysis,\n PairProcessor,\n PanLaw,\n PanMode,\n PitchResult,\n RealtimeVoiceChangerConfigInput,\n RealtimeVoiceChangerPodConfig,\n RhythmFeatures,\n RirResult,\n RirSynthOptions,\n RoomEstimateOptions,\n RoomEstimateResult,\n RoomGeometryOptions,\n RoomMorphOptions,\n Section,\n SendTiming,\n SoloProcessor,\n SpectralEditMode,\n SpectralEditOptions,\n SpectralEditWindow,\n SpectralRegionOp,\n StereoAnalysis,\n StftPowerResult,\n StftResult,\n StreamingEqualizerConfig,\n StreamingMasteringChainConfig,\n StreamingPlatform,\n StreamingRetuneConfig,\n TempogramMode,\n Timbre,\n TimeSignature,\n VoicePresetId,\n} from './public_types';\nexport {\n ChordQuality,\n KeyProfile,\n Mode,\n PitchClass,\n SectionType,\n} from './public_types';\nexport type {\n BpmAnalysisResult,\n BpmCandidate,\n DynamicsAnalysisResult,\n RhythmAnalysisResult,\n TimbreAnalysisResult,\n TimbreFrame,\n} from './quick_analysis';\nexport {\n analyze,\n analyzeBpm,\n analyzeDynamics,\n analyzeImpulseResponse,\n analyzeRhythm,\n analyzeTimbre,\n analyzeWithProgress,\n chordFunctionalAnalysis,\n detectAcoustic,\n detectBeats,\n detectBpm,\n detectChords,\n detectDownbeats,\n detectKey,\n detectKeyCandidates,\n detectOnsets,\n estimateRoom,\n hasFfmpegSupport,\n roomMorph,\n synthesizeRir,\n} from './quick_analysis';\nexport type {\n EngineAutomationPoint,\n EngineBounceOptions,\n EngineBounceResult,\n EngineBus,\n EngineCapabilities,\n EngineCaptureStatus,\n EngineClip,\n EngineFreezeOptions,\n EngineFreezeResult,\n EngineGraphSpec,\n EngineMarker,\n EngineMeterTelemetry,\n EngineMeterTelemetryWide,\n EngineMetronomeConfig,\n EngineMidiClipSchedule,\n EngineMidiEvent,\n EngineParameterInfo,\n EngineScopeTelemetry,\n EngineTelemetry,\n EngineTempoSegment,\n EngineTimeSignatureSegment,\n EngineTrackLane,\n EngineTrackSend,\n EngineTransportState,\n MidiCcBindOptions,\n} from './realtime_engine';\nexport { EXPECTED_ENGINE_ABI_VERSION, engineCapabilities, RealtimeEngine } from './realtime_engine';\nexport { scaleCorrectionSemitones, scalePitchClassEnabled, scaleQuantizeMidi } from './scale';\nexport type { ProgressCallback } from './sonare.js';\nexport { StreamAnalyzer, streamAnalyzerConfigDefaults } from './stream_analyzer';\nexport type {\n AnalyzerStats,\n BarChord,\n ChordChange,\n FrameBuffer,\n PatternScore,\n ProgressiveEstimate,\n StreamConfig,\n StreamConfigDefaults,\n StreamFramesI16,\n StreamFramesU8,\n StreamQuantizeConfig,\n} from './stream_types';\nexport type {\n MixerRealtimeBuffer,\n RealtimeVoiceChangerInterleavedBuffer,\n RealtimeVoiceChangerMonoBuffer,\n RealtimeVoiceChangerPlanarBuffer,\n} from './streaming_mixing';\nexport {\n Mixer,\n RealtimeVoiceChanger,\n realtimeVoiceChangerPresetJson,\n realtimeVoiceChangerPresetNames,\n StreamingEqualizer,\n StreamingMasteringChain,\n StreamingRetune,\n validateRealtimeVoiceChangerPresetJson,\n} from './streaming_mixing';\nexport type { ValidateOptions } from './validation';\nexport type {\n BindWebMidiOptions,\n WebMidiBinding,\n WebMidiCcBinding,\n WebMidiInputInfo,\n} from './web_midi';\nexport { bindWebMidi, isWebMidiAvailable } from './web_midi';\n\n/** Row-major 2-D matrix as a flat buffer plus its dimensions. */\nexport type Matrix2dResult = WasmMatrix2dResult;\n/** NMF factor matrices { w, h } from {@link decompose}. */\nexport type DecomposeResult = WasmDecomposeResult;\n/** Harmonic / percussive / residual signals from {@link hpssWithResidual}. */\nexport type HpssWithResidualResult = WasmHpssWithResidualResult;\n\n// ============================================================================\n// Module State\n// ============================================================================\n\nlet module: SonareModule | null = null;\nlet initPromise: Promise<void> | null = null;\n\n// ============================================================================\n// Initialization\n// ============================================================================\n\n/**\n * Initialize the WASM module.\n * Must be called before using any analysis functions.\n *\n * @param options - Optional module configuration\n * @returns Promise that resolves when initialization is complete\n */\nexport async function init(options?: {\n locateFile?: (path: string, prefix: string) => string;\n wasmBinary?: ArrayBuffer | Uint8Array;\n moduleFactory?: (options?: {\n locateFile?: (path: string, prefix: string) => string;\n wasmBinary?: ArrayBuffer | Uint8Array;\n }) => Promise<SonareModule>;\n}): Promise<void> {\n if (module) {\n return;\n }\n\n if (initPromise) {\n return initPromise;\n }\n\n initPromise = (async () => {\n try {\n const createModule = options?.moduleFactory ?? (await import('./sonare.js')).default;\n module = await createModule(options);\n setSonareModule(module);\n } catch (error) {\n initPromise = null;\n throw error;\n }\n })();\n\n return initPromise;\n}\n\n/**\n * Check if the module is initialized.\n */\nexport function isInitialized(): boolean {\n return module !== null;\n}\n\n/**\n * Get the library version.\n */\nexport function version(): string {\n if (!module) {\n throw new Error('Module not initialized. Call init() first.');\n }\n return module.version();\n}\n\nexport function engineAbiVersion(): number {\n if (!module) {\n throw new Error('Module not initialized. Call init() first.');\n }\n return module.engineAbiVersion();\n}\n\nexport function voiceChangerAbiVersion(): number {\n if (!module) {\n throw new Error('Module not initialized. Call init() first.');\n }\n return module.voiceChangerAbiVersion();\n}\n\n// Canonical ordinal order of the built-in voice-character presets, matching the\n// C ABI SonareVoiceCharacterPreset enum and SONARE_REALTIME_VOICE_CHANGER_PRESET_IDS.\nconst VOICE_PRESET_ORDINALS: readonly VoicePresetId[] = [\n 'neutral-monitor',\n 'bright-idol',\n 'soft-whisper',\n 'deep-narrator',\n 'robot-mascot',\n 'dark-villain',\n];\n\nfunction resolveVoicePresetOrdinal(preset: VoicePresetId | number): number {\n if (typeof preset === 'number') {\n return preset;\n }\n const ordinal = VOICE_PRESET_ORDINALS.indexOf(preset);\n if (ordinal < 0) {\n throw new Error(`Unknown voice character preset: ${preset}`);\n }\n return ordinal;\n}\n\n/**\n * Map a voice-character preset ordinal (or canonical id) to its canonical id\n * string (e.g. `'bright-idol'`). Returns `null` for an out-of-range ordinal.\n */\nexport function voiceCharacterPresetId(preset: VoicePresetId | number): string | null {\n if (!module) {\n throw new Error('Module not initialized. Call init() first.');\n }\n return module.voiceCharacterPresetId(resolveVoicePresetOrdinal(preset));\n}\n\n/**\n * Return the canonical (normalized) flat POD config for a built-in voice\n * preset, skipping the JSON round-trip. Accepts a canonical preset id or its\n * integer ordinal. Returns `null` for an out-of-range ordinal.\n */\nexport function realtimeVoiceChangerPresetConfig(\n preset: VoicePresetId | number,\n): RealtimeVoiceChangerPodConfig | null {\n if (!module) {\n throw new Error('Module not initialized. Call init() first.');\n }\n return module.realtimeVoiceChangerPresetConfig(resolveVoicePresetOrdinal(preset));\n}\n\n// ============================================================================\n// Re-exports\n// ============================================================================\n\nexport { PitchClass as Pitch } from './public_types';\n","import type { EngineMeterTelemetry, EngineTelemetry } from '../index';\n\nconst ENGINE_MIXER_TARGET_BASE = 0x4d580000;\nexport const ENGINE_MIXER_PARAM_FADER_DB = 1;\nexport const ENGINE_MIXER_PARAM_PAN = 2;\n\nexport function engineMixerLaneTarget(laneIndex: number, paramKind: number): number {\n return ENGINE_MIXER_TARGET_BASE | ((laneIndex & 0xff) << 8) | (paramKind & 0xff);\n}\n\nexport function engineMixerBusTarget(busIndex: number, paramKind: number): number {\n return ENGINE_MIXER_TARGET_BASE | (((0xfe - busIndex) & 0xff) << 8) | (paramKind & 0xff);\n}\n\nexport function engineMixerMasterTarget(paramKind: number): number {\n return ENGINE_MIXER_TARGET_BASE | (0xff << 8) | (paramKind & 0xff);\n}\n\nexport interface SonareWorkletMeterSnapshot {\n type: 'meter';\n targetId: number;\n frame: number;\n peakDbL: number;\n peakDbR: number;\n rmsDbL: number;\n rmsDbR: number;\n correlation: number;\n truePeakDbL: number;\n truePeakDbR: number;\n momentaryLufs: number;\n shortTermLufs: number;\n integratedLufs: number;\n gainReductionDb: number;\n}\n\nexport interface SonareWorkletSpectrumSnapshot {\n type: 'spectrum';\n frame: number;\n bands: Float32Array;\n}\n\nexport const SONARE_METER_RING_HEADER_INTS = 4;\n// Record layout: [frameLo, frameHi, targetId, peakDbL, peakDbR, rmsDbL, rmsDbR,\n// correlation, truePeakDbL, truePeakDbR, momentaryLufs, shortTermLufs,\n// integratedLufs, gainReductionDb].\n// The sample-frame index is monotonically increasing and quickly exceeds the\n// 2^24 exact-integer range of a single Float32 slot (~349 s at 48 kHz), so it is\n// stored split across two Float32 lanes (low 24 bits + high bits) for exact\n// reconstruction. See encodeFrameLo/encodeFrameHi/decodeFrame.\nexport const SONARE_METER_RING_RECORD_FLOATS = 14;\nexport const SONARE_SPECTRUM_RING_HEADER_INTS = 5;\n// Scope ring header: [writeIndex, capacity, recordFloats, bands, maxPoints,\n// reserved]. Record layout: [frameLo, frameHi, targetId, bandCount, pointCount,\n// band0..band(bands-1), l0, r0, l1, r1, ... (maxPoints stereo pairs)].\nexport const SONARE_SCOPE_RING_HEADER_INTS = 6;\nexport const SONARE_SCOPE_RING_RECORD_PREFIX_FLOATS = 5;\n\n/** Base for splitting a frame index into two exactly-representable Float32 lanes. */\nconst SONARE_FRAME_LANE_BASE = 0x1000000; // 2^24\n\n/** Low 24 bits of a frame index (exact in Float32). */\nexport function encodeFrameLo(frame: number): number {\n const f = Math.max(0, Math.floor(frame));\n return f % SONARE_FRAME_LANE_BASE;\n}\n\n/** High bits of a frame index above 2^24 (exact in Float32 up to ~2^48). */\nexport function encodeFrameHi(frame: number): number {\n const f = Math.max(0, Math.floor(frame));\n return Math.floor(f / SONARE_FRAME_LANE_BASE);\n}\n\n/** Reconstruct a frame index from its low/high Float32 lanes. */\nexport function decodeFrame(lo: number, hi: number): number {\n return hi * SONARE_FRAME_LANE_BASE + lo;\n}\nexport const SONARE_ENGINE_RING_HEADER_INTS = 5;\nexport const SONARE_ENGINE_COMMAND_RECORD_BYTES = 32;\nexport const SONARE_ENGINE_TELEMETRY_RECORD_BYTES = 48;\n\nexport enum SonareEngineCommandType {\n SetParam = 0,\n SetParamSmoothed = 1,\n TransportPlay = 2,\n TransportStop = 3,\n TransportSeekSample = 4,\n TransportSeekPpq = 5,\n SetTempoMap = 6,\n SetLoop = 7,\n SwapGraph = 8,\n SwapAutomation = 9,\n SetSoloMute = 10,\n AddClip = 11,\n RemoveClip = 12,\n ArmRecord = 13,\n Punch = 14,\n SetMetronome = 15,\n SetMarker = 16,\n SeekMarker = 17,\n}\n\nexport enum SonareEngineTelemetryType {\n ProcessBlock = 0,\n Error = 1,\n}\n\nexport enum SonareEngineTelemetryError {\n None = 0,\n CommandQueueOverflow = 1,\n PendingCommandOverflow = 2,\n BoundaryOverflow = 3,\n TelemetryOverflow = 4,\n CaptureOverflow = 5,\n MaxBlockExceeded = 6,\n UnknownTarget = 7,\n NonRealtimeSafeParameter = 8,\n NotPrepared = 9,\n NonQueueableCommand = 10,\n AutomationBindTargetOverflow = 11,\n StaleAutomationLanes = 12,\n SmoothedParameterCapacity = 13,\n}\n\nexport interface SonareMeterRingBuffer {\n sharedBuffer: SharedArrayBuffer;\n header: Int32Array;\n records: Float32Array;\n capacity: number;\n}\n\nexport interface SonareMeterRingReadResult {\n nextReadIndex: number;\n meters: SonareWorkletMeterSnapshot[];\n}\n\nexport interface SonareSpectrumRingBuffer {\n sharedBuffer: SharedArrayBuffer;\n header: Int32Array;\n records: Float32Array;\n capacity: number;\n bands: number;\n}\n\nexport interface SonareSpectrumRingReadResult {\n nextReadIndex: number;\n spectra: SonareWorkletSpectrumSnapshot[];\n}\n\n/**\n * A single target-addressed scope record drained from the realtime engine's\n * scope ring: an FFT magnitude spectrum plus a decimated goniometer/vectorscope\n * point cloud. Unlike {@link SonareWorkletSpectrumSnapshot} (the legacy\n * coarse-DFT meter spectrum), this carries a `targetId` (master/lane/bus) and a\n * stereo point cloud, mirroring the engine's `ScopeTelemetryRecord`.\n */\nexport interface SonareWorkletScopeSnapshot {\n type: 'scope';\n targetId: number;\n frame: number;\n /** Linear-band magnitudes in dB (length = the configured band count). */\n bands: Float32Array;\n /** Interleaved stereo goniometer points: [l0, r0, l1, r1, ...]. */\n points: Float32Array;\n}\n\nexport interface SonareScopeRingBuffer {\n sharedBuffer: SharedArrayBuffer;\n header: Int32Array;\n records: Float32Array;\n capacity: number;\n bands: number;\n maxPoints: number;\n}\n\nexport interface SonareScopeRingReadResult {\n nextReadIndex: number;\n scopes: SonareWorkletScopeSnapshot[];\n}\n\nexport interface SharedScopeRingWriter {\n header: Int32Array;\n records: Float32Array;\n capacity: number;\n bands: number;\n maxPoints: number;\n recordFloats: number;\n}\n\nexport interface SonareEngineCommandRecord {\n type: SonareEngineCommandType | number;\n targetId?: number;\n sampleTime?: number | bigint;\n argFloat?: number;\n argInt?: number | bigint;\n}\n\nexport interface SonareEngineTelemetryRecord {\n type: SonareEngineTelemetryType | number;\n error: SonareEngineTelemetryError | number;\n renderFrame: number;\n timelineSample: number;\n audibleTimelineSample: number;\n graphLatencySamplesQ8: number;\n value: number;\n}\n\nexport interface SonareEngineCommandRingBuffer {\n sharedBuffer: SharedArrayBuffer;\n header: Int32Array;\n view: DataView;\n capacity: number;\n}\n\nexport interface SonareEngineTelemetryRingBuffer {\n sharedBuffer: SharedArrayBuffer;\n header: Int32Array;\n view: DataView;\n capacity: number;\n}\n\nexport interface SonareEngineTelemetryRingReadResult {\n nextReadIndex: number;\n telemetry: SonareEngineTelemetryRecord[];\n}\n\nexport interface SharedMeterRingWriter {\n header: Int32Array;\n records: Float32Array;\n capacity: number;\n}\n\nexport interface SharedSpectrumRingWriter {\n header: Int32Array;\n records: Float32Array;\n capacity: number;\n bands: number;\n recordFloats: number;\n}\n\nexport function toDb(value: number): number {\n return value > 0 ? 20 * Math.log10(value) : Number.NEGATIVE_INFINITY;\n}\n\nexport function isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null;\n}\n\nexport function sonareMeterRingBufferByteLength(capacity: number): number {\n const clampedCapacity = Math.max(1, Math.floor(capacity));\n return (\n SONARE_METER_RING_HEADER_INTS * Int32Array.BYTES_PER_ELEMENT +\n clampedCapacity * SONARE_METER_RING_RECORD_FLOATS * Float32Array.BYTES_PER_ELEMENT\n );\n}\n\nexport function createSonareMeterRingBuffer(capacity = 128): SonareMeterRingBuffer {\n const clampedCapacity = Math.max(1, Math.floor(capacity));\n const sharedBuffer = new SharedArrayBuffer(sonareMeterRingBufferByteLength(clampedCapacity));\n const ring = meterRingFromSharedBuffer(sharedBuffer, clampedCapacity);\n Atomics.store(ring.header, 0, 0);\n Atomics.store(ring.header, 1, clampedCapacity);\n Atomics.store(ring.header, 2, SONARE_METER_RING_RECORD_FLOATS);\n Atomics.store(ring.header, 3, 0);\n return { sharedBuffer, header: ring.header, records: ring.records, capacity: ring.capacity };\n}\n\nexport function readSonareMeterRingBuffer(\n ring: SonareMeterRingBuffer,\n readIndex = 0,\n): SonareMeterRingReadResult {\n const writeIndex = Atomics.load(ring.header, 0);\n const recordFloats = Atomics.load(ring.header, 2) || SONARE_METER_RING_RECORD_FLOATS;\n const nextReadIndex = Math.max(0, Math.min(readIndex, writeIndex));\n const firstReadable = Math.max(nextReadIndex, writeIndex - ring.capacity);\n const meters: SonareWorkletMeterSnapshot[] = [];\n for (let index = firstReadable; index < writeIndex; index++) {\n const offset = (index % ring.capacity) * recordFloats;\n meters.push({\n type: 'meter',\n frame: decodeFrame(ring.records[offset], ring.records[offset + 1]),\n targetId: ring.records[offset + 2],\n peakDbL: ring.records[offset + 3],\n peakDbR: ring.records[offset + 4],\n rmsDbL: ring.records[offset + 5],\n rmsDbR: ring.records[offset + 6],\n correlation: ring.records[offset + 7],\n truePeakDbL: ring.records[offset + 8],\n truePeakDbR: ring.records[offset + 9],\n momentaryLufs: ring.records[offset + 10],\n shortTermLufs: ring.records[offset + 11],\n integratedLufs: ring.records[offset + 12],\n gainReductionDb: ring.records[offset + 13],\n });\n }\n return { nextReadIndex: writeIndex, meters };\n}\n\nexport function sonareSpectrumRingBufferByteLength(capacity: number, bands = 16): number {\n const clampedCapacity = Math.max(1, Math.floor(capacity));\n const clampedBands = Math.max(1, Math.floor(bands));\n // Record layout: [frameLo, frameHi, bandCount, band0, band1, ...]. frame is\n // split across two Float32 lanes for exact reconstruction beyond 2^24.\n return (\n SONARE_SPECTRUM_RING_HEADER_INTS * Int32Array.BYTES_PER_ELEMENT +\n clampedCapacity * (3 + clampedBands) * Float32Array.BYTES_PER_ELEMENT\n );\n}\n\nexport function createSonareSpectrumRingBuffer(\n capacity = 128,\n bands = 16,\n): SonareSpectrumRingBuffer {\n const clampedCapacity = Math.max(1, Math.floor(capacity));\n const clampedBands = Math.max(1, Math.floor(bands));\n const sharedBuffer = new SharedArrayBuffer(\n sonareSpectrumRingBufferByteLength(clampedCapacity, clampedBands),\n );\n const ring = spectrumRingFromSharedBuffer(sharedBuffer, clampedCapacity, clampedBands);\n Atomics.store(ring.header, 0, 0);\n Atomics.store(ring.header, 1, clampedCapacity);\n Atomics.store(ring.header, 2, ring.recordFloats);\n Atomics.store(ring.header, 3, clampedBands);\n Atomics.store(ring.header, 4, 0);\n return {\n sharedBuffer,\n header: ring.header,\n records: ring.records,\n capacity: ring.capacity,\n bands: ring.bands,\n };\n}\n\nexport function readSonareSpectrumRingBuffer(\n ring: SonareSpectrumRingBuffer,\n readIndex = 0,\n): SonareSpectrumRingReadResult {\n const writeIndex = Atomics.load(ring.header, 0);\n const recordFloats = Atomics.load(ring.header, 2) || 3 + ring.bands;\n const bands = Atomics.load(ring.header, 3) || ring.bands;\n const nextReadIndex = Math.max(0, Math.min(readIndex, writeIndex));\n const firstReadable = Math.max(nextReadIndex, writeIndex - ring.capacity);\n const spectra: SonareWorkletSpectrumSnapshot[] = [];\n for (let index = firstReadable; index < writeIndex; index++) {\n const offset = (index % ring.capacity) * recordFloats;\n const values = new Float32Array(bands);\n values.set(ring.records.subarray(offset + 3, offset + 3 + bands));\n spectra.push({\n type: 'spectrum',\n frame: decodeFrame(ring.records[offset], ring.records[offset + 1]),\n bands: values,\n });\n }\n return { nextReadIndex: writeIndex, spectra };\n}\n\nexport function sonareScopeRingRecordFloats(bands: number, maxPoints: number): number {\n return SONARE_SCOPE_RING_RECORD_PREFIX_FLOATS + bands + 2 * maxPoints;\n}\n\nexport function sonareScopeRingBufferByteLength(\n capacity: number,\n bands = 48,\n maxPoints = 32,\n): number {\n const clampedCapacity = Math.max(1, Math.floor(capacity));\n const clampedBands = Math.max(1, Math.floor(bands));\n const clampedPoints = Math.max(0, Math.floor(maxPoints));\n return (\n SONARE_SCOPE_RING_HEADER_INTS * Int32Array.BYTES_PER_ELEMENT +\n clampedCapacity *\n sonareScopeRingRecordFloats(clampedBands, clampedPoints) *\n Float32Array.BYTES_PER_ELEMENT\n );\n}\n\nexport function createSonareScopeRingBuffer(\n capacity = 64,\n bands = 48,\n maxPoints = 32,\n): SonareScopeRingBuffer {\n const clampedCapacity = Math.max(1, Math.floor(capacity));\n const clampedBands = Math.max(1, Math.floor(bands));\n const clampedPoints = Math.max(0, Math.floor(maxPoints));\n const sharedBuffer = new SharedArrayBuffer(\n sonareScopeRingBufferByteLength(clampedCapacity, clampedBands, clampedPoints),\n );\n const ring = scopeRingFromSharedBuffer(\n sharedBuffer,\n clampedCapacity,\n clampedBands,\n clampedPoints,\n );\n Atomics.store(ring.header, 0, 0);\n Atomics.store(ring.header, 1, clampedCapacity);\n Atomics.store(ring.header, 2, ring.recordFloats);\n Atomics.store(ring.header, 3, clampedBands);\n Atomics.store(ring.header, 4, clampedPoints);\n Atomics.store(ring.header, 5, 0);\n return {\n sharedBuffer,\n header: ring.header,\n records: ring.records,\n capacity: ring.capacity,\n bands: ring.bands,\n maxPoints: ring.maxPoints,\n };\n}\n\nexport function readSonareScopeRingBuffer(\n ring: SonareScopeRingBuffer,\n readIndex = 0,\n): SonareScopeRingReadResult {\n const writeIndex = Atomics.load(ring.header, 0);\n const bands = Atomics.load(ring.header, 3) || ring.bands;\n const maxPoints = Atomics.load(ring.header, 4);\n const recordFloats =\n Atomics.load(ring.header, 2) || sonareScopeRingRecordFloats(bands, maxPoints);\n const nextReadIndex = Math.max(0, Math.min(readIndex, writeIndex));\n const firstReadable = Math.max(nextReadIndex, writeIndex - ring.capacity);\n const scopes: SonareWorkletScopeSnapshot[] = [];\n for (let index = firstReadable; index < writeIndex; index++) {\n const offset = (index % ring.capacity) * recordFloats;\n const bandCount = Math.min(bands, Math.max(0, ring.records[offset + 3]));\n const pointCount = Math.min(maxPoints, Math.max(0, ring.records[offset + 4]));\n const bandsView = new Float32Array(bandCount);\n bandsView.set(\n ring.records.subarray(\n offset + SONARE_SCOPE_RING_RECORD_PREFIX_FLOATS,\n offset + SONARE_SCOPE_RING_RECORD_PREFIX_FLOATS + bandCount,\n ),\n );\n const pointsBase = offset + SONARE_SCOPE_RING_RECORD_PREFIX_FLOATS + bands;\n const pointsView = new Float32Array(pointCount * 2);\n pointsView.set(ring.records.subarray(pointsBase, pointsBase + pointCount * 2));\n scopes.push({\n type: 'scope',\n frame: decodeFrame(ring.records[offset], ring.records[offset + 1]),\n targetId: ring.records[offset + 2],\n bands: bandsView,\n points: pointsView,\n });\n }\n return { nextReadIndex: writeIndex, scopes };\n}\n\nexport function scopeRingFromSharedBuffer(\n sharedBuffer: SharedArrayBuffer,\n fallbackCapacity?: number,\n fallbackBands?: number,\n fallbackMaxPoints?: number,\n): SharedScopeRingWriter {\n const headerBytes = SONARE_SCOPE_RING_HEADER_INTS * Int32Array.BYTES_PER_ELEMENT;\n const header = new Int32Array(sharedBuffer, 0, SONARE_SCOPE_RING_HEADER_INTS);\n const existingCapacity = Atomics.load(header, 1);\n const existingBands = Atomics.load(header, 3);\n const existingMaxPoints = Atomics.load(header, 4);\n const capacity = Math.max(1, Math.floor(existingCapacity || fallbackCapacity || 1));\n const bands = Math.max(1, Math.floor(existingBands || fallbackBands || 48));\n const maxPoints = Math.max(0, Math.floor(existingMaxPoints || (fallbackMaxPoints ?? 32)));\n const recordFloats = sonareScopeRingRecordFloats(bands, maxPoints);\n const minBytes = sonareScopeRingBufferByteLength(capacity, bands, maxPoints);\n if (sharedBuffer.byteLength < minBytes) {\n throw new Error('scopeSharedBuffer is too small for the requested ring capacity.');\n }\n Atomics.store(header, 1, capacity);\n Atomics.store(header, 2, recordFloats);\n Atomics.store(header, 3, bands);\n Atomics.store(header, 4, maxPoints);\n return {\n header,\n records: new Float32Array(sharedBuffer, headerBytes, capacity * recordFloats),\n capacity,\n bands,\n maxPoints,\n recordFloats,\n };\n}\n\nexport function sonareEngineCommandRingBufferByteLength(capacity: number): number {\n const clampedCapacity = Math.max(1, Math.floor(capacity));\n return (\n SONARE_ENGINE_RING_HEADER_INTS * Int32Array.BYTES_PER_ELEMENT +\n clampedCapacity * SONARE_ENGINE_COMMAND_RECORD_BYTES\n );\n}\n\nexport function sonareEngineTelemetryRingBufferByteLength(capacity: number): number {\n const clampedCapacity = Math.max(1, Math.floor(capacity));\n return (\n SONARE_ENGINE_RING_HEADER_INTS * Int32Array.BYTES_PER_ELEMENT +\n clampedCapacity * SONARE_ENGINE_TELEMETRY_RECORD_BYTES\n );\n}\n\nexport function createSonareEngineCommandRingBuffer(capacity = 128): SonareEngineCommandRingBuffer {\n const clampedCapacity = Math.max(1, Math.floor(capacity));\n const sharedBuffer = new SharedArrayBuffer(\n sonareEngineCommandRingBufferByteLength(clampedCapacity),\n );\n const ring = engineRingFromSharedBuffer(\n sharedBuffer,\n SONARE_ENGINE_COMMAND_RECORD_BYTES,\n clampedCapacity,\n );\n return { sharedBuffer, header: ring.header, view: ring.view, capacity: ring.capacity };\n}\n\nexport function createSonareEngineTelemetryRingBuffer(\n capacity = 128,\n): SonareEngineTelemetryRingBuffer {\n const clampedCapacity = Math.max(1, Math.floor(capacity));\n const sharedBuffer = new SharedArrayBuffer(\n sonareEngineTelemetryRingBufferByteLength(clampedCapacity),\n );\n const ring = engineRingFromSharedBuffer(\n sharedBuffer,\n SONARE_ENGINE_TELEMETRY_RECORD_BYTES,\n clampedCapacity,\n );\n return { sharedBuffer, header: ring.header, view: ring.view, capacity: ring.capacity };\n}\n\nexport function pushSonareEngineCommandRingBuffer(\n ring: SonareEngineCommandRingBuffer,\n command: SonareEngineCommandRecord,\n): boolean {\n const writeIndex = Atomics.load(ring.header, 0);\n const readIndex = Atomics.load(ring.header, 1);\n if (writeIndex - readIndex >= ring.capacity) {\n Atomics.add(ring.header, 4, 1);\n return false;\n }\n writeEngineCommandRecord(\n ring.view,\n recordOffset(writeIndex, ring.capacity, SONARE_ENGINE_COMMAND_RECORD_BYTES),\n command,\n );\n Atomics.store(ring.header, 0, writeIndex + 1);\n return true;\n}\n\nexport function popSonareEngineCommandRingBuffer(\n ring: SonareEngineCommandRingBuffer,\n): SonareEngineCommandRecord | null {\n const readIndex = Atomics.load(ring.header, 1);\n const writeIndex = Atomics.load(ring.header, 0);\n if (readIndex >= writeIndex) {\n return null;\n }\n const command = readEngineCommandRecord(\n ring.view,\n recordOffset(readIndex, ring.capacity, SONARE_ENGINE_COMMAND_RECORD_BYTES),\n );\n Atomics.store(ring.header, 1, readIndex + 1);\n return command;\n}\n\nexport function writeSonareEngineTelemetryRingBuffer(\n ring: SonareEngineTelemetryRingBuffer,\n telemetry: SonareEngineTelemetryRecord,\n): void {\n const writeIndex = Atomics.load(ring.header, 0);\n writeEngineTelemetryRecord(\n ring.view,\n recordOffset(writeIndex, ring.capacity, SONARE_ENGINE_TELEMETRY_RECORD_BYTES),\n telemetry,\n );\n Atomics.store(ring.header, 0, writeIndex + 1);\n if (writeIndex + 1 > ring.capacity) {\n Atomics.store(ring.header, 4, writeIndex + 1 - ring.capacity);\n }\n}\n\nexport function readSonareEngineTelemetryRingBuffer(\n ring: SonareEngineTelemetryRingBuffer,\n readIndex = 0,\n): SonareEngineTelemetryRingReadResult {\n const writeIndex = Atomics.load(ring.header, 0);\n const nextReadIndex = Math.max(0, Math.min(readIndex, writeIndex));\n const firstReadable = Math.max(nextReadIndex, writeIndex - ring.capacity);\n const telemetry: SonareEngineTelemetryRecord[] = [];\n for (let index = firstReadable; index < writeIndex; index++) {\n telemetry.push(\n readEngineTelemetryRecord(\n ring.view,\n recordOffset(index, ring.capacity, SONARE_ENGINE_TELEMETRY_RECORD_BYTES),\n ),\n );\n }\n return { nextReadIndex: writeIndex, telemetry };\n}\n\nexport function meterRingFromSharedBuffer(\n sharedBuffer: SharedArrayBuffer,\n fallbackCapacity?: number,\n): SharedMeterRingWriter {\n const headerBytes = SONARE_METER_RING_HEADER_INTS * Int32Array.BYTES_PER_ELEMENT;\n const header = new Int32Array(sharedBuffer, 0, SONARE_METER_RING_HEADER_INTS);\n const existingCapacity = Atomics.load(header, 1);\n const capacity = Math.max(1, Math.floor(existingCapacity || fallbackCapacity || 1));\n const minBytes = sonareMeterRingBufferByteLength(capacity);\n if (sharedBuffer.byteLength < minBytes) {\n throw new Error('meterSharedBuffer is too small for the requested ring capacity.');\n }\n Atomics.store(header, 1, capacity);\n Atomics.store(header, 2, SONARE_METER_RING_RECORD_FLOATS);\n return {\n header,\n records: new Float32Array(\n sharedBuffer,\n headerBytes,\n capacity * SONARE_METER_RING_RECORD_FLOATS,\n ),\n capacity,\n };\n}\n\nexport function spectrumRingFromSharedBuffer(\n sharedBuffer: SharedArrayBuffer,\n fallbackCapacity?: number,\n fallbackBands?: number,\n): SharedSpectrumRingWriter {\n const headerBytes = SONARE_SPECTRUM_RING_HEADER_INTS * Int32Array.BYTES_PER_ELEMENT;\n const header = new Int32Array(sharedBuffer, 0, SONARE_SPECTRUM_RING_HEADER_INTS);\n const existingCapacity = Atomics.load(header, 1);\n const existingBands = Atomics.load(header, 3);\n const capacity = Math.max(1, Math.floor(existingCapacity || fallbackCapacity || 1));\n const bands = Math.max(1, Math.floor(existingBands || fallbackBands || 16));\n const recordFloats = 3 + bands;\n const minBytes = sonareSpectrumRingBufferByteLength(capacity, bands);\n if (sharedBuffer.byteLength < minBytes) {\n throw new Error('spectrumSharedBuffer is too small for the requested ring capacity.');\n }\n Atomics.store(header, 1, capacity);\n Atomics.store(header, 2, recordFloats);\n Atomics.store(header, 3, bands);\n return {\n header,\n records: new Float32Array(sharedBuffer, headerBytes, capacity * recordFloats),\n capacity,\n bands,\n recordFloats,\n };\n}\n\nexport function engineRingFromSharedBuffer(\n sharedBuffer: SharedArrayBuffer,\n recordBytes: number,\n fallbackCapacity?: number,\n): { header: Int32Array; view: DataView; capacity: number } {\n const headerBytes = SONARE_ENGINE_RING_HEADER_INTS * Int32Array.BYTES_PER_ELEMENT;\n const header = new Int32Array(sharedBuffer, 0, SONARE_ENGINE_RING_HEADER_INTS);\n const existingCapacity = Atomics.load(header, 2);\n const capacity = Math.max(1, Math.floor(existingCapacity || fallbackCapacity || 1));\n const minBytes = headerBytes + capacity * recordBytes;\n if (sharedBuffer.byteLength < minBytes) {\n throw new Error('engine SharedArrayBuffer is too small for the requested ring capacity.');\n }\n Atomics.store(header, 2, capacity);\n Atomics.store(header, 3, recordBytes);\n return {\n header,\n view: new DataView(sharedBuffer, headerBytes, capacity * recordBytes),\n capacity,\n };\n}\n\nfunction recordOffset(index: number, capacity: number, recordBytes: number): number {\n return (index % capacity) * recordBytes;\n}\n\nexport function toBigInt64(value: number | bigint | undefined, fallback: bigint): bigint {\n if (typeof value === 'bigint') {\n return value;\n }\n if (typeof value === 'number') {\n return BigInt(Math.trunc(value));\n }\n return fallback;\n}\n\nfunction writeEngineCommandRecord(\n view: DataView,\n offset: number,\n command: SonareEngineCommandRecord,\n): void {\n view.setUint32(offset, command.type, true);\n view.setUint32(offset + 4, command.targetId ?? 0, true);\n view.setBigInt64(offset + 8, toBigInt64(command.sampleTime, -1n), true);\n // argFloat occupies a full 8-byte Float64 slot (replacing the old Float32 +\n // 4-byte pad) so PPQ scalars carried here keep full double precision over the\n // SAB transport, matching the engine's double-precision seek/loop contract.\n view.setFloat64(offset + 16, command.argFloat ?? 0, true);\n view.setBigInt64(offset + 24, toBigInt64(command.argInt, 0n), true);\n}\n\nfunction readEngineCommandRecord(view: DataView, offset: number): SonareEngineCommandRecord {\n return {\n type: view.getUint32(offset, true),\n targetId: view.getUint32(offset + 4, true),\n sampleTime: Number(view.getBigInt64(offset + 8, true)),\n argFloat: view.getFloat64(offset + 16, true),\n argInt: Number(view.getBigInt64(offset + 24, true)),\n };\n}\n\nfunction writeEngineTelemetryRecord(\n view: DataView,\n offset: number,\n telemetry: SonareEngineTelemetryRecord,\n): void {\n view.setUint32(offset, telemetry.type, true);\n view.setUint32(offset + 4, telemetry.error, true);\n view.setBigInt64(offset + 8, BigInt(Math.trunc(telemetry.renderFrame)), true);\n view.setBigInt64(offset + 16, BigInt(Math.trunc(telemetry.timelineSample)), true);\n view.setBigInt64(offset + 24, BigInt(Math.trunc(telemetry.audibleTimelineSample)), true);\n view.setInt32(offset + 32, telemetry.graphLatencySamplesQ8, true);\n view.setUint32(offset + 36, telemetry.value, true);\n view.setBigInt64(offset + 40, 0n, true);\n}\n\nfunction readEngineTelemetryRecord(view: DataView, offset: number): SonareEngineTelemetryRecord {\n return {\n type: view.getUint32(offset, true),\n error: view.getUint32(offset + 4, true),\n renderFrame: Number(view.getBigInt64(offset + 8, true)),\n timelineSample: Number(view.getBigInt64(offset + 16, true)),\n audibleTimelineSample: Number(view.getBigInt64(offset + 24, true)),\n graphLatencySamplesQ8: view.getInt32(offset + 32, true),\n value: view.getUint32(offset + 36, true),\n };\n}\n\nexport function telemetryFromEngine(telemetry: EngineTelemetry): SonareEngineTelemetryRecord {\n return {\n type: telemetry.type,\n error: telemetry.error,\n renderFrame: telemetry.renderFrame,\n timelineSample: telemetry.timelineSample,\n audibleTimelineSample: telemetry.audibleTimelineSample,\n graphLatencySamplesQ8: telemetry.graphLatencySamplesQ8,\n value: telemetry.value,\n };\n}\n\nexport function meterFromEngine(meter: EngineMeterTelemetry): SonareWorkletMeterSnapshot {\n return {\n type: 'meter',\n targetId: meter.targetId,\n frame: meter.renderFrame,\n peakDbL: meter.peakDbL,\n peakDbR: meter.peakDbR,\n rmsDbL: meter.rmsDbL,\n rmsDbR: meter.rmsDbR,\n correlation: meter.correlation,\n truePeakDbL: meter.truePeakDbL,\n truePeakDbR: meter.truePeakDbR,\n momentaryLufs: meter.momentaryLufs,\n shortTermLufs: meter.shortTermLufs,\n integratedLufs: meter.integratedLufs,\n gainReductionDb: meter.gainReductionDb,\n };\n}\n\nexport function magnitudeToDb(value: number): number {\n return value > 1.0e-12 ? 20 * Math.log10(value) : -120;\n}\n","import type {\n SonareEngineCaptureRequestMessage,\n SonareEngineCaptureResponseMessage,\n SonareEngineSyncMessage,\n SonareEngineTransportRequestMessage,\n SonareEngineTransportResponseMessage,\n SonareRealtimeVoiceChangerMessage,\n SonareWorkletMessage,\n} from './messages';\nimport {\n isRecord,\n type SonareEngineCommandRecord,\n type SonareEngineTelemetryRecord,\n type SonareWorkletMeterSnapshot,\n} from './protocol';\n\nexport function isWorkletMessage(value: unknown): value is SonareWorkletMessage {\n if (!isRecord(value) || typeof value.type !== 'string') {\n return false;\n }\n return (\n value.type === 'scheduleInsertAutomation' ||\n value.type === 'setMeterInterval' ||\n value.type === 'destroy'\n );\n}\n\nexport function isEngineCommandRecord(value: unknown): value is SonareEngineCommandRecord {\n return isRecord(value) && typeof value.type === 'number';\n}\n\nexport function isEngineSyncMessage(value: unknown): value is SonareEngineSyncMessage {\n if (!isRecord(value) || typeof value.type !== 'string') {\n return false;\n }\n return (\n value.type === 'syncClips' ||\n value.type === 'syncClipsDelta' ||\n value.type === 'syncMidiClips' ||\n value.type === 'syncMarkers' ||\n value.type === 'syncMetronome' ||\n value.type === 'syncAutomation' ||\n value.type === 'syncTempo' ||\n value.type === 'syncMixer' ||\n value.type === 'syncCapture' ||\n value.type === 'syncTrackStripEqBand' ||\n value.type === 'syncMasterStripEqBand' ||\n value.type === 'syncTrackStripInsertBypassed' ||\n value.type === 'syncMasterStripInsertBypassed' ||\n value.type === 'syncTrackStripInsertParamByName' ||\n value.type === 'syncMasterStripInsertParamByName' ||\n value.type === 'syncTrackStripPan' ||\n value.type === 'syncTrackStripPanLaw' ||\n value.type === 'syncTrackStripPanMode' ||\n value.type === 'syncTrackStripDualPan' ||\n value.type === 'syncTrackStripChannelDelaySamples' ||\n value.type === 'syncBuiltinInstrument' ||\n value.type === 'syncSynthInstrument' ||\n value.type === 'syncSf2Instrument' ||\n value.type === 'syncLoadSoundFont' ||\n value.type === 'syncMidiNoteOn' ||\n value.type === 'syncMidiNoteOff' ||\n value.type === 'syncMidiCc' ||\n value.type === 'syncMidiPanic'\n );\n}\n\nexport function isEngineCaptureRequestMessage(\n value: unknown,\n): value is SonareEngineCaptureRequestMessage {\n return (\n isRecord(value) &&\n value.type === 'captureRequest' &&\n typeof value.requestId === 'number' &&\n (value.op === 'status' || value.op === 'read' || value.op === 'reset')\n );\n}\n\nexport function isEngineCaptureResponseMessage(\n value: unknown,\n): value is SonareEngineCaptureResponseMessage {\n return (\n isRecord(value) &&\n value.type === 'captureResponse' &&\n typeof value.requestId === 'number' &&\n typeof value.ok === 'boolean'\n );\n}\n\nexport function isEngineTransportRequestMessage(\n value: unknown,\n): value is SonareEngineTransportRequestMessage {\n return (\n isRecord(value) &&\n value.type === 'transportRequest' &&\n typeof value.requestId === 'number' &&\n value.op === 'state'\n );\n}\n\nexport function isEngineTransportResponseMessage(\n value: unknown,\n): value is SonareEngineTransportResponseMessage {\n return (\n isRecord(value) &&\n value.type === 'transportResponse' &&\n typeof value.requestId === 'number' &&\n typeof value.ok === 'boolean'\n );\n}\n\nexport function isRealtimeVoiceChangerMessage(\n value: unknown,\n): value is SonareRealtimeVoiceChangerMessage {\n if (!isRecord(value) || typeof value.type !== 'string') {\n return false;\n }\n return value.type === 'setConfig' || value.type === 'reset' || value.type === 'destroy';\n}\n\nexport function isEngineTelemetryRecord(value: unknown): value is SonareEngineTelemetryRecord {\n return (\n isRecord(value) &&\n typeof value.type === 'number' &&\n typeof value.error === 'number' &&\n typeof value.renderFrame === 'number' &&\n typeof value.timelineSample === 'number' &&\n typeof value.audibleTimelineSample === 'number' &&\n typeof value.graphLatencySamplesQ8 === 'number' &&\n typeof value.value === 'number'\n );\n}\n\nexport function isMeterSnapshot(value: unknown): value is SonareWorkletMeterSnapshot {\n return (\n isRecord(value) &&\n value.type === 'meter' &&\n typeof value.frame === 'number' &&\n typeof value.peakDbL === 'number' &&\n typeof value.peakDbR === 'number' &&\n typeof value.rmsDbL === 'number' &&\n typeof value.rmsDbR === 'number' &&\n typeof value.correlation === 'number' &&\n (typeof value.targetId === 'number' || value.targetId === undefined)\n );\n}\n","import type {\n EngineAutomationPoint,\n EngineBus,\n EngineCaptureStatus,\n EngineClip,\n EngineMarker,\n EngineMetronomeConfig,\n EngineMidiClipSchedule,\n EngineTempoSegment,\n EngineTimeSignatureSegment,\n EngineTrackLane,\n EngineTransportState,\n RealtimeVoiceChangerConfigInput,\n} from '../index';\nimport type { AutomationCurve } from '../public_types';\nimport type { SonareRtModule } from '../sonare-rt';\nimport type {\n SonareEngineCommandRecord,\n SonareEngineTelemetryRecord,\n SonareWorkletMeterSnapshot,\n SonareWorkletSpectrumSnapshot,\n} from './protocol';\n\nexport interface SonareWorkletProcessorOptions {\n sceneJson: string;\n sampleRate?: number;\n blockSize?: number;\n stripCount?: number;\n meterIntervalFrames?: number;\n meterSharedBuffer?: SharedArrayBuffer;\n meterRingCapacity?: number;\n spectrumIntervalFrames?: number;\n spectrumBands?: number;\n spectrumSharedBuffer?: SharedArrayBuffer;\n spectrumRingCapacity?: number;\n}\n\nexport interface SonareRealtimeEngineWorkletProcessorOptions {\n runtimeTarget?: 'embind' | 'sonare-rt';\n rtModuleUrl?: string;\n rtWasmBinary?: ArrayBuffer | Uint8Array;\n wasmBinary?: ArrayBuffer | Uint8Array;\n initialSyncMessages?: SonareEngineSyncMessage[];\n initialCommands?: SonareEngineCommandRecord[];\n sampleRate?: number;\n blockSize?: number;\n channelCount?: number;\n meterIntervalFrames?: number;\n commandSharedBuffer?: SharedArrayBuffer;\n commandRingCapacity?: number;\n telemetrySharedBuffer?: SharedArrayBuffer;\n telemetryRingCapacity?: number;\n meterSharedBuffer?: SharedArrayBuffer;\n meterRingCapacity?: number;\n // Scope telemetry (FFT spectrum + goniometer): opt-in. The ring is created\n // only when scopeIntervalFrames > 0, since the per-block FFT is heavier than\n // the meter path. scopeBands selects the linear band resolution.\n scopeIntervalFrames?: number;\n scopeBands?: number;\n scopeSharedBuffer?: SharedArrayBuffer;\n scopeRingCapacity?: number;\n}\n\nexport interface SonareRealtimeVoiceChangerWorkletProcessorOptions {\n preset?: RealtimeVoiceChangerConfigInput;\n sampleRate?: number;\n blockSize?: number;\n channelCount?: number;\n}\n\nexport interface SonareRealtimeVoiceChangerSetConfigMessage {\n type: 'setConfig';\n preset: RealtimeVoiceChangerConfigInput;\n}\n\nexport interface SonareRealtimeVoiceChangerResetMessage {\n type: 'reset';\n}\n\nexport interface SonareRealtimeVoiceChangerDestroyMessage {\n type: 'destroy';\n}\n\nexport type SonareRealtimeVoiceChangerMessage =\n | SonareRealtimeVoiceChangerSetConfigMessage\n | SonareRealtimeVoiceChangerResetMessage\n | SonareRealtimeVoiceChangerDestroyMessage;\n\nexport interface SonareRealtimeEngineNodeCapabilities {\n mode: 'sab' | 'postMessage';\n runtimeTarget: 'embind' | 'sonare-rt';\n sharedArrayBuffer: boolean;\n atomics: boolean;\n audioWorklet: boolean;\n engineAbiVersion?: number;\n expectedEngineAbiVersion?: number;\n abiCompatible?: boolean;\n degradedReason?: string;\n readyMessage?: boolean;\n}\n\nexport interface SonareRealtimeEngineNodeOptions\n extends SonareRealtimeEngineWorkletProcessorOptions {\n processorName?: string;\n moduleUrl?: string | URL;\n rtModuleUrl?: string;\n mode?: 'auto' | 'sab' | 'postMessage';\n engineAbiVersion?: number;\n expectedEngineAbiVersion?: number;\n requireAbiCompatible?: boolean;\n nodeFactory?: (\n context: BaseAudioContext,\n processorName: string,\n options: AudioWorkletNodeOptions,\n ) => AudioWorkletNode;\n}\n\nexport interface SonareRtRealtimeEngineRuntimeOptions {\n module: SonareRtModule;\n memory: WebAssembly.Memory;\n sampleRate?: number;\n blockSize?: number;\n channelCount?: number;\n commandSharedBuffer?: SharedArrayBuffer;\n commandRingCapacity?: number;\n telemetrySharedBuffer?: SharedArrayBuffer;\n telemetryRingCapacity?: number;\n}\n\nexport interface SonareEngineTransportFacade {\n play(sampleTime?: number): boolean;\n stop(sampleTime?: number): boolean;\n seekPpq(ppq: number, sampleTime?: number): boolean;\n seekSeconds(seconds: number, sampleTime?: number): boolean;\n setTempo(bpm: number): void;\n setTempoSegments(segments: readonly EngineTempoSegment[]): void;\n setLoop(startPpq: number, endPpq: number, enabled?: boolean): boolean;\n}\n\nexport interface SonareWorkletScheduleInsertAutomationMessage {\n type: 'scheduleInsertAutomation';\n stripIndex: number;\n insertIndex: number;\n paramId: number;\n value: number;\n samplePos?: number;\n curve?: AutomationCurve;\n}\n\nexport interface SonareWorkletSetMeterIntervalMessage {\n type: 'setMeterInterval';\n frames: number;\n}\n\nexport interface SonareWorkletDestroyMessage {\n type: 'destroy';\n}\n\nexport type SonareWorkletMessage =\n | SonareWorkletScheduleInsertAutomationMessage\n | SonareWorkletSetMeterIntervalMessage\n | SonareWorkletDestroyMessage;\n\nexport type SonareWorkletTransportMessage =\n | SonareWorkletMeterSnapshot\n | SonareWorkletSpectrumSnapshot\n | SonareEngineTelemetryRecord;\n\nexport interface WorkletTransport {\n postMessage?: (\n message:\n | SonareWorkletTransportMessage\n | SonareEngineCaptureResponseMessage\n | SonareEngineTransportResponseMessage,\n transfer?: Transferable[],\n ) => void;\n onMeter?: (meter: SonareWorkletMeterSnapshot) => void;\n onSpectrum?: (spectrum: SonareWorkletSpectrumSnapshot) => void;\n}\n\nexport interface ResolvedMetronomeConfig {\n beatGain: number;\n accentGain: number;\n clickSamples: number;\n}\n\n// Fallback metronome gains/click length used by the worklet consumer until the\n// host posts a 'syncMetronome' config. Aligned with the embind setMetronome\n// defaults (src/wasm/bindings.cpp) so offline and realtime metronomes match.\nexport const DEFAULT_METRONOME_CONFIG: ResolvedMetronomeConfig = {\n beatGain: 0.35,\n accentGain: 0.7,\n clickSamples: 96,\n};\n\nexport function resolveMetronomeConfig(config: EngineMetronomeConfig): ResolvedMetronomeConfig {\n return {\n beatGain: config.beatGain ?? DEFAULT_METRONOME_CONFIG.beatGain,\n accentGain: config.accentGain ?? DEFAULT_METRONOME_CONFIG.accentGain,\n clickSamples: config.clickSamples ?? DEFAULT_METRONOME_CONFIG.clickSamples,\n };\n}\n\n// Out-of-band control messages posted from the main-thread SonareEngine facade\n// to the worklet engine processor over node.port. Unlike SonareEngineCommandRecord\n// (a small POD POSTed/ringed every block) these carry bulk/structured payloads\n// (clip audio buffers, marker lists, metronome config) that cannot fit the\n// fixed-size SAB command record, so they are applied OUTSIDE process() — the\n// audio-thread equivalent of the engine's control-thread RtPublisher setters.\nexport interface SonareEngineSyncClipsMessage {\n type: 'syncClips';\n clips: EngineClip[];\n}\n\nexport interface SonareEngineSyncClipsDeltaMessage {\n type: 'syncClipsDelta';\n upserts: EngineClip[];\n removeIds: number[];\n}\n\nexport interface SonareEngineSyncMidiClipsMessage {\n type: 'syncMidiClips';\n clips: EngineMidiClipSchedule[];\n}\n\nexport interface SonareEngineSyncMarkersMessage {\n type: 'syncMarkers';\n markers: EngineMarker[];\n}\n\nexport interface SonareEngineSyncMetronomeMessage {\n type: 'syncMetronome';\n config: EngineMetronomeConfig;\n}\n\nexport interface SonareEngineSyncAutomationMessage {\n type: 'syncAutomation';\n paramId: number;\n points: EngineAutomationPoint[];\n}\n\nexport interface SonareEngineSyncTempoMessage {\n type: 'syncTempo';\n bpm: number;\n timeSignature: { numerator: number; denominator: number };\n tempoSegments?: EngineTempoSegment[];\n timeSignatureSegments?: EngineTimeSignatureSegment[];\n}\n\nexport interface SonareEngineSyncMixerMessage {\n type: 'syncMixer';\n lanes: EngineTrackLane[];\n buses?: EngineBus[];\n trackStrips?: Array<{ trackId: number; sceneJson: string }>;\n busStrips?: Array<{ busId: number; sceneJson: string }>;\n masterStripJson?: string;\n /** Lane insert sidechain bindings (replayed after lanes/strips). */\n laneSidechains?: Array<{ trackId: number; insertIndex: number; sourceTrackId: number }>;\n}\n\nexport interface SonareEngineSyncCaptureMessage {\n type: 'syncCapture';\n bufferFrames: number;\n channels: number;\n source: EngineCaptureStatus['source'];\n recordOffsetSamples: number;\n inputMonitor: { enabled: boolean; gain: number };\n}\n\nexport interface SonareEngineSyncTrackStripEqBandMessage {\n type: 'syncTrackStripEqBand';\n trackId: number;\n bandIndex: number;\n bandJson: string;\n}\n\nexport interface SonareEngineSyncMasterStripEqBandMessage {\n type: 'syncMasterStripEqBand';\n bandIndex: number;\n bandJson: string;\n}\n\nexport interface SonareEngineSyncTrackStripInsertBypassedMessage {\n type: 'syncTrackStripInsertBypassed';\n trackId: number;\n insertIndex: number;\n bypassed: boolean;\n resetOnBypass: boolean;\n}\n\nexport interface SonareEngineSyncMasterStripInsertBypassedMessage {\n type: 'syncMasterStripInsertBypassed';\n insertIndex: number;\n bypassed: boolean;\n resetOnBypass: boolean;\n}\n\nexport interface SonareEngineSyncTrackStripInsertParamByNameMessage {\n type: 'syncTrackStripInsertParamByName';\n trackId: number;\n insertIndex: number;\n paramName: string;\n value: number;\n}\n\nexport interface SonareEngineSyncMasterStripInsertParamByNameMessage {\n type: 'syncMasterStripInsertParamByName';\n insertIndex: number;\n paramName: string;\n value: number;\n}\n\nexport interface SonareEngineSyncTrackStripPanMessage {\n type: 'syncTrackStripPan';\n trackId: number;\n pan: number;\n}\n\nexport interface SonareEngineSyncTrackStripPanLawMessage {\n type: 'syncTrackStripPanLaw';\n trackId: number;\n panLaw: number;\n}\n\nexport interface SonareEngineSyncTrackStripPanModeMessage {\n type: 'syncTrackStripPanMode';\n trackId: number;\n panMode: number;\n}\n\nexport interface SonareEngineSyncTrackStripDualPanMessage {\n type: 'syncTrackStripDualPan';\n trackId: number;\n leftPan: number;\n rightPan: number;\n}\n\nexport interface SonareEngineSyncTrackStripChannelDelaySamplesMessage {\n type: 'syncTrackStripChannelDelaySamples';\n trackId: number;\n delaySamples: number;\n}\n\nexport interface SonareEngineSyncBuiltinInstrumentMessage {\n type: 'syncBuiltinInstrument';\n destinationId: number;\n config: { destinationId?: number } & Record<string, unknown>;\n}\n\nexport interface SonareEngineSyncSynthInstrumentMessage {\n type: 'syncSynthInstrument';\n destinationId: number;\n patch: Record<string, unknown> | string;\n}\n\nexport interface SonareEngineSyncSf2InstrumentMessage {\n type: 'syncSf2Instrument';\n destinationId: number;\n config: { destinationId?: number; gain?: number; polyphony?: number };\n}\n\nexport interface SonareEngineSyncLoadSoundFontMessage {\n type: 'syncLoadSoundFont';\n data: Uint8Array;\n}\n\nexport interface SonareEngineSyncMidiNoteMessage {\n type: 'syncMidiNoteOn' | 'syncMidiNoteOff';\n destinationId: number;\n group: number;\n channel: number;\n note: number;\n velocity: number;\n renderFrame: number;\n}\n\nexport interface SonareEngineSyncMidiCcMessage {\n type: 'syncMidiCc';\n destinationId: number;\n group: number;\n channel: number;\n controller: number;\n value: number;\n renderFrame: number;\n}\n\nexport interface SonareEngineSyncMidiPanicMessage {\n type: 'syncMidiPanic';\n renderFrame: number;\n}\n\nexport type SonareEngineInstrumentSyncMessage =\n | SonareEngineSyncBuiltinInstrumentMessage\n | SonareEngineSyncSynthInstrumentMessage\n | SonareEngineSyncSf2InstrumentMessage\n | SonareEngineSyncLoadSoundFontMessage;\n\nexport type SonareEngineSyncMessage =\n | SonareEngineSyncClipsMessage\n | SonareEngineSyncClipsDeltaMessage\n | SonareEngineSyncMidiClipsMessage\n | SonareEngineSyncMarkersMessage\n | SonareEngineSyncMetronomeMessage\n | SonareEngineSyncAutomationMessage\n | SonareEngineSyncTempoMessage\n | SonareEngineSyncMixerMessage\n | SonareEngineSyncCaptureMessage\n | SonareEngineSyncTrackStripEqBandMessage\n | SonareEngineSyncMasterStripEqBandMessage\n | SonareEngineSyncTrackStripInsertBypassedMessage\n | SonareEngineSyncMasterStripInsertBypassedMessage\n | SonareEngineSyncTrackStripInsertParamByNameMessage\n | SonareEngineSyncMasterStripInsertParamByNameMessage\n | SonareEngineSyncTrackStripPanMessage\n | SonareEngineSyncTrackStripPanLawMessage\n | SonareEngineSyncTrackStripPanModeMessage\n | SonareEngineSyncTrackStripDualPanMessage\n | SonareEngineSyncTrackStripChannelDelaySamplesMessage\n | SonareEngineSyncBuiltinInstrumentMessage\n | SonareEngineSyncSynthInstrumentMessage\n | SonareEngineSyncSf2InstrumentMessage\n | SonareEngineSyncLoadSoundFontMessage\n | SonareEngineSyncMidiNoteMessage\n | SonareEngineSyncMidiCcMessage\n | SonareEngineSyncMidiPanicMessage;\n\nexport interface WorkletPort {\n postMessage?: (message: unknown, transfer?: Transferable[]) => void;\n onmessage?: (event: { data: unknown }) => void;\n addEventListener?: (type: 'message', listener: (event: { data: unknown }) => void) => void;\n start?: () => void;\n}\n\nexport interface SonareEngineCaptureRequestMessage {\n type: 'captureRequest';\n requestId: number;\n op: 'status' | 'read' | 'reset';\n}\n\nexport interface SonareEngineCaptureResponseMessage {\n type: 'captureResponse';\n requestId: number;\n ok: boolean;\n status?: EngineCaptureStatus;\n channels?: Float32Array[] | number[][];\n error?: string;\n}\n\nexport interface SonareEngineTransportRequestMessage {\n type: 'transportRequest';\n requestId: number;\n op: 'state';\n}\n\nexport interface SonareEngineTransportResponseMessage {\n type: 'transportResponse';\n requestId: number;\n ok: boolean;\n state?: EngineTransportState;\n error?: string;\n}\n","import { panLawCode, panModeCode } from './codes';\nimport type {\n EngineAutomationPoint,\n EngineBus,\n EngineCaptureStatus,\n EngineClip,\n EngineMarker,\n EngineMetronomeConfig,\n EngineMidiClipSchedule,\n EngineParameterInfo,\n EngineScopeTelemetry,\n EngineTempoSegment,\n EngineTimeSignatureSegment,\n EngineTrackLane,\n EngineTrackSend,\n EngineTransportState,\n EqBand,\n MixerRealtimeBuffer,\n PanLaw,\n PanMode,\n} from './index';\nimport {\n engineCapabilities,\n init as initSonareModule,\n isInitialized,\n Mixer,\n RealtimeEngine,\n RealtimeVoiceChanger,\n} from './index';\nimport type { SonareModule } from './sonare.js';\nimport type { SonareRtModule } from './sonare-rt';\n\n// With code-splitting disabled, the worklet bundle carries its own copy of the\n// module singleton (a real AudioWorkletGlobalScope cannot resolve sibling\n// chunks, so the bundle must be self-contained). Re-export the lifecycle so that\n// realm can initialize its own wasm instance, independent of the main-thread\n// `index` module.\nexport { init, isInitialized } from './index';\n\nimport type { WorkletInput, WorkletOutput } from './worklet/audio_types';\nimport {\n isEngineCaptureRequestMessage,\n isEngineCaptureResponseMessage,\n isEngineCommandRecord,\n isEngineSyncMessage,\n isEngineTelemetryRecord,\n isEngineTransportRequestMessage,\n isEngineTransportResponseMessage,\n isMeterSnapshot,\n isRealtimeVoiceChangerMessage,\n isWorkletMessage,\n} from './worklet/guards';\nimport {\n DEFAULT_METRONOME_CONFIG,\n type ResolvedMetronomeConfig,\n resolveMetronomeConfig,\n type SonareEngineCaptureRequestMessage,\n type SonareEngineCaptureResponseMessage,\n type SonareEngineInstrumentSyncMessage,\n type SonareEngineSyncCaptureMessage,\n type SonareEngineSyncMessage,\n type SonareEngineTransportFacade,\n type SonareEngineTransportRequestMessage,\n type SonareEngineTransportResponseMessage,\n type SonareRealtimeEngineNodeCapabilities,\n type SonareRealtimeEngineNodeOptions,\n type SonareRealtimeEngineWorkletProcessorOptions,\n type SonareRealtimeVoiceChangerMessage,\n type SonareRealtimeVoiceChangerWorkletProcessorOptions,\n type SonareRtRealtimeEngineRuntimeOptions,\n type SonareWorkletMessage,\n type SonareWorkletProcessorOptions,\n type WorkletPort,\n type WorkletTransport,\n} from './worklet/messages';\n// --- internal modules (split out of this file; bundled back into a single\n// dist/worklet.js by tsup, so the public surface is unchanged) ---\nimport {\n createSonareEngineCommandRingBuffer,\n createSonareEngineTelemetryRingBuffer,\n createSonareMeterRingBuffer,\n createSonareScopeRingBuffer,\n ENGINE_MIXER_PARAM_FADER_DB,\n ENGINE_MIXER_PARAM_PAN,\n encodeFrameHi,\n encodeFrameLo,\n engineMixerBusTarget,\n engineMixerLaneTarget,\n engineMixerMasterTarget,\n engineRingFromSharedBuffer,\n isRecord,\n magnitudeToDb,\n meterFromEngine,\n meterRingFromSharedBuffer,\n popSonareEngineCommandRingBuffer,\n pushSonareEngineCommandRingBuffer,\n readSonareEngineTelemetryRingBuffer,\n readSonareMeterRingBuffer,\n readSonareScopeRingBuffer,\n type SharedMeterRingWriter,\n type SharedScopeRingWriter,\n type SharedSpectrumRingWriter,\n SONARE_ENGINE_COMMAND_RECORD_BYTES,\n SONARE_ENGINE_TELEMETRY_RECORD_BYTES,\n SONARE_METER_RING_RECORD_FLOATS,\n SONARE_SCOPE_RING_RECORD_PREFIX_FLOATS,\n type SonareEngineCommandRecord,\n type SonareEngineCommandRingBuffer,\n SonareEngineCommandType,\n SonareEngineTelemetryError,\n type SonareEngineTelemetryRecord,\n type SonareEngineTelemetryRingBuffer,\n SonareEngineTelemetryType,\n type SonareMeterRingBuffer,\n type SonareScopeRingBuffer,\n type SonareWorkletMeterSnapshot,\n type SonareWorkletScopeSnapshot,\n type SonareWorkletSpectrumSnapshot,\n scopeRingFromSharedBuffer,\n spectrumRingFromSharedBuffer,\n telemetryFromEngine,\n toBigInt64,\n toDb,\n writeSonareEngineTelemetryRingBuffer,\n} from './worklet/protocol';\n\nexport type {\n SonareEngineCaptureRequestMessage,\n SonareEngineCaptureResponseMessage,\n SonareEngineSyncAutomationMessage,\n SonareEngineSyncBuiltinInstrumentMessage,\n SonareEngineSyncCaptureMessage,\n SonareEngineSyncClipsDeltaMessage,\n SonareEngineSyncClipsMessage,\n SonareEngineSyncLoadSoundFontMessage,\n SonareEngineSyncMarkersMessage,\n SonareEngineSyncMasterStripEqBandMessage,\n SonareEngineSyncMasterStripInsertBypassedMessage,\n SonareEngineSyncMessage,\n SonareEngineSyncMetronomeMessage,\n SonareEngineSyncMidiCcMessage,\n SonareEngineSyncMidiClipsMessage,\n SonareEngineSyncMidiNoteMessage,\n SonareEngineSyncMidiPanicMessage,\n SonareEngineSyncMixerMessage,\n SonareEngineSyncSf2InstrumentMessage,\n SonareEngineSyncSynthInstrumentMessage,\n SonareEngineSyncTempoMessage,\n SonareEngineSyncTrackStripEqBandMessage,\n SonareEngineSyncTrackStripInsertBypassedMessage,\n SonareEngineTransportFacade,\n SonareEngineTransportRequestMessage,\n SonareEngineTransportResponseMessage,\n SonareRealtimeEngineNodeCapabilities,\n SonareRealtimeEngineNodeOptions,\n SonareRealtimeEngineWorkletProcessorOptions,\n SonareRealtimeVoiceChangerDestroyMessage,\n SonareRealtimeVoiceChangerMessage,\n SonareRealtimeVoiceChangerResetMessage,\n SonareRealtimeVoiceChangerSetConfigMessage,\n SonareRealtimeVoiceChangerWorkletProcessorOptions,\n SonareRtRealtimeEngineRuntimeOptions,\n SonareWorkletDestroyMessage,\n SonareWorkletMessage,\n SonareWorkletProcessorOptions,\n SonareWorkletScheduleInsertAutomationMessage,\n SonareWorkletSetMeterIntervalMessage,\n SonareWorkletTransportMessage,\n} from './worklet/messages';\nexport {\n createSonareEngineCommandRingBuffer,\n createSonareEngineTelemetryRingBuffer,\n createSonareMeterRingBuffer,\n createSonareScopeRingBuffer,\n createSonareSpectrumRingBuffer,\n decodeFrame,\n encodeFrameHi,\n encodeFrameLo,\n popSonareEngineCommandRingBuffer,\n pushSonareEngineCommandRingBuffer,\n readSonareEngineTelemetryRingBuffer,\n readSonareMeterRingBuffer,\n readSonareScopeRingBuffer,\n readSonareSpectrumRingBuffer,\n SONARE_ENGINE_COMMAND_RECORD_BYTES,\n SONARE_ENGINE_RING_HEADER_INTS,\n SONARE_ENGINE_TELEMETRY_RECORD_BYTES,\n SONARE_METER_RING_HEADER_INTS,\n SONARE_METER_RING_RECORD_FLOATS,\n SONARE_SCOPE_RING_HEADER_INTS,\n SONARE_SPECTRUM_RING_HEADER_INTS,\n type SonareEngineCommandRecord,\n type SonareEngineCommandRingBuffer,\n SonareEngineCommandType,\n SonareEngineTelemetryError,\n type SonareEngineTelemetryRecord,\n type SonareEngineTelemetryRingBuffer,\n type SonareEngineTelemetryRingReadResult,\n SonareEngineTelemetryType,\n type SonareMeterRingBuffer,\n type SonareMeterRingReadResult,\n type SonareScopeRingBuffer,\n type SonareScopeRingReadResult,\n type SonareSpectrumRingBuffer,\n type SonareSpectrumRingReadResult,\n type SonareWorkletMeterSnapshot,\n type SonareWorkletScopeSnapshot,\n type SonareWorkletSpectrumSnapshot,\n sonareEngineCommandRingBufferByteLength,\n sonareEngineTelemetryRingBufferByteLength,\n sonareMeterRingBufferByteLength,\n sonareScopeRingBufferByteLength,\n sonareSpectrumRingBufferByteLength,\n writeSonareEngineTelemetryRingBuffer,\n} from './worklet/protocol';\n\nexport interface SonareEngineOptions extends SonareRealtimeEngineNodeOptions {\n offlineEngine?: RealtimeEngine;\n offlineBlockSize?: number;\n offlineChannelCount?: number;\n}\n\ntype SuspendableAudioContext = BaseAudioContext & {\n suspend?: () => Promise<void>;\n resume?: () => Promise<void>;\n};\n\n/**\n * AudioWorklet-style mixer bridge backed by the package's single `sonare.wasm`.\n *\n * The WASM module must already be initialized via `init()` before constructing\n * this bridge. Each AudioWorklet input is treated as one stereo strip:\n * `inputs[strip][0]` is left and `inputs[strip][1]` is right. Missing channels\n * are replaced with preallocated silence.\n */\nexport class SonareWorkletProcessor {\n readonly sampleRate: number;\n readonly blockSize: number;\n private mixer: Mixer;\n private realtime: MixerRealtimeBuffer;\n private closed = false;\n private processedFrames = 0;\n private lastMeterFrame = 0;\n private meterIntervalFrames: number;\n private spectrumIntervalFrames: number;\n private lastSpectrumFrame = 0;\n private transport?: WorkletTransport;\n private meterRing?: SharedMeterRingWriter;\n private spectrumRing?: SharedSpectrumRingWriter;\n private spectrumBands: Float32Array;\n\n constructor(options: SonareWorkletProcessorOptions, transport?: WorkletTransport) {\n if (!options.sceneJson) {\n throw new Error('sceneJson is required.');\n }\n this.sampleRate = options.sampleRate ?? 48000;\n this.blockSize = options.blockSize ?? 128;\n this.meterIntervalFrames = Math.max(0, Math.floor(options.meterIntervalFrames ?? 2048));\n this.spectrumIntervalFrames = Math.max(0, Math.floor(options.spectrumIntervalFrames ?? 0));\n this.transport = transport;\n this.meterIntervalFrames = Math.max(0, Math.floor(options.meterIntervalFrames ?? 2048));\n this.meterRing = options.meterSharedBuffer\n ? meterRingFromSharedBuffer(options.meterSharedBuffer, options.meterRingCapacity)\n : undefined;\n this.spectrumRing = options.spectrumSharedBuffer\n ? spectrumRingFromSharedBuffer(\n options.spectrumSharedBuffer,\n options.spectrumRingCapacity,\n options.spectrumBands,\n )\n : undefined;\n const spectrumBandCount = this.spectrumRing?.bands ?? Math.max(1, options.spectrumBands ?? 16);\n this.spectrumBands = new Float32Array(spectrumBandCount);\n this.mixer = Mixer.fromSceneJson(options.sceneJson, this.sampleRate, this.blockSize);\n this.mixer.compile();\n const sceneStripCount = this.mixer.stripCount();\n const stripCount = options.stripCount ?? sceneStripCount;\n if (stripCount !== sceneStripCount) {\n throw new Error('stripCount must match the scene strip count.');\n }\n this.realtime = this.mixer.createRealtimeBuffer();\n }\n\n process(inputs: WorkletInput, outputs: WorkletOutput): boolean {\n if (this.closed) {\n return false;\n }\n const output = outputs[0];\n const leftOut = output?.[0];\n const rightOut = output?.[1];\n if (!leftOut) {\n return true;\n }\n const frames = leftOut.length;\n // The mixer's realtime heap buffers are sized to blockSize. A render quantum\n // that differs from blockSize (e.g. a future browser using a quantum other\n // than 128, or a misconfigured blockSize) must NOT return false here:\n // returning false permanently terminates the AudioWorkletProcessor and\n // silently kills the node mid-stream. Instead degrade gracefully by\n // processing min(frames, blockSize) and zero-filling any remainder, mirroring\n // the sonare-rt processor's behaviour.\n const usable = Math.min(frames, this.blockSize);\n\n for (let strip = 0; strip < this.realtime.leftInputs.length; strip++) {\n const input = inputs[strip];\n const left = input?.[0];\n const right = input?.[1];\n const leftTarget = this.realtime.leftInputs[strip];\n const rightTarget = this.realtime.rightInputs[strip];\n if (left && left.length >= usable) {\n leftTarget.set(left.subarray(0, usable));\n if (right && right.length >= usable) {\n rightTarget.set(right.subarray(0, usable));\n } else {\n rightTarget.set(left.subarray(0, usable));\n }\n } else {\n leftTarget.fill(0);\n rightTarget.fill(0);\n }\n }\n\n this.realtime.process(usable);\n if (usable === frames) {\n leftOut.set(this.realtime.outLeft.subarray(0, usable));\n if (rightOut) {\n rightOut.set(this.realtime.outRight.subarray(0, usable));\n }\n } else {\n // frames > blockSize: fill the produced part and zero the remaining tail.\n leftOut.fill(0);\n leftOut.set(this.realtime.outLeft.subarray(0, usable));\n if (rightOut) {\n rightOut.fill(0);\n rightOut.set(this.realtime.outRight.subarray(0, usable));\n }\n }\n this.processedFrames += usable;\n this.publishMeter(\n this.realtime.outLeft.subarray(0, usable),\n this.realtime.outRight.subarray(0, usable),\n );\n this.publishSpectrum(\n this.realtime.outLeft.subarray(0, usable),\n this.realtime.outRight.subarray(0, usable),\n );\n return true;\n }\n\n receiveMessage(message: SonareWorkletMessage): void {\n if (this.closed) {\n return;\n }\n if (message.type === 'destroy') {\n this.destroy();\n return;\n }\n if (message.type === 'setMeterInterval') {\n this.meterIntervalFrames = Math.max(0, Math.floor(message.frames));\n return;\n }\n if (message.type === 'scheduleInsertAutomation') {\n this.mixer.scheduleInsertAutomation(\n message.stripIndex,\n message.insertIndex,\n message.paramId,\n message.samplePos ?? this.processedFrames,\n message.value,\n message.curve ?? 'linear',\n );\n }\n }\n\n destroy(): void {\n if (!this.closed) {\n this.mixer.delete();\n this.closed = true;\n }\n }\n\n private publishMeter(left: Float32Array, right: Float32Array): void {\n if (!this.transport || this.meterIntervalFrames <= 0) {\n return;\n }\n if (this.processedFrames - this.lastMeterFrame < this.meterIntervalFrames) {\n return;\n }\n this.lastMeterFrame = this.processedFrames;\n\n let peakL = 0;\n let peakR = 0;\n let sumL = 0;\n let sumR = 0;\n let sumLR = 0;\n for (let i = 0; i < left.length; i++) {\n const l = left[i] ?? 0;\n const r = right[i] ?? 0;\n const absL = Math.abs(l);\n const absR = Math.abs(r);\n if (absL > peakL) {\n peakL = absL;\n }\n if (absR > peakR) {\n peakR = absR;\n }\n sumL += l * l;\n sumR += r * r;\n sumLR += l * r;\n }\n const rmsL = Math.sqrt(sumL / Math.max(1, left.length));\n const rmsR = Math.sqrt(sumR / Math.max(1, right.length));\n const denominator = Math.sqrt(sumL * sumR);\n const meter: SonareWorkletMeterSnapshot = {\n type: 'meter',\n targetId: 0,\n frame: this.processedFrames,\n peakDbL: toDb(peakL),\n peakDbR: toDb(peakR),\n rmsDbL: toDb(rmsL),\n rmsDbR: toDb(rmsR),\n correlation: denominator > 0 ? sumLR / denominator : 0,\n truePeakDbL: toDb(peakL),\n truePeakDbR: toDb(peakR),\n momentaryLufs: Number.NaN,\n shortTermLufs: Number.NaN,\n integratedLufs: Number.NaN,\n gainReductionDb: Number.NaN,\n };\n this.transport.onMeter?.(meter);\n if (this.meterRing) {\n this.writeMeterRing(meter);\n } else {\n this.transport.postMessage?.(meter);\n }\n }\n\n private writeMeterRing(meter: SonareWorkletMeterSnapshot): void {\n const ring = this.meterRing;\n if (!ring) {\n return;\n }\n const writeIndex = Atomics.load(ring.header, 0);\n const offset = (writeIndex % ring.capacity) * SONARE_METER_RING_RECORD_FLOATS;\n ring.records[offset] = encodeFrameLo(meter.frame);\n ring.records[offset + 1] = encodeFrameHi(meter.frame);\n ring.records[offset + 2] = meter.targetId;\n ring.records[offset + 3] = meter.peakDbL;\n ring.records[offset + 4] = meter.peakDbR;\n ring.records[offset + 5] = meter.rmsDbL;\n ring.records[offset + 6] = meter.rmsDbR;\n ring.records[offset + 7] = meter.correlation;\n ring.records[offset + 8] = meter.truePeakDbL;\n ring.records[offset + 9] = meter.truePeakDbR;\n ring.records[offset + 10] = meter.momentaryLufs;\n ring.records[offset + 11] = meter.shortTermLufs;\n ring.records[offset + 12] = meter.integratedLufs;\n ring.records[offset + 13] = meter.gainReductionDb;\n Atomics.store(ring.header, 0, writeIndex + 1);\n // writeIndex is a free-running monotonic counter, so an overflow guard here\n // would fire on essentially every write past the first `capacity` records\n // and store an ever-growing value, not a dropped-record count. Readers\n // already detect silent overrun via firstReadable = max(readIndex,\n // writeIndex - capacity), so header slot 3 is left at its initial 0.\n }\n\n private publishSpectrum(left: Float32Array, right: Float32Array): void {\n if (this.spectrumIntervalFrames <= 0) {\n return;\n }\n if (this.processedFrames - this.lastSpectrumFrame < this.spectrumIntervalFrames) {\n return;\n }\n this.lastSpectrumFrame = this.processedFrames;\n this.computeSpectrum(left, right);\n if (this.spectrumRing) {\n this.writeSpectrumRing(this.processedFrames, this.spectrumBands);\n return;\n }\n const spectrum: SonareWorkletSpectrumSnapshot = {\n type: 'spectrum',\n frame: this.processedFrames,\n bands: new Float32Array(this.spectrumBands),\n };\n this.transport?.onSpectrum?.(spectrum);\n this.transport?.postMessage?.(spectrum);\n }\n\n private computeSpectrum(left: Float32Array, right: Float32Array): void {\n // Coarse per-render-quantum band energy, NOT a full FFT analyzer: each band\n // is a single-bin DFT (bin = band + 1) evaluated over the current block of n\n // samples. Bins at or above the block Nyquist (band + 1 > floor(n / 2))\n // alias, so the evaluated band count is clamped to floor(n / 2) and any\n // higher bands are pinned to the silence floor. Bin resolution is therefore\n // tied to the render quantum (typically 128 samples); treat the output as a\n // rough spectral tilt, not a precise spectrum.\n const n = Math.max(1, Math.min(left.length, right.length));\n const maxBand = Math.floor(n / 2);\n for (let band = 0; band < this.spectrumBands.length; band++) {\n if (band >= maxBand) {\n this.spectrumBands[band] = magnitudeToDb(0);\n continue;\n }\n const bin = band + 1;\n let real = 0;\n let imag = 0;\n for (let i = 0; i < n; i++) {\n const sample = 0.5 * ((left[i] ?? 0) + (right[i] ?? 0));\n const phase = (-2 * Math.PI * bin * i) / n;\n real += sample * Math.cos(phase);\n imag += sample * Math.sin(phase);\n }\n this.spectrumBands[band] = magnitudeToDb((2 * Math.hypot(real, imag)) / n);\n }\n }\n\n private writeSpectrumRing(frame: number, bands: Float32Array): void {\n const ring = this.spectrumRing;\n if (!ring) {\n return;\n }\n const writeIndex = Atomics.load(ring.header, 0);\n const offset = (writeIndex % ring.capacity) * ring.recordFloats;\n ring.records[offset] = encodeFrameLo(frame);\n ring.records[offset + 1] = encodeFrameHi(frame);\n ring.records[offset + 2] = bands.length;\n ring.records.set(bands.subarray(0, ring.bands), offset + 3);\n Atomics.store(ring.header, 0, writeIndex + 1);\n // See writeMeterRing: header slot 4 (the spectrum-ring overflow slot) is\n // left at its initial 0; readers detect silent overrun via the\n // firstReadable = max(readIndex, writeIndex - capacity) clamp. (Slot 3 here\n // holds the band count and is still written at ring creation.)\n }\n}\n\n/**\n * AudioWorklet-style bridge for the DAW realtime engine facade.\n *\n * The default mode uses the existing `sonare.wasm` embind facade. The\n * `sonare-rt` target is exposed as a selectable runtime target for hosts that\n * load the dedicated Emscripten AudioWorklet module.\n */\nexport class SonareRealtimeEngineWorkletProcessor {\n private static warnedChannelScratchOverflow = false;\n readonly sampleRate: number;\n readonly blockSize: number;\n readonly channelCount: number;\n readonly runtimeTarget: 'embind' | 'sonare-rt';\n private engine: RealtimeEngine;\n private closed = false;\n private commandRing?: SonareEngineCommandRingBuffer;\n private telemetryRing?: SonareEngineTelemetryRingBuffer;\n private meterRing?: SharedMeterRingWriter;\n private scopeRing?: SharedScopeRingWriter;\n private transport?: WorkletTransport;\n private meterIntervalFrames: number;\n private lastMeterFrame = Number.NEGATIVE_INFINITY;\n // Latest metronome gains/click length pushed via 'syncMetronome'. The\n // SetMetronome command only toggles enabled state; the config arrives here.\n private metronomeConfig: ResolvedMetronomeConfig = { ...DEFAULT_METRONOME_CONFIG };\n // Zero-copy prepared realtime path: persistent per-channel views onto the\n // engine's WASM-heap scratch (acquired once on the main thread via\n // getChannelBuffer). process() writes the AudioWorklet input straight into\n // these views, calls engine.processPrepared(frames) which runs the engine IN\n // PLACE, then reads the same views back — no std::vector or JS Float32Array is\n // allocated per render quantum (the old engine.process() round-tripped fresh\n // arrays on both heaps every block, an RT-safety hazard).\n private channelBuffers: Float32Array[];\n private readonly liveClips = new Map<number, EngineClip>();\n\n constructor(\n options: SonareRealtimeEngineWorkletProcessorOptions = {},\n transport?: WorkletTransport,\n ) {\n this.sampleRate = options.sampleRate ?? 48000;\n this.blockSize = options.blockSize ?? 128;\n this.channelCount = Math.max(1, Math.floor(options.channelCount ?? 2));\n this.runtimeTarget = options.runtimeTarget ?? 'embind';\n if (this.runtimeTarget === 'sonare-rt') {\n throw new Error(\n 'sonare-rt runtime is provided by the dedicated Emscripten AudioWorklet module; use SonareRealtimeEngineNode.create({ runtimeTarget: \"sonare-rt\", moduleUrl: ... }) to load it.',\n );\n }\n this.transport = transport;\n this.meterIntervalFrames = Math.max(0, Math.floor(options.meterIntervalFrames ?? 2048));\n this.commandRing = options.commandSharedBuffer\n ? this.commandRingFromSharedBuffer(options.commandSharedBuffer, options.commandRingCapacity)\n : undefined;\n this.telemetryRing = options.telemetrySharedBuffer\n ? this.telemetryRingFromSharedBuffer(\n options.telemetrySharedBuffer,\n options.telemetryRingCapacity,\n )\n : undefined;\n this.meterRing = options.meterSharedBuffer\n ? meterRingFromSharedBuffer(options.meterSharedBuffer, options.meterRingCapacity)\n : undefined;\n this.scopeRing = options.scopeSharedBuffer\n ? scopeRingFromSharedBuffer(\n options.scopeSharedBuffer,\n options.scopeRingCapacity,\n options.scopeBands,\n )\n : undefined;\n this.engine = new RealtimeEngine(this.sampleRate, this.blockSize);\n // Allocate persistent WASM-heap scratch (worst case: channelCount channels x\n // blockSize frames) and acquire the per-channel heap views once.\n this.engine.prepareChannels(this.channelCount, this.blockSize);\n this.channelBuffers = new Array(this.channelCount);\n for (let ch = 0; ch < this.channelCount; ch++) {\n this.channelBuffers[ch] = this.engine.getChannelBuffer(ch, this.blockSize);\n }\n // Arm the engine's scope producer only when a scope ring was provided. The\n // band count follows the ring's record layout so writeScopeRing never\n // overruns its slot.\n if (this.scopeRing) {\n const interval = Math.max(1, Math.floor(options.scopeIntervalFrames ?? this.blockSize));\n this.engine.configureScopeTelemetry(interval, this.scopeRing.bands);\n }\n }\n\n process(inputs: WorkletInput, outputs: WorkletOutput): boolean {\n if (this.closed) {\n return false;\n }\n const output = outputs[0];\n const firstOutput = output?.[0];\n if (!firstOutput) {\n return true;\n }\n const frames = firstOutput.length;\n if (frames > this.blockSize) {\n for (const channel of output ?? []) {\n channel.fill(0);\n }\n this.publishTelemetry();\n return true;\n }\n\n this.drainCommands();\n\n // Clamp `frames` to the pre-allocated scratch capacity. The earlier\n // `frames > this.blockSize` branch already returns early, so this is\n // defensive — but we warn once if it ever fires so the contract violation\n // is visible.\n let usableFrames = frames;\n if (usableFrames > this.blockSize) {\n if (!SonareRealtimeEngineWorkletProcessor.warnedChannelScratchOverflow) {\n SonareRealtimeEngineWorkletProcessor.warnedChannelScratchOverflow = true;\n // biome-ignore lint/suspicious/noConsole: realtime-safety diagnostic.\n console.warn(\n `SonareRealtimeEngineWorkletProcessor: requested ${usableFrames} frames ` +\n `exceeds pre-allocated capacity ${this.blockSize}; clamping.`,\n );\n }\n usableFrames = this.blockSize;\n }\n\n // Defend against WASM linear-memory growth detaching the cached heap views:\n // if any view's backing ArrayBuffer has been detached (byteLength === 0),\n // re-acquire all of them. This is a control-flow check (no allocation in the\n // common case where memory did not grow).\n if ((this.channelBuffers[0]?.byteLength ?? 0) === 0) {\n this.reacquireChannelBuffers();\n }\n\n const input = inputs[0];\n // Write the AudioWorklet input straight into the engine's WASM-heap views;\n // no per-block heap allocation.\n for (let ch = 0; ch < this.channelCount; ch++) {\n const dst = this.channelBuffers[ch];\n const source = input?.[ch];\n if (source && source.length === usableFrames) {\n dst.set(source.subarray(0, usableFrames));\n } else {\n dst.fill(0, 0, usableFrames);\n }\n }\n\n // Run the engine in place over the prepared scratch (allocation-free).\n this.engine.processPrepared(usableFrames);\n\n for (let ch = 0; ch < output.length; ch++) {\n const target = output[ch];\n const source = this.channelBuffers[ch] ?? this.channelBuffers[0];\n if (source) {\n target.set(source.subarray(0, Math.min(target.length, usableFrames)));\n if (target.length > usableFrames) {\n target.fill(0, usableFrames);\n }\n } else {\n target.fill(0);\n }\n }\n this.publishTelemetry();\n this.publishMeters();\n this.publishScope();\n return true;\n }\n\n private reacquireChannelBuffers(): void {\n for (let ch = 0; ch < this.channelCount; ch++) {\n this.channelBuffers[ch] = this.engine.getChannelBuffer(ch, this.blockSize);\n }\n }\n\n receiveCommand(command: SonareEngineCommandRecord): void {\n if (!this.closed) {\n this.applyCommand(command);\n }\n }\n\n // Applies an out-of-band control-plane sync message. Runs on the AudioWorklet\n // global scope but OUTSIDE process() (the message-port callback), so the\n // bulk/allocating engine setters (setClips/setMarkers) are safe here — they\n // never run on the realtime render path. This is the audio-thread equivalent\n // of the engine's control-thread RtPublisher setters.\n receiveSync(message: SonareEngineSyncMessage): void {\n if (this.closed) {\n return;\n }\n switch (message.type) {\n case 'syncClips':\n this.liveClips.clear();\n for (const clip of message.clips) {\n if (clip.id !== undefined) {\n this.liveClips.set(clip.id, clip);\n }\n }\n this.engine.setClips(message.clips);\n break;\n case 'syncClipsDelta':\n for (const clipId of message.removeIds) {\n this.liveClips.delete(clipId);\n }\n for (const clip of message.upserts) {\n if (clip.id !== undefined) {\n this.liveClips.set(clip.id, clip);\n }\n }\n this.engine.setClips(Array.from(this.liveClips.values()));\n break;\n case 'syncMidiClips':\n this.engine.setMidiClips(message.clips);\n break;\n case 'syncMarkers':\n this.engine.setMarkers(message.markers);\n break;\n case 'syncMetronome':\n this.metronomeConfig = resolveMetronomeConfig(message.config);\n this.engine.setMetronome(message.config);\n break;\n case 'syncAutomation':\n this.engine.setAutomationLane(message.paramId, message.points);\n break;\n case 'syncTempo':\n if (message.tempoSegments) {\n this.engine.setTempoSegments(message.tempoSegments);\n } else {\n this.engine.setTempo(message.bpm);\n }\n if (message.timeSignatureSegments) {\n this.engine.setTimeSignatureSegments(message.timeSignatureSegments);\n } else {\n this.engine.setTimeSignature(\n message.timeSignature.numerator,\n message.timeSignature.denominator,\n );\n }\n break;\n case 'syncMixer':\n if (message.buses) {\n this.engine.setTrackBuses(message.buses);\n }\n this.engine.setTrackLanes(message.lanes);\n for (const strip of message.trackStrips ?? []) {\n this.engine.setTrackStripJson(strip.trackId, strip.sceneJson);\n }\n for (const strip of message.busStrips ?? []) {\n this.engine.setBusStripJson(strip.busId, strip.sceneJson);\n }\n if (message.masterStripJson) {\n this.engine.setMasterStripJson(message.masterStripJson);\n }\n for (const binding of message.laneSidechains ?? []) {\n this.engine.setLaneSidechain(binding.trackId, binding.insertIndex, binding.sourceTrackId);\n }\n break;\n case 'syncCapture':\n this.engine.setCaptureBuffer(message.channels, message.bufferFrames);\n this.engine.setCaptureSource(message.source);\n this.engine.setRecordOffsetSamples(message.recordOffsetSamples);\n this.engine.setInputMonitor(message.inputMonitor.enabled, message.inputMonitor.gain);\n break;\n case 'syncTrackStripEqBand':\n this.engine.setTrackStripEqBandJson(message.trackId, message.bandIndex, message.bandJson);\n break;\n case 'syncMasterStripEqBand':\n this.engine.setMasterStripEqBandJson(message.bandIndex, message.bandJson);\n break;\n case 'syncTrackStripInsertBypassed':\n this.engine.setTrackStripInsertBypassed(\n message.trackId,\n message.insertIndex,\n message.bypassed,\n message.resetOnBypass,\n );\n break;\n case 'syncMasterStripInsertBypassed':\n this.engine.setMasterStripInsertBypassed(\n message.insertIndex,\n message.bypassed,\n message.resetOnBypass,\n );\n break;\n case 'syncTrackStripInsertParamByName':\n this.engine.setTrackStripInsertParamByName(\n message.trackId,\n message.insertIndex,\n message.paramName,\n message.value,\n );\n break;\n case 'syncMasterStripInsertParamByName':\n this.engine.setMasterStripInsertParamByName(\n message.insertIndex,\n message.paramName,\n message.value,\n );\n break;\n case 'syncTrackStripPan':\n this.engine.setTrackStripPan(message.trackId, message.pan);\n break;\n case 'syncTrackStripPanLaw':\n this.engine.setTrackStripPanLaw(message.trackId, message.panLaw);\n break;\n case 'syncTrackStripPanMode':\n this.engine.setTrackStripPanMode(message.trackId, message.panMode);\n break;\n case 'syncTrackStripDualPan':\n this.engine.setTrackStripDualPan(message.trackId, message.leftPan, message.rightPan);\n break;\n case 'syncTrackStripChannelDelaySamples':\n this.engine.setTrackStripChannelDelaySamples(message.trackId, message.delaySamples);\n break;\n case 'syncBuiltinInstrument':\n this.engine.setBuiltinInstrument(message.config, message.destinationId);\n break;\n case 'syncSynthInstrument':\n this.engine.setSynthInstrument(message.patch, message.destinationId);\n break;\n case 'syncLoadSoundFont':\n this.engine.loadSoundFont(message.data);\n break;\n case 'syncSf2Instrument':\n this.engine.setSf2Instrument(message.config, message.destinationId);\n break;\n case 'syncMidiNoteOn':\n this.engine.pushMidiNoteOn(\n message.destinationId,\n message.group,\n message.channel,\n message.note,\n message.velocity,\n message.renderFrame,\n );\n break;\n case 'syncMidiNoteOff':\n this.engine.pushMidiNoteOff(\n message.destinationId,\n message.group,\n message.channel,\n message.note,\n message.velocity,\n message.renderFrame,\n );\n break;\n case 'syncMidiCc':\n this.engine.pushMidiCc(\n message.destinationId,\n message.group,\n message.channel,\n message.controller,\n message.value,\n message.renderFrame,\n );\n break;\n case 'syncMidiPanic':\n this.engine.pushMidiPanic(message.renderFrame);\n break;\n }\n }\n\n receiveCaptureRequest(message: SonareEngineCaptureRequestMessage): void {\n if (this.closed) {\n return;\n }\n try {\n if (message.op === 'status') {\n const status = this.engine.captureStatus();\n this.transport?.postMessage?.({\n type: 'captureResponse',\n requestId: message.requestId,\n ok: true,\n status: {\n capturedFrames: status.capturedFrames,\n overflowCount: status.overflowCount,\n armed: status.armed,\n punchEnabled: status.punchEnabled,\n source: status.source,\n recordOffsetSamples: status.recordOffsetSamples,\n },\n } satisfies SonareEngineCaptureResponseMessage);\n return;\n }\n if (message.op === 'read') {\n const captured = this.engine.capturedAudio();\n const channels: number[][] = [];\n for (let ch = 0; ch < captured.length; ch++) {\n const source = captured[ch];\n const copy: number[] = [];\n for (let i = 0; i < source.length; i++) {\n copy.push(Number(source[i]));\n }\n channels.push(copy);\n }\n this.transport?.postMessage?.({\n type: 'captureResponse',\n requestId: message.requestId,\n ok: true,\n channels,\n } satisfies SonareEngineCaptureResponseMessage);\n return;\n }\n this.engine.resetCapture();\n this.transport?.postMessage?.({\n type: 'captureResponse',\n requestId: message.requestId,\n ok: true,\n } satisfies SonareEngineCaptureResponseMessage);\n } catch (error) {\n this.transport?.postMessage?.({\n type: 'captureResponse',\n requestId: message.requestId,\n ok: false,\n error: error instanceof Error ? error.message : String(error),\n } satisfies SonareEngineCaptureResponseMessage);\n }\n }\n\n receiveTransportRequest(message: SonareEngineTransportRequestMessage): void {\n if (this.closed) {\n return;\n }\n try {\n this.transport?.postMessage?.({\n type: 'transportResponse',\n requestId: message.requestId,\n ok: true,\n state: this.engine.getTransportState(),\n } satisfies SonareEngineTransportResponseMessage);\n } catch (error) {\n this.transport?.postMessage?.({\n type: 'transportResponse',\n requestId: message.requestId,\n ok: false,\n error: error instanceof Error ? error.message : String(error),\n } satisfies SonareEngineTransportResponseMessage);\n }\n }\n\n destroy(): void {\n if (!this.closed) {\n this.engine.destroy();\n this.closed = true;\n }\n }\n\n private drainCommands(): void {\n if (!this.commandRing) {\n return;\n }\n for (let i = 0; i < 64; i++) {\n const command = popSonareEngineCommandRingBuffer(this.commandRing);\n if (!command) {\n return;\n }\n this.applyCommand(command);\n }\n }\n\n private applyCommand(command: SonareEngineCommandRecord): void {\n const sampleTime = Number(command.sampleTime ?? -1);\n switch (command.type) {\n case SonareEngineCommandType.SetParam:\n // paramId is carried in targetId, the new value in argFloat (matches the\n // SonareEngine.setParam producer). sampleTime is the render frame.\n this.engine.setParameter(\n Math.trunc(Number(command.targetId ?? 0)),\n Number(command.argFloat ?? 0),\n sampleTime,\n );\n break;\n case SonareEngineCommandType.SetParamSmoothed:\n this.engine.setParameterSmoothed(\n Math.trunc(Number(command.targetId ?? 0)),\n Number(command.argFloat ?? 0),\n sampleTime,\n );\n break;\n case SonareEngineCommandType.TransportPlay:\n this.engine.play(sampleTime);\n break;\n case SonareEngineCommandType.TransportStop:\n this.engine.stop(sampleTime);\n break;\n case SonareEngineCommandType.TransportSeekSample:\n this.engine.seekSample(Number(command.argInt ?? 0), sampleTime);\n break;\n case SonareEngineCommandType.TransportSeekPpq:\n this.engine.seekPpq(Number(command.argFloat ?? 0), sampleTime);\n break;\n case SonareEngineCommandType.SetTempoMap:\n this.engine.setTempo(Number(command.argFloat ?? 120));\n break;\n case SonareEngineCommandType.SetLoop:\n this.engine.setLoop(\n Number(command.argFloat ?? 0),\n Number(command.argInt ?? 0) / 1_000_000,\n command.targetId !== 0,\n );\n break;\n case SonareEngineCommandType.ArmRecord:\n this.engine.armCapture(Boolean(command.argInt));\n break;\n case SonareEngineCommandType.Punch:\n // Both endpoints already arrive as samples (see SonareEngine.punch);\n // do NOT re-scale by sampleRate.\n this.engine.setCapturePunch(\n Number(command.argInt ?? 0),\n Math.max(0, Math.round(Number(command.argFloat ?? 0))),\n true,\n );\n break;\n case SonareEngineCommandType.SetMetronome:\n // Metronome config (beatGain/accentGain/clickSamples/clickSeconds) is\n // delivered out-of-band via the 'syncMetronome' message so it carries\n // the caller's full config; the command only toggles enabled state as a\n // sample-aligned fallback.\n this.engine.setMetronome({\n enabled: Boolean(command.argInt),\n beatGain: this.metronomeConfig.beatGain,\n accentGain: this.metronomeConfig.accentGain,\n clickSamples: this.metronomeConfig.clickSamples,\n });\n break;\n case SonareEngineCommandType.SeekMarker:\n // The realtime engine's markers are kept in sync via 'syncMarkers'\n // (RtPublisher-style swap), so a queued kSeekMarker resolves correctly.\n this.engine.seekMarker(Math.trunc(Number(command.targetId ?? 0)), sampleTime);\n break;\n case SonareEngineCommandType.SetSoloMute:\n this.engine.setSoloMute(\n Math.trunc(Number(command.targetId ?? 0)),\n Boolean((Number(command.argInt ?? 0) & 0x2) !== 0),\n Boolean((Number(command.argInt ?? 0) & 0x1) !== 0),\n sampleTime,\n );\n break;\n default:\n this.publishTelemetryRecord({\n type: SonareEngineTelemetryType.Error,\n error: SonareEngineTelemetryError.UnknownTarget,\n renderFrame: 0,\n timelineSample: 0,\n audibleTimelineSample: 0,\n graphLatencySamplesQ8: 0,\n value: Number(command.type),\n });\n break;\n }\n }\n\n private publishTelemetry(): void {\n for (const item of this.engine.drainTelemetry(64)) {\n this.publishTelemetryRecord(telemetryFromEngine(item));\n }\n }\n\n private publishTelemetryRecord(record: SonareEngineTelemetryRecord): void {\n if (this.telemetryRing) {\n writeSonareEngineTelemetryRingBuffer(this.telemetryRing, record);\n return;\n }\n this.transport?.postMessage?.(record);\n }\n\n // Drains the engine meter telemetry queue into the stereo meter ring / transport.\n //\n // Shared-queue contract: `drainMeterTelemetry` and `drainMeterTelemetryWide`\n // pop the SAME single-consumer telemetry queue, so exactly ONE of them may run\n // per engine. The live worklet path owns the queue via the stereo drain below;\n // the worklet meter ring (SONARE_METER_RING_RECORD_FLOATS) is a fixed stereo\n // layout carrying planes 0/1 plus the correlation/LUFS summary. Per-plane\n // surround meters are NOT delivered over the live worklet ring — a host that\n // needs them must use the offline `drainMeterTelemetryWide()` API on a\n // non-worklet engine instance (do not also call it on a worklet-driven engine,\n // or the two drains will starve each other).\n private publishMeters(): void {\n if (this.meterIntervalFrames <= 0 || (!this.transport && !this.meterRing)) {\n return;\n }\n for (const item of this.engine.drainMeterTelemetry(64)) {\n const meter = meterFromEngine(item);\n if (\n meter.frame !== this.lastMeterFrame &&\n meter.frame - this.lastMeterFrame < this.meterIntervalFrames\n ) {\n continue;\n }\n if (meter.frame !== this.lastMeterFrame) {\n this.lastMeterFrame = meter.frame;\n }\n // Prefer the lock-free SAB meter ring (matching the telemetry path and\n // SonareWorkletProcessor); only fall back to structured-clone postMessage\n // when no ring was provided, so we do not allocate/post from the audio\n // render callback in SAB mode.\n if (this.meterRing) {\n this.writeMeterRing(meter);\n } else {\n this.transport?.onMeter?.(meter);\n this.transport?.postMessage?.(meter);\n }\n }\n }\n\n private writeMeterRing(meter: SonareWorkletMeterSnapshot): void {\n const ring = this.meterRing;\n if (!ring) {\n return;\n }\n const writeIndex = Atomics.load(ring.header, 0);\n const offset = (writeIndex % ring.capacity) * SONARE_METER_RING_RECORD_FLOATS;\n ring.records[offset] = encodeFrameLo(meter.frame);\n ring.records[offset + 1] = encodeFrameHi(meter.frame);\n ring.records[offset + 2] = meter.targetId;\n ring.records[offset + 3] = meter.peakDbL;\n ring.records[offset + 4] = meter.peakDbR;\n ring.records[offset + 5] = meter.rmsDbL;\n ring.records[offset + 6] = meter.rmsDbR;\n ring.records[offset + 7] = meter.correlation;\n ring.records[offset + 8] = meter.truePeakDbL;\n ring.records[offset + 9] = meter.truePeakDbR;\n ring.records[offset + 10] = meter.momentaryLufs;\n ring.records[offset + 11] = meter.shortTermLufs;\n ring.records[offset + 12] = meter.integratedLufs;\n ring.records[offset + 13] = meter.gainReductionDb;\n Atomics.store(ring.header, 0, writeIndex + 1);\n // writeIndex is a free-running monotonic counter, so an overflow guard here\n // would fire on essentially every write past the first `capacity` records\n // and store an ever-growing value, not a dropped-record count. Readers\n // already detect silent overrun via firstReadable = max(readIndex,\n // writeIndex - capacity), so header slot 3 is left at its initial 0.\n }\n\n // Drains the engine's scope producer (FFT spectrum + goniometer points) into\n // the lock-free SAB scope ring. Only the embind runtime publishes scope\n // telemetry; the sonare-rt runtime owns its own transport. No allocation on\n // the render path: records are written field-by-field into the ring.\n private publishScope(): void {\n const ring = this.scopeRing;\n if (!ring) {\n return;\n }\n for (const item of this.engine.drainScopeTelemetry(64)) {\n this.writeScopeRing(ring, item);\n }\n }\n\n private writeScopeRing(ring: SharedScopeRingWriter, record: EngineScopeTelemetry): void {\n const writeIndex = Atomics.load(ring.header, 0);\n const base = (writeIndex % ring.capacity) * ring.recordFloats;\n ring.records[base] = encodeFrameLo(record.renderFrame);\n ring.records[base + 1] = encodeFrameHi(record.renderFrame);\n ring.records[base + 2] = record.targetId;\n const bandCount = Math.min(ring.bands, record.bands.length);\n ring.records[base + 3] = bandCount;\n const pointCount = Math.min(ring.maxPoints, record.points.length);\n ring.records[base + 4] = pointCount;\n const bandsBase = base + SONARE_SCOPE_RING_RECORD_PREFIX_FLOATS;\n for (let i = 0; i < bandCount; i++) {\n ring.records[bandsBase + i] = record.bands[i];\n }\n const pointsBase = bandsBase + ring.bands;\n for (let i = 0; i < pointCount; i++) {\n const point = record.points[i];\n ring.records[pointsBase + 2 * i] = point.left;\n ring.records[pointsBase + 2 * i + 1] = point.right;\n }\n Atomics.store(ring.header, 0, writeIndex + 1);\n // Like writeMeterRing, writeIndex is a free-running monotonic counter; the\n // reader detects silent overrun via firstReadable, so the overflow slot\n // (header[5]) stays at its initial 0.\n }\n\n private commandRingFromSharedBuffer(\n sharedBuffer: SharedArrayBuffer,\n fallbackCapacity?: number,\n ): SonareEngineCommandRingBuffer {\n const ring = engineRingFromSharedBuffer(\n sharedBuffer,\n SONARE_ENGINE_COMMAND_RECORD_BYTES,\n fallbackCapacity,\n );\n return { sharedBuffer, header: ring.header, view: ring.view, capacity: ring.capacity };\n }\n\n private telemetryRingFromSharedBuffer(\n sharedBuffer: SharedArrayBuffer,\n fallbackCapacity?: number,\n ): SonareEngineTelemetryRingBuffer {\n const ring = engineRingFromSharedBuffer(\n sharedBuffer,\n SONARE_ENGINE_TELEMETRY_RECORD_BYTES,\n fallbackCapacity,\n );\n return { sharedBuffer, header: ring.header, view: ring.view, capacity: ring.capacity };\n }\n}\n\nexport class SonareRtRealtimeEngineRuntime {\n readonly sampleRate: number;\n readonly blockSize: number;\n readonly channelCount: number;\n private readonly module: SonareRtModule;\n private readonly memory: WebAssembly.Memory;\n private readonly engine: number;\n private readonly channelPointerTable: number;\n private readonly channelBuffers: number[];\n private readonly telemetryIntsPtr: number;\n private readonly telemetryFramesPtr: number;\n private readonly commandRing?: SonareEngineCommandRingBuffer;\n private readonly telemetryRing?: SonareEngineTelemetryRingBuffer;\n private metronomeConfig: ResolvedMetronomeConfig = { ...DEFAULT_METRONOME_CONFIG };\n private closed = false;\n\n constructor(options: SonareRtRealtimeEngineRuntimeOptions) {\n this.module = options.module;\n this.memory = options.memory;\n this.sampleRate = options.sampleRate ?? 48000;\n this.blockSize = options.blockSize ?? 128;\n this.channelCount = Math.max(1, Math.floor(options.channelCount ?? 2));\n this.commandRing = options.commandSharedBuffer\n ? this.commandRingFromSharedBuffer(options.commandSharedBuffer, options.commandRingCapacity)\n : undefined;\n this.telemetryRing = options.telemetrySharedBuffer\n ? this.telemetryRingFromSharedBuffer(\n options.telemetrySharedBuffer,\n options.telemetryRingCapacity,\n )\n : undefined;\n\n this.engine = this.module._sonare_rt_engine_create();\n if (this.engine <= 0) {\n throw new Error('failed to create sonare-rt engine');\n }\n if (\n this.module._sonare_rt_engine_prepare(\n this.engine,\n this.sampleRate,\n this.blockSize,\n 1024,\n 1024,\n ) !== 1\n ) {\n this.module._sonare_rt_engine_destroy(this.engine);\n throw new Error('failed to prepare sonare-rt engine');\n }\n this.channelPointerTable = this.module._malloc(\n this.channelCount * Uint32Array.BYTES_PER_ELEMENT,\n );\n this.channelBuffers = [];\n for (let ch = 0; ch < this.channelCount; ch++) {\n this.channelBuffers.push(\n this.module._malloc(this.blockSize * Float32Array.BYTES_PER_ELEMENT),\n );\n }\n this.telemetryIntsPtr = this.module._malloc(64 * 4 * Int32Array.BYTES_PER_ELEMENT);\n this.telemetryFramesPtr = this.module._malloc(64 * 3 * Float64Array.BYTES_PER_ELEMENT);\n this.writeChannelPointers();\n }\n\n process(inputs: WorkletInput, outputs: WorkletOutput): boolean {\n if (this.closed) {\n return false;\n }\n const output = outputs[0];\n const firstOutput = output?.[0];\n if (!firstOutput) {\n return true;\n }\n const frames = firstOutput.length;\n if (frames > this.blockSize) {\n for (const channel of output) {\n channel.fill(0);\n }\n return true;\n }\n\n this.drainCommands();\n const heap = new Float32Array(this.memory.buffer);\n const input = inputs[0];\n for (let ch = 0; ch < this.channelCount; ch++) {\n const ptr = this.channelBuffers[ch] ?? this.channelBuffers[0];\n const offset = ptr >> 2;\n const source = input?.[ch];\n if (source && source.length === frames) {\n heap.set(source, offset);\n } else {\n heap.fill(0, offset, offset + frames);\n }\n }\n\n this.module._sonare_rt_engine_process(\n this.engine,\n this.channelPointerTable,\n this.channelCount,\n frames,\n );\n\n for (let ch = 0; ch < output.length; ch++) {\n const target = output[ch];\n const ptr = this.channelBuffers[ch] ?? this.channelBuffers[0];\n target.set(heap.subarray(ptr >> 2, (ptr >> 2) + target.length));\n }\n this.publishTelemetry();\n return true;\n }\n\n receiveCommand(command: SonareEngineCommandRecord): void {\n if (!this.closed) {\n this.applyCommand(command);\n }\n }\n\n // Out-of-band control sync for the sonare-rt runtime. The sonare-rt C ABI\n // (src/wasm/rt_bindings.cpp) exposes set_metronome_enabled and seek_marker but\n // NOT set_clips / set_markers, so clip/marker mutations cannot be applied to a\n // live sonare-rt engine. We honor the metronome config and surface a clear\n // telemetry error for the unsupported clip/marker paths instead of silently\n // dropping them. The default 'embind' runtime wires all three fully.\n receiveSync(message: SonareEngineSyncMessage): void {\n if (this.closed) {\n return;\n }\n switch (message.type) {\n case 'syncMetronome':\n this.metronomeConfig = resolveMetronomeConfig(message.config);\n this.module._sonare_rt_engine_set_metronome_enabled(\n this.engine,\n message.config.enabled ? 1 : 0,\n this.metronomeConfig.beatGain,\n this.metronomeConfig.accentGain,\n this.metronomeConfig.clickSamples,\n );\n break;\n case 'syncTempo':\n this.module._sonare_rt_engine_set_tempo(this.engine, message.bpm);\n break;\n case 'syncClips':\n case 'syncClipsDelta':\n case 'syncMidiClips':\n case 'syncMarkers':\n case 'syncAutomation':\n case 'syncMixer':\n case 'syncCapture':\n case 'syncTrackStripEqBand':\n case 'syncMasterStripEqBand':\n case 'syncTrackStripInsertBypassed':\n case 'syncMasterStripInsertBypassed':\n case 'syncBuiltinInstrument':\n case 'syncSynthInstrument':\n case 'syncSf2Instrument':\n case 'syncLoadSoundFont':\n case 'syncMidiNoteOn':\n case 'syncMidiNoteOff':\n case 'syncMidiCc':\n case 'syncMidiPanic':\n // The sonare-rt C ABI exposes no set_clips / set_markers /\n // set_automation_lane / set_track_lanes, so these mutations cannot\n // reach a live sonare-rt engine. Surface a clear telemetry error rather\n // than silently dropping.\n if (this.telemetryRing) {\n writeSonareEngineTelemetryRingBuffer(this.telemetryRing, {\n type: SonareEngineTelemetryType.Error,\n error: SonareEngineTelemetryError.UnknownTarget,\n renderFrame: 0,\n timelineSample: 0,\n audibleTimelineSample: 0,\n graphLatencySamplesQ8: 0,\n value: 0,\n });\n }\n break;\n }\n }\n\n receiveCaptureRequest(message: SonareEngineCaptureRequestMessage, port?: WorkletPort): void {\n if (this.closed) {\n return;\n }\n port?.postMessage?.({\n type: 'captureResponse',\n requestId: message.requestId,\n ok: false,\n error: 'Capture read-back is not supported by the sonare-rt runtime.',\n } satisfies SonareEngineCaptureResponseMessage);\n }\n\n receiveTransportRequest(message: SonareEngineTransportRequestMessage, port?: WorkletPort): void {\n if (this.closed) {\n return;\n }\n port?.postMessage?.({\n type: 'transportResponse',\n requestId: message.requestId,\n ok: false,\n error: 'Transport state read-back is not supported by the sonare-rt runtime.',\n } satisfies SonareEngineTransportResponseMessage);\n }\n\n destroy(): void {\n if (this.closed) {\n return;\n }\n this.module._free(this.telemetryFramesPtr);\n this.module._free(this.telemetryIntsPtr);\n for (const ptr of this.channelBuffers) {\n this.module._free(ptr);\n }\n this.module._free(this.channelPointerTable);\n this.module._sonare_rt_engine_destroy(this.engine);\n this.closed = true;\n }\n\n private writeChannelPointers(): void {\n const pointers = new Uint32Array(this.memory.buffer);\n const offset = this.channelPointerTable >> 2;\n for (let ch = 0; ch < this.channelBuffers.length; ch++) {\n pointers[offset + ch] = this.channelBuffers[ch];\n }\n }\n\n private drainCommands(): void {\n if (!this.commandRing) {\n return;\n }\n for (let i = 0; i < 64; i++) {\n const command = popSonareEngineCommandRingBuffer(this.commandRing);\n if (!command) {\n return;\n }\n this.applyCommand(command);\n }\n }\n\n private applyCommand(command: SonareEngineCommandRecord): void {\n const sampleTime = toBigInt64(command.sampleTime, -1n);\n switch (command.type) {\n case SonareEngineCommandType.SetParam:\n case SonareEngineCommandType.SetParamSmoothed:\n // The sonare-rt C ABI (src/wasm/rt_bindings.cpp) does not export a\n // sonare_rt_engine_set_param entry point, so parameter automation has no\n // realtime transport on this runtime target. Surface a clear error\n // telemetry record (rather than silently dropping the command) so hosts\n // can detect the unsupported path; the embind runtime fully wires this.\n if (this.telemetryRing) {\n writeSonareEngineTelemetryRingBuffer(this.telemetryRing, {\n type: SonareEngineTelemetryType.Error,\n error: SonareEngineTelemetryError.UnknownTarget,\n renderFrame: 0,\n timelineSample: 0,\n audibleTimelineSample: 0,\n graphLatencySamplesQ8: 0,\n value: Number(command.type),\n });\n }\n break;\n case SonareEngineCommandType.TransportPlay:\n this.module._sonare_rt_engine_play(this.engine, sampleTime);\n break;\n case SonareEngineCommandType.TransportStop:\n this.module._sonare_rt_engine_stop(this.engine, sampleTime);\n break;\n case SonareEngineCommandType.TransportSeekSample:\n this.module._sonare_rt_engine_seek_sample(\n this.engine,\n toBigInt64(command.argInt, 0n),\n sampleTime,\n );\n break;\n case SonareEngineCommandType.TransportSeekPpq:\n this.module._sonare_rt_engine_seek_ppq(\n this.engine,\n Number(command.argFloat ?? 0),\n sampleTime,\n );\n break;\n case SonareEngineCommandType.SetTempoMap:\n this.module._sonare_rt_engine_set_tempo(this.engine, Number(command.argFloat ?? 120));\n break;\n case SonareEngineCommandType.SetLoop:\n this.module._sonare_rt_engine_set_loop(\n this.engine,\n Number(command.argFloat ?? 0),\n Number(command.argInt ?? 0) / 1_000_000,\n command.targetId ? 1 : 0,\n );\n break;\n case SonareEngineCommandType.ArmRecord:\n this.module._sonare_rt_engine_set_capture_armed(this.engine, command.argInt ? 1 : 0);\n break;\n case SonareEngineCommandType.Punch:\n // Both endpoints already arrive as samples (see SonareEngine.punch);\n // do NOT re-scale by sampleRate.\n this.module._sonare_rt_engine_set_capture_punch(\n this.engine,\n toBigInt64(command.argInt, 0n),\n BigInt(Math.max(0, Math.round(Number(command.argFloat ?? 0)))),\n 1,\n );\n break;\n case SonareEngineCommandType.SetMetronome:\n this.module._sonare_rt_engine_set_metronome_enabled(\n this.engine,\n command.argInt ? 1 : 0,\n this.metronomeConfig.beatGain,\n this.metronomeConfig.accentGain,\n this.metronomeConfig.clickSamples,\n );\n break;\n case SonareEngineCommandType.SeekMarker:\n this.module._sonare_rt_engine_seek_marker(\n this.engine,\n Math.trunc(command.targetId ?? 0),\n sampleTime,\n );\n break;\n default:\n if (this.telemetryRing) {\n writeSonareEngineTelemetryRingBuffer(this.telemetryRing, {\n type: SonareEngineTelemetryType.Error,\n error: SonareEngineTelemetryError.UnknownTarget,\n renderFrame: 0,\n timelineSample: 0,\n audibleTimelineSample: 0,\n graphLatencySamplesQ8: 0,\n value: Number(command.type),\n });\n }\n break;\n }\n }\n\n private publishTelemetry(): void {\n if (!this.telemetryRing) {\n this.module._sonare_rt_engine_drain_telemetry(\n this.engine,\n this.telemetryIntsPtr,\n this.telemetryFramesPtr,\n 64,\n );\n return;\n }\n const count = this.module._sonare_rt_engine_drain_telemetry(\n this.engine,\n this.telemetryIntsPtr,\n this.telemetryFramesPtr,\n 64,\n );\n const ints = new Int32Array(this.memory.buffer);\n const frames = new Float64Array(this.memory.buffer);\n const intBase = this.telemetryIntsPtr >> 2;\n const frameBase = this.telemetryFramesPtr >> 3;\n for (let i = 0; i < count; i++) {\n writeSonareEngineTelemetryRingBuffer(this.telemetryRing, {\n type: ints[intBase + i * 4],\n error: ints[intBase + i * 4 + 1],\n renderFrame: frames[frameBase + i * 3],\n timelineSample: frames[frameBase + i * 3 + 1],\n audibleTimelineSample: frames[frameBase + i * 3 + 2],\n graphLatencySamplesQ8: ints[intBase + i * 4 + 2],\n value: ints[intBase + i * 4 + 3],\n });\n }\n }\n\n private commandRingFromSharedBuffer(\n sharedBuffer: SharedArrayBuffer,\n fallbackCapacity?: number,\n ): SonareEngineCommandRingBuffer {\n const ring = engineRingFromSharedBuffer(\n sharedBuffer,\n SONARE_ENGINE_COMMAND_RECORD_BYTES,\n fallbackCapacity,\n );\n return { sharedBuffer, header: ring.header, view: ring.view, capacity: ring.capacity };\n }\n\n private telemetryRingFromSharedBuffer(\n sharedBuffer: SharedArrayBuffer,\n fallbackCapacity?: number,\n ): SonareEngineTelemetryRingBuffer {\n const ring = engineRingFromSharedBuffer(\n sharedBuffer,\n SONARE_ENGINE_TELEMETRY_RECORD_BYTES,\n fallbackCapacity,\n );\n return { sharedBuffer, header: ring.header, view: ring.view, capacity: ring.capacity };\n }\n}\n\nexport class SonareRealtimeEngineNode {\n readonly node: AudioWorkletNode;\n readonly capabilities: SonareRealtimeEngineNodeCapabilities;\n readonly commandRing?: SonareEngineCommandRingBuffer;\n readonly telemetryRing?: SonareEngineTelemetryRingBuffer;\n readonly meterRing?: SonareMeterRingBuffer;\n readonly scopeRing?: SonareScopeRingBuffer;\n readonly ready: Promise<void>;\n private telemetryReadIndex = 0;\n private meterReadIndex = 0;\n private scopeReadIndex = 0;\n private telemetryListeners = new Set<(telemetry: SonareEngineTelemetryRecord) => void>();\n private meterListeners = new Set<(meter: SonareWorkletMeterSnapshot) => void>();\n private scopeListeners = new Set<(scope: SonareWorkletScopeSnapshot) => void>();\n private captureRequestId = 1;\n private readonly captureRequests = new Map<\n number,\n {\n resolve: (response: SonareEngineCaptureResponseMessage) => void;\n reject: (reason?: unknown) => void;\n }\n >();\n private transportRequestId = 1;\n private readonly transportRequests = new Map<\n number,\n {\n resolve: (response: SonareEngineTransportResponseMessage) => void;\n reject: (reason?: unknown) => void;\n }\n >();\n private resolveReady!: () => void;\n private rejectReady!: (reason?: unknown) => void;\n private destroyed = false;\n\n private constructor(\n node: AudioWorkletNode,\n capabilities: SonareRealtimeEngineNodeCapabilities,\n commandRing?: SonareEngineCommandRingBuffer,\n telemetryRing?: SonareEngineTelemetryRingBuffer,\n meterRing?: SonareMeterRingBuffer,\n scopeRing?: SonareScopeRingBuffer,\n ) {\n this.node = node;\n this.capabilities = capabilities;\n this.commandRing = commandRing;\n this.telemetryRing = telemetryRing;\n this.meterRing = meterRing;\n this.scopeRing = scopeRing;\n this.ready = new Promise((resolve, reject) => {\n this.resolveReady = resolve;\n this.rejectReady = reject;\n });\n if (!capabilities.readyMessage) {\n this.resolveReady();\n }\n this.node.port.onmessage = (event: MessageEvent<unknown>) => {\n if (isEngineCaptureResponseMessage(event.data)) {\n const pending = this.captureRequests.get(event.data.requestId);\n if (pending) {\n this.captureRequests.delete(event.data.requestId);\n if (event.data.ok) {\n pending.resolve(event.data);\n } else {\n pending.reject(new Error(event.data.error ?? 'Capture request failed'));\n }\n }\n } else if (isEngineTransportResponseMessage(event.data)) {\n const pending = this.transportRequests.get(event.data.requestId);\n if (pending) {\n this.transportRequests.delete(event.data.requestId);\n if (event.data.ok) {\n pending.resolve(event.data);\n } else {\n pending.reject(new Error(event.data.error ?? 'Transport request failed'));\n }\n }\n } else if (isEngineTelemetryRecord(event.data)) {\n this.emitTelemetry(event.data);\n } else if (isMeterSnapshot(event.data)) {\n this.emitMeter(event.data);\n } else if (isRecord(event.data) && event.data.type === 'ready') {\n this.resolveReady();\n } else if (isRecord(event.data) && event.data.type === 'error') {\n this.rejectReady(new Error(String(event.data.message ?? 'AudioWorklet error')));\n }\n };\n }\n\n static async create(\n context: BaseAudioContext,\n options: SonareRealtimeEngineNodeOptions = {},\n ): Promise<SonareRealtimeEngineNode> {\n const runtimeTarget = options.runtimeTarget ?? 'embind';\n const processorName = options.processorName ?? 'sonare-realtime-engine-processor';\n const moduleUrl = options.moduleUrl;\n if (moduleUrl && context.audioWorklet?.addModule) {\n await context.audioWorklet.addModule(moduleUrl);\n }\n const detectedCapabilities =\n options.engineAbiVersion !== undefined\n ? {\n engineAbiVersion: options.engineAbiVersion,\n expectedEngineAbiVersion: options.expectedEngineAbiVersion ?? options.engineAbiVersion,\n abiCompatible:\n options.engineAbiVersion ===\n (options.expectedEngineAbiVersion ?? options.engineAbiVersion),\n }\n : runtimeTarget === 'embind'\n ? engineCapabilities()\n : undefined;\n if (options.requireAbiCompatible !== false && detectedCapabilities?.abiCompatible === false) {\n throw new Error(\n `Engine ABI mismatch: wasm=${detectedCapabilities.engineAbiVersion}, expected=${detectedCapabilities.expectedEngineAbiVersion}`,\n );\n }\n const sharedArrayBuffer = typeof globalThis.SharedArrayBuffer === 'function';\n const atomics = typeof globalThis.Atomics === 'object';\n const audioWorklet = typeof AudioWorkletNode !== 'undefined' || !!options.nodeFactory;\n const degradedReason =\n options.mode !== 'postMessage' && (!sharedArrayBuffer || !atomics)\n ? 'SharedArrayBuffer or Atomics unavailable; using postMessage transport.'\n : undefined;\n const mode =\n options.mode === 'postMessage' || !sharedArrayBuffer || !atomics ? 'postMessage' : 'sab';\n if (options.mode === 'sab' && mode !== 'sab') {\n throw new Error(\n 'SharedArrayBuffer mode requested but SharedArrayBuffer/Atomics are unavailable.',\n );\n }\n\n const commandRing =\n mode === 'sab'\n ? createSonareEngineCommandRingBuffer(options.commandRingCapacity ?? 128)\n : undefined;\n const telemetryRing =\n mode === 'sab'\n ? createSonareEngineTelemetryRingBuffer(options.telemetryRingCapacity ?? 128)\n : undefined;\n // Meter ring: only the embind runtime publishes engine meters into a SAB\n // ring (the sonare-rt runtime owns its own meter transport). Lock-free\n // meter delivery matches the telemetry path and keeps the audio render\n // callback allocation-free in SAB mode.\n const meterRing =\n mode === 'sab' && runtimeTarget === 'embind'\n ? createSonareMeterRingBuffer(options.meterRingCapacity ?? 128)\n : undefined;\n // Scope ring (FFT spectrum + goniometer): opt-in, embind-only. The\n // per-block FFT is heavier than the meter path, so it is created only when\n // the caller requests scope telemetry via scopeIntervalFrames > 0.\n const scopeIntervalFrames = Math.max(0, Math.floor(options.scopeIntervalFrames ?? 0));\n const scopeRing =\n mode === 'sab' && runtimeTarget === 'embind' && scopeIntervalFrames > 0\n ? createSonareScopeRingBuffer(options.scopeRingCapacity ?? 64, options.scopeBands ?? 48)\n : undefined;\n const channelCount = Math.max(1, Math.floor(options.channelCount ?? 2));\n const processorOptions: SonareRealtimeEngineWorkletProcessorOptions = {\n runtimeTarget,\n rtModuleUrl: options.rtModuleUrl,\n rtWasmBinary: options.rtWasmBinary,\n sampleRate: options.sampleRate ?? context.sampleRate,\n blockSize: options.blockSize,\n channelCount,\n commandSharedBuffer: commandRing?.sharedBuffer,\n commandRingCapacity: commandRing?.capacity,\n telemetrySharedBuffer: telemetryRing?.sharedBuffer,\n telemetryRingCapacity: telemetryRing?.capacity,\n meterSharedBuffer: meterRing?.sharedBuffer,\n meterRingCapacity: meterRing?.capacity,\n scopeSharedBuffer: scopeRing?.sharedBuffer,\n scopeRingCapacity: scopeRing?.capacity,\n scopeBands: scopeRing?.bands,\n scopeIntervalFrames: scopeRing ? scopeIntervalFrames : undefined,\n wasmBinary: options.wasmBinary,\n initialSyncMessages: options.initialSyncMessages,\n initialCommands: options.initialCommands,\n };\n const factory =\n options.nodeFactory ??\n ((ctx: BaseAudioContext, name: string, nodeOptions: AudioWorkletNodeOptions) =>\n new AudioWorkletNode(ctx, name, nodeOptions));\n const node = factory(context, processorName, {\n numberOfInputs: 1,\n numberOfOutputs: 1,\n outputChannelCount: [channelCount],\n processorOptions,\n });\n return new SonareRealtimeEngineNode(\n node,\n {\n mode,\n runtimeTarget,\n sharedArrayBuffer,\n atomics,\n audioWorklet,\n engineAbiVersion: detectedCapabilities?.engineAbiVersion,\n expectedEngineAbiVersion: detectedCapabilities?.expectedEngineAbiVersion,\n abiCompatible: detectedCapabilities?.abiCompatible,\n degradedReason,\n readyMessage:\n runtimeTarget === 'sonare-rt' ||\n (runtimeTarget === 'embind' && moduleUrl !== undefined && !options.nodeFactory),\n },\n commandRing,\n telemetryRing,\n meterRing,\n scopeRing,\n );\n }\n\n play(sampleTime = -1): boolean {\n return this.sendCommand({ type: SonareEngineCommandType.TransportPlay, sampleTime });\n }\n\n stop(sampleTime = -1): boolean {\n return this.sendCommand({ type: SonareEngineCommandType.TransportStop, sampleTime });\n }\n\n seekSample(timelineSample: number, sampleTime = -1): boolean {\n return this.sendCommand({\n type: SonareEngineCommandType.TransportSeekSample,\n sampleTime,\n argInt: timelineSample,\n });\n }\n\n seekPpq(ppq: number, sampleTime = -1): boolean {\n return this.sendCommand({\n type: SonareEngineCommandType.TransportSeekPpq,\n sampleTime,\n argFloat: ppq,\n });\n }\n\n sendCommand(command: SonareEngineCommandRecord): boolean {\n if (this.destroyed) {\n return false;\n }\n if (this.commandRing) {\n return pushSonareEngineCommandRingBuffer(this.commandRing, command);\n }\n this.node.port.postMessage(command);\n return true;\n }\n\n requestCaptureStatus(): Promise<EngineCaptureStatus> {\n return this.sendCaptureRequest('status').then((response) => {\n if (!response.status) {\n throw new Error('Capture status response is missing status.');\n }\n return response.status;\n });\n }\n\n requestCapturedAudio(): Promise<Float32Array[]> {\n return this.sendCaptureRequest('read').then((response) =>\n (response.channels ?? []).map((channel) =>\n channel instanceof Float32Array ? channel : new Float32Array(channel),\n ),\n );\n }\n\n requestCaptureReset(): Promise<void> {\n return this.sendCaptureRequest('reset').then(() => undefined);\n }\n\n requestTransportState(): Promise<EngineTransportState> {\n return this.sendTransportRequest().then((response) => {\n if (!response.state) {\n throw new Error('Transport state response is missing state.');\n }\n return response.state;\n });\n }\n\n pollTelemetry(): SonareEngineTelemetryRecord[] {\n if (!this.telemetryRing) {\n return [];\n }\n const read = readSonareEngineTelemetryRingBuffer(this.telemetryRing, this.telemetryReadIndex);\n this.telemetryReadIndex = read.nextReadIndex;\n for (const telemetry of read.telemetry) {\n this.emitTelemetry(telemetry);\n }\n return read.telemetry;\n }\n\n // Drains any meters published into the SAB meter ring (embind SAB mode) and\n // forwards them to onMeter listeners. In postMessage mode meters arrive via\n // node.port.onmessage instead, so this is a no-op then.\n pollMeters(): SonareWorkletMeterSnapshot[] {\n if (!this.meterRing) {\n return [];\n }\n const read = readSonareMeterRingBuffer(this.meterRing, this.meterReadIndex);\n this.meterReadIndex = read.nextReadIndex;\n for (const meter of read.meters) {\n this.emitMeter(meter);\n }\n return read.meters;\n }\n\n // Drains scope telemetry (FFT spectrum + goniometer points) published into the\n // SAB scope ring and forwards each record to onScope listeners. A no-op unless\n // the node was created with scopeIntervalFrames > 0 (embind SAB mode).\n pollScope(): SonareWorkletScopeSnapshot[] {\n if (!this.scopeRing) {\n return [];\n }\n const read = readSonareScopeRingBuffer(this.scopeRing, this.scopeReadIndex);\n this.scopeReadIndex = read.nextReadIndex;\n for (const scope of read.scopes) {\n this.emitScope(scope);\n }\n return read.scopes;\n }\n\n onTelemetry(callback: (telemetry: SonareEngineTelemetryRecord) => void): () => void {\n this.telemetryListeners.add(callback);\n return () => {\n this.telemetryListeners.delete(callback);\n };\n }\n\n onMeter(callback: (meter: SonareWorkletMeterSnapshot) => void): () => void {\n this.meterListeners.add(callback);\n return () => {\n this.meterListeners.delete(callback);\n };\n }\n\n onScope(callback: (scope: SonareWorkletScopeSnapshot) => void): () => void {\n this.scopeListeners.add(callback);\n return () => {\n this.scopeListeners.delete(callback);\n };\n }\n\n destroy(): void {\n if (this.destroyed) {\n return;\n }\n this.destroyed = true;\n this.node.port.postMessage({ type: SonareEngineCommandType.TransportStop, sampleTime: -1 });\n this.node.disconnect();\n for (const pending of this.captureRequests.values()) {\n pending.reject(new Error('Realtime engine node is destroyed.'));\n }\n this.captureRequests.clear();\n for (const pending of this.transportRequests.values()) {\n pending.reject(new Error('Realtime engine node is destroyed.'));\n }\n this.transportRequests.clear();\n this.telemetryListeners.clear();\n this.meterListeners.clear();\n this.scopeListeners.clear();\n }\n\n private emitTelemetry(telemetry: SonareEngineTelemetryRecord): void {\n for (const listener of this.telemetryListeners) {\n listener(telemetry);\n }\n }\n\n private emitMeter(meter: SonareWorkletMeterSnapshot): void {\n for (const listener of this.meterListeners) {\n listener(meter);\n }\n }\n\n private emitScope(scope: SonareWorkletScopeSnapshot): void {\n for (const listener of this.scopeListeners) {\n listener(scope);\n }\n }\n\n private sendCaptureRequest(\n op: SonareEngineCaptureRequestMessage['op'],\n ): Promise<SonareEngineCaptureResponseMessage> {\n if (this.destroyed) {\n return Promise.reject(new Error('Realtime engine node is destroyed.'));\n }\n const requestId = this.captureRequestId++;\n const promise = new Promise<SonareEngineCaptureResponseMessage>((resolve, reject) => {\n this.captureRequests.set(requestId, { resolve, reject });\n });\n this.node.port.postMessage({ type: 'captureRequest', requestId, op });\n return promise;\n }\n\n private sendTransportRequest(): Promise<SonareEngineTransportResponseMessage> {\n if (this.destroyed) {\n return Promise.reject(new Error('Realtime engine node is destroyed.'));\n }\n const requestId = this.transportRequestId++;\n const promise = new Promise<SonareEngineTransportResponseMessage>((resolve, reject) => {\n this.transportRequests.set(requestId, { resolve, reject });\n });\n this.node.port.postMessage({ type: 'transportRequest', requestId, op: 'state' });\n return promise;\n }\n}\n\nexport class SonareEngine {\n readonly node: AudioWorkletNode;\n readonly capabilities: SonareRealtimeEngineNodeCapabilities;\n readonly transport: SonareEngineTransportFacade;\n private readonly realtimeNode: SonareRealtimeEngineNode;\n private readonly offlineEngine: RealtimeEngine;\n private readonly context: SuspendableAudioContext;\n private readonly sampleRate: number;\n private readonly offlineBlockSize: number;\n private readonly offlineChannelCount: number;\n private readonly automationLanes = new Map<number, EngineAutomationPoint[]>();\n private readonly clips = new Map<number, EngineClip>();\n private readonly midiClips = new Map<number, EngineMidiClipSchedule>();\n private readonly markers = new Map<number, EngineMarker>();\n private readonly trackLaneIds: number[] = [];\n private readonly trackSends = new Map<number, EngineTrackSend[]>();\n private readonly trackOutputBus = new Map<number, number>();\n private readonly laneSidechains = new Map<\n string,\n { trackId: number; insertIndex: number; sourceTrackId: number }\n >();\n private readonly buses: EngineBus[] = [];\n private readonly trackStripJson = new Map<number, string>();\n private readonly busStripJson = new Map<number, string>();\n private masterStripJson: string | undefined;\n private captureConfig: Omit<SonareEngineSyncCaptureMessage, 'type'> | undefined;\n private tempoBpm = 120;\n private timeSignature = { numerator: 4, denominator: 4 };\n private tempoSegments: EngineTempoSegment[] = [{ startPpq: 0, bpm: 120 }];\n private timeSignatureSegments: EngineTimeSignatureSegment[] = [\n { startPpq: 0, numerator: 4, denominator: 4 },\n ];\n private latestTransportState: EngineTransportState | undefined;\n private nextClipId = 1;\n private nextMarkerId = 1;\n private transportPlaying = false;\n private readonly pendingInstrumentSync: SonareEngineInstrumentSyncMessage[] = [];\n private destroyed = false;\n\n private constructor(\n context: BaseAudioContext,\n realtimeNode: SonareRealtimeEngineNode,\n offlineEngine: RealtimeEngine,\n sampleRate: number,\n offlineBlockSize: number,\n offlineChannelCount: number,\n ) {\n this.context = context;\n this.realtimeNode = realtimeNode;\n this.offlineEngine = offlineEngine;\n this.node = realtimeNode.node;\n this.capabilities = realtimeNode.capabilities;\n this.sampleRate = sampleRate;\n this.offlineBlockSize = offlineBlockSize;\n this.offlineChannelCount = offlineChannelCount;\n this.transport = {\n play: (sampleTime = -1) => {\n const ok = this.realtimeNode.play(sampleTime);\n if (ok) {\n this.transportPlaying = true;\n }\n return ok;\n },\n stop: (sampleTime = -1) => {\n const ok = this.realtimeNode.stop(sampleTime);\n if (ok) {\n this.transportPlaying = false;\n this.flushPendingInstrumentSync();\n }\n return ok;\n },\n seekPpq: (ppq, sampleTime = -1) => {\n this.offlineEngine.seekPpq(ppq, sampleTime);\n return this.realtimeNode.seekPpq(ppq, sampleTime);\n },\n seekSeconds: (seconds, sampleTime = -1) => {\n const timelineSample = Math.max(0, Math.round(seconds * this.sampleRate));\n this.offlineEngine.seekSample(timelineSample, sampleTime);\n return this.realtimeNode.seekSample(timelineSample, sampleTime);\n },\n setTempo: (bpm) => this.setTempo(bpm),\n setTempoSegments: (segments) => this.setTempoSegments(segments),\n setLoop: (startPpq, endPpq, enabled = true) => this.setLoop(startPpq, endPpq, enabled),\n };\n }\n\n static async create(\n context: BaseAudioContext,\n options: SonareEngineOptions = {},\n ): Promise<SonareEngine> {\n const sampleRate = options.sampleRate ?? context.sampleRate;\n const blockSize = options.offlineBlockSize ?? options.blockSize ?? 128;\n const channelCount = Math.max(\n 1,\n Math.floor(options.offlineChannelCount ?? options.channelCount ?? 2),\n );\n const realtimeNode = await SonareRealtimeEngineNode.create(context, options);\n const offlineEngine = options.offlineEngine ?? new RealtimeEngine(sampleRate, blockSize);\n return new SonareEngine(\n context,\n realtimeNode,\n offlineEngine,\n sampleRate,\n blockSize,\n channelCount,\n );\n }\n\n async suspend(): Promise<void> {\n if (this.destroyed) {\n return;\n }\n await this.context.suspend?.();\n }\n\n async resume(): Promise<void> {\n if (this.destroyed) {\n return;\n }\n await this.context.resume?.();\n }\n\n setTempo(bpm: number): void {\n this.tempoBpm = bpm;\n this.tempoSegments = [{ startPpq: 0, bpm }];\n this.offlineEngine.setTempo(bpm);\n this.postTempoSync();\n this.realtimeNode.sendCommand({\n type: SonareEngineCommandType.SetTempoMap,\n sampleTime: -1,\n argFloat: bpm,\n });\n }\n\n setTempoSegments(segments: readonly EngineTempoSegment[]): void {\n this.tempoSegments = segments.map((segment) => ({ ...segment }));\n this.tempoBpm = this.tempoSegments[0]?.bpm ?? this.tempoBpm;\n this.offlineEngine.setTempoSegments(this.tempoSegments);\n this.postTempoSync();\n }\n\n setTimeSignature(numerator: number, denominator: number): void {\n this.timeSignature = { numerator, denominator };\n this.timeSignatureSegments = [{ startPpq: 0, numerator, denominator }];\n this.offlineEngine.setTimeSignature(numerator, denominator);\n this.postTempoSync();\n }\n\n setTimeSignatureSegments(segments: readonly EngineTimeSignatureSegment[]): void {\n this.timeSignatureSegments = segments.map((segment) => ({ ...segment }));\n const first = this.timeSignatureSegments[0];\n if (first) {\n this.timeSignature = { numerator: first.numerator, denominator: first.denominator };\n }\n this.offlineEngine.setTimeSignatureSegments(this.timeSignatureSegments);\n this.postTempoSync();\n }\n\n setLoop(startPpq: number, endPpq: number, enabled = true): boolean {\n this.offlineEngine.setLoop(startPpq, endPpq, enabled);\n // Transport precision contract: the SAB command record carries exactly one\n // Float64 lane (argFloat) and one Int64 lane (argInt). startPpq travels in\n // argFloat with full double precision, matching the offline engine; endPpq\n // is carried as micro-PPQ (round(endPpq * 1e6)) in the integer lane and\n // divided back by 1e6 on the consumer. Loop ENDS are therefore snapped to\n // the nearest 1e-6 PPQ over the realtime transport (max 5e-7 PPQ drift),\n // while loop STARTS and the offline path stay exact. This is intentional:\n // the record has no second free Float64 lane, and a micro-PPQ grid on the\n // loop end is well below audible/sample-accurate resolution at any tempo.\n return this.realtimeNode.sendCommand({\n type: SonareEngineCommandType.SetLoop,\n targetId: enabled ? 1 : 0,\n sampleTime: -1,\n argFloat: startPpq,\n argInt: Math.round(endPpq * 1_000_000),\n });\n }\n\n countInEndSample(startSample: number, bars: number): number {\n return this.offlineEngine.countInEndSample(startSample, bars);\n }\n\n async getTransportState(): Promise<EngineTransportState> {\n const state = await this.realtimeNode.requestTransportState();\n this.latestTransportState = state;\n return state;\n }\n\n cachedTransportState(): EngineTransportState | undefined {\n return this.latestTransportState;\n }\n\n setParam(nodeId: string, param: string | number, value: number): boolean {\n const paramId = this.resolveParamId(nodeId, param);\n // Mirror the change into the offline engine so a subsequent offline render\n // reflects the live value, then push a sample-accurate command to the\n // realtime runtime (mirrors setTempo/setLoop above).\n this.offlineEngine.setParameter(paramId, value);\n return this.realtimeNode.sendCommand({\n type: SonareEngineCommandType.SetParam,\n targetId: paramId,\n sampleTime: -1,\n argFloat: value,\n });\n }\n\n scheduleParam(\n nodeId: string,\n param: string | number,\n ppq: number,\n value: number,\n curve: number | 'linear' | 'exponential' = 'linear',\n ): void {\n const paramId = this.resolveParamId(nodeId, param);\n const lane = this.automationLanes.get(paramId) ?? [];\n lane.push({ ppq, value, curveToNext: this.curveCode(curve) });\n lane.sort((a, b) => a.ppq - b.ppq);\n this.automationLanes.set(paramId, lane);\n this.offlineEngine.setAutomationLane(paramId, lane);\n // Mirror the lane to the live worklet engine so scheduled automation plays\n // back in real time, not just in renderOffline(). Lanes can exceed the\n // fixed-size SAB command record, so they ride an out-of-band 'syncAutomation'\n // message applied outside process() (like syncClips/syncMarkers).\n this.postSync({ type: 'syncAutomation', paramId, points: lane });\n }\n\n addAutomationPoint(\n laneId: string | number,\n ppq: number,\n value: number,\n curve: number | 'linear' | 'exponential' = 'linear',\n ): void {\n this.scheduleParam('', laneId, ppq, value, curve);\n }\n\n /**\n * Replaces the automation lane for `paramId` with the given breakpoints.\n *\n * Unlike scheduleParam (which appends a single point), this sets the whole\n * lane at once; an empty array clears the lane. The points are defensively\n * copied and sorted by ppq before being mirrored to the offline engine and\n * the live worklet engine.\n *\n * @param paramId Automation target id (registered parameter or a reserved\n * engine mixer target from automationParamId/busAutomationParamId).\n * @param points Lane breakpoints; order does not matter.\n */\n setAutomationLane(paramId: number, points: ReadonlyArray<EngineAutomationPoint>): void {\n const sorted = points.map((point) => ({ ...point })).sort((a, b) => a.ppq - b.ppq);\n if (sorted.length === 0) {\n this.automationLanes.delete(paramId);\n } else {\n this.automationLanes.set(paramId, sorted);\n }\n this.offlineEngine.setAutomationLane(paramId, sorted);\n this.postSync({ type: 'syncAutomation', paramId, points: sorted });\n }\n\n /**\n * Returns the automation target id for a mixer strip parameter.\n *\n * The id addresses the engine's reserved mixer namespace, so it can be fed\n * straight to setAutomationLane to automate a fader or pan without\n * registering a parameter.\n *\n * @param target Track id (declares a mixer lane on first use) or 'master'.\n * @param kind Strip parameter to address.\n * @returns Reserved engine parameter id for the strip parameter.\n */\n automationParamId(target: string | number, kind: 'faderDb' | 'pan'): number {\n const paramKind = kind === 'pan' ? ENGINE_MIXER_PARAM_PAN : ENGINE_MIXER_PARAM_FADER_DB;\n if (target === 'master') {\n return engineMixerMasterTarget(paramKind);\n }\n return engineMixerLaneTarget(this.ensureTrackLane(target), paramKind);\n }\n\n /**\n * Returns the automation target id for a bus fader.\n *\n * @param busId Bus id (declares the mixer bus on first use).\n * @returns Reserved engine parameter id for the bus fader gain (dB).\n */\n busAutomationParamId(busId: number): number {\n return engineMixerBusTarget(this.ensureBus(busId), ENGINE_MIXER_PARAM_FADER_DB);\n }\n\n /**\n * Returns the number of automation lanes installed on the engine, including\n * lanes whose breakpoint list is currently empty.\n *\n * @returns Engine-side automation lane count.\n */\n automationLaneCount(): number {\n return this.offlineEngine.automationLaneCount();\n }\n\n listParameters(): EngineParameterInfo[] {\n const parameters: EngineParameterInfo[] = [];\n for (let index = 0; index < this.offlineEngine.parameterCount(); index++) {\n parameters.push(this.offlineEngine.parameterInfoByIndex(index));\n }\n return parameters;\n }\n\n setSoloMute(target: string | number, solo: boolean, mute: boolean): boolean {\n const laneIndex = this.ensureTrackLane(target);\n this.offlineEngine.setSoloMute(laneIndex, solo, mute);\n return this.realtimeNode.sendCommand({\n type: SonareEngineCommandType.SetSoloMute,\n targetId: laneIndex,\n sampleTime: -1,\n argInt: (mute ? 0x1 : 0) | (solo ? 0x2 : 0),\n });\n }\n\n setStripGain(target: string | number, db: number): boolean {\n if (target === 'master') {\n const paramId = engineMixerMasterTarget(ENGINE_MIXER_PARAM_FADER_DB);\n this.offlineEngine.setParameter(paramId, db);\n return this.realtimeNode.sendCommand({\n type: SonareEngineCommandType.SetParamSmoothed,\n targetId: paramId,\n sampleTime: -1,\n argFloat: db,\n });\n }\n const laneIndex = this.ensureTrackLane(target);\n const paramId = engineMixerLaneTarget(laneIndex, ENGINE_MIXER_PARAM_FADER_DB);\n this.offlineEngine.setParameter(paramId, db);\n return this.realtimeNode.sendCommand({\n type: SonareEngineCommandType.SetParamSmoothed,\n targetId: paramId,\n sampleTime: -1,\n argFloat: db,\n });\n }\n\n setStripPan(target: string | number, pan: number): boolean {\n if (target === 'master') {\n const paramId = engineMixerMasterTarget(ENGINE_MIXER_PARAM_PAN);\n this.offlineEngine.setParameter(paramId, pan);\n return this.realtimeNode.sendCommand({\n type: SonareEngineCommandType.SetParamSmoothed,\n targetId: paramId,\n sampleTime: -1,\n argFloat: pan,\n });\n }\n const laneIndex = this.ensureTrackLane(target);\n const paramId = engineMixerLaneTarget(laneIndex, ENGINE_MIXER_PARAM_PAN);\n this.offlineEngine.setParameter(paramId, pan);\n return this.realtimeNode.sendCommand({\n type: SonareEngineCommandType.SetParamSmoothed,\n targetId: paramId,\n sampleTime: -1,\n argFloat: pan,\n });\n }\n\n /**\n * Declares the mixer track lanes in an explicit order.\n *\n * Lane indices are append-only: once a track id occupies a lane, its index\n * stays fixed for the engine's lifetime. The given list must therefore start\n * with the already-declared lane ids in their current order and may only\n * append new track ids after them. Entries carrying `sends` replace that\n * track's send list; entries without `sends` leave existing sends untouched.\n *\n * @param lanes Track ids or lane descriptors in the desired lane order.\n */\n setTrackLanes(lanes: ReadonlyArray<number | EngineTrackLane>): void {\n const entries = lanes.map((lane) => (typeof lane === 'number' ? { trackId: lane } : lane));\n const ids: number[] = [];\n for (const entry of entries) {\n if (!Number.isInteger(entry.trackId) || entry.trackId <= 0) {\n throw new Error(`Invalid track id for mixer lane: ${String(entry.trackId)}`);\n }\n ids.push(entry.trackId);\n }\n if (new Set(ids).size !== ids.length) {\n throw new Error('Duplicate track id in mixer lane list');\n }\n for (let index = 0; index < this.trackLaneIds.length; index++) {\n if (ids[index] !== this.trackLaneIds[index]) {\n throw new Error(\n 'Mixer lanes are append-only: keep existing lanes in order and only append new track ids',\n );\n }\n }\n for (const entry of entries) {\n if (entry.sends) {\n this.trackSends.set(\n entry.trackId,\n entry.sends.map((send) => ({ ...send })),\n );\n }\n if (entry.outputBusId !== undefined) {\n if (entry.outputBusId === 0) {\n this.trackOutputBus.delete(entry.trackId);\n } else {\n this.trackOutputBus.set(entry.trackId, entry.outputBusId);\n }\n }\n }\n this.trackLaneIds.splice(0, this.trackLaneIds.length, ...ids);\n this.syncMixer();\n }\n\n /**\n * Routes a track lane's post-fader output into a declared bus instead of\n * the master mix (group/folder routing); busId 0 restores the master mix.\n */\n setTrackOutputBus(target: string | number, busId: number): void {\n const laneIndex = this.ensureTrackLane(target);\n const trackId = this.trackLaneIds[laneIndex];\n if (busId === 0) {\n this.trackOutputBus.delete(trackId);\n } else {\n this.trackOutputBus.set(trackId, busId);\n }\n this.syncMixer();\n }\n\n /**\n * Keys one insert of a lane strip from another lane's post-strip pre-fader\n * audio (ducking/sidechainRouter inserts). sourceTarget null removes the\n * binding.\n */\n setLaneSidechain(\n target: string | number,\n insertIndex: number,\n sourceTarget: string | number | null,\n ): void {\n const laneIndex = this.ensureTrackLane(target);\n const trackId = this.trackLaneIds[laneIndex];\n const key = `${trackId}:${insertIndex}`;\n let sourceTrackId = 0;\n if (sourceTarget !== null) {\n const sourceIndex = this.ensureTrackLane(sourceTarget);\n sourceTrackId = this.trackLaneIds[sourceIndex];\n }\n if (sourceTrackId === 0) {\n this.laneSidechains.delete(key);\n } else {\n this.laneSidechains.set(key, { trackId, insertIndex, sourceTrackId });\n }\n this.offlineEngine.setLaneSidechain(trackId, insertIndex, sourceTrackId);\n this.postSync({\n type: 'syncMixer',\n lanes: this.mixerLanes(),\n laneSidechains: [{ trackId, insertIndex, sourceTrackId }],\n });\n }\n\n setSends(target: string | number, sends: EngineTrackSend[]): void {\n const laneIndex = this.ensureTrackLane(target);\n const trackId = this.trackLaneIds[laneIndex];\n this.trackSends.set(\n trackId,\n sends.map((send) => ({ ...send })),\n );\n this.syncMixer();\n }\n\n setTrackBuses(buses: EngineBus[]): void {\n this.buses.splice(0, this.buses.length, ...buses.map((bus) => ({ ...bus })));\n this.syncMixer();\n }\n\n setBusGain(busId: number, db: number): boolean {\n const busIndex = this.ensureBus(busId);\n this.buses[busIndex] = { ...this.buses[busIndex], busId, gainDb: db };\n this.offlineEngine.setTrackBuses(this.buses);\n const paramId = engineMixerBusTarget(busIndex, ENGINE_MIXER_PARAM_FADER_DB);\n this.offlineEngine.setParameter(paramId, db);\n return this.realtimeNode.sendCommand({\n type: SonareEngineCommandType.SetParamSmoothed,\n targetId: paramId,\n sampleTime: -1,\n argFloat: db,\n });\n }\n\n setTrackStripJson(target: string | number, sceneJson: string): void {\n const laneIndex = this.ensureTrackLane(target);\n const trackId = this.trackLaneIds[laneIndex];\n this.offlineEngine.setTrackStripJson(trackId, sceneJson);\n this.trackStripJson.set(trackId, sceneJson);\n this.syncMixer();\n }\n\n setTrackStripEqBand(target: string | number, bandIndex: number, band: EqBand | string): void {\n const laneIndex = this.ensureTrackLane(target);\n const trackId = this.trackLaneIds[laneIndex];\n const bandJson = typeof band === 'string' ? band : JSON.stringify(band);\n this.offlineEngine.setTrackStripEqBandJson(trackId, bandIndex, bandJson);\n this.postSync({ type: 'syncTrackStripEqBand', trackId, bandIndex, bandJson });\n }\n\n setTrackStripInsertBypassed(\n target: string | number,\n insertIndex: number,\n bypassed: boolean,\n resetOnBypass = false,\n ): void {\n const laneIndex = this.ensureTrackLane(target);\n const trackId = this.trackLaneIds[laneIndex];\n this.offlineEngine.setTrackStripInsertBypassed(trackId, insertIndex, bypassed, resetOnBypass);\n this.postSync({\n type: 'syncTrackStripInsertBypassed',\n trackId,\n insertIndex,\n bypassed,\n resetOnBypass,\n });\n }\n\n setTrackStripInsertParamByName(\n target: string | number,\n insertIndex: number,\n paramName: string,\n value: number,\n ): void {\n const laneIndex = this.ensureTrackLane(target);\n const trackId = this.trackLaneIds[laneIndex];\n this.offlineEngine.setTrackStripInsertParamByName(trackId, insertIndex, paramName, value);\n this.postSync({\n type: 'syncTrackStripInsertParamByName',\n trackId,\n insertIndex,\n paramName,\n value,\n });\n }\n\n setTrackStripPan(target: string | number, pan: number): void {\n const trackId = this.trackLaneIds[this.ensureTrackLane(target)];\n this.offlineEngine.setTrackStripPan(trackId, pan);\n this.postSync({ type: 'syncTrackStripPan', trackId, pan });\n }\n\n setTrackStripPanLaw(target: string | number, panLaw: PanLaw | number): void {\n const trackId = this.trackLaneIds[this.ensureTrackLane(target)];\n const code = panLawCode(panLaw);\n this.offlineEngine.setTrackStripPanLaw(trackId, code);\n this.postSync({ type: 'syncTrackStripPanLaw', trackId, panLaw: code });\n }\n\n setTrackStripPanMode(target: string | number, panMode: PanMode | number): void {\n const trackId = this.trackLaneIds[this.ensureTrackLane(target)];\n const code = panModeCode(panMode);\n this.offlineEngine.setTrackStripPanMode(trackId, code);\n this.postSync({ type: 'syncTrackStripPanMode', trackId, panMode: code });\n }\n\n setTrackStripDualPan(target: string | number, leftPan: number, rightPan: number): void {\n const trackId = this.trackLaneIds[this.ensureTrackLane(target)];\n this.offlineEngine.setTrackStripDualPan(trackId, leftPan, rightPan);\n this.postSync({ type: 'syncTrackStripDualPan', trackId, leftPan, rightPan });\n }\n\n setTrackStripChannelDelaySamples(target: string | number, delaySamples: number): void {\n const trackId = this.trackLaneIds[this.ensureTrackLane(target)];\n this.offlineEngine.setTrackStripChannelDelaySamples(trackId, delaySamples);\n this.postSync({ type: 'syncTrackStripChannelDelaySamples', trackId, delaySamples });\n }\n\n setStripEq(target: string | number, bandIndex: number, band: EqBand | string): void {\n if (target === 'master') {\n this.setMasterStripEqBand(bandIndex, band);\n return;\n }\n this.setTrackStripEqBand(target, bandIndex, band);\n }\n\n setStripInsertBypassed(\n target: string | number,\n insertIndex: number,\n bypassed: boolean,\n resetOnBypass = false,\n ): void {\n if (target === 'master') {\n this.setMasterStripInsertBypassed(insertIndex, bypassed, resetOnBypass);\n return;\n }\n this.setTrackStripInsertBypassed(target, insertIndex, bypassed, resetOnBypass);\n }\n\n setStripInserts(target: string | number, sceneJson: string): void {\n if (target === 'master') {\n this.setMasterStripJson(sceneJson);\n return;\n }\n this.setTrackStripJson(target, sceneJson);\n }\n\n setBusStripJson(busId: number, sceneJson: string): void {\n this.ensureBus(busId);\n this.offlineEngine.setBusStripJson(busId, sceneJson);\n this.busStripJson.set(busId, sceneJson);\n this.syncMixer();\n }\n\n setMasterStripJson(sceneJson: string): void {\n this.offlineEngine.setMasterStripJson(sceneJson);\n this.masterStripJson = sceneJson;\n this.syncMixer();\n }\n\n setMasterStripEqBand(bandIndex: number, band: EqBand | string): void {\n const bandJson = typeof band === 'string' ? band : JSON.stringify(band);\n this.offlineEngine.setMasterStripEqBandJson(bandIndex, bandJson);\n this.postSync({ type: 'syncMasterStripEqBand', bandIndex, bandJson });\n }\n\n setMasterStripInsertBypassed(\n insertIndex: number,\n bypassed: boolean,\n resetOnBypass = false,\n ): void {\n this.offlineEngine.setMasterStripInsertBypassed(insertIndex, bypassed, resetOnBypass);\n this.postSync({\n type: 'syncMasterStripInsertBypassed',\n insertIndex,\n bypassed,\n resetOnBypass,\n });\n }\n\n setMasterStripInsertParamByName(insertIndex: number, paramName: string, value: number): void {\n this.offlineEngine.setMasterStripInsertParamByName(insertIndex, paramName, value);\n this.postSync({\n type: 'syncMasterStripInsertParamByName',\n insertIndex,\n paramName,\n value,\n });\n }\n\n setStripInsertParamByName(\n target: string | number,\n insertIndex: number,\n paramName: string,\n value: number,\n ): void {\n if (target === 'master') {\n this.setMasterStripInsertParamByName(insertIndex, paramName, value);\n return;\n }\n this.setTrackStripInsertParamByName(target, insertIndex, paramName, value);\n }\n\n setMasterChain(sceneJson: string): void {\n this.setMasterStripJson(sceneJson);\n }\n\n addClip(\n trackId: string | number,\n buffer: Float32Array[],\n startPpq: number,\n opts: Partial<Omit<EngineClip, 'channels' | 'startPpq'>> = {},\n ): number {\n const id = opts.id ?? this.nextClipId++;\n const clip: EngineClip = {\n ...opts,\n id,\n channels: buffer,\n startPpq,\n trackId: this.resolveTargetId(trackId),\n };\n this.ensureTrackLane(trackId);\n this.clips.set(id, clip);\n this.syncClipsDelta([clip], []);\n return id;\n }\n\n removeClip(clipId: number): void {\n this.clips.delete(clipId);\n this.syncClipsDelta([], [clipId]);\n }\n\n setMidiClips(clips: readonly EngineMidiClipSchedule[]): void {\n this.midiClips.clear();\n for (const clip of clips) {\n const id = clip.id ?? this.nextClipId++;\n this.midiClips.set(id, { ...clip, id, events: clip.events.map((event) => ({ ...event })) });\n }\n this.syncMidiClips();\n }\n\n setBuiltinInstrument(\n trackId: string | number,\n config: { destinationId?: number } & Record<string, unknown> = {},\n ): void {\n const destinationId = this.resolveTargetId(trackId);\n this.offlineEngine.setBuiltinInstrument(config, destinationId);\n this.postInstrumentSync({ type: 'syncBuiltinInstrument', destinationId, config });\n }\n\n setSynthInstrument(trackId: string | number, patch: Record<string, unknown> | string = {}): void {\n const destinationId = this.resolveTargetId(trackId);\n this.offlineEngine.setSynthInstrument(patch, destinationId);\n this.postInstrumentSync({ type: 'syncSynthInstrument', destinationId, patch });\n }\n\n loadSoundFont(data: Uint8Array): void {\n this.offlineEngine.loadSoundFont(data);\n this.postInstrumentSync({ type: 'syncLoadSoundFont', data });\n }\n\n setSf2Instrument(\n trackId: string | number,\n config: { destinationId?: number; gain?: number; polyphony?: number } = {},\n ): void {\n const destinationId = this.resolveTargetId(trackId);\n this.offlineEngine.setSf2Instrument(config, destinationId);\n this.postInstrumentSync({ type: 'syncSf2Instrument', destinationId, config });\n }\n\n pushMidiNoteOn(\n trackId: string | number,\n group: number,\n channel: number,\n note: number,\n velocity: number,\n renderFrame = -1,\n ): void {\n const destinationId = this.resolveTargetId(trackId);\n this.offlineEngine.pushMidiNoteOn(destinationId, group, channel, note, velocity, renderFrame);\n this.postSync({\n type: 'syncMidiNoteOn',\n destinationId,\n group,\n channel,\n note,\n velocity,\n renderFrame,\n });\n }\n\n pushMidiNoteOff(\n trackId: string | number,\n group: number,\n channel: number,\n note: number,\n velocity = 0,\n renderFrame = -1,\n ): void {\n const destinationId = this.resolveTargetId(trackId);\n this.offlineEngine.pushMidiNoteOff(destinationId, group, channel, note, velocity, renderFrame);\n this.postSync({\n type: 'syncMidiNoteOff',\n destinationId,\n group,\n channel,\n note,\n velocity,\n renderFrame,\n });\n }\n\n pushMidiCc(\n trackId: string | number,\n group: number,\n channel: number,\n controller: number,\n value: number,\n renderFrame = -1,\n ): void {\n const destinationId = this.resolveTargetId(trackId);\n this.offlineEngine.pushMidiCc(destinationId, group, channel, controller, value, renderFrame);\n this.postSync({\n type: 'syncMidiCc',\n destinationId,\n group,\n channel,\n controller,\n value,\n renderFrame,\n });\n }\n\n pushMidiPanic(renderFrame = -1): void {\n this.offlineEngine.pushMidiPanic(renderFrame);\n this.postSync({ type: 'syncMidiPanic', renderFrame });\n }\n\n configureCapture(options: {\n bufferFrames: number;\n channels?: number;\n source?: EngineCaptureStatus['source'];\n recordOffsetSamples?: number;\n inputMonitor?: { enabled: boolean; gain?: number };\n }): void {\n const bufferFrames = Math.trunc(options.bufferFrames);\n const channels = Math.trunc(options.channels ?? this.offlineChannelCount);\n const source = options.source ?? 'output';\n const recordOffsetSamples = Math.trunc(options.recordOffsetSamples ?? 0);\n const inputMonitor = {\n enabled: Boolean(options.inputMonitor?.enabled),\n gain: options.inputMonitor?.gain ?? 1,\n };\n this.offlineEngine.setCaptureBuffer(channels, bufferFrames);\n this.offlineEngine.setCaptureSource(source);\n this.offlineEngine.setRecordOffsetSamples(recordOffsetSamples);\n this.offlineEngine.setInputMonitor(inputMonitor.enabled, inputMonitor.gain);\n this.captureConfig = { bufferFrames, channels, source, recordOffsetSamples, inputMonitor };\n this.postSync({ type: 'syncCapture', ...this.captureConfig });\n }\n\n armRecord(trackId: string | number, enabled: boolean): boolean {\n if (enabled && !this.captureConfig) {\n throw new Error('Capture buffer is not configured');\n }\n this.offlineEngine.armCapture(enabled);\n return this.realtimeNode.sendCommand({\n type: SonareEngineCommandType.ArmRecord,\n targetId: this.resolveTargetId(trackId),\n sampleTime: -1,\n argInt: enabled ? 1 : 0,\n });\n }\n\n punch(inPpq: number, outPpq: number): boolean {\n const inSample = this.offlineEngine.sampleAtPpq(inPpq);\n const outSample = this.offlineEngine.sampleAtPpq(outPpq);\n this.offlineEngine.setCapturePunch(inSample, outSample, true);\n // Carry BOTH endpoints as already-converted SAMPLES so the realtime engine\n // agrees with the offline engine. The previous code sent the raw PPQ out\n // point and let the consumer multiply by sampleRate (treating PPQ as\n // seconds), which ignored tempo and produced a punch-out ~2x too large at\n // 120 BPM. argInt = in sample, argFloat = out sample (full-precision double).\n return this.realtimeNode.sendCommand({\n type: SonareEngineCommandType.Punch,\n sampleTime: -1,\n argInt: inSample,\n argFloat: outSample,\n });\n }\n\n captureStatus(): Promise<EngineCaptureStatus> {\n return this.realtimeNode.requestCaptureStatus();\n }\n\n capturedAudio(): Promise<Float32Array[]> {\n return this.realtimeNode.requestCapturedAudio();\n }\n\n async resetCapture(): Promise<void> {\n this.offlineEngine.resetCapture();\n await this.realtimeNode.requestCaptureReset();\n }\n\n setMetronome(opts: EngineMetronomeConfig): void {\n this.offlineEngine.setMetronome(opts);\n // The full config (beatGain/accentGain/clickSamples/clickSeconds) cannot fit\n // the fixed-size SAB command record, so it is delivered out-of-band; the\n // SetMetronome command then toggles enabled state on the audio thread.\n this.postSync({ type: 'syncMetronome', config: opts });\n this.realtimeNode.sendCommand({\n type: SonareEngineCommandType.SetMetronome,\n sampleTime: -1,\n argInt: opts.enabled ? 1 : 0,\n });\n }\n\n addMarker(ppq: number, name = ''): number {\n const id = this.nextMarkerId++;\n this.markers.set(id, { id, ppq, name });\n this.syncMarkers();\n return id;\n }\n\n /**\n * Replaces the whole marker set in one call.\n *\n * Entries without an `id` are assigned fresh ids; entries carrying an `id`\n * keep it (ids must be positive and unique within the list). Returns the\n * resolved markers in the order given, so a caller can map its own marker\n * identities to the engine ids used by `seekMarker`/`setLoopFromMarkers`.\n *\n * @param markers The full marker list (an empty list clears all markers).\n * @returns The markers with their resolved engine ids.\n */\n setMarkers(markers: ReadonlyArray<{ ppq: number; name?: string; id?: number }>): EngineMarker[] {\n const resolved: EngineMarker[] = [];\n const seen = new Set<number>();\n for (const marker of markers) {\n if (!Number.isFinite(marker.ppq)) {\n throw new Error(`Invalid marker ppq: ${String(marker.ppq)}`);\n }\n if (marker.id !== undefined) {\n if (!Number.isInteger(marker.id) || marker.id <= 0) {\n throw new Error(`Invalid marker id: ${String(marker.id)}`);\n }\n if (seen.has(marker.id)) {\n throw new Error(`Duplicate marker id: ${marker.id}`);\n }\n }\n const id = marker.id ?? this.nextMarkerId++;\n seen.add(id);\n if (id >= this.nextMarkerId) {\n this.nextMarkerId = id + 1;\n }\n resolved.push({ id, ppq: marker.ppq, name: marker.name ?? '' });\n }\n this.markers.clear();\n for (const marker of resolved) {\n this.markers.set(marker.id, marker);\n }\n this.syncMarkers();\n return resolved.map((marker) => ({ ...marker }));\n }\n\n markerCount(): number {\n return this.offlineEngine.markerCount();\n }\n\n markerByIndex(index: number): EngineMarker {\n return this.offlineEngine.markerByIndex(index);\n }\n\n marker(markerId: number): EngineMarker {\n return this.offlineEngine.marker(markerId);\n }\n\n seekMarker(markerId: number): boolean {\n this.offlineEngine.seekMarker(markerId);\n // Forward to the live worklet engine. Its marker set is kept in sync via the\n // 'syncMarkers' message (see syncMarkers), so a queued kSeekMarker resolves\n // the marker id to its frame on the audio thread. Returns the sendCommand\n // result (previously this method always returned a misleading `false`).\n return this.realtimeNode.sendCommand({\n type: SonareEngineCommandType.SeekMarker,\n targetId: markerId,\n sampleTime: -1,\n });\n }\n\n setLoopFromMarkers(startMarkerId: number, endMarkerId: number): boolean {\n this.offlineEngine.setLoopFromMarkers(startMarkerId, endMarkerId);\n const start = this.offlineEngine.marker(startMarkerId);\n const end = this.offlineEngine.marker(endMarkerId);\n return this.setLoop(start.ppq, end.ppq, true);\n }\n\n async renderOffline(totalFrames: number): Promise<Float32Array[]> {\n const frames = Math.max(0, Math.floor(totalFrames));\n const inputs: Float32Array[] = [];\n for (let ch = 0; ch < this.offlineChannelCount; ch++) {\n inputs.push(new Float32Array(frames));\n }\n return this.offlineEngine.renderOffline(inputs, this.offlineBlockSize);\n }\n\n onMeter(callback: (meter: SonareWorkletMeterSnapshot) => void): () => void {\n return this.realtimeNode.onMeter(callback);\n }\n\n onScope(callback: (scope: SonareWorkletScopeSnapshot) => void): () => void {\n return this.realtimeNode.onScope(callback);\n }\n\n onTelemetry(callback: (telemetry: SonareEngineTelemetryRecord) => void): () => void {\n return this.realtimeNode.onTelemetry(callback);\n }\n\n pollTelemetry(): SonareEngineTelemetryRecord[] {\n return this.realtimeNode.pollTelemetry();\n }\n\n pollMeters(): SonareWorkletMeterSnapshot[] {\n return this.realtimeNode.pollMeters();\n }\n\n pollScope(): SonareWorkletScopeSnapshot[] {\n return this.realtimeNode.pollScope();\n }\n\n destroy(): void {\n if (this.destroyed) {\n return;\n }\n this.destroyed = true;\n this.transport.stop();\n this.realtimeNode.pollTelemetry();\n this.realtimeNode.destroy();\n this.offlineEngine.destroy();\n }\n\n private syncClipsDelta(upserts: EngineClip[], removeIds: number[]): void {\n const clips = Array.from(this.clips.values());\n this.offlineEngine.setClips(clips);\n this.postSync({\n type: 'syncClipsDelta',\n upserts,\n removeIds,\n });\n }\n\n private syncMidiClips(): void {\n const clips = Array.from(this.midiClips.values());\n this.offlineEngine.setMidiClips(clips);\n this.postSync({ type: 'syncMidiClips', clips });\n }\n\n private mixerLanes(): EngineTrackLane[] {\n return this.trackLaneIds.map((trackId) => {\n const sends = this.trackSends.get(trackId);\n const outputBusId = this.trackOutputBus.get(trackId);\n return {\n trackId,\n ...(sends && sends.length > 0 ? { sends: sends.map((send) => ({ ...send })) } : {}),\n ...(outputBusId !== undefined ? { outputBusId } : {}),\n };\n });\n }\n\n private syncMixer(): void {\n const lanes = this.mixerLanes();\n const buses = this.buses.map((bus) => ({ ...bus }));\n this.offlineEngine.setTrackBuses(buses);\n if (lanes.length > 0) {\n this.offlineEngine.setTrackLanes(lanes);\n }\n const trackStrips = Array.from(this.trackStripJson, ([trackId, sceneJson]) => ({\n trackId,\n sceneJson,\n }));\n const busStrips = Array.from(this.busStripJson, ([busId, sceneJson]) => ({\n busId,\n sceneJson,\n }));\n this.postSync({\n type: 'syncMixer',\n lanes,\n buses,\n trackStrips,\n laneSidechains: Array.from(this.laneSidechains.values()),\n busStrips,\n masterStripJson: this.masterStripJson,\n });\n }\n\n private syncMarkers(): void {\n const markers = Array.from(this.markers.values()).sort((a, b) => a.ppq - b.ppq);\n this.offlineEngine.setMarkers(markers);\n this.postSync({ type: 'syncMarkers', markers });\n }\n\n private postInstrumentSync(message: SonareEngineInstrumentSyncMessage): void {\n if (this.destroyed) {\n return;\n }\n if (this.transportPlaying) {\n this.pendingInstrumentSync.push(message);\n return;\n }\n this.postSync(message);\n }\n\n private flushPendingInstrumentSync(): void {\n if (this.destroyed || this.pendingInstrumentSync.length === 0) {\n return;\n }\n const pending = this.pendingInstrumentSync.splice(0);\n for (const message of pending) {\n this.postSync(message);\n }\n }\n\n private postTempoSync(): void {\n this.postSync({\n type: 'syncTempo',\n bpm: this.tempoBpm,\n timeSignature: { ...this.timeSignature },\n tempoSegments: this.tempoSegments.map((segment) => ({ ...segment })),\n timeSignatureSegments: this.timeSignatureSegments.map((segment) => ({ ...segment })),\n });\n }\n\n // Posts an out-of-band control-sync message to the worklet engine processor.\n // Sync messages use a string `type` so the worklet's message handler routes\n // them to receiveSync() (numeric `type` is reserved for SonareEngineCommandRecord).\n private postSync(message: SonareEngineSyncMessage): void {\n if (this.destroyed) {\n return;\n }\n this.realtimeNode.node.port.postMessage(message);\n }\n\n private resolveParamId(nodeId: string, param: string | number): number {\n if (typeof param === 'number') {\n return param;\n }\n const byName = this.listParameters().find((info) => info.name === param);\n if (byName) {\n return byName.id;\n }\n return this.resolveTargetId(param || nodeId);\n }\n\n private resolveTargetId(target: string | number): number {\n if (typeof target === 'number') {\n return target;\n }\n const parsed = Number.parseInt(target, 10);\n return Number.isFinite(parsed) ? parsed : 0;\n }\n\n private ensureTrackLane(target: string | number): number {\n const trackId = this.resolveTargetId(target);\n if (!Number.isInteger(trackId) || trackId <= 0) {\n throw new Error(`Invalid track id for mixer lane: ${String(target)}`);\n }\n const existing = this.trackLaneIds.indexOf(trackId);\n if (existing >= 0) {\n return existing;\n }\n this.trackLaneIds.push(trackId);\n this.syncMixer();\n return this.trackLaneIds.length - 1;\n }\n\n private ensureBus(busId: number): number {\n const resolved = Math.trunc(busId);\n if (!Number.isInteger(resolved) || resolved <= 0) {\n throw new Error(`Invalid bus id for mixer bus: ${String(busId)}`);\n }\n const existing = this.buses.findIndex((bus) => bus.busId === resolved);\n if (existing >= 0) {\n return existing;\n }\n this.buses.push({ busId: resolved });\n this.syncMixer();\n return this.buses.length - 1;\n }\n\n private curveCode(curve: number | 'linear' | 'exponential'): number {\n if (typeof curve === 'number') {\n return curve;\n }\n return curve === 'exponential' ? 1 : 0;\n }\n}\n\nexport class SonareRealtimeVoiceChangerWorkletProcessor {\n private static warnedMonoOverflow = false;\n private static warnedInterleavedOverflow = false;\n private changer: RealtimeVoiceChanger;\n private readonly sampleRate: number;\n private readonly blockSize: number;\n private readonly channelCount: number;\n // WASM-heap typed-memory views, sized to the worst case (blockSize *\n // channelCount). Acquired on the main thread (constructor) so the\n // audio-thread process() never crosses an allocation boundary.\n private monoInput: Float32Array;\n private monoOutput: Float32Array;\n // Planar heap-backed views (one Float32Array per channel) used by the\n // multi-channel path. AudioWorklet inputs/outputs are already planar\n // Float32Arrays, so this avoids the per-sample interleave/deinterleave\n // passes that the older interleaved path needed.\n private planarChannels: Float32Array[];\n private destroyed = false;\n\n constructor(options: SonareRealtimeVoiceChangerWorkletProcessorOptions = {}) {\n this.sampleRate = options.sampleRate ?? 48000;\n this.blockSize = options.blockSize ?? 128;\n this.channelCount = Math.max(1, Math.floor(options.channelCount ?? 1));\n this.changer = new RealtimeVoiceChanger(options.preset ?? 'neutral-monitor');\n this.changer.prepare(this.sampleRate, this.blockSize, this.channelCount);\n // Acquire WASM-heap views once, sized to the worst case. These are alive\n // for the lifetime of the changer; if the host requests more frames per\n // process() than blockSize, we clamp (see ensure*Capacity).\n this.monoInput = this.changer.getMonoInputBuffer(this.blockSize);\n this.monoOutput = this.changer.getMonoOutputBuffer(this.blockSize);\n this.planarChannels = [];\n if (this.channelCount > 1) {\n for (let ch = 0; ch < this.channelCount; ch++) {\n this.planarChannels.push(this.changer.getPlanarChannelBuffer(ch, this.blockSize));\n }\n }\n }\n\n /**\n * Handles a control-plane message from the main thread. Runs on the\n * AudioWorklet global scope but OUTSIDE of `process()` (i.e. outside the\n * realtime audio callback), so it is safe to perform JSON parsing and\n * DSP coefficient recomputation here. `setConfig` MUST NOT be deferred\n * into `process()` because that would block the audio thread for longer\n * than one render quantum (e.g. 128 samples / 44.1 kHz = ~2.9 ms).\n */\n receiveMessage(message: SonareRealtimeVoiceChangerMessage): void {\n if (this.destroyed) {\n return;\n }\n if (message.type === 'setConfig') {\n // Apply synchronously on the message-handler thread. `setConfig` may\n // allocate and parse JSON internally; doing it here keeps `process()`\n // realtime-safe.\n this.changer.setConfig(message.preset);\n } else if (message.type === 'reset') {\n this.changer.reset();\n } else if (message.type === 'destroy') {\n this.destroy();\n }\n }\n\n process(inputs: WorkletInput, outputs: WorkletOutput): boolean {\n const output = outputs[0];\n if (this.destroyed || !output || output.length === 0) {\n return !this.destroyed;\n }\n\n // The cached heap views can detach if WASM linear memory grows (the embind\n // module is built ALLOW_MEMORY_GROWTH). Re-acquire them if detached\n // (byteLength === 0) before touching them; in the common no-growth case this\n // is a cheap branch with no allocation.\n if (this.monoInput.byteLength === 0) {\n this.reacquireBuffers();\n }\n\n const input = inputs[0];\n const requestedFrames = output[0]?.length ?? 0;\n const requestedChannels = Math.min(this.channelCount, output.length);\n if (requestedFrames === 0 || requestedChannels === 0) {\n return true;\n }\n\n if (requestedChannels === 1) {\n // Clamp to the pre-allocated capacity; warn (once) if the host violated\n // the contract. We never reallocate on the audio thread.\n const frames = this.ensureMonoCapacity(requestedFrames);\n const source = input?.[0];\n if (source) {\n this.monoInput.set(source.subarray(0, frames));\n } else {\n this.monoInput.fill(0, 0, frames);\n }\n this.changer.processMonoInto(\n this.monoInput.subarray(0, frames),\n this.monoOutput.subarray(0, frames),\n );\n output[0].set(this.monoOutput.subarray(0, frames));\n return true;\n }\n\n const frames = this.ensureInterleavedCapacity(requestedFrames, requestedChannels);\n const channels = requestedChannels;\n // Planar zero-copy path: AudioWorklet's input[ch] is already a\n // Float32Array per channel, so we set() straight into the heap-backed\n // planar view and processPreparedPlanar runs in place.\n for (let ch = 0; ch < channels; ch++) {\n const src = input?.[ch];\n const dst = this.planarChannels[ch];\n if (!dst) {\n continue;\n }\n if (src) {\n dst.set(src.subarray(0, frames));\n } else {\n dst.fill(0, 0, frames);\n }\n }\n this.changer.processPreparedPlanar(frames);\n for (let ch = 0; ch < channels; ch++) {\n const src = this.planarChannels[ch];\n if (src) {\n output[ch].set(src.subarray(0, frames));\n }\n // No `for frame` inner loop needed; output[ch] is a Float32Array.\n }\n return true;\n }\n\n destroy(): void {\n if (this.destroyed) {\n return;\n }\n this.destroyed = true;\n this.changer.delete();\n }\n\n // Re-acquires the cached WASM-heap views after a memory-growth detachment.\n // The underlying C++ vectors are pre-warmed (ensure_*_capacity ran at prepare\n // time), so getMono*/getPlanar* return fresh views onto the SAME storage\n // without reallocating it.\n private reacquireBuffers(): void {\n this.monoInput = this.changer.getMonoInputBuffer(this.blockSize);\n this.monoOutput = this.changer.getMonoOutputBuffer(this.blockSize);\n if (this.channelCount > 1) {\n for (let ch = 0; ch < this.channelCount; ch++) {\n this.planarChannels[ch] = this.changer.getPlanarChannelBuffer(ch, this.blockSize);\n }\n }\n }\n\n /**\n * Returns the number of frames we can actually process given the\n * pre-allocated capacity. If the host requests more frames than the\n * worst-case block size declared at construction time, we clamp to the\n * available capacity and warn once — we MUST NOT reallocate on the\n * realtime audio thread.\n */\n private ensureMonoCapacity(frames: number): number {\n const capacity = this.monoInput.length;\n if (frames <= capacity) {\n return frames;\n }\n if (!SonareRealtimeVoiceChangerWorkletProcessor.warnedMonoOverflow) {\n SonareRealtimeVoiceChangerWorkletProcessor.warnedMonoOverflow = true;\n // biome-ignore lint/suspicious/noConsole: realtime-safety diagnostic.\n console.warn(\n `SonareRealtimeVoiceChangerWorkletProcessor: requested ${frames} mono frames ` +\n `exceeds pre-allocated capacity ${capacity}; clamping. ` +\n 'Increase blockSize at construction time to avoid this.',\n );\n }\n return capacity;\n }\n\n /**\n * Same contract as ensureMonoCapacity but for the planar per-channel\n * scratch. Returns the number of frames that fit in the available capacity.\n */\n private ensureInterleavedCapacity(frames: number, channels: number): number {\n const capacity = this.planarChannels[0]?.length ?? 0;\n if (frames <= capacity) {\n return frames;\n }\n if (!SonareRealtimeVoiceChangerWorkletProcessor.warnedInterleavedOverflow) {\n SonareRealtimeVoiceChangerWorkletProcessor.warnedInterleavedOverflow = true;\n // biome-ignore lint/suspicious/noConsole: realtime-safety diagnostic.\n console.warn(\n `SonareRealtimeVoiceChangerWorkletProcessor: requested ${frames}x${channels} ` +\n `planar frames exceeds pre-allocated capacity ${capacity}; clamping. ` +\n 'Increase blockSize or channelCount at construction time to avoid this.',\n );\n }\n return capacity;\n }\n}\n\nexport function registerSonareWorkletProcessor(name = 'sonare-worklet-processor'): void {\n const scope = globalThis as unknown as {\n AudioWorkletProcessor?: new () => object;\n registerProcessor?: (processorName: string, processorCtor: unknown) => void;\n };\n if (!scope.AudioWorkletProcessor || !scope.registerProcessor) {\n throw new Error('AudioWorkletProcessor is not available in this context.');\n }\n const Base = scope.AudioWorkletProcessor;\n class RegisteredSonareWorkletProcessor extends Base {\n private bridge: SonareWorkletProcessor;\n readonly port?: WorkletPort;\n\n constructor(options?: { processorOptions?: SonareWorkletProcessorOptions }) {\n super();\n const port = this.port;\n this.bridge = new SonareWorkletProcessor(options?.processorOptions ?? { sceneJson: '' }, {\n postMessage: (message) => port?.postMessage?.(message),\n });\n const onMessage = (event: { data: unknown }) => {\n if (isWorkletMessage(event.data)) {\n this.bridge.receiveMessage(event.data);\n }\n };\n if (port?.addEventListener) {\n port.addEventListener('message', onMessage);\n port.start?.();\n } else if (port) {\n port.onmessage = onMessage;\n }\n }\n\n process(inputs: WorkletInput, outputs: WorkletOutput): boolean {\n return this.bridge.process(inputs, outputs);\n }\n }\n scope.registerProcessor(name, RegisteredSonareWorkletProcessor);\n}\n\nexport function registerSonareRealtimeVoiceChangerWorkletProcessor(\n name = 'sonare-realtime-voice-changer-processor',\n): void {\n const scope = globalThis as unknown as {\n AudioWorkletProcessor?: new () => object;\n registerProcessor?: (processorName: string, processorCtor: unknown) => void;\n };\n if (!scope.AudioWorkletProcessor || !scope.registerProcessor) {\n throw new Error('AudioWorkletProcessor is not available in this context.');\n }\n const Base = scope.AudioWorkletProcessor;\n class RegisteredSonareRealtimeVoiceChangerWorkletProcessor extends Base {\n private bridge: SonareRealtimeVoiceChangerWorkletProcessor;\n readonly port?: WorkletPort;\n\n constructor(options?: {\n processorOptions?: SonareRealtimeVoiceChangerWorkletProcessorOptions;\n }) {\n super();\n const port = this.port;\n this.bridge = new SonareRealtimeVoiceChangerWorkletProcessor(options?.processorOptions ?? {});\n const onMessage = (event: { data: unknown }) => {\n if (isRealtimeVoiceChangerMessage(event.data)) {\n this.bridge.receiveMessage(event.data);\n }\n };\n if (port?.addEventListener) {\n port.addEventListener('message', onMessage);\n port.start?.();\n } else if (port) {\n port.onmessage = onMessage;\n }\n }\n\n process(inputs: WorkletInput, outputs: WorkletOutput): boolean {\n return this.bridge.process(inputs, outputs);\n }\n }\n scope.registerProcessor(name, RegisteredSonareRealtimeVoiceChangerWorkletProcessor);\n}\n\nexport function registerSonareRealtimeEngineWorkletProcessor(\n name = 'sonare-realtime-engine-processor',\n): void {\n const scope = globalThis as unknown as {\n AudioWorkletProcessor?: new () => object;\n registerProcessor?: (processorName: string, processorCtor: unknown) => void;\n };\n if (!scope.AudioWorkletProcessor || !scope.registerProcessor) {\n throw new Error('AudioWorkletProcessor is not available in this context.');\n }\n const Base = scope.AudioWorkletProcessor;\n class RegisteredSonareRealtimeEngineWorkletProcessor extends Base {\n private bridge?: SonareRealtimeEngineWorkletProcessor;\n private rtBridge?: SonareRtRealtimeEngineRuntime;\n private readonly pendingMessages: unknown[] = [];\n readonly port?: WorkletPort;\n\n constructor(options?: { processorOptions?: SonareRealtimeEngineWorkletProcessorOptions }) {\n super();\n const port = this.port;\n const processorOptions = options?.processorOptions ?? {};\n if (processorOptions.runtimeTarget === 'sonare-rt') {\n void this.initializeSonareRt(processorOptions, port);\n } else {\n void this.initializeEmbind(processorOptions, port);\n }\n const onMessage = (event: { data: unknown }) => {\n if (!this.bridge && !this.rtBridge) {\n if (this.pendingMessages.length < 1024) {\n this.pendingMessages.push(event.data);\n }\n return;\n }\n if (isEngineCommandRecord(event.data)) {\n this.bridge?.receiveCommand(event.data);\n this.rtBridge?.receiveCommand(event.data);\n } else if (isEngineSyncMessage(event.data)) {\n this.bridge?.receiveSync(event.data);\n this.rtBridge?.receiveSync(event.data);\n } else if (isEngineCaptureRequestMessage(event.data)) {\n this.bridge?.receiveCaptureRequest(event.data);\n this.rtBridge?.receiveCaptureRequest(event.data, port);\n } else if (isEngineTransportRequestMessage(event.data)) {\n this.bridge?.receiveTransportRequest(event.data);\n this.rtBridge?.receiveTransportRequest(event.data, port);\n }\n };\n if (port?.addEventListener) {\n port.addEventListener('message', onMessage);\n port.start?.();\n } else if (port) {\n port.onmessage = onMessage;\n }\n }\n\n process(inputs: WorkletInput, outputs: WorkletOutput): boolean {\n if (this.rtBridge) {\n return this.rtBridge.process(inputs, outputs);\n }\n if (this.bridge) {\n return this.bridge.process(inputs, outputs);\n }\n const output = outputs[0];\n for (const channel of output ?? []) {\n channel.fill(0);\n }\n return true;\n }\n\n private replayPendingMessages(port?: WorkletPort): void {\n const messages = this.pendingMessages.splice(0);\n for (const data of messages) {\n if (isEngineCommandRecord(data)) {\n this.bridge?.receiveCommand(data);\n this.rtBridge?.receiveCommand(data);\n } else if (isEngineSyncMessage(data)) {\n this.bridge?.receiveSync(data);\n this.rtBridge?.receiveSync(data);\n } else if (isEngineCaptureRequestMessage(data)) {\n this.bridge?.receiveCaptureRequest(data);\n this.rtBridge?.receiveCaptureRequest(data, port);\n } else if (isEngineTransportRequestMessage(data)) {\n this.bridge?.receiveTransportRequest(data);\n this.rtBridge?.receiveTransportRequest(data, port);\n }\n }\n }\n\n private async initializeEmbind(\n options: SonareRealtimeEngineWorkletProcessorOptions,\n port?: WorkletPort,\n ): Promise<void> {\n try {\n const initPromise = (\n globalThis as typeof globalThis & { SonareEmbindInitPromise?: Promise<void> }\n ).SonareEmbindInitPromise;\n if (initPromise) {\n await initPromise;\n }\n if (!isInitialized()) {\n type EmbindModuleFactory = (options?: {\n locateFile?: (path: string, prefix: string) => string;\n wasmBinary?: ArrayBuffer | Uint8Array;\n }) => Promise<SonareModule>;\n const moduleFactory = (\n globalThis as typeof globalThis & {\n SonareEmbindModuleFactory?: EmbindModuleFactory;\n }\n ).SonareEmbindModuleFactory;\n if (!moduleFactory) {\n throw new Error('embind realtime engine module is not initialized.');\n }\n await initSonareModule({\n locateFile: (path) => path,\n wasmBinary: options.wasmBinary,\n moduleFactory,\n });\n }\n this.bridge = new SonareRealtimeEngineWorkletProcessor(options, {\n postMessage: (message) => port?.postMessage?.(message),\n onMeter: (meter) => port?.postMessage?.(meter),\n });\n for (const message of options.initialSyncMessages ?? []) {\n this.bridge.receiveSync(message);\n }\n for (const command of options.initialCommands ?? []) {\n this.bridge.receiveCommand(command);\n }\n this.replayPendingMessages(port);\n port?.postMessage?.({ type: 'ready', runtimeTarget: 'embind' });\n } catch (error) {\n port?.postMessage?.({\n type: 'error',\n message: error instanceof Error ? error.message : String(error),\n });\n }\n }\n\n private async initializeSonareRt(\n options: SonareRealtimeEngineWorkletProcessorOptions,\n port?: WorkletPort,\n ): Promise<void> {\n try {\n if (!options.rtModuleUrl) {\n throw new Error('rtModuleUrl is required for sonare-rt AudioWorklet runtime.');\n }\n const rtModuleUrl = options.rtModuleUrl;\n const memory = new WebAssembly.Memory({ initial: 1024, maximum: 1024, shared: true });\n const globalFactory = (\n globalThis as typeof globalThis & {\n SonareRtModuleFactory?: (options?: {\n wasmMemory?: WebAssembly.Memory;\n wasmBinary?: ArrayBuffer | Uint8Array;\n locateFile?: (path: string) => string;\n }) => Promise<SonareRtModule>;\n }\n ).SonareRtModuleFactory;\n const moduleFactory = globalFactory\n ? { default: globalFactory }\n : ((await import(rtModuleUrl)) as {\n default: (options?: {\n wasmMemory?: WebAssembly.Memory;\n wasmBinary?: ArrayBuffer | Uint8Array;\n locateFile?: (path: string) => string;\n }) => Promise<SonareRtModule>;\n });\n const module = await moduleFactory.default({\n wasmMemory: memory,\n wasmBinary: options.rtWasmBinary,\n locateFile: (path) => rtModuleUrl.replace(/[^/]*$/, path),\n });\n this.rtBridge = new SonareRtRealtimeEngineRuntime({\n module,\n memory,\n sampleRate: options.sampleRate,\n blockSize: options.blockSize,\n channelCount: options.channelCount,\n commandSharedBuffer: options.commandSharedBuffer,\n commandRingCapacity: options.commandRingCapacity,\n telemetrySharedBuffer: options.telemetrySharedBuffer,\n telemetryRingCapacity: options.telemetryRingCapacity,\n });\n this.replayPendingMessages(port);\n port?.postMessage?.({ type: 'ready', runtimeTarget: 'sonare-rt' });\n } catch (error) {\n port?.postMessage?.({\n type: 'error',\n message: error instanceof Error ? error.message : String(error),\n });\n }\n }\n }\n scope.registerProcessor(name, RegisteredSonareRealtimeEngineWorkletProcessor);\n}\n"],"mappings":"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","names":["module","module","module","module","SonareEngineCommandType","SonareEngineTelemetryType","SonareEngineTelemetryError","paramId","frames","initPromise","module"]}
1
+ {"version":3,"sources":["../src/codes.ts","../src/errors.ts","../src/module_state.ts","../src/mixer.ts","../src/realtime_voice_changer.ts","../src/realtime_engine.ts","../src/index.ts","../src/worklet/protocol.ts","../src/worklet/guards.ts","../src/worklet/messages.ts","../src/worklet.ts"],"sourcesContent":["import type { AutomationCurve, MeterTap, PanLaw, PanMode, SendTiming } from './public_types';\n\nexport function automationCurveCode(curve: AutomationCurve): number {\n switch (curve) {\n case 'linear':\n return 0;\n case 'exponential':\n return 1;\n case 'hold':\n return 2;\n case 's-curve':\n return 3;\n default:\n throw new Error(`Invalid automation curve: ${curve}`);\n }\n}\n\nexport function panLawCode(panLaw: PanLaw | number): number {\n if (typeof panLaw === 'number') {\n return panLaw;\n }\n switch (panLaw) {\n case 'const4.5dB':\n return 1;\n case 'const6dB':\n return 2;\n case 'linear0dB':\n return 3;\n default:\n return 0;\n }\n}\n\nexport function panModeCode(panMode: PanMode | number): number {\n if (typeof panMode === 'number') {\n return panMode;\n }\n switch (panMode) {\n case 'stereoPan':\n case 'stereo-pan':\n return 1;\n case 'dualPan':\n case 'dual-pan':\n return 2;\n default:\n return 0;\n }\n}\n\nexport function meterTapCode(tap: MeterTap | number): number {\n return tap === 'preFader' || tap === 0 ? 0 : 1;\n}\n\nexport function sendTimingCode(timing: SendTiming | number): number {\n // Mirrors SonareSendTiming: post-fader is 0 (so an omitted/zeroed value is\n // post-fader), pre-fader is 1. A raw number is passed through as the C ABI int.\n if (typeof timing === 'number') {\n return timing;\n }\n return timing === 'preFader' ? 1 : 0;\n}\n","/**\n * Numeric error codes carried by a {@link SonareError}. Mirrors the C ABI\n * `SonareError` enum (and the Node / Python surfaces), so the same failure\n * reports the same numeric code on every binding.\n */\nexport enum ErrorCode {\n Ok = 0,\n FileNotFound = 1,\n InvalidFormat = 2,\n DecodeFailed = 3,\n InvalidParameter = 4,\n OutOfMemory = 5,\n NotSupported = 6,\n InvalidState = 7,\n Unknown = 99,\n}\n\n/**\n * Error thrown by libsonare on a native (C++) failure. Carries a numeric\n * {@link ErrorCode} `code` plus its canonical `codeName`, so callers can branch\n * on the cause instead of matching message text.\n */\nexport class SonareError extends Error {\n /** Numeric error code, equal to an {@link ErrorCode} value. */\n readonly code: number;\n /** Canonical name of `code`, e.g. `'InvalidParameter'`. */\n readonly codeName: string;\n\n constructor(code: number, codeName: string, message: string) {\n super(message);\n this.name = 'SonareError';\n this.code = code;\n this.codeName = codeName;\n }\n}\n\n/** Type guard: whether a caught value is a libsonare {@link SonareError}. */\nexport function isSonareError(value: unknown): value is SonareError {\n return (\n value instanceof Error &&\n (value as { name?: unknown }).name === 'SonareError' &&\n typeof (value as { code?: unknown }).code === 'number'\n );\n}\n","import { ErrorCode, SonareError } from './errors';\nimport type { SonareModule } from './sonare.js';\n\nlet wrappedModule: SonareModule | null = null;\n\n/**\n * Shape of the structured info the native `sonareExceptionInfo(ptr)` returns.\n */\ninterface NativeExceptionInfo {\n code: number;\n codeName: string;\n message: string;\n}\n\n/**\n * Recover the native exception-object pointer from a value thrown across the\n * WASM boundary. emscripten surfaces a C++ throw in two shapes depending on the\n * toolchain/exception mode:\n * - a raw pointer number (older / classic surfacing), or\n * - a `CppException` object exposing the pointer as `excPtr` (emscripten with\n * `-fexceptions`).\n * Returns null when the thrown value is neither (a genuine JS error), so the\n * caller rethrows it unchanged.\n */\nfunction nativeExceptionPtr(error: unknown): number | null {\n if (typeof error === 'number') {\n return error;\n }\n if (error !== null && typeof error === 'object') {\n const ptr = (error as { excPtr?: unknown }).excPtr;\n if (typeof ptr === 'number') {\n return ptr;\n }\n }\n return null;\n}\n\n/**\n * Turn a thrown native exception pointer into a {@link SonareError}. The bound\n * `sonareExceptionInfo` decodes the pointer back into { code, codeName,\n * message }.\n */\nfunction makeSonareError(raw: SonareModule, thrown: number): SonareError {\n let code: number = ErrorCode.Unknown;\n let codeName = 'Unknown';\n let message = `libsonare native exception (${thrown})`;\n try {\n const info = (\n raw as unknown as { sonareExceptionInfo?: (ptr: number) => NativeExceptionInfo }\n ).sonareExceptionInfo?.(thrown);\n if (info) {\n code = info.code ?? code;\n codeName = info.codeName ?? codeName;\n message = info.message || message;\n }\n } catch {\n // Fall back to the generic message if decoding fails.\n }\n return new SonareError(code, codeName, message);\n}\n\n/**\n * Wrap the embind module so a native C++ exception (which surfaces as a raw\n * pointer number or a `CppException` carrying one) is rethrown as a\n * {@link SonareError}. Only function-valued\n * members are wrapped, and the wrapper is cached per member so repeated access\n * stays cheap; non-function members (typed-array heap views, etc.) pass through\n * unchanged. The dedicated realtime `sonare-rt` module is separate and is not\n * affected by this wrapper.\n */\nfunction wrapModuleErrors(raw: SonareModule): SonareModule {\n const cache = new Map<PropertyKey, unknown>();\n const objectCache = new WeakMap<object, unknown>();\n const convert = (error: unknown): never => {\n const ptr = nativeExceptionPtr(error);\n if (ptr !== null) {\n throw makeSonareError(raw, ptr);\n }\n throw error;\n };\n\n const wrapNativeObject = (value: unknown): unknown => {\n if (value === null || typeof value !== 'object') {\n return value;\n }\n if (ArrayBuffer.isView(value) || value instanceof ArrayBuffer || value instanceof Promise) {\n return value;\n }\n const objectValue = value as object;\n const cached = objectCache.get(objectValue);\n if (cached) {\n return cached;\n }\n const methodCache = new Map<PropertyKey, unknown>();\n const wrapped = new Proxy(objectValue, {\n get(target, prop, receiver) {\n const member = Reflect.get(target, prop, receiver);\n if (typeof member !== 'function') {\n return member;\n }\n const cachedMethod = methodCache.get(prop);\n if (cachedMethod) {\n return cachedMethod;\n }\n const method = member as (...a: unknown[]) => unknown;\n const wrappedMethod = (...args: unknown[]) => {\n try {\n return wrapNativeObject(Reflect.apply(method, target, args));\n } catch (error) {\n return convert(error);\n }\n };\n methodCache.set(prop, wrappedMethod);\n return wrappedMethod;\n },\n });\n objectCache.set(objectValue, wrapped);\n return wrapped;\n };\n\n const wrapFunction = (value: (...a: unknown[]) => unknown): unknown => {\n const fnCache = new Map<PropertyKey, unknown>();\n return new Proxy(value, {\n get(target, prop, receiver) {\n const member = Reflect.get(target, prop, receiver);\n if (typeof member !== 'function') {\n return member;\n }\n const cachedMember = fnCache.get(prop);\n if (cachedMember) {\n return cachedMember;\n }\n const fn = member as (...a: unknown[]) => unknown;\n const wrappedMember = (...args: unknown[]) => {\n try {\n return wrapNativeObject(Reflect.apply(fn, target, args));\n } catch (error) {\n return convert(error);\n }\n };\n fnCache.set(prop, wrappedMember);\n return wrappedMember;\n },\n apply(t, thisArg, args) {\n try {\n return wrapNativeObject(Reflect.apply(t, thisArg, args as unknown[]));\n } catch (error) {\n return convert(error);\n }\n },\n construct(t, args, newTarget) {\n try {\n return wrapNativeObject(Reflect.construct(t, args as unknown[], newTarget));\n } catch (error) {\n return convert(error) as object;\n }\n },\n });\n };\n\n return new Proxy(raw, {\n get(target, prop, receiver) {\n const value = Reflect.get(target, prop, receiver);\n if (typeof value !== 'function') {\n return value;\n }\n const cached = cache.get(prop);\n if (cached) {\n return cached;\n }\n // Wrap as a Proxy (not a plain function) so embind class constructors\n // invoked via `new module.Foo(...)` keep their `[[Construct]]` behaviour\n // and prototype while still converting thrown native pointers.\n const wrapped = wrapFunction(value as (...a: unknown[]) => unknown);\n cache.set(prop, wrapped);\n return wrapped;\n },\n }) as SonareModule;\n}\n\nexport function setSonareModule(module: SonareModule): void {\n wrappedModule = wrapModuleErrors(module);\n}\n\nexport function getSonareModule(): SonareModule {\n if (!wrappedModule) {\n throw new Error('Module not initialized. Call init() first.');\n }\n return wrappedModule;\n}\n","import {\n automationCurveCode,\n meterTapCode,\n panLawCode,\n panModeCode,\n sendTimingCode,\n} from './codes';\nimport { getSonareModule } from './module_state';\nimport type {\n AutomationCurve,\n GoniometerPoint,\n MeterTap,\n MixerProcessResult,\n MixMeterSnapshot,\n PanLaw,\n PanMode,\n SendTiming,\n SurroundPan,\n} from './public_types';\n\nexport interface MixerRealtimeBuffer {\n leftInputs: Float32Array[];\n rightInputs: Float32Array[];\n outLeft: Float32Array;\n outRight: Float32Array;\n process: (numSamples?: number) => void;\n}\n\n// ============================================================================\n// Mixer Class (scene-based persistent mixer)\n// ============================================================================\n\n/**\n * Persistent, scene-based stereo mixer.\n *\n * Build one from a scene JSON string (e.g. {@link mixingScenePresetJson} or a\n * hand-authored scene), then feed per-strip stereo blocks through\n * {@link processStereo} to get the routed stereo master. Strips, sends, buses,\n * and inserts are described entirely by the scene; the routing graph is\n * compiled lazily on the first {@link processStereo} call (or eagerly via\n * {@link compile}).\n *\n * Call {@link delete} (or use a `try/finally`) to release the underlying WASM\n * object — the embind handle is not garbage-collected automatically.\n *\n * @example\n * ```typescript\n * const mixer = Mixer.fromSceneJson(mixingScenePresetJson('basicStereo'), 48000, 512);\n * try {\n * const out = mixer.processStereo([stripL], [stripR]);\n * } finally {\n * mixer.delete();\n * }\n * ```\n */\nexport class Mixer {\n private mixer: import('./sonare.js').WasmMixer;\n\n private constructor(mixer: import('./sonare.js').WasmMixer) {\n this.mixer = mixer;\n }\n\n /**\n * Build a mixer from a scene JSON string.\n *\n * @param json - Scene JSON (strips, buses, sends, connections, inserts)\n * @param sampleRate - Sample rate in Hz (default: 48000)\n * @param blockSize - Maximum block size per {@link processStereo} call (default: 512)\n */\n static fromSceneJson(json: string, sampleRate = 48000, blockSize = 512): Mixer {\n const module = getSonareModule();\n return new Mixer(module.createMixerFromSceneJson(json, sampleRate, blockSize));\n }\n\n /** Rebuild and compile the routing graph from the current scene topology. */\n compile(): void {\n this.mixer.compile();\n }\n\n /**\n * Non-fatal warnings captured when this mixer was built from scene JSON: one\n * entry per channel-strip insert that was handed param keys it does not read\n * (a likely typo, or a key meant for a different processor). The scene still\n * loaded; these keys simply took no effect. Empty when every key was consumed.\n * Use {@link masteringInsertParamNames} to discover the keys an insert accepts.\n */\n sceneWarnings(): string[] {\n return this.mixer.sceneWarnings();\n }\n\n /**\n * Mix one block of per-strip stereo audio into the stereo master.\n *\n * @param leftChannels - `leftChannels[i]` is the left channel of strip `i`\n * @param rightChannels - `rightChannels[i]` is the right channel of strip `i`\n * @returns Mixed stereo master (`left`, `right`, `sampleRate`)\n */\n processStereo(leftChannels: Float32Array[], rightChannels: Float32Array[]): MixerProcessResult {\n if (leftChannels.length !== rightChannels.length) {\n throw new Error('leftChannels and rightChannels must have the same length.');\n }\n return this.mixer.processStereo(leftChannels, rightChannels);\n }\n\n /**\n * Mix one block into caller-owned output arrays.\n *\n * This avoids allocating the result object and result `Float32Array`s. It is\n * intended for realtime bridges such as AudioWorklet; the input channel count\n * must match the scene strip count and all arrays must have the same length.\n */\n processStereoInto(\n leftChannels: Float32Array[],\n rightChannels: Float32Array[],\n outLeft: Float32Array,\n outRight: Float32Array,\n ): void {\n if (leftChannels.length !== rightChannels.length) {\n throw new Error('leftChannels and rightChannels must have the same length.');\n }\n if (outLeft.length !== outRight.length) {\n throw new Error('outLeft and outRight must have the same length.');\n }\n this.mixer.processStereoInto(leftChannels, rightChannels, outLeft, outRight);\n }\n\n /**\n * Create reusable WASM-heap input/output views for realtime-style processing.\n *\n * Fill `leftInputs[i]` / `rightInputs[i]`, call `process()`, then read\n * `outLeft` / `outRight`. The views are owned by this mixer and become invalid\n * after {@link delete}.\n */\n createRealtimeBuffer(): MixerRealtimeBuffer {\n const stripCount = this.stripCount();\n let leftInputs: Float32Array[] = [];\n let rightInputs: Float32Array[] = [];\n let outLeft = this.mixer.outputLeftView();\n let outRight = this.mixer.outputRightView();\n const acquire = (): void => {\n leftInputs = [];\n rightInputs = [];\n for (let index = 0; index < stripCount; index++) {\n leftInputs.push(this.mixer.inputLeftView(index));\n rightInputs.push(this.mixer.inputRightView(index));\n }\n outLeft = this.mixer.outputLeftView();\n outRight = this.mixer.outputRightView();\n };\n acquire();\n // The cached heap views can detach if WASM linear memory grows (the embind\n // module is built ALLOW_MEMORY_GROWTH). Re-acquire them if detached\n // (byteLength === 0) before use, mirroring the worklet RT path.\n const reacquireIfDetached = (): void => {\n if (outLeft.byteLength === 0 || (leftInputs[0]?.byteLength ?? 1) === 0) {\n acquire();\n }\n };\n return {\n get leftInputs(): Float32Array[] {\n reacquireIfDetached();\n return leftInputs;\n },\n get rightInputs(): Float32Array[] {\n reacquireIfDetached();\n return rightInputs;\n },\n get outLeft(): Float32Array {\n reacquireIfDetached();\n return outLeft;\n },\n get outRight(): Float32Array {\n reacquireIfDetached();\n return outRight;\n },\n process: (numSamples = outLeft.length) => {\n reacquireIfDetached();\n this.mixer.processPreparedStereo(numSamples);\n },\n };\n }\n\n /** Number of strips in the mixer (e.g. strips loaded from the scene). */\n stripCount(): number {\n return this.mixer.stripCount();\n }\n\n /**\n * Schedule sample-accurate insert-parameter automation on a strip's insert.\n *\n * @param stripIndex - Strip index in `[0, stripCount())`\n * @param insertIndex - Index into the strip's combined insert sequence\n * (`[pre-inserts... post-inserts...]`)\n * @param paramId - Processor-specific parameter id\n * @param samplePos - Absolute samples from the start of processing (the mixer\n * advances an internal position from 0 on the first {@link processStereo}\n * call; recompiling resets it to 0)\n * @param value - Target parameter value\n * @param curve - Interpolation curve (default: `'linear'`)\n * @throws If the strip index is out of range or the schedule call fails\n * (unknown curve, out-of-range insert index, or full event lane)\n */\n scheduleInsertAutomation(\n stripIndex: number,\n insertIndex: number,\n paramId: number,\n samplePos: number,\n value: number,\n curve: AutomationCurve = 'linear',\n ): void {\n this.mixer.scheduleInsertAutomation(\n stripIndex,\n insertIndex,\n paramId,\n samplePos,\n value,\n automationCurveCode(curve),\n );\n }\n\n /**\n * Resolve a strip's index in `[0, stripCount())` from its scene id, or `null`\n * when no strip with that id exists (matches the Node binding's `number | null`).\n */\n stripById(id: string): number | null {\n const index = this.mixer.stripById(id);\n return index < 0 ? null : index;\n }\n\n /**\n * Add a bus to the mixer topology. `role` is one of `'master'`, `'aux'`, or\n * `'submix'` (defaults to `'aux'`). Marks the routing graph dirty; call\n * {@link compile} (or {@link processStereo}) to rebuild.\n */\n addBus(id: string, role = 'aux'): void {\n this.mixer.addBus(id, role);\n }\n\n /** Remove a bus by id. Marks the routing graph dirty. */\n removeBus(id: string): void {\n this.mixer.removeBus(id);\n }\n\n /** Number of buses in the mixer topology. */\n busCount(): number {\n return this.mixer.busCount();\n }\n\n /**\n * Add a VCA group with the given gain offset (dB). `members` is a list of\n * strip ids governed by the group (may be empty).\n */\n addVcaGroup(id: string, gainDb = 0.0, members: string[] = []): void {\n this.mixer.addVcaGroup(id, gainDb, members);\n }\n\n /** Set an existing VCA group's gain in dB. */\n setVcaGroupGainDb(id: string, gainDb: number): void {\n this.mixer.setVcaGroupGainDb(id, gainDb);\n }\n\n /** Remove a VCA group by id. */\n removeVcaGroup(id: string): void {\n this.mixer.removeVcaGroup(id);\n }\n\n /** Number of VCA groups in the mixer topology. */\n vcaGroupCount(): number {\n return this.mixer.vcaGroupCount();\n }\n\n /** Set the strip's input trim in dB. */\n setInputTrimDb(stripIndex: number, db: number): void {\n this.mixer.setInputTrimDb(stripIndex, db);\n }\n\n /** Set the strip's fader level in dB. */\n setFaderDb(stripIndex: number, db: number): void {\n this.mixer.setFaderDb(stripIndex, db);\n }\n\n /**\n * Set the strip's pan position.\n *\n * @param stripIndex - Strip index in `[0, stripCount())`\n * @param pan - Pan position in `[-1, 1]`\n * @param panMode - Optional pan mode. When omitted the strip's current pan\n * mode is kept (passes `SONARE_PAN_MODE_KEEP`), so a plain pan nudge does\n * not reset a scene-defined `'stereoPan'` / `'dualPan'` mode back to\n * balance. Pass `'balance'` (or `0`) explicitly to force balance mode.\n */\n setPan(stripIndex: number, pan: number, panMode?: PanMode | number): void {\n // SONARE_PAN_MODE_KEEP (-1) = keep the strip's current pan mode.\n const mode = panMode === undefined ? -1 : panModeCode(panMode);\n this.mixer.setPan(stripIndex, pan, mode);\n }\n\n /** Set the strip's stereo width. */\n setWidth(stripIndex: number, width: number): void {\n this.mixer.setWidth(stripIndex, width);\n }\n\n /** Set the strip's mute state. */\n setMuted(stripIndex: number, muted: boolean): void {\n this.mixer.setMuted(stripIndex, muted);\n }\n\n /**\n * Set a strip's solo state. Takes effect on the next process without a\n * graph recompile.\n */\n setSoloed(stripIndex: number, soloed: boolean): void {\n this.mixer.setSoloed(stripIndex, soloed);\n }\n\n /**\n * Mark a strip solo-safe so it is never implied-muted by another strip's\n * solo. Takes effect on the next process without a graph recompile.\n */\n setSoloSafe(stripIndex: number, soloSafe: boolean): void {\n this.mixer.setSoloSafe(stripIndex, soloSafe);\n }\n\n /** Invert the polarity of the left and/or right channel of a strip. */\n setPolarityInvert(stripIndex: number, invertLeft: boolean, invertRight: boolean): void {\n this.mixer.setPolarityInvert(stripIndex, invertLeft, invertRight);\n }\n\n /** Set the strip's pan law. */\n setPanLaw(stripIndex: number, panLaw: PanLaw | number): void {\n this.mixer.setPanLaw(stripIndex, panLawCode(panLaw));\n }\n\n /**\n * Set a per-strip channel delay in samples. This changes the strip's reported\n * latency; recompile to re-run latency compensation.\n */\n setChannelDelaySamples(stripIndex: number, delaySamples: number): void {\n this.mixer.setChannelDelaySamples(stripIndex, delaySamples);\n }\n\n /** Set the strip's live VCA gain offset in dB (not persisted to the scene). */\n setVcaOffsetDb(stripIndex: number, offsetDb: number): void {\n this.mixer.setVcaOffsetDb(stripIndex, offsetDb);\n }\n\n /** Set independent left/right pan positions (dual-pan mode). */\n setDualPan(stripIndex: number, leftPan: number, rightPan: number): void {\n this.mixer.setDualPan(stripIndex, leftPan, rightPan);\n }\n\n /**\n * Set the strip's surround pan position, used when it feeds a >2-channel bus.\n * Stored on the scene; inert until the surround DSP path applies it.\n */\n setSurroundPan(stripIndex: number, pan: SurroundPan): void {\n this.mixer.setSurroundPan(stripIndex, pan);\n }\n\n /**\n * Add a send to a strip after construction.\n *\n * @param stripIndex - Strip index in `[0, stripCount())`\n * @param id - Send id\n * @param destinationBusId - Destination bus id\n * @param sendDb - Initial send level in dB\n * @param timing - `'preFader'` or `'postFader'` (default: `'postFader'`)\n * @returns The new send's index\n */\n addSend(\n stripIndex: number,\n id: string,\n destinationBusId: string,\n sendDb = 0.0,\n timing: SendTiming | number = 'postFader',\n ): number {\n return this.mixer.addSend(stripIndex, id, destinationBusId, sendDb, sendTimingCode(timing));\n }\n\n /** Set the send level (in dB) for an existing send by index. */\n setSendDb(stripIndex: number, sendIndex: number, sendDb: number): void {\n this.mixer.setSendDb(stripIndex, sendIndex, sendDb);\n }\n\n /**\n * Remove an existing send from a strip by index.\n *\n * Sends are addressed in add order. After removal, sends with a higher index\n * than `sendIndex` shift down by one. Recompile (or process) before reading\n * results so the routing graph rebuilds.\n *\n * @param stripIndex - Strip index in `[0, stripCount())`\n * @param sendIndex - Send index in add order\n */\n removeSend(stripIndex: number, sendIndex: number): void {\n this.mixer.removeSend(stripIndex, sendIndex);\n }\n\n /**\n * Read a strip's meter snapshot at the given tap point.\n *\n * @param stripIndex - Strip index in `[0, stripCount())`\n * @param tap - `'preFader'` or `'postFader'` (default: `'postFader'`)\n */\n meterTap(stripIndex: number, tap: MeterTap = 'postFader'): MixMeterSnapshot {\n return this.mixer.meterTap(stripIndex, meterTapCode(tap));\n }\n\n /**\n * Read a strip's meter snapshot.\n *\n * With no `tap` argument this reads the strip's own (post-fader) meter,\n * matching the Node/Python tap-less `stripMeter` contract. Pass an optional\n * `tap` (`'preFader'` / `'postFader'`) to read the tap-selectable snapshot\n * instead — the same backing call as {@link meterTap}.\n *\n * @param stripIndex - Strip index in `[0, stripCount())`\n * @param tap - Optional tap point (`'preFader'` / `'postFader'`); when omitted\n * the tap-less post-fader strip meter is read.\n */\n stripMeter(stripIndex: number, tap?: MeterTap | number): MixMeterSnapshot {\n if (tap === undefined) {\n return this.mixer.stripMeter(stripIndex);\n }\n return this.mixer.meterTap(stripIndex, meterTapCode(tap));\n }\n\n /**\n * Schedule sample-accurate fader automation on a strip.\n *\n * @param stripIndex - Strip index in `[0, stripCount())`\n * @param samplePos - Absolute samples from the start of processing\n * @param faderDb - Target fader level in dB\n * @param curve - Interpolation curve (default: `'linear'`)\n */\n scheduleFaderAutomation(\n stripIndex: number,\n samplePos: number,\n faderDb: number,\n curve: AutomationCurve = 'linear',\n ): void {\n this.mixer.scheduleFaderAutomation(stripIndex, samplePos, faderDb, automationCurveCode(curve));\n }\n\n /**\n * Schedule sample-accurate pan automation on a strip.\n *\n * @param stripIndex - Strip index in `[0, stripCount())`\n * @param samplePos - Absolute samples from the start of processing\n * @param pan - Target pan position\n * @param curve - Interpolation curve (default: `'linear'`)\n */\n schedulePanAutomation(\n stripIndex: number,\n samplePos: number,\n pan: number,\n curve: AutomationCurve = 'linear',\n ): void {\n this.mixer.schedulePanAutomation(stripIndex, samplePos, pan, automationCurveCode(curve));\n }\n\n /**\n * Schedule sample-accurate width automation on a strip.\n *\n * @param stripIndex - Strip index in `[0, stripCount())`\n * @param samplePos - Absolute samples from the start of processing\n * @param width - Target stereo width\n * @param curve - Interpolation curve (default: `'linear'`)\n */\n scheduleWidthAutomation(\n stripIndex: number,\n samplePos: number,\n width: number,\n curve: AutomationCurve = 'linear',\n ): void {\n this.mixer.scheduleWidthAutomation(stripIndex, samplePos, width, automationCurveCode(curve));\n }\n\n /**\n * Schedule sample-accurate send-level automation on a strip's send.\n *\n * @param stripIndex - Strip index in `[0, stripCount())`\n * @param sendIndex - Send index in the strip's add order\n * @param samplePos - Absolute samples from the start of processing\n * @param db - Target send level in dB\n * @param curve - Interpolation curve (default: `'linear'`)\n */\n scheduleSendAutomation(\n stripIndex: number,\n sendIndex: number,\n samplePos: number,\n db: number,\n curve: AutomationCurve = 'linear',\n ): void {\n this.mixer.scheduleSendAutomation(\n stripIndex,\n sendIndex,\n samplePos,\n db,\n automationCurveCode(curve),\n );\n }\n\n /**\n * Read up to `maxPoints` of a strip's most recent goniometer samples\n * (oldest to newest).\n */\n readGoniometerLatest(stripIndex: number, maxPoints: number): GoniometerPoint[] {\n return this.mixer.readGoniometerLatest(stripIndex, maxPoints);\n }\n\n /** Serialize the current scene (strips, buses, sends, connections) to JSON. */\n toSceneJson(): string {\n return this.mixer.toSceneJson();\n }\n\n /**\n * Maximum processor tail length (samples) in the compiled mixer graph. Lazily\n * compiles the routing graph if the topology is dirty.\n */\n tailSamples(): number {\n return this.mixer.tailSamples();\n }\n\n /**\n * Drain delayed / tail audio by processing a zero-input block of `numSamples`\n * frames after the host stops feeding strip inputs. Returns the mixed stereo\n * master (`left`, `right`, `sampleRate`).\n */\n drainTailStereo(numSamples: number): MixerProcessResult {\n return this.mixer.drainTailStereo(numSamples);\n }\n\n /** Release the underlying WASM object. Safe to call only once. */\n delete(): void {\n this.mixer.delete();\n }\n\n /** Alias for {@link delete}, provided for cross-binding (Node) compatibility. */\n destroy(): void {\n this.delete();\n }\n}\n","import { getSonareModule } from './module_state';\nimport type { RealtimeVoiceChangerConfigInput, VoicePresetId } from './public_types';\n\n/**\n * Zero-copy realtime buffer pair for {@link RealtimeVoiceChanger} mono\n * processing. The `input` / `output` `Float32Array`s are typed-memory views\n * onto the WASM heap — write samples into `input`, call `process()`, then\n * read from `output`. The views are owned by the {@link RealtimeVoiceChanger}\n * and remain valid until `delete()` is called on it.\n */\nexport interface RealtimeVoiceChangerMonoBuffer {\n input: Float32Array;\n output: Float32Array;\n process: () => void;\n}\n\n/**\n * Zero-copy realtime buffer pair for {@link RealtimeVoiceChanger} interleaved\n * multi-channel processing. Layout is L0,R0,L1,R1,... for stereo. The views\n * are owned by the {@link RealtimeVoiceChanger}.\n */\nexport interface RealtimeVoiceChangerInterleavedBuffer {\n input: Float32Array;\n output: Float32Array;\n channels: number;\n process: () => void;\n}\n\n/**\n * Zero-copy realtime buffer for {@link RealtimeVoiceChanger} planar stereo\n * processing. Each entry in `channels` is a heap-backed `Float32Array` for one\n * channel (matching AudioWorklet's native layout). Process happens in place:\n * write samples into each channel view, call `process()`, then read back from\n * the same views.\n */\nexport interface RealtimeVoiceChangerPlanarBuffer {\n channels: Float32Array[];\n process: () => void;\n}\n\n// ============================================================================\n// RealtimeVoiceChanger Class\n// ============================================================================\n\nexport class RealtimeVoiceChanger {\n private changer: import('./sonare.js').WasmRealtimeVoiceChanger;\n\n constructor(config: RealtimeVoiceChangerConfigInput = 'neutral-monitor') {\n const module = getSonareModule();\n this.changer = module.createRealtimeVoiceChanger(config as Record<string, unknown> | string);\n }\n\n prepare(sampleRate: number, maxBlockSize = 128, channels = 1): void {\n this.changer.prepare(sampleRate, maxBlockSize, channels);\n }\n\n reset(): void {\n this.changer.reset();\n }\n\n setConfig(config: RealtimeVoiceChangerConfigInput): void {\n this.changer.setConfig(config as Record<string, unknown> | string);\n }\n\n configJson(): string {\n return this.changer.configJson();\n }\n\n latencySamples(): number {\n return this.changer.latencySamples();\n }\n\n processMono(samples: Float32Array): Float32Array {\n return this.changer.processMono(samples);\n }\n\n processMonoInto(samples: Float32Array, output: Float32Array): void {\n this.changer.processMonoInto(samples, output);\n }\n\n processInterleaved(samples: Float32Array, channels: number): Float32Array {\n return this.changer.processInterleaved(samples, channels);\n }\n\n processInterleavedInto(samples: Float32Array, channels: number, output: Float32Array): void {\n this.changer.processInterleavedInto(samples, channels, output);\n }\n\n /**\n * Acquire a typed-memory view onto the WASM heap for mono input.\n *\n * Write your input samples into the returned `Float32Array` directly (e.g.\n * via `input.set(source)`); no copy crosses the JS↔C++ bridge until\n * {@link processPreparedMono} is called. The view is owned by this\n * RealtimeVoiceChanger and becomes invalid after {@link delete}; it may\n * also be invalidated if you later call this method with a larger\n * `numSamples` value (the underlying buffer may be reallocated).\n */\n getMonoInputBuffer(numSamples: number): Float32Array {\n return this.changer.getMonoInputBuffer(numSamples);\n }\n\n /** Mono output view counterpart to {@link getMonoInputBuffer}. */\n getMonoOutputBuffer(numSamples: number): Float32Array {\n return this.changer.getMonoOutputBuffer(numSamples);\n }\n\n /**\n * Process the previously-acquired mono input buffer in place. The output\n * appears in the buffer returned by {@link getMonoOutputBuffer}. No JS↔C++\n * sample-level crossings happen on this call — it just hands control to\n * the underlying DSP on already-on-heap data.\n */\n processPreparedMono(numSamples: number): void {\n this.changer.processPreparedMono(numSamples);\n }\n\n /** Interleaved input view (layout L0,R0,L1,R1,...). */\n getInterleavedInputBuffer(numFrames: number, numChannels: number): Float32Array {\n return this.changer.getInterleavedInputBuffer(numFrames, numChannels);\n }\n\n /** Interleaved output view counterpart. */\n getInterleavedOutputBuffer(numFrames: number, numChannels: number): Float32Array {\n return this.changer.getInterleavedOutputBuffer(numFrames, numChannels);\n }\n\n /**\n * Process the previously-acquired interleaved buffer in place. Output\n * appears in the buffer returned by {@link getInterleavedOutputBuffer}.\n */\n processPreparedInterleaved(numFrames: number, numChannels: number): void {\n this.changer.processPreparedInterleaved(numFrames, numChannels);\n }\n\n /**\n * Planar-channel input/output view (one Float32Array per channel). Matches\n * AudioWorklet's native layout; processing happens in place.\n */\n getPlanarChannelBuffer(channel: number, numFrames: number): Float32Array {\n return this.changer.getPlanarChannelBuffer(channel, numFrames);\n }\n\n /**\n * Process the previously-acquired planar channel buffers in place. Each\n * channel must have been obtained from {@link getPlanarChannelBuffer}\n * with the same `numFrames`. Output replaces input in the same buffers.\n */\n processPreparedPlanar(numFrames: number): void {\n this.changer.processPreparedPlanar(numFrames);\n }\n\n /**\n * Convenience factory for the mono zero-copy path: returns the input/output\n * heap views plus a `process()` thunk wired to the same `numSamples`. The\n * views are reused across calls and become invalid after {@link delete}.\n */\n createRealtimeMonoBuffer(numSamples: number): RealtimeVoiceChangerMonoBuffer {\n let input = this.getMonoInputBuffer(numSamples);\n let output = this.getMonoOutputBuffer(numSamples);\n // The cached heap views can detach if WASM linear memory grows (the embind\n // module is built ALLOW_MEMORY_GROWTH). Re-acquire them if detached\n // (byteLength === 0) before use, mirroring the worklet RT path. In the\n // common no-growth case this is a cheap branch with no allocation.\n const reacquireIfDetached = (): void => {\n if (input.byteLength === 0 || output.byteLength === 0) {\n input = this.getMonoInputBuffer(numSamples);\n output = this.getMonoOutputBuffer(numSamples);\n }\n };\n return {\n get input(): Float32Array {\n reacquireIfDetached();\n return input;\n },\n get output(): Float32Array {\n reacquireIfDetached();\n return output;\n },\n process: () => {\n reacquireIfDetached();\n this.processPreparedMono(numSamples);\n },\n };\n }\n\n /** Same as {@link createRealtimeMonoBuffer} but for interleaved I/O. */\n createRealtimeInterleavedBuffer(\n numFrames: number,\n numChannels: number,\n ): RealtimeVoiceChangerInterleavedBuffer {\n let input = this.getInterleavedInputBuffer(numFrames, numChannels);\n let output = this.getInterleavedOutputBuffer(numFrames, numChannels);\n // Re-acquire detached views after WASM memory growth (see\n // createRealtimeMonoBuffer for rationale).\n const reacquireIfDetached = (): void => {\n if (input.byteLength === 0 || output.byteLength === 0) {\n input = this.getInterleavedInputBuffer(numFrames, numChannels);\n output = this.getInterleavedOutputBuffer(numFrames, numChannels);\n }\n };\n return {\n get input(): Float32Array {\n reacquireIfDetached();\n return input;\n },\n get output(): Float32Array {\n reacquireIfDetached();\n return output;\n },\n channels: numChannels,\n process: () => {\n reacquireIfDetached();\n this.processPreparedInterleaved(numFrames, numChannels);\n },\n };\n }\n\n /**\n * Convenience factory for the planar zero-copy path. Acquires one\n * heap-backed Float32Array per channel and returns a `process()` thunk\n * wired to the same `numFrames`. Buffers are reused across calls and\n * become invalid after {@link delete}.\n */\n createRealtimePlanarBuffer(\n numFrames: number,\n numChannels: number,\n ): RealtimeVoiceChangerPlanarBuffer {\n let channels: Float32Array[] = [];\n const acquire = (): void => {\n channels = [];\n for (let ch = 0; ch < numChannels; ch++) {\n channels.push(this.getPlanarChannelBuffer(ch, numFrames));\n }\n };\n acquire();\n // Re-acquire detached views after WASM memory growth (see\n // createRealtimeMonoBuffer for rationale).\n const reacquireIfDetached = (): void => {\n if ((channels[0]?.byteLength ?? 0) === 0) {\n acquire();\n }\n };\n return {\n get channels(): Float32Array[] {\n reacquireIfDetached();\n return channels;\n },\n process: () => {\n reacquireIfDetached();\n this.processPreparedPlanar(numFrames);\n },\n };\n }\n\n delete(): void {\n this.changer.delete();\n }\n}\n\nexport function realtimeVoiceChangerPresetNames(): VoicePresetId[] {\n // Array.from re-roots embind's vector as a plain, structured-cloneable Array.\n return Array.from(getSonareModule().realtimeVoiceChangerPresetNames()) as VoicePresetId[];\n}\n\nexport function realtimeVoiceChangerPresetJson(name: VoicePresetId): string {\n return getSonareModule().realtimeVoiceChangerPresetJson(name);\n}\n\nexport function validateRealtimeVoiceChangerPresetJson(json: string): {\n ok: boolean;\n normalizedJson?: string;\n error?: string;\n} {\n return getSonareModule().validateRealtimeVoiceChangerPresetJson(json);\n}\n","import { panLawCode, panModeCode, sendTimingCode } from './codes';\nimport { ErrorCode, SonareError } from './errors';\nimport { getSonareModule } from './module_state';\nimport type { SynthPatch } from './project';\nimport type { EqBand, PanLaw, PanMode, SendTiming } from './public_types';\nimport type {\n WasmClipPageRequest,\n WasmEngineAutomationPoint,\n WasmEngineBounceOptions,\n WasmEngineBounceResult,\n WasmEngineCaptureStatus,\n WasmEngineClip,\n WasmEngineFreezeOptions,\n WasmEngineFreezeResult,\n WasmEngineGraphSpec,\n WasmEngineMarker,\n WasmEngineMeterTelemetry,\n WasmEngineMeterTelemetryWide,\n WasmEngineMetronomeConfig,\n WasmEngineParameterInfo,\n WasmEngineProcessWithMonitorResult,\n WasmEngineScopeTelemetry,\n WasmEngineTelemetry,\n WasmEngineTempoSegment,\n WasmEngineTimeSignatureSegment,\n WasmEngineTransportState,\n WasmRealtimeEngine,\n} from './sonare.js';\n\nexport type EngineClip = WasmEngineClip;\nexport type ClipPageRequest = WasmClipPageRequest;\nexport type EngineParameterInfo = WasmEngineParameterInfo;\nexport type EngineAutomationPoint = WasmEngineAutomationPoint;\nexport type EngineMarker = WasmEngineMarker;\nexport type EngineMetronomeConfig = WasmEngineMetronomeConfig;\nexport type EngineGraphSpec = WasmEngineGraphSpec;\nexport type EngineCaptureStatus = WasmEngineCaptureStatus;\nexport type EngineBounceOptions = WasmEngineBounceOptions;\nexport type EngineBounceResult = WasmEngineBounceResult;\nexport type EngineFreezeOptions = WasmEngineFreezeOptions;\nexport type EngineFreezeResult = WasmEngineFreezeResult;\nexport type EngineTelemetry = WasmEngineTelemetry;\nexport type EngineMeterTelemetry = WasmEngineMeterTelemetry;\nexport type EngineMeterTelemetryWide = WasmEngineMeterTelemetryWide;\nexport type EngineScopeTelemetry = WasmEngineScopeTelemetry;\nexport type EngineTransportState = WasmEngineTransportState;\nexport type EngineTempoSegment = WasmEngineTempoSegment;\nexport type EngineTimeSignatureSegment = WasmEngineTimeSignatureSegment;\n\nexport interface EngineTrackSend {\n busId: number;\n levelDb?: number;\n enabled?: boolean;\n /**\n * Pre/post-fader tap point. Defaults to post-fader when omitted, matching the\n * historical lane-send behavior and the scene-JSON default.\n */\n sendTiming?: SendTiming | number;\n}\n\nexport interface EngineTrackLane {\n trackId: number;\n sends?: EngineTrackSend[];\n /**\n * Bus the lane's post-fader output sums into instead of the master mix\n * (group/folder routing); 0 or absent keeps the lane on the master mix.\n */\n outputBusId?: number;\n /**\n * Input channel layout of the source feeding this lane (`SonareChannelLayout`:\n * 0 mono, 1 stereo, 2 5.1, 3 7.1). Absent defaults to stereo. Stored but inert\n * until the surround DSP path lands.\n */\n sourceChannelLayout?: number;\n}\n\nexport interface EngineBus {\n busId: number;\n gainDb?: number;\n /**\n * Channel layout of the bus (`SonareChannelLayout`: 0 mono, 1 stereo, 2 5.1,\n * 3 7.1). A surround layout makes this a surround group bus: lanes routed to\n * it are surround-panned and it sums into the master plane-by-plane. Defaults\n * to stereo.\n */\n channelLayout?: number;\n}\n\nexport interface EngineMidiEvent {\n renderFrame: number;\n word0?: number;\n word1?: number;\n word2?: number;\n word3?: number;\n wordCount?: number;\n group?: number;\n sysexHandle?: number;\n data0?: number;\n data1?: number;\n}\n\nexport interface EngineMidiClipSchedule {\n id?: number;\n trackId?: number;\n destinationId?: number;\n startSample?: number;\n startPpq?: number;\n lengthSamples?: number;\n loop?: boolean;\n loopLengthSamples?: number;\n events: EngineMidiEvent[];\n}\n\nexport const EXPECTED_ENGINE_ABI_VERSION = 3;\n\n/** Options for {@link RealtimeEngine.bindMidiCc}. All fields are optional. */\nexport interface MidiCcBindOptions {\n /** Lower end of the mapped parameter range. Default `0`. */\n minValue?: number;\n /** Upper end of the mapped parameter range. Default `1`. */\n maxValue?: number;\n}\n\nexport interface EngineCapabilities {\n engineAbiVersion: number;\n expectedEngineAbiVersion: number;\n abiCompatible: boolean;\n sharedArrayBuffer: boolean;\n atomics: boolean;\n audioWorklet: boolean;\n mode: 'sab' | 'postMessage';\n}\n\nexport function engineCapabilities(): EngineCapabilities {\n const abiVersion = getSonareModule().engineAbiVersion();\n const sharedArrayBuffer = typeof globalThis.SharedArrayBuffer === 'function';\n const atomics = typeof globalThis.Atomics === 'object';\n const audioWorklet =\n typeof AudioWorkletNode !== 'undefined' ||\n typeof (globalThis as typeof globalThis & { AudioWorkletProcessor?: unknown })\n .AudioWorkletProcessor !== 'undefined';\n return {\n engineAbiVersion: abiVersion,\n expectedEngineAbiVersion: EXPECTED_ENGINE_ABI_VERSION,\n abiCompatible: abiVersion === EXPECTED_ENGINE_ABI_VERSION,\n sharedArrayBuffer,\n atomics,\n audioWorklet,\n mode: sharedArrayBuffer && atomics ? 'sab' : 'postMessage',\n };\n}\n\nexport class RealtimeEngine {\n private native: WasmRealtimeEngine;\n\n constructor(\n sampleRate = 48000,\n maxBlockSize = 128,\n commandCapacity = 1024,\n telemetryCapacity = 1024,\n ) {\n const module = getSonareModule();\n const capabilities = engineCapabilities();\n if (!capabilities.abiCompatible) {\n throw new Error(\n `Engine ABI mismatch: wasm=${capabilities.engineAbiVersion}, expected=${capabilities.expectedEngineAbiVersion}`,\n );\n }\n this.native = new module.RealtimeEngine(\n sampleRate,\n maxBlockSize,\n commandCapacity,\n telemetryCapacity,\n );\n }\n\n prepare(\n sampleRate: number,\n maxBlockSize: number,\n commandCapacity = 1024,\n telemetryCapacity = 1024,\n ): void {\n this.native.prepare(sampleRate, maxBlockSize, commandCapacity, telemetryCapacity);\n }\n\n /** Queue a sample-accurate parameter change (engine kSetParam). */\n setParameter(paramId: number, value: number, renderFrame = -1): void {\n this.native.setParameter(paramId, value, renderFrame);\n }\n\n /** Queue a smoothed parameter change (engine kSetParamSmoothed). */\n setParameterSmoothed(paramId: number, value: number, renderFrame = -1): void {\n this.native.setParameterSmoothed(paramId, value, renderFrame);\n }\n\n setSoloMute(laneIndex: number, solo: boolean, mute: boolean, renderFrame = -1): void {\n this.native.setSoloMute(laneIndex, solo, mute, renderFrame);\n }\n\n setMidiClips(clips: readonly EngineMidiClipSchedule[]): void {\n this.native.setMidiClips(clips);\n }\n\n setBuiltinInstrument(\n config: { destinationId?: number } & Record<string, unknown> = {},\n destinationId = config.destinationId ?? 0,\n ): void {\n this.native.setBuiltinInstrument(destinationId, config);\n }\n\n /**\n * Bind the patch-driven NativeSynth to a realtime MIDI destination. `patch`\n * is a {@link SynthPatch} or a preset-name string (`'saw-lead'` /\n * `'va:saw-lead'`; see {@link synthPresetNames}), resolving exactly like\n * {@link Project.bounceWithSynthInstrument}. Live note/CC commands and\n * scheduled MIDI clips routed to that destination render through the synth.\n * Unknown preset names throw. An object patch's `destinationId` is a JS\n * binding convenience, not part of the NativeSynth patch itself.\n */\n setSynthInstrument(\n patch: SynthPatch | string = {},\n destinationId = (typeof patch === 'object' ? patch.destinationId : undefined) ?? 0,\n ): void {\n this.native.setSynthInstrument(destinationId, patch);\n }\n\n /**\n * Load (parse) SoundFont 2 bytes into the engine so SF2 instruments can be\n * bound with {@link setSf2Instrument}. The host fetches the `.sf2` and\n * passes the raw bytes; they are copied into linear memory for the call and\n * not referenced afterwards. Replaces any previously loaded SoundFont.\n */\n loadSoundFont(data: Uint8Array): void {\n this.native.loadSoundFont(data);\n }\n\n /**\n * Bind a GS-compatible SoundFont player to a realtime MIDI destination, fed\n * by the engine's loaded SoundFont ({@link loadSoundFont}). Live note/CC\n * commands and scheduled MIDI clips routed to that destination render\n * through the player (16 MIDI channels, channel 10 drums, GS NRPN part\n * edits, GS/GM SysEx resets). Without a loaded SoundFont — or for programs\n * the SoundFont does not cover — notes play through the built-in\n * synthesizer GM fallback bank (the data-free floor).\n */\n setSf2Instrument(\n config: { destinationId?: number; gain?: number; polyphony?: number } = {},\n destinationId = config.destinationId ?? 0,\n ): void {\n this.native.setSf2Instrument(destinationId, config);\n }\n\n clearMidiInstrument(destinationId = 0): void {\n this.native.clearMidiInstrument(destinationId);\n }\n\n midiInstrumentCount(): number {\n return this.native.midiInstrumentCount();\n }\n\n /**\n * Bind a live MIDI CC to an engine automation parameter. The MIDI event still\n * reaches the destination instrument; when bound, its 7-bit value is also\n * mapped into [minValue, maxValue] for `paramId`.\n */\n bindMidiCc(\n channel: number,\n controller: number,\n paramId: number,\n options: MidiCcBindOptions = {},\n ): void {\n this.native.bindMidiCc(\n channel,\n controller,\n paramId,\n options.minValue ?? 0,\n options.maxValue ?? 1,\n );\n }\n\n clearMidiCcBindings(): void {\n this.native.clearMidiCcBindings();\n }\n\n midiCcBindingCount(): number {\n return this.native.midiCcBindingCount();\n }\n\n /** Install/replace a live non-destructive MIDI-FX insert for one destination. */\n setMidiFx(destinationId: number, configJson: string): void {\n this.native.setMidiFx(destinationId, configJson);\n }\n\n clearMidiFx(destinationId = 0): void {\n this.native.clearMidiFx(destinationId);\n }\n\n /** Enable the engine-owned live MIDI input source for a destination. */\n setMidiInputSource(destinationId = 0): void {\n this.native.setMidiInputSource(destinationId);\n }\n\n clearMidiInputSource(): void {\n this.native.clearMidiInputSource();\n }\n\n midiInputPendingCount(): number {\n return this.native.midiInputPendingCount();\n }\n\n pushMidiInputNoteOn(\n group: number,\n channel: number,\n note: number,\n velocity: number,\n portTimeSamples = 0,\n ): void {\n this.native.pushMidiInputNoteOn(group, channel, note, velocity, portTimeSamples);\n }\n\n pushMidiInputNoteOff(\n group: number,\n channel: number,\n note: number,\n velocity = 0,\n portTimeSamples = 0,\n ): void {\n this.native.pushMidiInputNoteOff(group, channel, note, velocity, portTimeSamples);\n }\n\n pushMidiInputCc(\n group: number,\n channel: number,\n controller: number,\n value: number,\n portTimeSamples = 0,\n ): void {\n this.native.pushMidiInputCc(group, channel, controller, value, portTimeSamples);\n }\n\n pushMidiNoteOn(\n destinationId: number,\n group: number,\n channel: number,\n note: number,\n velocity: number,\n renderFrame = -1,\n ): void {\n this.native.pushMidiNoteOn(destinationId, group, channel, note, velocity, renderFrame);\n }\n\n pushMidiNoteOff(\n destinationId: number,\n group: number,\n channel: number,\n note: number,\n velocity = 0,\n renderFrame = -1,\n ): void {\n this.native.pushMidiNoteOff(destinationId, group, channel, note, velocity, renderFrame);\n }\n\n /**\n * Queue an immediate (live) MIDI control change to a MIDI destination\n * (engine kMidiCcImmediate). `group`/`channel` are 0..15; `controller`/`value`\n * are 7-bit (0..127). `renderFrame` is the frame to fire at, or -1 for\n * immediate. Mirrors the Node/Python/C-ABI `pushMidiCc`.\n */\n pushMidiCc(\n destinationId: number,\n group: number,\n channel: number,\n controller: number,\n value: number,\n renderFrame = -1,\n ): void {\n this.native.pushMidiCc(destinationId, group, channel, controller, value, renderFrame);\n }\n\n /**\n * Queue a MIDI panic (all-notes-off) releasing every sounding note at\n * `renderFrame` (-1 = immediate). Mirrors the C-ABI `pushMidiPanic`.\n */\n pushMidiPanic(renderFrame = -1): void {\n this.native.pushMidiPanic(renderFrame);\n }\n\n /**\n * Remove all registered parameters (and their automation lanes). Control-thread\n * only; not realtime-safe. Mirrors the C-ABI `clearParameters`.\n */\n clearParameters(): void {\n this.native.clearParameters();\n }\n\n /** Read back the current transport state snapshot. */\n getTransportState(): EngineTransportState {\n return this.native.getTransportState();\n }\n\n play(renderFrame = -1): void {\n this.native.play(renderFrame);\n }\n\n stop(renderFrame = -1): void {\n this.native.stop(renderFrame);\n }\n\n seekSample(timelineSample: number, renderFrame = -1): void {\n this.native.seekSample(timelineSample, renderFrame);\n }\n\n /**\n * Snaps every in-flight parameter ramp (engine-level smoothed params, mixer\n * lane fader/pan/gate, bus gains) to its target value. Offline renders call\n * this after a priming process() block so the first audible block renders at\n * settled values instead of ramping in from defaults.\n */\n settleParameters(): void {\n this.native.settleParameters();\n }\n\n seekPpq(ppq: number, renderFrame = -1): void {\n this.native.seekPpq(ppq, renderFrame);\n }\n\n setTempo(bpm: number): void {\n this.native.setTempo(bpm);\n }\n\n setTempoSegments(segments: readonly EngineTempoSegment[]): void {\n this.native.setTempoSegments([...segments]);\n }\n\n setTimeSignature(numerator: number, denominator: number): void {\n this.native.setTimeSignature(numerator, denominator);\n }\n\n setTimeSignatureSegments(segments: readonly EngineTimeSignatureSegment[]): void {\n this.native.setTimeSignatureSegments([...segments]);\n }\n\n sampleAtPpq(ppq: number): number {\n return Number(this.native.sampleAtPpq(ppq));\n }\n\n setLoop(startPpq: number, endPpq: number, enabled = true): void {\n this.native.setLoop(startPpq, endPpq, enabled);\n }\n\n addParameter(info: EngineParameterInfo): void {\n this.native.addParameter(info);\n }\n\n parameterCount(): number {\n return this.native.parameterCount();\n }\n\n parameterInfoByIndex(index: number): EngineParameterInfo {\n return this.native.parameterInfoByIndex(index);\n }\n\n parameterInfo(id: number): EngineParameterInfo {\n return this.native.parameterInfo(id);\n }\n\n setAutomationLane(paramId: number, points: EngineAutomationPoint[]): void {\n this.native.setAutomationLane(paramId, points);\n }\n\n automationLaneCount(): number {\n return this.native.automationLaneCount();\n }\n\n setMarkers(markers: EngineMarker[]): void {\n this.native.setMarkers(markers);\n }\n\n markerCount(): number {\n return this.native.markerCount();\n }\n\n markerByIndex(index: number): EngineMarker {\n return this.native.markerByIndex(index);\n }\n\n marker(id: number): EngineMarker {\n return this.native.marker(id);\n }\n\n seekMarker(markerId: number, renderFrame = -1): void {\n this.native.seekMarker(markerId, renderFrame);\n }\n\n setLoopFromMarkers(startMarkerId: number, endMarkerId: number): void {\n this.native.setLoopFromMarkers(startMarkerId, endMarkerId);\n }\n\n setMetronome(config: EngineMetronomeConfig): void {\n this.native.setMetronome(config);\n }\n\n metronome(): Required<EngineMetronomeConfig> {\n return this.native.metronome();\n }\n\n countInEndSample(startSample: number, bars: number): number {\n return Number(this.native.countInEndSample(startSample, bars));\n }\n\n setGraph(spec: EngineGraphSpec): void {\n this.native.setGraph(spec);\n }\n\n graphNodeCount(): number {\n return this.native.graphNodeCount();\n }\n\n graphConnectionCount(): number {\n return this.native.graphConnectionCount();\n }\n\n setClips(clips: EngineClip[]): void {\n this.native.setClips(\n clips.map((clip) => ({\n ...clip,\n pageProvider:\n typeof clip.pageProvider === 'object' && clip.pageProvider !== null\n ? clip.pageProvider.id\n : clip.pageProvider,\n })),\n );\n }\n\n clipCount(): number {\n return this.native.clipCount();\n }\n\n setTrackLanes(lanes: Array<number | EngineTrackLane>): void {\n this.native.setTrackLanes(\n lanes.map((lane) => {\n if (typeof lane === 'number') {\n return { trackId: lane };\n }\n if (!lane.sends) {\n return lane;\n }\n // Normalize each send's pre/post tap point to the integer the native\n // layer reads (defaults to post-fader when omitted).\n return {\n ...lane,\n sends: lane.sends.map((send) => ({\n ...send,\n // Post-fader (0) is the default for an omitted sendTiming.\n sendTiming: send.sendTiming === undefined ? 0 : sendTimingCode(send.sendTiming),\n })),\n };\n }),\n );\n }\n\n /**\n * Keys one insert of a lane strip from another lane's post-strip audio\n * (ducking/sidechainRouter inserts). sourceTrackId 0 removes the binding.\n */\n setLaneSidechain(trackId: number, insertIndex: number, sourceTrackId: number): void {\n this.native.setLaneSidechain(trackId, insertIndex, sourceTrackId);\n }\n\n setTrackBuses(buses: EngineBus[]): void {\n this.native.setTrackBuses(buses);\n }\n\n setBusStripJson(busId: number, sceneJson: string): void {\n try {\n JSON.parse(sceneJson);\n } catch (error) {\n const message = error instanceof Error ? error.message : 'invalid bus strip JSON';\n throw new SonareError(ErrorCode.InvalidFormat, 'InvalidFormat', message);\n }\n this.native.setBusStripJson(busId, sceneJson);\n }\n\n setTrackStripJson(trackId: number, sceneJson: string): void {\n try {\n JSON.parse(sceneJson);\n } catch (error) {\n const message = error instanceof Error ? error.message : 'invalid track strip JSON';\n throw new SonareError(ErrorCode.InvalidFormat, 'InvalidFormat', message);\n }\n this.native.setTrackStripJson(trackId, sceneJson);\n }\n\n setTrackStripEqBand(trackId: number, bandIndex: number, band: EqBand | string): void {\n this.native.setTrackStripEqBandJson(\n trackId,\n bandIndex,\n typeof band === 'string' ? band : JSON.stringify(band),\n );\n }\n\n setTrackStripEqBandJson(trackId: number, bandIndex: number, bandJson: string): void {\n this.native.setTrackStripEqBandJson(trackId, bandIndex, bandJson);\n }\n\n setTrackStripInsertBypassed(\n trackId: number,\n insertIndex: number,\n bypassed: boolean,\n resetOnBypass = false,\n ): void {\n this.native.setTrackStripInsertBypassed(trackId, insertIndex, bypassed, resetOnBypass);\n }\n\n setMasterStripJson(sceneJson: string): void {\n try {\n JSON.parse(sceneJson);\n } catch (error) {\n const message = error instanceof Error ? error.message : 'invalid master strip JSON';\n throw new SonareError(ErrorCode.InvalidFormat, 'InvalidFormat', message);\n }\n this.native.setMasterStripJson(sceneJson);\n }\n\n setMasterStripEqBand(bandIndex: number, band: EqBand | string): void {\n this.native.setMasterStripEqBandJson(\n bandIndex,\n typeof band === 'string' ? band : JSON.stringify(band),\n );\n }\n\n setMasterStripEqBandJson(bandIndex: number, bandJson: string): void {\n this.native.setMasterStripEqBandJson(bandIndex, bandJson);\n }\n\n setMasterStripInsertBypassed(\n insertIndex: number,\n bypassed: boolean,\n resetOnBypass = false,\n ): void {\n this.native.setMasterStripInsertBypassed(insertIndex, bypassed, resetOnBypass);\n }\n\n /**\n * Changes one track-strip insert parameter in realtime, addressed by the\n * processor's JSON-key parameter name (see {@link masteringInsertParamInfo}).\n * Applied at the next block head via the engine command queue; safe during\n * playback. Throws if the track, insert, or name is unknown, the param is not\n * realtime-safe, or the command queue is full.\n */\n setTrackStripInsertParamByName(\n trackId: number,\n insertIndex: number,\n paramName: string,\n value: number,\n ): void {\n this.native.setTrackStripInsertParamByName(trackId, insertIndex, paramName, value);\n }\n\n /** Master-strip counterpart of {@link setTrackStripInsertParamByName}. */\n setMasterStripInsertParamByName(insertIndex: number, paramName: string, value: number): void {\n this.native.setMasterStripInsertParamByName(insertIndex, paramName, value);\n }\n\n /** Sets a track lane strip's pan position in realtime (glitch-free). */\n setTrackStripPan(trackId: number, pan: number): void {\n this.native.setTrackStripPan(trackId, pan);\n }\n\n /** Sets a track lane strip's pan law in realtime. */\n setTrackStripPanLaw(trackId: number, panLaw: PanLaw | number): void {\n this.native.setTrackStripPanLaw(trackId, panLawCode(panLaw));\n }\n\n /** Sets a track lane strip's pan mode in realtime. */\n setTrackStripPanMode(trackId: number, panMode: PanMode | number): void {\n this.native.setTrackStripPanMode(trackId, panModeCode(panMode));\n }\n\n /** Sets a track lane strip's dual-pan left/right positions in realtime. */\n setTrackStripDualPan(trackId: number, leftPan: number, rightPan: number): void {\n this.native.setTrackStripDualPan(trackId, leftPan, rightPan);\n }\n\n /**\n * Sets a track lane strip's inter-channel alignment delay (whole samples).\n * Adjusts strip latency, so PDC and reported graph latency are refreshed.\n */\n setTrackStripChannelDelaySamples(trackId: number, delaySamples: number): void {\n this.native.setTrackStripChannelDelaySamples(trackId, delaySamples);\n }\n\n createClipPageProvider(\n numChannels: number,\n numSamples: number,\n pageFrames: number,\n ): ClipPageProvider {\n const id = this.native.createClipPageProvider(numChannels, numSamples, pageFrames);\n return new ClipPageProvider(this, id);\n }\n\n supplyClipPage(providerId: number, pageIndex: number, channels: Float32Array[]): void {\n this.native.supplyClipPage(providerId, pageIndex, channels);\n }\n\n clearClipPage(providerId: number, pageIndex: number): void {\n this.native.clearClipPage(providerId, pageIndex);\n }\n\n destroyClipPageProvider(providerId: number): void {\n this.native.destroyClipPageProvider(providerId);\n }\n\n popClipPageRequest(): ClipPageRequest | null {\n return this.native.popClipPageRequest();\n }\n\n setCaptureBuffer(numChannels: number, capacityFrames: number): void {\n this.native.setCaptureBuffer(numChannels, capacityFrames);\n }\n\n armCapture(armed = true): void {\n this.native.armCapture(armed);\n }\n\n setCapturePunch(startSample: number, endSample: number, enabled = true): void {\n this.native.setCapturePunch(startSample, endSample, enabled);\n }\n\n setCaptureSource(source: EngineCaptureStatus['source']): void {\n this.native.setCaptureSource(source);\n }\n\n setRecordOffsetSamples(offsetSamples: number): void {\n this.native.setRecordOffsetSamples(offsetSamples);\n }\n\n setInputMonitor(enabled: boolean, gain = 1): void {\n this.native.setInputMonitor(enabled, gain);\n }\n\n resetCapture(): void {\n this.native.resetCapture();\n }\n\n captureStatus(): EngineCaptureStatus {\n return this.native.captureStatus();\n }\n\n capturedAudio(): Float32Array[] {\n return this.native.capturedAudio();\n }\n\n process(channels: Float32Array[]): Float32Array[] {\n return this.native.process(channels);\n }\n\n /**\n * Allocates persistent per-channel WASM-heap scratch for the zero-copy\n * `getChannelBuffer` / `processPrepared` realtime path. Call once (off the\n * audio thread) before driving `processPrepared` from an AudioWorklet so the\n * render callback never allocates on the C++/JS heap.\n */\n prepareChannels(numChannels: number, maxFrames: number): void {\n this.native.prepareChannels(numChannels, maxFrames);\n }\n\n /**\n * Returns a Float32Array view onto the persistent WASM-heap scratch for one\n * channel (valid for up to `numFrames`). Fill it, call `processPrepared`, then\n * read the same view back. Re-acquire after WASM memory growth.\n */\n getChannelBuffer(channel: number, numFrames: number): Float32Array {\n return this.native.getChannelBuffer(channel, numFrames);\n }\n\n /**\n * Runs the engine in place over the prepared per-channel scratch buffers.\n * Allocation-free: safe to call on the AudioWorklet render thread after\n * `prepareChannels`.\n */\n processPrepared(numFrames: number): void {\n this.native.processPrepared(numFrames);\n }\n\n processWithMonitor(channels: Float32Array[]): WasmEngineProcessWithMonitorResult {\n return this.native.processWithMonitor(channels);\n }\n\n renderOffline(channels: Float32Array[], blockSize = 128): Float32Array[] {\n return this.native.renderOffline(channels, blockSize);\n }\n\n bounceOffline(options: EngineBounceOptions): EngineBounceResult {\n return this.native.bounceOffline(options);\n }\n\n freezeOffline(options: EngineFreezeOptions): EngineFreezeResult {\n return this.native.freezeOffline(options);\n }\n\n drainTelemetry(maxRecords = 1024): EngineTelemetry[] {\n return this.native.drainTelemetry(maxRecords);\n }\n\n drainMeterTelemetry(maxRecords = 1024): EngineMeterTelemetry[] {\n return this.native.drainMeterTelemetry(maxRecords);\n }\n\n /**\n * Drains pending meter telemetry as per-plane (wide) records for a surround\n * target. Use this for a surround mix target; {@link drainMeterTelemetry}\n * stays the stereo fast path. The two share one queue — call only one per\n * target. The live AudioWorklet path owns the queue via the stereo drain, so\n * this wide drain is for an offline (non-worklet) engine instance; per-plane\n * surround meters are not delivered over the live worklet meter ring.\n */\n drainMeterTelemetryWide(maxRecords = 1024): EngineMeterTelemetryWide[] {\n return this.native.drainMeterTelemetryWide(maxRecords);\n }\n\n /**\n * Enables per-target spectrum + vectorscope capture. @param intervalFrames is\n * the minimum render-frame gap between snapshots (0 disables). @param bandCount\n * is the FFT band resolution (1..64); changing it re-prepares the tap. Returns\n * the band count actually applied.\n */\n configureScopeTelemetry(intervalFrames: number, bandCount: number): number {\n return this.native.configureScopeTelemetry(intervalFrames, bandCount);\n }\n\n /** Drains pending spectrum + vectorscope snapshots (per mix target). */\n drainScopeTelemetry(maxRecords = 1024): EngineScopeTelemetry[] {\n return this.native.drainScopeTelemetry(maxRecords);\n }\n\n destroy(): void {\n this.native.delete();\n }\n}\n\nexport class ClipPageProvider {\n private disposed = false;\n\n constructor(\n private readonly engine: RealtimeEngine,\n readonly id: number,\n ) {}\n\n supply(pageIndex: number, channels: Float32Array[]): void {\n if (this.disposed) {\n throw new Error('ClipPageProvider is destroyed');\n }\n this.engine.supplyClipPage(this.id, pageIndex, channels);\n }\n\n clear(pageIndex: number): void {\n if (this.disposed) {\n return;\n }\n this.engine.clearClipPage(this.id, pageIndex);\n }\n\n destroy(): void {\n if (this.disposed) {\n return;\n }\n this.disposed = true;\n this.engine.destroyClipPageProvider(this.id);\n }\n}\n","/**\n * sonare - Audio Analysis Library\n *\n * @example\n * ```typescript\n * import { init, detectBpm, detectKey, analyze } from '@libraz/libsonare';\n *\n * await init();\n *\n * // Detect BPM from audio samples\n * const bpm = detectBpm(samples, sampleRate);\n *\n * // Detect musical key\n * const key = detectKey(samples, sampleRate);\n *\n * // Full analysis\n * const result = analyze(samples, sampleRate);\n * ```\n */\n\nimport { setSonareModule } from './module_state';\nimport type { RealtimeVoiceChangerPodConfig, VoicePresetId } from './public_types';\nimport type {\n SonareModule,\n WasmDecomposeResult,\n WasmHpssWithResidualResult,\n WasmMatrix2dResult,\n} from './sonare.js';\n\nexport type { BrowserAudioDecodeOptions } from './audio';\nexport { Audio } from './audio';\nexport type {\n CompressorDetector,\n CompressorOptions,\n DeclickOptions,\n DeclipOptions,\n DecrackleMode,\n DecrackleOptions,\n DehumOptions,\n DenoiseClassicalMode,\n DenoiseClassicalNoiseEstimator,\n DenoiseClassicalOptions,\n DereverbClassicalOptions,\n DynamicsResult,\n GateOptions,\n MasteringChannelPolicy,\n MasteringInsertParamInfo,\n MasteringProcessorCatalogEntry,\n TransientShaperOptions,\n TrimSilenceMode,\n TrimSilenceOptions,\n VoiceChangeOptions,\n VoiceChangeRealtimeOptions,\n} from './effects_mastering';\nexport {\n harmonic,\n hpss,\n masterAudio,\n masterAudioStereo,\n masterAudioStereoWithProgress,\n masterAudioWithProgress,\n mastering,\n masteringAssistantSuggest,\n masteringAudioProfile,\n masteringChain,\n masteringChainStereo,\n masteringChainStereoWithProgress,\n masteringChainWithProgress,\n masteringDynamicsCompressor,\n masteringDynamicsGate,\n masteringDynamicsTransientShaper,\n masteringInsertNames,\n masteringInsertParamInfo,\n masteringInsertParamNames,\n masteringPairAnalysisNames,\n masteringPairAnalyze,\n masteringPairProcess,\n masteringPairProcessorNames,\n masteringPresetNames,\n masteringProcess,\n masteringProcessorCatalog,\n masteringProcessorNames,\n masteringProcessStereo,\n masteringRepairDeclick,\n masteringRepairDeclip,\n masteringRepairDecrackle,\n masteringRepairDehum,\n masteringRepairDenoiseClassical,\n masteringRepairDereverbClassical,\n masteringRepairTrimSilence,\n masteringStereoAnalysisNames,\n masteringStereoAnalyze,\n masteringStreamingPreview,\n mixingScenePresetJson,\n mixingScenePresetNames,\n mixStereo,\n normalize,\n noteStretch,\n percussive,\n pitchCorrectToMidi,\n pitchCorrectToMidiTimevarying,\n pitchShift,\n spectralEdit,\n timeStretch,\n voiceChange,\n voiceChangeRealtime,\n} from './effects_mastering';\nexport { ErrorCode, isSonareError, SonareError } from './errors';\nexport type { MelodyOptions } from './feature_music';\nexport {\n amplitudeToDb,\n analyzeMelody,\n analyzeSections,\n bassChroma,\n chroma,\n chromaCens,\n cqt,\n cyclicTempogram,\n dbToAmplitude,\n dbToPower,\n decompose,\n decomposeWithInit,\n deemphasis,\n ebur128LoudnessRange,\n estimateTuning,\n fixFrames,\n fixLength,\n fourierTempogram,\n frameSignal,\n framesToSamples,\n framesToTime,\n hpssWithResidual,\n hybridCqt,\n hzToMel,\n hzToMidi,\n hzToNote,\n lufs,\n lufsInterleaved,\n melSpectrogram,\n melToAudio,\n melToHz,\n melToStft,\n mfcc,\n mfccToAudio,\n mfccToMel,\n midiToHz,\n momentaryLufs,\n nnFilter,\n nnlsChroma,\n noteToHz,\n onsetEnvelope,\n onsetStrengthMulti,\n padCenter,\n pcen,\n peakPick,\n phaseVocoder,\n pitchPyin,\n pitchTuning,\n pitchYin,\n plp,\n polyFeatures,\n powerToDb,\n preemphasis,\n pseudoCqt,\n remix,\n resample,\n rmsEnergy,\n samplesToFrames,\n shortTermLufs,\n spectralBandwidth,\n spectralCentroid,\n spectralContrast,\n spectralFlatness,\n spectralRolloff,\n splitSilence,\n stft,\n stftDb,\n tempogram,\n tempogramRatio,\n timeToFrames,\n tonnetz,\n trim,\n trimSilence,\n vectorNormalize,\n vqt,\n zeroCrossingRate,\n zeroCrossings,\n} from './features';\nexport type { BindMicrophoneInputOptions, MicrophoneInputBinding } from './live_audio';\nexport { bindMicrophoneInput } from './live_audio';\nexport type {\n ClippingRegion,\n ClippingReport,\n DynamicRangeReport,\n MeteringDetectClippingOptions,\n MeteringDynamicRangeOptions,\n PhaseScopeReport,\n SpectrumOptions,\n SpectrumReport,\n VectorscopeReport,\n WaveformPeakPyramidOptions,\n WaveformPeaksOptions,\n WaveformPeaksReport,\n} from './metering';\nexport {\n meteringCrestFactorDb,\n meteringDcOffset,\n meteringDetectClipping,\n meteringDynamicRange,\n meteringPeakDb,\n meteringPhaseScope,\n meteringPhaseScopeDecimated,\n meteringRmsDb,\n meteringSpectrum,\n meteringSpectrumFrame,\n meteringStereoCorrelation,\n meteringStereoWidth,\n meteringTruePeakDb,\n meteringVectorscope,\n meteringVectorscopeDecimated,\n waveformPeakPyramid,\n waveformPeaks,\n} from './metering';\nexport type {\n OpfsClipPageProviderBinding,\n OpfsClipPageProviderOptions,\n} from './opfs_clip_pages';\nexport {\n createOpfsClipPageProvider,\n createOpfsClipPageWorker,\n opfsClipPageWorkerSource,\n} from './opfs_clip_pages';\nexport type {\n BuiltinSynthBinding,\n BuiltinSynthConfig,\n BuiltinSynthWaveform,\n MidiCcLearnOptions,\n ProjectAssistSidecar,\n ProjectAutomationCurve,\n ProjectAutomationLaneDesc,\n ProjectAutomationPoint,\n ProjectBounceOptions,\n ProjectChordSymbol,\n ProjectClipCompSegment,\n ProjectClipDesc,\n ProjectClipFade,\n ProjectClipTake,\n ProjectCompileResult,\n ProjectFadeCurve,\n ProjectKeySegment,\n ProjectLoopMode,\n ProjectLoopRecordingDesc,\n ProjectLoopRecordingResult,\n ProjectMarker,\n ProjectMidiClipResult,\n ProjectMidiEvent,\n ProjectNotePairValidation,\n ProjectTrackDesc,\n ProjectTrackKind,\n ProjectWarpAnchor,\n ProjectWarpMapDesc,\n Sf2InstrumentConfig,\n Sf2ProgramStatus,\n SourceBackend,\n SynthBodyType,\n SynthEngineMode,\n SynthEnumTables,\n SynthFilterModel,\n SynthFilterOutput,\n SynthModDestination,\n SynthModRouting,\n SynthModSource,\n SynthOscWaveform,\n SynthPatch,\n} from './project';\nexport {\n EXPECTED_PROJECT_ABI_VERSION,\n MarkerKind,\n Project,\n projectAbiVersion,\n SYNTH_BODY_TYPES,\n SYNTH_ENGINE_MODES,\n SYNTH_FILTER_MODELS,\n SYNTH_FILTER_OUTPUTS,\n SYNTH_MOD_DESTINATIONS,\n SYNTH_MOD_SOURCES,\n SYNTH_OSC_WAVEFORMS,\n synthEnumTables,\n synthPresetNames,\n synthPresetPatch,\n} from './project';\nexport type {\n AcousticOptions,\n AcousticResult,\n AnalysisResult,\n AnalyzeBpmOptions,\n AnalyzeDynamicsOptions,\n AnalyzeRhythmOptions,\n AnalyzeSectionsOptions,\n AnalyzeTimbreOptions,\n AutomationCurve,\n Beat,\n Chord,\n ChordAnalysisResult,\n ChordDetectionOptions,\n ChromaResult,\n CqtResult,\n Dynamics,\n EqBand,\n EqBandPhase,\n EqBandType,\n EqCoeffMode,\n EqMatchOptions,\n EqSpectrumSnapshot,\n EqStereoPlacement,\n GoniometerPoint,\n HpssResult,\n Key,\n KeyCandidate,\n KeyDetectionOptions,\n KeyProfileName,\n LufsResult,\n MasteringChainConfig,\n MasteringChainResult,\n MasteringOptions,\n MasteringPreset,\n MasteringProcessorParams,\n MasteringResult,\n MasteringStereoChainResult,\n MasteringStereoResult,\n MelodyPoint,\n MelodyResult,\n MelPowerResult,\n MelSpectrogramResult,\n MeterTap,\n MfccResult,\n MixerProcessResult,\n MixMeterSnapshot,\n MixOptions,\n MixResult,\n NoteStretchOptions,\n PairAnalysis,\n PairProcessor,\n PanLaw,\n PanMode,\n PitchResult,\n RealtimeVoiceChangerConfigInput,\n RealtimeVoiceChangerPodConfig,\n RhythmFeatures,\n RirResult,\n RirSynthOptions,\n RoomEstimateOptions,\n RoomEstimateResult,\n RoomGeometryOptions,\n RoomMorphOptions,\n Section,\n SendTiming,\n SoloProcessor,\n SpectralEditMode,\n SpectralEditOptions,\n SpectralEditWindow,\n SpectralRegionOp,\n StereoAnalysis,\n StftPowerResult,\n StftResult,\n StreamingEqualizerConfig,\n StreamingMasteringChainConfig,\n StreamingPlatform,\n StreamingRetuneConfig,\n TempogramMode,\n Timbre,\n TimeSignature,\n VoicePresetId,\n} from './public_types';\nexport {\n ChordQuality,\n KeyProfile,\n Mode,\n PitchClass,\n SectionType,\n} from './public_types';\nexport type {\n BpmAnalysisResult,\n BpmCandidate,\n DynamicsAnalysisResult,\n RhythmAnalysisResult,\n TimbreAnalysisResult,\n TimbreFrame,\n} from './quick_analysis';\nexport {\n analyze,\n analyzeBpm,\n analyzeDynamics,\n analyzeImpulseResponse,\n analyzeRhythm,\n analyzeTimbre,\n analyzeWithProgress,\n chordFunctionalAnalysis,\n detectAcoustic,\n detectBeats,\n detectBpm,\n detectChords,\n detectDownbeats,\n detectKey,\n detectKeyCandidates,\n detectOnsets,\n estimateRoom,\n hasFfmpegSupport,\n roomMorph,\n synthesizeRir,\n} from './quick_analysis';\nexport type {\n EngineAutomationPoint,\n EngineBounceOptions,\n EngineBounceResult,\n EngineBus,\n EngineCapabilities,\n EngineCaptureStatus,\n EngineClip,\n EngineFreezeOptions,\n EngineFreezeResult,\n EngineGraphSpec,\n EngineMarker,\n EngineMeterTelemetry,\n EngineMeterTelemetryWide,\n EngineMetronomeConfig,\n EngineMidiClipSchedule,\n EngineMidiEvent,\n EngineParameterInfo,\n EngineScopeTelemetry,\n EngineTelemetry,\n EngineTempoSegment,\n EngineTimeSignatureSegment,\n EngineTrackLane,\n EngineTrackSend,\n EngineTransportState,\n MidiCcBindOptions,\n} from './realtime_engine';\nexport { EXPECTED_ENGINE_ABI_VERSION, engineCapabilities, RealtimeEngine } from './realtime_engine';\nexport { scaleCorrectionSemitones, scalePitchClassEnabled, scaleQuantizeMidi } from './scale';\nexport type { ProgressCallback } from './sonare.js';\nexport { StreamAnalyzer, streamAnalyzerConfigDefaults } from './stream_analyzer';\nexport type {\n AnalyzerStats,\n BarChord,\n ChordChange,\n FrameBuffer,\n PatternScore,\n ProgressiveEstimate,\n StreamConfig,\n StreamConfigDefaults,\n StreamFramesI16,\n StreamFramesU8,\n StreamQuantizeConfig,\n} from './stream_types';\nexport type {\n MixerRealtimeBuffer,\n RealtimeVoiceChangerInterleavedBuffer,\n RealtimeVoiceChangerMonoBuffer,\n RealtimeVoiceChangerPlanarBuffer,\n} from './streaming_mixing';\nexport {\n Mixer,\n RealtimeVoiceChanger,\n realtimeVoiceChangerPresetJson,\n realtimeVoiceChangerPresetNames,\n StreamingEqualizer,\n StreamingMasteringChain,\n StreamingRetune,\n validateRealtimeVoiceChangerPresetJson,\n} from './streaming_mixing';\nexport type { ValidateOptions } from './validation';\nexport type {\n BindWebMidiOptions,\n WebMidiBinding,\n WebMidiCcBinding,\n WebMidiInputInfo,\n} from './web_midi';\nexport { bindWebMidi, isWebMidiAvailable } from './web_midi';\n\n/** Row-major 2-D matrix as a flat buffer plus its dimensions. */\nexport type Matrix2dResult = WasmMatrix2dResult;\n/** NMF factor matrices { w, h } from {@link decompose}. */\nexport type DecomposeResult = WasmDecomposeResult;\n/** Harmonic / percussive / residual signals from {@link hpssWithResidual}. */\nexport type HpssWithResidualResult = WasmHpssWithResidualResult;\n\n// ============================================================================\n// Module State\n// ============================================================================\n\nlet module: SonareModule | null = null;\nlet initPromise: Promise<void> | null = null;\n\n// ============================================================================\n// Initialization\n// ============================================================================\n\n/**\n * Initialize the WASM module.\n * Must be called before using any analysis functions.\n *\n * @param options - Optional module configuration\n * @returns Promise that resolves when initialization is complete\n */\nexport async function init(options?: {\n locateFile?: (path: string, prefix: string) => string;\n wasmBinary?: ArrayBuffer | Uint8Array;\n moduleFactory?: (options?: {\n locateFile?: (path: string, prefix: string) => string;\n wasmBinary?: ArrayBuffer | Uint8Array;\n }) => Promise<SonareModule>;\n}): Promise<void> {\n if (module) {\n return;\n }\n\n if (initPromise) {\n return initPromise;\n }\n\n initPromise = (async () => {\n try {\n const createModule = options?.moduleFactory ?? (await import('./sonare.js')).default;\n module = await createModule(options);\n setSonareModule(module);\n } catch (error) {\n initPromise = null;\n throw error;\n }\n })();\n\n return initPromise;\n}\n\n/**\n * Check if the module is initialized.\n */\nexport function isInitialized(): boolean {\n return module !== null;\n}\n\n/**\n * Get the library version.\n */\nexport function version(): string {\n if (!module) {\n throw new Error('Module not initialized. Call init() first.');\n }\n return module.version();\n}\n\nexport function engineAbiVersion(): number {\n if (!module) {\n throw new Error('Module not initialized. Call init() first.');\n }\n return module.engineAbiVersion();\n}\n\nexport function voiceChangerAbiVersion(): number {\n if (!module) {\n throw new Error('Module not initialized. Call init() first.');\n }\n return module.voiceChangerAbiVersion();\n}\n\n// Canonical ordinal order of the built-in voice-character presets, matching the\n// C ABI SonareVoiceCharacterPreset enum and SONARE_REALTIME_VOICE_CHANGER_PRESET_IDS.\nconst VOICE_PRESET_ORDINALS: readonly VoicePresetId[] = [\n 'neutral-monitor',\n 'bright-idol',\n 'soft-whisper',\n 'deep-narrator',\n 'robot-mascot',\n 'dark-villain',\n];\n\nfunction resolveVoicePresetOrdinal(preset: VoicePresetId | number): number {\n if (typeof preset === 'number') {\n return preset;\n }\n const ordinal = VOICE_PRESET_ORDINALS.indexOf(preset);\n if (ordinal < 0) {\n throw new Error(`Unknown voice character preset: ${preset}`);\n }\n return ordinal;\n}\n\n/**\n * Map a voice-character preset ordinal (or canonical id) to its canonical id\n * string (e.g. `'bright-idol'`). Returns `null` for an out-of-range ordinal.\n */\nexport function voiceCharacterPresetId(preset: VoicePresetId | number): string | null {\n if (!module) {\n throw new Error('Module not initialized. Call init() first.');\n }\n return module.voiceCharacterPresetId(resolveVoicePresetOrdinal(preset));\n}\n\n/**\n * Return the canonical (normalized) flat POD config for a built-in voice\n * preset, skipping the JSON round-trip. Accepts a canonical preset id or its\n * integer ordinal. Returns `null` for an out-of-range ordinal.\n */\nexport function realtimeVoiceChangerPresetConfig(\n preset: VoicePresetId | number,\n): RealtimeVoiceChangerPodConfig | null {\n if (!module) {\n throw new Error('Module not initialized. Call init() first.');\n }\n return module.realtimeVoiceChangerPresetConfig(resolveVoicePresetOrdinal(preset));\n}\n\n// ============================================================================\n// Re-exports\n// ============================================================================\n\nexport { PitchClass as Pitch } from './public_types';\n","import type { EngineMeterTelemetry, EngineTelemetry } from '../index';\n\nconst ENGINE_MIXER_TARGET_BASE = 0x4d580000;\nexport const ENGINE_MIXER_PARAM_FADER_DB = 1;\nexport const ENGINE_MIXER_PARAM_PAN = 2;\n\nexport function engineMixerLaneTarget(laneIndex: number, paramKind: number): number {\n return ENGINE_MIXER_TARGET_BASE | ((laneIndex & 0xff) << 8) | (paramKind & 0xff);\n}\n\nexport function engineMixerBusTarget(busIndex: number, paramKind: number): number {\n return ENGINE_MIXER_TARGET_BASE | (((0xfe - busIndex) & 0xff) << 8) | (paramKind & 0xff);\n}\n\nexport function engineMixerMasterTarget(paramKind: number): number {\n return ENGINE_MIXER_TARGET_BASE | (0xff << 8) | (paramKind & 0xff);\n}\n\nexport interface SonareWorkletMeterSnapshot {\n type: 'meter';\n targetId: number;\n frame: number;\n peakDbL: number;\n peakDbR: number;\n rmsDbL: number;\n rmsDbR: number;\n correlation: number;\n truePeakDbL: number;\n truePeakDbR: number;\n momentaryLufs: number;\n shortTermLufs: number;\n integratedLufs: number;\n gainReductionDb: number;\n}\n\nexport interface SonareWorkletSpectrumSnapshot {\n type: 'spectrum';\n frame: number;\n bands: Float32Array;\n}\n\nexport const SONARE_METER_RING_HEADER_INTS = 4;\n// Record layout: [frameLo, frameHi, targetId, peakDbL, peakDbR, rmsDbL, rmsDbR,\n// correlation, truePeakDbL, truePeakDbR, momentaryLufs, shortTermLufs,\n// integratedLufs, gainReductionDb].\n// The sample-frame index is monotonically increasing and quickly exceeds the\n// 2^24 exact-integer range of a single Float32 slot (~349 s at 48 kHz), so it is\n// stored split across two Float32 lanes (low 24 bits + high bits) for exact\n// reconstruction. See encodeFrameLo/encodeFrameHi/decodeFrame.\nexport const SONARE_METER_RING_RECORD_FLOATS = 14;\nexport const SONARE_SPECTRUM_RING_HEADER_INTS = 5;\n// Scope ring header: [writeIndex, capacity, recordFloats, bands, maxPoints,\n// reserved]. Record layout: [frameLo, frameHi, targetId, bandCount, pointCount,\n// band0..band(bands-1), l0, r0, l1, r1, ... (maxPoints stereo pairs)].\nexport const SONARE_SCOPE_RING_HEADER_INTS = 6;\nexport const SONARE_SCOPE_RING_RECORD_PREFIX_FLOATS = 5;\n\n/** Base for splitting a frame index into two exactly-representable Float32 lanes. */\nconst SONARE_FRAME_LANE_BASE = 0x1000000; // 2^24\n\n/** Low 24 bits of a frame index (exact in Float32). */\nexport function encodeFrameLo(frame: number): number {\n const f = Math.max(0, Math.floor(frame));\n return f % SONARE_FRAME_LANE_BASE;\n}\n\n/** High bits of a frame index above 2^24 (exact in Float32 up to ~2^48). */\nexport function encodeFrameHi(frame: number): number {\n const f = Math.max(0, Math.floor(frame));\n return Math.floor(f / SONARE_FRAME_LANE_BASE);\n}\n\n/** Reconstruct a frame index from its low/high Float32 lanes. */\nexport function decodeFrame(lo: number, hi: number): number {\n return hi * SONARE_FRAME_LANE_BASE + lo;\n}\nexport const SONARE_ENGINE_RING_HEADER_INTS = 5;\nexport const SONARE_ENGINE_COMMAND_RECORD_BYTES = 32;\nexport const SONARE_ENGINE_TELEMETRY_RECORD_BYTES = 48;\n\nexport enum SonareEngineCommandType {\n SetParam = 0,\n SetParamSmoothed = 1,\n TransportPlay = 2,\n TransportStop = 3,\n TransportSeekSample = 4,\n TransportSeekPpq = 5,\n SetTempoMap = 6,\n SetLoop = 7,\n SwapGraph = 8,\n SwapAutomation = 9,\n SetSoloMute = 10,\n AddClip = 11,\n RemoveClip = 12,\n ArmRecord = 13,\n Punch = 14,\n SetMetronome = 15,\n SetMarker = 16,\n SeekMarker = 17,\n}\n\nexport enum SonareEngineTelemetryType {\n ProcessBlock = 0,\n Error = 1,\n}\n\nexport enum SonareEngineTelemetryError {\n None = 0,\n CommandQueueOverflow = 1,\n PendingCommandOverflow = 2,\n BoundaryOverflow = 3,\n TelemetryOverflow = 4,\n CaptureOverflow = 5,\n MaxBlockExceeded = 6,\n UnknownTarget = 7,\n NonRealtimeSafeParameter = 8,\n NotPrepared = 9,\n NonQueueableCommand = 10,\n AutomationBindTargetOverflow = 11,\n StaleAutomationLanes = 12,\n SmoothedParameterCapacity = 13,\n}\n\nexport interface SonareMeterRingBuffer {\n sharedBuffer: SharedArrayBuffer;\n header: Int32Array;\n records: Float32Array;\n capacity: number;\n}\n\nexport interface SonareMeterRingReadResult {\n nextReadIndex: number;\n meters: SonareWorkletMeterSnapshot[];\n}\n\nexport interface SonareSpectrumRingBuffer {\n sharedBuffer: SharedArrayBuffer;\n header: Int32Array;\n records: Float32Array;\n capacity: number;\n bands: number;\n}\n\nexport interface SonareSpectrumRingReadResult {\n nextReadIndex: number;\n spectra: SonareWorkletSpectrumSnapshot[];\n}\n\n/**\n * A single target-addressed scope record drained from the realtime engine's\n * scope ring: an FFT magnitude spectrum plus a decimated goniometer/vectorscope\n * point cloud. Unlike {@link SonareWorkletSpectrumSnapshot} (the legacy\n * coarse-DFT meter spectrum), this carries a `targetId` (master/lane/bus) and a\n * stereo point cloud, mirroring the engine's `ScopeTelemetryRecord`.\n */\nexport interface SonareWorkletScopeSnapshot {\n type: 'scope';\n targetId: number;\n frame: number;\n /** Linear-band magnitudes in dB (length = the configured band count). */\n bands: Float32Array;\n /** Interleaved stereo goniometer points: [l0, r0, l1, r1, ...]. */\n points: Float32Array;\n}\n\nexport interface SonareScopeRingBuffer {\n sharedBuffer: SharedArrayBuffer;\n header: Int32Array;\n records: Float32Array;\n capacity: number;\n bands: number;\n maxPoints: number;\n}\n\nexport interface SonareScopeRingReadResult {\n nextReadIndex: number;\n scopes: SonareWorkletScopeSnapshot[];\n}\n\nexport interface SharedScopeRingWriter {\n header: Int32Array;\n records: Float32Array;\n capacity: number;\n bands: number;\n maxPoints: number;\n recordFloats: number;\n}\n\nexport interface SonareEngineCommandRecord {\n type: SonareEngineCommandType | number;\n targetId?: number;\n sampleTime?: number | bigint;\n argFloat?: number;\n argInt?: number | bigint;\n}\n\nexport interface SonareEngineTelemetryRecord {\n type: SonareEngineTelemetryType | number;\n error: SonareEngineTelemetryError | number;\n renderFrame: number;\n timelineSample: number;\n audibleTimelineSample: number;\n graphLatencySamplesQ8: number;\n value: number;\n}\n\nexport interface SonareEngineCommandRingBuffer {\n sharedBuffer: SharedArrayBuffer;\n header: Int32Array;\n view: DataView;\n capacity: number;\n}\n\nexport interface SonareEngineTelemetryRingBuffer {\n sharedBuffer: SharedArrayBuffer;\n header: Int32Array;\n view: DataView;\n capacity: number;\n}\n\nexport interface SonareEngineTelemetryRingReadResult {\n nextReadIndex: number;\n telemetry: SonareEngineTelemetryRecord[];\n}\n\nexport interface SharedMeterRingWriter {\n header: Int32Array;\n records: Float32Array;\n capacity: number;\n}\n\nexport interface SharedSpectrumRingWriter {\n header: Int32Array;\n records: Float32Array;\n capacity: number;\n bands: number;\n recordFloats: number;\n}\n\nexport function toDb(value: number): number {\n return value > 0 ? 20 * Math.log10(value) : Number.NEGATIVE_INFINITY;\n}\n\nexport function isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null;\n}\n\nexport function sonareMeterRingBufferByteLength(capacity: number): number {\n const clampedCapacity = Math.max(1, Math.floor(capacity));\n return (\n SONARE_METER_RING_HEADER_INTS * Int32Array.BYTES_PER_ELEMENT +\n clampedCapacity * SONARE_METER_RING_RECORD_FLOATS * Float32Array.BYTES_PER_ELEMENT\n );\n}\n\nexport function createSonareMeterRingBuffer(capacity = 128): SonareMeterRingBuffer {\n const clampedCapacity = Math.max(1, Math.floor(capacity));\n const sharedBuffer = new SharedArrayBuffer(sonareMeterRingBufferByteLength(clampedCapacity));\n const ring = meterRingFromSharedBuffer(sharedBuffer, clampedCapacity);\n Atomics.store(ring.header, 0, 0);\n Atomics.store(ring.header, 1, clampedCapacity);\n Atomics.store(ring.header, 2, SONARE_METER_RING_RECORD_FLOATS);\n Atomics.store(ring.header, 3, 0);\n return { sharedBuffer, header: ring.header, records: ring.records, capacity: ring.capacity };\n}\n\nexport function readSonareMeterRingBuffer(\n ring: SonareMeterRingBuffer,\n readIndex = 0,\n): SonareMeterRingReadResult {\n const writeIndex = Atomics.load(ring.header, 0);\n const recordFloats = Atomics.load(ring.header, 2) || SONARE_METER_RING_RECORD_FLOATS;\n const nextReadIndex = Math.max(0, Math.min(readIndex, writeIndex));\n const firstReadable = Math.max(nextReadIndex, writeIndex - ring.capacity);\n const meters: SonareWorkletMeterSnapshot[] = [];\n for (let index = firstReadable; index < writeIndex; index++) {\n const offset = (index % ring.capacity) * recordFloats;\n meters.push({\n type: 'meter',\n frame: decodeFrame(ring.records[offset], ring.records[offset + 1]),\n targetId: ring.records[offset + 2],\n peakDbL: ring.records[offset + 3],\n peakDbR: ring.records[offset + 4],\n rmsDbL: ring.records[offset + 5],\n rmsDbR: ring.records[offset + 6],\n correlation: ring.records[offset + 7],\n truePeakDbL: ring.records[offset + 8],\n truePeakDbR: ring.records[offset + 9],\n momentaryLufs: ring.records[offset + 10],\n shortTermLufs: ring.records[offset + 11],\n integratedLufs: ring.records[offset + 12],\n gainReductionDb: ring.records[offset + 13],\n });\n }\n return { nextReadIndex: writeIndex, meters };\n}\n\nexport function sonareSpectrumRingBufferByteLength(capacity: number, bands = 16): number {\n const clampedCapacity = Math.max(1, Math.floor(capacity));\n const clampedBands = Math.max(1, Math.floor(bands));\n // Record layout: [frameLo, frameHi, bandCount, band0, band1, ...]. frame is\n // split across two Float32 lanes for exact reconstruction beyond 2^24.\n return (\n SONARE_SPECTRUM_RING_HEADER_INTS * Int32Array.BYTES_PER_ELEMENT +\n clampedCapacity * (3 + clampedBands) * Float32Array.BYTES_PER_ELEMENT\n );\n}\n\nexport function createSonareSpectrumRingBuffer(\n capacity = 128,\n bands = 16,\n): SonareSpectrumRingBuffer {\n const clampedCapacity = Math.max(1, Math.floor(capacity));\n const clampedBands = Math.max(1, Math.floor(bands));\n const sharedBuffer = new SharedArrayBuffer(\n sonareSpectrumRingBufferByteLength(clampedCapacity, clampedBands),\n );\n const ring = spectrumRingFromSharedBuffer(sharedBuffer, clampedCapacity, clampedBands);\n Atomics.store(ring.header, 0, 0);\n Atomics.store(ring.header, 1, clampedCapacity);\n Atomics.store(ring.header, 2, ring.recordFloats);\n Atomics.store(ring.header, 3, clampedBands);\n Atomics.store(ring.header, 4, 0);\n return {\n sharedBuffer,\n header: ring.header,\n records: ring.records,\n capacity: ring.capacity,\n bands: ring.bands,\n };\n}\n\nexport function readSonareSpectrumRingBuffer(\n ring: SonareSpectrumRingBuffer,\n readIndex = 0,\n): SonareSpectrumRingReadResult {\n const writeIndex = Atomics.load(ring.header, 0);\n const recordFloats = Atomics.load(ring.header, 2) || 3 + ring.bands;\n const bands = Atomics.load(ring.header, 3) || ring.bands;\n const nextReadIndex = Math.max(0, Math.min(readIndex, writeIndex));\n const firstReadable = Math.max(nextReadIndex, writeIndex - ring.capacity);\n const spectra: SonareWorkletSpectrumSnapshot[] = [];\n for (let index = firstReadable; index < writeIndex; index++) {\n const offset = (index % ring.capacity) * recordFloats;\n const values = new Float32Array(bands);\n values.set(ring.records.subarray(offset + 3, offset + 3 + bands));\n spectra.push({\n type: 'spectrum',\n frame: decodeFrame(ring.records[offset], ring.records[offset + 1]),\n bands: values,\n });\n }\n return { nextReadIndex: writeIndex, spectra };\n}\n\nexport function sonareScopeRingRecordFloats(bands: number, maxPoints: number): number {\n return SONARE_SCOPE_RING_RECORD_PREFIX_FLOATS + bands + 2 * maxPoints;\n}\n\nexport function sonareScopeRingBufferByteLength(\n capacity: number,\n bands = 48,\n maxPoints = 32,\n): number {\n const clampedCapacity = Math.max(1, Math.floor(capacity));\n const clampedBands = Math.max(1, Math.floor(bands));\n const clampedPoints = Math.max(0, Math.floor(maxPoints));\n return (\n SONARE_SCOPE_RING_HEADER_INTS * Int32Array.BYTES_PER_ELEMENT +\n clampedCapacity *\n sonareScopeRingRecordFloats(clampedBands, clampedPoints) *\n Float32Array.BYTES_PER_ELEMENT\n );\n}\n\nexport function createSonareScopeRingBuffer(\n capacity = 64,\n bands = 48,\n maxPoints = 32,\n): SonareScopeRingBuffer {\n const clampedCapacity = Math.max(1, Math.floor(capacity));\n const clampedBands = Math.max(1, Math.floor(bands));\n const clampedPoints = Math.max(0, Math.floor(maxPoints));\n const sharedBuffer = new SharedArrayBuffer(\n sonareScopeRingBufferByteLength(clampedCapacity, clampedBands, clampedPoints),\n );\n const ring = scopeRingFromSharedBuffer(\n sharedBuffer,\n clampedCapacity,\n clampedBands,\n clampedPoints,\n );\n Atomics.store(ring.header, 0, 0);\n Atomics.store(ring.header, 1, clampedCapacity);\n Atomics.store(ring.header, 2, ring.recordFloats);\n Atomics.store(ring.header, 3, clampedBands);\n Atomics.store(ring.header, 4, clampedPoints);\n Atomics.store(ring.header, 5, 0);\n return {\n sharedBuffer,\n header: ring.header,\n records: ring.records,\n capacity: ring.capacity,\n bands: ring.bands,\n maxPoints: ring.maxPoints,\n };\n}\n\nexport function readSonareScopeRingBuffer(\n ring: SonareScopeRingBuffer,\n readIndex = 0,\n): SonareScopeRingReadResult {\n const writeIndex = Atomics.load(ring.header, 0);\n const bands = Atomics.load(ring.header, 3) || ring.bands;\n const maxPoints = Atomics.load(ring.header, 4);\n const recordFloats =\n Atomics.load(ring.header, 2) || sonareScopeRingRecordFloats(bands, maxPoints);\n const nextReadIndex = Math.max(0, Math.min(readIndex, writeIndex));\n const firstReadable = Math.max(nextReadIndex, writeIndex - ring.capacity);\n const scopes: SonareWorkletScopeSnapshot[] = [];\n for (let index = firstReadable; index < writeIndex; index++) {\n const offset = (index % ring.capacity) * recordFloats;\n const bandCount = Math.min(bands, Math.max(0, ring.records[offset + 3]));\n const pointCount = Math.min(maxPoints, Math.max(0, ring.records[offset + 4]));\n const bandsView = new Float32Array(bandCount);\n bandsView.set(\n ring.records.subarray(\n offset + SONARE_SCOPE_RING_RECORD_PREFIX_FLOATS,\n offset + SONARE_SCOPE_RING_RECORD_PREFIX_FLOATS + bandCount,\n ),\n );\n const pointsBase = offset + SONARE_SCOPE_RING_RECORD_PREFIX_FLOATS + bands;\n const pointsView = new Float32Array(pointCount * 2);\n pointsView.set(ring.records.subarray(pointsBase, pointsBase + pointCount * 2));\n scopes.push({\n type: 'scope',\n frame: decodeFrame(ring.records[offset], ring.records[offset + 1]),\n targetId: ring.records[offset + 2],\n bands: bandsView,\n points: pointsView,\n });\n }\n return { nextReadIndex: writeIndex, scopes };\n}\n\nexport function scopeRingFromSharedBuffer(\n sharedBuffer: SharedArrayBuffer,\n fallbackCapacity?: number,\n fallbackBands?: number,\n fallbackMaxPoints?: number,\n): SharedScopeRingWriter {\n const headerBytes = SONARE_SCOPE_RING_HEADER_INTS * Int32Array.BYTES_PER_ELEMENT;\n const header = new Int32Array(sharedBuffer, 0, SONARE_SCOPE_RING_HEADER_INTS);\n const existingCapacity = Atomics.load(header, 1);\n const existingBands = Atomics.load(header, 3);\n const existingMaxPoints = Atomics.load(header, 4);\n const capacity = Math.max(1, Math.floor(existingCapacity || fallbackCapacity || 1));\n const bands = Math.max(1, Math.floor(existingBands || fallbackBands || 48));\n const maxPoints = Math.max(0, Math.floor(existingMaxPoints || (fallbackMaxPoints ?? 32)));\n const recordFloats = sonareScopeRingRecordFloats(bands, maxPoints);\n const minBytes = sonareScopeRingBufferByteLength(capacity, bands, maxPoints);\n if (sharedBuffer.byteLength < minBytes) {\n throw new Error('scopeSharedBuffer is too small for the requested ring capacity.');\n }\n Atomics.store(header, 1, capacity);\n Atomics.store(header, 2, recordFloats);\n Atomics.store(header, 3, bands);\n Atomics.store(header, 4, maxPoints);\n return {\n header,\n records: new Float32Array(sharedBuffer, headerBytes, capacity * recordFloats),\n capacity,\n bands,\n maxPoints,\n recordFloats,\n };\n}\n\nexport function sonareEngineCommandRingBufferByteLength(capacity: number): number {\n const clampedCapacity = Math.max(1, Math.floor(capacity));\n return (\n SONARE_ENGINE_RING_HEADER_INTS * Int32Array.BYTES_PER_ELEMENT +\n clampedCapacity * SONARE_ENGINE_COMMAND_RECORD_BYTES\n );\n}\n\nexport function sonareEngineTelemetryRingBufferByteLength(capacity: number): number {\n const clampedCapacity = Math.max(1, Math.floor(capacity));\n return (\n SONARE_ENGINE_RING_HEADER_INTS * Int32Array.BYTES_PER_ELEMENT +\n clampedCapacity * SONARE_ENGINE_TELEMETRY_RECORD_BYTES\n );\n}\n\nexport function createSonareEngineCommandRingBuffer(capacity = 128): SonareEngineCommandRingBuffer {\n const clampedCapacity = Math.max(1, Math.floor(capacity));\n const sharedBuffer = new SharedArrayBuffer(\n sonareEngineCommandRingBufferByteLength(clampedCapacity),\n );\n const ring = engineRingFromSharedBuffer(\n sharedBuffer,\n SONARE_ENGINE_COMMAND_RECORD_BYTES,\n clampedCapacity,\n );\n return { sharedBuffer, header: ring.header, view: ring.view, capacity: ring.capacity };\n}\n\nexport function createSonareEngineTelemetryRingBuffer(\n capacity = 128,\n): SonareEngineTelemetryRingBuffer {\n const clampedCapacity = Math.max(1, Math.floor(capacity));\n const sharedBuffer = new SharedArrayBuffer(\n sonareEngineTelemetryRingBufferByteLength(clampedCapacity),\n );\n const ring = engineRingFromSharedBuffer(\n sharedBuffer,\n SONARE_ENGINE_TELEMETRY_RECORD_BYTES,\n clampedCapacity,\n );\n return { sharedBuffer, header: ring.header, view: ring.view, capacity: ring.capacity };\n}\n\nexport function pushSonareEngineCommandRingBuffer(\n ring: SonareEngineCommandRingBuffer,\n command: SonareEngineCommandRecord,\n): boolean {\n const writeIndex = Atomics.load(ring.header, 0);\n const readIndex = Atomics.load(ring.header, 1);\n if (writeIndex - readIndex >= ring.capacity) {\n Atomics.add(ring.header, 4, 1);\n return false;\n }\n writeEngineCommandRecord(\n ring.view,\n recordOffset(writeIndex, ring.capacity, SONARE_ENGINE_COMMAND_RECORD_BYTES),\n command,\n );\n Atomics.store(ring.header, 0, writeIndex + 1);\n return true;\n}\n\nexport function popSonareEngineCommandRingBuffer(\n ring: SonareEngineCommandRingBuffer,\n): SonareEngineCommandRecord | null {\n const readIndex = Atomics.load(ring.header, 1);\n const writeIndex = Atomics.load(ring.header, 0);\n if (readIndex >= writeIndex) {\n return null;\n }\n const command = readEngineCommandRecord(\n ring.view,\n recordOffset(readIndex, ring.capacity, SONARE_ENGINE_COMMAND_RECORD_BYTES),\n );\n Atomics.store(ring.header, 1, readIndex + 1);\n return command;\n}\n\nexport function writeSonareEngineTelemetryRingBuffer(\n ring: SonareEngineTelemetryRingBuffer,\n telemetry: SonareEngineTelemetryRecord,\n): void {\n const writeIndex = Atomics.load(ring.header, 0);\n writeEngineTelemetryRecord(\n ring.view,\n recordOffset(writeIndex, ring.capacity, SONARE_ENGINE_TELEMETRY_RECORD_BYTES),\n telemetry,\n );\n Atomics.store(ring.header, 0, writeIndex + 1);\n if (writeIndex + 1 > ring.capacity) {\n Atomics.store(ring.header, 4, writeIndex + 1 - ring.capacity);\n }\n}\n\nexport function readSonareEngineTelemetryRingBuffer(\n ring: SonareEngineTelemetryRingBuffer,\n readIndex = 0,\n): SonareEngineTelemetryRingReadResult {\n const writeIndex = Atomics.load(ring.header, 0);\n const nextReadIndex = Math.max(0, Math.min(readIndex, writeIndex));\n const firstReadable = Math.max(nextReadIndex, writeIndex - ring.capacity);\n const telemetry: SonareEngineTelemetryRecord[] = [];\n for (let index = firstReadable; index < writeIndex; index++) {\n telemetry.push(\n readEngineTelemetryRecord(\n ring.view,\n recordOffset(index, ring.capacity, SONARE_ENGINE_TELEMETRY_RECORD_BYTES),\n ),\n );\n }\n return { nextReadIndex: writeIndex, telemetry };\n}\n\nexport function meterRingFromSharedBuffer(\n sharedBuffer: SharedArrayBuffer,\n fallbackCapacity?: number,\n): SharedMeterRingWriter {\n const headerBytes = SONARE_METER_RING_HEADER_INTS * Int32Array.BYTES_PER_ELEMENT;\n const header = new Int32Array(sharedBuffer, 0, SONARE_METER_RING_HEADER_INTS);\n const existingCapacity = Atomics.load(header, 1);\n const capacity = Math.max(1, Math.floor(existingCapacity || fallbackCapacity || 1));\n const minBytes = sonareMeterRingBufferByteLength(capacity);\n if (sharedBuffer.byteLength < minBytes) {\n throw new Error('meterSharedBuffer is too small for the requested ring capacity.');\n }\n Atomics.store(header, 1, capacity);\n Atomics.store(header, 2, SONARE_METER_RING_RECORD_FLOATS);\n return {\n header,\n records: new Float32Array(\n sharedBuffer,\n headerBytes,\n capacity * SONARE_METER_RING_RECORD_FLOATS,\n ),\n capacity,\n };\n}\n\nexport function spectrumRingFromSharedBuffer(\n sharedBuffer: SharedArrayBuffer,\n fallbackCapacity?: number,\n fallbackBands?: number,\n): SharedSpectrumRingWriter {\n const headerBytes = SONARE_SPECTRUM_RING_HEADER_INTS * Int32Array.BYTES_PER_ELEMENT;\n const header = new Int32Array(sharedBuffer, 0, SONARE_SPECTRUM_RING_HEADER_INTS);\n const existingCapacity = Atomics.load(header, 1);\n const existingBands = Atomics.load(header, 3);\n const capacity = Math.max(1, Math.floor(existingCapacity || fallbackCapacity || 1));\n const bands = Math.max(1, Math.floor(existingBands || fallbackBands || 16));\n const recordFloats = 3 + bands;\n const minBytes = sonareSpectrumRingBufferByteLength(capacity, bands);\n if (sharedBuffer.byteLength < minBytes) {\n throw new Error('spectrumSharedBuffer is too small for the requested ring capacity.');\n }\n Atomics.store(header, 1, capacity);\n Atomics.store(header, 2, recordFloats);\n Atomics.store(header, 3, bands);\n return {\n header,\n records: new Float32Array(sharedBuffer, headerBytes, capacity * recordFloats),\n capacity,\n bands,\n recordFloats,\n };\n}\n\nexport function engineRingFromSharedBuffer(\n sharedBuffer: SharedArrayBuffer,\n recordBytes: number,\n fallbackCapacity?: number,\n): { header: Int32Array; view: DataView; capacity: number } {\n const headerBytes = SONARE_ENGINE_RING_HEADER_INTS * Int32Array.BYTES_PER_ELEMENT;\n const header = new Int32Array(sharedBuffer, 0, SONARE_ENGINE_RING_HEADER_INTS);\n const existingCapacity = Atomics.load(header, 2);\n const capacity = Math.max(1, Math.floor(existingCapacity || fallbackCapacity || 1));\n const minBytes = headerBytes + capacity * recordBytes;\n if (sharedBuffer.byteLength < minBytes) {\n throw new Error('engine SharedArrayBuffer is too small for the requested ring capacity.');\n }\n Atomics.store(header, 2, capacity);\n Atomics.store(header, 3, recordBytes);\n return {\n header,\n view: new DataView(sharedBuffer, headerBytes, capacity * recordBytes),\n capacity,\n };\n}\n\nfunction recordOffset(index: number, capacity: number, recordBytes: number): number {\n return (index % capacity) * recordBytes;\n}\n\nexport function toBigInt64(value: number | bigint | undefined, fallback: bigint): bigint {\n if (typeof value === 'bigint') {\n return value;\n }\n if (typeof value === 'number') {\n return BigInt(Math.trunc(value));\n }\n return fallback;\n}\n\nfunction writeEngineCommandRecord(\n view: DataView,\n offset: number,\n command: SonareEngineCommandRecord,\n): void {\n view.setUint32(offset, command.type, true);\n view.setUint32(offset + 4, command.targetId ?? 0, true);\n view.setBigInt64(offset + 8, toBigInt64(command.sampleTime, -1n), true);\n // argFloat occupies a full 8-byte Float64 slot (replacing the old Float32 +\n // 4-byte pad) so PPQ scalars carried here keep full double precision over the\n // SAB transport, matching the engine's double-precision seek/loop contract.\n view.setFloat64(offset + 16, command.argFloat ?? 0, true);\n view.setBigInt64(offset + 24, toBigInt64(command.argInt, 0n), true);\n}\n\nfunction readEngineCommandRecord(view: DataView, offset: number): SonareEngineCommandRecord {\n return {\n type: view.getUint32(offset, true),\n targetId: view.getUint32(offset + 4, true),\n sampleTime: Number(view.getBigInt64(offset + 8, true)),\n argFloat: view.getFloat64(offset + 16, true),\n argInt: Number(view.getBigInt64(offset + 24, true)),\n };\n}\n\nfunction writeEngineTelemetryRecord(\n view: DataView,\n offset: number,\n telemetry: SonareEngineTelemetryRecord,\n): void {\n view.setUint32(offset, telemetry.type, true);\n view.setUint32(offset + 4, telemetry.error, true);\n view.setBigInt64(offset + 8, BigInt(Math.trunc(telemetry.renderFrame)), true);\n view.setBigInt64(offset + 16, BigInt(Math.trunc(telemetry.timelineSample)), true);\n view.setBigInt64(offset + 24, BigInt(Math.trunc(telemetry.audibleTimelineSample)), true);\n view.setInt32(offset + 32, telemetry.graphLatencySamplesQ8, true);\n view.setUint32(offset + 36, telemetry.value, true);\n view.setBigInt64(offset + 40, 0n, true);\n}\n\nfunction readEngineTelemetryRecord(view: DataView, offset: number): SonareEngineTelemetryRecord {\n return {\n type: view.getUint32(offset, true),\n error: view.getUint32(offset + 4, true),\n renderFrame: Number(view.getBigInt64(offset + 8, true)),\n timelineSample: Number(view.getBigInt64(offset + 16, true)),\n audibleTimelineSample: Number(view.getBigInt64(offset + 24, true)),\n graphLatencySamplesQ8: view.getInt32(offset + 32, true),\n value: view.getUint32(offset + 36, true),\n };\n}\n\nexport function telemetryFromEngine(telemetry: EngineTelemetry): SonareEngineTelemetryRecord {\n return {\n type: telemetry.type,\n error: telemetry.error,\n renderFrame: telemetry.renderFrame,\n timelineSample: telemetry.timelineSample,\n audibleTimelineSample: telemetry.audibleTimelineSample,\n graphLatencySamplesQ8: telemetry.graphLatencySamplesQ8,\n value: telemetry.value,\n };\n}\n\nexport function meterFromEngine(meter: EngineMeterTelemetry): SonareWorkletMeterSnapshot {\n return {\n type: 'meter',\n targetId: meter.targetId,\n frame: meter.renderFrame,\n peakDbL: meter.peakDbL,\n peakDbR: meter.peakDbR,\n rmsDbL: meter.rmsDbL,\n rmsDbR: meter.rmsDbR,\n correlation: meter.correlation,\n truePeakDbL: meter.truePeakDbL,\n truePeakDbR: meter.truePeakDbR,\n momentaryLufs: meter.momentaryLufs,\n shortTermLufs: meter.shortTermLufs,\n integratedLufs: meter.integratedLufs,\n gainReductionDb: meter.gainReductionDb,\n };\n}\n\nexport function magnitudeToDb(value: number): number {\n return value > 1.0e-12 ? 20 * Math.log10(value) : -120;\n}\n","import type {\n SonareEngineCaptureRequestMessage,\n SonareEngineCaptureResponseMessage,\n SonareEngineSyncMessage,\n SonareEngineTransportRequestMessage,\n SonareEngineTransportResponseMessage,\n SonareRealtimeVoiceChangerMessage,\n SonareWorkletMessage,\n} from './messages';\nimport {\n isRecord,\n type SonareEngineCommandRecord,\n type SonareEngineTelemetryRecord,\n type SonareWorkletMeterSnapshot,\n} from './protocol';\n\nexport function isWorkletMessage(value: unknown): value is SonareWorkletMessage {\n if (!isRecord(value) || typeof value.type !== 'string') {\n return false;\n }\n return (\n value.type === 'scheduleInsertAutomation' ||\n value.type === 'setMeterInterval' ||\n value.type === 'destroy'\n );\n}\n\nexport function isEngineCommandRecord(value: unknown): value is SonareEngineCommandRecord {\n return isRecord(value) && typeof value.type === 'number';\n}\n\nexport function isEngineSyncMessage(value: unknown): value is SonareEngineSyncMessage {\n if (!isRecord(value) || typeof value.type !== 'string') {\n return false;\n }\n return (\n value.type === 'syncClips' ||\n value.type === 'syncClipsDelta' ||\n value.type === 'syncMidiClips' ||\n value.type === 'syncMarkers' ||\n value.type === 'syncMetronome' ||\n value.type === 'syncAutomation' ||\n value.type === 'syncTempo' ||\n value.type === 'syncMixer' ||\n value.type === 'syncCapture' ||\n value.type === 'syncTrackStripEqBand' ||\n value.type === 'syncMasterStripEqBand' ||\n value.type === 'syncTrackStripInsertBypassed' ||\n value.type === 'syncMasterStripInsertBypassed' ||\n value.type === 'syncTrackStripInsertParamByName' ||\n value.type === 'syncMasterStripInsertParamByName' ||\n value.type === 'syncTrackStripPan' ||\n value.type === 'syncTrackStripPanLaw' ||\n value.type === 'syncTrackStripPanMode' ||\n value.type === 'syncTrackStripDualPan' ||\n value.type === 'syncTrackStripChannelDelaySamples' ||\n value.type === 'syncBuiltinInstrument' ||\n value.type === 'syncSynthInstrument' ||\n value.type === 'syncSf2Instrument' ||\n value.type === 'syncLoadSoundFont' ||\n value.type === 'syncMidiNoteOn' ||\n value.type === 'syncMidiNoteOff' ||\n value.type === 'syncMidiCc' ||\n value.type === 'syncMidiPanic'\n );\n}\n\nexport function isEngineCaptureRequestMessage(\n value: unknown,\n): value is SonareEngineCaptureRequestMessage {\n return (\n isRecord(value) &&\n value.type === 'captureRequest' &&\n typeof value.requestId === 'number' &&\n (value.op === 'status' || value.op === 'read' || value.op === 'reset')\n );\n}\n\nexport function isEngineCaptureResponseMessage(\n value: unknown,\n): value is SonareEngineCaptureResponseMessage {\n return (\n isRecord(value) &&\n value.type === 'captureResponse' &&\n typeof value.requestId === 'number' &&\n typeof value.ok === 'boolean'\n );\n}\n\nexport function isEngineTransportRequestMessage(\n value: unknown,\n): value is SonareEngineTransportRequestMessage {\n return (\n isRecord(value) &&\n value.type === 'transportRequest' &&\n typeof value.requestId === 'number' &&\n value.op === 'state'\n );\n}\n\nexport function isEngineTransportResponseMessage(\n value: unknown,\n): value is SonareEngineTransportResponseMessage {\n return (\n isRecord(value) &&\n value.type === 'transportResponse' &&\n typeof value.requestId === 'number' &&\n typeof value.ok === 'boolean'\n );\n}\n\nexport function isRealtimeVoiceChangerMessage(\n value: unknown,\n): value is SonareRealtimeVoiceChangerMessage {\n if (!isRecord(value) || typeof value.type !== 'string') {\n return false;\n }\n return value.type === 'setConfig' || value.type === 'reset' || value.type === 'destroy';\n}\n\nexport function isEngineTelemetryRecord(value: unknown): value is SonareEngineTelemetryRecord {\n return (\n isRecord(value) &&\n typeof value.type === 'number' &&\n typeof value.error === 'number' &&\n typeof value.renderFrame === 'number' &&\n typeof value.timelineSample === 'number' &&\n typeof value.audibleTimelineSample === 'number' &&\n typeof value.graphLatencySamplesQ8 === 'number' &&\n typeof value.value === 'number'\n );\n}\n\nexport function isMeterSnapshot(value: unknown): value is SonareWorkletMeterSnapshot {\n return (\n isRecord(value) &&\n value.type === 'meter' &&\n typeof value.frame === 'number' &&\n typeof value.peakDbL === 'number' &&\n typeof value.peakDbR === 'number' &&\n typeof value.rmsDbL === 'number' &&\n typeof value.rmsDbR === 'number' &&\n typeof value.correlation === 'number' &&\n (typeof value.targetId === 'number' || value.targetId === undefined)\n );\n}\n","import type {\n EngineAutomationPoint,\n EngineBus,\n EngineCaptureStatus,\n EngineClip,\n EngineMarker,\n EngineMetronomeConfig,\n EngineMidiClipSchedule,\n EngineTempoSegment,\n EngineTimeSignatureSegment,\n EngineTrackLane,\n EngineTransportState,\n RealtimeVoiceChangerConfigInput,\n} from '../index';\nimport type { AutomationCurve } from '../public_types';\nimport type { SonareRtModule } from '../sonare-rt';\nimport type {\n SonareEngineCommandRecord,\n SonareEngineTelemetryRecord,\n SonareWorkletMeterSnapshot,\n SonareWorkletSpectrumSnapshot,\n} from './protocol';\n\nexport interface SonareWorkletProcessorOptions {\n sceneJson: string;\n sampleRate?: number;\n blockSize?: number;\n stripCount?: number;\n meterIntervalFrames?: number;\n meterSharedBuffer?: SharedArrayBuffer;\n meterRingCapacity?: number;\n spectrumIntervalFrames?: number;\n spectrumBands?: number;\n spectrumSharedBuffer?: SharedArrayBuffer;\n spectrumRingCapacity?: number;\n}\n\nexport interface SonareRealtimeEngineWorkletProcessorOptions {\n runtimeTarget?: 'embind' | 'sonare-rt';\n rtModuleUrl?: string;\n rtWasmBinary?: ArrayBuffer | Uint8Array;\n wasmBinary?: ArrayBuffer | Uint8Array;\n initialSyncMessages?: SonareEngineSyncMessage[];\n initialCommands?: SonareEngineCommandRecord[];\n sampleRate?: number;\n blockSize?: number;\n channelCount?: number;\n meterIntervalFrames?: number;\n commandSharedBuffer?: SharedArrayBuffer;\n commandRingCapacity?: number;\n telemetrySharedBuffer?: SharedArrayBuffer;\n telemetryRingCapacity?: number;\n meterSharedBuffer?: SharedArrayBuffer;\n meterRingCapacity?: number;\n // Scope telemetry (FFT spectrum + goniometer): opt-in. The ring is created\n // only when scopeIntervalFrames > 0, since the per-block FFT is heavier than\n // the meter path. scopeBands selects the linear band resolution.\n scopeIntervalFrames?: number;\n scopeBands?: number;\n scopeSharedBuffer?: SharedArrayBuffer;\n scopeRingCapacity?: number;\n}\n\nexport interface SonareRealtimeVoiceChangerWorkletProcessorOptions {\n preset?: RealtimeVoiceChangerConfigInput;\n sampleRate?: number;\n blockSize?: number;\n channelCount?: number;\n}\n\nexport interface SonareRealtimeVoiceChangerSetConfigMessage {\n type: 'setConfig';\n preset: RealtimeVoiceChangerConfigInput;\n}\n\nexport interface SonareRealtimeVoiceChangerResetMessage {\n type: 'reset';\n}\n\nexport interface SonareRealtimeVoiceChangerDestroyMessage {\n type: 'destroy';\n}\n\nexport type SonareRealtimeVoiceChangerMessage =\n | SonareRealtimeVoiceChangerSetConfigMessage\n | SonareRealtimeVoiceChangerResetMessage\n | SonareRealtimeVoiceChangerDestroyMessage;\n\nexport interface SonareRealtimeEngineNodeCapabilities {\n mode: 'sab' | 'postMessage';\n runtimeTarget: 'embind' | 'sonare-rt';\n sharedArrayBuffer: boolean;\n atomics: boolean;\n audioWorklet: boolean;\n engineAbiVersion?: number;\n expectedEngineAbiVersion?: number;\n abiCompatible?: boolean;\n degradedReason?: string;\n readyMessage?: boolean;\n}\n\nexport interface SonareRealtimeEngineNodeOptions\n extends SonareRealtimeEngineWorkletProcessorOptions {\n processorName?: string;\n moduleUrl?: string | URL;\n rtModuleUrl?: string;\n mode?: 'auto' | 'sab' | 'postMessage';\n engineAbiVersion?: number;\n expectedEngineAbiVersion?: number;\n requireAbiCompatible?: boolean;\n nodeFactory?: (\n context: BaseAudioContext,\n processorName: string,\n options: AudioWorkletNodeOptions,\n ) => AudioWorkletNode;\n}\n\nexport interface SonareRtRealtimeEngineRuntimeOptions {\n module: SonareRtModule;\n memory: WebAssembly.Memory;\n sampleRate?: number;\n blockSize?: number;\n channelCount?: number;\n commandSharedBuffer?: SharedArrayBuffer;\n commandRingCapacity?: number;\n telemetrySharedBuffer?: SharedArrayBuffer;\n telemetryRingCapacity?: number;\n}\n\nexport interface SonareEngineTransportFacade {\n play(sampleTime?: number): boolean;\n stop(sampleTime?: number): boolean;\n seekPpq(ppq: number, sampleTime?: number): boolean;\n seekSeconds(seconds: number, sampleTime?: number): boolean;\n setTempo(bpm: number): void;\n setTempoSegments(segments: readonly EngineTempoSegment[]): void;\n setLoop(startPpq: number, endPpq: number, enabled?: boolean): boolean;\n}\n\nexport interface SonareWorkletScheduleInsertAutomationMessage {\n type: 'scheduleInsertAutomation';\n stripIndex: number;\n insertIndex: number;\n paramId: number;\n value: number;\n samplePos?: number;\n curve?: AutomationCurve;\n}\n\nexport interface SonareWorkletSetMeterIntervalMessage {\n type: 'setMeterInterval';\n frames: number;\n}\n\nexport interface SonareWorkletDestroyMessage {\n type: 'destroy';\n}\n\nexport type SonareWorkletMessage =\n | SonareWorkletScheduleInsertAutomationMessage\n | SonareWorkletSetMeterIntervalMessage\n | SonareWorkletDestroyMessage;\n\nexport type SonareWorkletTransportMessage =\n | SonareWorkletMeterSnapshot\n | SonareWorkletSpectrumSnapshot\n | SonareEngineTelemetryRecord;\n\nexport interface WorkletTransport {\n postMessage?: (\n message:\n | SonareWorkletTransportMessage\n | SonareEngineCaptureResponseMessage\n | SonareEngineTransportResponseMessage,\n transfer?: Transferable[],\n ) => void;\n onMeter?: (meter: SonareWorkletMeterSnapshot) => void;\n onSpectrum?: (spectrum: SonareWorkletSpectrumSnapshot) => void;\n}\n\nexport interface ResolvedMetronomeConfig {\n beatGain: number;\n accentGain: number;\n clickSamples: number;\n}\n\n// Fallback metronome gains/click length used by the worklet consumer until the\n// host posts a 'syncMetronome' config. Aligned with the embind setMetronome\n// defaults (src/wasm/bindings.cpp) so offline and realtime metronomes match.\nexport const DEFAULT_METRONOME_CONFIG: ResolvedMetronomeConfig = {\n beatGain: 0.35,\n accentGain: 0.7,\n clickSamples: 96,\n};\n\nexport function resolveMetronomeConfig(config: EngineMetronomeConfig): ResolvedMetronomeConfig {\n return {\n beatGain: config.beatGain ?? DEFAULT_METRONOME_CONFIG.beatGain,\n accentGain: config.accentGain ?? DEFAULT_METRONOME_CONFIG.accentGain,\n clickSamples: config.clickSamples ?? DEFAULT_METRONOME_CONFIG.clickSamples,\n };\n}\n\n// Out-of-band control messages posted from the main-thread SonareEngine facade\n// to the worklet engine processor over node.port. Unlike SonareEngineCommandRecord\n// (a small POD POSTed/ringed every block) these carry bulk/structured payloads\n// (clip audio buffers, marker lists, metronome config) that cannot fit the\n// fixed-size SAB command record, so they are applied OUTSIDE process() — the\n// audio-thread equivalent of the engine's control-thread RtPublisher setters.\nexport interface SonareEngineSyncClipsMessage {\n type: 'syncClips';\n clips: EngineClip[];\n}\n\nexport interface SonareEngineSyncClipsDeltaMessage {\n type: 'syncClipsDelta';\n upserts: EngineClip[];\n removeIds: number[];\n}\n\nexport interface SonareEngineSyncMidiClipsMessage {\n type: 'syncMidiClips';\n clips: EngineMidiClipSchedule[];\n}\n\nexport interface SonareEngineSyncMarkersMessage {\n type: 'syncMarkers';\n markers: EngineMarker[];\n}\n\nexport interface SonareEngineSyncMetronomeMessage {\n type: 'syncMetronome';\n config: EngineMetronomeConfig;\n}\n\nexport interface SonareEngineSyncAutomationMessage {\n type: 'syncAutomation';\n paramId: number;\n points: EngineAutomationPoint[];\n}\n\nexport interface SonareEngineSyncTempoMessage {\n type: 'syncTempo';\n bpm: number;\n timeSignature: { numerator: number; denominator: number };\n tempoSegments?: EngineTempoSegment[];\n timeSignatureSegments?: EngineTimeSignatureSegment[];\n}\n\nexport interface SonareEngineSyncMixerMessage {\n type: 'syncMixer';\n lanes: EngineTrackLane[];\n buses?: EngineBus[];\n trackStrips?: Array<{ trackId: number; sceneJson: string }>;\n busStrips?: Array<{ busId: number; sceneJson: string }>;\n masterStripJson?: string;\n /** Lane insert sidechain bindings (replayed after lanes/strips). */\n laneSidechains?: Array<{ trackId: number; insertIndex: number; sourceTrackId: number }>;\n}\n\nexport interface SonareEngineSyncCaptureMessage {\n type: 'syncCapture';\n bufferFrames: number;\n channels: number;\n source: EngineCaptureStatus['source'];\n recordOffsetSamples: number;\n inputMonitor: { enabled: boolean; gain: number };\n}\n\nexport interface SonareEngineSyncTrackStripEqBandMessage {\n type: 'syncTrackStripEqBand';\n trackId: number;\n bandIndex: number;\n bandJson: string;\n}\n\nexport interface SonareEngineSyncMasterStripEqBandMessage {\n type: 'syncMasterStripEqBand';\n bandIndex: number;\n bandJson: string;\n}\n\nexport interface SonareEngineSyncTrackStripInsertBypassedMessage {\n type: 'syncTrackStripInsertBypassed';\n trackId: number;\n insertIndex: number;\n bypassed: boolean;\n resetOnBypass: boolean;\n}\n\nexport interface SonareEngineSyncMasterStripInsertBypassedMessage {\n type: 'syncMasterStripInsertBypassed';\n insertIndex: number;\n bypassed: boolean;\n resetOnBypass: boolean;\n}\n\nexport interface SonareEngineSyncTrackStripInsertParamByNameMessage {\n type: 'syncTrackStripInsertParamByName';\n trackId: number;\n insertIndex: number;\n paramName: string;\n value: number;\n}\n\nexport interface SonareEngineSyncMasterStripInsertParamByNameMessage {\n type: 'syncMasterStripInsertParamByName';\n insertIndex: number;\n paramName: string;\n value: number;\n}\n\nexport interface SonareEngineSyncTrackStripPanMessage {\n type: 'syncTrackStripPan';\n trackId: number;\n pan: number;\n}\n\nexport interface SonareEngineSyncTrackStripPanLawMessage {\n type: 'syncTrackStripPanLaw';\n trackId: number;\n panLaw: number;\n}\n\nexport interface SonareEngineSyncTrackStripPanModeMessage {\n type: 'syncTrackStripPanMode';\n trackId: number;\n panMode: number;\n}\n\nexport interface SonareEngineSyncTrackStripDualPanMessage {\n type: 'syncTrackStripDualPan';\n trackId: number;\n leftPan: number;\n rightPan: number;\n}\n\nexport interface SonareEngineSyncTrackStripChannelDelaySamplesMessage {\n type: 'syncTrackStripChannelDelaySamples';\n trackId: number;\n delaySamples: number;\n}\n\nexport interface SonareEngineSyncBuiltinInstrumentMessage {\n type: 'syncBuiltinInstrument';\n destinationId: number;\n config: { destinationId?: number } & Record<string, unknown>;\n}\n\nexport interface SonareEngineSyncSynthInstrumentMessage {\n type: 'syncSynthInstrument';\n destinationId: number;\n patch: Record<string, unknown> | string;\n}\n\nexport interface SonareEngineSyncSf2InstrumentMessage {\n type: 'syncSf2Instrument';\n destinationId: number;\n config: { destinationId?: number; gain?: number; polyphony?: number };\n}\n\nexport interface SonareEngineSyncLoadSoundFontMessage {\n type: 'syncLoadSoundFont';\n data: Uint8Array;\n}\n\nexport interface SonareEngineSyncMidiNoteMessage {\n type: 'syncMidiNoteOn' | 'syncMidiNoteOff';\n destinationId: number;\n group: number;\n channel: number;\n note: number;\n velocity: number;\n renderFrame: number;\n}\n\nexport interface SonareEngineSyncMidiCcMessage {\n type: 'syncMidiCc';\n destinationId: number;\n group: number;\n channel: number;\n controller: number;\n value: number;\n renderFrame: number;\n}\n\nexport interface SonareEngineSyncMidiPanicMessage {\n type: 'syncMidiPanic';\n renderFrame: number;\n}\n\nexport type SonareEngineInstrumentSyncMessage =\n | SonareEngineSyncBuiltinInstrumentMessage\n | SonareEngineSyncSynthInstrumentMessage\n | SonareEngineSyncSf2InstrumentMessage\n | SonareEngineSyncLoadSoundFontMessage;\n\nexport type SonareEngineSyncMessage =\n | SonareEngineSyncClipsMessage\n | SonareEngineSyncClipsDeltaMessage\n | SonareEngineSyncMidiClipsMessage\n | SonareEngineSyncMarkersMessage\n | SonareEngineSyncMetronomeMessage\n | SonareEngineSyncAutomationMessage\n | SonareEngineSyncTempoMessage\n | SonareEngineSyncMixerMessage\n | SonareEngineSyncCaptureMessage\n | SonareEngineSyncTrackStripEqBandMessage\n | SonareEngineSyncMasterStripEqBandMessage\n | SonareEngineSyncTrackStripInsertBypassedMessage\n | SonareEngineSyncMasterStripInsertBypassedMessage\n | SonareEngineSyncTrackStripInsertParamByNameMessage\n | SonareEngineSyncMasterStripInsertParamByNameMessage\n | SonareEngineSyncTrackStripPanMessage\n | SonareEngineSyncTrackStripPanLawMessage\n | SonareEngineSyncTrackStripPanModeMessage\n | SonareEngineSyncTrackStripDualPanMessage\n | SonareEngineSyncTrackStripChannelDelaySamplesMessage\n | SonareEngineSyncBuiltinInstrumentMessage\n | SonareEngineSyncSynthInstrumentMessage\n | SonareEngineSyncSf2InstrumentMessage\n | SonareEngineSyncLoadSoundFontMessage\n | SonareEngineSyncMidiNoteMessage\n | SonareEngineSyncMidiCcMessage\n | SonareEngineSyncMidiPanicMessage;\n\nexport interface WorkletPort {\n postMessage?: (message: unknown, transfer?: Transferable[]) => void;\n onmessage?: (event: { data: unknown }) => void;\n addEventListener?: (type: 'message', listener: (event: { data: unknown }) => void) => void;\n start?: () => void;\n}\n\nexport interface SonareEngineCaptureRequestMessage {\n type: 'captureRequest';\n requestId: number;\n op: 'status' | 'read' | 'reset';\n}\n\nexport interface SonareEngineCaptureResponseMessage {\n type: 'captureResponse';\n requestId: number;\n ok: boolean;\n status?: EngineCaptureStatus;\n channels?: Float32Array[] | number[][];\n error?: string;\n}\n\nexport interface SonareEngineTransportRequestMessage {\n type: 'transportRequest';\n requestId: number;\n op: 'state';\n}\n\nexport interface SonareEngineTransportResponseMessage {\n type: 'transportResponse';\n requestId: number;\n ok: boolean;\n state?: EngineTransportState;\n error?: string;\n}\n","import { panLawCode, panModeCode } from './codes';\nimport type {\n EngineAutomationPoint,\n EngineBus,\n EngineCaptureStatus,\n EngineClip,\n EngineMarker,\n EngineMetronomeConfig,\n EngineMidiClipSchedule,\n EngineParameterInfo,\n EngineScopeTelemetry,\n EngineTempoSegment,\n EngineTimeSignatureSegment,\n EngineTrackLane,\n EngineTrackSend,\n EngineTransportState,\n EqBand,\n MixerRealtimeBuffer,\n PanLaw,\n PanMode,\n} from './index';\nimport {\n engineCapabilities,\n init as initSonareModule,\n isInitialized,\n Mixer,\n RealtimeEngine,\n RealtimeVoiceChanger,\n} from './index';\nimport type { SonareModule } from './sonare.js';\nimport type { SonareRtModule } from './sonare-rt';\n\n// With code-splitting disabled, the worklet bundle carries its own copy of the\n// module singleton (a real AudioWorkletGlobalScope cannot resolve sibling\n// chunks, so the bundle must be self-contained). Re-export the lifecycle so that\n// realm can initialize its own wasm instance, independent of the main-thread\n// `index` module.\nexport { init, isInitialized } from './index';\n\nimport type { WorkletInput, WorkletOutput } from './worklet/audio_types';\nimport {\n isEngineCaptureRequestMessage,\n isEngineCaptureResponseMessage,\n isEngineCommandRecord,\n isEngineSyncMessage,\n isEngineTelemetryRecord,\n isEngineTransportRequestMessage,\n isEngineTransportResponseMessage,\n isMeterSnapshot,\n isRealtimeVoiceChangerMessage,\n isWorkletMessage,\n} from './worklet/guards';\nimport {\n DEFAULT_METRONOME_CONFIG,\n type ResolvedMetronomeConfig,\n resolveMetronomeConfig,\n type SonareEngineCaptureRequestMessage,\n type SonareEngineCaptureResponseMessage,\n type SonareEngineInstrumentSyncMessage,\n type SonareEngineSyncCaptureMessage,\n type SonareEngineSyncMessage,\n type SonareEngineTransportFacade,\n type SonareEngineTransportRequestMessage,\n type SonareEngineTransportResponseMessage,\n type SonareRealtimeEngineNodeCapabilities,\n type SonareRealtimeEngineNodeOptions,\n type SonareRealtimeEngineWorkletProcessorOptions,\n type SonareRealtimeVoiceChangerMessage,\n type SonareRealtimeVoiceChangerWorkletProcessorOptions,\n type SonareRtRealtimeEngineRuntimeOptions,\n type SonareWorkletMessage,\n type SonareWorkletProcessorOptions,\n type WorkletPort,\n type WorkletTransport,\n} from './worklet/messages';\n// --- internal modules (split out of this file; bundled back into a single\n// dist/worklet.js by tsup, so the public surface is unchanged) ---\nimport {\n createSonareEngineCommandRingBuffer,\n createSonareEngineTelemetryRingBuffer,\n createSonareMeterRingBuffer,\n createSonareScopeRingBuffer,\n ENGINE_MIXER_PARAM_FADER_DB,\n ENGINE_MIXER_PARAM_PAN,\n encodeFrameHi,\n encodeFrameLo,\n engineMixerBusTarget,\n engineMixerLaneTarget,\n engineMixerMasterTarget,\n engineRingFromSharedBuffer,\n isRecord,\n magnitudeToDb,\n meterFromEngine,\n meterRingFromSharedBuffer,\n popSonareEngineCommandRingBuffer,\n pushSonareEngineCommandRingBuffer,\n readSonareEngineTelemetryRingBuffer,\n readSonareMeterRingBuffer,\n readSonareScopeRingBuffer,\n type SharedMeterRingWriter,\n type SharedScopeRingWriter,\n type SharedSpectrumRingWriter,\n SONARE_ENGINE_COMMAND_RECORD_BYTES,\n SONARE_ENGINE_TELEMETRY_RECORD_BYTES,\n SONARE_METER_RING_RECORD_FLOATS,\n SONARE_SCOPE_RING_RECORD_PREFIX_FLOATS,\n type SonareEngineCommandRecord,\n type SonareEngineCommandRingBuffer,\n SonareEngineCommandType,\n SonareEngineTelemetryError,\n type SonareEngineTelemetryRecord,\n type SonareEngineTelemetryRingBuffer,\n SonareEngineTelemetryType,\n type SonareMeterRingBuffer,\n type SonareScopeRingBuffer,\n type SonareWorkletMeterSnapshot,\n type SonareWorkletScopeSnapshot,\n type SonareWorkletSpectrumSnapshot,\n scopeRingFromSharedBuffer,\n spectrumRingFromSharedBuffer,\n telemetryFromEngine,\n toBigInt64,\n toDb,\n writeSonareEngineTelemetryRingBuffer,\n} from './worklet/protocol';\n\nexport type {\n SonareEngineCaptureRequestMessage,\n SonareEngineCaptureResponseMessage,\n SonareEngineSyncAutomationMessage,\n SonareEngineSyncBuiltinInstrumentMessage,\n SonareEngineSyncCaptureMessage,\n SonareEngineSyncClipsDeltaMessage,\n SonareEngineSyncClipsMessage,\n SonareEngineSyncLoadSoundFontMessage,\n SonareEngineSyncMarkersMessage,\n SonareEngineSyncMasterStripEqBandMessage,\n SonareEngineSyncMasterStripInsertBypassedMessage,\n SonareEngineSyncMessage,\n SonareEngineSyncMetronomeMessage,\n SonareEngineSyncMidiCcMessage,\n SonareEngineSyncMidiClipsMessage,\n SonareEngineSyncMidiNoteMessage,\n SonareEngineSyncMidiPanicMessage,\n SonareEngineSyncMixerMessage,\n SonareEngineSyncSf2InstrumentMessage,\n SonareEngineSyncSynthInstrumentMessage,\n SonareEngineSyncTempoMessage,\n SonareEngineSyncTrackStripEqBandMessage,\n SonareEngineSyncTrackStripInsertBypassedMessage,\n SonareEngineTransportFacade,\n SonareEngineTransportRequestMessage,\n SonareEngineTransportResponseMessage,\n SonareRealtimeEngineNodeCapabilities,\n SonareRealtimeEngineNodeOptions,\n SonareRealtimeEngineWorkletProcessorOptions,\n SonareRealtimeVoiceChangerDestroyMessage,\n SonareRealtimeVoiceChangerMessage,\n SonareRealtimeVoiceChangerResetMessage,\n SonareRealtimeVoiceChangerSetConfigMessage,\n SonareRealtimeVoiceChangerWorkletProcessorOptions,\n SonareRtRealtimeEngineRuntimeOptions,\n SonareWorkletDestroyMessage,\n SonareWorkletMessage,\n SonareWorkletProcessorOptions,\n SonareWorkletScheduleInsertAutomationMessage,\n SonareWorkletSetMeterIntervalMessage,\n SonareWorkletTransportMessage,\n} from './worklet/messages';\nexport {\n createSonareEngineCommandRingBuffer,\n createSonareEngineTelemetryRingBuffer,\n createSonareMeterRingBuffer,\n createSonareScopeRingBuffer,\n createSonareSpectrumRingBuffer,\n decodeFrame,\n encodeFrameHi,\n encodeFrameLo,\n popSonareEngineCommandRingBuffer,\n pushSonareEngineCommandRingBuffer,\n readSonareEngineTelemetryRingBuffer,\n readSonareMeterRingBuffer,\n readSonareScopeRingBuffer,\n readSonareSpectrumRingBuffer,\n SONARE_ENGINE_COMMAND_RECORD_BYTES,\n SONARE_ENGINE_RING_HEADER_INTS,\n SONARE_ENGINE_TELEMETRY_RECORD_BYTES,\n SONARE_METER_RING_HEADER_INTS,\n SONARE_METER_RING_RECORD_FLOATS,\n SONARE_SCOPE_RING_HEADER_INTS,\n SONARE_SPECTRUM_RING_HEADER_INTS,\n type SonareEngineCommandRecord,\n type SonareEngineCommandRingBuffer,\n SonareEngineCommandType,\n SonareEngineTelemetryError,\n type SonareEngineTelemetryRecord,\n type SonareEngineTelemetryRingBuffer,\n type SonareEngineTelemetryRingReadResult,\n SonareEngineTelemetryType,\n type SonareMeterRingBuffer,\n type SonareMeterRingReadResult,\n type SonareScopeRingBuffer,\n type SonareScopeRingReadResult,\n type SonareSpectrumRingBuffer,\n type SonareSpectrumRingReadResult,\n type SonareWorkletMeterSnapshot,\n type SonareWorkletScopeSnapshot,\n type SonareWorkletSpectrumSnapshot,\n sonareEngineCommandRingBufferByteLength,\n sonareEngineTelemetryRingBufferByteLength,\n sonareMeterRingBufferByteLength,\n sonareScopeRingBufferByteLength,\n sonareSpectrumRingBufferByteLength,\n writeSonareEngineTelemetryRingBuffer,\n} from './worklet/protocol';\n\nexport interface SonareEngineOptions extends SonareRealtimeEngineNodeOptions {\n offlineEngine?: RealtimeEngine;\n offlineBlockSize?: number;\n offlineChannelCount?: number;\n}\n\ntype SuspendableAudioContext = BaseAudioContext & {\n suspend?: () => Promise<void>;\n resume?: () => Promise<void>;\n};\n\n/**\n * AudioWorklet-style mixer bridge backed by the package's single `sonare.wasm`.\n *\n * The WASM module must already be initialized via `init()` before constructing\n * this bridge. Each AudioWorklet input is treated as one stereo strip:\n * `inputs[strip][0]` is left and `inputs[strip][1]` is right. Missing channels\n * are replaced with preallocated silence.\n */\nexport class SonareWorkletProcessor {\n readonly sampleRate: number;\n readonly blockSize: number;\n private mixer: Mixer;\n private realtime: MixerRealtimeBuffer;\n private closed = false;\n private processedFrames = 0;\n private lastMeterFrame = 0;\n private meterIntervalFrames: number;\n private spectrumIntervalFrames: number;\n private lastSpectrumFrame = 0;\n private transport?: WorkletTransport;\n private meterRing?: SharedMeterRingWriter;\n private spectrumRing?: SharedSpectrumRingWriter;\n private spectrumBands: Float32Array;\n\n constructor(options: SonareWorkletProcessorOptions, transport?: WorkletTransport) {\n if (!options.sceneJson) {\n throw new Error('sceneJson is required.');\n }\n this.sampleRate = options.sampleRate ?? 48000;\n this.blockSize = options.blockSize ?? 128;\n this.meterIntervalFrames = Math.max(0, Math.floor(options.meterIntervalFrames ?? 2048));\n this.spectrumIntervalFrames = Math.max(0, Math.floor(options.spectrumIntervalFrames ?? 0));\n this.transport = transport;\n this.meterIntervalFrames = Math.max(0, Math.floor(options.meterIntervalFrames ?? 2048));\n this.meterRing = options.meterSharedBuffer\n ? meterRingFromSharedBuffer(options.meterSharedBuffer, options.meterRingCapacity)\n : undefined;\n this.spectrumRing = options.spectrumSharedBuffer\n ? spectrumRingFromSharedBuffer(\n options.spectrumSharedBuffer,\n options.spectrumRingCapacity,\n options.spectrumBands,\n )\n : undefined;\n const spectrumBandCount = this.spectrumRing?.bands ?? Math.max(1, options.spectrumBands ?? 16);\n this.spectrumBands = new Float32Array(spectrumBandCount);\n this.mixer = Mixer.fromSceneJson(options.sceneJson, this.sampleRate, this.blockSize);\n this.mixer.compile();\n const sceneStripCount = this.mixer.stripCount();\n const stripCount = options.stripCount ?? sceneStripCount;\n if (stripCount !== sceneStripCount) {\n throw new Error('stripCount must match the scene strip count.');\n }\n this.realtime = this.mixer.createRealtimeBuffer();\n }\n\n process(inputs: WorkletInput, outputs: WorkletOutput): boolean {\n if (this.closed) {\n return false;\n }\n const output = outputs[0];\n const leftOut = output?.[0];\n const rightOut = output?.[1];\n if (!leftOut) {\n return true;\n }\n const frames = leftOut.length;\n // The mixer's realtime heap buffers are sized to blockSize. A render quantum\n // that differs from blockSize (e.g. a future browser using a quantum other\n // than 128, or a misconfigured blockSize) must NOT return false here:\n // returning false permanently terminates the AudioWorkletProcessor and\n // silently kills the node mid-stream. Instead degrade gracefully by\n // processing min(frames, blockSize) and zero-filling any remainder, mirroring\n // the sonare-rt processor's behaviour.\n const usable = Math.min(frames, this.blockSize);\n\n for (let strip = 0; strip < this.realtime.leftInputs.length; strip++) {\n const input = inputs[strip];\n const left = input?.[0];\n const right = input?.[1];\n const leftTarget = this.realtime.leftInputs[strip];\n const rightTarget = this.realtime.rightInputs[strip];\n if (left && left.length >= usable) {\n leftTarget.set(left.subarray(0, usable));\n if (right && right.length >= usable) {\n rightTarget.set(right.subarray(0, usable));\n } else {\n rightTarget.set(left.subarray(0, usable));\n }\n } else {\n leftTarget.fill(0);\n rightTarget.fill(0);\n }\n }\n\n this.realtime.process(usable);\n if (usable === frames) {\n leftOut.set(this.realtime.outLeft.subarray(0, usable));\n if (rightOut) {\n rightOut.set(this.realtime.outRight.subarray(0, usable));\n }\n } else {\n // frames > blockSize: fill the produced part and zero the remaining tail.\n leftOut.fill(0);\n leftOut.set(this.realtime.outLeft.subarray(0, usable));\n if (rightOut) {\n rightOut.fill(0);\n rightOut.set(this.realtime.outRight.subarray(0, usable));\n }\n }\n this.processedFrames += usable;\n this.publishMeter(\n this.realtime.outLeft.subarray(0, usable),\n this.realtime.outRight.subarray(0, usable),\n );\n this.publishSpectrum(\n this.realtime.outLeft.subarray(0, usable),\n this.realtime.outRight.subarray(0, usable),\n );\n return true;\n }\n\n receiveMessage(message: SonareWorkletMessage): void {\n if (this.closed) {\n return;\n }\n if (message.type === 'destroy') {\n this.destroy();\n return;\n }\n if (message.type === 'setMeterInterval') {\n this.meterIntervalFrames = Math.max(0, Math.floor(message.frames));\n return;\n }\n if (message.type === 'scheduleInsertAutomation') {\n this.mixer.scheduleInsertAutomation(\n message.stripIndex,\n message.insertIndex,\n message.paramId,\n message.samplePos ?? this.processedFrames,\n message.value,\n message.curve ?? 'linear',\n );\n }\n }\n\n destroy(): void {\n if (!this.closed) {\n this.mixer.delete();\n this.closed = true;\n }\n }\n\n private publishMeter(left: Float32Array, right: Float32Array): void {\n if (!this.transport || this.meterIntervalFrames <= 0) {\n return;\n }\n if (this.processedFrames - this.lastMeterFrame < this.meterIntervalFrames) {\n return;\n }\n this.lastMeterFrame = this.processedFrames;\n\n let peakL = 0;\n let peakR = 0;\n let sumL = 0;\n let sumR = 0;\n let sumLR = 0;\n for (let i = 0; i < left.length; i++) {\n const l = left[i] ?? 0;\n const r = right[i] ?? 0;\n const absL = Math.abs(l);\n const absR = Math.abs(r);\n if (absL > peakL) {\n peakL = absL;\n }\n if (absR > peakR) {\n peakR = absR;\n }\n sumL += l * l;\n sumR += r * r;\n sumLR += l * r;\n }\n const rmsL = Math.sqrt(sumL / Math.max(1, left.length));\n const rmsR = Math.sqrt(sumR / Math.max(1, right.length));\n const denominator = Math.sqrt(sumL * sumR);\n const meter: SonareWorkletMeterSnapshot = {\n type: 'meter',\n targetId: 0,\n frame: this.processedFrames,\n peakDbL: toDb(peakL),\n peakDbR: toDb(peakR),\n rmsDbL: toDb(rmsL),\n rmsDbR: toDb(rmsR),\n correlation: denominator > 0 ? sumLR / denominator : 0,\n truePeakDbL: toDb(peakL),\n truePeakDbR: toDb(peakR),\n momentaryLufs: Number.NaN,\n shortTermLufs: Number.NaN,\n integratedLufs: Number.NaN,\n gainReductionDb: Number.NaN,\n };\n this.transport.onMeter?.(meter);\n if (this.meterRing) {\n this.writeMeterRing(meter);\n } else {\n this.transport.postMessage?.(meter);\n }\n }\n\n private writeMeterRing(meter: SonareWorkletMeterSnapshot): void {\n const ring = this.meterRing;\n if (!ring) {\n return;\n }\n const writeIndex = Atomics.load(ring.header, 0);\n const offset = (writeIndex % ring.capacity) * SONARE_METER_RING_RECORD_FLOATS;\n ring.records[offset] = encodeFrameLo(meter.frame);\n ring.records[offset + 1] = encodeFrameHi(meter.frame);\n ring.records[offset + 2] = meter.targetId;\n ring.records[offset + 3] = meter.peakDbL;\n ring.records[offset + 4] = meter.peakDbR;\n ring.records[offset + 5] = meter.rmsDbL;\n ring.records[offset + 6] = meter.rmsDbR;\n ring.records[offset + 7] = meter.correlation;\n ring.records[offset + 8] = meter.truePeakDbL;\n ring.records[offset + 9] = meter.truePeakDbR;\n ring.records[offset + 10] = meter.momentaryLufs;\n ring.records[offset + 11] = meter.shortTermLufs;\n ring.records[offset + 12] = meter.integratedLufs;\n ring.records[offset + 13] = meter.gainReductionDb;\n Atomics.store(ring.header, 0, writeIndex + 1);\n // writeIndex is a free-running monotonic counter, so an overflow guard here\n // would fire on essentially every write past the first `capacity` records\n // and store an ever-growing value, not a dropped-record count. Readers\n // already detect silent overrun via firstReadable = max(readIndex,\n // writeIndex - capacity), so header slot 3 is left at its initial 0.\n }\n\n private publishSpectrum(left: Float32Array, right: Float32Array): void {\n if (this.spectrumIntervalFrames <= 0) {\n return;\n }\n if (this.processedFrames - this.lastSpectrumFrame < this.spectrumIntervalFrames) {\n return;\n }\n this.lastSpectrumFrame = this.processedFrames;\n this.computeSpectrum(left, right);\n if (this.spectrumRing) {\n this.writeSpectrumRing(this.processedFrames, this.spectrumBands);\n return;\n }\n const spectrum: SonareWorkletSpectrumSnapshot = {\n type: 'spectrum',\n frame: this.processedFrames,\n bands: new Float32Array(this.spectrumBands),\n };\n this.transport?.onSpectrum?.(spectrum);\n this.transport?.postMessage?.(spectrum);\n }\n\n private computeSpectrum(left: Float32Array, right: Float32Array): void {\n // Coarse per-render-quantum band energy, NOT a full FFT analyzer: each band\n // is a single-bin DFT (bin = band + 1) evaluated over the current block of n\n // samples. Bins at or above the block Nyquist (band + 1 > floor(n / 2))\n // alias, so the evaluated band count is clamped to floor(n / 2) and any\n // higher bands are pinned to the silence floor. Bin resolution is therefore\n // tied to the render quantum (typically 128 samples); treat the output as a\n // rough spectral tilt, not a precise spectrum.\n const n = Math.max(1, Math.min(left.length, right.length));\n const maxBand = Math.floor(n / 2);\n for (let band = 0; band < this.spectrumBands.length; band++) {\n if (band >= maxBand) {\n this.spectrumBands[band] = magnitudeToDb(0);\n continue;\n }\n const bin = band + 1;\n let real = 0;\n let imag = 0;\n for (let i = 0; i < n; i++) {\n const sample = 0.5 * ((left[i] ?? 0) + (right[i] ?? 0));\n const phase = (-2 * Math.PI * bin * i) / n;\n real += sample * Math.cos(phase);\n imag += sample * Math.sin(phase);\n }\n this.spectrumBands[band] = magnitudeToDb((2 * Math.hypot(real, imag)) / n);\n }\n }\n\n private writeSpectrumRing(frame: number, bands: Float32Array): void {\n const ring = this.spectrumRing;\n if (!ring) {\n return;\n }\n const writeIndex = Atomics.load(ring.header, 0);\n const offset = (writeIndex % ring.capacity) * ring.recordFloats;\n ring.records[offset] = encodeFrameLo(frame);\n ring.records[offset + 1] = encodeFrameHi(frame);\n ring.records[offset + 2] = bands.length;\n ring.records.set(bands.subarray(0, ring.bands), offset + 3);\n Atomics.store(ring.header, 0, writeIndex + 1);\n // See writeMeterRing: header slot 4 (the spectrum-ring overflow slot) is\n // left at its initial 0; readers detect silent overrun via the\n // firstReadable = max(readIndex, writeIndex - capacity) clamp. (Slot 3 here\n // holds the band count and is still written at ring creation.)\n }\n}\n\n/**\n * AudioWorklet-style bridge for the DAW realtime engine facade.\n *\n * The default mode uses the existing `sonare.wasm` embind facade. The\n * `sonare-rt` target is exposed as a selectable runtime target for hosts that\n * load the dedicated Emscripten AudioWorklet module.\n */\nexport class SonareRealtimeEngineWorkletProcessor {\n private static warnedChannelScratchOverflow = false;\n readonly sampleRate: number;\n readonly blockSize: number;\n readonly channelCount: number;\n readonly runtimeTarget: 'embind' | 'sonare-rt';\n private engine: RealtimeEngine;\n private closed = false;\n private commandRing?: SonareEngineCommandRingBuffer;\n private telemetryRing?: SonareEngineTelemetryRingBuffer;\n private meterRing?: SharedMeterRingWriter;\n private scopeRing?: SharedScopeRingWriter;\n private transport?: WorkletTransport;\n private meterIntervalFrames: number;\n private lastMeterFrame = Number.NEGATIVE_INFINITY;\n // Latest metronome gains/click length pushed via 'syncMetronome'. The\n // SetMetronome command only toggles enabled state; the config arrives here.\n private metronomeConfig: ResolvedMetronomeConfig = { ...DEFAULT_METRONOME_CONFIG };\n // Zero-copy prepared realtime path: persistent per-channel views onto the\n // engine's WASM-heap scratch (acquired once on the main thread via\n // getChannelBuffer). process() writes the AudioWorklet input straight into\n // these views, calls engine.processPrepared(frames) which runs the engine IN\n // PLACE, then reads the same views back — no std::vector or JS Float32Array is\n // allocated per render quantum (the old engine.process() round-tripped fresh\n // arrays on both heaps every block, an RT-safety hazard).\n private channelBuffers: Float32Array[];\n private readonly liveClips = new Map<number, EngineClip>();\n\n constructor(\n options: SonareRealtimeEngineWorkletProcessorOptions = {},\n transport?: WorkletTransport,\n ) {\n this.sampleRate = options.sampleRate ?? 48000;\n this.blockSize = options.blockSize ?? 128;\n this.channelCount = Math.max(1, Math.floor(options.channelCount ?? 2));\n this.runtimeTarget = options.runtimeTarget ?? 'embind';\n if (this.runtimeTarget === 'sonare-rt') {\n throw new Error(\n 'sonare-rt runtime is provided by the dedicated Emscripten AudioWorklet module; use SonareRealtimeEngineNode.create({ runtimeTarget: \"sonare-rt\", moduleUrl: ... }) to load it.',\n );\n }\n this.transport = transport;\n this.meterIntervalFrames = Math.max(0, Math.floor(options.meterIntervalFrames ?? 2048));\n this.commandRing = options.commandSharedBuffer\n ? this.commandRingFromSharedBuffer(options.commandSharedBuffer, options.commandRingCapacity)\n : undefined;\n this.telemetryRing = options.telemetrySharedBuffer\n ? this.telemetryRingFromSharedBuffer(\n options.telemetrySharedBuffer,\n options.telemetryRingCapacity,\n )\n : undefined;\n this.meterRing = options.meterSharedBuffer\n ? meterRingFromSharedBuffer(options.meterSharedBuffer, options.meterRingCapacity)\n : undefined;\n this.scopeRing = options.scopeSharedBuffer\n ? scopeRingFromSharedBuffer(\n options.scopeSharedBuffer,\n options.scopeRingCapacity,\n options.scopeBands,\n )\n : undefined;\n this.engine = new RealtimeEngine(this.sampleRate, this.blockSize);\n // Allocate persistent WASM-heap scratch (worst case: channelCount channels x\n // blockSize frames) and acquire the per-channel heap views once.\n this.engine.prepareChannels(this.channelCount, this.blockSize);\n this.channelBuffers = new Array(this.channelCount);\n for (let ch = 0; ch < this.channelCount; ch++) {\n this.channelBuffers[ch] = this.engine.getChannelBuffer(ch, this.blockSize);\n }\n // Arm the engine's scope producer only when a scope ring was provided. The\n // band count follows the ring's record layout so writeScopeRing never\n // overruns its slot.\n if (this.scopeRing) {\n const interval = Math.max(1, Math.floor(options.scopeIntervalFrames ?? this.blockSize));\n this.engine.configureScopeTelemetry(interval, this.scopeRing.bands);\n }\n }\n\n process(inputs: WorkletInput, outputs: WorkletOutput): boolean {\n if (this.closed) {\n return false;\n }\n const output = outputs[0];\n const firstOutput = output?.[0];\n if (!firstOutput) {\n return true;\n }\n const frames = firstOutput.length;\n if (frames > this.blockSize) {\n for (const channel of output ?? []) {\n channel.fill(0);\n }\n this.publishTelemetry();\n return true;\n }\n\n this.drainCommands();\n\n // Clamp `frames` to the pre-allocated scratch capacity. The earlier\n // `frames > this.blockSize` branch already returns early, so this is\n // defensive — but we warn once if it ever fires so the contract violation\n // is visible.\n let usableFrames = frames;\n if (usableFrames > this.blockSize) {\n if (!SonareRealtimeEngineWorkletProcessor.warnedChannelScratchOverflow) {\n SonareRealtimeEngineWorkletProcessor.warnedChannelScratchOverflow = true;\n // biome-ignore lint/suspicious/noConsole: realtime-safety diagnostic.\n console.warn(\n `SonareRealtimeEngineWorkletProcessor: requested ${usableFrames} frames ` +\n `exceeds pre-allocated capacity ${this.blockSize}; clamping.`,\n );\n }\n usableFrames = this.blockSize;\n }\n\n // Defend against WASM linear-memory growth detaching the cached heap views:\n // if any view's backing ArrayBuffer has been detached (byteLength === 0),\n // re-acquire all of them. This is a control-flow check (no allocation in the\n // common case where memory did not grow).\n if ((this.channelBuffers[0]?.byteLength ?? 0) === 0) {\n this.reacquireChannelBuffers();\n }\n\n const input = inputs[0];\n // Write the AudioWorklet input straight into the engine's WASM-heap views;\n // no per-block heap allocation.\n for (let ch = 0; ch < this.channelCount; ch++) {\n const dst = this.channelBuffers[ch];\n const source = input?.[ch];\n if (source && source.length === usableFrames) {\n dst.set(source.subarray(0, usableFrames));\n } else {\n dst.fill(0, 0, usableFrames);\n }\n }\n\n // Run the engine in place over the prepared scratch (allocation-free).\n this.engine.processPrepared(usableFrames);\n\n for (let ch = 0; ch < output.length; ch++) {\n const target = output[ch];\n const source = this.channelBuffers[ch] ?? this.channelBuffers[0];\n if (source) {\n target.set(source.subarray(0, Math.min(target.length, usableFrames)));\n if (target.length > usableFrames) {\n target.fill(0, usableFrames);\n }\n } else {\n target.fill(0);\n }\n }\n this.publishTelemetry();\n this.publishMeters();\n this.publishScope();\n return true;\n }\n\n private reacquireChannelBuffers(): void {\n for (let ch = 0; ch < this.channelCount; ch++) {\n this.channelBuffers[ch] = this.engine.getChannelBuffer(ch, this.blockSize);\n }\n }\n\n receiveCommand(command: SonareEngineCommandRecord): void {\n if (!this.closed) {\n this.applyCommand(command);\n }\n }\n\n // Applies an out-of-band control-plane sync message. Runs on the AudioWorklet\n // global scope but OUTSIDE process() (the message-port callback), so the\n // bulk/allocating engine setters (setClips/setMarkers) are safe here — they\n // never run on the realtime render path. This is the audio-thread equivalent\n // of the engine's control-thread RtPublisher setters.\n receiveSync(message: SonareEngineSyncMessage): void {\n if (this.closed) {\n return;\n }\n switch (message.type) {\n case 'syncClips':\n this.liveClips.clear();\n for (const clip of message.clips) {\n if (clip.id !== undefined) {\n this.liveClips.set(clip.id, clip);\n }\n }\n this.engine.setClips(message.clips);\n break;\n case 'syncClipsDelta':\n for (const clipId of message.removeIds) {\n this.liveClips.delete(clipId);\n }\n for (const clip of message.upserts) {\n if (clip.id !== undefined) {\n this.liveClips.set(clip.id, clip);\n }\n }\n this.engine.setClips(Array.from(this.liveClips.values()));\n break;\n case 'syncMidiClips':\n this.engine.setMidiClips(message.clips);\n break;\n case 'syncMarkers':\n this.engine.setMarkers(message.markers);\n break;\n case 'syncMetronome':\n this.metronomeConfig = resolveMetronomeConfig(message.config);\n this.engine.setMetronome(message.config);\n break;\n case 'syncAutomation':\n this.engine.setAutomationLane(message.paramId, message.points);\n break;\n case 'syncTempo':\n if (message.tempoSegments) {\n this.engine.setTempoSegments(message.tempoSegments);\n } else {\n this.engine.setTempo(message.bpm);\n }\n if (message.timeSignatureSegments) {\n this.engine.setTimeSignatureSegments(message.timeSignatureSegments);\n } else {\n this.engine.setTimeSignature(\n message.timeSignature.numerator,\n message.timeSignature.denominator,\n );\n }\n break;\n case 'syncMixer':\n if (message.buses) {\n this.engine.setTrackBuses(message.buses);\n }\n this.engine.setTrackLanes(message.lanes);\n for (const strip of message.trackStrips ?? []) {\n this.engine.setTrackStripJson(strip.trackId, strip.sceneJson);\n }\n for (const strip of message.busStrips ?? []) {\n this.engine.setBusStripJson(strip.busId, strip.sceneJson);\n }\n if (message.masterStripJson) {\n this.engine.setMasterStripJson(message.masterStripJson);\n }\n for (const binding of message.laneSidechains ?? []) {\n this.engine.setLaneSidechain(binding.trackId, binding.insertIndex, binding.sourceTrackId);\n }\n break;\n case 'syncCapture':\n this.engine.setCaptureBuffer(message.channels, message.bufferFrames);\n this.engine.setCaptureSource(message.source);\n this.engine.setRecordOffsetSamples(message.recordOffsetSamples);\n this.engine.setInputMonitor(message.inputMonitor.enabled, message.inputMonitor.gain);\n break;\n case 'syncTrackStripEqBand':\n this.engine.setTrackStripEqBandJson(message.trackId, message.bandIndex, message.bandJson);\n break;\n case 'syncMasterStripEqBand':\n this.engine.setMasterStripEqBandJson(message.bandIndex, message.bandJson);\n break;\n case 'syncTrackStripInsertBypassed':\n this.engine.setTrackStripInsertBypassed(\n message.trackId,\n message.insertIndex,\n message.bypassed,\n message.resetOnBypass,\n );\n break;\n case 'syncMasterStripInsertBypassed':\n this.engine.setMasterStripInsertBypassed(\n message.insertIndex,\n message.bypassed,\n message.resetOnBypass,\n );\n break;\n case 'syncTrackStripInsertParamByName':\n this.engine.setTrackStripInsertParamByName(\n message.trackId,\n message.insertIndex,\n message.paramName,\n message.value,\n );\n break;\n case 'syncMasterStripInsertParamByName':\n this.engine.setMasterStripInsertParamByName(\n message.insertIndex,\n message.paramName,\n message.value,\n );\n break;\n case 'syncTrackStripPan':\n this.engine.setTrackStripPan(message.trackId, message.pan);\n break;\n case 'syncTrackStripPanLaw':\n this.engine.setTrackStripPanLaw(message.trackId, message.panLaw);\n break;\n case 'syncTrackStripPanMode':\n this.engine.setTrackStripPanMode(message.trackId, message.panMode);\n break;\n case 'syncTrackStripDualPan':\n this.engine.setTrackStripDualPan(message.trackId, message.leftPan, message.rightPan);\n break;\n case 'syncTrackStripChannelDelaySamples':\n this.engine.setTrackStripChannelDelaySamples(message.trackId, message.delaySamples);\n break;\n case 'syncBuiltinInstrument':\n this.engine.setBuiltinInstrument(message.config, message.destinationId);\n break;\n case 'syncSynthInstrument':\n this.engine.setSynthInstrument(message.patch, message.destinationId);\n break;\n case 'syncLoadSoundFont':\n this.engine.loadSoundFont(message.data);\n break;\n case 'syncSf2Instrument':\n this.engine.setSf2Instrument(message.config, message.destinationId);\n break;\n case 'syncMidiNoteOn':\n this.engine.pushMidiNoteOn(\n message.destinationId,\n message.group,\n message.channel,\n message.note,\n message.velocity,\n message.renderFrame,\n );\n break;\n case 'syncMidiNoteOff':\n this.engine.pushMidiNoteOff(\n message.destinationId,\n message.group,\n message.channel,\n message.note,\n message.velocity,\n message.renderFrame,\n );\n break;\n case 'syncMidiCc':\n this.engine.pushMidiCc(\n message.destinationId,\n message.group,\n message.channel,\n message.controller,\n message.value,\n message.renderFrame,\n );\n break;\n case 'syncMidiPanic':\n this.engine.pushMidiPanic(message.renderFrame);\n break;\n }\n }\n\n receiveCaptureRequest(message: SonareEngineCaptureRequestMessage): void {\n if (this.closed) {\n return;\n }\n try {\n if (message.op === 'status') {\n const status = this.engine.captureStatus();\n this.transport?.postMessage?.({\n type: 'captureResponse',\n requestId: message.requestId,\n ok: true,\n status: {\n capturedFrames: status.capturedFrames,\n overflowCount: status.overflowCount,\n armed: status.armed,\n punchEnabled: status.punchEnabled,\n source: status.source,\n recordOffsetSamples: status.recordOffsetSamples,\n },\n } satisfies SonareEngineCaptureResponseMessage);\n return;\n }\n if (message.op === 'read') {\n const captured = this.engine.capturedAudio();\n const channels: number[][] = [];\n for (let ch = 0; ch < captured.length; ch++) {\n const source = captured[ch];\n const copy: number[] = [];\n for (let i = 0; i < source.length; i++) {\n copy.push(Number(source[i]));\n }\n channels.push(copy);\n }\n this.transport?.postMessage?.({\n type: 'captureResponse',\n requestId: message.requestId,\n ok: true,\n channels,\n } satisfies SonareEngineCaptureResponseMessage);\n return;\n }\n this.engine.resetCapture();\n this.transport?.postMessage?.({\n type: 'captureResponse',\n requestId: message.requestId,\n ok: true,\n } satisfies SonareEngineCaptureResponseMessage);\n } catch (error) {\n this.transport?.postMessage?.({\n type: 'captureResponse',\n requestId: message.requestId,\n ok: false,\n error: error instanceof Error ? error.message : String(error),\n } satisfies SonareEngineCaptureResponseMessage);\n }\n }\n\n receiveTransportRequest(message: SonareEngineTransportRequestMessage): void {\n if (this.closed) {\n return;\n }\n try {\n this.transport?.postMessage?.({\n type: 'transportResponse',\n requestId: message.requestId,\n ok: true,\n state: this.engine.getTransportState(),\n } satisfies SonareEngineTransportResponseMessage);\n } catch (error) {\n this.transport?.postMessage?.({\n type: 'transportResponse',\n requestId: message.requestId,\n ok: false,\n error: error instanceof Error ? error.message : String(error),\n } satisfies SonareEngineTransportResponseMessage);\n }\n }\n\n destroy(): void {\n if (!this.closed) {\n this.engine.destroy();\n this.closed = true;\n }\n }\n\n private drainCommands(): void {\n if (!this.commandRing) {\n return;\n }\n for (let i = 0; i < 64; i++) {\n const command = popSonareEngineCommandRingBuffer(this.commandRing);\n if (!command) {\n return;\n }\n this.applyCommand(command);\n }\n }\n\n private applyCommand(command: SonareEngineCommandRecord): void {\n const sampleTime = Number(command.sampleTime ?? -1);\n switch (command.type) {\n case SonareEngineCommandType.SetParam:\n // paramId is carried in targetId, the new value in argFloat (matches the\n // SonareEngine.setParam producer). sampleTime is the render frame.\n this.engine.setParameter(\n Math.trunc(Number(command.targetId ?? 0)),\n Number(command.argFloat ?? 0),\n sampleTime,\n );\n break;\n case SonareEngineCommandType.SetParamSmoothed:\n this.engine.setParameterSmoothed(\n Math.trunc(Number(command.targetId ?? 0)),\n Number(command.argFloat ?? 0),\n sampleTime,\n );\n break;\n case SonareEngineCommandType.TransportPlay:\n this.engine.play(sampleTime);\n break;\n case SonareEngineCommandType.TransportStop:\n this.engine.stop(sampleTime);\n break;\n case SonareEngineCommandType.TransportSeekSample:\n this.engine.seekSample(Number(command.argInt ?? 0), sampleTime);\n break;\n case SonareEngineCommandType.TransportSeekPpq:\n this.engine.seekPpq(Number(command.argFloat ?? 0), sampleTime);\n break;\n case SonareEngineCommandType.SetTempoMap:\n this.engine.setTempo(Number(command.argFloat ?? 120));\n break;\n case SonareEngineCommandType.SetLoop:\n this.engine.setLoop(\n Number(command.argFloat ?? 0),\n Number(command.argInt ?? 0) / 1_000_000,\n command.targetId !== 0,\n );\n break;\n case SonareEngineCommandType.ArmRecord:\n this.engine.armCapture(Boolean(command.argInt));\n break;\n case SonareEngineCommandType.Punch:\n // Both endpoints already arrive as samples (see SonareEngine.punch);\n // do NOT re-scale by sampleRate.\n this.engine.setCapturePunch(\n Number(command.argInt ?? 0),\n Math.max(0, Math.round(Number(command.argFloat ?? 0))),\n true,\n );\n break;\n case SonareEngineCommandType.SetMetronome:\n // Metronome config (beatGain/accentGain/clickSamples/clickSeconds) is\n // delivered out-of-band via the 'syncMetronome' message so it carries\n // the caller's full config; the command only toggles enabled state as a\n // sample-aligned fallback.\n this.engine.setMetronome({\n enabled: Boolean(command.argInt),\n beatGain: this.metronomeConfig.beatGain,\n accentGain: this.metronomeConfig.accentGain,\n clickSamples: this.metronomeConfig.clickSamples,\n });\n break;\n case SonareEngineCommandType.SeekMarker:\n // The realtime engine's markers are kept in sync via 'syncMarkers'\n // (RtPublisher-style swap), so a queued kSeekMarker resolves correctly.\n this.engine.seekMarker(Math.trunc(Number(command.targetId ?? 0)), sampleTime);\n break;\n case SonareEngineCommandType.SetSoloMute:\n this.engine.setSoloMute(\n Math.trunc(Number(command.targetId ?? 0)),\n Boolean((Number(command.argInt ?? 0) & 0x2) !== 0),\n Boolean((Number(command.argInt ?? 0) & 0x1) !== 0),\n sampleTime,\n );\n break;\n default:\n this.publishTelemetryRecord({\n type: SonareEngineTelemetryType.Error,\n error: SonareEngineTelemetryError.UnknownTarget,\n renderFrame: 0,\n timelineSample: 0,\n audibleTimelineSample: 0,\n graphLatencySamplesQ8: 0,\n value: Number(command.type),\n });\n break;\n }\n }\n\n private publishTelemetry(): void {\n for (const item of this.engine.drainTelemetry(64)) {\n this.publishTelemetryRecord(telemetryFromEngine(item));\n }\n }\n\n private publishTelemetryRecord(record: SonareEngineTelemetryRecord): void {\n if (this.telemetryRing) {\n writeSonareEngineTelemetryRingBuffer(this.telemetryRing, record);\n return;\n }\n this.transport?.postMessage?.(record);\n }\n\n // Drains the engine meter telemetry queue into the stereo meter ring / transport.\n //\n // Shared-queue contract: `drainMeterTelemetry` and `drainMeterTelemetryWide`\n // pop the SAME single-consumer telemetry queue, so exactly ONE of them may run\n // per engine. The live worklet path owns the queue via the stereo drain below;\n // the worklet meter ring (SONARE_METER_RING_RECORD_FLOATS) is a fixed stereo\n // layout carrying planes 0/1 plus the correlation/LUFS summary. Per-plane\n // surround meters are NOT delivered over the live worklet ring — a host that\n // needs them must use the offline `drainMeterTelemetryWide()` API on a\n // non-worklet engine instance (do not also call it on a worklet-driven engine,\n // or the two drains will starve each other).\n private publishMeters(): void {\n if (this.meterIntervalFrames <= 0 || (!this.transport && !this.meterRing)) {\n return;\n }\n for (const item of this.engine.drainMeterTelemetry(64)) {\n const meter = meterFromEngine(item);\n if (\n meter.frame !== this.lastMeterFrame &&\n meter.frame - this.lastMeterFrame < this.meterIntervalFrames\n ) {\n continue;\n }\n if (meter.frame !== this.lastMeterFrame) {\n this.lastMeterFrame = meter.frame;\n }\n // Prefer the lock-free SAB meter ring (matching the telemetry path and\n // SonareWorkletProcessor); only fall back to structured-clone postMessage\n // when no ring was provided, so we do not allocate/post from the audio\n // render callback in SAB mode.\n if (this.meterRing) {\n this.writeMeterRing(meter);\n } else {\n this.transport?.onMeter?.(meter);\n this.transport?.postMessage?.(meter);\n }\n }\n }\n\n private writeMeterRing(meter: SonareWorkletMeterSnapshot): void {\n const ring = this.meterRing;\n if (!ring) {\n return;\n }\n const writeIndex = Atomics.load(ring.header, 0);\n const offset = (writeIndex % ring.capacity) * SONARE_METER_RING_RECORD_FLOATS;\n ring.records[offset] = encodeFrameLo(meter.frame);\n ring.records[offset + 1] = encodeFrameHi(meter.frame);\n ring.records[offset + 2] = meter.targetId;\n ring.records[offset + 3] = meter.peakDbL;\n ring.records[offset + 4] = meter.peakDbR;\n ring.records[offset + 5] = meter.rmsDbL;\n ring.records[offset + 6] = meter.rmsDbR;\n ring.records[offset + 7] = meter.correlation;\n ring.records[offset + 8] = meter.truePeakDbL;\n ring.records[offset + 9] = meter.truePeakDbR;\n ring.records[offset + 10] = meter.momentaryLufs;\n ring.records[offset + 11] = meter.shortTermLufs;\n ring.records[offset + 12] = meter.integratedLufs;\n ring.records[offset + 13] = meter.gainReductionDb;\n Atomics.store(ring.header, 0, writeIndex + 1);\n // writeIndex is a free-running monotonic counter, so an overflow guard here\n // would fire on essentially every write past the first `capacity` records\n // and store an ever-growing value, not a dropped-record count. Readers\n // already detect silent overrun via firstReadable = max(readIndex,\n // writeIndex - capacity), so header slot 3 is left at its initial 0.\n }\n\n // Drains the engine's scope producer (FFT spectrum + goniometer points) into\n // the lock-free SAB scope ring. Only the embind runtime publishes scope\n // telemetry; the sonare-rt runtime owns its own transport. No allocation on\n // the render path: records are written field-by-field into the ring.\n private publishScope(): void {\n const ring = this.scopeRing;\n if (!ring) {\n return;\n }\n for (const item of this.engine.drainScopeTelemetry(64)) {\n this.writeScopeRing(ring, item);\n }\n }\n\n private writeScopeRing(ring: SharedScopeRingWriter, record: EngineScopeTelemetry): void {\n const writeIndex = Atomics.load(ring.header, 0);\n const base = (writeIndex % ring.capacity) * ring.recordFloats;\n ring.records[base] = encodeFrameLo(record.renderFrame);\n ring.records[base + 1] = encodeFrameHi(record.renderFrame);\n ring.records[base + 2] = record.targetId;\n const bandCount = Math.min(ring.bands, record.bands.length);\n ring.records[base + 3] = bandCount;\n const pointCount = Math.min(ring.maxPoints, record.points.length);\n ring.records[base + 4] = pointCount;\n const bandsBase = base + SONARE_SCOPE_RING_RECORD_PREFIX_FLOATS;\n for (let i = 0; i < bandCount; i++) {\n ring.records[bandsBase + i] = record.bands[i];\n }\n const pointsBase = bandsBase + ring.bands;\n for (let i = 0; i < pointCount; i++) {\n const point = record.points[i];\n ring.records[pointsBase + 2 * i] = point.left;\n ring.records[pointsBase + 2 * i + 1] = point.right;\n }\n Atomics.store(ring.header, 0, writeIndex + 1);\n // Like writeMeterRing, writeIndex is a free-running monotonic counter; the\n // reader detects silent overrun via firstReadable, so the overflow slot\n // (header[5]) stays at its initial 0.\n }\n\n private commandRingFromSharedBuffer(\n sharedBuffer: SharedArrayBuffer,\n fallbackCapacity?: number,\n ): SonareEngineCommandRingBuffer {\n const ring = engineRingFromSharedBuffer(\n sharedBuffer,\n SONARE_ENGINE_COMMAND_RECORD_BYTES,\n fallbackCapacity,\n );\n return { sharedBuffer, header: ring.header, view: ring.view, capacity: ring.capacity };\n }\n\n private telemetryRingFromSharedBuffer(\n sharedBuffer: SharedArrayBuffer,\n fallbackCapacity?: number,\n ): SonareEngineTelemetryRingBuffer {\n const ring = engineRingFromSharedBuffer(\n sharedBuffer,\n SONARE_ENGINE_TELEMETRY_RECORD_BYTES,\n fallbackCapacity,\n );\n return { sharedBuffer, header: ring.header, view: ring.view, capacity: ring.capacity };\n }\n}\n\nexport class SonareRtRealtimeEngineRuntime {\n readonly sampleRate: number;\n readonly blockSize: number;\n readonly channelCount: number;\n private readonly module: SonareRtModule;\n private readonly memory: WebAssembly.Memory;\n private readonly engine: number;\n private readonly channelPointerTable: number;\n private readonly channelBuffers: number[];\n private readonly telemetryIntsPtr: number;\n private readonly telemetryFramesPtr: number;\n private readonly commandRing?: SonareEngineCommandRingBuffer;\n private readonly telemetryRing?: SonareEngineTelemetryRingBuffer;\n private metronomeConfig: ResolvedMetronomeConfig = { ...DEFAULT_METRONOME_CONFIG };\n private closed = false;\n\n constructor(options: SonareRtRealtimeEngineRuntimeOptions) {\n this.module = options.module;\n this.memory = options.memory;\n this.sampleRate = options.sampleRate ?? 48000;\n this.blockSize = options.blockSize ?? 128;\n this.channelCount = Math.max(1, Math.floor(options.channelCount ?? 2));\n this.commandRing = options.commandSharedBuffer\n ? this.commandRingFromSharedBuffer(options.commandSharedBuffer, options.commandRingCapacity)\n : undefined;\n this.telemetryRing = options.telemetrySharedBuffer\n ? this.telemetryRingFromSharedBuffer(\n options.telemetrySharedBuffer,\n options.telemetryRingCapacity,\n )\n : undefined;\n\n this.engine = this.module._sonare_rt_engine_create();\n if (this.engine <= 0) {\n throw new Error('failed to create sonare-rt engine');\n }\n if (\n this.module._sonare_rt_engine_prepare(\n this.engine,\n this.sampleRate,\n this.blockSize,\n 1024,\n 1024,\n ) !== 1\n ) {\n this.module._sonare_rt_engine_destroy(this.engine);\n throw new Error('failed to prepare sonare-rt engine');\n }\n this.channelPointerTable = this.module._malloc(\n this.channelCount * Uint32Array.BYTES_PER_ELEMENT,\n );\n this.channelBuffers = [];\n for (let ch = 0; ch < this.channelCount; ch++) {\n this.channelBuffers.push(\n this.module._malloc(this.blockSize * Float32Array.BYTES_PER_ELEMENT),\n );\n }\n this.telemetryIntsPtr = this.module._malloc(64 * 4 * Int32Array.BYTES_PER_ELEMENT);\n this.telemetryFramesPtr = this.module._malloc(64 * 3 * Float64Array.BYTES_PER_ELEMENT);\n this.writeChannelPointers();\n }\n\n process(inputs: WorkletInput, outputs: WorkletOutput): boolean {\n if (this.closed) {\n return false;\n }\n const output = outputs[0];\n const firstOutput = output?.[0];\n if (!firstOutput) {\n return true;\n }\n const frames = firstOutput.length;\n if (frames > this.blockSize) {\n for (const channel of output) {\n channel.fill(0);\n }\n return true;\n }\n\n this.drainCommands();\n const heap = new Float32Array(this.memory.buffer);\n const input = inputs[0];\n for (let ch = 0; ch < this.channelCount; ch++) {\n const ptr = this.channelBuffers[ch] ?? this.channelBuffers[0];\n const offset = ptr >> 2;\n const source = input?.[ch];\n if (source && source.length === frames) {\n heap.set(source, offset);\n } else {\n heap.fill(0, offset, offset + frames);\n }\n }\n\n this.module._sonare_rt_engine_process(\n this.engine,\n this.channelPointerTable,\n this.channelCount,\n frames,\n );\n\n for (let ch = 0; ch < output.length; ch++) {\n const target = output[ch];\n const ptr = this.channelBuffers[ch] ?? this.channelBuffers[0];\n target.set(heap.subarray(ptr >> 2, (ptr >> 2) + target.length));\n }\n this.publishTelemetry();\n return true;\n }\n\n receiveCommand(command: SonareEngineCommandRecord): void {\n if (!this.closed) {\n this.applyCommand(command);\n }\n }\n\n // Out-of-band control sync for the sonare-rt runtime. The sonare-rt C ABI\n // (src/wasm/rt_bindings.cpp) exposes set_metronome_enabled and seek_marker but\n // NOT set_clips / set_markers, so clip/marker mutations cannot be applied to a\n // live sonare-rt engine. We honor the metronome config and surface a clear\n // telemetry error for the unsupported clip/marker paths instead of silently\n // dropping them. The default 'embind' runtime wires all three fully.\n receiveSync(message: SonareEngineSyncMessage): void {\n if (this.closed) {\n return;\n }\n switch (message.type) {\n case 'syncMetronome':\n this.metronomeConfig = resolveMetronomeConfig(message.config);\n this.module._sonare_rt_engine_set_metronome_enabled(\n this.engine,\n message.config.enabled ? 1 : 0,\n this.metronomeConfig.beatGain,\n this.metronomeConfig.accentGain,\n this.metronomeConfig.clickSamples,\n );\n break;\n case 'syncTempo':\n this.module._sonare_rt_engine_set_tempo(this.engine, message.bpm);\n break;\n case 'syncClips':\n case 'syncClipsDelta':\n case 'syncMidiClips':\n case 'syncMarkers':\n case 'syncAutomation':\n case 'syncMixer':\n case 'syncCapture':\n case 'syncTrackStripEqBand':\n case 'syncMasterStripEqBand':\n case 'syncTrackStripInsertBypassed':\n case 'syncMasterStripInsertBypassed':\n case 'syncBuiltinInstrument':\n case 'syncSynthInstrument':\n case 'syncSf2Instrument':\n case 'syncLoadSoundFont':\n case 'syncMidiNoteOn':\n case 'syncMidiNoteOff':\n case 'syncMidiCc':\n case 'syncMidiPanic':\n // The sonare-rt C ABI exposes no set_clips / set_markers /\n // set_automation_lane / set_track_lanes, so these mutations cannot\n // reach a live sonare-rt engine. Surface a clear telemetry error rather\n // than silently dropping.\n if (this.telemetryRing) {\n writeSonareEngineTelemetryRingBuffer(this.telemetryRing, {\n type: SonareEngineTelemetryType.Error,\n error: SonareEngineTelemetryError.UnknownTarget,\n renderFrame: 0,\n timelineSample: 0,\n audibleTimelineSample: 0,\n graphLatencySamplesQ8: 0,\n value: 0,\n });\n }\n break;\n }\n }\n\n receiveCaptureRequest(message: SonareEngineCaptureRequestMessage, port?: WorkletPort): void {\n if (this.closed) {\n return;\n }\n port?.postMessage?.({\n type: 'captureResponse',\n requestId: message.requestId,\n ok: false,\n error: 'Capture read-back is not supported by the sonare-rt runtime.',\n } satisfies SonareEngineCaptureResponseMessage);\n }\n\n receiveTransportRequest(message: SonareEngineTransportRequestMessage, port?: WorkletPort): void {\n if (this.closed) {\n return;\n }\n port?.postMessage?.({\n type: 'transportResponse',\n requestId: message.requestId,\n ok: false,\n error: 'Transport state read-back is not supported by the sonare-rt runtime.',\n } satisfies SonareEngineTransportResponseMessage);\n }\n\n destroy(): void {\n if (this.closed) {\n return;\n }\n this.module._free(this.telemetryFramesPtr);\n this.module._free(this.telemetryIntsPtr);\n for (const ptr of this.channelBuffers) {\n this.module._free(ptr);\n }\n this.module._free(this.channelPointerTable);\n this.module._sonare_rt_engine_destroy(this.engine);\n this.closed = true;\n }\n\n private writeChannelPointers(): void {\n const pointers = new Uint32Array(this.memory.buffer);\n const offset = this.channelPointerTable >> 2;\n for (let ch = 0; ch < this.channelBuffers.length; ch++) {\n pointers[offset + ch] = this.channelBuffers[ch];\n }\n }\n\n private drainCommands(): void {\n if (!this.commandRing) {\n return;\n }\n for (let i = 0; i < 64; i++) {\n const command = popSonareEngineCommandRingBuffer(this.commandRing);\n if (!command) {\n return;\n }\n this.applyCommand(command);\n }\n }\n\n private applyCommand(command: SonareEngineCommandRecord): void {\n const sampleTime = toBigInt64(command.sampleTime, -1n);\n switch (command.type) {\n case SonareEngineCommandType.SetParam:\n case SonareEngineCommandType.SetParamSmoothed:\n // The sonare-rt C ABI (src/wasm/rt_bindings.cpp) does not export a\n // sonare_rt_engine_set_param entry point, so parameter automation has no\n // realtime transport on this runtime target. Surface a clear error\n // telemetry record (rather than silently dropping the command) so hosts\n // can detect the unsupported path; the embind runtime fully wires this.\n if (this.telemetryRing) {\n writeSonareEngineTelemetryRingBuffer(this.telemetryRing, {\n type: SonareEngineTelemetryType.Error,\n error: SonareEngineTelemetryError.UnknownTarget,\n renderFrame: 0,\n timelineSample: 0,\n audibleTimelineSample: 0,\n graphLatencySamplesQ8: 0,\n value: Number(command.type),\n });\n }\n break;\n case SonareEngineCommandType.TransportPlay:\n this.module._sonare_rt_engine_play(this.engine, sampleTime);\n break;\n case SonareEngineCommandType.TransportStop:\n this.module._sonare_rt_engine_stop(this.engine, sampleTime);\n break;\n case SonareEngineCommandType.TransportSeekSample:\n this.module._sonare_rt_engine_seek_sample(\n this.engine,\n toBigInt64(command.argInt, 0n),\n sampleTime,\n );\n break;\n case SonareEngineCommandType.TransportSeekPpq:\n this.module._sonare_rt_engine_seek_ppq(\n this.engine,\n Number(command.argFloat ?? 0),\n sampleTime,\n );\n break;\n case SonareEngineCommandType.SetTempoMap:\n this.module._sonare_rt_engine_set_tempo(this.engine, Number(command.argFloat ?? 120));\n break;\n case SonareEngineCommandType.SetLoop:\n this.module._sonare_rt_engine_set_loop(\n this.engine,\n Number(command.argFloat ?? 0),\n Number(command.argInt ?? 0) / 1_000_000,\n command.targetId ? 1 : 0,\n );\n break;\n case SonareEngineCommandType.ArmRecord:\n this.module._sonare_rt_engine_set_capture_armed(this.engine, command.argInt ? 1 : 0);\n break;\n case SonareEngineCommandType.Punch:\n // Both endpoints already arrive as samples (see SonareEngine.punch);\n // do NOT re-scale by sampleRate.\n this.module._sonare_rt_engine_set_capture_punch(\n this.engine,\n toBigInt64(command.argInt, 0n),\n BigInt(Math.max(0, Math.round(Number(command.argFloat ?? 0)))),\n 1,\n );\n break;\n case SonareEngineCommandType.SetMetronome:\n this.module._sonare_rt_engine_set_metronome_enabled(\n this.engine,\n command.argInt ? 1 : 0,\n this.metronomeConfig.beatGain,\n this.metronomeConfig.accentGain,\n this.metronomeConfig.clickSamples,\n );\n break;\n case SonareEngineCommandType.SeekMarker:\n this.module._sonare_rt_engine_seek_marker(\n this.engine,\n Math.trunc(command.targetId ?? 0),\n sampleTime,\n );\n break;\n default:\n if (this.telemetryRing) {\n writeSonareEngineTelemetryRingBuffer(this.telemetryRing, {\n type: SonareEngineTelemetryType.Error,\n error: SonareEngineTelemetryError.UnknownTarget,\n renderFrame: 0,\n timelineSample: 0,\n audibleTimelineSample: 0,\n graphLatencySamplesQ8: 0,\n value: Number(command.type),\n });\n }\n break;\n }\n }\n\n private publishTelemetry(): void {\n if (!this.telemetryRing) {\n this.module._sonare_rt_engine_drain_telemetry(\n this.engine,\n this.telemetryIntsPtr,\n this.telemetryFramesPtr,\n 64,\n );\n return;\n }\n const count = this.module._sonare_rt_engine_drain_telemetry(\n this.engine,\n this.telemetryIntsPtr,\n this.telemetryFramesPtr,\n 64,\n );\n const ints = new Int32Array(this.memory.buffer);\n const frames = new Float64Array(this.memory.buffer);\n const intBase = this.telemetryIntsPtr >> 2;\n const frameBase = this.telemetryFramesPtr >> 3;\n for (let i = 0; i < count; i++) {\n writeSonareEngineTelemetryRingBuffer(this.telemetryRing, {\n type: ints[intBase + i * 4],\n error: ints[intBase + i * 4 + 1],\n renderFrame: frames[frameBase + i * 3],\n timelineSample: frames[frameBase + i * 3 + 1],\n audibleTimelineSample: frames[frameBase + i * 3 + 2],\n graphLatencySamplesQ8: ints[intBase + i * 4 + 2],\n value: ints[intBase + i * 4 + 3],\n });\n }\n }\n\n private commandRingFromSharedBuffer(\n sharedBuffer: SharedArrayBuffer,\n fallbackCapacity?: number,\n ): SonareEngineCommandRingBuffer {\n const ring = engineRingFromSharedBuffer(\n sharedBuffer,\n SONARE_ENGINE_COMMAND_RECORD_BYTES,\n fallbackCapacity,\n );\n return { sharedBuffer, header: ring.header, view: ring.view, capacity: ring.capacity };\n }\n\n private telemetryRingFromSharedBuffer(\n sharedBuffer: SharedArrayBuffer,\n fallbackCapacity?: number,\n ): SonareEngineTelemetryRingBuffer {\n const ring = engineRingFromSharedBuffer(\n sharedBuffer,\n SONARE_ENGINE_TELEMETRY_RECORD_BYTES,\n fallbackCapacity,\n );\n return { sharedBuffer, header: ring.header, view: ring.view, capacity: ring.capacity };\n }\n}\n\nexport class SonareRealtimeEngineNode {\n readonly node: AudioWorkletNode;\n readonly capabilities: SonareRealtimeEngineNodeCapabilities;\n readonly commandRing?: SonareEngineCommandRingBuffer;\n readonly telemetryRing?: SonareEngineTelemetryRingBuffer;\n readonly meterRing?: SonareMeterRingBuffer;\n readonly scopeRing?: SonareScopeRingBuffer;\n readonly ready: Promise<void>;\n private telemetryReadIndex = 0;\n private meterReadIndex = 0;\n private scopeReadIndex = 0;\n private telemetryListeners = new Set<(telemetry: SonareEngineTelemetryRecord) => void>();\n private meterListeners = new Set<(meter: SonareWorkletMeterSnapshot) => void>();\n private scopeListeners = new Set<(scope: SonareWorkletScopeSnapshot) => void>();\n private captureRequestId = 1;\n private readonly captureRequests = new Map<\n number,\n {\n resolve: (response: SonareEngineCaptureResponseMessage) => void;\n reject: (reason?: unknown) => void;\n }\n >();\n private transportRequestId = 1;\n private readonly transportRequests = new Map<\n number,\n {\n resolve: (response: SonareEngineTransportResponseMessage) => void;\n reject: (reason?: unknown) => void;\n }\n >();\n private resolveReady!: () => void;\n private rejectReady!: (reason?: unknown) => void;\n private destroyed = false;\n\n private constructor(\n node: AudioWorkletNode,\n capabilities: SonareRealtimeEngineNodeCapabilities,\n commandRing?: SonareEngineCommandRingBuffer,\n telemetryRing?: SonareEngineTelemetryRingBuffer,\n meterRing?: SonareMeterRingBuffer,\n scopeRing?: SonareScopeRingBuffer,\n ) {\n this.node = node;\n this.capabilities = capabilities;\n this.commandRing = commandRing;\n this.telemetryRing = telemetryRing;\n this.meterRing = meterRing;\n this.scopeRing = scopeRing;\n this.ready = new Promise((resolve, reject) => {\n this.resolveReady = resolve;\n this.rejectReady = reject;\n });\n if (!capabilities.readyMessage) {\n this.resolveReady();\n }\n this.node.port.onmessage = (event: MessageEvent<unknown>) => {\n if (isEngineCaptureResponseMessage(event.data)) {\n const pending = this.captureRequests.get(event.data.requestId);\n if (pending) {\n this.captureRequests.delete(event.data.requestId);\n if (event.data.ok) {\n pending.resolve(event.data);\n } else {\n pending.reject(new Error(event.data.error ?? 'Capture request failed'));\n }\n }\n } else if (isEngineTransportResponseMessage(event.data)) {\n const pending = this.transportRequests.get(event.data.requestId);\n if (pending) {\n this.transportRequests.delete(event.data.requestId);\n if (event.data.ok) {\n pending.resolve(event.data);\n } else {\n pending.reject(new Error(event.data.error ?? 'Transport request failed'));\n }\n }\n } else if (isEngineTelemetryRecord(event.data)) {\n this.emitTelemetry(event.data);\n } else if (isMeterSnapshot(event.data)) {\n this.emitMeter(event.data);\n } else if (isRecord(event.data) && event.data.type === 'ready') {\n this.resolveReady();\n } else if (isRecord(event.data) && event.data.type === 'error') {\n this.rejectReady(new Error(String(event.data.message ?? 'AudioWorklet error')));\n }\n };\n }\n\n static async create(\n context: BaseAudioContext,\n options: SonareRealtimeEngineNodeOptions = {},\n ): Promise<SonareRealtimeEngineNode> {\n const runtimeTarget = options.runtimeTarget ?? 'embind';\n const processorName = options.processorName ?? 'sonare-realtime-engine-processor';\n const moduleUrl = options.moduleUrl;\n if (moduleUrl && context.audioWorklet?.addModule) {\n await context.audioWorklet.addModule(moduleUrl);\n }\n const detectedCapabilities =\n options.engineAbiVersion !== undefined\n ? {\n engineAbiVersion: options.engineAbiVersion,\n expectedEngineAbiVersion: options.expectedEngineAbiVersion ?? options.engineAbiVersion,\n abiCompatible:\n options.engineAbiVersion ===\n (options.expectedEngineAbiVersion ?? options.engineAbiVersion),\n }\n : runtimeTarget === 'embind'\n ? engineCapabilities()\n : undefined;\n if (options.requireAbiCompatible !== false && detectedCapabilities?.abiCompatible === false) {\n throw new Error(\n `Engine ABI mismatch: wasm=${detectedCapabilities.engineAbiVersion}, expected=${detectedCapabilities.expectedEngineAbiVersion}`,\n );\n }\n const sharedArrayBuffer = typeof globalThis.SharedArrayBuffer === 'function';\n const atomics = typeof globalThis.Atomics === 'object';\n const audioWorklet = typeof AudioWorkletNode !== 'undefined' || !!options.nodeFactory;\n const degradedReason =\n options.mode !== 'postMessage' && (!sharedArrayBuffer || !atomics)\n ? 'SharedArrayBuffer or Atomics unavailable; using postMessage transport.'\n : undefined;\n const mode =\n options.mode === 'postMessage' || !sharedArrayBuffer || !atomics ? 'postMessage' : 'sab';\n if (options.mode === 'sab' && mode !== 'sab') {\n throw new Error(\n 'SharedArrayBuffer mode requested but SharedArrayBuffer/Atomics are unavailable.',\n );\n }\n\n const commandRing =\n mode === 'sab'\n ? createSonareEngineCommandRingBuffer(options.commandRingCapacity ?? 128)\n : undefined;\n const telemetryRing =\n mode === 'sab'\n ? createSonareEngineTelemetryRingBuffer(options.telemetryRingCapacity ?? 128)\n : undefined;\n // Meter ring: only the embind runtime publishes engine meters into a SAB\n // ring (the sonare-rt runtime owns its own meter transport). Lock-free\n // meter delivery matches the telemetry path and keeps the audio render\n // callback allocation-free in SAB mode.\n const meterRing =\n mode === 'sab' && runtimeTarget === 'embind'\n ? createSonareMeterRingBuffer(options.meterRingCapacity ?? 128)\n : undefined;\n // Scope ring (FFT spectrum + goniometer): opt-in, embind-only. The\n // per-block FFT is heavier than the meter path, so it is created only when\n // the caller requests scope telemetry via scopeIntervalFrames > 0.\n const scopeIntervalFrames = Math.max(0, Math.floor(options.scopeIntervalFrames ?? 0));\n const scopeRing =\n mode === 'sab' && runtimeTarget === 'embind' && scopeIntervalFrames > 0\n ? createSonareScopeRingBuffer(options.scopeRingCapacity ?? 64, options.scopeBands ?? 48)\n : undefined;\n const channelCount = Math.max(1, Math.floor(options.channelCount ?? 2));\n const processorOptions: SonareRealtimeEngineWorkletProcessorOptions = {\n runtimeTarget,\n rtModuleUrl: options.rtModuleUrl,\n rtWasmBinary: options.rtWasmBinary,\n sampleRate: options.sampleRate ?? context.sampleRate,\n blockSize: options.blockSize,\n channelCount,\n commandSharedBuffer: commandRing?.sharedBuffer,\n commandRingCapacity: commandRing?.capacity,\n telemetrySharedBuffer: telemetryRing?.sharedBuffer,\n telemetryRingCapacity: telemetryRing?.capacity,\n meterSharedBuffer: meterRing?.sharedBuffer,\n meterRingCapacity: meterRing?.capacity,\n scopeSharedBuffer: scopeRing?.sharedBuffer,\n scopeRingCapacity: scopeRing?.capacity,\n scopeBands: scopeRing?.bands,\n scopeIntervalFrames: scopeRing ? scopeIntervalFrames : undefined,\n wasmBinary: options.wasmBinary,\n initialSyncMessages: options.initialSyncMessages,\n initialCommands: options.initialCommands,\n };\n const factory =\n options.nodeFactory ??\n ((ctx: BaseAudioContext, name: string, nodeOptions: AudioWorkletNodeOptions) =>\n new AudioWorkletNode(ctx, name, nodeOptions));\n const node = factory(context, processorName, {\n numberOfInputs: 1,\n numberOfOutputs: 1,\n outputChannelCount: [channelCount],\n processorOptions,\n });\n return new SonareRealtimeEngineNode(\n node,\n {\n mode,\n runtimeTarget,\n sharedArrayBuffer,\n atomics,\n audioWorklet,\n engineAbiVersion: detectedCapabilities?.engineAbiVersion,\n expectedEngineAbiVersion: detectedCapabilities?.expectedEngineAbiVersion,\n abiCompatible: detectedCapabilities?.abiCompatible,\n degradedReason,\n readyMessage:\n runtimeTarget === 'sonare-rt' ||\n (runtimeTarget === 'embind' && moduleUrl !== undefined && !options.nodeFactory),\n },\n commandRing,\n telemetryRing,\n meterRing,\n scopeRing,\n );\n }\n\n play(sampleTime = -1): boolean {\n return this.sendCommand({ type: SonareEngineCommandType.TransportPlay, sampleTime });\n }\n\n stop(sampleTime = -1): boolean {\n return this.sendCommand({ type: SonareEngineCommandType.TransportStop, sampleTime });\n }\n\n seekSample(timelineSample: number, sampleTime = -1): boolean {\n return this.sendCommand({\n type: SonareEngineCommandType.TransportSeekSample,\n sampleTime,\n argInt: timelineSample,\n });\n }\n\n seekPpq(ppq: number, sampleTime = -1): boolean {\n return this.sendCommand({\n type: SonareEngineCommandType.TransportSeekPpq,\n sampleTime,\n argFloat: ppq,\n });\n }\n\n sendCommand(command: SonareEngineCommandRecord): boolean {\n if (this.destroyed) {\n return false;\n }\n if (this.commandRing) {\n return pushSonareEngineCommandRingBuffer(this.commandRing, command);\n }\n this.node.port.postMessage(command);\n return true;\n }\n\n requestCaptureStatus(): Promise<EngineCaptureStatus> {\n return this.sendCaptureRequest('status').then((response) => {\n if (!response.status) {\n throw new Error('Capture status response is missing status.');\n }\n return response.status;\n });\n }\n\n requestCapturedAudio(): Promise<Float32Array[]> {\n return this.sendCaptureRequest('read').then((response) =>\n (response.channels ?? []).map((channel) =>\n channel instanceof Float32Array ? channel : new Float32Array(channel),\n ),\n );\n }\n\n requestCaptureReset(): Promise<void> {\n return this.sendCaptureRequest('reset').then(() => undefined);\n }\n\n requestTransportState(): Promise<EngineTransportState> {\n return this.sendTransportRequest().then((response) => {\n if (!response.state) {\n throw new Error('Transport state response is missing state.');\n }\n return response.state;\n });\n }\n\n pollTelemetry(): SonareEngineTelemetryRecord[] {\n if (!this.telemetryRing) {\n return [];\n }\n const read = readSonareEngineTelemetryRingBuffer(this.telemetryRing, this.telemetryReadIndex);\n this.telemetryReadIndex = read.nextReadIndex;\n for (const telemetry of read.telemetry) {\n this.emitTelemetry(telemetry);\n }\n return read.telemetry;\n }\n\n // Drains any meters published into the SAB meter ring (embind SAB mode) and\n // forwards them to onMeter listeners. In postMessage mode meters arrive via\n // node.port.onmessage instead, so this is a no-op then.\n pollMeters(): SonareWorkletMeterSnapshot[] {\n if (!this.meterRing) {\n return [];\n }\n const read = readSonareMeterRingBuffer(this.meterRing, this.meterReadIndex);\n this.meterReadIndex = read.nextReadIndex;\n for (const meter of read.meters) {\n this.emitMeter(meter);\n }\n return read.meters;\n }\n\n // Drains scope telemetry (FFT spectrum + goniometer points) published into the\n // SAB scope ring and forwards each record to onScope listeners. A no-op unless\n // the node was created with scopeIntervalFrames > 0 (embind SAB mode).\n pollScope(): SonareWorkletScopeSnapshot[] {\n if (!this.scopeRing) {\n return [];\n }\n const read = readSonareScopeRingBuffer(this.scopeRing, this.scopeReadIndex);\n this.scopeReadIndex = read.nextReadIndex;\n for (const scope of read.scopes) {\n this.emitScope(scope);\n }\n return read.scopes;\n }\n\n onTelemetry(callback: (telemetry: SonareEngineTelemetryRecord) => void): () => void {\n this.telemetryListeners.add(callback);\n return () => {\n this.telemetryListeners.delete(callback);\n };\n }\n\n onMeter(callback: (meter: SonareWorkletMeterSnapshot) => void): () => void {\n this.meterListeners.add(callback);\n return () => {\n this.meterListeners.delete(callback);\n };\n }\n\n onScope(callback: (scope: SonareWorkletScopeSnapshot) => void): () => void {\n this.scopeListeners.add(callback);\n return () => {\n this.scopeListeners.delete(callback);\n };\n }\n\n destroy(): void {\n if (this.destroyed) {\n return;\n }\n this.destroyed = true;\n this.node.port.postMessage({ type: SonareEngineCommandType.TransportStop, sampleTime: -1 });\n this.node.disconnect();\n for (const pending of this.captureRequests.values()) {\n pending.reject(new Error('Realtime engine node is destroyed.'));\n }\n this.captureRequests.clear();\n for (const pending of this.transportRequests.values()) {\n pending.reject(new Error('Realtime engine node is destroyed.'));\n }\n this.transportRequests.clear();\n this.telemetryListeners.clear();\n this.meterListeners.clear();\n this.scopeListeners.clear();\n }\n\n private emitTelemetry(telemetry: SonareEngineTelemetryRecord): void {\n for (const listener of this.telemetryListeners) {\n listener(telemetry);\n }\n }\n\n private emitMeter(meter: SonareWorkletMeterSnapshot): void {\n for (const listener of this.meterListeners) {\n listener(meter);\n }\n }\n\n private emitScope(scope: SonareWorkletScopeSnapshot): void {\n for (const listener of this.scopeListeners) {\n listener(scope);\n }\n }\n\n private sendCaptureRequest(\n op: SonareEngineCaptureRequestMessage['op'],\n ): Promise<SonareEngineCaptureResponseMessage> {\n if (this.destroyed) {\n return Promise.reject(new Error('Realtime engine node is destroyed.'));\n }\n const requestId = this.captureRequestId++;\n const promise = new Promise<SonareEngineCaptureResponseMessage>((resolve, reject) => {\n this.captureRequests.set(requestId, { resolve, reject });\n });\n this.node.port.postMessage({ type: 'captureRequest', requestId, op });\n return promise;\n }\n\n private sendTransportRequest(): Promise<SonareEngineTransportResponseMessage> {\n if (this.destroyed) {\n return Promise.reject(new Error('Realtime engine node is destroyed.'));\n }\n const requestId = this.transportRequestId++;\n const promise = new Promise<SonareEngineTransportResponseMessage>((resolve, reject) => {\n this.transportRequests.set(requestId, { resolve, reject });\n });\n this.node.port.postMessage({ type: 'transportRequest', requestId, op: 'state' });\n return promise;\n }\n}\n\nexport class SonareEngine {\n readonly node: AudioWorkletNode;\n readonly capabilities: SonareRealtimeEngineNodeCapabilities;\n readonly transport: SonareEngineTransportFacade;\n private readonly realtimeNode: SonareRealtimeEngineNode;\n private readonly offlineEngine: RealtimeEngine;\n private readonly context: SuspendableAudioContext;\n private readonly sampleRate: number;\n private readonly offlineBlockSize: number;\n private readonly offlineChannelCount: number;\n private readonly automationLanes = new Map<number, EngineAutomationPoint[]>();\n private readonly clips = new Map<number, EngineClip>();\n private readonly midiClips = new Map<number, EngineMidiClipSchedule>();\n private readonly markers = new Map<number, EngineMarker>();\n private readonly trackLaneIds: number[] = [];\n private readonly trackSends = new Map<number, EngineTrackSend[]>();\n private readonly trackOutputBus = new Map<number, number>();\n private readonly laneSidechains = new Map<\n string,\n { trackId: number; insertIndex: number; sourceTrackId: number }\n >();\n private readonly buses: EngineBus[] = [];\n private readonly trackStripJson = new Map<number, string>();\n private readonly busStripJson = new Map<number, string>();\n private masterStripJson: string | undefined;\n private captureConfig: Omit<SonareEngineSyncCaptureMessage, 'type'> | undefined;\n private tempoBpm = 120;\n private timeSignature = { numerator: 4, denominator: 4 };\n private tempoSegments: EngineTempoSegment[] = [{ startPpq: 0, bpm: 120 }];\n private timeSignatureSegments: EngineTimeSignatureSegment[] = [\n { startPpq: 0, numerator: 4, denominator: 4 },\n ];\n private latestTransportState: EngineTransportState | undefined;\n private nextClipId = 1;\n private nextMarkerId = 1;\n private transportPlaying = false;\n private readonly pendingInstrumentSync: SonareEngineInstrumentSyncMessage[] = [];\n private destroyed = false;\n\n private constructor(\n context: BaseAudioContext,\n realtimeNode: SonareRealtimeEngineNode,\n offlineEngine: RealtimeEngine,\n sampleRate: number,\n offlineBlockSize: number,\n offlineChannelCount: number,\n ) {\n this.context = context;\n this.realtimeNode = realtimeNode;\n this.offlineEngine = offlineEngine;\n this.node = realtimeNode.node;\n this.capabilities = realtimeNode.capabilities;\n this.sampleRate = sampleRate;\n this.offlineBlockSize = offlineBlockSize;\n this.offlineChannelCount = offlineChannelCount;\n this.transport = {\n play: (sampleTime = -1) => {\n const ok = this.realtimeNode.play(sampleTime);\n if (ok) {\n this.transportPlaying = true;\n }\n return ok;\n },\n stop: (sampleTime = -1) => {\n const ok = this.realtimeNode.stop(sampleTime);\n if (ok) {\n this.transportPlaying = false;\n this.flushPendingInstrumentSync();\n }\n return ok;\n },\n seekPpq: (ppq, sampleTime = -1) => {\n this.offlineEngine.seekPpq(ppq, sampleTime);\n return this.realtimeNode.seekPpq(ppq, sampleTime);\n },\n seekSeconds: (seconds, sampleTime = -1) => {\n const timelineSample = Math.max(0, Math.round(seconds * this.sampleRate));\n this.offlineEngine.seekSample(timelineSample, sampleTime);\n return this.realtimeNode.seekSample(timelineSample, sampleTime);\n },\n setTempo: (bpm) => this.setTempo(bpm),\n setTempoSegments: (segments) => this.setTempoSegments(segments),\n setLoop: (startPpq, endPpq, enabled = true) => this.setLoop(startPpq, endPpq, enabled),\n };\n }\n\n static async create(\n context: BaseAudioContext,\n options: SonareEngineOptions = {},\n ): Promise<SonareEngine> {\n const sampleRate = options.sampleRate ?? context.sampleRate;\n const blockSize = options.offlineBlockSize ?? options.blockSize ?? 128;\n const channelCount = Math.max(\n 1,\n Math.floor(options.offlineChannelCount ?? options.channelCount ?? 2),\n );\n const realtimeNode = await SonareRealtimeEngineNode.create(context, options);\n const offlineEngine = options.offlineEngine ?? new RealtimeEngine(sampleRate, blockSize);\n return new SonareEngine(\n context,\n realtimeNode,\n offlineEngine,\n sampleRate,\n blockSize,\n channelCount,\n );\n }\n\n async suspend(): Promise<void> {\n if (this.destroyed) {\n return;\n }\n await this.context.suspend?.();\n }\n\n async resume(): Promise<void> {\n if (this.destroyed) {\n return;\n }\n await this.context.resume?.();\n }\n\n setTempo(bpm: number): void {\n this.tempoBpm = bpm;\n this.tempoSegments = [{ startPpq: 0, bpm }];\n this.offlineEngine.setTempo(bpm);\n this.postTempoSync();\n this.realtimeNode.sendCommand({\n type: SonareEngineCommandType.SetTempoMap,\n sampleTime: -1,\n argFloat: bpm,\n });\n }\n\n setTempoSegments(segments: readonly EngineTempoSegment[]): void {\n this.tempoSegments = segments.map((segment) => ({ ...segment }));\n this.tempoBpm = this.tempoSegments[0]?.bpm ?? this.tempoBpm;\n this.offlineEngine.setTempoSegments(this.tempoSegments);\n this.postTempoSync();\n }\n\n setTimeSignature(numerator: number, denominator: number): void {\n this.timeSignature = { numerator, denominator };\n this.timeSignatureSegments = [{ startPpq: 0, numerator, denominator }];\n this.offlineEngine.setTimeSignature(numerator, denominator);\n this.postTempoSync();\n }\n\n setTimeSignatureSegments(segments: readonly EngineTimeSignatureSegment[]): void {\n this.timeSignatureSegments = segments.map((segment) => ({ ...segment }));\n const first = this.timeSignatureSegments[0];\n if (first) {\n this.timeSignature = { numerator: first.numerator, denominator: first.denominator };\n }\n this.offlineEngine.setTimeSignatureSegments(this.timeSignatureSegments);\n this.postTempoSync();\n }\n\n setLoop(startPpq: number, endPpq: number, enabled = true): boolean {\n this.offlineEngine.setLoop(startPpq, endPpq, enabled);\n // Transport precision contract: the SAB command record carries exactly one\n // Float64 lane (argFloat) and one Int64 lane (argInt). startPpq travels in\n // argFloat with full double precision, matching the offline engine; endPpq\n // is carried as micro-PPQ (round(endPpq * 1e6)) in the integer lane and\n // divided back by 1e6 on the consumer. Loop ENDS are therefore snapped to\n // the nearest 1e-6 PPQ over the realtime transport (max 5e-7 PPQ drift),\n // while loop STARTS and the offline path stay exact. This is intentional:\n // the record has no second free Float64 lane, and a micro-PPQ grid on the\n // loop end is well below audible/sample-accurate resolution at any tempo.\n return this.realtimeNode.sendCommand({\n type: SonareEngineCommandType.SetLoop,\n targetId: enabled ? 1 : 0,\n sampleTime: -1,\n argFloat: startPpq,\n argInt: Math.round(endPpq * 1_000_000),\n });\n }\n\n countInEndSample(startSample: number, bars: number): number {\n return this.offlineEngine.countInEndSample(startSample, bars);\n }\n\n async getTransportState(): Promise<EngineTransportState> {\n const state = await this.realtimeNode.requestTransportState();\n this.latestTransportState = state;\n return state;\n }\n\n cachedTransportState(): EngineTransportState | undefined {\n return this.latestTransportState;\n }\n\n setParam(nodeId: string, param: string | number, value: number): boolean {\n const paramId = this.resolveParamId(nodeId, param);\n // Mirror the change into the offline engine so a subsequent offline render\n // reflects the live value, then push a sample-accurate command to the\n // realtime runtime (mirrors setTempo/setLoop above).\n this.offlineEngine.setParameter(paramId, value);\n return this.realtimeNode.sendCommand({\n type: SonareEngineCommandType.SetParam,\n targetId: paramId,\n sampleTime: -1,\n argFloat: value,\n });\n }\n\n scheduleParam(\n nodeId: string,\n param: string | number,\n ppq: number,\n value: number,\n curve: number | 'linear' | 'exponential' = 'linear',\n ): void {\n const paramId = this.resolveParamId(nodeId, param);\n const lane = this.automationLanes.get(paramId) ?? [];\n lane.push({ ppq, value, curveToNext: this.curveCode(curve) });\n lane.sort((a, b) => a.ppq - b.ppq);\n this.automationLanes.set(paramId, lane);\n this.offlineEngine.setAutomationLane(paramId, lane);\n // Mirror the lane to the live worklet engine so scheduled automation plays\n // back in real time, not just in renderOffline(). Lanes can exceed the\n // fixed-size SAB command record, so they ride an out-of-band 'syncAutomation'\n // message applied outside process() (like syncClips/syncMarkers).\n this.postSync({ type: 'syncAutomation', paramId, points: lane });\n }\n\n addAutomationPoint(\n laneId: string | number,\n ppq: number,\n value: number,\n curve: number | 'linear' | 'exponential' = 'linear',\n ): void {\n this.scheduleParam('', laneId, ppq, value, curve);\n }\n\n /**\n * Replaces the automation lane for `paramId` with the given breakpoints.\n *\n * Unlike scheduleParam (which appends a single point), this sets the whole\n * lane at once; an empty array clears the lane. The points are defensively\n * copied and sorted by ppq before being mirrored to the offline engine and\n * the live worklet engine.\n *\n * @param paramId Automation target id (registered parameter or a reserved\n * engine mixer target from automationParamId/busAutomationParamId).\n * @param points Lane breakpoints; order does not matter.\n */\n setAutomationLane(paramId: number, points: ReadonlyArray<EngineAutomationPoint>): void {\n const sorted = points.map((point) => ({ ...point })).sort((a, b) => a.ppq - b.ppq);\n if (sorted.length === 0) {\n this.automationLanes.delete(paramId);\n } else {\n this.automationLanes.set(paramId, sorted);\n }\n this.offlineEngine.setAutomationLane(paramId, sorted);\n this.postSync({ type: 'syncAutomation', paramId, points: sorted });\n }\n\n /**\n * Returns the automation target id for a mixer strip parameter.\n *\n * The id addresses the engine's reserved mixer namespace, so it can be fed\n * straight to setAutomationLane to automate a fader or pan without\n * registering a parameter.\n *\n * @param target Track id (declares a mixer lane on first use) or 'master'.\n * @param kind Strip parameter to address.\n * @returns Reserved engine parameter id for the strip parameter.\n */\n automationParamId(target: string | number, kind: 'faderDb' | 'pan'): number {\n const paramKind = kind === 'pan' ? ENGINE_MIXER_PARAM_PAN : ENGINE_MIXER_PARAM_FADER_DB;\n if (target === 'master') {\n return engineMixerMasterTarget(paramKind);\n }\n return engineMixerLaneTarget(this.ensureTrackLane(target), paramKind);\n }\n\n /**\n * Returns the automation target id for a bus fader.\n *\n * @param busId Bus id (declares the mixer bus on first use).\n * @returns Reserved engine parameter id for the bus fader gain (dB).\n */\n busAutomationParamId(busId: number): number {\n return engineMixerBusTarget(this.ensureBus(busId), ENGINE_MIXER_PARAM_FADER_DB);\n }\n\n /**\n * Returns the number of automation lanes installed on the engine, including\n * lanes whose breakpoint list is currently empty.\n *\n * @returns Engine-side automation lane count.\n */\n automationLaneCount(): number {\n return this.offlineEngine.automationLaneCount();\n }\n\n listParameters(): EngineParameterInfo[] {\n const parameters: EngineParameterInfo[] = [];\n for (let index = 0; index < this.offlineEngine.parameterCount(); index++) {\n parameters.push(this.offlineEngine.parameterInfoByIndex(index));\n }\n return parameters;\n }\n\n setSoloMute(target: string | number, solo: boolean, mute: boolean): boolean {\n const laneIndex = this.ensureTrackLane(target);\n this.offlineEngine.setSoloMute(laneIndex, solo, mute);\n return this.realtimeNode.sendCommand({\n type: SonareEngineCommandType.SetSoloMute,\n targetId: laneIndex,\n sampleTime: -1,\n argInt: (mute ? 0x1 : 0) | (solo ? 0x2 : 0),\n });\n }\n\n setStripGain(target: string | number, db: number): boolean {\n if (target === 'master') {\n const paramId = engineMixerMasterTarget(ENGINE_MIXER_PARAM_FADER_DB);\n this.offlineEngine.setParameter(paramId, db);\n return this.realtimeNode.sendCommand({\n type: SonareEngineCommandType.SetParamSmoothed,\n targetId: paramId,\n sampleTime: -1,\n argFloat: db,\n });\n }\n const laneIndex = this.ensureTrackLane(target);\n const paramId = engineMixerLaneTarget(laneIndex, ENGINE_MIXER_PARAM_FADER_DB);\n this.offlineEngine.setParameter(paramId, db);\n return this.realtimeNode.sendCommand({\n type: SonareEngineCommandType.SetParamSmoothed,\n targetId: paramId,\n sampleTime: -1,\n argFloat: db,\n });\n }\n\n setStripPan(target: string | number, pan: number): boolean {\n if (target === 'master') {\n const paramId = engineMixerMasterTarget(ENGINE_MIXER_PARAM_PAN);\n this.offlineEngine.setParameter(paramId, pan);\n return this.realtimeNode.sendCommand({\n type: SonareEngineCommandType.SetParamSmoothed,\n targetId: paramId,\n sampleTime: -1,\n argFloat: pan,\n });\n }\n const laneIndex = this.ensureTrackLane(target);\n const paramId = engineMixerLaneTarget(laneIndex, ENGINE_MIXER_PARAM_PAN);\n this.offlineEngine.setParameter(paramId, pan);\n return this.realtimeNode.sendCommand({\n type: SonareEngineCommandType.SetParamSmoothed,\n targetId: paramId,\n sampleTime: -1,\n argFloat: pan,\n });\n }\n\n /**\n * Declares the mixer track lanes in an explicit order.\n *\n * Lane indices are append-only: once a track id occupies a lane, its index\n * stays fixed for the engine's lifetime. The given list must therefore start\n * with the already-declared lane ids in their current order and may only\n * append new track ids after them. Entries carrying `sends` replace that\n * track's send list; entries without `sends` leave existing sends untouched.\n *\n * @param lanes Track ids or lane descriptors in the desired lane order.\n */\n setTrackLanes(lanes: ReadonlyArray<number | EngineTrackLane>): void {\n const entries = lanes.map((lane) => (typeof lane === 'number' ? { trackId: lane } : lane));\n const ids: number[] = [];\n for (const entry of entries) {\n if (!Number.isInteger(entry.trackId) || entry.trackId <= 0) {\n throw new Error(`Invalid track id for mixer lane: ${String(entry.trackId)}`);\n }\n ids.push(entry.trackId);\n }\n if (new Set(ids).size !== ids.length) {\n throw new Error('Duplicate track id in mixer lane list');\n }\n for (let index = 0; index < this.trackLaneIds.length; index++) {\n if (ids[index] !== this.trackLaneIds[index]) {\n throw new Error(\n 'Mixer lanes are append-only: keep existing lanes in order and only append new track ids',\n );\n }\n }\n for (const entry of entries) {\n if (entry.sends) {\n this.trackSends.set(\n entry.trackId,\n entry.sends.map((send) => ({ ...send })),\n );\n }\n if (entry.outputBusId !== undefined) {\n if (entry.outputBusId === 0) {\n this.trackOutputBus.delete(entry.trackId);\n } else {\n this.trackOutputBus.set(entry.trackId, entry.outputBusId);\n }\n }\n }\n this.trackLaneIds.splice(0, this.trackLaneIds.length, ...ids);\n this.syncMixer();\n }\n\n /**\n * Routes a track lane's post-fader output into a declared bus instead of\n * the master mix (group/folder routing); busId 0 restores the master mix.\n */\n setTrackOutputBus(target: string | number, busId: number): void {\n const laneIndex = this.ensureTrackLane(target);\n const trackId = this.trackLaneIds[laneIndex];\n if (busId === 0) {\n this.trackOutputBus.delete(trackId);\n } else {\n this.trackOutputBus.set(trackId, busId);\n }\n this.syncMixer();\n }\n\n /**\n * Keys one insert of a lane strip from another lane's post-strip pre-fader\n * audio (ducking/sidechainRouter inserts). sourceTarget null removes the\n * binding.\n */\n setLaneSidechain(\n target: string | number,\n insertIndex: number,\n sourceTarget: string | number | null,\n ): void {\n const laneIndex = this.ensureTrackLane(target);\n const trackId = this.trackLaneIds[laneIndex];\n const key = `${trackId}:${insertIndex}`;\n let sourceTrackId = 0;\n if (sourceTarget !== null) {\n const sourceIndex = this.ensureTrackLane(sourceTarget);\n sourceTrackId = this.trackLaneIds[sourceIndex];\n }\n if (sourceTrackId === 0) {\n this.laneSidechains.delete(key);\n } else {\n this.laneSidechains.set(key, { trackId, insertIndex, sourceTrackId });\n }\n this.offlineEngine.setLaneSidechain(trackId, insertIndex, sourceTrackId);\n this.postSync({\n type: 'syncMixer',\n lanes: this.mixerLanes(),\n laneSidechains: [{ trackId, insertIndex, sourceTrackId }],\n });\n }\n\n setSends(target: string | number, sends: EngineTrackSend[]): void {\n const laneIndex = this.ensureTrackLane(target);\n const trackId = this.trackLaneIds[laneIndex];\n this.trackSends.set(\n trackId,\n sends.map((send) => ({ ...send })),\n );\n this.syncMixer();\n }\n\n setTrackBuses(buses: EngineBus[]): void {\n this.buses.splice(0, this.buses.length, ...buses.map((bus) => ({ ...bus })));\n this.syncMixer();\n }\n\n setBusGain(busId: number, db: number): boolean {\n const busIndex = this.ensureBus(busId);\n this.buses[busIndex] = { ...this.buses[busIndex], busId, gainDb: db };\n this.offlineEngine.setTrackBuses(this.buses);\n const paramId = engineMixerBusTarget(busIndex, ENGINE_MIXER_PARAM_FADER_DB);\n this.offlineEngine.setParameter(paramId, db);\n return this.realtimeNode.sendCommand({\n type: SonareEngineCommandType.SetParamSmoothed,\n targetId: paramId,\n sampleTime: -1,\n argFloat: db,\n });\n }\n\n setTrackStripJson(target: string | number, sceneJson: string): void {\n const laneIndex = this.ensureTrackLane(target);\n const trackId = this.trackLaneIds[laneIndex];\n this.offlineEngine.setTrackStripJson(trackId, sceneJson);\n this.trackStripJson.set(trackId, sceneJson);\n this.syncMixer();\n }\n\n setTrackStripEqBand(target: string | number, bandIndex: number, band: EqBand | string): void {\n const laneIndex = this.ensureTrackLane(target);\n const trackId = this.trackLaneIds[laneIndex];\n const bandJson = typeof band === 'string' ? band : JSON.stringify(band);\n this.offlineEngine.setTrackStripEqBandJson(trackId, bandIndex, bandJson);\n this.postSync({ type: 'syncTrackStripEqBand', trackId, bandIndex, bandJson });\n }\n\n setTrackStripInsertBypassed(\n target: string | number,\n insertIndex: number,\n bypassed: boolean,\n resetOnBypass = false,\n ): void {\n const laneIndex = this.ensureTrackLane(target);\n const trackId = this.trackLaneIds[laneIndex];\n this.offlineEngine.setTrackStripInsertBypassed(trackId, insertIndex, bypassed, resetOnBypass);\n this.postSync({\n type: 'syncTrackStripInsertBypassed',\n trackId,\n insertIndex,\n bypassed,\n resetOnBypass,\n });\n }\n\n setTrackStripInsertParamByName(\n target: string | number,\n insertIndex: number,\n paramName: string,\n value: number,\n ): void {\n const laneIndex = this.ensureTrackLane(target);\n const trackId = this.trackLaneIds[laneIndex];\n this.offlineEngine.setTrackStripInsertParamByName(trackId, insertIndex, paramName, value);\n this.postSync({\n type: 'syncTrackStripInsertParamByName',\n trackId,\n insertIndex,\n paramName,\n value,\n });\n }\n\n setTrackStripPan(target: string | number, pan: number): void {\n const trackId = this.trackLaneIds[this.ensureTrackLane(target)];\n this.offlineEngine.setTrackStripPan(trackId, pan);\n this.postSync({ type: 'syncTrackStripPan', trackId, pan });\n }\n\n setTrackStripPanLaw(target: string | number, panLaw: PanLaw | number): void {\n const trackId = this.trackLaneIds[this.ensureTrackLane(target)];\n const code = panLawCode(panLaw);\n this.offlineEngine.setTrackStripPanLaw(trackId, code);\n this.postSync({ type: 'syncTrackStripPanLaw', trackId, panLaw: code });\n }\n\n setTrackStripPanMode(target: string | number, panMode: PanMode | number): void {\n const trackId = this.trackLaneIds[this.ensureTrackLane(target)];\n const code = panModeCode(panMode);\n this.offlineEngine.setTrackStripPanMode(trackId, code);\n this.postSync({ type: 'syncTrackStripPanMode', trackId, panMode: code });\n }\n\n setTrackStripDualPan(target: string | number, leftPan: number, rightPan: number): void {\n const trackId = this.trackLaneIds[this.ensureTrackLane(target)];\n this.offlineEngine.setTrackStripDualPan(trackId, leftPan, rightPan);\n this.postSync({ type: 'syncTrackStripDualPan', trackId, leftPan, rightPan });\n }\n\n setTrackStripChannelDelaySamples(target: string | number, delaySamples: number): void {\n const trackId = this.trackLaneIds[this.ensureTrackLane(target)];\n this.offlineEngine.setTrackStripChannelDelaySamples(trackId, delaySamples);\n this.postSync({ type: 'syncTrackStripChannelDelaySamples', trackId, delaySamples });\n }\n\n setStripEq(target: string | number, bandIndex: number, band: EqBand | string): void {\n if (target === 'master') {\n this.setMasterStripEqBand(bandIndex, band);\n return;\n }\n this.setTrackStripEqBand(target, bandIndex, band);\n }\n\n setStripInsertBypassed(\n target: string | number,\n insertIndex: number,\n bypassed: boolean,\n resetOnBypass = false,\n ): void {\n if (target === 'master') {\n this.setMasterStripInsertBypassed(insertIndex, bypassed, resetOnBypass);\n return;\n }\n this.setTrackStripInsertBypassed(target, insertIndex, bypassed, resetOnBypass);\n }\n\n setStripInserts(target: string | number, sceneJson: string): void {\n if (target === 'master') {\n this.setMasterStripJson(sceneJson);\n return;\n }\n this.setTrackStripJson(target, sceneJson);\n }\n\n setBusStripJson(busId: number, sceneJson: string): void {\n this.ensureBus(busId);\n this.offlineEngine.setBusStripJson(busId, sceneJson);\n this.busStripJson.set(busId, sceneJson);\n this.syncMixer();\n }\n\n setMasterStripJson(sceneJson: string): void {\n this.offlineEngine.setMasterStripJson(sceneJson);\n this.masterStripJson = sceneJson;\n this.syncMixer();\n }\n\n setMasterStripEqBand(bandIndex: number, band: EqBand | string): void {\n const bandJson = typeof band === 'string' ? band : JSON.stringify(band);\n this.offlineEngine.setMasterStripEqBandJson(bandIndex, bandJson);\n this.postSync({ type: 'syncMasterStripEqBand', bandIndex, bandJson });\n }\n\n setMasterStripInsertBypassed(\n insertIndex: number,\n bypassed: boolean,\n resetOnBypass = false,\n ): void {\n this.offlineEngine.setMasterStripInsertBypassed(insertIndex, bypassed, resetOnBypass);\n this.postSync({\n type: 'syncMasterStripInsertBypassed',\n insertIndex,\n bypassed,\n resetOnBypass,\n });\n }\n\n setMasterStripInsertParamByName(insertIndex: number, paramName: string, value: number): void {\n this.offlineEngine.setMasterStripInsertParamByName(insertIndex, paramName, value);\n this.postSync({\n type: 'syncMasterStripInsertParamByName',\n insertIndex,\n paramName,\n value,\n });\n }\n\n setStripInsertParamByName(\n target: string | number,\n insertIndex: number,\n paramName: string,\n value: number,\n ): void {\n if (target === 'master') {\n this.setMasterStripInsertParamByName(insertIndex, paramName, value);\n return;\n }\n this.setTrackStripInsertParamByName(target, insertIndex, paramName, value);\n }\n\n setMasterChain(sceneJson: string): void {\n this.setMasterStripJson(sceneJson);\n }\n\n addClip(\n trackId: string | number,\n buffer: Float32Array[],\n startPpq: number,\n opts: Partial<Omit<EngineClip, 'channels' | 'startPpq'>> = {},\n ): number {\n const id = opts.id ?? this.nextClipId++;\n const clip: EngineClip = {\n ...opts,\n id,\n channels: buffer,\n startPpq,\n trackId: this.resolveTargetId(trackId),\n };\n this.ensureTrackLane(trackId);\n this.clips.set(id, clip);\n this.syncClipsDelta([clip], []);\n return id;\n }\n\n removeClip(clipId: number): void {\n this.clips.delete(clipId);\n this.syncClipsDelta([], [clipId]);\n }\n\n setMidiClips(clips: readonly EngineMidiClipSchedule[]): void {\n this.midiClips.clear();\n for (const clip of clips) {\n const id = clip.id ?? this.nextClipId++;\n this.midiClips.set(id, { ...clip, id, events: clip.events.map((event) => ({ ...event })) });\n }\n this.syncMidiClips();\n }\n\n setBuiltinInstrument(\n trackId: string | number,\n config: { destinationId?: number } & Record<string, unknown> = {},\n ): void {\n const destinationId = this.resolveTargetId(trackId);\n this.offlineEngine.setBuiltinInstrument(config, destinationId);\n this.postInstrumentSync({ type: 'syncBuiltinInstrument', destinationId, config });\n }\n\n setSynthInstrument(trackId: string | number, patch: Record<string, unknown> | string = {}): void {\n const destinationId = this.resolveTargetId(trackId);\n this.offlineEngine.setSynthInstrument(patch, destinationId);\n this.postInstrumentSync({ type: 'syncSynthInstrument', destinationId, patch });\n }\n\n loadSoundFont(data: Uint8Array): void {\n this.offlineEngine.loadSoundFont(data);\n this.postInstrumentSync({ type: 'syncLoadSoundFont', data });\n }\n\n setSf2Instrument(\n trackId: string | number,\n config: { destinationId?: number; gain?: number; polyphony?: number } = {},\n ): void {\n const destinationId = this.resolveTargetId(trackId);\n this.offlineEngine.setSf2Instrument(config, destinationId);\n this.postInstrumentSync({ type: 'syncSf2Instrument', destinationId, config });\n }\n\n pushMidiNoteOn(\n trackId: string | number,\n group: number,\n channel: number,\n note: number,\n velocity: number,\n renderFrame = -1,\n ): void {\n const destinationId = this.resolveTargetId(trackId);\n this.offlineEngine.pushMidiNoteOn(destinationId, group, channel, note, velocity, renderFrame);\n this.postSync({\n type: 'syncMidiNoteOn',\n destinationId,\n group,\n channel,\n note,\n velocity,\n renderFrame,\n });\n }\n\n pushMidiNoteOff(\n trackId: string | number,\n group: number,\n channel: number,\n note: number,\n velocity = 0,\n renderFrame = -1,\n ): void {\n const destinationId = this.resolveTargetId(trackId);\n this.offlineEngine.pushMidiNoteOff(destinationId, group, channel, note, velocity, renderFrame);\n this.postSync({\n type: 'syncMidiNoteOff',\n destinationId,\n group,\n channel,\n note,\n velocity,\n renderFrame,\n });\n }\n\n pushMidiCc(\n trackId: string | number,\n group: number,\n channel: number,\n controller: number,\n value: number,\n renderFrame = -1,\n ): void {\n const destinationId = this.resolveTargetId(trackId);\n this.offlineEngine.pushMidiCc(destinationId, group, channel, controller, value, renderFrame);\n this.postSync({\n type: 'syncMidiCc',\n destinationId,\n group,\n channel,\n controller,\n value,\n renderFrame,\n });\n }\n\n pushMidiPanic(renderFrame = -1): void {\n this.offlineEngine.pushMidiPanic(renderFrame);\n this.postSync({ type: 'syncMidiPanic', renderFrame });\n }\n\n configureCapture(options: {\n bufferFrames: number;\n channels?: number;\n source?: EngineCaptureStatus['source'];\n recordOffsetSamples?: number;\n inputMonitor?: { enabled: boolean; gain?: number };\n }): void {\n const bufferFrames = Math.trunc(options.bufferFrames);\n const channels = Math.trunc(options.channels ?? this.offlineChannelCount);\n const source = options.source ?? 'output';\n const recordOffsetSamples = Math.trunc(options.recordOffsetSamples ?? 0);\n const inputMonitor = {\n enabled: Boolean(options.inputMonitor?.enabled),\n gain: options.inputMonitor?.gain ?? 1,\n };\n this.offlineEngine.setCaptureBuffer(channels, bufferFrames);\n this.offlineEngine.setCaptureSource(source);\n this.offlineEngine.setRecordOffsetSamples(recordOffsetSamples);\n this.offlineEngine.setInputMonitor(inputMonitor.enabled, inputMonitor.gain);\n this.captureConfig = { bufferFrames, channels, source, recordOffsetSamples, inputMonitor };\n this.postSync({ type: 'syncCapture', ...this.captureConfig });\n }\n\n armRecord(trackId: string | number, enabled: boolean): boolean {\n if (enabled && !this.captureConfig) {\n throw new Error('Capture buffer is not configured');\n }\n this.offlineEngine.armCapture(enabled);\n return this.realtimeNode.sendCommand({\n type: SonareEngineCommandType.ArmRecord,\n targetId: this.resolveTargetId(trackId),\n sampleTime: -1,\n argInt: enabled ? 1 : 0,\n });\n }\n\n punch(inPpq: number, outPpq: number): boolean {\n const inSample = this.offlineEngine.sampleAtPpq(inPpq);\n const outSample = this.offlineEngine.sampleAtPpq(outPpq);\n this.offlineEngine.setCapturePunch(inSample, outSample, true);\n // Carry BOTH endpoints as already-converted SAMPLES so the realtime engine\n // agrees with the offline engine. The previous code sent the raw PPQ out\n // point and let the consumer multiply by sampleRate (treating PPQ as\n // seconds), which ignored tempo and produced a punch-out ~2x too large at\n // 120 BPM. argInt = in sample, argFloat = out sample (full-precision double).\n return this.realtimeNode.sendCommand({\n type: SonareEngineCommandType.Punch,\n sampleTime: -1,\n argInt: inSample,\n argFloat: outSample,\n });\n }\n\n captureStatus(): Promise<EngineCaptureStatus> {\n return this.realtimeNode.requestCaptureStatus();\n }\n\n capturedAudio(): Promise<Float32Array[]> {\n return this.realtimeNode.requestCapturedAudio();\n }\n\n async resetCapture(): Promise<void> {\n this.offlineEngine.resetCapture();\n await this.realtimeNode.requestCaptureReset();\n }\n\n setMetronome(opts: EngineMetronomeConfig): void {\n this.offlineEngine.setMetronome(opts);\n // The full config (beatGain/accentGain/clickSamples/clickSeconds) cannot fit\n // the fixed-size SAB command record, so it is delivered out-of-band; the\n // SetMetronome command then toggles enabled state on the audio thread.\n this.postSync({ type: 'syncMetronome', config: opts });\n this.realtimeNode.sendCommand({\n type: SonareEngineCommandType.SetMetronome,\n sampleTime: -1,\n argInt: opts.enabled ? 1 : 0,\n });\n }\n\n addMarker(ppq: number, name = ''): number {\n const id = this.nextMarkerId++;\n this.markers.set(id, { id, ppq, name });\n this.syncMarkers();\n return id;\n }\n\n /**\n * Replaces the whole marker set in one call.\n *\n * Entries without an `id` are assigned fresh ids; entries carrying an `id`\n * keep it (ids must be positive and unique within the list). Returns the\n * resolved markers in the order given, so a caller can map its own marker\n * identities to the engine ids used by `seekMarker`/`setLoopFromMarkers`.\n *\n * @param markers The full marker list (an empty list clears all markers).\n * @returns The markers with their resolved engine ids.\n */\n setMarkers(markers: ReadonlyArray<{ ppq: number; name?: string; id?: number }>): EngineMarker[] {\n const resolved: EngineMarker[] = [];\n const seen = new Set<number>();\n for (const marker of markers) {\n if (!Number.isFinite(marker.ppq)) {\n throw new Error(`Invalid marker ppq: ${String(marker.ppq)}`);\n }\n if (marker.id !== undefined) {\n if (!Number.isInteger(marker.id) || marker.id <= 0) {\n throw new Error(`Invalid marker id: ${String(marker.id)}`);\n }\n if (seen.has(marker.id)) {\n throw new Error(`Duplicate marker id: ${marker.id}`);\n }\n }\n const id = marker.id ?? this.nextMarkerId++;\n seen.add(id);\n if (id >= this.nextMarkerId) {\n this.nextMarkerId = id + 1;\n }\n resolved.push({ id, ppq: marker.ppq, name: marker.name ?? '' });\n }\n this.markers.clear();\n for (const marker of resolved) {\n this.markers.set(marker.id, marker);\n }\n this.syncMarkers();\n return resolved.map((marker) => ({ ...marker }));\n }\n\n markerCount(): number {\n return this.offlineEngine.markerCount();\n }\n\n markerByIndex(index: number): EngineMarker {\n return this.offlineEngine.markerByIndex(index);\n }\n\n marker(markerId: number): EngineMarker {\n return this.offlineEngine.marker(markerId);\n }\n\n seekMarker(markerId: number): boolean {\n this.offlineEngine.seekMarker(markerId);\n // Forward to the live worklet engine. Its marker set is kept in sync via the\n // 'syncMarkers' message (see syncMarkers), so a queued kSeekMarker resolves\n // the marker id to its frame on the audio thread. Returns the sendCommand\n // result (previously this method always returned a misleading `false`).\n return this.realtimeNode.sendCommand({\n type: SonareEngineCommandType.SeekMarker,\n targetId: markerId,\n sampleTime: -1,\n });\n }\n\n setLoopFromMarkers(startMarkerId: number, endMarkerId: number): boolean {\n this.offlineEngine.setLoopFromMarkers(startMarkerId, endMarkerId);\n const start = this.offlineEngine.marker(startMarkerId);\n const end = this.offlineEngine.marker(endMarkerId);\n return this.setLoop(start.ppq, end.ppq, true);\n }\n\n async renderOffline(totalFrames: number): Promise<Float32Array[]> {\n const frames = Math.max(0, Math.floor(totalFrames));\n const inputs: Float32Array[] = [];\n for (let ch = 0; ch < this.offlineChannelCount; ch++) {\n inputs.push(new Float32Array(frames));\n }\n return this.offlineEngine.renderOffline(inputs, this.offlineBlockSize);\n }\n\n onMeter(callback: (meter: SonareWorkletMeterSnapshot) => void): () => void {\n return this.realtimeNode.onMeter(callback);\n }\n\n onScope(callback: (scope: SonareWorkletScopeSnapshot) => void): () => void {\n return this.realtimeNode.onScope(callback);\n }\n\n onTelemetry(callback: (telemetry: SonareEngineTelemetryRecord) => void): () => void {\n return this.realtimeNode.onTelemetry(callback);\n }\n\n pollTelemetry(): SonareEngineTelemetryRecord[] {\n return this.realtimeNode.pollTelemetry();\n }\n\n pollMeters(): SonareWorkletMeterSnapshot[] {\n return this.realtimeNode.pollMeters();\n }\n\n pollScope(): SonareWorkletScopeSnapshot[] {\n return this.realtimeNode.pollScope();\n }\n\n destroy(): void {\n if (this.destroyed) {\n return;\n }\n this.destroyed = true;\n this.transport.stop();\n this.realtimeNode.pollTelemetry();\n this.realtimeNode.destroy();\n this.offlineEngine.destroy();\n }\n\n private syncClipsDelta(upserts: EngineClip[], removeIds: number[]): void {\n const clips = Array.from(this.clips.values());\n this.offlineEngine.setClips(clips);\n this.postSync({\n type: 'syncClipsDelta',\n upserts,\n removeIds,\n });\n }\n\n private syncMidiClips(): void {\n const clips = Array.from(this.midiClips.values());\n this.offlineEngine.setMidiClips(clips);\n this.postSync({ type: 'syncMidiClips', clips });\n }\n\n private mixerLanes(): EngineTrackLane[] {\n return this.trackLaneIds.map((trackId) => {\n const sends = this.trackSends.get(trackId);\n const outputBusId = this.trackOutputBus.get(trackId);\n return {\n trackId,\n ...(sends && sends.length > 0 ? { sends: sends.map((send) => ({ ...send })) } : {}),\n ...(outputBusId !== undefined ? { outputBusId } : {}),\n };\n });\n }\n\n private syncMixer(): void {\n const lanes = this.mixerLanes();\n const buses = this.buses.map((bus) => ({ ...bus }));\n this.offlineEngine.setTrackBuses(buses);\n if (lanes.length > 0) {\n this.offlineEngine.setTrackLanes(lanes);\n }\n const trackStrips = Array.from(this.trackStripJson, ([trackId, sceneJson]) => ({\n trackId,\n sceneJson,\n }));\n const busStrips = Array.from(this.busStripJson, ([busId, sceneJson]) => ({\n busId,\n sceneJson,\n }));\n this.postSync({\n type: 'syncMixer',\n lanes,\n buses,\n trackStrips,\n laneSidechains: Array.from(this.laneSidechains.values()),\n busStrips,\n masterStripJson: this.masterStripJson,\n });\n }\n\n private syncMarkers(): void {\n const markers = Array.from(this.markers.values()).sort((a, b) => a.ppq - b.ppq);\n this.offlineEngine.setMarkers(markers);\n this.postSync({ type: 'syncMarkers', markers });\n }\n\n private postInstrumentSync(message: SonareEngineInstrumentSyncMessage): void {\n if (this.destroyed) {\n return;\n }\n if (this.transportPlaying) {\n this.pendingInstrumentSync.push(message);\n return;\n }\n this.postSync(message);\n }\n\n private flushPendingInstrumentSync(): void {\n if (this.destroyed || this.pendingInstrumentSync.length === 0) {\n return;\n }\n const pending = this.pendingInstrumentSync.splice(0);\n for (const message of pending) {\n this.postSync(message);\n }\n }\n\n private postTempoSync(): void {\n this.postSync({\n type: 'syncTempo',\n bpm: this.tempoBpm,\n timeSignature: { ...this.timeSignature },\n tempoSegments: this.tempoSegments.map((segment) => ({ ...segment })),\n timeSignatureSegments: this.timeSignatureSegments.map((segment) => ({ ...segment })),\n });\n }\n\n // Posts an out-of-band control-sync message to the worklet engine processor.\n // Sync messages use a string `type` so the worklet's message handler routes\n // them to receiveSync() (numeric `type` is reserved for SonareEngineCommandRecord).\n private postSync(message: SonareEngineSyncMessage): void {\n if (this.destroyed) {\n return;\n }\n this.realtimeNode.node.port.postMessage(message);\n }\n\n private resolveParamId(nodeId: string, param: string | number): number {\n if (typeof param === 'number') {\n return param;\n }\n const byName = this.listParameters().find((info) => info.name === param);\n if (byName) {\n return byName.id;\n }\n return this.resolveTargetId(param || nodeId);\n }\n\n private resolveTargetId(target: string | number): number {\n if (typeof target === 'number') {\n return target;\n }\n const parsed = Number.parseInt(target, 10);\n return Number.isFinite(parsed) ? parsed : 0;\n }\n\n private ensureTrackLane(target: string | number): number {\n const trackId = this.resolveTargetId(target);\n if (!Number.isInteger(trackId) || trackId <= 0) {\n throw new Error(`Invalid track id for mixer lane: ${String(target)}`);\n }\n const existing = this.trackLaneIds.indexOf(trackId);\n if (existing >= 0) {\n return existing;\n }\n this.trackLaneIds.push(trackId);\n this.syncMixer();\n return this.trackLaneIds.length - 1;\n }\n\n private ensureBus(busId: number): number {\n const resolved = Math.trunc(busId);\n if (!Number.isInteger(resolved) || resolved <= 0) {\n throw new Error(`Invalid bus id for mixer bus: ${String(busId)}`);\n }\n const existing = this.buses.findIndex((bus) => bus.busId === resolved);\n if (existing >= 0) {\n return existing;\n }\n this.buses.push({ busId: resolved });\n this.syncMixer();\n return this.buses.length - 1;\n }\n\n private curveCode(curve: number | 'linear' | 'exponential'): number {\n if (typeof curve === 'number') {\n return curve;\n }\n return curve === 'exponential' ? 1 : 0;\n }\n}\n\nexport class SonareRealtimeVoiceChangerWorkletProcessor {\n private static warnedMonoOverflow = false;\n private static warnedInterleavedOverflow = false;\n private changer: RealtimeVoiceChanger;\n private readonly sampleRate: number;\n private readonly blockSize: number;\n private readonly channelCount: number;\n // WASM-heap typed-memory views, sized to the worst case (blockSize *\n // channelCount). Acquired on the main thread (constructor) so the\n // audio-thread process() never crosses an allocation boundary.\n private monoInput: Float32Array;\n private monoOutput: Float32Array;\n // Planar heap-backed views (one Float32Array per channel) used by the\n // multi-channel path. AudioWorklet inputs/outputs are already planar\n // Float32Arrays, so this avoids the per-sample interleave/deinterleave\n // passes that the older interleaved path needed.\n private planarChannels: Float32Array[];\n private destroyed = false;\n\n constructor(options: SonareRealtimeVoiceChangerWorkletProcessorOptions = {}) {\n this.sampleRate = options.sampleRate ?? 48000;\n this.blockSize = options.blockSize ?? 128;\n this.channelCount = Math.max(1, Math.floor(options.channelCount ?? 1));\n this.changer = new RealtimeVoiceChanger(options.preset ?? 'neutral-monitor');\n this.changer.prepare(this.sampleRate, this.blockSize, this.channelCount);\n // Acquire WASM-heap views once, sized to the worst case. These are alive\n // for the lifetime of the changer; if the host requests more frames per\n // process() than blockSize, we clamp (see ensure*Capacity).\n this.monoInput = this.changer.getMonoInputBuffer(this.blockSize);\n this.monoOutput = this.changer.getMonoOutputBuffer(this.blockSize);\n this.planarChannels = [];\n if (this.channelCount > 1) {\n for (let ch = 0; ch < this.channelCount; ch++) {\n this.planarChannels.push(this.changer.getPlanarChannelBuffer(ch, this.blockSize));\n }\n }\n }\n\n /**\n * Handles a control-plane message from the main thread. Runs on the\n * AudioWorklet global scope but OUTSIDE of `process()` (i.e. outside the\n * realtime audio callback), so it is safe to perform JSON parsing and\n * DSP coefficient recomputation here. `setConfig` MUST NOT be deferred\n * into `process()` because that would block the audio thread for longer\n * than one render quantum (e.g. 128 samples / 44.1 kHz = ~2.9 ms).\n */\n receiveMessage(message: SonareRealtimeVoiceChangerMessage): void {\n if (this.destroyed) {\n return;\n }\n if (message.type === 'setConfig') {\n // Apply synchronously on the message-handler thread. `setConfig` may\n // allocate and parse JSON internally; doing it here keeps `process()`\n // realtime-safe.\n this.changer.setConfig(message.preset);\n } else if (message.type === 'reset') {\n this.changer.reset();\n } else if (message.type === 'destroy') {\n this.destroy();\n }\n }\n\n process(inputs: WorkletInput, outputs: WorkletOutput): boolean {\n const output = outputs[0];\n if (this.destroyed || !output || output.length === 0) {\n return !this.destroyed;\n }\n\n // The cached heap views can detach if WASM linear memory grows (the embind\n // module is built ALLOW_MEMORY_GROWTH). Re-acquire them if detached\n // (byteLength === 0) before touching them; in the common no-growth case this\n // is a cheap branch with no allocation.\n if (this.monoInput.byteLength === 0) {\n this.reacquireBuffers();\n }\n\n const input = inputs[0];\n const requestedFrames = output[0]?.length ?? 0;\n const requestedChannels = Math.min(this.channelCount, output.length);\n if (requestedFrames === 0 || requestedChannels === 0) {\n return true;\n }\n\n if (requestedChannels === 1) {\n // Clamp to the pre-allocated capacity; warn (once) if the host violated\n // the contract. We never reallocate on the audio thread.\n const frames = this.ensureMonoCapacity(requestedFrames);\n const source = input?.[0];\n if (source) {\n this.monoInput.set(source.subarray(0, frames));\n } else {\n this.monoInput.fill(0, 0, frames);\n }\n this.changer.processMonoInto(\n this.monoInput.subarray(0, frames),\n this.monoOutput.subarray(0, frames),\n );\n output[0].set(this.monoOutput.subarray(0, frames));\n return true;\n }\n\n const frames = this.ensureInterleavedCapacity(requestedFrames, requestedChannels);\n const channels = requestedChannels;\n // Planar zero-copy path: AudioWorklet's input[ch] is already a\n // Float32Array per channel, so we set() straight into the heap-backed\n // planar view and processPreparedPlanar runs in place.\n for (let ch = 0; ch < channels; ch++) {\n const src = input?.[ch];\n const dst = this.planarChannels[ch];\n if (!dst) {\n continue;\n }\n if (src) {\n dst.set(src.subarray(0, frames));\n } else {\n dst.fill(0, 0, frames);\n }\n }\n this.changer.processPreparedPlanar(frames);\n for (let ch = 0; ch < channels; ch++) {\n const src = this.planarChannels[ch];\n if (src) {\n output[ch].set(src.subarray(0, frames));\n }\n // No `for frame` inner loop needed; output[ch] is a Float32Array.\n }\n return true;\n }\n\n destroy(): void {\n if (this.destroyed) {\n return;\n }\n this.destroyed = true;\n this.changer.delete();\n }\n\n // Re-acquires the cached WASM-heap views after a memory-growth detachment.\n // The underlying C++ vectors are pre-warmed (ensure_*_capacity ran at prepare\n // time), so getMono*/getPlanar* return fresh views onto the SAME storage\n // without reallocating it.\n private reacquireBuffers(): void {\n this.monoInput = this.changer.getMonoInputBuffer(this.blockSize);\n this.monoOutput = this.changer.getMonoOutputBuffer(this.blockSize);\n if (this.channelCount > 1) {\n for (let ch = 0; ch < this.channelCount; ch++) {\n this.planarChannels[ch] = this.changer.getPlanarChannelBuffer(ch, this.blockSize);\n }\n }\n }\n\n /**\n * Returns the number of frames we can actually process given the\n * pre-allocated capacity. If the host requests more frames than the\n * worst-case block size declared at construction time, we clamp to the\n * available capacity and warn once — we MUST NOT reallocate on the\n * realtime audio thread.\n */\n private ensureMonoCapacity(frames: number): number {\n const capacity = this.monoInput.length;\n if (frames <= capacity) {\n return frames;\n }\n if (!SonareRealtimeVoiceChangerWorkletProcessor.warnedMonoOverflow) {\n SonareRealtimeVoiceChangerWorkletProcessor.warnedMonoOverflow = true;\n // biome-ignore lint/suspicious/noConsole: realtime-safety diagnostic.\n console.warn(\n `SonareRealtimeVoiceChangerWorkletProcessor: requested ${frames} mono frames ` +\n `exceeds pre-allocated capacity ${capacity}; clamping. ` +\n 'Increase blockSize at construction time to avoid this.',\n );\n }\n return capacity;\n }\n\n /**\n * Same contract as ensureMonoCapacity but for the planar per-channel\n * scratch. Returns the number of frames that fit in the available capacity.\n */\n private ensureInterleavedCapacity(frames: number, channels: number): number {\n const capacity = this.planarChannels[0]?.length ?? 0;\n if (frames <= capacity) {\n return frames;\n }\n if (!SonareRealtimeVoiceChangerWorkletProcessor.warnedInterleavedOverflow) {\n SonareRealtimeVoiceChangerWorkletProcessor.warnedInterleavedOverflow = true;\n // biome-ignore lint/suspicious/noConsole: realtime-safety diagnostic.\n console.warn(\n `SonareRealtimeVoiceChangerWorkletProcessor: requested ${frames}x${channels} ` +\n `planar frames exceeds pre-allocated capacity ${capacity}; clamping. ` +\n 'Increase blockSize or channelCount at construction time to avoid this.',\n );\n }\n return capacity;\n }\n}\n\nexport function registerSonareWorkletProcessor(name = 'sonare-worklet-processor'): void {\n const scope = globalThis as unknown as {\n AudioWorkletProcessor?: new () => object;\n registerProcessor?: (processorName: string, processorCtor: unknown) => void;\n };\n if (!scope.AudioWorkletProcessor || !scope.registerProcessor) {\n throw new Error('AudioWorkletProcessor is not available in this context.');\n }\n const Base = scope.AudioWorkletProcessor;\n class RegisteredSonareWorkletProcessor extends Base {\n private bridge: SonareWorkletProcessor;\n readonly port?: WorkletPort;\n\n constructor(options?: { processorOptions?: SonareWorkletProcessorOptions }) {\n super();\n const port = this.port;\n this.bridge = new SonareWorkletProcessor(options?.processorOptions ?? { sceneJson: '' }, {\n postMessage: (message) => port?.postMessage?.(message),\n });\n const onMessage = (event: { data: unknown }) => {\n if (isWorkletMessage(event.data)) {\n this.bridge.receiveMessage(event.data);\n }\n };\n if (port?.addEventListener) {\n port.addEventListener('message', onMessage);\n port.start?.();\n } else if (port) {\n port.onmessage = onMessage;\n }\n }\n\n process(inputs: WorkletInput, outputs: WorkletOutput): boolean {\n return this.bridge.process(inputs, outputs);\n }\n }\n scope.registerProcessor(name, RegisteredSonareWorkletProcessor);\n}\n\nexport function registerSonareRealtimeVoiceChangerWorkletProcessor(\n name = 'sonare-realtime-voice-changer-processor',\n): void {\n const scope = globalThis as unknown as {\n AudioWorkletProcessor?: new () => object;\n registerProcessor?: (processorName: string, processorCtor: unknown) => void;\n };\n if (!scope.AudioWorkletProcessor || !scope.registerProcessor) {\n throw new Error('AudioWorkletProcessor is not available in this context.');\n }\n const Base = scope.AudioWorkletProcessor;\n class RegisteredSonareRealtimeVoiceChangerWorkletProcessor extends Base {\n private bridge: SonareRealtimeVoiceChangerWorkletProcessor;\n readonly port?: WorkletPort;\n\n constructor(options?: {\n processorOptions?: SonareRealtimeVoiceChangerWorkletProcessorOptions;\n }) {\n super();\n const port = this.port;\n this.bridge = new SonareRealtimeVoiceChangerWorkletProcessor(options?.processorOptions ?? {});\n const onMessage = (event: { data: unknown }) => {\n if (isRealtimeVoiceChangerMessage(event.data)) {\n this.bridge.receiveMessage(event.data);\n }\n };\n if (port?.addEventListener) {\n port.addEventListener('message', onMessage);\n port.start?.();\n } else if (port) {\n port.onmessage = onMessage;\n }\n }\n\n process(inputs: WorkletInput, outputs: WorkletOutput): boolean {\n return this.bridge.process(inputs, outputs);\n }\n }\n scope.registerProcessor(name, RegisteredSonareRealtimeVoiceChangerWorkletProcessor);\n}\n\nexport function registerSonareRealtimeEngineWorkletProcessor(\n name = 'sonare-realtime-engine-processor',\n): void {\n const scope = globalThis as unknown as {\n AudioWorkletProcessor?: new () => object;\n registerProcessor?: (processorName: string, processorCtor: unknown) => void;\n };\n if (!scope.AudioWorkletProcessor || !scope.registerProcessor) {\n throw new Error('AudioWorkletProcessor is not available in this context.');\n }\n const Base = scope.AudioWorkletProcessor;\n class RegisteredSonareRealtimeEngineWorkletProcessor extends Base {\n private bridge?: SonareRealtimeEngineWorkletProcessor;\n private rtBridge?: SonareRtRealtimeEngineRuntime;\n private readonly pendingMessages: unknown[] = [];\n readonly port?: WorkletPort;\n\n constructor(options?: { processorOptions?: SonareRealtimeEngineWorkletProcessorOptions }) {\n super();\n const port = this.port;\n const processorOptions = options?.processorOptions ?? {};\n if (processorOptions.runtimeTarget === 'sonare-rt') {\n void this.initializeSonareRt(processorOptions, port);\n } else {\n void this.initializeEmbind(processorOptions, port);\n }\n const onMessage = (event: { data: unknown }) => {\n if (!this.bridge && !this.rtBridge) {\n if (this.pendingMessages.length < 1024) {\n this.pendingMessages.push(event.data);\n }\n return;\n }\n if (isEngineCommandRecord(event.data)) {\n this.bridge?.receiveCommand(event.data);\n this.rtBridge?.receiveCommand(event.data);\n } else if (isEngineSyncMessage(event.data)) {\n this.bridge?.receiveSync(event.data);\n this.rtBridge?.receiveSync(event.data);\n } else if (isEngineCaptureRequestMessage(event.data)) {\n this.bridge?.receiveCaptureRequest(event.data);\n this.rtBridge?.receiveCaptureRequest(event.data, port);\n } else if (isEngineTransportRequestMessage(event.data)) {\n this.bridge?.receiveTransportRequest(event.data);\n this.rtBridge?.receiveTransportRequest(event.data, port);\n }\n };\n if (port?.addEventListener) {\n port.addEventListener('message', onMessage);\n port.start?.();\n } else if (port) {\n port.onmessage = onMessage;\n }\n }\n\n process(inputs: WorkletInput, outputs: WorkletOutput): boolean {\n if (this.rtBridge) {\n return this.rtBridge.process(inputs, outputs);\n }\n if (this.bridge) {\n return this.bridge.process(inputs, outputs);\n }\n const output = outputs[0];\n for (const channel of output ?? []) {\n channel.fill(0);\n }\n return true;\n }\n\n private replayPendingMessages(port?: WorkletPort): void {\n const messages = this.pendingMessages.splice(0);\n for (const data of messages) {\n if (isEngineCommandRecord(data)) {\n this.bridge?.receiveCommand(data);\n this.rtBridge?.receiveCommand(data);\n } else if (isEngineSyncMessage(data)) {\n this.bridge?.receiveSync(data);\n this.rtBridge?.receiveSync(data);\n } else if (isEngineCaptureRequestMessage(data)) {\n this.bridge?.receiveCaptureRequest(data);\n this.rtBridge?.receiveCaptureRequest(data, port);\n } else if (isEngineTransportRequestMessage(data)) {\n this.bridge?.receiveTransportRequest(data);\n this.rtBridge?.receiveTransportRequest(data, port);\n }\n }\n }\n\n private async initializeEmbind(\n options: SonareRealtimeEngineWorkletProcessorOptions,\n port?: WorkletPort,\n ): Promise<void> {\n try {\n const initPromise = (\n globalThis as typeof globalThis & { SonareEmbindInitPromise?: Promise<void> }\n ).SonareEmbindInitPromise;\n if (initPromise) {\n await initPromise;\n }\n if (!isInitialized()) {\n type EmbindModuleFactory = (options?: {\n locateFile?: (path: string, prefix: string) => string;\n wasmBinary?: ArrayBuffer | Uint8Array;\n }) => Promise<SonareModule>;\n const moduleFactory = (\n globalThis as typeof globalThis & {\n SonareEmbindModuleFactory?: EmbindModuleFactory;\n }\n ).SonareEmbindModuleFactory;\n if (!moduleFactory) {\n throw new Error('embind realtime engine module is not initialized.');\n }\n await initSonareModule({\n locateFile: (path) => path,\n wasmBinary: options.wasmBinary,\n moduleFactory,\n });\n }\n this.bridge = new SonareRealtimeEngineWorkletProcessor(options, {\n postMessage: (message) => port?.postMessage?.(message),\n onMeter: (meter) => port?.postMessage?.(meter),\n });\n for (const message of options.initialSyncMessages ?? []) {\n this.bridge.receiveSync(message);\n }\n for (const command of options.initialCommands ?? []) {\n this.bridge.receiveCommand(command);\n }\n this.replayPendingMessages(port);\n port?.postMessage?.({ type: 'ready', runtimeTarget: 'embind' });\n } catch (error) {\n port?.postMessage?.({\n type: 'error',\n message: error instanceof Error ? error.message : String(error),\n });\n }\n }\n\n private async initializeSonareRt(\n options: SonareRealtimeEngineWorkletProcessorOptions,\n port?: WorkletPort,\n ): Promise<void> {\n try {\n if (!options.rtModuleUrl) {\n throw new Error('rtModuleUrl is required for sonare-rt AudioWorklet runtime.');\n }\n const rtModuleUrl = options.rtModuleUrl;\n const memory = new WebAssembly.Memory({ initial: 1024, maximum: 1024, shared: true });\n const globalFactory = (\n globalThis as typeof globalThis & {\n SonareRtModuleFactory?: (options?: {\n wasmMemory?: WebAssembly.Memory;\n wasmBinary?: ArrayBuffer | Uint8Array;\n locateFile?: (path: string) => string;\n }) => Promise<SonareRtModule>;\n }\n ).SonareRtModuleFactory;\n const moduleFactory = globalFactory\n ? { default: globalFactory }\n : ((await import(rtModuleUrl)) as {\n default: (options?: {\n wasmMemory?: WebAssembly.Memory;\n wasmBinary?: ArrayBuffer | Uint8Array;\n locateFile?: (path: string) => string;\n }) => Promise<SonareRtModule>;\n });\n const module = await moduleFactory.default({\n wasmMemory: memory,\n wasmBinary: options.rtWasmBinary,\n locateFile: (path) => rtModuleUrl.replace(/[^/]*$/, path),\n });\n this.rtBridge = new SonareRtRealtimeEngineRuntime({\n module,\n memory,\n sampleRate: options.sampleRate,\n blockSize: options.blockSize,\n channelCount: options.channelCount,\n commandSharedBuffer: options.commandSharedBuffer,\n commandRingCapacity: options.commandRingCapacity,\n telemetrySharedBuffer: options.telemetrySharedBuffer,\n telemetryRingCapacity: options.telemetryRingCapacity,\n });\n this.replayPendingMessages(port);\n port?.postMessage?.({ type: 'ready', runtimeTarget: 'sonare-rt' });\n } catch (error) {\n port?.postMessage?.({\n type: 'error',\n message: error instanceof Error ? error.message : String(error),\n });\n }\n }\n }\n scope.registerProcessor(name, RegisteredSonareRealtimeEngineWorkletProcessor);\n}\n"],"mappings":"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","names":["module","module","module","module","SonareEngineCommandType","SonareEngineTelemetryType","SonareEngineTelemetryError","paramId","frames","initPromise","module"]}