1 /******************************************************************************
2 * *
3 * Copyright (C) 2018 The Android Open Source Project
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at:
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 *****************************************************************************
18 * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
19 */
20 #include <stdlib.h>
21 #include <stdio.h>
22
23 #include <ixheaacd_type_def.h>
24 #include "ixheaacd_interface.h"
25 #include "ixheaacd_constants.h"
26 #include <ixheaacd_basic_ops32.h>
27 #include "ixheaacd_basic_ops40.h"
28 #include "ixheaacd_function_selector.h"
29
30 extern const WORD32 ixheaacd_twiddle_table_fft_32x32[514];
31 extern const WORD32 ixheaacd_twiddle_table_3pr[1155];
32 extern const WORD32 ixheaacd_twiddle_table_3pi[1155];
33 extern const WORD8 ixheaacd_mps_dig_rev[16];
34
35 #define PLATFORM_INLINE __inline
36
37 #define DIG_REV(i, m, j) \
38 do { \
39 unsigned _ = (i); \
40 _ = ((_ & 0x33333333) << 2) | ((_ & ~0x33333333) >> 2); \
41 _ = ((_ & 0x0F0F0F0F) << 4) | ((_ & ~0x0F0F0F0F) >> 4); \
42 _ = ((_ & 0x00FF00FF) << 8) | ((_ & ~0x00FF00FF) >> 8); \
43 (j) = _ >> (m); \
44 } while (0)
45
ixheaacd_mult32_sat(WORD32 a,WORD32 b)46 static PLATFORM_INLINE WORD32 ixheaacd_mult32_sat(WORD32 a, WORD32 b) {
47 WORD32 result;
48 WORD64 temp_result;
49
50 temp_result = (WORD64)a * (WORD64)b;
51 result = ixheaacd_sat64_32(temp_result >> 31);
52
53 return (result);
54 }
55
ixheaacd_mac32_sat(WORD32 a,WORD32 b,WORD32 c)56 static PLATFORM_INLINE WORD32 ixheaacd_mac32_sat(WORD32 a, WORD32 b, WORD32 c) {
57 WORD32 result;
58
59 result = ixheaacd_add32_sat(a, ixheaacd_mult32_sat(b, c));
60
61 return (result);
62 }
63
64
ixheaacd_mps_complex_fft_64_dec(WORD32 * ptr_x,WORD32 * fin_re,WORD32 * fin_im,WORD32 nlength)65 VOID ixheaacd_mps_complex_fft_64_dec(WORD32 *ptr_x, WORD32 *fin_re,
66 WORD32 *fin_im, WORD32 nlength) {
67 WORD32 i, j, k, n_stages;
68 WORD32 h2, x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i;
69 WORD32 del, nodespacing, in_loop_cnt;
70 WORD32 y[128];
71 WORD32 npoints = nlength;
72 WORD32 *ptr_y = y;
73 const WORD32 *ptr_w;
74 n_stages = 30 - ixheaacd_norm32(npoints);
75
76 n_stages = n_stages >> 1;
77
78 ptr_w = ixheaacd_twiddle_table_fft_32x32;
79
80 for (i = 0; i < npoints; i += 4) {
81 WORD32 *inp = ptr_x;
82 h2 = ixheaacd_mps_dig_rev[i >> 2];
83 inp += (h2);
84
85 x0r = *inp;
86 x0i = *(inp + 1);
87 inp += (npoints >> 1);
88
89 x1r = *inp;
90 x1i = *(inp + 1);
91 inp += (npoints >> 1);
92
93 x2r = *inp;
94 x2i = *(inp + 1);
95 inp += (npoints >> 1);
96
97 x3r = *inp;
98 x3i = *(inp + 1);
99
100 x0r = ixheaacd_add32_sat(x0r, x2r);
101 x0i = ixheaacd_add32_sat(x0i, x2i);
102 x2r = ixheaacd_sub32_sat(x0r, ixheaacd_shl32_sat(x2r, 1));
103 x2i = ixheaacd_sub32_sat(x0i, ixheaacd_shl32_sat(x2i, 1));
104 x1r = ixheaacd_add32_sat(x1r, x3r);
105 x1i = ixheaacd_add32_sat(x1i, x3i);
106 x3r = ixheaacd_sub32_sat(x1r, ixheaacd_shl32_sat(x3r, 1));
107 x3i = ixheaacd_sub32_sat(x1i, ixheaacd_shl32_sat(x3i, 1));
108
109 x0r = ixheaacd_add32_sat(x0r, x1r);
110 x0i = ixheaacd_add32_sat(x0i, x1i);
111 x1r = ixheaacd_sub32_sat(x0r, ixheaacd_shl32_sat(x1r, 1));
112 x1i = ixheaacd_sub32_sat(x0i, ixheaacd_shl32_sat(x1i, 1));
113 x2r = ixheaacd_add32_sat(x2r, x3i);
114 x2i = ixheaacd_sub32_sat(x2i, x3r);
115 x3i = ixheaacd_sub32_sat(x2r, ixheaacd_shl32_sat(x3i, 1));
116 x3r = ixheaacd_add32_sat(x2i, ixheaacd_shl32_sat(x3r, 1));
117
118 *ptr_y++ = x0r;
119 *ptr_y++ = x0i;
120 *ptr_y++ = x2r;
121 *ptr_y++ = x2i;
122 *ptr_y++ = x1r;
123 *ptr_y++ = x1i;
124 *ptr_y++ = x3i;
125 *ptr_y++ = x3r;
126 }
127 ptr_y -= 2 * npoints;
128 del = 4;
129 nodespacing = 64;
130 in_loop_cnt = npoints >> 4;
131 for (i = n_stages - 1; i > 0; i--) {
132 const WORD32 *twiddles = ptr_w;
133 WORD32 *data = ptr_y;
134 WORD32 w1h, w2h, w3h, w1l, w2l, w3l;
135 WORD32 sec_loop_cnt;
136
137 for (k = in_loop_cnt; k != 0; k--) {
138 x0r = (*data);
139 x0i = (*(data + 1));
140 data += (del << 1);
141
142 x1r = (*data);
143 x1i = (*(data + 1));
144 data += (del << 1);
145
146 x2r = (*data);
147 x2i = (*(data + 1));
148 data += (del << 1);
149
150 x3r = (*data);
151 x3i = (*(data + 1));
152 data -= 3 * (del << 1);
153
154 x0r = ixheaacd_add32_sat(x0r, x2r);
155 x0i = ixheaacd_add32_sat(x0i, x2i);
156 x2r = ixheaacd_sub32_sat(x0r, ixheaacd_shl32_sat(x2r, 1));
157 x2i = ixheaacd_sub32_sat(x0i, ixheaacd_shl32_sat(x2i, 1));
158 x1r = ixheaacd_add32_sat(x1r, x3r);
159 x1i = ixheaacd_add32_sat(x1i, x3i);
160 x3r = ixheaacd_sub32_sat(x1r, ixheaacd_shl32_sat(x3r, 1));
161 x3i = ixheaacd_sub32_sat(x1i, ixheaacd_shl32_sat(x3i, 1));
162
163 x0r = ixheaacd_add32_sat(x0r, x1r);
164 x0i = ixheaacd_add32_sat(x0i, x1i);
165 x1r = ixheaacd_sub32_sat(x0r, ixheaacd_shl32_sat(x1r, 1));
166 x1i = ixheaacd_sub32_sat(x0i, ixheaacd_shl32_sat(x1i, 1));
167 x2r = ixheaacd_add32_sat(x2r, x3i);
168 x2i = ixheaacd_sub32_sat(x2i, x3r);
169 x3i = ixheaacd_sub32_sat(x2r, ixheaacd_shl32_sat(x3i, 1));
170 x3r = ixheaacd_add32_sat(x2i, ixheaacd_shl32_sat(x3r, 1));
171
172 *data = x0r;
173 *(data + 1) = x0i;
174 data += (del << 1);
175
176 *data = x2r;
177 *(data + 1) = x2i;
178 data += (del << 1);
179
180 *data = x1r;
181 *(data + 1) = x1i;
182 data += (del << 1);
183
184 *data = x3i;
185 *(data + 1) = x3r;
186 data += (del << 1);
187 }
188 data = ptr_y + 2;
189
190 sec_loop_cnt = (nodespacing * del);
191 sec_loop_cnt = (sec_loop_cnt / 4) + (sec_loop_cnt / 8) -
192 (sec_loop_cnt / 16) + (sec_loop_cnt / 32) -
193 (sec_loop_cnt / 64) + (sec_loop_cnt / 128) -
194 (sec_loop_cnt / 256);
195 j = nodespacing;
196
197 for (j = nodespacing; j <= sec_loop_cnt; j += nodespacing) {
198 w1h = *(twiddles + 2 * j);
199 w1l = *(twiddles + 2 * j + 1);
200 w2h = *(twiddles + 2 * (j << 1));
201 w2l = *(twiddles + 2 * (j << 1) + 1);
202 w3h = *(twiddles + 2 * j + 2 * (j << 1));
203 w3l = *(twiddles + 2 * j + 2 * (j << 1) + 1);
204
205 for (k = in_loop_cnt; k != 0; k--) {
206 WORD32 tmp;
207 WORD32 x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i;
208
209 data += (del << 1);
210
211 x1r = *data;
212 x1i = *(data + 1);
213 data += (del << 1);
214
215 x2r = *data;
216 x2i = *(data + 1);
217 data += (del << 1);
218
219 x3r = *data;
220 x3i = *(data + 1);
221 data -= 3 * (del << 1);
222
223 tmp = ixheaacd_sub32_sat(ixheaacd_mult32_sat(x1r, w1l),
224 ixheaacd_mult32_sat(x1i, w1h));
225 x1i = ixheaacd_mac32_sat(ixheaacd_mult32_sat(x1r, w1h), x1i, w1l);
226 x1r = tmp;
227
228 tmp = ixheaacd_sub32_sat(ixheaacd_mult32_sat(x2r, w2l),
229 ixheaacd_mult32_sat(x2i, w2h));
230 x2i = ixheaacd_mac32_sat(ixheaacd_mult32_sat(x2r, w2h), x2i, w2l);
231 x2r = tmp;
232
233 tmp = ixheaacd_sub32_sat(ixheaacd_mult32_sat(x3r, w3l),
234 ixheaacd_mult32_sat(x3i, w3h));
235 x3i = ixheaacd_mac32_sat(ixheaacd_mult32_sat(x3r, w3h), x3i, w3l);
236 x3r = tmp;
237
238 x0r = (*data);
239 x0i = (*(data + 1));
240
241 x0r = ixheaacd_add32_sat(x0r, x2r);
242 x0i = ixheaacd_add32_sat(x0i, x2i);
243 x2r = ixheaacd_sub32_sat(x0r, ixheaacd_shl32_sat(x2r, 1));
244 x2i = ixheaacd_sub32_sat(x0i, ixheaacd_shl32_sat(x2i, 1));
245 x1r = ixheaacd_add32_sat(x1r, x3r);
246 x1i = ixheaacd_add32_sat(x1i, x3i);
247 x3r = ixheaacd_sub32_sat(x1r, ixheaacd_shl32_sat(x3r, 1));
248 x3i = ixheaacd_sub32_sat(x1i, ixheaacd_shl32_sat(x3i, 1));
249
250 x0r = ixheaacd_add32_sat(x0r, x1r);
251 x0i = ixheaacd_add32_sat(x0i, x1i);
252 x1r = ixheaacd_sub32_sat(x0r, ixheaacd_shl32_sat(x1r, 1));
253 x1i = ixheaacd_sub32_sat(x0i, ixheaacd_shl32_sat(x1i, 1));
254 x2r = ixheaacd_add32_sat(x2r, x3i);
255 x2i = ixheaacd_sub32_sat(x2i, x3r);
256 x3i = ixheaacd_sub32_sat(x2r, ixheaacd_shl32_sat(x3i, 1));
257 x3r = ixheaacd_add32_sat(x2i, ixheaacd_shl32_sat(x3r, 1));
258
259 *data = x0r;
260 *(data + 1) = x0i;
261 data += (del << 1);
262
263 *data = x2r;
264 *(data + 1) = x2i;
265 data += (del << 1);
266
267 *data = x1r;
268 *(data + 1) = x1i;
269 data += (del << 1);
270
271 *data = x3i;
272 *(data + 1) = x3r;
273 data += (del << 1);
274 }
275 data -= 2 * npoints;
276 data += 2;
277 }
278 for (; j <= (nodespacing * del) >> 1; j += nodespacing) {
279 w1h = *(twiddles + 2 * j);
280 w2h = *(twiddles + 2 * (j << 1));
281 w3h = *(twiddles + 2 * j + 2 * (j << 1) - 512);
282 w1l = *(twiddles + 2 * j + 1);
283 w2l = *(twiddles + 2 * (j << 1) + 1);
284 w3l = *(twiddles + 2 * j + 2 * (j << 1) - 511);
285
286 for (k = in_loop_cnt; k != 0; k--) {
287 WORD32 tmp;
288 WORD32 x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i;
289
290 data += (del << 1);
291
292 x1r = *data;
293 x1i = *(data + 1);
294 data += (del << 1);
295
296 x2r = *data;
297 x2i = *(data + 1);
298 data += (del << 1);
299
300 x3r = *data;
301 x3i = *(data + 1);
302 data -= 3 * (del << 1);
303
304 tmp = ixheaacd_sub32_sat(ixheaacd_mult32_sat(x1r, w1l),
305 ixheaacd_mult32_sat(x1i, w1h));
306 x1i = ixheaacd_mac32_sat(ixheaacd_mult32_sat(x1r, w1h), x1i, w1l);
307 x1r = tmp;
308
309 tmp = ixheaacd_sub32_sat(ixheaacd_mult32_sat(x2r, w2l),
310 ixheaacd_mult32_sat(x2i, w2h));
311 x2i = ixheaacd_mac32_sat(ixheaacd_mult32_sat(x2r, w2h), x2i, w2l);
312 x2r = tmp;
313
314 tmp = ixheaacd_add32_sat(ixheaacd_mult32_sat(x3r, w3h),
315 ixheaacd_mult32_sat(x3i, w3l));
316 x3i = ixheaacd_sub32_sat(ixheaacd_mult32_sat(x3i, w3h),
317 ixheaacd_mult32_sat(x3r, w3l));
318 x3r = tmp;
319
320 x0r = (*data);
321 x0i = (*(data + 1));
322
323 x0r = ixheaacd_add32_sat(x0r, x2r);
324 x0i = ixheaacd_add32_sat(x0i, x2i);
325 x2r = ixheaacd_sub32_sat(x0r, ixheaacd_shl32_sat(x2r, 1));
326 x2i = ixheaacd_sub32_sat(x0i, ixheaacd_shl32_sat(x2i, 1));
327 x1r = ixheaacd_add32_sat(x1r, x3r);
328 x1i = ixheaacd_add32_sat(x1i, x3i);
329 x3r = ixheaacd_sub32_sat(x1r, ixheaacd_shl32_sat(x3r, 1));
330 x3i = ixheaacd_sub32_sat(x1i, ixheaacd_shl32_sat(x3i, 1));
331
332 x0r = ixheaacd_add32_sat(x0r, x1r);
333 x0i = ixheaacd_add32_sat(x0i, x1i);
334 x1r = ixheaacd_sub32_sat(x0r, ixheaacd_shl32_sat(x1r, 1));
335 x1i = ixheaacd_sub32_sat(x0i, ixheaacd_shl32_sat(x1i, 1));
336 x2r = ixheaacd_add32_sat(x2r, x3i);
337 x2i = ixheaacd_sub32_sat(x2i, x3r);
338 x3i = ixheaacd_sub32_sat(x2r, ixheaacd_shl32_sat(x3i, 1));
339 x3r = ixheaacd_add32_sat(x2i, ixheaacd_shl32_sat(x3r, 1));
340
341 *data = x0r;
342 *(data + 1) = x0i;
343 data += (del << 1);
344
345 *data = x2r;
346 *(data + 1) = x2i;
347 data += (del << 1);
348
349 *data = x1r;
350 *(data + 1) = x1i;
351 data += (del << 1);
352
353 *data = x3i;
354 *(data + 1) = x3r;
355 data += (del << 1);
356 }
357 data -= 2 * npoints;
358 data += 2;
359 }
360 for (; j <= sec_loop_cnt * 2; j += nodespacing) {
361 w1h = *(twiddles + 2 * j);
362 w2h = *(twiddles + 2 * (j << 1) - 512);
363 w3h = *(twiddles + 2 * j + 2 * (j << 1) - 512);
364 w1l = *(twiddles + 2 * j + 1);
365 w2l = *(twiddles + 2 * (j << 1) - 511);
366 w3l = *(twiddles + 2 * j + 2 * (j << 1) - 511);
367
368 for (k = in_loop_cnt; k != 0; k--) {
369 WORD32 tmp;
370 WORD32 x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i;
371
372 data += (del << 1);
373
374 x1r = *data;
375 x1i = *(data + 1);
376 data += (del << 1);
377
378 x2r = *data;
379 x2i = *(data + 1);
380 data += (del << 1);
381
382 x3r = *data;
383 x3i = *(data + 1);
384 data -= 3 * (del << 1);
385
386 tmp = ixheaacd_sub32_sat(ixheaacd_mult32_sat(x1r, w1l),
387 ixheaacd_mult32_sat(x1i, w1h));
388 x1i = ixheaacd_mac32_sat(ixheaacd_mult32_sat(x1r, w1h), x1i, w1l);
389 x1r = tmp;
390
391 tmp = ixheaacd_add32_sat(ixheaacd_mult32_sat(x2r, w2h),
392 ixheaacd_mult32_sat(x2i, w2l));
393 x2i = ixheaacd_sub32_sat(ixheaacd_mult32_sat(x2i, w2h),
394 ixheaacd_mult32_sat(x2r, w2l));
395 x2r = tmp;
396
397 tmp = ixheaacd_add32_sat(ixheaacd_mult32_sat(x3r, w3h),
398 ixheaacd_mult32_sat(x3i, w3l));
399 x3i = ixheaacd_sub32_sat(ixheaacd_mult32_sat(x3i, w3h),
400 ixheaacd_mult32_sat(x3r, w3l));
401 x3r = tmp;
402
403 x0r = (*data);
404 x0i = (*(data + 1));
405
406 x0r = ixheaacd_add32_sat(x0r, x2r);
407 x0i = ixheaacd_add32_sat(x0i, x2i);
408 x2r = ixheaacd_sub32_sat(x0r, ixheaacd_shl32_sat(x2r, 1));
409 x2i = ixheaacd_sub32_sat(x0i, ixheaacd_shl32_sat(x2i, 1));
410 x1r = ixheaacd_add32_sat(x1r, x3r);
411 x1i = ixheaacd_add32_sat(x1i, x3i);
412 x3r = ixheaacd_sub32_sat(x1r, ixheaacd_shl32_sat(x3r, 1));
413 x3i = ixheaacd_sub32_sat(x1i, ixheaacd_shl32_sat(x3i, 1));
414
415 x0r = ixheaacd_add32_sat(x0r, x1r);
416 x0i = ixheaacd_add32_sat(x0i, x1i);
417 x1r = ixheaacd_sub32_sat(x0r, ixheaacd_shl32_sat(x1r, 1));
418 x1i = ixheaacd_sub32_sat(x0i, ixheaacd_shl32_sat(x1i, 1));
419 x2r = ixheaacd_add32_sat(x2r, x3i);
420 x2i = ixheaacd_sub32_sat(x2i, x3r);
421 x3i = ixheaacd_sub32_sat(x2r, ixheaacd_shl32_sat(x3i, 1));
422 x3r = ixheaacd_add32_sat(x2i, ixheaacd_shl32_sat(x3r, 1));
423
424 *data = x0r;
425 *(data + 1) = x0i;
426 data += (del << 1);
427
428 *data = x2r;
429 *(data + 1) = x2i;
430 data += (del << 1);
431
432 *data = x1r;
433 *(data + 1) = x1i;
434 data += (del << 1);
435
436 *data = x3i;
437 *(data + 1) = x3r;
438 data += (del << 1);
439 }
440 data -= 2 * npoints;
441 data += 2;
442 }
443 for (; j < nodespacing * del; j += nodespacing) {
444 w1h = *(twiddles + 2 * j);
445 w2h = *(twiddles + 2 * (j << 1) - 512);
446 w3h = *(twiddles + 2 * j + 2 * (j << 1) - 1024);
447 w1l = *(twiddles + 2 * j + 1);
448 w2l = *(twiddles + 2 * (j << 1) - 511);
449 w3l = *(twiddles + 2 * j + 2 * (j << 1) - 1023);
450
451 for (k = in_loop_cnt; k != 0; k--) {
452 WORD32 tmp;
453 WORD32 x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i;
454
455 data += (del << 1);
456
457 x1r = *data;
458 x1i = *(data + 1);
459 data += (del << 1);
460
461 x2r = *data;
462 x2i = *(data + 1);
463 data += (del << 1);
464
465 x3r = *data;
466 x3i = *(data + 1);
467 data -= 3 * (del << 1);
468
469 tmp = ixheaacd_sub32_sat(ixheaacd_mult32_sat(x1r, w1l),
470 ixheaacd_mult32_sat(x1i, w1h));
471 x1i = ixheaacd_mac32_sat(ixheaacd_mult32_sat(x1r, w1h), x1i, w1l);
472 x1r = tmp;
473
474 tmp = ixheaacd_add32_sat(ixheaacd_mult32_sat(x2r, w2h),
475 ixheaacd_mult32_sat(x2i, w2l));
476 x2i = ixheaacd_sub32_sat(ixheaacd_mult32_sat(x2i, w2h),
477 ixheaacd_mult32_sat(x2r, w2l));
478 x2r = tmp;
479
480 tmp = ixheaacd_sub32_sat(ixheaacd_mult32_sat(x3i, w3h),
481 ixheaacd_mult32_sat(x3r, w3l));
482 x3i = ixheaacd_mac32_sat(ixheaacd_mult32_sat(x3r, w3h), x3i, w3l);
483 x3r = tmp;
484
485 x0r = (*data);
486 x0i = (*(data + 1));
487
488 x0r = ixheaacd_add32_sat(x0r, x2r);
489 x0i = ixheaacd_add32_sat(x0i, x2i);
490 x2r = ixheaacd_sub32_sat(x0r, ixheaacd_shl32_sat(x2r, 1));
491 x2i = ixheaacd_sub32_sat(x0i, ixheaacd_shl32_sat(x2i, 1));
492 x1r = ixheaacd_add32_sat(x1r, x3r);
493 x1i = ixheaacd_sub32_sat(x1i, x3i);
494 x3r = ixheaacd_sub32_sat(x1r, ixheaacd_shl32_sat(x3r, 1));
495 x3i = ixheaacd_add32_sat(x1i, ixheaacd_shl32_sat(x3i, 1));
496
497 x0r = ixheaacd_add32_sat(x0r, x1r);
498 x0i = ixheaacd_add32_sat(x0i, x1i);
499 x1r = ixheaacd_sub32_sat(x0r, ixheaacd_shl32_sat(x1r, 1));
500 x1i = ixheaacd_sub32_sat(x0i, ixheaacd_shl32_sat(x1i, 1));
501 x2r = ixheaacd_add32_sat(x2r, x3i);
502 x2i = ixheaacd_sub32_sat(x2i, x3r);
503 x3i = ixheaacd_sub32_sat(x2r, ixheaacd_shl32_sat(x3i, 1));
504 x3r = ixheaacd_add32_sat(x2i, ixheaacd_shl32_sat(x3r, 1));
505
506 *data = x0r;
507 *(data + 1) = x0i;
508 data += (del << 1);
509
510 *data = x2r;
511 *(data + 1) = x2i;
512 data += (del << 1);
513
514 *data = x1r;
515 *(data + 1) = x1i;
516 data += (del << 1);
517
518 *data = x3i;
519 *(data + 1) = x3r;
520 data += (del << 1);
521 }
522 data -= 2 * npoints;
523 data += 2;
524 }
525 nodespacing >>= 2;
526 del <<= 2;
527 in_loop_cnt >>= 2;
528 }
529
530 for (i = 0; i < 2 * nlength; i += 2) {
531 fin_re[i] = y[i];
532 fin_im[i] = y[i + 1];
533 }
534
535 return;
536 }
537
ixheaacd_complex_fft_p2_dec(WORD32 * xr,WORD32 * xi,WORD32 nlength,WORD32 fft_mode,WORD32 * preshift)538 VOID ixheaacd_complex_fft_p2_dec(WORD32 *xr, WORD32 *xi, WORD32 nlength,
539 WORD32 fft_mode, WORD32 *preshift) {
540 WORD32 i, j, k, n_stages;
541 WORD32 h2, x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i;
542 WORD32 del, nodespacing, in_loop_cnt;
543 WORD32 not_power_4;
544 WORD32 npts, shift;
545 WORD32 dig_rev_shift;
546 WORD32 ptr_x[1024];
547 WORD32 y[1024];
548 WORD32 npoints = nlength;
549 WORD32 n = 0;
550 WORD32 *ptr_y = y;
551 const WORD32 *ptr_w;
552 dig_rev_shift = ixheaacd_norm32(npoints) + 1 - 16;
553 n_stages = 30 - ixheaacd_norm32(npoints);
554 not_power_4 = n_stages & 1;
555
556 n_stages = n_stages >> 1;
557
558 npts = npoints;
559 while (npts >> 1) {
560 n++;
561 npts = npts >> 1;
562 }
563
564 if (n % 2 == 0)
565 shift = ((n + 4)) / 2;
566 else
567 shift = ((n + 3) / 2);
568
569 for (i = 0; i < nlength; i++) {
570 ptr_x[2 * i] = (xr[i] / (1 << (shift)));
571 ptr_x[2 * i + 1] = (xi[i] / (1 << (shift)));
572 }
573
574 if (fft_mode == -1) {
575 ptr_w = ixheaacd_twiddle_table_fft_32x32;
576
577 for (i = 0; i < npoints; i += 4) {
578 WORD32 *inp = ptr_x;
579
580 DIG_REV(i, dig_rev_shift, h2);
581 if (not_power_4) {
582 h2 += 1;
583 h2 &= ~1;
584 }
585 inp += (h2);
586
587 x0r = *inp;
588 x0i = *(inp + 1);
589 inp += (npoints >> 1);
590
591 x1r = *inp;
592 x1i = *(inp + 1);
593 inp += (npoints >> 1);
594
595 x2r = *inp;
596 x2i = *(inp + 1);
597 inp += (npoints >> 1);
598
599 x3r = *inp;
600 x3i = *(inp + 1);
601
602 x0r = ixheaacd_add32_sat(x0r, x2r);
603 x0i = ixheaacd_add32_sat(x0i, x2i);
604 x2r = ixheaacd_sub32_sat(x0r, ixheaacd_shl32_sat(x2r, 1));
605 x2i = ixheaacd_sub32_sat(x0i, ixheaacd_shl32_sat(x2i, 1));
606 x1r = ixheaacd_add32_sat(x1r, x3r);
607 x1i = ixheaacd_add32_sat(x1i, x3i);
608 x3r = ixheaacd_sub32_sat(x1r, ixheaacd_shl32_sat(x3r, 1));
609 x3i = ixheaacd_sub32_sat(x1i, ixheaacd_shl32_sat(x3i, 1));
610
611 x0r = ixheaacd_add32_sat(x0r, x1r);
612 x0i = ixheaacd_add32_sat(x0i, x1i);
613 x1r = ixheaacd_sub32_sat(x0r, ixheaacd_shl32_sat(x1r, 1));
614 x1i = ixheaacd_sub32_sat(x0i, ixheaacd_shl32_sat(x1i, 1));
615 x2r = ixheaacd_add32_sat(x2r, x3i);
616 x2i = ixheaacd_sub32_sat(x2i, x3r);
617 x3i = ixheaacd_sub32_sat(x2r, ixheaacd_shl32_sat(x3i, 1));
618 x3r = ixheaacd_add32_sat(x2i, ixheaacd_shl32_sat(x3r, 1));
619
620 *ptr_y++ = x0r;
621 *ptr_y++ = x0i;
622 *ptr_y++ = x2r;
623 *ptr_y++ = x2i;
624 *ptr_y++ = x1r;
625 *ptr_y++ = x1i;
626 *ptr_y++ = x3i;
627 *ptr_y++ = x3r;
628 }
629 ptr_y -= 2 * npoints;
630 del = 4;
631 nodespacing = 64;
632 in_loop_cnt = npoints >> 4;
633 for (i = n_stages - 1; i > 0; i--) {
634 const WORD32 *twiddles = ptr_w;
635 WORD32 *data = ptr_y;
636 WORD32 w1h, w2h, w3h, w1l, w2l, w3l;
637 WORD32 sec_loop_cnt;
638
639 for (k = in_loop_cnt; k != 0; k--) {
640 x0r = (*data);
641 x0i = (*(data + 1));
642 data += (del << 1);
643
644 x1r = (*data);
645 x1i = (*(data + 1));
646 data += (del << 1);
647
648 x2r = (*data);
649 x2i = (*(data + 1));
650 data += (del << 1);
651
652 x3r = (*data);
653 x3i = (*(data + 1));
654 data -= 3 * (del << 1);
655
656 x0r = ixheaacd_add32_sat(x0r, x2r);
657 x0i = ixheaacd_add32_sat(x0i, x2i);
658 x2r = ixheaacd_sub32_sat(x0r, ixheaacd_shl32_sat(x2r, 1));
659 x2i = ixheaacd_sub32_sat(x0i, ixheaacd_shl32_sat(x2i, 1));
660 x1r = ixheaacd_add32_sat(x1r, x3r);
661 x1i = ixheaacd_add32_sat(x1i, x3i);
662 x3r = ixheaacd_sub32_sat(x1r, ixheaacd_shl32_sat(x3r, 1));
663 x3i = ixheaacd_sub32_sat(x1i, ixheaacd_shl32_sat(x3i, 1));
664
665 x0r = ixheaacd_add32_sat(x0r, x1r);
666 x0i = ixheaacd_add32_sat(x0i, x1i);
667 x1r = ixheaacd_sub32_sat(x0r, ixheaacd_shl32_sat(x1r, 1));
668 x1i = ixheaacd_sub32_sat(x0i, ixheaacd_shl32_sat(x1i, 1));
669 x2r = ixheaacd_add32_sat(x2r, x3i);
670 x2i = ixheaacd_sub32_sat(x2i, x3r);
671 x3i = ixheaacd_sub32_sat(x2r, ixheaacd_shl32_sat(x3i, 1));
672 x3r = ixheaacd_add32_sat(x2i, ixheaacd_shl32_sat(x3r, 1));
673
674 *data = x0r;
675 *(data + 1) = x0i;
676 data += (del << 1);
677
678 *data = x2r;
679 *(data + 1) = x2i;
680 data += (del << 1);
681
682 *data = x1r;
683 *(data + 1) = x1i;
684 data += (del << 1);
685
686 *data = x3i;
687 *(data + 1) = x3r;
688 data += (del << 1);
689 }
690 data = ptr_y + 2;
691
692 sec_loop_cnt = (nodespacing * del);
693 sec_loop_cnt = (sec_loop_cnt / 4) + (sec_loop_cnt / 8) -
694 (sec_loop_cnt / 16) + (sec_loop_cnt / 32) -
695 (sec_loop_cnt / 64) + (sec_loop_cnt / 128) -
696 (sec_loop_cnt / 256);
697 j = nodespacing;
698
699 for (j = nodespacing; j <= sec_loop_cnt; j += nodespacing) {
700 w1h = *(twiddles + 2 * j);
701 w1l = *(twiddles + 2 * j + 1);
702 w2h = *(twiddles + 2 * (j << 1));
703 w2l = *(twiddles + 2 * (j << 1) + 1);
704 w3h = *(twiddles + 2 * j + 2 * (j << 1));
705 w3l = *(twiddles + 2 * j + 2 * (j << 1) + 1);
706
707 for (k = in_loop_cnt; k != 0; k--) {
708 WORD32 tmp;
709 WORD32 x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i;
710
711 data += (del << 1);
712
713 x1r = *data;
714 x1i = *(data + 1);
715 data += (del << 1);
716
717 x2r = *data;
718 x2i = *(data + 1);
719 data += (del << 1);
720
721 x3r = *data;
722 x3i = *(data + 1);
723 data -= 3 * (del << 1);
724
725 tmp = ixheaacd_sub32_sat(ixheaacd_mult32_sat(x1r, w1l),
726 ixheaacd_mult32_sat(x1i, w1h));
727 x1i = ixheaacd_mac32_sat(ixheaacd_mult32_sat(x1r, w1h), x1i, w1l);
728 x1r = tmp;
729
730 tmp = ixheaacd_sub32_sat(ixheaacd_mult32_sat(x2r, w2l),
731 ixheaacd_mult32_sat(x2i, w2h));
732 x2i = ixheaacd_mac32_sat(ixheaacd_mult32_sat(x2r, w2h), x2i, w2l);
733 x2r = tmp;
734
735 tmp = ixheaacd_sub32_sat(ixheaacd_mult32_sat(x3r, w3l),
736 ixheaacd_mult32_sat(x3i, w3h));
737 x3i = ixheaacd_mac32_sat(ixheaacd_mult32_sat(x3r, w3h), x3i, w3l);
738 x3r = tmp;
739
740 x0r = (*data);
741 x0i = (*(data + 1));
742
743 x0r = ixheaacd_add32_sat(x0r, x2r);
744 x0i = ixheaacd_add32_sat(x0i, x2i);
745 x2r = ixheaacd_sub32_sat(x0r, ixheaacd_shl32_sat(x2r, 1));
746 x2i = ixheaacd_sub32_sat(x0i, ixheaacd_shl32_sat(x2i, 1));
747 x1r = ixheaacd_add32_sat(x1r, x3r);
748 x1i = ixheaacd_add32_sat(x1i, x3i);
749 x3r = ixheaacd_sub32_sat(x1r, ixheaacd_shl32_sat(x3r, 1));
750 x3i = ixheaacd_sub32_sat(x1i, ixheaacd_shl32_sat(x3i, 1));
751
752 x0r = ixheaacd_add32_sat(x0r, x1r);
753 x0i = ixheaacd_add32_sat(x0i, x1i);
754 x1r = ixheaacd_sub32_sat(x0r, ixheaacd_shl32_sat(x1r, 1));
755 x1i = ixheaacd_sub32_sat(x0i, ixheaacd_shl32_sat(x1i, 1));
756 x2r = ixheaacd_add32_sat(x2r, x3i);
757 x2i = ixheaacd_sub32_sat(x2i, x3r);
758 x3i = ixheaacd_sub32_sat(x2r, ixheaacd_shl32_sat(x3i, 1));
759 x3r = ixheaacd_add32_sat(x2i, ixheaacd_shl32_sat(x3r, 1));
760
761 *data = x0r;
762 *(data + 1) = x0i;
763 data += (del << 1);
764
765 *data = x2r;
766 *(data + 1) = x2i;
767 data += (del << 1);
768
769 *data = x1r;
770 *(data + 1) = x1i;
771 data += (del << 1);
772
773 *data = x3i;
774 *(data + 1) = x3r;
775 data += (del << 1);
776 }
777 data -= 2 * npoints;
778 data += 2;
779 }
780 for (; j <= (nodespacing * del) >> 1; j += nodespacing) {
781 w1h = *(twiddles + 2 * j);
782 w2h = *(twiddles + 2 * (j << 1));
783 w3h = *(twiddles + 2 * j + 2 * (j << 1) - 512);
784 w1l = *(twiddles + 2 * j + 1);
785 w2l = *(twiddles + 2 * (j << 1) + 1);
786 w3l = *(twiddles + 2 * j + 2 * (j << 1) - 511);
787
788 for (k = in_loop_cnt; k != 0; k--) {
789 WORD32 tmp;
790 WORD32 x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i;
791 data += (del << 1);
792
793 x1r = *data;
794 x1i = *(data + 1);
795 data += (del << 1);
796
797 x2r = *data;
798 x2i = *(data + 1);
799 data += (del << 1);
800
801 x3r = *data;
802 x3i = *(data + 1);
803 data -= 3 * (del << 1);
804
805 tmp = ixheaacd_sub32_sat(ixheaacd_mult32_sat(x1r, w1l),
806 ixheaacd_mult32_sat(x1i, w1h));
807 x1i = ixheaacd_mac32_sat(ixheaacd_mult32_sat(x1r, w1h), x1i, w1l);
808 x1r = tmp;
809
810 tmp = ixheaacd_sub32_sat(ixheaacd_mult32_sat(x2r, w2l),
811 ixheaacd_mult32_sat(x2i, w2h));
812 x2i = ixheaacd_mac32_sat(ixheaacd_mult32_sat(x2r, w2h), x2i, w2l);
813 x2r = tmp;
814
815 tmp = ixheaacd_add32_sat(ixheaacd_mult32_sat(x3r, w3h),
816 ixheaacd_mult32_sat(x3i, w3l));
817 x3i = ixheaacd_sub32_sat(ixheaacd_mult32_sat(x3i, w3h),
818 ixheaacd_mult32_sat(x3r, w3l));
819 x3r = tmp;
820
821 x0r = (*data);
822 x0i = (*(data + 1));
823
824 x0r = ixheaacd_add32_sat(x0r, x2r);
825 x0i = ixheaacd_add32_sat(x0i, x2i);
826 x2r = ixheaacd_sub32_sat(x0r, ixheaacd_shl32_sat(x2r, 1));
827 x2i = ixheaacd_sub32_sat(x0i, ixheaacd_shl32_sat(x2i, 1));
828 x1r = ixheaacd_add32_sat(x1r, x3r);
829 x1i = ixheaacd_add32_sat(x1i, x3i);
830 x3r = ixheaacd_sub32_sat(x1r, ixheaacd_shl32_sat(x3r, 1));
831 x3i = ixheaacd_sub32_sat(x1i, ixheaacd_shl32_sat(x3i, 1));
832
833 x0r = ixheaacd_add32_sat(x0r, x1r);
834 x0i = ixheaacd_add32_sat(x0i, x1i);
835 x1r = ixheaacd_sub32_sat(x0r, ixheaacd_shl32_sat(x1r, 1));
836 x1i = ixheaacd_sub32_sat(x0i, ixheaacd_shl32_sat(x1i, 1));
837 x2r = ixheaacd_add32_sat(x2r, x3i);
838 x2i = ixheaacd_sub32_sat(x2i, x3r);
839 x3i = ixheaacd_sub32_sat(x2r, ixheaacd_shl32_sat(x3i, 1));
840 x3r = ixheaacd_add32_sat(x2i, ixheaacd_shl32_sat(x3r, 1));
841
842 *data = x0r;
843 *(data + 1) = x0i;
844 data += (del << 1);
845
846 *data = x2r;
847 *(data + 1) = x2i;
848 data += (del << 1);
849
850 *data = x1r;
851 *(data + 1) = x1i;
852 data += (del << 1);
853
854 *data = x3i;
855 *(data + 1) = x3r;
856 data += (del << 1);
857 }
858 data -= 2 * npoints;
859 data += 2;
860 }
861 for (; j <= sec_loop_cnt * 2; j += nodespacing) {
862 w1h = *(twiddles + 2 * j);
863 w2h = *(twiddles + 2 * (j << 1) - 512);
864 w3h = *(twiddles + 2 * j + 2 * (j << 1) - 512);
865 w1l = *(twiddles + 2 * j + 1);
866 w2l = *(twiddles + 2 * (j << 1) - 511);
867 w3l = *(twiddles + 2 * j + 2 * (j << 1) - 511);
868
869 for (k = in_loop_cnt; k != 0; k--) {
870 WORD32 tmp;
871 WORD32 x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i;
872
873 data += (del << 1);
874
875 x1r = *data;
876 x1i = *(data + 1);
877 data += (del << 1);
878
879 x2r = *data;
880 x2i = *(data + 1);
881 data += (del << 1);
882
883 x3r = *data;
884 x3i = *(data + 1);
885 data -= 3 * (del << 1);
886
887 tmp = ixheaacd_sub32_sat(ixheaacd_mult32_sat(x1r, w1l),
888 ixheaacd_mult32_sat(x1i, w1h));
889 x1i = ixheaacd_mac32_sat(ixheaacd_mult32_sat(x1r, w1h), x1i, w1l);
890 x1r = tmp;
891
892 tmp = ixheaacd_add32_sat(ixheaacd_mult32_sat(x2r, w2h),
893 ixheaacd_mult32_sat(x2i, w2l));
894 x2i = ixheaacd_sub32_sat(ixheaacd_mult32_sat(x2i, w2h),
895 ixheaacd_mult32_sat(x2r, w2l));
896 x2r = tmp;
897
898 tmp = ixheaacd_add32_sat(ixheaacd_mult32_sat(x3r, w3h),
899 ixheaacd_mult32_sat(x3i, w3l));
900 x3i = ixheaacd_sub32_sat(ixheaacd_mult32_sat(x3i, w3h),
901 ixheaacd_mult32_sat(x3r, w3l));
902 x3r = tmp;
903
904 x0r = (*data);
905 x0i = (*(data + 1));
906
907 x0r = ixheaacd_add32_sat(x0r, x2r);
908 x0i = ixheaacd_add32_sat(x0i, x2i);
909 x2r = ixheaacd_sub32_sat(x0r, ixheaacd_shl32_sat(x2r, 1));
910 x2i = ixheaacd_sub32_sat(x0i, ixheaacd_shl32_sat(x2i, 1));
911 x1r = ixheaacd_add32_sat(x1r, x3r);
912 x1i = ixheaacd_add32_sat(x1i, x3i);
913 x3r = ixheaacd_sub32_sat(x1r, ixheaacd_shl32_sat(x3r, 1));
914 x3i = ixheaacd_sub32_sat(x1i, ixheaacd_shl32_sat(x3i, 1));
915
916 x0r = ixheaacd_add32_sat(x0r, x1r);
917 x0i = ixheaacd_add32_sat(x0i, x1i);
918 x1r = ixheaacd_sub32_sat(x0r, ixheaacd_shl32_sat(x1r, 1));
919 x1i = ixheaacd_sub32_sat(x0i, ixheaacd_shl32_sat(x1i, 1));
920 x2r = ixheaacd_add32_sat(x2r, x3i);
921 x2i = ixheaacd_sub32_sat(x2i, x3r);
922 x3i = ixheaacd_sub32_sat(x2r, ixheaacd_shl32_sat(x3i, 1));
923 x3r = ixheaacd_add32_sat(x2i, ixheaacd_shl32_sat(x3r, 1));
924
925 *data = x0r;
926 *(data + 1) = x0i;
927 data += (del << 1);
928
929 *data = x2r;
930 *(data + 1) = x2i;
931 data += (del << 1);
932
933 *data = x1r;
934 *(data + 1) = x1i;
935 data += (del << 1);
936
937 *data = x3i;
938 *(data + 1) = x3r;
939 data += (del << 1);
940 }
941 data -= 2 * npoints;
942 data += 2;
943 }
944 for (; j < nodespacing * del; j += nodespacing) {
945 w1h = *(twiddles + 2 * j);
946 w2h = *(twiddles + 2 * (j << 1) - 512);
947 w3h = *(twiddles + 2 * j + 2 * (j << 1) - 1024);
948 w1l = *(twiddles + 2 * j + 1);
949 w2l = *(twiddles + 2 * (j << 1) - 511);
950 w3l = *(twiddles + 2 * j + 2 * (j << 1) - 1023);
951
952 for (k = in_loop_cnt; k != 0; k--) {
953 WORD32 tmp;
954 WORD32 x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i;
955
956 data += (del << 1);
957
958 x1r = *data;
959 x1i = *(data + 1);
960 data += (del << 1);
961
962 x2r = *data;
963 x2i = *(data + 1);
964 data += (del << 1);
965
966 x3r = *data;
967 x3i = *(data + 1);
968 data -= 3 * (del << 1);
969
970 tmp = ixheaacd_sub32_sat(ixheaacd_mult32_sat(x1r, w1l),
971 ixheaacd_mult32_sat(x1i, w1h));
972 x1i = ixheaacd_mac32_sat(ixheaacd_mult32_sat(x1r, w1h), x1i, w1l);
973 x1r = tmp;
974
975 tmp = ixheaacd_add32_sat(ixheaacd_mult32_sat(x2r, w2h),
976 ixheaacd_mult32_sat(x2i, w2l));
977 x2i = ixheaacd_sub32_sat(ixheaacd_mult32_sat(x2i, w2h),
978 ixheaacd_mult32_sat(x2r, w2l));
979 x2r = tmp;
980
981 tmp = ixheaacd_sub32_sat(ixheaacd_mult32_sat(x3i, w3h),
982 ixheaacd_mult32_sat(x3r, w3l));
983 x3i = ixheaacd_mac32_sat(ixheaacd_mult32_sat(x3r, w3h), x3i, w3l);
984 x3r = tmp;
985
986 x0r = (*data);
987 x0i = (*(data + 1));
988
989 x0r = ixheaacd_add32_sat(x0r, x2r);
990 x0i = ixheaacd_add32_sat(x0i, x2i);
991 x2r = ixheaacd_sub32_sat(x0r, ixheaacd_shl32_sat(x2r, 1));
992 x2i = ixheaacd_sub32_sat(x0i, ixheaacd_shl32_sat(x2i, 1));
993 x1r = ixheaacd_add32_sat(x1r, x3r);
994 x1i = ixheaacd_sub32_sat(x1i, x3i);
995 x3r = ixheaacd_sub32_sat(x1r, ixheaacd_shl32_sat(x3r, 1));
996 x3i = ixheaacd_add32_sat(x1i, ixheaacd_shl32_sat(x3i, 1));
997
998 x0r = ixheaacd_add32_sat(x0r, x1r);
999 x0i = ixheaacd_add32_sat(x0i, x1i);
1000 x1r = ixheaacd_sub32_sat(x0r, ixheaacd_shl32_sat(x1r, 1));
1001 x1i = ixheaacd_sub32_sat(x0i, ixheaacd_shl32_sat(x1i, 1));
1002 x2r = ixheaacd_add32_sat(x2r, x3i);
1003 x2i = ixheaacd_sub32_sat(x2i, x3r);
1004 x3i = ixheaacd_sub32_sat(x2r, ixheaacd_shl32_sat(x3i, 1));
1005 x3r = ixheaacd_add32_sat(x2i, ixheaacd_shl32_sat(x3r, 1));
1006
1007 *data = x0r;
1008 *(data + 1) = x0i;
1009 data += (del << 1);
1010
1011 *data = x2r;
1012 *(data + 1) = x2i;
1013 data += (del << 1);
1014
1015 *data = x1r;
1016 *(data + 1) = x1i;
1017 data += (del << 1);
1018
1019 *data = x3i;
1020 *(data + 1) = x3r;
1021 data += (del << 1);
1022 }
1023 data -= 2 * npoints;
1024 data += 2;
1025 }
1026 nodespacing >>= 2;
1027 del <<= 2;
1028 in_loop_cnt >>= 2;
1029 }
1030 if (not_power_4) {
1031 const WORD32 *twiddles = ptr_w;
1032 nodespacing <<= 1;
1033 shift += 1;
1034
1035 for (j = del / 2; j != 0; j--) {
1036 WORD32 w1h = *twiddles;
1037 WORD32 w1l = *(twiddles + 1);
1038 WORD32 tmp;
1039 twiddles += nodespacing * 2;
1040
1041 x0r = *ptr_y;
1042 x0i = *(ptr_y + 1);
1043 ptr_y += (del << 1);
1044
1045 x1r = *ptr_y;
1046 x1i = *(ptr_y + 1);
1047
1048 tmp = ixheaacd_sub32_sat(ixheaacd_mult32_sat(x1r, w1l),
1049 ixheaacd_mult32_sat(x1i, w1h));
1050 x1i = ixheaacd_mac32_sat(ixheaacd_mult32_sat(x1r, w1h), x1i, w1l);
1051 x1r = tmp;
1052
1053 *ptr_y = (x0r) / 2 - (x1r) / 2;
1054 *(ptr_y + 1) = (x0i) / 2 - (x1i) / 2;
1055 ptr_y -= (del << 1);
1056
1057 *ptr_y = (x0r) / 2 + (x1r) / 2;
1058 *(ptr_y + 1) = (x0i) / 2 + (x1i) / 2;
1059 ptr_y += 2;
1060 }
1061 twiddles = ptr_w;
1062 for (j = del / 2; j != 0; j--) {
1063 WORD32 w1h = *twiddles;
1064 WORD32 w1l = *(twiddles + 1);
1065 WORD32 tmp;
1066 twiddles += nodespacing * 2;
1067
1068 x0r = *ptr_y;
1069 x0i = *(ptr_y + 1);
1070 ptr_y += (del << 1);
1071
1072 x1r = *ptr_y;
1073 x1i = *(ptr_y + 1);
1074
1075 tmp = ixheaacd_add32_sat(ixheaacd_mult32_sat(x1r, w1h),
1076 ixheaacd_mult32_sat(x1i, w1l));
1077 x1i = ixheaacd_sub32_sat(ixheaacd_mult32_sat(x1i, w1h),
1078 ixheaacd_mult32_sat(x1r, w1l));
1079 x1r = tmp;
1080
1081 *ptr_y = (x0r) / 2 - (x1r) / 2;
1082 *(ptr_y + 1) = (x0i) / 2 - (x1i) / 2;
1083 ptr_y -= (del << 1);
1084
1085 *ptr_y = (x0r) / 2 + (x1r) / 2;
1086 *(ptr_y + 1) = (x0i) / 2 + (x1i) / 2;
1087 ptr_y += 2;
1088 }
1089 }
1090
1091 }
1092
1093 else {
1094 ptr_w = ixheaacd_twiddle_table_fft_32x32;
1095
1096 for (i = 0; i < npoints; i += 4) {
1097 WORD32 *inp = ptr_x;
1098
1099 DIG_REV(i, dig_rev_shift, h2);
1100 if (not_power_4) {
1101 h2 += 1;
1102 h2 &= ~1;
1103 }
1104 inp += (h2);
1105
1106 x0r = *inp;
1107 x0i = *(inp + 1);
1108 inp += (npoints >> 1);
1109
1110 x1r = *inp;
1111 x1i = *(inp + 1);
1112 inp += (npoints >> 1);
1113
1114 x2r = *inp;
1115 x2i = *(inp + 1);
1116 inp += (npoints >> 1);
1117
1118 x3r = *inp;
1119 x3i = *(inp + 1);
1120
1121 x0r = ixheaacd_add32_sat(x0r, x2r);
1122 x0i = ixheaacd_add32_sat(x0i, x2i);
1123 x2r = ixheaacd_sub32_sat(x0r, ixheaacd_shl32_sat(x2r, 1));
1124 x2i = ixheaacd_sub32_sat(x0i, ixheaacd_shl32_sat(x2i, 1));
1125 x1r = ixheaacd_add32_sat(x1r, x3r);
1126 x1i = ixheaacd_add32_sat(x1i, x3i);
1127 x3r = ixheaacd_sub32_sat(x1r, ixheaacd_shl32_sat(x3r, 1));
1128 x3i = ixheaacd_sub32_sat(x1i, ixheaacd_shl32_sat(x3i, 1));
1129
1130 x0r = ixheaacd_add32_sat(x0r, x1r);
1131 x0i = ixheaacd_add32_sat(x0i, x1i);
1132 x1r = ixheaacd_sub32_sat(x0r, ixheaacd_shl32_sat(x1r, 1));
1133 x1i = ixheaacd_sub32_sat(x0i, ixheaacd_shl32_sat(x1i, 1));
1134 x2r = ixheaacd_sub32_sat(x2r, x3i);
1135 x2i = ixheaacd_add32_sat(x2i, x3r);
1136 x3i = ixheaacd_add32_sat(x2r, ixheaacd_shl32_sat(x3i, 1));
1137 x3r = ixheaacd_sub32_sat(x2i, ixheaacd_shl32_sat(x3r, 1));
1138
1139 *ptr_y++ = x0r;
1140 *ptr_y++ = x0i;
1141 *ptr_y++ = x2r;
1142 *ptr_y++ = x2i;
1143 *ptr_y++ = x1r;
1144 *ptr_y++ = x1i;
1145 *ptr_y++ = x3i;
1146 *ptr_y++ = x3r;
1147 }
1148 ptr_y -= 2 * npoints;
1149 del = 4;
1150 nodespacing = 64;
1151 in_loop_cnt = npoints >> 4;
1152 for (i = n_stages - 1; i > 0; i--) {
1153 const WORD32 *twiddles = ptr_w;
1154 WORD32 *data = ptr_y;
1155 WORD32 w1h, w2h, w3h, w1l, w2l, w3l;
1156 WORD32 sec_loop_cnt;
1157
1158 for (k = in_loop_cnt; k != 0; k--) {
1159 x0r = (*data);
1160 x0i = (*(data + 1));
1161 data += (del << 1);
1162
1163 x1r = (*data);
1164 x1i = (*(data + 1));
1165 data += (del << 1);
1166
1167 x2r = (*data);
1168 x2i = (*(data + 1));
1169 data += (del << 1);
1170
1171 x3r = (*data);
1172 x3i = (*(data + 1));
1173 data -= 3 * (del << 1);
1174
1175 x0r = ixheaacd_add32_sat(x0r, x2r);
1176 x0i = ixheaacd_add32_sat(x0i, x2i);
1177 x2r = ixheaacd_sub32_sat(x0r, ixheaacd_shl32_sat(x2r, 1));
1178 x2i = ixheaacd_sub32_sat(x0i, ixheaacd_shl32_sat(x2i, 1));
1179 x1r = ixheaacd_add32_sat(x1r, x3r);
1180 x1i = ixheaacd_add32_sat(x1i, x3i);
1181 x3r = ixheaacd_sub32_sat(x1r, ixheaacd_shl32_sat(x3r, 1));
1182 x3i = ixheaacd_sub32_sat(x1i, ixheaacd_shl32_sat(x3i, 1));
1183
1184 x0r = ixheaacd_add32_sat(x0r, x1r);
1185 x0i = ixheaacd_add32_sat(x0i, x1i);
1186 x1r = ixheaacd_sub32_sat(x0r, ixheaacd_shl32_sat(x1r, 1));
1187 x1i = ixheaacd_sub32_sat(x0i, ixheaacd_shl32_sat(x1i, 1));
1188 x2r = ixheaacd_sub32_sat(x2r, x3i);
1189 x2i = ixheaacd_add32_sat(x2i, x3r);
1190 x3i = ixheaacd_add32_sat(x2r, ixheaacd_shl32_sat(x3i, 1));
1191 x3r = ixheaacd_sub32_sat(x2i, ixheaacd_shl32_sat(x3r, 1));
1192
1193 *data = x0r;
1194 *(data + 1) = x0i;
1195 data += (del << 1);
1196
1197 *data = x2r;
1198 *(data + 1) = x2i;
1199 data += (del << 1);
1200
1201 *data = x1r;
1202 *(data + 1) = x1i;
1203 data += (del << 1);
1204
1205 *data = x3i;
1206 *(data + 1) = x3r;
1207 data += (del << 1);
1208 }
1209 data = ptr_y + 2;
1210
1211 sec_loop_cnt = (nodespacing * del);
1212 sec_loop_cnt = (sec_loop_cnt / 4) + (sec_loop_cnt / 8) -
1213 (sec_loop_cnt / 16) + (sec_loop_cnt / 32) -
1214 (sec_loop_cnt / 64) + (sec_loop_cnt / 128) -
1215 (sec_loop_cnt / 256);
1216 j = nodespacing;
1217
1218 for (j = nodespacing; j <= sec_loop_cnt; j += nodespacing) {
1219 w1h = *(twiddles + 2 * j);
1220 w2h = *(twiddles + 2 * (j << 1));
1221 w3h = *(twiddles + 2 * j + 2 * (j << 1));
1222 w1l = *(twiddles + 2 * j + 1);
1223 w2l = *(twiddles + 2 * (j << 1) + 1);
1224 w3l = *(twiddles + 2 * j + 2 * (j << 1) + 1);
1225
1226 for (k = in_loop_cnt; k != 0; k--) {
1227 WORD32 tmp;
1228 WORD32 x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i;
1229
1230 data += (del << 1);
1231
1232 x1r = *data;
1233 x1i = *(data + 1);
1234 data += (del << 1);
1235
1236 x2r = *data;
1237 x2i = *(data + 1);
1238 data += (del << 1);
1239
1240 x3r = *data;
1241 x3i = *(data + 1);
1242 data -= 3 * (del << 1);
1243
1244 tmp = ixheaacd_add32_sat(ixheaacd_mult32_sat(x1r, w1l),
1245 ixheaacd_mult32_sat(x1i, w1h));
1246 x1i = ixheaacd_mac32_sat(-ixheaacd_mult32_sat(x1r, w1h), x1i, w1l);
1247 x1r = tmp;
1248
1249 tmp = ixheaacd_add32_sat(ixheaacd_mult32_sat(x2r, w2l),
1250 ixheaacd_mult32_sat(x2i, w2h));
1251 x2i = ixheaacd_mac32_sat(-ixheaacd_mult32_sat(x2r, w2h), x2i, w2l);
1252 x2r = tmp;
1253
1254 tmp = ixheaacd_add32_sat(ixheaacd_mult32_sat(x3r, w3l),
1255 ixheaacd_mult32_sat(x3i, w3h));
1256 x3i = ixheaacd_mac32_sat(-ixheaacd_mult32_sat(x3r, w3h), x3i, w3l);
1257 x3r = tmp;
1258
1259 x0r = (*data);
1260 x0i = (*(data + 1));
1261
1262 x0r = ixheaacd_add32_sat(x0r, x2r);
1263 x0i = ixheaacd_add32_sat(x0i, x2i);
1264 x2r = ixheaacd_sub32_sat(x0r, ixheaacd_shl32_sat(x2r, 1));
1265 x2i = ixheaacd_sub32_sat(x0i, ixheaacd_shl32_sat(x2i, 1));
1266 x1r = ixheaacd_add32_sat(x1r, x3r);
1267 x1i = ixheaacd_add32_sat(x1i, x3i);
1268 x3r = ixheaacd_sub32_sat(x1r, ixheaacd_shl32_sat(x3r, 1));
1269 x3i = ixheaacd_sub32_sat(x1i, ixheaacd_shl32_sat(x3i, 1));
1270
1271 x0r = ixheaacd_add32_sat(x0r, x1r);
1272 x0i = ixheaacd_add32_sat(x0i, x1i);
1273 x1r = ixheaacd_sub32_sat(x0r, ixheaacd_shl32_sat(x1r, 1));
1274 x1i = ixheaacd_sub32_sat(x0i, ixheaacd_shl32_sat(x1i, 1));
1275 x2r = ixheaacd_sub32_sat(x2r, x3i);
1276 x2i = ixheaacd_add32_sat(x2i, x3r);
1277 x3i = ixheaacd_add32_sat(x2r, ixheaacd_shl32_sat(x3i, 1));
1278 x3r = ixheaacd_sub32_sat(x2i, ixheaacd_shl32_sat(x3r, 1));
1279
1280 *data = x0r;
1281 *(data + 1) = x0i;
1282 data += (del << 1);
1283
1284 *data = x2r;
1285 *(data + 1) = x2i;
1286 data += (del << 1);
1287
1288 *data = x1r;
1289 *(data + 1) = x1i;
1290 data += (del << 1);
1291
1292 *data = x3i;
1293 *(data + 1) = x3r;
1294 data += (del << 1);
1295 }
1296 data -= 2 * npoints;
1297 data += 2;
1298 }
1299 for (; j <= (nodespacing * del) >> 1; j += nodespacing) {
1300 w1h = *(twiddles + 2 * j);
1301 w2h = *(twiddles + 2 * (j << 1));
1302 w3h = *(twiddles + 2 * j + 2 * (j << 1) - 512);
1303 w1l = *(twiddles + 2 * j + 1);
1304 w2l = *(twiddles + 2 * (j << 1) + 1);
1305 w3l = *(twiddles + 2 * j + 2 * (j << 1) - 511);
1306
1307 for (k = in_loop_cnt; k != 0; k--) {
1308 WORD32 tmp;
1309 WORD32 x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i;
1310
1311 data += (del << 1);
1312
1313 x1r = *data;
1314 x1i = *(data + 1);
1315 data += (del << 1);
1316
1317 x2r = *data;
1318 x2i = *(data + 1);
1319 data += (del << 1);
1320
1321 x3r = *data;
1322 x3i = *(data + 1);
1323 data -= 3 * (del << 1);
1324
1325 tmp = ixheaacd_add32_sat(ixheaacd_mult32_sat(x1r, w1l),
1326 ixheaacd_mult32_sat(x1i, w1h));
1327 x1i = ixheaacd_mac32_sat(-ixheaacd_mult32_sat(x1r, w1h), x1i, w1l);
1328 x1r = tmp;
1329
1330 tmp = ixheaacd_add32_sat(ixheaacd_mult32_sat(x2r, w2l),
1331 ixheaacd_mult32_sat(x2i, w2h));
1332 x2i = ixheaacd_mac32_sat(-ixheaacd_mult32_sat(x2r, w2h), x2i, w2l);
1333 x2r = tmp;
1334
1335 tmp = ixheaacd_sub32_sat(ixheaacd_mult32_sat(x3r, w3h),
1336 ixheaacd_mult32_sat(x3i, w3l));
1337 x3i = ixheaacd_add32_sat(ixheaacd_mult32_sat(x3r, w3l),
1338 ixheaacd_mult32_sat(x3i, w3h));
1339 x3r = tmp;
1340
1341 x0r = (*data);
1342 x0i = (*(data + 1));
1343
1344 x0r = ixheaacd_add32_sat(x0r, x2r);
1345 x0i = ixheaacd_add32_sat(x0i, x2i);
1346 x2r = ixheaacd_sub32_sat(x0r, ixheaacd_shl32_sat(x2r, 1));
1347 x2i = ixheaacd_sub32_sat(x0i, ixheaacd_shl32_sat(x2i, 1));
1348 x1r = ixheaacd_add32_sat(x1r, x3r);
1349 x1i = ixheaacd_add32_sat(x1i, x3i);
1350 x3r = ixheaacd_sub32_sat(x1r, ixheaacd_shl32_sat(x3r, 1));
1351 x3i = ixheaacd_sub32_sat(x1i, ixheaacd_shl32_sat(x3i, 1));
1352
1353 x0r = ixheaacd_add32_sat(x0r, x1r);
1354 x0i = ixheaacd_add32_sat(x0i, x1i);
1355 x1r = ixheaacd_sub32_sat(x0r, ixheaacd_shl32_sat(x1r, 1));
1356 x1i = ixheaacd_sub32_sat(x0i, ixheaacd_shl32_sat(x1i, 1));
1357 x2r = ixheaacd_sub32_sat(x2r, x3i);
1358 x2i = ixheaacd_add32_sat(x2i, x3r);
1359 x3i = ixheaacd_add32_sat(x2r, ixheaacd_shl32_sat(x3i, 1));
1360 x3r = ixheaacd_sub32_sat(x2i, ixheaacd_shl32_sat(x3r, 1));
1361
1362 *data = x0r;
1363 *(data + 1) = x0i;
1364 data += (del << 1);
1365
1366 *data = x2r;
1367 *(data + 1) = x2i;
1368 data += (del << 1);
1369
1370 *data = x1r;
1371 *(data + 1) = x1i;
1372 data += (del << 1);
1373
1374 *data = x3i;
1375 *(data + 1) = x3r;
1376 data += (del << 1);
1377 }
1378 data -= 2 * npoints;
1379 data += 2;
1380 }
1381 for (; j <= sec_loop_cnt * 2; j += nodespacing) {
1382 w1h = *(twiddles + 2 * j);
1383 w2h = *(twiddles + 2 * (j << 1) - 512);
1384 w3h = *(twiddles + 2 * j + 2 * (j << 1) - 512);
1385 w1l = *(twiddles + 2 * j + 1);
1386 w2l = *(twiddles + 2 * (j << 1) - 511);
1387 w3l = *(twiddles + 2 * j + 2 * (j << 1) - 511);
1388
1389 for (k = in_loop_cnt; k != 0; k--) {
1390 WORD32 tmp;
1391 WORD32 x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i;
1392
1393 data += (del << 1);
1394
1395 x1r = *data;
1396 x1i = *(data + 1);
1397 data += (del << 1);
1398
1399 x2r = *data;
1400 x2i = *(data + 1);
1401 data += (del << 1);
1402
1403 x3r = *data;
1404 x3i = *(data + 1);
1405 data -= 3 * (del << 1);
1406
1407 tmp = ixheaacd_add32_sat(ixheaacd_mult32_sat(x1r, w1l),
1408 ixheaacd_mult32_sat(x1i, w1h));
1409 x1i = ixheaacd_mac32_sat(-ixheaacd_mult32_sat(x1r, w1h), x1i, w1l);
1410 x1r = tmp;
1411
1412 tmp = ixheaacd_sub32_sat(ixheaacd_mult32_sat(x2r, w2h),
1413 ixheaacd_mult32_sat(x2i, w2l));
1414 x2i = ixheaacd_add32_sat(ixheaacd_mult32_sat(x2r, w2l),
1415 ixheaacd_mult32_sat(x2i, w2h));
1416 x2r = tmp;
1417
1418 tmp = ixheaacd_sub32_sat(ixheaacd_mult32_sat(x3r, w3h),
1419 ixheaacd_mult32_sat(x3i, w3l));
1420 x3i = ixheaacd_add32_sat(ixheaacd_mult32_sat(x3r, w3l),
1421 ixheaacd_mult32_sat(x3i, w3h));
1422 x3r = tmp;
1423
1424 x0r = (*data);
1425 x0i = (*(data + 1));
1426
1427 x0r = ixheaacd_add32_sat(x0r, x2r);
1428 x0i = ixheaacd_add32_sat(x0i, x2i);
1429 x2r = ixheaacd_sub32_sat(x0r, ixheaacd_shl32_sat(x2r, 1));
1430 x2i = ixheaacd_sub32_sat(x0i, ixheaacd_shl32_sat(x2i, 1));
1431 x1r = ixheaacd_add32_sat(x1r, x3r);
1432 x1i = ixheaacd_add32_sat(x1i, x3i);
1433 x3r = ixheaacd_sub32_sat(x1r, ixheaacd_shl32_sat(x3r, 1));
1434 x3i = ixheaacd_sub32_sat(x1i, ixheaacd_shl32_sat(x3i, 1));
1435
1436 x0r = ixheaacd_add32_sat(x0r, x1r);
1437 x0i = ixheaacd_add32_sat(x0i, x1i);
1438 x1r = ixheaacd_sub32_sat(x0r, ixheaacd_shl32_sat(x1r, 1));
1439 x1i = ixheaacd_sub32_sat(x0i, ixheaacd_shl32_sat(x1i, 1));
1440 x2r = ixheaacd_sub32_sat(x2r, x3i);
1441 x2i = ixheaacd_add32_sat(x2i, x3r);
1442 x3i = ixheaacd_add32_sat(x2r, ixheaacd_shl32_sat(x3i, 1));
1443 x3r = ixheaacd_sub32_sat(x2i, ixheaacd_shl32_sat(x3r, 1));
1444
1445 *data = x0r;
1446 *(data + 1) = x0i;
1447 data += (del << 1);
1448
1449 *data = x2r;
1450 *(data + 1) = x2i;
1451 data += (del << 1);
1452
1453 *data = x1r;
1454 *(data + 1) = x1i;
1455 data += (del << 1);
1456
1457 *data = x3i;
1458 *(data + 1) = x3r;
1459 data += (del << 1);
1460 }
1461 data -= 2 * npoints;
1462 data += 2;
1463 }
1464 for (; j < nodespacing * del; j += nodespacing) {
1465 w1h = *(twiddles + 2 * j);
1466 w2h = *(twiddles + 2 * (j << 1) - 512);
1467 w3h = *(twiddles + 2 * j + 2 * (j << 1) - 1024);
1468 w1l = *(twiddles + 2 * j + 1);
1469 w2l = *(twiddles + 2 * (j << 1) - 511);
1470 w3l = *(twiddles + 2 * j + 2 * (j << 1) - 1023);
1471
1472 for (k = in_loop_cnt; k != 0; k--) {
1473 WORD32 tmp;
1474 WORD32 x0r, x0i, x1r, x1i, x2r, x2i, x3r, x3i;
1475
1476 data += (del << 1);
1477
1478 x1r = *data;
1479 x1i = *(data + 1);
1480 data += (del << 1);
1481
1482 x2r = *data;
1483 x2i = *(data + 1);
1484 data += (del << 1);
1485
1486 x3r = *data;
1487 x3i = *(data + 1);
1488 data -= 3 * (del << 1);
1489
1490 tmp = ixheaacd_add32_sat(ixheaacd_mult32_sat(x1r, w1l),
1491 ixheaacd_mult32_sat(x1i, w1h));
1492 x1i = ixheaacd_mac32_sat(-ixheaacd_mult32_sat(x1r, w1h), x1i, w1l);
1493 x1r = tmp;
1494
1495 tmp = ixheaacd_sub32_sat(ixheaacd_mult32_sat(x2r, w2h),
1496 ixheaacd_mult32_sat(x2i, w2l));
1497 x2i = ixheaacd_add32_sat(ixheaacd_mult32_sat(x2r, w2l),
1498 ixheaacd_mult32_sat(x2i, w2h));
1499 x2r = tmp;
1500
1501 tmp = -ixheaacd_add32_sat(ixheaacd_mult32_sat(x3r, w3l),
1502 ixheaacd_mult32_sat(x3i, w3h));
1503 x3i = ixheaacd_mac32_sat(-ixheaacd_mult32_sat(x3r, w3h), x3i, w3l);
1504 x3r = tmp;
1505
1506 x0r = (*data);
1507 x0i = (*(data + 1));
1508
1509 x0r = ixheaacd_add32_sat(x0r, x2r);
1510 x0i = ixheaacd_add32_sat(x0i, x2i);
1511 x2r = ixheaacd_sub32_sat(x0r, ixheaacd_shl32_sat(x2r, 1));
1512 x2i = ixheaacd_sub32_sat(x0i, ixheaacd_shl32_sat(x2i, 1));
1513 x1r = ixheaacd_add32_sat(x1r, x3r);
1514 x1i = ixheaacd_sub32_sat(x1i, x3i);
1515 x3r = ixheaacd_sub32_sat(x1r, ixheaacd_shl32_sat(x3r, 1));
1516 x3i = ixheaacd_add32_sat(x1i, ixheaacd_shl32_sat(x3i, 1));
1517
1518 x0r = ixheaacd_add32_sat(x0r, x1r);
1519 x0i = ixheaacd_add32_sat(x0i, x1i);
1520 x1r = ixheaacd_sub32_sat(x0r, ixheaacd_shl32_sat(x1r, 1));
1521 x1i = ixheaacd_sub32_sat(x0i, ixheaacd_shl32_sat(x1i, 1));
1522 x2r = ixheaacd_sub32_sat(x2r, x3i);
1523 x2i = ixheaacd_add32_sat(x2i, x3r);
1524 x3i = ixheaacd_add32_sat(x2r, ixheaacd_shl32_sat(x3i, 1));
1525 x3r = ixheaacd_sub32_sat(x2i, ixheaacd_shl32_sat(x3r, 1));
1526
1527 *data = x0r;
1528 *(data + 1) = x0i;
1529 data += (del << 1);
1530
1531 *data = x2r;
1532 *(data + 1) = x2i;
1533 data += (del << 1);
1534
1535 *data = x1r;
1536 *(data + 1) = x1i;
1537 data += (del << 1);
1538
1539 *data = x3i;
1540 *(data + 1) = x3r;
1541 data += (del << 1);
1542 }
1543 data -= 2 * npoints;
1544 data += 2;
1545 }
1546 nodespacing >>= 2;
1547 del <<= 2;
1548 in_loop_cnt >>= 2;
1549 }
1550 if (not_power_4) {
1551 const WORD32 *twiddles = ptr_w;
1552 nodespacing <<= 1;
1553 shift += 1;
1554 for (j = del / 2; j != 0; j--) {
1555 WORD32 w1h = *twiddles;
1556 WORD32 w1l = *(twiddles + 1);
1557
1558 WORD32 tmp;
1559 twiddles += nodespacing * 2;
1560
1561 x0r = *ptr_y;
1562 x0i = *(ptr_y + 1);
1563 ptr_y += (del << 1);
1564
1565 x1r = *ptr_y;
1566 x1i = *(ptr_y + 1);
1567
1568 tmp = ixheaacd_add32_sat(ixheaacd_mult32_sat(x1r, w1l),
1569 ixheaacd_mult32_sat(x1i, w1h));
1570 x1i = ixheaacd_mac32_sat(-ixheaacd_mult32_sat(x1r, w1h), x1i, w1l);
1571 x1r = tmp;
1572
1573 *ptr_y = (x0r) / 2 - (x1r) / 2;
1574 *(ptr_y + 1) = (x0i) / 2 - (x1i) / 2;
1575 ptr_y -= (del << 1);
1576
1577 *ptr_y = (x0r) / 2 + (x1r) / 2;
1578 *(ptr_y + 1) = (x0i) / 2 + (x1i) / 2;
1579 ptr_y += 2;
1580 }
1581 twiddles = ptr_w;
1582 for (j = del / 2; j != 0; j--) {
1583 WORD32 w1h = *twiddles;
1584 WORD32 w1l = *(twiddles + 1);
1585 WORD32 tmp;
1586 twiddles += nodespacing * 2;
1587
1588 x0r = *ptr_y;
1589 x0i = *(ptr_y + 1);
1590 ptr_y += (del << 1);
1591
1592 x1r = *ptr_y;
1593 x1i = *(ptr_y + 1);
1594
1595 tmp = ixheaacd_sub32_sat(ixheaacd_mult32_sat(x1r, w1h),
1596 ixheaacd_mult32_sat(x1i, w1l));
1597 x1i = ixheaacd_add32_sat(ixheaacd_mult32_sat(x1r, w1l),
1598 ixheaacd_mult32_sat(x1i, w1h));
1599 x1r = tmp;
1600
1601 *ptr_y = (x0r) / 2 - (x1r) / 2;
1602 *(ptr_y + 1) = (x0i) / 2 - (x1i) / 2;
1603 ptr_y -= (del << 1);
1604
1605 *ptr_y = (x0r) / 2 + (x1r) / 2;
1606 *(ptr_y + 1) = (x0i) / 2 + (x1i) / 2;
1607 ptr_y += 2;
1608 }
1609 }
1610 }
1611
1612 for (i = 0; i < nlength; i++) {
1613 xr[i] = y[2 * i];
1614 xi[i] = y[2 * i + 1];
1615 }
1616
1617 *preshift = shift - *preshift;
1618 return;
1619 }
1620
ixheaacd_complex_3point_fft(WORD32 * inp,WORD32 * op,WORD32 sign_dir)1621 static PLATFORM_INLINE void ixheaacd_complex_3point_fft(WORD32 *inp, WORD32 *op,
1622 WORD32 sign_dir) {
1623 WORD32 add_r, sub_r;
1624 WORD32 add_i, sub_i;
1625 WORD32 temp_real, temp_imag, temp;
1626
1627 WORD32 p1, p2, p3, p4;
1628
1629 WORD32 sinmu;
1630 sinmu = -1859775393 * sign_dir;
1631
1632 temp_real = ixheaacd_add32_sat(inp[0], inp[2]);
1633 temp_imag = ixheaacd_add32_sat(inp[1], inp[3]);
1634
1635 add_r = ixheaacd_add32_sat(inp[2], inp[4]);
1636 add_i = ixheaacd_add32_sat(inp[3], inp[5]);
1637
1638 sub_r = ixheaacd_sub32_sat(inp[2], inp[4]);
1639 sub_i = ixheaacd_sub32_sat(inp[3], inp[5]);
1640
1641 p1 = add_r >> 1;
1642 p4 = add_i >> 1;
1643 p2 = ixheaacd_mult32_shl(sub_i, sinmu);
1644 p3 = ixheaacd_mult32_shl(sub_r, sinmu);
1645
1646 temp = ixheaacd_sub32(inp[0], p1);
1647
1648 op[0] = ixheaacd_add32_sat(temp_real, inp[4]);
1649 op[1] = ixheaacd_add32_sat(temp_imag, inp[5]);
1650 op[2] = ixheaacd_add32_sat(temp, p2);
1651 op[3] = ixheaacd_sub32_sat(ixheaacd_sub32_sat(inp[1], p3), p4);
1652 op[4] = ixheaacd_sub32_sat(temp, p2);
1653 op[5] = ixheaacd_sub32_sat(ixheaacd_add32_sat(inp[1], p3), p4);
1654
1655 return;
1656 }
1657
ixheaacd_complex_fft_p3(WORD32 * xr,WORD32 * xi,WORD32 nlength,WORD32 fft_mode,WORD32 * preshift)1658 VOID ixheaacd_complex_fft_p3(WORD32 *xr, WORD32 *xi, WORD32 nlength,
1659 WORD32 fft_mode, WORD32 *preshift) {
1660 WORD32 i, j;
1661 WORD32 shift = 0;
1662 WORD32 xr_3[384];
1663 WORD32 xi_3[384];
1664 WORD32 x[1024];
1665 WORD32 y[1024];
1666 WORD32 cnfac, npts;
1667 WORD32 mpass = nlength;
1668 WORD32 n = 0;
1669 WORD32 *ptr_x = x;
1670 WORD32 *ptr_y = y;
1671
1672 cnfac = 0;
1673 while (mpass % 3 == 0) {
1674 mpass /= 3;
1675 cnfac++;
1676 }
1677 npts = mpass;
1678
1679 for (i = 0; i < 3 * cnfac; i++) {
1680 for (j = 0; j < mpass; j++) {
1681 xr_3[j] = xr[3 * j + i];
1682 xi_3[j] = xi[3 * j + i];
1683 }
1684
1685 (*ixheaacd_complex_fft_p2)(xr_3, xi_3, mpass, fft_mode, &shift);
1686
1687 for (j = 0; j < mpass; j++) {
1688 xr[3 * j + i] = xr_3[j];
1689 xi[3 * j + i] = xi_3[j];
1690 }
1691 }
1692
1693 while (npts >> 1) {
1694 n++;
1695 npts = npts >> 1;
1696 }
1697
1698 if (n % 2 == 0)
1699 shift = ((n + 4)) / 2;
1700 else
1701 shift = ((n + 5) / 2);
1702
1703 *preshift = shift - *preshift + 1;
1704
1705 for (i = 0; i < nlength; i++) {
1706 ptr_x[2 * i] = (xr[i] >> 1);
1707 ptr_x[2 * i + 1] = (xi[i] >> 1);
1708 }
1709
1710 {
1711 const WORD32 *w1r, *w1i;
1712 WORD32 tmp;
1713 w1r = ixheaacd_twiddle_table_3pr;
1714 w1i = ixheaacd_twiddle_table_3pi;
1715
1716 if (fft_mode < 0) {
1717 for (i = 0; i < nlength; i += 3) {
1718 tmp = ixheaacd_sub32_sat(ixheaacd_mult32_sat(ptr_x[2 * i], (*w1r)),
1719 ixheaacd_mult32_sat(ptr_x[2 * i + 1], (*w1i)));
1720 ptr_x[2 * i + 1] =
1721 ixheaacd_add32_sat(ixheaacd_mult32_sat(ptr_x[2 * i], (*w1i)),
1722 ixheaacd_mult32_sat(ptr_x[2 * i + 1], (*w1r)));
1723 ptr_x[2 * i] = tmp;
1724
1725 w1r++;
1726 w1i++;
1727
1728 tmp = ixheaacd_sub32_sat(ixheaacd_mult32_sat(ptr_x[2 * i + 2], (*w1r)),
1729 ixheaacd_mult32_sat(ptr_x[2 * i + 3], (*w1i)));
1730 ptr_x[2 * i + 3] =
1731 ixheaacd_add32_sat(ixheaacd_mult32_sat(ptr_x[2 * i + 2], (*w1i)),
1732 ixheaacd_mult32_sat(ptr_x[2 * i + 3], (*w1r)));
1733 ptr_x[2 * i + 2] = tmp;
1734
1735 w1r++;
1736 w1i++;
1737
1738 tmp = ixheaacd_sub32_sat(ixheaacd_mult32_sat(ptr_x[2 * i + 4], (*w1r)),
1739 ixheaacd_mult32_sat(ptr_x[2 * i + 5], (*w1i)));
1740 ptr_x[2 * i + 5] =
1741 ixheaacd_add32_sat(ixheaacd_mult32_sat(ptr_x[2 * i + 4], (*w1i)),
1742 ixheaacd_mult32_sat(ptr_x[2 * i + 5], (*w1r)));
1743 ptr_x[2 * i + 4] = tmp;
1744
1745 w1r += 3 * (128 / mpass - 1) + 1;
1746 w1i += 3 * (128 / mpass - 1) + 1;
1747 }
1748 }
1749
1750 else {
1751 for (i = 0; i < nlength; i += 3) {
1752 tmp = ixheaacd_add32_sat(ixheaacd_mult32_sat(ptr_x[2 * i], (*w1r)),
1753 ixheaacd_mult32_sat(ptr_x[2 * i + 1], (*w1i)));
1754 ptr_x[2 * i + 1] =
1755 ixheaacd_sub32_sat(ixheaacd_mult32_sat(ptr_x[2 * i + 1], (*w1r)),
1756 ixheaacd_mult32_sat(ptr_x[2 * i], (*w1i)));
1757 ptr_x[2 * i] = tmp;
1758
1759 w1r++;
1760 w1i++;
1761
1762 tmp = ixheaacd_add32_sat(ixheaacd_mult32_sat(ptr_x[2 * i + 2], (*w1r)),
1763 ixheaacd_mult32_sat(ptr_x[2 * i + 3], (*w1i)));
1764 ptr_x[2 * i + 3] =
1765 ixheaacd_sub32_sat(ixheaacd_mult32_sat(ptr_x[2 * i + 3], (*w1r)),
1766 ixheaacd_mult32_sat(ptr_x[2 * i + 2], (*w1i)));
1767 ptr_x[2 * i + 2] = tmp;
1768
1769 w1r++;
1770 w1i++;
1771
1772 tmp = ixheaacd_add32_sat(ixheaacd_mult32_sat(ptr_x[2 * i + 4], (*w1r)),
1773 ixheaacd_mult32_sat(ptr_x[2 * i + 5], (*w1i)));
1774 ptr_x[2 * i + 5] =
1775 ixheaacd_sub32_sat(ixheaacd_mult32_sat(ptr_x[2 * i + 5], (*w1r)),
1776 ixheaacd_mult32_sat(ptr_x[2 * i + 4], (*w1i)));
1777 ptr_x[2 * i + 4] = tmp;
1778
1779 w1r += 3 * (128 / mpass - 1) + 1;
1780 w1i += 3 * (128 / mpass - 1) + 1;
1781 }
1782 }
1783 }
1784
1785 for (i = 0; i < mpass; i++) {
1786 ixheaacd_complex_3point_fft(ptr_x, ptr_y, fft_mode);
1787
1788 ptr_x = ptr_x + 6;
1789 ptr_y = ptr_y + 6;
1790 }
1791
1792 for (i = 0; i < mpass; i++) {
1793 xr[i] = y[6 * i];
1794 xi[i] = y[6 * i + 1];
1795 }
1796
1797 for (i = 0; i < mpass; i++) {
1798 xr[mpass + i] = y[6 * i + 2];
1799 xi[mpass + i] = y[6 * i + 3];
1800 }
1801
1802 for (i = 0; i < mpass; i++) {
1803 xr[2 * mpass + i] = y[6 * i + 4];
1804 xi[2 * mpass + i] = y[6 * i + 5];
1805 }
1806 return;
1807 }
1808
ixheaacd_complex_fft(WORD32 * data_r,WORD32 * data_i,WORD32 nlength,WORD32 fft_mode,WORD32 * preshift)1809 VOID ixheaacd_complex_fft(WORD32 *data_r, WORD32 *data_i, WORD32 nlength,
1810 WORD32 fft_mode, WORD32 *preshift) {
1811 if (nlength & (nlength - 1)) {
1812 if ((nlength != 24) && (nlength != 48) && (nlength != 96) &&
1813 (nlength != 192) && (nlength != 384)) {
1814 printf("%d point FFT not supported", nlength);
1815 exit(0);
1816 }
1817 ixheaacd_complex_fft_p3(data_r, data_i, nlength, fft_mode, preshift);
1818 } else
1819 (*ixheaacd_complex_fft_p2)(data_r, data_i, nlength, fft_mode, preshift);
1820
1821 return;
1822 }
1823