Line data Source code
1 : /******************************************************************************
2 : * ETSI TS 103 634 V1.5.1 *
3 : * Low Complexity Communication Codec Plus (LC3plus) *
4 : * *
5 : * Copyright licence is solely granted through ETSI Intellectual Property *
6 : * Rights Policy, 3rd April 2019. No patent licence is granted by implication, *
7 : * estoppel or otherwise. *
8 : ******************************************************************************/
9 :
10 : #include "options.h"
11 : #include "wmc_auto.h"
12 : #include "cfft.h"
13 : #include "iisfft.h" /* for M_PIl */
14 : #include <stdlib.h> /* for abs() */
15 : #include <assert.h>
16 :
17 : #define MAX_FFT_SIZE 1024
18 : #define MAX_TRIGDATA_SIZE (MAX_FFT_SIZE / 2)
19 :
20 : /**
21 : * \brief table aTrigData
22 :
23 : Generate table: aTrigData[i] = sin( pi * i / (2*MAX_TRIGDATA_SIZE) ); i = 0, ... MAX_TRIGDATA_SIZE
24 : */
25 : static const LC3_FLOAT static_table[MAX_TRIGDATA_SIZE + 1] = {
26 : 0.0000000000e+000, 3.0679567717e-003, 6.1358846724e-003, 9.2037543654e-003, 1.2271538377e-002, 1.5339205973e-002,
27 : 1.8406730145e-002, 2.1474080160e-002, 2.4541229010e-002, 2.7608145028e-002, 3.0674804002e-002, 3.3741172403e-002,
28 : 3.6807224154e-002, 3.9872925729e-002, 4.2938258499e-002, 4.6003181487e-002, 4.9067676067e-002, 5.2131704986e-002,
29 : 5.5195245892e-002, 5.8258265257e-002, 6.1320737004e-002, 6.4382627606e-002, 6.7443922162e-002, 7.0504575968e-002,
30 : 7.3564566672e-002, 7.6623864472e-002, 7.9682439566e-002, 8.2740262151e-002, 8.5797309875e-002, 8.8853552938e-002,
31 : 9.1908954084e-002, 9.4963498414e-002, 9.8017141223e-002, 1.0106986016e-001, 1.0412163287e-001, 1.0717242211e-001,
32 : 1.1022220552e-001, 1.1327095330e-001, 1.1631862819e-001, 1.1936521530e-001, 1.2241067737e-001, 1.2545497715e-001,
33 : 1.2849810719e-001, 1.3154003024e-001, 1.3458070159e-001, 1.3762012124e-001, 1.4065824449e-001, 1.4369502664e-001,
34 : 1.4673046768e-001, 1.4976453781e-001, 1.5279719234e-001, 1.5582840145e-001, 1.5885815024e-001, 1.6188639402e-001,
35 : 1.6491311789e-001, 1.6793829203e-001, 1.7096188664e-001, 1.7398387194e-001, 1.7700421810e-001, 1.8002289534e-001,
36 : 1.8303988874e-001, 1.8605515361e-001, 1.8906866014e-001, 1.9208039343e-001, 1.9509032369e-001, 1.9809840620e-001,
37 : 2.0110464096e-001, 2.0410896838e-001, 2.0711137354e-001, 2.1011184156e-001, 2.1311031282e-001, 2.1610680223e-001,
38 : 2.1910123527e-001, 2.2209362686e-001, 2.2508391738e-001, 2.2807207704e-001, 2.3105810583e-001, 2.3404195905e-001,
39 : 2.3702360690e-001, 2.4000301957e-001, 2.4298018217e-001, 2.4595504999e-001, 2.4892760813e-001, 2.5189781189e-001,
40 : 2.5486564636e-001, 2.5783109665e-001, 2.6079410315e-001, 2.6375466585e-001, 2.6671275496e-001, 2.6966831088e-001,
41 : 2.7262136340e-001, 2.7557182312e-001, 2.7851969004e-001, 2.8146493435e-001, 2.8440752625e-001, 2.8734746575e-001,
42 : 2.9028466344e-001, 2.9321914911e-001, 2.9615089297e-001, 2.9907983541e-001, 3.0200594664e-001, 3.0492922664e-001,
43 : 3.0784964561e-001, 3.1076714396e-001, 3.1368175149e-001, 3.1659337878e-001, 3.1950202584e-001, 3.2240769267e-001,
44 : 3.2531028986e-001, 3.2820984721e-001, 3.3110630512e-001, 3.3399966359e-001, 3.3688986301e-001, 3.3977687359e-001,
45 : 3.4266072512e-001, 3.4554132819e-001, 3.4841868281e-001, 3.5129275918e-001, 3.5416352749e-001, 3.5703095794e-001,
46 : 3.5989505053e-001, 3.6275571585e-001, 3.6561298370e-001, 3.6846682429e-001, 3.7131720781e-001, 3.7416407466e-001,
47 : 3.7700742483e-001, 3.7984719872e-001, 3.8268342614e-001, 3.8551604748e-001, 3.8834503293e-001, 3.9117038250e-001,
48 : 3.9399203658e-001, 3.9680999517e-001, 3.9962419868e-001, 4.0243464708e-001, 4.0524131060e-001, 4.0804415941e-001,
49 : 4.1084316373e-001, 4.1363832355e-001, 4.1642954946e-001, 4.1921690106e-001, 4.2200025916e-001, 4.2477968335e-001,
50 : 4.2755508423e-001, 4.3032649159e-001, 4.3309381604e-001, 4.3585708737e-001, 4.3861624599e-001, 4.4137126207e-001,
51 : 4.4412213564e-001, 4.4686883688e-001, 4.4961133599e-001, 4.5234957337e-001, 4.5508357882e-001, 4.5781329274e-001,
52 : 4.6053871512e-001, 4.6325978637e-001, 4.6597650647e-001, 4.6868881583e-001, 4.7139674425e-001, 4.7410020232e-001,
53 : 4.7679921985e-001, 4.7949376702e-001, 4.8218378425e-001, 4.8486924171e-001, 4.8755016923e-001, 4.9022647738e-001,
54 : 4.9289819598e-001, 4.9556526542e-001, 4.9822765589e-001, 5.0088536739e-001, 5.0353837013e-001, 5.0618666410e-001,
55 : 5.0883013010e-001, 5.1146882772e-001, 5.1410275698e-001, 5.1673179865e-001, 5.1935601234e-001, 5.2197527885e-001,
56 : 5.2458965778e-001, 5.2719914913e-001, 5.2980363369e-001, 5.3240311146e-001, 5.3499764204e-001, 5.3758704662e-001,
57 : 5.4017144442e-001, 5.4275077581e-001, 5.4532498121e-001, 5.4789406061e-001, 5.5045795441e-001, 5.5301672220e-001,
58 : 5.5557024479e-001, 5.5811852217e-001, 5.6066155434e-001, 5.6319934130e-001, 5.6573182344e-001, 5.6825894117e-001,
59 : 5.7078075409e-001, 5.7329714298e-001, 5.7580816746e-001, 5.7831376791e-001, 5.8081394434e-001, 5.8330863714e-001,
60 : 5.8579784632e-001, 5.8828157187e-001, 5.9075969458e-001, 5.9323227406e-001, 5.9569931030e-001, 5.9816068411e-001,
61 : 6.0061645508e-001, 6.0306662321e-001, 6.0551106930e-001, 6.0794979334e-001, 6.1038279533e-001, 6.1281007528e-001,
62 : 6.1523157358e-001, 6.1764729023e-001, 6.2005722523e-001, 6.2246125937e-001, 6.2485951185e-001, 6.2725180387e-001,
63 : 6.2963825464e-001, 6.3201874495e-001, 6.3439327478e-001, 6.3676184416e-001, 6.3912445307e-001, 6.4148104191e-001,
64 : 6.4383155107e-001, 6.4617604017e-001, 6.4851438999e-001, 6.5084666014e-001, 6.5317285061e-001, 6.5549284220e-001,
65 : 6.5780669451e-001, 6.6011434793e-001, 6.6241580248e-001, 6.6471099854e-001, 6.6699993610e-001, 6.6928261518e-001,
66 : 6.7155897617e-001, 6.7382901907e-001, 6.7609268427e-001, 6.7835003138e-001, 6.8060100079e-001, 6.8284553289e-001,
67 : 6.8508368731e-001, 6.8731534481e-001, 6.8954056501e-001, 6.9175922871e-001, 6.9397145510e-001, 6.9617712498e-001,
68 : 6.9837623835e-001, 7.0056879520e-001, 7.0275473595e-001, 7.0493406057e-001, 7.0710676908e-001, 7.0927280188e-001,
69 : 7.1143221855e-001, 7.1358484030e-001, 7.1573084593e-001, 7.1787005663e-001, 7.2000253201e-001, 7.2212821245e-001,
70 : 7.2424709797e-001, 7.2635912895e-001, 7.2846436501e-001, 7.3056274652e-001, 7.3265427351e-001, 7.3473888636e-001,
71 : 7.3681658506e-001, 7.3888731003e-001, 7.4095112085e-001, 7.4300795794e-001, 7.4505776167e-001, 7.4710059166e-001,
72 : 7.4913638830e-001, 7.5116515160e-001, 7.5318682194e-001, 7.5520139933e-001, 7.5720882416e-001, 7.5920921564e-001,
73 : 7.6120239496e-001, 7.6318842173e-001, 7.6516723633e-001, 7.6713889837e-001, 7.6910334826e-001, 7.7106052637e-001,
74 : 7.7301043272e-001, 7.7495312691e-001, 7.7688848972e-001, 7.7881652117e-001, 7.8073722124e-001, 7.8265058994e-001,
75 : 7.8455656767e-001, 7.8645521402e-001, 7.8834640980e-001, 7.9023021460e-001, 7.9210656881e-001, 7.9397547245e-001,
76 : 7.9583692551e-001, 7.9769086838e-001, 7.9953724146e-001, 8.0137616396e-001, 8.0320751667e-001, 8.0503135920e-001,
77 : 8.0684757233e-001, 8.0865615606e-001, 8.1045717001e-001, 8.1225061417e-001, 8.1403630972e-001, 8.1581443548e-001,
78 : 8.1758481264e-001, 8.1934750080e-001, 8.2110249996e-001, 8.2284981012e-001, 8.2458931208e-001, 8.2632106543e-001,
79 : 8.2804507017e-001, 8.2976120710e-001, 8.3146959543e-001, 8.3317017555e-001, 8.3486288786e-001, 8.3654773235e-001,
80 : 8.3822470903e-001, 8.3989381790e-001, 8.4155499935e-001, 8.4320825338e-001, 8.4485358000e-001, 8.4649091959e-001,
81 : 8.4812033176e-001, 8.4974175692e-001, 8.5135519505e-001, 8.5296058655e-001, 8.5455799103e-001, 8.5614734888e-001,
82 : 8.5772860050e-001, 8.5930180550e-001, 8.6086696386e-001, 8.6242395639e-001, 8.6397284269e-001, 8.6551362276e-001,
83 : 8.6704623699e-001, 8.6857068539e-001, 8.7008696795e-001, 8.7159508467e-001, 8.7309497595e-001, 8.7458664179e-001,
84 : 8.7607008219e-001, 8.7754529715e-001, 8.7901222706e-001, 8.8047087193e-001, 8.8192129135e-001, 8.8336336613e-001,
85 : 8.8479709625e-001, 8.8622254133e-001, 8.8763964176e-001, 8.8904833794e-001, 8.9044874907e-001, 8.9184069633e-001,
86 : 8.9322429895e-001, 8.9459949732e-001, 8.9596623182e-001, 8.9732456207e-001, 8.9867448807e-001, 9.0001589060e-001,
87 : 9.0134882927e-001, 9.0267330408e-001, 9.0398931503e-001, 9.0529674292e-001, 9.0659570694e-001, 9.0788608789e-001,
88 : 9.0916800499e-001, 9.1044127941e-001, 9.1170603037e-001, 9.1296219826e-001, 9.1420978308e-001, 9.1544872522e-001,
89 : 9.1667908430e-001, 9.1790080070e-001, 9.1911387444e-001, 9.2031830549e-001, 9.2151403427e-001, 9.2270112038e-001,
90 : 9.2387950420e-001, 9.2504924536e-001, 9.2621022463e-001, 9.2736250162e-001, 9.2850607634e-001, 9.2964088917e-001,
91 : 9.3076694012e-001, 9.3188428879e-001, 9.3299281597e-001, 9.3409252167e-001, 9.3518352509e-001, 9.3626564741e-001,
92 : 9.3733900785e-001, 9.3840354681e-001, 9.3945920467e-001, 9.4050604105e-001, 9.4154405594e-001, 9.4257318974e-001,
93 : 9.4359344244e-001, 9.4460481405e-001, 9.4560730457e-001, 9.4660091400e-001, 9.4758558273e-001, 9.4856137037e-001,
94 : 9.4952815771e-001, 9.5048606396e-001, 9.5143502951e-001, 9.5237499475e-001, 9.5330601931e-001, 9.5422810316e-001,
95 : 9.5514118671e-001, 9.5604526997e-001, 9.5694035292e-001, 9.5782643557e-001, 9.5870345831e-001, 9.5957154036e-001,
96 : 9.6043050289e-001, 9.6128046513e-001, 9.6212142706e-001, 9.6295326948e-001, 9.6377605200e-001, 9.6458977461e-001,
97 : 9.6539443731e-001, 9.6618998051e-001, 9.6697646379e-001, 9.6775382757e-001, 9.6852207184e-001, 9.6928125620e-001,
98 : 9.7003126144e-001, 9.7077214718e-001, 9.7150391340e-001, 9.7222650051e-001, 9.7293996811e-001, 9.7364425659e-001,
99 : 9.7433936596e-001, 9.7502535582e-001, 9.7570210695e-001, 9.7636973858e-001, 9.7702813148e-001, 9.7767734528e-001,
100 : 9.7831737995e-001, 9.7894817591e-001, 9.7956979275e-001, 9.8018211126e-001, 9.8078525066e-001, 9.8137921095e-001,
101 : 9.8196387291e-001, 9.8253929615e-001, 9.8310548067e-001, 9.8366242647e-001, 9.8421007395e-001, 9.8474848270e-001,
102 : 9.8527765274e-001, 9.8579752445e-001, 9.8630809784e-001, 9.8680937290e-001, 9.8730140924e-001, 9.8778414726e-001,
103 : 9.8825758696e-001, 9.8872166872e-001, 9.8917651176e-001, 9.8962199688e-001, 9.9005818367e-001, 9.9048507214e-001,
104 : 9.9090266228e-001, 9.9131083488e-001, 9.9170976877e-001, 9.9209928513e-001, 9.9247956276e-001, 9.9285042286e-001,
105 : 9.9321192503e-001, 9.9356412888e-001, 9.9390697479e-001, 9.9424046278e-001, 9.9456459284e-001, 9.9487930536e-001,
106 : 9.9518471956e-001, 9.9548077583e-001, 9.9576741457e-001, 9.9604469538e-001, 9.9631261826e-001, 9.9657112360e-001,
107 : 9.9682027102e-001, 9.9706006050e-001, 9.9729043245e-001, 9.9751144648e-001, 9.9772304296e-001, 9.9792528152e-001,
108 : 9.9811810255e-001, 9.9830156565e-001, 9.9847555161e-001, 9.9864023924e-001, 9.9879544973e-001, 9.9894130230e-001,
109 : 9.9907773733e-001, 9.9920475483e-001, 9.9932235479e-001, 9.9943059683e-001, 9.9952942133e-001, 9.9961882830e-001,
110 : 9.9969881773e-001, 9.9976938963e-001, 9.9983060360e-001, 9.9988234043e-001, 9.9992471933e-001, 9.9995762110e-001,
111 : 9.9998116493e-001, 9.9999529123e-001, 1.0000000000e+000};
112 :
113 : /**
114 : * \brief scramble
115 : The function sorts the complex vector re/im of length n from 'in-order' to 'bitreversed order'.
116 :
117 : * \param[i/o] re: real input
118 : * \param[i/o] im: imag input
119 : * \param[i ] n: size of fft
120 : * \param[i ] s: stride of real and imag input
121 :
122 : * \return none
123 : */
124 0 : static void scramble(LC3_FLOAT* re, LC3_FLOAT* im, LC3_INT n, LC3_INT s)
125 : {
126 : LC3_FLOAT tmp;
127 : LC3_INT m, k, j;
128 :
129 0 : for (m = 1, j = 0; m < (n - 1); m++) {
130 : {
131 0 : for (k = n >> 1; (!((j ^= k) & k)); k >>= 1)
132 : ;
133 : }
134 :
135 0 : if (j > m) {
136 0 : tmp = re[s * m];
137 0 : re[s * m] = re[s * j];
138 0 : re[s * j] = tmp;
139 :
140 0 : tmp = im[s * m];
141 0 : im[s * m] = im[s * j];
142 0 : im[s * j] = tmp;
143 : }
144 : }
145 0 : }
146 :
147 : /**
148 : * \brief fft
149 : The function performs a radix-2, decimation in time complex fft. The calculation takes place inplace.
150 : The real and imaginary part can reside in separate buffers as well as interleaved in one buffer. The
151 : stride length has to be set accordingly.
152 :
153 : * \param[i/o] re: real input / real output
154 : * \param[i/o] im: imag input / imag output
155 : * \param[i ] sizeOfFft: size of fft
156 : * \param[i ] s: stride of real and imag input / output
157 :
158 : * \return none
159 : */
160 0 : static void fft(const LC3_FLOAT* aTrigData, LC3_INT trigdata_size, LC3_FLOAT* re, LC3_FLOAT* im, LC3_INT sizeOfFft,
161 : LC3_INT s)
162 : {
163 : LC3_INT trigstep, i, ldm, n;
164 : LC3_INT trigDataSize;
165 0 : LC3_INT ldn = 0;
166 :
167 0 : trigDataSize = sizeOfFft / 2;
168 :
169 0 : while (sizeOfFft >>= 1) {
170 0 : ldn++;
171 : }
172 :
173 0 : n = 1 << ldn;
174 :
175 0 : scramble(re, im, n, s);
176 :
177 : /* 1+2 stage implemented as radix 4 */
178 0 : for (i = 0; i < n; i += 4) {
179 : LC3_FLOAT a00, a01, a10, a11;
180 : LC3_FLOAT a20, a21, a30, a31;
181 :
182 0 : a00 = re[s * (i + 0)] + re[s * (i + 1)];
183 0 : a10 = re[s * (i + 2)] + re[s * (i + 3)];
184 0 : a20 = im[s * (i + 0)] + im[s * (i + 1)];
185 0 : a30 = im[s * (i + 2)] + im[s * (i + 3)];
186 :
187 0 : a01 = re[s * (i + 0)] - re[s * (i + 1)];
188 0 : a21 = re[s * (i + 2)] - re[s * (i + 3)];
189 0 : a31 = im[s * (i + 0)] - im[s * (i + 1)];
190 0 : a11 = im[s * (i + 2)] - im[s * (i + 3)];
191 :
192 0 : re[s * (i + 0)] = a00 + a10;
193 0 : re[s * (i + 2)] = a00 - a10;
194 0 : im[s * (i + 0)] = a20 + a30;
195 0 : im[s * (i + 2)] = a20 - a30;
196 0 : re[s * (i + 1)] = a11 + a01;
197 0 : re[s * (i + 3)] = a01 - a11;
198 0 : im[s * (i + 1)] = a31 - a21;
199 0 : im[s * (i + 3)] = a21 + a31;
200 : }
201 :
202 : /* next stages implemented as radix 2 */
203 0 : for (ldm = 3; ldm <= ldn; ++ldm) {
204 0 : const LC3_INT m = (1 << ldm);
205 0 : const LC3_INT mh = (m >> 1);
206 : LC3_INT j, r;
207 :
208 0 : trigstep = ((trigDataSize * 4) >> ldm) * trigdata_size / trigDataSize;
209 :
210 0 : for (j = 0; j < mh / 2; ++j) {
211 : LC3_FLOAT c1, c2;
212 :
213 0 : c2 = aTrigData[j * trigstep];
214 0 : c1 = aTrigData[trigdata_size - j * trigstep];
215 :
216 0 : for (r = 0; r < n; r += m) {
217 : LC3_FLOAT vr, vi, ur, ui;
218 :
219 0 : LC3_INT t0 = r + j;
220 0 : LC3_INT t1 = s * t0;
221 0 : LC3_INT t2 = s * (t0 + mh);
222 :
223 0 : vr = re[t2] * c1 + im[t2] * c2;
224 0 : vi = -re[t2] * c2 + im[t2] * c1;
225 :
226 0 : ur = re[t1];
227 0 : ui = im[t1];
228 :
229 0 : re[t1] = re[t1] + vr;
230 0 : im[t1] = im[t1] + vi;
231 :
232 0 : re[t2] = ur - vr;
233 0 : im[t2] = ui - vi;
234 :
235 0 : t0 = r + j + mh / 2;
236 0 : t1 = s * t0;
237 0 : t2 = s * (t0 + mh);
238 :
239 0 : vr = -re[t2] * c2 + im[t2] * c1;
240 0 : vi = -re[t2] * c1 - im[t2] * c2;
241 :
242 0 : ur = re[t1];
243 0 : ui = im[t1];
244 0 : re[t1] = re[t1] + vr;
245 0 : im[t1] = im[t1] + vi;
246 :
247 0 : re[t2] = ur - vr;
248 0 : im[t2] = ui - vi;
249 : }
250 : }
251 : }
252 0 : }
253 :
254 : /**
255 : * \brief ifft
256 : The function performs a radix-2, decimation in time complex inverse fft. The calculation takes place
257 : inplace. The real and imaginary part can reside in separate buffers as well as interleaved in one buffer.
258 : The stride length has to be set accordingly.
259 :
260 : * \param[i/o] re: real input / real output
261 : * \param[i/o] im: imag input / imag output
262 : * \param[i ] sizeOfFft: size of fft
263 : * \param[i ] s: stride of real and imag input / output
264 :
265 : * \return none
266 : */
267 0 : static void ifft(const LC3_FLOAT* aTrigData, LC3_INT trigdata_size, LC3_FLOAT* re, LC3_FLOAT* im, LC3_INT sizeOfFft,
268 : LC3_INT s)
269 : {
270 : LC3_INT trigstep, i, ldm, n;
271 : LC3_INT trigDataSize;
272 0 : LC3_INT ldn = 0;
273 :
274 0 : trigDataSize = sizeOfFft;
275 :
276 0 : while (sizeOfFft >>= 1) {
277 0 : ldn++;
278 : }
279 :
280 0 : n = 1 << ldn;
281 :
282 0 : scramble(re, im, n, s);
283 :
284 : /* 1+2 stage radix 4 */
285 0 : for (i = 0; i < n; i += 4) {
286 : LC3_FLOAT a00, a01, a10, a11;
287 : LC3_FLOAT a20, a21, a30, a31;
288 :
289 0 : a00 = re[s * (i + 0)] + re[s * (i + 1)];
290 0 : a10 = re[s * (i + 2)] + re[s * (i + 3)];
291 0 : a20 = im[s * (i + 0)] + im[s * (i + 1)];
292 0 : a30 = im[s * (i + 2)] + im[s * (i + 3)];
293 :
294 0 : a01 = re[s * (i + 0)] - re[s * (i + 1)];
295 0 : a21 = re[s * (i + 2)] - re[s * (i + 3)];
296 0 : a31 = im[s * (i + 0)] - im[s * (i + 1)];
297 0 : a11 = im[s * (i + 2)] - im[s * (i + 3)];
298 :
299 0 : re[s * (i + 0)] = a00 + a10;
300 0 : re[s * (i + 2)] = a00 - a10;
301 0 : im[s * (i + 0)] = a20 + a30;
302 0 : im[s * (i + 2)] = a20 - a30;
303 :
304 0 : re[s * (i + 1)] = a01 - a11;
305 0 : re[s * (i + 3)] = a01 + a11;
306 0 : im[s * (i + 1)] = a31 + a21;
307 0 : im[s * (i + 3)] = a31 - a21;
308 : }
309 :
310 0 : for (ldm = 3; ldm <= ldn; ++ldm) {
311 0 : const LC3_INT m = (1 << ldm);
312 0 : const LC3_INT mh = (m >> 1);
313 : LC3_INT j, r;
314 :
315 0 : trigstep = ((trigDataSize * 4) >> ldm) * trigdata_size / trigDataSize;
316 :
317 0 : for (j = 0; j < mh / 2; ++j) {
318 : LC3_FLOAT c1, c2;
319 :
320 0 : c2 = aTrigData[j * trigstep];
321 0 : c1 = aTrigData[trigdata_size - j * trigstep];
322 :
323 0 : for (r = 0; r < n; r += m) {
324 : LC3_FLOAT vr, vi, ur, ui;
325 :
326 0 : LC3_INT t0 = r + j;
327 0 : LC3_INT t1 = s * t0;
328 0 : LC3_INT t2 = s * (t0 + mh);
329 :
330 0 : vr = re[t2] * c1 - im[t2] * c2;
331 0 : vi = re[t2] * c2 + im[t2] * c1;
332 :
333 0 : ur = re[t1];
334 0 : ui = im[t1];
335 :
336 0 : re[t1] = ur + vr;
337 0 : im[t1] = ui + vi;
338 :
339 0 : re[t2] = ur - vr;
340 0 : im[t2] = ui - vi;
341 :
342 0 : t0 = r + j + mh / 2;
343 0 : t1 = s * t0;
344 0 : t2 = s * (t0 + mh);
345 :
346 0 : vr = -re[t2] * c2 - im[t2] * c1;
347 0 : vi = re[t2] * c1 - im[t2] * c2;
348 :
349 0 : ur = re[t1];
350 0 : ui = im[t1];
351 :
352 0 : re[t1] = ur + vr;
353 0 : im[t1] = ui + vi;
354 0 : re[t2] = ur - vr;
355 0 : im[t2] = ui - vi;
356 : }
357 : }
358 : }
359 0 : }
360 :
361 : /**
362 : * \brief cfft
363 : The function serves as wrapper for the forward and inverse fft.
364 :
365 : * \param[i/o] re: real input / real output
366 : * \param[i/o] im: imag input / imag output
367 : * \param[i ] sizeOfFft: size of fft
368 : * \param[i ] s: stride of real and imag input / output
369 : * \param[i ] iSign: forward fft: -1 / inverse fft: 1
370 :
371 : * \return none
372 : */
373 0 : void LC3_cfft(LC3_FLOAT* re, LC3_FLOAT* im, LC3_INT length, LC3_INT stride, LC3_INT sign)
374 : {
375 0 : assert(abs(sign) == 1);
376 0 : assert(CFFT_SUPPORT(length));
377 :
378 0 : if (sign == -1) {
379 0 : fft(static_table, MAX_TRIGDATA_SIZE, re, im, length, stride);
380 : } else {
381 0 : ifft(static_table, MAX_TRIGDATA_SIZE, re, im, length, stride);
382 : }
383 0 : }
384 :
385 0 : LC3_INT LC3_cfft_plan(Cfft* handle, LC3_INT length, LC3_INT sign)
386 : {
387 : /* check if length is power of two */
388 0 : if (!CFFT_PLAN_SUPPORT(length) || (abs(sign) != 1))
389 : {
390 0 : return 0;
391 : }
392 :
393 0 : handle->len = length;
394 0 : handle->sign = sign;
395 :
396 0 : if (length <= MAX_FFT_SIZE) {
397 0 : handle->table = NULL;
398 : } else {
399 0 : LC3_INT i = 0;
400 0 : handle->table = (LC3_FLOAT*)malloc((length / 2 + 1) * sizeof(LC3_FLOAT));
401 0 : for (i = 0; i < length / 2 + 1; i++) {
402 0 : handle->table[i] = (LC3_FLOAT)LC3_SIN((LC3_FLOAT)M_PIl * i / length);
403 : }
404 : }
405 0 : return 1;
406 : }
407 :
408 0 : void LC3_cfft_apply(Cfft* handle, LC3_FLOAT* re, LC3_FLOAT* im, LC3_INT stride)
409 : {
410 0 : if (handle->len <= MAX_FFT_SIZE) {
411 0 : LC3_cfft(re, im, handle->len, stride, handle->sign);
412 0 : } else if (handle->sign == -1) {
413 0 : fft(handle->table, handle->len / 2, re, im, handle->len, stride);
414 : } else {
415 0 : ifft(handle->table, handle->len / 2, re, im, handle->len, stride);
416 : }
417 0 : }
418 :
419 0 : void LC3_cfft_free(Cfft* handle)
420 : {
421 0 : if (handle->table)
422 : {
423 0 : free(handle->table);
424 : }
425 0 : }
|