"voice 마다 자기 타이머를 주면 표류해. 클럭 하나를 주면 맞물려."
증상: 표류
v1 playback 엔진에서 solo, 코드, 메트로놈은 각각 맞는 음악적 순간에 울려야 해. 순진한 빌드는 각자 자기 타이머를 줘 — 그리고 천천히 미끄러져 갈라져, 독립 타이머가 독립 오차를 쌓으니까. 메트로놈이 머리카락만큼 일찍 치고, 코드가 늦고, 맞물려야 할 게 헐겁게 느껴져. 그게 jitter 고, 연습 도구의 죽음이야: 가만있지 않는 것에 맞춰 칠 수 없잖아.
수정: anchored 오디오 클럭 하나
수정은 단일 진실원이야 — 시간 의. anchor 하나를 골라(오디오-시간과 소스-시간이 함께 핀 박히는 순간), 모든 voice 의 소스 위치를 같은 함수로 오디오-시간에 매핑해. 귀로 정렬을 미세조정할 syncOffset knob 을 더해. 그다음 lookahead scheduler 를 돌려: 짧은 간격으로 깨어나, 다음 window 안에 도래하는 모든 걸 AudioContext 자기 클럭에 맞춰 스케줄해 — 절대 setTimeout 에 맞추지 마, 음악적 타이밍엔 너무 jitter 가 심하거든. 모든 voice 가 그 클럭 하나를 읽으니까, 물리적으로 갈라질 수 없어.
one-model 아이디어를, 시간에 적용
모양을 봐: 이건 정확히 Track 3 의 단일 진실원이 다른 모자를 쓴 거야. 거기선 음악 모델 하나와 의견 못 갈리는 view 여럿. 여기선 timebase 하나와 표류 못 하는 voice 여럿. 같은 원칙 — 모든 게 파생되는 단일 권위 소스 — 이 fragment 되는 게 데이터(모델)든 시간(클럭)이든 fragmentation 을 풀어. 표류를 보면, 빠진 단일 소스를 찾아.