Commit bbfc4049 authored by Sandesh Venkatesh's avatar Sandesh Venkatesh
Browse files

Merge branch 'ivas_tools_funcs_enc_integration' into 'main'

Encoder related ivas_tools functions converted to fxd and integrated

See merge request !413
parents d00833ab 5f41b03b
Loading
Loading
Loading
Loading
+15 −0
Original line number Diff line number Diff line
@@ -3459,6 +3459,13 @@ float sumAbs(
    const int16_t lvec                                          /* i  : length of input vector                  */
);

#ifdef IVAS_FLOAT_FIXED
Word32 sumAbs_fx(
    const Word32 *vec,                                           /* i  : input vector                            */
    const Word16 lvec                                          /* i  : length of input vector                  */
);
#endif

void mvc2c(
    const uint8_t x[],                                          /* i  : input vector                            */
    uint8_t y[],                                                /* o  : output vector                           */
@@ -3472,6 +3479,14 @@ float dot_product_cholesky(
    const int16_t N                                             /* i  : vector & matrix size                    */
);

#ifdef IVAS_FLOAT_FIXED
Word32 dot_product_cholesky_fx(
    const Word32 *x, /* i  : vector x                        */
    const Word32 *A, /* i  : Cholesky  matrix A              */
    const Word16 N /* i  : vector & matrix size            */
);
#endif

#ifdef IVAS_FLOAT_FIXED
void v_mult_mat_fx(
    Word32 *y_fx,                                               /* o  : the product x*A                         */
+53 −0
Original line number Diff line number Diff line
@@ -76,6 +76,26 @@ float sumAbs(
    return tmp;
}

#ifdef IVAS_FLOAT_FIXED
Word32 sumAbs_fx(
    const Word32 *vec, /* i  : input vector                     */
    const Word16 lvec  /* i  : length of input vector           */
)
{
    Word16 i;
    Word32 tmp;

    tmp = 0;
    move32();
    FOR( i = 0; i < lvec; i++ )
    {
        tmp = L_add( tmp, L_abs( vec[i] ) );
    }

    return tmp;
}
#endif

/*---------------------------------------------------------------------*
 * mvc2c()
 *
@@ -893,6 +913,39 @@ float dot_product_cholesky(
    return suma;
}

#ifdef IVAS_FLOAT_FIXED
Word32 dot_product_cholesky_fx(
    const Word32 *x, /* i  : vector x                        */
    const Word32 *A, /* i  : Cholesky  matrix A              */
    const Word16 N   /* i  : vector & matrix size            */
)
{
    Word16 i, j;
    Word32 suma, tmp_sum;
    const Word32 *pt_x, *pt_A;

    pt_A = A;
    suma = 0;
    move32();

    FOR( i = 0; i < N; i++ )
    {
        tmp_sum = 0;
        move32();
        pt_x = x;
        FOR( j = 0; j <= i; j++ )
        {
            tmp_sum = L_add( tmp_sum, Mpy_32_32( *pt_x++, *pt_A++ ) );
        }

        suma = L_add( suma, Mpy_32_32( tmp_sum, tmp_sum ) );
    }

    return suma;
}

#endif

#ifdef IVAS_FLOAT_FIXED
/*---------------------------------------------------------------------*
 * v_mult_mat_fx()
+292 −0
Original line number Diff line number Diff line
@@ -42,6 +42,7 @@
#include "rom_com.h"
#include "ivas_rom_com.h"
#include "prot_fx1.h"
#include "prot_fx2.h"

/*---------------------------------------------------------------
 * Local function prototypes
@@ -371,6 +372,7 @@ static void utilCrossCorr(
 *  Non-causal shift estimation to encode future samples.
 * ---------------------------------------------------------------*/

#ifdef IVAS_FLOAT_FIXED
static void corrStatsEst(
    STEREO_TCA_ENC_HANDLE hStereoTCA,    /* i/o: Stereo TCA Encoder handle   */
    const float *buf1,                   /* i  : channel 1                   */
@@ -431,8 +433,31 @@ static void corrStatsEst(
    }
    mvr2r( corrEst, hStereoTCA->corrEstPrev[2], tempLen );

#ifdef IVAS_FLOAT_FIXED
    Word32 buf1_fx[160];
    Word32 buf2_fx[160];
    Word16 buf1_q, buf2_q, guard_bits;
    Word32 temp_A_fx, temp_B_fx;
    f2me_buf( buf1, buf1_fx, &buf1_q, 160 );
    f2me_buf( buf2, buf2_fx, &buf2_q, 160 );
    buf1_q = sub( 31, buf1_q );
    buf2_q = sub( 31, buf2_q );
    Word16 buf_q = s_min( buf1_q, buf2_q );
    guard_bits = find_guarded_bits_fx( 160 );
    scale_sig32( buf1_fx, 160, sub( sub( buf_q, guard_bits ), buf1_q ) );
    scale_sig32( buf2_fx, 160, sub( sub( buf_q, guard_bits ), buf2_q ) );
    buf_q = sub( buf_q, guard_bits );
#endif

#ifdef IVAS_FLOAT_FIXED
    temp_A_fx = sumAbs_fx( buf1_fx, L_FRAME_DS - L_XCORRMEM_DS ) + sumAbs_fx( buf2_fx, L_FRAME_DS - L_XCORRMEM_DS );
    temp_B_fx = sumAbs_fx( buf1_fx + ( L_FRAME_DS - L_XCORRMEM_DS ), L_XCORRMEM_DS ) + sumAbs_fx( buf2_fx + ( L_FRAME_DS - L_XCORRMEM_DS ), L_XCORRMEM_DS );
    temp_A = fixedToFloat( temp_A_fx, buf_q );
    temp_B = fixedToFloat( temp_B_fx, buf_q );
#else
    temp_A = sumAbs( buf1, L_FRAME_DS - L_XCORRMEM_DS ) + sumAbs( buf2, L_FRAME_DS - L_XCORRMEM_DS );
    temp_B = sumAbs( buf1 + ( L_FRAME_DS - L_XCORRMEM_DS ), L_XCORRMEM_DS ) + sumAbs( buf2 + ( L_FRAME_DS - L_XCORRMEM_DS ), L_XCORRMEM_DS );
#endif
    tempF = temp_A + temp_B + hStereoTCA->mem_tempF;
    hStereoTCA->mem_tempF = temp_B;

@@ -637,7 +662,274 @@ static void corrStatsEst(

    return;
}
#else
static void corrStatsEst(
    STEREO_TCA_ENC_HANDLE hStereoTCA,    /* i/o: Stereo TCA Encoder handle   */
    const float *buf1,                   /* i  : channel 1                   */
    const float *buf2,                   /* i  : channel 2                   */
    const int16_t bufLenDS,              /* i  : buffer length               */
    const int16_t dsFactor,              /* i  : buffer length               */
    const int16_t vad_flag1,             /* i  : VAD flag channel 1          */
    const int16_t vad_flag2,             /* i  : VAD flag channel 2          */
    STEREO_CLASSIF_HANDLE hStereoClassif /* i/o: stereo classifier handle    */
)
{
    int16_t lagSearchRange[2];
    float corrEst[2 * L_NCSHIFT_DS + 1];
    int16_t corrLagStats[3];
    float *tempRK;
    const float *winInterp;
    float rInterp[MAX_INTERPOLATE];
    int16_t interpMin, interpMax, interpLen;
    int16_t i, j, k, m;
    float tempF, alpha;
    float win_bias;
    int16_t tempLen, win_width;
    float loc_weight_win[4 * L_NCSHIFT_DS + 1];
    float X_hat, Y_hat, XY_hat, X_SQR_hat;
    float alpha_reg, beta_reg, reg_prv_corr, dist_reg_prv_corr, bias_par, width_par;
    float k1, k2, temp_A, temp_B;
    int16_t stmp;
    float corrEst_ncorr;

    /* init of regression parameters*/
    X_hat = 0;
    X_SQR_hat = 0;
    XY_hat = 0;

    /* Initializations */
    alpha = 0.7f;
    lagSearchRange[0] = -L_NCSHIFT_DS;
    lagSearchRange[1] = L_NCSHIFT_DS;
    tempLen = ( 2 * L_NCSHIFT_DS + 1 );

    set_s( corrLagStats, 0, 3 );

    /* First iteration of xcorr estimation */
    utilCrossCorr_mod( hStereoTCA, buf1, buf2, corrEst, lagSearchRange, bufLenDS - L_XCORRMEM_DS );

    /* calculate features for the UNCLR classifier */
    unclr_calc_corr_features( hStereoClassif, hStereoTCA, buf1, buf2, bufLenDS - L_XCORRMEM_DS, corrEst, lagSearchRange, &corrEst_ncorr );

    for ( i = 1; i < 3; i++ )
    {
        v_add( hStereoTCA->corrEstPrev[i], hStereoTCA->corrEstPrev[0], hStereoTCA->corrEstPrev[0], tempLen );
    }

    /* back up the corrEst */
    for ( i = 0; i < 2; i++ )
    {
        mvr2r( hStereoTCA->corrEstPrev[i + 1], hStereoTCA->corrEstPrev[i], tempLen );
    }
    mvr2r( corrEst, hStereoTCA->corrEstPrev[2], tempLen );

    temp_A = sumAbs( buf1, L_FRAME_DS - L_XCORRMEM_DS ) + sumAbs( buf2, L_FRAME_DS - L_XCORRMEM_DS );
    temp_B = sumAbs( buf1 + ( L_FRAME_DS - L_XCORRMEM_DS ), L_XCORRMEM_DS ) + sumAbs( buf2 + ( L_FRAME_DS - L_XCORRMEM_DS ), L_XCORRMEM_DS );
    tempF = temp_A + temp_B + hStereoTCA->mem_tempF;
    hStereoTCA->mem_tempF = temp_B;

    alpha = 0.93f;
    if ( tempF > 4.0f * hStereoTCA->ica_envVarLT )
    {
        alpha = 0.83f;
    }
    else if ( tempF > 2.0f * hStereoTCA->ica_envVarLT )
    {
        alpha = 0.85f;
    }
    else if ( tempF > hStereoTCA->ica_envVarLT )
    {
        alpha = 0.90f;
    }

    hStereoTCA->corrStatsSmoothFac = alpha;

    /* long term corr Stats estimation */
    v_multc( hStereoTCA->corrEstLT, alpha, hStereoTCA->corrEstLT, 2 * L_NCSHIFT_DS + 1 );
    v_multc( corrEst, 1.0f - alpha, corrEst, 2 * L_NCSHIFT_DS + 1 );
    v_add( hStereoTCA->corrEstLT, corrEst, hStereoTCA->corrEstLT, 2 * L_NCSHIFT_DS + 1 );

    hStereoTCA->ica_envVarLT = SMOOTH_ENV_FACTOR * hStereoTCA->ica_envVarLT + ( 1 - SMOOTH_ENV_FACTOR ) * tempF;

    mvr2r( hStereoTCA->corrEstLT, corrEst, 2 * L_NCSHIFT_DS + 1 );
    Y_hat = hStereoTCA->delay_0_mem[0];
    /* Note: keep X_hat and X_SQR_hat calculations inside the loop to allow future tuning of MAX_DELAYREGLEN */
    for ( i = 1; i < MAX_DELAYREGLEN; i++ )
    {
        X_hat += (float) i;
        Y_hat += hStereoTCA->delay_0_mem[i];
        XY_hat += i * hStereoTCA->delay_0_mem[i];
        X_SQR_hat += (float) ( i * i );
    }
    X_hat *= INV_MAX_DELAYREGLEN;
    Y_hat *= INV_MAX_DELAYREGLEN;
    XY_hat *= INV_MAX_DELAYREGLEN;
    X_SQR_hat *= INV_MAX_DELAYREGLEN;

    beta_reg = 0;
    tempF = X_SQR_hat - ( X_hat * X_hat );
    if ( tempF != 0 )
    {
        beta_reg = ( XY_hat - X_hat * Y_hat ) / tempF;
    }
    alpha_reg = ( Y_hat - beta_reg * X_hat );
    reg_prv_corr = beta_reg * MAX_DELAYREGLEN + alpha_reg;

    if ( TRUNC( reg_prv_corr ) <= -L_NCSHIFT_DS )
    {
        reg_prv_corr = -L_NCSHIFT_DS + 1;
    }

    if ( TRUNC( reg_prv_corr ) >= L_NCSHIFT_DS )
    {
        reg_prv_corr = L_NCSHIFT_DS - 1;
    }

    bias_par = A_BIAS * hStereoTCA->smooth_dist_reg_prv_corr + B_BIAS;
    bias_par = min( bias_par, XH_BIAS );
    bias_par = max( bias_par, XL_BIAS );

    width_par = A_WIDTH * hStereoTCA->smooth_dist_reg_prv_corr + B_WIDTH;
    width_par = min( width_par, XH_WIDTH );
    width_par = max( width_par, XL_WIDTH );

    win_width = (int16_t) ( width_par * ( 4 * L_NCSHIFT_DS + 1 ) );
    win_bias = bias_par;
    k1 = 0.5f * ( 1.0f + win_bias );
    k2 = 0.5f * ( 1.0f - win_bias );

    for ( i = 0; i < ( 2 * L_NCSHIFT_DS - 2 * win_width ); i++ )
    {
        loc_weight_win[i] = win_bias;
    }

    for ( i = ( 2 * L_NCSHIFT_DS - 2 * win_width ); i <= ( 2 * L_NCSHIFT_DS + 2 * win_width ); i++ )
    {
        loc_weight_win[i] = k1 + k2 * cosf( EVS_PI * ( ( i - 2 * L_NCSHIFT_DS ) / ( 2.0f * win_width ) ) );
    }

    for ( i = ( 2 * L_NCSHIFT_DS + 2 * win_width ); i < ( 4 * L_NCSHIFT_DS + 1 ); i++ )
    {
        loc_weight_win[i] = win_bias;
    }

    for ( i = 0, j = L_NCSHIFT_DS - TRUNC( reg_prv_corr ); i < 2 * L_NCSHIFT_DS + 1; i++, j++ )
    {
        corrEst[i] *= loc_weight_win[j];
    }

    if ( hStereoTCA->prevTargetGain < 0.8f && vad_flag1 )
    {
        /* ch 2 is prev reference channel */
        v_multc( corrEst, 1.2f, corrEst, L_NCSHIFT_DS + 1 );
        v_multc( corrEst + L_NCSHIFT_DS + 1, 0.833f, corrEst + L_NCSHIFT_DS + 1, L_NCSHIFT_DS );
    }
    else if ( hStereoTCA->prevTargetGain > 1.2f && vad_flag1 )
    {
        /* ch 1 is prev reference channel */
        v_multc( corrEst, 0.833f, corrEst, L_NCSHIFT_DS );
        v_multc( corrEst + L_NCSHIFT_DS, 1.2f, corrEst + L_NCSHIFT_DS, L_NCSHIFT_DS + 1 );
    }

    if ( corrEst_ncorr > 0.8f && vad_flag1 )
    {
        i = max( 0, hStereoTCA->prevCorrLagStats[0] - 1 + L_NCSHIFT_DS );
        j = min( 2 * L_NCSHIFT_DS, hStereoTCA->prevCorrLagStats[0] + 1 + L_NCSHIFT_DS );
        k = j - i + 1;
        v_multc( corrEst + i, 1.2f, corrEst + i, k );
    }

    /* Initial corr lag estimate */
    corrLagStats[0] = maximum( corrEst, ( lagSearchRange[1] - lagSearchRange[0] + 1 ), &tempF );
    corrLagStats[0] += lagSearchRange[0];

    stmp = corrLagStats[0] * dsFactor;
    hStereoClassif->unclr_fv[E_corrLagStats0] = (float) stmp;
    hStereoClassif->xtalk_fv[E_corrLagStats0] = (float) stmp;
    hStereoClassif->xtalk_fv[E_ica_corr_value0] = tempF;

    if ( vad_flag1 == 0 && alpha > 0.7f )
    {
        corrLagStats[0] = 0;
    }

    dist_reg_prv_corr = fabsf( reg_prv_corr - corrLagStats[0] );

    if ( vad_flag1 == 1 && vad_flag2 == 1 )
    {
        hStereoTCA->smooth_dist_reg_prv_corr = SMOOTH_DIST_FACTOR * hStereoTCA->smooth_dist_reg_prv_corr + ( 1.0f - SMOOTH_DIST_FACTOR ) * dist_reg_prv_corr;

        mvr2r( &( hStereoTCA->delay_0_mem[1] ), &( hStereoTCA->delay_0_mem[0] ), MAX_DELAYREGLEN - 1 );

        hStereoTCA->delay_0_mem[MAX_DELAYREGLEN - 1] = 0.2f * hStereoTCA->delay_0_mem[MAX_DELAYREGLEN - 1] + 0.8f * corrLagStats[0];

        if ( fabsf( reg_prv_corr - hStereoTCA->delay_0_mem[0] ) > 25 )
        {
            set_f( &( hStereoTCA->delay_0_mem[0] ), hStereoTCA->delay_0_mem[MAX_DELAYREGLEN - 1], MAX_DELAYREGLEN - 1 );
        }
    }
    else
    {
        hStereoTCA->smooth_dist_reg_prv_corr = 0.;
    }

    if ( vad_flag1 == 0 || vad_flag2 == 0 )
    {
        corrLagStats[0] = TRUNC( hStereoTCA->delay_0_mem[MAX_DELAYREGLEN - 1] );
    }

    /* second iteration of xcorr update @ inputFs with interp*/
    tempRK = hStereoTCA->corrEstLT - lagSearchRange[0] + corrLagStats[0];
    set_f( rInterp, 0, MAX_INTERPOLATE );

    /* select the Rk interp sinc window */
    winInterp = ica_sincInterp4 + SINC_ORDER1;
    if ( dsFactor == 2 )
    {
        winInterp = ica_sincInterp2 + SINC_ORDER1;
    }
    else if ( dsFactor == 6 )
    {
        winInterp = ica_sincInterp6 + SINC_ORDER1;
    }

    corrLagStats[1] = corrLagStats[0] * dsFactor;

    interpMin = max( -( dsFactor - 1 ), -corrLagStats[1] - L_NCSHIFT_DS * dsFactor );
    interpMax = min( ( dsFactor - 1 ), L_NCSHIFT_DS * dsFactor - corrLagStats[1] );
    interpLen = interpMax - interpMin + 1;

    for ( i = interpMin, k = 0; i <= interpMax; i++, k++ )
    {
        rInterp[k] = 0.0f;
        for ( j = -SINC_ORDER1 / dsFactor; j <= SINC_ORDER1 / dsFactor; j++ )
        {
            m = j * dsFactor;
            if ( ( m - i >= -SINC_ORDER1 ) && ( m - i <= SINC_ORDER1 ) )
            {
                if ( j > lagSearchRange[1] - corrLagStats[0] )
                {
                    rInterp[k] += winInterp[m - i] * tempRK[lagSearchRange[1] - corrLagStats[0]];
                }
                else if ( j < lagSearchRange[0] - corrLagStats[0] )
                {
                    rInterp[k] += winInterp[m - i] * tempRK[lagSearchRange[0] - corrLagStats[0]];
                }
                else
                {
                    rInterp[k] += winInterp[m - i] * tempRK[j];
                }
            }
        }
    }
    corrLagStats[1] += ( maximum( rInterp, interpLen, &tempF ) + interpMin );

    /* save corr lag stats for the current frame */
    mvs2s( corrLagStats, hStereoTCA->corrLagStats, 3 );

    return;
}
#endif

/*---------------------------------------------------------------
 *  Function estDownmixGain()
+17 −0

File changed.

Preview size limit exceeded, changes collapsed.

+6 −0
Original line number Diff line number Diff line
@@ -137,6 +137,12 @@ extern const Word32 invV_speech_fx[];
extern const float lvm_speech[];
extern const Word32 lvm_speech_fx[];

#ifdef IVAS_FLOAT_FIXED
extern const Word32 prec_chol_speech_fx[];
extern const Word32 prec_chol_music_fx[];
extern const Word32 prec_chol_noise_fx[];
#endif

extern const float m_music[];
extern const Word16 m_music_fx[];
extern const float invV_music[];
Loading