LAB 001
El metrónomo que se equivoca
Dos metrónomos arrancan a la vez. Uno usa setInterval. El otro usa el reloj de la tarjeta de sonido. Dales treinta segundos y escucha lo que pasa.
Qué estás oyendo
El canal izquierdo dispara con setInterval. El navegador no garantiza cuándo va a ejecutar ese callback: si hay una animación, una pestaña que pierde el foco o el recolector de basura pasando por ahí, llega tarde. Y el error no se corrige — se acumula. Cada retraso empuja al siguiente.
El canal derecho no programa sonidos: programa momentos. Un temporizador tosco se despierta cada 25 ms, mira 100 ms hacia delante y le dice a la tarjeta de sonido en qué instante exacto debe sonar el siguiente clic. La tarjeta tiene su propio reloj, en hardware, y ese no se distrae. El temporizador puede llegar tarde y no pasa nada, porque el sonido ya estaba encolado.
La diferencia no es de precisión. Es de arquitectura: no preguntes «¿ya toca?», di «suena en el segundo 12,4545».
El patrón, en cuatro líneas
Un planificador con antelación cabe en menos código del que parece. Es esto:
setInterval(() => {
// mientras haya notas dentro de la ventana de 100 ms
while (next < ctx.currentTime + 0.1) {
click(next); // se encola en hardware
next += 60 / bpm; // el tiempo lo lleva la suma, no el reloj
}
}, 25);