diff --git a/agb/src/sound/mixer/sw_mixer.rs b/agb/src/sound/mixer/sw_mixer.rs index 55617aac..0e71faeb 100644 --- a/agb/src/sound/mixer/sw_mixer.rs +++ b/agb/src/sound/mixer/sw_mixer.rs @@ -484,7 +484,7 @@ impl MixerBuffer { for i in 0..self.frequency.buffer_size() { if channel.pos >= channel_len { if channel.should_loop { - channel.pos -= channel_len + channel.restart_point; + channel.pos -= channel_len - channel.restart_point; } else { channel.is_done = true; break; diff --git a/tracker/agb-tracker-interop/src/lib.rs b/tracker/agb-tracker-interop/src/lib.rs index 23d82b5b..e8502a50 100644 --- a/tracker/agb-tracker-interop/src/lib.rs +++ b/tracker/agb-tracker-interop/src/lib.rs @@ -18,6 +18,7 @@ pub struct Track<'a> { pub struct Sample<'a> { pub data: &'a [u8], pub should_loop: bool, + pub restart_point: u32, } #[derive(Debug)] @@ -95,6 +96,7 @@ impl<'a> quote::ToTokens for Sample<'a> { let self_as_u8s: Vec<_> = self.data.iter().map(|i| *i as u8).collect(); let samples = ByteString(&self_as_u8s); let should_loop = self.should_loop; + let restart_point = self.restart_point; tokens.append_all(quote! { { @@ -102,7 +104,7 @@ impl<'a> quote::ToTokens for Sample<'a> { struct AlignmentWrapper([u8; N]); const SAMPLE_DATA: &[u8] = &AlignmentWrapper(*#samples).0; - agb_tracker::__private::agb_tracker_interop::Sample { data: SAMPLE_DATA, should_loop: #should_loop } + agb_tracker::__private::agb_tracker_interop::Sample { data: SAMPLE_DATA, should_loop: #should_loop, restart_point: #restart_point } } }); } diff --git a/tracker/agb-tracker/src/lib.rs b/tracker/agb-tracker/src/lib.rs index b84ed05d..ab88bd32 100644 --- a/tracker/agb-tracker/src/lib.rs +++ b/tracker/agb-tracker/src/lib.rs @@ -106,7 +106,8 @@ impl Tracker { new_channel .panning(pattern_slot.panning) .volume(pattern_slot.volume) - .playback(pattern_slot.speed); + .playback(pattern_slot.speed) + .restart_point(sample.restart_point); if sample.should_loop { new_channel.should_loop(); diff --git a/tracker/agb-xm-core/src/lib.rs b/tracker/agb-xm-core/src/lib.rs index 5326e8ae..217e431a 100644 --- a/tracker/agb-xm-core/src/lib.rs +++ b/tracker/agb-xm-core/src/lib.rs @@ -54,6 +54,7 @@ pub fn parse_module(module: &Module) -> TokenStream { fine_tune: f64, relative_note: i8, volume: f64, + restart_point: u32, } let mut samples = vec![]; @@ -66,14 +67,23 @@ pub fn parse_module(module: &Module) -> TokenStream { let fine_tune = sample.finetune as f64; let relative_note = sample.relative_note; let volume = sample.volume as f64; + let restart_point = sample.loop_start; + let sample_len = if sample.loop_length > 0 { + (sample.loop_length + sample.loop_start) as usize + } else { + usize::MAX + }; let sample = match &sample.data { - SampleDataType::Depth8(depth8) => { - depth8.iter().map(|value| *value as u8).collect::>() - } + SampleDataType::Depth8(depth8) => depth8 + .iter() + .map(|value| *value as u8) + .take(sample_len) + .collect::>(), SampleDataType::Depth16(depth16) => depth16 .iter() .map(|sample| (sample >> 8) as i8 as u8) + .take(sample_len) .collect::>(), }; @@ -84,6 +94,7 @@ pub fn parse_module(module: &Module) -> TokenStream { fine_tune, relative_note, volume, + restart_point, }); } } @@ -193,6 +204,7 @@ pub fn parse_module(module: &Module) -> TokenStream { .map(|sample| agb_tracker_interop::Sample { data: &sample.data, should_loop: sample.should_loop, + restart_point: sample.restart_point, }) .collect();