diff --git a/lib_com/basop_util.c b/lib_com/basop_util.c index 6ecc23bee1debab7ccdd69defbf5e716030d802a..0bf796702fc3619f5f91c4dd636bea2cba7ae40d 100644 --- a/lib_com/basop_util.c +++ b/lib_com/basop_util.c @@ -2968,3 +2968,21 @@ Word64 Mpy_64_32( Word64 W_var1, Word32 L_var2 ) var_out = W_mac_32_32( W_shr( var_out, 31 ), W_extract_h( W_var1 ), L_var2 ); return var_out; } + +#ifndef FUNCTION_W_msu0_32_32 +Word64 W_msu0_32_32( Word64 L64_var1, Word32 L_var2, Word32 L_var3 ) +{ + /* no saturation */ + L64_var1 = W_sub_nosat( L64_var1, W_mult0_32_32( L_var2, L_var3 ) ); + return L64_var1; +} +#endif + +#ifndef FUNCTION_W_mac0_32_32 +Word64 W_mac0_32_32( Word64 L64_var1, Word32 L_var2, Word32 L_var3 ) +{ + /* no saturation */ + L64_var1 = W_add_nosat( L64_var1, W_mult0_32_32( L_var2, L_var3 ) ); + return L64_var1; +} +#endif diff --git a/lib_com/basop_util.h b/lib_com/basop_util.h index b016690d6c6ed3d8f1fecd87596f37b53f05552b..c63e62747821ba83e8855005550981d1131f7d50 100644 --- a/lib_com/basop_util.h +++ b/lib_com/basop_util.h @@ -929,4 +929,11 @@ cmplx CL_mult_32x16( cmplx input, cmplx_s coeff ); */ Word64 Mpy_64_32( Word64 W_var1, Word32 L_var2 ); +#ifndef FUNCTION_W_msu0_32_32 +Word64 W_msu0_32_32( Word64 L64_var1, Word32 L_var2, Word32 L_var3 ); +#endif +#ifndef FUNCTION_W_mac0_32_32 +Word64 W_mac0_32_32( Word64 L64_var1, Word32 L_var2, Word32 L_var3 ); +#endif + #endif /* __BASOP_UTIL_H__ */ diff --git a/lib_com/options.h b/lib_com/options.h index b73b5ee8a07ae4d0e864f861de938e225384bca1..dd41dd1bc5640eee34a64af179ca26c52b4e3fd8 100644 --- a/lib_com/options.h +++ b/lib_com/options.h @@ -105,11 +105,12 @@ /* #################### 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. */ -#define OPT_2185_MATRIX_OUT_SCALING /* Dolby: Issue 2185, optimize matrix-mul output-format. */ -#define OPT_2239_IVAS_FILTER_PROCESS /* Dolby: Issue 2239, optimize ivas_filter_process_fx. */ -#define NONBE_OPT_2193_EIG2X2 /* Dolby: Issue 2193, optimize eig2x2_fx. */ +#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. */ +#define OPT_2185_MATRIX_OUT_SCALING /* Dolby: Issue 2185, optimize matrix-mul output-format. */ +#define OPT_2239_IVAS_FILTER_PROCESS /* Dolby: Issue 2239, optimize ivas_filter_process_fx. */ +#define NONBE_OPT_2193_EIG2X2 /* Dolby: Issue 2193, optimize eig2x2_fx. */ +#define BE_FIX_2240_COMPUTE_COV_MTC_FX_FAST /* FhG: Speeds up covariance calculation e.g. 60 WMOPS for encoding -mc 7_1_4 24400 48 */ /* #################### End BASOP optimization switches ############################ */ diff --git a/lib_enc/ivas_mcmasa_enc_fx.c b/lib_enc/ivas_mcmasa_enc_fx.c index 280da94568e28c042476055c9fef075341e20982..bbc275acf4f0928725d05778808cbcb90912a18b 100644 --- a/lib_enc/ivas_mcmasa_enc_fx.c +++ b/lib_enc/ivas_mcmasa_enc_fx.c @@ -43,7 +43,6 @@ #include "wmc_auto.h" #include "ivas_prot_fx.h" - /*------------------------------------------------------------------------- * Local constants *------------------------------------------------------------------------*/ @@ -72,6 +71,17 @@ static void ivas_mcmasa_dmx_fx( const Word16 nchan_transport, const Word16 nchan_inp ); +#ifdef BE_FIX_2240_COMPUTE_COV_MTC_FX_FAST +/* Compute covariance matrix, i.e., xT * conj(x), and accumulate to the output */ +static void compute_cov_mtx_fx( + Word32 sr[MCMASA_MAX_ANA_CHANS][DIRAC_NO_FB_BANDS_MAX], /* i : Input matrix, real, s[ch][freq] (inp_exp) */ + Word32 si[MCMASA_MAX_ANA_CHANS][DIRAC_NO_FB_BANDS_MAX], /* i : Input matrix, imag, s[ch][freq] (inp_exp) */ + Word16 num_freq_bands, + const Word16 N, /* i : Number of channels */ + CovarianceMatrix pCOVls[MASA_FREQUENCY_BANDS], /* o : Output matrix, contains upper part of cov mtx */ + Word16 inp_exp, /*Stores exponent for temp*/ + Word16 *band_grouping ); +#else static void compute_cov_mtx_fx( Word32 sr[MCMASA_MAX_ANA_CHANS][DIRAC_NO_FB_BANDS_MAX], /* i : Input matrix, real, s[ch][freq] */ Word32 si[MCMASA_MAX_ANA_CHANS][DIRAC_NO_FB_BANDS_MAX], /* i : Input matrix, imag, s[ch][freq] */ @@ -80,6 +90,7 @@ static void compute_cov_mtx_fx( CovarianceMatrix *COVls, /* o : Output matrix, contains upper part of cov mtx */ Word16 inp_exp /*Stores exponent for temp*/ ); +#endif static void computeIntensityVector_enc_fx( const Word16 *band_grouping, @@ -919,7 +930,11 @@ void ivas_mcmasa_param_est_enc_fx( Word32 renormalization_factor_diff_fx[MASA_FREQUENCY_BANDS]; // renormalization_factor_diff_e Word16 renormalization_factor_diff_e[MASA_FREQUENCY_BANDS]; Word32 norm_tmp_fx; +#ifdef BE_FIX_2240_COMPUTE_COV_MTC_FX_FAST + Word16 mrange[2]; +#else Word16 mrange[2], brange[2]; +#endif Word16 numSubFramesForRatio; CovarianceMatrix COVls[MASA_FREQUENCY_BANDS]; Word32 absCOVls_fx[MCMASA_MAX_ANA_CHANS][MCMASA_MAX_ANA_CHANS]; @@ -1064,6 +1079,29 @@ void ivas_mcmasa_param_est_enc_fx( } inp_q = add( inp_q, sf ); +#ifdef BE_FIX_2240_COMPUTE_COV_MTC_FX_FAST + /* Compute covariance matrix */ + + assert( mrange[1] - mrange[0] == 1 ); + /*if this ever comes up, + 1. backup COVls to COVls_old + 2. reinitialize COVls (setzero) + 3. call compute_cov_mtx_fx(..,COVls,...) + 4. Add COVls_old to COVls + */ + + compute_cov_mtx_fx( Chnl_RealBuffer_fx, Chnl_ImagBuffer_fx, num_freq_bands, numAnalysisChannels, COVls, sub( 31, inp_q ), hMcMasa->band_grouping ); + + FOR( i = 0; i < num_freq_bands; i++ ) + { + /* Store energies for guiding metadata encoding */ + FOR( j = 0; j < numAnalysisChannels; j++ ) + { + move32(); + hMasa->data.energy_fx[block_m_idx][i] = BASOP_Util_Add_Mant32Exp( hMasa->data.energy_fx[block_m_idx][i], hMasa->data.energy_e[block_m_idx][i], COVls[i].xr_fx[j][j], COVls[i].xr_e[j][j], &hMasa->data.energy_e[block_m_idx][i] ); + } + } +#else /* Compute covariance matrix */ FOR( i = 0; i < num_freq_bands; i++ ) { @@ -1076,6 +1114,7 @@ void ivas_mcmasa_param_est_enc_fx( compute_cov_mtx_fx( Chnl_RealBuffer_fx, Chnl_ImagBuffer_fx, j, numAnalysisChannels, &( COVls[i] ), sub( 31, inp_q ) ); } + /* Store energies for guiding metadata encoding */ FOR( j = 0; j < numAnalysisChannels; j++ ) { @@ -1083,6 +1122,7 @@ void ivas_mcmasa_param_est_enc_fx( hMasa->data.energy_fx[block_m_idx][i] = BASOP_Util_Add_Mant32Exp( hMasa->data.energy_fx[block_m_idx][i], hMasa->data.energy_e[block_m_idx][i], COVls[i].xr_fx[j][j], COVls[i].xr_e[j][j], &hMasa->data.energy_e[block_m_idx][i] ); } } +#endif IF( !hMcMasa->separateChannelEnabled ) { @@ -2087,6 +2127,74 @@ static void ivas_mcmasa_dmx_fx( return; } + +#ifdef BE_FIX_2240_COMPUTE_COV_MTC_FX_FAST + +/* Compute covariance matrix, i.e., xT * conj(x), and accumulate to the output */ +static void compute_cov_mtx_fx( + Word32 sr[MCMASA_MAX_ANA_CHANS][DIRAC_NO_FB_BANDS_MAX], /* i : Input matrix, real, s[ch][freq] (inp_exp) */ + Word32 si[MCMASA_MAX_ANA_CHANS][DIRAC_NO_FB_BANDS_MAX], /* i : Input matrix, imag, s[ch][freq] (inp_exp) */ + Word16 num_freq_bands, + const Word16 N, /* i : Number of channels */ + CovarianceMatrix pCOVls[MASA_FREQUENCY_BANDS], /* o : Output matrix, contains upper part of cov mtx */ + Word16 inp_exp, /*Stores exponent for temp*/ + Word16 *band_grouping ) +{ + Word16 brange[2]; + Word16 freq; + int k; + int i, j; + Word16 tmp_16; + Word16 temp_exp = add( 1, shl( inp_exp, 1 ) ); + Word64 temp64_1_r_acc, temp64_1_i_acc; + + FOR( i = 0; i < N; i++ ) + { + FOR( j = i; j < N; j++ ) + { + FOR( k = 0; k < num_freq_bands; k++ ) + { + brange[0] = band_grouping[k]; + move16(); + brange[1] = band_grouping[k + 1]; + move16(); + CovarianceMatrix *COVls = &( pCOVls[k] ); + + move64(); + temp64_1_r_acc = 0; + move64(); + temp64_1_i_acc = 0; + + FOR( freq = brange[0]; freq < brange[1]; freq++ ) + { + temp64_1_r_acc = W_mac0_32_32( temp64_1_r_acc, si[i][freq], si[j][freq] ); // exp:2*inp_exp + temp64_1_r_acc = W_mac0_32_32( temp64_1_r_acc, sr[i][freq], sr[j][freq] ); // exp:2*inp_exp + + temp64_1_i_acc = W_mac0_32_32( temp64_1_i_acc, si[i][freq], sr[j][freq] ); + temp64_1_i_acc = W_msu0_32_32( temp64_1_i_acc, sr[i][freq], si[j][freq] ); + } + + tmp_16 = W_norm( temp64_1_r_acc ); + + COVls->xr_fx[i][j] = W_extract_h( W_shl( temp64_1_r_acc, tmp_16 ) ); // exp:max_exp-tmp_16 + COVls->xr_e[i][j] = sub( temp_exp, tmp_16 ); + move32(); + move16(); + + tmp_16 = W_norm( temp64_1_i_acc ); + + COVls->xi_fx[i][j] = W_extract_h( W_shl( temp64_1_i_acc, tmp_16 ) ); // exp:max_exp-tmp_16 + COVls->xi_e[i][j] = sub( temp_exp, tmp_16 ); + move32(); + move16(); + } + } + } + return; +} + + +#else /* Compute covariance matrix, i.e., xT * conj(x), and accumulate to the output */ static void compute_cov_mtx_fx( Word32 sr[MCMASA_MAX_ANA_CHANS][DIRAC_NO_FB_BANDS_MAX], /* i : Input matrix, real, s[ch][freq] (inp_exp) */ @@ -2133,6 +2241,7 @@ static void compute_cov_mtx_fx( } return; } +#endif static void computeIntensityVector_enc_fx( const Word16 *band_grouping,