Home | History | Annotate | Download | only in decoder
      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 
     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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 }
    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