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 "ixheaacd_sbr_common.h"
     21 #include <ixheaacd_type_def.h>
     22 
     23 #include "ixheaacd_constants.h"
     24 #include <ixheaacd_basic_ops32.h>
     25 #include <ixheaacd_basic_ops16.h>
     26 #include <ixheaacd_basic_ops40.h>
     27 #include "ixheaacd_basic_ops.h"
     28 
     29 #include "ixheaacd_intrinsics.h"
     30 #include "ixheaacd_bitbuffer.h"
     31 #include "ixheaacd_sbrdecsettings.h"
     32 #include "ixheaacd_defines.h"
     33 
     34 #include "ixheaacd_pns.h"
     35 
     36 #include <ixheaacd_aac_rom.h>
     37 #include "ixheaacd_pulsedata.h"
     38 #include "ixheaacd_drc_data_struct.h"
     39 
     40 #include "ixheaacd_lt_predict.h"
     41 
     42 #include "ixheaacd_channelinfo.h"
     43 #include "ixheaacd_drc_dec.h"
     44 
     45 #include "ixheaacd_sbrdecoder.h"
     46 #include "ixheaacd_sbr_scale.h"
     47 #include "ixheaacd_lpp_tran.h"
     48 
     49 #include "ixheaacd_env_extr_part.h"
     50 #include <ixheaacd_sbr_rom.h>
     51 #include "ixheaacd_hybrid.h"
     52 #include "ixheaacd_ps_dec.h"
     53 #include "ixheaacd_env_extr.h"
     54 
     55 #include "ixheaacd_sbr_const.h"
     56 #include "ixheaacd_common_rom.h"
     57 #include "ixheaacd_freq_sca.h"
     58 
     59 #include "ixheaacd_basic_funcs.h"
     60 #include "ixheaacd_env_extr.h"
     61 
     62 #include "ixheaacd_env_calc.h"
     63 #include <ixheaacd_basic_op.h>
     64 
     65 #include "ixheaacd_qmf_dec.h"
     66 
     67 #include "ixheaacd_pvc_dec.h"
     68 #include "ixheaacd_sbr_dec.h"
     69 #include "ixheaacd_function_selector.h"
     70 
     71 #include "ixheaacd_audioobjtypes.h"
     72 
     73 #define FACTOR 0x010b0000 * 2
     74 
     75 static VOID ixheaacd_alias_reduction(WORD16 *deg_patched, WORD16 *nrg_gain,
     76                                      WORD16 *nrg_est, WORD8 *alias_red_buf,
     77                                      WORD32 num_sub_bands,
     78                                      ixheaacd_misc_tables *pstr_common_tables) {
     79   WORD32 group, grouping, i, num_groups, k;
     80   WORD16 f_group_vec[MAX_FREQ_COEFFS], *ptr_f_group_vec;
     81 
     82   grouping = 0;
     83   i = 0;
     84 
     85   for (k = 0; k < num_sub_bands - 1; k++) {
     86     if ((deg_patched[k + 1] != 0) && alias_red_buf[k]) {
     87       if (grouping == 0) {
     88         f_group_vec[i] = k;
     89         grouping = 1;
     90         i++;
     91       } else {
     92         if ((f_group_vec[i - 1] + 3) == k) {
     93           f_group_vec[i] = (k + 1);
     94           grouping = 0;
     95           i++;
     96         }
     97       }
     98     } else {
     99       if (grouping) {
    100         grouping = 0;
    101         f_group_vec[i] = k;
    102 
    103         if (alias_red_buf[k]) f_group_vec[i] = k + 1;
    104 
    105         i++;
    106       }
    107     }
    108   }
    109 
    110   if (grouping) {
    111     f_group_vec[i] = num_sub_bands;
    112     i++;
    113   }
    114   num_groups = (i >> 1);
    115 
    116   ptr_f_group_vec = f_group_vec;
    117 
    118   for (group = num_groups; group != 0; group--) {
    119     WORD16 nrg_amp_mant;
    120     WORD16 nrg_amp_exp;
    121     WORD16 nrgMod_m;
    122     WORD16 nrgMod_e;
    123     WORD16 grp_gain_mant;
    124     WORD16 grp_gain_exp;
    125     WORD16 compensation_m;
    126     WORD16 compensation_e;
    127     WORD32 nrg_mod_mant;
    128     WORD32 nrg_mod_exp;
    129 
    130     WORD32 start_grp = *ptr_f_group_vec++;
    131     WORD32 stop_grp = *ptr_f_group_vec++;
    132 
    133     ixheaacd_avggain_calc(nrg_est, nrg_gain, start_grp, stop_grp, &nrg_amp_mant,
    134                           &nrg_amp_exp, &grp_gain_mant, &grp_gain_exp,
    135                           pstr_common_tables, 1);
    136 
    137     nrg_mod_mant = 0;
    138     nrg_mod_exp = 0;
    139     {
    140       WORD16 *ptr_nrg_gain_mant = &nrg_gain[2 * start_grp];
    141 
    142       for (k = start_grp; k < stop_grp; k++) {
    143         WORD32 tmp_mant, tmp_gain_mant, gain_m;
    144         WORD32 tmp_e, tmp_gain_exp;
    145         WORD16 one_minus_alpha, alpha = deg_patched[k];
    146 
    147         if (k < (num_sub_bands - 1)) {
    148           alpha = ixheaacd_max16(deg_patched[k + 1], alpha);
    149         }
    150         gain_m = (alpha * grp_gain_mant);
    151         one_minus_alpha = 0x7fff - alpha;
    152 
    153         tmp_gain_mant = *ptr_nrg_gain_mant;
    154         tmp_gain_exp = *(ptr_nrg_gain_mant + 1);
    155 
    156         {
    157           WORD32 exp_diff;
    158 
    159           tmp_gain_mant = (one_minus_alpha * tmp_gain_mant) >> 15;
    160 
    161           exp_diff = (grp_gain_exp - tmp_gain_exp);
    162 
    163           if (exp_diff >= 0) {
    164             tmp_gain_exp = grp_gain_exp;
    165             tmp_gain_mant = ixheaacd_shr32(tmp_gain_mant, exp_diff);
    166 
    167             tmp_gain_mant = (gain_m >> 15) + tmp_gain_mant;
    168 
    169           } else {
    170             tmp_gain_mant =
    171                 (ixheaacd_shr32(gain_m, (15 - exp_diff))) + tmp_gain_mant;
    172           }
    173         }
    174         *ptr_nrg_gain_mant++ = tmp_gain_mant;
    175         *ptr_nrg_gain_mant++ = tmp_gain_exp;
    176 
    177         tmp_mant = (tmp_gain_mant * (nrg_est[2 * k])) >> 16;
    178         tmp_e = (tmp_gain_exp + (nrg_est[2 * k + 1]) + 1);
    179 
    180         {
    181           WORD32 exp_diff;
    182           exp_diff = tmp_e - nrg_mod_exp;
    183           if (exp_diff >= 0) {
    184             nrg_mod_mant = tmp_mant + (ixheaacd_shr32(nrg_mod_mant, exp_diff));
    185             nrg_mod_exp = tmp_e;
    186           } else {
    187             exp_diff = -exp_diff;
    188             nrg_mod_mant = (ixheaacd_shr32(tmp_mant, exp_diff)) + nrg_mod_mant;
    189           }
    190         }
    191       }
    192     }
    193 
    194     {
    195       WORD32 norm_val;
    196       norm_val = 16 - ixheaacd_pnorm32(nrg_mod_mant);
    197       if (norm_val > 0) {
    198         nrg_mod_mant >>= norm_val;
    199         nrg_mod_exp += norm_val;
    200       }
    201     }
    202 
    203     nrgMod_m = (WORD16)nrg_mod_mant;
    204     nrgMod_e = (WORD16)nrg_mod_exp;
    205 
    206     compensation_e = ixheaacd_fix_mant_div(nrg_amp_mant, nrgMod_m,
    207                                            &compensation_m, pstr_common_tables);
    208     compensation_e += nrg_amp_exp - nrgMod_e + 1 + 1;
    209 
    210     {
    211       WORD16 *ptr_nrg_gain_mant = &nrg_gain[2 * start_grp];
    212 
    213       for (k = stop_grp - start_grp; k != 0; k--) {
    214         WORD16 temp1, temp2;
    215         temp1 = *ptr_nrg_gain_mant;
    216         temp2 = *(ptr_nrg_gain_mant + 1);
    217         temp1 = (temp1 * compensation_m) >> 16;
    218         temp2 = (temp2 + compensation_e);
    219         *ptr_nrg_gain_mant++ = temp1;
    220         *ptr_nrg_gain_mant++ = temp2;
    221       }
    222     }
    223   }
    224 }
    225 
    226 VOID ixheaacd_noiselimiting(ia_freq_band_data_struct *pstr_freq_band_data,
    227                             WORD32 skip_bands, WORD16 *ptr_enrg_orig,
    228                             WORD16 *nrg_est, WORD16 *nrg_gain,
    229                             WORD16 *noise_level_mant, WORD16 *nrg_sine,
    230                             WORD16 *ptr_limit_gain_table, FLAG noise_absc_flag,
    231                             ixheaacd_misc_tables *pstr_common_tables) {
    232   WORD32 c, k;
    233   WORD32 temp_val;
    234   WORD16 limit_gain_mant = *ptr_limit_gain_table++;
    235   WORD16 limit_gain_exp = *ptr_limit_gain_table;
    236   for (c = 0; c < pstr_freq_band_data->num_lf_bands; c++) {
    237     WORD16 max_gain_mant;
    238     WORD16 sum_orig_mant, sum_orig_exp;
    239     WORD16 max_gain_exp;
    240     WORD32 max_temp;
    241     WORD32 start_band = 0;
    242     WORD32 stop_band = 0;
    243 
    244     if ((pstr_freq_band_data->freq_band_tbl_lim[c] > skip_bands)) {
    245       start_band = (pstr_freq_band_data->freq_band_tbl_lim[c] - skip_bands);
    246     }
    247 
    248     if ((pstr_freq_band_data->freq_band_tbl_lim[c + 1] > skip_bands)) {
    249       stop_band = (pstr_freq_band_data->freq_band_tbl_lim[c + 1] - skip_bands);
    250     }
    251 
    252     if ((start_band < stop_band)) {
    253       ixheaacd_avggain_calc(ptr_enrg_orig, nrg_est, start_band, stop_band,
    254                             &sum_orig_mant, &sum_orig_exp, &max_gain_mant,
    255                             &max_gain_exp, pstr_common_tables, 0);
    256 
    257       max_temp = ixheaacd_mult16x16in32_shl(max_gain_mant, limit_gain_mant);
    258       max_gain_exp = (max_gain_exp + limit_gain_exp);
    259 
    260       temp_val = ixheaacd_norm32(max_temp);
    261 
    262       max_gain_exp = (WORD16)(max_gain_exp - temp_val);
    263       max_gain_mant = (WORD16)((max_temp << temp_val) >> 16);
    264 
    265       if ((max_gain_exp >= MAX_GAIN_EXP)) {
    266         max_gain_mant = 0x3000;
    267         max_gain_exp = MAX_GAIN_EXP;
    268       }
    269 
    270       {
    271         WORD16 *ptr_nrg_gain = &nrg_gain[2 * start_band];
    272         WORD16 *p_noise_level = &noise_level_mant[2 * start_band];
    273 
    274         for (k = stop_band - start_band; k != 0; k--) {
    275           WORD16 noise_amp_mant;
    276           WORD16 noise_amp_exp;
    277 
    278           WORD16 t_gain_mant = *(ptr_nrg_gain);
    279           WORD16 t_gain_exp = *(ptr_nrg_gain + 1);
    280 
    281           if (((t_gain_exp > max_gain_exp)) ||
    282               ((t_gain_exp == max_gain_exp) && (t_gain_mant > max_gain_mant))) {
    283             noise_amp_exp =
    284                 ixheaacd_fix_mant_div(max_gain_mant, t_gain_mant,
    285                                       &noise_amp_mant, pstr_common_tables);
    286             noise_amp_exp += (max_gain_exp - t_gain_exp) + 1;
    287 
    288             *p_noise_level = ixheaacd_extract16h(ixheaacd_shl32_dir_sat_limit(
    289                 ixheaacd_mult16x16in32_shl(*p_noise_level, noise_amp_mant),
    290                 noise_amp_exp));
    291 
    292             *ptr_nrg_gain = max_gain_mant;
    293             *(ptr_nrg_gain + 1) = max_gain_exp;
    294           }
    295           ptr_nrg_gain += 2;
    296           p_noise_level += 2;
    297         }
    298       }
    299 
    300       {
    301         WORD16 boost_gain_mant;
    302         WORD16 boost_gain_exp;
    303         WORD16 accu_m;
    304         WORD16 accu_e;
    305         WORD32 accu_m_t;
    306         WORD32 accu_e_t;
    307         WORD16 *ptr_nrg_gain = &nrg_gain[2 * start_band];
    308         WORD16 *ptr_enrg_est_buf = &nrg_est[2 * start_band];
    309         WORD16 *p_noise_level = &noise_level_mant[2 * start_band];
    310         WORD16 *p_nrg_sine = &nrg_sine[2 * start_band];
    311 
    312         accu_m_t = 0;
    313         accu_e_t = 0;
    314 
    315         for (k = stop_band - start_band; k != 0; k--) {
    316           WORD32 tmp_mant, tmp_e;
    317 
    318           tmp_mant = *ptr_nrg_gain++;
    319           tmp_e = *ptr_nrg_gain++;
    320           tmp_mant = (tmp_mant * (*ptr_enrg_est_buf++));
    321           tmp_e = (tmp_e + (*ptr_enrg_est_buf++));
    322           tmp_mant = tmp_mant >> 15;
    323           {
    324             WORD32 exp_diff;
    325             exp_diff = tmp_e - accu_e_t;
    326             if (exp_diff >= 0) {
    327               accu_m_t = tmp_mant + ixheaacd_shr32(accu_m_t, exp_diff);
    328               accu_e_t = tmp_e;
    329             } else {
    330               exp_diff = -exp_diff;
    331               accu_m_t = ixheaacd_shr32(tmp_mant, exp_diff) + accu_m_t;
    332             }
    333           }
    334 
    335           if (p_nrg_sine[0] != 0) {
    336             WORD32 exp_diff = p_nrg_sine[1] - accu_e_t;
    337             if (exp_diff >= 0) {
    338               accu_m_t = p_nrg_sine[0] + ixheaacd_shr32(accu_m_t, exp_diff);
    339               accu_e_t = p_nrg_sine[1];
    340             } else {
    341               exp_diff = -exp_diff;
    342               accu_m_t = accu_m_t + ixheaacd_shr32(p_nrg_sine[0], exp_diff);
    343             }
    344 
    345           } else {
    346             if (noise_absc_flag == 0) {
    347               WORD32 exp_diff = p_noise_level[1] - accu_e_t;
    348               if (exp_diff >= 0) {
    349                 accu_m_t =
    350                     p_noise_level[0] + ixheaacd_shr32(accu_m_t, exp_diff);
    351                 accu_e_t = p_noise_level[1];
    352               } else {
    353                 exp_diff = -exp_diff;
    354                 accu_m_t =
    355                     accu_m_t + ixheaacd_shr32(p_noise_level[0], exp_diff);
    356               }
    357             }
    358           }
    359           p_noise_level += 2;
    360           p_nrg_sine += 2;
    361         }
    362 
    363         {
    364           WORD32 norm_val;
    365           norm_val = 16 - ixheaacd_norm32(accu_m_t);
    366           if (norm_val > 0) {
    367             accu_m_t >>= norm_val;
    368             accu_e_t += norm_val;
    369           }
    370         }
    371 
    372         accu_m = (WORD16)accu_m_t;
    373         accu_e = (WORD16)accu_e_t;
    374 
    375         boost_gain_exp = ixheaacd_fix_mant_div(
    376             sum_orig_mant, accu_m, &boost_gain_mant, pstr_common_tables);
    377 
    378         boost_gain_exp += (sum_orig_exp - accu_e) + 1;
    379 
    380         if ((boost_gain_exp > 2) ||
    381             ((boost_gain_exp == 2) && (boost_gain_mant > 0x5061))) {
    382           boost_gain_mant = 0x5061;
    383           boost_gain_exp = 2;
    384         }
    385 
    386         ptr_nrg_gain = &nrg_gain[2 * start_band];
    387         p_noise_level = &noise_level_mant[2 * start_band];
    388         p_nrg_sine = &nrg_sine[2 * start_band];
    389 
    390         for (k = stop_band - start_band; k != 0; k--) {
    391           WORD16 temp1, temp2, temp3;
    392 
    393           temp1 = *ptr_nrg_gain;
    394           temp2 = *p_nrg_sine;
    395           temp3 = *p_noise_level;
    396 
    397           temp1 = ixheaacd_mult16_shl(temp1, boost_gain_mant);
    398           temp2 = ixheaacd_mult16_shl(temp2, boost_gain_mant);
    399           temp3 = ixheaacd_mult16_shl(temp3, boost_gain_mant);
    400           *ptr_nrg_gain++ = temp1;
    401           *p_nrg_sine++ = temp2;
    402           *p_noise_level++ = temp3;
    403 
    404           temp1 = *ptr_nrg_gain;
    405           temp2 = *p_nrg_sine;
    406           temp3 = *p_noise_level;
    407 
    408           temp1 = (temp1 + boost_gain_exp);
    409           temp2 = (temp2 + boost_gain_exp);
    410           temp3 = (temp3 + boost_gain_exp);
    411           *ptr_nrg_gain++ = (temp1);
    412           *p_nrg_sine++ = (temp2);
    413           *p_noise_level++ = (temp3);
    414         }
    415       }
    416     }
    417   }
    418 }
    419 
    420 VOID ixheaacd_conv_ergtoamplitudelp_dec(WORD32 bands, WORD16 noise_e,
    421                                         WORD16 *nrg_sine, WORD16 *nrg_gain,
    422                                         WORD16 *noise_level_mant,
    423                                         WORD16 *sqrt_table) {
    424   WORD32 k;
    425   for (k = 0; k < bands; k++) {
    426     WORD32 shift;
    427     ixheaacd_fix_mant_exp_sqrt(&nrg_sine[2 * k], sqrt_table);
    428     ixheaacd_fix_mant_exp_sqrt(&nrg_gain[2 * k], sqrt_table);
    429     ixheaacd_fix_mant_exp_sqrt(&noise_level_mant[2 * k], sqrt_table);
    430 
    431     shift = (noise_e - noise_level_mant[2 * k + 1]);
    432 
    433     shift = (shift - 4);
    434     if (shift > 0)
    435       noise_level_mant[2 * k] = (noise_level_mant[2 * k] >> shift);
    436     else
    437       noise_level_mant[2 * k] = (noise_level_mant[2 * k] << -shift);
    438 
    439     shift = (nrg_sine[2 * k + 1] - noise_e);
    440     if (shift > 0)
    441       nrg_sine[2 * k] = ixheaacd_shl16_sat(nrg_sine[2 * k], (WORD16)shift);
    442     else
    443       nrg_sine[2 * k] = ixheaacd_shr16(nrg_sine[2 * k], (WORD16)-shift);
    444   }
    445 }
    446 
    447 VOID ixheaacd_conv_ergtoamplitude_dec(WORD32 bands, WORD16 noise_e,
    448                                       WORD16 *nrg_sine, WORD16 *nrg_gain,
    449                                       WORD16 *noise_level_mant,
    450                                       WORD16 *sqrt_table) {
    451   WORD32 k;
    452   for (k = 0; k < bands; k++) {
    453     WORD32 shift;
    454 
    455     ixheaacd_fix_mant_exp_sqrt(&nrg_sine[2 * k], sqrt_table);
    456     ixheaacd_fix_mant_exp_sqrt(&nrg_gain[2 * k], sqrt_table);
    457     ixheaacd_fix_mant_exp_sqrt(&noise_level_mant[2 * k], sqrt_table);
    458 
    459     shift = (noise_e - noise_level_mant[2 * k + 1]);
    460 
    461     shift = (shift - 4);
    462     if (shift > 0)
    463       noise_level_mant[2 * k] = (noise_level_mant[2 * k] >> shift);
    464     else
    465       noise_level_mant[2 * k] = (noise_level_mant[2 * k] << -shift);
    466   }
    467 }
    468 
    469 static PLATFORM_INLINE VOID ixheaacd_adapt_noise_gain_calc(
    470     ia_sbr_calc_env_struct *ptr_sbr_calc_env, WORD32 noise_e,
    471     WORD32 num_sub_bands, WORD32 skip_bands, WORD16 *nrg_gain,
    472     WORD16 *noise_level_mant, WORD16 *nrg_sine, WORD32 start_pos,
    473     WORD32 end_pos, WORD32 input_e, WORD32 adj_e, WORD32 final_e,
    474     WORD32 sub_band_start, WORD32 lb_scale, FLAG noise_absc_flag,
    475     WORD32 smooth_length, WORD32 **anal_buf_real_mant,
    476     WORD32 **anal_buf_imag_mant, WORD32 low_pow_flag,
    477     ia_sbr_tables_struct *ptr_sbr_tables) {
    478   WORD32 l, k;
    479   WORD32 scale_change;
    480   WORD32 bands = num_sub_bands - skip_bands;
    481   WORD16 *ptr_filt_buf;
    482   WORD16 *ptr_filt_buf_noise;
    483   WORD16 *ptr_gain = &nrg_gain[0];
    484 
    485   if (ptr_sbr_calc_env->start_up) {
    486     WORD16 *ptr_noise = noise_level_mant;
    487     ptr_sbr_calc_env->start_up = 0;
    488 
    489     ptr_sbr_calc_env->filt_buf_noise_e = noise_e;
    490     ptr_filt_buf = &ptr_sbr_calc_env->filt_buf_me[skip_bands * 2];
    491     ptr_filt_buf_noise = &ptr_sbr_calc_env->filt_buf_noise_m[skip_bands];
    492 
    493     for (k = bands; k != 0; k--) {
    494       WORD16 temp1 = *ptr_gain++;
    495       WORD16 temp2 = *ptr_gain++;
    496       WORD16 temp3 = *ptr_noise;
    497       ptr_noise += 2;
    498 
    499       *ptr_filt_buf++ = temp1;
    500       *ptr_filt_buf++ = temp2;
    501       *ptr_filt_buf_noise++ = temp3;
    502     }
    503   } else {
    504     ixheaacd_equalize_filt_buff_exp(
    505         &ptr_sbr_calc_env->filt_buf_me[2 * skip_bands], nrg_gain, bands);
    506   }
    507 
    508   for (l = start_pos; l < end_pos; l++) {
    509     if ((l < MAX_COLS)) {
    510       scale_change = (adj_e - input_e);
    511     } else {
    512       scale_change = (final_e - input_e);
    513 
    514       if (((l == MAX_COLS)) && ((start_pos < MAX_COLS))) {
    515         WORD32 diff = final_e - noise_e;
    516         noise_e = final_e;
    517         ixheaacd_noise_level_rescaling(noise_level_mant, diff, bands, 2);
    518       }
    519     }
    520 
    521     ixheaacd_noise_level_rescaling(ptr_sbr_calc_env->filt_buf_noise_m,
    522                                    ptr_sbr_calc_env->filt_buf_noise_e - noise_e,
    523                                    num_sub_bands, 1);
    524 
    525     ptr_sbr_calc_env->filt_buf_noise_e = noise_e;
    526 
    527     {
    528       WORD32 *anal_buf_real_m_l;
    529       anal_buf_real_m_l = anal_buf_real_mant[l];
    530 
    531       if (low_pow_flag) {
    532         WORD32 index = ptr_sbr_calc_env->ph_index;
    533         WORD32 harm_index = ptr_sbr_calc_env->harm_index;
    534         WORD32 freq_inv_flag = (sub_band_start & 1);
    535         WORD32 *ptr_real_buf = &anal_buf_real_m_l[sub_band_start];
    536 
    537         const WORD32 *ptr_rand_ph = &ptr_sbr_tables->sbr_rand_ph[index + 1];
    538 
    539         ptr_sbr_calc_env->ph_index =
    540             (WORD16)((index + num_sub_bands) & (SBR_NF_NO_RANDOM_VAL - 1));
    541         ptr_sbr_calc_env->harm_index = (WORD16)(((harm_index + 1)) & 3);
    542 
    543         if (!(harm_index & 0x1)) {
    544           (*ixheaacd_harm_idx_zerotwolp)(
    545               ptr_real_buf, nrg_gain, scale_change, nrg_sine, ptr_rand_ph,
    546               noise_level_mant, num_sub_bands, noise_absc_flag, harm_index);
    547         } else {
    548           WORD32 noise = (noise_e - 16) - lb_scale;
    549 
    550           freq_inv_flag = (!freq_inv_flag);
    551           freq_inv_flag = (freq_inv_flag << 1) - 1;
    552 
    553           if (harm_index == 3) freq_inv_flag = -freq_inv_flag;
    554 
    555           ixheaacd_harm_idx_onethreelp(ptr_real_buf, nrg_gain, scale_change,
    556                                        nrg_sine, ptr_rand_ph, noise_level_mant,
    557                                        num_sub_bands, noise_absc_flag,
    558                                        freq_inv_flag, noise, sub_band_start);
    559         }
    560 
    561       } else {
    562         WORD16 smooth_ratio;
    563         WORD32 *anal_buf_imag_m_l;
    564         anal_buf_imag_m_l = anal_buf_imag_mant[l];
    565 
    566         if (((l - start_pos) < smooth_length)) {
    567           smooth_ratio = ptr_sbr_tables->env_calc_tables_ptr
    568                              ->sbr_smooth_filter[(l - start_pos)];
    569         } else {
    570           smooth_ratio = 0;
    571         }
    572 
    573         ixheaacd_adj_timeslot(
    574             &anal_buf_real_m_l[sub_band_start],
    575             &anal_buf_imag_m_l[sub_band_start],
    576             &ptr_sbr_calc_env->filt_buf_me[2 * skip_bands],
    577             &ptr_sbr_calc_env->filt_buf_noise_m[skip_bands], nrg_gain,
    578             noise_level_mant, nrg_sine, (WORD16)(noise_e - 16),
    579             &ptr_sbr_calc_env->harm_index, (WORD16)sub_band_start,
    580             (WORD16)(bands), (WORD16)scale_change, smooth_ratio,
    581             noise_absc_flag, &ptr_sbr_calc_env->ph_index, ptr_sbr_tables);
    582       }
    583     }
    584   }
    585 
    586   ixheaacd_filt_buf_update(ptr_sbr_calc_env->filt_buf_me + 2 * skip_bands,
    587                            ptr_sbr_calc_env->filt_buf_noise_m + skip_bands,
    588                            nrg_gain, noise_level_mant, bands);
    589 }
    590 
    591 VOID ixheaacd_calc_subband_gains(ia_freq_band_data_struct *pstr_freq_band_data,
    592                                  ia_sbr_frame_info_data_struct *ptr_frame_data,
    593                                  WORD32 freq_res, WORD16 *ptr_noise_floor,
    594                                  WORD32 num_sf_bands, WORD32 mvalue, WORD32 env,
    595                                  WORD8 *sine_mapped_matrix,
    596                                  WORD8 *alias_red_buf, WORD16 *ptr_enrg_orig,
    597                                  WORD16 *nrg_sine, WORD16 *nrg_est,
    598                                  WORD16 *nrg_gain, WORD16 *noise_level_mant,
    599                                  FLAG noise_absc_flag,
    600                                  ixheaacd_misc_tables *pstr_common_tables) {
    601   WORD16 *ptr_freq_band_tbl = pstr_freq_band_data->freq_band_table[freq_res];
    602   WORD32 ui_noise = pstr_freq_band_data->freq_band_tbl_noise[1];
    603   WORD32 nb_idx = 0;
    604   WORD16 tmp_noise_mant;
    605   WORD16 tmp_noise_exp;
    606   WORD8 *ptr_sine_mapped = sine_mapped_matrix;
    607   WORD32 sub_band_start = pstr_freq_band_data->sub_band_start;
    608   WORD32 skip_bands = (ptr_frame_data->max_qmf_subband_aac - sub_band_start);
    609   WORD8 *ptr_sine_mapped_1 = &sine_mapped_matrix[skip_bands];
    610   WORD32 k, c = 0, j;
    611 
    612   WORD16 *ptr_env_sf_arr = &ptr_frame_data->int_env_sf_arr[mvalue];
    613   WORD8 *ptr_alias_red_buf =
    614       &alias_red_buf[ptr_freq_band_tbl[0] - sub_band_start];
    615 
    616   tmp_noise_mant = (WORD16)(ptr_noise_floor[nb_idx] & MASK_M);
    617   tmp_noise_exp =
    618       (WORD16)(ptr_noise_floor[nb_idx] & MASK_FOR_EXP) - NOISE_EXP_OFFSET;
    619 
    620   for (j = 0; j < num_sf_bands; j++) {
    621     WORD8 sine_present_flag;
    622     WORD16 tmp_nrg_ref_exp, tmp_nrg_ref_mant;
    623     WORD16 li = *ptr_freq_band_tbl++;
    624     WORD16 ui = *ptr_freq_band_tbl;
    625     WORD16 env_sf_val = *ptr_env_sf_arr++;
    626 
    627     tmp_nrg_ref_exp =
    628         (WORD16)((env_sf_val & (WORD16)MASK_FOR_EXP) - NRG_EXP_OFFSET);
    629     tmp_nrg_ref_mant = (WORD16)(env_sf_val & MASK_M);
    630 
    631     sine_present_flag = 0;
    632     for (k = li; k < ui; k++) {
    633       if ((env >= *ptr_sine_mapped++)) sine_present_flag = 1;
    634     }
    635     for (k = li; k < ui; k++) {
    636       *ptr_alias_red_buf++ = !sine_present_flag;
    637 
    638       if ((k >= ui_noise)) {
    639         nb_idx++;
    640         ui_noise = pstr_freq_band_data->freq_band_tbl_noise[nb_idx + 1];
    641         tmp_noise_mant = (WORD16)(ptr_noise_floor[nb_idx] & MASK_M);
    642         tmp_noise_exp =
    643             (WORD16)(ptr_noise_floor[nb_idx] & MASK_FOR_EXP) - NOISE_EXP_OFFSET;
    644       }
    645 
    646       if ((k >= ptr_frame_data->max_qmf_subband_aac)) {
    647         ptr_enrg_orig[2 * c] = tmp_nrg_ref_mant;
    648         ptr_enrg_orig[2 * c + 1] = tmp_nrg_ref_exp;
    649         nrg_sine[2 * c] = 0;
    650         nrg_sine[2 * c + 1] = 0;
    651 
    652         ixheaacd_subbandgain_calc(
    653             tmp_nrg_ref_mant, tmp_noise_mant, nrg_est[2 * c],
    654             nrg_est[2 * c + 1], tmp_noise_exp, tmp_nrg_ref_exp,
    655             sine_present_flag,
    656             (env >= ptr_sine_mapped_1[c]) ? (FLAG)1 : (FLAG)0, noise_absc_flag,
    657             &nrg_gain[2 * c], &noise_level_mant[2 * c], &nrg_sine[2 * c],
    658             pstr_common_tables);
    659         c++;
    660       }
    661     }
    662   }
    663 }
    664 
    665 #define ALIGN_SIZE64(x) ((((x) + 7) >> 3) << 3)
    666 
    667 VOID ixheaacd_calc_sbrenvelope(
    668     ia_sbr_scale_fact_struct *ptr_sbr_scale_fac,
    669     ia_sbr_calc_env_struct *ptr_sbr_calc_env,
    670     ia_sbr_header_data_struct *ptr_header_data,
    671     ia_sbr_frame_info_data_struct *ptr_frame_data,
    672     ia_sbr_prev_frame_data_struct *ptr_frame_data_prev,
    673     WORD32 **anal_buf_real_mant, WORD32 **anal_buf_imag_mant,
    674     WORD16 *deg_patched, FLAG low_pow_flag,
    675     ia_sbr_tables_struct *ptr_sbr_tables,
    676     ixheaacd_misc_tables *pstr_common_tables, WORD32 *ptr_qmf_matrix,
    677     WORD32 audio_object_type) {
    678   WORD32 i, j, m;
    679   WORD32 noise_floor_idx;
    680   WORD32 start_pos, end_pos;
    681   WORD32 freq_res;
    682   WORD32 num_env = ptr_frame_data->str_frame_info_details.num_env;
    683   WORD16 *ptr_border_vec = ptr_frame_data->str_frame_info_details.border_vec;
    684 
    685   WORD16 *ptr_noise_floor;
    686   ia_freq_band_data_struct *pstr_freq_band_data =
    687       ptr_header_data->pstr_freq_band_data;
    688 
    689   FLAG noise_absc_flag;
    690   WORD32 smooth_length;
    691 
    692   const WORD16 *num_sf_bands = pstr_freq_band_data->num_sf_bands;
    693   const WORD32 num_nf_bands = pstr_freq_band_data->num_nf_bands;
    694 
    695   WORD32 sub_band_start = pstr_freq_band_data->sub_band_start;
    696   WORD32 sub_band_end = pstr_freq_band_data->sub_band_end;
    697   WORD32 num_sub_bands;
    698   WORD32 skip_bands;
    699   WORD32 bands;
    700 
    701   WORD num_cols;
    702   WORD32 first_start;
    703 
    704   WORD16 *ptr_sbr_lim_gain;
    705   WORD32 max_sfb_nrg_exp;
    706 
    707   WORD16 *ptr_enrg_orig;
    708 
    709   WORD32 input_e;
    710   WORD32 ov_adj_e;
    711   WORD32 adj_e;
    712   WORD32 output_e;
    713   WORD32 final_e;
    714   WORD16 noise_e;
    715   WORD16 lb_scale;
    716 
    717   WORD16 nrg_est[2 * MAX_FREQ_COEFFS];
    718 
    719   WORD16 nrg_gain[2 * MAX_FREQ_COEFFS];
    720   WORD16 noise_level_mant[2 * MAX_FREQ_COEFFS];
    721   WORD16 nrg_sine[2 * MAX_FREQ_COEFFS];
    722 
    723   WORD8 sine_mapped_matrix[MAX_FREQ_COEFFS];
    724   WORD8 alias_red_buf[64];
    725 
    726   ptr_noise_floor = ptr_frame_data->int_noise_floor;
    727 
    728   ptr_enrg_orig =
    729       (WORD16 *)((WORD8 *)ptr_frame_data +
    730                  ALIGN_SIZE64(sizeof(ia_sbr_frame_info_data_struct)));
    731 
    732   num_env = ptr_frame_data->str_frame_info_details.num_env;
    733   ptr_border_vec = ptr_frame_data->str_frame_info_details.border_vec;
    734   num_sub_bands = (sub_band_end - sub_band_start);
    735   skip_bands = (ptr_frame_data->max_qmf_subband_aac - sub_band_start);
    736 
    737   ixheaacd_map_sineflags(
    738       pstr_freq_band_data->freq_band_table[HIGH],
    739       pstr_freq_band_data->num_sf_bands[HIGH], ptr_frame_data->add_harmonics,
    740       ptr_sbr_calc_env->harm_flags_prev,
    741       ptr_frame_data->str_frame_info_details.transient_env, sine_mapped_matrix);
    742 
    743   adj_e = 0;
    744   {
    745     WORD16 max_noise;
    746     WORD32 first_band;
    747 
    748     if (ptr_frame_data_prev->max_qmf_subband_aac >
    749         ptr_frame_data->max_qmf_subband_aac)
    750       first_band = (ptr_frame_data_prev->max_qmf_subband_aac - sub_band_start);
    751     else
    752       first_band = (ptr_frame_data->max_qmf_subband_aac - sub_band_start);
    753 
    754     max_noise = 0;
    755     for (i = first_band; i < num_sub_bands; i++) {
    756       if (ptr_sbr_calc_env->filt_buf_noise_m[i] > max_noise) {
    757         max_noise = ptr_sbr_calc_env->filt_buf_noise_m[i];
    758       }
    759     }
    760     adj_e = ((ptr_sbr_calc_env->filt_buf_noise_e - ixheaacd_norm32(max_noise)) -
    761              16);
    762   }
    763 
    764   final_e = 0;
    765   {
    766     WORD16 *ptr_env_sf_buf = ptr_frame_data->int_env_sf_arr;
    767     for (i = 0; i < num_env; i++) {
    768       WORD32 temp_val;
    769 
    770       max_sfb_nrg_exp = NRG_EXP_OFFSET - SHORT_BITS;
    771 
    772       freq_res = ptr_frame_data->str_frame_info_details.freq_res[i];
    773 
    774       for (j = 0; j < num_sf_bands[freq_res]; j++) {
    775         temp_val = ((*ptr_env_sf_buf++ & MASK_FOR_EXP));
    776 
    777         if ((temp_val > max_sfb_nrg_exp)) {
    778           max_sfb_nrg_exp = temp_val;
    779         }
    780       }
    781 
    782       max_sfb_nrg_exp = (max_sfb_nrg_exp - NRG_EXP_OFFSET);
    783 
    784       temp_val = ((max_sfb_nrg_exp + 13) >> 1);
    785 
    786       if ((ptr_border_vec[i] < SBR_TIME_SLOTS)) {
    787         if ((temp_val > adj_e)) {
    788           adj_e = (WORD16)temp_val;
    789         }
    790       }
    791 
    792       if ((ptr_border_vec[i + 1] > SBR_TIME_SLOTS)) {
    793         if ((temp_val > final_e)) {
    794           final_e = (WORD16)temp_val;
    795         }
    796       }
    797     }
    798   }
    799 
    800   m = 0;
    801   noise_floor_idx = 0;
    802 
    803   for (i = 0; i < num_env; i++) {
    804     if (audio_object_type == AOT_ER_AAC_ELD ||
    805         audio_object_type == AOT_ER_AAC_LD) {
    806       start_pos = ptr_border_vec[i];
    807       end_pos = ptr_border_vec[i + 1];
    808     } else {
    809       start_pos = SBR_TIME_STEP * ptr_border_vec[i];
    810       end_pos = SBR_TIME_STEP * ptr_border_vec[i + 1];
    811     }
    812     freq_res = ptr_frame_data->str_frame_info_details.freq_res[i];
    813 
    814     if (ptr_border_vec[i] ==
    815         ptr_frame_data->str_frame_info_details
    816             .noise_border_vec[noise_floor_idx + 1]) {
    817       ptr_noise_floor += num_nf_bands;
    818       noise_floor_idx++;
    819     }
    820 
    821     if ((i == ptr_frame_data->str_frame_info_details.transient_env) ||
    822         (i == ptr_sbr_calc_env->tansient_env_prev)) {
    823       noise_absc_flag = 1;
    824       smooth_length = 0;
    825     } else {
    826       noise_absc_flag = 0;
    827       smooth_length = ((1 - ptr_header_data->smoothing_mode) << 2);
    828     }
    829 
    830     input_e = 15 - ptr_sbr_scale_fac->hb_scale;
    831 
    832     if (ptr_header_data->interpol_freq) {
    833       (*ixheaacd_enery_calc_per_subband)(
    834           start_pos, end_pos, ptr_frame_data->max_qmf_subband_aac, sub_band_end,
    835           input_e, nrg_est, low_pow_flag, ptr_sbr_tables, ptr_qmf_matrix);
    836     } else {
    837       ixheaacd_enery_calc_persfb(
    838           anal_buf_real_mant, anal_buf_imag_mant, num_sf_bands[freq_res],
    839           pstr_freq_band_data->freq_band_table[freq_res], start_pos, end_pos,
    840           ptr_frame_data->max_qmf_subband_aac, input_e, nrg_est, low_pow_flag,
    841           ptr_sbr_tables);
    842     }
    843 
    844     ixheaacd_calc_subband_gains(
    845         pstr_freq_band_data, ptr_frame_data, freq_res, ptr_noise_floor,
    846         num_sf_bands[freq_res], m, i, sine_mapped_matrix, alias_red_buf,
    847         ptr_enrg_orig, nrg_sine, nrg_est, nrg_gain, noise_level_mant,
    848         noise_absc_flag, pstr_common_tables);
    849 
    850     m += num_sf_bands[freq_res];
    851 
    852     ptr_sbr_lim_gain =
    853         &ptr_sbr_tables->env_calc_tables_ptr
    854              ->sbr_lim_gains_m[2 * ptr_header_data->limiter_gains];
    855     ixheaacd_noiselimiting(pstr_freq_band_data, skip_bands, ptr_enrg_orig,
    856                            nrg_est, nrg_gain, noise_level_mant, nrg_sine,
    857                            ptr_sbr_lim_gain, noise_absc_flag,
    858                            pstr_common_tables);
    859 
    860     if (low_pow_flag) {
    861       ixheaacd_alias_reduction(deg_patched + sub_band_start, nrg_gain, nrg_est,
    862                                alias_red_buf, num_sub_bands,
    863                                pstr_common_tables);
    864     }
    865 
    866     if ((start_pos < MAX_COLS)) {
    867       noise_e = adj_e;
    868     } else {
    869       noise_e = final_e;
    870     }
    871 
    872     bands = num_sub_bands - skip_bands;
    873 
    874     if (low_pow_flag) {
    875       (*ixheaacd_conv_ergtoamplitudelp)(
    876           bands, noise_e, nrg_sine, nrg_gain, noise_level_mant,
    877           (WORD16 *)pstr_common_tables->sqrt_table);
    878     } else
    879 
    880     {
    881       (*ixheaacd_conv_ergtoamplitude)(bands, noise_e, nrg_sine, nrg_gain,
    882                                       noise_level_mant,
    883                                       (WORD16 *)pstr_common_tables->sqrt_table);
    884     }
    885 
    886     lb_scale = ixheaacd_sub16(15, ptr_sbr_scale_fac->lb_scale);
    887 
    888     ixheaacd_adapt_noise_gain_calc(
    889         ptr_sbr_calc_env, noise_e, num_sub_bands, skip_bands, nrg_gain,
    890         noise_level_mant, nrg_sine, start_pos, end_pos, input_e, adj_e, final_e,
    891         ptr_frame_data->max_qmf_subband_aac, lb_scale, noise_absc_flag,
    892         smooth_length, anal_buf_real_mant, anal_buf_imag_mant, low_pow_flag,
    893         ptr_sbr_tables);
    894   }
    895 
    896   first_start = ptr_border_vec[0] * SBR_TIME_STEP;
    897   {
    898     WORD32 ov_reserve, reserve;
    899 
    900     ov_reserve = reserve = 0;
    901 
    902     if (audio_object_type != AOT_ER_AAC_ELD) {
    903       if (ptr_header_data->channel_mode == PS_STEREO) {
    904         ov_reserve = (*ixheaacd_ixheaacd_expsubbandsamples)(
    905             anal_buf_real_mant, anal_buf_imag_mant,
    906             ptr_frame_data->max_qmf_subband_aac, sub_band_end, 0, first_start,
    907             low_pow_flag);
    908 
    909         reserve = (*ixheaacd_ixheaacd_expsubbandsamples)(
    910             anal_buf_real_mant, anal_buf_imag_mant,
    911             ptr_frame_data->max_qmf_subband_aac, sub_band_end, first_start,
    912             MAX_COLS, low_pow_flag);
    913       }
    914     }
    915 
    916     output_e = 0;
    917 
    918     ov_adj_e = 15 - ptr_sbr_scale_fac->ov_hb_scale;
    919 
    920     if (((ov_adj_e - ov_reserve) > (adj_e - reserve)))
    921       output_e = (ov_adj_e - ov_reserve);
    922     else
    923       output_e = (adj_e - reserve);
    924 
    925     (*ixheaacd_adjust_scale)(anal_buf_real_mant, anal_buf_imag_mant,
    926                              ptr_frame_data->max_qmf_subband_aac, sub_band_end,
    927                              0, first_start, (ov_adj_e - output_e),
    928                              low_pow_flag);
    929 
    930     num_cols = (ptr_header_data->num_time_slots * ptr_header_data->time_step);
    931 
    932     (*ixheaacd_adjust_scale)(anal_buf_real_mant, anal_buf_imag_mant,
    933                              ptr_frame_data->max_qmf_subband_aac, sub_band_end,
    934                              first_start, num_cols, (adj_e - output_e),
    935                              low_pow_flag);
    936   }
    937 
    938   ptr_sbr_scale_fac->hb_scale = (WORD16)(15 - output_e);
    939 
    940   ptr_sbr_scale_fac->ov_hb_scale = (WORD16)(15 - final_e);
    941 
    942   if (ptr_frame_data->str_frame_info_details.transient_env == num_env) {
    943     ptr_sbr_calc_env->tansient_env_prev = 0;
    944   } else {
    945     ptr_sbr_calc_env->tansient_env_prev = -1;
    946   }
    947 }
    948 
    949 VOID ixheaacd_equalize_filt_buff_exp(WORD16 *ptr_filt_buf, WORD16 *nrg_gain,
    950                                      WORD32 subbands) {
    951   WORD32 band;
    952   WORD32 diff;
    953   WORD32 gain_m, gain_e;
    954   WORD32 filt_buf_mant, filt_buf_exp;
    955 
    956   for (band = subbands - 1; band >= 0; band--) {
    957     filt_buf_exp = *(ptr_filt_buf + 1);
    958     gain_e = *(nrg_gain + 1);
    959     filt_buf_mant = *ptr_filt_buf;
    960     gain_m = *nrg_gain;
    961     diff = (gain_e - filt_buf_exp);
    962 
    963     if (diff >= 0) {
    964       *(ptr_filt_buf + 1) = (WORD16)(gain_e);
    965 
    966       *ptr_filt_buf = (WORD16)(*ptr_filt_buf >> diff);
    967     } else {
    968       WORD32 reserve;
    969       reserve = (ixheaacd_norm32(filt_buf_mant) - 16);
    970 
    971       if ((diff + reserve) >= 0) {
    972         *ptr_filt_buf = (WORD16)(filt_buf_mant << -diff);
    973         *(ptr_filt_buf + 1) = (WORD16)(filt_buf_exp + diff);
    974       } else {
    975         WORD32 shift;
    976 
    977         *ptr_filt_buf = (WORD16)(filt_buf_mant << reserve);
    978 
    979         *(ptr_filt_buf + 1) = (WORD16)(filt_buf_exp - reserve);
    980 
    981         shift = -(reserve + diff);
    982 
    983         *nrg_gain = (WORD16)(gain_m >> shift);
    984         *(nrg_gain + 1) = (WORD16)(*(nrg_gain + 1) + shift);
    985       }
    986     }
    987     nrg_gain += 2;
    988     ptr_filt_buf += 2;
    989   }
    990 }
    991 
    992 PLATFORM_INLINE VOID ixheaacd_filt_buf_update(WORD16 *ptr_filt_buf,
    993                                               WORD16 *ptr_filt_buf_noise,
    994                                               WORD16 *nrg_gain,
    995                                               WORD16 *noise_level_mant,
    996                                               WORD32 num_sub_bands) {
    997   WORD32 k;
    998   WORD32 temp1, temp2;
    999 
   1000   for (k = num_sub_bands - 1; k >= 0; k--) {
   1001     temp1 = *nrg_gain;
   1002     nrg_gain += 2;
   1003     temp2 = *noise_level_mant;
   1004     noise_level_mant += 2;
   1005 
   1006     *ptr_filt_buf = temp1;
   1007     ptr_filt_buf += 2;
   1008     *ptr_filt_buf_noise++ = temp2;
   1009   }
   1010 }
   1011 
   1012 VOID ixheaacd_noise_level_rescaling(WORD16 *noise_level_mant, WORD32 diff,
   1013                                     WORD32 num_sub_bands,
   1014                                     WORD32 ixheaacd_drc_offset) {
   1015   WORD32 k;
   1016 
   1017   if (diff > 0) {
   1018     for (k = num_sub_bands - 1; k >= 0; k--) {
   1019       *noise_level_mant = *noise_level_mant >> diff;
   1020       noise_level_mant += ixheaacd_drc_offset;
   1021     }
   1022   } else if (diff < 0) {
   1023     diff = -diff;
   1024     for (k = num_sub_bands - 1; k >= 0; k--) {
   1025       *noise_level_mant = *noise_level_mant << diff;
   1026       noise_level_mant += ixheaacd_drc_offset;
   1027     }
   1028   }
   1029 }
   1030 
   1031 VOID ixheaacd_adjust_scale_dec(WORD32 **re, WORD32 **im, WORD32 sub_band_start,
   1032                                WORD32 sub_band_end, WORD32 start_pos,
   1033                                WORD32 next_pos, WORD32 shift,
   1034                                FLAG low_pow_flag) {
   1035   WORD32 k, l;
   1036 
   1037   if (shift != 0) {
   1038     WORD32 num_sub_bands = (sub_band_end - sub_band_start);
   1039 
   1040     shift = ixheaacd_min32(shift, 31);
   1041     shift = ixheaacd_max32(shift, -31);
   1042 
   1043     if (low_pow_flag) {
   1044       if (shift > 0) {
   1045         for (l = start_pos; l < next_pos; l++) {
   1046           WORD32 *ptr = re[l] + sub_band_start;
   1047           for (k = num_sub_bands - 1; k >= 0; k--) {
   1048             *ptr = (*ptr << shift);
   1049             ptr++;
   1050           }
   1051         }
   1052       } else {
   1053         shift = -shift;
   1054         for (l = start_pos; l < next_pos; l++) {
   1055           WORD32 *ptr = re[l] + sub_band_start;
   1056           for (k = num_sub_bands - 1; k >= 0; k--) {
   1057             *ptr = (*ptr >> shift);
   1058             ptr++;
   1059           }
   1060         }
   1061       }
   1062     } else {
   1063       if (shift > 0) {
   1064         for (l = start_pos; l < next_pos; l++) {
   1065           WORD32 *ptr = re[l] + sub_band_start;
   1066           WORD32 *pti = im[l] + sub_band_start;
   1067           for (k = num_sub_bands; k > 0; k--) {
   1068             *ptr = (*ptr << shift);
   1069             *pti = (*pti << shift);
   1070             pti++;
   1071             ptr++;
   1072           }
   1073         }
   1074       } else {
   1075         shift = -shift;
   1076         for (l = start_pos; l < next_pos; l++) {
   1077           WORD32 *ptr = re[l] + sub_band_start;
   1078           WORD32 *pti = im[l] + sub_band_start;
   1079           for (k = num_sub_bands; k > 0; k--) {
   1080             *ptr = (*ptr >> shift);
   1081             *pti = (*pti >> shift);
   1082             ptr++;
   1083             pti++;
   1084           }
   1085         }
   1086       }
   1087     }
   1088   }
   1089 }
   1090 
   1091 WORD16 ixheaacd_expsubbandsamples_dec(WORD32 **re, WORD32 **im,
   1092                                       WORD32 sub_band_start,
   1093                                       WORD32 sub_band_end, WORD32 start_pos,
   1094                                       WORD32 next_pos, FLAG low_pow_flag) {
   1095   WORD32 l, k;
   1096   WORD16 max_shift;
   1097 
   1098   WORD32 value;
   1099   WORD32 max_abs;
   1100   WORD32 num_sub_bands;
   1101 
   1102   WORD32 *ptr_real;
   1103   WORD32 *ptr_imag;
   1104 
   1105   max_abs = 1;
   1106   num_sub_bands = (sub_band_end - sub_band_start);
   1107 
   1108   if (low_pow_flag) {
   1109     for (l = start_pos; l < next_pos; l++) {
   1110       WORD32 temp_real;
   1111       ptr_real = re[l] + sub_band_start;
   1112       temp_real = *ptr_real++;
   1113       for (k = num_sub_bands; k > 0; k--) {
   1114         value = ixheaacd_abs32_nrm(temp_real);
   1115         max_abs |= value;
   1116         temp_real = *ptr_real++;
   1117       }
   1118     }
   1119     max_shift = ixheaacd_pnorm32(max_abs);
   1120   } else {
   1121     for (l = start_pos; l < next_pos; l++) {
   1122       ptr_real = re[l] + sub_band_start;
   1123       ptr_imag = im[l] + sub_band_start;
   1124 
   1125       for (k = num_sub_bands; k > 0; k--) {
   1126         WORD32 temp_real = *ptr_real++;
   1127         WORD32 tempIm = *ptr_imag++;
   1128 
   1129         temp_real = ixheaacd_abs32_nrm(temp_real);
   1130         max_abs |= temp_real;
   1131         tempIm = ixheaacd_abs32_nrm(tempIm);
   1132         max_abs |= tempIm;
   1133       }
   1134     }
   1135     max_shift = ixheaacd_pnorm32(max_abs);
   1136   }
   1137 
   1138   return max_shift;
   1139 }
   1140 
   1141 #define SHIFT_BEFORE_SQUARE 4
   1142 
   1143 VOID ixheaacd_enery_calc_per_subband_dec(WORD32 start_pos, WORD32 next_pos,
   1144                                          WORD32 sub_band_start,
   1145                                          WORD32 sub_band_end, WORD32 frame_exp,
   1146                                          WORD16 *nrg_est, FLAG low_pow_flag,
   1147                                          ia_sbr_tables_struct *ptr_sbr_tables,
   1148                                          WORD32 *ptr_qmf_matrix) {
   1149   WORD16 temp;
   1150   WORD16 inv_width;
   1151   WORD16 sum_m;
   1152   WORD32 accu;
   1153   WORD32 k, l;
   1154   WORD32 pre_shift_val;
   1155   WORD32 shift;
   1156   WORD32 *p_real;
   1157   WORD32 max_shift_gap = SHIFT_BEFORE_SQUARE;
   1158   WORD32 extra_shift = 0;
   1159   WORD32 num_cols = next_pos - start_pos;
   1160 
   1161   if (low_pow_flag) {
   1162     max_shift_gap -= 1;
   1163     p_real = ptr_qmf_matrix + sub_band_start + (start_pos << 6);
   1164     extra_shift++;
   1165   } else {
   1166     p_real = ptr_qmf_matrix + sub_band_start + (start_pos << 7);
   1167     num_cols = num_cols << 1;
   1168   }
   1169   inv_width = ptr_sbr_tables->env_calc_tables_ptr
   1170                   ->sbr_inv_int_table[(next_pos - start_pos)];
   1171   frame_exp = (frame_exp << 1);
   1172 
   1173   {
   1174     WORD32 *ptr;
   1175     for (k = sub_band_start; k < sub_band_end; k++) {
   1176       WORD32 max_val = 1;
   1177 
   1178       ptr = p_real;
   1179 
   1180       for (l = num_cols; l != 0; l -= 2) {
   1181         WORD32 value = ixheaacd_abs32_nrm(*ptr);
   1182         ptr += 64;
   1183         max_val = ixheaacd_max32(value, max_val);
   1184         value = ixheaacd_abs32_nrm(*ptr);
   1185         ptr += 64;
   1186         max_val = ixheaacd_max32(value, max_val);
   1187       }
   1188       pre_shift_val = (ixheaacd_pnorm32(max_val) - max_shift_gap);
   1189 
   1190       accu = 0L;
   1191       shift = 16 - pre_shift_val;
   1192       ptr = p_real;
   1193 
   1194       if (shift > 0)
   1195         for (l = num_cols; l != 0; l -= 2) {
   1196           temp = (WORD16)((*(ptr) >> shift));
   1197           ptr += 64;
   1198           accu += (temp * temp);
   1199           temp = (WORD16)((*(ptr) >> shift));
   1200           ptr += 64;
   1201           accu += (temp * temp);
   1202         }
   1203       else
   1204         for (l = num_cols; l != 0; l -= 2) {
   1205           temp = (WORD16)((*(ptr) << (-shift)));
   1206           ptr += 64;
   1207           accu += (temp * temp);
   1208           temp = (WORD16)((*(ptr) << (-shift)));
   1209           ptr += 64;
   1210           accu += (temp * temp);
   1211         }
   1212 
   1213       if (accu != 0L) {
   1214         shift = -(ixheaacd_pnorm32(accu));
   1215         sum_m = (WORD16)(ixheaacd_shr32_dir_sat_limit(accu, (16 + shift)));
   1216         *nrg_est++ = ixheaacd_mult16_shl_sat(sum_m, inv_width);
   1217         shift = (shift - (pre_shift_val << 1));
   1218         shift += extra_shift;
   1219         *nrg_est++ = (WORD16)(frame_exp + shift + 1);
   1220       } else {
   1221         *nrg_est++ = 0;
   1222         *nrg_est++ = 0;
   1223       }
   1224 
   1225       p_real++;
   1226     }
   1227   }
   1228 }
   1229 
   1230 VOID ixheaacd_enery_calc_persfb(WORD32 **anal_buf_real, WORD32 **anal_buf_imag,
   1231                                 WORD32 num_sf_bands, WORD16 *freq_band_table,
   1232                                 WORD32 start_pos, WORD32 next_pos,
   1233                                 WORD32 max_qmf_subband_aac, WORD32 frame_exp,
   1234                                 WORD16 *nrg_est, FLAG low_pow_flag,
   1235                                 ia_sbr_tables_struct *ptr_sbr_tables) {
   1236   WORD16 inv_width;
   1237   WORD32 pre_shift_val;
   1238   WORD32 shift;
   1239   WORD32 sum_e;
   1240   WORD16 sum_m;
   1241 
   1242   WORD32 j, k, l;
   1243   WORD32 li, ui;
   1244   WORD32 accu_line;
   1245   WORD32 accumulate;
   1246   WORD32 extra_shift = 10;
   1247 
   1248   inv_width = ptr_sbr_tables->env_calc_tables_ptr
   1249                   ->sbr_inv_int_table[(next_pos - start_pos)];
   1250 
   1251   frame_exp = (frame_exp << 1);
   1252 
   1253   if (low_pow_flag) extra_shift++;
   1254 
   1255   for (j = 0; j < num_sf_bands; j++) {
   1256     li = freq_band_table[j];
   1257 
   1258     if ((li >= max_qmf_subband_aac)) {
   1259       ui = freq_band_table[j + 1];
   1260 
   1261       pre_shift_val = (*ixheaacd_ixheaacd_expsubbandsamples)(
   1262           anal_buf_real, anal_buf_imag, li, ui, start_pos, next_pos,
   1263           low_pow_flag);
   1264 
   1265       pre_shift_val = (pre_shift_val - SHIFT_BEFORE_SQUARE);
   1266 
   1267       accumulate = 0;
   1268 
   1269       for (k = li; k < ui; k++) {
   1270         WORD32 pre_shift1 = (16 - pre_shift_val);
   1271         accu_line = 0L;
   1272         pre_shift1 = min(pre_shift1, 31);
   1273         {
   1274           WORD32 *ptr = &anal_buf_real[start_pos][k];
   1275           WORD32 inc = !low_pow_flag;
   1276           for (l = (next_pos - start_pos) << inc; l != 0; l--) {
   1277             WORD16 temp;
   1278             temp = ixheaacd_extract16l(ixheaacd_shr32_dir(*ptr, pre_shift1));
   1279             ptr += 64;
   1280             accu_line = ixheaacd_mac16x16in32(accu_line, temp, temp);
   1281           }
   1282         }
   1283         accumulate =
   1284             ixheaacd_add32_sat(accumulate, ixheaacd_shr32(accu_line, 9));
   1285       }
   1286 
   1287       shift = ixheaacd_pnorm32(accumulate);
   1288 
   1289       sum_m = ixheaacd_extract16l(
   1290           ixheaacd_shr32_dir_sat_limit(accumulate, (16 - shift)));
   1291 
   1292       if (sum_m == 0) {
   1293         sum_e = 0;
   1294       } else {
   1295         sum_m = ixheaacd_mult16_shl_sat(sum_m, inv_width);
   1296 
   1297         sum_m = ixheaacd_mult16_shl_sat(
   1298             sum_m,
   1299             ptr_sbr_tables->env_calc_tables_ptr->sbr_inv_int_table[ui - li]);
   1300 
   1301         sum_e = ((frame_exp + extra_shift) - shift);
   1302 
   1303         sum_e = (sum_e - (pre_shift_val << 1));
   1304       }
   1305 
   1306       for (k = li; k < ui; k++) {
   1307         *nrg_est++ = sum_m;
   1308         *nrg_est++ = (WORD16)sum_e;
   1309       }
   1310     }
   1311   }
   1312 }
   1313 
   1314 VOID ixheaacd_subbandgain_calc(WORD16 e_orig_mant_matrix, WORD16 tmp_noise_mant,
   1315                                WORD16 nrg_est_mant, WORD16 nrg_est_exp,
   1316                                WORD16 tmp_noise_exp, WORD16 nrg_ref_exp,
   1317                                FLAG sine_present_flag, FLAG sine_mapped_matrix,
   1318                                FLAG noise_absc_flag, WORD16 *ptr_nrg_gain_mant,
   1319                                WORD16 *ptr_noise_floor_mant,
   1320                                WORD16 *ptr_nrg_sine_m,
   1321                                ixheaacd_misc_tables *pstr_common_tables) {
   1322   WORD16 var1_mant;
   1323   WORD16 var1_exp;
   1324   WORD16 var2_mant;
   1325   WORD16 var2_exp;
   1326   WORD16 var3_mant;
   1327   WORD16 var3_exp;
   1328   WORD32 temp;
   1329 
   1330   if (nrg_est_mant == 0) {
   1331     nrg_est_mant = 0x4000;
   1332     nrg_est_exp = 1;
   1333   }
   1334 
   1335   var1_mant = ixheaacd_mult16_shl_sat(e_orig_mant_matrix, tmp_noise_mant);
   1336   var1_exp = (nrg_ref_exp + tmp_noise_exp);
   1337 
   1338   {
   1339     WORD32 accu, exp_diff;
   1340 
   1341     exp_diff = tmp_noise_exp - 1;
   1342 
   1343     if (exp_diff >= 0) {
   1344       accu = tmp_noise_mant + ixheaacd_shr32(0x4000, exp_diff);
   1345       var2_exp = tmp_noise_exp;
   1346     } else {
   1347       exp_diff = -exp_diff;
   1348       accu = ixheaacd_shr32((WORD32)tmp_noise_mant, exp_diff) + 0x4000;
   1349       var2_exp = 1;
   1350     }
   1351     if (ixheaacd_abs32(accu) >= 0x8000) {
   1352       accu = accu >> 1;
   1353       var2_exp++;
   1354     }
   1355     var2_mant = (WORD16)(accu);
   1356   }
   1357 
   1358   temp = ixheaacd_fix_mant_div(var1_mant, var2_mant, ptr_noise_floor_mant,
   1359                                pstr_common_tables);
   1360   *(ptr_noise_floor_mant + 1) = temp + (var1_exp - var2_exp) + 1;
   1361 
   1362   if (sine_present_flag || !noise_absc_flag) {
   1363     var3_mant = ixheaacd_mult16_shl_sat(var2_mant, nrg_est_mant);
   1364     var3_exp = (var2_exp + nrg_est_exp);
   1365   } else {
   1366     var3_mant = nrg_est_mant;
   1367     var3_exp = nrg_est_exp;
   1368   }
   1369 
   1370   if (sine_present_flag == 0) {
   1371     var1_mant = e_orig_mant_matrix;
   1372     var1_exp = nrg_ref_exp;
   1373   }
   1374 
   1375   temp = ixheaacd_fix_mant_div(var1_mant, var3_mant, ptr_nrg_gain_mant,
   1376                                pstr_common_tables);
   1377   *(ptr_nrg_gain_mant + 1) = temp + (var1_exp - var3_exp) + 1;
   1378 
   1379   if (sine_present_flag && sine_mapped_matrix) {
   1380     temp = ixheaacd_fix_mant_div(e_orig_mant_matrix, var2_mant, ptr_nrg_sine_m,
   1381                                  pstr_common_tables);
   1382     *(ptr_nrg_sine_m + 1) = temp + (nrg_ref_exp - var2_exp) + 1;
   1383   }
   1384 }
   1385 
   1386 VOID ixheaacd_avggain_calc(WORD16 *ptr_enrg_orig, WORD16 *nrg_est,
   1387                            WORD32 sub_band_start, WORD32 sub_band_end,
   1388                            WORD16 *ptr_enrg_orig_mant, WORD16 *ptr_sum_ref_exp,
   1389                            WORD16 *ptr_avg_gain_mant, WORD16 *ptr_avg_gain_exp,
   1390                            ixheaacd_misc_tables *pstr_common_tables,
   1391                            WORD32 flag) {
   1392   WORD16 sum_orig_mant;
   1393   WORD16 sum_orig_exp;
   1394   WORD16 sum_est_mant;
   1395   WORD16 sum_est_exp;
   1396 
   1397   WORD32 accu_sum_orig_mant;
   1398   WORD32 accu_sum_orig_exp;
   1399   WORD32 accu_sum_est_mant;
   1400   WORD32 accu_sum_est_exp;
   1401 
   1402   WORD32 k, temp;
   1403   WORD16 *ptr_enrg_orig_buf;
   1404   WORD16 *ptr_enrg_est_buf;
   1405 
   1406   {
   1407     accu_sum_orig_mant = 0;
   1408     accu_sum_orig_exp = 0;
   1409 
   1410     accu_sum_est_mant = 0;
   1411     accu_sum_est_exp = 0;
   1412   }
   1413 
   1414   ptr_enrg_orig_buf = &ptr_enrg_orig[sub_band_start << 1];
   1415   ptr_enrg_est_buf = &nrg_est[sub_band_start << 1];
   1416 
   1417   for (k = sub_band_end - sub_band_start; k != 0; k--) {
   1418     WORD16 tmp_mant, tmp_e;
   1419     WORD16 tmp2_m, tmp2_e;
   1420 
   1421     tmp_mant = *ptr_enrg_orig_buf++;
   1422     tmp_e = *ptr_enrg_orig_buf++;
   1423     tmp2_m = *ptr_enrg_est_buf++;
   1424     tmp2_e = *ptr_enrg_est_buf++;
   1425     {
   1426       WORD32 exp_diff;
   1427       exp_diff = tmp_e - accu_sum_orig_exp;
   1428       if (exp_diff >= 0) {
   1429         accu_sum_orig_mant =
   1430             tmp_mant + ixheaacd_shr32(accu_sum_orig_mant, exp_diff);
   1431         accu_sum_orig_exp = tmp_e;
   1432       } else {
   1433         exp_diff = -exp_diff;
   1434         accu_sum_orig_mant =
   1435             ixheaacd_shr32(tmp_mant, exp_diff) + accu_sum_orig_mant;
   1436       }
   1437     }
   1438     if (flag) {
   1439       tmp_mant = (tmp_mant * tmp2_m) >> 16;
   1440       tmp_e = (tmp_e + tmp2_e + 1);
   1441 
   1442     } else {
   1443       tmp_mant = tmp2_m;
   1444       tmp_e = tmp2_e;
   1445     }
   1446 
   1447     {
   1448       WORD32 exp_diff;
   1449       exp_diff = tmp_e - accu_sum_est_exp;
   1450       if (exp_diff >= 0) {
   1451         accu_sum_est_mant =
   1452             tmp_mant + ixheaacd_shr32(accu_sum_est_mant, exp_diff);
   1453         accu_sum_est_exp = tmp_e;
   1454       } else {
   1455         exp_diff = -exp_diff;
   1456         accu_sum_est_mant =
   1457             ixheaacd_shr32(tmp_mant, exp_diff) + accu_sum_est_mant;
   1458       }
   1459     }
   1460   }
   1461   {
   1462     WORD32 norm_val;
   1463     norm_val = 16 - ixheaacd_pnorm32(accu_sum_orig_mant);
   1464     if (norm_val > 0) {
   1465       accu_sum_orig_mant >>= norm_val;
   1466       accu_sum_orig_exp += norm_val;
   1467     }
   1468     norm_val = 16 - ixheaacd_pnorm32(accu_sum_est_mant);
   1469     if (norm_val > 0) {
   1470       accu_sum_est_mant >>= norm_val;
   1471       accu_sum_est_exp += norm_val;
   1472     }
   1473   }
   1474 
   1475   if (!flag) {
   1476     sum_orig_mant = (WORD16)accu_sum_orig_mant;
   1477     sum_orig_exp = (WORD16)accu_sum_orig_exp;
   1478     sum_est_mant = (WORD16)accu_sum_est_mant;
   1479     sum_est_exp = (WORD16)accu_sum_est_exp;
   1480   } else {
   1481     sum_est_mant = (WORD16)accu_sum_orig_mant;
   1482     sum_est_exp = (WORD16)accu_sum_orig_exp;
   1483     sum_orig_mant = (WORD16)accu_sum_est_mant;
   1484     sum_orig_exp = (WORD16)accu_sum_est_exp;
   1485   }
   1486 
   1487   {
   1488     temp = ixheaacd_fix_mant_div(sum_orig_mant, sum_est_mant, ptr_avg_gain_mant,
   1489                                  pstr_common_tables);
   1490     *ptr_avg_gain_exp = temp + (sum_orig_exp - sum_est_exp) + 1;
   1491     *ptr_enrg_orig_mant = sum_orig_mant;
   1492     *ptr_sum_ref_exp = sum_orig_exp;
   1493   }
   1494 }
   1495 
   1496 VOID ixheaacd_harm_idx_zerotwolp_dec(WORD32 *ptr_real_buf, WORD16 *ptr_gain_buf,
   1497                                      WORD32 scale_change,
   1498                                      WORD16 *ptr_sine_level_buf,
   1499                                      const WORD32 *ptr_rand_ph,
   1500                                      WORD16 *noise_level_mant,
   1501                                      WORD32 num_sub_bands, FLAG noise_absc_flag,
   1502                                      WORD32 harm_index) {
   1503   WORD32 shift, k;
   1504   WORD32 signal_real;
   1505   WORD32 sine_level;
   1506 
   1507   scale_change = scale_change - 1;
   1508   if (!noise_absc_flag) {
   1509     for (k = 0; k < num_sub_bands; k++) {
   1510       signal_real = ixheaacd_mult32x16in32(*ptr_real_buf, *ptr_gain_buf++);
   1511       shift = (*ptr_gain_buf++ - scale_change);
   1512 
   1513       if (shift > 0)
   1514         signal_real = (signal_real << shift);
   1515       else
   1516         signal_real = (signal_real >> -(shift));
   1517 
   1518       sine_level = (ptr_sine_level_buf[2 * k] << 16);
   1519 
   1520       if (sine_level == 0) {
   1521         *ptr_real_buf++ = ixheaacd_mac16x16in32_shl(
   1522             signal_real, ixheaacd_extract16h(ptr_rand_ph[k]),
   1523             noise_level_mant[2 * k]);
   1524       } else if (harm_index == 0)
   1525         *ptr_real_buf++ = ixheaacd_add32_sat(signal_real, sine_level);
   1526       else
   1527         *ptr_real_buf++ = ixheaacd_sub32_sat(signal_real, sine_level);
   1528     }
   1529   } else {
   1530     for (k = 0; k < num_sub_bands; k++) {
   1531       signal_real = ixheaacd_mult32x16in32(*ptr_real_buf, *ptr_gain_buf++);
   1532       shift = (*ptr_gain_buf++ - scale_change);
   1533 
   1534       if (shift > 0)
   1535         signal_real = (signal_real << shift);
   1536       else
   1537         signal_real = (signal_real >> -(shift));
   1538 
   1539       sine_level = (ptr_sine_level_buf[2 * k] << 16);
   1540 
   1541       if (harm_index == 0)
   1542         *ptr_real_buf++ = ixheaacd_add32_sat(signal_real, sine_level);
   1543       else
   1544         *ptr_real_buf++ = ixheaacd_sub32_sat(signal_real, sine_level);
   1545     }
   1546   }
   1547 }
   1548 
   1549 VOID ixheaacd_harm_idx_onethreelp(
   1550     WORD32 *ptr_real_buf, WORD16 *ptr_gain_buf, WORD32 scale_change,
   1551     WORD16 *ptr_sine_level_buf, const WORD32 *ptr_rand_ph,
   1552     WORD16 *noise_level_mant, WORD32 num_sub_bands, FLAG noise_absc_flag,
   1553     WORD32 freq_inv_flag, WORD32 noise_e, WORD32 sub_band_start) {
   1554   WORD32 shift, k = 0;
   1555   WORD32 signal_real, temp_mult, temp_mult2;
   1556   WORD16 sine_level, sine_level_prev, sine_level_next;
   1557   WORD32 tone_count = 0;
   1558   WORD16 tmp;
   1559 
   1560   scale_change = scale_change - 1;
   1561 
   1562   signal_real = ixheaacd_mult32x16in32(*ptr_real_buf, *ptr_gain_buf++);
   1563   shift = (*ptr_gain_buf++ - scale_change);
   1564 
   1565   if (shift > 0)
   1566     signal_real = (signal_real << shift);
   1567   else
   1568     signal_real = (signal_real >> -(shift));
   1569 
   1570   sine_level = ((ptr_sine_level_buf[2 * 0]));
   1571 
   1572   if (num_sub_bands > 1) {
   1573     sine_level_next = ((ptr_sine_level_buf[2 * 1]));
   1574   } else {
   1575     sine_level_next = 0;
   1576   }
   1577 
   1578   if (ptr_sine_level_buf[2 * 0] != 0) {
   1579     tone_count++;
   1580   } else {
   1581     if (!noise_absc_flag) {
   1582       signal_real = ixheaacd_mac16x16in32_shl(
   1583           signal_real, ixheaacd_extract16h(ptr_rand_ph[k]), *noise_level_mant);
   1584     }
   1585   }
   1586 
   1587   noise_level_mant += 2;
   1588   temp_mult2 = ixheaacd_mult32x16in32(FACTOR, sine_level_next);
   1589   temp_mult = ixheaacd_mult32x16in32(FACTOR, sine_level);
   1590   tmp = noise_e;
   1591 
   1592   if (tmp > 0) {
   1593     temp_mult = ixheaacd_shl32(temp_mult, tmp);
   1594   } else {
   1595     temp_mult = ixheaacd_shr32(temp_mult, -tmp);
   1596   }
   1597 
   1598   if (freq_inv_flag < 0) {
   1599     *(ptr_real_buf - 1) = ixheaacd_add32_sat(*(ptr_real_buf - 1), temp_mult);
   1600     signal_real = ixheaacd_sub32_sat(signal_real, temp_mult2);
   1601   } else {
   1602     *(ptr_real_buf - 1) = ixheaacd_sub32_sat(*(ptr_real_buf - 1), temp_mult);
   1603     signal_real = ixheaacd_add32_sat(signal_real, temp_mult2);
   1604   }
   1605   *ptr_real_buf++ = signal_real;
   1606 
   1607   num_sub_bands = num_sub_bands - 1;
   1608   for (k = 1; k < num_sub_bands; k++) {
   1609     WORD16 gain_m = *ptr_gain_buf++;
   1610     WORD16 gain_e = *ptr_gain_buf++;
   1611     WORD32 q_real = *ptr_real_buf;
   1612 
   1613     signal_real = ixheaacd_mult32x16in32(q_real, gain_m);
   1614 
   1615     if ((shift = (gain_e - scale_change)) >= 0)
   1616       signal_real = (signal_real << shift);
   1617     else
   1618       signal_real = (signal_real >> -(shift));
   1619 
   1620     sine_level_prev = sine_level;
   1621     sine_level = sine_level_next;
   1622     if (sine_level != 0) {
   1623       tone_count++;
   1624     }
   1625     sine_level_next = (ptr_sine_level_buf[2 * (k + 1)]);
   1626 
   1627     if ((!noise_absc_flag) && (sine_level == 0)) {
   1628       signal_real = ixheaacd_mac16x16in32_shl(
   1629           signal_real, ixheaacd_extract16h(ptr_rand_ph[k]), *noise_level_mant);
   1630     }
   1631     noise_level_mant += 2;
   1632 
   1633     if (tone_count <= 16) {
   1634       WORD32 temp_mult;
   1635       WORD32 add_sine = ixheaacd_mult32x16in32(
   1636           FACTOR, ixheaacd_sub16(sine_level_prev, sine_level_next));
   1637       temp_mult = add_sine * freq_inv_flag;
   1638       signal_real = ixheaacd_add32_sat(signal_real, temp_mult);
   1639     }
   1640     *ptr_real_buf++ = signal_real;
   1641     freq_inv_flag = -(freq_inv_flag);
   1642   }
   1643 
   1644   freq_inv_flag = (freq_inv_flag + 1) >> 1;
   1645 
   1646   if (num_sub_bands > 0) {
   1647     WORD32 temp_mult_sine;
   1648     signal_real = ixheaacd_mult32x16in32(*ptr_real_buf, *ptr_gain_buf++);
   1649     shift = (*ptr_gain_buf - scale_change);
   1650 
   1651     if (shift > 0)
   1652       signal_real = (signal_real << shift);
   1653     else
   1654       signal_real = (signal_real >> -(shift));
   1655 
   1656     temp_mult_sine = ixheaacd_mult32x16in32(FACTOR, sine_level);
   1657     sine_level = sine_level_next;
   1658 
   1659     if (sine_level != 0) {
   1660       tone_count++;
   1661     } else {
   1662       if (!noise_absc_flag) {
   1663         signal_real = ixheaacd_mac16x16in32_shl(
   1664             signal_real, ixheaacd_extract16h(ptr_rand_ph[k]),
   1665             *noise_level_mant);
   1666       }
   1667     }
   1668 
   1669     if (tone_count <= 16) {
   1670       temp_mult2 = ixheaacd_mult32x16in32(FACTOR, sine_level);
   1671 
   1672       if (freq_inv_flag) {
   1673         *ptr_real_buf++ = ixheaacd_add32_sat(signal_real, temp_mult_sine);
   1674 
   1675         if ((k + sub_band_start) < 62) {
   1676           *ptr_real_buf = ixheaacd_sub32_sat(*ptr_real_buf, temp_mult2);
   1677         }
   1678       } else {
   1679         *ptr_real_buf++ = ixheaacd_sub32_sat(signal_real, temp_mult_sine);
   1680 
   1681         if ((k + sub_band_start) < 62) {
   1682           *ptr_real_buf = ixheaacd_add32_sat(*ptr_real_buf, temp_mult2);
   1683         }
   1684       }
   1685     } else {
   1686       *ptr_real_buf = signal_real;
   1687     }
   1688   }
   1689 }
   1690 
   1691 VOID ixheaacd_harm_idx_zerotwo(FLAG noise_absc_flag, WORD16 num_sub_bands,
   1692                                WORD32 *ptr_real_buf, WORD32 *ptr_imag,
   1693                                WORD16 *smoothed_gain, WORD16 *smoothed_noise,
   1694                                WORD32 factor, WORD16 *ptr_gain_buf,
   1695                                WORD16 scale_change, const WORD32 *ptr_rand_ph,
   1696                                WORD16 *ptr_sine_level_buf, WORD16 noise_e,
   1697                                WORD32 harm_index) {
   1698   WORD32 k;
   1699   WORD32 signal_real, sig_imag;
   1700   WORD32 shift;
   1701   WORD32 sine_level;
   1702   ptr_gain_buf++;
   1703 
   1704   for (k = 0; k < num_sub_bands; k++) {
   1705     signal_real = ixheaacd_mult32x16in32(*ptr_real_buf, smoothed_gain[0]);
   1706     sig_imag = ixheaacd_mult32x16in32(*ptr_imag, smoothed_gain[0]);
   1707 
   1708     shift = ixheaacd_sub16(*ptr_gain_buf, scale_change);
   1709     ptr_gain_buf += 2;
   1710 
   1711     if (shift > 0) {
   1712       signal_real = ixheaacd_shl32(signal_real, shift);
   1713       sig_imag = ixheaacd_shl32(sig_imag, shift);
   1714     } else {
   1715       shift = -shift;
   1716       signal_real = ixheaacd_shr32(signal_real, shift);
   1717       sig_imag = ixheaacd_shr32(sig_imag, shift);
   1718     }
   1719 
   1720     ptr_rand_ph++;
   1721 
   1722     if (*ptr_sine_level_buf != 0) {
   1723       WORD32 tmp = ixheaacd_sub16(ptr_sine_level_buf[1], noise_e);
   1724 
   1725       if (tmp > 0)
   1726         sine_level = ixheaacd_shl32(ptr_sine_level_buf[0], tmp);
   1727       else
   1728         sine_level = ixheaacd_shr32(ptr_sine_level_buf[0], tmp);
   1729 
   1730       if (harm_index == 0)
   1731         *ptr_real_buf = ixheaacd_add32_sat(signal_real, sine_level);
   1732       else
   1733         *ptr_real_buf = ixheaacd_sub32_sat(signal_real, sine_level);
   1734 
   1735       *ptr_imag = sig_imag;
   1736     } else {
   1737       if (!noise_absc_flag) {
   1738         WORD32 random = *ptr_rand_ph;
   1739         WORD16 noise = smoothed_noise[0];
   1740 
   1741         *ptr_real_buf = ixheaacd_mac16x16in32_shl(
   1742             signal_real, ixheaacd_extract16h(random), noise);
   1743         *ptr_imag = ixheaacd_mac16x16in32_shl(
   1744             sig_imag, ixheaacd_extract16l(random), noise);
   1745       } else {
   1746         *ptr_real_buf = signal_real;
   1747         *ptr_imag = sig_imag;
   1748       }
   1749     }
   1750 
   1751     smoothed_noise += factor;
   1752     smoothed_gain += 2;
   1753     ptr_sine_level_buf += 2;
   1754     ptr_real_buf++;
   1755     ptr_imag++;
   1756   }
   1757 }
   1758 
   1759 VOID ixheaacd_harm_idx_onethree(FLAG noise_absc_flag, WORD16 num_sub_bands,
   1760                                 WORD32 *ptr_real_buf, WORD32 *ptr_imag,
   1761                                 WORD16 *smoothed_gain, WORD16 *smoothed_noise,
   1762                                 WORD32 factor, WORD16 *ptr_gain_buf,
   1763                                 WORD16 scale_change, const WORD32 *ptr_rand_ph,
   1764                                 WORD16 *ptr_sine_level_buf, WORD16 noise_e,
   1765                                 WORD32 freq_inv_flag, WORD32 harm_index) {
   1766   WORD32 k;
   1767   WORD32 signal_real, sig_imag;
   1768   WORD32 shift;
   1769   WORD32 sine_level;
   1770 
   1771   ptr_gain_buf++;
   1772 
   1773   if (harm_index == 1) freq_inv_flag = !freq_inv_flag;
   1774 
   1775   for (k = 0; k < num_sub_bands; k++) {
   1776     signal_real = ixheaacd_mult32x16in32(*ptr_real_buf, smoothed_gain[0]);
   1777     sig_imag = ixheaacd_mult32x16in32(*ptr_imag, smoothed_gain[0]);
   1778 
   1779     shift = ixheaacd_sub16(*ptr_gain_buf, scale_change);
   1780     ptr_gain_buf += 2;
   1781 
   1782     if (shift > 0) {
   1783       signal_real = ixheaacd_shl32(signal_real, shift);
   1784       sig_imag = ixheaacd_shl32(sig_imag, shift);
   1785     } else {
   1786       shift = -shift;
   1787       signal_real = ixheaacd_shr32(signal_real, shift);
   1788       sig_imag = ixheaacd_shr32(sig_imag, shift);
   1789     }
   1790 
   1791     ptr_rand_ph++;
   1792 
   1793     if (*ptr_sine_level_buf != 0) {
   1794       WORD32 tmp = ixheaacd_sub16(ptr_sine_level_buf[1], noise_e);
   1795 
   1796       if (tmp > 0)
   1797         sine_level = ixheaacd_shl32(ptr_sine_level_buf[0], tmp);
   1798       else
   1799         sine_level = ixheaacd_shr32(ptr_sine_level_buf[0], -tmp);
   1800 
   1801       *ptr_real_buf = signal_real;
   1802 
   1803       if (freq_inv_flag) {
   1804         *ptr_imag = ixheaacd_add32_sat(sig_imag, sine_level);
   1805       } else {
   1806         *ptr_imag = ixheaacd_sub32_sat(sig_imag, sine_level);
   1807       }
   1808 
   1809     } else {
   1810       if (!noise_absc_flag) {
   1811         WORD32 random = *ptr_rand_ph;
   1812         WORD16 noise = smoothed_noise[0];
   1813 
   1814         *ptr_real_buf = ixheaacd_mac16x16in32_shl(
   1815             signal_real, ixheaacd_extract16h(random), noise);
   1816         *ptr_imag = ixheaacd_mac16x16in32_shl(
   1817             sig_imag, ixheaacd_extract16l(random), noise);
   1818       } else {
   1819         *ptr_real_buf = signal_real;
   1820         *ptr_imag = sig_imag;
   1821       }
   1822     }
   1823 
   1824     freq_inv_flag = (!freq_inv_flag);
   1825     smoothed_gain += 2;
   1826     smoothed_noise += factor;
   1827     ptr_sine_level_buf += 2;
   1828     ptr_real_buf++;
   1829     ptr_imag++;
   1830   }
   1831 }
   1832