diff --git a/tracker/agb-tracker-interop/src/lib.rs b/tracker/agb-tracker-interop/src/lib.rs index 47b5bd04..23d82b5b 100644 --- a/tracker/agb-tracker-interop/src/lib.rs +++ b/tracker/agb-tracker-interop/src/lib.rs @@ -10,7 +10,8 @@ pub struct Track<'a> { pub patterns_to_play: &'a [usize], pub num_channels: usize, - pub frames_per_step: u16, + pub frames_per_tick: Num, + pub ticks_per_step: u16, } #[derive(Debug)] @@ -45,11 +46,14 @@ impl<'a> quote::ToTokens for Track<'a> { samples, pattern_data, patterns, - frames_per_step, + frames_per_tick, num_channels, patterns_to_play, + ticks_per_step, } = self; + let frames_per_tick = frames_per_tick.to_raw(); + tokens.append_all(quote! { { const SAMPLES: &[agb_tracker::__private::agb_tracker_interop::Sample<'static>] = &[#(#samples),*]; @@ -63,8 +67,9 @@ impl<'a> quote::ToTokens for Track<'a> { patterns: PATTERNS, patterns_to_play: PATTERNS_TO_PLAY, - frames_per_step: #frames_per_step, + frames_per_tick: agb_tracker::__private::Num::from_raw(#frames_per_tick), num_channels: #num_channels, + ticks_per_step: #ticks_per_step, } } }) diff --git a/tracker/agb-tracker/src/lib.rs b/tracker/agb-tracker/src/lib.rs index 3b4c18d2..b84ed05d 100644 --- a/tracker/agb-tracker/src/lib.rs +++ b/tracker/agb-tracker/src/lib.rs @@ -9,7 +9,10 @@ extern crate alloc; use alloc::vec::Vec; -use agb::sound::mixer::{ChannelId, Mixer, SoundChannel}; +use agb::{ + fixnum::Num, + sound::mixer::{ChannelId, Mixer, SoundChannel}, +}; #[cfg(feature = "xm")] pub use agb_xm::import_xm; @@ -25,7 +28,9 @@ pub struct Tracker { track: &'static Track<'static>, channels: Vec>, - step: u16, + frame: Num, + tick: u16, + current_row: usize, current_pattern: usize, } @@ -39,14 +44,16 @@ impl Tracker { track, channels, - step: 0, + frame: 0.into(), + tick: 0, + current_row: 0, current_pattern: 0, } } pub fn step(&mut self, mixer: &mut Mixer) { - if self.step != 0 { + if self.tick != 0 { self.increment_step(); return; // TODO: volume / pitch slides } @@ -113,9 +120,14 @@ impl Tracker { } fn increment_step(&mut self) { - self.step += 1; + self.frame += 1; - if self.step == self.track.frames_per_step { + if self.frame >= self.track.frames_per_tick { + self.tick += 1; + self.frame -= self.track.frames_per_tick; + } + + if self.tick == self.track.ticks_per_step { self.current_row += 1; if self.current_row @@ -129,7 +141,7 @@ impl Tracker { } } - self.step = 0; + self.tick = 0; } } } diff --git a/tracker/agb-xm-core/src/lib.rs b/tracker/agb-xm-core/src/lib.rs index 9e09c095..5326e8ae 100644 --- a/tracker/agb-xm-core/src/lib.rs +++ b/tracker/agb-xm-core/src/lib.rs @@ -202,6 +202,10 @@ pub fn parse_module(module: &Module) -> TokenStream { .map(|order| *order as usize) .collect::>(); + // Number 150 here deduced experimentally + let frames_per_tick = Num::::new(150) / module.default_bpm; + let ticks_per_step = module.default_tempo; + let interop = agb_tracker_interop::Track { samples: &samples, pattern_data: &pattern_data, @@ -209,7 +213,8 @@ pub fn parse_module(module: &Module) -> TokenStream { num_channels: module.get_num_channels(), patterns_to_play: &patterns_to_play, - frames_per_step: 4, // TODO calculate this correctly + frames_per_tick, + ticks_per_step, }; quote!(#interop)