use crate::effect::EffectPlugin;
use core::default::Default;
#[derive(Clone, Default)]
pub struct Arpeggio {
offset1: f32,
offset2: f32,
}
#[derive(Clone, Default)]
pub struct EffectArpeggio {
data: Arpeggio,
use_ft2_lut: bool,
tempo: usize,
tick: u8,
in_progress: bool,
}
impl EffectArpeggio {
pub fn new(use_ft2_lut: bool, tempo: usize) -> Self {
Self {
use_ft2_lut,
tempo,
..Default::default()
}
}
pub fn set_tempo(&mut self, tempo: usize) {
self.tempo = tempo;
}
fn ft2_arpeggio_index(tick: u8, tempo: usize) -> u8 {
if tempo == 0 {
return 0;
}
let tick = tick as usize % tempo;
if tick == 0 {
return 0;
}
let reverse_tick = (tempo - tick) as u8;
match reverse_tick {
0..=15 => reverse_tick % 3,
51 | 54 | 60 | 63 | 72 | 78 | 81 | 93 | 99 | 105 | 108 | 111 | 114 | 117 | 120
| 123 | 126 | 129 | 132 | 135 | 138 | 141 | 144 | 147 | 150 | 153 | 156 | 159 | 165
| 168 | 171 | 174 | 177 | 180 | 183 | 186 | 189 | 192 | 195 | 198 | 201 | 204 | 207
| 210 | 216 | 219 | 222 | 225 | 228 | 231 | 234 | 237 | 240 | 243 => 0,
_ => 2,
}
}
}
impl EffectPlugin for EffectArpeggio {
fn tick0(&mut self, param1: f32, param2: f32) -> f32 {
self.data.offset1 = param1;
self.data.offset2 = param2;
self.retrigger()
}
fn tick(&mut self) -> f32 {
self.in_progress = true;
self.tick += 1;
self.value()
}
fn in_progress(&self) -> bool {
self.in_progress
}
fn retrigger(&mut self) -> f32 {
self.tick = 0;
self.in_progress = false;
self.value()
}
fn value(&self) -> f32 {
let idx = if self.use_ft2_lut {
Self::ft2_arpeggio_index(self.tick, self.tempo)
} else {
self.tick % 3
};
match idx {
1 => self.data.offset1,
2 => self.data.offset2,
_ => 0.0,
}
}
}