saturation 0.2.3

Real-time saturation and clipping designed for use with vst's
Documentation
use core::{marker::PhantomData, ops::Range};
use alloc::alloc::{Allocator, Global};

use real_time_fir_iir_filters::param::FilterFloat;

use crate::CacheTable;

use super::{calc::PentodeCalc, PentodeClassA, PentodeModel};

#[derive(Debug, Copy, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
struct PentodeCacheFunc<F, M>
where
    F: FilterFloat,
    M: PentodeModel
{
    param: PentodeClassA<F>,
    marker: PhantomData<M>
}
impl<F, M> FnOnce<(F,)> for PentodeCacheFunc<F, M>
where
    F: FilterFloat,
    M: PentodeModel
{
    type Output = [F; 2];

    extern "rust-call" fn call_once(mut self, (vg,): (F,)) -> Self::Output
    {
        PentodeCalc::<F, M>::vp_a(&mut self.param, vg)
    }
}
impl<F, M> FnMut<(F,)> for PentodeCacheFunc<F, M>
where
    F: FilterFloat,
    M: PentodeModel
{
    extern "rust-call" fn call_mut(&mut self, (vg,): (F,)) -> Self::Output
    {
        PentodeCalc::<F, M>::vp_a(&mut self.param, vg)
    }
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct PentodeCache<F, M, A = Global>
where
    F: FilterFloat,
    M: PentodeModel,
    A: Allocator + Clone
{
    cache: CacheTable<F, 2, PentodeCacheFunc<F, M>, A>
}
impl<F, M> PentodeCache<F, M>
where
    F: FilterFloat,
    M: PentodeModel
{
    pub fn new(param: PentodeClassA<F>, range: Range<F>, resolution: usize) -> Self
    {
        Self::new_in(param, range, resolution, Global)
    }
}
impl<F, M, A> PentodeCache<F, M, A>
where
    F: FilterFloat,
    M: PentodeModel,
    A: Allocator + Clone
{
    pub fn new_in(param: PentodeClassA<F>, range: Range<F>, resolution: usize, alloc: A) -> Self
    {
        Self {
            cache: CacheTable::new_in(
                PentodeCacheFunc {
                    param,
                    marker: PhantomData
                },
                range,
                resolution,
                alloc
            )
        }
    }
}
impl<F, M, A> PentodeCalc<F, M> for PentodeCache<F, M, A>
where
    F: FilterFloat,
    M: PentodeModel,
    A: Allocator + Clone
{
    fn param(&self) -> &PentodeClassA<F>
    {
        &self.cache.func().param
    }
    fn param_mut(&mut self) -> &mut PentodeClassA<F>
    {
        &mut self.cache.func_mut().param
    }
    fn vp_a(&mut self, vg: F) -> [F; 2]
    {
        self.cache.saturate(vg)
    }
}