From 4c1e3987ec53559026af18a56d3b366cd7707c03 Mon Sep 17 00:00:00 2001 From: Emil Date: Mon, 22 Jun 2026 00:06:30 +0300 Subject: [PATCH] fix: audio sounds now overlap instead of queueing sequentially Each sound creates its own Sink via OutputStreamHandle and calls detach(), so sounds play simultaneously and self-clean when finished. --- src/audio/mod.rs | 31 +++++++++++-------------------- 1 file changed, 11 insertions(+), 20 deletions(-) diff --git a/src/audio/mod.rs b/src/audio/mod.rs index 598ca22..4103be3 100644 --- a/src/audio/mod.rs +++ b/src/audio/mod.rs @@ -1,12 +1,12 @@ use rodio::source::Source; -use rodio::{OutputStream, Sink}; +use rodio::{OutputStream, OutputStreamHandle, Sink}; use std::collections::HashMap; use std::io::Cursor; use std::time::Instant; pub struct AudioEngine { _stream: Option, - sink: Option, + handle: Option, sounds: HashMap<&'static str, &'static [u8]>, last_played: HashMap<&'static str, Instant>, volume: f32, @@ -22,13 +22,6 @@ impl AudioEngine { return Self::disabled(); } }; - let sink = match Sink::try_new(&handle) { - Ok(s) => s, - Err(e) => { - eprintln!("Audio sink init failed: {}", e); - return Self::disabled(); - } - }; let mut sounds = HashMap::new(); sounds.insert( @@ -73,7 +66,7 @@ impl AudioEngine { Self { _stream: Some(stream), - sink: Some(sink), + handle: Some(handle), sounds, last_played: HashMap::new(), volume: 0.5, @@ -84,7 +77,7 @@ impl AudioEngine { fn disabled() -> Self { Self { _stream: None, - sink: None, + handle: None, sounds: HashMap::new(), last_played: HashMap::new(), volume: 0.0, @@ -112,13 +105,18 @@ impl AudioEngine { Some(d) => *d, None => return, }; - let sink = match &self.sink { - Some(s) => s, + let handle = match &self.handle { + Some(h) => h, None => return, }; + let sink = match Sink::try_new(handle) { + Ok(s) => s, + Err(_) => return, + }; if let Ok(decoder) = rodio::Decoder::new(Cursor::new(data.to_vec())) { let source = decoder.amplify(self.volume).convert_samples::(); sink.append(source); + sink.detach(); } } @@ -128,13 +126,6 @@ impl AudioEngine { pub fn toggle(&mut self) { self.enabled = !self.enabled; - if let Some(sink) = &self.sink { - if !self.enabled { - sink.pause(); - } else { - sink.play(); - } - } } pub fn is_enabled(&self) -> bool {