• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /******************************************************************************
2  *                                                                            *
3  * Copyright (C) 2018 The Android Open Source Project
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at:
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  *****************************************************************************
18  * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
19 */
20 #include <string.h>
21 #include "ixheaacd_sbr_common.h"
22 #include <ixheaacd_type_def.h>
23 
24 #include "ixheaacd_constants.h"
25 #include <ixheaacd_basic_ops32.h>
26 #include <ixheaacd_basic_ops16.h>
27 #include <ixheaacd_basic_ops40.h>
28 #include "ixheaacd_basic_ops.h"
29 #include "ixheaacd_bitbuffer.h"
30 
31 #include <ixheaacd_basic_op.h>
32 #include "ixheaacd_intrinsics.h"
33 
34 #include "ixheaacd_defines.h"
35 
36 #include <ixheaacd_aac_rom.h>
37 
38 #include "ixheaacd_definitions.h"
39 
40 #include "ixheaacd_error_codes.h"
41 
42 #include "ixheaacd_pulsedata.h"
43 
44 #include "ixheaacd_pns.h"
45 #include "ixheaacd_drc_data_struct.h"
46 
47 #include "ixheaacd_lt_predict.h"
48 #include "ixheaacd_channelinfo.h"
49 #include "ixheaacd_cnst.h"
50 #include "ixheaacd_drc_dec.h"
51 
52 #include "ixheaacd_sbrdecoder.h"
53 
54 #include "ixheaacd_block.h"
55 #include "ixheaacd_channel.h"
56 
57 #include "ixheaacd_sbr_payload.h"
58 #include "ixheaacd_common_rom.h"
59 
60 #include <ixheaacd_type_def.h>
61 
62 #include "ixheaacd_sbrdecsettings.h"
63 #include "ixheaacd_sbr_scale.h"
64 #include "ixheaacd_env_extr_part.h"
65 #include <ixheaacd_sbr_rom.h>
66 
67 #include "ixheaacd_lpp_tran.h"
68 #include "ixheaacd_hybrid.h"
69 #include "ixheaacd_ps_dec.h"
70 
71 #include "ixheaacd_env_extr.h"
72 #include "ixheaacd_adts.h"
73 #include "ixheaacd_audioobjtypes.h"
74 #include "ixheaacd_memory_standards.h"
75 
76 #include "ixheaacd_latmdemux.h"
77 
78 #include "ixheaacd_aacdec.h"
79 #include "ixheaacd_mps_polyphase.h"
80 #include "ixheaacd_config.h"
81 #include "ixheaacd_mps_dec.h"
82 
83 #include "ixheaacd_struct_def.h"
84 
85 #include "ixheaacd_tns.h"
86 #include "ixheaacd_aac_imdct.h"
87 
88 #include "ixheaacd_multichannel.h"
89 #include "ixheaacd_function_selector.h"
90 
ixheaacd_shr32_drc(WORD32 a,WORD32 b)91 static PLATFORM_INLINE WORD32 ixheaacd_shr32_drc(WORD32 a, WORD32 b) {
92   WORD32 out_val;
93 
94   b = ((UWORD32)(b << 24) >> 24);
95   if (b >= 31) {
96     if (a < 0)
97       out_val = -1;
98     else
99       out_val = 0;
100   } else {
101     a = ixheaacd_add32_sat(a, (1 << (b - 1)));
102     out_val = (WORD32)a >> b;
103   }
104 
105   return out_val;
106 }
107 
ixheaacd_mult32x16in32_drc(WORD32 a,WORD16 b)108 static PLATFORM_INLINE WORD32 ixheaacd_mult32x16in32_drc(WORD32 a, WORD16 b) {
109   WORD32 result;
110   WORD64 temp_result;
111 
112   temp_result = (WORD64)a * (WORD64)b;
113 
114   if (temp_result < (WORD64)MIN_32)
115     result = MIN_32;
116 
117   else if (temp_result > (WORD64)MAX_32)
118     result = MAX_32;
119 
120   else
121     result = (WORD32)(temp_result);
122 
123   return (result);
124 }
125 
ixheaacd_process_win_seq(WORD32 * coef,WORD32 * prev,WORD16 * out,const WORD16 * window_long,const WORD16 * window_short,WORD16 q_shift,WORD16 ch_fac,WORD16 flag)126 VOID ixheaacd_process_win_seq(WORD32 *coef, WORD32 *prev, WORD16 *out,
127                               const WORD16 *window_long,
128                               const WORD16 *window_short, WORD16 q_shift,
129                               WORD16 ch_fac, WORD16 flag) {
130   WORD32 i, accu;
131   WORD32 *coef_1;
132   const WORD16 *temp_win_sh, *temp_win_long;
133   WORD16 *out1, *out2;
134   WORD32 *temp_prev;
135 
136   if (flag == 1) {
137     for (i = 0; i < SIZE07; i++) {
138       WORD32 temp1 = ixheaacd_shl32_dir_sat_limit(
139           ixheaacd_mult32x16in32(coef[SIZE08 + i], window_long[2 * i]),
140           (q_shift + 1));
141 
142       accu = ixheaacd_add32_sat(temp1, ((WORD32)prev[i] << 16));
143       out[ch_fac * i] = ixheaacd_round16(accu << 1);
144 
145       accu = ixheaacd_shl32_dir_sat_limit(
146           ixheaacd_mult32x16in32(-(coef[SIZE15 - 1 - i]),
147                                  window_long[2 * (SIZE07 - i) - 1]),
148           q_shift);
149       out[ch_fac * (i + SIZE09)] = ixheaacd_round16(accu << 2);
150     }
151 
152     temp_win_sh = &(window_short[0]);
153     coef_1 = &(coef[SIZE15]);
154     temp_win_long = &(window_long[SIZE14]);
155     temp_prev = &(prev[SIZE08 - 1]);
156     out1 = &(out[ch_fac * (SIZE07)]);
157     out2 = &(out[ch_fac * (SIZE09 - 1)]);
158 
159   } else {
160     for (i = 0; i < SIZE07; i++) {
161       accu = ixheaacd_mult32x16in32_drc(
162           prev[SIZE08 - 1 - i], ixheaacd_negate16(window_long[2 * i + 1]));
163 
164       out[ch_fac * i] = ixheaacd_round16(accu << 2);
165 
166       accu = ixheaacd_sub32_sat(
167           ixheaacd_shl32_dir_sat_limit(-(coef[SIZE15 - 1 - i]), (q_shift - 1)),
168           ixheaacd_mult32x16in32_drc(prev[i + SIZE01],
169                                      window_long[2 * SIZE07 - 2 - 2 * i]));
170 
171       out[ch_fac * (SIZE09 + i)] = ixheaacd_round16(accu << 2);
172     }
173 
174     temp_win_sh = &(window_long[SIZE14]);
175     coef_1 = &(coef[SIZE15]);
176     temp_win_long = &(window_short[0]);
177     temp_prev = &(prev[SIZE01 - 1]);
178     out1 = &(out[ch_fac * (SIZE07)]);
179     out2 = &(out[ch_fac * (SIZE09 - 1)]);
180   }
181 
182   for (i = SIZE01 - 1; i >= 0; i--) {
183     WORD32 temp_coef = *coef_1++;
184     WORD16 win1 = *temp_win_long++;
185     WORD16 win2 = *temp_win_long++;
186     WORD32 prev1 = *temp_prev--;
187     WORD16 win4 = *temp_win_sh++;
188     WORD16 win3 = *temp_win_sh++;
189     accu = ixheaacd_sub32_sat(
190         ixheaacd_shl32_dir_sat_limit(ixheaacd_mult32x16in32(temp_coef, win1),
191                                      q_shift),
192         ixheaacd_mult32x16in32_drc(prev1, win3));
193     *out1 = ixheaacd_round16(accu << 2);
194     out1 += ch_fac;
195 
196     accu = ixheaacd_sub32_sat(
197         ixheaacd_shl32_dir_sat_limit(
198             ixheaacd_mult32x16in32(ixheaacd_negate32_sat(temp_coef), win2),
199             q_shift),
200         ixheaacd_mult32x16in32_drc(prev1, win4));
201     *out2 = ixheaacd_round16(accu << 2);
202     out2 -= ch_fac;
203   }
204 }
205 
ixheaacd_long_short_win_process(WORD32 * current,WORD32 * prev,WORD16 * out,const WORD16 * short_window,const WORD16 * long_window_prev,WORD16 q_shift,WORD16 ch_fac,WORD32 flag)206 static PLATFORM_INLINE VOID ixheaacd_long_short_win_process(
207     WORD32 *current, WORD32 *prev, WORD16 *out, const WORD16 *short_window,
208     const WORD16 *long_window_prev, WORD16 q_shift, WORD16 ch_fac,
209     WORD32 flag) {
210   WORD i;
211   WORD32 accu;
212   WORD32 *current_tmp1 = &(current[(SIZE03 - 1)]);
213   WORD32 *current_tmp2 = &(current[-SIZE01]);
214   const WORD16 *short_ptr = &(short_window[SIZE02 - 1]);
215 
216   for (i = SIZE01 - 1; i >= 0; i--) {
217     WORD32 tmp1_cur = *current_tmp1--;
218     WORD32 tmp2_cur = *current_tmp2++;
219     WORD16 short1 = *short_ptr--;
220     WORD16 short2 = *short_ptr--;
221     accu = ixheaacd_sub32_sat(
222         ixheaacd_shl32_dir_sat_limit((ixheaacd_mult32x16in32(tmp1_cur, short2) -
223                                       ixheaacd_mult32x16in32(tmp2_cur, short1)),
224                                      q_shift),
225         ixheaacd_mult32x16in32_drc(prev[i], long_window_prev[0 - 2 - 2 * i]));
226     out[ch_fac * (0 + i)] = ixheaacd_round16(accu << 2);
227 
228     if (flag) {
229       accu = ixheaacd_sub32_sat(
230           ixheaacd_shl32_dir_sat_limit(
231               (ixheaacd_mult32x16in32(-(tmp1_cur), short1) -
232                ixheaacd_mult32x16in32(tmp2_cur, short2)),
233               q_shift),
234           ixheaacd_mult32x16in32_drc(prev[SIZE02 - 1 - i],
235                                      long_window_prev[-2 * SIZE02 + 2 * i]));
236       out[ch_fac * (SIZE02 - 1 - i)] = ixheaacd_round16(accu << 2);
237     }
238   }
239 }
240 
ixheaacd_long_short_win_seq(WORD32 * current,WORD32 * prev,WORD16 * out,const WORD16 * short_window,const WORD16 * short_window_prev,const WORD16 * long_window_prev,WORD16 q_shift,WORD16 ch_fac)241 VOID ixheaacd_long_short_win_seq(WORD32 *current, WORD32 *prev, WORD16 *out,
242                                  const WORD16 *short_window,
243                                  const WORD16 *short_window_prev,
244                                  const WORD16 *long_window_prev, WORD16 q_shift,
245                                  WORD16 ch_fac) {
246   WORD32 i, flag;
247   WORD32 accu;
248   for (i = 0; i < SIZE07; i++) {
249     accu = ixheaacd_mult32x16in32_drc(
250         prev[SIZE08 - 1 - i], ixheaacd_negate16(long_window_prev[2 * i + 1]));
251     out[ch_fac * i] = ixheaacd_round16(accu << 2);
252   }
253 
254   for (i = 0; i < SIZE01; i++) {
255     accu = ixheaacd_sub32_sat(
256         ixheaacd_shl32_dir_sat_limit(
257             ixheaacd_mult32x16in32(current[SIZE01 + i],
258                                    short_window_prev[2 * i]),
259             q_shift),
260         ixheaacd_mult32x16in32_drc(prev[SIZE01 - 1 - i],
261                                    long_window_prev[2 * SIZE07 + 1 + 2 * i]));
262     out[ch_fac * (SIZE07 + i)] = ixheaacd_round16(accu << 2);
263   }
264 
265   for (i = 0; i < SIZE01; i++) {
266     accu = ixheaacd_sub32_sat(
267         ixheaacd_shl32_dir_sat_limit(
268             ixheaacd_mult32x16in32(-(current[SIZE02 - 1 - i]),
269                                    short_window_prev[SIZE02 - 2 * i - 1]),
270             q_shift),
271         ixheaacd_mult32x16in32_drc(prev[i],
272                                    long_window_prev[SIZE16 - 2 - (2 * i)]));
273     out[ch_fac * (SIZE08 + i)] = ixheaacd_round16(accu << 2);
274   }
275 
276   flag = 1;
277   for (i = 0; i < 4; i++) {
278     WORD32 inc = i * SIZE02;
279 
280     if (i == 3) {
281       flag = 0;
282     }
283 
284     ixheaacd_long_short_win_process(&current[SIZE01 + inc], &prev[SIZE01 + inc],
285                                     &out[ch_fac * (SIZE09 + inc)], short_window,
286                                     &long_window_prev[2 * (SIZE07 - inc)],
287                                     q_shift, ch_fac, flag);
288   }
289 
290   for (i = 0; i < SIZE01; i++) {
291     accu = (ixheaacd_mult32x16in32(-(current[SIZE10 - 1 - i]),
292                                    short_window[SIZE02 - 2 * i - 1]) -
293             ixheaacd_mult32x16in32(current[SIZE06 + i],
294                                    short_window[SIZE02 - 2 * i - 2]));
295     prev[i] =
296         ixheaacd_round16(ixheaacd_shl32_dir_sat_limit(accu, (q_shift + 1)));
297   }
298 }
299 
ixheaacd_nolap1_32(WORD32 * coef,WORD32 * out,WORD16 q_shift,WORD16 ch_fac)300 VOID ixheaacd_nolap1_32(WORD32 *coef,
301 
302                         WORD32 *out,
303 
304                         WORD16 q_shift, WORD16 ch_fac) {
305   WORD32 i;
306 
307   for (i = 0; i < SIZE07; i++) {
308     out[ch_fac * i] = ixheaacd_shr32_drc(
309         ixheaacd_negate32_sat(coef[SIZE07 - 1 - i]), 16 - q_shift);
310   }
311 }
312 
ixheaacd_neg_shift_spec_dec(WORD32 * coef,WORD16 * out,WORD16 q_shift,WORD16 ch_fac)313 VOID ixheaacd_neg_shift_spec_dec(WORD32 *coef, WORD16 *out, WORD16 q_shift,
314                                  WORD16 ch_fac) {
315   WORD32 i;
316 
317   for (i = 0; i < SIZE07; i++) {
318     out[ch_fac * i] = ixheaacd_round16(ixheaacd_shl32_dir_sat_limit(
319         ixheaacd_negate32_sat(coef[SIZE07 - 1 - i]), q_shift));
320   }
321 }
322 
ixheaacd_spec_to_overlapbuf_dec(WORD32 * ptr_overlap_buf,WORD32 * ptr_spec_coeff,WORD32 q_shift,WORD32 size)323 VOID ixheaacd_spec_to_overlapbuf_dec(WORD32 *ptr_overlap_buf,
324                                      WORD32 *ptr_spec_coeff, WORD32 q_shift,
325                                      WORD32 size) {
326   WORD32 i;
327   for (i = 0; i < size; i++) {
328     ptr_overlap_buf[i] = ixheaacd_shr32_drc(ptr_spec_coeff[i], 16 - q_shift);
329   }
330 }
331 
ixheaacd_overlap_buf_out_dec(WORD16 * out_samples,WORD32 * ptr_overlap_buf,WORD32 size,const WORD16 ch_fac)332 VOID ixheaacd_overlap_buf_out_dec(WORD16 *out_samples, WORD32 *ptr_overlap_buf,
333                                   WORD32 size, const WORD16 ch_fac) {
334   WORD32 i;
335 
336   for (i = 0; i < size; i++) {
337     out_samples[ch_fac * i] = ixheaacd_shl16_sat((WORD16)ptr_overlap_buf[i], 1);
338   }
339 }
340 
ixheaacd_overlap_out_copy_dec(WORD16 * out_samples,WORD32 * ptr_overlap_buf,WORD32 * ptr_overlap_buf1,const WORD16 ch_fac)341 VOID ixheaacd_overlap_out_copy_dec(WORD16 *out_samples, WORD32 *ptr_overlap_buf,
342                                    WORD32 *ptr_overlap_buf1,
343                                    const WORD16 ch_fac) {
344   WORD32 i;
345 
346   for (i = 0; i < SIZE01; i++) {
347     out_samples[ch_fac * i] = ixheaacd_shl16_sat((WORD16)ptr_overlap_buf[i], 1);
348     ptr_overlap_buf[i] = ptr_overlap_buf1[i];
349   }
350 }
351 
ixheaacd_imdct_process(ia_aac_dec_overlap_info * ptr_aac_dec_overlap_info,WORD32 * ptr_spec_coeff,ia_ics_info_struct * ptr_ics_info,WORD16 out_samples[],const WORD16 ch_fac,WORD32 * scratch,ia_aac_dec_tables_struct * ptr_aac_tables,WORD32 object_type)352 VOID ixheaacd_imdct_process(ia_aac_dec_overlap_info *ptr_aac_dec_overlap_info,
353                             WORD32 *ptr_spec_coeff,
354                             ia_ics_info_struct *ptr_ics_info,
355                             WORD16 out_samples[], const WORD16 ch_fac,
356                             WORD32 *scratch,
357                             ia_aac_dec_tables_struct *ptr_aac_tables,
358                             WORD32 object_type) {
359   WORD32 *ptr_overlap_buf;
360   const WORD16 *ptr_long_window;
361   const WORD16 *ptr_short_window;
362 
363   ptr_overlap_buf = ptr_aac_dec_overlap_info->ptr_overlap_buf;
364   ptr_long_window =
365       ptr_aac_dec_overlap_info
366           ->ptr_long_window[(WORD32)ptr_aac_dec_overlap_info->window_shape];
367   ptr_short_window =
368       ptr_aac_dec_overlap_info
369           ->ptr_short_window[(WORD32)ptr_aac_dec_overlap_info->window_shape];
370 
371   if (ptr_ics_info->window_sequence != EIGHT_SHORT_SEQUENCE) {
372     WORD16 q_shift;
373     WORD32 expo, imdct_scale;
374 
375     if ((512 == ptr_ics_info->frame_length) ||
376         (480 == ptr_ics_info->frame_length)) {
377       if (512 == ptr_ics_info->frame_length) {
378         WORD32 *ld_cos_sin_ptr =
379             (WORD32 *)ptr_aac_tables->pstr_imdct_tables->cosine_array_1024;
380 
381         ixheaacd_inverse_transform_512(
382             ptr_spec_coeff, scratch, &imdct_scale, ld_cos_sin_ptr,
383             ptr_aac_tables->pstr_imdct_tables, object_type);
384 
385       } else {
386         ixheaacd_mdct_480_ld(ptr_spec_coeff, scratch, &imdct_scale, 0,
387                              ptr_aac_tables->pstr_imdct_tables, object_type);
388       }
389 
390       if (object_type == AOT_ER_AAC_ELD) {
391         int i, N = (ptr_ics_info->frame_length << 1);
392 
393         for (i = 0; i < N / 2; i++) {
394           ptr_spec_coeff[i] = -ptr_spec_coeff[i + N];
395           ptr_spec_coeff[i + N + N / 2] = -ptr_spec_coeff[i + N / 2];
396         }
397       }
398     } else
399 
400     {
401       expo = (*ixheaacd_calc_max_spectral_line)(ptr_spec_coeff, 1024) - 1;
402 
403       expo = 8 - expo;
404 
405       imdct_scale = ixheaacd_inverse_transform(
406           ptr_spec_coeff, scratch, ptr_aac_tables->pstr_imdct_tables, expo,
407           1024);
408     }
409 
410     q_shift = (31 + imdct_scale) + (-1 - 16 - 9);
411 
412     switch (ptr_ics_info->window_sequence) {
413       case ONLY_LONG_SEQUENCE:
414 
415         switch (ptr_aac_dec_overlap_info->window_sequence) {
416           case ONLY_LONG_SEQUENCE:
417           case LONG_STOP_SEQUENCE:
418 
419             if (1024 == ptr_ics_info->frame_length) {
420               ia_ics_info_struct *tmp_ptr_ics_info = ptr_ics_info;
421               (*ixheaacd_post_twid_overlap_add)(
422                   out_samples, ptr_spec_coeff,
423                   ptr_aac_tables->pstr_imdct_tables, 1024, ptr_overlap_buf,
424                   q_shift, ptr_long_window, ch_fac);
425               ptr_ics_info = tmp_ptr_ics_info;
426             }
427             if ((512 == ptr_ics_info->frame_length) ||
428                 (480 == ptr_ics_info->frame_length)) {
429               if (object_type != AOT_ER_AAC_ELD) {
430                 if (512 == ptr_ics_info->frame_length) {
431                   ixheaacd_lap1_512_480(ptr_spec_coeff, ptr_overlap_buf,
432                                         out_samples, ptr_long_window, q_shift,
433                                         SIZE04, ch_fac);
434                   ixheaacd_spec_to_overlapbuf(ptr_overlap_buf, ptr_spec_coeff,
435                                               q_shift, SIZE04);
436                 } else if (480 == ptr_ics_info->frame_length) {
437                   ixheaacd_lap1_512_480(ptr_spec_coeff, ptr_overlap_buf,
438                                         out_samples, ptr_long_window, q_shift,
439                                         240, ch_fac);
440                   ixheaacd_spec_to_overlapbuf(ptr_overlap_buf, ptr_spec_coeff,
441                                               q_shift, 240);
442                 }
443               } else {
444                 ixheaacd_eld_dec_windowing(
445                     ptr_spec_coeff, ptr_long_window, ptr_ics_info->frame_length,
446                     q_shift, ptr_overlap_buf, ch_fac, out_samples);
447               }
448             }
449             break;
450 
451           case LONG_START_SEQUENCE:
452           case EIGHT_SHORT_SEQUENCE:
453             if (1024 == ptr_ics_info->frame_length) {
454               (*ixheaacd_post_twiddle)(scratch, ptr_spec_coeff,
455                                        ptr_aac_tables->pstr_imdct_tables, 1024);
456             }
457 
458             ixheaacd_process_win_seq(scratch, ptr_overlap_buf, out_samples,
459                                      ptr_long_window, ptr_short_window, q_shift,
460                                      ch_fac, 1);
461 
462             if (512 == ptr_ics_info->frame_length) {
463               ixheaacd_spec_to_overlapbuf(ptr_overlap_buf, ptr_spec_coeff,
464                                           q_shift, SIZE04);
465             } else if (480 == ptr_ics_info->frame_length) {
466               ixheaacd_spec_to_overlapbuf(ptr_overlap_buf, ptr_spec_coeff,
467                                           q_shift, 240);
468             } else {
469               (*ixheaacd_spec_to_overlapbuf)(ptr_overlap_buf, scratch, q_shift,
470                                              SIZE08);
471             }
472             break;
473         }
474 
475         break;
476 
477       case LONG_START_SEQUENCE:
478         if (1024 == ptr_ics_info->frame_length) {
479           (*ixheaacd_post_twiddle)(scratch, ptr_spec_coeff,
480                                    ptr_aac_tables->pstr_imdct_tables, 1024);
481         }
482         switch (ptr_aac_dec_overlap_info->window_sequence) {
483           case ONLY_LONG_SEQUENCE:
484           case LONG_STOP_SEQUENCE:
485 
486             (*ixheaacd_over_lap_add1)(scratch, ptr_overlap_buf, out_samples,
487                                       ptr_long_window, q_shift, SIZE08, ch_fac);
488 
489             break;
490 
491           case LONG_START_SEQUENCE:
492           case EIGHT_SHORT_SEQUENCE:
493 
494             ixheaacd_process_win_seq(scratch, ptr_overlap_buf, out_samples,
495                                      ptr_long_window, ptr_short_window, q_shift,
496                                      ch_fac, 1);
497 
498             break;
499         }
500 
501         ixheaacd_nolap1_32(&scratch[SIZE01], ptr_overlap_buf, q_shift, 1);
502 
503         (*ixheaacd_spec_to_overlapbuf)(&ptr_overlap_buf[SIZE07], scratch,
504                                        q_shift, SIZE01);
505 
506         break;
507 
508       case LONG_STOP_SEQUENCE:
509         if (1024 == ptr_ics_info->frame_length) {
510           (*ixheaacd_post_twiddle)(scratch, ptr_spec_coeff,
511                                    ptr_aac_tables->pstr_imdct_tables, 1024);
512         }
513 
514         switch (ptr_aac_dec_overlap_info->window_sequence) {
515           case EIGHT_SHORT_SEQUENCE:
516           case LONG_START_SEQUENCE:
517 
518             (*ixheaacd_overlap_buf_out)(out_samples, ptr_overlap_buf, SIZE07,
519                                         ch_fac);
520 
521             (*ixheaacd_over_lap_add1)(
522                 &scratch[SIZE14], &ptr_overlap_buf[SIZE07],
523                 &out_samples[ch_fac * (SIZE07)], ptr_short_window, q_shift,
524                 SIZE01, ch_fac);
525 
526             {
527               WORD16 q_shift1 = q_shift + 1;
528               (*ixheaacd_neg_shift_spec)(&scratch[SIZE08],
529                                          &out_samples[ch_fac * SIZE09],
530                                          q_shift1, ch_fac);
531             }
532 
533             break;
534           case ONLY_LONG_SEQUENCE:
535           case LONG_STOP_SEQUENCE:
536 
537             ixheaacd_process_win_seq(scratch, ptr_overlap_buf, out_samples,
538                                      ptr_long_window, ptr_short_window, q_shift,
539                                      ch_fac, 0);
540             break;
541         }
542 
543         (*ixheaacd_spec_to_overlapbuf)(ptr_overlap_buf, scratch, q_shift,
544                                        SIZE08);
545 
546         break;
547     }
548 
549   } else {
550     WORD16 q_shift, max_scale;
551     WORD32 imdct_scale[8], i;
552     const WORD16 *short_window;
553 
554     short_window = ptr_aac_dec_overlap_info
555                        ->ptr_short_window[(WORD32)ptr_ics_info->window_shape];
556 
557     {
558       WORD32 expo;
559 
560       expo = (*ixheaacd_calc_max_spectral_line)(ptr_spec_coeff, 1024) - 1;
561 
562       expo = 5 - expo;
563 
564       for (i = 0; i < MAX_WINDOWS; i++) {
565         imdct_scale[i] = ixheaacd_inverse_transform(
566             &ptr_spec_coeff[i * SIZE02], &scratch[i * SIZE02],
567             ptr_aac_tables->pstr_imdct_tables, expo, 128);
568 
569         (*ixheaacd_post_twiddle)(&scratch[i * SIZE02],
570                                  &ptr_spec_coeff[i * SIZE02],
571                                  ptr_aac_tables->pstr_imdct_tables, 128);
572       }
573     }
574 
575     max_scale = 31 + imdct_scale[0];
576 
577     q_shift = max_scale + (-16 - 6 - 1);
578 
579     switch (ptr_aac_dec_overlap_info->window_sequence) {
580       WORD32 overlap_buf_loc[SIZE01];
581 
582       case EIGHT_SHORT_SEQUENCE:
583       case LONG_START_SEQUENCE:
584 
585         (*ixheaacd_overlap_buf_out)(out_samples, ptr_overlap_buf, SIZE07,
586                                     ch_fac);
587 
588         (*ixheaacd_over_lap_add1)(&scratch[0], &ptr_overlap_buf[SIZE07],
589                                   &out_samples[ch_fac * SIZE07],
590                                   ptr_short_window, q_shift, SIZE01, ch_fac);
591 
592         for (i = 0; i < 3; i++) {
593           WORD32 inc = (i * SIZE02);
594           (*ixheaacd_spec_to_overlapbuf)(overlap_buf_loc, &scratch[inc],
595                                          q_shift, SIZE01);
596 
597           (*ixheaacd_over_lap_add1)(&scratch[SIZE02 + inc], overlap_buf_loc,
598                                     &out_samples[ch_fac * (SIZE09 + inc)],
599                                     short_window, q_shift, SIZE01, ch_fac);
600         }
601 
602         (*ixheaacd_over_lap_add2)(&scratch[SIZE08], &scratch[SIZE06],
603                                   ptr_overlap_buf, short_window, q_shift,
604                                   SIZE01, 1);
605 
606         (*ixheaacd_overlap_out_copy)(&out_samples[ch_fac * SIZE15],
607                                      ptr_overlap_buf, &ptr_overlap_buf[SIZE01],
608                                      ch_fac);
609 
610         break;
611 
612       case ONLY_LONG_SEQUENCE:
613       case LONG_STOP_SEQUENCE:
614 
615         ixheaacd_long_short_win_seq(scratch, ptr_overlap_buf, out_samples,
616                                     short_window, ptr_short_window,
617                                     ptr_long_window, q_shift, ch_fac);
618 
619         break;
620     }
621 
622     for (i = 0; i < 3; i++) {
623       WORD32 inc = (i * SIZE02);
624       (*ixheaacd_over_lap_add2)(&scratch[SIZE10 + inc], &scratch[SIZE08 + inc],
625                                 &ptr_overlap_buf[SIZE01 + inc], short_window,
626                                 q_shift, SIZE01, 1);
627     }
628 
629     (*ixheaacd_spec_to_overlapbuf)(&ptr_overlap_buf[SIZE07], &scratch[SIZE14],
630                                    q_shift, SIZE01);
631   }
632 
633   ptr_aac_dec_overlap_info->window_shape = ptr_ics_info->window_shape;
634   ptr_aac_dec_overlap_info->window_sequence = ptr_ics_info->window_sequence;
635 }
ixheaacd_eld_dec_windowing(WORD32 * ptr_spect_coeff,const WORD16 * p_win,WORD32 framesize,WORD16 q_shift,WORD32 * p_overlap_buffer,const WORD16 stride,WORD16 * out_samples)636 void ixheaacd_eld_dec_windowing(WORD32 *ptr_spect_coeff, const WORD16 *p_win,
637                                 WORD32 framesize, WORD16 q_shift,
638                                 WORD32 *p_overlap_buffer, const WORD16 stride,
639                                 WORD16 *out_samples)
640 
641 {
642   int i = 0;
643   int loop_size;
644   WORD32 *ptr_z = ptr_spect_coeff;
645 
646   WORD32 *ptr_out, *p_out2;
647   WORD32 *p_overlap_buffer32 = (WORD32 *)p_overlap_buffer;
648   WORD32 delay = framesize >> 2;
649 
650   ptr_z = ptr_spect_coeff + delay;
651   p_win += delay;
652   ptr_out = p_overlap_buffer32;
653 
654   q_shift = q_shift + 2;
655 
656   if (q_shift >= 0) {
657     for (i = (delay)-1; i >= 0; i--) {
658       WORD32 win_op;
659       WORD32 win_ovadd_op;
660       WORD16 win_val;
661 
662       win_val = *p_win++;
663 
664       win_op = ixheaacd_mult32x16in32(*ptr_z++, (win_val));
665 
666       win_ovadd_op =
667           ixheaacd_add32_sat(ixheaacd_shl32(win_op, q_shift), *ptr_out++);
668 
669       *out_samples = ixheaacd_round16(ixheaacd_shl32_sat(win_ovadd_op, 1));
670       out_samples += stride;
671 
672       win_val = *p_win++;
673 
674       win_op = ixheaacd_mult32x16in32(*ptr_z++, (win_val));
675 
676       win_ovadd_op =
677           ixheaacd_add32_sat(ixheaacd_shl32(win_op, q_shift), *ptr_out++);
678 
679       *out_samples = ixheaacd_round16(ixheaacd_shl32_sat(win_ovadd_op, 1));
680       out_samples += stride;
681       win_val = *p_win++;
682 
683       win_op = ixheaacd_mult32x16in32(*ptr_z++, (win_val));
684 
685       win_ovadd_op =
686           ixheaacd_add32_sat(ixheaacd_shl32(win_op, q_shift), *ptr_out++);
687 
688       *out_samples = ixheaacd_round16(ixheaacd_shl32_sat(win_ovadd_op, 1));
689       out_samples += stride;
690 
691       win_val = *p_win++;
692 
693       win_op = ixheaacd_mult32x16in32(*ptr_z++, (win_val));
694 
695       win_ovadd_op =
696           ixheaacd_add32_sat(ixheaacd_shl32(win_op, q_shift), *ptr_out++);
697 
698       *out_samples = ixheaacd_round16(ixheaacd_shl32_sat(win_ovadd_op, 1));
699       out_samples += stride;
700     }
701 
702     p_out2 = p_overlap_buffer32;
703     loop_size = (((framesize * 3) - framesize) >> 2) - 1;
704 
705     for (i = loop_size; i >= 0; i--) {
706       WORD32 win_op;
707       WORD16 win_val;
708       win_val = *p_win++;
709       win_op = ixheaacd_mult32x16in32(*ptr_z++, (win_val));
710       *p_out2++ =
711           ixheaacd_add32_sat(ixheaacd_shl32(win_op, q_shift), *ptr_out++);
712 
713       win_val = *p_win++;
714       win_op = ixheaacd_mult32x16in32(*ptr_z++, (win_val));
715       *p_out2++ =
716           ixheaacd_add32_sat(ixheaacd_shl32(win_op, q_shift), *ptr_out++);
717 
718       win_val = *p_win++;
719       win_op = ixheaacd_mult32x16in32(*ptr_z++, (win_val));
720       *p_out2++ =
721           ixheaacd_add32_sat(ixheaacd_shl32(win_op, q_shift), *ptr_out++);
722 
723       win_val = *p_win++;
724       win_op = ixheaacd_mult32x16in32(*ptr_z++, (win_val));
725       *p_out2++ =
726           ixheaacd_add32_sat(ixheaacd_shl32(win_op, q_shift), *ptr_out++);
727     }
728 
729     loop_size = ((((framesize << 2) - delay) - (framesize * 3)) >> 2) - 1;
730     for (i = loop_size; i >= 0; i--) {
731       WORD32 win_op;
732       WORD16 win_val;
733 
734       win_val = *p_win++;
735       win_op = ixheaacd_mult32x16in32(*ptr_z++, (win_val));
736       *p_out2++ = ixheaacd_shl32(win_op, q_shift);
737 
738       win_val = *p_win++;
739       win_op = ixheaacd_mult32x16in32(*ptr_z++, (win_val));
740       *p_out2++ = ixheaacd_shl32(win_op, q_shift);
741 
742       win_val = *p_win++;
743       win_op = ixheaacd_mult32x16in32(*ptr_z++, (win_val));
744       *p_out2++ = ixheaacd_shl32(win_op, q_shift);
745 
746       win_val = *p_win++;
747       win_op = ixheaacd_mult32x16in32(*ptr_z++, (win_val));
748       *p_out2++ = ixheaacd_shl32(win_op, q_shift);
749     }
750   } else {
751     q_shift = -q_shift;
752 
753     for (i = (delay)-1; i >= 0; i--) {
754       WORD32 win_op;
755       WORD32 win_ovadd_op;
756       WORD16 win_val;
757 
758       win_val = *p_win++;
759       win_op = ixheaacd_mult32x16in32(*ptr_z++, (win_val));
760 
761       win_ovadd_op =
762           ixheaacd_add32_sat(ixheaacd_shr32(win_op, q_shift), *ptr_out++);
763 
764       *out_samples = ixheaacd_round16(ixheaacd_shl32(win_ovadd_op, 1));
765       out_samples += stride;
766 
767       win_val = *p_win++;
768       win_op = ixheaacd_mult32x16in32(*ptr_z++, (win_val));
769 
770       win_ovadd_op =
771           ixheaacd_add32_sat(ixheaacd_shr32(win_op, q_shift), *ptr_out++);
772 
773       *out_samples = ixheaacd_round16(ixheaacd_shl32(win_ovadd_op, 1));
774       out_samples += stride;
775 
776       win_val = *p_win++;
777       win_op = ixheaacd_mult32x16in32(*ptr_z++, (win_val));
778 
779       win_ovadd_op =
780           ixheaacd_add32_sat(ixheaacd_shr32(win_op, q_shift), *ptr_out++);
781 
782       *out_samples = ixheaacd_round16(ixheaacd_shl32(win_ovadd_op, 1));
783       out_samples += stride;
784 
785       win_val = *p_win++;
786       win_op = ixheaacd_mult32x16in32(*ptr_z++, (win_val));
787 
788       win_ovadd_op =
789           ixheaacd_add32_sat(ixheaacd_shr32(win_op, q_shift), *ptr_out++);
790 
791       *out_samples = ixheaacd_round16(ixheaacd_shl32(win_ovadd_op, 1));
792       out_samples += stride;
793     }
794 
795     p_out2 = p_overlap_buffer32;
796     loop_size = (((framesize * 3) - framesize) >> 2) - 1;
797 
798     for (i = loop_size; i >= 0; i--) {
799       WORD32 win_op;
800       WORD16 win_val;
801       win_val = *p_win++;
802       win_op = ixheaacd_mult32x16in32(*ptr_z++, (win_val));
803       *p_out2++ =
804           ixheaacd_add32_sat(ixheaacd_shr32(win_op, q_shift), *ptr_out++);
805 
806       win_val = *p_win++;
807       win_op = ixheaacd_mult32x16in32(*ptr_z++, (win_val));
808       *p_out2++ =
809           ixheaacd_add32_sat(ixheaacd_shr32(win_op, q_shift), *ptr_out++);
810 
811       win_val = *p_win++;
812       win_op = ixheaacd_mult32x16in32(*ptr_z++, (win_val));
813       *p_out2++ =
814           ixheaacd_add32_sat(ixheaacd_shr32(win_op, q_shift), *ptr_out++);
815 
816       win_val = *p_win++;
817       win_op = ixheaacd_mult32x16in32(*ptr_z++, (win_val));
818       *p_out2++ =
819           ixheaacd_add32_sat(ixheaacd_shr32(win_op, q_shift), *ptr_out++);
820     }
821     loop_size = ((((framesize << 2) - delay) - (framesize * 3)) >> 2) - 1;
822     for (i = loop_size; i >= 0; i--) {
823       WORD32 win_op;
824       WORD16 win_val;
825       win_val = *p_win++;
826       win_op = ixheaacd_mult32x16in32(*ptr_z++, (win_val));
827       *p_out2++ = ixheaacd_shr32(win_op, q_shift);
828 
829       win_val = *p_win++;
830       win_op = ixheaacd_mult32x16in32(*ptr_z++, (win_val));
831       *p_out2++ = ixheaacd_shr32(win_op, q_shift);
832 
833       win_val = *p_win++;
834       win_op = ixheaacd_mult32x16in32(*ptr_z++, (win_val));
835       *p_out2++ = ixheaacd_shr32(win_op, q_shift);
836 
837       win_val = *p_win++;
838       win_op = ixheaacd_mult32x16in32(*ptr_z++, (win_val));
839       *p_out2++ = ixheaacd_shr32(win_op, q_shift);
840     }
841   }
842 }
843