diff --git a/lib_com/options.h b/lib_com/options.h index 5ef2fe4f5c4e6d683cec5c0b337ef01707234237..4c6109723b038344e32550192f5030734050ec02 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -85,7 +85,7 @@ #define FIX_1980_CRASH_FDCNG_ENCODESID /* FhG: Add one bit of headroom in e_fx calculation in FdCng_encodeSID_ivas_fx() */ #define FIX_1987_CRASH_OMASA_ENERGY /* FhG: Replace cldfbAnalysis_ts_fx_fix_q() with cldfbAnalysis_ts_fx_var_q() to avoid assertion error */ #define FIX_1985_SBA_714_HF_LOSS /* Dlb: Fix for issue 1985, improved dirac ref pow precision*/ - +#define FIX_1819_EIGENVALUE_ERROR /* FhG: Workaround for zero eigenvalue: replace with epsilon if det != 0*/ /* #################### Start BASOP porting switches ############################ */ #define NONBE_1244_FIX_SWB_BWE_MEMORY /* VA: issue 1244: fix to SWB BWE memory in case of switching from FB coding - pending a review by Huawei */ diff --git a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c index f81fa0d3dcde3a47ebb7307f3f99f4ad25dfe4d4..be1f5b9ce463ecc7f52917e75533d6099d5ae4b6 100644 --- a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c +++ b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c @@ -76,6 +76,10 @@ Word16 slot_fx[4] = { 32767, 16384, 10922, 8192 }; #define ONE_DIV_EPSILON_EXP ( 40 ) #define ADAPT_HTPROTO_ROT_LIM_1 0.8f +#ifdef FIX_1819_EIGENVALUE_ERROR +#define SMALL_EIGENVALUE 50 +#endif + #define MAX_GAIN_CACHE_SIZE ( ( MASA_MAXIMUM_DIRECTIONS * 3 ) + MAX_NUM_OBJECTS ) /* == different calls to get gains */ typedef struct hrtfGainCache @@ -4557,6 +4561,20 @@ static void formulate2x2MixingMatrix_fx( eig2x2_fx( tmpRe_fx[0][0], tmpRe_fx[1][1], q_temp, tmpRe_fx[1][0], tmpIm_fx[1][0], q_temp, Ure_fx, Uim_fx, &q_U, D_fx, &q_D ); +#ifdef FIX_1819_EIGENVALUE_ERROR + IF( D_fx[0] != 0 && D_fx[1] == 0 ) // Due to an eig2x2 error, sometimes D_fx[1] becomes zero, which implies that the input matrix should be singular (i.e., determinant = 0). + { + Word32 det_fx = L_sub_sat( Mult_32_32( tmpRe_fx[0][0], tmpRe_fx[1][1] ), + L_add_sat( + Mult_32_32( tmpRe_fx[1][0], tmpRe_fx[1][0] ), + Mult_32_32( tmpIm_fx[1][0], tmpIm_fx[1][0] ) ) ); + if ( det_fx != 0 ) + { + D_fx[1] = SMALL_EIGENVALUE; // Setting D_fx[1] to epsilon has no effect, as the value is too small to affect the output. + move32(); + } + } +#endif IF( D_fx[0] == 0 ) { temp = ONE_DIV_EPSILON_MANT; /* Result of 1.0/eps with full precision */