mirror of
https://github.com/italicsjenga/agb.git
synced 2024-12-23 08:11:33 +11:00
Fix slides and add the portamento one
This commit is contained in:
parent
0911ca44c5
commit
f6a05178db
|
@ -50,6 +50,8 @@ pub enum PatternEffect {
|
||||||
VolumeSlide(Num<i16, 4>),
|
VolumeSlide(Num<i16, 4>),
|
||||||
NoteCut(u32),
|
NoteCut(u32),
|
||||||
Portamento(Num<u16, 8>),
|
Portamento(Num<u16, 8>),
|
||||||
|
/// Slide each tick the first amount to at most the second amount
|
||||||
|
TonePortamento(Num<u16, 8>, Num<u16, 8>),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "quote")]
|
#[cfg(feature = "quote")]
|
||||||
|
@ -208,6 +210,11 @@ 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::TonePortamento(amount, target) => {
|
||||||
|
let amount = amount.to_raw();
|
||||||
|
let target = target.to_raw();
|
||||||
|
quote! { TonePortamento(agb_tracker::__private::Num::from_raw(#amount), agb_tracker::__private::Num::from_raw(#target))}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
tokens.append_all(quote! {
|
tokens.append_all(quote! {
|
||||||
|
|
|
@ -124,7 +124,7 @@ impl Tracker {
|
||||||
tick: 0,
|
tick: 0,
|
||||||
|
|
||||||
current_row: 0,
|
current_row: 0,
|
||||||
current_pattern: 2,
|
current_pattern: 6,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -278,13 +278,19 @@ impl TrackerChannel {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
PatternEffect::Portamento(amount) => {
|
PatternEffect::Portamento(amount) => {
|
||||||
let mut new_speed = self.base_speed;
|
if tick != 0 {
|
||||||
|
self.base_speed *= amount.change_base();
|
||||||
for _ in 0..tick {
|
channel.playback(self.base_speed);
|
||||||
new_speed *= amount.change_base();
|
}
|
||||||
|
}
|
||||||
|
PatternEffect::TonePortamento(amount, target) => {
|
||||||
|
if *amount < 1.into() {
|
||||||
|
self.base_speed =
|
||||||
|
(self.base_speed * amount.change_base()).max(target.change_base());
|
||||||
|
} else {
|
||||||
|
self.base_speed =
|
||||||
|
(self.base_speed * amount.change_base()).min(target.change_base());
|
||||||
}
|
}
|
||||||
|
|
||||||
channel.playback(new_speed);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -137,6 +137,7 @@ pub fn parse_module(module: &Module) -> TokenStream {
|
||||||
|
|
||||||
let mut effect1 = PatternEffect::None;
|
let mut effect1 = PatternEffect::None;
|
||||||
|
|
||||||
|
let previous_note_and_sample = note_and_sample[channel_number];
|
||||||
let maybe_note_and_sample = if matches!(slot.note, Note::KeyOff) {
|
let maybe_note_and_sample = if matches!(slot.note, Note::KeyOff) {
|
||||||
effect1 = PatternEffect::Stop;
|
effect1 = PatternEffect::Stop;
|
||||||
note_and_sample[channel_number] = None;
|
note_and_sample[channel_number] = None;
|
||||||
|
@ -234,6 +235,40 @@ pub fn parse_module(module: &Module) -> TokenStream {
|
||||||
|
|
||||||
PatternEffect::Portamento(portamento_amount.try_change_base().unwrap())
|
PatternEffect::Portamento(portamento_amount.try_change_base().unwrap())
|
||||||
}
|
}
|
||||||
|
0x3 => {
|
||||||
|
if let Some((previous_note, sample)) = previous_note_and_sample {
|
||||||
|
// we want to pitch slide to at most the current note by the parameter amount
|
||||||
|
let c4_speed = note_to_speed(Note::C4, 0.0, 0, module.frequency_type);
|
||||||
|
|
||||||
|
let direction = if (previous_note as usize) < slot.note as usize {
|
||||||
|
-1.0
|
||||||
|
} else {
|
||||||
|
1.0
|
||||||
|
};
|
||||||
|
let speed = note_to_speed(
|
||||||
|
Note::C4,
|
||||||
|
effect_parameter as f64 * direction,
|
||||||
|
0,
|
||||||
|
module.frequency_type,
|
||||||
|
);
|
||||||
|
|
||||||
|
let portamento_amount = speed / c4_speed;
|
||||||
|
|
||||||
|
let target_speed = note_to_speed(
|
||||||
|
slot.note,
|
||||||
|
sample.fine_tune,
|
||||||
|
sample.relative_note,
|
||||||
|
module.frequency_type,
|
||||||
|
);
|
||||||
|
|
||||||
|
PatternEffect::TonePortamento(
|
||||||
|
portamento_amount.try_change_base().unwrap(),
|
||||||
|
target_speed.try_change_base().unwrap(),
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
PatternEffect::None
|
||||||
|
}
|
||||||
|
}
|
||||||
0x8 => {
|
0x8 => {
|
||||||
PatternEffect::Panning(Num::new(slot.effect_parameter as i16 - 128) / 128)
|
PatternEffect::Panning(Num::new(slot.effect_parameter as i16 - 128) / 128)
|
||||||
}
|
}
|
||||||
|
@ -356,7 +391,9 @@ fn note_to_frequency_linear(note: Note, fine_tune: f64, relative_note: i8) -> f6
|
||||||
}
|
}
|
||||||
|
|
||||||
fn note_to_frequency_amega(note: Note, fine_tune: f64, relative_note: i8) -> f64 {
|
fn note_to_frequency_amega(note: Note, fine_tune: f64, relative_note: i8) -> f64 {
|
||||||
let note = (note as usize) + relative_note as usize;
|
let note = (note as usize)
|
||||||
|
.checked_add_signed(relative_note as isize)
|
||||||
|
.expect("Note gone negative");
|
||||||
let pos = (note % 12) * 8 + (fine_tune / 16.0) as usize;
|
let pos = (note % 12) * 8 + (fine_tune / 16.0) as usize;
|
||||||
let frac = (fine_tune / 16.0) - (fine_tune / 16.0).floor();
|
let frac = (fine_tune / 16.0) - (fine_tune / 16.0).floor();
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue