1 /******************************************************************************
2 * *
3 * Copyright (C) 2023 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
21 #include <math.h>
22 #include "ixheaac_type_def.h"
23 #include "ixheaace_error_codes.h"
24 #include "ixheaac_error_standards.h"
25 #include "ixheaace_mps_common_fix.h"
26 #include "ixheaace_mps_defines.h"
27 #include "ixheaace_mps_common_define.h"
28 #include "ixheaace_bitbuffer.h"
29
30 #include "ixheaace_mps_struct_def.h"
31 #include "ixheaace_mps_sac_polyphase.h"
32 #include "ixheaace_mps_sac_hybfilter.h"
33 #include "ixheaace_mps_spatial_bitstream.h"
34 #include "ixheaace_mps_bitstream.h"
35 #include "ixheaace_mps_param_extract.h"
36 #include "ixheaace_mps_tree.h"
37 #include "ixheaace_mps_rom.h"
38 #include "ixheaace_mps_sac_hybfilter.h"
39
ixheaace_mps_cfftn_process(FLOAT32 * ptr_real,FLOAT32 * ptr_imag,WORD32 n_total,WORD32 n_pass,WORD32 n_span,WORD32 i_sign)40 static IA_ERRORCODE ixheaace_mps_cfftn_process(FLOAT32 *ptr_real, FLOAT32 *ptr_imag,
41 WORD32 n_total, WORD32 n_pass, WORD32 n_span,
42 WORD32 i_sign) {
43 IA_ERRORCODE error = IA_NO_ERROR;
44 WORD32 repeat = 0;
45 FLOAT64 sine_60 = SIN_60;
46 FLOAT64 cos_72 = COS_72;
47 FLOAT64 sin_72 = SIN_72;
48 FLOAT64 pi2 = M_PI;
49 WORD32 ii, mfactor, kspan, ispan, inc;
50 WORD32 j, jc, jf, jj, k, k1, k2, k3 = 0, k4, kk, kt, nn, ns, nt;
51
52 FLOAT64 radf;
53 FLOAT64 c1, c2 = 0.0, c3 = 0.0, cd;
54 FLOAT64 s1, s2 = 0.0, s3 = 0.0, sd;
55 FLOAT32 temp_real, temp_imag, temp_real_1, temp_imag_1, temp_real_2, temp_imag_2, temp_real_3,
56 temp_imag_3, temp_real_4, temp_imag_4, aj, bj, aa, bb;
57
58 FLOAT32 temp_real_array[MAX_FACTORS] = {0};
59 FLOAT32 temp_imag_array[MAX_FACTORS] = {0};
60 FLOAT64 cos_array[MAX_FACTORS] = {0};
61 FLOAT64 sin_array[MAX_FACTORS] = {0};
62
63 WORD32 perm[MAX_PERM] = {0};
64 WORD32 factor[NFACTOR] = {0};
65 if (n_pass < 2) {
66 return IA_EXHEAACE_EXE_FATAL_MPS_CFFT_PROCESS;
67 }
68
69 ptr_real--;
70 ptr_imag--;
71 inc = i_sign;
72 if (i_sign < 0) {
73 sin_72 = -sin_72;
74 sine_60 = -sine_60;
75 pi2 = -pi2;
76 inc = -inc;
77 }
78 ii = 0;
79 jf = 0;
80 mfactor = 0;
81 j = 3;
82
83 nt = inc * n_total;
84 ns = inc * n_span;
85 kspan = ns;
86 nn = nt - inc;
87 jc = ns / n_pass;
88 radf = pi2 * (FLOAT64)jc;
89 pi2 *= 2.0;
90 k = n_pass;
91
92 while (k % 16 == 0) {
93 mfactor++;
94 factor[mfactor - 1] = 4;
95 k /= 16;
96 }
97
98 jj = 9;
99 do {
100 while (k % jj == 0) {
101 mfactor++;
102 factor[mfactor - 1] = j;
103 k /= jj;
104 }
105 j += 2;
106 jj = j * j;
107 } while (jj <= k);
108
109 if (k > 4) {
110 if (k - (k / 4 << 2) == 0) {
111 mfactor++;
112 factor[mfactor - 1] = 2;
113 k /= 4;
114 }
115
116 kt = mfactor;
117 j = 2;
118
119 do {
120 if (k % j == 0) {
121 mfactor++;
122 factor[mfactor - 1] = j;
123 k /= j;
124 }
125 j = ((j + 1) / 2 << 1) + 1;
126 } while (j <= k);
127 } else {
128 kt = mfactor;
129 factor[mfactor] = k;
130 if (k != 1) {
131 mfactor++;
132 }
133 }
134
135 if (kt) {
136 j = kt;
137 do {
138 mfactor++;
139 factor[mfactor - 1] = factor[j - 1];
140 j--;
141 } while (j);
142 }
143
144 if (mfactor > NFACTOR) {
145 return IA_EXHEAACE_EXE_FATAL_MPS_CFFT_PROCESS;
146 }
147
148 do {
149 sd = radf / (FLOAT64)kspan;
150 cd = sin(sd);
151 cd = 2.0 * cd * cd;
152 sd = sin(sd + sd);
153 kk = 1;
154 ii++;
155 switch (factor[ii - 1]) {
156 case 4:
157 ispan = kspan;
158 (VOID) ispan;
159 kspan /= 4;
160
161 do {
162 c1 = 1.0;
163 s1 = 0.0;
164 do {
165 do {
166 k1 = kk + kspan;
167 k2 = k1 + kspan;
168 k3 = k2 + kspan;
169
170 temp_real_1 = ptr_real[kk] + ptr_real[k2];
171 temp_real_4 = ptr_real[kk] - ptr_real[k2];
172 temp_real_2 = ptr_real[k1] + ptr_real[k3];
173 temp_real_3 = ptr_real[k1] - ptr_real[k3];
174 temp_imag_1 = ptr_imag[kk] + ptr_imag[k2];
175 temp_imag_4 = ptr_imag[kk] - ptr_imag[k2];
176 temp_imag_2 = ptr_imag[k1] + ptr_imag[k3];
177 temp_imag_3 = ptr_imag[k1] - ptr_imag[k3];
178
179 ptr_real[kk] = temp_real_1 + temp_real_2;
180 ptr_imag[kk] = temp_imag_1 + temp_imag_2;
181
182 temp_real_2 = temp_real_1 - temp_real_2;
183 temp_imag_2 = temp_imag_1 - temp_imag_2;
184
185 if (i_sign >= 0) {
186 temp_real_1 = temp_real_4 - temp_imag_3;
187 temp_imag_1 = temp_imag_4 + temp_real_3;
188 temp_real_4 += temp_imag_3;
189 temp_imag_4 -= temp_real_3;
190 } else {
191 temp_real_1 = temp_real_4 + temp_imag_3;
192 temp_imag_1 = temp_imag_4 - temp_real_3;
193 temp_real_4 -= temp_imag_3;
194 temp_imag_4 += temp_real_3;
195 }
196
197 if (s1 == 0.0) {
198 ptr_real[k1] = temp_real_1;
199 ptr_real[k2] = temp_real_2;
200 ptr_real[k3] = temp_real_4;
201 ptr_imag[k1] = temp_imag_1;
202 ptr_imag[k2] = temp_imag_2;
203 ptr_imag[k3] = temp_imag_4;
204 } else {
205 ptr_real[k1] = (FLOAT32)(temp_real_1 * c1 - temp_imag_1 * s1);
206 ptr_real[k2] = (FLOAT32)(temp_real_2 * c2 - temp_imag_2 * s2);
207 ptr_real[k3] = (FLOAT32)(temp_real_4 * c3 - temp_imag_4 * s3);
208
209 ptr_imag[k1] = (FLOAT32)(temp_real_1 * s1 + temp_imag_1 * c1);
210 ptr_imag[k2] = (FLOAT32)(temp_real_2 * s2 + temp_imag_2 * c2);
211 ptr_imag[k3] = (FLOAT32)(temp_real_4 * s3 + temp_imag_4 * c3);
212 }
213
214 kk = k3 + kspan;
215 } while (kk <= nt);
216
217 c2 = c1 - (cd * c1 + sd * s1);
218 s1 = sd * c1 - cd * s1 + s1;
219
220 c1 = 2.0 - (c2 * c2 + s1 * s1);
221 s1 *= c1;
222 c1 *= c2;
223
224 c2 = c1 * c1 - s1 * s1;
225 s2 = 2.0 * c1 * s1;
226
227 c3 = c2 * c1 - s2 * s1;
228 s3 = c2 * s1 + s2 * c1;
229
230 kk = kk - nt + jc;
231 } while (kk <= kspan);
232 kk = kk - kspan + inc;
233
234 } while (kk <= jc);
235 if (kspan == jc) {
236 repeat = 1;
237 break;
238 }
239 break;
240 case 2:
241 kspan /= 2;
242 k1 = kspan + 2;
243 do {
244 do {
245 k2 = kk + kspan;
246 temp_real = ptr_real[k2];
247 temp_imag = ptr_imag[k2];
248 ptr_real[k2] = ptr_real[kk] - temp_real;
249 ptr_imag[k2] = ptr_imag[kk] - temp_imag;
250 ptr_real[kk] += temp_real;
251 ptr_imag[kk] += temp_imag;
252 kk = k2 + kspan;
253 } while (kk <= nn);
254
255 kk -= nn;
256 } while (kk <= jc);
257
258 if (kk > kspan) {
259 repeat = 1;
260 break;
261 }
262
263 do {
264 c1 = 1.0 - cd;
265 s1 = sd;
266 do {
267 do {
268 do {
269 k2 = kk + kspan;
270 temp_real = ptr_real[kk] - ptr_real[k2];
271 temp_imag = ptr_imag[kk] - ptr_imag[k2];
272
273 ptr_real[kk] += ptr_real[k2];
274 ptr_imag[kk] += ptr_imag[k2];
275
276 ptr_real[k2] = (FLOAT32)(c1 * temp_real - s1 * temp_imag);
277 ptr_imag[k2] = (FLOAT32)(s1 * temp_real + c1 * temp_imag);
278
279 kk = k2 + kspan;
280 } while (kk < nt);
281
282 k2 = kk - nt;
283 c1 = -c1;
284 kk = k1 - k2;
285 } while (kk > k2);
286
287 temp_real = (FLOAT32)(c1 - (cd * c1 + sd * s1));
288 s1 = sd * c1 - cd * s1 + s1;
289 c1 = 2.0 - (temp_real * temp_real + s1 * s1);
290
291 s1 *= c1;
292 c1 *= temp_real;
293 kk += jc;
294 } while (kk < k2);
295
296 k1 += inc + inc;
297 kk = (k1 - kspan) / 2 + jc;
298 } while (kk <= jc + jc);
299 break;
300 default:
301 k = factor[ii - 1];
302 ispan = kspan;
303 if (k != 0) kspan /= k;
304
305 switch (k) {
306 case 5:
307 c2 = cos_72 * cos_72 - sin_72 * sin_72;
308 s2 = 2.0 * cos_72 * sin_72;
309 do {
310 do {
311 k1 = kk + kspan;
312 k2 = k1 + kspan;
313 k3 = k2 + kspan;
314 k4 = k3 + kspan;
315
316 temp_real_1 = ptr_real[k1] + ptr_real[k4];
317 temp_real_4 = ptr_real[k1] - ptr_real[k4];
318 temp_imag_1 = ptr_imag[k1] + ptr_imag[k4];
319 temp_imag_4 = ptr_imag[k1] - ptr_imag[k4];
320 temp_real_2 = ptr_real[k2] + ptr_real[k3];
321 temp_real_3 = ptr_real[k2] - ptr_real[k3];
322 temp_imag_2 = ptr_imag[k2] + ptr_imag[k3];
323 temp_imag_3 = ptr_imag[k2] - ptr_imag[k3];
324
325 aa = ptr_real[kk];
326 bb = ptr_imag[kk];
327 ptr_real[kk] = aa + temp_real_1 + temp_real_2;
328 ptr_imag[kk] = bb + temp_imag_1 + temp_imag_2;
329
330 temp_real = (FLOAT32)(temp_real_1 * cos_72 + temp_real_2 * c2 + aa);
331 temp_imag = (FLOAT32)(temp_imag_1 * cos_72 + temp_imag_2 * c2 + bb);
332
333 aj = (FLOAT32)(temp_real_4 * sin_72 + temp_real_3 * s2);
334 bj = (FLOAT32)(temp_imag_4 * sin_72 + temp_imag_3 * s2);
335
336 ptr_real[k1] = temp_real - bj;
337 ptr_real[k4] = temp_real + bj;
338 ptr_imag[k1] = temp_imag + aj;
339 ptr_imag[k4] = temp_imag - aj;
340
341 temp_real = (FLOAT32)(temp_real_1 * c2 + temp_real_2 * cos_72 + aa);
342 temp_imag = (FLOAT32)(temp_imag_1 * c2 + temp_imag_2 * cos_72 + bb);
343
344 aj = (FLOAT32)(temp_real_4 * s2 - temp_real_3 * sin_72);
345 bj = (FLOAT32)(temp_imag_4 * s2 - temp_imag_3 * sin_72);
346
347 ptr_real[k2] = temp_real - bj;
348 ptr_real[k3] = temp_real + bj;
349 ptr_imag[k2] = temp_imag + aj;
350 ptr_imag[k3] = temp_imag - aj;
351
352 kk = k4 + kspan;
353 } while (kk < nn);
354 kk -= nn;
355 } while (kk <= kspan);
356 break;
357 case 3:
358 do {
359 do {
360 k1 = kk + kspan;
361 k2 = k1 + kspan;
362
363 temp_real = ptr_real[kk];
364 temp_imag = ptr_imag[kk];
365
366 aj = ptr_real[k1] + ptr_real[k2];
367 bj = ptr_imag[k1] + ptr_imag[k2];
368
369 ptr_real[kk] = temp_real + aj;
370 ptr_imag[kk] = temp_imag + bj;
371
372 temp_real -= 0.5f * aj;
373 temp_imag -= 0.5f * bj;
374
375 aj = (FLOAT32)((ptr_real[k1] - ptr_real[k2]) * sine_60);
376 bj = (FLOAT32)((ptr_imag[k1] - ptr_imag[k2]) * sine_60);
377
378 ptr_real[k1] = temp_real - bj;
379 ptr_real[k2] = temp_real + bj;
380 ptr_imag[k1] = temp_imag + aj;
381 ptr_imag[k2] = temp_imag - aj;
382
383 kk = k2 + kspan;
384 } while (kk < nn);
385 kk -= nn;
386 } while (kk <= kspan);
387 break;
388
389 default:
390 if (k != jf) {
391 jf = k;
392 s1 = pi2 / (FLOAT64)k;
393
394 c1 = cos(s1);
395 s1 = sin(s1);
396
397 if (jf > MAX_FACTORS) {
398 return IA_EXHEAACE_EXE_FATAL_MPS_CFFT_PROCESS;
399 }
400
401 cos_array[jf - 1] = 1.0;
402 sin_array[jf - 1] = 0.0;
403 j = 1;
404 do {
405 cos_array[j - 1] = cos_array[k - 1] * c1 + sin_array[k - 1] * s1;
406 sin_array[j - 1] = cos_array[k - 1] * s1 - sin_array[k - 1] * c1;
407
408 k--;
409 cos_array[k - 1] = cos_array[j - 1];
410 sin_array[k - 1] = -sin_array[j - 1];
411
412 j++;
413 } while (j < k);
414 }
415 do {
416 do {
417 k1 = kk;
418 k2 = kk + ispan;
419
420 temp_real = aa = ptr_real[kk];
421 temp_imag = bb = ptr_imag[kk];
422
423 j = 1;
424 k1 += kspan;
425 do {
426 k2 -= kspan;
427 j++;
428
429 temp_real_array[j - 1] = ptr_real[k1] + ptr_real[k2];
430 temp_real += temp_real_array[j - 1];
431 temp_imag_array[j - 1] = ptr_imag[k1] + ptr_imag[k2];
432 temp_imag += temp_imag_array[j - 1];
433 j++;
434
435 temp_real_array[j - 1] = ptr_real[k1] - ptr_real[k2];
436 temp_imag_array[j - 1] = ptr_imag[k1] - ptr_imag[k2];
437 k1 += kspan;
438
439 } while (k1 < k2);
440
441 ptr_real[kk] = temp_real;
442 ptr_imag[kk] = temp_imag;
443 k1 = kk;
444 k2 = kk + ispan;
445 j = 1;
446
447 do {
448 k1 += kspan;
449 k2 -= kspan;
450
451 jj = j;
452 temp_real = aa;
453 temp_imag = bb;
454 aj = 0.0;
455 bj = 0.0;
456 k = 1;
457
458 do {
459 k++;
460 temp_real += (FLOAT32)(temp_real_array[k - 1] * cos_array[jj - 1]);
461 temp_imag += (FLOAT32)(temp_imag_array[k - 1] * cos_array[jj - 1]);
462
463 k++;
464 aj += (FLOAT32)(temp_real_array[k - 1] * sin_array[jj - 1]);
465 bj += (FLOAT32)(temp_imag_array[k - 1] * sin_array[jj - 1]);
466
467 jj += j;
468 if (jj > jf) {
469 jj -= jf;
470 }
471 } while (k < jf);
472
473 k = jf - j;
474 ptr_real[k1] = temp_real - bj;
475 ptr_imag[k1] = temp_imag + aj;
476 ptr_real[k2] = temp_real + bj;
477 ptr_imag[k2] = temp_imag - aj;
478
479 j++;
480 } while (j < k);
481 kk += ispan;
482
483 } while (kk <= nn);
484 kk -= nn;
485
486 } while (kk <= kspan);
487 break;
488 }
489
490 if (ii == mfactor) {
491 repeat = 1;
492 break;
493 }
494
495 kk = jc + 1;
496
497 do {
498 c2 = 1.0 - cd;
499 s1 = sd;
500
501 do {
502 c1 = c2;
503 s2 = s1;
504 kk += kspan;
505 do {
506 do {
507 temp_real = ptr_real[kk];
508 ptr_real[kk] = (FLOAT32)(c2 * temp_real - s2 * ptr_imag[kk]);
509 ptr_imag[kk] = (FLOAT32)(s2 * temp_real + c2 * ptr_imag[kk]);
510 kk += ispan;
511
512 } while (kk <= nt);
513
514 temp_real = (FLOAT32)(s1 * s2);
515 s2 = s1 * c2 + c1 * s2;
516 c2 = c1 * c2 - temp_real;
517 kk = kk - nt + kspan;
518
519 } while (kk <= ispan);
520
521 c2 = c1 - (cd * c1 + sd * s1);
522 s1 += sd * c1 - cd * s1;
523 c1 = 2.0 - (c2 * c2 + s1 * s1);
524
525 s1 *= c1;
526 c2 *= c1;
527
528 kk = kk - ispan + jc;
529 } while (kk <= kspan);
530
531 kk = kk - kspan + jc + inc;
532
533 } while (kk <= jc + jc);
534 break;
535 }
536 } while (repeat == 0);
537
538 perm[0] = ns;
539
540 if (kt) {
541 k = kt + kt + 1;
542 if (mfactor < k) {
543 k--;
544 }
545
546 j = 1;
547 perm[k] = jc;
548
549 do {
550 perm[j] = perm[j - 1] / factor[j - 1];
551 perm[k - 1] = perm[k] * factor[j - 1];
552
553 j++;
554 k--;
555 } while (j < k);
556
557 k3 = perm[k];
558 kspan = perm[1];
559 kk = jc + 1;
560 k2 = kspan + 1;
561
562 j = 1;
563
564 if (n_pass == n_total) {
565 do {
566 do {
567 temp_real = ptr_real[kk];
568 ptr_real[kk] = ptr_real[k2];
569 ptr_real[k2] = temp_real;
570 temp_imag = ptr_imag[kk];
571 ptr_imag[kk] = ptr_imag[k2];
572 ptr_imag[k2] = temp_imag;
573
574 kk += inc;
575 k2 += kspan;
576
577 } while (k2 < ns);
578 do {
579 do {
580 k2 -= perm[j - 1];
581 j++;
582 k2 = perm[j] + k2;
583
584 } while (k2 > perm[j - 1]);
585
586 j = 1;
587 do {
588 if (kk < k2) {
589 repeat = 1;
590 break;
591 } else {
592 repeat = 0;
593 }
594
595 kk += inc;
596 k2 += kspan;
597
598 } while (k2 < ns);
599 if (repeat) {
600 break;
601 }
602 } while (kk < ns);
603 } while (repeat);
604 } else {
605 do {
606 do {
607 do {
608 k = kk + jc;
609 do {
610 temp_real = ptr_real[kk];
611 ptr_real[kk] = ptr_real[k2];
612 ptr_real[k2] = temp_real;
613 temp_imag = ptr_imag[kk];
614 ptr_imag[kk] = ptr_imag[k2];
615 ptr_imag[k2] = temp_imag;
616
617 kk += inc;
618 k2 += inc;
619
620 } while (kk < k);
621 kk += ns - jc;
622 k2 += ns - jc;
623
624 } while (kk < nt);
625
626 k2 = k2 - nt + kspan;
627 kk = kk - nt + jc;
628
629 } while (k2 < ns);
630
631 do {
632 do {
633 k2 -= perm[j - 1];
634 j++;
635 k2 = perm[j] + k2;
636 } while (k2 > perm[j - 1]);
637
638 j = 1;
639 do {
640 if (kk >= k2) {
641 repeat = 0;
642 } else {
643 repeat = 1;
644 break;
645 }
646
647 kk += jc;
648 k2 += kspan;
649
650 } while (k2 < ns);
651 if (repeat) {
652 break;
653 }
654 } while (kk < ns);
655 } while (repeat);
656 }
657 jc = k3;
658 }
659
660 if ((kt << 1) + 1 >= mfactor) {
661 return IA_NO_ERROR;
662 }
663
664 ispan = perm[kt];
665 j = mfactor - kt;
666 factor[j] = 1;
667
668 do {
669 factor[j - 1] *= factor[j];
670 j--;
671 } while (j != kt);
672
673 kt++;
674 nn = factor[kt - 1] - 1;
675
676 if (nn > MAX_PERM) {
677 return IA_EXHEAACE_EXE_FATAL_MPS_CFFT_PROCESS;
678 }
679
680 for (j = jj = 0; j <= nn; j++) {
681 k = kt + 1;
682 k2 = factor[kt - 1];
683 kk = factor[k - 1];
684
685 for (jj += kk; jj >= k2;) {
686 jj -= k2;
687 k2 = kk;
688 k++;
689 kk = factor[k - 1];
690 jj += kk;
691 }
692
693 perm[j - 1] = jj;
694 }
695
696 for (j = 0;;) {
697 do {
698 j++;
699 kk = perm[j - 1];
700
701 } while (kk < 0);
702
703 if (kk == j) {
704 perm[j - 1] = -j;
705 if (j == nn) {
706 break;
707 }
708 } else {
709 do {
710 k = kk;
711 kk = perm[k - 1];
712 perm[k - 1] = -kk;
713 } while (kk != j);
714
715 k3 = kk;
716 }
717 }
718 for (;;) {
719 j = k3 + 1;
720 nt -= ispan;
721 ii = nt - inc + 1;
722 if (nt < 0) {
723 break;
724 }
725 do {
726 do {
727 j--;
728 } while (perm[j - 1] < 0);
729
730 jj = jc;
731
732 do {
733 kspan = jj;
734 if (jj > MAX_FACTORS * inc) {
735 kspan = MAX_FACTORS * inc;
736 }
737
738 jj -= kspan;
739 k = perm[j - 1];
740 kk = jc * k + ii + jj;
741 k1 = kk + kspan;
742 k2 = 0;
743
744 do {
745 k2++;
746 temp_real_array[k2 - 1] = ptr_real[k1];
747 temp_imag_array[k2 - 1] = ptr_imag[k1];
748 k1 -= inc;
749 } while (k1 != kk);
750
751 do {
752 k1 = kk + kspan;
753 k2 = k1 - jc * (k + perm[k - 1]);
754 k = -perm[k - 1];
755
756 do {
757 ptr_real[k1] = ptr_real[k2];
758 ptr_imag[k1] = ptr_imag[k2];
759
760 k1 -= inc;
761 k2 -= inc;
762
763 } while (k1 != kk);
764 kk = k2;
765
766 } while (k != j);
767
768 k1 = kk + kspan;
769 k2 = 0;
770
771 do {
772 k2++;
773 ptr_real[k1] = temp_real_array[k2 - 1];
774 ptr_imag[k1] = temp_imag_array[k2 - 1];
775 k1 -= inc;
776
777 } while (k1 != kk);
778 } while (jj);
779 } while (j != 1);
780 }
781 (VOID) ispan;
782 return error;
783 }
784
ixheaace_mps_eight_channel_filtering(const FLOAT32 * ptr_qmf_real,const FLOAT32 * ptr_qmf_imag,FLOAT32 * ptr_hybrid_real,FLOAT32 * ptr_hybrid_imag)785 static IA_ERRORCODE ixheaace_mps_eight_channel_filtering(const FLOAT32 *ptr_qmf_real,
786 const FLOAT32 *ptr_qmf_imag,
787 FLOAT32 *ptr_hybrid_real,
788 FLOAT32 *ptr_hybrid_imag) {
789 IA_ERRORCODE error = IA_NO_ERROR;
790 WORD32 idx;
791 FLOAT32 ptr_real, ptr_imag;
792 FLOAT32 cum[16];
793
794 cum[0] = p8_13[HYBRID_FILTER_DELAY] * ptr_qmf_real[HYBRID_FILTER_DELAY];
795 cum[1] = p8_13[HYBRID_FILTER_DELAY] * ptr_qmf_imag[HYBRID_FILTER_DELAY];
796
797 ptr_real = p8_13[5] * ptr_qmf_real[5];
798 ptr_imag = p8_13[5] * ptr_qmf_imag[5];
799 cum[2] = ptr_real * COS_22_5 - ptr_imag * SIN_22_5;
800 cum[3] = ptr_real * COS_67_5 + ptr_imag * SIN_67_5;
801
802 ptr_real = p8_13[4] * ptr_qmf_real[4] + p8_13[12] * ptr_qmf_real[12];
803 ptr_imag = p8_13[4] * ptr_qmf_imag[4] + p8_13[12] * ptr_qmf_imag[12];
804 cum[4] = (ptr_imag - ptr_real) * INV_SQRT_2;
805 cum[5] = -(ptr_imag + ptr_real) * INV_SQRT_2;
806
807 ptr_real = p8_13[3] * ptr_qmf_real[3] + p8_13[11] * ptr_qmf_real[11];
808 ptr_imag = p8_13[3] * ptr_qmf_imag[3] + p8_13[11] * ptr_qmf_imag[11];
809 cum[6] = ptr_imag * SIN_67_5 - ptr_real * COS_67_5;
810 cum[7] = -(ptr_imag * SIN_22_5 + ptr_real * COS_22_5);
811 cum[9] = -(p8_13[2] * ptr_qmf_real[2] + p8_13[10] * ptr_qmf_real[10]);
812 cum[8] = p8_13[2] * ptr_qmf_imag[2] + p8_13[10] * ptr_qmf_imag[10];
813
814 ptr_real = p8_13[1] * ptr_qmf_real[1] + p8_13[9] * ptr_qmf_real[9];
815 ptr_imag = p8_13[1] * ptr_qmf_imag[1] + p8_13[9] * ptr_qmf_imag[9];
816 cum[10] = ptr_imag * SIN_67_5 + ptr_real * COS_67_5;
817 cum[11] = ptr_imag * SIN_22_5 - ptr_real * COS_22_5;
818
819 ptr_real = p8_13[0] * ptr_qmf_real[0] + p8_13[8] * ptr_qmf_real[8];
820 ptr_imag = p8_13[0] * ptr_qmf_imag[0] + p8_13[8] * ptr_qmf_imag[8];
821 cum[12] = (ptr_imag + ptr_real) * INV_SQRT_2;
822 cum[13] = (ptr_imag - ptr_real) * INV_SQRT_2;
823
824 ptr_real = p8_13[7] * ptr_qmf_real[7];
825 ptr_imag = p8_13[7] * ptr_qmf_imag[7];
826 cum[14] = ptr_imag * SIN_22_5 + ptr_real * COS_22_5;
827 cum[15] = ptr_imag * SIN_67_5 - ptr_real * COS_67_5;
828
829 error = ixheaace_mps_cfftn_process(&cum[0], &cum[1], 8, 8, 8, 2);
830 if (error) {
831 return error;
832 }
833 for (idx = 0; idx < 8; idx++) {
834 ptr_hybrid_real[idx] = cum[2 * idx];
835 ptr_hybrid_imag[idx] = cum[2 * idx + 1];
836 }
837 return error;
838 }
839
ixheaace_mps_two_channel_filtering(const FLOAT32 * p_qmf,FLOAT32 * ptr_hybrid)840 static VOID ixheaace_mps_two_channel_filtering(const FLOAT32 *p_qmf, FLOAT32 *ptr_hybrid) {
841 WORD32 n;
842 FLOAT32 cum0, cum1;
843
844 cum0 = 0.5f * p_qmf[HYBRID_FILTER_DELAY];
845
846 cum1 = 0;
847
848 for (n = 0; n < 6; n++) {
849 cum1 += p2_6[n] * p_qmf[2 * n + 1];
850 }
851
852 ptr_hybrid[0] = cum0 + cum1;
853 ptr_hybrid[1] = cum0 - cum1;
854 }
855
ixheaace_mps_515_apply_ana_hyb_filterbank(ixheaace_mps_pstr_hyb_filter_state pstr_hyb_filter_state,FLOAT32 * ptr_qmf_real,FLOAT32 * ptr_qmf_imag,WORD32 nr_samples,FLOAT32 * ptr_hybrid_real,FLOAT32 * ptr_hybrid_imag)856 VOID ixheaace_mps_515_apply_ana_hyb_filterbank(
857 ixheaace_mps_pstr_hyb_filter_state pstr_hyb_filter_state, FLOAT32 *ptr_qmf_real,
858 FLOAT32 *ptr_qmf_imag, WORD32 nr_samples, FLOAT32 *ptr_hybrid_real,
859 FLOAT32 *ptr_hybrid_imag) {
860 WORD32 nr_samples_shift_lf;
861 WORD32 nr_qmf_bands_lf;
862 WORD32 k, n;
863 WORD32 time_slot, ch_offset;
864
865 FLOAT32 m_temp_output_real[MAX_HYBRID_ONLY_BANDS_PER_QMF] = {0};
866 FLOAT32 m_temp_output_imag[MAX_HYBRID_ONLY_BANDS_PER_QMF] = {0};
867
868 nr_samples_shift_lf = BUFFER_LEN_LF - nr_samples;
869
870 nr_qmf_bands_lf = NUM_QMF_BANDS_TO_LF;
871 for (k = 0; k < nr_qmf_bands_lf; k++) {
872 for (n = 0; n < nr_samples_shift_lf; n++) {
873 pstr_hyb_filter_state->buffer_lf_real[k][n] =
874 pstr_hyb_filter_state->buffer_lf_real[k][n + nr_samples];
875 pstr_hyb_filter_state->buffer_lf_imag[k][n] =
876 pstr_hyb_filter_state->buffer_lf_imag[k][n + nr_samples];
877 }
878 }
879
880 for (k = 0; k < nr_qmf_bands_lf; k++) {
881 for (n = 0; n < nr_samples; n++) {
882 pstr_hyb_filter_state->buffer_lf_real[k][n + nr_samples_shift_lf] =
883 ptr_qmf_real[n * NUM_QMF_BANDS + k];
884 pstr_hyb_filter_state->buffer_lf_imag[k][n + nr_samples_shift_lf] =
885 ptr_qmf_imag[n * NUM_QMF_BANDS + k];
886 }
887 }
888 for (k = 0; k < NUM_QMF_BANDS - nr_qmf_bands_lf; k++) {
889 for (n = 0; n < BUFFER_LEN_HF; n++) {
890 ptr_hybrid_real[n * MAX_HYBRID_BANDS + k + 10] =
891 pstr_hyb_filter_state->buffer_hf_real[k][n];
892 ptr_hybrid_imag[n * MAX_HYBRID_BANDS + k + 10] =
893 pstr_hyb_filter_state->buffer_hf_imag[k][n];
894
895 pstr_hyb_filter_state->buffer_hf_real[k][n] =
896 ptr_qmf_real[(nr_samples - BUFFER_LEN_HF + n) * NUM_QMF_BANDS + k + nr_qmf_bands_lf];
897 pstr_hyb_filter_state->buffer_hf_imag[k][n] =
898 ptr_qmf_imag[(nr_samples - BUFFER_LEN_HF + n) * NUM_QMF_BANDS + k + nr_qmf_bands_lf];
899 }
900 }
901
902 for (k = 0; k < NUM_QMF_BANDS - nr_qmf_bands_lf; k++) {
903 for (n = BUFFER_LEN_HF; n < nr_samples; n++) {
904 ptr_hybrid_real[n * MAX_HYBRID_BANDS + k + 10] =
905 ptr_qmf_real[(n - BUFFER_LEN_HF) * NUM_QMF_BANDS + k + nr_qmf_bands_lf];
906 ptr_hybrid_imag[n * MAX_HYBRID_BANDS + k + 10] =
907 ptr_qmf_imag[(n - BUFFER_LEN_HF) * NUM_QMF_BANDS + k + nr_qmf_bands_lf];
908 }
909 }
910
911 for (time_slot = 0; time_slot < nr_samples; time_slot++) {
912 ch_offset = 0;
913
914 ixheaace_mps_eight_channel_filtering(
915 (const FLOAT32 *)&(pstr_hyb_filter_state->buffer_lf_real[0][nr_samples_shift_lf + 1 -
916 PROTO_LEN + time_slot]),
917 (const FLOAT32 *)&(pstr_hyb_filter_state->buffer_lf_imag[0][nr_samples_shift_lf + 1 -
918 PROTO_LEN + time_slot]),
919 m_temp_output_real, m_temp_output_imag);
920
921 ptr_hybrid_real[time_slot * MAX_HYBRID_BANDS + ch_offset + 0] = m_temp_output_real[6];
922 ptr_hybrid_imag[time_slot * MAX_HYBRID_BANDS + ch_offset + 0] = m_temp_output_imag[6];
923 ptr_hybrid_real[time_slot * MAX_HYBRID_BANDS + ch_offset + 1] = m_temp_output_real[7];
924 ptr_hybrid_imag[time_slot * MAX_HYBRID_BANDS + ch_offset + 1] = m_temp_output_imag[7];
925 ptr_hybrid_real[time_slot * MAX_HYBRID_BANDS + ch_offset + 2] = m_temp_output_real[0];
926 ptr_hybrid_imag[time_slot * MAX_HYBRID_BANDS + ch_offset + 2] = m_temp_output_imag[0];
927 ptr_hybrid_real[time_slot * MAX_HYBRID_BANDS + ch_offset + 3] = m_temp_output_real[1];
928 ptr_hybrid_imag[time_slot * MAX_HYBRID_BANDS + ch_offset + 3] = m_temp_output_imag[1];
929 ptr_hybrid_real[time_slot * MAX_HYBRID_BANDS + ch_offset + 4] =
930 m_temp_output_real[2] + m_temp_output_real[5];
931 ptr_hybrid_imag[time_slot * MAX_HYBRID_BANDS + ch_offset + 4] =
932 m_temp_output_imag[2] + m_temp_output_imag[5];
933 ptr_hybrid_real[time_slot * MAX_HYBRID_BANDS + ch_offset + 5] =
934 m_temp_output_real[3] + m_temp_output_real[4];
935 ptr_hybrid_imag[time_slot * MAX_HYBRID_BANDS + ch_offset + 5] =
936 m_temp_output_imag[3] + m_temp_output_imag[4];
937
938 ch_offset += 6;
939
940 ixheaace_mps_two_channel_filtering(
941 (const FLOAT32 *)&(pstr_hyb_filter_state->buffer_lf_real[1][nr_samples_shift_lf + 1 -
942 PROTO_LEN + time_slot]),
943 m_temp_output_real);
944 ixheaace_mps_two_channel_filtering(
945 (const FLOAT32 *)&(pstr_hyb_filter_state->buffer_lf_imag[1][nr_samples_shift_lf + 1 -
946 PROTO_LEN + time_slot]),
947 m_temp_output_imag);
948 ptr_hybrid_real[time_slot * MAX_HYBRID_BANDS + ch_offset] = m_temp_output_real[1];
949 ptr_hybrid_imag[time_slot * MAX_HYBRID_BANDS + ch_offset] = m_temp_output_imag[1];
950 ptr_hybrid_real[time_slot * MAX_HYBRID_BANDS + ch_offset + 1] = m_temp_output_real[0];
951 ptr_hybrid_imag[time_slot * MAX_HYBRID_BANDS + ch_offset + 1] = m_temp_output_imag[0];
952
953 ch_offset += 2;
954
955 ixheaace_mps_two_channel_filtering(
956 (const FLOAT32 *)&(pstr_hyb_filter_state->buffer_lf_real[2][nr_samples_shift_lf + 1 -
957 PROTO_LEN + time_slot]),
958 m_temp_output_real);
959 ixheaace_mps_two_channel_filtering(
960 (const FLOAT32 *)&(pstr_hyb_filter_state->buffer_lf_imag[2][nr_samples_shift_lf + 1 -
961 PROTO_LEN + time_slot]),
962 m_temp_output_imag);
963
964 ptr_hybrid_real[time_slot * MAX_HYBRID_BANDS + ch_offset] = m_temp_output_real[0];
965 ptr_hybrid_imag[time_slot * MAX_HYBRID_BANDS + ch_offset] = m_temp_output_imag[0];
966 ptr_hybrid_real[time_slot * MAX_HYBRID_BANDS + ch_offset + 1] = m_temp_output_real[1];
967 ptr_hybrid_imag[time_slot * MAX_HYBRID_BANDS + ch_offset + 1] = m_temp_output_imag[1];
968 }
969 }
970
ixheaace_mps_515_apply_syn_hyb_filterbank(FLOAT32 * ptr_hybrid_real,FLOAT32 * ptr_hybrid_imag,WORD32 nr_samples,FLOAT32 * ptr_qmf_real,FLOAT32 * ptr_qmf_imag)971 VOID ixheaace_mps_515_apply_syn_hyb_filterbank(FLOAT32 *ptr_hybrid_real, FLOAT32 *ptr_hybrid_imag,
972 WORD32 nr_samples, FLOAT32 *ptr_qmf_real,
973 FLOAT32 *ptr_qmf_imag) {
974 WORD32 k, n;
975
976 for (n = 0; n < nr_samples; n++) {
977 ptr_qmf_real[n * NUM_QMF_BANDS] = ptr_hybrid_real[n * MAX_HYBRID_BANDS];
978 ptr_qmf_imag[n * NUM_QMF_BANDS] = ptr_hybrid_imag[n * MAX_HYBRID_BANDS];
979
980 for (k = 1; k < 6; k++) {
981 ptr_qmf_real[n * NUM_QMF_BANDS] += ptr_hybrid_real[n * MAX_HYBRID_BANDS + k];
982 ptr_qmf_imag[n * NUM_QMF_BANDS] += ptr_hybrid_imag[n * MAX_HYBRID_BANDS + k];
983 }
984
985 ptr_qmf_real[n * NUM_QMF_BANDS + 1] =
986 ptr_hybrid_real[n * MAX_HYBRID_BANDS + 6] + ptr_hybrid_real[n * MAX_HYBRID_BANDS + 7];
987 ptr_qmf_imag[n * NUM_QMF_BANDS + 1] =
988 ptr_hybrid_imag[n * MAX_HYBRID_BANDS + 6] + ptr_hybrid_imag[n * MAX_HYBRID_BANDS + 7];
989
990 ptr_qmf_real[n * NUM_QMF_BANDS + 2] =
991 ptr_hybrid_real[n * MAX_HYBRID_BANDS + 8] + ptr_hybrid_real[n * MAX_HYBRID_BANDS + 9];
992 ptr_qmf_imag[n * NUM_QMF_BANDS + 2] =
993 ptr_hybrid_imag[n * MAX_HYBRID_BANDS + 8] + ptr_hybrid_imag[n * MAX_HYBRID_BANDS + 9];
994
995 for (k = 0; k < 61; k++) {
996 ptr_qmf_real[n * NUM_QMF_BANDS + k + 3] = ptr_hybrid_real[n * MAX_HYBRID_BANDS + k + 10];
997 ptr_qmf_imag[n * NUM_QMF_BANDS + k + 3] = ptr_hybrid_imag[n * MAX_HYBRID_BANDS + k + 10];
998 }
999 }
1000 }
1001