biquad

NODE

EQ and filters. Eight response shapes, from a bell to a notch, all solved as a state-variable filter.

Parameters

FIELDWHAT IT DECIDESRANGEREQUIRED
cutoff_hzCutoff / centre frequency [Hz]. The maximum is the internal Nyquist of the lower rate family.0 〜 352,800yes
gain_db?Gain [dB]. Required for bell and the shelves, null or omitted for the other shapes.-24 〜 24no
qQ.0.05 〜 40yes
shapeResponse shape.low_pass / high_pass / band_pass / notch / all_pass / bell / low_shelf / high_shelfyes

? = the field may be omitted

{
  "cutoff_hz": 1000,
  "gain_db": 3,
  "q": 1,
  "shape": "bell",
  "type": "biquad"
}

How it is computed

g = tan(π · cutoff_hz / rate)     rate = 705,600 or 768,000 Hz
k = 1 / q                        (for a bell, 1 / (q · A))

the five coefficients (g, k and three mixing terms) are solved from
the shape, the cutoff, q and gain_db, then run as a TPT state-variable filter
A topology-preserving state-variable form is used rather than a direct-form biquad. At 768 kHz the ratio of cutoff to rate is very small, and direct-form coefficients degenerate there: the filter drifts toward the instability the validation exists to catch. In this form, any cutoff below Nyquist with a positive q stays stable however the coefficients round.
  • gain_db applies to bell, low_shelf and high_shelf. For the other shapes it must be omitted or null.
  • The coefficients are solved by the same code that draws the response curve in the app, so the curve you see and the filter you hear cannot disagree.
  • Coefficients are solved again at both internal rates, and the design has to be valid at both.

Using it

  • The cutoff can be set far above the audible band.

    The maximum is the internal Nyquist of the lower family. That is deliberate: filters that shape what a nonlinear stage produced up there are a legitimate thing to write. What is refused is amplifying that band.

  • A high q is not refused, it is measured.

    A very narrow filter with a large boost has a large peak gain, and the coefficient check measures exactly that. If it refuses, the numbers it returns tell you how far over you are.

  • It is linear, so it joins the loudness match.

    A biquad that lifts a band raises the measured level of the chain, and the A/B matching accounts for it from the coefficients.