1use crate::filtering::{biquad_cascade_df1_f32, fir_f32, BiquadCascadeInstanceF32, FirInstanceF32};
4use crate::matrix::{
5 mat_add_f32, mat_mult_f32, mat_scale_f32, mat_sub_f32, mat_trans_f32, MatrixInstance,
6 MatrixInstanceMut,
7};
8
9#[derive(Debug, Clone)]
11#[cfg_attr(feature = "defmt", derive(defmt::Format))]
12pub struct FirFilter<const TAPS: usize> {
13 pub coeffs: [f32; TAPS],
14 state: [f32; TAPS],
15}
16
17impl<const TAPS: usize> FirFilter<TAPS> {
18 pub fn new(coeffs: [f32; TAPS]) -> Self {
20 Self {
21 coeffs,
22 state: [0.0; TAPS],
23 }
24 }
25
26 pub fn process(&mut self, src: &[f32], dst: &mut [f32]) {
28 let mut instance = FirInstanceF32 {
29 num_taps: TAPS as u16,
30 coeffs: &self.coeffs,
31 state: &mut self.state,
32 };
33 fir_f32(&mut instance, src, dst);
34 }
35
36 pub fn reset(&mut self) {
38 self.state.fill(0.0);
39 }
40}
41
42#[derive(Debug, Clone)]
44#[cfg_attr(feature = "defmt", derive(defmt::Format))]
45pub struct BiquadCascade<const COEFFS_LEN: usize, const STATE_LEN: usize> {
46 pub coeffs: [f32; COEFFS_LEN],
47 pub state: [f32; STATE_LEN],
48 num_stages: u8,
49}
50
51impl<const COEFFS_LEN: usize, const STATE_LEN: usize> BiquadCascade<COEFFS_LEN, STATE_LEN> {
52 pub fn new(coeffs: [f32; COEFFS_LEN]) -> Self {
54 let num_stages = (COEFFS_LEN / 5) as u8;
55 Self {
56 coeffs,
57 state: [0.0; STATE_LEN],
58 num_stages,
59 }
60 }
61
62 pub fn process(&mut self, src: &[f32], dst: &mut [f32]) {
64 let mut instance = BiquadCascadeInstanceF32 {
65 num_stages: self.num_stages,
66 coeffs: &self.coeffs,
67 state: &mut self.state,
68 };
69 biquad_cascade_df1_f32(&mut instance, src, dst);
70 }
71
72 pub fn reset(&mut self) {
74 self.state.fill(0.0);
75 }
76}
77
78#[derive(Debug, Clone, Copy, PartialEq)]
80#[cfg_attr(feature = "defmt", derive(defmt::Format))]
81pub struct Matrix<const R: usize, const C: usize, const N: usize> {
82 pub data: [f32; N],
83}
84
85impl<const R: usize, const C: usize, const N: usize> Matrix<R, C, N> {
86 pub const fn new(data: [f32; N]) -> Self {
88 Self { data }
89 }
90
91 pub fn zeros() -> Self {
93 Self { data: [0.0; N] }
94 }
95
96 pub fn add(&self, rhs: &Self) -> Self {
98 let mut out = Self::zeros();
99 let a_inst = MatrixInstance::new(R as u16, C as u16, &self.data);
100 let b_inst = MatrixInstance::new(R as u16, C as u16, &rhs.data);
101 let mut out_inst = MatrixInstanceMut::new(R as u16, C as u16, &mut out.data);
102 mat_add_f32(&a_inst, &b_inst, &mut out_inst);
103 out
104 }
105
106 pub fn sub(&self, rhs: &Self) -> Self {
108 let mut out = Self::zeros();
109 let a_inst = MatrixInstance::new(R as u16, C as u16, &self.data);
110 let b_inst = MatrixInstance::new(R as u16, C as u16, &rhs.data);
111 let mut out_inst = MatrixInstanceMut::new(R as u16, C as u16, &mut out.data);
112 mat_sub_f32(&a_inst, &b_inst, &mut out_inst);
113 out
114 }
115
116 pub fn scale(&self, scale: f32) -> Self {
118 let mut out = Self::zeros();
119 let a_inst = MatrixInstance::new(R as u16, C as u16, &self.data);
120 let mut out_inst = MatrixInstanceMut::new(R as u16, C as u16, &mut out.data);
121 mat_scale_f32(&a_inst, scale, &mut out_inst);
122 out
123 }
124
125 pub fn transpose(&self) -> Matrix<C, R, N> {
127 let mut out = Matrix::<C, R, N>::zeros();
128 let a_inst = MatrixInstance::new(R as u16, C as u16, &self.data);
129 let mut out_inst = MatrixInstanceMut::new(C as u16, R as u16, &mut out.data);
130 mat_trans_f32(&a_inst, &mut out_inst);
131 out
132 }
133
134 pub fn mul_mat<const C2: usize, const N2: usize, const N_OUT: usize>(
136 &self,
137 rhs: &Matrix<C, C2, N2>,
138 ) -> Matrix<R, C2, N_OUT> {
139 let mut out = Matrix::<R, C2, N_OUT>::zeros();
140 let a_inst = MatrixInstance::new(R as u16, C as u16, &self.data);
141 let b_inst = MatrixInstance::new(C as u16, C2 as u16, &rhs.data);
142 let mut out_inst = MatrixInstanceMut::new(R as u16, C2 as u16, &mut out.data);
143 mat_mult_f32(&a_inst, &b_inst, &mut out_inst);
144 out
145 }
146}