1use core::f64::consts::PI;
2
3use super::{
4 complex::{Complex, Scaler},
5 config::Lc3Config,
6 kissfft::KissFastFourierTransform,
7};
8
9#[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 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 self.fft.transform(self.input, self.output);
60
61 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}