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