1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
ix!();

pub use crate::coeff::*;

pub const HALFRATE_MAX_M: usize = 6;

#[derive(Debug,Clone)]
#[repr(align(16))]
pub struct HalfRateFilterSSE {
    pub va:       A1d::<__m128>,
    pub vx0:      A1d::<__m128>,
    pub vx1:      A1d::<__m128>,
    pub vx2:      A1d::<__m128>,
    pub vy0:      A1d::<__m128>,
    pub vy1:      A1d::<__m128>,
    pub vy2:      A1d::<__m128>,
    pub oldout:   __m128,
    pub m:        usize,
    pub steep:    bool,
    pub oldout_l: f32,
    pub oldout_r: f32,
}

impl Default for HalfRateFilterSSE {
    fn default() -> Self {
        Self {
            va:       Self::scratch_zero(),
            vx0:      Self::scratch_zero(),
            vx1:      Self::scratch_zero(),
            vx2:      Self::scratch_zero(),
            vy0:      Self::scratch_zero(),
            vy1:      Self::scratch_zero(),
            vy2:      Self::scratch_zero(),
            oldout:   unsafe { z128![] },
            m:        0,
            steep:    false,
            oldout_l: 0.0,
            oldout_r: 0.0,
        }
    }
}

impl HalfRateFilterSSE {

    #[inline] pub fn scratch_zero() -> A1d::<__m128> {
        unsafe {
            A1d::<__m128>::from_elem(HALFRATE_MAX_M, z128![])
        }
    }

    pub fn new(m: usize, steep: bool) -> Self {
        assert!(!(m > HALFRATE_MAX_M));
        let mut result = Self {
            m,
            steep,
            .. Default::default()
        };
        result.load_coefficients();
        result.reset();
        result
    }
}

impl Reset for HalfRateFilterSSE {
    fn reset(&mut self) {
        unsafe {
            for i in 0..self.m {
                self.vx0[i] = z128![];
                self.vx1[i] = z128![];
                self.vx2[i] = z128![];
                self.vy0[i] = z128![];
                self.vy1[i] = z128![];
                self.vy2[i] = z128![];
            }
            self.oldout = z128![];
        }
    }
}