Skip to content

Automation

Automation is a pure curve over beat-time. You attach one to a track parameter with track.automate(param, curve) inside a section body; the runtime samples the curve and compiles it to parameter ramps (filter sweeps, gain fades, stereo drift) at schedule time.

import { value, ramp, sweep, sine, bars } from "@barline/core";

The automatable parameters are cutoff, resonance, gain, pan, and pitch (the set is extensible by packages via declaration merging). cutoff and resonance lazily create a dedicated filter on the track the first time they’re automated, so they’re audible.

kick.automate("gain", value(0.8)); // hold a fixed value

Interpolates linearly from from to to across over beats, then holds.

kick.automate("gain", ramp(0.7, 1, bars(16))); // fade the kick up over the section
hats.automate("gain", ramp(0.4, 1, bars(16))); // bring the hats in
rumble.automate("gain", ramp(0.8, 0.15, bars(16))); // wind the bass down in the outro

sweep(from, to, over, curve = "exp") — a filter sweep

Section titled “sweep(from, to, over, curve = "exp") — a filter sweep”

Like ramp, but exponential by default — the natural shape for a frequency sweep, where the ear hears ratios, not differences. Pass "lin" for linear, or let it fall back to linear automatically across a zero or sign change.

rumble.automate("cutoff", sweep(250, 2500, bars(16), "exp")); // the classic opening filter
rumble.automate("cutoff", sweep(400, 6000, bars(16))); // exp is the default

Oscillates around center by ±amp, one full cycle every period beats. Great for stereo drift and slow filter wobble.

ride.automate("pan", sine(0, 0.5, bars(4))); // slow stereo drift
acid.automate("cutoff", sine(1400, 900, bars(8))); // a wandering filter

A curve built from one of these four constructors with plain numeric literals (or bars(n) / beats(n) wrappers) is editable from the Clip detail panel — each argument shows as a scrub/select control that writes back into the literal in your code. A computed curve, or two constructor calls on one line, locks the row with a reason instead. Custom curve objects (any object with an at(pos): number method) work too, but carry no call-site metadata, so they always render read-only.