1#[allow(unused_imports)]
4use crate::math::FloatMath;
5use crate::types::q15;
6
7#[inline]
8fn q15_from_unit(v: f32) -> q15 {
9 q15::saturating_from_num(v)
10}
11
12pub fn hanning_f32(dst: &mut [f32]) {
14 let n = dst.len();
15 if n == 0 {
16 return;
17 }
18 if n == 1 {
19 dst[0] = 1.0;
20 return;
21 }
22 let factor = 2.0 * core::f32::consts::PI / ((n - 1) as f32);
23 for i in 0..n {
24 dst[i] = 0.5 * (1.0 - ((i as f32) * factor).cos());
25 }
26}
27
28pub fn hamming_f32(dst: &mut [f32]) {
30 let n = dst.len();
31 if n == 0 {
32 return;
33 }
34 if n == 1 {
35 dst[0] = 1.0;
36 return;
37 }
38 let factor = 2.0 * core::f32::consts::PI / ((n - 1) as f32);
39 for i in 0..n {
40 dst[i] = 0.54 - 0.46 * ((i as f32) * factor).cos();
41 }
42}
43
44pub fn blackman_f32(dst: &mut [f32]) {
46 let n = dst.len();
47 if n == 0 {
48 return;
49 }
50 if n == 1 {
51 dst[0] = 1.0;
52 return;
53 }
54 let factor = 2.0 * core::f32::consts::PI / ((n - 1) as f32);
55 for i in 0..n {
56 let a = (i as f32) * factor;
57 dst[i] = 0.42 - 0.5 * a.cos() + 0.08 * (2.0 * a).cos();
58 }
59}
60
61pub fn blackman_harris_f32(dst: &mut [f32]) {
63 let n = dst.len();
64 if n == 0 {
65 return;
66 }
67 if n == 1 {
68 dst[0] = 1.0;
69 return;
70 }
71 let factor = 2.0 * core::f32::consts::PI / ((n - 1) as f32);
72 for i in 0..n {
73 let a = (i as f32) * factor;
74 dst[i] =
75 0.35875 - 0.48829 * a.cos() + 0.14128 * (2.0 * a).cos() - 0.01168 * (3.0 * a).cos();
76 }
77}
78
79pub fn bartlett_f32(dst: &mut [f32]) {
81 let n = dst.len();
82 if n == 0 {
83 return;
84 }
85 if n == 1 {
86 dst[0] = 1.0;
87 return;
88 }
89 let half = ((n - 1) as f32) / 2.0;
90 for i in 0..n {
91 dst[i] = 1.0 - ((i as f32 - half) / half).abs();
92 }
93}
94
95pub fn welch_f32(dst: &mut [f32]) {
97 let n = dst.len();
98 if n == 0 {
99 return;
100 }
101 if n == 1 {
102 dst[0] = 1.0;
103 return;
104 }
105 let half = ((n - 1) as f32) / 2.0;
106 for i in 0..n {
107 let term = (i as f32 - half) / half;
108 dst[i] = 1.0 - term * term;
109 }
110}
111
112pub fn flattop_f32(dst: &mut [f32]) {
114 let n = dst.len();
115 if n == 0 {
116 return;
117 }
118 if n == 1 {
119 dst[0] = 1.0;
120 return;
121 }
122 let factor = 2.0 * core::f32::consts::PI / ((n - 1) as f32);
123 for i in 0..n {
124 let a = (i as f32) * factor;
125 dst[i] = 0.21557895 - 0.41663158 * a.cos() + 0.277_263_16 * (2.0 * a).cos()
126 - 0.08357895 * (3.0 * a).cos()
127 + 0.006947368 * (4.0 * a).cos();
128 }
129}
130
131#[inline]
133pub fn bessel_i0(x: f32) -> f32 {
134 let mut sum = 1.0f32;
135 let mut term = 1.0f32;
136 let half_x = 0.5 * x;
137 for k in 1..=16 {
138 term *= (half_x / k as f32) * (half_x / k as f32);
139 sum += term;
140 if term < 1e-7 * sum {
141 break;
142 }
143 }
144 sum
145}
146
147pub fn kaiser_f32(dst: &mut [f32], beta: f32) {
154 let n = dst.len();
155 if n == 0 {
156 return;
157 }
158 if n == 1 {
159 dst[0] = 1.0;
160 return;
161 }
162 let den = bessel_i0(beta);
163 let n_minus_1 = (n - 1) as f32;
164 for (i, val) in dst.iter_mut().enumerate() {
165 let frac = (2.0 * i as f32 / n_minus_1) - 1.0;
166 let arg = (1.0 - frac * frac).max(0.0).sqrt();
167 *val = bessel_i0(beta * arg) / den;
168 }
169}
170
171pub fn apply_window_f32(signal: &mut [f32], window: &[f32]) {
173 let len = signal.len().min(window.len());
174 for i in 0..len {
175 signal[i] *= window[i];
176 }
177}
178
179fn fill_window_q15(dst: &mut [q15], fill: impl Fn(usize, usize) -> f32) {
180 let n = dst.len();
181 if n == 0 {
182 return;
183 }
184 if n == 1 {
185 dst[0] = q15::MAX;
186 return;
187 }
188 for i in 0..n {
189 dst[i] = q15_from_unit(fill(i, n));
190 }
191}
192
193pub fn hanning_q15(dst: &mut [q15]) {
195 fill_window_q15(dst, |i, n| {
196 let factor = 2.0 * core::f32::consts::PI / ((n - 1) as f32);
197 0.5 * (1.0 - ((i as f32) * factor).cos())
198 });
199}
200
201pub fn hamming_q15(dst: &mut [q15]) {
203 fill_window_q15(dst, |i, n| {
204 let factor = 2.0 * core::f32::consts::PI / ((n - 1) as f32);
205 0.54 - 0.46 * ((i as f32) * factor).cos()
206 });
207}
208
209pub fn blackman_q15(dst: &mut [q15]) {
211 fill_window_q15(dst, |i, n| {
212 let factor = 2.0 * core::f32::consts::PI / ((n - 1) as f32);
213 let a = (i as f32) * factor;
214 0.42 - 0.5 * a.cos() + 0.08 * (2.0 * a).cos()
215 });
216}
217
218pub fn bartlett_q15(dst: &mut [q15]) {
220 fill_window_q15(dst, |i, n| {
221 let half = (n - 1) as f32 / 2.0;
222 1.0 - ((i as f32 - half) / half).abs()
223 });
224}
225
226pub fn apply_window_q15(signal: &mut [q15], window: &[q15]) {
228 let len = signal.len().min(window.len());
229 for i in 0..len {
230 signal[i] = signal[i].wrapping_mul(window[i]);
231 }
232}