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 num_channels: usize,
pub frames_per_step: u16,
pub frames_per_tick: Num<u16, 8>,
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,
}
}
})

View file

@ -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<Option<ChannelId>>,
step: u16,
frame: Num<u16, 8>,
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;
}
}
}

View file

@ -202,6 +202,10 @@ pub fn parse_module(module: &Module) -> TokenStream {
.map(|order| *order as usize)
.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 {
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)