diff --git a/lib_com/ivas_prot.h b/lib_com/ivas_prot.h index 88ddd63edc3393693fd97e07dea2e8a6aa4e14cd..5d4faf0eb0e247cba971677498011e6e9755ebdc 100644 --- a/lib_com/ivas_prot.h +++ b/lib_com/ivas_prot.h @@ -1559,6 +1559,10 @@ int16_t read_BS_adapt_GR_sg( void stereo_dft_hybrid_ITD_flag( STEREO_DFT_CONFIG_DATA_HANDLE hConfig, /* o : DFT stereo configuration */ const int32_t input_Fs /* i : CPE element sampling rate */ +#ifdef HYBRID_ITD_MAX + , + const int16_t hybrid_itd_max /* i : flag for hybrid ITD for very large ITDs */ +#endif ); void stereo_dft_enc_compute_itd( diff --git a/lib_com/options.h b/lib_com/options.h index 77fe75096d82188105ab9065fc13264b8e461df9..4150e91a5df06f3aa0a6f9e1ac1f49acd6ffdc11 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -218,6 +218,9 @@ #define FIX_DIRAC_LS_SYNTHESIS_CONFIG_479 /* FhG: fix for issue 479, broken LS output with DirAC at high BRs */ +#define HYBRID_ITD_MAX /* FhG: Improvement for DFT-stereo for cases with large ITDs */ + + /* ################## End DEVELOPMENT switches ######################### */ /* clang-format on */ diff --git a/lib_enc/ivas_cpe_enc.c b/lib_enc/ivas_cpe_enc.c index b60f8be45b3807ced769a80dbe65b106df875963..522cfb885de6f90d12fb2fa4b9389cba04a1c121 100644 --- a/lib_enc/ivas_cpe_enc.c +++ b/lib_enc/ivas_cpe_enc.c @@ -333,7 +333,12 @@ ivas_error ivas_cpe_enc( if ( hCPE->element_mode == IVAS_CPE_DFT ) { - stereo_dft_hybrid_ITD_flag( hCPE->hStereoDft->hConfig, input_Fs ); + stereo_dft_hybrid_ITD_flag( hCPE->hStereoDft->hConfig, input_Fs +#ifdef HYBRID_ITD_MAX + , + hCPE->hStereoDft->hItd->hybrid_itd_max +#endif + ); /* Time Domain ITD compensation using extrapolation */ #ifdef DEBUG_MODE_DFT diff --git a/lib_enc/ivas_stat_enc.h b/lib_enc/ivas_stat_enc.h index 58b77976621fb97676c96b1d46a1951fe229e122..07cdae30b7dc7736a356ce047eb569abc38eb584 100644 --- a/lib_enc/ivas_stat_enc.h +++ b/lib_enc/ivas_stat_enc.h @@ -81,6 +81,10 @@ typedef struct stereo_itd_data_struct int16_t prev_itd1; int16_t prev_itd2; +#ifdef HYBRID_ITD_MAX + /*flag for hybrid ITD for very large ITDs*/ + int16_t hybrid_itd_max; +#endif } ITD_DATA, *ITD_DATA_HANDLE; typedef struct dft_ana_struct diff --git a/lib_enc/ivas_stereo_dft_enc.c b/lib_enc/ivas_stereo_dft_enc.c index 43546261a41b954622c9bdaa07ef0bee191c2072..dbc06622554a01af8246712094ef87be2d10d0e5 100644 --- a/lib_enc/ivas_stereo_dft_enc.c +++ b/lib_enc/ivas_stereo_dft_enc.c @@ -294,9 +294,16 @@ ivas_error stereo_dft_enc_create( hStereoDft_loc->hConfig->force_mono_transmission = 0; stereo_dft_config( hStereoDft_loc->hConfig, IVAS_24k4, &tmpS, &tmpS ); - stereo_dft_hybrid_ITD_flag( hStereoDft_loc->hConfig, input_Fs ); + stereo_dft_enc_open( hStereoDft_loc, input_Fs, max_bwidth ); + stereo_dft_hybrid_ITD_flag( hStereoDft_loc->hConfig, input_Fs +#ifdef HYBRID_ITD_MAX + , + hStereoDft_loc->hItd->hybrid_itd_max +#endif + ); + *hStereoDft = hStereoDft_loc; return IVAS_ERR_OK; @@ -560,6 +567,9 @@ void stereo_enc_itd_init( hItd->prev_itd1 = 0; hItd->prev_itd2 = 0; +#ifdef HYBRID_ITD_MAX + hItd->hybrid_itd_max = 0; +#endif return; } diff --git a/lib_enc/ivas_stereo_dft_enc_itd.c b/lib_enc/ivas_stereo_dft_enc_itd.c index d2c0bc7fe1ec78ae00051af7f280b97fe93c1d2a..025729e0cdc3832e6487d73f76e1f8781f275130 100644 --- a/lib_enc/ivas_stereo_dft_enc_itd.c +++ b/lib_enc/ivas_stereo_dft_enc_itd.c @@ -115,11 +115,19 @@ static void set_band_limits( void stereo_dft_hybrid_ITD_flag( STEREO_DFT_CONFIG_DATA_HANDLE hConfig, /* o : DFT stereo configuration */ const int32_t input_Fs /* i : CPE element sampling rate */ +#ifdef HYBRID_ITD_MAX + , + const int16_t hybrid_itd_max /* i : flag for hybrid ITD for very large ITDs */ +#endif ) { if ( hConfig != NULL ) { - if ( hConfig->res_cod_mode || ( hConfig->ada_wb_res_cod_mode && input_Fs == 16000 ) ) + if ( hConfig->res_cod_mode || ( hConfig->ada_wb_res_cod_mode && input_Fs == 16000 ) +#ifdef HYBRID_ITD_MAX + || ( hybrid_itd_max == 1 ) +#endif + ) { hConfig->hybrid_itd_flag = 1; } @@ -642,6 +650,11 @@ void stereo_dft_enc_compute_itd( float cng_xcorr_filt; +#ifdef HYBRID_ITD_MAX + int16_t prev_itd_max; + int16_t itd_max_flip; +#endif + if ( hCPE->element_mode == IVAS_CPE_DFT ) { hStereoDft = hCPE->hStereoDft; @@ -1328,7 +1341,12 @@ void stereo_dft_enc_compute_itd( hItd->prev_sum_nrg_L_lb = sum_nrg_L_lb; mvr2r( xcorr_lb, hItd->prev_xcorr_lb, STEREO_DFT_XCORR_LB_MAX ); } - +#ifdef HYBRID_ITD_MAX + /*save previous flag*/ + prev_itd_max = hItd->hybrid_itd_max; + /* enable hybrid ITD handling for very large ITDs*/ + hItd->hybrid_itd_max = ( abs( itd ) > STEREO_DFT_ITD_MAX && abs( itd ) < STEREO_DFT_ITD_MAX_ANA && !hCPE->hCoreCoder[0]->sp_aud_decision0 && hCPE->element_brate < IVAS_32k ); +#endif /* Update memory */ hItd->prev_itd = itd; @@ -1343,7 +1361,7 @@ void stereo_dft_enc_compute_itd( #ifdef DEBUG_STEREO_CLF dbgwrite( &hItd->itd[k_offset], sizeof( float ), 1, 1, "res/ITD.x" ); #endif - + /* limit ITD range for MDCT stereo even more */ if ( hCPE->element_mode == IVAS_CPE_MDCT && fabsf( hItd->itd[k_offset] ) > ITD_MAX_MDCT ) { itd = 0; @@ -1353,7 +1371,25 @@ void stereo_dft_enc_compute_itd( hItd->deltaItd[k_offset] = hItd->itd[k_offset] - hItd->td_itd[k_offset]; - /* limit ITD range for MDCT stereo even more */ +#ifdef HYBRID_ITD_MAX + if ( hItd->hybrid_itd_max ) + { + /*check if there is an ITD flip*/ + itd_max_flip = ( hItd->itd[k_offset] * hItd->itd[k_offset - 1] < 0 ); + + if ( hItd->deltaItd[k_offset - 1] != 0 && itd_max_flip == 0 ) + { + int16_t tmp_itd = (int16_t) floor( ( ( hItd->prev_itd ) * ( (float) input_frame / 640 ) ) + 0.5f ); + hItd->deltaItd[k_offset] = -1.0f * tmp_itd - hItd->td_itd[k_offset]; + } + } + /*signal change for next frame*/ + if ( prev_itd_max == 1 && hItd->hybrid_itd_max == 0 ) + { + hItd->hybrid_itd_max = -1; + } +#endif + #ifdef DEBUG_MODE_DFT { int16_t tmp; diff --git a/lib_enc/ivas_stereo_dft_td_itd.c b/lib_enc/ivas_stereo_dft_td_itd.c index b7fb95422f3136080892b0df097b65719ef747c6..27a71dfae477f0d3702d266163887e9204d73f00 100644 --- a/lib_enc/ivas_stereo_dft_td_itd.c +++ b/lib_enc/ivas_stereo_dft_td_itd.c @@ -271,11 +271,18 @@ void stereo_td_itd( hITD->td_itd_32k[i] = hITD->td_itd_32k[i + 1]; } } +#ifdef HYBRID_ITD_MAX + /*reset TD ITDs in case of hybrid itd_max change - turn hybrid ITD off*/ + if ( hITD->hybrid_itd_max == -1 && hybrid_itd_flag == 0 ) + { + hITD->td_itd[k_offset] = 0; + hITD->td_itd_32k[k_offset] = 0; + } +#endif if ( hybrid_itd_flag == 0 ) { return; } - stereo_td_get_td_itd( &( hITD->td_itd[k_offset] ), &( hITD->td_itd_32k[k_offset] ), hITD->itd[k_offset], sts[0]->input_Fs ); /* initializations*/