Commit 7cdb2ffa authored by Sandesh Venkatesh's avatar Sandesh Venkatesh
Browse files

Few functions in ivas_cov_smooth.c converted to fxd

Converted ivas_calculate_update_factor and
ivas_set_up_cov_smoothing functions to fixed point.
parent 1ba24726
Loading
Loading
Loading
Loading
Loading
+77 −20
Original line number Diff line number Diff line
@@ -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;

+85 −0
Original line number Diff line number Diff line
@@ -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;
+8 −0
Original line number Diff line number Diff line
@@ -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;

+12 −0
Original line number Diff line number Diff line
@@ -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 )