mirror of
https://github.com/italicsjenga/agb.git
synced 2024-12-23 08:11:33 +11:00
Implement vibrato correctly and add a small test case
This commit is contained in:
parent
431833b216
commit
d15063373d
|
@ -62,7 +62,8 @@ pub enum PatternEffect {
|
|||
Arpeggio(Num<u16, 8>, Num<u16, 8>),
|
||||
Panning(Num<i16, 4>),
|
||||
Volume(Num<i16, 8>),
|
||||
VolumeSlide(Num<i16, 8>),
|
||||
// bool = maintain vibrato?
|
||||
VolumeSlide(Num<i16, 8>, bool),
|
||||
FineVolumeSlide(Num<i16, 8>),
|
||||
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();
|
||||
|
|
|
@ -133,6 +133,8 @@ struct Waves {
|
|||
frame: usize,
|
||||
speed: usize,
|
||||
amount: Num<i32, 12>,
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 => {
|
||||
|
|
BIN
tracker/desktop-player/tests/vibrato.xm
Normal file
BIN
tracker/desktop-player/tests/vibrato.xm
Normal file
Binary file not shown.
Loading…
Reference in a new issue