diff --git a/lib_com/ivas_cnst.h b/lib_com/ivas_cnst.h index 6787571189c0cbcd7fc0855d0f3e0489dbc90524..0c64a519382d99d62acd5d78af491c02b0be2b11 100755 --- a/lib_com/ivas_cnst.h +++ b/lib_com/ivas_cnst.h @@ -1556,6 +1556,9 @@ typedef enum #define MAX_SPLIT_MD_SUBFRAMES 1 #define COMPLEX_MD_BAND_THRESH MAX_SPLIT_REND_MD_BANDS #define COMPLEX_MD_BAND_THRESH_LOW 5 +#ifdef SPLIT_REND_HF_TUNING +#define SPLIT_REND_RO_MD_BAND_THRESH 4 +#endif #define IVAS_SPLIT_REND_NUM_QUANT_STRATS 4 #define IVAS_SPLIT_REND_PRED_63QUANT_PNTS 63 diff --git a/lib_com/options.h b/lib_com/options.h index 2f3f3803eb3addb2b4a33ff71da50218c768a80a..e77cbadb38ac55cc55446e43bf77a58ffd461dc6 100755 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -163,6 +163,12 @@ #define NONBE_FIX_944_FEC_OMASA_1SEP_OBJ_MASA /* Nokia: issue 944: fix FEC error in OMASA */ #define NONBE_FIX_949_MC_5MS_FRAMING /* Dlb: issue 949: fix for issue 949, distorted output in MC mode with 5ms framing*/ +#ifdef SPLIT_REND_WITH_HEAD_ROT +#define SPLIT_REND_HF_TUNING /* Dlb: issue 950: split rendering MD tuning change at high frequencies*/ +#define SPLIT_REND_MC_FIX_LFE /* Dlb: issue 950: split rendering LFE fix for 7.1 and 5.1 MC mode*/ +#define SPLIT_EXT_REND_FIX_LIMITER_POS /* Dlb: issue 950: fixing limiter position in split rendering mode in external renderer*/ +#endif + /* ##################### End NON-BE switches ########################### */ /* ################## End DEVELOPMENT switches ######################### */ diff --git a/lib_dec/ivas_binRenderer_internal.c b/lib_dec/ivas_binRenderer_internal.c index 964a1fcd9cc930308ccc092f124e01adea299925..77e9095c9ee84ed1032ba0e0bd0b33b1027eb4cc 100644 --- a/lib_dec/ivas_binRenderer_internal.c +++ b/lib_dec/ivas_binRenderer_internal.c @@ -1535,6 +1535,9 @@ void ivas_binaural_add_LFE( { int16_t render_lfe, idx_lfe; float gain; +#ifdef SPLIT_REND_MC_FIX_LFE + float lfe_tc[L_FRAME48k]; +#endif if ( st_ivas->hBinRenderer != NULL ) { @@ -1558,10 +1561,17 @@ void ivas_binaural_add_LFE( for ( idx_lfe = 0; idx_lfe < st_ivas->hIntSetup.num_lfe; idx_lfe++ ) { +#ifdef SPLIT_REND_MC_FIX_LFE + v_multc( input_f[st_ivas->hIntSetup.index_lfe[idx_lfe]], gain, lfe_tc, output_frame ); + /* copy LFE to left and right channels */ + v_add( output_f[0], lfe_tc, output_f[0], output_frame ); + v_add( output_f[1], lfe_tc, output_f[1], output_frame ); +#else v_multc( input_f[st_ivas->hIntSetup.index_lfe[idx_lfe]], gain, input_f[st_ivas->hIntSetup.index_lfe[idx_lfe]], output_frame ); /* copy LFE to left and right channels */ v_add( output_f[0], input_f[st_ivas->hIntSetup.index_lfe[idx_lfe]], output_f[0], output_frame ); v_add( output_f[1], input_f[st_ivas->hIntSetup.index_lfe[idx_lfe]], output_f[1], output_frame ); +#endif } } diff --git a/lib_dec/ivas_objectRenderer_internal.c b/lib_dec/ivas_objectRenderer_internal.c index 99c9c17963972c8a56ef7fb3e65aac442b17b743..0f6159baf884da9af9ebdf32ae2ef968e7b81344 100644 --- a/lib_dec/ivas_objectRenderer_internal.c +++ b/lib_dec/ivas_objectRenderer_internal.c @@ -342,6 +342,18 @@ ivas_error ivas_td_binaural_renderer_sf_splitBinaural( { return error; } + +#ifdef SPLIT_REND_MC_FIX_LFE + if ( st_ivas->ivas_format == MC_FORMAT ) + { + float *p_tc[MAX_TRANSPORT_CHANNELS]; + for ( i = 0; i < st_ivas->nchan_transport; i++ ) + { + p_tc[i] = st_ivas->hTcBuffer->tc[i] + st_ivas->hTcBuffer->n_samples_rendered; + } + ivas_binaural_add_LFE( st_ivas, nSamplesRendered, p_tc, p_bin_output ); + } +#endif } for ( i = 0; i < pMultiBinPoseData->num_poses * BINAURAL_CHANNELS; i++ ) diff --git a/lib_dec/lib_dec.c b/lib_dec/lib_dec.c index a9e907bae263c64fe6a21774c004354a4eb2bf7b..bbe67a0f6057fa613cab80b30117fb0314f401c7 100644 --- a/lib_dec/lib_dec.c +++ b/lib_dec/lib_dec.c @@ -1051,6 +1051,9 @@ ivas_error IVAS_DEC_GetSplitBinauralBitstream( int16_t pcm_out_flag; int16_t td_input; int16_t numPoses; +#ifdef SPLIT_REND_HF_TUNING + int16_t ro_md_flag; +#endif error = IVAS_ERR_OK; st_ivas = hIvasDec->st_ivas; @@ -1153,6 +1156,26 @@ ivas_error IVAS_DEC_GetSplitBinauralBitstream( pcm_out_flag = ( output_config == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ? 1 : 0; td_input = st_ivas->renderer_type != RENDERER_BINAURAL_FASTCONV && st_ivas->renderer_type != RENDERER_BINAURAL_PARAMETRIC && st_ivas->renderer_type != RENDERER_BINAURAL_PARAMETRIC_ROOM && st_ivas->renderer_type != RENDERER_STEREO_PARAMETRIC; +#ifdef SPLIT_REND_HF_TUNING + if ( st_ivas->hBinRendererTd != NULL ) + { + ro_md_flag = 1; + } + else + { + ro_md_flag = 0; + } + + if ( ( error = ivas_renderMultiBinToSplitBinaural( &hSplitBinRend->splitrend, + st_ivas->hHeadTrackData->Quaternions[0], + st_ivas->hRenderConfig->split_rend_config.splitRendBitRate, + st_ivas->hRenderConfig->split_rend_config.codec, + st_ivas->hRenderConfig->split_rend_config.codec_frame_size_ms, + hSplitBinRend->hSplitRendBits, + hSplitBinRend->hMultiBinCldfbData->Cldfb_RealBuffer_Binaural, + hSplitBinRend->hMultiBinCldfbData->Cldfb_ImagBuffer_Binaural, + max_band, pOutput, 1, !td_input, pcm_out_flag, ro_md_flag ) ) != IVAS_ERR_OK ) +#else if ( ( error = ivas_renderMultiBinToSplitBinaural( &hSplitBinRend->splitrend, st_ivas->hHeadTrackData->Quaternions[0], st_ivas->hRenderConfig->split_rend_config.splitRendBitRate, @@ -1162,6 +1185,7 @@ ivas_error IVAS_DEC_GetSplitBinauralBitstream( hSplitBinRend->hMultiBinCldfbData->Cldfb_RealBuffer_Binaural, hSplitBinRend->hMultiBinCldfbData->Cldfb_ImagBuffer_Binaural, max_band, pOutput, 1, !td_input, pcm_out_flag ) ) != IVAS_ERR_OK ) +#endif { return error; } @@ -3699,6 +3723,7 @@ static ivas_error set_pcm_buffer_to_zero( { ivas_error error; + error = IVAS_ERR_OK; switch ( pcmType ) { case IVAS_DEC_PCM_FLOAT: diff --git a/lib_rend/ivas_prot_rend.h b/lib_rend/ivas_prot_rend.h index 4ab44209ba6719df9265db39bc4cfd7fb6c2581e..bb120dcafa050a70ee9e0095a5acd8f41fb07b6f 100644 --- a/lib_rend/ivas_prot_rend.h +++ b/lib_rend/ivas_prot_rend.h @@ -1554,6 +1554,24 @@ void ivas_renderSplitUpdateNoCorrectionPoseData( MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData ); +#ifdef SPLIT_REND_HF_TUNING +ivas_error ivas_renderMultiBinToSplitBinaural( + SPLIT_REND_WRAPPER *hSplitBin, + const IVAS_QUATERNION headPosition, + const int32_t SplitRendBitRate, + IVAS_SPLIT_REND_CODEC splitCodec, + int16_t codec_frame_size_ms, + IVAS_SPLIT_REND_BITS_HANDLE pBits, + float Cldfb_In_BinReal[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + float Cldfb_In_BinImag[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + const int16_t max_bands, + float *output[], + const int16_t low_res_pre_rend_rot, + const int16_t cldfb_in_flag, + const int16_t pcm_out_flag, + const int16_t ro_md_flag +); +#else ivas_error ivas_renderMultiBinToSplitBinaural( SPLIT_REND_WRAPPER *hSplitBin, const IVAS_QUATERNION headPosition, @@ -1569,7 +1587,21 @@ ivas_error ivas_renderMultiBinToSplitBinaural( const int16_t cldfb_in_flag, const int16_t pcm_out_flag ); +#endif +#ifdef SPLIT_REND_HF_TUNING +void ivas_rend_CldfbSplitPreRendProcess( + const BIN_HR_SPLIT_PRE_REND_HANDLE hBinHrSplitPreRend, + const IVAS_QUATERNION headPosition, + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, + float Cldfb_In_BinReal[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + float Cldfb_In_BinImag[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + IVAS_SPLIT_REND_BITS_HANDLE pBits, + const int32_t target_md_bits, + const int16_t low_res_pre_rend_rot, + const int16_t ro_md_flag +); +#else void ivas_rend_CldfbSplitPreRendProcess( const BIN_HR_SPLIT_PRE_REND_HANDLE hBinHrSplitPreRend, const IVAS_QUATERNION headPosition, @@ -1580,6 +1612,7 @@ void ivas_rend_CldfbSplitPreRendProcess( const int32_t target_md_bits, const int16_t low_res_pre_rend_rot ); +#endif void ivas_rend_CldfbSplitPostRendProcess( BIN_HR_SPLIT_POST_REND_HANDLE hBinHrSplitPostRend, @@ -1652,6 +1685,16 @@ void ivas_log_cldfb2wav_data( ); #endif +#ifdef SPLIT_REND_HF_TUNING +void ivas_SplitRenderer_GetRotMd( + BIN_HR_SPLIT_PRE_REND_HANDLE hBinHrSplitPreRend, /* i/o: binaural renderer handle */ + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, + float Cldfb_RealBuffer_Ref_Binaural[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* o : Reference Binaural signals */ + float Cldfb_ImagBuffer_Ref_Binaural[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* o : Reference Binaural signals */ + const int16_t low_res, + const int16_t ro_md_flag +); +#else void ivas_SplitRenderer_GetRotMd( BIN_HR_SPLIT_PRE_REND_HANDLE hBinHrSplitPreRend, /* i/o: binaural renderer handle */ MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, @@ -1659,6 +1702,7 @@ void ivas_SplitRenderer_GetRotMd( float Cldfb_ImagBuffer_Ref_Binaural[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* o : Reference Binaural signals */ const int16_t low_res ); +#endif void ivas_SplitRenderer_PostRenderer( BIN_HR_SPLIT_POST_REND_HANDLE hBinPostRenderer, /* i/o: binaural renderer handle */ diff --git a/lib_rend/ivas_splitRendererPre.c b/lib_rend/ivas_splitRendererPre.c index 700117931f2e33170f3ac7dae3f6da45ef375955..973432ec50f157b6f5a5b58ecb4c62f9c9a69938 100644 --- a/lib_rend/ivas_splitRendererPre.c +++ b/lib_rend/ivas_splitRendererPre.c @@ -584,45 +584,71 @@ static void ComputeCoeffs( } else { - cov_norm_fact = GetNormFact( cov_ii_re, cov_ii_im, cov_io_re, cov_io_im, cov_oo_re ); - - /* normalize the covariance */ - for ( i = 0; i < BINAURAL_CHANNELS; i++ ) +#ifdef SPLIT_REND_HF_TUNING + if ( real_only ) { - for ( j = 0; j < BINAURAL_CHANNELS; j++ ) + float gd_tmp[BINAURAL_CHANNELS]; + + for ( i = 0; i < BINAURAL_CHANNELS; i++ ) { - cov_ii_norm_re[i][j] = cov_ii_re[i][j] * cov_norm_fact; - cov_ii_norm_im[i][j] = cov_ii_im[i][j] * cov_norm_fact; - cov_io_norm_re[i][j] = cov_io_re[i][j] * cov_norm_fact; - cov_io_norm_im[i][j] = cov_io_im[i][j] * cov_norm_fact; - cov_oo_norm_re[i][j] = cov_oo_re[i][j] * cov_norm_fact; + gd_tmp[i] = cov_ii_re[i][i]; + if ( gd_tmp[i] < EPSILON ) + { + gd_tmp[i] = 1.0f; + } + else + { + gd_tmp[i] = ( cov_oo_re[i][i] ) / gd_tmp[i]; + gd_tmp[i] = sqrtf( gd_tmp[i] ); + } + hMd->pred_mat_re[i][i] = gd_tmp[i]; + set_zero( hMd->pred_mat_im[i], BINAURAL_CHANNELS ); } + hMd->pred_mat_re[1][0] = 0.0f; + hMd->pred_mat_re[0][1] = 0.0f; } + else + { +#endif + cov_norm_fact = GetNormFact( cov_ii_re, cov_ii_im, cov_io_re, cov_io_im, cov_oo_re ); - ComputePredMat( cov_ii_norm_re, cov_ii_norm_im, cov_io_norm_re, cov_io_norm_im, hMd->pred_mat_re, hMd->pred_mat_im, BINAURAL_CHANNELS, real_only ); + /* normalize the covariance */ + for ( i = 0; i < BINAURAL_CHANNELS; i++ ) + { + for ( j = 0; j < BINAURAL_CHANNELS; j++ ) + { + cov_ii_norm_re[i][j] = cov_ii_re[i][j] * cov_norm_fact; + cov_ii_norm_im[i][j] = cov_ii_im[i][j] * cov_norm_fact; + cov_io_norm_re[i][j] = cov_io_re[i][j] * cov_norm_fact; + cov_io_norm_im[i][j] = cov_io_im[i][j] * cov_norm_fact; + cov_oo_norm_re[i][j] = cov_oo_re[i][j] * cov_norm_fact; + } + } - /*TODO : change this function to real only as thats what is needed*/ - ComputePostPredCov( cov_ii_norm_re, cov_ii_norm_im, hMd->pred_mat_re, hMd->pred_mat_im, postpred_cov_re, postpred_cov_im, BINAURAL_CHANNELS ); + ComputePredMat( cov_ii_norm_re, cov_ii_norm_im, cov_io_norm_re, cov_io_norm_im, hMd->pred_mat_re, hMd->pred_mat_im, BINAURAL_CHANNELS, real_only ); - /* normalize everything to +-1 range */ - gd = 1.0f / ( PCM16_TO_FLT_FAC ); - for ( i = 0; i < BINAURAL_CHANNELS; i++ ) - { - for ( j = 0; j < BINAURAL_CHANNELS; j++ ) + /*TODO : change this function to real only as thats what is needed*/ + ComputePostPredCov( cov_ii_norm_re, cov_ii_norm_im, hMd->pred_mat_re, hMd->pred_mat_im, postpred_cov_re, postpred_cov_im, BINAURAL_CHANNELS ); + + /* normalize everything to +-1 range */ + gd = 1.0f / ( PCM16_TO_FLT_FAC ); + for ( i = 0; i < BINAURAL_CHANNELS; i++ ) { - postpred_cov_re[i][j] *= gd; - cov_ii_norm_re[i][j] = cov_ii_norm_re[i][j] * gd; - cov_oo_norm_re[i][j] = cov_oo_norm_re[i][j] * gd; + for ( j = 0; j < BINAURAL_CHANNELS; j++ ) + { + postpred_cov_re[i][j] *= gd; + cov_ii_norm_re[i][j] = cov_ii_norm_re[i][j] * gd; + cov_oo_norm_re[i][j] = cov_oo_norm_re[i][j] * gd; + } } - } #if 0 if ( 1 ) { #endif - gd2 = 0.0f; - sigma_d = 0.0f; - hMd->gd = 0.0f; + gd2 = 0.0f; + sigma_d = 0.0f; + hMd->gd = 0.0f; #if 0 } else @@ -680,42 +706,45 @@ static void ComputeCoeffs( } #endif /* 0 */ - if ( postpred_cov_re[0][0] > EPSILON ) - { - gl2 = ( cov_oo_norm_re[0][0] - ( gd2 * sigma_d ) ) / max( EPSILON, postpred_cov_re[0][0] ); - gl2 = max( gl2, 1.0f ); - gl2 = sqrtf( gl2 ); - } - else - { - gl2 = 1.0f; - } - - if ( postpred_cov_re[1][1] > EPSILON ) - { - gr2 = ( cov_oo_norm_re[1][1] - ( gd2 * sigma_d ) ) / max( EPSILON, postpred_cov_re[1][1] ); - gr2 = max( gr2, 1.0f ); - gr2 = sqrtf( gr2 ); - } - else - { - gr2 = 1.0f; - } + if ( postpred_cov_re[0][0] > EPSILON ) + { + gl2 = ( cov_oo_norm_re[0][0] - ( gd2 * sigma_d ) ) / max( EPSILON, postpred_cov_re[0][0] ); + gl2 = max( gl2, 1.0f ); + gl2 = sqrtf( gl2 ); + } + else + { + gl2 = 1.0f; + } - for ( i = 0; i < BINAURAL_CHANNELS; i++ ) - { - hMd->pred_mat_re[i][0] *= gl2; - hMd->pred_mat_re[i][1] *= gr2; - } + if ( postpred_cov_re[1][1] > EPSILON ) + { + gr2 = ( cov_oo_norm_re[1][1] - ( gd2 * sigma_d ) ) / max( EPSILON, postpred_cov_re[1][1] ); + gr2 = max( gr2, 1.0f ); + gr2 = sqrtf( gr2 ); + } + else + { + gr2 = 1.0f; + } - if ( real_only == 0 ) - { for ( i = 0; i < BINAURAL_CHANNELS; i++ ) { - hMd->pred_mat_im[i][0] *= gl2; - hMd->pred_mat_im[i][1] *= gr2; + hMd->pred_mat_re[i][0] *= gl2; + hMd->pred_mat_re[i][1] *= gr2; } + + if ( real_only == 0 ) + { + for ( i = 0; i < BINAURAL_CHANNELS; i++ ) + { + hMd->pred_mat_im[i][0] *= gl2; + hMd->pred_mat_im[i][1] *= gr2; + } + } +#ifdef SPLIT_REND_HF_TUNING } +#endif } return; @@ -1323,12 +1352,22 @@ static void ivas_SplitRenderer_quant_code( * *------------------------------------------------------------------------*/ +#ifdef SPLIT_REND_HF_TUNING +void ivas_SplitRenderer_GetRotMd( + BIN_HR_SPLIT_PRE_REND_HANDLE hBinHrSplitPreRend, /* i/o: binaural renderer handle */ + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, + float Cldfb_RealBuffer_Ref_Binaural[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* o : Reference Binaural signals */ + float Cldfb_ImagBuffer_Ref_Binaural[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* o : Reference Binaural signals */ + const int16_t low_res, + const int16_t ro_md_flag ) +#else void ivas_SplitRenderer_GetRotMd( BIN_HR_SPLIT_PRE_REND_HANDLE hBinHrSplitPreRend, /* i/o: binaural renderer handle */ MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, float Cldfb_RealBuffer_Ref_Binaural[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* o : Reference Binaural signals */ float Cldfb_ImagBuffer_Ref_Binaural[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], /* o : Reference Binaural signals */ const int16_t low_res ) +#endif { float cov_ii_re[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; float cov_oo_re[BINAURAL_CHANNELS][BINAURAL_CHANNELS]; @@ -1363,7 +1402,11 @@ void ivas_SplitRenderer_GetRotMd( start_slot_idx = sf_idx * num_slots; for ( b = 0; b < num_md_bands; b++ ) { +#ifndef SPLIT_REND_HF_TUNING if ( b < COMPLEX_MD_BAND_THRESH ) +#else + if ( ( b < SPLIT_REND_RO_MD_BAND_THRESH ) || ( !ro_md_flag && b < COMPLEX_MD_BAND_THRESH ) ) +#endif { real_only = 0; } @@ -1399,6 +1442,18 @@ void ivas_SplitRenderer_GetRotMd( * *------------------------------------------------------------------------*/ +#ifdef SPLIT_REND_HF_TUNING +void ivas_rend_CldfbSplitPreRendProcess( + const BIN_HR_SPLIT_PRE_REND_HANDLE hBinHrSplitPreRend, + const IVAS_QUATERNION headPosition, + MULTI_BIN_REND_POSE_DATA *pMultiBinPoseData, + float Cldfb_In_BinReal[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + float Cldfb_In_BinImag[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + IVAS_SPLIT_REND_BITS_HANDLE pBits, + const int32_t target_md_bits, + const int16_t low_res_pre_rend_rot, + const int16_t ro_md_flag ) +#else void ivas_rend_CldfbSplitPreRendProcess( const BIN_HR_SPLIT_PRE_REND_HANDLE hBinHrSplitPreRend, const IVAS_QUATERNION headPosition, @@ -1408,16 +1463,23 @@ void ivas_rend_CldfbSplitPreRendProcess( IVAS_SPLIT_REND_BITS_HANDLE pBits, const int32_t target_md_bits, const int16_t low_res_pre_rend_rot ) +#endif { push_wmops( "ivas_rend_CldfbSplitPreRendProcess" ); +#ifdef SPLIT_REND_HF_TUNING + ivas_SplitRenderer_GetRotMd( hBinHrSplitPreRend, pMultiBinPoseData, Cldfb_In_BinReal, Cldfb_In_BinImag, low_res_pre_rend_rot, ro_md_flag ); +#else ivas_SplitRenderer_GetRotMd( hBinHrSplitPreRend, pMultiBinPoseData, Cldfb_In_BinReal, Cldfb_In_BinImag, low_res_pre_rend_rot ); +#endif ivas_SplitRenderer_quant_code( hBinHrSplitPreRend, headPosition, pMultiBinPoseData, pBits, low_res_pre_rend_rot, target_md_bits ); #ifdef SPLIT_POSE_CORRECTION_DEBUG float tmpCrendBuffer[2][L_FRAME48k], quant_val, step, minv, maxv; - IVAS_QUATERNION QuaternionsPost[MAX_PARAM_SPATIAL_SUBFRAMES]; + IVAS_QUATERNION QuaternionsPost[MAX_PARAM_SPATIAL_SUBFRAMES], head_pos_euler; + float Cldfb_RealBuffer_Binaural_5ms[BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; + float Cldfb_ImagBuffer_Binaural_5ms[BINAURAL_CHANNELS][MAX_PARAM_SPATIAL_SUBFRAMES][CLDFB_NO_CHANNELS_MAX]; int16_t sf_idx, pos_idx, b, ch1, ch2; int32_t read_off, write_off; for ( sf_idx = 0; sf_idx < MAX_PARAM_SPATIAL_SUBFRAMES; sf_idx++ ) @@ -1444,7 +1506,11 @@ void ivas_rend_CldfbSplitPreRendProcess( set_pose_types( hBinHrSplitPreRend->hBinHrSplitPostRend->pose_type, pMultiBinPoseData ); for ( sf_idx = 0; sf_idx < MAX_PARAM_SPATIAL_SUBFRAMES; sf_idx++ ) { - hBinHrSplitPreRend->hBinHrSplitPostRend->QuaternionsPre[sf_idx] = headPositions[sf_idx]; + Quat2EulerDegree( headPosition, &head_pos_euler.z, &head_pos_euler.y, &head_pos_euler.x ); + hBinHrSplitPreRend->hBinHrSplitPostRend->QuaternionsPre[sf_idx].w = -3.0f; + hBinHrSplitPreRend->hBinHrSplitPostRend->QuaternionsPre[sf_idx].x = roundf( head_pos_euler.x ); + hBinHrSplitPreRend->hBinHrSplitPostRend->QuaternionsPre[sf_idx].y = roundf( head_pos_euler.y ); + hBinHrSplitPreRend->hBinHrSplitPostRend->QuaternionsPre[sf_idx].z = roundf( head_pos_euler.z ); } for ( sf_idx = 0; sf_idx < 1; sf_idx++ ) { @@ -1453,12 +1519,12 @@ void ivas_rend_CldfbSplitPreRendProcess( for ( b = 0; b < MAX_SPLIT_REND_MD_BANDS; b++ ) { hBinHrSplitPreRend->hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b] = hBinHrSplitPreRend->rot_md[pos_idx][sf_idx][b]; -#if 0 +#if 1 BIN_HR_SPLIT_REND_MD_HANDLE hMd; hMd = &hBinHrSplitPreRend->hBinHrSplitPostRend->rot_md[pos_idx][sf_idx][b]; minv = -1.4f; maxv = 1.4f; - step = ( maxv - minv ) / 30.0f; + step = ( maxv - minv ) / 62.0f; if ( b >= 20 ) { float sign; @@ -1496,14 +1562,21 @@ void ivas_rend_CldfbSplitPreRendProcess( } #endif - ivas_rend_CldfbSplitPostRendProcess( hBinHrSplitPreRend->hBinHrSplitPostRend, pMultiBinPoseData, QuaternionsPost, Cldfb_In_BinReal[0], Cldfb_In_BinImag[0], tmpCrendBuffer, 1 ); - + for ( sf_idx = 0; sf_idx < MAX_PARAM_SPATIAL_SUBFRAMES; sf_idx++ ) { - float *pOut[2]; - char fname[200] = "ref_act_pos.wav"; - pOut[0] = tmpCrendBuffer[0]; - pOut[1] = tmpCrendBuffer[1]; - dbgwrite_wav( pOut, CLDFB_NO_COL_MAX * hBinHrSplitPreRend->hBinHrSplitPostRend->cldfbSyn[0]->no_channels, fname, 48000, 2 ); + mvr2r( (float *) Cldfb_In_BinReal[0][sf_idx * MAX_PARAM_SPATIAL_SUBFRAMES], (float *) Cldfb_RealBuffer_Binaural_5ms[0], MAX_PARAM_SPATIAL_SUBFRAMES * CLDFB_NO_CHANNELS_MAX ); + mvr2r( (float *) Cldfb_In_BinReal[1][sf_idx * MAX_PARAM_SPATIAL_SUBFRAMES], (float *) Cldfb_RealBuffer_Binaural_5ms[1], MAX_PARAM_SPATIAL_SUBFRAMES * CLDFB_NO_CHANNELS_MAX ); + mvr2r( (float *) Cldfb_In_BinImag[0][sf_idx * MAX_PARAM_SPATIAL_SUBFRAMES], (float *) Cldfb_ImagBuffer_Binaural_5ms[0], MAX_PARAM_SPATIAL_SUBFRAMES * CLDFB_NO_CHANNELS_MAX ); + mvr2r( (float *) Cldfb_In_BinImag[1][sf_idx * MAX_PARAM_SPATIAL_SUBFRAMES], (float *) Cldfb_ImagBuffer_Binaural_5ms[1], MAX_PARAM_SPATIAL_SUBFRAMES * CLDFB_NO_CHANNELS_MAX ); + ivas_rend_CldfbSplitPostRendProcess( hBinHrSplitPreRend->hBinHrSplitPostRend, pMultiBinPoseData, QuaternionsPost[0], Cldfb_RealBuffer_Binaural_5ms, Cldfb_ImagBuffer_Binaural_5ms, tmpCrendBuffer, 1 ); + + { + float *pOut[2]; + char fname[200] = "ref_act_pos.wav"; + pOut[0] = tmpCrendBuffer[0]; + pOut[1] = tmpCrendBuffer[1]; + dbgwrite_wav( pOut, CLDFB_NO_COL_MAX * hBinHrSplitPreRend->hBinHrSplitPostRend->cldfbSyn[0]->no_channels, fname, 48000, 2 ); + } } #endif @@ -1578,6 +1651,7 @@ ivas_error ivas_splitBinPreRendOpen( ivas_split_rend_init_huff_cfg( &hBinRend->huff_cfg ); #ifdef SPLIT_POSE_CORRECTION_DEBUG + ivas_error error; if ( ( error = ivas_splitBinPostRendOpen( &hBinRend->hBinHrSplitPostRend, pMultiBinPoseData, 48000 ) ) != IVAS_ERR_OK ) { return error; @@ -2094,6 +2168,19 @@ static ivas_error splitRendLc3plusEncodeAndWrite( * *------------------------------------------------------------------------*/ +#ifdef SPLIT_REND_HF_TUNING +static ivas_error ivas_renderMultiTDBinToSplitBinaural( + SPLIT_REND_WRAPPER *hSplitBin, + const IVAS_QUATERNION headPosition, + const int32_t SplitRendBitRate, + const int16_t codec_frame_size_ms, + IVAS_SPLIT_REND_BITS_HANDLE pBits, + const int16_t max_bands, + float *in[], + const int16_t low_res_pre_rend_rot, + const int16_t pcm_out_flag, + const int16_t ro_md_flag ) +#else static ivas_error ivas_renderMultiTDBinToSplitBinaural( SPLIT_REND_WRAPPER *hSplitBin, const IVAS_QUATERNION headPosition, @@ -2104,6 +2191,7 @@ static ivas_error ivas_renderMultiTDBinToSplitBinaural( float *in[], const int16_t low_res_pre_rend_rot, const int16_t pcm_out_flag ) +#endif { ivas_error error; int32_t bit_len, available_bits, target_md_bits, actual_md_bits; @@ -2187,8 +2275,11 @@ static ivas_error ivas_renderMultiTDBinToSplitBinaural( target_md_bits = ivas_get_split_rend_md_target_brate( SplitRendBitRate, pcm_out_flag ) * L_FRAME48k / 48000; actual_md_bits = pBits->bits_written; - +#ifdef SPLIT_REND_HF_TUNING + ivas_rend_CldfbSplitPreRendProcess( hSplitBin->hBinHrSplitPreRend, headPosition, &hSplitBin->multiBinPoseData, Cldfb_In_BinReal, Cldfb_In_BinImag, pBits, target_md_bits, low_res_pre_rend_rot, ro_md_flag ); +#else ivas_rend_CldfbSplitPreRendProcess( hSplitBin->hBinHrSplitPreRend, headPosition, &hSplitBin->multiBinPoseData, Cldfb_In_BinReal, Cldfb_In_BinImag, pBits, target_md_bits, low_res_pre_rend_rot ); +#endif } if ( pcm_out_flag == 0 ) @@ -2316,6 +2407,23 @@ static void lc3plusTimeAlignCldfbPoseCorr( * *------------------------------------------------------------------------*/ +#ifdef SPLIT_REND_HF_TUNING +ivas_error ivas_renderMultiBinToSplitBinaural( + SPLIT_REND_WRAPPER *hSplitBin, + const IVAS_QUATERNION headPosition, + const int32_t SplitRendBitRate, + IVAS_SPLIT_REND_CODEC splitCodec, + int16_t codec_frame_size_ms, + IVAS_SPLIT_REND_BITS_HANDLE pBits, + float Cldfb_In_BinReal[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + float Cldfb_In_BinImag[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], + const int16_t max_bands, + float *output[], + const int16_t low_res_pre_rend_rot, + const int16_t cldfb_in_flag, + const int16_t pcm_out_flag, + const int16_t ro_md_flag ) +#else ivas_error ivas_renderMultiBinToSplitBinaural( SPLIT_REND_WRAPPER *hSplitBin, const IVAS_QUATERNION headPosition, @@ -2330,6 +2438,7 @@ ivas_error ivas_renderMultiBinToSplitBinaural( const int16_t low_res_pre_rend_rot, const int16_t cldfb_in_flag, const int16_t pcm_out_flag ) +#endif { ivas_error error; int32_t bit_len, target_md_bits, actual_md_bits, available_bits; @@ -2355,7 +2464,11 @@ ivas_error ivas_renderMultiBinToSplitBinaural( { /*TD input*/ /*if CLDFB handles have been allocated then assume valid multi binaural input in out[][] buffer and perform CLDFB analysis*/ +#ifdef SPLIT_REND_HF_TUNING + error = ivas_renderMultiTDBinToSplitBinaural( hSplitBin, headPosition, SplitRendBitRate, codec_frame_size_ms, pBits, max_bands, output, low_res_pre_rend_rot, pcm_out_flag, ro_md_flag ); +#else error = ivas_renderMultiTDBinToSplitBinaural( hSplitBin, headPosition, SplitRendBitRate, codec_frame_size_ms, pBits, max_bands, output, low_res_pre_rend_rot, pcm_out_flag ); +#endif pop_wmops(); return error; @@ -2373,7 +2486,11 @@ ivas_error ivas_renderMultiBinToSplitBinaural( target_md_bits = ivas_get_split_rend_md_target_brate( SplitRendBitRate, pcm_out_flag ) * L_FRAME48k / 48000; actual_md_bits = pBits->bits_written; +#ifdef SPLIT_REND_HF_TUNING + ivas_rend_CldfbSplitPreRendProcess( hSplitBin->hBinHrSplitPreRend, headPosition, &hSplitBin->multiBinPoseData, Cldfb_In_BinReal, Cldfb_In_BinImag, pBits, target_md_bits, low_res_pre_rend_rot, ro_md_flag ); +#else ivas_rend_CldfbSplitPreRendProcess( hSplitBin->hBinHrSplitPreRend, headPosition, &hSplitBin->multiBinPoseData, Cldfb_In_BinReal, Cldfb_In_BinImag, pBits, target_md_bits, low_res_pre_rend_rot ); +#endif } if ( pcm_out_flag == 0 ) diff --git a/lib_rend/ivas_stat_rend.h b/lib_rend/ivas_stat_rend.h index ccd6641b52bd30595093932dea89e3aca56a5b7e..bbf40ed41b6aa8992bd2f6e646b430cc0a01b6c6 100644 --- a/lib_rend/ivas_stat_rend.h +++ b/lib_rend/ivas_stat_rend.h @@ -1373,21 +1373,6 @@ typedef struct ivas_binaural_head_rot_split_rendering_huff_struct } BIN_HR_SPLIT_REND_HUFF, *BIN_HR_SPLIT_REND_HUFF_HANDLE; -typedef struct ivas_binaural_head_rot_split_pre_rendering_struct -{ - BIN_HR_SPLIT_REND_MD rot_md[MAX_HEAD_ROT_POSES - 1][MAX_SPLIT_MD_SUBFRAMES][MAX_SPLIT_REND_MD_BANDS]; - float fix_pos_rot_mat[MAX_HEAD_ROT_POSES - 1][BINAURAL_CHANNELS][BINAURAL_CHANNELS]; - IVAS_SPLIT_REND_POSE_TYPE pose_type[MAX_HEAD_ROT_POSES - 1]; - BIN_HR_SPLIT_REND_HUFF huff_cfg; -#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG - HANDLE_CLDFB_FILTER_BANK cldfbSynRotBinDec[MAX_HEAD_ROT_POSES + 1][BINAURAL_CHANNELS]; -#endif - -#ifdef SPLIT_POSE_CORRECTION_DEBUG - BIN_HR_SPLIT_POST_REND_HANDLE hBinHrSplitPostRend; -#endif - -} BIN_HR_SPLIT_PRE_REND, *BIN_HR_SPLIT_PRE_REND_HANDLE; typedef struct ivas_binaural_head_rot_split_post_rendering_struct { @@ -1416,6 +1401,22 @@ typedef struct ivas_binaural_head_rot_split_post_rendering_struct } BIN_HR_SPLIT_POST_REND, *BIN_HR_SPLIT_POST_REND_HANDLE; +typedef struct ivas_binaural_head_rot_split_pre_rendering_struct +{ + BIN_HR_SPLIT_REND_MD rot_md[MAX_HEAD_ROT_POSES - 1][MAX_SPLIT_MD_SUBFRAMES][MAX_SPLIT_REND_MD_BANDS]; + float fix_pos_rot_mat[MAX_HEAD_ROT_POSES - 1][BINAURAL_CHANNELS][BINAURAL_CHANNELS]; + IVAS_SPLIT_REND_POSE_TYPE pose_type[MAX_HEAD_ROT_POSES - 1]; + BIN_HR_SPLIT_REND_HUFF huff_cfg; +#ifdef SPLIT_REND_WITH_HEAD_ROT_DEBUG + HANDLE_CLDFB_FILTER_BANK cldfbSynRotBinDec[MAX_HEAD_ROT_POSES + 1][BINAURAL_CHANNELS]; +#endif + +#ifdef SPLIT_POSE_CORRECTION_DEBUG + BIN_HR_SPLIT_POST_REND_HANDLE hBinHrSplitPostRend; +#endif + +} BIN_HR_SPLIT_PRE_REND, *BIN_HR_SPLIT_PRE_REND_HANDLE; + typedef struct ivas_binaural_head_rot_split_rendering_lcld_enc_struct { void *pLcld_enc; diff --git a/lib_rend/lib_rend.c b/lib_rend/lib_rend.c index a9120a66a25fbdcabbe0d446d1478bcfefade04a..3604080f75fa48091e79d781f546861d2bb280f3 100644 --- a/lib_rend/lib_rend.c +++ b/lib_rend/lib_rend.c @@ -6522,8 +6522,11 @@ static ivas_error renderMcToSplitBinaural( /* copy input for in-place rotation */ +#ifdef SPLIT_REND_MC_FIX_LFE + set_zero( tmpRotBuffer.data, tmpRotBuffer.config.numSamplesPerChannel * tmpRotBuffer.config.numChannels ); +#else mvr2r( mcInput->base.inputBuffer.data, tmpRotBuffer.data, tmpRotBuffer.config.numChannels * tmpRotBuffer.config.numSamplesPerChannel ); - +#endif /* perform rotation in source format to tmpRotBuffer */ pCombinedOrientationDataLocal = &combinedOrientationDataLocal; if ( ( error = rotateFrameMc( mcInput->base.inputBuffer, mcInput->base.inConfig, &mcInput->customLsInput, mcInput->base.ctx.pHeadRotData, &pCombinedOrientationDataLocal, mcInput->rot_gains_prev[pos_idx], mcInput->efapInWrapper.hEfap, tmpRotBuffer ) ) != IVAS_ERR_OK ) @@ -6559,13 +6562,18 @@ static ivas_error renderMcToSplitBinaural( free( tmpRotBuffer.data ); } +#ifdef SPLIT_REND_MC_FIX_LFE + accumulate2dArrayToBuffer( tmpSplitBinauralBuffer, &outAudio ); +#endif + if ( ( error = renderLfeToBinaural( mcInput, outConfig, outAudio ) ) != IVAS_ERR_OK ) { return error; } +#ifndef SPLIT_REND_MC_FIX_LFE accumulate2dArrayToBuffer( tmpSplitBinauralBuffer, &outAudio ); - +#endif pop_wmops(); return IVAS_ERR_OK; } @@ -8181,6 +8189,7 @@ static ivas_error getSamplesInternal( { return error; } +#ifndef SPLIT_EXT_REND_FIX_LIMITER_POS if ( outAudio.config.is_cldfb == 0 ) { @@ -8191,6 +8200,7 @@ static ivas_error getSamplesInternal( limitRendererOutput( hIvasRend->hLimiter, outAudio.data, outAudio.config.numSamplesPerChannel, IVAS_LIMITER_THRESHOLD ); #endif } +#endif #else #ifndef DISABLE_LIMITER @@ -8209,6 +8219,9 @@ static ivas_error getSamplesInternal( float Cldfb_RealBuffer_Binaural[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; float Cldfb_ImagBuffer_Binaural[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX]; int16_t ch; +#ifdef SPLIT_REND_HF_TUNING + int16_t i, ro_md_flag; +#endif float *tmpBinaural[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS], tmpBinaural_buff[MAX_HEAD_ROT_POSES * BINAURAL_CHANNELS][L_FRAME48k]; for ( ch = 0; ch < MAX_OUTPUT_CHANNELS; ch++ ) @@ -8230,8 +8243,23 @@ static ivas_error getSamplesInternal( /* Encode split rendering bitstream */ convertBitsBufferToInternalBitsBuff( *hBits, &bits ); +#ifdef SPLIT_REND_HF_TUNING + ro_md_flag = 0; + for ( i = 0; i < RENDERER_MAX_ISM_INPUTS; ++i ) + { + if ( hIvasRend->inputsIsm[i].base.inConfig != IVAS_AUDIO_CONFIG_INVALID ) + { + ro_md_flag = 1; + break; + } + } + + if ( ( error = ivas_renderMultiBinToSplitBinaural( &hIvasRend->splitRendWrapper, hIvasRend->headRotData.headPositions[0], hIvasRend->hRendererConfig->split_rend_config.splitRendBitRate, hIvasRend->hRendererConfig->split_rend_config.codec, hIvasRend->hRendererConfig->split_rend_config.codec_frame_size_ms, + &bits, Cldfb_RealBuffer_Binaural, Cldfb_ImagBuffer_Binaural, ( const int16_t )( ( BINAURAL_MAXBANDS * hIvasRend->sampleRateOut ) / 48000 ), tmpBinaural, 1, cldfb_in_flag, ( hIvasRend->outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ? 1 : 0, ro_md_flag ) ) != IVAS_ERR_OK ) +#else if ( ( error = ivas_renderMultiBinToSplitBinaural( &hIvasRend->splitRendWrapper, hIvasRend->headRotData.headPositions[0], hIvasRend->hRendererConfig->split_rend_config.splitRendBitRate, hIvasRend->hRendererConfig->split_rend_config.codec, hIvasRend->hRendererConfig->split_rend_config.codec_frame_size_ms, &bits, Cldfb_RealBuffer_Binaural, Cldfb_ImagBuffer_Binaural, ( const int16_t )( ( BINAURAL_MAXBANDS * hIvasRend->sampleRateOut ) / 48000 ), tmpBinaural, 1, cldfb_in_flag, ( hIvasRend->outputConfig == IVAS_AUDIO_CONFIG_BINAURAL_SPLIT_PCM ) ? 1 : 0 ) ) != IVAS_ERR_OK ) +#endif { return error; } @@ -8248,6 +8276,18 @@ static ivas_error getSamplesInternal( } #endif +#ifdef SPLIT_EXT_REND_FIX_LIMITER_POS + if ( outAudio.config.is_cldfb == 0 ) + { +#ifndef DISABLE_LIMITER +#ifdef DEBUGGING + hIvasRend->numClipping += +#endif + limitRendererOutput( hIvasRend->hLimiter, outAudio.data, outAudio.config.numSamplesPerChannel, IVAS_LIMITER_THRESHOLD ); +#endif + } +#endif + /* update global cominbed orientation start index */ ivas_combined_orientation_update_start_index( hIvasRend->hCombinedOrientationData, outAudio.config.numSamplesPerChannel );