1use crate::{
2 common::{complex::Scaler, config::FrameDuration},
3 tables::temporal_noise_shaping_tables::{MAXLAG, TNS_NUMFILTERS_MAX},
4};
5use core::f64::consts::PI;
6use heapless::Vec;
7#[allow(unused_imports)]
8use num_traits::real::Real;
9
10use super::side_info::Bandwidth;
11
12pub fn apply_temporal_noise_shaping(
25 duration: FrameDuration,
26 bandwidth: Bandwidth,
27 num_tns_filters: usize,
28 reflect_coef_order: &[usize],
29 reflect_coef_ints: &[usize],
30 spec_lines: &mut [Scaler],
31) {
32 let mut bands = split_into_frequency_bands(duration, bandwidth, spec_lines);
36
37 let mut rc_quant: [Scaler; TNS_NUMFILTERS_MAX * MAXLAG] = [0.0; TNS_NUMFILTERS_MAX * MAXLAG];
39 const QUANTIZER_STEPSIZE: Scaler = (PI / 17.0) as Scaler;
40
41 for (rc_q_item, rc_i_item) in rc_quant.iter_mut().zip(reflect_coef_ints) {
43 if *rc_i_item != 0 {
44 *rc_q_item = (QUANTIZER_STEPSIZE * (*rc_i_item as i32 - 8) as Scaler).sin()
45 }
46 }
47
48 let mut lattice_state = [0.0; 8];
49
50 for (f, (band, order)) in bands
52 .iter_mut()
53 .zip(reflect_coef_order[..num_tns_filters].iter())
54 .enumerate()
55 {
56 if *order > 0 {
57 let offset = f * 8;
58
59 for spectral_line in band.iter_mut() {
61 let k = *order - 1;
62 let mut t = *spectral_line - rc_quant[k + offset] * lattice_state[k];
63 for k in (0..*order - 1).rev() {
64 let rc = rc_quant[k + offset];
65 t -= rc * lattice_state[k];
66 lattice_state[k + 1] = rc * t + lattice_state[k];
67 }
68
69 *spectral_line = t;
70 lattice_state[0] = t;
71 }
72 }
73 }
74}
75
76fn split_into_frequency_bands(
84 duration: FrameDuration,
85 bandwidth: Bandwidth,
86 spec_lines: &mut [Scaler],
87) -> Vec<&mut [Scaler], 2> {
88 let mut bands: Vec<&mut [Scaler], 2> = Vec::new();
89 match duration {
90 FrameDuration::TenMs => match bandwidth {
91 Bandwidth::NarrowBand => {
92 bands.push(&mut spec_lines[12..80]).ok();
93 }
94 Bandwidth::WideBand => {
95 bands.push(&mut spec_lines[12..160]).ok();
96 }
97 Bandwidth::SemiSuperWideBand => {
98 bands.push(&mut spec_lines[12..240]).ok();
99 }
100 Bandwidth::SuperWideBand => {
101 let (left, right) = spec_lines.split_at_mut(160);
103 bands.push(&mut left[12..]).ok();
104 bands.push(&mut right[..160]).ok();
105 }
106 Bandwidth::FullBand => {
107 let (left, right) = spec_lines.split_at_mut(200);
109 bands.push(&mut left[12..]).ok();
110 bands.push(&mut right[..200]).ok();
111 }
112 },
113 FrameDuration::SevenPointFiveMs => match bandwidth {
114 Bandwidth::NarrowBand => {
115 bands.push(&mut spec_lines[9..60]).ok();
116 }
117 Bandwidth::WideBand => {
118 bands.push(&mut spec_lines[9..120]).ok();
119 }
120 Bandwidth::SemiSuperWideBand => {
121 bands.push(&mut spec_lines[9..180]).ok();
122 }
123 Bandwidth::SuperWideBand => {
124 let (left, right) = spec_lines.split_at_mut(120);
126 bands.push(&mut left[9..]).ok();
127 bands.push(&mut right[..120]).ok();
128 }
129 Bandwidth::FullBand => {
130 let (left, right) = spec_lines.split_at_mut(150);
132 bands.push(&mut left[9..]).ok();
133 bands.push(&mut right[..150]).ok();
134 }
135 },
136 };
137 bands
138}
139
140#[cfg(test)]
141mod tests {
142 extern crate std;
143 use super::*;
144 use crate::common::config::FrameDuration;
145
146 #[test]
147 fn decode_test() {
148 let duration = FrameDuration::TenMs;
149 let bandwidth = Bandwidth::FullBand;
150 let num_tns_filters = 2;
151 let reflect_coef_order = [8, 0];
152 let reflect_coef_ints = [6, 10, 7, 8, 7, 9, 7, 7];
153 let mut spec_lines: [f32; 400] = [
154 -568.56555, 1972.808, 3987.5906, 2461.2402, -263.29547, -2949.6724, -2217.0242, 141.18742, 1270.6868,
155 -385.4035, 1667.538, 568.56555, -538.0386, -1606.4839, 538.0386, -263.29547, -49.60639, 751.7276,
156 -476.98453, -141.18742, 1423.3219, -2033.862, -599.0926, 202.24144, -934.8897, -202.24144, 324.3495,
157 1056.9977, -80.1334, 751.7276, 1667.538, -263.29547, 507.51154, 141.18742, 629.61957, -446.45752,
158 507.51154, -385.4035, 202.24144, -1331.7408, 1453.8489, -385.4035, -49.60639, 141.18742, 0.0, 80.1334,
159 -488.43216, 183.16206, -122.10804, 0.0, 0.0, 122.10804, -366.32413, -122.10804, -244.21608, -183.16206,
160 0.0, 61.05402, 0.0, -427.37814, -244.21608, -671.59424, -427.37814, -366.32413, 0.0, 183.16206, 610.5402,
161 122.10804, 549.4862, 183.16206, 427.37814, -122.10804, 122.10804, -122.10804, -61.05402, -61.05402, 0.0,
162 0.0, 0.0, 0.0, 61.05402, 244.21608, -61.05402, -61.05402, -61.05402, 122.10804, 61.05402, 183.16206,
163 183.16206, 61.05402, -122.10804, -122.10804, 61.05402, 305.2701, 122.10804, -122.10804, -305.2701,
164 -244.21608, -122.10804, 0.0, 0.0, 0.0, -61.05402, 61.05402, -61.05402, 61.05402, 61.05402, 61.05402,
165 -61.05402, -183.16206, -61.05402, 61.05402, 183.16206, 0.0, 0.0, 61.05402, 122.10804, -61.05402, -61.05402,
166 61.05402, 122.10804, 122.10804, 61.05402, 122.10804, 0.0, -122.10804, -183.16206, 0.0, 183.16206,
167 122.10804, 0.0, 0.0, 0.0, 0.0, 61.05402, 61.05402, 0.0, -61.05402, 0.0, 0.0, 0.0, -61.05402, -61.05402,
168 61.05402, 122.10804, 0.0, 0.0, 0.0, 19.079382, 0.0, 0.0, 0.0, -61.05402, 122.10804, 0.0, -61.05402,
169 -61.05402, 0.0, 122.10804, 0.0, 122.10804, 0.0, 0.0, -122.10804, -61.05402, 0.0, 61.05402, 0.0, -61.05402,
170 0.0, 61.05402, 122.10804, 0.0, -61.05402, 0.0, 61.05402, 0.0, 61.05402, 0.0, 61.05402, -61.05402,
171 -61.05402, 0.0, 0.0, 0.0, 0.0, -61.05402, -61.05402, 0.0, 0.0, 61.05402, 0.0, -61.05402, 0.0, 0.0, 0.0,
172 0.0, 61.05402, 0.0, 61.05402, 0.0, 0.0, 0.0, 61.05402, 0.0, 61.05402, 0.0, 61.05402, 0.0, 0.0, 0.0,
173 -61.05402, 61.05402, 122.10804, -61.05402, 0.0, 122.10804, 0.0, 61.05402, -61.05402, 0.0, 0.0, -61.05402,
174 0.0, 0.0, 122.10804, -61.05402, -61.05402, 0.0, 0.0, 0.0, 0.0, -61.05402, 61.05402, -61.05402, 61.05402,
175 61.05402, 61.05402, 0.0, 0.0, 61.05402, 0.0, 0.0, 0.0, 61.05402, 61.05402, 61.05402, 0.0, 0.0, 61.05402,
176 0.0, 0.0, 61.05402, 122.10804, -122.10804, 0.0, -61.05402, -61.05402, 0.0, 0.0, 0.0, 0.0, -61.05402, 0.0,
177 0.0, -61.05402, 61.05402, 61.05402, 61.05402, -122.10804, -61.05402, -61.05402, 0.0, 61.05402, -61.05402,
178 0.0, 0.0, 61.05402, 0.0, 0.0, 0.0, -61.05402, 61.05402, -61.05402, 0.0, 0.0, -61.05402, 61.05402, 0.0, 0.0,
179 0.0, 61.05402, 61.05402, 0.0, -61.05402, -61.05402, 0.0, -61.05402, 0.0, -61.05402, -61.05402, 0.0,
180 61.05402, 0.0, 0.0, 0.0, 0.0, -61.05402, 0.0, 61.05402, 61.05402, 0.0, 0.0, 0.0, 0.0, -61.05402, -61.05402,
181 -61.05402, 0.0, 0.0, 0.0, -61.05402, 0.0, 0.0, 61.05402, 0.0, -61.05402, 0.0, 61.05402, 0.0, 0.0, 0.0,
182 -61.05402, 0.0, 0.0, 0.0, -61.05402, 0.0, 0.0, -61.05402, 0.0, 0.0, 0.0, 0.0, -61.05402, 61.05402, 0.0,
183 0.0, 0.0, 0.0, 61.05402, 0.0, 0.0, 0.0, 0.0, -61.05402, -61.05402, 61.05402, 0.0, 0.0, 0.0, -19.079382,
184 -19.079382, -19.079382, -19.079382, 19.079382, -19.079382, 19.079382, 0.0, 0.0, 0.0, -61.05402, -61.05402,
185 0.0, 0.0, 61.05402, -61.05402, -61.05402, 0.0, 0.0, 61.05402, 0.0, 0.0, 0.0, 0.0, -61.05402, 0.0, 61.05402,
186 0.0, 61.05402, 0.0, 0.0, 0.0, 0.0, 0.0, -61.05402, 0.0, 0.0, 61.05402, 61.05402,
187 ];
188
189 apply_temporal_noise_shaping(
190 duration,
191 bandwidth,
192 num_tns_filters,
193 &reflect_coef_order,
194 &reflect_coef_ints,
195 &mut spec_lines,
196 );
197
198 #[rustfmt::skip]
199 let spec_lines_expected: [f32; 400] = [
200 -568.56555, 1972.808, 3987.5906, 2461.2402, -263.29547, -2949.6724, -2217.0242, 141.18742, 1270.6868,
201 -385.4035, 1667.538, 568.56555, -538.0386, -1924.9376, -330.6227, 358.01404, -103.25958, 640.72064,
202 -380.6663, -565.7268, 1425.4789, -1620.2815, -2171.777, 65.41626, -630.4777, -241.61359, 70.17501,
203 648.6986, 913.1724, 377.05695, 1248.8955, 447.55414, 122.224335, 387.0873, 670.9608, 202.11314, 470.52597,
204 9.777176, 250.14848, -869.4124, 705.27844, 764.594, -196.6836, 162.10555, 32.383907, 212.68384, -200.68219,
205 -385.05658, 74.749176, 244.4491, 75.39133, 71.7427, -370.58853, -284.1499, -221.86317, -378.81683,
206 -78.224205, 120.7565, 49.39573, -431.70422, -639.2284, -863.50916, -762.39795, -557.4247, -210.2326,
207 207.37712, 667.06, 268.28708, 266.76526, 180.27934, 266.1345, 18.510933, -71.35217, -18.678001, 61.719135,
208 78.072945, 41.07525, 31.682747, 65.34431, 39.83117, 50.713173, 265.0006, 87.029144, -105.01486, -92.9501,
209 109.07149, 213.51758, 237.69977, 244.04578, 169.18098, -60.653255, -202.20692, -5.709038, 418.32336,
210 390.42206, -52.63867, -409.54736, -371.99884, -123.08209, 15.460239, -13.179712, 10.579021, 10.312677,
211 49.179047, -104.04299, -108.42853, 45.232265, 106.2404, -18.412956, -252.0934, -189.36148, 85.68147,
212 260.1948, 66.20917, -89.14935, 37.372047, 196.89316, 4.2800827, -186.45068, -10.664055, 251.7307,
213 283.97842, 87.595795, 65.05641, 91.597, -64.72161, -260.67474, -120.33, 275.7829, 360.36444, 76.64067,
214 -85.21214, -19.708641, 59.083878, 71.03325, 37.62242, 41.2656, 33.881153, 25.94694, -3.6607666, -15.336594,
215 -46.333282, -68.63583, 51.637062, 181.11745, 75.242294, -25.19682, -26.834858, 23.40418, 38.82212,
216 -11.055281, -14.305193, -22.998611, 129.22333, 87.56438, -91.969635, -113.919846, -21.006641, 165.25201,
217 93.82325, 70.90962, 56.982315, 15.586489, -109.50122, -156.43475, -32.77449, 127.61873, 86.515625,
218 -71.82623, -60.272907, 74.61493, 174.22997, 35.206467, -130.87024, -37.255043, 125.10912, 72.04756,
219 28.948765, 1.5288572, 89.77242, 28.662163, -122.471275, -64.80139, 35.938797, 56.74036, 19.603413,
220 -92.18097, -95.45599, 4.2908516, 4.6752024, 39.53695, 19.507534, -69.66742, -24.112461, -4.6465445,
221 -19.89853, -2.2964888, 51.27441, 41.12713, 64.92945, 0.0, 0.0, 0.0, 61.05402, 0.0, 61.05402, 0.0, 61.05402,
222 0.0, 0.0, 0.0, -61.05402, 61.05402, 122.10804, -61.05402, 0.0, 122.10804, 0.0, 61.05402, -61.05402, 0.0,
223 0.0, -61.05402, 0.0, 0.0, 122.10804, -61.05402, -61.05402, 0.0, 0.0, 0.0, 0.0, -61.05402, 61.05402,
224 -61.05402, 61.05402, 61.05402, 61.05402, 0.0, 0.0, 61.05402, 0.0, 0.0, 0.0, 61.05402, 61.05402, 61.05402,
225 0.0, 0.0, 61.05402, 0.0, 0.0, 61.05402, 122.10804, -122.10804, 0.0, -61.05402, -61.05402, 0.0, 0.0, 0.0,
226 0.0, -61.05402, 0.0, 0.0, -61.05402, 61.05402, 61.05402, 61.05402, -122.10804, -61.05402, -61.05402, 0.0,
227 61.05402, -61.05402, 0.0, 0.0, 61.05402, 0.0, 0.0, 0.0, -61.05402, 61.05402, -61.05402, 0.0, 0.0,
228 -61.05402, 61.05402, 0.0, 0.0, 0.0, 61.05402, 61.05402, 0.0, -61.05402, -61.05402, 0.0, -61.05402, 0.0,
229 -61.05402, -61.05402, 0.0, 61.05402, 0.0, 0.0, 0.0, 0.0, -61.05402, 0.0, 61.05402, 61.05402, 0.0, 0.0, 0.0,
230 0.0, -61.05402, -61.05402, -61.05402, 0.0, 0.0, 0.0, -61.05402, 0.0, 0.0, 61.05402, 0.0, -61.05402, 0.0,
231 61.05402, 0.0, 0.0, 0.0, -61.05402, 0.0, 0.0, 0.0, -61.05402, 0.0, 0.0, -61.05402, 0.0, 0.0, 0.0, 0.0,
232 -61.05402, 61.05402, 0.0, 0.0, 0.0, 0.0, 61.05402, 0.0, 0.0, 0.0, 0.0, -61.05402, -61.05402, 61.05402, 0.0,
233 0.0, 0.0, -19.079382, -19.079382, -19.079382, -19.079382, 19.079382, -19.079382, 19.079382, 0.0, 0.0, 0.0,
234 -61.05402, -61.05402, 0.0, 0.0, 61.05402, -61.05402, -61.05402, 0.0, 0.0, 61.05402, 0.0, 0.0, 0.0, 0.0,
235 -61.05402, 0.0, 61.05402, 0.0, 61.05402, 0.0, 0.0, 0.0, 0.0, 0.0, -61.05402, 0.0, 0.0, 61.05402, 61.05402,
236 ];
237
238 assert_eq![spec_lines, spec_lines_expected];
239 }
240}