1#[allow(unused_imports)]
4use crate::math::FloatMath;
5use crate::types::q15;
6
7#[inline]
8fn q15_from_unit(v: f32) -> q15 {
9 (v * 32767.0).clamp(-32768.0, 32767.0) as q15
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
131pub fn apply_window_f32(signal: &mut [f32], window: &[f32]) {
133 let len = signal.len().min(window.len());
134 for i in 0..len {
135 signal[i] *= window[i];
136 }
137}
138
139fn fill_window_q15(dst: &mut [q15], fill: impl Fn(usize, usize) -> f32) {
140 let n = dst.len();
141 if n == 0 {
142 return;
143 }
144 if n == 1 {
145 dst[0] = 32767;
146 return;
147 }
148 for i in 0..n {
149 dst[i] = q15_from_unit(fill(i, n));
150 }
151}
152
153pub fn hanning_q15(dst: &mut [q15]) {
155 fill_window_q15(dst, |i, n| {
156 let factor = 2.0 * core::f32::consts::PI / ((n - 1) as f32);
157 0.5 * (1.0 - ((i as f32) * factor).cos())
158 });
159}
160
161pub fn hamming_q15(dst: &mut [q15]) {
163 fill_window_q15(dst, |i, n| {
164 let factor = 2.0 * core::f32::consts::PI / ((n - 1) as f32);
165 0.54 - 0.46 * ((i as f32) * factor).cos()
166 });
167}
168
169pub fn blackman_q15(dst: &mut [q15]) {
171 fill_window_q15(dst, |i, n| {
172 let factor = 2.0 * core::f32::consts::PI / ((n - 1) as f32);
173 let a = (i as f32) * factor;
174 0.42 - 0.5 * a.cos() + 0.08 * (2.0 * a).cos()
175 });
176}
177
178pub fn bartlett_q15(dst: &mut [q15]) {
180 fill_window_q15(dst, |i, n| {
181 let half = (n - 1) as f32 / 2.0;
182 1.0 - ((i as f32 - half) / half).abs()
183 });
184}
185
186pub fn apply_window_q15(signal: &mut [q15], window: &[q15]) {
188 let len = signal.len().min(window.len());
189 for i in 0..len {
190 signal[i] = (((signal[i] as i32) * (window[i] as i32)) >> 15) as q15;
191 }
192}