Support fine portamentos

This commit is contained in:
Gwilym Inzani 2024-07-10 12:01:19 +01:00
parent 31ca8f631f
commit c1eaae64e1
3 changed files with 54 additions and 2 deletions

View file

@ -67,6 +67,7 @@ pub enum PatternEffect {
NoteCut(u32),
NoteDelay(u32),
Portamento(Num<u16, 12>),
FinePortamento(Num<u16, 12>),
/// Slide each tick the first amount to at most the second amount
TonePortamento(Num<u16, 12>, Num<u16, 12>),
Vibrato(Waveform, Num<u16, 12>, u8),
@ -311,6 +312,10 @@ impl quote::ToTokens for PatternEffect {
let amount = amount.to_raw();
quote! { Portamento(agb_tracker::__private::Num::from_raw(#amount))}
}
PatternEffect::FinePortamento(amount) => {
let amount = amount.to_raw();
quote! { FinePortamento(agb_tracker::__private::Num::from_raw(#amount))}
}
PatternEffect::TonePortamento(amount, target) => {
let amount = amount.to_raw();
let target = target.to_raw();

View file

@ -462,6 +462,12 @@ impl TrackerChannel {
self.current_speed = self.base_speed.change_base();
}
}
PatternEffect::FinePortamento(amount) => {
if tick == 1 {
self.base_speed *= amount.change_base();
self.current_speed = self.base_speed.change_base();
}
}
PatternEffect::TonePortamento(amount, target) => {
self.current_volume = (self.volume * global_settings.volume)
.try_change_base()

View file

@ -316,6 +316,40 @@ pub fn parse_module(module: &Module) -> agb_tracker_interop::Track {
}
}
0xE => match slot.effect_parameter >> 4 {
0x1 => {
let c4_speed: Num<u32, 12> =
note_to_speed(Note::C4, 0.0, 0, module.frequency_type)
.change_base();
let speed: Num<u32, 12> = note_to_speed(
Note::C4,
effect_parameter as f64 * 8.0,
0,
module.frequency_type,
)
.change_base();
let portamento_amount = speed / c4_speed;
PatternEffect::FinePortamento(
portamento_amount.try_change_base().unwrap(),
)
}
0x2 => {
let c4_speed = note_to_speed(Note::C4, 0.0, 0, module.frequency_type);
let speed = note_to_speed(
Note::C4,
effect_parameter as f64 * 8.0,
0,
module.frequency_type,
);
let portamento_amount = c4_speed / speed;
PatternEffect::FinePortamento(
portamento_amount.try_change_base().unwrap(),
)
}
0xA => PatternEffect::FineVolumeSlide(
Num::new((slot.effect_parameter & 0xf) as i16) / 128,
),
@ -324,7 +358,10 @@ pub fn parse_module(module: &Module) -> agb_tracker_interop::Track {
),
0xC => PatternEffect::NoteCut((slot.effect_parameter & 0xf).into()),
0xD => PatternEffect::NoteDelay((slot.effect_parameter & 0xf).into()),
_ => PatternEffect::None,
u => {
eprintln!("Unsupported extended effect E{u:X}y");
PatternEffect::None
}
},
0xF => match slot.effect_parameter {
0 => PatternEffect::SetTicksPerStep(u32::MAX),
@ -348,7 +385,11 @@ pub fn parse_module(module: &Module) -> agb_tracker_interop::Track {
PatternEffect::GlobalVolumeSlide(Num::new(first as i32) / 0x40)
}
}
_ => PatternEffect::None,
e => {
eprintln!("Unsupported effect {e:X}xy");
PatternEffect::None
}
};
if sample == 0