Skip to main content

embedded_dsp/
window.rs

1//! Window functions (Hanning, Hamming, Blackman, Blackman-Harris, Bartlett, Welch, Flat-top window generators).
2
3#[allow(unused_imports)]
4use crate::math::FloatMath;
5
6/// Generate Hanning window of length `n`.
7pub fn hanning_f32(dst: &mut [f32]) {
8    let n = dst.len();
9    if n == 0 {
10        return;
11    }
12    if n == 1 {
13        dst[0] = 1.0;
14        return;
15    }
16    let factor = 2.0 * core::f32::consts::PI / ((n - 1) as f32);
17    for i in 0..n {
18        dst[i] = 0.5 * (1.0 - ((i as f32) * factor).cos());
19    }
20}
21
22/// Generate Hamming window of length `n`.
23pub fn hamming_f32(dst: &mut [f32]) {
24    let n = dst.len();
25    if n == 0 {
26        return;
27    }
28    if n == 1 {
29        dst[0] = 1.0;
30        return;
31    }
32    let factor = 2.0 * core::f32::consts::PI / ((n - 1) as f32);
33    for i in 0..n {
34        dst[i] = 0.54 - 0.46 * ((i as f32) * factor).cos();
35    }
36}
37
38/// Generate Blackman window of length `n`.
39pub fn blackman_f32(dst: &mut [f32]) {
40    let n = dst.len();
41    if n == 0 {
42        return;
43    }
44    if n == 1 {
45        dst[0] = 1.0;
46        return;
47    }
48    let factor = 2.0 * core::f32::consts::PI / ((n - 1) as f32);
49    for i in 0..n {
50        let a = (i as f32) * factor;
51        dst[i] = 0.42 - 0.5 * a.cos() + 0.08 * (2.0 * a).cos();
52    }
53}
54
55/// Generate 4-term Blackman-Harris window of length `n` (>92 dB sidelobe rejection).
56pub fn blackman_harris_f32(dst: &mut [f32]) {
57    let n = dst.len();
58    if n == 0 {
59        return;
60    }
61    if n == 1 {
62        dst[0] = 1.0;
63        return;
64    }
65    let factor = 2.0 * core::f32::consts::PI / ((n - 1) as f32);
66    for i in 0..n {
67        let a = (i as f32) * factor;
68        dst[i] =
69            0.35875 - 0.48829 * a.cos() + 0.14128 * (2.0 * a).cos() - 0.01168 * (3.0 * a).cos();
70    }
71}
72
73/// Generate Bartlett (Triangular) window of length `n`.
74pub fn bartlett_f32(dst: &mut [f32]) {
75    let n = dst.len();
76    if n == 0 {
77        return;
78    }
79    if n == 1 {
80        dst[0] = 1.0;
81        return;
82    }
83    let half = ((n - 1) as f32) / 2.0;
84    for i in 0..n {
85        dst[i] = 1.0 - ((i as f32 - half) / half).abs();
86    }
87}
88
89/// Generate Welch parabolic window of length `n`.
90pub fn welch_f32(dst: &mut [f32]) {
91    let n = dst.len();
92    if n == 0 {
93        return;
94    }
95    if n == 1 {
96        dst[0] = 1.0;
97        return;
98    }
99    let half = ((n - 1) as f32) / 2.0;
100    for i in 0..n {
101        let term = (i as f32 - half) / half;
102        dst[i] = 1.0 - term * term;
103    }
104}
105
106/// Generate Flat-top window of length `n`.
107pub fn flattop_f32(dst: &mut [f32]) {
108    let n = dst.len();
109    if n == 0 {
110        return;
111    }
112    if n == 1 {
113        dst[0] = 1.0;
114        return;
115    }
116    let factor = 2.0 * core::f32::consts::PI / ((n - 1) as f32);
117    for i in 0..n {
118        let a = (i as f32) * factor;
119        dst[i] = 0.21557895 - 0.41663158 * a.cos() + 0.277_263_16 * (2.0 * a).cos()
120            - 0.08357895 * (3.0 * a).cos()
121            + 0.006947368 * (4.0 * a).cos();
122    }
123}
124
125/// Multiply signal elements in-place by window array.
126pub fn apply_window_f32(signal: &mut [f32], window: &[f32]) {
127    let len = signal.len().min(window.len());
128    for i in 0..len {
129        signal[i] *= window[i];
130    }
131}