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>),
|
Arpeggio(Num<u16, 8>, Num<u16, 8>),
|
||||||
Panning(Num<i16, 4>),
|
Panning(Num<i16, 4>),
|
||||||
Volume(Num<i16, 8>),
|
Volume(Num<i16, 8>),
|
||||||
VolumeSlide(Num<i16, 8>),
|
// bool = maintain vibrato?
|
||||||
|
VolumeSlide(Num<i16, 8>, bool),
|
||||||
FineVolumeSlide(Num<i16, 8>),
|
FineVolumeSlide(Num<i16, 8>),
|
||||||
NoteCut(u32),
|
NoteCut(u32),
|
||||||
NoteDelay(u32),
|
NoteDelay(u32),
|
||||||
|
@ -298,9 +299,9 @@ impl quote::ToTokens for PatternEffect {
|
||||||
let volume = volume.to_raw();
|
let volume = volume.to_raw();
|
||||||
quote! { Volume(agb_tracker::__private::Num::from_raw(#volume))}
|
quote! { Volume(agb_tracker::__private::Num::from_raw(#volume))}
|
||||||
}
|
}
|
||||||
PatternEffect::VolumeSlide(amount) => {
|
PatternEffect::VolumeSlide(amount, vibrato) => {
|
||||||
let amount = amount.to_raw();
|
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) => {
|
PatternEffect::FineVolumeSlide(amount) => {
|
||||||
let amount = amount.to_raw();
|
let amount = amount.to_raw();
|
||||||
|
|
|
@ -133,6 +133,8 @@ struct Waves {
|
||||||
frame: usize,
|
frame: usize,
|
||||||
speed: usize,
|
speed: usize,
|
||||||
amount: Num<i32, 12>,
|
amount: Num<i32, 12>,
|
||||||
|
|
||||||
|
enable: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Waves {
|
impl Waves {
|
||||||
|
@ -254,6 +256,8 @@ impl<'track, TChannelId> TrackerInner<'track, TChannelId> {
|
||||||
channel.set_speed(pattern_slot.speed.change_base());
|
channel.set_speed(pattern_slot.speed.change_base());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
channel.vibrato.enable = false;
|
||||||
|
|
||||||
channel.apply_effect(
|
channel.apply_effect(
|
||||||
&pattern_slot.effect1,
|
&pattern_slot.effect1,
|
||||||
self.tick,
|
self.tick,
|
||||||
|
@ -282,7 +286,7 @@ impl<'track, TChannelId> TrackerInner<'track, TChannelId> {
|
||||||
{
|
{
|
||||||
let mut current_speed = tracker_channel.current_speed;
|
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();
|
current_speed *= tracker_channel.vibrato.value().change_base();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -419,13 +423,15 @@ impl TrackerChannel {
|
||||||
|
|
||||||
self.volume = volume.change_base();
|
self.volume = volume.change_base();
|
||||||
}
|
}
|
||||||
PatternEffect::VolumeSlide(amount) => {
|
PatternEffect::VolumeSlide(amount, keep_vibrato) => {
|
||||||
if tick != 0 {
|
if tick != 0 {
|
||||||
self.volume = (self.volume + amount.change_base()).max(0.into());
|
self.volume = (self.volume + amount.change_base()).max(0.into());
|
||||||
self.current_volume = (self.volume * global_settings.volume)
|
self.current_volume = (self.volume * global_settings.volume)
|
||||||
.try_change_base()
|
.try_change_base()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self.vibrato.enable = *keep_vibrato;
|
||||||
}
|
}
|
||||||
PatternEffect::FineVolumeSlide(amount) => {
|
PatternEffect::FineVolumeSlide(amount) => {
|
||||||
if tick == 0 {
|
if tick == 0 {
|
||||||
|
@ -506,10 +512,17 @@ impl TrackerChannel {
|
||||||
(global_settings.volume + *volume_delta).clamp(0.into(), 1.into());
|
(global_settings.volume + *volume_delta).clamp(0.into(), 1.into());
|
||||||
}
|
}
|
||||||
PatternEffect::Vibrato(waveform, amount, speed) => {
|
PatternEffect::Vibrato(waveform, amount, speed) => {
|
||||||
self.vibrato.waveform = *waveform;
|
if *amount != 0.into() {
|
||||||
self.vibrato.amount = amount.change_base();
|
self.vibrato.amount = amount.change_base();
|
||||||
|
}
|
||||||
|
|
||||||
|
if *speed != 0 {
|
||||||
self.vibrato.speed = *speed as usize;
|
self.vibrato.speed = *speed as usize;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self.vibrato.waveform = *waveform;
|
||||||
|
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)
|
.map(|note_and_sample| note_and_sample.1.volume)
|
||||||
.unwrap_or(1.into()),
|
.unwrap_or(1.into()),
|
||||||
),
|
),
|
||||||
0x60..=0x6F => {
|
0x60..=0x6F => PatternEffect::VolumeSlide(
|
||||||
PatternEffect::VolumeSlide(-Num::new((slot.volume - 0x60) as i16) / 64)
|
-Num::new((slot.volume - 0x60) as i16) / 64,
|
||||||
}
|
false,
|
||||||
0x70..=0x7F => {
|
),
|
||||||
PatternEffect::VolumeSlide(Num::new((slot.volume - 0x70) as i16) / 64)
|
0x70..=0x7F => PatternEffect::VolumeSlide(
|
||||||
}
|
Num::new((slot.volume - 0x70) as i16) / 64,
|
||||||
|
false,
|
||||||
|
),
|
||||||
0x80..=0x8F => PatternEffect::FineVolumeSlide(
|
0x80..=0x8F => PatternEffect::FineVolumeSlide(
|
||||||
-Num::new((slot.volume - 0x80) as i16) / 128,
|
-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 c4_speed = note_to_speed(Note::C4, 0.0, 0, module.frequency_type);
|
||||||
let speed =
|
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;
|
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;
|
let second = effect_parameter & 0xF;
|
||||||
|
|
||||||
if first == 0 {
|
if first == 0 {
|
||||||
PatternEffect::VolumeSlide(-Num::new(second as i16) / 64)
|
PatternEffect::VolumeSlide(
|
||||||
|
-Num::new(second as i16) / 64,
|
||||||
|
slot.effect_type == 0x6,
|
||||||
|
)
|
||||||
} else {
|
} else {
|
||||||
PatternEffect::VolumeSlide(Num::new(first as i16) / 64)
|
PatternEffect::VolumeSlide(
|
||||||
|
Num::new(first as i16) / 64,
|
||||||
|
slot.effect_type == 0x6,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
0xC => {
|
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