Get closer to some reasonable sounding

This commit is contained in:
Gwilym Inzani 2023-07-12 18:52:29 +01:00
parent 308cb3a19c
commit 436b49c80d
7 changed files with 32 additions and 30 deletions

View file

@ -8,6 +8,7 @@ pub struct Track<'a> {
pub pattern_data: &'a [PatternSlot],
pub patterns: &'a [Pattern],
pub num_channels: usize,
pub frames_per_step: u16,
}
@ -19,7 +20,6 @@ pub struct Sample<'a> {
#[derive(Debug)]
pub struct Pattern {
pub num_channels: usize,
pub length: usize,
pub start_position: usize,
}
@ -42,6 +42,7 @@ impl<'a> quote::ToTokens for Track<'a> {
pattern_data,
patterns,
frames_per_step,
num_channels,
} = self;
tokens.append_all(quote! {
@ -58,6 +59,7 @@ impl<'a> quote::ToTokens for Track<'a> {
patterns: PATTERNS,
frames_per_step: #frames_per_step,
num_channels: #num_channels,
}
}
})
@ -136,7 +138,6 @@ impl quote::ToTokens for Pattern {
use quote::{quote, TokenStreamExt};
let Pattern {
num_channels,
length,
start_position,
} = self;
@ -146,7 +147,6 @@ impl quote::ToTokens for Pattern {
use agb_tracker_interop::*;
Pattern {
num_channels: #num_channels,
length: #length,
start_position: #start_position,
}

View file

@ -5,7 +5,7 @@ use agb::sound::mixer::Frequency;
use agb::Gba;
use agb_tracker::{import_xm, Track, Tracker};
const AJOJ: Track = import_xm!("examples/ajoj.xm");
const AJOJ: Track = import_xm!("examples/db_toffe.xm");
#[agb::entry]
fn main(mut gba: Gba) -> ! {

Binary file not shown.

Binary file not shown.

View file

@ -7,7 +7,7 @@
extern crate alloc;
use alloc::{vec, vec::Vec};
use alloc::vec::Vec;
use agb::sound::mixer::{ChannelId, Mixer, SoundChannel};
@ -29,11 +29,12 @@ pub struct Tracker {
impl Tracker {
pub fn new(track: &'static Track<'static>) -> Self {
agb::println!("{}", track.frames_per_step);
let mut channels = Vec::new();
channels.resize_with(track.num_channels, || None);
Self {
track,
channels: vec![],
channels,
step: 0,
current_row: 0,
@ -49,16 +50,21 @@ impl Tracker {
let current_pattern = &self.track.patterns[self.current_pattern];
let channels_to_play = current_pattern.num_channels;
self.channels.resize_with(channels_to_play, || None);
let pattern_data_pos = current_pattern.start_position + self.current_row * channels_to_play;
let pattern_data_pos =
current_pattern.start_position + self.current_row * self.track.num_channels;
let pattern_slots =
&self.track.pattern_data[pattern_data_pos..pattern_data_pos + channels_to_play];
&self.track.pattern_data[pattern_data_pos..pattern_data_pos + self.track.num_channels];
for (channel_id, pattern_slot) in self.channels.iter_mut().zip(pattern_slots) {
if pattern_slot.sample == 0 {
// do nothing
if pattern_slot.speed == 0.into() {
if let Some(channel) = channel_id
.take()
.and_then(|channel_id| mixer.channel(&channel_id))
{
channel.stop();
}
}
} else {
if let Some(channel) = channel_id
.take()

View file

@ -99,7 +99,6 @@ pub fn parse_module(module: &Module) -> TokenStream {
let mut pattern_data = vec![];
for pattern in &module.pattern {
let mut num_channels = 0;
let start_pos = pattern_data.len();
for row in pattern.iter() {
@ -122,19 +121,21 @@ pub fn parse_module(module: &Module) -> TokenStream {
}
};
let volume = Num::new(
if slot.volume == 0 {
64
} else {
slot.volume as i16
} / 64,
);
let volume = Num::new(if slot.volume == 0 {
64
} else {
slot.volume as i16
}) / 64;
if sample == 0 {
// TODO should take into account previous sample played on this channel
pattern_data.push(agb_tracker_interop::PatternSlot {
volume: Num::new(0),
speed: Num::new(0),
speed: if matches!(slot.note, Note::KeyOff) {
0.into()
} else {
note_to_speed(slot.note, 0.0, 0)
},
panning: Num::new(0),
sample: 0,
})
@ -156,12 +157,9 @@ pub fn parse_module(module: &Module) -> TokenStream {
});
}
}
num_channels = row.len();
}
patterns.push(agb_tracker_interop::Pattern {
num_channels,
length: pattern.len(),
start_position: start_pos,
});
@ -175,15 +173,13 @@ pub fn parse_module(module: &Module) -> TokenStream {
})
.collect();
let frames_per_step =
((60.0 * 60.0) / module.default_bpm as f64 / module.default_tempo as f64) as u16;
let interop = agb_tracker_interop::Track {
samples: &samples,
pattern_data: &pattern_data,
patterns: &patterns,
num_channels: module.get_num_channels(),
frames_per_step,
frames_per_step: 2, // TODO calculate this correctly
};
quote!(#interop)

View file

@ -1,6 +1,6 @@
fn main() -> Result<(), Box<dyn std::error::Error>> {
let module = agb_xm_core::load_module_from_file(&std::path::Path::new(
"../agb-tracker/examples/ajoj.xm",
"../agb-tracker/examples/final_countdown.xm",
))?;
let output = agb_xm_core::parse_module(&module);