FX
Each FX function wraps a Machine and returns a new Machine with the effect in the signal path.
Usage
Direct form
Pass the machine as the first argument:
const synth = reverb(comp(vasynth({ wave: 'sawtooth' }), { threshold: -20 }), { mix: 0.3 })chain() helper
Use chain() to apply multiple FX without deep nesting. Call each FX with options only (curried form) to get a (Machine) => Machine transformer:
const synth = chain( vasynth({ wave: 'sawtooth' }), comp({ threshold: -20, ratio: 4 }), reverb({ mix: 0.3 }),)chain(machine, ...fxChain) → Machine| Argument | Type | Description |
|---|---|---|
machine | Machine | Source machine |
...fxChain | ((m: Machine) => Machine)[] | FX functions in curried form |
Both forms are interchangeable and fully backward-compatible.
Available effects
eq — Parametric EQ
Filters and shapes individual frequency bands.
chain(vasynth(), eq({ type: 'highpass', freq: 80 }))| Parameter | Default | Description |
|---|---|---|
type | 'peaking' | lowpass / highpass / bandpass / notch / peaking / lowshelf / highshelf |
freq | 1000 | Center / cutoff frequency (Hz) |
gain | 0 | Band gain in dB (peaking / shelf only) |
q | 1 | Bandwidth / resonance |
mix | 1.0 | Wet/dry mix |
env | — | Envelope sequencer for mix modulation |
comp — Compressor
Reduces dynamic range for punch and consistency.
chain(vasynth(), comp({ threshold: -24, ratio: 4, makeup: 6 }))| Parameter | Default | Description |
|---|---|---|
threshold | -24 | Compression threshold (dB) |
ratio | 4 | Compression ratio |
attack | 0.003 | Attack time (s) |
release | 0.25 | Release time (s) |
knee | 6 | Knee width (dB) |
makeup | 0 | Makeup gain (dB) |
mix | 1.0 | Wet/dry mix |
env | — | Envelope sequencer for mix modulation |
limit — Hard Limiter
Prevents output from exceeding a ceiling.
chain(vasynth(), limit({ threshold: -3 }))| Parameter | Default | Description |
|---|---|---|
threshold | -3 | Limiter ceiling (dB) |
release | 0.05 | Release time (s) |
saturate — Tape Saturation
Adds warmth and harmonic density via tanh soft-clipping.
chain(vasynth(), saturate({ drive: 3, mix: 0.8 }))| Parameter | Default | Description |
|---|---|---|
drive | 2 | Saturation amount (1 = linear, 10 = heavy) |
output | 0.8 | Output makeup gain |
mix | 1.0 | Wet/dry mix |
env | — | Envelope sequencer for mix modulation |
distort — Waveshaper Distortion
Hard-clip waveshaper with tone control.
chain(vasynth(), distort({ drive: 10, tone: 3000 }))| Parameter | Default | Description |
|---|---|---|
drive | 10 | Pre-clip gain |
tone | 5000 | Post-clip low-pass cutoff (Hz) |
output | 0.5 | Output makeup gain |
mix | 1.0 | Wet/dry mix |
env | — | Envelope sequencer for mix modulation |
reverb — Reverb
Convolution reverb using a synthetically generated impulse response.
chain(vasynth(), reverb({ size: 0.7, mix: 0.3 }))| Parameter | Default | Description |
|---|---|---|
size | 0.7 | IR length scale (0.1–2) |
decay | 2.0 | Decay speed — higher = shorter tail (0.5–10) |
damping | 0.5 | High-frequency damping (0 = dark, 1 = bright) |
mix | 0.3 | Wet/dry mix |
env | — | Envelope sequencer for mix modulation |
pingpong — Ping-Pong Delay
Stereo ping-pong delay that alternates L → R → L.
chain(vasynth(), pingpong({ time: 0.375, feedback: 0.4, mix: 0.4 }))| Parameter | Default | Description |
|---|---|---|
time | 0.375 | Delay time per tap (s) |
feedback | 0.4 | Feedback amount (0–0.9) |
mix | 0.4 | Wet/dry mix |
env | — | Envelope sequencer for mix modulation |
chorus — Chorus
LFO-modulated short delay that thickens the sound.
chain(vasynth(), chorus({ rate: 0.5, depth: 0.5, mix: 0.5 }))| Parameter | Default | Description |
|---|---|---|
rate | 0.5 | LFO rate (Hz) |
depth | 0.5 | Modulation depth (0–1) |
delay | 25 | Center delay time (ms) |
feedback | 0.2 | Feedback amount (0–0.5) |
mix | 0.5 | Wet/dry mix |
env | — | Envelope sequencer for mix modulation |
flanger — Flanger
Jet-sweep effect using a very short LFO-modulated delay (1–5 ms).
chain(vasynth(), flanger({ rate: 0.3, depth: 0.7, feedback: 0.5 }))| Parameter | Default | Description |
|---|---|---|
rate | 0.3 | LFO rate (Hz) |
depth | 0.7 | Modulation depth (0–1) |
delay | 3 | Center delay time (ms) |
feedback | 0.5 | Feedback amount (0–0.95) |
mix | 0.5 | Wet/dry mix |
env | — | Envelope sequencer for mix modulation |
phaser — Phaser
Cascaded allpass filters swept by an LFO, creating phase-interference notches.
chain(vasynth(), phaser({ stages: 4, rate: 0.5, centerFreq: 800 }))| Parameter | Default | Description |
|---|---|---|
rate | 0.5 | LFO rate (Hz) |
depth | 0.7 | Modulation depth (0–1) |
stages | 4 | Number of allpass stages (2 / 4 / 6 / 8) |
feedback | 0.4 | Feedback amount (0–0.9) |
centerFreq | 800 | Allpass center frequency (Hz) |
mix | 0.5 | Wet/dry mix |
env | — | Envelope sequencer for mix modulation |
stutter — Rhythmic Gate
Rapidly gates the wet signal to create stuttering repetitions. The gate pattern is scheduled once per cycle via scheduleAutomation.
chain(vasynth(), stutter({ rate: 8, duty: 0.5, mix: 0.8 }))| Parameter | Default | Description |
|---|---|---|
rate | 8 | Gate subdivisions per beat (e.g. 8 = 1/8-beat gate) |
duty | 0.5 | Gate open fraction 0–1 (0.5 = 50% on, 50% off) |
mix | 0.8 | Wet/dry mix — dry signal passes through unaffected |
// 1/16-note stutter with tight gatechain(lead, stutter({ rate: 16, duty: 0.3, mix: 0.9 }))
// Slow gate on a pad, every half-beatchain(pad, stutter({ rate: 2, duty: 0.6, mix: 0.7 }))freeze — Feedback Freeze
High-feedback delay loop that sustains the signal, approximating a freeze/hold effect. Useful for ambient drones and glitchy sustain tails.
chain(pad, freeze({ feedback: 0.92, loopTime: 0.4, mix: 0.7 }))| Parameter | Default | Description |
|---|---|---|
feedback | 0.92 | Feedback amount 0–0.999 (higher = longer sustain) |
loopTime | 0.4 | Feedback loop length in seconds |
mix | 0.7 | Wet/dry mix |
// Long ambient drone tailchain(strings({ attack: 1.2, gain: 0.3 }), freeze({ feedback: 0.97, loopTime: 0.6 }))
// Short glitchy freeze burstchain(vasynth(), freeze({ feedback: 0.85, loopTime: 0.1, mix: 0.5 }))