xref: /aosp_15_r20/external/libxaac/decoder/ixheaacd_mps_hybrid_filt.c (revision 15dc779a375ca8b5125643b829a8aa4b70d7f451)
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 <string.h>
21 #include "ixheaac_type_def.h"
22 #include "ixheaacd_bitbuffer.h"
23 #include "ixheaacd_common_rom.h"
24 #include "ixheaacd_sbrdecsettings.h"
25 #include "ixheaacd_sbr_scale.h"
26 #include "ixheaacd_env_extr_part.h"
27 #include "ixheaacd_sbr_rom.h"
28 #include "ixheaacd_hybrid.h"
29 #include "ixheaacd_ps_dec.h"
30 #include "ixheaacd_config.h"
31 #include "ixheaacd_qmf_dec.h"
32 #include "ixheaacd_mps_polyphase.h"
33 #include "ixheaac_constants.h"
34 #include "ixheaacd_mps_struct_def.h"
35 #include "ixheaacd_mps_res_rom.h"
36 #include "ixheaacd_mps_aac_struct.h"
37 #include "ixheaacd_mps_dec.h"
38 #include "ixheaac_basic_ops32.h"
39 #include "ixheaac_basic_ops40.h"
40 #include "ixheaacd_mps_macro_def.h"
41 #include "ixheaacd_mps_basic_op.h"
42 
43 extern const FLOAT32 ixheaacd_ia_mps_hyb_filter_coeff_8[QMF_HYBRID_FILT_ORDER];
44 extern const FLOAT32 ixheaacd_mps_hyb_filter_coeff_2[QMF_HYBRID_FILT_ORDER];
45 
46 extern const FLOAT32 ixheaacd_sine[8][8];
47 extern const FLOAT32 ixheaacd_cosine[8][8];
48 
ixheaacd_mps_hyb_filt_type1(ia_cmplx_flt_struct * input,ia_cmplx_flt_struct output[8][MAX_TIME_SLOTS],WORD32 num_samples,const FLOAT32 * filt_coeff)49 static VOID ixheaacd_mps_hyb_filt_type1(ia_cmplx_flt_struct *input,
50                                         ia_cmplx_flt_struct output[8][MAX_TIME_SLOTS],
51                                         WORD32 num_samples, const FLOAT32 *filt_coeff) {
52   WORD32 i, n, q;
53 
54   FLOAT32 in_re, in_im;
55   FLOAT32 coeff;
56   FLOAT32 acc_re_l, acc_re_h, acc_im_l, acc_im_h;
57 
58   for (i = 0; i < num_samples; i++) {
59     FLOAT32 x0_re[13], x0_im[13], x0_1_re[8], x0_1_im[8];
60     FLOAT32 acc_re_val[8], acc_im_val[8];
61     for (n = 0; n < QMF_HYBRID_FILT_ORDER; n++) {
62       in_re = input[n + i].re;
63       in_im = input[n + i].im;
64 
65       coeff = filt_coeff[QMF_HYBRID_FILT_ORDER - 1 - n];
66 
67       x0_re[n] = coeff * in_re;
68       x0_im[n] = coeff * in_im;
69     }
70 
71     x0_1_re[0] = x0_re[6];
72     x0_1_im[0] = x0_im[6];
73 
74     x0_1_re[1] = x0_re[7];
75     x0_1_im[1] = x0_im[7];
76 
77     x0_1_re[2] = x0_re[8] - x0_re[0];
78     x0_1_im[2] = x0_im[8] - x0_im[0];
79 
80     x0_1_re[3] = x0_re[9] - x0_re[1];
81     x0_1_im[3] = x0_im[9] - x0_im[1];
82 
83     x0_1_re[4] = x0_re[10] - x0_re[2];
84     x0_1_im[4] = x0_im[10] - x0_im[2];
85 
86     x0_1_re[5] = x0_re[11] - x0_re[3];
87     x0_1_im[5] = x0_im[11] - x0_im[3];
88 
89     x0_1_re[6] = x0_re[12] - x0_re[4];
90     x0_1_im[6] = x0_im[12] - x0_im[4];
91 
92     x0_1_re[7] = -(x0_re[5]);
93     x0_1_im[7] = -(x0_im[5]);
94 
95     acc_re_val[0] = x0_1_re[0];
96     acc_re_val[1] = x0_1_re[1] - x0_1_re[7];
97     acc_re_val[2] = x0_1_re[2] - x0_1_re[6];
98     acc_re_val[3] = x0_1_re[3] - x0_1_re[5];
99     acc_re_val[4] = x0_1_im[1] + x0_1_im[7];
100     acc_re_val[5] = x0_1_im[2] + x0_1_im[6];
101     acc_re_val[6] = x0_1_im[3] + x0_1_im[5];
102     acc_re_val[7] = x0_1_im[4];
103 
104     acc_im_val[0] = x0_1_im[0];
105     acc_im_val[1] = x0_1_im[1] - x0_1_im[7];
106     acc_im_val[2] = x0_1_im[2] - x0_1_im[6];
107     acc_im_val[3] = x0_1_im[3] - x0_1_im[5];
108     acc_im_val[4] = x0_1_re[1] + x0_1_re[7];
109     acc_im_val[5] = x0_1_re[2] + x0_1_re[6];
110     acc_im_val[6] = x0_1_re[3] + x0_1_re[5];
111     acc_im_val[7] = x0_1_re[4];
112 
113     for (q = 0; q < 4; q++) {
114       acc_re_l = 0;
115       acc_im_l = 0;
116       acc_re_h = 0;
117       acc_im_h = 0;
118 
119       acc_re_l += acc_re_val[0];
120       acc_re_l += acc_re_val[1] * ixheaacd_cosine[q][1];
121       acc_re_l += acc_re_val[2] * ixheaacd_cosine[q][2];
122       acc_re_l += acc_re_val[3] * ixheaacd_cosine[q][3];
123 
124       acc_re_h = acc_re_l;
125 
126       acc_re_l -= acc_re_val[4] * ixheaacd_sine[q][1];
127       acc_re_l -= acc_re_val[5] * ixheaacd_sine[q][2];
128       acc_re_l -= acc_re_val[6] * ixheaacd_sine[q][3];
129       acc_re_l -= acc_re_val[7] * ixheaacd_sine[q][4];
130 
131       acc_re_h = acc_re_h - (acc_re_l - acc_re_h);
132 
133       acc_im_l += acc_im_val[0];
134       acc_im_l += acc_im_val[1] * ixheaacd_cosine[q][1];
135       acc_im_l += acc_im_val[2] * ixheaacd_cosine[q][2];
136       acc_im_l += acc_im_val[3] * ixheaacd_cosine[q][3];
137 
138       acc_im_h = acc_im_l;
139 
140       acc_im_l += acc_im_val[4] * ixheaacd_sine[q][1];
141       acc_im_l += acc_im_val[5] * ixheaacd_sine[q][2];
142       acc_im_l += acc_im_val[6] * ixheaacd_sine[q][3];
143       acc_im_l += acc_im_val[7] * ixheaacd_sine[q][4];
144 
145       acc_im_h = acc_im_h - (acc_im_l - acc_im_h);
146 
147       output[q][i].re = acc_re_l;
148       output[q][i].im = acc_im_l;
149 
150       output[7 - q][i].re = acc_re_h;
151       output[7 - q][i].im = acc_im_h;
152     }
153   }
154 }
155 
ixheaacd_mps_hyb_filt_type2(ia_cmplx_flt_struct * input,ia_cmplx_flt_struct output[2][MAX_TIME_SLOTS],WORD32 num_samples,const FLOAT32 * filt_coeff)156 static VOID ixheaacd_mps_hyb_filt_type2(ia_cmplx_flt_struct *input,
157                                         ia_cmplx_flt_struct output[2][MAX_TIME_SLOTS],
158                                         WORD32 num_samples, const FLOAT32 *filt_coeff) {
159   WORD32 i, n;
160 
161   FLOAT32 in_re, in_im;
162   FLOAT32 coeff;
163   FLOAT32 acc_re[2], acc_im[2];
164 
165   for (i = 0; i < num_samples; i++) {
166     FLOAT32 x_0_re[13], x_0_im[13];
167 
168     for (n = 1; n < 6; n = n + 2) {
169       in_re = input[n + i].re;
170       in_im = input[n + i].im;
171 
172       in_re += input[12 - n + i].re;
173       in_im += input[12 - n + i].im;
174 
175       coeff = filt_coeff[QMF_HYBRID_FILT_ORDER - 1 - n];
176 
177       x_0_re[n] = coeff * in_re;
178       x_0_im[n] = coeff * in_im;
179     }
180 
181     n = 6;
182     in_re = input[n + i].re;
183     in_im = input[n + i].im;
184 
185     coeff = filt_coeff[QMF_HYBRID_FILT_ORDER - 1 - n];
186 
187     x_0_re[n] = coeff * in_re;
188     x_0_im[n] = coeff * in_im;
189 
190     x_0_re[1] = x_0_re[1] + x_0_re[3] + x_0_re[5];
191     x_0_im[1] = x_0_im[1] + x_0_im[3] + x_0_im[5];
192 
193     acc_re[0] = x_0_re[6] + x_0_re[1];
194     acc_im[0] = x_0_im[6] + x_0_im[1];
195 
196     acc_re[1] = x_0_re[6] - x_0_re[1];
197     acc_im[1] = x_0_im[6] - x_0_im[1];
198 
199     output[0][i].re = acc_re[0];
200     output[0][i].im = acc_im[0];
201 
202     output[1][i].re = acc_re[1];
203     output[1][i].im = acc_im[1];
204   }
205 }
206 
ixheaacd_mps_qmf_hybrid_analysis_init(ia_mps_hybrid_filt_struct * handle)207 VOID ixheaacd_mps_qmf_hybrid_analysis_init(ia_mps_hybrid_filt_struct *handle) {
208   memset(handle->lf_buffer, 0,
209          QMF_BANDS_TO_HYBRID * BUFFER_LEN_LF_MPS * sizeof(ia_cmplx_w32_struct));
210   memset(handle->hf_buffer, 0,
211          MAX_NUM_QMF_BANDS_MPS * BUFFER_LEN_HF_MPS * sizeof(ia_cmplx_flt_struct));
212 }
213 
ixheaacd_mps_qmf_hybrid_analysis_no_pre_mix(ia_mps_hybrid_filt_struct * handle,ia_cmplx_flt_struct in_qmf[MAX_NUM_QMF_BANDS_MPS][MAX_TIME_SLOTS],WORD32 num_bands,WORD32 num_samples,ia_cmplx_flt_struct v[MAX_TIME_SLOTS][MAX_HYBRID_BANDS_MPS])214 VOID ixheaacd_mps_qmf_hybrid_analysis_no_pre_mix(
215     ia_mps_hybrid_filt_struct *handle,
216     ia_cmplx_flt_struct in_qmf[MAX_NUM_QMF_BANDS_MPS][MAX_TIME_SLOTS], WORD32 num_bands,
217     WORD32 num_samples, ia_cmplx_flt_struct v[MAX_TIME_SLOTS][MAX_HYBRID_BANDS_MPS]) {
218   WORD32 lf_samples_shift;
219   WORD32 hf_samples_shift;
220   WORD32 lf_qmf_bands;
221   WORD32 k, n;
222 
223   ia_cmplx_flt_struct scratch[MAX_HYBRID_ONLY_BANDS_PER_QMF][MAX_TIME_SLOTS];
224 
225   lf_samples_shift = BUFFER_LEN_LF_MPS - num_samples;
226   hf_samples_shift = BUFFER_LEN_HF_MPS - num_samples;
227 
228   lf_qmf_bands = QMF_BANDS_TO_HYBRID;
229 
230   for (k = 0; k < lf_qmf_bands; k++) {
231     memmove(&handle->lf_buffer[k][0].re, &handle->lf_buffer[k][num_samples].re,
232             2 * lf_samples_shift * sizeof(FLOAT32));
233   }
234 
235   for (k = 0; k < lf_qmf_bands; k++) {
236     memcpy(&handle->lf_buffer[k][lf_samples_shift].re, &in_qmf[k][0].re,
237            2 * num_samples * sizeof(FLOAT32));
238   }
239 
240   for (k = 0; k < MAX_NUM_QMF_BANDS_SAC / 2 - lf_qmf_bands; k++) {
241     memmove(&handle->hf_buffer[k][0].re, &handle->hf_buffer[k][num_samples].re,
242             2 * hf_samples_shift * sizeof(FLOAT32));
243   }
244 
245   for (k = 0; k < num_bands - lf_qmf_bands; k++) {
246     memcpy(&handle->hf_buffer[k][hf_samples_shift].re, &in_qmf[k + lf_qmf_bands][0].re,
247            2 * num_samples * sizeof(FLOAT32));
248   }
249 
250   ixheaacd_mps_hyb_filt_type1(
251       &(handle->lf_buffer[0][lf_samples_shift + 1 - QMF_HYBRID_FILT_ORDER]), scratch, num_samples,
252       ixheaacd_ia_mps_hyb_filter_coeff_8);
253 
254   for (k = 0; k < 2; k++) {
255     for (n = 0; n < num_samples; n++) {
256       v[n][k].re = scratch[k + 6][n].re;
257       v[n][k + 2].re = scratch[k][n].re;
258       v[n][k + 4].re = scratch[k + 2][n].re;
259       v[n][k + 4].re += scratch[5 - k][n].re;
260 
261       v[n][k].im = scratch[k + 6][n].im;
262       v[n][k + 2].im = scratch[k][n].im;
263       v[n][k + 4].im = scratch[k + 2][n].im;
264       v[n][k + 4].im += scratch[5 - k][n].im;
265     }
266   }
267 
268   ixheaacd_mps_hyb_filt_type2(
269       &(handle->lf_buffer[1][lf_samples_shift + 1 - QMF_HYBRID_FILT_ORDER]), scratch, num_samples,
270       ixheaacd_mps_hyb_filter_coeff_2);
271 
272   for (k = 0; k < 2; k++) {
273     for (n = 0; n < num_samples; n++) {
274       v[n][k + 6].re = scratch[1 - k][n].re;
275       v[n][k + 6].im = scratch[1 - k][n].im;
276     }
277   }
278 
279   ixheaacd_mps_hyb_filt_type2(
280       &(handle->lf_buffer[2][lf_samples_shift + 1 - QMF_HYBRID_FILT_ORDER]), scratch, num_samples,
281       ixheaacd_mps_hyb_filter_coeff_2);
282 
283   for (k = 0; k < 2; k++) {
284     for (n = 0; n < num_samples; n++) {
285       v[n][k + 8].re = scratch[k][n].re;
286       v[n][k + 8].im = scratch[k][n].im;
287     }
288   }
289 
290   for (k = 0; k < num_bands - lf_qmf_bands; k++) {
291     for (n = 0; n < num_samples; n++) {
292       v[n][k + 10].re = (handle->hf_buffer[k][n + hf_samples_shift].re);
293       v[n][k + 10].im = (handle->hf_buffer[k][n + hf_samples_shift].im);
294     }
295   }
296 }
297 
ixheaacd_mps_qmf_hybrid_analysis(ia_mps_hybrid_filt_struct * handle,ia_cmplx_flt_struct in_qmf[MAX_NUM_QMF_BANDS_MPS_NEW][MAX_TIME_SLOTS],WORD32 num_bands,WORD32 num_samples,ia_cmplx_flt_struct hyb[MAX_HYBRID_BANDS_MPS][MAX_TIME_SLOTS])298 VOID ixheaacd_mps_qmf_hybrid_analysis(
299     ia_mps_hybrid_filt_struct *handle,
300     ia_cmplx_flt_struct in_qmf[MAX_NUM_QMF_BANDS_MPS_NEW][MAX_TIME_SLOTS], WORD32 num_bands,
301     WORD32 num_samples, ia_cmplx_flt_struct hyb[MAX_HYBRID_BANDS_MPS][MAX_TIME_SLOTS]) {
302   WORD32 lf_samples_shift;
303   WORD32 hf_samples_shift;
304   WORD32 lf_qmf_bands;
305   WORD32 k, n;
306 
307   ia_cmplx_flt_struct scratch[MAX_HYBRID_ONLY_BANDS_PER_QMF][MAX_TIME_SLOTS];
308 
309   lf_samples_shift = BUFFER_LEN_LF_MPS - num_samples;
310   hf_samples_shift = BUFFER_LEN_HF_MPS - num_samples;
311 
312   lf_qmf_bands = QMF_BANDS_TO_HYBRID;
313 
314   for (k = 0; k < lf_qmf_bands; k++) {
315     memmove(&handle->lf_buffer[k][0].re, &handle->lf_buffer[k][num_samples].re,
316             2 * lf_samples_shift * sizeof(FLOAT32));
317   }
318 
319   for (k = 0; k < lf_qmf_bands; k++) {
320     memcpy(&handle->lf_buffer[k][lf_samples_shift].re, &in_qmf[k][0].re,
321            2 * num_samples * sizeof(FLOAT32));
322   }
323 
324   for (k = 0; k < MAX_NUM_QMF_BANDS_SAC / 2 - lf_qmf_bands; k++) {
325     memmove(&handle->hf_buffer[k][0].re, &handle->hf_buffer[k][num_samples].re,
326             2 * hf_samples_shift * sizeof(FLOAT32));
327   }
328 
329   for (k = 0; k < num_bands - lf_qmf_bands; k++) {
330     memcpy(&handle->hf_buffer[k][hf_samples_shift].re, &in_qmf[k + lf_qmf_bands][0].re,
331            2 * num_samples * sizeof(FLOAT32));
332   }
333 
334   ixheaacd_mps_hyb_filt_type1(
335       &(handle->lf_buffer[0][lf_samples_shift + 1 - QMF_HYBRID_FILT_ORDER]), scratch, num_samples,
336       ixheaacd_ia_mps_hyb_filter_coeff_8);
337 
338   for (k = 0; k < 2; k++) {
339     for (n = 0; n < num_samples; n++) {
340       hyb[k][n].re = scratch[k + 6][n].re;
341       hyb[k + 2][n].re = scratch[k][n].re;
342       hyb[k + 4][n].re = scratch[k + 2][n].re;
343       hyb[k + 4][n].re += scratch[5 - k][n].re;
344 
345       hyb[k][n].im = scratch[k + 6][n].im;
346       hyb[k + 2][n].im = scratch[k][n].im;
347       hyb[k + 4][n].im = scratch[k + 2][n].im;
348       hyb[k + 4][n].im += scratch[5 - k][n].im;
349     }
350   }
351 
352   ixheaacd_mps_hyb_filt_type2(
353       &(handle->lf_buffer[1][lf_samples_shift + 1 - QMF_HYBRID_FILT_ORDER]), scratch, num_samples,
354       ixheaacd_mps_hyb_filter_coeff_2);
355 
356   for (k = 0; k < 2; k++) {
357     for (n = 0; n < num_samples; n++) {
358       hyb[k + 6][n].re = scratch[1 - k][n].re;
359       hyb[k + 6][n].im = scratch[1 - k][n].im;
360     }
361   }
362 
363   ixheaacd_mps_hyb_filt_type2(
364       &(handle->lf_buffer[2][lf_samples_shift + 1 - QMF_HYBRID_FILT_ORDER]), scratch, num_samples,
365       ixheaacd_mps_hyb_filter_coeff_2);
366 
367   for (k = 0; k < 2; k++) {
368     for (n = 0; n < num_samples; n++) {
369       hyb[k + 8][n].re = scratch[k][n].re;
370       hyb[k + 8][n].im = scratch[k][n].im;
371     }
372   }
373 
374   for (k = 0; k < num_bands - lf_qmf_bands; k++) {
375     memcpy(&hyb[k + 10][0].re, &handle->hf_buffer[k][hf_samples_shift].re,
376            2 * num_samples * sizeof(FLOAT32));
377   }
378 }
379 
ixheaacd_mps_qmf_hybrid_synthesis(ia_cmplx_flt_struct hyb[MAX_TIME_SLOTS][MAX_HYBRID_BANDS_MPS],WORD32 num_bands,WORD32 num_samples,ia_cmplx_flt_struct in_qmf[MAX_TIME_SLOTS][MAX_NUM_QMF_BANDS_MPS])380 VOID ixheaacd_mps_qmf_hybrid_synthesis(
381     ia_cmplx_flt_struct hyb[MAX_TIME_SLOTS][MAX_HYBRID_BANDS_MPS], WORD32 num_bands,
382     WORD32 num_samples, ia_cmplx_flt_struct in_qmf[MAX_TIME_SLOTS][MAX_NUM_QMF_BANDS_MPS]) {
383   WORD32 k, n;
384 
385   for (n = 0; n < num_samples; n++) {
386     in_qmf[n][0].re = hyb[n][0].re;
387     in_qmf[n][0].im = hyb[n][0].im;
388 
389     for (k = 1; k < 6; k++) {
390       in_qmf[n][0].re += hyb[n][k].re;
391       in_qmf[n][0].im += hyb[n][k].im;
392     }
393 
394     in_qmf[n][1].re = hyb[n][6].re + hyb[n][7].re;
395     in_qmf[n][1].im = hyb[n][6].im + hyb[n][7].im;
396 
397     in_qmf[n][2].re = hyb[n][8].re + hyb[n][9].re;
398     in_qmf[n][2].im = hyb[n][8].im + hyb[n][9].im;
399 
400     memcpy(&in_qmf[n][3].re, &hyb[n][10].re, 2 * (num_bands - 3) * sizeof(FLOAT32));
401   }
402 }
403 
ixheaacd_mps_fft(complex * out,LOOPINDEX idx,WORD32 nob,const ia_mps_dec_hybrid_tables_struct * hyb_tab)404 VOID ixheaacd_mps_fft(complex *out, LOOPINDEX idx, WORD32 nob,
405                       const ia_mps_dec_hybrid_tables_struct *hyb_tab) {
406   LOOPINDEX block_per_stage, stage_num, inner;
407   const WORD32 *cosine_array = hyb_tab->cosine_array;
408   const WORD32 *sine_array = hyb_tab->sine_array;
409   WORD32 index_1, index_2, index, tab_modifier;
410   WORD32 len, increment, i;
411 
412   WORD32 cos_val;
413   WORD32 sin_val;
414 
415   WORD16 index1;
416   WORD32 re_temp;
417   WORD32 im_temp;
418   WORD32 *out1_w32, *out2_w32;
419 
420   len = idx;
421   i = 1;
422   increment = 0;
423 
424   len = len >> 1;
425   index_1 = 0;
426   increment += 1;
427 
428   index = 11 - increment;
429   tab_modifier = ixheaac_shl32(1, index);
430 
431   out1_w32 = (WORD32 *)&out[index_1];
432   out2_w32 = (WORD32 *)&out[index_1 + 1];
433 
434   for (block_per_stage = 0; block_per_stage < len; block_per_stage++) {
435     re_temp = out2_w32[0];
436     im_temp = out2_w32[1];
437 
438     out2_w32[0] = (out1_w32[0] - re_temp);
439     out2_w32[1] = (out1_w32[1] - im_temp);
440 
441     out1_w32[0] = (re_temp + out1_w32[0]);
442     out1_w32[1] = (im_temp + out1_w32[1]);
443 
444     out1_w32 += 4;
445     out2_w32 += 4;
446   }
447 
448   i <<= 1;
449 
450   for (stage_num = 1; stage_num < nob; stage_num++) {
451     len = len >> 1;
452     index_1 = 0;
453     increment += 1;
454 
455     index = 11 - increment;
456     tab_modifier = ixheaac_shl32(1, index);
457 
458     for (block_per_stage = 0; block_per_stage < len; block_per_stage++) {
459       index_2 = index_1 + i;
460 
461       out1_w32 = (WORD32 *)&out[index_1];
462       out2_w32 = (WORD32 *)&out[index_2];
463 
464       re_temp = out1_w32[0];
465       im_temp = out1_w32[1];
466 
467       out1_w32[0] = (re_temp + out2_w32[0]) >> 1;
468       out1_w32[1] = (im_temp + out2_w32[1]) >> 1;
469 
470       out2_w32[0] = (re_temp - out2_w32[0]) >> 1;
471       out2_w32[1] = (im_temp - out2_w32[1]) >> 1;
472 
473       index1 = tab_modifier;
474 
475       out1_w32 += 2;
476       out2_w32 += 2;
477 
478       for (inner = 0; inner < ((i - 1) << 1); inner += 2) {
479         cos_val = cosine_array[index1];
480         sin_val = sine_array[index1];
481 
482         re_temp = ixheaacd_mps_mult32x16_shr_16(out2_w32[inner], cos_val) +
483                   ixheaacd_mps_mult32x16_shr_16(out2_w32[inner + 1], sin_val);
484         im_temp = ixheaacd_mps_mult32x16_shr_16(out2_w32[inner + 1], cos_val) -
485                   ixheaacd_mps_mult32x16_shr_16(out2_w32[inner], sin_val);
486 
487         out1_w32[inner] >>= 1;
488         out1_w32[inner + 1] >>= 1;
489 
490         out2_w32[inner] = out1_w32[inner] - re_temp;
491         out2_w32[inner + 1] = out1_w32[inner + 1] - im_temp;
492 
493         out1_w32[inner] = (out1_w32[inner] + re_temp);
494         out1_w32[inner + 1] = (out1_w32[inner + 1] + im_temp);
495 
496         index1 += tab_modifier;
497       }
498 
499       index_1 += ixheaac_shl32(1, increment);
500     }
501     i <<= 1;
502   }
503 }
504 
ixheaacd_8ch_filtering(const WORD32 * p_qmf_real,const WORD32 * p_qmf_imag,WORD32 * m_hybrid_real,WORD32 * m_hybrid_imag,const ia_mps_dec_hybrid_tables_struct * hyb_tab)505 VOID ixheaacd_8ch_filtering(const WORD32 *p_qmf_real, const WORD32 *p_qmf_imag,
506                             WORD32 *m_hybrid_real, WORD32 *m_hybrid_imag,
507                             const ia_mps_dec_hybrid_tables_struct *hyb_tab) {
508   WORD32 n;
509   WORD32 real, imag;
510   const WORD16 tcos = COS_PI_BY_8;
511   const WORD16 tsin = SIN_PI_BY_8;
512   WORD32 cum[16];
513   WORD32 *p_complex;
514   const WORD16 *p8_13 = hyb_tab->p8_13;
515 
516   real = ixheaac_shl32((ixheaac_mult32x16in32(p_qmf_real[4], p8_13[4]) +
517                          ixheaac_mult32x16in32(p_qmf_real[12], p8_13[12])),
518                         1);
519   imag = ixheaac_shl32((ixheaac_mult32x16in32(p_qmf_imag[4], p8_13[4]) +
520                          ixheaac_mult32x16in32(p_qmf_imag[12], p8_13[12])),
521                         1);
522 
523   cum[5] = imag - real;
524   cum[4] = -(imag + real);
525 
526   real = ixheaac_shl32((ixheaac_mult32x16in32(p_qmf_real[3], p8_13[3]) +
527                          ixheaac_mult32x16in32(p_qmf_real[11], p8_13[11])),
528                         1);
529   imag = ixheaac_shl32((ixheaac_mult32x16in32(p_qmf_imag[3], p8_13[3]) +
530                          ixheaac_mult32x16in32(p_qmf_imag[11], p8_13[11])),
531                         1);
532 
533   cum[13] = ixheaac_shl32(
534       (ixheaac_mult32x16in32(imag, tcos) - ixheaac_mult32x16in32(real, tsin)), 1);
535   cum[12] = ixheaac_shl32(
536       -((ixheaac_mult32x16in32(imag, tsin) + ixheaac_mult32x16in32(real, tcos))), 1);
537 
538   cum[2] = ixheaac_shl32(ixheaac_mult32x16in32((p_qmf_real[2] - p_qmf_real[10]), p8_13[10]), 1);
539   cum[3] = ixheaac_shl32(ixheaac_mult32x16in32((p_qmf_imag[2] - p_qmf_imag[10]), p8_13[2]), 1);
540 
541   real = ixheaac_shl32((ixheaac_mult32x16in32(p_qmf_real[1], p8_13[1]) +
542                          ixheaac_mult32x16in32(p_qmf_real[9], p8_13[9])),
543                         1);
544   imag = ixheaac_shl32((ixheaac_mult32x16in32(p_qmf_imag[1], p8_13[1]) +
545                          ixheaac_mult32x16in32(p_qmf_imag[9], p8_13[9])),
546                         1);
547 
548   cum[11] = ixheaac_shl32(
549       (ixheaac_mult32x16in32(imag, tcos) + ixheaac_mult32x16in32(real, tsin)), 1);
550   cum[10] = ixheaac_shl32(
551       (ixheaac_mult32x16in32(imag, tsin) - ixheaac_mult32x16in32(real, tcos)), 1);
552 
553   real = ixheaac_shl32((ixheaac_mult32x16in32(p_qmf_real[0], p8_13[0]) +
554                          ixheaac_mult32x16in32(p_qmf_real[8], p8_13[8])),
555                         1);
556   imag = ixheaac_shl32((ixheaac_mult32x16in32(p_qmf_imag[0], p8_13[0]) +
557                          ixheaac_mult32x16in32(p_qmf_imag[8], p8_13[8])),
558                         1);
559 
560   cum[7] = imag + real;
561   cum[6] = imag - real;
562 
563   cum[15] = ixheaac_shl32((ixheaac_mult32x16in32(p_qmf_imag[7], p8_13[14]) +
564                             ixheaac_mult32x16in32(p_qmf_real[7], p8_13[13])),
565                            1);
566   cum[14] = ixheaac_shl32((ixheaac_mult32x16in32(p_qmf_imag[7], p8_13[13]) -
567                             ixheaac_mult32x16in32(p_qmf_real[7], p8_13[14])),
568                            1);
569 
570   cum[1] = ixheaac_shl32(
571       ixheaac_mult32x16in32(p_qmf_real[HYBRID_FILTER_DELAY], p8_13[HYBRID_FILTER_DELAY]), 1);
572   cum[0] = ixheaac_shl32(
573       ixheaac_mult32x16in32(p_qmf_imag[HYBRID_FILTER_DELAY], p8_13[HYBRID_FILTER_DELAY]), 1);
574 
575   cum[9] = ixheaac_shl32((ixheaac_mult32x16in32(p_qmf_real[5], p8_13[13]) -
576                            ixheaac_mult32x16in32(p_qmf_imag[5], p8_13[14])),
577                           1);
578   cum[8] = ixheaac_shl32((ixheaac_mult32x16in32(p_qmf_real[5], p8_13[14]) +
579                            ixheaac_mult32x16in32(p_qmf_imag[5], p8_13[13])),
580                           1);
581 
582   ixheaacd_mps_fft((complex *)cum, 8, 3, hyb_tab);
583 
584   p_complex = cum;
585 
586   for (n = 0; n < 8; n++) {
587     m_hybrid_imag[n] = *p_complex++;
588     m_hybrid_real[n] = *p_complex++;
589   }
590 }
591 
ixheaacd_2ch_filtering(WORD32 * p_qmf,WORD32 * m_hybrid,const ia_mps_dec_hybrid_tables_struct * hyb_tab_ptr)592 VOID ixheaacd_2ch_filtering(WORD32 *p_qmf, WORD32 *m_hybrid,
593                             const ia_mps_dec_hybrid_tables_struct *hyb_tab_ptr) {
594   WORD32 cum0, cum1;
595   WORD64 temp;
596   const WORD16 *p2_6 = hyb_tab_ptr->p2_6;
597 
598   cum0 = (WORD32)p_qmf[HYBRID_FILTER_DELAY] >> 1;
599 
600   temp = (WORD64)((WORD64)p2_6[0] * (WORD64)(p_qmf[1] + p_qmf[11]) +
601                   (WORD64)p2_6[1] * (WORD64)(p_qmf[3] + p_qmf[9]));
602   temp += (WORD64)p2_6[2] * (WORD64)(p_qmf[5] + p_qmf[7]);
603   cum1 = (WORD32)(temp >> 16);
604 
605   m_hybrid[0] = cum0 + cum1;
606   m_hybrid[1] = cum0 - cum1;
607 }
608 
ixheaacd_get_qmf_sb(WORD32 hybrid_subband,const ia_mps_dec_mdct2qmf_table_struct * ixheaacd_mps_dec_mdct2qmf_table)609 WORD32 ixheaacd_get_qmf_sb(
610     WORD32 hybrid_subband,
611     const ia_mps_dec_mdct2qmf_table_struct *ixheaacd_mps_dec_mdct2qmf_table) {
612   return ixheaacd_mps_dec_mdct2qmf_table->hybrid_2_qmf[hybrid_subband];
613 }
614 
ixheaacd_init_ana_hyb_filt_bank(ia_mps_dec_thyb_filter_state_struct * hyb_state)615 VOID ixheaacd_init_ana_hyb_filt_bank(ia_mps_dec_thyb_filter_state_struct *hyb_state) {
616   WORD32 k, n;
617 
618   for (k = 0; k < QMF_BANDS_TO_HYBRID; k++) {
619     for (n = 0; n < PROTO_LEN - 1 + MAX_TIME_SLOTS; n++) {
620       hyb_state->buffer_lf_real[k][n] = 0;
621       hyb_state->buffer_lf_imag[k][n] = 0;
622       hyb_state->qmf_lf_real[k][n] = 0;
623       hyb_state->qmf_lf_imag[k][n] = 0;
624     }
625   }
626 
627   for (k = 0; k < MAX_NUM_QMF_BANDS; k++) {
628     for (n = 0; n < ((PROTO_LEN - 1) >> 1) + MAX_TIME_SLOTS; n++) {
629       hyb_state->buffer_hf_real[k][n] = 0;
630       hyb_state->buffer_hf_imag[k][n] = 0;
631     }
632   }
633 }
634 
ixheaacd_apply_ana_hyb_filt_bank_create_x(ia_mps_dec_thyb_filter_state_struct * hyb_state,WORD32 * m_qmf_real,WORD32 * m_qmf_imag,WORD32 nr_bands,WORD32 nr_samples,WORD32 * m_hybrid_real,WORD32 * m_hybrid_imag,const ia_mps_dec_hybrid_tables_struct * hyb_tab_ptr)635 VOID ixheaacd_apply_ana_hyb_filt_bank_create_x(
636     ia_mps_dec_thyb_filter_state_struct *hyb_state, WORD32 *m_qmf_real, WORD32 *m_qmf_imag,
637     WORD32 nr_bands, WORD32 nr_samples, WORD32 *m_hybrid_real, WORD32 *m_hybrid_imag,
638     const ia_mps_dec_hybrid_tables_struct *hyb_tab_ptr) {
639   WORD32 nr_samples_shift_lf;
640   WORD32 nr_qmf_bands_lf;
641   WORD32 k, n;
642   WORD32 time_slot;
643 
644   WORD32 proto_len = (PROTO_LEN - 1) >> 1;
645   WORD32 val = nr_samples - proto_len;
646   WORD32 val_xhb = val * MAX_HYBRID_BANDS;
647   WORD32 loop_cnt, loop_cnt_x4;
648   WORD32 *p_qmf_real, *p_qmf_re, *p_qmf_imag, *p_qmf_im;
649 
650   WORD32 m_temp_output_real[MAX_HYBRID_ONLY_BANDS_PER_QMF];
651   WORD32 m_temp_output_imag[MAX_HYBRID_ONLY_BANDS_PER_QMF];
652 
653   WORD32 *p_hybrid_real = m_hybrid_real + 10;
654   WORD32 *p_hybrid_imag = m_hybrid_imag + 10;
655 
656   WORD32 *p_hybrid_re, *p_hybrid_im;
657 
658   nr_samples_shift_lf = BUFFER_LEN_LF - nr_samples;
659 
660   nr_qmf_bands_lf = QMF_BANDS_TO_HYBRID;
661   loop_cnt = nr_bands - nr_qmf_bands_lf;
662   loop_cnt_x4 = (loop_cnt << 2);
663 
664   for (k = 0; k < nr_qmf_bands_lf; k++) {
665     for (n = 0; n < nr_samples_shift_lf; n++) {
666       hyb_state->buffer_lf_real[k][n] = hyb_state->buffer_lf_real[k][n + nr_samples];
667       hyb_state->buffer_lf_imag[k][n] = hyb_state->buffer_lf_imag[k][n + nr_samples];
668 
669       hyb_state->qmf_lf_real[k][n] = hyb_state->qmf_lf_real[k][n + nr_samples];
670       hyb_state->qmf_lf_imag[k][n] = hyb_state->qmf_lf_imag[k][n + nr_samples];
671     }
672   }
673 
674   p_qmf_real = m_qmf_real;
675   p_qmf_imag = m_qmf_imag;
676   for (k = 0; k < nr_qmf_bands_lf; k++) {
677     p_qmf_re = p_qmf_real;
678     p_qmf_im = p_qmf_imag;
679 
680     for (n = 0; n < nr_samples; n++) {
681       hyb_state->buffer_lf_real[k][n + nr_samples_shift_lf] = *p_qmf_re;
682       hyb_state->buffer_lf_imag[k][n + nr_samples_shift_lf] = *p_qmf_im;
683 
684       hyb_state->qmf_lf_imag[k][n + nr_samples_shift_lf] = *p_qmf_im;
685       hyb_state->qmf_lf_real[k][n + nr_samples_shift_lf] = *p_qmf_re;
686 
687       p_qmf_re += MAX_HYBRID_BANDS;
688       p_qmf_im += MAX_HYBRID_BANDS;
689     }
690 
691     p_qmf_real++;
692     p_qmf_imag++;
693   }
694 
695   p_qmf_real = m_qmf_real + nr_qmf_bands_lf + val_xhb;
696   p_qmf_imag = m_qmf_imag + nr_qmf_bands_lf + val_xhb;
697 
698   for (n = 0; n < proto_len; n++) {
699     p_qmf_re = p_qmf_real;
700     p_qmf_im = p_qmf_imag;
701 
702     p_hybrid_re = p_hybrid_real;
703     p_hybrid_im = p_hybrid_imag;
704 
705     for (k = 0; k < loop_cnt; k++) {
706       *p_hybrid_re++ = hyb_state->buffer_hf_real[k][n];
707       *p_hybrid_im++ = hyb_state->buffer_hf_imag[k][n];
708 
709       hyb_state->buffer_hf_real[k][n] = *p_qmf_re++;
710       hyb_state->buffer_hf_imag[k][n] = *p_qmf_im++;
711     }
712     p_qmf_real += MAX_HYBRID_BANDS;
713     p_qmf_imag += MAX_HYBRID_BANDS;
714 
715     p_hybrid_real += MAX_HYBRID_BANDS;
716     p_hybrid_imag += MAX_HYBRID_BANDS;
717   }
718 
719   p_qmf_real = m_qmf_real;
720   p_qmf_imag = m_qmf_imag;
721 
722   p_hybrid_real = m_hybrid_real + 10;
723   p_hybrid_imag = m_hybrid_imag + 10;
724 
725   k = proto_len * MAX_HYBRID_BANDS;
726 
727   p_hybrid_re = p_hybrid_real + k;
728   p_hybrid_im = p_hybrid_imag + k;
729 
730   p_qmf_re = p_qmf_real + nr_qmf_bands_lf;
731   p_qmf_im = p_qmf_imag + nr_qmf_bands_lf;
732 
733   for (n = 0; n < val; n++) {
734     memcpy(p_hybrid_re, p_qmf_re, loop_cnt_x4);
735     memcpy(p_hybrid_im, p_qmf_im, loop_cnt_x4);
736 
737     p_qmf_re += MAX_HYBRID_BANDS;
738     p_qmf_im += MAX_HYBRID_BANDS;
739 
740     p_hybrid_re += MAX_HYBRID_BANDS;
741     p_hybrid_im += MAX_HYBRID_BANDS;
742   }
743 
744   p_hybrid_real = m_hybrid_real;
745   p_hybrid_imag = m_hybrid_imag;
746 
747   for (time_slot = 0; time_slot < nr_samples; time_slot++) {
748     p_hybrid_re = p_hybrid_real;
749     p_hybrid_im = p_hybrid_imag;
750 
751     ixheaacd_8ch_filtering(
752         &(hyb_state->buffer_lf_real[0][time_slot + nr_samples_shift_lf + 1 - PROTO_LEN]),
753         &(hyb_state->buffer_lf_imag[0][time_slot + nr_samples_shift_lf + 1 - PROTO_LEN]),
754         m_temp_output_real, m_temp_output_imag, hyb_tab_ptr);
755 
756     *p_hybrid_re++ = m_temp_output_real[6];
757     *p_hybrid_re++ = m_temp_output_real[7];
758     *p_hybrid_re++ = m_temp_output_real[0];
759     *p_hybrid_re++ = m_temp_output_real[1];
760     *p_hybrid_re++ = (m_temp_output_real[2] + m_temp_output_real[5]);
761     *p_hybrid_re++ = (m_temp_output_real[3] + m_temp_output_real[4]);
762 
763     *p_hybrid_im++ = m_temp_output_imag[6];
764     *p_hybrid_im++ = m_temp_output_imag[7];
765     *p_hybrid_im++ = m_temp_output_imag[0];
766     *p_hybrid_im++ = m_temp_output_imag[1];
767     *p_hybrid_im++ = (m_temp_output_imag[2] + m_temp_output_imag[5]);
768     *p_hybrid_im++ = (m_temp_output_imag[3] + m_temp_output_imag[4]);
769 
770     ixheaacd_2ch_filtering(
771         &(hyb_state->buffer_lf_real[1][time_slot + nr_samples_shift_lf + 1 - PROTO_LEN]),
772         m_temp_output_real, hyb_tab_ptr);
773 
774     ixheaacd_2ch_filtering(
775         &(hyb_state->buffer_lf_imag[1][time_slot + nr_samples_shift_lf + 1 - PROTO_LEN]),
776         m_temp_output_imag, hyb_tab_ptr);
777 
778     *p_hybrid_re++ = m_temp_output_real[1];
779     *p_hybrid_re++ = m_temp_output_real[0];
780 
781     *p_hybrid_im++ = m_temp_output_imag[1];
782     *p_hybrid_im++ = m_temp_output_imag[0];
783 
784     ixheaacd_2ch_filtering(
785         &(hyb_state->buffer_lf_real[2][time_slot + nr_samples_shift_lf + 1 - PROTO_LEN]),
786         m_temp_output_real, hyb_tab_ptr);
787 
788     ixheaacd_2ch_filtering(
789         &(hyb_state->buffer_lf_imag[2][time_slot + nr_samples_shift_lf + 1 - PROTO_LEN]),
790         m_temp_output_imag, hyb_tab_ptr);
791 
792     *p_hybrid_re++ = m_temp_output_real[0];
793     *p_hybrid_re++ = m_temp_output_real[1];
794 
795     *p_hybrid_im++ = m_temp_output_imag[0];
796     *p_hybrid_im++ = m_temp_output_imag[1];
797 
798     p_hybrid_real += MAX_HYBRID_BANDS;
799     p_hybrid_imag += MAX_HYBRID_BANDS;
800   }
801 
802   p_qmf_real = m_qmf_real;
803   p_qmf_imag = m_qmf_imag;
804   for (k = 0; k < nr_qmf_bands_lf; k++) {
805     p_qmf_re = p_qmf_real;
806     p_qmf_im = p_qmf_imag;
807     for (n = MAX_TIME_SLOTS; n < nr_samples_shift_lf; n++) {
808       hyb_state->buffer_lf_real[k][n] = hyb_state->qmf_lf_real[k][n];
809       hyb_state->buffer_lf_imag[k][n] = hyb_state->qmf_lf_imag[k][n];
810     }
811     for (n = 0; n < nr_samples; n++) {
812       hyb_state->buffer_lf_real[k][n + nr_samples_shift_lf] = *p_qmf_re;
813       hyb_state->buffer_lf_imag[k][n + nr_samples_shift_lf] = *p_qmf_im;
814 
815       p_qmf_re += MAX_HYBRID_BANDS;
816       p_qmf_im += MAX_HYBRID_BANDS;
817     }
818     p_qmf_real++;
819     p_qmf_imag++;
820   }
821 }
822 
ixheaacd_apply_ana_hyb_filt_bank_merge_res_decor(ia_mps_dec_thyb_filter_state_struct * hyb_state,WORD32 * m_qmf_real,WORD32 * m_qmf_imag,WORD32 nr_bands,WORD32 nr_samples,WORD32 * m_hybrid_real,WORD32 * m_hybrid_imag,const ia_mps_dec_hybrid_tables_struct * hyb_tab_ptr)823 VOID ixheaacd_apply_ana_hyb_filt_bank_merge_res_decor(
824     ia_mps_dec_thyb_filter_state_struct *hyb_state, WORD32 *m_qmf_real, WORD32 *m_qmf_imag,
825     WORD32 nr_bands, WORD32 nr_samples, WORD32 *m_hybrid_real, WORD32 *m_hybrid_imag,
826     const ia_mps_dec_hybrid_tables_struct *hyb_tab_ptr) {
827   WORD32 nr_samples_shift_lf;
828   WORD32 nr_qmf_bands_lf;
829   WORD32 k, n;
830   WORD32 time_slot;
831 
832   WORD32 m_temp_output_real[MAX_HYBRID_ONLY_BANDS_PER_QMF];
833   WORD32 m_temp_output_imag[MAX_HYBRID_ONLY_BANDS_PER_QMF];
834 
835   WORD32 proto_len = (PROTO_LEN - 1) >> 1;
836   WORD32 val = nr_samples - proto_len;
837   WORD32 loop_cnt;
838 
839   WORD32 *p_qmf_real = m_qmf_real;
840   WORD32 *p_qmf_imag = m_qmf_imag;
841 
842   WORD32 *p_hybrid_real = m_hybrid_real + 10;
843   WORD32 *p_hybrid_imag = m_hybrid_imag + 10;
844   WORD32 *p_buffer_lf_real, *p_buffer_lf_imag;
845 
846   WORD32 nr_samples_x4 = nr_samples << 2;
847 
848   nr_samples_shift_lf = BUFFER_LEN_LF - nr_samples;
849 
850   nr_qmf_bands_lf = QMF_BANDS_TO_HYBRID;
851   loop_cnt = nr_bands - nr_qmf_bands_lf;
852 
853   for (k = 0; k < nr_qmf_bands_lf; k++) {
854     for (n = 0; n < nr_samples_shift_lf; n++) {
855       hyb_state->buffer_lf_real[k][n] = hyb_state->buffer_lf_real[k][n + nr_samples];
856       hyb_state->buffer_lf_imag[k][n] = hyb_state->buffer_lf_imag[k][n + nr_samples];
857 
858       hyb_state->qmf_lf_real[k][n] = hyb_state->qmf_lf_real[k][n + nr_samples];
859       hyb_state->qmf_lf_imag[k][n] = hyb_state->qmf_lf_imag[k][n + nr_samples];
860     }
861   }
862   for (k = 0; k < nr_qmf_bands_lf; k++) {
863     WORD32 *qmf_real = p_qmf_real;
864     WORD32 *qmf_imag = p_qmf_imag;
865     for (n = 0; n < nr_samples; n++) {
866       hyb_state->buffer_lf_real[k][n + nr_samples_shift_lf] = *qmf_real;
867       hyb_state->buffer_lf_imag[k][n + nr_samples_shift_lf] = *qmf_imag;
868 
869       hyb_state->qmf_lf_imag[k][n + nr_samples_shift_lf] = *qmf_imag++;
870       hyb_state->qmf_lf_real[k][n + nr_samples_shift_lf] = *qmf_real++;
871     }
872     p_qmf_real += MAX_TIME_SLOTS;
873     p_qmf_imag += MAX_TIME_SLOTS;
874   }
875 
876   p_qmf_real = m_qmf_real + nr_qmf_bands_lf * MAX_TIME_SLOTS;
877   p_qmf_imag = m_qmf_imag + nr_qmf_bands_lf * MAX_TIME_SLOTS;
878 
879   for (k = 0; k < loop_cnt; k++) {
880     WORD32 *qmf_real = p_qmf_real + val;
881     WORD32 *qmf_imag = p_qmf_imag + val;
882 
883     WORD32 *hybrid_real = p_hybrid_real;
884     WORD32 *hybrid_imag = p_hybrid_imag;
885 
886     for (n = 0; n < proto_len; n++) {
887       *hybrid_real = hyb_state->buffer_hf_real[k][n];
888       *hybrid_imag = hyb_state->buffer_hf_imag[k][n];
889 
890       hyb_state->buffer_hf_real[k][n] = *qmf_real++;
891       hyb_state->buffer_hf_imag[k][n] = *qmf_imag++;
892 
893       hybrid_real += MAX_HYBRID_BANDS;
894       hybrid_imag += MAX_HYBRID_BANDS;
895     }
896 
897     p_qmf_real += MAX_TIME_SLOTS;
898     p_qmf_imag += MAX_TIME_SLOTS;
899 
900     p_hybrid_real++;
901     p_hybrid_imag++;
902   }
903 
904   p_qmf_real = m_qmf_real + NR_QMF_BANDS_LFXTS;
905   p_qmf_imag = m_qmf_imag + NR_QMF_BANDS_LFXTS;
906 
907   p_hybrid_real = m_hybrid_real + 10;
908   p_hybrid_imag = m_hybrid_imag + 10;
909 
910   for (k = 0; k < loop_cnt; k++) {
911     WORD32 *qmf_real = p_qmf_real;
912     WORD32 *qmf_imag = p_qmf_imag;
913 
914     WORD32 *hybrid_real = p_hybrid_real + proto_len * MAX_HYBRID_BANDS;
915     WORD32 *hybrid_imag = p_hybrid_imag + proto_len * MAX_HYBRID_BANDS;
916 
917     for (n = 0; n < val; n++) {
918       *hybrid_real = *qmf_real++;
919       *hybrid_imag = *qmf_imag++;
920 
921       hybrid_real += MAX_HYBRID_BANDS;
922       hybrid_imag += MAX_HYBRID_BANDS;
923     }
924 
925     p_qmf_real += MAX_TIME_SLOTS;
926     p_qmf_imag += MAX_TIME_SLOTS;
927 
928     p_hybrid_real++;
929     p_hybrid_imag++;
930   }
931 
932   p_hybrid_real = m_hybrid_real;
933   p_hybrid_imag = m_hybrid_imag;
934 
935   for (time_slot = 0; time_slot < nr_samples; time_slot++) {
936     WORD32 *hybrid_real = p_hybrid_real;
937     WORD32 *hybrid_imag = p_hybrid_imag;
938 
939     ixheaacd_8ch_filtering(
940         &(hyb_state->buffer_lf_real[0][time_slot + nr_samples_shift_lf + 1 - PROTO_LEN]),
941         &(hyb_state->buffer_lf_imag[0][time_slot + nr_samples_shift_lf + 1 - PROTO_LEN]),
942         m_temp_output_real, m_temp_output_imag, hyb_tab_ptr);
943 
944     *hybrid_real++ = m_temp_output_real[6];
945     *hybrid_real++ = m_temp_output_real[7];
946     *hybrid_real++ = m_temp_output_real[0];
947     *hybrid_real++ = m_temp_output_real[1];
948     *hybrid_imag++ = (m_temp_output_imag[2] + m_temp_output_imag[5]);
949     *hybrid_real++ = (m_temp_output_real[3] + m_temp_output_real[4]);
950 
951     *hybrid_imag++ = m_temp_output_imag[6];
952     *hybrid_imag++ = m_temp_output_imag[7];
953     *hybrid_imag++ = m_temp_output_imag[0];
954     *hybrid_imag++ = m_temp_output_imag[1];
955     *hybrid_real++ = (m_temp_output_real[2] + m_temp_output_real[5]);
956     *hybrid_imag++ = (m_temp_output_imag[3] + m_temp_output_imag[4]);
957 
958     ixheaacd_2ch_filtering(
959         &(hyb_state->buffer_lf_real[1][time_slot + nr_samples_shift_lf + 1 - PROTO_LEN]),
960         m_temp_output_real, hyb_tab_ptr);
961 
962     ixheaacd_2ch_filtering(
963         &(hyb_state->buffer_lf_imag[1][time_slot + nr_samples_shift_lf + 1 - PROTO_LEN]),
964         m_temp_output_imag, hyb_tab_ptr);
965 
966     *hybrid_real++ = m_temp_output_real[1];
967     *hybrid_real++ = m_temp_output_real[0];
968 
969     *hybrid_imag++ = m_temp_output_imag[0];
970     *hybrid_imag++ = m_temp_output_imag[1];
971 
972     ixheaacd_2ch_filtering(
973         &(hyb_state->buffer_lf_real[2][time_slot + nr_samples_shift_lf + 1 - PROTO_LEN]),
974         m_temp_output_real, hyb_tab_ptr);
975 
976     ixheaacd_2ch_filtering(
977         &(hyb_state->buffer_lf_imag[2][time_slot + nr_samples_shift_lf + 1 - PROTO_LEN]),
978         m_temp_output_imag, hyb_tab_ptr);
979 
980     *hybrid_real++ = m_temp_output_real[0];
981     *hybrid_real++ = m_temp_output_real[1];
982 
983     *hybrid_imag++ = m_temp_output_imag[0];
984     *hybrid_imag++ = m_temp_output_imag[1];
985 
986     p_hybrid_real += MAX_HYBRID_BANDS;
987     p_hybrid_imag += MAX_HYBRID_BANDS;
988   }
989 
990   p_qmf_real = m_qmf_real;
991   p_qmf_imag = m_qmf_imag;
992 
993   p_buffer_lf_real = &hyb_state->buffer_lf_real[0][nr_samples_shift_lf];
994   p_buffer_lf_imag = &hyb_state->buffer_lf_imag[0][nr_samples_shift_lf];
995 
996   for (k = 0; k < nr_qmf_bands_lf; k++) {
997     for (n = MAX_TIME_SLOTS; n < nr_samples_shift_lf; n++) {
998       hyb_state->buffer_lf_real[k][n] = hyb_state->qmf_lf_real[k][n];
999       hyb_state->buffer_lf_imag[k][n] = hyb_state->qmf_lf_imag[k][n];
1000     }
1001     {
1002       memcpy(p_buffer_lf_real, p_qmf_real, nr_samples_x4);
1003       memcpy(p_buffer_lf_imag, p_qmf_imag, nr_samples_x4);
1004     }
1005     p_qmf_real += MAX_TIME_SLOTS;
1006     p_qmf_imag += MAX_TIME_SLOTS;
1007 
1008     p_buffer_lf_real += BUFFER_LEN_LF;
1009     p_buffer_lf_imag += BUFFER_LEN_LF;
1010   }
1011 }
1012 
ixheaacd_apply_ana_hyb_filt_bank_create_x_res(ia_mps_dec_thyb_filter_state_struct * hyb_state,WORD32 * m_qmf_real,WORD32 * m_qmf_imag,WORD32 nr_bands,WORD32 nr_samples,WORD32 * m_hybrid_real,WORD32 * m_hybrid_imag,SIZE_T * indx,WORD32 res,WORD32 hyb_bands,WORD32 num_parameter_bands,WORD32 * counter,const ia_mps_dec_hybrid_tables_struct * hyb_tab_ptr)1013 VOID ixheaacd_apply_ana_hyb_filt_bank_create_x_res(
1014     ia_mps_dec_thyb_filter_state_struct *hyb_state, WORD32 *m_qmf_real, WORD32 *m_qmf_imag,
1015     WORD32 nr_bands, WORD32 nr_samples, WORD32 *m_hybrid_real, WORD32 *m_hybrid_imag,
1016     SIZE_T *indx, WORD32 res, WORD32 hyb_bands, WORD32 num_parameter_bands, WORD32 *counter,
1017     const ia_mps_dec_hybrid_tables_struct *hyb_tab_ptr) {
1018   WORD32 nr_samples_shift_lf;
1019   WORD32 nr_qmf_bands_lf;
1020   WORD32 k, n, qs;
1021   WORD32 time_slot, ch_off_set;
1022   SIZE_T *idx = indx;
1023 
1024   WORD32 proto_len = (PROTO_LEN - 1) >> 1;
1025   WORD32 val = nr_samples - proto_len;
1026 
1027   WORD32 *p_qmf_real = m_qmf_real;
1028   WORD32 *p_qmf_imag = m_qmf_imag;
1029   WORD32 loop_cnt;
1030 
1031   WORD32 m_temp_output_real[MAX_HYBRID_ONLY_BANDS_PER_QMF];
1032   WORD32 m_temp_output_imag[MAX_HYBRID_ONLY_BANDS_PER_QMF];
1033 
1034   WORD32 *p_hybrid_real = m_hybrid_real + 10;
1035   WORD32 *p_hybrid_imag = m_hybrid_imag + 10;
1036 
1037   WORD32 *p_hybrid_re, *p_hybrid_im;
1038 
1039   WORD32 *p_buffer_lf_real, *p_buffer_lf_imag;
1040 
1041   WORD32 nr_samples_x4 = nr_samples << 2;
1042 
1043   nr_samples_shift_lf = BUFFER_LEN_LF - nr_samples;
1044 
1045   nr_qmf_bands_lf = QMF_BANDS_TO_HYBRID;
1046   loop_cnt = nr_bands - nr_qmf_bands_lf;
1047   ch_off_set = 0;
1048 
1049   for (k = 0; k < nr_qmf_bands_lf; k++) {
1050     for (n = 0; n < nr_samples_shift_lf; n++) {
1051       hyb_state->buffer_lf_real[k][n] = hyb_state->buffer_lf_real[k][n + nr_samples];
1052       hyb_state->buffer_lf_imag[k][n] = hyb_state->buffer_lf_imag[k][n + nr_samples];
1053 
1054       hyb_state->qmf_lf_real[k][n] = hyb_state->qmf_lf_real[k][n + nr_samples];
1055       hyb_state->qmf_lf_imag[k][n] = hyb_state->qmf_lf_imag[k][n + nr_samples];
1056     }
1057   }
1058   for (k = 0; k < nr_qmf_bands_lf; k++) {
1059     WORD32 *qmf_real = p_qmf_real;
1060     WORD32 *qmf_imag = p_qmf_imag;
1061 
1062     for (n = 0; n < nr_samples; n++) {
1063       hyb_state->buffer_lf_real[k][n + nr_samples_shift_lf] = *qmf_real;
1064       hyb_state->buffer_lf_imag[k][n + nr_samples_shift_lf] = *qmf_imag;
1065 
1066       hyb_state->qmf_lf_imag[k][n + nr_samples_shift_lf] = *qmf_imag++;
1067       hyb_state->qmf_lf_real[k][n + nr_samples_shift_lf] = *qmf_real++;
1068     }
1069     p_qmf_real += MAX_TIME_SLOTS;
1070     p_qmf_imag += MAX_TIME_SLOTS;
1071   }
1072 
1073   p_qmf_real = m_qmf_real + NR_QMF_BANDS_LFXTS;
1074   p_qmf_imag = m_qmf_imag + NR_QMF_BANDS_LFXTS;
1075 
1076   for (k = 0; k < loop_cnt; k++) {
1077     WORD32 *qmf_real = p_qmf_real + val;
1078     WORD32 *qmf_imag = p_qmf_imag + val;
1079 
1080     p_hybrid_re = p_hybrid_real;
1081     p_hybrid_im = p_hybrid_imag;
1082 
1083     for (n = 0; n < proto_len; n++) {
1084       *p_hybrid_re = hyb_state->buffer_hf_real[k][n];
1085       *p_hybrid_im = hyb_state->buffer_hf_imag[k][n];
1086 
1087       hyb_state->buffer_hf_real[k][n] = *qmf_real++;
1088       hyb_state->buffer_hf_imag[k][n] = *qmf_imag++;
1089 
1090       p_hybrid_re += MAX_HYBRID_BANDS;
1091       p_hybrid_im += MAX_HYBRID_BANDS;
1092     }
1093     p_qmf_real += MAX_TIME_SLOTS;
1094     p_qmf_imag += MAX_TIME_SLOTS;
1095 
1096     p_hybrid_real++;
1097     p_hybrid_imag++;
1098   }
1099 
1100   p_qmf_real = m_qmf_real + NR_QMF_BANDS_LFXTS;
1101   p_qmf_imag = m_qmf_imag + NR_QMF_BANDS_LFXTS;
1102 
1103   p_hybrid_real = m_hybrid_real + 10;
1104   p_hybrid_imag = m_hybrid_imag + 10;
1105 
1106   for (k = 0; k < loop_cnt; k++) {
1107     WORD32 *qmf_real = p_qmf_real;
1108     WORD32 *qmf_imag = p_qmf_imag;
1109 
1110     p_hybrid_re = p_hybrid_real + proto_len * MAX_HYBRID_BANDS;
1111     p_hybrid_im = p_hybrid_imag + proto_len * MAX_HYBRID_BANDS;
1112 
1113     for (n = 0; n < val; n++) {
1114       *p_hybrid_re = *qmf_real++;
1115       *p_hybrid_im = *qmf_imag++;
1116 
1117       p_hybrid_re += MAX_HYBRID_BANDS;
1118       p_hybrid_im += MAX_HYBRID_BANDS;
1119     }
1120     p_qmf_real += MAX_TIME_SLOTS;
1121     p_qmf_imag += MAX_TIME_SLOTS;
1122 
1123     p_hybrid_real++;
1124     p_hybrid_imag++;
1125   }
1126 
1127   if (res == 1 && (num_parameter_bands == 20 || num_parameter_bands == 28))
1128     *counter = 3;
1129   else {
1130     idx = indx;
1131     for (qs = 0; qs < hyb_bands; qs++) {
1132       if (*idx++ >= (SIZE_T)res) {
1133         *counter = qs;
1134         qs = hyb_bands;
1135       }
1136     }
1137   }
1138 
1139   p_hybrid_real = m_hybrid_real;
1140   p_hybrid_imag = m_hybrid_imag;
1141   for (time_slot = 0; time_slot < nr_samples; time_slot++) {
1142     idx = indx;
1143     p_hybrid_re = p_hybrid_real;
1144     p_hybrid_im = p_hybrid_imag;
1145 
1146     ixheaacd_8ch_filtering(
1147         &(hyb_state->buffer_lf_real[0][time_slot + nr_samples_shift_lf + 1 - PROTO_LEN]),
1148         &(hyb_state->buffer_lf_imag[0][time_slot + nr_samples_shift_lf + 1 - PROTO_LEN]),
1149         m_temp_output_real, m_temp_output_imag, hyb_tab_ptr);
1150 
1151     *p_hybrid_re++ = m_temp_output_real[6];
1152     *p_hybrid_re++ = m_temp_output_real[7];
1153     *p_hybrid_re++ = m_temp_output_real[0];
1154 
1155     *p_hybrid_re++ = m_temp_output_real[1];
1156 
1157     *p_hybrid_im++ = m_temp_output_imag[6];
1158     *p_hybrid_im++ = m_temp_output_imag[7];
1159     *p_hybrid_im++ = m_temp_output_imag[0];
1160     *p_hybrid_im++ = m_temp_output_imag[1];
1161 
1162     if (*counter > 4) {
1163       *p_hybrid_re++ = (m_temp_output_real[2] + m_temp_output_real[5]);
1164       *p_hybrid_im++ = (m_temp_output_imag[2] + m_temp_output_imag[5]);
1165     }
1166 
1167     if (*counter > 5) {
1168       *p_hybrid_re++ = (m_temp_output_real[3] + m_temp_output_real[4]);
1169       *p_hybrid_im++ = (m_temp_output_imag[3] + m_temp_output_imag[4]);
1170     }
1171 
1172     ch_off_set = 6;
1173     p_hybrid_re = p_hybrid_real + ch_off_set;
1174     p_hybrid_im = p_hybrid_imag + ch_off_set;
1175 
1176     ixheaacd_2ch_filtering(
1177         &(hyb_state->buffer_lf_real[1][time_slot + nr_samples_shift_lf + 1 - PROTO_LEN]),
1178         m_temp_output_real, hyb_tab_ptr);
1179 
1180     ixheaacd_2ch_filtering(
1181         &(hyb_state->buffer_lf_imag[1][time_slot + nr_samples_shift_lf + 1 - PROTO_LEN]),
1182         m_temp_output_imag, hyb_tab_ptr);
1183 
1184     *p_hybrid_re++ = m_temp_output_real[1];
1185     *p_hybrid_re++ = m_temp_output_real[0];
1186 
1187     *p_hybrid_im++ = m_temp_output_imag[1];
1188     *p_hybrid_im++ = m_temp_output_imag[0];
1189 
1190     ixheaacd_2ch_filtering(
1191         &(hyb_state->buffer_lf_real[2][time_slot + nr_samples_shift_lf + 1 - PROTO_LEN]),
1192         m_temp_output_real, hyb_tab_ptr);
1193 
1194     ixheaacd_2ch_filtering(
1195         &(hyb_state->buffer_lf_imag[2][time_slot + nr_samples_shift_lf + 1 - PROTO_LEN]),
1196         m_temp_output_imag, hyb_tab_ptr);
1197 
1198     *p_hybrid_re++ = m_temp_output_real[0];
1199     *p_hybrid_re++ = m_temp_output_real[1];
1200 
1201     *p_hybrid_im++ = m_temp_output_imag[0];
1202     *p_hybrid_im++ = m_temp_output_imag[1];
1203 
1204     p_hybrid_real += MAX_HYBRID_BANDS;
1205     p_hybrid_imag += MAX_HYBRID_BANDS;
1206   }
1207   p_qmf_real = m_qmf_real;
1208   p_qmf_imag = m_qmf_imag;
1209 
1210   p_buffer_lf_real = &hyb_state->buffer_lf_real[0][nr_samples_shift_lf];
1211   p_buffer_lf_imag = &hyb_state->buffer_lf_imag[0][nr_samples_shift_lf];
1212 
1213   for (k = 0; k < nr_qmf_bands_lf; k++) {
1214     for (n = MAX_TIME_SLOTS; n < nr_samples_shift_lf; n++) {
1215       hyb_state->buffer_lf_real[k][n] = hyb_state->qmf_lf_real[k][n];
1216       hyb_state->buffer_lf_imag[k][n] = hyb_state->qmf_lf_imag[k][n];
1217     }
1218     {
1219       memcpy(p_buffer_lf_real, p_qmf_real, nr_samples_x4);
1220       memcpy(p_buffer_lf_imag, p_qmf_imag, nr_samples_x4);
1221     }
1222     p_qmf_real += MAX_TIME_SLOTS;
1223     p_qmf_imag += MAX_TIME_SLOTS;
1224 
1225     p_buffer_lf_real += BUFFER_LEN_LF;
1226     p_buffer_lf_imag += BUFFER_LEN_LF;
1227   }
1228 }
1229