From eb67ffb1702aa8401cef4589f888f18a8474a420 Mon Sep 17 00:00:00 2001 From: Nicolas Roussin Date: Mon, 3 Nov 2025 18:37:41 +0000 Subject: [PATCH 1/3] Move scale operations outside mul operations. --- lib_com/options.h | 1 + .../ivas_dirac_dec_binaural_functions_fx.c | 83 ++++++++++++++++++- 2 files changed, 83 insertions(+), 1 deletion(-) diff --git a/lib_com/options.h b/lib_com/options.h index 729e366af..c6c962f3d 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -141,6 +141,7 @@ /* #################### Start BASOP optimization switches ############################ */ #define OPT_2181_MATRIX_TRANSP_1_MUL /* Dolby: Issue 2181, optimize matrixTransp1Mul_fx. */ +#define OPT_2182_MATRIX_SCALE_OPS /* Dolby: Issue 2181, move matrix scale operations outside mul operations. */ /* #################### End BASOP optimization switches ############################ */ diff --git a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c index fda10d47c..fb8a12a29 100644 --- a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c +++ b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c @@ -118,9 +118,17 @@ static void ivas_masa_ext_rend_parambin_internal_fx( MASA_EXT_REND_HANDLE hMasaE static void formulate2x2MixingMatrix_fx( Word32 Ein1_fx /*q_Ein*/, Word32 Ein2_fx /*q_Ein*/, Word16 q_Ein, Word32 CinRe_fx /*q_Cin*/, Word32 CinIm_fx /*q_Cin*/, Word16 q_Cin, Word32 Eout1_fx /*q_Eout*/, Word32 Eout2_fx /*q_Eout*/, Word16 q_Eout, Word32 CoutRe_fx /*q_Cout*/, Word32 CoutIm_fx /*q_Cout*/, Word16 q_Cout, Word32 Q_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS] /*Q31*/, Word32 Mre_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS] /*q_M*/, Word32 Mim_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS] /*q_M*/, Word16 *q_M, const Word16 regularizationFactor_fx /*Q14*/ ); +#ifdef OPT_2182_MATRIX_SCALE_OPS +static void matrixScale_fx( Word32 Are_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS] /*q_A*/, Word32 Aim_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS] /*q_A*/, Word16 *q_A ); +#endif + static void matrixMul_fx( Word32 Are[BINAURAL_CHANNELS][BINAURAL_CHANNELS] /*q_A*/, Word32 Aim[BINAURAL_CHANNELS][BINAURAL_CHANNELS] /*q_A*/, Word16 *q_A, Word32 Bre[BINAURAL_CHANNELS][BINAURAL_CHANNELS] /*q_B*/, Word32 Bim[BINAURAL_CHANNELS][BINAURAL_CHANNELS] /*q_B*/, Word16 *q_B, Word32 outRe[BINAURAL_CHANNELS][BINAURAL_CHANNELS] /*q_out*/, Word32 outIm[BINAURAL_CHANNELS][BINAURAL_CHANNELS] /*q_out*/, Word16 *q_out ); +#ifdef OPT_2182_MATRIX_SCALE_OPS +static void matrixTransp2Mul_fx( Word32 Are[BINAURAL_CHANNELS][BINAURAL_CHANNELS] /*q_A*/, Word32 Aim[BINAURAL_CHANNELS][BINAURAL_CHANNELS] /*q_A*/, Word16 *q_A, Word32 Bre[BINAURAL_CHANNELS][BINAURAL_CHANNELS] /*q_B*/, Word32 Bim[BINAURAL_CHANNELS][BINAURAL_CHANNELS] /*q_B*/, Word16 *q_B, Word32 outRe[BINAURAL_CHANNELS][BINAURAL_CHANNELS] /*q_out*/, Word32 outIm[BINAURAL_CHANNELS][BINAURAL_CHANNELS] /*q_out*/, Word16 *q_out ); +#else static void matrixTransp2Mul_fx( Word32 Are[BINAURAL_CHANNELS][BINAURAL_CHANNELS] /*q_A*/, Word32 Aim[BINAURAL_CHANNELS][BINAURAL_CHANNELS] /*q_A*/, Word16 *q_A, Word32 Bre[BINAURAL_CHANNELS][BINAURAL_CHANNELS] /*q_B*/, Word32 Bim[BINAURAL_CHANNELS][BINAURAL_CHANNELS] /*q_B*/, Word16 *q_B, Word32 Ascale, Word32 Bscale, Word32 outRe[BINAURAL_CHANNELS][BINAURAL_CHANNELS] /*q_out*/, Word32 outIm[BINAURAL_CHANNELS][BINAURAL_CHANNELS] /*q_out*/, Word16 *q_out ); +#endif /*------------------------------------------------------------------------- @@ -2260,12 +2268,23 @@ static void ivas_dirac_dec_binaural_determine_processing_matrices_fx( } /* Make matrix multiplication M*Cx*M' to determine resulting covariance matrix of processing input with M */ +#ifdef OPT_2182_MATRIX_SCALE_OPS + matrixScale_fx( Mre_fx, Mim_fx, &q_M ); + matrixScale_fx( CxRe_fx, CxIm_fx, &q_Cx ); +#endif matrixMul_fx( Mre_fx, Mim_fx, &q_M, CxRe_fx, CxIm_fx, &q_Cx, tmpMtxRe_fx, tmpMtxIm_fx, &q_tmp ); +#ifdef OPT_2182_MATRIX_SCALE_OPS + matrixScale_fx( tmpMtxRe_fx, tmpMtxIm_fx, &q_tmp ); + matrixTransp2Mul_fx( + tmpMtxRe_fx, tmpMtxIm_fx, &q_tmp, Mre_fx, Mim_fx, &q_M, + resultMtxRe_fx, resultMtxIm_fx, &q_res ); +#else matrixTransp2Mul_fx( tmpMtxRe_fx, tmpMtxIm_fx, &q_tmp, Mre_fx, Mim_fx, &q_M, 1 /*int Ascale*/, 0 /*int Bscale*/, resultMtxRe_fx, resultMtxIm_fx, &q_res ); +#endif /* When below the frequency limit where decorrelation is applied, we inject the decorrelated * residual (or missing) signal component. The procedure is active when there are not enough independent @@ -3914,6 +3933,22 @@ static void matrixDiagMul_fx( return; } +#ifdef OPT_2182_MATRIX_SCALE_OPS +static void matrixScale_fx( + Word32 Are_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], /*q_A*/ + Word32 Aim_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], /*q_A*/ + Word16 *q_A ) +{ + Word16 shift; + Word16 size = i_mult( BINAURAL_CHANNELS, BINAURAL_CHANNELS ); + shift = sub( s_min( L_norm_arr( Are_fx[0], size ), L_norm_arr( Aim_fx[0], size ) ), 1 ); + scale_sig32( Are_fx[0], size, shift ); + scale_sig32( Aim_fx[0], size, shift ); + *q_A = add( *q_A, shift ); + move16(); +} +#endif + static void matrixMul_fx( Word32 Are_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], /*q_A*/ Word32 Aim_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], /*q_A*/ @@ -3925,6 +3960,10 @@ static void matrixMul_fx( Word32 outIm_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], /*q_out*/ Word16 *q_out ) { +#ifdef OPT_2182_MATRIX_SCALE_OPS + Word16 chA, chB; + Word16 size = i_mult( BINAURAL_CHANNELS, BINAURAL_CHANNELS ); +#else Word16 chA, chB; Word16 min_q_shift1, min_q_shift2; Word16 size = i_mult( BINAURAL_CHANNELS, BINAURAL_CHANNELS ); @@ -3941,6 +3980,7 @@ static void matrixMul_fx( *q_B = add( *q_B, min_q_shift2 ); move16(); move16(); +#endif FOR( chA = 0; chA < BINAURAL_CHANNELS; chA++ ) { @@ -4092,6 +4132,18 @@ static void matrixTransp1Mul_fx( return; } +#ifdef OPT_2182_MATRIX_SCALE_OPS +static void matrixTransp2Mul_fx( + Word32 Are_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], /*q_A*/ + Word32 Aim_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], /*q_A*/ + Word16 *q_A, + Word32 Bre_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], /*q_B*/ + Word32 Bim_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], /*q_B*/ + Word16 *q_B, + Word32 outRe_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], /*q_out*/ + Word32 outIm_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], /*q_out*/ + Word16 *q_out ) +#else static void matrixTransp2Mul_fx( Word32 Are_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], /*q_A*/ Word32 Aim_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], /*q_A*/ @@ -4104,7 +4156,12 @@ static void matrixTransp2Mul_fx( Word32 outRe_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], /*q_out*/ Word32 outIm_fx[BINAURAL_CHANNELS][BINAURAL_CHANNELS], /*q_out*/ Word16 *q_out ) +#endif { +#ifdef OPT_2182_MATRIX_SCALE_OPS + Word16 chA, chB; + Word16 size = BINAURAL_CHANNELS * BINAURAL_CHANNELS; +#else Word16 chA, chB; Word16 min_q_shift; Word16 size = BINAURAL_CHANNELS * BINAURAL_CHANNELS; @@ -4126,6 +4183,7 @@ static void matrixTransp2Mul_fx( *q_B = add( *q_B, min_q_shift ); move16(); } +#endif FOR( chA = 0; chA < BINAURAL_CHANNELS; chA++ ) { @@ -4663,6 +4721,10 @@ static void formulate2x2MixingMatrix_fx( q_temp = sub( add( q_ky, q_GhatQ ), 31 ); /* A = Ky' * G_hat * Q * Kx (see publication) */ +#ifdef OPT_2182_MATRIX_SCALE_OPS + matrixScale_fx( tmpRe_fx, tmpIm_fx, &q_temp ); + matrixScale_fx( Kxre_fx, Kxim_fx, &q_Kx ); +#endif matrixMul_fx( tmpRe_fx, tmpIm_fx, &q_temp, Kxre_fx, Kxim_fx, &q_Kx, Are_fx, Aim_fx, &q_A ); /* Find nearest orthonormal matrix P to A = Ky' * G_hat * Q * Kx @@ -4720,6 +4782,10 @@ static void formulate2x2MixingMatrix_fx( div_fx[0] = L_min( div_fx[0], thresh ); // q_div div_fx[1] = L_min( div_fx[1], thresh ); // q_div +#ifdef OPT_2182_MATRIX_SCALE_OPS + matrixScale_fx( Are_fx, Aim_fx, &q_A ); + matrixScale_fx( Ure_fx, Uim_fx, &q_U ); +#endif matrixMul_fx( Are_fx, Aim_fx, &q_A, Ure_fx, Uim_fx, &q_U, tmpRe_fx, tmpIm_fx, &q_temp ); exp = L_norm_arr( div_fx, BINAURAL_CHANNELS ); @@ -4783,10 +4849,15 @@ static void formulate2x2MixingMatrix_fx( } } +#ifdef OPT_2182_MATRIX_SCALE_OPS + matrixTransp2Mul_fx( tmpRe_fx, tmpIm_fx, &q_temp, Ure_fx, Uim_fx, &q_U, + Pre_fx, Pim_fx, &q_P ); /* Nearest orthonormal matrix P to matrix A formulated */ +#else matrixTransp2Mul_fx( tmpRe_fx, tmpIm_fx, &q_temp, Ure_fx, Uim_fx, &q_U, 0 /*int Ascale*/, 0 /*int Bscale*/, Pre_fx, Pim_fx, &q_P ); /* Nearest orthonormal matrix P to matrix A formulated */ +#endif /* These are the final formulas of the JAES publication M = Ky P Kx^(-1) */ #if ( BINAURAL_CHANNELS != 2 ) @@ -4917,12 +4988,22 @@ static void formulate2x2MixingMatrix_fx( } } +#ifdef OPT_2182_MATRIX_SCALE_OPS + matrixScale_fx( KyRe_fx, KyIm_fx, &q_ky ); + matrixScale_fx( Pre_fx, Pim_fx, &q_P ); +#endif matrixMul_fx( KyRe_fx, KyIm_fx, &q_ky, Pre_fx, Pim_fx, &q_P, tmpRe_fx, tmpIm_fx, &q_temp ); - +#ifdef OPT_2182_MATRIX_SCALE_OPS + matrixScale_fx( tmpRe_fx, tmpIm_fx, &q_temp ); + matrixTransp2Mul_fx( tmpRe_fx, tmpIm_fx, &q_temp, Uxre_fx, Uxim_fx, &q_Ux, + Mre_fx, Mim_fx, q_M ); +#else matrixTransp2Mul_fx( tmpRe_fx, tmpIm_fx, &q_temp, Uxre_fx, Uxim_fx, &q_Ux, 1 /*int Ascale*/, 0 /*int Bscale*/, Mre_fx, Mim_fx, q_M ); +#endif + return; } -- GitLab From 6fadb2b497f0910a4dfc72b8bfca1d1c9c32ab8f Mon Sep 17 00:00:00 2001 From: Nicolas Roussin Date: Mon, 10 Nov 2025 10:53:10 +0000 Subject: [PATCH 2/3] Address Thomas Dettbarn's comments. --- .../ivas_dirac_dec_binaural_functions_fx.c | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c index 19c12a3ec..7a7ad9292 100644 --- a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c +++ b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c @@ -2300,7 +2300,8 @@ static void ivas_dirac_dec_binaural_determine_processing_matrices_fx( #ifdef OPT_2182_MATRIX_SCALE_OPS matrixScale_fx( tmpMtxRe_fx, tmpMtxIm_fx, &q_tmp ); matrixTransp2Mul_fx( - tmpMtxRe_fx, tmpMtxIm_fx, &q_tmp, Mre_fx, Mim_fx, &q_M, + tmpMtxRe_fx, tmpMtxIm_fx, &q_tmp, + Mre_fx, Mim_fx, &q_M, resultMtxRe_fx, resultMtxIm_fx, &q_res ); #else matrixTransp2Mul_fx( @@ -3964,7 +3965,7 @@ static void matrixScale_fx( Word16 *q_A ) { Word16 shift; - Word16 size = i_mult( BINAURAL_CHANNELS, BINAURAL_CHANNELS ); + Word16 size = BINAURAL_CHANNELS * BINAURAL_CHANNELS; shift = sub( s_min( L_norm_arr( Are_fx[0], size ), L_norm_arr( Aim_fx[0], size ) ), 1 ); scale_sig32( Are_fx[0], size, shift ); scale_sig32( Aim_fx[0], size, shift ); @@ -3986,7 +3987,7 @@ static void matrixMul_fx( { #ifdef OPT_2182_MATRIX_SCALE_OPS Word16 chA, chB; - Word16 size = i_mult( BINAURAL_CHANNELS, BINAURAL_CHANNELS ); + Word16 size = BINAURAL_CHANNELS * BINAURAL_CHANNELS; #else Word16 chA, chB; Word16 min_q_shift1, min_q_shift2; @@ -4874,8 +4875,10 @@ static void formulate2x2MixingMatrix_fx( } #ifdef OPT_2182_MATRIX_SCALE_OPS - matrixTransp2Mul_fx( tmpRe_fx, tmpIm_fx, &q_temp, Ure_fx, Uim_fx, &q_U, - Pre_fx, Pim_fx, &q_P ); /* Nearest orthonormal matrix P to matrix A formulated */ + matrixTransp2Mul_fx( + tmpRe_fx, tmpIm_fx, &q_temp, + Ure_fx, Uim_fx, &q_U, + Pre_fx, Pim_fx, &q_P ); /* Nearest orthonormal matrix P to matrix A formulated */ #else matrixTransp2Mul_fx( tmpRe_fx, tmpIm_fx, &q_temp, Ure_fx, Uim_fx, &q_U, 0 /*int Ascale*/, @@ -5019,8 +5022,10 @@ static void formulate2x2MixingMatrix_fx( matrixMul_fx( KyRe_fx, KyIm_fx, &q_ky, Pre_fx, Pim_fx, &q_P, tmpRe_fx, tmpIm_fx, &q_temp ); #ifdef OPT_2182_MATRIX_SCALE_OPS matrixScale_fx( tmpRe_fx, tmpIm_fx, &q_temp ); - matrixTransp2Mul_fx( tmpRe_fx, tmpIm_fx, &q_temp, Uxre_fx, Uxim_fx, &q_Ux, - Mre_fx, Mim_fx, q_M ); + matrixTransp2Mul_fx( + tmpRe_fx, tmpIm_fx, &q_temp, + Uxre_fx, Uxim_fx, &q_Ux, + Mre_fx, Mim_fx, q_M ); #else matrixTransp2Mul_fx( tmpRe_fx, tmpIm_fx, &q_temp, Uxre_fx, Uxim_fx, &q_Ux, 1 /*int Ascale*/, -- GitLab From d232e69f3609e89c375fa0fc7136f772e41670e4 Mon Sep 17 00:00:00 2001 From: Nicolas Roussin Date: Mon, 1 Dec 2025 11:18:57 +0000 Subject: [PATCH 3/3] Apply clang format. --- lib_rend/ivas_dirac_dec_binaural_functions_fx.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c index a243a9105..e0c49cf20 100644 --- a/lib_rend/ivas_dirac_dec_binaural_functions_fx.c +++ b/lib_rend/ivas_dirac_dec_binaural_functions_fx.c @@ -4823,8 +4823,8 @@ static void formulate2x2MixingMatrix_fx( } #ifdef OPT_2182_MATRIX_SCALE_OPS - matrixTransp2Mul_fx( - tmpRe_fx, tmpIm_fx, &q_temp, + matrixTransp2Mul_fx( + tmpRe_fx, tmpIm_fx, &q_temp, Ure_fx, Uim_fx, &q_U, Pre_fx, Pim_fx, &q_P ); /* Nearest orthonormal matrix P to matrix A formulated */ #else @@ -4970,8 +4970,8 @@ static void formulate2x2MixingMatrix_fx( matrixMul_fx( KyRe_fx, KyIm_fx, &q_ky, Pre_fx, Pim_fx, &q_P, tmpRe_fx, tmpIm_fx, &q_temp ); #ifdef OPT_2182_MATRIX_SCALE_OPS matrixScale_fx( tmpRe_fx, tmpIm_fx, &q_temp ); - matrixTransp2Mul_fx( - tmpRe_fx, tmpIm_fx, &q_temp, + matrixTransp2Mul_fx( + tmpRe_fx, tmpIm_fx, &q_temp, Uxre_fx, Uxim_fx, &q_Ux, Mre_fx, Mim_fx, q_M ); #else -- GitLab