]>
Commit | Line | Data |
---|---|---|
1 | //! Window generating functions. | |
2 | use std::f32::consts; | |
3 | ||
4 | /// Known window types. | |
5 | #[derive(Debug,Clone,Copy,PartialEq)] | |
6 | pub enum WindowType { | |
7 | /// Simple square window. | |
8 | Square, | |
9 | /// Simple sine window. | |
10 | Sine, | |
11 | /// Kaiser-Bessel derived window. | |
12 | KaiserBessel(f32), | |
13 | } | |
14 | ||
15 | /// Calculates window coefficients for the requested window type and size. | |
16 | /// | |
17 | /// Set `half` flag to calculate only the first half of the window. | |
18 | pub fn generate_window(mode: WindowType, scale: f32, size: usize, half: bool, dst: &mut [f32]) { | |
19 | match mode { | |
20 | WindowType::Square => { | |
21 | for n in 0..size { dst[n] = scale; } | |
22 | }, | |
23 | WindowType::Sine => { | |
24 | let param = if half { | |
25 | consts::PI / ((2 * size) as f32) | |
26 | } else { | |
27 | consts::PI / (size as f32) | |
28 | }; | |
29 | for n in 0..size { | |
30 | dst[n] = (((n as f32) + 0.5) * param).sin() * scale; | |
31 | } | |
32 | }, | |
33 | WindowType::KaiserBessel(alpha) => { | |
34 | let dlen = if half { size as f32 } else { (size as f32) * 0.5 }; | |
35 | let alpha2 = f64::from((alpha * consts::PI / dlen) * (alpha * consts::PI / dlen)); | |
36 | ||
37 | let mut kb: Vec<f64> = Vec::with_capacity(size); | |
38 | let mut sum = 0.0; | |
39 | for n in 0..size { | |
40 | let b = bessel_i0(((n * (size - n)) as f64) * alpha2); | |
41 | sum += b; | |
42 | kb.push(sum); | |
43 | } | |
44 | sum += 1.0; | |
45 | for n in 0..size { | |
46 | dst[n] = (kb[n] / sum).sqrt() as f32; | |
47 | } | |
48 | }, | |
49 | }; | |
50 | } | |
51 | ||
52 | fn bessel_i0(inval: f64) -> f64 { | |
53 | let mut val: f64 = 1.0; | |
54 | for n in (1..64).rev() { | |
55 | val *= inval / f64::from(n * n); | |
56 | val += 1.0; | |
57 | } | |
58 | val | |
59 | } |