From 97fc5f51e4f841ed932050075735c0cb840c6a12 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Tue, 26 Mar 2024 23:06:55 +0530 Subject: [PATCH] Integration of fixed point sub-functions 9 [x] ism_param_dec_renderer Added fixed implementation for the following ivas_param_ism_dec_render_fx ivas_param_ism_render_slot_fx ivas_param_ism_update_mixing_matrix_fx bug fix added in cldfbSynthesis_ivas_fx [x] Add conversion changes for ivas_ls_setup_conversion_process_mdct_param_mc_fx [x] ivas_omasa_separate_object_render function --- lib_com/cldfb.c | 30 +- lib_com/ivas_prot.h | 18 + lib_com/ivas_prot_fx.h | 2 +- lib_dec/ivas_ism_param_dec.c | 451 ++++++++++++++++++++++++- lib_dec/ivas_jbm_dec.c | 17 + lib_dec/ivas_mc_param_dec.c | 12 + lib_dec/ivas_mct_dec.c | 58 ++++ lib_dec/ivas_mdct_core_dec.c | 2 +- lib_dec/ivas_omasa_dec.c | 99 ++---- lib_dec/ivas_out_setup_conversion.c | 340 +++++++++++++++++++ lib_dec/ivas_stat_dec.h | 6 + lib_dec/ivas_stereo_mdct_core_dec_fx.c | 33 +- lib_rend/ivas_stat_rend.h | 4 + 13 files changed, 968 insertions(+), 104 deletions(-) diff --git a/lib_com/cldfb.c b/lib_com/cldfb.c index 5a99b1483..db9fd9b27 100644 --- a/lib_com/cldfb.c +++ b/lib_com/cldfb.c @@ -2006,8 +2006,8 @@ static void cldfb_init_proto_and_twiddles( #ifdef IVAS_FLOAT_FIXED hs->rot_vec_ana_delay_re_fx = rot_vec_delay_re_LDQMF_fx; hs->rot_vec_ana_delay_im_fx = rot_vec_delay_im_LDQMF_fx; - hs->rot_vec_syn_delay_im_fx = rot_vec_delay_re_LDQMF_fx; - hs->rot_vec_syn_delay_re_fx = rot_vec_delay_im_LDQMF_fx; + hs->rot_vec_syn_delay_re_fx = rot_vec_delay_re_LDQMF_fx; + hs->rot_vec_syn_delay_im_fx = rot_vec_delay_im_LDQMF_fx; hs->p_filter_sf = (Word16) 15388; hs->p_filter = LDQMF_10_fx; hs->q_scale = norm_s((Word16)LDQMF_10_SCALE); @@ -2061,8 +2061,8 @@ static void cldfb_init_proto_and_twiddles( #ifdef IVAS_FLOAT_FIXED hs->rot_vec_ana_delay_re_fx = rot_vec_delay_re_LDQMF_fx; hs->rot_vec_ana_delay_im_fx = rot_vec_delay_im_LDQMF_fx; - hs->rot_vec_syn_delay_im_fx = rot_vec_delay_re_LDQMF_fx; - hs->rot_vec_syn_delay_re_fx = rot_vec_delay_im_LDQMF_fx; + hs->rot_vec_syn_delay_re_fx = rot_vec_delay_re_LDQMF_fx; + hs->rot_vec_syn_delay_im_fx = rot_vec_delay_im_LDQMF_fx; hs->p_filter_sf = (Word16) 15388; hs->p_filter = LDQMF_16_fx; hs->q_scale = norm_s((Word16)LDQMF_16_SCALE); @@ -2116,8 +2116,8 @@ static void cldfb_init_proto_and_twiddles( #ifdef IVAS_FLOAT_FIXED hs->rot_vec_ana_delay_re_fx = rot_vec_delay_re_LDQMF_fx; hs->rot_vec_ana_delay_im_fx = rot_vec_delay_im_LDQMF_fx; - hs->rot_vec_syn_delay_im_fx = rot_vec_delay_re_LDQMF_fx; - hs->rot_vec_syn_delay_re_fx = rot_vec_delay_im_LDQMF_fx; + hs->rot_vec_syn_delay_re_fx = rot_vec_delay_re_LDQMF_fx; + hs->rot_vec_syn_delay_im_fx = rot_vec_delay_im_LDQMF_fx; hs->p_filter_sf = (Word16) 15390; hs->p_filter = LDQMF_20_fx; hs->q_scale = norm_s((Word16)LDQMF_20_SCALE); @@ -2171,8 +2171,8 @@ static void cldfb_init_proto_and_twiddles( #ifdef IVAS_FLOAT_FIXED hs->rot_vec_ana_delay_re_fx = rot_vec_delay_re_LDQMF_fx; hs->rot_vec_ana_delay_im_fx = rot_vec_delay_im_LDQMF_fx; - hs->rot_vec_syn_delay_im_fx = rot_vec_delay_re_LDQMF_fx; - hs->rot_vec_syn_delay_re_fx = rot_vec_delay_im_LDQMF_fx; + hs->rot_vec_syn_delay_re_fx = rot_vec_delay_re_LDQMF_fx; + hs->rot_vec_syn_delay_im_fx = rot_vec_delay_im_LDQMF_fx; hs->p_filter_sf = (Word16) 15388; hs->p_filter = LDQMF_30_fx; hs->q_scale = norm_s((Word16)LDQMF_30_SCALE); @@ -2226,8 +2226,8 @@ static void cldfb_init_proto_and_twiddles( #ifdef IVAS_FLOAT_FIXED hs->rot_vec_ana_delay_re_fx = rot_vec_delay_re_LDQMF_fx; hs->rot_vec_ana_delay_im_fx = rot_vec_delay_im_LDQMF_fx; - hs->rot_vec_syn_delay_im_fx = rot_vec_delay_re_LDQMF_fx; - hs->rot_vec_syn_delay_re_fx = rot_vec_delay_im_LDQMF_fx; + hs->rot_vec_syn_delay_re_fx = rot_vec_delay_re_LDQMF_fx; + hs->rot_vec_syn_delay_im_fx = rot_vec_delay_im_LDQMF_fx; hs->p_filter_sf = (Word16) 15392; hs->p_filter = LDQMF_32_fx; hs->q_scale = norm_s((Word16)LDQMF_32_SCALE); @@ -2281,8 +2281,8 @@ static void cldfb_init_proto_and_twiddles( #ifdef IVAS_FLOAT_FIXED hs->rot_vec_ana_delay_re_fx = rot_vec_delay_re_LDQMF_fx; hs->rot_vec_ana_delay_im_fx = rot_vec_delay_im_LDQMF_fx; - hs->rot_vec_syn_delay_im_fx = rot_vec_delay_re_LDQMF_fx; - hs->rot_vec_syn_delay_re_fx = rot_vec_delay_im_LDQMF_fx; + hs->rot_vec_syn_delay_re_fx = rot_vec_delay_re_LDQMF_fx; + hs->rot_vec_syn_delay_im_fx = rot_vec_delay_im_LDQMF_fx; hs->p_filter_sf = (Word16) 15391; hs->p_filter = LDQMF_40_fx; hs->q_scale = norm_s((Word16)LDQMF_40_SCALE); @@ -2315,8 +2315,8 @@ static void cldfb_init_proto_and_twiddles( #ifdef IVAS_FLOAT_FIXED hs->rot_vec_ana_delay_re_fx = NULL; hs->rot_vec_ana_delay_im_fx = NULL; - hs->rot_vec_syn_delay_im_fx = NULL; hs->rot_vec_syn_delay_re_fx = NULL; + hs->rot_vec_syn_delay_im_fx = NULL; hs->p_filter_sf = (Word16) 17051; hs->p_filter = CLDFB80_60_fx; hs->q_scale = norm_s((Word16)CLDFB80_60_SCALE); @@ -2336,8 +2336,8 @@ static void cldfb_init_proto_and_twiddles( #ifdef IVAS_FLOAT_FIXED hs->rot_vec_ana_delay_re_fx = rot_vec_delay_re_LDQMF_fx; hs->rot_vec_ana_delay_im_fx = rot_vec_delay_im_LDQMF_fx; - hs->rot_vec_syn_delay_im_fx = rot_vec_delay_re_LDQMF_fx; - hs->rot_vec_syn_delay_re_fx = rot_vec_delay_im_LDQMF_fx; + hs->rot_vec_syn_delay_re_fx = rot_vec_delay_re_LDQMF_fx; + hs->rot_vec_syn_delay_im_fx = rot_vec_delay_im_LDQMF_fx; hs->p_filter_sf = (Word16) 15391; hs->p_filter = LDQMF_60_fx; hs->q_scale = norm_s((Word16)LDQMF_60_SCALE); diff --git a/lib_com/ivas_prot.h b/lib_com/ivas_prot.h index 030047e15..0f42b5251 100644 --- a/lib_com/ivas_prot.h +++ b/lib_com/ivas_prot.h @@ -1237,6 +1237,17 @@ void ivas_param_ism_dec_render( float *output_f[] /* o : rendered time signal */ ); +#ifdef IVAS_FLOAT_FIXED +void ivas_param_ism_dec_render_fx( + Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ + const uint16_t nSamplesAsked, /* i : number of CLDFB slots requested */ + uint16_t *nSamplesRendered, /* o : number of CLDFB slots rendered */ + uint16_t *nSamplesAvailable, /* o : number of CLDFB slots still to render */ + float *output_f[], /* o : rendered time signal */ + Word32 *output_f_fx[] +); +#endif + void ivas_param_ism_params_to_masa_param_mapping( Decoder_Struct *st_ivas /* i/o: IVAS decoder structure */ ); @@ -6171,6 +6182,13 @@ void ivas_ls_setup_conversion_process_mdct( Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ float *output[] /* i/o: output synthesis signal */ ); +#ifdef IVAS_FLOAT_FIXED +void ivas_ls_setup_conversion_process_mdct_param_mc_fx( + Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ + Word32 *x_fx[][NB_DIV], /* i/o: Fixed output synthesis signal */ + Word16 x_e[MAX_CICP_CHANNELS][NB_DIV]/* i/o: Exponent for output synthesis signal */ +); +#endif // IVAS_FLOAT_FIXED void ivas_ls_setup_conversion_process_mdct_param_mc( Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ diff --git a/lib_com/ivas_prot_fx.h b/lib_com/ivas_prot_fx.h index 9370a84de..1ff34c20e 100644 --- a/lib_com/ivas_prot_fx.h +++ b/lib_com/ivas_prot_fx.h @@ -1330,7 +1330,7 @@ void ivas_mdct_core_tns_ns_fx( Word32 *x_fx[CPE_CHANNELS][NB_DIV], /* o : synthesis @internal_FS */ Word32 Aq_fx[CPE_CHANNELS][(NB_SUBFR16k + 1) * (M + 1)], /* o : LP coefficients */ const Word16 MCT_flag, /* i : hMCT handle allocated (1) or not (0) */ - Word16 x_e[CPE_CHANNELS][NB_DIV] + Word16 x_e[MAX_CICP_CHANNELS][NB_DIV] ); void decoder_tcx_imdct_fx( diff --git a/lib_dec/ivas_ism_param_dec.c b/lib_dec/ivas_ism_param_dec.c index b1cd70474..bec2e773b 100644 --- a/lib_dec/ivas_ism_param_dec.c +++ b/lib_dec/ivas_ism_param_dec.c @@ -43,6 +43,7 @@ #include "ivas_prot_fx.h" #include "prot_fx1.h" #include "prot_fx2.h" +#include "debug.h" /*-----------------------------------------------------------------------* * Local function definitions @@ -307,6 +308,97 @@ static void ivas_param_ism_compute_mixing_matrix( return; } +#ifdef IVAS_FLOAT_FIXED +static void ivas_param_ism_render_slot_fx( + PARAM_ISM_DEC_HANDLE hParamIsmDec, + SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, + Word32 *Cldfb_RealBuffer_in_fx[PARAM_ISM_MAX_DMX], + Word32 *Cldfb_ImagBuffer_in_fx[PARAM_ISM_MAX_DMX], + Word32 Cldfb_RealBuffer_fx[PARAM_ISM_MAX_CHAN][JBM_CLDFB_SLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX], + Word32 Cldfb_ImagBuffer_fx[PARAM_ISM_MAX_CHAN][JBM_CLDFB_SLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX], + Word16 *exp_real, + Word16 *exp_imag, + Word32 mixing_matrix_fx[CLDFB_NO_CHANNELS_MAX][PARAM_ISM_MAX_CHAN * PARAM_ISM_MAX_DMX], + const Word16 interpolator_idx, + const Word16 out_slot_idx, + const Word16 num_ch_LS, + const Word16 nchan_transport ) +{ + Word16 outchIdx, inchIdx, bin_idx; + Word32 tmp_1_fx, mixing_matrix_smooth_fx; + +#if 1 + hParamIsmDec->hParamIsmRendering->interpolator_fx[interpolator_idx] = (Word16) floatToFixed( hParamIsmDec->hParamIsmRendering->interpolator[interpolator_idx], Q14 ); +#endif + tmp_1_fx = L_deposit_h( hParamIsmDec->hParamIsmRendering->interpolator_fx[interpolator_idx] ); // Q30 + + Word16 res_exp = 0; + Word16 real_buf_exp = hParamIsmDec->hParamIsmRendering->Cldfb_RealBuffer_tc_exp; + Word16 imag_buf_exp = hParamIsmDec->hParamIsmRendering->Cldfb_ImagBuffer_tc_exp; + + /*exponent buffers to handle variable exp*/ + Word16 exp_buf_real[PARAM_ISM_MAX_CHAN][JBM_CLDFB_SLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX]; + Word16 exp_buf_imag[PARAM_ISM_MAX_CHAN][JBM_CLDFB_SLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX]; + for (int i = 0; i < PARAM_ISM_MAX_CHAN; i++) { + for (int j = 0; j < JBM_CLDFB_SLOTS_IN_SUBFRAME; j++) { + for (int k = 0; k < CLDFB_NO_CHANNELS_MAX; k++) { + exp_buf_real[i][j][k] = 0; + exp_buf_imag[i][j][k] = 0; + } + } + } + for ( bin_idx = 0; bin_idx < hSpatParamRendCom->num_freq_bands; bin_idx++ ) + { + /* smooth the mixing matrix */ + for ( outchIdx = 0; outchIdx < num_ch_LS; outchIdx++ ) + { + for ( inchIdx = 0; inchIdx < nchan_transport; inchIdx++ ) + { + Word32 tmp_2 = Mpy_32_32( tmp_1_fx, mixing_matrix_fx[bin_idx][outchIdx + inchIdx * num_ch_LS] ); // 1 + hParamIsmDec->hParamIsmRendering->exp_mixing_matrix_lin // Q29 + Word32 tmp_3 = Mpy_32_32( L_sub( ONE_IN_Q30, tmp_1_fx ), hParamIsmDec->hParamIsmRendering->mixing_matrix_lin_old_fx[bin_idx][outchIdx + inchIdx * num_ch_LS] ); // 1 + hParamIsmDec->hParamIsmRendering->exp_mixing_matrix_lin_old + mixing_matrix_smooth_fx = BASOP_Util_Add_Mant32Exp( tmp_2, 1 + hParamIsmDec->hParamIsmRendering->exp_mixing_matrix_lin_fx, tmp_3, 1 + hParamIsmDec->hParamIsmRendering->exp_mixing_matrix_lin_old_fx, &res_exp ); + + Word32 tmp_4 = Mpy_32_32( mixing_matrix_smooth_fx, Cldfb_RealBuffer_in_fx[inchIdx][bin_idx] ); // res_exp + hParamIsmDec->hParamIsmRendering->Cldfb_RealBuffer_tc_exp + Word32 tmp_5 = Mpy_32_32( mixing_matrix_smooth_fx, Cldfb_ImagBuffer_in_fx[inchIdx][bin_idx] ); // res_exp + hParamIsmDec->hParamIsmRendering->Cldfb_ImagBuffer_tc_exp + + Cldfb_RealBuffer_fx[outchIdx][out_slot_idx][bin_idx] = BASOP_Util_Add_Mant32Exp( Cldfb_RealBuffer_fx[outchIdx][out_slot_idx][bin_idx], real_buf_exp, + tmp_4, res_exp + hParamIsmDec->hParamIsmRendering->Cldfb_RealBuffer_tc_exp, &real_buf_exp ); + Cldfb_ImagBuffer_fx[outchIdx][out_slot_idx][bin_idx] = BASOP_Util_Add_Mant32Exp( Cldfb_ImagBuffer_fx[outchIdx][out_slot_idx][bin_idx], imag_buf_exp, + tmp_5, res_exp + hParamIsmDec->hParamIsmRendering->Cldfb_ImagBuffer_tc_exp, &imag_buf_exp ); + + exp_buf_real[outchIdx][out_slot_idx][bin_idx] = real_buf_exp; + exp_buf_imag[outchIdx][out_slot_idx][bin_idx] = imag_buf_exp; + } + } + } + + /*Make same exponent for whole buffer*/ + Word16 max_exp_real = MIN_16; + Word16 max_exp_imag = MIN_16; + for (bin_idx = 0; bin_idx < hSpatParamRendCom->num_freq_bands; bin_idx++) + { + for (outchIdx = 0; outchIdx < num_ch_LS; outchIdx++) + { + max_exp_real = max(max_exp_real, exp_buf_real[outchIdx][out_slot_idx][bin_idx]); + max_exp_imag = max(max_exp_imag, exp_buf_imag[outchIdx][out_slot_idx][bin_idx]); + } + } + + for (bin_idx = 0; bin_idx < hSpatParamRendCom->num_freq_bands; bin_idx++) + { + for (outchIdx = 0; outchIdx < num_ch_LS; outchIdx++) + { + Cldfb_RealBuffer_fx[outchIdx][out_slot_idx][bin_idx] = L_shr(Cldfb_RealBuffer_fx[outchIdx][out_slot_idx][bin_idx], max_exp_real - exp_buf_real[outchIdx][out_slot_idx][bin_idx]); + Cldfb_ImagBuffer_fx[outchIdx][out_slot_idx][bin_idx] = L_shr(Cldfb_ImagBuffer_fx[outchIdx][out_slot_idx][bin_idx], max_exp_imag - exp_buf_imag[outchIdx][out_slot_idx][bin_idx]); + } + } + + *exp_real = max_exp_real; + *exp_imag = max_exp_imag; + + return; +} +#endif static void ivas_param_ism_render_slot( PARAM_ISM_DEC_HANDLE hParamIsmDec, @@ -433,6 +525,36 @@ static ivas_error ivas_param_ism_rendering_init( return IVAS_ERR_OK; } +#ifdef IVAS_FLOAT_FIXED +static void ivas_param_ism_update_mixing_matrix_fx( + PARAM_ISM_DEC_HANDLE hParamIsmDec, + Word32 mixing_matrix_fx[CLDFB_NO_CHANNELS_MAX][PARAM_ISM_MAX_CHAN * PARAM_ISM_MAX_DMX], + const Word16 nchan_in, + const Word16 nchan_out) +{ + Word16 inchIdx, outchIdx, bin_idx, band_idx; + Word16 brange[2]; + + FOR (band_idx = 0; band_idx < hParamIsmDec->hParamIsm->nbands; band_idx++) + { + brange[0] = hParamIsmDec->hParamIsm->band_grouping[band_idx]; + brange[1] = hParamIsmDec->hParamIsm->band_grouping[band_idx + 1]; + + FOR (bin_idx = brange[0]; bin_idx < brange[1]; bin_idx++) + { + FOR (inchIdx = 0; inchIdx < nchan_in; inchIdx++) + { + FOR (outchIdx = 0; outchIdx < nchan_out; outchIdx++) + { + hParamIsmDec->hParamIsmRendering->mixing_matrix_lin_old_fx[bin_idx][outchIdx + inchIdx * nchan_out] = mixing_matrix_fx[bin_idx][outchIdx + inchIdx * nchan_out]; + } + } + } + } + + return; +} +#endif static void ivas_param_ism_update_mixing_matrix( PARAM_ISM_DEC_HANDLE hParamIsmDec, @@ -1407,8 +1529,17 @@ void ivas_param_ism_dec_digest_tc( for ( bin_idx = 0; bin_idx < hSpatParamRendCom->num_freq_bands; bin_idx++ ) { set_f( hParamIsmDec->hParamIsmRendering->mixing_matrix_lin[bin_idx], 0.0f, nchan_transport * nchan_out_woLFE ); +#ifdef IVAS_FLOAT_FIXED + set32_fx(hParamIsmDec->hParamIsmRendering->mixing_matrix_lin_fx[bin_idx], 0, nchan_transport * nchan_out_woLFE); +#endif } - +#ifdef IVAS_FLOAT_FIXED + /*to avoide garbage values*/ + for (bin_idx = 0; bin_idx < CLDFB_NO_CHANNELS_MAX; bin_idx++) + { + set_f(hParamIsmDec->hParamIsmRendering->mixing_matrix_lin[bin_idx], 0.0f, PARAM_ISM_MAX_CHAN * PARAM_ISM_MAX_DMX); + } +#endif /* Compute mixing matrix */ ivas_param_ism_compute_mixing_matrix( st_ivas->nchan_ism, hParamIsmDec, st_ivas->hISMDTX, direct_response, nchan_transport, nchan_out_woLFE, cx_diag, ref_power, hParamIsmDec->hParamIsmRendering->mixing_matrix_lin ); @@ -1616,7 +1747,180 @@ void ivas_ism_param_dec_tc_gain_ajust_fx( * * *-------------------------------------------------------------------------*/ +#ifdef IVAS_FLOAT_FIXED +static void ivas_ism_param_dec_render_sf_fx( + Decoder_Struct *st_ivas, + IVAS_OUTPUT_SETUP hSetup, + const int16_t nchan_transport, + const int16_t nchan_out, + const int16_t nchan_out_woLFE, + float *output_f[], /* o : rendered time signal */ + Word32 *output_f_fx[] +) +{ + int16_t ch, slot_idx, i, index_slot; + /* CLDFB Output Buffers */ + float Cldfb_RealBuffer[PARAM_ISM_MAX_CHAN][JBM_CLDFB_SLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX]; + float Cldfb_ImagBuffer[PARAM_ISM_MAX_CHAN][JBM_CLDFB_SLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX]; + float *Cldfb_RealBuffer_in[PARAM_ISM_MAX_DMX]; + float *Cldfb_ImagBuffer_in[PARAM_ISM_MAX_DMX]; +#ifdef IVAS_FLOAT_FIXED + Word32 Cldfb_RealBuffer_fx[PARAM_ISM_MAX_CHAN][JBM_CLDFB_SLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX]; + Word32 Cldfb_ImagBuffer_fx[PARAM_ISM_MAX_CHAN][JBM_CLDFB_SLOTS_IN_SUBFRAME][CLDFB_NO_CHANNELS_MAX]; + Word32 *Cldfb_RealBuffer_in_fx[PARAM_ISM_MAX_DMX]; + Word32 *Cldfb_ImagBuffer_in_fx[PARAM_ISM_MAX_DMX]; +#endif + PARAM_ISM_DEC_HANDLE hParamIsmDec; + SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom; + Word16 slot_idx_start; + Word16 idx_in; + Word16 idx_lfe; + Word16 subframe_idx; + + hParamIsmDec = st_ivas->hParamIsmDec; + hSpatParamRendCom = st_ivas->hSpatParamRendCom; + slot_idx_start = hSpatParamRendCom->slots_rendered; + subframe_idx = hSpatParamRendCom->subframes_rendered; + + /* Set some memories to zero */ + for (ch = 0; ch < nchan_out_woLFE; ch++) + { + for (slot_idx = 0; slot_idx < hSpatParamRendCom->subframe_nbslots[subframe_idx]; slot_idx++) + { + set_f(Cldfb_RealBuffer[ch][slot_idx], 0.0f, hSpatParamRendCom->num_freq_bands); + set_f(Cldfb_ImagBuffer[ch][slot_idx], 0.0f, hSpatParamRendCom->num_freq_bands); +#ifdef IVAS_FLOAT_FIXED + set32_fx(Cldfb_RealBuffer_fx[ch][slot_idx], 0, hSpatParamRendCom->num_freq_bands); + set32_fx(Cldfb_ImagBuffer_fx[ch][slot_idx], 0, hSpatParamRendCom->num_freq_bands); +#endif + } + } + +#if 1 + f2me_buf(hParamIsmDec->hParamIsmRendering->Cldfb_RealBuffer_tc, hParamIsmDec->hParamIsmRendering->Cldfb_RealBuffer_tc_fx, &hParamIsmDec->hParamIsmRendering->Cldfb_RealBuffer_tc_exp, (slot_idx_start + hSpatParamRendCom->subframe_nbslots[subframe_idx] ) * st_ivas->nchan_transport * hSpatParamRendCom->num_freq_bands); + f2me_buf(hParamIsmDec->hParamIsmRendering->Cldfb_ImagBuffer_tc, hParamIsmDec->hParamIsmRendering->Cldfb_ImagBuffer_tc_fx, &hParamIsmDec->hParamIsmRendering->Cldfb_ImagBuffer_tc_exp, (slot_idx_start + hSpatParamRendCom->subframe_nbslots[subframe_idx] ) * st_ivas->nchan_transport * hSpatParamRendCom->num_freq_bands); +#endif + Word16 real_exp[JBM_CLDFB_SLOTS_IN_SUBFRAME]; + Word16 imag_exp[JBM_CLDFB_SLOTS_IN_SUBFRAME]; + for (slot_idx = 0; slot_idx < hSpatParamRendCom->subframe_nbslots[subframe_idx]; slot_idx++) + { + index_slot = slot_idx_start + slot_idx; + + for (ch = 0; ch < nchan_transport; ch++) + { + Cldfb_RealBuffer_in[ch] = &hParamIsmDec->hParamIsmRendering->Cldfb_RealBuffer_tc[index_slot * hSpatParamRendCom->num_freq_bands * nchan_transport + ch * hSpatParamRendCom->num_freq_bands]; + Cldfb_ImagBuffer_in[ch] = &hParamIsmDec->hParamIsmRendering->Cldfb_ImagBuffer_tc[index_slot * hSpatParamRendCom->num_freq_bands * nchan_transport + ch * hSpatParamRendCom->num_freq_bands]; +#ifdef IVAS_FLOAT_FIXED + Cldfb_RealBuffer_in_fx[ch] = &hParamIsmDec->hParamIsmRendering->Cldfb_RealBuffer_tc_fx[index_slot * hSpatParamRendCom->num_freq_bands * nchan_transport + ch * hSpatParamRendCom->num_freq_bands];//Q11 + Cldfb_ImagBuffer_in_fx[ch] = &hParamIsmDec->hParamIsmRendering->Cldfb_ImagBuffer_tc_fx[index_slot * hSpatParamRendCom->num_freq_bands * nchan_transport + ch * hSpatParamRendCom->num_freq_bands];//Q11 +#endif + } + + /* Compute bandwise rendering to target LS using covariance rendering */ +#ifdef IVAS_FLOAT_FIXED +#if 1 + f2me_buf((float*)hParamIsmDec->hParamIsmRendering->mixing_matrix_lin, (Word32*)hParamIsmDec->hParamIsmRendering->mixing_matrix_lin_fx, &hParamIsmDec->hParamIsmRendering->exp_mixing_matrix_lin_fx, CLDFB_NO_CHANNELS_MAX * (PARAM_ISM_MAX_CHAN * PARAM_ISM_MAX_DMX)); + f2me_buf((float*)hParamIsmDec->hParamIsmRendering->mixing_matrix_lin_old, (Word32*)hParamIsmDec->hParamIsmRendering->mixing_matrix_lin_old_fx, &hParamIsmDec->hParamIsmRendering->exp_mixing_matrix_lin_old_fx, CLDFB_NO_CHANNELS_MAX * (PARAM_ISM_MAX_CHAN * PARAM_ISM_MAX_DMX)); +#endif + real_exp[slot_idx] = 0; + imag_exp[slot_idx] = 0; + ivas_param_ism_render_slot_fx( hParamIsmDec, hSpatParamRendCom, + Cldfb_RealBuffer_in_fx, Cldfb_ImagBuffer_in_fx, Cldfb_RealBuffer_fx, Cldfb_ImagBuffer_fx, &real_exp[slot_idx], &imag_exp[slot_idx], + hParamIsmDec->hParamIsmRendering->mixing_matrix_lin_fx, + index_slot, slot_idx, nchan_out_woLFE, nchan_transport ); + +#if 1 + for (int bin_idx = 0; bin_idx < hSpatParamRendCom->num_freq_bands; bin_idx++) + { + for (int outchIdx = 0; outchIdx < nchan_out_woLFE; outchIdx++) + { + Cldfb_RealBuffer[outchIdx][slot_idx][bin_idx] = me2f(Cldfb_RealBuffer_fx[outchIdx][slot_idx][bin_idx], real_exp[slot_idx]); + Cldfb_ImagBuffer[outchIdx][slot_idx][bin_idx] = me2f(Cldfb_ImagBuffer_fx[outchIdx][slot_idx][bin_idx], imag_exp[slot_idx]); + } + } +#endif +#else + ivas_param_ism_render_slot(hParamIsmDec, hSpatParamRendCom, Cldfb_RealBuffer_in, Cldfb_ImagBuffer_in, + Cldfb_RealBuffer, Cldfb_ImagBuffer, hParamIsmDec->hParamIsmRendering->mixing_matrix_lin, index_slot, slot_idx, nchan_out_woLFE, nchan_transport); +#endif + } + + /* CLDFB Synthesis */ + idx_in = 0; + idx_lfe = 0; + + for (ch = 0; ch < nchan_out; ch++) + { + if ((hSetup.num_lfe > 0) && (hSetup.index_lfe[idx_lfe] == ch)) + { + set_zero(output_f[ch], hSpatParamRendCom->subframe_nbslots[subframe_idx] * hSpatParamRendCom->num_freq_bands); + set32_fx(output_f_fx[ch], 0, hSpatParamRendCom->subframe_nbslots[subframe_idx] * hSpatParamRendCom->num_freq_bands); + + if (idx_lfe < (hSetup.num_lfe - 1)) + { + idx_lfe++; + } + } + else + { + float *RealBuffer[16]; + float *ImagBuffer[16]; + + /* open CLDFB buffer up to CLDFB_NO_CHANNELS_MAX bands for 48kHz */ + for (i = 0; i < hSpatParamRendCom->subframe_nbslots[subframe_idx]; i++) + { + RealBuffer[i] = Cldfb_RealBuffer[idx_in][i]; + ImagBuffer[i] = Cldfb_ImagBuffer[idx_in][i]; + } +#ifdef IVAS_FLOAT_FIXED + Word32 *RealBuffer_fx[16]; + Word32 *ImagBuffer_fx[16]; + + Word16 Q_real = 31; + + for ( i = 0; i < hSpatParamRendCom->subframe_nbslots[subframe_idx]; i++ ) + { + RealBuffer_fx[i] = Cldfb_RealBuffer_fx[idx_in][i]; + ImagBuffer_fx[i] = Cldfb_ImagBuffer_fx[idx_in][i]; + Q_real = min( Q_real, 31 - imag_exp[i] ); + Q_real = min( Q_real, 31 - real_exp[i] ); + } + + Q_real -= 3; //guarded bits + + for (i = 0; i < hSpatParamRendCom->subframe_nbslots[subframe_idx]; i++) + { + Scale_sig32(RealBuffer_fx[i], CLDFB_NO_CHANNELS_MAX, Q_real - 31 + real_exp[i]); + Scale_sig32(ImagBuffer_fx[i], CLDFB_NO_CHANNELS_MAX, Q_real - 31 + imag_exp[i]); + } + + floatToFixed_arrL( st_ivas->cldfbSynDec[ch]->cldfb_state, st_ivas->cldfbSynDec[ch]->cldfb_state_fx, Q_real - 1, st_ivas->cldfbSynDec[ch]->p_filter_length ); + + cldfbSynthesis_ivas_fx( RealBuffer_fx, ImagBuffer_fx, output_f_fx[ch], hSpatParamRendCom->num_freq_bands * hSpatParamRendCom->subframe_nbslots[subframe_idx], st_ivas->cldfbSynDec[ch] ); + + Word16 samplesToProcess = hSpatParamRendCom->num_freq_bands * hSpatParamRendCom->subframe_nbslots[subframe_idx]; + Word16 no_col = st_ivas->cldfbSynDec[ch]->no_col; + IF(GT_16(samplesToProcess, -1)) + { + no_col = min(no_col, (samplesToProcess + st_ivas->cldfbSynDec[ch]->no_channels - 1) / st_ivas->cldfbSynDec[ch]->no_channels); + move16(); + } + + fixedToFloat_arrL( output_f_fx[ch], output_f[ch], Q_real - 1, st_ivas->cldfbSynDec[ch]->no_channels * no_col); + fixedToFloat_arrL( st_ivas->cldfbSynDec[ch]->cldfb_state_fx, st_ivas->cldfbSynDec[ch]->cldfb_state, Q_real - 1, st_ivas->cldfbSynDec[ch]->p_filter_length ); +#else + cldfbSynthesis_ivas(RealBuffer, ImagBuffer, output_f[ch], hSpatParamRendCom->num_freq_bands * hSpatParamRendCom->subframe_nbslots[subframe_idx], st_ivas->cldfbSynDec[ch]); +#endif + idx_in++; + } + } + + hSpatParamRendCom->slots_rendered += hSpatParamRendCom->subframe_nbslots[subframe_idx]; + hSpatParamRendCom->subframes_rendered++; + return; +} +#endif static void ivas_ism_param_dec_render_sf( Decoder_Struct *st_ivas, IVAS_OUTPUT_SETUP hSetup, @@ -1634,10 +1938,10 @@ static void ivas_ism_param_dec_render_sf( float *Cldfb_ImagBuffer_in[PARAM_ISM_MAX_DMX]; PARAM_ISM_DEC_HANDLE hParamIsmDec; SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom; - int16_t slot_idx_start; - int16_t idx_in; - int16_t idx_lfe; - int16_t subframe_idx; + Word16 slot_idx_start; + Word16 idx_in; + Word16 idx_lfe; + Word16 subframe_idx; hParamIsmDec = st_ivas->hParamIsmDec; hSpatParamRendCom = st_ivas->hSpatParamRendCom; @@ -1712,7 +2016,142 @@ static void ivas_ism_param_dec_render_sf( * * *-------------------------------------------------------------------------*/ +#ifdef IVAS_FLOAT_FIXED +void ivas_param_ism_dec_render_fx( + Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ + const UWord16 nSamplesAsked, /* i : number of CLDFB slots requested */ + UWord16 *nSamplesRendered, /* o : number of CLDFB slots rendered */ + UWord16 *nSamplesAvailableNext, /* o : number of CLDFB slots still to render */ + float *output_f[], /* o : rendered time signal */ + Word32 *output_f_fx[] +) +{ + Word16 ch, slots_to_render, first_sf, last_sf, subframe_idx; + UWord16 slot_size, n_samples_sf; + PARAM_ISM_DEC_HANDLE hParamIsmDec; + SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom; + IVAS_OUTPUT_SETUP hSetup; + Word16 nchan_transport, nchan_out, nchan_out_woLFE; + float *output_f_local[MAX_OUTPUT_CHANNELS]; + Word32 *output_f_local_fx[MAX_OUTPUT_CHANNELS]; + hParamIsmDec = st_ivas->hParamIsmDec; + hSpatParamRendCom = st_ivas->hSpatParamRendCom; + hSetup = st_ivas->hIntSetup; + nchan_transport = st_ivas->nchan_transport; + IF (st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_EXTERNAL) + { + nchan_out = st_ivas->nchan_ism; + nchan_out_woLFE = nchan_out; + st_ivas->hDecoderConfig->nchan_out = nchan_out; + } + ELSE + { + nchan_out = st_ivas->hIntSetup.nchan_out_woLFE + st_ivas->hIntSetup.num_lfe; + nchan_out_woLFE = st_ivas->hIntSetup.nchan_out_woLFE; + } + slot_size = NS2SA(st_ivas->hDecoderConfig->output_Fs, CLDFB_SLOT_NS); + + /* loop for synthesis, assume we always have to render in multiples of 5ms subframes with spills */ + slots_to_render = min(hSpatParamRendCom->num_slots - hSpatParamRendCom->slots_rendered, nSamplesAsked / slot_size); + *nSamplesRendered = slots_to_render * slot_size; + first_sf = hSpatParamRendCom->subframes_rendered; + last_sf = first_sf; + + WHILE (slots_to_render > 0) + { + slots_to_render -= hSpatParamRendCom->subframe_nbslots[last_sf]; + last_sf++; + } + + FOR (ch = 0; ch < nchan_out; ch++) + { + output_f_local[ch] = &output_f[ch][0]; + output_f_local_fx[ch] = &output_f_fx[ch][0]; + } + + FOR (subframe_idx = first_sf; subframe_idx < last_sf; subframe_idx++) + { +#ifdef IVAS_FLOAT_FIXED + ivas_ism_param_dec_render_sf_fx(st_ivas, hSetup, nchan_transport, nchan_out, nchan_out_woLFE, output_f_local, output_f_local_fx); +#else + ivas_ism_param_dec_render_sf(st_ivas, hSetup, nchan_transport, nchan_out, nchan_out_woLFE, output_f_local); +#endif + n_samples_sf = hSpatParamRendCom->subframe_nbslots[subframe_idx] * hSpatParamRendCom->slot_size; + FOR (ch = 0; ch < nchan_out; ch++) + { + output_f_local[ch] += n_samples_sf; + output_f_local_fx[ch] += n_samples_sf; + } + } + + IF (hSpatParamRendCom->slots_rendered == hSpatParamRendCom->num_slots) + { + /* copy the memories */ + /* store mixing matrix for next subframe */ +#if 1 + f2me_buf((float*)hParamIsmDec->hParamIsmRendering->mixing_matrix_lin, (Word32*)hParamIsmDec->hParamIsmRendering->mixing_matrix_lin_fx, &hParamIsmDec->hParamIsmRendering->exp_mixing_matrix_lin_fx, CLDFB_NO_CHANNELS_MAX * (PARAM_ISM_MAX_CHAN * PARAM_ISM_MAX_DMX)); +#endif + ivas_param_ism_update_mixing_matrix_fx(hParamIsmDec, hParamIsmDec->hParamIsmRendering->mixing_matrix_lin_fx, nchan_transport, nchan_out_woLFE); +#if 1 + Word16 inchIdx, outchIdx, bin_idx, band_idx; + Word16 brange[2]; + + FOR(band_idx = 0; band_idx < hParamIsmDec->hParamIsm->nbands; band_idx++) + { + brange[0] = hParamIsmDec->hParamIsm->band_grouping[band_idx]; + brange[1] = hParamIsmDec->hParamIsm->band_grouping[band_idx + 1]; + + FOR(bin_idx = brange[0]; bin_idx < brange[1]; bin_idx++) + { + FOR(inchIdx = 0; inchIdx < nchan_transport; inchIdx++) + { + FOR(outchIdx = 0; outchIdx < nchan_out_woLFE; outchIdx++) + { + hParamIsmDec->hParamIsmRendering->mixing_matrix_lin_old[bin_idx][outchIdx + inchIdx * nchan_out_woLFE] = me2f(hParamIsmDec->hParamIsmRendering->mixing_matrix_lin_old_fx[bin_idx][outchIdx + inchIdx * nchan_out_woLFE], hParamIsmDec->hParamIsmRendering->exp_mixing_matrix_lin_fx); + } + } + } + } +#endif + + /* store MetaData parameters */ +#if 1 + FOR ( ch = 0; ch < st_ivas->nchan_ism; ch++ ) + { + st_ivas->hParamIsmDec->azimuth_values_fx[ch] = floatToFixed( st_ivas->hParamIsmDec->azimuth_values[ch], Q22 ); + st_ivas->hParamIsmDec->elevation_values_fx[ch] = floatToFixed( st_ivas->hParamIsmDec->elevation_values[ch], Q22 ); + } +#endif + FOR ( ch = 0; ch < st_ivas->nchan_ism; ch++ ) + { + IF ( st_ivas->hParamIsmDec->azimuth_values_fx[ch] > 754974720 /*180.f in Q22*/ ) + { + st_ivas->hIsmMetaData[ch]->azimuth_fx = L_sub( st_ivas->hParamIsmDec->azimuth_values_fx[ch], 1509949440 ) /*360.0F in Q22*/; + } + ELSE + { + st_ivas->hIsmMetaData[ch]->azimuth_fx = st_ivas->hParamIsmDec->azimuth_values_fx[ch]; + } + + st_ivas->hIsmMetaData[ch]->elevation_fx = st_ivas->hParamIsmDec->elevation_values_fx[ch]; + } + +#if 1 + FOR ( ch = 0; ch < st_ivas->nchan_ism; ch++ ) + { + st_ivas->hIsmMetaData[ch]->azimuth = fixedToFloat( st_ivas->hIsmMetaData[ch]->azimuth_fx, Q22 ); + st_ivas->hIsmMetaData[ch]->elevation = fixedToFloat( st_ivas->hIsmMetaData[ch]->elevation_fx, Q22 ); + } +#endif + } + + *nSamplesAvailableNext = (hSpatParamRendCom->num_slots - hSpatParamRendCom->slots_rendered) * slot_size; + + return; +} + +#else void ivas_param_ism_dec_render( Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ const uint16_t nSamplesAsked, /* i : number of CLDFB slots requested */ @@ -1799,7 +2238,7 @@ void ivas_param_ism_dec_render( return; } - +#endif /*-------------------------------------------------------------------------* * ivas_param_ism_params_to_masa_param_mapping() diff --git a/lib_dec/ivas_jbm_dec.c b/lib_dec/ivas_jbm_dec.c index 2fb1fb56f..af681b941 100644 --- a/lib_dec/ivas_jbm_dec.c +++ b/lib_dec/ivas_jbm_dec.c @@ -3578,7 +3578,24 @@ ivas_error ivas_jbm_dec_render( } else if ( st_ivas->renderer_type == RENDERER_PARAM_ISM || st_ivas->renderer_type == RENDERER_SBA_LINEAR_ENC ) { +#ifdef IVAS_FLOAT_FIXED + Word32 output_fx_tmp[MAX_OUTPUT_CHANNELS + MAX_NUM_OBJECTS][L_FRAME48k]; + Word32 *p_output_fx_tmp[MAX_OUTPUT_CHANNELS + MAX_NUM_OBJECTS]; + FOR( Word16 lp = 0; lp < MAX_OUTPUT_CHANNELS + MAX_NUM_OBJECTS; lp++ ) + { + p_output_fx_tmp[lp] = &output_fx_tmp[lp][0]; + } + + Word16 Q_p_output_buf = Q11; + FOR(i = 0; i < st_ivas->hIntSetup.nchan_out_woLFE + st_ivas->hIntSetup.num_lfe; i++) + { + floatToFixed_arrL(p_output[i], p_output_fx_tmp[i], Q_p_output_buf, L_FRAME48k); + } + + ivas_param_ism_dec_render_fx(st_ivas, nSamplesAskedLocal, nSamplesRendered, nSamplesAvailableNext, p_output, p_output_fx_tmp); +#else ivas_param_ism_dec_render( st_ivas, nSamplesAskedLocal, nSamplesRendered, nSamplesAvailableNext, p_output ); +#endif if ( st_ivas->renderer_type == RENDERER_SBA_LINEAR_ENC ) { diff --git a/lib_dec/ivas_mc_param_dec.c b/lib_dec/ivas_mc_param_dec.c index fcc175f72..4690c7af3 100644 --- a/lib_dec/ivas_mc_param_dec.c +++ b/lib_dec/ivas_mc_param_dec.c @@ -240,6 +240,12 @@ ivas_error ivas_param_mc_dec_open( { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Parametric MC\n" ) ); } +#ifdef IVAS_FLOAT_FIXED + if ( ( hParamMC->icld_q_fx = (Word16 *) malloc( hParamMC->hMetadataPMC->num_parameter_bands * hParamMC->hMetadataPMC->ild_mapping_conf->ild_map_size_lfe * sizeof( Word16 ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Parametric MC\n" ) ); + } +#endif // IVAS_FLOAT_FIXED set_f( hParamMC->icld_q, PARAM_MC_DEFAULT_MIN_ILD, hParamMC->hMetadataPMC->num_parameter_bands * hParamMC->hMetadataPMC->ild_mapping_conf->ild_map_size_lfe ); set_f( hParamMC->icc_q, 0.0f, hParamMC->hMetadataPMC->num_parameter_bands * hParamMC->hMetadataPMC->icc_mapping_conf->icc_map_size_lfe ); @@ -726,6 +732,12 @@ ivas_error ivas_param_mc_dec_reconfig( { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Parametric MC\n" ) ); } +#ifdef IVAS_FLOAT_FIXED + if ( ( hParamMC->icld_q_fx = (Word16 *) malloc( hParamMC->hMetadataPMC->num_parameter_bands * hParamMC->hMetadataPMC->ild_mapping_conf->ild_map_size_lfe * sizeof(Word16) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for Parametric MC\n" ) ); + } +#endif // IVAS_FLOAT_FIXED set_f( hParamMC->icld_q, PARAM_MC_DEFAULT_MIN_ILD, hParamMC->hMetadataPMC->num_parameter_bands * hParamMC->hMetadataPMC->ild_mapping_conf->ild_map_size_lfe ); set_f( hParamMC->icc_q, 0.0f, hParamMC->hMetadataPMC->num_parameter_bands * hParamMC->hMetadataPMC->icc_mapping_conf->icc_map_size_lfe ); diff --git a/lib_dec/ivas_mct_dec.c b/lib_dec/ivas_mct_dec.c index 13f327cd4..9896b95ec 100644 --- a/lib_dec/ivas_mct_dec.c +++ b/lib_dec/ivas_mct_dec.c @@ -461,7 +461,65 @@ ivas_error ivas_mct_dec( } } +#ifdef IVAS_FLOAT_FIXED + Word32 **output_fx; + Word16 x_all_e[MAX_CICP_CHANNELS][NB_DIV] = { 0 }; + Word32 *x_all_fx[MAX_CICP_CHANNELS][NB_DIV]; + IF( ( output_fx = (Word32 **) malloc( MAX_CICP_CHANNELS * sizeof( Word32 * ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for HP20 filter memory\n" ) ); + } + FOR( cpe_id = 0; cpe_id < nCPE; cpe_id++ ) + { + FOR( n = 0; n < CPE_CHANNELS; n++ ) + { + IF( ( output_fx[n + cpe_id * CPE_CHANNELS] = (Word32 *) malloc( ( 48000 / FRAMES_PER_SEC ) * sizeof( Word32 ) ) ) == NULL ) + { + return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for floating-point output audio buffer!\n" ) ); + } + f2me_buf( output[n + cpe_id * CPE_CHANNELS], output_fx[n + cpe_id * CPE_CHANNELS], &x_all_e[n + cpe_id * CPE_CHANNELS][0], 960 ); + Scale_sig32( output_fx[n + cpe_id * CPE_CHANNELS], L_FRAME48k, -1 ); /*Scaling the signal down by 1 because of overflow*/ + x_all_e[n + cpe_id * CPE_CHANNELS][0]++; + x_all_fx[n + cpe_id * CPE_CHANNELS][0] = output_fx[n + cpe_id * CPE_CHANNELS]; + x_all_fx[n + cpe_id * CPE_CHANNELS][1] = output_fx[n + cpe_id * CPE_CHANNELS] + ( L_FRAME48k / 2 ); + x_all_e[n + cpe_id * CPE_CHANNELS][1] = x_all_e[n + cpe_id * CPE_CHANNELS][0]; + } + } + f2me_buf( st_ivas->hLsSetUpConversion->targetEnergyPrev[0], st_ivas->hLsSetUpConversion->targetEnergyPrev_fx[0], &st_ivas->hLsSetUpConversion->te_prev_exp, st_ivas->hLsSetUpConversion->sfbCnt ); + f2me_buf( st_ivas->hLsSetUpConversion->dmxEnergyPrev[0], st_ivas->hLsSetUpConversion->dmxEnergyPrev_fx[0], &st_ivas->hLsSetUpConversion->dmx_prev_exp, st_ivas->hLsSetUpConversion->sfbCnt ); + PARAM_MC_DEC_HANDLE hParamMC; + hParamMC = st_ivas->hParamMC; + floatToFixed_arr16( hParamMC->icld_q, hParamMC->icld_q_fx, 8, hParamMC->hMetadataPMC->num_parameter_bands * hParamMC->hMetadataPMC->ild_mapping_conf->ild_map_size_lfe ); + floatToFixed_arr32( hParamMC->ls_conv_dmx_matrix, hParamMC->ls_conv_dmx_matrix_fx, 15, st_ivas->hDecoderConfig->nchan_out * ( st_ivas->hTransSetup.nchan_out_woLFE + st_ivas->hTransSetup.num_lfe ) ); + FOR(Word16 chOutIdx = 0; chOutIdx < st_ivas->hDecoderConfig->nchan_out; chOutIdx++) + { + FOR(Word16 chInIdx = 0; chInIdx < st_ivas->nchan_transport; chInIdx++) + { + st_ivas->hLsSetUpConversion->dmxMtx_fx[chInIdx][chOutIdx] = float_to_fix(st_ivas->hLsSetUpConversion->dmxMtx[chInIdx][chOutIdx], 30); /*Q30*/ + } + } + ivas_ls_setup_conversion_process_mdct_param_mc_fx( st_ivas, x_all_fx, x_all_e ); + FOR( cpe_id = 0; cpe_id < nCPE; cpe_id++ ) + { + FOR( n = 0; n < CPE_CHANNELS; n++ ) + { + me2f_buf( &x_all_fx[n + cpe_id * CPE_CHANNELS][0][0], x_all_e[n + cpe_id * CPE_CHANNELS][0], &x_all[n + cpe_id * CPE_CHANNELS][0][0], L_FRAME48k / 2 ); + me2f_buf( &x_all_fx[n + cpe_id * CPE_CHANNELS][1][0], x_all_e[n + cpe_id * CPE_CHANNELS][1], &x_all[n + cpe_id * CPE_CHANNELS][1][0], L_FRAME48k / 2 ); + } + } + me2f_buf( st_ivas->hLsSetUpConversion->targetEnergyPrev_fx[0], st_ivas->hLsSetUpConversion->te_prev_exp, st_ivas->hLsSetUpConversion->targetEnergyPrev[0], st_ivas->hLsSetUpConversion->sfbCnt ); + me2f_buf( st_ivas->hLsSetUpConversion->dmxEnergyPrev_fx[0], st_ivas->hLsSetUpConversion->dmx_prev_exp, st_ivas->hLsSetUpConversion->dmxEnergyPrev[0], st_ivas->hLsSetUpConversion->sfbCnt ); + + FOR( cpe_id = 0; cpe_id < nCPE; cpe_id++ ) + { + FOR( n = 0; n < CPE_CHANNELS; n++ ) + { + free( output_fx[n + cpe_id * CPE_CHANNELS] ); + } + } +#else ivas_ls_setup_conversion_process_mdct_param_mc( st_ivas, x_all ); +#endif // } for ( cpe_id = 0; cpe_id < nCPE; cpe_id++ ) diff --git a/lib_dec/ivas_mdct_core_dec.c b/lib_dec/ivas_mdct_core_dec.c index 1a7d43e84..1b83441f9 100644 --- a/lib_dec/ivas_mdct_core_dec.c +++ b/lib_dec/ivas_mdct_core_dec.c @@ -2444,7 +2444,7 @@ void ivas_mdct_core_tns_ns_fx( Word32 *x_fx[CPE_CHANNELS][NB_DIV], /* o : synthesis @internal_FS */ Word32 Aq_fx[CPE_CHANNELS][( NB_SUBFR16k + 1 ) * ( M + 1 )], /* o : LP coefficients */ const Word16 MCT_flag, /* i : hMCT handle allocated (1) or not (0) */ - Word16 x_e[CPE_CHANNELS][NB_DIV] + Word16 x_e[MAX_CICP_CHANNELS][NB_DIV] ) { Word16 ch, k, bfi; diff --git a/lib_dec/ivas_omasa_dec.c b/lib_dec/ivas_omasa_dec.c index 9b833d71a..880fedc13 100644 --- a/lib_dec/ivas_omasa_dec.c +++ b/lib_dec/ivas_omasa_dec.c @@ -1219,12 +1219,12 @@ void ivas_omasa_dirac_rend_jbm( ivas_dirac_dec_render( st_ivas, nchan_transport, nSamplesAsked, nSamplesRendered, nSamplesAvailable, output_f ); -#ifdef IVAS_FLOAT_FIXED1 +#ifdef IVAS_FLOAT_FIXED Word16 q_output = 31, q_inverse_matrix = 31; Word32 **output_fx, data_separated_objects_fx[4][960]; FOR(Word16 ind = 0; ind < st_ivas->hIntSetup.nchan_out_woLFE + st_ivas->hIntSetup.num_lfe; ind++) { - FOR(Word16 ind2 = 0; ind2 < nSamplesAsked; ind2++) + FOR(Word16 ind2 = 0; ind2 < 960; ind2++) { IF(L_abs((Word32)output_f[ind][ind2])!=0) q_output = s_min(q_output, norm_l((Word32)output_f[ind][ind2])); IF((ind < st_ivas->nchan_ism) && L_abs((Word32)data_separated_objects[ind][ind2])!=0) q_output = s_min(q_output, norm_l((Word32)data_separated_objects[ind][ind2])); @@ -1250,7 +1250,8 @@ void ivas_omasa_dirac_rend_jbm( { FOR(Word16 ind2 = 0; ind2 < nSamplesAsked; ind2++) { - data_separated_objects_fx[ind][ind2] = (Word32)(data_separated_objects[ind][ind2] * (1<hIntSetup.nchan_out_woLFE + st_ivas->hIntSetup.num_lfe)); @@ -1259,86 +1260,35 @@ void ivas_omasa_dirac_rend_jbm( output_fx[ind] = (Word32*)malloc(sizeof(Word32) * 960); FOR(Word16 ind2 = 0; ind2 < 960; ind2++) { - output_fx[ind][ind2] =(Word32)(output_f[ind][ind2] * (1<hVBAPdata) - FOR(Word16 ind1 = 0; ind1 < 2; ind1++) + Word16 len; + IF( st_ivas->ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ || st_ivas->ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ ) { - FOR(Word16 ind2 = 0; ind2 < 4; ind2++) - { - FOR(Word16 ind3 = 0; ind3 < 3; ind3++) - { - FOR(Word16 ind4 = 0; ind4 < 3; ind4++) - { - IF (L_abs((Word32)st_ivas->hVBAPdata->search_struct[ind1].triplets[ind2].inverse_matrix[ind3][ind4]) != 0) - { - q_inverse_matrix = s_min(q_inverse_matrix, norm_l((Word32)st_ivas->hVBAPdata->search_struct[ind1].triplets[ind2].inverse_matrix[ind3][ind4])); - } - } - } - } + len = 1; } - IF(st_ivas->hVBAPdata) + ELSE { - IF(st_ivas->hVBAPdata->back_virtual_speaker_node_division_gains) - FOR(Word16 ind = 0; ind < st_ivas->hVBAPdata->num_speaker_nodes; ind++) - { - st_ivas->hVBAPdata->back_virtual_speaker_node_division_gains_fx[ind] = (Word32)(st_ivas->hVBAPdata->back_virtual_speaker_node_division_gains[ind] * (2147483647)); - } - IF(st_ivas->hVBAPdata->bottom_virtual_speaker_node_division_gains) - FOR(Word16 ind = 0; ind < st_ivas->hVBAPdata->num_speaker_nodes; ind++) - { - st_ivas->hVBAPdata->bottom_virtual_speaker_node_division_gains_fx[ind] = (Word32)(st_ivas->hVBAPdata->bottom_virtual_speaker_node_division_gains[ind] * (2147483647)); - } - IF(st_ivas->hVBAPdata->top_virtual_speaker_node_division_gains) - FOR(Word16 ind = 0; ind < st_ivas->hVBAPdata->num_speaker_nodes; ind++) - { - st_ivas->hVBAPdata->top_virtual_speaker_node_division_gains_fx[ind] = (Word32)(st_ivas->hVBAPdata->top_virtual_speaker_node_division_gains[ind] * (2147483647)); - } - IF(st_ivas->hVBAPdata->object_mode_bottom_virtual_speaker_node_division_gains) - FOR(Word16 ind = 0; ind < st_ivas->hVBAPdata->num_speaker_nodes; ind++) - { - st_ivas->hVBAPdata->object_mode_bottom_virtual_speaker_node_division_gains_fx[ind] = (Word32)(st_ivas->hVBAPdata->object_mode_bottom_virtual_speaker_node_division_gains[ind] * (2147483647)); - } - IF(st_ivas->hVBAPdata->object_mode_back_virtual_speaker_node_division_gains) - FOR(Word16 ind = 0; ind < st_ivas->hVBAPdata->num_speaker_nodes; ind++) - { - st_ivas->hVBAPdata->object_mode_back_virtual_speaker_node_division_gains_fx[ind] = (Word32)(st_ivas->hVBAPdata->object_mode_back_virtual_speaker_node_division_gains[ind] * (2147483647)); - } - IF(st_ivas->hVBAPdata->object_mode_top_virtual_speaker_node_division_gains) - FOR(Word16 ind = 0; ind < st_ivas->hVBAPdata->num_speaker_nodes; ind++) - { - st_ivas->hVBAPdata->object_mode_top_virtual_speaker_node_division_gains_fx[ind] = (Word32)(st_ivas->hVBAPdata->object_mode_top_virtual_speaker_node_division_gains[ind] * (2147483647)); - } + len = st_ivas->nchan_ism; } - IF(st_ivas->hVBAPdata) - FOR(Word16 ind1 = 0; ind1 < 2; ind1++) + IF( st_ivas->hDecoderConfig->Opt_tsm ) { - FOR(Word16 ind2 = 0; ind2 < st_ivas->hVBAPdata->search_struct[ind1].num_triplets; ind2++) + FOR( Word16 ind1 = 0; ind1 < len + 2; ind1++ ) { - st_ivas->hVBAPdata->search_struct[ind1].triplets[ind2].q_inverse_matrix = q_inverse_matrix; - FOR(Word16 ind3 = 0; ind3 < 3; ind3++) + FOR( Word16 ind2 = 0; ind2 < 960; ind2++ ) { - FOR(Word16 ind4 = 0; ind4 < 3; ind4++) - { - st_ivas->hVBAPdata->search_struct[ind1].triplets[ind2].inverse_matrix_fx[ind3][ind4] = (Word32)(st_ivas->hVBAPdata->search_struct[ind1].triplets[ind2].inverse_matrix[ind3][ind4] * (1 << q_inverse_matrix)); - } + //st_ivas->hTcBuffer->tc_fx[ind1][ind2] = (Word32) ( st_ivas->hTcBuffer->tc[ind1][ind2] * ( 1 << q_output ) ); + st_ivas->hTcBuffer->tc_fx[ind1][ind2] = floatToFixed( st_ivas->hTcBuffer->tc[ind1][ind2] ,q_output ); } } } - FOR(Word16 ind1 = 0; ind1 < st_ivas->nchan_ism; ind1++) - { - FOR(Word16 ind2 = 0; ind2 < 960; ind2++) - { - st_ivas->hTcBuffer->tc_fx[ind1][ind2] = (Word32)(st_ivas->hTcBuffer->tc[ind1][ind2] * (1 << q_output)); - } - } FOR(Word16 ind1 = 0; ind1 < st_ivas->hMasaIsmData->delayBuffer_nchan; ind1++) { FOR(Word16 ind2 = 0; ind2 < st_ivas->hMasaIsmData->delayBuffer_size; ind2++) { - st_ivas->hMasaIsmData->delayBuffer_fx[ind1][ind2] = (Word32)(st_ivas->hMasaIsmData->delayBuffer[ind1][ind2] * (1 << q_output)); + st_ivas->hMasaIsmData->delayBuffer_fx[ind1][ind2] = floatToFixed(st_ivas->hMasaIsmData->delayBuffer[ind1][ind2] , q_output); } } FOR ( Word16 k = 0; k < st_ivas->hIsmRendererData->interpolator_length; k++ ) @@ -1360,7 +1310,7 @@ void ivas_omasa_dirac_rend_jbm( { FOR(Word16 ind2 = 0; ind2 < 960; ind2++) { - output_f[ind][ind2] =(float)(output_fx[ind][ind2]) / (float)(1<hIsmRendererData->prev_gains[ind1][ind2] = (float)(st_ivas->hIsmRendererData->prev_gains_fx[ind1][ind2]) / (float)(1 << 29); } } - FOR(Word16 ind1 = 0; ind1 < st_ivas->nchan_ism; ind1++) + IF( st_ivas->hDecoderConfig->Opt_tsm ) { - FOR(Word16 ind2 = 0; ind2 < 960; ind2++) + FOR( Word16 ind1 = 0; ind1 < len + 2; ind1++ ) { - st_ivas->hTcBuffer->tc[ind1][ind2] = (float)(st_ivas->hTcBuffer->tc_fx[ind1][ind2]) / (float)(1 << q_output); + FOR( Word16 ind2 = 0; ind2 < 960; ind2++ ) + { + st_ivas->hTcBuffer->tc[ind1][ind2] = fixedToFloat(st_ivas->hTcBuffer->tc_fx[ind1][ind2], q_output); + } } } FOR(Word16 ind1 = 0; ind1 < st_ivas->hMasaIsmData->delayBuffer_nchan; ind1++) { FOR(Word16 ind2 = 0; ind2 < st_ivas->hMasaIsmData->delayBuffer_size; ind2++) { - st_ivas->hMasaIsmData->delayBuffer[ind1][ind2] = (float)(st_ivas->hMasaIsmData->delayBuffer_fx[ind1][ind2]) / (float)(1 << q_output); + st_ivas->hMasaIsmData->delayBuffer[ind1][ind2] = fixedToFloat(st_ivas->hMasaIsmData->delayBuffer_fx[ind1][ind2], q_output); } } FOR ( Word16 k = 0; k < st_ivas->hIsmRendererData->interpolator_length; k++ ) { st_ivas->hIsmRendererData->interpolator[k] = (float)st_ivas->hIsmRendererData->interpolator_fx[k] / (float)(1<<15); } + + //dbgwrite2_txt(output_f[1],960,"../omasa_soutput_f.txt"); #else ivas_omasa_separate_object_render_jbm( st_ivas, *nSamplesRendered, data_separated_objects, output_f, subframes_rendered, slots_rendered ); #endif diff --git a/lib_dec/ivas_out_setup_conversion.c b/lib_dec/ivas_out_setup_conversion.c index e8b76a64f..cee1062b1 100644 --- a/lib_dec/ivas_out_setup_conversion.c +++ b/lib_dec/ivas_out_setup_conversion.c @@ -1718,6 +1718,346 @@ void ivas_ls_setup_conversion_process_mdct( * * Equalization in MDCT Domain *-------------------------------------------------------------------------*/ +#ifdef IVAS_FLOAT_FIXED +void ivas_ls_setup_conversion_process_mdct_param_mc_fx( + Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ + Word32 *x_fx[][NB_DIV], + Word16 x_e[MAX_CICP_CHANNELS][NB_DIV] /* i/o: Exponent for output synthesis signal */ +) +{ + Word32 targetEnergy_fx[MAX_SFB + 2], dmxEnergy_fx[MAX_SFB + 2]; + Word32 eqGain_fx; + Word32 *sig_fx[MAX_CICP_CHANNELS][NB_DIV], *pTmp_fx[NB_DIV]; + Word32 mdst_fx[MAX_CICP_CHANNELS][L_FRAME48k]; + Word32 convertRes_fx[MAX_CICP_CHANNELS][L_FRAME48k]; + Word32 cx_fx[PARAM_MC_MAX_PARAMETER_BANDS][PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS]; + Word32 cx_imag_fx[PARAM_MC_MAX_PARAMETER_BANDS][PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS]; + Word32 cy_fx[MAX_CICP_CHANNELS * MAX_CICP_CHANNELS]; + Word32 real_in_buffer_fx[PARAM_MC_MAX_BANDS_IN_PARAMETER_BAND * PARAM_MC_BAND_TO_MDCT_BAND_RATIO * MAX_TRANSPORT_CHANNELS]; + Word32 imag_in_buffer_fx[PARAM_MC_MAX_BANDS_IN_PARAMETER_BAND * PARAM_MC_BAND_TO_MDCT_BAND_RATIO * MAX_TRANSPORT_CHANNELS]; + Word32 real_buffer_fx[PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS]; + Word32 imag_buffer_fx[PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS]; + Word32 Nrqq_fx[MAX_OUTPUT_CHANNELS]; + Word32 target_ch_ener_fx[MAX_OUTPUT_CHANNELS]; + Word16 *ild_q_fx; + + Word32 DMXEne_fx; + Word32 dmxCoeff_fx; + Word32 dmxSignalReal_fx[L_FRAME48k], dmxSignalImag_fx[L_FRAME48k]; + + Word32 tmpReal_fx, tmpImag_fx; + Word32 tmpDMXSig_fx; + + /* Declaration of all required variables */ + Word16 i; + Word16 idx; + Word16 nchan_transport, nchan_out, nchan_transport_format; + Word16 chInIdx, chOutIdx, cpe_idx, subFrameIdx, binIdx; + Word16 band, bandIdx, num_bands; + + Word16 num_CPE; + Word16 transform_type[MAX_CICP_CHANNELS][2]; + Word16 frameSize; + + Word16 start, stop, start_tcx5, stop_tcx5; + Word16 mct_chan_mode[MAX_CICP_CHANNELS]; + + /* Declare all handles */ + LSSETUP_CONVERSION_HANDLE hLsSetUpConversion; + CPE_DEC_HANDLE hCPE[MCT_MAX_BLOCKS]; + PARAM_MC_DEC_HANDLE hParamMC; + + /* Step 0: Set the buffers to zero */ + set_zero_fx( dmxSignalReal_fx, L_FRAME48k ); + set_zero_fx( dmxSignalImag_fx, L_FRAME48k ); + + /* Assign all the declared variables */ + nchan_transport = st_ivas->nchan_transport; + nchan_out = st_ivas->hDecoderConfig->nchan_out; + num_CPE = st_ivas->nCPE; + nchan_transport_format = add(st_ivas->hTransSetup.nchan_out_woLFE , st_ivas->hTransSetup.num_lfe); + hLsSetUpConversion = st_ivas->hLsSetUpConversion; + /* Assign all the declared handles*/ + FOR( cpe_idx = 0; cpe_idx < num_CPE; cpe_idx++ ) + { + hCPE[cpe_idx] = st_ivas->hCPE[cpe_idx]; + } + hParamMC = st_ivas->hParamMC; + + /* Get the core type */ + FOR( cpe_idx = 0; cpe_idx < num_CPE; cpe_idx++ ) + { + FOR( idx = 0; idx < CPE_CHANNELS; idx++ ) + { + /* get the channel index */ + chInIdx = add(imult1616(cpe_idx , CPE_CHANNELS) , idx); + assert( chInIdx <= nchan_transport ); + transform_type[chInIdx][0] = hCPE[cpe_idx]->hCoreCoder[idx]->transform_type[0]; + transform_type[chInIdx][1] = hCPE[cpe_idx]->hCoreCoder[idx]->transform_type[1]; + mct_chan_mode[chInIdx] = hCPE[cpe_idx]->hCoreCoder[idx]->mct_chan_mode; + } + } + + /* set overall frequency resolution of (sub)frame to maximum of (sub)frame, requires conversion if both channels are not the same */ + frameSize = hLsSetUpConversion->sfbOffset[hLsSetUpConversion->sfbCnt]; + set_zero_fx( targetEnergy_fx, MAX_SFB + 2 ); + set_zero_fx( dmxEnergy_fx, MAX_SFB + 2 ); + + FOR ( chInIdx = 0; chInIdx < nchan_transport; chInIdx++ ) + { + IF ( NE_16(mct_chan_mode[chInIdx] , MCT_CHAN_MODE_IGNORE) ) + { + /* initially, set pointers to input; if conversion occurs in (sub)frame, set to convertRes */ + sig_fx[chInIdx][0] = pTmp_fx[0] = x_fx[chInIdx][0]; /*Q=31-x_e[chInIdx][0]*/ + sig_fx[chInIdx][1] = pTmp_fx[1] = x_fx[chInIdx][1]; /*Q=31-x_e[chInIdx][1]*/ + /* convert (sub)frames to higher frequency resolution */ + IF ( NE_16(transform_type[chInIdx][0] , TCX_20) ) + { + FOR ( subFrameIdx = 0; subFrameIdx < NB_DIV; subFrameIdx++ ) + { + IF ( EQ_16(transform_type[chInIdx][subFrameIdx] , TCX_5) ) + { + /* subframe is TCX5, but TCX10 or TCX20 in other channel -> convert channel with TCX5 to TCX10 resolution */ + pTmp_fx[subFrameIdx] = sig_fx[chInIdx][subFrameIdx] = convertRes_fx[chInIdx] + subFrameIdx * frameSize / 2; + convert_coeffs_to_higher_res_fx( x_fx[chInIdx][subFrameIdx], x_fx[chInIdx][subFrameIdx] + frameSize / 4, pTmp_fx[subFrameIdx], frameSize / 4 ); /*Q=31-x_e[chInIdx][subFrameIdx]*/ + } + } + + /* convert channel with TCX10 to TCX20 resolution */ + sig_fx[chInIdx][0] = convertRes_fx[chInIdx]; + + // Scale_sig32(pTmp_fx_1_0, frameSize / 2, x_e[chInIdx][1] - x_e[chInIdx][0] ); /*Scaling down the Q from 31-x_e[chInIdx][1] to 31-x_e[chInIdx][0]*/ + convert_coeffs_to_higher_res_fx( pTmp_fx[0], pTmp_fx[1], sig_fx[chInIdx][0], frameSize / 2 ); /*Q=31-x_e[chInIdx][0]*/ + } + } + } + Word16 input_exp, output_exp=0; + + /* precalculate MDST estimate */ + FOR ( chInIdx = 0; chInIdx < nchan_transport; chInIdx++ ) + { + IF ( NE_16(mct_chan_mode[chInIdx] , MCT_CHAN_MODE_IGNORE) ) + { + mdst_fx[chInIdx][0] = mdst_fx[chInIdx][frameSize - 1] = 0; + FOR ( i = 1; i < frameSize - 1; i++ ) + { + mdst_fx[chInIdx][i] = L_sub( sig_fx[chInIdx][0][i + 1], sig_fx[chInIdx][0][i - 1] ); /*Q=31-x_e[chInIdx][0]*/ + } + } + } + + /* Step 1.1, calculate Cx from MDST estimate */ + FOR ( bandIdx = 0; bandIdx < PARAM_MC_MAX_PARAMETER_BANDS; bandIdx++ ) + { + set_zero_fx( cx_fx[bandIdx], PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS ); + set_zero_fx( cx_imag_fx[bandIdx], PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS ); + } + set_zero_fx( Nrqq_fx, MAX_OUTPUT_CHANNELS ); + set_zero_fx( target_ch_ener_fx, MAX_OUTPUT_CHANNELS ); + Word16 max_e = 0; + FOR ( idx = 0; idx < nchan_transport; idx++ ) + { + IF ( NE_16(mct_chan_mode[idx] , MCT_CHAN_MODE_IGNORE) ) + { + max_e = s_max( max_e, x_e[idx][0] ); + } + } + FOR ( bandIdx = 0; bandIdx < hLsSetUpConversion->sfbCnt; bandIdx++ ) + { + set_zero_fx( real_in_buffer_fx, PARAM_MC_MAX_BANDS_IN_PARAMETER_BAND * PARAM_MC_BAND_TO_MDCT_BAND_RATIO * MAX_TRANSPORT_CHANNELS ); + set_zero_fx( imag_in_buffer_fx, PARAM_MC_MAX_BANDS_IN_PARAMETER_BAND * PARAM_MC_BAND_TO_MDCT_BAND_RATIO * MAX_TRANSPORT_CHANNELS ); + set_zero_fx( real_buffer_fx, PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS ); + set_zero_fx( imag_buffer_fx, PARAM_MC_MAX_TRANSPORT_CHANS * PARAM_MC_MAX_TRANSPORT_CHANS ); + + start = hLsSetUpConversion->sfbOffset[bandIdx]; + stop = hLsSetUpConversion->sfbOffset[bandIdx + 1]; + num_bands = sub(stop , start); + + FOR ( i = 0; i < num_bands; i++ ) + { + band = start + i; + FOR ( idx = 0; idx < nchan_transport; idx++ ) + { + IF ( mct_chan_mode[idx] != MCT_CHAN_MODE_IGNORE ) + { + real_in_buffer_fx[i + num_bands * idx] = L_shr( sig_fx[idx][0][band], max_e - x_e[idx][0] ); /*Setting the exponent to max_e*/ + imag_in_buffer_fx[i + num_bands * idx] = L_shr( mdst_fx[idx][band], max_e - x_e[idx][0] ); /*Setting the exponent to max_e*/ + } + } + } + Word16 shift = 1; + FOR( i = 0; i < num_bands * nchan_transport; ++i ) + { + real_in_buffer_fx[i] = L_shr( real_in_buffer_fx[i], shift ); + imag_in_buffer_fx[i] = L_shr( imag_in_buffer_fx[i], shift ); + } + input_exp = max_e; + input_exp = add(input_exp,shift); + cmplx_matrix_square_fx( real_in_buffer_fx, imag_in_buffer_fx, num_bands, nchan_transport, real_buffer_fx, imag_buffer_fx, input_exp, &output_exp ); + v_add_32( cx_fx[bandIdx], real_buffer_fx, cx_fx[bandIdx], nchan_transport * nchan_transport ); /*Q=Q_real_buffer=Q_imag_buffer=output_exp*/ + v_add_32( cx_imag_fx[bandIdx], imag_buffer_fx, cx_imag_fx[bandIdx], nchan_transport * nchan_transport ); /*Q=Q_real_buffer=Q_imag_buffer=output_exp*/ + } + Word16 exp_in = 10, exp_out = 0; + FOR ( bandIdx = 0; bandIdx < hLsSetUpConversion->sfbCnt; bandIdx++ ) + { + DMXEne_fx = 0; + set_zero_fx( cy_fx, MAX_CICP_CHANNELS * MAX_CICP_CHANNELS ); + set_zero_fx( Nrqq_fx, MAX_OUTPUT_CHANNELS ); + set_zero_fx( target_ch_ener_fx, MAX_OUTPUT_CHANNELS ); + /* Step 1.2, get target channel energies for the transported format as in ivas_param_mc_get_mono_stereo_mixing_matrices(), Nrqq calculation */ + ild_q_fx = hParamMC->icld_q_fx + imult1616( bandIdx, hParamMC->hMetadataPMC->ild_mapping_conf->ild_map_size_lfe ); + FOR ( chInIdx = 0; chInIdx < nchan_transport_format; chInIdx++ ) + { + Word32 ref_ener_fx = 0; + Word16 ref_channel_cnt; + Word16 ref_channel_idx; + + FOR ( ref_channel_cnt = 0; ref_channel_cnt < hParamMC->hMetadataPMC->ild_mapping_conf->num_ref_channels[chInIdx]; ref_channel_cnt++ ) + { + ref_channel_idx = hParamMC->hMetadataPMC->ild_mapping_conf->ref_channel_idx[chInIdx][ref_channel_cnt]; + ref_ener_fx = L_add( ref_ener_fx, cx_fx[bandIdx][ref_channel_idx + ref_channel_idx * nchan_transport] ); /*Exponent=output_exp*/ + } + Word32 temp; + temp = BASOP_util_Pow2( L_mult0( ild_q_fx[chInIdx], 2721 /*log2(10)*(2^13)/10*/ ), exp_in, &exp_out ); + Nrqq_fx[hParamMC->hMetadataPMC->ild_mapping_conf->ild_index[chInIdx]] = L_shr( Mpy_32_16_1( ref_ener_fx, (Word16) Mpy_32_32( temp, hParamMC->hMetadataPMC->ild_factors_fx[chInIdx] ) ), 2 - exp_out ); /*exp=output_exp*/ + } + + /* Step 1.3 get target Cy like in ivas_param_mc_get_mono_stereo_mixing_matrices() (with dmx matrix from CICPX to MONO/STEREO saved in hParamMC) */ + FOR ( chOutIdx = 0; chOutIdx < nchan_out; chOutIdx++ ) + { + FOR ( i = 0; i < nchan_transport_format; i++ ) + { + IF ( EQ_32(hParamMC->ls_conv_dmx_matrix_fx[chOutIdx + i * nchan_out] , 32768) ) + hParamMC->ls_conv_dmx_matrix_fx[chOutIdx + i * nchan_out] = 32767; + target_ch_ener_fx[chOutIdx] = L_add( target_ch_ener_fx[chOutIdx], Mpy_32_16_1( Nrqq_fx[i], (Word16) hParamMC->ls_conv_dmx_matrix_fx[chOutIdx + i * nchan_out] ) ); /*output_exp + 2*/ + } + cy_fx[chOutIdx + nchan_out * chOutIdx] = target_ch_ener_fx[chOutIdx]; + } + + /* Step 1.4 final target energy for the band would then be the sum over the diagonal of Cy*/ + FOR ( chOutIdx = 0; chOutIdx < nchan_out; chOutIdx++ ) + { + targetEnergy_fx[bandIdx] = L_add( targetEnergy_fx[bandIdx], cy_fx[chOutIdx + nchan_out * chOutIdx] ); /*exp=output_exp+2*/ + } + + /* Step 2: Calculate DMX ener */ + start = hLsSetUpConversion->sfbOffset[bandIdx]; + stop = hLsSetUpConversion->sfbOffset[bandIdx + 1]; + + FOR ( chOutIdx = 0; chOutIdx < nchan_out; chOutIdx++ ) + { + FOR ( chInIdx = 0; chInIdx < nchan_transport; chInIdx++ ) + { + IF ( mct_chan_mode[chInIdx] != MCT_CHAN_MODE_IGNORE ) + { + dmxCoeff_fx = hLsSetUpConversion->dmxMtx_fx[chInIdx][chOutIdx]; + + /* Step 1: Compute the target energy and DMX signal (possible since we have all signals in TCX20 resolution) */ + IF ( dmxCoeff_fx ) + { + /* Loop over all the bins in the band */ + FOR ( binIdx = start; binIdx < stop; binIdx++ ) + { + tmpDMXSig_fx = Mult_32_32( dmxCoeff_fx, L_shr( sig_fx[chInIdx][0][binIdx], max_e - x_e[chInIdx][0] ) ); /*max_e+1*/ + dmxSignalReal_fx[binIdx] = L_add( dmxSignalReal_fx[binIdx], tmpDMXSig_fx ); + + tmpDMXSig_fx = Mult_32_32( dmxCoeff_fx, L_shr( mdst_fx[chInIdx][binIdx], max_e - x_e[chInIdx][0] ) ); /*max_e+1*/ + dmxSignalImag_fx[binIdx] = L_add( dmxSignalImag_fx[binIdx], tmpDMXSig_fx ); + } + } + } + } + /* Loop over all the bins in the band */ + DMXEne_fx = 0; + FOR ( binIdx = start; binIdx < stop; binIdx++ ) + { + tmpReal_fx = L_shr( dmxSignalReal_fx[binIdx], 1 ); + tmpImag_fx = L_shr( dmxSignalImag_fx[binIdx], 1 ); + + DMXEne_fx = L_add( DMXEne_fx, Mult_32_32( tmpReal_fx, tmpReal_fx ) + Mult_32_32( tmpImag_fx, tmpImag_fx ) ); /*2*(max_e + 2)*/ + } + } + + dmxEnergy_fx[bandIdx] = DMXEne_fx; /*2*(max_e+2)*/ + } + + /* Step 3: Peform energy smoothing */ + FOR ( bandIdx = 0; bandIdx < hLsSetUpConversion->sfbCnt; bandIdx++ ) + { + targetEnergy_fx[bandIdx] = L_add( Mult_32_32( LS_OUT_CONV_SMOOTHING_FACTOR_Q31, targetEnergy_fx[bandIdx] ), Mult_32_32( L_sub( MAX_32, LS_OUT_CONV_SMOOTHING_FACTOR_Q31 ), L_shr( hLsSetUpConversion->targetEnergyPrev_fx[0][bandIdx], output_exp + 2 - hLsSetUpConversion->te_prev_exp ) ) ); /*output_exp + 2*/ + dmxEnergy_fx[bandIdx] = L_add( Mult_32_32( LS_OUT_CONV_SMOOTHING_FACTOR_Q31, dmxEnergy_fx[bandIdx] ), Mult_32_32( L_sub( MAX_32, LS_OUT_CONV_SMOOTHING_FACTOR_Q31 ), L_shr( hLsSetUpConversion->dmxEnergyPrev_fx[0][bandIdx], 2 * ( max_e + 2 ) - hLsSetUpConversion->dmx_prev_exp ) ) ); /*2 * (max_e + 2)*/ + hLsSetUpConversion->targetEnergyPrev_fx[0][bandIdx] = targetEnergy_fx[bandIdx]; + hLsSetUpConversion->dmxEnergyPrev_fx[0][bandIdx] = dmxEnergy_fx[bandIdx]; + } + hLsSetUpConversion->te_prev_exp = output_exp + 2; + hLsSetUpConversion->dmx_prev_exp = 2 * ( max_e + 2 ); + /* Step 4: Perform equalization */ + FOR ( chInIdx = 0; chInIdx < nchan_transport; chInIdx++ ) + { + IF ( NE_16(mct_chan_mode[chInIdx] , MCT_CHAN_MODE_IGNORE) ) + { + IF ( EQ_16(transform_type[chInIdx][0] , TCX_20) ) + { + /*TCX20*/ + FOR ( bandIdx = 0; bandIdx < hLsSetUpConversion->sfbCnt; bandIdx++ ) + { + start = hLsSetUpConversion->sfbOffset[bandIdx]; + stop = hLsSetUpConversion->sfbOffset[bandIdx + 1]; + + /*Compute Eq gains */ + ivas_lssetupconversion_computeEQFactor_fx( &targetEnergy_fx[bandIdx], &dmxEnergy_fx[bandIdx], &eqGain_fx ); + + FOR ( binIdx = start; binIdx < stop; binIdx++ ) + { + x_fx[chInIdx][0][binIdx] = L_shl( Mult_32_32( x_fx[chInIdx][0][binIdx], eqGain_fx ), 1 ); + } + } + } + ELSE + { + stop_tcx5 = 0; + FOR ( bandIdx = 0; bandIdx < hLsSetUpConversion->sfbCnt; bandIdx++ ) + { + start = hLsSetUpConversion->sfbOffset[bandIdx] / 2; + stop = hLsSetUpConversion->sfbOffset[bandIdx + 1] / 2; + + /*Compute Eq gains */ + ivas_lssetupconversion_computeEQFactor_fx( &targetEnergy_fx[bandIdx], &dmxEnergy_fx[bandIdx], &eqGain_fx ); + + + FOR ( subFrameIdx = 0; subFrameIdx < NB_DIV; subFrameIdx++ ) + { + IF ( EQ_16(transform_type[chInIdx][subFrameIdx] , TCX_10) ) + { + /*TCX10*/ + FOR ( binIdx = start; binIdx < stop; binIdx++ ) + { + x_fx[chInIdx][subFrameIdx][binIdx] = L_shl( Mult_32_32( x_fx[chInIdx][subFrameIdx][binIdx], eqGain_fx ), 1 ); + } + } + ELSE + { + /* TCX5*/ + start_tcx5 = stop_tcx5; + stop_tcx5 = ( stop + 1 ) / 2; + FOR ( binIdx = start_tcx5; binIdx < stop_tcx5; binIdx++ ) + { + x_fx[chInIdx][subFrameIdx][binIdx] = L_shl( Mult_32_32( x_fx[chInIdx][subFrameIdx][binIdx], eqGain_fx ), 1 ); + } + + FOR ( binIdx = start_tcx5; binIdx < stop_tcx5; binIdx++ ) + { + x_fx[chInIdx][subFrameIdx][binIdx + ( frameSize >> 2 )] = L_shl( Mult_32_32( x_fx[chInIdx][subFrameIdx][binIdx + ( frameSize >> 2 )], eqGain_fx ), 1 ); + } + } + } + } + } + } + } + return; +} +#endif // IVAS_FLOAT_FIXED void ivas_ls_setup_conversion_process_mdct_param_mc( Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ diff --git a/lib_dec/ivas_stat_dec.h b/lib_dec/ivas_stat_dec.h index 2e7cc53d3..6993ad0ba 100644 --- a/lib_dec/ivas_stat_dec.h +++ b/lib_dec/ivas_stat_dec.h @@ -615,8 +615,14 @@ typedef struct param_ism_rendering Word16 *interpolator_fx; Word32 *Cldfb_RealBuffer_tc_fx; Word16 *Cldfb_RealBuffer_tc_e; + Word16 Cldfb_RealBuffer_tc_exp; Word32 *Cldfb_ImagBuffer_tc_fx; Word16 *Cldfb_ImagBuffer_tc_e; + Word16 Cldfb_ImagBuffer_tc_exp; + Word32 mixing_matrix_lin_fx[CLDFB_NO_CHANNELS_MAX][PARAM_ISM_MAX_CHAN * PARAM_ISM_MAX_DMX]; + Word16 exp_mixing_matrix_lin_fx; + Word32 mixing_matrix_lin_old_fx[CLDFB_NO_CHANNELS_MAX][PARAM_ISM_MAX_CHAN * PARAM_ISM_MAX_DMX]; + Word16 exp_mixing_matrix_lin_old_fx; #endif // IVAS_FLOAT_FIXED float *proto_matrix; float *interpolator; diff --git a/lib_dec/ivas_stereo_mdct_core_dec_fx.c b/lib_dec/ivas_stereo_mdct_core_dec_fx.c index 8e14ab91c..05ab00c23 100644 --- a/lib_dec/ivas_stereo_mdct_core_dec_fx.c +++ b/lib_dec/ivas_stereo_mdct_core_dec_fx.c @@ -643,7 +643,7 @@ void stereo_mdct_core_dec_fx( #ifdef IVAS_FLOAT_FIXED #if 1 /*Float to fixed conversion*/ Word32 Aq_fx[2][102]; - Word16 x_e[2][2]; + Word16 x_e[MAX_CICP_CHANNELS][2] = { 0 }; Word32 *x_fx[CPE_CHANNELS][NB_DIV]; FOR( Word16 ind = 0; ind < 2; ind++ ) { @@ -722,21 +722,36 @@ void stereo_mdct_core_dec_fx( } } } - FOR( Word16 i = 0; i < CPE_CHANNELS; i++ ) - { - FOR( Word16 j = 0; j < NB_DIV; j++ ) - { - free( x_fx[i][j] ); - } - } #endif #else ivas_mdct_core_tns_ns( hCPE, fUseTns, tnsData, x, Aq, 0 ); #endif - } if ( st_ivas->renderer_type == RENDERER_MC_PARAMMC && ( st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_MONO || st_ivas->hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_STEREO ) ) { +#ifdef IVAS_FLOAT_FIXED + f2me_buf( st_ivas->hLsSetUpConversion->targetEnergyPrev[0], st_ivas->hLsSetUpConversion->targetEnergyPrev_fx[0], &st_ivas->hLsSetUpConversion->te_prev_exp, st_ivas->hLsSetUpConversion->sfbCnt ); + f2me_buf( st_ivas->hLsSetUpConversion->dmxEnergyPrev[0], st_ivas->hLsSetUpConversion->dmxEnergyPrev_fx[0], &st_ivas->hLsSetUpConversion->dmx_prev_exp, st_ivas->hLsSetUpConversion->sfbCnt ); + FOR(Word16 chOutIdx = 0; chOutIdx < st_ivas->hDecoderConfig->nchan_out; chOutIdx++ ) + { + FOR(Word16 chInIdx = 0; chInIdx < st_ivas->nchan_transport; chInIdx++ ) + { + st_ivas->hLsSetUpConversion->dmxMtx_fx[chInIdx][chOutIdx] = float_to_fix( st_ivas->hLsSetUpConversion->dmxMtx[chInIdx][chOutIdx], 30 ); /*Q30*/ + } + } + ivas_ls_setup_conversion_process_mdct_param_mc_fx( st_ivas, x_fx, x_e ); + me2f_buf( st_ivas->hLsSetUpConversion->targetEnergyPrev_fx[0], st_ivas->hLsSetUpConversion->te_prev_exp, st_ivas->hLsSetUpConversion->targetEnergyPrev[0], st_ivas->hLsSetUpConversion->sfbCnt ); + me2f_buf( st_ivas->hLsSetUpConversion->dmxEnergyPrev_fx[0], st_ivas->hLsSetUpConversion->dmx_prev_exp, st_ivas->hLsSetUpConversion->dmxEnergyPrev[0], st_ivas->hLsSetUpConversion->sfbCnt ); +#else ivas_ls_setup_conversion_process_mdct_param_mc( st_ivas, x ); +#endif // IVAS_FLOAT_FIXED + } + FOR( Word16 i = 0; i < CPE_CHANNELS; i++ ) + { + FOR( Word16 j = 0; j < NB_DIV; j++ ) + { + free( x_fx[i][j] ); + } + } } run_min_stats_fx( sts, x ); diff --git a/lib_rend/ivas_stat_rend.h b/lib_rend/ivas_stat_rend.h index 0edbd69a4..478e84c65 100644 --- a/lib_rend/ivas_stat_rend.h +++ b/lib_rend/ivas_stat_rend.h @@ -1947,6 +1947,10 @@ typedef struct ivas_LS_setupconversion_struct Word32 *dmxEnergyPrev_fx[MAX_OUTPUT_CHANNELS]; int16_t sfbOffset[MAX_SFB + 2]; int16_t sfbCnt; +#ifdef IVAS_FLOAT_FIXED + Word16 te_prev_exp; + Word16 dmx_prev_exp; +#endif // IVAS_FLOAT_FIXED } LSSETUP_CONVERSION_STRUCT, *LSSETUP_CONVERSION_HANDLE; -- GitLab