Implement fadeout

This commit is contained in:
Gwilym Inzani 2023-08-05 23:51:12 +01:00
parent f6ed1c484b
commit 67de2d5833
3 changed files with 21 additions and 5 deletions

View file

@ -23,6 +23,7 @@ pub struct Sample<'a> {
pub restart_point: u32, pub restart_point: u32,
pub volume: Num<i16, 8>, pub volume: Num<i16, 8>,
pub volume_envelope: Option<usize>, pub volume_envelope: Option<usize>,
pub fadeout: Num<i32, 8>,
} }
#[derive(Debug)] #[derive(Debug)]
@ -181,12 +182,14 @@ impl<'a> quote::ToTokens for Sample<'a> {
restart_point, restart_point,
volume, volume,
volume_envelope, volume_envelope,
fadeout,
} = self; } = self;
let volume_envelope = match volume_envelope { let volume_envelope = match volume_envelope {
Some(index) => quote!(Some(#index)), Some(index) => quote!(Some(#index)),
None => quote!(None), None => quote!(None),
}; };
let fadeout = fadeout.to_raw();
let samples = ByteString(data); let samples = ByteString(data);
let volume = volume.to_raw(); let volume = volume.to_raw();
@ -203,6 +206,7 @@ impl<'a> quote::ToTokens for Sample<'a> {
restart_point: #restart_point, restart_point: #restart_point,
volume: agb_tracker::__private::Num::from_raw(#volume), volume: agb_tracker::__private::Num::from_raw(#volume),
volume_envelope: #volume_envelope, volume_envelope: #volume_envelope,
fadeout: agb_tracker::__private::Num::from_raw(#fadeout),
} }
} }
}); });

View file

@ -113,6 +113,7 @@ struct EnvelopeState {
frame: usize, frame: usize,
envelope_id: usize, envelope_id: usize,
finished: bool, finished: bool,
fadeout: Num<i32, 8>,
} }
#[derive(Clone)] #[derive(Clone)]
@ -179,6 +180,7 @@ impl Tracker {
frame: 0, frame: 0,
envelope_id, envelope_id,
finished: false, finished: false,
fadeout: sample.fadeout,
}); });
} }
@ -212,7 +214,7 @@ impl Tracker {
if !channel.update_volume_envelope( if !channel.update_volume_envelope(
mixer, mixer,
envelope_state.frame, envelope_state,
envelope, envelope,
&self.global_settings, &self.global_settings,
) { ) {
@ -448,9 +450,9 @@ impl TrackerChannel {
#[must_use] #[must_use]
fn update_volume_envelope( fn update_volume_envelope(
&self, &mut self,
mixer: &mut Mixer<'_>, mixer: &mut Mixer<'_>,
frame: usize, envelope_state: &EnvelopeState,
envelope: &agb_tracker_interop::Envelope<'_>, envelope: &agb_tracker_interop::Envelope<'_>,
global_settings: &GlobalSettings, global_settings: &GlobalSettings,
) -> bool { ) -> bool {
@ -459,14 +461,19 @@ impl TrackerChannel {
.as_ref() .as_ref()
.and_then(|channel_id| mixer.channel(channel_id)) .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( channel.volume(
(self.volume * amount.change_base() * global_settings.volume) (self.volume * amount.change_base() * global_settings.volume)
.try_change_base() .try_change_base()
.unwrap(), .unwrap(),
); );
true
self.volume != 0.into()
} else { } else {
false false
} }

View file

@ -57,6 +57,7 @@ pub fn parse_module(module: &Module) -> TokenStream {
restart_point: u32, restart_point: u32,
volume: Num<i16, 8>, volume: Num<i16, 8>,
envelope_id: Option<usize>, envelope_id: Option<usize>,
fadeout: Num<i32, 8>,
} }
let mut samples = vec![]; let mut samples = vec![];
@ -109,6 +110,8 @@ pub fn parse_module(module: &Module) -> TokenStream {
.collect::<Vec<_>>(), .collect::<Vec<_>>(),
}; };
let fadeout = Num::from_raw((instrument.volume_fadeout * ((1 << 8) as f32)) as i32);
instruments_map.insert((instrument_index, sample_index), samples.len()); instruments_map.insert((instrument_index, sample_index), samples.len());
samples.push(SampleData { samples.push(SampleData {
data: sample, data: sample,
@ -118,6 +121,7 @@ pub fn parse_module(module: &Module) -> TokenStream {
restart_point, restart_point,
volume, volume,
envelope_id, envelope_id,
fadeout,
}); });
} }
} }
@ -412,6 +416,7 @@ pub fn parse_module(module: &Module) -> TokenStream {
restart_point: sample.restart_point, restart_point: sample.restart_point,
volume: sample.volume, volume: sample.volume,
volume_envelope: sample.envelope_id, volume_envelope: sample.envelope_id,
fadeout: sample.fadeout,
}) })
.collect(); .collect();