openmixer — generated API reference
    Preparing search index...

    Function rbjSection

    • One biquad section, designed to MATCH THE ANALOGUE PROTOTYPE rather than to be its bilinear image. THE single transcription of the design in the codebase: both the coefficients the engine pushes (rbjCoeffs) and the magnitude the surface draws (biquadMagnitudeDb) come from here, so the drawn curve can never disagree with what the engine runs.

      WHY THIS IS NOT THE RBJ COOKBOOK ANY MORE (operator ruling, 2026-09-14). The cookbook designs by the bilinear transform, which compresses the whole analogue frequency axis into [0, Nyquist). Pre-warping puts f0 back where it was asked for and leaves everything above it squeezed: at the 96 kHz the graph runs, a +12 dB bell at 16 kHz Q 2 was 1.28 dB low at 20 kHz and a +12 dB high shelf at 12 kHz 0.50 dB high — measured, not argued (an internal spec §5). Raising the graph rate shrinks that error but costs 1.98x the CPU on every stage; an EQ is LINEAR, so oversampling it buys nothing at all. The ruling: match the prototype BY COEFFICIENT DESIGN, at the rate the desk runs.

      THE DESIGNS, per kind — each one measured against its analogue prototype by packages/pipewire-native/tools/eq-matched-probe.c, which prints the before/after table:

      • peaking, lowShelf, highShelf — matched-Z pole/zero placement (Vicanek, Matched Second Order Digital Filters, 2016). Every pole and zero of the prototype is finite, so exp(sT) places all four exactly and one scalar sets the reference gain (unity at DC, except the low shelf, whose DC gain is the shelf gain). A peaking section is a zero pair at f0 damped A/(2Q) over a pole pair at f0 damped 1/(2AQ); a shelf is a pair at f0*sqrt(A) over a pair at f0/sqrt(A) (swapped for the low shelf), both damped 1/(2Q).
      • lowpass — matched-Z poles, but the prototype's two zeros are at s = infinity and the map has nowhere to put them, so the numerator is instead FITTED to the prototype's magnitude at DC, at f0 and at Nyquist (Vicanek's construction for the same reason).
      • notch — matched-Z poles under the cookbook's own numerator, which already IS the matched-Z zero pair ({1, -2cos(w0), 1} puts both zeros exactly on the unit circle at f0), so only the denominator changes and the null at f0 stays exact.
      • highpass — UNCHANGED, still the cookbook's. Measured first: over the 20-1000 Hz its pass filter serves, the bilinear error is 0.005 dB at 96 kHz — there is nothing to fix, and the fitted alternative is infeasible over much of the space and worse where it is not.

      A 0 dB peaking or shelf section is still EXACTLY identity — zeros and poles are designed by the same call with the same arguments when A = 1, so they cancel term for term and the scalar is exactly 1. eqBandIsIdentity rests on that.

      gainDb is used only by the peaking/shelf kinds (the pass kinds ignore it). The centre/cutoff is clamped just under Nyquist so a band dragged to the top of the audio band can't produce a degenerate section.

      Parameters

      • kind: BiquadKind
      • freqHz: number
      • q: number
      • gainDb: number
      • sampleRate: number

      Returns BiquadSection