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

View file

@ -462,6 +462,12 @@ impl TrackerChannel {
self.current_speed = self.base_speed.change_base(); 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) => { PatternEffect::TonePortamento(amount, target) => {
self.current_volume = (self.volume * global_settings.volume) self.current_volume = (self.volume * global_settings.volume)
.try_change_base() .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 { 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( 0xA => PatternEffect::FineVolumeSlide(
Num::new((slot.effect_parameter & 0xf) as i16) / 128, 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()), 0xC => PatternEffect::NoteCut((slot.effect_parameter & 0xf).into()),
0xD => PatternEffect::NoteDelay((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 { 0xF => match slot.effect_parameter {
0 => PatternEffect::SetTicksPerStep(u32::MAX), 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::GlobalVolumeSlide(Num::new(first as i32) / 0x40)
} }
} }
_ => PatternEffect::None, e => {
eprintln!("Unsupported effect {e:X}xy");
PatternEffect::None
}
}; };
if sample == 0 if sample == 0