Skip to main content

nice_plug_core/util/
window.rs

1//! Windowing functions, useful in conjunction with [`StftHelper`][super::StftHelper].
2
3use std::f32;
4
5/// A Blackman window function with the 'standard' coefficients.
6///
7/// <https://en.wikipedia.org/wiki/Window_function#Blackman_window>
8pub fn blackman(size: usize) -> Vec<f32> {
9    let mut window = vec![0.0; size];
10    blackman_in_place(&mut window);
11
12    window
13}
14
15/// The same as [`blackman()`], but filling an existing slice instead. asfasdf
16pub fn blackman_in_place(window: &mut [f32]) {
17    let size = window.len();
18
19    let scale_1 = (2.0 * f32::consts::PI) / (size - 1) as f32;
20    let scale_2 = scale_1 * 2.0;
21    for (i, sample) in window.iter_mut().enumerate() {
22        let cos_1 = (scale_1 * i as f32).cos();
23        let cos_2 = (scale_2 * i as f32).cos();
24        *sample = 0.42 - (0.5 * cos_1) + (0.08 * cos_2);
25    }
26}
27
28/// A Hann window function.
29///
30/// <https://en.wikipedia.org/wiki/Hann_function>
31pub fn hann(size: usize) -> Vec<f32> {
32    let mut window = vec![0.0; size];
33    hann_in_place(&mut window);
34
35    window
36}
37
38/// The same as [`hann()`], but filling an existing slice instead.
39pub fn hann_in_place(window: &mut [f32]) {
40    let size = window.len();
41
42    // We want to scale `[0, size - 1]` to `[0, pi]`.
43    // XXX: The `sin^2()` version results in weird rounding errors that cause spectral leakage
44    let scale = (size as f32 - 1.0).recip() * f32::consts::TAU;
45    for (i, sample) in window.iter_mut().enumerate() {
46        let cos = (i as f32 * scale).cos();
47        *sample = 0.5 - (0.5 * cos)
48    }
49}
50
51/// Multiply a buffer with a window function.
52#[inline]
53pub fn multiply_with_window(buffer: &mut [f32], window_function: &[f32]) {
54    // TODO: ALso use SIMD here if available
55    for (sample, window_sample) in buffer.iter_mut().zip(window_function) {
56        *sample *= window_sample;
57    }
58}