1pub struct TwiddleFactors {
20 pub a :Vec<f32>,
21 pub b :Vec<f32>,
22 pub c :Vec<f32>,
23}
24
25pub struct CachedBlocksizeDerived {
26 pub twiddle_factors : TwiddleFactors,
27 pub window_slope : Vec<f32>,
28 pub bitrev : Vec<u32>,
29}
30
31impl CachedBlocksizeDerived {
32 pub fn from_blocksize(bs :u8) -> Self {
33 CachedBlocksizeDerived {
34 window_slope : generate_window((1 << (bs as u16)) >> 1),
35 twiddle_factors : compute_twiddle_factors(bs),
36 bitrev : compute_bitreverse(bs),
37 }
38 }
39}
40
41fn win_slope(x :u16, n :u16) -> f32 {
42 let v = (0.5 * std::f32::consts::PI * (x as f32 + 0.5) / n as f32).sin();
51 return (0.5 * std::f32::consts::PI * v * v ).sin();
52}
53
54fn generate_window(n :u16) -> Vec<f32> {
55 let mut window = Vec::with_capacity(n as usize);
56 for i in 0 .. n {
57 window.push(win_slope(i, n));
58 }
59 return window;
60}
61
62fn compute_twiddle_factors(blocksize :u8) -> TwiddleFactors {
63 let n = 1 << (blocksize as u16);
64
65 let n2 = n >> 1;
66 let n4 = n >> 2;
67 let n8 = n >> 3;
68
69 let mut a = Vec::with_capacity(n2);
70 let mut b = Vec::with_capacity(n2);
71 let mut c = Vec::with_capacity(n4);
72
73 let mut k2 = 0;
74
75 let pi_4_n = 4.0 * std::f32::consts::PI / (n as f32);
76 let pi_05_n = 0.5 * std::f32::consts::PI / (n as f32);
77 let pi_2_n = 2.0 * std::f32::consts::PI / (n as f32);
78
79 for k in 0..n4 {
80 a.push( f32::cos((k as f32) * pi_4_n));
81 a.push(-f32::sin((k as f32) * pi_4_n));
82 b.push( f32::cos(((k2+1) as f32) * pi_05_n) * 0.5);
83 b.push( f32::sin(((k2+1) as f32) * pi_05_n) * 0.5);
84 k2 += 2;
85 }
86 k2 = 0;
87 for _ in 0..n8 {
88 c.push( f32::cos(((k2 + 1) as f32) * pi_2_n));
89 c.push(-f32::sin(((k2 + 1) as f32) * pi_2_n));
90 k2 += 2;
91 }
92 return TwiddleFactors {
93 a,
94 b,
95 c,
96 };
97}
98
99fn compute_bitreverse(blocksize :u8) -> Vec<u32> {
100 let ld = blocksize as u16;
101 let n = 1 << blocksize;
102 let n8 = n >> 3;
103 let mut rev = Vec::with_capacity(n8);
104 for i in 0 .. n8 {
105 rev.push((::bit_reverse(i as u32) as u32 >> (32 - ld + 3)) << 2);
106 }
107 return rev;
108}
109
110#[test]
111fn test_compute_bitreverse() {
112 let br = compute_bitreverse(8);
113 let cmp_arr = &[
116 0, 64, 32, 96,
117 16, 80, 48, 112,
118 8, 72, 40, 104,
119 24, 88, 56, 120,
120 4, 68, 36, 100,
121 20, 84, 52, 116,
122 12, 76, 44, 108,
123 28, 92, 60, 124];
124 assert_eq!(br, cmp_arr);
125}
126
127#[inline]
128fn bark(x :f32) -> f32 {
129 13.1 * (0.00074 * x).atan() + 2.24 * (0.0000000185*x*x).atan() + 0.0001 * x
130}
131
132pub fn compute_bark_map_cos_omega(n :u16, floor0_rate :u16,
141 floor0_bark_map_size :u16) -> Vec<f32> {
142 let mut res = Vec::with_capacity(n as usize);
143 let hfl = floor0_rate as f32 / 2.0;
144 let hfl_dn = hfl / n as f32;
145 let foobar_const_part = floor0_bark_map_size as f32 / bark(hfl);
146 let bms_m1 = floor0_bark_map_size as f32 - 1.0;
148 let omega_factor = std::f32::consts::PI / floor0_bark_map_size as f32;
149 for i in 0 .. n {
150 let foobar = (bark(i as f32 * hfl_dn) * foobar_const_part).floor();
151 let map_elem = foobar.min(bms_m1);
152 let cos_omega = (map_elem * omega_factor).cos();
153 res.push(cos_omega);
154 }
155 return res;
156}