# TickSource The `TickSource` class converts between audio time (seconds) and musical ticks, integrating tempo curves for sample-accurate scheduling. _(no submodules)_ ## Purpose `TickSource` is the mathematical engine behind `Transport`. It translates wall-clock seconds into musical ticks and back, accounting for tempo ramps and anchors. The integration is exact for constant, linear, and exponential tempo segments, ensuring that `getTicksAtTime` and `getTimeOfTick` remain mutual inverses within floating-point tolerance. ## Features - Exact inverse conversions under constant tempo - Integration of linear and exponential tempo ramps - `forEachTickBetween` for sample-accurate tick iteration - `setTicksAtTime` for anchoring the counter - Start, stop, and pause lifecycle - No wall-clock reads — all methods take explicit times ## Usage: Basic ```ts import { TickSource, Signal } from "@suaveplan/audio-transport"; const ts = new TickSource({ ppq: 192, bpm: new Signal({ initialValue: 120 }) }); ts.start(0); const ticks = ts.getTicksAtTime(1); // 384 ``` ## Usage: Advanced ```ts const bpm = new Signal({ initialValue: 120 }); bpm.linearRampToValueAtTime(240, 1); const ts = new TickSource({ ppq: 192, bpm }); ts.start(0); ts.forEachTickBetween(0, 1, (time, tick) => { console.log("tick", tick, "at", time); }); ``` ## API Reference ### Constructor `new TickSource(options?)` ### Properties - `ppq` — pulses per quarter note - `bpm` — `SignalLike` tempo curve ### Methods - `getTicksAtTime(time)` — ticks at audio time - `getTimeOfTick(tick, before?)` — audio time of tick - `setTicksAtTime(ticks, time)` — anchor counter - `start(time, offset?)` — begin counting - `stop(time)` — stop counting - `pause(time)` — pause counting - `forEachTickBetween(start, end, callback)` — iterate ticks ## Implementation Notes Tick integration uses closed-form integrals for constant, linear, and exponential tempo segments. `getTimeOfTick` uses binary search over the integrated curve. The `forEachTickBetween` method guarantees no duplicate or skipped ticks across consecutive windows. The source maintains an internal `_running` flag and `_offsetTicks` value so that start, stop, and pause operations preserve the accumulated tick count correctly.