@jpdutoit/squelchy 0.0.2 → 0.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -3
- package/{chunk-NDUSYSHF.js → chunk-MEZE4P3U.js} +5 -5
- package/chunk-MEZE4P3U.js.map +7 -0
- package/docs/GUIDE.md +29 -7
- package/docs/MODULES.md +6 -6
- package/docs/modules.json +10 -10
- package/index.d.ts +7 -241
- package/index.js +68 -260
- package/index.js.map +4 -4
- package/kits/compu-78/bd.flac +0 -0
- package/kits/compu-78/ch.flac +0 -0
- package/kits/compu-78/clap.flac +0 -0
- package/kits/compu-78/cym.flac +0 -0
- package/kits/compu-78/ht.flac +0 -0
- package/kits/compu-78/lt.flac +0 -0
- package/kits/compu-78/mt.flac +0 -0
- package/kits/compu-78/oh.flac +0 -0
- package/kits/compu-78/perc.flac +0 -0
- package/kits/compu-78/rim.flac +0 -0
- package/kits/compu-78/sd.flac +0 -0
- package/kits/compu-78.d.ts +7 -0
- package/kits/compu-78.js +22 -0
- package/kits/deep-analogue/bd.flac +0 -0
- package/kits/deep-analogue/ch.flac +0 -0
- package/kits/deep-analogue/clap.flac +0 -0
- package/kits/deep-analogue/cym.flac +0 -0
- package/kits/deep-analogue/ht.flac +0 -0
- package/kits/deep-analogue/lt.flac +0 -0
- package/kits/deep-analogue/mt.flac +0 -0
- package/kits/deep-analogue/oh.flac +0 -0
- package/kits/deep-analogue/perc.flac +0 -0
- package/kits/deep-analogue/rim.flac +0 -0
- package/kits/deep-analogue/sd.flac +0 -0
- package/kits/deep-analogue.d.ts +7 -0
- package/kits/deep-analogue.js +22 -0
- package/kits/dr5-studio/bd.flac +0 -0
- package/kits/dr5-studio/ch.flac +0 -0
- package/kits/dr5-studio/clap.flac +0 -0
- package/kits/dr5-studio/cym.flac +0 -0
- package/kits/dr5-studio/ht.flac +0 -0
- package/kits/dr5-studio/lt.flac +0 -0
- package/kits/dr5-studio/mt.flac +0 -0
- package/kits/dr5-studio/oh.flac +0 -0
- package/kits/dr5-studio/perc.flac +0 -0
- package/kits/dr5-studio/rim.flac +0 -0
- package/kits/dr5-studio/sd.flac +0 -0
- package/kits/dr5-studio.d.ts +7 -0
- package/kits/dr5-studio.js +22 -0
- package/kits/hard-cell/bd.flac +0 -0
- package/kits/hard-cell/ch.flac +0 -0
- package/kits/hard-cell/clap.flac +0 -0
- package/kits/hard-cell/cym.flac +0 -0
- package/kits/hard-cell/ht.flac +0 -0
- package/kits/hard-cell/lt.flac +0 -0
- package/kits/hard-cell/mt.flac +0 -0
- package/kits/hard-cell/oh.flac +0 -0
- package/kits/hard-cell/perc.flac +0 -0
- package/kits/hard-cell/rim.flac +0 -0
- package/kits/hard-cell/sd.flac +0 -0
- package/kits/hard-cell.d.ts +7 -0
- package/kits/hard-cell.js +22 -0
- package/kits/micro-click/bd.flac +0 -0
- package/kits/micro-click/ch.flac +0 -0
- package/kits/micro-click/clap.flac +0 -0
- package/kits/micro-click/cym.flac +0 -0
- package/kits/micro-click/ht.flac +0 -0
- package/kits/micro-click/lt.flac +0 -0
- package/kits/micro-click/mt.flac +0 -0
- package/kits/micro-click/oh.flac +0 -0
- package/kits/micro-click/perc.flac +0 -0
- package/kits/micro-click/rim.flac +0 -0
- package/kits/micro-click/sd.flac +0 -0
- package/kits/micro-click.d.ts +7 -0
- package/kits/micro-click.js +22 -0
- package/kits/roland-808/bd.flac +0 -0
- package/kits/roland-808/ch.flac +0 -0
- package/kits/roland-808/clap.flac +0 -0
- package/kits/roland-808/cym.flac +0 -0
- package/kits/roland-808/ht.flac +0 -0
- package/kits/roland-808/lt.flac +0 -0
- package/kits/roland-808/mt.flac +0 -0
- package/kits/roland-808/oh.flac +0 -0
- package/kits/roland-808/perc.flac +0 -0
- package/kits/roland-808/rim.flac +0 -0
- package/kits/roland-808/sd.flac +0 -0
- package/kits/roland-808.d.ts +7 -0
- package/kits/roland-808.js +22 -0
- package/kits/rx5-fm/bd.flac +0 -0
- package/kits/rx5-fm/ch.flac +0 -0
- package/kits/rx5-fm/clap.flac +0 -0
- package/kits/rx5-fm/cym.flac +0 -0
- package/kits/rx5-fm/ht.flac +0 -0
- package/kits/rx5-fm/lt.flac +0 -0
- package/kits/rx5-fm/mt.flac +0 -0
- package/kits/rx5-fm/oh.flac +0 -0
- package/kits/rx5-fm/perc.flac +0 -0
- package/kits/rx5-fm/rim.flac +0 -0
- package/kits/rx5-fm/sd.flac +0 -0
- package/kits/rx5-fm.d.ts +7 -0
- package/kits/rx5-fm.js +22 -0
- package/kits/tape-dust/bd.flac +0 -0
- package/kits/tape-dust/ch.flac +0 -0
- package/kits/tape-dust/clap.flac +0 -0
- package/kits/tape-dust/cym.flac +0 -0
- package/kits/tape-dust/ht.flac +0 -0
- package/kits/tape-dust/lt.flac +0 -0
- package/kits/tape-dust/mt.flac +0 -0
- package/kits/tape-dust/oh.flac +0 -0
- package/kits/tape-dust/perc.flac +0 -0
- package/kits/tape-dust/rim.flac +0 -0
- package/kits/tape-dust/sd.flac +0 -0
- package/kits/tape-dust.d.ts +7 -0
- package/kits/tape-dust.js +22 -0
- package/kits/tr-606/bd.flac +0 -0
- package/kits/tr-606/ch.flac +0 -0
- package/kits/tr-606/cym.flac +0 -0
- package/kits/tr-606/ht.flac +0 -0
- package/kits/tr-606/lt.flac +0 -0
- package/kits/tr-606/mt.flac +0 -0
- package/kits/tr-606/oh.flac +0 -0
- package/kits/tr-606/sd.flac +0 -0
- package/kits/tr-606.d.ts +7 -0
- package/kits/tr-606.js +19 -0
- package/kits/tr-707/bd.flac +0 -0
- package/kits/tr-707/ch.flac +0 -0
- package/kits/tr-707/clap.flac +0 -0
- package/kits/tr-707/cym.flac +0 -0
- package/kits/tr-707/ht.flac +0 -0
- package/kits/tr-707/lt.flac +0 -0
- package/kits/tr-707/mt.flac +0 -0
- package/kits/tr-707/oh.flac +0 -0
- package/kits/tr-707/perc.flac +0 -0
- package/kits/tr-707/rim.flac +0 -0
- package/kits/tr-707/sd.flac +0 -0
- package/kits/tr-707.d.ts +7 -0
- package/kits/tr-707.js +22 -0
- package/kits/tr-909/bd.flac +0 -0
- package/kits/tr-909/ch.flac +0 -0
- package/kits/tr-909/clap.flac +0 -0
- package/kits/tr-909/cym.flac +0 -0
- package/kits/tr-909/ht.flac +0 -0
- package/kits/tr-909/lt.flac +0 -0
- package/kits/tr-909/mt.flac +0 -0
- package/kits/tr-909/oh.flac +0 -0
- package/kits/tr-909/perc.flac +0 -0
- package/kits/tr-909/rim.flac +0 -0
- package/kits/tr-909/sd.flac +0 -0
- package/kits/tr-909.d.ts +7 -0
- package/kits/tr-909.js +22 -0
- package/meta.json +16 -16
- package/package.json +6 -1
- package/{worklets-inline-MUVFLGPY.js → worklets-inline-DFWINMCS.js} +2 -2
- package/chunk-NDUSYSHF.js.map +0 -7
- /package/{worklets-inline-MUVFLGPY.js.map → worklets-inline-DFWINMCS.js.map} +0 -0
package/index.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
|
-
"sources": ["../src/lib-runtime/core.ts", "../src/lib-runtime/time/transport.ts", "../src/lib/dsp/prng.ts", "../src/lib-runtime/time/voices.ts", "../src/lib-runtime/units.ts", "../src/lib/dsp/pulse.ts", "../src/lib/samples/types.ts", "../src/lib-runtime/samples.ts", "../src/
|
|
4
|
-
"sourcesContent": ["/**\n * Library runtime core \u2014 the only code the shipped package needs beyond the\n * stripped module descriptors themselves.\n *\n * Public entry point: preload(ctx) \u2014 register the inlined worklet processors,\n * once per context. defineModule() is internal: the generated module wrappers\n * call it, but it is not exported from the package (its parameter is the\n * app's ModuleDescriptor, which would drag Solid UI types into index.d.ts).\n *\n * Worklet sources reach here two ways:\n * - each module's pure-annotated defineModule() call passes the worklet\n * strings it needs (tree-shaken away with the module when unused), and\n * - preload(ctx, { allWorklets: true }) lazily pulls in the full generated\n * worklet set \u2014 the simple path for dev builds and the app itself.\n */\n\nimport type { ModuleDescriptor, ParamSpec, PortDefinition } from '@/modules/ModuleDescriptor';\nimport type { BaseModule } from '@/types/synth';\n\n// \u2500\u2500\u2500 preload(ctx) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/** Worklet sources of every module whose defineModule() call survived tree\n * shaking (i.e. every module the consumer actually references). Filled by\n * defineModule \u2014 a deliberate side effect inside the @__PURE__-annotated\n * factory call: shake the module away and its worklet strings vanish too. */\nconst pendingSources: Record<string, string> = {};\n\n/** One registration promise per context (each BaseAudioContext needs its own addModule calls). */\nconst registrations = new WeakMap<BaseAudioContext, Promise<void>>();\n\n/**\n * Register every bundled worklet processor on `ctx`. Required before any\n * module's create() on that context. Safe to call twice or concurrently \u2014\n * subsequent calls return the same promise.\n *\n * Processors are inlined as minified source strings and loaded via blob URLs,\n * so the package needs zero fetches and zero consumer asset setup. Consumers\n * under a strict CSP need `worker-src blob:` allowed.\n */\nexport function preload(ctx: BaseAudioContext, opts?: { allWorklets?: boolean }): Promise<void> {\n const existing = registrations.get(ctx);\n if (existing) return existing;\n\n // Default: only the worklets of modules that survived tree shaking.\n // allWorklets: pull in the full generated set (dev builds, the app itself).\n const sources = opts?.allWorklets\n ? import('./generated/worklets-inline').then((m) => m.WORKLET_SOURCES)\n : Promise.resolve(pendingSources);\n\n const promise = sources.then((map) =>\n Promise.all(Object.entries(map).map(async ([name, src]) => {\n const url = URL.createObjectURL(new Blob([src], { type: 'text/javascript' }));\n try {\n await ctx.audioWorklet.addModule(url);\n } catch (err) {\n throw new Error(`squelchy: failed to register worklet \"${name}\": ${err}`);\n } finally {\n URL.revokeObjectURL(url);\n }\n })),\n ).then(() => {});\n\n registrations.set(ctx, promise);\n return promise;\n}\n\n// \u2500\u2500\u2500 Public module shape \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport type ParamValue = number | string | boolean | number[] | boolean[][];\n\n/** Runtime metadata \u2014 only what code needs. Human-facing text (names,\n * descriptions, labels) is stripped from the bundle; it lives in the\n * generated docs/MODULES.md, meta.json and the .d.ts JSDoc instead. */\nexport interface ModuleMeta {\n type: string;\n ports: Record<string, Pick<PortDefinition, 'type' | 'signal'>>;\n params: Record<string, Pick<ParamSpec, 'default' | 'kind' | 'min' | 'max' | 'scale' | 'options' | 'node' | 'field'>>;\n}\n\ntype AnyParams = Record<string, ParamValue>;\n\n/** Port map: slug \u2192 the signal type behind that port. Pitch outputs are\n * `Signal<Note>` (absolute key positions, 69 = A4); everything else (audio,\n * gate, clock, CV) is a plain AudioNode \u2014 factor signals connect freely. */\nexport type PortMap = Record<string, AudioNode>;\n\n/** Native connect targets: `src.connect(module.input(slug))` works for every\n * key \u2014 an AudioParam where the port drives a real parameter (Web Audio sums\n * the CV onto the knob's base value), otherwise the AudioNode. */\nexport type InputMap = Record<string, AudioNode | AudioParam>;\n\nexport interface InstanceApi<P extends object = AnyParams, In extends InputMap = InputMap, Out extends PortMap = PortMap> {\n /** Native connect target behind an input slug: AudioParam or AudioNode. */\n input<K extends keyof In & string>(slug: K): In[K];\n output<K extends keyof Out & string>(slug: K): Out[K];\n /** Change a parameter now. For timed changes (ramps, curves, schedules)\n * use the native AudioParam in `params` \u2014 enums and derived params\n * (curves, filter banks) are set()-only by design. */\n set<K extends keyof P & string>(key: K, value: Exclude<P[K], undefined>): void;\n dispose(): void;\n}\n\n/** A module instance is the API above plus one native-feeling property per\n * port: camelCased slug \u2192 the same AudioParam/AudioNode input()/output()\n * returns, so `lfo.out.connect(vco.modDetune)` reads like a native node.\n * Slugs that would collide (with each other after camelCasing, or with a\n * reserved method name) are simply not exposed \u2014 the build refuses them. */\nexport type ModuleInstance<P extends object = AnyParams, In extends InputMap = InputMap, Out extends PortMap = PortMap, Props extends object = Record<never, never>> = InstanceApi<P, In, Out> & Props;\n\nexport interface LibModule<P extends object = AnyParams, In extends InputMap = InputMap, Out extends PortMap = PortMap, Props extends object = Record<never, never>> {\n meta: ModuleMeta;\n create(ctx: BaseAudioContext, params?: Partial<P>): ModuleInstance<P, In, Out, Props>;\n}\n\nlet instanceCounter = 0;\n\n/** Wrap a stripped module descriptor into the library's public module shape.\n * `opts.worklets` carries the minified sources of the processors this module\n * needs; they are registered with preload() here, deliberately, so that a\n * module shaken away by the consumer's bundler takes its worklets with it. */\nexport function defineModule(desc: ModuleDescriptor, opts?: { worklets?: Record<string, string> }): LibModule {\n if (opts?.worklets) Object.assign(pendingSources, opts.worklets);\n const meta: ModuleMeta = { type: desc.type, ports: desc.ports, params: desc.params ?? {} };\n\n return {\n meta,\n create(ctx, params = {}) {\n const module = { ...desc.createModule(`lib-${desc.type}-${instanceCounter++}`, { x: 0, y: 0 }), ...params };\n // Descriptors are typed against AudioContext; BaseAudioContext is the\n // structural superset the DSP actually uses (offline contexts included).\n const nodes = desc.createNodes(ctx as AudioContext, module);\n return withPortProperties(new Instance(desc, module, nodes), desc) as ModuleInstance<any, any, any, any>;\n },\n };\n}\n\n/** Property names the instance API already owns \u2014 a port slug colliding with\n * one of these is not exposed as a property (the build refuses such slugs). */\nconst RESERVED_PROPS = new Set(['input', 'output', 'set', 'dispose', 'params', 'then']);\n\n/** Wrap an instance in a Proxy that exposes each port as a native-feeling\n * property: the slug itself (camelCase by convention) \u2192 the same\n * AudioParam/AudioNode input()/output() returns. Slugs are the property\n * names verbatim \u2014 no conversion layer. A slug shared by an input and an\n * output, or colliding with a reserved name, is skipped (input()/output()\n * still reach it); the lib build's collision check refuses such modules. */\nfunction withPortProperties(inst: Instance, desc: ModuleDescriptor): Instance {\n const props = new Map<string, () => AudioNode | AudioParam>();\n for (const [slug, p] of Object.entries(desc.ports)) {\n if (RESERVED_PROPS.has(slug) || props.has(slug)) continue;\n props.set(slug, p.type === 'output' ? () => inst.output(slug) : () => inst.input(slug));\n }\n return new Proxy(inst, {\n get(target, key, receiver) {\n if (typeof key === 'string') {\n const hit = props.get(key);\n if (hit) return hit();\n }\n return Reflect.get(target, key, receiver);\n },\n });\n}\n\nclass Instance implements ModuleInstance {\n constructor(\n private desc: ModuleDescriptor,\n private module: BaseModule,\n private nodes: Record<string, AudioNode>,\n ) {}\n\n private port(slug: string): PortDefinition {\n const p = this.desc.ports[slug];\n if (!p) throw new Error(`squelchy: unknown port \"${slug}\" on ${this.desc.type}`);\n return p;\n }\n\n private nodeFor(slug: string): AudioNode {\n const p = this.port(slug);\n const node = p.node ? this.nodes[p.node] : undefined;\n if (!node) throw new Error(`squelchy: port \"${slug}\" on ${this.desc.type} has no audio node`);\n return node;\n }\n\n input(slug: string): AudioNode | AudioParam {\n const p = this.port(slug);\n const node = this.nodeFor(slug);\n if (!p.field) return node;\n // Native params (GainNode.gain, ConstantSource.offset) or worklet params.\n return this.resolveParam(p.node!, p.field, `port \"${slug}\"`);\n }\n output(slug: string): AudioNode { return this.nodeFor(slug); }\n\n /** Native AudioParams behind params declaring `node` + `field` (1:1 mapped,\n * no conversion) \u2014 full Web Audio automation: ramps, curves, CV. */\n get params(): Record<string, AudioParam> {\n const out: Record<string, AudioParam> = {};\n for (const [key, spec] of Object.entries(this.desc.params ?? {})) {\n if (!spec.node || !spec.field) continue;\n Object.defineProperty(out, key, { enumerable: true, get: () => this.resolveParam(spec.node!, spec.field!, `param \"${key}\"`) });\n }\n return out;\n }\n\n private resolveParam(nodeKey: string, field: string, what: string): AudioParam {\n const node = this.nodes[nodeKey];\n const param = (node as unknown as Record<string, AudioParam | undefined> | undefined)?.[field]\n ?? (node as AudioWorkletNode | undefined)?.parameters?.get(field);\n if (!param || typeof (param as AudioParam).setValueAtTime !== 'function') throw new Error(`squelchy: ${what} on ${this.desc.type} has no AudioParam \"${nodeKey}.${field}\"`);\n return param;\n }\n\n set(key: string, value: any): void {\n (this.module as unknown as Record<string, ParamValue>)[key] = value;\n this.desc.updateParam(this.nodes, this.module, key, value);\n }\n\n dispose(): void {\n this.desc.dispose?.(this.nodes);\n for (const node of Object.values(this.nodes)) {\n if (typeof (node as AudioScheduledSourceNode).stop === 'function') { try { (node as AudioScheduledSourceNode).stop(); } catch { /* not started / already stopped */ } }\n try { node.disconnect(); } catch { /* already disconnected */ }\n }\n }\n}\n", "/**\n * Library transport \u2014 musical time for plain Web Audio code.\n *\n * Library-only on purpose (the app keeps its own globalTransport for now).\n *\n * Units, chosen to be the easiest thing to write correctly:\n * - Musical positions are plain numbers in BEATS (quarter notes). Bar 2 of\n * a 4/4 song starts at beat 4. 16ths are 0.25.\n * - Audio times are ctx.currentTime seconds, as everywhere in Web Audio.\n * - A pattern is a plain array; one element per step. Step length defaults\n * to a 16th (`every: 0.25`).\n *\n * Scheduling is the usual lookahead pattern (timer on the main thread, events\n * written with sample-accurate `when` times). On an OfflineAudioContext the\n * whole render window is scheduled up front, so offline renders are exact.\n */\n\nimport type { Beats, Note, Seconds } from '../units';\nexport type { Beats };\n\n/** Where a playback starts. Default 'bar' = next bar line (beat 0 if stopped). */\nexport type StartAt = 'now' | 'beat' | 'bar' | { bar: number } | { beat: Beats };\n\n/** Rich step form, for when a plain value isn't enough. */\nexport interface StepObject<V> {\n value: V;\n /** 0..1, default 1. */\n velocity?: number;\n /** Gate length in steps, default = the playback's `gate`. */\n length?: number;\n}\n\n/** A pattern step: a value, a rest (null/undefined/false/0/'.'/'-'), or a StepObject. */\nexport type Step<V> = V | StepObject<V> | null | undefined | false;\n\n/** What a voice receives per hit. */\nexport interface Hit<V = unknown> {\n /** Audio time the sound starts (ctx.currentTime domain). */\n time: Seconds;\n /** Musical position of the hit, in beats. */\n beat: Beats;\n /** Step index within the pattern. */\n step: number;\n /** Loop iteration, 0-based. */\n cycle: number;\n /** The step's value (true for `steps('x..x')`, a midi number for melodies, \u2026). */\n value: V;\n velocity: number;\n /** Gate length in seconds. */\n duration: Seconds;\n}\n\n/**\n * Anything that makes sound at a time. Voice objects expose `trigger`; a plain\n * function `(time, hit) => void` works too, so any existing Web Audio code\n * (e.g. `(t) => osc.start(t)`) can be driven by a pattern.\n */\nexport type Voice<V = unknown> =\n | { trigger(time: Seconds, hit?: Partial<Hit<V>>): void }\n | ((time: Seconds, hit: Hit<V>) => void);\n\nexport interface PlayOptions<V> {\n /** Step length in beats. Default 0.25 (16ths). */\n every?: Beats;\n /** Where to start. Default 'bar'. */\n start?: StartAt;\n /** true = forever (default), false = once, n = n times. */\n loop?: boolean | number;\n /** Gate length as a fraction of a step. Default 0.5. */\n gate?: number;\n /** 0..1 \u2014 delays every odd step by swing \u00D7 half a step. Default 0. */\n swing?: number;\n /** Visual tap for this playback (fires when the hit is audible). */\n onHit?: (hit: Hit<V>) => void;\n}\n\nexport interface Playback<V> {\n /** Swap the pattern; takes effect at the next cycle start, so it stays in time. */\n set(pattern: readonly Step<V>[]): void;\n /** Stop scheduling. With a StartAt, stops at that musical boundary instead of now. */\n stop(at?: StartAt): void;\n readonly done: boolean;\n}\n\nexport interface TransportOptions {\n bpm?: number;\n beatsPerBar?: number;\n /** Seconds scheduled ahead. Default 0.1. */\n lookahead?: Seconds;\n /** 'auto' = internal 25 ms timer; 'manual' = you call tick() (tests, custom loops). */\n clock?: 'auto' | 'manual';\n}\n\nexport interface Transport {\n readonly ctx: BaseAudioContext;\n bpm: number;\n readonly beatsPerBar: number;\n readonly running: boolean;\n /** Start at audio time `when` (default: a hair from now). Beat 0 = that moment. */\n start(when?: Seconds): void;\n /** Stop scheduling and cancel pending taps. Already-written events (\u2264 lookahead) still sound. */\n stop(): void;\n /** Musical position at an audio time. */\n beatAt(time: Seconds): Beats;\n /** Audio time of a musical position. */\n timeAt(beat: Beats): Seconds;\n /** Resolve a StartAt to a beat, from the current position. */\n resolve(at: StartAt): Beats;\n /** Play a pattern array through a voice. */\n play<V>(pattern: readonly Step<V>[], voice: Voice<V>, opts?: PlayOptions<V>): Playback<V>;\n /** Run `fn(time)` once at a musical position \u2014 for automation, e.g. `vca.set('gain', 0, time)`. */\n at(when: StartAt | Beats, fn: (time: Seconds) => void): () => void;\n /** Global visual tap: every hit of every playback, fired when audible. Returns unsubscribe. */\n onHit(cb: (hit: Hit) => void): () => void;\n /** Schedule everything due inside the lookahead window. Auto-called in 'auto' mode. */\n tick(): void;\n dispose(): void;\n}\n\nconst EPS = 1e-9;\n\nexport function isRest(v: unknown): boolean {\n return v == null || v === false || v === 0 || v === '.' || v === '-';\n}\n\nfunction normStep<V>(s: Step<V>): StepObject<V> | null {\n if (isRest(s)) return null;\n if (typeof s === 'object' && s !== null && 'value' in (s as object)) {\n const o = s as StepObject<V>;\n return isRest(o.value) ? null : o;\n }\n return { value: s as V };\n}\n\nfunction callVoice<V>(voice: Voice<V>, hit: Hit<V>) {\n if (typeof voice === 'function') voice(hit.time, hit);\n else voice.trigger(hit.time, hit);\n}\n\ninterface Job {\n /** Next beat this job needs scheduling at. */\n nextBeat(): number;\n /** Schedule everything strictly before `until`. Returns false when finished. */\n run(until: number): boolean;\n}\n\nexport function createTransport(ctx: BaseAudioContext, opts: TransportOptions = {}): Transport {\n const beatsPerBar = opts.beatsPerBar ?? 4;\n const lookahead = opts.lookahead ?? 0.1;\n // OfflineAudioContext has a fixed `length` and no close(); realtime contexts have close().\n const offline = typeof (ctx as OfflineAudioContext).length === 'number' && typeof (ctx as AudioContext).close !== 'function';\n let bpm = opts.bpm ?? 120;\n // Tempo anchor: beat `aBeat` happens at time `aTime`; tempo is constant after it.\n let aBeat = 0;\n let aTime = 0;\n let running = false;\n /** Everything before this beat has been written. */\n let horizon = 0;\n let timer: ReturnType<typeof setInterval> | null = null;\n const jobs = new Set<Job>();\n const taps = new Set<(h: Hit) => void>();\n const tapTimers = new Set<ReturnType<typeof setTimeout>>();\n\n const spb = () => 60 / bpm;\n const beatAt = (t: number): Beats => (aBeat + (t - aTime) / spb()) as Beats;\n const timeAt = (b: number): Seconds => (aTime + (b - aBeat) * spb()) as Seconds;\n\n const current = (): number => (running ? Math.max(0, beatAt(ctx.currentTime + 0.005)) : 0);\n\n function resolve(at: StartAt): Beats {\n return resolveNum(at) as Beats;\n }\n function resolveNum(at: StartAt): number {\n const now = current();\n if (at === 'now') return now;\n if (at === 'beat') return Math.ceil(now - EPS);\n if (at === 'bar') return Math.ceil(now / beatsPerBar - EPS) * beatsPerBar;\n if ('bar' in at) return at.bar * beatsPerBar;\n return at.beat;\n }\n\n const latency = () => (ctx as AudioContext).outputLatency || (ctx as AudioContext).baseLatency || 0;\n\n function emitTap<V>(hit: Hit<V>, local?: (h: Hit<V>) => void) {\n if (!local && taps.size === 0) return;\n const fire = () => { local?.(hit); for (const cb of taps) cb(hit as Hit); };\n if (offline) { fire(); return; }\n const delay = Math.max(0, (hit.time - ctx.currentTime + latency()) * 1000);\n const id = setTimeout(() => { tapTimers.delete(id); fire(); }, delay);\n tapTimers.add(id);\n }\n\n function horizonBeat(): number {\n if (offline) return beatAt((ctx as OfflineAudioContext).length / ctx.sampleRate);\n return beatAt(ctx.currentTime + lookahead);\n }\n\n function tick() {\n if (!running) return;\n const until = horizonBeat();\n for (const job of jobs) if (!job.run(until)) jobs.delete(job);\n horizon = Math.max(horizon, until);\n }\n\n const t: Transport = {\n ctx,\n beatsPerBar,\n get bpm() { return bpm; },\n set bpm(v: number) {\n if (!(v > 0)) throw new RangeError('bpm must be > 0');\n // Re-anchor at the scheduling horizon: everything already written keeps\n // its old-tempo timing, everything after follows the new tempo.\n if (running) { const b = Math.max(horizon, beatAt(ctx.currentTime)); aTime = timeAt(b); aBeat = b; }\n bpm = v;\n },\n get running() { return running; },\n start(when = ctx.currentTime + 0.05) {\n if (running) return;\n aBeat = 0; aTime = when; horizon = 0; running = true;\n tick();\n if (!offline && opts.clock !== 'manual') timer = setInterval(tick, 25);\n },\n stop() {\n running = false;\n if (timer) clearInterval(timer);\n timer = null;\n for (const id of tapTimers) clearTimeout(id);\n tapTimers.clear();\n jobs.clear();\n },\n beatAt, timeAt, resolve,\n play<V>(pattern: readonly Step<V>[], voice: Voice<V>, o: PlayOptions<V> = {}): Playback<V> {\n const every = o.every ?? 0.25;\n const gate = o.gate ?? 0.5;\n const swing = o.swing ?? 0;\n const maxCycles = o.loop === false ? 1 : o.loop === true || o.loop === undefined ? Infinity : o.loop;\n let pat = pattern;\n let pending: readonly Step<V>[] | null = null;\n // Resolved now: when stopped, positions are relative to the coming start (beat 0).\n const startBeat: number = resolve(o.start ?? 'bar');\n let stopBeat = Infinity;\n let k = 0; // absolute step counter\n let done = false;\n\n const stepBeat = (i: number) => startBeat + i * every + (i % 2 === 1 ? swing * every * 0.5 : 0);\n\n const job: Job = {\n nextBeat: () => stepBeat(k),\n run(until) {\n while (!done) {\n if (pat.length === 0) { done = true; break; }\n const idx = k % pat.length;\n if (idx === 0 && pending) { pat = pending; pending = null; continue; }\n const cycle = Math.floor(k / pat.length);\n const b = stepBeat(k);\n if (cycle >= maxCycles || b >= stopBeat - EPS) { done = true; break; }\n if (b >= until) break;\n const s = normStep(pat[idx]);\n if (s) {\n const time = timeAt(b);\n const hit: Hit<V> = {\n time, beat: b as Beats, step: idx, cycle, value: s.value,\n velocity: s.velocity ?? 1,\n duration: ((s.length ?? gate) * every * spb()) as Seconds,\n };\n callVoice(voice, hit);\n emitTap(hit, o.onHit);\n }\n k++;\n }\n return !done;\n },\n };\n jobs.add(job);\n if (running) job.run(horizonBeat());\n return {\n set(p) { pending = p; },\n stop(at) {\n if (at) stopBeat = resolve(at);\n else { done = true; jobs.delete(job); }\n },\n get done() { return done; },\n };\n },\n at(when, fn) {\n const b: number = typeof when === 'number' ? when : resolve(when);\n let fired = false;\n const job: Job = {\n nextBeat: () => b,\n run(until) {\n if (fired) return false;\n if (b < until) { fired = true; fn(timeAt(b)); return false; }\n return true;\n },\n };\n jobs.add(job);\n if (running) tick();\n return () => { fired = true; jobs.delete(job); };\n },\n onHit(cb) { taps.add(cb); return () => { taps.delete(cb); }; },\n tick,\n dispose() { t.stop(); taps.clear(); },\n };\n return t;\n}\n\n// \u2500\u2500\u2500 Pattern helpers (all return plain arrays) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/** `steps('x... x... x..x x...')` \u2192 boolean[]. x/X = hit, anything else = rest; spaces/| ignored. */\nexport function steps(s: string): boolean[] {\n return [...s.replace(/[\\s|]/g, '')].map((c) => c === 'x' || c === 'X');\n}\n\nconst NOTE_RE = /^([A-Ga-g])([#b]?)(-?\\d+)$/;\nconst PC: Record<string, number> = { c: 0, d: 2, e: 4, f: 5, g: 7, a: 9, b: 11 };\n\n/** 'A4' \u2192 69, 'C4' \u2192 60, 'F#2' \u2192 42; a number passes through typed. Midi numbers are the pitch unit everywhere (V/Oct = semitones). */\nexport function note(name: string | number): Note {\n if (typeof name === 'number') return name as Note;\n const m = NOTE_RE.exec(name.trim());\n if (!m) throw new Error(`note(): can't parse \"${name}\"`);\n return ((parseInt(m[3], 10) + 1) * 12 + PC[m[1].toLowerCase()] + (m[2] === '#' ? 1 : m[2] === 'b' ? -1 : 0)) as Note;\n}\n\n/** `notes('C3 . E3 G3 - C4')` \u2192 (Note | null)[]. '.'/'-' = rest. */\nexport function notes(s: string): (Note | null)[] {\n return s.trim().split(/\\s+/).map((tok) => (tok === '.' || tok === '-' ? null : note(tok)));\n}\n", "/**\n * Deterministic PRNG for audio noise sources.\n *\n * Every noise buffer in the engine loops (or is a one-shot burst), so it was\n * always \"one particular random signal played back\" \u2014 the only question is\n * which one. Seeding fixes *which one* without changing the character:\n * a listener cannot tell one white-noise loop from another, but the QA\n * harness can tell a \u221239 dB render from a \u221241 dB one. Unseeded Math.random\n * made offline audits nondeterministic (doc:resonator:2 swung \u00B11.1 dB run to\n * run because its 30 ms noise burst excited the resonator's five modes with\n * different energy every render \u2014 see CHANGES-2026-08-04-probe-laws.md).\n *\n * This is also authentic hardware behaviour: sample-based drum machines play\n * the identical noise transient on every hit, and several classic noise\n * circuits are looped shift-register (LFSR) sequences \u2014 literally a fixed\n * pseudo-random loop.\n *\n * mulberry32: tiny, fast, passes gjrand; more than enough for audio noise.\n */\n\n/** Uniform [0, 1) generator from a 32-bit seed. */\nexport function mulberry32(seed: number): () => number {\n let a = seed >>> 0;\n return () => {\n a = (a + 0x6d2b79f5) | 0;\n let t = Math.imul(a ^ (a >>> 15), 1 | a);\n t = (t + Math.imul(t ^ (t >>> 7), 61 | t)) ^ t;\n return ((t ^ (t >>> 14)) >>> 0) / 4294967296;\n };\n}\n\n/** Uniform [-1, 1) generator \u2014 the audio-noise shape. */\nexport function noiseSource(seed: number): () => number {\n const rand = mulberry32(seed);\n return () => rand() * 2 - 1;\n}\n\n/**\n * Stable seeds per noise purpose. Distinct so no two sources share a\n * sequence (two modules playing the same loop would correlate and bus-sum\n * +6 dB instead of +3 dB). Values are arbitrary but committed: changing one\n * changes rendered audio and will move audit levels a fraction of a dB.\n */\nexport const NOISE_SEEDS = {\n noiseWhite: 0x9e3779b9,\n noisePink: 0x85ebca6b,\n noiseBrown: 0xc2b2ae35,\n loFiCrackle: 0x27d4eb2f,\n drumSnare: 0x165667b1,\n drumHat: 0xd3a2646c,\n d808Snare: 0xfd7046c5,\n d808ClosedHat: 0xb55a4f09,\n d808OpenHat: 0x2b2ae3c2,\n} as const;\n", "/**\n * Triggerable voices for the library. `X.create(ctx)` mirrors the module API;\n * every voice is a Voice (has `trigger(time, hit?)`) with an `output` node and\n * a Web-Audio-style `connect()`.\n *\n * Trigger decision: `trigger(time, { velocity, value, duration })`.\n * - `time` first and positional, like `AudioScheduledSourceNode.start(when)`.\n * - velocity 0..1 scales the hit's peak level (not a separate param to automate).\n * - value is pitch in midi (NoteCv) and ignored by drums.\n * Voices are copied from the app's drums module and may diverge from it.\n */\nimport { noiseSource, NOISE_SEEDS } from '@/lib/dsp/prng';\nimport type { Hit } from './transport';\nimport type { Note, Seconds, Signal } from '../units';\n\nexport interface VoiceInstance<V = unknown> {\n output: AudioNode;\n trigger(time: Seconds, hit?: Partial<Hit<V>>): void;\n connect<T extends AudioNode>(dest: T): T;\n disconnect(): void;\n}\n\nfunction voice<V>(output: GainNode, trigger: VoiceInstance<V>['trigger']): VoiceInstance<V> {\n return {\n output, trigger,\n connect: (d) => { output.connect(d); return d; },\n disconnect: () => output.disconnect(),\n };\n}\n\nfunction noiseBuffer(ctx: BaseAudioContext, seconds: number, seed: number) {\n const n = Math.floor(ctx.sampleRate * seconds);\n const buf = ctx.createBuffer(1, n, ctx.sampleRate);\n const d = buf.getChannelData(0);\n const rand = noiseSource(seed);\n for (let i = 0; i < n; i++) d[i] = rand();\n return buf;\n}\n\nconst vel = (h?: Partial<Hit>) => Math.max(0, Math.min(1, h?.velocity ?? 1));\n\nexport const Kick = {\n create(ctx: BaseAudioContext): VoiceInstance {\n const out = ctx.createGain();\n return voice(out, (when, h) => {\n const osc = ctx.createOscillator();\n const g = ctx.createGain();\n osc.frequency.setValueAtTime(150, when);\n osc.frequency.exponentialRampToValueAtTime(40, when + 0.1);\n g.gain.setValueAtTime(0.8 * vel(h) + 1e-4, when);\n g.gain.exponentialRampToValueAtTime(1e-4, when + 0.3);\n osc.connect(g).connect(out);\n osc.start(when); osc.stop(when + 0.3);\n });\n },\n};\n\nexport const Snare = {\n create(ctx: BaseAudioContext): VoiceInstance {\n const out = ctx.createGain();\n const buf = noiseBuffer(ctx, 0.15, NOISE_SEEDS.drumSnare);\n return voice(out, (when, h) => {\n const v = vel(h);\n const n = ctx.createBufferSource(); n.buffer = buf;\n const ng = ctx.createGain();\n ng.gain.setValueAtTime(0.4 * v + 1e-4, when);\n ng.gain.exponentialRampToValueAtTime(1e-4, when + 0.15);\n n.connect(ng).connect(out);\n const osc = ctx.createOscillator(); osc.type = 'triangle';\n const og = ctx.createGain();\n osc.frequency.setValueAtTime(200, when);\n osc.frequency.exponentialRampToValueAtTime(80, when + 0.05);\n og.gain.setValueAtTime(0.5 * v + 1e-4, when);\n og.gain.exponentialRampToValueAtTime(1e-4, when + 0.08);\n osc.connect(og).connect(out);\n n.start(when); osc.start(when); osc.stop(when + 0.15);\n });\n },\n};\n\nexport const Hat = {\n create(ctx: BaseAudioContext): VoiceInstance {\n const out = ctx.createGain();\n const buf = noiseBuffer(ctx, 0.05, NOISE_SEEDS.drumHat);\n return voice(out, (when, h) => {\n const n = ctx.createBufferSource(); n.buffer = buf;\n const f = ctx.createBiquadFilter(); f.type = 'highpass'; f.frequency.value = 8000;\n const g = ctx.createGain();\n g.gain.setValueAtTime(0.2 * vel(h) + 1e-4, when);\n g.gain.exponentialRampToValueAtTime(1e-4, when + 0.05);\n n.connect(f).connect(g).connect(out);\n n.start(when);\n });\n },\n};\n\n/**\n * Gate + pitch CV for driving patchable modules (Envelope trig, V/Oct inputs).\n * `gate` goes to the hit's velocity at `time`, back to 0 after `duration`;\n * `pitch` holds the note (absolute key position, 69 = A4), typed as the\n * library's pitch signal like every other V/OCT output. Both are\n * ConstantSourceNodes.\n */\nexport interface NoteCvInstance {\n /** Gate CV: the hit's velocity while a note is held, 0 otherwise. */\n gate: ConstantSourceNode;\n /** Pitch CV: the current note (69 = A4), held between notes. */\n pitch: ConstantSourceNode & Signal<Note>;\n trigger(time: Seconds, hit?: Partial<Hit<Note>>): void;\n dispose(): void;\n}\n\nexport const NoteCv = {\n create(ctx: BaseAudioContext): NoteCvInstance {\n const gate = ctx.createConstantSource(); gate.offset.value = 0; gate.start();\n const pitch = ctx.createConstantSource() as ConstantSourceNode & Signal<Note>; pitch.offset.value = 60; pitch.start();\n return {\n gate, pitch,\n trigger(time: Seconds, h?: Partial<Hit<Note>>) {\n if (typeof h?.value === 'number') pitch.offset.setValueAtTime(h.value, time);\n // Drop to 0 one sample early so back-to-back notes still produce a rising edge.\n gate.offset.setValueAtTime(0, Math.max(0, time - 1 / ctx.sampleRate));\n gate.offset.setValueAtTime(vel(h), time);\n gate.offset.setValueAtTime(0, time + (h?.duration ?? 0.1));\n },\n dispose() { gate.stop(); pitch.stop(); gate.disconnect(); pitch.disconnect(); },\n };\n },\n};\n", "/**\n * Branded unit types for the library API. Zero runtime cost: brands exist only\n * in the type system. A plain number never silently becomes a Note or Hz \u2014\n * go through a converter, or say what you mean with an `as` cast\n * (`60 as Note`, `ctx.currentTime as Seconds`). Casts are the reinterpretation\n * escape hatch: explicit and greppable.\n *\n * Dimensionless values (`factor` params: mix, feedback, drive\u2026) are plain\n * `number` \u2014 a brand there would only add noise.\n *\n * Arithmetic on brands yields `number` (TS can't know `note + 7` is still a\n * note), so re-brand results with a converter or a cast.\n */\ndeclare const unit: unique symbol;\ntype Brand<U extends string> = number & { readonly [unit]: U };\n\n/** Absolute key position, MIDI datum (69 = A4). */\nexport type Note = Brand<'note'>;\n/** Relative pitch offset (12 = one octave). Also the V/OCT signal scale. */\nexport type Semitones = Brand<'semitone'>;\n/** 1/100 semitone, relative. */\nexport type Cents = Brand<'cents'>;\n/** Cycles per second. */\nexport type Hz = Brand<'Hz'>;\n/** Audio time or duration in seconds (ctx.currentTime domain). */\nexport type Seconds = Brand<'s'>;\nexport type Milliseconds = Brand<'ms'>;\nexport type Decibels = Brand<'dB'>;\n/** Musical position or length in quarter-note beats. */\nexport type Beats = Brand<'beats'>;\n\n// \u2500\u2500\u2500 Shorthand constructors \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n// The readable way to brand a literal: `t.start(sec(0))`, `{ every: beats(0.25) }`.\n// Identity at runtime \u2014 they exist only to satisfy the type system.\n\nexport const sec = (v: number): Seconds => v as Seconds;\nexport const ms = (v: number): Milliseconds => v as Milliseconds;\nexport const beats = (v: number): Beats => v as Beats;\nexport const hz = (v: number): Hz => v as Hz;\nexport const semitones = (v: number): Semitones => v as Semitones;\nexport const cents = (v: number): Cents => v as Cents;\nexport const db = (v: number): Decibels => v as Decibels;\n\nexport const noteToHz = (n: Note): Hz => (440 * 2 ** ((n - 69) / 12)) as Hz;\nexport const hzToNote = (f: Hz): Note => (69 + 12 * Math.log2(f / 440)) as Note;\nexport const transpose = (n: Note, by: Semitones): Note => (n + by) as Note;\n/** Distance from `a` to `b`. */\nexport const interval = (a: Note, b: Note): Semitones => (b - a) as Semitones;\nexport const centsToSemitones = (c: Cents): Semitones => (c / 100) as Semitones;\nexport const msToSeconds = (ms: Milliseconds): Seconds => (ms / 1000) as Seconds;\nexport const dbToGain = (db: Decibels): number => 10 ** (db / 20);\nexport const gainToDb = (g: number): Decibels => (20 * Math.log10(g)) as Decibels;\n/** `ctx.currentTime`, typed. */\nexport const now = (ctx: BaseAudioContext): Seconds => ctx.currentTime as Seconds;\n\n// \u2500\u2500\u2500 Signals (ports) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n// One scheme for values and ports: a port is a stream of values, so a port\n// type is \"a signal carrying quantity Q\". There is no separate gate/clock/\n// modulation kind \u2014 those are all factor signals (dimensionless: \u00B11 audio,\n// 0/1 gates and clocks, unit-scaled CV). Only pitch gets a distinct brand,\n// because plugging raw CV into a V/OCT input is the one mistake that is\n// silent and musical (five octaves off, not \"no sound\").\n//\n// The pitch brand is Note, not Semitones: our V/OCT wires carry ABSOLUTE\n// key positions on the MIDI datum (69 = A4 \u2014 map-voct-to-freq converts\n// `440 * 2^((note - 69) / 12)`). Offsets (transpose, detune, LFO depth)\n// live in params as Semitones, never on a wire.\ndeclare const signal: unique symbol;\n\n/** An AudioNode whose stream carries quantity Q. `Signal<Note>` is a V/OCT\n * pitch signal (absolute key position, 69 = A4); factor signals are plain\n * `AudioNode` (no wrapper \u2014 audio, gates, clocks and CV connect freely). */\nexport type Signal<Q> = AudioNode & { readonly [signal]: Q };\n\n/** Reinterpret a node as a pitch signal \u2014 the greppable escape hatch for\n * deliberate cross-quantity patches. */\nexport const asPitch = (n: AudioNode): Signal<Note> => n as Signal<Note>;\n", "/**\n * One-shot gate pulse: a sample-accurate rising edge at `when`.\n *\n * Gate/trigger inputs (tape-stop TRIG, spring KNOCK, \u2026) act on a rising\n * edge. A panel button and a scheduled library call both fire the action by\n * pulsing that input \u2014 one path, sample-accurate, no worklet messages\n * (which arrive \"whenever\", not at a context time).\n *\n * pulse(tapeStop.trigger, ctx.currentTime + 1) // library\n *\n * The pulse sums with anything else patched into the input, so a gate held\n * high at that moment (sum already > threshold) produces no new edge \u2014\n * exactly as a second cable would behave on hardware.\n */\nconst PULSE_S = 0.001; // many samples at any rate; edge detectors fire once\n\nexport function pulse(target: AudioNode, when?: number): void {\n const ctx = target.context;\n const at = Math.max(when ?? 0, ctx.currentTime);\n const src = ctx.createConstantSource();\n src.offset.value = 1;\n src.connect(target);\n src.start(at);\n src.stop(at + PULSE_S);\n src.onended = () => src.disconnect();\n}\n", "/** Canonical percussion voice keys shared by every sample set and by any\n * module that plays percussion (DRUMS, 808, and anything added later).\n *\n * A set may omit voices; `resolveVoice` in sampleBank.ts walks a fallback\n * chain so a module never goes silent because a kit lacks, say, an open hat.\n */\nexport const VOICE_KEYS = [\n 'bd', 'sd', 'rim', 'clap', 'ch', 'oh', 'lt', 'mt', 'ht', 'cym', 'perc',\n] as const;\n\nexport type VoiceKey = (typeof VOICE_KEYS)[number];\n\nexport const VOICE_LABELS: Record<VoiceKey, string> = {\n bd: 'Bass drum',\n sd: 'Snare',\n rim: 'Rim / click',\n clap: 'Clap',\n ch: 'Closed hat',\n oh: 'Open hat',\n lt: 'Low tom',\n mt: 'Mid tom',\n ht: 'High tom',\n cym: 'Cymbal',\n perc: 'Percussion',\n};\n\n/** If a set is missing a voice, try these in order instead. */\nexport const VOICE_FALLBACKS: Record<VoiceKey, VoiceKey[]> = {\n bd: ['lt', 'mt'],\n sd: ['clap', 'rim'],\n rim: ['perc', 'ch'],\n clap: ['sd', 'perc'],\n ch: ['perc', 'rim'],\n oh: ['ch', 'cym'],\n lt: ['mt', 'bd'],\n mt: ['lt', 'ht'],\n ht: ['mt', 'lt'],\n cym: ['oh', 'ch'],\n perc: ['rim', 'ch'],\n};\n\nexport interface SampleSet {\n /** Stable id stored in patches. */\n id: string;\n name: string;\n /** One-line character description shown in the picker. */\n blurb: string;\n /** Grouping shown in the picker. */\n family: 'Machines' | 'Acoustic' | 'Digital' | 'Character' | 'Synthesised';\n credit: string;\n license: string;\n licenseUrl?: string;\n /** URL per voice. Empty for the built-in synthesis set. */\n voices: Partial<Record<VoiceKey, string>>;\n /** True for the zero-download, procedurally generated set. */\n synthesised?: boolean;\n}\n\n/** Id of the built-in (non-sampled) set. */\nexport const SYNTH_SET_ID = 'synth';\n", "/**\n * Sample kits for the library. All kits are CC0 / public domain (see AGENTS.md).\n *\n * The kit table (`SampleSets`, generated by scripts/lib/build.ts) is a single\n * pure-annotated export: it tree-shakes as a group \u2014 a consumer that never\n * imports it pays zero bytes; importing it brings every kit's metadata + URLs\n * (a few KB; audio is only fetched by `loadSampleSet`).\n *\n * const kit = await loadSampleSet(ctx, SampleSets['roland-808']);\n * const bd = SampleVoice.create(ctx, kit, 'bd');\n * transport.play(steps('x...x...'), bd);\n */\nimport { VOICE_FALLBACKS, VOICE_KEYS, type VoiceKey } from '@/lib/samples/types';\nimport type { Hit } from './time/transport';\nimport type { VoiceInstance } from './time/voices';\n\nexport { VOICE_KEYS };\nexport type { VoiceKey };\n\n/** Where the kit audio is hosted. Override with `loadSampleSet(..., { baseUrl })`. */\nexport const DEFAULT_SAMPLE_BASE_URL = 'https://squelchy.studio';\n\nexport interface SampleSetInfo {\n name: string;\n blurb: string;\n family: 'Machines' | 'Acoustic' | 'Digital' | 'Character';\n credit: string;\n license: string;\n licenseUrl: string;\n /** Root-relative sample path per voice; resolved against baseUrl on load. */\n voices: Partial<Record<VoiceKey, string>>;\n}\n\nexport function defineSampleSets<T extends Record<string, SampleSetInfo>>(sets: T): T {\n return sets;\n}\n\nexport interface LoadedSampleSet {\n set: SampleSetInfo;\n buffers: Partial<Record<VoiceKey, AudioBuffer>>;\n /** Buffer for a voice, walking the fallback chain when the kit lacks it. */\n buffer(key: VoiceKey): AudioBuffer | undefined;\n}\n\n/** Fetch + decode every voice of a kit in parallel. */\nexport async function loadSampleSet(\n ctx: BaseAudioContext,\n set: SampleSetInfo,\n opts: { baseUrl?: string; fetch?: typeof fetch } = {},\n): Promise<LoadedSampleSet> {\n const base = opts.baseUrl ?? DEFAULT_SAMPLE_BASE_URL;\n const f = opts.fetch ?? fetch;\n const buffers: Partial<Record<VoiceKey, AudioBuffer>> = {};\n await Promise.all(\n (Object.entries(set.voices) as [VoiceKey, string][]).map(async ([key, path]) => {\n const res = await f(new URL(path, base).href);\n if (!res.ok) throw new Error(`loadSampleSet: ${key} ${res.status}`);\n buffers[key] = await ctx.decodeAudioData(await res.arrayBuffer());\n }),\n );\n return {\n set,\n buffers,\n buffer(key) {\n return buffers[key] ?? VOICE_FALLBACKS[key].map((k) => buffers[k]).find(Boolean);\n },\n };\n}\n\n/** A one-sample voice. velocity 0..1 scales level; a number `value`\n * repitches in semitones, anything else (e.g. `true` from steps()) plays it\n * unshifted. */\nexport const SampleVoice = {\n create(ctx: BaseAudioContext, kit: LoadedSampleSet, key: VoiceKey): VoiceInstance<number | boolean> {\n const out = ctx.createGain();\n const buf = kit.buffer(key);\n const trigger = (when: number, h?: Partial<Hit<number | boolean>>) => {\n if (!buf) return;\n const src = ctx.createBufferSource();\n const g = ctx.createGain();\n src.buffer = buf;\n if (typeof h?.value === 'number') src.playbackRate.value = 2 ** (h.value / 12);\n g.gain.value = Math.max(0, Math.min(1, h?.velocity ?? 1));\n src.connect(g).connect(out);\n src.start(when);\n if (h?.duration) src.stop(when + h.duration);\n };\n return {\n output: out, trigger,\n connect: (d) => { out.connect(d); return d; },\n disconnect: () => out.disconnect(),\n };\n },\n};\n", "import { defineSampleSets } from '../samples';\n\nexport const SampleSets = /* @__PURE__ */ defineSampleSets({\n \"roland-808\": {\n \"name\": \"Roland TR-808\",\n \"blurb\": \"The original machine, sampled from hardware. Deep sub kick, ticking hats.\",\n \"family\": \"Machines\",\n \"credit\": \"Michael Fischer / Technopolis TR-808 sample set, released to the public domain\",\n \"license\": \"CC0 1.0 / public domain \u2014 free to use, no attribution required\",\n \"licenseUrl\": \"https://creativecommons.org/publicdomain/zero/1.0/\",\n \"voices\": {\n \"bd\": \"/__l5e/assets-v1/c4b2fc55-dcf1-4248-a7fb-2cd3653a659b/roland-808-bd.flac\",\n \"ch\": \"/__l5e/assets-v1/c1ec3b3d-571f-46a6-9d05-12b2fe5f6fc5/roland-808-ch.flac\",\n \"clap\": \"/__l5e/assets-v1/8bd15e4b-96b7-46b6-b26a-35283c816f1e/roland-808-clap.flac\",\n \"cym\": \"/__l5e/assets-v1/033f0719-913a-4a7a-998e-92a7319d806f/roland-808-cym.flac\",\n \"ht\": \"/__l5e/assets-v1/ca555782-7544-446a-a461-9b56b4d30072/roland-808-ht.flac\",\n \"lt\": \"/__l5e/assets-v1/8e100e1c-3844-42aa-bbe7-9eb52b9d704e/roland-808-lt.flac\",\n \"mt\": \"/__l5e/assets-v1/93dd309f-9347-4ea1-909f-56196b08dc88/roland-808-mt.flac\",\n \"oh\": \"/__l5e/assets-v1/4881941c-b558-4159-babd-fe224b0f1543/roland-808-oh.flac\",\n \"perc\": \"/__l5e/assets-v1/d13076b5-50ca-4675-9d4e-70afd6e6203d/roland-808-perc.flac\",\n \"rim\": \"/__l5e/assets-v1/ce82e0e9-402d-4a5e-bf01-59dfb922d1ba/roland-808-rim.flac\",\n \"sd\": \"/__l5e/assets-v1/67a799c9-e019-442b-8025-99d69bc493b9/roland-808-sd.flac\"\n }\n },\n \"tr-909\": {\n \"name\": \"Roland TR-909\",\n \"blurb\": \"Punchy transistor kick, snappy sampled snare, sizzling metal hats. House and techno.\",\n \"family\": \"Machines\",\n \"credit\": \"MckAudio TR8 sample pack, dedicated to the public domain (CC0)\",\n \"license\": \"CC0 1.0 / public domain \u2014 free to use, no attribution required\",\n \"licenseUrl\": \"https://creativecommons.org/publicdomain/zero/1.0/\",\n \"voices\": {\n \"bd\": \"/__l5e/assets-v1/fd3911bb-6783-4db6-bee2-bb8c5a589f26/tr-909-bd.flac\",\n \"ch\": \"/__l5e/assets-v1/6f795c20-fb89-4cd5-b696-3a505d487baa/tr-909-ch.flac\",\n \"clap\": \"/__l5e/assets-v1/7b1ccf8e-0dd6-4189-82d7-03a910e895f2/tr-909-clap.flac\",\n \"cym\": \"/__l5e/assets-v1/f0d5ce25-3238-4e89-bb09-f5b7118fa0a7/tr-909-cym.flac\",\n \"ht\": \"/__l5e/assets-v1/5f9b4c37-25a7-492c-aaed-f7fe24fbfe2c/tr-909-ht.flac\",\n \"lt\": \"/__l5e/assets-v1/8477dddd-b9ed-4957-9a48-b5501bc77056/tr-909-lt.flac\",\n \"mt\": \"/__l5e/assets-v1/92d461e5-d74a-4ba2-a899-4dea1ad06d13/tr-909-mt.flac\",\n \"oh\": \"/__l5e/assets-v1/20c51259-d8d1-4ee3-a1d6-e850c3227b1a/tr-909-oh.flac\",\n \"perc\": \"/__l5e/assets-v1/147d346e-9ae7-4413-a50a-de4f03ef7342/tr-909-perc.flac\",\n \"rim\": \"/__l5e/assets-v1/0c9f157d-1329-4804-aa12-6819651d69fb/tr-909-rim.flac\",\n \"sd\": \"/__l5e/assets-v1/bd8069c2-e07c-4d5c-b05a-fb5b9a31eadb/tr-909-sd.flac\"\n }\n },\n \"tr-707\": {\n \"name\": \"Roland TR-707\",\n \"blurb\": \"Twelve-bit sampled kit with early-digital crunch. Big eighties snare and claps.\",\n \"family\": \"Machines\",\n \"credit\": \"MckAudio TR8 sample pack, dedicated to the public domain (CC0)\",\n \"license\": \"CC0 1.0 / public domain \u2014 free to use, no attribution required\",\n \"licenseUrl\": \"https://creativecommons.org/publicdomain/zero/1.0/\",\n \"voices\": {\n \"bd\": \"/__l5e/assets-v1/825b2c7c-5c5f-411c-8191-306549ee26f2/tr-707-bd.flac\",\n \"ch\": \"/__l5e/assets-v1/6b35b393-7e9c-462d-8d2f-dc834417062b/tr-707-ch.flac\",\n \"clap\": \"/__l5e/assets-v1/efbe819a-b13e-4bf2-a6bd-9bc15a09ff3f/tr-707-clap.flac\",\n \"cym\": \"/__l5e/assets-v1/4a34902b-8592-46d8-b339-05a0648cac4f/tr-707-cym.flac\",\n \"ht\": \"/__l5e/assets-v1/e58beee9-45e5-4b65-af99-a05fcb96f55b/tr-707-ht.flac\",\n \"lt\": \"/__l5e/assets-v1/a0d6f499-4af6-4d34-96de-5ad7c2397229/tr-707-lt.flac\",\n \"mt\": \"/__l5e/assets-v1/6c4bd12b-78ff-4f70-863b-cd482f684eb6/tr-707-mt.flac\",\n \"oh\": \"/__l5e/assets-v1/c07159f3-d763-4698-a786-aeae60d38ac9/tr-707-oh.flac\",\n \"perc\": \"/__l5e/assets-v1/2f8cffcb-8e86-4f65-99db-a705727ed3ab/tr-707-perc.flac\",\n \"rim\": \"/__l5e/assets-v1/3d6445b1-38bd-4e9f-b048-db8c079b3c03/tr-707-rim.flac\",\n \"sd\": \"/__l5e/assets-v1/aaf70dd8-c740-4b05-9369-feb80f3e26be/tr-707-sd.flac\"\n }\n },\n \"tr-606\": {\n \"name\": \"Roland TR-606\",\n \"blurb\": \"Tiny Drumatix voices \u2014 thin kick, spitty snare, ticking hats. Perfect with a 303.\",\n \"family\": \"Machines\",\n \"credit\": \"MckAudio TR8 sample pack, dedicated to the public domain (CC0)\",\n \"license\": \"CC0 1.0 / public domain \u2014 free to use, no attribution required\",\n \"licenseUrl\": \"https://creativecommons.org/publicdomain/zero/1.0/\",\n \"voices\": {\n \"bd\": \"/__l5e/assets-v1/f46ec897-9319-4c25-b63b-74df979de508/tr-606-bd.flac\",\n \"ch\": \"/__l5e/assets-v1/f4c57254-c711-43b0-82c6-52b011e205ba/tr-606-ch.flac\",\n \"cym\": \"/__l5e/assets-v1/db524ec1-36d3-43db-bfc4-fd84a1ddd2ac/tr-606-cym.flac\",\n \"ht\": \"/__l5e/assets-v1/74b486cf-c1f1-45c7-bd2a-4fd0c3794e1a/tr-606-ht.flac\",\n \"lt\": \"/__l5e/assets-v1/6b1a564f-6388-40c1-8028-3ea9b6824256/tr-606-lt.flac\",\n \"mt\": \"/__l5e/assets-v1/d871a86a-fcc8-45a6-b5a4-83977a689593/tr-606-mt.flac\",\n \"oh\": \"/__l5e/assets-v1/a4c607d2-d62c-49b5-ac99-549fd6262468/tr-606-oh.flac\",\n \"sd\": \"/__l5e/assets-v1/2062f1d4-e34f-406f-911b-2eb2ec523a89/tr-606-sd.flac\"\n }\n },\n \"compu-78\": {\n \"name\": \"Compu-78\",\n \"blurb\": \"Tiny, dry preset-box percussion. Bossa nova organ rhythm energy.\",\n \"family\": \"Machines\",\n \"credit\": \"Synthesised for Squelchy\",\n \"license\": \"CC0 1.0 / public domain \u2014 free to use, no attribution required\",\n \"licenseUrl\": \"https://creativecommons.org/publicdomain/zero/1.0/\",\n \"voices\": {\n \"bd\": \"/__l5e/assets-v1/150a91e2-8b92-40f2-80e0-10b30f10976b/compu-78-bd.flac\",\n \"ch\": \"/__l5e/assets-v1/da9dcfc4-5f29-43b9-979f-9679edeb09ed/compu-78-ch.flac\",\n \"clap\": \"/__l5e/assets-v1/f3b5d485-44bc-4b34-b2bc-d37f436dffc2/compu-78-clap.flac\",\n \"cym\": \"/__l5e/assets-v1/627db2bf-08d5-4054-8de9-b8ec0ca4436a/compu-78-cym.flac\",\n \"ht\": \"/__l5e/assets-v1/1323f20c-3c98-45fb-abd1-e4b1e4be158f/compu-78-ht.flac\",\n \"lt\": \"/__l5e/assets-v1/ba67ce5c-3f01-4e1b-9fd8-a96bb5428cf4/compu-78-lt.flac\",\n \"mt\": \"/__l5e/assets-v1/f8cd42d6-2f98-4e9d-9428-ba091ec125cf/compu-78-mt.flac\",\n \"oh\": \"/__l5e/assets-v1/b4a1d5b2-0022-4f1b-ac52-1618ba03ea67/compu-78-oh.flac\",\n \"perc\": \"/__l5e/assets-v1/55e15a92-ba17-48cb-aec0-47e5198f073f/compu-78-perc.flac\",\n \"rim\": \"/__l5e/assets-v1/698aaf24-8e84-4b3b-8f13-dc95f2b3f157/compu-78-rim.flac\",\n \"sd\": \"/__l5e/assets-v1/41357245-d767-410e-8415-08dbb9e7503e/compu-78-sd.flac\"\n }\n },\n \"dr5-studio\": {\n \"name\": \"Studio Kit\",\n \"blurb\": \"Acoustic drums in a small dry room. Skin, air and a little ambience.\",\n \"family\": \"Acoustic\",\n \"credit\": \"MckAudio DR5 sample pack, dedicated to the public domain (CC0)\",\n \"license\": \"CC0 1.0 / public domain \u2014 free to use, no attribution required\",\n \"licenseUrl\": \"https://creativecommons.org/publicdomain/zero/1.0/\",\n \"voices\": {\n \"bd\": \"/__l5e/assets-v1/9bc4c40f-432c-4fd1-98f8-dc3343b5dd31/dr5-studio-bd.flac\",\n \"ch\": \"/__l5e/assets-v1/862411a4-6d87-45e7-a3a2-2c4062f8e79b/dr5-studio-ch.flac\",\n \"clap\": \"/__l5e/assets-v1/2feebc4f-49d2-4ea0-9b5a-890059c24a9c/dr5-studio-clap.flac\",\n \"cym\": \"/__l5e/assets-v1/5abff1b5-b403-403b-b681-9ac37a394442/dr5-studio-cym.flac\",\n \"ht\": \"/__l5e/assets-v1/4e6883a5-e310-4035-a6ae-ee4033c7a0a1/dr5-studio-ht.flac\",\n \"lt\": \"/__l5e/assets-v1/faf35ae9-f89f-4ceb-ad5e-c562dd5d261a/dr5-studio-lt.flac\",\n \"mt\": \"/__l5e/assets-v1/4b923b44-9e79-4aa0-a9ef-4178a9f0279b/dr5-studio-mt.flac\",\n \"oh\": \"/__l5e/assets-v1/5a5e6d0c-4c8f-4dc5-9dea-55f90083a55a/dr5-studio-oh.flac\",\n \"perc\": \"/__l5e/assets-v1/8d286dd0-4201-49f6-9738-0a39e3a3d860/dr5-studio-perc.flac\",\n \"rim\": \"/__l5e/assets-v1/1d139e86-288e-48bd-baba-f7d2502271a5/dr5-studio-rim.flac\",\n \"sd\": \"/__l5e/assets-v1/eb7b02d6-7063-4350-9515-40010dd583cb/dr5-studio-sd.flac\"\n }\n },\n \"tape-dust\": {\n \"name\": \"Tape Dust\",\n \"blurb\": \"Wobbly, hissy and rolled-off. Everything through a tired cassette.\",\n \"family\": \"Character\",\n \"credit\": \"Synthesised for Squelchy\",\n \"license\": \"CC0 1.0 / public domain \u2014 free to use, no attribution required\",\n \"licenseUrl\": \"https://creativecommons.org/publicdomain/zero/1.0/\",\n \"voices\": {\n \"bd\": \"/__l5e/assets-v1/7e90ada0-1da8-4930-9c05-48c395e8a863/tape-dust-bd.flac\",\n \"ch\": \"/__l5e/assets-v1/538fd73f-f7ee-408e-ab69-f8865506f4f5/tape-dust-ch.flac\",\n \"clap\": \"/__l5e/assets-v1/21b5b5ea-6dce-495d-b740-e7162941c972/tape-dust-clap.flac\",\n \"cym\": \"/__l5e/assets-v1/ac1a7f2d-9a96-4f61-b2ec-743854f15bbe/tape-dust-cym.flac\",\n \"ht\": \"/__l5e/assets-v1/93dd3f9c-8267-4f4e-b292-807cf0022c9e/tape-dust-ht.flac\",\n \"lt\": \"/__l5e/assets-v1/7a51ff67-62ec-408b-b6c3-4a0cae248eaf/tape-dust-lt.flac\",\n \"mt\": \"/__l5e/assets-v1/ba3340c5-6ead-419a-836a-a041448f06da/tape-dust-mt.flac\",\n \"oh\": \"/__l5e/assets-v1/e924553d-ac9a-427e-a69a-2939032ee618/tape-dust-oh.flac\",\n \"perc\": \"/__l5e/assets-v1/abfad1e6-998b-47a8-8c98-6f511c151143/tape-dust-perc.flac\",\n \"rim\": \"/__l5e/assets-v1/c86262d8-9711-41d4-b866-19a1ffcaf443/tape-dust-rim.flac\",\n \"sd\": \"/__l5e/assets-v1/2d1090cf-0284-4c33-9ba2-430c5c7b4730/tape-dust-sd.flac\"\n }\n },\n \"hard-cell\": {\n \"name\": \"Hard Cell\",\n \"blurb\": \"Overdriven and bit-crushed. Industrial techno with no headroom left.\",\n \"family\": \"Character\",\n \"credit\": \"Synthesised for Squelchy\",\n \"license\": \"CC0 1.0 / public domain \u2014 free to use, no attribution required\",\n \"licenseUrl\": \"https://creativecommons.org/publicdomain/zero/1.0/\",\n \"voices\": {\n \"bd\": \"/__l5e/assets-v1/d8f1c5cf-8e07-4a1e-a519-d7f69781329b/hard-cell-bd.flac\",\n \"ch\": \"/__l5e/assets-v1/c3275e9a-dd79-4ac8-b4b9-84ebe25b5529/hard-cell-ch.flac\",\n \"clap\": \"/__l5e/assets-v1/160a5d2c-01e0-49da-a998-149a0cf08317/hard-cell-clap.flac\",\n \"cym\": \"/__l5e/assets-v1/910f3623-0209-439f-9e34-0c0f842bc78f/hard-cell-cym.flac\",\n \"ht\": \"/__l5e/assets-v1/36f5b37b-9d44-49b8-a57b-bf5d2a1aa523/hard-cell-ht.flac\",\n \"lt\": \"/__l5e/assets-v1/6065e512-578b-477f-88d9-49b3ccccacea/hard-cell-lt.flac\",\n \"mt\": \"/__l5e/assets-v1/4e33c147-b8da-4b03-abca-4fd254d5006d/hard-cell-mt.flac\",\n \"oh\": \"/__l5e/assets-v1/3e5b3bce-f21b-4ecb-8f28-375ce871427f/hard-cell-oh.flac\",\n \"perc\": \"/__l5e/assets-v1/ab27e781-3d41-4e04-8f44-f7a568543586/hard-cell-perc.flac\",\n \"rim\": \"/__l5e/assets-v1/ea2989c5-2354-4574-ae38-4786deeee151/hard-cell-rim.flac\",\n \"sd\": \"/__l5e/assets-v1/5bd3dca9-bdb7-4618-8e0b-9ed1c0b062c7/hard-cell-sd.flac\"\n }\n },\n \"rx5-fm\": {\n \"name\": \"Yamaha RX5\",\n \"blurb\": \"FM percussion \u2014 glassy, bell-like, unmistakably late-eighties digital.\",\n \"family\": \"Digital\",\n \"credit\": \"MckAudio RX5 sample pack, dedicated to the public domain (CC0)\",\n \"license\": \"CC0 1.0 / public domain \u2014 free to use, no attribution required\",\n \"licenseUrl\": \"https://creativecommons.org/publicdomain/zero/1.0/\",\n \"voices\": {\n \"bd\": \"/__l5e/assets-v1/22b27f9f-d301-48e2-a0e4-e6b6e538ec31/rx5-fm-bd.flac\",\n \"ch\": \"/__l5e/assets-v1/236fb4f5-7d2a-48c0-be18-bc3777a6be91/rx5-fm-ch.flac\",\n \"clap\": \"/__l5e/assets-v1/58402fc0-996c-4577-9074-bb40b585c26e/rx5-fm-clap.flac\",\n \"cym\": \"/__l5e/assets-v1/d3e6ba9b-a2b8-4467-8923-97594723720e/rx5-fm-cym.flac\",\n \"ht\": \"/__l5e/assets-v1/a5edef5d-7861-4b3a-99bc-10ece111ca64/rx5-fm-ht.flac\",\n \"lt\": \"/__l5e/assets-v1/7151d30d-fe90-4ac5-9c9f-e91a808a1efa/rx5-fm-lt.flac\",\n \"mt\": \"/__l5e/assets-v1/46119925-9ecd-431a-94ee-2135c8ce4382/rx5-fm-mt.flac\",\n \"oh\": \"/__l5e/assets-v1/9fe4938f-fda7-43f8-84c6-c53325fd674c/rx5-fm-oh.flac\",\n \"perc\": \"/__l5e/assets-v1/1aa471d4-4737-45e6-9070-6301892dcdfa/rx5-fm-perc.flac\",\n \"rim\": \"/__l5e/assets-v1/2b0409a0-1aa6-41a4-9593-553247a2e624/rx5-fm-rim.flac\",\n \"sd\": \"/__l5e/assets-v1/3d9c426c-7783-4106-940f-1e6b6405bdd5/rx5-fm-sd.flac\"\n }\n },\n \"micro-click\": {\n \"name\": \"Micro Click\",\n \"blurb\": \"Clicks, ticks and pops. Minimal and micro-house, nothing sustains.\",\n \"family\": \"Digital\",\n \"credit\": \"Synthesised for Squelchy\",\n \"license\": \"CC0 1.0 / public domain \u2014 free to use, no attribution required\",\n \"licenseUrl\": \"https://creativecommons.org/publicdomain/zero/1.0/\",\n \"voices\": {\n \"bd\": \"/__l5e/assets-v1/58e3ce80-d300-47c6-8d79-52b00376550f/micro-click-bd.flac\",\n \"ch\": \"/__l5e/assets-v1/1c12e400-5c5f-4aae-b006-5a3fe3c6ef2c/micro-click-ch.flac\",\n \"clap\": \"/__l5e/assets-v1/b1f402f6-a85d-421b-9684-4b78719726d5/micro-click-clap.flac\",\n \"cym\": \"/__l5e/assets-v1/fe501055-43d7-427f-9ab4-5efd0423292e/micro-click-cym.flac\",\n \"ht\": \"/__l5e/assets-v1/3aab93cb-cd84-4600-a3e5-458fa74a2a86/micro-click-ht.flac\",\n \"lt\": \"/__l5e/assets-v1/b09a0d61-c9a2-4b31-b0f2-10d3c10ef83c/micro-click-lt.flac\",\n \"mt\": \"/__l5e/assets-v1/988e7a56-e914-43ad-aff1-71ec3a04b8e4/micro-click-mt.flac\",\n \"oh\": \"/__l5e/assets-v1/122a3f93-4542-471b-b390-996665248653/micro-click-oh.flac\",\n \"perc\": \"/__l5e/assets-v1/cae413d7-a68c-411a-a4b4-b7c20a83946d/micro-click-perc.flac\",\n \"rim\": \"/__l5e/assets-v1/41922292-1c6e-4bef-ac8e-fa1ce09eefca/micro-click-rim.flac\",\n \"sd\": \"/__l5e/assets-v1/6218ccdd-cba1-466e-af8b-665d7a2d4640/micro-click-sd.flac\"\n }\n },\n \"deep-analogue\": {\n \"name\": \"Deep Analogue\",\n \"blurb\": \"Long sub kick, soft snare, warm hats. Deep house at three in the morning.\",\n \"family\": \"Acoustic\",\n \"credit\": \"Synthesised for Squelchy\",\n \"license\": \"CC0 1.0 / public domain \u2014 free to use, no attribution required\",\n \"licenseUrl\": \"https://creativecommons.org/publicdomain/zero/1.0/\",\n \"voices\": {\n \"bd\": \"/__l5e/assets-v1/93c55e12-44f1-4cf9-8b19-82833257a68f/deep-analogue-bd.flac\",\n \"ch\": \"/__l5e/assets-v1/7c881111-83d8-4c1a-b4af-4f09d2a09f4b/deep-analogue-ch.flac\",\n \"clap\": \"/__l5e/assets-v1/e8b67bb8-8f7f-4b87-9ee4-d9cb7bc43efe/deep-analogue-clap.flac\",\n \"cym\": \"/__l5e/assets-v1/b329f9e1-3eb0-471c-b7c7-8ad7f639323f/deep-analogue-cym.flac\",\n \"ht\": \"/__l5e/assets-v1/a381a6b5-fd09-4fa6-b88e-86a29b8f25d9/deep-analogue-ht.flac\",\n \"lt\": \"/__l5e/assets-v1/c9ebc90a-20aa-4f76-9e79-f440258d4bac/deep-analogue-lt.flac\",\n \"mt\": \"/__l5e/assets-v1/5e1b803c-748e-4f09-bed7-c7b4511dc8b0/deep-analogue-mt.flac\",\n \"oh\": \"/__l5e/assets-v1/289d67f2-6d55-4a04-8607-302442465e81/deep-analogue-oh.flac\",\n \"perc\": \"/__l5e/assets-v1/8ef1f592-a3a4-45a5-9ea4-80362953aee4/deep-analogue-perc.flac\",\n \"rim\": \"/__l5e/assets-v1/102a1c23-6e5f-468e-95c8-e414ce849884/deep-analogue-rim.flac\",\n \"sd\": \"/__l5e/assets-v1/9be98c57-13c4-4337-bb2f-53c0b2ff7150/deep-analogue-sd.flac\"\n }\n }\n} as const);\nexport type SampleSetId = keyof typeof SampleSets;\n", "import type { Component } from 'solid-js';\nimport type { BaseModule, Cable, Position } from '@/types/synth';\n\n/** Self-contained example patch living next to each module.\n * Generic param M defaults to BaseModule for the descriptor interface,\n * but example files use TypedExample (= ModuleExample<SynthModule>)\n * for compile-time param checking. */\nexport interface ModuleExample<M extends BaseModule = BaseModule> {\n id: string;\n name: string;\n description: string;\n modules: M[];\n cables: Cable[];\n}\n\n/** Props passed to every module content component. */\nexport interface ModuleContentProps<T extends BaseModule = BaseModule> {\n module: T;\n updateParam: (param: string, value: number | string | boolean | number[] | boolean[][]) => void;\n cables?: Cable[];\n connectedOutputModuleId?: string | null;\n}\n\n/** Description pair used for tooltips/info bar. */\nexport interface Description {\n short: string;\n long: string;\n}\n\n/** Measurement unit of a param value \u2014 part of the signal contract, not human\n * prose, so it survives library stripping and shows up in generated docs.\n *\n * Two pitch-space units exist on purpose. They share a ruler (1 = one\n * semitone, 12 = one octave) but not a datum:\n * - `semitone` is an OFFSET from wherever the target already is (transpose,\n * detune, modulation depth).\n * - `note` is an ABSOLUTE key position on the MIDI datum (69 = A4).\n * Feeding a `note` into a `semitone` slot shifts the target by the note\n * number itself \u2014 note 60 into a \u00B112 transpose knob is five octaves. */\nexport const PARAM_UNITS = [\n 'Hz', // cycles per second\n 'ms', // milliseconds\n 's', // seconds\n 'semitone', // relative pitch offset (12 = one octave)\n 'cents', // 1/100 semitone, relative\n 'note', // absolute key position, MIDI datum (69 = A4)\n 'factor', // dimensionless multiplier: 0.5 = half wet, 5 = \u00D75 into the clipper\n 'dB', // decibels\n] as const;\n\nexport type ParamUnit = (typeof PARAM_UNITS)[number];\n\n/** Slugs whose meaning is the same in every module, pinned to one unit.\n * The param-units test fails any drift (a `note` param tagged in Hz, a\n * `frequency` param tagged in semitones, \u2026). Slugs whose meaning depends on\n * the module (`depth`, `amount`, `gain`) are deliberately absent: they only\n * have to carry *a* unit. */\nexport const UNIT_BY_SLUG = {\n frequency: 'Hz',\n time: 's',\n attack: 's',\n decay: 's',\n release: 's',\n sustain: 'factor',\n mix: 'factor',\n feedback: 'factor',\n damping: 'factor',\n tone: 'factor',\n drive: 'factor',\n note: 'note',\n detune: 'semitone',\n transpose: 'semitone',\n} as const satisfies Record<string, ParamUnit>;\n\n/** Single source of truth for one user-facing setting (plan \u00A72).\n * Knobs read range/scale/label from it, createModule defaults come from\n * `default`, hover tips derive from label+short+long, and the library build\n * generates docs + param types from it. Doc-only text (label, short,\n * long) is stripped from the library runtime; `unit` is kept. */\nexport interface ParamSpec {\n /** Optional convenience for modules whose panel maps 1:1 onto params.\n * When the UI diverges (connection-dependent labels/ranges), omit it and\n * keep labels + hover tips in the UI layer (see lfo). Never shipped in docs. */\n label?: string;\n default: number | string | boolean;\n /** One-shot actions are not params: they are rising edges on a gate port\n * (panel buttons use `pulse()` from src/lib/dsp/pulse.ts). */\n kind?: 'number' | 'enum';\n min?: number;\n max?: number;\n scale?: 'linear' | 'log' | 'sqrt';\n unit?: string;\n options?: readonly string[];\n /** Backing AudioParam, resolved like ports: key in the createNodes record\n * + AudioParam property (or worklet parameter) name. Declare ONLY when the\n * param value is written to that AudioParam 1:1 \u2014 no conversion, no split.\n * The library exposes it as `instance.params.<key>` for native automation. */\n node?: string;\n field?: string;\n short: string;\n long: string;\n}\n\n/** Default values for createModule, derived from a params schema. */\nexport function paramDefaults<P extends Record<string, ParamSpec>>(params: P): { [K in keyof P]: P[K]['default'] } {\n const out = {} as Record<string, ParamSpec['default']>;\n for (const k in params) out[k] = params[k].default;\n return out as { [K in keyof P]: P[K]['default'] };\n}\n\n/** Static port definition \u2014 constant metadata, NOT instance state. */\nexport interface PortDefinition {\n type: 'input' | 'output' | 'modulation' | 'trigger';\n label: string;\n name: string;\n desc: string;\n /** Key in the createNodes record that this port maps to.\n * Omit for trigger ports which are routed by the engine without audio nodes. */\n node?: string;\n /** For modulation ports: the AudioParam property name on the target node (e.g. 'frequency', 'gain'). */\n field?: string;\n /** Signal semantics \u2014 determines port and cable colour.\n * 'audio' = emerald, 'pitch' = amber, 'gate' = orange, 'modulation' = violet. */\n signal: 'audio' | 'pitch' | 'gate' | 'modulation';\n}\n\n/**\n * Complete descriptor for a single module type.\n *\n * Generic parameters:\n * - T: the module's state interface\n * - N: the exact record returned by createNodes (inferred by defineDescriptor)\n *\n * Ports are defined as static metadata \u2014 module instances do NOT carry ports.\n */\nexport interface ModuleDescriptor<\n T extends BaseModule = BaseModule,\n N extends Record<string, AudioNode> = Record<string, AudioNode>,\n> {\n\n // Identity\n type: T['type'];\n name: string;\n icon: string;\n color: string;\n\n // Categorisation\n categories: string[];\n\n // Layout\n width: number;\n height: number;\n\n // Static port definitions \u2014 keyed by slug (e.g. 'in', 'out', 'modFreq')\n ports: Record<string, PortDefinition>;\n\n // Factory \u2014 returns pure state (no ports array)\n createModule(id: string, position: { x: number; y: number }): T;\n\n // Audio engine \u2014 returns a port-keyed record of AudioNodes\n createNodes(ctx: AudioContext, module: T): N;\n updateParam(nodes: N, module: T, param: string, value: number | string | boolean | number[] | boolean[][], when?: number): void;\n\n // Connection hooks \u2014 called when a cable is connected/disconnected to this module's INPUT port.\n // Return true if the module handled the connection itself (engine skips default routing).\n onConnect?(nodes: N, module: T, portId: string, sourceNode: AudioNode): boolean;\n onDisconnect?(nodes: N, module: T, portId: string, sourceNode: AudioNode): boolean;\n\n // Output connection hooks \u2014 called when a cable is connected/disconnected FROM this module's OUTPUT port.\n // Allows the source module to react (e.g. clock registering downstream modules).\n onOutputConnect?(module: T, fromPortId: string, toModule: BaseModule, toPortId: string): void;\n onOutputDisconnect?(module: T, fromPortId: string, toModule: BaseModule, toPortId: string): void;\n\n // Clocked module hooks \u2014 type-safe on N and T (all optional)\n /** Called by the scheduler on each tick. portId is the destination port slug that received the tick.\n * update(key, value) writes immediately; update(key, value, when) defers until audio-playback time. */\n onTick?(ctx: AudioContext, nodes: N, module: T, when: number, update: (key: string, value: any, at?: number) => void, portId: string): void;\n /** Called on reset trigger \u2014 resets step counter to 0. */\n onReset?(module: T): void;\n /** Called when playback is stopped \u2014 clean up outputs (e.g. gate off). */\n onStop?(nodes: N, module?: T): void;\n /** Called when the module is removed \u2014 clean up timers, worklets, etc. */\n dispose?(nodes: N): void;\n\n // UI\n Content: Component<ModuleContentProps<T>>;\n\n // Example patch (loaded via right-click \"Show Example\")\n example: ModuleExample;\n\n // Documentation\n description: Description;\n /** Hover tips keyed by knob label. Derived from `params` when present. */\n controlDescriptions: Record<string, Description>;\n /** Settings schema \u2014 single source of truth for ranges, defaults, docs. */\n params?: Record<string, ParamSpec>;\n}\n\n/** Identity helper \u2013 infers both T and N from the inline descriptor. */\nexport function defineDescriptor<T extends BaseModule, N extends Record<string, AudioNode>>(\n desc: Omit<ModuleDescriptor<T, N>, 'controlDescriptions'> & { controlDescriptions?: Record<string, Description> },\n): ModuleDescriptor<T, N> {\n if (desc.params && !desc.controlDescriptions) {\n // Enum params are driven by buttons, not hoverable knobs \u2014 no hover tip.\n const cd: Record<string, Description> = {};\n for (const p of Object.values(desc.params)) {\n if (p.kind !== 'enum' && p.label) cd[p.label] = { short: p.short, long: p.long };\n }\n return { ...desc, controlDescriptions: cd };\n }\n return desc as ModuleDescriptor<T, N>;\n}\n", "/**\n * Central worklet registry.\n *\n * All AudioWorklet processors are registered once during audioEngine.initialize().\n * Module descriptors call the factory functions synchronously.\n *\n */\n\n\n/**\n * One registration promise per context.\n *\n * A `WeakMap` rather than a single slot because the QA harness renders into\n * short-lived `OfflineAudioContext`s: each one needs its own `addModule`\n * calls (processor definitions live in the context's worklet global scope),\n * and re-adding a module to a context that already has it would throw\n * \"a processor with this name is already registered\". Weak keys let the dead\n * offline contexts and their promises be collected.\n */\nconst registrations = new WeakMap<BaseAudioContext, Promise<void>>();\n\n/** Register every worklet processor. Call once per context.\n * Safe to call concurrently \u2014 subsequent calls return the same promise.\n * Accepts an `OfflineAudioContext` (patch audit) as well as a live one. */\n\n\n// \u2500\u2500\u2500 Node factories (synchronous after registration) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n// Processor names are internal IDs registered in each worklet file.\n\n// Control-signal worklets (envelopes, V/Oct mappers, followers, dividers,\n// crushers) write channel 0 only, so their output channel count is pinned to\n// [1]. Without the pin, WebAudio derives the count from the *input* \u2014 and a\n// stereo source in the trigger fan (even one merely scheduled in the\n// lookahead queue) flips the output to 2ch mid-render. Ch0-only writers then\n// deliver [x, 0] to AudioParams, which downmix to x/2: every envelope-driven\n// VCA and cutoff silently HALVED whenever the next clock tick was queued\n// (pass 12 root cause \u2014 8 Hz pluck tails measured \u22126.02 dB).\n\nexport function createVoctFreqNode(ctx: AudioContext): AudioWorkletNode {\n return new AudioWorkletNode(ctx, 'map-voct-to-freq', {\n numberOfInputs: 1,\n numberOfOutputs: 1,\n outputChannelCount: [1],\n });\n}\n\nexport function createVoctPeriodNode(ctx: AudioContext): AudioWorkletNode {\n return new AudioWorkletNode(ctx, 'map-voct-to-period', {\n numberOfInputs: 1,\n numberOfOutputs: 1,\n outputChannelCount: [1],\n });\n}\n\nexport function createAdsrNode(\n ctx: AudioContext,\n init?: { attack?: number; decay?: number; sustain?: number; release?: number },\n): AudioWorkletNode {\n const node = new AudioWorkletNode(ctx, 'adsr-envelope', {\n numberOfInputs: 1,\n numberOfOutputs: 1,\n outputChannelCount: [1],\n });\n if (init) {\n for (const [k, v] of Object.entries(init)) {\n if (v === undefined) continue;\n const p = node.parameters.get(k);\n if (p) p.value = v;\n }\n }\n return node;\n}\n\nexport function createFormantNode(ctx: AudioContext): AudioWorkletNode {\n return new AudioWorkletNode(ctx, 'formant-table', {\n numberOfInputs: 1,\n numberOfOutputs: 1,\n outputChannelCount: [5],\n });\n}\n\nexport function createBitcrusherNode(ctx: AudioContext): AudioWorkletNode {\n return new AudioWorkletNode(ctx, 'bitcrusher', {\n numberOfInputs: 1,\n numberOfOutputs: 1,\n outputChannelCount: [1],\n });\n}\n\nexport function createSubOctaveNode(ctx: AudioContext): AudioWorkletNode {\n return new AudioWorkletNode(ctx, 'freq-divider', {\n numberOfInputs: 1,\n numberOfOutputs: 1,\n outputChannelCount: [1],\n });\n}\n\nexport function createEnvFollowerNode(ctx: AudioContext): AudioWorkletNode {\n return new AudioWorkletNode(ctx, 'env-follower', {\n numberOfInputs: 1,\n numberOfOutputs: 1,\n outputChannelCount: [1],\n });\n}\n\nexport function createWaveshaperNode(ctx: AudioContext): AudioWorkletNode {\n return new AudioWorkletNode(ctx, 'waveshaper', {\n numberOfInputs: 1,\n numberOfOutputs: 1,\n outputChannelCount: [1],\n });\n}\n\nexport function createScopeNode(ctx: AudioContext): AudioWorkletNode {\n return new AudioWorkletNode(ctx, 'scope-ringbuf', {\n numberOfInputs: 1,\n numberOfOutputs: 0,\n });\n}\n\nexport function createGlideNode(ctx: AudioContext): AudioWorkletNode {\n return new AudioWorkletNode(ctx, 'glide', {\n numberOfInputs: 2,\n numberOfOutputs: 1,\n outputChannelCount: [1],\n });\n}\n\nexport function createTapeStopNode(ctx: AudioContext, time = 0.5, mix = 1): AudioWorkletNode {\n return new AudioWorkletNode(ctx, 'tape-stop', {\n numberOfInputs: 2,\n numberOfOutputs: 1,\n outputChannelCount: [2],\n channelCount: 2,\n channelCountMode: 'explicit',\n parameterData: { time, mix },\n });\n}\n\nexport function createSpringReverbNode(\n ctx: AudioContext,\n params: { decay: number; tone: number; drip: number },\n): AudioWorkletNode {\n return new AudioWorkletNode(ctx, 'spring-reverb', {\n numberOfInputs: 2,\n numberOfOutputs: 1,\n outputChannelCount: [2],\n channelCount: 2,\n channelCountMode: 'explicit',\n parameterData: { decay: params.decay, tone: params.tone, drip: params.drip },\n });\n}\n\nexport function createFdnReverbNode(\n ctx: BaseAudioContext,\n opts: { rt60: number; damping: number; size?: number; feedbackCeiling?: number },\n): AudioWorkletNode {\n return new AudioWorkletNode(ctx as AudioContext, 'fdn-reverb', {\n numberOfInputs: 1,\n numberOfOutputs: 1,\n // Stereo tank: L/R in (mono upmixes to L=R \u2192 identical mid), L/R out.\n outputChannelCount: [2],\n channelCount: 2,\n channelCountMode: 'explicit',\n parameterData: { rt60: opts.rt60, damping: opts.damping },\n processorOptions: {\n size: opts.size ?? 1,\n feedbackCeiling: opts.feedbackCeiling ?? 0.97,\n },\n });\n}\n\nexport function createFreqShifterNode(ctx: AudioContext, shift = 0): AudioWorkletNode {\n return new AudioWorkletNode(ctx, 'freq-shifter', {\n numberOfInputs: 1,\n numberOfOutputs: 1,\n outputChannelCount: [1],\n parameterData: { shift },\n });\n}\n\n/** Frequency divider with the extra raw + pitch-tracking outputs the octaver needs. */\nexport function createOctaverDividerNode(ctx: AudioContext): AudioWorkletNode {\n return new AudioWorkletNode(ctx, 'freq-divider', {\n numberOfInputs: 1,\n numberOfOutputs: 3,\n outputChannelCount: [1, 2, 1],\n });\n}\n\nexport function createPitchShifterNode(ctx: AudioContext, semitones = 12): AudioWorkletNode {\n return new AudioWorkletNode(ctx, 'pitch-shifter', {\n numberOfInputs: 1,\n numberOfOutputs: 1,\n outputChannelCount: [1],\n channelCount: 1,\n channelCountMode: 'explicit',\n parameterData: { semitones },\n });\n}\n\nexport function createVcaNode(ctx: AudioContext, gain = 0.5, cvAmount = 1): AudioWorkletNode {\n return new AudioWorkletNode(ctx, 'vca', {\n numberOfInputs: 1,\n numberOfOutputs: 1,\n parameterData: { gain, cvAmount },\n });\n}\n\n/**\n * Master-bus brickwall limiter (engine-level, one per AudioContext).\n * Stereo-linked, 1.5 ms lookahead \u2014 see `master-limiter.ts`.\n */\nexport function createMasterLimiterNode(ctx: AudioContext): AudioWorkletNode {\n return new AudioWorkletNode(ctx, 'master-limiter', {\n numberOfInputs: 1,\n numberOfOutputs: 1,\n channelCount: 2,\n channelCountMode: 'explicit',\n channelInterpretation: 'speakers',\n outputChannelCount: [2],\n });\n}\n\n/**\n * True transistor-ladder lowpass (24 dB/oct, global tanh feedback,\n * self-oscillates at resonance \u2265 1.0). See `ladder-filter.ts`.\n * `cutoff` is driven in Hz by a map-voct-to-freq worklet output;\n * `resonance` is normalized 0\u20131 of full travel so res CV cables can\n * connect straight to the param (+1 CV = full range).\n */\nexport function createLadderFilterNode(\n ctx: AudioContext,\n init?: { resonance?: number; drive?: number },\n): AudioWorkletNode {\n return new AudioWorkletNode(ctx, 'ladder-filter', {\n numberOfInputs: 1,\n numberOfOutputs: 1,\n parameterData: {\n cutoff: 0,\n resonance: init?.resonance ?? 0.6,\n drive: init?.drive ?? 0.3,\n },\n });\n}\n\n/**\n * Resonance CV \u2192 BiquadFilter.Q mapper (true-Q domain in every filter mode;\n * LP/HP get the dB conversion the Web Audio spec expects). See `map-res.ts`.\n */\nexport function createMapResNode(\n ctx: AudioContext,\n init?: { base?: number; dbOut?: boolean; qMin?: number; qMax?: number; cvScale?: number },\n): AudioWorkletNode {\n const qMin = init?.qMin ?? 0.1;\n const qMax = init?.qMax ?? 20;\n return new AudioWorkletNode(ctx, 'map-res', {\n numberOfInputs: 1,\n numberOfOutputs: 1,\n parameterData: {\n base: init?.base ?? 1,\n cvScale: init?.cvScale ?? qMax - qMin,\n qMin,\n qMax,\n dbOut: init?.dbOut === false ? 0 : 1,\n },\n });\n}\n\n/** COMB module: recirculating comb with single-sample feedback (native\n * DelayNode loops add a render quantum and detune the comb \u2014 see the\n * worklet header). `period` is driven by map-voct-to-period. */\n/** `channels` is pinned, never derived from the input (see the pin note\n * above): COMB is a mono voice (1), DELAY keeps stereo sources stereo (2). */\nexport function createCombFilterNode(ctx: BaseAudioContext, feedback = 0.7, maxPeriod = 0.1, channels: 1 | 2 = 1): AudioWorkletNode {\n return new AudioWorkletNode(ctx as AudioContext, 'comb-filter', {\n numberOfInputs: 1,\n numberOfOutputs: 1,\n outputChannelCount: [channels],\n channelCount: channels,\n channelCountMode: 'explicit',\n channelInterpretation: 'speakers',\n parameterData: { period: 0, feedback },\n processorOptions: { maxPeriod },\n });\n}\n\n/** FLANGER wet path: LFO-swept delay with single-sample feedback (the native\n * loop hid a render quantum, detuning the regeneration comb against the\n * dry+wet notches \u2014 see the worklet header). Dry/wet mix stays native. */\nexport function createFlangerNode(\n ctx: BaseAudioContext,\n opts: { rate: number; depth: number; feedback: number },\n): AudioWorkletNode {\n return new AudioWorkletNode(ctx as AudioContext, 'flanger', {\n numberOfInputs: 1,\n numberOfOutputs: 1,\n parameterData: { rate: opts.rate, depth: opts.depth, feedback: opts.feedback },\n });\n}\n\n\n/** Tape echo: in-loop saturation + damping + wow/flutter, sample-exact grid. */\nexport function createTapeDelayNode(\n ctx: BaseAudioContext,\n opts: { time: number; feedback: number; saturation: number; flutter: number },\n): AudioWorkletNode {\n return new AudioWorkletNode(ctx as AudioContext, 'tape-delay', {\n numberOfInputs: 1,\n numberOfOutputs: 1,\n parameterData: { ...opts },\n });\n}\n\n/** Ping-pong: cross-fed L/R delay lines with exact tap grid. Output 0 = L tap, 1 = R tap. */\nexport function createPingPongNode(\n ctx: BaseAudioContext,\n opts: { time: number; feedback: number },\n): AudioWorkletNode {\n return new AudioWorkletNode(ctx as AudioContext, 'ping-pong', {\n numberOfInputs: 1,\n numberOfOutputs: 2,\n parameterData: { ...opts },\n });\n}\n", "// @ts-nocheck \u2014 generated by scripts/lib/build.ts\nimport type { BaseModule, Position } from '@/types/synth';\n\nimport { defineDescriptor, paramDefaults } from '@/modules/ModuleDescriptor';\nimport { createAdsrNode, createVoctFreqNode } from '@/worklets';\n\nexport interface Filter303Module extends BaseModule {\n type: '303-filter';\n /** Cutoff as a note (69 = 440 Hz), driving the V/OCT worklet 1:1. */\n note: number;\n resonance: number;\n envMod: number;\n accent: number;\n decay: number;\n}\n\n// \u2500\u2500\u2500 PARAMS \u2014 the signal contract (no UI knowledge) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nconst params = {\n note: { node: '_cutoffVoct', field: 'transpose', unit: 'note', default: 67, min: 15, max: 135, },\n // Split across two cascaded biquads' Q (0.7x / 0.4x) \u2014 not a single\n // AudioParam \u2014 so this stays set-only.\n resonance: { unit: 'factor', default: 8, min: 0, max: 15, scale: 'sqrt', },\n envMod: { unit: 'factor', default: 0.7, min: 0, max: 1, },\n accent: { unit: 'factor', default: 0.5, min: 0, max: 1, },\n decay: { node: 'envSmoother', field: 'decay', unit: 's', default: 0.2, min: 0.05, max: 1, scale: 'log', },\n} satisfies Record<string, ParamSpec>;\n\n// \u2500\u2500\u2500 UI \u2014 presentation layer (stripped from the library) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n\n// \u2500\u2500\u2500 DESCRIPTOR \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport const filter303Descriptor = /* @__PURE__ */ defineDescriptor({\n type: '303-filter',\n params,\n\n ports: {\n 'in': { type: 'input', signal: 'audio', node: 'input', },\n 'out': { type: 'output', signal: 'audio', node: 'output', },\n 'trigger': { type: 'input', signal: 'gate', node: 'trigInput', },\n 'modFreq': { type: 'modulation', signal: 'modulation', node: '_cutoffVoct', },\n },\n\n createModule(id: string, position: Position): Filter303Module {\n return { id, type: '303-filter', position, ...paramDefaults(params) };\n },\n\n createNodes(ctx, module) {\n const input = ctx.createGain();\n\n // Two cascaded lowpass filters for 4-pole (24dB/oct) response\n const filter1 = ctx.createBiquadFilter();\n filter1.type = 'lowpass';\n filter1.frequency.value = 0; // driven by voct\n filter1.Q.value = module.resonance * 0.7; // split Q across stages\n const filter2 = ctx.createBiquadFilter();\n filter2.type = 'lowpass';\n filter2.frequency.value = 0;\n filter2.Q.value = module.resonance * 0.4;\n\n // Accent VCA \u2014 boosts output level on accented notes\n const accentVCA = ctx.createGain();\n accentVCA.gain.value = 1;\n const output = ctx.createGain();\n\n // V/Oct cutoff\n const _cutoffVoct = createVoctFreqNode(ctx);\n _cutoffVoct.parameters.get('transpose')!.value = module.note;\n\n const _cutoffBase = ctx.createConstantSource();\n _cutoffBase.offset.value = 0;\n _cutoffBase.start();\n\n _cutoffBase.connect(_cutoffVoct);\n _cutoffVoct.connect(filter1.frequency);\n _cutoffVoct.connect(filter2.frequency);\n\n // Trigger envelope \u2192 voct input (semitones).\n //\n // The TB-303's envelope is a snappy attack into an exponential decay with\n // no sustain stage. Clock and sequencer gate outputs are single-sample\n // impulses, so this runs the shared ADSR worklet, which latches a rising\n // edge for one full attack + decay \u2014 a smoothing filter fed by a lone\n // sample would only ever produce a few thousandths of an envelope.\n const trigInput = ctx.createGain();\n\n const envSmoother = createAdsrNode(ctx, {\n attack: 0.003,\n decay: module.decay,\n sustain: 0,\n release: 0.01,\n });\n\n // Envelope depth in semitones: envMod * (1 + accent) * 36\n const envDepth = ctx.createGain();\n envDepth.gain.value = module.envMod * (1 + module.accent) * 36;\n\n // Accent envelope \u2192 VCA boost (adds ~6dB on full accent)\n const accentEnvGain = ctx.createGain();\n accentEnvGain.gain.value = module.accent * 0.5;\n\n input.connect(filter1);\n filter1.connect(filter2);\n filter2.connect(accentVCA);\n accentVCA.connect(output);\n\n trigInput.connect(envSmoother);\n envSmoother.connect(envDepth);\n envDepth.connect(_cutoffVoct); // semitones \u2192 voct input\n\n // Route envelope to accent VCA too\n envSmoother.connect(accentEnvGain);\n accentEnvGain.connect(accentVCA.gain);\n\n return { input, output, trigInput, filter1, filter2, accentVCA, accentEnvGain, envSmoother, envDepth, _cutoffVoct, _cutoffBase };\n },\n\n updateParam(nodes, module, param, value) {\n switch (param) {\n case 'note':\n nodes._cutoffVoct.parameters.get('transpose')!.value = value as number;\n break;\n case 'resonance': {\n const q = value as number;\n nodes.filter1.Q.value = q * 0.7;\n nodes.filter2.Q.value = q * 0.4;\n break;\n }\n case 'envMod':\n nodes.envDepth.gain.value = (value as number) * (1 + module.accent) * 36;\n break;\n case 'accent': {\n const acc = value as number;\n nodes.envDepth.gain.value = module.envMod * (1 + acc) * 36;\n nodes.accentEnvGain.gain.value = acc * 0.5;\n break;\n }\n case 'decay': {\n const p = nodes.envSmoother.parameters.get('decay');\n if (p) p.value = value as number;\n break;\n }\n }\n },\n\n dispose(nodes) {\n nodes._cutoffBase.stop();\n },\n\n});\n", "import { defineModule } from '../../core';\nimport { filter303Descriptor } from './303-filter';\nimport type { AcidFilterParams, AcidFilterInputs, AcidFilterOutputs, AcidFilterProps } from './303-filter.types';\nimport adsr_envelope from '../worklet-src/adsr-envelope';\nimport map_voct_to_freq from '../worklet-src/map-voct-to-freq';\n\nexport const AcidFilter = /* @__PURE__ */ defineModule(filter303Descriptor, {\n worklets: {\n 'adsr-envelope': adsr_envelope,\n 'map-voct-to-freq': map_voct_to_freq,\n },\n}) as import('../../core').LibModule<AcidFilterParams, AcidFilterInputs, AcidFilterOutputs, AcidFilterProps>;\nexport type { AcidFilterParams, AcidFilterInputs, AcidFilterOutputs, AcidFilterProps };\n", "// @ts-nocheck \u2014 generated by scripts/lib/build.ts\n\nimport { BaseModule } from '@/types/synth';\n\nexport interface AutoPanModule extends BaseModule {\n type: 'auto-pan';\n rate: number;\n depth: number;\n shape: 'sine' | 'triangle' | 'square';\n}\nimport { defineDescriptor, paramDefaults } from '@/modules/ModuleDescriptor';\n\nconst shapes = ['sine', 'triangle', 'square'] as const;\n\n// \u2500\u2500\u2500 PARAMS \u2014 the signal contract (no UI knowledge) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nconst params = {\n rate: { node: 'lfo', field: 'frequency', unit: 'Hz', default: 2, min: 0.1, max: 10, },\n depth: { node: 'lfoGain', field: 'gain', unit: 'factor', default: 0.8, min: 0, max: 1, },\n shape: { kind: 'enum', options: shapes, default: 'sine', },\n} satisfies Record<string, ParamSpec>;\n\n// \u2500\u2500\u2500 UI \u2014 presentation layer (stripped from the library) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n\nexport const autoPanDescriptor = /* @__PURE__ */ defineDescriptor({\n type: 'auto-pan',\n params,\n\n ports: {\n 'in': { type: 'input', signal: 'audio', node: 'input', },\n 'out': { type: 'output', signal: 'audio', node: 'output', },\n 'modRate': { type: 'modulation', signal: 'modulation', node: 'lfo', field: 'frequency' },\n 'modDepth': { type: 'modulation', signal: 'modulation', node: 'lfoGain', field: 'gain' },\n },\n\n createModule(id, position) {\n return { id, type: 'auto-pan', position, ...paramDefaults(params) };\n },\n\n createNodes(ctx, module) {\n const input = ctx.createGain();\n const panner = ctx.createStereoPanner();\n const output = ctx.createGain();\n const lfo = ctx.createOscillator();\n const lfoGain = ctx.createGain();\n\n lfo.type = module.shape as OscillatorType;\n lfo.frequency.value = module.rate;\n lfoGain.gain.value = module.depth;\n lfo.connect(lfoGain);\n lfoGain.connect(panner.pan);\n lfo.start();\n\n input.connect(panner);\n panner.connect(output);\n\n return { input, output, lfo, lfoGain };\n },\n\n updateParam(nodes, _m, param, value) {\n if (param === 'rate') {\n nodes.lfo.frequency.value = value as number;\n } else if (param === 'depth') {\n nodes.lfoGain.gain.value = value as number;\n } else if (param === 'shape') {\n nodes.lfo.type = value as OscillatorType;\n }\n },\n\n dispose(nodes) {\n nodes.lfo.stop();\n },\n\n});\n", "import { defineModule } from '../../core';\nimport { autoPanDescriptor } from './auto-pan';\nimport type { AutoPanParams, AutoPanInputs, AutoPanOutputs, AutoPanProps } from './auto-pan.types';\n\n\nexport const AutoPan = /* @__PURE__ */ defineModule(autoPanDescriptor) as import('../../core').LibModule<AutoPanParams, AutoPanInputs, AutoPanOutputs, AutoPanProps>;\nexport type { AutoPanParams, AutoPanInputs, AutoPanOutputs, AutoPanProps };\n", "/**\n * Dry/wet mix as ONE AudioParam.\n *\n * A single ConstantSource carries the mix value (0 = dry, 1 = wet); native\n * nodes derive both gains from it at audio rate, so `mix` is automatable and\n * CV-modulatable like any native parameter, and stays exact under ramps.\n *\n * linear dry = 1 \u2212 mix, wet = mix \u00B7 wetScale\n * equal-power dry = cos(mix\u00B7\u03C0/2), wet = sin(mix\u00B7\u03C0/2) \u00B7 wetScale\n *\n * The returned ConstantSource is the node to register in createNodes\n * (conventionally `_mix`, param spec `{ node: '_mix', field: 'offset' }`);\n * hosts stop it on dispose like any other source.\n */\nexport type MixLaw = 'linear' | 'equal-power';\n\nconst CURVE_POINTS = 2049; // spans input \u22121\u20261; 1024 intervals over 0\u20261\n\nfunction lawCurve(fn: (m: number) => number): Float32Array<ArrayBuffer> {\n const c = new Float32Array(CURVE_POINTS);\n for (let i = 0; i < CURVE_POINTS; i++) {\n const x = -1 + (2 * i) / (CURVE_POINTS - 1);\n c[i] = fn(Math.min(1, Math.max(0, x)));\n }\n return c;\n}\n\nexport function createMix(\n ctx: BaseAudioContext,\n dry: GainNode,\n wet: GainNode,\n value: number,\n law: MixLaw,\n wetScale = 1,\n): ConstantSourceNode {\n const mix = ctx.createConstantSource();\n mix.offset.value = value;\n\n let toWet: AudioNode = mix;\n if (law === 'linear') {\n dry.gain.value = 1;\n const invert = ctx.createGain();\n invert.gain.value = -1;\n mix.connect(invert).connect(dry.gain);\n } else {\n dry.gain.value = 0;\n const cos = ctx.createWaveShaper();\n cos.curve = lawCurve((m) => Math.cos(m * 0.5 * Math.PI));\n const sin = ctx.createWaveShaper();\n sin.curve = lawCurve((m) => Math.sin(m * 0.5 * Math.PI));\n mix.connect(cos).connect(dry.gain);\n toWet = mix.connect(sin);\n }\n\n wet.gain.value = 0;\n if (wetScale !== 1) {\n const scale = ctx.createGain();\n scale.gain.value = wetScale;\n toWet = toWet.connect(scale);\n }\n toWet.connect(wet.gain);\n\n mix.start();\n return mix;\n}\n", "// @ts-nocheck \u2014 generated by scripts/lib/build.ts\nimport { createMix } from '@/lib/dsp/mix';\nimport { BaseModule } from '@/types/synth';\nimport { defineDescriptor, paramDefaults } from '@/modules/ModuleDescriptor';\nimport { createBitcrusherNode } from '@/worklets';\n\nexport interface BitcrusherModule extends BaseModule {\n type: 'bitcrusher';\n bits: number;\n rate: number;\n mix: number;\n}\n\n// \u2500\u2500\u2500 PARAMS \u2014 the signal contract (no UI knowledge) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nconst params = {\n bits: { node: 'crusher', field: 'bits', unit: 'factor', default: 8, min: 1, max: 16, },\n rate: { node: 'crusher', field: 'rate', unit: 'factor', default: 0.5, min: 0.01, max: 1, scale: 'log', },\n mix: { node: '_mix', field: 'offset', unit: 'factor', default: 1.0, min: 0, max: 1, },\n} satisfies Record<string, ParamSpec>;\n\n\n\n// \u2500\u2500\u2500 DESCRIPTOR \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport const bitcrusherDescriptor = /* @__PURE__ */ defineDescriptor({\n type: 'bitcrusher',\n params,\n\n\n ports: {\n 'in': { type: 'input', signal: 'audio', node: 'input', },\n 'out': { type: 'output', signal: 'audio', node: 'output', },\n },\n\n\n createModule(id, position) {\n return { id, type: 'bitcrusher', position, ...paramDefaults(params) };\n },\n\n createNodes(ctx, module) {\n const input = ctx.createGain();\n const output = ctx.createGain();\n const dryGain = ctx.createGain();\n const wetGain = ctx.createGain();\n\n const crusher = createBitcrusherNode(ctx);\n const cp = crusher.parameters as any;\n cp.get('bits').value = module.bits;\n cp.get('rate').value = module.rate;\n\n const _mix = createMix(ctx, dryGain, wetGain, module.mix, 'linear');\n\n input.connect(dryGain);\n input.connect(crusher);\n crusher.connect(wetGain);\n dryGain.connect(output);\n wetGain.connect(output);\n\n return { input, output, crusher, dryGain, wetGain, _mix };\n },\n\n updateParam(nodes, _m, param, value) {\n if (param === 'bits') {\n (nodes.crusher.parameters as any).get('bits').value = value as number;\n } else if (param === 'rate') {\n (nodes.crusher.parameters as any).get('rate').value = value as number;\n } else if (param === 'mix') {\n (nodes._mix as ConstantSourceNode).offset.value = value as number;\n }\n },\n\n});\n", "import { defineModule } from '../../core';\nimport { bitcrusherDescriptor } from './bitcrusher';\nimport type { BitcrusherParams, BitcrusherInputs, BitcrusherOutputs, BitcrusherProps } from './bitcrusher.types';\nimport bitcrusher from '../worklet-src/bitcrusher';\n\nexport const Bitcrusher = /* @__PURE__ */ defineModule(bitcrusherDescriptor, {\n worklets: {\n 'bitcrusher': bitcrusher,\n },\n}) as import('../../core').LibModule<BitcrusherParams, BitcrusherInputs, BitcrusherOutputs, BitcrusherProps>;\nexport type { BitcrusherParams, BitcrusherInputs, BitcrusherOutputs, BitcrusherProps };\n", "// @ts-nocheck \u2014 generated by scripts/lib/build.ts\nimport { BaseModule } from '@/types/synth';\n\nexport interface ChorusModule extends BaseModule {\n type: 'chorus';\n rate: number;\n depth: number;\n mix: number;\n}\nimport { defineDescriptor, paramDefaults } from '@/modules/ModuleDescriptor';\n\nconst params = {\n rate: { node: 'lfo', field: 'frequency', unit: 'Hz', default: 1.5, min: 0.1, max: 5, },\n depth: { unit: 'factor', default: 0.5, min: 0, max: 1, },\n mix: { node: '_mix', field: 'offset', unit: 'factor', default: 0.5, min: 0, max: 1, },\n} satisfies Record<string, ParamSpec>;\n\n\n\nexport const chorusDescriptor = /* @__PURE__ */ defineDescriptor({\n type: 'chorus',\n params,\n\n ports: {\n 'in': { type: 'input', signal: 'audio', node: 'input', },\n 'out': { type: 'output', signal: 'audio', node: 'output', },\n 'modRate': { type: 'modulation', signal: 'modulation', node: 'lfo', field: 'frequency' },\n 'modMix': { type: 'modulation', signal: 'modulation', node: '_mix', field: 'offset' },\n },\n\n createModule(id, position) {\n return { id, type: 'chorus', position, ...paramDefaults(params) };\n },\n\n createNodes(ctx, module) {\n const input = ctx.createGain();\n const output = ctx.createGain();\n const dryGain = ctx.createGain();\n const wetGain = ctx.createGain();\n const monoIn = ctx.createGain();\n monoIn.channelCount = 1;\n monoIn.channelCountMode = 'explicit';\n monoIn.channelInterpretation = 'speakers';\n const delayL = ctx.createDelay(0.1);\n const delayR = ctx.createDelay(0.1);\n const lfo = ctx.createOscillator();\n const lfoGain = ctx.createGain();\n const lfoInv = ctx.createGain();\n const merger = ctx.createChannelMerger(2);\n delayL.delayTime.value = 0.02;\n delayR.delayTime.value = 0.02;\n\n // Mix as one honest AudioParam: this module's law (dry = 1 \u2212 mix\u00B70.5,\n // wet = mix) isn't either law createMix ships, so it's built the same\n // way createMix does internally \u2014 one ConstantSource whose offset IS\n // the mix param, intrinsic dry gain of 1 with a \u22120.5 tap from the\n // source, wet gain 0 with a direct tap \u2014 rather than forcing a\n // different loudness curve onto the module.\n const _mix = ctx.createConstantSource();\n _mix.offset.value = module.mix;\n dryGain.gain.value = 1;\n const dryTap = ctx.createGain();\n dryTap.gain.value = -0.5;\n _mix.connect(dryTap).connect(dryGain.gain);\n wetGain.gain.value = 0;\n _mix.connect(wetGain.gain);\n _mix.start();\n\n lfo.type = 'sine';\n lfo.frequency.value = module.rate;\n lfoGain.gain.value = module.depth * 0.01;\n lfoInv.gain.value = -1;\n lfo.connect(lfoGain);\n lfoGain.connect(delayL.delayTime);\n lfoGain.connect(lfoInv);\n lfoInv.connect(delayR.delayTime);\n lfo.start();\n input.connect(dryGain);\n input.connect(monoIn);\n monoIn.connect(delayL);\n monoIn.connect(delayR);\n delayL.connect(merger, 0, 0);\n delayR.connect(merger, 0, 1);\n merger.connect(wetGain);\n dryGain.connect(output);\n wetGain.connect(output);\n return { input, output, lfo, lfoGain, lfoInv, dryGain, wetGain, monoIn, delayL, delayR, merger, _mix };\n },\n\n updateParam(nodes, _m, param, value) {\n switch (param) {\n case 'rate': nodes.lfo.frequency.value = value as number; break;\n case 'depth': nodes.lfoGain.gain.value = (value as number) * 0.01; break;\n case 'mix': (nodes._mix as ConstantSourceNode).offset.value = value as number; break;\n }\n },\n\n dispose(nodes) {\n nodes.lfo.stop();\n (nodes._mix as ConstantSourceNode).stop();\n },\n\n});\n", "import { defineModule } from '../../core';\nimport { chorusDescriptor } from './chorus';\nimport type { ChorusParams, ChorusInputs, ChorusOutputs, ChorusProps } from './chorus.types';\n\n\nexport const Chorus = /* @__PURE__ */ defineModule(chorusDescriptor) as import('../../core').LibModule<ChorusParams, ChorusInputs, ChorusOutputs, ChorusProps>;\nexport type { ChorusParams, ChorusInputs, ChorusOutputs, ChorusProps };\n", "import type { ExposedPort, MacroKnob } from './macro';\n\n// \u2500\u2500\u2500 Shared value types \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport type DistortionType = 'soft' | 'hard' | 'fuzz';\nexport type WaveformType = 'sine' | 'square' | 'sawtooth' | 'triangle';\nexport type FilterType = 'lowpass' | 'highpass' | 'bandpass' | 'notch';\nexport type NoiseType = 'white' | 'pink' | 'brown';\n\n// \u2500\u2500\u2500 Core types \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport interface Position {\n x: number;\n y: number;\n}\n\n/**\n * Runtime port \u2014 derived from the descriptor at render time.\n * NOT stored on module instances.\n */\nexport interface Port {\n id: string; // Composite key: 'moduleId:portSlug'\n moduleId: string;\n portId: string; // Slug only: 'in', 'out', 'voct', 'modFreq'\n type: 'input' | 'output' | 'modulation' | 'trigger';\n label: string;\n signal: 'audio' | 'pitch' | 'gate' | 'modulation';\n}\n\n/**\n * Cable connecting two ports.\n * Uses compact 'moduleId:portSlug' format for both ends.\n * Identity is implicit: the composite 'from>to' is unique.\n * The legacy `id` field is kept optional for backward compatibility with\n * saved patches and preset data \u2014 it is never read at runtime.\n */\nexport interface Cable {\n id?: string; // legacy, ignored \u2014 kept for compat\n from: string; // 'moduleId:portSlug'\n to: string; // 'moduleId:portSlug'\n}\n\n/** Derive a unique key for a cable from its endpoints. */\nexport function cableId(c: Cable): string {\n return `${c.from}>${c.to}`;\n}\n\n/** Parse a cable endpoint string into moduleId and portId. */\nexport function parseCableEnd(end: string): { moduleId: string; portId: string } {\n const i = end.lastIndexOf(':');\n return { moduleId: end.slice(0, i), portId: end.slice(i + 1) };\n}\n\n/** Create a cable endpoint string from moduleId and portId. */\nexport function cableEnd(moduleId: string, portId: string): string {\n return `${moduleId}:${portId}`;\n}\n\n/**\n * Base module \u2014 pure state (params + position). No ports array.\n * Ports are derived from the descriptor at render time.\n */\nexport interface BaseModule {\n id: string;\n type: string;\n position: Position;\n}\n\n// \u2500\u2500\u2500 Macro (no descriptor file yet) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport interface MacroModule extends BaseModule {\n type: 'macro';\n macroId: string;\n macroName: string;\n macroIcon: string;\n knobValues: Record<string, number>;\n customKnobs: MacroKnob[];\n}\n\n// \u2500\u2500\u2500 ModuleType & SynthModule (derived from registered descriptors) \u2500\u2500\n\nexport type { ModuleType, SynthModule } from '@/modules';\n\n// \u2500\u2500\u2500 Re-exports from module descriptors \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n// Each module defines its own interface; we re-export here for backward compat.\n\nexport type { OscillatorModule } from '@/modules/vco';\nexport type { FilterModule } from '@/modules/vcf';\nexport type { GainModule } from '@/modules/vca';\nexport type { LFOModule } from '@/modules/lfo';\nexport type { DelayModule } from '@/modules/delay';\nexport type { ReverbModule } from '@/modules/reverb';\nexport type { OutputModule } from '@/modules/output';\nexport type { KeyboardModule } from '@/modules/keyboard';\nexport type { EnvelopeModule } from '@/modules/envelope';\nexport type { SequencerModule } from '@/modules/sequencer';\nexport type { NoiseModule } from '@/modules/noise';\nexport type { MixerModule } from '@/modules/mixer';\nexport type { ScopeModule } from '@/modules/scope';\nexport type { DistortionModule } from '@/modules/distortion';\nexport type { CompressorModule } from '@/modules/comp';\nexport type { DrumsModule } from '@/modules/drums';\nexport type { LadderFilterModule } from '@/modules/ladder-filter';\nexport type { Filter303Module } from '@/modules/303-filter';\nexport type { Drums808Module } from '@/modules/808-drums';\nexport type { TapeDelayModule } from '@/modules/tape-delay';\nexport type { SpringReverbModule } from '@/modules/spring-reverb';\nexport type { PhaserModule } from '@/modules/phaser';\nexport type { ChorusModule } from '@/modules/chorus';\nexport type { BitcrusherModule } from '@/modules/bitcrusher';\nexport type { RingModModule } from '@/modules/ring-mod';\nexport type { WavefolderModule } from '@/modules/wavefolder';\nexport type { FlangerModule } from '@/modules/flanger';\nexport type { TremoloModule } from '@/modules/tremolo';\nexport type { EQ3Module } from '@/modules/eq3';\nexport type { FreqShifterModule } from '@/modules/freq-shifter';\nexport type { SaturatorModule } from '@/modules/saturator';\nexport type { CombFilterModule } from '@/modules/comb-filter';\nexport type { AutoPanModule } from '@/modules/auto-pan';\nexport type { LoFiModule } from '@/modules/lo-fi';\nexport type { WahModule } from '@/modules/wah';\nexport type { DimensionModule } from '@/modules/dimension';\nexport type { FormantModule } from '@/modules/formant';\nexport type { RotaryModule } from '@/modules/rotary';\nexport type { ExciterModule } from '@/modules/exciter';\nexport type { StereoSpreadModule } from '@/modules/stereo-spread';\nexport type { DuckerModule } from '@/modules/ducker';\nexport type { SubHarmModule } from '@/modules/sub-harm';\nexport type { MidSideModule } from '@/modules/mid-side';\nexport type { SoftLimitModule } from '@/modules/soft-limit';\nexport type { TapeStopModule } from '@/modules/tape-stop';\nexport type { TiltEQModule } from '@/modules/tilt';\nexport type { PingPongModule } from '@/modules/ping-pong';\nexport type { GateModule } from '@/modules/gate';\nexport type { ResonatorModule } from '@/modules/resonator';\nexport type { HaasModule } from '@/modules/haas';\nexport type { CrossfadeModule } from '@/modules/crossfade';\nexport type { ShimmerModule } from '@/modules/shimmer';\nexport type { HarmonicTremModule } from '@/modules/harmonic-trem';\nexport type { OctaverModule } from '@/modules/octaver';\nexport type { EnvFollowModule } from '@/modules/env-follow';\nexport type { GlideModule } from '@/modules/glide';\nexport type { FracClockModule } from '@/modules/frac-clock';\n\n// \u2500\u2500\u2500 Constants & helpers \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/** Map a signal semantic to a cable hex colour.\n * Audio = emerald, pitch = amber, gate = orange,\n * modulation = violet. */\nexport function signalColor(signal: Port['signal']): string {\n switch (signal) {\n case 'audio': return '#10b981'; // emerald\n case 'pitch': return '#eab308'; // amber\n case 'gate': return '#f97316'; // orange\n case 'modulation': return '#8b5cf6'; // violet\n default: return '#94a3b8'; // slate\n }\n}\n\nexport const NOTE_FREQUENCIES: Record<string, number> = {\n 'C': 261.63, 'C#': 277.18, 'D': 293.66, 'D#': 311.13,\n 'E': 329.63, 'F': 349.23, 'F#': 369.99, 'G': 392.00,\n 'G#': 415.30, 'A': 440.00, 'A#': 466.16, 'B': 493.88,\n};\n\n/** Convert Hz to MIDI note number: 12 * log2(hz / 440) + 69 */\nexport function hzToMidi(hz: number): number {\n return 12 * Math.log2(hz / 440) + 69;\n}\n\n/** Convert MIDI note number to Hz: 440 * 2^((note - 69) / 12) */\nexport function midiToHz(note: number): number {\n return 440 * Math.pow(2, (note - 69) / 12);\n}\n", "// @ts-nocheck \u2014 generated by scripts/lib/build.ts\nimport { createMix } from '@/lib/dsp/mix';\nimport { BaseModule } from '@/types/synth';\nimport { hzToMidi } from '@/types/synth';\nimport { defineDescriptor, paramDefaults } from '@/modules/ModuleDescriptor';\nimport { createVoctPeriodNode, createCombFilterNode } from '@/worklets';\n\n// \u2500\u2500\u2500 PARAMS (single source of truth: knobs, defaults, hover tips, docs) \u2500\u2500\n// Pitch is plain V/OCT arithmetic, same as the VCO: the comb's note is the\n// V/OCT input (absolute notes, silence = 0) plus `offset` semitones \u2014 no\n// normalling. The app panel keeps `frequency` (unpatched) and `transpose`\n// (patched) as separate memories and writes whichever applies into offset.\nconst params = {\n offset: { node: '_freqVoct', field: 'transpose', default: 55, min: -48, max: 96, unit: 'semitone', },\n feedback: { node: 'comb', field: 'feedback', unit: 'factor', default: 0.7, min: 0, max: 0.95, },\n mix: { node: '_mix', field: 'offset', unit: 'factor', default: 0.5, min: 0, max: 1, },\n tuning: { kind: 'enum' as const, options: ['chromatic', 'free'], default: 'chromatic', },\n} as const satisfies Record<string, ParamSpec>;\n\nexport interface CombFilterModule extends BaseModule {\n type: 'comb-filter';\n frequency: number; // panel memory: Hz (50\u20132000) while V/OCT is unpatched\n transpose?: number; // panel memory: semitone shift while V/OCT is patched\n offset?: number; // library-only DSP state (see params.offset); the app derives it\n feedback: number;\n mix: number;\n tuning?: 'chromatic' | 'free';\n}\n\nconst TUNING_OPTIONS = [\n { value: 'chromatic' as const, label: 'CHROMATIC' },\n { value: 'free' as const, label: 'FREE' },\n];\n\n// MIDI range matching Hz 50\u20132000\nconst MIN_MIDI = /* @__PURE__ */ hzToMidi(50); // ~33.5\nconst MAX_MIDI = /* @__PURE__ */ hzToMidi(2000); // ~95.5\n\n/** Cables currently on V/OCT, per node set \u2014 picks the live panel memory. */\nconst patchCount = new WeakMap<object, number>();\n\n\nexport const combFilterDescriptor = /* @__PURE__ */ defineDescriptor({\n type: 'comb-filter',\n params,\n // Panel controls diverge from params (the ribbon edits two memories that\n // feed `offset`), so they are listed here, not derived from labels.\n\n ports: {\n 'in': { type: 'input', signal: 'audio', node: 'input', },\n 'out': { type: 'output', signal: 'audio', node: 'output', },\n 'voct': { type: 'input', signal: 'pitch', node: '_freqVoct', },\n 'modFreq': { type: 'modulation', signal: 'modulation', node: '_freqVoct', },\n },\n\n\n createModule(id, position): CombFilterModule {\n const { offset: _dsp, ...rest } = paramDefaults(params);\n return { id, type: 'comb-filter' as const, position, ...rest, frequency: 200, transpose: 0 };\n },\n\n createNodes(ctx, module) {\n const input = ctx.createGain();\n const output = ctx.createGain();\n const dryGain = ctx.createGain();\n const wetGain = ctx.createGain();\n\n // Worklet comb: true single-sample feedback. The previous native\n // DelayNode\u2192GainNode loop carried a hidden render quantum (128/sr) per\n // cycle, so the comb resonated at 1/(period + 2.9ms) \u2014 a comb \"tuned\"\n // to 440 Hz actually rang at ~193 Hz. See src/worklets/comb-filter.ts.\n const comb = createCombFilterNode(ctx, module.feedback);\n\n // V/Oct \u2192 period: summed V/OCT input + offset (worklet `transpose`) \u2192\n // map-voct-to-period \u2192 comb's `period` param. V/OCT lines carry absolute\n // notes, so a patched comb wants offset \u2248 0 (the transpose memory) and an\n // unpatched one wants the absolute note (hzToMidi of the frequency memory).\n const _freqVoct = createVoctPeriodNode(ctx);\n _freqVoct.parameters.get('transpose')!.value = module.offset ?? hzToMidi(module.frequency);\n\n const periodParam = comb.parameters.get('period')!;\n periodParam.value = 0; // driven exclusively by map-voct-to-period worklet\n _freqVoct.connect(periodParam);\n\n const _mix = createMix(ctx, dryGain, wetGain, module.mix, 'linear');\n\n input.connect(dryGain);\n input.connect(comb);\n comb.connect(wetGain);\n dryGain.connect(output);\n wetGain.connect(output);\n\n return { input, output, comb, dryGain, wetGain, _freqVoct, _mix };\n },\n\n updateParam(nodes, _m, param, value) {\n const t = (nodes._freqVoct as AudioWorkletNode).parameters.get('transpose')!;\n if (param === 'offset') {\n t.value = value as number;\n } else if (param === 'frequency') {\n if (!patchCount.get(nodes)) t.value = hzToMidi(value as number);\n } else if (param === 'transpose') {\n if (patchCount.get(nodes)) t.value = value as number;\n } else if (param === 'feedback') {\n (nodes.comb as AudioWorkletNode).parameters.get('feedback')!.value = value as number;\n } else if (param === 'mix') {\n (nodes._mix as ConstantSourceNode).offset.value = value as number;\n }\n // 'tuning' is UI-only, no audio change needed\n },\n\n // App-only: plain summing connect; the hooks only swap which panel memory\n // drives the offset.\n onConnect(nodes, module, portId, sourceNode) {\n if (portId !== 'voct') return false;\n const v = nodes._freqVoct as AudioWorkletNode;\n sourceNode.connect(v);\n patchCount.set(nodes, (patchCount.get(nodes) ?? 0) + 1);\n v.parameters.get('transpose')!.value = module.transpose ?? 0;\n return true;\n },\n\n onDisconnect(nodes, module, portId, sourceNode) {\n if (portId !== 'voct') return false;\n const v = nodes._freqVoct as AudioWorkletNode;\n try { sourceNode.disconnect(v); } catch (e) { /* already detached */ }\n const n = Math.max(0, (patchCount.get(nodes) ?? 0) - 1);\n patchCount.set(nodes, n);\n if (!n) v.parameters.get('transpose')!.value = hzToMidi(module.frequency);\n return true;\n },\n\n});\n", "import { defineModule } from '../../core';\nimport { combFilterDescriptor } from './comb-filter';\nimport type { CombFilterParams, CombFilterInputs, CombFilterOutputs, CombFilterProps } from './comb-filter.types';\nimport map_voct_to_period from '../worklet-src/map-voct-to-period';\nimport comb_filter from '../worklet-src/comb-filter';\n\nexport const CombFilter = /* @__PURE__ */ defineModule(combFilterDescriptor, {\n worklets: {\n 'map-voct-to-period': map_voct_to_period,\n 'comb-filter': comb_filter,\n },\n}) as import('../../core').LibModule<CombFilterParams, CombFilterInputs, CombFilterOutputs, CombFilterProps>;\nexport type { CombFilterParams, CombFilterInputs, CombFilterOutputs, CombFilterProps };\n", "// @ts-nocheck \u2014 generated by scripts/lib/build.ts\nimport { BaseModule } from '@/types/synth';\n\nexport interface CompressorModule extends BaseModule {\n type: 'compressor';\n threshold: number;\n ratio: number;\n attack: number;\n release: number;\n knee: number;\n makeup: number;\n}\nimport { defineDescriptor, paramDefaults } from '@/modules/ModuleDescriptor';\n\n// \u2500\u2500\u2500 PARAMS \u2014 the signal contract (no UI knowledge) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nconst params = {\n threshold: { node: 'comp', field: 'threshold', unit: 'dB', default: -24, min: -60, max: 0, },\n ratio: { node: 'comp', field: 'ratio', unit: 'factor', default: 4, min: 1, max: 20, scale: 'log', },\n attack: { node: 'comp', field: 'attack', unit: 's', default: 0.003, min: 0.001, max: 1, scale: 'log', },\n release: { node: 'comp', field: 'release', unit: 's', default: 0.25, min: 0.01, max: 1, scale: 'log', },\n knee: { node: 'comp', field: 'knee', unit: 'dB', default: 10, min: 0, max: 40, },\n // makeup is stored in dB but drives a linear gain node (Math.pow(10, v/20)) \u2014\n // not a 1:1 AudioParam mapping, so no node/field.\n makeup: { unit: 'dB', default: 0, min: 0, max: 30, },\n} satisfies Record<string, ParamSpec>;\n\n\n\n// \u2500\u2500\u2500 DESCRIPTOR \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport const compressorDescriptor = /* @__PURE__ */ defineDescriptor({\n type: 'compressor',\n params,\n\n\n ports: {\n 'in': { type: 'input', signal: 'audio', node: 'comp', },\n 'out': { type: 'output', signal: 'audio', node: 'makeup', },\n },\n\n\n createModule(id, position) {\n return { id, type: 'compressor', position, ...paramDefaults(params) };\n },\n\n createNodes(ctx, module) {\n const comp = ctx.createDynamicsCompressor();\n comp.threshold.value = module.threshold;\n comp.ratio.value = module.ratio;\n comp.attack.value = module.attack;\n comp.release.value = module.release;\n comp.knee.value = module.knee;\n const makeup = ctx.createGain();\n makeup.gain.value = Math.pow(10, (module.makeup || 0) / 20);\n comp.connect(makeup);\n return { comp, makeup };\n },\n\n updateParam(nodes, _m, param, value) {\n const v = value as number;\n switch (param) {\n case 'threshold': nodes.comp.threshold.value = v; break;\n case 'ratio': nodes.comp.ratio.value = v; break;\n case 'attack': nodes.comp.attack.value = v; break;\n case 'release': nodes.comp.release.value = v; break;\n case 'knee': nodes.comp.knee.value = v; break;\n case 'makeup': nodes.makeup.gain.value = Math.pow(10, v / 20); break;\n }\n },\n\n});\n", "import { defineModule } from '../../core';\nimport { compressorDescriptor } from './comp';\nimport type { CompressorParams, CompressorInputs, CompressorOutputs, CompressorProps } from './comp.types';\n\n\nexport const Compressor = /* @__PURE__ */ defineModule(compressorDescriptor) as import('../../core').LibModule<CompressorParams, CompressorInputs, CompressorOutputs, CompressorProps>;\nexport type { CompressorParams, CompressorInputs, CompressorOutputs, CompressorProps };\n", "// @ts-nocheck \u2014 generated by scripts/lib/build.ts\n\nimport type { BaseModule, Position } from '@/types/synth';\nimport { defineDescriptor, paramDefaults } from '@/modules/ModuleDescriptor';\n\nexport interface CrossfadeModule extends BaseModule {\n type: 'crossfade';\n blend: number;\n curve: 'linear' | 'equal-power';\n}\n\n// \u2500\u2500\u2500 PARAMS \u2014 the signal contract \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n// `blend` used to be two direct .gain.value writes \u2014 not a single AudioParam.\n// Now ONE ConstantSource (`_mix`) carries blend at audio rate; two WaveShapers\n// turn it into gainA/gainB per the active law, so blend is an honest 1:1\n// AudioParam (automatable, CV-modulatable). `curve` swaps the shaper tables \u2014\n// not a single AudioParam \u2014 so it stays a set-only enum.\nconst params = {\n blend: { node: '_mix', field: 'offset', unit: 'factor', default: 0.5, min: 0, max: 1, },\n curve: { kind: 'enum', default: 'equal-power', options: ['linear', 'equal-power'], },\n} satisfies Record<string, ParamSpec>;\n\n\nconst CURVE_POINTS = 2049; // spans input \u22121\u20261\n\nfunction lawCurve(fn: (m: number) => number): Float32Array<ArrayBuffer> {\n const c = new Float32Array(CURVE_POINTS);\n for (let i = 0; i < CURVE_POINTS; i++) {\n const x = -1 + (2 * i) / (CURVE_POINTS - 1);\n c[i] = fn(Math.min(1, Math.max(0, x)));\n }\n return c;\n}\n\nfunction curvesFor(curve: string): { a: Float32Array<ArrayBuffer>; b: Float32Array<ArrayBuffer> } {\n if (curve === 'equal-power') {\n return {\n a: lawCurve((m) => Math.cos(m * Math.PI / 2)),\n b: lawCurve((m) => Math.sin(m * Math.PI / 2)),\n };\n }\n return {\n a: lawCurve((m) => 1 - m),\n b: lawCurve((m) => m),\n };\n}\n\n\n// nodes: [inputA, inputB, output, _mix, curveA, curveB]\nexport const crossfadeDescriptor = /* @__PURE__ */ defineDescriptor({\n type: 'crossfade',\n params,\n\n ports: {\n 'a': { type: 'input', signal: 'audio', node: 'inputA', },\n 'b': { type: 'input', signal: 'audio', node: 'inputB', },\n 'out': { type: 'output', signal: 'audio', node: 'output', },\n },\n\n createModule(id, position) {\n return { id, type: 'crossfade', position, ...paramDefaults(params) } as CrossfadeModule;\n },\n\n createNodes(ctx, module) {\n const inputA = ctx.createGain();\n const inputB = ctx.createGain();\n const output = ctx.createGain();\n\n inputA.gain.value = 0;\n inputB.gain.value = 0;\n\n const _mix = ctx.createConstantSource();\n _mix.offset.value = module.blend;\n\n const { a, b } = curvesFor(module.curve);\n const curveA = ctx.createWaveShaper();\n curveA.curve = a;\n const curveB = ctx.createWaveShaper();\n curveB.curve = b;\n\n _mix.connect(curveA).connect(inputA.gain);\n _mix.connect(curveB).connect(inputB.gain);\n _mix.start();\n\n inputA.connect(output);\n inputB.connect(output);\n\n return { inputA, inputB, output, _mix, curveA, curveB };\n },\n\n updateParam(nodes, module, param, value) {\n if (param === 'blend') {\n (nodes._mix as ConstantSourceNode).offset.value = value as number;\n } else if (param === 'curve') {\n const { a, b } = curvesFor(value as string);\n (nodes.curveA as WaveShaperNode).curve = a;\n (nodes.curveB as WaveShaperNode).curve = b;\n }\n },\n\n});\n", "import { defineModule } from '../../core';\nimport { crossfadeDescriptor } from './crossfade';\nimport type { CrossfadeParams, CrossfadeInputs, CrossfadeOutputs, CrossfadeProps } from './crossfade.types';\n\n\nexport const Crossfade = /* @__PURE__ */ defineModule(crossfadeDescriptor) as import('../../core').LibModule<CrossfadeParams, CrossfadeInputs, CrossfadeOutputs, CrossfadeProps>;\nexport type { CrossfadeParams, CrossfadeInputs, CrossfadeOutputs, CrossfadeProps };\n", "// @ts-nocheck \u2014 generated by scripts/lib/build.ts\nimport { createMix } from '@/lib/dsp/mix';\nimport { createCombFilterNode } from '@/worklets';\nimport { BaseModule } from '@/types/synth';\n\nexport interface DelayModule extends BaseModule {\n type: 'delay';\n time: number;\n feedback: number;\n mix: number;\n}\nimport { defineDescriptor, paramDefaults } from '@/modules/ModuleDescriptor';\n\n// \u2500\u2500\u2500 PARAMS (single source of truth: knobs, defaults, hover tips, docs) \u2500\u2500\nconst params = {\n time: { node: 'delay', field: 'period', default: 0.3, min: 0.01, max: 1, scale: 'log', unit: 's', },\n feedback: { node: 'delay', field: 'feedback', unit: 'factor', default: 0.4, min: 0, max: 0.95, },\n mix: { node: '_mix', field: 'offset', unit: 'factor', default: 0.5, min: 0, max: 1, },\n} satisfies Record<string, ParamSpec>;\n\n\n\n// \u2500\u2500\u2500 DESCRIPTOR \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport const delayDescriptor = /* @__PURE__ */ defineDescriptor({\n type: 'delay',\n params,\n\n\n ports: {\n 'in': { type: 'input', signal: 'audio', node: 'input', },\n 'out': { type: 'output', signal: 'audio', node: 'output', },\n },\n\n createModule(id, position) {\n return { id, type: 'delay', position, ...paramDefaults(params) };\n },\n\n createNodes(ctx, module) {\n // Single-sample-feedback delay line (the COMB processor with a 5 s line).\n // A native DelayNode\u2192GainNode loop hides one render quantum per cycle, so\n // echo spacing was TIME + 128/sr; the old fix subtracted it and made the\n // FIRST echo land 128 frames early. Inside one processor both are exact,\n // and `time` is the real AudioParam (a-rate: ramps give tape-style pitch).\n const delay = createCombFilterNode(ctx, module.feedback, 5, 2);\n delay.parameters.get('period')!.value = module.time;\n const dryGain = ctx.createGain();\n const wetGain = ctx.createGain();\n const input = ctx.createGain();\n const output = ctx.createGain();\n const _mix = createMix(ctx, dryGain, wetGain, module.mix, 'linear');\n input.connect(dryGain);\n input.connect(delay);\n delay.connect(wetGain);\n dryGain.connect(output);\n wetGain.connect(output);\n return { input, output, delay, dryGain, wetGain, _mix };\n },\n\n updateParam(nodes, _m, param, value) {\n switch (param) {\n case 'time': (nodes.delay as AudioWorkletNode).parameters.get('period')!.value = value as number; break;\n case 'feedback': (nodes.delay as AudioWorkletNode).parameters.get('feedback')!.value = value as number; break;\n case 'mix':\n (nodes._mix as ConstantSourceNode).offset.value = value as number;\n break;\n }\n },\n\n});\n", "import { defineModule } from '../../core';\nimport { delayDescriptor } from './delay';\nimport type { DelayParams, DelayInputs, DelayOutputs, DelayProps } from './delay.types';\nimport comb_filter from '../worklet-src/comb-filter';\n\nexport const Delay = /* @__PURE__ */ defineModule(delayDescriptor, {\n worklets: {\n 'comb-filter': comb_filter,\n },\n}) as import('../../core').LibModule<DelayParams, DelayInputs, DelayOutputs, DelayProps>;\nexport type { DelayParams, DelayInputs, DelayOutputs, DelayProps };\n", "// @ts-nocheck \u2014 generated by scripts/lib/build.ts\nimport { BaseModule } from '@/types/synth';\n\nexport interface DimensionModule extends BaseModule {\n type: 'dimension';\n rate: number;\n depth: number;\n}\nimport { defineDescriptor, paramDefaults } from '@/modules/ModuleDescriptor';\n\nconst params = {\n rate: { node: 'lfo', field: 'frequency', unit: 'Hz', default: 0.5, min: 0.1, max: 5, },\n depth: { unit: 'factor', default: 0.3, min: 0, max: 1, },\n} satisfies Record<string, ParamSpec>;\n\n\n\nexport const dimensionDescriptor = /* @__PURE__ */ defineDescriptor({\n type: 'dimension',\n params,\n\n ports: {\n 'in': { type: 'input', signal: 'audio', node: 'input', },\n 'out': { type: 'output', signal: 'audio', node: 'output', },\n 'modRate': { type: 'modulation', signal: 'modulation', node: 'lfo', field: 'frequency' },\n },\n\n createModule(id, position) {\n return { id, type: 'dimension', position, ...paramDefaults(params) };\n },\n\n createNodes(ctx, module) {\n const input = ctx.createGain();\n input.channelCount = 2;\n input.channelCountMode = 'explicit';\n input.channelInterpretation = 'speakers';\n const output = ctx.createGain();\n const splitter = ctx.createChannelSplitter(2);\n const merger = ctx.createChannelMerger(2);\n const leftDelay = ctx.createDelay(0.05);\n const rightDelay = ctx.createDelay(0.05);\n const lfo = ctx.createOscillator();\n const lfoGainL = ctx.createGain();\n const lfoGainR = ctx.createGain();\n\n const llGain = ctx.createGain();\n const lrGain = ctx.createGain();\n const rlGain = ctx.createGain();\n const rrGain = ctx.createGain();\n\n const w = module.width;\n llGain.gain.value = (1 + w) / 2;\n rrGain.gain.value = (1 + w) / 2;\n rlGain.gain.value = (1 - w) / 2;\n lrGain.gain.value = (1 - w) / 2;\n\n leftDelay.delayTime.value = 0.01;\n rightDelay.delayTime.value = 0.012;\n lfo.type = 'sine';\n lfo.frequency.value = module.rate;\n lfoGainL.gain.value = module.depth * 0.002;\n lfoGainR.gain.value = -module.depth * 0.002;\n\n lfo.connect(lfoGainL);\n lfo.connect(lfoGainR);\n lfoGainL.connect(leftDelay.delayTime);\n lfoGainR.connect(rightDelay.delayTime);\n lfo.start();\n\n input.connect(splitter);\n splitter.connect(leftDelay, 0);\n splitter.connect(rightDelay, 1);\n\n leftDelay.connect(llGain);\n leftDelay.connect(lrGain);\n rightDelay.connect(rrGain);\n rightDelay.connect(rlGain);\n\n llGain.connect(merger, 0, 0);\n rlGain.connect(merger, 0, 0);\n lrGain.connect(merger, 0, 1);\n rrGain.connect(merger, 0, 1);\n\n merger.connect(output);\n\n return { input, output, splitter, merger, leftDelay, rightDelay, lfo, lfoGainL, lfoGainR, llGain, rrGain, lrGain, rlGain };\n },\n\n updateParam(nodes, _m, param, value) {\n if (param === 'width') {\n const w = value as number;\n nodes.llGain.gain.value = (1 + w) / 2;\n nodes.rrGain.gain.value = (1 + w) / 2;\n nodes.rlGain.gain.value = (1 - w) / 2;\n nodes.lrGain.gain.value = (1 - w) / 2;\n } else if (param === 'rate') nodes.lfo.frequency.value = value as number;\n else if (param === 'depth') {\n nodes.lfoGainL.gain.value = (value as number) * 0.002;\n nodes.lfoGainR.gain.value = -(value as number) * 0.002;\n }\n },\n\n dispose(nodes) {\n nodes.lfo.stop();\n },\n\n});\n", "import { defineModule } from '../../core';\nimport { dimensionDescriptor } from './dimension';\nimport type { DimensionParams, DimensionInputs, DimensionOutputs, DimensionProps } from './dimension.types';\n\n\nexport const Dimension = /* @__PURE__ */ defineModule(dimensionDescriptor) as import('../../core').LibModule<DimensionParams, DimensionInputs, DimensionOutputs, DimensionProps>;\nexport type { DimensionParams, DimensionInputs, DimensionOutputs, DimensionProps };\n", "// @ts-nocheck \u2014 generated by scripts/lib/build.ts\nimport { createMix } from '@/lib/dsp/mix';\n\nimport { BaseModule, DistortionType } from '@/types/synth';\n\nexport interface DistortionModule extends BaseModule {\n type: 'distortion';\n distortionType: DistortionType;\n drive: number;\n /** TONE: post-clip lowpass cutoff in Hz (500 = dark, 16000 = open). */\n frequency: number;\n mix: number;\n}\nimport { defineDescriptor, paramDefaults } from '@/modules/ModuleDescriptor';\n\n// \u2500\u2500\u2500 PARAMS (single source of truth: knobs, defaults, hover tips, docs) \u2500\u2500\nconst params = {\n distortionType: { kind: 'enum', default: 'soft', options: ['soft', 'hard', 'fuzz'] as const, },\n drive: { unit: 'factor', default: 5, min: 1, max: 20, scale: 'log', },\n frequency: { node: 'toneFilter', field: 'frequency', unit: 'Hz', default: 16000, min: 500, max: 16000, scale: 'log', },\n mix: { node: '_mix', field: 'offset', unit: 'factor', default: 0.8, min: 0, max: 1, },\n} satisfies Record<string, ParamSpec>;\n\n\n/**\n * Honest transfer curves \u2014 rebuilt 2026-08-04 (see reports/distortion.md).\n *\n * The pre-rebuild module fed `drive*10` into three curves of which \"hard\"\n * was the MDN soft-knee demo formula (never exceeded \u00B10.35 \u2014 softer than\n * \"soft\") and \"fuzz\" was a piecewise-linear clip. Now each mode is the\n * circuit its name promises, with k = drive (1\u201320) directly:\n *\n * soft \u2014 symmetric tanh(k\u00B7x): classic soft clipper, odd harmonics,\n * gradual onset. k=1 is near-linear warmth, k=20 heavy squash.\n * (The old \u00D710 multiplier saturated the entire knob by ~drive 3.)\n * hard \u2014 clamp(k\u00B7x, \u00B11): a true diode-style rail clipper (RAT/DS-1\n * family). At high drive the wave genuinely flattens to a square.\n * fuzz \u2014 exponential saturator with a fixed forward bias:\n * f(u) = sign(u)\u00B7(1 \u2212 e^\u2212|u|), y = (f(k\u00B7x + B) \u2212 f(B)) / (1 + f(B)).\n * Smoothly saturating (no piecewise corners), asymmetric (the bias\n * clips one half earlier \u2192 even harmonics), normalised to |y| \u2264 1.\n * Bias asymmetry produces DC, which the blocker below removes \u2014\n * the coupling cap every real fuzz circuit has.\n */\nconst FUZZ_BIAS = 0.7;\n\nfunction transfer(type: string, k: number, x: number): number {\n if (type === 'soft') return Math.tanh(k * x);\n if (type === 'hard') return Math.max(-1, Math.min(1, k * x));\n const f = (u: number) => Math.sign(u) * (1 - Math.exp(-Math.abs(u)));\n return (f(k * x + FUZZ_BIAS) - f(FUZZ_BIAS)) / (1 + f(FUZZ_BIAS));\n}\n\nconst CURVE_LEN = 16384;\n\nfunction makeDistortionCurve(type: string, drive: number): Float32Array {\n const k = Math.max(1, Math.min(20, drive));\n const curve = new Float32Array(CURVE_LEN);\n for (let i = 0; i < CURVE_LEN; i++) {\n const x = (i * 2) / (CURVE_LEN - 1) - 1;\n curve[i] = transfer(type, k, x);\n }\n return curve;\n}\n\n/**\n * Loudness compensation: waveshaping changes RMS wildly between modes and\n * across the drive range (a rail-clipped square is ~9 dB hotter than the\n * sine that made it). Real pedals hand the player a Level knob; in a rack,\n * a static makeup gain that pins nominal-level output back to nominal input\n * is the modular equivalent \u2014 DRIVE and TYPE become timbre controls, not\n * volume controls (same philosophy as `bandpassMakeup` in dsp/gainComp).\n *\n * Computed numerically: AC RMS (mean removed \u2014 the DC blocker eats the mean)\n * of the curve applied to a 0.5-amplitude sine, the fleet's nominal level.\n */\nfunction computeMakeup(type: string, drive: number): number {\n const k = Math.max(1, Math.min(20, drive));\n const N = 512;\n let sum = 0;\n let sumSq = 0;\n for (let i = 0; i < N; i++) {\n const y = transfer(type, k, 0.5 * Math.sin((2 * Math.PI * i) / N));\n sum += y;\n sumSq += y * y;\n }\n const mean = sum / N;\n const acRms = Math.sqrt(Math.max(0, sumSq / N - mean * mean));\n const rmsIn = 0.5 / Math.SQRT2;\n if (acRms < 1e-6) return 1;\n return Math.min(4, Math.max(0.25, rmsIn / acRms));\n}\n\n\nconst distortionTypes = params.distortionType.options;\n\n\nexport const distortionDescriptor = /* @__PURE__ */ defineDescriptor({\n type: 'distortion',\n params,\n\n ports: {\n 'in': { type: 'input', signal: 'audio', node: 'input', },\n 'out': { type: 'output', signal: 'audio', node: 'output', },\n },\n createModule(id, position) {\n return {\n id, type: 'distortion', position, ...paramDefaults(params),\n };\n },\n\n createNodes(ctx, module) {\n const input = ctx.createGain();\n const output = ctx.createGain();\n const dryGain = ctx.createGain();\n const wetGain = ctx.createGain();\n const waveshaper = ctx.createWaveShaper();\n const makeup = ctx.createGain();\n // DC blocker \u2014 output coupling cap. The fuzz curve's bias asymmetry\n // (and any asymmetric program material) produces a DC component that\n // would otherwise bias downstream envelope followers and scopes.\n const dcBlock = ctx.createBiquadFilter();\n const toneFilter = ctx.createBiquadFilter();\n\n waveshaper.curve = makeDistortionCurve(module.distortionType, module.drive) as Float32Array<ArrayBuffer>;\n waveshaper.oversample = '4x';\n makeup.gain.value = computeMakeup(module.distortionType, module.drive);\n dcBlock.type = 'highpass';\n dcBlock.frequency.value = 10;\n dcBlock.Q.value = 0.707;\n toneFilter.type = 'lowpass';\n toneFilter.frequency.value = module.frequency;\n toneFilter.Q.value = 0.707;\n const _mix = createMix(ctx, dryGain, wetGain, module.mix, 'linear');\n\n input.connect(dryGain);\n input.connect(waveshaper);\n waveshaper.connect(makeup);\n makeup.connect(dcBlock);\n dcBlock.connect(toneFilter);\n toneFilter.connect(wetGain);\n dryGain.connect(output);\n wetGain.connect(output);\n\n return { input, output, waveshaper, makeup, dcBlock, toneFilter, dryGain, wetGain, _mix };\n },\n\n updateParam(nodes, module, param, value) {\n if (param === 'drive' || param === 'distortionType') {\n nodes.waveshaper.curve = makeDistortionCurve(module.distortionType, module.drive) as Float32Array<ArrayBuffer>;\n nodes.makeup.gain.value = computeMakeup(module.distortionType, module.drive);\n }\n if (param === 'frequency') {\n nodes.toneFilter.frequency.value = value as number;\n }\n if (param === 'mix') {\n (nodes._mix as ConstantSourceNode).offset.value = value as number;\n }\n },\n\n});\n", "import { defineModule } from '../../core';\nimport { distortionDescriptor } from './distortion';\nimport type { DistortionParams, DistortionInputs, DistortionOutputs, DistortionProps } from './distortion.types';\n\n\nexport const Distortion = /* @__PURE__ */ defineModule(distortionDescriptor) as import('../../core').LibModule<DistortionParams, DistortionInputs, DistortionOutputs, DistortionProps>;\nexport type { DistortionParams, DistortionInputs, DistortionOutputs, DistortionProps };\n", "// @ts-nocheck \u2014 generated by scripts/lib/build.ts\nimport type { BaseModule, Position } from '@/types/synth';\nimport { createEnvFollowerNode } from '@/worklets';\n\nexport interface DuckerModule extends BaseModule {\n type: 'ducker';\n threshold: number;\n amount: number;\n attack: number;\n release: number;\n}\nimport { defineDescriptor, paramDefaults } from '@/modules/ModuleDescriptor';\n\n// \u2500\u2500\u2500 PARAMS \u2014 the signal contract (no UI knowledge) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nconst params = {\n // Feeds scInput.gain via 1/10^(threshold/20) \u2014 a conversion, not a 1:1\n // AudioParam write \u2014 so no node/field.\n threshold: { unit: 'dB', default: -24, min: -60, max: 0, },\n // Feeds invertGain.gain via negation (-amount) \u2014 no node/field.\n amount: { unit: 'factor', default: 0.7, min: 0, max: 1, },\n attack: { node: 'envFollower', field: 'attack', unit: 's', default: 0.01, min: 0.001, max: 0.1, scale: 'log', },\n release: { node: 'envFollower', field: 'release', unit: 's', default: 0.2, min: 0.001, max: 1, scale: 'log', },\n} satisfies Record<string, ParamSpec>;\n\n\n\nexport const duckerDescriptor = /* @__PURE__ */ defineDescriptor({\n type: 'ducker' as const,\n params,\n\n ports: {\n 'in': { type: 'input' as const, signal: 'audio' as const, node: 'input', },\n 'sc': { type: 'input' as const, signal: 'audio' as const, node: 'scInput', },\n 'out': { type: 'output' as const, signal: 'audio' as const, node: 'output', },\n },\n\n createModule(id: string, position: Position): DuckerModule {\n return { id, type: 'ducker', position, ...paramDefaults(params) };\n },\n\n createNodes(ctx, module) {\n const input = ctx.createGain();\n const scInput = ctx.createGain();\n const output = ctx.createGain();\n const duckGain = ctx.createGain();\n\n // Threshold normalization: scale sidechain so that threshold level \u2192 ~1.0\n scInput.gain.value = 1 / Math.max(0.001, Math.pow(10, module.threshold / 20));\n\n // Detector saturation. Without it a kick sitting 30 dB over the threshold\n // charges the follower to ~30, and REL then has to bleed all of that off\n // before the gain moves at all \u2014 the duck never opens between hits and the\n // patch just sounds permanently quiet. Real sidechain detectors saturate\n // (diode/optical), so the follower sees a soft-limited copy: reaching the\n // threshold is enough for the full duck, and going past it makes no\n // further difference. y = A\u00B7tanh(x/A), which is linear for small x.\n const scClamp = ctx.createWaveShaper();\n scClamp.oversample = 'none';\n const SAT = 1.2;\n const curve = new Float32Array(1024);\n for (let i = 0; i < curve.length; i++) {\n const x = (i / (curve.length - 1)) * 2 - 1;\n curve[i] = SAT * Math.tanh(x / SAT);\n }\n scClamp.curve = curve;\n\n // Worklet: sample-accurate asymmetric envelope follower\n const envFollower = createEnvFollowerNode(ctx);\n (envFollower.parameters as any).get('attack').value = module.attack;\n (envFollower.parameters as any).get('release').value = module.release;\n\n // Clamp the drive so the duck gain can never go negative (which would\n // phase-invert and AMPLIFY loud sidechains instead of ducking):\n // gain = 1 \u2212 amount \u00B7 clamp01(1.2 \u00B7 env)\n // With the saturating detector above, env tops out at A\u00B7tanh(1/A) \u2248 0.83,\n // so 1.2 puts full duck depth (1 \u2212 amount) right at the threshold and\n // gives a soft knee underneath it (6 dB under \u2248 half the duck).\n const envDrive = ctx.createGain();\n envDrive.gain.value = 1.2;\n const envClamp = ctx.createWaveShaper();\n envClamp.curve = new Float32Array([0, 0, 1]); // x<0 \u2192 0, 0..1 \u2192 x, x>1 \u2192 1\n\n const invertGain = ctx.createGain();\n invertGain.gain.value = -module.amount;\n\n const constantSource = ctx.createConstantSource();\n constantSource.offset.value = 1.0;\n constantSource.start();\n\n scInput.connect(scClamp);\n scClamp.connect(envFollower);\n envFollower.connect(envDrive);\n envDrive.connect(envClamp);\n envClamp.connect(invertGain);\n invertGain.connect(duckGain.gain);\n constantSource.connect(duckGain.gain);\n\n duckGain.gain.value = 0;\n input.connect(duckGain);\n duckGain.connect(output);\n\n return { input, scInput, scClamp, output, invertGain, envFollower, envDrive, envClamp, constantSource };\n },\n\n updateParam(nodes, _m, param, value) {\n if (param === 'threshold') {\n nodes.scInput.gain.value = 1 / Math.max(0.001, Math.pow(10, (value as number) / 20));\n } else if (param === 'amount') {\n nodes.invertGain.gain.value = -(value as number);\n } else if (param === 'attack') {\n (nodes.envFollower.parameters as any).get('attack').value = value as number;\n } else if (param === 'release') {\n (nodes.envFollower.parameters as any).get('release').value = value as number;\n }\n },\n\n dispose(nodes) {\n nodes.constantSource.stop();\n },\n\n});\n", "import { defineModule } from '../../core';\nimport { duckerDescriptor } from './ducker';\nimport type { DuckerParams, DuckerInputs, DuckerOutputs, DuckerProps } from './ducker.types';\nimport env_follower from '../worklet-src/env-follower';\n\nexport const Ducker = /* @__PURE__ */ defineModule(duckerDescriptor, {\n worklets: {\n 'env-follower': env_follower,\n },\n}) as import('../../core').LibModule<DuckerParams, DuckerInputs, DuckerOutputs, DuckerProps>;\nexport type { DuckerParams, DuckerInputs, DuckerOutputs, DuckerProps };\n", "// @ts-nocheck \u2014 generated by scripts/lib/build.ts\nimport type { BaseModule, Position } from '@/types/synth';\nimport { createEnvFollowerNode } from '@/worklets';\n\nexport interface EnvFollowModule extends BaseModule {\n type: 'env-follow';\n attack: number;\n release: number;\n sensitivity: number;\n depth: number;\n}\nimport { defineDescriptor, paramDefaults } from '@/modules/ModuleDescriptor';\n\n// \u2500\u2500\u2500 PARAMS \u2014 the signal contract (no UI knowledge) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nconst params = {\n attack: { node: 'envFollower', field: 'attack', unit: 's', default: 0.01, min: 0.001, max: 0.5, scale: 'log', },\n release: { node: 'envFollower', field: 'release', unit: 's', default: 0.1, min: 0.001, max: 2, scale: 'log', },\n // sensitivityGain.gain = sensitivity * 4 \u2014 a scaled conversion, not a 1:1\n // AudioParam write \u2014 so no node/field.\n sensitivity: { unit: 'factor', default: 0.5, min: 0, max: 1, },\n depth: { node: 'depthGain', field: 'gain', unit: 'semitone', default: 48, min: 0, max: 96, scale: 'sqrt', },\n} satisfies Record<string, ParamSpec>;\n\n\n\nexport const envFollowDescriptor = /* @__PURE__ */ defineDescriptor({\n type: 'env-follow' as const,\n params,\n\n ports: {\n 'in': { type: 'input' as const, signal: 'audio' as const, node: 'input', },\n 'env': { type: 'output' as const, node: 'depthGain', signal: 'modulation' },\n },\n\n createModule(id: string, position: Position): EnvFollowModule {\n return { id, type: 'env-follow', position, ...paramDefaults(params) };\n },\n\n createNodes(ctx, module) {\n const input = ctx.createGain();\n const depthGain = ctx.createGain();\n const sensitivityGain = ctx.createGain();\n sensitivityGain.gain.value = module.sensitivity * 4;\n depthGain.gain.value = module.depth; // semitones\n\n const envFollower = createEnvFollowerNode(ctx);\n (envFollower.parameters as any).get('attack').value = module.attack;\n (envFollower.parameters as any).get('release').value = module.release;\n\n input.connect(sensitivityGain);\n sensitivityGain.connect(envFollower);\n envFollower.connect(depthGain);\n\n return { input, depthGain, sensitivityGain, envFollower };\n },\n\n updateParam(nodes, _m, param, value) {\n if (param === 'sensitivity') {\n nodes.sensitivityGain.gain.value = (value as number) * 4;\n } else if (param === 'depth') {\n nodes.depthGain.gain.value = value as number; // semitones\n } else if (param === 'attack') {\n (nodes.envFollower.parameters as any).get('attack').value = value as number;\n } else if (param === 'release') {\n (nodes.envFollower.parameters as any).get('release').value = value as number;\n }\n },\n\n});\n", "import { defineModule } from '../../core';\nimport { envFollowDescriptor } from './env-follow';\nimport type { EnvelopeFollowerParams, EnvelopeFollowerInputs, EnvelopeFollowerOutputs, EnvelopeFollowerProps } from './env-follow.types';\nimport env_follower from '../worklet-src/env-follower';\n\nexport const EnvelopeFollower = /* @__PURE__ */ defineModule(envFollowDescriptor, {\n worklets: {\n 'env-follower': env_follower,\n },\n}) as import('../../core').LibModule<EnvelopeFollowerParams, EnvelopeFollowerInputs, EnvelopeFollowerOutputs, EnvelopeFollowerProps>;\nexport type { EnvelopeFollowerParams, EnvelopeFollowerInputs, EnvelopeFollowerOutputs, EnvelopeFollowerProps };\n", "// @ts-nocheck \u2014 generated by scripts/lib/build.ts\nimport type { BaseModule, Position } from '@/types/synth';\n\nexport interface EnvelopeModule extends BaseModule {\n type: 'envelope';\n attack: number;\n decay: number;\n sustain: number;\n release: number;\n depth: number;\n}\nimport { defineDescriptor, paramDefaults } from '@/modules/ModuleDescriptor';\nimport { createAdsrNode } from '@/worklets';\n\n// \u2500\u2500\u2500 PARAMS (single source of truth: knobs, defaults, hover tips, docs) \u2500\u2500\nconst params = {\n attack: { node: 'adsrNode', field: 'attack', default: 0.01, min: 0.001, max: 2, scale: 'log' as const, unit: 's', },\n decay: { node: 'adsrNode', field: 'decay', default: 0.1, min: 0.001, max: 2, scale: 'log' as const, unit: 's', },\n sustain: { node: 'adsrNode', field: 'sustain', unit: 'factor', default: 0.7, min: 0, max: 1, },\n release: { node: 'adsrNode', field: 'release', default: 0.3, min: 0.001, max: 3, scale: 'log' as const, unit: 's', },\n depth: { node: 'envOut', field: 'gain', default: 48, min: 0, max: 96, scale: 'sqrt' as const, unit: 'semitone', },\n} as const satisfies Record<string, ParamSpec>;\n\n// \u2500\u2500\u2500 UI \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n\n// \u2500\u2500\u2500 DESCRIPTOR \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport const envelopeDescriptor = /* @__PURE__ */ defineDescriptor({\n type: 'envelope',\n params,\n\n ports: {\n 'in': { type: 'input', signal: 'audio', node: 'mainGain', },\n 'out': { type: 'output', signal: 'audio', node: 'mainGain', },\n 'env': { type: 'output', signal: 'modulation', node: 'envOut', },\n 'trigger': { type: 'input', signal: 'gate', node: 'adsrNode', },\n },\n\n\n createModule(id: string, position: Position): EnvelopeModule {\n return { id, type: 'envelope', position, ...paramDefaults(params) };\n },\n\n createNodes(ctx, module) {\n const mainGain = ctx.createGain();\n mainGain.gain.value = 0;\n\n // ADSR worklet: gate input \u2192 envelope output (0\u20131)\n const adsrNode = createAdsrNode(ctx);\n adsrNode.parameters.get('attack')!.value = module.attack;\n adsrNode.parameters.get('decay')!.value = module.decay;\n adsrNode.parameters.get('sustain')!.value = module.sustain;\n adsrNode.parameters.get('release')!.value = module.release;\n\n // Worklet envelope output drives the VCA gain\n adsrNode.connect(mainGain.gain);\n\n // Raw envelope CV output (pass-through gain node at unity)\n const depth = module.depth ?? 48;\n const envOut = ctx.createGain();\n envOut.gain.value = depth;\n adsrNode.connect(envOut);\n\n return { mainGain, adsrNode, envOut };\n },\n\n updateParam(nodes, _module, param, value) {\n const v = value as number;\n const p = nodes.adsrNode.parameters;\n switch (param) {\n case 'attack': p.get('attack')!.value = v; break;\n case 'decay': p.get('decay')!.value = v; break;\n case 'sustain': p.get('sustain')!.value = v; break;\n case 'release': p.get('release')!.value = v; break;\n case 'depth': nodes.envOut.gain.value = v; break;\n }\n },\n\n});\n", "import { defineModule } from '../../core';\nimport { envelopeDescriptor } from './envelope';\nimport type { EnvelopeParams, EnvelopeInputs, EnvelopeOutputs, EnvelopeProps } from './envelope.types';\nimport adsr_envelope from '../worklet-src/adsr-envelope';\n\nexport const Envelope = /* @__PURE__ */ defineModule(envelopeDescriptor, {\n worklets: {\n 'adsr-envelope': adsr_envelope,\n },\n}) as import('../../core').LibModule<EnvelopeParams, EnvelopeInputs, EnvelopeOutputs, EnvelopeProps>;\nexport type { EnvelopeParams, EnvelopeInputs, EnvelopeOutputs, EnvelopeProps };\n", "// @ts-nocheck \u2014 generated by scripts/lib/build.ts\nimport { BaseModule } from '@/types/synth';\n\nexport interface EQ3Module extends BaseModule {\n type: 'eq3';\n low: number;\n mid: number;\n high: number;\n midFreq: number;\n}\nimport { defineDescriptor, paramDefaults } from '@/modules/ModuleDescriptor';\n\n// \u2500\u2500\u2500 PARAMS \u2500 the signal contract (no UI knowledge) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nconst params = {\n low: { node: 'lowShelf', field: 'gain', unit: 'dB', default: 0, min: -12, max: 12, },\n mid: { node: 'midPeak', field: 'gain', unit: 'dB', default: 0, min: -12, max: 12, },\n high: { node: 'highShelf', field: 'gain', unit: 'dB', default: 0, min: -12, max: 12, },\n midFreq: { node: 'midPeak', field: 'frequency', unit: 'Hz', default: 1000, min: 200, max: 5000, scale: 'log', },\n} satisfies Record<string, ParamSpec>;\n\n// \u2500\u2500\u2500 UI \u2500 presentation layer (stripped from the library) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n\nexport const eq3Descriptor = /* @__PURE__ */ defineDescriptor({\n type: 'eq3',\n params,\n\n ports: {\n 'in': { type: 'input', signal: 'audio', node: 'input', },\n 'out': { type: 'output', signal: 'audio', node: 'output', },\n },\n\n createModule(id, position) {\n return { id, type: 'eq3', position, ...paramDefaults(params) };\n },\n\n createNodes(ctx, module) {\n const input = ctx.createGain();\n const output = ctx.createGain();\n const lowShelf = ctx.createBiquadFilter();\n const midPeak = ctx.createBiquadFilter();\n const highShelf = ctx.createBiquadFilter();\n lowShelf.type = 'lowshelf'; lowShelf.frequency.value = 320; lowShelf.gain.value = module.low;\n midPeak.type = 'peaking'; midPeak.frequency.value = module.midFreq; midPeak.Q.value = 1.5; midPeak.gain.value = module.mid;\n highShelf.type = 'highshelf'; highShelf.frequency.value = 3200; highShelf.gain.value = module.high;\n input.connect(lowShelf); lowShelf.connect(midPeak); midPeak.connect(highShelf); highShelf.connect(output);\n return { input, output, lowShelf, midPeak, highShelf };\n },\n\n updateParam(nodes, _m, param, value) {\n switch (param) {\n case 'low': nodes.lowShelf.gain.value = value as number; break;\n case 'mid': nodes.midPeak.gain.value = value as number; break;\n case 'high': nodes.highShelf.gain.value = value as number; break;\n case 'midFreq': nodes.midPeak.frequency.value = value as number; break;\n }\n },\n\n});\n", "import { defineModule } from '../../core';\nimport { eq3Descriptor } from './eq3';\nimport type { ThreeBandEqParams, ThreeBandEqInputs, ThreeBandEqOutputs, ThreeBandEqProps } from './eq3.types';\n\n\nexport const ThreeBandEq = /* @__PURE__ */ defineModule(eq3Descriptor) as import('../../core').LibModule<ThreeBandEqParams, ThreeBandEqInputs, ThreeBandEqOutputs, ThreeBandEqProps>;\nexport type { ThreeBandEqParams, ThreeBandEqInputs, ThreeBandEqOutputs, ThreeBandEqProps };\n", "// @ts-nocheck \u2014 generated by scripts/lib/build.ts\nimport type { BaseModule, Position } from '@/types/synth';\nimport { defineDescriptor, paramDefaults } from '@/modules/ModuleDescriptor';\n\nexport interface ExciterModule extends BaseModule {\n type: 'exciter';\n drive: number;\n frequency: number;\n mix: number;\n}\n\n// \u2500\u2500\u2500 PARAMS \u2014 the signal contract (no UI knowledge) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nconst params = {\n // drive rebuilds the saturation curve AND scales highshelf.gain \u2014 not a\n // 1:1 AudioParam write, so no node/field.\n drive: { unit: 'factor', default: 0.5, min: 0, max: 1, },\n // frequency writes BOTH highpass.frequency and highshelf.frequency \u2014 two\n // AudioParams, so no single node/field mapping.\n frequency: { unit: 'Hz', default: 4000, min: 2000, max: 8000, scale: 'log', },\n // Additive blend, not a dry/wet crossfade: dry stays at unity while wetGain\n // scales the excited signal \u2014 a genuine 1:1 AudioParam write.\n mix: { node: 'wetGain', field: 'gain', unit: 'factor', default: 0.5, min: 0, max: 1, },\n} satisfies Record<string, ParamSpec>;\n\n\nfunction makeExciterCurve(amount: number): Float32Array {\n const samples = 44100;\n const curve = new Float32Array(samples);\n const k = 1 + amount * 8;\n // Level-match the drive stage to a 0.5-amplitude reference: tanh(k\u00B7x) has\n // small-signal gain k (up to 9 = +19 dB), which made the wet leg sit\n // ~+18 dB over dry and clip full-scale on bright input before the shelf\n // even applied (found by probe:exciter-hf, 2026-08-08). With the curve\n // pinned to 0.5 \u2192 0.5, DRIVE grows harmonic content and the highshelf\n // (6 + drive\u00B76 dB) carries the advertised brightness, not raw gain.\n const norm = 0.5 / (Math.tanh(k * 0.5) * 1.15);\n for (let i = 0; i < samples; i++) {\n const x = (i * 2) / samples - 1;\n curve[i] = Math.tanh(k * x) * (1 + Math.abs(x) * 0.3) * norm;\n }\n return curve;\n}\n\n\nexport const exciterDescriptor = /* @__PURE__ */ defineDescriptor({\n type: 'exciter' as const,\n params,\n\n ports: {\n 'in': { type: 'input' as const, signal: 'audio' as const, node: 'input', },\n 'out': { type: 'output' as const, signal: 'audio' as const, node: 'output', },\n },\n\n createModule(id: string, position: Position): ExciterModule {\n return { id, type: 'exciter', position, ...paramDefaults(params) };\n },\n\n createNodes(ctx, module) {\n const input = ctx.createGain();\n const output = ctx.createGain();\n const dryGain = ctx.createGain();\n const wetGain = ctx.createGain();\n const highpass = ctx.createBiquadFilter();\n const saturation = ctx.createWaveShaper();\n const highshelf = ctx.createBiquadFilter();\n\n highpass.type = 'highpass';\n highpass.frequency.value = module.frequency;\n highpass.Q.value = 0.7;\n saturation.curve = makeExciterCurve(module.drive) as Float32Array<ArrayBuffer>;\n saturation.oversample = '2x';\n highshelf.type = 'highshelf';\n highshelf.frequency.value = module.frequency;\n highshelf.gain.value = 6 + module.drive * 6;\n dryGain.gain.value = 1;\n wetGain.gain.value = module.mix;\n\n input.connect(dryGain);\n input.connect(highpass);\n highpass.connect(saturation);\n saturation.connect(highshelf);\n highshelf.connect(wetGain);\n dryGain.connect(output);\n wetGain.connect(output);\n\n return { input, output, highpass, saturation, highshelf, wetGain };\n },\n\n updateParam(nodes, _m, param, value) {\n if (param === 'drive') {\n nodes.saturation.curve = makeExciterCurve(value as number) as Float32Array<ArrayBuffer>;\n nodes.highshelf.gain.value = 6 + (value as number) * 6;\n } else if (param === 'frequency') {\n nodes.highpass.frequency.value = value as number;\n nodes.highshelf.frequency.value = value as number;\n } else if (param === 'mix') {\n nodes.wetGain.gain.value = value as number;\n }\n },\n\n});\n", "import { defineModule } from '../../core';\nimport { exciterDescriptor } from './exciter';\nimport type { ExciterParams, ExciterInputs, ExciterOutputs, ExciterProps } from './exciter.types';\n\n\nexport const Exciter = /* @__PURE__ */ defineModule(exciterDescriptor) as import('../../core').LibModule<ExciterParams, ExciterInputs, ExciterOutputs, ExciterProps>;\nexport type { ExciterParams, ExciterInputs, ExciterOutputs, ExciterProps };\n", "// @ts-nocheck \u2014 generated by scripts/lib/build.ts\nimport { BaseModule } from '@/types/synth';\n\nexport interface FlangerModule extends BaseModule {\n type: 'flanger';\n rate: number;\n depth: number;\n feedback: number;\n mix: number;\n}\nimport { defineDescriptor, paramDefaults } from '@/modules/ModuleDescriptor';\nimport { createFlangerNode } from '@/worklets';\nimport { createMix } from '@/lib/dsp/mix';\n\nconst params = {\n rate: { node: 'flanger', field: 'rate', unit: 'Hz', default: 0.5, min: 0.1, max: 5, },\n depth: { node: 'flanger', field: 'depth', unit: 'factor', default: 0.7, min: 0, max: 1, },\n feedback: { node: 'flanger', field: 'feedback', unit: 'factor', default: 0.7, min: 0, max: 0.95, },\n mix: { node: '_mix', field: 'offset', unit: 'factor', default: 0.5, min: 0, max: 1, },\n} satisfies Record<string, ParamSpec>;\n\n\n\nexport const flangerDescriptor = /* @__PURE__ */ defineDescriptor({\n type: 'flanger',\n params,\n\n ports: {\n 'in': { type: 'input', signal: 'audio', node: 'input', },\n 'out': { type: 'output', signal: 'audio', node: 'output', },\n 'modRate': { type: 'modulation', signal: 'modulation', node: 'flanger', field: 'rate' },\n 'modDepth': { type: 'modulation', signal: 'modulation', node: 'flanger', field: 'depth' },\n 'modFeedback': { type: 'modulation', signal: 'modulation', node: 'flanger', field: 'feedback' },\n 'modMix': { type: 'modulation', signal: 'modulation', node: '_mix', field: 'offset' },\n },\n\n createModule(id, position) {\n return { id, type: 'flanger', position, ...paramDefaults(params) };\n },\n\n createNodes(ctx, module) {\n const input = ctx.createGain();\n const output = ctx.createGain();\n const dryGain = ctx.createGain();\n const wetGain = ctx.createGain();\n const flanger = createFlangerNode(ctx, {\n rate: module.rate, depth: module.depth, feedback: module.feedback,\n });\n const _mix = createMix(ctx, dryGain, wetGain, module.mix, 'linear');\n input.connect(dryGain);\n input.connect(flanger);\n flanger.connect(wetGain);\n dryGain.connect(output);\n wetGain.connect(output);\n return { input, output, flanger, dryGain, wetGain, _mix };\n },\n\n updateParam(nodes, _m, param, value) {\n switch (param) {\n case 'rate':\n case 'depth':\n case 'feedback':\n (nodes.flanger as AudioWorkletNode).parameters.get(param)!.value = value as number;\n break;\n case 'mix':\n (nodes._mix as ConstantSourceNode).offset.value = value as number;\n break;\n }\n },\n\n dispose(nodes) {\n (nodes._mix as ConstantSourceNode).stop();\n },\n\n});\n", "import { defineModule } from '../../core';\nimport { flangerDescriptor } from './flanger';\nimport type { FlangerParams, FlangerInputs, FlangerOutputs, FlangerProps } from './flanger.types';\nimport flanger from '../worklet-src/flanger';\n\nexport const Flanger = /* @__PURE__ */ defineModule(flangerDescriptor, {\n worklets: {\n 'flanger': flanger,\n },\n}) as import('../../core').LibModule<FlangerParams, FlangerInputs, FlangerOutputs, FlangerProps>;\nexport type { FlangerParams, FlangerInputs, FlangerOutputs, FlangerProps };\n", "// @ts-nocheck \u2014 generated by scripts/lib/build.ts\n\nimport type { BaseModule } from '@/types/synth';\nimport { createFormantNode } from '@/worklets';\n\nexport interface FormantModule extends BaseModule {\n type: 'formant';\n morph: number;\n resonance: number;\n mix: number;\n}\nimport { defineDescriptor, paramDefaults } from '@/modules/ModuleDescriptor';\n\nconst vowelFreqs: [number, number, number, number, number][] = [\n [800, 1200, 2500, 3300, 3750],\n [400, 2000, 2800, 3500, 4500],\n [300, 2300, 3000, 3500, 4500],\n [500, 900, 2500, 3300, 3750],\n [350, 700, 2500, 3300, 3750],\n];\n\nfunction getMorphedFormants(morph: number): [number, number, number, number, number] {\n const wrapped = ((morph % 5) + 5) % 5;\n const lower = Math.floor(wrapped) % 5;\n const upper = (lower + 1) % 5;\n const frac = wrapped - Math.floor(wrapped);\n return [\n vowelFreqs[lower][0] + (vowelFreqs[upper][0] - vowelFreqs[lower][0]) * frac,\n vowelFreqs[lower][1] + (vowelFreqs[upper][1] - vowelFreqs[lower][1]) * frac,\n vowelFreqs[lower][2] + (vowelFreqs[upper][2] - vowelFreqs[lower][2]) * frac,\n vowelFreqs[lower][3] + (vowelFreqs[upper][3] - vowelFreqs[lower][3]) * frac,\n vowelFreqs[lower][4] + (vowelFreqs[upper][4] - vowelFreqs[lower][4]) * frac,\n ];\n}\n\nconst vowels = ['A', 'E', 'I', 'O', 'U'] as const;\nconst vowelOptions = /* @__PURE__ */ vowels.map((v, i) => ({ value: String(i), label: v }));\n\n// \u2500\u2500\u2500 PARAMS \u2500 the signal contract (no UI knowledge) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nconst params = {\n morph: { unit: 'factor', default: 0, min: 0, max: 5, },\n resonance: { unit: 'factor', default: 6, min: 1, max: 20, scale: 'sqrt', },\n mix: { unit: 'factor', default: 1.0, min: 0, max: 1, },\n} satisfies Record<string, ParamSpec>;\n\n// \u2500\u2500\u2500 UI \u2500 presentation layer (stripped from the library) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n\nexport const formantDescriptor = /* @__PURE__ */ defineDescriptor({\n type: 'formant',\n params,\n\n ports: {\n 'in': { type: 'input', signal: 'audio', node: 'input', },\n 'out': { type: 'output', signal: 'audio', node: 'output', },\n 'modVowel': { type: 'modulation', signal: 'modulation', node: 'vowelCV', },\n },\n\n createModule(id, position) {\n return { id, type: 'formant', position, ...paramDefaults(params) };\n },\n\n createNodes(ctx, module) {\n const input = ctx.createGain();\n const output = ctx.createGain();\n const dryGain = ctx.createGain();\n const wetGain = ctx.createGain();\n const f1 = ctx.createBiquadFilter();\n const f2 = ctx.createBiquadFilter();\n const f3 = ctx.createBiquadFilter();\n const f4 = ctx.createBiquadFilter();\n const f5 = ctx.createBiquadFilter();\n const formantMix = ctx.createGain();\n\n // Worklet: takes CV input, outputs 5-channel formant frequencies\n const formantWorklet = createFormantNode(ctx);\n (formantWorklet.parameters as any).get('baseMorph').value = module.morph;\n\n // CV input gain node \u2014 engine connects modulation sources here.\n const vowelCV = ctx.createGain();\n vowelCV.gain.value = 1;\n vowelCV.connect(formantWorklet);\n\n // Splitter to route 5-channel worklet output to individual filter frequencies\n const splitter = ctx.createChannelSplitter(5);\n formantWorklet.connect(splitter);\n\n // Connect each worklet output channel \u2192 filter frequency AudioParam\n splitter.connect(f1.frequency, 0);\n splitter.connect(f2.frequency, 1);\n splitter.connect(f3.frequency, 2);\n splitter.connect(f4.frequency, 3);\n splitter.connect(f5.frequency, 4);\n\n // Set base filter frequencies to 0 since worklet drives them\n f1.frequency.value = 0;\n f2.frequency.value = 0;\n f3.frequency.value = 0;\n f4.frequency.value = 0;\n f5.frequency.value = 0;\n\n f1.type = 'bandpass';\n f2.type = 'bandpass';\n f3.type = 'bandpass';\n f4.type = 'bandpass';\n f5.type = 'bandpass';\n f1.Q.value = module.resonance * 0.5;\n f2.Q.value = module.resonance * 0.4;\n f3.Q.value = module.resonance * 0.3;\n // F4/F5 are presence/air formants \u2014 narrower Q, lower gain\n f4.Q.value = module.resonance * 0.25;\n f5.Q.value = module.resonance * 0.2;\n\n dryGain.gain.value = 1 - module.mix;\n wetGain.gain.value = module.mix;\n formantMix.gain.value = 2.0;\n\n // F4/F5 at reduced level \u2014 they add presence without dominating\n const f4Gain = ctx.createGain();\n const f5Gain = ctx.createGain();\n f4Gain.gain.value = 0.5;\n f5Gain.gain.value = 0.35;\n\n input.connect(dryGain);\n input.connect(f1);\n input.connect(f2);\n input.connect(f3);\n input.connect(f4);\n input.connect(f5);\n f1.connect(formantMix);\n f2.connect(formantMix);\n f3.connect(formantMix);\n f4.connect(f4Gain);\n f5.connect(f5Gain);\n f4Gain.connect(formantMix);\n f5Gain.connect(formantMix);\n formantMix.connect(wetGain);\n dryGain.connect(output);\n wetGain.connect(output);\n\n return { input, output, vowelCV, f1, f2, f3, f4, f5, f4Gain, f5Gain, dryGain, wetGain, formantWorklet };\n },\n\n updateParam(nodes, _module, param, value) {\n if (param === 'morph') {\n (nodes.formantWorklet.parameters as any).get('baseMorph').value = value as number;\n } else if (param === 'resonance') {\n const r = value as number;\n nodes.f1.Q.value = r * 0.5;\n nodes.f2.Q.value = r * 0.4;\n nodes.f3.Q.value = r * 0.3;\n nodes.f4.Q.value = r * 0.25;\n nodes.f5.Q.value = r * 0.2;\n } else if (param === 'mix') {\n nodes.dryGain.gain.value = 1 - (value as number);\n nodes.wetGain.gain.value = value as number;\n }\n },\n\n});\n", "import { defineModule } from '../../core';\nimport { formantDescriptor } from './formant';\nimport type { FormantParams, FormantInputs, FormantOutputs, FormantProps } from './formant.types';\nimport formant_table from '../worklet-src/formant-table';\n\nexport const Formant = /* @__PURE__ */ defineModule(formantDescriptor, {\n worklets: {\n 'formant-table': formant_table,\n },\n}) as import('../../core').LibModule<FormantParams, FormantInputs, FormantOutputs, FormantProps>;\nexport type { FormantParams, FormantInputs, FormantOutputs, FormantProps };\n", "// @ts-nocheck \u2014 generated by scripts/lib/build.ts\nimport { BaseModule } from '@/types/synth';\nimport { defineDescriptor, paramDefaults } from '@/modules/ModuleDescriptor';\nimport { createFreqShifterNode } from '@/worklets';\nimport { createMix } from '@/lib/dsp/mix';\n\nexport interface FreqShifterModule extends BaseModule {\n type: 'freq-shifter';\n shift: number;\n mix: number;\n}\n\n// \u2500\u2500\u2500 PARAMS \u2014 the signal contract \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n// `shift` drives the worklet's own `shift` AudioParam 1:1 (Hz). `mix` used\n// to be two direct .gain.value writes on dryGain/wetGain \u2014 not a single\n// AudioParam \u2014 so it now runs through createMix's ConstantSource (`_mix`),\n// linear law, preserving the original 1-mix/mix levels exactly.\nconst params = {\n shift: { node: 'shifter', field: 'shift', unit: 'Hz', default: 0, min: -500, max: 500, },\n mix: { node: '_mix', field: 'offset', unit: 'factor', default: 1.0, min: 0, max: 1, },\n} satisfies Record<string, ParamSpec>;\n\n\n// \u2500\u2500\u2500 DESCRIPTOR \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport const freqShifterDescriptor = /* @__PURE__ */ defineDescriptor({\n type: 'freq-shifter',\n params,\n\n\n ports: {\n 'in': { type: 'input', signal: 'audio', node: 'input', },\n 'out': { type: 'output', signal: 'audio', node: 'output', },\n 'modShift': { type: 'modulation', signal: 'modulation', node: 'shifter', field: 'shift' },\n },\n\n createModule(id, position) {\n return { id, type: 'freq-shifter', position, ...paramDefaults(params) } as FreqShifterModule;\n },\n\n createNodes(ctx, module) {\n const input = ctx.createGain();\n const output = ctx.createGain();\n const dryGain = ctx.createGain();\n const wetGain = ctx.createGain();\n\n // Real SSB shifter: Hilbert allpass pair + quadrature oscillator (worklet)\n const shifter = createFreqShifterNode(ctx, module.shift);\n\n const _mix = createMix(ctx, dryGain, wetGain, module.mix, 'linear');\n\n input.connect(dryGain);\n input.connect(shifter);\n shifter.connect(wetGain);\n dryGain.connect(output);\n wetGain.connect(output);\n\n return { input, output, shifter, dryGain, wetGain, _mix };\n },\n\n updateParam(nodes, _m, param, value) {\n if (param === 'shift') {\n const p = (nodes.shifter as AudioWorkletNode).parameters.get('shift')!;\n p.setTargetAtTime(value as number, nodes.shifter.context.currentTime, 0.01);\n } else if (param === 'mix') {\n (nodes._mix as ConstantSourceNode).offset.value = value as number;\n }\n },\n\n});\n", "import { defineModule } from '../../core';\nimport { freqShifterDescriptor } from './freq-shifter';\nimport type { FrequencyShifterParams, FrequencyShifterInputs, FrequencyShifterOutputs, FrequencyShifterProps } from './freq-shifter.types';\nimport freq_shifter from '../worklet-src/freq-shifter';\n\nexport const FrequencyShifter = /* @__PURE__ */ defineModule(freqShifterDescriptor, {\n worklets: {\n 'freq-shifter': freq_shifter,\n },\n}) as import('../../core').LibModule<FrequencyShifterParams, FrequencyShifterInputs, FrequencyShifterOutputs, FrequencyShifterProps>;\nexport type { FrequencyShifterParams, FrequencyShifterInputs, FrequencyShifterOutputs, FrequencyShifterProps };\n", "// @ts-nocheck \u2014 generated by scripts/lib/build.ts\nimport type { BaseModule, Position } from '@/types/synth';\nimport { createEnvFollowerNode } from '@/worklets';\n\nexport interface GateModule extends BaseModule {\n type: 'gate';\n threshold: number;\n range: number;\n attack: number;\n release: number;\n}\nimport { defineDescriptor, paramDefaults } from '@/modules/ModuleDescriptor';\n\n// \u2500\u2500\u2500 PARAMS \u2014 the signal contract (no UI knowledge) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nconst params = {\n // threshold/range rebuild the gateShaper curve \u2014 not a 1:1 AudioParam\n // write \u2014 so no node/field.\n threshold: { unit: 'dB', default: -40, min: -60, max: 0, },\n range: { unit: 'factor', default: 0.8, min: 0, max: 1, },\n attack: { node: 'envFollower', field: 'attack', unit: 's', default: 0.005, min: 0.001, max: 0.05, scale: 'log', },\n release: { node: 'envFollower', field: 'release', unit: 's', default: 0.1, min: 0.01, max: 0.5, scale: 'log', },\n} satisfies Record<string, ParamSpec>;\n\n\n\n/**\n * WaveShaper indexes its curve across the BIPOLAR input domain [-1, +1]:\n * index = floor((x + 1) / 2 * (len - 1))\n * The envelope follower feeds a unipolar [0, 1] signal, so the curve must be\n * built over the bipolar domain and the threshold compared against that same\n * mapping \u2014 otherwise only the top half of the table is ever addressed and the\n * gate never closes for thresholds below ~-6 dB.\n *\n * A small hysteresis-free soft knee (~2 dB) avoids zipper/chatter on material\n * hovering around the threshold.\n */\nfunction makeGateCurve(threshold: number, range: number): Float32Array {\n const threshLinear = Math.pow(10, threshold / 20);\n const kneeLow = Math.pow(10, (threshold - 2) / 20); // 2 dB soft knee below threshold\n const closed = 1.0 - range;\n const gsLen = 32768; // fine resolution: low thresholds occupy few table slots\n const gsCurve = new Float32Array(gsLen);\n for (let i = 0; i < gsLen; i++) {\n const x = (i / (gsLen - 1)) * 2 - 1; // bipolar input value at this index\n const env = Math.max(0, x); // envelope is unipolar; negative half unused\n let g: number;\n if (env >= threshLinear) g = 1.0;\n else if (env <= kneeLow) g = closed;\n else g = closed + (1.0 - closed) * ((env - kneeLow) / (threshLinear - kneeLow));\n gsCurve[i] = g;\n }\n return gsCurve;\n}\n\n\nexport const gateDescriptor = /* @__PURE__ */ defineDescriptor({\n type: 'gate' as const,\n params,\n\n ports: {\n 'in': { type: 'input' as const, signal: 'audio' as const, node: 'input', },\n 'out': { type: 'output' as const, signal: 'audio' as const, node: 'output', },\n },\n\n createModule(id: string, position: Position): GateModule {\n return { id, type: 'gate', position, ...paramDefaults(params) };\n },\n\n createNodes(ctx, module) {\n const input = ctx.createGain();\n const output = ctx.createGain();\n const gateGain = ctx.createGain();\n\n // Worklet: sample-accurate asymmetric envelope follower\n const envFollower = createEnvFollowerNode(ctx);\n (envFollower.parameters as any).get('attack').value = module.attack;\n (envFollower.parameters as any).get('release').value = module.release;\n\n // Gate shaper: converts envelope level to gate on/off based on threshold\n const gateShaper = ctx.createWaveShaper();\n gateShaper.curve = makeGateCurve(module.threshold, module.range) as Float32Array<ArrayBuffer>;\n\n gateGain.gain.value = 0;\n input.connect(envFollower);\n envFollower.connect(gateShaper);\n gateShaper.connect(gateGain.gain);\n\n input.connect(gateGain);\n gateGain.connect(output);\n\n return { input, output, envFollower, gateShaper };\n },\n\n updateParam(nodes, module, param, value) {\n if (param === 'threshold' || param === 'range') {\n const thresh = param === 'threshold' ? value as number : module.threshold;\n const range = param === 'range' ? value as number : module.range;\n nodes.gateShaper.curve = makeGateCurve(thresh, range) as Float32Array<ArrayBuffer>;\n } else if (param === 'attack') {\n (nodes.envFollower.parameters as any).get('attack').value = value as number;\n } else if (param === 'release') {\n (nodes.envFollower.parameters as any).get('release').value = value as number;\n }\n },\n\n});\n", "import { defineModule } from '../../core';\nimport { gateDescriptor } from './gate';\nimport type { GateParams, GateInputs, GateOutputs, GateProps } from './gate.types';\nimport env_follower from '../worklet-src/env-follower';\n\nexport const Gate = /* @__PURE__ */ defineModule(gateDescriptor, {\n worklets: {\n 'env-follower': env_follower,\n },\n}) as import('../../core').LibModule<GateParams, GateInputs, GateOutputs, GateProps>;\nexport type { GateParams, GateInputs, GateOutputs, GateProps };\n", "// @ts-nocheck \u2014 generated by scripts/lib/build.ts\nimport { BaseModule } from '@/types/synth';\nimport { defineDescriptor, paramDefaults } from '@/modules/ModuleDescriptor';\nimport { createGlideNode } from '@/worklets';\n\nexport interface GlideModule extends BaseModule {\n type: 'glide';\n time: number;\n}\n\n// \u2500\u2500\u2500 PARAMS \u2014 the signal contract \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n// `time` drives the worklet's own `time` AudioParam 1:1.\nconst params = {\n time: { node: '_glide', field: 'time', unit: 's', default: 0.1, min: 0.01, max: 10, scale: 'log', },\n} satisfies Record<string, ParamSpec>;\n\n\n// \u2500\u2500\u2500 DESCRIPTOR \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport const glideDescriptor = /* @__PURE__ */ defineDescriptor({\n type: 'glide',\n params,\n\n\n ports: {\n 'in': { type: 'input', signal: 'pitch', node: '_glide', },\n 'gate': { type: 'input', signal: 'gate', node: '_gateIn', },\n 'out': { type: 'output', signal: 'pitch', node: 'output', },\n },\n\n createModule(id, position) {\n return { id, type: 'glide', position, ...paramDefaults(params) } as GlideModule;\n },\n\n createNodes(ctx, module) {\n const _glide = createGlideNode(ctx);\n _glide.parameters.get('time')!.value = module.time;\n\n const output = ctx.createGain();\n output.gain.value = 1;\n _glide.connect(output);\n\n // Gate input gain node \u2014 gate signal connects here, feeds worklet input 1\n const _gateIn = ctx.createGain();\n _gateIn.gain.value = 1;\n _gateIn.connect(_glide, 0, 1);\n\n return { _glide, _gateIn, output };\n },\n\n updateParam(nodes, _m, param, value) {\n if (param === 'time') {\n nodes._glide.parameters.get('time')!.value = value as number;\n }\n },\n\n});\n", "import { defineModule } from '../../core';\nimport { glideDescriptor } from './glide';\nimport type { GlideParams, GlideInputs, GlideOutputs, GlideProps } from './glide.types';\nimport glide from '../worklet-src/glide';\n\nexport const Glide = /* @__PURE__ */ defineModule(glideDescriptor, {\n worklets: {\n 'glide': glide,\n },\n}) as import('../../core').LibModule<GlideParams, GlideInputs, GlideOutputs, GlideProps>;\nexport type { GlideParams, GlideInputs, GlideOutputs, GlideProps };\n", "// @ts-nocheck \u2014 generated by scripts/lib/build.ts\n\nimport { createMix } from '@/lib/dsp/mix';\nimport { BaseModule } from '@/types/synth';\n\nexport interface HaasModule extends BaseModule {\n type: 'haas';\n delay: number;\n side: 'left' | 'right';\n mix: number;\n}\nimport { defineDescriptor, paramDefaults } from '@/modules/ModuleDescriptor';\n\n// \u2500\u2500\u2500 PARAMS \u2014 the signal contract (no UI knowledge) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n// `delay` converts ms \u2192 seconds before it reaches delayNode.delayTime, so it\n// stays set-only (an honest 1:1 param can't carry a unit conversion). `mix`\n// is a real dry/wet crossfade of the delayed channel (directBleed/delayedGain),\n// so it is rebuilt on createMix and exposed 1:1. `side` re-routes the merger\n// on change \u2014 not a single AudioParam \u2014 so it stays a set-only enum.\nconst params = {\n delay: { unit: 'ms', default: 15, min: 1, max: 35, },\n side: { kind: 'enum', default: 'right', options: ['left', 'right'], },\n mix: { node: '_mix', field: 'offset', unit: 'factor', default: 1, min: 0, max: 1, },\n} satisfies Record<string, ParamSpec>;\n\n\n\n// nodes: [input, output, delayNode, directGain, delayedGain, directBleed, merger, _mix]\nexport const haasDescriptor = /* @__PURE__ */ defineDescriptor({\n type: 'haas',\n params,\n\n ports: {\n 'in': { type: 'input', signal: 'audio', node: 'input', },\n 'out': { type: 'output', signal: 'audio', node: 'output', },\n },\n\n createModule(id, position) {\n return { id, type: 'haas', position, ...paramDefaults(params) } as HaasModule;\n },\n\n createNodes(ctx, module) {\n const input = ctx.createGain();\n const output = ctx.createGain();\n const delayNode = ctx.createDelay(0.05);\n const directGain = ctx.createGain();\n const delayedGain = ctx.createGain();\n // Mono-integrity leg (2026-08-08 fix): the delayed-side channel\n // crossfades between the DIRECT signal (mix 0) and the DELAYED signal\n // (mix 1). Before this, MIX 0 left the delayed channel SILENT \u2014 the\n // \"widener\" hard-panned the input to one side and the mono sum lost\n // 6.02 dB (probe:haas-dry). Same fault class as the DIM mono-silencing\n // bug: a channel nobody feeds. MIX 0 now means mono passthrough.\n // directBleed (dry) / delayedGain (wet) crossfade on ONE ConstantSource\n // (`_mix`), same as delay.ts, so `mix` is an honest 1:1 AudioParam.\n const directBleed = ctx.createGain();\n const merger = ctx.createChannelMerger(2);\n const _mix = createMix(ctx, directBleed, delayedGain, module.mix, 'linear');\n\n delayNode.delayTime.value = module.delay / 1000;\n directGain.gain.value = 1;\n\n input.connect(directGain);\n input.connect(directBleed);\n input.connect(delayNode);\n delayNode.connect(delayedGain);\n\n if (module.side === 'right') {\n directGain.connect(merger, 0, 0);\n delayedGain.connect(merger, 0, 1);\n directBleed.connect(merger, 0, 1);\n } else {\n delayedGain.connect(merger, 0, 0);\n directBleed.connect(merger, 0, 0);\n directGain.connect(merger, 0, 1);\n }\n merger.connect(output);\n\n return { input, output, delayNode, directGain, delayedGain, directBleed, merger, _mix };\n },\n\n updateParam(nodes, _m, param, value) {\n if (param === 'delay') {\n nodes.delayNode.delayTime.value = (value as number) / 1000;\n } else if (param === 'mix') {\n (nodes._mix as ConstantSourceNode).offset.value = value as number;\n } else if (param === 'side') {\n try { nodes.directGain.disconnect(nodes.merger); } catch (_) {}\n try { nodes.delayedGain.disconnect(nodes.merger); } catch (_) {}\n try { nodes.directBleed.disconnect(nodes.merger); } catch (_) {}\n if (value === 'right') {\n nodes.directGain.connect(nodes.merger, 0, 0);\n nodes.delayedGain.connect(nodes.merger, 0, 1);\n nodes.directBleed.connect(nodes.merger, 0, 1);\n } else {\n nodes.delayedGain.connect(nodes.merger, 0, 0);\n nodes.directBleed.connect(nodes.merger, 0, 0);\n nodes.directGain.connect(nodes.merger, 0, 1);\n }\n }\n },\n\n});\n", "import { defineModule } from '../../core';\nimport { haasDescriptor } from './haas';\nimport type { HaasWidenerParams, HaasWidenerInputs, HaasWidenerOutputs, HaasWidenerProps } from './haas.types';\n\n\nexport const HaasWidener = /* @__PURE__ */ defineModule(haasDescriptor) as import('../../core').LibModule<HaasWidenerParams, HaasWidenerInputs, HaasWidenerOutputs, HaasWidenerProps>;\nexport type { HaasWidenerParams, HaasWidenerInputs, HaasWidenerOutputs, HaasWidenerProps };\n", "// @ts-nocheck \u2014 generated by scripts/lib/build.ts\nimport type { BaseModule, Position } from '@/types/synth';\n\nexport interface HarmonicTremModule extends BaseModule {\n type: 'harmonic-trem';\n rate: number;\n depth: number;\n crossover: number;\n}\nimport { defineDescriptor, paramDefaults } from '@/modules/ModuleDescriptor';\n\nconst params = {\n rate: { node: 'lfo', field: 'frequency', unit: 'Hz', default: 4, min: 1, max: 10, },\n depth: { unit: 'factor', default: 0.7, min: 0, max: 1, },\n crossover: { node: 'lowpass', field: 'frequency', unit: 'Hz', default: 800, min: 200, max: 2000, },\n} satisfies Record<string, ParamSpec>;\n\n\n\nexport const harmonicTremDescriptor = /* @__PURE__ */ defineDescriptor({\n type: 'harmonic-trem' as const,\n params,\n\n ports: {\n 'in': { type: 'input' as const, signal: 'audio' as const, node: 'input', },\n 'out': { type: 'output' as const, signal: 'audio' as const, node: 'output', },\n 'modRate': { type: 'modulation', signal: 'modulation', node: 'lfo', field: 'frequency' },\n 'modCrossover': { type: 'modulation', signal: 'modulation', node: 'lowpass', field: 'frequency' },\n },\n\n createModule(id: string, position: Position): HarmonicTremModule {\n return { id, type: 'harmonic-trem', position, ...paramDefaults(params) };\n },\n\n createNodes(ctx, module) {\n const input = ctx.createGain();\n const output = ctx.createGain();\n const lowpass = ctx.createBiquadFilter();\n const lpInvert = ctx.createGain();\n const highBand = ctx.createGain();\n const lowGain = ctx.createGain();\n const highGain = ctx.createGain();\n const lfo = ctx.createOscillator();\n const lfoGainLow = ctx.createGain();\n const lfoGainHigh = ctx.createGain();\n const lfoInvert = ctx.createGain();\n\n lowpass.type = 'lowpass';\n lowpass.frequency.value = module.crossover;\n lowpass.Q.value = -6.0206; // dB \u2192 Q_lin 0.5\n lpInvert.gain.value = -1;\n highBand.gain.value = 1;\n\n lfo.type = 'sine'; lfo.frequency.value = module.rate;\n lfoGainLow.gain.value = module.depth * 0.5;\n lfoGainHigh.gain.value = module.depth * 0.5;\n lfoInvert.gain.value = -1;\n lowGain.gain.value = 1;\n highGain.gain.value = 1;\n\n input.connect(lowpass);\n input.connect(highBand);\n lowpass.connect(lpInvert);\n lpInvert.connect(highBand);\n lfo.connect(lfoGainLow);\n lfo.connect(lfoInvert);\n lfoInvert.connect(lfoGainHigh);\n lfoGainLow.connect(lowGain.gain);\n lfoGainHigh.connect(highGain.gain);\n lowpass.connect(lowGain);\n highBand.connect(highGain);\n lowGain.connect(output);\n highGain.connect(output);\n lfo.start();\n\n return { input, output, lfo, lfoGainLow, lfoGainHigh, lowpass, lpInvert, highBand };\n },\n\n updateParam(nodes, _m, param, value) {\n if (param === 'rate') nodes.lfo.frequency.value = value as number;\n else if (param === 'depth') {\n nodes.lfoGainLow.gain.value = (value as number) * 0.5;\n nodes.lfoGainHigh.gain.value = (value as number) * 0.5;\n } else if (param === 'crossover') {\n nodes.lowpass.frequency.value = value as number;\n }\n },\n\n dispose(nodes) {\n nodes.lfo.stop();\n },\n\n});\n", "import { defineModule } from '../../core';\nimport { harmonicTremDescriptor } from './harmonic-trem';\nimport type { HarmonicTremoloParams, HarmonicTremoloInputs, HarmonicTremoloOutputs, HarmonicTremoloProps } from './harmonic-trem.types';\n\n\nexport const HarmonicTremolo = /* @__PURE__ */ defineModule(harmonicTremDescriptor) as import('../../core').LibModule<HarmonicTremoloParams, HarmonicTremoloInputs, HarmonicTremoloOutputs, HarmonicTremoloProps>;\nexport type { HarmonicTremoloParams, HarmonicTremoloInputs, HarmonicTremoloOutputs, HarmonicTremoloProps };\n", "// @ts-nocheck \u2014 generated by scripts/lib/build.ts\nimport type { BaseModule, Position } from '@/types/synth';\n\nimport { defineDescriptor, paramDefaults } from '@/modules/ModuleDescriptor';\nimport { createLadderFilterNode, createVoctFreqNode } from '@/worklets';\n\nexport interface LadderFilterModule extends BaseModule {\n type: 'ladder-filter';\n /** Cutoff as a note (69 = 440 Hz), driving the V/OCT worklet 1:1. */\n note: number;\n resonance: number; // 0\u20134 stored (UI shows % of travel); worklet param is resonance/4\n drive: number;\n}\n\n/** Worklet resonance at knob max: 1.0 is oscillation onset (k = 4), so land\n * a bit past it \u2014 100% RES must ring up confidently, like hardware. */\nconst RES_TOP = 1.1;\n\n// \u2500\u2500\u2500 PARAMS \u2014 the signal contract (no UI knowledge) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nconst params = {\n note: { node: '_cutoffVoct', field: 'transpose', unit: 'note', default: 83, min: 15, max: 135, },\n // Stored 0\u20134 (UI shows % of travel) but the worklet's resonance param is\n // resonance/4\u00B7RES_TOP \u2014 a scale, not a 1:1 mapping \u2014 so this stays set-only.\n resonance: { unit: 'factor', default: 2.5, min: 0, max: 4, scale: 'sqrt', },\n drive: { node: 'ladder', field: 'drive', unit: 'factor', default: 0.3, min: 0, max: 1, },\n} satisfies Record<string, ParamSpec>;\n\n// \u2500\u2500\u2500 UI \u2014 presentation layer (stripped from the library) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n\n// \u2500\u2500\u2500 DESCRIPTOR \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport const ladderFilterDescriptor = /* @__PURE__ */ defineDescriptor({\n type: 'ladder-filter',\n params,\n\n ports: {\n 'in': { type: 'input', signal: 'audio', node: 'input', },\n 'out': { type: 'output', signal: 'audio', node: 'output', },\n 'modFreq': { type: 'modulation', signal: 'modulation', node: '_cutoffVoct', },\n 'modRes': { type: 'modulation', signal: 'modulation', node: 'ladder', field: 'resonance' },\n },\n\n createModule(id: string, position: Position): LadderFilterModule {\n return { id, type: 'ladder-filter', position, ...paramDefaults(params) };\n },\n\n createNodes(ctx, module) {\n const input = ctx.createGain();\n const output = ctx.createGain();\n\n // The whole filter lives in one worklet: 4 one-pole stages with a global\n // tanh-saturated feedback path (see worklets/ladder-filter.ts). Drive is\n // an input-stage saturation *inside* the loop, so no external waveshaper.\n // Knob max maps to 1.1 (k = 4.4), a little PAST oscillation onset (1.0),\n // so 100% RES rings up confidently instead of hovering at the threshold \u2014\n // hardware ladders behave the same at max resonance.\n const ladder = createLadderFilterNode(ctx, {\n resonance: (module.resonance / 4) * RES_TOP,\n drive: module.drive,\n });\n\n // V/Oct cutoff: ConstantSource(0) \u2192 voct(transpose=cutoff note) \u2192 cutoff param\n const _cutoffVoct = createVoctFreqNode(ctx);\n _cutoffVoct.parameters.get('transpose')!.value = module.note;\n\n const _cutoffBase = ctx.createConstantSource();\n _cutoffBase.offset.value = 0;\n _cutoffBase.start();\n _cutoffBase.connect(_cutoffVoct);\n _cutoffVoct.connect(ladder.parameters.get('cutoff')! as AudioParam);\n\n input.connect(ladder);\n ladder.connect(output);\n\n return { input, output, ladder, _cutoffVoct, _cutoffBase };\n },\n\n updateParam(nodes, _module, param, value) {\n switch (param) {\n case 'note':\n nodes._cutoffVoct.parameters.get('transpose')!.value = value as number;\n break;\n case 'resonance':\n nodes.ladder.parameters.get('resonance')!.value = ((value as number) / 4) * RES_TOP;\n break;\n case 'drive':\n nodes.ladder.parameters.get('drive')!.value = value as number;\n break;\n }\n },\n\n dispose(nodes) {\n try { nodes._cutoffBase.stop(); } catch (_) { /* already stopped */ }\n },\n\n});\n", "import { defineModule } from '../../core';\nimport { ladderFilterDescriptor } from './ladder-filter';\nimport type { LadderFilterParams, LadderFilterInputs, LadderFilterOutputs, LadderFilterProps } from './ladder-filter.types';\nimport ladder_filter from '../worklet-src/ladder-filter';\nimport map_voct_to_freq from '../worklet-src/map-voct-to-freq';\n\nexport const LadderFilter = /* @__PURE__ */ defineModule(ladderFilterDescriptor, {\n worklets: {\n 'ladder-filter': ladder_filter,\n 'map-voct-to-freq': map_voct_to_freq,\n },\n}) as import('../../core').LibModule<LadderFilterParams, LadderFilterInputs, LadderFilterOutputs, LadderFilterProps>;\nexport type { LadderFilterParams, LadderFilterInputs, LadderFilterOutputs, LadderFilterProps };\n", "// @ts-nocheck \u2014 generated by scripts/lib/build.ts\nimport type { BaseModule, Position } from '@/types/synth';\n\nexport interface LFOModule extends BaseModule {\n type: 'lfo';\n skew: number; // -1\u20131\n shape: number; // -1\u20131\n frequency: number;\n amount: number;\n}\nimport { defineDescriptor, paramDefaults } from '@/modules/ModuleDescriptor';\nimport { createWaveshaperNode } from '@/worklets';\n\n// \u2500\u2500\u2500 Waveform \u2192 skew/shape mapping for migration \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nconst WAVE_MAP: Record<string, { skew: number; shape: number }> = {\n sine: { skew: 0.0, shape: 1.0 },\n triangle: { skew: 0.0, shape: 0.0 },\n square: { skew: 0.0, shape: -1.0 },\n sawtooth: { skew: 1.0, shape: 0.0 },\n};\n\n// \u2500\u2500\u2500 PARAMS \u2014 the signal contract (no UI knowledge) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n// Canonical DSP identity, range and behaviour. Drives createModule\n// defaults, library param types and library docs. Wording describes the\n// signal, never a panel control.\nconst params = {\n skew: { node: '_ws', field: 'skew', unit: 'factor', default: 0, min: -1, max: 1, },\n shape: { node: '_ws', field: 'shape', unit: 'factor', default: 1, min: -1, max: 1, },\n frequency: { node: '_freqSrc', field: 'offset', default: 2, min: -10, max: 20, unit: 'Hz', },\n amount: { node: 'gain', field: 'gain', unit: 'semitone', default: 12, min: 0, max: 500, scale: 'sqrt', },\n} satisfies Record<string, ParamSpec>;\n\n// \u2500\u2500\u2500 UI \u2014 presentation layer (stripped from the library) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n// Panel labels, knob ranges and hover tips optimised for playing the\n// module. Free to diverge from `params`: e.g. the frequency knob becomes\n// a bipolar OFFSET when Rate CV is patched, and AMT reads BASE under CV.\n\nconst rateKnob = (cv: boolean) => cv\n ? { label: 'OFFSET', min: -10, max: 10, log: false, format: (v: number) => `${v >= 0 ? '+' : ''}${Math.abs(v) < 1 ? v.toFixed(2) : v.toFixed(1)}` }\n : { label: 'RATE', min: 0.01, max: 20, log: true, format: (v: number) => (v < 1 ? v.toFixed(2) : v.toFixed(1)) };\n\n\n// \u2500\u2500\u2500 DESCRIPTOR \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport const lfoDescriptor = /* @__PURE__ */ defineDescriptor({\n type: 'lfo',\n params,\n\n\n\n ports: {\n 'out': { type: 'output', node: 'gain', signal: 'modulation' },\n 'modRate': { type: 'modulation', signal: 'modulation', node: '_freqSrc', field: 'offset' },\n 'modAmount': { type: 'modulation', signal: 'modulation', node: 'gain', field: 'gain' },\n 'modSkew': { type: 'modulation', signal: 'modulation', node: '_ws', field: 'skew' },\n 'modShape': { type: 'modulation', signal: 'modulation', node: '_ws', field: 'shape' },\n \n },\n\n\n createModule(id: string, position: Position): LFOModule {\n return { id, type: 'lfo', position, ...paramDefaults(params) };\n },\n\n createNodes(ctx, module) {\n const _ws = createWaveshaperNode(ctx);\n const gain = ctx.createGain();\n // Feed frequency via ConstantSource\n const _freqSrc = ctx.createConstantSource();\n _freqSrc.offset.value = module.frequency;\n _freqSrc.start();\n _freqSrc.connect(_ws); // frequency input\n\n // Set waveshape\n _ws.parameters.get('skew')!.value = module.skew;\n _ws.parameters.get('shape')!.value = module.shape;\n\n gain.gain.value = module.amount;\n _ws.connect(gain);\n\n return { gain, _ws, _freqSrc };\n },\n\n updateParam(nodes, _module, param, value) {\n switch (param) {\n case 'skew': nodes._ws.parameters.get('skew')!.value = value as number; break;\n case 'shape': nodes._ws.parameters.get('shape')!.value = value as number; break;\n case 'frequency': nodes._freqSrc.offset.value = value as number; break;\n case 'amount': nodes.gain.gain.value = value as number; break;\n }\n },\n\n dispose(nodes) {\n nodes._freqSrc.stop();\n },\n\n});\n", "import { defineModule } from '../../core';\nimport { lfoDescriptor } from './lfo';\nimport type { LfoParams, LfoInputs, LfoOutputs, LfoProps } from './lfo.types';\nimport waveshaper from '../worklet-src/waveshaper';\n\nexport const Lfo = /* @__PURE__ */ defineModule(lfoDescriptor, {\n worklets: {\n 'waveshaper': waveshaper,\n },\n}) as import('../../core').LibModule<LfoParams, LfoInputs, LfoOutputs, LfoProps>;\nexport type { LfoParams, LfoInputs, LfoOutputs, LfoProps };\n", "// @ts-nocheck \u2014 generated by scripts/lib/build.ts\nimport { noiseSource, NOISE_SEEDS } from '@/lib/dsp/prng';\nimport { BaseModule } from '@/types/synth';\n\nexport interface LoFiModule extends BaseModule {\n type: 'lo-fi';\n drive: number;\n cutoff: number;\n noise: number;\n wobble: number;\n}\nimport { defineDescriptor, paramDefaults } from '@/modules/ModuleDescriptor';\n\nfunction makeLoFiSaturationCurve(amount: number): Float32Array {\n const samples = 44100;\n const curve = new Float32Array(samples);\n const k = 1 + amount * 5;\n for (let i = 0; i < samples; i++) {\n const x = (i * 2) / samples - 1;\n curve[i] = x >= 0 ? Math.tanh(k * x * 0.8) : Math.tanh(k * x * 1.2);\n }\n return curve;\n}\n\nconst params = {\n drive: { unit: 'factor', default: 0.3, min: 0, max: 1, },\n cutoff: { node: 'lowpass', field: 'frequency', unit: 'Hz', default: 4000, min: 500, max: 8000, },\n noise: { unit: 'factor', default: 0.2, min: 0, max: 1, },\n wobble: { unit: 'factor', default: 0.1, min: 0, max: 1, },\n} satisfies Record<string, ParamSpec>;\n\n\n\nexport const loFiDescriptor = /* @__PURE__ */ defineDescriptor({\n type: 'lo-fi',\n params,\n\n ports: {\n 'in': { type: 'input', signal: 'audio', node: 'input', },\n 'out': { type: 'output', signal: 'audio', node: 'output', },\n 'modCutoff': { type: 'modulation', signal: 'modulation', node: 'lowpass', field: 'frequency' },\n },\n\n createModule(id, position) {\n return { id, type: 'lo-fi', position, ...paramDefaults(params) };\n },\n\n createNodes(ctx, module) {\n const input = ctx.createGain();\n const output = ctx.createGain();\n const saturation = ctx.createWaveShaper();\n const lowpass = ctx.createBiquadFilter();\n const noiseGain = ctx.createGain();\n const wobbleLfo = ctx.createOscillator();\n const wobbleGain = ctx.createGain();\n\n saturation.curve = makeLoFiSaturationCurve(module.drive) as Float32Array<ArrayBuffer>;\n saturation.oversample = '2x';\n\n lowpass.type = 'lowpass';\n lowpass.frequency.value = module.cutoff;\n lowpass.Q.value = 0.7;\n\n const bufferSize = 2 * ctx.sampleRate;\n const noiseBuffer = ctx.createBuffer(1, bufferSize, ctx.sampleRate);\n const data = noiseBuffer.getChannelData(0);\n const rand = noiseSource(NOISE_SEEDS.loFiCrackle);\n let b0 = 0, b1 = 0, b2 = 0;\n for (let i = 0; i < bufferSize; i++) {\n const white = rand();\n b0 = 0.99765 * b0 + white * 0.0990460;\n b1 = 0.96300 * b1 + white * 0.2965164;\n b2 = 0.57000 * b2 + white * 1.0526913;\n data[i] = (b0 + b1 + b2) * 0.1;\n }\n const noiseSrc = ctx.createBufferSource();\n noiseSrc.buffer = noiseBuffer;\n noiseSrc.loop = true;\n noiseGain.gain.value = module.noise * 0.05;\n noiseSrc.connect(noiseGain);\n noiseSrc.start();\n\n const wobbleDelay = ctx.createDelay(0.05);\n wobbleDelay.delayTime.value = 0.01;\n wobbleLfo.type = 'sine';\n wobbleLfo.frequency.value = 0.73;\n wobbleGain.gain.value = module.wobble * 0.002;\n wobbleLfo.connect(wobbleGain);\n wobbleGain.connect(wobbleDelay.delayTime);\n wobbleLfo.start();\n\n input.connect(saturation);\n saturation.connect(lowpass);\n lowpass.connect(wobbleDelay);\n wobbleDelay.connect(output);\n noiseGain.connect(output);\n\n return { input, output, saturation, lowpass, wobbleDelay, noiseGain, wobbleGain, wobbleLfo, noiseSrc };\n },\n\n updateParam(nodes, _m, param, value) {\n if (param === 'drive') {\n nodes.saturation.curve = makeLoFiSaturationCurve(value as number) as Float32Array<ArrayBuffer>;\n } else if (param === 'cutoff') {\n nodes.lowpass.frequency.value = value as number;\n } else if (param === 'noise') {\n nodes.noiseGain.gain.value = (value as number) * 0.05;\n } else if (param === 'wobble') {\n nodes.wobbleGain.gain.value = (value as number) * 0.002;\n }\n },\n\n dispose(nodes) {\n nodes.wobbleLfo.stop();\n nodes.noiseSrc.stop();\n },\n\n});\n", "import { defineModule } from '../../core';\nimport { loFiDescriptor } from './lo-fi';\nimport type { LoFiParams, LoFiInputs, LoFiOutputs, LoFiProps } from './lo-fi.types';\n\n\nexport const LoFi = /* @__PURE__ */ defineModule(loFiDescriptor) as import('../../core').LibModule<LoFiParams, LoFiInputs, LoFiOutputs, LoFiProps>;\nexport type { LoFiParams, LoFiInputs, LoFiOutputs, LoFiProps };\n", "// @ts-nocheck \u2014 generated by scripts/lib/build.ts\nimport type { BaseModule, Position } from '@/types/synth';\n\nexport interface MidSideModule extends BaseModule {\n type: 'mid-side';\n midGain: number;\n sideGain: number;\n}\nimport { defineDescriptor, paramDefaults } from '@/modules/ModuleDescriptor';\n\n// \u2500\u2500\u2500 PARAMS \u2014 the signal contract \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n// sideGain used to be baked into ONE gain node as sideGain*width (not a\n// single AudioParam). Split into two chained gain stages so each param maps\n// 1:1 onto its own AudioParam.\nconst params = {\n midGain: { node: 'midGainNode', field: 'gain', unit: 'factor', default: 1, min: 0, max: 2, },\n sideGain: { node: 'sideGainNode', field: 'gain', unit: 'factor', default: 1, min: 0, max: 2, },\n} satisfies Record<string, ParamSpec>;\n\n\nexport const midSideDescriptor = /* @__PURE__ */ defineDescriptor({\n type: 'mid-side' as const,\n params,\n\n ports: {\n 'in': { type: 'input' as const, signal: 'audio', node: 'input', },\n 'out': { type: 'output' as const, signal: 'audio', node: 'output', },\n },\n\n createModule(id: string, position: Position): MidSideModule {\n return { id, type: 'mid-side', position, ...paramDefaults(params) };\n },\n\n createNodes(ctx, module) {\n // Force stereo interpretation so a mono source upmixes to L=R (side = 0)\n const input = ctx.createGain();\n input.channelCount = 2;\n input.channelCountMode = 'explicit';\n input.channelInterpretation = 'speakers';\n\n const output = ctx.createGain();\n const splitter = ctx.createChannelSplitter(2);\n const merger = ctx.createChannelMerger(2);\n\n // \u2500\u2500 Encode: M = (L+R)/2, S = (L-R)/2 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n const midSum = ctx.createGain(); // L + R, halved\n midSum.gain.value = 0.5;\n const sideSum = ctx.createGain(); // L - R, halved\n sideSum.gain.value = 0.5;\n const rInvEnc = ctx.createGain(); // -R for the difference\n rInvEnc.gain.value = -1;\n\n input.connect(splitter);\n splitter.connect(midSum, 0);\n splitter.connect(midSum, 1);\n splitter.connect(sideSum, 0);\n splitter.connect(rInvEnc, 1);\n rInvEnc.connect(sideSum);\n\n // \u2500\u2500 Gain stage on the M and S components \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n // sideGainNode and widthNode are two chained AudioParams (each 1:1 with\n // its own param) instead of one node carrying sideGain*width.\n const midGainNode = ctx.createGain();\n midGainNode.gain.value = module.midGain;\n const sideGainNode = ctx.createGain();\n sideGainNode.gain.value = module.sideGain;\n const widthNode = ctx.createGain();\n widthNode.gain.value = module.width;\n\n midSum.connect(midGainNode);\n sideSum.connect(sideGainNode);\n sideGainNode.connect(widthNode);\n\n // \u2500\u2500 Decode: L = M + S, R = M - S \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n const leftOut = ctx.createGain();\n const rightOut = ctx.createGain();\n const sideInvDec = ctx.createGain();\n sideInvDec.gain.value = -1;\n\n midGainNode.connect(leftOut);\n midGainNode.connect(rightOut);\n widthNode.connect(leftOut);\n widthNode.connect(sideInvDec);\n sideInvDec.connect(rightOut);\n\n leftOut.connect(merger, 0, 0);\n rightOut.connect(merger, 0, 1);\n merger.connect(output);\n\n return { input, output, midGainNode, sideGainNode, widthNode };\n },\n\n updateParam(nodes, _module, param, value) {\n if (param === 'midGain') nodes.midGainNode.gain.value = value as number;\n else if (param === 'sideGain') nodes.sideGainNode.gain.value = value as number;\n else if (param === 'width') nodes.widthNode.gain.value = value as number;\n },\n\n});\n", "import { defineModule } from '../../core';\nimport { midSideDescriptor } from './mid-side';\nimport type { MidSideParams, MidSideInputs, MidSideOutputs, MidSideProps } from './mid-side.types';\n\n\nexport const MidSide = /* @__PURE__ */ defineModule(midSideDescriptor) as import('../../core').LibModule<MidSideParams, MidSideInputs, MidSideOutputs, MidSideProps>;\nexport type { MidSideParams, MidSideInputs, MidSideOutputs, MidSideProps };\n", "// @ts-nocheck \u2014 generated by scripts/lib/build.ts\nimport { noiseSource, NOISE_SEEDS } from '@/lib/dsp/prng';\nimport type { BaseModule, Position, NoiseType } from '@/types/synth';\nimport { defineDescriptor, paramDefaults } from '@/modules/ModuleDescriptor';\n\nexport interface NoiseModule extends BaseModule {\n type: 'noise';\n noiseType: NoiseType;\n gain: number;\n}\n\n// \u2500\u2500\u2500 PARAMS \u2014 the signal contract \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n// `gain` maps 1:1 onto output.gain (updateParam still smooths it with\n// setTargetAtTime to avoid zippering when a modLevel CV sums on top).\n// `noiseType` cross-fades three pre-rendered buffers \u2014 not a single\n// AudioParam \u2014 so it stays a set-only enum.\nconst params = {\n noiseType: { kind: 'enum', default: 'white', options: ['white', 'pink', 'brown'], },\n gain: { node: 'output', field: 'gain', unit: 'factor', default: 0.3, min: 0, max: 1, },\n} satisfies Record<string, ParamSpec>;\n\n// \u2500\u2500\u2500 NOISE BUFFER GENERATION \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n// Seeded per type: the buffer loops every 2 s regardless, so this only picks\n// *which* random loop plays \u2014 inaudible, but it makes renders reproducible\n// (see src/lib/dsp/prng.ts).\n\nfunction generateNoiseBuffer(ctx: AudioContext, type: NoiseType): AudioBuffer {\n const bufferSize = 2 * ctx.sampleRate;\n const buffer = ctx.createBuffer(1, bufferSize, ctx.sampleRate);\n const data = buffer.getChannelData(0);\n\n if (type === 'white') {\n const rand = noiseSource(NOISE_SEEDS.noiseWhite);\n for (let i = 0; i < bufferSize; i++) data[i] = rand();\n } else if (type === 'pink') {\n const rand = noiseSource(NOISE_SEEDS.noisePink);\n let b0 = 0, b1 = 0, b2 = 0, b3 = 0, b4 = 0, b5 = 0, b6 = 0;\n for (let i = 0; i < bufferSize; i++) {\n const w = rand();\n b0 = 0.99886 * b0 + w * 0.0555179;\n b1 = 0.99332 * b1 + w * 0.0750759;\n b2 = 0.96900 * b2 + w * 0.1538520;\n b3 = 0.86650 * b3 + w * 0.3104856;\n b4 = 0.55000 * b4 + w * 0.5329522;\n b5 = -0.7616 * b5 - w * 0.0168980;\n data[i] = (b0 + b1 + b2 + b3 + b4 + b5 + b6 + w * 0.5362) * 0.11;\n b6 = w * 0.115926;\n }\n } else {\n const rand = noiseSource(NOISE_SEEDS.noiseBrown);\n let lastOut = 0;\n for (let i = 0; i < bufferSize; i++) {\n const w = rand();\n data[i] = (lastOut + 0.02 * w) / 1.02;\n lastOut = data[i];\n data[i] *= 3.5;\n }\n }\n return buffer;\n}\n\n// \u2500\u2500\u2500 UI \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nconst noiseOptions = [\n { value: 'white' as NoiseType, label: 'WHT' },\n { value: 'pink' as NoiseType, label: 'PNK' },\n { value: 'brown' as NoiseType, label: 'BRN' },\n];\n\n\n// \u2500\u2500\u2500 DESCRIPTOR \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport const noiseDescriptor = /* @__PURE__ */ defineDescriptor({\n type: 'noise',\n params,\n\n\n ports: {\n 'out': { type: 'output', signal: 'audio', node: 'output', },\n 'modLevel': { type: 'modulation', signal: 'modulation', node: 'output', field: 'gain' },\n },\n\n createModule(id: string, position: Position): NoiseModule {\n return { id, type: 'noise', position, ...paramDefaults(params) } as NoiseModule;\n },\n\n createNodes(ctx, module) {\n const whiteSrc = ctx.createBufferSource();\n whiteSrc.buffer = generateNoiseBuffer(ctx, 'white');\n whiteSrc.loop = true;\n const pinkSrc = ctx.createBufferSource();\n pinkSrc.buffer = generateNoiseBuffer(ctx, 'pink');\n pinkSrc.loop = true;\n const brownSrc = ctx.createBufferSource();\n brownSrc.buffer = generateNoiseBuffer(ctx, 'brown');\n brownSrc.loop = true;\n\n const whiteGain = ctx.createGain();\n const pinkGain = ctx.createGain();\n const brownGain = ctx.createGain();\n\n whiteGain.gain.value = module.noiseType === 'white' ? 1 : 0;\n pinkGain.gain.value = module.noiseType === 'pink' ? 1 : 0;\n brownGain.gain.value = module.noiseType === 'brown' ? 1 : 0;\n\n const output = ctx.createGain();\n output.gain.value = module.gain;\n\n whiteSrc.connect(whiteGain);\n pinkSrc.connect(pinkGain);\n brownSrc.connect(brownGain);\n whiteGain.connect(output);\n pinkGain.connect(output);\n brownGain.connect(output);\n\n whiteSrc.start(0);\n pinkSrc.start(0);\n brownSrc.start(0);\n\n return { output, whiteGain, pinkGain, brownGain, _whiteSrc: whiteSrc, _pinkSrc: pinkSrc, _brownSrc: brownSrc };\n },\n\n updateParam(nodes, _module, param, value) {\n const t = nodes.output.context.currentTime;\n switch (param) {\n case 'noiseType':\n nodes.whiteGain.gain.setTargetAtTime(value === 'white' ? 1 : 0, t, 0.005);\n nodes.pinkGain.gain.setTargetAtTime(value === 'pink' ? 1 : 0, t, 0.005);\n nodes.brownGain.gain.setTargetAtTime(value === 'brown' ? 1 : 0, t, 0.005);\n break;\n case 'gain':\n // Smoothed like noiseType above: a hard .value write stomps the\n // AudioParam's intrinsic value with no ramp, which zippers/clicks\n // when a modLevel CV is summing on top (noise report Finding #1).\n nodes.output.gain.setTargetAtTime(value as number, t, 0.005);\n break;\n }\n },\n\n dispose(nodes) {\n try { nodes._whiteSrc.stop(); } catch (_) {}\n try { nodes._pinkSrc.stop(); } catch (_) {}\n try { nodes._brownSrc.stop(); } catch (_) {}\n },\n\n});\n", "import { defineModule } from '../../core';\nimport { noiseDescriptor } from './noise';\nimport type { NoiseParams, NoiseInputs, NoiseOutputs, NoiseProps } from './noise.types';\n\n\nexport const Noise = /* @__PURE__ */ defineModule(noiseDescriptor) as import('../../core').LibModule<NoiseParams, NoiseInputs, NoiseOutputs, NoiseProps>;\nexport type { NoiseParams, NoiseInputs, NoiseOutputs, NoiseProps };\n", "// @ts-nocheck \u2014 generated by scripts/lib/build.ts\nimport type { BaseModule, Position } from '@/types/synth';\nimport { defineDescriptor, paramDefaults } from '@/modules/ModuleDescriptor';\nimport { createOctaverDividerNode } from '@/worklets';\n\nexport interface OctaverModule extends BaseModule {\n type: 'octaver';\n octDown1: number;\n octDown2: number;\n octUp: number;\n dry: number;\n}\n\n// \u2500\u2500\u2500 PARAMS \u2014 the signal contract (no UI knowledge) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n// All four voices are plain gain sends \u2014 genuine 1:1 AudioParam writes.\nconst params = {\n octDown2: { node: 'oct2Gain', field: 'gain', unit: 'factor', default: 0.3, min: 0, max: 1, },\n octDown1: { node: 'oct1Gain', field: 'gain', unit: 'factor', default: 0.5, min: 0, max: 1, },\n dry: { node: 'dryGain', field: 'gain', unit: 'factor', default: 0.7, min: 0, max: 1, },\n octUp: { node: 'octUpGain', field: 'gain', unit: 'factor', default: 0, min: 0, max: 1, },\n} satisfies Record<string, ParamSpec>;\n\n\nfunction makeFullWaveRectifierCurve(): Float32Array {\n const samples = 8192;\n const curve = new Float32Array(samples);\n for (let i = 0; i < samples; i++) {\n const x = (i * 2) / samples - 1;\n curve[i] = Math.abs(x) * 2 - 1; // rectify and re-centre\n }\n return curve;\n}\n\n\nexport const octaverDescriptor = /* @__PURE__ */ defineDescriptor({\n type: 'octaver',\n params,\n\n ports: {\n 'in': { type: 'input', signal: 'audio', node: 'input', },\n 'out': { type: 'output', signal: 'audio', node: 'output', },\n },\n\n createModule(id: string, position: Position): OctaverModule {\n return { id, type: 'octaver', position, ...paramDefaults(params) };\n },\n\n createNodes(ctx, module) {\n const input = ctx.createGain();\n const output = ctx.createGain();\n const dryGain = ctx.createGain();\n const oct1Gain = ctx.createGain();\n const oct2Gain = ctx.createGain();\n const octUpGain = ctx.createGain();\n\n // \u2500\u2500 True frequency division (worklet, zero-crossing flip-flop) \u2500\u2500\u2500\u2500\n const divider = createOctaverDividerNode(ctx);\n (divider.parameters as unknown as Map<string, AudioParam>).get('oct1Level')!.value = 1;\n (divider.parameters as unknown as Map<string, AudioParam>).get('oct2Level')!.value = 1;\n\n const splitter = ctx.createChannelSplitter(2);\n\n const lowpass1 = ctx.createBiquadFilter();\n lowpass1.type = 'lowpass'; lowpass1.frequency.value = 1200; lowpass1.Q.value = 0.7;\n const lowpass2 = ctx.createBiquadFilter();\n lowpass2.type = 'lowpass'; lowpass2.frequency.value = 600; lowpass2.Q.value = 0.7;\n\n // \u2500\u2500 Octave up: rectifier + pitch-tracked bandpass \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n const waveshaperUp = ctx.createWaveShaper();\n waveshaperUp.curve = makeFullWaveRectifierCurve() as Float32Array<ArrayBuffer>;\n const bpUp = ctx.createBiquadFilter();\n bpUp.type = 'bandpass';\n bpUp.frequency.value = 20; // floor; the tracked estimate is summed on top\n bpUp.Q.value = 2.5;\n const freqTrack = ctx.createGain();\n freqTrack.gain.value = 2; // octave up = 2\u00D7 the detected fundamental\n\n dryGain.gain.value = module.dry;\n oct1Gain.gain.value = module.octDown1;\n oct2Gain.gain.value = module.octDown2;\n octUpGain.gain.value = module.octUp;\n\n input.connect(dryGain);\n\n input.connect(divider);\n divider.connect(splitter, 1, 0); // raw square outputs\n splitter.connect(lowpass1, 0);\n splitter.connect(lowpass2, 1);\n lowpass1.connect(oct1Gain);\n lowpass2.connect(oct2Gain);\n\n divider.connect(freqTrack, 2, 0); // Hz estimate\n freqTrack.connect(bpUp.frequency);\n\n input.connect(waveshaperUp);\n waveshaperUp.connect(bpUp);\n bpUp.connect(octUpGain);\n\n dryGain.connect(output);\n oct1Gain.connect(output);\n oct2Gain.connect(output);\n octUpGain.connect(output);\n\n return { input, output, dryGain, oct1Gain, oct2Gain, octUpGain, divider, bpUp, freqTrack };\n },\n\n updateParam(nodes, _m, param, value) {\n if (param === 'dry') nodes.dryGain.gain.value = value as number;\n else if (param === 'octDown1') nodes.oct1Gain.gain.value = value as number;\n else if (param === 'octDown2') nodes.oct2Gain.gain.value = value as number;\n else if (param === 'octUp') nodes.octUpGain.gain.value = value as number;\n },\n\n});\n", "import { defineModule } from '../../core';\nimport { octaverDescriptor } from './octaver';\nimport type { OctaverParams, OctaverInputs, OctaverOutputs, OctaverProps } from './octaver.types';\nimport freq_divider from '../worklet-src/freq-divider';\n\nexport const Octaver = /* @__PURE__ */ defineModule(octaverDescriptor, {\n worklets: {\n 'freq-divider': freq_divider,\n },\n}) as import('../../core').LibModule<OctaverParams, OctaverInputs, OctaverOutputs, OctaverProps>;\nexport type { OctaverParams, OctaverInputs, OctaverOutputs, OctaverProps };\n", "// @ts-nocheck \u2014 generated by scripts/lib/build.ts\nimport { BaseModule } from '@/types/synth';\n\nexport interface PhaserModule extends BaseModule {\n type: 'phaser';\n rate: number;\n depth: number;\n feedback: number;\n mix: number;\n}\nimport { defineDescriptor, paramDefaults } from '@/modules/ModuleDescriptor';\nimport { createMix } from '@/lib/dsp/mix';\n\nconst params = {\n rate: { node: 'lfo', field: 'frequency', unit: 'Hz', default: 0.5, min: 0.1, max: 10, },\n depth: { unit: 'factor', default: 0.7, min: 0, max: 1, },\n feedback: { node: 'feedback', field: 'gain', unit: 'factor', default: 0.6, min: 0, max: 0.9, },\n mix: { node: '_mix', field: 'offset', unit: 'factor', default: 0.5, min: 0, max: 1, },\n} satisfies Record<string, ParamSpec>;\n\n\n\nexport const phaserDescriptor = /* @__PURE__ */ defineDescriptor({\n type: 'phaser',\n params,\n\n ports: {\n 'in': { type: 'input', signal: 'audio', node: 'input', },\n 'out': { type: 'output', signal: 'audio', node: 'output', },\n 'modRate': { type: 'modulation', signal: 'modulation', node: 'lfo', field: 'frequency' },\n 'modFeedback': { type: 'modulation', signal: 'modulation', node: 'feedback', field: 'gain' },\n 'modMix': { type: 'modulation', signal: 'modulation', node: '_mix', field: 'offset' },\n },\n\n createModule(id, position) {\n return { id, type: 'phaser', position, ...paramDefaults(params) };\n },\n\n createNodes(ctx, module) {\n const input = ctx.createGain();\n const output = ctx.createGain();\n const dryGain = ctx.createGain();\n const wetGain = ctx.createGain();\n const lfo = ctx.createOscillator();\n const feedback = ctx.createGain();\n const stageBases = [200, 400, 600, 800];\n const allpasses = stageBases.map((base) => {\n const ap = ctx.createBiquadFilter();\n ap.type = 'allpass';\n ap.frequency.value = base;\n ap.Q.value = 0.5;\n return ap;\n });\n const stageGains = stageBases.map((base) => {\n const g = ctx.createGain();\n g.gain.value = module.depth * base * 0.8;\n return g;\n });\n const _mix = createMix(ctx, dryGain, wetGain, module.mix, 'linear');\n feedback.gain.value = module.feedback;\n lfo.type = 'sine';\n lfo.frequency.value = module.rate;\n allpasses.forEach((ap, i) => {\n lfo.connect(stageGains[i]);\n stageGains[i].connect(ap.frequency);\n });\n lfo.start();\n input.connect(dryGain);\n input.connect(allpasses[0]);\n allpasses[0].connect(allpasses[1]);\n allpasses[1].connect(allpasses[2]);\n allpasses[2].connect(allpasses[3]);\n allpasses[3].connect(feedback);\n feedback.connect(allpasses[0]);\n allpasses[3].connect(wetGain);\n dryGain.connect(output);\n wetGain.connect(output);\n return {\n input, output, lfo, feedback, dryGain, wetGain, _mix,\n stageGain0: stageGains[0], stageGain1: stageGains[1],\n stageGain2: stageGains[2], stageGain3: stageGains[3],\n };\n },\n\n updateParam(nodes, _m, param, value) {\n switch (param) {\n case 'rate': nodes.lfo.frequency.value = value as number; break;\n case 'depth': {\n const d = value as number;\n [200, 400, 600, 800].forEach((base, i) => {\n const g = nodes[`stageGain${i}` as 'stageGain0'] as GainNode;\n g.gain.value = d * base * 0.8;\n });\n break;\n }\n case 'feedback': nodes.feedback.gain.value = value as number; break;\n case 'mix': (nodes._mix as ConstantSourceNode).offset.value = value as number; break;\n }\n },\n\n dispose(nodes) {\n nodes.lfo.stop();\n (nodes._mix as ConstantSourceNode).stop();\n },\n\n});\n", "import { defineModule } from '../../core';\nimport { phaserDescriptor } from './phaser';\nimport type { PhaserParams, PhaserInputs, PhaserOutputs, PhaserProps } from './phaser.types';\n\n\nexport const Phaser = /* @__PURE__ */ defineModule(phaserDescriptor) as import('../../core').LibModule<PhaserParams, PhaserInputs, PhaserOutputs, PhaserProps>;\nexport type { PhaserParams, PhaserInputs, PhaserOutputs, PhaserProps };\n", "// @ts-nocheck \u2014 generated by scripts/lib/build.ts\nimport type { BaseModule, Position } from '@/types/synth';\nimport { defineDescriptor, paramDefaults } from '@/modules/ModuleDescriptor';\nimport { createPingPongNode } from '@/worklets';\nimport { createMix } from '@/lib/dsp/mix';\n\nexport interface PingPongModule extends BaseModule {\n type: 'ping-pong';\n time: number;\n feedback: number;\n spread: number;\n mix: number;\n}\n\n// \u2500\u2500\u2500 PARAMS \u2014 the signal contract \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n// `time`/`feedback` drive the ping-pong worklet's own AudioParams 1:1.\n// `spread` sets two StereoPannerNode.pan values at once \u2014 not a single\n// AudioParam \u2014 so it stays a set-only enum-like knob. `mix` now runs\n// through createMix's ConstantSource (`_mix`), linear law.\nconst params = {\n time: { node: 'worklet', field: 'time', unit: 's', default: 0.3, min: 0.1, max: 1, scale: 'log', },\n feedback: { node: 'worklet', field: 'feedback', unit: 'factor', default: 0.4, min: 0, max: 0.9, },\n spread: { unit: 'factor', default: 1, min: 0, max: 1, },\n mix: { node: '_mix', field: 'offset', unit: 'factor', default: 0.5, min: 0, max: 1, },\n} satisfies Record<string, ParamSpec>;\n\n\nexport const pingPongDescriptor = /* @__PURE__ */ defineDescriptor({\n type: 'ping-pong' as const,\n params,\n\n ports: {\n 'in': { type: 'input' as const, signal: 'audio', node: 'input', },\n 'out': { type: 'output' as const, signal: 'audio', node: 'output', },\n },\n\n createModule(id: string, position: Position): PingPongModule {\n return { id, type: 'ping-pong', position, ...paramDefaults(params) } as PingPongModule;\n },\n\n // The delay lines and cross-feedback live in the 'ping-pong' AudioWorklet\n // (src/worklets/ping-pong.ts) as of 2026-08-08. A native two-DelayNode\n // cycle carries ONE render quantum of hidden latency at an UNSTABLE\n // position: identical code measured +3.01 dB (coherent grid) on one run\n // and \u22120.19 dB (right leg off by a quantum) on the next, so no static\n // delayTime compensation can hold the tap grid. The worklet's grid is\n // exact by construction. Pans, spread, and dry/wet mix stay native.\n createNodes(ctx, module) {\n const input = ctx.createGain();\n const output = ctx.createGain();\n const dryGain = ctx.createGain();\n const wetGain = ctx.createGain();\n const panL = ctx.createStereoPanner();\n const panR = ctx.createStereoPanner();\n const worklet = createPingPongNode(ctx, {\n time: module.time,\n feedback: module.feedback,\n });\n\n panL.pan.value = -module.spread;\n panR.pan.value = module.spread;\n\n const _mix = createMix(ctx, dryGain, wetGain, module.mix, 'linear');\n\n input.connect(dryGain);\n input.connect(worklet);\n worklet.connect(panL, 0); // output 0: L taps at T, 4T, 7T\u2026\n worklet.connect(panR, 1); // output 1: R taps at 3T, 6T, 9T\u2026\n panL.connect(wetGain);\n panR.connect(wetGain);\n dryGain.connect(output);\n wetGain.connect(output);\n\n return { input, output, worklet, dryGain, wetGain, panL, panR, _mix };\n },\n\n updateParam(nodes, _m, param, value) {\n if (param === 'time' || param === 'feedback') {\n const p = (nodes.worklet as AudioWorkletNode).parameters.get(param);\n if (p) p.value = value as number;\n } else if (param === 'spread') {\n nodes.panL.pan.value = -(value as number);\n nodes.panR.pan.value = value as number;\n } else if (param === 'mix') {\n (nodes._mix as ConstantSourceNode).offset.value = value as number;\n }\n },\n\n});\n", "import { defineModule } from '../../core';\nimport { pingPongDescriptor } from './ping-pong';\nimport type { PingPongParams, PingPongInputs, PingPongOutputs, PingPongProps } from './ping-pong.types';\nimport ping_pong from '../worklet-src/ping-pong';\n\nexport const PingPong = /* @__PURE__ */ defineModule(pingPongDescriptor, {\n worklets: {\n 'ping-pong': ping_pong,\n },\n}) as import('../../core').LibModule<PingPongParams, PingPongInputs, PingPongOutputs, PingPongProps>;\nexport type { PingPongParams, PingPongInputs, PingPongOutputs, PingPongProps };\n", "/**\n * Modal-resonator maths \u2014 the RESO module's DAMP law, kept pure so it is\n * unit-tested directly (modal.test.ts) instead of only through patches.\n *\n * Each mode is a second-order bandpass (Web Audio's RBJ biquad), i.e. a\n * damped harmonic oscillator whose poles sit at \u2212\u03C90/(2Q). Its impulse\n * response decays as e^(\u2212\u03C90\u00B7t / 2Q), so the time to fall 60 dB is\n *\n * ```text\n * T60 = 2Q\u00B7ln(1000) / \u03C90 = (3\u00B7ln10 / \u03C0) \u00B7 Q / f0 \u2248 2.2 \u00B7 Q / f0\n * ```\n *\n * Q is constant across the five modes, so upper partials die proportionally\n * faster than the fundamental \u2014 the brightness-first decay of a real plucked\n * string or struck bar (and the constant-Q choice of classic modal designs).\n *\n * DAMP maps exponentially onto Q over 2.7 decades, which is what makes it a\n * decay-TIME control rather than a narrow tone knob: at A3 it spans ~10 s\n * (DAMP 0) to ~20 ms (DAMP 1), equal knob travel = equal ratio of ring time.\n */\n\n/** DAMP 0 \u2014 longest ring: ~10 s at A3, ~40 s at the bottom of FREQ. */\nexport const MODAL_Q_MAX = 1000;\n/** DAMP 1 \u2014 a damped thud: ~20 ms at A3. */\nexport const MODAL_Q_MIN = 2;\n\n/** T60 per unit Q per unit Hz: 3\u00B7ln(10)/\u03C0 \u2248 2.199 s\u00B7Hz. */\nexport const T60_PER_Q_HZ = (3 * Math.LN10) / Math.PI;\n\n/** DAMP (0\u20131) \u2192 mode Q, exponential between MODAL_Q_MAX and MODAL_Q_MIN. */\nexport function dampingToQ(damping: number): number {\n const d = Math.min(1, Math.max(0, Number.isFinite(damping) ? damping : 0.5));\n return MODAL_Q_MAX * Math.pow(MODAL_Q_MIN / MODAL_Q_MAX, d);\n}\n\n/** Seconds for a mode at `hz` with quality `q` to ring down 60 dB. */\nexport function modeT60(q: number, hz: number): number {\n return (T60_PER_Q_HZ * q) / hz;\n}\n\n/**\n * Per-mode makeup, \u221AQ and deliberately UNCAPPED (unlike the filters'\n * `bandpassMakeup`, whose cap guards a self-oscillating filter from a sine\n * parked on its peak). A unity-peak bandpass passes (\u03C0/2)\u00B7f0/Q of white\n * noise's bandwidth \u2014 and, by Parseval, a strike's impulse-response energy\n * scales the same way \u2014 so \u221AQ holds both the steady-state loudness of a\n * noise-fed bank and the total energy of a pluck constant across all of\n * DAMP. Less damping = the same strike spread over a longer ring, never a\n * quieter one (the capped version lost 18 dB at DAMP 0).\n */\nexport function modalMakeup(q: number): number {\n return Math.sqrt(Math.max(1, q));\n}\n", "// @ts-nocheck \u2014 generated by scripts/lib/build.ts\nimport { createMix } from '@/lib/dsp/mix';\nimport type { BaseModule, Position } from '@/types/synth';\n\n\nexport interface ResonatorModule extends BaseModule {\n type: 'resonator';\n note: number; // panel memory: absolute root note while V/OCT is unpatched\n transpose?: number; // panel memory: semitone shift while V/OCT is patched\n offset?: number; // library-only DSP state (see params.offset); the app derives it\n structure: number;\n damping: number;\n mix: number;\n}\nimport { defineDescriptor, paramDefaults } from '@/modules/ModuleDescriptor';\nimport { createVoctFreqNode } from '@/worklets';\nimport { dampingToQ, modalMakeup } from '@/lib/dsp/modal';\n\n// \u2500\u2500\u2500 PARAMS (single source of truth: knobs, defaults, hover tips, docs) \u2500\u2500\nconst params = {\n // Root pitch = V/OCT input (absolute notes, silence = 0) + MOD (semitones) + offset.\n offset: { node: '_root', field: 'offset', default: 57, min: -48, max: 108, unit: 'semitone', },\n structure: { unit: 'factor', default: 0, min: 0, max: 1, },\n damping: { unit: 'factor', default: 0.5, min: 0, max: 1, },\n mix: { node: '_mix', field: 'offset', unit: 'factor', default: 0.5, min: 0, max: 1, },\n} as const satisfies Record<string, ParamSpec>;\n\n/** Partial n sits at root \u00B7 n^(1+structure): as a pitch offset that is\n * 12\u00B7log2(n^(1+structure)) semitones above the root. */\nfunction partialOffset(partial: number, structure: number): number {\n return 12 * (1 + structure) * Math.log2(partial);\n}\n\n/** Cables currently on V/OCT, per node set \u2014 picks the live panel memory. */\nconst patchCount = new WeakMap<object, number>();\n\n\n/** Ring time at the root as the DAMP readout: \"85ms\", \"1.2s\", \"12s\". */\nfunction fmtT60(t: number): string {\n return t < 1 ? `${Math.round(t * 1000)}ms` : t < 10 ? `${t.toFixed(1)}s` : `${Math.round(t)}s`;\n}\n\n\nexport const resonatorDescriptor = /* @__PURE__ */ defineDescriptor({\n type: 'resonator' as const,\n params,\n\n ports: {\n 'in': { type: 'input' as const, signal: 'audio', node: 'input', },\n 'out': { type: 'output' as const, signal: 'audio', node: 'output', },\n 'voct': { type: 'input' as const, signal: 'pitch', node: '_pitch', },\n 'modFreq': { type: 'modulation' as const, signal: 'modulation', node: '_pitch', },\n },\n\n\n createModule(id: string, position: Position): ResonatorModule {\n const { offset: _dsp, ...rest } = paramDefaults(params);\n return { id, type: 'resonator', position, ...rest, note: 57, transpose: 0 };\n },\n\n createNodes(ctx, module) {\n const input = ctx.createGain();\n const output = ctx.createGain();\n const dryGain = ctx.createGain();\n const wetGain = ctx.createGain();\n\n // Pitch bus: root note (ConstantSource, the `note` param 1:1) + FM/V/OCT\n // semitones sum here, then fan out to one V/OCT\u2192Hz converter per partial.\n // Each converter's `transpose` holds that partial's fixed offset, so the\n // whole series tracks pitch \u2014 previously only f1 did, and f2\u2013f5 sat at\n // knob-computed Hz while the root moved.\n const _root = ctx.createConstantSource();\n _root.offset.value = module.offset ?? module.note;\n _root.start();\n const _pitch = ctx.createGain();\n _root.connect(_pitch);\n\n const filters: BiquadFilterNode[] = [];\n const partialGains: GainNode[] = [];\n const voct: AudioWorkletNode[] = [];\n const q = dampingToQ(module.damping);\n const makeup = modalMakeup(q);\n for (let i = 1; i <= 5; i++) {\n const v = createVoctFreqNode(ctx as AudioContext);\n v.parameters.get('transpose')!.value = partialOffset(i, module.structure);\n _pitch.connect(v);\n const filter = ctx.createBiquadFilter();\n filter.type = 'bandpass';\n filter.frequency.value = 0; // driven by the partial's converter\n v.connect(filter.frequency);\n filter.Q.value = q;\n filters.push(filter);\n voct.push(v);\n input.connect(filter);\n // Each mode gets \u221AQ (energy-invariant across DAMP \u2014 see dsp/modal.ts)\n // and a gentle 1/\u221An tilt so the upper partials sit behind the root;\n // five narrow unity-peak bands alone would throw the excitation away.\n const partialGain = ctx.createGain();\n partialGain.gain.value = makeup / Math.sqrt(i);\n filter.connect(partialGain);\n partialGain.connect(wetGain);\n partialGains.push(partialGain);\n }\n\n const _mix = createMix(ctx, dryGain, wetGain, module.mix, 'linear', 0.6);\n input.connect(dryGain);\n dryGain.connect(output);\n wetGain.connect(output);\n\n return {\n input, output, dryGain, wetGain, _mix, _root, _pitch,\n v1: voct[0], v2: voct[1], v3: voct[2], v4: voct[3], v5: voct[4],\n f1: filters[0], f2: filters[1], f3: filters[2], f4: filters[3], f5: filters[4],\n g1: partialGains[0], g2: partialGains[1], g3: partialGains[2],\n g4: partialGains[3], g5: partialGains[4],\n };\n },\n\n updateParam(nodes, _module, param, value) {\n const filters = [nodes.f1, nodes.f2, nodes.f3, nodes.f4, nodes.f5];\n if (param === 'offset') {\n nodes._root.offset.value = value as number;\n } else if (param === 'note') {\n if (!patchCount.get(nodes)) nodes._root.offset.value = value as number;\n } else if (param === 'transpose') {\n if (patchCount.get(nodes)) nodes._root.offset.value = value as number;\n } else if (param === 'structure') {\n const voct = [nodes.v1, nodes.v2, nodes.v3, nodes.v4, nodes.v5];\n for (let i = 1; i < 5; i++) {\n voct[i].parameters.get('transpose')!.value = partialOffset(i + 1, value as number);\n }\n } else if (param === 'damping') {\n const q = dampingToQ(value as number);\n const makeup = modalMakeup(q);\n const gains = [nodes.g1, nodes.g2, nodes.g3, nodes.g4, nodes.g5];\n for (let i = 0; i < 5; i++) {\n filters[i].Q.value = q;\n gains[i].gain.value = makeup / Math.sqrt(i + 1);\n }\n } else if (param === 'mix') {\n nodes._mix.offset.value = value as number;\n }\n },\n\n // App-only: plain summing connect; the hooks only swap which panel memory\n // drives the offset.\n onConnect(nodes, module, portId, sourceNode) {\n if (portId !== 'voct') return false;\n sourceNode.connect(nodes._pitch);\n patchCount.set(nodes, (patchCount.get(nodes) ?? 0) + 1);\n nodes._root.offset.value = module.transpose ?? 0;\n return true;\n },\n\n onDisconnect(nodes, module, portId, sourceNode) {\n if (portId !== 'voct') return false;\n try { sourceNode.disconnect(nodes._pitch); } catch (_) {}\n const n = Math.max(0, (patchCount.get(nodes) ?? 0) - 1);\n patchCount.set(nodes, n);\n if (!n) nodes._root.offset.value = module.note;\n return true;\n },\n\n dispose(nodes) {\n nodes._root.stop();\n },\n\n});\n", "import { defineModule } from '../../core';\nimport { resonatorDescriptor } from './resonator';\nimport type { ResonatorParams, ResonatorInputs, ResonatorOutputs, ResonatorProps } from './resonator.types';\nimport map_voct_to_freq from '../worklet-src/map-voct-to-freq';\n\nexport const Resonator = /* @__PURE__ */ defineModule(resonatorDescriptor, {\n worklets: {\n 'map-voct-to-freq': map_voct_to_freq,\n },\n}) as import('../../core').LibModule<ResonatorParams, ResonatorInputs, ResonatorOutputs, ResonatorProps>;\nexport type { ResonatorParams, ResonatorInputs, ResonatorOutputs, ResonatorProps };\n", "/**\n * Schroeder / small-FDN reverb tank.\n *\n * Topology (implemented inside the `fdn-reverb` AudioWorklet):\n * in \u2500\u25BA 4 parallel damped comb filters, whose feedback taps are cross-mixed\n * through a normalised 4\u00D74 Hadamard matrix (a minimal feedback delay\n * network \u2014 far denser than 4 independent combs)\n * \u2500\u25BA 2 series Schroeder allpass diffusors\n * \u2500\u25BA out\n *\n * WHY A WORKLET: this tank used to be built from native nodes (delays, biquads\n * and 16 cross-feed gains). Chrome breaks feedback cycles by inserting\n * render-quantum latencies, and it does so inconsistently across the matrix\n * paths \u2014 which destroys the Hadamard's energy conservation and makes the\n * tank self-oscillate even though the math says loop gain < 1. Measured\n * growth was ~1e15\u00D7 over 6 s. Sample-accurate matrixing inside a worklet is\n * unconditionally stable.\n *\n * decay/damping are real AudioParams on the worklet node, so knob moves are\n * smooth and never reallocate buffers.\n */\n\nexport const COMB_TIMES_MS = [29.7, 37.1, 41.1, 43.7];\n\n/** Feedback gain for a comb of length T seconds to reach an RT60 of `rt60` seconds. */\nexport function combFeedbackGain(delaySeconds: number, rt60: number, ceiling = 0.97): number {\n const g = Math.pow(10, (-3 * delaySeconds) / Math.max(rt60, 0.05));\n return Math.min(g, ceiling);\n}\n\n/** Damping 0 \u2192 dark (800 Hz), 1 \u2192 bright (16 kHz), log taper. */\nexport function dampingToCutoff(damping: number): number {\n const minHz = 800, maxHz = 16000;\n return minHz * Math.pow(maxHz / minHz, Math.max(0, Math.min(1, damping)));\n}\n\nexport interface FdnTank {\n /** Feed audio in here. */\n input: GainNode;\n /** Diffused reverberant output. */\n output: GainNode;\n /** The worklet doing the actual work \u2014 owns the rt60/damping AudioParams. */\n node: AudioWorkletNode;\n}\n\nimport { createFdnReverbNode } from '@/worklets';\n\nexport function createFdnTank(\n ctx: BaseAudioContext,\n opts: { rt60: number; damping: number; size?: number; feedbackCeiling?: number },\n): FdnTank {\n const input = ctx.createGain();\n const output = ctx.createGain();\n\n const node = createFdnReverbNode(ctx, opts);\n\n input.connect(node);\n node.connect(output);\n\n return { input, output, node };\n}\n\n/** Retune the tank's RT60 without reallocating anything. */\nexport function setTankDecay(tank: Pick<FdnTank, 'node'>, rt60: number, now: number, t = 0.02) {\n tank.node.parameters.get('rt60')!.setTargetAtTime(rt60, now, t);\n}\n\n/** Retune the tank's high-frequency damping. */\nexport function setTankDamping(tank: Pick<FdnTank, 'node'>, damping: number, now: number, t = 0.02) {\n tank.node.parameters.get('damping')!.setTargetAtTime(damping, now, t);\n}\n", "// @ts-nocheck \u2014 generated by scripts/lib/build.ts\nimport { createMix } from '@/lib/dsp/mix';\nimport type { BaseModule, Position } from '@/types/synth';\n\nexport interface ReverbModule extends BaseModule {\n type: 'reverb';\n decay: number;\n mix: number;\n}\nimport { defineDescriptor, paramDefaults } from '@/modules/ModuleDescriptor';\n\n// \u2500\u2500\u2500 PARAMS (single source of truth: knobs, defaults, hover tips, docs) \u2500\u2500\nconst params = {\n decay: { node: 'tankNode', field: 'rt60', default: 2, min: 0.1, max: 8, scale: 'log', unit: 's', },\n mix: { node: '_mix', field: 'offset', unit: 'factor', default: 0.3, min: 0, max: 1, },\n} satisfies Record<string, ParamSpec>;\n\nimport { createFdnTank, setTankDecay } from '@/lib/dsp/fdnTank';\n\n\nexport const reverbDescriptor = /* @__PURE__ */ defineDescriptor({\n type: 'reverb',\n params,\n\n ports: {\n 'in': { type: 'input', signal: 'audio', node: 'input', },\n 'out': { type: 'output', signal: 'audio', node: 'output', },\n },\n createModule(id: string, position: Position): ReverbModule {\n return {\n id, type: 'reverb', position, ...paramDefaults(params),\n };\n },\n\n createNodes(ctx, module) {\n const input = ctx.createGain();\n const output = ctx.createGain();\n const dryGain = ctx.createGain();\n const wetGain = ctx.createGain();\n\n // Equal-power crossfade\n const _mix = createMix(ctx, dryGain, wetGain, module.mix, 'equal-power');\n\n const preDelay = ctx.createDelay(0.5);\n preDelay.delayTime.value = 0.02;\n\n const tank = createFdnTank(ctx, { rt60: module.decay, damping: 0.55 });\n\n input.connect(dryGain);\n input.connect(preDelay);\n preDelay.connect(tank.input);\n tank.output.connect(wetGain);\n dryGain.connect(output);\n wetGain.connect(output);\n\n return {\n input, output, dryGain, wetGain, _mix, preDelay,\n tankInput: tank.input, tankOutput: tank.output, tankNode: tank.node,\n };\n },\n\n updateParam(nodes, _m, param, value) {\n const now = nodes.input.context.currentTime;\n if (param === 'mix') {\n (nodes._mix as ConstantSourceNode).offset.setTargetAtTime(value as number, now, 0.02);\n } else if (param === 'decay') {\n // No buffer reallocation \u2014 just retune the tank's RT60 AudioParam\n setTankDecay({ node: nodes.tankNode as AudioWorkletNode }, value as number, now);\n }\n },\n\n});\n", "import { defineModule } from '../../core';\nimport { reverbDescriptor } from './reverb';\nimport type { ReverbParams, ReverbInputs, ReverbOutputs, ReverbProps } from './reverb.types';\nimport fdn_reverb from '../worklet-src/fdn-reverb';\n\nexport const Reverb = /* @__PURE__ */ defineModule(reverbDescriptor, {\n worklets: {\n 'fdn-reverb': fdn_reverb,\n },\n}) as import('../../core').LibModule<ReverbParams, ReverbInputs, ReverbOutputs, ReverbProps>;\nexport type { ReverbParams, ReverbInputs, ReverbOutputs, ReverbProps };\n", "// @ts-nocheck \u2014 generated by scripts/lib/build.ts\nimport type { BaseModule, Position } from '@/types/synth';\n\nimport { defineDescriptor, paramDefaults } from '@/modules/ModuleDescriptor';\nimport { createVoctFreqNode } from '@/worklets';\n\nexport interface RingModModule extends BaseModule {\n type: 'ring-mod';\n note: number; // panel memory: absolute carrier note while V/OCT is unpatched\n transpose?: number; // panel memory: semitone shift while V/OCT is patched\n offset?: number; // library-only DSP state (see params.offset); the app derives it\n mix: number;\n}\n\nconst params = {\n // Carrier pitch = V/OCT input (absolute notes, silence = 0) + MOD (semitones) + offset.\n offset: { node: '_carrierVoct', field: 'transpose', unit: 'semitone', default: 69, min: -48, max: 108, },\n // Dry/wet is split across two gain nodes, not one AudioParam \u2014 set-only.\n mix: { unit: 'factor', default: 0.5, min: 0, max: 1, },\n} satisfies Record<string, ParamSpec>;\n\n\n/** Cables currently on V/OCT, per node set \u2014 picks the live panel memory. */\nconst patchCount = new WeakMap<object, number>();\n\n\nexport const ringModDescriptor = /* @__PURE__ */ defineDescriptor({\n type: 'ring-mod',\n params,\n\n ports: {\n 'in': { type: 'input', signal: 'audio', node: 'input', },\n 'out': { type: 'output', signal: 'audio', node: 'output', },\n 'voct': { type: 'input', signal: 'pitch', node: '_carrierVoct', },\n 'modFreq': { type: 'modulation', signal: 'modulation', node: '_carrierVoct', },\n },\n\n createModule(id: string, position: Position): RingModModule {\n const { offset: _dsp, ...rest } = paramDefaults(params);\n return { id, type: 'ring-mod', position, ...rest, note: 69, transpose: 0 };\n },\n\n createNodes(ctx, module) {\n const input = ctx.createGain();\n const output = ctx.createGain();\n const dryGain = ctx.createGain();\n const wetGain = ctx.createGain();\n const carrier = ctx.createOscillator();\n const ringMod = ctx.createGain();\n\n dryGain.gain.value = 1 - module.mix;\n wetGain.gain.value = module.mix;\n carrier.type = 'sine';\n ringMod.gain.value = 0;\n carrier.connect(ringMod.gain);\n carrier.start();\n\n // V/Oct carrier pitch: ConstantSource(0) \u2192 voct(transpose=carrier note) \u2192 carrier.frequency\n // Same pattern as VCF cutoff \u2014 mod CV arrives in semitone space, \u00B112 = one octave.\n carrier.frequency.value = 0; // driven exclusively by voct\n const _carrierVoct = createVoctFreqNode(ctx);\n _carrierVoct.parameters.get('transpose')!.value = module.offset ?? module.note;\n\n const _carrierBase = ctx.createConstantSource();\n _carrierBase.offset.value = 0;\n _carrierBase.start();\n\n _carrierBase.connect(_carrierVoct);\n _carrierVoct.connect(carrier.frequency);\n\n input.connect(dryGain);\n input.connect(ringMod);\n ringMod.connect(wetGain);\n dryGain.connect(output);\n wetGain.connect(output);\n\n return { input, output, carrier, ringMod, dryGain, wetGain, _carrierVoct, _carrierBase };\n },\n\n updateParam(nodes, _m, param, value) {\n const t = nodes._carrierVoct.parameters.get('transpose')!;\n if (param === 'offset') t.value = value as number;\n // App panel memories: only the one matching the patch state is live.\n else if (param === 'note') { if (!patchCount.get(nodes)) t.value = value as number; }\n else if (param === 'transpose') { if (patchCount.get(nodes)) t.value = value as number; }\n else if (param === 'mix') {\n nodes.dryGain.gain.value = 1 - (value as number);\n nodes.wetGain.gain.value = value as number;\n }\n },\n\n // App-only: plain summing connect; the hooks only swap which panel memory\n // drives the offset.\n onConnect(nodes, module, portId, sourceNode) {\n if (portId !== 'voct') return false;\n sourceNode.connect(nodes._carrierVoct);\n patchCount.set(nodes, (patchCount.get(nodes) ?? 0) + 1);\n nodes._carrierVoct.parameters.get('transpose')!.value = module.transpose ?? 0;\n return true;\n },\n\n onDisconnect(nodes, module, portId, sourceNode) {\n if (portId !== 'voct') return false;\n try { sourceNode.disconnect(nodes._carrierVoct); } catch (_) {}\n const n = Math.max(0, (patchCount.get(nodes) ?? 0) - 1);\n patchCount.set(nodes, n);\n if (!n) nodes._carrierVoct.parameters.get('transpose')!.value = module.note;\n return true;\n },\n\n dispose(nodes) {\n try { nodes.carrier.stop(); } catch (_) {}\n try { nodes._carrierBase.stop(); } catch (_) {}\n },\n\n});\n", "import { defineModule } from '../../core';\nimport { ringModDescriptor } from './ring-mod';\nimport type { RingModulatorParams, RingModulatorInputs, RingModulatorOutputs, RingModulatorProps } from './ring-mod.types';\nimport map_voct_to_freq from '../worklet-src/map-voct-to-freq';\n\nexport const RingModulator = /* @__PURE__ */ defineModule(ringModDescriptor, {\n worklets: {\n 'map-voct-to-freq': map_voct_to_freq,\n },\n}) as import('../../core').LibModule<RingModulatorParams, RingModulatorInputs, RingModulatorOutputs, RingModulatorProps>;\nexport type { RingModulatorParams, RingModulatorInputs, RingModulatorOutputs, RingModulatorProps };\n", "// @ts-nocheck \u2014 generated by scripts/lib/build.ts\n\nimport type { BaseModule, Position } from '@/types/synth';\n\nexport interface RotaryModule extends BaseModule {\n type: 'rotary';\n speed: 'slow' | 'fast';\n slowRate: number;\n fastRate: number;\n mix: number;\n}\nimport { defineDescriptor, paramDefaults } from '@/modules/ModuleDescriptor';\nimport { createMix } from '@/lib/dsp/mix';\n\ninterface RotorSpec {\n baseDelay: number; dopplerSec: number; ampBase: number; ampDepth: number;\n phaseDeg: number; tauUp: number; tauDown: number;\n}\nconst CROSSOVER_HZ = 800;\nconst BUTTERWORTH_Q_DB = -3.0103; // 1/\u221A2 in dB\nconst DRUM_RATIO = 0.85; // 122 drum \u2248 0.67/5.7 Hz vs horn \u2248 0.8/6.7 Hz\nconst HORN: RotorSpec = { baseDelay: 0.003, dopplerSec: 0.00044, ampBase: 0.7, ampDepth: 0.3, phaseDeg: 0, tauUp: 0.35, tauDown: 0.55 };\nconst DRUM: RotorSpec = { baseDelay: 0.003, dopplerSec: 0.0002, ampBase: 0.8, ampDepth: 0.2, phaseDeg: 90, tauUp: 1.5, tauDown: 1.7 };\n\n// \u2500\u2500\u2500 PARAMS \u2014 the signal contract (no UI knowledge) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n// `speed` is a mode switch with inertia, not a rate: the horn and drum\n// ramp toward slowRate/fastRate at different physical time constants\n// (setTargetAtTime), so there is no single instant value a rate\n// AudioParam could honestly hold \u2014 an AudioParam ramp is one curve, but\n// SLOW\u2194FAST here drives two rotors on two different curves whose target\n// also depends on which mode was already active. Modelled as an enum\n// (set-only) plus two set-only rate params rather than faking a rate\n// AudioParam. Only `mix` maps 1:1 to a real AudioParam here.\nconst params = {\n speed: { kind: 'enum', options: ['slow', 'fast'] as const, default: 'slow' as const, },\n slowRate: { unit: 'Hz', default: 0.8, min: 0.5, max: 2, },\n fastRate: { unit: 'Hz', default: 6, min: 4, max: 8, },\n mix: { node: '_mix', field: 'offset', unit: 'factor', default: 0.7, min: 0, max: 1, },\n} satisfies Record<string, ParamSpec>;\n\n\n\nexport const rotaryDescriptor = /* @__PURE__ */ defineDescriptor({\n type: 'rotary' as const,\n params,\n\n ports: {\n 'in': { type: 'input' as const, signal: 'audio', node: 'input', },\n 'out': { type: 'output' as const, signal: 'audio', node: 'output', },\n 'modMix': { type: 'modulation', signal: 'modulation', node: '_mix', field: 'offset' },\n },\n\n createModule(id: string, position: Position): RotaryModule {\n return { id, type: 'rotary', position, ...paramDefaults(params) };\n },\n\n createNodes(ctx, module) {\n const input = ctx.createGain();\n const output = ctx.createGain();\n const dryGain = ctx.createGain();\n const wetGain = ctx.createGain();\n const monoIn = ctx.createGain();\n monoIn.channelCount = 1;\n monoIn.channelCountMode = 'explicit';\n monoIn.channelInterpretation = 'speakers';\n const merger = ctx.createChannelMerger(2);\n const MIC_DEG = 60;\n\n const biquad = (type: BiquadFilterType) => {\n const f = ctx.createBiquadFilter();\n f.type = type;\n f.frequency.value = CROSSOVER_HZ;\n f.Q.value = BUTTERWORTH_Q_DB;\n return f;\n };\n const lp1 = biquad('lowpass'), lp2 = biquad('lowpass');\n const hp1 = biquad('highpass'), hp2 = biquad('highpass');\n monoIn.connect(lp1); lp1.connect(lp2);\n monoIn.connect(hp1); hp1.connect(hp2);\n\n const hornRate = module.speed === 'slow' ? module.slowRate : module.fastRate;\n const sources: (OscillatorNode | ConstantSourceNode)[] = [];\n\n const rotor = (band: AudioNode, spec: RotorSpec, rate: number) => {\n const speed = ctx.createConstantSource();\n speed.offset.value = rate;\n sources.push(speed);\n [MIC_DEG, -MIC_DEG].forEach((micDeg, ch) => {\n const phi = ((micDeg + spec.phaseDeg) * Math.PI) / 180;\n const wave = ctx.createPeriodicWave(\n new Float32Array([0, Math.cos(phi)]),\n new Float32Array([0, Math.sin(phi)]),\n { disableNormalization: true },\n );\n const osc = ctx.createOscillator();\n osc.setPeriodicWave(wave);\n osc.frequency.value = 0;\n speed.connect(osc.frequency);\n sources.push(osc);\n\n const delay = ctx.createDelay(0.02);\n delay.delayTime.value = spec.baseDelay;\n const dop = ctx.createGain();\n dop.gain.value = -spec.dopplerSec;\n osc.connect(dop); dop.connect(delay.delayTime);\n\n const amp = ctx.createGain();\n amp.gain.value = spec.ampBase;\n const am = ctx.createGain();\n am.gain.value = spec.ampDepth;\n osc.connect(am); am.connect(amp.gain);\n\n band.connect(delay); delay.connect(amp); amp.connect(merger, 0, ch);\n });\n return speed;\n };\n const hornSpeed = rotor(hp2, HORN, hornRate);\n const drumSpeed = rotor(lp2, DRUM, hornRate * DRUM_RATIO);\n sources.forEach((n) => n.start());\n\n const _mix = createMix(ctx, dryGain, wetGain, module.mix, 'linear');\n input.connect(dryGain);\n input.connect(monoIn);\n merger.connect(wetGain);\n dryGain.connect(output);\n wetGain.connect(output);\n\n const srcNodes = Object.fromEntries(sources.map((n, i) => [`src${i}`, n])) as Record<string, AudioNode>;\n return { input, output, dryGain, wetGain, hornSpeed, drumSpeed, _mix, ...srcNodes } as Record<string, AudioNode>;\n },\n\n updateParam(nodes, module, param, value) {\n const now = nodes.input.context.currentTime;\n const setRate = (horn: number, inertia: boolean) => {\n const hs = nodes.hornSpeed as ConstantSourceNode;\n const ds = nodes.drumSpeed as ConstantSourceNode;\n const up = horn > hs.offset.value;\n const tH = inertia ? (up ? HORN.tauUp : HORN.tauDown) : 0.05;\n const tD = inertia ? (up ? DRUM.tauUp : DRUM.tauDown) : 0.05;\n hs.offset.cancelScheduledValues(now);\n ds.offset.cancelScheduledValues(now);\n hs.offset.setTargetAtTime(horn, now, tH);\n ds.offset.setTargetAtTime(horn * DRUM_RATIO, now, tD);\n };\n if (param === 'speed') {\n setRate(value === 'slow' ? module.slowRate : module.fastRate, true);\n } else if (param === 'slowRate') {\n if (module.speed === 'slow') setRate(value as number, false);\n } else if (param === 'fastRate') {\n if (module.speed === 'fast') setRate(value as number, false);\n } else if (param === 'mix') {\n (nodes._mix as ConstantSourceNode).offset.value = value as number;\n }\n },\n\n dispose(nodes) {\n for (const [k, n] of Object.entries(nodes)) {\n if (k.startsWith('src')) (n as OscillatorNode | ConstantSourceNode).stop();\n }\n (nodes._mix as ConstantSourceNode).stop();\n },\n\n});\n", "import { defineModule } from '../../core';\nimport { rotaryDescriptor } from './rotary';\nimport type { RotaryParams, RotaryInputs, RotaryOutputs, RotaryProps } from './rotary.types';\n\n\nexport const Rotary = /* @__PURE__ */ defineModule(rotaryDescriptor) as import('../../core').LibModule<RotaryParams, RotaryInputs, RotaryOutputs, RotaryProps>;\nexport type { RotaryParams, RotaryInputs, RotaryOutputs, RotaryProps };\n", "// @ts-nocheck \u2014 generated by scripts/lib/build.ts\nimport { createMix } from '@/lib/dsp/mix';\nimport { BaseModule } from '@/types/synth';\n\nexport interface SaturatorModule extends BaseModule {\n type: 'saturator';\n drive: number;\n warmth: number;\n mix: number;\n}\nimport { defineDescriptor, paramDefaults } from '@/modules/ModuleDescriptor';\n\n// \u2500\u2500\u2500 PARAMS \u2014 the signal contract (no UI knowledge) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nconst params = {\n // drive feeds both driveGain.gain (1 + drive*4) and the waveshaper curve \u2014\n // a conversion, not a 1:1 AudioParam write, so no node/field.\n drive: { unit: 'factor', default: 0.5, min: 0, max: 1, },\n // warmthFilter.gain = warmth * 6 \u2014 a scaled conversion, so no node/field.\n warmth: { unit: 'factor', default: 0.5, min: 0, max: 1, },\n mix: { node: '_mix', field: 'offset', unit: 'factor', default: 1.0, min: 0, max: 1, },\n} satisfies Record<string, ParamSpec>;\n\n\nfunction makeSaturationCurve(amount: number): Float32Array {\n const samples = 44100;\n const curve = new Float32Array(samples);\n const k = 1 + amount * 10;\n for (let i = 0; i < samples; i++) {\n const x = (i * 2) / samples - 1;\n curve[i] = Math.tanh(k * x) / Math.tanh(k);\n }\n return curve;\n}\n\n\nexport const saturatorDescriptor = /* @__PURE__ */ defineDescriptor({\n type: 'saturator',\n params,\n\n ports: {\n 'in': { type: 'input', signal: 'audio', node: 'input', },\n 'out': { type: 'output', signal: 'audio', node: 'output', },\n },\n\n createModule(id, position) {\n return { id, type: 'saturator', position, ...paramDefaults(params) };\n },\n\n createNodes(ctx, module) {\n const input = ctx.createGain();\n const output = ctx.createGain();\n const dryGain = ctx.createGain();\n const wetGain = ctx.createGain();\n const driveGain = ctx.createGain();\n const waveshaper = ctx.createWaveShaper();\n const warmthFilter = ctx.createBiquadFilter();\n\n driveGain.gain.value = 1 + module.drive * 4;\n waveshaper.curve = makeSaturationCurve(module.drive) as Float32Array<ArrayBuffer>;\n waveshaper.oversample = '2x';\n warmthFilter.type = 'lowshelf';\n warmthFilter.frequency.value = 300;\n warmthFilter.gain.value = module.warmth * 6;\n const _mix = createMix(ctx, dryGain, wetGain, module.mix, 'linear');\n\n input.connect(dryGain);\n input.connect(driveGain);\n driveGain.connect(waveshaper);\n waveshaper.connect(warmthFilter);\n warmthFilter.connect(wetGain);\n dryGain.connect(output);\n wetGain.connect(output);\n\n return { input, output, driveGain, waveshaper, warmthFilter, dryGain, wetGain, _mix };\n },\n\n updateParam(nodes, _m, param, value) {\n if (param === 'drive') {\n nodes.driveGain.gain.value = 1 + (value as number) * 4;\n nodes.waveshaper.curve = makeSaturationCurve(value as number) as Float32Array<ArrayBuffer>;\n } else if (param === 'warmth') {\n nodes.warmthFilter.gain.value = (value as number) * 6;\n } else if (param === 'mix') {\n (nodes._mix as ConstantSourceNode).offset.value = value as number;\n }\n },\n\n});\n", "import { defineModule } from '../../core';\nimport { saturatorDescriptor } from './saturator';\nimport type { SaturatorParams, SaturatorInputs, SaturatorOutputs, SaturatorProps } from './saturator.types';\n\n\nexport const Saturator = /* @__PURE__ */ defineModule(saturatorDescriptor) as import('../../core').LibModule<SaturatorParams, SaturatorInputs, SaturatorOutputs, SaturatorProps>;\nexport type { SaturatorParams, SaturatorInputs, SaturatorOutputs, SaturatorProps };\n", "// @ts-nocheck \u2014 generated by scripts/lib/build.ts\nimport type { BaseModule, Position } from '@/types/synth';\nimport { defineDescriptor, paramDefaults } from '@/modules/ModuleDescriptor';\nimport { createFdnTank, setTankDecay } from '@/lib/dsp/fdnTank';\nimport { createPitchShifterNode } from '@/worklets';\nimport { createMix } from '@/lib/dsp/mix';\n\nexport interface ShimmerModule extends BaseModule {\n type: 'shimmer';\n decay: number;\n pitch: number;\n mix: number;\n shimmer: number;\n}\n\n// \u2500\u2500\u2500 PARAMS \u2014 the signal contract \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n// `decay` sets the FDN tank's RT60 via setTankDecay. `shimmer` maps 1:1 onto\n// regenGain.gain. `pitch` re-tunes TWO worklets (L+R shifters) \u2014 not a\n// single AudioParam \u2014 so it stays a set-only knob. `mix` now runs through\n// createMix's ConstantSource (`_mix`), equal-power law, replacing the manual\n// cos/sin gain writes with the identical curve.\nconst params = {\n decay: { unit: 's', default: 3, min: 0.5, max: 10, scale: 'log', },\n pitch: { unit: 'semitone', default: 12, min: -12, max: 24, },\n mix: { node: '_mix', field: 'offset', unit: 'factor', default: 0.5, min: 0, max: 1, },\n shimmer: { node: 'regenGain', field: 'gain', unit: 'factor', default: 0.5, min: 0, max: 0.95, },\n} satisfies Record<string, ParamSpec>;\n\n\nexport const shimmerDescriptor = /* @__PURE__ */ defineDescriptor({\n type: 'shimmer',\n params,\n\n ports: {\n 'in': { type: 'input', signal: 'audio', node: 'input', },\n 'out': { type: 'output', signal: 'audio', node: 'output', },\n },\n\n createModule(id: string, position: Position): ShimmerModule {\n return { id, type: 'shimmer', position, ...paramDefaults(params) } as ShimmerModule;\n },\n\n createNodes(ctx, module) {\n const input = ctx.createGain();\n const output = ctx.createGain();\n const dryGain = ctx.createGain();\n const wetGain = ctx.createGain();\n\n const _mix = createMix(ctx, dryGain, wetGain, module.mix, 'equal-power');\n\n const tank = createFdnTank(ctx, { rt60: module.decay, damping: 0.5, feedbackCeiling: 0.93 });\n\n // Pitch-shifted regeneration, per channel like a real stereo shimmer\n // (Eventide-style): tank L/R \u2192 per-channel highpass \u2192 per-channel\n // granular shifter \u2192 merge \u2192 regen gain \u2192 back in. Summing to mid before\n // shifting would collapse the tail's width on every pass.\n // The explicit DelayNode is required: with the tank inside a worklet this\n // outer loop no longer contains a native DelayNode, and Web Audio mutes\n // any cycle without one. 20 ms also acts as a pleasant regen pre-delay.\n const splitter = ctx.createChannelSplitter(2);\n const merger = ctx.createChannelMerger(2);\n const mkRegenTap = () => {\n const hp = ctx.createBiquadFilter();\n hp.type = 'highpass';\n hp.frequency.value = 300; // keep the loop from accumulating mud\n const shifter = createPitchShifterNode(ctx, module.pitch);\n return { hp, shifter };\n };\n const tapL = mkRegenTap();\n const tapR = mkRegenTap();\n const regenGain = ctx.createGain();\n regenGain.gain.value = module.shimmer;\n const regenDelay = ctx.createDelay(0.1);\n regenDelay.delayTime.value = 0.02;\n\n tank.output.connect(splitter);\n splitter.connect(tapL.hp, 0);\n splitter.connect(tapR.hp, 1);\n tapL.hp.connect(tapL.shifter);\n tapR.hp.connect(tapR.shifter);\n tapL.shifter.connect(merger, 0, 0);\n tapR.shifter.connect(merger, 0, 1);\n merger.connect(regenGain);\n regenGain.connect(regenDelay);\n regenDelay.connect(tank.input);\n\n input.connect(dryGain);\n input.connect(tank.input);\n tank.output.connect(wetGain);\n dryGain.connect(output);\n wetGain.connect(output);\n\n return {\n input, output, dryGain, wetGain, _mix, splitter, merger,\n highpassL: tapL.hp, highpassR: tapR.hp,\n pitchShifterL: tapL.shifter, pitchShifterR: tapR.shifter,\n regenGain, regenDelay,\n tankInput: tank.input, tankOutput: tank.output, tankNode: tank.node,\n };\n },\n\n updateParam(nodes, _m, param, value) {\n const now = nodes.input.context.currentTime;\n if (param === 'mix') {\n (nodes._mix as ConstantSourceNode).offset.value = value as number;\n } else if (param === 'shimmer') {\n nodes.regenGain.gain.setTargetAtTime(value as number, now, 0.02);\n } else if (param === 'pitch') {\n for (const key of ['pitchShifterL', 'pitchShifterR'] as const) {\n (nodes[key] as AudioWorkletNode).parameters.get('semitones')!\n .setTargetAtTime(value as number, now, 0.02);\n }\n } else if (param === 'decay') {\n setTankDecay({ node: nodes.tankNode as AudioWorkletNode }, value as number, now);\n }\n },\n\n});\n", "import { defineModule } from '../../core';\nimport { shimmerDescriptor } from './shimmer';\nimport type { ShimmerParams, ShimmerInputs, ShimmerOutputs, ShimmerProps } from './shimmer.types';\nimport pitch_shifter from '../worklet-src/pitch-shifter';\nimport fdn_reverb from '../worklet-src/fdn-reverb';\n\nexport const Shimmer = /* @__PURE__ */ defineModule(shimmerDescriptor, {\n worklets: {\n 'pitch-shifter': pitch_shifter,\n 'fdn-reverb': fdn_reverb,\n },\n}) as import('../../core').LibModule<ShimmerParams, ShimmerInputs, ShimmerOutputs, ShimmerProps>;\nexport type { ShimmerParams, ShimmerInputs, ShimmerOutputs, ShimmerProps };\n", "// @ts-nocheck \u2014 generated by scripts/lib/build.ts\nimport type { BaseModule, Position } from '@/types/synth';\nimport { defineDescriptor, paramDefaults } from '@/modules/ModuleDescriptor';\n\nexport interface SoftLimitModule extends BaseModule {\n type: 'soft-limit';\n ceiling: number;\n drive: number;\n knee: number;\n}\n\n// \u2500\u2500\u2500 PARAMS \u2014 the signal contract (no UI knowledge) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n// drive/knee rebuild the waveshaper curve; ceiling drives ceiling.gain via a\n// dB\u2192linear conversion. None is a 1:1 AudioParam write, so all set-only.\nconst params = {\n drive: { unit: 'factor', default: 0.5, min: 0, max: 1, },\n knee: { unit: 'factor', default: 0.5, min: 0, max: 1, },\n ceiling: { unit: 'dB', default: -0.5, min: -12, max: 0, },\n} satisfies Record<string, ParamSpec>;\n\n\nfunction makeSoftLimitCurve(knee: number, drive: number): Float32Array {\n const samples = 44100;\n const curve = new Float32Array(samples);\n const k = 0.1 + knee * 0.9;\n // Drive lives INSIDE the curve. The previous topology put a \u00D7(1+drive\u00B73)\n // GainNode in front of a curve that only spans input [\u22121, 1]: everything\n // past \u00B11 slammed into the curve's endpoint value \u2014 a hard clip at\n // 0.1+0.9\u00B7tanh(1), which is exactly the flat-topping a \"soft limit\"\n // module promises not to do (measured by probe:softlimit-rails,\n // 2026-08-08). Folding the drive into the transfer keeps the whole\n // driven range on the smooth tanh law; inputs beyond \u00B11 land on the\n // asymptote, which is correct limiter behaviour.\n const driveMul = 1 + drive * 3;\n for (let i = 0; i < samples; i++) {\n const x = ((i * 2) / samples - 1) * driveMul;\n if (Math.abs(x) < k) {\n curve[i] = x;\n } else {\n const sign = x > 0 ? 1 : -1;\n curve[i] = sign * (k + (1 - k) * Math.tanh((Math.abs(x) - k) / (1 - k)));\n }\n }\n return curve;\n}\n\n\nexport const softLimitDescriptor = /* @__PURE__ */ defineDescriptor({\n type: 'soft-limit' as const,\n params,\n\n ports: {\n 'in': { type: 'input' as const, signal: 'audio', node: 'input', },\n 'out': { type: 'output' as const, signal: 'audio', node: 'output', },\n },\n\n createModule(id: string, position: Position): SoftLimitModule {\n return { id, type: 'soft-limit', position, ...paramDefaults(params) };\n },\n\n createNodes(ctx, module) {\n const input = ctx.createGain();\n const output = ctx.createGain();\n const waveshaper = ctx.createWaveShaper();\n const ceiling = ctx.createGain();\n\n // No pre-gain node: drive is baked into the curve (see\n // makeSoftLimitCurve) so the shaper's input never leaves the curve's\n // defined domain.\n waveshaper.curve = makeSoftLimitCurve(module.knee, module.drive) as Float32Array<ArrayBuffer>;\n waveshaper.oversample = '2x';\n ceiling.gain.value = Math.pow(10, module.ceiling / 20);\n\n input.connect(waveshaper);\n waveshaper.connect(ceiling);\n ceiling.connect(output);\n\n return { input, output, waveshaper, ceiling };\n },\n\n updateParam(nodes, m, param, value) {\n if (param === 'drive') nodes.waveshaper.curve = makeSoftLimitCurve(m.knee, value as number) as Float32Array<ArrayBuffer>;\n else if (param === 'knee') nodes.waveshaper.curve = makeSoftLimitCurve(value as number, m.drive) as Float32Array<ArrayBuffer>;\n else if (param === 'ceiling') nodes.ceiling.gain.value = Math.pow(10, (value as number) / 20);\n },\n\n});\n", "import { defineModule } from '../../core';\nimport { softLimitDescriptor } from './soft-limit';\nimport type { SoftLimiterParams, SoftLimiterInputs, SoftLimiterOutputs, SoftLimiterProps } from './soft-limit.types';\n\n\nexport const SoftLimiter = /* @__PURE__ */ defineModule(softLimitDescriptor) as import('../../core').LibModule<SoftLimiterParams, SoftLimiterInputs, SoftLimiterOutputs, SoftLimiterProps>;\nexport type { SoftLimiterParams, SoftLimiterInputs, SoftLimiterOutputs, SoftLimiterProps };\n", "// @ts-nocheck \u2014 generated by scripts/lib/build.ts\nimport { createMix } from '@/lib/dsp/mix';\nimport { BaseModule } from '@/types/synth';\n\nexport interface SpringReverbModule extends BaseModule {\n type: 'spring-reverb';\n mix: number;\n decay: number;\n tone: number;\n drip: number;\n}\nimport { defineDescriptor, paramDefaults } from '@/modules/ModuleDescriptor';\n\nimport { createSpringReverbNode } from '@/worklets';\nimport { pulse } from '@/lib/dsp/pulse';\n\n// \u2500\u2500\u2500 PARAMS (single source of truth: knobs, defaults, hover tips, docs) \u2500\u2500\nconst params = {\n mix: { node: '_mix', field: 'offset', unit: 'factor', default: 0.35, min: 0, max: 1, },\n decay: { node: '_worklet', field: 'decay', default: 1.5, min: 0.3, max: 4, scale: 'log' as const, unit: 's', },\n tone: { node: '_worklet', field: 'tone', unit: 'factor', default: 0.6, min: 0, max: 1, },\n drip: { node: '_worklet', field: 'drip', unit: 'factor', default: 0.5, min: 0, max: 1, },\n} as const satisfies Record<string, ParamSpec>;\n\n\nexport const springReverbDescriptor = /* @__PURE__ */ defineDescriptor({\n type: 'spring-reverb',\n params,\n\n ports: {\n 'in': { type: 'input', signal: 'audio', node: 'input', },\n 'knock': { type: 'input', signal: 'gate', node: '_knockIn', },\n 'out': { type: 'output', signal: 'audio', node: 'output', },\n },\n\n createModule(id, position): SpringReverbModule {\n return { id, type: 'spring-reverb', position, ...paramDefaults(params) };\n },\n\n createNodes(ctx, module) {\n const input = ctx.createGain();\n const output = ctx.createGain();\n const dryGain = ctx.createGain();\n const wetGain = ctx.createGain();\n\n const _worklet = createSpringReverbNode(ctx, {\n decay: module.decay,\n tone: module.tone,\n drip: module.drip,\n });\n\n // Knock trigger: second input of the worklet.\n const _knockIn = ctx.createGain();\n _knockIn.gain.value = 1;\n _knockIn.connect(_worklet, 0, 1);\n\n // Equal-power mix law: 50% keeps both paths at \u22123 dB instead of the\n // \u22126 dB dip a linear crossfade causes between two correlated-ish signals.\n const _mix = createMix(ctx, dryGain, wetGain, module.mix, 'equal-power');\n\n input.connect(dryGain);\n input.connect(_worklet, 0, 0);\n _worklet.connect(wetGain);\n dryGain.connect(output);\n wetGain.connect(output);\n\n return { input, output, dryGain, wetGain, _mix, _worklet, _knockIn };\n },\n\n updateParam(nodes, _module, param, value, when) {\n const worklet = nodes._worklet as AudioWorkletNode;\n if (param === 'mix') {\n (nodes._mix as ConstantSourceNode).offset.value = value as number;\n } else if (param === 'decay' || param === 'tone' || param === 'drip') {\n worklet.parameters.get(param)!.value = value as number;\n } else if (param === 'knock') {\n // Panel button = a rising edge on the KNOCK input (same path as a cable).\n pulse(nodes._knockIn as AudioNode, when);\n }\n },\n\n dispose(_nodes) {},\n\n});\n", "import { defineModule } from '../../core';\nimport { springReverbDescriptor } from './spring-reverb';\nimport type { SpringReverbParams, SpringReverbInputs, SpringReverbOutputs, SpringReverbProps } from './spring-reverb.types';\nimport spring_reverb from '../worklet-src/spring-reverb';\n\nexport const SpringReverb = /* @__PURE__ */ defineModule(springReverbDescriptor, {\n worklets: {\n 'spring-reverb': spring_reverb,\n },\n}) as import('../../core').LibModule<SpringReverbParams, SpringReverbInputs, SpringReverbOutputs, SpringReverbProps>;\nexport type { SpringReverbParams, SpringReverbInputs, SpringReverbOutputs, SpringReverbProps };\n", "// @ts-nocheck \u2014 generated by scripts/lib/build.ts\nimport { BaseModule } from '@/types/synth';\nimport { defineDescriptor, paramDefaults } from '@/modules/ModuleDescriptor';\n\nexport interface StereoSpreadModule extends BaseModule {\n type: 'stereo-spread';\n spread: number;\n center: number;\n}\n\n// \u2500\u2500\u2500 PARAMS \u2014 the signal contract \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n// `width` is a straight dry/wet level on the widened-highs bus, so it maps\n// 1:1 onto wetGain.gain. `spread` drives THREE things at once (two pan\n// positions plus a delay time) and `center` re-tunes two filters \u2014 neither\n// is a single AudioParam, so both stay set-only.\nconst params = {\n spread: { unit: 'factor', default: 0.7, min: 0, max: 1, },\n center: { unit: 'Hz', default: 800, min: 200, max: 2000, scale: 'log', },\n} satisfies Record<string, ParamSpec>;\n\n\n/**\n * Stereo Spread \u2014 frequency-dependent stereo widening via Haas effect.\n *\n * Lows (below CENTER) pass through unaffected.\n * Highs are split into two paths:\n * - Direct \u2192 panned left by SPREAD amount\n * - Micro-delayed (0\u20135ms) \u2192 panned right by SPREAD amount\n * This creates real psychoacoustic stereo width via the Haas/precedence effect.\n *\n * WIDTH controls dry/wet balance of the widened highs.\n */\nexport const stereoSpreadDescriptor = /* @__PURE__ */ defineDescriptor({\n type: 'stereo-spread',\n params,\n\n ports: {\n 'in': { type: 'input', signal: 'audio', node: 'input', },\n 'out': { type: 'output', signal: 'audio', node: 'output', },\n },\n\n createModule(id, position) {\n return { id, type: 'stereo-spread', position, ...paramDefaults(params) } as StereoSpreadModule;\n },\n\n createNodes(ctx, module) {\n const input = ctx.createGain();\n const output = ctx.createGain();\n\n // Crossover\n const lowpass = ctx.createBiquadFilter();\n const highpass = ctx.createBiquadFilter();\n lowpass.type = 'lowpass';\n lowpass.frequency.value = module.center;\n highpass.type = 'highpass';\n highpass.frequency.value = module.center;\n\n // Haas widening for highs: direct path panned left, delayed path panned right\n const panLeft = ctx.createStereoPanner();\n const panRight = ctx.createStereoPanner();\n const haasDelay = ctx.createDelay(0.02);\n\n panLeft.pan.value = -module.spread;\n panRight.pan.value = module.spread;\n haasDelay.delayTime.value = module.spread * 0.005; // 0\u20135ms\n\n // Width controls wet level of the widened highs\n const wetGain = ctx.createGain();\n wetGain.gain.value = module.width;\n\n // Lows pass through directly (mono, centered)\n input.connect(lowpass);\n lowpass.connect(output);\n\n // Highs: split into left (direct) + right (delayed) for Haas effect\n input.connect(highpass);\n highpass.connect(panLeft); // direct highs \u2192 left\n highpass.connect(haasDelay); // delayed highs \u2192 right\n haasDelay.connect(panRight);\n panLeft.connect(wetGain);\n panRight.connect(wetGain);\n wetGain.connect(output);\n\n return { input, output, lowpass, highpass, panLeft, panRight, haasDelay, wetGain };\n },\n\n updateParam(nodes, _m, param, value) {\n if (param === 'spread') {\n nodes.panLeft.pan.value = -(value as number);\n nodes.panRight.pan.value = value as number;\n nodes.haasDelay.delayTime.value = (value as number) * 0.005;\n } else if (param === 'width') {\n nodes.wetGain.gain.value = value as number;\n } else if (param === 'center') {\n nodes.lowpass.frequency.value = value as number;\n nodes.highpass.frequency.value = value as number;\n }\n },\n\n});\n", "import { defineModule } from '../../core';\nimport { stereoSpreadDescriptor } from './stereo-spread';\nimport type { StereoSpreadParams, StereoSpreadInputs, StereoSpreadOutputs, StereoSpreadProps } from './stereo-spread.types';\n\n\nexport const StereoSpread = /* @__PURE__ */ defineModule(stereoSpreadDescriptor) as import('../../core').LibModule<StereoSpreadParams, StereoSpreadInputs, StereoSpreadOutputs, StereoSpreadProps>;\nexport type { StereoSpreadParams, StereoSpreadInputs, StereoSpreadOutputs, StereoSpreadProps };\n", "// @ts-nocheck \u2014 generated by scripts/lib/build.ts\nimport type { BaseModule, Position } from '@/types/synth';\nimport { createSubOctaveNode } from '@/worklets';\nimport { defineDescriptor, paramDefaults } from '@/modules/ModuleDescriptor';\n\nexport interface SubHarmModule extends BaseModule {\n type: 'sub-harm';\n direct: number;\n octave1: number;\n octave2: number;\n}\n\n// \u2500\u2500\u2500 PARAMS \u2014 the signal contract (no UI knowledge) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nconst params = {\n direct: { node: 'dryGain', field: 'gain', unit: 'factor', default: 1, min: 0, max: 1, },\n octave1: { node: 'subOctave', field: 'oct1Level', unit: 'factor', default: 0.5, min: 0, max: 1, },\n octave2: { node: 'subOctave', field: 'oct2Level', unit: 'factor', default: 0.3, min: 0, max: 1, },\n} satisfies Record<string, ParamSpec>;\n\n\n\nexport const subHarmDescriptor = /* @__PURE__ */ defineDescriptor({\n type: 'sub-harm' as const,\n params,\n\n ports: {\n 'in': { type: 'input' as const, signal: 'audio', node: 'input', },\n 'out': { type: 'output' as const, signal: 'audio', node: 'output', },\n },\n\n createModule(id: string, position: Position): SubHarmModule {\n return { id, type: 'sub-harm', position, ...paramDefaults(params) };\n },\n\n createNodes(ctx, module) {\n const input = ctx.createGain();\n const output = ctx.createGain();\n const dryGain = ctx.createGain();\n const wetGain = ctx.createGain();\n\n // Worklet does real frequency division via zero-crossing flip-flop\n const subOctave = createSubOctaveNode(ctx);\n (subOctave.parameters as any).get('oct1Level').value = module.octave1;\n (subOctave.parameters as any).get('oct2Level').value = module.octave2;\n\n // Lowpass to smooth the square-wave sub output\n const subFilter = ctx.createBiquadFilter();\n subFilter.type = 'lowpass';\n subFilter.frequency.value = 400;\n subFilter.Q.value = 0.7;\n\n dryGain.gain.value = module.direct;\n wetGain.gain.value = 1;\n\n input.connect(dryGain);\n input.connect(subOctave);\n subOctave.connect(subFilter);\n subFilter.connect(wetGain);\n dryGain.connect(output);\n wetGain.connect(output);\n\n return { input, output, subOctave, dryGain, wetGain };\n },\n\n updateParam(nodes, _m, param, value) {\n if (param === 'octave1') {\n (nodes.subOctave.parameters as any).get('oct1Level').value = value as number;\n } else if (param === 'octave2') {\n (nodes.subOctave.parameters as any).get('oct2Level').value = value as number;\n } else if (param === 'direct') {\n nodes.dryGain.gain.value = value as number;\n }\n },\n\n});\n", "import { defineModule } from '../../core';\nimport { subHarmDescriptor } from './sub-harm';\nimport type { SubharmonicParams, SubharmonicInputs, SubharmonicOutputs, SubharmonicProps } from './sub-harm.types';\nimport freq_divider from '../worklet-src/freq-divider';\n\nexport const Subharmonic = /* @__PURE__ */ defineModule(subHarmDescriptor, {\n worklets: {\n 'freq-divider': freq_divider,\n },\n}) as import('../../core').LibModule<SubharmonicParams, SubharmonicInputs, SubharmonicOutputs, SubharmonicProps>;\nexport type { SubharmonicParams, SubharmonicInputs, SubharmonicOutputs, SubharmonicProps };\n", "// @ts-nocheck \u2014 generated by scripts/lib/build.ts\nimport { BaseModule } from '@/types/synth';\nimport { defineDescriptor, paramDefaults } from '@/modules/ModuleDescriptor';\nimport { createTapeDelayNode } from '@/worklets';\nimport { createMix } from '@/lib/dsp/mix';\n\nexport interface TapeDelayModule extends BaseModule {\n type: 'tape-delay';\n time: number;\n feedback: number;\n mix: number;\n flutter: number;\n saturation: number;\n}\n\n// \u2500\u2500\u2500 PARAMS \u2014 the signal contract \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n// `time`/`feedback`/`saturation`/`flutter` drive the tape-delay worklet's own\n// AudioParams 1:1 (TIME varispeed glide happens inside the worklet). `mix`\n// now runs through createMix's ConstantSource (`_mix`), linear law.\nconst params = {\n time: { node: 'worklet', field: 'time', unit: 's', default: 0.375, min: 0.05, max: 1.5, scale: 'log', },\n feedback: { node: 'worklet', field: 'feedback', unit: 'factor', default: 0.5, min: 0, max: 0.95, },\n mix: { node: '_mix', field: 'offset', unit: 'factor', default: 0.4, min: 0, max: 1, },\n flutter: { node: 'worklet', field: 'flutter', unit: 'factor', default: 0.3, min: 0, max: 1, },\n saturation: { node: 'worklet', field: 'saturation', unit: 'factor', default: 0.4, min: 0, max: 1, },\n} satisfies Record<string, ParamSpec>;\n\n\n// nodes: [input, output, worklet, dryGain, wetGain, _mix]\n//\n// The delay/saturation/feedback/flutter graph lives in the 'tape-delay'\n// AudioWorklet (src/worklets/tape-delay.ts) as of 2026-08-08: the native\n// version put a 2x-oversampled WaveShaper inside the feedback cycle, and\n// Chrome's oversampler adds 128 samples of unspec'd latency, so echoes ran\n// one render quantum off the TIME grid even after the cycle compensation.\n// The worklet also carries the module report's missing tape behaviours:\n// per-repeat 6 kHz damping, composite wow+flutter (seeded, deterministic),\n// and varispeed TIME glide. Dry/wet mix stays native, same as before.\nexport const tapeDelayDescriptor = /* @__PURE__ */ defineDescriptor({\n type: 'tape-delay',\n params,\n\n ports: {\n 'in': { type: 'input', signal: 'audio', node: 'input', },\n 'out': { type: 'output', signal: 'audio', node: 'output', },\n },\n\n createModule(id, position) {\n return { id, type: 'tape-delay', position, ...paramDefaults(params) } as TapeDelayModule;\n },\n\n createNodes(ctx, module) {\n const input = ctx.createGain();\n const output = ctx.createGain();\n const dryGain = ctx.createGain();\n const wetGain = ctx.createGain();\n const worklet = createTapeDelayNode(ctx, {\n time: module.time,\n feedback: module.feedback,\n saturation: module.saturation,\n flutter: module.flutter,\n });\n\n const _mix = createMix(ctx, dryGain, wetGain, module.mix, 'linear');\n\n input.connect(dryGain);\n input.connect(worklet);\n worklet.connect(wetGain);\n dryGain.connect(output);\n wetGain.connect(output);\n\n return { input, output, worklet, dryGain, wetGain, _mix };\n },\n\n updateParam(nodes, _m, param, value) {\n const worklet = nodes.worklet as AudioWorkletNode;\n if (param === 'time' || param === 'feedback' || param === 'saturation' || param === 'flutter') {\n // TIME slew (varispeed glide) happens inside the worklet, so the\n // param itself is set instantly.\n const p = worklet.parameters.get(param);\n if (p) p.value = value as number;\n } else if (param === 'mix') {\n (nodes._mix as ConstantSourceNode).offset.value = value as number;\n }\n },\n\n});\n", "import { defineModule } from '../../core';\nimport { tapeDelayDescriptor } from './tape-delay';\nimport type { TapeDelayParams, TapeDelayInputs, TapeDelayOutputs, TapeDelayProps } from './tape-delay.types';\nimport tape_delay from '../worklet-src/tape-delay';\n\nexport const TapeDelay = /* @__PURE__ */ defineModule(tapeDelayDescriptor, {\n worklets: {\n 'tape-delay': tape_delay,\n },\n}) as import('../../core').LibModule<TapeDelayParams, TapeDelayInputs, TapeDelayOutputs, TapeDelayProps>;\nexport type { TapeDelayParams, TapeDelayInputs, TapeDelayOutputs, TapeDelayProps };\n", "// @ts-nocheck \u2014 generated by scripts/lib/build.ts\n\nimport type { BaseModule, Position } from '@/types/synth';\n\nexport interface TapeStopModule extends BaseModule {\n type: 'tape-stop';\n time: number;\n mix: number;\n}\nimport { defineDescriptor, paramDefaults } from '@/modules/ModuleDescriptor';\n\n// \u2500\u2500\u2500 PARAMS (single source of truth: knobs, defaults, hover tips, docs) \u2500\u2500\nconst params = {\n time: { node: '_worklet', field: 'time', default: 0.5, min: 0.01, max: 4, scale: 'log' as const, unit: 's', },\n mix: { node: '_worklet', field: 'mix', unit: 'factor', default: 1.0, min: 0, max: 1, },\n} as const satisfies Record<string, ParamSpec>;\n\nimport { createTapeStopNode } from '@/worklets';\nimport { pulse } from '@/lib/dsp/pulse';\n\n\nexport const tapeStopDescriptor = /* @__PURE__ */ defineDescriptor({\n type: 'tape-stop' as const,\n params,\n\n ports: {\n 'in': { type: 'input' as const, signal: 'audio', node: '_worklet', },\n 'trigger': { type: 'input' as const, signal: 'gate', node: '_trigIn', },\n 'out': { type: 'output' as const, signal: 'audio', node: 'output', },\n },\n\n createModule(id: string, position: Position): TapeStopModule {\n return { id, type: 'tape-stop', position, ...paramDefaults(params) };\n },\n\n createNodes(ctx, module) {\n const _worklet = createTapeStopNode(ctx, module.time, module.mix);\n\n // Trigger input: second input of the worklet\n const _trigIn = ctx.createGain();\n _trigIn.gain.value = 1;\n _trigIn.connect(_worklet, 0, 1);\n\n const output = ctx.createGain();\n _worklet.connect(output);\n\n return { _worklet, _trigIn, output };\n },\n\n updateParam(nodes, _module, param, value, when) {\n if (param === 'time') {\n nodes._worklet.parameters.get('time')!.value = value as number;\n } else if (param === 'mix') {\n nodes._worklet.parameters.get('mix')!.value = value as number;\n } else if (param === 'trigger') {\n // Panel button = a rising edge on the TRIG input (same path as a cable).\n pulse(nodes._trigIn, when);\n }\n },\n\n dispose(_nodes) {},\n\n});", "import { defineModule } from '../../core';\nimport { tapeStopDescriptor } from './tape-stop';\nimport type { TapeStopParams, TapeStopInputs, TapeStopOutputs, TapeStopProps } from './tape-stop.types';\nimport tape_stop from '../worklet-src/tape-stop';\n\nexport const TapeStop = /* @__PURE__ */ defineModule(tapeStopDescriptor, {\n worklets: {\n 'tape-stop': tape_stop,\n },\n}) as import('../../core').LibModule<TapeStopParams, TapeStopInputs, TapeStopOutputs, TapeStopProps>;\nexport type { TapeStopParams, TapeStopInputs, TapeStopOutputs, TapeStopProps };\n", "// @ts-nocheck \u2014 generated by scripts/lib/build.ts\nimport { BaseModule } from '@/types/synth';\n\nexport interface TiltEQModule extends BaseModule {\n type: 'tilt-eq';\n tilt: number;\n frequency: number;\n}\nimport { defineDescriptor, paramDefaults } from '@/modules/ModuleDescriptor';\n\n// \u2500\u2500\u2500 PARAMS \u2500 the signal contract (no UI knowledge) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nconst params = {\n tilt: { unit: 'dB', default: 0, min: -12, max: 12, },\n frequency: { unit: 'Hz', default: 1000, min: 200, max: 5000, },\n} satisfies Record<string, ParamSpec>;\n\n// \u2500\u2500\u2500 UI \u2500 presentation layer (stripped from the library) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n\n// \u2500\u2500\u2500 DESCRIPTOR \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport const tiltEqDescriptor = /* @__PURE__ */ defineDescriptor({\n type: 'tilt-eq',\n params,\n\n\n ports: {\n 'in': { type: 'input', signal: 'audio', node: 'input', },\n 'out': { type: 'output', signal: 'audio', node: 'output', },\n },\n\n\n createModule(id, position) {\n return { id, type: 'tilt-eq', position, ...paramDefaults(params) };\n },\n\n createNodes(ctx, module) {\n const input = ctx.createGain();\n const output = ctx.createGain();\n const lowShelf = ctx.createBiquadFilter();\n const highShelf = ctx.createBiquadFilter();\n lowShelf.type = 'lowshelf';\n lowShelf.frequency.value = module.frequency;\n lowShelf.gain.value = -module.tilt;\n highShelf.type = 'highshelf';\n highShelf.frequency.value = module.frequency;\n highShelf.gain.value = module.tilt;\n input.connect(lowShelf);\n lowShelf.connect(highShelf);\n highShelf.connect(output);\n return { input, output, lowShelf, highShelf };\n },\n\n updateParam(nodes, _m, param, value) {\n if (param === 'tilt') {\n nodes.lowShelf.gain.value = -(value as number);\n nodes.highShelf.gain.value = value as number;\n } else if (param === 'frequency') {\n nodes.lowShelf.frequency.value = value as number;\n nodes.highShelf.frequency.value = value as number;\n }\n },\n\n});\n", "import { defineModule } from '../../core';\nimport { tiltEqDescriptor } from './tilt';\nimport type { TiltParams, TiltInputs, TiltOutputs, TiltProps } from './tilt.types';\n\n\nexport const Tilt = /* @__PURE__ */ defineModule(tiltEqDescriptor) as import('../../core').LibModule<TiltParams, TiltInputs, TiltOutputs, TiltProps>;\nexport type { TiltParams, TiltInputs, TiltOutputs, TiltProps };\n", "// @ts-nocheck \u2014 generated by scripts/lib/build.ts\nimport { BaseModule } from '@/types/synth';\n\nexport interface TremoloModule extends BaseModule {\n type: 'tremolo';\n rate: number;\n depth: number;\n shape: 'sine' | 'triangle' | 'square';\n}\nimport { defineDescriptor, paramDefaults } from '@/modules/ModuleDescriptor';\n\n\nconst shapes = ['sine', 'triangle', 'square'] as const;\n\nconst params = {\n rate: { node: 'lfo', field: 'frequency', unit: 'Hz', default: 5, min: 0.5, max: 20, },\n depth: { unit: 'factor', default: 0.5, min: 0, max: 1, },\n shape: { kind: 'enum', options: shapes, default: 'sine', },\n} satisfies Record<string, ParamSpec>;\n\n\n\nexport const tremoloDescriptor = /* @__PURE__ */ defineDescriptor({\n type: 'tremolo',\n params,\n\n ports: {\n 'in': { type: 'input', signal: 'audio', node: 'input', },\n 'out': { type: 'output', signal: 'audio', node: 'output', },\n 'modRate': { type: 'modulation', signal: 'modulation', node: 'lfo', field: 'frequency' },\n },\n\n createModule(id, position) {\n return { id, type: 'tremolo', position, ...paramDefaults(params) };\n },\n\n createNodes(ctx, module) {\n const input = ctx.createGain();\n const output = ctx.createGain();\n const tremGain = ctx.createGain();\n const lfo = ctx.createOscillator();\n const lfoGain = ctx.createGain();\n const dcOffset = ctx.createConstantSource();\n tremGain.gain.value = 0;\n lfo.type = module.shape as OscillatorType;\n lfo.frequency.value = module.rate;\n lfoGain.gain.value = module.depth * 0.5;\n dcOffset.offset.value = 1 - module.depth * 0.5;\n lfo.connect(lfoGain);\n lfoGain.connect(tremGain.gain);\n dcOffset.connect(tremGain.gain);\n lfo.start();\n dcOffset.start();\n input.connect(tremGain);\n tremGain.connect(output);\n return { input, output, lfo, lfoGain, dcOffset };\n },\n\n updateParam(nodes, _m, param, value) {\n switch (param) {\n case 'rate': nodes.lfo.frequency.value = value as number; break;\n case 'depth':\n nodes.lfoGain.gain.value = (value as number) * 0.5;\n nodes.dcOffset.offset.value = 1 - (value as number) * 0.5;\n break;\n case 'shape': nodes.lfo.type = value as OscillatorType; break;\n }\n },\n\n dispose(nodes) {\n nodes.lfo.stop();\n nodes.dcOffset.stop();\n },\n\n});\n", "import { defineModule } from '../../core';\nimport { tremoloDescriptor } from './tremolo';\nimport type { TremoloParams, TremoloInputs, TremoloOutputs, TremoloProps } from './tremolo.types';\n\n\nexport const Tremolo = /* @__PURE__ */ defineModule(tremoloDescriptor) as import('../../core').LibModule<TremoloParams, TremoloInputs, TremoloOutputs, TremoloProps>;\nexport type { TremoloParams, TremoloInputs, TremoloOutputs, TremoloProps };\n", "// @ts-nocheck \u2014 generated by scripts/lib/build.ts\nimport type { BaseModule, Position } from '@/types/synth';\n\nexport interface GainModule extends BaseModule {\n type: 'gain';\n gain: number;\n /** CV attenuverter: scales (and can invert) the signal patched into the CV input. */\n cvAmount?: number;\n}\nimport { defineDescriptor, paramDefaults } from '@/modules/ModuleDescriptor';\n\n// \u2500\u2500\u2500 PARAMS (single source of truth: knobs, defaults, hover tips, docs) \u2500\u2500\nconst params = {\n gain: { node: 'gain', field: 'gain', unit: 'factor', default: 0.5, min: 0, max: 2, },\n cvAmount: { node: 'gain', field: 'cvAmount', unit: 'factor', default: 1, min: -1, max: 1, },\n} satisfies Record<string, ParamSpec>;\nimport { createVcaNode } from '@/worklets';\n\n// \u2500\u2500\u2500 UI \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n\n// \u2500\u2500\u2500 DESCRIPTOR \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport const gainDescriptor = /* @__PURE__ */ defineDescriptor({\n type: 'gain',\n params,\n\n\n\n ports: {\n 'in': { type: 'input', signal: 'audio', node: 'gain', },\n 'out': { type: 'output', signal: 'audio', node: 'gain', },\n 'modGain': { type: 'modulation', signal: 'modulation', node: 'gain', field: 'cv' },\n },\n\n createModule(id: string, position: Position): GainModule {\n return { id, type: 'gain', position, ...paramDefaults(params) };\n },\n\n createNodes(ctx, module) {\n const gain = createVcaNode(ctx, module.gain, module.cvAmount ?? 1);\n return { gain };\n },\n\n updateParam(nodes, _module, param, value) {\n if (param === 'gain' || param === 'cvAmount') {\n const p = nodes.gain.parameters.get(param);\n if (p) p.value = value as number;\n }\n },\n\n});\n", "import { defineModule } from '../../core';\nimport { gainDescriptor } from './vca';\nimport type { VcaParams, VcaInputs, VcaOutputs, VcaProps } from './vca.types';\nimport vca from '../worklet-src/vca';\n\nexport const Vca = /* @__PURE__ */ defineModule(gainDescriptor, {\n worklets: {\n 'vca': vca,\n },\n}) as import('../../core').LibModule<VcaParams, VcaInputs, VcaOutputs, VcaProps>;\nexport type { VcaParams, VcaInputs, VcaOutputs, VcaProps };\n", "/**\n * Gain compensation helpers for resonant filters.\n *\n * Web Audio's `BiquadFilterNode` bandpass is normalised to **unity gain at the\n * centre frequency**, which is not how a resonant analog filter behaves. A\n * Cry Baby's inductor stage, a modal resonator, a formant bank \u2014 all of them\n * *boost* at resonance, and the narrower the peak, the bigger the boost. With\n * a unity-peak biquad the audible result is that turning RES up makes a patch\n * quieter and quieter until it disappears, because a narrow window throws away\n * almost all of a broadband source's energy.\n *\n * ### The maths\n *\n * For white noise of power-spectral density `S`, a 2-pole bandpass with unity\n * peak gain has equivalent noise bandwidth `(\u03C0/2)\u00B7f0/Q`, so\n *\n * ```text\n * P_out = S \u00B7 (\u03C0/2) \u00B7 f0 / Q \u21D2 RMS_out \u221D 1 / sqrt(Q)\n * ```\n *\n * Multiplying the filter output by `sqrt(Q)` therefore makes the *loudness*\n * independent of Q: RES becomes a tone control instead of a volume control,\n * which is exactly what a real resonant filter feels like under the fingers.\n * It also lands the peak gain in the right place \u2014 `sqrt(8) \u2248 +9 dB`,\n * `sqrt(20) \u2248 +13 dB`, against roughly +9\u2026+18 dB measured on a real wah.\n *\n * The cap keeps a self-oscillating setting from turning a sine that sits\n * exactly on the peak into a clipped square.\n */\nexport function bandpassMakeup(q: number, cap = 4): number {\n if (!Number.isFinite(q) || q <= 1) return 1;\n return Math.min(Math.sqrt(q), cap);\n}\n", "// @ts-nocheck \u2014 generated by scripts/lib/build.ts\nimport { BaseModule, FilterType } from '@/types/synth';\n\n\nexport interface FilterModule extends BaseModule {\n type: 'filter';\n filterType: FilterType;\n /** Cutoff as a note (69 = 440 Hz), driving the V/OCT worklet 1:1. */\n note: number;\n resonance: number;\n /** Marker: resonance is true Q in every mode (LP/HP convert to dB in the\n * map-res worklet). Saves without it predate the convention and hold dB\n * values for LP/HP \u2014 migrated once in patchStorage/tabStorage. */\n resUnit?: 'q';\n}\nimport { defineDescriptor, paramDefaults } from '@/modules/ModuleDescriptor';\nimport { createMapResNode, createVoctFreqNode } from '@/worklets';\nimport { bandpassMakeup } from '@/lib/dsp/gainComp';\n\n/** Only the bandpass tap needs resonance makeup \u2014 see lib/dsp/gainComp. */\nconst makeupFor = (type: FilterType, q: number) =>\n type === 'bandpass' ? bandpassMakeup(q) : 1;\n\n/** Web Audio biquads read Q in dB for LP/HP, dimensionless for BP/notch. */\nconst qIsDb = (type: FilterType) => type === 'lowpass' || type === 'highpass';\n\n// \u2500\u2500\u2500 PARAMS \u2014 the signal contract (no UI knowledge) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nconst params = {\n filterType: { kind: 'enum', options: ['lowpass', 'highpass', 'bandpass', 'notch'], default: 'lowpass', },\n note: { node: '_cutoffVoct', field: 'transpose', unit: 'note', default: 83, min: 15, max: 135, },\n // Resonance is split across the map-res worklet AND a compensation gain,\n // so it cannot honestly declare a single AudioParam \u2014 see lib/dsp/mix.ts\n // convention: rebuild or leave set-only. It stays set-only here.\n resonance: { unit: 'factor', default: 1, min: 0.1, max: 20, scale: 'sqrt', },\n} satisfies Record<string, ParamSpec>;\n\n// \u2500\u2500\u2500 UI \u2014 presentation layer (stripped from the library) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n\n// \u2500\u2500\u2500 DESCRIPTOR \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport const filterDescriptor = /* @__PURE__ */ defineDescriptor({\n type: 'filter',\n params,\n\n\n ports: {\n 'in': { type: 'input', signal: 'audio', node: 'filter', },\n 'out': { type: 'output', signal: 'audio', node: 'output', },\n 'modFreq': { type: 'modulation', signal: 'modulation', node: '_cutoffVoct', },\n 'modQ': { type: 'modulation', signal: 'modulation', node: '_resMap', },\n },\n\n\n createModule(id, position): FilterModule {\n return { id, type: 'filter', position, resUnit: 'q', ...paramDefaults(params) } as FilterModule;\n },\n\n createNodes(ctx, module) {\n const filter = ctx.createBiquadFilter();\n filter.type = module.filterType as BiquadFilterType;\n filter.frequency.value = 0; // driven exclusively by voct\n filter.Q.value = 0; // driven exclusively by the map-res worklet\n\n // Bandpass is the one biquad mode Web Audio normalises to unity peak\n // gain, so a narrow setting would quietly throw the signal away. An\n // analog SVF's bandpass tap gets louder as it narrows; sqrt(Q) makeup\n // restores that. Every other mode passes through untouched.\n const output = ctx.createGain();\n output.gain.value = makeupFor(module.filterType as FilterType, module.resonance);\n filter.connect(output);\n\n // V/Oct cutoff: ConstantSource(0) \u2192 voct(transpose=cutoff note) \u2192 filter.frequency\n const _cutoffVoct = createVoctFreqNode(ctx);\n _cutoffVoct.parameters.get('transpose')!.value = module.note;\n\n const _cutoffBase = ctx.createConstantSource();\n _cutoffBase.offset.value = 0;\n _cutoffBase.start();\n\n _cutoffBase.connect(_cutoffVoct);\n _cutoffVoct.connect(filter.frequency);\n\n // True-Q resonance: RES knob and CV live in one Q domain for every mode.\n // The worklet clamps (knob + CV\u00B7fullRange) to 0.1\u201320, then feeds the\n // biquad what its Q param expects: 20\u00B7log10(Q) dB for LP/HP, plain Q\n // for BP/notch (Web Audio spec quirk \u2014 see worklets/map-res.ts).\n const _resMap = createMapResNode(ctx, {\n base: module.resonance,\n dbOut: qIsDb(module.filterType as FilterType),\n });\n _resMap.connect(filter.Q);\n\n return { filter, output, _cutoffVoct, _cutoffBase, _resMap };\n },\n\n dispose(nodes) {\n try { nodes._cutoffBase.stop(); } catch (_) {}\n },\n\n updateParam(nodes, module, param, value) {\n switch (param) {\n case 'filterType':\n nodes.filter.type = value as BiquadFilterType;\n nodes._resMap.parameters.get('dbOut')!.value = qIsDb(value as FilterType) ? 1 : 0;\n nodes.output.gain.value = makeupFor(value as FilterType, module.resonance);\n break;\n case 'note': nodes._cutoffVoct.parameters.get('transpose')!.value = value as number; break;\n case 'resonance':\n nodes._resMap.parameters.get('base')!.value = value as number;\n nodes.output.gain.value = makeupFor(module.filterType as FilterType, value as number);\n break;\n }\n },\n\n\n});\n", "import { defineModule } from '../../core';\nimport { filterDescriptor } from './vcf';\nimport type { VcfParams, VcfInputs, VcfOutputs, VcfProps } from './vcf.types';\nimport map_res from '../worklet-src/map-res';\nimport map_voct_to_freq from '../worklet-src/map-voct-to-freq';\n\nexport const Vcf = /* @__PURE__ */ defineModule(filterDescriptor, {\n worklets: {\n 'map-res': map_res,\n 'map-voct-to-freq': map_voct_to_freq,\n },\n}) as import('../../core').LibModule<VcfParams, VcfInputs, VcfOutputs, VcfProps>;\nexport type { VcfParams, VcfInputs, VcfOutputs, VcfProps };\n", "// @ts-nocheck \u2014 generated by scripts/lib/build.ts\nimport type { BaseModule, Position } from '@/types/synth';\n\nexport interface OscillatorModule extends BaseModule {\n type: 'oscillator';\n skew: number; // -1\u20131: symmetry (-1=rev saw, 0=symmetric, 1=saw)\n shape: number; // -1\u20131: curvature (-1=square, 0=triangle, 1=sine)\n note: number; // panel memory: absolute note (24\u2013108) while V/OCT is unpatched\n transpose?: number; // panel memory: semitone shift (\u221248\u201348) while V/OCT is patched\n offset?: number; // library-only DSP state (see params.offset); the app derives it\n detune: number; // -1 to 1 semitones (displayed as -100 to 100 cents)\n gain: number;\n}\nimport { defineDescriptor, paramDefaults } from '@/modules/ModuleDescriptor';\nimport { createVoctFreqNode, createWaveshaperNode } from '@/worklets';\n\n// \u2500\u2500\u2500 SETTINGS \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n// DSP signal contract. Pitch is plain V/OCT arithmetic: the sounding note is\n// the V/OCT input (absolute notes, silence = 0) plus `offset` semitones. No\n// normalling \u2014 `voct` is an ordinary summing input. The app panel keeps two\n// memories (absolute `note` unpatched, relative `transpose` patched) and writes\n// whichever applies into the offset; the DSP never knows about cables.\nconst params = {\n skew: { node: '_ws', field: 'skew', unit: 'factor', default: 1.0, min: -1, max: 1, },\n shape: { node: '_ws', field: 'shape', unit: 'factor', default: 0.0, min: -1, max: 1, },\n offset: { node: '_voct', field: 'transpose', default: 69, min: -48, max: 108, unit: 'semitone', },\n detune: { node: '_detune', field: 'offset', default: 0, min: -1, max: 1, unit: 'semitone', },\n gain: { node: 'gain', field: 'gain', unit: 'factor', default: 0.5, min: 0, max: 1, },\n} as const satisfies Record<string, ParamSpec>;\n\n/** Cables currently on V/OCT, per node set \u2014 picks the live panel memory. */\nconst patchCount = new WeakMap<object, number>();\n\n// \u2500\u2500\u2500 UI \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n\n// \u2500\u2500\u2500 DESCRIPTOR \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport const oscillatorDescriptor = /* @__PURE__ */ defineDescriptor({\n type: 'oscillator',\n\n\n\n ports: {\n 'voct': { type: 'input', node: '_voct', signal: 'pitch' },\n 'out': { type: 'output', signal: 'audio', node: 'gain', },\n 'modSkew': { type: 'modulation', signal: 'modulation', node: '_ws', field: 'skew' },\n 'modShape': { type: 'modulation', signal: 'modulation', node: '_ws', field: 'shape' },\n 'modDetune': { type: 'modulation', signal: 'modulation', node: '_detune', field: 'offset' },\n },\n\n params,\n\n\n // \u2500\u2500\u2500 Factory \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n createModule(id: string, position: Position): OscillatorModule {\n const { offset: _dsp, ...rest } = paramDefaults(params);\n return { id, type: 'oscillator', position, ...rest, note: 69, transpose: 0 };\n },\n\n // \u2500\u2500\u2500 Audio Engine \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n createNodes(ctx, module) {\n // Waveshaper worklet replaces OscillatorNode\n const _ws = createWaveshaperNode(ctx);\n const gain = ctx.createGain();\n \n // Detune: ConstantSource in semitones, feeds into V/Oct sum\n const _detune = ctx.createConstantSource();\n _detune.offset.value = module.detune;\n _detune.start();\n\n // V/OCT worklet \u2014 always in the signal path.\n // V/OCT worklet \u2014 always in the signal path. Its input sums V/OCT cables\n // and detune; its `transpose` param is the pitch offset. Nothing patched\n // = silent input, so the offset alone is the note. Library instances set\n // `offset`; app modules start unpatched, so the note memory applies\n // (onConnect swaps to the transpose memory when a cable lands).\n const _voct = createVoctFreqNode(ctx);\n _detune.connect(_voct); // detune sums into V/Oct input\n _voct.connect(_ws); // frequency input to waveshaper\n _voct.parameters.get('transpose')!.value = module.offset ?? module.note;\n\n // Set initial waveshape params\n _ws.parameters.get('skew')!.value = module.skew;\n _ws.parameters.get('shape')!.value = module.shape;\n _ws.parameters.get('normalize')!.value = 1;\n\n gain.gain.value = module.gain;\n _ws.connect(gain);\n\n return { gain, _ws, _voct, _detune };\n },\n\n updateParam(nodes, _module, param, value) {\n switch (param) {\n case 'skew': nodes._ws.parameters.get('skew')!.value = value as number; break;\n case 'shape': nodes._ws.parameters.get('shape')!.value = value as number; break;\n case 'offset': nodes._voct.parameters.get('transpose')!.value = value as number; break;\n // App panel memories: only the one matching the patch state is live.\n case 'note':\n if (!patchCount.get(nodes)) nodes._voct.parameters.get('transpose')!.value = value as number;\n break;\n case 'transpose':\n if (patchCount.get(nodes)) nodes._voct.parameters.get('transpose')!.value = value as number;\n break;\n case 'detune': nodes._detune.offset.value = value as number; break;\n case 'gain': nodes.gain.gain.value = value as number; break;\n }\n },\n\n // App-only: the connection is a plain summing connect; these hooks only\n // swap which panel memory drives the offset.\n onConnect(nodes, module, portId, sourceNode) {\n if (portId !== 'voct') return false;\n sourceNode.connect(nodes._voct);\n patchCount.set(nodes, (patchCount.get(nodes) ?? 0) + 1);\n nodes._voct.parameters.get('transpose')!.value = module.transpose ?? 0;\n return true;\n },\n\n onDisconnect(nodes, module, portId, sourceNode) {\n if (portId !== 'voct') return false;\n try { sourceNode.disconnect(nodes._voct); } catch (e) {}\n const n = Math.max(0, (patchCount.get(nodes) ?? 0) - 1);\n patchCount.set(nodes, n);\n if (!n) nodes._voct.parameters.get('transpose')!.value = module.note;\n return true;\n },\n\n dispose(nodes) {\n nodes._detune.stop();\n },\n\n});\n", "import { defineModule } from '../../core';\nimport { oscillatorDescriptor } from './vco';\nimport type { VcoParams, VcoInputs, VcoOutputs, VcoProps } from './vco.types';\nimport map_voct_to_freq from '../worklet-src/map-voct-to-freq';\nimport waveshaper from '../worklet-src/waveshaper';\n\nexport const Vco = /* @__PURE__ */ defineModule(oscillatorDescriptor, {\n worklets: {\n 'map-voct-to-freq': map_voct_to_freq,\n 'waveshaper': waveshaper,\n },\n}) as import('../../core').LibModule<VcoParams, VcoInputs, VcoOutputs, VcoProps>;\nexport type { VcoParams, VcoInputs, VcoOutputs, VcoProps };\n", "// @ts-nocheck \u2014 generated by scripts/lib/build.ts\nimport { BaseModule } from '@/types/synth';\n\nimport { defineDescriptor, paramDefaults } from '@/modules/ModuleDescriptor';\nimport { createVoctFreqNode } from '@/worklets';\nimport { bandpassMakeup } from '@/lib/dsp/gainComp';\n\nexport interface WahModule extends BaseModule {\n type: 'wah';\n /** Center frequency as a note (69 = 440 Hz), driving the V/OCT worklet 1:1. */\n note: number;\n resonance: number;\n rate: number;\n depth: number;\n}\n\nconst params = {\n note: { node: '_cutoffVoct', field: 'transpose', unit: 'note', default: 79, min: 55, max: 95, },\n // Resonance drives both the filter Q and a separate makeup gain \u2014 a split, so it stays set-only.\n resonance: { unit: 'factor', default: 8, min: 1, max: 20, scale: 'log', },\n rate: { node: 'lfo', field: 'frequency', unit: 'Hz', default: 1, min: 0.1, max: 10, scale: 'log', },\n // Depth is stored 0-1 but scaled by 36 semitones onto lfoGain.gain \u2014 a conversion, so set-only.\n depth: { unit: 'factor', default: 0.6, min: 0, max: 1, },\n} satisfies Record<string, ParamSpec>;\n\n\n\nexport const wahDescriptor = /* @__PURE__ */ defineDescriptor({\n type: 'wah',\n params,\n\n ports: {\n 'in': { type: 'input', signal: 'audio', node: 'input', },\n 'out': { type: 'output', signal: 'audio', node: 'output', },\n 'modFreq': { type: 'modulation', signal: 'modulation', node: '_cutoffVoct', },\n },\n\n createModule(id, position) {\n return { id, type: 'wah', position, ...paramDefaults(params) };\n },\n\n createNodes(ctx, module) {\n const input = ctx.createGain();\n const output = ctx.createGain();\n const filter = ctx.createBiquadFilter();\n const lfo = ctx.createOscillator();\n const lfoGain = ctx.createGain();\n\n filter.type = 'bandpass';\n filter.frequency.value = 0; // driven by voct\n filter.Q.value = module.resonance;\n\n // A real wah's filter stage *boosts* at resonance; a Web Audio bandpass\n // peaks at unity, so a narrow setting would just fade the signal away.\n // sqrt(Q) makeup restores the pedal's resonant peak gain and keeps RES a\n // tone control rather than a volume control. See lib/dsp/gainComp.\n const makeup = ctx.createGain();\n makeup.gain.value = bandpassMakeup(module.resonance);\n\n // V/Oct cutoff\n const _cutoffVoct = createVoctFreqNode(ctx);\n _cutoffVoct.parameters.get('transpose')!.value = module.note;\n\n const _cutoffBase = ctx.createConstantSource();\n _cutoffBase.offset.value = 0;\n _cutoffBase.start();\n\n _cutoffBase.connect(_cutoffVoct);\n _cutoffVoct.connect(filter.frequency);\n\n // Internal LFO \u2192 voct input (semitones)\n // depth 1.0 = 36 semitones = 3 octaves of sweep\n lfo.type = 'sine';\n lfo.frequency.value = module.rate;\n lfoGain.gain.value = module.depth * 36;\n\n lfo.connect(lfoGain);\n lfoGain.connect(_cutoffVoct); // semitones \u2192 voct input\n lfo.start();\n\n input.connect(filter);\n filter.connect(makeup);\n makeup.connect(output);\n\n return { input, output, filter, makeup, lfo, lfoGain, _cutoffVoct, _cutoffBase };\n },\n\n updateParam(nodes, _module, param, value) {\n if (param === 'note') {\n nodes._cutoffVoct.parameters.get('transpose')!.value = value as number;\n } else if (param === 'resonance') {\n nodes.filter.Q.value = value as number;\n nodes.makeup.gain.value = bandpassMakeup(value as number);\n\n } else if (param === 'rate') {\n nodes.lfo.frequency.value = value as number;\n } else if (param === 'depth') {\n nodes.lfoGain.gain.value = (value as number) * 36;\n }\n },\n\n dispose(nodes) {\n nodes.lfo.stop();\n nodes._cutoffBase.stop();\n },\n\n});\n", "import { defineModule } from '../../core';\nimport { wahDescriptor } from './wah';\nimport type { WahParams, WahInputs, WahOutputs, WahProps } from './wah.types';\nimport map_voct_to_freq from '../worklet-src/map-voct-to-freq';\n\nexport const Wah = /* @__PURE__ */ defineModule(wahDescriptor, {\n worklets: {\n 'map-voct-to-freq': map_voct_to_freq,\n },\n}) as import('../../core').LibModule<WahParams, WahInputs, WahOutputs, WahProps>;\nexport type { WahParams, WahInputs, WahOutputs, WahProps };\n", "// @ts-nocheck \u2014 generated by scripts/lib/build.ts\nimport { createMix } from '@/lib/dsp/mix';\nimport { BaseModule } from '@/types/synth';\nimport { defineDescriptor, paramDefaults } from '@/modules/ModuleDescriptor';\n\nexport interface WavefolderModule extends BaseModule {\n type: 'wavefolder';\n folds: number;\n symmetry: number;\n mix: number;\n}\n\n// \u2500\u2500\u2500 PARAMS \u2014 the signal contract (no UI knowledge) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n// folds/symmetry rebuild the waveshaper curve \u2014 not a 1:1 AudioParam write.\nconst params = {\n folds: { unit: 'factor', default: 2, min: 1, max: 10, },\n symmetry: { unit: 'factor', default: 0, min: -1, max: 1, },\n mix: { node: '_mix', field: 'offset', unit: 'factor', default: 1.0, min: 0, max: 1, },\n} satisfies Record<string, ParamSpec>;\n\n\n/**\n * True sine-fold transfer: y = sin(\u03C0/2 \u00B7 folds \u00B7 (x + bias)), DC-compensated.\n *\n * FOLDS is baked into the curve itself so the transfer genuinely folds \u2014\n * folds 1 is a gentle monotonic shaper (x=\u00B11 \u2192 \u00B11), folds 10 reflects a\n * full-scale input ten quarter-periods deep. The previous design pre-scaled\n * the INPUT by folds into a fixed sin(\u03C0x) curve; WaveShaper clamps its\n * domain at \u00B11, so anything past drive 1 saturated at the curve endpoints\n * instead of folding (reports/wavefolder.md findings #1/#2). Input level\n * still plays the folder West-Coast style: quiet signals stay in the\n * near-linear origin segment, hot signals reach deeper folds.\n *\n * SYM biases the fold point (bias = 0.2\u00B7sym); the resulting DC at silence\n * is subtracted so an idle folder outputs 0, and the curve is renormalized\n * to peak 1 when the bias shift pushes it past full scale.\n */\nfunction makeWavefoldCurve(folds: number, symmetry: number): Float32Array {\n const samples = 65536;\n const curve = new Float32Array(samples);\n const bias = symmetry * 0.2;\n const w = (Math.PI / 2) * folds;\n const dc = Math.sin(w * bias);\n let peak = 0;\n for (let i = 0; i < samples; i++) {\n const x = (i * 2) / samples - 1;\n const y = Math.sin(w * (x + bias)) - dc;\n curve[i] = y;\n const a = Math.abs(y);\n if (a > peak) peak = a;\n }\n if (peak > 1) {\n const inv = 1 / peak;\n for (let i = 0; i < samples; i++) curve[i] *= inv;\n }\n return curve;\n}\n\n\nexport const wavefolderDescriptor = /* @__PURE__ */ defineDescriptor({\n type: 'wavefolder',\n params,\n\n ports: {\n 'in': { type: 'input', signal: 'audio', node: 'input', },\n 'out': { type: 'output', signal: 'audio', node: 'output', },\n },\n\n createModule(id, position) {\n return { id, type: 'wavefolder', position, ...paramDefaults(params) };\n },\n\n createNodes(ctx, module) {\n const input = ctx.createGain();\n const output = ctx.createGain();\n const dryGain = ctx.createGain();\n const wetGain = ctx.createGain();\n const waveshaper = ctx.createWaveShaper();\n\n waveshaper.curve = makeWavefoldCurve(module.folds, module.symmetry) as Float32Array<ArrayBuffer>;\n waveshaper.oversample = '4x';\n const _mix = createMix(ctx, dryGain, wetGain, module.mix, 'linear');\n\n // No pre-gain stage: FOLDS lives in the transfer curve, so the shaper's\n // \u00B11 domain is never exceeded and every knob position genuinely folds.\n input.connect(dryGain);\n input.connect(waveshaper);\n waveshaper.connect(wetGain);\n dryGain.connect(output);\n wetGain.connect(output);\n\n return { input, output, waveshaper, dryGain, wetGain, _mix };\n },\n\n updateParam(nodes, module, param, value) {\n if (param === 'folds' || param === 'symmetry') {\n // Same pattern as distortion: the reactive module proxy is mutated\n // before the engine relays the update, so both curve params are current.\n nodes.waveshaper.curve = makeWavefoldCurve(module.folds, module.symmetry) as Float32Array<ArrayBuffer>;\n } else if (param === 'mix') {\n (nodes._mix as ConstantSourceNode).offset.value = value as number;\n }\n },\n\n});\n", "import { defineModule } from '../../core';\nimport { wavefolderDescriptor } from './wavefolder';\nimport type { WavefolderParams, WavefolderInputs, WavefolderOutputs, WavefolderProps } from './wavefolder.types';\n\n\nexport const Wavefolder = /* @__PURE__ */ defineModule(wavefolderDescriptor) as import('../../core').LibModule<WavefolderParams, WavefolderInputs, WavefolderOutputs, WavefolderProps>;\nexport type { WavefolderParams, WavefolderInputs, WavefolderOutputs, WavefolderProps };\n"],
|
|
5
|
-
"mappings": "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",
|
|
6
|
-
"names": ["params", "voice", "t", "now", "ms", "db", "params", "params", "semitones", "params", "params", "params", "hz", "params", "params", "params", "params", "CURVE_POINTS", "lawCurve", "params", "params", "params", "params", "params", "params", "params", "params", "params", "params", "params", "params", "params", "params", "params", "params", "params", "params", "params", "noiseBuffer", "params", "params", "params", "params", "params", "params", "params", "patchCount", "params", "patchCount", "now", "params", "now", "params", "patchCount", "params", "now", "params", "params", "now", "params", "params", "params", "params", "params", "params", "params", "shapes", "params", "params", "params", "params", "patchCount", "params", "params"]
|
|
3
|
+
"sources": ["../src/lib-runtime/core.ts", "../src/lib-runtime/time/transport.ts", "../src/lib/dsp/prng.ts", "../src/lib-runtime/time/voices.ts", "../src/lib-runtime/units.ts", "../src/lib/dsp/pulse.ts", "../src/lib/samples/types.ts", "../src/lib-runtime/samples.ts", "../src/modules/ModuleDescriptor.ts", "../src/lib-runtime/generated/worklet-factories.ts", "../src/lib/dsp/keepAlive.ts", "../src/lib-runtime/generated/modules/303-filter.tsx", "../src/lib-runtime/generated/modules/303-filter.wrapper.ts", "../src/lib-runtime/generated/modules/auto-pan.tsx", "../src/lib-runtime/generated/modules/auto-pan.wrapper.ts", "../src/lib/dsp/mix.ts", "../src/lib-runtime/generated/modules/bitcrusher.tsx", "../src/lib-runtime/generated/modules/bitcrusher.wrapper.ts", "../src/lib-runtime/generated/modules/chorus.tsx", "../src/lib-runtime/generated/modules/chorus.wrapper.ts", "../src/types/synth.ts", "../src/lib-runtime/generated/modules/comb-filter.tsx", "../src/lib-runtime/generated/modules/comb-filter.wrapper.ts", "../src/lib-runtime/generated/modules/comp.tsx", "../src/lib-runtime/generated/modules/comp.wrapper.ts", "../src/lib-runtime/generated/modules/crossfade.tsx", "../src/lib-runtime/generated/modules/crossfade.wrapper.ts", "../src/lib-runtime/generated/modules/delay.tsx", "../src/lib-runtime/generated/modules/delay.wrapper.ts", "../src/lib-runtime/generated/modules/dimension.tsx", "../src/lib-runtime/generated/modules/dimension.wrapper.ts", "../src/lib-runtime/generated/modules/distortion.tsx", "../src/lib-runtime/generated/modules/distortion.wrapper.ts", "../src/lib-runtime/generated/modules/ducker.tsx", "../src/lib-runtime/generated/modules/ducker.wrapper.ts", "../src/lib-runtime/generated/modules/env-follow.tsx", "../src/lib-runtime/generated/modules/env-follow.wrapper.ts", "../src/lib-runtime/generated/modules/envelope.tsx", "../src/lib-runtime/generated/modules/envelope.wrapper.ts", "../src/lib-runtime/generated/modules/eq3.tsx", "../src/lib-runtime/generated/modules/eq3.wrapper.ts", "../src/lib-runtime/generated/modules/exciter.tsx", "../src/lib-runtime/generated/modules/exciter.wrapper.ts", "../src/lib-runtime/generated/modules/flanger.tsx", "../src/lib-runtime/generated/modules/flanger.wrapper.ts", "../src/lib-runtime/generated/modules/formant.tsx", "../src/lib-runtime/generated/modules/formant.wrapper.ts", "../src/lib-runtime/generated/modules/freq-shifter.tsx", "../src/lib-runtime/generated/modules/freq-shifter.wrapper.ts", "../src/lib-runtime/generated/modules/gate.tsx", "../src/lib-runtime/generated/modules/gate.wrapper.ts", "../src/lib-runtime/generated/modules/glide.tsx", "../src/lib-runtime/generated/modules/glide.wrapper.ts", "../src/lib-runtime/generated/modules/haas.tsx", "../src/lib-runtime/generated/modules/haas.wrapper.ts", "../src/lib-runtime/generated/modules/harmonic-trem.tsx", "../src/lib-runtime/generated/modules/harmonic-trem.wrapper.ts", "../src/lib-runtime/generated/modules/ladder-filter.tsx", "../src/lib-runtime/generated/modules/ladder-filter.wrapper.ts", "../src/lib-runtime/generated/modules/lfo.tsx", "../src/lib-runtime/generated/modules/lfo.wrapper.ts", "../src/lib-runtime/generated/modules/lo-fi.tsx", "../src/lib-runtime/generated/modules/lo-fi.wrapper.ts", "../src/lib-runtime/generated/modules/mid-side.tsx", "../src/lib-runtime/generated/modules/mid-side.wrapper.ts", "../src/lib-runtime/generated/modules/noise.tsx", "../src/lib-runtime/generated/modules/noise.wrapper.ts", "../src/lib-runtime/generated/modules/octaver.tsx", "../src/lib-runtime/generated/modules/octaver.wrapper.ts", "../src/lib-runtime/generated/modules/phaser.tsx", "../src/lib-runtime/generated/modules/phaser.wrapper.ts", "../src/lib-runtime/generated/modules/ping-pong.tsx", "../src/lib-runtime/generated/modules/ping-pong.wrapper.ts", "../src/lib/dsp/modal.ts", "../src/lib-runtime/generated/modules/resonator.tsx", "../src/lib-runtime/generated/modules/resonator.wrapper.ts", "../src/lib/dsp/fdnTank.ts", "../src/lib-runtime/generated/modules/reverb.tsx", "../src/lib-runtime/generated/modules/reverb.wrapper.ts", "../src/lib-runtime/generated/modules/ring-mod.tsx", "../src/lib-runtime/generated/modules/ring-mod.wrapper.ts", "../src/lib-runtime/generated/modules/rotary.tsx", "../src/lib-runtime/generated/modules/rotary.wrapper.ts", "../src/lib-runtime/generated/modules/saturator.tsx", "../src/lib-runtime/generated/modules/saturator.wrapper.ts", "../src/lib-runtime/generated/modules/shimmer.tsx", "../src/lib-runtime/generated/modules/shimmer.wrapper.ts", "../src/lib-runtime/generated/modules/soft-limit.tsx", "../src/lib-runtime/generated/modules/soft-limit.wrapper.ts", "../src/lib-runtime/generated/modules/spring-reverb.tsx", "../src/lib-runtime/generated/modules/spring-reverb.wrapper.ts", "../src/lib-runtime/generated/modules/stereo-spread.tsx", "../src/lib-runtime/generated/modules/stereo-spread.wrapper.ts", "../src/lib-runtime/generated/modules/sub-harm.tsx", "../src/lib-runtime/generated/modules/sub-harm.wrapper.ts", "../src/lib-runtime/generated/modules/tape-delay.tsx", "../src/lib-runtime/generated/modules/tape-delay.wrapper.ts", "../src/lib-runtime/generated/modules/tape-stop.tsx", "../src/lib-runtime/generated/modules/tape-stop.wrapper.ts", "../src/lib-runtime/generated/modules/tilt.tsx", "../src/lib-runtime/generated/modules/tilt.wrapper.ts", "../src/lib-runtime/generated/modules/tremolo.tsx", "../src/lib-runtime/generated/modules/tremolo.wrapper.ts", "../src/lib-runtime/generated/modules/vca.tsx", "../src/lib-runtime/generated/modules/vca.wrapper.ts", "../src/lib/dsp/gainComp.ts", "../src/lib-runtime/generated/modules/vcf.tsx", "../src/lib-runtime/generated/modules/vcf.wrapper.ts", "../src/lib-runtime/generated/modules/vco.tsx", "../src/lib-runtime/generated/modules/vco.wrapper.ts", "../src/lib-runtime/generated/modules/wah.tsx", "../src/lib-runtime/generated/modules/wah.wrapper.ts", "../src/lib-runtime/generated/modules/wavefolder.tsx", "../src/lib-runtime/generated/modules/wavefolder.wrapper.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * Library runtime core \u2014 the only code the shipped package needs beyond the\n * stripped module descriptors themselves.\n *\n * Public entry point: preload(ctx) \u2014 register the inlined worklet processors,\n * once per context. defineModule() is internal: the generated module wrappers\n * call it, but it is not exported from the package (its parameter is the\n * app's ModuleDescriptor, which would drag Solid UI types into index.d.ts).\n *\n * Worklet sources reach here two ways:\n * - each module's pure-annotated defineModule() call passes the worklet\n * strings it needs (tree-shaken away with the module when unused), and\n * - preload(ctx, { allWorklets: true }) lazily pulls in the full generated\n * worklet set \u2014 the simple path for dev builds and the app itself.\n */\n\nimport type { ModuleDescriptor, ParamSpec, PortDefinition } from '@/modules/ModuleDescriptor';\nimport type { BaseModule } from '@/types/synth';\n\n// \u2500\u2500\u2500 preload(ctx) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/** Worklet sources of every module whose defineModule() call survived tree\n * shaking (i.e. every module the consumer actually references). Filled by\n * defineModule \u2014 a deliberate side effect inside the @__PURE__-annotated\n * factory call: shake the module away and its worklet strings vanish too. */\nconst pendingSources: Record<string, string> = {};\n\n/** One registration promise per context (each BaseAudioContext needs its own addModule calls). */\nconst registrations = new WeakMap<BaseAudioContext, Promise<void>>();\n\n/**\n * Register every bundled worklet processor on `ctx`. Required before any\n * module's create() on that context. Safe to call twice or concurrently \u2014\n * subsequent calls return the same promise.\n *\n * Processors are inlined as minified source strings and loaded via blob URLs,\n * so the package needs zero fetches and zero consumer asset setup. Consumers\n * under a strict CSP need `worker-src blob:` allowed.\n */\nexport function preload(ctx: BaseAudioContext, opts?: { allWorklets?: boolean }): Promise<void> {\n const existing = registrations.get(ctx);\n if (existing) return existing;\n\n // Default: only the worklets of modules that survived tree shaking.\n // allWorklets: pull in the full generated set (dev builds, the app itself).\n const sources = opts?.allWorklets\n ? import('./generated/worklets-inline').then((m) => m.WORKLET_SOURCES)\n : Promise.resolve(pendingSources);\n\n const promise = sources.then((map) =>\n Promise.all(Object.entries(map).map(async ([name, src]) => {\n const url = URL.createObjectURL(new Blob([src], { type: 'text/javascript' }));\n try {\n await ctx.audioWorklet.addModule(url);\n } catch (err) {\n throw new Error(`squelchy: failed to register worklet \"${name}\": ${err}`);\n } finally {\n URL.revokeObjectURL(url);\n }\n })),\n ).then(() => {});\n\n registrations.set(ctx, promise);\n return promise;\n}\n\n// \u2500\u2500\u2500 Public module shape \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport type ParamValue = number | string | boolean | number[] | boolean[][];\n\n/** Runtime metadata \u2014 only what code needs. Human-facing text (names,\n * descriptions, labels) is stripped from the bundle; it lives in the\n * generated docs/MODULES.md, meta.json and the .d.ts JSDoc instead. */\nexport interface ModuleMeta {\n type: string;\n ports: Record<string, Pick<PortDefinition, 'type' | 'signal'>>;\n params: Record<string, Pick<ParamSpec, 'default' | 'kind' | 'min' | 'max' | 'scale' | 'options' | 'node' | 'field'>>;\n}\n\ntype AnyParams = Record<string, ParamValue>;\n\n/** Port map: slug \u2192 the signal type behind that port. Pitch outputs are\n * `Signal<Note>` (absolute key positions, 69 = A4); everything else (audio,\n * gate, clock, CV) is a plain AudioNode \u2014 factor signals connect freely. */\nexport type PortMap = Record<string, AudioNode>;\n\n/** Native connect targets: `src.connect(module.input(slug))` works for every\n * key \u2014 an AudioParam where the port drives a real parameter (Web Audio sums\n * the CV onto the knob's base value), otherwise the AudioNode. */\nexport type InputMap = Record<string, AudioNode | AudioParam>;\n\nexport interface InstanceApi<P extends object = AnyParams, In extends InputMap = InputMap, Out extends PortMap = PortMap> {\n /** Native connect target behind an input slug: AudioParam or AudioNode. */\n input<K extends keyof In & string>(slug: K): In[K];\n output<K extends keyof Out & string>(slug: K): Out[K];\n /** Change a parameter now. For timed changes (ramps, curves, schedules)\n * use the native AudioParam in `params` \u2014 enums and derived params\n * (curves, filter banks) are set()-only by design. */\n set<K extends keyof P & string>(key: K, value: Exclude<P[K], undefined>): void;\n dispose(): void;\n}\n\n/** A module instance is the API above plus one native-feeling property per\n * port: camelCased slug \u2192 the same AudioParam/AudioNode input()/output()\n * returns, so `lfo.out.connect(vco.modDetune)` reads like a native node.\n * Slugs that would collide (with each other after camelCasing, or with a\n * reserved method name) are simply not exposed \u2014 the build refuses them. */\nexport type ModuleInstance<P extends object = AnyParams, In extends InputMap = InputMap, Out extends PortMap = PortMap, Props extends object = Record<never, never>> = InstanceApi<P, In, Out> & Props;\n\nexport interface LibModule<P extends object = AnyParams, In extends InputMap = InputMap, Out extends PortMap = PortMap, Props extends object = Record<never, never>> {\n meta: ModuleMeta;\n create(ctx: BaseAudioContext, params?: Partial<P>): ModuleInstance<P, In, Out, Props>;\n}\n\nlet instanceCounter = 0;\n\n/** Wrap a stripped module descriptor into the library's public module shape.\n * `opts.worklets` carries the minified sources of the processors this module\n * needs; they are registered with preload() here, deliberately, so that a\n * module shaken away by the consumer's bundler takes its worklets with it. */\nexport function defineModule(desc: ModuleDescriptor, opts?: { worklets?: Record<string, string> }): LibModule {\n if (opts?.worklets) Object.assign(pendingSources, opts.worklets);\n const meta: ModuleMeta = { type: desc.type, ports: desc.ports, params: desc.params ?? {} };\n\n return {\n meta,\n create(ctx, params = {}) {\n const module = { ...desc.createModule(`lib-${desc.type}-${instanceCounter++}`, { x: 0, y: 0 }), ...params };\n // Descriptors are typed against AudioContext; BaseAudioContext is the\n // structural superset the DSP actually uses (offline contexts included).\n const nodes = desc.createNodes(ctx as AudioContext, module);\n return withPortProperties(new Instance(desc, module, nodes), desc) as ModuleInstance<any, any, any, any>;\n },\n };\n}\n\n/** Property names the instance API already owns \u2014 a port slug colliding with\n * one of these is not exposed as a property (the build refuses such slugs). */\nconst RESERVED_PROPS = new Set(['input', 'output', 'set', 'dispose', 'params', 'then']);\n\n/** Wrap an instance in a Proxy that exposes each port as a native-feeling\n * property: the slug itself (camelCase by convention) \u2192 the same\n * AudioParam/AudioNode input()/output() returns. Slugs are the property\n * names verbatim \u2014 no conversion layer. A slug shared by an input and an\n * output, or colliding with a reserved name, is skipped (input()/output()\n * still reach it); the lib build's collision check refuses such modules. */\nfunction withPortProperties(inst: Instance, desc: ModuleDescriptor): Instance {\n const props = new Map<string, () => AudioNode | AudioParam>();\n for (const [slug, p] of Object.entries(desc.ports)) {\n if (RESERVED_PROPS.has(slug) || props.has(slug)) continue;\n props.set(slug, p.type === 'output' ? () => inst.output(slug) : () => inst.input(slug));\n }\n return new Proxy(inst, {\n get(target, key, receiver) {\n if (typeof key === 'string') {\n const hit = props.get(key);\n if (hit) return hit();\n }\n return Reflect.get(target, key, receiver);\n },\n });\n}\n\nclass Instance implements ModuleInstance {\n constructor(\n private desc: ModuleDescriptor,\n private module: BaseModule,\n private nodes: Record<string, AudioNode>,\n ) {}\n\n private port(slug: string): PortDefinition {\n const p = this.desc.ports[slug];\n if (!p) throw new Error(`squelchy: unknown port \"${slug}\" on ${this.desc.type}`);\n return p;\n }\n\n private nodeFor(slug: string): AudioNode {\n const p = this.port(slug);\n const node = p.node ? this.nodes[p.node] : undefined;\n if (!node) throw new Error(`squelchy: port \"${slug}\" on ${this.desc.type} has no audio node`);\n return node;\n }\n\n input(slug: string): AudioNode | AudioParam {\n const p = this.port(slug);\n const node = this.nodeFor(slug);\n if (!p.field) return node;\n // Native params (GainNode.gain, ConstantSource.offset) or worklet params.\n return this.resolveParam(p.node!, p.field, `port \"${slug}\"`);\n }\n output(slug: string): AudioNode { return this.nodeFor(slug); }\n\n /** Native AudioParams behind params declaring `node` + `field` (1:1 mapped,\n * no conversion) \u2014 full Web Audio automation: ramps, curves, CV. */\n get params(): Record<string, AudioParam> {\n const out: Record<string, AudioParam> = {};\n for (const [key, spec] of Object.entries(this.desc.params ?? {})) {\n if (!spec.node || !spec.field) continue;\n Object.defineProperty(out, key, { enumerable: true, get: () => this.resolveParam(spec.node!, spec.field!, `param \"${key}\"`) });\n }\n return out;\n }\n\n private resolveParam(nodeKey: string, field: string, what: string): AudioParam {\n const node = this.nodes[nodeKey];\n const param = (node as unknown as Record<string, AudioParam | undefined> | undefined)?.[field]\n ?? (node as AudioWorkletNode | undefined)?.parameters?.get(field);\n if (!param || typeof (param as AudioParam).setValueAtTime !== 'function') throw new Error(`squelchy: ${what} on ${this.desc.type} has no AudioParam \"${nodeKey}.${field}\"`);\n return param;\n }\n\n set(key: string, value: any): void {\n (this.module as unknown as Record<string, ParamValue>)[key] = value;\n this.desc.updateParam(this.nodes, this.module, key, value);\n }\n\n dispose(): void {\n this.desc.dispose?.(this.nodes);\n for (const node of Object.values(this.nodes)) {\n if (typeof (node as AudioScheduledSourceNode).stop === 'function') { try { (node as AudioScheduledSourceNode).stop(); } catch { /* not started / already stopped */ } }\n try { node.disconnect(); } catch { /* already disconnected */ }\n }\n }\n}\n", "/**\n * Library transport \u2014 musical time for plain Web Audio code.\n *\n * Library-only on purpose (the app keeps its own globalTransport for now).\n *\n * Units, chosen to be the easiest thing to write correctly:\n * - Musical positions are plain numbers in BEATS (quarter notes). Bar 2 of\n * a 4/4 song starts at beat 4. 16ths are 0.25.\n * - Audio times are ctx.currentTime seconds, as everywhere in Web Audio.\n * - A pattern is a plain array; one element per step. Step length defaults\n * to a 16th (`every: 0.25`).\n *\n * Scheduling is the usual lookahead pattern (timer on the main thread, events\n * written with sample-accurate `when` times). On an OfflineAudioContext the\n * whole render window is scheduled up front, so offline renders are exact.\n */\n\nimport type { Beats, Note, Seconds } from '../units';\nexport type { Beats };\n\n/** Where a playback starts. Default 'bar' = next bar line (beat 0 if stopped). */\nexport type StartAt = 'now' | 'beat' | 'bar' | { bar: number } | { beat: Beats };\n\n/** Rich step form, for when a plain value isn't enough. */\nexport interface StepObject<V> {\n value: V;\n /** 0..1, default 1. */\n velocity?: number;\n /** Gate length in steps, default = the playback's `gate`. */\n length?: number;\n}\n\n/** A pattern step: a value, a rest (null/undefined/false/0/'.'/'-'), or a StepObject. */\nexport type Step<V> = V | StepObject<V> | null | undefined | false;\n\n/** What a voice receives per hit. */\nexport interface Hit<V = unknown> {\n /** Audio time the sound starts (ctx.currentTime domain). */\n time: Seconds;\n /** Musical position of the hit, in beats. */\n beat: Beats;\n /** Step index within the pattern. */\n step: number;\n /** Loop iteration, 0-based. */\n cycle: number;\n /** The step's value (true for `steps('x..x')`, a midi number for melodies, \u2026). */\n value: V;\n velocity: number;\n /** Gate length in seconds. */\n duration: Seconds;\n}\n\n/**\n * Anything that makes sound at a time. Voice objects expose `trigger`; a plain\n * function `(time, hit) => void` works too, so any existing Web Audio code\n * (e.g. `(t) => osc.start(t)`) can be driven by a pattern.\n */\nexport type Voice<V = unknown> =\n | { trigger(time: Seconds, hit?: Partial<Hit<V>>): void }\n | ((time: Seconds, hit: Hit<V>) => void);\n\nexport interface PlayOptions<V> {\n /** Step length in beats. Default 0.25 (16ths). */\n every?: Beats;\n /** Where to start. Default 'bar'. */\n start?: StartAt;\n /** true = forever (default), false = once, n = n times. */\n loop?: boolean | number;\n /** Gate length as a fraction of a step. Default 0.5. */\n gate?: number;\n /** 0..1 \u2014 delays every odd step by swing \u00D7 half a step. Default 0. */\n swing?: number;\n /** Visual tap for this playback (fires when the hit is audible). */\n onHit?: (hit: Hit<V>) => void;\n}\n\nexport interface Playback<V> {\n /** Swap the pattern; takes effect at the next cycle start, so it stays in time. */\n set(pattern: readonly Step<V>[]): void;\n /** Stop scheduling. With a StartAt, stops at that musical boundary instead of now. */\n stop(at?: StartAt): void;\n readonly done: boolean;\n}\n\nexport interface TransportOptions {\n bpm?: number;\n beatsPerBar?: number;\n /** Seconds scheduled ahead. Default 0.1. */\n lookahead?: Seconds;\n /** 'auto' = internal 25 ms timer; 'manual' = you call tick() (tests, custom loops). */\n clock?: 'auto' | 'manual';\n}\n\nexport interface Transport {\n readonly ctx: BaseAudioContext;\n bpm: number;\n readonly beatsPerBar: number;\n readonly running: boolean;\n /** Start at audio time `when` (default: a hair from now). Beat 0 = that moment. */\n start(when?: Seconds): void;\n /** Stop scheduling and cancel pending taps. Already-written events (\u2264 lookahead) still sound. */\n stop(): void;\n /** Musical position at an audio time. */\n beatAt(time: Seconds): Beats;\n /** Audio time of a musical position. */\n timeAt(beat: Beats): Seconds;\n /** Resolve a StartAt to a beat, from the current position. */\n resolve(at: StartAt): Beats;\n /** Play a pattern array through a voice. */\n play<V>(pattern: readonly Step<V>[], voice: Voice<V>, opts?: PlayOptions<V>): Playback<V>;\n /** Run `fn(time)` once at a musical position \u2014 for automation, e.g. `vca.set('gain', 0, time)`. */\n at(when: StartAt | Beats, fn: (time: Seconds) => void): () => void;\n /** Global visual tap: every hit of every playback, fired when audible. Returns unsubscribe. */\n onHit(cb: (hit: Hit) => void): () => void;\n /** Schedule everything due inside the lookahead window. Auto-called in 'auto' mode. */\n tick(): void;\n dispose(): void;\n}\n\nconst EPS = 1e-9;\n\nexport function isRest(v: unknown): boolean {\n return v == null || v === false || v === 0 || v === '.' || v === '-';\n}\n\nfunction normStep<V>(s: Step<V>): StepObject<V> | null {\n if (isRest(s)) return null;\n if (typeof s === 'object' && s !== null && 'value' in (s as object)) {\n const o = s as StepObject<V>;\n return isRest(o.value) ? null : o;\n }\n return { value: s as V };\n}\n\nfunction callVoice<V>(voice: Voice<V>, hit: Hit<V>) {\n if (typeof voice === 'function') voice(hit.time, hit);\n else voice.trigger(hit.time, hit);\n}\n\ninterface Job {\n /** Next beat this job needs scheduling at. */\n nextBeat(): number;\n /** Schedule everything strictly before `until`. Returns false when finished. */\n run(until: number): boolean;\n}\n\nexport function createTransport(ctx: BaseAudioContext, opts: TransportOptions = {}): Transport {\n const beatsPerBar = opts.beatsPerBar ?? 4;\n const lookahead = opts.lookahead ?? 0.1;\n // OfflineAudioContext has a fixed `length` and no close(); realtime contexts have close().\n const offline = typeof (ctx as OfflineAudioContext).length === 'number' && typeof (ctx as AudioContext).close !== 'function';\n let bpm = opts.bpm ?? 120;\n // Tempo anchor: beat `aBeat` happens at time `aTime`; tempo is constant after it.\n let aBeat = 0;\n let aTime = 0;\n let running = false;\n /** Everything before this beat has been written. */\n let horizon = 0;\n let timer: ReturnType<typeof setInterval> | null = null;\n const jobs = new Set<Job>();\n const taps = new Set<(h: Hit) => void>();\n const tapTimers = new Set<ReturnType<typeof setTimeout>>();\n\n const spb = () => 60 / bpm;\n const beatAt = (t: number): Beats => (aBeat + (t - aTime) / spb()) as Beats;\n const timeAt = (b: number): Seconds => (aTime + (b - aBeat) * spb()) as Seconds;\n\n const current = (): number => (running ? Math.max(0, beatAt(ctx.currentTime + 0.005)) : 0);\n\n function resolve(at: StartAt): Beats {\n return resolveNum(at) as Beats;\n }\n function resolveNum(at: StartAt): number {\n const now = current();\n if (at === 'now') return now;\n if (at === 'beat') return Math.ceil(now - EPS);\n if (at === 'bar') return Math.ceil(now / beatsPerBar - EPS) * beatsPerBar;\n if ('bar' in at) return at.bar * beatsPerBar;\n return at.beat;\n }\n\n const latency = () => (ctx as AudioContext).outputLatency || (ctx as AudioContext).baseLatency || 0;\n\n function emitTap<V>(hit: Hit<V>, local?: (h: Hit<V>) => void) {\n if (!local && taps.size === 0) return;\n const fire = () => { local?.(hit); for (const cb of taps) cb(hit as Hit); };\n if (offline) { fire(); return; }\n const delay = Math.max(0, (hit.time - ctx.currentTime + latency()) * 1000);\n const id = setTimeout(() => { tapTimers.delete(id); fire(); }, delay);\n tapTimers.add(id);\n }\n\n function horizonBeat(): number {\n if (offline) return beatAt((ctx as OfflineAudioContext).length / ctx.sampleRate);\n return beatAt(ctx.currentTime + lookahead);\n }\n\n function tick() {\n if (!running) return;\n const until = horizonBeat();\n for (const job of jobs) if (!job.run(until)) jobs.delete(job);\n horizon = Math.max(horizon, until);\n }\n\n const t: Transport = {\n ctx,\n beatsPerBar,\n get bpm() { return bpm; },\n set bpm(v: number) {\n if (!(v > 0)) throw new RangeError('bpm must be > 0');\n // Re-anchor at the scheduling horizon: everything already written keeps\n // its old-tempo timing, everything after follows the new tempo.\n if (running) { const b = Math.max(horizon, beatAt(ctx.currentTime)); aTime = timeAt(b); aBeat = b; }\n bpm = v;\n },\n get running() { return running; },\n start(when = ctx.currentTime + 0.05) {\n if (running) return;\n aBeat = 0; aTime = when; horizon = 0; running = true;\n tick();\n if (!offline && opts.clock !== 'manual') timer = setInterval(tick, 25);\n },\n stop() {\n running = false;\n if (timer) clearInterval(timer);\n timer = null;\n for (const id of tapTimers) clearTimeout(id);\n tapTimers.clear();\n jobs.clear();\n },\n beatAt, timeAt, resolve,\n play<V>(pattern: readonly Step<V>[], voice: Voice<V>, o: PlayOptions<V> = {}): Playback<V> {\n const every = o.every ?? 0.25;\n const gate = o.gate ?? 0.5;\n const swing = o.swing ?? 0;\n const maxCycles = o.loop === false ? 1 : o.loop === true || o.loop === undefined ? Infinity : o.loop;\n let pat = pattern;\n let pending: readonly Step<V>[] | null = null;\n // Resolved now: when stopped, positions are relative to the coming start (beat 0).\n const startBeat: number = resolve(o.start ?? 'bar');\n let stopBeat = Infinity;\n let k = 0; // absolute step counter\n let done = false;\n\n const stepBeat = (i: number) => startBeat + i * every + (i % 2 === 1 ? swing * every * 0.5 : 0);\n\n const job: Job = {\n nextBeat: () => stepBeat(k),\n run(until) {\n while (!done) {\n if (pat.length === 0) { done = true; break; }\n const idx = k % pat.length;\n if (idx === 0 && pending) { pat = pending; pending = null; continue; }\n const cycle = Math.floor(k / pat.length);\n const b = stepBeat(k);\n if (cycle >= maxCycles || b >= stopBeat - EPS) { done = true; break; }\n if (b >= until) break;\n const s = normStep(pat[idx]);\n if (s) {\n const time = timeAt(b);\n const hit: Hit<V> = {\n time, beat: b as Beats, step: idx, cycle, value: s.value,\n velocity: s.velocity ?? 1,\n duration: ((s.length ?? gate) * every * spb()) as Seconds,\n };\n callVoice(voice, hit);\n emitTap(hit, o.onHit);\n }\n k++;\n }\n return !done;\n },\n };\n jobs.add(job);\n if (running) job.run(horizonBeat());\n return {\n set(p) { pending = p; },\n stop(at) {\n if (at) stopBeat = resolve(at);\n else { done = true; jobs.delete(job); }\n },\n get done() { return done; },\n };\n },\n at(when, fn) {\n const b: number = typeof when === 'number' ? when : resolve(when);\n let fired = false;\n const job: Job = {\n nextBeat: () => b,\n run(until) {\n if (fired) return false;\n if (b < until) { fired = true; fn(timeAt(b)); return false; }\n return true;\n },\n };\n jobs.add(job);\n if (running) tick();\n return () => { fired = true; jobs.delete(job); };\n },\n onHit(cb) { taps.add(cb); return () => { taps.delete(cb); }; },\n tick,\n dispose() { t.stop(); taps.clear(); },\n };\n return t;\n}\n\n// \u2500\u2500\u2500 Pattern helpers (all return plain arrays) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/** `steps('x... x... x..x x...')` \u2192 boolean[]. x/X = hit, anything else = rest; spaces/| ignored. */\nexport function steps(s: string): boolean[] {\n return [...s.replace(/[\\s|]/g, '')].map((c) => c === 'x' || c === 'X');\n}\n\nconst NOTE_RE = /^([A-Ga-g])([#b]?)(-?\\d+)$/;\nconst PC: Record<string, number> = { c: 0, d: 2, e: 4, f: 5, g: 7, a: 9, b: 11 };\n\n/** 'A4' \u2192 69, 'C4' \u2192 60, 'F#2' \u2192 42; a number passes through typed. Midi numbers are the pitch unit everywhere (V/Oct = semitones). */\nexport function note(name: string | number): Note {\n if (typeof name === 'number') return name as Note;\n const m = NOTE_RE.exec(name.trim());\n if (!m) throw new Error(`note(): can't parse \"${name}\"`);\n return ((parseInt(m[3], 10) + 1) * 12 + PC[m[1].toLowerCase()] + (m[2] === '#' ? 1 : m[2] === 'b' ? -1 : 0)) as Note;\n}\n\n/** `notes('C3 . E3 G3 - C4')` \u2192 (Note | null)[]. '.'/'-' = rest. */\nexport function notes(s: string): (Note | null)[] {\n return s.trim().split(/\\s+/).map((tok) => (tok === '.' || tok === '-' ? null : note(tok)));\n}\n", "/**\n * Deterministic PRNG for audio noise sources.\n *\n * Every noise buffer in the engine loops (or is a one-shot burst), so it was\n * always \"one particular random signal played back\" \u2014 the only question is\n * which one. Seeding fixes *which one* without changing the character:\n * a listener cannot tell one white-noise loop from another, but the QA\n * harness can tell a \u221239 dB render from a \u221241 dB one. Unseeded Math.random\n * made offline audits nondeterministic (doc:resonator:2 swung \u00B11.1 dB run to\n * run because its 30 ms noise burst excited the resonator's five modes with\n * different energy every render \u2014 see CHANGES-2026-08-04-probe-laws.md).\n *\n * This is also authentic hardware behaviour: sample-based drum machines play\n * the identical noise transient on every hit, and several classic noise\n * circuits are looped shift-register (LFSR) sequences \u2014 literally a fixed\n * pseudo-random loop.\n *\n * mulberry32: tiny, fast, passes gjrand; more than enough for audio noise.\n */\n\n/** Uniform [0, 1) generator from a 32-bit seed. */\nexport function mulberry32(seed: number): () => number {\n let a = seed >>> 0;\n return () => {\n a = (a + 0x6d2b79f5) | 0;\n let t = Math.imul(a ^ (a >>> 15), 1 | a);\n t = (t + Math.imul(t ^ (t >>> 7), 61 | t)) ^ t;\n return ((t ^ (t >>> 14)) >>> 0) / 4294967296;\n };\n}\n\n/** Uniform [-1, 1) generator \u2014 the audio-noise shape. */\nexport function noiseSource(seed: number): () => number {\n const rand = mulberry32(seed);\n return () => rand() * 2 - 1;\n}\n\n/**\n * Stable seeds per noise purpose. Distinct so no two sources share a\n * sequence (two modules playing the same loop would correlate and bus-sum\n * +6 dB instead of +3 dB). Values are arbitrary but committed: changing one\n * changes rendered audio and will move audit levels a fraction of a dB.\n */\nexport const NOISE_SEEDS = {\n noiseWhite: 0x9e3779b9,\n noisePink: 0x85ebca6b,\n noiseBrown: 0xc2b2ae35,\n loFiCrackle: 0x27d4eb2f,\n drumSnare: 0x165667b1,\n drumHat: 0xd3a2646c,\n d808Snare: 0xfd7046c5,\n d808ClosedHat: 0xb55a4f09,\n d808OpenHat: 0x2b2ae3c2,\n} as const;\n", "/**\n * Triggerable voices for the library. `X.create(ctx)` mirrors the module API;\n * every voice is a Voice (has `trigger(time, hit?)`) with an `output` node and\n * a Web-Audio-style `connect()`.\n *\n * Trigger decision: `trigger(time, { velocity, value, duration })`.\n * - `time` first and positional, like `AudioScheduledSourceNode.start(when)`.\n * - velocity 0..1 scales the hit's peak level (not a separate param to automate).\n * - value is pitch in midi (NoteCv) and ignored by drums.\n * Voices are copied from the app's drums module and may diverge from it.\n */\nimport { noiseSource, NOISE_SEEDS } from '@/lib/dsp/prng';\nimport type { Hit } from './transport';\nimport type { Note, Seconds, Signal } from '../units';\n\nexport interface VoiceInstance<V = unknown> {\n output: AudioNode;\n trigger(time: Seconds, hit?: Partial<Hit<V>>): void;\n connect<T extends AudioNode>(dest: T): T;\n disconnect(): void;\n}\n\nfunction voice<V>(output: GainNode, trigger: VoiceInstance<V>['trigger']): VoiceInstance<V> {\n return {\n output, trigger,\n connect: (d) => { output.connect(d); return d; },\n disconnect: () => output.disconnect(),\n };\n}\n\nfunction noiseBuffer(ctx: BaseAudioContext, seconds: number, seed: number) {\n const n = Math.floor(ctx.sampleRate * seconds);\n const buf = ctx.createBuffer(1, n, ctx.sampleRate);\n const d = buf.getChannelData(0);\n const rand = noiseSource(seed);\n for (let i = 0; i < n; i++) d[i] = rand();\n return buf;\n}\n\nconst vel = (h?: Partial<Hit>) => Math.max(0, Math.min(1, h?.velocity ?? 1));\n\nexport const Kick = {\n create(ctx: BaseAudioContext): VoiceInstance {\n const out = ctx.createGain();\n return voice(out, (when, h) => {\n const osc = ctx.createOscillator();\n const g = ctx.createGain();\n osc.frequency.setValueAtTime(150, when);\n osc.frequency.exponentialRampToValueAtTime(40, when + 0.1);\n g.gain.setValueAtTime(0.8 * vel(h) + 1e-4, when);\n g.gain.exponentialRampToValueAtTime(1e-4, when + 0.3);\n osc.connect(g).connect(out);\n osc.start(when); osc.stop(when + 0.3);\n });\n },\n};\n\nexport const Snare = {\n create(ctx: BaseAudioContext): VoiceInstance {\n const out = ctx.createGain();\n const buf = noiseBuffer(ctx, 0.15, NOISE_SEEDS.drumSnare);\n return voice(out, (when, h) => {\n const v = vel(h);\n const n = ctx.createBufferSource(); n.buffer = buf;\n const ng = ctx.createGain();\n ng.gain.setValueAtTime(0.4 * v + 1e-4, when);\n ng.gain.exponentialRampToValueAtTime(1e-4, when + 0.15);\n n.connect(ng).connect(out);\n const osc = ctx.createOscillator(); osc.type = 'triangle';\n const og = ctx.createGain();\n osc.frequency.setValueAtTime(200, when);\n osc.frequency.exponentialRampToValueAtTime(80, when + 0.05);\n og.gain.setValueAtTime(0.5 * v + 1e-4, when);\n og.gain.exponentialRampToValueAtTime(1e-4, when + 0.08);\n osc.connect(og).connect(out);\n n.start(when); osc.start(when); osc.stop(when + 0.15);\n });\n },\n};\n\nexport const Hat = {\n create(ctx: BaseAudioContext): VoiceInstance {\n const out = ctx.createGain();\n const buf = noiseBuffer(ctx, 0.05, NOISE_SEEDS.drumHat);\n return voice(out, (when, h) => {\n const n = ctx.createBufferSource(); n.buffer = buf;\n const f = ctx.createBiquadFilter(); f.type = 'highpass'; f.frequency.value = 8000;\n const g = ctx.createGain();\n g.gain.setValueAtTime(0.2 * vel(h) + 1e-4, when);\n g.gain.exponentialRampToValueAtTime(1e-4, when + 0.05);\n n.connect(f).connect(g).connect(out);\n n.start(when);\n });\n },\n};\n\n/**\n * Gate + pitch CV for driving patchable modules (Envelope trig, V/Oct inputs).\n * `gate` goes to the hit's velocity at `time`, back to 0 after `duration`;\n * `pitch` holds the note (absolute key position, 69 = A4), typed as the\n * library's pitch signal like every other V/OCT output. Both are\n * ConstantSourceNodes.\n */\nexport interface NoteCvInstance {\n /** Gate CV: the hit's velocity while a note is held, 0 otherwise. */\n gate: ConstantSourceNode;\n /** Pitch CV: the current note (69 = A4), held between notes. */\n pitch: ConstantSourceNode & Signal<Note>;\n trigger(time: Seconds, hit?: Partial<Hit<Note>>): void;\n dispose(): void;\n}\n\nexport const NoteCv = {\n create(ctx: BaseAudioContext): NoteCvInstance {\n const gate = ctx.createConstantSource(); gate.offset.value = 0; gate.start();\n const pitch = ctx.createConstantSource() as ConstantSourceNode & Signal<Note>; pitch.offset.value = 60; pitch.start();\n return {\n gate, pitch,\n trigger(time: Seconds, h?: Partial<Hit<Note>>) {\n if (typeof h?.value === 'number') pitch.offset.setValueAtTime(h.value, time);\n // Drop to 0 one sample early so back-to-back notes still produce a rising edge.\n gate.offset.setValueAtTime(0, Math.max(0, time - 1 / ctx.sampleRate));\n gate.offset.setValueAtTime(vel(h), time);\n gate.offset.setValueAtTime(0, time + (h?.duration ?? 0.1));\n },\n dispose() { gate.stop(); pitch.stop(); gate.disconnect(); pitch.disconnect(); },\n };\n },\n};\n", "/**\n * Branded unit types for the library API. Zero runtime cost: brands exist only\n * in the type system. A plain number never silently becomes a Note or Hz \u2014\n * go through a converter, or say what you mean with an `as` cast\n * (`60 as Note`, `ctx.currentTime as Seconds`). Casts are the reinterpretation\n * escape hatch: explicit and greppable.\n *\n * Dimensionless values (`factor` params: mix, feedback, drive\u2026) are plain\n * `number` \u2014 a brand there would only add noise.\n *\n * Arithmetic on brands yields `number` (TS can't know `note + 7` is still a\n * note), so re-brand results with a converter or a cast.\n */\ndeclare const unit: unique symbol;\ntype Brand<U extends string> = number & { readonly [unit]: U };\n\n/** Absolute key position, MIDI datum (69 = A4). */\nexport type Note = Brand<'note'>;\n/** Relative pitch offset (12 = one octave). Also the V/OCT signal scale. */\nexport type Semitones = Brand<'semitone'>;\n/** 1/100 semitone, relative. */\nexport type Cents = Brand<'cents'>;\n/** Cycles per second. */\nexport type Hz = Brand<'Hz'>;\n/** Audio time or duration in seconds (ctx.currentTime domain). */\nexport type Seconds = Brand<'s'>;\nexport type Milliseconds = Brand<'ms'>;\nexport type Decibels = Brand<'dB'>;\n/** Musical position or length in quarter-note beats. */\nexport type Beats = Brand<'beats'>;\n\n// \u2500\u2500\u2500 Shorthand constructors \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n// The readable way to brand a literal: `t.start(sec(0))`, `{ every: beats(0.25) }`.\n// Identity at runtime \u2014 they exist only to satisfy the type system.\n\nexport const sec = (v: number): Seconds => v as Seconds;\nexport const ms = (v: number): Milliseconds => v as Milliseconds;\nexport const beats = (v: number): Beats => v as Beats;\nexport const hz = (v: number): Hz => v as Hz;\nexport const semitones = (v: number): Semitones => v as Semitones;\nexport const cents = (v: number): Cents => v as Cents;\nexport const db = (v: number): Decibels => v as Decibels;\n\nexport const noteToHz = (n: Note): Hz => (440 * 2 ** ((n - 69) / 12)) as Hz;\nexport const hzToNote = (f: Hz): Note => (69 + 12 * Math.log2(f / 440)) as Note;\nexport const transpose = (n: Note, by: Semitones): Note => (n + by) as Note;\n/** Distance from `a` to `b`. */\nexport const interval = (a: Note, b: Note): Semitones => (b - a) as Semitones;\nexport const centsToSemitones = (c: Cents): Semitones => (c / 100) as Semitones;\nexport const msToSeconds = (ms: Milliseconds): Seconds => (ms / 1000) as Seconds;\nexport const dbToGain = (db: Decibels): number => 10 ** (db / 20);\nexport const gainToDb = (g: number): Decibels => (20 * Math.log10(g)) as Decibels;\n/** `ctx.currentTime`, typed. */\nexport const now = (ctx: BaseAudioContext): Seconds => ctx.currentTime as Seconds;\n\n// \u2500\u2500\u2500 Signals (ports) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n// One scheme for values and ports: a port is a stream of values, so a port\n// type is \"a signal carrying quantity Q\". There is no separate gate/clock/\n// modulation kind \u2014 those are all factor signals (dimensionless: \u00B11 audio,\n// 0/1 gates and clocks, unit-scaled CV). Only pitch gets a distinct brand,\n// because plugging raw CV into a V/OCT input is the one mistake that is\n// silent and musical (five octaves off, not \"no sound\").\n//\n// The pitch brand is Note, not Semitones: our V/OCT wires carry ABSOLUTE\n// key positions on the MIDI datum (69 = A4 \u2014 map-voct-to-freq converts\n// `440 * 2^((note - 69) / 12)`). Offsets (transpose, detune, LFO depth)\n// live in params as Semitones, never on a wire.\ndeclare const signal: unique symbol;\n\n/** An AudioNode whose stream carries quantity Q. `Signal<Note>` is a V/OCT\n * pitch signal (absolute key position, 69 = A4); factor signals are plain\n * `AudioNode` (no wrapper \u2014 audio, gates, clocks and CV connect freely). */\nexport type Signal<Q> = AudioNode & { readonly [signal]: Q };\n\n/** Reinterpret a node as a pitch signal \u2014 the greppable escape hatch for\n * deliberate cross-quantity patches. */\nexport const asPitch = (n: AudioNode): Signal<Note> => n as Signal<Note>;\n", "/**\n * One-shot gate pulse: a sample-accurate rising edge at `when`.\n *\n * Gate/trigger inputs (tape-stop TRIG, spring KNOCK, \u2026) act on a rising\n * edge. A panel button and a scheduled library call both fire the action by\n * pulsing that input \u2014 one path, sample-accurate, no worklet messages\n * (which arrive \"whenever\", not at a context time).\n *\n * pulse(tapeStop.trigger, ctx.currentTime + 1) // library\n *\n * The pulse sums with anything else patched into the input, so a gate held\n * high at that moment (sum already > threshold) produces no new edge \u2014\n * exactly as a second cable would behave on hardware.\n */\nconst PULSE_S = 0.001; // many samples at any rate; edge detectors fire once\n\nexport function pulse(target: AudioNode, when?: number): void {\n const ctx = target.context;\n const at = Math.max(when ?? 0, ctx.currentTime);\n const src = ctx.createConstantSource();\n src.offset.value = 1;\n src.connect(target);\n src.start(at);\n src.stop(at + PULSE_S);\n src.onended = () => src.disconnect();\n}\n", "/** Canonical percussion voice keys shared by every sample set and by any\n * module that plays percussion (DRUMS, 808, and anything added later).\n *\n * A set may omit voices; `resolveVoice` in sampleBank.ts walks a fallback\n * chain so a module never goes silent because a kit lacks, say, an open hat.\n */\nexport const VOICE_KEYS = [\n 'bd', 'sd', 'rim', 'clap', 'ch', 'oh', 'lt', 'mt', 'ht', 'cym', 'perc',\n] as const;\n\nexport type VoiceKey = (typeof VOICE_KEYS)[number];\n\nexport const VOICE_LABELS: Record<VoiceKey, string> = {\n bd: 'Bass drum',\n sd: 'Snare',\n rim: 'Rim / click',\n clap: 'Clap',\n ch: 'Closed hat',\n oh: 'Open hat',\n lt: 'Low tom',\n mt: 'Mid tom',\n ht: 'High tom',\n cym: 'Cymbal',\n perc: 'Percussion',\n};\n\n/** If a set is missing a voice, try these in order instead. */\nexport const VOICE_FALLBACKS: Record<VoiceKey, VoiceKey[]> = {\n bd: ['lt', 'mt'],\n sd: ['clap', 'rim'],\n rim: ['perc', 'ch'],\n clap: ['sd', 'perc'],\n ch: ['perc', 'rim'],\n oh: ['ch', 'cym'],\n lt: ['mt', 'bd'],\n mt: ['lt', 'ht'],\n ht: ['mt', 'lt'],\n cym: ['oh', 'ch'],\n perc: ['rim', 'ch'],\n};\n\nexport interface SampleSet {\n /** Stable id stored in patches. */\n id: string;\n name: string;\n /** One-line character description shown in the picker. */\n blurb: string;\n /** Grouping shown in the picker. */\n family: 'Machines' | 'Acoustic' | 'Digital' | 'Character' | 'Synthesised';\n credit: string;\n license: string;\n licenseUrl?: string;\n /** URL per voice. Empty for the built-in synthesis set. */\n voices: Partial<Record<VoiceKey, string>>;\n /** True for the zero-download, procedurally generated set. */\n synthesised?: boolean;\n}\n\n/** Id of the built-in (non-sampled) set. */\nexport const SYNTH_SET_ID = 'synth';\n", "/**\n * Sample kits for the library. All kits are CC0 / public domain (see AGENTS.md).\n *\n * Each kit ships inside the package as its own entry,\n * `<pkg>/kits/<id>` (generated by scripts/lib/build.ts), whose voice URLs are\n * `new URL('./<id>/<voice>.flac', import.meta.url)`. Bundlers that understand\n * that pattern (Vite 8.3+, webpack 5, Parcel) copy and hash the audio of the\n * kits a consumer imports \u2014 and only those, because an unimported kit module\n * is never read.\n *\n * import { Tr909 } from '<pkg>/kits/tr-909';\n * const kit = await loadSampleSet(ctx, Tr909);\n * const bd = SampleVoice.create(ctx, kit, 'bd');\n * transport.play(steps('x...x...'), bd);\n */\nimport { VOICE_FALLBACKS, VOICE_KEYS, type VoiceKey } from '@/lib/samples/types';\nimport type { Hit } from './time/transport';\nimport type { VoiceInstance } from './time/voices';\n\nexport { VOICE_KEYS };\nexport type { VoiceKey };\n\nexport interface SampleSetInfo {\n name: string;\n blurb: string;\n family: 'Machines' | 'Acoustic' | 'Digital' | 'Character';\n credit: string;\n license: string;\n licenseUrl: string;\n /** Audio URL per voice, fetched as-is by `loadSampleSet`. */\n voices: Partial<Record<VoiceKey, string>>;\n}\n\nexport interface LoadedSampleSet {\n set: SampleSetInfo;\n buffers: Partial<Record<VoiceKey, AudioBuffer>>;\n /** Buffer for a voice, walking the fallback chain when the kit lacks it. */\n buffer(key: VoiceKey): AudioBuffer | undefined;\n}\n\n/** Fetch + decode every voice of a kit in parallel. */\nexport async function loadSampleSet(\n ctx: BaseAudioContext,\n set: SampleSetInfo,\n opts: { fetch?: typeof fetch } = {},\n): Promise<LoadedSampleSet> {\n const f = opts.fetch ?? fetch;\n const buffers: Partial<Record<VoiceKey, AudioBuffer>> = {};\n await Promise.all(\n (Object.entries(set.voices) as [VoiceKey, string][]).map(async ([key, url]) => {\n const res = await f(url);\n if (!res.ok) throw new Error(`loadSampleSet: ${key} ${res.status}`);\n buffers[key] = await ctx.decodeAudioData(await res.arrayBuffer());\n }),\n );\n return {\n set,\n buffers,\n buffer(key) {\n return buffers[key] ?? VOICE_FALLBACKS[key].map((k) => buffers[k]).find(Boolean);\n },\n };\n}\n\n/** A one-sample voice. velocity 0..1 scales level; a number `value`\n * repitches in semitones, anything else (e.g. `true` from steps()) plays it\n * unshifted. */\nexport const SampleVoice = {\n create(ctx: BaseAudioContext, kit: LoadedSampleSet, key: VoiceKey): VoiceInstance<number | boolean> {\n const out = ctx.createGain();\n const buf = kit.buffer(key);\n const trigger = (when: number, h?: Partial<Hit<number | boolean>>) => {\n if (!buf) return;\n const src = ctx.createBufferSource();\n const g = ctx.createGain();\n src.buffer = buf;\n if (typeof h?.value === 'number') src.playbackRate.value = 2 ** (h.value / 12);\n g.gain.value = Math.max(0, Math.min(1, h?.velocity ?? 1));\n src.connect(g).connect(out);\n src.start(when);\n if (h?.duration) src.stop(when + h.duration);\n };\n return {\n output: out, trigger,\n connect: (d) => { out.connect(d); return d; },\n disconnect: () => out.disconnect(),\n };\n },\n};\n", "import type { Component } from 'solid-js';\nimport type { BaseModule, Cable, Position } from '@/types/synth';\n\n/** Self-contained example patch living next to each module.\n * Generic param M defaults to BaseModule for the descriptor interface,\n * but example files use TypedExample (= ModuleExample<SynthModule>)\n * for compile-time param checking. */\nexport interface ModuleExample<M extends BaseModule = BaseModule> {\n id: string;\n name: string;\n description: string;\n modules: M[];\n cables: Cable[];\n}\n\n/** Props passed to every module content component. */\nexport interface ModuleContentProps<T extends BaseModule = BaseModule> {\n module: T;\n updateParam: (param: string, value: number | string | boolean | number[] | boolean[][]) => void;\n cables?: Cable[];\n connectedOutputModuleId?: string | null;\n}\n\n/** Description pair used for tooltips/info bar. */\nexport interface Description {\n short: string;\n long: string;\n}\n\n/** Measurement unit of a param value \u2014 part of the signal contract, not human\n * prose, so it survives library stripping and shows up in generated docs.\n *\n * Two pitch-space units exist on purpose. They share a ruler (1 = one\n * semitone, 12 = one octave) but not a datum:\n * - `semitone` is an OFFSET from wherever the target already is (transpose,\n * detune, modulation depth).\n * - `note` is an ABSOLUTE key position on the MIDI datum (69 = A4).\n * Feeding a `note` into a `semitone` slot shifts the target by the note\n * number itself \u2014 note 60 into a \u00B112 transpose knob is five octaves. */\nexport const PARAM_UNITS = [\n 'Hz', // cycles per second\n 'ms', // milliseconds\n 's', // seconds\n 'semitone', // relative pitch offset (12 = one octave)\n 'cents', // 1/100 semitone, relative\n 'note', // absolute key position, MIDI datum (69 = A4)\n 'factor', // dimensionless multiplier: 0.5 = half wet, 5 = \u00D75 into the clipper\n 'dB', // decibels\n] as const;\n\nexport type ParamUnit = (typeof PARAM_UNITS)[number];\n\n/** Slugs whose meaning is the same in every module, pinned to one unit.\n * The param-units test fails any drift (a `note` param tagged in Hz, a\n * `frequency` param tagged in semitones, \u2026). Slugs whose meaning depends on\n * the module (`depth`, `amount`, `gain`) are deliberately absent: they only\n * have to carry *a* unit. */\nexport const UNIT_BY_SLUG = {\n frequency: 'Hz',\n time: 's',\n attack: 's',\n decay: 's',\n release: 's',\n sustain: 'factor',\n mix: 'factor',\n feedback: 'factor',\n damping: 'factor',\n tone: 'factor',\n drive: 'factor',\n note: 'note',\n detune: 'semitone',\n transpose: 'semitone',\n} as const satisfies Record<string, ParamUnit>;\n\n/** Single source of truth for one user-facing setting (plan \u00A72).\n * Knobs read range/scale/label from it, createModule defaults come from\n * `default`, hover tips derive from label+short+long, and the library build\n * generates docs + param types from it. Doc-only text (label, short,\n * long) is stripped from the library runtime; `unit` is kept. */\nexport interface ParamSpec {\n /** Optional convenience for modules whose panel maps 1:1 onto params.\n * When the UI diverges (connection-dependent labels/ranges), omit it and\n * keep labels + hover tips in the UI layer (see lfo). Never shipped in docs. */\n label?: string;\n default: number | string | boolean;\n /** One-shot actions are not params: they are rising edges on a gate port\n * (panel buttons use `pulse()` from src/lib/dsp/pulse.ts). */\n kind?: 'number' | 'enum';\n min?: number;\n max?: number;\n scale?: 'linear' | 'log' | 'sqrt';\n unit?: string;\n options?: readonly string[];\n /** Backing AudioParam, resolved like ports: key in the createNodes record\n * + AudioParam property (or worklet parameter) name. Declare ONLY when the\n * param value is written to that AudioParam 1:1 \u2014 no conversion, no split.\n * The library exposes it as `instance.params.<key>` for native automation. */\n node?: string;\n field?: string;\n short: string;\n long: string;\n}\n\n/** Default values for createModule, derived from a params schema. */\nexport function paramDefaults<P extends Record<string, ParamSpec>>(params: P): { [K in keyof P]: P[K]['default'] } {\n const out = {} as Record<string, ParamSpec['default']>;\n for (const k in params) out[k] = params[k].default;\n return out as { [K in keyof P]: P[K]['default'] };\n}\n\n/** Static port definition \u2014 constant metadata, NOT instance state. */\nexport interface PortDefinition {\n type: 'input' | 'output' | 'modulation' | 'trigger';\n label: string;\n name: string;\n desc: string;\n /** Key in the createNodes record that this port maps to.\n * Omit for trigger ports which are routed by the engine without audio nodes. */\n node?: string;\n /** For modulation ports: the AudioParam property name on the target node (e.g. 'frequency', 'gain'). */\n field?: string;\n /** Signal semantics \u2014 determines port and cable colour.\n * 'audio' = emerald, 'pitch' = amber, 'gate' = orange, 'modulation' = violet. */\n signal: 'audio' | 'pitch' | 'gate' | 'modulation';\n}\n\n/**\n * Complete descriptor for a single module type.\n *\n * Generic parameters:\n * - T: the module's state interface\n * - N: the exact record returned by createNodes (inferred by defineDescriptor)\n *\n * Ports are defined as static metadata \u2014 module instances do NOT carry ports.\n */\nexport interface ModuleDescriptor<\n T extends BaseModule = BaseModule,\n N extends Record<string, AudioNode> = Record<string, AudioNode>,\n> {\n\n // Identity\n type: T['type'];\n name: string;\n icon: string;\n color: string;\n\n // Categorisation\n categories: string[];\n\n // Layout\n width: number;\n height: number;\n\n // Static port definitions \u2014 keyed by slug (e.g. 'in', 'out', 'modFreq')\n ports: Record<string, PortDefinition>;\n\n // Factory \u2014 returns pure state (no ports array)\n createModule(id: string, position: { x: number; y: number }): T;\n\n // Audio engine \u2014 returns a port-keyed record of AudioNodes\n createNodes(ctx: AudioContext, module: T): N;\n updateParam(nodes: N, module: T, param: string, value: number | string | boolean | number[] | boolean[][], when?: number): void;\n\n // Connection hooks \u2014 called when a cable is connected/disconnected to this module's INPUT port.\n // Return true if the module handled the connection itself (engine skips default routing).\n onConnect?(nodes: N, module: T, portId: string, sourceNode: AudioNode): boolean;\n onDisconnect?(nodes: N, module: T, portId: string, sourceNode: AudioNode): boolean;\n\n // Output connection hooks \u2014 called when a cable is connected/disconnected FROM this module's OUTPUT port.\n // Allows the source module to react (e.g. clock registering downstream modules).\n onOutputConnect?(module: T, fromPortId: string, toModule: BaseModule, toPortId: string): void;\n onOutputDisconnect?(module: T, fromPortId: string, toModule: BaseModule, toPortId: string): void;\n\n // Clocked module hooks \u2014 type-safe on N and T (all optional)\n /** Called by the scheduler on each tick. portId is the destination port slug that received the tick.\n * update(key, value) writes immediately; update(key, value, when) defers until audio-playback time. */\n onTick?(ctx: AudioContext, nodes: N, module: T, when: number, update: (key: string, value: any, at?: number) => void, portId: string): void;\n /** Called on reset trigger \u2014 resets step counter to 0. */\n onReset?(module: T): void;\n /** Called when playback is stopped \u2014 clean up outputs (e.g. gate off). */\n onStop?(nodes: N, module?: T): void;\n /** Called when the module is removed \u2014 clean up timers, worklets, etc. */\n dispose?(nodes: N): void;\n\n // UI\n Content: Component<ModuleContentProps<T>>;\n\n // Example patch (loaded via right-click \"Show Example\")\n example: ModuleExample;\n\n // Documentation\n description: Description;\n /** Hover tips keyed by knob label. Derived from `params` when present. */\n controlDescriptions: Record<string, Description>;\n /** Settings schema \u2014 single source of truth for ranges, defaults, docs. */\n params?: Record<string, ParamSpec>;\n}\n\n/** Identity helper \u2013 infers both T and N from the inline descriptor. */\nexport function defineDescriptor<T extends BaseModule, N extends Record<string, AudioNode>>(\n desc: Omit<ModuleDescriptor<T, N>, 'controlDescriptions'> & { controlDescriptions?: Record<string, Description> },\n): ModuleDescriptor<T, N> {\n if (desc.params && !desc.controlDescriptions) {\n // Enum params are driven by buttons, not hoverable knobs \u2014 no hover tip.\n const cd: Record<string, Description> = {};\n for (const p of Object.values(desc.params)) {\n if (p.kind !== 'enum' && p.label) cd[p.label] = { short: p.short, long: p.long };\n }\n return { ...desc, controlDescriptions: cd };\n }\n return desc as ModuleDescriptor<T, N>;\n}\n", "/**\n * Central worklet registry.\n *\n * All AudioWorklet processors are registered once during audioEngine.initialize().\n * Module descriptors call the factory functions synchronously.\n *\n */\n\n\n/**\n * One registration promise per context.\n *\n * A `WeakMap` rather than a single slot because the QA harness renders into\n * short-lived `OfflineAudioContext`s: each one needs its own `addModule`\n * calls (processor definitions live in the context's worklet global scope),\n * and re-adding a module to a context that already has it would throw\n * \"a processor with this name is already registered\". Weak keys let the dead\n * offline contexts and their promises be collected.\n */\nconst registrations = new WeakMap<BaseAudioContext, Promise<void>>();\n\n/** Register every worklet processor. Call once per context.\n * Safe to call concurrently \u2014 subsequent calls return the same promise.\n * Accepts an `OfflineAudioContext` (patch audit) as well as a live one. */\n\n\n// \u2500\u2500\u2500 Node factories (synchronous after registration) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n// Processor names are internal IDs registered in each worklet file.\n\n// Control-signal worklets (envelopes, V/Oct mappers, followers, dividers,\n// crushers) write channel 0 only, so their output channel count is pinned to\n// [1]. Without the pin, WebAudio derives the count from the *input* \u2014 and a\n// stereo source in the trigger fan (even one merely scheduled in the\n// lookahead queue) flips the output to 2ch mid-render. Ch0-only writers then\n// deliver [x, 0] to AudioParams, which downmix to x/2: every envelope-driven\n// VCA and cutoff silently HALVED whenever the next clock tick was queued\n// (pass 12 root cause \u2014 8 Hz pluck tails measured \u22126.02 dB).\n\nexport function createVoctFreqNode(ctx: AudioContext): AudioWorkletNode {\n return new AudioWorkletNode(ctx, 'map-voct-to-freq', {\n numberOfInputs: 1,\n numberOfOutputs: 1,\n outputChannelCount: [1],\n });\n}\n\nexport function createVoctPeriodNode(ctx: AudioContext): AudioWorkletNode {\n return new AudioWorkletNode(ctx, 'map-voct-to-period', {\n numberOfInputs: 1,\n numberOfOutputs: 1,\n outputChannelCount: [1],\n });\n}\n\nexport function createAdsrNode(\n ctx: AudioContext,\n init?: { attack?: number; decay?: number; sustain?: number; release?: number },\n): AudioWorkletNode {\n const node = new AudioWorkletNode(ctx, 'adsr-envelope', {\n numberOfInputs: 1,\n numberOfOutputs: 1,\n outputChannelCount: [1],\n });\n if (init) {\n for (const [k, v] of Object.entries(init)) {\n if (v === undefined) continue;\n const p = node.parameters.get(k);\n if (p) p.value = v;\n }\n }\n return node;\n}\n\nexport function createFormantNode(ctx: AudioContext): AudioWorkletNode {\n return new AudioWorkletNode(ctx, 'formant-table', {\n numberOfInputs: 1,\n numberOfOutputs: 1,\n outputChannelCount: [5],\n });\n}\n\nexport function createBitcrusherNode(ctx: AudioContext): AudioWorkletNode {\n return new AudioWorkletNode(ctx, 'bitcrusher', {\n numberOfInputs: 1,\n numberOfOutputs: 1,\n outputChannelCount: [1],\n });\n}\n\nexport function createSubOctaveNode(ctx: AudioContext): AudioWorkletNode {\n return new AudioWorkletNode(ctx, 'freq-divider', {\n numberOfInputs: 1,\n numberOfOutputs: 1,\n outputChannelCount: [1],\n });\n}\n\nexport function createEnvFollowerNode(ctx: AudioContext): AudioWorkletNode {\n return new AudioWorkletNode(ctx, 'env-follower', {\n numberOfInputs: 1,\n numberOfOutputs: 1,\n outputChannelCount: [1],\n });\n}\n\nexport function createWaveshaperNode(ctx: AudioContext): AudioWorkletNode {\n return new AudioWorkletNode(ctx, 'waveshaper', {\n numberOfInputs: 1,\n numberOfOutputs: 1,\n outputChannelCount: [1],\n });\n}\n\nexport function createScopeNode(ctx: AudioContext): AudioWorkletNode {\n return new AudioWorkletNode(ctx, 'scope-ringbuf', {\n numberOfInputs: 1,\n numberOfOutputs: 0,\n });\n}\n\nexport function createGlideNode(ctx: AudioContext): AudioWorkletNode {\n return new AudioWorkletNode(ctx, 'glide', {\n numberOfInputs: 2,\n numberOfOutputs: 1,\n outputChannelCount: [1],\n });\n}\n\nexport function createTapeStopNode(ctx: AudioContext, time = 0.5, mix = 1): AudioWorkletNode {\n return new AudioWorkletNode(ctx, 'tape-stop', {\n numberOfInputs: 2,\n numberOfOutputs: 1,\n outputChannelCount: [2],\n channelCount: 2,\n channelCountMode: 'explicit',\n parameterData: { time, mix },\n });\n}\n\nexport function createSpringReverbNode(\n ctx: AudioContext,\n params: { decay: number; tone: number; drip: number },\n): AudioWorkletNode {\n return new AudioWorkletNode(ctx, 'spring-reverb', {\n numberOfInputs: 2,\n numberOfOutputs: 1,\n outputChannelCount: [2],\n channelCount: 2,\n channelCountMode: 'explicit',\n parameterData: { decay: params.decay, tone: params.tone, drip: params.drip },\n });\n}\n\nexport function createFdnReverbNode(\n ctx: BaseAudioContext,\n opts: { rt60: number; damping: number; size?: number; feedbackCeiling?: number },\n): AudioWorkletNode {\n return new AudioWorkletNode(ctx as AudioContext, 'fdn-reverb', {\n numberOfInputs: 1,\n numberOfOutputs: 1,\n // Stereo tank: L/R in (mono upmixes to L=R \u2192 identical mid), L/R out.\n outputChannelCount: [2],\n channelCount: 2,\n channelCountMode: 'explicit',\n parameterData: { rt60: opts.rt60, damping: opts.damping },\n processorOptions: {\n size: opts.size ?? 1,\n feedbackCeiling: opts.feedbackCeiling ?? 0.995,\n },\n });\n}\n\nexport function createFreqShifterNode(ctx: AudioContext, shift = 0): AudioWorkletNode {\n return new AudioWorkletNode(ctx, 'freq-shifter', {\n numberOfInputs: 1,\n numberOfOutputs: 1,\n outputChannelCount: [1],\n parameterData: { shift },\n });\n}\n\n/** Frequency divider with the extra raw + pitch-tracking outputs the octaver needs. */\nexport function createOctaverDividerNode(ctx: AudioContext): AudioWorkletNode {\n return new AudioWorkletNode(ctx, 'freq-divider', {\n numberOfInputs: 1,\n numberOfOutputs: 3,\n outputChannelCount: [1, 2, 1],\n });\n}\n\nexport function createPitchShifterNode(ctx: AudioContext, semitones = 12, seed = 0x9e3779b9): AudioWorkletNode {\n return new AudioWorkletNode(ctx, 'pitch-shifter', {\n numberOfInputs: 1,\n numberOfOutputs: 1,\n outputChannelCount: [1],\n channelCount: 1,\n channelCountMode: 'explicit',\n parameterData: { semitones },\n processorOptions: { seed },\n });\n}\n\nexport function createVcaNode(ctx: AudioContext, gain = 0.5, cvAmount = 1): AudioWorkletNode {\n return new AudioWorkletNode(ctx, 'vca', {\n numberOfInputs: 1,\n numberOfOutputs: 1,\n parameterData: { gain, cvAmount },\n });\n}\n\n/**\n * Master-bus brickwall limiter (engine-level, one per AudioContext).\n * Stereo-linked, 1.5 ms lookahead \u2014 see `master-limiter.ts`.\n */\nexport function createMasterLimiterNode(ctx: AudioContext): AudioWorkletNode {\n return new AudioWorkletNode(ctx, 'master-limiter', {\n numberOfInputs: 1,\n numberOfOutputs: 1,\n channelCount: 2,\n channelCountMode: 'explicit',\n channelInterpretation: 'speakers',\n outputChannelCount: [2],\n });\n}\n\n/**\n * True transistor-ladder lowpass (24 dB/oct, global tanh feedback,\n * self-oscillates at resonance \u2265 1.0). See `ladder-filter.ts`.\n * `cutoff` is driven in Hz by a map-voct-to-freq worklet output;\n * `resonance` is normalized 0\u20131 of full travel so res CV cables can\n * connect straight to the param (+1 CV = full range).\n */\nexport function createLadderFilterNode(\n ctx: AudioContext,\n init?: { resonance?: number; drive?: number },\n): AudioWorkletNode {\n return new AudioWorkletNode(ctx, 'ladder-filter', {\n numberOfInputs: 1,\n numberOfOutputs: 1,\n parameterData: {\n cutoff: 0,\n resonance: init?.resonance ?? 0.6,\n drive: init?.drive ?? 0.3,\n },\n });\n}\n\n/**\n * Resonance CV \u2192 BiquadFilter.Q mapper (true-Q domain in every filter mode;\n * LP/HP get the dB conversion the Web Audio spec expects). See `map-res.ts`.\n */\nexport function createMapResNode(\n ctx: AudioContext,\n init?: { base?: number; dbOut?: boolean; qMin?: number; qMax?: number; cvScale?: number },\n): AudioWorkletNode {\n const qMin = init?.qMin ?? 0.1;\n const qMax = init?.qMax ?? 20;\n return new AudioWorkletNode(ctx, 'map-res', {\n numberOfInputs: 1,\n numberOfOutputs: 1,\n parameterData: {\n base: init?.base ?? 1,\n cvScale: init?.cvScale ?? qMax - qMin,\n qMin,\n qMax,\n dbOut: init?.dbOut === false ? 0 : 1,\n },\n });\n}\n\n/** COMB module: recirculating comb with single-sample feedback (native\n * DelayNode loops add a render quantum and detune the comb \u2014 see the\n * worklet header). `period` is driven by map-voct-to-period. */\n/** `channels` is pinned, never derived from the input (see the pin note\n * above): COMB is a mono voice (1), DELAY keeps stereo sources stereo (2). */\nexport function createCombFilterNode(ctx: BaseAudioContext, feedback = 0.7, maxPeriod = 0.1, channels: 1 | 2 = 1): AudioWorkletNode {\n return new AudioWorkletNode(ctx as AudioContext, 'comb-filter', {\n numberOfInputs: 1,\n numberOfOutputs: 1,\n outputChannelCount: [channels],\n channelCount: channels,\n channelCountMode: 'explicit',\n channelInterpretation: 'speakers',\n parameterData: { period: 0, feedback },\n processorOptions: { maxPeriod },\n });\n}\n\n/** FLANGER wet path: LFO-swept delay with single-sample feedback (the native\n * loop hid a render quantum, detuning the regeneration comb against the\n * dry+wet notches \u2014 see the worklet header). Dry/wet mix stays native. */\nexport function createFlangerNode(\n ctx: BaseAudioContext,\n opts: { rate: number; depth: number; feedback: number },\n): AudioWorkletNode {\n return new AudioWorkletNode(ctx as AudioContext, 'flanger', {\n numberOfInputs: 1,\n numberOfOutputs: 1,\n parameterData: { rate: opts.rate, depth: opts.depth, feedback: opts.feedback },\n });\n}\n\n\n/** Tape echo: in-loop saturation + damping + wow/flutter, sample-exact grid. */\nexport function createTapeDelayNode(\n ctx: BaseAudioContext,\n opts: { time: number; feedback: number; saturation: number; flutter: number },\n): AudioWorkletNode {\n return new AudioWorkletNode(ctx as AudioContext, 'tape-delay', {\n numberOfInputs: 1,\n numberOfOutputs: 1,\n parameterData: { ...opts },\n });\n}\n\n/** Ping-pong: cross-fed L/R delay lines with exact tap grid. Output 0 = L tap, 1 = R tap. */\nexport function createPingPongNode(\n ctx: BaseAudioContext,\n opts: { time: number; feedback: number },\n): AudioWorkletNode {\n return new AudioWorkletNode(ctx as AudioContext, 'ping-pong', {\n numberOfInputs: 1,\n numberOfOutputs: 2,\n parameterData: { ...opts },\n });\n}\n", "/**\n * Keep native resonant filters ringing after their input goes quiet.\n *\n * Chrome stops processing a BiquadFilterNode once its input has been silent\n * for the filter's computed \"tail time\" \u2014 and that tail estimate is far too\n * short for narrow filters. Measured 2026-09-30 (HeadlessChrome 141, single\n * impulse into a 220 Hz bandpass): Q 113 (T60 1.14 s) was cut to exact\n * zeros at 0.35 s, Q 20 (T60 0.20 s) at 0.11 s \u2014 about \u221230 dB into the\n * ring, whatever the input level. Every way of striking a resonator with a\n * sound that then *ends* (a clock impulse, a drum sample, a gain at 0, a\n * pulled cable) chopped its tail off audibly.\n *\n * \"Silent\" is Chrome's bus flag, not the sample values: a source that\n * genuinely runs keeps the filter alive even when it is numerically\n * negligible. So each resonant module owns one ConstantSource at\n * KEEP_ALIVE_DC wired straight into its filters. 1e-12 is \u2212240 dBFS: it\n * sits ~100 dB under float32 dither, a bandpass rejects it outright (its\n * DC gain is exactly zero), and through a lowpass it is a DC offset no\n * meter or blocker downstream can see. Verified: with it connected the same\n * Q 113 impulse rings its full theoretical T60 (the `probe:t60-reso-*`\n * laws measure exactly this).\n */\n\n/** \u2212240 dBFS: numerically inaudible, but enough to mark the bus non-silent. */\nexport const KEEP_ALIVE_DC = 1e-12;\n\n/**\n * Start a keep-alive source wired into every target filter. Call `.stop()`\n * on the returned node in the module's `dispose`.\n */\nexport function createKeepAlive(ctx: BaseAudioContext, ...targets: AudioNode[]): ConstantSourceNode {\n const src = ctx.createConstantSource();\n src.offset.value = KEEP_ALIVE_DC;\n for (const t of targets) src.connect(t);\n src.start();\n return src;\n}\n", "// @ts-nocheck \u2014 generated by scripts/lib/build.ts\nimport type { BaseModule, Position } from '@/types/synth';\n\nimport { defineDescriptor, paramDefaults } from '@/modules/ModuleDescriptor';\nimport { createAdsrNode, createVoctFreqNode } from '@/worklets';\nimport { createKeepAlive } from '@/lib/dsp/keepAlive';\n\nexport interface Filter303Module extends BaseModule {\n type: '303-filter';\n /** Cutoff as a note (69 = 440 Hz), driving the V/OCT worklet 1:1. */\n note: number;\n resonance: number;\n envMod: number;\n accent: number;\n decay: number;\n}\n\n// \u2500\u2500\u2500 PARAMS \u2014 the signal contract (no UI knowledge) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nconst params = {\n note: { node: '_cutoffVoct', field: 'transpose', unit: 'note', default: 67, min: 15, max: 135, },\n // Split across two cascaded biquads' Q (0.7x / 0.4x) \u2014 not a single\n // AudioParam \u2014 so this stays set-only.\n resonance: { unit: 'factor', default: 8, min: 0, max: 15, scale: 'sqrt', },\n envMod: { unit: 'factor', default: 0.7, min: 0, max: 1, },\n accent: { unit: 'factor', default: 0.5, min: 0, max: 1, },\n decay: { node: 'envSmoother', field: 'decay', unit: 's', default: 0.2, min: 0.05, max: 1, scale: 'log', },\n} satisfies Record<string, ParamSpec>;\n\n// \u2500\u2500\u2500 UI \u2014 presentation layer (stripped from the library) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n\n// \u2500\u2500\u2500 DESCRIPTOR \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport const filter303Descriptor = /* @__PURE__ */ defineDescriptor({\n type: '303-filter',\n params,\n\n ports: {\n 'in': { type: 'input', signal: 'audio', node: 'input', },\n 'out': { type: 'output', signal: 'audio', node: 'output', },\n 'trigger': { type: 'input', signal: 'gate', node: 'trigInput', },\n 'modFreq': { type: 'modulation', signal: 'modulation', node: '_cutoffVoct', },\n },\n\n createModule(id: string, position: Position): Filter303Module {\n return { id, type: '303-filter', position, ...paramDefaults(params) };\n },\n\n createNodes(ctx, module) {\n const input = ctx.createGain();\n\n // Two cascaded lowpass filters for 4-pole (24dB/oct) response\n const filter1 = ctx.createBiquadFilter();\n filter1.type = 'lowpass';\n filter1.frequency.value = 0; // driven by voct\n filter1.Q.value = module.resonance * 0.7; // split Q across stages\n const filter2 = ctx.createBiquadFilter();\n filter2.type = 'lowpass';\n filter2.frequency.value = 0;\n filter2.Q.value = module.resonance * 0.4;\n\n // Accent VCA \u2014 boosts output level on accented notes\n const accentVCA = ctx.createGain();\n accentVCA.gain.value = 1;\n const output = ctx.createGain();\n\n // V/Oct cutoff\n const _cutoffVoct = createVoctFreqNode(ctx);\n _cutoffVoct.parameters.get('transpose')!.value = module.note;\n\n const _cutoffBase = ctx.createConstantSource();\n _cutoffBase.offset.value = 0;\n _cutoffBase.start();\n\n _cutoffBase.connect(_cutoffVoct);\n _cutoffVoct.connect(filter1.frequency);\n _cutoffVoct.connect(filter2.frequency);\n\n // Trigger envelope \u2192 voct input (semitones).\n //\n // The TB-303's envelope is a snappy attack into an exponential decay with\n // no sustain stage. Clock and sequencer gate outputs are single-sample\n // impulses, so this runs the shared ADSR worklet, which latches a rising\n // edge for one full attack + decay \u2014 a smoothing filter fed by a lone\n // sample would only ever produce a few thousandths of an envelope.\n const trigInput = ctx.createGain();\n\n const envSmoother = createAdsrNode(ctx, {\n attack: 0.003,\n decay: module.decay,\n sustain: 0,\n release: 0.01,\n });\n\n // Envelope depth in semitones: envMod * (1 + accent) * 36\n const envDepth = ctx.createGain();\n envDepth.gain.value = module.envMod * (1 + module.accent) * 36;\n\n // Accent envelope \u2192 VCA boost (adds ~6dB on full accent)\n const accentEnvGain = ctx.createGain();\n accentEnvGain.gain.value = module.accent * 0.5;\n\n input.connect(filter1);\n filter1.connect(filter2);\n filter2.connect(accentVCA);\n accentVCA.connect(output);\n\n trigInput.connect(envSmoother);\n envSmoother.connect(envDepth);\n envDepth.connect(_cutoffVoct); // semitones \u2192 voct input\n\n // Route envelope to accent VCA too\n envSmoother.connect(accentEnvGain);\n accentEnvGain.connect(accentVCA.gain);\n\n // Chrome cuts silent-input biquad rings early \u2014 see dsp/keepAlive.ts.\n const _alive = createKeepAlive(ctx, filter1);\n\n return { input, output, trigInput, filter1, filter2, accentVCA, accentEnvGain, envSmoother, envDepth, _cutoffVoct, _cutoffBase, _alive };\n },\n\n updateParam(nodes, module, param, value) {\n switch (param) {\n case 'note':\n nodes._cutoffVoct.parameters.get('transpose')!.value = value as number;\n break;\n case 'resonance': {\n const q = value as number;\n nodes.filter1.Q.value = q * 0.7;\n nodes.filter2.Q.value = q * 0.4;\n break;\n }\n case 'envMod':\n nodes.envDepth.gain.value = (value as number) * (1 + module.accent) * 36;\n break;\n case 'accent': {\n const acc = value as number;\n nodes.envDepth.gain.value = module.envMod * (1 + acc) * 36;\n nodes.accentEnvGain.gain.value = acc * 0.5;\n break;\n }\n case 'decay': {\n const p = nodes.envSmoother.parameters.get('decay');\n if (p) p.value = value as number;\n break;\n }\n }\n },\n\n dispose(nodes) {\n nodes._cutoffBase.stop();\n nodes._alive.stop();\n },\n\n});\n", "import { defineModule } from '../../core';\nimport { filter303Descriptor } from './303-filter';\nimport type { AcidFilterParams, AcidFilterInputs, AcidFilterOutputs, AcidFilterProps } from './303-filter.types';\nimport adsr_envelope from '../worklet-src/adsr-envelope';\nimport map_voct_to_freq from '../worklet-src/map-voct-to-freq';\n\nexport const AcidFilter = /* @__PURE__ */ defineModule(filter303Descriptor, {\n worklets: {\n 'adsr-envelope': adsr_envelope,\n 'map-voct-to-freq': map_voct_to_freq,\n },\n}) as import('../../core').LibModule<AcidFilterParams, AcidFilterInputs, AcidFilterOutputs, AcidFilterProps>;\nexport type { AcidFilterParams, AcidFilterInputs, AcidFilterOutputs, AcidFilterProps };\n", "// @ts-nocheck \u2014 generated by scripts/lib/build.ts\n\nimport { BaseModule } from '@/types/synth';\n\nexport interface AutoPanModule extends BaseModule {\n type: 'auto-pan';\n rate: number;\n depth: number;\n shape: 'sine' | 'triangle' | 'square';\n}\nimport { defineDescriptor, paramDefaults } from '@/modules/ModuleDescriptor';\n\nconst shapes = ['sine', 'triangle', 'square'] as const;\n\n// \u2500\u2500\u2500 PARAMS \u2014 the signal contract (no UI knowledge) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nconst params = {\n rate: { node: 'lfo', field: 'frequency', unit: 'Hz', default: 2, min: 0.1, max: 10, },\n depth: { node: 'lfoGain', field: 'gain', unit: 'factor', default: 0.8, min: 0, max: 1, },\n shape: { kind: 'enum', options: shapes, default: 'sine', },\n} satisfies Record<string, ParamSpec>;\n\n// \u2500\u2500\u2500 UI \u2014 presentation layer (stripped from the library) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n\nexport const autoPanDescriptor = /* @__PURE__ */ defineDescriptor({\n type: 'auto-pan',\n params,\n\n ports: {\n 'in': { type: 'input', signal: 'audio', node: 'input', },\n 'out': { type: 'output', signal: 'audio', node: 'output', },\n 'modRate': { type: 'modulation', signal: 'modulation', node: 'lfo', field: 'frequency' },\n 'modDepth': { type: 'modulation', signal: 'modulation', node: 'lfoGain', field: 'gain' },\n },\n\n createModule(id, position) {\n return { id, type: 'auto-pan', position, ...paramDefaults(params) };\n },\n\n createNodes(ctx, module) {\n const input = ctx.createGain();\n const panner = ctx.createStereoPanner();\n const output = ctx.createGain();\n const lfo = ctx.createOscillator();\n const lfoGain = ctx.createGain();\n\n lfo.type = module.shape as OscillatorType;\n lfo.frequency.value = module.rate;\n lfoGain.gain.value = module.depth;\n lfo.connect(lfoGain);\n lfoGain.connect(panner.pan);\n lfo.start();\n\n input.connect(panner);\n panner.connect(output);\n\n return { input, output, lfo, lfoGain };\n },\n\n updateParam(nodes, _m, param, value) {\n if (param === 'rate') {\n nodes.lfo.frequency.value = value as number;\n } else if (param === 'depth') {\n nodes.lfoGain.gain.value = value as number;\n } else if (param === 'shape') {\n nodes.lfo.type = value as OscillatorType;\n }\n },\n\n dispose(nodes) {\n nodes.lfo.stop();\n },\n\n});\n", "import { defineModule } from '../../core';\nimport { autoPanDescriptor } from './auto-pan';\nimport type { AutoPanParams, AutoPanInputs, AutoPanOutputs, AutoPanProps } from './auto-pan.types';\n\n\nexport const AutoPan = /* @__PURE__ */ defineModule(autoPanDescriptor) as import('../../core').LibModule<AutoPanParams, AutoPanInputs, AutoPanOutputs, AutoPanProps>;\nexport type { AutoPanParams, AutoPanInputs, AutoPanOutputs, AutoPanProps };\n", "/**\n * Dry/wet mix as ONE AudioParam.\n *\n * A single ConstantSource carries the mix value (0 = dry, 1 = wet); native\n * nodes derive both gains from it at audio rate, so `mix` is automatable and\n * CV-modulatable like any native parameter, and stays exact under ramps.\n *\n * linear dry = 1 \u2212 mix, wet = mix \u00B7 wetScale\n * equal-power dry = cos(mix\u00B7\u03C0/2), wet = sin(mix\u00B7\u03C0/2) \u00B7 wetScale\n *\n * The returned ConstantSource is the node to register in createNodes\n * (conventionally `_mix`, param spec `{ node: '_mix', field: 'offset' }`);\n * hosts stop it on dispose like any other source.\n */\nexport type MixLaw = 'linear' | 'equal-power';\n\nconst CURVE_POINTS = 2049; // spans input \u22121\u20261; 1024 intervals over 0\u20261\n\nfunction lawCurve(fn: (m: number) => number): Float32Array<ArrayBuffer> {\n const c = new Float32Array(CURVE_POINTS);\n for (let i = 0; i < CURVE_POINTS; i++) {\n const x = -1 + (2 * i) / (CURVE_POINTS - 1);\n c[i] = fn(Math.min(1, Math.max(0, x)));\n }\n return c;\n}\n\nexport function createMix(\n ctx: BaseAudioContext,\n dry: GainNode,\n wet: GainNode,\n value: number,\n law: MixLaw,\n wetScale = 1,\n): ConstantSourceNode {\n const mix = ctx.createConstantSource();\n mix.offset.value = value;\n\n let toWet: AudioNode = mix;\n if (law === 'linear') {\n dry.gain.value = 1;\n const invert = ctx.createGain();\n invert.gain.value = -1;\n mix.connect(invert).connect(dry.gain);\n } else {\n dry.gain.value = 0;\n const cos = ctx.createWaveShaper();\n cos.curve = lawCurve((m) => Math.cos(m * 0.5 * Math.PI));\n const sin = ctx.createWaveShaper();\n sin.curve = lawCurve((m) => Math.sin(m * 0.5 * Math.PI));\n mix.connect(cos).connect(dry.gain);\n toWet = mix.connect(sin);\n }\n\n wet.gain.value = 0;\n if (wetScale !== 1) {\n const scale = ctx.createGain();\n scale.gain.value = wetScale;\n toWet = toWet.connect(scale);\n }\n toWet.connect(wet.gain);\n\n mix.start();\n return mix;\n}\n", "// @ts-nocheck \u2014 generated by scripts/lib/build.ts\nimport { createMix } from '@/lib/dsp/mix';\nimport { BaseModule } from '@/types/synth';\nimport { defineDescriptor, paramDefaults } from '@/modules/ModuleDescriptor';\nimport { createBitcrusherNode } from '@/worklets';\n\nexport interface BitcrusherModule extends BaseModule {\n type: 'bitcrusher';\n bits: number;\n rate: number;\n mix: number;\n}\n\n// \u2500\u2500\u2500 PARAMS \u2014 the signal contract (no UI knowledge) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nconst params = {\n bits: { node: 'crusher', field: 'bits', unit: 'factor', default: 8, min: 1, max: 16, },\n rate: { node: 'crusher', field: 'rate', unit: 'factor', default: 0.5, min: 0.01, max: 1, scale: 'log', },\n mix: { node: '_mix', field: 'offset', unit: 'factor', default: 1.0, min: 0, max: 1, },\n} satisfies Record<string, ParamSpec>;\n\n\n\n// \u2500\u2500\u2500 DESCRIPTOR \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport const bitcrusherDescriptor = /* @__PURE__ */ defineDescriptor({\n type: 'bitcrusher',\n params,\n\n\n ports: {\n 'in': { type: 'input', signal: 'audio', node: 'input', },\n 'out': { type: 'output', signal: 'audio', node: 'output', },\n },\n\n\n createModule(id, position) {\n return { id, type: 'bitcrusher', position, ...paramDefaults(params) };\n },\n\n createNodes(ctx, module) {\n const input = ctx.createGain();\n const output = ctx.createGain();\n const dryGain = ctx.createGain();\n const wetGain = ctx.createGain();\n\n const crusher = createBitcrusherNode(ctx);\n const cp = crusher.parameters as any;\n cp.get('bits').value = module.bits;\n cp.get('rate').value = module.rate;\n\n const _mix = createMix(ctx, dryGain, wetGain, module.mix, 'linear');\n\n input.connect(dryGain);\n input.connect(crusher);\n crusher.connect(wetGain);\n dryGain.connect(output);\n wetGain.connect(output);\n\n return { input, output, crusher, dryGain, wetGain, _mix };\n },\n\n updateParam(nodes, _m, param, value) {\n if (param === 'bits') {\n (nodes.crusher.parameters as any).get('bits').value = value as number;\n } else if (param === 'rate') {\n (nodes.crusher.parameters as any).get('rate').value = value as number;\n } else if (param === 'mix') {\n (nodes._mix as ConstantSourceNode).offset.value = value as number;\n }\n },\n\n});\n", "import { defineModule } from '../../core';\nimport { bitcrusherDescriptor } from './bitcrusher';\nimport type { BitcrusherParams, BitcrusherInputs, BitcrusherOutputs, BitcrusherProps } from './bitcrusher.types';\nimport bitcrusher from '../worklet-src/bitcrusher';\n\nexport const Bitcrusher = /* @__PURE__ */ defineModule(bitcrusherDescriptor, {\n worklets: {\n 'bitcrusher': bitcrusher,\n },\n}) as import('../../core').LibModule<BitcrusherParams, BitcrusherInputs, BitcrusherOutputs, BitcrusherProps>;\nexport type { BitcrusherParams, BitcrusherInputs, BitcrusherOutputs, BitcrusherProps };\n", "// @ts-nocheck \u2014 generated by scripts/lib/build.ts\nimport { BaseModule } from '@/types/synth';\n\nexport interface ChorusModule extends BaseModule {\n type: 'chorus';\n rate: number;\n depth: number;\n mix: number;\n}\nimport { defineDescriptor, paramDefaults } from '@/modules/ModuleDescriptor';\n\nconst params = {\n rate: { node: 'lfo', field: 'frequency', unit: 'Hz', default: 1.5, min: 0.1, max: 5, },\n depth: { unit: 'factor', default: 0.5, min: 0, max: 1, },\n mix: { node: '_mix', field: 'offset', unit: 'factor', default: 0.5, min: 0, max: 1, },\n} satisfies Record<string, ParamSpec>;\n\n\n\nexport const chorusDescriptor = /* @__PURE__ */ defineDescriptor({\n type: 'chorus',\n params,\n\n ports: {\n 'in': { type: 'input', signal: 'audio', node: 'input', },\n 'out': { type: 'output', signal: 'audio', node: 'output', },\n 'modRate': { type: 'modulation', signal: 'modulation', node: 'lfo', field: 'frequency' },\n 'modMix': { type: 'modulation', signal: 'modulation', node: '_mix', field: 'offset' },\n },\n\n createModule(id, position) {\n return { id, type: 'chorus', position, ...paramDefaults(params) };\n },\n\n createNodes(ctx, module) {\n const input = ctx.createGain();\n const output = ctx.createGain();\n const dryGain = ctx.createGain();\n const wetGain = ctx.createGain();\n const monoIn = ctx.createGain();\n monoIn.channelCount = 1;\n monoIn.channelCountMode = 'explicit';\n monoIn.channelInterpretation = 'speakers';\n const delayL = ctx.createDelay(0.1);\n const delayR = ctx.createDelay(0.1);\n const lfo = ctx.createOscillator();\n const lfoGain = ctx.createGain();\n const lfoInv = ctx.createGain();\n const merger = ctx.createChannelMerger(2);\n delayL.delayTime.value = 0.02;\n delayR.delayTime.value = 0.02;\n\n // Mix as one honest AudioParam: this module's law (dry = 1 \u2212 mix\u00B70.5,\n // wet = mix) isn't either law createMix ships, so it's built the same\n // way createMix does internally \u2014 one ConstantSource whose offset IS\n // the mix param, intrinsic dry gain of 1 with a \u22120.5 tap from the\n // source, wet gain 0 with a direct tap \u2014 rather than forcing a\n // different loudness curve onto the module.\n const _mix = ctx.createConstantSource();\n _mix.offset.value = module.mix;\n dryGain.gain.value = 1;\n const dryTap = ctx.createGain();\n dryTap.gain.value = -0.5;\n _mix.connect(dryTap).connect(dryGain.gain);\n wetGain.gain.value = 0;\n _mix.connect(wetGain.gain);\n _mix.start();\n\n lfo.type = 'sine';\n lfo.frequency.value = module.rate;\n lfoGain.gain.value = module.depth * 0.01;\n lfoInv.gain.value = -1;\n lfo.connect(lfoGain);\n lfoGain.connect(delayL.delayTime);\n lfoGain.connect(lfoInv);\n lfoInv.connect(delayR.delayTime);\n lfo.start();\n input.connect(dryGain);\n input.connect(monoIn);\n monoIn.connect(delayL);\n monoIn.connect(delayR);\n delayL.connect(merger, 0, 0);\n delayR.connect(merger, 0, 1);\n merger.connect(wetGain);\n dryGain.connect(output);\n wetGain.connect(output);\n return { input, output, lfo, lfoGain, lfoInv, dryGain, wetGain, monoIn, delayL, delayR, merger, _mix };\n },\n\n updateParam(nodes, _m, param, value) {\n switch (param) {\n case 'rate': nodes.lfo.frequency.value = value as number; break;\n case 'depth': nodes.lfoGain.gain.value = (value as number) * 0.01; break;\n case 'mix': (nodes._mix as ConstantSourceNode).offset.value = value as number; break;\n }\n },\n\n dispose(nodes) {\n nodes.lfo.stop();\n (nodes._mix as ConstantSourceNode).stop();\n },\n\n});\n", "import { defineModule } from '../../core';\nimport { chorusDescriptor } from './chorus';\nimport type { ChorusParams, ChorusInputs, ChorusOutputs, ChorusProps } from './chorus.types';\n\n\nexport const Chorus = /* @__PURE__ */ defineModule(chorusDescriptor) as import('../../core').LibModule<ChorusParams, ChorusInputs, ChorusOutputs, ChorusProps>;\nexport type { ChorusParams, ChorusInputs, ChorusOutputs, ChorusProps };\n", "import type { ExposedPort, MacroKnob } from './macro';\n\n// \u2500\u2500\u2500 Shared value types \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport type DistortionType = 'soft' | 'hard' | 'fuzz';\nexport type WaveformType = 'sine' | 'square' | 'sawtooth' | 'triangle';\nexport type FilterType = 'lowpass' | 'highpass' | 'bandpass' | 'notch';\nexport type NoiseType = 'white' | 'pink' | 'brown';\n\n// \u2500\u2500\u2500 Core types \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport interface Position {\n x: number;\n y: number;\n}\n\n/**\n * Runtime port \u2014 derived from the descriptor at render time.\n * NOT stored on module instances.\n */\nexport interface Port {\n id: string; // Composite key: 'moduleId:portSlug'\n moduleId: string;\n portId: string; // Slug only: 'in', 'out', 'voct', 'modFreq'\n type: 'input' | 'output' | 'modulation' | 'trigger';\n label: string;\n signal: 'audio' | 'pitch' | 'gate' | 'modulation';\n}\n\n/**\n * Cable connecting two ports.\n * Uses compact 'moduleId:portSlug' format for both ends.\n * Identity is implicit: the composite 'from>to' is unique.\n * The legacy `id` field is kept optional for backward compatibility with\n * saved patches and preset data \u2014 it is never read at runtime.\n */\nexport interface Cable {\n id?: string; // legacy, ignored \u2014 kept for compat\n from: string; // 'moduleId:portSlug'\n to: string; // 'moduleId:portSlug'\n}\n\n/** Derive a unique key for a cable from its endpoints. */\nexport function cableId(c: Cable): string {\n return `${c.from}>${c.to}`;\n}\n\n/** Parse a cable endpoint string into moduleId and portId. */\nexport function parseCableEnd(end: string): { moduleId: string; portId: string } {\n const i = end.lastIndexOf(':');\n return { moduleId: end.slice(0, i), portId: end.slice(i + 1) };\n}\n\n/** Create a cable endpoint string from moduleId and portId. */\nexport function cableEnd(moduleId: string, portId: string): string {\n return `${moduleId}:${portId}`;\n}\n\n/**\n * Base module \u2014 pure state (params + position). No ports array.\n * Ports are derived from the descriptor at render time.\n */\nexport interface BaseModule {\n id: string;\n type: string;\n position: Position;\n}\n\n// \u2500\u2500\u2500 Macro (no descriptor file yet) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport interface MacroModule extends BaseModule {\n type: 'macro';\n macroId: string;\n macroName: string;\n macroIcon: string;\n knobValues: Record<string, number>;\n customKnobs: MacroKnob[];\n}\n\n// \u2500\u2500\u2500 ModuleType & SynthModule (derived from registered descriptors) \u2500\u2500\n\nexport type { ModuleType, SynthModule } from '@/modules';\n\n// \u2500\u2500\u2500 Re-exports from module descriptors \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n// Each module defines its own interface; we re-export here for backward compat.\n\nexport type { OscillatorModule } from '@/modules/vco';\nexport type { FilterModule } from '@/modules/vcf';\nexport type { GainModule } from '@/modules/vca';\nexport type { LFOModule } from '@/modules/lfo';\nexport type { DelayModule } from '@/modules/delay';\nexport type { ReverbModule } from '@/modules/reverb';\nexport type { OutputModule } from '@/modules/output';\nexport type { KeyboardModule } from '@/modules/keyboard';\nexport type { EnvelopeModule } from '@/modules/envelope';\nexport type { SequencerModule } from '@/modules/sequencer';\nexport type { NoiseModule } from '@/modules/noise';\nexport type { MixerModule } from '@/modules/mixer';\nexport type { ScopeModule } from '@/modules/scope';\nexport type { DistortionModule } from '@/modules/distortion';\nexport type { CompressorModule } from '@/modules/comp';\nexport type { DrumsModule } from '@/modules/drums';\nexport type { LadderFilterModule } from '@/modules/ladder-filter';\nexport type { Filter303Module } from '@/modules/303-filter';\nexport type { Drums808Module } from '@/modules/808-drums';\nexport type { TapeDelayModule } from '@/modules/tape-delay';\nexport type { SpringReverbModule } from '@/modules/spring-reverb';\nexport type { PhaserModule } from '@/modules/phaser';\nexport type { ChorusModule } from '@/modules/chorus';\nexport type { BitcrusherModule } from '@/modules/bitcrusher';\nexport type { RingModModule } from '@/modules/ring-mod';\nexport type { WavefolderModule } from '@/modules/wavefolder';\nexport type { FlangerModule } from '@/modules/flanger';\nexport type { TremoloModule } from '@/modules/tremolo';\nexport type { EQ3Module } from '@/modules/eq3';\nexport type { FreqShifterModule } from '@/modules/freq-shifter';\nexport type { SaturatorModule } from '@/modules/saturator';\nexport type { CombFilterModule } from '@/modules/comb-filter';\nexport type { AutoPanModule } from '@/modules/auto-pan';\nexport type { LoFiModule } from '@/modules/lo-fi';\nexport type { WahModule } from '@/modules/wah';\nexport type { DimensionModule } from '@/modules/dimension';\nexport type { FormantModule } from '@/modules/formant';\nexport type { RotaryModule } from '@/modules/rotary';\nexport type { ExciterModule } from '@/modules/exciter';\nexport type { StereoSpreadModule } from '@/modules/stereo-spread';\nexport type { DuckerModule } from '@/modules/ducker';\nexport type { SubHarmModule } from '@/modules/sub-harm';\nexport type { MidSideModule } from '@/modules/mid-side';\nexport type { SoftLimitModule } from '@/modules/soft-limit';\nexport type { TapeStopModule } from '@/modules/tape-stop';\nexport type { TiltEQModule } from '@/modules/tilt';\nexport type { PingPongModule } from '@/modules/ping-pong';\nexport type { GateModule } from '@/modules/gate';\nexport type { ResonatorModule } from '@/modules/resonator';\nexport type { HaasModule } from '@/modules/haas';\nexport type { CrossfadeModule } from '@/modules/crossfade';\nexport type { ShimmerModule } from '@/modules/shimmer';\nexport type { HarmonicTremModule } from '@/modules/harmonic-trem';\nexport type { OctaverModule } from '@/modules/octaver';\nexport type { EnvFollowModule } from '@/modules/env-follow';\nexport type { GlideModule } from '@/modules/glide';\nexport type { FracClockModule } from '@/modules/frac-clock';\n\n// \u2500\u2500\u2500 Constants & helpers \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n/** Map a signal semantic to a cable hex colour.\n * Audio = emerald, pitch = amber, gate = orange,\n * modulation = violet. */\nexport function signalColor(signal: Port['signal']): string {\n switch (signal) {\n case 'audio': return '#10b981'; // emerald\n case 'pitch': return '#eab308'; // amber\n case 'gate': return '#f97316'; // orange\n case 'modulation': return '#8b5cf6'; // violet\n default: return '#94a3b8'; // slate\n }\n}\n\nexport const NOTE_FREQUENCIES: Record<string, number> = {\n 'C': 261.63, 'C#': 277.18, 'D': 293.66, 'D#': 311.13,\n 'E': 329.63, 'F': 349.23, 'F#': 369.99, 'G': 392.00,\n 'G#': 415.30, 'A': 440.00, 'A#': 466.16, 'B': 493.88,\n};\n\n/** Convert Hz to MIDI note number: 12 * log2(hz / 440) + 69 */\nexport function hzToMidi(hz: number): number {\n return 12 * Math.log2(hz / 440) + 69;\n}\n\n/** Convert MIDI note number to Hz: 440 * 2^((note - 69) / 12) */\nexport function midiToHz(note: number): number {\n return 440 * Math.pow(2, (note - 69) / 12);\n}\n", "// @ts-nocheck \u2014 generated by scripts/lib/build.ts\nimport { createMix } from '@/lib/dsp/mix';\nimport { BaseModule } from '@/types/synth';\nimport { hzToMidi } from '@/types/synth';\nimport { defineDescriptor, paramDefaults } from '@/modules/ModuleDescriptor';\nimport { createVoctPeriodNode, createCombFilterNode } from '@/worklets';\n\n// \u2500\u2500\u2500 PARAMS (single source of truth: knobs, defaults, hover tips, docs) \u2500\u2500\n// Pitch is plain V/OCT arithmetic, same as the VCO: the comb's note is the\n// V/OCT input (absolute notes, silence = 0) plus `offset` semitones \u2014 no\n// normalling. The app panel keeps `frequency` (unpatched) and `transpose`\n// (patched) as separate memories and writes whichever applies into offset.\nconst params = {\n offset: { node: '_freqVoct', field: 'transpose', default: 55, min: -48, max: 96, unit: 'semitone', },\n feedback: { node: 'comb', field: 'feedback', unit: 'factor', default: 0.7, min: 0, max: 0.95, },\n mix: { node: '_mix', field: 'offset', unit: 'factor', default: 0.5, min: 0, max: 1, },\n tuning: { kind: 'enum' as const, options: ['chromatic', 'free'], default: 'chromatic', },\n} as const satisfies Record<string, ParamSpec>;\n\nexport interface CombFilterModule extends BaseModule {\n type: 'comb-filter';\n frequency: number; // panel memory: Hz (50\u20132000) while V/OCT is unpatched\n transpose?: number; // panel memory: semitone shift while V/OCT is patched\n offset?: number; // library-only DSP state (see params.offset); the app derives it\n feedback: number;\n mix: number;\n tuning?: 'chromatic' | 'free';\n}\n\nconst TUNING_OPTIONS = [\n { value: 'chromatic' as const, label: 'CHROMATIC' },\n { value: 'free' as const, label: 'FREE' },\n];\n\n// MIDI range matching Hz 50\u20132000\nconst MIN_MIDI = /* @__PURE__ */ hzToMidi(50); // ~33.5\nconst MAX_MIDI = /* @__PURE__ */ hzToMidi(2000); // ~95.5\n\n/** Cables currently on V/OCT, per node set \u2014 picks the live panel memory. */\nconst patchCount = new WeakMap<object, number>();\n\n\nexport const combFilterDescriptor = /* @__PURE__ */ defineDescriptor({\n type: 'comb-filter',\n params,\n // Panel controls diverge from params (the ribbon edits two memories that\n // feed `offset`), so they are listed here, not derived from labels.\n\n ports: {\n 'in': { type: 'input', signal: 'audio', node: 'input', },\n 'out': { type: 'output', signal: 'audio', node: 'output', },\n 'voct': { type: 'input', signal: 'pitch', node: '_freqVoct', },\n 'modFreq': { type: 'modulation', signal: 'modulation', node: '_freqVoct', },\n },\n\n\n createModule(id, position): CombFilterModule {\n const { offset: _dsp, ...rest } = paramDefaults(params);\n return { id, type: 'comb-filter' as const, position, ...rest, frequency: 200, transpose: 0 };\n },\n\n createNodes(ctx, module) {\n const input = ctx.createGain();\n const output = ctx.createGain();\n const dryGain = ctx.createGain();\n const wetGain = ctx.createGain();\n\n // Worklet comb: true single-sample feedback. The previous native\n // DelayNode\u2192GainNode loop carried a hidden render quantum (128/sr) per\n // cycle, so the comb resonated at 1/(period + 2.9ms) \u2014 a comb \"tuned\"\n // to 440 Hz actually rang at ~193 Hz. See src/worklets/comb-filter.ts.\n const comb = createCombFilterNode(ctx, module.feedback);\n\n // V/Oct \u2192 period: summed V/OCT input + offset (worklet `transpose`) \u2192\n // map-voct-to-period \u2192 comb's `period` param. V/OCT lines carry absolute\n // notes, so a patched comb wants offset \u2248 0 (the transpose memory) and an\n // unpatched one wants the absolute note (hzToMidi of the frequency memory).\n const _freqVoct = createVoctPeriodNode(ctx);\n _freqVoct.parameters.get('transpose')!.value = module.offset ?? hzToMidi(module.frequency);\n\n const periodParam = comb.parameters.get('period')!;\n periodParam.value = 0; // driven exclusively by map-voct-to-period worklet\n _freqVoct.connect(periodParam);\n\n const _mix = createMix(ctx, dryGain, wetGain, module.mix, 'linear');\n\n input.connect(dryGain);\n input.connect(comb);\n comb.connect(wetGain);\n dryGain.connect(output);\n wetGain.connect(output);\n\n return { input, output, comb, dryGain, wetGain, _freqVoct, _mix };\n },\n\n updateParam(nodes, _m, param, value) {\n const t = (nodes._freqVoct as AudioWorkletNode).parameters.get('transpose')!;\n if (param === 'offset') {\n t.value = value as number;\n } else if (param === 'frequency') {\n if (!patchCount.get(nodes)) t.value = hzToMidi(value as number);\n } else if (param === 'transpose') {\n if (patchCount.get(nodes)) t.value = value as number;\n } else if (param === 'feedback') {\n (nodes.comb as AudioWorkletNode).parameters.get('feedback')!.value = value as number;\n } else if (param === 'mix') {\n (nodes._mix as ConstantSourceNode).offset.value = value as number;\n }\n // 'tuning' is UI-only, no audio change needed\n },\n\n // App-only: plain summing connect; the hooks only swap which panel memory\n // drives the offset.\n onConnect(nodes, module, portId, sourceNode) {\n if (portId !== 'voct') return false;\n const v = nodes._freqVoct as AudioWorkletNode;\n sourceNode.connect(v);\n patchCount.set(nodes, (patchCount.get(nodes) ?? 0) + 1);\n v.parameters.get('transpose')!.value = module.transpose ?? 0;\n return true;\n },\n\n onDisconnect(nodes, module, portId, sourceNode) {\n if (portId !== 'voct') return false;\n const v = nodes._freqVoct as AudioWorkletNode;\n try { sourceNode.disconnect(v); } catch (e) { /* already detached */ }\n const n = Math.max(0, (patchCount.get(nodes) ?? 0) - 1);\n patchCount.set(nodes, n);\n if (!n) v.parameters.get('transpose')!.value = hzToMidi(module.frequency);\n return true;\n },\n\n});\n", "import { defineModule } from '../../core';\nimport { combFilterDescriptor } from './comb-filter';\nimport type { CombFilterParams, CombFilterInputs, CombFilterOutputs, CombFilterProps } from './comb-filter.types';\nimport map_voct_to_period from '../worklet-src/map-voct-to-period';\nimport comb_filter from '../worklet-src/comb-filter';\n\nexport const CombFilter = /* @__PURE__ */ defineModule(combFilterDescriptor, {\n worklets: {\n 'map-voct-to-period': map_voct_to_period,\n 'comb-filter': comb_filter,\n },\n}) as import('../../core').LibModule<CombFilterParams, CombFilterInputs, CombFilterOutputs, CombFilterProps>;\nexport type { CombFilterParams, CombFilterInputs, CombFilterOutputs, CombFilterProps };\n", "// @ts-nocheck \u2014 generated by scripts/lib/build.ts\nimport { BaseModule } from '@/types/synth';\n\nexport interface CompressorModule extends BaseModule {\n type: 'compressor';\n threshold: number;\n ratio: number;\n attack: number;\n release: number;\n knee: number;\n makeup: number;\n}\nimport { defineDescriptor, paramDefaults } from '@/modules/ModuleDescriptor';\n\n// \u2500\u2500\u2500 PARAMS \u2014 the signal contract (no UI knowledge) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nconst params = {\n threshold: { node: 'comp', field: 'threshold', unit: 'dB', default: -24, min: -60, max: 0, },\n ratio: { node: 'comp', field: 'ratio', unit: 'factor', default: 4, min: 1, max: 20, scale: 'log', },\n attack: { node: 'comp', field: 'attack', unit: 's', default: 0.003, min: 0.001, max: 1, scale: 'log', },\n release: { node: 'comp', field: 'release', unit: 's', default: 0.25, min: 0.01, max: 1, scale: 'log', },\n knee: { node: 'comp', field: 'knee', unit: 'dB', default: 10, min: 0, max: 40, },\n // makeup is stored in dB but drives a linear gain node (Math.pow(10, v/20)) \u2014\n // not a 1:1 AudioParam mapping, so no node/field.\n makeup: { unit: 'dB', default: 0, min: 0, max: 30, },\n} satisfies Record<string, ParamSpec>;\n\n\n\n// \u2500\u2500\u2500 DESCRIPTOR \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport const compressorDescriptor = /* @__PURE__ */ defineDescriptor({\n type: 'compressor',\n params,\n\n\n ports: {\n 'in': { type: 'input', signal: 'audio', node: 'comp', },\n 'out': { type: 'output', signal: 'audio', node: 'makeup', },\n },\n\n\n createModule(id, position) {\n return { id, type: 'compressor', position, ...paramDefaults(params) };\n },\n\n createNodes(ctx, module) {\n const comp = ctx.createDynamicsCompressor();\n comp.threshold.value = module.threshold;\n comp.ratio.value = module.ratio;\n comp.attack.value = module.attack;\n comp.release.value = module.release;\n comp.knee.value = module.knee;\n const makeup = ctx.createGain();\n makeup.gain.value = Math.pow(10, (module.makeup || 0) / 20);\n comp.connect(makeup);\n return { comp, makeup };\n },\n\n updateParam(nodes, _m, param, value) {\n const v = value as number;\n switch (param) {\n case 'threshold': nodes.comp.threshold.value = v; break;\n case 'ratio': nodes.comp.ratio.value = v; break;\n case 'attack': nodes.comp.attack.value = v; break;\n case 'release': nodes.comp.release.value = v; break;\n case 'knee': nodes.comp.knee.value = v; break;\n case 'makeup': nodes.makeup.gain.value = Math.pow(10, v / 20); break;\n }\n },\n\n});\n", "import { defineModule } from '../../core';\nimport { compressorDescriptor } from './comp';\nimport type { CompressorParams, CompressorInputs, CompressorOutputs, CompressorProps } from './comp.types';\n\n\nexport const Compressor = /* @__PURE__ */ defineModule(compressorDescriptor) as import('../../core').LibModule<CompressorParams, CompressorInputs, CompressorOutputs, CompressorProps>;\nexport type { CompressorParams, CompressorInputs, CompressorOutputs, CompressorProps };\n", "// @ts-nocheck \u2014 generated by scripts/lib/build.ts\n\nimport type { BaseModule, Position } from '@/types/synth';\nimport { defineDescriptor, paramDefaults } from '@/modules/ModuleDescriptor';\n\nexport interface CrossfadeModule extends BaseModule {\n type: 'crossfade';\n blend: number;\n curve: 'linear' | 'equal-power';\n}\n\n// \u2500\u2500\u2500 PARAMS \u2014 the signal contract \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n// `blend` used to be two direct .gain.value writes \u2014 not a single AudioParam.\n// Now ONE ConstantSource (`_mix`) carries blend at audio rate; two WaveShapers\n// turn it into gainA/gainB per the active law, so blend is an honest 1:1\n// AudioParam (automatable, CV-modulatable). `curve` swaps the shaper tables \u2014\n// not a single AudioParam \u2014 so it stays a set-only enum.\nconst params = {\n blend: { node: '_mix', field: 'offset', unit: 'factor', default: 0.5, min: 0, max: 1, },\n curve: { kind: 'enum', default: 'equal-power', options: ['linear', 'equal-power'], },\n} satisfies Record<string, ParamSpec>;\n\n\nconst CURVE_POINTS = 2049; // spans input \u22121\u20261\n\nfunction lawCurve(fn: (m: number) => number): Float32Array<ArrayBuffer> {\n const c = new Float32Array(CURVE_POINTS);\n for (let i = 0; i < CURVE_POINTS; i++) {\n const x = -1 + (2 * i) / (CURVE_POINTS - 1);\n c[i] = fn(Math.min(1, Math.max(0, x)));\n }\n return c;\n}\n\nfunction curvesFor(curve: string): { a: Float32Array<ArrayBuffer>; b: Float32Array<ArrayBuffer> } {\n if (curve === 'equal-power') {\n return {\n a: lawCurve((m) => Math.cos(m * Math.PI / 2)),\n b: lawCurve((m) => Math.sin(m * Math.PI / 2)),\n };\n }\n return {\n a: lawCurve((m) => 1 - m),\n b: lawCurve((m) => m),\n };\n}\n\n\n// nodes: [inputA, inputB, output, _mix, curveA, curveB]\nexport const crossfadeDescriptor = /* @__PURE__ */ defineDescriptor({\n type: 'crossfade',\n params,\n\n ports: {\n 'a': { type: 'input', signal: 'audio', node: 'inputA', },\n 'b': { type: 'input', signal: 'audio', node: 'inputB', },\n 'out': { type: 'output', signal: 'audio', node: 'output', },\n },\n\n createModule(id, position) {\n return { id, type: 'crossfade', position, ...paramDefaults(params) } as CrossfadeModule;\n },\n\n createNodes(ctx, module) {\n const inputA = ctx.createGain();\n const inputB = ctx.createGain();\n const output = ctx.createGain();\n\n inputA.gain.value = 0;\n inputB.gain.value = 0;\n\n const _mix = ctx.createConstantSource();\n _mix.offset.value = module.blend;\n\n const { a, b } = curvesFor(module.curve);\n const curveA = ctx.createWaveShaper();\n curveA.curve = a;\n const curveB = ctx.createWaveShaper();\n curveB.curve = b;\n\n _mix.connect(curveA).connect(inputA.gain);\n _mix.connect(curveB).connect(inputB.gain);\n _mix.start();\n\n inputA.connect(output);\n inputB.connect(output);\n\n return { inputA, inputB, output, _mix, curveA, curveB };\n },\n\n updateParam(nodes, module, param, value) {\n if (param === 'blend') {\n (nodes._mix as ConstantSourceNode).offset.value = value as number;\n } else if (param === 'curve') {\n const { a, b } = curvesFor(value as string);\n (nodes.curveA as WaveShaperNode).curve = a;\n (nodes.curveB as WaveShaperNode).curve = b;\n }\n },\n\n});\n", "import { defineModule } from '../../core';\nimport { crossfadeDescriptor } from './crossfade';\nimport type { CrossfadeParams, CrossfadeInputs, CrossfadeOutputs, CrossfadeProps } from './crossfade.types';\n\n\nexport const Crossfade = /* @__PURE__ */ defineModule(crossfadeDescriptor) as import('../../core').LibModule<CrossfadeParams, CrossfadeInputs, CrossfadeOutputs, CrossfadeProps>;\nexport type { CrossfadeParams, CrossfadeInputs, CrossfadeOutputs, CrossfadeProps };\n", "// @ts-nocheck \u2014 generated by scripts/lib/build.ts\nimport { createMix } from '@/lib/dsp/mix';\nimport { createCombFilterNode } from '@/worklets';\nimport { BaseModule } from '@/types/synth';\n\nexport interface DelayModule extends BaseModule {\n type: 'delay';\n time: number;\n feedback: number;\n mix: number;\n}\nimport { defineDescriptor, paramDefaults } from '@/modules/ModuleDescriptor';\n\n// \u2500\u2500\u2500 PARAMS (single source of truth: knobs, defaults, hover tips, docs) \u2500\u2500\nconst params = {\n time: { node: 'delay', field: 'period', default: 0.3, min: 0.01, max: 1, scale: 'log', unit: 's', },\n feedback: { node: 'delay', field: 'feedback', unit: 'factor', default: 0.4, min: 0, max: 0.95, },\n mix: { node: '_mix', field: 'offset', unit: 'factor', default: 0.5, min: 0, max: 1, },\n} satisfies Record<string, ParamSpec>;\n\n\n\n// \u2500\u2500\u2500 DESCRIPTOR \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport const delayDescriptor = /* @__PURE__ */ defineDescriptor({\n type: 'delay',\n params,\n\n\n ports: {\n 'in': { type: 'input', signal: 'audio', node: 'input', },\n 'out': { type: 'output', signal: 'audio', node: 'output', },\n },\n\n createModule(id, position) {\n return { id, type: 'delay', position, ...paramDefaults(params) };\n },\n\n createNodes(ctx, module) {\n // Single-sample-feedback delay line (the COMB processor with a 5 s line).\n // A native DelayNode\u2192GainNode loop hides one render quantum per cycle, so\n // echo spacing was TIME + 128/sr; the old fix subtracted it and made the\n // FIRST echo land 128 frames early. Inside one processor both are exact,\n // and `time` is the real AudioParam (a-rate: ramps give tape-style pitch).\n const delay = createCombFilterNode(ctx, module.feedback, 5, 2);\n delay.parameters.get('period')!.value = module.time;\n const dryGain = ctx.createGain();\n const wetGain = ctx.createGain();\n const input = ctx.createGain();\n const output = ctx.createGain();\n const _mix = createMix(ctx, dryGain, wetGain, module.mix, 'linear');\n input.connect(dryGain);\n input.connect(delay);\n delay.connect(wetGain);\n dryGain.connect(output);\n wetGain.connect(output);\n return { input, output, delay, dryGain, wetGain, _mix };\n },\n\n updateParam(nodes, _m, param, value) {\n switch (param) {\n case 'time': (nodes.delay as AudioWorkletNode).parameters.get('period')!.value = value as number; break;\n case 'feedback': (nodes.delay as AudioWorkletNode).parameters.get('feedback')!.value = value as number; break;\n case 'mix':\n (nodes._mix as ConstantSourceNode).offset.value = value as number;\n break;\n }\n },\n\n});\n", "import { defineModule } from '../../core';\nimport { delayDescriptor } from './delay';\nimport type { DelayParams, DelayInputs, DelayOutputs, DelayProps } from './delay.types';\nimport comb_filter from '../worklet-src/comb-filter';\n\nexport const Delay = /* @__PURE__ */ defineModule(delayDescriptor, {\n worklets: {\n 'comb-filter': comb_filter,\n },\n}) as import('../../core').LibModule<DelayParams, DelayInputs, DelayOutputs, DelayProps>;\nexport type { DelayParams, DelayInputs, DelayOutputs, DelayProps };\n", "// @ts-nocheck \u2014 generated by scripts/lib/build.ts\nimport { BaseModule } from '@/types/synth';\n\nexport interface DimensionModule extends BaseModule {\n type: 'dimension';\n rate: number;\n depth: number;\n}\nimport { defineDescriptor, paramDefaults } from '@/modules/ModuleDescriptor';\n\nconst params = {\n rate: { node: 'lfo', field: 'frequency', unit: 'Hz', default: 0.5, min: 0.1, max: 5, },\n depth: { unit: 'factor', default: 0.3, min: 0, max: 1, },\n} satisfies Record<string, ParamSpec>;\n\n\n\nexport const dimensionDescriptor = /* @__PURE__ */ defineDescriptor({\n type: 'dimension',\n params,\n\n ports: {\n 'in': { type: 'input', signal: 'audio', node: 'input', },\n 'out': { type: 'output', signal: 'audio', node: 'output', },\n 'modRate': { type: 'modulation', signal: 'modulation', node: 'lfo', field: 'frequency' },\n },\n\n createModule(id, position) {\n return { id, type: 'dimension', position, ...paramDefaults(params) };\n },\n\n createNodes(ctx, module) {\n const input = ctx.createGain();\n input.channelCount = 2;\n input.channelCountMode = 'explicit';\n input.channelInterpretation = 'speakers';\n const output = ctx.createGain();\n const splitter = ctx.createChannelSplitter(2);\n const merger = ctx.createChannelMerger(2);\n const leftDelay = ctx.createDelay(0.05);\n const rightDelay = ctx.createDelay(0.05);\n const lfo = ctx.createOscillator();\n const lfoGainL = ctx.createGain();\n const lfoGainR = ctx.createGain();\n\n const llGain = ctx.createGain();\n const lrGain = ctx.createGain();\n const rlGain = ctx.createGain();\n const rrGain = ctx.createGain();\n\n const w = module.width;\n llGain.gain.value = (1 + w) / 2;\n rrGain.gain.value = (1 + w) / 2;\n rlGain.gain.value = (1 - w) / 2;\n lrGain.gain.value = (1 - w) / 2;\n\n leftDelay.delayTime.value = 0.01;\n rightDelay.delayTime.value = 0.012;\n lfo.type = 'sine';\n lfo.frequency.value = module.rate;\n lfoGainL.gain.value = module.depth * 0.002;\n lfoGainR.gain.value = -module.depth * 0.002;\n\n lfo.connect(lfoGainL);\n lfo.connect(lfoGainR);\n lfoGainL.connect(leftDelay.delayTime);\n lfoGainR.connect(rightDelay.delayTime);\n lfo.start();\n\n input.connect(splitter);\n splitter.connect(leftDelay, 0);\n splitter.connect(rightDelay, 1);\n\n leftDelay.connect(llGain);\n leftDelay.connect(lrGain);\n rightDelay.connect(rrGain);\n rightDelay.connect(rlGain);\n\n llGain.connect(merger, 0, 0);\n rlGain.connect(merger, 0, 0);\n lrGain.connect(merger, 0, 1);\n rrGain.connect(merger, 0, 1);\n\n merger.connect(output);\n\n return { input, output, splitter, merger, leftDelay, rightDelay, lfo, lfoGainL, lfoGainR, llGain, rrGain, lrGain, rlGain };\n },\n\n updateParam(nodes, _m, param, value) {\n if (param === 'width') {\n const w = value as number;\n nodes.llGain.gain.value = (1 + w) / 2;\n nodes.rrGain.gain.value = (1 + w) / 2;\n nodes.rlGain.gain.value = (1 - w) / 2;\n nodes.lrGain.gain.value = (1 - w) / 2;\n } else if (param === 'rate') nodes.lfo.frequency.value = value as number;\n else if (param === 'depth') {\n nodes.lfoGainL.gain.value = (value as number) * 0.002;\n nodes.lfoGainR.gain.value = -(value as number) * 0.002;\n }\n },\n\n dispose(nodes) {\n nodes.lfo.stop();\n },\n\n});\n", "import { defineModule } from '../../core';\nimport { dimensionDescriptor } from './dimension';\nimport type { DimensionParams, DimensionInputs, DimensionOutputs, DimensionProps } from './dimension.types';\n\n\nexport const Dimension = /* @__PURE__ */ defineModule(dimensionDescriptor) as import('../../core').LibModule<DimensionParams, DimensionInputs, DimensionOutputs, DimensionProps>;\nexport type { DimensionParams, DimensionInputs, DimensionOutputs, DimensionProps };\n", "// @ts-nocheck \u2014 generated by scripts/lib/build.ts\nimport { createMix } from '@/lib/dsp/mix';\n\nimport { BaseModule, DistortionType } from '@/types/synth';\n\nexport interface DistortionModule extends BaseModule {\n type: 'distortion';\n distortionType: DistortionType;\n drive: number;\n /** TONE: post-clip lowpass cutoff in Hz (500 = dark, 16000 = open). */\n frequency: number;\n mix: number;\n}\nimport { defineDescriptor, paramDefaults } from '@/modules/ModuleDescriptor';\n\n// \u2500\u2500\u2500 PARAMS (single source of truth: knobs, defaults, hover tips, docs) \u2500\u2500\nconst params = {\n distortionType: { kind: 'enum', default: 'soft', options: ['soft', 'hard', 'fuzz'] as const, },\n drive: { unit: 'factor', default: 5, min: 1, max: 20, scale: 'log', },\n frequency: { node: 'toneFilter', field: 'frequency', unit: 'Hz', default: 16000, min: 500, max: 16000, scale: 'log', },\n mix: { node: '_mix', field: 'offset', unit: 'factor', default: 0.8, min: 0, max: 1, },\n} satisfies Record<string, ParamSpec>;\n\n\n/**\n * Honest transfer curves \u2014 rebuilt 2026-08-04 (see reports/distortion.md).\n *\n * The pre-rebuild module fed `drive*10` into three curves of which \"hard\"\n * was the MDN soft-knee demo formula (never exceeded \u00B10.35 \u2014 softer than\n * \"soft\") and \"fuzz\" was a piecewise-linear clip. Now each mode is the\n * circuit its name promises, with k = drive (1\u201320) directly:\n *\n * soft \u2014 symmetric tanh(k\u00B7x): classic soft clipper, odd harmonics,\n * gradual onset. k=1 is near-linear warmth, k=20 heavy squash.\n * (The old \u00D710 multiplier saturated the entire knob by ~drive 3.)\n * hard \u2014 clamp(k\u00B7x, \u00B11): a true diode-style rail clipper (RAT/DS-1\n * family). At high drive the wave genuinely flattens to a square.\n * fuzz \u2014 exponential saturator with a fixed forward bias:\n * f(u) = sign(u)\u00B7(1 \u2212 e^\u2212|u|), y = (f(k\u00B7x + B) \u2212 f(B)) / (1 + f(B)).\n * Smoothly saturating (no piecewise corners), asymmetric (the bias\n * clips one half earlier \u2192 even harmonics), normalised to |y| \u2264 1.\n * Bias asymmetry produces DC, which the blocker below removes \u2014\n * the coupling cap every real fuzz circuit has.\n */\nconst FUZZ_BIAS = 0.7;\n\nfunction transfer(type: string, k: number, x: number): number {\n if (type === 'soft') return Math.tanh(k * x);\n if (type === 'hard') return Math.max(-1, Math.min(1, k * x));\n const f = (u: number) => Math.sign(u) * (1 - Math.exp(-Math.abs(u)));\n return (f(k * x + FUZZ_BIAS) - f(FUZZ_BIAS)) / (1 + f(FUZZ_BIAS));\n}\n\nconst CURVE_LEN = 16384;\n\nfunction makeDistortionCurve(type: string, drive: number): Float32Array {\n const k = Math.max(1, Math.min(20, drive));\n const curve = new Float32Array(CURVE_LEN);\n for (let i = 0; i < CURVE_LEN; i++) {\n const x = (i * 2) / (CURVE_LEN - 1) - 1;\n curve[i] = transfer(type, k, x);\n }\n return curve;\n}\n\n/**\n * Loudness compensation: waveshaping changes RMS wildly between modes and\n * across the drive range (a rail-clipped square is ~9 dB hotter than the\n * sine that made it). Real pedals hand the player a Level knob; in a rack,\n * a static makeup gain that pins nominal-level output back to nominal input\n * is the modular equivalent \u2014 DRIVE and TYPE become timbre controls, not\n * volume controls (same philosophy as `bandpassMakeup` in dsp/gainComp).\n *\n * Computed numerically: AC RMS (mean removed \u2014 the DC blocker eats the mean)\n * of the curve applied to a 0.5-amplitude sine, the fleet's nominal level.\n */\nfunction computeMakeup(type: string, drive: number): number {\n const k = Math.max(1, Math.min(20, drive));\n const N = 512;\n let sum = 0;\n let sumSq = 0;\n for (let i = 0; i < N; i++) {\n const y = transfer(type, k, 0.5 * Math.sin((2 * Math.PI * i) / N));\n sum += y;\n sumSq += y * y;\n }\n const mean = sum / N;\n const acRms = Math.sqrt(Math.max(0, sumSq / N - mean * mean));\n const rmsIn = 0.5 / Math.SQRT2;\n if (acRms < 1e-6) return 1;\n return Math.min(4, Math.max(0.25, rmsIn / acRms));\n}\n\n\nconst distortionTypes = params.distortionType.options;\n\n\nexport const distortionDescriptor = /* @__PURE__ */ defineDescriptor({\n type: 'distortion',\n params,\n\n ports: {\n 'in': { type: 'input', signal: 'audio', node: 'input', },\n 'out': { type: 'output', signal: 'audio', node: 'output', },\n },\n createModule(id, position) {\n return {\n id, type: 'distortion', position, ...paramDefaults(params),\n };\n },\n\n createNodes(ctx, module) {\n const input = ctx.createGain();\n const output = ctx.createGain();\n const dryGain = ctx.createGain();\n const wetGain = ctx.createGain();\n const waveshaper = ctx.createWaveShaper();\n const makeup = ctx.createGain();\n // DC blocker \u2014 output coupling cap. The fuzz curve's bias asymmetry\n // (and any asymmetric program material) produces a DC component that\n // would otherwise bias downstream envelope followers and scopes.\n const dcBlock = ctx.createBiquadFilter();\n const toneFilter = ctx.createBiquadFilter();\n\n waveshaper.curve = makeDistortionCurve(module.distortionType, module.drive) as Float32Array<ArrayBuffer>;\n waveshaper.oversample = '4x';\n makeup.gain.value = computeMakeup(module.distortionType, module.drive);\n dcBlock.type = 'highpass';\n dcBlock.frequency.value = 10;\n dcBlock.Q.value = 0.707;\n toneFilter.type = 'lowpass';\n toneFilter.frequency.value = module.frequency;\n toneFilter.Q.value = 0.707;\n const _mix = createMix(ctx, dryGain, wetGain, module.mix, 'linear');\n\n input.connect(dryGain);\n input.connect(waveshaper);\n waveshaper.connect(makeup);\n makeup.connect(dcBlock);\n dcBlock.connect(toneFilter);\n toneFilter.connect(wetGain);\n dryGain.connect(output);\n wetGain.connect(output);\n\n return { input, output, waveshaper, makeup, dcBlock, toneFilter, dryGain, wetGain, _mix };\n },\n\n updateParam(nodes, module, param, value) {\n if (param === 'drive' || param === 'distortionType') {\n nodes.waveshaper.curve = makeDistortionCurve(module.distortionType, module.drive) as Float32Array<ArrayBuffer>;\n nodes.makeup.gain.value = computeMakeup(module.distortionType, module.drive);\n }\n if (param === 'frequency') {\n nodes.toneFilter.frequency.value = value as number;\n }\n if (param === 'mix') {\n (nodes._mix as ConstantSourceNode).offset.value = value as number;\n }\n },\n\n});\n", "import { defineModule } from '../../core';\nimport { distortionDescriptor } from './distortion';\nimport type { DistortionParams, DistortionInputs, DistortionOutputs, DistortionProps } from './distortion.types';\n\n\nexport const Distortion = /* @__PURE__ */ defineModule(distortionDescriptor) as import('../../core').LibModule<DistortionParams, DistortionInputs, DistortionOutputs, DistortionProps>;\nexport type { DistortionParams, DistortionInputs, DistortionOutputs, DistortionProps };\n", "// @ts-nocheck \u2014 generated by scripts/lib/build.ts\nimport type { BaseModule, Position } from '@/types/synth';\nimport { createEnvFollowerNode } from '@/worklets';\n\nexport interface DuckerModule extends BaseModule {\n type: 'ducker';\n threshold: number;\n amount: number;\n attack: number;\n release: number;\n}\nimport { defineDescriptor, paramDefaults } from '@/modules/ModuleDescriptor';\n\n// \u2500\u2500\u2500 PARAMS \u2014 the signal contract (no UI knowledge) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nconst params = {\n // Feeds scInput.gain via 1/10^(threshold/20) \u2014 a conversion, not a 1:1\n // AudioParam write \u2014 so no node/field.\n threshold: { unit: 'dB', default: -24, min: -60, max: 0, },\n // Feeds invertGain.gain via negation (-amount) \u2014 no node/field.\n amount: { unit: 'factor', default: 0.7, min: 0, max: 1, },\n attack: { node: 'envFollower', field: 'attack', unit: 's', default: 0.01, min: 0.001, max: 0.1, scale: 'log', },\n release: { node: 'envFollower', field: 'release', unit: 's', default: 0.2, min: 0.001, max: 1, scale: 'log', },\n} satisfies Record<string, ParamSpec>;\n\n\n\nexport const duckerDescriptor = /* @__PURE__ */ defineDescriptor({\n type: 'ducker' as const,\n params,\n\n ports: {\n 'in': { type: 'input' as const, signal: 'audio' as const, node: 'input', },\n 'sc': { type: 'input' as const, signal: 'audio' as const, node: 'scInput', },\n 'out': { type: 'output' as const, signal: 'audio' as const, node: 'output', },\n },\n\n createModule(id: string, position: Position): DuckerModule {\n return { id, type: 'ducker', position, ...paramDefaults(params) };\n },\n\n createNodes(ctx, module) {\n const input = ctx.createGain();\n const scInput = ctx.createGain();\n const output = ctx.createGain();\n const duckGain = ctx.createGain();\n\n // Threshold normalization: scale sidechain so that threshold level \u2192 ~1.0\n scInput.gain.value = 1 / Math.max(0.001, Math.pow(10, module.threshold / 20));\n\n // Detector saturation. Without it a kick sitting 30 dB over the threshold\n // charges the follower to ~30, and REL then has to bleed all of that off\n // before the gain moves at all \u2014 the duck never opens between hits and the\n // patch just sounds permanently quiet. Real sidechain detectors saturate\n // (diode/optical), so the follower sees a soft-limited copy: reaching the\n // threshold is enough for the full duck, and going past it makes no\n // further difference. y = A\u00B7tanh(x/A), which is linear for small x.\n const scClamp = ctx.createWaveShaper();\n scClamp.oversample = 'none';\n const SAT = 1.2;\n const curve = new Float32Array(1024);\n for (let i = 0; i < curve.length; i++) {\n const x = (i / (curve.length - 1)) * 2 - 1;\n curve[i] = SAT * Math.tanh(x / SAT);\n }\n scClamp.curve = curve;\n\n // Worklet: sample-accurate asymmetric envelope follower\n const envFollower = createEnvFollowerNode(ctx);\n (envFollower.parameters as any).get('attack').value = module.attack;\n (envFollower.parameters as any).get('release').value = module.release;\n\n // Clamp the drive so the duck gain can never go negative (which would\n // phase-invert and AMPLIFY loud sidechains instead of ducking):\n // gain = 1 \u2212 amount \u00B7 clamp01(1.2 \u00B7 env)\n // With the saturating detector above, env tops out at A\u00B7tanh(1/A) \u2248 0.83,\n // so 1.2 puts full duck depth (1 \u2212 amount) right at the threshold and\n // gives a soft knee underneath it (6 dB under \u2248 half the duck).\n const envDrive = ctx.createGain();\n envDrive.gain.value = 1.2;\n const envClamp = ctx.createWaveShaper();\n envClamp.curve = new Float32Array([0, 0, 1]); // x<0 \u2192 0, 0..1 \u2192 x, x>1 \u2192 1\n\n const invertGain = ctx.createGain();\n invertGain.gain.value = -module.amount;\n\n const constantSource = ctx.createConstantSource();\n constantSource.offset.value = 1.0;\n constantSource.start();\n\n scInput.connect(scClamp);\n scClamp.connect(envFollower);\n envFollower.connect(envDrive);\n envDrive.connect(envClamp);\n envClamp.connect(invertGain);\n invertGain.connect(duckGain.gain);\n constantSource.connect(duckGain.gain);\n\n duckGain.gain.value = 0;\n input.connect(duckGain);\n duckGain.connect(output);\n\n return { input, scInput, scClamp, output, invertGain, envFollower, envDrive, envClamp, constantSource };\n },\n\n updateParam(nodes, _m, param, value) {\n if (param === 'threshold') {\n nodes.scInput.gain.value = 1 / Math.max(0.001, Math.pow(10, (value as number) / 20));\n } else if (param === 'amount') {\n nodes.invertGain.gain.value = -(value as number);\n } else if (param === 'attack') {\n (nodes.envFollower.parameters as any).get('attack').value = value as number;\n } else if (param === 'release') {\n (nodes.envFollower.parameters as any).get('release').value = value as number;\n }\n },\n\n dispose(nodes) {\n nodes.constantSource.stop();\n },\n\n});\n", "import { defineModule } from '../../core';\nimport { duckerDescriptor } from './ducker';\nimport type { DuckerParams, DuckerInputs, DuckerOutputs, DuckerProps } from './ducker.types';\nimport env_follower from '../worklet-src/env-follower';\n\nexport const Ducker = /* @__PURE__ */ defineModule(duckerDescriptor, {\n worklets: {\n 'env-follower': env_follower,\n },\n}) as import('../../core').LibModule<DuckerParams, DuckerInputs, DuckerOutputs, DuckerProps>;\nexport type { DuckerParams, DuckerInputs, DuckerOutputs, DuckerProps };\n", "// @ts-nocheck \u2014 generated by scripts/lib/build.ts\nimport type { BaseModule, Position } from '@/types/synth';\nimport { createEnvFollowerNode } from '@/worklets';\n\nexport interface EnvFollowModule extends BaseModule {\n type: 'env-follow';\n attack: number;\n release: number;\n sensitivity: number;\n depth: number;\n}\nimport { defineDescriptor, paramDefaults } from '@/modules/ModuleDescriptor';\n\n// \u2500\u2500\u2500 PARAMS \u2014 the signal contract (no UI knowledge) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nconst params = {\n attack: { node: 'envFollower', field: 'attack', unit: 's', default: 0.01, min: 0.001, max: 0.5, scale: 'log', },\n release: { node: 'envFollower', field: 'release', unit: 's', default: 0.1, min: 0.001, max: 2, scale: 'log', },\n // sensitivityGain.gain = sensitivity * 4 \u2014 a scaled conversion, not a 1:1\n // AudioParam write \u2014 so no node/field.\n sensitivity: { unit: 'factor', default: 0.5, min: 0, max: 1, },\n depth: { node: 'depthGain', field: 'gain', unit: 'semitone', default: 48, min: 0, max: 96, scale: 'sqrt', },\n} satisfies Record<string, ParamSpec>;\n\n\n\nexport const envFollowDescriptor = /* @__PURE__ */ defineDescriptor({\n type: 'env-follow' as const,\n params,\n\n ports: {\n 'in': { type: 'input' as const, signal: 'audio' as const, node: 'input', },\n 'env': { type: 'output' as const, node: 'depthGain', signal: 'modulation' },\n },\n\n createModule(id: string, position: Position): EnvFollowModule {\n return { id, type: 'env-follow', position, ...paramDefaults(params) };\n },\n\n createNodes(ctx, module) {\n const input = ctx.createGain();\n const depthGain = ctx.createGain();\n const sensitivityGain = ctx.createGain();\n sensitivityGain.gain.value = module.sensitivity * 4;\n depthGain.gain.value = module.depth; // semitones\n\n const envFollower = createEnvFollowerNode(ctx);\n (envFollower.parameters as any).get('attack').value = module.attack;\n (envFollower.parameters as any).get('release').value = module.release;\n\n input.connect(sensitivityGain);\n sensitivityGain.connect(envFollower);\n envFollower.connect(depthGain);\n\n return { input, depthGain, sensitivityGain, envFollower };\n },\n\n updateParam(nodes, _m, param, value) {\n if (param === 'sensitivity') {\n nodes.sensitivityGain.gain.value = (value as number) * 4;\n } else if (param === 'depth') {\n nodes.depthGain.gain.value = value as number; // semitones\n } else if (param === 'attack') {\n (nodes.envFollower.parameters as any).get('attack').value = value as number;\n } else if (param === 'release') {\n (nodes.envFollower.parameters as any).get('release').value = value as number;\n }\n },\n\n});\n", "import { defineModule } from '../../core';\nimport { envFollowDescriptor } from './env-follow';\nimport type { EnvelopeFollowerParams, EnvelopeFollowerInputs, EnvelopeFollowerOutputs, EnvelopeFollowerProps } from './env-follow.types';\nimport env_follower from '../worklet-src/env-follower';\n\nexport const EnvelopeFollower = /* @__PURE__ */ defineModule(envFollowDescriptor, {\n worklets: {\n 'env-follower': env_follower,\n },\n}) as import('../../core').LibModule<EnvelopeFollowerParams, EnvelopeFollowerInputs, EnvelopeFollowerOutputs, EnvelopeFollowerProps>;\nexport type { EnvelopeFollowerParams, EnvelopeFollowerInputs, EnvelopeFollowerOutputs, EnvelopeFollowerProps };\n", "// @ts-nocheck \u2014 generated by scripts/lib/build.ts\nimport type { BaseModule, Position } from '@/types/synth';\n\nexport interface EnvelopeModule extends BaseModule {\n type: 'envelope';\n attack: number;\n decay: number;\n sustain: number;\n release: number;\n depth: number;\n /** Save-format marker: decay/release are T60s of exponential segments\n * (2026-09-30). Absent on older saves \u2192 patchStorage migrateEnvelopeTimes. */\n timeUnit?: 't60';\n}\nimport { defineDescriptor, paramDefaults } from '@/modules/ModuleDescriptor';\nimport { createAdsrNode } from '@/worklets';\n\n// \u2500\u2500\u2500 PARAMS (single source of truth: knobs, defaults, hover tips, docs) \u2500\u2500\n// Decay and release are exponential (analog RC) segments; each knob is the\n// segment's T60 \u2014 the time to fall 60 dB (worklets/adsr-envelope.ts).\nconst params = {\n attack: { node: 'adsrNode', field: 'attack', default: 0.01, min: 0.001, max: 2, scale: 'log' as const, unit: 's', },\n decay: { node: 'adsrNode', field: 'decay', default: 0.46, min: 0.001, max: 10, scale: 'log' as const, unit: 's', },\n sustain: { node: 'adsrNode', field: 'sustain', unit: 'factor', default: 0.7, min: 0, max: 1, },\n release: { node: 'adsrNode', field: 'release', default: 2.1, min: 0.001, max: 20, scale: 'log' as const, unit: 's', },\n depth: { node: 'envOut', field: 'gain', default: 48, min: 0, max: 96, scale: 'sqrt' as const, unit: 'semitone', },\n} as const satisfies Record<string, ParamSpec>;\n\n// \u2500\u2500\u2500 UI \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n\n// \u2500\u2500\u2500 DESCRIPTOR \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport const envelopeDescriptor = /* @__PURE__ */ defineDescriptor({\n type: 'envelope',\n params,\n\n ports: {\n 'in': { type: 'input', signal: 'audio', node: 'mainGain', },\n 'out': { type: 'output', signal: 'audio', node: 'mainGain', },\n 'env': { type: 'output', signal: 'modulation', node: 'envOut', },\n 'trigger': { type: 'input', signal: 'gate', node: 'adsrNode', },\n },\n\n\n createModule(id: string, position: Position): EnvelopeModule {\n return { id, type: 'envelope', position, timeUnit: 't60', ...paramDefaults(params) };\n },\n\n createNodes(ctx, module) {\n const mainGain = ctx.createGain();\n mainGain.gain.value = 0;\n\n // ADSR worklet: gate input \u2192 envelope output (0\u20131)\n const adsrNode = createAdsrNode(ctx);\n adsrNode.parameters.get('attack')!.value = module.attack;\n adsrNode.parameters.get('decay')!.value = module.decay;\n adsrNode.parameters.get('sustain')!.value = module.sustain;\n adsrNode.parameters.get('release')!.value = module.release;\n\n // Worklet envelope output drives the VCA gain\n adsrNode.connect(mainGain.gain);\n\n // Raw envelope CV output (pass-through gain node at unity)\n const depth = module.depth ?? 48;\n const envOut = ctx.createGain();\n envOut.gain.value = depth;\n adsrNode.connect(envOut);\n\n return { mainGain, adsrNode, envOut };\n },\n\n updateParam(nodes, _module, param, value) {\n const v = value as number;\n const p = nodes.adsrNode.parameters;\n switch (param) {\n case 'attack': p.get('attack')!.value = v; break;\n case 'decay': p.get('decay')!.value = v; break;\n case 'sustain': p.get('sustain')!.value = v; break;\n case 'release': p.get('release')!.value = v; break;\n case 'depth': nodes.envOut.gain.value = v; break;\n }\n },\n\n});\n", "import { defineModule } from '../../core';\nimport { envelopeDescriptor } from './envelope';\nimport type { EnvelopeParams, EnvelopeInputs, EnvelopeOutputs, EnvelopeProps } from './envelope.types';\nimport adsr_envelope from '../worklet-src/adsr-envelope';\n\nexport const Envelope = /* @__PURE__ */ defineModule(envelopeDescriptor, {\n worklets: {\n 'adsr-envelope': adsr_envelope,\n },\n}) as import('../../core').LibModule<EnvelopeParams, EnvelopeInputs, EnvelopeOutputs, EnvelopeProps>;\nexport type { EnvelopeParams, EnvelopeInputs, EnvelopeOutputs, EnvelopeProps };\n", "// @ts-nocheck \u2014 generated by scripts/lib/build.ts\nimport { BaseModule } from '@/types/synth';\n\nexport interface EQ3Module extends BaseModule {\n type: 'eq3';\n low: number;\n mid: number;\n high: number;\n midFreq: number;\n}\nimport { defineDescriptor, paramDefaults } from '@/modules/ModuleDescriptor';\n\n// \u2500\u2500\u2500 PARAMS \u2500 the signal contract (no UI knowledge) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nconst params = {\n low: { node: 'lowShelf', field: 'gain', unit: 'dB', default: 0, min: -12, max: 12, },\n mid: { node: 'midPeak', field: 'gain', unit: 'dB', default: 0, min: -12, max: 12, },\n high: { node: 'highShelf', field: 'gain', unit: 'dB', default: 0, min: -12, max: 12, },\n midFreq: { node: 'midPeak', field: 'frequency', unit: 'Hz', default: 1000, min: 200, max: 5000, scale: 'log', },\n} satisfies Record<string, ParamSpec>;\n\n// \u2500\u2500\u2500 UI \u2500 presentation layer (stripped from the library) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n\nexport const eq3Descriptor = /* @__PURE__ */ defineDescriptor({\n type: 'eq3',\n params,\n\n ports: {\n 'in': { type: 'input', signal: 'audio', node: 'input', },\n 'out': { type: 'output', signal: 'audio', node: 'output', },\n },\n\n createModule(id, position) {\n return { id, type: 'eq3', position, ...paramDefaults(params) };\n },\n\n createNodes(ctx, module) {\n const input = ctx.createGain();\n const output = ctx.createGain();\n const lowShelf = ctx.createBiquadFilter();\n const midPeak = ctx.createBiquadFilter();\n const highShelf = ctx.createBiquadFilter();\n lowShelf.type = 'lowshelf'; lowShelf.frequency.value = 320; lowShelf.gain.value = module.low;\n midPeak.type = 'peaking'; midPeak.frequency.value = module.midFreq; midPeak.Q.value = 1.5; midPeak.gain.value = module.mid;\n highShelf.type = 'highshelf'; highShelf.frequency.value = 3200; highShelf.gain.value = module.high;\n input.connect(lowShelf); lowShelf.connect(midPeak); midPeak.connect(highShelf); highShelf.connect(output);\n return { input, output, lowShelf, midPeak, highShelf };\n },\n\n updateParam(nodes, _m, param, value) {\n switch (param) {\n case 'low': nodes.lowShelf.gain.value = value as number; break;\n case 'mid': nodes.midPeak.gain.value = value as number; break;\n case 'high': nodes.highShelf.gain.value = value as number; break;\n case 'midFreq': nodes.midPeak.frequency.value = value as number; break;\n }\n },\n\n});\n", "import { defineModule } from '../../core';\nimport { eq3Descriptor } from './eq3';\nimport type { ThreeBandEqParams, ThreeBandEqInputs, ThreeBandEqOutputs, ThreeBandEqProps } from './eq3.types';\n\n\nexport const ThreeBandEq = /* @__PURE__ */ defineModule(eq3Descriptor) as import('../../core').LibModule<ThreeBandEqParams, ThreeBandEqInputs, ThreeBandEqOutputs, ThreeBandEqProps>;\nexport type { ThreeBandEqParams, ThreeBandEqInputs, ThreeBandEqOutputs, ThreeBandEqProps };\n", "// @ts-nocheck \u2014 generated by scripts/lib/build.ts\nimport type { BaseModule, Position } from '@/types/synth';\nimport { defineDescriptor, paramDefaults } from '@/modules/ModuleDescriptor';\n\nexport interface ExciterModule extends BaseModule {\n type: 'exciter';\n drive: number;\n frequency: number;\n mix: number;\n}\n\n// \u2500\u2500\u2500 PARAMS \u2014 the signal contract (no UI knowledge) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nconst params = {\n // drive rebuilds the saturation curve AND scales highshelf.gain \u2014 not a\n // 1:1 AudioParam write, so no node/field.\n drive: { unit: 'factor', default: 0.5, min: 0, max: 1, },\n // frequency writes BOTH highpass.frequency and highshelf.frequency \u2014 two\n // AudioParams, so no single node/field mapping.\n frequency: { unit: 'Hz', default: 4000, min: 2000, max: 8000, scale: 'log', },\n // Additive blend, not a dry/wet crossfade: dry stays at unity while wetGain\n // scales the excited signal \u2014 a genuine 1:1 AudioParam write.\n mix: { node: 'wetGain', field: 'gain', unit: 'factor', default: 0.5, min: 0, max: 1, },\n} satisfies Record<string, ParamSpec>;\n\n\nfunction makeExciterCurve(amount: number): Float32Array {\n const samples = 44100;\n const curve = new Float32Array(samples);\n const k = 1 + amount * 8;\n // Level-match the drive stage to a 0.5-amplitude reference: tanh(k\u00B7x) has\n // small-signal gain k (up to 9 = +19 dB), which made the wet leg sit\n // ~+18 dB over dry and clip full-scale on bright input before the shelf\n // even applied (found by probe:exciter-hf, 2026-08-08). With the curve\n // pinned to 0.5 \u2192 0.5, DRIVE grows harmonic content and the highshelf\n // (6 + drive\u00B76 dB) carries the advertised brightness, not raw gain.\n const norm = 0.5 / (Math.tanh(k * 0.5) * 1.15);\n for (let i = 0; i < samples; i++) {\n const x = (i * 2) / samples - 1;\n curve[i] = Math.tanh(k * x) * (1 + Math.abs(x) * 0.3) * norm;\n }\n return curve;\n}\n\n\nexport const exciterDescriptor = /* @__PURE__ */ defineDescriptor({\n type: 'exciter' as const,\n params,\n\n ports: {\n 'in': { type: 'input' as const, signal: 'audio' as const, node: 'input', },\n 'out': { type: 'output' as const, signal: 'audio' as const, node: 'output', },\n },\n\n createModule(id: string, position: Position): ExciterModule {\n return { id, type: 'exciter', position, ...paramDefaults(params) };\n },\n\n createNodes(ctx, module) {\n const input = ctx.createGain();\n const output = ctx.createGain();\n const dryGain = ctx.createGain();\n const wetGain = ctx.createGain();\n const highpass = ctx.createBiquadFilter();\n const saturation = ctx.createWaveShaper();\n const highshelf = ctx.createBiquadFilter();\n\n highpass.type = 'highpass';\n highpass.frequency.value = module.frequency;\n highpass.Q.value = 0.7;\n saturation.curve = makeExciterCurve(module.drive) as Float32Array<ArrayBuffer>;\n saturation.oversample = '2x';\n highshelf.type = 'highshelf';\n highshelf.frequency.value = module.frequency;\n highshelf.gain.value = 6 + module.drive * 6;\n dryGain.gain.value = 1;\n wetGain.gain.value = module.mix;\n\n input.connect(dryGain);\n input.connect(highpass);\n highpass.connect(saturation);\n saturation.connect(highshelf);\n highshelf.connect(wetGain);\n dryGain.connect(output);\n wetGain.connect(output);\n\n return { input, output, highpass, saturation, highshelf, wetGain };\n },\n\n updateParam(nodes, _m, param, value) {\n if (param === 'drive') {\n nodes.saturation.curve = makeExciterCurve(value as number) as Float32Array<ArrayBuffer>;\n nodes.highshelf.gain.value = 6 + (value as number) * 6;\n } else if (param === 'frequency') {\n nodes.highpass.frequency.value = value as number;\n nodes.highshelf.frequency.value = value as number;\n } else if (param === 'mix') {\n nodes.wetGain.gain.value = value as number;\n }\n },\n\n});\n", "import { defineModule } from '../../core';\nimport { exciterDescriptor } from './exciter';\nimport type { ExciterParams, ExciterInputs, ExciterOutputs, ExciterProps } from './exciter.types';\n\n\nexport const Exciter = /* @__PURE__ */ defineModule(exciterDescriptor) as import('../../core').LibModule<ExciterParams, ExciterInputs, ExciterOutputs, ExciterProps>;\nexport type { ExciterParams, ExciterInputs, ExciterOutputs, ExciterProps };\n", "// @ts-nocheck \u2014 generated by scripts/lib/build.ts\nimport { BaseModule } from '@/types/synth';\n\nexport interface FlangerModule extends BaseModule {\n type: 'flanger';\n rate: number;\n depth: number;\n feedback: number;\n mix: number;\n}\nimport { defineDescriptor, paramDefaults } from '@/modules/ModuleDescriptor';\nimport { createFlangerNode } from '@/worklets';\nimport { createMix } from '@/lib/dsp/mix';\n\nconst params = {\n rate: { node: 'flanger', field: 'rate', unit: 'Hz', default: 0.5, min: 0.1, max: 5, },\n depth: { node: 'flanger', field: 'depth', unit: 'factor', default: 0.7, min: 0, max: 1, },\n feedback: { node: 'flanger', field: 'feedback', unit: 'factor', default: 0.7, min: 0, max: 0.95, },\n mix: { node: '_mix', field: 'offset', unit: 'factor', default: 0.5, min: 0, max: 1, },\n} satisfies Record<string, ParamSpec>;\n\n\n\nexport const flangerDescriptor = /* @__PURE__ */ defineDescriptor({\n type: 'flanger',\n params,\n\n ports: {\n 'in': { type: 'input', signal: 'audio', node: 'input', },\n 'out': { type: 'output', signal: 'audio', node: 'output', },\n 'modRate': { type: 'modulation', signal: 'modulation', node: 'flanger', field: 'rate' },\n 'modDepth': { type: 'modulation', signal: 'modulation', node: 'flanger', field: 'depth' },\n 'modFeedback': { type: 'modulation', signal: 'modulation', node: 'flanger', field: 'feedback' },\n 'modMix': { type: 'modulation', signal: 'modulation', node: '_mix', field: 'offset' },\n },\n\n createModule(id, position) {\n return { id, type: 'flanger', position, ...paramDefaults(params) };\n },\n\n createNodes(ctx, module) {\n const input = ctx.createGain();\n const output = ctx.createGain();\n const dryGain = ctx.createGain();\n const wetGain = ctx.createGain();\n const flanger = createFlangerNode(ctx, {\n rate: module.rate, depth: module.depth, feedback: module.feedback,\n });\n const _mix = createMix(ctx, dryGain, wetGain, module.mix, 'linear');\n input.connect(dryGain);\n input.connect(flanger);\n flanger.connect(wetGain);\n dryGain.connect(output);\n wetGain.connect(output);\n return { input, output, flanger, dryGain, wetGain, _mix };\n },\n\n updateParam(nodes, _m, param, value) {\n switch (param) {\n case 'rate':\n case 'depth':\n case 'feedback':\n (nodes.flanger as AudioWorkletNode).parameters.get(param)!.value = value as number;\n break;\n case 'mix':\n (nodes._mix as ConstantSourceNode).offset.value = value as number;\n break;\n }\n },\n\n dispose(nodes) {\n (nodes._mix as ConstantSourceNode).stop();\n },\n\n});\n", "import { defineModule } from '../../core';\nimport { flangerDescriptor } from './flanger';\nimport type { FlangerParams, FlangerInputs, FlangerOutputs, FlangerProps } from './flanger.types';\nimport flanger from '../worklet-src/flanger';\n\nexport const Flanger = /* @__PURE__ */ defineModule(flangerDescriptor, {\n worklets: {\n 'flanger': flanger,\n },\n}) as import('../../core').LibModule<FlangerParams, FlangerInputs, FlangerOutputs, FlangerProps>;\nexport type { FlangerParams, FlangerInputs, FlangerOutputs, FlangerProps };\n", "// @ts-nocheck \u2014 generated by scripts/lib/build.ts\n\nimport type { BaseModule } from '@/types/synth';\nimport { createFormantNode } from '@/worklets';\n\nexport interface FormantModule extends BaseModule {\n type: 'formant';\n morph: number;\n resonance: number;\n mix: number;\n}\nimport { defineDescriptor, paramDefaults } from '@/modules/ModuleDescriptor';\nimport { createKeepAlive } from '@/lib/dsp/keepAlive';\n\nconst vowelFreqs: [number, number, number, number, number][] = [\n [800, 1200, 2500, 3300, 3750],\n [400, 2000, 2800, 3500, 4500],\n [300, 2300, 3000, 3500, 4500],\n [500, 900, 2500, 3300, 3750],\n [350, 700, 2500, 3300, 3750],\n];\n\nfunction getMorphedFormants(morph: number): [number, number, number, number, number] {\n const wrapped = ((morph % 5) + 5) % 5;\n const lower = Math.floor(wrapped) % 5;\n const upper = (lower + 1) % 5;\n const frac = wrapped - Math.floor(wrapped);\n return [\n vowelFreqs[lower][0] + (vowelFreqs[upper][0] - vowelFreqs[lower][0]) * frac,\n vowelFreqs[lower][1] + (vowelFreqs[upper][1] - vowelFreqs[lower][1]) * frac,\n vowelFreqs[lower][2] + (vowelFreqs[upper][2] - vowelFreqs[lower][2]) * frac,\n vowelFreqs[lower][3] + (vowelFreqs[upper][3] - vowelFreqs[lower][3]) * frac,\n vowelFreqs[lower][4] + (vowelFreqs[upper][4] - vowelFreqs[lower][4]) * frac,\n ];\n}\n\nconst vowels = ['A', 'E', 'I', 'O', 'U'] as const;\nconst vowelOptions = /* @__PURE__ */ vowels.map((v, i) => ({ value: String(i), label: v }));\n\n// \u2500\u2500\u2500 PARAMS \u2500 the signal contract (no UI knowledge) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nconst params = {\n morph: { unit: 'factor', default: 0, min: 0, max: 5, },\n resonance: { unit: 'factor', default: 6, min: 1, max: 20, scale: 'sqrt', },\n mix: { unit: 'factor', default: 1.0, min: 0, max: 1, },\n} satisfies Record<string, ParamSpec>;\n\n// \u2500\u2500\u2500 UI \u2500 presentation layer (stripped from the library) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n\nexport const formantDescriptor = /* @__PURE__ */ defineDescriptor({\n type: 'formant',\n params,\n\n ports: {\n 'in': { type: 'input', signal: 'audio', node: 'input', },\n 'out': { type: 'output', signal: 'audio', node: 'output', },\n 'modVowel': { type: 'modulation', signal: 'modulation', node: 'vowelCV', },\n },\n\n createModule(id, position) {\n return { id, type: 'formant', position, ...paramDefaults(params) };\n },\n\n createNodes(ctx, module) {\n const input = ctx.createGain();\n const output = ctx.createGain();\n const dryGain = ctx.createGain();\n const wetGain = ctx.createGain();\n const f1 = ctx.createBiquadFilter();\n const f2 = ctx.createBiquadFilter();\n const f3 = ctx.createBiquadFilter();\n const f4 = ctx.createBiquadFilter();\n const f5 = ctx.createBiquadFilter();\n const formantMix = ctx.createGain();\n\n // Worklet: takes CV input, outputs 5-channel formant frequencies\n const formantWorklet = createFormantNode(ctx);\n (formantWorklet.parameters as any).get('baseMorph').value = module.morph;\n\n // CV input gain node \u2014 engine connects modulation sources here.\n const vowelCV = ctx.createGain();\n vowelCV.gain.value = 1;\n vowelCV.connect(formantWorklet);\n\n // Splitter to route 5-channel worklet output to individual filter frequencies\n const splitter = ctx.createChannelSplitter(5);\n formantWorklet.connect(splitter);\n\n // Connect each worklet output channel \u2192 filter frequency AudioParam\n splitter.connect(f1.frequency, 0);\n splitter.connect(f2.frequency, 1);\n splitter.connect(f3.frequency, 2);\n splitter.connect(f4.frequency, 3);\n splitter.connect(f5.frequency, 4);\n\n // Set base filter frequencies to 0 since worklet drives them\n f1.frequency.value = 0;\n f2.frequency.value = 0;\n f3.frequency.value = 0;\n f4.frequency.value = 0;\n f5.frequency.value = 0;\n\n f1.type = 'bandpass';\n f2.type = 'bandpass';\n f3.type = 'bandpass';\n f4.type = 'bandpass';\n f5.type = 'bandpass';\n f1.Q.value = module.resonance * 0.5;\n f2.Q.value = module.resonance * 0.4;\n f3.Q.value = module.resonance * 0.3;\n // F4/F5 are presence/air formants \u2014 narrower Q, lower gain\n f4.Q.value = module.resonance * 0.25;\n f5.Q.value = module.resonance * 0.2;\n\n dryGain.gain.value = 1 - module.mix;\n wetGain.gain.value = module.mix;\n formantMix.gain.value = 2.0;\n\n // F4/F5 at reduced level \u2014 they add presence without dominating\n const f4Gain = ctx.createGain();\n const f5Gain = ctx.createGain();\n f4Gain.gain.value = 0.5;\n f5Gain.gain.value = 0.35;\n\n input.connect(dryGain);\n input.connect(f1);\n input.connect(f2);\n input.connect(f3);\n input.connect(f4);\n input.connect(f5);\n f1.connect(formantMix);\n f2.connect(formantMix);\n f3.connect(formantMix);\n f4.connect(f4Gain);\n f5.connect(f5Gain);\n f4Gain.connect(formantMix);\n f5Gain.connect(formantMix);\n formantMix.connect(wetGain);\n dryGain.connect(output);\n wetGain.connect(output);\n\n // Chrome cuts silent-input biquad rings early \u2014 see dsp/keepAlive.ts.\n const _alive = createKeepAlive(ctx, f1, f2, f3, f4, f5);\n\n return { input, output, vowelCV, f1, f2, f3, f4, f5, f4Gain, f5Gain, dryGain, wetGain, formantWorklet, _alive };\n },\n\n updateParam(nodes, _module, param, value) {\n if (param === 'morph') {\n (nodes.formantWorklet.parameters as any).get('baseMorph').value = value as number;\n } else if (param === 'resonance') {\n const r = value as number;\n nodes.f1.Q.value = r * 0.5;\n nodes.f2.Q.value = r * 0.4;\n nodes.f3.Q.value = r * 0.3;\n nodes.f4.Q.value = r * 0.25;\n nodes.f5.Q.value = r * 0.2;\n } else if (param === 'mix') {\n nodes.dryGain.gain.value = 1 - (value as number);\n nodes.wetGain.gain.value = value as number;\n }\n },\n\n dispose(nodes) {\n nodes._alive.stop();\n },\n\n});\n", "import { defineModule } from '../../core';\nimport { formantDescriptor } from './formant';\nimport type { FormantParams, FormantInputs, FormantOutputs, FormantProps } from './formant.types';\nimport formant_table from '../worklet-src/formant-table';\n\nexport const Formant = /* @__PURE__ */ defineModule(formantDescriptor, {\n worklets: {\n 'formant-table': formant_table,\n },\n}) as import('../../core').LibModule<FormantParams, FormantInputs, FormantOutputs, FormantProps>;\nexport type { FormantParams, FormantInputs, FormantOutputs, FormantProps };\n", "// @ts-nocheck \u2014 generated by scripts/lib/build.ts\nimport { BaseModule } from '@/types/synth';\nimport { defineDescriptor, paramDefaults } from '@/modules/ModuleDescriptor';\nimport { createFreqShifterNode } from '@/worklets';\nimport { createMix } from '@/lib/dsp/mix';\n\nexport interface FreqShifterModule extends BaseModule {\n type: 'freq-shifter';\n shift: number;\n mix: number;\n}\n\n// \u2500\u2500\u2500 PARAMS \u2014 the signal contract \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n// `shift` drives the worklet's own `shift` AudioParam 1:1 (Hz). `mix` used\n// to be two direct .gain.value writes on dryGain/wetGain \u2014 not a single\n// AudioParam \u2014 so it now runs through createMix's ConstantSource (`_mix`),\n// linear law, preserving the original 1-mix/mix levels exactly.\nconst params = {\n shift: { node: 'shifter', field: 'shift', unit: 'Hz', default: 0, min: -500, max: 500, },\n mix: { node: '_mix', field: 'offset', unit: 'factor', default: 1.0, min: 0, max: 1, },\n} satisfies Record<string, ParamSpec>;\n\n\n// \u2500\u2500\u2500 DESCRIPTOR \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport const freqShifterDescriptor = /* @__PURE__ */ defineDescriptor({\n type: 'freq-shifter',\n params,\n\n\n ports: {\n 'in': { type: 'input', signal: 'audio', node: 'input', },\n 'out': { type: 'output', signal: 'audio', node: 'output', },\n 'modShift': { type: 'modulation', signal: 'modulation', node: 'shifter', field: 'shift' },\n },\n\n createModule(id, position) {\n return { id, type: 'freq-shifter', position, ...paramDefaults(params) } as FreqShifterModule;\n },\n\n createNodes(ctx, module) {\n const input = ctx.createGain();\n const output = ctx.createGain();\n const dryGain = ctx.createGain();\n const wetGain = ctx.createGain();\n\n // Real SSB shifter: Hilbert allpass pair + quadrature oscillator (worklet)\n const shifter = createFreqShifterNode(ctx, module.shift);\n\n const _mix = createMix(ctx, dryGain, wetGain, module.mix, 'linear');\n\n input.connect(dryGain);\n input.connect(shifter);\n shifter.connect(wetGain);\n dryGain.connect(output);\n wetGain.connect(output);\n\n return { input, output, shifter, dryGain, wetGain, _mix };\n },\n\n updateParam(nodes, _m, param, value) {\n if (param === 'shift') {\n const p = (nodes.shifter as AudioWorkletNode).parameters.get('shift')!;\n p.setTargetAtTime(value as number, nodes.shifter.context.currentTime, 0.01);\n } else if (param === 'mix') {\n (nodes._mix as ConstantSourceNode).offset.value = value as number;\n }\n },\n\n});\n", "import { defineModule } from '../../core';\nimport { freqShifterDescriptor } from './freq-shifter';\nimport type { FrequencyShifterParams, FrequencyShifterInputs, FrequencyShifterOutputs, FrequencyShifterProps } from './freq-shifter.types';\nimport freq_shifter from '../worklet-src/freq-shifter';\n\nexport const FrequencyShifter = /* @__PURE__ */ defineModule(freqShifterDescriptor, {\n worklets: {\n 'freq-shifter': freq_shifter,\n },\n}) as import('../../core').LibModule<FrequencyShifterParams, FrequencyShifterInputs, FrequencyShifterOutputs, FrequencyShifterProps>;\nexport type { FrequencyShifterParams, FrequencyShifterInputs, FrequencyShifterOutputs, FrequencyShifterProps };\n", "// @ts-nocheck \u2014 generated by scripts/lib/build.ts\nimport type { BaseModule, Position } from '@/types/synth';\nimport { createEnvFollowerNode } from '@/worklets';\n\nexport interface GateModule extends BaseModule {\n type: 'gate';\n threshold: number;\n range: number;\n attack: number;\n release: number;\n}\nimport { defineDescriptor, paramDefaults } from '@/modules/ModuleDescriptor';\n\n// \u2500\u2500\u2500 PARAMS \u2014 the signal contract (no UI knowledge) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nconst params = {\n // threshold/range rebuild the gateShaper curve \u2014 not a 1:1 AudioParam\n // write \u2014 so no node/field.\n threshold: { unit: 'dB', default: -40, min: -60, max: 0, },\n range: { unit: 'factor', default: 0.8, min: 0, max: 1, },\n attack: { node: 'envFollower', field: 'attack', unit: 's', default: 0.005, min: 0.001, max: 0.05, scale: 'log', },\n release: { node: 'envFollower', field: 'release', unit: 's', default: 0.1, min: 0.01, max: 0.5, scale: 'log', },\n} satisfies Record<string, ParamSpec>;\n\n\n\n/**\n * WaveShaper indexes its curve across the BIPOLAR input domain [-1, +1]:\n * index = floor((x + 1) / 2 * (len - 1))\n * The envelope follower feeds a unipolar [0, 1] signal, so the curve must be\n * built over the bipolar domain and the threshold compared against that same\n * mapping \u2014 otherwise only the top half of the table is ever addressed and the\n * gate never closes for thresholds below ~-6 dB.\n *\n * A small hysteresis-free soft knee (~2 dB) avoids zipper/chatter on material\n * hovering around the threshold.\n */\nfunction makeGateCurve(threshold: number, range: number): Float32Array {\n const threshLinear = Math.pow(10, threshold / 20);\n const kneeLow = Math.pow(10, (threshold - 2) / 20); // 2 dB soft knee below threshold\n const closed = 1.0 - range;\n const gsLen = 32768; // fine resolution: low thresholds occupy few table slots\n const gsCurve = new Float32Array(gsLen);\n for (let i = 0; i < gsLen; i++) {\n const x = (i / (gsLen - 1)) * 2 - 1; // bipolar input value at this index\n const env = Math.max(0, x); // envelope is unipolar; negative half unused\n let g: number;\n if (env >= threshLinear) g = 1.0;\n else if (env <= kneeLow) g = closed;\n else g = closed + (1.0 - closed) * ((env - kneeLow) / (threshLinear - kneeLow));\n gsCurve[i] = g;\n }\n return gsCurve;\n}\n\n\nexport const gateDescriptor = /* @__PURE__ */ defineDescriptor({\n type: 'gate' as const,\n params,\n\n ports: {\n 'in': { type: 'input' as const, signal: 'audio' as const, node: 'input', },\n 'out': { type: 'output' as const, signal: 'audio' as const, node: 'output', },\n },\n\n createModule(id: string, position: Position): GateModule {\n return { id, type: 'gate', position, ...paramDefaults(params) };\n },\n\n createNodes(ctx, module) {\n const input = ctx.createGain();\n const output = ctx.createGain();\n const gateGain = ctx.createGain();\n\n // Worklet: sample-accurate asymmetric envelope follower\n const envFollower = createEnvFollowerNode(ctx);\n (envFollower.parameters as any).get('attack').value = module.attack;\n (envFollower.parameters as any).get('release').value = module.release;\n\n // Gate shaper: converts envelope level to gate on/off based on threshold\n const gateShaper = ctx.createWaveShaper();\n gateShaper.curve = makeGateCurve(module.threshold, module.range) as Float32Array<ArrayBuffer>;\n\n gateGain.gain.value = 0;\n input.connect(envFollower);\n envFollower.connect(gateShaper);\n gateShaper.connect(gateGain.gain);\n\n input.connect(gateGain);\n gateGain.connect(output);\n\n return { input, output, envFollower, gateShaper };\n },\n\n updateParam(nodes, module, param, value) {\n if (param === 'threshold' || param === 'range') {\n const thresh = param === 'threshold' ? value as number : module.threshold;\n const range = param === 'range' ? value as number : module.range;\n nodes.gateShaper.curve = makeGateCurve(thresh, range) as Float32Array<ArrayBuffer>;\n } else if (param === 'attack') {\n (nodes.envFollower.parameters as any).get('attack').value = value as number;\n } else if (param === 'release') {\n (nodes.envFollower.parameters as any).get('release').value = value as number;\n }\n },\n\n});\n", "import { defineModule } from '../../core';\nimport { gateDescriptor } from './gate';\nimport type { GateParams, GateInputs, GateOutputs, GateProps } from './gate.types';\nimport env_follower from '../worklet-src/env-follower';\n\nexport const Gate = /* @__PURE__ */ defineModule(gateDescriptor, {\n worklets: {\n 'env-follower': env_follower,\n },\n}) as import('../../core').LibModule<GateParams, GateInputs, GateOutputs, GateProps>;\nexport type { GateParams, GateInputs, GateOutputs, GateProps };\n", "// @ts-nocheck \u2014 generated by scripts/lib/build.ts\nimport { BaseModule } from '@/types/synth';\nimport { defineDescriptor, paramDefaults } from '@/modules/ModuleDescriptor';\nimport { createGlideNode } from '@/worklets';\n\nexport interface GlideModule extends BaseModule {\n type: 'glide';\n time: number;\n}\n\n// \u2500\u2500\u2500 PARAMS \u2014 the signal contract \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n// `time` drives the worklet's own `time` AudioParam 1:1.\nconst params = {\n time: { node: '_glide', field: 'time', unit: 's', default: 0.1, min: 0.01, max: 10, scale: 'log', },\n} satisfies Record<string, ParamSpec>;\n\n\n// \u2500\u2500\u2500 DESCRIPTOR \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport const glideDescriptor = /* @__PURE__ */ defineDescriptor({\n type: 'glide',\n params,\n\n\n ports: {\n 'in': { type: 'input', signal: 'pitch', node: '_glide', },\n 'gate': { type: 'input', signal: 'gate', node: '_gateIn', },\n 'out': { type: 'output', signal: 'pitch', node: 'output', },\n },\n\n createModule(id, position) {\n return { id, type: 'glide', position, ...paramDefaults(params) } as GlideModule;\n },\n\n createNodes(ctx, module) {\n const _glide = createGlideNode(ctx);\n _glide.parameters.get('time')!.value = module.time;\n\n const output = ctx.createGain();\n output.gain.value = 1;\n _glide.connect(output);\n\n // Gate input gain node \u2014 gate signal connects here, feeds worklet input 1\n const _gateIn = ctx.createGain();\n _gateIn.gain.value = 1;\n _gateIn.connect(_glide, 0, 1);\n\n return { _glide, _gateIn, output };\n },\n\n updateParam(nodes, _m, param, value) {\n if (param === 'time') {\n nodes._glide.parameters.get('time')!.value = value as number;\n }\n },\n\n});\n", "import { defineModule } from '../../core';\nimport { glideDescriptor } from './glide';\nimport type { GlideParams, GlideInputs, GlideOutputs, GlideProps } from './glide.types';\nimport glide from '../worklet-src/glide';\n\nexport const Glide = /* @__PURE__ */ defineModule(glideDescriptor, {\n worklets: {\n 'glide': glide,\n },\n}) as import('../../core').LibModule<GlideParams, GlideInputs, GlideOutputs, GlideProps>;\nexport type { GlideParams, GlideInputs, GlideOutputs, GlideProps };\n", "// @ts-nocheck \u2014 generated by scripts/lib/build.ts\n\nimport { createMix } from '@/lib/dsp/mix';\nimport { BaseModule } from '@/types/synth';\n\nexport interface HaasModule extends BaseModule {\n type: 'haas';\n delay: number;\n side: 'left' | 'right';\n mix: number;\n}\nimport { defineDescriptor, paramDefaults } from '@/modules/ModuleDescriptor';\n\n// \u2500\u2500\u2500 PARAMS \u2014 the signal contract (no UI knowledge) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n// `delay` converts ms \u2192 seconds before it reaches delayNode.delayTime, so it\n// stays set-only (an honest 1:1 param can't carry a unit conversion). `mix`\n// is a real dry/wet crossfade of the delayed channel (directBleed/delayedGain),\n// so it is rebuilt on createMix and exposed 1:1. `side` re-routes the merger\n// on change \u2014 not a single AudioParam \u2014 so it stays a set-only enum.\nconst params = {\n delay: { unit: 'ms', default: 15, min: 1, max: 35, },\n side: { kind: 'enum', default: 'right', options: ['left', 'right'], },\n mix: { node: '_mix', field: 'offset', unit: 'factor', default: 1, min: 0, max: 1, },\n} satisfies Record<string, ParamSpec>;\n\n\n\n// nodes: [input, output, delayNode, directGain, delayedGain, directBleed, merger, _mix]\nexport const haasDescriptor = /* @__PURE__ */ defineDescriptor({\n type: 'haas',\n params,\n\n ports: {\n 'in': { type: 'input', signal: 'audio', node: 'input', },\n 'out': { type: 'output', signal: 'audio', node: 'output', },\n },\n\n createModule(id, position) {\n return { id, type: 'haas', position, ...paramDefaults(params) } as HaasModule;\n },\n\n createNodes(ctx, module) {\n const input = ctx.createGain();\n const output = ctx.createGain();\n const delayNode = ctx.createDelay(0.05);\n const directGain = ctx.createGain();\n const delayedGain = ctx.createGain();\n // Mono-integrity leg (2026-08-08 fix): the delayed-side channel\n // crossfades between the DIRECT signal (mix 0) and the DELAYED signal\n // (mix 1). Before this, MIX 0 left the delayed channel SILENT \u2014 the\n // \"widener\" hard-panned the input to one side and the mono sum lost\n // 6.02 dB (probe:haas-dry). Same fault class as the DIM mono-silencing\n // bug: a channel nobody feeds. MIX 0 now means mono passthrough.\n // directBleed (dry) / delayedGain (wet) crossfade on ONE ConstantSource\n // (`_mix`), same as delay.ts, so `mix` is an honest 1:1 AudioParam.\n const directBleed = ctx.createGain();\n const merger = ctx.createChannelMerger(2);\n const _mix = createMix(ctx, directBleed, delayedGain, module.mix, 'linear');\n\n delayNode.delayTime.value = module.delay / 1000;\n directGain.gain.value = 1;\n\n input.connect(directGain);\n input.connect(directBleed);\n input.connect(delayNode);\n delayNode.connect(delayedGain);\n\n if (module.side === 'right') {\n directGain.connect(merger, 0, 0);\n delayedGain.connect(merger, 0, 1);\n directBleed.connect(merger, 0, 1);\n } else {\n delayedGain.connect(merger, 0, 0);\n directBleed.connect(merger, 0, 0);\n directGain.connect(merger, 0, 1);\n }\n merger.connect(output);\n\n return { input, output, delayNode, directGain, delayedGain, directBleed, merger, _mix };\n },\n\n updateParam(nodes, _m, param, value) {\n if (param === 'delay') {\n nodes.delayNode.delayTime.value = (value as number) / 1000;\n } else if (param === 'mix') {\n (nodes._mix as ConstantSourceNode).offset.value = value as number;\n } else if (param === 'side') {\n try { nodes.directGain.disconnect(nodes.merger); } catch (_) {}\n try { nodes.delayedGain.disconnect(nodes.merger); } catch (_) {}\n try { nodes.directBleed.disconnect(nodes.merger); } catch (_) {}\n if (value === 'right') {\n nodes.directGain.connect(nodes.merger, 0, 0);\n nodes.delayedGain.connect(nodes.merger, 0, 1);\n nodes.directBleed.connect(nodes.merger, 0, 1);\n } else {\n nodes.delayedGain.connect(nodes.merger, 0, 0);\n nodes.directBleed.connect(nodes.merger, 0, 0);\n nodes.directGain.connect(nodes.merger, 0, 1);\n }\n }\n },\n\n});\n", "import { defineModule } from '../../core';\nimport { haasDescriptor } from './haas';\nimport type { HaasWidenerParams, HaasWidenerInputs, HaasWidenerOutputs, HaasWidenerProps } from './haas.types';\n\n\nexport const HaasWidener = /* @__PURE__ */ defineModule(haasDescriptor) as import('../../core').LibModule<HaasWidenerParams, HaasWidenerInputs, HaasWidenerOutputs, HaasWidenerProps>;\nexport type { HaasWidenerParams, HaasWidenerInputs, HaasWidenerOutputs, HaasWidenerProps };\n", "// @ts-nocheck \u2014 generated by scripts/lib/build.ts\nimport type { BaseModule, Position } from '@/types/synth';\n\nexport interface HarmonicTremModule extends BaseModule {\n type: 'harmonic-trem';\n rate: number;\n depth: number;\n crossover: number;\n}\nimport { defineDescriptor, paramDefaults } from '@/modules/ModuleDescriptor';\n\nconst params = {\n rate: { node: 'lfo', field: 'frequency', unit: 'Hz', default: 4, min: 1, max: 10, },\n depth: { unit: 'factor', default: 0.7, min: 0, max: 1, },\n crossover: { node: 'lowpass', field: 'frequency', unit: 'Hz', default: 800, min: 200, max: 2000, },\n} satisfies Record<string, ParamSpec>;\n\n\n\nexport const harmonicTremDescriptor = /* @__PURE__ */ defineDescriptor({\n type: 'harmonic-trem' as const,\n params,\n\n ports: {\n 'in': { type: 'input' as const, signal: 'audio' as const, node: 'input', },\n 'out': { type: 'output' as const, signal: 'audio' as const, node: 'output', },\n 'modRate': { type: 'modulation', signal: 'modulation', node: 'lfo', field: 'frequency' },\n 'modCrossover': { type: 'modulation', signal: 'modulation', node: 'lowpass', field: 'frequency' },\n },\n\n createModule(id: string, position: Position): HarmonicTremModule {\n return { id, type: 'harmonic-trem', position, ...paramDefaults(params) };\n },\n\n createNodes(ctx, module) {\n const input = ctx.createGain();\n const output = ctx.createGain();\n const lowpass = ctx.createBiquadFilter();\n const lpInvert = ctx.createGain();\n const highBand = ctx.createGain();\n const lowGain = ctx.createGain();\n const highGain = ctx.createGain();\n const lfo = ctx.createOscillator();\n const lfoGainLow = ctx.createGain();\n const lfoGainHigh = ctx.createGain();\n const lfoInvert = ctx.createGain();\n\n lowpass.type = 'lowpass';\n lowpass.frequency.value = module.crossover;\n lowpass.Q.value = -6.0206; // dB \u2192 Q_lin 0.5\n lpInvert.gain.value = -1;\n highBand.gain.value = 1;\n\n lfo.type = 'sine'; lfo.frequency.value = module.rate;\n lfoGainLow.gain.value = module.depth * 0.5;\n lfoGainHigh.gain.value = module.depth * 0.5;\n lfoInvert.gain.value = -1;\n lowGain.gain.value = 1;\n highGain.gain.value = 1;\n\n input.connect(lowpass);\n input.connect(highBand);\n lowpass.connect(lpInvert);\n lpInvert.connect(highBand);\n lfo.connect(lfoGainLow);\n lfo.connect(lfoInvert);\n lfoInvert.connect(lfoGainHigh);\n lfoGainLow.connect(lowGain.gain);\n lfoGainHigh.connect(highGain.gain);\n lowpass.connect(lowGain);\n highBand.connect(highGain);\n lowGain.connect(output);\n highGain.connect(output);\n lfo.start();\n\n return { input, output, lfo, lfoGainLow, lfoGainHigh, lowpass, lpInvert, highBand };\n },\n\n updateParam(nodes, _m, param, value) {\n if (param === 'rate') nodes.lfo.frequency.value = value as number;\n else if (param === 'depth') {\n nodes.lfoGainLow.gain.value = (value as number) * 0.5;\n nodes.lfoGainHigh.gain.value = (value as number) * 0.5;\n } else if (param === 'crossover') {\n nodes.lowpass.frequency.value = value as number;\n }\n },\n\n dispose(nodes) {\n nodes.lfo.stop();\n },\n\n});\n", "import { defineModule } from '../../core';\nimport { harmonicTremDescriptor } from './harmonic-trem';\nimport type { HarmonicTremoloParams, HarmonicTremoloInputs, HarmonicTremoloOutputs, HarmonicTremoloProps } from './harmonic-trem.types';\n\n\nexport const HarmonicTremolo = /* @__PURE__ */ defineModule(harmonicTremDescriptor) as import('../../core').LibModule<HarmonicTremoloParams, HarmonicTremoloInputs, HarmonicTremoloOutputs, HarmonicTremoloProps>;\nexport type { HarmonicTremoloParams, HarmonicTremoloInputs, HarmonicTremoloOutputs, HarmonicTremoloProps };\n", "// @ts-nocheck \u2014 generated by scripts/lib/build.ts\nimport type { BaseModule, Position } from '@/types/synth';\n\nimport { defineDescriptor, paramDefaults } from '@/modules/ModuleDescriptor';\nimport { createLadderFilterNode, createVoctFreqNode } from '@/worklets';\n\nexport interface LadderFilterModule extends BaseModule {\n type: 'ladder-filter';\n /** Cutoff as a note (69 = 440 Hz), driving the V/OCT worklet 1:1. */\n note: number;\n resonance: number; // 0\u20134 stored (UI shows % of travel); worklet param is resonance/4\n drive: number;\n}\n\n/** Worklet resonance at knob max: 1.0 is oscillation onset (k = 4), so land\n * a bit past it \u2014 100% RES must ring up confidently, like hardware. */\nconst RES_TOP = 1.1;\n\n// \u2500\u2500\u2500 PARAMS \u2014 the signal contract (no UI knowledge) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nconst params = {\n note: { node: '_cutoffVoct', field: 'transpose', unit: 'note', default: 83, min: 15, max: 135, },\n // Stored 0\u20134 (UI shows % of travel) but the worklet's resonance param is\n // resonance/4\u00B7RES_TOP \u2014 a scale, not a 1:1 mapping \u2014 so this stays set-only.\n resonance: { unit: 'factor', default: 2.5, min: 0, max: 4, scale: 'sqrt', },\n drive: { node: 'ladder', field: 'drive', unit: 'factor', default: 0.3, min: 0, max: 1, },\n} satisfies Record<string, ParamSpec>;\n\n// \u2500\u2500\u2500 UI \u2014 presentation layer (stripped from the library) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n\n// \u2500\u2500\u2500 DESCRIPTOR \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport const ladderFilterDescriptor = /* @__PURE__ */ defineDescriptor({\n type: 'ladder-filter',\n params,\n\n ports: {\n 'in': { type: 'input', signal: 'audio', node: 'input', },\n 'out': { type: 'output', signal: 'audio', node: 'output', },\n 'modFreq': { type: 'modulation', signal: 'modulation', node: '_cutoffVoct', },\n 'modRes': { type: 'modulation', signal: 'modulation', node: 'ladder', field: 'resonance' },\n },\n\n createModule(id: string, position: Position): LadderFilterModule {\n return { id, type: 'ladder-filter', position, ...paramDefaults(params) };\n },\n\n createNodes(ctx, module) {\n const input = ctx.createGain();\n const output = ctx.createGain();\n\n // The whole filter lives in one worklet: 4 one-pole stages with a global\n // tanh-saturated feedback path (see worklets/ladder-filter.ts). Drive is\n // an input-stage saturation *inside* the loop, so no external waveshaper.\n // Knob max maps to 1.1 (k = 4.4), a little PAST oscillation onset (1.0),\n // so 100% RES rings up confidently instead of hovering at the threshold \u2014\n // hardware ladders behave the same at max resonance.\n const ladder = createLadderFilterNode(ctx, {\n resonance: (module.resonance / 4) * RES_TOP,\n drive: module.drive,\n });\n\n // V/Oct cutoff: ConstantSource(0) \u2192 voct(transpose=cutoff note) \u2192 cutoff param\n const _cutoffVoct = createVoctFreqNode(ctx);\n _cutoffVoct.parameters.get('transpose')!.value = module.note;\n\n const _cutoffBase = ctx.createConstantSource();\n _cutoffBase.offset.value = 0;\n _cutoffBase.start();\n _cutoffBase.connect(_cutoffVoct);\n _cutoffVoct.connect(ladder.parameters.get('cutoff')! as AudioParam);\n\n input.connect(ladder);\n ladder.connect(output);\n\n return { input, output, ladder, _cutoffVoct, _cutoffBase };\n },\n\n updateParam(nodes, _module, param, value) {\n switch (param) {\n case 'note':\n nodes._cutoffVoct.parameters.get('transpose')!.value = value as number;\n break;\n case 'resonance':\n nodes.ladder.parameters.get('resonance')!.value = ((value as number) / 4) * RES_TOP;\n break;\n case 'drive':\n nodes.ladder.parameters.get('drive')!.value = value as number;\n break;\n }\n },\n\n dispose(nodes) {\n try { nodes._cutoffBase.stop(); } catch (_) { /* already stopped */ }\n },\n\n});\n", "import { defineModule } from '../../core';\nimport { ladderFilterDescriptor } from './ladder-filter';\nimport type { LadderFilterParams, LadderFilterInputs, LadderFilterOutputs, LadderFilterProps } from './ladder-filter.types';\nimport ladder_filter from '../worklet-src/ladder-filter';\nimport map_voct_to_freq from '../worklet-src/map-voct-to-freq';\n\nexport const LadderFilter = /* @__PURE__ */ defineModule(ladderFilterDescriptor, {\n worklets: {\n 'ladder-filter': ladder_filter,\n 'map-voct-to-freq': map_voct_to_freq,\n },\n}) as import('../../core').LibModule<LadderFilterParams, LadderFilterInputs, LadderFilterOutputs, LadderFilterProps>;\nexport type { LadderFilterParams, LadderFilterInputs, LadderFilterOutputs, LadderFilterProps };\n", "// @ts-nocheck \u2014 generated by scripts/lib/build.ts\nimport type { BaseModule, Position } from '@/types/synth';\n\nexport interface LFOModule extends BaseModule {\n type: 'lfo';\n skew: number; // -1\u20131\n shape: number; // -1\u20131\n frequency: number;\n amount: number;\n}\nimport { defineDescriptor, paramDefaults } from '@/modules/ModuleDescriptor';\nimport { createWaveshaperNode } from '@/worklets';\n\n// \u2500\u2500\u2500 Waveform \u2192 skew/shape mapping for migration \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nconst WAVE_MAP: Record<string, { skew: number; shape: number }> = {\n sine: { skew: 0.0, shape: 1.0 },\n triangle: { skew: 0.0, shape: 0.0 },\n square: { skew: 0.0, shape: -1.0 },\n sawtooth: { skew: 1.0, shape: 0.0 },\n};\n\n// \u2500\u2500\u2500 PARAMS \u2014 the signal contract (no UI knowledge) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n// Canonical DSP identity, range and behaviour. Drives createModule\n// defaults, library param types and library docs. Wording describes the\n// signal, never a panel control.\nconst params = {\n skew: { node: '_ws', field: 'skew', unit: 'factor', default: 0, min: -1, max: 1, },\n shape: { node: '_ws', field: 'shape', unit: 'factor', default: 1, min: -1, max: 1, },\n frequency: { node: '_freqSrc', field: 'offset', default: 2, min: -10, max: 20, unit: 'Hz', },\n amount: { node: 'gain', field: 'gain', unit: 'semitone', default: 12, min: 0, max: 500, scale: 'sqrt', },\n} satisfies Record<string, ParamSpec>;\n\n// \u2500\u2500\u2500 UI \u2014 presentation layer (stripped from the library) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n// Panel labels, knob ranges and hover tips optimised for playing the\n// module. Free to diverge from `params`: e.g. the frequency knob becomes\n// a bipolar OFFSET when Rate CV is patched, and AMT reads BASE under CV.\n\nconst rateKnob = (cv: boolean) => cv\n ? { label: 'OFFSET', min: -10, max: 10, log: false, format: (v: number) => `${v >= 0 ? '+' : ''}${Math.abs(v) < 1 ? v.toFixed(2) : v.toFixed(1)}` }\n : { label: 'RATE', min: 0.01, max: 20, log: true, format: (v: number) => (v < 1 ? v.toFixed(2) : v.toFixed(1)) };\n\n\n// \u2500\u2500\u2500 DESCRIPTOR \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport const lfoDescriptor = /* @__PURE__ */ defineDescriptor({\n type: 'lfo',\n params,\n\n\n\n ports: {\n 'out': { type: 'output', node: 'gain', signal: 'modulation' },\n 'modRate': { type: 'modulation', signal: 'modulation', node: '_freqSrc', field: 'offset' },\n 'modAmount': { type: 'modulation', signal: 'modulation', node: 'gain', field: 'gain' },\n 'modSkew': { type: 'modulation', signal: 'modulation', node: '_ws', field: 'skew' },\n 'modShape': { type: 'modulation', signal: 'modulation', node: '_ws', field: 'shape' },\n \n },\n\n\n createModule(id: string, position: Position): LFOModule {\n return { id, type: 'lfo', position, ...paramDefaults(params) };\n },\n\n createNodes(ctx, module) {\n const _ws = createWaveshaperNode(ctx);\n const gain = ctx.createGain();\n // Feed frequency via ConstantSource\n const _freqSrc = ctx.createConstantSource();\n _freqSrc.offset.value = module.frequency;\n _freqSrc.start();\n _freqSrc.connect(_ws); // frequency input\n\n // Set waveshape\n _ws.parameters.get('skew')!.value = module.skew;\n _ws.parameters.get('shape')!.value = module.shape;\n\n gain.gain.value = module.amount;\n _ws.connect(gain);\n\n return { gain, _ws, _freqSrc };\n },\n\n updateParam(nodes, _module, param, value) {\n switch (param) {\n case 'skew': nodes._ws.parameters.get('skew')!.value = value as number; break;\n case 'shape': nodes._ws.parameters.get('shape')!.value = value as number; break;\n case 'frequency': nodes._freqSrc.offset.value = value as number; break;\n case 'amount': nodes.gain.gain.value = value as number; break;\n }\n },\n\n dispose(nodes) {\n nodes._freqSrc.stop();\n },\n\n});\n", "import { defineModule } from '../../core';\nimport { lfoDescriptor } from './lfo';\nimport type { LfoParams, LfoInputs, LfoOutputs, LfoProps } from './lfo.types';\nimport waveshaper from '../worklet-src/waveshaper';\n\nexport const Lfo = /* @__PURE__ */ defineModule(lfoDescriptor, {\n worklets: {\n 'waveshaper': waveshaper,\n },\n}) as import('../../core').LibModule<LfoParams, LfoInputs, LfoOutputs, LfoProps>;\nexport type { LfoParams, LfoInputs, LfoOutputs, LfoProps };\n", "// @ts-nocheck \u2014 generated by scripts/lib/build.ts\nimport { noiseSource, NOISE_SEEDS } from '@/lib/dsp/prng';\nimport { BaseModule } from '@/types/synth';\n\nexport interface LoFiModule extends BaseModule {\n type: 'lo-fi';\n drive: number;\n cutoff: number;\n noise: number;\n wobble: number;\n}\nimport { defineDescriptor, paramDefaults } from '@/modules/ModuleDescriptor';\n\nfunction makeLoFiSaturationCurve(amount: number): Float32Array {\n const samples = 44100;\n const curve = new Float32Array(samples);\n const k = 1 + amount * 5;\n for (let i = 0; i < samples; i++) {\n const x = (i * 2) / samples - 1;\n curve[i] = x >= 0 ? Math.tanh(k * x * 0.8) : Math.tanh(k * x * 1.2);\n }\n return curve;\n}\n\nconst params = {\n drive: { unit: 'factor', default: 0.3, min: 0, max: 1, },\n cutoff: { node: 'lowpass', field: 'frequency', unit: 'Hz', default: 4000, min: 500, max: 8000, },\n noise: { unit: 'factor', default: 0.2, min: 0, max: 1, },\n wobble: { unit: 'factor', default: 0.1, min: 0, max: 1, },\n} satisfies Record<string, ParamSpec>;\n\n\n\nexport const loFiDescriptor = /* @__PURE__ */ defineDescriptor({\n type: 'lo-fi',\n params,\n\n ports: {\n 'in': { type: 'input', signal: 'audio', node: 'input', },\n 'out': { type: 'output', signal: 'audio', node: 'output', },\n 'modCutoff': { type: 'modulation', signal: 'modulation', node: 'lowpass', field: 'frequency' },\n },\n\n createModule(id, position) {\n return { id, type: 'lo-fi', position, ...paramDefaults(params) };\n },\n\n createNodes(ctx, module) {\n const input = ctx.createGain();\n const output = ctx.createGain();\n const saturation = ctx.createWaveShaper();\n const lowpass = ctx.createBiquadFilter();\n const noiseGain = ctx.createGain();\n const wobbleLfo = ctx.createOscillator();\n const wobbleGain = ctx.createGain();\n\n saturation.curve = makeLoFiSaturationCurve(module.drive) as Float32Array<ArrayBuffer>;\n saturation.oversample = '2x';\n\n lowpass.type = 'lowpass';\n lowpass.frequency.value = module.cutoff;\n lowpass.Q.value = 0.7;\n\n const bufferSize = 2 * ctx.sampleRate;\n const noiseBuffer = ctx.createBuffer(1, bufferSize, ctx.sampleRate);\n const data = noiseBuffer.getChannelData(0);\n const rand = noiseSource(NOISE_SEEDS.loFiCrackle);\n let b0 = 0, b1 = 0, b2 = 0;\n for (let i = 0; i < bufferSize; i++) {\n const white = rand();\n b0 = 0.99765 * b0 + white * 0.0990460;\n b1 = 0.96300 * b1 + white * 0.2965164;\n b2 = 0.57000 * b2 + white * 1.0526913;\n data[i] = (b0 + b1 + b2) * 0.1;\n }\n const noiseSrc = ctx.createBufferSource();\n noiseSrc.buffer = noiseBuffer;\n noiseSrc.loop = true;\n noiseGain.gain.value = module.noise * 0.05;\n noiseSrc.connect(noiseGain);\n noiseSrc.start();\n\n const wobbleDelay = ctx.createDelay(0.05);\n wobbleDelay.delayTime.value = 0.01;\n wobbleLfo.type = 'sine';\n wobbleLfo.frequency.value = 0.73;\n wobbleGain.gain.value = module.wobble * 0.002;\n wobbleLfo.connect(wobbleGain);\n wobbleGain.connect(wobbleDelay.delayTime);\n wobbleLfo.start();\n\n input.connect(saturation);\n saturation.connect(lowpass);\n lowpass.connect(wobbleDelay);\n wobbleDelay.connect(output);\n noiseGain.connect(output);\n\n return { input, output, saturation, lowpass, wobbleDelay, noiseGain, wobbleGain, wobbleLfo, noiseSrc };\n },\n\n updateParam(nodes, _m, param, value) {\n if (param === 'drive') {\n nodes.saturation.curve = makeLoFiSaturationCurve(value as number) as Float32Array<ArrayBuffer>;\n } else if (param === 'cutoff') {\n nodes.lowpass.frequency.value = value as number;\n } else if (param === 'noise') {\n nodes.noiseGain.gain.value = (value as number) * 0.05;\n } else if (param === 'wobble') {\n nodes.wobbleGain.gain.value = (value as number) * 0.002;\n }\n },\n\n dispose(nodes) {\n nodes.wobbleLfo.stop();\n nodes.noiseSrc.stop();\n },\n\n});\n", "import { defineModule } from '../../core';\nimport { loFiDescriptor } from './lo-fi';\nimport type { LoFiParams, LoFiInputs, LoFiOutputs, LoFiProps } from './lo-fi.types';\n\n\nexport const LoFi = /* @__PURE__ */ defineModule(loFiDescriptor) as import('../../core').LibModule<LoFiParams, LoFiInputs, LoFiOutputs, LoFiProps>;\nexport type { LoFiParams, LoFiInputs, LoFiOutputs, LoFiProps };\n", "// @ts-nocheck \u2014 generated by scripts/lib/build.ts\nimport type { BaseModule, Position } from '@/types/synth';\n\nexport interface MidSideModule extends BaseModule {\n type: 'mid-side';\n midGain: number;\n sideGain: number;\n}\nimport { defineDescriptor, paramDefaults } from '@/modules/ModuleDescriptor';\n\n// \u2500\u2500\u2500 PARAMS \u2014 the signal contract \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n// sideGain used to be baked into ONE gain node as sideGain*width (not a\n// single AudioParam). Split into two chained gain stages so each param maps\n// 1:1 onto its own AudioParam.\nconst params = {\n midGain: { node: 'midGainNode', field: 'gain', unit: 'factor', default: 1, min: 0, max: 2, },\n sideGain: { node: 'sideGainNode', field: 'gain', unit: 'factor', default: 1, min: 0, max: 2, },\n} satisfies Record<string, ParamSpec>;\n\n\nexport const midSideDescriptor = /* @__PURE__ */ defineDescriptor({\n type: 'mid-side' as const,\n params,\n\n ports: {\n 'in': { type: 'input' as const, signal: 'audio', node: 'input', },\n 'out': { type: 'output' as const, signal: 'audio', node: 'output', },\n },\n\n createModule(id: string, position: Position): MidSideModule {\n return { id, type: 'mid-side', position, ...paramDefaults(params) };\n },\n\n createNodes(ctx, module) {\n // Force stereo interpretation so a mono source upmixes to L=R (side = 0)\n const input = ctx.createGain();\n input.channelCount = 2;\n input.channelCountMode = 'explicit';\n input.channelInterpretation = 'speakers';\n\n const output = ctx.createGain();\n const splitter = ctx.createChannelSplitter(2);\n const merger = ctx.createChannelMerger(2);\n\n // \u2500\u2500 Encode: M = (L+R)/2, S = (L-R)/2 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n const midSum = ctx.createGain(); // L + R, halved\n midSum.gain.value = 0.5;\n const sideSum = ctx.createGain(); // L - R, halved\n sideSum.gain.value = 0.5;\n const rInvEnc = ctx.createGain(); // -R for the difference\n rInvEnc.gain.value = -1;\n\n input.connect(splitter);\n splitter.connect(midSum, 0);\n splitter.connect(midSum, 1);\n splitter.connect(sideSum, 0);\n splitter.connect(rInvEnc, 1);\n rInvEnc.connect(sideSum);\n\n // \u2500\u2500 Gain stage on the M and S components \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n // sideGainNode and widthNode are two chained AudioParams (each 1:1 with\n // its own param) instead of one node carrying sideGain*width.\n const midGainNode = ctx.createGain();\n midGainNode.gain.value = module.midGain;\n const sideGainNode = ctx.createGain();\n sideGainNode.gain.value = module.sideGain;\n const widthNode = ctx.createGain();\n widthNode.gain.value = module.width;\n\n midSum.connect(midGainNode);\n sideSum.connect(sideGainNode);\n sideGainNode.connect(widthNode);\n\n // \u2500\u2500 Decode: L = M + S, R = M - S \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n const leftOut = ctx.createGain();\n const rightOut = ctx.createGain();\n const sideInvDec = ctx.createGain();\n sideInvDec.gain.value = -1;\n\n midGainNode.connect(leftOut);\n midGainNode.connect(rightOut);\n widthNode.connect(leftOut);\n widthNode.connect(sideInvDec);\n sideInvDec.connect(rightOut);\n\n leftOut.connect(merger, 0, 0);\n rightOut.connect(merger, 0, 1);\n merger.connect(output);\n\n return { input, output, midGainNode, sideGainNode, widthNode };\n },\n\n updateParam(nodes, _module, param, value) {\n if (param === 'midGain') nodes.midGainNode.gain.value = value as number;\n else if (param === 'sideGain') nodes.sideGainNode.gain.value = value as number;\n else if (param === 'width') nodes.widthNode.gain.value = value as number;\n },\n\n});\n", "import { defineModule } from '../../core';\nimport { midSideDescriptor } from './mid-side';\nimport type { MidSideParams, MidSideInputs, MidSideOutputs, MidSideProps } from './mid-side.types';\n\n\nexport const MidSide = /* @__PURE__ */ defineModule(midSideDescriptor) as import('../../core').LibModule<MidSideParams, MidSideInputs, MidSideOutputs, MidSideProps>;\nexport type { MidSideParams, MidSideInputs, MidSideOutputs, MidSideProps };\n", "// @ts-nocheck \u2014 generated by scripts/lib/build.ts\nimport { noiseSource, NOISE_SEEDS } from '@/lib/dsp/prng';\nimport type { BaseModule, Position, NoiseType } from '@/types/synth';\nimport { defineDescriptor, paramDefaults } from '@/modules/ModuleDescriptor';\n\nexport interface NoiseModule extends BaseModule {\n type: 'noise';\n noiseType: NoiseType;\n gain: number;\n}\n\n// \u2500\u2500\u2500 PARAMS \u2014 the signal contract \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n// `gain` maps 1:1 onto output.gain (updateParam still smooths it with\n// setTargetAtTime to avoid zippering when a modLevel CV sums on top).\n// `noiseType` cross-fades three pre-rendered buffers \u2014 not a single\n// AudioParam \u2014 so it stays a set-only enum.\nconst params = {\n noiseType: { kind: 'enum', default: 'white', options: ['white', 'pink', 'brown'], },\n gain: { node: 'output', field: 'gain', unit: 'factor', default: 0.3, min: 0, max: 1, },\n} satisfies Record<string, ParamSpec>;\n\n// \u2500\u2500\u2500 NOISE BUFFER GENERATION \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n// Seeded per type: the buffer loops every 2 s regardless, so this only picks\n// *which* random loop plays \u2014 inaudible, but it makes renders reproducible\n// (see src/lib/dsp/prng.ts).\n\nfunction generateNoiseBuffer(ctx: AudioContext, type: NoiseType): AudioBuffer {\n const bufferSize = 2 * ctx.sampleRate;\n const buffer = ctx.createBuffer(1, bufferSize, ctx.sampleRate);\n const data = buffer.getChannelData(0);\n\n if (type === 'white') {\n const rand = noiseSource(NOISE_SEEDS.noiseWhite);\n for (let i = 0; i < bufferSize; i++) data[i] = rand();\n } else if (type === 'pink') {\n const rand = noiseSource(NOISE_SEEDS.noisePink);\n let b0 = 0, b1 = 0, b2 = 0, b3 = 0, b4 = 0, b5 = 0, b6 = 0;\n for (let i = 0; i < bufferSize; i++) {\n const w = rand();\n b0 = 0.99886 * b0 + w * 0.0555179;\n b1 = 0.99332 * b1 + w * 0.0750759;\n b2 = 0.96900 * b2 + w * 0.1538520;\n b3 = 0.86650 * b3 + w * 0.3104856;\n b4 = 0.55000 * b4 + w * 0.5329522;\n b5 = -0.7616 * b5 - w * 0.0168980;\n data[i] = (b0 + b1 + b2 + b3 + b4 + b5 + b6 + w * 0.5362) * 0.11;\n b6 = w * 0.115926;\n }\n } else {\n const rand = noiseSource(NOISE_SEEDS.noiseBrown);\n let lastOut = 0;\n for (let i = 0; i < bufferSize; i++) {\n const w = rand();\n data[i] = (lastOut + 0.02 * w) / 1.02;\n lastOut = data[i];\n data[i] *= 3.5;\n }\n }\n return buffer;\n}\n\n// \u2500\u2500\u2500 UI \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nconst noiseOptions = [\n { value: 'white' as NoiseType, label: 'WHT' },\n { value: 'pink' as NoiseType, label: 'PNK' },\n { value: 'brown' as NoiseType, label: 'BRN' },\n];\n\n\n// \u2500\u2500\u2500 DESCRIPTOR \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport const noiseDescriptor = /* @__PURE__ */ defineDescriptor({\n type: 'noise',\n params,\n\n\n ports: {\n 'out': { type: 'output', signal: 'audio', node: 'output', },\n 'modLevel': { type: 'modulation', signal: 'modulation', node: 'output', field: 'gain' },\n },\n\n createModule(id: string, position: Position): NoiseModule {\n return { id, type: 'noise', position, ...paramDefaults(params) } as NoiseModule;\n },\n\n createNodes(ctx, module) {\n const whiteSrc = ctx.createBufferSource();\n whiteSrc.buffer = generateNoiseBuffer(ctx, 'white');\n whiteSrc.loop = true;\n const pinkSrc = ctx.createBufferSource();\n pinkSrc.buffer = generateNoiseBuffer(ctx, 'pink');\n pinkSrc.loop = true;\n const brownSrc = ctx.createBufferSource();\n brownSrc.buffer = generateNoiseBuffer(ctx, 'brown');\n brownSrc.loop = true;\n\n const whiteGain = ctx.createGain();\n const pinkGain = ctx.createGain();\n const brownGain = ctx.createGain();\n\n whiteGain.gain.value = module.noiseType === 'white' ? 1 : 0;\n pinkGain.gain.value = module.noiseType === 'pink' ? 1 : 0;\n brownGain.gain.value = module.noiseType === 'brown' ? 1 : 0;\n\n const output = ctx.createGain();\n output.gain.value = module.gain;\n\n whiteSrc.connect(whiteGain);\n pinkSrc.connect(pinkGain);\n brownSrc.connect(brownGain);\n whiteGain.connect(output);\n pinkGain.connect(output);\n brownGain.connect(output);\n\n whiteSrc.start(0);\n pinkSrc.start(0);\n brownSrc.start(0);\n\n return { output, whiteGain, pinkGain, brownGain, _whiteSrc: whiteSrc, _pinkSrc: pinkSrc, _brownSrc: brownSrc };\n },\n\n updateParam(nodes, _module, param, value) {\n const t = nodes.output.context.currentTime;\n switch (param) {\n case 'noiseType':\n nodes.whiteGain.gain.setTargetAtTime(value === 'white' ? 1 : 0, t, 0.005);\n nodes.pinkGain.gain.setTargetAtTime(value === 'pink' ? 1 : 0, t, 0.005);\n nodes.brownGain.gain.setTargetAtTime(value === 'brown' ? 1 : 0, t, 0.005);\n break;\n case 'gain':\n // Smoothed like noiseType above: a hard .value write stomps the\n // AudioParam's intrinsic value with no ramp, which zippers/clicks\n // when a modLevel CV is summing on top (noise report Finding #1).\n nodes.output.gain.setTargetAtTime(value as number, t, 0.005);\n break;\n }\n },\n\n dispose(nodes) {\n try { nodes._whiteSrc.stop(); } catch (_) {}\n try { nodes._pinkSrc.stop(); } catch (_) {}\n try { nodes._brownSrc.stop(); } catch (_) {}\n },\n\n});\n", "import { defineModule } from '../../core';\nimport { noiseDescriptor } from './noise';\nimport type { NoiseParams, NoiseInputs, NoiseOutputs, NoiseProps } from './noise.types';\n\n\nexport const Noise = /* @__PURE__ */ defineModule(noiseDescriptor) as import('../../core').LibModule<NoiseParams, NoiseInputs, NoiseOutputs, NoiseProps>;\nexport type { NoiseParams, NoiseInputs, NoiseOutputs, NoiseProps };\n", "// @ts-nocheck \u2014 generated by scripts/lib/build.ts\nimport type { BaseModule, Position } from '@/types/synth';\nimport { defineDescriptor, paramDefaults } from '@/modules/ModuleDescriptor';\nimport { createOctaverDividerNode } from '@/worklets';\n\nexport interface OctaverModule extends BaseModule {\n type: 'octaver';\n octDown1: number;\n octDown2: number;\n octUp: number;\n dry: number;\n}\n\n// \u2500\u2500\u2500 PARAMS \u2014 the signal contract (no UI knowledge) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n// All four voices are plain gain sends \u2014 genuine 1:1 AudioParam writes.\nconst params = {\n octDown2: { node: 'oct2Gain', field: 'gain', unit: 'factor', default: 0.3, min: 0, max: 1, },\n octDown1: { node: 'oct1Gain', field: 'gain', unit: 'factor', default: 0.5, min: 0, max: 1, },\n dry: { node: 'dryGain', field: 'gain', unit: 'factor', default: 0.7, min: 0, max: 1, },\n octUp: { node: 'octUpGain', field: 'gain', unit: 'factor', default: 0, min: 0, max: 1, },\n} satisfies Record<string, ParamSpec>;\n\n\nfunction makeFullWaveRectifierCurve(): Float32Array {\n const samples = 8192;\n const curve = new Float32Array(samples);\n for (let i = 0; i < samples; i++) {\n const x = (i * 2) / samples - 1;\n curve[i] = Math.abs(x) * 2 - 1; // rectify and re-centre\n }\n return curve;\n}\n\n\nexport const octaverDescriptor = /* @__PURE__ */ defineDescriptor({\n type: 'octaver',\n params,\n\n ports: {\n 'in': { type: 'input', signal: 'audio', node: 'input', },\n 'out': { type: 'output', signal: 'audio', node: 'output', },\n },\n\n createModule(id: string, position: Position): OctaverModule {\n return { id, type: 'octaver', position, ...paramDefaults(params) };\n },\n\n createNodes(ctx, module) {\n const input = ctx.createGain();\n const output = ctx.createGain();\n const dryGain = ctx.createGain();\n const oct1Gain = ctx.createGain();\n const oct2Gain = ctx.createGain();\n const octUpGain = ctx.createGain();\n\n // \u2500\u2500 True frequency division (worklet, zero-crossing flip-flop) \u2500\u2500\u2500\u2500\n const divider = createOctaverDividerNode(ctx);\n (divider.parameters as unknown as Map<string, AudioParam>).get('oct1Level')!.value = 1;\n (divider.parameters as unknown as Map<string, AudioParam>).get('oct2Level')!.value = 1;\n\n const splitter = ctx.createChannelSplitter(2);\n\n const lowpass1 = ctx.createBiquadFilter();\n lowpass1.type = 'lowpass'; lowpass1.frequency.value = 1200; lowpass1.Q.value = 0.7;\n const lowpass2 = ctx.createBiquadFilter();\n lowpass2.type = 'lowpass'; lowpass2.frequency.value = 600; lowpass2.Q.value = 0.7;\n\n // \u2500\u2500 Octave up: rectifier + pitch-tracked bandpass \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n const waveshaperUp = ctx.createWaveShaper();\n waveshaperUp.curve = makeFullWaveRectifierCurve() as Float32Array<ArrayBuffer>;\n const bpUp = ctx.createBiquadFilter();\n bpUp.type = 'bandpass';\n bpUp.frequency.value = 20; // floor; the tracked estimate is summed on top\n bpUp.Q.value = 2.5;\n const freqTrack = ctx.createGain();\n freqTrack.gain.value = 2; // octave up = 2\u00D7 the detected fundamental\n\n dryGain.gain.value = module.dry;\n oct1Gain.gain.value = module.octDown1;\n oct2Gain.gain.value = module.octDown2;\n octUpGain.gain.value = module.octUp;\n\n input.connect(dryGain);\n\n input.connect(divider);\n divider.connect(splitter, 1, 0); // raw square outputs\n splitter.connect(lowpass1, 0);\n splitter.connect(lowpass2, 1);\n lowpass1.connect(oct1Gain);\n lowpass2.connect(oct2Gain);\n\n divider.connect(freqTrack, 2, 0); // Hz estimate\n freqTrack.connect(bpUp.frequency);\n\n input.connect(waveshaperUp);\n waveshaperUp.connect(bpUp);\n bpUp.connect(octUpGain);\n\n dryGain.connect(output);\n oct1Gain.connect(output);\n oct2Gain.connect(output);\n octUpGain.connect(output);\n\n return { input, output, dryGain, oct1Gain, oct2Gain, octUpGain, divider, bpUp, freqTrack };\n },\n\n updateParam(nodes, _m, param, value) {\n if (param === 'dry') nodes.dryGain.gain.value = value as number;\n else if (param === 'octDown1') nodes.oct1Gain.gain.value = value as number;\n else if (param === 'octDown2') nodes.oct2Gain.gain.value = value as number;\n else if (param === 'octUp') nodes.octUpGain.gain.value = value as number;\n },\n\n});\n", "import { defineModule } from '../../core';\nimport { octaverDescriptor } from './octaver';\nimport type { OctaverParams, OctaverInputs, OctaverOutputs, OctaverProps } from './octaver.types';\nimport freq_divider from '../worklet-src/freq-divider';\n\nexport const Octaver = /* @__PURE__ */ defineModule(octaverDescriptor, {\n worklets: {\n 'freq-divider': freq_divider,\n },\n}) as import('../../core').LibModule<OctaverParams, OctaverInputs, OctaverOutputs, OctaverProps>;\nexport type { OctaverParams, OctaverInputs, OctaverOutputs, OctaverProps };\n", "// @ts-nocheck \u2014 generated by scripts/lib/build.ts\nimport { BaseModule } from '@/types/synth';\n\nexport interface PhaserModule extends BaseModule {\n type: 'phaser';\n rate: number;\n depth: number;\n feedback: number;\n mix: number;\n}\nimport { defineDescriptor, paramDefaults } from '@/modules/ModuleDescriptor';\nimport { createMix } from '@/lib/dsp/mix';\n\nconst params = {\n rate: { node: 'lfo', field: 'frequency', unit: 'Hz', default: 0.5, min: 0.1, max: 10, },\n depth: { unit: 'factor', default: 0.7, min: 0, max: 1, },\n feedback: { node: 'feedback', field: 'gain', unit: 'factor', default: 0.6, min: 0, max: 0.9, },\n mix: { node: '_mix', field: 'offset', unit: 'factor', default: 0.5, min: 0, max: 1, },\n} satisfies Record<string, ParamSpec>;\n\n\n\nexport const phaserDescriptor = /* @__PURE__ */ defineDescriptor({\n type: 'phaser',\n params,\n\n ports: {\n 'in': { type: 'input', signal: 'audio', node: 'input', },\n 'out': { type: 'output', signal: 'audio', node: 'output', },\n 'modRate': { type: 'modulation', signal: 'modulation', node: 'lfo', field: 'frequency' },\n 'modFeedback': { type: 'modulation', signal: 'modulation', node: 'feedback', field: 'gain' },\n 'modMix': { type: 'modulation', signal: 'modulation', node: '_mix', field: 'offset' },\n },\n\n createModule(id, position) {\n return { id, type: 'phaser', position, ...paramDefaults(params) };\n },\n\n createNodes(ctx, module) {\n const input = ctx.createGain();\n const output = ctx.createGain();\n const dryGain = ctx.createGain();\n const wetGain = ctx.createGain();\n const lfo = ctx.createOscillator();\n const feedback = ctx.createGain();\n const stageBases = [200, 400, 600, 800];\n const allpasses = stageBases.map((base) => {\n const ap = ctx.createBiquadFilter();\n ap.type = 'allpass';\n ap.frequency.value = base;\n ap.Q.value = 0.5;\n return ap;\n });\n const stageGains = stageBases.map((base) => {\n const g = ctx.createGain();\n g.gain.value = module.depth * base * 0.8;\n return g;\n });\n const _mix = createMix(ctx, dryGain, wetGain, module.mix, 'linear');\n feedback.gain.value = module.feedback;\n lfo.type = 'sine';\n lfo.frequency.value = module.rate;\n allpasses.forEach((ap, i) => {\n lfo.connect(stageGains[i]);\n stageGains[i].connect(ap.frequency);\n });\n lfo.start();\n input.connect(dryGain);\n input.connect(allpasses[0]);\n allpasses[0].connect(allpasses[1]);\n allpasses[1].connect(allpasses[2]);\n allpasses[2].connect(allpasses[3]);\n allpasses[3].connect(feedback);\n feedback.connect(allpasses[0]);\n allpasses[3].connect(wetGain);\n dryGain.connect(output);\n wetGain.connect(output);\n return {\n input, output, lfo, feedback, dryGain, wetGain, _mix,\n stageGain0: stageGains[0], stageGain1: stageGains[1],\n stageGain2: stageGains[2], stageGain3: stageGains[3],\n };\n },\n\n updateParam(nodes, _m, param, value) {\n switch (param) {\n case 'rate': nodes.lfo.frequency.value = value as number; break;\n case 'depth': {\n const d = value as number;\n [200, 400, 600, 800].forEach((base, i) => {\n const g = nodes[`stageGain${i}` as 'stageGain0'] as GainNode;\n g.gain.value = d * base * 0.8;\n });\n break;\n }\n case 'feedback': nodes.feedback.gain.value = value as number; break;\n case 'mix': (nodes._mix as ConstantSourceNode).offset.value = value as number; break;\n }\n },\n\n dispose(nodes) {\n nodes.lfo.stop();\n (nodes._mix as ConstantSourceNode).stop();\n },\n\n});\n", "import { defineModule } from '../../core';\nimport { phaserDescriptor } from './phaser';\nimport type { PhaserParams, PhaserInputs, PhaserOutputs, PhaserProps } from './phaser.types';\n\n\nexport const Phaser = /* @__PURE__ */ defineModule(phaserDescriptor) as import('../../core').LibModule<PhaserParams, PhaserInputs, PhaserOutputs, PhaserProps>;\nexport type { PhaserParams, PhaserInputs, PhaserOutputs, PhaserProps };\n", "// @ts-nocheck \u2014 generated by scripts/lib/build.ts\nimport type { BaseModule, Position } from '@/types/synth';\nimport { defineDescriptor, paramDefaults } from '@/modules/ModuleDescriptor';\nimport { createPingPongNode } from '@/worklets';\nimport { createMix } from '@/lib/dsp/mix';\n\nexport interface PingPongModule extends BaseModule {\n type: 'ping-pong';\n time: number;\n feedback: number;\n spread: number;\n mix: number;\n}\n\n// \u2500\u2500\u2500 PARAMS \u2014 the signal contract \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n// `time`/`feedback` drive the ping-pong worklet's own AudioParams 1:1.\n// `spread` sets two StereoPannerNode.pan values at once \u2014 not a single\n// AudioParam \u2014 so it stays a set-only enum-like knob. `mix` now runs\n// through createMix's ConstantSource (`_mix`), linear law.\nconst params = {\n time: { node: 'worklet', field: 'time', unit: 's', default: 0.3, min: 0.1, max: 1, scale: 'log', },\n feedback: { node: 'worklet', field: 'feedback', unit: 'factor', default: 0.4, min: 0, max: 0.9, },\n spread: { unit: 'factor', default: 1, min: 0, max: 1, },\n mix: { node: '_mix', field: 'offset', unit: 'factor', default: 0.5, min: 0, max: 1, },\n} satisfies Record<string, ParamSpec>;\n\n\nexport const pingPongDescriptor = /* @__PURE__ */ defineDescriptor({\n type: 'ping-pong' as const,\n params,\n\n ports: {\n 'in': { type: 'input' as const, signal: 'audio', node: 'input', },\n 'out': { type: 'output' as const, signal: 'audio', node: 'output', },\n },\n\n createModule(id: string, position: Position): PingPongModule {\n return { id, type: 'ping-pong', position, ...paramDefaults(params) } as PingPongModule;\n },\n\n // The delay lines and cross-feedback live in the 'ping-pong' AudioWorklet\n // (src/worklets/ping-pong.ts) as of 2026-08-08. A native two-DelayNode\n // cycle carries ONE render quantum of hidden latency at an UNSTABLE\n // position: identical code measured +3.01 dB (coherent grid) on one run\n // and \u22120.19 dB (right leg off by a quantum) on the next, so no static\n // delayTime compensation can hold the tap grid. The worklet's grid is\n // exact by construction. Pans, spread, and dry/wet mix stay native.\n createNodes(ctx, module) {\n const input = ctx.createGain();\n const output = ctx.createGain();\n const dryGain = ctx.createGain();\n const wetGain = ctx.createGain();\n const panL = ctx.createStereoPanner();\n const panR = ctx.createStereoPanner();\n const worklet = createPingPongNode(ctx, {\n time: module.time,\n feedback: module.feedback,\n });\n\n panL.pan.value = -module.spread;\n panR.pan.value = module.spread;\n\n const _mix = createMix(ctx, dryGain, wetGain, module.mix, 'linear');\n\n input.connect(dryGain);\n input.connect(worklet);\n worklet.connect(panL, 0); // output 0: L taps at T, 4T, 7T\u2026\n worklet.connect(panR, 1); // output 1: R taps at 3T, 6T, 9T\u2026\n panL.connect(wetGain);\n panR.connect(wetGain);\n dryGain.connect(output);\n wetGain.connect(output);\n\n return { input, output, worklet, dryGain, wetGain, panL, panR, _mix };\n },\n\n updateParam(nodes, _m, param, value) {\n if (param === 'time' || param === 'feedback') {\n const p = (nodes.worklet as AudioWorkletNode).parameters.get(param);\n if (p) p.value = value as number;\n } else if (param === 'spread') {\n nodes.panL.pan.value = -(value as number);\n nodes.panR.pan.value = value as number;\n } else if (param === 'mix') {\n (nodes._mix as ConstantSourceNode).offset.value = value as number;\n }\n },\n\n});\n", "import { defineModule } from '../../core';\nimport { pingPongDescriptor } from './ping-pong';\nimport type { PingPongParams, PingPongInputs, PingPongOutputs, PingPongProps } from './ping-pong.types';\nimport ping_pong from '../worklet-src/ping-pong';\n\nexport const PingPong = /* @__PURE__ */ defineModule(pingPongDescriptor, {\n worklets: {\n 'ping-pong': ping_pong,\n },\n}) as import('../../core').LibModule<PingPongParams, PingPongInputs, PingPongOutputs, PingPongProps>;\nexport type { PingPongParams, PingPongInputs, PingPongOutputs, PingPongProps };\n", "/**\n * Modal-resonator maths \u2014 the RESO module's DAMP law, kept pure so it is\n * unit-tested directly (modal.test.ts) instead of only through patches.\n *\n * Each mode is a second-order bandpass (Web Audio's RBJ biquad), i.e. a\n * damped harmonic oscillator whose poles sit at \u2212\u03C90/(2Q). Its impulse\n * response decays as e^(\u2212\u03C90\u00B7t / 2Q), so the time to fall 60 dB is\n *\n * ```text\n * T60 = 2Q\u00B7ln(1000) / \u03C90 = (3\u00B7ln10 / \u03C0) \u00B7 Q / f0 \u2248 2.2 \u00B7 Q / f0\n * ```\n *\n * Q is constant across the five modes, so upper partials die proportionally\n * faster than the fundamental \u2014 the brightness-first decay of a real plucked\n * string or struck bar (and the constant-Q choice of classic modal designs).\n *\n * DAMP maps exponentially onto Q over 2.7 decades, which is what makes it a\n * decay-TIME control rather than a narrow tone knob: at A3 it spans ~10 s\n * (DAMP 0) to ~20 ms (DAMP 1), equal knob travel = equal ratio of ring time.\n */\n\n/** DAMP 0 \u2014 longest ring: ~10 s at A3, ~40 s at the bottom of FREQ. */\nexport const MODAL_Q_MAX = 1000;\n/** DAMP 1 \u2014 a damped thud: ~20 ms at A3. */\nexport const MODAL_Q_MIN = 2;\n\n/** T60 per unit Q per unit Hz: 3\u00B7ln(10)/\u03C0 \u2248 2.199 s\u00B7Hz. */\nexport const T60_PER_Q_HZ = (3 * Math.LN10) / Math.PI;\n\n/** DAMP (0\u20131) \u2192 mode Q, exponential between MODAL_Q_MAX and MODAL_Q_MIN. */\nexport function dampingToQ(damping: number): number {\n const d = Math.min(1, Math.max(0, Number.isFinite(damping) ? damping : 0.5));\n return MODAL_Q_MAX * Math.pow(MODAL_Q_MIN / MODAL_Q_MAX, d);\n}\n\n/** Seconds for a mode at `hz` with quality `q` to ring down 60 dB. */\nexport function modeT60(q: number, hz: number): number {\n return (T60_PER_Q_HZ * q) / hz;\n}\n\n/**\n * Per-mode makeup, \u221AQ and deliberately UNCAPPED (unlike the filters'\n * `bandpassMakeup`, whose cap guards a self-oscillating filter from a sine\n * parked on its peak). A unity-peak bandpass passes (\u03C0/2)\u00B7f0/Q of white\n * noise's bandwidth \u2014 and, by Parseval, a strike's impulse-response energy\n * scales the same way \u2014 so \u221AQ holds both the steady-state loudness of a\n * noise-fed bank and the total energy of a pluck constant across all of\n * DAMP. Less damping = the same strike spread over a longer ring, never a\n * quieter one (the capped version lost 18 dB at DAMP 0).\n */\nexport function modalMakeup(q: number): number {\n return Math.sqrt(Math.max(1, q));\n}\n", "// @ts-nocheck \u2014 generated by scripts/lib/build.ts\nimport { createMix } from '@/lib/dsp/mix';\nimport { createKeepAlive } from '@/lib/dsp/keepAlive';\nimport type { BaseModule, Position } from '@/types/synth';\n\n\nexport interface ResonatorModule extends BaseModule {\n type: 'resonator';\n note: number; // panel memory: absolute root note while V/OCT is unpatched\n transpose?: number; // panel memory: semitone shift while V/OCT is patched\n offset?: number; // library-only DSP state (see params.offset); the app derives it\n structure: number;\n damping: number;\n mix: number;\n}\nimport { defineDescriptor, paramDefaults } from '@/modules/ModuleDescriptor';\nimport { createVoctFreqNode } from '@/worklets';\nimport { dampingToQ, modalMakeup } from '@/lib/dsp/modal';\n\n// \u2500\u2500\u2500 PARAMS (single source of truth: knobs, defaults, hover tips, docs) \u2500\u2500\nconst params = {\n // Root pitch = V/OCT input (absolute notes, silence = 0) + MOD (semitones) + offset.\n offset: { node: '_root', field: 'offset', default: 57, min: -48, max: 108, unit: 'semitone', },\n structure: { unit: 'factor', default: 0, min: 0, max: 1, },\n damping: { unit: 'factor', default: 0.5, min: 0, max: 1, },\n mix: { node: '_mix', field: 'offset', unit: 'factor', default: 0.5, min: 0, max: 1, },\n} as const satisfies Record<string, ParamSpec>;\n\n/** Partial n sits at root \u00B7 n^(1+structure): as a pitch offset that is\n * 12\u00B7log2(n^(1+structure)) semitones above the root. */\nfunction partialOffset(partial: number, structure: number): number {\n return 12 * (1 + structure) * Math.log2(partial);\n}\n\n/** Cables currently on V/OCT, per node set \u2014 picks the live panel memory. */\nconst patchCount = new WeakMap<object, number>();\n\n\n/** Ring time at the root as the DAMP readout: \"85ms\", \"1.2s\", \"12s\". */\nfunction fmtT60(t: number): string {\n return t < 1 ? `${Math.round(t * 1000)}ms` : t < 10 ? `${t.toFixed(1)}s` : `${Math.round(t)}s`;\n}\n\n\nexport const resonatorDescriptor = /* @__PURE__ */ defineDescriptor({\n type: 'resonator' as const,\n params,\n\n ports: {\n 'in': { type: 'input' as const, signal: 'audio', node: 'input', },\n 'out': { type: 'output' as const, signal: 'audio', node: 'output', },\n 'voct': { type: 'input' as const, signal: 'pitch', node: '_pitch', },\n 'modFreq': { type: 'modulation' as const, signal: 'modulation', node: '_pitch', },\n },\n\n\n createModule(id: string, position: Position): ResonatorModule {\n const { offset: _dsp, ...rest } = paramDefaults(params);\n return { id, type: 'resonator', position, ...rest, note: 57, transpose: 0 };\n },\n\n createNodes(ctx, module) {\n const input = ctx.createGain();\n const output = ctx.createGain();\n const dryGain = ctx.createGain();\n const wetGain = ctx.createGain();\n\n // Pitch bus: root note (ConstantSource, the `note` param 1:1) + FM/V/OCT\n // semitones sum here, then fan out to one V/OCT\u2192Hz converter per partial.\n // Each converter's `transpose` holds that partial's fixed offset, so the\n // whole series tracks pitch \u2014 previously only f1 did, and f2\u2013f5 sat at\n // knob-computed Hz while the root moved.\n const _root = ctx.createConstantSource();\n _root.offset.value = module.offset ?? module.note;\n _root.start();\n const _pitch = ctx.createGain();\n _root.connect(_pitch);\n\n const filters: BiquadFilterNode[] = [];\n const partialGains: GainNode[] = [];\n const voct: AudioWorkletNode[] = [];\n const q = dampingToQ(module.damping);\n const makeup = modalMakeup(q);\n for (let i = 1; i <= 5; i++) {\n const v = createVoctFreqNode(ctx as AudioContext);\n v.parameters.get('transpose')!.value = partialOffset(i, module.structure);\n _pitch.connect(v);\n const filter = ctx.createBiquadFilter();\n filter.type = 'bandpass';\n filter.frequency.value = 0; // driven by the partial's converter\n v.connect(filter.frequency);\n filter.Q.value = q;\n filters.push(filter);\n voct.push(v);\n input.connect(filter);\n // Each mode gets \u221AQ (energy-invariant across DAMP \u2014 see dsp/modal.ts)\n // and a gentle 1/\u221An tilt so the upper partials sit behind the root;\n // five narrow unity-peak bands alone would throw the excitation away.\n const partialGain = ctx.createGain();\n partialGain.gain.value = makeup / Math.sqrt(i);\n filter.connect(partialGain);\n partialGain.connect(wetGain);\n partialGains.push(partialGain);\n }\n\n // Chrome would otherwise cut every mode's ring ~30 dB in once the strike\n // ends \u2014 see dsp/keepAlive.ts. Bandpass modes reject the DC outright.\n const _alive = createKeepAlive(ctx, ...filters);\n\n const _mix = createMix(ctx, dryGain, wetGain, module.mix, 'linear', 0.6);\n input.connect(dryGain);\n dryGain.connect(output);\n wetGain.connect(output);\n\n return {\n input, output, dryGain, wetGain, _mix, _root, _pitch, _alive,\n v1: voct[0], v2: voct[1], v3: voct[2], v4: voct[3], v5: voct[4],\n f1: filters[0], f2: filters[1], f3: filters[2], f4: filters[3], f5: filters[4],\n g1: partialGains[0], g2: partialGains[1], g3: partialGains[2],\n g4: partialGains[3], g5: partialGains[4],\n };\n },\n\n updateParam(nodes, _module, param, value) {\n const filters = [nodes.f1, nodes.f2, nodes.f3, nodes.f4, nodes.f5];\n if (param === 'offset') {\n nodes._root.offset.value = value as number;\n } else if (param === 'note') {\n if (!patchCount.get(nodes)) nodes._root.offset.value = value as number;\n } else if (param === 'transpose') {\n if (patchCount.get(nodes)) nodes._root.offset.value = value as number;\n } else if (param === 'structure') {\n const voct = [nodes.v1, nodes.v2, nodes.v3, nodes.v4, nodes.v5];\n for (let i = 1; i < 5; i++) {\n voct[i].parameters.get('transpose')!.value = partialOffset(i + 1, value as number);\n }\n } else if (param === 'damping') {\n const q = dampingToQ(value as number);\n const makeup = modalMakeup(q);\n const gains = [nodes.g1, nodes.g2, nodes.g3, nodes.g4, nodes.g5];\n for (let i = 0; i < 5; i++) {\n filters[i].Q.value = q;\n gains[i].gain.value = makeup / Math.sqrt(i + 1);\n }\n } else if (param === 'mix') {\n nodes._mix.offset.value = value as number;\n }\n },\n\n // App-only: plain summing connect; the hooks only swap which panel memory\n // drives the offset.\n onConnect(nodes, module, portId, sourceNode) {\n if (portId !== 'voct') return false;\n sourceNode.connect(nodes._pitch);\n patchCount.set(nodes, (patchCount.get(nodes) ?? 0) + 1);\n nodes._root.offset.value = module.transpose ?? 0;\n return true;\n },\n\n onDisconnect(nodes, module, portId, sourceNode) {\n if (portId !== 'voct') return false;\n try { sourceNode.disconnect(nodes._pitch); } catch (_) {}\n const n = Math.max(0, (patchCount.get(nodes) ?? 0) - 1);\n patchCount.set(nodes, n);\n if (!n) nodes._root.offset.value = module.note;\n return true;\n },\n\n dispose(nodes) {\n nodes._root.stop();\n nodes._alive.stop();\n },\n\n});\n", "import { defineModule } from '../../core';\nimport { resonatorDescriptor } from './resonator';\nimport type { ResonatorParams, ResonatorInputs, ResonatorOutputs, ResonatorProps } from './resonator.types';\nimport map_voct_to_freq from '../worklet-src/map-voct-to-freq';\n\nexport const Resonator = /* @__PURE__ */ defineModule(resonatorDescriptor, {\n worklets: {\n 'map-voct-to-freq': map_voct_to_freq,\n },\n}) as import('../../core').LibModule<ResonatorParams, ResonatorInputs, ResonatorOutputs, ResonatorProps>;\nexport type { ResonatorParams, ResonatorInputs, ResonatorOutputs, ResonatorProps };\n", "/**\n * Schroeder / small-FDN reverb tank.\n *\n * Topology (implemented inside the `fdn-reverb` AudioWorklet):\n * in \u2500\u25BA 4 parallel damped comb filters, whose feedback taps are cross-mixed\n * through a normalised 4\u00D74 Hadamard matrix (a minimal feedback delay\n * network \u2014 far denser than 4 independent combs)\n * \u2500\u25BA 2 series Schroeder allpass diffusors\n * \u2500\u25BA out\n *\n * WHY A WORKLET: this tank used to be built from native nodes (delays, biquads\n * and 16 cross-feed gains). Chrome breaks feedback cycles by inserting\n * render-quantum latencies, and it does so inconsistently across the matrix\n * paths \u2014 which destroys the Hadamard's energy conservation and makes the\n * tank self-oscillate even though the math says loop gain < 1. Measured\n * growth was ~1e15\u00D7 over 6 s. Sample-accurate matrixing inside a worklet is\n * unconditionally stable.\n *\n * decay/damping are real AudioParams on the worklet node, so knob moves are\n * smooth and never reallocate buffers.\n */\n\nexport const COMB_TIMES_MS = [29.7, 37.1, 41.1, 43.7];\n\n/** Feedback gain for a comb of length T seconds to reach an RT60 of `rt60` seconds. */\nexport function combFeedbackGain(delaySeconds: number, rt60: number, ceiling = 0.995): number {\n const g = Math.pow(10, (-3 * delaySeconds) / Math.max(rt60, 0.05));\n return Math.min(g, ceiling);\n}\n\n/** Damping 0 \u2192 dark (800 Hz), 1 \u2192 bright (16 kHz), log taper. */\nexport function dampingToCutoff(damping: number): number {\n const minHz = 800, maxHz = 16000;\n return minHz * Math.pow(maxHz / minHz, Math.max(0, Math.min(1, damping)));\n}\n\n/**\n * Steady-state energy gain of the tank (input \u2192 one output channel) in the\n * 500 Hz band, where the worklet honours RT60 exactly (fdn-reverb RT_REF_HZ).\n * With per-line loop gain \u03B3\u1D62 = 10^(\u22123\u00B7d\u1D62/RT60) at 500 Hz, a recirculating\n * network's energy goes as 1/(1 \u2212 \u03B3\u00B2); the constants are fitted to the real\n * worklet (band noise, 2026-09-30) and hold to \u00B10.5 dB energy over RT60\n * 0.5\u201310 s (fdn-reverb.test.ts re-measures it). Longer tails store more\n * energy, so anything that feeds the tank back into itself (SHIMMER's regen)\n * must divide by \u221AE to keep its own loop gain meaning the same at every\n * DECAY. Assumes the feedback ceiling does not bind (true at DECAY \u2264 10 s\n * unless damping is near 0).\n */\nexport function tankEnergyGain500(rt60: number, size = 1): number {\n let g2 = 0;\n for (const ms of COMB_TIMES_MS) g2 += Math.pow(10, (-6 * (ms / 1000) * size) / Math.max(rt60, 0.05));\n g2 /= COMB_TIMES_MS.length;\n return Math.max(0.05, 0.8006 / (1 - g2) - 0.531);\n}\n\nexport interface FdnTank {\n /** Feed audio in here. */\n input: GainNode;\n /** Diffused reverberant output. */\n output: GainNode;\n /** The worklet doing the actual work \u2014 owns the rt60/damping AudioParams. */\n node: AudioWorkletNode;\n}\n\nimport { createFdnReverbNode } from '@/worklets';\n\nexport function createFdnTank(\n ctx: BaseAudioContext,\n opts: { rt60: number; damping: number; size?: number; feedbackCeiling?: number },\n): FdnTank {\n const input = ctx.createGain();\n const output = ctx.createGain();\n\n const node = createFdnReverbNode(ctx, opts);\n\n input.connect(node);\n node.connect(output);\n\n return { input, output, node };\n}\n\n/** Retune the tank's RT60 without reallocating anything. */\nexport function setTankDecay(tank: Pick<FdnTank, 'node'>, rt60: number, now: number, t = 0.02) {\n tank.node.parameters.get('rt60')!.setTargetAtTime(rt60, now, t);\n}\n\n/** Retune the tank's high-frequency damping. */\nexport function setTankDamping(tank: Pick<FdnTank, 'node'>, damping: number, now: number, t = 0.02) {\n tank.node.parameters.get('damping')!.setTargetAtTime(damping, now, t);\n}\n", "// @ts-nocheck \u2014 generated by scripts/lib/build.ts\nimport { createMix } from '@/lib/dsp/mix';\nimport type { BaseModule, Position } from '@/types/synth';\n\nexport interface ReverbModule extends BaseModule {\n type: 'reverb';\n decay: number;\n mix: number;\n}\nimport { defineDescriptor, paramDefaults } from '@/modules/ModuleDescriptor';\n\n// \u2500\u2500\u2500 PARAMS (single source of truth: knobs, defaults, hover tips, docs) \u2500\u2500\nconst params = {\n decay: { node: 'tankNode', field: 'rt60', default: 2, min: 0.1, max: 8, scale: 'log', unit: 's', },\n mix: { node: '_mix', field: 'offset', unit: 'factor', default: 0.3, min: 0, max: 1, },\n} satisfies Record<string, ParamSpec>;\n\nimport { createFdnTank, setTankDecay } from '@/lib/dsp/fdnTank';\n\n\nexport const reverbDescriptor = /* @__PURE__ */ defineDescriptor({\n type: 'reverb',\n params,\n\n ports: {\n 'in': { type: 'input', signal: 'audio', node: 'input', },\n 'out': { type: 'output', signal: 'audio', node: 'output', },\n },\n createModule(id: string, position: Position): ReverbModule {\n return {\n id, type: 'reverb', position, ...paramDefaults(params),\n };\n },\n\n createNodes(ctx, module) {\n const input = ctx.createGain();\n const output = ctx.createGain();\n const dryGain = ctx.createGain();\n const wetGain = ctx.createGain();\n\n // Equal-power crossfade\n const _mix = createMix(ctx, dryGain, wetGain, module.mix, 'equal-power');\n\n const preDelay = ctx.createDelay(0.5);\n preDelay.delayTime.value = 0.02;\n\n const tank = createFdnTank(ctx, { rt60: module.decay, damping: 0.55 });\n\n input.connect(dryGain);\n input.connect(preDelay);\n preDelay.connect(tank.input);\n tank.output.connect(wetGain);\n dryGain.connect(output);\n wetGain.connect(output);\n\n return {\n input, output, dryGain, wetGain, _mix, preDelay,\n tankInput: tank.input, tankOutput: tank.output, tankNode: tank.node,\n };\n },\n\n updateParam(nodes, _m, param, value) {\n const now = nodes.input.context.currentTime;\n if (param === 'mix') {\n (nodes._mix as ConstantSourceNode).offset.setTargetAtTime(value as number, now, 0.02);\n } else if (param === 'decay') {\n // No buffer reallocation \u2014 just retune the tank's RT60 AudioParam\n setTankDecay({ node: nodes.tankNode as AudioWorkletNode }, value as number, now);\n }\n },\n\n});\n", "import { defineModule } from '../../core';\nimport { reverbDescriptor } from './reverb';\nimport type { ReverbParams, ReverbInputs, ReverbOutputs, ReverbProps } from './reverb.types';\nimport fdn_reverb from '../worklet-src/fdn-reverb';\n\nexport const Reverb = /* @__PURE__ */ defineModule(reverbDescriptor, {\n worklets: {\n 'fdn-reverb': fdn_reverb,\n },\n}) as import('../../core').LibModule<ReverbParams, ReverbInputs, ReverbOutputs, ReverbProps>;\nexport type { ReverbParams, ReverbInputs, ReverbOutputs, ReverbProps };\n", "// @ts-nocheck \u2014 generated by scripts/lib/build.ts\nimport type { BaseModule, Position } from '@/types/synth';\n\nimport { defineDescriptor, paramDefaults } from '@/modules/ModuleDescriptor';\nimport { createVoctFreqNode } from '@/worklets';\n\nexport interface RingModModule extends BaseModule {\n type: 'ring-mod';\n note: number; // panel memory: absolute carrier note while V/OCT is unpatched\n transpose?: number; // panel memory: semitone shift while V/OCT is patched\n offset?: number; // library-only DSP state (see params.offset); the app derives it\n mix: number;\n}\n\nconst params = {\n // Carrier pitch = V/OCT input (absolute notes, silence = 0) + MOD (semitones) + offset.\n offset: { node: '_carrierVoct', field: 'transpose', unit: 'semitone', default: 69, min: -48, max: 108, },\n // Dry/wet is split across two gain nodes, not one AudioParam \u2014 set-only.\n mix: { unit: 'factor', default: 0.5, min: 0, max: 1, },\n} satisfies Record<string, ParamSpec>;\n\n\n/** Cables currently on V/OCT, per node set \u2014 picks the live panel memory. */\nconst patchCount = new WeakMap<object, number>();\n\n\nexport const ringModDescriptor = /* @__PURE__ */ defineDescriptor({\n type: 'ring-mod',\n params,\n\n ports: {\n 'in': { type: 'input', signal: 'audio', node: 'input', },\n 'out': { type: 'output', signal: 'audio', node: 'output', },\n 'voct': { type: 'input', signal: 'pitch', node: '_carrierVoct', },\n 'modFreq': { type: 'modulation', signal: 'modulation', node: '_carrierVoct', },\n },\n\n createModule(id: string, position: Position): RingModModule {\n const { offset: _dsp, ...rest } = paramDefaults(params);\n return { id, type: 'ring-mod', position, ...rest, note: 69, transpose: 0 };\n },\n\n createNodes(ctx, module) {\n const input = ctx.createGain();\n const output = ctx.createGain();\n const dryGain = ctx.createGain();\n const wetGain = ctx.createGain();\n const carrier = ctx.createOscillator();\n const ringMod = ctx.createGain();\n\n dryGain.gain.value = 1 - module.mix;\n wetGain.gain.value = module.mix;\n carrier.type = 'sine';\n ringMod.gain.value = 0;\n carrier.connect(ringMod.gain);\n carrier.start();\n\n // V/Oct carrier pitch: ConstantSource(0) \u2192 voct(transpose=carrier note) \u2192 carrier.frequency\n // Same pattern as VCF cutoff \u2014 mod CV arrives in semitone space, \u00B112 = one octave.\n carrier.frequency.value = 0; // driven exclusively by voct\n const _carrierVoct = createVoctFreqNode(ctx);\n _carrierVoct.parameters.get('transpose')!.value = module.offset ?? module.note;\n\n const _carrierBase = ctx.createConstantSource();\n _carrierBase.offset.value = 0;\n _carrierBase.start();\n\n _carrierBase.connect(_carrierVoct);\n _carrierVoct.connect(carrier.frequency);\n\n input.connect(dryGain);\n input.connect(ringMod);\n ringMod.connect(wetGain);\n dryGain.connect(output);\n wetGain.connect(output);\n\n return { input, output, carrier, ringMod, dryGain, wetGain, _carrierVoct, _carrierBase };\n },\n\n updateParam(nodes, _m, param, value) {\n const t = nodes._carrierVoct.parameters.get('transpose')!;\n if (param === 'offset') t.value = value as number;\n // App panel memories: only the one matching the patch state is live.\n else if (param === 'note') { if (!patchCount.get(nodes)) t.value = value as number; }\n else if (param === 'transpose') { if (patchCount.get(nodes)) t.value = value as number; }\n else if (param === 'mix') {\n nodes.dryGain.gain.value = 1 - (value as number);\n nodes.wetGain.gain.value = value as number;\n }\n },\n\n // App-only: plain summing connect; the hooks only swap which panel memory\n // drives the offset.\n onConnect(nodes, module, portId, sourceNode) {\n if (portId !== 'voct') return false;\n sourceNode.connect(nodes._carrierVoct);\n patchCount.set(nodes, (patchCount.get(nodes) ?? 0) + 1);\n nodes._carrierVoct.parameters.get('transpose')!.value = module.transpose ?? 0;\n return true;\n },\n\n onDisconnect(nodes, module, portId, sourceNode) {\n if (portId !== 'voct') return false;\n try { sourceNode.disconnect(nodes._carrierVoct); } catch (_) {}\n const n = Math.max(0, (patchCount.get(nodes) ?? 0) - 1);\n patchCount.set(nodes, n);\n if (!n) nodes._carrierVoct.parameters.get('transpose')!.value = module.note;\n return true;\n },\n\n dispose(nodes) {\n try { nodes.carrier.stop(); } catch (_) {}\n try { nodes._carrierBase.stop(); } catch (_) {}\n },\n\n});\n", "import { defineModule } from '../../core';\nimport { ringModDescriptor } from './ring-mod';\nimport type { RingModulatorParams, RingModulatorInputs, RingModulatorOutputs, RingModulatorProps } from './ring-mod.types';\nimport map_voct_to_freq from '../worklet-src/map-voct-to-freq';\n\nexport const RingModulator = /* @__PURE__ */ defineModule(ringModDescriptor, {\n worklets: {\n 'map-voct-to-freq': map_voct_to_freq,\n },\n}) as import('../../core').LibModule<RingModulatorParams, RingModulatorInputs, RingModulatorOutputs, RingModulatorProps>;\nexport type { RingModulatorParams, RingModulatorInputs, RingModulatorOutputs, RingModulatorProps };\n", "// @ts-nocheck \u2014 generated by scripts/lib/build.ts\n\nimport type { BaseModule, Position } from '@/types/synth';\n\nexport interface RotaryModule extends BaseModule {\n type: 'rotary';\n speed: 'slow' | 'fast';\n slowRate: number;\n fastRate: number;\n mix: number;\n}\nimport { defineDescriptor, paramDefaults } from '@/modules/ModuleDescriptor';\nimport { createMix } from '@/lib/dsp/mix';\n\ninterface RotorSpec {\n baseDelay: number; dopplerSec: number; ampBase: number; ampDepth: number;\n phaseDeg: number; tauUp: number; tauDown: number;\n}\nconst CROSSOVER_HZ = 800;\nconst BUTTERWORTH_Q_DB = -3.0103; // 1/\u221A2 in dB\nconst DRUM_RATIO = 0.85; // 122 drum \u2248 0.67/5.7 Hz vs horn \u2248 0.8/6.7 Hz\nconst HORN: RotorSpec = { baseDelay: 0.003, dopplerSec: 0.00044, ampBase: 0.7, ampDepth: 0.3, phaseDeg: 0, tauUp: 0.35, tauDown: 0.55 };\nconst DRUM: RotorSpec = { baseDelay: 0.003, dopplerSec: 0.0002, ampBase: 0.8, ampDepth: 0.2, phaseDeg: 90, tauUp: 1.5, tauDown: 1.7 };\n\n// \u2500\u2500\u2500 PARAMS \u2014 the signal contract (no UI knowledge) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n// `speed` is a mode switch with inertia, not a rate: the horn and drum\n// ramp toward slowRate/fastRate at different physical time constants\n// (setTargetAtTime), so there is no single instant value a rate\n// AudioParam could honestly hold \u2014 an AudioParam ramp is one curve, but\n// SLOW\u2194FAST here drives two rotors on two different curves whose target\n// also depends on which mode was already active. Modelled as an enum\n// (set-only) plus two set-only rate params rather than faking a rate\n// AudioParam. Only `mix` maps 1:1 to a real AudioParam here.\nconst params = {\n speed: { kind: 'enum', options: ['slow', 'fast'] as const, default: 'slow' as const, },\n slowRate: { unit: 'Hz', default: 0.8, min: 0.5, max: 2, },\n fastRate: { unit: 'Hz', default: 6, min: 4, max: 8, },\n mix: { node: '_mix', field: 'offset', unit: 'factor', default: 0.7, min: 0, max: 1, },\n} satisfies Record<string, ParamSpec>;\n\n\n\nexport const rotaryDescriptor = /* @__PURE__ */ defineDescriptor({\n type: 'rotary' as const,\n params,\n\n ports: {\n 'in': { type: 'input' as const, signal: 'audio', node: 'input', },\n 'out': { type: 'output' as const, signal: 'audio', node: 'output', },\n 'modMix': { type: 'modulation', signal: 'modulation', node: '_mix', field: 'offset' },\n },\n\n createModule(id: string, position: Position): RotaryModule {\n return { id, type: 'rotary', position, ...paramDefaults(params) };\n },\n\n createNodes(ctx, module) {\n const input = ctx.createGain();\n const output = ctx.createGain();\n const dryGain = ctx.createGain();\n const wetGain = ctx.createGain();\n const monoIn = ctx.createGain();\n monoIn.channelCount = 1;\n monoIn.channelCountMode = 'explicit';\n monoIn.channelInterpretation = 'speakers';\n const merger = ctx.createChannelMerger(2);\n const MIC_DEG = 60;\n\n const biquad = (type: BiquadFilterType) => {\n const f = ctx.createBiquadFilter();\n f.type = type;\n f.frequency.value = CROSSOVER_HZ;\n f.Q.value = BUTTERWORTH_Q_DB;\n return f;\n };\n const lp1 = biquad('lowpass'), lp2 = biquad('lowpass');\n const hp1 = biquad('highpass'), hp2 = biquad('highpass');\n monoIn.connect(lp1); lp1.connect(lp2);\n monoIn.connect(hp1); hp1.connect(hp2);\n\n const hornRate = module.speed === 'slow' ? module.slowRate : module.fastRate;\n const sources: (OscillatorNode | ConstantSourceNode)[] = [];\n\n const rotor = (band: AudioNode, spec: RotorSpec, rate: number) => {\n const speed = ctx.createConstantSource();\n speed.offset.value = rate;\n sources.push(speed);\n [MIC_DEG, -MIC_DEG].forEach((micDeg, ch) => {\n const phi = ((micDeg + spec.phaseDeg) * Math.PI) / 180;\n const wave = ctx.createPeriodicWave(\n new Float32Array([0, Math.cos(phi)]),\n new Float32Array([0, Math.sin(phi)]),\n { disableNormalization: true },\n );\n const osc = ctx.createOscillator();\n osc.setPeriodicWave(wave);\n osc.frequency.value = 0;\n speed.connect(osc.frequency);\n sources.push(osc);\n\n const delay = ctx.createDelay(0.02);\n delay.delayTime.value = spec.baseDelay;\n const dop = ctx.createGain();\n dop.gain.value = -spec.dopplerSec;\n osc.connect(dop); dop.connect(delay.delayTime);\n\n const amp = ctx.createGain();\n amp.gain.value = spec.ampBase;\n const am = ctx.createGain();\n am.gain.value = spec.ampDepth;\n osc.connect(am); am.connect(amp.gain);\n\n band.connect(delay); delay.connect(amp); amp.connect(merger, 0, ch);\n });\n return speed;\n };\n const hornSpeed = rotor(hp2, HORN, hornRate);\n const drumSpeed = rotor(lp2, DRUM, hornRate * DRUM_RATIO);\n sources.forEach((n) => n.start());\n\n const _mix = createMix(ctx, dryGain, wetGain, module.mix, 'linear');\n input.connect(dryGain);\n input.connect(monoIn);\n merger.connect(wetGain);\n dryGain.connect(output);\n wetGain.connect(output);\n\n const srcNodes = Object.fromEntries(sources.map((n, i) => [`src${i}`, n])) as Record<string, AudioNode>;\n return { input, output, dryGain, wetGain, hornSpeed, drumSpeed, _mix, ...srcNodes } as Record<string, AudioNode>;\n },\n\n updateParam(nodes, module, param, value) {\n const now = nodes.input.context.currentTime;\n const setRate = (horn: number, inertia: boolean) => {\n const hs = nodes.hornSpeed as ConstantSourceNode;\n const ds = nodes.drumSpeed as ConstantSourceNode;\n const up = horn > hs.offset.value;\n const tH = inertia ? (up ? HORN.tauUp : HORN.tauDown) : 0.05;\n const tD = inertia ? (up ? DRUM.tauUp : DRUM.tauDown) : 0.05;\n hs.offset.cancelScheduledValues(now);\n ds.offset.cancelScheduledValues(now);\n hs.offset.setTargetAtTime(horn, now, tH);\n ds.offset.setTargetAtTime(horn * DRUM_RATIO, now, tD);\n };\n if (param === 'speed') {\n setRate(value === 'slow' ? module.slowRate : module.fastRate, true);\n } else if (param === 'slowRate') {\n if (module.speed === 'slow') setRate(value as number, false);\n } else if (param === 'fastRate') {\n if (module.speed === 'fast') setRate(value as number, false);\n } else if (param === 'mix') {\n (nodes._mix as ConstantSourceNode).offset.value = value as number;\n }\n },\n\n dispose(nodes) {\n for (const [k, n] of Object.entries(nodes)) {\n if (k.startsWith('src')) (n as OscillatorNode | ConstantSourceNode).stop();\n }\n (nodes._mix as ConstantSourceNode).stop();\n },\n\n});\n", "import { defineModule } from '../../core';\nimport { rotaryDescriptor } from './rotary';\nimport type { RotaryParams, RotaryInputs, RotaryOutputs, RotaryProps } from './rotary.types';\n\n\nexport const Rotary = /* @__PURE__ */ defineModule(rotaryDescriptor) as import('../../core').LibModule<RotaryParams, RotaryInputs, RotaryOutputs, RotaryProps>;\nexport type { RotaryParams, RotaryInputs, RotaryOutputs, RotaryProps };\n", "// @ts-nocheck \u2014 generated by scripts/lib/build.ts\nimport { createMix } from '@/lib/dsp/mix';\nimport { BaseModule } from '@/types/synth';\n\nexport interface SaturatorModule extends BaseModule {\n type: 'saturator';\n drive: number;\n warmth: number;\n mix: number;\n}\nimport { defineDescriptor, paramDefaults } from '@/modules/ModuleDescriptor';\n\n// \u2500\u2500\u2500 PARAMS \u2014 the signal contract (no UI knowledge) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nconst params = {\n // drive feeds both driveGain.gain (1 + drive*4) and the waveshaper curve \u2014\n // a conversion, not a 1:1 AudioParam write, so no node/field.\n drive: { unit: 'factor', default: 0.5, min: 0, max: 1, },\n // warmthFilter.gain = warmth * 6 \u2014 a scaled conversion, so no node/field.\n warmth: { unit: 'factor', default: 0.5, min: 0, max: 1, },\n mix: { node: '_mix', field: 'offset', unit: 'factor', default: 1.0, min: 0, max: 1, },\n} satisfies Record<string, ParamSpec>;\n\n\nfunction makeSaturationCurve(amount: number): Float32Array {\n const samples = 44100;\n const curve = new Float32Array(samples);\n const k = 1 + amount * 10;\n for (let i = 0; i < samples; i++) {\n const x = (i * 2) / samples - 1;\n curve[i] = Math.tanh(k * x) / Math.tanh(k);\n }\n return curve;\n}\n\n\nexport const saturatorDescriptor = /* @__PURE__ */ defineDescriptor({\n type: 'saturator',\n params,\n\n ports: {\n 'in': { type: 'input', signal: 'audio', node: 'input', },\n 'out': { type: 'output', signal: 'audio', node: 'output', },\n },\n\n createModule(id, position) {\n return { id, type: 'saturator', position, ...paramDefaults(params) };\n },\n\n createNodes(ctx, module) {\n const input = ctx.createGain();\n const output = ctx.createGain();\n const dryGain = ctx.createGain();\n const wetGain = ctx.createGain();\n const driveGain = ctx.createGain();\n const waveshaper = ctx.createWaveShaper();\n const warmthFilter = ctx.createBiquadFilter();\n\n driveGain.gain.value = 1 + module.drive * 4;\n waveshaper.curve = makeSaturationCurve(module.drive) as Float32Array<ArrayBuffer>;\n waveshaper.oversample = '2x';\n warmthFilter.type = 'lowshelf';\n warmthFilter.frequency.value = 300;\n warmthFilter.gain.value = module.warmth * 6;\n const _mix = createMix(ctx, dryGain, wetGain, module.mix, 'linear');\n\n input.connect(dryGain);\n input.connect(driveGain);\n driveGain.connect(waveshaper);\n waveshaper.connect(warmthFilter);\n warmthFilter.connect(wetGain);\n dryGain.connect(output);\n wetGain.connect(output);\n\n return { input, output, driveGain, waveshaper, warmthFilter, dryGain, wetGain, _mix };\n },\n\n updateParam(nodes, _m, param, value) {\n if (param === 'drive') {\n nodes.driveGain.gain.value = 1 + (value as number) * 4;\n nodes.waveshaper.curve = makeSaturationCurve(value as number) as Float32Array<ArrayBuffer>;\n } else if (param === 'warmth') {\n nodes.warmthFilter.gain.value = (value as number) * 6;\n } else if (param === 'mix') {\n (nodes._mix as ConstantSourceNode).offset.value = value as number;\n }\n },\n\n});\n", "import { defineModule } from '../../core';\nimport { saturatorDescriptor } from './saturator';\nimport type { SaturatorParams, SaturatorInputs, SaturatorOutputs, SaturatorProps } from './saturator.types';\n\n\nexport const Saturator = /* @__PURE__ */ defineModule(saturatorDescriptor) as import('../../core').LibModule<SaturatorParams, SaturatorInputs, SaturatorOutputs, SaturatorProps>;\nexport type { SaturatorParams, SaturatorInputs, SaturatorOutputs, SaturatorProps };\n", "// @ts-nocheck \u2014 generated by scripts/lib/build.ts\nimport type { BaseModule, Position } from '@/types/synth';\nimport { defineDescriptor, paramDefaults } from '@/modules/ModuleDescriptor';\nimport { createFdnTank, setTankDecay, tankEnergyGain500 } from '@/lib/dsp/fdnTank';\nimport { createPitchShifterNode } from '@/worklets';\nimport { createMix } from '@/lib/dsp/mix';\n\nexport interface ShimmerModule extends BaseModule {\n type: 'shimmer';\n decay: number;\n pitch: number;\n mix: number;\n shimmer: number;\n}\n\n// \u2500\u2500\u2500 REGEN LOOP GAIN (2026-09-30) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n// SHIMMER is the gain once round the regen loop (tank \u2192 highpass \u2192 pitch\n// shifter \u2192 back in), measured at 500 Hz \u2014 the band where DECAY is exact.\n// The tank's own energy gain grows with DECAY (a 10 s tail stores ~20\u00D7 the\n// energy of a 0.5 s one), so a fixed-gain regen would mean something\n// different at every DECAY. `regenNorm` divides it out:\n// norm = 1 / (\u221AE_tank(500 Hz) \u00B7 |HP(500 Hz)| \u00B7 \u221A(shifter energy))\n// so 0.5 = each octave generation 6 dB below the last at any DECAY, and\n// 0.95 = a near-endless climb. Before, the tank was capped at feedback 0.93\n// (DECAY 8 rang 3 s) and SHIMMER 0.5 was really ~1.06 round the loop.\nconst REGEN_HP_HZ = 300;\n/** Butterworth highpass, Q in dB for Web Audio HP (1/\u221A2 \u2192 \u22123.01 dB): no\n * resonant bump for the loop to pile up on every pass. */\nconst REGEN_HP_Q_DB = 20 * Math.log10(Math.SQRT1_2);\nconst HP_AT_500 = 1 / Math.sqrt(1 + Math.pow(REGEN_HP_HZ / 500, 4));\n/** Two Hann grains half a grain apart: \u03A3w\u00B2 averages 3/4 for any shift \u2260 0\n * (measured 0.733\u20130.755 on band noise; 1.0 at exactly 0 st, coherent). */\nconst SHIFTER_ENERGY = 0.75;\n\nfunction shimmerRegenNorm(decay: number): number {\n return 1 / (Math.sqrt(tankEnergyGain500(decay)) * HP_AT_500 * Math.sqrt(SHIFTER_ENERGY));\n}\n\n// \u2500\u2500\u2500 PARAMS \u2014 the signal contract \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n// `decay` sets the FDN tank's RT60 via setTankDecay (and retunes regenNorm).\n// `shimmer` maps 1:1 onto regenGain.gain. `pitch` re-tunes TWO worklets (L+R shifters) \u2014 not a\n// single AudioParam \u2014 so it stays a set-only knob. `mix` now runs through\n// createMix's ConstantSource (`_mix`), equal-power law, replacing the manual\n// cos/sin gain writes with the identical curve.\nconst params = {\n decay: { unit: 's', default: 3, min: 0.5, max: 10, scale: 'log', },\n pitch: { unit: 'semitone', default: 12, min: -12, max: 24, },\n mix: { node: '_mix', field: 'offset', unit: 'factor', default: 0.5, min: 0, max: 1, },\n shimmer: { node: 'regenGain', field: 'gain', unit: 'factor', default: 0.5, min: 0, max: 0.95, },\n} satisfies Record<string, ParamSpec>;\n\n\nexport const shimmerDescriptor = /* @__PURE__ */ defineDescriptor({\n type: 'shimmer',\n params,\n\n ports: {\n 'in': { type: 'input', signal: 'audio', node: 'input', },\n 'out': { type: 'output', signal: 'audio', node: 'output', },\n },\n\n createModule(id: string, position: Position): ShimmerModule {\n return { id, type: 'shimmer', position, ...paramDefaults(params) } as ShimmerModule;\n },\n\n createNodes(ctx, module) {\n const input = ctx.createGain();\n const output = ctx.createGain();\n const dryGain = ctx.createGain();\n const wetGain = ctx.createGain();\n\n const _mix = createMix(ctx, dryGain, wetGain, module.mix, 'equal-power');\n\n const tank = createFdnTank(ctx, { rt60: module.decay, damping: 0.5 });\n\n // Pitch-shifted regeneration, per channel like a real stereo shimmer\n // (Eventide-style): tank L/R \u2192 per-channel highpass \u2192 per-channel\n // granular shifter \u2192 merge \u2192 regen gain \u2192 back in. Summing to mid before\n // shifting would collapse the tail's width on every pass.\n // The explicit DelayNode is required: with the tank inside a worklet this\n // outer loop no longer contains a native DelayNode, and Web Audio mutes\n // any cycle without one. 20 ms also acts as a pleasant regen pre-delay.\n const splitter = ctx.createChannelSplitter(2);\n const merger = ctx.createChannelMerger(2);\n const mkRegenTap = (seed: number) => {\n const hp = ctx.createBiquadFilter();\n hp.type = 'highpass';\n hp.frequency.value = REGEN_HP_HZ; // keep the loop from accumulating mud\n hp.Q.value = REGEN_HP_Q_DB;\n const shifter = createPitchShifterNode(ctx, module.pitch, seed); // own grain jitter per side\n return { hp, shifter };\n };\n const tapL = mkRegenTap(0x51f15e);\n const tapR = mkRegenTap(0x2c1b3c6d);\n const regenNorm = ctx.createGain();\n regenNorm.gain.value = shimmerRegenNorm(module.decay);\n const regenGain = ctx.createGain();\n regenGain.gain.value = module.shimmer;\n const regenDelay = ctx.createDelay(0.1);\n regenDelay.delayTime.value = 0.02;\n\n tank.output.connect(splitter);\n splitter.connect(tapL.hp, 0);\n splitter.connect(tapR.hp, 1);\n tapL.hp.connect(tapL.shifter);\n tapR.hp.connect(tapR.shifter);\n tapL.shifter.connect(merger, 0, 0);\n tapR.shifter.connect(merger, 0, 1);\n merger.connect(regenNorm);\n regenNorm.connect(regenGain);\n regenGain.connect(regenDelay);\n regenDelay.connect(tank.input);\n\n input.connect(dryGain);\n input.connect(tank.input);\n tank.output.connect(wetGain);\n dryGain.connect(output);\n wetGain.connect(output);\n\n return {\n input, output, dryGain, wetGain, _mix, splitter, merger,\n highpassL: tapL.hp, highpassR: tapR.hp,\n pitchShifterL: tapL.shifter, pitchShifterR: tapR.shifter,\n regenNorm, regenGain, regenDelay,\n tankInput: tank.input, tankOutput: tank.output, tankNode: tank.node,\n };\n },\n\n updateParam(nodes, _m, param, value) {\n const now = nodes.input.context.currentTime;\n if (param === 'mix') {\n (nodes._mix as ConstantSourceNode).offset.value = value as number;\n } else if (param === 'shimmer') {\n nodes.regenGain.gain.setTargetAtTime(value as number, now, 0.02);\n } else if (param === 'pitch') {\n for (const key of ['pitchShifterL', 'pitchShifterR'] as const) {\n (nodes[key] as AudioWorkletNode).parameters.get('semitones')!\n .setTargetAtTime(value as number, now, 0.02);\n }\n } else if (param === 'decay') {\n setTankDecay({ node: nodes.tankNode as AudioWorkletNode }, value as number, now);\n nodes.regenNorm.gain.setTargetAtTime(shimmerRegenNorm(value as number), now, 0.02);\n }\n },\n\n});\n", "import { defineModule } from '../../core';\nimport { shimmerDescriptor } from './shimmer';\nimport type { ShimmerParams, ShimmerInputs, ShimmerOutputs, ShimmerProps } from './shimmer.types';\nimport pitch_shifter from '../worklet-src/pitch-shifter';\nimport fdn_reverb from '../worklet-src/fdn-reverb';\n\nexport const Shimmer = /* @__PURE__ */ defineModule(shimmerDescriptor, {\n worklets: {\n 'pitch-shifter': pitch_shifter,\n 'fdn-reverb': fdn_reverb,\n },\n}) as import('../../core').LibModule<ShimmerParams, ShimmerInputs, ShimmerOutputs, ShimmerProps>;\nexport type { ShimmerParams, ShimmerInputs, ShimmerOutputs, ShimmerProps };\n", "// @ts-nocheck \u2014 generated by scripts/lib/build.ts\nimport type { BaseModule, Position } from '@/types/synth';\nimport { defineDescriptor, paramDefaults } from '@/modules/ModuleDescriptor';\n\nexport interface SoftLimitModule extends BaseModule {\n type: 'soft-limit';\n ceiling: number;\n drive: number;\n knee: number;\n}\n\n// \u2500\u2500\u2500 PARAMS \u2014 the signal contract (no UI knowledge) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n// drive/knee rebuild the waveshaper curve; ceiling drives ceiling.gain via a\n// dB\u2192linear conversion. None is a 1:1 AudioParam write, so all set-only.\nconst params = {\n drive: { unit: 'factor', default: 0.5, min: 0, max: 1, },\n knee: { unit: 'factor', default: 0.5, min: 0, max: 1, },\n ceiling: { unit: 'dB', default: -0.5, min: -12, max: 0, },\n} satisfies Record<string, ParamSpec>;\n\n\nfunction makeSoftLimitCurve(knee: number, drive: number): Float32Array {\n const samples = 44100;\n const curve = new Float32Array(samples);\n const k = 0.1 + knee * 0.9;\n // Drive lives INSIDE the curve. The previous topology put a \u00D7(1+drive\u00B73)\n // GainNode in front of a curve that only spans input [\u22121, 1]: everything\n // past \u00B11 slammed into the curve's endpoint value \u2014 a hard clip at\n // 0.1+0.9\u00B7tanh(1), which is exactly the flat-topping a \"soft limit\"\n // module promises not to do (measured by probe:softlimit-rails,\n // 2026-08-08). Folding the drive into the transfer keeps the whole\n // driven range on the smooth tanh law; inputs beyond \u00B11 land on the\n // asymptote, which is correct limiter behaviour.\n const driveMul = 1 + drive * 3;\n for (let i = 0; i < samples; i++) {\n const x = ((i * 2) / samples - 1) * driveMul;\n if (Math.abs(x) < k) {\n curve[i] = x;\n } else {\n const sign = x > 0 ? 1 : -1;\n curve[i] = sign * (k + (1 - k) * Math.tanh((Math.abs(x) - k) / (1 - k)));\n }\n }\n return curve;\n}\n\n\nexport const softLimitDescriptor = /* @__PURE__ */ defineDescriptor({\n type: 'soft-limit' as const,\n params,\n\n ports: {\n 'in': { type: 'input' as const, signal: 'audio', node: 'input', },\n 'out': { type: 'output' as const, signal: 'audio', node: 'output', },\n },\n\n createModule(id: string, position: Position): SoftLimitModule {\n return { id, type: 'soft-limit', position, ...paramDefaults(params) };\n },\n\n createNodes(ctx, module) {\n const input = ctx.createGain();\n const output = ctx.createGain();\n const waveshaper = ctx.createWaveShaper();\n const ceiling = ctx.createGain();\n\n // No pre-gain node: drive is baked into the curve (see\n // makeSoftLimitCurve) so the shaper's input never leaves the curve's\n // defined domain.\n waveshaper.curve = makeSoftLimitCurve(module.knee, module.drive) as Float32Array<ArrayBuffer>;\n waveshaper.oversample = '2x';\n ceiling.gain.value = Math.pow(10, module.ceiling / 20);\n\n input.connect(waveshaper);\n waveshaper.connect(ceiling);\n ceiling.connect(output);\n\n return { input, output, waveshaper, ceiling };\n },\n\n updateParam(nodes, m, param, value) {\n if (param === 'drive') nodes.waveshaper.curve = makeSoftLimitCurve(m.knee, value as number) as Float32Array<ArrayBuffer>;\n else if (param === 'knee') nodes.waveshaper.curve = makeSoftLimitCurve(value as number, m.drive) as Float32Array<ArrayBuffer>;\n else if (param === 'ceiling') nodes.ceiling.gain.value = Math.pow(10, (value as number) / 20);\n },\n\n});\n", "import { defineModule } from '../../core';\nimport { softLimitDescriptor } from './soft-limit';\nimport type { SoftLimiterParams, SoftLimiterInputs, SoftLimiterOutputs, SoftLimiterProps } from './soft-limit.types';\n\n\nexport const SoftLimiter = /* @__PURE__ */ defineModule(softLimitDescriptor) as import('../../core').LibModule<SoftLimiterParams, SoftLimiterInputs, SoftLimiterOutputs, SoftLimiterProps>;\nexport type { SoftLimiterParams, SoftLimiterInputs, SoftLimiterOutputs, SoftLimiterProps };\n", "// @ts-nocheck \u2014 generated by scripts/lib/build.ts\nimport { createMix } from '@/lib/dsp/mix';\nimport { BaseModule } from '@/types/synth';\n\nexport interface SpringReverbModule extends BaseModule {\n type: 'spring-reverb';\n mix: number;\n decay: number;\n tone: number;\n drip: number;\n}\nimport { defineDescriptor, paramDefaults } from '@/modules/ModuleDescriptor';\n\nimport { createSpringReverbNode } from '@/worklets';\nimport { pulse } from '@/lib/dsp/pulse';\n\n// \u2500\u2500\u2500 PARAMS (single source of truth: knobs, defaults, hover tips, docs) \u2500\u2500\nconst params = {\n mix: { node: '_mix', field: 'offset', unit: 'factor', default: 0.35, min: 0, max: 1, },\n decay: { node: '_worklet', field: 'decay', default: 1.5, min: 0.3, max: 4, scale: 'log' as const, unit: 's', },\n tone: { node: '_worklet', field: 'tone', unit: 'factor', default: 0.6, min: 0, max: 1, },\n drip: { node: '_worklet', field: 'drip', unit: 'factor', default: 0.5, min: 0, max: 1, },\n} as const satisfies Record<string, ParamSpec>;\n\n\nexport const springReverbDescriptor = /* @__PURE__ */ defineDescriptor({\n type: 'spring-reverb',\n params,\n\n ports: {\n 'in': { type: 'input', signal: 'audio', node: 'input', },\n 'knock': { type: 'input', signal: 'gate', node: '_knockIn', },\n 'out': { type: 'output', signal: 'audio', node: 'output', },\n },\n\n createModule(id, position): SpringReverbModule {\n return { id, type: 'spring-reverb', position, ...paramDefaults(params) };\n },\n\n createNodes(ctx, module) {\n const input = ctx.createGain();\n const output = ctx.createGain();\n const dryGain = ctx.createGain();\n const wetGain = ctx.createGain();\n\n const _worklet = createSpringReverbNode(ctx, {\n decay: module.decay,\n tone: module.tone,\n drip: module.drip,\n });\n\n // Knock trigger: second input of the worklet.\n const _knockIn = ctx.createGain();\n _knockIn.gain.value = 1;\n _knockIn.connect(_worklet, 0, 1);\n\n // Equal-power mix law: 50% keeps both paths at \u22123 dB instead of the\n // \u22126 dB dip a linear crossfade causes between two correlated-ish signals.\n const _mix = createMix(ctx, dryGain, wetGain, module.mix, 'equal-power');\n\n input.connect(dryGain);\n input.connect(_worklet, 0, 0);\n _worklet.connect(wetGain);\n dryGain.connect(output);\n wetGain.connect(output);\n\n return { input, output, dryGain, wetGain, _mix, _worklet, _knockIn };\n },\n\n updateParam(nodes, _module, param, value, when) {\n const worklet = nodes._worklet as AudioWorkletNode;\n if (param === 'mix') {\n (nodes._mix as ConstantSourceNode).offset.value = value as number;\n } else if (param === 'decay' || param === 'tone' || param === 'drip') {\n worklet.parameters.get(param)!.value = value as number;\n } else if (param === 'knock') {\n // Panel button = a rising edge on the KNOCK input (same path as a cable).\n pulse(nodes._knockIn as AudioNode, when);\n }\n },\n\n dispose(_nodes) {},\n\n});\n", "import { defineModule } from '../../core';\nimport { springReverbDescriptor } from './spring-reverb';\nimport type { SpringReverbParams, SpringReverbInputs, SpringReverbOutputs, SpringReverbProps } from './spring-reverb.types';\nimport spring_reverb from '../worklet-src/spring-reverb';\n\nexport const SpringReverb = /* @__PURE__ */ defineModule(springReverbDescriptor, {\n worklets: {\n 'spring-reverb': spring_reverb,\n },\n}) as import('../../core').LibModule<SpringReverbParams, SpringReverbInputs, SpringReverbOutputs, SpringReverbProps>;\nexport type { SpringReverbParams, SpringReverbInputs, SpringReverbOutputs, SpringReverbProps };\n", "// @ts-nocheck \u2014 generated by scripts/lib/build.ts\nimport { BaseModule } from '@/types/synth';\nimport { defineDescriptor, paramDefaults } from '@/modules/ModuleDescriptor';\n\nexport interface StereoSpreadModule extends BaseModule {\n type: 'stereo-spread';\n spread: number;\n center: number;\n}\n\n// \u2500\u2500\u2500 PARAMS \u2014 the signal contract \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n// `width` is a straight dry/wet level on the widened-highs bus, so it maps\n// 1:1 onto wetGain.gain. `spread` drives THREE things at once (two pan\n// positions plus a delay time) and `center` re-tunes two filters \u2014 neither\n// is a single AudioParam, so both stay set-only.\nconst params = {\n spread: { unit: 'factor', default: 0.7, min: 0, max: 1, },\n center: { unit: 'Hz', default: 800, min: 200, max: 2000, scale: 'log', },\n} satisfies Record<string, ParamSpec>;\n\n\n/**\n * Stereo Spread \u2014 frequency-dependent stereo widening via Haas effect.\n *\n * Lows (below CENTER) pass through unaffected.\n * Highs are split into two paths:\n * - Direct \u2192 panned left by SPREAD amount\n * - Micro-delayed (0\u20135ms) \u2192 panned right by SPREAD amount\n * This creates real psychoacoustic stereo width via the Haas/precedence effect.\n *\n * WIDTH controls dry/wet balance of the widened highs.\n */\nexport const stereoSpreadDescriptor = /* @__PURE__ */ defineDescriptor({\n type: 'stereo-spread',\n params,\n\n ports: {\n 'in': { type: 'input', signal: 'audio', node: 'input', },\n 'out': { type: 'output', signal: 'audio', node: 'output', },\n },\n\n createModule(id, position) {\n return { id, type: 'stereo-spread', position, ...paramDefaults(params) } as StereoSpreadModule;\n },\n\n createNodes(ctx, module) {\n const input = ctx.createGain();\n const output = ctx.createGain();\n\n // Crossover\n const lowpass = ctx.createBiquadFilter();\n const highpass = ctx.createBiquadFilter();\n lowpass.type = 'lowpass';\n lowpass.frequency.value = module.center;\n highpass.type = 'highpass';\n highpass.frequency.value = module.center;\n\n // Haas widening for highs: direct path panned left, delayed path panned right\n const panLeft = ctx.createStereoPanner();\n const panRight = ctx.createStereoPanner();\n const haasDelay = ctx.createDelay(0.02);\n\n panLeft.pan.value = -module.spread;\n panRight.pan.value = module.spread;\n haasDelay.delayTime.value = module.spread * 0.005; // 0\u20135ms\n\n // Width controls wet level of the widened highs\n const wetGain = ctx.createGain();\n wetGain.gain.value = module.width;\n\n // Lows pass through directly (mono, centered)\n input.connect(lowpass);\n lowpass.connect(output);\n\n // Highs: split into left (direct) + right (delayed) for Haas effect\n input.connect(highpass);\n highpass.connect(panLeft); // direct highs \u2192 left\n highpass.connect(haasDelay); // delayed highs \u2192 right\n haasDelay.connect(panRight);\n panLeft.connect(wetGain);\n panRight.connect(wetGain);\n wetGain.connect(output);\n\n return { input, output, lowpass, highpass, panLeft, panRight, haasDelay, wetGain };\n },\n\n updateParam(nodes, _m, param, value) {\n if (param === 'spread') {\n nodes.panLeft.pan.value = -(value as number);\n nodes.panRight.pan.value = value as number;\n nodes.haasDelay.delayTime.value = (value as number) * 0.005;\n } else if (param === 'width') {\n nodes.wetGain.gain.value = value as number;\n } else if (param === 'center') {\n nodes.lowpass.frequency.value = value as number;\n nodes.highpass.frequency.value = value as number;\n }\n },\n\n});\n", "import { defineModule } from '../../core';\nimport { stereoSpreadDescriptor } from './stereo-spread';\nimport type { StereoSpreadParams, StereoSpreadInputs, StereoSpreadOutputs, StereoSpreadProps } from './stereo-spread.types';\n\n\nexport const StereoSpread = /* @__PURE__ */ defineModule(stereoSpreadDescriptor) as import('../../core').LibModule<StereoSpreadParams, StereoSpreadInputs, StereoSpreadOutputs, StereoSpreadProps>;\nexport type { StereoSpreadParams, StereoSpreadInputs, StereoSpreadOutputs, StereoSpreadProps };\n", "// @ts-nocheck \u2014 generated by scripts/lib/build.ts\nimport type { BaseModule, Position } from '@/types/synth';\nimport { createSubOctaveNode } from '@/worklets';\nimport { defineDescriptor, paramDefaults } from '@/modules/ModuleDescriptor';\n\nexport interface SubHarmModule extends BaseModule {\n type: 'sub-harm';\n direct: number;\n octave1: number;\n octave2: number;\n}\n\n// \u2500\u2500\u2500 PARAMS \u2014 the signal contract (no UI knowledge) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nconst params = {\n direct: { node: 'dryGain', field: 'gain', unit: 'factor', default: 1, min: 0, max: 1, },\n octave1: { node: 'subOctave', field: 'oct1Level', unit: 'factor', default: 0.5, min: 0, max: 1, },\n octave2: { node: 'subOctave', field: 'oct2Level', unit: 'factor', default: 0.3, min: 0, max: 1, },\n} satisfies Record<string, ParamSpec>;\n\n\n\nexport const subHarmDescriptor = /* @__PURE__ */ defineDescriptor({\n type: 'sub-harm' as const,\n params,\n\n ports: {\n 'in': { type: 'input' as const, signal: 'audio', node: 'input', },\n 'out': { type: 'output' as const, signal: 'audio', node: 'output', },\n },\n\n createModule(id: string, position: Position): SubHarmModule {\n return { id, type: 'sub-harm', position, ...paramDefaults(params) };\n },\n\n createNodes(ctx, module) {\n const input = ctx.createGain();\n const output = ctx.createGain();\n const dryGain = ctx.createGain();\n const wetGain = ctx.createGain();\n\n // Worklet does real frequency division via zero-crossing flip-flop\n const subOctave = createSubOctaveNode(ctx);\n (subOctave.parameters as any).get('oct1Level').value = module.octave1;\n (subOctave.parameters as any).get('oct2Level').value = module.octave2;\n\n // Lowpass to smooth the square-wave sub output\n const subFilter = ctx.createBiquadFilter();\n subFilter.type = 'lowpass';\n subFilter.frequency.value = 400;\n subFilter.Q.value = 0.7;\n\n dryGain.gain.value = module.direct;\n wetGain.gain.value = 1;\n\n input.connect(dryGain);\n input.connect(subOctave);\n subOctave.connect(subFilter);\n subFilter.connect(wetGain);\n dryGain.connect(output);\n wetGain.connect(output);\n\n return { input, output, subOctave, dryGain, wetGain };\n },\n\n updateParam(nodes, _m, param, value) {\n if (param === 'octave1') {\n (nodes.subOctave.parameters as any).get('oct1Level').value = value as number;\n } else if (param === 'octave2') {\n (nodes.subOctave.parameters as any).get('oct2Level').value = value as number;\n } else if (param === 'direct') {\n nodes.dryGain.gain.value = value as number;\n }\n },\n\n});\n", "import { defineModule } from '../../core';\nimport { subHarmDescriptor } from './sub-harm';\nimport type { SubharmonicParams, SubharmonicInputs, SubharmonicOutputs, SubharmonicProps } from './sub-harm.types';\nimport freq_divider from '../worklet-src/freq-divider';\n\nexport const Subharmonic = /* @__PURE__ */ defineModule(subHarmDescriptor, {\n worklets: {\n 'freq-divider': freq_divider,\n },\n}) as import('../../core').LibModule<SubharmonicParams, SubharmonicInputs, SubharmonicOutputs, SubharmonicProps>;\nexport type { SubharmonicParams, SubharmonicInputs, SubharmonicOutputs, SubharmonicProps };\n", "// @ts-nocheck \u2014 generated by scripts/lib/build.ts\nimport { BaseModule } from '@/types/synth';\nimport { defineDescriptor, paramDefaults } from '@/modules/ModuleDescriptor';\nimport { createTapeDelayNode } from '@/worklets';\nimport { createMix } from '@/lib/dsp/mix';\n\nexport interface TapeDelayModule extends BaseModule {\n type: 'tape-delay';\n time: number;\n feedback: number;\n mix: number;\n flutter: number;\n saturation: number;\n}\n\n// \u2500\u2500\u2500 PARAMS \u2014 the signal contract \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n// `time`/`feedback`/`saturation`/`flutter` drive the tape-delay worklet's own\n// AudioParams 1:1 (TIME varispeed glide happens inside the worklet). `mix`\n// now runs through createMix's ConstantSource (`_mix`), linear law.\nconst params = {\n time: { node: 'worklet', field: 'time', unit: 's', default: 0.375, min: 0.05, max: 1.5, scale: 'log', },\n feedback: { node: 'worklet', field: 'feedback', unit: 'factor', default: 0.5, min: 0, max: 0.95, },\n mix: { node: '_mix', field: 'offset', unit: 'factor', default: 0.4, min: 0, max: 1, },\n flutter: { node: 'worklet', field: 'flutter', unit: 'factor', default: 0.3, min: 0, max: 1, },\n saturation: { node: 'worklet', field: 'saturation', unit: 'factor', default: 0.4, min: 0, max: 1, },\n} satisfies Record<string, ParamSpec>;\n\n\n// nodes: [input, output, worklet, dryGain, wetGain, _mix]\n//\n// The delay/saturation/feedback/flutter graph lives in the 'tape-delay'\n// AudioWorklet (src/worklets/tape-delay.ts) as of 2026-08-08: the native\n// version put a 2x-oversampled WaveShaper inside the feedback cycle, and\n// Chrome's oversampler adds 128 samples of unspec'd latency, so echoes ran\n// one render quantum off the TIME grid even after the cycle compensation.\n// The worklet also carries the module report's missing tape behaviours:\n// per-repeat 6 kHz damping, composite wow+flutter (seeded, deterministic),\n// and varispeed TIME glide. Dry/wet mix stays native, same as before.\nexport const tapeDelayDescriptor = /* @__PURE__ */ defineDescriptor({\n type: 'tape-delay',\n params,\n\n ports: {\n 'in': { type: 'input', signal: 'audio', node: 'input', },\n 'out': { type: 'output', signal: 'audio', node: 'output', },\n },\n\n createModule(id, position) {\n return { id, type: 'tape-delay', position, ...paramDefaults(params) } as TapeDelayModule;\n },\n\n createNodes(ctx, module) {\n const input = ctx.createGain();\n const output = ctx.createGain();\n const dryGain = ctx.createGain();\n const wetGain = ctx.createGain();\n const worklet = createTapeDelayNode(ctx, {\n time: module.time,\n feedback: module.feedback,\n saturation: module.saturation,\n flutter: module.flutter,\n });\n\n const _mix = createMix(ctx, dryGain, wetGain, module.mix, 'linear');\n\n input.connect(dryGain);\n input.connect(worklet);\n worklet.connect(wetGain);\n dryGain.connect(output);\n wetGain.connect(output);\n\n return { input, output, worklet, dryGain, wetGain, _mix };\n },\n\n updateParam(nodes, _m, param, value) {\n const worklet = nodes.worklet as AudioWorkletNode;\n if (param === 'time' || param === 'feedback' || param === 'saturation' || param === 'flutter') {\n // TIME slew (varispeed glide) happens inside the worklet, so the\n // param itself is set instantly.\n const p = worklet.parameters.get(param);\n if (p) p.value = value as number;\n } else if (param === 'mix') {\n (nodes._mix as ConstantSourceNode).offset.value = value as number;\n }\n },\n\n});\n", "import { defineModule } from '../../core';\nimport { tapeDelayDescriptor } from './tape-delay';\nimport type { TapeDelayParams, TapeDelayInputs, TapeDelayOutputs, TapeDelayProps } from './tape-delay.types';\nimport tape_delay from '../worklet-src/tape-delay';\n\nexport const TapeDelay = /* @__PURE__ */ defineModule(tapeDelayDescriptor, {\n worklets: {\n 'tape-delay': tape_delay,\n },\n}) as import('../../core').LibModule<TapeDelayParams, TapeDelayInputs, TapeDelayOutputs, TapeDelayProps>;\nexport type { TapeDelayParams, TapeDelayInputs, TapeDelayOutputs, TapeDelayProps };\n", "// @ts-nocheck \u2014 generated by scripts/lib/build.ts\n\nimport type { BaseModule, Position } from '@/types/synth';\n\nexport interface TapeStopModule extends BaseModule {\n type: 'tape-stop';\n time: number;\n mix: number;\n}\nimport { defineDescriptor, paramDefaults } from '@/modules/ModuleDescriptor';\n\n// \u2500\u2500\u2500 PARAMS (single source of truth: knobs, defaults, hover tips, docs) \u2500\u2500\nconst params = {\n time: { node: '_worklet', field: 'time', default: 0.5, min: 0.01, max: 4, scale: 'log' as const, unit: 's', },\n mix: { node: '_worklet', field: 'mix', unit: 'factor', default: 1.0, min: 0, max: 1, },\n} as const satisfies Record<string, ParamSpec>;\n\nimport { createTapeStopNode } from '@/worklets';\nimport { pulse } from '@/lib/dsp/pulse';\n\n\nexport const tapeStopDescriptor = /* @__PURE__ */ defineDescriptor({\n type: 'tape-stop' as const,\n params,\n\n ports: {\n 'in': { type: 'input' as const, signal: 'audio', node: '_worklet', },\n 'trigger': { type: 'input' as const, signal: 'gate', node: '_trigIn', },\n 'out': { type: 'output' as const, signal: 'audio', node: 'output', },\n },\n\n createModule(id: string, position: Position): TapeStopModule {\n return { id, type: 'tape-stop', position, ...paramDefaults(params) };\n },\n\n createNodes(ctx, module) {\n const _worklet = createTapeStopNode(ctx, module.time, module.mix);\n\n // Trigger input: second input of the worklet\n const _trigIn = ctx.createGain();\n _trigIn.gain.value = 1;\n _trigIn.connect(_worklet, 0, 1);\n\n const output = ctx.createGain();\n _worklet.connect(output);\n\n return { _worklet, _trigIn, output };\n },\n\n updateParam(nodes, _module, param, value, when) {\n if (param === 'time') {\n nodes._worklet.parameters.get('time')!.value = value as number;\n } else if (param === 'mix') {\n nodes._worklet.parameters.get('mix')!.value = value as number;\n } else if (param === 'trigger') {\n // Panel button = a rising edge on the TRIG input (same path as a cable).\n pulse(nodes._trigIn, when);\n }\n },\n\n dispose(_nodes) {},\n\n});", "import { defineModule } from '../../core';\nimport { tapeStopDescriptor } from './tape-stop';\nimport type { TapeStopParams, TapeStopInputs, TapeStopOutputs, TapeStopProps } from './tape-stop.types';\nimport tape_stop from '../worklet-src/tape-stop';\n\nexport const TapeStop = /* @__PURE__ */ defineModule(tapeStopDescriptor, {\n worklets: {\n 'tape-stop': tape_stop,\n },\n}) as import('../../core').LibModule<TapeStopParams, TapeStopInputs, TapeStopOutputs, TapeStopProps>;\nexport type { TapeStopParams, TapeStopInputs, TapeStopOutputs, TapeStopProps };\n", "// @ts-nocheck \u2014 generated by scripts/lib/build.ts\nimport { BaseModule } from '@/types/synth';\n\nexport interface TiltEQModule extends BaseModule {\n type: 'tilt-eq';\n tilt: number;\n frequency: number;\n}\nimport { defineDescriptor, paramDefaults } from '@/modules/ModuleDescriptor';\n\n// \u2500\u2500\u2500 PARAMS \u2500 the signal contract (no UI knowledge) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nconst params = {\n tilt: { unit: 'dB', default: 0, min: -12, max: 12, },\n frequency: { unit: 'Hz', default: 1000, min: 200, max: 5000, },\n} satisfies Record<string, ParamSpec>;\n\n// \u2500\u2500\u2500 UI \u2500 presentation layer (stripped from the library) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n\n// \u2500\u2500\u2500 DESCRIPTOR \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport const tiltEqDescriptor = /* @__PURE__ */ defineDescriptor({\n type: 'tilt-eq',\n params,\n\n\n ports: {\n 'in': { type: 'input', signal: 'audio', node: 'input', },\n 'out': { type: 'output', signal: 'audio', node: 'output', },\n },\n\n\n createModule(id, position) {\n return { id, type: 'tilt-eq', position, ...paramDefaults(params) };\n },\n\n createNodes(ctx, module) {\n const input = ctx.createGain();\n const output = ctx.createGain();\n const lowShelf = ctx.createBiquadFilter();\n const highShelf = ctx.createBiquadFilter();\n lowShelf.type = 'lowshelf';\n lowShelf.frequency.value = module.frequency;\n lowShelf.gain.value = -module.tilt;\n highShelf.type = 'highshelf';\n highShelf.frequency.value = module.frequency;\n highShelf.gain.value = module.tilt;\n input.connect(lowShelf);\n lowShelf.connect(highShelf);\n highShelf.connect(output);\n return { input, output, lowShelf, highShelf };\n },\n\n updateParam(nodes, _m, param, value) {\n if (param === 'tilt') {\n nodes.lowShelf.gain.value = -(value as number);\n nodes.highShelf.gain.value = value as number;\n } else if (param === 'frequency') {\n nodes.lowShelf.frequency.value = value as number;\n nodes.highShelf.frequency.value = value as number;\n }\n },\n\n});\n", "import { defineModule } from '../../core';\nimport { tiltEqDescriptor } from './tilt';\nimport type { TiltParams, TiltInputs, TiltOutputs, TiltProps } from './tilt.types';\n\n\nexport const Tilt = /* @__PURE__ */ defineModule(tiltEqDescriptor) as import('../../core').LibModule<TiltParams, TiltInputs, TiltOutputs, TiltProps>;\nexport type { TiltParams, TiltInputs, TiltOutputs, TiltProps };\n", "// @ts-nocheck \u2014 generated by scripts/lib/build.ts\nimport { BaseModule } from '@/types/synth';\n\nexport interface TremoloModule extends BaseModule {\n type: 'tremolo';\n rate: number;\n depth: number;\n shape: 'sine' | 'triangle' | 'square';\n}\nimport { defineDescriptor, paramDefaults } from '@/modules/ModuleDescriptor';\n\n\nconst shapes = ['sine', 'triangle', 'square'] as const;\n\nconst params = {\n rate: { node: 'lfo', field: 'frequency', unit: 'Hz', default: 5, min: 0.5, max: 20, },\n depth: { unit: 'factor', default: 0.5, min: 0, max: 1, },\n shape: { kind: 'enum', options: shapes, default: 'sine', },\n} satisfies Record<string, ParamSpec>;\n\n\n\nexport const tremoloDescriptor = /* @__PURE__ */ defineDescriptor({\n type: 'tremolo',\n params,\n\n ports: {\n 'in': { type: 'input', signal: 'audio', node: 'input', },\n 'out': { type: 'output', signal: 'audio', node: 'output', },\n 'modRate': { type: 'modulation', signal: 'modulation', node: 'lfo', field: 'frequency' },\n },\n\n createModule(id, position) {\n return { id, type: 'tremolo', position, ...paramDefaults(params) };\n },\n\n createNodes(ctx, module) {\n const input = ctx.createGain();\n const output = ctx.createGain();\n const tremGain = ctx.createGain();\n const lfo = ctx.createOscillator();\n const lfoGain = ctx.createGain();\n const dcOffset = ctx.createConstantSource();\n tremGain.gain.value = 0;\n lfo.type = module.shape as OscillatorType;\n lfo.frequency.value = module.rate;\n lfoGain.gain.value = module.depth * 0.5;\n dcOffset.offset.value = 1 - module.depth * 0.5;\n lfo.connect(lfoGain);\n lfoGain.connect(tremGain.gain);\n dcOffset.connect(tremGain.gain);\n lfo.start();\n dcOffset.start();\n input.connect(tremGain);\n tremGain.connect(output);\n return { input, output, lfo, lfoGain, dcOffset };\n },\n\n updateParam(nodes, _m, param, value) {\n switch (param) {\n case 'rate': nodes.lfo.frequency.value = value as number; break;\n case 'depth':\n nodes.lfoGain.gain.value = (value as number) * 0.5;\n nodes.dcOffset.offset.value = 1 - (value as number) * 0.5;\n break;\n case 'shape': nodes.lfo.type = value as OscillatorType; break;\n }\n },\n\n dispose(nodes) {\n nodes.lfo.stop();\n nodes.dcOffset.stop();\n },\n\n});\n", "import { defineModule } from '../../core';\nimport { tremoloDescriptor } from './tremolo';\nimport type { TremoloParams, TremoloInputs, TremoloOutputs, TremoloProps } from './tremolo.types';\n\n\nexport const Tremolo = /* @__PURE__ */ defineModule(tremoloDescriptor) as import('../../core').LibModule<TremoloParams, TremoloInputs, TremoloOutputs, TremoloProps>;\nexport type { TremoloParams, TremoloInputs, TremoloOutputs, TremoloProps };\n", "// @ts-nocheck \u2014 generated by scripts/lib/build.ts\nimport type { BaseModule, Position } from '@/types/synth';\n\nexport interface GainModule extends BaseModule {\n type: 'gain';\n gain: number;\n /** CV attenuverter: scales (and can invert) the signal patched into the CV input. */\n cvAmount?: number;\n}\nimport { defineDescriptor, paramDefaults } from '@/modules/ModuleDescriptor';\n\n// \u2500\u2500\u2500 PARAMS (single source of truth: knobs, defaults, hover tips, docs) \u2500\u2500\nconst params = {\n gain: { node: 'gain', field: 'gain', unit: 'factor', default: 0.5, min: 0, max: 2, },\n cvAmount: { node: 'gain', field: 'cvAmount', unit: 'factor', default: 1, min: -1, max: 1, },\n} satisfies Record<string, ParamSpec>;\nimport { createVcaNode } from '@/worklets';\n\n// \u2500\u2500\u2500 UI \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n\n// \u2500\u2500\u2500 DESCRIPTOR \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport const gainDescriptor = /* @__PURE__ */ defineDescriptor({\n type: 'gain',\n params,\n\n\n\n ports: {\n 'in': { type: 'input', signal: 'audio', node: 'gain', },\n 'out': { type: 'output', signal: 'audio', node: 'gain', },\n 'modGain': { type: 'modulation', signal: 'modulation', node: 'gain', field: 'cv' },\n },\n\n createModule(id: string, position: Position): GainModule {\n return { id, type: 'gain', position, ...paramDefaults(params) };\n },\n\n createNodes(ctx, module) {\n const gain = createVcaNode(ctx, module.gain, module.cvAmount ?? 1);\n return { gain };\n },\n\n updateParam(nodes, _module, param, value) {\n if (param === 'gain' || param === 'cvAmount') {\n const p = nodes.gain.parameters.get(param);\n if (p) p.value = value as number;\n }\n },\n\n});\n", "import { defineModule } from '../../core';\nimport { gainDescriptor } from './vca';\nimport type { VcaParams, VcaInputs, VcaOutputs, VcaProps } from './vca.types';\nimport vca from '../worklet-src/vca';\n\nexport const Vca = /* @__PURE__ */ defineModule(gainDescriptor, {\n worklets: {\n 'vca': vca,\n },\n}) as import('../../core').LibModule<VcaParams, VcaInputs, VcaOutputs, VcaProps>;\nexport type { VcaParams, VcaInputs, VcaOutputs, VcaProps };\n", "/**\n * Gain compensation helpers for resonant filters.\n *\n * Web Audio's `BiquadFilterNode` bandpass is normalised to **unity gain at the\n * centre frequency**, which is not how a resonant analog filter behaves. A\n * Cry Baby's inductor stage, a modal resonator, a formant bank \u2014 all of them\n * *boost* at resonance, and the narrower the peak, the bigger the boost. With\n * a unity-peak biquad the audible result is that turning RES up makes a patch\n * quieter and quieter until it disappears, because a narrow window throws away\n * almost all of a broadband source's energy.\n *\n * ### The maths\n *\n * For white noise of power-spectral density `S`, a 2-pole bandpass with unity\n * peak gain has equivalent noise bandwidth `(\u03C0/2)\u00B7f0/Q`, so\n *\n * ```text\n * P_out = S \u00B7 (\u03C0/2) \u00B7 f0 / Q \u21D2 RMS_out \u221D 1 / sqrt(Q)\n * ```\n *\n * Multiplying the filter output by `sqrt(Q)` therefore makes the *loudness*\n * independent of Q: RES becomes a tone control instead of a volume control,\n * which is exactly what a real resonant filter feels like under the fingers.\n * It also lands the peak gain in the right place \u2014 `sqrt(8) \u2248 +9 dB`,\n * `sqrt(20) \u2248 +13 dB`, against roughly +9\u2026+18 dB measured on a real wah.\n *\n * The cap keeps a self-oscillating setting from turning a sine that sits\n * exactly on the peak into a clipped square.\n */\nexport function bandpassMakeup(q: number, cap = 4): number {\n if (!Number.isFinite(q) || q <= 1) return 1;\n return Math.min(Math.sqrt(q), cap);\n}\n", "// @ts-nocheck \u2014 generated by scripts/lib/build.ts\nimport { BaseModule, FilterType } from '@/types/synth';\n\n\nexport interface FilterModule extends BaseModule {\n type: 'filter';\n filterType: FilterType;\n /** Cutoff as a note (69 = 440 Hz), driving the V/OCT worklet 1:1. */\n note: number;\n resonance: number;\n /** Marker: resonance is true Q in every mode (LP/HP convert to dB in the\n * map-res worklet). Saves without it predate the convention and hold dB\n * values for LP/HP \u2014 migrated once in patchStorage/tabStorage. */\n resUnit?: 'q';\n}\nimport { defineDescriptor, paramDefaults } from '@/modules/ModuleDescriptor';\nimport { createMapResNode, createVoctFreqNode } from '@/worklets';\nimport { bandpassMakeup } from '@/lib/dsp/gainComp';\nimport { createKeepAlive } from '@/lib/dsp/keepAlive';\n\n/** Only the bandpass tap needs resonance makeup \u2014 see lib/dsp/gainComp. */\nconst makeupFor = (type: FilterType, q: number) =>\n type === 'bandpass' ? bandpassMakeup(q) : 1;\n\n/** Web Audio biquads read Q in dB for LP/HP, dimensionless for BP/notch. */\nconst qIsDb = (type: FilterType) => type === 'lowpass' || type === 'highpass';\n\n// \u2500\u2500\u2500 PARAMS \u2014 the signal contract (no UI knowledge) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nconst params = {\n filterType: { kind: 'enum', options: ['lowpass', 'highpass', 'bandpass', 'notch'], default: 'lowpass', },\n note: { node: '_cutoffVoct', field: 'transpose', unit: 'note', default: 83, min: 15, max: 135, },\n // Resonance is split across the map-res worklet AND a compensation gain,\n // so it cannot honestly declare a single AudioParam \u2014 see lib/dsp/mix.ts\n // convention: rebuild or leave set-only. It stays set-only here.\n resonance: { unit: 'factor', default: 1, min: 0.1, max: 20, scale: 'sqrt', },\n} satisfies Record<string, ParamSpec>;\n\n// \u2500\u2500\u2500 UI \u2014 presentation layer (stripped from the library) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n\n// \u2500\u2500\u2500 DESCRIPTOR \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport const filterDescriptor = /* @__PURE__ */ defineDescriptor({\n type: 'filter',\n params,\n\n\n ports: {\n 'in': { type: 'input', signal: 'audio', node: 'filter', },\n 'out': { type: 'output', signal: 'audio', node: 'output', },\n 'modFreq': { type: 'modulation', signal: 'modulation', node: '_cutoffVoct', },\n 'modQ': { type: 'modulation', signal: 'modulation', node: '_resMap', },\n },\n\n\n createModule(id, position): FilterModule {\n return { id, type: 'filter', position, resUnit: 'q', ...paramDefaults(params) } as FilterModule;\n },\n\n createNodes(ctx, module) {\n const filter = ctx.createBiquadFilter();\n filter.type = module.filterType as BiquadFilterType;\n filter.frequency.value = 0; // driven exclusively by voct\n filter.Q.value = 0; // driven exclusively by the map-res worklet\n\n // Bandpass is the one biquad mode Web Audio normalises to unity peak\n // gain, so a narrow setting would quietly throw the signal away. An\n // analog SVF's bandpass tap gets louder as it narrows; sqrt(Q) makeup\n // restores that. Every other mode passes through untouched.\n const output = ctx.createGain();\n output.gain.value = makeupFor(module.filterType as FilterType, module.resonance);\n filter.connect(output);\n\n // V/Oct cutoff: ConstantSource(0) \u2192 voct(transpose=cutoff note) \u2192 filter.frequency\n const _cutoffVoct = createVoctFreqNode(ctx);\n _cutoffVoct.parameters.get('transpose')!.value = module.note;\n\n const _cutoffBase = ctx.createConstantSource();\n _cutoffBase.offset.value = 0;\n _cutoffBase.start();\n\n _cutoffBase.connect(_cutoffVoct);\n _cutoffVoct.connect(filter.frequency);\n\n // True-Q resonance: RES knob and CV live in one Q domain for every mode.\n // The worklet clamps (knob + CV\u00B7fullRange) to 0.1\u201320, then feeds the\n // biquad what its Q param expects: 20\u00B7log10(Q) dB for LP/HP, plain Q\n // for BP/notch (Web Audio spec quirk \u2014 see worklets/map-res.ts).\n const _resMap = createMapResNode(ctx, {\n base: module.resonance,\n dbOut: qIsDb(module.filterType as FilterType),\n });\n _resMap.connect(filter.Q);\n\n // Keeps a resonant ping ringing past the end of its strike (Chrome cuts\n // silent-input biquads early \u2014 see dsp/keepAlive.ts).\n const _alive = createKeepAlive(ctx, filter);\n\n return { filter, output, _cutoffVoct, _cutoffBase, _resMap, _alive };\n },\n\n dispose(nodes) {\n try { nodes._cutoffBase.stop(); } catch (_) {}\n try { nodes._alive.stop(); } catch (_) {}\n },\n\n updateParam(nodes, module, param, value) {\n switch (param) {\n case 'filterType':\n nodes.filter.type = value as BiquadFilterType;\n nodes._resMap.parameters.get('dbOut')!.value = qIsDb(value as FilterType) ? 1 : 0;\n nodes.output.gain.value = makeupFor(value as FilterType, module.resonance);\n break;\n case 'note': nodes._cutoffVoct.parameters.get('transpose')!.value = value as number; break;\n case 'resonance':\n nodes._resMap.parameters.get('base')!.value = value as number;\n nodes.output.gain.value = makeupFor(module.filterType as FilterType, value as number);\n break;\n }\n },\n\n\n});\n", "import { defineModule } from '../../core';\nimport { filterDescriptor } from './vcf';\nimport type { VcfParams, VcfInputs, VcfOutputs, VcfProps } from './vcf.types';\nimport map_res from '../worklet-src/map-res';\nimport map_voct_to_freq from '../worklet-src/map-voct-to-freq';\n\nexport const Vcf = /* @__PURE__ */ defineModule(filterDescriptor, {\n worklets: {\n 'map-res': map_res,\n 'map-voct-to-freq': map_voct_to_freq,\n },\n}) as import('../../core').LibModule<VcfParams, VcfInputs, VcfOutputs, VcfProps>;\nexport type { VcfParams, VcfInputs, VcfOutputs, VcfProps };\n", "// @ts-nocheck \u2014 generated by scripts/lib/build.ts\nimport type { BaseModule, Position } from '@/types/synth';\n\nexport interface OscillatorModule extends BaseModule {\n type: 'oscillator';\n skew: number; // -1\u20131: symmetry (-1=rev saw, 0=symmetric, 1=saw)\n shape: number; // -1\u20131: curvature (-1=square, 0=triangle, 1=sine)\n note: number; // panel memory: absolute note (24\u2013108) while V/OCT is unpatched\n transpose?: number; // panel memory: semitone shift (\u221248\u201348) while V/OCT is patched\n offset?: number; // library-only DSP state (see params.offset); the app derives it\n detune: number; // -1 to 1 semitones (displayed as -100 to 100 cents)\n gain: number;\n}\nimport { defineDescriptor, paramDefaults } from '@/modules/ModuleDescriptor';\nimport { createVoctFreqNode, createWaveshaperNode } from '@/worklets';\n\n// \u2500\u2500\u2500 SETTINGS \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n// DSP signal contract. Pitch is plain V/OCT arithmetic: the sounding note is\n// the V/OCT input (absolute notes, silence = 0) plus `offset` semitones. No\n// normalling \u2014 `voct` is an ordinary summing input. The app panel keeps two\n// memories (absolute `note` unpatched, relative `transpose` patched) and writes\n// whichever applies into the offset; the DSP never knows about cables.\nconst params = {\n skew: { node: '_ws', field: 'skew', unit: 'factor', default: 1.0, min: -1, max: 1, },\n shape: { node: '_ws', field: 'shape', unit: 'factor', default: 0.0, min: -1, max: 1, },\n offset: { node: '_voct', field: 'transpose', default: 69, min: -48, max: 108, unit: 'semitone', },\n detune: { node: '_detune', field: 'offset', default: 0, min: -1, max: 1, unit: 'semitone', },\n gain: { node: 'gain', field: 'gain', unit: 'factor', default: 0.5, min: 0, max: 1, },\n} as const satisfies Record<string, ParamSpec>;\n\n/** Cables currently on V/OCT, per node set \u2014 picks the live panel memory. */\nconst patchCount = new WeakMap<object, number>();\n\n// \u2500\u2500\u2500 UI \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n\n// \u2500\u2500\u2500 DESCRIPTOR \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\nexport const oscillatorDescriptor = /* @__PURE__ */ defineDescriptor({\n type: 'oscillator',\n\n\n\n ports: {\n 'voct': { type: 'input', node: '_voct', signal: 'pitch' },\n 'out': { type: 'output', signal: 'audio', node: 'gain', },\n 'modSkew': { type: 'modulation', signal: 'modulation', node: '_ws', field: 'skew' },\n 'modShape': { type: 'modulation', signal: 'modulation', node: '_ws', field: 'shape' },\n 'modDetune': { type: 'modulation', signal: 'modulation', node: '_detune', field: 'offset' },\n },\n\n params,\n\n\n // \u2500\u2500\u2500 Factory \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n createModule(id: string, position: Position): OscillatorModule {\n const { offset: _dsp, ...rest } = paramDefaults(params);\n return { id, type: 'oscillator', position, ...rest, note: 69, transpose: 0 };\n },\n\n // \u2500\u2500\u2500 Audio Engine \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n\n createNodes(ctx, module) {\n // Waveshaper worklet replaces OscillatorNode\n const _ws = createWaveshaperNode(ctx);\n const gain = ctx.createGain();\n \n // Detune: ConstantSource in semitones, feeds into V/Oct sum\n const _detune = ctx.createConstantSource();\n _detune.offset.value = module.detune;\n _detune.start();\n\n // V/OCT worklet \u2014 always in the signal path.\n // V/OCT worklet \u2014 always in the signal path. Its input sums V/OCT cables\n // and detune; its `transpose` param is the pitch offset. Nothing patched\n // = silent input, so the offset alone is the note. Library instances set\n // `offset`; app modules start unpatched, so the note memory applies\n // (onConnect swaps to the transpose memory when a cable lands).\n const _voct = createVoctFreqNode(ctx);\n _detune.connect(_voct); // detune sums into V/Oct input\n _voct.connect(_ws); // frequency input to waveshaper\n _voct.parameters.get('transpose')!.value = module.offset ?? module.note;\n\n // Set initial waveshape params\n _ws.parameters.get('skew')!.value = module.skew;\n _ws.parameters.get('shape')!.value = module.shape;\n _ws.parameters.get('normalize')!.value = 1;\n\n gain.gain.value = module.gain;\n _ws.connect(gain);\n\n return { gain, _ws, _voct, _detune };\n },\n\n updateParam(nodes, _module, param, value) {\n switch (param) {\n case 'skew': nodes._ws.parameters.get('skew')!.value = value as number; break;\n case 'shape': nodes._ws.parameters.get('shape')!.value = value as number; break;\n case 'offset': nodes._voct.parameters.get('transpose')!.value = value as number; break;\n // App panel memories: only the one matching the patch state is live.\n case 'note':\n if (!patchCount.get(nodes)) nodes._voct.parameters.get('transpose')!.value = value as number;\n break;\n case 'transpose':\n if (patchCount.get(nodes)) nodes._voct.parameters.get('transpose')!.value = value as number;\n break;\n case 'detune': nodes._detune.offset.value = value as number; break;\n case 'gain': nodes.gain.gain.value = value as number; break;\n }\n },\n\n // App-only: the connection is a plain summing connect; these hooks only\n // swap which panel memory drives the offset.\n onConnect(nodes, module, portId, sourceNode) {\n if (portId !== 'voct') return false;\n sourceNode.connect(nodes._voct);\n patchCount.set(nodes, (patchCount.get(nodes) ?? 0) + 1);\n nodes._voct.parameters.get('transpose')!.value = module.transpose ?? 0;\n return true;\n },\n\n onDisconnect(nodes, module, portId, sourceNode) {\n if (portId !== 'voct') return false;\n try { sourceNode.disconnect(nodes._voct); } catch (e) {}\n const n = Math.max(0, (patchCount.get(nodes) ?? 0) - 1);\n patchCount.set(nodes, n);\n if (!n) nodes._voct.parameters.get('transpose')!.value = module.note;\n return true;\n },\n\n dispose(nodes) {\n nodes._detune.stop();\n },\n\n});\n", "import { defineModule } from '../../core';\nimport { oscillatorDescriptor } from './vco';\nimport type { VcoParams, VcoInputs, VcoOutputs, VcoProps } from './vco.types';\nimport map_voct_to_freq from '../worklet-src/map-voct-to-freq';\nimport waveshaper from '../worklet-src/waveshaper';\n\nexport const Vco = /* @__PURE__ */ defineModule(oscillatorDescriptor, {\n worklets: {\n 'map-voct-to-freq': map_voct_to_freq,\n 'waveshaper': waveshaper,\n },\n}) as import('../../core').LibModule<VcoParams, VcoInputs, VcoOutputs, VcoProps>;\nexport type { VcoParams, VcoInputs, VcoOutputs, VcoProps };\n", "// @ts-nocheck \u2014 generated by scripts/lib/build.ts\nimport { BaseModule } from '@/types/synth';\n\nimport { defineDescriptor, paramDefaults } from '@/modules/ModuleDescriptor';\nimport { createVoctFreqNode } from '@/worklets';\nimport { bandpassMakeup } from '@/lib/dsp/gainComp';\nimport { createKeepAlive } from '@/lib/dsp/keepAlive';\n\nexport interface WahModule extends BaseModule {\n type: 'wah';\n /** Center frequency as a note (69 = 440 Hz), driving the V/OCT worklet 1:1. */\n note: number;\n resonance: number;\n rate: number;\n depth: number;\n}\n\nconst params = {\n note: { node: '_cutoffVoct', field: 'transpose', unit: 'note', default: 79, min: 55, max: 95, },\n // Resonance drives both the filter Q and a separate makeup gain \u2014 a split, so it stays set-only.\n resonance: { unit: 'factor', default: 8, min: 1, max: 20, scale: 'log', },\n rate: { node: 'lfo', field: 'frequency', unit: 'Hz', default: 1, min: 0.1, max: 10, scale: 'log', },\n // Depth is stored 0-1 but scaled by 36 semitones onto lfoGain.gain \u2014 a conversion, so set-only.\n depth: { unit: 'factor', default: 0.6, min: 0, max: 1, },\n} satisfies Record<string, ParamSpec>;\n\n\n\nexport const wahDescriptor = /* @__PURE__ */ defineDescriptor({\n type: 'wah',\n params,\n\n ports: {\n 'in': { type: 'input', signal: 'audio', node: 'input', },\n 'out': { type: 'output', signal: 'audio', node: 'output', },\n 'modFreq': { type: 'modulation', signal: 'modulation', node: '_cutoffVoct', },\n },\n\n createModule(id, position) {\n return { id, type: 'wah', position, ...paramDefaults(params) };\n },\n\n createNodes(ctx, module) {\n const input = ctx.createGain();\n const output = ctx.createGain();\n const filter = ctx.createBiquadFilter();\n const lfo = ctx.createOscillator();\n const lfoGain = ctx.createGain();\n\n filter.type = 'bandpass';\n filter.frequency.value = 0; // driven by voct\n filter.Q.value = module.resonance;\n\n // A real wah's filter stage *boosts* at resonance; a Web Audio bandpass\n // peaks at unity, so a narrow setting would just fade the signal away.\n // sqrt(Q) makeup restores the pedal's resonant peak gain and keeps RES a\n // tone control rather than a volume control. See lib/dsp/gainComp.\n const makeup = ctx.createGain();\n makeup.gain.value = bandpassMakeup(module.resonance);\n\n // V/Oct cutoff\n const _cutoffVoct = createVoctFreqNode(ctx);\n _cutoffVoct.parameters.get('transpose')!.value = module.note;\n\n const _cutoffBase = ctx.createConstantSource();\n _cutoffBase.offset.value = 0;\n _cutoffBase.start();\n\n _cutoffBase.connect(_cutoffVoct);\n _cutoffVoct.connect(filter.frequency);\n\n // Internal LFO \u2192 voct input (semitones)\n // depth 1.0 = 36 semitones = 3 octaves of sweep\n lfo.type = 'sine';\n lfo.frequency.value = module.rate;\n lfoGain.gain.value = module.depth * 36;\n\n lfo.connect(lfoGain);\n lfoGain.connect(_cutoffVoct); // semitones \u2192 voct input\n lfo.start();\n\n input.connect(filter);\n filter.connect(makeup);\n makeup.connect(output);\n\n // Chrome cuts silent-input biquad rings early \u2014 see dsp/keepAlive.ts.\n const _alive = createKeepAlive(ctx, filter);\n\n return { input, output, filter, makeup, lfo, lfoGain, _cutoffVoct, _cutoffBase, _alive };\n },\n\n updateParam(nodes, _module, param, value) {\n if (param === 'note') {\n nodes._cutoffVoct.parameters.get('transpose')!.value = value as number;\n } else if (param === 'resonance') {\n nodes.filter.Q.value = value as number;\n nodes.makeup.gain.value = bandpassMakeup(value as number);\n\n } else if (param === 'rate') {\n nodes.lfo.frequency.value = value as number;\n } else if (param === 'depth') {\n nodes.lfoGain.gain.value = (value as number) * 36;\n }\n },\n\n dispose(nodes) {\n nodes.lfo.stop();\n nodes._cutoffBase.stop();\n nodes._alive.stop();\n },\n\n});\n", "import { defineModule } from '../../core';\nimport { wahDescriptor } from './wah';\nimport type { WahParams, WahInputs, WahOutputs, WahProps } from './wah.types';\nimport map_voct_to_freq from '../worklet-src/map-voct-to-freq';\n\nexport const Wah = /* @__PURE__ */ defineModule(wahDescriptor, {\n worklets: {\n 'map-voct-to-freq': map_voct_to_freq,\n },\n}) as import('../../core').LibModule<WahParams, WahInputs, WahOutputs, WahProps>;\nexport type { WahParams, WahInputs, WahOutputs, WahProps };\n", "// @ts-nocheck \u2014 generated by scripts/lib/build.ts\nimport { createMix } from '@/lib/dsp/mix';\nimport { BaseModule } from '@/types/synth';\nimport { defineDescriptor, paramDefaults } from '@/modules/ModuleDescriptor';\n\nexport interface WavefolderModule extends BaseModule {\n type: 'wavefolder';\n folds: number;\n symmetry: number;\n mix: number;\n}\n\n// \u2500\u2500\u2500 PARAMS \u2014 the signal contract (no UI knowledge) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\n// folds/symmetry rebuild the waveshaper curve \u2014 not a 1:1 AudioParam write.\nconst params = {\n folds: { unit: 'factor', default: 2, min: 1, max: 10, },\n symmetry: { unit: 'factor', default: 0, min: -1, max: 1, },\n mix: { node: '_mix', field: 'offset', unit: 'factor', default: 1.0, min: 0, max: 1, },\n} satisfies Record<string, ParamSpec>;\n\n\n/**\n * True sine-fold transfer: y = sin(\u03C0/2 \u00B7 folds \u00B7 (x + bias)), DC-compensated.\n *\n * FOLDS is baked into the curve itself so the transfer genuinely folds \u2014\n * folds 1 is a gentle monotonic shaper (x=\u00B11 \u2192 \u00B11), folds 10 reflects a\n * full-scale input ten quarter-periods deep. The previous design pre-scaled\n * the INPUT by folds into a fixed sin(\u03C0x) curve; WaveShaper clamps its\n * domain at \u00B11, so anything past drive 1 saturated at the curve endpoints\n * instead of folding (reports/wavefolder.md findings #1/#2). Input level\n * still plays the folder West-Coast style: quiet signals stay in the\n * near-linear origin segment, hot signals reach deeper folds.\n *\n * SYM biases the fold point (bias = 0.2\u00B7sym); the resulting DC at silence\n * is subtracted so an idle folder outputs 0, and the curve is renormalized\n * to peak 1 when the bias shift pushes it past full scale.\n */\nfunction makeWavefoldCurve(folds: number, symmetry: number): Float32Array {\n const samples = 65536;\n const curve = new Float32Array(samples);\n const bias = symmetry * 0.2;\n const w = (Math.PI / 2) * folds;\n const dc = Math.sin(w * bias);\n let peak = 0;\n for (let i = 0; i < samples; i++) {\n const x = (i * 2) / samples - 1;\n const y = Math.sin(w * (x + bias)) - dc;\n curve[i] = y;\n const a = Math.abs(y);\n if (a > peak) peak = a;\n }\n if (peak > 1) {\n const inv = 1 / peak;\n for (let i = 0; i < samples; i++) curve[i] *= inv;\n }\n return curve;\n}\n\n\nexport const wavefolderDescriptor = /* @__PURE__ */ defineDescriptor({\n type: 'wavefolder',\n params,\n\n ports: {\n 'in': { type: 'input', signal: 'audio', node: 'input', },\n 'out': { type: 'output', signal: 'audio', node: 'output', },\n },\n\n createModule(id, position) {\n return { id, type: 'wavefolder', position, ...paramDefaults(params) };\n },\n\n createNodes(ctx, module) {\n const input = ctx.createGain();\n const output = ctx.createGain();\n const dryGain = ctx.createGain();\n const wetGain = ctx.createGain();\n const waveshaper = ctx.createWaveShaper();\n\n waveshaper.curve = makeWavefoldCurve(module.folds, module.symmetry) as Float32Array<ArrayBuffer>;\n waveshaper.oversample = '4x';\n const _mix = createMix(ctx, dryGain, wetGain, module.mix, 'linear');\n\n // No pre-gain stage: FOLDS lives in the transfer curve, so the shaper's\n // \u00B11 domain is never exceeded and every knob position genuinely folds.\n input.connect(dryGain);\n input.connect(waveshaper);\n waveshaper.connect(wetGain);\n dryGain.connect(output);\n wetGain.connect(output);\n\n return { input, output, waveshaper, dryGain, wetGain, _mix };\n },\n\n updateParam(nodes, module, param, value) {\n if (param === 'folds' || param === 'symmetry') {\n // Same pattern as distortion: the reactive module proxy is mutated\n // before the engine relays the update, so both curve params are current.\n nodes.waveshaper.curve = makeWavefoldCurve(module.folds, module.symmetry) as Float32Array<ArrayBuffer>;\n } else if (param === 'mix') {\n (nodes._mix as ConstantSourceNode).offset.value = value as number;\n }\n },\n\n});\n", "import { defineModule } from '../../core';\nimport { wavefolderDescriptor } from './wavefolder';\nimport type { WavefolderParams, WavefolderInputs, WavefolderOutputs, WavefolderProps } from './wavefolder.types';\n\n\nexport const Wavefolder = /* @__PURE__ */ defineModule(wavefolderDescriptor) as import('../../core').LibModule<WavefolderParams, WavefolderInputs, WavefolderOutputs, WavefolderProps>;\nexport type { WavefolderParams, WavefolderInputs, WavefolderOutputs, WavefolderProps };\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["params", "voice", "t", "now", "ms", "db", "params", "params", "semitones", "params", "params", "params", "hz", "params", "params", "params", "params", "CURVE_POINTS", "lawCurve", "params", "params", "params", "params", "params", "params", "params", "params", "params", "params", "params", "params", "params", "params", "params", "params", "params", "params", "params", "noiseBuffer", "params", "params", "params", "params", "params", "params", "params", "patchCount", "params", "patchCount", "ms", "now", "params", "now", "params", "patchCount", "params", "now", "params", "params", "now", "params", "params", "params", "params", "params", "params", "params", "shapes", "params", "params", "params", "params", "patchCount", "params", "params"]
|
|
7
7
|
}
|