@maruaudio/dsp/control/musical-clock turns musical time into frames at the Processor's prepared sample rate. Pure conversions take the rate and tempo as arguments, each in one fixed operation order: frames per beat is (sampleRate × 60) / bpm, milliseconds are (ms × sampleRate) / 1000. A beat is a quarter note and tempo is quarter notes per minute, the units of the host transport contract. The stateful clock keeps an anchor beat and a whole-frame count since it, so every position and grid boundary is computed from the anchor in one expression and rounded once, half up: it never drifts more than half a frame however long it runs.
Parameters
| Path | Setter | Range as coded | Default | Unit |
|---|---|---|---|---|
sampleRate | prepareMusicalClock | Finite and above 0, else refused (returns false, no change) | 48000 placeholder until prepared | Hz |
bpm | setMusicalClockTempo, syncMusicalClock | Finite and above 0, else refused; range policy (such as 20 to 300) is the owner's | 120 | quarter notes per minute |
beats | setMusicalClockPosition, syncMusicalClock | Non-finite → 0 | 0 | quarter notes |
Lifecycle
createMusicalClock(bpm) builds one record → prepareMusicalClock(state, rate) → setMusicalClockTempo, setMusicalClockPosition or syncMusicalClock(state, tempo, ppqPosition) per host block → advanceMusicalClock(state, frames) after rendering, with musicalClockFramesToBoundary(state, stepBeats) and the conversion queries in between. Prepare and tempo changes re-anchor at the current position, so the beat position is continuous across both and only the frames still to come are re-derived. There is no reset; seek to beat 0 instead.
When to use it
Anything authored in beats, milliseconds or seconds: a step sequencer's grid, an arpeggiator's rate, a strum's spread, a timeout. It replaces hard-coded ms × 48 or 48000 placeholders (musical time). musicalGridFrame(index, framesPerStep) gives the same rounding law to owners that walk their own step index.
Limits
advanceMusicalClockfloors its count and ignores counts of 0 or less.musicalClockFramesToBoundaryreturns 0 on a boundary and −1 for a step of 0 or less. Exact ties withinMUSICAL_CLOCK_TIE_FRAMES(10⁻⁶ frame) resolve up.musicalBpmFromPulseFramesreturns 0 for a non-positive period or pulse count; MIDI beat clock isMUSICAL_CLOCK_MIDI_PPQ(24).syncMusicalClocktakes the position even when it refuses the tempo.- f64 scalar arithmetic; no allocation after create.