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 <math.h>
     22 #include "ixheaacd_sbr_common.h"
     23 #include <ixheaacd_type_def.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 #include "ixheaacd_defines.h"
     31 
     32 #include "ixheaacd_intrinsics.h"
     33 #include "ixheaacd_sbr_const.h"
     34 #include <ixheaacd_basic_op.h>
     35 #include "ixheaacd_defines.h"
     36 #include "ixheaacd_bitbuffer.h"
     37 #include "ixheaacd_pns.h"
     38 
     39 #include <ixheaacd_aac_rom.h>
     40 #include "ixheaacd_pulsedata.h"
     41 
     42 #include "ixheaacd_drc_data_struct.h"
     43 #include "ixheaacd_lt_predict.h"
     44 #include "ixheaacd_channelinfo.h"
     45 #include "ixheaacd_drc_dec.h"
     46 
     47 #include "ixheaacd_sbrdecoder.h"
     48 
     49 #include "ixheaacd_sbrdecsettings.h"
     50 #include "ixheaacd_sbr_scale.h"
     51 #include "ixheaacd_lpp_tran.h"
     52 #include "ixheaacd_env_extr_part.h"
     53 #include <ixheaacd_sbr_rom.h>
     54 #include "ixheaacd_hybrid.h"
     55 #include "ixheaacd_ps_dec.h"
     56 #include "ixheaacd_ps_bitdec.h"
     57 #include "ixheaacd_env_extr.h"
     58 #include "ixheaacd_common_rom.h"
     59 #include "ixheaacd_freq_sca.h"
     60 
     61 #include "ixheaacd_qmf_dec.h"
     62 
     63 #include "ixheaacd_env_calc.h"
     64 
     65 #include "ixheaacd_pvc_dec.h"
     66 #include "ixheaacd_sbr_dec.h"
     67 #include "ixheaacd_env_dec.h"
     68 #include "ixheaacd_basic_funcs.h"
     69 #include "ixheaacd_sbr_crc.h"
     70 #include "ixheaacd_function_selector.h"
     71 
     72 #include "ixheaacd_audioobjtypes.h"
     73 
     74 #define ALIGN_SIZE64(x) ((((x) + 7) >> 3) << 3)
     75 
     76 static FLOAT32 ixheaacd_new_bw_table[4][4] = {{0.00f, 0.60f, 0.90f, 0.98f},
     77                                               {0.60f, 0.75f, 0.90f, 0.98f},
     78                                               {0.00f, 0.75f, 0.90f, 0.98f},
     79                                               {0.00f, 0.75f, 0.90f, 0.98f}};
     80 static WORD32 ixheaacd_inew_bw_table[4][4] = {
     81     {0x00000000, 0x4ccccccd, 0x73333333, 0x7d70a3d7},
     82     {0x4ccccccd, 0x60000000, 0x73333333, 0x7d70a3d7},
     83     {0x00000000, 0x60000000, 0x73333333, 0x7d70a3d7},
     84     {0x00000000, 0x60000000, 0x73333333, 0x7d70a3d7}};
     85 
     86 VOID ixheaacd_reset_sbrenvelope_calc(ia_sbr_calc_env_struct *h_cal_env) {
     87   h_cal_env->ph_index = 0;
     88   h_cal_env->filt_buf_noise_e = 0;
     89   h_cal_env->start_up = 1;
     90 }
     91 
     92 WORD32 ixheaacd_derive_lim_band_tbl(
     93     ia_sbr_header_data_struct *ptr_header_data,
     94     const ia_patch_param_struct *p_str_patch_param, WORD16 num_patches,
     95     ixheaacd_misc_tables *pstr_common_tables) {
     96   WORD32 i, k, k_1;
     97   WORD32 nr_lim, patch_border_k, patch_border_k_1, temp_nr_lim;
     98 
     99   WORD16 lim_table[MAX_FREQ_COEFFS / 2 + MAX_NUM_PATCHES + 1];
    100   WORD16 patch_borders[MAX_NUM_PATCHES + 1];
    101   WORD16 kx, k2;
    102   WORD16 temp, lim_bands, num_octaves;
    103 
    104   WORD16 *f_lim_tbl = ptr_header_data->pstr_freq_band_data->freq_band_tbl_lim;
    105   WORD16 *num_lf_bands = &ptr_header_data->pstr_freq_band_data->num_lf_bands;
    106   WORD16 *f_low_tbl =
    107       ptr_header_data->pstr_freq_band_data->freq_band_table[LOW];
    108   WORD16 num_low_bnd = ptr_header_data->pstr_freq_band_data->num_sf_bands[LOW];
    109   WORD16 limiter_bands = ptr_header_data->limiter_bands;
    110 
    111   WORD16 sub_band_start = f_low_tbl[0];
    112   WORD16 sub_band_end = f_low_tbl[num_low_bnd];
    113   WORD16 limbnd_per_oct[4] = {(WORD16)0x2000, (WORD16)0x2666, (WORD16)0x4000,
    114                               (WORD16)0x6000};
    115 
    116   if (limiter_bands == 0) {
    117     f_lim_tbl[0] = 0;
    118     f_lim_tbl[1] = sub_band_end - sub_band_start;
    119     nr_lim = 1;
    120   } else {
    121     for (k = 0; k < num_patches; k++) {
    122       patch_borders[k] = p_str_patch_param[k].guard_start_band - sub_band_start;
    123     }
    124     patch_borders[k] = sub_band_end - sub_band_start;
    125 
    126     for (k = 0; k <= num_low_bnd; k++) {
    127       lim_table[k] = f_low_tbl[k] - sub_band_start;
    128     }
    129     for (k = 1; k < num_patches; k++) {
    130       lim_table[num_low_bnd + k] = patch_borders[k];
    131     }
    132 
    133     temp_nr_lim = nr_lim = (num_low_bnd + num_patches) - 1;
    134     ixheaacd_aac_shellsort(lim_table, (temp_nr_lim + 1));
    135 
    136     k = 1;
    137     k_1 = 0;
    138 
    139     lim_bands = limbnd_per_oct[limiter_bands];
    140 
    141     while ((k - temp_nr_lim) <= 0) {
    142       k2 = lim_table[k] + sub_band_start;
    143       kx = lim_table[k_1] + sub_band_start;
    144 
    145       num_octaves = pstr_common_tables->log_dual_is_table[k2];
    146       num_octaves -= pstr_common_tables->log_dual_is_table[kx];
    147 
    148       temp = (WORD16)(((WORD32)lim_bands * (WORD32)num_octaves) >> 15);
    149 
    150       if (temp < 0x01f6) {
    151         if (lim_table[k_1] == lim_table[k]) {
    152           lim_table[k] = sub_band_end;
    153           nr_lim = nr_lim - 1;
    154           k = (k + 1);
    155           continue;
    156         }
    157         patch_border_k_1 = patch_border_k = 0;
    158 
    159         for (i = 0; i <= num_patches; i++) {
    160           if (lim_table[k] == patch_borders[i]) {
    161             patch_border_k = 1;
    162           }
    163           if (lim_table[k_1] == patch_borders[i]) {
    164             patch_border_k_1 = 1;
    165           }
    166         }
    167         if (!patch_border_k) {
    168           lim_table[k] = sub_band_end;
    169           nr_lim = nr_lim - 1;
    170           k = (k + 1);
    171           continue;
    172         }
    173 
    174         if (!patch_border_k_1) {
    175           lim_table[k_1] = sub_band_end;
    176           nr_lim = nr_lim - 1;
    177         }
    178       }
    179       k_1 = k;
    180       k = (k + 1);
    181     }
    182     ixheaacd_aac_shellsort(lim_table, (temp_nr_lim + 1));
    183 
    184     memcpy(f_lim_tbl, lim_table, sizeof(WORD16) * (nr_lim + 1));
    185   }
    186   *num_lf_bands = nr_lim;
    187 
    188   return 0;
    189 }
    190 
    191 VOID ixheaacd_lean_sbrconcealment(
    192     ia_sbr_header_data_struct *ptr_header_data,
    193     ia_sbr_frame_info_data_struct *ptr_sbr_data,
    194     ia_sbr_prev_frame_data_struct *ptr_prev_data) {
    195   WORD32 target;
    196   WORD32 step;
    197   WORD32 i;
    198 
    199   WORD16 cur_start_pos;
    200   WORD16 cur_stop_pos;
    201 
    202   ptr_sbr_data->amp_res = ptr_prev_data->amp_res;
    203   ptr_sbr_data->coupling_mode = ptr_prev_data->coupling_mode;
    204   ptr_sbr_data->max_qmf_subband_aac = ptr_prev_data->max_qmf_subband_aac;
    205 
    206   memcpy(ptr_sbr_data->sbr_invf_mode, ptr_prev_data->sbr_invf_mode,
    207          sizeof(WORD32) * MAX_INVF_BANDS);
    208 
    209   ptr_sbr_data->str_frame_info_details.num_env = 1;
    210 
    211   cur_start_pos = ptr_prev_data->end_position - ptr_header_data->num_time_slots;
    212   cur_stop_pos = ptr_header_data->num_time_slots;
    213 
    214   ptr_sbr_data->str_frame_info_details.border_vec[0] = cur_start_pos;
    215   ptr_sbr_data->str_frame_info_details.border_vec[1] = cur_stop_pos;
    216 
    217   ptr_sbr_data->str_frame_info_details.noise_border_vec[0] = cur_start_pos;
    218   ptr_sbr_data->str_frame_info_details.noise_border_vec[1] = cur_stop_pos;
    219   ;
    220 
    221   ptr_sbr_data->str_frame_info_details.freq_res[0] = 1;
    222   ptr_sbr_data->str_frame_info_details.transient_env = -1;
    223   ptr_sbr_data->str_frame_info_details.num_noise_env = 1;
    224 
    225   ptr_sbr_data->num_env_sfac =
    226       ptr_header_data->pstr_freq_band_data->num_sf_bands[1];
    227 
    228   ptr_sbr_data->del_cod_dir_arr[0] = DTDF_DIR_TIME;
    229 
    230   if (ptr_sbr_data->coupling_mode == COUPLING_BAL) {
    231     target = SBR_ENERGY_PAN_OFFSET;
    232   } else {
    233     target = 0;
    234   }
    235 
    236   step = 1;
    237 
    238   if (ptr_sbr_data->amp_res - SBR_AMPLITUDE_RESOLUTION_1_5 == 0) {
    239     target = (target << 1);
    240     step = (step << 1);
    241   }
    242 
    243   for (i = 0; i < ptr_sbr_data->num_env_sfac; i++) {
    244     if (ptr_prev_data->sfb_nrg_prev[i] > target)
    245       ptr_sbr_data->int_env_sf_arr[i] = -(step);
    246     else
    247       ptr_sbr_data->int_env_sf_arr[i] = step;
    248   }
    249 
    250   ptr_sbr_data->del_cod_dir_noise_arr[0] = DTDF_DIR_TIME;
    251 
    252   memset(ptr_sbr_data->int_noise_floor, 0,
    253          sizeof(WORD16) * ptr_header_data->pstr_freq_band_data->num_nf_bands);
    254 
    255   memset(ptr_sbr_data->add_harmonics, 0, sizeof(FLAG) * MAX_FREQ_COEFFS);
    256 }
    257 
    258 static WORD16 ixheaacd_find_closest_entry(WORD32 goal_sb, WORD16 *f_master_tbl,
    259                                           WORD16 num_mf_bands,
    260                                           WORD16 direction) {
    261   WORD32 index;
    262 
    263   if (goal_sb <= f_master_tbl[0]) return f_master_tbl[0];
    264 
    265   if (goal_sb >= f_master_tbl[num_mf_bands]) return f_master_tbl[num_mf_bands];
    266 
    267   if (direction) {
    268     index = 0;
    269     while (f_master_tbl[index] < goal_sb) {
    270       index++;
    271     }
    272   } else {
    273     index = num_mf_bands;
    274     while (f_master_tbl[index] > goal_sb) {
    275       index--;
    276     }
    277   }
    278 
    279   return f_master_tbl[index];
    280 }
    281 
    282 WORD32 ixheaacd_reset_hf_generator(ia_sbr_hf_generator_struct *ptr_hf_gen_str,
    283                                    ia_sbr_header_data_struct *ptr_header_data,
    284                                    WORD audio_object_type) {
    285   WORD32 patch, sb;
    286   WORD32 temp;
    287   WORD16 *ptr_noise_freq_tbl;
    288   WORD32 num_nf_bands;
    289 
    290   ia_transposer_settings_struct *pstr_transposer_settings =
    291       ptr_hf_gen_str->pstr_settings;
    292   ia_patch_param_struct *p_str_patch_param =
    293       pstr_transposer_settings->str_patch_param;
    294 
    295   WORD32 sub_band_start = ptr_header_data->pstr_freq_band_data->sub_band_start;
    296   WORD16 *f_master_tbl = ptr_header_data->pstr_freq_band_data->f_master_tbl;
    297   WORD16 num_mf_bands = ptr_header_data->pstr_freq_band_data->num_mf_bands;
    298   WORD16 usb = ptr_header_data->pstr_freq_band_data->sub_band_end;
    299 
    300   WORD32 src_start_band;
    301   WORD32 patch_stride;
    302   WORD32 num_bands_in_patch;
    303 
    304   WORD32 lsb = f_master_tbl[0];
    305   WORD16 xover_offset = sub_band_start - lsb;
    306 
    307   WORD16 goal_sb;
    308   WORD32 fs = ptr_header_data->out_sampling_freq;
    309 
    310   if (lsb < (SHIFT_START_SB + 4)) {
    311     return (1);
    312   }
    313   switch (fs) {
    314     case 16000:
    315     case 22050:
    316     case 24000:
    317     case 32000:
    318       goal_sb = 64;
    319       break;
    320     case 44100:
    321       goal_sb = 46;
    322       break;
    323     case 48000:
    324       goal_sb = 43;
    325       break;
    326     case 64000:
    327       goal_sb = 32;
    328       break;
    329     case 88200:
    330       goal_sb = 23;
    331       break;
    332     case 96000:
    333       goal_sb = 21;
    334       break;
    335     default:
    336       return (0);
    337   }
    338 
    339   goal_sb = ixheaacd_find_closest_entry(goal_sb, f_master_tbl, num_mf_bands, 1);
    340   if (audio_object_type != AOT_ER_AAC_ELD &&
    341       audio_object_type != AOT_ER_AAC_LD) {
    342     if (ixheaacd_abs16_sat((WORD16)(goal_sb - usb)) < 4) {
    343       goal_sb = usb;
    344     }
    345   }
    346 
    347   src_start_band = SHIFT_START_SB + xover_offset;
    348   sb = (lsb + xover_offset);
    349 
    350   patch = 0;
    351 
    352   if ((goal_sb < sb) && (lsb > src_start_band)) {
    353     return -1;
    354   }
    355 
    356   while (((sb - usb) < 0) && (patch < MAX_NUM_PATCHES)) {
    357     ia_patch_param_struct *ptr_loc_patch_param = &p_str_patch_param[patch];
    358 
    359     ptr_loc_patch_param->guard_start_band = sb;
    360     sb = (sb + GUARDBANDS);
    361     ptr_loc_patch_param->dst_start_band = sb;
    362 
    363     num_bands_in_patch = (goal_sb - sb);
    364 
    365     if ((num_bands_in_patch - (lsb - src_start_band)) >= 0) {
    366       patch_stride = sb - src_start_band;
    367       patch_stride = (WORD16)(patch_stride & ~1);
    368       num_bands_in_patch = (lsb - (sb - patch_stride));
    369       num_bands_in_patch = ixheaacd_find_closest_entry(
    370           sb + num_bands_in_patch, f_master_tbl, num_mf_bands, 0);
    371       num_bands_in_patch -= sb;
    372     }
    373 
    374     patch_stride = ((num_bands_in_patch + sb) - lsb);
    375     patch_stride = (WORD16)((patch_stride + 1) & ~1);
    376 
    377     if (num_bands_in_patch > 0) {
    378       ptr_loc_patch_param->src_start_band = (sb - patch_stride);
    379       ptr_loc_patch_param->dst_end_band = patch_stride;
    380       ptr_loc_patch_param->num_bands_in_patch = num_bands_in_patch;
    381       ptr_loc_patch_param->src_end_band =
    382           (ptr_loc_patch_param->src_start_band + num_bands_in_patch);
    383 
    384       sb = (sb + ptr_loc_patch_param->num_bands_in_patch);
    385       patch++;
    386     }
    387 
    388     src_start_band = SHIFT_START_SB;
    389 
    390     if ((ixheaacd_abs16_sat((WORD16)((sb - goal_sb))) - 3) < 0) {
    391       goal_sb = usb;
    392     }
    393   }
    394 
    395   patch--;
    396 
    397   if ((patch > 0) && (p_str_patch_param[patch].num_bands_in_patch < 3)) {
    398     patch--;
    399     sb = p_str_patch_param[patch].dst_start_band +
    400          p_str_patch_param[patch].num_bands_in_patch;
    401   }
    402 
    403   if (patch >= MAX_NUM_PATCHES) {
    404     return -1;
    405   }
    406 
    407   pstr_transposer_settings->num_patches = patch + 1;
    408 
    409   temp = 0;
    410 
    411   for (patch = 0; patch < pstr_transposer_settings->num_patches; patch++) {
    412     sb = ixheaacd_min32(sb, p_str_patch_param[patch].src_start_band);
    413     temp = ixheaacd_max32(temp, p_str_patch_param[patch].src_end_band);
    414   }
    415 
    416   pstr_transposer_settings->start_patch = sb;
    417   pstr_transposer_settings->stop_patch = temp;
    418 
    419   ptr_noise_freq_tbl =
    420       ptr_header_data->pstr_freq_band_data->freq_band_tbl_noise;
    421   num_nf_bands = ptr_header_data->pstr_freq_band_data->num_nf_bands;
    422 
    423   memcpy(&pstr_transposer_settings->bw_borders[0], &ptr_noise_freq_tbl[1],
    424          sizeof(WORD16) * num_nf_bands);
    425 
    426   memset(ptr_hf_gen_str->bw_array_prev, 0, sizeof(WORD32) * MAX_NUM_PATCHES);
    427 
    428   return 0;
    429 }
    430 VOID ixheaacd_rescale_x_overlap(
    431     ia_sbr_dec_struct *ptr_sbr_dec, ia_sbr_header_data_struct *ptr_header_data,
    432     ia_sbr_frame_info_data_struct *ptr_frame_data,
    433     ia_sbr_prev_frame_data_struct *ptr_frame_data_prev,
    434     WORD32 **pp_overlap_buffer_real, WORD32 **pp_overlap_buffer_imag,
    435     FLAG low_pow_flag) {
    436   WORD32 k, l;
    437   WORD32 start_band, end_band;
    438   WORD32 target_lsb, target_usb;
    439   WORD32 source_scale, target_scale, delta_scale, reserve;
    440 
    441   WORD32 old_lsb = ptr_frame_data_prev->max_qmf_subband_aac;
    442   WORD32 start_slot =
    443       (ptr_header_data->time_step *
    444        (ptr_frame_data_prev->end_position - ptr_header_data->num_time_slots));
    445   WORD32 new_lsb = ptr_frame_data->max_qmf_subband_aac;
    446 
    447   ptr_sbr_dec->str_codec_qmf_bank.usb = new_lsb;
    448   ptr_sbr_dec->str_synthesis_qmf_bank.lsb = new_lsb;
    449 
    450   start_band = ixheaacd_min32(old_lsb, new_lsb);
    451   end_band = ixheaacd_max32(old_lsb, new_lsb);
    452 
    453   if (new_lsb != old_lsb && old_lsb > 0) {
    454     for (l = start_slot; l < 6; l++) {
    455       for (k = old_lsb; k < new_lsb; k++) {
    456         pp_overlap_buffer_real[l][k] = 0L;
    457 
    458         if (!low_pow_flag) {
    459           pp_overlap_buffer_imag[l][k] = 0L;
    460         }
    461       }
    462     }
    463 
    464     if (new_lsb > old_lsb) {
    465       source_scale = ptr_sbr_dec->str_sbr_scale_fact.ov_hb_scale;
    466       target_scale = ptr_sbr_dec->str_sbr_scale_fact.ov_lb_scale;
    467       target_lsb = 0;
    468       target_usb = old_lsb;
    469     } else {
    470       source_scale = ptr_sbr_dec->str_sbr_scale_fact.ov_lb_scale;
    471       target_scale = ptr_sbr_dec->str_sbr_scale_fact.ov_hb_scale;
    472       target_lsb = old_lsb;
    473       target_usb = ptr_sbr_dec->str_synthesis_qmf_bank.usb;
    474     }
    475 
    476     reserve = (*ixheaacd_ixheaacd_expsubbandsamples)(
    477         pp_overlap_buffer_real, pp_overlap_buffer_imag, start_band, end_band, 0,
    478         start_slot, low_pow_flag);
    479 
    480     (*ixheaacd_adjust_scale)(pp_overlap_buffer_real, pp_overlap_buffer_imag,
    481                              start_band, end_band, 0, start_slot, reserve,
    482                              low_pow_flag);
    483 
    484     source_scale += reserve;
    485 
    486     delta_scale = (target_scale - source_scale);
    487 
    488     if (delta_scale > 0) {
    489       delta_scale = -(delta_scale);
    490       start_band = target_lsb;
    491       end_band = target_usb;
    492 
    493       if (new_lsb > old_lsb) {
    494         ptr_sbr_dec->str_sbr_scale_fact.ov_lb_scale = source_scale;
    495       } else {
    496         ptr_sbr_dec->str_sbr_scale_fact.ov_hb_scale = source_scale;
    497       }
    498     }
    499 
    500     (*ixheaacd_adjust_scale)(pp_overlap_buffer_real, pp_overlap_buffer_imag,
    501                              start_band, end_band, 0, start_slot, delta_scale,
    502                              low_pow_flag);
    503   }
    504 }
    505 
    506 VOID ixheaacd_map_sineflags(WORD16 *freq_band_table, WORD16 num_sf_bands,
    507                             FLAG *add_harmonics, WORD8 *harm_flags_prev,
    508                             WORD16 transient_env, WORD8 *sine_mapped)
    509 
    510 {
    511   WORD32 qmfband2, li, ui, i;
    512   WORD32 low_subband_sec;
    513   WORD32 oldflags;
    514 
    515   low_subband_sec = (freq_band_table[0] << 1);
    516 
    517   memset(sine_mapped, MAX_ENVELOPES, sizeof(WORD8) * MAX_FREQ_COEFFS);
    518 
    519   for (i = (num_sf_bands - 1); i >= 0; i--) {
    520     oldflags = *harm_flags_prev;
    521     *harm_flags_prev++ = add_harmonics[i];
    522 
    523     if (add_harmonics[i]) {
    524       li = freq_band_table[i];
    525 
    526       ui = freq_band_table[i + 1];
    527 
    528       qmfband2 = ((ui + li) - low_subband_sec) >> 1;
    529 
    530       if (oldflags)
    531         sine_mapped[qmfband2] = 0;
    532       else
    533         sine_mapped[qmfband2] = (WORD8)transient_env;
    534     }
    535   }
    536 }
    537 
    538 VOID ixheaacd_map_34_params_to_20(WORD16 *params) {
    539   params[0] = ixheaacd_divideby3(params[0] + params[0] + params[1]);
    540   params[1] = ixheaacd_divideby3(params[1] + params[2] + params[2]);
    541   params[2] = ixheaacd_divideby3(params[3] + params[3] + params[4]);
    542   params[3] = ixheaacd_divideby3(params[4] + params[5] + params[5]);
    543   params[4] = ixheaacd_divideby2(params[6] + params[7]);
    544   params[5] = ixheaacd_divideby2(params[8] + params[9]);
    545   params[6] = params[10];
    546   params[7] = params[11];
    547   params[8] = ixheaacd_divideby2(params[12] + params[13]);
    548   params[9] = ixheaacd_divideby2(params[14] + params[15]);
    549   params[10] = params[16];
    550   params[11] = params[17];
    551   params[12] = params[18];
    552   params[13] = params[19];
    553   params[14] = ixheaacd_divideby2(params[20] + params[21]);
    554   params[15] = ixheaacd_divideby2(params[22] + params[23]);
    555   params[16] = ixheaacd_divideby2(params[24] + params[25]);
    556   params[17] = ixheaacd_divideby2(params[26] + params[27]);
    557   params[18] = ixheaacd_divideby2(
    558       ixheaacd_divideby2(params[28] + params[29] + params[30] + params[31]));
    559   params[19] = ixheaacd_divideby2(params[32] + params[33]);
    560 }
    561 
    562 extern const WORD16 ixheaacd_num_bands[3];
    563 
    564 WORD16 ixheaacd_read_ps_data(ia_ps_dec_struct *ptr_ps_dec,
    565                              ia_bit_buf_struct *it_bit_buff,
    566                              WORD16 num_bits_left,
    567                              ia_ps_tables_struct *ps_tables_ptr) {
    568   WORD b, e, temp;
    569   const WORD16 num_env_tab[4] = {0, 1, 2, 4};
    570   WORD cnt_bits;
    571   ia_huffman_data_type huffman_table, huffman_df_table, huffman_dt_table;
    572   FLAG enable_ps_header;
    573 
    574   if (!ptr_ps_dec) {
    575     return 0;
    576   }
    577 
    578   cnt_bits = it_bit_buff->cnt_bits;
    579 
    580   enable_ps_header = ixheaacd_read_bits_buf(it_bit_buff, 1);
    581 
    582   if (enable_ps_header) {
    583     ptr_ps_dec->enable_iid = ixheaacd_read_bits_buf(it_bit_buff, 1);
    584     if (ptr_ps_dec->enable_iid) {
    585       ptr_ps_dec->iid_mode = ixheaacd_read_bits_buf(it_bit_buff, 3);
    586     }
    587 
    588     if (ptr_ps_dec->iid_mode > 2) {
    589       ptr_ps_dec->iid_quant = 1;
    590       ptr_ps_dec->iid_mode -= 3;
    591     } else {
    592       ptr_ps_dec->iid_quant = 0;
    593     }
    594 
    595     ptr_ps_dec->enable_icc = ixheaacd_read_bits_buf(it_bit_buff, 1);
    596     if (ptr_ps_dec->enable_icc) {
    597       ptr_ps_dec->icc_mode = ixheaacd_read_bits_buf(it_bit_buff, 3);
    598     }
    599 
    600     ptr_ps_dec->enable_ext = ixheaacd_read_bits_buf(it_bit_buff, 1);
    601 
    602     if (ptr_ps_dec->icc_mode > 2) {
    603       ptr_ps_dec->icc_mode -= 3;
    604     }
    605   }
    606 
    607   if ((ptr_ps_dec->enable_iid && ptr_ps_dec->iid_mode > 2) ||
    608       (ptr_ps_dec->enable_icc && ptr_ps_dec->icc_mode > 2)) {
    609     ptr_ps_dec->ps_data_present = 0;
    610 
    611     num_bits_left -= (cnt_bits - it_bit_buff->cnt_bits);
    612 
    613     while (num_bits_left > 8) {
    614       ixheaacd_read_bits_buf(it_bit_buff, 8);
    615       num_bits_left -= 8;
    616     }
    617     ixheaacd_read_bits_buf(it_bit_buff, num_bits_left);
    618 
    619     return (cnt_bits - it_bit_buff->cnt_bits);
    620   }
    621 
    622   ptr_ps_dec->frame_class = (FLAG)ixheaacd_read_bits_buf(it_bit_buff, 1);
    623 
    624   temp = ixheaacd_read_bits_buf(it_bit_buff, 2);
    625 
    626   if (ptr_ps_dec->frame_class == 0) {
    627     ptr_ps_dec->num_env = num_env_tab[temp];
    628   } else {
    629     ptr_ps_dec->num_env = (((1 + temp) << 8) >> 8);
    630 
    631     for (e = 1; e < ptr_ps_dec->num_env + 1; e++) {
    632       ptr_ps_dec->border_position[e] =
    633           (((ixheaacd_read_bits_buf(it_bit_buff, 5) + 1) << 8) >> 8);
    634     }
    635   }
    636 
    637   if (ptr_ps_dec->enable_iid) {
    638     if (ptr_ps_dec->iid_quant) {
    639       huffman_df_table = (ia_huffman_data_type)&ps_tables_ptr->huff_iid_df_fine;
    640       huffman_dt_table = (ia_huffman_data_type)&ps_tables_ptr->huff_iid_dt_fine;
    641     } else {
    642       huffman_df_table = (ia_huffman_data_type)&ps_tables_ptr->huff_iid_df;
    643       huffman_dt_table = (ia_huffman_data_type)&ps_tables_ptr->huff_iid_dt;
    644     }
    645 
    646     for (e = 0; e < ptr_ps_dec->num_env; e++) {
    647       ptr_ps_dec->iid_dt[e] = (FLAG)ixheaacd_read_bits_buf(it_bit_buff, 1);
    648 
    649       if (ptr_ps_dec->iid_dt[e]) {
    650         huffman_table = huffman_dt_table;
    651       } else {
    652         huffman_table = huffman_df_table;
    653       }
    654 
    655       for (b = 0; b < ixheaacd_num_bands[ptr_ps_dec->iid_mode]; b++) {
    656         ptr_ps_dec->iid_par_table[e][b] =
    657             ixheaacd_ssc_huff_dec(huffman_table, it_bit_buff);
    658       }
    659     }
    660   }
    661 
    662   if (ptr_ps_dec->enable_icc) {
    663     huffman_df_table = (ia_huffman_data_type)&ps_tables_ptr->huff_icc_df;
    664     huffman_dt_table = (ia_huffman_data_type)&ps_tables_ptr->huff_icc_dt;
    665 
    666     for (e = 0; e < ptr_ps_dec->num_env; e++) {
    667       ptr_ps_dec->icc_dt[e] = ixheaacd_read_bits_buf(it_bit_buff, 1);
    668 
    669       if (ptr_ps_dec->icc_dt[e]) {
    670         huffman_table = huffman_dt_table;
    671       } else {
    672         huffman_table = huffman_df_table;
    673       }
    674 
    675       for (b = 0; b < ixheaacd_num_bands[ptr_ps_dec->icc_mode]; b++) {
    676         ptr_ps_dec->icc_par_table[e][b] =
    677             ixheaacd_ssc_huff_dec(huffman_table, it_bit_buff);
    678       }
    679     }
    680   }
    681 
    682   if (ptr_ps_dec->enable_ext) {
    683     WORD32 cnt = ixheaacd_read_bits_buf(it_bit_buff, 4);
    684 
    685     if (cnt == 15) {
    686       cnt += ixheaacd_read_bits_buf(it_bit_buff, 8);
    687     }
    688     while (cnt--) {
    689       ixheaacd_read_bits_buf(it_bit_buff, 8);
    690     }
    691   }
    692 
    693   ptr_ps_dec->ps_data_present = 1;
    694 
    695   return (cnt_bits - it_bit_buff->cnt_bits);
    696 }
    697 
    698 VOID ixheaacd_invfilt_level_emphasis(ia_sbr_hf_generator_struct *ptr_hf_gen_str,
    699                                      WORD32 num_if_bands, WORD32 *inv_filt_mode,
    700                                      WORD32 *inv_filt_mode_prev,
    701                                      WORD32 *bw_array) {
    702   WORD32 i;
    703   WORD32 accu;
    704   WORD16 w1, w2;
    705 
    706   for (i = 0; i < num_if_bands; i++) {
    707     bw_array[i] =
    708         ixheaacd_inew_bw_table[inv_filt_mode_prev[i]][inv_filt_mode[i]];
    709 
    710     if (bw_array[i] < ptr_hf_gen_str->bw_array_prev[i]) {
    711       w1 = 0x6000;
    712       w2 = 0x2000;
    713     } else {
    714       w1 = 0x7400;
    715       w2 = 0x0c00;
    716     }
    717     accu = ixheaacd_add32(
    718         ixheaacd_mult32x16in32_shl(bw_array[i], w1),
    719         ixheaacd_mult32x16in32_shl(ptr_hf_gen_str->bw_array_prev[i], w2));
    720 
    721     if (accu < 0x02000000) {
    722       accu = 0;
    723     }
    724 
    725     if (accu >= 0x7f800000) {
    726       accu = 0x7f800000;
    727     }
    728     bw_array[i] = accu;
    729   }
    730 }
    731 
    732 typedef struct {
    733   FLOAT32 phi_0_1_real;
    734   FLOAT32 phi_0_1_imag;
    735   FLOAT32 phi_0_2_real;
    736   FLOAT32 phi_0_2_imag;
    737   FLOAT32 phi_1_1;
    738   FLOAT32 phi_1_2_real;
    739   FLOAT32 phi_1_2_imag;
    740   FLOAT32 phi_2_2;
    741   FLOAT32 det;
    742 } ia_auto_corr_ele_struct;
    743 
    744 static VOID ixheaacd_esbr_calc_co_variance(
    745     ia_auto_corr_ele_struct *pstr_auto_corr, FLOAT32 vec_x_real[][64],
    746     FLOAT32 vec_x_imag[][64], WORD32 bd, WORD32 len) {
    747   WORD32 j, jminus1, jminus2;
    748 
    749   memset(pstr_auto_corr, 0, sizeof(ia_auto_corr_ele_struct));
    750 
    751   for (j = 0; j < len; j++) {
    752     jminus1 = j - 1;
    753     jminus2 = jminus1 - 1;
    754 
    755     pstr_auto_corr->phi_0_1_real +=
    756         vec_x_real[j][bd] * vec_x_real[jminus1][bd] +
    757         vec_x_imag[j][bd] * vec_x_imag[jminus1][bd];
    758 
    759     pstr_auto_corr->phi_0_1_imag +=
    760         vec_x_imag[j][bd] * vec_x_real[jminus1][bd] -
    761         vec_x_real[j][bd] * vec_x_imag[jminus1][bd];
    762 
    763     pstr_auto_corr->phi_0_2_real +=
    764         vec_x_real[j][bd] * vec_x_real[jminus2][bd] +
    765         vec_x_imag[j][bd] * vec_x_imag[jminus2][bd];
    766 
    767     pstr_auto_corr->phi_0_2_imag +=
    768         vec_x_imag[j][bd] * vec_x_real[jminus2][bd] -
    769         vec_x_real[j][bd] * vec_x_imag[jminus2][bd];
    770 
    771     pstr_auto_corr->phi_1_1 +=
    772         vec_x_real[jminus1][bd] * vec_x_real[jminus1][bd] +
    773         vec_x_imag[jminus1][bd] * vec_x_imag[jminus1][bd];
    774 
    775     pstr_auto_corr->phi_1_2_real +=
    776         vec_x_real[jminus1][bd] * vec_x_real[jminus2][bd] +
    777         vec_x_imag[jminus1][bd] * vec_x_imag[jminus2][bd];
    778 
    779     pstr_auto_corr->phi_1_2_imag +=
    780         vec_x_imag[jminus1][bd] * vec_x_real[jminus2][bd] -
    781         vec_x_real[jminus1][bd] * vec_x_imag[jminus2][bd];
    782 
    783     pstr_auto_corr->phi_2_2 +=
    784         vec_x_real[jminus2][bd] * vec_x_real[jminus2][bd] +
    785         vec_x_imag[jminus2][bd] * vec_x_imag[jminus2][bd];
    786   }
    787 
    788   pstr_auto_corr->det =
    789       pstr_auto_corr->phi_1_1 * pstr_auto_corr->phi_2_2 -
    790       (pstr_auto_corr->phi_1_2_real * pstr_auto_corr->phi_1_2_real +
    791        pstr_auto_corr->phi_1_2_imag * pstr_auto_corr->phi_1_2_imag) *
    792           SBR_HF_RELAXATION_PARAM;
    793 }
    794 
    795 static void ixheaacd_esbr_chirp_fac_calc(WORD32 *inv_filt_mode,
    796                                          WORD32 *inv_filt_mode_prev,
    797                                          WORD32 num_if_bands, FLOAT32 *bw_array,
    798                                          FLOAT32 *bw_array_prev) {
    799   WORD32 i;
    800 
    801   for (i = 0; i < num_if_bands; i++) {
    802     bw_array[i] =
    803         ixheaacd_new_bw_table[inv_filt_mode_prev[i]][inv_filt_mode[i]];
    804 
    805     if (bw_array[i] < bw_array_prev[i])
    806       bw_array[i] = 0.75000f * bw_array[i] + 0.25000f * bw_array_prev[i];
    807     else
    808       bw_array[i] = 0.90625f * bw_array[i] + 0.09375f * bw_array_prev[i];
    809 
    810     if (bw_array[i] < 0.015625) bw_array[i] = 0;
    811   }
    812 }
    813 
    814 static void ixheaacd_gausssolve(WORD32 n, FLOAT32 a[][MAXDEG + 1], FLOAT32 b[],
    815                                 FLOAT32 y[]) {
    816   WORD32 i, j, k, imax;
    817   FLOAT32 v;
    818 
    819   for (i = 0; i < n; i++) {
    820     imax = i;
    821     for (k = i + 1; k < n; k++) {
    822       if (fabs(a[k][i]) > fabs(a[imax][i])) {
    823         imax = k;
    824       }
    825     }
    826     if (imax != i) {
    827       v = b[imax];
    828       b[imax] = b[i];
    829       b[i] = v;
    830       for (j = i; j < n; j++) {
    831         v = a[imax][j];
    832         a[imax][j] = a[i][j];
    833         a[i][j] = v;
    834       }
    835     }
    836 
    837     v = a[i][i];
    838 
    839     b[i] /= v;
    840     for (j = i; j < n; j++) {
    841       a[i][j] /= v;
    842     }
    843 
    844     for (k = i + 1; k < n; k++) {
    845       v = a[k][i];
    846       b[k] -= v * b[i];
    847       for (j = i + 1; j < n; j++) {
    848         a[k][j] -= v * a[i][j];
    849       }
    850     }
    851   }
    852 
    853   for (i = n - 1; i >= 0; i--) {
    854     y[i] = b[i];
    855     for (j = i + 1; j < n; j++) {
    856       y[i] -= a[i][j] * y[j];
    857     }
    858   }
    859 }
    860 
    861 void ixheaacd_polyfit(WORD32 n, FLOAT32 y[], FLOAT32 p[]) {
    862   WORD32 i, j, k;
    863   FLOAT32 a[MAXDEG + 1][MAXDEG + 1];
    864   FLOAT32 b[MAXDEG + 1];
    865   FLOAT32 v[2 * MAXDEG + 1];
    866 
    867   for (i = 0; i <= MAXDEG; i++) {
    868     b[i] = 0.0f;
    869     for (j = 0; j <= MAXDEG; j++) {
    870       a[i][j] = 0.0f;
    871     }
    872   }
    873 
    874   for (k = 0; k < n; k++) {
    875     v[0] = 1.0;
    876     for (i = 1; i <= 2 * MAXDEG; i++) {
    877       v[i] = k * v[i - 1];
    878     }
    879 
    880     for (i = 0; i <= MAXDEG; i++) {
    881       b[i] += v[MAXDEG - i] * y[k];
    882       for (j = 0; j <= MAXDEG; j++) {
    883         a[i][j] += v[2 * MAXDEG - i - j];
    884       }
    885     }
    886   }
    887 
    888   ixheaacd_gausssolve(MAXDEG + 1, a, b, p);
    889 }
    890 
    891 VOID ixheaacd_pre_processing(FLOAT32 ptr_src_buf_real[][64],
    892                              FLOAT32 ptr_src_buf_imag[][64],
    893                              FLOAT32 gain_vector[], WORD32 num_bands,
    894                              WORD32 start_sample, WORD32 end_sample) {
    895   WORD32 k, i;
    896   FLOAT32 poly_coeff[4];
    897   FLOAT32 mean_enrg = 0;
    898   FLOAT32 low_env_slope[64];
    899   FLOAT32 low_env[64];
    900   FLOAT32 a0;
    901   FLOAT32 a1;
    902   FLOAT32 a2;
    903   FLOAT32 a3;
    904 
    905   for (k = 0; k < num_bands; k++) {
    906     FLOAT32 temp = 0;
    907     for (i = start_sample; i < end_sample; i++) {
    908       temp += ptr_src_buf_real[i][k] * ptr_src_buf_real[i][k] +
    909               ptr_src_buf_imag[i][k] * ptr_src_buf_imag[i][k];
    910     }
    911     temp /= (end_sample - start_sample);
    912     low_env[k] = (FLOAT32)(10 * log10(temp + 1));
    913     mean_enrg = mean_enrg + low_env[k];
    914   }
    915   mean_enrg /= num_bands;
    916 
    917   ixheaacd_polyfit(num_bands, low_env, poly_coeff);
    918 
    919   a0 = poly_coeff[0];
    920   a1 = poly_coeff[1];
    921   a2 = poly_coeff[2];
    922   a3 = poly_coeff[3];
    923   for (k = 0; k < num_bands; k++) {
    924     FLOAT32 x_low_l = (FLOAT32)k;
    925     FLOAT32 low_env_slope_l = a3;
    926     low_env_slope_l = low_env_slope_l + a2 * x_low_l;
    927 
    928     x_low_l = x_low_l * x_low_l;
    929     low_env_slope_l = low_env_slope_l + a1 * x_low_l;
    930 
    931     x_low_l = x_low_l * (FLOAT32)k;
    932     low_env_slope_l = low_env_slope_l + a0 * x_low_l;
    933 
    934     low_env_slope[k] = low_env_slope_l;
    935   }
    936 
    937   for (i = 0; i < num_bands; i++) {
    938     gain_vector[i] = (FLOAT32)pow(10, (mean_enrg - low_env_slope[i]) / 20.0f);
    939   }
    940 }
    941 
    942 WORD32 ixheaacd_generate_hf(FLOAT32 ptr_src_buf_real[][64],
    943                             FLOAT32 ptr_src_buf_imag[][64],
    944                             FLOAT32 ptr_ph_vocod_buf_real[][64],
    945                             FLOAT32 ptr_ph_vocod_buf_imag[][64],
    946                             FLOAT32 ptr_dst_buf_real[][64],
    947                             FLOAT32 ptr_dst_buf_imag[][64],
    948                             ia_sbr_frame_info_data_struct *ptr_frame_data,
    949                             ia_sbr_header_data_struct *ptr_header_data) {
    950   WORD32 bw_index, i, k, k2, patch = 0;
    951   WORD32 co_var_len;
    952   WORD32 start_sample, end_sample, goal_sb;
    953   WORD32 sb, source_start_band, patch_stride, num_bands_in_patch;
    954   WORD32 hbe_flag = ptr_header_data->hbe_flag;
    955   FLOAT32 a0r, a0i, a1r, a1i;
    956   FLOAT32 bw_array[MAX_NUM_PATCHES] = {0};
    957 
    958   ia_auto_corr_ele_struct str_auto_corr;
    959 
    960   WORD16 *ptr_invf_band_tbl =
    961       &ptr_header_data->pstr_freq_band_data
    962            ->freq_band_tbl_noise[1];  // offest 1 used as base address of
    963                                       // ptr_invf_band_tbl
    964   WORD32 num_if_bands = ptr_header_data->pstr_freq_band_data->num_nf_bands;
    965   WORD32 sub_band_start = ptr_header_data->pstr_freq_band_data->sub_band_start;
    966   WORD16 *f_master_tbl = ptr_header_data->pstr_freq_band_data->f_master_tbl;
    967   WORD32 num_mf_bands = ptr_header_data->pstr_freq_band_data->num_mf_bands;
    968   WORD32 *inv_filt_mode = ptr_frame_data->sbr_invf_mode;
    969   WORD32 *inv_filt_mode_prev = ptr_frame_data->sbr_invf_mode_prev;
    970   WORD32 sbr_patching_mode = ptr_frame_data->sbr_patching_mode;
    971   ia_frame_info_struct *p_frame_info = &ptr_frame_data->str_frame_info_details;
    972   WORD32 pre_proc_flag = ptr_header_data->pre_proc_flag;
    973   WORD32 is_usf_4 = ptr_header_data->is_usf_4;
    974   WORD32 fs = ptr_header_data->out_sampling_freq;
    975 
    976   WORD32 lsb = f_master_tbl[0];
    977   WORD32 usb = f_master_tbl[num_mf_bands];
    978   WORD32 xover_offset = sub_band_start - f_master_tbl[0];
    979 
    980   FLOAT32 bw = 0.0f;
    981   FLOAT32 fac = 0.0f;
    982 
    983   FLOAT32 gain;
    984   FLOAT32 gain_vector[64];
    985 
    986   WORD32 slope_length = 0;
    987   WORD32 first_slot_offset = p_frame_info->border_vec[0];
    988   WORD32 end_slot_offs = 0;
    989 
    990   FLOAT32 *bw_array_prev = ptr_frame_data->bw_array_prev;
    991 
    992   end_slot_offs = p_frame_info->border_vec[p_frame_info->num_env] - 16;
    993   if (is_usf_4) {
    994     start_sample = first_slot_offset * 4;
    995     end_sample = 64 + end_slot_offs * 4;
    996     co_var_len = 76;
    997   } else {
    998     start_sample = first_slot_offset * 2;
    999     end_sample = 32 + end_slot_offs * 2;
   1000     co_var_len = 38;
   1001   }
   1002 
   1003   if (pre_proc_flag) {
   1004     ixheaacd_pre_processing(ptr_src_buf_real, ptr_src_buf_imag, gain_vector,
   1005                             f_master_tbl[0], start_sample, end_sample);
   1006   }
   1007 
   1008   ixheaacd_esbr_chirp_fac_calc(inv_filt_mode, inv_filt_mode_prev, num_if_bands,
   1009                                bw_array, bw_array_prev);
   1010 
   1011   for (i = start_sample; i < end_sample; i++) {
   1012     memset(ptr_dst_buf_real[i] + usb, 0, (64 - usb) * sizeof(FLOAT32));
   1013     memset(ptr_dst_buf_imag[i] + usb, 0, (64 - usb) * sizeof(FLOAT32));
   1014   }
   1015 
   1016   if (sbr_patching_mode || !hbe_flag) {
   1017     FLOAT32 alpha_real[64][2], alpha_imag[64][2];
   1018 
   1019     for (k = 1; k < f_master_tbl[0]; k++) {
   1020       ixheaacd_esbr_calc_co_variance(&str_auto_corr, &ptr_src_buf_real[0],
   1021                                      &ptr_src_buf_imag[0], k, co_var_len);
   1022       if (str_auto_corr.det == 0.0f) {
   1023         alpha_real[k][1] = alpha_imag[k][1] = 0;
   1024       } else {
   1025         fac = 1.0f / str_auto_corr.det;
   1026         alpha_real[k][1] =
   1027             (str_auto_corr.phi_0_1_real * str_auto_corr.phi_1_2_real -
   1028              str_auto_corr.phi_0_1_imag * str_auto_corr.phi_1_2_imag -
   1029              str_auto_corr.phi_0_2_real * str_auto_corr.phi_1_1) *
   1030             fac;
   1031         alpha_imag[k][1] =
   1032             (str_auto_corr.phi_0_1_imag * str_auto_corr.phi_1_2_real +
   1033              str_auto_corr.phi_0_1_real * str_auto_corr.phi_1_2_imag -
   1034              str_auto_corr.phi_0_2_imag * str_auto_corr.phi_1_1) *
   1035             fac;
   1036       }
   1037 
   1038       if (str_auto_corr.phi_1_1 == 0) {
   1039         alpha_real[k][0] = alpha_imag[k][0] = 0;
   1040       } else {
   1041         fac = 1.0f / str_auto_corr.phi_1_1;
   1042         alpha_real[k][0] = -(str_auto_corr.phi_0_1_real +
   1043                              alpha_real[k][1] * str_auto_corr.phi_1_2_real +
   1044                              alpha_imag[k][1] * str_auto_corr.phi_1_2_imag) *
   1045                            fac;
   1046         alpha_imag[k][0] = -(str_auto_corr.phi_0_1_imag +
   1047                              alpha_imag[k][1] * str_auto_corr.phi_1_2_real -
   1048                              alpha_real[k][1] * str_auto_corr.phi_1_2_imag) *
   1049                            fac;
   1050       }
   1051 
   1052       if ((alpha_real[k][0] * alpha_real[k][0] +
   1053                alpha_imag[k][0] * alpha_imag[k][0] >=
   1054            16.0f) ||
   1055           (alpha_real[k][1] * alpha_real[k][1] +
   1056                alpha_imag[k][1] * alpha_imag[k][1] >=
   1057            16.0f)) {
   1058         alpha_real[k][0] = 0.0f;
   1059         alpha_imag[k][0] = 0.0f;
   1060         alpha_real[k][1] = 0.0f;
   1061         alpha_imag[k][1] = 0.0f;
   1062       }
   1063     }
   1064 
   1065     goal_sb = (WORD32)(2.048e6f / fs + 0.5f);
   1066     {
   1067       WORD32 index;
   1068       if (goal_sb < f_master_tbl[num_mf_bands]) {
   1069         for (index = 0; (f_master_tbl[index] < goal_sb); index++)
   1070           ;
   1071         goal_sb = f_master_tbl[index];
   1072       } else {
   1073         goal_sb = f_master_tbl[num_mf_bands];
   1074       }
   1075     }
   1076 
   1077     source_start_band = xover_offset + 1;
   1078     sb = lsb + xover_offset;
   1079 
   1080     patch = 0;
   1081     while (sb < usb) {
   1082       if (MAX_NUM_PATCHES <= patch) return -1;
   1083       ptr_frame_data->patch_param.start_subband[patch] = sb;
   1084       num_bands_in_patch = goal_sb - sb;
   1085 
   1086       if (num_bands_in_patch >= lsb - source_start_band) {
   1087         patch_stride = sb - source_start_band;
   1088         patch_stride = patch_stride & ~1;
   1089         num_bands_in_patch = lsb - (sb - patch_stride);
   1090         num_bands_in_patch =
   1091             ixheaacd_find_closest_entry(sb + num_bands_in_patch, f_master_tbl,
   1092                                         (WORD16)(num_mf_bands), 0) -
   1093             (WORD32)(sb);
   1094       }
   1095 
   1096       patch_stride = num_bands_in_patch + sb - lsb;
   1097       patch_stride = (patch_stride + 1) & ~1;
   1098 
   1099       source_start_band = 1;
   1100 
   1101       if (goal_sb - (sb + num_bands_in_patch) < 3) {
   1102         goal_sb = usb;
   1103       }
   1104 
   1105       if ((num_bands_in_patch < 3) && (patch > 0) &&
   1106           (sb + num_bands_in_patch == usb)) {
   1107         for (i = start_sample + slope_length; i < end_sample + slope_length;
   1108              i++) {
   1109           for (k2 = sb; k2 < sb + num_bands_in_patch; k2++) {
   1110             ptr_dst_buf_real[i][k2] = 0.0f;
   1111             ptr_dst_buf_imag[i][k2] = 0.0f;
   1112           }
   1113         }
   1114 
   1115         break;
   1116       }
   1117 
   1118       if (num_bands_in_patch <= 0) {
   1119         return -1;
   1120       }
   1121 
   1122       for (k2 = sb; k2 < sb + num_bands_in_patch; k2++) {
   1123         k = k2 - patch_stride;
   1124         bw_index = 0;
   1125         while (k2 >= ptr_invf_band_tbl[bw_index]) {
   1126           bw_index++;
   1127           if (bw_index >= MAX_NOISE_COEFFS) return -1;
   1128         }
   1129 
   1130         if (bw_index >= MAX_NUM_PATCHES) return -1;
   1131         bw = bw_array[bw_index];
   1132 
   1133         a0r = bw * alpha_real[k][0];
   1134         a0i = bw * alpha_imag[k][0];
   1135         bw *= bw;
   1136         a1r = bw * alpha_real[k][1];
   1137         a1i = bw * alpha_imag[k][1];
   1138 
   1139         if (pre_proc_flag) {
   1140           gain = gain_vector[k];
   1141         } else {
   1142           gain = 1.0f;
   1143         }
   1144 
   1145         for (i = start_sample + slope_length; i < end_sample + slope_length;
   1146              i++) {
   1147           ptr_dst_buf_real[i][k2] = ptr_src_buf_real[i][k] * gain;
   1148 
   1149           ptr_dst_buf_imag[i][k2] = ptr_src_buf_imag[i][k] * gain;
   1150 
   1151           if (bw > 0.0f) {
   1152             ptr_dst_buf_real[i][k2] += (a0r * ptr_src_buf_real[i - 1][k] -
   1153                                         a0i * ptr_src_buf_imag[i - 1][k] +
   1154                                         a1r * ptr_src_buf_real[i - 2][k] -
   1155                                         a1i * ptr_src_buf_imag[i - 2][k]) *
   1156                                        gain;
   1157             ptr_dst_buf_imag[i][k2] += (a0i * ptr_src_buf_real[i - 1][k] +
   1158                                         a0r * ptr_src_buf_imag[i - 1][k] +
   1159                                         a1i * ptr_src_buf_real[i - 2][k] +
   1160                                         a1r * ptr_src_buf_imag[i - 2][k]) *
   1161                                        gain;
   1162           }
   1163         }
   1164       }
   1165       sb += num_bands_in_patch;
   1166       patch++;
   1167     }
   1168   }
   1169 
   1170   if (hbe_flag && !sbr_patching_mode) {
   1171     FLOAT32 alpha_real[2], alpha_imag[2];
   1172 
   1173     bw_index = 0, patch = 1;
   1174     if (NULL == ptr_ph_vocod_buf_real || NULL == ptr_ph_vocod_buf_imag)
   1175       return -1;
   1176 
   1177     for (k2 = sub_band_start; k2 < f_master_tbl[num_mf_bands]; k2++) {
   1178       ixheaacd_esbr_calc_co_variance(&str_auto_corr, &ptr_ph_vocod_buf_real[0],
   1179                                      &ptr_ph_vocod_buf_imag[0], k2, co_var_len);
   1180 
   1181       if (str_auto_corr.det == 0.0f) {
   1182         alpha_real[1] = alpha_imag[1] = 0;
   1183       } else {
   1184         fac = 1.0f / str_auto_corr.det;
   1185         alpha_real[1] =
   1186             (str_auto_corr.phi_0_1_real * str_auto_corr.phi_1_2_real -
   1187              str_auto_corr.phi_0_1_imag * str_auto_corr.phi_1_2_imag -
   1188              str_auto_corr.phi_0_2_real * str_auto_corr.phi_1_1) *
   1189             fac;
   1190         alpha_imag[1] =
   1191             (str_auto_corr.phi_0_1_imag * str_auto_corr.phi_1_2_real +
   1192              str_auto_corr.phi_0_1_real * str_auto_corr.phi_1_2_imag -
   1193              str_auto_corr.phi_0_2_imag * str_auto_corr.phi_1_1) *
   1194             fac;
   1195       }
   1196 
   1197       if (str_auto_corr.phi_1_1 == 0) {
   1198         alpha_real[0] = alpha_imag[0] = 0;
   1199       } else {
   1200         fac = 1.0f / str_auto_corr.phi_1_1;
   1201         alpha_real[0] = -(str_auto_corr.phi_0_1_real +
   1202                           alpha_real[1] * str_auto_corr.phi_1_2_real +
   1203                           alpha_imag[1] * str_auto_corr.phi_1_2_imag) *
   1204                         fac;
   1205         alpha_imag[0] = -(str_auto_corr.phi_0_1_imag +
   1206                           alpha_imag[1] * str_auto_corr.phi_1_2_real -
   1207                           alpha_real[1] * str_auto_corr.phi_1_2_imag) *
   1208                         fac;
   1209       }
   1210 
   1211       if (alpha_real[0] * alpha_real[0] + alpha_imag[0] * alpha_imag[0] >=
   1212               16.0f ||
   1213           alpha_real[1] * alpha_real[1] + alpha_imag[1] * alpha_imag[1] >=
   1214               16.0f) {
   1215         alpha_real[0] = 0.0f;
   1216         alpha_imag[0] = 0.0f;
   1217         alpha_real[1] = 0.0f;
   1218         alpha_imag[1] = 0.0f;
   1219       }
   1220 
   1221       while (k2 >= ptr_invf_band_tbl[bw_index]) {
   1222         bw_index++;
   1223         if (bw_index >= MAX_NOISE_COEFFS) return -1;
   1224       }
   1225 
   1226       if (bw_index >= MAX_NUM_PATCHES) return -1;
   1227       bw = bw_array[bw_index];
   1228 
   1229       a0r = bw * alpha_real[0];
   1230       a0i = bw * alpha_imag[0];
   1231       bw *= bw;
   1232       a1r = bw * alpha_real[1];
   1233       a1i = bw * alpha_imag[1];
   1234 
   1235       if (bw > 0.0f) {
   1236         for (i = start_sample; i < end_sample; i++) {
   1237           FLOAT32 real1, imag1, real2, imag2, realTarget, imag_target;
   1238 
   1239           realTarget = ptr_ph_vocod_buf_real[i][k2];
   1240           imag_target = ptr_ph_vocod_buf_imag[i][k2];
   1241           real1 = ptr_ph_vocod_buf_real[i - 1][k2];
   1242           imag1 = ptr_ph_vocod_buf_imag[i - 1][k2];
   1243           real2 = ptr_ph_vocod_buf_real[i - 2][k2];
   1244           imag2 = ptr_ph_vocod_buf_imag[i - 2][k2];
   1245           realTarget +=
   1246               ((a0r * real1 - a0i * imag1) + (a1r * real2 - a1i * imag2));
   1247           imag_target +=
   1248               ((a0i * real1 + a0r * imag1) + (a1i * real2 + a1r * imag2));
   1249 
   1250           ptr_dst_buf_real[i][k2] = realTarget;
   1251           ptr_dst_buf_imag[i][k2] = imag_target;
   1252         }
   1253       } else {
   1254         for (i = start_sample; i < end_sample; i++) {
   1255           ptr_dst_buf_real[i][k2] = ptr_ph_vocod_buf_real[i][k2];
   1256           ptr_dst_buf_imag[i][k2] = ptr_ph_vocod_buf_imag[i][k2];
   1257         }
   1258       }
   1259     }
   1260   }
   1261   ptr_frame_data->patch_param.num_patches = patch;
   1262   if (patch >= (MAX_NUM_PATCHES + 1)) return -1;
   1263   for (i = 0; i < num_if_bands; i++) {
   1264     bw_array_prev[i] = bw_array[i];
   1265   }
   1266   return 0;
   1267 }
   1268