FX
Filter
Biquad filter as a bus FX insert. Lowpass for muffles, highpass for radios, bandpass for telephone, peaking for EQ.
Everything muffles when the player goes underwater, and the cheapest convincing version of that is one filter on one bus.
A Filter is a single
BiquadFilterNode wrapped in the FX-insert contract. Pick a
type, a frequency and a Q. Drive any of them from a
Parameter when you want the transition
rather than the state.
API surface
class Filter implements FxInsert {
readonly input: GainNode;
readonly output: GainNode;
bypassed: boolean;
setType(t: FilterKind): void;
setFrequency(hz: number): void;
setQ(q: number): void;
setGain(db: number): void; // peaking gain, live
dispose(): void;
}
type FilterKind = 'lowpass' | 'highpass' | 'bandpass' | 'notch' | 'peaking' | 'allpass';
interface FilterConfig {
type?: FilterKind;
frequency?: number; // Hz
q?: number;
gain?: number; // dB — peaking only
} Live demo
Type, frequency, Q. Try lowpass at 400 Hz with high Q for a wah.
Recipes
Insert + live tweak
import { Filter } from '@schmooky/zvuk';
const fx = new Filter(engine.context, {
type: 'lowpass',
frequency: 800,
q: 1.2,
});
engine.bus('music').addFx(fx);
// Live sweep
fx.setFrequency(2000);
fx.setQ(0.7); "Underwater" sweep from a Parameter
// Sweep a filter from a Parameter for "underwater" / "muffled" effects.
const muffle = engine.parameter('muffle', 0);
muffle.bindTo((v) => fx.setFrequency(v), { from: 20000, to: 400, curve: 'easeIn' });
muffle.set(1); // fully underwater Common starting points
| Effect | Type | Frequency | Q |
|---|---|---|---|
| Muffled / underwater | lowpass | 400–800 Hz | 1 |
| Tinny radio / phone | bandpass | 1500 Hz | 2 |
| Subwoofer cut | highpass | 120 Hz | 1 |
| De-hiss | lowpass | 10 kHz | 0.7 |
| Wah | bandpass | swept | 4–8 |
Pitfalls
Don't push Q to extremes.
Q above 10 starts ringing. On music, that's a feedback howl. Stay under
5 unless you're sweeping for a deliberate effect.