Skip to main content

rescale_core/fft/
window.rs

1//! Fungsi-fungsi Windowing untuk mengurangi Spectral Leakage pada FFT.
2
3use std::f32::consts::PI;
4
5#[derive(Debug, Clone, Copy, PartialEq, Eq)]
6pub enum WindowType {
7    Rectangular,
8    Hann,
9    Hamming,
10    BlackmanHarris,
11}
12
13pub struct Window;
14
15impl Window {
16    /// Menghasilkan bobot windowing untuk buffer berukuran `size`
17    pub fn generate(size: usize, window_type: WindowType) -> Vec<f32> {
18        if size == 0 {
19            return Vec::new();
20        }
21        if size == 1 {
22            return vec![1.0];
23        }
24
25        let n_minus_1 = (size - 1) as f32;
26        let mut weights = Vec::with_capacity(size);
27
28        for n in 0..size {
29            let n_f = n as f32;
30            let w = match window_type {
31                WindowType::Rectangular => 1.0,
32                WindowType::Hann => 0.5 * (1.0 - (2.0 * PI * n_f / n_minus_1).cos()),
33                WindowType::Hamming => 0.54 - 0.46 * (2.0 * PI * n_f / n_minus_1).cos(),
34                WindowType::BlackmanHarris => {
35                    let a0 = 0.35875;
36                    let a1 = 0.48829;
37                    let a2 = 0.14128;
38                    let a3 = 0.01168;
39
40                    a0 - a1 * (2.0 * PI * n_f / n_minus_1).cos()
41                        + a2 * (4.0 * PI * n_f / n_minus_1).cos()
42                        - a3 * (6.0 * PI * n_f / n_minus_1).cos()
43                }
44            };
45            weights.push(w);
46        }
47
48        weights
49    }
50
51    /// Mengaplikasikan windowing in-place ke buffer sinyal audio
52    pub fn apply(buffer: &mut [f32], window_type: WindowType) {
53        let weights = Self::generate(buffer.len(), window_type);
54        for (sample, &weight) in buffer.iter_mut().zip(weights.iter()) {
55            *sample *= weight;
56        }
57    }
58}