• 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 
22 #include "ixheaacd_sbr_common.h"
23 #include "ixheaacd_type_def.h"
24 
25 #include "ixheaacd_constants.h"
26 #include "ixheaacd_basic_ops32.h"
27 #include "ixheaacd_basic_ops16.h"
28 #include "ixheaacd_basic_ops40.h"
29 #include "ixheaacd_basic_ops.h"
30 
31 #include "ixheaacd_intrinsics.h"
32 #include "ixheaacd_common_rom.h"
33 #include "ixheaacd_bitbuffer.h"
34 #include "ixheaacd_sbrdecsettings.h"
35 #include "ixheaacd_sbr_scale.h"
36 #include "ixheaacd_lpp_tran.h"
37 #include "ixheaacd_env_extr_part.h"
38 #include "ixheaacd_sbr_rom.h"
39 #include "ixheaacd_hybrid.h"
40 #include "ixheaacd_ps_dec.h"
41 #include "ixheaacd_env_extr.h"
42 #include "ixheaacd_qmf_dec.h"
43 
44 #include "ixheaacd_basic_op.h"
45 #include "ixheaacd_env_calc.h"
46 
47 #include "ixheaacd_interface.h"
48 
49 #include "ixheaacd_function_selector.h"
50 #include "ixheaacd_audioobjtypes.h"
51 
52 #define DCT3_LEN (32)
53 #define DCT2_LEN (64)
54 
55 #define LP_SHIFT_VAL 7
56 #define HQ_SHIFT_64 4
57 #define RADIXSHIFT 1
58 #define ROUNDING_SPECTRA 1
59 #define HQ_SHIFT_VAL 4
60 
ixheaacd_mult32x32in32_shift25(WORD32 a,WORD32 b)61 static PLATFORM_INLINE WORD32 ixheaacd_mult32x32in32_shift25(WORD32 a,
62                                                              WORD32 b) {
63   WORD32 result;
64   WORD64 temp_result;
65 
66   temp_result = (WORD64)a * (WORD64)b;
67 
68   result = (WORD32)(temp_result >> 25);
69 
70   return (result);
71 }
72 
ixheaacd_pretwdct2(WORD32 * inp,WORD32 * out_fwd)73 VOID ixheaacd_pretwdct2(WORD32 *inp, WORD32 *out_fwd) {
74   WORD32 n;
75   WORD32 *out_rev = out_fwd + DCT2_LEN - 1;
76 
77   for (n = 0; n < DCT2_LEN / 2; n++) {
78     *out_fwd = *inp;
79     inp++;
80     *out_rev = *inp;
81     out_fwd++;
82 
83     out_rev--;
84     inp++;
85   }
86 
87   return;
88 }
89 
ixheaacd_pretwdct2_32(WORD32 * inp,WORD32 * out_fwd,int dct2_len)90 static PLATFORM_INLINE VOID ixheaacd_pretwdct2_32(WORD32 *inp, WORD32 *out_fwd,
91                                                   int dct2_len) {
92   WORD32 n;
93 
94   WORD32 *out_rev = out_fwd + dct2_len - 1;
95   for (n = dct2_len / 2 - 1; n >= 0; n--) {
96     *out_fwd = *inp;
97     inp++;
98     *out_rev = *inp;
99     out_fwd++;
100 
101     out_rev--;
102     inp++;
103   }
104 
105   return;
106 }
107 
ixheaacd_fftposttw(WORD32 * out,ia_qmf_dec_tables_struct * qmf_dec_tables_ptr)108 VOID ixheaacd_fftposttw(WORD32 *out,
109                         ia_qmf_dec_tables_struct *qmf_dec_tables_ptr) {
110   int k;
111   WORD32 *p_out_fwd, *ptr_out_rev;
112   const WORD16 *twidle_fwd, *twidle_rev;
113   WORD32 in1, in2, val1, val2;
114 
115   twidle_fwd = qmf_dec_tables_ptr->post_fft_tbl + 1;
116   twidle_rev = qmf_dec_tables_ptr->post_fft_tbl + 15;
117 
118   p_out_fwd = out;
119   ptr_out_rev = out + DCT2_LEN - 1;
120 
121   in1 = ((*p_out_fwd++) << 1);
122   val1 = ((*p_out_fwd--) << 1);
123 
124   *p_out_fwd++ = in1;
125   *p_out_fwd++ = val1;
126 
127   for (k = 1; k <= DCT2_LEN / 4; k++) {
128     WORD32 temp[4];
129     WORD16 twid_re, twid_im;
130 
131     temp[0] = *p_out_fwd++;
132     temp[1] = *p_out_fwd--;
133     temp[3] = *ptr_out_rev--;
134     temp[2] = *ptr_out_rev++;
135 
136     in2 = ixheaacd_sub32_sat(temp[3], temp[1]);
137     in1 = ixheaacd_add32_sat(temp[3], temp[1]);
138 
139     temp[1] = ixheaacd_sub32_sat(temp[0], temp[2]);
140     temp[3] = ixheaacd_add32_sat(temp[0], temp[2]);
141 
142     twid_re = *twidle_fwd++;
143     twid_im = *twidle_rev--;
144     val1 = ixheaacd_mult32x16in32(in1, twid_re) -
145            ixheaacd_mult32x16in32(temp[1], twid_im);
146     val2 = ixheaacd_mult32x16in32(temp[1], twid_re) +
147            ixheaacd_mult32x16in32(in1, twid_im);
148     val1 = val1 << 1;
149     val2 = val2 << 1;
150 
151     *p_out_fwd++ = ixheaacd_add32_sat(temp[3], val1);
152     *p_out_fwd++ = ixheaacd_add32_sat(in2, val2);
153 
154     *ptr_out_rev-- = ixheaacd_sub32_sat(val2, in2);
155     *ptr_out_rev-- = ixheaacd_sub32_sat(temp[3], val1);
156   }
157 
158   return;
159 }
160 
ixheaacd_posttwdct2(WORD32 * inp,WORD16 * out_fwd,ia_qmf_dec_tables_struct * qmf_dec_tables_ptr)161 VOID ixheaacd_posttwdct2(WORD32 *inp, WORD16 *out_fwd,
162                          ia_qmf_dec_tables_struct *qmf_dec_tables_ptr) {
163   WORD32 k;
164   WORD32 inp_re, inp_im, out_re, out_im, last_val, out_re1;
165   WORD16 *out_fwd2, *out_rev2, *out_rev;
166   WORD16 twid_re, twid_im;
167   const WORD16 *twidle_fwd;
168   WORD16 re1, im1, im2;
169 
170   out_rev = out_fwd + DCT2_LEN - 1;
171   out_rev2 = out_fwd - 1;
172   out_fwd2 = out_fwd + 65;
173   out_re = *inp++;
174   out_im = *inp++;
175   out_re1 =
176       ixheaacd_sat64_32(ixheaacd_add64((WORD64)out_re, (WORD64)out_im) >> 1);
177   re1 = ixheaacd_round16(ixheaacd_shl32(out_re1, (5 - 1)));
178 
179   *out_fwd++ = re1;
180 
181   last_val = ixheaacd_sub32_sat(out_re, out_im);
182 
183   twidle_fwd = qmf_dec_tables_ptr->dct23_tw + 2;
184   for (k = DCT2_LEN / 2 - 2; k >= 0; k--) {
185     inp_re = *inp++;
186     inp_im = *inp++;
187 
188     twid_re = *twidle_fwd++;
189     twid_im = *twidle_fwd++;
190     out_re = ixheaacd_sub32_sat(ixheaacd_mult32x16in32(inp_re, twid_re),
191                                 ixheaacd_mult32x16in32(inp_im, twid_im));
192     out_im = ixheaacd_add32_sat(ixheaacd_mult32x16in32(inp_im, twid_re),
193                                 ixheaacd_mult32x16in32(inp_re, twid_im));
194     re1 = ixheaacd_round16(ixheaacd_shl32(out_re, (5 - 1)));
195     im1 = ixheaacd_round16(ixheaacd_shl32(out_im, (5 - 1)));
196     im2 = ixheaacd_negate16(im1);
197 
198     *out_fwd++ = re1;
199     *out_rev2-- = re1;
200     *out_rev-- = im1;
201     *out_fwd2++ = im2;
202   }
203   twid_re = *twidle_fwd++;
204 
205   out_re = ixheaacd_mult32x16in32(last_val, twid_re);
206   re1 = ixheaacd_round16(ixheaacd_shl32(out_re, (5 - 1)));
207 
208   *out_fwd++ = re1;
209   *out_rev2-- = re1;
210 
211   return;
212 }
213 
ixheaacd_fftposttw_32(WORD32 * out,int dct2_len,ia_qmf_dec_tables_struct * qmf_dec_tables_ptr)214 static PLATFORM_INLINE VOID ixheaacd_fftposttw_32(
215     WORD32 *out, int dct2_len, ia_qmf_dec_tables_struct *qmf_dec_tables_ptr) {
216   int k;
217   WORD32 *ptr_out_fwd, *ptr_out_rev;
218   const WORD16 *twidle_fwd, *twidle_rev;
219   WORD32 in1, in2, val1, val2;
220 
221   twidle_fwd = qmf_dec_tables_ptr->post_fft_tbl + 2;
222   twidle_rev = qmf_dec_tables_ptr->post_fft_tbl + 14;
223 
224   ptr_out_fwd = out;
225   ptr_out_rev = out + dct2_len - 1;
226 
227   in1 = ((*ptr_out_fwd++) << 1);
228   val1 = ((*ptr_out_fwd--) << 1);
229 
230   *ptr_out_fwd++ = in1;
231   *ptr_out_fwd++ = val1;
232 
233   for (k = dct2_len / 4 - 1; k >= 0; k--) {
234     WORD32 temp0, temp1, temp2, temp3;
235     WORD16 twid_re, twid_im;
236 
237     temp0 = *ptr_out_fwd++;
238     temp1 = *ptr_out_fwd--;
239     temp3 = *ptr_out_rev--;
240     temp2 = *ptr_out_rev++;
241 
242     in1 = ixheaacd_add32_sat(temp1, temp3);
243     in2 = ixheaacd_sub32_sat(temp3, temp1);
244 
245     temp1 = ixheaacd_sub32_sat(temp0, temp2);
246     temp3 = ixheaacd_add32_sat(temp0, temp2);
247 
248     twid_re = *twidle_fwd;
249     twidle_fwd += 2;
250 
251     twid_im = *twidle_rev;
252     twidle_rev -= 2;
253 
254     val1 = ixheaacd_mult32x16in32(in1, twid_re) -
255            ixheaacd_mult32x16in32(temp1, twid_im);
256     val2 = ixheaacd_mult32x16in32(temp1, twid_re) +
257            ixheaacd_mult32x16in32(in1, twid_im);
258 
259     val1 = val1 << 1;
260     val2 = val2 << 1;
261 
262     *ptr_out_fwd++ = ixheaacd_add32_sat(temp3, val1);
263     *ptr_out_fwd++ = ixheaacd_add32_sat(in2, val2);
264 
265     *ptr_out_rev-- = ixheaacd_sub32_sat(val2, in2);
266     *ptr_out_rev-- = ixheaacd_sub32_sat(temp3, val1);
267   }
268 
269   return;
270 }
271 
272 static PLATFORM_INLINE VOID
ixheaacd_posttwdct2_32(WORD32 * inp,WORD16 * out_fwd,ia_qmf_dec_tables_struct * qmf_dec_tables_ptr)273 ixheaacd_posttwdct2_32(WORD32 *inp, WORD16 *out_fwd,
274                        ia_qmf_dec_tables_struct *qmf_dec_tables_ptr) {
275   int k;
276   WORD32 inp_re, out_re, out_im, last_val, out_re1;
277   WORD16 *out_rev, *out_rev2, *out_fwd2;
278   WORD16 twid_re, twid_im;
279   const WORD16 *twidle_fwd;
280   WORD16 re1, im1, im2;
281   WORD32 rounding_fac = 0x8000;
282 
283   out_rev = out_fwd + 32 - 1;
284   out_rev2 = out_fwd - 1;
285   out_fwd2 = out_fwd + 32 + 1;
286   out_fwd[32] = 0;
287 
288   out_re = *inp++;
289   out_im = *inp++;
290 
291   out_re1 =
292       ixheaacd_sat64_32(ixheaacd_add64((WORD64)out_re, (WORD64)out_im) >> 1);
293   re1 = ixheaacd_round16(ixheaacd_shl32_sat(out_re1, (5 - 1)));
294   *out_fwd++ = re1;
295   last_val = ixheaacd_sub32_sat(out_re, out_im);
296 
297   twidle_fwd = qmf_dec_tables_ptr->dct23_tw + 4;
298   for (k = 14; k >= 0; k--) {
299     WORD32 temp1, temp2;
300     inp_re = *inp++;
301     twid_re = *twidle_fwd++;
302     twid_im = *twidle_fwd;
303     twidle_fwd += 3;
304 
305     temp1 = ixheaacd_mult32x16in32(inp_re, twid_re);
306     temp2 = ixheaacd_mult32x16in32(inp_re, twid_im);
307 
308     inp_re = *inp++;
309 
310     out_re = ixheaacd_sub32_sat(temp1, ixheaacd_mult32x16in32(inp_re, twid_im));
311     out_im = ixheaacd_add32_sat(ixheaacd_mult32x16in32(inp_re, twid_re), temp2);
312 
313     out_re = ixheaacd_add32_sat(out_re, out_re);
314     out_im = ixheaacd_add32_sat(out_im, out_im);
315     out_re = ixheaacd_add32_sat(out_re, out_re);
316     out_im = ixheaacd_add32_sat(out_im, out_im);
317     out_re = ixheaacd_add32_sat(out_re, out_re);
318     out_im = ixheaacd_add32_sat(out_im, out_im);
319     out_re = ixheaacd_add32_sat(out_re, out_re);
320     out_im = ixheaacd_add32_sat(out_im, out_im);
321     out_re = ixheaacd_add32_sat(out_re, rounding_fac);
322     out_im = ixheaacd_add32_sat(out_im, rounding_fac);
323     re1 = (out_re >> 16);
324     im1 = (out_im >> 16);
325     im2 = ixheaacd_negate16(im1);
326 
327     *out_fwd++ = re1;
328     *out_rev2-- = re1;
329     *out_rev-- = im1;
330     *out_fwd2++ = im2;
331   }
332   twid_re = *twidle_fwd++;
333 
334   out_re = ixheaacd_mult32x16in32(last_val, twid_re);
335   re1 = ixheaacd_round16(ixheaacd_shl32_sat(out_re, (5 - 1)));
336   *out_fwd++ = re1;
337   *out_rev2-- = re1;
338 
339   return;
340 }
341 
ixheaacd_dct2_32(WORD32 * inp,WORD32 * out,ia_qmf_dec_tables_struct * qmf_dec_tables_ptr,WORD16 * filter_states)342 VOID ixheaacd_dct2_32(WORD32 *inp, WORD32 *out,
343                       ia_qmf_dec_tables_struct *qmf_dec_tables_ptr,
344                       WORD16 *filter_states) {
345   WORD32 *output;
346 
347   output = out + 16;
348   filter_states = filter_states + 16;
349   ixheaacd_pretwdct2_32(inp, output, 32);
350 
351   ixheaacd_radix4bfly(qmf_dec_tables_ptr->w_16, output, 1, 4);
352   ixheaacd_postradixcompute4(inp, output, qmf_dec_tables_ptr->dig_rev_table4_16,
353                              16);
354   ixheaacd_fftposttw_32(inp, 32, qmf_dec_tables_ptr);
355 
356   ixheaacd_posttwdct2_32(inp, filter_states, qmf_dec_tables_ptr);
357 
358   return;
359 }
360 
ixheaacd_sbr_qmfanal32_winadd_eld_mps(WORD32 * inp1,WORD32 * inp2,const WORD32 * p_qmf1,const WORD32 * p_qmf2,WORD32 * p_out)361 VOID ixheaacd_sbr_qmfanal32_winadd_eld_mps(WORD32 *inp1, WORD32 *inp2,
362                                            const WORD32 *p_qmf1,
363                                            const WORD32 *p_qmf2,
364                                            WORD32 *p_out) {
365   WORD32 n;
366   WORD32 resolution = 64;
367 
368   for (n = 0; n < 64; n += 2) {
369     WORD32 accu;
370     accu = ixheaacd_mul32_sh(inp1[n + 0], p_qmf1[(n + 0)], 31);
371     accu = ixheaacd_add32(accu,
372                           ixheaacd_mul32_sh(inp1[n + 2 * resolution],
373                                             p_qmf1[(n + 2 * resolution)], 31));
374     accu = ixheaacd_add32(accu,
375                           ixheaacd_mul32_sh(inp1[n + 4 * resolution],
376                                             p_qmf1[(n + 4 * resolution)], 31));
377     accu = ixheaacd_add32(accu,
378                           ixheaacd_mul32_sh(inp1[n + 6 * resolution],
379                                             p_qmf1[(n + 6 * resolution)], 31));
380     accu = ixheaacd_add32(accu,
381                           ixheaacd_mul32_sh(inp1[n + 8 * resolution],
382                                             p_qmf1[(n + 8 * resolution)], 31));
383     p_out[n] = accu;
384 
385     accu = ixheaacd_mul32_sh(inp1[n + 1 + 0], p_qmf1[(n + 1 + 0)], 31);
386     accu = ixheaacd_add32_sat(
387         accu, ixheaacd_mul32_sh(inp1[n + 1 + 2 * resolution],
388                                 p_qmf1[(n + 1 + 2 * resolution)], 31));
389     accu = ixheaacd_add32_sat(
390         accu, ixheaacd_mul32_sh(inp1[n + 1 + 4 * resolution],
391                                 p_qmf1[(n + 1 + 4 * resolution)], 31));
392     accu = ixheaacd_add32_sat(
393         accu, ixheaacd_mul32_sh(inp1[n + 1 + 6 * resolution],
394                                 p_qmf1[(n + 1 + 6 * resolution)], 31));
395     accu = ixheaacd_add32_sat(
396         accu, ixheaacd_mul32_sh(inp1[n + 1 + 8 * resolution],
397                                 p_qmf1[(n + 1 + 8 * resolution)], 31));
398     p_out[n + 1] = accu;
399 
400     accu = ixheaacd_mul32_sh(inp2[n + 0], p_qmf2[(n + 0)], 31);
401     accu = ixheaacd_add32(accu,
402                           ixheaacd_mul32_sh(inp2[n + 2 * resolution],
403                                             p_qmf2[(n + 2 * resolution)], 31));
404     accu = ixheaacd_add32(accu,
405                           ixheaacd_mul32_sh(inp2[n + 4 * resolution],
406                                             p_qmf2[(n + 4 * resolution)], 31));
407     accu = ixheaacd_add32(accu,
408                           ixheaacd_mul32_sh(inp2[n + 6 * resolution],
409                                             p_qmf2[(n + 6 * resolution)], 31));
410     accu = ixheaacd_add32(accu,
411                           ixheaacd_mul32_sh(inp2[n + 8 * resolution],
412                                             p_qmf2[(n + 8 * resolution)], 31));
413     p_out[n + 64] = accu;
414 
415     accu = ixheaacd_mul32_sh(inp2[n + 1 + 0], p_qmf2[(n + 1 + 0)], 31);
416     accu = ixheaacd_add32_sat(
417         accu, ixheaacd_mul32_sh(inp2[n + 1 + 2 * resolution],
418                                 p_qmf2[(n + 1 + 2 * resolution)], 31));
419     accu = ixheaacd_add32_sat(
420         accu, ixheaacd_mul32_sh(inp2[n + 1 + 4 * resolution],
421                                 p_qmf2[(n + 1 + 4 * resolution)], 31));
422     accu = ixheaacd_add32_sat(
423         accu, ixheaacd_mul32_sh(inp2[n + 1 + 6 * resolution],
424                                 p_qmf2[(n + 1 + 6 * resolution)], 31));
425     accu = ixheaacd_add32_sat(
426         accu, ixheaacd_mul32_sh(inp2[n + 1 + 8 * resolution],
427                                 p_qmf2[(n + 1 + 8 * resolution)], 31));
428     p_out[n + 1 + 64] = accu;
429   }
430 }
431 
ixheaacd_sbr_qmfanal32_winadd_eld_32(WORD32 * inp1,WORD32 * inp2,const WORD32 * p_qmf1,const WORD32 * p_qmf2,WORD32 * p_out)432 VOID ixheaacd_sbr_qmfanal32_winadd_eld_32(WORD32 *inp1, WORD32 *inp2,
433                                           const WORD32 *p_qmf1,
434                                           const WORD32 *p_qmf2, WORD32 *p_out) {
435   WORD32 n;
436 
437   for (n = 0; n < 32; n += 2) {
438     WORD32 accu;
439     accu = ixheaacd_mul32_sh(inp1[n + 0], p_qmf1[(n + 0)], 31);
440     accu = ixheaacd_add32(
441         accu, ixheaacd_mul32_sh(inp1[n + 64], p_qmf1[(n + 64)], 31));
442     accu = ixheaacd_add32(
443         accu, ixheaacd_mul32_sh(inp1[n + 128], p_qmf1[(n + 128)], 31));
444     accu = ixheaacd_add32(
445         accu, ixheaacd_mul32_sh(inp1[n + 192], p_qmf1[(n + 192)], 31));
446     accu = ixheaacd_add32(
447         accu, ixheaacd_mul32_sh(inp1[n + 256], p_qmf1[(n + 256)], 31));
448     p_out[n] = accu;
449 
450     accu = ixheaacd_mul32_sh(inp1[n + 1 + 0], p_qmf1[(n + 1 + 0)], 31);
451     accu = ixheaacd_add32_sat(
452         accu, ixheaacd_mul32_sh(inp1[n + 1 + 64], p_qmf1[(n + 1 + 64)], 31));
453     accu = ixheaacd_add32_sat(
454         accu, ixheaacd_mul32_sh(inp1[n + 1 + 128], p_qmf1[(n + 1 + 128)], 31));
455     accu = ixheaacd_add32_sat(
456         accu, ixheaacd_mul32_sh(inp1[n + 1 + 192], p_qmf1[(n + 1 + 192)], 31));
457     accu = ixheaacd_add32_sat(
458         accu, ixheaacd_mul32_sh(inp1[n + 1 + 256], p_qmf1[(n + 1 + 256)], 31));
459     p_out[n + 1] = accu;
460 
461     accu = ixheaacd_mul32_sh(inp2[n + 0], p_qmf2[(n + 0)], 31);
462     accu = ixheaacd_add32(
463         accu, ixheaacd_mul32_sh(inp2[n + 64], p_qmf2[(n + 64)], 31));
464     accu = ixheaacd_add32(
465         accu, ixheaacd_mul32_sh(inp2[n + 128], p_qmf2[(n + 128)], 31));
466     accu = ixheaacd_add32(
467         accu, ixheaacd_mul32_sh(inp2[n + 192], p_qmf2[(n + 192)], 31));
468     accu = ixheaacd_add32(
469         accu, ixheaacd_mul32_sh(inp2[n + 256], p_qmf2[(n + 256)], 31));
470     p_out[n + 32] = accu;
471 
472     accu = ixheaacd_mul32_sh(inp2[n + 1 + 0], p_qmf2[(n + 1 + 0)], 31);
473     accu = ixheaacd_add32_sat(
474         accu, ixheaacd_mul32_sh(inp2[n + 1 + 64], p_qmf2[(n + 1 + 64)], 31));
475     accu = ixheaacd_add32_sat(
476         accu, ixheaacd_mul32_sh(inp2[n + 1 + 128], p_qmf2[(n + 1 + 128)], 31));
477     accu = ixheaacd_add32_sat(
478         accu, ixheaacd_mul32_sh(inp2[n + 1 + 192], p_qmf2[(n + 1 + 192)], 31));
479     accu = ixheaacd_add32_sat(
480         accu, ixheaacd_mul32_sh(inp2[n + 1 + 256], p_qmf2[(n + 1 + 256)], 31));
481     p_out[n + 1 + 32] = accu;
482   }
483 }
484 
ixheaacd_sbr_qmfanal32_winadd_eld(WORD16 * inp1,WORD16 * inp2,const WORD16 * p_qmf1,const WORD16 * p_qmf2,WORD32 * p_out)485 VOID ixheaacd_sbr_qmfanal32_winadd_eld(WORD16 *inp1, WORD16 *inp2,
486                                        const WORD16 *p_qmf1,
487                                        const WORD16 *p_qmf2, WORD32 *p_out) {
488   WORD32 n;
489 
490   for (n = 0; n < 32; n += 2) {
491     WORD32 accu;
492     accu = ixheaacd_mult16x16in32(inp1[n + 0], p_qmf1[(n + 0)]);
493     accu = ixheaacd_add32_sat(
494         accu, ixheaacd_mult16x16in32(inp1[n + 64], p_qmf1[(n + 64)]));
495     accu = ixheaacd_add32_sat(
496         accu, ixheaacd_mult16x16in32(inp1[n + 128], p_qmf1[(n + 128)]));
497     accu = ixheaacd_add32_sat(
498         accu, ixheaacd_mult16x16in32(inp1[n + 192], p_qmf1[(n + 192)]));
499     accu = ixheaacd_add32_sat(
500         accu, ixheaacd_mult16x16in32(inp1[n + 256], p_qmf1[(n + 256)]));
501     p_out[n] = accu;
502 
503     accu = ixheaacd_mult16x16in32(inp1[n + 1 + 0], p_qmf1[(n + 1 + 0)]);
504     accu = ixheaacd_add32_sat(
505         accu, ixheaacd_mult16x16in32(inp1[n + 1 + 64], p_qmf1[(n + 1 + 64)]));
506     accu = ixheaacd_add32_sat(
507         accu, ixheaacd_mult16x16in32(inp1[n + 1 + 128], p_qmf1[(n + 1 + 128)]));
508     accu = ixheaacd_add32_sat(
509         accu, ixheaacd_mult16x16in32(inp1[n + 1 + 192], p_qmf1[(n + 1 + 192)]));
510     accu = ixheaacd_add32_sat(
511         accu, ixheaacd_mult16x16in32(inp1[n + 1 + 256], p_qmf1[(n + 1 + 256)]));
512     p_out[n + 1] = accu;
513 
514     accu = ixheaacd_mult16x16in32(inp2[n + 0], p_qmf2[(n + 0)]);
515     accu = ixheaacd_add32_sat(
516         accu, ixheaacd_mult16x16in32(inp2[n + 64], p_qmf2[(n + 64)]));
517     accu = ixheaacd_add32_sat(
518         accu, ixheaacd_mult16x16in32(inp2[n + 128], p_qmf2[(n + 128)]));
519     accu = ixheaacd_add32_sat(
520         accu, ixheaacd_mult16x16in32(inp2[n + 192], p_qmf2[(n + 192)]));
521     accu = ixheaacd_add32_sat(
522         accu, ixheaacd_mult16x16in32(inp2[n + 256], p_qmf2[(n + 256)]));
523     p_out[n + 32] = accu;
524 
525     accu = ixheaacd_mult16x16in32(inp2[n + 1 + 0], p_qmf2[(n + 1 + 0)]);
526     accu = ixheaacd_add32_sat(
527         accu, ixheaacd_mult16x16in32(inp2[n + 1 + 64], p_qmf2[(n + 1 + 64)]));
528     accu = ixheaacd_add32_sat(
529         accu, ixheaacd_mult16x16in32(inp2[n + 1 + 128], p_qmf2[(n + 1 + 128)]));
530     accu = ixheaacd_add32_sat(
531         accu, ixheaacd_mult16x16in32(inp2[n + 1 + 192], p_qmf2[(n + 1 + 192)]));
532     accu = ixheaacd_add32_sat(
533         accu, ixheaacd_mult16x16in32(inp2[n + 1 + 256], p_qmf2[(n + 1 + 256)]));
534     p_out[n + 1 + 32] = accu;
535   }
536 }
537 
ixheaacd_esbr_qmfanal32_winadd(WORD32 * inp1,WORD32 * inp2,WORD32 * p_qmf1,WORD32 * p_qmf2,WORD32 * p_out,WORD32 num_band_anal_qmf)538 VOID ixheaacd_esbr_qmfanal32_winadd(WORD32 *inp1, WORD32 *inp2, WORD32 *p_qmf1,
539                                     WORD32 *p_qmf2, WORD32 *p_out,
540                                     WORD32 num_band_anal_qmf) {
541   WORD32 n;
542   WORD64 accu;
543 
544   if (num_band_anal_qmf == 32) {
545     for (n = 0; n < num_band_anal_qmf; n += 2) {
546       accu = ixheaacd_mult64(inp1[n + 0], p_qmf1[2 * (n + 0)]);
547       accu = ixheaacd_add64(
548           accu, ixheaacd_mult64(inp1[n + 2 * num_band_anal_qmf],
549                                 p_qmf1[2 * (n + 2 * num_band_anal_qmf)]));
550       accu = ixheaacd_add64(
551           accu, ixheaacd_mult64(inp1[n + 4 * num_band_anal_qmf],
552                                 p_qmf1[2 * (n + 4 * num_band_anal_qmf)]));
553       accu = ixheaacd_add64(
554           accu, ixheaacd_mult64(inp1[n + 6 * num_band_anal_qmf],
555                                 p_qmf1[2 * (n + 6 * num_band_anal_qmf)]));
556       accu = ixheaacd_add64(
557           accu, ixheaacd_mult64(inp1[n + 8 * num_band_anal_qmf],
558                                 p_qmf1[2 * (n + 8 * num_band_anal_qmf)]));
559       p_out[n] = (WORD32)(accu >> 31);
560 
561       accu = ixheaacd_mult64(inp1[n + 1 + 0], p_qmf1[2 * (n + 1 + 0)]);
562       accu = ixheaacd_add64(
563           accu, ixheaacd_mult64(inp1[n + 1 + 2 * num_band_anal_qmf],
564                                 p_qmf1[2 * (n + 1 + 2 * num_band_anal_qmf)]));
565       accu = ixheaacd_add64(
566           accu, ixheaacd_mult64(inp1[n + 1 + 4 * num_band_anal_qmf],
567                                 p_qmf1[2 * (n + 1 + 4 * num_band_anal_qmf)]));
568       accu = ixheaacd_add64(
569           accu, ixheaacd_mult64(inp1[n + 1 + 6 * num_band_anal_qmf],
570                                 p_qmf1[2 * (n + 1 + 6 * num_band_anal_qmf)]));
571       accu = ixheaacd_add64(
572           accu, ixheaacd_mult64(inp1[n + 1 + 8 * num_band_anal_qmf],
573                                 p_qmf1[2 * (n + 1 + 8 * num_band_anal_qmf)]));
574       p_out[n + 1] = (WORD32)(accu >> 31);
575 
576       accu = ixheaacd_mult64(inp2[n + 0], p_qmf2[2 * (n + 0)]);
577       accu = ixheaacd_add64(
578           accu, ixheaacd_mult64(inp2[n + 2 * num_band_anal_qmf],
579                                 p_qmf2[2 * (n + 2 * num_band_anal_qmf)]));
580       accu = ixheaacd_add64(
581           accu, ixheaacd_mult64(inp2[n + 4 * num_band_anal_qmf],
582                                 p_qmf2[2 * (n + 4 * num_band_anal_qmf)]));
583       accu = ixheaacd_add64(
584           accu, ixheaacd_mult64(inp2[n + 6 * num_band_anal_qmf],
585                                 p_qmf2[2 * (n + 6 * num_band_anal_qmf)]));
586       accu = ixheaacd_add64(
587           accu, ixheaacd_mult64(inp2[n + 8 * num_band_anal_qmf],
588                                 p_qmf2[2 * (n + 8 * num_band_anal_qmf)]));
589       p_out[n + num_band_anal_qmf] = (WORD32)(accu >> 31);
590 
591       accu = ixheaacd_mult64(inp2[n + 1 + 0], p_qmf2[2 * (n + 1 + 0)]);
592       accu = ixheaacd_add64(
593           accu, ixheaacd_mult64(inp2[n + 1 + 2 * num_band_anal_qmf],
594                                 p_qmf2[2 * (n + 1 + 2 * num_band_anal_qmf)]));
595       accu = ixheaacd_add64(
596           accu, ixheaacd_mult64(inp2[n + 1 + 4 * num_band_anal_qmf],
597                                 p_qmf2[2 * (n + 1 + 4 * num_band_anal_qmf)]));
598       accu = ixheaacd_add64(
599           accu, ixheaacd_mult64(inp2[n + 1 + 6 * num_band_anal_qmf],
600                                 p_qmf2[2 * (n + 1 + 6 * num_band_anal_qmf)]));
601       accu = ixheaacd_add64(
602           accu, ixheaacd_mult64(inp2[n + 1 + 8 * num_band_anal_qmf],
603                                 p_qmf2[2 * (n + 1 + 8 * num_band_anal_qmf)]));
604       p_out[n + 1 + num_band_anal_qmf] = (WORD32)(accu >> 31);
605     }
606   } else if (num_band_anal_qmf == 24) {
607     for (n = 0; n < num_band_anal_qmf; n += 2) {
608       accu = ixheaacd_mult64(inp1[n + 0], p_qmf1[(n + 0)]);
609       accu = ixheaacd_add64(
610           accu, ixheaacd_mult64(inp1[n + 2 * num_band_anal_qmf],
611                                 p_qmf1[(n + 2 * num_band_anal_qmf)]));
612       accu = ixheaacd_add64(
613           accu, ixheaacd_mult64(inp1[n + 4 * num_band_anal_qmf],
614                                 p_qmf1[(n + 4 * num_band_anal_qmf)]));
615       accu = ixheaacd_add64(
616           accu, ixheaacd_mult64(inp1[n + 6 * num_band_anal_qmf],
617                                 p_qmf1[(n + 6 * num_band_anal_qmf)]));
618       accu = ixheaacd_add64(
619           accu, ixheaacd_mult64(inp1[n + 8 * num_band_anal_qmf],
620                                 p_qmf1[(n + 8 * num_band_anal_qmf)]));
621       p_out[n] = (WORD32)(accu >> 31);
622 
623       accu = ixheaacd_mult64(inp1[n + 1 + 0], p_qmf1[(n + 1 + 0)]);
624       accu = ixheaacd_add64(
625           accu, ixheaacd_mult64(inp1[n + 1 + 2 * num_band_anal_qmf],
626                                 p_qmf1[(n + 1 + 2 * num_band_anal_qmf)]));
627       accu = ixheaacd_add64(
628           accu, ixheaacd_mult64(inp1[n + 1 + 4 * num_band_anal_qmf],
629                                 p_qmf1[(n + 1 + 4 * num_band_anal_qmf)]));
630       accu = ixheaacd_add64(
631           accu, ixheaacd_mult64(inp1[n + 1 + 6 * num_band_anal_qmf],
632                                 p_qmf1[(n + 1 + 6 * num_band_anal_qmf)]));
633       accu = ixheaacd_add64(
634           accu, ixheaacd_mult64(inp1[n + 1 + 8 * num_band_anal_qmf],
635                                 p_qmf1[(n + 1 + 8 * num_band_anal_qmf)]));
636       p_out[n + 1] = (WORD32)(accu >> 31);
637 
638       accu = ixheaacd_mult64(inp2[n + 0], p_qmf2[(n + 0)]);
639       accu = ixheaacd_add64(
640           accu, ixheaacd_mult64(inp2[n + 2 * num_band_anal_qmf],
641                                 p_qmf2[(n + 2 * num_band_anal_qmf)]));
642       accu = ixheaacd_add64(
643           accu, ixheaacd_mult64(inp2[n + 4 * num_band_anal_qmf],
644                                 p_qmf2[(n + 4 * num_band_anal_qmf)]));
645       accu = ixheaacd_add64(
646           accu, ixheaacd_mult64(inp2[n + 6 * num_band_anal_qmf],
647                                 p_qmf2[(n + 6 * num_band_anal_qmf)]));
648       accu = ixheaacd_add64(
649           accu, ixheaacd_mult64(inp2[n + 8 * num_band_anal_qmf],
650                                 p_qmf2[(n + 8 * num_band_anal_qmf)]));
651       p_out[n + num_band_anal_qmf] = (WORD32)(accu >> 31);
652 
653       accu = ixheaacd_mult64(inp2[n + 1 + 0], p_qmf2[(n + 1 + 0)]);
654       accu = ixheaacd_add64(
655           accu, ixheaacd_mult64(inp2[n + 1 + 2 * num_band_anal_qmf],
656                                 p_qmf2[(n + 1 + 2 * num_band_anal_qmf)]));
657       accu = ixheaacd_add64(
658           accu, ixheaacd_mult64(inp2[n + 1 + 4 * num_band_anal_qmf],
659                                 p_qmf2[(n + 1 + 4 * num_band_anal_qmf)]));
660       accu = ixheaacd_add64(
661           accu, ixheaacd_mult64(inp2[n + 1 + 6 * num_band_anal_qmf],
662                                 p_qmf2[(n + 1 + 6 * num_band_anal_qmf)]));
663       accu = ixheaacd_add64(
664           accu, ixheaacd_mult64(inp2[n + 1 + 8 * num_band_anal_qmf],
665                                 p_qmf2[(n + 1 + 8 * num_band_anal_qmf)]));
666       p_out[n + 1 + num_band_anal_qmf] = (WORD32)(accu >> 31);
667     }
668 
669   } else {
670     for (n = 0; n < num_band_anal_qmf; n += 2) {
671       accu = ixheaacd_mult64(inp1[n + 0], p_qmf1[4 * (n + 0)]);
672       accu = ixheaacd_add64(
673           accu, ixheaacd_mult64(inp1[n + 2 * num_band_anal_qmf],
674                                 p_qmf1[4 * (n + 2 * num_band_anal_qmf)]));
675       accu = ixheaacd_add64(
676           accu, ixheaacd_mult64(inp1[n + 4 * num_band_anal_qmf],
677                                 p_qmf1[4 * (n + 4 * num_band_anal_qmf)]));
678       accu = ixheaacd_add64(
679           accu, ixheaacd_mult64(inp1[n + 6 * num_band_anal_qmf],
680                                 p_qmf1[4 * (n + 6 * num_band_anal_qmf)]));
681       accu = ixheaacd_add64(
682           accu, ixheaacd_mult64(inp1[n + 8 * num_band_anal_qmf],
683                                 p_qmf1[4 * (n + 8 * num_band_anal_qmf)]));
684       p_out[n] = (WORD32)(accu >> 31);
685 
686       accu = ixheaacd_mult64(inp1[n + 1 + 0], p_qmf1[4 * (n + 1 + 0)]);
687       accu = ixheaacd_add64(
688           accu, ixheaacd_mult64(inp1[n + 1 + 2 * num_band_anal_qmf],
689                                 p_qmf1[4 * (n + 1 + 2 * num_band_anal_qmf)]));
690       accu = ixheaacd_add64(
691           accu, ixheaacd_mult64(inp1[n + 1 + 4 * num_band_anal_qmf],
692                                 p_qmf1[4 * (n + 1 + 4 * num_band_anal_qmf)]));
693       accu = ixheaacd_add64(
694           accu, ixheaacd_mult64(inp1[n + 1 + 6 * num_band_anal_qmf],
695                                 p_qmf1[4 * (n + 1 + 6 * num_band_anal_qmf)]));
696       accu = ixheaacd_add64(
697           accu, ixheaacd_mult64(inp1[n + 1 + 8 * num_band_anal_qmf],
698                                 p_qmf1[4 * (n + 1 + 8 * num_band_anal_qmf)]));
699       p_out[n + 1] = (WORD32)(accu >> 31);
700 
701       accu = ixheaacd_mult64(inp2[n + 0], p_qmf2[4 * (n + 0)]);
702       accu = ixheaacd_add64(
703           accu, ixheaacd_mult64(inp2[n + 2 * num_band_anal_qmf],
704                                 p_qmf2[4 * (n + 2 * num_band_anal_qmf)]));
705       accu = ixheaacd_add64(
706           accu, ixheaacd_mult64(inp2[n + 4 * num_band_anal_qmf],
707                                 p_qmf2[4 * (n + 4 * num_band_anal_qmf)]));
708       accu = ixheaacd_add64(
709           accu, ixheaacd_mult64(inp2[n + 6 * num_band_anal_qmf],
710                                 p_qmf2[4 * (n + 6 * num_band_anal_qmf)]));
711       accu = ixheaacd_add64(
712           accu, ixheaacd_mult64(inp2[n + 8 * num_band_anal_qmf],
713                                 p_qmf2[4 * (n + 8 * num_band_anal_qmf)]));
714       p_out[n + num_band_anal_qmf] = (WORD32)(accu >> 31);
715 
716       accu = ixheaacd_mult64(inp2[n + 1 + 0], p_qmf2[4 * (n + 1 + 0)]);
717       accu = ixheaacd_add64(
718           accu, ixheaacd_mult64(inp2[n + 1 + 2 * num_band_anal_qmf],
719                                 p_qmf2[4 * (n + 1 + 2 * num_band_anal_qmf)]));
720       accu = ixheaacd_add64(
721           accu, ixheaacd_mult64(inp2[n + 1 + 4 * num_band_anal_qmf],
722                                 p_qmf2[4 * (n + 1 + 4 * num_band_anal_qmf)]));
723       accu = ixheaacd_add64(
724           accu, ixheaacd_mult64(inp2[n + 1 + 6 * num_band_anal_qmf],
725                                 p_qmf2[4 * (n + 1 + 6 * num_band_anal_qmf)]));
726       accu = ixheaacd_add64(
727           accu, ixheaacd_mult64(inp2[n + 1 + 8 * num_band_anal_qmf],
728                                 p_qmf2[4 * (n + 1 + 8 * num_band_anal_qmf)]));
729       p_out[n + 1 + num_band_anal_qmf] = (WORD32)(accu >> 31);
730     }
731   }
732 }
733 
ixheaacd_esbr_inv_modulation(WORD32 * qmf_real,ia_sbr_qmf_filter_bank_struct * syn_qmf,ia_qmf_dec_tables_struct * qmf_dec_tables_ptr,WORD32 no_synthesis_channels)734 VOID ixheaacd_esbr_inv_modulation(
735     WORD32 *qmf_real, ia_sbr_qmf_filter_bank_struct *syn_qmf,
736     ia_qmf_dec_tables_struct *qmf_dec_tables_ptr, WORD32 no_synthesis_channels) {
737 
738     if (no_synthesis_channels == NO_SYNTHESIS_CHANNELS_DOWN_SAMPLED)
739     {
740       ixheaacd_esbr_cos_sin_mod(qmf_real, syn_qmf, qmf_dec_tables_ptr->esbr_w_16,
741         qmf_dec_tables_ptr->dig_rev_table4_16);
742     }
743     else
744     {
745       ixheaacd_esbr_cos_sin_mod(qmf_real, syn_qmf, qmf_dec_tables_ptr->esbr_w_32,
746         qmf_dec_tables_ptr->dig_rev_table2_32);
747     }
748 }
749 
ixheaacd_sbr_qmfsyn32_winadd(WORD16 * tmp1,WORD16 * tmp2,WORD16 * inp1,WORD16 * sample_buffer,FLAG shift,WORD32 ch_fac)750 VOID ixheaacd_sbr_qmfsyn32_winadd(WORD16 *tmp1, WORD16 *tmp2, WORD16 *inp1,
751                                   WORD16 *sample_buffer, FLAG shift,
752                                   WORD32 ch_fac) {
753   WORD32 k;
754   WORD32 rounding_fac = 0x8000;
755   rounding_fac = rounding_fac >> shift;
756 
757   for (k = 0; k < 32; k++) {
758     WORD32 syn_out = rounding_fac;
759 
760     syn_out = ixheaacd_add32(
761         syn_out, ixheaacd_mult16x16in32(tmp1[0 + k], inp1[2 * (k + 0)]));
762     syn_out = ixheaacd_add32(
763         syn_out, ixheaacd_mult16x16in32(tmp1[128 + k], inp1[2 * (k + 64)]));
764     syn_out = ixheaacd_add32(
765         syn_out, ixheaacd_mult16x16in32(tmp1[256 + k], inp1[2 * (k + 128)]));
766     syn_out = ixheaacd_add32(
767         syn_out, ixheaacd_mult16x16in32(tmp1[384 + k], inp1[2 * (k + 192)]));
768     syn_out = ixheaacd_add32(
769         syn_out, ixheaacd_mult16x16in32(tmp1[512 + k], inp1[2 * (k + 256)]));
770 
771     syn_out = ixheaacd_add32(
772         syn_out, ixheaacd_mult16x16in32(tmp2[64 + k], inp1[2 * (k + 32)]));
773     syn_out = ixheaacd_add32(
774         syn_out, ixheaacd_mult16x16in32(tmp2[192 + k], inp1[2 * (k + 96)]));
775     syn_out = ixheaacd_add32(
776         syn_out, ixheaacd_mult16x16in32(tmp2[320 + k], inp1[2 * (k + 160)]));
777     syn_out = ixheaacd_add32(
778         syn_out, ixheaacd_mult16x16in32(tmp2[448 + k], inp1[2 * (k + 224)]));
779     syn_out = ixheaacd_add32(
780         syn_out, ixheaacd_mult16x16in32(tmp2[576 + k], inp1[2 * (k + 288)]));
781     syn_out = ixheaacd_add32_sat(syn_out, syn_out);
782     if (shift == 2) {
783       syn_out = ixheaacd_add32_sat(syn_out, syn_out);
784     }
785     sample_buffer[ch_fac * k] = (syn_out >> 16);
786   }
787 }
788 
ixheaacd_sbr_pre_twiddle(WORD32 * p_xre,WORD32 * p_xim,WORD16 * p_twiddles)789 void ixheaacd_sbr_pre_twiddle(WORD32 *p_xre, WORD32 *p_xim,
790                               WORD16 *p_twiddles) {
791   int k;
792 
793   for (k = 62; k >= 0; k--) {
794     WORD32 x_re = *p_xre;
795     WORD32 x_im = *p_xim;
796 
797     WORD16 ixheaacd_cosine = *p_twiddles++;
798     WORD16 ixheaacd_sine = *p_twiddles++;
799 
800     WORD32 re, im;
801 
802     re = ixheaacd_mac32x16in32_shl_sat(
803         ixheaacd_mult32x16in32_shl(x_re, ixheaacd_cosine), x_im, ixheaacd_sine);
804     im = ixheaacd_sub32_sat(ixheaacd_mult32x16in32_shl(x_im, ixheaacd_cosine),
805                             ixheaacd_mult32x16in32_shl(x_re, ixheaacd_sine));
806 
807     *p_xre++ = re;
808     *p_xim++ = im;
809   }
810 }
811 
ixheaacd_cplx_synt_qmffilt(WORD32 ** qmf_real,WORD32 ** qmf_imag,WORD32 split,ia_sbr_scale_fact_struct * sbr_scale_factor,WORD16 * time_out,ia_sbr_qmf_filter_bank_struct * qmf_bank,ia_ps_dec_struct * ptr_ps_dec,FLAG active,FLAG low_pow_flag,ia_sbr_tables_struct * sbr_tables_ptr,ixheaacd_misc_tables * pstr_common_tables,WORD32 ch_fac,FLAG drc_on,WORD32 drc_sbr_factors[][64],WORD32 audio_object_type)812 VOID ixheaacd_cplx_synt_qmffilt(
813     WORD32 **qmf_real, WORD32 **qmf_imag, WORD32 split,
814     ia_sbr_scale_fact_struct *sbr_scale_factor, WORD16 *time_out,
815     ia_sbr_qmf_filter_bank_struct *qmf_bank, ia_ps_dec_struct *ptr_ps_dec,
816     FLAG active, FLAG low_pow_flag, ia_sbr_tables_struct *sbr_tables_ptr,
817     ixheaacd_misc_tables *pstr_common_tables, WORD32 ch_fac, FLAG drc_on,
818     WORD32 drc_sbr_factors[][64], WORD32 audio_object_type) {
819   WORD32 i;
820 
821   WORD32 code_scale_factor;
822   WORD32 scale_factor;
823   WORD32 out_scale_factor;
824   WORD32 low_band_scale_factor;
825   WORD32 high_band_scale_factor;
826   WORD16 *filter_states = qmf_bank->filter_states;
827   WORD32 **ptr_qmf_imag_temp;
828   WORD32 qmf_real2[2 * NO_SYNTHESIS_CHANNELS];
829 
830   WORD32 no_synthesis_channels = qmf_bank->no_channels;
831   WORD32 p1;
832 
833   WORD16 *fp1;
834   WORD16 *fp2;
835 
836   WORD32 sixty4 = NO_SYNTHESIS_CHANNELS;
837   WORD32 thirty2 = qmf_bank->no_channels;
838 
839   WORD16 *filter_coeff;
840   WORD32 num_time_slots = qmf_bank->num_time_slots;
841   WORD32 ixheaacd_drc_offset;
842   WORD32 ov_lb_scale = sbr_scale_factor->ov_lb_scale;
843   WORD32 lb_scale = sbr_scale_factor->lb_scale;
844   WORD32 st_syn_scale = sbr_scale_factor->st_syn_scale;
845   WORD32 ov_lb_shift, lb_shift, hb_shift;
846 
847   WORD32 *qmf_real_tmp = qmf_real2;
848   WORD32 *qmf_imag_tmp = &qmf_real2[NO_SYNTHESIS_CHANNELS];
849   WORD32 env = 0;
850 
851   WORD32 common_shift = 0;
852 
853   if (no_synthesis_channels == 32) {
854     qmf_bank->cos_twiddle =
855         (WORD16 *)sbr_tables_ptr->qmf_dec_tables_ptr->sbr_sin_cos_twiddle_l32;
856     qmf_bank->alt_sin_twiddle =
857         (WORD16 *)sbr_tables_ptr->qmf_dec_tables_ptr->sbr_alt_sin_twiddle_l32;
858     qmf_bank->t_cos =
859         (WORD16 *)
860             sbr_tables_ptr->qmf_dec_tables_ptr->sbr_cos_sin_twiddle_ds_l32;
861   } else {
862     qmf_bank->cos_twiddle =
863         (WORD16 *)sbr_tables_ptr->qmf_dec_tables_ptr->sbr_sin_cos_twiddle_l64;
864     qmf_bank->alt_sin_twiddle =
865         (WORD16 *)sbr_tables_ptr->qmf_dec_tables_ptr->sbr_alt_sin_twiddle_l64;
866   }
867   if (audio_object_type != AOT_ER_AAC_ELD &&
868       audio_object_type != AOT_ER_AAC_LD) {
869     qmf_bank->filter_pos_syn +=
870         (sbr_tables_ptr->qmf_dec_tables_ptr->qmf_c - qmf_bank->p_filter);
871     qmf_bank->p_filter = sbr_tables_ptr->qmf_dec_tables_ptr->qmf_c;
872   } else {
873     qmf_bank->filter_pos_syn +=
874         (sbr_tables_ptr->qmf_dec_tables_ptr->qmf_c_eld - qmf_bank->p_filter);
875     qmf_bank->p_filter = sbr_tables_ptr->qmf_dec_tables_ptr->qmf_c_eld;
876   }
877 
878   fp1 = &filter_states[0];
879   fp2 = fp1 + no_synthesis_channels;
880 
881   if (audio_object_type == AOT_ER_AAC_ELD ||
882       audio_object_type == AOT_ER_AAC_LD) {
883     fp1 = qmf_bank->fp1_syn;
884     fp2 = qmf_bank->fp2_syn;
885     sixty4 = qmf_bank->sixty4;
886   }
887 
888   filter_coeff = qmf_bank->filter_pos_syn;
889 
890   if (active) {
891     code_scale_factor = scale_factor = sbr_scale_factor->ps_scale;
892   } else {
893     code_scale_factor = ixheaacd_min32(lb_scale, ov_lb_scale);
894     scale_factor = sbr_scale_factor->hb_scale;
895   }
896 
897   low_band_scale_factor = (st_syn_scale - code_scale_factor);
898   high_band_scale_factor = (st_syn_scale - scale_factor);
899 
900   p1 = 0;
901 
902   if (low_pow_flag)
903 
904   {
905     ov_lb_shift = (st_syn_scale - ov_lb_scale) - 4;
906     lb_shift = (st_syn_scale - lb_scale) - 4;
907     hb_shift = high_band_scale_factor - 4;
908     out_scale_factor = -((sbr_scale_factor->st_syn_scale - 1));
909     ptr_qmf_imag_temp = 0;
910 
911   }
912 
913   else {
914     out_scale_factor = -((sbr_scale_factor->st_syn_scale - 3));
915     if (active) {
916       ov_lb_shift = (sbr_scale_factor->ps_scale - ov_lb_scale);
917       lb_shift = (sbr_scale_factor->ps_scale - lb_scale);
918       hb_shift = (sbr_scale_factor->ps_scale - sbr_scale_factor->hb_scale);
919       common_shift = low_band_scale_factor - 8;
920 
921     } else {
922       if (audio_object_type != AOT_ER_AAC_ELD &&
923           audio_object_type != AOT_ER_AAC_LD) {
924         ov_lb_shift = (st_syn_scale - ov_lb_scale) - 8;
925         lb_shift = (st_syn_scale - lb_scale) - 8;
926         hb_shift = high_band_scale_factor - 8;
927       } else {
928         ov_lb_shift = (st_syn_scale - ov_lb_scale) - 7;
929         lb_shift = (st_syn_scale - lb_scale) - 7;
930         hb_shift = high_band_scale_factor - 7;
931       }
932       common_shift = 0;
933     }
934     ptr_qmf_imag_temp = qmf_imag;
935   }
936 
937   {
938     if (ov_lb_shift == lb_shift) {
939       (*ixheaacd_adjust_scale)(qmf_real, ptr_qmf_imag_temp, 0, qmf_bank->lsb, 0,
940                                num_time_slots, ov_lb_shift, low_pow_flag);
941 
942     } else {
943       (*ixheaacd_adjust_scale)(qmf_real, ptr_qmf_imag_temp, 0, qmf_bank->lsb, 0,
944                                split, ov_lb_shift, low_pow_flag);
945 
946       (*ixheaacd_adjust_scale)(qmf_real, ptr_qmf_imag_temp, 0, qmf_bank->lsb,
947                                split, num_time_slots, lb_shift, low_pow_flag);
948     }
949 
950     (*ixheaacd_adjust_scale)(qmf_real, ptr_qmf_imag_temp, qmf_bank->lsb,
951                              qmf_bank->usb, 0, num_time_slots, hb_shift,
952                              low_pow_flag);
953   }
954 
955   ixheaacd_drc_offset = qmf_bank->ixheaacd_drc_offset;
956 
957   if (1 == drc_on) {
958     for (i = 0; i < num_time_slots; i++) {
959       WORD32 loop_val;
960       for (loop_val = 0; loop_val < 64; loop_val++) {
961         qmf_real[i][loop_val] = ixheaacd_mult32x32in32_shift25(
962             qmf_real[i][loop_val], drc_sbr_factors[6 + i][loop_val]);
963       }
964     }
965   }
966 
967   if (low_pow_flag)
968 
969   {
970     WORD16 *fptemp;
971 
972     VOID(*sbr_qmf_syn_winadd)
973     (WORD16 *, WORD16 *, WORD16 *, WORD16 *, FLAG, WORD32);
974     ia_qmf_dec_tables_struct *qmf_tab_ptr = sbr_tables_ptr->qmf_dec_tables_ptr;
975 
976     if (no_synthesis_channels == NO_SYNTHESIS_CHANNELS_DOWN_SAMPLED)
977       sbr_qmf_syn_winadd = ixheaacd_sbr_qmfsyn32_winadd;
978     else
979       sbr_qmf_syn_winadd = ixheaacd_sbr_qmfsyn64_winadd;
980 
981     for (i = 0; i < num_time_slots; i++) {
982       ixheaacd_inv_modulation_lp(qmf_real[i],
983                                  &filter_states[ixheaacd_drc_offset], qmf_bank,
984                                  qmf_tab_ptr);
985 
986       sbr_qmf_syn_winadd(fp1, fp2, filter_coeff, &time_out[ch_fac * p1], 2,
987                          ch_fac);
988 
989       ixheaacd_drc_offset -= no_synthesis_channels << 1;
990 
991       if (ixheaacd_drc_offset < 0)
992         ixheaacd_drc_offset += ((no_synthesis_channels << 1) * 10);
993 
994       fptemp = fp1;
995       fp1 = fp2;
996       fp2 = fptemp;
997 
998       filter_coeff += 64;
999 
1000       if (filter_coeff == qmf_bank->p_filter + 640)
1001         filter_coeff = (WORD16 *)qmf_bank->p_filter;
1002 
1003       p1 += no_synthesis_channels;
1004     }
1005 
1006   } else {
1007     for (i = 0; i < num_time_slots; i++) {
1008       WORD32 *t_qmf_imag;
1009       t_qmf_imag = qmf_imag[i];
1010 
1011       if (active) {
1012         if (i == ptr_ps_dec->border_position[env]) {
1013           ixheaacd_init_rot_env(ptr_ps_dec, (WORD16)env, qmf_bank->usb,
1014                                 sbr_tables_ptr, pstr_common_tables->trig_data);
1015           env++;
1016         }
1017 
1018         ixheaacd_apply_ps(ptr_ps_dec, &qmf_real[i], &qmf_imag[i], qmf_real_tmp,
1019                           qmf_imag_tmp, sbr_scale_factor, (WORD16)i,
1020                           sbr_tables_ptr, num_time_slots);
1021       }
1022       if (1 == drc_on) {
1023         WORD32 loop_val;
1024         for (loop_val = 0; loop_val < 64; loop_val++) {
1025           qmf_real[i][loop_val] = ixheaacd_mult32x32in32_shift25(
1026               qmf_real[i][loop_val], drc_sbr_factors[6 + i][loop_val]);
1027         }
1028       }
1029 
1030       if (active) {
1031         if (common_shift)
1032           ixheaacd_shiftrountine(qmf_real[i], t_qmf_imag, no_synthesis_channels,
1033                                  common_shift);
1034       }
1035 
1036       if (audio_object_type == AOT_ER_AAC_ELD ||
1037           audio_object_type == AOT_ER_AAC_LD)
1038         ixheaacd_sbr_pre_twiddle(
1039             qmf_real[i], t_qmf_imag,
1040             sbr_tables_ptr->qmf_dec_tables_ptr->ixheaacd_sbr_synth_cos_sin_l32);
1041 
1042       ixheaacd_inv_emodulation(qmf_real[i], qmf_bank,
1043                                sbr_tables_ptr->qmf_dec_tables_ptr);
1044 
1045       {
1046         WORD32 temp_out_scale_fac = out_scale_factor + 1;
1047         if (audio_object_type == AOT_ER_AAC_LD ||
1048             audio_object_type == AOT_ER_AAC_ELD) {
1049           temp_out_scale_fac = temp_out_scale_fac - 1;
1050 
1051           ixheaacd_shiftrountine_with_rnd_eld(
1052               qmf_real[i], t_qmf_imag, &filter_states[ixheaacd_drc_offset],
1053               no_synthesis_channels, temp_out_scale_fac);
1054 
1055         }
1056 
1057         else {
1058           ixheaacd_shiftrountine_with_rnd(
1059               qmf_real[i], t_qmf_imag, &filter_states[ixheaacd_drc_offset],
1060               no_synthesis_channels, temp_out_scale_fac);
1061         }
1062       }
1063 
1064       if (no_synthesis_channels == NO_SYNTHESIS_CHANNELS_DOWN_SAMPLED) {
1065         WORD32 temp = 1;
1066         if (audio_object_type == AOT_ER_AAC_LD ||
1067             audio_object_type == AOT_ER_AAC_ELD) {
1068           temp = 2;
1069         }
1070         ixheaacd_sbr_qmfsyn32_winadd(fp1, fp2, filter_coeff,
1071                                      &time_out[ch_fac * p1], temp, ch_fac);
1072 
1073         fp1 += thirty2;
1074         fp2 -= thirty2;
1075         thirty2 = -thirty2;
1076 
1077         ixheaacd_drc_offset -= 64;
1078 
1079         if (ixheaacd_drc_offset < 0) ixheaacd_drc_offset += 640;
1080 
1081       } else {
1082         WORD32 temp = 1;
1083         if (audio_object_type == AOT_ER_AAC_LD ||
1084             audio_object_type == AOT_ER_AAC_ELD) {
1085           temp = 2;
1086         }
1087         ixheaacd_sbr_qmfsyn64_winadd(fp1, fp2, filter_coeff,
1088                                      &time_out[ch_fac * p1], temp, ch_fac);
1089 
1090         fp1 += sixty4;
1091         fp2 -= sixty4;
1092         sixty4 = -sixty4;
1093         ixheaacd_drc_offset -= 128;
1094 
1095         if (ixheaacd_drc_offset < 0) ixheaacd_drc_offset += 1280;
1096       }
1097 
1098       filter_coeff += 64;
1099 
1100       if (filter_coeff == qmf_bank->p_filter + 640)
1101         filter_coeff = (WORD16 *)qmf_bank->p_filter;
1102 
1103       p1 += no_synthesis_channels;
1104 
1105       if (active)
1106         memcpy(qmf_real[i], qmf_real_tmp,
1107                2 * no_synthesis_channels * sizeof(WORD32));
1108     }
1109   }
1110 
1111   if (audio_object_type == AOT_ER_AAC_LD ||
1112       audio_object_type == AOT_ER_AAC_ELD) {
1113     qmf_bank->fp1_syn = fp1;
1114     qmf_bank->fp2_syn = fp2;
1115     qmf_bank->sixty4 = sixty4;
1116   }
1117 
1118   qmf_bank->filter_pos_syn = filter_coeff;
1119   qmf_bank->ixheaacd_drc_offset = ixheaacd_drc_offset;
1120 }
1121