From b3e0fe3b309af5e853a155e9d25dcfa72540bf0f Mon Sep 17 00:00:00 2001 From: Mute Date: Mon, 17 Aug 2026 06:41:32 +0000 Subject: [PATCH] fix: drain loop uses fixed 100ms deadline instead of idle timeout --- rvsttd/src/main.rs | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/rvsttd/src/main.rs b/rvsttd/src/main.rs index 2d4720d..2a1050b 100644 --- a/rvsttd/src/main.rs +++ b/rvsttd/src/main.rs @@ -288,11 +288,9 @@ fn transcriber_loop( r.log_event(&format!("session {} started", shared.session_id)); } - let drain_timeout = Duration::from_millis(100); - // Main loop: process audio until stop_signal while !stop_signal.load(Ordering::SeqCst) { - match rx.recv_timeout(drain_timeout) { + match rx.recv_timeout(Duration::from_millis(100)) { Ok(chunk) => { if let Some(ref mut r) = recorder { r.add_audio(&chunk); @@ -323,9 +321,12 @@ fn transcriber_loop( } } - // Drain trailing audio from ALSA buffer (cpal stream still alive) - loop { - match rx.recv_timeout(drain_timeout) { + // Drain trailing audio from ALSA buffer (cpal stream still alive). + // Fixed 100ms window — cpal delivers every ~50ms (800 samples @ 16kHz), + // so this captures 1-2 more callbacks worth of trailing audio. + let drain_deadline = std::time::Instant::now() + Duration::from_millis(100); + while std::time::Instant::now() < drain_deadline { + match rx.recv_timeout(drain_deadline - std::time::Instant::now()) { Ok(chunk) => { if let Some(ref mut r) = recorder { r.add_audio(&chunk);