use crate::building_blocks::{
Modulator, MonoEffect, SampleBuffer, SynthParameterLabel, SynthParameterValue,
};
pub struct Waveshaper<const BUFSIZE: usize> {
mix: f32,
}
impl<const BUFSIZE: usize> Waveshaper<BUFSIZE> {
pub fn new() -> Self {
Waveshaper { mix: 0.0 }
}
}
impl<const BUFSIZE: usize> Default for Waveshaper<BUFSIZE> {
fn default() -> Self {
Self::new()
}
}
impl<const BUFSIZE: usize> MonoEffect<BUFSIZE> for Waveshaper<BUFSIZE> {
fn set_modulator(&mut self, _: SynthParameterLabel, _: f32, _: Modulator<BUFSIZE>) {}
fn set_parameter(&mut self, label: SynthParameterLabel, value: &SynthParameterValue) {
if let SynthParameterLabel::WaveshaperMix = label
&& let SynthParameterValue::ScalarF32(val) = value
{
self.mix = *val;
}
}
fn finish(&mut self) {} fn is_finished(&self) -> bool {
false
}
fn process_block(
&mut self,
block: [f32; BUFSIZE],
_: usize,
_: &[SampleBuffer],
) -> [f32; BUFSIZE] {
if self.mix == 0.0 {
block
} else {
let mut out_block = [0.0; BUFSIZE];
for (i, x) in block.iter().enumerate() {
let y = if *x > 1.0 {
1.0
} else if *x < -1.0 {
-1.0
} else {
1.5 * x - 0.5 * x * x * x
};
out_block[i] = ((1.0 - self.mix) * x) + (self.mix * y);
}
out_block
}
}
}