wav-dwt 0.2.1

An experimental implementation of the A Trous Wavelet Decomposition algorithms for audio instead of images
Documentation
use convolve_nd::exports::ndarray::Array1;

use crate::aggregate::Aggregate;
use crate::decompose::WaveletDecompose;
use crate::kernels::Kernel;
use crate::layer::{WaveletLayer, WaveletLayerBuffer};

#[derive(Copy, Clone)]
pub struct Scale {
    min: f32,
    #[allow(unused)]
    max: f32,
    scaling_ratio: f32,
}

impl Scale {
    pub fn new(min: f32, max: f32) -> Self {
        Self {
            min,
            max,
            scaling_ratio: max - min,
        }
    }

    #[inline]
    pub fn apply(&self, value: f32) -> f32 {
        (value - self.min) / self.scaling_ratio
    }
}

#[derive(Clone)]
struct ATrousTransformInput {
    data: Array1<f32>,
}

impl Aggregate for ATrousTransformInput {
    fn min(&self) -> f32 {
        self.data.min()
    }

    fn max(&self) -> f32 {
        self.data.max()
    }
}

#[derive(Clone)]
pub struct ATrousTransform {
    input: ATrousTransformInput,
    levels: usize,
    kernel: Kernel,
    current_level: usize,
}

impl ATrousTransform {
    pub fn new(input: Vec<f32>, levels: usize, kernel: Kernel) -> Self {
        let data = input.into();

        Self {
            input: ATrousTransformInput { data },
            levels,
            kernel,
            current_level: 0,
        }
    }

    pub fn linear(input: Vec<f32>, levels: usize) -> Self {
        ATrousTransform::new(input, levels, Kernel::LinearInterpolationKernel)
    }

    pub fn low_scale(input: Vec<f32>, levels: usize) -> Self {
        ATrousTransform::new(input, levels, Kernel::LowScaleKernel)
    }

    pub fn b_spline(input: Vec<f32>, levels: usize) -> Self {
        ATrousTransform::new(input, levels, Kernel::B3SplineKernel)
    }
}

impl Iterator for ATrousTransform {
    type Item = WaveletLayer;

    fn next(&mut self) -> Option<Self::Item> {
        let pixel_scale = self.current_level;
        self.current_level += 1;

        if pixel_scale > self.levels {
            return None;
        }

        if pixel_scale == self.levels {
            return Some(WaveletLayer {
                buffer: WaveletLayerBuffer {
                    data: self.input.data.clone(),
                },
                pixel_scale: None,
            });
        }

        let kernel = self.kernel;

        let layer_buffer = self.input.data.wavelet_decompose(kernel, pixel_scale);
        Some(WaveletLayer {
            pixel_scale: Some(pixel_scale),
            buffer: layer_buffer,
        })
    }
}