/** * Biquad filters and dynamics. * * Coefficient formulas follow the Audio EQ Cookbook (Robert Bristow-Johnson), * the same derivation the Web Audio `BiquadFilterNode` uses — so a filter * configured here and one configured in the browser produce matching results. */ export type FilterType = 'lowpass' | 'highpass' | 'bandpass' | 'notch' | 'peaking' | 'lowshelf' | 'highshelf' | 'allpass'; export interface FilterOptions { type: FilterType; /** Corner or centre frequency in Hz. */ frequency: number; /** Resonance. Defaults to 0.7071 (Butterworth — maximally flat, no peak). */ q?: number; /** Gain in dB. Used only by `peaking`, `lowshelf`, and `highshelf`. */ gain?: number; } /** Applies a biquad filter to every channel. */ export declare function applyFilter(channels: readonly Float32Array[], options: FilterOptions, sampleRate: number): Float32Array[]; export interface LimiterOptions { /** Ceiling in dBFS. Defaults to -1. The output is guaranteed not to exceed it. */ threshold?: number; /** * Lookahead in milliseconds. Defaults to 5. * * Gain reduction is ramped in over this window *before* a peak arrives, which * is what stops a hard limiter from sounding like a click on every transient. * It costs latency: the result is delayed by exactly this much, and the * function compensates so the returned audio stays sample-aligned with its * input. */ lookahead?: number; /** Release time in ms. Defaults to 50. */ release?: number; } /** * A lookahead peak limiter. * * The ceiling is a guarantee, not a target. That rules out the naive design — * smoothing the rectified signal and dividing by it — because a slow attack lets * the very first transient through at full level before the envelope has moved. * Instead the envelope takes the maximum over a lookahead window, so reduction * is already in place by the time the peak arrives, and decays with the release * time afterwards. * * Gain reduction is computed from the loudest channel and applied to all of * them. Limiting channels independently would shift the stereo image whenever * one side is louder — audible as the image pulling toward the quieter channel * on every transient. */ export declare function applyLimiter(channels: readonly Float32Array[], sampleRate: number, options?: LimiterOptions): Float32Array[];