From f21e5224e5911611250679d331beee81e6f5a6ea Mon Sep 17 00:00:00 2001 From: Patrick Reynolds Date: Sun, 28 Jan 2024 20:43:57 -0500 Subject: [PATCH] Hold the queue in the caller Instead of sleeping and then dropping the queue in `play_sound`, pass the queue back to the caller for safekeeping. Not pretty, but it makes the program work as expected. I think AudioQueue may just be broken. I would expect to be able to call `AudioQueue.queue_audio` repeatedly on the same object and have it play the sounds in sequence, or immediately, if no sound is currently playing. That's how it works on macOS. But on Linux (with PulseAudio), only the first `queue_audio` call plays anything, and subsequent calls are silent. Several variations of calls to `.pause`, `.resume`, and `.clear`, didn't improve matters. So the fix is to make a new queue for each sound and make sure it isn't dropped until that sound has finished playing. --- src/bin/letters.rs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/bin/letters.rs b/src/bin/letters.rs index 9f22a3d..71ac4cf 100644 --- a/src/bin/letters.rs +++ b/src/bin/letters.rs @@ -1,6 +1,5 @@ use std::collections::HashMap; -use std::time::Duration; -use sdl2::{ttf::{self, Font}, pixels::Color, event::Event, keyboard::Mod, render::Canvas, video::Window, rect::{Rect, Point}, audio::{AudioSpecWAV, AudioSpecDesired}, Sdl}; +use sdl2::{ttf::{self, Font}, pixels::Color, event::Event, keyboard::Mod, render::Canvas, video::Window, rect::{Rect, Point}, audio::{AudioQueue, AudioSpecDesired, AudioSpecWAV}, Sdl}; fn main() { let sdl = sdl2::init().unwrap(); @@ -15,6 +14,8 @@ fn main() { canvas.clear(); canvas.present(); + let mut queue: Option> = None; + for event in sdl.event_pump().unwrap().wait_iter() { match event { Event::Quit { timestamp: _ } => { break }, @@ -38,7 +39,7 @@ fn main() { // display and play sound for any letter or number if c.is_alphanumeric() { draw_letter(&mut canvas, &font, c); - play_sound(&sdl, sounds.get(&c).unwrap()); + queue = Some(play_sound(&sdl, sounds.get(&c).unwrap())); } } } @@ -47,7 +48,7 @@ fn main() { }; } - println!("quit"); + println!("quit: {}", queue.is_some()); } fn draw_letter(canvas: &mut Canvas, font: &Font, c: char) { @@ -85,7 +86,7 @@ fn init_audio() -> HashMap { sounds } -fn play_sound(sdl: &Sdl, sound: &AudioSpecWAV) { +fn play_sound(sdl: &Sdl, sound: &AudioSpecWAV) -> AudioQueue { let desired = AudioSpecDesired{ freq: Some(sound.freq), channels: Some(sound.channels), @@ -95,6 +96,5 @@ fn play_sound(sdl: &Sdl, sound: &AudioSpecWAV) { let sound_queue = audio.open_queue(None, &desired).unwrap(); sound_queue.queue_audio(sound.buffer()).unwrap(); sound_queue.resume(); - let audio_len = sound.buffer().len(); // bytes - std::thread::sleep(Duration::from_millis(audio_len as u64 * 1000 / sound.freq as u64 / sound.channels as u64)); + sound_queue } \ No newline at end of file