generated from GarandPLG/rust-flake-template
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.
This commit is contained in:
+30
-20
@@ -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<Decoder<BufReader<File>>> {
|
||||
fn load_audio(part: &SoundrackParts) -> Amplify<Decoder<BufReader<File>>> {
|
||||
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<Decoder<BufReader<File>>> {
|
||||
}
|
||||
|
||||
pub fn handle_audio(rx: Receiver<AudioCmd>, 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<AudioCmd>, 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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user