xref: /aosp_15_r20/external/libxaac/encoder/ixheaace_mps_hybrid_filter.c (revision 15dc779a375ca8b5125643b829a8aa4b70d7f451)
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