From 66f720f1eee0e2c5b23cbe2a9473d0d829e04037 Mon Sep 17 00:00:00 2001 From: Siavash Sameni Date: Fri, 27 Mar 2026 18:44:33 +0400 Subject: [PATCH] =?UTF-8?q?fix:=20cap=20web=20playback=20latency=20at=2030?= =?UTF-8?q?0ms=20=E2=80=94=20prevents=20drift=20accumulation?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When playback buffer drifts beyond 300ms ahead of real-time, reset to 40ms. This prevents the unbounded latency growth over long sessions. Co-Authored-By: Claude Opus 4.6 (1M context) --- crates/wzp-web/static/index.html | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/crates/wzp-web/static/index.html b/crates/wzp-web/static/index.html index f3c6313..42f4409 100644 --- a/crates/wzp-web/static/index.html +++ b/crates/wzp-web/static/index.html @@ -190,11 +190,15 @@ function playAudio(pcmInt16) { source.buffer = buffer; source.connect(audioCtx.destination); - // Schedule seamlessly: each buffer starts exactly where the last one ended const now = audioCtx.currentTime; + const MAX_LATENCY = 0.3; // 300ms max buffer — reset if we drift beyond this + if (nextPlayTime < now) { - // Fell behind — reset with small lookahead - nextPlayTime = now + 0.04; // 40ms initial buffer + // Fell behind — reset + nextPlayTime = now + 0.04; + } else if (nextPlayTime > now + MAX_LATENCY) { + // Too far ahead — skip to reduce latency + nextPlayTime = now + 0.04; } source.start(nextPlayTime); nextPlayTime += buffer.duration;