diff --git a/lib_com/options.h b/lib_com/options.h index 6cad54698e10e13a3d880d2ddf7c0a1be00eeff1..ae63ea2b7b0f80dfc33fe11c7d314a2302548a53 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -210,8 +210,9 @@ #define FIX_1113_CLDFB_REND_IN_ISAR /* issue 1113: fix the use of CLDFB renderer in split-rendering at the external renderer */ #define NONBE_1894_OSBA_SCALING /* FhG: port OSBA scaling MRs (298,355,360) jointly */ -#define NONBE_1360_LFE_DELAY /* Dlb: LFE delay alignment when rendering in CLDFB domain*/ +#define NONBE_1360_LFE_DELAY /* Dlb: LFE delay alignment when rendering in CLDFB domain*/ #define NONBE_1229_FIX_ISM1_DPID /* Eri: issue 1229: fix bug causing ISM 1 to use default -dpid instead of the specified one */ +#define NONBE_SVD_OPTIMIZATION /* #################### End BASOP porting switches ############################ */ diff --git a/lib_dec/ivas_svd_dec.c b/lib_dec/ivas_svd_dec.c index d4ac7d139b5330753a0e8c1560328e9e86be3363..0f9c7523b6c68af53dac88b8b9217ac1b3f76efc 100644 --- a/lib_dec/ivas_svd_dec.c +++ b/lib_dec/ivas_svd_dec.c @@ -42,7 +42,6 @@ #endif #include "wmc_auto.h" - /*-----------------------------------------------------------------------* * Local constants *-----------------------------------------------------------------------*/ @@ -58,10 +57,14 @@ *-----------------------------------------------------------------------*/ static float GivensRotation( const float x, const float z ); - +#ifdef NONBE_SVD_OPTIMIZATION +static void biDiagonalReductionLeft( float singularVectors[][MAX_OUTPUT_CHANNELS], const int16_t nChannelsL, const int16_t nChannelsC, const int16_t currChannel, float *g ); +static void biDiagonalReductionRight( float singularVectors[][MAX_OUTPUT_CHANNELS], const int16_t nChannelsL, const int16_t nChannelsC, const int16_t currChannel, float *g ); +#else static void biDiagonalReductionLeft( float singularVectors[][MAX_OUTPUT_CHANNELS], float singularValues[MAX_OUTPUT_CHANNELS], float secDiag[MAX_OUTPUT_CHANNELS], const int16_t nChannelsL, const int16_t nChannelsC, const int16_t currChannel, float *sig_x, float *g ); - static void biDiagonalReductionRight( float singularVectors[][MAX_OUTPUT_CHANNELS], float secDiag[MAX_OUTPUT_CHANNELS], const int16_t nChannelsL, const int16_t nChannelsC, const int16_t currChannel, float *sig_x, float *g ); +#endif + static void singularVectorsAccumulationLeft( float singularVectors_Left[][MAX_OUTPUT_CHANNELS], float singularValues[MAX_OUTPUT_CHANNELS], const int16_t nChannelsL, const int16_t nChannelsC ); @@ -488,16 +491,30 @@ static void HouseholderReduction( float *eps_x ) { int16_t nCh; - float g = 0.0f, sig_x = 0.0f; +#ifdef NONBE_SVD_OPTIMIZATION + float g_left = 0.0f; + float g_right = 0.0f; +#else + float sig_x = 0.0f; + float g = 0.0f; +#endif /* Bidiagonal Reduction for every channel */ for ( nCh = 0; nCh < nChannelsC; nCh++ ) /* nChannelsC */ { +#ifdef NONBE_SVD_OPTIMIZATION + secDiag[nCh] = g_right; /* from the previous channel */ + biDiagonalReductionLeft( singularVectors_Left, nChannelsL, nChannelsC, nCh, &g_left ); + singularValues[nCh] = g_left; + biDiagonalReductionRight( singularVectors_Left, nChannelsL, nChannelsC, nCh, &g_right ); +#else biDiagonalReductionLeft( singularVectors_Left, singularValues, secDiag, nChannelsL, nChannelsC, nCh, &sig_x, &g ); biDiagonalReductionRight( singularVectors_Left, secDiag, nChannelsL, nChannelsC, nCh, &sig_x, &g ); +#endif *eps_x = max( *eps_x, ( fabsf( singularValues[nCh] ) + fabsf( secDiag[nCh] ) ) ); } + /* SingularVecotr Accumulation */ singularVectorsAccumulationRight( singularVectors_Left, singularVectors_Right, secDiag, nChannelsC ); singularVectorsAccumulationLeft( singularVectors_Left, singularValues, nChannelsL, nChannelsC ); @@ -506,12 +523,123 @@ static void HouseholderReduction( } +#ifdef NONBE_SVD_OPTIMIZATION /*------------------------------------------------------------------------- * biDiagonalReductionLeft() * * *-------------------------------------------------------------------------*/ +static void biDiagonalReductionLeft( + float singularVectors[][MAX_OUTPUT_CHANNELS], + const int16_t nChannelsL, + const int16_t nChannelsC, + const int16_t currChannel, + float *g ) +{ + int16_t iCh, jCh; + float norm_x, f, r; + + /* Setting values to 0 */ + ( *g ) = 0.0f; + + if ( currChannel < nChannelsL ) /* i <= m */ + { + norm_x = 0.0f; + + + for ( jCh = currChannel; jCh < nChannelsL; jCh++ ) /* nChannelsL */ + { + norm_x += ( singularVectors[jCh][currChannel] * singularVectors[jCh][currChannel] ); + } + if ( ( norm_x ) ) /*(fabsf(*sig_x) > EPSILON * fabsf(*sig_x)) { */ + { + ( *g ) = -( singularVectors[currChannel][currChannel] >= 0 ? 1 : ( -1 ) ) * sqrtf( norm_x ); + r = ( *g ) * singularVectors[currChannel][currChannel] - norm_x; + singularVectors[currChannel][currChannel] = ( singularVectors[currChannel][currChannel] - ( *g ) ); + + for ( iCh = currChannel + 1; iCh < nChannelsC; iCh++ ) /* nChannelsC */ + { + norm_x = 0.0f; + for ( jCh = currChannel; jCh < nChannelsL; jCh++ ) /* nChannelsL */ + { + norm_x += ( singularVectors[jCh][currChannel] * singularVectors[jCh][iCh] ); + } + + f = norm_x / maxWithSign( r ); + + + for ( jCh = currChannel; jCh < nChannelsL; jCh++ ) /* nChannelsL */ + { + singularVectors[jCh][iCh] += ( f * singularVectors[jCh][currChannel] ); + } + } + } + } + + return; +} + +/*------------------------------------------------------------------------- + * biDiagonalReductionRight() + * + * + *-------------------------------------------------------------------------*/ +static void biDiagonalReductionRight( + float singularVectors[][MAX_OUTPUT_CHANNELS], + const int16_t nChannelsL, + const int16_t nChannelsC, + const int16_t currChannel, + float *g ) +{ + int16_t iCh, jCh, idx; + float norm_x, r; + + /* Setting values to 0 */ + ( *g ) = 0.0f; + + if ( currChannel < nChannelsL && currChannel != ( nChannelsC - 1 ) ) /* i <=m && i !=n */ + { + idx = currChannel + 1; + + norm_x = 0.0f; + + for ( jCh = idx; jCh < nChannelsC; jCh++ ) /*nChannelsC */ + { + norm_x += ( singularVectors[currChannel][jCh] * singularVectors[currChannel][jCh] ); + } + + if ( norm_x ) /*(fabsf(*sig_x) > EPSILON * fabsf(*sig_x)) { */ + { + ( *g ) = -( singularVectors[currChannel][idx] >= 0 ? 1 : ( -1 ) ) * sqrtf( norm_x ); + r = ( *g ) * singularVectors[currChannel][idx] - norm_x; + singularVectors[currChannel][idx] = ( singularVectors[currChannel][idx] - ( *g ) ); + + for ( iCh = currChannel + 1; iCh < nChannelsL; iCh++ ) /* nChannelsL */ + { + norm_x = 0.0f; + for ( jCh = idx; jCh < nChannelsC; jCh++ ) /* nChannelsC */ + { + norm_x += ( singularVectors[iCh][jCh] * singularVectors[currChannel][jCh] ); + } + norm_x /= r; + for ( jCh = idx; jCh < nChannelsC; jCh++ ) /* nChannelsC */ + { + singularVectors[iCh][jCh] += ( norm_x * singularVectors[currChannel][jCh] ); + } + } + } + } + return; +} + +#else + +/*------------------------------------------------------------------------- + * biDiagonalReductionLeft() + * + * + *-------------------------------------------------------------------------*/ static void biDiagonalReductionLeft( float singularVectors[][MAX_OUTPUT_CHANNELS], float singularValues[MAX_OUTPUT_CHANNELS], @@ -582,14 +710,16 @@ static void biDiagonalReductionLeft( return; } - +#endif /*------------------------------------------------------------------------- * biDiagonalReductionRight() * * *-------------------------------------------------------------------------*/ +#ifdef NONBE_SVD_OPTIMIZATION +#else static void biDiagonalReductionRight( float singularVectors[][MAX_OUTPUT_CHANNELS], float secDiag[MAX_OUTPUT_CHANNELS], @@ -632,7 +762,6 @@ static void biDiagonalReductionRight( { secDiag[jCh] = singularVectors[currChannel][jCh] / maxWithSign( r ); } - for ( iCh = currChannel + 1; iCh < nChannelsL; iCh++ ) /* nChannelsL */ { norm_x = 0.0f; @@ -657,7 +786,7 @@ static void biDiagonalReductionRight( return; } - +#endif /*------------------------------------------------------------------------- * singularVectorsAccumulationLeft() *