diff --git a/lib_com/ivas_cov_smooth.c b/lib_com/ivas_cov_smooth.c index e3715930012569590c0f2644614aac3e39ed7f9f..0c6ec76319cc7918769f648e074e7ac95fef11ac 100644 --- a/lib_com/ivas_cov_smooth.c +++ b/lib_com/ivas_cov_smooth.c @@ -44,6 +44,28 @@ #define BAND_SMOOTH_REST_START_IDX ( 2 ) +#ifdef IVAS_FLOAT_FIXED +/*-----------------------------------------------------------------------------------------* + * Function ivas_calculate_update_factor_fx() + * + * To calculate the update factor + *-----------------------------------------------------------------------------------------*/ + +static Word32 ivas_calculate_update_factor_fx( + Word32 *p_bin_to_band, + Word16 active_bins ) +{ + Word32 update_factor_temp = 0; + Word16 k; + + FOR( k = 0; k < active_bins; k++ ) + { + update_factor_temp += p_bin_to_band[k]; // Q22 + } + + return update_factor_temp; +} +#else /*-----------------------------------------------------------------------------------------* * Function ivas_calculate_update_factor() * @@ -64,6 +86,7 @@ static float ivas_calculate_update_factor( return update_factor_temp; } +#endif #ifdef IVAS_FLOAT_FIXED @@ -86,7 +109,7 @@ static void ivas_calculate_smoothning_factor_fx( Word16 tmp, exp_diff = 0; tmp = BASOP_Util_Divide3232_Scale( update_factor, L_shl( L_deposit_l( min_pool_size ), Q22 ), &exp_diff ); // (Q15 - exp_diff) - *Smoothing_factor = L_shl_sat( L_deposit_l( tmp ), ( Q15 + exp_diff ) ); // Q30 + *Smoothing_factor = L_shl_sat( L_deposit_l( tmp ), add( Q13, exp_diff ) ); // Q28 IF( NE_32( smooth_mode, COV_SMOOTH_MC ) ) { @@ -100,11 +123,11 @@ static void ivas_calculate_smoothning_factor_fx( } L_tmp = Mpy_32_16_1( smooth_fact, add( j, 1 ) ); // (Q31 , Q0) -> Q16 - *Smoothing_factor = Mpy_32_32( *Smoothing_factor, L_tmp ); // (Q30, Q16) -> Q15 - *Smoothing_factor = L_shl_sat( *Smoothing_factor, Q15 ); // Q30 + *Smoothing_factor = Mpy_32_32( *Smoothing_factor, L_tmp ); // (Q28, Q16) -> Q13 + *Smoothing_factor = L_shl_sat( *Smoothing_factor, Q15 ); // Q28 } - IF( *Smoothing_factor > max_update_rate ) // Q30 + IF( *Smoothing_factor > max_update_rate ) // Q28 { *Smoothing_factor = max_update_rate; } @@ -152,6 +175,51 @@ static void ivas_calculate_smoothning_factor( #endif +#ifdef IVAS_FLOAT_FIXED +/*-----------------------------------------------------------------------------------------* + * Function ivas_set_up_cov_smoothing_fx() + * + * Setup for covariance smoothing + *-----------------------------------------------------------------------------------------*/ + +static void ivas_set_up_cov_smoothing_fx( + ivas_cov_smooth_state_t *hCovState, + ivas_filterbank_t *pFb, + const Word32 max_update_rate, + const Word16 min_pool_size, + const COV_SMOOTHING_TYPE smooth_mode, /* i : flag multichannel vs SPAR */ + const Word32 ivas_total_brate ) +{ + Word16 j; + Word32 update_factor; + + IF( EQ_32( smooth_mode, COV_SMOOTH_MC ) ) + { + FOR( j = 0; j < pFb->filterbank_num_bands; j++ ) + { + 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] = (float) hCovState->pSmoothing_factor_fx[j] / ONE_IN_Q28; + } + } + ELSE + { + FOR( j = 0; j < pFb->filterbank_num_bands; j++ ) + { + Word32 *p_bin_to_band = pFb->fb_bin_to_band.pp_short_stride_bin_to_band_fx[j]; + 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] = (float) hCovState->pSmoothing_factor_fx[j] / ONE_IN_Q28; + } + } + + hCovState->prior_bank_idx = -1; + + return; +} +#else /*-----------------------------------------------------------------------------------------* * Function ivas_set_up_cov_smoothing() * @@ -168,23 +236,13 @@ static void ivas_set_up_cov_smoothing( { int16_t j; float update_factor; -#ifdef IVAS_FLOAT_FIXED - Word32 update_factor_fx, max_update_rate_fx; - max_update_rate_fx = (Word32) ( max_update_rate * ONE_IN_Q30 ); -#endif if ( smooth_mode == COV_SMOOTH_MC ) { for ( j = 0; j < pFb->filterbank_num_bands; j++ ) { int16_t active_bins = pFb->fb_bin_to_band.pFb_active_bins_per_band[j]; update_factor = ivas_calculate_update_factor( pFb->fb_bin_to_band.pFb_bin_to_band[j], active_bins ); -#ifdef IVAS_FLOAT_FIXED - update_factor_fx = (Word32) ( update_factor * ONE_IN_Q22 ); - ivas_calculate_smoothning_factor_fx( &hCovState->pSmoothing_factor_fx[j], update_factor_fx, min_pool_size, max_update_rate_fx, smooth_mode, ivas_total_brate, j ); - hCovState->pSmoothing_factor[j] = (float) hCovState->pSmoothing_factor_fx[j] / ONE_IN_Q30; -#else ivas_calculate_smoothning_factor( &hCovState->pSmoothing_factor[j], update_factor, min_pool_size, max_update_rate, smooth_mode, ivas_total_brate, j ); -#endif } } else @@ -194,13 +252,7 @@ static void ivas_set_up_cov_smoothing( float *p_bin_to_band = pFb->fb_bin_to_band.pp_short_stride_bin_to_band[j]; int16_t active_bins = pFb->fb_bin_to_band.p_short_stride_num_bins_per_band[j]; update_factor = ivas_calculate_update_factor( p_bin_to_band, active_bins ); -#ifdef IVAS_FLOAT_FIXED - update_factor_fx = (Word32) ( update_factor * ONE_IN_Q22 ); - ivas_calculate_smoothning_factor_fx( &hCovState->pSmoothing_factor_fx[j], update_factor_fx, min_pool_size, max_update_rate_fx, smooth_mode, ivas_total_brate, j ); - hCovState->pSmoothing_factor[j] = (float) hCovState->pSmoothing_factor_fx[j] / ONE_IN_Q30; -#else ivas_calculate_smoothning_factor( &hCovState->pSmoothing_factor[j], update_factor, min_pool_size, max_update_rate, smooth_mode, ivas_total_brate, j ); -#endif } } @@ -208,6 +260,7 @@ static void ivas_set_up_cov_smoothing( return; } +#endif /*------------------------------------------------------------------------- @@ -256,7 +309,11 @@ ivas_error ivas_spar_covar_smooth_enc_open( } } +#ifdef IVAS_FLOAT_FIXED + ivas_set_up_cov_smoothing_fx( hCovState, pFb, cov_smooth_cfg->max_update_rate_fx, cov_smooth_cfg->min_pool_size, smooth_mode, ivas_total_brate ); +#else ivas_set_up_cov_smoothing( hCovState, pFb, cov_smooth_cfg->max_update_rate, cov_smooth_cfg->min_pool_size, smooth_mode, ivas_total_brate ); +#endif *hCovState_out = hCovState; diff --git a/lib_com/ivas_fb_mixer.c b/lib_com/ivas_fb_mixer.c index dd93003afc522e36cc72c24f1e3f42e5046dba16..e7cdc7c5baadb772e981d64140e62ec8c9a6af0a 100644 --- a/lib_com/ivas_fb_mixer.c +++ b/lib_com/ivas_fb_mixer.c @@ -284,6 +284,12 @@ ivas_error ivas_FB_mixer_open( { return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for FB mixer encoder" ); } +#ifdef IVAS_FLOAT_FIXED + IF( ( hFbMixer->pFb->fb_bin_to_band.pFb_bin_to_band_fx[i] = (Word32 *) malloc( sizeof( Word32 ) * pActive_bins_per_band_abs[i] ) ) == NULL ) + { + return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for FB mixer encoder fixed" ); + } +#endif } } @@ -417,6 +423,10 @@ void ivas_FB_mixer_close( { free( hFbMixer->pFb->fb_bin_to_band.pFb_bin_to_band[i] ); hFbMixer->pFb->fb_bin_to_band.pFb_bin_to_band[i] = NULL; +#ifdef IVAS_FLOAT_FIXED + free( hFbMixer->pFb->fb_bin_to_band.pFb_bin_to_band_fx[i] ); + hFbMixer->pFb->fb_bin_to_band.pFb_bin_to_band_fx[i] = NULL; +#endif } } @@ -767,6 +777,9 @@ static int16_t ivas_calculate_abs_fr( { int16_t frame_len; float ppFilterbank_FRs_s[L_FRAME48k]; +#ifdef IVAS_FLOAT_FIXED + Word32 ppFilterbank_FRs_s_fx[L_FRAME48k]; +#endif int16_t bands = pFb->filterbank_num_bands; int16_t i, j, num_active_bands = 0; int16_t idx_short_stride_bin_to_band = 0; @@ -780,30 +793,55 @@ static int16_t ivas_calculate_abs_fr( int16_t short_mdft_start_bin = -1; float short_stride_pow_spec[MDFT_FB_BANDS_240]; float short_stride_nrg = 0.0f; +#ifdef IVAS_FLOAT_FIXED + Word32 short_stride_pow_spec_fx[MDFT_FB_BANDS_240]; + Word32 short_stride_nrg_fx = 0; + Word16 exp_diff = 0, tmp; +#endif float cldfb_nrg = 0.0f; int16_t short_stride = pFb->fb_bin_to_band.short_stride; const int16_t num_bins_per_short_stride_bin = ( const int16_t )( ( sampling_rate / FRAMES_PER_SEC ) / short_stride ); const int16_t num_bins_per_cldfb_band = ( const int16_t )( ( sampling_rate / FRAMES_PER_SEC ) / pFb->fb_bin_to_band.num_cldfb_bands ); float short_stride_max_per_spar_band = 1e-9f; +#ifdef IVAS_FLOAT_FIXED + Word32 short_stride_max_per_spar_band_fx = 1; +#endif /*loop over all stored Filter Bank Response MDFT coefficients*/ set_f( short_stride_pow_spec, 0, MDFT_FB_BANDS_240 ); +#ifdef IVAS_FLOAT_FIXED + set_l( short_stride_pow_spec_fx, 0, MDFT_FB_BANDS_240 ); +#endif for ( j = start_offset; j < num_bins + start_offset; j++ ) { float sq_abs; +#ifdef IVAS_FLOAT_FIXED + Word32 sq_abs_fx; +#endif /*calculate bin energy */ IVAS_CALCULATE_SQ_ABS( *long_mdft_ptr_re, *long_mdft_ptr_im, sq_abs ); +#ifdef IVAS_FLOAT_FIXED + sq_abs_fx = (Word32) ( sq_abs * ONE_IN_Q22 ); +#endif long_mdft_ptr_re++; long_mdft_ptr_im++; /* accumulate bin energies within a short stride bin */ short_stride_nrg += sq_abs; +#ifdef IVAS_FLOAT_FIXED + short_stride_nrg_fx = L_add( short_stride_nrg_fx, sq_abs_fx ); +#endif if ( !( ( j + 1 ) % num_bins_per_short_stride_bin ) ) { /* new short stride bin */ short_stride_pow_spec[j / num_bins_per_short_stride_bin] = short_stride_nrg; /* energy rather than magnitude works better for covariance weighting*/ short_stride_max_per_spar_band = max( short_stride_nrg, short_stride_max_per_spar_band ); /*compute highest magnitude per band*/ short_stride_nrg = 0.0f; +#ifdef IVAS_FLOAT_FIXED + short_stride_pow_spec_fx[j / num_bins_per_short_stride_bin] = short_stride_nrg_fx; /* energy rather than magnitude works better for covariance weighting*/ + short_stride_max_per_spar_band_fx = max( short_stride_nrg_fx, short_stride_max_per_spar_band_fx ); /*compute highest magnitude per band*/ + short_stride_nrg_fx = 0; +#endif } /* accumulate bin energies within a CLDFB band */ @@ -821,7 +859,17 @@ static int16_t ivas_calculate_abs_fr( /* normalize and sparsify the energies */ short_stride_pow_spec[j] /= short_stride_max_per_spar_band; short_stride_pow_spec[j] = max( short_stride_pow_spec[j] - 0.3f, 0.0f ) / 0.7f; +#ifdef IVAS_FLOAT_FIXED + tmp = BASOP_Util_Divide3232_Scale( short_stride_pow_spec_fx[j], short_stride_max_per_spar_band_fx, &exp_diff ); + short_stride_pow_spec_fx[j] = L_shl( L_deposit_l( tmp ), add( Q7, exp_diff ) ); // Q22 + short_stride_pow_spec_fx[j] = L_max( L_sub( short_stride_pow_spec_fx[j], (Word32) ( 0.3f * ONE_IN_Q22 ) ), 0 ); + tmp = BASOP_Util_Divide3232_Scale( short_stride_pow_spec_fx[j], (Word32) ( 0.7f * ONE_IN_Q22 ), &exp_diff ); + short_stride_pow_spec_fx[j] = L_shl( L_deposit_l( tmp ), add( Q7, exp_diff ) ); // Q22 + + IF( GT_32( short_stride_pow_spec_fx[j], 0 ) ) +#else if ( short_stride_pow_spec[j] > 0.0f ) +#endif { assert( idx_short_stride_bin_to_band < 2 * MDFT_FB_BANDS_240 ); /* array size of p_short_stride_bin_to_band */ if ( short_mdft_start_bin == -1 ) @@ -829,8 +877,17 @@ static int16_t ivas_calculate_abs_fr( short_mdft_start_bin = j; pFb->fb_bin_to_band.p_short_stride_start_bin_per_band[i] = j; pFb->fb_bin_to_band.pp_short_stride_bin_to_band[i] = &pFb->fb_bin_to_band.p_short_stride_bin_to_band[idx_short_stride_bin_to_band]; +#ifdef IVAS_FLOAT_FIXED + pFb->fb_bin_to_band.pp_short_stride_bin_to_band_fx[i] = &pFb->fb_bin_to_band.p_short_stride_bin_to_band_fx[idx_short_stride_bin_to_band]; +#endif } +#ifdef IVAS_FLOAT_FIXED + pFb->fb_bin_to_band.p_short_stride_bin_to_band[idx_short_stride_bin_to_band] = short_stride_pow_spec[j]; + pFb->fb_bin_to_band.p_short_stride_bin_to_band_fx[idx_short_stride_bin_to_band] = short_stride_pow_spec_fx[j]; + idx_short_stride_bin_to_band++; +#else pFb->fb_bin_to_band.p_short_stride_bin_to_band[idx_short_stride_bin_to_band++] = short_stride_pow_spec[j]; +#endif pFb->fb_bin_to_band.p_short_stride_num_bins_per_band[i]++; } } @@ -872,6 +929,9 @@ static int16_t ivas_calculate_abs_fr( frame_len = (int16_t) ( sampling_rate / FRAMES_PER_SEC ); set_f( ppFilterbank_FRs_s, 0, frame_len ); +#ifdef IVAS_FLOAT_FIXED + set_l( ppFilterbank_FRs_s_fx, 0, frame_len ); +#endif /*Commented logic is for calculating number of active bands, can be removed if not needed */ for ( i = 0; i < bands; i++ ) @@ -903,10 +963,19 @@ static int16_t ivas_calculate_abs_fr( if ( j < ( abs_active_bins + abs_start_offset ) && j >= abs_start_offset && alloc_fb_resp != -1 ) { +#ifdef IVAS_FLOAT_FIXED + pFb->fb_bin_to_band.pFb_bin_to_band[i][idx] = temp; + pFb->fb_bin_to_band.pFb_bin_to_band_fx[i][idx] = (Word32) ( temp * ONE_IN_Q22 ); + idx = add( idx, 1 ); +#else pFb->fb_bin_to_band.pFb_bin_to_band[i][idx++] = temp; +#endif } ppFilterbank_FRs_s[j] += temp; +#ifdef IVAS_FLOAT_FIXED + ppFilterbank_FRs_s_fx[j] = L_add( ppFilterbank_FRs_s_fx[j], (Word32) ( temp * ONE_IN_Q22 ) ); +#endif } } @@ -915,6 +984,9 @@ static int16_t ivas_calculate_abs_fr( if ( ppFilterbank_FRs_s[i] < 0.1f ) { ppFilterbank_FRs_s[i] = 0.1f; +#ifdef IVAS_FLOAT_FIXED + ppFilterbank_FRs_s_fx[i] = (Word32) ( 0.1f * ONE_IN_Q22 ); +#endif } } @@ -924,10 +996,17 @@ static int16_t ivas_calculate_abs_fr( { int16_t abs_active_bins = pFb->fb_bin_to_band.pFb_active_bins_per_band[j]; int16_t abs_start_offset = pFb->fb_bin_to_band.pFb_start_bin_per_band[j]; +#ifdef IVAS_FLOAT_FIXED + Word16 exp_diff = 0, tmp; +#endif for ( i = 0; i < abs_active_bins; i++ ) { pFb->fb_bin_to_band.pFb_bin_to_band[j][i] /= ppFilterbank_FRs_s[i + abs_start_offset]; +#ifdef IVAS_FLOAT_FIXED + tmp = BASOP_Util_Divide3232_Scale( pFb->fb_bin_to_band.pFb_bin_to_band_fx[j][i], ppFilterbank_FRs_s_fx[i + abs_start_offset], &exp_diff ); + pFb->fb_bin_to_band.pFb_bin_to_band_fx[j][i] = L_shl( L_deposit_l( tmp ), add( Q7, exp_diff ) ); // Q22 +#endif /*if(pFb->fb_bin_to_band.pFb_bin_to_band[j][i] > 0.5f) { num_active_bands = j + 1; @@ -1047,6 +1126,9 @@ static ivas_error ivas_filterbank_setup( /*pFb->fb_bin_to_band.cldfb_stride = ( int16_t )( ( sampling_rate / FRAMES_PER_SEC ) / CLDFB_NO_COL_MAX );*/ /* equals num_cldfb_bands*/ pFb->fb_bin_to_band.short_stride = (int16_t) ( ( sampling_rate / FRAMES_PER_SEC ) / 4 ); set_f( pFb->fb_bin_to_band.p_short_stride_bin_to_band, 0.0f, 2 * MDFT_FB_BANDS_240 ); +#ifdef IVAS_FLOAT_FIXED + set_l( pFb->fb_bin_to_band.p_short_stride_bin_to_band_fx, 0, 2 * MDFT_FB_BANDS_240 ); +#endif set_s( pFb->fb_bin_to_band.p_cldfb_map_to_spar_band, 0, CLDFB_NO_CHANNELS_MAX ); set_s( pFb->fb_bin_to_band.p_spar_start_bands, 0, CLDFB_NO_CHANNELS_MAX ); @@ -1055,6 +1137,9 @@ static ivas_error ivas_filterbank_setup( pFb->fb_bin_to_band.p_short_stride_num_bins_per_band[j] = 0; /* aka num_active_bins per SPAR band */ pFb->fb_bin_to_band.p_short_stride_start_bin_per_band[j] = 0; /* first considered bin index per SPAR band */ pFb->fb_bin_to_band.pp_short_stride_bin_to_band[j] = NULL; +#ifdef IVAS_FLOAT_FIXED + pFb->fb_bin_to_band.pp_short_stride_bin_to_band_fx[j] = NULL; +#endif for ( i = 0; i < CLDFB_NO_CHANNELS_MAX; i++ ) { pFb->fb_bin_to_band.pp_cldfb_weights_per_spar_band[i][j] = 0.0f; diff --git a/lib_com/ivas_stat_com.h b/lib_com/ivas_stat_com.h index 857dd332fff0de39a5657c4c347771d6d505ea02..fe9c6ca9c71a50b3277bf774fcf81ee89c317ac2 100644 --- a/lib_com/ivas_stat_com.h +++ b/lib_com/ivas_stat_com.h @@ -371,6 +371,9 @@ typedef struct ivas_cov_smooth_cfg_t int16_t min_pool_size; int16_t max_bands; int16_t num_bins; +#ifdef IVAS_FLOAT_FIXED + Word32 max_update_rate_fx; +#endif } ivas_cov_smooth_cfg_t; @@ -770,6 +773,11 @@ typedef struct ivas_fb_bin_to_band_data_t float *pp_short_stride_bin_to_band[IVAS_MAX_NUM_FB_BANDS]; int16_t short_stride; int16_t num_cldfb_bands; +#ifdef IVAS_FLOAT_FIXED + Word32 *pFb_bin_to_band_fx[IVAS_MAX_NUM_FB_BANDS]; + Word32 p_short_stride_bin_to_band_fx[2 * MDFT_FB_BANDS_240]; + Word32 *pp_short_stride_bin_to_band_fx[IVAS_MAX_NUM_FB_BANDS]; +#endif } ivas_fb_bin_to_band_data_t; diff --git a/lib_enc/ivas_enc_cov_handler.c b/lib_enc/ivas_enc_cov_handler.c index a73397454ca2123b2751e180c53557213a1570db..9a11ad9846e92d4fd563271bc59cddf96478a9ab 100644 --- a/lib_enc/ivas_enc_cov_handler.c +++ b/lib_enc/ivas_enc_cov_handler.c @@ -80,11 +80,19 @@ 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_Q28 ); // Q28 +#else cov_smooth_cfg.max_update_rate = MAX_UPDATE_RATE; +#endif cov_smooth_cfg.min_pool_size = MIN_POOL_SIZE; if ( smooth_mode == COV_SMOOTH_MC ) { +#ifdef IVAS_FLOAT_FIXED + cov_smooth_cfg.max_update_rate_fx = (Word32) ( 1.0f * ONE_IN_Q28 ); // Q28 +#else cov_smooth_cfg.max_update_rate = 1.0f; +#endif cov_smooth_cfg.min_pool_size = 20; } @@ -93,7 +101,11 @@ ivas_error ivas_spar_covar_enc_open( return error; } +#ifdef IVAS_FLOAT_FIXED + cov_smooth_cfg.max_update_rate_fx = (Word32) ( MAX_UPDATE_RATE_DTX * ONE_IN_Q28 ); // Q28 +#else cov_smooth_cfg.max_update_rate = MAX_UPDATE_RATE_DTX; +#endif 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 )