Reverb Module — Convolution Reverb

Convolution reverb using ConvolverNode with a decaying filtered noise impulse response, rendered asynchronously via OfflineAudioContext. Stereo spread via 3ms inter-aural delay on the right channel.

Available as a send effect in the sequencer (Reverb card in the master collapsible section, Snd tab per-sound send fader).

Signal Flow

input → preDelay → convolver → makeupGain (×2.5) → wetGain → outputL
                                                 → wetGain → outputR

The input is mono-summed (pre-delay is mono). The convolver output feeds a makeup gain stage (+8dB) to compensate for convolution energy loss, then splits to stereo outputs.

Impulse Response Generation

The reverb tail is rendered asynchronously via renderTail():

OfflineAudioContext(2, sampleRate × decay, sampleRate)
  → white noise buffer (full length)
  → highpass filter (lowCut, default 50 Hz)
  → lowpass filter (highCut, default 8 kHz)
  → exponential gain ramp (1 → 0.001 over decay seconds)
  → split L/R: L direct, R with 3ms delay
  → destination

The impulse response is generated on first build() and can be re-rendered at any time via renderTailAsync() (e.g. when decay or filter params change).

Parameters

Param Range Default Description
reverbMix 0–1 0.4 Wet/dry blend
reverbDecay 0.3–10 s 2.5 s Reverb tail length
reverbPreDelay 0–0.2 s 0.02 s Pre-delay before reverb onset
reverbLowCut 20–500 Hz 50 Hz Highpass filter on tail
reverbHighCut 500–20000 Hz 8000 Hz Lowpass filter on tail

Exports

Export Signature Purpose
paramDefs UI param definitions (5 params)
build (ctx, params) Create stereo reverb chain, returns { input, outputL, outputR, nodes }
update (nodes, params) Update pre-delay and mix from params
renderTailAsync (nodes, params) Re-render impulse response with current decay/filter settings

Integration

As sequencer send FX

The reverb is wired in ensureMasterBus alongside ruina:

engine._reverbInput = ac.createGain()
engine._reverbNode = reverbMod.build(ac, engine)
engine._reverbInput → engine._reverbNode.input
engine._reverbNode.outputL → _limSumL
engine._reverbNode.outputR → _limSumR

Per-sound send level is controlled via sound.sends.reverb (set in Snd tab). The reverb return injects post-glue-compressor, pre-brickwall-limiter so tails don't pump the compressor.

In a synth engine

Can be added to any engine's modules array for per-voice reverb.

Files

File Purpose
modules/reverb.js Module implementation (120 lines)
sequencer-audio.js Master bus wiring (ensureMasterBus)
sequencer-ui.js Master section Reverb card + Snd tab slider
sequencer.js _playNote reverb send routing

See Also