FX
Reverb
Convolution reverb with synthetic-IR fallback. Use a real impulse response for spaces, or skip it for ambient wash.
Two sounds recorded in the same room share something no amount of EQ will fake, and a mix where nothing shares a room sounds like a pile of files.
A Reverb wraps a
ConvolverNode with dry/wet mixing and pre-delay. Pass an
impulse AudioBuffer to put your sounds in a real measured
space. Omit it and zvuk generates a synthetic exponential-decay noise
impulse instead, which costs nothing to ship and carries far less
character, but holds up fine as atmosphere.
API surface
class Reverb implements FxInsert {
readonly input: GainNode;
readonly output: GainNode;
bypassed: boolean;
setWet(mix: number): void; // 0..1
setImpulse(buffer: AudioBuffer): void;
dispose(): void;
}
interface ReverbConfig {
wet?: number; // default 0.3
impulse?: AudioBuffer; // your own IR
decay?: { seconds?: number; preDelay?: number };
} Live demo
Wet mix slider, decay length (regenerates the IR), bypass toggle.
Recipes
Synthetic IR
import { Reverb } from '@schmooky/zvuk';
// Synthetic IR — ~free, fine for atmosphere.
const verb = new Reverb(engine.context, {
wet: 0.3,
decay: { seconds: 1.5, preDelay: 0.02 },
});
engine.bus('music').addFx(verb); Real impulse response
// Real impulse response — load like any other audio asset.
const irBuf = await fetch('/ir/cathedral.wav')
.then((r) => r.arrayBuffer())
.then((ab) => engine.context.decodeAudioData(ab));
const verb = new Reverb(engine.context, { wet: 0.4, impulse: irBuf });
engine.bus('music').addFx(verb); Wet driven by a Parameter
// Drive wet from a Parameter so multiple things tilt with one knob.
const intensity = engine.parameter('intensity', 0.3);
intensity.bindTo((v) => verb.setWet(v), { from: 0.1, to: 0.6 }); Pitfalls
Don't reverb SFX.
Individual hits get smeared and mushy. Reserve reverb for the long-tailed
sources: music, ambience, voice. SFX want to land sharp.
Don't ship a 5-second IR for a UI bus.
Convolution cost scales with impulse length times sample rate, and a five
second impulse at 48 kHz costs the same every frame whether the bus has
audio on it or not. Keep impulses under two seconds unless you genuinely
need a cathedral.