From cbf257c46a071fc8faedc7c1740f12e94c04c4ab Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Wed, 3 Jul 2024 08:52:56 +0530 Subject: [PATCH 1/2] Converted ivas_enc_cov_handler_process function and its subfunctions [x] Converted the following functions from float to fixed ivas_enc_cov_handler_process ivas_spar_get_activeW_flag ivas_band_cov [x] Integrated the function in SBA path. [x] Function to be integrated in MC path in a separate MR. --- lib_com/ivas_cnst.h | 3 + lib_com/ivas_cov_smooth.c | 72 ++-- lib_com/ivas_fb_mixer.c | 11 +- lib_com/ivas_prot.h | 69 ++-- lib_com/ivas_stat_com.h | 7 +- lib_enc/ivas_enc_cov_handler.c | 612 +++++++++++++++++++++++++-------- lib_enc/ivas_spar_encoder.c | 102 ++++++ lib_enc/ivas_stat_enc.h | 3 + 8 files changed, 683 insertions(+), 196 deletions(-) diff --git a/lib_com/ivas_cnst.h b/lib_com/ivas_cnst.h index d82507787..126cc3d1c 100644 --- a/lib_com/ivas_cnst.h +++ b/lib_com/ivas_cnst.h @@ -1068,6 +1068,9 @@ typedef enum #define IVAS_SPAR_DYN_ACTIVEW_THRESH (0.0039f) #define IVAS_SPAR_DYN_ACTIVEW_THRESH_FX (8375186) /* 0.0039f in Q31 */ #define IVAS_SPAR_SIDE_CH_DYN_ACTIVEW_THRESH (32.0f) +#ifdef IVAS_FLOAT_FIXED +#define IVAS_SPAR_SIDE_CH_DYN_ACTIVEW_THRESH_Q0 (32) +#endif #define MAX_QUANT_STRATS 3 #define MAX_CODING_STRATS 3 diff --git a/lib_com/ivas_cov_smooth.c b/lib_com/ivas_cov_smooth.c index 6a762cb95..b7f195b9c 100644 --- a/lib_com/ivas_cov_smooth.c +++ b/lib_com/ivas_cov_smooth.c @@ -206,6 +206,7 @@ static void ivas_set_up_cov_smoothing_fx( Word16 active_bins = pFb->fb_bin_to_band.pFb_active_bins_per_band[j]; update_factor = ivas_calculate_update_factor_fx( pFb->fb_bin_to_band.pFb_bin_to_band_fx[j], active_bins ); ivas_calculate_smoothning_factor_fx( &hCovState->pSmoothing_factor_fx[j], update_factor, min_pool_size, max_update_rate, smooth_mode, ivas_total_brate, j ); + hCovState->pSmoothing_factor[j] = fixedToFloat( hCovState->pSmoothing_factor_fx[j], Q31 ); } } ELSE @@ -216,6 +217,7 @@ static void ivas_set_up_cov_smoothing_fx( Word16 active_bins = pFb->fb_bin_to_band.p_short_stride_num_bins_per_band[j]; update_factor = ivas_calculate_update_factor_fx( p_bin_to_band, active_bins ); ivas_calculate_smoothning_factor_fx( &hCovState->pSmoothing_factor_fx[j], update_factor, min_pool_size, max_update_rate, smooth_mode, ivas_total_brate, j ); + hCovState->pSmoothing_factor[j] = fixedToFloat( hCovState->pSmoothing_factor_fx[j], Q31 ); } } @@ -297,12 +299,11 @@ ivas_error ivas_spar_covar_smooth_enc_open( { return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for SPAR COV encoder" ); } -#else +#endif if ( ( hCovState->pSmoothing_factor = (float *) malloc( sizeof( float ) * cov_smooth_cfg->max_bands ) ) == NULL ) { return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for SPAR COV encoder" ); } -#endif for ( i = 0; i < nchan_inp; i++ ) { @@ -319,6 +320,13 @@ ivas_error ivas_spar_covar_smooth_enc_open( return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for SPAR COV encoder Fixed" ); } set_zero_fx( hCovState->pPrior_cov_real_fx[i][j], cov_smooth_cfg->max_bands ); +#endif +#ifdef IVAS_FLOAT_FIXED + if ( ( hCovState->q_cov_real_per_band[i][j] = (Word16 *) malloc( sizeof( Word16 ) * cov_smooth_cfg->max_bands ) ) == NULL ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for SPAR COV encoder Fixed" ); + } + set_s( hCovState->q_cov_real_per_band[i][j], Q31, cov_smooth_cfg->max_bands ); #endif } } @@ -398,10 +406,9 @@ void ivas_spar_covar_smooth_enc_close( #ifdef IVAS_FLOAT_FIXED free( hCovState->pSmoothing_factor_fx ); hCovState->pSmoothing_factor_fx = NULL; -#else +#endif free( hCovState->pSmoothing_factor ); hCovState->pSmoothing_factor = NULL; -#endif for ( i = 0; i < nchan_inp; i++ ) { @@ -412,6 +419,10 @@ void ivas_spar_covar_smooth_enc_close( #ifdef IVAS_FLOAT_FIXED free( hCovState->pPrior_cov_real_fx[i][j] ); hCovState->pPrior_cov_real_fx[i][j] = NULL; +#endif +#ifdef IVAS_FLOAT_FIXED + free( hCovState->q_cov_real_per_band[i][j] ); + hCovState->q_cov_real_per_band[i][j] = NULL; #endif } } @@ -473,25 +484,35 @@ static void ivas_compute_smooth_cov_fx( const Word16 end_band, const Word16 num_ch, const Word16 transient_det[2], - Word16 q_cov[][IVAS_SPAR_MAX_CH] ) + Word16 *q_cov[IVAS_SPAR_MAX_CH] ) { Word16 i, j, k; Word16 prev_idx = hCovState->prior_bank_idx; Word32 factor = 0, L_tmp, L_tmp1; Word16 sm_b; Word16 non_sm_b_idx; + Word16 q_tmp[IVAS_MAX_NUM_BANDS]; + sm_b = BAND_SMOOTH_REST_START_IDX; + move16(); - assert( end_band <= pFb->filterbank_num_bands ); + assert( LE_16( end_band, pFb->filterbank_num_bands ) ); IF( EQ_16( prev_idx, -1 ) || EQ_16( transient_det[1], 1 ) ) { + FOR( i = 0; i < num_ch; i++ ) + { + FOR( j = 0; j < num_ch; j++ ) + { + set_s( hCovState->q_cov_real_per_band[i][j], q_cov[i][j], pFb->filterbank_num_bands ); + } + } FOR( i = 0; i < num_ch; i++ ) { FOR( k = start_band; k < end_band; k++ ) { L_tmp = Mpy_32_32( hCovState->pSmoothing_factor_fx[k], fac ); // (Q31, Q31) -> Q31 - pCov_buf[i][i][k] = L_add( pCov_buf[i][i][k], L_shl( L_tmp, sub( q_cov[i][i], Q31 ) ) ); + pCov_buf[i][i][k] = L_add( pCov_buf[i][i][k], L_shl( L_tmp, sub( hCovState->q_cov_real_per_band[i][i][k], Q31 ) ) ); move32(); } } @@ -514,16 +535,20 @@ static void ivas_compute_smooth_cov_fx( move32(); } + set_s( q_tmp, q_cov[i][j], sub( end_band, start_band ) ); FOR( k = start_band; k < non_sm_b_idx; k++ ) { L_tmp = Mpy_32_32( hCovState->pSmoothing_factor_fx[k], pCov_buf[i][j][k] ); // (Q31, q_cov[i][j]) -> q_cov[i][j] - L_tmp1 = Mpy_32_32( L_sub( ONE_IN_Q31, hCovState->pSmoothing_factor_fx[k] ), pPrior_cov_buf[i][j][k] ); // (Q31, q_cov[i][j]) -> q_cov[i][j] - pCov_buf[i][j][k] = L_add( L_tmp, L_tmp1 ); + L_tmp1 = Mpy_32_32( L_sub( ONE_IN_Q31, hCovState->pSmoothing_factor_fx[k] ), pPrior_cov_buf[i][j][k] ); // (Q31, hCovState->q_cov_real_per_band[i][j][k]) -> hCovState->q_cov_real_per_band[i][j][k] + pCov_buf[i][j][k] = BASOP_Util_Add_Mant32Exp( L_tmp, sub( Q31, q_cov[i][j] ), L_tmp1, sub( Q31, hCovState->q_cov_real_per_band[i][j][k] ), &q_tmp[k] ); move32(); - L_tmp = L_shl( Mpy_32_32( hCovState->pSmoothing_factor_fx[k], factor ), sub( q_cov[i][j], Q31 ) ); // ((Q31, Q31) -> Q31) -> q_cov[i][j] + q_tmp[k] = sub( Q31, q_tmp[k] ); + move16(); + L_tmp = L_shl( Mpy_32_32( hCovState->pSmoothing_factor_fx[k], factor ), sub( q_tmp[k], Q31 ) ); // ((Q31, Q31) -> Q31) -> q_tmp[k] pCov_buf[i][j][k] = L_add( pCov_buf[i][j][k], L_tmp ); move32(); } + mvs2s( q_tmp, hCovState->q_cov_real_per_band[i][j], pFb->filterbank_num_bands ); } } FOR( i = 0; i < num_ch; i++ ) @@ -531,7 +556,7 @@ static void ivas_compute_smooth_cov_fx( FOR( k = non_sm_b_idx; k < end_band; k++ ) { L_tmp = Mpy_32_32( hCovState->pSmoothing_factor_fx[k], fac ); // (Q31, Q31) -> Q31 - pCov_buf[i][i][k] = L_add( pCov_buf[i][i][k], L_shl( L_tmp, sub( q_cov[i][i], Q31 ) ) ); + pCov_buf[i][i][k] = L_add( pCov_buf[i][i][k], L_shl( L_tmp, sub( hCovState->q_cov_real_per_band[i][i][k], Q31 ) ) ); move32(); } } @@ -556,20 +581,25 @@ static void ivas_compute_smooth_cov_fx( FOR( k = start_band; k < end_band; k++ ) { L_tmp = Mpy_32_32( hCovState->pSmoothing_factor_fx[k], pCov_buf[i][j][k] ); // (Q31, q_cov[i][j]) -> q_cov[i][j] - L_tmp1 = Mpy_32_32( L_sub( ONE_IN_Q31, hCovState->pSmoothing_factor_fx[k] ), pPrior_cov_buf[i][j][k] ); // (Q31, q_cov[i][j]) -> q_cov[i][j] - pCov_buf[i][j][k] = L_add( L_tmp, L_tmp1 ); + L_tmp1 = Mpy_32_32( L_sub( ONE_IN_Q31, hCovState->pSmoothing_factor_fx[k] ), pPrior_cov_buf[i][j][k] ); // (Q31, hCovState->q_cov_real_per_band[i][j][k]) -> hCovState->q_cov_real_per_band[i][j][k] + pCov_buf[i][j][k] = BASOP_Util_Add_Mant32Exp( L_tmp, sub( Q31, q_cov[i][j] ), L_tmp1, sub( Q31, hCovState->q_cov_real_per_band[i][j][k] ), &q_tmp[k] ); move32(); - L_tmp = L_shl( Mpy_32_32( hCovState->pSmoothing_factor_fx[k], factor ), sub( q_cov[i][j], Q31 ) ); // ((Q31, Q31) -> Q31) -> q_cov[i][j] + q_tmp[k] = sub( Q31, q_tmp[k] ); + move16(); + L_tmp = L_shl( Mpy_32_32( hCovState->pSmoothing_factor_fx[k], factor ), sub( q_tmp[k], Q31 ) ); // ((Q31, Q31) -> Q31) -> q_tmp[k] pCov_buf[i][j][k] = L_add( pCov_buf[i][j][k], L_tmp ); move32(); } + mvs2s( q_tmp, hCovState->q_cov_real_per_band[i][j], pFb->filterbank_num_bands ); } } } return; } -#else +#endif + + /*-----------------------------------------------------------------------------------------* * Function ivas_compute_smooth_cov() * @@ -661,7 +691,6 @@ static void ivas_compute_smooth_cov( return; } -#endif #ifdef IVAS_FLOAT_FIXED @@ -679,12 +708,12 @@ void ivas_cov_smooth_process_fx( const Word16 end_band, const Word16 num_ch, const Word16 transient_det[2], - Word16 q_cov[][IVAS_SPAR_MAX_CH] ) + Word16 *q_cov[IVAS_SPAR_MAX_CH] ) { Word16 i, j; - Word16 num_bands = end_band - start_band; + Word16 num_bands = sub( end_band, start_band ); - ivas_compute_smooth_cov_fx( hCovState, pFb, cov_real, hCovState->pPrior_cov_real_fx, (Word32) ( 1e-20f * ONE_IN_Q31 ), start_band, end_band, num_ch, transient_det, q_cov ); + ivas_compute_smooth_cov_fx( hCovState, pFb, cov_real, hCovState->pPrior_cov_real_fx, 0, start_band, end_band, num_ch, transient_det, q_cov ); FOR( i = 0; i < num_ch; i++ ) { @@ -699,7 +728,9 @@ void ivas_cov_smooth_process_fx( return; } -#else +#endif + + /*-----------------------------------------------------------------------------------------* * Function ivas_cov_smooth_process() * @@ -732,4 +763,3 @@ void ivas_cov_smooth_process( return; } -#endif diff --git a/lib_com/ivas_fb_mixer.c b/lib_com/ivas_fb_mixer.c index 749952dfd..60caa2e17 100644 --- a/lib_com/ivas_fb_mixer.c +++ b/lib_com/ivas_fb_mixer.c @@ -62,6 +62,7 @@ static ivas_error ivas_fb_mixer_get_window_fx( const Word16 fade_len, const Word #endif +#ifdef IVAS_FLOAT_FIXED /*-----------------------------------------------------------------------------------------* * Function ivas_get_num_bands_from_bw_idx() * @@ -69,7 +70,6 @@ static ivas_error ivas_fb_mixer_get_window_fx( const Word16 fade_len, const Word *-----------------------------------------------------------------------------------------*/ /*! r: number of spectral bands */ -#ifdef IVAS_FLOAT_FIXED Word16 ivas_get_num_bands_from_bw_idx( const Word16 bwidth /* i : audio bandwidth */ ) @@ -78,10 +78,18 @@ Word16 ivas_get_num_bands_from_bw_idx( assert( bwidth > 0 ); /*NB BW is not supported*/ num_active_bands = ivas_num_active_bands[bwidth - 1]; + move16(); return num_active_bands; } #else +/*-----------------------------------------------------------------------------------------* + * Function ivas_get_num_bands_from_bw_idx() + * + * Get number of bands from BW index + *-----------------------------------------------------------------------------------------*/ + +/*! r: number of spectral bands */ int16_t ivas_get_num_bands_from_bw_idx( const int16_t bwidth /* i : audio bandwidth */ ) @@ -95,6 +103,7 @@ int16_t ivas_get_num_bands_from_bw_idx( } #endif + /*-----------------------------------------------------------------------------------------* * Function ivas_get_num_bands() * diff --git a/lib_com/ivas_prot.h b/lib_com/ivas_prot.h index 766ec38de..d085e06be 100644 --- a/lib_com/ivas_prot.h +++ b/lib_com/ivas_prot.h @@ -5868,26 +5868,30 @@ void ivas_spar_covar_enc_close( ); #ifdef IVAS_FLOAT_FIXED -ivas_error ivas_enc_cov_handler_process( - ivas_enc_cov_handler_state_t *hCovEnc, /* i/o: SPAR Covar. encoder handle */ - float **ppIn_FR_real, - float **ppIn_FR_imag, - float *cov_real[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH], - float *cov_dtx_real[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH], - ivas_filterbank_t *pFb, /* i/o: FB handle */ - const int16_t start_band, - const int16_t end_band, - const int16_t num_ch, - const int16_t dtx_vad, - const int16_t transient_det[2], - const int16_t HOA_md_ind[IVAS_SPAR_MAX_CH], - int16_t *res_ind, - const int16_t *remix_order, - int16_t *dyn_active_w_flag, - const int16_t nchan_transport, - const int16_t is_sba +void ivas_enc_cov_handler_process_fx( + ivas_enc_cov_handler_state_t *hCovEnc, /* i/o: SPAR Covar. encoder handle */ + Word32 **ppIn_FR_real, + Word32 **ppIn_FR_imag, + Word16 *q_ppIn_FR, + Word32 *cov_real[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH], + Word16 *q_cov_real[IVAS_SPAR_MAX_CH], + Word32 *cov_dtx_real[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH], + Word16 *q_cov_dtx_real[IVAS_SPAR_MAX_CH], + ivas_filterbank_t *pFb, /* i/o: FB handle */ + const Word16 start_band, + const Word16 end_band, + const Word16 num_ch, + const Word16 dtx_vad, + const Word16 transient_det[2], + const Word16 HOA_md_ind[IVAS_SPAR_MAX_CH], + Word16 *res_ind, + const Word16 *remix_order, + Word16 *dyn_active_w_flag, + const Word16 nchan_transport, + const Word16 is_sba ); -#else +#endif + void ivas_enc_cov_handler_process( ivas_enc_cov_handler_state_t *hCovEnc, /* i/o: SPAR Covar. encoder handle */ float **ppIn_FR_real, @@ -5907,6 +5911,21 @@ void ivas_enc_cov_handler_process( const int16_t nchan_transport, const int16_t is_sba ); + +#ifdef IVAS_FLOAT_FIXED_ +ivas_error ivas_spar_covar_smooth_enc_open_fx( + ivas_cov_smooth_state_t **hCovState, /* i/o: SPAR Covar. smoothing handle */ + const ivas_cov_smooth_cfg_t *cov_smooth_cfg, /* i : SPAR config. handle */ + ivas_filterbank_t *pFb, /* i/o: FB handle */ + const Word16 nchan_inp, /* i : number of input channels */ + const COV_SMOOTHING_TYPE smooth_mode, /* i : Smooth covariance for SPAR or MC */ + const Word32 ivas_total_brate /* i : IVAS total bitrate */ +); + +void ivas_spar_covar_smooth_enc_close_fx( + ivas_cov_smooth_state_t **hCovState, /* i/o: SPAR Covar. encoder handle */ + const Word16 nchan_inp /* i : number of input channels */ +); #endif ivas_error ivas_spar_covar_smooth_enc_open( @@ -5932,9 +5951,10 @@ void ivas_cov_smooth_process_fx( const Word16 end_band, const Word16 num_ch, const Word16 transient_det[2], - Word16 q_cov[][IVAS_SPAR_MAX_CH] + Word16 *q_cov[IVAS_SPAR_MAX_CH] ); -#else +#endif + void ivas_cov_smooth_process( ivas_cov_smooth_state_t *hCovState, /* i/o: Covariance state handle */ float *cov_real[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH], @@ -5944,7 +5964,6 @@ void ivas_cov_smooth_process( const int16_t num_ch, const int16_t transient_det[2] ); -#endif /* Transient detector module */ ivas_error ivas_transient_det_open( @@ -7591,9 +7610,15 @@ void ivas_fb_mixer_cross_fading( ); /*! r: number of spectral bands */ +#ifdef IVAS_FLOAT_FIXED +Word16 ivas_get_num_bands_from_bw_idx( + const Word16 bwidth /* i : audio bandwidth */ +); +#else int16_t ivas_get_num_bands_from_bw_idx( const int16_t bwidth /* i : audio bandwidth */ ); +#endif #ifdef IVAS_FLOAT_FIXED /*to be moved to prot_fx1.h*/ diff --git a/lib_com/ivas_stat_com.h b/lib_com/ivas_stat_com.h index 34b7942d6..6e13c5f29 100644 --- a/lib_com/ivas_stat_com.h +++ b/lib_com/ivas_stat_com.h @@ -369,12 +369,12 @@ typedef struct ivas_cov_smooth_state_t { float *pPrior_cov_real[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH]; int16_t prior_bank_idx; -#ifndef IVAS_FLOAT_FIXED float *pSmoothing_factor; -#endif int16_t num_bins; #ifdef IVAS_FLOAT_FIXED Word32 *pPrior_cov_real_fx[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH]; + Word16 *q_cov_real[IVAS_SPAR_MAX_CH]; + Word16 *q_cov_real_per_band[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH]; Word32 *pSmoothing_factor_fx; /* Q31 */ #endif @@ -382,9 +382,8 @@ typedef struct ivas_cov_smooth_state_t typedef struct ivas_cov_smooth_cfg_t { -#ifndef IVAS_FLOAT_FIXED float max_update_rate; -#else +#ifdef IVAS_FLOAT_FIXED Word32 max_update_rate_fx; /* Q31 */ #endif int16_t min_pool_size; diff --git a/lib_enc/ivas_enc_cov_handler.c b/lib_enc/ivas_enc_cov_handler.c index d017a28bf..cda2b4676 100644 --- a/lib_enc/ivas_enc_cov_handler.c +++ b/lib_enc/ivas_enc_cov_handler.c @@ -48,12 +48,19 @@ #define MAX_UPDATE_RATE 0.8f #define MIN_POOL_SIZE_DTX 40 #define MAX_UPDATE_RATE_DTX 0.4f +#ifdef IVAS_FLOAT_FIXED +#define MAX_UPDATE_RATE_Q31 ( 1717986944 ) +#define MAX_UPDATE_RATE_DTX_Q31 ( 858993472 ) +#endif /*------------------------------------------------------------------------------------------* * Local functions declarations *------------------------------------------------------------------------------------------*/ +#ifdef IVAS_FLOAT_FIXED +static void ivas_band_cov_fx( Word32 **ppIn_FR_real, Word32 **ppIn_FR_imag, Word16 *q_In_FR, const Word16 num_chans, const Word16 num_bins, Word16 stride, Word32 **pFb_bin_to_band, const Word16 *pFb_start_bin_per_band, const Word16 *pFb_active_bins_per_band, const Word16 start_band, const Word16 end_band, Word32 *cov_real[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH], Word16 *q_cov_real[IVAS_SPAR_MAX_CH], const Word16 HOA_md_ind[IVAS_SPAR_MAX_CH] ); +#endif static void ivas_band_cov( float **ppIn_FR_real, float **ppIn_FR_imag, const int16_t num_chans, const int16_t num_bins, int16_t stride, float **pFb_bin_to_band, const int16_t *pFb_start_bin_per_band, const int16_t *pFb_active_bins_per_band, const int16_t start_band, const int16_t end_band, float *cov_real[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH], const int16_t HOA_md_ind[IVAS_SPAR_MAX_CH] ); /*------------------------------------------------------------------------- @@ -84,19 +91,16 @@ ivas_error ivas_spar_covar_enc_open( cov_smooth_cfg.max_bands = IVAS_MAX_NUM_BANDS; #ifdef IVAS_FLOAT_FIXED - cov_smooth_cfg.max_update_rate_fx = (Word32) ( MAX_UPDATE_RATE * ONE_IN_Q31 ); // Q31 -#else - cov_smooth_cfg.max_update_rate = MAX_UPDATE_RATE; + cov_smooth_cfg.max_update_rate_fx = MAX_UPDATE_RATE_Q31; #endif + cov_smooth_cfg.max_update_rate = MAX_UPDATE_RATE; cov_smooth_cfg.min_pool_size = MIN_POOL_SIZE; if ( smooth_mode == COV_SMOOTH_MC ) { #ifdef IVAS_FLOAT_FIXED - // Note: (Word32) ( 1.0f * ONE_IN_Q31 ) overflows to INT_MIN cov_smooth_cfg.max_update_rate_fx = ONE_IN_Q31; // Q31 -#else - cov_smooth_cfg.max_update_rate = 1.0f; #endif + cov_smooth_cfg.max_update_rate = 1.0f; cov_smooth_cfg.min_pool_size = 20; } @@ -106,10 +110,9 @@ ivas_error ivas_spar_covar_enc_open( } #ifdef IVAS_FLOAT_FIXED - cov_smooth_cfg.max_update_rate_fx = (Word32) ( MAX_UPDATE_RATE_DTX * ONE_IN_Q31 ); // Q31 -#else - cov_smooth_cfg.max_update_rate = MAX_UPDATE_RATE_DTX; + cov_smooth_cfg.max_update_rate_fx = MAX_UPDATE_RATE_DTX_Q31; #endif + cov_smooth_cfg.max_update_rate = MAX_UPDATE_RATE_DTX; cov_smooth_cfg.min_pool_size = MIN_POOL_SIZE_DTX; if ( ( error = ivas_spar_covar_smooth_enc_open( &hCovState->pCov_dtx_state, &cov_smooth_cfg, pFb, nchan_inp, smooth_mode, ivas_total_brate ) ) != IVAS_ERR_OK ) @@ -160,6 +163,171 @@ void ivas_spar_covar_enc_close( } +#ifdef IVAS_FLOAT_FIXED +/*-----------------------------------------------------------------------------------------* + * Function ivas_spar_get_activeW_flag_fx() + * + * + *-----------------------------------------------------------------------------------------*/ + +static Word16 ivas_spar_get_activeW_flag_fx( + ivas_enc_cov_handler_state_t *hCovEnc, + Word32 *cov_real[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH], + Word32 *cov_dtx_real[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH], + Word16 *q_cov_real[IVAS_SPAR_MAX_CH], + const Word16 dtx_vad, + const Word16 nchan_inp, + const Word16 nchan_transport, + Word16 *res_ind, + const Word16 *dmx_order ) +{ + Word16 b, ch, num_bands, num_chs, activeW_flag; + Word32 bb_var[FOA_CHANNELS], sm_fact, side_ch_var, en_ratio; + Word64 bb_var_64bit[FOA_CHANNELS]; + Word16 q_shift; + Word16 q_bb_var[FOA_CHANNELS]; + Word32 L_tmp, L_tmp1; + Word16 exp_diff, q_com, guard_bits; + + num_chs = s_min( nchan_inp, FOA_CHANNELS ); + num_bands = ivas_get_num_bands_from_bw_idx( SPAR_CONFIG_BW ); + + set_zero_fx( bb_var, FOA_CHANNELS ); + set_s( q_bb_var, Q31, FOA_CHANNELS ); + FOR( ch = 0; ch < FOA_CHANNELS; ch++ ) + { + bb_var_64bit[ch] = 0; + move64(); + } + + IF( EQ_16( dtx_vad, 1 ) ) + { + FOR( ch = 0; ch < num_chs; ch++ ) + { + FOR( b = 0; b < num_bands; b++ ) + { + bb_var_64bit[ch] = W_add_nosat( bb_var_64bit[ch], W_deposit32_l( cov_real[ch][ch][b] ) ); // q_cov_real[ch][ch] + move64(); + q_bb_var[ch] = q_cov_real[ch][ch]; + move16(); + } + } + } + ELSE + { + FOR( ch = 0; ch < num_chs; ch++ ) + { + FOR( b = 0; b < num_bands; b++ ) + { + bb_var_64bit[ch] = W_add_nosat( bb_var_64bit[ch], W_deposit32_l( cov_dtx_real[ch][ch][b] ) ); // q_cov_real[ch][ch] + move64(); + q_bb_var[ch] = q_cov_real[ch][ch]; + move16(); + } + } + } + + FOR( ch = 0; ch < num_chs; ch++ ) + { + q_shift = Q31; + move16(); + q_shift = W_norm( bb_var_64bit[ch] ); + bb_var[ch] = W_extract_l( W_shl_nosat( bb_var_64bit[ch], sub( q_shift, 32 ) ) ); + move32(); + q_bb_var[ch] = add( q_bb_var[ch], sub( q_shift, 32 ) ); + move16(); + } + + IF( EQ_16( hCovEnc->prior_var_flag, -1 ) ) + { + FOR( ch = 0; ch < num_chs; ch++ ) + { + hCovEnc->bb_var_lt_fx[ch] = bb_var[ch]; // q_bb_var[ch] + move32(); + } + } + ELSE + { + sm_fact = ONE_IN_Q30; // Q31 + move32(); + FOR( ch = 0; ch < num_chs; ch++ ) + { + L_tmp = Mpy_32_32( sm_fact, hCovEnc->bb_var_lt_fx[ch] ); // (Q31, q_bb_var[ch]) -> q_bb_var[ch] + L_tmp1 = Mpy_32_32( L_sub( ONE_IN_Q31, sm_fact ), bb_var[ch] ); // (Q31, q_bb_var[ch]) -> q_bb_var[ch] + hCovEnc->bb_var_lt_fx[ch] = L_add( L_tmp, L_tmp1 ); // q_bb_var[ch] + move32(); + } + } + + side_ch_var = L_deposit_l( EPSILLON_FX ); // Note: To handle divide-by-0 asserts + guard_bits = find_guarded_bits_fx( L_deposit_l( sub( num_chs, nchan_transport ) ) ); + q_com = Q20; + move16(); + FOR( ch = nchan_transport; ch < num_chs; ch++ ) + { + q_com = s_min( q_com, q_bb_var[dmx_order[ch]] ); + } + FOR( ch = nchan_transport; ch < num_chs; ch++ ) + { + side_ch_var = L_add( side_ch_var, L_shr( L_shl( hCovEnc->bb_var_lt_fx[dmx_order[ch]], sub( q_com, q_bb_var[dmx_order[ch]] ) ), guard_bits ) ); // Q(q_com - guard_bits) + } + + IF( LT_32( side_ch_var, L_shl( L_mult0( IVAS_SPAR_SIDE_CH_DYN_ACTIVEW_THRESH_Q0, IVAS_SPAR_SIDE_CH_DYN_ACTIVEW_THRESH_Q0 ), sub( q_com, guard_bits ) ) ) ) // LHS Q(q_com - guard_bits) :: RHS Q(q_com - guard_bits) + { + activeW_flag = 0; + move16(); + } + ELSE + { + L_tmp = BASOP_Util_Divide3232_Scale_cadence( hCovEnc->bb_var_lt_fx[0], side_ch_var, &exp_diff ); // (Q31 - exp_diff) + en_ratio = L_shl_sat( L_tmp, exp_diff ); // Q31 + IF( LT_32( en_ratio, Mpy_32_32( IVAS_SPAR_DYN_ACTIVEW_THRESH_FX, IVAS_SPAR_DYN_ACTIVEW_THRESH_FX ) ) ) // LHS Q31 :: RHS Q31 + { + activeW_flag = 1; + move16(); + } + ELSE + { + activeW_flag = 0; + move16(); + } + } + + IF( activeW_flag ) + { + *res_ind = 0; + move16(); + IF( EQ_16( nchan_transport, 2 ) ) + { + Word16 max_idx; + Word32 max_val; + max_idx = nchan_transport; + move16(); + max_val = hCovEnc->bb_var_lt_fx[max_idx]; // q_bb_var[max_idx] + move32(); + FOR( ch = nchan_transport; ch < num_chs; ch++ ){ + IF( GT_32( hCovEnc->bb_var_lt_fx[ch], max_val ) ){ + max_idx = ch; + move16(); + max_val = hCovEnc->bb_var_lt_fx[ch]; + move32(); + } + } + *res_ind = max_idx; + move16(); +} +ELSE IF( EQ_16( nchan_transport, 3 ) ) +{ + *res_ind = dmx_order[nchan_transport]; + move16(); +} +} + +return activeW_flag; +} +#endif + + /*-----------------------------------------------------------------------------------------* * Function ivas_spar_get_activeW_flag() * @@ -272,34 +440,173 @@ static int16_t ivas_spar_get_activeW_flag( } +#ifdef IVAS_FLOAT_FIXED /*-----------------------------------------------------------------------------------------* - * Function ivas_enc_cov_handler_process() + * Function ivas_enc_cov_handler_process_fx() * * Encoder covariance handler process call *-----------------------------------------------------------------------------------------*/ -#ifdef IVAS_FLOAT_FIXED -ivas_error ivas_enc_cov_handler_process( +void ivas_enc_cov_handler_process_fx( ivas_enc_cov_handler_state_t *hCovEnc, /* i/o: SPAR Covar. encoder handle */ - float **ppIn_FR_real, - float **ppIn_FR_imag, - float *cov_real[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH], - float *cov_dtx_real[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH], + Word32 **ppIn_FR_real, + Word32 **ppIn_FR_imag, + Word16 *q_ppIn_FR, + Word32 *cov_real[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH], + Word16 *q_cov_real[IVAS_SPAR_MAX_CH], + Word32 *cov_dtx_real[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH], + Word16 *q_cov_dtx_real[IVAS_SPAR_MAX_CH], ivas_filterbank_t *pFb, /* i/o: FB handle */ - const int16_t start_band, - const int16_t end_band, - const int16_t num_ch, - const int16_t dtx_vad, - const int16_t transient_det[2], - const int16_t HOA_md_ind[IVAS_SPAR_MAX_CH], - int16_t *res_ind, - const int16_t *remix_order, - int16_t *dyn_active_w_flag, - const int16_t nchan_transport, - const int16_t is_sba + const Word16 start_band, + const Word16 end_band, + const Word16 num_ch, + const Word16 dtx_vad, + const Word16 transient_det[2], + const Word16 HOA_md_ind[IVAS_SPAR_MAX_CH], + Word16 *res_ind, + const Word16 *remix_order, + Word16 *dyn_active_w_flag, + const Word16 nchan_transport, + const Word16 is_sba ) +{ + Word16 i, j; + Word16 dtx_cov_flag; + Word16 cov_real_zero[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH]; + Word16 k; + + IF( EQ_16( dtx_vad, 1 ) ) + { + dtx_cov_flag = 0; + move16(); + } + ELSE + { + dtx_cov_flag = 1; + move16(); + } + + ivas_band_cov_fx( ppIn_FR_real, ppIn_FR_imag, q_ppIn_FR, num_ch, hCovEnc->num_bins, + pFb->fb_bin_to_band.short_stride, + pFb->fb_bin_to_band.pp_short_stride_bin_to_band_fx, // Q22 + pFb->fb_bin_to_band.p_short_stride_start_bin_per_band, + pFb->fb_bin_to_band.p_short_stride_num_bins_per_band, + start_band, end_band, cov_real, q_cov_real, HOA_md_ind ); + + FOR( i = 0; i < num_ch; i++ ) + { + set_s( cov_real_zero[i], 1, num_ch ); + } + // Check if a particular band array is zero + FOR( i = 0; i < num_ch; i++ ) + { + FOR( j = 0; j < num_ch; j++ ) + { + FOR( k = start_band; k < end_band; k++ ) + { + IF( cov_real[i][j][k] != 0 ) + { + cov_real_zero[i][j] = 0; + move16(); + BREAK; + } + } + } + } + // Set q_cov_real to Q31 for the zero band array + FOR( i = 0; i < num_ch; i++ ) + { + FOR( j = 0; j < num_ch; j++ ) + { + IF( EQ_16( cov_real_zero[i][j], 1 ) ) + { + q_cov_real[i][j] = Q31; + move16(); + } + } + } + + IF( is_sba ) + { + *res_ind = 0; + move16(); + IF( GT_16( nchan_transport, 1 ) && LE_16( nchan_transport, sub( FOA_CHANNELS, 1 ) ) ) + { + *dyn_active_w_flag = ivas_spar_get_activeW_flag_fx( hCovEnc, cov_real, cov_real, q_cov_real, dtx_vad, num_ch, nchan_transport, res_ind, remix_order ); + } + ELSE + { + *dyn_active_w_flag = 0; + move16(); + } + } + + FOR( i = 0; i < num_ch; i++ ) + { + FOR( j = 0; j < num_ch; j++ ) + { + mvl2l( cov_real[i][j], cov_dtx_real[i][j], pFb->filterbank_num_bands ); + q_cov_dtx_real[i][j] = q_cov_real[i][j]; + move16(); + } + } + + ivas_cov_smooth_process_fx( hCovEnc->pCov_state, cov_real, pFb, start_band, end_band, num_ch, transient_det, q_cov_real ); + + IF( dtx_cov_flag == 0 ) + { + FOR( i = 0; i < num_ch; i++ ) + { + FOR( j = 0; j < num_ch; j++ ) + { + mvl2l( cov_real[i][j], hCovEnc->pCov_dtx_state->pPrior_cov_real_fx[i][j], pFb->filterbank_num_bands ); + mvl2l( cov_real[i][j], cov_dtx_real[i][j], pFb->filterbank_num_bands ); + mvs2s( hCovEnc->pCov_state->q_cov_real_per_band[i][j], hCovEnc->pCov_dtx_state->q_cov_real_per_band[i][j], pFb->filterbank_num_bands ); + } + } + hCovEnc->prior_dtx_present = 1; + move16(); + } + ELSE + { + IF( transient_det[0] == 0 && transient_det[1] == 0 ) + { + ivas_cov_smooth_process_fx( hCovEnc->pCov_dtx_state, cov_dtx_real, pFb, start_band, end_band, num_ch, transient_det, q_cov_dtx_real ); + hCovEnc->prior_dtx_present = 1; + move16(); + } + ELSE + { + IF( hCovEnc->prior_dtx_present == 0 ) + { + ivas_cov_smooth_process_fx( hCovEnc->pCov_dtx_state, cov_dtx_real, pFb, start_band, end_band, num_ch, transient_det, q_cov_dtx_real ); + hCovEnc->prior_dtx_present = 1; + move16(); + } + ELSE + { + FOR( i = 0; i < num_ch; i++ ) + { + FOR( j = 0; j < num_ch; j++ ) + { + mvl2l( hCovEnc->pCov_dtx_state->pPrior_cov_real_fx[i][j], cov_dtx_real[i][j], pFb->filterbank_num_bands ); + } + } + hCovEnc->prior_dtx_present = 1; + move16(); + } + } + } + + return; +} +#endif + +/*-----------------------------------------------------------------------------------------* + * Function ivas_enc_cov_handler_process() + * + * Encoder covariance handler process call + *-----------------------------------------------------------------------------------------*/ -) -#else void ivas_enc_cov_handler_process( ivas_enc_cov_handler_state_t *hCovEnc, /* i/o: SPAR Covar. encoder handle */ float **ppIn_FR_real, @@ -320,14 +627,9 @@ void ivas_enc_cov_handler_process( const int16_t is_sba ) -#endif { int16_t i, j; int16_t dtx_cov_flag; -#ifdef IVAS_FLOAT_FIXED - Word32 *cov_real_fx[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH], *cov_dtx_real_fx[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH]; - Word16 q_cov[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH]; -#endif dtx_cov_flag = ( dtx_vad == 1 ) ? 0 : 1; @@ -359,53 +661,7 @@ void ivas_enc_cov_handler_process( } } -#ifdef IVAS_FLOAT_FIXED - for ( i = 0; i < num_ch; i++ ) - { - for ( j = 0; j < num_ch; j++ ) - { - if ( ( cov_real_fx[i][j] = (Word32 *) malloc( sizeof( Word32 ) * pFb->filterbank_num_bands ) ) == NULL ) - { - return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for SPAR COV encoder Fixed" ); - } - set_zero_fx( cov_real_fx[i][j], pFb->filterbank_num_bands ); - if ( ( cov_dtx_real_fx[i][j] = (Word32 *) malloc( sizeof( Word32 ) * pFb->filterbank_num_bands ) ) == NULL ) - { - return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for SPAR COV encoder Fixed" ); - } - set_zero_fx( cov_dtx_real_fx[i][j], pFb->filterbank_num_bands ); - } - set_s( q_cov[i], 0, num_ch ); - } - - for ( i = 0; i < num_ch; i++ ) - { - for ( j = 0; j < num_ch; j++ ) - { - q_cov[i][j] = L_get_q_buf( hCovEnc->pCov_state->pPrior_cov_real[i][j], pFb->filterbank_num_bands ); - q_cov[i][j] = min( q_cov[i][j], L_get_q_buf( cov_real[i][j], pFb->filterbank_num_bands ) ); - floatToFixed_arrL( cov_real[i][j], cov_real_fx[i][j], q_cov[i][j], pFb->filterbank_num_bands ); - floatToFixed_arrL( hCovEnc->pCov_state->pPrior_cov_real[i][j], hCovEnc->pCov_state->pPrior_cov_real_fx[i][j], q_cov[i][j], pFb->filterbank_num_bands ); - } - } -#endif - -#ifdef IVAS_FLOAT_FIXED - ivas_cov_smooth_process_fx( hCovEnc->pCov_state, cov_real_fx, pFb, start_band, end_band, num_ch, transient_det, q_cov ); -#else ivas_cov_smooth_process( hCovEnc->pCov_state, cov_real, pFb, start_band, end_band, num_ch, transient_det ); -#endif - -#ifdef IVAS_FLOAT_FIXED - for ( i = 0; i < num_ch; i++ ) - { - for ( j = 0; j < num_ch; j++ ) - { - fixedToFloat_arrL( cov_real_fx[i][j], cov_real[i][j], q_cov[i][j], pFb->filterbank_num_bands ); - fixedToFloat_arrL( hCovEnc->pCov_state->pPrior_cov_real_fx[i][j], hCovEnc->pCov_state->pPrior_cov_real[i][j], q_cov[i][j], pFb->filterbank_num_bands ); - } - } -#endif if ( dtx_cov_flag == 0 ) { @@ -424,110 +680,170 @@ void ivas_enc_cov_handler_process( { if ( ( transient_det[0] == 0 ) && ( transient_det[1] == 0 ) ) { -#ifdef IVAS_FLOAT_FIXED - for ( i = 0; i < num_ch; i++ ) - { - set_s( q_cov[i], 0, num_ch ); - for ( j = 0; j < num_ch; j++ ) - { - q_cov[i][j] = L_get_q_buf( hCovEnc->pCov_dtx_state->pPrior_cov_real[i][j], pFb->filterbank_num_bands ); - q_cov[i][j] = min( q_cov[i][j], L_get_q_buf( cov_dtx_real[i][j], pFb->filterbank_num_bands ) ); - floatToFixed_arrL( cov_dtx_real[i][j], cov_dtx_real_fx[i][j], q_cov[i][j], pFb->filterbank_num_bands ); - floatToFixed_arrL( hCovEnc->pCov_dtx_state->pPrior_cov_real[i][j], hCovEnc->pCov_dtx_state->pPrior_cov_real_fx[i][j], q_cov[i][j], pFb->filterbank_num_bands ); - } - } -#endif - -#ifdef IVAS_FLOAT_FIXED - ivas_cov_smooth_process_fx( hCovEnc->pCov_dtx_state, cov_dtx_real_fx, pFb, start_band, end_band, num_ch, transient_det, q_cov ); -#else ivas_cov_smooth_process( hCovEnc->pCov_dtx_state, cov_dtx_real, pFb, start_band, end_band, num_ch, transient_det ); -#endif - -#ifdef IVAS_FLOAT_FIXED - for ( i = 0; i < num_ch; i++ ) - { - for ( j = 0; j < num_ch; j++ ) - { - fixedToFloat_arrL( cov_dtx_real_fx[i][j], cov_dtx_real[i][j], q_cov[i][j], pFb->filterbank_num_bands ); - fixedToFloat_arrL( hCovEnc->pCov_dtx_state->pPrior_cov_real_fx[i][j], hCovEnc->pCov_dtx_state->pPrior_cov_real[i][j], q_cov[i][j], pFb->filterbank_num_bands ); - } - } -#endif - hCovEnc->prior_dtx_present = 1; } else { if ( hCovEnc->prior_dtx_present == 0 ) { -#ifdef IVAS_FLOAT_FIXED + ivas_cov_smooth_process( hCovEnc->pCov_dtx_state, cov_dtx_real, pFb, start_band, end_band, num_ch, transient_det ); + hCovEnc->prior_dtx_present = 1; + } + else + { for ( i = 0; i < num_ch; i++ ) { - set_s( q_cov[i], 0, num_ch ); for ( j = 0; j < num_ch; j++ ) { - q_cov[i][j] = L_get_q_buf( hCovEnc->pCov_dtx_state->pPrior_cov_real[i][j], pFb->filterbank_num_bands ); - q_cov[i][j] = min( q_cov[i][j], L_get_q_buf( cov_dtx_real[i][j], pFb->filterbank_num_bands ) ); - floatToFixed_arrL( cov_dtx_real[i][j], cov_dtx_real_fx[i][j], q_cov[i][j], pFb->filterbank_num_bands ); - floatToFixed_arrL( hCovEnc->pCov_dtx_state->pPrior_cov_real[i][j], hCovEnc->pCov_dtx_state->pPrior_cov_real_fx[i][j], q_cov[i][j], pFb->filterbank_num_bands ); + mvr2r( hCovEnc->pCov_dtx_state->pPrior_cov_real[i][j], cov_dtx_real[i][j], pFb->filterbank_num_bands ); } } -#endif -#ifdef IVAS_FLOAT_FIXED - ivas_cov_smooth_process_fx( hCovEnc->pCov_dtx_state, cov_dtx_real_fx, pFb, start_band, end_band, num_ch, transient_det, q_cov ); -#else - ivas_cov_smooth_process( hCovEnc->pCov_dtx_state, cov_dtx_real, pFb, start_band, end_band, num_ch, transient_det ); -#endif + hCovEnc->prior_dtx_present = 1; + } + } + } + + return; +} + #ifdef IVAS_FLOAT_FIXED - for ( i = 0; i < num_ch; i++ ) +static void ivas_band_cov_fx( + Word32 **ppIn_FR_real, + Word32 **ppIn_FR_imag, + Word16 *q_In_FR, + const Word16 num_chans, + const Word16 num_bins, + Word16 stride, + Word32 **pFb_bin_to_band, + const Word16 *pFb_start_bin_per_band, + const Word16 *pFb_active_bins_per_band, + const Word16 start_band, + const Word16 end_band, + Word32 *cov_real[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH], + Word16 *q_cov_real[IVAS_SPAR_MAX_CH], + const Word16 HOA_md_ind[IVAS_SPAR_MAX_CH] ) +{ + Word16 i, j, k; + Word32 pV_re[L_FRAME48k]; + Word64 pV_re_64bit[L_FRAME48k]; + Word64 cov_real_64bit[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH][IVAS_MAX_NUM_BANDS]; + Word16 q_shift; + Word16 m, start_bin, active_bins; + + FOR( i = 0; i < num_chans; i++ ) + { + FOR( j = i; j < num_chans; j++ ) + { + Word16 i1 = HOA_md_ind[i]; + Word16 j1 = HOA_md_ind[j]; + move16(); + move16(); + + FOR( k = 0; k < num_bins; k++ ) + { + pV_re_64bit[k] = W_add( W_mult0_32_32( ppIn_FR_real[i1][k], ppIn_FR_real[j1][k] ), + W_mult0_32_32( ppIn_FR_imag[i1][k], ppIn_FR_imag[j1][k] ) ); //(q_In_FR[i1], q_In_FR[j1]) -> (q_In_FR[i1] + q_In_FR[j1]) + move64(); + } + + q_shift = 31; + move16(); + FOR( k = 0; k < num_bins; k++ ) + { + IF( pV_re_64bit[k] != 0 ) { - for ( j = 0; j < num_ch; j++ ) - { - fixedToFloat_arrL( cov_dtx_real_fx[i][j], cov_dtx_real[i][j], q_cov[i][j], pFb->filterbank_num_bands ); - fixedToFloat_arrL( hCovEnc->pCov_dtx_state->pPrior_cov_real_fx[i][j], hCovEnc->pCov_dtx_state->pPrior_cov_real[i][j], q_cov[i][j], pFb->filterbank_num_bands ); - } + q_shift = s_min( q_shift, W_norm( pV_re_64bit[k] ) ); } -#endif - - hCovEnc->prior_dtx_present = 1; } - else + FOR( k = 0; k < num_bins; k++ ) { - for ( i = 0; i < num_ch; i++ ) + pV_re[k] = W_extract_l( W_shl_nosat( pV_re_64bit[k], sub( q_shift, 32 ) ) ); //(q_In_FR[i1] + q_In_FR[j1]) + (q_shift - 32) + move32(); + /* perform rounding towards lower value for negative results */ + IF( pV_re[k] < 0 ) { - for ( j = 0; j < num_ch; j++ ) + pV_re[k] = L_add( pV_re[k], 1 ); + } + } + + FOR( k = start_band; k < end_band; k++ ) + { + Word64 temp; + const Word32 *p_bin_to_band = pFb_bin_to_band[k]; // Q22 + Word32 *cov_ptr = pV_re; + Word16 num_blocks; + Word16 blk; + + temp = 0; + move64(); + num_blocks = idiv1616( num_bins, stride ); + move16(); + start_bin = pFb_start_bin_per_band[k]; + move16(); + active_bins = pFb_active_bins_per_band[k]; + move16(); + + FOR( blk = 0; blk < num_blocks; blk++ ) + { + /* optional: add temporal weight here */ + FOR( m = start_bin; m < add( start_bin, active_bins ); m++ ) { - mvr2r( hCovEnc->pCov_dtx_state->pPrior_cov_real[i][j], cov_dtx_real[i][j], pFb->filterbank_num_bands ); + temp = W_add( temp, W_mult0_32_32( cov_ptr[m], p_bin_to_band[sub( m, start_bin )] ) ); // ((q_In_FR[i1] + q_In_FR[j1]) + (q_shift - 32), Q22) -> (q_In_FR[i1] + q_In_FR[j1] + (q_shift - 10) } + cov_ptr += stride; } + // What basop to add below???? + cov_real_64bit[i][j][k] = temp * (Word64) ( num_blocks ); // (q_In_FR[i1] + q_In_FR[j1] + (q_shift - 10) - guard_bits + move64(); + } + q_cov_real[i][j] = add( add( q_In_FR[i1], q_In_FR[j1] ), sub( q_shift, Q10 ) ); + move16(); + } + } - hCovEnc->prior_dtx_present = 1; + FOR( i = 0; i < num_chans; i++ ) + { + FOR( j = i; j < num_chans; j++ ) + { + q_shift = 31; + move16(); + FOR( k = start_band; k < end_band; k++ ) + { + IF( cov_real_64bit[i][j][k] != 0 ) + { + q_shift = s_min( q_shift, W_norm( cov_real_64bit[i][j][k] ) ); + } + } + FOR( k = start_band; k < end_band; k++ ) + { + cov_real[i][j][k] = W_extract_l( W_shl_nosat( cov_real_64bit[i][j][k], sub( q_shift, 32 ) ) ); + move32(); } + q_cov_real[i][j] = add( q_cov_real[i][j], sub( q_shift, 32 ) ); + move16(); } } -#ifdef IVAS_FLOAT_FIXED - for ( i = 0; i < num_ch; i++ ) + FOR( i = 0; i < num_chans; i++ ) { - for ( j = 0; j < num_ch; j++ ) + FOR( j = 0; j < i; j++ ) { - free( cov_real_fx[i][j] ); - cov_real_fx[i][j] = NULL; - free( cov_dtx_real_fx[i][j] ); - cov_dtx_real_fx[i][j] = NULL; + FOR( k = start_band; k < end_band; k++ ) + { + cov_real[i][j][k] = cov_real[j][i][k]; // q_cov_real[i][j] + move32(); + } + q_cov_real[i][j] = q_cov_real[j][i]; + move16(); } } -#endif -#ifdef IVAS_FLOAT_FIXED - return IVAS_ERR_OK; -#else return; -#endif } +#endif static void ivas_band_cov( diff --git a/lib_enc/ivas_spar_encoder.c b/lib_enc/ivas_spar_encoder.c index 75c174481..238a9ff7b 100644 --- a/lib_enc/ivas_spar_encoder.c +++ b/lib_enc/ivas_spar_encoder.c @@ -635,6 +635,18 @@ static ivas_error ivas_spar_cov_md_process( float *cov_dtx_real[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH]; float cov_real_buf[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH][IVAS_MAX_NUM_BANDS]; float cov_dtx_real_buf[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH][IVAS_MAX_NUM_BANDS]; +#ifdef IVAS_FLOAT_FIXED + Word32 *cov_real_fx[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH]; + Word32 *cov_dtx_real_fx[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH]; + Word16 *q_cov_real[IVAS_SPAR_MAX_CH]; + Word16 *q_cov_dtx_real[IVAS_SPAR_MAX_CH]; + Word32 cov_real_buf_fx[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH][IVAS_MAX_NUM_BANDS]; + Word32 cov_dtx_real_buf_fx[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH][IVAS_MAX_NUM_BANDS]; + Word32 *ppIn_FR_real_fx[IVAS_SPAR_MAX_CH], *ppIn_FR_imag_fx[IVAS_SPAR_MAX_CH]; + Word16 q_ppIn_FR[IVAS_SPAR_MAX_CH]; + Word16 input_frame; + Word16 nchan_fb_in; +#endif ivas_error error; error = IVAS_ERR_OK; @@ -681,8 +693,98 @@ static ivas_error ivas_spar_cov_md_process( } } +#ifdef IVAS_FLOAT_FIXED + FOR( i = 0; i < nchan_inp; i++ ) + { + FOR( j = 0; j < nchan_inp; j++ ) + { + cov_real_fx[i][j] = cov_real_buf_fx[i][j]; + cov_dtx_real_fx[i][j] = cov_dtx_real_buf_fx[i][j]; + FOR( b = hSpar->hFbMixer->pFb->filterbank_num_bands; b < IVAS_MAX_NUM_BANDS; b++ ) + { + cov_real_fx[i][j][b] = 0; + move16(); + cov_dtx_real_fx[i][j][b] = 0; + move16(); + } + } + IF( ( q_cov_real[i] = (Word16 *) malloc( sizeof( Word16 ) * nchan_inp ) ) == NULL ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for SPAR COV encoder Fixed" ); + } + set_s( q_cov_real[i], Q31, nchan_inp ); + IF( ( q_cov_dtx_real[i] = (Word16 *) malloc( sizeof( Word16 ) * nchan_inp ) ) == NULL ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for SPAR COV encoder Fixed" ); + } + set_s( q_cov_dtx_real[i], Q31, nchan_inp ); + } +#endif + +#ifdef IVAS_FLOAT_FIXED + input_frame = extract_l( Mpy_32_32( hEncoderConfig->input_Fs, ONE_BY_FRAMES_PER_SEC_Q31 ) ); + nchan_fb_in = hSpar->hFbMixer->fb_cfg->nchan_fb_in; + move16(); + + FOR( i = 0; i < nchan_fb_in; i++ ) + { + IF( ( ppIn_FR_real_fx[i] = (Word32 *) malloc( sizeof( Word32 ) * input_frame ) ) == NULL ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for SPAR encoder Fixed" ); + } + set_zero_fx( ppIn_FR_real_fx[i], input_frame ); + IF( ( ppIn_FR_imag_fx[i] = (Word32 *) malloc( sizeof( Word32 ) * input_frame ) ) == NULL ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for SPAR encoder Fixed" ); + } + set_zero_fx( ppIn_FR_imag_fx[i], input_frame ); + } + set_s( q_ppIn_FR, Q31, nchan_fb_in ); + + FOR( i = 0; i < nchan_fb_in; i++ ) + { + q_ppIn_FR[i] = L_get_q_buf1( ppIn_FR_real[i], input_frame ); + q_ppIn_FR[i] = min( q_ppIn_FR[i], L_get_q_buf1( ppIn_FR_imag[i], input_frame ) ); + floatToFixed_arrL( ppIn_FR_real[i], ppIn_FR_real_fx[i], q_ppIn_FR[i], input_frame ); + floatToFixed_arrL( ppIn_FR_imag[i], ppIn_FR_imag_fx[i], q_ppIn_FR[i], input_frame ); + } +#endif + +#ifdef IVAS_FLOAT_FIXED + ivas_enc_cov_handler_process_fx( hSpar->hCovEnc, ppIn_FR_real_fx, ppIn_FR_imag_fx, q_ppIn_FR, cov_real_fx, q_cov_real, cov_dtx_real_fx, q_cov_dtx_real, hSpar->hFbMixer->pFb, 0, hSpar->hFbMixer->pFb->filterbank_num_bands, nchan_inp, dtx_vad, transient_det, hSpar->hMdEnc->HOA_md_ind, + &hSpar->hMdEnc->spar_md.res_ind, remix_order_set[hSpar->hMdEnc->spar_md_cfg.remix_unmix_order], dyn_active_w_flag, nchan_transport, 1 ); +#else ivas_enc_cov_handler_process( hSpar->hCovEnc, ppIn_FR_real, ppIn_FR_imag, cov_real, cov_dtx_real, hSpar->hFbMixer->pFb, 0, hSpar->hFbMixer->pFb->filterbank_num_bands, nchan_inp, dtx_vad, transient_det, hSpar->hMdEnc->HOA_md_ind, &hSpar->hMdEnc->spar_md.res_ind, remix_order_set[hSpar->hMdEnc->spar_md_cfg.remix_unmix_order], dyn_active_w_flag, nchan_transport, 1 ); +#endif + +#ifdef IVAS_FLOAT_FIXED + FOR( i = 0; i < nchan_inp; i++ ) + { + FOR( j = 0; j < nchan_inp; j++ ) + { + Word16 k; + FOR( k = 0; k < hSpar->hFbMixer->pFb->filterbank_num_bands; k++ ) + { + cov_real[i][j][k] = me2f( cov_real_fx[i][j][k], sub( Q31, hSpar->hCovEnc->pCov_state->q_cov_real_per_band[i][j][k] ) ); + cov_dtx_real[i][j][k] = me2f( cov_dtx_real_fx[i][j][k], sub( Q31, hSpar->hCovEnc->pCov_dtx_state->q_cov_real_per_band[i][j][k] ) ); + } + } + free( q_cov_real[i] ); + q_cov_real[i] = NULL; + free( q_cov_dtx_real[i] ); + q_cov_dtx_real[i] = NULL; + } + // Note: No need to convert ppIn_FR_real_fx and ppIn_FR_imag_fx back to float as they are not used after ivas_spar_cov_md_process() + + FOR( i = 0; i < nchan_fb_in; i++ ) + { + free( ppIn_FR_real_fx[i] ); + ppIn_FR_real_fx[i] = NULL; + free( ppIn_FR_imag_fx[i] ); + ppIn_FR_imag_fx[i] = NULL; + } +#endif if ( nchan_transport > 1 && nchan_transport <= ( FOA_CHANNELS - 1 ) ) { diff --git a/lib_enc/ivas_stat_enc.h b/lib_enc/ivas_stat_enc.h index e804e272f..3e9ec271f 100644 --- a/lib_enc/ivas_stat_enc.h +++ b/lib_enc/ivas_stat_enc.h @@ -857,6 +857,9 @@ typedef struct ivas_enc_cov_handler_state_t int16_t prior_dtx_present; float bb_var_lt[FOA_CHANNELS]; int16_t prior_var_flag; +#ifdef IVAS_FLOAT_FIXED + Word32 bb_var_lt_fx[FOA_CHANNELS]; +#endif } ivas_enc_cov_handler_state_t; -- GitLab From 02f4dbe73dbd34a001b107c070bdd4e63ad2401a Mon Sep 17 00:00:00 2001 From: Sandesh Venkatesh Date: Wed, 3 Jul 2024 08:57:18 +0530 Subject: [PATCH 2/2] Clang formatting changes --- lib_com/ivas_stat_com.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib_com/ivas_stat_com.h b/lib_com/ivas_stat_com.h index 6e13c5f29..78227e56b 100644 --- a/lib_com/ivas_stat_com.h +++ b/lib_com/ivas_stat_com.h @@ -595,7 +595,7 @@ typedef struct ivas_masa_qmetadata_frame_struct #ifndef IVAS_FLOAT_FIXED float dir_comp_ratio; #else - Word16 dir_comp_ratio_fx; /* Q15 */ + Word16 dir_comp_ratio_fx; /* Q15 */ #endif uint8_t is_masa_ivas_format; -- GitLab