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