use crate::{
common::{complex::Scaler, config::FrameDuration},
tables::temporal_noise_shaping_tables::{MAXLAG, TNS_NUMFILTERS_MAX},
};
use core::f64::consts::PI;
use heapless::Vec;
#[allow(unused_imports)]
use num_traits::real::Real;
use super::side_info::Bandwidth;
pub fn apply_temporal_noise_shaping(
duration: FrameDuration,
bandwidth: Bandwidth,
num_tns_filters: usize,
reflect_coef_order: &[usize],
reflect_coef_ints: &[usize],
spec_lines: &mut [Scaler],
) {
let mut bands = split_into_frequency_bands(duration, bandwidth, spec_lines);
let mut rc_quant: [Scaler; TNS_NUMFILTERS_MAX * MAXLAG] = [0.0; TNS_NUMFILTERS_MAX * MAXLAG];
const QUANTIZER_STEPSIZE: Scaler = (PI / 17.0) as Scaler;
for (rc_q_item, rc_i_item) in rc_quant.iter_mut().zip(reflect_coef_ints) {
if *rc_i_item != 0 {
*rc_q_item = (QUANTIZER_STEPSIZE * (*rc_i_item as i32 - 8) as Scaler).sin()
}
}
let mut lattice_state = [0.0; 8];
for (f, (band, order)) in bands
.iter_mut()
.zip(reflect_coef_order[..num_tns_filters].iter())
.enumerate()
{
if *order > 0 {
let offset = f * 8;
for spectral_line in band.iter_mut() {
let k = *order - 1;
let mut t = *spectral_line - rc_quant[k + offset] * lattice_state[k];
for k in (0..*order - 1).rev() {
let rc = rc_quant[k + offset];
t -= rc * lattice_state[k];
lattice_state[k + 1] = rc * t + lattice_state[k];
}
*spectral_line = t;
lattice_state[0] = t;
}
}
}
}
fn split_into_frequency_bands(
duration: FrameDuration,
bandwidth: Bandwidth,
spec_lines: &mut [Scaler],
) -> Vec<&mut [Scaler], 2> {
let mut bands: Vec<&mut [Scaler], 2> = Vec::new();
match duration {
FrameDuration::TenMs => match bandwidth {
Bandwidth::NarrowBand => {
bands.push(&mut spec_lines[12..80]).ok();
}
Bandwidth::WideBand => {
bands.push(&mut spec_lines[12..160]).ok();
}
Bandwidth::SemiSuperWideBand => {
bands.push(&mut spec_lines[12..240]).ok();
}
Bandwidth::SuperWideBand => {
let (left, right) = spec_lines.split_at_mut(160);
bands.push(&mut left[12..]).ok();
bands.push(&mut right[..160]).ok();
}
Bandwidth::FullBand => {
let (left, right) = spec_lines.split_at_mut(200);
bands.push(&mut left[12..]).ok();
bands.push(&mut right[..200]).ok();
}
},
FrameDuration::SevenPointFiveMs => match bandwidth {
Bandwidth::NarrowBand => {
bands.push(&mut spec_lines[9..60]).ok();
}
Bandwidth::WideBand => {
bands.push(&mut spec_lines[9..120]).ok();
}
Bandwidth::SemiSuperWideBand => {
bands.push(&mut spec_lines[9..180]).ok();
}
Bandwidth::SuperWideBand => {
let (left, right) = spec_lines.split_at_mut(120);
bands.push(&mut left[9..]).ok();
bands.push(&mut right[..120]).ok();
}
Bandwidth::FullBand => {
let (left, right) = spec_lines.split_at_mut(150);
bands.push(&mut left[9..]).ok();
bands.push(&mut right[..150]).ok();
}
},
};
bands
}
#[cfg(test)]
mod tests {
extern crate std;
use super::*;
use crate::common::config::FrameDuration;
#[test]
fn decode_test() {
let duration = FrameDuration::TenMs;
let bandwidth = Bandwidth::FullBand;
let num_tns_filters = 2;
let reflect_coef_order = [8, 0];
let reflect_coef_ints = [6, 10, 7, 8, 7, 9, 7, 7];
let mut spec_lines: [f32; 400] = [
-568.56555, 1972.808, 3987.5906, 2461.2402, -263.29547, -2949.6724, -2217.0242, 141.18742, 1270.6868,
-385.4035, 1667.538, 568.56555, -538.0386, -1606.4839, 538.0386, -263.29547, -49.60639, 751.7276,
-476.98453, -141.18742, 1423.3219, -2033.862, -599.0926, 202.24144, -934.8897, -202.24144, 324.3495,
1056.9977, -80.1334, 751.7276, 1667.538, -263.29547, 507.51154, 141.18742, 629.61957, -446.45752,
507.51154, -385.4035, 202.24144, -1331.7408, 1453.8489, -385.4035, -49.60639, 141.18742, 0.0, 80.1334,
-488.43216, 183.16206, -122.10804, 0.0, 0.0, 122.10804, -366.32413, -122.10804, -244.21608, -183.16206,
0.0, 61.05402, 0.0, -427.37814, -244.21608, -671.59424, -427.37814, -366.32413, 0.0, 183.16206, 610.5402,
122.10804, 549.4862, 183.16206, 427.37814, -122.10804, 122.10804, -122.10804, -61.05402, -61.05402, 0.0,
0.0, 0.0, 0.0, 61.05402, 244.21608, -61.05402, -61.05402, -61.05402, 122.10804, 61.05402, 183.16206,
183.16206, 61.05402, -122.10804, -122.10804, 61.05402, 305.2701, 122.10804, -122.10804, -305.2701,
-244.21608, -122.10804, 0.0, 0.0, 0.0, -61.05402, 61.05402, -61.05402, 61.05402, 61.05402, 61.05402,
-61.05402, -183.16206, -61.05402, 61.05402, 183.16206, 0.0, 0.0, 61.05402, 122.10804, -61.05402, -61.05402,
61.05402, 122.10804, 122.10804, 61.05402, 122.10804, 0.0, -122.10804, -183.16206, 0.0, 183.16206,
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,
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,
-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,
0.0, 61.05402, 122.10804, 0.0, -61.05402, 0.0, 61.05402, 0.0, 61.05402, 0.0, 61.05402, -61.05402,
-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,
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,
-61.05402, 61.05402, 122.10804, -61.05402, 0.0, 122.10804, 0.0, 61.05402, -61.05402, 0.0, 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, -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, 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, 0.0, -61.05402, 0.0,
0.0, -61.05402, 61.05402, 61.05402, 61.05402, -122.10804, -61.05402, -61.05402, 0.0, 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, 61.05402, 0.0, 0.0,
0.0, 61.05402, 61.05402, 0.0, -61.05402, -61.05402, 0.0, -61.05402, 0.0, -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, 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, 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, -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, 0.0, 0.0, -19.079382,
-19.079382, -19.079382, -19.079382, 19.079382, -19.079382, 19.079382, 0.0, 0.0, 0.0, -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, -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,
];
apply_temporal_noise_shaping(
duration,
bandwidth,
num_tns_filters,
&reflect_coef_order,
&reflect_coef_ints,
&mut spec_lines,
);
#[rustfmt::skip]
let spec_lines_expected: [f32; 400] = [
-568.56555, 1972.808, 3987.5906, 2461.2402, -263.29547, -2949.6724, -2217.0242, 141.18742, 1270.6868,
-385.4035, 1667.538, 568.56555, -538.0386, -1924.9376, -330.6227, 358.01404, -103.25958, 640.72064,
-380.6663, -565.7268, 1425.4789, -1620.2815, -2171.777, 65.41626, -630.4777, -241.61359, 70.17501,
648.6986, 913.1724, 377.05695, 1248.8955, 447.55414, 122.224335, 387.0873, 670.9608, 202.11314, 470.52597,
9.777176, 250.14848, -869.4124, 705.27844, 764.594, -196.6836, 162.10555, 32.383907, 212.68384, -200.68219,
-385.05658, 74.749176, 244.4491, 75.39133, 71.7427, -370.58853, -284.1499, -221.86317, -378.81683,
-78.224205, 120.7565, 49.39573, -431.70422, -639.2284, -863.50916, -762.39795, -557.4247, -210.2326,
207.37712, 667.06, 268.28708, 266.76526, 180.27934, 266.1345, 18.510933, -71.35217, -18.678001, 61.719135,
78.072945, 41.07525, 31.682747, 65.34431, 39.83117, 50.713173, 265.0006, 87.029144, -105.01486, -92.9501,
109.07149, 213.51758, 237.69977, 244.04578, 169.18098, -60.653255, -202.20692, -5.709038, 418.32336,
390.42206, -52.63867, -409.54736, -371.99884, -123.08209, 15.460239, -13.179712, 10.579021, 10.312677,
49.179047, -104.04299, -108.42853, 45.232265, 106.2404, -18.412956, -252.0934, -189.36148, 85.68147,
260.1948, 66.20917, -89.14935, 37.372047, 196.89316, 4.2800827, -186.45068, -10.664055, 251.7307,
283.97842, 87.595795, 65.05641, 91.597, -64.72161, -260.67474, -120.33, 275.7829, 360.36444, 76.64067,
-85.21214, -19.708641, 59.083878, 71.03325, 37.62242, 41.2656, 33.881153, 25.94694, -3.6607666, -15.336594,
-46.333282, -68.63583, 51.637062, 181.11745, 75.242294, -25.19682, -26.834858, 23.40418, 38.82212,
-11.055281, -14.305193, -22.998611, 129.22333, 87.56438, -91.969635, -113.919846, -21.006641, 165.25201,
93.82325, 70.90962, 56.982315, 15.586489, -109.50122, -156.43475, -32.77449, 127.61873, 86.515625,
-71.82623, -60.272907, 74.61493, 174.22997, 35.206467, -130.87024, -37.255043, 125.10912, 72.04756,
28.948765, 1.5288572, 89.77242, 28.662163, -122.471275, -64.80139, 35.938797, 56.74036, 19.603413,
-92.18097, -95.45599, 4.2908516, 4.6752024, 39.53695, 19.507534, -69.66742, -24.112461, -4.6465445,
-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,
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,
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,
-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,
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,
0.0, -61.05402, 0.0, 0.0, -61.05402, 61.05402, 61.05402, 61.05402, -122.10804, -61.05402, -61.05402, 0.0,
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, 61.05402, 0.0, 0.0, 0.0, 61.05402, 61.05402, 0.0, -61.05402, -61.05402, 0.0, -61.05402, 0.0,
-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,
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,
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,
-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,
0.0, 0.0, -19.079382, -19.079382, -19.079382, -19.079382, 19.079382, -19.079382, 19.079382, 0.0, 0.0, 0.0,
-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,
-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,
];
assert_eq![spec_lines, spec_lines_expected];
}
}