Correctly track restart point

This commit is contained in:
Gwilym Inzani 2023-07-16 23:12:42 +01:00
parent 1dd4c9fb83
commit 7861571a96
4 changed files with 21 additions and 6 deletions

View file

@ -484,7 +484,7 @@ impl MixerBuffer {
for i in 0..self.frequency.buffer_size() { for i in 0..self.frequency.buffer_size() {
if channel.pos >= channel_len { if channel.pos >= channel_len {
if channel.should_loop { if channel.should_loop {
channel.pos -= channel_len + channel.restart_point; channel.pos -= channel_len - channel.restart_point;
} else { } else {
channel.is_done = true; channel.is_done = true;
break; break;

View file

@ -18,6 +18,7 @@ pub struct Track<'a> {
pub struct Sample<'a> { pub struct Sample<'a> {
pub data: &'a [u8], pub data: &'a [u8],
pub should_loop: bool, pub should_loop: bool,
pub restart_point: u32,
} }
#[derive(Debug)] #[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 self_as_u8s: Vec<_> = self.data.iter().map(|i| *i as u8).collect();
let samples = ByteString(&self_as_u8s); let samples = ByteString(&self_as_u8s);
let should_loop = self.should_loop; let should_loop = self.should_loop;
let restart_point = self.restart_point;
tokens.append_all(quote! { tokens.append_all(quote! {
{ {
@ -102,7 +104,7 @@ impl<'a> quote::ToTokens for Sample<'a> {
struct AlignmentWrapper<const N: usize>([u8; N]); struct AlignmentWrapper<const N: usize>([u8; N]);
const SAMPLE_DATA: &[u8] = &AlignmentWrapper(*#samples).0; 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 }
} }
}); });
} }

View file

@ -106,7 +106,8 @@ impl Tracker {
new_channel new_channel
.panning(pattern_slot.panning) .panning(pattern_slot.panning)
.volume(pattern_slot.volume) .volume(pattern_slot.volume)
.playback(pattern_slot.speed); .playback(pattern_slot.speed)
.restart_point(sample.restart_point);
if sample.should_loop { if sample.should_loop {
new_channel.should_loop(); new_channel.should_loop();

View file

@ -54,6 +54,7 @@ pub fn parse_module(module: &Module) -> TokenStream {
fine_tune: f64, fine_tune: f64,
relative_note: i8, relative_note: i8,
volume: f64, volume: f64,
restart_point: u32,
} }
let mut samples = vec![]; let mut samples = vec![];
@ -66,14 +67,23 @@ pub fn parse_module(module: &Module) -> TokenStream {
let fine_tune = sample.finetune as f64; let fine_tune = sample.finetune as f64;
let relative_note = sample.relative_note; let relative_note = sample.relative_note;
let volume = sample.volume as f64; 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 { let sample = match &sample.data {
SampleDataType::Depth8(depth8) => { SampleDataType::Depth8(depth8) => depth8
depth8.iter().map(|value| *value as u8).collect::<Vec<_>>() .iter()
} .map(|value| *value as u8)
.take(sample_len)
.collect::<Vec<_>>(),
SampleDataType::Depth16(depth16) => depth16 SampleDataType::Depth16(depth16) => depth16
.iter() .iter()
.map(|sample| (sample >> 8) as i8 as u8) .map(|sample| (sample >> 8) as i8 as u8)
.take(sample_len)
.collect::<Vec<_>>(), .collect::<Vec<_>>(),
}; };
@ -84,6 +94,7 @@ pub fn parse_module(module: &Module) -> TokenStream {
fine_tune, fine_tune,
relative_note, relative_note,
volume, volume,
restart_point,
}); });
} }
} }
@ -193,6 +204,7 @@ pub fn parse_module(module: &Module) -> TokenStream {
.map(|sample| agb_tracker_interop::Sample { .map(|sample| agb_tracker_interop::Sample {
data: &sample.data, data: &sample.data,
should_loop: sample.should_loop, should_loop: sample.should_loop,
restart_point: sample.restart_point,
}) })
.collect(); .collect();