Effects
An effect processes a track’s audio after the instrument — an echo, a filter, a reverb. In DAW terms these are insert effects: they sit in the track’s signal chain, each one feeding the next, before the result reaches the master.
The built-in effects live in the std/effects module. Import the ones you need:
use "std/effects" { Delay, Lowpass, Reverb };Here’s a beat with an echo on it:
use "std/instruments" { Sampler, Kit };use "std/effects" { Delay };
let drums = AudioTrack("drums");drums.load_instrument(Sampler(Kit("CR-78")));drums << [bd sd bd sd];
drums.load_effect(Delay(0.25, 0.5));
PLAY;Delay(0.25, 0.5) builds a delay effect; load_effect adds it to the track’s
chain. The drums now repeat with a quarter-second echo.
Building a Chain
Section titled “Building a Chain”load_effect appends to the chain, and order matters — each effect processes
what the one before it produced. Add a delay then a lowpass, and the filter
smooths the echoes; swap the order and you’d echo an already-filtered signal:
use "std/instruments" { Sampler, Kit };use "std/effects" { Delay, Lowpass };
let drums = AudioTrack("drums");drums.load_instrument(Sampler(Kit("CR-78")));drums << [bd sd bd sd];
drums.load_effect(Delay(0.25, 0.5)); // signal -> delay -> lowpass -> outdrums.load_effect(Lowpass(800));
PLAY;To load several at once, hand load_effects an array (Resonon arrays use
#[...]):
use "std/instruments" { Sampler, Kit };use "std/effects" { Highpass, Delay };
let hats = AudioTrack("hats");hats.load_instrument(Sampler(Kit("CR-78")));hats << [hh*8];
hats.load_effects(#[Highpass(2000), Delay(0.125, 0.3)]);
PLAY;show(track) prints the full chain in order if you lose track of what’s loaded.
The Built-in Effects
Section titled “The Built-in Effects”Delay(time, feedback) is an echo. time is the delay in seconds; feedback
(0–1) is how much of the output loops back in, so higher values mean more, longer
repeats. Delay(0.25, 0.5) echoes every quarter second at half feedback.
Filters
Section titled “Filters”The filters all take a cutoff frequency in Hz, plus an optional resonance (Q)
as a second argument. Resonance defaults to 0.707 — a flat, neutral response —
and rising values narrow and emphasise the cutoff into a sharper peak.
Lowpass(cutoff)keeps lows, cuts highs — warmer, darker.Highpass(cutoff)keeps highs, cuts lows — thinner, airier.Bandpass(cutoff)keeps a band around the cutoff, cutting either side.Notch(cutoff)is the inverse — removes a band, e.g.Notch(60)to kill mains hum.Allpass(cutoff, q)passes everything but shifts phase — a phaser building block.Peak(cutoff)is a bell: a boost or emphasis around the cutoff.
use "std/instruments" { Sampler, Kit };use "std/effects" { Lowpass, Highpass };
let drums = AudioTrack("drums");drums.load_instrument(Sampler(Kit("CR-78")));drums << [bd sd bd sd];
drums.load_effect(Lowpass(800, 3.0)); // resonant lowpass at 800 Hz, Q 3.0drums.load_effect(Highpass(120)); // clear out the sub-rumble
PLAY;Reverb
Section titled “Reverb”Two reverbs add space. Reverb(size, damping) is a room/hall: size (0–1) sets
how large the space feels, damping (0–1) how quickly the highs decay. The
PlateReverb models a lusher, more diffuse plate with its own size and tone
controls.
use "std/instruments" { Sampler, Kit };use "std/effects" { Reverb };
let drums = AudioTrack("drums");drums.load_instrument(Sampler(Kit("CR-78")));drums << [bd sd bd sd];
drums.load_effect(Reverb(0.8, 0.3)); // big room, gentle damping
PLAY;For wet/dry control — keeping the dry signal and sending only a copy through the reverb — use a send to a dedicated effect track, covered in Routing, Buses & Sends.
Overdrive(amount) and Distortion(amount) add harmonics and grit, from gentle
warmth to hard clipping as amount rises:
use "std/instruments" { Sampler, Kit };use "std/effects" { Overdrive };
let drums = AudioTrack("drums");drums.load_instrument(Sampler(Kit("CR-78")));drums << [bd sd bd sd];
drums.load_effect(Overdrive(0.5));
PLAY;Changing Parameters
Section titled “Changing Parameters”You’ll often want to adjust an effect after creating it. Keep a reference to it, then set parameters by name. There are two ways, and they do the same thing for a static value:
use "std/effects" { Delay };
let echo = Delay(0.25, 0.5);
echo.param_set("Time", 0.4); // method formecho.param("Time") << 0.15; // operator formparam_set returns the effect, so calls chain. The << form is the one to
remember, though, because it accepts more than a fixed number: feed it a moving
signal and the parameter sweeps over time.
echo.param("Feedback") << Sine(0.2).range(0.2, 0.7); // feedback driftsThat’s modulation — the bridge from static effects to living, moving ones — and it’s the subject of the next-but-one chapter.
Next Steps
Section titled “Next Steps”You can load effects, chain them in order, and dial their parameters. Next, wire tracks together, then make those parameters move.
- Routing, Buses & Sends — shared effect
buses, sends, and submixes with
>> - Signals & Automation — drive any parameter with LFOs and envelopes
- Plugins — load external VST3 and CLAP effects alongside the built-ins