lc3_codec/common/
dct_iv.rs

1use core::f64::consts::PI;
2
3use super::{
4    complex::{Complex, Scaler},
5    config::Lc3Config,
6    kissfft::KissFastFourierTransform,
7};
8
9// for cos and sin
10#[allow(unused_imports)]
11use num_traits::real::Real;
12
13pub struct DiscreteCosTransformIv<'a> {
14    nf: usize,
15    fft: KissFastFourierTransform<'a>,
16    input: &'a mut [Complex],
17    output: &'a mut [Complex],
18    twiddle: &'a [Complex],
19}
20
21impl<'a> DiscreteCosTransformIv<'a> {
22    pub fn new(nf: usize, complex_buf: &'a mut [Complex]) -> (Self, &'a mut [Complex]) {
23        let count = nf / 2;
24        let (fft, complex_buf) = KissFastFourierTransform::new(count, false, complex_buf);
25
26        let (input, complex_buf) = complex_buf.split_at_mut(count);
27        let (output, complex_buf) = complex_buf.split_at_mut(count);
28        let (twiddle, complex_buf) = complex_buf.split_at_mut(count);
29
30        for (i, tw) in twiddle.iter_mut().enumerate() {
31            let temp: f64 = -PI * (8 * i + 1) as f64 / (8. * (count as f64) * 2.);
32            let re = temp.cos() as Scaler;
33            let im = temp.sin() as Scaler;
34            *tw = Complex::new(re, im)
35        }
36
37        (
38            Self {
39                fft,
40                input,
41                output,
42                twiddle,
43                nf,
44            },
45            complex_buf,
46        )
47    }
48
49    pub fn run(&mut self, buf: &mut [Scaler]) {
50        assert_eq!(buf.len(), self.nf);
51
52        // 0.183 ms - twiddle and input are nf / 2 in length
53        for (n, (input_n, twiddle_n)) in self.input.iter_mut().zip(self.twiddle.iter()).enumerate() {
54            let complex = Complex::new(buf[2 * n] as Scaler, buf[self.nf - 2 * n - 1] as Scaler);
55            *input_n = *twiddle_n * complex;
56        }
57
58        // 1.068 ms
59        self.fft.transform(self.input, self.output);
60
61        //  0.244 ms
62        for (n, (output_n, twiddle_n)) in self.output.iter().zip(self.twiddle.iter()).enumerate() {
63            let complex = *twiddle_n * *output_n;
64            buf[2 * n] = complex.r * 2.0;
65            buf[self.nf - 2 * n - 1] = -complex.i * 2.0;
66        }
67    }
68
69    pub const fn calc_working_buffer_length(config: &Lc3Config) -> usize {
70        config.nf / 2 * 4
71    }
72}
73
74#[cfg(test)]
75mod tests {
76    extern crate std;
77    use super::*;
78
79    #[test]
80    fn mdct_iv_run() {
81        #[rustfmt::skip]
82        let mut buf = [
83            -1151.1439, -1112.3599, -1085.3574, -1077.8644, -1070.7073, -1059.7205, -1051.5808, -1039.1353,
84            -1016.79926, -985.77637, -937.9641, -872.2066, -804.987, -735.0268, -645.5973, -540.59094, -445.7364,
85            -379.97342, -329.78387, -287.61658, -248.73645, -194.97568, -132.01953, -87.83206, -59.05179, -21.33966,
86            28.456268, 75.12015, 104.14502, 126.35922, 163.03879, 207.7316, 244.9042, 280.17496, 329.70657, 384.692,
87            429.06854, 468.5974, 507.30542, 538.7573, 555.2137, 559.3202, 549.44965, 517.106, 470.24667, 421.52972,
88            378.42108, 328.0757, 261.8973, 204.63681, 169.20972, 133.6887, 89.40567, 45.5087, 1.8208256, -51.57547,
89            -116.857216, -181.88756, -228.51405, -253.13322, -270.69318, -293.7555, -291.11374, -263.67313, -257.9944,
90            -271.16644, -284.35455, -300.54276, -318.74222, -330.98096, -324.272, -293.57587, -253.82837, -217.01317,
91            -200.1537, -184.26631, -161.3379, -154.41936, -154.51157, -145.56474, -145.64432, -166.82468, -187.01743,
92            -190.12439, -182.15967, -163.10861, -137.99463, -114.87286, -107.85967, -126.04913, -160.38882, -204.83882,
93            -259.40686, -319.0512, -373.67438, -419.2287, -448.63275, -457.83063, -452.87408, -458.0198, -481.36447,
94            -512.8027, -544.24536, -578.726, -619.2813, -668.94806, -717.6076, -744.00006, -733.9459, -694.5221,
95            -637.87317, -558.9336, -463.77808, -383.7987, -320.0128, -256.2199, -192.42207, -125.582275, -56.71489,
96            -0.0, 62.790855, 137.73273, 208.62027, 279.5032, 362.53262, 450.61743, 520.467, 585.2453, 664.1902,
97            745.1488, 830.1458, 925.25323, 1026.4205, 1129.5961, 1227.6956, 1325.7788, 1435.9908, 1546.1846, 1640.1724,
98            1724.0271, 1813.9401, 1906.873, 2000.8048, 2095.7344, 2176.493, 2240.0476, 2294.496, 2338.8267, 2363.9446,
99            2369.8525, 2365.655, 2357.418, 2345.1448, 2326.812, 2306.466, 2282.0845, 2253.67, 2219.1987, 2187.7695,
100            2137.149, 2042.08, 1954.0955, 1901.4863, 1845.8536, 1762.9521, 1645.7102, 1512.316, 1383.9817, 1268.7894,
101            1184.9191, 1129.3385, 1079.8218, 1027.2783, 966.65656, 882.80615, 777.7468, 661.5806, 528.2468, 384.8168,
102            247.45058, 120.18839, 4.039876, -105.03485, -204.00577, -291.86313, -368.60675, -449.38492, -546.3138,
103            -663.4306, -776.4972, -849.16364, -887.49115, -919.75366, -945.95056, -971.13055, -998.3203, -1033.5762,
104            -1091.0243, -1173.6866, -1263.3905, -1354.0791, -1447.7665, -1546.4689, -1655.2242, -1762.9342, -1858.5024,
105            -1933.867, -1963.8292, -1971.5941, -1992.4425, -2027.3772, -2067.3215, -2084.0703, -2074.6118, -2077.2256,
106            -2099.9563, -2110.5864, -2108.1143, -2111.6667, -2105.144, -2093.5842, -2083.0205, -2058.38, -2024.695,
107            -1971.9304, -1913.1561, -1860.429, -1793.6683, -1712.8892, -1593.0242, -1416.0586, -1230.1669, -1057.4105,
108            -925.83453, -852.4332, -797.09894, -738.7938, -661.50824, -546.2522, -421.0648, -301.95352, -168.92197,
109            -23.981562, 123.86677, 279.61398, 440.2585, 600.8071, 759.2652, 910.64966, 1054.9677, 1210.1713, 1379.2416,
110            1540.2524, 1688.2316, 1853.0662, 2036.7341, 2211.3604, 2359.0437, 2476.8264, 2573.6802, 2656.586,
111            2726.5464, 2772.6436, 2825.6924, 2902.58, 2968.5303, 3027.5256, 3086.5186, 3145.5137, 3219.395, 3266.4854,
112            3291.7568, 3325.9734, 3340.3665, 3350.8147, 3363.2656, 3362.8506, 3351.5532, 3311.5388, 3232.9014,
113            3134.4832, 3040.0652, 2949.6475, 2856.2886, 2757.018, 2654.803, 2570.446, 2490.0732, 2392.8848, 2278.8787,
114            2154.9905, 2031.12, 1907.2666, 1795.3096, 1699.2092, 1598.167, 1485.2521, 1364.4232, 1240.6321, 1114.8663,
115            996.0373, 879.1924, 756.41156, 637.5943, 506.90018, 385.11966, 297.9931, 212.84882, 121.76733, 44.548203,
116            -17.81894, -78.20368, -159.37349, -241.5289, -303.88278, -347.42578, -388.98587, -446.37817, -510.69357,
117            -574.01276, -631.38794, -672.9228, -708.5152, -718.37494, -705.4752, -720.27765, -739.03436, -741.9585,
118            -763.6762, -774.5085, -772.48016, -786.2747, -804.0224, -825.7217, -844.4508, -866.1421, -898.7055,
119            -923.3545, -952.9424, -987.4675, -1007.16284, -1022.9016, -1043.5804, -1054.3751, -1049.3606, -1059.1682,
120            -1069.9648, -1067.9191, -1066.8647, -1028.2771, -951.17645, -877.05005, -796.0218, -709.0786, -632.02167,
121            -567.811, -510.52008, -450.27264, -407.80435, -380.15088, -342.6267, -292.26892, -214.2659, -125.401405,
122            -56.28368, 7.899685, 78.999756, 165.90694, 257.7623, 350.61832, 471.147, 605.52826, 732.03625, 849.68445,
123            941.677, 1019.8661, 1105.0065, 1187.2183, 1265.516, 1339.8994, 1377.733, 1393.8356, 1425.7958, 1457.7892,
124            1485.8596, 1516.9357, 1548.0525, 1579.2103, 1598.5201, 1635.7124, 1684.8588, 1716.2114, 1730.7483,
125            1711.5737, 1675.5337, 1637.5085, 1593.5199, 1539.5785, 1476.664, 1426.6606, 1369.6654, 1293.7024,
126            1195.7439, 1059.7758, 909.6835, 790.3926, 708.957, 623.42126, 520.7512, 416.93396, 297.9144, 177.69846,
127            56.27153, -72.41664, -201.35234, -354.7364, -514.50073, -644.32556, -747.1622, -846.21265, 0.0, 0.0, 0.0,
128            0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
129            0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
130            0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
131        ];
132        #[rustfmt::skip]
133        let output_expected = [
134            134279.8, -192857.94, -24321.12, -19488.932, -140086.0, -173445.83, 354607.28, 333707.97, -534731.2,
135            -225319.13, 115608.06, -34106.453, 24847.12, -50890.566, 40088.67, -88494.59, -106796.29, 24301.7,
136            -41594.426, 35246.684, 3566.0825, 4010.7156, 9450.515, 7043.612, 25580.322, -12644.026, 10708.8,
137            -23169.813, 2657.5105, -3224.439, -13022.397, 7615.456, -7282.2847, 12290.9, -12216.196, -5567.7266,
138            -13677.083, 4075.0027, 9677.127, -6880.005, 16973.074, -6161.1885, 4664.7744, 786.0519, 3567.3757,
139            8139.9155, -8118.442, 2863.6213, 12620.795, 9580.478, -10332.186, 2361.7834, -1185.4126, 5613.147,
140            3286.0688, -6276.6753, 4728.7764, -5407.978, 9487.262, -3964.7568, -3207.2961, 677.737, -3482.7031,
141            3468.6658, -4747.2354, 7553.264, 1077.2087, 2940.6465, -5444.228, -2990.0256, 3689.9841, -5681.706,
142            5117.67, -566.61597, 4100.3433, -1360.1891, 2552.4695, 3759.5542, -2384.3584, -3911.2842, -11678.024,
143            2888.744, -2007.426, 1754.469, -2962.591, -951.4337, 6340.9526, -4058.5715, 2520.5059, -3854.3477,
144            1292.3181, -2600.8745, 405.77042, 2828.9236, -3062.887, 1365.2626, -5680.265, 2964.701, -2238.3647,
145            1542.199, 359.3588, -5297.5386, 3690.2964, -615.3517, 2236.0962, -1866.2739, 1530.4124, 57.729164,
146            -698.58795, 456.72375, -801.3196, 2647.136, -3817.2634, 789.2886, -1270.2273, 1325.1702, 97.41034,
147            -973.451, 2327.5786, -1111.4073, 2407.3682, -2948.4363, 1359.8818, 476.48746, -622.20056, -1836.3676,
148            -1540.9446, 3386.4412, -1706.2571, 1940.293, -2874.5078, 810.76733, 365.78207, -555.44147, 1135.6486,
149            -3028.9243, 2758.37, -3360.7607, 1453.7012, 20.651535, -1344.2458, 871.4512, -2525.1543, 1797.0403,
150            -1009.63477, 2152.4438, -1778.0021, 153.65367, -21.298262, -2046.1221, 521.5571, -2095.9717, 2781.192,
151            -2193.4463, 209.06802, -64.48659, 319.48178, 974.058, -2314.1055, 2035.9204, -1649.1543, 1599.4414,
152            -913.9054, 201.88297, 974.7435, -730.2687, 1544.824, -2347.0889, 1844.2062, -192.4591, 263.73944,
153            -623.37555, -660.52856, 923.87933, -180.29233, 1713.4355, -1572.7996, 697.8552, -1107.4888, 973.8319,
154            264.04266, -867.2302, 1104.9248, -1528.9341, 1461.5837, -1355.1389, 731.19836, -462.1931, -328.72046,
155            218.60495, -1447.4258, 909.68805, -1770.2904, 1568.5381, -970.35706, 47.89151, -379.5102, -974.69055,
156            839.3532, -1789.6791, 1556.8756, -1678.9006, 852.04333, -273.94238, -645.3089, 1241.1493, -871.0111,
157            863.39606, -1612.5491, 1535.1023, -395.382, 284.2515, 280.52936, -718.2119, 806.0485, -1446.5269,
158            1362.3002, -1454.2728, 226.44131, -442.95612, -62.481964, 941.9998, -1256.6742, 1175.601, -673.7061,
159            873.5429, -1273.9908, 554.24646, 331.55685, -794.5202, 836.4542, -1727.5991, 664.07086, -1402.3522,
160            613.0379, -318.773, -245.42827, 867.88354, -865.23364, 1334.9285, -781.3045, 942.71967, -537.3795,
161            515.18286, 39.96443, -443.6733, 1067.8035, -1059.969, 968.45593, -1157.2415, 734.04865, -305.91083,
162            166.25241, 556.5151, -1116.4346, 904.91736, -1402.9304, 949.4951, -873.3258, 377.93643, 235.7786,
163            -762.03326, 706.8014, -1179.781, 1154.1796, -962.5187, 647.1154, -578.2769, -320.19247, 482.26605,
164            -873.5564, 1125.1039, -1183.6094, 999.5639, -761.72754, 302.39154, -11.429527, -677.78906, 846.6859,
165            -1521.4277, 1008.58044, -842.4281, 635.2627, -288.71335, -155.38348, 483.04324, -869.5158, 1242.9233,
166            -1278.4092, 1013.47345, -504.3029, -38.8347, 314.9142, -693.8956, 521.9867, -911.3921, 953.4586, -877.5658,
167            741.8982, -205.44937, 154.66678, 585.34045, -945.2477, 993.062, -1029.3003, 936.89404, -646.115, 234.7078,
168            103.012024, -516.1824, 647.51697, -1183.4977, 1173.4989, -808.34644, 576.38196, -280.01492, -86.85938,
169            433.6588, -948.1439, 1058.1208, -982.5629, 833.92737, -629.3578, 303.54974, 65.002075, -470.8509, 816.7289,
170            -1081.8557, 1098.1157, -1091.2821, 616.04956, -29.062012, -258.1767, 540.5199, -792.38715, 881.3971,
171            -907.85925, 1069.831, -707.43945, 61.462585, 261.32416, -412.4166, 770.306, -1081.4803, 1011.30365,
172            -745.94727, 552.3527, -344.6149, 20.181732, 639.5872, -919.5929, 1047.3007, -1106.7876, 782.7749,
173            -482.9046, 108.289154, 178.94853, -559.4037, 808.773, -924.8269, 906.15314, -771.47284, 572.54205,
174            -206.80208, -215.20123, 503.5349, -619.3348, 897.2041, -1142.1086, 888.94275, -588.21967, 74.00014,
175            231.53099, -531.6199, 791.73645, -907.09546, 864.05054, -801.43274, 626.70276, -206.63289, -166.87213,
176            568.93884, -882.163, 962.2217, -900.864, 679.10846, -507.54388, 187.45087, 230.94904, -557.2191, 730.41205,
177            -787.49915, 861.8645, -812.4855, 514.20074, -182.32861, -161.72064, 476.62347, -723.1917, 805.2969,
178            -912.8767, 829.8983, -542.258, 227.16342, 150.54852, -484.72797, 758.2896, -906.1738, 921.81274,
179            -782.21606, 531.3093, -197.79224, -155.81439, 501.6934, -754.2457, 910.2756, -913.09375, 763.9564,
180            -520.2622, 182.65375, 161.61816, -505.6129, 743.6228, -902.08527, 884.6575, -763.13184, 513.0149,
181            -185.41383, -146.10025, 500.8833, -755.7407, 870.8114, -902.7257, 758.7993, -523.9071, 185.79965, 170.0043,
182            -493.21155, 731.12695, -891.3262, 904.5192, -765.20935, 507.34592, -185.3772, -167.05844, 496.45715,
183            -754.5099, 884.4947, -890.67456, 750.69495, -516.05066, 178.06616, 167.25635, -502.44177, 750.40186,
184            -878.62146, 892.9469, -750.4216, 510.5553, -167.19324, -174.48193, 497.8518, -743.3898, 860.9834,
185            -902.1443, 762.0443, -497.40417, 175.34583, 176.48462, -502.2439, 762.06104, -865.8496, 877.19336,
186            -760.2788, 492.2058, -167.54333, -172.98795, 506.0147, -742.92, 872.8751,
187        ];
188        let mut complex_buf = [Complex::default(); 960];
189        let (mut dct_iv, _) = DiscreteCosTransformIv::new(480, &mut complex_buf);
190
191        dct_iv.run(&mut buf);
192
193        assert_eq!(buf, output_expected);
194    }
195}