1#![allow(clippy::excessive_precision)]
2
3use crate::{
4 common::{
5 complex::Scaler,
6 config::{FrameDuration, Lc3Config},
7 },
8 tables::temporal_noise_shaping_tables::*,
9};
10use core::{f64::consts::PI, panic};
11#[allow(unused_imports)]
12use num_traits::real::Real;
13
14pub struct TemporalNoiseShaping {
15 config: Lc3Config,
16}
17
18pub struct TnsResult {
19 pub nbits_tns: usize,
20 pub lpc_weighting: u8,
21 pub num_tns_filters: usize,
22 pub rc_order: [usize; 2], pub rc_i: [usize; 16], pub rc_q: [Scaler; 16], }
26
27struct TnsParams {
28 pub num_tns_filters: usize,
29 pub start_freq: [usize; 2],
30 pub stop_freq: [usize; 2],
31 pub sub_start: [[usize; 3]; 2],
32 pub sub_stop: [[usize; 3]; 2],
33}
34
35impl TemporalNoiseShaping {
36 pub fn new(config: Lc3Config) -> Self {
37 Self { config }
38 }
39
40 pub fn run(&self, x_s: &mut [Scaler], p_bw: usize, nbits: usize, near_nyquist_flag: bool) -> TnsResult {
41 assert_eq!(x_s.len(), self.config.ne);
42 let tns = self.get_tns_params(p_bw);
43 let mut rc_order = [0; 2];
44 let mut rc_i = [0; 16];
45 let mut rc_q = [0.0; 16];
46 let num_tns_filters = tns.num_tns_filters;
47
48 let lpc_weighting = match self.config.n_ms {
50 FrameDuration::TenMs if nbits < 480 => 1,
51 FrameDuration::SevenPointFiveMs if nbits < 360 => 1,
52 _ => 0,
53 };
54
55 for (f, (sub_start, sub_stop)) in tns.sub_start[..num_tns_filters].iter().zip(&tns.sub_stop).enumerate() {
56 let r = Self::compute_normalized_autocorrelation(sub_start, sub_stop, x_s);
57 Self::tns_analysis(&r, f, near_nyquist_flag, lpc_weighting, &mut rc_q);
58 }
59
60 Self::apply_quantization(num_tns_filters, &mut rc_q, &mut rc_i, &mut rc_order);
62
63 let nbits_tns = Self::calc_bit_budget(num_tns_filters, lpc_weighting, &rc_i, &rc_order);
65
66 Self::apply_filtering(&tns, x_s, &mut rc_q, &mut rc_order);
68
69 TnsResult {
70 nbits_tns,
72 num_tns_filters,
73 rc_i,
74 rc_q,
75 rc_order,
76 lpc_weighting,
77 }
78 }
79
80 fn compute_normalized_autocorrelation(sub_start: &[usize], sub_stop: &[usize], x_s: &[Scaler]) -> [Scaler; 9] {
81 let lag_window = [
82 1.0, 0.9980280260203829, 0.9921354055113971, 0.9823915844707989, 0.9689107911912967, 0.9518498073692735,
83 0.9314049334023056, 0.9078082299969592, 0.8813231366694713,
84 ];
85
86 let mut r = [0.0; 9];
87 for (k, (r, lag_window)) in r.iter_mut().zip(&lag_window).enumerate() {
88 let r0 = if k == 0 { 3.0 } else { 0.0 };
89 let mut rk = 0.0;
90 let mut e_prod = 1.0;
91
92 for (start, stop) in sub_start.iter().zip(sub_stop.iter()) {
93 let es: Scaler = x_s[*start..*stop].iter().map(|x| *x * *x).sum();
94
95 let k_from = *start + k;
97 let ac: Scaler = if k_from < x_s.len() && k_from < *stop {
98 x_s[k_from..*stop]
99 .iter()
100 .zip(x_s[*start..*stop].iter())
101 .map(|(kx, x)| *x * *kx)
102 .sum()
103 } else {
104 0.0
105 };
106
107 e_prod *= es;
108 rk += ac / es;
109 }
110
111 *r = if e_prod == 0.0 { r0 } else { rk } * *lag_window;
112 }
113
114 r
115 }
116
117 fn get_tns_params(&self, p_bw: usize) -> TnsParams {
118 match self.config.n_ms {
119 FrameDuration::TenMs => match p_bw {
120 0 => TnsParams {
121 num_tns_filters: 1,
122 start_freq: [12, 160],
123 stop_freq: [80, 0],
124 sub_start: [[12, 34, 57], [0, 0, 0]],
125 sub_stop: [[34, 57, 80], [0, 0, 0]],
126 },
127 1 => TnsParams {
128 num_tns_filters: 1,
129 start_freq: [12, 160],
130 stop_freq: [160, 0],
131 sub_start: [[12, 61, 110], [0, 0, 0]],
132 sub_stop: [[61, 110, 160], [0, 0, 0]],
133 },
134 2 => TnsParams {
135 num_tns_filters: 1,
136 start_freq: [12, 160],
137 stop_freq: [200, 0],
138 sub_start: [[12, 88, 164], [0, 0, 0]],
139 sub_stop: [[88, 164, 240], [0, 0, 0]],
140 },
141 3 => TnsParams {
142 num_tns_filters: 2,
143 start_freq: [12, 160],
144 stop_freq: [160, 320],
145 sub_start: [[12, 61, 110], [160, 213, 266]],
146 sub_stop: [[61, 110, 160], [213, 266, 320]],
147 },
148 4 => TnsParams {
149 num_tns_filters: 2,
150 start_freq: [12, 200],
151 stop_freq: [200, 400],
152 sub_start: [[12, 74, 137], [200, 266, 333]],
153 sub_stop: [[74, 137, 200], [266, 333, 400]],
154 },
155 _ => panic!(
156 "Cannot create valid start and stop freq indexes because of an invalid p_bw: {}",
157 p_bw
158 ),
159 },
160 FrameDuration::SevenPointFiveMs => match p_bw {
161 0 => TnsParams {
162 num_tns_filters: 1,
163 start_freq: [9, 120],
164 stop_freq: [60, 0],
165 sub_start: [[9, 26, 43], [0, 0, 0]],
166 sub_stop: [[26, 43, 60], [0, 0, 0]],
167 },
168 1 => TnsParams {
169 num_tns_filters: 1,
170 start_freq: [9, 120],
171 stop_freq: [120, 0],
172 sub_start: [[9, 46, 83], [0, 0, 0]],
173 sub_stop: [[46, 83, 120], [0, 0, 0]],
174 },
175 2 => TnsParams {
176 num_tns_filters: 1,
177 start_freq: [9, 120],
178 stop_freq: [180, 0],
179 sub_start: [[9, 66, 123], [0, 0, 0]],
180 sub_stop: [[66, 123, 180], [0, 0, 0]],
181 },
182 3 => TnsParams {
183 num_tns_filters: 2,
184 start_freq: [9, 120],
185 stop_freq: [120, 240],
186 sub_start: [[9, 46, 82], [120, 159, 200]],
187 sub_stop: [[46, 82, 120], [159, 200, 240]],
188 },
189 4 => TnsParams {
190 num_tns_filters: 2,
191 start_freq: [9, 150],
192 stop_freq: [150, 300],
193 sub_start: [[9, 56, 103], [150, 200, 250]],
194 sub_stop: [[56, 103, 150], [200, 250, 300]],
195 },
196 _ => panic!(
197 "Cannot create valid start and stop freq indexes because of an invalid p_bw: {}",
198 p_bw
199 ),
200 },
201 }
202 }
203
204 fn tns_analysis(r: &[Scaler], f: usize, near_nyquist_flag: bool, lpc_weighting: u8, rc_q: &mut [Scaler]) {
205 let mut a_memory = [[0.0; 9]; 2];
207 let (a, a_last) = a_memory.split_at_mut(1);
208 let mut a = &mut a[0];
209 let mut a_last = &mut a_last[0];
210
211 let mut e = r[0];
212 a[0] = 1.0;
213 for k in 1..9 {
214 core::mem::swap(&mut a_last, &mut a);
215
216 let mut rc = 0.0;
218 for n in 0..k {
219 rc -= a_last[n] * r[k - n];
220 }
221 if e != 0.0 {
222 rc /= e;
223 }
224
225 a[0] = 1.0;
227 for n in 1..k {
228 a[n] = a_last[n] + rc * a_last[k - n];
229 }
230 a[k] = rc;
231 e *= 1.0 - rc * rc;
232 }
233
234 let pred_gain = if e == 0.0 { r[0] } else { r[0] / e };
235 const THRESH: Scaler = 1.5;
236 if pred_gain > THRESH && !near_nyquist_flag {
237 let mut gamma = 1.0;
239 const THRESH2: Scaler = 2.0;
240 if lpc_weighting > 0 && pred_gain < THRESH2 {
241 gamma -= (1.0 - 0.85) * (THRESH2 - pred_gain) / (THRESH2 - THRESH);
242 }
243 for (k, a_k) in a.iter_mut().enumerate() {
244 *a_k *= gamma.powi(k as i32);
245 }
246 let rc = &mut rc_q[f * 8..];
247 let mut a_k = a;
248 let mut a_km1 = a_last;
249 for k in (1..9).rev() {
250 rc[k - 1] = a_k[k];
251 let e = 1.0 - rc[k - 1] * rc[k - 1];
252 for n in 1..k {
253 a_km1[n] = a_k[n] - rc[k - 1] * a_k[k - n];
254 a_km1[n] /= e;
255 }
256 core::mem::swap(&mut a_k, &mut a_km1);
257 }
258 } else {
259 let rc = &mut rc_q[f * 8..];
261 for rc_n in rc[..8].iter_mut() {
262 *rc_n = 0.0;
263 }
264 }
265 }
266
267 fn apply_quantization(num_tns_filters: usize, rc_q: &mut [Scaler], rc_i: &mut [usize], rc_order: &mut [usize]) {
268 const QUANTIZER_STEPSIZE: Scaler = PI as Scaler / 17.0;
269 for f in 0..num_tns_filters {
270 let rc = &mut rc_q[f * 8..];
271 for (rc_quant, rc_int) in rc[..8].iter_mut().zip(rc_i[(f * 8)..(f * 8 + 8)].iter_mut()) {
272 *rc_int = (to_int((*rc_quant).asin() / QUANTIZER_STEPSIZE) + 8) as usize;
273 *rc_quant = (QUANTIZER_STEPSIZE * (*rc_int as Scaler - 8.0)).sin();
274 }
275
276 let mut k: i8 = 7;
278 while k >= 0 && rc_i[f * 8 + k as usize] == 8 {
279 k -= 1;
280 }
281 rc_order[f] = (k + 1) as usize;
282 }
283
284 for f in num_tns_filters..2 {
286 for k in 0..8 {
287 rc_i[f * 8 + k] = 8;
288 rc_q[f * 8 + k] = 0.0;
289 }
290 rc_order[f] = 0;
291 }
292 }
293
294 fn calc_bit_budget(num_tns_filters: usize, tns_lpc_weighting: u8, rc_i: &[usize], rc_order: &[usize]) -> usize {
295 let mut nbits_tns = 0;
296 for f in 0..num_tns_filters {
297 let nbits_tns_order = if rc_order[f] != 0 {
298 AC_TNS_ORDER_BITS[tns_lpc_weighting as usize][rc_order[f] - 1]
299 } else {
300 0
301 };
302 let mut nbits_tns_coef = 0;
303 for (k, coef_bits) in AC_TNS_COEF_BITS[..rc_order[f]].iter().enumerate() {
304 nbits_tns_coef += coef_bits[rc_i[f * 8 + k]];
305 }
306
307 nbits_tns += ((2048.0 + nbits_tns_order as Scaler + nbits_tns_coef as Scaler) / 2048.0).ceil() as usize;
308 }
309
310 nbits_tns
311 }
312
313 fn apply_filtering(tns: &TnsParams, x_s: &mut [Scaler], rc_q: &mut [Scaler], rc_order: &mut [usize]) {
314 let mut st = [0.0; 8];
315 for f in 0..tns.num_tns_filters {
316 if rc_order[f] != 0 {
317 let from = tns.start_freq[f];
318 let to = tns.stop_freq[f];
319
320 for x_f in &mut x_s[from..to] {
323 let mut t = *x_f;
324 let mut st_save = t;
325 let prev_order = rc_order[f] - 1;
326
327 for (st, rcq) in st[..prev_order].iter_mut().zip(&rc_q[f * 8..f * 8 + prev_order]) {
328 let st_tmp = *rcq * t + *st;
329 t += *rcq * *st;
330 *st = st_save;
331 st_save = st_tmp;
332 }
333
334 t += rc_q[f * 8 + prev_order] * st[prev_order];
335 st[prev_order] = st_save;
336 *x_f = t;
337 }
338 }
339 }
340 }
341}
342
343fn to_int(x: Scaler) -> i8 {
344 if x >= 0.0 {
345 (x + 0.5) as i8
346 } else {
347 -(-x + 0.5) as i8
348 }
349}
350
351#[cfg(test)]
352mod tests {
353 extern crate std;
354 use super::*;
355 use crate::common::config::SamplingFrequency;
356
357 #[rustfmt::skip]
358 #[test]
359 fn temporal_noise_shaping_run() {
360 let config = Lc3Config::new(SamplingFrequency::Hz48000, FrameDuration::TenMs);
361 let tns = TemporalNoiseShaping::new(config);
362 let mut x_s = [
363 2511.287, -3606.8093, -453.28122, -360.71924, -2574.9756, -3166.2068, 6525.6, 6284.0137, -10303.951,
364 -4442.8755, 2318.4038, -691.36865, 509.12134, -1054.0342, 852.0186, -1959.2595, -2463.084, 583.8584,
365 -1045.9277, 886.3083, 94.29779, 106.0552, 262.7902, 195.86151, 748.0028, -369.72824, 326.68167, -706.81616,
366 83.90518, -101.80473, -425.53433, 248.85109, -246.2868, 415.67813, -428.0742, -195.10165, -497.12534,
367 148.11542, 351.7376, -259.38834, 639.9149, -232.2877, 182.4239, 30.73989, 139.50827, 315.7314, -314.8985,
368 111.07428, 464.2896, 352.44342, -380.097, 82.403694, -41.359577, 195.84523, 114.65242, -207.70195,
369 156.48032, -178.95581, 313.9437, -130.90295, -105.89414, 22.376598, -114.98715, 120.20845, -164.51794,
370 261.76236, 37.331238, 106.96828, -198.03798, -108.76448, 134.22601, -216.93547, 195.3998, -21.63419,
371 156.55684, -51.93392, 101.626854, 149.68706, -94.93349, -155.7282, -464.9618, 119.154236, -82.80184,
372 72.36793, -122.200264, -39.244514, 270.96143, -173.43079, 107.70619, -164.70389, 55.223305, -111.1405,
373 17.96329, 125.23528, -135.59274, 60.439613, -251.46301, 131.2461, -101.01771, 69.59965, 16.21791,
374 -239.07864, 166.54358, -27.770905, 100.91532, -84.49127, 69.28591, 2.6135557, -31.626968, 20.677122,
375 -36.27791, 119.84301, -173.36378, 35.84611, -57.688297, 60.183567, 4.423961, -44.209984, 105.70867,
376 -50.634827, 109.67776, -134.32838, 61.955124, 21.708387, -28.346958, -83.66344, -70.2042, 154.10416,
377 -77.64532, 88.29541, -130.808, 36.89496, 16.645363, -25.276045, 51.67908, -137.08151, 124.83691, -152.0996,
378 65.79087, 0.93463665, -60.837196, 39.439693, -114.28214, 81.32954, -45.443783, 96.88175, -80.02808,
379 6.91597, -0.9586373, -92.0962, 23.475348, -94.339935, 125.18178, -98.72728, 9.358742, -2.886684, 14.301312,
380 43.602825, -103.58884, 91.13613, -73.82291, 71.59755, -40.91015, 9.037108, 43.62777, -32.685516, 69.14355,
381 -105.05149, 82.54336, -8.614124, 11.804503, -27.901173, -29.564074, 41.35118, -8.069561, 77.09149,
382 -70.76394, 31.398144, -49.828518, 43.814983, 11.879899, -39.018723, 49.713158, -68.79033, 65.760086,
383 -60.97088, 33.07043, -20.903938, -14.867276, 9.887002, -65.46376, 41.143112, -80.06619, 70.94139,
384 -43.88703, 2.1660235, -17.16438, -44.083027, 38.160618, -81.36653, 70.78228, -76.33006, 38.737568,
385 -12.454603, -29.338528, 56.428005, -39.599926, 39.25371, -73.31344, 69.79237, -17.97577, 12.852926,
386 12.684623, -32.4752, 36.446888, -65.407234, 61.598774, -65.757484, 10.238938, -20.029032, -2.825231,
387 42.594162, -56.822716, 53.156845, -30.462795, 38.866444, -56.68353, 24.660025, 14.751921, -35.350494,
388 37.21626, -76.86587, 29.546429, -62.394695, 27.275826, -14.183131, -10.919811, 38.614643, -38.49674,
389 59.394817, -34.20599, 41.272846, -23.526806, 22.555021, 1.7496673, -19.42429, 46.749092, -46.406094,
390 42.399597, -50.664745, 32.1371, -13.392963, 7.2786326, 24.364573, -48.878193, 39.617836, -60.437885,
391 40.904007, -37.622654, 16.281404, 10.157282, -32.828197, 30.448824, -50.824665, 49.72176, -41.46506,
392 27.87757, -24.912022, -13.79381, 20.7759, -37.632587, 48.469193, -50.989594, 42.78355, -32.603626,
393 12.9430275, -0.48920912, -29.010874, 36.240032, -65.120476, 43.169476, -36.05779, 27.190653, -12.357571,
394 -6.6507573, 20.675322, -37.217205, 53.199875, -54.718746, 43.378906, -21.585281, -1.6675593, 13.522394,
395 -29.79583, 22.414072, -39.135113, 40.94145, -37.682613, 31.857054, -8.821981, 6.641381, 25.134476,
396 -40.58887, 42.64201, -44.198082, 40.230164, -27.744131, 10.078336, 4.423329, -22.164833, 27.893787,
397 -50.982807, 50.552082, -34.822014, 24.829428, -12.062506, -3.7417355, 18.681189, -40.84422, 45.581814,
398 -42.326923, 35.923992, -27.111525, 13.07634, 2.8001645, -20.283352, 35.183113, -46.604267, 47.304718,
399 -47.010338, 26.623617, -1.2559637, -11.157539, 23.359474, -34.244343, 38.091057, -39.234665, 46.234547,
400 -30.573185, 2.6562088, 11.293563, -17.823277, 33.29007, -46.73799, 43.705185, -32.237366, 23.87085,
401 -14.893113, 0.8721875, 27.640835, -39.741753, 45.260857, -47.98558, 33.93777, -20.93668, 4.6949544,
402 7.7584434, -24.253351, 35.06494, -40.09654, 39.286926, -33.447765, 24.822977, -8.966054, -9.330206,
403 21.831121, -26.851707, 38.898933, -49.516945, 38.540756, -25.502691, 3.2083294, 10.038194, -23.048763,
404 34.32631, -39.45431, 37.582066, -34.85849, 27.25857, -8.987542, -7.2581387, 24.746119, -38.36987, 41.85204,
405 -39.183273, 29.537968, -22.075731, 8.153215, 10.045177, -24.236364, 31.76943, -34.252445, 37.48698,
406 -35.33923, 22.365273, -7.9304223, -7.034074, 20.73084, -31.455378, 35.02656,
407 ];
408
409 let result = tns.run(&mut x_s, 4, 1200, false);
410
411 let x_f_expected = [
412 2511.287, -3606.8093, -453.28122, -360.71924, -2574.9756, -3166.2068, 6525.6, 6284.0137, -10303.951,
413 -4442.8755, 2318.4038, -691.36865, 509.12134, -938.29266, 525.9005, -1542.4482, -3091.5273, 262.27206,
414 -379.65656, -98.486786, 668.16437, -213.70082, -114.14174, 80.94827, 83.418945, -16.794994, 6.197174,
415 -332.66284, -48.91777, 0.084522665, -281.5821, 78.69863, 133.78897, 102.63185, -259.9021, -450.69684,
416 -538.17615, 102.73462, 256.75674, -122.24531, 414.3129, 90.33753, -141.62321, 64.58323, 158.11197,
417 264.04486, -70.996445, -74.847595, 715.87695, 398.03842, -383.14874, 81.798744, 100.61626, 183.76709,
418 107.91918, -74.72749, 137.34314, -12.11866, 145.58879, -8.319928, -146.90816, 21.44834, -14.692991,
419 -26.504921, -44.41256, 169.60251, 157.3852, 57.295708, -223.72159, -105.66721, 85.917145, -124.74416,
420 67.12806, 148.09708, 108.51118, -38.312347, 85.37175, 124.25812, -19.708088, -252.26158, -396.83145,
421 30.49828, 24.158318, 4.4514937, -100.692856, -19.743237, 174.73466, -129.2712, -94.76638, -48.278133,
422 -12.916355, -108.09598, 15.809202, 102.17793, -36.756264, -59.4923, -168.1815, 18.80262, -43.62355,
423 23.15091, 16.152151, -187.13437, 30.643784, 90.79638, -16.21843, -39.05421, 62.11714, -2.155285, -19.06319,
424 -42.414265, 35.171066, 84.379585, -116.602325, -33.51855, -7.659307, 44.801598, -11.07798, -14.886959,
425 62.95822, 14.218942, 31.104227, -83.76815, 17.044928, 55.428146, -13.889921, -126.15556, -27.248165,
426 120.640366, -19.761774, 14.046745, -73.71858, 0.10803318, 10.083524, -16.70562, 4.7014112, -62.691025,
427 50.462833, -84.346176, -13.629369, 36.10631, -46.619267, -21.598942, -48.490704, -6.3323555, 15.65649,
428 48.896317, -56.442543, -6.640568, -17.761715, -70.73248, -40.4366, -36.27153, 74.86966, -46.19746,
429 -44.013317, 2.0889094, 26.809942, -6.282827, -65.310585, 33.484646, -9.667151, 15.079562, -16.305983,
430 9.046168, 29.939863, 5.129214, 16.5475, -50.21096, 31.017387, 38.323303, -3.0681198, -36.80033, -1.2009478,
431 11.490404, 26.555166, 44.298775, -31.610435, 4.04779, -32.927948, 29.660675, 11.896004, -18.109625,
432 25.200207, -23.730797, 15.500507, -25.358208, 6.163124, -7.3798866, -7.921206, -16.156162, -36.149162,
433 -1.5045524, -43.494595, 29.947332, -15.511134, -17.982704, -28.039505, -30.445019, -3.5225277, -46.805386,
434 -1.0227482, -23.363768, -17.676548, -3.6520846, -12.88875, 4.756609, 31.271141, -6.629322, -37.832882,
435 -0.21950912, 38.885174, 21.138603, 6.2617035, -9.60021, -11.284341, -19.242826, -1.6980145, -9.359415,
436 -41.126484, -29.448069, -5.9372683, 25.94433, 1.3254867, -14.705631, 15.379487, 16.574158, -27.095804,
437 -19.93113, 20.497425, 0.79107094, -7.7554317, -36.76988, -52.092567, -38.030884, -20.167278, -0.28380156,
438 -7.2491307, 8.2373905, 7.9681587, 12.655432, 23.266579, 13.15513, 5.5212536, 12.821712, 10.402097, -1.8669,
439 17.029139, 7.877034, -3.6022367, -13.437171, -10.018736, 6.7936516, 12.0322485, 17.809977, -13.797862,
440 -19.886257, -20.896944, -13.391824, -3.7870193, -6.042081, 9.495218, -8.35246, -16.302475, -16.089418,
441 -2.2239032, 5.133191, -1.9499176, -12.571083, -26.08479, -8.472019, -4.010655, 5.987412, -1.6527638,
442 -5.525652, -1.8339038, -6.3098893, -2.546278, -14.999996, -4.8673024, -21.751396, -23.044847, 0.98999345,
443 3.2206738, 1.6813838, -5.9552116, -2.9898171, -6.6439576, 10.739187, -0.41604716, -6.192164, 10.029629,
444 -8.77803, -3.0170813, -3.2569091, -16.77877, -12.368547, 2.8054588, -1.341449, 4.0487995, 9.832774,
445 9.444449, 19.458578, -5.653375, -5.7151184, -1.1136432, 2.3793151, 5.6741295, -4.6841993, -0.53913784,
446 -5.0413313, -4.085096, -17.153347, -1.8630176, 11.785563, 1.1223254, -0.71278524, -4.503395, 1.1829545,
447 -10.829809, -1.1153163, 3.7169714, -0.4367964, -0.591923, -2.8435392, 1.75674, -4.178983, 4.8031635,
448 -5.574907, -0.26360065, -4.317787, -11.108944, 12.20769, 3.0794377, -0.6653844, -2.5413795, -2.403656,
449 -0.8925853, 13.288289, 6.883606, -15.778875, -1.6005001, 5.696593, 8.6179, -7.1294184, -5.413874,
450 5.2202096, 2.9486847, -2.3101602, -2.2582812, 15.61281, -0.8072282, -0.08025418, -4.076133, -9.068343,
451 4.1847715, -2.2272792, -1.0373013, -4.7336984, 1.2461259, -0.5397187, 0.18704754, -0.1272373, 0.41515422,
452 4.11998, -5.550728, 0.5320622, 3.4917614, 8.215734, -10.053921, -7.784162, 3.4075887, -8.748142,
453 0.87312615, -1.6497533, 1.9920977, -0.20973617, -1.9895163, -3.3932712, 1.6009337, 7.0630236, -3.209106,
454 5.2722173, -5.2088814, -1.2551317, 2.55086, -3.7561512, -1.9274446, -2.2996173, 5.709345, -2.3815656,
455 -0.94840765, 0.60572165, 4.09223, -2.2723556, -4.731332, 2.7107785, -2.495332, 3.3961606, -2.640641,
456 -1.3273795,
457 ];
458 assert_eq!(x_s, x_f_expected);
459 assert_eq!(result.rc_i, [10, 7, 8, 9, 7, 9, 8, 9, 14, 11, 6, 9, 7, 9, 8, 8]);
460 assert_eq!(
461 result.rc_q,
462 [
463 0.36124167, -0.18374951, 0.0, 0.18374951, -0.18374951, 0.18374951, 0.0, 0.18374951, 0.8951633,
464 0.52643216, -0.36124167, 0.18374951, -0.18374951, 0.18374951, 0.0, 0.0
465 ]
466 );
467 assert_eq!(result.lpc_weighting, 0);
468 assert_eq!(result.num_tns_filters, 2);
469 assert_eq!(result.rc_order, [8, 6]);
470 assert_eq!(result.nbits_tns, 42)
471 }
472}