/*
 Taken from Till's magic Arduino Sketch
*/
pub trait ZTransformFilter {
    fn process(&mut self, sample: f32) -> f32;
}

// 20 - 200Hz Single Pole Bandpass IIR Filter
#[derive(Default)]
pub struct BassFilter {
    xv: [f32; 3],
    yv: [f32; 3],
}

impl ZTransformFilter for BassFilter {
    fn process(&mut self, sample: f32) -> f32 {
        self.xv[0] = self.xv[1];
        self.xv[1] = self.xv[2];
        self.xv[2] = sample / 3.0f32;

        self.yv[0] = self.yv[1];
        self.yv[1] = self.yv[2];
        self.yv[2] = (self.xv[2] - self.xv[0])
            + (-0.7960060012f32 * self.yv[0])
            + (1.7903124146f32 * self.yv[1]);

        self.yv[2]
    }
}

// 10Hz Single Pole Lowpass IIR Filter
#[derive(Default)]
pub struct EnvelopeFilter {
    xv: [f32; 2],
    yv: [f32; 2],
}

impl ZTransformFilter for EnvelopeFilter {
    fn process(&mut self, sample: f32) -> f32 {
        self.xv[0] = self.xv[1];
        self.xv[1] = sample / 50.0f32;

        self.yv[0] = self.yv[1];
        self.yv[1] = (self.xv[0] + self.xv[1]) + (0.9875119299f32 * self.yv[0]);

        self.yv[1]
    }
}

// 1.7 - 3.0Hz Single Pole Bandpass IIR Filter
#[derive(Default)]
pub struct BeatFilter {
    xv: [f32; 3],
    yv: [f32; 3],
}

impl ZTransformFilter for BeatFilter {
    fn process(&mut self, sample: f32) -> f32 {
        self.xv[0] = self.xv[1];
        self.xv[1] = self.xv[2];
        self.xv[2] = sample / 2.7f32;

        self.yv[0] = self.yv[1];
        self.yv[1] = self.yv[2];
        self.yv[2] = (self.xv[2] - self.xv[0])
            + (-0.7169861741f32 * self.yv[0])
            + (1.4453653501f32 * self.yv[1]);

        self.yv[2]
    }
}
