@maruaudio/dsp/filters/state-variable is Andrew Simper's trapezoidal-integrator (TPT) state-variable filter with seven response modes. Coefficients are g = tan(π·f/fs), k = 1/Q, a1 = 1/(1 + g(g + k)), a2 = g·a1, a3 = g·a2, and each mode is a mix m0·x + m1·v1 + m2·v2 of the input, band and low outputs. Coefficients, state and output are rounded to f32. It is adapted from Synthlet's @synthlet/state-variable-filter (MIT), whose notices live in ``.
const state = initStateVariableFilterNode(48000)
setStateVariableFilterNodeType(state, SVF_BANDPASS)
setStateVariableFilterNodeFrequency(state, 1200)
updateStateVariableFilterNodeCoefficients(state) // before the next tick
const y = stateVariableFilterNodeTick(state, x)Parameters
| Setter | Range the setter enforces | Default |
|---|---|---|
setStateVariableFilterNodeType | Rounded, then 0 to 6: SVF_BYPASS, LOWPASS, BANDPASS, HIGHPASS, NOTCH, PEAK, ALLPASS | Low-pass |
setStateVariableFilterNodeFrequency | 10 Hz to 0.45 × the sample rate | 1000 Hz |
setStateVariableFilterNodeQ | 0.025 to 40 | 0.7071 |
Lifecycle
initStateVariableFilterNode → setters → updateStateVariableFilterNodeCoefficients → stateVariableFilterNodeTick → resetStateVariableFilterNode. Setters only store values; a new state passes its input through until the coefficients are updated. The update may run once per block or per sample for audio-rate cutoff modulation. prepareStateVariableFilterNodeSampleRate sets a new rate and re-clamps the stored frequency; update the coefficients again before the next tick. Reset clears the two integrators and keeps the settings.
When to use it
A resonant synth or envelope filter whose cutoff moves, or one filter that switches between low-pass, band-pass and high-pass taps. The source allows a coefficient update per sample for audio-rate cutoff modulation.
Limits
- Mono sample tick, second order.
- No coefficient smoothing; changes apply at the next update.
- Bypass still advances the integrators, so switching back to a filtered mode does not resume stale history.
- The clamp is the kernel node's conditional clamp, not
@maru/math-range.