From 2b873a92a203d12eb3ca01d3b2c69cea0c7fbb27 Mon Sep 17 00:00:00 2001 From: Alula <6276139+alula@users.noreply.github.com> Date: Sun, 27 Jun 2021 08:02:21 +0200 Subject: [PATCH] sample looping support --- src/sound/mod.rs | 18 ++++++++++++++++- src/sound/pixtone.rs | 48 +++++++++++++++++++++++++++++++++++++++----- 2 files changed, 60 insertions(+), 6 deletions(-) diff --git a/src/sound/mod.rs b/src/sound/mod.rs index 92abc1f..874a82e 100644 --- a/src/sound/mod.rs +++ b/src/sound/mod.rs @@ -78,6 +78,14 @@ impl SoundManager { let _ = self.tx.send(PlaybackMessage::PlaySample(id)); } + pub fn loop_sfx(&self, id: u8) { + let _ = self.tx.send(PlaybackMessage::LoopSample(id)); + } + + pub fn stop_sfx(&self, id: u8) { + let _ = self.tx.send(PlaybackMessage::StopSample(id)); + } + pub fn play_song( &mut self, song_id: usize, @@ -255,7 +263,6 @@ impl SoundManager { let _ = splits.next(); if let Some(str) = splits.next() { - println!("{}", str); return str.trim().parse::().map_err(|_| GameError::ParseError("failed to parse the value as specified type.".to_string())) } else { break; @@ -314,6 +321,8 @@ enum PlaybackMessage { #[cfg(feature = "ogg-playback")] PlayOggSongMultiPart(Box>, Box>), PlaySample(u8), + LoopSample(u8), + StopSample(u8), SetSpeed(f32), SaveState, RestoreState, @@ -428,6 +437,13 @@ where Ok(PlaybackMessage::PlaySample(id)) => { pixtone.play_sfx(id); } + + Ok(PlaybackMessage::LoopSample(id)) => { + pixtone.loop_sfx(id); + } + Ok(PlaybackMessage::StopSample(id)) => { + pixtone.stop_sfx(id); + } Ok(PlaybackMessage::Stop) => { if state == PlaybackState::Stopped { saved_state = PlaybackStateType::None; diff --git a/src/sound/pixtone.rs b/src/sound/pixtone.rs index 00ffc15..0bee3e8 100644 --- a/src/sound/pixtone.rs +++ b/src/sound/pixtone.rs @@ -177,7 +177,12 @@ impl PixToneParameters { } #[derive(Copy, Clone, PartialEq)] -pub struct PlaybackState(u8, f32, u32); +pub struct PlaybackState { + id: u8 + pos: f32, + tag: u32, + looping: bool, +} pub struct PixTonePlayback { pub samples: HashMap>, @@ -213,17 +218,50 @@ impl PixTonePlayback { pub fn play_sfx(&mut self, id: u8) { for state in self.playback_state.iter_mut() { - if state.0 == id && state.2 == 0 { - state.1 = 0.0; + if state.id == id && state.tag == 0 { + state.pos = 0.0; + state.looping = false; return; } } - self.playback_state.push(PlaybackState(id, 0.0, 0)); + self.playback_state.push(PlaybackState { + id, + pos: 0.0, + tag: 0, + looping: false + }); + } + + pub fn loop_sfx(&mut self, id: u8) { + for state in self.playback_state.iter_mut() { + if state.id == id && state.tag == 0 { + state.looping = true; + return; + } + } + + self.playback_state.push(PlaybackState { + id, + pos: 0.0, + tag: 0, + looping: true + }); + } + + pub fn stop_sfx(&mut self, id: u8) { + if let Some(pos) = self.playback_state.iter().position(|s| s.id == id && s.tag == 0) { + self.playback_state.remove(pos); + } } pub fn play_concurrent(&mut self, id: u8, tag: u32) { - self.playback_state.push(PlaybackState(id, 0.0, tag)); + self.playback_state.push(PlaybackState { + id, + pos: 0.0, + tag, + looping: false + }); } pub fn mix(&mut self, dst: &mut [u16], sample_rate: f32) {