1use crate::filtering::{
4 BiquadCascadeInstanceF32, BiquadCascadeInstanceQ15, FirInstanceF32, FirInstanceQ15,
5 biquad_cascade_df1_f32, biquad_cascade_df1_q15, fir_f32, fir_q15,
6};
7use crate::matrix::{
8 MatrixInstance, MatrixInstanceMut, mat_add_f32, mat_mult_f32, mat_scale_f32, mat_sub_f32,
9 mat_trans_f32,
10};
11use crate::types::q15;
12
13#[derive(Debug, Clone)]
15#[cfg_attr(feature = "defmt", derive(defmt::Format))]
16pub struct FirFilter<const TAPS: usize> {
17 pub coeffs: [f32; TAPS],
18 state: [f32; TAPS],
19}
20
21impl<const TAPS: usize> FirFilter<TAPS> {
22 pub fn new(coeffs: [f32; TAPS]) -> Self {
24 Self {
25 coeffs,
26 state: [0.0; TAPS],
27 }
28 }
29
30 pub fn process(&mut self, src: &[f32], dst: &mut [f32]) {
32 let mut instance = FirInstanceF32 {
33 num_taps: TAPS as u16,
34 coeffs: &self.coeffs,
35 state: &mut self.state,
36 };
37 fir_f32(&mut instance, src, dst);
38 }
39
40 pub fn reset(&mut self) {
42 self.state.fill(0.0);
43 }
44}
45
46#[derive(Debug, Clone)]
48#[cfg_attr(feature = "defmt", derive(defmt::Format))]
49pub struct BiquadCascade<const COEFFS_LEN: usize, const STATE_LEN: usize> {
50 pub coeffs: [f32; COEFFS_LEN],
51 pub state: [f32; STATE_LEN],
52 num_stages: u8,
53}
54
55impl<const COEFFS_LEN: usize, const STATE_LEN: usize> BiquadCascade<COEFFS_LEN, STATE_LEN> {
56 pub fn new(coeffs: [f32; COEFFS_LEN]) -> Self {
58 let num_stages = (COEFFS_LEN / 5) as u8;
59 Self {
60 coeffs,
61 state: [0.0; STATE_LEN],
62 num_stages,
63 }
64 }
65
66 pub fn process(&mut self, src: &[f32], dst: &mut [f32]) {
68 let mut instance = BiquadCascadeInstanceF32 {
69 num_stages: self.num_stages,
70 coeffs: &self.coeffs,
71 state: &mut self.state,
72 };
73 biquad_cascade_df1_f32(&mut instance, src, dst);
74 }
75
76 pub fn reset(&mut self) {
78 self.state.fill(0.0);
79 }
80}
81
82#[derive(Debug, Clone)]
84#[cfg_attr(feature = "defmt", derive(defmt::Format))]
85pub struct FirFilterQ15<const TAPS: usize> {
86 pub coeffs: [q15; TAPS],
87 state: [q15; TAPS],
88}
89
90impl<const TAPS: usize> FirFilterQ15<TAPS> {
91 pub fn new(coeffs: [q15; TAPS]) -> Self {
92 Self {
93 coeffs,
94 state: [q15::ZERO; TAPS],
95 }
96 }
97
98 pub fn process(&mut self, src: &[q15], dst: &mut [q15]) {
99 let mut instance = FirInstanceQ15 {
100 num_taps: TAPS as u16,
101 coeffs: &self.coeffs,
102 state: &mut self.state,
103 };
104 fir_q15(&mut instance, src, dst);
105 }
106
107 pub fn reset(&mut self) {
108 self.state.fill(q15::ZERO);
109 }
110}
111
112#[derive(Debug, Clone)]
114#[cfg_attr(feature = "defmt", derive(defmt::Format))]
115pub struct BiquadCascadeQ15<const COEFFS_LEN: usize, const STATE_LEN: usize> {
116 pub coeffs: [q15; COEFFS_LEN],
117 pub state: [q15; STATE_LEN],
118 num_stages: u8,
119 post_shift: u8,
120}
121
122impl<const COEFFS_LEN: usize, const STATE_LEN: usize> BiquadCascadeQ15<COEFFS_LEN, STATE_LEN> {
123 pub fn new(coeffs: [q15; COEFFS_LEN], post_shift: u8) -> Self {
124 let num_stages = (COEFFS_LEN / 5) as u8;
125 Self {
126 coeffs,
127 state: [q15::ZERO; STATE_LEN],
128 num_stages,
129 post_shift,
130 }
131 }
132
133 pub fn process(&mut self, src: &[q15], dst: &mut [q15]) {
134 let mut instance = BiquadCascadeInstanceQ15 {
135 num_stages: self.num_stages,
136 post_shift: self.post_shift,
137 coeffs: &self.coeffs,
138 state: &mut self.state,
139 };
140 biquad_cascade_df1_q15(&mut instance, src, dst);
141 }
142
143 pub fn reset(&mut self) {
144 self.state.fill(q15::ZERO);
145 }
146}
147
148#[derive(Debug, Clone, Copy, PartialEq)]
150#[cfg_attr(feature = "defmt", derive(defmt::Format))]
151pub struct Matrix<const R: usize, const C: usize, const N: usize> {
152 pub data: [f32; N],
153}
154
155impl<const R: usize, const C: usize, const N: usize> Matrix<R, C, N> {
156 pub const fn new(data: [f32; N]) -> Self {
158 Self { data }
159 }
160
161 pub fn zeros() -> Self {
163 Self { data: [0.0; N] }
164 }
165
166 pub fn add(&self, rhs: &Self) -> Self {
168 let mut out = Self::zeros();
169 let a_inst = MatrixInstance::new(R as u16, C as u16, &self.data);
170 let b_inst = MatrixInstance::new(R as u16, C as u16, &rhs.data);
171 let mut out_inst = MatrixInstanceMut::new(R as u16, C as u16, &mut out.data);
172 mat_add_f32(&a_inst, &b_inst, &mut out_inst);
173 out
174 }
175
176 pub fn sub(&self, rhs: &Self) -> Self {
178 let mut out = Self::zeros();
179 let a_inst = MatrixInstance::new(R as u16, C as u16, &self.data);
180 let b_inst = MatrixInstance::new(R as u16, C as u16, &rhs.data);
181 let mut out_inst = MatrixInstanceMut::new(R as u16, C as u16, &mut out.data);
182 mat_sub_f32(&a_inst, &b_inst, &mut out_inst);
183 out
184 }
185
186 pub fn scale(&self, scale: f32) -> Self {
188 let mut out = Self::zeros();
189 let a_inst = MatrixInstance::new(R as u16, C as u16, &self.data);
190 let mut out_inst = MatrixInstanceMut::new(R as u16, C as u16, &mut out.data);
191 mat_scale_f32(&a_inst, scale, &mut out_inst);
192 out
193 }
194
195 pub fn transpose(&self) -> Matrix<C, R, N> {
197 let mut out = Matrix::<C, R, N>::zeros();
198 let a_inst = MatrixInstance::new(R as u16, C as u16, &self.data);
199 let mut out_inst = MatrixInstanceMut::new(C as u16, R as u16, &mut out.data);
200 mat_trans_f32(&a_inst, &mut out_inst);
201 out
202 }
203
204 pub fn mul_mat<const C2: usize, const N2: usize, const N_OUT: usize>(
206 &self,
207 rhs: &Matrix<C, C2, N2>,
208 ) -> Matrix<R, C2, N_OUT> {
209 let mut out = Matrix::<R, C2, N_OUT>::zeros();
210 let a_inst = MatrixInstance::new(R as u16, C as u16, &self.data);
211 let b_inst = MatrixInstance::new(C as u16, C2 as u16, &rhs.data);
212 let mut out_inst = MatrixInstanceMut::new(R as u16, C2 as u16, &mut out.data);
213 mat_mult_f32(&a_inst, &b_inst, &mut out_inst);
214 out
215 }
216}