use core::f32::consts::PI;
#[allow(unused_imports)]
use num_traits::real::Real;
use crate::utils::linspace;
#[derive(Clone, Copy)]
pub enum Window {
Hann,
}
pub fn get_window<const N: usize>(win: Window, sym: bool) -> [f32; N]
where
[(); N + 1]: Sized,
{
use Window::*;
match win {
Hann => {
let alpha = 0.5;
let a = [alpha, 1. - alpha];
let mut w = [0.0; N];
(0..a.len()).for_each(|i| {
if sym {
let fac = linspace::<N>(-PI, PI);
w.iter_mut().zip(fac).for_each(|(iw, f)| {
*iw += a[i] * (i as f32 * f).cos();
});
} else {
let fac = linspace::<{ N + 1 }>(-PI, PI);
w.iter_mut().zip(fac).for_each(|(iw, f)| {
*iw += a[i] * (i as f32 * f).cos();
});
};
});
w
}
}
}
#[cfg(test)]
mod test {
use core::ops;
use num_traits::ToPrimitive;
use super::*;
fn all_close<T, const N: usize>(a: &[T; N], b: &[T; N]) -> bool
where
T: ops::Sub<Output = T> + ToPrimitive + Copy,
{
const EPSILON: f32 = 1e-5;
for i in 0..N {
if (a[i] - b[i]).to_f32().unwrap() > EPSILON {
return false;
}
}
true
}
#[test]
#[allow(clippy::excessive_precision)]
fn test_window_hann() {
assert!(all_close(
&get_window(Window::Hann, true),
&[0., 0.75, 0.75, 0.]
));
assert!(all_close(
&get_window(Window::Hann, false),
&[0., 0.5, 1., 0.5]
));
}
}