xref: /aosp_15_r20/external/libxaac/decoder/ixheaacd_qmf_dec.c (revision 15dc779a375ca8b5125643b829a8aa4b70d7f451)
1 /******************************************************************************
2  *                                                                            *
3  * Copyright (C) 2018 The Android Open Source Project
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at:
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  *****************************************************************************
18  * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
19 */
20 #include <string.h>
21 
22 #include "ixheaacd_sbr_common.h"
23 #include "ixheaac_type_def.h"
24 
25 #include "ixheaac_constants.h"
26 #include "ixheaac_basic_ops32.h"
27 #include "ixheaac_basic_ops16.h"
28 #include "ixheaac_basic_ops40.h"
29 #include "ixheaac_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 "ixheaac_basic_op.h"
45 #include "ixheaacd_env_calc.h"
46 #include "ixheaacd_interface.h"
47 
48 #include "ixheaacd_function_selector.h"
49 #include "ixheaacd_audioobjtypes.h"
50 
51 #define DCT3_LEN (32)
52 #define DCT2_LEN (64)
53 
54 #define LP_SHIFT_VAL 7
55 #define HQ_SHIFT_64 4
56 #define RADIXSHIFT 1
57 #define ROUNDING_SPECTRA 1
58 #define HQ_SHIFT_VAL 4
59 
ixheaacd_mult32x32in32_shift25(WORD32 a,WORD32 b)60 static PLATFORM_INLINE WORD32 ixheaacd_mult32x32in32_shift25(WORD32 a,
61                                                              WORD32 b) {
62   WORD32 result;
63   WORD64 temp_result;
64 
65   temp_result = (WORD64)a * (WORD64)b;
66 
67   result = (WORD32)(temp_result >> 25);
68 
69   return (result);
70 }
71 
ixheaacd_pretwdct2(WORD32 * inp,WORD32 * out_fwd)72 VOID ixheaacd_pretwdct2(WORD32 *inp, WORD32 *out_fwd) {
73   WORD32 n;
74   WORD32 *out_rev = out_fwd + DCT2_LEN - 1;
75 
76   for (n = 0; n < DCT2_LEN / 2; n++) {
77     *out_fwd = *inp;
78     inp++;
79     *out_rev = *inp;
80     out_fwd++;
81 
82     out_rev--;
83     inp++;
84   }
85 
86   return;
87 }
88 
ixheaacd_pretwdct2_32(WORD32 * inp,WORD32 * out_fwd,int dct2_len)89 static PLATFORM_INLINE VOID ixheaacd_pretwdct2_32(WORD32 *inp, WORD32 *out_fwd,
90                                                   int dct2_len) {
91   WORD32 n;
92 
93   WORD32 *out_rev = out_fwd + dct2_len - 1;
94   for (n = dct2_len / 2 - 1; n >= 0; n--) {
95     *out_fwd = *inp;
96     inp++;
97     *out_rev = *inp;
98     out_fwd++;
99 
100     out_rev--;
101     inp++;
102   }
103 
104   return;
105 }
106 
ixheaacd_fftposttw(WORD32 * out,ia_qmf_dec_tables_struct * qmf_dec_tables_ptr)107 VOID ixheaacd_fftposttw(WORD32 *out,
108                         ia_qmf_dec_tables_struct *qmf_dec_tables_ptr) {
109   int k;
110   WORD32 *p_out_fwd, *ptr_out_rev;
111   const WORD16 *twidle_fwd, *twidle_rev;
112   WORD32 in1, in2, val1, val2;
113 
114   twidle_fwd = qmf_dec_tables_ptr->post_fft_tbl + 1;
115   twidle_rev = qmf_dec_tables_ptr->post_fft_tbl + 15;
116 
117   p_out_fwd = out;
118   ptr_out_rev = out + DCT2_LEN - 1;
119 
120   in1 = ((*p_out_fwd++) << 1);
121   val1 = ((*p_out_fwd--) << 1);
122 
123   *p_out_fwd++ = in1;
124   *p_out_fwd++ = val1;
125 
126   for (k = 1; k <= DCT2_LEN / 4; k++) {
127     WORD32 temp[4];
128     WORD16 twid_re, twid_im;
129 
130     temp[0] = *p_out_fwd++;
131     temp[1] = *p_out_fwd--;
132     temp[3] = *ptr_out_rev--;
133     temp[2] = *ptr_out_rev++;
134 
135     in2 = ixheaac_sub32_sat(temp[3], temp[1]);
136     in1 = ixheaac_add32_sat(temp[3], temp[1]);
137 
138     temp[1] = ixheaac_sub32_sat(temp[0], temp[2]);
139     temp[3] = ixheaac_add32_sat(temp[0], temp[2]);
140 
141     twid_re = *twidle_fwd++;
142     twid_im = *twidle_rev--;
143     val1 = ixheaac_mult32x16in32(in1, twid_re) -
144            ixheaac_mult32x16in32(temp[1], twid_im);
145     val2 = ixheaac_mult32x16in32(temp[1], twid_re) +
146            ixheaac_mult32x16in32(in1, twid_im);
147     val1 = val1 << 1;
148     val2 = val2 << 1;
149 
150     *p_out_fwd++ = ixheaac_add32_sat(temp[3], val1);
151     *p_out_fwd++ = ixheaac_add32_sat(in2, val2);
152 
153     *ptr_out_rev-- = ixheaac_sub32_sat(val2, in2);
154     *ptr_out_rev-- = ixheaac_sub32_sat(temp[3], val1);
155   }
156 
157   return;
158 }
159 
ixheaacd_posttwdct2(WORD32 * inp,WORD16 * out_fwd,ia_qmf_dec_tables_struct * qmf_dec_tables_ptr)160 VOID ixheaacd_posttwdct2(WORD32 *inp, WORD16 *out_fwd,
161                          ia_qmf_dec_tables_struct *qmf_dec_tables_ptr) {
162   WORD32 k;
163   WORD32 inp_re, inp_im, out_re, out_im, last_val, out_re1;
164   WORD16 *out_fwd2, *out_rev2, *out_rev;
165   WORD16 twid_re, twid_im;
166   const WORD16 *twidle_fwd;
167   WORD16 re1, im1, im2;
168 
169   out_rev = out_fwd + DCT2_LEN - 1;
170   out_rev2 = out_fwd - 1;
171   out_fwd2 = out_fwd + 65;
172   out_re = *inp++;
173   out_im = *inp++;
174   out_re1 =
175       ixheaac_sat64_32(ixheaac_add64((WORD64)out_re, (WORD64)out_im) >> 1);
176   re1 = ixheaac_round16(ixheaac_shl32(out_re1, (5 - 1)));
177 
178   *out_fwd++ = re1;
179 
180   last_val = ixheaac_sub32_sat(out_re, out_im);
181 
182   twidle_fwd = qmf_dec_tables_ptr->dct23_tw + 2;
183   for (k = DCT2_LEN / 2 - 2; k >= 0; k--) {
184     inp_re = *inp++;
185     inp_im = *inp++;
186 
187     twid_re = *twidle_fwd++;
188     twid_im = *twidle_fwd++;
189     out_re = ixheaac_sub32_sat(ixheaac_mult32x16in32(inp_re, twid_re),
190                                 ixheaac_mult32x16in32(inp_im, twid_im));
191     out_im = ixheaac_add32_sat(ixheaac_mult32x16in32(inp_im, twid_re),
192                                 ixheaac_mult32x16in32(inp_re, twid_im));
193     re1 = ixheaac_round16(ixheaac_shl32(out_re, (5 - 1)));
194     im1 = ixheaac_round16(ixheaac_shl32(out_im, (5 - 1)));
195     im2 = ixheaac_negate16(im1);
196 
197     *out_fwd++ = re1;
198     *out_rev2-- = re1;
199     *out_rev-- = im1;
200     *out_fwd2++ = im2;
201   }
202   twid_re = *twidle_fwd++;
203 
204   out_re = ixheaac_mult32x16in32(last_val, twid_re);
205   re1 = ixheaac_round16(ixheaac_shl32(out_re, (5 - 1)));
206 
207   *out_fwd++ = re1;
208   *out_rev2-- = re1;
209 
210   return;
211 }
212 
ixheaacd_fftposttw_32(WORD32 * out,int dct2_len,ia_qmf_dec_tables_struct * qmf_dec_tables_ptr)213 static PLATFORM_INLINE VOID ixheaacd_fftposttw_32(
214     WORD32 *out, int dct2_len, ia_qmf_dec_tables_struct *qmf_dec_tables_ptr) {
215   int k;
216   WORD32 *ptr_out_fwd, *ptr_out_rev;
217   const WORD16 *twidle_fwd, *twidle_rev;
218   WORD32 in1, in2, val1, val2;
219 
220   twidle_fwd = qmf_dec_tables_ptr->post_fft_tbl + 2;
221   twidle_rev = qmf_dec_tables_ptr->post_fft_tbl + 14;
222 
223   ptr_out_fwd = out;
224   ptr_out_rev = out + dct2_len - 1;
225 
226   in1 = ((*ptr_out_fwd++) << 1);
227   val1 = ((*ptr_out_fwd--) << 1);
228 
229   *ptr_out_fwd++ = in1;
230   *ptr_out_fwd++ = val1;
231 
232   for (k = dct2_len / 4 - 1; k >= 0; k--) {
233     WORD32 temp0, temp1, temp2, temp3;
234     WORD16 twid_re, twid_im;
235 
236     temp0 = *ptr_out_fwd++;
237     temp1 = *ptr_out_fwd--;
238     temp3 = *ptr_out_rev--;
239     temp2 = *ptr_out_rev++;
240 
241     in1 = ixheaac_add32_sat(temp1, temp3);
242     in2 = ixheaac_sub32_sat(temp3, temp1);
243 
244     temp1 = ixheaac_sub32_sat(temp0, temp2);
245     temp3 = ixheaac_add32_sat(temp0, temp2);
246 
247     twid_re = *twidle_fwd;
248     twidle_fwd += 2;
249 
250     twid_im = *twidle_rev;
251     twidle_rev -= 2;
252 
253     val1 = ixheaac_mult32x16in32(in1, twid_re) -
254            ixheaac_mult32x16in32(temp1, twid_im);
255     val2 = ixheaac_mult32x16in32(temp1, twid_re) +
256            ixheaac_mult32x16in32(in1, twid_im);
257 
258     val1 = val1 << 1;
259     val2 = val2 << 1;
260 
261     *ptr_out_fwd++ = ixheaac_add32_sat(temp3, val1);
262     *ptr_out_fwd++ = ixheaac_add32_sat(in2, val2);
263 
264     *ptr_out_rev-- = ixheaac_sub32_sat(val2, in2);
265     *ptr_out_rev-- = ixheaac_sub32_sat(temp3, val1);
266   }
267 
268   return;
269 }
270 
271 static PLATFORM_INLINE VOID
ixheaacd_posttwdct2_32(WORD32 * inp,WORD16 * out_fwd,ia_qmf_dec_tables_struct * qmf_dec_tables_ptr)272 ixheaacd_posttwdct2_32(WORD32 *inp, WORD16 *out_fwd,
273                        ia_qmf_dec_tables_struct *qmf_dec_tables_ptr) {
274   int k;
275   WORD32 inp_re, out_re, out_im, last_val, out_re1;
276   WORD16 *out_rev, *out_rev2, *out_fwd2;
277   WORD16 twid_re, twid_im;
278   const WORD16 *twidle_fwd;
279   WORD16 re1, im1, im2;
280   WORD32 rounding_fac = 0x8000;
281 
282   out_rev = out_fwd + 32 - 1;
283   out_rev2 = out_fwd - 1;
284   out_fwd2 = out_fwd + 32 + 1;
285   out_fwd[32] = 0;
286 
287   out_re = *inp++;
288   out_im = *inp++;
289 
290   out_re1 =
291       ixheaac_sat64_32(ixheaac_add64((WORD64)out_re, (WORD64)out_im) >> 1);
292   re1 = ixheaac_round16(ixheaac_shl32_sat(out_re1, (5 - 1)));
293   *out_fwd++ = re1;
294   last_val = ixheaac_sub32_sat(out_re, out_im);
295 
296   twidle_fwd = qmf_dec_tables_ptr->dct23_tw + 4;
297   for (k = 14; k >= 0; k--) {
298     WORD32 temp1, temp2;
299     inp_re = *inp++;
300     twid_re = *twidle_fwd++;
301     twid_im = *twidle_fwd;
302     twidle_fwd += 3;
303 
304     temp1 = ixheaac_mult32x16in32(inp_re, twid_re);
305     temp2 = ixheaac_mult32x16in32(inp_re, twid_im);
306 
307     inp_re = *inp++;
308 
309     out_re = ixheaac_sub32_sat(temp1, ixheaac_mult32x16in32(inp_re, twid_im));
310     out_im = ixheaac_add32_sat(ixheaac_mult32x16in32(inp_re, twid_re), temp2);
311 
312     out_re = ixheaac_add32_sat(out_re, out_re);
313     out_im = ixheaac_add32_sat(out_im, out_im);
314     out_re = ixheaac_add32_sat(out_re, out_re);
315     out_im = ixheaac_add32_sat(out_im, out_im);
316     out_re = ixheaac_add32_sat(out_re, out_re);
317     out_im = ixheaac_add32_sat(out_im, out_im);
318     out_re = ixheaac_add32_sat(out_re, out_re);
319     out_im = ixheaac_add32_sat(out_im, out_im);
320     out_re = ixheaac_add32_sat(out_re, rounding_fac);
321     out_im = ixheaac_add32_sat(out_im, rounding_fac);
322     re1 = (out_re >> 16);
323     im1 = (out_im >> 16);
324     im2 = ixheaac_negate16(im1);
325 
326     *out_fwd++ = re1;
327     *out_rev2-- = re1;
328     *out_rev-- = im1;
329     *out_fwd2++ = im2;
330   }
331   twid_re = *twidle_fwd++;
332 
333   out_re = ixheaac_mult32x16in32(last_val, twid_re);
334   re1 = ixheaac_round16(ixheaac_shl32_sat(out_re, (5 - 1)));
335   *out_fwd++ = re1;
336   *out_rev2-- = re1;
337 
338   return;
339 }
340 
ixheaacd_dct2_32(WORD32 * inp,WORD32 * out,ia_qmf_dec_tables_struct * qmf_dec_tables_ptr,WORD16 * filter_states)341 VOID ixheaacd_dct2_32(WORD32 *inp, WORD32 *out,
342                       ia_qmf_dec_tables_struct *qmf_dec_tables_ptr,
343                       WORD16 *filter_states) {
344   WORD32 *output;
345 
346   output = out + 16;
347   filter_states = filter_states + 16;
348   ixheaacd_pretwdct2_32(inp, output, 32);
349 
350   ixheaacd_radix4bfly(qmf_dec_tables_ptr->w_16, output, 1, 4);
351   ixheaacd_postradixcompute4(inp, output, qmf_dec_tables_ptr->dig_rev_table4_16,
352                              16);
353   ixheaacd_fftposttw_32(inp, 32, qmf_dec_tables_ptr);
354 
355   ixheaacd_posttwdct2_32(inp, filter_states, qmf_dec_tables_ptr);
356 
357   return;
358 }
359 
ixheaacd_sbr_qmfanal32_winadd_eld_mps(WORD32 * inp1,WORD32 * inp2,const WORD32 * p_qmf1,const WORD32 * p_qmf2,WORD32 * p_out)360 VOID ixheaacd_sbr_qmfanal32_winadd_eld_mps(WORD32 *inp1, WORD32 *inp2,
361                                            const WORD32 *p_qmf1,
362                                            const WORD32 *p_qmf2,
363                                            WORD32 *p_out) {
364   WORD32 n;
365   WORD32 resolution = 64;
366 
367   for (n = 0; n < 64; n += 2) {
368     WORD32 accu;
369     accu = ixheaac_mul32_sh(inp1[n + 0], p_qmf1[(n + 0)], 31);
370     accu = ixheaac_add32_sat(
371         accu, ixheaac_mul32_sh(inp1[n + 2 * resolution],
372                                 p_qmf1[(n + 2 * resolution)], 31));
373     accu = ixheaac_add32_sat(
374         accu, ixheaac_mul32_sh(inp1[n + 4 * resolution],
375                                 p_qmf1[(n + 4 * resolution)], 31));
376     accu = ixheaac_add32_sat(
377         accu, ixheaac_mul32_sh(inp1[n + 6 * resolution],
378                                 p_qmf1[(n + 6 * resolution)], 31));
379     accu = ixheaac_add32_sat(
380         accu, ixheaac_mul32_sh(inp1[n + 8 * resolution],
381                                 p_qmf1[(n + 8 * resolution)], 31));
382     p_out[n] = accu;
383 
384     accu = ixheaac_mul32_sh(inp1[n + 1 + 0], p_qmf1[(n + 1 + 0)], 31);
385     accu = ixheaac_add32_sat(
386         accu, ixheaac_mul32_sh(inp1[n + 1 + 2 * resolution],
387                                 p_qmf1[(n + 1 + 2 * resolution)], 31));
388     accu = ixheaac_add32_sat(
389         accu, ixheaac_mul32_sh(inp1[n + 1 + 4 * resolution],
390                                 p_qmf1[(n + 1 + 4 * resolution)], 31));
391     accu = ixheaac_add32_sat(
392         accu, ixheaac_mul32_sh(inp1[n + 1 + 6 * resolution],
393                                 p_qmf1[(n + 1 + 6 * resolution)], 31));
394     accu = ixheaac_add32_sat(
395         accu, ixheaac_mul32_sh(inp1[n + 1 + 8 * resolution],
396                                 p_qmf1[(n + 1 + 8 * resolution)], 31));
397     p_out[n + 1] = accu;
398 
399     accu = ixheaac_mul32_sh(inp2[n + 0], p_qmf2[(n + 0)], 31);
400     accu = ixheaac_add32_sat(
401         accu, ixheaac_mul32_sh(inp2[n + 2 * resolution],
402                                 p_qmf2[(n + 2 * resolution)], 31));
403     accu = ixheaac_add32_sat(
404         accu, ixheaac_mul32_sh(inp2[n + 4 * resolution],
405                                 p_qmf2[(n + 4 * resolution)], 31));
406     accu = ixheaac_add32_sat(
407         accu, ixheaac_mul32_sh(inp2[n + 6 * resolution],
408                                 p_qmf2[(n + 6 * resolution)], 31));
409     accu = ixheaac_add32_sat(
410         accu, ixheaac_mul32_sh(inp2[n + 8 * resolution],
411                                 p_qmf2[(n + 8 * resolution)], 31));
412     p_out[n + 64] = accu;
413 
414     accu = ixheaac_mul32_sh(inp2[n + 1 + 0], p_qmf2[(n + 1 + 0)], 31);
415     accu = ixheaac_add32_sat(
416         accu, ixheaac_mul32_sh(inp2[n + 1 + 2 * resolution],
417                                 p_qmf2[(n + 1 + 2 * resolution)], 31));
418     accu = ixheaac_add32_sat(
419         accu, ixheaac_mul32_sh(inp2[n + 1 + 4 * resolution],
420                                 p_qmf2[(n + 1 + 4 * resolution)], 31));
421     accu = ixheaac_add32_sat(
422         accu, ixheaac_mul32_sh(inp2[n + 1 + 6 * resolution],
423                                 p_qmf2[(n + 1 + 6 * resolution)], 31));
424     accu = ixheaac_add32_sat(
425         accu, ixheaac_mul32_sh(inp2[n + 1 + 8 * resolution],
426                                 p_qmf2[(n + 1 + 8 * resolution)], 31));
427     p_out[n + 1 + 64] = accu;
428   }
429 }
430 
ixheaacd_sbr_qmfanal32_winadd_eld_32(WORD32 * inp1,WORD32 * inp2,const WORD32 * p_qmf1,const WORD32 * p_qmf2,WORD32 * p_out)431 VOID ixheaacd_sbr_qmfanal32_winadd_eld_32(WORD32 *inp1, WORD32 *inp2,
432                                           const WORD32 *p_qmf1,
433                                           const WORD32 *p_qmf2, WORD32 *p_out) {
434   WORD32 n;
435 
436   for (n = 0; n < 32; n += 2) {
437     WORD32 accu;
438     accu = ixheaac_mul32_sh(inp1[n + 0], p_qmf1[(n + 0)], 31);
439     accu = ixheaac_add32_sat(
440         accu, ixheaac_mul32_sh(inp1[n + 64], p_qmf1[(n + 64)], 31));
441     accu = ixheaac_add32_sat(
442         accu, ixheaac_mul32_sh(inp1[n + 128], p_qmf1[(n + 128)], 31));
443     accu = ixheaac_add32_sat(
444         accu, ixheaac_mul32_sh(inp1[n + 192], p_qmf1[(n + 192)], 31));
445     accu = ixheaac_add32_sat(
446         accu, ixheaac_mul32_sh(inp1[n + 256], p_qmf1[(n + 256)], 31));
447     p_out[n] = accu;
448 
449     accu = ixheaac_mul32_sh(inp1[n + 1 + 0], p_qmf1[(n + 1 + 0)], 31);
450     accu = ixheaac_add32_sat(
451         accu, ixheaac_mul32_sh(inp1[n + 1 + 64], p_qmf1[(n + 1 + 64)], 31));
452     accu = ixheaac_add32_sat(
453         accu, ixheaac_mul32_sh(inp1[n + 1 + 128], p_qmf1[(n + 1 + 128)], 31));
454     accu = ixheaac_add32_sat(
455         accu, ixheaac_mul32_sh(inp1[n + 1 + 192], p_qmf1[(n + 1 + 192)], 31));
456     accu = ixheaac_add32_sat(
457         accu, ixheaac_mul32_sh(inp1[n + 1 + 256], p_qmf1[(n + 1 + 256)], 31));
458     p_out[n + 1] = accu;
459 
460     accu = ixheaac_mul32_sh(inp2[n + 0], p_qmf2[(n + 0)], 31);
461     accu = ixheaac_add32_sat(
462         accu, ixheaac_mul32_sh(inp2[n + 64], p_qmf2[(n + 64)], 31));
463     accu = ixheaac_add32_sat(
464         accu, ixheaac_mul32_sh(inp2[n + 128], p_qmf2[(n + 128)], 31));
465     accu = ixheaac_add32_sat(
466         accu, ixheaac_mul32_sh(inp2[n + 192], p_qmf2[(n + 192)], 31));
467     accu = ixheaac_add32_sat(
468         accu, ixheaac_mul32_sh(inp2[n + 256], p_qmf2[(n + 256)], 31));
469     p_out[n + 32] = accu;
470 
471     accu = ixheaac_mul32_sh(inp2[n + 1 + 0], p_qmf2[(n + 1 + 0)], 31);
472     accu = ixheaac_add32_sat(
473         accu, ixheaac_mul32_sh(inp2[n + 1 + 64], p_qmf2[(n + 1 + 64)], 31));
474     accu = ixheaac_add32_sat(
475         accu, ixheaac_mul32_sh(inp2[n + 1 + 128], p_qmf2[(n + 1 + 128)], 31));
476     accu = ixheaac_add32_sat(
477         accu, ixheaac_mul32_sh(inp2[n + 1 + 192], p_qmf2[(n + 1 + 192)], 31));
478     accu = ixheaac_add32_sat(
479         accu, ixheaac_mul32_sh(inp2[n + 1 + 256], p_qmf2[(n + 1 + 256)], 31));
480     p_out[n + 1 + 32] = accu;
481   }
482 }
483 
ixheaacd_sbr_qmfanal32_winadd_eld(WORD16 * inp1,WORD16 * inp2,const WORD16 * p_qmf1,const WORD16 * p_qmf2,WORD32 * p_out)484 VOID ixheaacd_sbr_qmfanal32_winadd_eld(WORD16 *inp1, WORD16 *inp2,
485                                        const WORD16 *p_qmf1,
486                                        const WORD16 *p_qmf2, WORD32 *p_out) {
487   WORD32 n;
488 
489   for (n = 0; n < 32; n += 2) {
490     WORD32 accu;
491     accu = ixheaac_mult16x16in32(inp1[n + 0], p_qmf1[(n + 0)]);
492     accu = ixheaac_add32_sat(
493         accu, ixheaac_mult16x16in32(inp1[n + 64], p_qmf1[(n + 64)]));
494     accu = ixheaac_add32_sat(
495         accu, ixheaac_mult16x16in32(inp1[n + 128], p_qmf1[(n + 128)]));
496     accu = ixheaac_add32_sat(
497         accu, ixheaac_mult16x16in32(inp1[n + 192], p_qmf1[(n + 192)]));
498     accu = ixheaac_add32_sat(
499         accu, ixheaac_mult16x16in32(inp1[n + 256], p_qmf1[(n + 256)]));
500     p_out[n] = accu;
501 
502     accu = ixheaac_mult16x16in32(inp1[n + 1 + 0], p_qmf1[(n + 1 + 0)]);
503     accu = ixheaac_add32_sat(
504         accu, ixheaac_mult16x16in32(inp1[n + 1 + 64], p_qmf1[(n + 1 + 64)]));
505     accu = ixheaac_add32_sat(
506         accu, ixheaac_mult16x16in32(inp1[n + 1 + 128], p_qmf1[(n + 1 + 128)]));
507     accu = ixheaac_add32_sat(
508         accu, ixheaac_mult16x16in32(inp1[n + 1 + 192], p_qmf1[(n + 1 + 192)]));
509     accu = ixheaac_add32_sat(
510         accu, ixheaac_mult16x16in32(inp1[n + 1 + 256], p_qmf1[(n + 1 + 256)]));
511     p_out[n + 1] = accu;
512 
513     accu = ixheaac_mult16x16in32(inp2[n + 0], p_qmf2[(n + 0)]);
514     accu = ixheaac_add32_sat(
515         accu, ixheaac_mult16x16in32(inp2[n + 64], p_qmf2[(n + 64)]));
516     accu = ixheaac_add32_sat(
517         accu, ixheaac_mult16x16in32(inp2[n + 128], p_qmf2[(n + 128)]));
518     accu = ixheaac_add32_sat(
519         accu, ixheaac_mult16x16in32(inp2[n + 192], p_qmf2[(n + 192)]));
520     accu = ixheaac_add32_sat(
521         accu, ixheaac_mult16x16in32(inp2[n + 256], p_qmf2[(n + 256)]));
522     p_out[n + 32] = accu;
523 
524     accu = ixheaac_mult16x16in32(inp2[n + 1 + 0], p_qmf2[(n + 1 + 0)]);
525     accu = ixheaac_add32_sat(
526         accu, ixheaac_mult16x16in32(inp2[n + 1 + 64], p_qmf2[(n + 1 + 64)]));
527     accu = ixheaac_add32_sat(
528         accu, ixheaac_mult16x16in32(inp2[n + 1 + 128], p_qmf2[(n + 1 + 128)]));
529     accu = ixheaac_add32_sat(
530         accu, ixheaac_mult16x16in32(inp2[n + 1 + 192], p_qmf2[(n + 1 + 192)]));
531     accu = ixheaac_add32_sat(
532         accu, ixheaac_mult16x16in32(inp2[n + 1 + 256], p_qmf2[(n + 1 + 256)]));
533     p_out[n + 1 + 32] = accu;
534   }
535 }
536 
ixheaacd_esbr_qmfanal32_winadd(WORD32 * inp1,WORD32 * inp2,WORD32 * p_qmf1,WORD32 * p_qmf2,WORD32 * p_out,WORD32 num_band_anal_qmf)537 VOID ixheaacd_esbr_qmfanal32_winadd(WORD32 *inp1, WORD32 *inp2, WORD32 *p_qmf1,
538                                     WORD32 *p_qmf2, WORD32 *p_out,
539                                     WORD32 num_band_anal_qmf) {
540   WORD32 n;
541   WORD64 accu;
542 
543   if (num_band_anal_qmf == 32) {
544     for (n = 0; n < num_band_anal_qmf; n += 2) {
545       accu = ixheaac_mult64(inp1[n + 0], p_qmf1[2 * (n + 0)]);
546       accu = ixheaac_add64(
547           accu, ixheaac_mult64(inp1[n + 2 * num_band_anal_qmf],
548                                 p_qmf1[2 * (n + 2 * num_band_anal_qmf)]));
549       accu = ixheaac_add64(
550           accu, ixheaac_mult64(inp1[n + 4 * num_band_anal_qmf],
551                                 p_qmf1[2 * (n + 4 * num_band_anal_qmf)]));
552       accu = ixheaac_add64(
553           accu, ixheaac_mult64(inp1[n + 6 * num_band_anal_qmf],
554                                 p_qmf1[2 * (n + 6 * num_band_anal_qmf)]));
555       accu = ixheaac_add64(
556           accu, ixheaac_mult64(inp1[n + 8 * num_band_anal_qmf],
557                                 p_qmf1[2 * (n + 8 * num_band_anal_qmf)]));
558       p_out[n] = (WORD32)(accu >> 31);
559 
560       accu = ixheaac_mult64(inp1[n + 1 + 0], p_qmf1[2 * (n + 1 + 0)]);
561       accu = ixheaac_add64(
562           accu, ixheaac_mult64(inp1[n + 1 + 2 * num_band_anal_qmf],
563                                 p_qmf1[2 * (n + 1 + 2 * num_band_anal_qmf)]));
564       accu = ixheaac_add64(
565           accu, ixheaac_mult64(inp1[n + 1 + 4 * num_band_anal_qmf],
566                                 p_qmf1[2 * (n + 1 + 4 * num_band_anal_qmf)]));
567       accu = ixheaac_add64(
568           accu, ixheaac_mult64(inp1[n + 1 + 6 * num_band_anal_qmf],
569                                 p_qmf1[2 * (n + 1 + 6 * num_band_anal_qmf)]));
570       accu = ixheaac_add64(
571           accu, ixheaac_mult64(inp1[n + 1 + 8 * num_band_anal_qmf],
572                                 p_qmf1[2 * (n + 1 + 8 * num_band_anal_qmf)]));
573       p_out[n + 1] = (WORD32)(accu >> 31);
574 
575       accu = ixheaac_mult64(inp2[n + 0], p_qmf2[2 * (n + 0)]);
576       accu = ixheaac_add64(
577           accu, ixheaac_mult64(inp2[n + 2 * num_band_anal_qmf],
578                                 p_qmf2[2 * (n + 2 * num_band_anal_qmf)]));
579       accu = ixheaac_add64(
580           accu, ixheaac_mult64(inp2[n + 4 * num_band_anal_qmf],
581                                 p_qmf2[2 * (n + 4 * num_band_anal_qmf)]));
582       accu = ixheaac_add64(
583           accu, ixheaac_mult64(inp2[n + 6 * num_band_anal_qmf],
584                                 p_qmf2[2 * (n + 6 * num_band_anal_qmf)]));
585       accu = ixheaac_add64(
586           accu, ixheaac_mult64(inp2[n + 8 * num_band_anal_qmf],
587                                 p_qmf2[2 * (n + 8 * num_band_anal_qmf)]));
588       p_out[n + num_band_anal_qmf] = (WORD32)(accu >> 31);
589 
590       accu = ixheaac_mult64(inp2[n + 1 + 0], p_qmf2[2 * (n + 1 + 0)]);
591       accu = ixheaac_add64(
592           accu, ixheaac_mult64(inp2[n + 1 + 2 * num_band_anal_qmf],
593                                 p_qmf2[2 * (n + 1 + 2 * num_band_anal_qmf)]));
594       accu = ixheaac_add64(
595           accu, ixheaac_mult64(inp2[n + 1 + 4 * num_band_anal_qmf],
596                                 p_qmf2[2 * (n + 1 + 4 * num_band_anal_qmf)]));
597       accu = ixheaac_add64(
598           accu, ixheaac_mult64(inp2[n + 1 + 6 * num_band_anal_qmf],
599                                 p_qmf2[2 * (n + 1 + 6 * num_band_anal_qmf)]));
600       accu = ixheaac_add64(
601           accu, ixheaac_mult64(inp2[n + 1 + 8 * num_band_anal_qmf],
602                                 p_qmf2[2 * (n + 1 + 8 * num_band_anal_qmf)]));
603       p_out[n + 1 + num_band_anal_qmf] = (WORD32)(accu >> 31);
604     }
605   } else if (num_band_anal_qmf == 24) {
606     for (n = 0; n < num_band_anal_qmf; n += 2) {
607       accu = ixheaac_mult64(inp1[n + 0], p_qmf1[(n + 0)]);
608       accu = ixheaac_add64(
609           accu, ixheaac_mult64(inp1[n + 2 * num_band_anal_qmf],
610                                 p_qmf1[(n + 2 * num_band_anal_qmf)]));
611       accu = ixheaac_add64(
612           accu, ixheaac_mult64(inp1[n + 4 * num_band_anal_qmf],
613                                 p_qmf1[(n + 4 * num_band_anal_qmf)]));
614       accu = ixheaac_add64(
615           accu, ixheaac_mult64(inp1[n + 6 * num_band_anal_qmf],
616                                 p_qmf1[(n + 6 * num_band_anal_qmf)]));
617       accu = ixheaac_add64(
618           accu, ixheaac_mult64(inp1[n + 8 * num_band_anal_qmf],
619                                 p_qmf1[(n + 8 * num_band_anal_qmf)]));
620       p_out[n] = (WORD32)(accu >> 31);
621 
622       accu = ixheaac_mult64(inp1[n + 1 + 0], p_qmf1[(n + 1 + 0)]);
623       accu = ixheaac_add64(
624           accu, ixheaac_mult64(inp1[n + 1 + 2 * num_band_anal_qmf],
625                                 p_qmf1[(n + 1 + 2 * num_band_anal_qmf)]));
626       accu = ixheaac_add64(
627           accu, ixheaac_mult64(inp1[n + 1 + 4 * num_band_anal_qmf],
628                                 p_qmf1[(n + 1 + 4 * num_band_anal_qmf)]));
629       accu = ixheaac_add64(
630           accu, ixheaac_mult64(inp1[n + 1 + 6 * num_band_anal_qmf],
631                                 p_qmf1[(n + 1 + 6 * num_band_anal_qmf)]));
632       accu = ixheaac_add64(
633           accu, ixheaac_mult64(inp1[n + 1 + 8 * num_band_anal_qmf],
634                                 p_qmf1[(n + 1 + 8 * num_band_anal_qmf)]));
635       p_out[n + 1] = (WORD32)(accu >> 31);
636 
637       accu = ixheaac_mult64(inp2[n + 0], p_qmf2[(n + 0)]);
638       accu = ixheaac_add64(
639           accu, ixheaac_mult64(inp2[n + 2 * num_band_anal_qmf],
640                                 p_qmf2[(n + 2 * num_band_anal_qmf)]));
641       accu = ixheaac_add64(
642           accu, ixheaac_mult64(inp2[n + 4 * num_band_anal_qmf],
643                                 p_qmf2[(n + 4 * num_band_anal_qmf)]));
644       accu = ixheaac_add64(
645           accu, ixheaac_mult64(inp2[n + 6 * num_band_anal_qmf],
646                                 p_qmf2[(n + 6 * num_band_anal_qmf)]));
647       accu = ixheaac_add64(
648           accu, ixheaac_mult64(inp2[n + 8 * num_band_anal_qmf],
649                                 p_qmf2[(n + 8 * num_band_anal_qmf)]));
650       p_out[n + num_band_anal_qmf] = (WORD32)(accu >> 31);
651 
652       accu = ixheaac_mult64(inp2[n + 1 + 0], p_qmf2[(n + 1 + 0)]);
653       accu = ixheaac_add64(
654           accu, ixheaac_mult64(inp2[n + 1 + 2 * num_band_anal_qmf],
655                                 p_qmf2[(n + 1 + 2 * num_band_anal_qmf)]));
656       accu = ixheaac_add64(
657           accu, ixheaac_mult64(inp2[n + 1 + 4 * num_band_anal_qmf],
658                                 p_qmf2[(n + 1 + 4 * num_band_anal_qmf)]));
659       accu = ixheaac_add64(
660           accu, ixheaac_mult64(inp2[n + 1 + 6 * num_band_anal_qmf],
661                                 p_qmf2[(n + 1 + 6 * num_band_anal_qmf)]));
662       accu = ixheaac_add64(
663           accu, ixheaac_mult64(inp2[n + 1 + 8 * num_band_anal_qmf],
664                                 p_qmf2[(n + 1 + 8 * num_band_anal_qmf)]));
665       p_out[n + 1 + num_band_anal_qmf] = (WORD32)(accu >> 31);
666     }
667 
668   } else {
669     for (n = 0; n < num_band_anal_qmf; n += 2) {
670       accu = ixheaac_mult64(inp1[n + 0], p_qmf1[4 * (n + 0)]);
671       accu = ixheaac_add64(
672           accu, ixheaac_mult64(inp1[n + 2 * num_band_anal_qmf],
673                                 p_qmf1[4 * (n + 2 * num_band_anal_qmf)]));
674       accu = ixheaac_add64(
675           accu, ixheaac_mult64(inp1[n + 4 * num_band_anal_qmf],
676                                 p_qmf1[4 * (n + 4 * num_band_anal_qmf)]));
677       accu = ixheaac_add64(
678           accu, ixheaac_mult64(inp1[n + 6 * num_band_anal_qmf],
679                                 p_qmf1[4 * (n + 6 * num_band_anal_qmf)]));
680       accu = ixheaac_add64(
681           accu, ixheaac_mult64(inp1[n + 8 * num_band_anal_qmf],
682                                 p_qmf1[4 * (n + 8 * num_band_anal_qmf)]));
683       p_out[n] = (WORD32)(accu >> 31);
684 
685       accu = ixheaac_mult64(inp1[n + 1 + 0], p_qmf1[4 * (n + 1 + 0)]);
686       accu = ixheaac_add64(
687           accu, ixheaac_mult64(inp1[n + 1 + 2 * num_band_anal_qmf],
688                                 p_qmf1[4 * (n + 1 + 2 * num_band_anal_qmf)]));
689       accu = ixheaac_add64(
690           accu, ixheaac_mult64(inp1[n + 1 + 4 * num_band_anal_qmf],
691                                 p_qmf1[4 * (n + 1 + 4 * num_band_anal_qmf)]));
692       accu = ixheaac_add64(
693           accu, ixheaac_mult64(inp1[n + 1 + 6 * num_band_anal_qmf],
694                                 p_qmf1[4 * (n + 1 + 6 * num_band_anal_qmf)]));
695       accu = ixheaac_add64(
696           accu, ixheaac_mult64(inp1[n + 1 + 8 * num_band_anal_qmf],
697                                 p_qmf1[4 * (n + 1 + 8 * num_band_anal_qmf)]));
698       p_out[n + 1] = (WORD32)(accu >> 31);
699 
700       accu = ixheaac_mult64(inp2[n + 0], p_qmf2[4 * (n + 0)]);
701       accu = ixheaac_add64(
702           accu, ixheaac_mult64(inp2[n + 2 * num_band_anal_qmf],
703                                 p_qmf2[4 * (n + 2 * num_band_anal_qmf)]));
704       accu = ixheaac_add64(
705           accu, ixheaac_mult64(inp2[n + 4 * num_band_anal_qmf],
706                                 p_qmf2[4 * (n + 4 * num_band_anal_qmf)]));
707       accu = ixheaac_add64(
708           accu, ixheaac_mult64(inp2[n + 6 * num_band_anal_qmf],
709                                 p_qmf2[4 * (n + 6 * num_band_anal_qmf)]));
710       accu = ixheaac_add64(
711           accu, ixheaac_mult64(inp2[n + 8 * num_band_anal_qmf],
712                                 p_qmf2[4 * (n + 8 * num_band_anal_qmf)]));
713       p_out[n + num_band_anal_qmf] = (WORD32)(accu >> 31);
714 
715       accu = ixheaac_mult64(inp2[n + 1 + 0], p_qmf2[4 * (n + 1 + 0)]);
716       accu = ixheaac_add64(
717           accu, ixheaac_mult64(inp2[n + 1 + 2 * num_band_anal_qmf],
718                                 p_qmf2[4 * (n + 1 + 2 * num_band_anal_qmf)]));
719       accu = ixheaac_add64(
720           accu, ixheaac_mult64(inp2[n + 1 + 4 * num_band_anal_qmf],
721                                 p_qmf2[4 * (n + 1 + 4 * num_band_anal_qmf)]));
722       accu = ixheaac_add64(
723           accu, ixheaac_mult64(inp2[n + 1 + 6 * num_band_anal_qmf],
724                                 p_qmf2[4 * (n + 1 + 6 * num_band_anal_qmf)]));
725       accu = ixheaac_add64(
726           accu, ixheaac_mult64(inp2[n + 1 + 8 * num_band_anal_qmf],
727                                 p_qmf2[4 * (n + 1 + 8 * num_band_anal_qmf)]));
728       p_out[n + 1 + num_band_anal_qmf] = (WORD32)(accu >> 31);
729     }
730   }
731 }
732 
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)733 VOID ixheaacd_esbr_inv_modulation(
734     WORD32 *qmf_real, ia_sbr_qmf_filter_bank_struct *syn_qmf,
735     ia_qmf_dec_tables_struct *qmf_dec_tables_ptr, WORD32 no_synthesis_channels) {
736 
737     if (no_synthesis_channels == NO_SYNTHESIS_CHANNELS_DOWN_SAMPLED)
738     {
739       ixheaacd_esbr_cos_sin_mod(qmf_real, syn_qmf, qmf_dec_tables_ptr->esbr_w_16,
740         qmf_dec_tables_ptr->dig_rev_table4_16);
741     }
742     else
743     {
744       ixheaacd_esbr_cos_sin_mod(qmf_real, syn_qmf, qmf_dec_tables_ptr->esbr_w_32,
745         qmf_dec_tables_ptr->dig_rev_table2_32);
746     }
747 }
748 
ixheaacd_sbr_qmfsyn32_winadd(WORD16 * tmp1,WORD16 * tmp2,WORD16 * inp1,WORD16 * sample_buffer,FLAG shift,WORD32 ch_fac)749 VOID ixheaacd_sbr_qmfsyn32_winadd(WORD16 *tmp1, WORD16 *tmp2, WORD16 *inp1,
750                                   WORD16 *sample_buffer, FLAG shift,
751                                   WORD32 ch_fac) {
752   WORD32 k;
753   WORD32 rounding_fac = 0x8000;
754   rounding_fac = rounding_fac >> shift;
755 
756   for (k = 0; k < 32; k++) {
757     WORD32 syn_out = rounding_fac;
758 
759     syn_out = ixheaac_add32(
760         syn_out, ixheaac_mult16x16in32(tmp1[0 + k], inp1[2 * (k + 0)]));
761     syn_out = ixheaac_add32(
762         syn_out, ixheaac_mult16x16in32(tmp1[128 + k], inp1[2 * (k + 64)]));
763     syn_out = ixheaac_add32(
764         syn_out, ixheaac_mult16x16in32(tmp1[256 + k], inp1[2 * (k + 128)]));
765     syn_out = ixheaac_add32(
766         syn_out, ixheaac_mult16x16in32(tmp1[384 + k], inp1[2 * (k + 192)]));
767     syn_out = ixheaac_add32(
768         syn_out, ixheaac_mult16x16in32(tmp1[512 + k], inp1[2 * (k + 256)]));
769 
770     syn_out = ixheaac_add32(
771         syn_out, ixheaac_mult16x16in32(tmp2[64 + k], inp1[2 * (k + 32)]));
772     syn_out = ixheaac_add32(
773         syn_out, ixheaac_mult16x16in32(tmp2[192 + k], inp1[2 * (k + 96)]));
774     syn_out = ixheaac_add32(
775         syn_out, ixheaac_mult16x16in32(tmp2[320 + k], inp1[2 * (k + 160)]));
776     syn_out = ixheaac_add32(
777         syn_out, ixheaac_mult16x16in32(tmp2[448 + k], inp1[2 * (k + 224)]));
778     syn_out = ixheaac_add32(
779         syn_out, ixheaac_mult16x16in32(tmp2[576 + k], inp1[2 * (k + 288)]));
780     syn_out = ixheaac_add32_sat(syn_out, syn_out);
781     if (shift == 2) {
782       syn_out = ixheaac_add32_sat(syn_out, syn_out);
783     }
784     sample_buffer[ch_fac * k] = (syn_out >> 16);
785   }
786 }
787 
ixheaacd_sbr_pre_twiddle(WORD32 * p_xre,WORD32 * p_xim,WORD16 * p_twiddles)788 void ixheaacd_sbr_pre_twiddle(WORD32 *p_xre, WORD32 *p_xim,
789                               WORD16 *p_twiddles) {
790   int k;
791 
792   for (k = 62; k >= 0; k--) {
793     WORD32 x_re = *p_xre;
794     WORD32 x_im = *p_xim;
795 
796     WORD16 ixheaacd_cosine = *p_twiddles++;
797     WORD16 ixheaacd_sine = *p_twiddles++;
798 
799     WORD32 re, im;
800 
801     re = ixheaac_mac32x16in32_shl_sat(
802         ixheaac_mult32x16in32_shl(x_re, ixheaacd_cosine), x_im, ixheaacd_sine);
803     im = ixheaac_sub32_sat(ixheaac_mult32x16in32_shl(x_im, ixheaacd_cosine),
804                             ixheaac_mult32x16in32_shl(x_re, ixheaacd_sine));
805 
806     *p_xre++ = re;
807     *p_xim++ = im;
808   }
809 }
810 
ixheaacd_cplx_synt_qmffilt(WORD32 ** qmf_real,WORD32 ** qmf_imag,WORD32 split,WORD32 * qmf_real_out[MAX_ENV_COLS],WORD32 * qmf_imag_out[MAX_ENV_COLS],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)811 VOID ixheaacd_cplx_synt_qmffilt(
812     WORD32 **qmf_real, WORD32 **qmf_imag, WORD32 split,
813     WORD32 *qmf_real_out[MAX_ENV_COLS], WORD32 *qmf_imag_out[MAX_ENV_COLS],
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, j;
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 = ixheaac_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   for (i = 0; i < num_time_slots; i++)
967   {
968     for (j = 0; j < no_synthesis_channels; j++)
969     {
970       qmf_real_out[i][j] = qmf_real[i][j];
971       if (!low_pow_flag)
972       {
973         qmf_imag_out[i][j] = qmf_imag[i][j];
974       }
975     }
976   }
977   if (low_pow_flag)
978   {
979     WORD16 *fptemp;
980 
981     VOID(*sbr_qmf_syn_winadd)
982     (WORD16 *, WORD16 *, WORD16 *, WORD16 *, FLAG, WORD32);
983     ia_qmf_dec_tables_struct *qmf_tab_ptr = sbr_tables_ptr->qmf_dec_tables_ptr;
984 
985     if (no_synthesis_channels == NO_SYNTHESIS_CHANNELS_DOWN_SAMPLED)
986       sbr_qmf_syn_winadd = ixheaacd_sbr_qmfsyn32_winadd;
987     else
988       sbr_qmf_syn_winadd = ixheaacd_sbr_qmfsyn64_winadd;
989 
990     for (i = 0; i < num_time_slots; i++) {
991       ixheaacd_inv_modulation_lp(qmf_real[i],
992                                  &filter_states[ixheaacd_drc_offset], qmf_bank,
993                                  qmf_tab_ptr);
994 
995       sbr_qmf_syn_winadd(fp1, fp2, filter_coeff, &time_out[ch_fac * p1], 2,
996                          ch_fac);
997 
998       ixheaacd_drc_offset -= no_synthesis_channels << 1;
999 
1000       if (ixheaacd_drc_offset < 0)
1001         ixheaacd_drc_offset += ((no_synthesis_channels << 1) * 10);
1002 
1003       fptemp = fp1;
1004       fp1 = fp2;
1005       fp2 = fptemp;
1006 
1007       filter_coeff += 64;
1008 
1009       if (filter_coeff == qmf_bank->p_filter + 640)
1010         filter_coeff = (WORD16 *)qmf_bank->p_filter;
1011 
1012       p1 += no_synthesis_channels;
1013     }
1014 
1015   } else {
1016     for (i = 0; i < num_time_slots; i++) {
1017       WORD32 *t_qmf_imag;
1018       t_qmf_imag = qmf_imag[i];
1019 
1020       if (active) {
1021         if (i == ptr_ps_dec->border_position[env]) {
1022           ixheaacd_init_rot_env(ptr_ps_dec, (WORD16)env, qmf_bank->usb,
1023                                 sbr_tables_ptr, pstr_common_tables->trig_data);
1024           env++;
1025         }
1026 
1027         ixheaacd_apply_ps(ptr_ps_dec, &qmf_real[i], &qmf_imag[i], qmf_real_tmp,
1028                           qmf_imag_tmp, sbr_scale_factor, (WORD16)i,
1029                           sbr_tables_ptr, num_time_slots);
1030       }
1031       if (1 == drc_on) {
1032         WORD32 loop_val;
1033         for (loop_val = 0; loop_val < 64; loop_val++) {
1034           qmf_real[i][loop_val] = ixheaacd_mult32x32in32_shift25(
1035               qmf_real[i][loop_val], drc_sbr_factors[6 + i][loop_val]);
1036         }
1037       }
1038 
1039       if (active) {
1040         if (common_shift)
1041           ixheaacd_shiftrountine(qmf_real[i], t_qmf_imag, no_synthesis_channels,
1042                                  common_shift);
1043       }
1044 
1045       if (audio_object_type == AOT_ER_AAC_ELD ||
1046           audio_object_type == AOT_ER_AAC_LD)
1047         ixheaacd_sbr_pre_twiddle(
1048             qmf_real[i], t_qmf_imag,
1049             sbr_tables_ptr->qmf_dec_tables_ptr->ixheaacd_sbr_synth_cos_sin_l32);
1050 
1051       ixheaacd_inv_emodulation(qmf_real[i], qmf_bank,
1052                                sbr_tables_ptr->qmf_dec_tables_ptr);
1053 
1054       {
1055         WORD32 temp_out_scale_fac = out_scale_factor + 1;
1056         if (audio_object_type == AOT_ER_AAC_LD ||
1057             audio_object_type == AOT_ER_AAC_ELD) {
1058           temp_out_scale_fac = temp_out_scale_fac - 1;
1059 
1060           ixheaacd_shiftrountine_with_rnd_eld(
1061               qmf_real[i], t_qmf_imag, &filter_states[ixheaacd_drc_offset],
1062               no_synthesis_channels, temp_out_scale_fac);
1063 
1064         }
1065 
1066         else {
1067           ixheaacd_shiftrountine_with_rnd(
1068               qmf_real[i], t_qmf_imag, &filter_states[ixheaacd_drc_offset],
1069               no_synthesis_channels, temp_out_scale_fac);
1070         }
1071       }
1072 
1073       if (no_synthesis_channels == NO_SYNTHESIS_CHANNELS_DOWN_SAMPLED) {
1074         WORD32 temp = 1;
1075         if (audio_object_type == AOT_ER_AAC_LD ||
1076             audio_object_type == AOT_ER_AAC_ELD) {
1077           temp = 2;
1078         }
1079         ixheaacd_sbr_qmfsyn32_winadd(fp1, fp2, filter_coeff,
1080                                      &time_out[ch_fac * p1], temp, ch_fac);
1081 
1082         fp1 += thirty2;
1083         fp2 -= thirty2;
1084         thirty2 = -thirty2;
1085 
1086         ixheaacd_drc_offset -= 64;
1087 
1088         if (ixheaacd_drc_offset < 0) ixheaacd_drc_offset += 640;
1089 
1090       } else {
1091         WORD32 temp = 1;
1092         if (audio_object_type == AOT_ER_AAC_LD ||
1093             audio_object_type == AOT_ER_AAC_ELD) {
1094           temp = 2;
1095         }
1096         ixheaacd_sbr_qmfsyn64_winadd(fp1, fp2, filter_coeff,
1097                                      &time_out[ch_fac * p1], temp, ch_fac);
1098 
1099         fp1 += sixty4;
1100         fp2 -= sixty4;
1101         sixty4 = -sixty4;
1102         ixheaacd_drc_offset -= 128;
1103 
1104         if (ixheaacd_drc_offset < 0) ixheaacd_drc_offset += 1280;
1105       }
1106 
1107       filter_coeff += 64;
1108 
1109       if (filter_coeff == qmf_bank->p_filter + 640)
1110         filter_coeff = (WORD16 *)qmf_bank->p_filter;
1111 
1112       p1 += no_synthesis_channels;
1113 
1114       if (active)
1115         memcpy(qmf_real[i], qmf_real_tmp,
1116                2 * no_synthesis_channels * sizeof(WORD32));
1117     }
1118   }
1119 
1120   if (audio_object_type == AOT_ER_AAC_LD ||
1121       audio_object_type == AOT_ER_AAC_ELD) {
1122     qmf_bank->fp1_syn = fp1;
1123     qmf_bank->fp2_syn = fp2;
1124     qmf_bank->sixty4 = sixty4;
1125   }
1126 
1127   qmf_bank->filter_pos_syn = filter_coeff;
1128   qmf_bank->ixheaacd_drc_offset = ixheaacd_drc_offset;
1129 }
1130