diff --git a/tracker/agb-tracker-interop/src/lib.rs b/tracker/agb-tracker-interop/src/lib.rs index 17429fef..9ed051d9 100644 --- a/tracker/agb-tracker-interop/src/lib.rs +++ b/tracker/agb-tracker-interop/src/lib.rs @@ -62,7 +62,8 @@ pub enum PatternEffect { Arpeggio(Num, Num), Panning(Num), Volume(Num), - VolumeSlide(Num), + // bool = maintain vibrato? + VolumeSlide(Num, bool), FineVolumeSlide(Num), NoteCut(u32), NoteDelay(u32), @@ -298,9 +299,9 @@ impl quote::ToTokens for PatternEffect { let volume = volume.to_raw(); quote! { Volume(agb_tracker::__private::Num::from_raw(#volume))} } - PatternEffect::VolumeSlide(amount) => { + PatternEffect::VolumeSlide(amount, vibrato) => { let amount = amount.to_raw(); - quote! { VolumeSlide(agb_tracker::__private::Num::from_raw(#amount))} + quote! { VolumeSlide(agb_tracker::__private::Num::from_raw(#amount), #vibrato)} } PatternEffect::FineVolumeSlide(amount) => { let amount = amount.to_raw(); diff --git a/tracker/agb-tracker/src/lib.rs b/tracker/agb-tracker/src/lib.rs index 968ab14e..3a8639f2 100644 --- a/tracker/agb-tracker/src/lib.rs +++ b/tracker/agb-tracker/src/lib.rs @@ -133,6 +133,8 @@ struct Waves { frame: usize, speed: usize, amount: Num, + + enable: bool, } impl Waves { @@ -254,6 +256,8 @@ impl<'track, TChannelId> TrackerInner<'track, TChannelId> { channel.set_speed(pattern_slot.speed.change_base()); } + channel.vibrato.enable = false; + channel.apply_effect( &pattern_slot.effect1, self.tick, @@ -282,7 +286,7 @@ impl<'track, TChannelId> TrackerInner<'track, TChannelId> { { let mut current_speed = tracker_channel.current_speed; - if tracker_channel.vibrato.speed != 0 { + if tracker_channel.vibrato.speed != 0 && tracker_channel.vibrato.enable { current_speed *= tracker_channel.vibrato.value().change_base(); } @@ -419,13 +423,15 @@ impl TrackerChannel { self.volume = volume.change_base(); } - PatternEffect::VolumeSlide(amount) => { + PatternEffect::VolumeSlide(amount, keep_vibrato) => { if tick != 0 { self.volume = (self.volume + amount.change_base()).max(0.into()); self.current_volume = (self.volume * global_settings.volume) .try_change_base() .unwrap(); } + + self.vibrato.enable = *keep_vibrato; } PatternEffect::FineVolumeSlide(amount) => { if tick == 0 { @@ -506,9 +512,16 @@ impl TrackerChannel { (global_settings.volume + *volume_delta).clamp(0.into(), 1.into()); } PatternEffect::Vibrato(waveform, amount, speed) => { + if *amount != 0.into() { + self.vibrato.amount = amount.change_base(); + } + + if *speed != 0 { + self.vibrato.speed = *speed as usize; + } + self.vibrato.waveform = *waveform; - self.vibrato.amount = amount.change_base(); - self.vibrato.speed = *speed as usize; + self.vibrato.enable = true; } } } diff --git a/tracker/agb-xm-core/src/lib.rs b/tracker/agb-xm-core/src/lib.rs index f63088ad..a895c3a8 100644 --- a/tracker/agb-xm-core/src/lib.rs +++ b/tracker/agb-xm-core/src/lib.rs @@ -147,12 +147,14 @@ pub fn parse_module(module: &Module) -> agb_tracker_interop::Track { .map(|note_and_sample| note_and_sample.1.volume) .unwrap_or(1.into()), ), - 0x60..=0x6F => { - PatternEffect::VolumeSlide(-Num::new((slot.volume - 0x60) as i16) / 64) - } - 0x70..=0x7F => { - PatternEffect::VolumeSlide(Num::new((slot.volume - 0x70) as i16) / 64) - } + 0x60..=0x6F => PatternEffect::VolumeSlide( + -Num::new((slot.volume - 0x60) as i16) / 64, + false, + ), + 0x70..=0x7F => PatternEffect::VolumeSlide( + Num::new((slot.volume - 0x70) as i16) / 64, + false, + ), 0x80..=0x8F => PatternEffect::FineVolumeSlide( -Num::new((slot.volume - 0x80) as i16) / 128, ), @@ -283,7 +285,7 @@ pub fn parse_module(module: &Module) -> agb_tracker_interop::Track { let c4_speed = note_to_speed(Note::C4, 0.0, 0, module.frequency_type); let speed = - note_to_speed(Note::C4, depth as f64 * 8.0, 0, module.frequency_type); + note_to_speed(Note::C4, depth as f64 * 16.0, 0, module.frequency_type); let amount = speed / c4_speed - 1; @@ -301,9 +303,15 @@ pub fn parse_module(module: &Module) -> agb_tracker_interop::Track { let second = effect_parameter & 0xF; if first == 0 { - PatternEffect::VolumeSlide(-Num::new(second as i16) / 64) + PatternEffect::VolumeSlide( + -Num::new(second as i16) / 64, + slot.effect_type == 0x6, + ) } else { - PatternEffect::VolumeSlide(Num::new(first as i16) / 64) + PatternEffect::VolumeSlide( + Num::new(first as i16) / 64, + slot.effect_type == 0x6, + ) } } 0xC => { diff --git a/tracker/desktop-player/tests/vibrato.xm b/tracker/desktop-player/tests/vibrato.xm new file mode 100644 index 00000000..ea20a923 Binary files /dev/null and b/tracker/desktop-player/tests/vibrato.xm differ