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 <assert.h>
     21 #include <float.h>
     22 #include <stdlib.h>
     23 #include <stdio.h>
     24 #include <math.h>
     25 #include <string.h>
     26 
     27 #include <ixheaacd_type_def.h>
     28 #include "ixheaacd_bitbuffer.h"
     29 #include "ixheaacd_interface.h"
     30 #include "ixheaacd_tns_usac.h"
     31 #include "ixheaacd_cnst.h"
     32 #include "ixheaacd_acelp_info.h"
     33 
     34 #include "ixheaacd_sbrdecsettings.h"
     35 #include "ixheaacd_info.h"
     36 #include "ixheaacd_sbr_common.h"
     37 #include "ixheaacd_drc_data_struct.h"
     38 #include "ixheaacd_drc_dec.h"
     39 #include "ixheaacd_sbrdecoder.h"
     40 #include "ixheaacd_mps_polyphase.h"
     41 #include "ixheaacd_sbr_const.h"
     42 #include "ixheaacd_main.h"
     43 #include "ixheaacd_arith_dec.h"
     44 
     45 #include "ixheaacd_func_def.h"
     46 #include "ixheaacd_windows.h"
     47 #include "ixheaacd_acelp_com.h"
     48 #include "ixheaacd_constants.h"
     49 #include <ixheaacd_basic_ops32.h>
     50 #include <ixheaacd_basic_ops40.h>
     51 
     52 #define LSF_GAP_F 50.0f
     53 #define FREQ_MAX_F 6400.0f
     54 #define FREQ_DIV_F 400.0f
     55 
     56 extern const FLOAT32 lsf_init[ORDER];
     57 
     58 extern const FLOAT32 ixheaacd_fir_lp_filt[1 + FILTER_DELAY];
     59 
     60 WORD32 ixheaacd_pow_10_i_by_128[128] = {
     61     16384,     17788,     19312,     20968,     22765,     24716,     26835,
     62     29135,     31632,     34343,     37287,     40483,     43953,     47720,
     63     51810,     56251,     61072,     66307,     71990,     78161,     84860,
     64     92134,     100030,    108604,    117913,    128019,    138992,    150905,
     65     163840,    177882,    193129,    209682,    227654,    247167,    268352,
     66     291353,    316325,    343438,    372874,    404834,    439532,    477205,
     67     518107,    562515,    610728,    663075,    719908,    781612,    848605,
     68     921340,    1000309,   1086046,   1179133,   1280197,   1389925,   1509057,
     69     1638400,   1778829,   1931294,   2096827,   2276549,   2471675,   2683525,
     70     2913532,   3163255,   3434381,   3728745,   4048340,   4395328,   4772057,
     71     5181075,   5625151,   6107289,   6630752,   7199081,   7816122,   8486051,
     72     9213400,   10003091,  10860467,  11791330,  12801978,  13899250,  15090570,
     73     16384000,  17788290,  19312945,  20968279,  22765494,  24716750,  26835250,
     74     29135329,  31632551,  34343813,  37287459,  40483409,  43953287,  47720573,
     75     51810757,  56251515,  61072895,  66307521,  71990813,  78161226,  84860513,
     76     92134002,  100030911, 108604672, 117913300, 128019781, 138992500, 150905703,
     77     163840000, 177882909, 193129453, 209682794, 227654941, 247167501, 268352504,
     78     291353298, 316325515, 343438130, 372874596, 404834095, 439532879, 477205734,
     79     518107571, 562515151};
     80 
     81 VOID ixheaacd_lsf_weight_2st_flt(float *lsfq, float *w, WORD32 mode);
     82 
     83 static PLATFORM_INLINE WORD32 ixheaacd_mult32_m(WORD32 a, WORD32 b) {
     84   WORD32 result;
     85   WORD64 temp_result;
     86 
     87   temp_result = (WORD64)a * (WORD64)b;
     88   result = (WORD32)(temp_result >> 31);
     89 
     90   return (result);
     91 }
     92 
     93 void ixheaacd_reset_acelp_data_fix(ia_usac_data_struct *usac_data,
     94                                    ia_usac_lpd_decoder_handle st,
     95                                    WORD32 *ptr_overlap_buf,
     96                                    WORD32 was_last_short, WORD32 tw_mdct) {
     97   WORD32 i;
     98 
     99   if (was_last_short == 1) {
    100     st->mode_prev = -2;
    101   } else {
    102     st->mode_prev = -1;
    103   }
    104 
    105   for (i = 0; i < NUM_SUBFR_SUPERFRAME_BY2 - 1; i++) {
    106     st->pitch_prev[i] = 64;
    107     st->gain_prev[i] = 0;
    108   }
    109 
    110   st->bpf_active_prev = 0;
    111 
    112   if (ptr_overlap_buf != NULL && !tw_mdct) {
    113     const WORD32 *ptr_window_coeff;
    114     WORD32 fac_length;
    115     if (was_last_short) {
    116       fac_length = (usac_data->ccfl) / 16;
    117     } else {
    118       fac_length = (usac_data->len_subfrm) / 2;
    119     }
    120 
    121     if (fac_length == 48) {
    122       ptr_window_coeff = ixheaacd_sine_win_96;
    123     } else if (fac_length == 64) {
    124       ptr_window_coeff = ixheaacd_sine_win_128;
    125     } else if (fac_length == 96) {
    126       ptr_window_coeff = ixheaacd_sine_win_192;
    127     } else {
    128       ptr_window_coeff = ixheaacd_sine_win_256;
    129     }
    130 
    131     for (i = 0; i < 2 * fac_length; i++) {
    132       ptr_overlap_buf[(usac_data->ccfl) / 2 - fac_length + i] =
    133           ixheaacd_mult32_m(
    134               ptr_overlap_buf[(usac_data->ccfl) / 2 - fac_length + i],
    135               ptr_window_coeff[2 * fac_length - 1 - i]);
    136     }
    137     for (i = 0; i < (usac_data->ccfl) / 2 - fac_length; i++) {
    138       ptr_overlap_buf[(usac_data->ccfl) / 2 + fac_length + i] = 0;
    139     }
    140   }
    141 
    142   return;
    143 }
    144 
    145 VOID ixheaacd_fix2flt_data(ia_usac_data_struct *usac_data,
    146                            ia_usac_lpd_decoder_handle st, WORD32 k) {
    147   WORD32 i;
    148   WORD32 fac_length;
    149   WORD32 window_sequence_last = usac_data->window_sequence_last[k];
    150   WORD32 *p_ola_buffer = usac_data->overlap_data_ptr[k];
    151   if (window_sequence_last == EIGHT_SHORT_SEQUENCE) {
    152     fac_length = (usac_data->ccfl) / 16;
    153   } else {
    154     fac_length = (usac_data->len_subfrm) / 2;
    155   }
    156 
    157   ixheaacd_memset(st->lp_flt_coeff_a_prev, 2 * (ORDER + 1));
    158   ixheaacd_memset(st->exc_prev, 1 + (2 * FAC_LENGTH));
    159   ixheaacd_memset(st->xcitation_prev, MAX_PITCH + INTER_LP_FIL_ORDER + 1);
    160   ixheaacd_memset(st->synth_prev, MAX_PITCH + SYNTH_DELAY_LMAX);
    161   ixheaacd_memset(st->bpf_prev, FILTER_DELAY + LEN_SUBFR);
    162 
    163   st->gain_threshold = 0.0f;
    164 
    165   if (p_ola_buffer != NULL) {
    166     for (i = 0; i < (usac_data->len_subfrm) / 2 - fac_length; i++) {
    167       st->exc_prev[i] = 0;
    168     }
    169     for (i = 0; i < 2 * fac_length + 1; i++) {
    170       st->exc_prev[(usac_data->len_subfrm) / 2 - fac_length + i] = (FLOAT32)(
    171           p_ola_buffer[i + usac_data->ccfl / 2 - fac_length - 1] / 16384.0);
    172     }
    173   } else {
    174     ixheaacd_memset(st->exc_prev, 1 + (2 * FAC_LENGTH));
    175   }
    176 
    177   return;
    178 }
    179 
    180 void ixheaacd_init_acelp_data(ia_usac_data_struct *usac_data,
    181                               ia_usac_lpd_decoder_handle st) {
    182   ixheaacd_reset_acelp_data_fix(usac_data, st, NULL, 0, 0);
    183 }
    184 
    185 #define PI_BY_6400 (PI / 6400.0)
    186 #define SCALE1 (6400.0 / PI)
    187 
    188 void ixheaacd_lsp_2_lsf_conversion(float lsp[], float lsf[], WORD32 m) {
    189   short i;
    190   for (i = 0; i < m; i++) {
    191     lsf[i] = (float)(acos(lsp[i]) * SCALE1);
    192   }
    193   return;
    194 }
    195 
    196 static VOID ixheaacd_lsf_2_lsp_conversion_float(FLOAT32 lsf[], FLOAT32 lsp[],
    197                                                 WORD32 m) {
    198   WORD32 i;
    199   for (i = 0; i < m; i++)
    200     lsp[i] = (FLOAT32)cos((double)lsf[i] * (double)PI_BY_6400);
    201 
    202   return;
    203 }
    204 
    205 static WORD32 ixheaacd_bass_post_filter(FLOAT32 *synth_sig, WORD32 *pitch,
    206                                         FLOAT32 *pitch_gain, FLOAT32 *synth_out,
    207                                         WORD32 len_fr, WORD32 len2,
    208                                         FLOAT32 bpf_prev[]) {
    209   WORD32 i, j, sf, num_subfr, pitch_lag, lg;
    210   FLOAT32 x_energy, xy_corr, y_energy, norm_corr, energy, gain, tmp, alpha;
    211   FLOAT32 noise_buf[FILTER_DELAY + (2 * LEN_SUBFR)], *noise_tmp1, *noise_tmp2,
    212       *x, *y;
    213 
    214   noise_tmp1 = noise_buf + FILTER_DELAY;
    215   noise_tmp2 = noise_buf + FILTER_DELAY + LEN_SUBFR;
    216 
    217   memcpy(synth_out, synth_sig - LEN_SUBFR, len_fr * sizeof(FLOAT32));
    218 
    219   if (len_fr % 64)
    220     memset(synth_out + len_fr, 0, (LEN_SUBFR - len_fr % 64) * sizeof(FLOAT32));
    221 
    222   sf = 0;
    223   for (num_subfr = 0; num_subfr < len_fr; num_subfr += LEN_SUBFR, sf++) {
    224     pitch_lag = pitch[sf];
    225     gain = pitch_gain[sf];
    226     if (((pitch_lag >> 1) + 96 - num_subfr) > MAX_PITCH) return -1;
    227     if (gain > 1.0f) gain = 1.0f;
    228     if (gain < 0.0f) gain = 0.0f;
    229 
    230     x = &synth_sig[num_subfr - 96];
    231     y = &synth_sig[num_subfr - pitch_lag / 2 - 96];
    232 
    233     x_energy = 0.01f;
    234     xy_corr = 0.01f;
    235     y_energy = 0.01f;
    236     for (i = 0; i < LEN_SUBFR + 96; i++) {
    237       x_energy += x[i] * x[i];
    238       xy_corr += x[i] * y[i];
    239       y_energy += y[i] * y[i];
    240     }
    241 
    242     norm_corr = xy_corr / (FLOAT32)sqrt(x_energy * y_energy);
    243 
    244     if (norm_corr > 0.95f) pitch_lag >>= 1;
    245 
    246     lg = len_fr + len2 - pitch_lag - num_subfr;
    247     if (lg < 0) lg = 0;
    248     if (lg > LEN_SUBFR) lg = LEN_SUBFR;
    249 
    250     if (gain > 0) {
    251       if (lg > 0) {
    252         tmp = 0.01f;
    253         for (i = 0; i < lg; i++) {
    254           tmp += synth_sig[i + num_subfr] * synth_sig[i + num_subfr];
    255         }
    256         energy = 0.01f;
    257         for (i = 0; i < lg; i++) {
    258           energy += synth_sig[i + num_subfr + pitch_lag] *
    259                     synth_sig[i + num_subfr + pitch_lag];
    260         }
    261         tmp = (FLOAT32)sqrt(tmp / energy);
    262         if (tmp < gain) gain = tmp;
    263       }
    264 
    265       alpha = 0.5f * gain;
    266       for (i = 0; i < lg; i++) {
    267         noise_tmp2[i] = alpha * (synth_sig[i + num_subfr] -
    268                                  0.5f * synth_sig[i + num_subfr - pitch_lag] -
    269                                  0.5f * synth_sig[i + num_subfr + pitch_lag]);
    270       }
    271       for (i = lg; i < LEN_SUBFR; i++) {
    272         noise_tmp2[i] = alpha * (synth_sig[i + num_subfr] -
    273                                  synth_sig[i + num_subfr - pitch_lag]);
    274       }
    275     } else {
    276       memset(noise_tmp2, 0, LEN_SUBFR * sizeof(FLOAT32));
    277     }
    278 
    279     memcpy(noise_buf, bpf_prev, (FILTER_DELAY + LEN_SUBFR) * sizeof(FLOAT32));
    280     memcpy(bpf_prev, noise_buf + LEN_SUBFR,
    281            (FILTER_DELAY + LEN_SUBFR) * sizeof(FLOAT32));
    282 
    283     for (i = 0; i < LEN_SUBFR; i++) {
    284       tmp = ixheaacd_fir_lp_filt[0] * noise_tmp1[i];
    285       for (j = 1; j <= FILTER_DELAY; j++) {
    286         tmp +=
    287             ixheaacd_fir_lp_filt[j] * (noise_tmp1[i - j] + noise_tmp1[i + j]);
    288       }
    289       synth_out[i + num_subfr] -= tmp;
    290     }
    291   }
    292 
    293   return 0;
    294 }
    295 
    296 void ixheaacd_reorder_lsf(float *lsf, float min_dist, int n) {
    297   int i;
    298   float lsf_min;
    299 
    300   lsf_min = min_dist;
    301   for (i = 0; i < n; i++) {
    302     if (lsf[i] < lsf_min) lsf[i] = lsf_min;
    303 
    304     lsf_min = lsf[i] + min_dist;
    305   }
    306 
    307   lsf_min = FREQ_MAX_F - min_dist;
    308   for (i = n - 1; i >= 0; i--) {
    309     if (lsf[i] > lsf_min) lsf[i] = lsf_min;
    310 
    311     lsf_min = lsf[i] - min_dist;
    312   }
    313 
    314   return;
    315 }
    316 
    317 WORD32 ixheaacd_lpd_dec(ia_usac_data_struct *usac_data,
    318                         ia_usac_lpd_decoder_handle st,
    319                         ia_td_frame_data_struct *pstr_td_frame_data,
    320                         FLOAT32 fsynth[], WORD32 first_lpd_flag,
    321                         WORD32 short_fac_flag, WORD32 bpf_control_info) {
    322   FLOAT32 *synth_buf = usac_data->synth_buf;
    323   FLOAT32 *xcitation_buff = usac_data->exc_buf;
    324   FLOAT32 lsp_curr[ORDER];
    325   FLOAT32 lsf_curr[ORDER];
    326   FLOAT32 *lp_flt_coff_a = usac_data->lp_flt_coff;
    327   FLOAT32 *synth, *xcitation_curr;
    328   WORD32 *pitch = usac_data->pitch;
    329   FLOAT32 *pitch_gain = usac_data->pitch_gain;
    330   FLOAT32 lsf_flt[(2 * NUM_FRAMES + 1) * ORDER];
    331 
    332   WORD32 i, k, tp, mode;
    333   WORD32 *mod;
    334   FLOAT32 gain, stability_factor;
    335   FLOAT32 tmp, synth_corr, synth_energy;
    336 
    337   WORD32 len_fr;
    338   WORD32 len_subfrm;
    339   WORD32 num_subfr;
    340   WORD32 num_subfr_in_superfr;
    341   WORD32 num_subfr_by2;
    342   WORD32 synth_delay;
    343   WORD32 num_samples = 0;
    344 
    345   WORD32 *ptr_scratch = &usac_data->scratch_buffer[0];
    346 
    347   WORD32 subfr_len, n_subfr;
    348   WORD32 err = 0;
    349 
    350   len_fr = usac_data->ccfl;
    351   len_subfrm = usac_data->len_subfrm;
    352   num_subfr = usac_data->num_subfrm;
    353   num_subfr_in_superfr = NUM_FRAMES * num_subfr;
    354   num_subfr_by2 = (num_subfr_in_superfr / 2) - 1;
    355   synth_delay = num_subfr_by2 * LEN_SUBFR;
    356 
    357   synth = synth_buf + MAX_PITCH + synth_delay;
    358   ixheaacd_mem_cpy(st->synth_prev, synth_buf, MAX_PITCH + synth_delay);
    359   ixheaacd_memset(synth, SYNTH_DELAY_LMAX + LEN_SUPERFRAME - synth_delay);
    360 
    361   xcitation_curr = xcitation_buff + MAX_PITCH + INTER_LP_FIL_ORDER + 1;
    362   ixheaacd_mem_cpy(st->xcitation_prev, xcitation_buff,
    363                    MAX_PITCH + INTER_LP_FIL_ORDER + 1);
    364   memset(xcitation_curr, 0, sizeof(FLOAT32) * (LEN_SUPERFRAME + 1));
    365 
    366   mod = pstr_td_frame_data->mod;
    367 
    368   for (i = 0; i < num_subfr_by2; i++) {
    369     pitch[i] = st->pitch_prev[i];
    370     pitch_gain[i] = st->gain_prev[i];
    371   }
    372   for (i = 0; i < num_subfr_in_superfr; i++) {
    373     pitch[i + num_subfr_by2] = 64;
    374     pitch_gain[i + num_subfr_by2] = 0.0f;
    375   }
    376   if (!first_lpd_flag) {
    377     ixheaacd_lsp_2_lsf_conversion(st->lspold, lsf_flt, ORDER);
    378   }
    379 
    380   ixheaacd_alg_vec_dequant(pstr_td_frame_data, first_lpd_flag, lsf_flt,
    381                            pstr_td_frame_data->mod);
    382 
    383   if (first_lpd_flag) {
    384     ixheaacd_mem_cpy(&lsf_flt[0], st->lsf_prev, ORDER);
    385     ixheaacd_lsf_2_lsp_conversion_float(st->lsf_prev, st->lspold, ORDER);
    386   }
    387 
    388   if ((first_lpd_flag && mod[0] == 0) || (first_lpd_flag && mod[1] == 0) ||
    389       ((first_lpd_flag && mod[2] == 0 && len_subfrm != LEN_FRAME))) {
    390     FLOAT32 lp_flt_coeff_a[9 * (ORDER + 1)];
    391     FLOAT32 tmp_buf[3 * LEN_FRAME + ORDER];
    392     FLOAT32 tmp_res_buf[3 * LEN_FRAME];
    393     FLOAT32 *tmp = &(tmp_buf[LEN_FRAME]);
    394     FLOAT32 *ptr_tmp = &(tmp_res_buf[LEN_FRAME]);
    395     WORD32 tmp_start;
    396     FLOAT32 mem = 0;
    397     WORD32 gain;
    398     WORD32 length;
    399 
    400     ixheaacd_interpolation_lsp_params(st->lspold, st->lspold, lp_flt_coeff_a,
    401                                       8);
    402 
    403     memcpy(st->lp_flt_coeff_a_prev, lp_flt_coeff_a,
    404            (ORDER + 1) * sizeof(FLOAT32));
    405     memcpy(st->lp_flt_coeff_a_prev + ORDER + 1, lp_flt_coeff_a,
    406            (ORDER + 1) * sizeof(FLOAT32));
    407 
    408     if (mod[0] == 0) {
    409       WORD32 fac_length;
    410       if (short_fac_flag) {
    411         fac_length = (len_subfrm * NUM_FRAMES) / 16;
    412       } else {
    413         fac_length = len_subfrm / 2;
    414       }
    415       if ((pstr_td_frame_data->fac_data[0] < 0) ||
    416           (pstr_td_frame_data->fac_data[0] > 128)) {
    417         return -1;
    418       }
    419       gain = ixheaacd_pow_10_i_by_128[pstr_td_frame_data->fac_data[0]];
    420 
    421       memcpy(ptr_scratch, &pstr_td_frame_data->fac_data[0],
    422              129 * sizeof(WORD32));
    423 
    424       for (i = 0; i < 64; i++) {
    425         pstr_td_frame_data->fac_data[i] = ptr_scratch[2 * i + 1] << 16;
    426         pstr_td_frame_data->fac_data[64 + i] = ptr_scratch[fac_length - 2 * i]
    427                                                << 16;
    428       }
    429 
    430       err = ixheaacd_fwd_alias_cancel_tool(usac_data, pstr_td_frame_data,
    431                                            fac_length, lp_flt_coeff_a, gain);
    432       if (err == -1) return err;
    433 
    434       memset(
    435           &usac_data->overlap_data_ptr[usac_data->present_chan][(len_fr / 2)],
    436           0, fac_length * sizeof(WORD32));
    437     }
    438 
    439     if (mod[0] == 0 && len_subfrm != LEN_FRAME) {
    440       for (i = 0; i < 3 * len_subfrm; i++)
    441         st->fd_synth[ORDER - len_subfrm + i] = (FLOAT32)(
    442             (FLOAT32)usac_data
    443                 ->overlap_data_ptr[usac_data->present_chan][i - len_subfrm] /
    444             16384.0);
    445       num_samples = min(3 * len_subfrm, MAX_PITCH + synth_delay);
    446     } else {
    447       for (i = 0; i < 2 * len_subfrm; i++)
    448         st->fd_synth[ORDER + i] = (FLOAT32)(
    449             (FLOAT32)usac_data->overlap_data_ptr[usac_data->present_chan][i] /
    450             16384.0);
    451       num_samples = min(2 * len_subfrm, MAX_PITCH + synth_delay);
    452     }
    453     ixheaacd_mem_cpy(st->fd_synth + ORDER, synth - 2 * len_subfrm,
    454                      2 * len_subfrm);
    455     if (mod[0] == 0 && len_subfrm != LEN_FRAME) {
    456       ixheaacd_preemphsis_tool_float(st->fd_synth + ORDER - len_subfrm,
    457                                      PREEMPH_FILT_FAC, 3 * len_subfrm, mem);
    458     } else {
    459       ixheaacd_preemphsis_tool_float(st->fd_synth + ORDER, PREEMPH_FILT_FAC,
    460                                      2 * len_subfrm, mem);
    461     }
    462 
    463     if (mod[0] == 0 && len_subfrm != LEN_FRAME) {
    464       ixheaacd_memset(tmp - len_subfrm, ORDER);
    465       ixheaacd_mem_cpy(st->fd_synth + ORDER - len_subfrm,
    466                        tmp - len_subfrm + ORDER, 3 * len_subfrm);
    467       tmp_start = -len_subfrm;
    468     } else {
    469       ixheaacd_memset(tmp, ORDER);
    470       ixheaacd_mem_cpy(st->fd_synth + ORDER, tmp + ORDER, 2 * len_subfrm);
    471       tmp_start = 0;
    472     }
    473     ixheaacd_memset(ptr_tmp - len_subfrm, 3 * len_subfrm);
    474     memset(st->fd_synth, 0, ORDER * sizeof(WORD32));
    475     length = (2 * len_subfrm - tmp_start) / LEN_SUBFR;
    476 
    477     ixheaacd_residual_tool_float1(lp_flt_coeff_a,
    478                                   &st->fd_synth[ORDER + tmp_start],
    479                                   &ptr_tmp[tmp_start], LEN_SUBFR, length);
    480 
    481     if (mod[0] != 0 && (len_subfrm == LEN_FRAME || mod[1] != 0)) {
    482       num_samples = min(len_subfrm, MAX_PITCH + INTER_LP_FIL_ORDER + 1);
    483     } else if (mod[0] == 0 && len_subfrm != LEN_FRAME) {
    484       num_samples = min(3 * len_subfrm, MAX_PITCH + INTER_LP_FIL_ORDER + 1);
    485     } else {
    486       num_samples = min(2 * len_subfrm, MAX_PITCH + INTER_LP_FIL_ORDER + 1);
    487     }
    488     ixheaacd_mem_cpy(ptr_tmp + 2 * len_subfrm - num_samples,
    489                      xcitation_curr - num_samples, num_samples);
    490   }
    491 
    492   k = 0;
    493 
    494   while (k < 4) {
    495     mode = mod[k];
    496     if ((st->mode_prev == 0) && (mode > 0) &&
    497         (k != 0 || st->bpf_active_prev == 1)) {
    498       i = (k * num_subfr) + num_subfr_by2;
    499       pitch[i + 1] = pitch[i] = pitch[i - 1];
    500       pitch_gain[i + 1] = pitch_gain[i] = pitch_gain[i - 1];
    501     }
    502 
    503     if ((mode == 0) || (mode == 1))
    504       memcpy(lsf_curr, &lsf_flt[(k + 1) * ORDER], ORDER * sizeof(FLOAT32));
    505     else if (mode == 2)
    506       memcpy(lsf_curr, &lsf_flt[(k + 2) * ORDER], ORDER * sizeof(FLOAT32));
    507     else
    508       memcpy(lsf_curr, &lsf_flt[(k + 4) * ORDER], ORDER * sizeof(FLOAT32));
    509 
    510     ixheaacd_lsf_2_lsp_conversion_float(lsf_curr, lsp_curr, ORDER);
    511 
    512     tmp = 0.0f;
    513     for (i = 0; i < ORDER; i++) {
    514       tmp += (lsf_curr[i] - st->lsf_prev[i]) * (lsf_curr[i] - st->lsf_prev[i]);
    515     }
    516     stability_factor = (FLOAT32)(1.25f - (tmp / 400000.0f));
    517     if (stability_factor > 1.0f) {
    518       stability_factor = 1.0f;
    519     }
    520     if (stability_factor < 0.0f) {
    521       stability_factor = 0.0f;
    522     }
    523 
    524     if (mode == 0) {
    525       ixheaacd_interpolation_lsp_params(st->lspold, lsp_curr, lp_flt_coff_a,
    526                                         num_subfr);
    527 
    528       ixheaacd_acelp_alias_cnx(usac_data, pstr_td_frame_data, k, lp_flt_coff_a,
    529                                stability_factor, st);
    530 
    531       if ((st->mode_prev != 0) && bpf_control_info) {
    532         i = (k * num_subfr) + num_subfr_by2;
    533         pitch[i - 1] = pitch[i];
    534         pitch_gain[i - 1] = pitch_gain[i];
    535         if (st->mode_prev != -2) {
    536           pitch[i - 2] = pitch[i];
    537           pitch_gain[i - 2] = pitch_gain[i];
    538         }
    539       }
    540       k++;
    541     } else {
    542       if (mode == 1) {
    543         subfr_len = len_subfrm;
    544         n_subfr = num_subfr;
    545       } else if (mode == 2) {
    546         subfr_len = len_subfrm << 1;
    547         n_subfr = num_subfr_in_superfr / 2;
    548       } else if (mode == 3) {
    549         subfr_len = len_subfrm << 2;
    550         n_subfr = num_subfr_in_superfr;
    551       }
    552 
    553       ixheaacd_lpc_coef_gen(st->lspold, lsp_curr, lp_flt_coff_a, n_subfr,
    554                             ORDER);
    555 
    556       ixheaacd_tcx_mdct(usac_data, pstr_td_frame_data, k, lp_flt_coff_a,
    557                         subfr_len, st);
    558       k += (1 << (mode - 1));
    559     }
    560 
    561     st->mode_prev = mode;
    562 
    563     ixheaacd_mem_cpy(lsp_curr, st->lspold, ORDER);
    564     ixheaacd_mem_cpy(lsf_curr, st->lsf_prev, ORDER);
    565   }
    566 
    567   ixheaacd_mem_cpy(xcitation_buff + len_fr, st->xcitation_prev,
    568                    MAX_PITCH + INTER_LP_FIL_ORDER + 1);
    569 
    570   ixheaacd_mem_cpy(synth_buf + len_fr, st->synth_prev, MAX_PITCH + synth_delay);
    571 
    572   if (!bpf_control_info) {
    573     if (mod[0] != 0 && st->bpf_active_prev) {
    574       for (i = 2; i < num_subfr_in_superfr; i++)
    575         pitch_gain[num_subfr_by2 + i] = 0.0;
    576     } else {
    577       for (i = 0; i < num_subfr_in_superfr; i++)
    578         pitch_gain[num_subfr_by2 + i] = 0.0;
    579     }
    580   }
    581   st->bpf_active_prev = bpf_control_info;
    582 
    583   for (i = 0; i < num_subfr_by2; i++) {
    584     st->pitch_prev[i] = pitch[num_subfr_in_superfr + i];
    585     st->gain_prev[i] = pitch_gain[num_subfr_in_superfr + i];
    586   }
    587 
    588   synth = synth_buf + MAX_PITCH;
    589 
    590   for (i = 0; i < num_subfr_in_superfr; i++) {
    591     tp = pitch[i];
    592     gain = pitch_gain[i];
    593     if (gain > 0.0f) {
    594       synth_corr = 0.0f, synth_energy = 1e-6f;
    595       for (k = 0; k < LEN_SUBFR; k++) {
    596         synth_corr +=
    597             synth[i * LEN_SUBFR + k] * synth[(i * LEN_SUBFR) - tp + k];
    598         synth_energy +=
    599             synth[(i * LEN_SUBFR) - tp + k] * synth[(i * LEN_SUBFR) - tp + k];
    600       }
    601       pitch_gain[i] = synth_corr / synth_energy;
    602     }
    603   }
    604 
    605   if (mod[3] == 0) {
    606     err = ixheaacd_bass_post_filter(synth, pitch, pitch_gain, fsynth, len_fr,
    607                                     synth_delay, st->bpf_prev);
    608   } else {
    609     err =
    610         ixheaacd_bass_post_filter(synth, pitch, pitch_gain, fsynth, len_fr,
    611                                   synth_delay - (len_subfrm / 2), st->bpf_prev);
    612   }
    613   return err;
    614 }
    615 
    616 WORD32 ixheaacd_lpd_dec_update(ia_usac_lpd_decoder_handle tddec,
    617                                ia_usac_data_struct *usac_data, WORD32 i_ch) {
    618   WORD32 err = 0, i, k;
    619 
    620   WORD32 *ptr_overlap = &usac_data->overlap_data_ptr[i_ch][0];
    621   WORD32 len_fr, lpd_sbf_len, lpd_delay, num_subfr_by2, synth_delay, fac_length;
    622 
    623   if (usac_data->tw_mdct[0])
    624     ptr_overlap = &usac_data->overlap_data_ptr[i_ch][usac_data->ccfl / 2];
    625 
    626   len_fr = usac_data->ccfl;
    627   lpd_sbf_len = (NUM_FRAMES * usac_data->num_subfrm) / 2;
    628   lpd_delay = lpd_sbf_len * LEN_SUBFR;
    629   num_subfr_by2 = lpd_sbf_len - 1;
    630   synth_delay = num_subfr_by2 * LEN_SUBFR;
    631   fac_length = (usac_data->len_subfrm) / 2;
    632 
    633   for (i = 0; i < LEN_SUBFR + synth_delay; i++)
    634     ptr_overlap[i] = (WORD32)(
    635         (FLOAT32)tddec->synth_prev[MAX_PITCH - (LEN_SUBFR) + i] * 16384.0);
    636 
    637   ptr_overlap += LEN_SUBFR + synth_delay - fac_length;
    638 
    639   for (k = 0; k < 2 * fac_length; k++)
    640     ptr_overlap[k] = (WORD32)((FLOAT32)tddec->exc_prev[k + 1] * 16384.0);
    641 
    642   ptr_overlap = &usac_data->overlap_data_ptr[i_ch][lpd_delay + fac_length];
    643 
    644   for (i = 0; i < len_fr - lpd_delay - fac_length; i++) ptr_overlap[i] = 0;
    645 
    646   usac_data->window_shape[i_ch] = WIN_SEL_0;
    647   usac_data->window_sequence_last[i_ch] = EIGHT_SHORT_SEQUENCE;
    648   usac_data->td_frame_prev[i_ch] = 1;
    649 
    650   if (tddec->mode_prev == 0) {
    651     memmove(usac_data->lpc_prev[i_ch], &tddec->lp_flt_coeff_a_prev[ORDER + 1],
    652             (ORDER + 1) * sizeof(FLOAT32));
    653     memmove(usac_data->acelp_in[i_ch], tddec->exc_prev,
    654             (1 + (2 * FAC_LENGTH)) * sizeof(FLOAT32));
    655   }
    656 
    657   return err;
    658 }
    659 
    660 WORD32 ixheaacd_lpd_bpf_fix(ia_usac_data_struct *usac_data,
    661                             WORD32 is_short_flag, FLOAT32 out_buffer[],
    662                             ia_usac_lpd_decoder_handle st) {
    663   WORD32 i, tp, k;
    664   float synth_buf[MAX_PITCH + SYNTH_DELAY_LMAX + LEN_SUPERFRAME];
    665   float signal_out[LEN_SUPERFRAME];
    666   float *synth, synth_corr, synth_energy;
    667   WORD32 pitch[NUM_SUBFR_SUPERFRAME_BY2 + 3];
    668   float pitch_gain[NUM_SUBFR_SUPERFRAME_BY2 + 3];
    669   WORD32 len_fr, lpd_sbf_len, lpd_delay, num_subfr_by2, synth_delay, fac_length;
    670   WORD32 err = 0;
    671 
    672   len_fr = usac_data->ccfl;
    673   lpd_sbf_len = (NUM_FRAMES * usac_data->num_subfrm) / 2;
    674   lpd_delay = lpd_sbf_len * LEN_SUBFR;
    675   num_subfr_by2 = lpd_sbf_len - 1;
    676   synth_delay = num_subfr_by2 * LEN_SUBFR;
    677   fac_length = (usac_data->len_subfrm) / 2;
    678 
    679   ixheaacd_memset(synth_buf, MAX_PITCH + synth_delay + len_fr);
    680   synth = synth_buf + MAX_PITCH + synth_delay;
    681   ixheaacd_mem_cpy(st->synth_prev, synth_buf, MAX_PITCH + synth_delay);
    682   ixheaacd_mem_cpy(out_buffer, synth_buf + MAX_PITCH - (LEN_SUBFR),
    683                    synth_delay + len_fr + (LEN_SUBFR));
    684 
    685   for (i = 0; i < num_subfr_by2; i++) {
    686     pitch[i] = st->pitch_prev[i];
    687     pitch_gain[i] = st->gain_prev[i];
    688   }
    689   for (i = num_subfr_by2; i < lpd_sbf_len + 3; i++) {
    690     pitch[i] = 64;
    691     pitch_gain[i] = 0.0f;
    692   }
    693   if (st->mode_prev == 0) {
    694     pitch[num_subfr_by2] = pitch[num_subfr_by2 - 1];
    695     pitch_gain[num_subfr_by2] = pitch_gain[num_subfr_by2 - 1];
    696     if (!is_short_flag) {
    697       pitch[num_subfr_by2 + 1] = pitch[num_subfr_by2];
    698       pitch_gain[num_subfr_by2 + 1] = pitch_gain[num_subfr_by2];
    699     }
    700   }
    701 
    702   synth = synth_buf + MAX_PITCH;
    703 
    704   for (i = 0; i < num_subfr_by2 + 2; i++) {
    705     tp = pitch[i];
    706     if ((i * LEN_SUBFR + MAX_PITCH) < tp) {
    707       return -1;
    708     } else if ((i * LEN_SUBFR + MAX_PITCH - tp) >= 1883) {
    709       return -1;
    710     }
    711     if (pitch_gain[i] > 0.0f) {
    712       synth_corr = 0.0f, synth_energy = 1e-6f;
    713       for (k = 0; k < LEN_SUBFR; k++) {
    714         synth_corr +=
    715             synth[i * LEN_SUBFR + k] * synth[(i * LEN_SUBFR) - tp + k];
    716         synth_energy +=
    717             synth[(i * LEN_SUBFR) - tp + k] * synth[(i * LEN_SUBFR) - tp + k];
    718       }
    719       pitch_gain[i] = synth_corr / synth_energy;
    720     }
    721   }
    722 
    723   err = ixheaacd_bass_post_filter(synth, pitch, pitch_gain, signal_out,
    724                                   (lpd_sbf_len + 2) * LEN_SUBFR + LEN_SUBFR,
    725                                   len_fr - (lpd_sbf_len + 2) * LEN_SUBFR,
    726                                   st->bpf_prev);
    727   if (err != 0) return err;
    728 
    729   ixheaacd_mem_cpy(signal_out, out_buffer,
    730                    (lpd_sbf_len + 2) * LEN_SUBFR + LEN_SUBFR);
    731   return err;
    732 }
    733