mirror of
https://github.com/italicsjenga/agb.git
synced 2024-12-23 08:11:33 +11:00
Add vibrato
This commit is contained in:
parent
f6e7625bb1
commit
31ca8f631f
|
@ -69,6 +69,7 @@ pub enum PatternEffect {
|
|||
Portamento(Num<u16, 12>),
|
||||
/// Slide each tick the first amount to at most the second amount
|
||||
TonePortamento(Num<u16, 12>, Num<u16, 12>),
|
||||
Vibrato(Waveform, Num<u16, 12>, u8),
|
||||
SetTicksPerStep(u32),
|
||||
SetFramesPerTick(Num<u32, 8>),
|
||||
SetGlobalVolume(Num<i32, 8>),
|
||||
|
@ -77,7 +78,7 @@ pub enum PatternEffect {
|
|||
PitchBend(Num<u32, 8>),
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, Clone, PartialEq, Eq)]
|
||||
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq)]
|
||||
pub enum Waveform {
|
||||
#[default]
|
||||
Sine,
|
||||
|
@ -334,6 +335,10 @@ impl quote::ToTokens for PatternEffect {
|
|||
let amount = amount.to_raw();
|
||||
quote! { PitchBend(agb_tracker::__private::Num::from_raw(#amount)) }
|
||||
}
|
||||
PatternEffect::Vibrato(waveform, amount, speed) => {
|
||||
let amount = amount.to_raw();
|
||||
quote! { Vibrato(#waveform, #amount, #speed) }
|
||||
}
|
||||
};
|
||||
|
||||
tokens.append_all(quote! {
|
||||
|
|
|
@ -5,17 +5,17 @@ use std::fs;
|
|||
use std::path::Path;
|
||||
|
||||
fn main() {
|
||||
let sine = (0..64).map(|i| (Num::<i32, 8>::new(i) / 64).sin());
|
||||
let sine = (0..64).map(|i| (Num::<i32, 12>::new(i) / 64).sin());
|
||||
|
||||
let square = (0..64).map(|i| {
|
||||
if i < 32 {
|
||||
Num::<i32, 8>::new(-1)
|
||||
Num::<i32, 12>::new(-1)
|
||||
} else {
|
||||
Num::<i32, 8>::new(1)
|
||||
Num::<i32, 12>::new(1)
|
||||
}
|
||||
});
|
||||
|
||||
let saw = (0..64).map(|i| (Num::<i32, 8>::new(i) - 32) / 32);
|
||||
let saw = (0..64).map(|i| (Num::<i32, 12>::new(i) - 32) / 32);
|
||||
|
||||
let out_dir = env::var_os("OUT_DIR").unwrap();
|
||||
let dest_path = Path::new(&out_dir).join("lookups.rs");
|
||||
|
@ -24,9 +24,9 @@ fn main() {
|
|||
&dest_path,
|
||||
format!(
|
||||
"
|
||||
pub(crate) static SINE_LOOKUP: [agb_fixnum::Num<i32, 8>; 64] = [{sine_lookup}];
|
||||
pub(crate) static SQUARE_LOOKUP: [agb_fixnum::Num<i32, 8>; 64] = [{square_lookup}];
|
||||
pub(crate) static SAW_LOOKUP: [agb_fixnum::Num<i32, 8>; 64] = [{saw_lookup}];
|
||||
pub(crate) static SINE_LOOKUP: [agb_fixnum::Num<i32, 12>; 64] = [{sine_lookup}];
|
||||
pub(crate) static SQUARE_LOOKUP: [agb_fixnum::Num<i32, 12>; 64] = [{square_lookup}];
|
||||
pub(crate) static SAW_LOOKUP: [agb_fixnum::Num<i32, 12>; 64] = [{saw_lookup}];
|
||||
",
|
||||
sine_lookup = gen_lookup(sine),
|
||||
square_lookup = gen_lookup(square),
|
||||
|
@ -38,7 +38,7 @@ fn main() {
|
|||
println!("cargo::rerun-if-changed=build.rs");
|
||||
}
|
||||
|
||||
fn gen_lookup(input: impl IntoIterator<Item = Num<i32, 8>>) -> String {
|
||||
fn gen_lookup(input: impl IntoIterator<Item = Num<i32, 12>>) -> String {
|
||||
let output: Vec<_> = input
|
||||
.into_iter()
|
||||
.map(|v| format!("agb_fixnum::Num::from_raw({})", v.to_raw()))
|
||||
|
|
|
@ -132,7 +132,7 @@ struct Waves {
|
|||
waveform: Waveform,
|
||||
frame: usize,
|
||||
speed: usize,
|
||||
amount: Num<i32, 8>,
|
||||
amount: Num<i32, 12>,
|
||||
}
|
||||
|
||||
impl Waves {
|
||||
|
@ -281,6 +281,7 @@ impl<'track, TChannelId> TrackerInner<'track, TChannelId> {
|
|||
.and_then(|channel_id| mixer.channel(channel_id))
|
||||
{
|
||||
let mut current_speed = tracker_channel.current_speed;
|
||||
|
||||
if tracker_channel.vibrato.speed != 0 {
|
||||
current_speed *= tracker_channel.vibrato.value().change_base();
|
||||
}
|
||||
|
@ -498,6 +499,11 @@ impl TrackerChannel {
|
|||
global_settings.volume =
|
||||
(global_settings.volume + *volume_delta).clamp(0.into(), 1.into());
|
||||
}
|
||||
PatternEffect::Vibrato(waveform, amount, speed) => {
|
||||
self.vibrato.waveform = *waveform;
|
||||
self.vibrato.amount = amount.change_base();
|
||||
self.vibrato.speed = *speed as usize;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use std::collections::HashMap;
|
||||
|
||||
use agb_fixnum::Num;
|
||||
use agb_tracker_interop::PatternEffect;
|
||||
use agb_tracker_interop::{PatternEffect, Waveform};
|
||||
|
||||
use xmrs::prelude::*;
|
||||
|
||||
|
@ -277,6 +277,22 @@ pub fn parse_module(module: &Module) -> agb_tracker_interop::Track {
|
|||
PatternEffect::None
|
||||
}
|
||||
}
|
||||
0x4 => {
|
||||
let vibrato_speed = effect_parameter >> 4;
|
||||
let depth = effect_parameter & 0xF;
|
||||
|
||||
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);
|
||||
|
||||
let amount = speed / c4_speed - 1;
|
||||
|
||||
PatternEffect::Vibrato(
|
||||
Waveform::Sine,
|
||||
amount.try_change_base().unwrap(),
|
||||
vibrato_speed,
|
||||
)
|
||||
}
|
||||
0x8 => {
|
||||
PatternEffect::Panning(Num::new(slot.effect_parameter as i16 - 128) / 128)
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue