• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "ixheaacd_sbr_common.h"
22 #include "ixheaacd_type_def.h"
23 
24 #include "ixheaacd_constants.h"
25 #include "ixheaacd_basic_ops32.h"
26 #include "ixheaacd_basic_ops16.h"
27 #include "ixheaacd_basic_ops40.h"
28 #include "ixheaacd_basic_ops.h"
29 
30 #include "ixheaacd_intrinsics.h"
31 #include "ixheaacd_common_rom.h"
32 #include "ixheaacd_bitbuffer.h"
33 #include "ixheaacd_sbrdecsettings.h"
34 #include "ixheaacd_sbr_scale.h"
35 #include "ixheaacd_lpp_tran.h"
36 #include "ixheaacd_env_extr_part.h"
37 #include "ixheaacd_sbr_rom.h"
38 #include "ixheaacd_hybrid.h"
39 #include "ixheaacd_ps_dec.h"
40 #include "ixheaacd_env_extr.h"
41 #include "ixheaacd_qmf_dec.h"
42 
43 #include "ixheaacd_basic_op.h"
44 #include "ixheaacd_env_calc.h"
45 
46 #include "ixheaacd_interface.h"
47 #include "ixheaacd_function_selector.h"
48 #include "ixheaacd_audioobjtypes.h"
49 
50 #define mult16x16_16(a, b) ixheaacd_mult16((a), (b))
51 #define mac16x16(a, b, c) ixheaacd_mac16x16in32_sat((a), (b), (c))
52 #define mpy_32x16(a, b) fixmuldiv2_32x16b((a), (b))
53 #define mpy_16x16(a, b) ixheaacd_mult16x16in32((a), (b))
54 #define mpy_32x32(a, b) ixheaacd_mult32((a), (b))
55 #define mpy_32x16H_n(a, b) ixheaacd_mult32x16hin32((a), (b))
56 #define msu16x16(a, b, c) msu16x16in32((a), (b), (c))
57 
58 #define DCT3_LEN (32)
59 #define DCT2_LEN (64)
60 
61 #define LP_SHIFT_VAL 7
62 #define HQ_SHIFT_64 4
63 #define RADIXSHIFT 1
64 #define ROUNDING_SPECTRA 1
65 #define HQ_SHIFT_VAL 4
66 
ixheaacd_dct3_32(WORD32 * input,WORD32 * output,const WORD16 * main_twidle_fwd,const WORD16 * post_tbl,const WORD16 * w_16,const WORD32 * p_table)67 VOID ixheaacd_dct3_32(WORD32 *input, WORD32 *output,
68                       const WORD16 *main_twidle_fwd, const WORD16 *post_tbl,
69                       const WORD16 *w_16, const WORD32 *p_table) {
70   WORD32 n, k;
71 
72   WORD32 temp1[6];
73   WORD32 temp2[4];
74   WORD16 twid_re, twid_im;
75   WORD32 *ptr_reverse, *ptr_forward, *p_out, *ptr_out1;
76   const WORD16 *twidle_fwd, *twidle_rev;
77 
78   ptr_forward = &input[49];
79   ptr_reverse = &input[47];
80 
81   p_out = output;
82   twidle_fwd = main_twidle_fwd;
83   twidle_fwd += 4;
84 
85   *p_out++ = input[48] >> LP_SHIFT_VAL;
86   *p_out++ = 0;
87 
88   for (n = 1; n < DCT3_LEN / 2; n++) {
89     temp1[0] = *ptr_forward++;
90     temp1[1] = *ptr_reverse--;
91     temp1[0] = ixheaacd_add32_sat(ixheaacd_shr32(temp1[0], LP_SHIFT_VAL),
92                                   ixheaacd_shr32(temp1[1], LP_SHIFT_VAL));
93 
94     temp1[2] = *(ptr_forward - 33);
95     temp1[3] = *(ptr_reverse - 31);
96     temp1[1] = ixheaacd_sub32_sat(ixheaacd_shr32(temp1[2], LP_SHIFT_VAL),
97                                   ixheaacd_shr32(temp1[3], LP_SHIFT_VAL));
98     twid_re = *twidle_fwd++;
99 
100     twid_im = *twidle_fwd;
101     twidle_fwd += 3;
102 
103     *p_out++ = ixheaacd_add32_sat(ixheaacd_mult32x16in32(temp1[0], twid_re),
104                                   ixheaacd_mult32x16in32(temp1[1], twid_im));
105     *p_out++ = ixheaacd_sub32_sat(ixheaacd_mult32x16in32(temp1[0], twid_im),
106                                   ixheaacd_mult32x16in32(temp1[1], twid_re));
107   }
108 
109   twid_re = *twidle_fwd++;
110 
111   twid_im = *twidle_fwd;
112   twidle_fwd += 3;
113 
114   temp1[1] = *ptr_reverse--;
115   temp1[0] = *(ptr_reverse - 31);
116   temp1[1] = ixheaacd_sub32_sat(ixheaacd_shr32(temp1[1], LP_SHIFT_VAL),
117                                 ixheaacd_shr32(temp1[0], LP_SHIFT_VAL));
118 
119   temp1[0] = temp1[1];
120 
121   temp2[2] = ixheaacd_add32_sat(ixheaacd_mult32x16in32(temp1[0], twid_re),
122                                 ixheaacd_mult32x16in32(temp1[1], twid_im));
123   temp2[3] = ixheaacd_sub32_sat(ixheaacd_mult32x16in32(temp1[0], twid_im),
124                                 ixheaacd_mult32x16in32(temp1[1], twid_re));
125 
126   ptr_forward = output;
127   ptr_reverse = &output[DCT3_LEN - 1];
128 
129   temp2[0] = *ptr_forward++;
130   temp2[1] = *ptr_forward--;
131 
132   temp1[0] = ixheaacd_negate32_sat(ixheaacd_add32_sat(temp2[1], temp2[3]));
133   temp1[1] = ixheaacd_sub32_sat(temp2[0], temp2[2]);
134   temp2[0] =
135       ixheaacd_add32_sat(ixheaacd_add32_sat(temp2[0], temp2[2]), temp1[0]);
136   temp2[1] =
137       ixheaacd_add32_sat(ixheaacd_sub32_sat(temp2[1], temp2[3]), temp1[1]);
138 
139   temp2[0] >>= 1;
140   temp2[1] >>= 1;
141 
142   *ptr_forward++ = temp2[0];
143   *ptr_forward++ = temp2[1];
144 
145   twidle_fwd = post_tbl + 2;
146   twidle_rev = post_tbl + 14;
147 
148   for (n = 1; n < DCT3_LEN / 4; n++) {
149     temp2[0] = *ptr_forward++;
150     temp2[1] = *ptr_forward--;
151     temp2[3] = *ptr_reverse--;
152     temp2[2] = *ptr_reverse++;
153 
154     twid_re = *twidle_rev;
155     twidle_rev -= 2;
156     twid_im = *twidle_fwd;
157     twidle_fwd += 2;
158 
159     temp1[0] = ixheaacd_sub32_sat(temp2[0], temp2[2]);
160     temp1[1] = ixheaacd_add32_sat(temp2[0], temp2[2]);
161 
162     temp1[2] = ixheaacd_add32_sat(temp2[1], temp2[3]);
163     temp1[3] = ixheaacd_sub32_sat(temp2[1], temp2[3]);
164 
165     temp1[4] = ixheaacd_add32_sat(ixheaacd_mult32x16in32(temp1[0], twid_re),
166                                   ixheaacd_mult32x16in32(temp1[2], twid_im));
167     temp1[5] = ixheaacd_sub32_sat(ixheaacd_mult32x16in32(temp1[0], twid_im),
168                                   ixheaacd_mult32x16in32(temp1[2], twid_re));
169 
170     temp1[1] >>= 1;
171     temp1[3] >>= 1;
172 
173     *ptr_forward++ = ixheaacd_sub32_sat(temp1[1], temp1[4]);
174     *ptr_forward++ = ixheaacd_add32_sat(temp1[3], temp1[5]);
175 
176     *ptr_reverse-- = ixheaacd_sub32_sat(temp1[5], temp1[3]);
177     *ptr_reverse-- = ixheaacd_add32_sat(temp1[1], temp1[4]);
178   }
179   temp2[0] = *ptr_forward++;
180   temp2[1] = *ptr_forward--;
181   temp2[3] = *ptr_reverse--;
182   temp2[2] = *ptr_reverse++;
183 
184   twid_re = -*twidle_rev;
185   twidle_rev -= 2;
186   twid_im = *twidle_fwd;
187   twidle_fwd += 2;
188 
189   temp1[0] = ixheaacd_sub32_sat(temp2[0], temp2[2]);
190   temp1[1] = ixheaacd_add32_sat(temp2[0], temp2[2]);
191 
192   temp1[2] = ixheaacd_add32_sat(temp2[1], temp2[3]);
193   temp1[3] = ixheaacd_sub32_sat(temp2[1], temp2[3]);
194 
195   temp1[4] = ixheaacd_sub32_sat(ixheaacd_mult32x16in32(temp1[0], twid_re),
196                                 ixheaacd_mult32x16in32(temp1[2], twid_im));
197   temp1[5] = ixheaacd_add32_sat(ixheaacd_mult32x16in32(temp1[2], twid_re),
198                                 ixheaacd_mult32x16in32(temp1[0], twid_im));
199 
200   temp1[1] >>= 1;
201   temp1[3] >>= 1;
202   *ptr_forward++ = ixheaacd_add32_sat(temp1[1], temp1[4]);
203   *ptr_forward++ = ixheaacd_add32_sat(temp1[3], temp1[5]);
204 
205   ixheaacd_radix4bfly(w_16, output, 1, 4);
206   ixheaacd_postradixcompute4(input, output, p_table, 16);
207 
208   output[0] = input[0];
209   output[2] = input[1];
210 
211   p_out = input + 2;
212   ptr_forward = output + 1;
213   ptr_reverse = output + 30;
214   ptr_out1 = input + 18;
215 
216   for (k = (DCT3_LEN / 4) - 1; k != 0; k--) {
217     WORD32 tempre, tempim;
218 
219     tempre = *p_out++;
220     tempim = *p_out++;
221     *ptr_forward = (tempim);
222     ptr_forward += 2;
223     *ptr_forward = (tempre);
224     ptr_forward += 2;
225 
226     tempre = *ptr_out1++;
227     tempim = *ptr_out1++;
228     *ptr_reverse = (tempim);
229     ptr_reverse -= 2;
230     *ptr_reverse = (tempre);
231     ptr_reverse -= 2;
232   }
233 
234   {
235     WORD32 tempre, tempim;
236     tempre = *p_out++;
237     tempim = *p_out++;
238     *ptr_forward = (tempim);
239     ptr_forward += 2;
240     *ptr_forward = (tempre);
241     ptr_forward += 2;
242   }
243 
244   return;
245 }
ixheaacd_dct2_64(WORD32 * x,WORD32 * X,ia_qmf_dec_tables_struct * qmf_dec_tables_ptr,WORD16 * filter_states)246 VOID ixheaacd_dct2_64(WORD32 *x, WORD32 *X,
247                       ia_qmf_dec_tables_struct *qmf_dec_tables_ptr,
248                       WORD16 *filter_states) {
249   ixheaacd_pretwdct2(x, X);
250 
251   ixheaacd_sbr_imdct_using_fft(qmf_dec_tables_ptr->w1024, 32, X, x,
252                                qmf_dec_tables_ptr->dig_rev_table2_128,
253                                qmf_dec_tables_ptr->dig_rev_table2_128,
254                                qmf_dec_tables_ptr->dig_rev_table2_128,
255                                qmf_dec_tables_ptr->dig_rev_table2_128);
256 
257   ixheaacd_fftposttw(x, qmf_dec_tables_ptr);
258 
259   ixheaacd_posttwdct2(x, filter_states, qmf_dec_tables_ptr);
260 
261   return;
262 }
263 
ixheaacd_cos_sin_mod(WORD32 * subband,ia_sbr_qmf_filter_bank_struct * qmf_bank,WORD16 * p_twiddle,WORD32 * p_dig_rev_tbl)264 VOID ixheaacd_cos_sin_mod(WORD32 *subband,
265                           ia_sbr_qmf_filter_bank_struct *qmf_bank,
266                           WORD16 *p_twiddle, WORD32 *p_dig_rev_tbl) {
267   WORD32 M = ixheaacd_shr32(qmf_bank->no_channels, 1);
268 
269   const WORD16 *p_sin;
270   const WORD16 *p_sin_cos = &qmf_bank->cos_twiddle[0];
271   WORD32 subband_tmp[128];
272 
273   ixheaacd_cos_sin_mod_loop1(subband, M, p_sin_cos, subband_tmp);
274 
275   if (M == 32) {
276     ixheaacd_sbr_imdct_using_fft(
277         (const WORD32 *)p_twiddle, 32, subband_tmp, subband,
278         (UWORD8 *)p_dig_rev_tbl, (UWORD8 *)p_dig_rev_tbl,
279         (UWORD8 *)p_dig_rev_tbl, (UWORD8 *)p_dig_rev_tbl);
280 
281     ixheaacd_sbr_imdct_using_fft(
282         (const WORD32 *)p_twiddle, 32, &subband_tmp[64], &subband[64],
283         (UWORD8 *)p_dig_rev_tbl, (UWORD8 *)p_dig_rev_tbl,
284         (UWORD8 *)p_dig_rev_tbl, (UWORD8 *)p_dig_rev_tbl);
285 
286   } else {
287     ixheaacd_sbr_imdct_using_fft(
288         (const WORD32 *)p_twiddle, 16, subband_tmp, subband,
289         (UWORD8 *)p_dig_rev_tbl, (UWORD8 *)p_dig_rev_tbl,
290         (UWORD8 *)p_dig_rev_tbl, (UWORD8 *)p_dig_rev_tbl);
291 
292     ixheaacd_sbr_imdct_using_fft(
293         (const WORD32 *)p_twiddle, 16, &subband_tmp[64], &subband[64],
294         (UWORD8 *)p_dig_rev_tbl, (UWORD8 *)p_dig_rev_tbl,
295         (UWORD8 *)p_dig_rev_tbl, (UWORD8 *)p_dig_rev_tbl);
296   }
297 
298   p_sin = &qmf_bank->alt_sin_twiddle[0];
299   ixheaacd_cos_sin_mod_loop2(subband, p_sin, M);
300 }
301 
ixheaacd_fwd_modulation(const WORD32 * p_time_in1,WORD32 * real_subband,WORD32 * imag_subband,ia_sbr_qmf_filter_bank_struct * qmf_bank,ia_qmf_dec_tables_struct * qmf_dec_tables_ptr)302 VOID ixheaacd_fwd_modulation(const WORD32 *p_time_in1, WORD32 *real_subband,
303                              WORD32 *imag_subband,
304                              ia_sbr_qmf_filter_bank_struct *qmf_bank,
305                              ia_qmf_dec_tables_struct *qmf_dec_tables_ptr) {
306   WORD32 i;
307   const WORD32 *p_time_in2 = &p_time_in1[2 * NO_ANALYSIS_CHANNELS - 1];
308   WORD32 temp1, temp2;
309   WORD32 *t_real_subband = real_subband;
310   WORD32 *t_imag_subband = imag_subband;
311   const WORD16 *tcos;
312 
313   for (i = NO_ANALYSIS_CHANNELS - 1; i >= 0; i--) {
314     temp1 = ixheaacd_shr32(*p_time_in1++, HQ_SHIFT_VAL);
315     temp2 = ixheaacd_shr32(*p_time_in2--, HQ_SHIFT_VAL);
316 
317     *t_real_subband++ = ixheaacd_sub32_sat(temp1, temp2);
318     ;
319     *t_imag_subband++ = ixheaacd_add32_sat(temp1, temp2);
320     ;
321   }
322 
323   ixheaacd_cos_sin_mod(real_subband, qmf_bank,
324                        (WORD16 *)qmf_dec_tables_ptr->w1024,
325                        (WORD32 *)qmf_dec_tables_ptr->dig_rev_table2_128);
326 
327   tcos = qmf_bank->t_cos;
328 
329   for (i = (qmf_bank->usb - qmf_bank->lsb - 1); i >= 0; i--) {
330     WORD16 cosh, sinh;
331     WORD32 re, im;
332 
333     re = *real_subband;
334     im = *imag_subband;
335     cosh = *tcos++;
336     sinh = *tcos++;
337     *real_subband++ = ixheaacd_add32_sat(ixheaacd_mult32x16in32_shl(re, cosh),
338                                          ixheaacd_mult32x16in32_shl(im, sinh));
339     *imag_subband++ = ixheaacd_sub32_sat(ixheaacd_mult32x16in32_shl(im, cosh),
340                                          ixheaacd_mult32x16in32_shl(re, sinh));
341   }
342 }
343 
ixheaacd_cplx_anal_qmffilt(const WORD16 * time_sample_buf,ia_sbr_scale_fact_struct * sbr_scale_factor,WORD32 ** qmf_real,WORD32 ** qmf_imag,ia_sbr_qmf_filter_bank_struct * qmf_bank,ia_qmf_dec_tables_struct * qmf_dec_tables_ptr,WORD32 ch_fac,WORD32 low_pow_flag,WORD audio_object_type)344 VOID ixheaacd_cplx_anal_qmffilt(const WORD16 *time_sample_buf,
345                                 ia_sbr_scale_fact_struct *sbr_scale_factor,
346                                 WORD32 **qmf_real, WORD32 **qmf_imag,
347                                 ia_sbr_qmf_filter_bank_struct *qmf_bank,
348                                 ia_qmf_dec_tables_struct *qmf_dec_tables_ptr,
349                                 WORD32 ch_fac, WORD32 low_pow_flag,
350                                 WORD audio_object_type) {
351   WORD32 i, k;
352   WORD32 num_time_slots = qmf_bank->num_time_slots;
353 
354   WORD32 analysis_buffer[4 * NO_ANALYSIS_CHANNELS];
355   WORD16 *filter_states = qmf_bank->core_samples_buffer;
356 
357   WORD16 *fp1, *fp2, *tmp;
358 
359   WORD16 *filter_1;
360   WORD16 *filter_2;
361   WORD16 *filt_ptr;
362   if (audio_object_type != AOT_ER_AAC_ELD &&
363       audio_object_type != AOT_ER_AAC_LD) {
364     qmf_bank->filter_pos +=
365         (qmf_dec_tables_ptr->qmf_c - qmf_bank->analy_win_coeff);
366     qmf_bank->analy_win_coeff = qmf_dec_tables_ptr->qmf_c;
367   } else {
368     qmf_bank->filter_pos +=
369         (qmf_dec_tables_ptr->qmf_c_eld3 - qmf_bank->analy_win_coeff);
370     qmf_bank->analy_win_coeff = qmf_dec_tables_ptr->qmf_c_eld3;
371   }
372 
373   filter_1 = qmf_bank->filter_pos;
374 
375   if (audio_object_type != AOT_ER_AAC_ELD &&
376       audio_object_type != AOT_ER_AAC_LD) {
377     filter_2 = filter_1 + 64;
378   } else {
379     filter_2 = filter_1 + 32;
380   }
381 
382   sbr_scale_factor->st_lb_scale = 0;
383   sbr_scale_factor->lb_scale = -10;
384   if (!low_pow_flag) {
385     if (audio_object_type != AOT_ER_AAC_ELD &&
386         audio_object_type != AOT_ER_AAC_LD) {
387       sbr_scale_factor->lb_scale = -8;
388     } else {
389       sbr_scale_factor->lb_scale = -9;
390     }
391     qmf_bank->cos_twiddle =
392         (WORD16 *)qmf_dec_tables_ptr->sbr_sin_cos_twiddle_l32;
393     qmf_bank->alt_sin_twiddle =
394         (WORD16 *)qmf_dec_tables_ptr->sbr_alt_sin_twiddle_l32;
395     if (audio_object_type != AOT_ER_AAC_ELD &&
396         audio_object_type != AOT_ER_AAC_LD) {
397       qmf_bank->t_cos = (WORD16 *)qmf_dec_tables_ptr->sbr_t_cos_sin_l32;
398     } else {
399       qmf_bank->t_cos =
400           (WORD16 *)qmf_dec_tables_ptr->ixheaacd_sbr_t_cos_sin_l32_eld;
401     }
402   }
403 
404   fp1 = qmf_bank->anal_filter_states;
405   fp2 = qmf_bank->anal_filter_states + NO_ANALYSIS_CHANNELS;
406 
407   if (audio_object_type == AOT_ER_AAC_ELD ||
408       audio_object_type == AOT_ER_AAC_LD) {
409     filter_2 = qmf_bank->filter_2;
410     fp1 = qmf_bank->fp1_anal;
411     fp2 = qmf_bank->fp2_anal;
412   }
413 
414   for (i = 0; i < num_time_slots; i++) {
415     for (k = 0; k < NO_ANALYSIS_CHANNELS; k++)
416       filter_states[NO_ANALYSIS_CHANNELS - 1 - k] = time_sample_buf[ch_fac * k];
417 
418     if (audio_object_type != AOT_ER_AAC_ELD &&
419         audio_object_type != AOT_ER_AAC_LD) {
420       ixheaacd_sbr_qmfanal32_winadds(fp1, fp2, filter_1, filter_2,
421                                      analysis_buffer, filter_states,
422                                      time_sample_buf, ch_fac);
423     }
424 
425     else {
426       ixheaacd_sbr_qmfanal32_winadd_eld(fp1, fp2, filter_1, filter_2,
427                                         analysis_buffer);
428     }
429 
430     time_sample_buf += NO_ANALYSIS_CHANNELS * ch_fac;
431 
432     filter_states -= NO_ANALYSIS_CHANNELS;
433     if (filter_states < qmf_bank->anal_filter_states) {
434       filter_states = qmf_bank->anal_filter_states + 288;
435     }
436 
437     tmp = fp1;
438     fp1 = fp2;
439     fp2 = tmp;
440     if (audio_object_type != AOT_ER_AAC_ELD &&
441         audio_object_type != AOT_ER_AAC_LD) {
442       filter_1 += 64;
443       filter_2 += 64;
444     } else {
445       filter_1 += 32;
446       filter_2 += 32;
447     }
448 
449     filt_ptr = filter_1;
450     filter_1 = filter_2;
451     filter_2 = filt_ptr;
452     if (audio_object_type != AOT_ER_AAC_ELD &&
453         audio_object_type != AOT_ER_AAC_LD) {
454       if (filter_2 > (qmf_bank->analy_win_coeff + 640)) {
455         filter_1 = (WORD16 *)qmf_bank->analy_win_coeff;
456         filter_2 = (WORD16 *)qmf_bank->analy_win_coeff + 64;
457       }
458     } else {
459       if (filter_2 > (qmf_bank->analy_win_coeff + 320)) {
460         filter_1 = (WORD16 *)qmf_bank->analy_win_coeff;
461         filter_2 = (WORD16 *)qmf_bank->analy_win_coeff + 32;
462       }
463     }
464 
465     if (!low_pow_flag) {
466       ixheaacd_fwd_modulation(analysis_buffer, qmf_real[i], qmf_imag[i],
467                               qmf_bank, qmf_dec_tables_ptr);
468     } else {
469       ixheaacd_dct3_32(
470           (WORD32 *)analysis_buffer, qmf_real[i], qmf_dec_tables_ptr->dct23_tw,
471           qmf_dec_tables_ptr->post_fft_tbl, qmf_dec_tables_ptr->w_16,
472           qmf_dec_tables_ptr->dig_rev_table4_16);
473     }
474   }
475 
476   qmf_bank->filter_pos = filter_1;
477   qmf_bank->core_samples_buffer = filter_states;
478 
479   if (audio_object_type == AOT_ER_AAC_ELD || audio_object_type == AOT_ER_AAC_LD)
480 
481   {
482     qmf_bank->fp1_anal = fp1;
483     qmf_bank->fp2_anal = fp2;
484     qmf_bank->filter_2 = filter_2;
485   }
486 }
487 
ixheaacd_inv_modulation_lp(WORD32 * qmf_real,WORD16 * filter_states,ia_sbr_qmf_filter_bank_struct * syn_qmf,ia_qmf_dec_tables_struct * qmf_dec_tables_ptr)488 VOID ixheaacd_inv_modulation_lp(WORD32 *qmf_real, WORD16 *filter_states,
489                                 ia_sbr_qmf_filter_bank_struct *syn_qmf,
490                                 ia_qmf_dec_tables_struct *qmf_dec_tables_ptr) {
491   WORD32 L = syn_qmf->no_channels;
492   const WORD32 M = (L >> 1);
493   WORD32 *dct_in = qmf_real;
494   WORD32 time_out[2 * NO_SYNTHESIS_CHANNELS];
495 
496   WORD32 ui_rem = ((WORD64)(&time_out[0]) % 8);
497   WORD32 *ptime_out = (pVOID)((WORD8 *)&time_out[0] + 8 - ui_rem);
498 
499   if (L == 64)
500     ixheaacd_dct2_64(dct_in, ptime_out, qmf_dec_tables_ptr, filter_states + M);
501   else
502     ixheaacd_dct2_32(dct_in, time_out, qmf_dec_tables_ptr, filter_states);
503 
504   filter_states[3 * M] = 0;
505 }
506 
ixheaacd_inv_emodulation(WORD32 * qmf_real,ia_sbr_qmf_filter_bank_struct * syn_qmf,ia_qmf_dec_tables_struct * qmf_dec_tables_ptr)507 VOID ixheaacd_inv_emodulation(WORD32 *qmf_real,
508                               ia_sbr_qmf_filter_bank_struct *syn_qmf,
509                               ia_qmf_dec_tables_struct *qmf_dec_tables_ptr) {
510   ixheaacd_cos_sin_mod(qmf_real, syn_qmf, (WORD16 *)qmf_dec_tables_ptr->w1024,
511                        (WORD32 *)qmf_dec_tables_ptr->dig_rev_table2_128);
512 }
513 
ixheaacd_esbr_radix4bfly(const WORD32 * w,WORD32 * x,WORD32 index1,WORD32 index)514 VOID ixheaacd_esbr_radix4bfly(const WORD32 *w, WORD32 *x, WORD32 index1,
515                               WORD32 index) {
516   int i;
517   WORD32 l1, l2, h2, fft_jmp;
518   WORD64 xt0_0, yt0_0, xt1_0, yt1_0, xt2_0, yt2_0;
519   WORD64 xh0_0, xh1_0, xh20_0, xh21_0, xl0_0, xl1_0, xl20_0, xl21_0;
520   WORD32 x_0, x_1, x_l1_0, x_l1_1, x_l2_0, x_l2_1;
521   WORD32 x_h2_0, x_h2_1;
522   WORD32 si10, si20, si30, co10, co20, co30;
523 
524   WORD64 mul_1, mul_2, mul_3, mul_4, mul_5, mul_6;
525   WORD64 mul_7, mul_8, mul_9, mul_10, mul_11, mul_12;
526   WORD32 *x_l1;
527   WORD32 *x_l2;
528   WORD32 *x_h2;
529   const WORD32 *w_ptr = w;
530   WORD32 i1;
531 
532   h2 = index << 1;
533   l1 = index << 2;
534   l2 = (index << 2) + (index << 1);
535 
536   x_l1 = &(x[l1]);
537   x_l2 = &(x[l2]);
538   x_h2 = &(x[h2]);
539 
540   fft_jmp = 6 * (index);
541 
542   for (i1 = 0; i1 < index1; i1++) {
543     for (i = 0; i < index; i++) {
544       si10 = (*w_ptr++);
545       co10 = (*w_ptr++);
546       si20 = (*w_ptr++);
547       co20 = (*w_ptr++);
548       si30 = (*w_ptr++);
549       co30 = (*w_ptr++);
550 
551       x_0 = x[0];
552       x_h2_0 = x[h2];
553       x_l1_0 = x[l1];
554       x_l2_0 = x[l2];
555 
556       xh0_0 = (WORD64)x_0 + (WORD64)x_l1_0;
557       xl0_0 = (WORD64)x_0 - (WORD64)x_l1_0;
558 
559       xh20_0 = (WORD64)x_h2_0 + (WORD64)x_l2_0;
560       xl20_0 = (WORD64)x_h2_0 - (WORD64)x_l2_0;
561 
562       x[0] = (WORD32)ixheaacd_add64_sat(xh0_0, xh20_0);
563       xt0_0 = (WORD64)xh0_0 - (WORD64)xh20_0;
564 
565       x_1 = x[1];
566       x_h2_1 = x[h2 + 1];
567       x_l1_1 = x[l1 + 1];
568       x_l2_1 = x[l2 + 1];
569 
570       xh1_0 = (WORD64)x_1 + (WORD64)x_l1_1;
571       xl1_0 = (WORD64)x_1 - (WORD64)x_l1_1;
572 
573       xh21_0 = (WORD64)x_h2_1 + (WORD64)x_l2_1;
574       xl21_0 = (WORD64)x_h2_1 - (WORD64)x_l2_1;
575 
576       x[1] = (WORD32)ixheaacd_add64_sat(xh1_0, xh21_0);
577       yt0_0 = (WORD64)xh1_0 - (WORD64)xh21_0;
578 
579       xt1_0 = (WORD64)xl0_0 + (WORD64)xl21_0;
580       xt2_0 = (WORD64)xl0_0 - (WORD64)xl21_0;
581 
582       yt2_0 = (WORD64)xl1_0 + (WORD64)xl20_0;
583       yt1_0 = (WORD64)xl1_0 - (WORD64)xl20_0;
584 
585       mul_11 = ixheaacd_mult64(xt2_0, co30);
586       mul_3 = ixheaacd_mult64(yt2_0, si30);
587       x[l2] = ixheaacd_sat64_32(((mul_3 + mul_11) >> 32) << RADIXSHIFT);
588 
589       mul_5 = ixheaacd_mult64(xt2_0, si30);
590       mul_9 = ixheaacd_mult64(yt2_0, co30);
591       x[l2 + 1] = ixheaacd_sat64_32(((mul_9 - mul_5) >> 32) << RADIXSHIFT);
592 
593       mul_12 = ixheaacd_mult64(xt0_0, co20);
594       mul_2 = ixheaacd_mult64(yt0_0, si20);
595       x[l1] = ixheaacd_sat64_32(((mul_2 + mul_12) >> 32) << RADIXSHIFT);
596 
597       mul_6 = ixheaacd_mult64(xt0_0, si20);
598       mul_8 = ixheaacd_mult64(yt0_0, co20);
599       x[l1 + 1] = ixheaacd_sat64_32(((mul_8 - mul_6) >> 32) << RADIXSHIFT);
600 
601       mul_4 = ixheaacd_mult64(xt1_0, co10);
602       mul_1 = ixheaacd_mult64(yt1_0, si10);
603       x[h2] = ixheaacd_sat64_32(((mul_1 + mul_4) >> 32) << RADIXSHIFT);
604 
605       mul_10 = ixheaacd_mult64(xt1_0, si10);
606       mul_7 = ixheaacd_mult64(yt1_0, co10);
607       x[h2 + 1] = ixheaacd_sat64_32(((mul_7 - mul_10) >> 32) << RADIXSHIFT);
608 
609       x += 2;
610     }
611     x += fft_jmp;
612     w_ptr = w_ptr - fft_jmp;
613   }
614 }
615 
ixheaacd_esbr_postradixcompute2(WORD32 * ptr_y,WORD32 * ptr_x,const WORD32 * pdig_rev_tbl,WORD32 npoints)616 VOID ixheaacd_esbr_postradixcompute2(WORD32 *ptr_y, WORD32 *ptr_x,
617                                      const WORD32 *pdig_rev_tbl,
618                                      WORD32 npoints) {
619   WORD32 i, k;
620   WORD32 h2;
621   WORD32 x_0, x_1, x_2, x_3;
622   WORD32 x_4, x_5, x_6, x_7;
623   WORD32 x_8, x_9, x_a, x_b, x_c, x_d, x_e, x_f;
624   WORD32 n0, j0;
625   WORD32 *x2, *x0;
626   WORD32 *y0, *y1, *y2, *y3;
627 
628   y0 = ptr_y;
629   y2 = ptr_y + (WORD32)npoints;
630   x0 = ptr_x;
631   x2 = ptr_x + (WORD32)(npoints >> 1);
632 
633   y1 = y0 + (WORD32)(npoints >> 2);
634   y3 = y2 + (WORD32)(npoints >> 2);
635   j0 = 8;
636   n0 = npoints >> 1;
637 
638   for (k = 0; k < 2; k++) {
639     for (i = 0; i<npoints>> 1; i += 8) {
640       h2 = *pdig_rev_tbl++ >> 2;
641 
642       x_0 = *x0++;
643       x_1 = *x0++;
644       x_2 = *x0++;
645       x_3 = *x0++;
646       x_4 = *x0++;
647       x_5 = *x0++;
648       x_6 = *x0++;
649       x_7 = *x0++;
650 
651       y0[h2] = ixheaacd_add32_sat(x_0, x_2);
652       y0[h2 + 1] = ixheaacd_add32_sat(x_1, x_3);
653       y1[h2] = ixheaacd_add32_sat(x_4, x_6);
654       y1[h2 + 1] = ixheaacd_add32_sat(x_5, x_7);
655       y2[h2] = ixheaacd_sub32_sat(x_0, x_2);
656       y2[h2 + 1] = ixheaacd_sub32_sat(x_1, x_3);
657       y3[h2] = ixheaacd_sub32_sat(x_4, x_6);
658       y3[h2 + 1] = ixheaacd_sub32_sat(x_5, x_7);
659 
660       x_8 = *x2++;
661       x_9 = *x2++;
662       x_a = *x2++;
663       x_b = *x2++;
664       x_c = *x2++;
665       x_d = *x2++;
666       x_e = *x2++;
667       x_f = *x2++;
668 
669       y0[h2 + 2] = ixheaacd_add32_sat(x_8, x_a);
670       y0[h2 + 3] = ixheaacd_add32_sat(x_9, x_b);
671       y1[h2 + 2] = ixheaacd_add32_sat(x_c, x_e);
672       y1[h2 + 3] = ixheaacd_add32_sat(x_d, x_f);
673       y2[h2 + 2] = ixheaacd_sub32_sat(x_8, x_a);
674       y2[h2 + 3] = ixheaacd_sub32_sat(x_9, x_b);
675       y3[h2 + 2] = ixheaacd_sub32_sat(x_c, x_e);
676       y3[h2 + 3] = ixheaacd_sub32_sat(x_d, x_f);
677     }
678     x0 += (WORD32)npoints >> 1;
679     x2 += (WORD32)npoints >> 1;
680   }
681 }
682 
ixheaacd_esbr_postradixcompute4(WORD32 * ptr_y,WORD32 * ptr_x,const WORD32 * p_dig_rev_tbl,WORD32 npoints)683 VOID ixheaacd_esbr_postradixcompute4(WORD32 *ptr_y, WORD32 *ptr_x,
684                                      const WORD32 *p_dig_rev_tbl,
685                                      WORD32 npoints) {
686   WORD32 i, k;
687   WORD32 h2;
688   WORD32 xh0_0, xh1_0, xl0_0, xl1_0;
689   WORD32 xh0_1, xh1_1, xl0_1, xl1_1;
690   WORD32 x_0, x_1, x_2, x_3;
691   WORD32 xh0_2, xh1_2, xl0_2, xl1_2, xh0_3, xh1_3, xl0_3, xl1_3;
692   WORD32 x_4, x_5, x_6, x_7;
693   WORD32 x_8, x_9, x_a, x_b, x_c, x_d, x_e, x_f;
694   WORD32 n00, n10, n20, n30, n01, n11, n21, n31;
695   WORD32 n02, n12, n22, n32, n03, n13, n23, n33;
696   WORD32 n0, j0;
697   WORD32 *x2, *x0;
698   WORD32 *y0, *y1, *y2, *y3;
699 
700   y0 = ptr_y;
701   y2 = ptr_y + (WORD32)npoints;
702   x0 = ptr_x;
703   x2 = ptr_x + (WORD32)(npoints >> 1);
704 
705   y1 = y0 + (WORD32)(npoints >> 1);
706   y3 = y2 + (WORD32)(npoints >> 1);
707 
708   j0 = 4;
709   n0 = npoints >> 2;
710 
711   for (k = 0; k < 2; k++) {
712     for (i = 0; i<npoints>> 1; i += 8) {
713       h2 = *p_dig_rev_tbl++ >> 2;
714       x_0 = *x0++;
715       x_1 = *x0++;
716       x_2 = *x0++;
717       x_3 = *x0++;
718       x_4 = *x0++;
719       x_5 = *x0++;
720       x_6 = *x0++;
721       x_7 = *x0++;
722 
723       xh0_0 = ixheaacd_add32_sat(x_0, x_4);
724       xh1_0 = ixheaacd_add32_sat(x_1, x_5);
725       xl0_0 = ixheaacd_sub32_sat(x_0, x_4);
726       xl1_0 = ixheaacd_sub32_sat(x_1, x_5);
727       xh0_1 = ixheaacd_add32_sat(x_2, x_6);
728       xh1_1 = ixheaacd_add32_sat(x_3, x_7);
729       xl0_1 = ixheaacd_sub32_sat(x_2, x_6);
730       xl1_1 = ixheaacd_sub32_sat(x_3, x_7);
731 
732       n00 = ixheaacd_add32_sat(xh0_0, xh0_1);
733       n01 = ixheaacd_add32_sat(xh1_0, xh1_1);
734       n10 = ixheaacd_add32_sat(xl0_0, xl1_1);
735       n11 = ixheaacd_sub32_sat(xl1_0, xl0_1);
736       n20 = ixheaacd_sub32_sat(xh0_0, xh0_1);
737       n21 = ixheaacd_sub32_sat(xh1_0, xh1_1);
738       n30 = ixheaacd_sub32_sat(xl0_0, xl1_1);
739       n31 = ixheaacd_add32_sat(xl1_0, xl0_1);
740 
741       y0[h2] = n00;
742       y0[h2 + 1] = n01;
743       y1[h2] = n10;
744       y1[h2 + 1] = n11;
745       y2[h2] = n20;
746       y2[h2 + 1] = n21;
747       y3[h2] = n30;
748       y3[h2 + 1] = n31;
749 
750       x_8 = *x2++;
751       x_9 = *x2++;
752       x_a = *x2++;
753       x_b = *x2++;
754       x_c = *x2++;
755       x_d = *x2++;
756       x_e = *x2++;
757       x_f = *x2++;
758 
759       xh0_2 = ixheaacd_add32_sat(x_8, x_c);
760       xh1_2 = ixheaacd_add32_sat(x_9, x_d);
761       xl0_2 = ixheaacd_sub32_sat(x_8, x_c);
762       xl1_2 = ixheaacd_sub32_sat(x_9, x_d);
763       xh0_3 = ixheaacd_add32_sat(x_a, x_e);
764       xh1_3 = ixheaacd_add32_sat(x_b, x_f);
765       xl0_3 = ixheaacd_sub32_sat(x_a, x_e);
766       xl1_3 = ixheaacd_sub32_sat(x_b, x_f);
767 
768       n02 = ixheaacd_add32_sat(xh0_2, xh0_3);
769       n03 = ixheaacd_add32_sat(xh1_2, xh1_3);
770       n12 = ixheaacd_add32_sat(xl0_2, xl1_3);
771       n13 = ixheaacd_sub32_sat(xl1_2, xl0_3);
772       n22 = ixheaacd_sub32_sat(xh0_2, xh0_3);
773       n23 = ixheaacd_sub32_sat(xh1_2, xh1_3);
774       n32 = ixheaacd_sub32_sat(xl0_2, xl1_3);
775       n33 = ixheaacd_add32_sat(xl1_2, xl0_3);
776 
777       y0[h2 + 2] = n02;
778       y0[h2 + 3] = n03;
779       y1[h2 + 2] = n12;
780       y1[h2 + 3] = n13;
781       y2[h2 + 2] = n22;
782       y2[h2 + 3] = n23;
783       y3[h2 + 2] = n32;
784       y3[h2 + 3] = n33;
785     }
786     x0 += (WORD32)npoints >> 1;
787     x2 += (WORD32)npoints >> 1;
788   }
789 }
790 
ixheaacd_esbr_cos_sin_mod(WORD32 * subband,ia_sbr_qmf_filter_bank_struct * qmf_bank,WORD32 * p_twiddle,WORD32 * p_dig_rev_tbl)791 VOID ixheaacd_esbr_cos_sin_mod(WORD32 *subband,
792                                ia_sbr_qmf_filter_bank_struct *qmf_bank,
793                                WORD32 *p_twiddle, WORD32 *p_dig_rev_tbl) {
794   WORD32 z;
795   WORD32 temp[128];
796   WORD32 scaleshift = 0;
797 
798   WORD32 re2, re3;
799   WORD32 wim, wre;
800 
801   WORD32 i, M_2;
802   WORD32 M = ixheaacd_shr32(qmf_bank->no_channels, 1);
803 
804   const WORD32 *p_sin;
805   const WORD32 *p_sin_cos;
806 
807   WORD32 subband_tmp[128];
808   WORD32 re;
809   WORD32 im;
810   WORD32 *psubband, *psubband1;
811   WORD32 *psubband_t, *psubband1_t;
812   WORD32 *psubband2, *psubband12;
813   WORD32 *psubband_t2, *psubband1_t2;
814 
815   M_2 = ixheaacd_shr32(M, 1);
816 
817   p_sin_cos = qmf_bank->esbr_cos_twiddle;
818 
819   psubband = &subband[0];
820   psubband1 = &subband[2 * M - 1];
821   psubband_t = subband_tmp;
822   psubband1_t = &subband_tmp[2 * M - 1];
823 
824   psubband2 = &subband[64];
825   psubband12 = &subband[2 * M - 1 + 64];
826   psubband_t2 = &subband_tmp[64];
827   psubband1_t2 = &subband_tmp[2 * M - 1 + 64];
828 
829   for (i = (M_2 >> 1) - 1; i >= 0; i--) {
830     re = *psubband++;
831     im = *psubband1--;
832 
833     wim = *p_sin_cos++;
834     wre = *p_sin_cos++;
835 
836     *psubband_t++ = (WORD32)(
837         (ixheaacd_add64(ixheaacd_mult64(re, wre), ixheaacd_mult64(im, wim))) >>
838         32);
839     *psubband_t++ = (WORD32)((ixheaacd_sub64_sat(ixheaacd_mult64(im, wre),
840                                                  ixheaacd_mult64(re, wim))) >>
841                              32);
842 
843     re = *psubband2++;
844     im = *psubband12--;
845 
846     *psubband_t2++ = (WORD32)((ixheaacd_sub64_sat(ixheaacd_mult64(im, wim),
847                                                   ixheaacd_mult64(re, wre))) >>
848                               32);
849     *psubband_t2++ = (WORD32)(
850         (ixheaacd_add64(ixheaacd_mult64(re, wim), ixheaacd_mult64(im, wre))) >>
851         32);
852 
853     re = *psubband1--;
854     im = *psubband++;
855 
856     wim = *p_sin_cos++;
857     wre = *p_sin_cos++;
858 
859     *psubband1_t-- = (WORD32)((ixheaacd_sub64_sat(ixheaacd_mult64(im, wre),
860                                                   ixheaacd_mult64(re, wim))) >>
861                               32);
862     *psubband1_t-- = (WORD32)(
863         (ixheaacd_add64(ixheaacd_mult64(re, wre), ixheaacd_mult64(im, wim))) >>
864         32);
865 
866     re = *psubband12--;
867     im = *psubband2++;
868 
869     *psubband1_t2-- = (WORD32)(
870         (ixheaacd_add64(ixheaacd_mult64(re, wim), ixheaacd_mult64(im, wre))) >>
871         32);
872     *psubband1_t2-- = (WORD32)((ixheaacd_sub64_sat(ixheaacd_mult64(im, wim),
873                                                    ixheaacd_mult64(re, wre))) >>
874                                32);
875 
876     re = *psubband++;
877     im = *psubband1--;
878 
879     wim = *p_sin_cos++;
880     wre = *p_sin_cos++;
881 
882     *psubband_t++ = (WORD32)(
883         (ixheaacd_add64(ixheaacd_mult64(re, wre), ixheaacd_mult64(im, wim))) >>
884         32);
885     *psubband_t++ = (WORD32)((ixheaacd_sub64_sat(ixheaacd_mult64(im, wre),
886                                                  ixheaacd_mult64(re, wim))) >>
887                              32);
888 
889     re = *psubband2++;
890     im = *psubband12--;
891 
892     *psubband_t2++ = (WORD32)((ixheaacd_sub64_sat(ixheaacd_mult64(im, wim),
893                                                   ixheaacd_mult64(re, wre))) >>
894                               32);
895     *psubband_t2++ = (WORD32)(
896         (ixheaacd_add64(ixheaacd_mult64(re, wim), ixheaacd_mult64(im, wre))) >>
897         32);
898 
899     re = *psubband1--;
900     im = *psubband++;
901     ;
902 
903     wim = *p_sin_cos++;
904     wre = *p_sin_cos++;
905 
906     *psubband1_t-- = (WORD32)((ixheaacd_sub64_sat(ixheaacd_mult64(im, wre),
907                                                   ixheaacd_mult64(re, wim))) >>
908                               32);
909     *psubband1_t-- = (WORD32)(
910         (ixheaacd_add64(ixheaacd_mult64(re, wre), ixheaacd_mult64(im, wim))) >>
911         32);
912 
913     re = *psubband12--;
914     im = *psubband2++;
915     ;
916 
917     *psubband1_t2-- = (WORD32)(
918         (ixheaacd_add64(ixheaacd_mult64(re, wim), ixheaacd_mult64(im, wre))) >>
919         32);
920     *psubband1_t2-- = (WORD32)((ixheaacd_sub64_sat(ixheaacd_mult64(im, wim),
921                                                    ixheaacd_mult64(re, wre))) >>
922                                32);
923   }
924 
925   if (M == 32) {
926     ixheaacd_esbr_radix4bfly(p_twiddle, subband_tmp, 1, 8);
927     ixheaacd_esbr_radix4bfly(p_twiddle + 48, subband_tmp, 4, 2);
928     ixheaacd_esbr_postradixcompute2(subband, subband_tmp, p_dig_rev_tbl, 32);
929 
930     ixheaacd_esbr_radix4bfly(p_twiddle, &subband_tmp[64], 1, 8);
931     ixheaacd_esbr_radix4bfly(p_twiddle + 48, &subband_tmp[64], 4, 2);
932     ixheaacd_esbr_postradixcompute2(&subband[64], &subband_tmp[64],
933                                     p_dig_rev_tbl, 32);
934 
935   }
936 
937   else if (M == 16) {
938     ixheaacd_esbr_radix4bfly(p_twiddle, subband_tmp, 1, 4);
939     ixheaacd_esbr_postradixcompute4(subband, subband_tmp, p_dig_rev_tbl, 16);
940 
941     ixheaacd_esbr_radix4bfly(p_twiddle, &subband_tmp[64], 1, 4);
942     ixheaacd_esbr_postradixcompute4(&subband[64], &subband_tmp[64],
943                                     p_dig_rev_tbl, 16);
944 
945   }
946 
947   else if (M == 12) {
948     for (z = 0; z < (qmf_bank->no_channels >> 1); z++) {
949       temp[z] = subband_tmp[2 * z];
950       temp[12 + z] = subband_tmp[2 * z + 1];
951     }
952 
953     ixheaacd_complex_fft_p3(temp, &temp[12], 12, -1, &scaleshift);
954 
955     for (z = 0; z < (qmf_bank->no_channels >> 1); z++) {
956       subband[2 * z] = temp[z];
957       subband[2 * z + 1] = temp[z + 12];
958     }
959     scaleshift = 0;
960     for (z = 0; z < (qmf_bank->no_channels >> 1); z++) {
961       temp[z] = subband_tmp[64 + 2 * z];
962       temp[12 + z] = subband_tmp[64 + 2 * z + 1];
963     }
964 
965     ixheaacd_complex_fft_p3(temp, &temp[12], 12, -1, &scaleshift);
966 
967     for (z = 0; z < (qmf_bank->no_channels >> 1); z++) {
968       subband[64 + 2 * z] = temp[z];
969       subband[64 + 2 * z + 1] = temp[z + 12];
970     }
971 
972   }
973 
974   else {
975     for (z = 0; z < (qmf_bank->no_channels >> 1); z++) {
976       temp[z] = subband_tmp[2 * z];
977       temp[8 + z] = subband_tmp[2 * z + 1];
978     }
979 
980     (*ixheaacd_complex_fft_p2)(temp, &temp[8], 8, -1, &scaleshift);
981 
982     for (z = 0; z < (qmf_bank->no_channels >> 1); z++) {
983       subband[2 * z] = ixheaacd_shl32_sat(temp[z], scaleshift);
984       subband[2 * z + 1] = ixheaacd_shl32_sat(temp[z + 8], scaleshift);
985     }
986     scaleshift = 0;
987     for (z = 0; z < (qmf_bank->no_channels >> 1); z++) {
988       temp[z] = subband_tmp[64 + 2 * z];
989       temp[8 + z] = subband_tmp[64 + 2 * z + 1];
990     }
991 
992     (*ixheaacd_complex_fft_p2)(temp, &temp[8], 8, -1, &scaleshift);
993 
994     for (z = 0; z < (qmf_bank->no_channels >> 1); z++) {
995       subband[64 + 2 * z] = ixheaacd_shl32_sat(temp[z], scaleshift);
996       subband[64 + 2 * z + 1] = ixheaacd_shl32_sat(temp[8 + z], scaleshift);
997     }
998   }
999 
1000   psubband = &subband[0];
1001   psubband1 = &subband[2 * M - 1];
1002 
1003   re = *psubband1;
1004 
1005   *psubband = *psubband >> 1;
1006   psubband++;
1007   *psubband1 = ixheaacd_negate32(*psubband >> 1);
1008   psubband1--;
1009 
1010   p_sin = qmf_bank->esbr_alt_sin_twiddle;
1011 
1012   wim = *p_sin++;
1013   wre = *p_sin++;
1014 
1015   im = *psubband1;
1016   ;
1017 
1018   *psubband1-- = (WORD32)(
1019       (ixheaacd_add64(ixheaacd_mult64(re, wre), ixheaacd_mult64(im, wim))) >>
1020       32);
1021   *psubband++ = (WORD32)((ixheaacd_sub64_sat(ixheaacd_mult64(im, wre),
1022                                              ixheaacd_mult64(re, wim))) >>
1023                          32);
1024 
1025   psubband2 = &subband[64];
1026   psubband12 = &subband[2 * M - 1 + 64];
1027 
1028   re = *psubband12;
1029   ;
1030 
1031   *psubband12-- = ixheaacd_negate32_sat(*psubband2 >> 1);
1032   ;
1033   *psubband2 = psubband2[1] >> 1;
1034   ;
1035   psubband2++;
1036 
1037   im = *psubband12;
1038   ;
1039 
1040   *psubband2++ = ixheaacd_negate32_sat((WORD32)(
1041       (ixheaacd_add64(ixheaacd_mult64(re, wre), ixheaacd_mult64(im, wim))) >>
1042       32));
1043   *psubband12-- = (WORD32)((ixheaacd_sub64_sat(ixheaacd_mult64(re, wim),
1044                                                ixheaacd_mult64(im, wre))) >>
1045                            32);
1046 
1047   for (i = (M_2 - 2); i >= 0; i--) {
1048     im = psubband[0];
1049     ;
1050     re = psubband[1];
1051     ;
1052     re2 = *psubband1;
1053     ;
1054 
1055     *psubband++ = (WORD32)(
1056         (ixheaacd_add64(ixheaacd_mult64(re, wim), ixheaacd_mult64(im, wre))) >>
1057         32);
1058     *psubband1-- = (WORD32)((ixheaacd_sub64_sat(ixheaacd_mult64(im, wim),
1059                                                 ixheaacd_mult64(re, wre))) >>
1060                             32);
1061 
1062     im = psubband2[0];
1063     ;
1064     re = psubband2[1];
1065     ;
1066     re3 = *psubband12;
1067     ;
1068 
1069     *psubband12-- = ixheaacd_negate32_sat((WORD32)(
1070         (ixheaacd_add64(ixheaacd_mult64(re, wim), ixheaacd_mult64(im, wre))) >>
1071         32));
1072     *psubband2++ = (WORD32)((ixheaacd_sub64_sat(ixheaacd_mult64(re, wre),
1073                                                 ixheaacd_mult64(im, wim))) >>
1074                             32);
1075 
1076     wim = *p_sin++;
1077     wre = *p_sin++;
1078     im = psubband1[0];
1079     ;
1080 
1081     *psubband1-- = (WORD32)(
1082         (ixheaacd_add64(ixheaacd_mult64(re2, wre), ixheaacd_mult64(im, wim))) >>
1083         32);
1084     *psubband++ = (WORD32)((ixheaacd_sub64_sat(ixheaacd_mult64(im, wre),
1085                                                ixheaacd_mult64(re2, wim))) >>
1086                            32);
1087 
1088     im = psubband12[0];
1089     ;
1090 
1091     *psubband2++ = ixheaacd_negate32_sat((WORD32)(
1092         (ixheaacd_add64(ixheaacd_mult64(re3, wre), ixheaacd_mult64(im, wim))) >>
1093         32));
1094     *psubband12-- = (WORD32)((ixheaacd_sub64_sat(ixheaacd_mult64(re3, wim),
1095                                                  ixheaacd_mult64(im, wre))) >>
1096                              32);
1097   }
1098 }
1099 
ixheaacd_esbr_fwd_modulation(const WORD32 * time_sample_buf,WORD32 * real_subband,WORD32 * imag_subband,ia_sbr_qmf_filter_bank_struct * qmf_bank,ia_qmf_dec_tables_struct * qmf_dec_tables_ptr)1100 VOID ixheaacd_esbr_fwd_modulation(
1101     const WORD32 *time_sample_buf, WORD32 *real_subband, WORD32 *imag_subband,
1102     ia_sbr_qmf_filter_bank_struct *qmf_bank,
1103     ia_qmf_dec_tables_struct *qmf_dec_tables_ptr) {
1104   WORD32 i;
1105   const WORD32 *time_sample_buf1 =
1106       &time_sample_buf[2 * qmf_bank->no_channels - 1];
1107   WORD32 temp1, temp2;
1108   WORD32 *t_real_subband = real_subband;
1109   WORD32 *t_imag_subband = imag_subband;
1110   const WORD32 *tcos;
1111 
1112   for (i = qmf_bank->no_channels - 1; i >= 0; i--) {
1113     temp1 = ixheaacd_shr32(*time_sample_buf++, HQ_SHIFT_64);
1114     temp2 = ixheaacd_shr32(*time_sample_buf1--, HQ_SHIFT_64);
1115 
1116     *t_real_subband++ = ixheaacd_sub32_sat(temp1, temp2);
1117     ;
1118     *t_imag_subband++ = ixheaacd_add32_sat(temp1, temp2);
1119     ;
1120   }
1121 
1122   ixheaacd_esbr_cos_sin_mod(real_subband, qmf_bank,
1123                             qmf_dec_tables_ptr->esbr_w_16,
1124                             qmf_dec_tables_ptr->dig_rev_table4_16);
1125 
1126   tcos = qmf_bank->esbr_t_cos;
1127 
1128   for (i = (qmf_bank->usb - qmf_bank->lsb - 1); i >= 0; i--) {
1129     WORD32 cosh, sinh;
1130     WORD32 re, im;
1131 
1132     re = *real_subband;
1133     im = *imag_subband;
1134     cosh = *tcos++;
1135     sinh = *tcos++;
1136     *real_subband++ =
1137         ixheaacd_sat64_32((ixheaacd_add64(ixheaacd_mult64(re, cosh),
1138                                           ixheaacd_mult64(im, sinh))) >>
1139                           31);
1140     *imag_subband++ =
1141         ixheaacd_sat64_32((ixheaacd_sub64_sat(ixheaacd_mult64(im, cosh),
1142                                               ixheaacd_mult64(re, sinh))) >>
1143                           31);
1144   }
1145 }
1146 
ixheaacd_esbr_qmfsyn64_winadd(WORD32 * tmp1,WORD32 * tmp2,WORD32 * inp1,WORD32 * sample_buffer,WORD32 ch_fac)1147 VOID ixheaacd_esbr_qmfsyn64_winadd(WORD32 *tmp1, WORD32 *tmp2, WORD32 *inp1,
1148                                    WORD32 *sample_buffer, WORD32 ch_fac) {
1149   WORD32 k;
1150 
1151   for (k = 0; k < 64; k++) {
1152     WORD64 syn_out = 0;
1153 
1154     syn_out =
1155         ixheaacd_add64(syn_out, ixheaacd_mult64(tmp1[0 + k], inp1[k + 0]));
1156     syn_out =
1157         ixheaacd_add64(syn_out, ixheaacd_mult64(tmp1[256 + k], inp1[k + 128]));
1158     syn_out =
1159         ixheaacd_add64(syn_out, ixheaacd_mult64(tmp1[512 + k], inp1[k + 256]));
1160     syn_out =
1161         ixheaacd_add64(syn_out, ixheaacd_mult64(tmp1[768 + k], inp1[k + 384]));
1162     syn_out =
1163         ixheaacd_add64(syn_out, ixheaacd_mult64(tmp1[1024 + k], inp1[k + 512]));
1164 
1165     syn_out =
1166         ixheaacd_add64(syn_out, ixheaacd_mult64(tmp2[128 + k], inp1[k + 64]));
1167     syn_out =
1168         ixheaacd_add64(syn_out, ixheaacd_mult64(tmp2[384 + k], inp1[k + 192]));
1169     syn_out =
1170         ixheaacd_add64(syn_out, ixheaacd_mult64(tmp2[640 + k], inp1[k + 320]));
1171     syn_out =
1172         ixheaacd_add64(syn_out, ixheaacd_mult64(tmp2[896 + k], inp1[k + 448]));
1173     syn_out =
1174         ixheaacd_add64(syn_out, ixheaacd_mult64(tmp2[1152 + k], inp1[k + 576]));
1175 
1176     sample_buffer[ch_fac * k] = ixheaacd_sat64_32(syn_out >> 31);
1177   }
1178 }
1179 
ixheaacd_shiftrountine(WORD32 * qmf_real,WORD32 * qmf_imag,WORD32 len,WORD32 common_shift)1180 VOID ixheaacd_shiftrountine(WORD32 *qmf_real, WORD32 *qmf_imag, WORD32 len,
1181                             WORD32 common_shift) {
1182   WORD32 treal, timag;
1183   WORD32 j;
1184 
1185   if (common_shift < 0) {
1186     WORD32 cshift = -common_shift;
1187     cshift = ixheaacd_min32(cshift, 31);
1188     for (j = len - 1; j >= 0; j--) {
1189       treal = *qmf_real;
1190       timag = *qmf_imag;
1191 
1192       treal = (ixheaacd_shr32(treal, cshift));
1193       timag = (ixheaacd_shr32(timag, cshift));
1194 
1195       *qmf_real++ = treal;
1196       *qmf_imag++ = timag;
1197     }
1198   } else {
1199     for (j = len - 1; j >= 0; j--) {
1200       treal = (ixheaacd_shl32_sat(*qmf_real, common_shift));
1201       timag = (ixheaacd_shl32_sat(*qmf_imag, common_shift));
1202       *qmf_real++ = treal;
1203       *qmf_imag++ = timag;
1204     }
1205   }
1206 }
1207 
ixheaacd_shiftrountine_with_rnd_hq(WORD32 * qmf_real,WORD32 * qmf_imag,WORD32 * filter_states,WORD32 len,WORD32 shift)1208 VOID ixheaacd_shiftrountine_with_rnd_hq(WORD32 *qmf_real, WORD32 *qmf_imag,
1209                                         WORD32 *filter_states, WORD32 len,
1210                                         WORD32 shift) {
1211   WORD32 *filter_states_rev = filter_states + len;
1212   WORD32 treal, timag;
1213   WORD32 j;
1214 
1215   for (j = (len - 1); j >= 0; j -= 2) {
1216     WORD32 r1, r2, i1, i2;
1217     i2 = qmf_imag[j];
1218     r2 = qmf_real[j];
1219     r1 = *qmf_real++;
1220     i1 = *qmf_imag++;
1221 
1222     timag = ixheaacd_add32_sat(i1, r1);
1223     timag = (ixheaacd_shl32_sat(timag, shift));
1224     filter_states_rev[j] = timag;
1225 
1226     treal = ixheaacd_sub32_sat(i2, r2);
1227     treal = (ixheaacd_shl32_sat(treal, shift));
1228     filter_states[j] = treal;
1229 
1230     treal = ixheaacd_sub32_sat(i1, r1);
1231     treal = (ixheaacd_shl32_sat(treal, shift));
1232     *filter_states++ = treal;
1233 
1234     timag = ixheaacd_add32_sat(i2, r2);
1235     timag = (ixheaacd_shl32_sat(timag, shift));
1236     *filter_states_rev++ = timag;
1237   }
1238 }
1239 
ixheaacd_radix4bfly(const WORD16 * w,WORD32 * x,WORD32 index1,WORD32 index)1240 VOID ixheaacd_radix4bfly(const WORD16 *w, WORD32 *x, WORD32 index1,
1241                          WORD32 index) {
1242   int i;
1243   WORD32 l1, l2, h2, fft_jmp;
1244   WORD32 xt0_0, yt0_0, xt1_0, yt1_0, xt2_0, yt2_0;
1245   WORD32 xh0_0, xh1_0, xh20_0, xh21_0, xl0_0, xl1_0, xl20_0, xl21_0;
1246   WORD32 x_0, x_1, x_l1_0, x_l1_1, x_l2_0, x_l2_1;
1247   WORD32 x_h2_0, x_h2_1;
1248   WORD16 si10, si20, si30, co10, co20, co30;
1249 
1250   WORD32 mul_1, mul_2, mul_3, mul_4, mul_5, mul_6;
1251   WORD32 mul_7, mul_8, mul_9, mul_10, mul_11, mul_12;
1252   WORD32 *x_l1;
1253   WORD32 *x_l2;
1254   WORD32 *x_h2;
1255   const WORD16 *w_ptr = w;
1256   WORD32 i1;
1257 
1258   h2 = index << 1;
1259   l1 = index << 2;
1260   l2 = (index << 2) + (index << 1);
1261 
1262   x_l1 = &(x[l1]);
1263   x_l2 = &(x[l2]);
1264   x_h2 = &(x[h2]);
1265 
1266   fft_jmp = 6 * (index);
1267 
1268   for (i1 = 0; i1 < index1; i1++) {
1269     for (i = 0; i < index; i++) {
1270       si10 = (*w_ptr++);
1271       co10 = (*w_ptr++);
1272       si20 = (*w_ptr++);
1273       co20 = (*w_ptr++);
1274       si30 = (*w_ptr++);
1275       co30 = (*w_ptr++);
1276 
1277       x_0 = x[0];
1278       x_h2_0 = x[h2];
1279       x_l1_0 = x[l1];
1280       x_l2_0 = x[l2];
1281 
1282       xh0_0 = ixheaacd_add32_sat(x_0, x_l1_0);
1283       xl0_0 = ixheaacd_sub32_sat(x_0, x_l1_0);
1284 
1285       xh20_0 = ixheaacd_add32_sat(x_h2_0, x_l2_0);
1286       xl20_0 = ixheaacd_sub32_sat(x_h2_0, x_l2_0);
1287 
1288       x[0] = ixheaacd_add32_sat(xh0_0, xh20_0);
1289       xt0_0 = ixheaacd_sub32_sat(xh0_0, xh20_0);
1290 
1291       x_1 = x[1];
1292       x_h2_1 = x[h2 + 1];
1293       x_l1_1 = x[l1 + 1];
1294       x_l2_1 = x[l2 + 1];
1295 
1296       xh1_0 = ixheaacd_add32_sat(x_1, x_l1_1);
1297       xl1_0 = ixheaacd_sub32_sat(x_1, x_l1_1);
1298 
1299       xh21_0 = ixheaacd_add32_sat(x_h2_1, x_l2_1);
1300       xl21_0 = ixheaacd_sub32_sat(x_h2_1, x_l2_1);
1301 
1302       x[1] = ixheaacd_add32_sat(xh1_0, xh21_0);
1303       yt0_0 = ixheaacd_sub32_sat(xh1_0, xh21_0);
1304 
1305       xt1_0 = ixheaacd_add32_sat(xl0_0, xl21_0);
1306       xt2_0 = ixheaacd_sub32_sat(xl0_0, xl21_0);
1307 
1308       yt2_0 = ixheaacd_add32_sat(xl1_0, xl20_0);
1309       yt1_0 = ixheaacd_sub32_sat(xl1_0, xl20_0);
1310 
1311       mul_11 = ixheaacd_mult32x16in32(xt2_0, co30);
1312       mul_3 = ixheaacd_mult32x16in32(yt2_0, si30);
1313       x[l2] = ixheaacd_shl32_sat((mul_3 + mul_11), RADIXSHIFT);
1314 
1315       mul_5 = ixheaacd_mult32x16in32(xt2_0, si30);
1316       mul_9 = ixheaacd_mult32x16in32(yt2_0, co30);
1317       x[l2 + 1] = ixheaacd_shl32_sat((mul_9 - mul_5), RADIXSHIFT);
1318 
1319       mul_12 = ixheaacd_mult32x16in32(xt0_0, co20);
1320       mul_2 = ixheaacd_mult32x16in32(yt0_0, si20);
1321       x[l1] = ixheaacd_shl32_sat((mul_2 + mul_12), RADIXSHIFT);
1322 
1323       mul_6 = ixheaacd_mult32x16in32(xt0_0, si20);
1324       mul_8 = ixheaacd_mult32x16in32(yt0_0, co20);
1325       x[l1 + 1] = ixheaacd_shl32_sat((mul_8 - mul_6), RADIXSHIFT);
1326 
1327       mul_4 = ixheaacd_mult32x16in32(xt1_0, co10);
1328       mul_1 = ixheaacd_mult32x16in32(yt1_0, si10);
1329       x[h2] = ixheaacd_shl32_sat((mul_1 + mul_4), RADIXSHIFT);
1330 
1331       mul_10 = ixheaacd_mult32x16in32(xt1_0, si10);
1332       mul_7 = ixheaacd_mult32x16in32(yt1_0, co10);
1333       x[h2 + 1] = ixheaacd_shl32_sat((mul_7 - mul_10), RADIXSHIFT);
1334 
1335       x += 2;
1336     }
1337     x += fft_jmp;
1338     w_ptr = w_ptr - fft_jmp;
1339   }
1340 }