fix: keep cpal Stream alive until playback completes (Closes #404) (#405)

The cpal Stream was created and play() called but then immediately
dropped when play_to_device() returned. When a cpal Stream is dropped,
audio output stops immediately. This caused silent playback.

Fix: add a spin-wait loop that holds the Stream in scope until all
samples have been consumed (or stop_flag is set).
This commit is contained in:
Cocoon-Break
2026-04-16 01:54:31 -07:00
committed by GitHub
parent be7c0cec12
commit 3e7727d1d2
+17 -1
View File
@@ -401,9 +401,25 @@ impl AudioOutputState {
eprintln!("play_to_device: Failed to play stream: {}", e);
format!("Failed to play stream: {}", e)
})?;
eprintln!("play_to_device: Stream started successfully");
// Keep the stream alive until playback finishes.
// Previously the stream was dropped immediately on function return,
// causing silent playback (cpal stops output when its Stream is dropped).
let total_samples = {
buffer.lock().unwrap().len()
};
loop {
let pos = position.load(std::sync::atomic::Ordering::Relaxed);
if pos >= total_samples || stop_flag.load(std::sync::atomic::Ordering::Relaxed) {
break;
}
std::thread::sleep(std::time::Duration::from_millis(10));
}
// stream is dropped here, after audio has finished playing
drop(stream);
eprintln!("play_to_device: Function completed successfully");
Ok(())
}