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 += (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_shl32_dir_sat_limit(-(coef[SIZE15 - 1 - i]),
    167                                            (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_shl32_dir_sat_limit(ixheaacd_mult32x16in32(temp_coef, win1),
    190                                         q_shift) -
    191            ixheaacd_mult32x16in32_drc(prev1, win3);
    192     *out1 = ixheaacd_round16(accu << 2);
    193     out1 += ch_fac;
    194 
    195     accu = ixheaacd_sub32_sat(
    196         ixheaacd_shl32_dir_sat_limit(
    197             ixheaacd_mult32x16in32(ixheaacd_negate32_sat(temp_coef), win2),
    198             q_shift),
    199         ixheaacd_mult32x16in32_drc(prev1, win4));
    200     *out2 = ixheaacd_round16(accu << 2);
    201     out2 -= ch_fac;
    202   }
    203 }
    204 
    205 static PLATFORM_INLINE VOID ixheaacd_long_short_win_process(
    206     WORD32 *current, WORD32 *prev, WORD16 *out, const WORD16 *short_window,
    207     const WORD16 *long_window_prev, WORD16 q_shift, WORD16 ch_fac,
    208     WORD32 flag) {
    209   WORD i;
    210   WORD32 accu;
    211   WORD32 *current_tmp1 = &(current[(SIZE03 - 1)]);
    212   WORD32 *current_tmp2 = &(current[-SIZE01]);
    213   const WORD16 *short_ptr = &(short_window[SIZE02 - 1]);
    214 
    215   for (i = SIZE01 - 1; i >= 0; i--) {
    216     WORD32 tmp1_cur = *current_tmp1--;
    217     WORD32 tmp2_cur = *current_tmp2++;
    218     WORD16 short1 = *short_ptr--;
    219     WORD16 short2 = *short_ptr--;
    220     accu =
    221         (ixheaacd_shl32_dir_sat_limit(
    222              (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_shl32_dir_sat_limit(
    230                   (ixheaacd_mult32x16in32(-(tmp1_cur), short1) -
    231                    ixheaacd_mult32x16in32(tmp2_cur, short2)),
    232                   q_shift) -
    233               ixheaacd_mult32x16in32_drc(
    234                   prev[SIZE02 - 1 - i], long_window_prev[-2 * SIZE02 + 2 * i]));
    235       out[ch_fac * (SIZE02 - 1 - i)] = ixheaacd_round16(accu << 2);
    236     }
    237   }
    238 }
    239 
    240 VOID ixheaacd_long_short_win_seq(WORD32 *current, WORD32 *prev, WORD16 *out,
    241                                  const WORD16 *short_window,
    242                                  const WORD16 *short_window_prev,
    243                                  const WORD16 *long_window_prev, WORD16 q_shift,
    244                                  WORD16 ch_fac) {
    245   WORD32 i, flag;
    246   WORD32 accu;
    247   for (i = 0; i < SIZE07; i++) {
    248     accu = ixheaacd_mult32x16in32_drc(
    249         prev[SIZE08 - 1 - i], ixheaacd_negate16(long_window_prev[2 * i + 1]));
    250     out[ch_fac * i] = ixheaacd_round16(accu << 2);
    251   }
    252 
    253   for (i = 0; i < SIZE01; i++) {
    254     accu =
    255         (ixheaacd_shl32_dir_sat_limit(
    256              ixheaacd_mult32x16in32(current[SIZE01 + i],
    257                                     short_window_prev[2 * i]),
    258              q_shift) -
    259          ixheaacd_mult32x16in32_drc(prev[SIZE01 - 1 - i],
    260                                     long_window_prev[2 * SIZE07 + 1 + 2 * i]));
    261     out[ch_fac * (SIZE07 + i)] = ixheaacd_round16(accu << 2);
    262   }
    263 
    264   for (i = 0; i < SIZE01; i++) {
    265     accu = (ixheaacd_shl32_dir_sat_limit(
    266                 ixheaacd_mult32x16in32(-(current[SIZE02 - 1 - i]),
    267                                        short_window_prev[SIZE02 - 2 * i - 1]),
    268                 q_shift) -
    269             ixheaacd_mult32x16in32_drc(prev[i],
    270                                        long_window_prev[SIZE16 - 2 - (2 * i)]));
    271     out[ch_fac * (SIZE08 + i)] = ixheaacd_round16(accu << 2);
    272   }
    273 
    274   flag = 1;
    275   for (i = 0; i < 4; i++) {
    276     WORD32 inc = i * SIZE02;
    277 
    278     if (i == 3) {
    279       flag = 0;
    280     }
    281 
    282     ixheaacd_long_short_win_process(&current[SIZE01 + inc], &prev[SIZE01 + inc],
    283                                     &out[ch_fac * (SIZE09 + inc)], short_window,
    284                                     &long_window_prev[2 * (SIZE07 - inc)],
    285                                     q_shift, ch_fac, flag);
    286   }
    287 
    288   for (i = 0; i < SIZE01; i++) {
    289     accu = (ixheaacd_mult32x16in32(-(current[SIZE10 - 1 - i]),
    290                                    short_window[SIZE02 - 2 * i - 1]) -
    291             ixheaacd_mult32x16in32(current[SIZE06 + i],
    292                                    short_window[SIZE02 - 2 * i - 2]));
    293     prev[i] =
    294         ixheaacd_round16(ixheaacd_shl32_dir_sat_limit(accu, (q_shift + 1)));
    295   }
    296 }
    297 
    298 VOID ixheaacd_nolap1_32(WORD32 *coef,
    299 
    300                         WORD32 *out,
    301 
    302                         WORD16 q_shift, WORD16 ch_fac) {
    303   WORD32 i;
    304 
    305   for (i = 0; i < SIZE07; i++) {
    306     out[ch_fac * i] = ixheaacd_shr32_drc(
    307         ixheaacd_negate32_sat(coef[SIZE07 - 1 - i]), 16 - q_shift);
    308   }
    309 }
    310 
    311 VOID ixheaacd_neg_shift_spec_dec(WORD32 *coef, WORD16 *out, WORD16 q_shift,
    312                                  WORD16 ch_fac) {
    313   WORD32 i;
    314 
    315   for (i = 0; i < SIZE07; i++) {
    316     out[ch_fac * i] = ixheaacd_round16(ixheaacd_shl32_dir_sat_limit(
    317         ixheaacd_negate32_sat(coef[SIZE07 - 1 - i]), q_shift));
    318   }
    319 }
    320 
    321 VOID ixheaacd_spec_to_overlapbuf_dec(WORD32 *ptr_overlap_buf,
    322                                      WORD32 *ptr_spec_coeff, WORD32 q_shift,
    323                                      WORD32 size) {
    324   WORD32 i;
    325   for (i = 0; i < size; i++) {
    326     ptr_overlap_buf[i] = ixheaacd_shr32_drc(ptr_spec_coeff[i], 16 - q_shift);
    327   }
    328 }
    329 
    330 VOID ixheaacd_overlap_buf_out_dec(WORD16 *out_samples, WORD32 *ptr_overlap_buf,
    331                                   WORD32 size, const WORD16 ch_fac) {
    332   WORD32 i;
    333 
    334   for (i = 0; i < size; i++) {
    335     out_samples[ch_fac * i] = ixheaacd_shl16_sat((WORD16)ptr_overlap_buf[i], 1);
    336   }
    337 }
    338 
    339 VOID ixheaacd_overlap_out_copy_dec(WORD16 *out_samples, WORD32 *ptr_overlap_buf,
    340                                    WORD32 *ptr_overlap_buf1,
    341                                    const WORD16 ch_fac) {
    342   WORD32 i;
    343 
    344   for (i = 0; i < SIZE01; i++) {
    345     out_samples[ch_fac * i] = ixheaacd_shl16_sat((WORD16)ptr_overlap_buf[i], 1);
    346     ptr_overlap_buf[i] = ptr_overlap_buf1[i];
    347   }
    348 }
    349 
    350 VOID ixheaacd_imdct_process(ia_aac_dec_overlap_info *ptr_aac_dec_overlap_info,
    351                             WORD32 *ptr_spec_coeff,
    352                             ia_ics_info_struct *ptr_ics_info,
    353                             WORD16 out_samples[], const WORD16 ch_fac,
    354                             WORD32 *scratch,
    355                             ia_aac_dec_tables_struct *ptr_aac_tables,
    356                             WORD32 object_type) {
    357   WORD32 *ptr_overlap_buf;
    358   const WORD16 *ptr_long_window;
    359   const WORD16 *ptr_short_window;
    360 
    361   ptr_overlap_buf = ptr_aac_dec_overlap_info->ptr_overlap_buf;
    362   ptr_long_window =
    363       ptr_aac_dec_overlap_info
    364           ->ptr_long_window[(WORD32)ptr_aac_dec_overlap_info->window_shape];
    365   ptr_short_window =
    366       ptr_aac_dec_overlap_info
    367           ->ptr_short_window[(WORD32)ptr_aac_dec_overlap_info->window_shape];
    368 
    369   if (ptr_ics_info->window_sequence != EIGHT_SHORT_SEQUENCE) {
    370     WORD16 q_shift;
    371     WORD32 expo, imdct_scale;
    372 
    373     if ((512 == ptr_ics_info->frame_length) ||
    374         (480 == ptr_ics_info->frame_length)) {
    375       if (512 == ptr_ics_info->frame_length) {
    376         WORD32 *ld_cos_sin_ptr =
    377             (WORD32 *)ptr_aac_tables->pstr_imdct_tables->cosine_array_1024;
    378 
    379         ixheaacd_inverse_transform_512(
    380             ptr_spec_coeff, scratch, &imdct_scale, ld_cos_sin_ptr,
    381             ptr_aac_tables->pstr_imdct_tables, object_type);
    382 
    383       } else {
    384         ixheaacd_mdct_480_ld(ptr_spec_coeff, scratch, &imdct_scale, 0,
    385                              ptr_aac_tables->pstr_imdct_tables, object_type);
    386       }
    387 
    388       if (object_type == AOT_ER_AAC_ELD) {
    389         int i, N = (ptr_ics_info->frame_length << 1);
    390 
    391         for (i = 0; i < N / 2; i++) {
    392           ptr_spec_coeff[i] = -ptr_spec_coeff[i + N];
    393           ptr_spec_coeff[i + N + N / 2] = -ptr_spec_coeff[i + N / 2];
    394         }
    395       }
    396     } else
    397 
    398     {
    399       expo = (*ixheaacd_calc_max_spectral_line)(ptr_spec_coeff, 1024) - 1;
    400 
    401       expo = 8 - expo;
    402 
    403       imdct_scale = ixheaacd_inverse_transform(
    404           ptr_spec_coeff, scratch, ptr_aac_tables->pstr_imdct_tables, expo,
    405           1024);
    406     }
    407 
    408     q_shift = (31 + imdct_scale) + (-1 - 16 - 9);
    409 
    410     switch (ptr_ics_info->window_sequence) {
    411       case ONLY_LONG_SEQUENCE:
    412 
    413         switch (ptr_aac_dec_overlap_info->window_sequence) {
    414           case ONLY_LONG_SEQUENCE:
    415           case LONG_STOP_SEQUENCE:
    416 
    417             if (1024 == ptr_ics_info->frame_length) {
    418               ia_ics_info_struct *tmp_ptr_ics_info = ptr_ics_info;
    419               (*ixheaacd_post_twid_overlap_add)(
    420                   out_samples, ptr_spec_coeff,
    421                   ptr_aac_tables->pstr_imdct_tables, 1024, ptr_overlap_buf,
    422                   q_shift, ptr_long_window, ch_fac);
    423               ptr_ics_info = tmp_ptr_ics_info;
    424             }
    425             if ((512 == ptr_ics_info->frame_length) ||
    426                 (480 == ptr_ics_info->frame_length)) {
    427               if (object_type != AOT_ER_AAC_ELD) {
    428                 if (512 == ptr_ics_info->frame_length) {
    429                   ixheaacd_lap1_512_480(ptr_spec_coeff, ptr_overlap_buf,
    430                                         out_samples, ptr_long_window, q_shift,
    431                                         SIZE04, ch_fac);
    432                   ixheaacd_spec_to_overlapbuf(ptr_overlap_buf, ptr_spec_coeff,
    433                                               q_shift, SIZE04);
    434                 } else if (480 == ptr_ics_info->frame_length) {
    435                   ixheaacd_lap1_512_480(ptr_spec_coeff, ptr_overlap_buf,
    436                                         out_samples, ptr_long_window, q_shift,
    437                                         240, ch_fac);
    438                   ixheaacd_spec_to_overlapbuf(ptr_overlap_buf, ptr_spec_coeff,
    439                                               q_shift, 240);
    440                 }
    441               } else {
    442                 ixheaacd_eld_dec_windowing(
    443                     ptr_spec_coeff, ptr_long_window, ptr_ics_info->frame_length,
    444                     q_shift, ptr_overlap_buf, ch_fac, out_samples);
    445               }
    446             }
    447             break;
    448 
    449           case LONG_START_SEQUENCE:
    450           case EIGHT_SHORT_SEQUENCE:
    451             if (1024 == ptr_ics_info->frame_length) {
    452               (*ixheaacd_post_twiddle)(scratch, ptr_spec_coeff,
    453                                        ptr_aac_tables->pstr_imdct_tables, 1024);
    454             }
    455 
    456             ixheaacd_process_win_seq(scratch, ptr_overlap_buf, out_samples,
    457                                      ptr_long_window, ptr_short_window, q_shift,
    458                                      ch_fac, 1);
    459 
    460             if (512 == ptr_ics_info->frame_length) {
    461               ixheaacd_spec_to_overlapbuf(ptr_overlap_buf, ptr_spec_coeff,
    462                                           q_shift, SIZE04);
    463             } else if (480 == ptr_ics_info->frame_length) {
    464               ixheaacd_spec_to_overlapbuf(ptr_overlap_buf, ptr_spec_coeff,
    465                                           q_shift, 240);
    466             } else {
    467               (*ixheaacd_spec_to_overlapbuf)(ptr_overlap_buf, scratch, q_shift,
    468                                              SIZE08);
    469             }
    470             break;
    471         }
    472 
    473         break;
    474 
    475       case LONG_START_SEQUENCE:
    476         if (1024 == ptr_ics_info->frame_length) {
    477           (*ixheaacd_post_twiddle)(scratch, ptr_spec_coeff,
    478                                    ptr_aac_tables->pstr_imdct_tables, 1024);
    479         }
    480         switch (ptr_aac_dec_overlap_info->window_sequence) {
    481           case ONLY_LONG_SEQUENCE:
    482           case LONG_STOP_SEQUENCE:
    483 
    484             (*ixheaacd_over_lap_add1)(scratch, ptr_overlap_buf, out_samples,
    485                                       ptr_long_window, q_shift, SIZE08, ch_fac);
    486 
    487             break;
    488 
    489           case LONG_START_SEQUENCE:
    490           case EIGHT_SHORT_SEQUENCE:
    491 
    492             ixheaacd_process_win_seq(scratch, ptr_overlap_buf, out_samples,
    493                                      ptr_long_window, ptr_short_window, q_shift,
    494                                      ch_fac, 1);
    495 
    496             break;
    497         }
    498 
    499         ixheaacd_nolap1_32(&scratch[SIZE01], ptr_overlap_buf, q_shift, 1);
    500 
    501         (*ixheaacd_spec_to_overlapbuf)(&ptr_overlap_buf[SIZE07], scratch,
    502                                        q_shift, SIZE01);
    503 
    504         break;
    505 
    506       case LONG_STOP_SEQUENCE:
    507         if (1024 == ptr_ics_info->frame_length) {
    508           (*ixheaacd_post_twiddle)(scratch, ptr_spec_coeff,
    509                                    ptr_aac_tables->pstr_imdct_tables, 1024);
    510         }
    511 
    512         switch (ptr_aac_dec_overlap_info->window_sequence) {
    513           case EIGHT_SHORT_SEQUENCE:
    514           case LONG_START_SEQUENCE:
    515 
    516             (*ixheaacd_overlap_buf_out)(out_samples, ptr_overlap_buf, SIZE07,
    517                                         ch_fac);
    518 
    519             (*ixheaacd_over_lap_add1)(
    520                 &scratch[SIZE14], &ptr_overlap_buf[SIZE07],
    521                 &out_samples[ch_fac * (SIZE07)], ptr_short_window, q_shift,
    522                 SIZE01, ch_fac);
    523 
    524             {
    525               WORD16 q_shift1 = q_shift + 1;
    526               (*ixheaacd_neg_shift_spec)(&scratch[SIZE08],
    527                                          &out_samples[ch_fac * SIZE09],
    528                                          q_shift1, ch_fac);
    529             }
    530 
    531             break;
    532           case ONLY_LONG_SEQUENCE:
    533           case LONG_STOP_SEQUENCE:
    534 
    535             ixheaacd_process_win_seq(scratch, ptr_overlap_buf, out_samples,
    536                                      ptr_long_window, ptr_short_window, q_shift,
    537                                      ch_fac, 0);
    538             break;
    539         }
    540 
    541         (*ixheaacd_spec_to_overlapbuf)(ptr_overlap_buf, scratch, q_shift,
    542                                        SIZE08);
    543 
    544         break;
    545     }
    546 
    547   } else {
    548     WORD16 q_shift, max_scale;
    549     WORD32 imdct_scale[8], i;
    550     const WORD16 *short_window;
    551 
    552     short_window = ptr_aac_dec_overlap_info
    553                        ->ptr_short_window[(WORD32)ptr_ics_info->window_shape];
    554 
    555     {
    556       WORD32 expo;
    557 
    558       expo = (*ixheaacd_calc_max_spectral_line)(ptr_spec_coeff, 1024) - 1;
    559 
    560       expo = 5 - expo;
    561 
    562       for (i = 0; i < MAX_WINDOWS; i++) {
    563         imdct_scale[i] = ixheaacd_inverse_transform(
    564             &ptr_spec_coeff[i * SIZE02], &scratch[i * SIZE02],
    565             ptr_aac_tables->pstr_imdct_tables, expo, 128);
    566 
    567         (*ixheaacd_post_twiddle)(&scratch[i * SIZE02],
    568                                  &ptr_spec_coeff[i * SIZE02],
    569                                  ptr_aac_tables->pstr_imdct_tables, 128);
    570       }
    571     }
    572 
    573     max_scale = 31 + imdct_scale[0];
    574 
    575     q_shift = max_scale + (-16 - 6 - 1);
    576 
    577     switch (ptr_aac_dec_overlap_info->window_sequence) {
    578       WORD32 overlap_buf_loc[SIZE01];
    579 
    580       case EIGHT_SHORT_SEQUENCE:
    581       case LONG_START_SEQUENCE:
    582 
    583         (*ixheaacd_overlap_buf_out)(out_samples, ptr_overlap_buf, SIZE07,
    584                                     ch_fac);
    585 
    586         (*ixheaacd_over_lap_add1)(&scratch[0], &ptr_overlap_buf[SIZE07],
    587                                   &out_samples[ch_fac * SIZE07],
    588                                   ptr_short_window, q_shift, SIZE01, ch_fac);
    589 
    590         for (i = 0; i < 3; i++) {
    591           WORD32 inc = (i * SIZE02);
    592           (*ixheaacd_spec_to_overlapbuf)(overlap_buf_loc, &scratch[inc],
    593                                          q_shift, SIZE01);
    594 
    595           (*ixheaacd_over_lap_add1)(&scratch[SIZE02 + inc], overlap_buf_loc,
    596                                     &out_samples[ch_fac * (SIZE09 + inc)],
    597                                     short_window, q_shift, SIZE01, ch_fac);
    598         }
    599 
    600         (*ixheaacd_over_lap_add2)(&scratch[SIZE08], &scratch[SIZE06],
    601                                   ptr_overlap_buf, short_window, q_shift,
    602                                   SIZE01, 1);
    603 
    604         (*ixheaacd_overlap_out_copy)(&out_samples[ch_fac * SIZE15],
    605                                      ptr_overlap_buf, &ptr_overlap_buf[SIZE01],
    606                                      ch_fac);
    607 
    608         break;
    609 
    610       case ONLY_LONG_SEQUENCE:
    611       case LONG_STOP_SEQUENCE:
    612 
    613         ixheaacd_long_short_win_seq(scratch, ptr_overlap_buf, out_samples,
    614                                     short_window, ptr_short_window,
    615                                     ptr_long_window, q_shift, ch_fac);
    616 
    617         break;
    618     }
    619 
    620     for (i = 0; i < 3; i++) {
    621       WORD32 inc = (i * SIZE02);
    622       (*ixheaacd_over_lap_add2)(&scratch[SIZE10 + inc], &scratch[SIZE08 + inc],
    623                                 &ptr_overlap_buf[SIZE01 + inc], short_window,
    624                                 q_shift, SIZE01, 1);
    625     }
    626 
    627     (*ixheaacd_spec_to_overlapbuf)(&ptr_overlap_buf[SIZE07], &scratch[SIZE14],
    628                                    q_shift, SIZE01);
    629   }
    630 
    631   ptr_aac_dec_overlap_info->window_shape = ptr_ics_info->window_shape;
    632   ptr_aac_dec_overlap_info->window_sequence = ptr_ics_info->window_sequence;
    633 }
    634 void ixheaacd_eld_dec_windowing(WORD32 *ptr_spect_coeff, const WORD16 *p_win,
    635                                 WORD32 framesize, WORD16 q_shift,
    636                                 WORD32 *p_overlap_buffer, const WORD16 stride,
    637                                 WORD16 *out_samples)
    638 
    639 {
    640   int i = 0;
    641   int loop_size;
    642   WORD32 *ptr_z = ptr_spect_coeff;
    643 
    644   WORD32 *ptr_out, *p_out2;
    645   WORD32 *p_overlap_buffer32 = (WORD32 *)p_overlap_buffer;
    646   WORD32 delay = framesize >> 2;
    647 
    648   ptr_z = ptr_spect_coeff + delay;
    649   p_win += delay;
    650   ptr_out = p_overlap_buffer32;
    651 
    652   q_shift = q_shift + 2;
    653 
    654   if (q_shift >= 0) {
    655     for (i = (delay)-1; i >= 0; i--) {
    656       WORD32 win_op;
    657       WORD32 win_ovadd_op;
    658       WORD16 win_val;
    659 
    660       win_val = *p_win++;
    661 
    662       win_op = ixheaacd_mult32x16in32(*ptr_z++, (win_val));
    663 
    664       win_ovadd_op =
    665           ixheaacd_add32(ixheaacd_shl32(win_op, q_shift), *ptr_out++);
    666 
    667       *out_samples = ixheaacd_round16(ixheaacd_shl32_sat(win_ovadd_op, 1));
    668       out_samples += stride;
    669 
    670       win_val = *p_win++;
    671 
    672       win_op = ixheaacd_mult32x16in32(*ptr_z++, (win_val));
    673 
    674       win_ovadd_op =
    675           ixheaacd_add32(ixheaacd_shl32(win_op, q_shift), *ptr_out++);
    676 
    677       *out_samples = ixheaacd_round16(ixheaacd_shl32_sat(win_ovadd_op, 1));
    678       out_samples += stride;
    679       win_val = *p_win++;
    680 
    681       win_op = ixheaacd_mult32x16in32(*ptr_z++, (win_val));
    682 
    683       win_ovadd_op =
    684           ixheaacd_add32(ixheaacd_shl32(win_op, q_shift), *ptr_out++);
    685 
    686       *out_samples = ixheaacd_round16(ixheaacd_shl32_sat(win_ovadd_op, 1));
    687       out_samples += stride;
    688 
    689       win_val = *p_win++;
    690 
    691       win_op = ixheaacd_mult32x16in32(*ptr_z++, (win_val));
    692 
    693       win_ovadd_op =
    694           ixheaacd_add32(ixheaacd_shl32(win_op, q_shift), *ptr_out++);
    695 
    696       *out_samples = ixheaacd_round16(ixheaacd_shl32_sat(win_ovadd_op, 1));
    697       out_samples += stride;
    698     }
    699 
    700     p_out2 = p_overlap_buffer32;
    701     loop_size = (((framesize * 3) - framesize) >> 2) - 1;
    702 
    703     for (i = loop_size; i >= 0; i--) {
    704       WORD32 win_op;
    705       WORD16 win_val;
    706       win_val = *p_win++;
    707       win_op = ixheaacd_mult32x16in32(*ptr_z++, (win_val));
    708       *p_out2++ = ixheaacd_add32(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++ = ixheaacd_add32(ixheaacd_shl32(win_op, q_shift), *ptr_out++);
    713 
    714       win_val = *p_win++;
    715       win_op = ixheaacd_mult32x16in32(*ptr_z++, (win_val));
    716       *p_out2++ = ixheaacd_add32(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++ = ixheaacd_add32(ixheaacd_shl32(win_op, q_shift), *ptr_out++);
    721     }
    722 
    723     loop_size = ((((framesize << 2) - delay) - (framesize * 3)) >> 2) - 1;
    724     for (i = loop_size; i >= 0; i--) {
    725       WORD32 win_op;
    726       WORD16 win_val;
    727 
    728       win_val = *p_win++;
    729       win_op = ixheaacd_mult32x16in32(*ptr_z++, (win_val));
    730       *p_out2++ = ixheaacd_shl32(win_op, q_shift);
    731 
    732       win_val = *p_win++;
    733       win_op = ixheaacd_mult32x16in32(*ptr_z++, (win_val));
    734       *p_out2++ = ixheaacd_shl32(win_op, q_shift);
    735 
    736       win_val = *p_win++;
    737       win_op = ixheaacd_mult32x16in32(*ptr_z++, (win_val));
    738       *p_out2++ = ixheaacd_shl32(win_op, q_shift);
    739 
    740       win_val = *p_win++;
    741       win_op = ixheaacd_mult32x16in32(*ptr_z++, (win_val));
    742       *p_out2++ = ixheaacd_shl32(win_op, q_shift);
    743     }
    744   } else {
    745     q_shift = -q_shift;
    746 
    747     for (i = (delay)-1; i >= 0; i--) {
    748       WORD32 win_op;
    749       WORD32 win_ovadd_op;
    750       WORD16 win_val;
    751 
    752       win_val = *p_win++;
    753       win_op = ixheaacd_mult32x16in32(*ptr_z++, (win_val));
    754 
    755       win_ovadd_op =
    756           ixheaacd_add32(ixheaacd_shr32(win_op, q_shift), *ptr_out++);
    757 
    758       *out_samples = ixheaacd_round16(ixheaacd_shl32(win_ovadd_op, 1));
    759       out_samples += stride;
    760 
    761       win_val = *p_win++;
    762       win_op = ixheaacd_mult32x16in32(*ptr_z++, (win_val));
    763 
    764       win_ovadd_op =
    765           ixheaacd_add32(ixheaacd_shr32(win_op, q_shift), *ptr_out++);
    766 
    767       *out_samples = ixheaacd_round16(ixheaacd_shl32(win_ovadd_op, 1));
    768       out_samples += stride;
    769 
    770       win_val = *p_win++;
    771       win_op = ixheaacd_mult32x16in32(*ptr_z++, (win_val));
    772 
    773       win_ovadd_op =
    774           ixheaacd_add32(ixheaacd_shr32(win_op, q_shift), *ptr_out++);
    775 
    776       *out_samples = ixheaacd_round16(ixheaacd_shl32(win_ovadd_op, 1));
    777       out_samples += stride;
    778 
    779       win_val = *p_win++;
    780       win_op = ixheaacd_mult32x16in32(*ptr_z++, (win_val));
    781 
    782       win_ovadd_op =
    783           ixheaacd_add32(ixheaacd_shr32(win_op, q_shift), *ptr_out++);
    784 
    785       *out_samples = ixheaacd_round16(ixheaacd_shl32(win_ovadd_op, 1));
    786       out_samples += stride;
    787     }
    788 
    789     p_out2 = p_overlap_buffer32;
    790     loop_size = (((framesize * 3) - framesize) >> 2) - 1;
    791 
    792     for (i = loop_size; i >= 0; i--) {
    793       WORD32 win_op;
    794       WORD16 win_val;
    795       win_val = *p_win++;
    796       win_op = ixheaacd_mult32x16in32(*ptr_z++, (win_val));
    797       *p_out2++ = ixheaacd_add32(ixheaacd_shr32(win_op, q_shift), *ptr_out++);
    798 
    799       win_val = *p_win++;
    800       win_op = ixheaacd_mult32x16in32(*ptr_z++, (win_val));
    801       *p_out2++ = ixheaacd_add32(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++ = ixheaacd_add32(ixheaacd_shr32(win_op, q_shift), *ptr_out++);
    806 
    807       win_val = *p_win++;
    808       win_op = ixheaacd_mult32x16in32(*ptr_z++, (win_val));
    809       *p_out2++ = ixheaacd_add32(ixheaacd_shr32(win_op, q_shift), *ptr_out++);
    810     }
    811     loop_size = ((((framesize << 2) - delay) - (framesize * 3)) >> 2) - 1;
    812     for (i = loop_size; i >= 0; i--) {
    813       WORD32 win_op;
    814       WORD16 win_val;
    815       win_val = *p_win++;
    816       win_op = ixheaacd_mult32x16in32(*ptr_z++, (win_val));
    817       *p_out2++ = ixheaacd_shr32(win_op, q_shift);
    818 
    819       win_val = *p_win++;
    820       win_op = ixheaacd_mult32x16in32(*ptr_z++, (win_val));
    821       *p_out2++ = ixheaacd_shr32(win_op, q_shift);
    822 
    823       win_val = *p_win++;
    824       win_op = ixheaacd_mult32x16in32(*ptr_z++, (win_val));
    825       *p_out2++ = ixheaacd_shr32(win_op, q_shift);
    826 
    827       win_val = *p_win++;
    828       win_op = ixheaacd_mult32x16in32(*ptr_z++, (win_val));
    829       *p_out2++ = ixheaacd_shr32(win_op, q_shift);
    830     }
    831   }
    832 }
    833