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 <stdio.h>
     21 #include <string.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 
     31 #include <ixheaacd_basic_op.h>
     32 #include "ixheaacd_intrinsics.h"
     33 #include "ixheaacd_common_rom.h"
     34 #include "ixheaacd_basic_funcs.h"
     35 #include "ixheaacd_sbr_scale.h"
     36 #include "ixheaacd_sbrdecsettings.h"
     37 #include "ixheaacd_lpp_tran.h"
     38 #include "ixheaacd_bitbuffer.h"
     39 #include "ixheaacd_defines.h"
     40 
     41 #include "ixheaacd_pns.h"
     42 
     43 #include <ixheaacd_aac_rom.h>
     44 #include "ixheaacd_pulsedata.h"
     45 
     46 #include "ixheaacd_drc_data_struct.h"
     47 
     48 #include "ixheaacd_lt_predict.h"
     49 
     50 #include "ixheaacd_channelinfo.h"
     51 #include "ixheaacd_drc_dec.h"
     52 
     53 #include "ixheaacd_sbrdecoder.h"
     54 #include "ixheaacd_sbr_scale.h"
     55 #include "ixheaacd_lpp_tran.h"
     56 #include "ixheaacd_env_extr_part.h"
     57 #include <ixheaacd_sbr_rom.h>
     58 #include "ixheaacd_hybrid.h"
     59 #include "ixheaacd_ps_dec.h"
     60 #include "ixheaacd_env_extr.h"
     61 
     62 #include "ixheaacd_intrinsics.h"
     63 #include "ixheaacd_basic_funcs.h"
     64 
     65 #include "ixheaacd_qmf_dec.h"
     66 #include "ixheaacd_env_calc.h"
     67 #include "ixheaacd_sbr_const.h"
     68 
     69 #include "ixheaacd_pvc_dec.h"
     70 #include "ixheaacd_sbr_dec.h"
     71 #include "ixheaacd_function_selector.h"
     72 
     73 #include "ixheaacd_audioobjtypes.h"
     74 
     75 #define LPC_SCALE_FACTOR 2
     76 
     77 #define SHIFT 5
     78 
     79 static PLATFORM_INLINE WORD32 ixheaacd_mult32x16hin32(WORD32 a, WORD32 b) {
     80   WORD32 result;
     81   WORD64 temp_result;
     82 
     83   temp_result = (WORD64)(a) * (WORD64)(b >> 16);
     84   result = (WORD32)(temp_result >> 16);
     85 
     86   return (result);
     87 }
     88 
     89 static PLATFORM_INLINE WORD32 ixheaacd_mac32x16hin32(WORD32 a, WORD32 b,
     90                                                      WORD32 c) {
     91   WORD32 result;
     92 
     93   result = a + ixheaacd_mult32x16hin32(b, c);
     94 
     95   return (result);
     96 }
     97 
     98 static PLATFORM_INLINE WORD32 ixheaacd_macn32x16hin32(WORD32 a, WORD32 b,
     99                                                       WORD32 c) {
    100   WORD32 result;
    101 
    102   result = a - ixheaacd_mult32x16hin32(b, c);
    103 
    104   return (result);
    105 }
    106 
    107 VOID ixheaacd_filterstep3(WORD16 a0r, WORD16 a0i, WORD16 a1r, WORD16 a1i,
    108                           WORD32 start_indx, WORD32 stop_idx, WORD32 low_band,
    109                           WORD32 high_band, WORD32 *qmf_buffer) {
    110   WORD32 i;
    111   WORD32 prev1r, prev1i;
    112   WORD32 prev2r, prev2i;
    113   WORD16 coef1r = (a0r);
    114   WORD16 coef1i = (a0i);
    115   WORD16 coef2r = (a1r);
    116   WORD16 coef2i = (a1i);
    117   WORD32 *p_src, *p_dst;
    118   WORD32 qmf_real, qmf_imag;
    119 
    120   WORD32 curr, curi;
    121   p_src = qmf_buffer + low_band + ((start_indx) << 7);
    122   prev2r = *p_src;
    123   p_src += 64;
    124 
    125   prev2i = *p_src;
    126   p_src += 64;
    127 
    128   prev1r = *p_src;
    129   p_src += 64;
    130 
    131   prev1i = *p_src;
    132   p_src += 64;
    133 
    134   p_dst = qmf_buffer + high_band + ((start_indx + 2) << 7);
    135 
    136   for (i = stop_idx - start_indx; i != 0; i--) {
    137     WORD32 accu;
    138 
    139     curr = *p_src;
    140     p_src += 64;
    141 
    142     curi = *p_src;
    143     p_src += 64;
    144 
    145     qmf_real = (curr >> LPC_SCALE_FACTOR);
    146     qmf_imag = (curi >> LPC_SCALE_FACTOR);
    147 
    148     accu = ixheaacd_sub32(
    149         ixheaacd_add32(ixheaacd_sub32(ixheaacd_mult32x16in32(prev1r, coef1r),
    150                                       ixheaacd_mult32x16in32(prev1i, coef1i)),
    151                        ixheaacd_mult32x16in32(prev2r, coef2r)),
    152         ixheaacd_mult32x16in32(prev2i, coef2i));
    153 
    154     *p_dst = ixheaacd_add32(qmf_real, (accu << 1));
    155     p_dst += 64;
    156 
    157     accu = ixheaacd_add32(
    158         ixheaacd_add32_sat(
    159             ixheaacd_add32_sat(ixheaacd_mult32x16in32(prev1r, coef1i),
    160                                ixheaacd_mult32x16in32(prev1i, coef1r)),
    161             ixheaacd_mult32x16in32(prev2r, coef2i)),
    162         ixheaacd_mult32x16in32(prev2i, coef2r));
    163 
    164     *p_dst = ixheaacd_add32(qmf_imag, (accu << 1));
    165     p_dst += 64;
    166 
    167     prev2r = prev1r;
    168     prev1r = curr;
    169     prev2i = prev1i;
    170     prev1i = curi;
    171   }
    172 }
    173 
    174 VOID ixheaacd_covariance_matrix_calc_dec(
    175     WORD32 *sub_sign_xlow, ixheaacd_lpp_trans_cov_matrix *cov_matrix,
    176     WORD32 count) {
    177   WORD32 j, k;
    178   WORD32 ixheaacd_drc_offset = 2;
    179   WORD32 len = 38;
    180   WORD32 factor;
    181   WORD32 max_val, q_factor;
    182   WORD32 temp1, temp2, temp3, temp4;
    183   WORD32 *temp_buf_ptr = sub_sign_xlow;
    184 
    185   for (k = count; k > 0; k--) {
    186     WORD32 t_phi_01 = 0, t_phi_02 = 0, t_phi_11 = 0;
    187     WORD32 t_phi_12 = 0, t_phi_22 = 0;
    188 
    189     factor = -3;
    190     j = ixheaacd_drc_offset;
    191     sub_sign_xlow = temp_buf_ptr;
    192 
    193     temp1 = ixheaacd_shl32_dir(*sub_sign_xlow, factor);
    194     sub_sign_xlow += 64;
    195 
    196     temp2 = ixheaacd_shl32_dir(*sub_sign_xlow, factor);
    197     sub_sign_xlow += 64;
    198 
    199     for (; (j = j + 3) < ixheaacd_drc_offset + len;) {
    200       temp3 = ixheaacd_shl32_dir(*sub_sign_xlow, factor);
    201       sub_sign_xlow += 64;
    202 
    203       t_phi_01 += ixheaacd_mult32x16hin32(temp3, temp2);
    204       t_phi_02 += ixheaacd_mult32x16hin32(temp3, temp1);
    205       t_phi_11 += ixheaacd_mult32x16hin32(temp2, temp2);
    206 
    207       temp1 = ixheaacd_shl32_dir(*sub_sign_xlow, factor);
    208       sub_sign_xlow += 64;
    209 
    210       t_phi_01 += ixheaacd_mult32x16hin32(temp1, temp3);
    211       t_phi_02 += ixheaacd_mult32x16hin32(temp1, temp2);
    212       t_phi_11 += ixheaacd_mult32x16hin32(temp3, temp3);
    213 
    214       temp2 = ixheaacd_shl32_dir(*sub_sign_xlow, factor);
    215       sub_sign_xlow += 64;
    216 
    217       t_phi_01 += ixheaacd_mult32x16hin32(temp2, temp1);
    218       t_phi_02 += ixheaacd_mult32x16hin32(temp2, temp3);
    219       t_phi_11 += ixheaacd_mult32x16hin32(temp1, temp1);
    220     }
    221 
    222     temp3 = ixheaacd_shl32_dir(*sub_sign_xlow, factor);
    223     sub_sign_xlow += 64;
    224 
    225     t_phi_01 += ixheaacd_mult32x16hin32(temp3, temp2);
    226     t_phi_02 += ixheaacd_mult32x16hin32(temp3, temp1);
    227     t_phi_11 += ixheaacd_mult32x16hin32(temp2, temp2);
    228 
    229     temp1 = ixheaacd_shl32_dir(*sub_sign_xlow, factor);
    230     sub_sign_xlow += 64;
    231 
    232     t_phi_01 += ixheaacd_mult32x16hin32(temp1, temp3);
    233     t_phi_02 += ixheaacd_mult32x16hin32(temp1, temp2);
    234     t_phi_11 += ixheaacd_mult32x16hin32(temp3, temp3);
    235 
    236     temp2 = ixheaacd_shl32_dir(*temp_buf_ptr, factor);
    237     temp4 = ixheaacd_shl32_dir(*(temp_buf_ptr + 64), factor);
    238 
    239     t_phi_12 = (t_phi_01 - ixheaacd_mult32x16hin32(temp1, temp3) +
    240                 ixheaacd_mult32x16hin32(temp4, temp2));
    241 
    242     t_phi_22 = (t_phi_11 - ixheaacd_mult32x16hin32(temp3, temp3) +
    243                 ixheaacd_mult32x16hin32(temp2, temp2));
    244 
    245     max_val = ixheaacd_abs32_nrm(t_phi_01);
    246     max_val = max_val | ixheaacd_abs32_nrm(t_phi_02);
    247     max_val = max_val | ixheaacd_abs32_nrm(t_phi_12);
    248     max_val = max_val | (t_phi_11);
    249     max_val = max_val | (t_phi_22);
    250 
    251     q_factor = ixheaacd_pnorm32(max_val);
    252 
    253     cov_matrix->phi_11 = (t_phi_11 << q_factor);
    254     cov_matrix->phi_22 = (t_phi_22 << q_factor);
    255     cov_matrix->phi_01 = (t_phi_01 << q_factor);
    256     cov_matrix->phi_02 = (t_phi_02 << q_factor);
    257     cov_matrix->phi_12 = (t_phi_12 << q_factor);
    258 
    259     cov_matrix->d = ixheaacd_sub32_sat(
    260         ixheaacd_mult32(cov_matrix->phi_22, cov_matrix->phi_11),
    261         ixheaacd_mult32(cov_matrix->phi_12, cov_matrix->phi_12));
    262 
    263     cov_matrix++;
    264     temp_buf_ptr++;
    265   }
    266 
    267   return;
    268 }
    269 
    270 VOID ixheaacd_covariance_matrix_calc_2_dec(
    271     ixheaacd_lpp_trans_cov_matrix *cov_matrix,
    272 
    273     WORD32 *real_buffer, WORD32 num_bands, WORD16 slots) {
    274   WORD32 k;
    275   WORD32 *img_buffer;
    276   WORD32 *ptr_real = real_buffer;
    277   ixheaacd_lpp_trans_cov_matrix *pac_arr = cov_matrix;
    278 
    279   for (k = 0; k < num_bands; k++) {
    280     WORD32 t_phi_11 = 0, t_phi_01 = 0, t_phi_01_i = 0;
    281     WORD32 prev_real, prev_imag, curr_real, curr_imag;
    282 
    283     real_buffer = ptr_real;
    284     img_buffer = real_buffer + 64;
    285     cov_matrix = pac_arr;
    286 
    287     prev_real = real_buffer[-128];
    288     prev_imag = img_buffer[-128];
    289 
    290     curr_real = real_buffer[0];
    291     curr_imag = img_buffer[0];
    292 
    293     curr_real = ixheaacd_shr32(curr_real, 3);
    294     curr_imag = ixheaacd_shr32(curr_imag, 3);
    295     prev_real = ixheaacd_shr32(prev_real, 3);
    296     prev_imag = ixheaacd_shr32(prev_imag, 3);
    297 
    298     t_phi_01 = ixheaacd_mult32x16hin32(curr_real, prev_real);
    299     t_phi_01 = ixheaacd_mac32x16hin32(t_phi_01, curr_imag, prev_imag);
    300 
    301     t_phi_01_i = ixheaacd_mult32x16hin32(curr_imag, prev_real);
    302     t_phi_01_i = ixheaacd_macn32x16hin32(t_phi_01_i, curr_real, prev_imag);
    303 
    304     t_phi_11 = ixheaacd_mult32x16hin32(prev_real, prev_real);
    305     t_phi_11 = ixheaacd_mac32x16hin32(t_phi_11, prev_imag, prev_imag);
    306 
    307     {
    308       WORD n;
    309       WORD32 *real1 = &real_buffer[128];
    310       WORD32 *imag1 = &img_buffer[128];
    311 
    312       prev_real = curr_real;
    313       prev_imag = curr_imag;
    314 
    315       for (n = ((slots - 2) >> 1); n; n--) {
    316         curr_real = *real1;
    317         real1 += 128;
    318         curr_imag = *imag1;
    319         imag1 += 128;
    320 
    321         curr_real = ixheaacd_shr32(curr_real, 3);
    322         curr_imag = ixheaacd_shr32(curr_imag, 3);
    323 
    324         t_phi_01 = ixheaacd_mac32x16hin32(t_phi_01, curr_real, prev_real);
    325         t_phi_01 = ixheaacd_mac32x16hin32(t_phi_01, curr_imag, prev_imag);
    326 
    327         t_phi_01_i = ixheaacd_mac32x16hin32(t_phi_01_i, curr_imag, prev_real);
    328         t_phi_01_i = ixheaacd_macn32x16hin32(t_phi_01_i, curr_real, prev_imag);
    329 
    330         t_phi_11 = ixheaacd_mac32x16hin32(t_phi_11, prev_real, prev_real);
    331         t_phi_11 = ixheaacd_mac32x16hin32(t_phi_11, prev_imag, prev_imag);
    332 
    333         prev_real = *real1;
    334         real1 += 128;
    335         prev_imag = *imag1;
    336         imag1 += 128;
    337 
    338         prev_real = ixheaacd_shr32(prev_real, 3);
    339         prev_imag = ixheaacd_shr32(prev_imag, 3);
    340 
    341         t_phi_01 = ixheaacd_mac32x16hin32(t_phi_01, prev_real, curr_real);
    342         t_phi_01 = ixheaacd_mac32x16hin32(t_phi_01, prev_imag, curr_imag);
    343 
    344         t_phi_01_i = ixheaacd_mac32x16hin32(t_phi_01_i, prev_imag, curr_real);
    345         t_phi_01_i = ixheaacd_macn32x16hin32(t_phi_01_i, prev_real, curr_imag);
    346 
    347         t_phi_11 = ixheaacd_mac32x16hin32(t_phi_11, curr_real, curr_real);
    348         t_phi_11 = ixheaacd_mac32x16hin32(t_phi_11, curr_imag, curr_imag);
    349       }
    350 
    351       if (slots & 0x01) {
    352         curr_real = *real1;
    353         curr_imag = *imag1;
    354 
    355         curr_real = ixheaacd_shr32(curr_real, 3);
    356         curr_imag = ixheaacd_shr32(curr_imag, 3);
    357 
    358         t_phi_01 = ixheaacd_mac32x16hin32(t_phi_01, curr_real, prev_real);
    359         t_phi_01 = ixheaacd_mac32x16hin32(t_phi_01, curr_imag, prev_imag);
    360 
    361         t_phi_01_i = ixheaacd_mac32x16hin32(t_phi_01_i, curr_imag, prev_real);
    362         t_phi_01_i = ixheaacd_macn32x16hin32(t_phi_01_i, curr_real, prev_imag);
    363 
    364         t_phi_11 = ixheaacd_mac32x16hin32(t_phi_11, prev_real, prev_real);
    365         t_phi_11 = ixheaacd_mac32x16hin32(t_phi_11, prev_imag, prev_imag);
    366       }
    367     }
    368 
    369     {
    370       WORD32 t_phi_22 = t_phi_11;
    371       WORD32 curr_real = real_buffer[-2 * 128];
    372       WORD32 curr_imag = img_buffer[-2 * 128];
    373 
    374       curr_real = ixheaacd_shr32(curr_real, 3);
    375       curr_imag = ixheaacd_shr32(curr_imag, 3);
    376 
    377       t_phi_22 = ixheaacd_mac32x16hin32(t_phi_22, curr_real, curr_real);
    378       t_phi_22 = ixheaacd_mac32x16hin32(t_phi_22, curr_imag, curr_imag);
    379 
    380       curr_real = real_buffer[(slots - 2) * 128];
    381       curr_imag = img_buffer[(slots - 2) * 128];
    382 
    383       curr_real = ixheaacd_shr32(curr_real, 3);
    384       curr_imag = ixheaacd_shr32(curr_imag, 3);
    385 
    386       t_phi_11 = ixheaacd_mac32x16hin32(t_phi_11, curr_real, curr_real);
    387       t_phi_11 = ixheaacd_mac32x16hin32(t_phi_11, curr_imag, curr_imag);
    388 
    389       cov_matrix->phi_11 = t_phi_11;
    390       cov_matrix->phi_22 = t_phi_22;
    391     }
    392 
    393     {
    394       WORD32 t_phi_12 = t_phi_01;
    395 
    396       t_phi_12 = ixheaacd_mac32x16hin32(t_phi_12, real_buffer[-128] >> 3,
    397                                         real_buffer[-2 * 128] >> 3);
    398       t_phi_12 = ixheaacd_mac32x16hin32(t_phi_12, img_buffer[-128] >> 3,
    399                                         img_buffer[-2 * 128] >> 3);
    400       t_phi_01 =
    401           ixheaacd_mac32x16hin32(t_phi_01, real_buffer[(slots - 1) * 128] >> 3,
    402                                  real_buffer[(slots - 2) * 128] >> 3);
    403       t_phi_01 =
    404           ixheaacd_mac32x16hin32(t_phi_01, img_buffer[(slots - 1) * 128] >> 3,
    405                                  img_buffer[(slots - 2) * 128] >> 3);
    406 
    407       cov_matrix->phi_01 = t_phi_01;
    408       cov_matrix->phi_12 = t_phi_12;
    409     }
    410 
    411     {
    412       WORD32 t_phi_12_i = t_phi_01_i;
    413 
    414       t_phi_12_i = ixheaacd_mac32x16hin32(t_phi_12_i, img_buffer[-128] >> 3,
    415                                           real_buffer[-2 * 128] >> 3);
    416       t_phi_12_i = ixheaacd_macn32x16hin32(t_phi_12_i, real_buffer[-128] >> 3,
    417                                            img_buffer[-2 * 128] >> 3);
    418       t_phi_01_i =
    419           ixheaacd_mac32x16hin32(t_phi_01_i, img_buffer[(slots - 1) * 128] >> 3,
    420                                  real_buffer[(slots - 2) * 128] >> 3);
    421       t_phi_01_i = ixheaacd_macn32x16hin32(t_phi_01_i,
    422                                            real_buffer[(slots - 1) * 128] >> 3,
    423                                            img_buffer[(slots - 2) * 128] >> 3);
    424 
    425       cov_matrix->phi_01_im = t_phi_01_i;
    426       cov_matrix->phi_12_im = t_phi_12_i;
    427     }
    428 
    429     {
    430       WORD16 n, len_by_4, p;
    431       WORD32 t_phi_02 = 0x00, t_phi_02_i = 0x00;
    432 
    433       len_by_4 = (slots >> 2);
    434       p = 0;
    435       for (n = 0; n < len_by_4; n++) {
    436         WORD32 real1, real2, imag1, imag2;
    437         real1 = real_buffer[p * 128];
    438         real2 = real_buffer[(p - 2) * 128];
    439         imag1 = img_buffer[p * 128];
    440         imag2 = img_buffer[(p - 2) * 128];
    441 
    442         real1 = ixheaacd_shr32(real1, 3);
    443         real2 = ixheaacd_shr32(real2, 3);
    444         imag1 = ixheaacd_shr32(imag1, 3);
    445         imag2 = ixheaacd_shr32(imag2, 3);
    446 
    447         t_phi_02 = ixheaacd_mac32x16hin32(t_phi_02, real1, real2);
    448         t_phi_02 = ixheaacd_mac32x16hin32(t_phi_02, imag1, imag2);
    449         t_phi_02_i = ixheaacd_mac32x16hin32(t_phi_02_i, imag1, real2);
    450         t_phi_02_i = ixheaacd_macn32x16hin32(t_phi_02_i, real1, imag2);
    451 
    452         real1 = real_buffer[(p + 1) * 128];
    453         real2 = real_buffer[(p - 1) * 128];
    454         imag1 = img_buffer[(p + 1) * 128];
    455         imag2 = img_buffer[(p - 1) * 128];
    456 
    457         real1 = ixheaacd_shr32(real1, 3);
    458         real2 = ixheaacd_shr32(real2, 3);
    459         imag1 = ixheaacd_shr32(imag1, 3);
    460         imag2 = ixheaacd_shr32(imag2, 3);
    461 
    462         t_phi_02 = ixheaacd_mac32x16hin32(t_phi_02, real1, real2);
    463         t_phi_02 = ixheaacd_mac32x16hin32(t_phi_02, imag1, imag2);
    464         t_phi_02_i = ixheaacd_mac32x16hin32(t_phi_02_i, imag1, real2);
    465         t_phi_02_i = ixheaacd_macn32x16hin32(t_phi_02_i, real1, imag2);
    466 
    467         real1 = real_buffer[(p + 2) * 128];
    468         real2 = real_buffer[p * 128];
    469         imag1 = img_buffer[(p + 2) * 128];
    470         imag2 = img_buffer[p * 128];
    471 
    472         real1 = ixheaacd_shr32(real1, 3);
    473         real2 = ixheaacd_shr32(real2, 3);
    474         imag1 = ixheaacd_shr32(imag1, 3);
    475         imag2 = ixheaacd_shr32(imag2, 3);
    476 
    477         t_phi_02 = ixheaacd_mac32x16hin32(t_phi_02, real1, real2);
    478         t_phi_02 = ixheaacd_mac32x16hin32(t_phi_02, imag1, imag2);
    479         t_phi_02_i = ixheaacd_mac32x16hin32(t_phi_02_i, imag1, real2);
    480         t_phi_02_i = ixheaacd_macn32x16hin32(t_phi_02_i, real1, imag2);
    481 
    482         real1 = real_buffer[(p + 3) * 128];
    483         real2 = real_buffer[(p + 1) * 128];
    484         imag1 = img_buffer[(p + 3) * 128];
    485         imag2 = img_buffer[(p + 1) * 128];
    486 
    487         real1 = ixheaacd_shr32(real1, 3);
    488         real2 = ixheaacd_shr32(real2, 3);
    489         imag1 = ixheaacd_shr32(imag1, 3);
    490         imag2 = ixheaacd_shr32(imag2, 3);
    491 
    492         t_phi_02 = ixheaacd_mac32x16hin32(t_phi_02, real1, real2);
    493         t_phi_02 = ixheaacd_mac32x16hin32(t_phi_02, imag1, imag2);
    494         t_phi_02_i = ixheaacd_mac32x16hin32(t_phi_02_i, imag1, real2);
    495         t_phi_02_i = ixheaacd_macn32x16hin32(t_phi_02_i, real1, imag2);
    496         p += 4;
    497       }
    498       n = ixheaacd_shl16(len_by_4, 2);
    499       for (; n < slots; n++) {
    500         WORD32 real1, real2, imag1, imag2;
    501         real1 = real_buffer[(n * 128)];
    502         real2 = real_buffer[(n - 2) * 128];
    503         imag1 = img_buffer[n * 128];
    504         imag2 = img_buffer[(n - 2) * 128];
    505 
    506         real1 = ixheaacd_shr32(real1, 3);
    507         real2 = ixheaacd_shr32(real2, 3);
    508         imag1 = ixheaacd_shr32(imag1, 3);
    509         imag2 = ixheaacd_shr32(imag2, 3);
    510 
    511         t_phi_02 = ixheaacd_mac32x16hin32(t_phi_02, real1, real2);
    512         t_phi_02 = ixheaacd_mac32x16hin32(t_phi_02, imag1, imag2);
    513         t_phi_02_i = ixheaacd_mac32x16hin32(t_phi_02_i, imag1, real2);
    514         t_phi_02_i = ixheaacd_macn32x16hin32(t_phi_02_i, real1, imag2);
    515       }
    516 
    517       cov_matrix->phi_02 = t_phi_02;
    518       cov_matrix->phi_02_im = t_phi_02_i;
    519     }
    520     ptr_real++;
    521     pac_arr++;
    522   }
    523 }
    524 
    525 static PLATFORM_INLINE VOID ixheaacd_filt_step3_lp(WORD len, WORD32 coef1,
    526                                                    WORD32 coef2,
    527                                                    WORD32 *pqmf_real_low,
    528                                                    WORD32 *pqmf_real_high) {
    529   WORD32 prev1;
    530   WORD32 prev2;
    531   WORD32 i;
    532 
    533   prev2 = *pqmf_real_low;
    534   pqmf_real_low += 64;
    535 
    536   prev1 = *pqmf_real_low;
    537   pqmf_real_low += 64;
    538 
    539   for (i = len; i >= 0; i -= 2) {
    540     WORD32 curr = *pqmf_real_low;
    541     WORD32 temp = ixheaacd_mult32x16hin32(prev2, coef2);
    542     pqmf_real_low += 64;
    543 
    544     *pqmf_real_high =
    545         ixheaacd_add32((curr >> LPC_SCALE_FACTOR),
    546                        ((ixheaacd_mac32x16hin32(temp, prev1, coef1)) << 1));
    547     pqmf_real_high += 64;
    548 
    549     prev2 = *pqmf_real_low;
    550     temp = ixheaacd_mult32x16hin32(prev1, coef2);
    551     pqmf_real_low += 64;
    552 
    553     *pqmf_real_high =
    554         ixheaacd_add32((prev2 >> LPC_SCALE_FACTOR),
    555                        ((ixheaacd_mac32x16hin32(temp, curr, coef1)) << 1));
    556     pqmf_real_high += 64;
    557 
    558     prev1 = prev2;
    559     prev2 = curr;
    560   }
    561 }
    562 
    563 VOID ixheaacd_filter1_lp(ia_sbr_hf_generator_struct *hf_generator,
    564                          ixheaacd_lpp_trans_cov_matrix *cov_matrix_seq,
    565                          WORD32 *bw_array, WORD16 *degree_alias,
    566                          WORD32 start_idx, WORD32 stop_idx,
    567                          WORD32 max_qmf_subband, WORD32 start_patch,
    568                          WORD32 stop_patch, WORD32 *sub_sig_x) {
    569   WORD16 k1, k1_below = 0, k1_below2 = 0;
    570   WORD32 i;
    571   WORD16 alpha_real[LPC_ORDER];
    572   WORD32 low_band, high_band;
    573   WORD32 patch;
    574   WORD16 bw = 0;
    575   WORD32 a0r, a1r;
    576 
    577   WORD num_patches = hf_generator->pstr_settings->num_patches;
    578   ia_patch_param_struct *patch_param =
    579       hf_generator->pstr_settings->str_patch_param;
    580   WORD32 bw_index[MAX_NUM_PATCHES];
    581 
    582   memset(bw_index, 0, sizeof(WORD32) * num_patches);
    583 
    584   for (low_band = start_patch; low_band < stop_patch; low_band++) {
    585     ixheaacd_lpp_trans_cov_matrix *p_cov_matrix = &cov_matrix_seq[low_band];
    586 
    587     alpha_real[1] = 0;
    588     alpha_real[0] = 0;
    589 
    590     if (p_cov_matrix->d != 0) {
    591       WORD32 tmp_r, temp_real, modulus_d;
    592       WORD16 inverse_d;
    593       WORD32 norm_d;
    594 
    595       norm_d = ixheaacd_norm32(p_cov_matrix->d);
    596 
    597       inverse_d =
    598           (WORD16)(*ixheaacd_fix_div)(0x40000000, (p_cov_matrix->d << norm_d));
    599       modulus_d = ixheaacd_abs32(p_cov_matrix->d);
    600 
    601       tmp_r =
    602           (ixheaacd_sub32_sat(
    603                ixheaacd_mult32(p_cov_matrix->phi_01, p_cov_matrix->phi_12),
    604                ixheaacd_mult32(p_cov_matrix->phi_02, p_cov_matrix->phi_11)) >>
    605            LPC_SCALE_FACTOR);
    606       temp_real = ixheaacd_abs32(tmp_r);
    607 
    608       if (temp_real < modulus_d) {
    609         alpha_real[1] = (WORD16)(
    610             (ixheaacd_mult32x16in32_shl_sat(tmp_r, inverse_d) << norm_d) >> 15);
    611       }
    612 
    613       tmp_r =
    614           (ixheaacd_sub32_sat(
    615                ixheaacd_mult32(p_cov_matrix->phi_02, p_cov_matrix->phi_12),
    616                ixheaacd_mult32(p_cov_matrix->phi_01, p_cov_matrix->phi_22)) >>
    617            LPC_SCALE_FACTOR);
    618       temp_real = ixheaacd_abs32(tmp_r);
    619 
    620       if (temp_real < modulus_d) {
    621         alpha_real[0] = (WORD16)(
    622             (ixheaacd_mult32x16in32_shl_sat(tmp_r, inverse_d) << norm_d) >> 15);
    623       }
    624     }
    625 
    626     if (p_cov_matrix->phi_11 == 0) {
    627       k1 = 0;
    628     } else {
    629       if (ixheaacd_abs32_sat(p_cov_matrix->phi_01) >= p_cov_matrix->phi_11) {
    630         if (p_cov_matrix->phi_01 < 0) {
    631           k1 = 0x7fff;
    632         } else {
    633           k1 = (WORD16)-0x8000;
    634         }
    635       } else {
    636         k1 = -((WORD16)(
    637             (*ixheaacd_fix_div)(p_cov_matrix->phi_01, p_cov_matrix->phi_11)));
    638       }
    639     }
    640 
    641     if (low_band > 1) {
    642       WORD16 deg = ixheaacd_sub16_sat(
    643           0x7fff, ixheaacd_mult16_shl_sat(k1_below, k1_below));
    644       degree_alias[low_band] = 0;
    645 
    646       if (((low_band & 1) == 0) && (k1 < 0)) {
    647         if (k1_below < 0) {
    648           degree_alias[low_band] = 0x7fff;
    649 
    650           if (k1_below2 > 0) {
    651             degree_alias[low_band - 1] = deg;
    652           }
    653         } else {
    654           if (k1_below2 > 0) {
    655             degree_alias[low_band] = deg;
    656           }
    657         }
    658       }
    659 
    660       if (((low_band & 1) != 0) && (k1 > 0)) {
    661         if (k1_below > 0) {
    662           degree_alias[low_band] = 0x7fff;
    663 
    664           if (k1_below2 < 0) {
    665             degree_alias[low_band - 1] = deg;
    666           }
    667         } else {
    668           if (k1_below2 < 0) {
    669             degree_alias[low_band] = deg;
    670           }
    671         }
    672       }
    673     }
    674 
    675     k1_below2 = k1_below;
    676     k1_below = k1;
    677 
    678     patch = 0;
    679     while (patch < num_patches) {
    680       ia_patch_param_struct *p_loc_patch_param = &patch_param[patch];
    681       WORD32 bw_vec, bw_idx;
    682       WORD16 alpha1, alpha2;
    683 
    684       high_band = (((low_band + p_loc_patch_param->dst_end_band) << 8) >> 8);
    685 
    686       if ((low_band < p_loc_patch_param->src_start_band) ||
    687           (low_band >= p_loc_patch_param->src_end_band) ||
    688           (high_band < max_qmf_subband)) {
    689         patch++;
    690         continue;
    691       }
    692 
    693       bw_idx = bw_index[patch];
    694       while (high_band >= hf_generator->pstr_settings->bw_borders[bw_idx]) {
    695         bw_idx++;
    696         bw_index[patch] = bw_idx;
    697       }
    698 
    699       bw_vec = bw_array[bw_idx];
    700       alpha1 = alpha_real[0];
    701       alpha2 = alpha_real[1];
    702 
    703       bw = ixheaacd_extract16h(bw_vec);
    704       a0r = ixheaacd_mult16x16in32_shl(bw, alpha1);
    705       bw = ixheaacd_mult16_shl_sat(bw, bw);
    706       a1r = ixheaacd_mult16x16in32_shl(bw, alpha2);
    707 
    708       {
    709         WORD32 *p_sub_signal_xlow = sub_sig_x + low_band + ((start_idx) << 6);
    710         WORD32 *p_sub_signal_xhigh =
    711             sub_sig_x + high_band + ((start_idx + 2) << 6);
    712         WORD32 len = stop_idx - start_idx - 1;
    713 
    714         if (bw > 0) {
    715           ixheaacd_filt_step3_lp(len, a0r, a1r, p_sub_signal_xlow,
    716                                  p_sub_signal_xhigh);
    717 
    718         } else {
    719           p_sub_signal_xlow += 128;
    720           for (i = len; i >= 0; i--) {
    721             *p_sub_signal_xhigh = *p_sub_signal_xlow >> LPC_SCALE_FACTOR;
    722             p_sub_signal_xlow += 64;
    723             p_sub_signal_xhigh += 64;
    724           }
    725         }
    726       }
    727 
    728       patch++;
    729     }
    730   }
    731 }
    732 
    733 VOID ixheaacd_clr_subsamples(WORD32 *ptr_qmf_buf, WORD32 num, WORD32 size) {
    734   WORD32 i;
    735   for (i = num; i >= 0; i--) {
    736     memset(ptr_qmf_buf, 0, sizeof(WORD32) * (size));
    737     ptr_qmf_buf += 64;
    738   }
    739 }
    740 
    741 VOID ixheaacd_low_pow_hf_generator(ia_sbr_hf_generator_struct *hf_generator,
    742                                    WORD32 **qmf_real, WORD16 *degree_alias,
    743                                    WORD32 start_idx, WORD32 stop_idx,
    744                                    WORD32 num_if_bands, WORD32 max_qmf_subband,
    745                                    WORD32 *sbr_invf_mode,
    746                                    WORD32 *sbr_invf_mode_prev, WORD32 norm_max,
    747                                    WORD32 *sub_sig_x) {
    748   WORD32 bw_array[MAX_NUM_PATCHES];
    749   WORD32 i;
    750   WORD32 start_patch, stop_patch, low_band, high_band;
    751   ia_patch_param_struct *patch_param =
    752       hf_generator->pstr_settings->str_patch_param;
    753   WORD32 patch;
    754   ixheaacd_lpp_trans_cov_matrix cov_matrix_seq[MAX_COLS];
    755 
    756   WORD32 actual_stop_band;
    757   WORD32 num_patches = hf_generator->pstr_settings->num_patches;
    758 
    759   stop_idx = (hf_generator->pstr_settings->num_columns + stop_idx);
    760 
    761   ixheaacd_invfilt_level_emphasis(hf_generator, num_if_bands, sbr_invf_mode,
    762                                   sbr_invf_mode_prev, bw_array);
    763 
    764   actual_stop_band =
    765       ixheaacd_add16(patch_param[num_patches - 1].dst_start_band,
    766                      patch_param[num_patches - 1].num_bands_in_patch);
    767 
    768   {
    769     WORD32 *p_qmf_real;
    770     WORD32 len = 6, num;
    771 
    772     if (len > stop_idx) len = stop_idx;
    773 
    774     p_qmf_real = &qmf_real[start_idx][actual_stop_band];
    775     num = (len - start_idx - 1);
    776     ixheaacd_clr_subsamples(p_qmf_real, num,
    777                             (NO_SYNTHESIS_CHANNELS - actual_stop_band));
    778 
    779     if (actual_stop_band < 32) {
    780       num = (stop_idx - len - 1);
    781       p_qmf_real = &qmf_real[len][actual_stop_band];
    782       ixheaacd_clr_subsamples(p_qmf_real, num,
    783                               (NO_ANALYSIS_CHANNELS - actual_stop_band));
    784     }
    785   }
    786 
    787   start_patch = ixheaacd_max16(
    788       1, ixheaacd_sub16(hf_generator->pstr_settings->start_patch, 2));
    789   stop_patch = patch_param[0].dst_start_band;
    790 
    791   {
    792     WORD32 *ptr = &sub_sig_x[0];
    793     WORD32 *plpc_filt_states_real = &hf_generator->lpc_filt_states_real[0][0];
    794     for (i = LPC_ORDER; i != 0; i--) {
    795       memcpy(ptr, plpc_filt_states_real, sizeof(WORD32) * (stop_patch));
    796       ptr += NO_SYNTHESIS_CHANNELS;
    797       plpc_filt_states_real += 32;
    798     }
    799   }
    800   if (norm_max != 30) {
    801     (*ixheaacd_covariance_matrix_calc)(sub_sig_x + start_patch,
    802                                        &cov_matrix_seq[start_patch],
    803                                        (stop_patch - start_patch));
    804 
    805   } else {
    806     memset(&cov_matrix_seq[0], 0,
    807            sizeof(ixheaacd_lpp_trans_cov_matrix) * stop_patch);
    808   }
    809 
    810   ixheaacd_filter1_lp(hf_generator, cov_matrix_seq, bw_array, degree_alias,
    811                       start_idx, stop_idx, max_qmf_subband, start_patch,
    812                       stop_patch, sub_sig_x);
    813 
    814   start_patch = hf_generator->pstr_settings->start_patch;
    815   stop_patch = hf_generator->pstr_settings->stop_patch;
    816 
    817   for (low_band = start_patch; low_band < stop_patch; low_band++) {
    818     WORD32 src_start_band, src_end_band, dst_start_band, dst_end_band;
    819     patch = 0;
    820 
    821     while (patch < num_patches) {
    822       ia_patch_param_struct *ptr_loc_patch_param = &patch_param[patch];
    823 
    824       src_start_band = ptr_loc_patch_param->src_start_band;
    825       src_end_band = ptr_loc_patch_param->src_end_band;
    826       dst_start_band = ptr_loc_patch_param->dst_start_band;
    827       dst_end_band = ptr_loc_patch_param->dst_end_band;
    828 
    829       high_band = (low_band + ptr_loc_patch_param->dst_end_band);
    830 
    831       if ((low_band < src_start_band) || (low_band >= src_end_band) ||
    832           (high_band >= NO_SYNTHESIS_CHANNELS)) {
    833         patch++;
    834         continue;
    835       }
    836 
    837       if ((high_band != dst_start_band)) {
    838         degree_alias[high_band] = degree_alias[low_band];
    839       }
    840 
    841       patch++;
    842     }
    843   }
    844 
    845   memcpy(hf_generator->bw_array_prev, bw_array, sizeof(WORD32) * num_if_bands);
    846 }
    847 
    848 VOID ixheaacd_hf_generator(ia_sbr_hf_generator_struct *hf_generator,
    849                            ia_sbr_scale_fact_struct *scale_factor,
    850                            WORD32 **qmf_real, WORD32 **qmf_imag, WORD32 factor,
    851                            WORD32 start_idx, WORD32 stop_idx,
    852                            WORD32 num_if_bands, WORD32 max_qmf_subband,
    853                            WORD32 *sbr_invf_mode, WORD32 *sbr_invf_mode_prev,
    854                            WORD32 *sub_sig_x, WORD audio_object_type) {
    855   WORD32 bw_index[MAX_NUM_PATCHES];
    856   WORD32 bw_array[MAX_NUM_PATCHES];
    857 
    858   WORD32 i, j;
    859   WORD32 start_patch, stop_patch, low_band, high_band;
    860   ia_patch_param_struct *patch_param =
    861       hf_generator->pstr_settings->str_patch_param;
    862   WORD32 patch;
    863 
    864   WORD16 alpha_real[LPC_ORDER];
    865   WORD16 a0r, a1r;
    866   WORD16 alpha_imag[LPC_ORDER];
    867   WORD16 a0i = 0, a1i = 0;
    868 
    869   WORD16 bw = 0;
    870 
    871   ixheaacd_lpp_trans_cov_matrix cov_matrix;
    872   ixheaacd_lpp_trans_cov_matrix cov_matrix_seq[MAX_COLS];
    873 
    874   WORD32 common_scale;
    875   WORD32 actual_stop_band;
    876   WORD32 num_patches = hf_generator->pstr_settings->num_patches;
    877 
    878   start_idx = (start_idx * factor);
    879 
    880   stop_idx = (hf_generator->pstr_settings->num_columns + (stop_idx * factor));
    881 
    882   ixheaacd_invfilt_level_emphasis(hf_generator, num_if_bands, sbr_invf_mode,
    883                                   sbr_invf_mode_prev, bw_array);
    884 
    885   actual_stop_band =
    886       ixheaacd_add16(patch_param[num_patches - 1].dst_start_band,
    887                      patch_param[num_patches - 1].num_bands_in_patch);
    888 
    889   for (i = start_idx; i < stop_idx; i++) {
    890     WORD32 *p_qmf_real = &qmf_real[i][actual_stop_band];
    891     WORD32 *p_qmf_imag = &qmf_imag[i][actual_stop_band];
    892 
    893     for (j = NO_SYNTHESIS_CHANNELS - actual_stop_band; j != 0; j--) {
    894       *p_qmf_real++ = 0;
    895       *p_qmf_imag++ = 0;
    896     }
    897   }
    898 
    899   memset(bw_index, 0, sizeof(WORD32) * num_patches);
    900 
    901   common_scale =
    902       ixheaacd_min32(scale_factor->ov_lb_scale, scale_factor->lb_scale);
    903 
    904   start_patch = hf_generator->pstr_settings->start_patch;
    905   stop_patch = hf_generator->pstr_settings->stop_patch;
    906 
    907   {
    908     WORD32 *ptr;
    909     for (i = 0; i < LPC_ORDER; i++) {
    910       ptr = sub_sig_x + (start_patch) + i * 128;
    911       memcpy(ptr, &hf_generator->lpc_filt_states_real[i][start_patch],
    912              sizeof(WORD32) * (stop_patch - start_patch));
    913       memcpy(ptr + 64, &hf_generator->lpc_filt_states_imag[i][start_patch],
    914              sizeof(WORD32) * (stop_patch - start_patch));
    915     }
    916   }
    917   if (audio_object_type != AOT_ER_AAC_ELD &&
    918       audio_object_type != AOT_ER_AAC_LD) {
    919     (*ixheaacd_covariance_matrix_calc_2)(
    920         &cov_matrix_seq[start_patch],
    921         (sub_sig_x + start_patch + LPC_ORDER * 128), (stop_patch - start_patch),
    922         38);
    923   } else {
    924     (*ixheaacd_covariance_matrix_calc_2)(
    925         &cov_matrix_seq[start_patch],
    926         (sub_sig_x + start_patch + LPC_ORDER * 128), (stop_patch - start_patch),
    927         16);
    928   }
    929 
    930   for (low_band = start_patch; low_band < stop_patch; low_band++) {
    931     FLAG reset_lpc_coeff = 0;
    932     WORD32 max_val;
    933     WORD32 q_shift;
    934     WORD32 v;
    935     max_val = ixheaacd_abs32_nrm(cov_matrix_seq[low_band].phi_01);
    936     max_val = max_val | ixheaacd_abs32_nrm(cov_matrix_seq[low_band].phi_02);
    937     max_val = max_val | ixheaacd_abs32_nrm(cov_matrix_seq[low_band].phi_12);
    938 
    939     max_val = max_val | (cov_matrix_seq[low_band].phi_11);
    940     max_val = max_val | (cov_matrix_seq[low_band].phi_22);
    941     max_val = max_val | ixheaacd_abs32_nrm(cov_matrix_seq[low_band].phi_01_im);
    942     max_val = max_val | ixheaacd_abs32_nrm(cov_matrix_seq[low_band].phi_02_im);
    943     max_val = max_val | ixheaacd_abs32_nrm(cov_matrix_seq[low_band].phi_12_im);
    944 
    945     q_shift = ixheaacd_pnorm32(max_val);
    946 
    947     cov_matrix.phi_11 = (cov_matrix_seq[low_band].phi_11 << q_shift);
    948     cov_matrix.phi_22 = (cov_matrix_seq[low_band].phi_22 << q_shift);
    949     cov_matrix.phi_01 = (cov_matrix_seq[low_band].phi_01 << q_shift);
    950     cov_matrix.phi_02 = (cov_matrix_seq[low_band].phi_02 << q_shift);
    951     cov_matrix.phi_12 = (cov_matrix_seq[low_band].phi_12 << q_shift);
    952     cov_matrix.phi_01_im = (cov_matrix_seq[low_band].phi_01_im << q_shift);
    953     cov_matrix.phi_02_im = (cov_matrix_seq[low_band].phi_02_im << q_shift);
    954     cov_matrix.phi_12_im = (cov_matrix_seq[low_band].phi_12_im << q_shift);
    955 
    956     max_val = ixheaacd_mult32(cov_matrix.phi_12, cov_matrix.phi_12);
    957     max_val = ixheaacd_add32_sat(
    958         max_val, ixheaacd_mult32(cov_matrix.phi_12_im, cov_matrix.phi_12_im));
    959 
    960     v = ixheaacd_sub32(ixheaacd_mult32(cov_matrix.phi_11, cov_matrix.phi_22),
    961                        max_val)
    962         << 1;
    963     cov_matrix.d = v;
    964 
    965     alpha_real[1] = 0;
    966     alpha_imag[1] = 0;
    967 
    968     if (cov_matrix.d != 0) {
    969       WORD32 tmp_r, temp_real, modulus_d;
    970       WORD32 tmp_i, temp_imag;
    971       WORD16 inverse_d;
    972       WORD32 norm_d;
    973 
    974       norm_d = ixheaacd_norm32(cov_matrix.d);
    975 
    976       inverse_d =
    977           (WORD16)(*ixheaacd_fix_div)(0x40000000, (cov_matrix.d << norm_d));
    978 
    979       modulus_d = ixheaacd_abs32_sat(cov_matrix.d);
    980       tmp_r =
    981           (ixheaacd_sub32(
    982               ixheaacd_sub32(
    983                   ixheaacd_mult32(cov_matrix.phi_01, cov_matrix.phi_12),
    984                   ixheaacd_mult32(cov_matrix.phi_01_im, cov_matrix.phi_12_im)),
    985               ixheaacd_mult32(cov_matrix.phi_02, cov_matrix.phi_11))) >>
    986           (LPC_SCALE_FACTOR - 1);
    987       tmp_i = (ixheaacd_sub32_sat(
    988                   ixheaacd_add32_sat(
    989                       ixheaacd_mult32(cov_matrix.phi_01_im, cov_matrix.phi_12),
    990                       ixheaacd_mult32(cov_matrix.phi_01, cov_matrix.phi_12_im)),
    991                   ixheaacd_mult32(cov_matrix.phi_02_im, cov_matrix.phi_11))) >>
    992               (LPC_SCALE_FACTOR - 1);
    993       temp_imag = ixheaacd_abs32(tmp_i);
    994       temp_real = ixheaacd_abs32(tmp_r);
    995 
    996       if (temp_real >= modulus_d) {
    997         reset_lpc_coeff = 1;
    998       } else {
    999         alpha_real[1] = (WORD16)(
   1000             (ixheaacd_mult32x16in32(tmp_r, inverse_d) << (norm_d + 1)) >> 15);
   1001       }
   1002 
   1003       if (temp_imag >= modulus_d) {
   1004         reset_lpc_coeff = 1;
   1005       } else {
   1006         alpha_imag[1] = (WORD16)(
   1007             (ixheaacd_mult32x16in32(tmp_i, inverse_d) << (norm_d + 1)) >> 15);
   1008       }
   1009     }
   1010 
   1011     alpha_real[0] = 0;
   1012     alpha_imag[0] = 0;
   1013 
   1014     if (cov_matrix.phi_11 != 0) {
   1015       WORD32 tmp_r, temp_real;
   1016       WORD32 tmp_i = 0, temp_imag = 0;
   1017       WORD16 inverse_r11;
   1018       WORD32 norm_r11;
   1019 
   1020       norm_r11 = ixheaacd_norm32(cov_matrix.phi_11);
   1021 
   1022       inverse_r11 = (WORD16)(*ixheaacd_fix_div)(
   1023           0x40000000, (cov_matrix.phi_11 << norm_r11));
   1024 
   1025       tmp_r = ixheaacd_add32(
   1026           ixheaacd_add32(
   1027               (cov_matrix.phi_01 >> (LPC_SCALE_FACTOR + 1)),
   1028               ixheaacd_mult32x16in32(cov_matrix.phi_12, alpha_real[1])),
   1029           ixheaacd_mult32x16in32(cov_matrix.phi_12_im, alpha_imag[1]));
   1030       tmp_i = ixheaacd_sub32(
   1031           ixheaacd_add32(
   1032               (cov_matrix.phi_01_im >> (LPC_SCALE_FACTOR + 1)),
   1033               ixheaacd_mult32x16in32(cov_matrix.phi_12, alpha_imag[1])),
   1034           ixheaacd_mult32x16in32(cov_matrix.phi_12_im, alpha_real[1]));
   1035 
   1036       tmp_r = tmp_r << 1;
   1037       tmp_i = tmp_i << 1;
   1038 
   1039       temp_imag = ixheaacd_abs32(tmp_i);
   1040       temp_real = ixheaacd_abs32(tmp_r);
   1041 
   1042       if (temp_real >= cov_matrix.phi_11) {
   1043         reset_lpc_coeff = 1;
   1044       } else {
   1045         alpha_real[0] = (WORD16)(
   1046             (ixheaacd_mult32x16in32(ixheaacd_sub32_sat(0, tmp_r), inverse_r11)
   1047              << (norm_r11 + 1)) >>
   1048             15);
   1049       }
   1050 
   1051       if (temp_imag >= cov_matrix.phi_11) {
   1052         reset_lpc_coeff = 1;
   1053       } else {
   1054         alpha_imag[0] = (WORD16)(
   1055             (ixheaacd_mult32x16in32(ixheaacd_sub32_sat(0, tmp_i), inverse_r11)
   1056              << (norm_r11 + 1)) >>
   1057             15);
   1058       }
   1059     }
   1060 
   1061     if (ixheaacd_add32((alpha_real[0] * alpha_real[0]),
   1062                        (alpha_imag[0] * alpha_imag[0])) >= 0x40000000L) {
   1063       reset_lpc_coeff = 1;
   1064     }
   1065 
   1066     if (ixheaacd_add32((alpha_real[1] * alpha_real[1]),
   1067                        (alpha_imag[1] * alpha_imag[1])) >= 0x40000000L) {
   1068       reset_lpc_coeff = 1;
   1069     }
   1070 
   1071     if (reset_lpc_coeff) {
   1072       alpha_real[0] = 0;
   1073       alpha_real[1] = 0;
   1074       alpha_imag[0] = 0;
   1075       alpha_imag[1] = 0;
   1076     }
   1077 
   1078     patch = 0;
   1079 
   1080     while (patch < num_patches) {
   1081       high_band = (low_band + patch_param[patch].dst_end_band);
   1082 
   1083       if ((low_band < patch_param[patch].src_start_band) ||
   1084           (low_band >= patch_param[patch].src_end_band)) {
   1085         patch++;
   1086         continue;
   1087       }
   1088 
   1089       if (high_band < max_qmf_subband) {
   1090         patch++;
   1091         continue;
   1092       }
   1093 
   1094       while (high_band >=
   1095              hf_generator->pstr_settings->bw_borders[bw_index[patch]]) {
   1096         bw_index[patch] = (bw_index[patch] + 1);
   1097       }
   1098 
   1099       bw = ixheaacd_extract16h(bw_array[bw_index[patch]]);
   1100       a0r = ixheaacd_mult16_shl_sat(bw, alpha_real[0]);
   1101       a0i = ixheaacd_mult16_shl_sat(bw, alpha_imag[0]);
   1102       bw = ixheaacd_mult16_shl_sat(bw, bw);
   1103       a1r = ixheaacd_mult16_shl_sat(bw, alpha_real[1]);
   1104       a1i = ixheaacd_mult16_shl_sat(bw, alpha_imag[1]);
   1105 
   1106       if (bw > 0) {
   1107         ixheaacd_filterstep3(a0r, a0i, a1r, a1i, start_idx, stop_idx, low_band,
   1108                              high_band, sub_sig_x);
   1109 
   1110       } else {
   1111         WORD32 *p_src = sub_sig_x + low_band + ((start_idx + 2) << 7);
   1112         WORD32 *p_dst = sub_sig_x + high_band + ((start_idx + 2) << 7);
   1113 
   1114         for (i = stop_idx - start_idx; i != 0; i--) {
   1115           *(p_dst) = *(p_src) >> LPC_SCALE_FACTOR;
   1116           p_src += 64;
   1117           p_dst += 64;
   1118           *(p_dst) = *(p_src) >> LPC_SCALE_FACTOR;
   1119           p_src += 64;
   1120           p_dst += 64;
   1121         }
   1122       }
   1123 
   1124       patch++;
   1125     }
   1126   }
   1127 
   1128   memcpy(hf_generator->bw_array_prev, bw_array, sizeof(WORD32) * num_if_bands);
   1129 
   1130   scale_factor->hb_scale = (WORD16)(common_scale - LPC_SCALE_FACTOR);
   1131 }
   1132