A constant tempo is the special case, not the rule. In Volta tempo is a map — a piecewise-linear function of the beat number, written in source and compiled into the IR. Everything already scheduled in beats inherits the curve for free.
tempo = tempoMap [[0, 124bpm], [32, 124bpm], [64, 140bpm]] declares breakpoints on the beat axis. Between two points the bpm interpolates linearly; before the first and after the last it holds. A hold is just a repeated value — there is no hold keyword, and equal-beat breakpoints are rejected because they would break the beat↔seconds bijection.
accel 124bpm 140bpm 16bars and ritard 174bpm 87bpm 4bars are stdlib sugar for the one-segment case. A bar here is the fixed authoring bar of 4 beats — 16bars is always 64 beats, whatever your patterns' cycle lengths are.
Module.tempo is redefined as the map's value at beat 0, so a curved song still reports one honest starting tempo and everything downstream — pattern events, note durations, shred waits, scene quantization, the arrangement walk — follows the curve without knowing about it.
|> clock (3/4) is polytempo: that track runs at three quarters of the global tempo, so a track-beat b lands at global beat b·4/3. The ratio must be a literal rational. Three notes now spread across the space four used to fill, and the parts drift in and out of phase.
One thing does not follow the map yet: c-declared LFO, delay and grain rates still bake their hertz at the compile tempo. Write ms/s when you need a modulation rate to stay absolute through a ramp.
The starting point#
The lesson opens with this song in the editor. Every edit recompiles and plays.
-- Tempo: the journey — one number, one speed, for the whole song.
tempo = 100bpm
pad = patch {
source = saw (freq pitch) |> unison 5 18,
ampEnv = adsr 250ms 250ms 0.7 500ms,
cutoff = 1600Hz,
gain = vel * 0.3
}
bell = patch {
source = sine (freq pitch),
ampEnv = adsr 2ms 400ms 0 300ms,
gain = vel * 0.35
}
kick = sound !"bd ~ bd ~"
chord = play pad !"c3 eb3 g3"
bells = play bell !"c5 eb5 g5 bb5"
What to watch#
Put the scope on the kick and let the ramp run: the spacing between transients closes visibly, but no note ever jumps or clicks — the clock integrates a closed-form curve rather than stepping between tempos. Under clock (3/4) the two grids beat against each other and slowly re-align.
Goals#
The workbench checks these as you work; the solution is there when you want it.
- Open somewhere danceable — 118 to 178 bpm
- Make the tempo a curve, not a number
- Write the map by hand: hold, then lift
- Stretch: run one track on its own clock
Make it yours#
Build the classic drop entrance: hold your tempo flat for sixteen bars, drag it down four bars into a breakdown with a ritard-shaped segment, then snap back up over one beat. Listen to what a one-beat segment sounds like versus a thirty-two-beat one.
Further reading#
Tempo changes and independent clocks in the reference.