mirror of
https://github.com/italicsjenga/agb.git
synced 2024-12-23 08:11:33 +11:00
Consider the global volume
This commit is contained in:
parent
de085fc1ff
commit
a91069eac2
|
@ -19,6 +19,7 @@ pub struct Sample<'a> {
|
||||||
pub data: &'a [u8],
|
pub data: &'a [u8],
|
||||||
pub should_loop: bool,
|
pub should_loop: bool,
|
||||||
pub restart_point: u32,
|
pub restart_point: u32,
|
||||||
|
pub volume: Num<i16, 4>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
@ -104,10 +105,16 @@ impl<'a> quote::ToTokens for Sample<'a> {
|
||||||
fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
|
fn to_tokens(&self, tokens: &mut proc_macro2::TokenStream) {
|
||||||
use quote::{quote, TokenStreamExt};
|
use quote::{quote, TokenStreamExt};
|
||||||
|
|
||||||
let self_as_u8s: Vec<_> = self.data.iter().map(|i| *i as u8).collect();
|
let Sample {
|
||||||
|
data,
|
||||||
|
should_loop,
|
||||||
|
restart_point,
|
||||||
|
volume,
|
||||||
|
} = self;
|
||||||
|
|
||||||
|
let self_as_u8s: Vec<_> = 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 volume = volume.to_raw();
|
||||||
let restart_point = self.restart_point;
|
|
||||||
|
|
||||||
tokens.append_all(quote! {
|
tokens.append_all(quote! {
|
||||||
{
|
{
|
||||||
|
@ -115,7 +122,12 @@ 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, restart_point: #restart_point }
|
agb_tracker::__private::agb_tracker_interop::Sample {
|
||||||
|
data: SAMPLE_DATA,
|
||||||
|
should_loop: #should_loop,
|
||||||
|
restart_point: #restart_point,
|
||||||
|
volume: agb_tracker::__private::Num::from_raw(#volume),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -148,6 +148,8 @@ impl TrackerChannel {
|
||||||
|
|
||||||
let mut new_channel = SoundChannel::new(sample.data);
|
let mut new_channel = SoundChannel::new(sample.data);
|
||||||
|
|
||||||
|
new_channel.volume(sample.volume);
|
||||||
|
|
||||||
if sample.should_loop {
|
if sample.should_loop {
|
||||||
new_channel
|
new_channel
|
||||||
.should_loop()
|
.should_loop()
|
||||||
|
|
|
@ -55,6 +55,7 @@ pub fn parse_module(module: &Module) -> TokenStream {
|
||||||
fine_tune: f64,
|
fine_tune: f64,
|
||||||
relative_note: i8,
|
relative_note: i8,
|
||||||
restart_point: u32,
|
restart_point: u32,
|
||||||
|
volume: Num<i16, 4>,
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut samples = vec![];
|
let mut samples = vec![];
|
||||||
|
@ -73,6 +74,8 @@ pub fn parse_module(module: &Module) -> TokenStream {
|
||||||
usize::MAX
|
usize::MAX
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let volume = Num::from_raw((sample.volume * (1 << 4) as f32) as i16);
|
||||||
|
|
||||||
let sample = match &sample.data {
|
let sample = match &sample.data {
|
||||||
SampleDataType::Depth8(depth8) => depth8
|
SampleDataType::Depth8(depth8) => depth8
|
||||||
.iter()
|
.iter()
|
||||||
|
@ -93,6 +96,7 @@ pub fn parse_module(module: &Module) -> TokenStream {
|
||||||
fine_tune,
|
fine_tune,
|
||||||
relative_note,
|
relative_note,
|
||||||
restart_point,
|
restart_point,
|
||||||
|
volume,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -127,50 +131,62 @@ pub fn parse_module(module: &Module) -> TokenStream {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut effect1 = match slot.volume {
|
let mut effect1 = PatternEffect::None;
|
||||||
0x10..=0x50 => {
|
|
||||||
PatternEffect::Volume(Num::new((slot.volume - 0x10) as i16) / 64)
|
|
||||||
}
|
|
||||||
0xC0..=0xCF => PatternEffect::Panning(
|
|
||||||
Num::new(slot.volume as i16 - (0xC0 + (0xCF - 0xC0) / 2)) / 64,
|
|
||||||
),
|
|
||||||
_ => PatternEffect::None,
|
|
||||||
};
|
|
||||||
|
|
||||||
if matches!(slot.note, Note::KeyOff) {
|
let maybe_note_and_sample = if matches!(slot.note, Note::KeyOff) {
|
||||||
effect1 = PatternEffect::Stop;
|
effect1 = PatternEffect::Stop;
|
||||||
note_and_sample[channel_number] = None;
|
note_and_sample[channel_number] = None;
|
||||||
|
&None
|
||||||
} else if !matches!(slot.note, Note::None) {
|
} else if !matches!(slot.note, Note::None) {
|
||||||
if sample != 0 {
|
if sample != 0 {
|
||||||
note_and_sample[channel_number] = Some((slot.note, &samples[sample - 1]));
|
note_and_sample[channel_number] = Some((slot.note, &samples[sample - 1]));
|
||||||
} else if let Some((note, _)) = &mut note_and_sample[channel_number] {
|
} else if let Some((note, _)) = &mut note_and_sample[channel_number] {
|
||||||
*note = slot.note;
|
*note = slot.note;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
¬e_and_sample[channel_number]
|
||||||
|
} else {
|
||||||
|
¬e_and_sample[channel_number]
|
||||||
|
};
|
||||||
|
|
||||||
|
if matches!(effect1, PatternEffect::None) {
|
||||||
|
effect1 = match slot.volume {
|
||||||
|
0x10..=0x50 => PatternEffect::Volume(
|
||||||
|
(Num::new((slot.volume - 0x10) as i16) / 64)
|
||||||
|
* maybe_note_and_sample
|
||||||
|
.map(|note_and_sample| note_and_sample.1.volume)
|
||||||
|
.unwrap_or(1.into()),
|
||||||
|
),
|
||||||
|
0xC0..=0xCF => PatternEffect::Panning(
|
||||||
|
Num::new(slot.volume as i16 - (0xC0 + (0xCF - 0xC0) / 2)) / 64,
|
||||||
|
),
|
||||||
|
_ => PatternEffect::None,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
let effect2 = match slot.effect_type {
|
let effect2 = match slot.effect_type {
|
||||||
0x0 => {
|
0x0 => {
|
||||||
if slot.effect_parameter == 0 {
|
if slot.effect_parameter == 0 {
|
||||||
PatternEffect::None
|
PatternEffect::None
|
||||||
} else if let Some((note, sample)) = note_and_sample[channel_number] {
|
} else if let Some((note, sample)) = maybe_note_and_sample {
|
||||||
let first_arpeggio = slot.effect_parameter >> 4;
|
let first_arpeggio = slot.effect_parameter >> 4;
|
||||||
let second_arpeggio = slot.effect_parameter & 0xF;
|
let second_arpeggio = slot.effect_parameter & 0xF;
|
||||||
|
|
||||||
let note_speed = note_to_speed(
|
let note_speed = note_to_speed(
|
||||||
note,
|
*note,
|
||||||
sample.fine_tune,
|
sample.fine_tune,
|
||||||
sample.relative_note,
|
sample.relative_note,
|
||||||
module.frequency_type,
|
module.frequency_type,
|
||||||
);
|
);
|
||||||
|
|
||||||
let first_arpeggio_speed = note_to_speed(
|
let first_arpeggio_speed = note_to_speed(
|
||||||
note,
|
*note,
|
||||||
sample.fine_tune,
|
sample.fine_tune,
|
||||||
sample.relative_note + first_arpeggio as i8,
|
sample.relative_note + first_arpeggio as i8,
|
||||||
module.frequency_type,
|
module.frequency_type,
|
||||||
);
|
);
|
||||||
let second_arpeggio_speed = note_to_speed(
|
let second_arpeggio_speed = note_to_speed(
|
||||||
note,
|
*note,
|
||||||
sample.fine_tune,
|
sample.fine_tune,
|
||||||
sample.relative_note + second_arpeggio as i8,
|
sample.relative_note + second_arpeggio as i8,
|
||||||
module.frequency_type,
|
module.frequency_type,
|
||||||
|
@ -207,7 +223,15 @@ pub fn parse_module(module: &Module) -> TokenStream {
|
||||||
PatternEffect::VolumeSlide(Num::new(first as i16) / 16)
|
PatternEffect::VolumeSlide(Num::new(first as i16) / 16)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
0xC => PatternEffect::Volume(Num::new(slot.effect_parameter as i16) / 255),
|
0xC => {
|
||||||
|
if let Some((_, sample)) = maybe_note_and_sample {
|
||||||
|
PatternEffect::Volume(
|
||||||
|
(Num::new(slot.effect_parameter as i16) / 255) * sample.volume,
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
PatternEffect::None
|
||||||
|
}
|
||||||
|
}
|
||||||
_ => PatternEffect::None,
|
_ => PatternEffect::None,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -250,6 +274,7 @@ pub fn parse_module(module: &Module) -> TokenStream {
|
||||||
data: &sample.data,
|
data: &sample.data,
|
||||||
should_loop: sample.should_loop,
|
should_loop: sample.should_loop,
|
||||||
restart_point: sample.restart_point,
|
restart_point: sample.restart_point,
|
||||||
|
volume: sample.volume,
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue