fix: capture master clock start time from first tick callback

The _masterTime was captured from Tone.now() BEFORE the clock started,
but the time parameter in Tone.Clock callbacks comes from a different
scheduler timeline. This caused elapsed to drift systematically.

Now _masterTime is set from the first callback's own time parameter,
guaranteeing both are on the exact same clock source. Zero drift.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Jose Luis
2026-03-21 17:57:10 +01:00
parent 18661961a1
commit 8bdb953b52

View File

@@ -35,8 +35,14 @@ export function unsubscribeTick(id) {
function startMasterClock() {
if (_masterClock) return;
_masterTime = Tone.now();
_masterTime = 0; // Will be set from first tick
let _started = false;
_masterClock = new Tone.Clock((time) => {
// Capture start time from the FIRST callback — guarantees same clock source
if (!_started) {
_masterTime = time;
_started = true;
}
const elapsed = time - _masterTime;
for (const cb of _tickListeners.values()) {
cb(time, elapsed);