ten-vad-rs 0.1.7

Rust library for working with the TEN VAD ONNX model.
Documentation
const AGORA_UAP_BIQUAD_MAX_SECTION: usize = 20;

pub const ANTI_ALIAS_SECTIONS: usize = 5;
pub const AUP_PE_B_4KHZ: [[f32; 3]; ANTI_ALIAS_SECTIONS] = [
    [1.0, 1.198825, 1.0],
    [1.0, -0.567461, 1.0],
    [1.0, -1.099061, 1.0],
    [1.0, -1.265846, 1.0],
    [1.0, -1.318849, 1.0],
];
pub const AUP_PE_A_4KHZ: [[f32; 3]; ANTI_ALIAS_SECTIONS] = [
    [1.0, -1.445267, 0.5463974],
    [1.0, -1.426720, 0.6820138],
    [1.0, -1.408255, 0.8286664],
    [1.0, -1.400909, 0.9240320],
    [1.0, -1.408242, 0.9789776],
];
pub const AUP_PE_G_4KHZ: [f32; ANTI_ALIAS_SECTIONS] =
    [0.2692541, 0.2692541, 0.2692541, 0.2692541, 0.2692541];

#[derive(Clone, Debug)]
pub struct BiquadFilter {
    nsect: usize,
    b_coeff: [[f32; 3]; AGORA_UAP_BIQUAD_MAX_SECTION],
    a_coeff: [[f32; 3]; AGORA_UAP_BIQUAD_MAX_SECTION],
    g_coeff: [f32; AGORA_UAP_BIQUAD_MAX_SECTION],
    sect_w: [[f32; 2]; AGORA_UAP_BIQUAD_MAX_SECTION],
}

impl BiquadFilter {
    pub fn new(b: &[[f32; 3]], a: &[[f32; 3]], g: &[f32]) -> Self {
        assert_eq!(b.len(), a.len());
        assert_eq!(b.len(), g.len());
        assert!(b.len() <= AGORA_UAP_BIQUAD_MAX_SECTION);

        let nsect = b.len();
        let mut filter = Self {
            nsect,
            b_coeff: [[0.0; 3]; AGORA_UAP_BIQUAD_MAX_SECTION],
            a_coeff: [[0.0; 3]; AGORA_UAP_BIQUAD_MAX_SECTION],
            g_coeff: [0.0; AGORA_UAP_BIQUAD_MAX_SECTION],
            sect_w: [[0.0; 2]; AGORA_UAP_BIQUAD_MAX_SECTION],
        };

        filter.b_coeff[..nsect].copy_from_slice(&b[..nsect]);
        filter.a_coeff[..nsect].copy_from_slice(&a[..nsect]);
        filter.g_coeff[..nsect].copy_from_slice(&g[..nsect]);
        filter
    }

    pub fn process(&mut self, input: &[f32], output: &mut [f32]) {
        assert_eq!(input.len(), output.len());
        output.copy_from_slice(input);

        for sect in 0..self.nsect {
            let b = self.b_coeff[sect];
            let a = self.a_coeff[sect];
            let g = self.g_coeff[sect];
            let mut w1 = self.sect_w[sect][0];
            let mut w2 = self.sect_w[sect][1];

            for y in output.iter_mut() {
                let x = *y;
                let w0 = x - a[1] * w1 - a[2] * w2;
                let out = g * (b[0] * w0 + b[1] * w1 + b[2] * w2);
                w2 = w1;
                w1 = w0;
                *y = out;
            }

            self.sect_w[sect][0] = w1;
            self.sect_w[sect][1] = w2;
        }
    }

    pub fn reset(&mut self) {
        for state in &mut self.sect_w {
            *state = [0.0; 2];
        }
    }
}