From 8a30caccbdfa69731c617532af46368802b56c88 Mon Sep 17 00:00:00 2001 From: nenikitov Date: Fri, 3 May 2024 16:18:32 -0400 Subject: [PATCH] feat(effect): start playback direction --- engine/src/asset/sound/dat/mixer.rs | 12 +++++++----- engine/src/asset/sound/dat/pattern_effect.rs | 16 ++++++++++++---- engine/src/asset/sound/dat/t_instrument.rs | 10 ++++------ engine/src/asset/sound/mod.rs | 4 ++-- engine/src/asset/sound/sample.rs | 10 ++++------ 5 files changed, 29 insertions(+), 23 deletions(-) diff --git a/engine/src/asset/sound/dat/mixer.rs b/engine/src/asset/sound/dat/mixer.rs index 4ad2469..fafb046 100644 --- a/engine/src/asset/sound/dat/mixer.rs +++ b/engine/src/asset/sound/dat/mixer.rs @@ -82,7 +82,7 @@ impl TSongMixerUtils for TSong { channel.effects[e].expect("effect is initialized after assignment") }) { match effect { - PatternEffect::Dummy => {} + PatternEffect::Dummy(_) => {} PatternEffect::Speed(Speed::Bpm(s)) => { bpm = s; } @@ -92,16 +92,17 @@ impl TSongMixerUtils for TSong { PatternEffect::Volume(Volume::Value(volume)) => { channel.volume = volume; } - PatternEffect::Volume(Volume::Slide(Some(volume))) => { - channel.volume_slide = volume; - } PatternEffect::SampleOffset(Some(offset)) => { channel.sample_position = offset; } + PatternEffect::PlaybackDirection(direction) => { + channel.playback_direaction = direction + } PatternEffect::Volume(Volume::Slide(None)) | PatternEffect::SampleOffset(None) => { unreachable!("effect memory should already be initialized") } + _ => {} }; } @@ -172,7 +173,8 @@ struct Channel<'a> { volume: f32, volume_evelope_position: usize, - volume_slide: f32, + + playback_direaction: PlaybackDirection, } impl<'a> Channel<'a> { diff --git a/engine/src/asset/sound/dat/pattern_effect.rs b/engine/src/asset/sound/dat/pattern_effect.rs index 0d58c15..7c3fedf 100644 --- a/engine/src/asset/sound/dat/pattern_effect.rs +++ b/engine/src/asset/sound/dat/pattern_effect.rs @@ -18,6 +18,13 @@ pub enum Volume { Slide(Option), } +#[derive(Debug, Default, Clone, Copy)] +pub enum PlaybackDirection { + #[default] + Forwards, + Backwards, +} + #[derive(Debug, Hash, PartialEq, Eq, Clone, Copy)] pub enum PatternEffectMemoryKey { VolumeSlide, @@ -26,10 +33,11 @@ pub enum PatternEffectMemoryKey { #[derive(Debug, Clone, Copy)] pub enum PatternEffect { - Dummy, + Dummy(u8), Speed(Speed), Volume(Volume), SampleOffset(Option), + PlaybackDirection(PlaybackDirection), } impl PatternEffect { @@ -88,7 +96,7 @@ impl AssetParser for Option { 0x00 | 0x01 | 0x02 | 0x03 | 0x04 | 0x05 | 0x06 | 0x07 | 0x08 | 0x0A | 0x0B | 0x0C | 0x0D | 0x0F | 0x14 | 0x15 | 0x16 | 0x1D | 0x1E | 0x1F | 0x20 | 0x21 | 0x22 | 0x24 | 0x25 | 0x2E | 0x2F | 0x30 | 0x31 | 0x32 | 0x33 - | 0x34 | 0x35 | 0x36 | 0x37 => PatternEffect::Dummy, + | 0x34 | 0x35 => PatternEffect::Dummy(kind), // TODO(nenikitov): Add support for other effects // 0x00 => Self::Arpegio, // 0x01 => Self::PortaUp, @@ -123,8 +131,8 @@ impl AssetParser for Option { // 0x33 => Self::SoundControlQuad, // 0x34 => Self::FilterGlobal, // 0x35 => Self::FilterLocal, - // 0x36 => Self::PlayForward, - // 0x37 => Self::PlayBackward, + 0x36 => PatternEffect::PlaybackDirection(PlaybackDirection::Forwards), + 0x37 => PatternEffect::PlaybackDirection(PlaybackDirection::Backwards), // TODO(nenikitov): Should be a `Result` kind => unreachable!("Effect is outside the range {kind}"), }), diff --git a/engine/src/asset/sound/dat/t_instrument.rs b/engine/src/asset/sound/dat/t_instrument.rs index 8d527f9..8723acb 100644 --- a/engine/src/asset/sound/dat/t_instrument.rs +++ b/engine/src/asset/sound/dat/t_instrument.rs @@ -265,12 +265,10 @@ impl AssetParser for TSample { // TODO(nenikitov): Look into resampling the sample to 48 KHz loop_length, data: Sample { - data: Box::new( - sample_data[sample_offset as usize..loop_end as usize] - .into_iter() - .map(|&s| [s]) - .collect(), - ), + data: sample_data[sample_offset as usize..loop_end as usize] + .into_iter() + .map(|&s| [s]) + .collect(), sample_rate: Self::SAMPLE_RATE, }, }, diff --git a/engine/src/asset/sound/mod.rs b/engine/src/asset/sound/mod.rs index 8f95baf..4ffa6f8 100644 --- a/engine/src/asset/sound/mod.rs +++ b/engine/src/asset/sound/mod.rs @@ -89,8 +89,8 @@ mod tests { Sound::Song(s) => Some(s), Sound::Effect(_) => None, }) - .collect::>()[0x0]; - dbg!(&test_music.patterns[0][0x17][2].effects); + .collect::>()[0x9]; + dbg!(&test_music.patterns[0][0x29][5].effects); sounds .iter() diff --git a/engine/src/asset/sound/sample.rs b/engine/src/asset/sound/sample.rs index 257b6f9..4695d92 100644 --- a/engine/src/asset/sound/sample.rs +++ b/engine/src/asset/sound/sample.rs @@ -78,7 +78,7 @@ pub enum Interpolation { #[derive(Debug, Clone)] pub struct Sample { - pub data: Box>, + pub data: Vec<[S; CHANNELS]>, pub sample_rate: usize, } @@ -165,7 +165,7 @@ impl Sample { .stretch(sample_rate as f32 / self.sample_rate as f32, interpolation); Self { - data: Box::new(data), + data, sample_rate: self.sample_rate, } } @@ -226,10 +226,8 @@ impl SampleDataProcessing let len = (self.len() as f32 * factor).round() as usize; (0..len) - .into_iter() .map(|(i_sample)| { (0..CHANNELS) - .into_iter() .map(|i_channel| match interpolation { Interpolation::Nearest => { self[(i_sample as f32 / factor).floor() as usize][i_channel] @@ -272,7 +270,7 @@ impl Sample { let data = self.data.iter().map(|[s]| [*s, *s]).collect(); Sample:: { - data: Box::new(data), + data, sample_rate: self.sample_rate, } } @@ -299,7 +297,7 @@ impl Sample { .collect_vec(); Sample:: { - data: Box::new(data), + data, sample_rate: self.sample_rate, } }