From 67de2d5833bffd79a9360f1ce62402a0cc9c53a7 Mon Sep 17 00:00:00 2001 From: Gwilym Inzani Date: Sat, 5 Aug 2023 23:51:12 +0100 Subject: [PATCH] Implement fadeout --- tracker/agb-tracker-interop/src/lib.rs | 4 ++++ tracker/agb-tracker/src/lib.rs | 17 ++++++++++++----- tracker/agb-xm-core/src/lib.rs | 5 +++++ 3 files changed, 21 insertions(+), 5 deletions(-) diff --git a/tracker/agb-tracker-interop/src/lib.rs b/tracker/agb-tracker-interop/src/lib.rs index 1132aa39..7261d683 100644 --- a/tracker/agb-tracker-interop/src/lib.rs +++ b/tracker/agb-tracker-interop/src/lib.rs @@ -23,6 +23,7 @@ pub struct Sample<'a> { pub restart_point: u32, pub volume: Num, pub volume_envelope: Option, + pub fadeout: Num, } #[derive(Debug)] @@ -181,12 +182,14 @@ impl<'a> quote::ToTokens for Sample<'a> { restart_point, volume, volume_envelope, + fadeout, } = self; let volume_envelope = match volume_envelope { Some(index) => quote!(Some(#index)), None => quote!(None), }; + let fadeout = fadeout.to_raw(); let samples = ByteString(data); let volume = volume.to_raw(); @@ -203,6 +206,7 @@ impl<'a> quote::ToTokens for Sample<'a> { restart_point: #restart_point, volume: agb_tracker::__private::Num::from_raw(#volume), volume_envelope: #volume_envelope, + fadeout: agb_tracker::__private::Num::from_raw(#fadeout), } } }); diff --git a/tracker/agb-tracker/src/lib.rs b/tracker/agb-tracker/src/lib.rs index 86c0ef0c..533f6940 100644 --- a/tracker/agb-tracker/src/lib.rs +++ b/tracker/agb-tracker/src/lib.rs @@ -113,6 +113,7 @@ struct EnvelopeState { frame: usize, envelope_id: usize, finished: bool, + fadeout: Num, } #[derive(Clone)] @@ -179,6 +180,7 @@ impl Tracker { frame: 0, envelope_id, finished: false, + fadeout: sample.fadeout, }); } @@ -212,7 +214,7 @@ impl Tracker { if !channel.update_volume_envelope( mixer, - envelope_state.frame, + envelope_state, envelope, &self.global_settings, ) { @@ -448,9 +450,9 @@ impl TrackerChannel { #[must_use] fn update_volume_envelope( - &self, + &mut self, mixer: &mut Mixer<'_>, - frame: usize, + envelope_state: &EnvelopeState, envelope: &agb_tracker_interop::Envelope<'_>, global_settings: &GlobalSettings, ) -> bool { @@ -459,14 +461,19 @@ impl TrackerChannel { .as_ref() .and_then(|channel_id| mixer.channel(channel_id)) { - let amount = envelope.amount[frame]; + let amount = envelope.amount[envelope_state.frame]; + + if envelope_state.finished { + self.volume = (self.volume - envelope_state.fadeout).max(0.into()); + } channel.volume( (self.volume * amount.change_base() * global_settings.volume) .try_change_base() .unwrap(), ); - true + + self.volume != 0.into() } else { false } diff --git a/tracker/agb-xm-core/src/lib.rs b/tracker/agb-xm-core/src/lib.rs index 72f1f7da..ccc1251e 100644 --- a/tracker/agb-xm-core/src/lib.rs +++ b/tracker/agb-xm-core/src/lib.rs @@ -57,6 +57,7 @@ pub fn parse_module(module: &Module) -> TokenStream { restart_point: u32, volume: Num, envelope_id: Option, + fadeout: Num, } let mut samples = vec![]; @@ -109,6 +110,8 @@ pub fn parse_module(module: &Module) -> TokenStream { .collect::>(), }; + let fadeout = Num::from_raw((instrument.volume_fadeout * ((1 << 8) as f32)) as i32); + instruments_map.insert((instrument_index, sample_index), samples.len()); samples.push(SampleData { data: sample, @@ -118,6 +121,7 @@ pub fn parse_module(module: &Module) -> TokenStream { restart_point, volume, envelope_id, + fadeout, }); } } @@ -412,6 +416,7 @@ pub fn parse_module(module: &Module) -> TokenStream { restart_point: sample.restart_point, volume: sample.volume, volume_envelope: sample.envelope_id, + fadeout: sample.fadeout, }) .collect();