resofilter

resofilter · processors

Multi-mode filter — clean-room TypeScript port of gabrielsoule/resonarium's MultiFilter (Source/dsp/MultiFilter.{h,cpp}). 5 modes drawn straight from upstream's MultiFilter::Type enum and filterTextFunction: LP / HP / BP / Notch / Allpass. All five characters share a single Cytomic / Zavalishin TPT state-variable filter per channel, so the MODE knob is a pure output picker — switching modes mid-render is pop-free. Cutoff 20 Hz – 20 kHz (log), resonance 0..1 (k = 2 − 2·res, edge-of-self-oscillation at the top), per-param CV inputs (cutoff_cv, reso_cv) sum into the AudioParams with a 50 Hz internal one-pole smoother on cutoff to prevent the steep transfer function from clicking on rapid CV jumps. Stereo input (independent L/R SVF state). The card displays the long-form mode name (e.g. "Low-pass") in a label next to the MODE knob — the headline UX feature: the dial updates the text reactively as you turn it. Drive is intentionally omitted (upstream MultiFilter has no drive stage; saturation lives in WrappedSVF / Distortion which is out of scope for this port).

A clean multi-mode resonant filter (ported from Resonarium's MultiFilter) built on a zero-delay-feedback state-variable topology, so all of its modes share one filter state and switching between them mid-sound is pop-free. One MODE knob picks the response — Low-pass (attenuate above cutoff), High-pass (attenuate below), Band-pass (peak at cutoff), Notch (dip at cutoff), or Allpass (flat magnitude, phase-rotating) — and the card prints the long-form name of the current mode next to the knob. The input is stereo-aware (independent L/R filter state preserves the image), CUTOFF and RESONANCE are CV-modulatable, and a MIX knob crossfades dry to wet (turn it to 0 for bypass). A general-purpose tone-shaper for both subtractive synth voices and full mixes.

the faceplate

resofilteraudioaudiocutoff_cvcvreso_cvcvout_laudioout_raudioaudiocvgatepitch
3 inputs · 2 outputs · 0 params

inputs

idcablewhat it does
audioaudioThe signal to filter (mono or stereo). A stereo source keeps its left/right separation through independent per-channel filter state; a mono source feeds both channels.
audio signal
cutoff_cvcvCV control of the CUTOFF frequency — patch an envelope or LFO here for filter sweeps. It adds to the knob position IN HERTZ, not in octaves: a full-scale CV moves the corner by ±9990 Hz and the result is clamped to 20 Hz..20 kHz, so the reachable window is strongly asymmetric and changes with where the knob sits. From 1 kHz it reaches 20 Hz..10.99 kHz (5.64 octaves down, 3.46 up); from 100 Hz it reaches 20 Hz..10.09 kHz (2.32 down, 6.66 up); and with the knob at its 20 Hz minimum the CV cannot travel downward at all. The faceplate prints this window as CV REACH. (Most log-tapered params in the rack — including the qbrt and moog904c cutoffs — scale their CV logarithmically instead, which is symmetric at ±4.98 octaves everywhere.)
control voltage (CV); modulates cutoff (additive offset — ±1 CV sweeps the full range, centered on the knob)
reso_cvcvCV control of the RESONANCE — modulate the emphasis at the cutoff for talking/wah-style motion (adds to the knob position). What that emphasis IS depends on MODE: see the RESONANCE control note. Above resonance 0.9985 the underlying damping is clamped, so CV pushed into the top 0.15 % of the scale changes nothing.
control voltage (CV); modulates resonance (additive offset — ±1 CV sweeps the full range, centered on the knob)

outputs

idcablewhat it does
out_laudioLeft filtered output (with the dry/wet MIX applied).
audio signal; L/R stereo pair with out_r
out_raudioRight filtered output. With a mono input it carries the same filtered signal as OUT L.
audio signal; L/R stereo pair with out_l

controls

controlwhat it does
CutoffThe corner frequency the filter pivots around (20 Hz to 20 kHz, log, default 1 kHz) — what 'above'/'below'/'at cutoff' refers to for the selected mode. Two settings are worth knowing because they read as a broken module rather than a setting: a HIGH-PASS at the 20 Hz bottom of this dial is a bypass (measured at the dry level to two decimals), and so is a NOTCH there, because there is nothing below 20 Hz to remove. The CUTOFF CV input adds to this — see its own note, it is additive in Hertz rather than in octaves.
MixDry/wet balance (0 to 1, default fully wet): 1 is the pure filtered signal, 0 is full bypass, and in between blends the two. At 0 the output is BIT-EXACTLY the input in all five modes (measured max|out − in| = 0.000e+0), so it is a true bypass rather than a very quiet filter. In between, dry and wet are summed as SIGNALS and not as levels — they have different phase, so the result is not a fade between the two curves: a low-pass at resonance 0.9 measures +14.0 dB at cutoff fully wet and +8.1 dB at MIX 0.5, where blending the two magnitudes would predict +9.5. Mixing dry into the ALLPASS is where that matters most, and it is how you get a phaser: the allpass has unity magnitude everywhere, so blending magnitudes would predict no change at all, while the rotating phase actually cancels against the dry path and turns a flat response into a deep notch at the cutoff.
ModePicks the filter response among Low-pass, High-pass, Band-pass, Notch, and Allpass. All five are taps off ONE shared state-variable filter, so MODE is a pure output picker and changing it while audio plays is pop-free by construction — there is no state to reset and nothing to crossfade. It also decides what RESONANCE means; see that control's note. MODE rounds to the nearest state at exactly 0.5, so a CV or automation lane sitting on 0.5 selects High-pass, not Low-pass.
ResonanceOne dial that sets one number — the SVF damping k = 2 − 2·resonance — and four different audible things depending on MODE. In LOW-PASS and HIGH-PASS it is the gain at the cutoff frequency and nothing else: exactly 1/k, measured −6.0 dB at resonance 0, 0.0 dB at 0.5, +14.0 dB at 0.9 and +34.0 dB at 0.99, identical in both modes and at every cutoff. In BAND-PASS it is that same peak AND the band's width. In NOTCH it is the WIDTH ONLY — the notch is a true zero at the cutoff at every resonance, and the dial takes it from 2.53 octaves wide down to 0.004, which a broadband level meter cannot see at all (0.55 dB across the whole travel). In ALLPASS it changes the output level by exactly nothing — the magnitude is unity at every frequency and every resonance — and is a pure phase rotation, controlling how abruptly the 360° sweep happens across the same octave span. Two hazards: the damping is CLAMPED at k = 0.003, so everything from resonance 0.9985 to 1.0 is the identical filter (the top 0.15 % of the dial is a plateau), and at that plateau the gain at cutoff is +50.46 dB with nothing here limiting it — a −6 dBFS sine leaves at +44.5 dBFS.

source

resofilter.ts on GitHub.

Generated from packages/web/src/lib/{audio,video}/module-registry.ts · repo