fix: reduce main thread pressure to prevent audio buffer underruns

The periodic audio glitches were caused by main thread starvation:
~840 events/sec during playback starved the audio buffer.

Changes:
- Master clock 480→120 Hz (still 6x headroom for 300 BPM sixteenths)
- Connection cache: replace O(n) reduce hash with dirty flag (zero work
  on cache hit, flag set only when connections actually change)
- Tone.js lookAhead: 100ms→50ms for tighter scheduling
- ModuleNode LFO visualization RAF: 60fps→15fps (every 4th frame)
- ScopeDisplay RAF: 60fps→30fps (every 2nd frame)

Net effect: ~840 events/sec → ~200 events/sec during playback.
Audio processing gets 4x more main thread headroom.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Jose Luis
2026-03-21 18:19:12 +01:00
parent 7596aea491
commit 7e6c960b0b
5 changed files with 26 additions and 10 deletions

View File

@@ -22,7 +22,13 @@ export default function ScopeDisplay({ moduleId }) {
const w = canvas.width = 160;
const h = canvas.height = 60;
let frameCount = 0;
const draw = () => {
frameCount++;
rafRef.current = requestAnimationFrame(draw);
// Throttle to ~30fps to reduce main thread pressure during playback
if (frameCount % 2 !== 0) return;
ctx.fillStyle = '#050510';
ctx.fillRect(0, 0, w, h);
@@ -58,7 +64,6 @@ export default function ScopeDisplay({ moduleId }) {
ctx.stroke();
}
rafRef.current = requestAnimationFrame(draw);
};
draw();