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 
     30 #include <ixheaacd_basic_op.h>
     31 #include "ixheaacd_intrinsics.h"
     32 #include "ixheaacd_bitbuffer.h"
     33 #include "ixheaacd_sbrdecsettings.h"
     34 #include "ixheaacd_sbr_scale.h"
     35 #include "ixheaacd_lpp_tran.h"
     36 #include "ixheaacd_env_extr_part.h"
     37 #include <ixheaacd_sbr_rom.h>
     38 #include "ixheaacd_hybrid.h"
     39 #include "ixheaacd_ps_dec.h"
     40 
     41 #include "ixheaacd_env_extr.h"
     42 #include "ixheaacd_common_rom.h"
     43 #include "ixheaacd_env_dec.h"
     44 #include "ixheaacd_sbr_const.h"
     45 
     46 #include "ixheaacd_basic_funcs.h"
     47 
     48 #include "math.h"
     49 
     50 #define add16_m(a, b) ((a) + (b))
     51 #define sub16_m(a, b) ((a) - (b))
     52 
     53 #define mult16x16_16(a, b) ixheaacd_mult16((a), (b))
     54 
     55 static VOID ixheaacd_dequant_esbr_env_data(FLOAT32 *ptr_env_sf,
     56                                            WORD32 num_env_sf,
     57                                            WORD32 num_noise_fac, WORD32 amp_res,
     58                                            FLOAT32 *ptr_noise_floor) {
     59   WORD32 i;
     60   FLOAT32 array[2] = {0.5f, 1.0f};
     61   FLOAT32 a_flt = array[amp_res];
     62 
     63   for (i = 0; i < num_env_sf; i++) {
     64     ptr_env_sf[i] = (FLOAT32)(pow(2, ptr_env_sf[i] * a_flt) * 64);
     65   }
     66 
     67   for (i = 0; i < num_noise_fac; i++) {
     68     FLOAT32 temp = ptr_noise_floor[i];
     69 
     70     temp = NOISE_FLOOR_OFFSET - temp;
     71     temp = (FLOAT32)pow(2.0f, temp);
     72 
     73     ptr_noise_floor[i] = temp;
     74   }
     75 }
     76 
     77 static VOID ixheaacd_dequant_pvc_env_data(WORD32 num_noise_fac,
     78                                           FLOAT32 *ptr_noise_floor) {
     79   WORD32 i;
     80 
     81   for (i = 0; i < num_noise_fac; i++) {
     82     FLOAT32 temp = ptr_noise_floor[i];
     83 
     84     temp = NOISE_FLOOR_OFFSET - temp;
     85     temp = (FLOAT32)pow(2.0f, temp);
     86 
     87     ptr_noise_floor[i] = temp;
     88   }
     89 }
     90 
     91 VOID ixheaacd_map_res_energy(WORD16 curr_val, WORD16 *prev_data,
     92                              WORD32 ixheaacd_drc_offset, WORD32 index,
     93                              WORD32 res) {
     94   if (res == LOW) {
     95     if (ixheaacd_drc_offset >= 0) {
     96       if (index < ixheaacd_drc_offset) {
     97         prev_data[index] = curr_val;
     98       } else {
     99         WORD32 index_2;
    100         index_2 = ((index + index) - ixheaacd_drc_offset);
    101         prev_data[index_2] = curr_val;
    102         prev_data[index_2 + 1] = curr_val;
    103       }
    104     } else {
    105       ixheaacd_drc_offset = -(ixheaacd_drc_offset);
    106 
    107       if (index < ixheaacd_drc_offset) {
    108         WORD32 index_3;
    109         index_3 = ((index + index) + index);
    110         prev_data[index_3] = curr_val;
    111         prev_data[index_3 + 1] = curr_val;
    112         prev_data[index_3 + 2] = curr_val;
    113       } else {
    114         WORD32 index_2;
    115         index_2 = ((index + index) + ixheaacd_drc_offset);
    116         prev_data[index_2] = curr_val;
    117         prev_data[index_2 + 1] = curr_val;
    118       }
    119     }
    120   } else {
    121     prev_data[index] = curr_val;
    122   }
    123 }
    124 
    125 VOID ixheaacd_process_del_cod_env_data(
    126     ia_sbr_header_data_struct *ptr_header_data,
    127     ia_sbr_frame_info_data_struct *ptr_sbr_data,
    128     ia_sbr_prev_frame_data_struct *ptr_prev_data) {
    129   WORD32 i, dtdf_dir, num_sf_bands, band, freq_res;
    130   WORD16 temp_val;
    131   WORD16 *ptr_prev_env_sf = ptr_prev_data->sfb_nrg_prev;
    132   WORD16 *ptr_env_sf = ptr_sbr_data->int_env_sf_arr;
    133 
    134   FLOAT32 *ptr_env_sf_float = ptr_sbr_data->flt_env_sf_arr;
    135 
    136   WORD32 ixheaacd_drc_offset;
    137   band = 0;
    138 
    139   ixheaacd_drc_offset =
    140       ((ptr_header_data->pstr_freq_band_data->num_sf_bands[LOW] << 1) -
    141        ptr_header_data->pstr_freq_band_data->num_sf_bands[HIGH]);
    142 
    143   for (i = 0; i < ptr_sbr_data->str_frame_info_details.num_env; i++) {
    144     dtdf_dir = ptr_sbr_data->del_cod_dir_arr[i];
    145     freq_res = ptr_sbr_data->str_frame_info_details.freq_res[i];
    146 
    147     num_sf_bands = ptr_header_data->pstr_freq_band_data->num_sf_bands[freq_res];
    148 
    149     if (dtdf_dir == DTDF_DIR_FREQ) {
    150       ixheaacd_map_res_energy(*ptr_env_sf, ptr_prev_env_sf, ixheaacd_drc_offset,
    151                               0, freq_res);
    152       ptr_env_sf++;
    153 
    154       ptr_env_sf_float++;
    155 
    156       for (band = 1; band < num_sf_bands; band++) {
    157         *ptr_env_sf = *ptr_env_sf + *(ptr_env_sf - 1);
    158         ixheaacd_map_res_energy(*ptr_env_sf, ptr_prev_env_sf,
    159                                 ixheaacd_drc_offset, band, freq_res);
    160 
    161         *ptr_env_sf_float = (FLOAT32)(*ptr_env_sf);
    162         ptr_env_sf_float++;
    163 
    164         ptr_env_sf++;
    165       }
    166 
    167     } else {
    168       if (freq_res == LOW) {
    169         if (ixheaacd_drc_offset < 0) {
    170           WORD32 tar, index_3;
    171           ixheaacd_drc_offset = -ixheaacd_drc_offset;
    172           tar = ixheaacd_min32(ixheaacd_drc_offset, band);
    173 
    174           for (band = 0; band < tar; band++) {
    175             index_3 = ((band + band) + band);
    176             temp_val = add16_m(*ptr_env_sf, ptr_prev_env_sf[index_3]);
    177 
    178             ptr_prev_env_sf[index_3] = temp_val;
    179             ptr_prev_env_sf[index_3 + 1] = temp_val;
    180             ptr_prev_env_sf[index_3 + 2] = temp_val;
    181             *ptr_env_sf++ = temp_val;
    182 
    183             *ptr_env_sf_float = (FLOAT32)temp_val;
    184             ptr_env_sf_float++;
    185           }
    186 
    187           for (; band < num_sf_bands; band++) {
    188             index_3 = (band << 1) + ixheaacd_drc_offset;
    189             temp_val = add16_m(*ptr_env_sf, ptr_prev_env_sf[index_3]);
    190             ptr_prev_env_sf[index_3] = temp_val;
    191             ptr_prev_env_sf[index_3 + 1] = temp_val;
    192             *ptr_env_sf++ = temp_val;
    193             *ptr_env_sf_float = (FLOAT32)temp_val;
    194             ptr_env_sf_float++;
    195           }
    196         } else {
    197           WORD32 tar, index_2;
    198           WORD16 *ptr2 = ptr_prev_env_sf;
    199           tar = ixheaacd_min32(ixheaacd_drc_offset, band);
    200           for (band = 0; band < tar; band++) {
    201             *ptr_env_sf = add16_m(*ptr_env_sf, *ptr2);
    202             *ptr2 = *ptr_env_sf;
    203 
    204             *ptr_env_sf_float = (FLOAT32)(*ptr_env_sf);
    205             ptr_env_sf_float++;
    206 
    207             ptr2++;
    208             ptr_env_sf++;
    209           }
    210 
    211           for (; band < num_sf_bands; band++) {
    212             index_2 = (band < ixheaacd_drc_offset)
    213                           ? band
    214                           : ((band << 1) - ixheaacd_drc_offset);
    215             temp_val = add16_m(*ptr_env_sf, ptr_prev_env_sf[index_2]);
    216             ptr_prev_env_sf[index_2] = temp_val;
    217             ptr_prev_env_sf[index_2 + 1] = temp_val;
    218             *ptr_env_sf++ = temp_val;
    219 
    220             *ptr_env_sf_float = (FLOAT32)temp_val;
    221             ptr_env_sf_float++;
    222           }
    223         }
    224 
    225       } else {
    226         WORD16 *ptr2 = ptr_prev_env_sf;
    227         for (band = num_sf_bands - 1; band >= 0; band--) {
    228           *ptr_env_sf = add16_m(*ptr_env_sf, *ptr2);
    229           *ptr2 = *ptr_env_sf;
    230           *ptr_env_sf_float = (FLOAT32)(*ptr_env_sf);
    231           ptr_env_sf_float++;
    232           ptr2++;
    233           ptr_env_sf++;
    234         }
    235         band = num_sf_bands;
    236       }
    237     }
    238   }
    239 }
    240 
    241 static PLATFORM_INLINE VOID
    242 ixheaacd_wrong_timing_compensate(ia_sbr_header_data_struct *ptr_header_data,
    243                                  ia_sbr_frame_info_data_struct *ptr_sbr_data,
    244                                  ia_sbr_prev_frame_data_struct *ptr_prev_data,
    245                                  ixheaacd_misc_tables *pstr_common_tables) {
    246   WORD32 i, num_env_sf;
    247   ia_frame_info_struct *p_frame_info = &ptr_sbr_data->str_frame_info_details;
    248   WORD16 *num_sf_bands = ptr_header_data->pstr_freq_band_data->num_sf_bands;
    249   WORD32 start_pos_est;
    250   WORD32 ref_len, new_len, shift;
    251   WORD16 delta_exp;
    252 
    253   start_pos_est =
    254       (ptr_prev_data->end_position - ptr_header_data->num_time_slots);
    255 
    256   ref_len = (p_frame_info->border_vec[1] - p_frame_info->border_vec[0]);
    257 
    258   new_len = (p_frame_info->border_vec[1] - start_pos_est);
    259 
    260   if (new_len <= 0) {
    261     new_len = ref_len;
    262     start_pos_est = p_frame_info->border_vec[0];
    263   }
    264 
    265   delta_exp = pstr_common_tables->log_dual_is_table[ref_len];
    266   delta_exp -= pstr_common_tables->log_dual_is_table[new_len];
    267 
    268   shift = (SHORT_BITS - ENV_EXP_FRACT - 3 - ptr_sbr_data->amp_res);
    269   delta_exp = ixheaacd_shr16(delta_exp, (WORD16)shift);
    270   p_frame_info->border_vec[0] = start_pos_est;
    271   p_frame_info->noise_border_vec[0] = start_pos_est;
    272 
    273   if (ptr_sbr_data->coupling_mode != COUPLING_BAL) {
    274     num_env_sf =
    275         ((p_frame_info->freq_res[0]) ? num_sf_bands[HIGH] : num_sf_bands[LOW]);
    276 
    277     for (i = 0; i < num_env_sf; i++) {
    278       ptr_sbr_data->int_env_sf_arr[i] =
    279           add16_m(ptr_sbr_data->int_env_sf_arr[i], delta_exp);
    280     }
    281   }
    282 }
    283 
    284 WORD16 ixheaacd_check_env_data(ia_sbr_header_data_struct *ptr_header_data,
    285                                ia_sbr_frame_info_data_struct *ptr_sbr_data,
    286                                ia_sbr_prev_frame_data_struct *ptr_prev_data) {
    287   WORD16 *ptr_evn_sf = ptr_sbr_data->int_env_sf_arr;
    288   WORD16 *ptr_prev_evn_sf = ptr_prev_data->sfb_nrg_prev;
    289   WORD32 i;
    290   FLAG error_code = 0;
    291   WORD16 sbr_max_env_sf;
    292   WORD32 amp_res = ptr_sbr_data->amp_res;
    293 
    294   sbr_max_env_sf = (SBR_ENV_SF_MAX_VAL_1_5 >> amp_res);
    295 
    296   for (i = 0; i < ptr_sbr_data->num_env_sfac; i++) {
    297     if (ptr_evn_sf[i] > sbr_max_env_sf) {
    298       error_code = 1;
    299     }
    300     if (ptr_evn_sf[i] < 0) {
    301       ptr_evn_sf[i] = 0;
    302     }
    303   }
    304 
    305   for (i = 0; i < ptr_header_data->pstr_freq_band_data->num_sf_bands[HIGH];
    306        i++) {
    307     if (ptr_prev_evn_sf[i] < 0) {
    308       ptr_prev_evn_sf[i] = 0;
    309     } else {
    310       if (ptr_prev_evn_sf[i] > sbr_max_env_sf)
    311         ptr_prev_evn_sf[i] = sbr_max_env_sf;
    312     }
    313   }
    314   return (WORD16)(error_code);
    315 }
    316 
    317 VOID ixheaacd_dequant_env_data(ia_sbr_frame_info_data_struct *ptr_sbr_data,
    318                                WORD32 amp_res) {
    319   WORD32 i;
    320   WORD32 num_env_sf = ptr_sbr_data->num_env_sfac;
    321   WORD32 mantissa;
    322   WORD32 amp_res_1;
    323   WORD32 exponent;
    324   WORD32 exp_add = (7 + NRG_EXP_OFFSET);
    325   WORD16 *ptr_env_sf = ptr_sbr_data->int_env_sf_arr;
    326   WORD32 mant_arr[2] = {0x4000, 0x5a80};
    327 
    328   amp_res_1 = (1 - amp_res);
    329 
    330   for (i = num_env_sf - 1; i >= 0; i--) {
    331     exponent = *ptr_env_sf;
    332     mantissa = mant_arr[(exponent & amp_res_1)];
    333     exponent = (exponent >> amp_res_1);
    334     exponent = (exponent + exp_add);
    335     *ptr_env_sf++ = (WORD16)(mantissa | (exponent & MASK_FOR_EXP));
    336   }
    337 }
    338 
    339 static PLATFORM_INLINE VOID
    340 ixheaacd_limit_noise_floor_fac(ia_sbr_header_data_struct *ptr_header_data,
    341                                ia_sbr_frame_info_data_struct *ptr_sbr_data) {
    342   WORD32 i, tot_nf_bands;
    343   WORD32 value;
    344   WORD32 num_nf_bands;
    345   WORD16 *ptr_noise_floor;
    346 
    347   num_nf_bands = ptr_header_data->pstr_freq_band_data->num_nf_bands;
    348 
    349   tot_nf_bands =
    350       ptr_sbr_data->str_frame_info_details.num_noise_env * num_nf_bands;
    351 
    352   ptr_noise_floor = ptr_sbr_data->int_noise_floor;
    353 
    354   for (i = tot_nf_bands - 1; i >= 0; i--) {
    355     value = *ptr_noise_floor;
    356     if (value > MAX_NOISE_FLOOR_FAC_VAL) {
    357       *ptr_noise_floor = MAX_NOISE_FLOOR_FAC_VAL;
    358     } else {
    359       if (value < MIN_NOISE_FLOOR_FAC_VAL) {
    360         *ptr_noise_floor = MIN_NOISE_FLOOR_FAC_VAL;
    361       }
    362     }
    363     ptr_noise_floor++;
    364   }
    365 }
    366 
    367 VOID ixheaacd_add_arr(WORD16 *ptr1, WORD16 *ptr2, WORD32 num) {
    368   WORD32 i;
    369   for (i = num - 1; i >= 0; i--) {
    370     *ptr2 = (*ptr2 + *ptr1);
    371     ptr2++;
    372     ptr1++;
    373   }
    374 }
    375 
    376 VOID ixheaacd_calc_noise_floor(ia_sbr_header_data_struct *ptr_header_data,
    377                                ia_sbr_frame_info_data_struct *ptr_sbr_data,
    378                                ia_sbr_prev_frame_data_struct *ptr_prev_data) {
    379   WORD32 i;
    380   WORD32 num_nf_bands;
    381   WORD32 num_noise_env;
    382   WORD32 ixheaacd_drc_offset;
    383   WORD16 *ptr_noise_floor = ptr_sbr_data->int_noise_floor;
    384 
    385   WORD16 *ptr_prev_noise_floor = ptr_prev_data->prev_noise_level;
    386   WORD16 *ptr1, *ptr2;
    387   WORD32 num;
    388   FLOAT32 *ptr_noise_floor_float = ptr_sbr_data->flt_noise_floor;
    389 
    390   num_nf_bands = ptr_header_data->pstr_freq_band_data->num_nf_bands;
    391   num_noise_env = ptr_sbr_data->str_frame_info_details.num_noise_env;
    392 
    393   if (ptr_sbr_data->del_cod_dir_noise_arr[0] == DTDF_DIR_FREQ) {
    394     ptr1 = ptr_noise_floor++;
    395     ptr2 = ptr_noise_floor;
    396     num = num_nf_bands - 1;
    397   } else {
    398     ptr1 = ptr_prev_noise_floor;
    399     ptr2 = ptr_sbr_data->int_noise_floor;
    400     num = num_nf_bands;
    401   }
    402 
    403   ixheaacd_add_arr(ptr1, ptr2, num);
    404 
    405   if (num_noise_env > 1) {
    406     if (ptr_sbr_data->del_cod_dir_noise_arr[1] == DTDF_DIR_FREQ) {
    407       ptr1 = &ptr_sbr_data->int_noise_floor[num_nf_bands];
    408       ptr2 = &ptr_sbr_data->int_noise_floor[(num_nf_bands + 1)];
    409 
    410       num = num_nf_bands - 1;
    411     } else {
    412       ptr1 = &ptr_sbr_data->int_noise_floor[0];
    413       ptr2 = &ptr_sbr_data->int_noise_floor[num_nf_bands];
    414 
    415       num = num_nf_bands;
    416     }
    417     ixheaacd_add_arr(ptr1, ptr2, num);
    418   }
    419 
    420   ixheaacd_limit_noise_floor_fac(ptr_header_data, ptr_sbr_data);
    421 
    422   ixheaacd_drc_offset = num_nf_bands * (num_noise_env - 1);
    423   ptr1 = &ptr_sbr_data->int_noise_floor[ixheaacd_drc_offset];
    424   ptr2 = ptr_prev_noise_floor;
    425 
    426   memcpy(ptr2, ptr1, sizeof(WORD16) * (num_nf_bands));
    427 
    428   if (ptr_sbr_data->coupling_mode != COUPLING_BAL) {
    429     WORD32 noise_floor_exp, tot_nf_bands;
    430 
    431     tot_nf_bands = (num_nf_bands * num_noise_env);
    432     ptr_noise_floor = &ptr_sbr_data->int_noise_floor[0];
    433 
    434     for (i = 0; i < tot_nf_bands; i++) {
    435       noise_floor_exp =
    436           (NOISE_FLOOR_OFFSET_INT + 1 + NOISE_EXP_OFFSET - *ptr_noise_floor);
    437 
    438       *ptr_noise_floor_float++ = *ptr_noise_floor;
    439       *ptr_noise_floor++ = (WORD16)(0x4000 + (noise_floor_exp & MASK_FOR_EXP));
    440     }
    441   }
    442 }
    443 
    444 VOID ixheaacd_dec_sbrdata_for_pvc(
    445     ia_sbr_header_data_struct *ptr_header_data,
    446     ia_sbr_frame_info_data_struct *ptr_sbr_data,
    447     ia_sbr_prev_frame_data_struct *ptr_prev_data) {
    448   ixheaacd_calc_noise_floor(ptr_header_data, ptr_sbr_data, ptr_prev_data);
    449 
    450   if (!ptr_sbr_data->coupling_mode) {
    451     ptr_sbr_data->num_noise_sfac =
    452         ptr_header_data->pstr_freq_band_data->num_nf_bands *
    453         ptr_sbr_data->str_frame_info_details.num_noise_env;
    454     ixheaacd_dequant_pvc_env_data(ptr_sbr_data->num_noise_sfac,
    455                                   ptr_sbr_data->flt_noise_floor);
    456   }
    457 }
    458 
    459 VOID ixheaacd_sbr_env_dequant_coup_fix(
    460     ia_sbr_header_data_struct *ptr_header_data,
    461     ia_sbr_frame_info_data_struct *ptr_data_left,
    462     ia_sbr_frame_info_data_struct *ptr_data_right,
    463     ixheaacd_misc_tables *pstr_common_tables) {
    464   WORD32 i;
    465   WORD32 num_env_sf = ptr_data_left->num_env_sfac;
    466   WORD16 temp_left_mant, temp_right_mant, temp_right_plus1_mant, new_left_mant,
    467       new_right_mant;
    468   WORD16 temp_left_exp, temp_right_exp, temp_rightplus1_exp, new_left_exp,
    469       new_right_exp;
    470   WORD32 i_end;
    471   WORD16 *r_data = ptr_data_right->int_env_sf_arr;
    472   WORD16 *l_data = ptr_data_left->int_env_sf_arr;
    473 
    474   for (i = 0; i < num_env_sf; i++) {
    475     temp_right_mant = (WORD16)(*r_data & MASK_M);
    476     temp_right_exp = (WORD16)(*r_data & MASK_FOR_EXP);
    477 
    478     temp_right_exp = sub16_m(temp_right_exp, add16_m(18, NRG_EXP_OFFSET));
    479     temp_left_mant = (WORD16)(*l_data & MASK_M);
    480     temp_left_exp = (WORD16)(*l_data & MASK_FOR_EXP);
    481 
    482     temp_left_exp = sub16_m(temp_left_exp, NRG_EXP_OFFSET);
    483 
    484     ixheaacd_fix_mant_exp_add(temp_right_mant, temp_right_exp, 0x4000, 1,
    485                               &temp_right_plus1_mant, &temp_rightplus1_exp);
    486 
    487     new_right_exp = ixheaacd_fix_mant_div(temp_left_mant, temp_right_plus1_mant,
    488                                           &new_right_mant, pstr_common_tables);
    489 
    490     new_right_exp += temp_left_exp - temp_rightplus1_exp + 2;
    491 
    492     new_left_mant = ixheaacd_mult16_shl(temp_right_mant, new_right_mant);
    493 
    494     new_left_exp = add16_m(temp_right_exp, new_right_exp);
    495 
    496     *r_data++ = (WORD16)(((new_right_mant + ROUNDING) & MASK_M) +
    497                          ((new_right_exp + NRG_EXP_OFFSET) & MASK_FOR_EXP));
    498     *l_data++ = (WORD16)(((new_left_mant + ROUNDING) & MASK_M) +
    499                          ((new_left_exp + NRG_EXP_OFFSET) & MASK_FOR_EXP));
    500   }
    501 
    502   i_end = ptr_header_data->pstr_freq_band_data->num_nf_bands *
    503           ptr_data_left->str_frame_info_details.num_noise_env;
    504   r_data = ptr_data_right->int_noise_floor;
    505   l_data = ptr_data_left->int_noise_floor;
    506 
    507   for (i = i_end - 1; i >= 0; i--) {
    508     temp_left_exp =
    509         sub16_m((WORD16)(*l_data & (WORD16)MASK_FOR_EXP), NOISE_EXP_OFFSET);
    510     temp_right_exp = sub16_m(*r_data, 12);
    511 
    512     ixheaacd_fix_mant_exp_add(0x4000, ixheaacd_add16(1, temp_right_exp), 0x4000,
    513                               1, &temp_right_plus1_mant, &temp_rightplus1_exp);
    514 
    515     new_right_exp = ixheaacd_fix_mant_div(0x4000, temp_right_plus1_mant,
    516                                           &new_right_mant, pstr_common_tables);
    517 
    518     new_right_exp += temp_left_exp - temp_rightplus1_exp + 2;
    519 
    520     new_left_mant = new_right_mant;
    521     new_left_exp = add16_m(new_right_exp, temp_right_exp);
    522     *r_data++ = (WORD16)(((new_right_mant + ROUNDING) & MASK_M) +
    523                          ((new_right_exp + NOISE_EXP_OFFSET) & MASK_FOR_EXP));
    524     *l_data++ = (WORD16)(((new_left_mant + ROUNDING) & MASK_M) +
    525                          ((new_left_exp + NOISE_EXP_OFFSET) & MASK_FOR_EXP));
    526   }
    527 }
    528 
    529 VOID ixheaacd_sbr_env_dequant_coup(
    530     ia_sbr_frame_info_data_struct *ptr_data_ch_0,
    531     ia_sbr_frame_info_data_struct *ptr_data_ch_1) {
    532   FLOAT32 *ptr_env_sf_left = ptr_data_ch_0->flt_env_sf_arr;
    533   FLOAT32 *ptr_env_sf_right = ptr_data_ch_1->flt_env_sf_arr;
    534   FLOAT32 *ptr_noise_floor_left = ptr_data_ch_0->flt_noise_floor;
    535   FLOAT32 *ptr_noise_floor_right = ptr_data_ch_1->flt_noise_floor;
    536   WORD32 num_env_sf = ptr_data_ch_0->num_env_sfac;
    537   WORD32 num_noise_fac = ptr_data_ch_0->num_noise_sfac;
    538   WORD32 amp_res = ptr_data_ch_0->amp_res;
    539 
    540   WORD32 i;
    541   FLOAT32 temp_l, temp_r;
    542   FLOAT32 pan_offset[2] = {24.0f, 12.0f};
    543   FLOAT32 a_arr[2] = {0.5f, 1.0f};
    544 
    545   FLOAT32 a = a_arr[amp_res];
    546 
    547   for (i = 0; i < num_env_sf; i++) {
    548     temp_l = ptr_env_sf_left[i];
    549     temp_r = ptr_env_sf_right[i];
    550 
    551     ptr_env_sf_left[i] =
    552         (FLOAT32)(64 * (pow(2, temp_l * a + 1) /
    553                         (1 + pow(2, (pan_offset[amp_res] - temp_r) * a))));
    554     ptr_env_sf_right[i] =
    555         (FLOAT32)(64 * (pow(2, temp_l * a + 1) /
    556                         (1 + pow(2, (temp_r - pan_offset[amp_res]) * a))));
    557   }
    558 
    559   for (i = 0; i < num_noise_fac; i++) {
    560     temp_l = ptr_noise_floor_left[i];
    561     temp_r = ptr_noise_floor_right[i];
    562 
    563     ptr_noise_floor_left[i] =
    564         (FLOAT32)(pow(2, NOISE_FLOOR_OFFSET - temp_l + 1) /
    565                   (1 + pow(2, pan_offset[1] - temp_r)));
    566     ptr_noise_floor_right[i] =
    567         (FLOAT32)(pow(2, NOISE_FLOOR_OFFSET - temp_l + 1) /
    568                   (1 + pow(2, temp_r - pan_offset[1])));
    569   }
    570 }
    571 VOID ixheaacd_dec_sbrdata(ia_sbr_header_data_struct *ptr_header_data_ch_0,
    572                           ia_sbr_header_data_struct *ptr_header_data_ch_1,
    573                           ia_sbr_frame_info_data_struct *ptr_sbr_data_ch_0,
    574                           ia_sbr_prev_frame_data_struct *ptr_prev_data_ch_0,
    575                           ia_sbr_frame_info_data_struct *ptr_sbr_data_ch_1,
    576                           ia_sbr_prev_frame_data_struct *ptr_prev_data_ch_1,
    577                           ixheaacd_misc_tables *ptr_common_tables) {
    578   FLAG error_code;
    579   WORD32 usac_flag = ptr_header_data_ch_0->usac_flag;
    580 
    581   ixheaacd_dec_envelope(ptr_header_data_ch_0, ptr_sbr_data_ch_0,
    582                         ptr_prev_data_ch_0, ptr_prev_data_ch_1,
    583                         ptr_common_tables);
    584 
    585   ixheaacd_calc_noise_floor(ptr_header_data_ch_0, ptr_sbr_data_ch_0,
    586                             ptr_prev_data_ch_0);
    587 
    588   if (!ptr_sbr_data_ch_0->coupling_mode && usac_flag) {
    589     ptr_sbr_data_ch_0->num_noise_sfac =
    590         ptr_header_data_ch_0->pstr_freq_band_data->num_nf_bands *
    591         ptr_sbr_data_ch_0->str_frame_info_details.num_noise_env;
    592 
    593     ixheaacd_dequant_esbr_env_data(
    594         ptr_sbr_data_ch_0->flt_env_sf_arr, ptr_sbr_data_ch_0->num_env_sfac,
    595         ptr_sbr_data_ch_0->num_noise_sfac, ptr_sbr_data_ch_0->amp_res,
    596         ptr_sbr_data_ch_0->flt_noise_floor);
    597   }
    598 
    599   if (ptr_sbr_data_ch_1 != NULL) {
    600     error_code = ptr_header_data_ch_0->err_flag;
    601     ixheaacd_dec_envelope(ptr_header_data_ch_1, ptr_sbr_data_ch_1,
    602                           ptr_prev_data_ch_1, ptr_prev_data_ch_0,
    603                           ptr_common_tables);
    604 
    605     ixheaacd_calc_noise_floor(ptr_header_data_ch_1, ptr_sbr_data_ch_1,
    606                               ptr_prev_data_ch_1);
    607 
    608     if (!ptr_sbr_data_ch_1->coupling_mode && usac_flag) {
    609       ptr_sbr_data_ch_1->num_noise_sfac =
    610           ptr_header_data_ch_1->pstr_freq_band_data->num_nf_bands *
    611           ptr_sbr_data_ch_1->str_frame_info_details.num_noise_env;
    612 
    613       ixheaacd_dequant_esbr_env_data(
    614           ptr_sbr_data_ch_1->flt_env_sf_arr, ptr_sbr_data_ch_1->num_env_sfac,
    615           ptr_sbr_data_ch_1->num_noise_sfac, ptr_sbr_data_ch_1->amp_res,
    616           ptr_sbr_data_ch_1->flt_noise_floor);
    617     }
    618 
    619     if (!usac_flag) {
    620       if (!error_code && ptr_header_data_ch_0->err_flag) {
    621         ixheaacd_dec_envelope(ptr_header_data_ch_0, ptr_sbr_data_ch_0,
    622                               ptr_prev_data_ch_0, ptr_prev_data_ch_1,
    623                               ptr_common_tables);
    624       }
    625     }
    626 
    627     if (ptr_sbr_data_ch_0->coupling_mode) {
    628       ixheaacd_sbr_env_dequant_coup_fix(ptr_header_data_ch_0, ptr_sbr_data_ch_0,
    629                                         ptr_sbr_data_ch_1, ptr_common_tables);
    630 
    631       ixheaacd_sbr_env_dequant_coup(ptr_sbr_data_ch_0, ptr_sbr_data_ch_1);
    632     }
    633   }
    634 }
    635 VOID ixheaacd_dec_envelope(ia_sbr_header_data_struct *ptr_header_data,
    636                            ia_sbr_frame_info_data_struct *ptr_sbr_data,
    637                            ia_sbr_prev_frame_data_struct *ptr_prev_data_ch_0,
    638                            ia_sbr_prev_frame_data_struct *ptr_prev_data_ch_1,
    639                            ixheaacd_misc_tables *pstr_common_tables) {
    640   FLAG error_code;
    641   WORD16 env_sf_local_arr[MAX_FREQ_COEFFS];
    642   WORD32 usac_flag = ptr_header_data->usac_flag;
    643   WORD32 temp_1 =
    644       ptr_prev_data_ch_0->end_position - ptr_header_data->num_time_slots;
    645   temp_1 = ptr_sbr_data->str_frame_info_details.border_vec[0] - temp_1;
    646 
    647   if ((!ptr_header_data->err_flag_prev) && (!ptr_header_data->err_flag) &&
    648       (temp_1 != 0)) {
    649     if (ptr_sbr_data->del_cod_dir_arr[0] == DTDF_DIR_TIME) {
    650       ptr_header_data->err_flag = 1;
    651     } else {
    652       ptr_header_data->err_flag_prev = 1;
    653     }
    654   }
    655 
    656   if (ptr_header_data->err_flag && !usac_flag) {
    657     ixheaacd_lean_sbrconcealment(ptr_header_data, ptr_sbr_data,
    658                                  ptr_prev_data_ch_0);
    659 
    660     ixheaacd_process_del_cod_env_data(ptr_header_data, ptr_sbr_data,
    661                                       ptr_prev_data_ch_0);
    662   } else {
    663     WORD32 num = ptr_header_data->pstr_freq_band_data->num_sf_bands[HIGH];
    664     if (ptr_header_data->err_flag_prev && !usac_flag) {
    665       WORD16 *ptr1, *ptr2;
    666       WORD32 i;
    667       ixheaacd_wrong_timing_compensate(ptr_header_data, ptr_sbr_data,
    668                                        ptr_prev_data_ch_0, pstr_common_tables);
    669 
    670       if (ptr_sbr_data->coupling_mode !=
    671           (WORD16)ptr_prev_data_ch_0->coupling_mode) {
    672         if (ptr_prev_data_ch_0->coupling_mode == COUPLING_BAL) {
    673           memcpy(ptr_prev_data_ch_0->sfb_nrg_prev,
    674                  ptr_prev_data_ch_1->sfb_nrg_prev, sizeof(WORD16) * num);
    675         } else {
    676           if (ptr_sbr_data->coupling_mode == COUPLING_LEVEL) {
    677             ptr1 = ptr_prev_data_ch_0->sfb_nrg_prev;
    678             ptr2 = ptr_prev_data_ch_1->sfb_nrg_prev;
    679 
    680             for (i = 0; i < num; i++) {
    681               *ptr1 = (add16_m(*ptr1, *ptr2) >> 1);
    682               ptr2++;
    683               ptr1++;
    684             }
    685           } else {
    686             if (ptr_sbr_data->coupling_mode == COUPLING_BAL) {
    687               memset(ptr_prev_data_ch_0->sfb_nrg_prev, SBR_ENERGY_PAN_OFFSET,
    688                      sizeof(WORD16) * num);
    689             }
    690           }
    691         }
    692       }
    693     }
    694 
    695     memcpy(env_sf_local_arr, ptr_prev_data_ch_0->sfb_nrg_prev,
    696            sizeof(WORD16) * MAX_FREQ_COEFFS);
    697 
    698     ixheaacd_process_del_cod_env_data(ptr_header_data, ptr_sbr_data,
    699                                       ptr_prev_data_ch_0);
    700 
    701     if (!usac_flag) {
    702       error_code = ixheaacd_check_env_data(ptr_header_data, ptr_sbr_data,
    703                                            ptr_prev_data_ch_0);
    704 
    705       if (error_code) {
    706         ptr_header_data->err_flag = 1;
    707 
    708         memcpy(ptr_prev_data_ch_0->sfb_nrg_prev, env_sf_local_arr,
    709                sizeof(WORD16) * MAX_FREQ_COEFFS);
    710 
    711         ixheaacd_dec_envelope(ptr_header_data, ptr_sbr_data, ptr_prev_data_ch_0,
    712                               ptr_prev_data_ch_1, pstr_common_tables);
    713         return;
    714       }
    715     }
    716   }
    717   if (!usac_flag)
    718     ixheaacd_dequant_env_data(ptr_sbr_data, ptr_sbr_data->amp_res);
    719 }
    720 
    721 VOID ixheaacd_adj_timeslot(WORD32 *ptr_buf_real, WORD32 *ptr_buf_imag,
    722                            WORD16 *ptr_filt_buf, WORD16 *ptr_filt_buf_noise,
    723                            WORD16 *ptr_gain_buf, WORD16 *ptr_noise_floor,
    724                            WORD16 *ptr_sine_lvl_buf, WORD16 noise_floor_exp,
    725                            WORD16 *ptr_harm_index, WORD16 sub_band_start,
    726                            WORD16 num_sub_bands, WORD16 scale_change,
    727                            WORD16 smooth_ratio, FLAG num_noise_flg,
    728                            WORD16 *ptr_phase_index,
    729                            ia_sbr_tables_struct *ptr_sbr_tables) {
    730   WORD16 k;
    731   WORD16 *ptr_smoothed_gain, *ptr_smoothed_noise;
    732   WORD16 direct_ratio;
    733   WORD32 index = *ptr_phase_index;
    734   WORD32 harm_idx = *ptr_harm_index;
    735   WORD32 freq_inv_flag;
    736   const WORD32 *ptr_rand_ph_buf;
    737   WORD32 factor = 0;
    738 
    739   direct_ratio = ixheaacd_sub16_sat(0x7fff, smooth_ratio);
    740   freq_inv_flag = (sub_band_start & 1);
    741 
    742   scale_change = scale_change - 1;
    743 
    744   ptr_rand_ph_buf = &ptr_sbr_tables->sbr_rand_ph[index];
    745   *ptr_phase_index =
    746       (WORD16)((index + num_sub_bands) & (SBR_NF_NO_RANDOM_VAL - 1));
    747 
    748   if (smooth_ratio) {
    749     WORD16 *ptr_filt_buf_local = &ptr_filt_buf[0];
    750     WORD16 *ptr_gain_buf_local = &ptr_gain_buf[0];
    751     WORD16 *ptr_filt_noise_local = &ptr_filt_buf_noise[0];
    752     WORD16 *ptr_noise_floor_local = &ptr_noise_floor[0];
    753 
    754     WORD16 tmp, tmp1;
    755 
    756     for (k = 0; k < num_sub_bands; k++) {
    757       tmp = add16_m(mult16x16_16(smooth_ratio, *ptr_filt_buf_local),
    758                     mult16x16_16(direct_ratio, *ptr_gain_buf_local++));
    759 
    760       ptr_gain_buf_local++;
    761 
    762       tmp1 = add16_m(mult16x16_16(smooth_ratio, *ptr_filt_noise_local),
    763                      mult16x16_16(direct_ratio, *ptr_noise_floor_local++));
    764 
    765       ptr_noise_floor_local++;
    766 
    767       *ptr_filt_buf_local++ = tmp << 1;
    768       ptr_filt_buf_local++;
    769       *ptr_filt_noise_local++ = tmp1 << 1;
    770     }
    771     ptr_smoothed_gain = ptr_filt_buf;
    772     ptr_smoothed_noise = ptr_filt_buf_noise;
    773     factor = 1;
    774   } else {
    775     ptr_smoothed_gain = ptr_gain_buf;
    776     ptr_smoothed_noise = ptr_noise_floor;
    777     factor = 2;
    778   }
    779 
    780   switch (harm_idx) {
    781     case 0:
    782     case 2:
    783       ixheaacd_harm_idx_zerotwo(num_noise_flg, num_sub_bands, ptr_buf_real,
    784                                 ptr_buf_imag, ptr_smoothed_gain,
    785                                 ptr_smoothed_noise, factor, ptr_gain_buf,
    786                                 scale_change, ptr_rand_ph_buf, ptr_sine_lvl_buf,
    787                                 noise_floor_exp, harm_idx);
    788       break;
    789     case 1:
    790     case 3:
    791       ixheaacd_harm_idx_onethree(
    792           num_noise_flg, num_sub_bands, ptr_buf_real, ptr_buf_imag,
    793           ptr_smoothed_gain, ptr_smoothed_noise, factor, ptr_gain_buf,
    794           scale_change, ptr_rand_ph_buf, ptr_sine_lvl_buf, noise_floor_exp,
    795           freq_inv_flag, harm_idx);
    796       break;
    797   }
    798   *ptr_harm_index = (WORD16)((harm_idx + 1) & 3);
    799 }
    800