rill-core-wdf 0.3.1

Wave Digital Filter core — elements, adapters, and analysis for analog circuit modeling
Documentation
#[macro_export]
macro_rules! wdf_cascade {
    (
        name: $name:ident<T>,
        section: $section:ty,
        count: $count:expr,
        params: { $($pname:ident: $ptype:ty),* },
        state: { $($sname:ident: $stype:ty),* },
        feedback: |$f_self:ident, $f_in:ident, $f_out:ident| $feedback:tt,
        update: |$u_self:ident| $update:tt,
    ) => {
        #[derive(Debug, Clone)]
        pub struct $name<T: $crate::Transcendental> {
            pub poles: [$section; $count],
            $($pname: $ptype,)*
            $($sname: $stype,)*
        }

        impl<T: $crate::Transcendental> $name<T> {
            pub fn new(section: $section, $($pname: $ptype),*) -> Self {
                Self {
                    poles: [section; $count],
                    $($pname,)*
                    $($sname: T::ZERO,)*
                }
            }

            pub fn update_coeffs(&mut self) { let $u_self = self; $update }

            pub fn process_sample(&mut self, input: T) -> T {
                let a0 = {
                    let $f_self = &self;
                    let $f_in = input;
                    let $f_out = $f_self.feedback_prev;
                    $feedback
                };
                let mut a = a0;
                a = $crate::WdfElement::process_incident(&mut self.poles[0], a);
                a = $crate::WdfElement::process_incident(&mut self.poles[1], a);
                a = $crate::WdfElement::process_incident(&mut self.poles[2], a);
                a = $crate::WdfElement::process_incident(&mut self.poles[3], a);
                self.feedback_prev = a;
                a
            }

            pub fn cutoff(&self) -> T { self.cutoff }
            pub fn set_cutoff(&mut self, cutoff: T) {
                let half_sr = self.sample_rate / T::from_f32(2.0);
                self.cutoff = cutoff.clamp(T::from_f32(20.0), half_sr);
                self.update_coeffs();
            }
            pub fn resonance(&self) -> T { self.resonance }
            pub fn set_resonance(&mut self, resonance: T) {
                self.resonance = resonance.clamp(T::ZERO, T::ONE);
            }
            pub fn set_sample_rate(&mut self, sample_rate: T) {
                self.sample_rate = sample_rate;
                self.update_coeffs();
            }

            pub fn reset(&mut self) {
                for p in &mut self.poles { $crate::WdfElement::reset(p); }
                self.feedback_prev = T::ZERO;
            }
        }
    };
}