From d54739f5163454c8e10a5a834355533b485586a0 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Mon, 29 Apr 2024 19:43:26 +0530 Subject: [PATCH 1/3] Restore float funcs, dirac dec and stat_dec struct cleanup --- lib_dec/acelp_core_dec.c | 4 +- lib_dec/ivas_binRenderer_internal.c | 2 +- lib_dec/ivas_core_dec.c | 15 +- lib_dec/ivas_corecoder_dec_reconfig.c | 4 +- lib_dec/ivas_cpe_dec_fx.c | 102 +--- lib_dec/ivas_dirac_dec.c | 650 +++++++++++++------------ lib_dec/ivas_init_dec.c | 28 +- lib_dec/ivas_ism_dec.c | 14 +- lib_dec/ivas_jbm_dec.c | 145 +----- lib_dec/ivas_mct_dec.c | 8 +- lib_dec/ivas_omasa_dec.c | 16 +- lib_dec/ivas_pca_dec.c | 3 +- lib_dec/ivas_sba_dec.c | 14 +- lib_dec/ivas_sba_dirac_stereo_dec_fx.c | 1 + lib_dec/ivas_sba_rendering_internal.c | 7 +- lib_dec/ivas_spar_decoder.c | 2 +- lib_dec/ivas_stat_dec.h | 18 +- lib_dec/ivas_stereo_dft_dec.c | 309 +++++++++++- lib_dec/ivas_stereo_dft_dec_fx.c | 21 +- lib_dec/ivas_stereo_icbwe_dec.c | 7 +- 20 files changed, 721 insertions(+), 649 deletions(-) diff --git a/lib_dec/acelp_core_dec.c b/lib_dec/acelp_core_dec.c index 9146adea3..325bfc5b5 100644 --- a/lib_dec/acelp_core_dec.c +++ b/lib_dec/acelp_core_dec.c @@ -612,11 +612,11 @@ ivas_error acelp_core_dec( nb_bits = -1; } - config_acelp1( DEC, st->total_brate, st->core_brate, st->core, st->extl_orig, st->extl_brate_orig, st->L_frame, st->GSC_noisy_speech, &( st->acelp_cfg ), st->next_bit_pos, st->coder_type, tc_subfr_tmp, 1, &nb_bits, unbits, st->element_mode, &uc_two_stage_flag, tdm_lp_reuse_flag, tdm_low_rate_mode, st->idchan, st->active_cnt, tdm_Pitch_reuse_flag, st->tdm_LRTD_flag, st->GSC_IVAS_mode ); + config_acelp1_IVAS( DEC, st->total_brate, st->core_brate, st->core, st->extl_orig, st->extl_brate_orig, st->L_frame, st->GSC_noisy_speech, &( st->acelp_cfg ), st->next_bit_pos, st->coder_type, tc_subfr_tmp, 1, &nb_bits, unbits, st->element_mode, &uc_two_stage_flag, tdm_lp_reuse_flag, tdm_low_rate_mode, st->idchan, st->active_cnt, tdm_Pitch_reuse_flag, st->tdm_LRTD_flag, st->GSC_IVAS_mode ); if ( st->coder_type == TRANSITION && tc_subfr < L_SUBFR && st->L_frame == L_FRAME ) { - config_acelp1( DEC, st->total_brate, st->core_brate, st->core, st->extl_orig, st->extl_brate_orig, st->L_frame, -1, &( st->acelp_cfg ), st->next_bit_pos, st->coder_type, tc_subfr, 2, &nb_bits, unbits, st->element_mode, &uc_two_stage_flag, tdm_lp_reuse_flag, tdm_low_rate_mode, st->idchan, st->active_cnt, tdm_Pitch_reuse_flag, st->tdm_LRTD_flag, st->GSC_IVAS_mode ); + config_acelp1_IVAS( DEC, st->total_brate, st->core_brate, st->core, st->extl_orig, st->extl_brate_orig, st->L_frame, -1, &( st->acelp_cfg ), st->next_bit_pos, st->coder_type, tc_subfr, 2, &nb_bits, unbits, st->element_mode, &uc_two_stage_flag, tdm_lp_reuse_flag, tdm_low_rate_mode, st->idchan, st->active_cnt, tdm_Pitch_reuse_flag, st->tdm_LRTD_flag, st->GSC_IVAS_mode ); } } diff --git a/lib_dec/ivas_binRenderer_internal.c b/lib_dec/ivas_binRenderer_internal.c index f5c63a08e..cd17505e1 100644 --- a/lib_dec/ivas_binRenderer_internal.c +++ b/lib_dec/ivas_binRenderer_internal.c @@ -2459,7 +2459,7 @@ void ivas_binRenderer_fx( /* memory reset for the binaural output */ FOR(chIdx = 0; chIdx < BINAURAL_CHANNELS; chIdx++) { - FOR(k = 0; k < numTimeSlots; k++) + FOR(k = 0; k < MAX_PARAM_SPATIAL_SUBFRAMES; k++) { set32_fx(Cldfb_RealBuffer_Binaural_fx[chIdx][k], 0, CLDFB_NO_CHANNELS_MAX); set32_fx(Cldfb_ImagBuffer_Binaural_fx[chIdx][k], 0, CLDFB_NO_CHANNELS_MAX); diff --git a/lib_dec/ivas_core_dec.c b/lib_dec/ivas_core_dec.c index 0ad040129..fd93643d2 100644 --- a/lib_dec/ivas_core_dec.c +++ b/lib_dec/ivas_core_dec.c @@ -1162,7 +1162,7 @@ ivas_error ivas_core_dec( if ( hCPE->hStereoDft != NULL ) { - floatToFixed_arrL( hCPE->hStereoDft->hb_stefi_sig, hCPE->hStereoDft->hb_stefi_sig_fx, q, L_FRAME48k + NS2SA( 48000, STEREO_DFT_TD_STEFI_DELAY_NS ) ); + //floatToFixed_arrL( hCPE->hStereoDft->hb_stefi_sig, hCPE->hStereoDft->hb_stefi_sig_fx, q, L_FRAME48k + NS2SA( 48000, STEREO_DFT_TD_STEFI_DELAY_NS ) ); hCPE->hStereoDft->td_gain_fx[0] = 1; } Scale_sig( tmp_buffer_fx, L_FRAME48k, Q11 - Q_white_exc ); @@ -1171,19 +1171,6 @@ ivas_error ivas_core_dec( Scale_sig32(hb_synth_32_fx[0], L_FRAME48k, sub(Q11 , q)); Scale_sig32(hb_synth_32_fx[1], L_FRAME48k, sub(Q11 , q)); - if ( hCPE->hStereoDft != NULL ) - { - - fixedToFloat_arrL( hCPE->hStereoDft->hb_stefi_sig_fx, hCPE->hStereoDft->hb_stefi_sig, 16, L_FRAME48k + NS2SA( 48000, STEREO_DFT_TD_STEFI_DELAY_NS ) ); - hCPE->hStereoDft->hb_nrg_subr[0] = (float) hCPE->hStereoDft->hb_nrg_subr_fx[0] / ( 1u << hCPE->hStereoDft->Q_nrg_subr ); - hCPE->hStereoDft->hb_nrg_subr[1] = (float) hCPE->hStereoDft->hb_nrg_subr_fx[1] / ( 1u << hCPE->hStereoDft->Q_nrg_subr ); - hCPE->hStereoDft->hb_nrg[0] = (float) hCPE->hStereoDft->hb_nrg_fx[0] / ( 1u << ( hCPE->hStereoDft->Q_nrg_subr + 9 ) ); - - if ( hCPE->hStereoDft->td_gain_fx[0] == 0 ) - { - hCPE->hStereoDft->td_gain[0] = 0; - } - } } IF( EQ_16( st->element_mode, EVS_MONO ) ) diff --git a/lib_dec/ivas_corecoder_dec_reconfig.c b/lib_dec/ivas_corecoder_dec_reconfig.c index 67f65d1af..bae8ece3c 100644 --- a/lib_dec/ivas_corecoder_dec_reconfig.c +++ b/lib_dec/ivas_corecoder_dec_reconfig.c @@ -864,7 +864,7 @@ ivas_error ivas_hp20_dec_reconfig_fx( return error; } -#endif +#else ivas_error ivas_hp20_dec_reconfig( Decoder_Struct *st_ivas, /* i/o: IVAS decoder structure */ const int16_t nchan_hp20_old /* i : number of HP20 filters in previous frame */ @@ -941,7 +941,7 @@ ivas_error ivas_hp20_dec_reconfig( return error; } - +#endif /*-------------------------------------------------------------------* * ivas_cldfb_dec_reconfig() diff --git a/lib_dec/ivas_cpe_dec_fx.c b/lib_dec/ivas_cpe_dec_fx.c index d6b5c3d6d..373b15f1a 100644 --- a/lib_dec/ivas_cpe_dec_fx.c +++ b/lib_dec/ivas_cpe_dec_fx.c @@ -704,60 +704,13 @@ ivas_error ivas_cpe_dec_fx( scale_sig32( hCPE->hStereoDft->res_cod_mem_fx, STEREO_DFT_OVL_8k, sub( hCPE->hStereoDft->q_dft, hCPE->hStereoDft->q_res_cod_mem_fx ) ); hCPE->hStereoDft->q_res_cod_mem_fx = hCPE->hStereoDft->q_dft; - for ( int ii = 0; ii < sizeof( hCPE->hStereoDft->hb_nrg_subr_fx ) / sizeof( hCPE->hStereoDft->hb_nrg_subr_fx[0] ); ii++ ) - { - if ( l_hb_nrg_subr < hCPE->hStereoDft->hb_nrg_subr[ii] ) - { - l_hb_nrg_subr = hCPE->hStereoDft->hb_nrg_subr[ii]; - } - } - hCPE->hStereoDft->q_hb_nrg_subr = 0; - if ( l_hb_nrg_subr > (float) MAX_32 ) - { - int quotient = (int) ceil( l_hb_nrg_subr / (float) MAX_32 ); - hCPE->hStereoDft->q_hb_nrg_subr = Q31 - norm_l( quotient ); - } - for ( int ii = 0; ii < sizeof( hCPE->hStereoDft->hb_nrg_subr_fx ) / sizeof( hCPE->hStereoDft->hb_nrg_subr_fx[0] ); ii++ ) - { - hCPE->hStereoDft->hb_nrg_subr_fx[ii] = (Word32) ( hCPE->hStereoDft->hb_nrg_subr[ii] / ( (float) ( 1 << hCPE->hStereoDft->q_hb_nrg_subr ) ) ); - } - - - for ( int ii = 0; ii < sizeof( hCPE->hStereoDft->hb_nrg_fx ) / sizeof( hCPE->hStereoDft->hb_nrg_fx[0] ); ii++ ) - { - if ( l_hb_nrg < hCPE->hStereoDft->hb_nrg[ii] ) - { - l_hb_nrg = hCPE->hStereoDft->hb_nrg[ii]; - } - } - hCPE->hStereoDft->q_hb_nrg = 0; - if ( l_hb_nrg > (float) MAX_32 ) - { - int quotient = (int) ceil( l_hb_nrg / (float) MAX_32 ); - hCPE->hStereoDft->q_hb_nrg = Q31 - norm_l( quotient ); - } - for ( int ii = 0; ii < sizeof( hCPE->hStereoDft->hb_nrg_fx ) / sizeof( hCPE->hStereoDft->hb_nrg_fx[0] ); ii++ ) - { - hCPE->hStereoDft->hb_nrg_fx[ii] = (Word32) ( hCPE->hStereoDft->hb_nrg[ii] / ( (float) ( 1 << hCPE->hStereoDft->q_hb_nrg ) ) ); - } - floatToFixed_arr( &hCPE->hStereoCng->cm[0], &hCPE->hStereoCng->cm_fx[0], Q15, sizeof( hCPE->hStereoCng->cm_fx ) / sizeof( hCPE->hStereoCng->cm_fx[0] ) ); #endif stereo_dft_unify_dmx_fx( hCPE->hStereoDft, sts[0], DFT_fx, hCPE->input_mem_fx[1], hCPE->hStereoCng->prev_sid_nodata ); #if 1 scale_sig32( hCPE->hStereoDft->res_cod_mem_fx, STEREO_DFT_OVL_8k, sub( Q16, hCPE->hStereoDft->q_res_cod_mem_fx ) ); hCPE->hStereoDft->q_res_cod_mem_fx = Q16; - - for ( int ii = 0; ii < sizeof( hCPE->hStereoDft->hb_nrg_subr_fx ) / sizeof( hCPE->hStereoDft->hb_nrg_subr_fx[0] ); ii++ ) - { - hCPE->hStereoDft->hb_nrg_subr[0] = ( (float) hCPE->hStereoDft->hb_nrg_subr_fx[0] * ( (float) ( 1 << hCPE->hStereoDft->q_hb_nrg_subr ) ) ); - } - for ( int ii = 0; ii < sizeof( hCPE->hStereoDft->hb_nrg_fx ) / sizeof( hCPE->hStereoDft->hb_nrg_fx[0] ); ii++ ) - { - hCPE->hStereoDft->hb_nrg[ii] = ( (float) hCPE->hStereoDft->hb_nrg_fx[ii] * ( (float) ( 1 << hCPE->hStereoDft->q_hb_nrg ) ) ); - } fixedToFloat_arr( &hCPE->hStereoCng->cm_fx[0], &hCPE->hStereoCng->cm[0], Q15, sizeof( hCPE->hStereoCng->cm_fx ) / sizeof( hCPE->hStereoCng->cm_fx[0] ) ); - fixedToFloat_arrL( &hCPE->hStereoDft->td_gain_fx[0], &hCPE->hStereoDft->td_gain[0], Q15, sizeof( hCPE->hStereoDft->td_gain_fx ) / sizeof( hCPE->hStereoDft->td_gain_fx[0] ) ); #endif } ELSE @@ -777,60 +730,13 @@ ivas_error ivas_cpe_dec_fx( scale_sig32( hCPE->hStereoDft->res_cod_mem_fx, STEREO_DFT_OVL_8k, sub( hCPE->hStereoDft->q_dft, hCPE->hStereoDft->q_res_cod_mem_fx ) ); hCPE->hStereoDft->q_res_cod_mem_fx = hCPE->hStereoDft->q_dft; - - for ( int ii = 0; ii < sizeof( hCPE->hStereoDft->hb_nrg_subr_fx ) / sizeof( hCPE->hStereoDft->hb_nrg_subr_fx[0] ); ii++ ) - { - if ( l_hb_nrg_subr < hCPE->hStereoDft->hb_nrg_subr[ii] ) - { - l_hb_nrg_subr = hCPE->hStereoDft->hb_nrg_subr[ii]; - } - } - hCPE->hStereoDft->q_hb_nrg_subr = 0; - if ( l_hb_nrg_subr > (float) MAX_32 ) - { - int quotient = (int) ceil( l_hb_nrg_subr / (float) MAX_32 ); - hCPE->hStereoDft->q_hb_nrg_subr = Q31 - norm_l( quotient ); - } - for ( int ii = 0; ii < sizeof( hCPE->hStereoDft->hb_nrg_subr_fx ) / sizeof( hCPE->hStereoDft->hb_nrg_subr_fx[0] ); ii++ ) - { - hCPE->hStereoDft->hb_nrg_subr_fx[ii] = (Word32) ( hCPE->hStereoDft->hb_nrg_subr[ii] / ( (float) ( 1 << hCPE->hStereoDft->q_hb_nrg_subr ) ) ); - } - - - for ( int ii = 0; ii < sizeof( hCPE->hStereoDft->hb_nrg_fx ) / sizeof( hCPE->hStereoDft->hb_nrg_fx[0] ); ii++ ) - { - if ( l_hb_nrg < hCPE->hStereoDft->hb_nrg[ii] ) - { - l_hb_nrg = hCPE->hStereoDft->hb_nrg[ii]; - } - } - hCPE->hStereoDft->q_hb_nrg = 0; - if ( l_hb_nrg > (float) MAX_32 ) - { - int quotient = (int) ceil( l_hb_nrg / (float) MAX_32 ); - hCPE->hStereoDft->q_hb_nrg = Q31 - norm_l( quotient ); - } - for ( int ii = 0; ii < sizeof( hCPE->hStereoDft->hb_nrg_fx ) / sizeof( hCPE->hStereoDft->hb_nrg_fx[0] ); ii++ ) - { - hCPE->hStereoDft->hb_nrg_fx[ii] = (Word32) ( hCPE->hStereoDft->hb_nrg[ii] / ( (float) ( 1 << hCPE->hStereoDft->q_hb_nrg ) ) ); - } - floatToFixed_arr( &hCPE->hStereoCng->cm[0], &hCPE->hStereoCng->cm_fx[0], Q15, sizeof( hCPE->hStereoCng->cm_fx ) / sizeof( hCPE->hStereoCng->cm_fx[0] ) ); } #endif stereo_dft_dec_fx( hCPE->hStereoDft, sts[0], DFT_fx, hCPE->input_mem_fx[1], hCPE->hStereoCng, 0, 0, 0, 0, 0, 0, MAX_PARAM_SPATIAL_SUBFRAMES ); #if 1 { - for ( int ii = 0; ii < sizeof( hCPE->hStereoDft->hb_nrg_subr_fx ) / sizeof( hCPE->hStereoDft->hb_nrg_subr_fx[0] ); ii++ ) - { - hCPE->hStereoDft->hb_nrg_subr[0] = ( (float) hCPE->hStereoDft->hb_nrg_subr_fx[0] * ( (float) ( 1 << hCPE->hStereoDft->q_hb_nrg_subr ) ) ); - } - for ( int ii = 0; ii < sizeof( hCPE->hStereoDft->hb_nrg_fx ) / sizeof( hCPE->hStereoDft->hb_nrg_fx[0] ); ii++ ) - { - hCPE->hStereoDft->hb_nrg[ii] = ( (float) hCPE->hStereoDft->hb_nrg_fx[ii] * ( (float) ( 1 << hCPE->hStereoDft->q_hb_nrg ) ) ); - } fixedToFloat_arr( &hCPE->hStereoCng->cm_fx[0], &hCPE->hStereoCng->cm[0], Q15, sizeof( hCPE->hStereoCng->cm_fx ) / sizeof( hCPE->hStereoCng->cm_fx[0] ) ); - fixedToFloat_arrL( &hCPE->hStereoDft->td_gain_fx[0], &hCPE->hStereoDft->td_gain[0], Q15, sizeof( hCPE->hStereoDft->td_gain_fx ) / sizeof( hCPE->hStereoDft->td_gain_fx[0] ) ); scale_sig32( hCPE->hStereoDft->res_cod_mem_fx, STEREO_DFT_OVL_8k, sub( Q16, hCPE->hStereoDft->q_res_cod_mem_fx ) ); hCPE->hStereoDft->q_res_cod_mem_fx = Q16; @@ -901,8 +807,8 @@ ivas_error ivas_cpe_dec_fx( // Delete below IF( hCPE->hStereoDft != NULL ) { - Word16 q_td_gain = Q_factor_arr( hCPE->hStereoDft->td_gain, STEREO_DFT_CORE_HIST_MAX ); - floatToFixed_arrL( hCPE->hStereoDft->td_gain, hCPE->hStereoDft->td_gain_fx, q_td_gain, STEREO_DFT_CORE_HIST_MAX ); // Checking this. + //Word16 q_td_gain = Q_factor_arr( hCPE->hStereoDft->td_gain, STEREO_DFT_CORE_HIST_MAX ); + //floatToFixed_arrL( hCPE->hStereoDft->td_gain, hCPE->hStereoDft->td_gain_fx, q_td_gain, STEREO_DFT_CORE_HIST_MAX ); // Checking this. } //////Till here @@ -965,8 +871,8 @@ ivas_error ivas_cpe_dec_fx( // delete below IF( hCPE->hStereoDft != NULL ) { - Word16 q_td_gain = Q_factor_arr( hCPE->hStereoDft->td_gain, STEREO_DFT_CORE_HIST_MAX ); - fixedToFloat_arrL( hCPE->hStereoDft->td_gain_fx, hCPE->hStereoDft->td_gain, q_td_gain, STEREO_DFT_CORE_HIST_MAX ); // Checking this. + //Word16 q_td_gain = Q_factor_arr( hCPE->hStereoDft->td_gain, STEREO_DFT_CORE_HIST_MAX ); + //fixedToFloat_arrL( hCPE->hStereoDft->td_gain_fx, hCPE->hStereoDft->td_gain, q_td_gain, STEREO_DFT_CORE_HIST_MAX ); // Checking this. } /*----------------------------------------------------------------* diff --git a/lib_dec/ivas_dirac_dec.c b/lib_dec/ivas_dirac_dec.c index 23ad8c10c..0a00321e0 100644 --- a/lib_dec/ivas_dirac_dec.c +++ b/lib_dec/ivas_dirac_dec.c @@ -3622,6 +3622,8 @@ void ivas_dirac_dec_render_sf_fx( Word32 pppQMfFrame_ts_im_fx[MAX_OUTPUT_CHANNELS + MAX_NUM_OBJECTS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; Word32 Cldfb_RealBuffer_fx[MAX_OUTPUT_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; Word32 Cldfb_ImagBuffer_fx[MAX_OUTPUT_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; + Word32 Cldfb_RealBuffer_Binaural_fx[BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; + Word32 Cldfb_ImagBuffer_Binaural_fx[BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; set_zero_fx(surCohRatio_fx, CLDFB_NO_CHANNELS_MAX); Word16 q_cldfb, q_temp_cldfb = 0; //Word32 proto_frame_f_fx[2 * MAX_OUTPUT_CHANNELS * CLDFB_SLOTS_PER_SUBFRAME * CLDFB_NO_CHANNELS_MAX]; @@ -5304,39 +5306,63 @@ void ivas_dirac_dec_render_sf_fx( index_slot = slot_idx_start_cldfb_synth; #ifdef IVAS_FLOAT_FIXED - Word16 cldfb_re_q = Q6; // Q_factor_arrL((float *)Cldfb_RealBuffer, MAX_OUTPUT_CHANNELS*MAX_PARAM_SPATIAL_SUBFRAMES*CLDFB_NO_CHANNELS_MAX); - Word16 cldfb_im_q = Q6; // Q_factor_arrL((float *)Cldfb_ImagBuffer, MAX_OUTPUT_CHANNELS*MAX_PARAM_SPATIAL_SUBFRAMES*CLDFB_NO_CHANNELS_MAX); + //////////////////////////////////////////////// FLOAT TO FIXED ///////////////////////////////////////////// for (int idx1 = 0; idx1 < MAX_OUTPUT_CHANNELS; idx1++) { for (int idx2 = 0; idx2 < MAX_PARAM_SPATIAL_SUBFRAMES; idx2++) { for (int idx3 = 0; idx3 < CLDFB_NO_CHANNELS_MAX; idx3++) { - Cldfb_RealBuffer_fx[idx1][idx2][idx3] = floatToFixed(Cldfb_RealBuffer[idx1][idx2][idx3], cldfb_re_q); - Cldfb_ImagBuffer_fx[idx1][idx2][idx3] = floatToFixed(Cldfb_ImagBuffer[idx1][idx2][idx3], cldfb_im_q); + Cldfb_RealBuffer_fx[idx1][idx2][idx3] = floatToFixed(Cldfb_RealBuffer[idx1][idx2][idx3], Q6); + Cldfb_ImagBuffer_fx[idx1][idx2][idx3] = floatToFixed(Cldfb_ImagBuffer[idx1][idx2][idx3], Q6); } } } -#endif - if ( st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV || st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV_ROOM ) + Word32 output_buf_fx[MAX_OUTPUT_CHANNELS][L_FRAME48k]; + if (st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV || st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV_ROOM) { -#ifdef IVAS_FLOAT_FIXED // Float to fixed - Word32 output_buf_fx[MAX_OUTPUT_CHANNELS][L_FRAME48k]; for (i = 0; i < st_ivas->hDecoderConfig->nchan_out; i++) { floatToFixed_arrL(output_f[i], output_buf_fx[i], Q11, L_FRAME48k); } + } + else if (st_ivas->ivas_format == SBA_FORMAT || st_ivas->ivas_format == SBA_ISM_FORMAT) + { + /* output_f not being used here. */ + } + else + { + Word16 outchannels = add(hDirACRend->hOutSetup.nchan_out_woLFE, hDirACRend->hOutSetup.num_lfe); + + IF(hDirACRend->hOutSetup.separateChannelEnabled && (hDirACRend->hOutSetup.output_config == IVAS_AUDIO_CONFIG_5_1 || + hDirACRend->hOutSetup.output_config == IVAS_AUDIO_CONFIG_7_1 || + hDirACRend->hOutSetup.output_config == IVAS_AUDIO_CONFIG_5_1_2 || + hDirACRend->hOutSetup.output_config == IVAS_AUDIO_CONFIG_5_1_4 || + hDirACRend->hOutSetup.output_config == IVAS_AUDIO_CONFIG_7_1_4 || + (hDirACRend->hOutSetup.output_config == IVAS_AUDIO_CONFIG_LS_CUSTOM && st_ivas->hLsSetupCustom->separate_ch_found))) + { + outchannels = add(outchannels, 1); + } + + for (i = 0; i < outchannels; i++) + { + floatToFixed_arrL(output_f[i], output_buf_fx[i], Q11, L_FRAME48k); + } + } + ////////////////////////////////////////////////////////////////////////////////////////////////////////////// #endif #ifdef IVAS_FLOAT_FIXED + IF( st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV || st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV_ROOM ) + { /* render objects in combined format onto the CICP19 channels for BINAURAL_ROOM_IR */ - if ( st_ivas->ivas_format == SBA_ISM_FORMAT && st_ivas->ism_mode == ISM_SBA_MODE_DISC && st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV_ROOM ) + IF ( st_ivas->ivas_format == SBA_ISM_FORMAT && st_ivas->ism_mode == ISM_SBA_MODE_DISC && st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV_ROOM ) { - int16_t in_ch; - for ( in_ch = 0; in_ch < st_ivas->nchan_ism; in_ch++ ) + Word16 in_ch; + FOR ( in_ch = 0; in_ch < st_ivas->nchan_ism; in_ch++ ) { Word16 j, k, j2, l; Word16 num_objects, nchan_out_woLFE, lfe_index; @@ -5427,124 +5453,33 @@ void ivas_dirac_dec_render_sf_fx( } } } -#else - /* render objects in combined format onto the CICP19 channels for BINAURAL_ROOM_IR */ - if ( st_ivas->ivas_format == SBA_ISM_FORMAT && st_ivas->ism_mode == ISM_SBA_MODE_DISC && st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV_ROOM ) - { - int16_t in_ch; - for ( in_ch = 0; in_ch < st_ivas->nchan_ism; in_ch++ ) - { - int16_t j, k, j2, l; - int16_t num_objects, nchan_out_woLFE, lfe_index; - int16_t az1, el1; - int16_t n_slots_to_render; - int16_t n_samples_to_render; - int16_t interp_offset; - - float gain, prev_gain; - - num_objects = st_ivas->nchan_ism; - nchan_out_woLFE = st_ivas->hIntSetup.nchan_out_woLFE; - n_slots_to_render = st_ivas->hSpar->subframe_nbslots[st_ivas->hSpar->subframes_rendered]; - n_samples_to_render = hSpatParamRendCom->num_freq_bands * n_slots_to_render; - interp_offset = st_ivas->hTcBuffer->n_samples_rendered; - - if ( st_ivas->hCombinedOrientationData && st_ivas->hCombinedOrientationData->enableCombinedOrientation[0] ) - { - ivas_jbm_dec_get_adapted_linear_interpolator( n_samples_to_render, n_samples_to_render, st_ivas->hIsmRendererData->interpolator_fx ); - - interp_offset = 0; - } - for ( i = 0; i < num_objects; i++ ) - { - /* Combined rotation: rotate the object positions depending the head and external orientations */ - if ( st_ivas->hCombinedOrientationData != NULL && st_ivas->hCombinedOrientationData->enableCombinedOrientation[0] == 1 ) - { - rotateAziEle( st_ivas->hIsmMetaData[i]->azimuth, st_ivas->hIsmMetaData[i]->elevation, &az1, &el1, st_ivas->hCombinedOrientationData->Rmat[0], st_ivas->hIntSetup.is_planar_setup ); - if ( st_ivas->hEFAPdata != NULL ) - { - efap_determine_gains( st_ivas->hEFAPdata, st_ivas->hIsmRendererData->gains[i], az1, el1, EFAP_MODE_EFAP ); - } - } - - lfe_index = 0; - for ( j = 0, j2 = 0; j < nchan_out_woLFE; j++, j2++ ) - { - if ( ( st_ivas->hIntSetup.num_lfe > 0 ) && ( st_ivas->hIntSetup.index_lfe[lfe_index] == j ) ) - { - ( lfe_index < ( st_ivas->hIntSetup.num_lfe - 1 ) ) ? ( lfe_index++, j2++ ) : j2++; - } - gain = st_ivas->hIsmRendererData->gains[i][j]; - prev_gain = st_ivas->hIsmRendererData->prev_gains[i][j]; - if ( fabsf( gain ) > 0.0f || fabsf( prev_gain ) > 0.0f ) - { - float *tc_re, *tc_im; - - float *w1, w2; - - w1 = &st_ivas->hIsmRendererData->interpolator[interp_offset]; - tc_re = pppQMfFrame_ts_re[nchan_transport + i][0]; - tc_im = pppQMfFrame_ts_im[nchan_transport + i][0]; - for ( k = 0; k < n_slots_to_render; k++ ) - { - float g; - w2 = 1.0f - *w1; - g = ( *w1 * gain + w2 * prev_gain ); - - for ( l = 0; l < hSpatParamRendCom->num_freq_bands; l++ ) - { - Cldfb_RealBuffer[j2][0][k * hSpatParamRendCom->num_freq_bands + l] += g * *( tc_re++ ); - Cldfb_ImagBuffer[j2][0][k * hSpatParamRendCom->num_freq_bands + l] += g * *( tc_im++ ); - } - w1 += hSpatParamRendCom->num_freq_bands; - } - } - /* update here only in case of head rotation */ - if ( st_ivas->hCombinedOrientationData != NULL && st_ivas->hCombinedOrientationData->enableCombinedOrientation[0] == 1 ) - { - st_ivas->hIsmRendererData->prev_gains[i][j] = gain; - } - } - } - } - } -#endif /* Perform binaural rendering */ - ivas_binRenderer( st_ivas->hBinRenderer, - st_ivas->hCombinedOrientationData, - hSpatParamRendCom->subframe_nbslots[subframe_idx], - Cldfb_RealBuffer_Binaural, Cldfb_ImagBuffer_Binaural, Cldfb_RealBuffer, Cldfb_ImagBuffer ); + Word16 input_q = Q6; + ivas_binRenderer_fx( st_ivas->hBinRenderer, + st_ivas->hCombinedOrientationData, + hSpatParamRendCom->subframe_nbslots[subframe_idx], + Cldfb_RealBuffer_Binaural_fx, Cldfb_ImagBuffer_Binaural_fx, + Cldfb_RealBuffer_fx, Cldfb_ImagBuffer_fx, &input_q ); -#ifdef IVAS_FLOAT_FIXED - Word32 Cldfb_RealBuffer_Binaural_fx[BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; // cldfb_re_bin_q - Word32 Cldfb_ImagBuffer_Binaural_fx[BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; // cldfb_im_bin_q - - Word16 cldfb_re_bin_q, cldfb_im_bin_q; - cldfb_re_bin_q = Q6;//Q_factor_arrL( (float *)Cldfb_RealBuffer_Binaural, BINAURAL_CHANNELS*MAX_PARAM_SPATIAL_SUBFRAMES*CLDFB_NO_CHANNELS_MAX ); - cldfb_im_bin_q = Q6;//Q_factor_arrL( (float *)Cldfb_ImagBuffer_Binaural, BINAURAL_CHANNELS*MAX_PARAM_SPATIAL_SUBFRAMES*CLDFB_NO_CHANNELS_MAX ); - for (int idx1 = 0; idx1 < BINAURAL_CHANNELS; idx1++) + FOR ( Word16 idx1 = 0; idx1 < BINAURAL_CHANNELS; idx1++ ) { - for (int idx2 = 0; idx2 < MAX_PARAM_SPATIAL_SUBFRAMES; idx2++) + FOR ( Word16 idx2 = 0; idx2 < MAX_PARAM_SPATIAL_SUBFRAMES; idx2++ ) { - for (int idx3 = 0; idx3 < CLDFB_NO_CHANNELS_MAX; idx3++) - { - Cldfb_RealBuffer_Binaural_fx[idx1][idx2][idx3] = float_to_fix(Cldfb_RealBuffer_Binaural[idx1][idx2][idx3], cldfb_re_bin_q); - Cldfb_ImagBuffer_Binaural_fx[idx1][idx2][idx3] = float_to_fix(Cldfb_ImagBuffer_Binaural[idx1][idx2][idx3], cldfb_im_bin_q); - - } + Scale_sig32(Cldfb_RealBuffer_Binaural_fx[idx1][idx2], CLDFB_NO_CHANNELS_MAX, Q6 - input_q ); + Scale_sig32(Cldfb_ImagBuffer_Binaural_fx[idx1][idx2], CLDFB_NO_CHANNELS_MAX, Q6 - input_q ); } } -#endif /* Inverse CLDFB*/ - for ( ch = 0; ch < st_ivas->hDecoderConfig->nchan_out; ch++ ) + FOR ( ch = 0; ch < st_ivas->hDecoderConfig->nchan_out; ch++ ) { /* open CLDFB buffer up to CLDFB_NO_CHANNELS_MAX bands for 48kHz */ -#ifdef IVAS_FLOAT_FIXED - Word32 *synth_fx = &output_buf_fx[ch][index_slot * hSpatParamRendCom->num_freq_bands]; +#if 1 // TODOD: remove float to fixed st_ivas->cldfbSynDec[ch]->Q_cldfb_state = Q_factor_arrL( st_ivas->cldfbSynDec[ch]->cldfb_state, st_ivas->cldfbSynDec[ch]->p_filter_length ); floatToFixed_arrL( st_ivas->cldfbSynDec[ch]->cldfb_state, st_ivas->cldfbSynDec[ch]->cldfb_state_fx, st_ivas->cldfbSynDec[ch]->Q_cldfb_state, st_ivas->cldfbSynDec[ch]->p_filter_length ); +#endif + Word32 *synth_fx = &output_buf_fx[ch][index_slot * hSpatParamRendCom->num_freq_bands]; Word32 *RealBuffer_fx[MAX_PARAM_SPATIAL_SUBFRAMES]; Word32 *ImagBuffer_fx[MAX_PARAM_SPATIAL_SUBFRAMES]; @@ -5553,19 +5488,10 @@ void ivas_dirac_dec_render_sf_fx( RealBuffer_fx[i] = Cldfb_RealBuffer_Binaural_fx[ch][i]; ImagBuffer_fx[i] = Cldfb_ImagBuffer_Binaural_fx[ch][i]; } - Word16 common_q = sub( s_min( cldfb_re_bin_q, cldfb_im_bin_q ), 1 ); // 1 guard bit. - FOR( i = 0; i < hSpatParamRendCom->subframe_nbslots[subframe_idx]; i++ ) - { - scale_sig32( RealBuffer_fx[i], CLDFB_NO_CHANNELS_MAX, sub( common_q, cldfb_re_bin_q ) ); - scale_sig32( ImagBuffer_fx[i], CLDFB_NO_CHANNELS_MAX, sub( common_q, cldfb_im_bin_q ) ); - } - cldfb_re_bin_q = common_q; - move16(); - cldfb_im_bin_q = common_q; - move16(); - scale_sig32( st_ivas->cldfbSynDec[ch]->cldfb_state_fx, st_ivas->cldfbSynDec[ch]->p_filter_length, sub( sub( common_q, 1 ), st_ivas->cldfbSynDec[ch]->Q_cldfb_state ) ); - st_ivas->cldfbSynDec[ch]->Q_cldfb_state = sub( common_q, 1 ); + scale_sig32( st_ivas->cldfbSynDec[ch]->cldfb_state_fx, st_ivas->cldfbSynDec[ch]->p_filter_length, sub( Q6 - 1, st_ivas->cldfbSynDec[ch]->Q_cldfb_state ) ); + st_ivas->cldfbSynDec[ch]->Q_cldfb_state = Q6 - 1; + move16(); cldfbSynthesis_ivas_fx( RealBuffer_fx, ImagBuffer_fx, synth_fx, hSpatParamRendCom->num_freq_bands * hSpatParamRendCom->subframe_nbslots[subframe_idx], st_ivas->cldfbSynDec[ch] ); @@ -5577,67 +5503,31 @@ void ivas_dirac_dec_render_sf_fx( } Word16 synth_len = imult1616( no_col, no_channels ); - scale_sig32( synth_fx, synth_len, sub( Q11, sub( common_q, 1 ) ) ); - for (i = 0; i < hSpatParamRendCom->subframe_nbslots[subframe_idx]; i++) - { - scale_sig32(RealBuffer_fx[i], CLDFB_NO_CHANNELS_MAX, sub( Q6, common_q ) ); - scale_sig32(ImagBuffer_fx[i], CLDFB_NO_CHANNELS_MAX, sub( Q6, common_q ) ); - } - cldfb_re_bin_q = Q6; - cldfb_im_bin_q = Q6; + scale_sig32( synth_fx, synth_len, Q11 - ( Q6 - 1 ) ); - // Fixed to float +#if 1 // TODOD: remove Fixed to float fixedToFloat_arrL( st_ivas->cldfbSynDec[ch]->cldfb_state_fx, st_ivas->cldfbSynDec[ch]->cldfb_state, st_ivas->cldfbSynDec[ch]->Q_cldfb_state, st_ivas->cldfbSynDec[ch]->p_filter_length ); for ( i = 0; i < hSpatParamRendCom->subframe_nbslots[subframe_idx]; i++ ) { fixedToFloat_arrL( Cldfb_RealBuffer_Binaural_fx[ch][i], Cldfb_RealBuffer_Binaural[ch][i], CLDFB_NO_CHANNELS_MAX, Q6 ); fixedToFloat_arrL( Cldfb_ImagBuffer_Binaural_fx[ch][i], Cldfb_ImagBuffer_Binaural[ch][i], CLDFB_NO_CHANNELS_MAX, Q6 ); } -#else - float *RealBuffer[MAX_PARAM_SPATIAL_SUBFRAMES]; - float *ImagBuffer[MAX_PARAM_SPATIAL_SUBFRAMES]; - for (i = 0; i < hSpatParamRendCom->subframe_nbslots[subframe_idx]; i++) - { - RealBuffer[i] = Cldfb_RealBuffer_Binaural[ch][i]; - ImagBuffer[i] = Cldfb_ImagBuffer_Binaural[ch][i]; - } - cldfbSynthesis_ivas( RealBuffer, ImagBuffer, &( output_f[ch][index_slot * hSpatParamRendCom->num_freq_bands] ), hSpatParamRendCom->num_freq_bands * hSpatParamRendCom->subframe_nbslots[subframe_idx], st_ivas->cldfbSynDec[ch] ); #endif } -#ifdef IVAS_FLOAT_FIXED - for (i = 0; i < st_ivas->hDecoderConfig->nchan_out; i++) - { - fixedToFloat_arrL(output_buf_fx[i], output_f[i], Q11, index_slot * hSpatParamRendCom->num_freq_bands + hSpatParamRendCom->num_freq_bands * hSpatParamRendCom->subframe_nbslots[subframe_idx]); - } -#endif } - else if ( st_ivas->ivas_format == SBA_FORMAT || st_ivas->ivas_format == SBA_ISM_FORMAT ) + ELSE IF( st_ivas->ivas_format == SBA_FORMAT || st_ivas->ivas_format == SBA_ISM_FORMAT ) { -#ifdef IVAS_FLOAT_FIXED for ( ch = 0; ch < hDirACRend->hOutSetup.nchan_out_woLFE; ch++ ) { for ( slot_idx = 0; slot_idx < hSpatParamRendCom->subframe_nbslots[subframe_idx]; slot_idx++ ) { - Copy32( Cldfb_RealBuffer_fx[ch][slot_idx], pppQMfFrame_ts_re_fx[ch][slot_idx], hSpatParamRendCom->num_freq_bands ); - Copy32( Cldfb_ImagBuffer_fx[ch][slot_idx], pppQMfFrame_ts_im_fx[ch][slot_idx], hSpatParamRendCom->num_freq_bands ); - scale_sig32( pppQMfFrame_ts_re_fx[ch][slot_idx], hSpatParamRendCom->num_freq_bands, sub( Q6, cldfb_re_q ) ); - scale_sig32( pppQMfFrame_ts_im_fx[ch][slot_idx], hSpatParamRendCom->num_freq_bands, sub( Q6, cldfb_im_q ) ); + Copy32( Cldfb_RealBuffer_fx[ch][slot_idx], pppQMfFrame_ts_re_fx[ch][slot_idx], hSpatParamRendCom->num_freq_bands ); // Q6 + Copy32( Cldfb_ImagBuffer_fx[ch][slot_idx], pppQMfFrame_ts_im_fx[ch][slot_idx], hSpatParamRendCom->num_freq_bands ); // Q6 } } -#else - for ( ch = 0; ch < hDirACRend->hOutSetup.nchan_out_woLFE; ch++ ) - { - for ( slot_idx = 0; slot_idx < hSpatParamRendCom->subframe_nbslots[subframe_idx]; slot_idx++ ) - { - mvr2r( Cldfb_RealBuffer[ch][slot_idx], pppQMfFrame_ts_re[ch][slot_idx], hSpatParamRendCom->num_freq_bands ); - mvr2r( Cldfb_ImagBuffer[ch][slot_idx], pppQMfFrame_ts_im[ch][slot_idx], hSpatParamRendCom->num_freq_bands ); - } - } -#endif } - else + ELSE { -#ifdef IVAS_FLOAT_FIXED Word32 *RealBuffer_fx[MAX_PARAM_SPATIAL_SUBFRAMES]; Word32 *ImagBuffer_fx[MAX_PARAM_SPATIAL_SUBFRAMES]; Word16 outchannels; @@ -5649,7 +5539,7 @@ void ivas_dirac_dec_render_sf_fx( outchannels = add( hDirACRend->hOutSetup.nchan_out_woLFE, hDirACRend->hOutSetup.num_lfe ); - if ( hDirACRend->hOutSetup.separateChannelEnabled && ( hDirACRend->hOutSetup.output_config == IVAS_AUDIO_CONFIG_5_1 || + IF ( hDirACRend->hOutSetup.separateChannelEnabled && ( hDirACRend->hOutSetup.output_config == IVAS_AUDIO_CONFIG_5_1 || hDirACRend->hOutSetup.output_config == IVAS_AUDIO_CONFIG_7_1 || hDirACRend->hOutSetup.output_config == IVAS_AUDIO_CONFIG_5_1_2 || hDirACRend->hOutSetup.output_config == IVAS_AUDIO_CONFIG_5_1_4 || @@ -5658,39 +5548,9 @@ void ivas_dirac_dec_render_sf_fx( { outchannels = add(outchannels, 1); } -#else - float *RealBuffer[MAX_PARAM_SPATIAL_SUBFRAMES]; - float *ImagBuffer[MAX_PARAM_SPATIAL_SUBFRAMES]; - int16_t outchannels; - - idx_in = 0; - idx_lfe = 0; - - outchannels = hDirACRend->hOutSetup.nchan_out_woLFE + hDirACRend->hOutSetup.num_lfe; - - if ( hDirACRend->hOutSetup.separateChannelEnabled && ( hDirACRend->hOutSetup.output_config == IVAS_AUDIO_CONFIG_5_1 || - hDirACRend->hOutSetup.output_config == IVAS_AUDIO_CONFIG_7_1 || - hDirACRend->hOutSetup.output_config == IVAS_AUDIO_CONFIG_5_1_2 || - hDirACRend->hOutSetup.output_config == IVAS_AUDIO_CONFIG_5_1_4 || - hDirACRend->hOutSetup.output_config == IVAS_AUDIO_CONFIG_7_1_4 || - ( hDirACRend->hOutSetup.output_config == IVAS_AUDIO_CONFIG_LS_CUSTOM && st_ivas->hLsSetupCustom->separate_ch_found ) ) ) - { - outchannels++; - } -#endif - -#ifdef IVAS_FLOAT_FIXED - // Float to fixed - Word32 output_buf_fx[MAX_OUTPUT_CHANNELS][L_FRAME48k]; - for (i = 0; i < outchannels; i++) - { - floatToFixed_arrL(output_f[i], output_buf_fx[i], Q11, L_FRAME48k); - } -#endif - if ( hDirACRend->hOutSetup.separateChannelEnabled && hDirACRend->hOutSetup.output_config == IVAS_AUDIO_CONFIG_LS_CUSTOM ) + IF( hDirACRend->hOutSetup.separateChannelEnabled && hDirACRend->hOutSetup.output_config == IVAS_AUDIO_CONFIG_LS_CUSTOM ) { -#ifdef IVAS_FLOAT_FIXED Word32 tmp_separated_fx[L_FRAME48k / MAX_PARAM_SPATIAL_SUBFRAMES]; Word32 tmp_lfe_fx[L_FRAME48k / MAX_PARAM_SPATIAL_SUBFRAMES]; const Word16 subframe_start_sample = imult1616( index_slot, hSpatParamRendCom->num_freq_bands ); @@ -5737,106 +5597,26 @@ void ivas_dirac_dec_render_sf_fx( idx_in = add( idx_in, 1 ); } } -#else - float tmp_separated[L_FRAME48k / MAX_PARAM_SPATIAL_SUBFRAMES]; - float tmp_lfe[L_FRAME48k / MAX_PARAM_SPATIAL_SUBFRAMES]; - const int16_t subframe_start_sample = index_slot * hSpatParamRendCom->num_freq_bands; - const int16_t num_samples_subframe = hSpatParamRendCom->num_freq_bands * hSpatParamRendCom->subframe_nbslots[subframe_idx]; - - /* Move the separated and the LFE channels to temporary variables as spatial synthesis may overwrite current channels */ - mvr2r( &( output_f[st_ivas->hOutSetup.separateChannelIndex][subframe_start_sample] ), tmp_separated, num_samples_subframe ); - mvr2r( &( output_f[LFE_CHANNEL][subframe_start_sample] ), tmp_lfe, num_samples_subframe ); - for ( ch = 0; ch < outchannels; ch++ ) - { - if ( ( hDirACRend->hOutSetup.num_lfe > 0 ) && ( hDirACRend->hOutSetup.index_lfe[idx_lfe] == ch ) ) - { - /* Move the LFE channel to the correct place */ - mvr2r( tmp_lfe, &( output_f[ch][subframe_start_sample] ), num_samples_subframe ); - - if ( idx_lfe < ( hDirACRend->hOutSetup.num_lfe - 1 ) ) - { - idx_lfe++; - } - } - else if ( ( st_ivas->hLsSetupCustom->separate_ch_found ) && ( hDirACRend->hOutSetup.separateChannelIndex == ch ) ) - { - /* Move the separated channel to the correct place. Thus, the separated channel is - * combined with the synthesized channels here when there is a matching channel. */ - mvr2r( tmp_separated, &( output_f[ch][subframe_start_sample] ), num_samples_subframe ); - } - else - { - /* 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]; - } - cldfbSynthesis_ivas( RealBuffer, ImagBuffer, &( output_f[ch][subframe_start_sample] ), num_samples_subframe, st_ivas->cldfbSynDec[idx_in] ); - - if ( !st_ivas->hLsSetupCustom->separate_ch_found ) - { - /* Pan the separated channel and mix with the synthesized channels. Thus, the separated channel - * is combined with the synthesized channels here when there is no matching channel. */ - v_multc_acc( tmp_separated, st_ivas->hLsSetupCustom->separate_ch_gains[idx_in], &( output_f[ch][subframe_start_sample] ), num_samples_subframe ); - } - - idx_in++; - } - } -#endif } - else + ELSE { -#ifdef IVAS_FLOAT_FIXED FOR ( ch = 0; ch < outchannels; ch++ ) { -#if 1 // Float to fixed - Word16 tmp_idx_in = idx_in; - Word16 tmp_idx_lfe = idx_lfe; - IF((hDirACRend->hOutSetup.num_lfe > 0) && (EQ_16(hDirACRend->hOutSetup.index_lfe[idx_lfe], ch))) + IF ( ( hDirACRend->hOutSetup.num_lfe > 0 ) && ( EQ_16( hDirACRend->hOutSetup.index_lfe[idx_lfe], ch ) ) ) { IF(st_ivas->mc_mode == MC_MODE_MCMASA && !hDirACRend->hOutSetup.separateChannelEnabled) { - // Float to fixed - Word16 cldfbSynIdx = hDirACRend->hOutSetup.nchan_out_woLFE + tmp_idx_lfe; + FOR(i = 0; i < hSpatParamRendCom->subframe_nbslots[subframe_idx]; i++) + { + RealBuffer_fx[i] = Cldfb_RealBuffer_fx[MAX_OUTPUT_CHANNELS - 1][i]; + ImagBuffer_fx[i] = Cldfb_ImagBuffer_fx[MAX_OUTPUT_CHANNELS - 1][i]; + } + Word16 cldfbSynIdx = hDirACRend->hOutSetup.nchan_out_woLFE + idx_lfe; + +#if 1 // TODO: remove float to fixed code st_ivas->cldfbSynDec[cldfbSynIdx]->Q_cldfb_state = Q_factor_arrL(st_ivas->cldfbSynDec[cldfbSynIdx]->cldfb_state, st_ivas->cldfbSynDec[cldfbSynIdx]->p_filter_length); floatToFixed_arrL(st_ivas->cldfbSynDec[cldfbSynIdx]->cldfb_state, st_ivas->cldfbSynDec[cldfbSynIdx]->cldfb_state_fx, st_ivas->cldfbSynDec[cldfbSynIdx]->Q_cldfb_state, st_ivas->cldfbSynDec[cldfbSynIdx]->p_filter_length); - } - ELSE IF(st_ivas->mc_mode == MC_MODE_MCMASA && hDirACRend->hOutSetup.separateChannelEnabled) - { - /* LFE has been synthesized in the time domain, do nothing. */ - } - ELSE - { - } - IF(LT_16(tmp_idx_lfe, sub(hDirACRend->hOutSetup.num_lfe, 1))) - { - tmp_idx_lfe = add(tmp_idx_lfe, 1); - } - } - ELSE IF((hDirACRend->hOutSetup.separateChannelEnabled) && EQ_16(hDirACRend->hOutSetup.separateChannelIndex, ch)) - { - /* The separated channel is already set to output_f[hOutSetup.separateChannelIndex]. Thus, the separated - * channel is combined with the synthesized channels here. */ - } - ELSE - { - /* open CLDFB buffer up to CLDFB_NO_CHANNELS_MAX bands for 48kHz */ - st_ivas->cldfbSynDec[idx_in]->Q_cldfb_state = Q_factor_arrL(st_ivas->cldfbSynDec[idx_in]->cldfb_state, st_ivas->cldfbSynDec[idx_in]->p_filter_length); - floatToFixed_arrL(st_ivas->cldfbSynDec[idx_in]->cldfb_state, st_ivas->cldfbSynDec[idx_in]->cldfb_state_fx, st_ivas->cldfbSynDec[idx_in]->Q_cldfb_state, st_ivas->cldfbSynDec[idx_in]->p_filter_length); - } #endif - IF ( ( hDirACRend->hOutSetup.num_lfe > 0 ) && ( EQ_16( hDirACRend->hOutSetup.index_lfe[idx_lfe], ch ) ) ) - { - IF(st_ivas->mc_mode == MC_MODE_MCMASA && !hDirACRend->hOutSetup.separateChannelEnabled) - { - FOR(i = 0; i < hSpatParamRendCom->subframe_nbslots[subframe_idx]; i++) - { - RealBuffer_fx[i] = Cldfb_RealBuffer_fx[MAX_OUTPUT_CHANNELS - 1][i]; - ImagBuffer_fx[i] = Cldfb_ImagBuffer_fx[MAX_OUTPUT_CHANNELS - 1][i]; - } - Word16 cldfbSynIdx = hDirACRend->hOutSetup.nchan_out_woLFE + idx_lfe; Word16 samplesToProcess = hSpatParamRendCom->num_freq_bands * hSpatParamRendCom->subframe_nbslots[subframe_idx]; Word32 *p_out = &(output_buf_fx[ch][index_slot * hSpatParamRendCom->num_freq_bands]); @@ -5854,6 +5634,9 @@ void ivas_dirac_dec_render_sf_fx( Word16 synth_len = imult1616(no_col, no_channels); scale_sig32(p_out, synth_len, (Q11 - (Q6 - 1))); +#if 1 // TODO: remove fixed to float code + fixedToFloat_arrL(st_ivas->cldfbSynDec[cldfbSynIdx]->cldfb_state_fx, st_ivas->cldfbSynDec[cldfbSynIdx]->cldfb_state, st_ivas->cldfbSynDec[cldfbSynIdx]->Q_cldfb_state, st_ivas->cldfbSynDec[cldfbSynIdx]->p_filter_length); +#endif } ELSE IF( st_ivas->mc_mode == MC_MODE_MCMASA && hDirACRend->hOutSetup.separateChannelEnabled ) { @@ -5876,6 +5659,11 @@ void ivas_dirac_dec_render_sf_fx( ELSE { /* open CLDFB buffer up to CLDFB_NO_CHANNELS_MAX bands for 48kHz */ + +#if 1 // TODO: remove float to fixed code + st_ivas->cldfbSynDec[idx_in]->Q_cldfb_state = Q_factor_arrL(st_ivas->cldfbSynDec[idx_in]->cldfb_state, st_ivas->cldfbSynDec[idx_in]->p_filter_length); + floatToFixed_arrL(st_ivas->cldfbSynDec[idx_in]->cldfb_state, st_ivas->cldfbSynDec[idx_in]->cldfb_state_fx, st_ivas->cldfbSynDec[idx_in]->Q_cldfb_state, st_ivas->cldfbSynDec[idx_in]->p_filter_length); +#endif Word32 *p_out = &( output_buf_fx[ch][index_slot * hSpatParamRendCom->num_freq_bands] ); Word16 samplesToProcess, out_len; FOR( i = 0; i < hSpatParamRendCom->subframe_nbslots[subframe_idx]; i++ ) @@ -5906,53 +5694,203 @@ void ivas_dirac_dec_render_sf_fx( // Scaling output from Q6-1 to Q10 scale_sig32(p_out, out_len, (Q10 - (Q6 - 1))); +#if 1 /* TODO: remove fixed to float */ + fixedToFloat_arrL(st_ivas->cldfbSynDec[idx_in]->cldfb_state_fx, st_ivas->cldfbSynDec[idx_in]->cldfb_state, st_ivas->cldfbSynDec[idx_in]->Q_cldfb_state, st_ivas->cldfbSynDec[idx_in]->p_filter_length); +#endif idx_in = add( idx_in, 1 ); } -#if 1 // Fixed to float - IF((hDirACRend->hOutSetup.num_lfe > 0) && (EQ_16(hDirACRend->hOutSetup.index_lfe[idx_lfe], ch))) + } + } + } + + hSpatParamRendCom->slots_rendered = add( hSpatParamRendCom->slots_rendered, hSpatParamRendCom->subframe_nbslots[subframe_idx] ); + hSpatParamRendCom->subframes_rendered = add( hSpatParamRendCom->subframes_rendered, 1 ); + +#else + if ( st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV || st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV_ROOM ) + { + /* render objects in combined format onto the CICP19 channels for BINAURAL_ROOM_IR */ + if ( st_ivas->ivas_format == SBA_ISM_FORMAT && st_ivas->ism_mode == ISM_SBA_MODE_DISC && st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV_ROOM ) + { + int16_t in_ch; + for ( in_ch = 0; in_ch < st_ivas->nchan_ism; in_ch++ ) + { + int16_t j, k, j2, l; + int16_t num_objects, nchan_out_woLFE, lfe_index; + int16_t az1, el1; + int16_t n_slots_to_render; + int16_t n_samples_to_render; + int16_t interp_offset; + + float gain, prev_gain; + + num_objects = st_ivas->nchan_ism; + nchan_out_woLFE = st_ivas->hIntSetup.nchan_out_woLFE; + n_slots_to_render = st_ivas->hSpar->subframe_nbslots[st_ivas->hSpar->subframes_rendered]; + n_samples_to_render = hSpatParamRendCom->num_freq_bands * n_slots_to_render; + interp_offset = st_ivas->hTcBuffer->n_samples_rendered; + + if ( st_ivas->hCombinedOrientationData && st_ivas->hCombinedOrientationData->enableCombinedOrientation[0] ) { - IF(st_ivas->mc_mode == MC_MODE_MCMASA && !hDirACRend->hOutSetup.separateChannelEnabled) + ivas_jbm_dec_get_adapted_linear_interpolator( n_samples_to_render, n_samples_to_render, st_ivas->hIsmRendererData->interpolator_fx ); + + interp_offset = 0; + } + for ( i = 0; i < num_objects; i++ ) + { + /* Combined rotation: rotate the object positions depending the head and external orientations */ + if ( st_ivas->hCombinedOrientationData != NULL && st_ivas->hCombinedOrientationData->enableCombinedOrientation[0] == 1 ) { - Word16 cldfbSynIdx = hDirACRend->hOutSetup.nchan_out_woLFE + idx_lfe; - // Fixed to float - fixedToFloat_arrL(st_ivas->cldfbSynDec[cldfbSynIdx]->cldfb_state_fx, st_ivas->cldfbSynDec[cldfbSynIdx]->cldfb_state, st_ivas->cldfbSynDec[cldfbSynIdx]->Q_cldfb_state, st_ivas->cldfbSynDec[cldfbSynIdx]->p_filter_length); - for (i = 0; i < hSpatParamRendCom->subframe_nbslots[subframe_idx]; i++) + rotateAziEle( st_ivas->hIsmMetaData[i]->azimuth, st_ivas->hIsmMetaData[i]->elevation, &az1, &el1, st_ivas->hCombinedOrientationData->Rmat[0], st_ivas->hIntSetup.is_planar_setup ); + if ( st_ivas->hEFAPdata != NULL ) { - fixedToFloat_arrL(Cldfb_RealBuffer_fx[MAX_OUTPUT_CHANNELS - 1][i], Cldfb_RealBuffer[MAX_OUTPUT_CHANNELS - 1][i], CLDFB_NO_CHANNELS_MAX, Q6); - fixedToFloat_arrL(Cldfb_ImagBuffer_fx[MAX_OUTPUT_CHANNELS - 1][i], Cldfb_ImagBuffer[MAX_OUTPUT_CHANNELS - 1][i], CLDFB_NO_CHANNELS_MAX, Q6); + efap_determine_gains( st_ivas->hEFAPdata, st_ivas->hIsmRendererData->gains[i], az1, el1, EFAP_MODE_EFAP ); } - fixedToFloat_arrL(output_buf_fx[ch], output_f[ch], Q11, hSpatParamRendCom->subframe_nbslots[subframe_idx] * hSpatParamRendCom->num_freq_bands + index_slot * hSpatParamRendCom->num_freq_bands); } - ELSE IF(st_ivas->mc_mode == MC_MODE_MCMASA && hDirACRend->hOutSetup.separateChannelEnabled) + + lfe_index = 0; + for ( j = 0, j2 = 0; j < nchan_out_woLFE; j++, j2++ ) { - /* LFE has been synthesized in the time domain, do nothing. */ + if ( ( st_ivas->hIntSetup.num_lfe > 0 ) && ( st_ivas->hIntSetup.index_lfe[lfe_index] == j ) ) + { + ( lfe_index < ( st_ivas->hIntSetup.num_lfe - 1 ) ) ? ( lfe_index++, j2++ ) : j2++; + } + gain = st_ivas->hIsmRendererData->gains[i][j]; + prev_gain = st_ivas->hIsmRendererData->prev_gains[i][j]; + if ( fabsf( gain ) > 0.0f || fabsf( prev_gain ) > 0.0f ) + { + float *tc_re, *tc_im; + float *w1, w2; + w1 = &st_ivas->hIsmRendererData->interpolator[interp_offset]; + tc_re = pppQMfFrame_ts_re[nchan_transport + i][0]; + tc_im = pppQMfFrame_ts_im[nchan_transport + i][0]; + for ( k = 0; k < n_slots_to_render; k++ ) + { + float g; + w2 = 1.0f - *w1; + g = ( *w1 * gain + w2 * prev_gain ); + + for ( l = 0; l < hSpatParamRendCom->num_freq_bands; l++ ) + { + Cldfb_RealBuffer[j2][0][k * hSpatParamRendCom->num_freq_bands + l] += g * *( tc_re++ ); + Cldfb_ImagBuffer[j2][0][k * hSpatParamRendCom->num_freq_bands + l] += g * *( tc_im++ ); + } + w1 += hSpatParamRendCom->num_freq_bands; + } + } + /* update here only in case of head rotation */ + if ( st_ivas->hCombinedOrientationData != NULL && st_ivas->hCombinedOrientationData->enableCombinedOrientation[0] == 1 ) + { + st_ivas->hIsmRendererData->prev_gains[i][j] = gain; + } } - ELSE + } + } + } + + /* Perform binaural rendering */ + ivas_binRenderer( st_ivas->hBinRenderer, + st_ivas->hCombinedOrientationData, + hSpatParamRendCom->subframe_nbslots[subframe_idx], + Cldfb_RealBuffer_Binaural, Cldfb_ImagBuffer_Binaural, Cldfb_RealBuffer, Cldfb_ImagBuffer ); + + /* Inverse CLDFB*/ + for (ch = 0; ch < st_ivas->hDecoderConfig->nchan_out; ch++) + { + /* open CLDFB buffer up to CLDFB_NO_CHANNELS_MAX bands for 48kHz */ + float *RealBuffer[MAX_PARAM_SPATIAL_SUBFRAMES]; + float *ImagBuffer[MAX_PARAM_SPATIAL_SUBFRAMES]; + for (i = 0; i < hSpatParamRendCom->subframe_nbslots[subframe_idx]; i++) + { + RealBuffer[i] = Cldfb_RealBuffer_Binaural[ch][i]; + ImagBuffer[i] = Cldfb_ImagBuffer_Binaural[ch][i]; + } + cldfbSynthesis_ivas( RealBuffer, ImagBuffer, &( output_f[ch][index_slot * hSpatParamRendCom->num_freq_bands] ), hSpatParamRendCom->num_freq_bands * hSpatParamRendCom->subframe_nbslots[subframe_idx], st_ivas->cldfbSynDec[ch] ); + } + } + else if ( st_ivas->ivas_format == SBA_FORMAT || st_ivas->ivas_format == SBA_ISM_FORMAT ) + { + for ( ch = 0; ch < hDirACRend->hOutSetup.nchan_out_woLFE; ch++ ) + { + for ( slot_idx = 0; slot_idx < hSpatParamRendCom->subframe_nbslots[subframe_idx]; slot_idx++ ) + { + mvr2r( Cldfb_RealBuffer[ch][slot_idx], pppQMfFrame_ts_re[ch][slot_idx], hSpatParamRendCom->num_freq_bands ); + mvr2r( Cldfb_ImagBuffer[ch][slot_idx], pppQMfFrame_ts_im[ch][slot_idx], hSpatParamRendCom->num_freq_bands ); + } + } + } + else + { + float *RealBuffer[MAX_PARAM_SPATIAL_SUBFRAMES]; + float *ImagBuffer[MAX_PARAM_SPATIAL_SUBFRAMES]; + int16_t outchannels; + + idx_in = 0; + idx_lfe = 0; + + outchannels = hDirACRend->hOutSetup.nchan_out_woLFE + hDirACRend->hOutSetup.num_lfe; + + if ( hDirACRend->hOutSetup.separateChannelEnabled && ( hDirACRend->hOutSetup.output_config == IVAS_AUDIO_CONFIG_5_1 || + hDirACRend->hOutSetup.output_config == IVAS_AUDIO_CONFIG_7_1 || + hDirACRend->hOutSetup.output_config == IVAS_AUDIO_CONFIG_5_1_2 || + hDirACRend->hOutSetup.output_config == IVAS_AUDIO_CONFIG_5_1_4 || + hDirACRend->hOutSetup.output_config == IVAS_AUDIO_CONFIG_7_1_4 || + ( hDirACRend->hOutSetup.output_config == IVAS_AUDIO_CONFIG_LS_CUSTOM && st_ivas->hLsSetupCustom->separate_ch_found ) ) ) + { + outchannels++; + } + + if ( hDirACRend->hOutSetup.separateChannelEnabled && hDirACRend->hOutSetup.output_config == IVAS_AUDIO_CONFIG_LS_CUSTOM ) + { + float tmp_separated[L_FRAME48k / MAX_PARAM_SPATIAL_SUBFRAMES]; + float tmp_lfe[L_FRAME48k / MAX_PARAM_SPATIAL_SUBFRAMES]; + const int16_t subframe_start_sample = index_slot * hSpatParamRendCom->num_freq_bands; + const int16_t num_samples_subframe = hSpatParamRendCom->num_freq_bands * hSpatParamRendCom->subframe_nbslots[subframe_idx]; + + /* Move the separated and the LFE channels to temporary variables as spatial synthesis may overwrite current channels */ + mvr2r( &( output_f[st_ivas->hOutSetup.separateChannelIndex][subframe_start_sample] ), tmp_separated, num_samples_subframe ); + mvr2r( &( output_f[LFE_CHANNEL][subframe_start_sample] ), tmp_lfe, num_samples_subframe ); + for ( ch = 0; ch < outchannels; ch++ ) + { + if ( ( hDirACRend->hOutSetup.num_lfe > 0 ) && ( hDirACRend->hOutSetup.index_lfe[idx_lfe] == ch ) ) + { + /* Move the LFE channel to the correct place */ + mvr2r( tmp_lfe, &( output_f[ch][subframe_start_sample] ), num_samples_subframe ); + + if ( idx_lfe < ( hDirACRend->hOutSetup.num_lfe - 1 ) ) { - // Float to fixed. - fixedToFloat_arrL(output_buf_fx[ch], output_f[ch], Q11, hSpatParamRendCom->subframe_nbslots[subframe_idx] * hSpatParamRendCom->num_freq_bands + index_slot * hSpatParamRendCom->num_freq_bands); + idx_lfe++; } } - ELSE IF((hDirACRend->hOutSetup.separateChannelEnabled) && EQ_16(hDirACRend->hOutSetup.separateChannelIndex, ch)) + else if ( ( st_ivas->hLsSetupCustom->separate_ch_found ) && ( hDirACRend->hOutSetup.separateChannelIndex == ch ) ) { - /* The separated channel is already set to output_f[hOutSetup.separateChannelIndex]. Thus, the separated - * channel is combined with the synthesized channels here. */ + /* Move the separated channel to the correct place. Thus, the separated channel is + * combined with the synthesized channels here when there is a matching channel. */ + mvr2r( tmp_separated, &( output_f[ch][subframe_start_sample] ), num_samples_subframe ); } - ELSE + else { - // Fixed to float - fixedToFloat_arrL(st_ivas->cldfbSynDec[tmp_idx_in]->cldfb_state_fx, st_ivas->cldfbSynDec[tmp_idx_in]->cldfb_state, st_ivas->cldfbSynDec[tmp_idx_in]->Q_cldfb_state, st_ivas->cldfbSynDec[tmp_idx_in]->p_filter_length); - for (i = 0; i < hSpatParamRendCom->subframe_nbslots[subframe_idx]; i++) + /* 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]; + } + cldfbSynthesis_ivas( RealBuffer, ImagBuffer, &( output_f[ch][subframe_start_sample] ), num_samples_subframe, st_ivas->cldfbSynDec[idx_in] ); + + if ( !st_ivas->hLsSetupCustom->separate_ch_found ) { - fixedToFloat_arrL(Cldfb_RealBuffer_fx[tmp_idx_in][i], Cldfb_RealBuffer[tmp_idx_in][i], CLDFB_NO_CHANNELS_MAX, Q6); - fixedToFloat_arrL(Cldfb_ImagBuffer_fx[tmp_idx_in][i], Cldfb_ImagBuffer[tmp_idx_in][i], CLDFB_NO_CHANNELS_MAX, Q6); + /* Pan the separated channel and mix with the synthesized channels. Thus, the separated channel + * is combined with the synthesized channels here when there is no matching channel. */ + v_multc_acc( tmp_separated, st_ivas->hLsSetupCustom->separate_ch_gains[idx_in], &( output_f[ch][subframe_start_sample] ), num_samples_subframe ); } - fixedToFloat_arrL(output_buf_fx[ch], output_f[ch], Q10, hSpatParamRendCom->num_freq_bands * hSpatParamRendCom->subframe_nbslots[subframe_idx] + index_slot * hSpatParamRendCom->num_freq_bands); - tmp_idx_in++; + + idx_in++; } -#endif } -#else + } + else + { for ( ch = 0; ch < outchannels; ch++ ) { if ( ( hDirACRend->hOutSetup.num_lfe > 0 ) && ( hDirACRend->hOutSetup.index_lfe[idx_lfe] == ch ) ) @@ -5996,15 +5934,23 @@ void ivas_dirac_dec_render_sf_fx( idx_in++; } } -#endif } } + hSpatParamRendCom->slots_rendered += hSpatParamRendCom->subframe_nbslots[subframe_idx]; hSpatParamRendCom->subframes_rendered++; +#endif #ifdef IVAS_FLOAT_FIXED - // Fixed to float - if (st_ivas->ivas_format == SBA_FORMAT || st_ivas->ivas_format == SBA_ISM_FORMAT) + /////////////////////////////////////////////////////// FIXED TO FLOAT ////////////////////////////////////////////////////////////////////////////////////////// + if (st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV || st_ivas->renderer_type == RENDERER_BINAURAL_FASTCONV_ROOM) + { + for (i = 0; i < st_ivas->hDecoderConfig->nchan_out; i++) + { + fixedToFloat_arrL(output_buf_fx[i], output_f[i], Q11, index_slot * hSpatParamRendCom->num_freq_bands + hSpatParamRendCom->num_freq_bands * hSpatParamRendCom->subframe_nbslots[subframe_idx]); + } + } + else if (st_ivas->ivas_format == SBA_FORMAT || st_ivas->ivas_format == SBA_ISM_FORMAT) { for (ch = 0; ch < hDirACRend->hOutSetup.nchan_out_woLFE; ch++) { @@ -6015,6 +5961,64 @@ void ivas_dirac_dec_render_sf_fx( } } } + else + { + Word16 outchannels = add(hDirACRend->hOutSetup.nchan_out_woLFE, hDirACRend->hOutSetup.num_lfe); + + IF(hDirACRend->hOutSetup.separateChannelEnabled && (hDirACRend->hOutSetup.output_config == IVAS_AUDIO_CONFIG_5_1 || + hDirACRend->hOutSetup.output_config == IVAS_AUDIO_CONFIG_7_1 || + hDirACRend->hOutSetup.output_config == IVAS_AUDIO_CONFIG_5_1_2 || + hDirACRend->hOutSetup.output_config == IVAS_AUDIO_CONFIG_5_1_4 || + hDirACRend->hOutSetup.output_config == IVAS_AUDIO_CONFIG_7_1_4 || + (hDirACRend->hOutSetup.output_config == IVAS_AUDIO_CONFIG_LS_CUSTOM && st_ivas->hLsSetupCustom->separate_ch_found))) + { + outchannels = add(outchannels, 1); + } + if (!hDirACRend->hOutSetup.separateChannelEnabled || hDirACRend->hOutSetup.output_config != IVAS_AUDIO_CONFIG_LS_CUSTOM) + { + Word16 tmp_lfe_idx = 0; + for (ch = 0; ch < outchannels; ch++) + { + //fixedToFloat_arrL(output_buf_fx[i], output_f[i], Q11, index_slot * hSpatParamRendCom->num_freq_bands + hSpatParamRendCom->num_freq_bands * hSpatParamRendCom->subframe_nbslots[subframe_idx]); + IF((hDirACRend->hOutSetup.num_lfe > 0) && (EQ_16(hDirACRend->hOutSetup.index_lfe[tmp_lfe_idx], ch))) + { + IF(st_ivas->mc_mode == MC_MODE_MCMASA && !hDirACRend->hOutSetup.separateChannelEnabled) + { + // Fixed to float + fixedToFloat_arrL(output_buf_fx[ch], output_f[ch], Q11, hSpatParamRendCom->subframe_nbslots[subframe_idx] * hSpatParamRendCom->num_freq_bands + index_slot * hSpatParamRendCom->num_freq_bands); + } + ELSE IF(st_ivas->mc_mode == MC_MODE_MCMASA && hDirACRend->hOutSetup.separateChannelEnabled) + { + /* LFE has been synthesized in the time domain, do nothing. */ + } + ELSE + { + // Float to fixed. + fixedToFloat_arrL(output_buf_fx[ch], output_f[ch], Q11, hSpatParamRendCom->subframe_nbslots[subframe_idx] * hSpatParamRendCom->num_freq_bands + index_slot * hSpatParamRendCom->num_freq_bands); + } + IF(LT_16(tmp_lfe_idx, sub(hDirACRend->hOutSetup.num_lfe, 1))) + { + tmp_lfe_idx = add(tmp_lfe_idx, 1); + } + } + ELSE IF((hDirACRend->hOutSetup.separateChannelEnabled) && EQ_16(hDirACRend->hOutSetup.separateChannelIndex, ch)) + { + /* The separated channel is already set to output_f[hOutSetup.separateChannelIndex]. Thus, the separated + * channel is combined with the synthesized channels here. */ + } + ELSE + { + // Fixed to float + fixedToFloat_arrL(output_buf_fx[ch], output_f[ch], Q10, hSpatParamRendCom->num_freq_bands * hSpatParamRendCom->subframe_nbslots[subframe_idx] + index_slot * hSpatParamRendCom->num_freq_bands); + } + } + } + else + { + /* NOTE: according to line coverage report this part is not being hit by any test case. Not adding fixed to float conversion here. */ + } + } + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// #endif pop_wmops(); diff --git a/lib_dec/ivas_init_dec.c b/lib_dec/ivas_init_dec.c index 53e5ce546..219d67aa7 100644 --- a/lib_dec/ivas_init_dec.c +++ b/lib_dec/ivas_init_dec.c @@ -2133,10 +2133,11 @@ ivas_error ivas_init_decoder_fx( IF ( GT_16(n, 0 )) { - IF ( ( st_ivas->mem_hp20_out = (float **) malloc( n * sizeof( float * ) ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for HP20 filter memory\n" ) ); - } + //IF ( ( st_ivas->mem_hp20_out = (float **) malloc( n * sizeof( float * ) ) ) == NULL ) + //{ + // return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for HP20 filter memory\n" ) ); + //} + IF( ( st_ivas->mem_hp20_out_fx = (Word32 **) malloc( n * sizeof(Word32 * ) ) ) == NULL ) { return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for HP20 filter memory\n" ) ); @@ -2144,18 +2145,20 @@ ivas_error ivas_init_decoder_fx( } ELSE { - st_ivas->mem_hp20_out = NULL; + //st_ivas->mem_hp20_out = NULL; + st_ivas->mem_hp20_out_fx = NULL; } FOR ( i = 0; i < n; i++ ) { - IF ( ( st_ivas->mem_hp20_out[i] = (float *) malloc( L_HP20_MEM * sizeof( float ) ) ) == NULL ) - { - return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for HP20 filter memory\n" ) ); - } + //IF ( ( st_ivas->mem_hp20_out[i] = (float *) malloc( L_HP20_MEM * sizeof( float ) ) ) == NULL ) + //{ + // return ( IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for HP20 filter memory\n" ) ); + //} + + //set_f( st_ivas->mem_hp20_out[i], 0.0f, L_HP20_MEM ); - set_f( st_ivas->mem_hp20_out[i], 0.0f, L_HP20_MEM ); IF((st_ivas->mem_hp20_out_fx[i] = (Word32 *)malloc((L_HP20_MEM + 2) * sizeof(Word32))) == NULL) { return (IVAS_ERROR(IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for HP20 filter memory\n")); @@ -3822,7 +3825,7 @@ void ivas_initialize_handles_dec( } st_ivas->bit_stream = NULL; - st_ivas->mem_hp20_out = NULL; + //st_ivas->mem_hp20_out = NULL; #ifdef IVAS_FLOAT_FIXED st_ivas->mem_hp20_out_fx = NULL; #endif // IVAS_FLOAT_FIXED @@ -3957,7 +3960,7 @@ void ivas_destroy_dec( free( st_ivas->mem_hp20_out_fx ); st_ivas->mem_hp20_out_fx = NULL; } -#endif +#else IF(st_ivas->mem_hp20_out != NULL) { FOR(i = 0; i < getNumChanSynthesis(st_ivas); i++) @@ -3968,6 +3971,7 @@ void ivas_destroy_dec( free(st_ivas->mem_hp20_out); st_ivas->mem_hp20_out = NULL; } +#endif /* ISM metadata handles */ ivas_ism_metadata_close( st_ivas->hIsmMetaData, 0 ); diff --git a/lib_dec/ivas_ism_dec.c b/lib_dec/ivas_ism_dec.c index 399e6508d..60f88277f 100644 --- a/lib_dec/ivas_ism_dec.c +++ b/lib_dec/ivas_ism_dec.c @@ -109,12 +109,6 @@ static ivas_error ivas_ism_bitrate_switching_dec_fx( { return error; } -#ifdef IVAS_FLOAT_FIXED_TO_BE_REMOVED - IF( ( error = ivas_hp20_dec_reconfig( st_ivas, nchan_transport_old ) ) != IVAS_ERR_OK ) - { - return error; - } -#endif /* save old IntSetup, might be needed for JBM flushing...*/ intern_config_old = st_ivas->intern_config; @@ -440,10 +434,10 @@ static ivas_error ivas_ism_bitrate_switching_dec( return error; } - if ( ( error = ivas_hp20_dec_reconfig( st_ivas, nchan_transport_old ) ) != IVAS_ERR_OK ) - { - return error; - } + //if ( ( error = ivas_hp20_dec_reconfig( st_ivas, nchan_transport_old ) ) != IVAS_ERR_OK ) + //{ + // return error; + //} /* save old IntSetup, might be needed for JBM flushing...*/ intern_config_old = st_ivas->intern_config; diff --git a/lib_dec/ivas_jbm_dec.c b/lib_dec/ivas_jbm_dec.c index 86b499d06..a21e3c74a 100644 --- a/lib_dec/ivas_jbm_dec.c +++ b/lib_dec/ivas_jbm_dec.c @@ -749,40 +749,7 @@ ivas_error ivas_jbm_dec_tc( hCPE->hStereoDft->q_smoothed_nrg = Q6; // hCPE->hStereoDft->q_dft; hCPE->hStereoDft->q_ap_delay_mem_fx = hCPE->hStereoDft->q_dft; } - for ( int ii = 0; ii < sizeof( hCPE->hStereoDft->hb_nrg_subr_fx ) / sizeof( hCPE->hStereoDft->hb_nrg_subr_fx[0] ); ii++ ) - { - if ( l_hb_nrg_subr < hCPE->hStereoDft->hb_nrg_subr[ii] ) - { - l_hb_nrg_subr = hCPE->hStereoDft->hb_nrg_subr[ii]; - } - } - hCPE->hStereoDft->q_hb_nrg_subr = 0; - if ( l_hb_nrg_subr > (float) MAX_32 ) - { - int quotient = (int) ceil( l_hb_nrg_subr / (float) MAX_32 ); - hCPE->hStereoDft->q_hb_nrg_subr = Q31 - norm_l( quotient ); - } - for ( int ii = 0; ii < sizeof( hCPE->hStereoDft->hb_nrg_subr_fx ) / sizeof( hCPE->hStereoDft->hb_nrg_subr_fx[0] ); ii++ ) - { - hCPE->hStereoDft->hb_nrg_subr_fx[ii] = (Word32) ( hCPE->hStereoDft->hb_nrg_subr[ii] / ( (float) ( 1 << hCPE->hStereoDft->q_hb_nrg_subr ) ) ); - } - for ( int ii = 0; ii < sizeof( hCPE->hStereoDft->hb_nrg_fx ) / sizeof( hCPE->hStereoDft->hb_nrg_fx[0] ); ii++ ) - { - if ( l_hb_nrg < hCPE->hStereoDft->hb_nrg[ii] ) - { - l_hb_nrg = hCPE->hStereoDft->hb_nrg[ii]; - } - } - hCPE->hStereoDft->q_hb_nrg = 0; - if ( l_hb_nrg > (float) MAX_32 ) - { - int quotient = (int) ceil( l_hb_nrg / (float) MAX_32 ); - hCPE->hStereoDft->q_hb_nrg = Q31 - norm_l( quotient ); - } - for ( int ii = 0; ii < sizeof( hCPE->hStereoDft->hb_nrg_fx ) / sizeof( hCPE->hStereoDft->hb_nrg_fx[0] ); ii++ ) - { - hCPE->hStereoDft->hb_nrg_fx[ii] = (Word32) ( hCPE->hStereoDft->hb_nrg[ii] * ( (float) ( 1 << hCPE->hStereoDft->q_hb_nrg ) ) ); - } + IF( hCPE->hStereoCng != NULL ) { floatToFixed_arr( &hCPE->hStereoCng->cm[0], &hCPE->hStereoCng->cm_fx[0], Q15, sizeof( hCPE->hStereoCng->cm_fx ) / sizeof( hCPE->hStereoCng->cm_fx[0] ) ); @@ -814,9 +781,6 @@ ivas_error ivas_jbm_dec_tc( scale_sig32( hCPE->hStereoDft->buff_LBTCX_mem_fx, NS2SA( 16000, STEREO_DFT32MS_OVL_NS ), sub( hCPE->hStereoDft->q_dft, Q11 ) ); scale_sig32( hCPE->hStereoDft->ap_delay_mem_fx, NS2SA( 16000, DELAY_BWE_TOTAL_NS ), sub( hCPE->hStereoDft->q_dft, hCPE->hStereoDft->q_ap_fade_mem_fx ) ); hCPE->hStereoDft->q_ap_fade_mem_fx = hCPE->hStereoDft->q_dft; - - floatToFixed_arrL( &hCPE->hStereoDft->td_gain[0], &hCPE->hStereoDft->td_gain_fx[0], Q31, sizeof( hCPE->hStereoDft->td_gain_fx ) / sizeof( hCPE->hStereoDft->td_gain_fx[0] ) ); - //floatToFixed_arrL( &st_ivas->hSpar->hMdDec->mixer_mat_prev[0][0][0][0], &st_ivas->hSpar->hMdDec->mixer_mat_prev_fx[0][0][0][0], Q31, sizeof( st_ivas->hSpar->hMdDec->mixer_mat_prev_fx ) / sizeof( st_ivas->hSpar->hMdDec->mixer_mat_prev_fx[0][0][0][0] ) ); } st_ivas->hSpar->hMdDec->Q_mixer_mat = 30; for ( int ii = 0; ii < CPE_CHANNELS; ii++ ) @@ -834,14 +798,6 @@ ivas_error ivas_jbm_dec_tc( } fixedToFloat_arrL( &hCPE->prev_synth_fx[0][0], &hCPE->prev_synth[0][0], hCPE->q_prev_synth_fx, sizeof( hCPE->prev_synth ) / sizeof( hCPE->prev_synth[0][0] ) ); - for ( int ii = 0; ii < sizeof( hCPE->hStereoDft->hb_nrg_subr_fx ) / sizeof( hCPE->hStereoDft->hb_nrg_subr_fx[0] ); ii++ ) - { - hCPE->hStereoDft->hb_nrg_subr[ii] = ( (float) hCPE->hStereoDft->hb_nrg_subr_fx[ii] / ( (float) ( 1 << hCPE->hStereoDft->q_hb_nrg_subr ) ) ); - } - for ( int ii = 0; ii < sizeof( hCPE->hStereoDft->hb_nrg_fx ) / sizeof( hCPE->hStereoDft->hb_nrg_fx[0] ); ii++ ) - { - hCPE->hStereoDft->hb_nrg[ii] = ( (float) hCPE->hStereoDft->hb_nrg_fx[ii] * ( (float) ( 1 << hCPE->hStereoDft->q_hb_nrg ) ) ); - } IF( hCPE->hStereoCng != NULL ) { fixedToFloat_arr( &hCPE->hStereoCng->cm_fx[0], &hCPE->hStereoCng->cm[0], Q15, sizeof( hCPE->hStereoCng->cm_fx ) / sizeof( hCPE->hStereoCng->cm_fx[0] ) ); @@ -870,8 +826,6 @@ ivas_error ivas_jbm_dec_tc( scale_sig32( hCPE->hStereoDft->buff_LBTCX_mem_fx, NS2SA( 16000, STEREO_DFT32MS_OVL_NS ), sub( Q11, hCPE->hStereoDft->q_dft ) ); scale_sig32( hCPE->hStereoDft->ap_delay_mem_fx, NS2SA( 16000, DELAY_BWE_TOTAL_NS ), sub( Q11, hCPE->hStereoDft->q_ap_fade_mem_fx ) ); hCPE->hStereoDft->q_ap_fade_mem_fx = Q11; - - fixedToFloat_arrL( &hCPE->hStereoDft->td_gain_fx[0], &hCPE->hStereoDft->td_gain[0], Q31, sizeof( hCPE->hStereoDft->td_gain_fx ) / sizeof( hCPE->hStereoDft->td_gain_fx[0] ) ); } st_ivas->hSpar->hMdDec->Q_mixer_mat = 30; for ( int ii = 0; ii < CPE_CHANNELS; ii++ ) @@ -1628,40 +1582,6 @@ ivas_error ivas_jbm_dec_tc( hCPE->hStereoDft->q_smoothed_nrg = Q6; // hCPE->hStereoDft->q_dft; hCPE->hStereoDft->q_ap_delay_mem_fx = hCPE->hStereoDft->q_dft; } - for ( int ii = 0; ii < sizeof( hCPE->hStereoDft->hb_nrg_subr_fx ) / sizeof( hCPE->hStereoDft->hb_nrg_subr_fx[0] ); ii++ ) - { - if ( l_hb_nrg_subr < hCPE->hStereoDft->hb_nrg_subr[ii] ) - { - l_hb_nrg_subr = hCPE->hStereoDft->hb_nrg_subr[ii]; - } - } - hCPE->hStereoDft->q_hb_nrg_subr = 0; - if ( l_hb_nrg_subr > (float) MAX_32 ) - { - int quotient = (int) ceil( l_hb_nrg_subr / (float) MAX_32 ); - hCPE->hStereoDft->q_hb_nrg_subr = Q31 - norm_l( quotient ); - } - for ( int ii = 0; ii < sizeof( hCPE->hStereoDft->hb_nrg_subr_fx ) / sizeof( hCPE->hStereoDft->hb_nrg_subr_fx[0] ); ii++ ) - { - hCPE->hStereoDft->hb_nrg_subr_fx[ii] = (Word32) ( hCPE->hStereoDft->hb_nrg_subr[ii] / ( (float) ( 1 << hCPE->hStereoDft->q_hb_nrg_subr ) ) ); - } - for ( int ii = 0; ii < sizeof( hCPE->hStereoDft->hb_nrg_fx ) / sizeof( hCPE->hStereoDft->hb_nrg_fx[0] ); ii++ ) - { - if ( l_hb_nrg < hCPE->hStereoDft->hb_nrg[ii] ) - { - l_hb_nrg = hCPE->hStereoDft->hb_nrg[ii]; - } - } - hCPE->hStereoDft->q_hb_nrg = 0; - if ( l_hb_nrg > (float) MAX_32 ) - { - int quotient = (int) ceil( l_hb_nrg / (float) MAX_32 ); - hCPE->hStereoDft->q_hb_nrg = Q31 - norm_l( quotient ); - } - for ( int ii = 0; ii < sizeof( hCPE->hStereoDft->hb_nrg_fx ) / sizeof( hCPE->hStereoDft->hb_nrg_fx[0] ); ii++ ) - { - hCPE->hStereoDft->hb_nrg_fx[ii] = (Word32) ( hCPE->hStereoDft->hb_nrg[ii] * ( (float) ( 1 << hCPE->hStereoDft->q_hb_nrg ) ) ); - } IF( hCPE->hStereoCng != NULL ) { @@ -1694,9 +1614,6 @@ ivas_error ivas_jbm_dec_tc( scale_sig32( hCPE->hStereoDft->buff_LBTCX_mem_fx, NS2SA( 16000, STEREO_DFT32MS_OVL_NS ), sub( hCPE->hStereoDft->q_dft, Q11 ) ); scale_sig32( hCPE->hStereoDft->ap_delay_mem_fx, NS2SA( 16000, DELAY_BWE_TOTAL_NS ), sub( hCPE->hStereoDft->q_dft, hCPE->hStereoDft->q_ap_fade_mem_fx ) ); hCPE->hStereoDft->q_ap_fade_mem_fx = hCPE->hStereoDft->q_dft; - - floatToFixed_arrL( &hCPE->hStereoDft->td_gain[0], &hCPE->hStereoDft->td_gain_fx[0], Q31, sizeof( hCPE->hStereoDft->td_gain_fx ) / sizeof( hCPE->hStereoDft->td_gain_fx[0] ) ); - //floatToFixed_arrL( &st_ivas->hSpar->hMdDec->mixer_mat_prev[0][0][0][0], &st_ivas->hSpar->hMdDec->mixer_mat_prev_fx[0][0][0][0], Q31, sizeof( st_ivas->hSpar->hMdDec->mixer_mat_prev_fx ) / sizeof( st_ivas->hSpar->hMdDec->mixer_mat_prev_fx[0][0][0][0] ) ); } st_ivas->hSpar->hMdDec->Q_mixer_mat = Q30; #if 0 @@ -1723,14 +1640,6 @@ ivas_error ivas_jbm_dec_tc( Scale_sig32( p_output_fx[sba_ch_idx + i], L_FRAME48k, negate( s ) ); } fixedToFloat_arrL( &hCPE->prev_synth_fx[0][0], &hCPE->prev_synth[0][0], hCPE->q_prev_synth_fx, sizeof( hCPE->prev_synth ) / sizeof( hCPE->prev_synth[0][0] ) ); - for ( int ii = 0; ii < sizeof( hCPE->hStereoDft->hb_nrg_subr_fx ) / sizeof( hCPE->hStereoDft->hb_nrg_subr_fx[0] ); ii++ ) - { - hCPE->hStereoDft->hb_nrg_subr[ii] = ( (float) hCPE->hStereoDft->hb_nrg_subr_fx[ii] / ( (float) ( 1 << hCPE->hStereoDft->q_hb_nrg_subr ) ) ); - } - for ( int ii = 0; ii < sizeof( hCPE->hStereoDft->hb_nrg_fx ) / sizeof( hCPE->hStereoDft->hb_nrg_fx[0] ); ii++ ) - { - hCPE->hStereoDft->hb_nrg[ii] = ( (float) hCPE->hStereoDft->hb_nrg_fx[ii] * ( (float) ( 1 << hCPE->hStereoDft->q_hb_nrg ) ) ); - } IF( hCPE->hStereoCng != NULL ) { fixedToFloat_arr( &hCPE->hStereoCng->cm_fx[0], &hCPE->hStereoCng->cm[0], Q15, sizeof( hCPE->hStereoCng->cm_fx ) / sizeof( hCPE->hStereoCng->cm_fx[0] ) ); @@ -1758,9 +1667,6 @@ ivas_error ivas_jbm_dec_tc( scale_sig32( hCPE->hStereoDft->buff_LBTCX_mem_fx, NS2SA( 16000, STEREO_DFT32MS_OVL_NS ), sub( Q11, hCPE->hStereoDft->q_dft ) ); scale_sig32( hCPE->hStereoDft->ap_delay_mem_fx, NS2SA( 16000, DELAY_BWE_TOTAL_NS ), sub( Q11, hCPE->hStereoDft->q_ap_fade_mem_fx ) ); hCPE->hStereoDft->q_ap_fade_mem_fx = Q11; - - fixedToFloat_arrL( &hCPE->hStereoDft->td_gain_fx[0], &hCPE->hStereoDft->td_gain[0], Q31, sizeof( hCPE->hStereoDft->td_gain_fx ) / sizeof( hCPE->hStereoDft->td_gain_fx[0] ) ); - //fixedToFloat_arrL( &st_ivas->hSpar->hMdDec->mixer_mat_prev_fx[0][0][0][0], &st_ivas->hSpar->hMdDec->mixer_mat_prev[0][0][0][0], Q31, sizeof( st_ivas->hSpar->hMdDec->mixer_mat_prev_fx ) / sizeof( st_ivas->hSpar->hMdDec->mixer_mat_prev_fx[0][0][0][0] ) ); } st_ivas->hSpar->hMdDec->Q_mixer_mat = 30; FOR (int ii = 0; ii < CPE_CHANNELS; ii++) @@ -2767,41 +2673,6 @@ ivas_error ivas_jbm_dec_tc( hCPE->hStereoDft->q_ap_delay_mem_fx = hCPE->hStereoDft->q_dft; } - for ( int ii = 0; ii < sizeof( hCPE->hStereoDft->hb_nrg_subr_fx ) / sizeof( hCPE->hStereoDft->hb_nrg_subr_fx[0] ); ii++ ) - { - if ( l_hb_nrg_subr < hCPE->hStereoDft->hb_nrg_subr[ii] ) - { - l_hb_nrg_subr = hCPE->hStereoDft->hb_nrg_subr[ii]; - } - } - hCPE->hStereoDft->q_hb_nrg_subr = 0; - if ( l_hb_nrg_subr > (float) MAX_32 ) - { - int quotient = (int) ceil( l_hb_nrg_subr / (float) MAX_32 ); - hCPE->hStereoDft->q_hb_nrg_subr = Q31 - norm_l( quotient ); - } - for ( int ii = 0; ii < sizeof( hCPE->hStereoDft->hb_nrg_subr_fx ) / sizeof( hCPE->hStereoDft->hb_nrg_subr_fx[0] ); ii++ ) - { - hCPE->hStereoDft->hb_nrg_subr_fx[ii] = (Word32) ( hCPE->hStereoDft->hb_nrg_subr[ii] / ( (float) ( 1 << hCPE->hStereoDft->q_hb_nrg_subr ) ) ); - } - for ( int ii = 0; ii < sizeof( hCPE->hStereoDft->hb_nrg_fx ) / sizeof( hCPE->hStereoDft->hb_nrg_fx[0] ); ii++ ) - { - if ( l_hb_nrg < hCPE->hStereoDft->hb_nrg[ii] ) - { - l_hb_nrg = hCPE->hStereoDft->hb_nrg[ii]; - } - } - hCPE->hStereoDft->q_hb_nrg = 0; - if ( l_hb_nrg > (float) MAX_32 ) - { - int quotient = (int) ceil( l_hb_nrg / (float) MAX_32 ); - hCPE->hStereoDft->q_hb_nrg = Q31 - norm_l( quotient ); - } - for ( int ii = 0; ii < sizeof( hCPE->hStereoDft->hb_nrg_fx ) / sizeof( hCPE->hStereoDft->hb_nrg_fx[0] ); ii++ ) - { - hCPE->hStereoDft->hb_nrg_fx[ii] = (Word32) ( hCPE->hStereoDft->hb_nrg[ii] * ( (float) ( 1 << hCPE->hStereoDft->q_hb_nrg ) ) ); - } - IF( hCPE->hStereoCng != NULL ) { floatToFixed_arr( &hCPE->hStereoCng->cm[0], &hCPE->hStereoCng->cm_fx[0], Q15, sizeof( hCPE->hStereoCng->cm_fx ) / sizeof( hCPE->hStereoCng->cm_fx[0] ) ); @@ -2834,7 +2705,7 @@ ivas_error ivas_jbm_dec_tc( scale_sig32( hCPE->hStereoDft->ap_delay_mem_fx, NS2SA( 16000, DELAY_BWE_TOTAL_NS ), sub( hCPE->hStereoDft->q_dft, hCPE->hStereoDft->q_ap_fade_mem_fx ) ); hCPE->hStereoDft->q_ap_fade_mem_fx = hCPE->hStereoDft->q_dft; - floatToFixed_arrL( &hCPE->hStereoDft->td_gain[0], &hCPE->hStereoDft->td_gain_fx[0], Q31, sizeof( hCPE->hStereoDft->td_gain_fx ) / sizeof( hCPE->hStereoDft->td_gain_fx[0] ) ); + //floatToFixed_arrL( &hCPE->hStereoDft->td_gain[0], &hCPE->hStereoDft->td_gain_fx[0], Q31, sizeof( hCPE->hStereoDft->td_gain_fx ) / sizeof( hCPE->hStereoDft->td_gain_fx[0] ) ); } IF( st_ivas->hSpar != NULL ) { @@ -2866,14 +2737,6 @@ ivas_error ivas_jbm_dec_tc( } fixedToFloat_arrL( &hCPE->prev_synth_fx[0][0], &hCPE->prev_synth[0][0], hCPE->q_prev_synth_fx, sizeof( hCPE->prev_synth ) / sizeof( hCPE->prev_synth[0][0] ) ); - for ( int ii = 0; ii < sizeof( hCPE->hStereoDft->hb_nrg_subr_fx ) / sizeof( hCPE->hStereoDft->hb_nrg_subr_fx[0] ); ii++ ) - { - hCPE->hStereoDft->hb_nrg_subr[ii] = ( (float) hCPE->hStereoDft->hb_nrg_subr_fx[ii] / ( (float) ( 1 << hCPE->hStereoDft->q_hb_nrg_subr ) ) ); - } - for ( int ii = 0; ii < sizeof( hCPE->hStereoDft->hb_nrg_fx ) / sizeof( hCPE->hStereoDft->hb_nrg_fx[0] ); ii++ ) - { - hCPE->hStereoDft->hb_nrg[ii] = ( (float) hCPE->hStereoDft->hb_nrg_fx[ii] * ( (float) ( 1 << hCPE->hStereoDft->q_hb_nrg ) ) ); - } IF( hCPE->hStereoCng != NULL ) { fixedToFloat_arr( &hCPE->hStereoCng->cm_fx[0], &hCPE->hStereoCng->cm[0], Q15, sizeof( hCPE->hStereoCng->cm_fx ) / sizeof( hCPE->hStereoCng->cm_fx[0] ) ); @@ -2902,7 +2765,7 @@ ivas_error ivas_jbm_dec_tc( scale_sig32( hCPE->hStereoDft->ap_delay_mem_fx, NS2SA( 16000, DELAY_BWE_TOTAL_NS ), sub( Q11, hCPE->hStereoDft->q_ap_fade_mem_fx ) ); hCPE->hStereoDft->q_ap_fade_mem_fx = Q11; - fixedToFloat_arrL( &hCPE->hStereoDft->td_gain_fx[0], &hCPE->hStereoDft->td_gain[0], Q31, sizeof( hCPE->hStereoDft->td_gain_fx ) / sizeof( hCPE->hStereoDft->td_gain_fx[0] ) ); + //fixedToFloat_arrL( &hCPE->hStereoDft->td_gain_fx[0], &hCPE->hStereoDft->td_gain[0], Q31, sizeof( hCPE->hStereoDft->td_gain_fx ) / sizeof( hCPE->hStereoDft->td_gain_fx[0] ) ); } IF( st_ivas->hSpar != NULL ) { @@ -2910,7 +2773,7 @@ ivas_error ivas_jbm_dec_tc( st_ivas->hSpar->hMdDec->Q_mixer_mat = 31; for (int ii = 0; ii < st_ivas->hSpar->hMdDec->mix_mat_dim_0_1; ii++) { - fixedToFloat_arrL( &hCPE->hStereoDft->td_gain_fx[0], &hCPE->hStereoDft->td_gain[0], Q31, sizeof( hCPE->hStereoDft->td_gain_fx ) / sizeof( hCPE->hStereoDft->td_gain_fx[0] ) ); + //fixedToFloat_arrL( &hCPE->hStereoDft->td_gain_fx[0], &hCPE->hStereoDft->td_gain[0], Q31, sizeof( hCPE->hStereoDft->td_gain_fx ) / sizeof( hCPE->hStereoDft->td_gain_fx[0] ) ); } #if 0 IF( st_ivas->hSpar != NULL ) diff --git a/lib_dec/ivas_mct_dec.c b/lib_dec/ivas_mct_dec.c index 2ed47f58f..3c5cd9a64 100644 --- a/lib_dec/ivas_mct_dec.c +++ b/lib_dec/ivas_mct_dec.c @@ -2180,10 +2180,10 @@ static ivas_error ivas_mc_dec_reconfig( } #endif // IVAS_FLOAT_FIXED /*To be removed later: Contains memory allocations for floating point buffers*/ - if ( ( error = ivas_hp20_dec_reconfig( st_ivas, nchan_hp20_old ) ) != IVAS_ERR_OK ) - { - return error; - } + //if ( ( error = ivas_hp20_dec_reconfig( st_ivas, nchan_hp20_old ) ) != IVAS_ERR_OK ) + //{ + // return error; + //} /*-----------------------------------------------------------------* * Allocate the LFE handle that is coded separately after the allocation of the core coders diff --git a/lib_dec/ivas_omasa_dec.c b/lib_dec/ivas_omasa_dec.c index 98af89d37..ba46a5eb7 100644 --- a/lib_dec/ivas_omasa_dec.c +++ b/lib_dec/ivas_omasa_dec.c @@ -493,10 +493,10 @@ ivas_error ivas_omasa_dec_config_fx( } #ifdef IVAS_FLOAT_FIXED_TO_BE_REMOVED /* Float code to be removed. */ - IF( ( error = ivas_hp20_dec_reconfig( st_ivas, nchan_hp20_old ) ) != IVAS_ERR_OK ) - { - return error; - } + //IF( ( error = ivas_hp20_dec_reconfig( st_ivas, nchan_hp20_old ) ) != IVAS_ERR_OK ) + //{ + // return error; + //} #endif /* reconfigure core-coders for ISMs */ @@ -766,11 +766,17 @@ ivas_error ivas_omasa_dec_config( ivas_set_omasa_TC( st_ivas->ism_mode, st_ivas->nchan_ism, &st_ivas->nSCE, &st_ivas->nCPE ); /* re-configure hp20 memories */ +#ifdef IVAS_FLOAT_FIXED + IF ( ( error = ivas_hp20_dec_reconfig_fx( st_ivas, nchan_hp20_old ) ) != IVAS_ERR_OK ) + { + return error; + } +#else if ( ( error = ivas_hp20_dec_reconfig( st_ivas, nchan_hp20_old ) ) != IVAS_ERR_OK ) { return error; } - +#endif /* reconfigure core-coders for ISMs */ k = 0; while ( k < SIZE_IVAS_BRATE_TBL && ivas_total_brate != ivas_brate_tbl[k] ) diff --git a/lib_dec/ivas_pca_dec.c b/lib_dec/ivas_pca_dec.c index 492cff90d..ffb10f8eb 100644 --- a/lib_dec/ivas_pca_dec.c +++ b/lib_dec/ivas_pca_dec.c @@ -42,7 +42,7 @@ /*-----------------------------------------------------------------------* * Local function definitions *-----------------------------------------------------------------------*/ - +#ifndef IVAS_FLOAT_FIXED static int32_t ivas_bitstream_read_int32( Decoder_State *st0, const int16_t bits ) @@ -309,3 +309,4 @@ void ivas_pca_dec( return; } +#endif \ No newline at end of file diff --git a/lib_dec/ivas_sba_dec.c b/lib_dec/ivas_sba_dec.c index bc9814a9c..3d8c0efb5 100644 --- a/lib_dec/ivas_sba_dec.c +++ b/lib_dec/ivas_sba_dec.c @@ -764,10 +764,10 @@ ivas_error ivas_sba_dec_reconfigure( return error; } #endif // IVAS_FLOAT_FIXED - if ( ( error = ivas_hp20_dec_reconfig( st_ivas, nchan_hp20_old ) ) != IVAS_ERR_OK ) - { - return error; - } + //if ( ( error = ivas_hp20_dec_reconfig( st_ivas, nchan_hp20_old ) ) != IVAS_ERR_OK ) + //{ + // return error; + //} /*-----------------------------------------------------------------* * TD Decorrelator @@ -1267,7 +1267,7 @@ ivas_error ivas_sba_dec_reconfigure_fx( return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for PCA decoder" ); } - ivas_pca_dec_init( hSpar->hPCA ); + //ivas_pca_dec_init( hSpar->hPCA ); #ifdef IVAS_FLOAT_FIXED ivas_pca_dec_init_fx(hSpar->hPCA); #endif @@ -1535,12 +1535,12 @@ ivas_error ivas_sba_dec_reconfigure_fx( { return error; } -#endif // IVAS_FLOAT_FIXED +#else if ( ( error = ivas_hp20_dec_reconfig( st_ivas, nchan_hp20_old ) ) != IVAS_ERR_OK ) { return error; } - +#endif /*-----------------------------------------------------------------* * TD Decorrelator *-----------------------------------------------------------------*/ diff --git a/lib_dec/ivas_sba_dirac_stereo_dec_fx.c b/lib_dec/ivas_sba_dirac_stereo_dec_fx.c index b6929edf8..1aadd2881 100644 --- a/lib_dec/ivas_sba_dirac_stereo_dec_fx.c +++ b/lib_dec/ivas_sba_dirac_stereo_dec_fx.c @@ -731,6 +731,7 @@ static void ivas_sba_dirac_stereo_compute_td_stefi_nrgs( } hStereoDft->hb_nrg_subr_fx[0] = hb_nrg2; + hStereoDft->q_hb_nrg_subr = sub(shl(q_hb_synth, 1), 31); move32(); hb_nrg = L_add(hb_nrg, hb_nrg2); hb_nrg2 = EPSILON_FIX; diff --git a/lib_dec/ivas_sba_rendering_internal.c b/lib_dec/ivas_sba_rendering_internal.c index 7ef0a5f8b..97adb9a73 100644 --- a/lib_dec/ivas_sba_rendering_internal.c +++ b/lib_dec/ivas_sba_rendering_internal.c @@ -653,7 +653,7 @@ void ivas_ism2sba_sf_fx( return; } #else // IVAS_FLOAT_FIXED - + void ivas_ism2sba_sf( float *buffer_in[], /* i : TC buffer */ float *buffer_out[], /* o : TD signal buffers */ @@ -686,13 +686,8 @@ void ivas_ism2sba_sf( g2 = hIsmRendererData->interpolator + offset; tc = buffer_in[i] + offset; out = buffer_tmp[j]; -#ifdef IVAS_FLOAT_FIXED - gain = fix_to_float(hIsmRendererData->gains_fx[i][j], Q30); - prev_gain = fix_to_float(hIsmRendererData->prev_gains_fx[i][j], Q30); -#else gain = hIsmRendererData->gains[i][j]; prev_gain = hIsmRendererData->prev_gains[i][j]; -#endif for ( k = 0; k < n_samples_to_render; k++ ) { g1 = 1.0f - *g2; diff --git a/lib_dec/ivas_spar_decoder.c b/lib_dec/ivas_spar_decoder.c index af6840a9f..5f23d5dc7 100644 --- a/lib_dec/ivas_spar_decoder.c +++ b/lib_dec/ivas_spar_decoder.c @@ -381,7 +381,7 @@ ivas_error ivas_spar_dec_open_fx( return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for PCA decoder" ); } - ivas_pca_dec_init( hSpar->hPCA ); + //ivas_pca_dec_init( hSpar->hPCA ); #ifdef IVAS_FLOAT_FIXED ivas_pca_dec_init_fx(hSpar->hPCA); #endif diff --git a/lib_dec/ivas_stat_dec.h b/lib_dec/ivas_stat_dec.h index 589f269d1..adf8e5727 100644 --- a/lib_dec/ivas_stat_dec.h +++ b/lib_dec/ivas_stat_dec.h @@ -297,11 +297,19 @@ typedef struct stereo_dft_dec_data_struct float smooth_res_nrg[STEREO_DFT_BAND_MAX]; #endif int16_t core_hist[STEREO_DFT_CORE_HIST_MAX]; +#ifndef IVAS_FLOAT_FIXED float hb_stefi_sig[L_FRAME48k + NS2SA( 48000, STEREO_DFT_TD_STEFI_DELAY_NS )]; +#endif int16_t hb_stefi_delay; +#ifndef IVAS_FLOAT_FIXED float hb_nrg[STEREO_DFT_CORE_HIST_MAX]; +#endif +#ifndef IVAS_FLOAT_FIXED float hb_nrg_subr[STEREO_DFT_NBDIV]; +#endif +#ifndef IVAS_FLOAT_FIXED float td_gain[STEREO_DFT_CORE_HIST_MAX]; +#endif #ifdef IVAS_FLOAT_FIXED Word32 smooth_dmx_nrg_fx[STEREO_DFT_BAND_MAX]; /* Q(q_smoothed_nrg) */ Word32 smooth_res_nrg_fx[STEREO_DFT_BAND_MAX]; /* Q(q_smoothed_nrg) */ @@ -756,6 +764,7 @@ typedef struct ivas_dirac_dec_data_structure typedef struct dirac_output_synthesis_cov_state_structure { /* only pointer to local buffers */ +#ifndef IVAS_FLOAT_FIXED float *direct_power_factor; float *diffuse_power_factor; @@ -769,7 +778,7 @@ typedef struct dirac_output_synthesis_cov_state_structure float *proto_diffuse_buffer_f; /* Buffer for diffuse sound prototype signals. Size: 2*num_freq_bands*num_channels*buffer_length (complex interleaved). */ float *proto_power; /* Smoothed power of the prototype signals. Size: num_freq_bands*num_channels. */ float *proto_power_diff; - +#endif float *cx_old[CLDFB_NO_CHANNELS_MAX]; float *cy_old[CLDFB_NO_CHANNELS_MAX]; float *mixing_matrix_old[CLDFB_NO_CHANNELS_MAX]; @@ -1015,10 +1024,14 @@ typedef struct ivas_agc_dec_state_t /* PCA structure */ typedef struct { +#ifndef IVAS_FLOAT_FIXED float prev_ql[IVAS_PCA_INTERP]; float prev_qr[IVAS_PCA_INTERP]; +#endif int16_t prev_pca_bypass; +#ifndef IVAS_FLOAT_FIXED float mem_eigVec_interp[IVAS_PCA_LEN_INTERP_EIG_DEC]; +#endif /* parser output: */ int16_t pca_bypass; int32_t index[2]; @@ -1495,8 +1508,9 @@ typedef struct Decoder_Struct uint16_t *bit_stream; /* Pointer to bitstream buffer */ int16_t writeFECoffset; /* parameter for debugging JBM stuff */ - +#ifndef IVAS_FLOAT_FIXED float **mem_hp20_out; /* output signals HP filter memories */ +#endif IVAS_LIMITER_HANDLE hLimiter; /* Limiter handle */ float *p_output_f[MAX_OUTPUT_CHANNELS+MAX_NUM_OBJECTS]; /* floating-point output audio buffers */ diff --git a/lib_dec/ivas_stereo_dft_dec.c b/lib_dec/ivas_stereo_dft_dec.c index 7ac9987ad..e57859e02 100644 --- a/lib_dec/ivas_stereo_dft_dec.c +++ b/lib_dec/ivas_stereo_dft_dec.c @@ -707,9 +707,9 @@ void stereo_dft_dec_reset( set_s( hStereoDft->core_hist, ACELP_CORE, STEREO_DFT_CORE_HIST_MAX ); - set_zero( hStereoDft->hb_stefi_sig, L_FRAME48k + NS2SA( 48000, STEREO_DFT_TD_STEFI_DELAY_NS ) ); - set_zero( hStereoDft->hb_nrg, STEREO_DFT_CORE_HIST_MAX ); - set_zero( hStereoDft->td_gain, STEREO_DFT_CORE_HIST_MAX ); + //set_zero( hStereoDft->hb_stefi_sig, L_FRAME48k + NS2SA( 48000, STEREO_DFT_TD_STEFI_DELAY_NS ) ); + //set_zero( hStereoDft->hb_nrg, STEREO_DFT_CORE_HIST_MAX ); + //set_zero( hStereoDft->td_gain, STEREO_DFT_CORE_HIST_MAX ); #ifdef IVAS_FLOAT_FIXED set32_fx(hStereoDft->hb_stefi_sig_fx, 0, L_FRAME48k + NS2SA(48000, STEREO_DFT_TD_STEFI_DELAY_NS)); @@ -1070,9 +1070,9 @@ void stereo_dft_dec_update( hStereoDft->core_hist[i] = hStereoDft->core_hist[i - 1]; } - mvr2r( hStereoDft->hb_stefi_sig + output_frame, hStereoDft->hb_stefi_sig, hStereoDft->hb_stefi_delay ); - mvr2r( hStereoDft->hb_nrg, hStereoDft->hb_nrg + 1, STEREO_DFT_CORE_HIST_MAX - 1 ); - mvr2r( hStereoDft->td_gain, hStereoDft->td_gain + 1, STEREO_DFT_CORE_HIST_MAX - 1 ); + //mvr2r( hStereoDft->hb_stefi_sig + output_frame, hStereoDft->hb_stefi_sig, hStereoDft->hb_stefi_delay ); + //mvr2r( hStereoDft->hb_nrg, hStereoDft->hb_nrg + 1, STEREO_DFT_CORE_HIST_MAX - 1 ); + //mvr2r( hStereoDft->td_gain, hStereoDft->td_gain + 1, STEREO_DFT_CORE_HIST_MAX - 1 ); #ifndef IVAS_FLOAT_FIXED if ( sba_dirac_stereo_flag ) @@ -3517,7 +3517,302 @@ void stereo_dft_generate_res_pred( * * * ---------------------------------------------------------------*/ +#if 1 +void stereo_dft_dec_smooth_parameters( + STEREO_DFT_DEC_DATA_HANDLE hStereoDft, /* i/o: decoder DFT stereo handle */ + const int16_t prev_sid_nodata, /* i : Previous SID/No data indicator */ + const int16_t active_frame_counter, /* i : Active frame counter */ + const int32_t element_brate /* i : Element bitrate */ +) +{ + int16_t k_offset, k, k2, b, N_div; + float *pIpd, *pInterpol; + float *pgIpd; + float *pSideGain; + float diff_ipd; + int16_t nbands; + int16_t max_res_pred_ind; + + N_div = STEREO_DFT_NBDIV; + k_offset = STEREO_DFT_OFFSET; + + if ( hStereoDft->frame_sid_nodata || prev_sid_nodata ) + { + k = 1; + for ( b = 0; b < hStereoDft->nbands; b++ ) + { + *( hStereoDft->side_gain + ( ( k + k_offset ) - 1 ) * STEREO_DFT_BAND_MAX + b ) = *( hStereoDft->side_gain + ( k + k_offset ) * STEREO_DFT_BAND_MAX + b ); + } + + if ( hStereoDft->frame_sid_nodata ) + { + /* set new xfade target if new itd received */ + if ( hStereoDft->gipd[k + k_offset] != hStereoDft->ipd_xfade_target ) + { + if ( ( hStereoDft->gipd[k + k_offset] - hStereoDft->ipd_xfade_prev ) > EVS_PI ) + { + hStereoDft->ipd_xfade_target = hStereoDft->gipd[k + k_offset] - 2 * EVS_PI; + hStereoDft->ipd_xfade_step = ( hStereoDft->ipd_xfade_target - hStereoDft->ipd_xfade_prev ) / ( STEREO_DFT_ITD_CNG_XFADE - hStereoDft->ipd_xfade_counter ); + } + else if ( ( hStereoDft->ipd_xfade_prev - hStereoDft->gipd[k + k_offset] ) > EVS_PI ) + { + hStereoDft->ipd_xfade_target = hStereoDft->gipd[k + k_offset] + 2 * EVS_PI; + hStereoDft->ipd_xfade_step = ( hStereoDft->ipd_xfade_target - hStereoDft->ipd_xfade_prev ) / ( STEREO_DFT_ITD_CNG_XFADE - hStereoDft->ipd_xfade_counter ); + } + else + { + hStereoDft->ipd_xfade_target = hStereoDft->gipd[k + k_offset]; + hStereoDft->ipd_xfade_step = ( hStereoDft->ipd_xfade_target - hStereoDft->ipd_xfade_prev ) / ( STEREO_DFT_ITD_CNG_XFADE - hStereoDft->ipd_xfade_counter ); + } + } + + /* xfade */ + if ( hStereoDft->ipd_xfade_prev != hStereoDft->ipd_xfade_target && hStereoDft->ipd_xfade_counter < STEREO_DFT_ITD_CNG_XFADE && hStereoDft->last_active_element_brate <= 24400 ) + { + hStereoDft->gipd[k + k_offset] = hStereoDft->ipd_xfade_prev + hStereoDft->ipd_xfade_step; + hStereoDft->ipd_xfade_prev = hStereoDft->gipd[k + k_offset]; + hStereoDft->ipd_xfade_counter++; + } + } + else + { + /* First active frame, "reset" everything if long enough active encoding, only triggered if STEREO_DFT_ITD_CNG_XFADE_RESET = -1 */ + if ( active_frame_counter > STEREO_DFT_ITD_CNG_XFADE_RESET ) + { + hStereoDft->ipd_xfade_target = hStereoDft->gipd[k + k_offset]; + hStereoDft->ipd_xfade_prev = hStereoDft->gipd[k + k_offset]; + hStereoDft->ipd_xfade_counter = 0; + } + } + + for ( k2 = 1; k2 < hStereoDft->prm_res[k + k_offset]; k2++ ) + { + hStereoDft->gipd[( k + k_offset ) - k2] = hStereoDft->gipd[k + k_offset]; + } + + if ( hStereoDft->frame_sid_nodata ) + { + /* set new xfade target if new itd received */ + if ( hStereoDft->itd[k + k_offset] != hStereoDft->itd_xfade_target ) + { + hStereoDft->itd_xfade_target = hStereoDft->itd[k + k_offset]; + hStereoDft->itd_xfade_step = ( hStereoDft->itd_xfade_target - hStereoDft->itd_xfade_prev ) / ( STEREO_DFT_ITD_CNG_XFADE - hStereoDft->itd_xfade_counter ); + } + + /* xfade */ + if ( hStereoDft->itd_xfade_prev != hStereoDft->itd_xfade_target && hStereoDft->itd_xfade_counter < STEREO_DFT_ITD_CNG_XFADE && hStereoDft->last_active_element_brate <= 24400 ) + { + hStereoDft->itd[k + k_offset] = hStereoDft->itd_xfade_prev + hStereoDft->itd_xfade_step; + hStereoDft->itd_xfade_prev = hStereoDft->itd[k + k_offset]; + hStereoDft->itd_xfade_counter++; + } + } + else + { + /* First active frame, "reset" everything if long enough active encoding, only triggered if STEREO_DFT_ITD_CNG_XFADE_RESET = -1 */ + if ( active_frame_counter > STEREO_DFT_ITD_CNG_XFADE_RESET ) + { + hStereoDft->itd_xfade_target = hStereoDft->itd[k + k_offset]; + hStereoDft->itd_xfade_prev = hStereoDft->itd[k + k_offset]; + hStereoDft->itd_xfade_counter = 0; + } + hStereoDft->last_active_element_brate = element_brate; + } + for ( k2 = 1; k2 < hStereoDft->prm_res[k + k_offset]; k2++ ) + { + hStereoDft->itd[( k + k_offset ) - k2] = hStereoDft->itd[k + k_offset]; + } + + return; + } + + /* Active frame, "reset" everything "reset" everything if long enough active encoding */ + if ( active_frame_counter > STEREO_DFT_ITD_CNG_XFADE_RESET ) + { + hStereoDft->itd_xfade_counter = 0; + hStereoDft->itd_xfade_target = hStereoDft->itd[STEREO_DFT_NBDIV - 1]; + hStereoDft->itd_xfade_prev = hStereoDft->itd[STEREO_DFT_NBDIV - 1]; + hStereoDft->ipd_xfade_counter = 0; + hStereoDft->ipd_xfade_target = hStereoDft->gipd[STEREO_DFT_NBDIV - 1]; + hStereoDft->ipd_xfade_prev = hStereoDft->gipd[STEREO_DFT_NBDIV - 1]; + } + + hStereoDft->last_active_element_brate = element_brate; + + for ( k = hStereoDft->prm_res[k_offset] - 1; k < N_div; k += hStereoDft->prm_res[k + k_offset] ) + { + max_res_pred_ind = 0; + + if ( hStereoDft->reverb_flag == 1 ) + { + nbands = min( 10, hStereoDft->nbands_respred ); + + /*Shift 2 last bands residual prediction gains for SWB/FB*/ + if ( hStereoDft->band_res[k_offset] == STEREO_DFT_BAND_RES_HIGH ) + { + for ( b = hStereoDft->nbands_respred - 1; b >= nbands; b-- ) + { + hStereoDft->res_gains_ind[1][b + STEREO_DFT_BAND_MAX] = + hStereoDft->res_gains_ind[1][b - STEREO_DFT_RES_PRED_BAND_MIN_RED + hStereoDft->res_pred_band_min + STEREO_DFT_BAND_MAX]; + hStereoDft->res_gains_ind[1][b - STEREO_DFT_RES_PRED_BAND_MIN_RED + hStereoDft->res_pred_band_min + STEREO_DFT_BAND_MAX] = 0; + } + } + + /* Get maximal index */ + for ( b = hStereoDft->res_pred_band_min; b < ( nbands - STEREO_DFT_RES_PRED_BAND_MIN_CONST ); b++ ) + { + if ( max_res_pred_ind < hStereoDft->res_gains_ind[1][b + STEREO_DFT_BAND_MAX] ) + { + max_res_pred_ind = (int16_t) hStereoDft->res_gains_ind[1][b + STEREO_DFT_BAND_MAX]; + } + } + + /* predictive values */ + for ( ; b < nbands; b++ ) + { + assert( hStereoDft->res_gains_ind[1][b + STEREO_DFT_BAND_MAX] == 0 ); + hStereoDft->res_gains_ind[1][b + STEREO_DFT_BAND_MAX] = max_res_pred_ind; + } + } + + for ( b = hStereoDft->res_pred_band_min; b < hStereoDft->res_cod_band_max; b++ ) + { + float tmp; + int16_t tmps1, tmps2; + + hStereoDft->res_gains_ind[0][b] = hStereoDft->res_gains_ind[0][b + STEREO_DFT_BAND_MAX]; + /*stereo_dft_dequantize_res_gains_f(&hStereoDft->res_gains_ind[0][b], &hStereoDft->res_gains_ind[1][b+STEREO_DFT_BAND_MAX],hStereoDft->side_gain+(k+k_offset)*STEREO_DFT_BAND_MAX+b, hStereoDft->res_pred_gain+(k+k_offset)*STEREO_DFT_BAND_MAX+b, 1);*/ + tmps1 = (int16_t) ( hStereoDft->res_gains_ind[0][b] ); + tmps2 = (int16_t) ( hStereoDft->res_gains_ind[1][b + STEREO_DFT_BAND_MAX] ); + stereo_dft_dequantize_res_gains( &tmps1, &tmps2, hStereoDft->side_gain + ( k + k_offset ) * STEREO_DFT_BAND_MAX + b, hStereoDft->res_pred_gain + ( k + k_offset ) * STEREO_DFT_BAND_MAX + b, 1 ); + + if ( hStereoDft->attackPresent ) + { + hStereoDft->res_gains_ind[1][b] = 0.8f * hStereoDft->res_gains_ind[1][b]; + } + else if ( hStereoDft->trans || ( hStereoDft->res_pred_mode[k] && ( hStereoDft->res_gains_ind[1][b + STEREO_DFT_BAND_MAX] < 2.f ) ) ) + { + hStereoDft->res_gains_ind[1][b] = 0.6f * hStereoDft->res_gains_ind[1][b] + 0.4f * hStereoDft->res_gains_ind[1][b + STEREO_DFT_BAND_MAX]; + } + else + { + hStereoDft->res_gains_ind[1][b] = dft_alpha_s2[b] * hStereoDft->res_gains_ind[1][b] + ( 1 - dft_alpha_s2[b] ) * hStereoDft->res_gains_ind[1][b + STEREO_DFT_BAND_MAX]; + } + + stereo_dft_dequantize_res_gains_f( &hStereoDft->res_gains_ind[0][b], &hStereoDft->res_gains_ind[1][b], &tmp, hStereoDft->res_pred_gain + ( k + k_offset ) * STEREO_DFT_BAND_MAX + b, 1 ); + } + + /* Smoothing of prediction gains between ftrames */ + for ( ; b < hStereoDft->nbands; b++ ) + { + if ( hStereoDft->attackPresent ) + { + hStereoDft->res_gains_ind[0][b] = hStereoDft->res_gains_ind[0][b + STEREO_DFT_BAND_MAX]; + hStereoDft->res_gains_ind[1][b] = 0.8f * hStereoDft->res_gains_ind[1][b]; + } + else if ( hStereoDft->trans || ( hStereoDft->res_pred_mode[k] && ( hStereoDft->res_gains_ind[1][b + STEREO_DFT_BAND_MAX] < 2.f ) ) ) + { + hStereoDft->res_gains_ind[0][b] = hStereoDft->res_gains_ind[0][b + STEREO_DFT_BAND_MAX]; + + if ( hStereoDft->hConfig->band_res == STEREO_DFT_BAND_RES_LOW ) + { + hStereoDft->res_gains_ind[1][b] = dft_alpha_w_b2[b] * hStereoDft->res_gains_ind[1][b] + ( 1 - dft_alpha_w_b2[b] ) * hStereoDft->res_gains_ind[1][b + STEREO_DFT_BAND_MAX]; + } + else + { + hStereoDft->res_gains_ind[1][b] = dft_alpha_w[b] * hStereoDft->res_gains_ind[1][b] + ( 1 - dft_alpha_w[b] ) * hStereoDft->res_gains_ind[1][b + STEREO_DFT_BAND_MAX]; + } + } + else + { + if ( hStereoDft->hConfig->band_res == STEREO_DFT_BAND_RES_LOW ) + { + hStereoDft->res_gains_ind[0][b] = dft_alpha_s_b2[b] * hStereoDft->res_gains_ind[0][b] + ( 1 - dft_alpha_s_b2[b] ) * hStereoDft->res_gains_ind[0][b + STEREO_DFT_BAND_MAX]; + hStereoDft->res_gains_ind[1][b] = dft_alpha_s2_b2[b] * hStereoDft->res_gains_ind[1][b] + ( 1 - dft_alpha_s2_b2[b] ) * hStereoDft->res_gains_ind[1][b + STEREO_DFT_BAND_MAX]; + } + else + { + hStereoDft->res_gains_ind[0][b] = dft_alpha_s[b] * hStereoDft->res_gains_ind[0][b] + ( 1 - dft_alpha_s[b] ) * hStereoDft->res_gains_ind[0][b + STEREO_DFT_BAND_MAX]; + hStereoDft->res_gains_ind[1][b] = dft_alpha_s2[b] * hStereoDft->res_gains_ind[1][b] + ( 1 - dft_alpha_s2[b] ) * hStereoDft->res_gains_ind[1][b + STEREO_DFT_BAND_MAX]; + } + } + + if ( !hStereoDft->recovery_flg ) + { + stereo_dft_dequantize_res_gains_f( &hStereoDft->res_gains_ind[0][b], &hStereoDft->res_gains_ind[1][b], hStereoDft->side_gain + ( k + k_offset ) * STEREO_DFT_BAND_MAX + b, hStereoDft->res_pred_gain + ( k + k_offset ) * STEREO_DFT_BAND_MAX + b, 1 ); + } + } + + /* Smoothing of IPDs*/ + pgIpd = hStereoDft->gipd + ( k + k_offset ); + diff_ipd = pgIpd[0] - pgIpd[-hStereoDft->prm_res[k + k_offset]]; + if ( diff_ipd < -EVS_PI ) + { + pgIpd[0] += PI2; + } + else if ( diff_ipd > EVS_PI ) + { + pgIpd[0] -= PI2; + } + + if ( !hStereoDft->attackPresent ) + { + if ( hStereoDft->wasTransient ) + { + pgIpd[0] = 0.8f * pgIpd[0] + 0.2f * pgIpd[-hStereoDft->prm_res[k + k_offset]]; + } + else + { + pgIpd[0] = 0.5f * pgIpd[0] + 0.5f * pgIpd[-hStereoDft->prm_res[k + k_offset]]; + } + } + + + if ( !hStereoDft->attackPresent ) + { + pSideGain = hStereoDft->side_gain + ( k + k_offset ) * STEREO_DFT_BAND_MAX; + for ( b = 0; b < hStereoDft->res_cod_band_max; b++ ) + { + pSideGain[b] = dft_res_cod_alpha[b] * pSideGain[b] + ( 1 - dft_res_cod_alpha[b] ) * pSideGain[b - hStereoDft->prm_res[k + k_offset] * STEREO_DFT_BAND_MAX]; + } + } + + /*Interpolation between DFT slots*/ + for ( k2 = 1; k2 < hStereoDft->prm_res[k + k_offset]; k2++ ) + { + pInterpol = hStereoDft->gipd + ( ( k + k_offset ) - k2 ); + pIpd = hStereoDft->gipd + ( k + k_offset ); + if ( hStereoDft->attackPresent ) + { + *( pInterpol ) = *( pIpd ); + } + else + { + *( pInterpol ) = *( hStereoDft->gipd + ( k + k_offset - hStereoDft->prm_res[k + k_offset] ) ); + } + + for ( b = 0; b < hStereoDft->nbands; b++ ) + { + *( hStereoDft->res_pred_gain + ( ( k + k_offset ) - k2 ) * STEREO_DFT_BAND_MAX + b ) = *( hStereoDft->res_pred_gain + ( k + k_offset - hStereoDft->prm_res[k + k_offset] ) * STEREO_DFT_BAND_MAX + b ); + + if ( b < hStereoDft->res_cod_band_max || hStereoDft->attackPresent || hStereoDft->trans || ( hStereoDft->res_pred_mode[k] && ( hStereoDft->res_gains_ind[1][b + STEREO_DFT_BAND_MAX] < 2.f ) ) ) + { + *( hStereoDft->side_gain + ( ( k + k_offset ) - k2 ) * STEREO_DFT_BAND_MAX + b ) = *( hStereoDft->side_gain + ( k + k_offset ) * STEREO_DFT_BAND_MAX + b ); + } + else + { + *( hStereoDft->side_gain + ( ( k + k_offset ) - k2 ) * STEREO_DFT_BAND_MAX + b ) = *( hStereoDft->side_gain + ( k + k_offset - hStereoDft->prm_res[k + k_offset] ) * STEREO_DFT_BAND_MAX + b ); + } + } + + hStereoDft->itd[( k + k_offset ) - k2] = hStereoDft->itd[k + k_offset]; + } /*end of interpolation*/ + } + + return; +} +#else void stereo_dft_dec_smooth_parameters( STEREO_DFT_DEC_DATA_HANDLE hStereoDft, /* i/o: decoder DFT stereo handle */ const int16_t prev_sid_nodata, /* i : Previous SID/No data indicator */ @@ -3820,7 +4115,7 @@ void stereo_dft_dec_smooth_parameters( return; } - +#endif /*--------------------------------------------------------------- * stereo_dft_adapt_sf_delay() diff --git a/lib_dec/ivas_stereo_dft_dec_fx.c b/lib_dec/ivas_stereo_dft_dec_fx.c index 002582f22..14122fe14 100644 --- a/lib_dec/ivas_stereo_dft_dec_fx.c +++ b/lib_dec/ivas_stereo_dft_dec_fx.c @@ -2222,26 +2222,24 @@ static void stereo_dft_compute_td_stefi_params_fx( } wsum = L_shl(wsum, sub(Q16 , shift_g)); pred_g = BASOP_Util_Divide3232_Scale(pred_g, wsum, &q_div); - IF (GT_16(q_div, 16)) + IF (GT_16(sub(15, q_div), 15)) { - pred_g = L_shl(pred_g, 16); - q_pred_g = sub(q_div , 16); + pred_g = L_shl(pred_g, q_div); + q_pred_g = 15; } ELSE { - pred_g = L_shl(pred_g, q_div); - q_pred_g = 0; + q_pred_g = sub(15, q_div); } pred_gain_avg = BASOP_Util_Divide3232_Scale(pred_gain_avg, wsum, &q_div); - IF (GT_16(q_div, 16)) + IF (GT_16(sub(15, q_div), 15)) { - pred_gain_avg = L_shl(pred_gain_avg, 16); - q_pred_gain_avg = sub(q_div , 16); + pred_gain_avg = L_shl(pred_gain_avg, q_div); + q_pred_gain_avg = 15; } ELSE { - pred_gain_avg = L_shl(pred_gain_avg, q_div); - q_pred_gain_avg = 0; + q_pred_gain_avg = sub(15, q_div);; } nrg_DMX = hStereoDft->hb_nrg_fx[0]; nrg_pred_DMX = hStereoDft->hb_nrg_fx[1]; @@ -2277,9 +2275,8 @@ static void stereo_dft_compute_td_stefi_params_fx( } hStereoDft->td_gain_fx[0] = L_deposit_h((Word16)g2); + hStereoDft->q_td_gain[0] = add(16, q_pred_gain_avg); move32(); - if (q_pred_gain_avg != 0) - hStereoDft->q_td_gain[0] = q_pred_gain_avg; move16(); #ifdef DBG_TD_STEFI diff --git a/lib_dec/ivas_stereo_icbwe_dec.c b/lib_dec/ivas_stereo_icbwe_dec.c index 7e0d1ab82..150df7e1d 100644 --- a/lib_dec/ivas_stereo_icbwe_dec.c +++ b/lib_dec/ivas_stereo_icbwe_dec.c @@ -645,6 +645,7 @@ void stereo_icBWE_dec_fx( hCPE->hStereoDft->hb_nrg_subr_fx[0] = hb_nrg2_fx; move32(); + hStereoDft->q_hb_nrg_subr = sub(add(*Q_syn, synthRef_shift), 31); hb_nrg_fx = L_add( hb_nrg_fx, hb_nrg2_fx ); hb_nrg2_fx = 0; move32(); @@ -660,6 +661,8 @@ void stereo_icBWE_dec_fx( hb_nrg_fx = L_add( hb_nrg_fx, hb_nrg2_fx ); Copy32( synthRef_fx, hCPE->hStereoDft->hb_stefi_sig_fx + hCPE->hStereoDft->hb_stefi_delay, output_frame ); + + Scale_sig32(hCPE->hStereoDft->hb_stefi_sig_fx + hCPE->hStereoDft->hb_stefi_delay, output_frame, -5); } ELSE { @@ -669,7 +672,7 @@ void stereo_icBWE_dec_fx( move32(); hCPE->hStereoDft->hb_nrg_subr_fx[1] = ( Mpy_32_16_1( hCPE->hStereoDft->hb_nrg_subr_fx[1], shl( hCPE->hStereoDft->NFFT / 2, 6 ) ) ); // 2 * (Qx + SynthRef_shift) - 40 move32(); - hCPE->hStereoDft->Q_nrg_subr = sub( shl( ( *Q_syn + synthRef_shift ), 1 ), 40 ); + hCPE->hStereoDft->q_hb_nrg_subr = sub( shl( ( *Q_syn + synthRef_shift ), 1 ), 40 ); hCPE->hStereoDft->hb_nrg_fx[0] = hb_nrg_fx; // 2 * (Qx + SynthRef_shift) - 31 move32(); hCPE->hStereoDft->td_gain_fx[0] = 0; @@ -2017,6 +2020,8 @@ void stereo_icBWE_decproc_fx( dftOvlLen = hCPE->hStereoDft->dft32ms_ovl; move16(); + //Scale_sig32(hCPE->hStereoDft->td_gain_fx, STEREO_DFT_CORE_HIST_MAX, -12); + FOR( i = 0; i < dftOvlLen; i++ ) { win_in_fx = L_mult( win_dft_fx[mult0( STEREO_DFT32MS_STEP, i )], win_dft_fx[mult0( STEREO_DFT32MS_STEP, i )] ); /* Q31 */ -- GitLab From 23ab02e5312945500bb1644d0e220f925ebbd1a2 Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Mon, 29 Apr 2024 20:03:11 +0530 Subject: [PATCH 2/3] High MLD issue fix --- lib_com/ivas_pca_tools.c | 29 ++++++++++++++++------------- lib_dec/ivas_pca_dec_fx.c | 18 +++++++++--------- 2 files changed, 25 insertions(+), 22 deletions(-) diff --git a/lib_com/ivas_pca_tools.c b/lib_com/ivas_pca_tools.c index 9cf0732c7..b3f04d7ef 100644 --- a/lib_com/ivas_pca_tools.c +++ b/lib_com/ivas_pca_tools.c @@ -951,7 +951,7 @@ static void sp2cart_fx( q[3] = mult( getSinWord16( ph3 ), s1s2 ); // q15 q[2] = mult( getCosWord16( ph3 ), s1s2 ); // q15 q[1] = mult( getCosWord16( ph2 ), s1 ); // q15 - q[0] = getCosWord16( ph1 ); // q14 + q[0] = shl_sat(getCosWord16( ph1 ), 1); //q15 return; } @@ -975,12 +975,12 @@ static Word16 calc_n2_fx( const Word16 ph1 ) { Word16 n2; - Word16 temp = mult( 23040, getSinWord16( ph1 ) ); // q8 + Word32 temp = L_mult( 23040, getSinWord16( ph1 ) ); // q8 n2 = round_fx( temp ); - + n2 = shr(n2, 7); IF( EQ_16( s_and( n2, 1 ), 0 ) ) { - n2 = add( n2, ONE_IN_Q8 ); + n2 = add( n2, 1 ); } return n2; @@ -1015,19 +1015,21 @@ static Word16 calc_n3_fx( const Word16 ph2 ) { Word16 n3; - Word16 temp1 = mult( 23040, getSinWord16( ph1 ) ); // q7 + q15 - q15 - n3 = round_fx( mult( temp1, getSinWord16( ph2 ) ) ); // q7 + q15 - q15 + Word16 temp1 = mult( getSinWord16( ph2 ), getSinWord16( ph1 ) ); // q7 + q15 - q15 + n3 = round_fx( L_mult( temp1, getSinWord16( ph2 ) ) ); // q7 + q15 - q15 + + n3 = shr(n3, 8); IF( EQ_16( n3, 0 ) ) { - n3 = ONE_IN_Q7; + n3 = 1; move16(); } ELSE { IF( ( s_and( n3, 1 ) ) == 1 ) { - n3 = add( n3, ONE_IN_Q7 ); + n3 = add( n3, 1 ); } } @@ -1438,7 +1440,7 @@ void pca_dec_s3_fx( Word16 num_fx = 12868; d_fx = idiv1616( num_fx, n1 ); // Q12 - ph1_q_fx = mult( index1, d_fx ); // Q12 + ph1_q_fx = i_mult( index1, d_fx ); // Q12 n2 = calc_n2_fx( ph1_q_fx ); @@ -1467,8 +1469,8 @@ void pca_dec_s3_fx( num_fx = 12868; move16(); - d_fx = idiv1616( num_fx, n1 ); // Q12 - ph2_q_fx = mult( index2, d_fx ); // Q12 + d_fx = idiv1616( num_fx, sub(n2, 1) ); // Q12 + ph2_q_fx = i_mult( index2, d_fx ); // Q12 } j = L_sub(j, ivas_pca_offset_index2[index2 + get_pca_offset_n2_fx( index1 )]); @@ -1486,8 +1488,9 @@ void pca_dec_s3_fx( { num_fx = 6434; move16(); - d_fx = idiv1616( num_fx, n3 ); // Q11 - ph3_q_fx = mult( index3, d_fx ); // Q11 + d_fx = idiv1616( num_fx, n3 ); // Q10 + ph3_q_fx = round_fx(L_mult( index3, d_fx )); // Q10 + //ph3_q_fx = shl(ph3_q_fx, 2); } sp2cart_fx( ph1_q_fx, ph2_q_fx, ph3_q_fx, q_fx ); diff --git a/lib_dec/ivas_pca_dec_fx.c b/lib_dec/ivas_pca_dec_fx.c index e19b1bda9..ef53d89b3 100644 --- a/lib_dec/ivas_pca_dec_fx.c +++ b/lib_dec/ivas_pca_dec_fx.c @@ -246,10 +246,10 @@ void ivas_pca_dec_fx( } ELSE { - pca_dec_inv_transform_fx( hPCA, ql_fx, ql_fx, output_frame, n_channels, pcm_out_fx ); + pca_dec_inv_transform_fx( hPCA, ql_fx, qr_fx, output_frame, n_channels, pcm_out_fx ); } - pca_dec_update_dquat_fx( hPCA, ql_fx, ql_fx ); + pca_dec_update_dquat_fx( hPCA, ql_fx, qr_fx ); hPCA->prev_pca_bypass = add(hPCA->prev_pca_bypass, 1); move16(); @@ -276,7 +276,7 @@ void ivas_pca_dec_fx( IF( EQ_16(pca_bypass, PCA_MODE_INACTIVE )) { - pca_dec_reset_dquat_fx( ql_fx, ql_fx ); + pca_dec_reset_dquat_fx( ql_fx, qr_fx ); IF( GT_16(hPCA->prev_pca_bypass, 1 )) //&& (hPCA->pca_off_hangover == 0)) { @@ -285,10 +285,10 @@ void ivas_pca_dec_fx( } ELSE { - pca_dec_inv_transform_fx( hPCA, ql_fx, ql_fx, output_frame, n_channels, pcm_out_fx ); + pca_dec_inv_transform_fx( hPCA, ql_fx, qr_fx, output_frame, n_channels, pcm_out_fx ); } - pca_dec_update_dquat_fx( hPCA, ql_fx, ql_fx ); + pca_dec_update_dquat_fx( hPCA, ql_fx, qr_fx ); hPCA->prev_pca_bypass = add(hPCA->prev_pca_bypass , 1); hPCA->prev_pca_bypass = min( hPCA->prev_pca_bypass, 2 ); @@ -299,19 +299,19 @@ void ivas_pca_dec_fx( IF( !bfi ) { pca_dec_s3_fx( hPCA->index[0], ql_fx ); - pca_dec_s3_fx( hPCA->index[1], ql_fx ); + pca_dec_s3_fx( hPCA->index[1], qr_fx ); } ELSE { /* freeze */ // todo : check if update of prev_ql_fx is required Copy( hPCA->prev_ql_fx, ql_fx, IVAS_PCA_INTERP ); - Copy( hPCA->prev_qr_fx, ql_fx, IVAS_PCA_INTERP ); + Copy( hPCA->prev_qr_fx, qr_fx, IVAS_PCA_INTERP ); } - pca_dec_inv_transform_fx( hPCA, ql_fx, ql_fx, output_frame, n_channels, pcm_out_fx ); + pca_dec_inv_transform_fx( hPCA, ql_fx, qr_fx, output_frame, n_channels, pcm_out_fx ); /* update for next frame */ - pca_dec_update_dquat_fx( hPCA, ql_fx, ql_fx ); + pca_dec_update_dquat_fx( hPCA, ql_fx, qr_fx ); hPCA->prev_pca_bypass = 0; move16(); -- GitLab From d2b9cbd3e7ea6615c4a1783f093180f15d500ebb Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Tue, 30 Apr 2024 00:56:52 +0530 Subject: [PATCH 3/3] Floating point code restore --- lib_dec/core_switching_dec.c | 1443 +++++++++-------- lib_dec/ivas_mct_dec.c | 12 +- lib_dec/ivas_sba_dec.c | 119 +- lib_dec/ivas_spar_md_dec.c | 2768 ++++++++++++++++++++++++++++++++- lib_dec/ivas_stereo_dft_dec.c | 83 +- 5 files changed, 3562 insertions(+), 863 deletions(-) diff --git a/lib_dec/core_switching_dec.c b/lib_dec/core_switching_dec.c index c2a318b2e..e7238d971 100644 --- a/lib_dec/core_switching_dec.c +++ b/lib_dec/core_switching_dec.c @@ -175,6 +175,7 @@ ivas_error core_switching_pre_dec_ivas_fx( { st->last_core = HQ_CORE; move16(); + Copy32( st->hTcxDec->FBTCXdelayBuf_32, st->prev_synth_buffer32_fx, NS2SA( st->output_Fs, DELAY_BWE_TOTAL_NS - DELAY_CLDFB_NS ) ); //Copy_Scale_sig_32_16( st->hTcxDec->FBTCXdelayBuf_32, st->prev_synth_buffer_fx, NS2SA( st->output_Fs, DELAY_BWE_TOTAL_NS - DELAY_CLDFB_NS ), -11 ); //Q11 -> Q0 } @@ -700,496 +701,488 @@ ivas_error core_switching_pre_dec_ivas_fx( #endif // IVAS_FLOAT_FIXED #ifndef IVAS_FLOAT_FIXED ivas_error core_switching_pre_dec( - Decoder_State *st, /* i/o: decoder state structure */ - const int16_t output_frame, /* i : frame length */ - const int32_t last_core_brate_st0, /* i : channel 0 last core bitrate */ - const int16_t nchan_out, /* i : number of output channels */ - const int16_t last_element_mode, /* i : last_element_mode */ - const int32_t last_element_brate /* i : last element bitrate */ + Decoder_State *st, /* i/o: decoder state structure */ + const int16_t output_frame, /* i : frame length */ + const int32_t last_core_brate_st0, /* i : channel 0 last core bitrate */ + const int16_t nchan_out, /* i : number of output channels */ + const int16_t last_element_mode, /* i : last_element_mode */ + const int32_t last_element_brate /* i : last element bitrate */ ) { - int16_t i, oldLenClasBuff, newLenClasBuff; - ivas_error error; - float tmp; + int16_t i, oldLenClasBuff, newLenClasBuff; + ivas_error error; + float tmp; - error = IVAS_ERR_OK; + error = IVAS_ERR_OK; - /* Codec mode switching */ - if ( st->last_codec_mode == MODE2 || ( ( st->last_core == TCX_20_CORE || st->last_core == TCX_10_CORE ) && st->element_mode > EVS_MONO ) ) + /* Codec mode switching */ + if (st->last_codec_mode == MODE2 || ((st->last_core == TCX_20_CORE || st->last_core == TCX_10_CORE) && st->element_mode > EVS_MONO)) + { + mvr2r(st->mem_syn2, st->mem_syn1, M); + set_f(st->agc_mem2, 0, 2); + st->mem_deemph = st->syn_float[M]; + st->bpf_off = 1; + if (st->hBPF != NULL) { - mvr2r( st->mem_syn2, st->mem_syn1, M ); - set_f( st->agc_mem2, 0, 2 ); - st->mem_deemph = st->syn_float[M]; - st->bpf_off = 1; - if ( st->hBPF != NULL ) - { - set_f( st->hBPF->pst_old_syn, 0, NBPSF_PIT_MAX ); - st->hBPF->pst_mem_deemp_err = 0; - } - st->psf_lp_noise = st->lp_noise_float; + set_f(st->hBPF->pst_old_syn, 0, NBPSF_PIT_MAX); + st->hBPF->pst_mem_deemp_err = 0; + } + st->psf_lp_noise = st->lp_noise_float; - /* reset old HB synthesis buffer */ - if ( st->last_L_frame == L_FRAME ) - { - st->old_bwe_delay = NS2SA( st->output_Fs, MAX_DELAY_TBE_NS - DELAY_SWB_TBE_12k8_NS ); - } - else - { - st->old_bwe_delay = NS2SA( st->output_Fs, MAX_DELAY_TBE_NS - DELAY_SWB_TBE_16k_NS ); - } - set_f( st->hb_prev_synth_buffer, 0, NS2SA( 48000, DELAY_BWE_TOTAL_NS ) ); + /* reset old HB synthesis buffer */ + if (st->last_L_frame == L_FRAME) + { + st->old_bwe_delay = NS2SA(st->output_Fs, MAX_DELAY_TBE_NS - DELAY_SWB_TBE_12k8_NS); + } + else + { + st->old_bwe_delay = NS2SA(st->output_Fs, MAX_DELAY_TBE_NS - DELAY_SWB_TBE_16k_NS); + } + set_f(st->hb_prev_synth_buffer, 0, NS2SA(48000, DELAY_BWE_TOTAL_NS)); - if ( st->hBWE_TD != NULL && st->last_core != ACELP_CORE ) - { - /* reset BWE memories */ - set_f( st->hBWE_TD->old_bwe_exc, 0, PIT16k_MAX * 2 ); - st->hBWE_TD->bwe_non_lin_prev_scale = 0.0f; - } + if (st->hBWE_TD != NULL && st->last_core != ACELP_CORE) + { + /* reset BWE memories */ + set_f(st->hBWE_TD->old_bwe_exc, 0, PIT16k_MAX * 2); + st->hBWE_TD->bwe_non_lin_prev_scale = 0.0f; + } - /* reset upd_cnt */ - st->upd_cnt = MAX_UPD_CNT; + /* reset upd_cnt */ + st->upd_cnt = MAX_UPD_CNT; - st->igf = 0; + st->igf = 0; - if ( st->output_Fs >= 16000 && st->hBWE_zero != NULL ) - { - hf_synth_reset( st->hBWE_zero ); - } - - if ( st->hBWE_FD != NULL ) - { - set_f( st->hBWE_FD->old_syn_12k8_16k, 0, NS2SA( 16000, DELAY_FD_BWE_ENC_NS ) ); - } - - if ( st->hHQ_core != NULL ) - { - set_f( st->hHQ_core->prev_env, 0, SFM_N_WB ); - set_f( st->hHQ_core->prev_normq, 0, SFM_N_WB ); + if (st->output_Fs >= 16000 && st->hBWE_zero != NULL) + { + hf_synth_reset(st->hBWE_zero); + } - set_f( st->hHQ_core->last_ni_gain, 0, BANDS_MAX ); - set_f( st->hHQ_core->last_env, 0, BANDS_MAX ); - st->hHQ_core->last_max_pos_pulse = 0; + if (st->hBWE_FD != NULL) + { + set_f(st->hBWE_FD->old_syn_12k8_16k, 0, NS2SA(16000, DELAY_FD_BWE_ENC_NS)); + } - if ( st->output_Fs > 16000 ) - { - set_f( st->hHQ_core->prev_coeff_out, 0, L_HQ_WB_BWE ); - } + if (st->hHQ_core != NULL) + { + set_f(st->hHQ_core->prev_env, 0, SFM_N_WB); + set_f(st->hHQ_core->prev_normq, 0, SFM_N_WB); - /* pre-echo */ - st->hHQ_core->pastpre = 0; - } + set_f(st->hHQ_core->last_ni_gain, 0, BANDS_MAX); + set_f(st->hHQ_core->last_env, 0, BANDS_MAX); + st->hHQ_core->last_max_pos_pulse = 0; - /* reset the GSC pre echo energy threshold in case of switching */ - if ( st->hGSCDec != NULL ) - { - st->hGSCDec->Last_frame_ener = (float) MAX_32; - } + if (st->output_Fs > 16000) + { + set_f(st->hHQ_core->prev_coeff_out, 0, L_HQ_WB_BWE); + } - if ( st->last_core == TCX_20_CORE || st->last_core == TCX_10_CORE ) - { - if ( st->element_mode == EVS_MONO ) - { - st->last_core = HQ_CORE; - mvr2r( st->hTcxDec->FBTCXdelayBuf_float, st->prev_synth_buffer, NS2SA( st->output_Fs, DELAY_BWE_TOTAL_NS - DELAY_CLDFB_NS ) ); - } + /* pre-echo */ + st->hHQ_core->pastpre = 0; + } - if ( st->hHQ_core != NULL ) - { - set_f( st->hHQ_core->last_ni_gain, 0, BANDS_MAX ); - set_f( st->hHQ_core->last_env, 0, BANDS_MAX ); - st->hHQ_core->last_max_pos_pulse = 0; + /* reset the GSC pre echo energy threshold in case of switching */ + if (st->hGSCDec != NULL) + { + st->hGSCDec->Last_frame_ener = (float)MAX_32; + } - set_s( st->hHQ_core->prev_SWB_peak_pos, 0, SPT_SHORTEN_SBNUM ); - st->hHQ_core->prev_frm_hfe2 = 0; - st->hHQ_core->prev_stab_hfe2 = 0; - } - } + if (st->last_core == TCX_20_CORE || st->last_core == TCX_10_CORE) + { + if (st->element_mode == EVS_MONO) + { + st->last_core = HQ_CORE; + mvr2r(st->hTcxDec->FBTCXdelayBuf_float, st->prev_synth_buffer, NS2SA(st->output_Fs, DELAY_BWE_TOTAL_NS - DELAY_CLDFB_NS)); + } - if ( st->prev_bfi != 0 ) - { - int16_t delay_comp; + if (st->hHQ_core != NULL) + { + set_f(st->hHQ_core->last_ni_gain, 0, BANDS_MAX); + set_f(st->hHQ_core->last_env, 0, BANDS_MAX); + st->hHQ_core->last_max_pos_pulse = 0; - /*switch off Hq Voicing as it was not updated in MODE2*/ - if ( st->hHQ_core != NULL ) - { - st->hHQ_core->oldHqVoicing = 0; - st->hHQ_core->HqVoicing = 0; - } + set_s(st->hHQ_core->prev_SWB_peak_pos, 0, SPT_SHORTEN_SBNUM); + st->hHQ_core->prev_frm_hfe2 = 0; + st->hHQ_core->prev_stab_hfe2 = 0; + } + } - delay_comp = NS2SA( st->output_Fs, DELAY_CLDFB_NS ); + if (st->prev_bfi != 0) + { + int16_t delay_comp; - if ( !st->last_con_tcx && st->last_core_bfi == ACELP_CORE && st->core == HQ_CORE ) - { - float *realBuffer[CLDFB_NO_COL_MAX_SWITCH], *imagBuffer[CLDFB_NO_COL_MAX_SWITCH]; - float realBufferTmp[CLDFB_NO_COL_MAX_SWITCH][CLDFB_NO_CHANNELS_MAX], imagBufferTmp[CLDFB_NO_COL_MAX_SWITCH][CLDFB_NO_CHANNELS_MAX]; + /*switch off Hq Voicing as it was not updated in MODE2*/ + if (st->hHQ_core != NULL) + { + st->hHQ_core->oldHqVoicing = 0; + st->hHQ_core->HqVoicing = 0; + } - for ( i = 0; i < CLDFB_NO_COL_MAX_SWITCH; i++ ) - { - set_f( realBufferTmp[i], 0, CLDFB_NO_CHANNELS_MAX ); - set_f( imagBufferTmp[i], 0, CLDFB_NO_CHANNELS_MAX ); - realBuffer[i] = realBufferTmp[i]; - imagBuffer[i] = imagBufferTmp[i]; - } + delay_comp = NS2SA(st->output_Fs, DELAY_CLDFB_NS); - /* CLDFB analysis of the synthesis at internal sampling rate */ - if ( ( error = cldfb_save_memory_ivas( st->cldfbAna ) ) != IVAS_ERR_OK ) - { - return error; - } + if (!st->last_con_tcx && st->last_core_bfi == ACELP_CORE && st->core == HQ_CORE) + { + float *realBuffer[CLDFB_NO_COL_MAX_SWITCH], *imagBuffer[CLDFB_NO_COL_MAX_SWITCH]; + float realBufferTmp[CLDFB_NO_COL_MAX_SWITCH][CLDFB_NO_CHANNELS_MAX], imagBufferTmp[CLDFB_NO_COL_MAX_SWITCH][CLDFB_NO_CHANNELS_MAX]; - cldfbAnalysis_ivas( st->hTcxDec->syn_Overl_float, realBuffer, imagBuffer, delay_comp, st->cldfbAna ); - cldfb_restore_memory_ivas( st->cldfbAna ); + for (i = 0; i < CLDFB_NO_COL_MAX_SWITCH; i++) + { + set_f(realBufferTmp[i], 0, CLDFB_NO_CHANNELS_MAX); + set_f(imagBufferTmp[i], 0, CLDFB_NO_CHANNELS_MAX); + realBuffer[i] = realBufferTmp[i]; + imagBuffer[i] = imagBufferTmp[i]; + } - /* CLDFB synthesis of the combined signal */ - if ( ( error = cldfb_save_memory_ivas( st->cldfbSyn ) ) != IVAS_ERR_OK ) - { - return error; - } + /* CLDFB analysis of the synthesis at internal sampling rate */ + if ((error = cldfb_save_memory_ivas(st->cldfbAna)) != IVAS_ERR_OK) + { + return error; + } - cldfbSynthesis_ivas( realBuffer, imagBuffer, st->hHQ_core->fer_samples, delay_comp, st->cldfbSyn ); - cldfb_restore_memory_ivas( st->cldfbSyn ); - } + cldfbAnalysis_ivas(st->hTcxDec->syn_Overl_float, realBuffer, imagBuffer, delay_comp, st->cldfbAna); + cldfb_restore_memory_ivas(st->cldfbAna); - if ( !st->last_con_tcx && st->last_core_bfi == ACELP_CORE && st->core == HQ_CORE ) - { - lerp_flt( st->hTcxDec->syn_Overl_float, st->hHQ_core->fer_samples + delay_comp, output_frame / 2, st->last_L_frame / 2 ); - /*Set to zero the remaining part*/ - set_f( st->hHQ_core->fer_samples + delay_comp + output_frame / 2, 0, ( output_frame / 2 ) - delay_comp ); - } + /* CLDFB synthesis of the combined signal */ + if ((error = cldfb_save_memory_ivas(st->cldfbSyn)) != IVAS_ERR_OK) + { + return error; } - st->use_acelp_preq = 0; - st->reset_mem_AR = 0; + cldfbSynthesis_ivas(realBuffer, imagBuffer, st->hHQ_core->fer_samples, delay_comp, st->cldfbSyn); + cldfb_restore_memory_ivas(st->cldfbSyn); + } + + if (!st->last_con_tcx && st->last_core_bfi == ACELP_CORE && st->core == HQ_CORE) + { + lerp_flt(st->hTcxDec->syn_Overl_float, st->hHQ_core->fer_samples + delay_comp, output_frame / 2, st->last_L_frame / 2); + /*Set to zero the remaining part*/ + set_f(st->hHQ_core->fer_samples + delay_comp + output_frame / 2, 0, (output_frame / 2) - delay_comp); + } } - /*FEC*/ - if ( st->L_frame <= L_FRAME16k ) + st->use_acelp_preq = 0; + st->reset_mem_AR = 0; + } + + /*FEC*/ + if (st->L_frame <= L_FRAME16k) + { + if (st->last_L_frame <= L_FRAME16k && st->core != HQ_CORE) { - if ( st->last_L_frame <= L_FRAME16k && st->core != HQ_CORE ) + if (st->L_frame != st->last_L_frame) + { + if (st->L_frame > st->last_L_frame) { - if ( st->L_frame != st->last_L_frame ) - { - if ( st->L_frame > st->last_L_frame ) - { - oldLenClasBuff = L_SYN_MEM_CLAS_ESTIM * st->last_L_frame / st->L_frame; - newLenClasBuff = L_SYN_MEM_CLAS_ESTIM; - } - else - { - oldLenClasBuff = L_SYN_MEM_CLAS_ESTIM; - newLenClasBuff = L_SYN_MEM_CLAS_ESTIM * st->L_frame / st->last_L_frame; - } - lerp_flt( &st->mem_syn_clas_estim[L_SYN_MEM_CLAS_ESTIM - oldLenClasBuff], &st->mem_syn_clas_estim[L_SYN_MEM_CLAS_ESTIM - newLenClasBuff], newLenClasBuff, oldLenClasBuff ); - } + oldLenClasBuff = L_SYN_MEM_CLAS_ESTIM * st->last_L_frame / st->L_frame; + newLenClasBuff = L_SYN_MEM_CLAS_ESTIM; } else { - set_zero( st->mem_syn_clas_estim, L_SYN_MEM_CLAS_ESTIM ); + oldLenClasBuff = L_SYN_MEM_CLAS_ESTIM; + newLenClasBuff = L_SYN_MEM_CLAS_ESTIM * st->L_frame / st->last_L_frame; } + lerp_flt(&st->mem_syn_clas_estim[L_SYN_MEM_CLAS_ESTIM - oldLenClasBuff], &st->mem_syn_clas_estim[L_SYN_MEM_CLAS_ESTIM - newLenClasBuff], newLenClasBuff, oldLenClasBuff); + } } - - /* Here we only handle cases where last_ppp and last_nelp not updated when coming from CodecB or other cores - within ACELP_CORE if switching from another bitarate to vbr, last_ppp and last_nelp is always updated in the previous frame */ - if ( st->core == ACELP_CORE && ( st->last_core != ACELP_CORE || st->last_codec_mode == MODE2 ) ) + else { - st->last_ppp_mode_dec = 0; - st->last_nelp_mode_dec = 0; + set_zero(st->mem_syn_clas_estim, L_SYN_MEM_CLAS_ESTIM); } + } - /* Handle state reset of stat_noise_uv_mod memory */ - if ( st->core == ACELP_CORE && ( st->last_core != ACELP_CORE || st->last_codec_mode == MODE2 || st->last_total_brate <= PPP_NELP_2k80 ) ) + /* Here we only handle cases where last_ppp and last_nelp not updated when coming from CodecB or other cores + within ACELP_CORE if switching from another bitarate to vbr, last_ppp and last_nelp is always updated in the previous frame */ + if (st->core == ACELP_CORE && (st->last_core != ACELP_CORE || st->last_codec_mode == MODE2)) + { + st->last_ppp_mode_dec = 0; + st->last_nelp_mode_dec = 0; + } + + /* Handle state reset of stat_noise_uv_mod memory */ + if (st->core == ACELP_CORE && (st->last_core != ACELP_CORE || st->last_codec_mode == MODE2 || st->last_total_brate <= PPP_NELP_2k80)) + { + st->act_count = 3; + st->uv_count = 0; + } + + if (((st->core == ACELP_CORE || st->core == AMR_WB_CORE) && st->last_core == HQ_CORE) || ((st->element_mode == IVAS_CPE_DFT || st->element_mode == IVAS_CPE_TD || (st->element_mode == IVAS_CPE_MDCT && last_element_mode == IVAS_CPE_DFT)) && nchan_out == 2 && + st->core_brate != SID_2k40 && st->core_brate != FRAME_NO_DATA && (last_core_brate_st0 == FRAME_NO_DATA || last_core_brate_st0 == SID_2k40))) + { + if (st->element_mode == IVAS_CPE_DFT || st->element_mode == IVAS_CPE_TD) { - st->act_count = 3; - st->uv_count = 0; + st->hPFstat->reset = 1; } - if ( ( ( st->core == ACELP_CORE || st->core == AMR_WB_CORE ) && st->last_core == HQ_CORE ) || ( ( st->element_mode == IVAS_CPE_DFT || st->element_mode == IVAS_CPE_TD || ( st->element_mode == IVAS_CPE_MDCT && last_element_mode == IVAS_CPE_DFT ) ) && nchan_out == 2 && - st->core_brate != SID_2k40 && st->core_brate != FRAME_NO_DATA && ( last_core_brate_st0 == FRAME_NO_DATA || last_core_brate_st0 == SID_2k40 ) ) ) + if (st->L_frame == L_FRAME16k) { - if ( st->element_mode == IVAS_CPE_DFT || st->element_mode == IVAS_CPE_TD ) - { - st->hPFstat->reset = 1; - } - - if ( st->L_frame == L_FRAME16k ) - { - mvr2r( TRWB2_Ave, st->lsf_old, M ); /* init of LSP */ - mvr2r( TRWB2_Ave, st->lsfoldbfi1, M ); - mvr2r( TRWB2_Ave, st->lsfoldbfi0, M ); - mvr2r( TRWB2_Ave, st->lsf_adaptive_mean, M ); - lsf2lsp( st->lsf_old, st->lsp_old, M, INT_FS_16k ); - } - else - { - mvr2r( TRWB_Ave, st->lsf_old, M ); /* init of LSP */ - mvr2r( TRWB_Ave, st->lsfoldbfi1, M ); - mvr2r( TRWB_Ave, st->lsfoldbfi0, M ); - mvr2r( TRWB_Ave, st->lsf_adaptive_mean, M ); - lsf2lsp( st->lsf_old, st->lsp_old, M, INT_FS_12k8 ); - } - - if ( ( st->element_mode == IVAS_CPE_DFT || st->element_mode == IVAS_CPE_TD ) && nchan_out == 2 && st->core_brate > SID_2k40 && ( last_core_brate_st0 == FRAME_NO_DATA || last_core_brate_st0 == SID_2k40 ) && st->hTcxDec != NULL ) - { - /* Last frame was Stereo CNG and the synthesis memory is outdated -- reset */ - set_f( st->hTcxDec->old_syn_Overl_float, 0.0f, L_FRAME32k / 2 ); - set_f( st->hFdCngDec->hFdCngCom->olapBufferAna_flt, 0.0f, FFTLEN ); -#ifdef IVAS_FLOAT_FIXED - set16_fx( st->hFdCngDec->hFdCngCom->olapBufferAna_fx, 0, FFTLEN ); -#endif // IVAS_FLOAT_FIXED - } + mvr2r(TRWB2_Ave, st->lsf_old, M); /* init of LSP */ + mvr2r(TRWB2_Ave, st->lsfoldbfi1, M); + mvr2r(TRWB2_Ave, st->lsfoldbfi0, M); + mvr2r(TRWB2_Ave, st->lsf_adaptive_mean, M); + lsf2lsp(st->lsf_old, st->lsp_old, M, INT_FS_16k); + } + else + { + mvr2r(TRWB_Ave, st->lsf_old, M); /* init of LSP */ + mvr2r(TRWB_Ave, st->lsfoldbfi1, M); + mvr2r(TRWB_Ave, st->lsfoldbfi0, M); + mvr2r(TRWB_Ave, st->lsf_adaptive_mean, M); + lsf2lsp(st->lsf_old, st->lsp_old, M, INT_FS_12k8); + } - set_f( st->agc_mem2, 0, 2 ); - st->mem_deemph = 0; - if ( !st->last_con_tcx ) - { - set_f( st->mem_syn2, 0.0f, M ); - } - set_f( st->mem_syn1, 0.0f, M ); - if ( st->hBWE_TD != NULL ) - { - st->hBWE_TD->bwe_non_lin_prev_scale = 0.0f; - } + if ((st->element_mode == IVAS_CPE_DFT || st->element_mode == IVAS_CPE_TD) && nchan_out == 2 && st->core_brate > SID_2k40 && (last_core_brate_st0 == FRAME_NO_DATA || last_core_brate_st0 == SID_2k40) && st->hTcxDec != NULL) + { + /* Last frame was Stereo CNG and the synthesis memory is outdated -- reset */ + set_f(st->hTcxDec->old_syn_Overl_float, 0.0f, L_FRAME32k / 2); + set_f(st->hFdCngDec->hFdCngCom->olapBufferAna_flt, 0.0f, FFTLEN); + } - /* Reset ACELP parameters */ - set_zero( st->mem_MA, M ); - if ( st->sr_core == INT_FS_16k ) - { - mvr2r( GEWB2_Ave, st->mem_AR, M ); - } - else - { - mvr2r( GEWB_Ave, st->mem_AR, M ); - } - st->tilt_code = 0.0f; - st->gc_threshold = 0.0f; - set_f( st->dispMem, 0, 8 ); + set_f(st->agc_mem2, 0, 2); + st->mem_deemph = 0; + if (!st->last_con_tcx) + { + set_f(st->mem_syn2, 0.0f, M); + } + set_f(st->mem_syn1, 0.0f, M); + if (st->hBWE_TD != NULL) + { + st->hBWE_TD->bwe_non_lin_prev_scale = 0.0f; + } - st->last_coder_type = GENERIC; + /* Reset ACELP parameters */ + set_zero(st->mem_MA, M); + if (st->sr_core == INT_FS_16k) + { + mvr2r(GEWB2_Ave, st->mem_AR, M); + } + else + { + mvr2r(GEWB_Ave, st->mem_AR, M); + } + st->tilt_code = 0.0f; + st->gc_threshold = 0.0f; + set_f(st->dispMem, 0, 8); - fer_energy( output_frame, UNVOICED_CLAS, st->previoussynth, -1, &st->enr_old, 1 ); - st->lp_gainp = 0.0f; - st->lp_gainc = (float) sqrt( st->lp_ener ); + st->last_coder_type = GENERIC; - st->last_voice_factor = 0; - st->Last_GSC_noisy_speech_flag = 0; + fer_energy(output_frame, UNVOICED_CLAS, st->previoussynth, -1, &st->enr_old, 1); + st->lp_gainp = 0.0f; + st->lp_gainc = (float)sqrt(st->lp_ener); - /* reset CLDFB memories */ - cldfb_reset_memory_ivas( st->cldfbAna ); - cldfb_reset_memory_ivas( st->cldfbBPF ); - cldfb_reset_memory_ivas( st->cldfbSyn ); + st->last_voice_factor = 0; + st->Last_GSC_noisy_speech_flag = 0; - /* reset TBE memories */ - if ( !st->last_con_tcx && !( ( st->last_core == HQ_CORE ) && st->element_mode > EVS_MONO ) ) - { - set_f( st->old_exc, 0, L_EXC_MEM_DEC ); - } - else if ( st->L_frame < L_FRAME16k ) - { - /* resample from 16kHz to 12.8kHZ */ - synth_mem_updt2_flt( st->L_frame, L_FRAME16k, st->old_exc, st->mem_syn_r_float, st->mem_syn2, NULL, DEC ); - } + /* reset CLDFB memories */ + cldfb_reset_memory_ivas(st->cldfbAna); + cldfb_reset_memory_ivas(st->cldfbBPF); + cldfb_reset_memory_ivas(st->cldfbSyn); - if ( st->hBWE_TD != NULL ) - { - set_f( st->hBWE_TD->old_bwe_exc, 0, PIT16k_MAX * 2 ); - } + /* reset TBE memories */ + if (!st->last_con_tcx && !((st->last_core == HQ_CORE) && st->element_mode > EVS_MONO)) + { + set_f(st->old_exc, 0, L_EXC_MEM_DEC); + } + else if (st->L_frame < L_FRAME16k) + { + /* resample from 16kHz to 12.8kHZ */ + synth_mem_updt2_flt(st->L_frame, L_FRAME16k, st->old_exc, st->mem_syn_r_float, st->mem_syn2, NULL, DEC); + } - if ( st->output_Fs >= 16000 && st->hBWE_zero != NULL ) - { - hf_synth_reset( st->hBWE_zero ); - } + if (st->hBWE_TD != NULL) + { + set_f(st->hBWE_TD->old_bwe_exc, 0, PIT16k_MAX * 2); + } - if ( st->hBWE_FD != NULL ) - { - set_f( st->hBWE_FD->old_syn_12k8_16k, 0, NS2SA( 16000, DELAY_FD_BWE_ENC_NS ) ); - } + if (st->output_Fs >= 16000 && st->hBWE_zero != NULL) + { + hf_synth_reset(st->hBWE_zero); } - if ( ( st->core == ACELP_CORE || st->core == AMR_WB_CORE ) && ( st->last_core == TCX_20_CORE || st->last_core == TCX_10_CORE ) ) + if (st->hBWE_FD != NULL) { - if ( st->hBWE_TD != NULL ) - { - st->hBWE_TD->bwe_non_lin_prev_scale = 0.0f; - set_f( st->hBWE_TD->old_bwe_exc, 0, PIT16k_MAX * 2 ); - } + set_f(st->hBWE_FD->old_syn_12k8_16k, 0, NS2SA(16000, DELAY_FD_BWE_ENC_NS)); + } + } - st->tilt_code = 0.0f; - st->gc_threshold = 0.0f; - set_f( st->dispMem, 0, 8 ); + if ((st->core == ACELP_CORE || st->core == AMR_WB_CORE) && (st->last_core == TCX_20_CORE || st->last_core == TCX_10_CORE)) + { + if (st->hBWE_TD != NULL) + { + st->hBWE_TD->bwe_non_lin_prev_scale = 0.0f; + set_f(st->hBWE_TD->old_bwe_exc, 0, PIT16k_MAX * 2); + } - st->last_coder_type = GENERIC; + st->tilt_code = 0.0f; + st->gc_threshold = 0.0f; + set_f(st->dispMem, 0, 8); - fer_energy( output_frame, UNVOICED_CLAS, st->previoussynth, -1, &st->enr_old, 1 ); - st->lp_gainp = 0.0f; - st->lp_gainc = (float) sqrt( st->lp_ener ); + st->last_coder_type = GENERIC; - st->last_voice_factor = 0; - st->Last_GSC_noisy_speech_flag = 0; + fer_energy(output_frame, UNVOICED_CLAS, st->previoussynth, -1, &st->enr_old, 1); + st->lp_gainp = 0.0f; + st->lp_gainc = (float)sqrt(st->lp_ener); - if ( st->output_Fs >= 16000 && st->hBWE_zero != NULL ) - { - hf_synth_reset( st->hBWE_zero ); - } + st->last_voice_factor = 0; + st->Last_GSC_noisy_speech_flag = 0; - if ( st->hBWE_FD != NULL ) - { - set_f( st->hBWE_FD->old_syn_12k8_16k, 0, NS2SA( 16000, DELAY_FD_BWE_ENC_NS ) ); - } + if (st->output_Fs >= 16000 && st->hBWE_zero != NULL) + { + hf_synth_reset(st->hBWE_zero); + } - if ( nchan_out == 1 && st->element_mode == IVAS_CPE_DFT && st->element_brate <= IVAS_24k4 && last_element_brate > IVAS_24k4 ) - { - /* update cldbf state with previous frame TCX synthesis when going from a bitrate with residual coding to a bitrate without it */ - int16_t offset; - offset = st->cldfbAna->p_filter_length - st->cldfbAna->no_channels; - mvr2r( st->hTcxDec->old_synthFB + st->hTcxDec->old_synth_lenFB - offset, st->cldfbAna->cldfb_state, offset ); - } + if (st->hBWE_FD != NULL) + { + set_f(st->hBWE_FD->old_syn_12k8_16k, 0, NS2SA(16000, DELAY_FD_BWE_ENC_NS)); } - if ( st->core == HQ_CORE && ( st->last_core == ACELP_CORE || st->last_core == AMR_WB_CORE || ( ( st->element_mode != EVS_MONO ) && ( st->last_core != HQ_CORE ) ) ) ) + if (nchan_out == 1 && st->element_mode == IVAS_CPE_DFT && st->element_brate <= IVAS_24k4 && last_element_brate > IVAS_24k4) { - set_f( st->hHQ_core->prev_env, 0, SFM_N_WB ); - set_f( st->hHQ_core->prev_normq, 0, SFM_N_WB ); + /* update cldbf state with previous frame TCX synthesis when going from a bitrate with residual coding to a bitrate without it */ + int16_t offset; + offset = st->cldfbAna->p_filter_length - st->cldfbAna->no_channels; + mvr2r(st->hTcxDec->old_synthFB + st->hTcxDec->old_synth_lenFB - offset, st->cldfbAna->cldfb_state, offset); + } + } - set_f( st->hHQ_core->last_ni_gain, 0, BANDS_MAX ); - set_f( st->hHQ_core->last_env, 0, BANDS_MAX ); - st->hHQ_core->last_max_pos_pulse = 0; + if (st->core == HQ_CORE && (st->last_core == ACELP_CORE || st->last_core == AMR_WB_CORE || ((st->element_mode != EVS_MONO) && (st->last_core != HQ_CORE)))) + { + set_f(st->hHQ_core->prev_env, 0, SFM_N_WB); + set_f(st->hHQ_core->prev_normq, 0, SFM_N_WB); - set_s( st->hHQ_core->prev_SWB_peak_pos, 0, SPT_SHORTEN_SBNUM ); - st->hHQ_core->prev_frm_hfe2 = 0; - st->hHQ_core->prev_stab_hfe2 = 0; - if ( st->output_Fs > 16000 ) - { - set_f( st->hHQ_core->prev_coeff_out, 0, L_HQ_WB_BWE ); - } + set_f(st->hHQ_core->last_ni_gain, 0, BANDS_MAX); + set_f(st->hHQ_core->last_env, 0, BANDS_MAX); + st->hHQ_core->last_max_pos_pulse = 0; - if ( st->element_mode != EVS_MONO ) - { - /* Estimate mem_env_delta to reinit env_stab */ - tmp = max( 0, ENV_STAB_EST1 + ( ENV_STAB_EST2 * st->stab_fac_smooth_lt ) + ( ENV_STAB_EST3 * st->log_energy_diff_lt ) ); - st->hHQ_core->mem_env_delta = (int16_t) min( MAX16B, (int32_t) ( tmp * ( 1 << 12 ) ) ); /* Convert to Q12 and handle saturation */ + set_s(st->hHQ_core->prev_SWB_peak_pos, 0, SPT_SHORTEN_SBNUM); + st->hHQ_core->prev_frm_hfe2 = 0; + st->hHQ_core->prev_stab_hfe2 = 0; + if (st->output_Fs > 16000) + { + set_f(st->hHQ_core->prev_coeff_out, 0, L_HQ_WB_BWE); + } - if ( st->last_core != TCX_20_CORE && st->last_core != TCX_10_CORE ) - { - set_f( st->hHQ_core->old_out, 0, output_frame ); - set_f( st->hHQ_core->old_outLB, 0, L_FRAME16k ); - } + if (st->element_mode != EVS_MONO) + { + /* Estimate mem_env_delta to reinit env_stab */ + tmp = max(0, ENV_STAB_EST1 + (ENV_STAB_EST2 * st->stab_fac_smooth_lt) + (ENV_STAB_EST3 * st->log_energy_diff_lt)); + st->hHQ_core->mem_env_delta = (int16_t)min(MAX16B, (int32_t)(tmp * (1 << 12))); /* Convert to Q12 and handle saturation */ - st->hHQ_core->no_att_hangover = 0; - st->hHQ_core->energy_lt = 300.0f; + if (st->last_core != TCX_20_CORE && st->last_core != TCX_10_CORE) + { + set_f(st->hHQ_core->old_out, 0, output_frame); + set_f(st->hHQ_core->old_outLB, 0, L_FRAME16k); + } - set_s( st->hHQ_core->old_is_transient, 0, 3 ); - set_f( st->hHQ_core->prev_noise_level, 0.0f, 2 ); - st->hHQ_core->prev_R = 0; - set_s( st->hHQ_core->mem_norm + 1, 39, SFM_N_ENV_STAB - 1 ); - st->hHQ_core->prev_hqswb_clas = HQ_NORMAL; - st->hHQ_core->prev_ni_ratio = 0.5f; - set_f( st->hHQ_core->prev_En_sb, 0.0f, NB_SWB_SUBBANDS ); - } - else - { - set_f( st->hHQ_core->old_out, 0, output_frame ); - set_f( st->hHQ_core->old_outLB, 0, L_FRAME16k ); - } - } + st->hHQ_core->no_att_hangover = 0; + st->hHQ_core->energy_lt = 300.0f; - /* handle switching cases where preecho_sb was not called in the last frame (memory not up to date) */ - if ( st->hHQ_core != NULL ) + set_s(st->hHQ_core->old_is_transient, 0, 3); + set_f(st->hHQ_core->prev_noise_level, 0.0f, 2); + st->hHQ_core->prev_R = 0; + set_s(st->hHQ_core->mem_norm + 1, 39, SFM_N_ENV_STAB - 1); + st->hHQ_core->prev_hqswb_clas = HQ_NORMAL; + st->hHQ_core->prev_ni_ratio = 0.5f; + set_f(st->hHQ_core->prev_En_sb, 0.0f, NB_SWB_SUBBANDS); + } + else { - st->hHQ_core->pastpre--; - if ( st->hHQ_core->pastpre <= 0 ) - { - reset_preecho_dec( st->hHQ_core ); - } + set_f(st->hHQ_core->old_out, 0, output_frame); + set_f(st->hHQ_core->old_outLB, 0, L_FRAME16k); } + } - if ( st->core_brate == FRAME_NO_DATA ) + /* handle switching cases where preecho_sb was not called in the last frame (memory not up to date) */ + if (st->hHQ_core != NULL) + { + st->hHQ_core->pastpre--; + if (st->hHQ_core->pastpre <= 0) { - st->VAD = 0; - st->m_frame_type = ZERO_FRAME; + reset_preecho_dec(st->hHQ_core); } - else if ( st->core_brate == SID_2k40 || st->core_brate == SID_1k75 ) + } + + if (st->core_brate == FRAME_NO_DATA) + { + st->VAD = 0; + st->m_frame_type = ZERO_FRAME; + } + else if (st->core_brate == SID_2k40 || st->core_brate == SID_1k75) + { + st->VAD = 0; + st->m_frame_type = SID_FRAME; + } + else + { + st->VAD = 1; + st->m_frame_type = ACTIVE_FRAME; + } + + /*switch on CNA on active frames*/ + if (st->element_mode == EVS_MONO) /* for IVAS modes, st->flag_cna is set earlier */ + { + if (st->VAD && ((st->core != AMR_WB_CORE && st->total_brate <= CNA_MAX_BRATE) || (st->core == AMR_WB_CORE && st->total_brate <= ACELP_8k85))) { - st->VAD = 0; - st->m_frame_type = SID_FRAME; + st->flag_cna = 1; } - else + else if (st->VAD || ((st->cng_type == FD_CNG) && (st->L_frame == L_FRAME16k))) { - st->VAD = 1; - st->m_frame_type = ACTIVE_FRAME; + st->flag_cna = 0; } + } - /*switch on CNA on active frames*/ - if ( st->element_mode == EVS_MONO ) /* for IVAS modes, st->flag_cna is set earlier */ - { - if ( st->VAD && ( ( st->core != AMR_WB_CORE && st->total_brate <= CNA_MAX_BRATE ) || ( st->core == AMR_WB_CORE && st->total_brate <= ACELP_8k85 ) ) ) - { - st->flag_cna = 1; - } - else if ( st->VAD || ( ( st->cng_type == FD_CNG ) && ( st->L_frame == L_FRAME16k ) ) ) - { - st->flag_cna = 0; - } - } + if (st->core == AMR_WB_CORE) + { + st->cng_type = LP_CNG; + } - if ( st->core == AMR_WB_CORE ) + /* Reconfigure CNG */ + if (st->hFdCngDec && ((st->last_L_frame != st->L_frame) || (st->hFdCngDec->hFdCngCom->frameSize != st->L_frame) || st->ini_frame == 0 || st->bwidth != st->last_bwidth)) + { + /* || st->last_core == AMR_WB_CORE || st->last_codec_mode == MODE2)){*/ + if (st->core != AMR_WB_CORE) { - st->cng_type = LP_CNG; + configureFdCngDec(st->hFdCngDec, st->bwidth, st->rf_flag == 1 && st->total_brate == ACELP_13k20 ? ACELP_9k60 : st->total_brate, st->L_frame, st->last_L_frame, st->element_mode); } + else + { + configureFdCngDec(st->hFdCngDec, WB, ACELP_8k00, st->L_frame, st->last_L_frame, st->element_mode); - /* Reconfigure CNG */ - if ( st->hFdCngDec && ( ( st->last_L_frame != st->L_frame ) || ( st->hFdCngDec->hFdCngCom->frameSize != st->L_frame ) || st->ini_frame == 0 || st->bwidth != st->last_bwidth ) ) + if (st->VAD) + { + st->hFdCngDec->hFdCngCom->CngBitrate = st->total_brate; + } + } + if (st->last_L_frame != st->L_frame && st->L_frame <= L_FRAME16k && st->last_L_frame <= L_FRAME16k) { - /* || st->last_core == AMR_WB_CORE || st->last_codec_mode == MODE2)){*/ - if ( st->core != AMR_WB_CORE ) + if (st->element_mode == IVAS_CPE_DFT || st->element_mode == IVAS_CPE_TD) + { + lerp_flt(st->hFdCngDec->hFdCngCom->olapBufferAna_flt + st->last_L_frame, st->hFdCngDec->hFdCngCom->olapBufferAna_flt + st->L_frame, st->L_frame, st->last_L_frame); + } + + lerp_flt(st->hFdCngDec->hFdCngCom->olapBufferSynth2_flt, st->hFdCngDec->hFdCngCom->olapBufferSynth2_flt, st->L_frame * 2, st->last_L_frame * 2); + + if (st->total_brate <= SID_2k40 && st->last_total_brate <= SID_2k40) + { + lerp_flt(st->hFdCngDec->hFdCngCom->olapBufferSynth_flt, st->hFdCngDec->hFdCngCom->olapBufferSynth_flt, st->L_frame * 2, st->last_L_frame * 2); + + if (st->L_frame == L_FRAME) { - configureFdCngDec( st->hFdCngDec, st->bwidth, st->rf_flag == 1 && st->total_brate == ACELP_13k20 ? ACELP_9k60 : st->total_brate, st->L_frame, st->last_L_frame, st->element_mode ); - configureFdCngDec_fx( st->hFdCngDec, st->bwidth, st->rf_flag == 1 && st->total_brate == ACELP_13k20 ? ACELP_9k60 : st->total_brate, st->L_frame, st->last_L_frame, st->element_mode ); + for (i = 0; i < st->L_frame * 2; i++) + { + st->hFdCngDec->hFdCngCom->olapBufferSynth_flt[i] = st->hFdCngDec->hFdCngCom->olapBufferSynth_flt[i] * 0.6250f; + } } else { - configureFdCngDec( st->hFdCngDec, WB, ACELP_8k00, st->L_frame, st->last_L_frame, st->element_mode ); - configureFdCngDec_fx( st->hFdCngDec, WB, ACELP_8k00, st->L_frame, st->last_L_frame, st->element_mode ); - - if ( st->VAD ) - { - st->hFdCngDec->hFdCngCom->CngBitrate = st->total_brate; - } - } - if ( st->last_L_frame != st->L_frame && st->L_frame <= L_FRAME16k && st->last_L_frame <= L_FRAME16k ) - { - if ( st->element_mode == IVAS_CPE_DFT || st->element_mode == IVAS_CPE_TD ) - { - lerp_flt( st->hFdCngDec->hFdCngCom->olapBufferAna_flt + st->last_L_frame, st->hFdCngDec->hFdCngCom->olapBufferAna_flt + st->L_frame, st->L_frame, st->last_L_frame ); -#ifdef IVAS_FLOAT_FIXED - lerp( st->hFdCngDec->hFdCngCom->olapBufferAna_fx + st->last_L_frame, st->hFdCngDec->hFdCngCom->olapBufferAna_fx + st->L_frame, st->L_frame, st->last_L_frame ); -#endif // IVAS_FLOAT_FIXED - } - - lerp_flt( st->hFdCngDec->hFdCngCom->olapBufferSynth2_flt, st->hFdCngDec->hFdCngCom->olapBufferSynth2_flt, st->L_frame * 2, st->last_L_frame * 2 ); - - if ( st->total_brate <= SID_2k40 && st->last_total_brate <= SID_2k40 ) - { - lerp_flt( st->hFdCngDec->hFdCngCom->olapBufferSynth_flt, st->hFdCngDec->hFdCngCom->olapBufferSynth_flt, st->L_frame * 2, st->last_L_frame * 2 ); - - if ( st->L_frame == L_FRAME ) - { - for ( i = 0; i < st->L_frame * 2; i++ ) - { - st->hFdCngDec->hFdCngCom->olapBufferSynth_flt[i] = st->hFdCngDec->hFdCngCom->olapBufferSynth_flt[i] * 0.6250f; - } - } - else - { - for ( i = 0; i < st->L_frame * 2; i++ ) - { - st->hFdCngDec->hFdCngCom->olapBufferSynth_flt[i] = st->hFdCngDec->hFdCngCom->olapBufferSynth_flt[i] * 1.6f; - } - } - } + for (i = 0; i < st->L_frame * 2; i++) + { + st->hFdCngDec->hFdCngCom->olapBufferSynth_flt[i] = st->hFdCngDec->hFdCngCom->olapBufferSynth_flt[i] * 1.6f; + } } } + } + } - return error; + return error; } #endif #ifndef IVAS_FLOAT_FIXED @@ -1199,402 +1192,376 @@ ivas_error core_switching_pre_dec( * Postprocessing for ACELP/HQ core switching *---------------------------------------------------------------------*/ ivas_error core_switching_post_dec( - Decoder_State *st, /* i/o: decoder state structure */ - float *synth, /* i/o: output synthesis */ - float *output, /* i/o: LB synth/upsampled LB synth */ - float output_mem[], /* i : OLA memory from last TCX/HQ frame */ - const IVAS_FORMAT ivas_format, /* i : IVAS format */ - const int16_t use_cldfb_for_dft, /* i : flag to use of CLDFB for DFT Stereo */ - const int16_t output_frame, /* i : frame length */ - const int16_t core_switching_flag, /* i : ACELP->HQ switching flag */ - const int16_t sba_dirac_stereo_flag, /* i : signal stereo output for SBA DirAC */ - const int16_t nchan_out, /* i : number of output channels */ - const int16_t last_element_mode /* i : element mode of previous frame */ + Decoder_State *st, /* i/o: decoder state structure */ + float *synth, /* i/o: output synthesis */ + float *output, /* i/o: LB synth/upsampled LB synth */ + float output_mem[], /* i : OLA memory from last TCX/HQ frame */ + const IVAS_FORMAT ivas_format, /* i : IVAS format */ + const int16_t use_cldfb_for_dft, /* i : flag to use of CLDFB for DFT Stereo */ + const int16_t output_frame, /* i : frame length */ + const int16_t core_switching_flag, /* i : ACELP->HQ switching flag */ + const int16_t sba_dirac_stereo_flag, /* i : signal stereo output for SBA DirAC */ + const int16_t nchan_out, /* i : number of output channels */ + const int16_t last_element_mode /* i : element mode of previous frame */ ) { - int16_t i, delay_comp, delta; -#ifdef IVAS_FLOAT_FIXED - Word32 synth_fx[960]; - //Word32 output_fx[1500]; -#endif - float tmpF; - float tmpDelta; - float synth_subfr_out[SWITCH_MAX_GAP], synth_subfr_bwe[SWITCH_MAX_GAP]; - float mem_synth[NS2SA( 16000, DELAY_CLDFB_NS ) + 2]; - int16_t nZeros; - int16_t offset; - ivas_error error; - - error = IVAS_ERR_OK; - - if ( st->core == ACELP_CORE && st->bfi && st->hHQ_core != NULL && !st->con_tcx ) - { - if ( ( error = acelp_core_switch_dec_bfi( st ) ) != IVAS_ERR_OK ) - { + int16_t i, delay_comp, delta; + float tmpF; + float tmpDelta; + float synth_subfr_out[SWITCH_MAX_GAP], synth_subfr_bwe[SWITCH_MAX_GAP]; + float mem_synth[NS2SA(16000, DELAY_CLDFB_NS) + 2]; + int16_t nZeros; + int16_t offset; + ivas_error error; + + error = IVAS_ERR_OK; + + if (st->core == ACELP_CORE && st->bfi && st->hHQ_core != NULL && !st->con_tcx) + { + if ((error = acelp_core_switch_dec_bfi(st)) != IVAS_ERR_OK) + { + return error; + } + } + + /* set multiplication factor according to the sampling rate */ + delta = 1; + if (output_frame == L_FRAME16k) + { + delta = 2; + } + else if (output_frame == L_FRAME32k) + { + delta = 4; + } + else if (output_frame == L_FRAME48k) + { + delta = 6; + } + + /* set delay compensation between HQ synthesis and ACELP synthesis */ + delay_comp = delta * HQ_DELAY_COMP; + + /* Core switching done in DFT domain afterward*/ + if ((st->element_mode != IVAS_CPE_DFT || use_cldfb_for_dft) && (!sba_dirac_stereo_flag || (sba_dirac_stereo_flag && st->core_brate == SID_2k40 && st->cng_type == FD_CNG))) + { + if (st->core == HQ_CORE || st->core == TCX_20_CORE || st->core == TCX_10_CORE || (st->core == ACELP_CORE && st->bfi == 1 && st->con_tcx == 1)) + { + st->use_acelp_preq = 0; + if (st->hBWE_FD != NULL) + { + st->hBWE_FD->mem_deemph_old_syn = 0.0f; + } + + if (st->element_mode == EVS_MONO && st->core == HQ_CORE) /* ACELP->HQ-CORE */ + { + if (core_switching_flag && st->last_L_frame == st->last_L_frame_ori && (st->last_core == ACELP_CORE || st->last_core == AMR_WB_CORE)) + { + if ((error = acelp_core_switch_dec(st, synth_subfr_out, synth_subfr_bwe, output_frame, core_switching_flag, mem_synth, nchan_out)) != IVAS_ERR_OK) + { return error; + } } - } - - /* set multiplication factor according to the sampling rate */ - delta = 1; - if ( output_frame == L_FRAME16k ) - { - delta = 2; - } - else if ( output_frame == L_FRAME32k ) - { - delta = 4; - } - else if ( output_frame == L_FRAME48k ) - { - delta = 6; - } - - /* set delay compensation between HQ synthesis and ACELP synthesis */ - delay_comp = delta * HQ_DELAY_COMP; - /* Core switching done in DFT domain afterward*/ - if ( ( st->element_mode != IVAS_CPE_DFT || use_cldfb_for_dft ) && ( !sba_dirac_stereo_flag || ( sba_dirac_stereo_flag && st->core_brate == SID_2k40 && st->cng_type == FD_CNG ) ) ) - { - if ( st->core == HQ_CORE || st->core == TCX_20_CORE || st->core == TCX_10_CORE || ( st->core == ACELP_CORE && st->bfi == 1 && st->con_tcx == 1 ) ) + if (core_switching_flag && st->last_core == HQ_CORE && st->prev_bfi) { - st->use_acelp_preq = 0; - if ( st->hBWE_FD != NULL ) - { - st->hBWE_FD->mem_deemph_old_syn = 0.0f; - } - - if ( st->element_mode == EVS_MONO && st->core == HQ_CORE ) /* ACELP->HQ-CORE */ - { - if ( core_switching_flag && st->last_L_frame == st->last_L_frame_ori && ( st->last_core == ACELP_CORE || st->last_core == AMR_WB_CORE ) ) - { - if ( ( error = acelp_core_switch_dec( st, synth_subfr_out, synth_subfr_bwe, output_frame, core_switching_flag, mem_synth, nchan_out ) ) != IVAS_ERR_OK ) - { - return error; - } - } - - if ( core_switching_flag && st->last_core == HQ_CORE && st->prev_bfi ) - { - mvr2r( st->delay_buf_out, synth_subfr_out, delay_comp ); - } - } + mvr2r(st->delay_buf_out, synth_subfr_out, delay_comp); + } + } - /* delay HQ synthesis to synchronize with ACELP synthesis */ -#ifdef IVAS_FLOAT_FIXED - floatToFixed_arrL(synth, synth_fx, Q11, 960); - floatToFixed_arrL(st->delay_buf_out, st->delay_buf_out32_fx, Q11, 60); + /* delay HQ synthesis to synchronize with ACELP synthesis */ + delay_signal_float(synth, output_frame, st->delay_buf_out, delay_comp); - delay_signal_fx( synth_fx, output_frame, st->delay_buf_out32_fx, delay_comp ); + if (st->element_mode == EVS_MONO && st->core == HQ_CORE) /* ACELP->HQ-CORE */ + { + if (core_switching_flag && st->last_L_frame == st->last_L_frame_ori && (st->last_core == ACELP_CORE || st->last_core == AMR_WB_CORE)) + { + core_switching_OLA(mem_synth, st->last_L_frame, st->output_Fs, synth, synth_subfr_out, synth_subfr_bwe, output_frame, st->bwidth); + } + else if (core_switching_flag && st->last_core == HQ_CORE && st->prev_bfi) /* HQ | ACELP | TRANSITION with ACELP frame lost */ + { + /* Overlap between old->out[] (stocked in st->fer_samples[]) and good HQ frame on L/2 */ + nZeros = (int16_t)(NS2SA(st->output_Fs, N_ZERO_MDCT_NS)); + tmpDelta = 1.0f / (float)(output_frame >> 1); + for (i = 0; i < (output_frame >> 1); i++) + { + tmpF = (float)i * tmpDelta; + synth[i + delay_comp] = (1 - tmpF) * st->hHQ_core->fer_samples[i + nZeros] + synth[i + delay_comp] * tmpF; + } + } + else if ((!core_switching_flag && st->core == HQ_CORE && (st->last_core == ACELP_CORE || st->last_core == AMR_WB_CORE)) || /* ACELP | TRANSITION | HQ with TRANSITION lost */ + (core_switching_flag && st->prev_bfi && st->last_L_frame != st->last_L_frame_ori)) /* ACELP@12k8 | ACELP@16k | TRANSITION with ACELP@16k lost */ + { + /* Overlap between CELP estimation (BFI) and good HQ frame on L/2 */ + tmpDelta = 1.0f / (float)(output_frame >> 1); + for (i = 0; i < (output_frame >> 1); i++) + { + tmpF = (float)i * tmpDelta; + synth[i] = synth[i] * tmpF + (1 - tmpF) * st->hHQ_core->fer_samples[i]; + } + } + } + else if (((st->last_core == ACELP_CORE || st->last_core_bfi == ACELP_CORE) && !(st->prev_bfi == 1 && st->last_con_tcx == 1)) || st->last_core == AMR_WB_CORE) /*ACELP->TCX/HQ*/ + { + /* if this is first active MDCT-Stereo frame after a CNG frame and output format is mono DMX, this should only be done for the zero-th channel, the other one will simply be copied over after this function */ + if (((st->last_core_brate != SID_2k40 && st->last_core_brate != FRAME_NO_DATA) || (st->element_mode != IVAS_CPE_DFT && st->element_mode != IVAS_CPE_TD) || nchan_out == 1) && !(st->element_mode == IVAS_CPE_MDCT && st->idchan == 1 && (nchan_out == 1 || last_element_mode == IVAS_CPE_DFT))) + { + core_switch_lb_upsamp(st, output); + } - fixedToFloat_arrL(synth_fx, synth, Q11, 960); - fixedToFloat_arrL(st->delay_buf_out32_fx, st->delay_buf_out, Q11, 60); -#else - delay_signal_float( synth, output_frame, st->delay_buf_out, delay_comp ); -#endif + mvr2r(st->previoussynth, synth, delay_comp); - if ( st->element_mode == EVS_MONO && st->core == HQ_CORE ) /* ACELP->HQ-CORE */ - { - if ( core_switching_flag && st->last_L_frame == st->last_L_frame_ori && ( st->last_core == ACELP_CORE || st->last_core == AMR_WB_CORE ) ) - { - core_switching_OLA( mem_synth, st->last_L_frame, st->output_Fs, synth, synth_subfr_out, synth_subfr_bwe, output_frame, st->bwidth ); - } - else if ( core_switching_flag && st->last_core == HQ_CORE && st->prev_bfi ) /* HQ | ACELP | TRANSITION with ACELP frame lost */ - { - /* Overlap between old->out[] (stocked in st->fer_samples[]) and good HQ frame on L/2 */ - nZeros = (int16_t) ( NS2SA( st->output_Fs, N_ZERO_MDCT_NS ) ); - tmpDelta = 1.0f / (float) ( output_frame >> 1 ); - for ( i = 0; i < ( output_frame >> 1 ); i++ ) - { - tmpF = (float) i * tmpDelta; - synth[i + delay_comp] = ( 1 - tmpF ) * st->hHQ_core->fer_samples[i + nZeros] + synth[i + delay_comp] * tmpF; - } - } - else if ( ( !core_switching_flag && st->core == HQ_CORE && ( st->last_core == ACELP_CORE || st->last_core == AMR_WB_CORE ) ) || /* ACELP | TRANSITION | HQ with TRANSITION lost */ - ( core_switching_flag && st->prev_bfi && st->last_L_frame != st->last_L_frame_ori ) ) /* ACELP@12k8 | ACELP@16k | TRANSITION with ACELP@16k lost */ - { - /* Overlap between CELP estimation (BFI) and good HQ frame on L/2 */ - tmpDelta = 1.0f / (float) ( output_frame >> 1 ); - for ( i = 0; i < ( output_frame >> 1 ); i++ ) - { - tmpF = (float) i * tmpDelta; - synth[i] = synth[i] * tmpF + ( 1 - tmpF ) * st->hHQ_core->fer_samples[i]; - } - } - } - else if ( ( ( st->last_core == ACELP_CORE || st->last_core_bfi == ACELP_CORE ) && !( st->prev_bfi == 1 && st->last_con_tcx == 1 ) ) || st->last_core == AMR_WB_CORE ) /*ACELP->TCX/HQ*/ - { - /* if this is first active MDCT-Stereo frame after a CNG frame and output format is mono DMX, this should only be done for the zero-th channel, the other one will simply be copied over after this function */ - if ( ( ( st->last_core_brate != SID_2k40 && st->last_core_brate != FRAME_NO_DATA ) || ( st->element_mode != IVAS_CPE_DFT && st->element_mode != IVAS_CPE_TD ) || nchan_out == 1 ) && !( st->element_mode == IVAS_CPE_MDCT && st->idchan == 1 && ( nchan_out == 1 || last_element_mode == IVAS_CPE_DFT ) ) ) - { - core_switch_lb_upsamp( st, output ); - } + /* Overlap between TCX-LB and TCX-FB*/ + tmpDelta = NS2SA(st->output_Fs, DELAY_BWE_TOTAL_NS); + for (i = 0; i < tmpDelta; i++) + { + synth[i + delay_comp] = (synth[i + delay_comp] * i + (tmpDelta - i) * st->previoussynth[i + delay_comp]) / tmpDelta; + } - mvr2r( st->previoussynth, synth, delay_comp ); + if ((st->element_mode == IVAS_CPE_MDCT || (ivas_format == ISM_FORMAT && st->core == TCX_20_CORE /* <- means TCX in general, TCX10 is forbidden after ACELP */)) && st->last_core_brate <= SID_2k40 && st->core_brate > SID_2k40) + { + /* smooth transitions to avoid pops in car noise items */ + smoothTransitionDtxToTcx(synth, output_frame, delay_comp); + } - /* Overlap between TCX-LB and TCX-FB*/ - tmpDelta = NS2SA( st->output_Fs, DELAY_BWE_TOTAL_NS ); - for ( i = 0; i < tmpDelta; i++ ) - { - synth[i + delay_comp] = ( synth[i + delay_comp] * i + ( tmpDelta - i ) * st->previoussynth[i + delay_comp] ) / tmpDelta; - } + /* Reset memories of CLDFBs */ + if (st->cldfbAna != NULL) + { + if (st->cldfbAna->no_channels * st->cldfbAna->no_col != st->L_frame) + { + configureCldfb_ivas(st->cldfbAna, st->L_frame * FRAMES_PER_SEC); + configureCldfb_ivas(st->cldfbBPF, min(16000, st->L_frame * FRAMES_PER_SEC)); + } - if ( ( st->element_mode == IVAS_CPE_MDCT || ( ivas_format == ISM_FORMAT && st->core == TCX_20_CORE /* <- means TCX in general, TCX10 is forbidden after ACELP */ ) ) && st->last_core_brate <= SID_2k40 && st->core_brate > SID_2k40 ) - { - /* smooth transitions to avoid pops in car noise items */ -#ifdef IVAS_FLOAT_FIXED + cldfb_reset_memory_ivas(st->cldfbAna); + cldfb_reset_memory_ivas(st->cldfbBPF); + } + cldfb_reset_memory_ivas(st->cldfbSyn); - for ( int lp = 0; lp < 960; lp++ ) - { - synth_fx[lp] = (Word32) ( synth[lp] * ( 1u << 4 ) ); - } - smoothTransitionDtxToTcx_fx( synth_fx, output_frame, delay_comp ); - for ( int lp = 0; lp < 2 * delay_comp; lp++ ) - { - synth[lp] = (float) synth_fx[lp] / ( 1u << 4 ); - } -#else - smoothTransitionDtxToTcx( synth, output_frame, delay_comp ); -#endif - } + /* Update memories for CLDFB ana for eventual next ACELP frame */ + if (st->cldfbAna != NULL) + { + delta = st->cldfbAna->no_channels; + offset = st->cldfbAna->p_filter_length - st->cldfbAna->no_channels; + for (i = 0; i < delta; i++) + { + st->cldfbAna->cldfb_state[offset - delta + i] = + output[st->L_frame - delta + i] * ((float)(i + 1)) / ((float)delta); + } + } + } + else if (st->element_mode != EVS_MONO) + { + /* Reset memories of CLDFBs */ + if (st->cldfbAna != NULL) + { + if (st->cldfbAna->no_channels * st->cldfbAna->no_col != st->L_frame) + { + configureCldfb_ivas(st->cldfbAna, st->L_frame * FRAMES_PER_SEC); + configureCldfb_ivas(st->cldfbBPF, min(16000, st->L_frame * FRAMES_PER_SEC)); + } - /* Reset memories of CLDFBs */ - if ( st->cldfbAna != NULL ) - { - if ( st->cldfbAna->no_channels * st->cldfbAna->no_col != st->L_frame ) - { - configureCldfb_ivas( st->cldfbAna, st->L_frame * FRAMES_PER_SEC ); - configureCldfb_ivas( st->cldfbBPF, min( 16000, st->L_frame * FRAMES_PER_SEC ) ); - } + cldfb_reset_memory_ivas(st->cldfbAna); + cldfb_reset_memory_ivas(st->cldfbBPF); + } - cldfb_reset_memory_ivas( st->cldfbAna ); - cldfb_reset_memory_ivas( st->cldfbBPF ); - } - cldfb_reset_memory_ivas( st->cldfbSyn ); + if (st->cldfbSyn != NULL) + { + cldfb_reset_memory_ivas(st->cldfbSyn); + } - /* Update memories for CLDFB ana for eventual next ACELP frame */ - if ( st->cldfbAna != NULL ) - { - delta = st->cldfbAna->no_channels; - offset = st->cldfbAna->p_filter_length - st->cldfbAna->no_channels; - for ( i = 0; i < delta; i++ ) - { - st->cldfbAna->cldfb_state[offset - delta + i] = - output[st->L_frame - delta + i] * ( (float) ( i + 1 ) ) / ( (float) delta ); - } - } - } - else if ( st->element_mode != EVS_MONO ) - { - /* Reset memories of CLDFBs */ - if ( st->cldfbAna != NULL ) - { - if ( st->cldfbAna->no_channels * st->cldfbAna->no_col != st->L_frame ) - { - configureCldfb_ivas( st->cldfbAna, st->L_frame * FRAMES_PER_SEC ); - configureCldfb_ivas( st->cldfbBPF, min( 16000, st->L_frame * FRAMES_PER_SEC ) ); - } + /* Update memories for CLDFB ana for eventual next ACELP frame */ + /* Analysis CLDF memory is fed with ramped signal for last slot */ + if (st->cldfbAna != NULL) + { + delta = st->cldfbAna->no_channels; + offset = st->cldfbAna->p_filter_length - st->cldfbAna->no_channels; + for (i = 0; i < delta; i++) + { + st->cldfbAna->cldfb_state[offset - delta + i] = + output[st->L_frame - delta + i] * ((float)(i + 1)) / ((float)delta); + } + } + } - cldfb_reset_memory_ivas( st->cldfbAna ); - cldfb_reset_memory_ivas( st->cldfbBPF ); - } + if (st->hBWE_TD != NULL) + { + st->hBWE_TD->bwe_non_lin_prev_scale = 0.0; + } - if ( st->cldfbSyn != NULL ) - { - cldfb_reset_memory_ivas( st->cldfbSyn ); - } + if (st->hHQ_core != NULL && !(inner_frame_tbl[st->bwidth] == L_FRAME16k && st->core_brate <= HQ_32k)) + { + set_f(st->hHQ_core->prev_env, 0, SFM_N_WB); + set_f(st->hHQ_core->prev_normq, 0, SFM_N_WB); + } - /* Update memories for CLDFB ana for eventual next ACELP frame */ - /* Analysis CLDF memory is fed with ramped signal for last slot */ - if ( st->cldfbAna != NULL ) - { - delta = st->cldfbAna->no_channels; - offset = st->cldfbAna->p_filter_length - st->cldfbAna->no_channels; - for ( i = 0; i < delta; i++ ) - { - st->cldfbAna->cldfb_state[offset - delta + i] = - output[st->L_frame - delta + i] * ( (float) ( i + 1 ) ) / ( (float) delta ); - } - } - } + mvr2r(synth, st->previoussynth, output_frame); - if ( st->hBWE_TD != NULL ) - { - st->hBWE_TD->bwe_non_lin_prev_scale = 0.0; - } + /*Set post-filtering flag to zero*/ + if (st->hBPF != NULL) + { + st->hPFstat->on = 0; + } +} + else + { + /* MDCT to ACELP transition */ + if (st->last_core == HQ_CORE || st->last_core == TCX_20_CORE || st->last_core == TCX_10_CORE) + { + nZeros = (int16_t)(NS2SA(st->output_Fs, N_ZERO_MDCT_NS)); + mvr2r(st->delay_buf_out, synth, delay_comp); /* copy the HQ/ACELP delay synchronization buffer at the beginning of ACELP frame */ - if ( st->hHQ_core != NULL && !( inner_frame_tbl[st->bwidth] == L_FRAME16k && st->core_brate <= HQ_32k ) ) - { - set_f( st->hHQ_core->prev_env, 0, SFM_N_WB ); - set_f( st->hHQ_core->prev_normq, 0, SFM_N_WB ); - } + if (st->prev_bfi && st->hHQ_core != NULL && st->hHQ_core->HqVoicing && st->last_core == HQ_CORE) + { + mvr2r(st->hHQ_core->fer_samples, st->hHQ_core->old_out + nZeros, NS2SA(st->output_Fs, 3000000)); + } - mvr2r( synth, st->previoussynth, output_frame ); + tmpF = 1.0f / (float)NS2SA(st->output_Fs, 3000000); - /*Set post-filtering flag to zero*/ - if ( st->hBPF != NULL ) - { - st->hPFstat->on = 0; - } + if (st->element_mode == IVAS_CPE_TD && st->hHQ_core == NULL) + { + for (i = 0; i < NS2SA(st->output_Fs, 3000000); i++) + { + synth[i + delay_comp] = (1 - tmpF * (float)i) * output_mem[i] + tmpF * (float)i * synth[i + delay_comp]; + } + } + else if (st->element_mode == IVAS_CPE_MDCT && st->core_brate <= SID_2k40 && st->prev_bfi) + { + for (i = 0; i < NS2SA(st->output_Fs, 3000000); i++) + { + synth[i + delay_comp] = (1 - tmpF * (float)i) * st->hHQ_core->old_out[i + nZeros] * st->hTcxDec->conceal_eof_gain_float + tmpF * (float)i * synth[i + delay_comp]; + } } else { - /* MDCT to ACELP transition */ - if ( st->last_core == HQ_CORE || st->last_core == TCX_20_CORE || st->last_core == TCX_10_CORE ) - { - nZeros = (int16_t) ( NS2SA( st->output_Fs, N_ZERO_MDCT_NS ) ); - mvr2r( st->delay_buf_out, synth, delay_comp ); /* copy the HQ/ACELP delay synchronization buffer at the beginning of ACELP frame */ - - if ( st->prev_bfi && st->hHQ_core != NULL && st->hHQ_core->HqVoicing && st->last_core == HQ_CORE ) - { - mvr2r( st->hHQ_core->fer_samples, st->hHQ_core->old_out + nZeros, NS2SA( st->output_Fs, 3000000 ) ); - } - - tmpF = 1.0f / (float) NS2SA( st->output_Fs, 3000000 ); - - if ( st->element_mode == IVAS_CPE_TD && st->hHQ_core == NULL ) - { - for ( i = 0; i < NS2SA( st->output_Fs, 3000000 ); i++ ) - { - synth[i + delay_comp] = ( 1 - tmpF * (float) i ) * output_mem[i] + tmpF * (float) i * synth[i + delay_comp]; - } - } - else if ( st->element_mode == IVAS_CPE_MDCT && st->core_brate <= SID_2k40 && st->prev_bfi ) - { - for ( i = 0; i < NS2SA( st->output_Fs, 3000000 ); i++ ) - { - synth[i + delay_comp] = ( 1 - tmpF * (float) i ) * st->hHQ_core->old_out[i + nZeros] * st->hTcxDec->conceal_eof_gain_float + tmpF * (float) i * synth[i + delay_comp]; - } - } - else - { - for ( i = 0; i < NS2SA( st->output_Fs, 3000000 ); i++ ) - { - synth[i + delay_comp] = ( 1 - tmpF * (float) i ) * st->hHQ_core->old_out[i + nZeros] + tmpF * (float) i * synth[i + delay_comp]; - } - } - } - - set_f( st->delay_buf_out, 0, HQ_DELTA_MAX * HQ_DELAY_COMP ); - if ( st->hHQ_core != NULL ) - { - st->hHQ_core->oldHqVoicing = 0; - } + for (i = 0; i < NS2SA(st->output_Fs, 3000000); i++) + { + synth[i + delay_comp] = (1 - tmpF * (float)i) * st->hHQ_core->old_out[i + nZeros] + tmpF * (float)i * synth[i + delay_comp]; + } } - } - else - { - /* memory update needed for DFT stereo -> TD stereo switching */ - mvr2r( synth + output_frame - delay_comp, st->delay_buf_out, delay_comp ); - } + } - /* reset SWB BWE buffers */ - if ( st->bws_cnt == 0 || ( st->bws_cnt > 0 && st->coder_type != INACTIVE && st->coder_type != AUDIO ) ) - { - st->attenu1 = 0.1f; + set_f(st->delay_buf_out, 0, HQ_DELTA_MAX * HQ_DELAY_COMP); + if (st->hHQ_core != NULL) + { + st->hHQ_core->oldHqVoicing = 0; + } } + } + else + { + /* memory update needed for DFT stereo -> TD stereo switching */ + mvr2r(synth + output_frame - delay_comp, st->delay_buf_out, delay_comp); + } - if ( st->hBWE_FD != NULL && - ( ( st->last_extl != SWB_BWE && st->extl == SWB_BWE ) || ( st->last_extl != FB_BWE && st->extl == FB_BWE ) || - ( ( st->last_core == HQ_CORE || st->last_core == TCX_20_CORE || st->last_core == TCX_10_CORE || st->last_extl == SWB_TBE ) && st->extl < 0 && st->core == ACELP_CORE ) || ( st->last_core == ACELP_CORE && st->core == ACELP_CORE && ( ( st->prev_coder_type != INACTIVE && st->coder_type != INACTIVE ) || ( st->prev_coder_type != AUDIO && st->coder_type == AUDIO ) ) && st->bws_cnt > 0 ) ) ) - { - set_f( st->hBWE_FD->old_wtda_swb, 0, output_frame ); - - if ( st->last_extl != WB_BWE ) - { - st->hBWE_FD->prev_mode = NORMAL; - } + /* reset SWB BWE buffers */ + if (st->bws_cnt == 0 || (st->bws_cnt > 0 && st->coder_type != INACTIVE && st->coder_type != AUDIO)) + { + st->attenu1 = 0.1f; + } - st->hBWE_FD->prev_Energy = 0.0f; - st->hBWE_FD->prev_L_swb_norm = 8; - st->hBWE_FD->prev_frica_flag = 0; - set_f( st->hBWE_FD->mem_imdct, 0, L_FRAME48k ); - st->hBWE_FD->prev_td_energy = 0.0f; - st->hBWE_FD->prev_weight = 0.2f; - st->hBWE_FD->prev_fb_ener_adjust = 0.0f; - } + if (st->hBWE_FD != NULL && + ((st->last_extl != SWB_BWE && st->extl == SWB_BWE) || (st->last_extl != FB_BWE && st->extl == FB_BWE) || + ((st->last_core == HQ_CORE || st->last_core == TCX_20_CORE || st->last_core == TCX_10_CORE || st->last_extl == SWB_TBE) && st->extl < 0 && st->core == ACELP_CORE) || (st->last_core == ACELP_CORE && st->core == ACELP_CORE && ((st->prev_coder_type != INACTIVE && st->coder_type != INACTIVE) || (st->prev_coder_type != AUDIO && st->coder_type == AUDIO)) && st->bws_cnt > 0))) + { + set_f(st->hBWE_FD->old_wtda_swb, 0, output_frame); - /* reset WB BWE buffers */ - if ( st->last_extl != WB_BWE && st->extl == WB_BWE && st->hBWE_FD != NULL ) + if (st->last_extl != WB_BWE) { - set_f( st->hBWE_FD->old_wtda_swb, 0, output_frame ); + st->hBWE_FD->prev_mode = NORMAL; + } - if ( st->last_extl != SWB_BWE && st->last_extl != FB_BWE ) - { - st->hBWE_FD->prev_mode = NORMAL; - } + st->hBWE_FD->prev_Energy = 0.0f; + st->hBWE_FD->prev_L_swb_norm = 8; + st->hBWE_FD->prev_frica_flag = 0; + set_f(st->hBWE_FD->mem_imdct, 0, L_FRAME48k); + st->hBWE_FD->prev_td_energy = 0.0f; + st->hBWE_FD->prev_weight = 0.2f; + st->hBWE_FD->prev_fb_ener_adjust = 0.0f; + } - st->hBWE_FD->prev_Energy_wb = 0.0f; - st->hBWE_FD->prev_L_swb_norm = 8; - set_f( st->hBWE_FD->mem_imdct, 0, L_FRAME48k ); - st->hBWE_FD->prev_flag = 0; - } + /* reset WB BWE buffers */ + if (st->last_extl != WB_BWE && st->extl == WB_BWE && st->hBWE_FD != NULL) + { + set_f(st->hBWE_FD->old_wtda_swb, 0, output_frame); - /* reset TBE buffers */ - if ( st->hBWE_TD != NULL ) + if (st->last_extl != SWB_BWE && st->last_extl != FB_BWE) { - /* reset SWB TBE buffers */ - if ( ( ( st->extl == SWB_TBE || st->extl == FB_TBE || st->extl == SWB_CNG ) && - ( st->L_frame != st->last_L_frame || ( st->last_extl != SWB_TBE && st->last_extl != FB_TBE && st->last_core != TCX_20_CORE && st->last_core != TCX_10_CORE ) || st->last_core == HQ_CORE ) ) || - ( st->bwidth < st->last_bwidth && st->last_extl != SWB_TBE ) || st->old_ppp_mode || ( ( st->prev_coder_type == AUDIO || st->prev_coder_type == INACTIVE ) && st->bws_cnt > 0 ) || ( st->bws_cnt == 0 && st->prev_bws_cnt == N_WS2N_FRAMES ) ) - { - swb_tbe_reset( st->hBWE_TD->mem_csfilt, st->hBWE_TD->mem_genSHBexc_filt_down_shb, st->hBWE_TD->state_lpc_syn, st->hBWE_TD->syn_overlap, st->hBWE_TD->state_syn_shbexc, &( st->hBWE_TD->tbe_demph ), &( st->hBWE_TD->tbe_premph ), st->hBWE_TD->mem_stp_swb, &( st->hBWE_TD->gain_prec_swb ) ); + st->hBWE_FD->prev_mode = NORMAL; + } - /* reset GainShape delay for SWB TBE FEC */ - set_f( st->hBWE_TD->GainShape_Delay, 0, NUM_SHB_SUBFR / 2 ); + st->hBWE_FD->prev_Energy_wb = 0.0f; + st->hBWE_FD->prev_L_swb_norm = 8; + set_f(st->hBWE_FD->mem_imdct, 0, L_FRAME48k); + st->hBWE_FD->prev_flag = 0; + } - swb_tbe_reset_synth( st->hBWE_TD->genSHBsynth_Hilbert_Mem, st->hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local ); + /* reset TBE buffers */ + if (st->hBWE_TD != NULL) + { + /* reset SWB TBE buffers */ + if (((st->extl == SWB_TBE || st->extl == FB_TBE || st->extl == SWB_CNG) && + (st->L_frame != st->last_L_frame || (st->last_extl != SWB_TBE && st->last_extl != FB_TBE && st->last_core != TCX_20_CORE && st->last_core != TCX_10_CORE) || st->last_core == HQ_CORE)) || + (st->bwidth < st->last_bwidth && st->last_extl != SWB_TBE) || st->old_ppp_mode || ((st->prev_coder_type == AUDIO || st->prev_coder_type == INACTIVE) && st->bws_cnt > 0) || (st->bws_cnt == 0 && st->prev_bws_cnt == N_WS2N_FRAMES)) + { + swb_tbe_reset(st->hBWE_TD->mem_csfilt, st->hBWE_TD->mem_genSHBexc_filt_down_shb, st->hBWE_TD->state_lpc_syn, st->hBWE_TD->syn_overlap, st->hBWE_TD->state_syn_shbexc, &(st->hBWE_TD->tbe_demph), &(st->hBWE_TD->tbe_premph), st->hBWE_TD->mem_stp_swb, &(st->hBWE_TD->gain_prec_swb)); - if ( output_frame == L_FRAME16k ) - { - set_f( st->hBWE_TD->mem_resamp_HB_32k, 0, 2 * ALLPASSSECTIONS_STEEP + 1 ); /* reset in case that SWB TBE layer is transmitted, but the output is 16kHz sampled */ - } + /* reset GainShape delay for SWB TBE FEC */ + set_f(st->hBWE_TD->GainShape_Delay, 0, NUM_SHB_SUBFR / 2); - set_f( st->hBWE_TD->int_3_over_2_tbemem_dec, 0.0f, INTERP_3_2_MEM_LEN ); - st->hBWE_TD->prev_pow_exc16kWhtnd = 1.0f; - st->hBWE_TD->prev_mix_factor = 1.0f; - } - else if ( ( st->extl == SWB_TBE || st->extl == FB_TBE ) && ( ( st->element_mode == IVAS_CPE_TD && st->last_extl != SWB_TBE && st->last_extl != FB_TBE ) || ( st->element_mode != IVAS_CPE_TD && st->last_total_brate != st->total_brate ) || ( st->last_bwidth != st->bwidth ) || ( st->last_codec_mode != MODE1 ) || ( st->rf_flag != st->rf_flag_last ) ) ) - { - set_f( st->hBWE_TD->state_lpc_syn, 0.0f, LPC_SHB_ORDER ); - set_f( st->hBWE_TD->state_syn_shbexc, 0.0f, L_SHB_LAHEAD ); - set_f( st->hBWE_TD->mem_stp_swb, 0.0f, LPC_SHB_ORDER ); - set_f( st->hBWE_TD->mem_zero_swb, 0, LPC_SHB_ORDER ); - st->hBWE_TD->gain_prec_swb = 1.0f; - } - else if ( st->hBWE_TD != NULL && ( st->last_core == TCX_20_CORE || st->last_core == TCX_10_CORE ) ) - { - TBEreset_dec( st ); - } + swb_tbe_reset_synth(st->hBWE_TD->genSHBsynth_Hilbert_Mem, st->hBWE_TD->genSHBsynth_state_lsyn_filt_shb_local); - /* reset FB TBE buffers */ - if ( ( st->L_frame != st->last_L_frame || st->last_extl != FB_TBE ) && st->extl == FB_TBE ) - { - set_f( st->hBWE_TD->fb_state_lpc_syn, 0, LPC_SHB_ORDER ); - st->hBWE_TD->fb_tbe_demph = 0; - fb_tbe_reset_synth( st->hBWE_TD->fbbwe_hpf_mem, &st->hBWE_TD->prev_fbbwe_ratio ); - } + if (output_frame == L_FRAME16k) + { + set_f(st->hBWE_TD->mem_resamp_HB_32k, 0, 2 * ALLPASSSECTIONS_STEEP + 1); /* reset in case that SWB TBE layer is transmitted, but the output is 16kHz sampled */ + } - /* reset WB TBE buffers */ - if ( st->last_extl != WB_TBE && st->extl == WB_TBE && st->last_core != TCX_20_CORE && st->last_core != TCX_10_CORE ) - { - wb_tbe_extras_reset( st->hBWE_TD->mem_genSHBexc_filt_down_wb2, st->hBWE_TD->mem_genSHBexc_filt_down_wb3 ); - wb_tbe_extras_reset_synth( st->hBWE_TD->state_lsyn_filt_shb, st->hBWE_TD->state_lsyn_filt_dwn_shb, st->hBWE_TD->mem_resamp_HB ); + set_f(st->hBWE_TD->int_3_over_2_tbemem_dec, 0.0f, INTERP_3_2_MEM_LEN); + st->hBWE_TD->prev_pow_exc16kWhtnd = 1.0f; + st->hBWE_TD->prev_mix_factor = 1.0f; + } + else if ((st->extl == SWB_TBE || st->extl == FB_TBE) && ((st->element_mode == IVAS_CPE_TD && st->last_extl != SWB_TBE && st->last_extl != FB_TBE) || (st->element_mode != IVAS_CPE_TD && st->last_total_brate != st->total_brate) || (st->last_bwidth != st->bwidth) || (st->last_codec_mode != MODE1) || (st->rf_flag != st->rf_flag_last))) + { + set_f(st->hBWE_TD->state_lpc_syn, 0.0f, LPC_SHB_ORDER); + set_f(st->hBWE_TD->state_syn_shbexc, 0.0f, L_SHB_LAHEAD); + set_f(st->hBWE_TD->mem_stp_swb, 0.0f, LPC_SHB_ORDER); + set_f(st->hBWE_TD->mem_zero_swb, 0, LPC_SHB_ORDER); + st->hBWE_TD->gain_prec_swb = 1.0f; + } + else if (st->hBWE_TD != NULL && (st->last_core == TCX_20_CORE || st->last_core == TCX_10_CORE)) + { + TBEreset_dec(st); + } - set_f( st->hBWE_TD->state_syn_shbexc, 0, L_SHB_LAHEAD / 4 ); - set_f( st->hBWE_TD->syn_overlap, 0, L_SHB_LAHEAD ); - set_f( st->hBWE_TD->mem_csfilt, 0, 2 ); - } + /* reset FB TBE buffers */ + if ((st->L_frame != st->last_L_frame || st->last_extl != FB_TBE) && st->extl == FB_TBE) + { + set_f(st->hBWE_TD->fb_state_lpc_syn, 0, LPC_SHB_ORDER); + st->hBWE_TD->fb_tbe_demph = 0; + fb_tbe_reset_synth(st->hBWE_TD->fbbwe_hpf_mem, &st->hBWE_TD->prev_fbbwe_ratio); } - /* Interp_3_2 CNG buffers reset */ - if ( st->hTdCngDec != NULL && st->output_Fs == 48000 && ( st->last_core_brate > SID_2k40 ) && ( st->core_brate == FRAME_NO_DATA || st->core_brate == SID_2k40 ) && st->hTdCngDec != NULL ) + /* reset WB TBE buffers */ + if (st->last_extl != WB_TBE && st->extl == WB_TBE && st->last_core != TCX_20_CORE && st->last_core != TCX_10_CORE) { - set_f( st->hTdCngDec->interpol_3_2_cng_dec, 0.0f, INTERP_3_2_MEM_LEN ); + wb_tbe_extras_reset(st->hBWE_TD->mem_genSHBexc_filt_down_wb2, st->hBWE_TD->mem_genSHBexc_filt_down_wb3); + wb_tbe_extras_reset_synth(st->hBWE_TD->state_lsyn_filt_shb, st->hBWE_TD->state_lsyn_filt_dwn_shb, st->hBWE_TD->mem_resamp_HB); + + set_f(st->hBWE_TD->state_syn_shbexc, 0, L_SHB_LAHEAD / 4); + set_f(st->hBWE_TD->syn_overlap, 0, L_SHB_LAHEAD); + set_f(st->hBWE_TD->mem_csfilt, 0, 2); } + } - return error; + /* Interp_3_2 CNG buffers reset */ + if (st->hTdCngDec != NULL && st->output_Fs == 48000 && (st->last_core_brate > SID_2k40) && (st->core_brate == FRAME_NO_DATA || st->core_brate == SID_2k40) && st->hTdCngDec != NULL) + { + set_f(st->hTdCngDec->interpol_3_2_cng_dec, 0.0f, INTERP_3_2_MEM_LEN); + } + + return error; } + #endif /*---------------------------------------------------------------------* * core_switching_hq_prepare_dec() diff --git a/lib_dec/ivas_mct_dec.c b/lib_dec/ivas_mct_dec.c index 3c5cd9a64..390fc1ae4 100644 --- a/lib_dec/ivas_mct_dec.c +++ b/lib_dec/ivas_mct_dec.c @@ -2178,13 +2178,13 @@ static ivas_error ivas_mc_dec_reconfig( { return error; } -#endif // IVAS_FLOAT_FIXED +#else // IVAS_FLOAT_FIXED /*To be removed later: Contains memory allocations for floating point buffers*/ - //if ( ( error = ivas_hp20_dec_reconfig( st_ivas, nchan_hp20_old ) ) != IVAS_ERR_OK ) - //{ - // return error; - //} - + if ( ( error = ivas_hp20_dec_reconfig( st_ivas, nchan_hp20_old ) ) != IVAS_ERR_OK ) + { + return error; + } +#endif /*-----------------------------------------------------------------* * Allocate the LFE handle that is coded separately after the allocation of the core coders *-----------------------------------------------------------------*/ diff --git a/lib_dec/ivas_sba_dec.c b/lib_dec/ivas_sba_dec.c index 3d8c0efb5..848c602fc 100644 --- a/lib_dec/ivas_sba_dec.c +++ b/lib_dec/ivas_sba_dec.c @@ -763,12 +763,12 @@ ivas_error ivas_sba_dec_reconfigure( { return error; } -#endif // IVAS_FLOAT_FIXED - //if ( ( error = ivas_hp20_dec_reconfig( st_ivas, nchan_hp20_old ) ) != IVAS_ERR_OK ) - //{ - // return error; - //} - +#else + if ( ( error = ivas_hp20_dec_reconfig( st_ivas, nchan_hp20_old ) ) != IVAS_ERR_OK ) + { + return error; + } +#endif /*-----------------------------------------------------------------* * TD Decorrelator *-----------------------------------------------------------------*/ @@ -2154,7 +2154,6 @@ ivas_error ivas_sba_dec_render( output_f_local[ch] = output_f[ch]; } - 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 */ @@ -2173,113 +2172,7 @@ ivas_error ivas_sba_dec_render( { int16_t n_samples_sf = slot_size * hSpar->subframe_nbslots[subframe_idx]; -#ifdef IVAS_FLOAT_FIXED1 -#if 1 /*Float to fixed conversion*/ - Word16 numch_out = hSpar->hFbMixer->fb_cfg->num_out_chans; - Word16 numch_in = hSpar->hFbMixer->fb_cfg->num_in_chans; - Word16 num_spar_bands = hSpar->hFbMixer->pFb->filterbank_num_bands; - DECODER_CONFIG_HANDLE hDecoderConfig; - hDecoderConfig = st_ivas->hDecoderConfig; - Word16 numch_out_dirac = hDecoderConfig->nchan_out; - - Word16 num_md_sub_frames = ivas_get_spar_dec_md_num_subframes( st_ivas->sba_order, hDecoderConfig->ivas_total_brate, st_ivas->last_active_ivas_total_brate ); - - for ( int i = 0; i < s_max( st_ivas->nchan_ism, 0 ) + nchan_internal; i++ ) - { - floatToFixed_arr32( st_ivas->hTcBuffer->tc[i], st_ivas->hTcBuffer->tc_fx[i], Q11, st_ivas->hTcBuffer->n_samples_available ); - } -#endif -#if 0 - Word16 q1 = 30, q2 = 30; - for ( int l = 0; l < numch_out; l++ ) - { - for ( int j = 0; j < numch_in; j++ ) - { - for ( int k = 0; k < num_md_sub_frames * IVAS_MAX_NUM_BANDS; k++ ) - { - hSpar->hMdDec->mixer_mat_fx[l][j][k] = floatToFixed(hSpar->hMdDec->mixer_mat[l][j][k] , q1 ); - } - } - } - for ( int m = 0; m < MAX_PARAM_SPATIAL_SUBFRAMES + 1; m++ ) - { - for ( int j = 0; j < IVAS_MAX_FB_MIXER_OUT_CH; j++ ) - { - for ( int k = 0; k < IVAS_MAX_SPAR_FB_MIXER_IN_CH; k++ ) - { - for ( int l = 0; l < IVAS_MAX_NUM_BANDS; l++ ) - { - hSpar->hMdDec->mixer_mat_prev_fx[m][j][k][l] = floatToFixed( hSpar->hMdDec->mixer_mat_prev[m][j][k][l] , q2 ); - } - } - } - } -#endif -#if 1 - for ( Word16 in_ch = 0; in_ch < numch_in; in_ch++ ) - { - for ( Word16 i = 0; i < st_ivas->cldfbAnaDec[in_ch]->p_filter_length - st_ivas->cldfbAnaDec[in_ch]->no_channels; i++ ) - { - st_ivas->cldfbAnaDec[in_ch]->cldfb_state_fx[i] = (Word32) ( st_ivas->cldfbAnaDec[in_ch]->cldfb_state[i] * ( 1LL << ( Q11 ) ) ); - } - } - if ( ( hDecoderConfig->ivas_total_brate < IVAS_24k4 ) && ( ( hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_HOA2 ) || ( hDecoderConfig->output_config == IVAS_AUDIO_CONFIG_HOA3 ) ) ) - { - for ( Word16 i = 0; i < IVAS_MAX_NUM_BANDS; i++ ) - { - floatToFixed_arrL( hSpar->hMdDec->smooth_buf[i], hSpar->hMdDec->smooth_buf_fx[i], 0, 2 * SBA_DIRAC_NRG_SMOOTH_LONG + 1 ); - } - floatToFixed_arr( hSpar->hMdDec->smooth_fac, hSpar->hMdDec->smooth_fac_fx, Q15, IVAS_MAX_NUM_BANDS ); - } -#endif // - ivas_spar_dec_upmixer_sf_fx( st_ivas, output_f_local_fx, nchan_internal ); -#ifdef IVAS_FLOAT_FIXED /*Fixed to float */ - FOR( Word16 in_ch = 0; in_ch < numch_in; in_ch++ ) - { - FOR( Word16 i = 0; i < st_ivas->cldfbAnaDec[in_ch]->p_filter_length - st_ivas->cldfbAnaDec[in_ch]->no_channels; i++ ) - { - st_ivas->cldfbAnaDec[in_ch]->cldfb_state[i] = ( (float) ( st_ivas->cldfbAnaDec[in_ch]->cldfb_state_fx[i] ) / ( 1LL << ( Q11 ) ) ); /*Rounding off*/ - } - } -#if 0 - FOR( int m = 0; m < MAX_PARAM_SPATIAL_SUBFRAMES + 1; m++ ) - { - FOR( int j = 0; j < IVAS_MAX_FB_MIXER_OUT_CH; j++ ) - { - FOR( int k = 0; k < IVAS_MAX_SPAR_FB_MIXER_IN_CH; k++ ) - { - FOR( int l = 0; l < IVAS_MAX_NUM_BANDS; l++ ) - { - hSpar->hMdDec->mixer_mat_prev[m][j][k][l] = ( (float) hSpar->hMdDec->mixer_mat_prev_fx[m][j][k][l] / ( 1 << q2 ) ); - } - } - } - } -#endif - // fix2float (to be cleaned) - IF( ( LT_32( hDecoderConfig->ivas_total_brate, IVAS_24k4 ) ) && ( ( EQ_16( hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_HOA2 ) ) || ( EQ_16( hDecoderConfig->output_config, IVAS_AUDIO_CONFIG_HOA3 ) ) ) ) - { - fixedToFloat_arr( hSpar->hMdDec->smooth_fac_fx, hSpar->hMdDec->smooth_fac, Q15, IVAS_MAX_NUM_BANDS ); - FOR( Word16 i = 0; i < IVAS_MAX_NUM_BANDS; i++ ) - { - fixedToFloat_arrL( hSpar->hMdDec->smooth_buf_fx[i], hSpar->hMdDec->smooth_buf[i], 0, 2 * SBA_DIRAC_NRG_SMOOTH_LONG + 1 ); - } - } - // fix2float end - FOR( Word16 out_ch = 0; out_ch < numch_out_dirac; out_ch++ ) - { - IF( st_ivas->cldfbSynDec[out_ch] ) - { - FOR( Word16 i = 0; i < st_ivas->cldfbSynDec[out_ch]->p_filter_length; i++ ) - { - st_ivas->cldfbSynDec[out_ch]->cldfb_state[i] = ( (float) ( st_ivas->cldfbSynDec[out_ch]->cldfb_state_fx[i] ) / (float) ( 1LL << ( Q7 ) ) ); /*Rounding off*/ - } - } - } -#endif -#else ivas_spar_dec_upmixer_sf( st_ivas, output_f_local, nchan_internal ); -#endif // IVAS_FLOAT_FIXED for ( ch = 0; ch < nchan_out; ch++ ) { output_f_local[ch] += n_samples_sf; diff --git a/lib_dec/ivas_spar_md_dec.c b/lib_dec/ivas_spar_md_dec.c index 5ec2167a7..b37c4720f 100644 --- a/lib_dec/ivas_spar_md_dec.c +++ b/lib_dec/ivas_spar_md_dec.c @@ -45,7 +45,7 @@ #include "prot_fx2.h" #include "ivas_prot_fx.h" #endif // IVAS_FLOAT_FIXED - +#ifdef IVAS_FLOAT_FIXED /*------------------------------------------------------------------------------------------* * Local constants @@ -1332,7 +1332,6 @@ static void ivas_dec_mono_sba_handling_fx( return; } - #endif #ifdef IVAS_FLOAT_FIXED /*-----------------------------------------------------------------------------------------* @@ -3510,7 +3509,6 @@ static void ivas_decode_arith_bs( return; } - /*-----------------------------------------------------------------------------------------* * Function ivas_fill_band_coeffs_idx() * @@ -3903,6 +3901,7 @@ static void ivas_spar_md_fill_invalid_bands( } #endif +#ifdef IVAS_FLOAT_FIXED static void ivas_spar_md_fill_invalid_bandcoeffs( ivas_band_coeffs_t *pBand_coeffs, ivas_band_coeffs_t *pBand_coeffs_prev, @@ -3991,7 +3990,87 @@ static void ivas_spar_md_fill_invalid_bandcoeffs( return; } +#else +static void ivas_spar_md_fill_invalid_bandcoeffs( + ivas_band_coeffs_t *pBand_coeffs, + ivas_band_coeffs_t *pBand_coeffs_prev, + const int16_t *valid_bands, + int16_t *base_band_age, + int16_t *first_valid_frame, + const int16_t num_bands ) +{ + int16_t j, k, b, all_valid; + int16_t valid_band_idx[IVAS_MAX_NUM_BANDS], idx = -1; + int16_t last_valid_band_idx[IVAS_MAX_NUM_BANDS]; + float w = 0; + + ivas_spar_plc_get_band_age( valid_bands, base_band_age, num_bands, + last_valid_band_idx, valid_band_idx, &all_valid, &idx ); + + assert( idx > 0 ); /* some bands should be valid */ + + if ( all_valid == 0 ) + { + for ( b = 0; b < num_bands; b++ ) + { + /* check against non zero in if and else if */ + if ( ( base_band_age[b] > 3 ) || ( *first_valid_frame == 0 ) ) /* old invalid bands */ + { + int16_t id0, id1; + ivas_spar_get_plc_interp_weights( valid_band_idx, last_valid_band_idx[b], + idx, b, &w, &id0, &id1 ); + + for ( j = 0; j < IVAS_SPAR_MAX_CH - 1; j++ ) + { + pBand_coeffs[b].pred_re[j] = ( 1 - w ) * pBand_coeffs[id0].pred_re[j] + w * pBand_coeffs[id1].pred_re[j]; + } + + for ( j = 0; j < IVAS_SPAR_MAX_CH - IVAS_SPAR_MAX_DMX_CHS; j++ ) + { + for ( k = 0; k < IVAS_SPAR_MAX_DMX_CHS - 1; k++ ) + { + pBand_coeffs[b].C_re[j][k] = ( 1 - w ) * pBand_coeffs[id0].C_re[j][k] + w * pBand_coeffs[id1].C_re[j][k]; + } + } + + for ( j = 0; j < IVAS_SPAR_MAX_CH - 1; j++ ) + { + pBand_coeffs[b].P_re[j] = ( 1 - w ) * pBand_coeffs[id0].P_re[j] + w * pBand_coeffs[id1].P_re[j]; + } + } + else /* young invalid bands */ + { + if ( valid_bands[b] == 0 ) + { + for ( j = 0; j < IVAS_SPAR_MAX_CH - 1; j++ ) + { + pBand_coeffs[b].pred_re[j] = pBand_coeffs_prev[b].pred_re[j]; + } + + for ( j = 0; j < IVAS_SPAR_MAX_CH - IVAS_SPAR_MAX_DMX_CHS; j++ ) + { + for ( k = 0; k < IVAS_SPAR_MAX_DMX_CHS - 1; k++ ) + { + pBand_coeffs[b].C_re[j][k] = pBand_coeffs_prev[b].C_re[j][k]; + } + } + for ( j = 0; j < IVAS_SPAR_MAX_CH - 1; j++ ) + { + pBand_coeffs[b].P_re[j] = pBand_coeffs_prev[b].P_re[j]; + } + } + } + } + } + else + { + *first_valid_frame = 1; + } + + return; +} +#endif /*-----------------------------------------------------------------------------------------* * Function ivas_spar_dec_compute_ramp_down_post_matrix_fx() @@ -5234,3 +5313,2686 @@ void ivas_spar_to_dirac_fx( } #endif +#else + +/*------------------------------------------------------------------------------------------* + * Local constants + *------------------------------------------------------------------------------------------*/ + +#define IVAS_DEFAULT_DTX_CNG_RAMP ( 8 ) + +/* PLC constants */ +static const int16_t ivas_spar_dec_plc_num_frames_keep = 9; +static const int16_t ivas_spar_dec_plc_num_frames_fade_out = 9; +static const int16_t ivas_spar_dec_plc_per_frame_ramp_down_gain_dB = 3; +static const int16_t ivas_spar_dec_plc_max_num_frames_ramp_down = 33; +static const int16_t ivas_spar_dec_plc_spatial_target[IVAS_SPAR_MAX_CH] = { 1, 0, 0, 0, 0, 0, 0, 0 }; + + +/*------------------------------------------------------------------------------------------* + * Static functions declaration + *------------------------------------------------------------------------------------------*/ + +static void ivas_get_spar_matrices( ivas_spar_md_dec_state_t *hMdDec, const int16_t num_bands_out, const int16_t n_ts, const int16_t bw, const int16_t dtx_vad, const int16_t nB, const int16_t numch_out, const int16_t active_w_vlbr, const int16_t dyn_active_w_flag ); + +static void ivas_decode_arith_bs( ivas_spar_md_dec_state_t *hMdDec, Decoder_State *st, const uint16_t qsi, const int16_t nB, const int16_t bands_bw, int16_t *pDo_diff, const int16_t strat, const int32_t ivas_total_brate ); + +static void ivas_decode_huffman_bs( ivas_spar_md_dec_state_t *hMdDec, Decoder_State *st, const uint16_t qsi, const int16_t nB, const int16_t bands_bw ); + +static void ivas_fill_band_coeffs_idx( ivas_band_coeffs_ind_t *pBands_idx, const int16_t nB, int16_t *pSymbol_re, ivas_cell_dim_t *pCell_dims, ivas_coeffs_type_t coeff_type ); + +static void ivas_mat_col_rearrange( float in_re[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH], const int16_t order[IVAS_SPAR_MAX_CH], const int16_t i_ts, float ***mixer_mat, const int16_t bands, const int16_t num_ch ); + +static void ivas_spar_dec_compute_ramp_down_post_matrix( ivas_spar_md_dec_state_t *hMdDec, const int16_t num_bands, const int16_t bfi, const int16_t num_md_sub_frames ); + +static void ivas_spar_md_fill_invalid_bands( ivas_spar_dec_matrices_t *pSpar_coeffs, ivas_spar_dec_matrices_t *pSpar_coeffs_prev, const int16_t *valid_bands, int16_t *base_band_age, const int16_t num_bands, const int16_t numch_out, const int16_t num_md_sub_frames ); + +static void ivas_spar_md_fill_invalid_bandcoeffs( ivas_band_coeffs_t *pBand_coeffs, ivas_band_coeffs_t *pBand_coeffs_prev, const int16_t *valid_bands, int16_t *base_band_age, int16_t *first_valid_frame, const int16_t num_bands ); +static ivas_error ivas_spar_set_dec_config( ivas_spar_md_dec_state_t *hMdDec, const int16_t nchan_transport, float *pFC ); + +static void ivas_parse_parameter_bitstream_dtx( ivas_spar_md_t *pSpar_md, Decoder_State *st, const int16_t bw, const int16_t num_bands, int16_t *num_dmx_per_band, int16_t *num_dec_per_band ); + +static ivas_error ivas_deindex_real_index( const int16_t *index, const int16_t q_levels, const float min_value, const float max_value, float *quant, const int16_t num_ch_dim2 ); + +static void ivas_spar_dec_parse_md_bs( ivas_spar_md_dec_state_t *hMdDec, Decoder_State *st, int16_t *nB, int16_t *bands_bw, int16_t *dtx_vad, const int32_t ivas_total_brate, const int16_t sba_inactive_mode +); + + +/*------------------------------------------------------------------------- + * ivas_spar_md_dec_matrix_open() + * + * Allocate and initialize SPAR MD decoder matrices + *------------------------------------------------------------------------*/ + +ivas_error ivas_spar_md_dec_matrix_open( + ivas_spar_md_dec_state_t *hMdDec, /* i/o: SPAR MD decoder handle */ + const int16_t num_channels, /* i : number of internal channels */ + const int16_t num_md_sub_frames /* i : number of MD subframes */ +) +{ + int16_t i, j; + int16_t k; + if ( ( hMdDec->spar_md.band_coeffs = (ivas_band_coeffs_t *) malloc( IVAS_MAX_NUM_BANDS * num_md_sub_frames * sizeof( ivas_band_coeffs_t ) ) ) == NULL ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for band_coeffs in SPAR MD" ); + } + if ( ( hMdDec->band_coeffs_prev = (ivas_band_coeffs_t *) malloc( IVAS_MAX_NUM_BANDS * sizeof( ivas_band_coeffs_t ) ) ) == NULL ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for band_coeffs in SPAR MD" ); + } + if ( ( hMdDec->mixer_mat = (float ***) malloc( num_channels * sizeof( float ** ) ) ) == NULL ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for SPAR MD matrix" ); + } + for ( i = 0; i < num_channels; i++ ) + { + if ( ( hMdDec->mixer_mat[i] = (float **) malloc( num_channels * sizeof( float * ) ) ) == NULL ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for SPAR MD matrix" ); + } + for ( j = 0; j < num_channels; j++ ) + { + if ( ( hMdDec->mixer_mat[i][j] = (float *) malloc( num_md_sub_frames * IVAS_MAX_NUM_BANDS * sizeof( float ) ) ) == NULL ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for SPAR MD matrix" ); + } + } + } + + if ( ( hMdDec->spar_coeffs.C_re = (float ***) malloc( num_channels * sizeof( float ** ) ) ) == NULL ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for SPAR MD matrix" ); + } + for ( i = 0; i < num_channels; i++ ) + { + if ( ( hMdDec->spar_coeffs.C_re[i] = (float **) malloc( num_channels * sizeof( float * ) ) ) == NULL ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for SPAR MD matrix" ); + } + for ( j = 0; j < num_channels; j++ ) + { + if ( ( hMdDec->spar_coeffs.C_re[i][j] = (float *) malloc( num_md_sub_frames * IVAS_MAX_NUM_BANDS * sizeof( float ) ) ) == NULL ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for SPAR MD matrix" ); + } + } + } + + if ( ( hMdDec->spar_coeffs.P_re = (float ***) malloc( num_channels * sizeof( float ** ) ) ) == NULL ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for SPAR MD matrix" ); + } + for ( i = 0; i < num_channels; i++ ) + { + if ( ( hMdDec->spar_coeffs.P_re[i] = (float **) malloc( num_channels * sizeof( float * ) ) ) == NULL ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for SPAR MD matrix" ); + } + for ( j = 0; j < num_channels; j++ ) + { + if ( ( hMdDec->spar_coeffs.P_re[i][j] = (float *) malloc( num_md_sub_frames * IVAS_MAX_NUM_BANDS * sizeof( float ) ) ) == NULL ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for SPAR MD matrix" ); + } + } + } + + if ( ( hMdDec->spar_coeffs_prev.C_re = (float ***) malloc( num_channels * sizeof( float ** ) ) ) == NULL ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for SPAR MD matrix" ); + } + for ( i = 0; i < num_channels; i++ ) + { + if ( ( hMdDec->spar_coeffs_prev.C_re[i] = (float **) malloc( num_channels * sizeof( float * ) ) ) == NULL ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for SPAR MD matrix" ); + } + for ( j = 0; j < num_channels; j++ ) + { + if ( ( hMdDec->spar_coeffs_prev.C_re[i][j] = (float *) malloc( IVAS_MAX_NUM_BANDS * sizeof( float ) ) ) == NULL ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for SPAR MD matrix" ); + } + } + } + + if ( ( hMdDec->spar_coeffs_prev.P_re = (float ***) malloc( num_channels * sizeof( float ** ) ) ) == NULL ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for SPAR MD matrix" ); + } + for ( i = 0; i < num_channels; i++ ) + { + if ( ( hMdDec->spar_coeffs_prev.P_re[i] = (float **) malloc( num_channels * sizeof( float * ) ) ) == NULL ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for SPAR MD matrix" ); + } + for ( j = 0; j < num_channels; j++ ) + { + if ( ( hMdDec->spar_coeffs_prev.P_re[i][j] = (float *) malloc( IVAS_MAX_NUM_BANDS * sizeof( float ) ) ) == NULL ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for SPAR MD matrix" ); + } + } + } + + if ( ( hMdDec->spar_coeffs_tar.C_re = (float ***) malloc( num_channels * sizeof( float ** ) ) ) == NULL ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for SPAR MD matrix" ); + } + for ( i = 0; i < num_channels; i++ ) + { + if ( ( hMdDec->spar_coeffs_tar.C_re[i] = (float **) malloc( num_channels * sizeof( float * ) ) ) == NULL ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for SPAR MD matrix" ); + } + for ( j = 0; j < num_channels; j++ ) + { + if ( ( hMdDec->spar_coeffs_tar.C_re[i][j] = (float *) malloc( IVAS_MAX_NUM_BANDS * sizeof( float ) ) ) == NULL ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for SPAR MD matrix" ); + } + } + } + + if ( ( hMdDec->spar_coeffs_tar.P_re = (float ***) malloc( num_channels * sizeof( float ** ) ) ) == NULL ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for SPAR MD matrix" ); + } + for ( i = 0; i < num_channels; i++ ) + { + if ( ( hMdDec->spar_coeffs_tar.P_re[i] = (float **) malloc( num_channels * sizeof( float * ) ) ) == NULL ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for SPAR MD matrix" ); + } + for ( j = 0; j < num_channels; j++ ) + { + if ( ( hMdDec->spar_coeffs_tar.P_re[i][j] = (float *) malloc( IVAS_MAX_NUM_BANDS * sizeof( float ) ) ) == NULL ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for SPAR MD matrix" ); + } + } + } + for ( i = 0; i < num_channels; i++ ) + { + for ( j = 0; j < num_channels; j++ ) + { + for ( k = 0; k < IVAS_MAX_NUM_BANDS; k++ ) + { + hMdDec->spar_coeffs_prev.C_re[i][j][k] = 0.0f; + hMdDec->spar_coeffs_prev.P_re[i][j][k] = 0.0f; + hMdDec->spar_coeffs_tar.C_re[i][j][k] = 0.0f; + hMdDec->spar_coeffs_tar.P_re[i][j][k] = 0.0f; + } + } + } + + return IVAS_ERR_OK; +} + + +/*------------------------------------------------------------------------- + * ivas_get_spar_dec_md_num_subframes() + * + * return number of MD subframes + *------------------------------------------------------------------------*/ + +/*! r: number of MD subframes */ +int16_t ivas_get_spar_dec_md_num_subframes( + const int16_t sba_order, /* i : Ambisonic (SBA) order */ + const int32_t ivas_total_brate, /* i : IVAS total bitrate */ + const int32_t ivas_last_active_brate /* i : IVAS last active bitrate */ +) +{ + int16_t num_subframes; + + num_subframes = MAX_PARAM_SPATIAL_SUBFRAMES; + if ( sba_order > SBA_FOA_ORDER ) + { + if ( ivas_total_brate >= IVAS_512k ) + { + num_subframes = 1; + } + } + + if ( ( ivas_total_brate <= IVAS_SID_5k2 && ivas_last_active_brate < IVAS_24k4 ) || ( ivas_total_brate > IVAS_SID_5k2 && ivas_total_brate < IVAS_24k4 ) ) + { + + num_subframes = 1; + } + + return ( num_subframes ); +} + + +/*------------------------------------------------------------------------- + * ivas_spar_md_dec_open() + * + * Allocate and initialize SPAR MD decoder handle + *------------------------------------------------------------------------*/ + +ivas_error ivas_spar_md_dec_open( + ivas_spar_md_dec_state_t **hMdDec_out, /* i/o: SPAR MD decoder handle */ + const DECODER_CONFIG_HANDLE hDecoderConfig, /* i : configuration structure */ + const int16_t num_channels, /* i : number of internal channels */ + const int16_t sba_order, /* i : SBA order */ + const int16_t sid_format, /* i : SID format */ + const int32_t last_active_ivas_total_brate /* i : IVAS last active bitrate */ +) +{ + ivas_spar_md_dec_state_t *hMdDec; + ivas_error error; + int16_t num_md_sub_frames; + + error = IVAS_ERR_OK; + + if ( ( hMdDec = (ivas_spar_md_dec_state_t *) malloc( sizeof( ivas_spar_md_dec_state_t ) ) ) == NULL ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for SPAR MD decoder" ); + } + + num_md_sub_frames = ivas_get_spar_dec_md_num_subframes( sba_order, hDecoderConfig->ivas_total_brate, last_active_ivas_total_brate ); + + if ( ( error = ivas_spar_md_dec_matrix_open( hMdDec, num_channels, num_md_sub_frames ) ) != IVAS_ERR_OK ) + { + return error; + } + + if ( hDecoderConfig->ivas_total_brate == IVAS_SID_5k2 ) + { + if ( sid_format == SID_SBA_2TC ) + { + hMdDec->table_idx = ivas_get_spar_table_idx( IVAS_48k, sba_order, SPAR_CONFIG_BW, NULL, NULL ); + } + else + { + hMdDec->table_idx = ivas_get_spar_table_idx( IVAS_24k4, sba_order, SPAR_CONFIG_BW, NULL, NULL ); + } + } + else + { + hMdDec->table_idx = ivas_get_spar_table_idx( hDecoderConfig->ivas_total_brate, sba_order, SPAR_CONFIG_BW, NULL, NULL ); + } + + if ( ( error = ivas_spar_md_dec_init( hMdDec, hDecoderConfig, num_channels, sba_order ) ) != IVAS_ERR_OK ) + { + return error; + } + + *hMdDec_out = hMdDec; + + return error; +} + + +/*------------------------------------------------------------------------- + * ivas_spar_md_dec_matrix_close() + * + * Deallocate SPAR MD decoder matrices + *------------------------------------------------------------------------*/ + +void ivas_spar_md_dec_matrix_close( + ivas_spar_md_dec_state_t *hMdDecoder, /* i/o: SPAR MD decoder handle */ + const int16_t num_channels /* i : number of internal channels */ +) +{ + int16_t i, j; + + if ( hMdDecoder->spar_md.band_coeffs != NULL ) + { + free( hMdDecoder->spar_md.band_coeffs ); + hMdDecoder->spar_md.band_coeffs = NULL; + } + if ( hMdDecoder->band_coeffs_prev != NULL ) + { + free( hMdDecoder->band_coeffs_prev ); + hMdDecoder->band_coeffs_prev = NULL; + } + + if ( hMdDecoder->mixer_mat != NULL ) + { + for ( i = 0; i < num_channels; i++ ) + { + for ( j = 0; j < num_channels; j++ ) + { + free( hMdDecoder->mixer_mat[i][j] ); + } + free( hMdDecoder->mixer_mat[i] ); + } + free( hMdDecoder->mixer_mat ); + } + + if ( hMdDecoder->spar_coeffs.C_re != NULL ) + { + for ( i = 0; i < num_channels; i++ ) + { + for ( j = 0; j < num_channels; j++ ) + { + free( hMdDecoder->spar_coeffs.C_re[i][j] ); + } + free( hMdDecoder->spar_coeffs.C_re[i] ); + } + free( hMdDecoder->spar_coeffs.C_re ); + } + + if ( hMdDecoder->spar_coeffs.P_re != NULL ) + { + for ( i = 0; i < num_channels; i++ ) + { + for ( j = 0; j < num_channels; j++ ) + { + free( hMdDecoder->spar_coeffs.P_re[i][j] ); + } + free( hMdDecoder->spar_coeffs.P_re[i] ); + } + free( hMdDecoder->spar_coeffs.P_re ); + } + + if ( hMdDecoder->spar_coeffs_prev.C_re != NULL ) + { + for ( i = 0; i < num_channels; i++ ) + { + for ( j = 0; j < num_channels; j++ ) + { + free( hMdDecoder->spar_coeffs_prev.C_re[i][j] ); + } + free( hMdDecoder->spar_coeffs_prev.C_re[i] ); + } + free( hMdDecoder->spar_coeffs_prev.C_re ); + } + + if ( hMdDecoder->spar_coeffs_prev.P_re != NULL ) + { + for ( i = 0; i < num_channels; i++ ) + { + for ( j = 0; j < num_channels; j++ ) + { + free( hMdDecoder->spar_coeffs_prev.P_re[i][j] ); + } + free( hMdDecoder->spar_coeffs_prev.P_re[i] ); + } + free( hMdDecoder->spar_coeffs_prev.P_re ); + } + + if ( hMdDecoder->spar_coeffs_tar.C_re != NULL ) + { + for ( i = 0; i < num_channels; i++ ) + { + for ( j = 0; j < num_channels; j++ ) + { + free( hMdDecoder->spar_coeffs_tar.C_re[i][j] ); + } + free( hMdDecoder->spar_coeffs_tar.C_re[i] ); + } + free( hMdDecoder->spar_coeffs_tar.C_re ); + } + + if ( hMdDecoder->spar_coeffs_tar.P_re != NULL ) + { + for ( i = 0; i < num_channels; i++ ) + { + for ( j = 0; j < num_channels; j++ ) + { + free( hMdDecoder->spar_coeffs_tar.P_re[i][j] ); + } + free( hMdDecoder->spar_coeffs_tar.P_re[i] ); + } + free( hMdDecoder->spar_coeffs_tar.P_re ); + } + + return; +} + + +/*------------------------------------------------------------------------- + * ivas_spar_md_dec_close() + * + * Deallocate SPAR MD decoder handle + *------------------------------------------------------------------------*/ + +void ivas_spar_md_dec_close( + ivas_spar_md_dec_state_t **hMdDec /* i/o: SPAR MD decoder handle */ +) +{ + ivas_spar_md_dec_state_t *hMdDecoder; + int16_t num_channels; + + hMdDecoder = *hMdDec; + num_channels = hMdDecoder->spar_md_cfg.num_umx_chs; + + ivas_spar_md_dec_matrix_close( hMdDecoder, num_channels ); + + free( *hMdDec ); + *hMdDec = NULL; + + return; +} + + +/*-----------------------------------------------------------------------------------------* + * Function ivas_spar_md_dec_init() + * + * SPAR MD decoder initialization + *-----------------------------------------------------------------------------------------*/ + +ivas_error ivas_spar_md_dec_init( + ivas_spar_md_dec_state_t *hMdDec, /* i/o: SPAR MD decoder handle */ + const DECODER_CONFIG_HANDLE hDecoderConfig, /* i : configuration structure */ + const int16_t num_channels, /* i : number of internal channels */ + const int16_t sba_order /* i : SBA order */ +) +{ + int16_t i, j; + int16_t nchan_transport; + float pFC[IVAS_MAX_NUM_BANDS], PR_minmax[2]; + ivas_error error; + + ivas_sba_get_spar_hoa_md_flag( sba_order, hDecoderConfig->ivas_total_brate, &hMdDec->spar_hoa_md_flag, &hMdDec->spar_hoa_dirac2spar_md_flag ); + + ivas_sba_get_spar_hoa_ch_ind( num_channels, hDecoderConfig->ivas_total_brate, hMdDec->HOA_md_ind ); + + hMdDec->spar_md.num_bands = ( hMdDec->spar_hoa_md_flag ) ? IVAS_MAX_NUM_BANDS : min( IVAS_MAX_NUM_BANDS, SPAR_DIRAC_SPLIT_START_BAND ); + + ivas_spar_set_bitrate_config( &hMdDec->spar_md_cfg, hMdDec->table_idx, hMdDec->spar_md.num_bands, hMdDec->spar_hoa_dirac2spar_md_flag, 0, 0, 0 ); + + nchan_transport = hMdDec->spar_md_cfg.nchan_transport; + + /* get FB coefficients */ + for ( i = 0; i < IVAS_MAX_NUM_BANDS; i++ ) + { + pFC[i] = ivas_fb_fcs_12band_1ms[i] * hDecoderConfig->output_Fs * 0.5f; + } + + if ( ( error = ivas_spar_set_dec_config( hMdDec, nchan_transport, pFC ) ) != IVAS_ERR_OK ) + { + return error; + } + + if ( nchan_transport != 2 && ( ( hMdDec->spar_md_cfg.remix_unmix_order == 2 ) || ( hMdDec->spar_md_cfg.remix_unmix_order == 1 ) ) ) + { + return IVAS_ERR_INTERNAL; + } + + /* DTX quant init */ + PR_minmax[0] = hMdDec->spar_md_cfg.quant_strat[0].PR.min; + PR_minmax[1] = hMdDec->spar_md_cfg.quant_strat[0].PR.max; + ivas_spar_quant_dtx_init( &hMdDec->spar_md, PR_minmax ); + + ivas_spar_arith_coeffs_com_init( &hMdDec->arith_coeffs, &hMdDec->spar_md_cfg, hMdDec->table_idx, DEC ); + ivas_spar_huff_coeffs_com_init( &hMdDec->huff_coeffs, &hMdDec->spar_md_cfg, hMdDec->table_idx, DEC ); + + hMdDec->spar_md_cfg.prev_quant_idx = -1; + + /* initialize PLC state */ + set_s( hMdDec->valid_bands, 0, IVAS_MAX_NUM_BANDS ); + set_s( hMdDec->base_band_age, 0, IVAS_MAX_NUM_BANDS ); + set_s( hMdDec->base_band_coeffs_age, 0, IVAS_MAX_NUM_BANDS ); + hMdDec->spar_plc_num_lost_frames = 0; + hMdDec->spar_plc_enable_fadeout_flag = 1; + hMdDec->dtx_md_smoothing_cntr = 1; + + ivas_clear_band_coeffs( hMdDec->spar_md.band_coeffs, IVAS_MAX_NUM_BANDS ); + ivas_clear_band_coeffs( hMdDec->band_coeffs_prev, IVAS_MAX_NUM_BANDS ); + ivas_clear_band_coeff_idx( hMdDec->spar_md.band_coeffs_idx, IVAS_MAX_NUM_BANDS ); + ivas_clear_band_coeff_idx( hMdDec->spar_md_prev.band_coeffs_idx, IVAS_MAX_NUM_BANDS ); + ivas_clear_band_coeff_idx( hMdDec->spar_md_prev.band_coeffs_idx_mapped, IVAS_MAX_NUM_BANDS ); + + hMdDec->spar_md.dtx_vad = 0; + hMdDec->td_decorr_flag = 1; + + set_f( hMdDec->spar_md.en_ratio_slow, 0.0f, IVAS_MAX_NUM_BANDS ); + set_f( hMdDec->spar_md.ref_pow_slow, 0.0f, IVAS_MAX_NUM_BANDS ); + + set_zero( hMdDec->smooth_fac, IVAS_MAX_NUM_BANDS ); + for ( i = 0; i < IVAS_MAX_NUM_BANDS; i++ ) + { + set_zero( hMdDec->smooth_buf[i], 2 * SBA_DIRAC_NRG_SMOOTH_LONG + 1 ); + } + + for ( i = 0; i < IVAS_SPAR_MAX_CH; i++ ) + { + for ( j = 0; j < IVAS_SPAR_MAX_CH; j++ ) + { + set_zero( hMdDec->mixer_mat_prev2[i][j], IVAS_MAX_NUM_BANDS ); + } + } + hMdDec->first_valid_frame = 1; + + return IVAS_ERR_OK; +} + + +/*-----------------------------------------------------------------------------------------* + * Function ivas_spar_set_dec_config() + * + * Set configuration for SPAR MD decoder + *-----------------------------------------------------------------------------------------*/ + +static ivas_error ivas_spar_set_dec_config( + ivas_spar_md_dec_state_t *hMdDec, + const int16_t nchan_transport, + float *pFC ) +{ + int16_t i, j, nchan, dmx_ch; + + for ( i = 0; i < nchan_transport; i++ ) + { + hMdDec->spar_md_cfg.max_freq_per_chan[i] = ivas_spar_br_table_consts[hMdDec->table_idx].fpcs; + } + + nchan = ivas_sba_get_nchan_metadata( ivas_spar_br_table_consts[hMdDec->table_idx].sba_order, ivas_spar_br_table_consts[hMdDec->table_idx].ivas_total_brate ); + + switch ( nchan ) + { + case 4: /* FOA_CHANNELS */ + hMdDec->num_decorr = IVAS_TD_DECORR_OUT_3CH; + break; + case 9: /* IVAS_HOA_2_CH */ + hMdDec->num_decorr = IVAS_TD_DECORR_OUT_5CH; + break; + case 6: /* IVAS_HOA_2_CH */ + hMdDec->num_decorr = IVAS_TD_DECORR_OUT_2CH; + break; + case 8: /* IVAS_HOA_3_CH */ + hMdDec->num_decorr = IVAS_TD_DECORR_OUT_4CH; + break; + } + + hMdDec->spar_md_cfg.num_umx_chs = nchan; + + dmx_ch = 0; + for ( i = 0; i < IVAS_MAX_NUM_BANDS; i++ ) + { + dmx_ch = 0; + for ( j = 0; j < nchan_transport; j++ ) + { + if ( pFC[i] < hMdDec->spar_md_cfg.max_freq_per_chan[j] ) + { + dmx_ch += 1; + } + } + + hMdDec->spar_md_cfg.num_dmx_chans_per_band[i] = hMdDec->spar_md_cfg.nchan_transport; + hMdDec->spar_md_cfg.num_decorr_per_band[i] = nchan - hMdDec->spar_md_cfg.nchan_transport; + } + + hMdDec->spar_md_cfg.nchan_transport = dmx_ch; + + return IVAS_ERR_OK; +} + + +/*-----------------------------------------------------------------------------------------* + * Function ivas_dec_mono_sba_handling() + * + * + *-----------------------------------------------------------------------------------------*/ + +static void ivas_dec_mono_sba_handling( + Decoder_Struct *st_ivas /* i/o: IVAS decoder handle */ +) +{ + int16_t mono_flag, b, block; + + mono_flag = 1; + + for ( b = 0; b < st_ivas->hQMetaData->q_direction[0].cfg.nbands; b++ ) + { + for ( block = 0; block < MAX_PARAM_SPATIAL_SUBFRAMES; ++block ) + { + float azimuth = st_ivas->hQMetaData->q_direction[0].band_data[b].azimuth[block]; + float elevation = st_ivas->hQMetaData->q_direction[0].band_data[b].azimuth[block]; + float energy_ratio = st_ivas->hQMetaData->q_direction[0].band_data[0].energy_ratio[block]; + if ( + ( azimuth != 0.0f ) || + ( elevation != 0.0f ) || + ( energy_ratio > 0.15f ) ) /* 0.15f is just above the lowest quantised value. */ + { + mono_flag = 0; + } + } + } + + /* Combine the SPAR prediction coefs flag with the azimuth, elevation and energy ratio flag.*/ + mono_flag = mono_flag && ivas_spar_chk_zero_coefs( st_ivas ); + + if ( mono_flag ) + { + /* Set Energy Ratio values to be zero */ + for ( b = 0; b < st_ivas->hQMetaData->q_direction[0].cfg.nbands; b++ ) + { + set_zero( st_ivas->hQMetaData->q_direction[0].band_data[b].energy_ratio, MAX_PARAM_SPATIAL_SUBFRAMES ); + } + if ( st_ivas->hDirAC != NULL ) + { + for ( block = 0; block < st_ivas->hSpatParamRendCom->dirac_md_buffer_length; ++block ) + { + /* Set directional Energy Ratio values to be zero */ + set_zero( st_ivas->hSpatParamRendCom->energy_ratio1[block], st_ivas->hSpatParamRendCom->num_freq_bands ); + if ( st_ivas->hQMetaData->no_directions == 2 ) + { + set_zero( st_ivas->hSpatParamRendCom->energy_ratio2[block], st_ivas->hSpatParamRendCom->num_freq_bands ); + } + /* Set Diffuseness values to be 1.0 */ + set_f( st_ivas->hSpatParamRendCom->diffuseness_vector[block], 1.0f, st_ivas->hSpatParamRendCom->num_freq_bands ); + } + } + } + + return; +} + + +/*-----------------------------------------------------------------------------------------* + * Function ivas_spar_md_dec_process() + * + * SPAR Meta Data decoder process + *-----------------------------------------------------------------------------------------*/ + +void ivas_spar_md_dec_process( + Decoder_Struct *st_ivas, /* i/o: IVAS decoder handle */ + Decoder_State *st0, /* i/o: decoder state structure - for bitstream handling */ + const int16_t num_bands_out, /* i : number of output bands */ + const int16_t sba_order /* i : Ambisonic (SBA) order */ +) +{ + int16_t j, k, b, bw, dtx_vad, nB, i_ts; + ivas_spar_md_dec_state_t *hMdDec; + int16_t num_md_chs; + int16_t num_md_sub_frames; + int16_t dyn_active_w_flag; + int16_t active_w_vlbr; + + hMdDec = st_ivas->hSpar->hMdDec; + + active_w_vlbr = ( st_ivas->hDecoderConfig->ivas_total_brate < IVAS_24k4 ) ? 1 : 0; + + num_md_chs = ivas_sba_get_nchan_metadata( sba_order, st_ivas->hDecoderConfig->ivas_total_brate ); + + num_md_sub_frames = ivas_get_spar_dec_md_num_subframes( sba_order, st_ivas->hDecoderConfig->ivas_total_brate, st_ivas->last_active_ivas_total_brate ); + + if ( hMdDec->spar_md_cfg.nchan_transport > 1 && hMdDec->spar_md_cfg.nchan_transport <= 3 ) + { + hMdDec->spar_md.res_ind = 0; + dyn_active_w_flag = get_next_indice( st0, 1 ); + if ( dyn_active_w_flag == 1 ) + { + if ( hMdDec->spar_md_cfg.nchan_transport == 2 ) + { + hMdDec->spar_md.res_ind = get_next_indice( st0, 1 ); + hMdDec->spar_md.res_ind += hMdDec->spar_md_cfg.nchan_transport; + } + else if ( hMdDec->spar_md_cfg.nchan_transport == 3 ) + { + hMdDec->spar_md.res_ind = remix_order_set[hMdDec->spar_md_cfg.remix_unmix_order][hMdDec->spar_md_cfg.nchan_transport]; + } + } + } + else + { + dyn_active_w_flag = 0; + if ( hMdDec->spar_md_cfg.nchan_transport == FOA_CHANNELS ) + { + get_next_indice( st0, 1 ); + } + } + + ivas_spar_dec_parse_md_bs( hMdDec, st0, &nB, &bw, &dtx_vad, st_ivas->hDecoderConfig->ivas_total_brate, + st_ivas->hQMetaData->sba_inactive_mode + ); + + assert( nB == hMdDec->spar_md.num_bands ); + assert( bw == 1 ); + ivas_spar_md_fill_invalid_bandcoeffs( + hMdDec->spar_md.band_coeffs, + hMdDec->band_coeffs_prev, + &hMdDec->valid_bands[0], + &hMdDec->base_band_coeffs_age[0], + &hMdDec->first_valid_frame, + nB ); + + ivas_dec_mono_sba_handling( st_ivas ); + + /* SPAR to DirAC conversion */ + if ( hMdDec->spar_hoa_dirac2spar_md_flag == 1 ) + { + ivas_spar_to_dirac( st_ivas, hMdDec, dtx_vad, num_bands_out, bw, dyn_active_w_flag ); + } + + /* set correct number of bands*/ + nB = IVAS_MAX_NUM_BANDS; + + /* expand DirAC MD to all time slots */ + for ( i_ts = 1; i_ts < num_md_sub_frames; i_ts++ ) + { + for ( b = 0; b < hMdDec->spar_md.num_bands; b++ ) + { + for ( j = 0; j < IVAS_SPAR_MAX_CH - 1; j++ ) + { + hMdDec->spar_md.band_coeffs[b + i_ts * IVAS_MAX_NUM_BANDS].pred_re[j] = hMdDec->spar_md.band_coeffs[b].pred_re[j]; + } + + for ( j = 0; j < IVAS_SPAR_MAX_CH - IVAS_SPAR_MAX_DMX_CHS; j++ ) + { + for ( k = 0; k < IVAS_SPAR_MAX_DMX_CHS - 1; k++ ) + { + hMdDec->spar_md.band_coeffs[b + i_ts * IVAS_MAX_NUM_BANDS].C_re[j][k] = hMdDec->spar_md.band_coeffs[b].C_re[j][k]; + } + } + + for ( j = 0; j < IVAS_SPAR_MAX_CH - 1; j++ ) + { + hMdDec->spar_md.band_coeffs[b + i_ts * IVAS_MAX_NUM_BANDS].P_re[j] = hMdDec->spar_md.band_coeffs[b].P_re[j]; + } + } + } + + ivas_get_spar_matrices( hMdDec, num_bands_out, num_md_sub_frames, bw, dtx_vad, nB, num_md_chs, active_w_vlbr, dyn_active_w_flag ); + +#ifdef DEBUG_SPAR_DIRAC_WRITE_OUT_PRED_PARS + { + static FILE *fid = 0; + int16_t band = 9; + if ( !fid ) + { + fid = fopen( "pred_coeffs_dec.txt", "wt" ); + } + fprintf( fid, "%.6f\n", hMdDec->mixer_mat[1][0][band] ); + } +#endif + ivas_spar_md_fill_invalid_bands( &hMdDec->spar_coeffs, &hMdDec->spar_coeffs_prev, &hMdDec->valid_bands[0], &hMdDec->base_band_age[0], num_bands_out, num_md_chs, num_md_sub_frames ); + + + hMdDec->dtx_md_smoothing_cntr = 1; + + return; +} + + +/*-----------------------------------------------------------------------------------------* + * Function ivas_spar_chk_zero_coefs() + * + * Check for zeroed SPAR coefficients + *-----------------------------------------------------------------------------------------*/ + +int16_t ivas_spar_chk_zero_coefs( + Decoder_Struct *st_ivas /* i/o: IVAS decoder handle */ +) +{ + int16_t j, k, b; + ivas_spar_md_dec_state_t *hMdDec; + int16_t mono = 1; + int16_t ndec, ndm; + + hMdDec = st_ivas->hSpar->hMdDec; + ndec = hMdDec->spar_md_cfg.num_decorr_per_band[0]; + ndm = hMdDec->spar_md_cfg.num_dmx_chans_per_band[0]; + + for ( b = 0; b < min( hMdDec->spar_md.num_bands, SPAR_DIRAC_SPLIT_START_BAND ); b++ ) + { + for ( j = 0; j < ndm + ndec - 1; j++ ) + { + if ( hMdDec->spar_md.band_coeffs[b].pred_re[j] != 0.0f ) + { + mono = 0; + } + } + for ( j = 0; j < ndec; j++ ) + { + for ( k = 0; k < ndm - 1; k++ ) + { + if ( hMdDec->spar_md.band_coeffs[b].C_re[j][k] != 0.0f ) + { + mono = 0; + } + } + } + for ( j = 0; j < ndec; j++ ) + { + if ( hMdDec->spar_md.band_coeffs[b].P_re[j] != 0.0f ) + { + mono = 0; + } + } + } + + return mono; +} + + +/*-----------------------------------------------------------------------------------------* + * Function ivas_spar_smooth_md_dtx() + * + * Smooth MD during no data frame during DTX + *-----------------------------------------------------------------------------------------*/ + +void ivas_spar_smooth_md_dtx( + ivas_spar_md_dec_state_t *hMdDec, /* i/o: SPAR MD decoder handle */ + const int16_t num_bands_out, /* i : number of output bands */ + const int16_t num_md_sub_frames /* i : number of metadata subframes */ +) +{ + int16_t j, k, b, dmx_ch; + float ramp, tar, prev, new_val; + + ramp = (float) hMdDec->dtx_md_smoothing_cntr / IVAS_DEFAULT_DTX_CNG_RAMP; + + for ( b = 0; b < num_bands_out; b++ ) + { + dmx_ch = hMdDec->spar_md_cfg.num_dmx_chans_per_band[b]; + + for ( j = 1; j < FOA_CHANNELS; j++ ) + { + for ( k = dmx_ch; k < FOA_CHANNELS; k++ ) + { + prev = hMdDec->spar_coeffs_prev.P_re[j][k][b]; + tar = hMdDec->spar_coeffs_tar.P_re[j][k][b]; + new_val = prev + ( ramp * ( tar - prev ) ); + hMdDec->spar_coeffs.P_re[j][k][b] = new_val; + } + } + + for ( j = 0; j < FOA_CHANNELS; j++ ) + { + for ( k = 0; k < dmx_ch; k++ ) + { + prev = hMdDec->spar_coeffs_prev.C_re[j][k][b]; + tar = hMdDec->spar_coeffs_tar.C_re[j][k][b]; + new_val = prev + ( ramp * ( tar - prev ) ); + hMdDec->spar_coeffs.C_re[j][k][b] = new_val; + } + } + } + + /* expand MD to all time slots */ + for ( int16_t i_ts = 1; i_ts < num_md_sub_frames; i_ts++ ) + { + for ( b = 0; b < num_bands_out; b++ ) + { + dmx_ch = hMdDec->spar_md_cfg.num_dmx_chans_per_band[b]; + + for ( j = 1; j < FOA_CHANNELS; j++ ) + { + for ( k = dmx_ch; k < FOA_CHANNELS; k++ ) + + { + hMdDec->spar_coeffs.P_re[j][k][b + i_ts * IVAS_MAX_NUM_BANDS] = hMdDec->spar_coeffs.P_re[j][k][b]; + } + } + + for ( j = 0; j < FOA_CHANNELS; j++ ) + { + for ( k = 0; k < dmx_ch; k++ ) + { + hMdDec->spar_coeffs.C_re[j][k][b + i_ts * IVAS_MAX_NUM_BANDS] = hMdDec->spar_coeffs.C_re[j][k][b]; + } + } + } + } + + hMdDec->dtx_md_smoothing_cntr = min( hMdDec->dtx_md_smoothing_cntr + 1, IVAS_DEFAULT_DTX_CNG_RAMP ); + + return; +} + + +/*-----------------------------------------------------------------------------------------* + * Function ivas_spar_setup_md_smoothing() + * + * Set up smoothing of SPAR MD when SID update frame is received + *-----------------------------------------------------------------------------------------*/ + +void ivas_spar_setup_md_smoothing( + ivas_spar_md_dec_state_t *hMdDec, /* i/o: SPAR MD decoder handle */ + const int16_t num_bands_out, /* i : number of output bands */ + const int16_t num_md_sub_frames /* i : number of metadata subframes */ +) +{ + /* copy the coeffs */ + int16_t num_channels, i, j, k; + + num_channels = hMdDec->spar_md_cfg.num_umx_chs; + + for ( i = 0; i < num_channels; i++ ) + { + for ( j = 0; j < num_channels; j++ ) + { + for ( k = 0; k < IVAS_MAX_NUM_BANDS; k++ ) + { + hMdDec->spar_coeffs_prev.C_re[i][j][k] = hMdDec->spar_coeffs_tar.C_re[i][j][k]; + } + } + } + + for ( i = 0; i < num_channels; i++ ) + { + for ( j = 0; j < num_channels; j++ ) + { + for ( k = 0; k < IVAS_MAX_NUM_BANDS; k++ ) + { + hMdDec->spar_coeffs_prev.P_re[i][j][k] = hMdDec->spar_coeffs_tar.P_re[i][j][k]; + } + } + } + + for ( i = 0; i < num_channels; i++ ) + { + for ( j = 0; j < num_channels; j++ ) + { + for ( k = 0; k < IVAS_MAX_NUM_BANDS; k++ ) + { + hMdDec->spar_coeffs_tar.C_re[i][j][k] = hMdDec->spar_coeffs.C_re[i][j][k]; + } + } + } + + for ( i = 0; i < num_channels; i++ ) + { + for ( j = 0; j < num_channels; j++ ) + { + for ( k = 0; k < IVAS_MAX_NUM_BANDS; k++ ) + { + hMdDec->spar_coeffs_tar.P_re[i][j][k] = hMdDec->spar_coeffs.P_re[i][j][k]; + } + } + } + + ivas_spar_smooth_md_dtx( hMdDec, num_bands_out, num_md_sub_frames ); + + return; +} + + +/*-----------------------------------------------------------------------------------------* + * Function ivas_spar_update_md_hist() + * + * Update previous and target MD + *-----------------------------------------------------------------------------------------*/ + +void ivas_spar_update_md_hist( + ivas_spar_md_dec_state_t *hMdDec /* i/o: SPAR MD decoder handle */ +) +{ + int16_t num_channels, i, j, k; + + num_channels = hMdDec->spar_md_cfg.num_umx_chs; + + for ( i = 0; i < num_channels; i++ ) + { + for ( j = 0; j < num_channels; j++ ) + { + for ( k = 0; k < IVAS_MAX_NUM_BANDS; k++ ) + { + hMdDec->spar_coeffs_prev.C_re[i][j][k] = hMdDec->spar_coeffs.C_re[i][j][k]; + } + } + } + + for ( i = 0; i < num_channels; i++ ) + { + for ( j = 0; j < num_channels; j++ ) + { + for ( k = 0; k < IVAS_MAX_NUM_BANDS; k++ ) + { + hMdDec->spar_coeffs_prev.P_re[i][j][k] = hMdDec->spar_coeffs.P_re[i][j][k]; + } + } + } + + for ( i = 0; i < num_channels; i++ ) + { + for ( j = 0; j < num_channels; j++ ) + { + for ( k = 0; k < IVAS_MAX_NUM_BANDS; k++ ) + { + hMdDec->spar_coeffs_tar.C_re[i][j][k] = hMdDec->spar_coeffs.C_re[i][j][k]; + } + } + } + + for ( i = 0; i < num_channels; i++ ) + { + for ( j = 0; j < num_channels; j++ ) + { + for ( k = 0; k < IVAS_MAX_NUM_BANDS; k++ ) + { + hMdDec->spar_coeffs_tar.P_re[i][j][k] = hMdDec->spar_coeffs.P_re[i][j][k]; + } + } + } + + return; +} + + +/*-----------------------------------------------------------------------------------------* + * Function ivas_get_spar_matrices() + * + * Get SPAR matrices + *-----------------------------------------------------------------------------------------*/ + +static void ivas_get_spar_matrices( + ivas_spar_md_dec_state_t *hMdDec, + const int16_t num_bands_out, + const int16_t n_ts, + const int16_t bw, + const int16_t dtx_vad, + const int16_t nB, + const int16_t numch_out, + const int16_t active_w_vlbr, + const int16_t dyn_active_w_flag ) +{ + int16_t num_bands, dmx_ch, split_band; + int16_t i, j, k, m, b, i_ts, active_w; + const int16_t *order; + float active_w_dm_fac, re; + + + num_bands = num_bands_out; + order = remix_order_set[hMdDec->spar_md_cfg.remix_unmix_order]; + + split_band = SPAR_DIRAC_SPLIT_START_BAND; + if ( split_band >= IVAS_MAX_NUM_BANDS ) + { + /*store previous 4x4 parameters for linear interpolation to current*/ + for ( i = 0; i < numch_out; i++ ) + { + for ( j = 0; j < numch_out; j++ ) + { + for ( b = 0; b < num_bands; b++ ) + { + hMdDec->mixer_mat_prev[0][i][j][b] = hMdDec->mixer_mat[i][j][b]; + } + } + } + } + + if ( bw == IVAS_RED_BAND_FACT ) + { + num_bands = num_bands >> 1; + } + + active_w = ( dyn_active_w_flag == 1 ) || ( hMdDec->spar_md_cfg.active_w == 1 ); + active_w_dm_fac = ( dtx_vad == 0 ) ? IVAS_ACTIVEW_DM_F_SCALE_DTX : ( ( active_w_vlbr ) ? IVAS_ACTIVEW_DM_F_SCALE_VLBR : IVAS_ACTIVEW_DM_F_SCALE ); + + for ( i_ts = 0; i_ts < n_ts; i_ts++ ) + { + for ( i = 0; i < numch_out; i++ ) + { + for ( j = 0; j < numch_out; j++ ) + { + set_zero( &hMdDec->spar_coeffs.C_re[i][j][i_ts * IVAS_MAX_NUM_BANDS], IVAS_MAX_NUM_BANDS ); + set_zero( &hMdDec->spar_coeffs.P_re[i][j][i_ts * IVAS_MAX_NUM_BANDS], IVAS_MAX_NUM_BANDS ); + } + } + num_bands = min( num_bands, nB ); + + for ( b = 0; b < num_bands; b++ ) + { + float tmp_C1_re[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH]; + float tmp_C2_re[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH]; + float tmp_dm_re[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH]; + + dmx_ch = hMdDec->spar_md_cfg.num_dmx_chans_per_band[bw * b]; + + for ( j = 0; j < numch_out; j++ ) + { + set_zero( tmp_C1_re[j], numch_out ); + set_zero( tmp_C2_re[j], numch_out ); + set_zero( tmp_dm_re[j], numch_out ); + + tmp_C1_re[j][j] = 1.0f; + tmp_C2_re[j][j] = 1.0f; + tmp_dm_re[j][j] = 1.0f; + } + + for ( j = 1; j < numch_out; j++ ) + { + tmp_C1_re[j][0] = hMdDec->spar_md.band_coeffs[b + i_ts * IVAS_MAX_NUM_BANDS].pred_re[j - 1]; + } + + if ( active_w == 1 ) + { + for ( j = 1; j < numch_out; j++ ) + { + tmp_C2_re[0][j] = active_w_dm_fac * -hMdDec->spar_md.band_coeffs[b + i_ts * IVAS_MAX_NUM_BANDS].pred_re[j - 1]; + } + + IVAS_RMULT_FLOAT( tmp_C2_re[0][1], tmp_C1_re[1][0], re ); + tmp_dm_re[0][0] = 1 + re; + + IVAS_RMULT_FLOAT( tmp_C2_re[0][2], tmp_C1_re[2][0], re ); + tmp_dm_re[0][0] += re; + + IVAS_RMULT_FLOAT( tmp_C2_re[0][3], tmp_C1_re[3][0], re ); + tmp_dm_re[0][0] += re; + + if ( dyn_active_w_flag == 1 ) + { + tmp_dm_re[0][0] *= IVAS_SPAR_DYN_ACTIVEW_THRESH; + } + + tmp_dm_re[0][1] = tmp_C2_re[0][1]; + + tmp_dm_re[0][2] = tmp_C2_re[0][2]; + + tmp_dm_re[0][3] = tmp_C2_re[0][3]; + + tmp_dm_re[1][0] = tmp_C1_re[1][0]; + + tmp_dm_re[2][0] = tmp_C1_re[2][0]; + + tmp_dm_re[3][0] = tmp_C1_re[3][0]; + + if ( hMdDec->spar_md_cfg.remix_unmix_order != 3 ) + { + ivas_mat_col_rearrange( tmp_dm_re, order, i_ts, hMdDec->mixer_mat, b, numch_out ); + } + } + else + { + if ( hMdDec->spar_md_cfg.remix_unmix_order != 3 ) + { + ivas_mat_col_rearrange( tmp_C1_re, order, i_ts, hMdDec->mixer_mat, b, numch_out ); + } + } + + if ( dmx_ch > 0 ) + { + float tmpC_re[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH]; + float tmpP_re[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH]; + + for ( j = 0; j < numch_out; j++ ) + { + set_zero( tmpC_re[j], numch_out ); + set_zero( tmpP_re[j], numch_out ); + } + + for ( j = 0; j < numch_out; j++ ) + { + set_zero( tmpC_re[j], numch_out ); + } + + for ( k = 0; k < dmx_ch; k++ ) + { + tmpC_re[k][k] = 1; + } + + for ( j = dmx_ch; j < numch_out; j++ ) + { + for ( k = 1; k < dmx_ch; k++ ) + { + tmpC_re[j][k] = hMdDec->spar_md.band_coeffs[b + i_ts * IVAS_MAX_NUM_BANDS].C_re[j - dmx_ch][k - 1]; + } + } + + for ( j = dmx_ch; j < numch_out; j++ ) + { + for ( k = dmx_ch; k < numch_out; k++ ) + { + if ( ( j - dmx_ch ) == ( k - dmx_ch ) ) + { + tmpP_re[j][k] = hMdDec->spar_md.band_coeffs[b + i_ts * IVAS_MAX_NUM_BANDS].P_re[k - dmx_ch]; + } + else + { + tmpP_re[j][k] = 0; + } + } + } + + for ( j = 1; j < numch_out; j++ ) + { + for ( k = dmx_ch; k < numch_out; k++ ) + { + for ( m = 0; m < numch_out; m++ ) + { + IVAS_RMULT_FLOAT( hMdDec->mixer_mat[j][m][b + i_ts * IVAS_MAX_NUM_BANDS], tmpP_re[m][k], re ); + hMdDec->spar_coeffs.P_re[j][k][( b * bw ) + i_ts * IVAS_MAX_NUM_BANDS] += re; + } + } + } + + for ( j = 0; j < numch_out; j++ ) + { + for ( k = 0; k < dmx_ch; k++ ) + { + for ( m = 0; m < numch_out; m++ ) + { + IVAS_RMULT_FLOAT( hMdDec->mixer_mat[j][m][b + i_ts * IVAS_MAX_NUM_BANDS], tmpC_re[m][k], re ); + hMdDec->spar_coeffs.C_re[j][k][( b * bw ) + i_ts * IVAS_MAX_NUM_BANDS] += re; + } + } + } + + hMdDec->spar_coeffs.C_re[0][0][( b * bw ) + i_ts * IVAS_MAX_NUM_BANDS] = + max( 0, hMdDec->spar_coeffs.C_re[0][0][( b * bw ) + i_ts * IVAS_MAX_NUM_BANDS] ); + } + } + + /* band mixing */ + if ( bw == IVAS_RED_BAND_FACT ) + { + for ( b = 0; b < num_bands_out; b = b + bw ) + { + dmx_ch = hMdDec->spar_md_cfg.num_dmx_chans_per_band[b]; + for ( j = 0; j < numch_out; j++ ) + { + for ( k = dmx_ch; k < numch_out; k++ ) + { + hMdDec->spar_coeffs.P_re[j][k][( b + 1 ) + i_ts * IVAS_MAX_NUM_BANDS] = hMdDec->spar_coeffs.P_re[j][k][b + i_ts * IVAS_MAX_NUM_BANDS]; + } + } + + for ( j = 0; j < numch_out; j++ ) + { + for ( k = 0; k < dmx_ch; k++ ) + { + hMdDec->spar_coeffs.C_re[j][k][( b + 1 ) + i_ts * IVAS_MAX_NUM_BANDS] = hMdDec->spar_coeffs.C_re[j][k][b + i_ts * IVAS_MAX_NUM_BANDS]; + } + } + } + } + } + + return; +} + + +/*-----------------------------------------------------------------------------------------* + * Function ivas_mat_col_rearrange() + * + * reorders the input matrix based on order + *-----------------------------------------------------------------------------------------*/ + +static void ivas_mat_col_rearrange( + float in_re[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH], + const int16_t order[IVAS_SPAR_MAX_CH], + const int16_t i_ts, + float ***mixer_mat, + const int16_t bands, + const int16_t num_ch ) +{ + int16_t i, j, idx; + + for ( i = 0; i < num_ch; i++ ) + { + idx = order[i]; + + for ( j = 0; j < num_ch; j++ ) + { + mixer_mat[j][i][bands + i_ts * IVAS_MAX_NUM_BANDS] = in_re[j][idx]; + } + } + + return; +} + + +/*-----------------------------------------------------------------------------------------* + * Function ivas_spar_dec_gen_umx_mat() + * + * generates upmix matrix + *-----------------------------------------------------------------------------------------*/ + +void ivas_spar_dec_gen_umx_mat( + ivas_spar_md_dec_state_t *hMdDec, /* i/o: SPAR MD decoder handle */ + const int16_t nchan_transport, /* i : number of transport channels */ + const int16_t num_bands_out, /* i : number of output bands */ + const int16_t bfi, /* i : bad frame indicator */ + const int16_t num_md_sub_frames ) +{ + int16_t i, j, b, i_ts, num_out_ch; + + num_out_ch = hMdDec->spar_md_cfg.num_umx_chs; + + for ( i_ts = 0; i_ts < num_md_sub_frames; i_ts++ ) + { + if ( hMdDec->td_decorr_flag == 1 ) + { + for ( i = 0; i < num_out_ch; i++ ) + { + for ( j = 0; j < nchan_transport; j++ ) + { + for ( b = 0; b < num_bands_out; b++ ) + { + hMdDec->mixer_mat[i][j][b + i_ts * IVAS_MAX_NUM_BANDS] = hMdDec->spar_coeffs.C_re[i][j][b + i_ts * IVAS_MAX_NUM_BANDS]; + } + } + } + + for ( i = 0; i < num_out_ch; i++ ) + { + for ( j = nchan_transport; j < num_out_ch; j++ ) + { + for ( b = 0; b < num_bands_out; b++ ) + { + hMdDec->mixer_mat[i][j][b + i_ts * IVAS_MAX_NUM_BANDS] = hMdDec->spar_coeffs.P_re[i][j][b + i_ts * IVAS_MAX_NUM_BANDS]; + } + } + } + } + else + { + for ( i = 0; i < num_out_ch; i++ ) + { + for ( j = 0; j < nchan_transport; j++ ) + { + for ( b = 0; b < num_bands_out; b++ ) + { + hMdDec->mixer_mat[i][j][b + i_ts * IVAS_MAX_NUM_BANDS] = hMdDec->spar_coeffs.C_re[i][j][b + i_ts * IVAS_MAX_NUM_BANDS]; + } + } + } + } + + } + + ivas_spar_dec_compute_ramp_down_post_matrix( hMdDec, num_bands_out, bfi, num_md_sub_frames ); + + return; +} + +static void ivas_spar_md_band_upmix( + ivas_band_coeffs_t *band_coeffs, + int16_t *nB, + int16_t *bands_bw, + int16_t *valid_bands, + int16_t bw_final, + int16_t ndec, + int16_t ndm ) +{ + int16_t i, ii, jj, b, idx, bw_fact; + + bw_fact = *bands_bw / bw_final; + for ( i = *nB - 1; i >= 0; i-- ) + { + + for ( b = bw_fact - 1; b >= 0; b-- ) + { + idx = i * bw_fact + b; + for ( ii = 0; ii < ndec + ndm - 1; ii++ ) + { + band_coeffs[idx].pred_re[ii] = band_coeffs[i].pred_re[ii]; + } + for ( ii = 0; ii < ndec; ii++ ) + { + for ( jj = 0; jj < ndm - 1; jj++ ) + { + band_coeffs[idx].C_re[ii][jj] = band_coeffs[i].C_re[ii][jj]; + } + } + for ( jj = 0; jj < ndec; jj++ ) + { + band_coeffs[idx].P_re[jj] = band_coeffs[i].P_re[jj]; + } + valid_bands[idx] = valid_bands[i]; + } + } + *nB = ( *nB ) * ( *bands_bw ) / bw_final; + *bands_bw = bw_final; + + return; +} + +/*-----------------------------------------------------------------------------------------* + * Function ivas_spar_dec_parse_md_bs() + * + * Parse SPAR MD bitstream + *-----------------------------------------------------------------------------------------*/ + +static void ivas_spar_dec_parse_md_bs( + ivas_spar_md_dec_state_t *hMdDec, + Decoder_State *st0, + int16_t *nB, + int16_t *bands_bw, + int16_t *dtx_vad, + const int32_t ivas_total_brate, + const int16_t sba_inactive_mode +) +{ + int16_t i, j, k, num_bands; + int16_t ii, jj, ndec, ndm; + uint16_t qsi; + ivas_quant_strat_t qs; + int16_t strat, no_ec; + int16_t do_diff[IVAS_MAX_NUM_BANDS]; + float quant[IVAS_SPAR_MAX_C_COEFF]; + int16_t do_repeat[IVAS_MAX_NUM_BANDS]; + *dtx_vad = 1; + *bands_bw = 1; + qsi = 0; + num_bands = hMdDec->spar_md.num_bands; + + if ( ivas_total_brate > IVAS_SID_5k2 ) + { + if ( hMdDec->spar_md_cfg.quant_strat_bits > 0 ) + { + if ( ivas_total_brate >= BRATE_SPAR_Q_STRAT ) + { + /*only one bit written for quantization strategy to indicate either a fixed quantization strategy or dtx_vad==0 */ + qsi = get_next_indice( st0, 1 ); + if ( qsi == 1 ) + { + *dtx_vad = 0; + } + } + else + { + if ( sba_inactive_mode == 1 ) + { + *dtx_vad = 0; + qsi = hMdDec->spar_md_cfg.quant_strat_bits + 1; + } + else + { + qsi = get_next_indice( st0, hMdDec->spar_md_cfg.quant_strat_bits ); + } + } + } + else + { + qsi = 0; + } + } + else + { + *dtx_vad = 0; + } + + hMdDec->dtx_vad = *dtx_vad; + + if ( *dtx_vad == 0 ) + { + *nB = SPAR_DTX_BANDS; + *bands_bw = num_bands / *nB; + + for ( i = 0; i < *nB; i++ ) + { + for ( j = 0; j < IVAS_SPAR_MAX_CH - 1; j++ ) + { + hMdDec->spar_md.band_coeffs[i].pred_re[j] = 0; + hMdDec->spar_md.band_coeffs[i].P_re[j] = 0; + } + hMdDec->valid_bands[i] = 1; + } + + for ( i = 0; i < num_bands; i++ ) + { + for ( j = 0; j < ( IVAS_SPAR_MAX_CH - IVAS_SPAR_MAX_DMX_CHS ); j++ ) + { + for ( k = 0; k < ( IVAS_SPAR_MAX_DMX_CHS - 1 ); k++ ) + { + hMdDec->spar_md.band_coeffs[i].C_re[j][k] = 0; + } + } + } + + ivas_parse_parameter_bitstream_dtx( &hMdDec->spar_md, st0, *bands_bw, *nB, hMdDec->spar_md_cfg.num_dmx_chans_per_band, hMdDec->spar_md_cfg.num_decorr_per_band ); + + if ( *bands_bw != 1 ) + { + ndec = hMdDec->spar_md_cfg.num_decorr_per_band[0]; + ndm = hMdDec->spar_md_cfg.num_dmx_chans_per_band[0]; + ivas_spar_md_band_upmix( + hMdDec->spar_md.band_coeffs, + nB, + bands_bw, + hMdDec->valid_bands, + 1, + ndec, + ndm ); + } + + return; + } + + qs = hMdDec->spar_md_cfg.quant_strat[qsi]; + + strat = get_next_indice( st0, 3 ); + + no_ec = 0; + + if ( strat < 2 ) + { + *bands_bw = strat + 1; + *nB = num_bands / *bands_bw; + for ( i = 0; i < *nB; i++ ) + { + do_diff[i] = 0; + do_repeat[i] = 0; + } + } + else if ( strat < 4 ) + { + *bands_bw = strat - 1; + *nB = num_bands / *bands_bw; + for ( i = 0; i < *nB; i++ ) + { + do_diff[i] = 0; + do_repeat[i] = 0; + } + no_ec = 1; + } + else if ( ivas_total_brate < IVAS_24k4 ) + { + *bands_bw = 2; + *nB = num_bands / *bands_bw; + + for ( i = 0; i < *nB; i++ ) + { + do_diff[i] = 0; + do_repeat[i] = ( ( strat % 2 ) == ( ( i + 1 ) % 2 ) ); + } + } + else + { + *bands_bw = 1; + *nB = num_bands; + + for ( i = 0; i < *nB; i++ ) + { + do_diff[i] = ( ( ( i + 1 ) & 3 ) != strat - 4 ); + do_repeat[i] = 0; + } + if ( hMdDec->spar_md_cfg.prev_quant_idx >= 0 ) + { + ivas_map_prior_coeffs_quant( &hMdDec->spar_md_prev, &hMdDec->spar_md_cfg, qsi, *nB ); + } + } + hMdDec->spar_md_cfg.prev_quant_idx = qsi; + + if ( no_ec == 0 ) + { + ivas_decode_arith_bs( hMdDec, st0, qsi, *nB, *bands_bw, do_diff, strat, ivas_total_brate ); + } + else + { + ivas_decode_huffman_bs( hMdDec, st0, qsi, *nB, *bands_bw ); + } + + for ( i = 0; i < *nB; i++ ) + { + ndec = hMdDec->spar_md_cfg.num_decorr_per_band[( *bands_bw ) * i]; + ndm = hMdDec->spar_md_cfg.num_dmx_chans_per_band[( *bands_bw ) * i]; + + ivas_deindex_real_index( hMdDec->spar_md.band_coeffs_idx[i].pred_index_re, qs.PR.q_levels[0], qs.PR.min, qs.PR.max, hMdDec->spar_md.band_coeffs[i].pred_re, ndm + ndec - 1 ); + + j = 0; + for ( ii = 0; ii < ndec; ii++ ) + { + for ( jj = 0; jj < ndm - 1; jj++ ) + { + quant[j] = hMdDec->spar_md.band_coeffs[i].C_re[ii][jj]; + j++; + } + } + + ivas_deindex_real_index( hMdDec->spar_md.band_coeffs_idx[i].drct_index_re, qs.C.q_levels[0], qs.C.min, qs.C.max, quant, ndec * ( ndm - 1 ) ); + + j = 0; + for ( ii = 0; ii < ndec; ii++ ) + { + for ( jj = 0; jj < ndm - 1; jj++ ) + { + hMdDec->spar_md.band_coeffs[i].C_re[ii][jj] = quant[j]; + j++; + } + } + + ivas_deindex_real_index( hMdDec->spar_md.band_coeffs_idx[i].decd_index_re, qs.P_r.q_levels[0], qs.P_r.min, qs.P_r.max, hMdDec->spar_md.band_coeffs[i].P_re, ndm + ndec - 1 ); + + /* Store prior coefficient indices */ + for ( j = 0; j < ndm + ndec - 1; j++ ) + { + hMdDec->spar_md_prev.band_coeffs_idx[i].pred_index_re[j] = hMdDec->spar_md.band_coeffs_idx[i].pred_index_re[j]; + } + for ( j = 0; j < ndec * ( ndm - 1 ); j++ ) + { + hMdDec->spar_md_prev.band_coeffs_idx[i].drct_index_re[j] = hMdDec->spar_md.band_coeffs_idx[i].drct_index_re[j]; + } + for ( j = 0; j < ndec; j++ ) + { + hMdDec->spar_md_prev.band_coeffs_idx[i].decd_index_re[j] = hMdDec->spar_md.band_coeffs_idx[i].decd_index_re[j]; + } + hMdDec->valid_bands[i] |= ( do_diff[i] == 0 && do_repeat[i] == 0 ) ? 1 : 0; + } + + ndec = hMdDec->spar_md_cfg.num_decorr_per_band[0]; + ndm = hMdDec->spar_md_cfg.num_dmx_chans_per_band[0]; + if ( *bands_bw != 1 ) + { + ivas_spar_md_band_upmix( + hMdDec->spar_md.band_coeffs, + nB, + bands_bw, + hMdDec->valid_bands, + 1, + ndec, + ndm ); + } + + + return; +} + + +/*-----------------------------------------------------------------------------------------* + * Function ivas_decode_arith_bs() + * + * Decode bitstream with arith decoder + *-----------------------------------------------------------------------------------------*/ + +static void ivas_decode_arith_bs( + ivas_spar_md_dec_state_t *hMdDec, + Decoder_State *st0, /* i/o: decoder state structure - for bitstream handling*/ + const uint16_t qsi, + const int16_t nB, + const int16_t bands_bw, + int16_t *pDo_diff, + const int16_t strat, + const int32_t ivas_total_brate ) +{ + int16_t i, ndm, ndec; + int16_t j; + ivas_cell_dim_t pred_cell_dims[IVAS_MAX_NUM_BANDS]; + ivas_cell_dim_t drct_cell_dims[IVAS_MAX_NUM_BANDS]; + ivas_cell_dim_t decd_cell_dims[IVAS_MAX_NUM_BANDS]; + ivas_cell_dim_t decx_cell_dims[IVAS_MAX_NUM_BANDS]; + int16_t symbol_arr_re[IVAS_MAX_INPUT_LEN]; + int16_t symbol_arr_old_re[IVAS_MAX_INPUT_LEN]; + int16_t any_diff; + + for ( i = 0; i < nB; i++ ) + { + ndm = hMdDec->spar_md_cfg.num_dmx_chans_per_band[bands_bw * i]; + ndec = hMdDec->spar_md_cfg.num_decorr_per_band[bands_bw * i]; + if ( ( ivas_total_brate < IVAS_24k4 ) && ( strat > 3 ) && ( ( ( i % 2 == 1 ) && ( strat % 2 == 0 ) ) || ( ( i % 2 == 0 ) && ( strat % 2 == 1 ) ) ) ) + { + pred_cell_dims[i].dim1 = 0; + pred_cell_dims[i].dim2 = 0; + drct_cell_dims[i].dim1 = 0; + drct_cell_dims[i].dim2 = 0; + decd_cell_dims[i].dim1 = 0; + decd_cell_dims[i].dim2 = 0; + decx_cell_dims[i].dim1 = 0; + decx_cell_dims[i].dim2 = 0; + } + else + { + pred_cell_dims[i].dim1 = ndm + ndec - 1; + if ( hMdDec->spar_hoa_md_flag && hMdDec->spar_hoa_dirac2spar_md_flag ) + { + if ( i >= SPAR_DIRAC_SPLIT_START_BAND ) + { + pred_cell_dims[i].dim1 -= ( FOA_CHANNELS - 1 ); + } + } + pred_cell_dims[i].dim2 = 1; + drct_cell_dims[i].dim1 = ndec; + drct_cell_dims[i].dim2 = ndm - 1; + decd_cell_dims[i].dim1 = ndec; + decd_cell_dims[i].dim2 = 1; + decx_cell_dims[i].dim1 = ( ndec * ( ndec - 1 ) ) >> 1; + decx_cell_dims[i].dim2 = 1; + } + } + + any_diff = 0; + for ( i = 0; i < nB; i++ ) + { + if ( pDo_diff[i] != 0 ) + { + any_diff = 1; + break; + } + } + + if ( any_diff == 1 ) + { + if ( hMdDec->spar_hoa_md_flag && hMdDec->spar_hoa_dirac2spar_md_flag ) + { + for ( i = 0; i < nB; i++ ) + { + if ( i >= SPAR_DIRAC_SPLIT_START_BAND ) + { + for ( j = 0; j < pred_cell_dims[i].dim1; j++ ) + { + hMdDec->spar_md_prev.band_coeffs_idx_mapped[i].pred_index_re[j] = + hMdDec->spar_md_prev.band_coeffs_idx_mapped[i].pred_index_re[j + ( FOA_CHANNELS - 1 )]; + } + } + } + } + + ivas_copy_band_coeffs_idx_to_arr( hMdDec->spar_md_prev.band_coeffs_idx_mapped, nB, symbol_arr_old_re, pred_cell_dims, PRED_COEFF ); + } + + ivas_arith_decode_cmplx_cell_array( &hMdDec->arith_coeffs.pred_arith_re[qsi], &hMdDec->arith_coeffs.pred_arith_re_diff[qsi], + st0, pred_cell_dims, pDo_diff, nB, symbol_arr_re, symbol_arr_old_re ); + + ivas_fill_band_coeffs_idx( hMdDec->spar_md.band_coeffs_idx, nB, symbol_arr_re, pred_cell_dims, PRED_COEFF ); + + if ( hMdDec->spar_hoa_md_flag && hMdDec->spar_hoa_dirac2spar_md_flag ) + { + for ( i = 0; i < nB; i++ ) + { + if ( i >= SPAR_DIRAC_SPLIT_START_BAND ) + { + for ( j = pred_cell_dims[i].dim1 - 1; j >= 0; j-- ) + { + hMdDec->spar_md.band_coeffs_idx[i].pred_index_re[j + ( FOA_CHANNELS - 1 )] = + hMdDec->spar_md.band_coeffs_idx[i].pred_index_re[j]; + } + for ( j = 0; j < FOA_CHANNELS - 1; j++ ) + { + hMdDec->spar_md.band_coeffs_idx[i].pred_index_re[j] = 0; + } + } + } + } + + if ( any_diff == 1 ) + { + ivas_copy_band_coeffs_idx_to_arr( hMdDec->spar_md_prev.band_coeffs_idx_mapped, nB, symbol_arr_old_re, drct_cell_dims, DRCT_COEFF ); + } + + ivas_arith_decode_cmplx_cell_array( &hMdDec->arith_coeffs.drct_arith_re[qsi], &hMdDec->arith_coeffs.drct_arith_re_diff[qsi], + st0, drct_cell_dims, pDo_diff, nB, symbol_arr_re, symbol_arr_old_re ); + + ivas_fill_band_coeffs_idx( hMdDec->spar_md.band_coeffs_idx, nB, symbol_arr_re, drct_cell_dims, DRCT_COEFF ); + + if ( any_diff == 1 ) + { + ivas_copy_band_coeffs_idx_to_arr( hMdDec->spar_md_prev.band_coeffs_idx_mapped, nB, symbol_arr_old_re, decd_cell_dims, DECD_COEFF ); + } + + ivas_arith_decode_cmplx_cell_array( &hMdDec->arith_coeffs.decd_arith_re[qsi], &hMdDec->arith_coeffs.decd_arith_re_diff[qsi], + st0, decd_cell_dims, pDo_diff, nB, symbol_arr_re, symbol_arr_old_re ); + + ivas_fill_band_coeffs_idx( hMdDec->spar_md.band_coeffs_idx, nB, symbol_arr_re, decd_cell_dims, DECD_COEFF ); + + if ( any_diff == 1 ) + { + ivas_copy_band_coeffs_idx_to_arr( hMdDec->spar_md_prev.band_coeffs_idx_mapped, nB, symbol_arr_old_re, decx_cell_dims, DECX_COEFF ); + } + + ivas_fill_band_coeffs_idx( hMdDec->spar_md.band_coeffs_idx, nB, symbol_arr_re, decx_cell_dims, DECX_COEFF ); + + return; +} + + +/*-----------------------------------------------------------------------------------------* + * Function ivas_fill_band_coeffs_idx() + * + * Copy pred band coeffs to arr + *-----------------------------------------------------------------------------------------*/ + +static void ivas_fill_band_coeffs_idx( + ivas_band_coeffs_ind_t *pBands_idx, + const int16_t nB, + int16_t *pSymbol_re, + ivas_cell_dim_t *pCell_dims, + const ivas_coeffs_type_t coeff_type ) +{ + int16_t i, len; + int16_t *pPtr_idx = NULL; + + for ( i = 0; i < nB; i++ ) + { + switch ( coeff_type ) + { + case PRED_COEFF: + { + pPtr_idx = pBands_idx[i].pred_index_re; + break; + } + case DRCT_COEFF: + { + pPtr_idx = pBands_idx[i].drct_index_re; + break; + } + case DECD_COEFF: + { + pPtr_idx = pBands_idx[i].decd_index_re; + break; + } + case DECX_COEFF: + { + break; + } + + default: + assert( !"unsupported config!" ); + } + + if ( coeff_type != DECX_COEFF ) + { + len = pCell_dims[i].dim1 * pCell_dims[i].dim2; + mvs2s( pSymbol_re, pPtr_idx, len ); + pSymbol_re += len; + } + } + + return; +} + + +/*-----------------------------------------------------------------------------------------* + * Function ivas_decode_huffman_bs() + * + * Decode bitstream with huffman decoder + *-----------------------------------------------------------------------------------------*/ + +static void ivas_decode_huffman_bs( + ivas_spar_md_dec_state_t *hMdDec, + Decoder_State *st0, /* i/o: decoder state structure - for bitstream handling*/ + const uint16_t qsi, + const int16_t nB, + const int16_t bands_bw ) +{ + int16_t i, j; + int16_t ndm, ndec; + int16_t pred_dim, drct_dim, decd_dim, pred_offset; + + for ( i = 0; i < nB; i++ ) + { + ndm = hMdDec->spar_md_cfg.num_dmx_chans_per_band[bands_bw * i]; + ndec = hMdDec->spar_md_cfg.num_decorr_per_band[bands_bw * i]; + + pred_dim = ndec + ndm - 1; + drct_dim = ndec * ( ndm - 1 ); + decd_dim = ndec; + pred_offset = 0; + + if ( hMdDec->spar_hoa_md_flag && hMdDec->spar_hoa_dirac2spar_md_flag ) + { + if ( i >= SPAR_DIRAC_SPLIT_START_BAND ) + { + pred_offset = FOA_CHANNELS - 1; + } + } + + for ( j = pred_offset; j < pred_dim; j++ ) + { + ivas_huffman_decode( &hMdDec->huff_coeffs.pred_huff_re[qsi], st0, &hMdDec->spar_md.band_coeffs_idx[i].pred_index_re[j] ); + } + + if ( hMdDec->spar_hoa_md_flag && hMdDec->spar_hoa_dirac2spar_md_flag ) + { + if ( i >= SPAR_DIRAC_SPLIT_START_BAND ) + { + for ( j = 0; j < pred_offset; j++ ) + { + hMdDec->spar_md.band_coeffs_idx[i].pred_index_re[j] = 0; + } + } + } + + for ( j = 0; j < drct_dim; j++ ) + { + ivas_huffman_decode( &hMdDec->huff_coeffs.drct_huff_re[qsi], st0, &hMdDec->spar_md.band_coeffs_idx[i].drct_index_re[j] ); + } + + for ( j = 0; j < decd_dim; j++ ) + { + ivas_huffman_decode( &hMdDec->huff_coeffs.decd_huff_re[qsi], st0, &hMdDec->spar_md.band_coeffs_idx[i].decd_index_re[j] ); + } + } + + return; +} + +static void ivas_spar_plc_get_band_age( + const int16_t *valid_bands, + int16_t *base_band_age, + const int16_t num_bands, + int16_t last_valid_band_idx[IVAS_MAX_NUM_BANDS], + int16_t valid_band_idx[IVAS_MAX_NUM_BANDS], + int16_t *all_valid, + int16_t *b_idx ) +{ + int16_t b, idx; + + set_s( valid_band_idx, 0, IVAS_MAX_NUM_BANDS ); + set_s( last_valid_band_idx, 0, IVAS_MAX_NUM_BANDS ); + idx = -1; + *all_valid = 1; + for ( b = 0; b < num_bands; b++ ) + { + if ( valid_bands[b] != 0 ) + { + base_band_age[b] = 0; /* reset band age */ + idx++; + valid_band_idx[idx] = b; + } + else + { + base_band_age[b] += 1; /* increment the age of invalid bands */ + + if ( base_band_age[b] > 3 ) + { + last_valid_band_idx[b] = idx; + } + *all_valid = 0; + } + } + *b_idx = idx; + + return; +} + +static void ivas_spar_get_plc_interp_weights( + int16_t valid_band_idx[IVAS_MAX_NUM_BANDS], + int16_t last_valid_band_idx, + int16_t idx, + int16_t b, + float *w, + int16_t *id0, + int16_t *id1 ) +{ + if ( last_valid_band_idx < 0 ) /* Extrapolation */ + { + *id1 = valid_band_idx[0]; + *id0 = 0; + *w = 1; + } + else if ( last_valid_band_idx == idx ) /* Extrapolation */ + { + *id1 = valid_band_idx[last_valid_band_idx]; + *id0 = valid_band_idx[last_valid_band_idx]; + *w = 0; + } + else /* Interpolation */ + { + *id0 = valid_band_idx[last_valid_band_idx]; + *id1 = valid_band_idx[last_valid_band_idx + 1]; + *w = ( (float) ( b - *id0 ) ) / ( *id1 - *id0 ); + } + return; +} + +/*-----------------------------------------------------------------------------------------* + * Function ivas_spar_md_fill_invalid_bands() + * + * Fill invalid bands in interpolation/extrapolation of valid bands + * when PLC is to be done with partial time differential coding + *-----------------------------------------------------------------------------------------*/ +static void ivas_spar_md_fill_invalid_bands( + ivas_spar_dec_matrices_t *pSpar_coeffs, + ivas_spar_dec_matrices_t *pSpar_coeffs_prev, + const int16_t *valid_bands, + int16_t *base_band_age, + const int16_t num_bands, + const int16_t num_channels, + const int16_t num_md_sub_frames ) +{ + int16_t i, j, b, all_valid; + int16_t valid_band_idx[IVAS_MAX_NUM_BANDS], idx = -1; + int16_t last_valid_band_idx[IVAS_MAX_NUM_BANDS]; + float w = 0; + ivas_spar_plc_get_band_age( valid_bands, base_band_age, num_bands, + last_valid_band_idx, valid_band_idx, &all_valid, &idx ); + assert( idx > 0 ); /* some bands should be valid */ + + if ( all_valid == 0 ) + { + for ( b = 0; b < num_bands; b++ ) + { + /* check against non zero in if and else if */ + if ( base_band_age[b] > 3 ) /* old invalid bands */ + { + int16_t id0, id1; + ivas_spar_get_plc_interp_weights( valid_band_idx, last_valid_band_idx[b], + idx, b, &w, &id0, &id1 ); + for ( i = 0; i < num_channels; i++ ) + { + for ( j = 0; j < num_channels; j++ ) + { + pSpar_coeffs->C_re[i][j][b] = ( 1 - w ) * pSpar_coeffs->C_re[i][j][id0] + w * pSpar_coeffs->C_re[i][j][id1]; + pSpar_coeffs->P_re[i][j][b] = ( 1 - w ) * pSpar_coeffs->P_re[i][j][id0] + w * pSpar_coeffs->P_re[i][j][id1]; + } + } + } + else /* young invalid bands */ + { + if ( valid_bands[b] == 0 ) + { + for ( i = 0; i < num_channels; i++ ) + { + for ( j = 0; j < num_channels; j++ ) + { + pSpar_coeffs->C_re[i][j][b] = pSpar_coeffs_prev->C_re[i][j][b]; + pSpar_coeffs->P_re[i][j][b] = pSpar_coeffs_prev->P_re[i][j][b]; + } + } + } + } + + if ( valid_bands[b] == 0 ) + { + int16_t i_ts; + for ( i = 0; i < num_channels; i++ ) + { + for ( j = 0; j < num_channels; j++ ) + { + for ( i_ts = 1; i_ts < num_md_sub_frames; i_ts++ ) + { + pSpar_coeffs->C_re[i][j][b + i_ts * IVAS_MAX_NUM_BANDS] = pSpar_coeffs->C_re[i][j][b]; + pSpar_coeffs->P_re[i][j][b + i_ts * IVAS_MAX_NUM_BANDS] = pSpar_coeffs->P_re[i][j][b]; + } + } + } + } + } + } + + return; +} + +static void ivas_spar_md_fill_invalid_bandcoeffs( + ivas_band_coeffs_t *pBand_coeffs, + ivas_band_coeffs_t *pBand_coeffs_prev, + const int16_t *valid_bands, + int16_t *base_band_age, + int16_t *first_valid_frame, + const int16_t num_bands ) +{ + int16_t j, k, b, all_valid; + int16_t valid_band_idx[IVAS_MAX_NUM_BANDS], idx = -1; + int16_t last_valid_band_idx[IVAS_MAX_NUM_BANDS]; + float w = 0; + + ivas_spar_plc_get_band_age( valid_bands, base_band_age, num_bands, + last_valid_band_idx, valid_band_idx, &all_valid, &idx ); + + assert( idx > 0 ); /* some bands should be valid */ + + if ( all_valid == 0 ) + { + for ( b = 0; b < num_bands; b++ ) + { + /* check against non zero in if and else if */ + if ( ( base_band_age[b] > 3 ) || ( *first_valid_frame == 0 ) ) /* old invalid bands */ + { + int16_t id0, id1; + ivas_spar_get_plc_interp_weights( valid_band_idx, last_valid_band_idx[b], + idx, b, &w, &id0, &id1 ); + + for ( j = 0; j < IVAS_SPAR_MAX_CH - 1; j++ ) + { + pBand_coeffs[b].pred_re[j] = ( 1 - w ) * pBand_coeffs[id0].pred_re[j] + w * pBand_coeffs[id1].pred_re[j]; + } + + for ( j = 0; j < IVAS_SPAR_MAX_CH - IVAS_SPAR_MAX_DMX_CHS; j++ ) + { + for ( k = 0; k < IVAS_SPAR_MAX_DMX_CHS - 1; k++ ) + { + pBand_coeffs[b].C_re[j][k] = ( 1 - w ) * pBand_coeffs[id0].C_re[j][k] + w * pBand_coeffs[id1].C_re[j][k]; + } + } + + for ( j = 0; j < IVAS_SPAR_MAX_CH - 1; j++ ) + { + pBand_coeffs[b].P_re[j] = ( 1 - w ) * pBand_coeffs[id0].P_re[j] + w * pBand_coeffs[id1].P_re[j]; + } + } + else /* young invalid bands */ + { + if ( valid_bands[b] == 0 ) + { + for ( j = 0; j < IVAS_SPAR_MAX_CH - 1; j++ ) + { + pBand_coeffs[b].pred_re[j] = pBand_coeffs_prev[b].pred_re[j]; + } + + for ( j = 0; j < IVAS_SPAR_MAX_CH - IVAS_SPAR_MAX_DMX_CHS; j++ ) + { + for ( k = 0; k < IVAS_SPAR_MAX_DMX_CHS - 1; k++ ) + { + pBand_coeffs[b].C_re[j][k] = pBand_coeffs_prev[b].C_re[j][k]; + } + } + + for ( j = 0; j < IVAS_SPAR_MAX_CH - 1; j++ ) + { + pBand_coeffs[b].P_re[j] = pBand_coeffs_prev[b].P_re[j]; + } + } + } + } + } + else + { + *first_valid_frame = 1; + } + + return; +} + + +/*-----------------------------------------------------------------------------------------* + * Function ivas_spar_dec_compute_ramp_down_post_matrix() + * + * + *-----------------------------------------------------------------------------------------*/ + +static void ivas_spar_dec_compute_ramp_down_post_matrix( + ivas_spar_md_dec_state_t *hMdDec, + const int16_t num_bands_out, + const int16_t bfi, + const int16_t num_md_sub_frames ) +{ + int16_t num_in_ch, num_out_ch, i, j, b; + + num_in_ch = hMdDec->spar_md_cfg.num_umx_chs; + num_out_ch = hMdDec->spar_md_cfg.num_umx_chs; + + if ( bfi == 0 ) + { + hMdDec->spar_plc_num_lost_frames = 0; + } + else + { + if ( hMdDec->td_decorr_flag == 0 ) + { + assert( 0 ); + } + + hMdDec->spar_plc_num_lost_frames += 1; + hMdDec->spar_plc_num_lost_frames = min( hMdDec->spar_plc_num_lost_frames, 100 ); + + if ( hMdDec->spar_plc_num_lost_frames > ivas_spar_dec_plc_num_frames_keep ) + { + int16_t num_fade_frames; + int16_t gain_dB; + float gain; + float post_matrix[IVAS_SPAR_MAX_CH]; + + num_fade_frames = max( hMdDec->spar_plc_num_lost_frames - ivas_spar_dec_plc_num_frames_keep, 0 ); + gain_dB = -min( num_fade_frames, ivas_spar_dec_plc_max_num_frames_ramp_down ) * ivas_spar_dec_plc_per_frame_ramp_down_gain_dB; + gain = powf( 10, ( ( (float) gain_dB ) / 20 ) ); + + for ( i = 0; i < IVAS_SPAR_MAX_CH; i++ ) + { + post_matrix[i] = 1 + min( ( (float) num_fade_frames ) / ivas_spar_dec_plc_num_frames_fade_out, 1 ) * ( ivas_spar_dec_plc_spatial_target[i] - 1 ); + post_matrix[i] *= gain; + } + + /* apply the post matrix */ + for ( int16_t i_ts = 0; i_ts < num_md_sub_frames; i_ts++ ) + { + for ( i = 0; i < num_out_ch; i++ ) + { + for ( j = 0; j < num_in_ch; j++ ) + { + for ( b = 0; b < num_bands_out; b++ ) + { + hMdDec->mixer_mat[i][j][b + i_ts * IVAS_MAX_NUM_BANDS] *= post_matrix[i]; + } + } + } + } + } + } + + return; +} + + +/*-----------------------------------------------------------------------------------------* + * Function ivas_spar_unquant_dtx_indicies() + * + * Unquantize SPAR MD DYX indices + *-----------------------------------------------------------------------------------------*/ + +static void ivas_spar_unquant_dtx_indicies( + ivas_spar_md_t *pSpar_md, + const int16_t nB, + const int16_t bw, + int16_t *ndm_per_band ) +{ + int16_t i, b; + int16_t q_lvl; + float val; + int16_t idx; + float pr_min_max[2]; + + pr_min_max[0] = pSpar_md->min_max[0]; + pr_min_max[1] = pSpar_md->min_max[1]; + + for ( b = 0; b < nB; b++ ) + { + for ( i = 0; i < FOA_CHANNELS - 1; i++ ) + { + q_lvl = dtx_pr_real_q_levels[ndm_per_band[bw * b] - 1][i]; + idx = pSpar_md->band_coeffs_idx[b].pred_index_re[i]; + ivas_deindex_real_index( &idx, q_lvl, pr_min_max[0], pr_min_max[1], &val, 1 ); + pSpar_md->band_coeffs[b].pred_re[i] = val; + } + + for ( i = 0; i < FOA_CHANNELS - ndm_per_band[bw * b]; i++ ) + { + q_lvl = dtx_pd_real_q_levels[ndm_per_band[bw * b] - 1][i]; + idx = pSpar_md->band_coeffs_idx[b].decd_index_re[i]; + ivas_deindex_real_index( &idx, q_lvl, dtx_pd_real_min_max[0], dtx_pd_real_min_max[1], &val, 1 ); + pSpar_md->band_coeffs[b].P_re[i] = val; + } + } + + return; +} + + +/*-----------------------------------------------------------------------------------------* + * Function ivas_parse_parameter_bitstream_dtx() + * + * parse DTX bitstream parameters + *-----------------------------------------------------------------------------------------*/ + +static void ivas_parse_parameter_bitstream_dtx( + ivas_spar_md_t *pSpar_md, + Decoder_State *st0, /* i/o: decoder state structure - for bitstream handling*/ + const int16_t bw, + const int16_t num_bands, + int16_t *num_dmx_per_band, + int16_t *num_dec_per_band ) +{ + int16_t i, j, ndec, ndm; + float val; + int16_t idx; + float pr_min_max[2]; + int16_t pr_q_lvls, pr, pd, pd_q_lvls, pr_pd_bits; + int16_t zero_pad_bits, sid_bits_len; + + sid_bits_len = st0->next_bit_pos; + pr_min_max[0] = pSpar_md->min_max[0]; + pr_min_max[1] = pSpar_md->min_max[1]; + + for ( i = 0; i < num_bands; i++ ) + { + ndec = num_dec_per_band[bw * i]; + ndm = num_dmx_per_band[bw * i]; + + for ( j = 0; j < FOA_CHANNELS - 1; j++ ) + { + int16_t pr_idx_1, pr_idx_2, pd_idx_1, pd_idx_2; + uint16_t value; + + pr_idx_1 = pr_pr_idx_pairs[ndm - 1][j][0]; + pr_idx_2 = pr_pr_idx_pairs[ndm - 1][j][1]; + pd_idx_1 = pr_pd_idx_pairs[ndm - 1][j][0]; + pd_idx_2 = pr_pd_idx_pairs[ndm - 1][j][1]; + + if ( pr_idx_1 != 0 || pd_idx_1 != 0 || pr_idx_2 != 0 || pd_idx_2 != 0 ) + { + pr_q_lvls = dtx_pr_real_q_levels[ndm - 1][pd_idx_1 - 1]; + + if ( ( j + 1 ) > ndec ) + { + pd_q_lvls = 1; + } + else + { + pd_q_lvls = dtx_pd_real_q_levels[ndm - 1][pd_idx_2 - 1]; + } + + pr_pd_bits = ivas_get_bits_to_encode( pd_q_lvls * pr_q_lvls ); + + value = get_next_indice( st0, pr_pd_bits ); + + pr = (int16_t) floor( value / pd_q_lvls ); + pd = value - pr * pd_q_lvls; + val = dtx_pd_real_min_max[0]; + ivas_quantise_real_values( &val, pd_q_lvls, dtx_pd_real_min_max[0], dtx_pd_real_min_max[1], &idx, &val, 1 ); + pd = pd + idx; + + val = pr_min_max[0]; + ivas_quantise_real_values( &val, pr_q_lvls, pr_min_max[0], pr_min_max[1], &idx, &val, 1 ); + pr = pr + idx; + + if ( ( j + 1 ) <= ndec ) + { + pSpar_md->band_coeffs_idx[i].decd_index_re[pd_idx_2 - 1] = pd; + } + + pSpar_md->band_coeffs_idx[i].pred_index_re[pd_idx_1 - 1] = pr; + } + } + } + + sid_bits_len = st0->next_bit_pos - sid_bits_len; + zero_pad_bits = ( SPAR_DTX_BANDS * SPAR_SID_BITS_TAR_PER_BAND ) - sid_bits_len; + assert( zero_pad_bits >= 0 ); + if ( num_dmx_per_band[0] == 2 ) + { + zero_pad_bits -= 1; + } + + for ( j = 0; j < zero_pad_bits; j++ ) + { + get_next_indice( st0, 1 ); + } + + ivas_spar_unquant_dtx_indicies( pSpar_md, num_bands, bw, num_dmx_per_band ); + + return; +} + + +/*-----------------------------------------------------------------------------------------* + * Function ivas_deindex_real_index() + * + * Deindex real index + *-----------------------------------------------------------------------------------------*/ + +static ivas_error ivas_deindex_real_index( + const int16_t *index, + const int16_t q_levels, + const float min_value, + const float max_value, + float *quant, + const int16_t dim ) +{ + int16_t i; + float q_step; + + if ( q_levels == 0 ) + { + return IVAS_ERR_INTERNAL; + } + + if ( q_levels == 1 ) + { + for ( i = 0; i < dim; i++ ) + { + quant[i] = 0; + } + } + else + { + q_step = ( max_value - min_value ) / ( q_levels - 1 ); + for ( i = 0; i < dim; i++ ) + { + quant[i] = index[i] * q_step; + } + } + + return IVAS_ERR_OK; +} + + +/*-----------------------------------------------------------------------------------------* + * Function ivas_spar_to_dirac() + * + * + *-----------------------------------------------------------------------------------------*/ + +void ivas_spar_to_dirac( + Decoder_Struct *st_ivas, + ivas_spar_md_dec_state_t *hMdDec, /* i/o: SPAR MD decoder handle */ + const int16_t dtx_vad, /* i : DTX frame flag */ + const int16_t num_bands_out, /* i : number of output bands */ + const int16_t bw, /* i : band joining factor */ + const int16_t dyn_active_w_flag ) +{ + DIRAC_DEC_HANDLE hDirAC; + int16_t start_band, end_band, band, qmf_band_start, qmf_band_end; + int16_t block, b; + int16_t *band_grouping; + float diffuseness[IVAS_MAX_NUM_BANDS]; + int16_t sba_order_internal; + float azi_dirac[IVAS_MAX_NUM_BANDS][MAX_PARAM_SPATIAL_SUBFRAMES]; + float ele_dirac[IVAS_MAX_NUM_BANDS][MAX_PARAM_SPATIAL_SUBFRAMES]; + int16_t azi[IVAS_MAX_NUM_BANDS]; + int16_t ele[IVAS_MAX_NUM_BANDS]; + float dvx[IVAS_MAX_NUM_BANDS], dvy[IVAS_MAX_NUM_BANDS], dvz[IVAS_MAX_NUM_BANDS]; + float radius; + float en_ratio, res_pow; + int16_t num_slots_in_subfr; + int16_t tmp_write_idx_param_band; + int16_t tmp_write_idx_band; + float pred_re_20ms[IVAS_MAX_NUM_BANDS][IVAS_SPAR_MAX_CH - 1]; + int16_t pred_idx; + int16_t *dirac_to_spar_md_bands; + int16_t enc_param_start_band; + int16_t active_w_vlbr; + int16_t i, num_subframes; + int16_t active_w; + SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom; + + active_w = ( dyn_active_w_flag == 1 ) || ( hMdDec->spar_md_cfg.active_w == 1 ); + sba_order_internal = min( st_ivas->sba_analysis_order, IVAS_MAX_SBA_ORDER ); + start_band = 0; + end_band = min( num_bands_out, SPAR_DIRAC_SPLIT_START_BAND ) / bw; + + hDirAC = st_ivas->hDirAC; + hSpatParamRendCom = st_ivas->hSpatParamRendCom; + + dirac_to_spar_md_bands = st_ivas->hSpar->dirac_to_spar_md_bands; + enc_param_start_band = st_ivas->hSpar->enc_param_start_band / bw; + active_w_vlbr = ( st_ivas->hDecoderConfig->ivas_total_brate < IVAS_24k4 ) ? 1 : 0; + + if ( hDirAC != NULL && ivas_get_hodirac_flag( st_ivas->hDecoderConfig->ivas_total_brate, st_ivas->sba_analysis_order ) == 0 ) + { + band_grouping = hDirAC->band_grouping; + num_slots_in_subfr = st_ivas->hDirAC->hConfig->dec_param_estim ? CLDFB_NO_COL_MAX / MAX_PARAM_SPATIAL_SUBFRAMES : 1; + + for ( band = start_band; band < end_band; band++ ) + { + float PR[3], Pd[3], dvnorm, g_pred; + + PR[0] = hMdDec->spar_md.band_coeffs[band].pred_re[2]; + PR[1] = hMdDec->spar_md.band_coeffs[band].pred_re[0]; + PR[2] = hMdDec->spar_md.band_coeffs[band].pred_re[1]; + g_pred = PR[0] * PR[0] + PR[1] * PR[1] + PR[2] * PR[2]; + if ( g_pred <= EPSILON ) + { + dvx[band] = 1.0f; + dvy[band] = 0.0f; + dvz[band] = 0.0f; + } + else + { + g_pred = sqrtf( g_pred ); + dvnorm = 1.0f / g_pred; + dvx[band] = PR[0] * dvnorm; + dvy[band] = PR[1] * dvnorm; + dvz[band] = PR[2] * dvnorm; + } + + radius = sqrtf( dvx[band] * dvx[band] + dvy[band] * dvy[band] ); + azi[band] = (int16_t) ( max( -180.0f, min( 180.0f, atan2f( dvy[band], dvx[band] ) / EVS_PI * 180.0f ) ) + 0.5f ); + ele[band] = (int16_t) ( max( -90.0f, min( 180.0f, atan2f( dvz[band], radius ) / EVS_PI * 180.0f ) ) + 0.5f ); + + if ( st_ivas->nchan_transport == 1 ) + { + float w_en_norm, f_scale; + if ( active_w ) + { + if ( dtx_vad == 0 ) + { + f_scale = IVAS_ACTIVEW_DM_F_SCALE_DTX; + } + else + { + f_scale = ( active_w_vlbr ) ? IVAS_ACTIVEW_DM_F_SCALE_VLBR : IVAS_ACTIVEW_DM_F_SCALE; + } + } + else + { + f_scale = 0.0f; + } + + w_en_norm = ( 1.0f - ( f_scale * g_pred * g_pred ) ); + w_en_norm *= w_en_norm; + + Pd[0] = hMdDec->spar_md.band_coeffs[band].P_re[1]; + Pd[1] = hMdDec->spar_md.band_coeffs[band].P_re[0]; + Pd[2] = hMdDec->spar_md.band_coeffs[band].P_re[2]; + en_ratio = PR[0] * PR[0] + PR[1] * PR[1] + PR[2] * PR[2]; + res_pow = w_en_norm + en_ratio + ( Pd[0] * Pd[0] + Pd[1] * Pd[1] + Pd[2] * Pd[2] ); + res_pow *= 0.5f; + hMdDec->spar_md.en_ratio_slow[band] = 0.75f * hMdDec->spar_md.en_ratio_slow[band] + 0.25f * en_ratio; + hMdDec->spar_md.ref_pow_slow[band] = 0.75f * hMdDec->spar_md.ref_pow_slow[band] + 0.25f * res_pow; + en_ratio = sqrtf( hMdDec->spar_md.en_ratio_slow[band] ) / ( hMdDec->spar_md.ref_pow_slow[band] + EPSILON ); + } + else + { + en_ratio = PR[0] * PR[0] + PR[1] * PR[1] + PR[2] * PR[2]; + hMdDec->spar_md.en_ratio_slow[band] = 0.75f * hMdDec->spar_md.en_ratio_slow[band] + 0.25f * en_ratio; + en_ratio = sqrtf( hMdDec->spar_md.en_ratio_slow[band] ); + } + diffuseness[band] = 1.0f - en_ratio; /*compute diffuseness*/ + diffuseness[band] = ( ( diffuseness[band] < 1.0f ) ? ( ( diffuseness[band] < 0.0f ) ? 0.f : diffuseness[band] ) : 1.0f ); + } + + for ( band = start_band; band < end_band; band++ ) + { + int16_t azi_dith, ele_dith; + tmp_write_idx_param_band = hDirAC->spar_to_dirac_write_idx; + + en_ratio = 1.0f - diffuseness[band]; + masa_sq( 1.0f - en_ratio, diffuseness_thresholds, DIRAC_DIFFUSE_LEVELS ); + + qmf_band_start = band_grouping[band]; + qmf_band_end = band_grouping[band + 1]; + + for ( block = 0; block < MAX_PARAM_SPATIAL_SUBFRAMES; block++ ) + { + int16_t ts_start, ts_end, ts; + + ts_start = DirAC_block_grouping[block]; + ts_end = DirAC_block_grouping[block + 1]; + for ( b = qmf_band_start; b < qmf_band_end; b++ ) + { + + azi_dith = azi[band]; + ele_dith = ele[band]; + + hSpatParamRendCom->energy_ratio1[block][b] = en_ratio; + tmp_write_idx_band = tmp_write_idx_param_band; + + if ( hDirAC->hConfig->dec_param_estim == FALSE ) + { + hSpatParamRendCom->elevation[tmp_write_idx_band][b] = ele_dith; + hSpatParamRendCom->azimuth[tmp_write_idx_band][b] = azi_dith; + hSpatParamRendCom->diffuseness_vector[tmp_write_idx_band][b] = diffuseness[band]; + } + else + { + for ( ts = ts_start; ts < ts_end; ts++ ) + { + hSpatParamRendCom->elevation[tmp_write_idx_band][b] = ele_dith; + hSpatParamRendCom->azimuth[tmp_write_idx_band][b] = azi_dith; + hSpatParamRendCom->diffuseness_vector[tmp_write_idx_band][b] = diffuseness[band]; + tmp_write_idx_band = ( tmp_write_idx_band + 1 ) % hSpatParamRendCom->dirac_md_buffer_length; + } + } + } + tmp_write_idx_param_band = ( tmp_write_idx_param_band + num_slots_in_subfr ) % hSpatParamRendCom->dirac_md_buffer_length; + } + } + + /* update buffer write index */ + if ( hDirAC->hConfig->dec_param_estim == FALSE ) + { + hDirAC->spar_to_dirac_write_idx = ( hDirAC->spar_to_dirac_write_idx + MAX_PARAM_SPATIAL_SUBFRAMES ) % hSpatParamRendCom->dirac_md_buffer_length; + } + else + { + hDirAC->spar_to_dirac_write_idx = ( hDirAC->spar_to_dirac_write_idx + CLDFB_NO_COL_MAX ) % hSpatParamRendCom->dirac_md_buffer_length; + } + } + else + { + band = end_band; + } + + /*read DirAC metadata, convert DirAC to SPAR*/ + for ( ; band < num_bands_out / bw; band++ ) + { + int16_t dirac_band_idx; + + dirac_band_idx = dirac_to_spar_md_bands[band] - enc_param_start_band; + + num_subframes = MAX_PARAM_SPATIAL_SUBFRAMES; + if ( st_ivas->hQMetaData->useLowerRes ) + { + num_subframes = 1; + } + + for ( block = 0; block < num_subframes; block++ ) + { + if ( st_ivas->hQMetaData->q_direction->band_data[dirac_band_idx].azimuth[block] < 0.f ) + { + st_ivas->hQMetaData->q_direction->band_data[dirac_band_idx].azimuth[block] += 360.f; + } + azi_dirac[band][block] = st_ivas->hQMetaData->q_direction->band_data[dirac_band_idx].azimuth[block]; + ele_dirac[band][block] = st_ivas->hQMetaData->q_direction->band_data[dirac_band_idx].elevation[block]; + } + + diffuseness[band] = 1.0f - st_ivas->hQMetaData->q_direction->band_data[dirac_band_idx].energy_ratio[0]; + } + + /* DirAC MD averaged over 4 subframes and converted to SPAR format similar to encoder processing */ + if ( hMdDec->spar_md_cfg.nchan_transport > 1 ) + { + ivas_get_spar_md_from_dirac( azi_dirac, ele_dirac, diffuseness, 1, NULL, &hMdDec->spar_md, &hMdDec->spar_md_cfg, end_band, num_bands_out, ( hMdDec->spar_hoa_md_flag ) ? 1 : sba_order_internal, dtx_vad, NULL, st_ivas->hQMetaData->useLowerRes, active_w_vlbr, dyn_active_w_flag ); + + /* temporarily copy frame-wise prediction coefficients in DirAC bands*/ + for ( pred_idx = 0; pred_idx < FOA_CHANNELS - 1; pred_idx++ ) + { + for ( band = SPAR_DIRAC_SPLIT_START_BAND; band < IVAS_MAX_NUM_BANDS; band++ ) + { + pred_re_20ms[band][pred_idx] = hMdDec->spar_md.band_coeffs[band].pred_re[pred_idx]; + } + } + } + + int16_t num_md_sub_frames; + num_md_sub_frames = ivas_get_spar_dec_md_num_subframes( sba_order_internal, st_ivas->hDecoderConfig->ivas_total_brate, st_ivas->last_active_ivas_total_brate ); + ivas_get_spar_md_from_dirac( azi_dirac, ele_dirac, diffuseness, num_md_sub_frames, NULL, &hMdDec->spar_md, &hMdDec->spar_md_cfg, end_band, num_bands_out / bw, ( hMdDec->spar_hoa_md_flag ) ? 1 : sba_order_internal, dtx_vad, NULL, st_ivas->hQMetaData->useLowerRes, active_w_vlbr, dyn_active_w_flag ); + + if ( st_ivas->hQMetaData->useLowerRes && dtx_vad ) + { + for ( band = SPAR_DIRAC_SPLIT_START_BAND; band < IVAS_MAX_NUM_BANDS; band++ ) + { + for ( block = 1; block < num_md_sub_frames; block++ ) + { + for ( i = 0; i < FOA_CHANNELS - 1; i++ ) /* pred coefficient index (index 0, 1, 2 predicts Y, Z, X respectively) */ + { + hMdDec->spar_md.band_coeffs[band + block * IVAS_MAX_NUM_BANDS].pred_re[i] = hMdDec->spar_md.band_coeffs[band].pred_re[i]; + } + for ( i = 0; i < FOA_CHANNELS - 1; i++ ) /* pred coefficient index (index 0, 1, 2 predicts Y, Z, X respectively) */ + { + hMdDec->spar_md.band_coeffs[band + block * IVAS_MAX_NUM_BANDS].P_re[i] = hMdDec->spar_md.band_coeffs[band].P_re[i]; + } + } + } + } + + /* expand DirAC TC 20ms MD for residual channels to all subframes*/ + for ( block = 0; block < num_md_sub_frames; block++ ) + { + for ( band = SPAR_DIRAC_SPLIT_START_BAND; band < IVAS_MAX_NUM_BANDS; band++ ) + { + for ( pred_idx = 0; pred_idx < FOA_CHANNELS - 1; pred_idx++ ) /* pred coefficient index (index 0, 1, 2 predicts Y, Z, X respectively) */ + { + if ( ivas_is_res_channel( pred_idx + 1, hMdDec->spar_md_cfg.nchan_transport ) ) + { + /* use 20ms coefficients only for residual channels */ + hMdDec->spar_md.band_coeffs[band + block * IVAS_MAX_NUM_BANDS].pred_re[pred_idx] = pred_re_20ms[band][pred_idx]; + } + } + } + } + + for ( b = end_band * bw; b < num_bands_out; b++ ) + { + hMdDec->valid_bands[b] = 1; + } + + return; +} +#endif \ No newline at end of file diff --git a/lib_dec/ivas_stereo_dft_dec.c b/lib_dec/ivas_stereo_dft_dec.c index e57859e02..680b25b0d 100644 --- a/lib_dec/ivas_stereo_dft_dec.c +++ b/lib_dec/ivas_stereo_dft_dec.c @@ -996,7 +996,7 @@ void stereo_dft_dec_reset( * * Update DFT memories for new frame *-------------------------------------------------------------------------*/ - +#ifdef IVAS_FLOAT_FIXED void stereo_dft_dec_update( STEREO_DFT_DEC_DATA_HANDLE hStereoDft, /* i/o: decoder DFT stereo handle */ const int16_t output_frame, /* i : output frame length */ @@ -1102,7 +1102,81 @@ void stereo_dft_dec_update( return; } +#else + +void stereo_dft_dec_update( + STEREO_DFT_DEC_DATA_HANDLE hStereoDft, /* i/o: decoder DFT stereo handle */ + const int16_t output_frame, /* i : output frame length */ + const int16_t sba_dirac_stereo_flag /* i : signal stereo output for SBA DirAC */ +) +{ + int16_t b, i, k_offset; + + /* Initialization */ + k_offset = STEREO_DFT_OFFSET; /*Add an offset*/ + + /* Update parameters */ + for (i = 0; i < k_offset * STEREO_DFT_BAND_MAX; i++) + { + hStereoDft->side_gain[i] = hStereoDft->side_gain[STEREO_DFT_NBDIV * STEREO_DFT_BAND_MAX + i]; + hStereoDft->res_pred_gain[i] = hStereoDft->res_pred_gain[STEREO_DFT_NBDIV * STEREO_DFT_BAND_MAX + i]; + } + + for (i = 0; i < k_offset; i++) + { + hStereoDft->gipd[i] = hStereoDft->gipd[STEREO_DFT_NBDIV + i]; + } + + /* Update configuration memories */ + for (i = 0; i < k_offset; i++) + { + hStereoDft->band_res[i] = hStereoDft->band_res[i + STEREO_DFT_NBDIV]; + hStereoDft->prm_res[i] = hStereoDft->prm_res[i + STEREO_DFT_NBDIV]; + hStereoDft->itd[i] = hStereoDft->itd[STEREO_DFT_NBDIV + i]; + hStereoDft->res_cod_mode[i] = hStereoDft->res_cod_mode[i + STEREO_DFT_NBDIV]; + hStereoDft->res_pred_mode[i] = hStereoDft->res_pred_mode[i + STEREO_DFT_NBDIV]; + } + /* Load new configurations */ + set_s(hStereoDft->band_res + k_offset, hStereoDft->hConfig->band_res, STEREO_DFT_NBDIV); + set_s(hStereoDft->prm_res + k_offset, hStereoDft->hConfig->prm_res, STEREO_DFT_NBDIV); + set_s(hStereoDft->res_pred_mode + k_offset, hStereoDft->hConfig->res_pred_mode, STEREO_DFT_NBDIV); + set_s(hStereoDft->res_cod_mode + k_offset, hStereoDft->hConfig->res_cod_mode, STEREO_DFT_NBDIV); + + /*Update attack info*/ + if (hStereoDft->attackPresent) + { + hStereoDft->wasTransient = 1; + } + else if (hStereoDft->wasTransient) + { + hStereoDft->wasTransient = 0; + } + + for (i = STEREO_DFT_CORE_HIST_MAX - 1; i > 0; i--) + { + hStereoDft->core_hist[i] = hStereoDft->core_hist[i - 1]; + } + + mvr2r(hStereoDft->hb_stefi_sig + output_frame, hStereoDft->hb_stefi_sig, hStereoDft->hb_stefi_delay); + mvr2r(hStereoDft->hb_nrg, hStereoDft->hb_nrg + 1, STEREO_DFT_CORE_HIST_MAX - 1); + mvr2r(hStereoDft->td_gain, hStereoDft->td_gain + 1, STEREO_DFT_CORE_HIST_MAX - 1); + + if (sba_dirac_stereo_flag) + { + /* buffer update, push back by 2 because of 2 subframes */ + for (b = 0; b < hStereoDft->nbands; b++) + { + for (i = SBA_DIRAC_NRG_SMOOTH_LONG; i > 1; i--) + { + hStereoDft->smooth_buf[b][i] = hStereoDft->smooth_buf[b][i - 2]; + } + } + } + + return; +} +#endif /*------------------------------------------------------------------------- * stereo_dft_dec_destroy() @@ -3510,13 +3584,14 @@ void stereo_dft_generate_res_pred( pop_wmops(); return; } - +#endif /*--------------------------------------------------------------- * stereo_dft_dec_smooth_parameters() * * * ---------------------------------------------------------------*/ +#ifndef IVAS_FLOAT_FIXED #if 1 void stereo_dft_dec_smooth_parameters( STEREO_DFT_DEC_DATA_HANDLE hStereoDft, /* i/o: decoder DFT stereo handle */ @@ -4116,7 +4191,9 @@ void stereo_dft_dec_smooth_parameters( return; } #endif +#endif +#ifndef IVAS_FLOAT_FIXED /*--------------------------------------------------------------- * stereo_dft_adapt_sf_delay() * @@ -4203,4 +4280,4 @@ static void stereo_dft_adapt_sf_delay( return; } -#endif +#endif \ No newline at end of file -- GitLab