Build with this node

Start with a prompt in Studio, or copy it into your own coding agent.

Ask Studio

@maruaudio/dsp/dynamics/stereo-de-esser lowers a high shelf when sibilant energy rises. Each channel runs an RBJ high-pass at the frequency (Q 0.7071); the larger of the two magnitudes drives one peak envelope (0.5 ms attack, 60 ms release), so both channels move together. Every 16 samples the reduction clamp(20·log10(envelope) − threshold, 0, range) is applied as negative gain on an RBJ high shelf at 0.8 × the frequency (Q 0.8), when it moved by more than 0.05 dB or reached 0. Filters are @maru/filters-biquad states.

const state = initStereoDeEsser(48000)
configureStereoDeEsser(state, 6000, 10, -30, false)
stereoDeEsserTick(state, left, right) // state.outLeft, state.outRight

Parameters

configureStereoDeEsser(state, frequencyHz, rangeDb, thresholdDb, listen); a non-finite value takes the default, then clamps. Filters recompute only when the frequency changes.

ArgumentRange the code appliesDefaultUnit
frequencyHz2000 to 16000, then the biquad's 0.45 × rate ceiling6000Hz
rangeDb0 to 2410dB
thresholdDb−60 to 0−30dBFS
listentrue outputs the detector high-pass insteadfalseflag

Lifecycle

initStereoDeEsser(sampleRate) (rate bounded to 8 to 192 kHz, NaN gives 48 kHz) on the control thread → configureStereoDeEsser → stereoDeEsserTick per frame → resetStereoDeEsser, which clears every filter, the envelope and the clock and returns the shelf to 0 dB. Configure, tick and reset allocate nothing.

When to use it

Reducing sibilance on a vocal or spoken-word track; Listen exposes the detector.

Limits

  • Stereo, linked, no internal mix, lookahead or alignment delay. The 16-sample control clock persists across host blocks and reads only past samples.
  • The shelf keeps running in Listen, so switching back does not revive stale state. NaN and infinite input are read as 0.

Algorithm properties and proofs

No Lean 4 proof is mapped to this node.

Explore proofs alongside performance

Dependencies

Dependents

Used by