use super::types::FxDelayTimeOnTheGrid;
use crate::{
error::{ConversionError, ParameterError, RytmError},
util::{i8_to_u8_midpoint_of_u8_input_range, u8_to_i8_midpoint_of_u8_input_range},
};
use rytm_rs_macro::parameter_range;
use rytm_sys::ar_kit_t;
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
pub struct FxDelay {
time: u8,
ping_pong: bool,
stereo_width: i8,
feedback: u8,
hpf: u8,
lpf: u8,
reverb_send: u8,
volume: u8,
}
impl Default for FxDelay {
fn default() -> Self {
Self {
time: 23,
ping_pong: false,
stereo_width: 0,
feedback: 49,
hpf: 32,
lpf: 96,
reverb_send: 0,
volume: 110,
}
}
}
impl TryFrom<&ar_kit_t> for FxDelay {
type Error = ConversionError;
fn try_from(raw_kit: &ar_kit_t) -> Result<Self, Self::Error> {
let feedback = (raw_kit.fx_delay_feedback as f32 / 127.0 * 198.0) as u8;
Ok(Self {
time: raw_kit.fx_delay_time,
ping_pong: raw_kit.fx_delay_pingpong != 0,
stereo_width: u8_to_i8_midpoint_of_u8_input_range(
raw_kit.fx_delay_stereo_width,
0,
127,
),
feedback,
hpf: raw_kit.fx_delay_hpf,
lpf: raw_kit.fx_delay_lpf,
reverb_send: raw_kit.fx_delay_reverb_send,
volume: raw_kit.fx_delay_volume,
})
}
}
impl FxDelay {
pub(crate) fn apply_to_raw_kit(self, raw_kit: &mut ar_kit_t) {
let feedback = (self.feedback as f32 / 198.0 * 127.0) as u8;
raw_kit.fx_delay_time = self.time;
raw_kit.fx_delay_pingpong = self.ping_pong as u8;
raw_kit.fx_delay_stereo_width =
i8_to_u8_midpoint_of_u8_input_range(self.stereo_width, 0, 127);
raw_kit.fx_delay_feedback = feedback;
raw_kit.fx_delay_hpf = self.hpf;
raw_kit.fx_delay_lpf = self.lpf;
raw_kit.fx_delay_reverb_send = self.reverb_send;
raw_kit.fx_delay_volume = self.volume;
}
#[parameter_range(range = "time:0..=127")]
pub fn set_time(&mut self, time: usize) -> Result<(), RytmError> {
self.time = time as u8;
Ok(())
}
pub fn set_time_on_grid(&mut self, time: FxDelayTimeOnTheGrid) {
self.time = time.into();
}
pub fn set_ping_pong(&mut self, enable: bool) {
self.ping_pong = enable;
}
#[parameter_range(range = "stereo_width:-64..=63")]
pub fn set_stereo_width(&mut self, stereo_width: isize) -> Result<(), RytmError> {
self.stereo_width = stereo_width as i8;
Ok(())
}
#[parameter_range(range = "feedback:0..=198")]
pub fn set_feedback(&mut self, feedback: usize) -> Result<(), RytmError> {
self.feedback = feedback as u8;
Ok(())
}
#[parameter_range(range = "hpf:0..=127")]
pub fn set_hpf(&mut self, hpf: usize) -> Result<(), RytmError> {
self.hpf = hpf as u8;
Ok(())
}
#[parameter_range(range = "lpf:0..=127")]
pub fn set_lpf(&mut self, lpf: usize) -> Result<(), RytmError> {
self.lpf = lpf as u8;
Ok(())
}
#[parameter_range(range = "reverb_send:0..=127")]
pub fn set_reverb_send(&mut self, reverb_send: usize) -> Result<(), RytmError> {
self.reverb_send = reverb_send as u8;
Ok(())
}
#[parameter_range(range = "volume:0..=127")]
pub fn set_volume(&mut self, volume: usize) -> Result<(), RytmError> {
self.volume = volume as u8;
Ok(())
}
pub const fn time(&self) -> usize {
self.time as usize
}
pub const fn ping_pong(&self) -> bool {
self.ping_pong
}
pub const fn stereo_width(&self) -> isize {
self.stereo_width as isize
}
pub const fn feedback(&self) -> usize {
self.feedback as usize
}
pub const fn hpf(&self) -> usize {
self.hpf as usize
}
pub const fn lpf(&self) -> usize {
self.lpf as usize
}
pub const fn reverb_send(&self) -> usize {
self.reverb_send as usize
}
pub const fn volume(&self) -> usize {
self.volume as usize
}
}