microdsp 0.1.3

DSP algorithms and utilities. Performant, embedded friendly and no_std compatible.
Documentation
use crate::common::WindowFunctionType;
use crate::common::WindowProcessor;
use crate::sfnov::{
    compression_function::{CompressionFunction, HardKneeCompression},
    spectral_flux::SpectralFlux,
};

pub struct SpectralFluxNoveltyDetector<C: CompressionFunction> {
    window_processor: WindowProcessor,
    flux: SpectralFlux,
    window_func: WindowFunctionType,
    compression_func: C,
}

impl SpectralFluxNoveltyDetector<HardKneeCompression> {
    pub fn new(window_size: usize) -> Self {
        SpectralFluxNoveltyDetector {
            window_processor: WindowProcessor::new(1, window_size, window_size / 2),
            window_func: WindowFunctionType::Hann,
            compression_func: HardKneeCompression::new(),
            flux: SpectralFlux::new(window_size),
        }
    }
}

impl<C: CompressionFunction> SpectralFluxNoveltyDetector<C> {
    pub fn from_options(
        window_func: WindowFunctionType,
        compression_func: C,
        downsampled_window_size: usize,
        downsampling: usize,
        downsampled_hop_size: usize,
    ) -> Self {
        SpectralFluxNoveltyDetector {
            window_processor: WindowProcessor::new(
                downsampled_window_size,
                downsampled_hop_size,
                downsampling,
            ),
            window_func,
            compression_func,
            flux: SpectralFlux::new(downsampled_window_size),
        }
    }

    pub fn compression_function(&mut self) -> &C {
        &mut self.compression_func
    }

    pub fn reset(&mut self) {
        self.window_processor.reset();
        self.flux.clear()
    }

    pub fn novelty(&self) -> &SpectralFlux {
        &self.flux
    }

    pub fn process<F>(&mut self, buffer: &[f32], mut handler: F)
    where
        F: FnMut(&SpectralFlux),
    {
        let flux = &mut self.flux;
        let window_func = self.window_func;
        let compression_func = &self.compression_func;
        self.window_processor.process(buffer, |window| {
            if flux.process_window(window, window_func, compression_func) {
                handler(&flux)
            }
        })
    }
}