/******************************************************************************
 *                                                                            *
 * Copyright (C) 2018 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at:
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 *****************************************************************************
 * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
*/
#include <string.h>
#include "ixheaacd_sbr_common.h"
#include <ixheaacd_type_def.h>
#include "ixheaacd_error_standards.h"

#include "ixheaacd_constants.h"
#include <ixheaacd_basic_ops32.h>
#include <ixheaacd_basic_ops16.h>
#include <ixheaacd_basic_ops40.h>
#include "ixheaacd_basic_ops.h"

#include <ixheaacd_basic_op.h>
#include "ixheaacd_intrinsics.h"
#include "ixheaacd_bitbuffer.h"
#include "ixheaacd_sbrdecsettings.h"
#include "ixheaacd_sbr_scale.h"
#include "ixheaacd_lpp_tran.h"
#include "ixheaacd_env_extr_part.h"
#include <ixheaacd_sbr_rom.h>
#include "ixheaacd_hybrid.h"
#include "ixheaacd_ps_dec.h"

#include "ixheaacd_env_extr.h"
#include "ixheaacd_common_rom.h"
#include "ixheaacd_env_dec.h"
#include "ixheaacd_sbr_const.h"

#include "ixheaacd_basic_funcs.h"

#include "math.h"

#define add16_m(a, b) ((a) + (b))
#define sub16_m(a, b) ((a) - (b))

#define mult16x16_16(a, b) ixheaacd_mult16((a), (b))

static VOID ixheaacd_dequant_esbr_env_data(FLOAT32 *ptr_env_sf,
                                           WORD32 num_env_sf,
                                           WORD32 num_noise_fac, WORD32 amp_res,
                                           FLOAT32 *ptr_noise_floor) {
  WORD32 i;
  FLOAT32 array[2] = {0.5f, 1.0f};
  FLOAT32 a_flt = array[amp_res];

  for (i = 0; i < num_env_sf; i++) {
    ptr_env_sf[i] = (FLOAT32)(pow(2, ptr_env_sf[i] * a_flt) * 64);
  }

  for (i = 0; i < num_noise_fac; i++) {
    FLOAT32 temp = ptr_noise_floor[i];

    temp = NOISE_FLOOR_OFFSET - temp;
    temp = (FLOAT32)pow(2.0f, temp);

    ptr_noise_floor[i] = temp;
  }
}

static VOID ixheaacd_dequant_pvc_env_data(WORD32 num_noise_fac,
                                          FLOAT32 *ptr_noise_floor) {
  WORD32 i;

  for (i = 0; i < num_noise_fac; i++) {
    FLOAT32 temp = ptr_noise_floor[i];

    temp = NOISE_FLOOR_OFFSET - temp;
    temp = (FLOAT32)pow(2.0f, temp);

    ptr_noise_floor[i] = temp;
  }
}

VOID ixheaacd_map_res_energy(WORD16 curr_val, WORD16 *prev_data,
                             WORD32 ixheaacd_drc_offset, WORD32 index,
                             WORD32 res) {
  if (res == LOW) {
    if (ixheaacd_drc_offset >= 0) {
      if (index < ixheaacd_drc_offset) {
        prev_data[index] = curr_val;
      } else {
        WORD32 index_2;
        index_2 = ((index + index) - ixheaacd_drc_offset);
        prev_data[index_2] = curr_val;
        prev_data[index_2 + 1] = curr_val;
      }
    } else {
      ixheaacd_drc_offset = -(ixheaacd_drc_offset);

      if (index < ixheaacd_drc_offset) {
        WORD32 index_3;
        index_3 = ((index + index) + index);
        prev_data[index_3] = curr_val;
        prev_data[index_3 + 1] = curr_val;
        prev_data[index_3 + 2] = curr_val;
      } else {
        WORD32 index_2;
        index_2 = ((index + index) + ixheaacd_drc_offset);
        prev_data[index_2] = curr_val;
        prev_data[index_2 + 1] = curr_val;
      }
    }
  } else {
    prev_data[index] = curr_val;
  }
}

VOID ixheaacd_process_del_cod_env_data(
    ia_sbr_header_data_struct *ptr_header_data,
    ia_sbr_frame_info_data_struct *ptr_sbr_data,
    ia_sbr_prev_frame_data_struct *ptr_prev_data) {
  WORD32 i, dtdf_dir, num_sf_bands, band, freq_res;
  WORD16 temp_val;
  WORD16 *ptr_prev_env_sf = ptr_prev_data->sfb_nrg_prev;
  WORD16 *ptr_env_sf = ptr_sbr_data->int_env_sf_arr;

  FLOAT32 *ptr_env_sf_float = ptr_sbr_data->flt_env_sf_arr;

  WORD32 ixheaacd_drc_offset;
  band = 0;

  ixheaacd_drc_offset =
      ((ptr_header_data->pstr_freq_band_data->num_sf_bands[LOW] << 1) -
       ptr_header_data->pstr_freq_band_data->num_sf_bands[HIGH]);

  for (i = 0; i < ptr_sbr_data->str_frame_info_details.num_env; i++) {
    dtdf_dir = ptr_sbr_data->del_cod_dir_arr[i];
    freq_res = ptr_sbr_data->str_frame_info_details.freq_res[i];

    num_sf_bands = ptr_header_data->pstr_freq_band_data->num_sf_bands[freq_res];

    if (dtdf_dir == DTDF_DIR_FREQ) {
      ixheaacd_map_res_energy(*ptr_env_sf, ptr_prev_env_sf, ixheaacd_drc_offset,
                              0, freq_res);
      ptr_env_sf++;

      ptr_env_sf_float++;

      for (band = 1; band < num_sf_bands; band++) {
        *ptr_env_sf = *ptr_env_sf + *(ptr_env_sf - 1);
        ixheaacd_map_res_energy(*ptr_env_sf, ptr_prev_env_sf,
                                ixheaacd_drc_offset, band, freq_res);

        *ptr_env_sf_float = (FLOAT32)(*ptr_env_sf);
        ptr_env_sf_float++;

        ptr_env_sf++;
      }

    } else {
      if (freq_res == LOW) {
        if (ixheaacd_drc_offset < 0) {
          WORD32 tar, index_3;
          ixheaacd_drc_offset = -ixheaacd_drc_offset;
          tar = ixheaacd_min32(ixheaacd_drc_offset, band);

          for (band = 0; band < tar; band++) {
            index_3 = ((band + band) + band);
            temp_val = add16_m(*ptr_env_sf, ptr_prev_env_sf[index_3]);

            ptr_prev_env_sf[index_3] = temp_val;
            ptr_prev_env_sf[index_3 + 1] = temp_val;
            ptr_prev_env_sf[index_3 + 2] = temp_val;
            *ptr_env_sf++ = temp_val;

            *ptr_env_sf_float = (FLOAT32)temp_val;
            ptr_env_sf_float++;
          }

          for (; band < num_sf_bands; band++) {
            index_3 = (band << 1) + ixheaacd_drc_offset;
            temp_val = add16_m(*ptr_env_sf, ptr_prev_env_sf[index_3]);
            ptr_prev_env_sf[index_3] = temp_val;
            ptr_prev_env_sf[index_3 + 1] = temp_val;
            *ptr_env_sf++ = temp_val;
            *ptr_env_sf_float = (FLOAT32)temp_val;
            ptr_env_sf_float++;
          }
        } else {
          WORD32 tar, index_2;
          WORD16 *ptr2 = ptr_prev_env_sf;
          tar = ixheaacd_min32(ixheaacd_drc_offset, band);
          for (band = 0; band < tar; band++) {
            *ptr_env_sf = add16_m(*ptr_env_sf, *ptr2);
            *ptr2 = *ptr_env_sf;

            *ptr_env_sf_float = (FLOAT32)(*ptr_env_sf);
            ptr_env_sf_float++;

            ptr2++;
            ptr_env_sf++;
          }

          for (; band < num_sf_bands; band++) {
            index_2 = (band < ixheaacd_drc_offset)
                          ? band
                          : ((band << 1) - ixheaacd_drc_offset);
            temp_val = add16_m(*ptr_env_sf, ptr_prev_env_sf[index_2]);
            ptr_prev_env_sf[index_2] = temp_val;
            ptr_prev_env_sf[index_2 + 1] = temp_val;
            *ptr_env_sf++ = temp_val;

            *ptr_env_sf_float = (FLOAT32)temp_val;
            ptr_env_sf_float++;
          }
        }

      } else {
        WORD16 *ptr2 = ptr_prev_env_sf;
        for (band = num_sf_bands - 1; band >= 0; band--) {
          *ptr_env_sf = add16_m(*ptr_env_sf, *ptr2);
          *ptr2 = *ptr_env_sf;
          *ptr_env_sf_float = (FLOAT32)(*ptr_env_sf);
          ptr_env_sf_float++;
          ptr2++;
          ptr_env_sf++;
        }
        band = num_sf_bands;
      }
    }
  }
}

static PLATFORM_INLINE WORD32
ixheaacd_wrong_timing_compensate(ia_sbr_header_data_struct *ptr_header_data,
                                 ia_sbr_frame_info_data_struct *ptr_sbr_data,
                                 ia_sbr_prev_frame_data_struct *ptr_prev_data,
                                 ixheaacd_misc_tables *pstr_common_tables) {
  WORD32 i, num_env_sf;
  ia_frame_info_struct *p_frame_info = &ptr_sbr_data->str_frame_info_details;
  WORD16 *num_sf_bands = ptr_header_data->pstr_freq_band_data->num_sf_bands;
  WORD32 start_pos_est;
  WORD32 ref_len, new_len, shift;
  WORD16 delta_exp;

  start_pos_est =
      (ptr_prev_data->end_position - ptr_header_data->num_time_slots);

  ref_len = (p_frame_info->border_vec[1] - p_frame_info->border_vec[0]);

  new_len = (p_frame_info->border_vec[1] - start_pos_est);

  if (new_len <= 0) {
    new_len = ref_len;
    start_pos_est = p_frame_info->border_vec[0];
  }

  delta_exp = pstr_common_tables->log_dual_is_table[ref_len];
  delta_exp -= pstr_common_tables->log_dual_is_table[new_len];

  shift = (SHORT_BITS - ENV_EXP_FRACT - 3 - ptr_sbr_data->amp_res);
  delta_exp = ixheaacd_shr16(delta_exp, (WORD16)shift);
  p_frame_info->border_vec[0] = start_pos_est;
  p_frame_info->noise_border_vec[0] = start_pos_est;

  if (start_pos_est < 0) return -1;

  if (ptr_sbr_data->coupling_mode != COUPLING_BAL) {
    num_env_sf =
        ((p_frame_info->freq_res[0]) ? num_sf_bands[HIGH] : num_sf_bands[LOW]);

    for (i = 0; i < num_env_sf; i++) {
      ptr_sbr_data->int_env_sf_arr[i] =
          add16_m(ptr_sbr_data->int_env_sf_arr[i], delta_exp);
    }
  }

  return 0;
}

WORD16 ixheaacd_check_env_data(ia_sbr_header_data_struct *ptr_header_data,
                               ia_sbr_frame_info_data_struct *ptr_sbr_data,
                               ia_sbr_prev_frame_data_struct *ptr_prev_data) {
  WORD16 *ptr_evn_sf = ptr_sbr_data->int_env_sf_arr;
  WORD16 *ptr_prev_evn_sf = ptr_prev_data->sfb_nrg_prev;
  WORD32 i;
  FLAG error_code = 0;
  WORD16 sbr_max_env_sf;
  WORD32 amp_res = ptr_sbr_data->amp_res;

  sbr_max_env_sf = (SBR_ENV_SF_MAX_VAL_1_5 >> amp_res);

  for (i = 0; i < ptr_sbr_data->num_env_sfac; i++) {
    if (ptr_evn_sf[i] > sbr_max_env_sf) {
      error_code = 1;
    }
    if (ptr_evn_sf[i] < 0) {
      ptr_evn_sf[i] = 0;
    }
  }

  for (i = 0; i < ptr_header_data->pstr_freq_band_data->num_sf_bands[HIGH];
       i++) {
    if (ptr_prev_evn_sf[i] < 0) {
      ptr_prev_evn_sf[i] = 0;
    } else {
      if (ptr_prev_evn_sf[i] > sbr_max_env_sf)
        ptr_prev_evn_sf[i] = sbr_max_env_sf;
    }
  }
  return (WORD16)(error_code);
}

VOID ixheaacd_dequant_env_data(ia_sbr_frame_info_data_struct *ptr_sbr_data,
                               WORD32 amp_res) {
  WORD32 i;
  WORD32 num_env_sf = ptr_sbr_data->num_env_sfac;
  WORD32 mantissa;
  WORD32 amp_res_1;
  WORD32 exponent;
  WORD32 exp_add = (7 + NRG_EXP_OFFSET);
  WORD16 *ptr_env_sf = ptr_sbr_data->int_env_sf_arr;
  WORD32 mant_arr[2] = {0x4000, 0x5a80};

  amp_res_1 = (1 - amp_res);

  for (i = num_env_sf - 1; i >= 0; i--) {
    exponent = *ptr_env_sf;
    mantissa = mant_arr[(exponent & amp_res_1)];
    exponent = (exponent >> amp_res_1);
    exponent = (exponent + exp_add);
    *ptr_env_sf++ = (WORD16)(mantissa | (exponent & MASK_FOR_EXP));
  }
}

static PLATFORM_INLINE VOID
ixheaacd_limit_noise_floor_fac(ia_sbr_header_data_struct *ptr_header_data,
                               ia_sbr_frame_info_data_struct *ptr_sbr_data) {
  WORD32 i, tot_nf_bands;
  WORD32 value;
  WORD32 num_nf_bands;
  WORD16 *ptr_noise_floor;

  num_nf_bands = ptr_header_data->pstr_freq_band_data->num_nf_bands;

  tot_nf_bands =
      ptr_sbr_data->str_frame_info_details.num_noise_env * num_nf_bands;

  ptr_noise_floor = ptr_sbr_data->int_noise_floor;

  for (i = tot_nf_bands - 1; i >= 0; i--) {
    value = *ptr_noise_floor;
    if (value > MAX_NOISE_FLOOR_FAC_VAL) {
      *ptr_noise_floor = MAX_NOISE_FLOOR_FAC_VAL;
    } else {
      if (value < MIN_NOISE_FLOOR_FAC_VAL) {
        *ptr_noise_floor = MIN_NOISE_FLOOR_FAC_VAL;
      }
    }
    ptr_noise_floor++;
  }
}

VOID ixheaacd_add_arr(WORD16 *ptr1, WORD16 *ptr2, WORD32 num) {
  WORD32 i;
  for (i = num - 1; i >= 0; i--) {
    *ptr2 = (*ptr2 + *ptr1);
    ptr2++;
    ptr1++;
  }
}

IA_ERRORCODE ixheaacd_calc_noise_floor(
    ia_sbr_header_data_struct *ptr_header_data,
    ia_sbr_frame_info_data_struct *ptr_sbr_data,
    ia_sbr_prev_frame_data_struct *ptr_prev_data) {
  WORD32 i;
  WORD32 num_nf_bands;
  WORD32 num_noise_env;
  WORD32 ixheaacd_drc_offset;
  WORD16 *ptr_noise_floor = ptr_sbr_data->int_noise_floor;

  WORD16 *ptr_prev_noise_floor = ptr_prev_data->prev_noise_level;
  WORD16 *ptr1, *ptr2;
  WORD32 num;
  FLOAT32 *ptr_noise_floor_float = ptr_sbr_data->flt_noise_floor;

  num_nf_bands = ptr_header_data->pstr_freq_band_data->num_nf_bands;
  num_noise_env = ptr_sbr_data->str_frame_info_details.num_noise_env;

  if (ptr_sbr_data->del_cod_dir_noise_arr[0] == DTDF_DIR_FREQ) {
    ptr1 = ptr_noise_floor++;
    ptr2 = ptr_noise_floor;
    num = num_nf_bands - 1;
  } else {
    ptr1 = ptr_prev_noise_floor;
    ptr2 = ptr_sbr_data->int_noise_floor;
    num = num_nf_bands;
  }

  ixheaacd_add_arr(ptr1, ptr2, num);

  if (num_noise_env > 1) {
    if (ptr_sbr_data->del_cod_dir_noise_arr[1] == DTDF_DIR_FREQ) {
      ptr1 = &ptr_sbr_data->int_noise_floor[num_nf_bands];
      ptr2 = &ptr_sbr_data->int_noise_floor[(num_nf_bands + 1)];

      num = num_nf_bands - 1;
    } else {
      ptr1 = &ptr_sbr_data->int_noise_floor[0];
      ptr2 = &ptr_sbr_data->int_noise_floor[num_nf_bands];

      num = num_nf_bands;
    }
    ixheaacd_add_arr(ptr1, ptr2, num);
  }

  ixheaacd_limit_noise_floor_fac(ptr_header_data, ptr_sbr_data);

  ixheaacd_drc_offset = num_nf_bands * (num_noise_env - 1);
  if (ixheaacd_drc_offset < 0 || ixheaacd_drc_offset >= MAX_NUM_NOISE_VALUES)
    return IA_FATAL_ERROR;
  ptr1 = &ptr_sbr_data->int_noise_floor[ixheaacd_drc_offset];
  ptr2 = ptr_prev_noise_floor;

  memcpy(ptr2, ptr1, sizeof(WORD16) * (num_nf_bands));

  if (ptr_sbr_data->coupling_mode != COUPLING_BAL) {
    WORD32 noise_floor_exp, tot_nf_bands;

    tot_nf_bands = (num_nf_bands * num_noise_env);
    ptr_noise_floor = &ptr_sbr_data->int_noise_floor[0];

    for (i = 0; i < tot_nf_bands; i++) {
      noise_floor_exp =
          (NOISE_FLOOR_OFFSET_INT + 1 + NOISE_EXP_OFFSET - *ptr_noise_floor);

      *ptr_noise_floor_float++ = *ptr_noise_floor;
      *ptr_noise_floor++ = (WORD16)(0x4000 + (noise_floor_exp & MASK_FOR_EXP));
    }
  }
  return IA_NO_ERROR;
}

IA_ERRORCODE ixheaacd_dec_sbrdata_for_pvc(
    ia_sbr_header_data_struct *ptr_header_data,
    ia_sbr_frame_info_data_struct *ptr_sbr_data,
    ia_sbr_prev_frame_data_struct *ptr_prev_data) {
  WORD32 err = 0;
  err = ixheaacd_calc_noise_floor(ptr_header_data, ptr_sbr_data, ptr_prev_data);
  if (err) return err;

  if (!ptr_sbr_data->coupling_mode) {
    ptr_sbr_data->num_noise_sfac =
        ptr_header_data->pstr_freq_band_data->num_nf_bands *
        ptr_sbr_data->str_frame_info_details.num_noise_env;
    ixheaacd_dequant_pvc_env_data(ptr_sbr_data->num_noise_sfac,
                                  ptr_sbr_data->flt_noise_floor);
  }
  return IA_NO_ERROR;
}

VOID ixheaacd_sbr_env_dequant_coup_fix(
    ia_sbr_header_data_struct *ptr_header_data,
    ia_sbr_frame_info_data_struct *ptr_data_left,
    ia_sbr_frame_info_data_struct *ptr_data_right,
    ixheaacd_misc_tables *pstr_common_tables) {
  WORD32 i;
  WORD32 num_env_sf = ptr_data_left->num_env_sfac;
  WORD16 temp_left_mant, temp_right_mant, temp_right_plus1_mant, new_left_mant,
      new_right_mant;
  WORD16 temp_left_exp, temp_right_exp, temp_rightplus1_exp, new_left_exp,
      new_right_exp;
  WORD32 i_end;
  WORD16 *r_data = ptr_data_right->int_env_sf_arr;
  WORD16 *l_data = ptr_data_left->int_env_sf_arr;

  for (i = 0; i < num_env_sf; i++) {
    temp_right_mant = (WORD16)(*r_data & MASK_M);
    temp_right_exp = (WORD16)(*r_data & MASK_FOR_EXP);

    temp_right_exp = sub16_m(temp_right_exp, add16_m(18, NRG_EXP_OFFSET));
    temp_left_mant = (WORD16)(*l_data & MASK_M);
    temp_left_exp = (WORD16)(*l_data & MASK_FOR_EXP);

    temp_left_exp = sub16_m(temp_left_exp, NRG_EXP_OFFSET);

    ixheaacd_fix_mant_exp_add(temp_right_mant, temp_right_exp, 0x4000, 1,
                              &temp_right_plus1_mant, &temp_rightplus1_exp);

    new_right_exp = ixheaacd_fix_mant_div(temp_left_mant, temp_right_plus1_mant,
                                          &new_right_mant, pstr_common_tables);

    new_right_exp += temp_left_exp - temp_rightplus1_exp + 2;

    new_left_mant = ixheaacd_mult16_shl(temp_right_mant, new_right_mant);

    new_left_exp = add16_m(temp_right_exp, new_right_exp);

    *r_data++ = (WORD16)(((new_right_mant + ROUNDING) & MASK_M) +
                         ((new_right_exp + NRG_EXP_OFFSET) & MASK_FOR_EXP));
    *l_data++ = (WORD16)(((new_left_mant + ROUNDING) & MASK_M) +
                         ((new_left_exp + NRG_EXP_OFFSET) & MASK_FOR_EXP));
  }

  i_end = ptr_header_data->pstr_freq_band_data->num_nf_bands *
          ptr_data_left->str_frame_info_details.num_noise_env;
  r_data = ptr_data_right->int_noise_floor;
  l_data = ptr_data_left->int_noise_floor;

  for (i = i_end - 1; i >= 0; i--) {
    temp_left_exp =
        sub16_m((WORD16)(*l_data & (WORD16)MASK_FOR_EXP), NOISE_EXP_OFFSET);
    temp_right_exp = sub16_m(*r_data, 12);

    ixheaacd_fix_mant_exp_add(0x4000, ixheaacd_add16(1, temp_right_exp), 0x4000,
                              1, &temp_right_plus1_mant, &temp_rightplus1_exp);

    new_right_exp = ixheaacd_fix_mant_div(0x4000, temp_right_plus1_mant,
                                          &new_right_mant, pstr_common_tables);

    new_right_exp += temp_left_exp - temp_rightplus1_exp + 2;

    new_left_mant = new_right_mant;
    new_left_exp = add16_m(new_right_exp, temp_right_exp);
    *r_data++ = (WORD16)(((new_right_mant + ROUNDING) & MASK_M) +
                         ((new_right_exp + NOISE_EXP_OFFSET) & MASK_FOR_EXP));
    *l_data++ = (WORD16)(((new_left_mant + ROUNDING) & MASK_M) +
                         ((new_left_exp + NOISE_EXP_OFFSET) & MASK_FOR_EXP));
  }
}

VOID ixheaacd_sbr_env_dequant_coup(
    ia_sbr_frame_info_data_struct *ptr_data_ch_0,
    ia_sbr_frame_info_data_struct *ptr_data_ch_1) {
  FLOAT32 *ptr_env_sf_left = ptr_data_ch_0->flt_env_sf_arr;
  FLOAT32 *ptr_env_sf_right = ptr_data_ch_1->flt_env_sf_arr;
  FLOAT32 *ptr_noise_floor_left = ptr_data_ch_0->flt_noise_floor;
  FLOAT32 *ptr_noise_floor_right = ptr_data_ch_1->flt_noise_floor;
  WORD32 num_env_sf = ptr_data_ch_0->num_env_sfac;
  WORD32 num_noise_fac = ptr_data_ch_0->num_noise_sfac;
  WORD32 amp_res = ptr_data_ch_0->amp_res;

  WORD32 i;
  FLOAT32 temp_l, temp_r;
  FLOAT32 pan_offset[2] = {24.0f, 12.0f};
  FLOAT32 a_arr[2] = {0.5f, 1.0f};

  FLOAT32 a = a_arr[amp_res];

  for (i = 0; i < num_env_sf; i++) {
    temp_l = ptr_env_sf_left[i];
    temp_r = ptr_env_sf_right[i];

    ptr_env_sf_left[i] =
        (FLOAT32)(64 * (pow(2, temp_l * a + 1) /
                        (1 + pow(2, (pan_offset[amp_res] - temp_r) * a))));
    ptr_env_sf_right[i] =
        (FLOAT32)(64 * (pow(2, temp_l * a + 1) /
                        (1 + pow(2, (temp_r - pan_offset[amp_res]) * a))));
  }

  for (i = 0; i < num_noise_fac; i++) {
    temp_l = ptr_noise_floor_left[i];
    temp_r = ptr_noise_floor_right[i];

    ptr_noise_floor_left[i] =
        (FLOAT32)(pow(2, NOISE_FLOOR_OFFSET - temp_l + 1) /
                  (1 + pow(2, pan_offset[1] - temp_r)));
    ptr_noise_floor_right[i] =
        (FLOAT32)(pow(2, NOISE_FLOOR_OFFSET - temp_l + 1) /
                  (1 + pow(2, temp_r - pan_offset[1])));
  }
}
WORD32 ixheaacd_dec_sbrdata(ia_sbr_header_data_struct *ptr_header_data_ch_0,
                            ia_sbr_header_data_struct *ptr_header_data_ch_1,
                            ia_sbr_frame_info_data_struct *ptr_sbr_data_ch_0,
                            ia_sbr_prev_frame_data_struct *ptr_prev_data_ch_0,
                            ia_sbr_frame_info_data_struct *ptr_sbr_data_ch_1,
                            ia_sbr_prev_frame_data_struct *ptr_prev_data_ch_1,
                            ixheaacd_misc_tables *ptr_common_tables) {
  FLAG error_code;
  WORD32 err = 0;
  WORD32 usac_flag = ptr_header_data_ch_0->usac_flag;

  err = ixheaacd_dec_envelope(ptr_header_data_ch_0, ptr_sbr_data_ch_0,
                              ptr_prev_data_ch_0, ptr_prev_data_ch_1,
                              ptr_common_tables);

  if (err) return err;

  err = ixheaacd_calc_noise_floor(ptr_header_data_ch_0, ptr_sbr_data_ch_0,
                                  ptr_prev_data_ch_0);

  if (err == (WORD32)IA_FATAL_ERROR) return (WORD32)IA_FATAL_ERROR;

  if (!ptr_sbr_data_ch_0->coupling_mode && usac_flag) {
    ptr_sbr_data_ch_0->num_noise_sfac =
        ptr_header_data_ch_0->pstr_freq_band_data->num_nf_bands *
        ptr_sbr_data_ch_0->str_frame_info_details.num_noise_env;

    ixheaacd_dequant_esbr_env_data(
        ptr_sbr_data_ch_0->flt_env_sf_arr, ptr_sbr_data_ch_0->num_env_sfac,
        ptr_sbr_data_ch_0->num_noise_sfac, ptr_sbr_data_ch_0->amp_res,
        ptr_sbr_data_ch_0->flt_noise_floor);
  }

  if (ptr_sbr_data_ch_1 != NULL) {
    error_code = ptr_header_data_ch_0->err_flag;
    err = ixheaacd_dec_envelope(ptr_header_data_ch_1, ptr_sbr_data_ch_1,
                                ptr_prev_data_ch_1, ptr_prev_data_ch_0,
                                ptr_common_tables);

    if (err) return err;

    err = ixheaacd_calc_noise_floor(ptr_header_data_ch_1, ptr_sbr_data_ch_1,
                                    ptr_prev_data_ch_1);

    if (err) return err;

    if (!ptr_sbr_data_ch_1->coupling_mode && usac_flag) {
      ptr_sbr_data_ch_1->num_noise_sfac =
          ptr_header_data_ch_1->pstr_freq_band_data->num_nf_bands *
          ptr_sbr_data_ch_1->str_frame_info_details.num_noise_env;

      ixheaacd_dequant_esbr_env_data(
          ptr_sbr_data_ch_1->flt_env_sf_arr, ptr_sbr_data_ch_1->num_env_sfac,
          ptr_sbr_data_ch_1->num_noise_sfac, ptr_sbr_data_ch_1->amp_res,
          ptr_sbr_data_ch_1->flt_noise_floor);
    }

    if (!usac_flag) {
      if (!error_code && ptr_header_data_ch_0->err_flag) {
        err = ixheaacd_dec_envelope(ptr_header_data_ch_0, ptr_sbr_data_ch_0,
                                    ptr_prev_data_ch_0, ptr_prev_data_ch_1,
                                    ptr_common_tables);

        if (err) return err;
      }
    }

    if (ptr_sbr_data_ch_0->coupling_mode) {
      ixheaacd_sbr_env_dequant_coup_fix(ptr_header_data_ch_0, ptr_sbr_data_ch_0,
                                        ptr_sbr_data_ch_1, ptr_common_tables);

      ixheaacd_sbr_env_dequant_coup(ptr_sbr_data_ch_0, ptr_sbr_data_ch_1);
    }
  }

  return 0;
}
WORD32 ixheaacd_dec_envelope(ia_sbr_header_data_struct *ptr_header_data,
                             ia_sbr_frame_info_data_struct *ptr_sbr_data,
                             ia_sbr_prev_frame_data_struct *ptr_prev_data_ch_0,
                             ia_sbr_prev_frame_data_struct *ptr_prev_data_ch_1,
                             ixheaacd_misc_tables *pstr_common_tables) {
  FLAG error_code;
  WORD32 err;
  WORD16 env_sf_local_arr[MAX_FREQ_COEFFS];
  WORD32 usac_flag = ptr_header_data->usac_flag;
  WORD32 temp_1 =
      ptr_prev_data_ch_0->end_position - ptr_header_data->num_time_slots;
  if (temp_1 < 0) return -1;
  temp_1 = ptr_sbr_data->str_frame_info_details.border_vec[0] - temp_1;

  if ((!ptr_header_data->err_flag_prev) && (!ptr_header_data->err_flag) &&
      (temp_1 != 0)) {
    if (ptr_sbr_data->del_cod_dir_arr[0] == DTDF_DIR_TIME) {
      ptr_header_data->err_flag = 1;
    } else {
      ptr_header_data->err_flag_prev = 1;
    }
  }

  if (ptr_header_data->err_flag && !usac_flag) {
    ixheaacd_lean_sbrconcealment(ptr_header_data, ptr_sbr_data,
                                 ptr_prev_data_ch_0);

    ixheaacd_process_del_cod_env_data(ptr_header_data, ptr_sbr_data,
                                      ptr_prev_data_ch_0);
  } else {
    WORD32 num = ptr_header_data->pstr_freq_band_data->num_sf_bands[HIGH];
    if (ptr_header_data->err_flag_prev && !usac_flag) {
      WORD16 *ptr1, *ptr2;
      WORD32 i;

      err = ixheaacd_wrong_timing_compensate(ptr_header_data, ptr_sbr_data,
                                             ptr_prev_data_ch_0,
                                             pstr_common_tables);

      if (err) return err;

      if (ptr_sbr_data->coupling_mode !=
          (WORD16)ptr_prev_data_ch_0->coupling_mode) {
        if (ptr_prev_data_ch_0->coupling_mode == COUPLING_BAL) {
          memcpy(ptr_prev_data_ch_0->sfb_nrg_prev,
                 ptr_prev_data_ch_1->sfb_nrg_prev, sizeof(WORD16) * num);
        } else {
          if (ptr_sbr_data->coupling_mode == COUPLING_LEVEL) {
            ptr1 = ptr_prev_data_ch_0->sfb_nrg_prev;
            ptr2 = ptr_prev_data_ch_1->sfb_nrg_prev;

            for (i = 0; i < num; i++) {
              *ptr1 = (add16_m(*ptr1, *ptr2) >> 1);
              ptr2++;
              ptr1++;
            }
          } else {
            if (ptr_sbr_data->coupling_mode == COUPLING_BAL) {
              memset(ptr_prev_data_ch_0->sfb_nrg_prev, SBR_ENERGY_PAN_OFFSET,
                     sizeof(WORD16) * num);
            }
          }
        }
      }
    }

    memcpy(env_sf_local_arr, ptr_prev_data_ch_0->sfb_nrg_prev,
           sizeof(WORD16) * MAX_FREQ_COEFFS);

    ixheaacd_process_del_cod_env_data(ptr_header_data, ptr_sbr_data,
                                      ptr_prev_data_ch_0);

    if (!usac_flag) {
      error_code = ixheaacd_check_env_data(ptr_header_data, ptr_sbr_data,
                                           ptr_prev_data_ch_0);

      if (error_code) {
        ptr_header_data->err_flag = 1;

        memcpy(ptr_prev_data_ch_0->sfb_nrg_prev, env_sf_local_arr,
               sizeof(WORD16) * MAX_FREQ_COEFFS);

        err = ixheaacd_dec_envelope(ptr_header_data, ptr_sbr_data,
                                    ptr_prev_data_ch_0, ptr_prev_data_ch_1,
                                    pstr_common_tables);

        if (err) return err;
        return 0;
      }
    }
  }
  if (!usac_flag)
    ixheaacd_dequant_env_data(ptr_sbr_data, ptr_sbr_data->amp_res);

  return 0;
}

VOID ixheaacd_adj_timeslot(WORD32 *ptr_buf_real, WORD32 *ptr_buf_imag,
                           WORD16 *ptr_filt_buf, WORD16 *ptr_filt_buf_noise,
                           WORD16 *ptr_gain_buf, WORD16 *ptr_noise_floor,
                           WORD16 *ptr_sine_lvl_buf, WORD16 noise_floor_exp,
                           WORD16 *ptr_harm_index, WORD16 sub_band_start,
                           WORD16 num_sub_bands, WORD16 scale_change,
                           WORD16 smooth_ratio, FLAG num_noise_flg,
                           WORD16 *ptr_phase_index,
                           ia_sbr_tables_struct *ptr_sbr_tables) {
  WORD16 k;
  WORD16 *ptr_smoothed_gain, *ptr_smoothed_noise;
  WORD16 direct_ratio;
  WORD32 index = *ptr_phase_index;
  WORD32 harm_idx = *ptr_harm_index;
  WORD32 freq_inv_flag;
  const WORD32 *ptr_rand_ph_buf;
  WORD32 factor = 0;

  direct_ratio = ixheaacd_sub16_sat(0x7fff, smooth_ratio);
  freq_inv_flag = (sub_band_start & 1);

  scale_change = scale_change - 1;

  ptr_rand_ph_buf = &ptr_sbr_tables->sbr_rand_ph[index];
  *ptr_phase_index =
      (WORD16)((index + num_sub_bands) & (SBR_NF_NO_RANDOM_VAL - 1));

  if (smooth_ratio) {
    WORD16 *ptr_filt_buf_local = &ptr_filt_buf[0];
    WORD16 *ptr_gain_buf_local = &ptr_gain_buf[0];
    WORD16 *ptr_filt_noise_local = &ptr_filt_buf_noise[0];
    WORD16 *ptr_noise_floor_local = &ptr_noise_floor[0];

    WORD16 tmp, tmp1;

    for (k = 0; k < num_sub_bands; k++) {
      tmp = add16_m(mult16x16_16(smooth_ratio, *ptr_filt_buf_local),
                    mult16x16_16(direct_ratio, *ptr_gain_buf_local++));

      ptr_gain_buf_local++;

      tmp1 = add16_m(mult16x16_16(smooth_ratio, *ptr_filt_noise_local),
                     mult16x16_16(direct_ratio, *ptr_noise_floor_local++));

      ptr_noise_floor_local++;

      *ptr_filt_buf_local++ = tmp << 1;
      ptr_filt_buf_local++;
      *ptr_filt_noise_local++ = tmp1 << 1;
    }
    ptr_smoothed_gain = ptr_filt_buf;
    ptr_smoothed_noise = ptr_filt_buf_noise;
    factor = 1;
  } else {
    ptr_smoothed_gain = ptr_gain_buf;
    ptr_smoothed_noise = ptr_noise_floor;
    factor = 2;
  }

  switch (harm_idx) {
    case 0:
    case 2:
      ixheaacd_harm_idx_zerotwo(num_noise_flg, num_sub_bands, ptr_buf_real,
                                ptr_buf_imag, ptr_smoothed_gain,
                                ptr_smoothed_noise, factor, ptr_gain_buf,
                                scale_change, ptr_rand_ph_buf, ptr_sine_lvl_buf,
                                noise_floor_exp, harm_idx);
      break;
    case 1:
    case 3:
      ixheaacd_harm_idx_onethree(
          num_noise_flg, num_sub_bands, ptr_buf_real, ptr_buf_imag,
          ptr_smoothed_gain, ptr_smoothed_noise, factor, ptr_gain_buf,
          scale_change, ptr_rand_ph_buf, ptr_sine_lvl_buf, noise_floor_exp,
          freq_inv_flag, harm_idx);
      break;
  }
  *ptr_harm_index = (WORD16)((harm_idx + 1) & 3);
}
