991 lines
		
	
	
		
			34 KiB
		
	
	
	
		
			C
		
	
	
	
			
		
		
	
	
			991 lines
		
	
	
		
			34 KiB
		
	
	
	
		
			C
		
	
	
	
| /******************************************************************************
 | |
|  *                                                                            *
 | |
|  * Copyright (C) 2018 The Android Open Source Project
 | |
|  *
 | |
|  * Licensed under the Apache License, Version 2.0 (the "License");
 | |
|  * you may not use this file except in compliance with the License.
 | |
|  * You may obtain a copy of the License at:
 | |
|  *
 | |
|  * http://www.apache.org/licenses/LICENSE-2.0
 | |
|  *
 | |
|  * Unless required by applicable law or agreed to in writing, software
 | |
|  * distributed under the License is distributed on an "AS IS" BASIS,
 | |
|  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | |
|  * See the License for the specific language governing permissions and
 | |
|  * limitations under the License.
 | |
|  *
 | |
|  *****************************************************************************
 | |
|  * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
 | |
| */
 | |
| #include <string.h>
 | |
| #include "ixheaacd_sbr_common.h"
 | |
| #include "ixheaacd_type_def.h"
 | |
| 
 | |
| #include "ixheaacd_constants.h"
 | |
| #include "ixheaacd_basic_ops32.h"
 | |
| #include "ixheaacd_basic_ops16.h"
 | |
| #include "ixheaacd_basic_ops40.h"
 | |
| #include "ixheaacd_basic_ops_arr.h"
 | |
| #include "ixheaacd_basic_ops.h"
 | |
| 
 | |
| #include "ixheaacd_defines.h"
 | |
| #include "ixheaacd_basic_op.h"
 | |
| #include "ixheaacd_intrinsics.h"
 | |
| #include "ixheaacd_common_rom.h"
 | |
| #include "ixheaacd_basic_funcs.h"
 | |
| #include "ixheaacd_bitbuffer.h"
 | |
| #include "ixheaacd_sbrdecsettings.h"
 | |
| #include "ixheaacd_defines.h"
 | |
| 
 | |
| #include "ixheaacd_pns.h"
 | |
| 
 | |
| #include "ixheaacd_aac_rom.h"
 | |
| #include "ixheaacd_pulsedata.h"
 | |
| 
 | |
| #include "ixheaacd_drc_data_struct.h"
 | |
| #include "ixheaacd_lt_predict.h"
 | |
| #include "ixheaacd_channelinfo.h"
 | |
| #include "ixheaacd_drc_dec.h"
 | |
| 
 | |
| #include "ixheaacd_sbrdecoder.h"
 | |
| #include "ixheaacd_sbr_scale.h"
 | |
| #include "ixheaacd_lpp_tran.h"
 | |
| #include "ixheaacd_env_extr_part.h"
 | |
| #include "ixheaacd_sbr_rom.h"
 | |
| 
 | |
| #include "ixheaacd_hybrid.h"
 | |
| #include "ixheaacd_ps_dec.h"
 | |
| 
 | |
| #include "ixheaacd_env_extr.h"
 | |
| 
 | |
| #include "ixheaacd_ps_dec.h"
 | |
| 
 | |
| #include "ixheaacd_qmf_dec.h"
 | |
| #include "ixheaacd_env_calc.h"
 | |
| #include "ixheaacd_sbr_const.h"
 | |
| 
 | |
| #include "ixheaacd_pvc_dec.h"
 | |
| #include "ixheaacd_sbr_dec.h"
 | |
| #include "ixheaacd_function_selector.h"
 | |
| 
 | |
| static PLATFORM_INLINE WORD16 ixheaacd_shl16_saturate(WORD16 op1,
 | |
|                                                       WORD16 shift) {
 | |
|   WORD16 var_out;
 | |
|   WORD32 temp;
 | |
| 
 | |
|   temp = (WORD32)(op1 << shift);
 | |
|   var_out = ixheaacd_sat16(temp);
 | |
|   return (var_out);
 | |
| }
 | |
| 
 | |
| static PLATFORM_INLINE VOID ixheaacd_shl16_arr_saturate(WORD16 *word16_arr,
 | |
|                                                         WORD16 shift, WORD n) {
 | |
|   WORD i;
 | |
| 
 | |
|   for (i = n - 1; i >= 0; i--) {
 | |
|     *word16_arr = ixheaacd_shl16_saturate(*word16_arr, shift);
 | |
|     word16_arr++;
 | |
|   }
 | |
| 
 | |
|   return;
 | |
| }
 | |
| 
 | |
| VOID ixheaacd_scale_short_vec_left(WORD16 *word16_arr, WORD32 n, WORD16 shift) {
 | |
|   ixheaacd_shl16_arr_saturate(word16_arr, shift, n);
 | |
| }
 | |
| 
 | |
| VOID ixheaacd_scale_int_vec_left(WORD32 *word32_arr, WORD32 n, WORD16 shift) {
 | |
|   ixheaacd_shl32_arr_sat(word32_arr, shift, n);
 | |
| }
 | |
| 
 | |
| VOID ixheaacd_scale_int_vec_right(WORD32 *word32_arr, WORD32 n, WORD16 shift) {
 | |
|   ixheaacd_shr32_arr(word32_arr, shift, n);
 | |
| }
 | |
| 
 | |
| VOID ixheaacd_scale_short_vec_right(WORD16 *word16_arr, WORD32 n,
 | |
|                                     WORD16 shift) {
 | |
|   ixheaacd_shr16_arr(word16_arr, shift, n);
 | |
| }
 | |
| 
 | |
| WORD32 ixheaacd_calc_max(WORD16 *array, WORD32 size) {
 | |
|   WORD n;
 | |
|   WORD32 max_val = 0;
 | |
|   WORD16 temp1, temp2;
 | |
| 
 | |
|   for (n = size; n != 0; n--) {
 | |
|     temp1 = *array++;
 | |
|     temp2 = *array++;
 | |
| 
 | |
|     max_val = max_val | ixheaacd_abs32_nrm(temp1);
 | |
|     max_val = max_val | ixheaacd_abs32_nrm(temp2);
 | |
|   }
 | |
| 
 | |
|   return max_val;
 | |
| }
 | |
| 
 | |
| static WORD ixheaacd_get_ps_scale(ia_ps_dec_struct *ptr_ps_dec) {
 | |
|   WORD i, m, n, len;
 | |
|   WORD32 max_val = 0;
 | |
|   WORD16 *ptr_re;
 | |
|   WORD32 *ptr_re_temp, *ptr_im;
 | |
| 
 | |
|   for (m = 0; m < 2; m++) {
 | |
|     ptr_re = &ptr_ps_dec->delay_buf_qmf_ap_re_im[m][2 * 3];
 | |
|     max_val |=
 | |
|         ixheaacd_calc_max(ptr_re, NUM_OF_QUAD_MIRROR_FILTER_ALL_PASS_CHNLS);
 | |
|   }
 | |
| 
 | |
|   ptr_re = (WORD16 *)ptr_ps_dec->delay_buf_qmf_ld_re_im;
 | |
| 
 | |
|   max_val |= ixheaacd_calc_max(ptr_re, HIGH_DEL * SMALL_DEL_STRT);
 | |
| 
 | |
|   ptr_re = (WORD16 *)ptr_ps_dec->delay_buf_qmf_sd_re_im;
 | |
| 
 | |
|   max_val |= ixheaacd_calc_max(
 | |
|       ptr_re, (SMALL_DEL *
 | |
|                (NUM_OF_QUAD_MIRROR_FILTER_ICC_CHNLS -
 | |
|                 (NUM_OF_QUAD_MIRROR_FILTER_ALL_PASS_CHNLS + SMALL_DEL_STRT))));
 | |
| 
 | |
|   ptr_re = (WORD16 *)ptr_ps_dec->delay_buf_qmf_sub_re_im;
 | |
| 
 | |
|   max_val |= ixheaacd_calc_max(ptr_re, 16 * DEL_ALL_PASS);
 | |
| 
 | |
|   for (i = 0; i < NUM_SER_AP_LINKS; i++) {
 | |
|     for (m = 0; m < ptr_ps_dec->delay_sample_ser[i]; m++) {
 | |
|       ptr_re = &ptr_ps_dec->delay_buf_qmf_ser_re_im[m][i][2 * 3];
 | |
| 
 | |
|       max_val |=
 | |
|           ixheaacd_calc_max(ptr_re, NUM_OF_QUAD_MIRROR_FILTER_ALL_PASS_CHNLS);
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   ptr_re = (WORD16 *)ptr_ps_dec->delay_buf_qmf_sub_ser_re_im;
 | |
|   max_val |= ixheaacd_calc_max(ptr_re, NUM_SER_AP_LINKS * 5 * 16);
 | |
| 
 | |
|   max_val = max_val << 16;
 | |
| 
 | |
|   len = ptr_ps_dec->str_hybrid.ptr_qmf_buf;
 | |
| 
 | |
|   for (i = 0; i < NO_QMF_CHANNELS_IN_HYBRID; i++) {
 | |
|     ptr_re_temp = &ptr_ps_dec->str_hybrid.ptr_qmf_buf_re[i][0];
 | |
|     ptr_im = &ptr_ps_dec->str_hybrid.ptr_qmf_buf_im[i][0];
 | |
| 
 | |
|     for (n = len; n != 0; n--) {
 | |
|       WORD32 temp3 = *ptr_re_temp++;
 | |
|       WORD32 temp4 = *ptr_im++;
 | |
| 
 | |
|       max_val = max_val | ixheaacd_abs32_nrm(temp3);
 | |
|       max_val = max_val | ixheaacd_abs32_nrm(temp4);
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   return ixheaacd_pnorm32(max_val);
 | |
| }
 | |
| 
 | |
| VOID ixheaacd_init_ps_scale(ia_ps_dec_struct *ptr_ps_dec,
 | |
|                             ia_sbr_scale_fact_struct *sbr_scale_factor)
 | |
| 
 | |
| {
 | |
|   WORD32 reserve, change;
 | |
|   WORD16 temp;
 | |
| 
 | |
|   reserve = ixheaacd_get_ps_scale(ptr_ps_dec);
 | |
| 
 | |
|   ptr_ps_dec->delay_buffer_scale = (ptr_ps_dec->delay_buffer_scale + reserve);
 | |
|   temp =
 | |
|       ixheaacd_min16(sbr_scale_factor->lb_scale, sbr_scale_factor->ov_lb_scale);
 | |
|   temp = ixheaacd_min16(temp, sbr_scale_factor->hb_scale);
 | |
|   temp = ixheaacd_min16(temp, ptr_ps_dec->delay_buffer_scale);
 | |
|   sbr_scale_factor->ps_scale = (temp - 1);
 | |
| 
 | |
|   change = (sbr_scale_factor->ps_scale - ptr_ps_dec->delay_buffer_scale);
 | |
|   change = (change + reserve);
 | |
| 
 | |
|   ixheaacd_scale_ps_states(ptr_ps_dec, (WORD16)change);
 | |
| 
 | |
|   ptr_ps_dec->delay_buffer_scale = sbr_scale_factor->ps_scale;
 | |
| }
 | |
| 
 | |
| WORD32 ixheaacd_divide16_pos_dec(WORD32 op1, WORD32 op2) {
 | |
|   UWORD32 v;
 | |
|   UWORD32 u;
 | |
|   WORD k, nrm;
 | |
| 
 | |
|   nrm = ixheaacd_norm32(op2);
 | |
|   u = (op1 << nrm);
 | |
|   v = (op2 << nrm);
 | |
|   u = (u & 0xffff0000);
 | |
|   v = (v & 0xffff0000);
 | |
| 
 | |
|   if (u != 0) {
 | |
|     for (k = 16; k > 0; k--) {
 | |
|       if (u >= (UWORD32)v) {
 | |
|         u = ((u - v) << 1) + 1;
 | |
|       } else {
 | |
|         u = (u << 1);
 | |
|       }
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   return (u);
 | |
| }
 | |
| 
 | |
| VOID ixheaacd_decorr_filter1_dec(ia_ps_dec_struct *ptr_ps_dec,
 | |
|                                  ia_ps_tables_struct *ps_tables_ptr,
 | |
|                                  WORD16 *transient_ratio) {
 | |
|   WORD sb;
 | |
|   WORD m;
 | |
| 
 | |
|   WORD16 delay_buf_idx;
 | |
|   WORD16 *p_delay_buf_sub_re_im;
 | |
|   WORD16 *p_frac_delay_phase_fac_ser_re_im, *p_frac_delay_phase_fac_ser_re_im1;
 | |
| 
 | |
|   const WORD16 *p_frac_delay_phase_fac_re_im;
 | |
|   REVERB_BUFFERS_CH_RI *p_delay_buf_ser_sub_re_im;
 | |
| 
 | |
|   WORD32 *p_left_real;
 | |
|   WORD32 *p_left_imag;
 | |
|   WORD32 *p_right_real;
 | |
|   WORD32 *p_right_imag;
 | |
| 
 | |
|   p_frac_delay_phase_fac_re_im =
 | |
|       &ps_tables_ptr->frac_delay_phase_fac_qmf_sub_re_im[0];
 | |
|   p_delay_buf_ser_sub_re_im = &ptr_ps_dec->delay_buf_qmf_sub_ser_re_im;
 | |
|   p_frac_delay_phase_fac_ser_re_im =
 | |
|       &ps_tables_ptr->frac_delay_phase_fac_qmf_sub_ser_re_im[0][0];
 | |
| 
 | |
|   p_left_real = ptr_ps_dec->ptr_hyb_left_re;
 | |
|   p_left_imag = ptr_ps_dec->ptr_hyb_left_im;
 | |
|   p_right_real = ptr_ps_dec->ptr_hyb_right_re;
 | |
|   p_right_imag = ptr_ps_dec->ptr_hyb_right_im;
 | |
| 
 | |
|   delay_buf_idx = ptr_ps_dec->delay_buf_idx;
 | |
|   p_delay_buf_sub_re_im =
 | |
|       &ptr_ps_dec->delay_buf_qmf_sub_re_im[delay_buf_idx][0];
 | |
|   for (sb = 0; sb < SUBQMF_GROUPS; sb++) {
 | |
|     WORD16 real_tmp, imag_tmp, real_tmp0, imag_tmp0, real_in, imag_in, bin;
 | |
| 
 | |
|     real_tmp0 = p_delay_buf_sub_re_im[0];
 | |
|     imag_tmp0 = p_delay_buf_sub_re_im[1];
 | |
| 
 | |
|     real_in = (WORD16)(
 | |
|         ixheaacd_sub32_sat(
 | |
|             ixheaacd_mult16x16in32(real_tmp0, p_frac_delay_phase_fac_re_im[0]),
 | |
|             ixheaacd_mult16x16in32(imag_tmp0,
 | |
|                                    p_frac_delay_phase_fac_re_im[1])) >>
 | |
|         15);
 | |
|     imag_in = (WORD16)(
 | |
|         ixheaacd_add32_sat(
 | |
|             ixheaacd_mult16x16in32(real_tmp0, p_frac_delay_phase_fac_re_im[1]),
 | |
|             ixheaacd_mult16x16in32(imag_tmp0,
 | |
|                                    p_frac_delay_phase_fac_re_im[0])) >>
 | |
|         15);
 | |
|     *p_delay_buf_sub_re_im++ = ixheaacd_round16(p_left_real[sb]);
 | |
|     *p_delay_buf_sub_re_im++ = ixheaacd_round16(p_left_imag[sb]);
 | |
|     p_frac_delay_phase_fac_re_im += 2;
 | |
| 
 | |
|     p_frac_delay_phase_fac_ser_re_im1 = p_frac_delay_phase_fac_ser_re_im;
 | |
|     p_frac_delay_phase_fac_ser_re_im += 2;
 | |
| 
 | |
|     for (m = 0; m < NUM_SER_AP_LINKS; m++) {
 | |
|       WORD16 decay;
 | |
|       WORD16 delay_buf_idx_ser;
 | |
|       delay_buf_idx_ser = ptr_ps_dec->delay_buf_idx_ser[m];
 | |
|       real_tmp0 = (*p_delay_buf_ser_sub_re_im)[delay_buf_idx_ser][m][2 * sb];
 | |
|       imag_tmp0 =
 | |
|           (*p_delay_buf_ser_sub_re_im)[delay_buf_idx_ser][m][2 * sb + 1];
 | |
| 
 | |
|       real_tmp =
 | |
|           (WORD16)(ixheaacd_sub32_sat(
 | |
|                        ixheaacd_mult16x16in32(
 | |
|                            real_tmp0, p_frac_delay_phase_fac_ser_re_im1[0]),
 | |
|                        ixheaacd_mult16x16in32(
 | |
|                            imag_tmp0, p_frac_delay_phase_fac_ser_re_im1[1])) >>
 | |
|                    15);
 | |
|       imag_tmp =
 | |
|           (WORD16)(ixheaacd_add32_sat(
 | |
|                        ixheaacd_mult16x16in32(
 | |
|                            real_tmp0, p_frac_delay_phase_fac_ser_re_im1[1]),
 | |
|                        ixheaacd_mult16x16in32(
 | |
|                            imag_tmp0, p_frac_delay_phase_fac_ser_re_im1[0])) >>
 | |
|                    15);
 | |
| 
 | |
|       decay = ps_tables_ptr->rev_link_decay_ser[m];
 | |
| 
 | |
|       real_tmp = ixheaacd_sub16(real_tmp, ixheaacd_mult16_shl(real_in, decay));
 | |
|       imag_tmp = ixheaacd_sub16(imag_tmp, ixheaacd_mult16_shl(imag_in, decay));
 | |
| 
 | |
|       (*p_delay_buf_ser_sub_re_im)[delay_buf_idx_ser][m][sb * 2] =
 | |
|           ixheaacd_add16(real_in, ixheaacd_mult16_shl(real_tmp, decay));
 | |
|       (*p_delay_buf_ser_sub_re_im)[delay_buf_idx_ser][m][sb * 2 + 1] =
 | |
|           ixheaacd_add16(imag_in, ixheaacd_mult16_shl(imag_tmp, decay));
 | |
| 
 | |
|       real_in = real_tmp;
 | |
|       imag_in = imag_tmp;
 | |
|       p_frac_delay_phase_fac_ser_re_im1 += 32;
 | |
|     }
 | |
| 
 | |
|     bin = ps_tables_ptr->hybrid_to_bin[sb];
 | |
|     p_right_real[sb] =
 | |
|         ixheaacd_mult16x16in32_shl(real_in, transient_ratio[bin]);
 | |
|     p_right_imag[sb] =
 | |
|         ixheaacd_mult16x16in32_shl(imag_in, transient_ratio[bin]);
 | |
|   }
 | |
| }
 | |
| 
 | |
| VOID ixheaacd_decorr_filter2_dec(
 | |
|     ia_ps_dec_struct *ptr_ps_dec, WORD32 *p_buf_left_real,
 | |
|     WORD32 *p_buf_left_imag, WORD32 *p_buf_right_real, WORD32 *p_buf_right_imag,
 | |
|     ia_ps_tables_struct *ps_tables_ptr, WORD16 *transient_ratio) {
 | |
|   WORD sb, di, sb_delay;
 | |
|   WORD m, bin;
 | |
|   WORD32 *p_left_real;
 | |
|   WORD32 *p_left_imag;
 | |
|   WORD32 *p_right_real;
 | |
|   WORD32 *p_right_imag;
 | |
|   WORD16 delay_buf_idx;
 | |
|   REVERB_BUFFERS_RI *p_delay_buf_ser_re_im;
 | |
|   WORD16 *p_delay_buf_ap_re_im;
 | |
|   const WORD16 *p_frac_delay_phase_fac_re_im;
 | |
|   WORD16 *p_frac_delay_phase_fac_ser_ap_re_im,
 | |
|       *p_frac_delay_phase_fac_ser_ap_re_im_temp;
 | |
| 
 | |
|   p_left_real = p_buf_left_real;
 | |
|   p_left_imag = p_buf_left_imag;
 | |
|   p_right_real = p_buf_right_real;
 | |
|   p_right_imag = p_buf_right_imag;
 | |
| 
 | |
|   p_delay_buf_ser_re_im = &ptr_ps_dec->delay_buf_qmf_ser_re_im;
 | |
|   p_frac_delay_phase_fac_re_im = ps_tables_ptr->frac_delay_phase_fac_qmf_re_im;
 | |
|   p_frac_delay_phase_fac_ser_ap_re_im =
 | |
|       &ps_tables_ptr->frac_delay_phase_fac_qmf_ser_re_im[0][0];
 | |
| 
 | |
|   delay_buf_idx = ptr_ps_dec->delay_buf_idx;
 | |
| 
 | |
|   p_delay_buf_ap_re_im = &ptr_ps_dec->delay_buf_qmf_ap_re_im[delay_buf_idx][0];
 | |
|   p_frac_delay_phase_fac_re_im += 6;
 | |
|   p_frac_delay_phase_fac_ser_ap_re_im += 6;
 | |
|   p_delay_buf_ap_re_im += 6;
 | |
| 
 | |
|   for (sb = 3, di = 9; sb < 23; sb++) {
 | |
|     WORD16 real_tmp, imag_tmp, real_tmp0, imag_tmp0, real_in, imag_in;
 | |
| 
 | |
|     sb_delay = sb;
 | |
| 
 | |
|     real_tmp0 = p_delay_buf_ap_re_im[0];
 | |
|     imag_tmp0 = p_delay_buf_ap_re_im[1];
 | |
| 
 | |
|     real_in = (WORD16)(
 | |
|         ixheaacd_sub32_sat(
 | |
|             ixheaacd_mult16x16in32(real_tmp0, p_frac_delay_phase_fac_re_im[0]),
 | |
|             ixheaacd_mult16x16in32(imag_tmp0,
 | |
|                                    p_frac_delay_phase_fac_re_im[1])) >>
 | |
|         15);
 | |
|     imag_in = (WORD16)(
 | |
|         ixheaacd_add32_sat(
 | |
|             ixheaacd_mult16x16in32(real_tmp0, p_frac_delay_phase_fac_re_im[1]),
 | |
|             ixheaacd_mult16x16in32(imag_tmp0,
 | |
|                                    p_frac_delay_phase_fac_re_im[0])) >>
 | |
|         15);
 | |
| 
 | |
|     *p_delay_buf_ap_re_im++ = ixheaacd_round16(p_left_real[sb]);
 | |
|     *p_delay_buf_ap_re_im++ = ixheaacd_round16(p_left_imag[sb]);
 | |
| 
 | |
|     p_frac_delay_phase_fac_re_im += 2;
 | |
| 
 | |
|     p_frac_delay_phase_fac_ser_ap_re_im_temp =
 | |
|         p_frac_delay_phase_fac_ser_ap_re_im;
 | |
|     p_frac_delay_phase_fac_ser_ap_re_im += 2;
 | |
| 
 | |
|     for (m = 0; m < NUM_SER_AP_LINKS; m++, di++) {
 | |
|       WORD16 decay;
 | |
|       WORD16 delay_buf_idx_ser;
 | |
|       delay_buf_idx_ser = ptr_ps_dec->delay_buf_idx_ser[m];
 | |
| 
 | |
|       real_tmp0 = (*p_delay_buf_ser_re_im)[delay_buf_idx_ser][m][sb_delay * 2];
 | |
|       imag_tmp0 =
 | |
|           (*p_delay_buf_ser_re_im)[delay_buf_idx_ser][m][sb_delay * 2 + 1];
 | |
| 
 | |
|       real_tmp = (WORD16)(
 | |
|           ixheaacd_sub32_sat(
 | |
|               ixheaacd_mult16x16in32(
 | |
|                   real_tmp0, p_frac_delay_phase_fac_ser_ap_re_im_temp[0]),
 | |
|               ixheaacd_mult16x16in32(
 | |
|                   imag_tmp0, p_frac_delay_phase_fac_ser_ap_re_im_temp[1])) >>
 | |
|           15);
 | |
|       imag_tmp = (WORD16)(
 | |
|           ixheaacd_add32_sat(
 | |
|               ixheaacd_mult16x16in32(
 | |
|                   real_tmp0, p_frac_delay_phase_fac_ser_ap_re_im_temp[1]),
 | |
|               ixheaacd_mult16x16in32(
 | |
|                   imag_tmp0, p_frac_delay_phase_fac_ser_ap_re_im_temp[0])) >>
 | |
|           15);
 | |
| 
 | |
|       decay = ps_tables_ptr->decay_scale_factor[di];
 | |
| 
 | |
|       real_tmp = ixheaacd_sub16(real_tmp, ixheaacd_mult16_shl(real_in, decay));
 | |
|       imag_tmp = ixheaacd_sub16(imag_tmp, ixheaacd_mult16_shl(imag_in, decay));
 | |
| 
 | |
|       (*p_delay_buf_ser_re_im)[delay_buf_idx_ser][m][sb_delay * 2] =
 | |
|           ixheaacd_add16(real_in, ixheaacd_mult16_shl(real_tmp, decay));
 | |
|       (*p_delay_buf_ser_re_im)[delay_buf_idx_ser][m][sb_delay * 2 + 1] =
 | |
|           ixheaacd_add16(imag_in, ixheaacd_mult16_shl(imag_tmp, decay));
 | |
| 
 | |
|       real_in = real_tmp;
 | |
|       imag_in = imag_tmp;
 | |
|       p_frac_delay_phase_fac_ser_ap_re_im_temp += 64;
 | |
|     }
 | |
| 
 | |
|     bin = ps_tables_ptr->delay_to_bin[sb_delay];
 | |
|     p_right_real[sb] =
 | |
|         ixheaacd_mult16x16in32_shl(real_in, transient_ratio[bin]);
 | |
|     p_right_imag[sb] =
 | |
|         ixheaacd_mult16x16in32_shl(imag_in, transient_ratio[bin]);
 | |
|   }
 | |
| }
 | |
| 
 | |
| VOID ixheaacd_decorrelation_dec(ia_ps_dec_struct *ptr_ps_dec,
 | |
|                                 WORD32 *p_buf_left_real,
 | |
|                                 WORD32 *p_buf_left_imag,
 | |
|                                 WORD32 *p_buf_right_real,
 | |
|                                 WORD32 *p_buf_right_imag,
 | |
|                                 ia_ps_tables_struct *ps_tables_ptr) {
 | |
|   WORD sb;
 | |
| 
 | |
|   WORD gr, bin, sband, maxsband;
 | |
| 
 | |
|   WORD32 peak_diff, nrg;
 | |
|   WORD32 power_buf[NUM_OF_BINS];
 | |
|   WORD16 transient_ratio[NUM_OF_BINS + 1];
 | |
| 
 | |
|   WORD32 *p_left_real;
 | |
|   WORD32 *p_left_imag;
 | |
|   WORD32 *p_right_real;
 | |
|   WORD32 *p_right_imag;
 | |
| 
 | |
|   WORD16 *p_delay_buf_re_im_ld;
 | |
|   WORD16 *p_delay_buf_re_im_sd;
 | |
| 
 | |
|   WORD usb = ptr_ps_dec->usb;
 | |
|   WORD16 delay_buf_idx;
 | |
| 
 | |
|   p_left_real = ptr_ps_dec->ptr_hyb_left_re;
 | |
|   p_left_imag = ptr_ps_dec->ptr_hyb_left_im;
 | |
|   p_right_real = ptr_ps_dec->ptr_hyb_right_re;
 | |
|   p_right_imag = ptr_ps_dec->ptr_hyb_right_im;
 | |
| 
 | |
|   {
 | |
|     WORD32 re0, im0, re1, im1;
 | |
| 
 | |
|     re0 = (p_left_real[0]);
 | |
|     im0 = (p_left_imag[0]);
 | |
|     re1 = (p_left_real[5]);
 | |
|     im1 = (p_left_imag[5]);
 | |
| 
 | |
|     power_buf[0] = ixheaacd_mult32x16in32(re0, (WORD16)(re0 >> 16));
 | |
|     power_buf[0] = ixheaacd_add32_sat(
 | |
|         power_buf[0], ixheaacd_mult32x16in32(im0, (WORD16)(im0 >> 16)));
 | |
|     power_buf[0] = ixheaacd_add32_sat(
 | |
|         power_buf[0], ixheaacd_mult32x16in32(re1, (WORD16)(re1 >> 16)));
 | |
|     power_buf[0] = ixheaacd_add32_sat(
 | |
|         power_buf[0], ixheaacd_mult32x16in32(im1, (WORD16)(im1 >> 16)));
 | |
| 
 | |
|     re0 = (p_left_real[4]);
 | |
|     im0 = (p_left_imag[4]);
 | |
|     re1 = (p_left_real[1]);
 | |
|     im1 = (p_left_imag[1]);
 | |
| 
 | |
|     power_buf[1] = ixheaacd_mult32x16in32(re0, (WORD16)(re0 >> 16));
 | |
|     power_buf[1] = ixheaacd_add32_sat(
 | |
|         power_buf[1], ixheaacd_mult32x16in32(im0, (WORD16)(im0 >> 16)));
 | |
|     power_buf[1] = ixheaacd_add32_sat(
 | |
|         power_buf[1], ixheaacd_mult32x16in32(re1, (WORD16)(re1 >> 16)));
 | |
|     power_buf[1] = ixheaacd_add32_sat(
 | |
|         power_buf[1], ixheaacd_mult32x16in32(im1, (WORD16)(im1 >> 16)));
 | |
|   }
 | |
| 
 | |
|   bin = 4 - 2;
 | |
|   for (gr = 4; gr < SUBQMF_GROUPS; gr++) {
 | |
|     WORD32 re, im;
 | |
|     sb = ps_tables_ptr->borders_group[gr];
 | |
|     re = (p_left_real[sb]);
 | |
|     im = (p_left_imag[sb]);
 | |
|     power_buf[bin] = ixheaacd_mult32x16in32(re, (WORD16)(re >> 16));
 | |
|     power_buf[bin] = ixheaacd_add32_sat(
 | |
|         power_buf[bin], ixheaacd_mult32x16in32(im, (WORD16)(im >> 16)));
 | |
|     bin++;
 | |
|   }
 | |
| 
 | |
|   p_left_real = p_buf_left_real;
 | |
|   p_left_imag = p_buf_left_imag;
 | |
| 
 | |
|   bin = NO_QMF_CHANNELS_IN_HYBRID + 5;
 | |
|   for (sband = NO_QMF_CHANNELS_IN_HYBRID; sband < NO_QMF_CHANNELS_IN_HYBRID + 6;
 | |
|        sband++) {
 | |
|     WORD32 re = (p_left_real[sband]);
 | |
|     WORD32 im = (p_left_imag[sband]);
 | |
|     power_buf[bin] = ixheaacd_mult32x16in32(re, (WORD16)(re >> 16));
 | |
|     power_buf[bin] = ixheaacd_add32_sat(
 | |
|         power_buf[bin], ixheaacd_mult32x16in32(im, (WORD16)(im >> 16)));
 | |
|     bin++;
 | |
|   }
 | |
| 
 | |
|   bin = 16 - 2;
 | |
|   for (gr = 16; gr < NO_IID_GROUPS; gr++) {
 | |
|     WORD32 accu = 0, tmp;
 | |
|     WORD32 re, im;
 | |
| 
 | |
|     maxsband = ixheaacd_min32(usb, ps_tables_ptr->borders_group[gr + 1]);
 | |
| 
 | |
|     for (sband = ps_tables_ptr->borders_group[gr]; sband < maxsband; sband++) {
 | |
|       re = (p_left_real[sband]);
 | |
|       im = (p_left_imag[sband]);
 | |
| 
 | |
|       tmp = ixheaacd_mult32x16in32(re, (WORD16)(re >> 16));
 | |
|       tmp = ixheaacd_add32_sat(tmp,
 | |
|                                ixheaacd_mult32x16in32(im, (WORD16)(im >> 16)));
 | |
|       tmp = (tmp >> ps_tables_ptr->group_shift[gr - (SUBQMF_GROUPS + 6)]);
 | |
| 
 | |
|       accu = ixheaacd_add32_sat(accu, tmp);
 | |
|     }
 | |
|     power_buf[bin] = accu;
 | |
|     bin++;
 | |
|   }
 | |
| 
 | |
|   p_left_real = ptr_ps_dec->ptr_hyb_left_re;
 | |
|   p_left_imag = ptr_ps_dec->ptr_hyb_left_im;
 | |
| 
 | |
|   for (bin = 0; bin < NUM_OF_BINS; bin++) {
 | |
|     power_buf[bin] = ixheaacd_shl32(power_buf[bin], 1);
 | |
| 
 | |
|     power_buf[bin] = ixheaacd_max32(0, power_buf[bin]);
 | |
| 
 | |
|     ptr_ps_dec->peak_decay_diff[bin] = ixheaacd_mult32x16in32_shl(
 | |
|         ptr_ps_dec->peak_decay_diff[bin], PEAK_DECAYING_FACT);
 | |
| 
 | |
|     ptr_ps_dec->peak_decay_diff[bin] =
 | |
|         ixheaacd_max32(ptr_ps_dec->peak_decay_diff[bin], power_buf[bin]);
 | |
| 
 | |
|     peak_diff = ixheaacd_add32_sat(
 | |
|         ixheaacd_mult32x16in32_shl(ptr_ps_dec->peak_decay_diff_prev[bin],
 | |
|                                    0x6000),
 | |
|         ((ixheaacd_sub32_sat(ptr_ps_dec->peak_decay_diff[bin],
 | |
|                              power_buf[bin]) >>
 | |
|           2)));
 | |
| 
 | |
|     ptr_ps_dec->peak_decay_diff_prev[bin] = peak_diff;
 | |
| 
 | |
|     nrg = ixheaacd_add32_sat(
 | |
|         ixheaacd_mult32x16in32_shl(ptr_ps_dec->energy_prev[bin], 0x6000),
 | |
|         (power_buf[bin] >> 2));
 | |
|     ptr_ps_dec->energy_prev[bin] = nrg;
 | |
| 
 | |
|     peak_diff = ixheaacd_add32_sat(peak_diff, (peak_diff >> 1));
 | |
| 
 | |
|     if (peak_diff <= nrg) {
 | |
|       transient_ratio[bin] = 0x7fff;
 | |
|     } else {
 | |
|       transient_ratio[bin] =
 | |
|           ixheaacd_extract16l((*ixheaacd_divide16_pos)(nrg, peak_diff));
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   (*ixheaacd_decorr_filter1)(ptr_ps_dec, ps_tables_ptr, transient_ratio);
 | |
| 
 | |
|   transient_ratio[20] = 0;
 | |
| 
 | |
|   (*ixheaacd_decorr_filter2)(ptr_ps_dec, p_buf_left_real, p_buf_left_imag,
 | |
|                              p_buf_right_real, p_buf_right_imag, ps_tables_ptr,
 | |
|                              transient_ratio);
 | |
| 
 | |
|   {
 | |
|     WORD16 trans_ratio = transient_ratio[18];
 | |
| 
 | |
|     p_left_real = p_buf_left_real;
 | |
|     p_left_imag = p_buf_left_imag;
 | |
|     p_right_real = p_buf_right_real;
 | |
|     p_right_imag = p_buf_right_imag;
 | |
| 
 | |
|     maxsband = ixheaacd_min32((WORD16)usb, ps_tables_ptr->borders_group[21]);
 | |
|     delay_buf_idx = ptr_ps_dec->delay_buf_idx_long;
 | |
|     p_delay_buf_re_im_ld =
 | |
|         &ptr_ps_dec->delay_buf_qmf_ld_re_im[delay_buf_idx][0];
 | |
| 
 | |
|     for (sband = ps_tables_ptr->borders_group[20]; sband < maxsband; sband++) {
 | |
|       WORD16 real_in, imag_in;
 | |
| 
 | |
|       real_in = p_delay_buf_re_im_ld[0];
 | |
|       imag_in = p_delay_buf_re_im_ld[1];
 | |
|       *p_delay_buf_re_im_ld++ = ixheaacd_round16(p_left_real[sband]);
 | |
|       *p_delay_buf_re_im_ld++ = ixheaacd_round16(p_left_imag[sband]);
 | |
| 
 | |
|       p_right_real[sband] = ixheaacd_mult16x16in32_shl(real_in, trans_ratio);
 | |
|       p_right_imag[sband] = ixheaacd_mult16x16in32_shl(imag_in, trans_ratio);
 | |
|     }
 | |
| 
 | |
|     ptr_ps_dec->delay_buf_idx_long =
 | |
|         ixheaacd_add16(ptr_ps_dec->delay_buf_idx_long, 1);
 | |
| 
 | |
|     if (ptr_ps_dec->delay_buf_idx_long >= 14) {
 | |
|       ptr_ps_dec->delay_buf_idx_long = 0;
 | |
|     }
 | |
| 
 | |
|     p_delay_buf_re_im_sd = &ptr_ps_dec->delay_buf_qmf_sd_re_im[0][0];
 | |
| 
 | |
|     trans_ratio = transient_ratio[19];
 | |
|     maxsband = ixheaacd_min32((WORD16)usb, ps_tables_ptr->borders_group[22]);
 | |
|     for (sband = ps_tables_ptr->borders_group[21]; sband < maxsband; sband++) {
 | |
|       WORD16 real_in, imag_in;
 | |
| 
 | |
|       real_in = p_delay_buf_re_im_sd[0];
 | |
|       imag_in = p_delay_buf_re_im_sd[1];
 | |
|       *p_delay_buf_re_im_sd++ = ixheaacd_round16(p_left_real[sband]);
 | |
|       *p_delay_buf_re_im_sd++ = ixheaacd_round16(p_left_imag[sband]);
 | |
| 
 | |
|       p_right_real[sband] = ixheaacd_mult16x16in32_shl(real_in, trans_ratio);
 | |
|       p_right_imag[sband] = ixheaacd_mult16x16in32_shl(imag_in, trans_ratio);
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   for (sband = usb; sband < NO_SYNTHESIS_CHANNELS; sband++) {
 | |
|     p_right_real[sband] = 0;
 | |
|     p_right_imag[sband] = 0;
 | |
|   }
 | |
| 
 | |
|   ptr_ps_dec->delay_buf_idx = (WORD16)(ptr_ps_dec->delay_buf_idx + 1);
 | |
|   if (ptr_ps_dec->delay_buf_idx >= DEL_ALL_PASS) {
 | |
|     ptr_ps_dec->delay_buf_idx = 0;
 | |
|   }
 | |
| 
 | |
|   {
 | |
|     WORD delay_m;
 | |
| 
 | |
|     for (delay_m = 0; delay_m < NUM_SER_AP_LINKS; delay_m++) {
 | |
|       ptr_ps_dec->delay_buf_idx_ser[delay_m] =
 | |
|           (ptr_ps_dec->delay_buf_idx_ser[delay_m] + 1);
 | |
|       if (ptr_ps_dec->delay_buf_idx_ser[delay_m] >=
 | |
|           ptr_ps_dec->delay_sample_ser[delay_m]) {
 | |
|         ptr_ps_dec->delay_buf_idx_ser[delay_m] = 0;
 | |
|       }
 | |
|     }
 | |
|   }
 | |
| }
 | |
| 
 | |
| static WORD16 ixheaacd_cos512(WORD phi_by_4, const WORD16 *cos_sin_lookup_tab) {
 | |
|   WORD index;
 | |
|   index = ixheaacd_round16(ixheaacd_abs32_sat(phi_by_4));
 | |
| 
 | |
|   index = (index & 0x3FF);
 | |
| 
 | |
|   if (index < 512) {
 | |
|     return cos_sin_lookup_tab[512 - index];
 | |
|   } else {
 | |
|     return (WORD16)(-(cos_sin_lookup_tab[index - 512]));
 | |
|   }
 | |
| }
 | |
| 
 | |
| static WORD16 ixheaacd_sin512(WORD phi_by_4, const WORD16 *cos_sin_lookup_tab) {
 | |
|   WORD index;
 | |
| 
 | |
|   index = ixheaacd_round16(phi_by_4);
 | |
| 
 | |
|   if (index < 0) {
 | |
|     index = (-(index)&0x3FF);
 | |
| 
 | |
|     if (index < 512) {
 | |
|       return (WORD16)(-cos_sin_lookup_tab[index]);
 | |
|     } else {
 | |
|       return (WORD16)(-cos_sin_lookup_tab[1024 - index]);
 | |
|     }
 | |
|   } else {
 | |
|     index = (index & 0x3FF);
 | |
| 
 | |
|     if (index < 512) {
 | |
|       return cos_sin_lookup_tab[index];
 | |
|     } else {
 | |
|       return cos_sin_lookup_tab[1024 - index];
 | |
|     }
 | |
|   }
 | |
| }
 | |
| 
 | |
| VOID ixheaacd_init_rot_env(ia_ps_dec_struct *ptr_ps_dec, WORD16 env, WORD16 usb,
 | |
|                            ia_sbr_tables_struct *sbr_tables_ptr,
 | |
|                            const WORD16 *cos_sin_lookup_tab) {
 | |
|   WORD group, bin, num_iid_steps;
 | |
|   WORD16 c2, c1;
 | |
|   WORD32 alpha, beta;
 | |
|   WORD16 h11, h12, h21, h22;
 | |
|   WORD16 inv_env_len;
 | |
|   const WORD16 *p_scale_factors;
 | |
|   WORD16 *p_iid_idx;
 | |
|   WORD indexplusa, indexminusa;
 | |
| 
 | |
|   const WORD32 rescale = (0x0517cc1b << 1);
 | |
| 
 | |
|   if (env == 0) {
 | |
|     WORD usb_prev = ptr_ps_dec->usb;
 | |
|     WORD16 *ptr_tmp;
 | |
|     ptr_ps_dec->usb = usb;
 | |
| 
 | |
|     if ((usb > usb_prev) && usb_prev) {
 | |
|       WORD i, j, delay, offset1;
 | |
|       WORD ixheaacd_drc_offset =
 | |
|           (usb < NUM_OF_QUAD_MIRROR_FILTER_ALL_PASS_CHNLS
 | |
|                ? usb
 | |
|                : NUM_OF_QUAD_MIRROR_FILTER_ALL_PASS_CHNLS);
 | |
| 
 | |
|       if (ixheaacd_drc_offset > usb_prev) {
 | |
|         for (i = 0; i < NUM_SER_AP_LINKS; i++) {
 | |
|           for (j = 0; j < ptr_ps_dec->delay_sample_ser[i]; j++) {
 | |
|             ptr_tmp = &ptr_ps_dec->delay_buf_qmf_ser_re_im[j][i][usb_prev * 2];
 | |
| 
 | |
|             memset(ptr_tmp, 0,
 | |
|                    sizeof(WORD16) * (ixheaacd_drc_offset - usb_prev) * 2);
 | |
|           }
 | |
|         }
 | |
|       }
 | |
| 
 | |
|       offset1 =
 | |
|           (usb < (NUM_OF_QUAD_MIRROR_FILTER_ALL_PASS_CHNLS + SMALL_DEL_STRT)
 | |
|                ? usb
 | |
|                : (NUM_OF_QUAD_MIRROR_FILTER_ALL_PASS_CHNLS + SMALL_DEL_STRT));
 | |
|       delay = HIGH_DEL;
 | |
| 
 | |
|       if ((offset1 >= ixheaacd_drc_offset) && (offset1 <= SMALL_DEL_STRT)) {
 | |
|         for (i = 0; i < delay; i++) {
 | |
|           ptr_tmp =
 | |
|               &ptr_ps_dec->delay_buf_qmf_ld_re_im[i][ixheaacd_drc_offset * 2];
 | |
| 
 | |
|           memset(ptr_tmp, 0,
 | |
|                  sizeof(WORD16) * 2 * (offset1 - ixheaacd_drc_offset));
 | |
|         }
 | |
|       }
 | |
| 
 | |
|       delay = SMALL_DEL;
 | |
| 
 | |
|       if ((usb >= offset1) && (usb <= 16)) {
 | |
|         for (i = 0; i < delay; i++) {
 | |
|           ptr_tmp = &ptr_ps_dec->delay_buf_qmf_sd_re_im[i][offset1 * 2];
 | |
| 
 | |
|           memset(ptr_tmp, 0, sizeof(WORD16) * 2 * (usb - offset1));
 | |
|         }
 | |
|       }
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   if (ptr_ps_dec->iid_quant) {
 | |
|     num_iid_steps = NUM_IID_LEVELS_FINE;
 | |
|     p_scale_factors = sbr_tables_ptr->ps_tables_ptr->scale_factors_fine;
 | |
|   } else {
 | |
|     num_iid_steps = NUM_IID_LEVELS;
 | |
|     p_scale_factors = sbr_tables_ptr->ps_tables_ptr->scale_factors;
 | |
|   }
 | |
| 
 | |
|   inv_env_len =
 | |
|       sbr_tables_ptr->env_calc_tables_ptr->sbr_inv_int_table[ixheaacd_abs16(
 | |
|           ixheaacd_sub16_sat(ptr_ps_dec->border_position[env + 1],
 | |
|                              ptr_ps_dec->border_position[env]))];
 | |
| 
 | |
|   p_iid_idx = &ptr_ps_dec->iid_par_table[env][0];
 | |
| 
 | |
|   for (group = 0; group < NO_IID_GROUPS; group++) {
 | |
|     WORD16 bplusa, bminusa;
 | |
|     WORD num_iid_idx, num_icc_idx;
 | |
| 
 | |
|     bin = sbr_tables_ptr->ps_tables_ptr->group_to_bin[group];
 | |
| 
 | |
|     num_iid_idx = p_iid_idx[bin];
 | |
|     num_icc_idx = p_iid_idx[bin + 238];
 | |
| 
 | |
|     c1 = p_scale_factors[(num_iid_steps + num_iid_idx)];
 | |
|     c2 = p_scale_factors[(num_iid_steps - num_iid_idx)];
 | |
| 
 | |
|     beta = ixheaacd_mult32x16in32_shl(
 | |
|         ixheaacd_mult16x16in32_shl(
 | |
|             sbr_tables_ptr->ps_tables_ptr->alpha_values[num_icc_idx],
 | |
|             ixheaacd_sub16(c1, c2)),
 | |
|         PSC_SQRT05F);
 | |
|     alpha = ixheaacd_shr32_dir_sat_limit(
 | |
|         ixheaacd_deposit16h_in32(
 | |
|             sbr_tables_ptr->ps_tables_ptr->alpha_values[num_icc_idx]),
 | |
|         1);
 | |
| 
 | |
|     bplusa = ixheaacd_round16(ixheaacd_add32_sat(beta, alpha));
 | |
|     bminusa = ixheaacd_round16(ixheaacd_sub32_sat(beta, alpha));
 | |
| 
 | |
|     indexplusa = ixheaacd_mult32x16in32(rescale, bplusa);
 | |
|     indexminusa = ixheaacd_mult32x16in32(rescale, bminusa);
 | |
| 
 | |
|     h11 = ixheaacd_mult16_shl(ixheaacd_cos512(indexplusa, cos_sin_lookup_tab),
 | |
|                               c2);
 | |
|     h12 = ixheaacd_mult16_shl(ixheaacd_cos512(indexminusa, cos_sin_lookup_tab),
 | |
|                               c1);
 | |
|     h21 = ixheaacd_mult16_shl(ixheaacd_sin512(indexplusa, cos_sin_lookup_tab),
 | |
|                               c2);
 | |
|     h22 = ixheaacd_mult16_shl(ixheaacd_sin512(indexminusa, cos_sin_lookup_tab),
 | |
|                               c1);
 | |
| 
 | |
|     ptr_ps_dec->delta_h11_h12[2 * group + 0] = ixheaacd_mult16_shl(
 | |
|         inv_env_len,
 | |
|         ixheaacd_sub16(h11, ptr_ps_dec->h11_h12_vec[2 * group + 0]));
 | |
|     ptr_ps_dec->delta_h11_h12[2 * group + 1] = ixheaacd_mult16_shl(
 | |
|         inv_env_len,
 | |
|         ixheaacd_sub16(h12, ptr_ps_dec->h11_h12_vec[2 * group + 1]));
 | |
|     ptr_ps_dec->delta_h21_h22[2 * group + 0] = ixheaacd_mult16_shl(
 | |
|         inv_env_len,
 | |
|         ixheaacd_sub16(h21, ptr_ps_dec->h21_h22_vec[2 * group + 0]));
 | |
|     ptr_ps_dec->delta_h21_h22[2 * group + 1] = ixheaacd_mult16_shl(
 | |
|         inv_env_len,
 | |
|         ixheaacd_sub16(h22, ptr_ps_dec->h21_h22_vec[2 * group + 1]));
 | |
| 
 | |
|     ptr_ps_dec->H11_H12[2 * group + 0] = ptr_ps_dec->h11_h12_vec[2 * group + 0];
 | |
|     ptr_ps_dec->H11_H12[2 * group + 1] = ptr_ps_dec->h11_h12_vec[2 * group + 1];
 | |
|     ptr_ps_dec->H21_H22[2 * group + 0] = ptr_ps_dec->h21_h22_vec[2 * group + 0];
 | |
|     ptr_ps_dec->H21_H22[2 * group + 1] = ptr_ps_dec->h21_h22_vec[2 * group + 1];
 | |
| 
 | |
|     ptr_ps_dec->h11_h12_vec[2 * group + 0] = h11;
 | |
|     ptr_ps_dec->h11_h12_vec[2 * group + 1] = h12;
 | |
|     ptr_ps_dec->h21_h22_vec[2 * group + 0] = h21;
 | |
|     ptr_ps_dec->h21_h22_vec[2 * group + 1] = h22;
 | |
|   }
 | |
| }
 | |
| 
 | |
| VOID ixheaacd_apply_rot_dec(ia_ps_dec_struct *ptr_ps_dec, WORD32 *p_qmf_left_re,
 | |
|                             WORD32 *p_qmf_left_im, WORD32 *p_qmf_right_re,
 | |
|                             WORD32 *p_qmf_right_im,
 | |
|                             ia_sbr_tables_struct *sbr_tables_ptr,
 | |
|                             const WORD16 *ptr_res) {
 | |
|   WORD group, subband, max_subband, usb, k;
 | |
|   WORD32 *p_hyb_left_re, *p_hyb_left_re1;
 | |
|   WORD32 *p_hyb_left_im, *p_hyb_left_im1;
 | |
|   WORD32 *p_hyb_right_re, *p_hyb_right_re1;
 | |
|   WORD32 *p_hyb_right_im, *p_hyb_right_im1;
 | |
|   WORD32 temp_left_real, temp_left_imag;
 | |
|   WORD32 temp_right_real, temp_right_imag;
 | |
|   WORD16 hybrid_resol;
 | |
|   WORD32 tmp_real, tmp_img;
 | |
|   WORD32 tmp_real1, tmp_img1;
 | |
|   WORD32 loopcnt;
 | |
|   WORD16 H11_H12[128 * 2];
 | |
| 
 | |
|   usb = ptr_ps_dec->usb;
 | |
| 
 | |
|   p_hyb_left_re1 = ptr_ps_dec->ptr_hyb_left_re;
 | |
|   p_hyb_left_im1 = ptr_ps_dec->ptr_hyb_left_im;
 | |
|   p_hyb_right_re1 = ptr_ps_dec->ptr_hyb_right_re;
 | |
|   p_hyb_right_im1 = ptr_ps_dec->ptr_hyb_right_im;
 | |
| 
 | |
|   for (group = 0; group < NO_IID_GROUPS; group++) {
 | |
|     ptr_ps_dec->H11_H12[2 * group + 0] =
 | |
|         ixheaacd_add16(ptr_ps_dec->H11_H12[2 * group + 0],
 | |
|                        ptr_ps_dec->delta_h11_h12[2 * group + 0]);
 | |
|     ptr_ps_dec->H11_H12[2 * group + 1] =
 | |
|         ixheaacd_add16(ptr_ps_dec->H11_H12[2 * group + 1],
 | |
|                        ptr_ps_dec->delta_h11_h12[2 * group + 1]);
 | |
| 
 | |
|     ptr_ps_dec->H21_H22[2 * group + 0] =
 | |
|         ixheaacd_add16(ptr_ps_dec->H21_H22[2 * group + 0],
 | |
|                        ptr_ps_dec->delta_h21_h22[2 * group + 0]);
 | |
|     ptr_ps_dec->H21_H22[2 * group + 1] =
 | |
|         ixheaacd_add16(ptr_ps_dec->H21_H22[2 * group + 1],
 | |
|                        ptr_ps_dec->delta_h21_h22[2 * group + 1]);
 | |
|   }
 | |
| 
 | |
|   for (subband = 0; subband < SUBQMF_GROUPS; subband++) {
 | |
|     temp_left_real = ixheaacd_add32_sat(
 | |
|         ixheaacd_mult32x16in32(p_hyb_left_re1[subband],
 | |
|                                ptr_ps_dec->H11_H12[2 * subband + 0]),
 | |
|         ixheaacd_mult32x16in32(p_hyb_right_re1[subband],
 | |
|                                ptr_ps_dec->H21_H22[2 * subband + 0]));
 | |
|     temp_left_imag = ixheaacd_add32_sat(
 | |
|         ixheaacd_mult32x16in32(p_hyb_left_im1[subband],
 | |
|                                ptr_ps_dec->H11_H12[2 * subband + 0]),
 | |
|         ixheaacd_mult32x16in32(p_hyb_right_im1[subband],
 | |
|                                ptr_ps_dec->H21_H22[2 * subband + 0]));
 | |
|     temp_right_real = ixheaacd_add32_sat(
 | |
|         ixheaacd_mult32x16in32(p_hyb_left_re1[subband],
 | |
|                                ptr_ps_dec->H11_H12[2 * subband + 1]),
 | |
|         ixheaacd_mult32x16in32(p_hyb_right_re1[subband],
 | |
|                                ptr_ps_dec->H21_H22[2 * subband + 1]));
 | |
|     temp_right_imag = ixheaacd_add32_sat(
 | |
|         ixheaacd_mult32x16in32(p_hyb_left_im1[subband],
 | |
|                                ptr_ps_dec->H11_H12[2 * subband + 1]),
 | |
|         ixheaacd_mult32x16in32(p_hyb_right_im1[subband],
 | |
|                                ptr_ps_dec->H21_H22[2 * subband + 1]));
 | |
|     p_hyb_left_re1[subband] = ixheaacd_shl32(temp_left_real, 2);
 | |
|     p_hyb_left_im1[subband] = ixheaacd_shl32(temp_left_imag, 2);
 | |
|     p_hyb_right_re1[subband] = ixheaacd_shl32(temp_right_real, 2);
 | |
|     p_hyb_right_im1[subband] = ixheaacd_shl32(temp_right_imag, 2);
 | |
|   }
 | |
| 
 | |
|   p_hyb_left_re = p_qmf_left_re;
 | |
|   p_hyb_left_im = p_qmf_left_im;
 | |
|   p_hyb_right_re = p_qmf_right_re;
 | |
|   p_hyb_right_im = p_qmf_right_im;
 | |
| 
 | |
|   {
 | |
|     WORD32 *h11_h12_src = (WORD32 *)ptr_ps_dec->H11_H12;
 | |
|     WORD32 *h21_h22_src = (WORD32 *)ptr_ps_dec->H21_H22;
 | |
|     WORD32 *h11_h12_dst = (WORD32 *)H11_H12;
 | |
| 
 | |
|     for (group = SUBQMF_GROUPS; group < NO_IID_GROUPS; group++) {
 | |
|       max_subband = ixheaacd_min32(
 | |
|           usb, sbr_tables_ptr->ps_tables_ptr->borders_group[group + 1]);
 | |
|       for (subband = sbr_tables_ptr->ps_tables_ptr->borders_group[group];
 | |
|            subband < max_subband; subband++) {
 | |
|         h11_h12_dst[2 * subband] = h11_h12_src[group];
 | |
|         h11_h12_dst[2 * subband + 1] = h21_h22_src[group];
 | |
|       }
 | |
|     }
 | |
|   }
 | |
|   loopcnt = (usb + 15) >> 4;
 | |
| 
 | |
|   for (subband = 0; subband < NO_QMF_CHANNELS_IN_HYBRID; subband++) {
 | |
|     tmp_real = *p_hyb_left_re1++;
 | |
|     tmp_img = *p_hyb_left_im1++;
 | |
|     tmp_real1 = *p_hyb_right_re1++;
 | |
|     tmp_img1 = *p_hyb_right_im1++;
 | |
| 
 | |
|     hybrid_resol = ixheaacd_min16(*ptr_res++, 6);
 | |
| 
 | |
|     for (k = hybrid_resol - 2; k >= 0; k--) {
 | |
|       tmp_real = ixheaacd_add32_sat(tmp_real, *p_hyb_left_re1++);
 | |
|       tmp_img = ixheaacd_add32_sat(tmp_img, *p_hyb_left_im1++);
 | |
|       tmp_real1 = ixheaacd_add32_sat(tmp_real1, *p_hyb_right_re1++);
 | |
|       tmp_img1 = ixheaacd_add32_sat(tmp_img1, *p_hyb_right_im1++);
 | |
|     }
 | |
| 
 | |
|     p_hyb_left_re[subband] = tmp_real;
 | |
|     p_hyb_left_im[subband] = tmp_img;
 | |
|     p_hyb_right_re[subband] = tmp_real1;
 | |
|     p_hyb_right_im[subband] = tmp_img1;
 | |
|   }
 | |
| 
 | |
|   for (; subband < usb; subband++) {
 | |
|     temp_left_real =
 | |
|         ixheaacd_add32_sat(ixheaacd_mult32x16in32(p_hyb_left_re[subband],
 | |
|                                                   H11_H12[4 * subband + 0]),
 | |
|                            ixheaacd_mult32x16in32(p_hyb_right_re[subband],
 | |
|                                                   H11_H12[4 * subband + 2]));
 | |
|     temp_left_imag =
 | |
|         ixheaacd_add32_sat(ixheaacd_mult32x16in32(p_hyb_left_im[subband],
 | |
|                                                   H11_H12[4 * subband + 0]),
 | |
|                            ixheaacd_mult32x16in32(p_hyb_right_im[subband],
 | |
|                                                   H11_H12[4 * subband + 2]));
 | |
|     temp_right_real =
 | |
|         ixheaacd_add32_sat(ixheaacd_mult32x16in32(p_hyb_left_re[subband],
 | |
|                                                   H11_H12[4 * subband + 1]),
 | |
|                            ixheaacd_mult32x16in32(p_hyb_right_re[subband],
 | |
|                                                   H11_H12[4 * subband + 3]));
 | |
|     temp_right_imag =
 | |
|         ixheaacd_add32_sat(ixheaacd_mult32x16in32(p_hyb_left_im[subband],
 | |
|                                                   H11_H12[4 * subband + 1]),
 | |
|                            ixheaacd_mult32x16in32(p_hyb_right_im[subband],
 | |
|                                                   H11_H12[4 * subband + 3]));
 | |
|     p_hyb_left_re[subband] = ixheaacd_shl32(temp_left_real, 2);
 | |
|     p_hyb_left_im[subband] = ixheaacd_shl32(temp_left_imag, 2);
 | |
|     p_hyb_right_re[subband] = ixheaacd_shl32(temp_right_real, 2);
 | |
|     p_hyb_right_im[subband] = ixheaacd_shl32(temp_right_imag, 2);
 | |
|   }
 | |
| }
 |