Attempt to calculate the speed to play more correctly

This commit is contained in:
Gwilym Inzani 2023-07-16 21:12:12 +01:00
parent c66f495cc7
commit a0be2a333e
3 changed files with 33 additions and 11 deletions

View file

@ -10,7 +10,8 @@ pub struct Track<'a> {
pub patterns_to_play: &'a [usize], pub patterns_to_play: &'a [usize],
pub num_channels: usize, pub num_channels: usize,
pub frames_per_step: u16, pub frames_per_tick: Num<u16, 8>,
pub ticks_per_step: u16,
} }
#[derive(Debug)] #[derive(Debug)]
@ -45,11 +46,14 @@ impl<'a> quote::ToTokens for Track<'a> {
samples, samples,
pattern_data, pattern_data,
patterns, patterns,
frames_per_step, frames_per_tick,
num_channels, num_channels,
patterns_to_play, patterns_to_play,
ticks_per_step,
} = self; } = self;
let frames_per_tick = frames_per_tick.to_raw();
tokens.append_all(quote! { tokens.append_all(quote! {
{ {
const SAMPLES: &[agb_tracker::__private::agb_tracker_interop::Sample<'static>] = &[#(#samples),*]; 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: PATTERNS,
patterns_to_play: PATTERNS_TO_PLAY, 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, num_channels: #num_channels,
ticks_per_step: #ticks_per_step,
} }
} }
}) })

View file

@ -9,7 +9,10 @@ extern crate alloc;
use alloc::vec::Vec; use alloc::vec::Vec;
use agb::sound::mixer::{ChannelId, Mixer, SoundChannel}; use agb::{
fixnum::Num,
sound::mixer::{ChannelId, Mixer, SoundChannel},
};
#[cfg(feature = "xm")] #[cfg(feature = "xm")]
pub use agb_xm::import_xm; pub use agb_xm::import_xm;
@ -25,7 +28,9 @@ pub struct Tracker {
track: &'static Track<'static>, track: &'static Track<'static>,
channels: Vec<Option<ChannelId>>, channels: Vec<Option<ChannelId>>,
step: u16, frame: Num<u16, 8>,
tick: u16,
current_row: usize, current_row: usize,
current_pattern: usize, current_pattern: usize,
} }
@ -39,14 +44,16 @@ impl Tracker {
track, track,
channels, channels,
step: 0, frame: 0.into(),
tick: 0,
current_row: 0, current_row: 0,
current_pattern: 0, current_pattern: 0,
} }
} }
pub fn step(&mut self, mixer: &mut Mixer) { pub fn step(&mut self, mixer: &mut Mixer) {
if self.step != 0 { if self.tick != 0 {
self.increment_step(); self.increment_step();
return; // TODO: volume / pitch slides return; // TODO: volume / pitch slides
} }
@ -113,9 +120,14 @@ impl Tracker {
} }
fn increment_step(&mut self) { 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; self.current_row += 1;
if self.current_row if self.current_row
@ -129,7 +141,7 @@ impl Tracker {
} }
} }
self.step = 0; self.tick = 0;
} }
} }
} }

View file

@ -202,6 +202,10 @@ pub fn parse_module(module: &Module) -> TokenStream {
.map(|order| *order as usize) .map(|order| *order as usize)
.collect::<Vec<_>>(); .collect::<Vec<_>>();
// Number 150 here deduced experimentally
let frames_per_tick = Num::<u16, 8>::new(150) / module.default_bpm;
let ticks_per_step = module.default_tempo;
let interop = agb_tracker_interop::Track { let interop = agb_tracker_interop::Track {
samples: &samples, samples: &samples,
pattern_data: &pattern_data, pattern_data: &pattern_data,
@ -209,7 +213,8 @@ pub fn parse_module(module: &Module) -> TokenStream {
num_channels: module.get_num_channels(), num_channels: module.get_num_channels(),
patterns_to_play: &patterns_to_play, patterns_to_play: &patterns_to_play,
frames_per_step: 4, // TODO calculate this correctly frames_per_tick,
ticks_per_step,
}; };
quote!(#interop) quote!(#interop)