From 3e932e563832f2878217d8ad4628c781fa15e079 Mon Sep 17 00:00:00 2001 From: GarandPLG Date: Thu, 9 Apr 2026 01:08:50 +0200 Subject: [PATCH] Add ChangePart command and buffered audio sink Introduce a `ChangePart` variant to `AudioCmd` and a `current_part` state in `handle_audio`. The audio sink is now created via `DeviceSinkBuilder::from_default_device` with a fixed buffer size. `load_audio` now accepts a reference to `SoundrackParts`, and the player automatically queues the correct part when the queue becomes empty. --- src/app/threads/audio.rs | 50 ++++++++++++++++++++++++---------------- 1 file changed, 30 insertions(+), 20 deletions(-) diff --git a/src/app/threads/audio.rs b/src/app/threads/audio.rs index e80ba1b..a515ef2 100644 --- a/src/app/threads/audio.rs +++ b/src/app/threads/audio.rs @@ -1,4 +1,6 @@ -use rodio::{Decoder, DeviceSinkBuilder, MixerDeviceSink, Player, Source, source::Amplify}; +use rodio::{ + Decoder, DeviceSinkBuilder, MixerDeviceSink, Player, Source, cpal::BufferSize, source::Amplify, +}; use std::{fs::File, io::BufReader, sync::mpsc::Receiver}; #[derive(Debug)] @@ -6,8 +8,10 @@ pub enum AudioCmd { Mute, VolumeUp, VolumeDown, + ChangePart(SoundrackParts), } +#[derive(Debug)] pub enum SoundrackParts { Calm, Buildup, @@ -15,7 +19,7 @@ pub enum SoundrackParts { Outro, } -fn load_audio(part: SoundrackParts) -> Amplify>> { +fn load_audio(part: &SoundrackParts) -> Amplify>> { let file: File = match part { SoundrackParts::Calm => File::open("soundtrack/default/test.ogg").expect("open audio file"), SoundrackParts::Buildup => { @@ -35,36 +39,33 @@ fn load_audio(part: SoundrackParts) -> Amplify>> { } pub fn handle_audio(rx: Receiver, mute: bool) { - let mut handle: MixerDeviceSink = - DeviceSinkBuilder::open_default_sink().expect("open default audio stream"); - + let mut handle: MixerDeviceSink = DeviceSinkBuilder::from_default_device() + .expect("get default device") + .with_buffer_size(BufferSize::Fixed(4096)) + .open_sink_or_fallback() + .expect("open device audio stream"); handle.log_on_drop(false); let player: Player = Player::connect_new(&handle.mixer()); let mut volume: f32 = player.volume(); + player.set_volume(if mute { 0.0 } else { volume }); - if mute { - player.set_volume(0.0); - } else { - player.set_volume(volume); - } + // let preloaded_soundtrack_files: [File; 4] = [ + // File::open("soundtrack/default/test.ogg").expect("open audio file"), + // File::open("soundtrack/default/test.ogg").expect("open audio file"), + // File::open("soundtrack/default/test.ogg").expect("open audio file"), + // File::open("soundtrack/default/test.ogg").expect("open audio file"), + // ]; - player.append(load_audio(SoundrackParts::Calm)); + let mut current_part: SoundrackParts = SoundrackParts::Calm; + player.append(load_audio(¤t_part)); loop { - if player.empty() { - player.append(load_audio(SoundrackParts::Calm)); - } - for cmd in rx.try_iter() { match cmd { AudioCmd::Mute => { - if player.volume() == 0.0 { - player.set_volume(volume); - } else { - player.set_volume(0.0); - } + player.set_volume(if player.volume() == 0.0 { volume } else { 0.0 }); } AudioCmd::VolumeUp => { volume = (volume + 0.1).min(1.0); @@ -74,7 +75,16 @@ pub fn handle_audio(rx: Receiver, mute: bool) { volume = (volume - 0.1).max(0.0); player.set_volume(volume); } + AudioCmd::ChangePart(part) => { + current_part = part; + player.append(load_audio(¤t_part)); + player.skip_one(); + } } } + + if player.empty() { + player.append(load_audio(¤t_part)); + } } }