Loading lib_com/options.h +3 −1 Original line number Diff line number Diff line Loading @@ -158,6 +158,8 @@ #define SMOOTH_WITH_TRANS_DET #endif #define NOKIA_ADAPTIVE_BINAURAL_PROTOS /* ################## End DEVELOPMENT switches ######################### */ /* clang-format on */ #endif lib_rend/ivas_dirac_dec_binaural_functions.c +95 −0 Original line number Diff line number Diff line Loading @@ -54,6 +54,14 @@ #define IVAS_TDET_DUCK_MULT_FAC_PARA_BIN ( 2.0f ) #define IVAS_TDET_DUCK_MULT_FAC_PARA_BIN_LOW_BR ( 3.0f ) #ifdef NOKIA_ADAPTIVE_BINAURAL_PROTOS #define ADAPT_HTPROTO_IIR_FAC 0.95f #define ADAPT_HTPROTO_ILD_LIM_DB0 1.0f #define ADAPT_HTPROTO_ILD_LIM_DB1 4.0f #define ADAPT_HTPROTO_ROT_LIM_0 0.4f #define ADAPT_HTPROTO_ROT_LIM_1 0.8f #endif /*------------------------------------------------------------------------- * Local function prototypes *------------------------------------------------------------------------*/ Loading @@ -68,6 +76,10 @@ static void ivas_dirac_dec_binaural_determine_processing_matrices( Decoder_Struc static void ivas_dirac_dec_binaural_process_output( Decoder_Struct *st_ivas, float output_f[][L_FRAME48k], float inRe[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], float inIm[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], const int16_t max_band_decorr, const uint8_t numInputChannels, const uint8_t firstSlot, const uint8_t slotEnd ); #ifdef NOKIA_ADAPTIVE_BINAURAL_PROTOS static void adaptTransportSignalsHeadtracked( HEAD_TRACK_DATA_HANDLE hHeadTrackData, float inIm[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], float inRe[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], const uint8_t firstSlot, const uint8_t slotEnd, const uint8_t nBins, float Rmat[3][3] ); #endif static void ivas_dirac_dec_binaural_check_and_switch_transports_headtracked( HEAD_TRACK_DATA_HANDLE hHeadTrackData, float inIm[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], float inRe[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], const uint8_t firstSlot, const uint8_t slotEnd, const uint8_t nBins, float Rmat[3][3] ); static void formulate2x2MixingMatrix( float Ein1, float Ein2, float CinRe, float CinIm, float Eout1, float Eout2, float CoutRe, float CoutIm, float Q[BINAURAL_CHANNELS][BINAURAL_CHANNELS], float Mre[BINAURAL_CHANNELS][BINAURAL_CHANNELS], float Mim[BINAURAL_CHANNELS][BINAURAL_CHANNELS], const float regularizationFactor ); Loading Loading @@ -562,6 +574,10 @@ static void ivas_dirac_dec_binaural_internal( if ( nchan_transport == 2 ) { #ifdef NOKIA_ADAPTIVE_BINAURAL_PROTOS adaptTransportSignalsHeadtracked( st_ivas->hHeadTrackData, Cldfb_RealBuffer_in, Cldfb_ImagBuffer_in, firstSlot, slotEnd, nBins, Rmat ); #endif ivas_dirac_dec_binaural_check_and_switch_transports_headtracked( st_ivas->hHeadTrackData, Cldfb_ImagBuffer_in, Cldfb_RealBuffer_in, firstSlot, slotEnd, nBins, Rmat ); } } Loading Loading @@ -1332,6 +1348,85 @@ static void ivas_dirac_dec_binaural_process_output( } #ifdef NOKIA_ADAPTIVE_BINAURAL_PROTOS static void adaptTransportSignalsHeadtracked( HEAD_TRACK_DATA_HANDLE hHeadTrackData, float inIm[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], float inRe[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], const uint8_t firstSlot, const uint8_t slotEnd, const uint8_t nBins, float Rmat[3][3] ) { int16_t slot, ch, bin, louderCh; float re[2], im[2], ILD, mono_factor_ILD, mono_factor_rotation, mono_factor, y_val; float proc_re[2], proc_im[2], sum_re, sum_im, ene_proc, ene_target, mf; /* Determine head-orientation-based mono factor. Rmat[1][1] entry informs how close the ears are aligned according to transport signals. */ y_val = 1.0f - fabsf( Rmat[1][1] ); mono_factor_rotation = ( y_val - ADAPT_HTPROTO_ROT_LIM_0 ) / ( ADAPT_HTPROTO_ROT_LIM_1 - ADAPT_HTPROTO_ROT_LIM_0 ); mono_factor_rotation = fmaxf( 0.0f, fminf( 1.0f, mono_factor_rotation ) ); /* Adapt transport signals in frequency bands */ for ( slot = firstSlot; slot < slotEnd; slot++ ) { float eqVal[60]; for ( bin = 0; bin < nBins; bin++ ) { /* Determine channel energies */ for ( ch = 0; ch < 2; ch++ ) { re[ch] = inRe[ch][slot][bin]; im[ch] = inIm[ch][slot][bin]; hHeadTrackData->chEneIIR[ch][bin] *= ADAPT_HTPROTO_IIR_FAC; hHeadTrackData->chEneIIR[ch][bin] += ( 1.0f - ADAPT_HTPROTO_IIR_FAC ) * ( ( re[ch] * re[ch] ) + ( im[ch] * im[ch] ) ); } /* Determine ILD */ ILD = fabsf( 10.0f * log10f( fmaxf( 1e-12f, hHeadTrackData->chEneIIR[0][bin] ) / fmaxf( 1e-12f, hHeadTrackData->chEneIIR[1][bin] ) ) ); louderCh = ( hHeadTrackData->chEneIIR[1][bin] > hHeadTrackData->chEneIIR[0][bin] ); /* Determine ILD-based mono factor */ mono_factor_ILD = ( ILD - ADAPT_HTPROTO_ILD_LIM_DB0 ) / ( ADAPT_HTPROTO_ILD_LIM_DB1 - ADAPT_HTPROTO_ILD_LIM_DB0 ); mono_factor_ILD = fmaxf( 0.0f, fminf( 1.0f, mono_factor_ILD ) ); /* Combine mono factors */ mono_factor = mono_factor_ILD * mono_factor_rotation; /* Mix original audio and sum signal according to determined mono factor */ sum_re = re[0] + re[1]; sum_im = im[0] + im[1]; for ( ch = 0; ch < 2; ch++ ) { mf = ( ch == louderCh ) ? 0.0f : mono_factor; proc_re[ch] = mf * sum_re + ( 1.0f - mf ) * re[ch]; proc_im[ch] = mf * sum_im + ( 1.0f - mf ) * im[ch]; hHeadTrackData->procChEneIIR[ch][bin] *= ADAPT_HTPROTO_IIR_FAC; hHeadTrackData->procChEneIIR[ch][bin] += ( 1.0f - ADAPT_HTPROTO_IIR_FAC ) * ( ( proc_re[ch] * proc_re[ch] ) + ( proc_im[ch] * proc_im[ch] ) ); } /* Equalize */ ene_target = hHeadTrackData->chEneIIR[0][bin] + hHeadTrackData->chEneIIR[1][bin]; ene_proc = hHeadTrackData->procChEneIIR[0][bin] + hHeadTrackData->procChEneIIR[1][bin]; eqVal[bin] = fminf( 4.0f, sqrtf( ene_target / fmaxf( 1e-12f, ene_proc ) ) ); for ( ch = 0; ch < 2; ch++ ) { inRe[ch][slot][bin] = proc_re[ch] * eqVal[bin]; inIm[ch][slot][bin] = proc_im[ch] * eqVal[bin]; } } } return; } #endif static void ivas_dirac_dec_binaural_check_and_switch_transports_headtracked( HEAD_TRACK_DATA_HANDLE hHeadTrackData, float inIm[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], Loading lib_rend/ivas_hrtf.c +7 −0 Original line number Diff line number Diff line Loading @@ -235,5 +235,12 @@ ivas_error ivas_headTrack_open( ( *hHeadTrackData )->Rmat_prev[i][i] = 1.0f; } #ifdef NOKIA_ADAPTIVE_BINAURAL_PROTOS set_zero( ( *hHeadTrackData )->chEneIIR[0], CLDFB_NO_CHANNELS_MAX ); set_zero( ( *hHeadTrackData )->chEneIIR[1], CLDFB_NO_CHANNELS_MAX ); set_zero( ( *hHeadTrackData )->procChEneIIR[0], CLDFB_NO_CHANNELS_MAX ); set_zero( ( *hHeadTrackData )->procChEneIIR[1], CLDFB_NO_CHANNELS_MAX ); #endif return IVAS_ERR_OK; } lib_rend/ivas_stat_rend.h +5 −0 Original line number Diff line number Diff line Loading @@ -245,6 +245,11 @@ typedef struct ivas_binaural_head_track_struct uint8_t lrSwitchedCurrent; float lrSwitchInterpVal; #ifdef NOKIA_ADAPTIVE_BINAURAL_PROTOS float chEneIIR[2][CLDFB_NO_CHANNELS_MAX]; float procChEneIIR[2][CLDFB_NO_CHANNELS_MAX]; #endif int16_t shd_rot_max_order; } HEAD_TRACK_DATA, *HEAD_TRACK_DATA_HANDLE; Loading lib_dec/ivas_stat_dec.h +2 −2 File changed.Contains only whitespace changes. Show changes Loading
lib_com/options.h +3 −1 Original line number Diff line number Diff line Loading @@ -158,6 +158,8 @@ #define SMOOTH_WITH_TRANS_DET #endif #define NOKIA_ADAPTIVE_BINAURAL_PROTOS /* ################## End DEVELOPMENT switches ######################### */ /* clang-format on */ #endif
lib_rend/ivas_dirac_dec_binaural_functions.c +95 −0 Original line number Diff line number Diff line Loading @@ -54,6 +54,14 @@ #define IVAS_TDET_DUCK_MULT_FAC_PARA_BIN ( 2.0f ) #define IVAS_TDET_DUCK_MULT_FAC_PARA_BIN_LOW_BR ( 3.0f ) #ifdef NOKIA_ADAPTIVE_BINAURAL_PROTOS #define ADAPT_HTPROTO_IIR_FAC 0.95f #define ADAPT_HTPROTO_ILD_LIM_DB0 1.0f #define ADAPT_HTPROTO_ILD_LIM_DB1 4.0f #define ADAPT_HTPROTO_ROT_LIM_0 0.4f #define ADAPT_HTPROTO_ROT_LIM_1 0.8f #endif /*------------------------------------------------------------------------- * Local function prototypes *------------------------------------------------------------------------*/ Loading @@ -68,6 +76,10 @@ static void ivas_dirac_dec_binaural_determine_processing_matrices( Decoder_Struc static void ivas_dirac_dec_binaural_process_output( Decoder_Struct *st_ivas, float output_f[][L_FRAME48k], float inRe[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], float inIm[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], const int16_t max_band_decorr, const uint8_t numInputChannels, const uint8_t firstSlot, const uint8_t slotEnd ); #ifdef NOKIA_ADAPTIVE_BINAURAL_PROTOS static void adaptTransportSignalsHeadtracked( HEAD_TRACK_DATA_HANDLE hHeadTrackData, float inIm[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], float inRe[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], const uint8_t firstSlot, const uint8_t slotEnd, const uint8_t nBins, float Rmat[3][3] ); #endif static void ivas_dirac_dec_binaural_check_and_switch_transports_headtracked( HEAD_TRACK_DATA_HANDLE hHeadTrackData, float inIm[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], float inRe[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], const uint8_t firstSlot, const uint8_t slotEnd, const uint8_t nBins, float Rmat[3][3] ); static void formulate2x2MixingMatrix( float Ein1, float Ein2, float CinRe, float CinIm, float Eout1, float Eout2, float CoutRe, float CoutIm, float Q[BINAURAL_CHANNELS][BINAURAL_CHANNELS], float Mre[BINAURAL_CHANNELS][BINAURAL_CHANNELS], float Mim[BINAURAL_CHANNELS][BINAURAL_CHANNELS], const float regularizationFactor ); Loading Loading @@ -562,6 +574,10 @@ static void ivas_dirac_dec_binaural_internal( if ( nchan_transport == 2 ) { #ifdef NOKIA_ADAPTIVE_BINAURAL_PROTOS adaptTransportSignalsHeadtracked( st_ivas->hHeadTrackData, Cldfb_RealBuffer_in, Cldfb_ImagBuffer_in, firstSlot, slotEnd, nBins, Rmat ); #endif ivas_dirac_dec_binaural_check_and_switch_transports_headtracked( st_ivas->hHeadTrackData, Cldfb_ImagBuffer_in, Cldfb_RealBuffer_in, firstSlot, slotEnd, nBins, Rmat ); } } Loading Loading @@ -1332,6 +1348,85 @@ static void ivas_dirac_dec_binaural_process_output( } #ifdef NOKIA_ADAPTIVE_BINAURAL_PROTOS static void adaptTransportSignalsHeadtracked( HEAD_TRACK_DATA_HANDLE hHeadTrackData, float inIm[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], float inRe[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], const uint8_t firstSlot, const uint8_t slotEnd, const uint8_t nBins, float Rmat[3][3] ) { int16_t slot, ch, bin, louderCh; float re[2], im[2], ILD, mono_factor_ILD, mono_factor_rotation, mono_factor, y_val; float proc_re[2], proc_im[2], sum_re, sum_im, ene_proc, ene_target, mf; /* Determine head-orientation-based mono factor. Rmat[1][1] entry informs how close the ears are aligned according to transport signals. */ y_val = 1.0f - fabsf( Rmat[1][1] ); mono_factor_rotation = ( y_val - ADAPT_HTPROTO_ROT_LIM_0 ) / ( ADAPT_HTPROTO_ROT_LIM_1 - ADAPT_HTPROTO_ROT_LIM_0 ); mono_factor_rotation = fmaxf( 0.0f, fminf( 1.0f, mono_factor_rotation ) ); /* Adapt transport signals in frequency bands */ for ( slot = firstSlot; slot < slotEnd; slot++ ) { float eqVal[60]; for ( bin = 0; bin < nBins; bin++ ) { /* Determine channel energies */ for ( ch = 0; ch < 2; ch++ ) { re[ch] = inRe[ch][slot][bin]; im[ch] = inIm[ch][slot][bin]; hHeadTrackData->chEneIIR[ch][bin] *= ADAPT_HTPROTO_IIR_FAC; hHeadTrackData->chEneIIR[ch][bin] += ( 1.0f - ADAPT_HTPROTO_IIR_FAC ) * ( ( re[ch] * re[ch] ) + ( im[ch] * im[ch] ) ); } /* Determine ILD */ ILD = fabsf( 10.0f * log10f( fmaxf( 1e-12f, hHeadTrackData->chEneIIR[0][bin] ) / fmaxf( 1e-12f, hHeadTrackData->chEneIIR[1][bin] ) ) ); louderCh = ( hHeadTrackData->chEneIIR[1][bin] > hHeadTrackData->chEneIIR[0][bin] ); /* Determine ILD-based mono factor */ mono_factor_ILD = ( ILD - ADAPT_HTPROTO_ILD_LIM_DB0 ) / ( ADAPT_HTPROTO_ILD_LIM_DB1 - ADAPT_HTPROTO_ILD_LIM_DB0 ); mono_factor_ILD = fmaxf( 0.0f, fminf( 1.0f, mono_factor_ILD ) ); /* Combine mono factors */ mono_factor = mono_factor_ILD * mono_factor_rotation; /* Mix original audio and sum signal according to determined mono factor */ sum_re = re[0] + re[1]; sum_im = im[0] + im[1]; for ( ch = 0; ch < 2; ch++ ) { mf = ( ch == louderCh ) ? 0.0f : mono_factor; proc_re[ch] = mf * sum_re + ( 1.0f - mf ) * re[ch]; proc_im[ch] = mf * sum_im + ( 1.0f - mf ) * im[ch]; hHeadTrackData->procChEneIIR[ch][bin] *= ADAPT_HTPROTO_IIR_FAC; hHeadTrackData->procChEneIIR[ch][bin] += ( 1.0f - ADAPT_HTPROTO_IIR_FAC ) * ( ( proc_re[ch] * proc_re[ch] ) + ( proc_im[ch] * proc_im[ch] ) ); } /* Equalize */ ene_target = hHeadTrackData->chEneIIR[0][bin] + hHeadTrackData->chEneIIR[1][bin]; ene_proc = hHeadTrackData->procChEneIIR[0][bin] + hHeadTrackData->procChEneIIR[1][bin]; eqVal[bin] = fminf( 4.0f, sqrtf( ene_target / fmaxf( 1e-12f, ene_proc ) ) ); for ( ch = 0; ch < 2; ch++ ) { inRe[ch][slot][bin] = proc_re[ch] * eqVal[bin]; inIm[ch][slot][bin] = proc_im[ch] * eqVal[bin]; } } } return; } #endif static void ivas_dirac_dec_binaural_check_and_switch_transports_headtracked( HEAD_TRACK_DATA_HANDLE hHeadTrackData, float inIm[][CLDFB_NO_COL_MAX][CLDFB_NO_CHANNELS_MAX], Loading
lib_rend/ivas_hrtf.c +7 −0 Original line number Diff line number Diff line Loading @@ -235,5 +235,12 @@ ivas_error ivas_headTrack_open( ( *hHeadTrackData )->Rmat_prev[i][i] = 1.0f; } #ifdef NOKIA_ADAPTIVE_BINAURAL_PROTOS set_zero( ( *hHeadTrackData )->chEneIIR[0], CLDFB_NO_CHANNELS_MAX ); set_zero( ( *hHeadTrackData )->chEneIIR[1], CLDFB_NO_CHANNELS_MAX ); set_zero( ( *hHeadTrackData )->procChEneIIR[0], CLDFB_NO_CHANNELS_MAX ); set_zero( ( *hHeadTrackData )->procChEneIIR[1], CLDFB_NO_CHANNELS_MAX ); #endif return IVAS_ERR_OK; }
lib_rend/ivas_stat_rend.h +5 −0 Original line number Diff line number Diff line Loading @@ -245,6 +245,11 @@ typedef struct ivas_binaural_head_track_struct uint8_t lrSwitchedCurrent; float lrSwitchInterpVal; #ifdef NOKIA_ADAPTIVE_BINAURAL_PROTOS float chEneIIR[2][CLDFB_NO_CHANNELS_MAX]; float procChEneIIR[2][CLDFB_NO_CHANNELS_MAX]; #endif int16_t shd_rot_max_order; } HEAD_TRACK_DATA, *HEAD_TRACK_DATA_HANDLE; Loading