lasprs 0.14.0

Library for Acoustic Signal Processing (Rust edition, with optional Python bindings via pyo3)
//! Contains filter implemententations for [Biquad]s, series of
//! biquads ([SeriesBiquad]) and banks of series of biquads ([BiquadBank]).
//!
//! Contains [Biquad], [SeriesBiquad], [BiquadBank] and [FIR]. These are all
//! constructs that work on blocks of input data and apply filters to it.
#![allow(non_snake_case)]
use enum_dispatch::enum_dispatch;
use std::fmt::Debug;

use crate::StrictlyPositive;

use super::config::*;
use serde::{Deserialize, Serialize};

mod adaptablefir;
mod biquad;
mod biquadbank;
mod butter;
mod dummy;
mod eq;
mod error;
mod fir;
mod octave;
mod seriesbiquad;
mod zpkmodel;

type Result<T> = std::result::Result<T, FilterError>;
pub use adaptablefir::AdaptableFIR;

pub use biquad::Biquad;
pub use biquadbank::BiquadBank;
pub use dummy::DummyFilter;
pub use eq::*;
pub use error::*;
pub use fir::FIR;
pub use octave::{FREQ_REF, G, StandardFilterDescriptor};
pub use seriesbiquad::SeriesBiquad;
pub use zpkmodel::{FilterSpec, PoleOrZero, ZPKModel};

/// Implementations of this trait are able to DSP-filter input data. The filter
/// trait is implemented by, for example, [Biquad], [SeriesBiquad], and
/// [BiquadBank].
#[enum_dispatch]
pub trait FilterMethods {
    /// Filter input to generate output. A vector of output floats is generated
    /// with the same length as the input.
    fn filter(&mut self, input: &[Flt], output: &mut [Flt]);

    /// Reset the filter state(s). In essence, this makes sure that all memory
    /// of the past is forgotten.
    fn reset(&mut self);

    /// Filter, but works on general iterators. The default implementation
    /// copies over in temporary buffers. More efficient implementations may
    /// override this.
    fn filter_iter<'a>(
        &mut self,
        input: impl Iterator<Item = &'a Flt>,
        output: impl Iterator<Item = &'a mut Flt>,
    ) {
        // Generate temporary buffer from the input iterator
        let itmp = input.copied().collect::<Vec<_>>();
        // Generate temporary buffer for output
        let mut otmp = vec![0.; itmp.len()];

        // Filter the temp. input into the temp. output buffer
        self.filter(&itmp, &mut otmp);
        // Copy over the slice to the output iterator
        for (o, v) in output.zip(otmp) {
            *o = v;
        }
    }
}

/// Filter types that transform input to output using a transfer function.
#[enum_dispatch(FilterMethods)]
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum Filter {
    /// Simple biquad variant
    Biquad(Biquad),
    /// Series of biquads
    SeriesBiquad(SeriesBiquad),
    /// No-op
    Dummy(DummyFilter),
    /// Bank of series of biquads (see [BiquadBank])
    BiquadBank(BiquadBank),
}

/// Implementations are able to generate transfer functions of itself
pub trait TransferFunction<'a, T>: Send
where
    T: AsArray<'a, Flt>,
{
    /// Compute frequency response (i.e. transfer function from input to output)
    ///
    /// # Args
    ///
    /// * `freq` - The frequency in \[Hz\]
    ///
    /// # Returns
    ///
    /// The transfer function: A column vector with the frequency response for
    /// each frequency in `freq`.
    ///
    fn tf(&self, fs: StrictlyPositive, freq: T) -> Ccol;
}