"Give every voice its own timer and they drift. Give them one clock and they lock."
The Symptom: Drift
In the v1 playback engine, the solo, the chords, and the metronome each need to sound at the right musical moment. The naive build gives each its own timer — and they slowly slide apart, because independent timers accumulate independent error. The metronome ticks a hair early, the chords lag, and what should be locked feels loose. That's jitter, and it's the death of a practice tool: you can't play along with something that won't hold still.
The Fix: One Anchored Audio Clock
The fix is a single source of truth — for time. Pick one anchor (a moment where audio-time and source-time are pinned together), and map every voice's source position to audio-time through the same function. Add a syncOffset knob to nudge alignment by ear. Then run a lookahead scheduler: wake on a short interval, and schedule everything due in the next window against the AudioContext's own clock — never against setTimeout, which is far too jittery for musical timing. Because every voice reads the one clock, they physically cannot drift apart.
It's the One-Model Idea, Applied to Time
Notice the shape: this is exactly Track 3's single-source-of-truth, wearing a different hat. There, one music model and many views that can't disagree. Here, one timebase and many voices that can't drift. The same principle — a single authoritative source that everything derives from — solves fragmentation whether the thing being fragmented is data (the model) or time (the clock). When you see drift, look for the missing single source.