/* Laroia low complexity NLSF weights */
void SKP_Silk_NLSF_VQ_weights_laroia_FLP( 
          SKP_float     *pXW,           /* 0: Pointer to input vector weights           [D x 1] */
    const SKP_float     *pX,            /* I: Pointer to input vector                   [D x 1] */ 
    const SKP_int        D              /* I: Input vector dimension                            */
)
{
    SKP_int   k;
    SKP_float tmp1, tmp2;
    
    /* Safety checks */
    SKP_assert( D > 0 );
    SKP_assert( ( D & 1 ) == 0 );
    
    /* First value */
    tmp1 = 1.0f / SKP_max_float( pX[ 0 ],           MIN_NDELTA );
    tmp2 = 1.0f / SKP_max_float( pX[ 1 ] - pX[ 0 ], MIN_NDELTA );
    pXW[ 0 ] = tmp1 + tmp2;
    
    /* Main loop */
    for( k = 1; k < D - 1; k += 2 ) {
        tmp1 = 1.0f / SKP_max_float( pX[ k + 1 ] - pX[ k ], MIN_NDELTA );
        pXW[ k ] = tmp1 + tmp2;

        tmp2 = 1.0f / SKP_max_float( pX[ k + 2 ] - pX[ k + 1 ], MIN_NDELTA );
        pXW[ k + 1 ] = tmp1 + tmp2;
    }
    
    /* Last value */
    tmp1 = 1.0f / SKP_max_float( 1.0f - pX[ D - 1 ], MIN_NDELTA );
    pXW[ D - 1 ] = tmp1 + tmp2;
}
Example #2
0
SKP_float SKP_Silk_schur_FLP(             /* O    returns residual energy                     */
    SKP_float       refl_coef[],        /* O    reflection coefficients (length order)      */
    const SKP_float auto_corr[],        /* I    autotcorrelation sequence (length order+1)  */
    SKP_int         order               /* I    order                                       */
)
{
    SKP_int   k, n;
    SKP_float C[SKP_Silk_MAX_ORDER_LPC + 1][2];
    SKP_float Ctmp1, Ctmp2, rc_tmp;
    
    /* copy correlations */
    for( k = 0; k < order+1; k++ ){
        C[k][0] = C[k][1] = auto_corr[k];
    }

    for( k = 0; k < order; k++ ) {
        /* get reflection coefficient */
        rc_tmp = -C[k + 1][0] / SKP_max_float( C[0][1], 1e-9f );

        /* save the output */
        refl_coef[k] = rc_tmp;

        /* update correlations */
        for( n = 0; n < order - k; n++ ){
            Ctmp1 = C[n + k + 1][0];
            Ctmp2 = C[n][1];
            C[n + k + 1][0] = Ctmp1 + Ctmp2 * rc_tmp;
            C[n][1]         = Ctmp2 + Ctmp1 * rc_tmp;
        }
    }

    /* return residual energy */
    return C[0][1];
}
Example #3
0
/* Solve the normal equations using the Levinson-Durbin recursion */
SKP_float silk_levinsondurbin_FLP(    /* O    prediction error energy                     */
    SKP_float       A[],                /* O    prediction coefficients [order]             */
    const SKP_float corr[],             /* I    input auto-correlations [order + 1]         */
    const SKP_int   order               /* I    prediction order                            */
)
{
    SKP_int   i, mHalf, m;
    SKP_float min_nrg, nrg, t, km, Atmp1, Atmp2;
    
    min_nrg = 1e-12f * corr[ 0 ] + 1e-9f;
    nrg = corr[ 0 ];
    nrg = SKP_max_float(min_nrg, nrg);
    A[ 0 ] = corr[ 1 ] / nrg;
    nrg -= A[ 0 ] * corr[ 1 ];
    nrg = SKP_max_float(min_nrg, nrg);

    for( m = 1; m < order; m++ )
    {
        t = corr[ m + 1 ];
        for( i = 0; i < m; i++ ) {
            t -= A[ i ] * corr[ m - i ];
        }

        /* reflection coefficient */
        km = t / nrg;

        /* residual energy */
        nrg -= km * t;
        nrg = SKP_max_float(min_nrg, nrg);

        mHalf = m >> 1;
        for( i = 0; i < mHalf; i++ ) {
            Atmp1 = A[ i ];
            Atmp2 = A[ m - i - 1 ];
            A[ m - i - 1 ] -= km * Atmp1;
            A[ i ]         -= km * Atmp2;
        }
        if( m & 1 ) {
            A[ mHalf ]     -= km * A[ mHalf ];
        }
        A[ m ] = km;
    }

    /* return the residual energy */
    return nrg;
}
void silk_LTP_scale_ctrl_FLP(
    silk_encoder_state_FLP      *psEnc,             /* I/O  Encoder state FLP                       */
    silk_encoder_control_FLP    *psEncCtrl          /* I/O  Encoder control FLP                     */
)
{
    opus_int   round_loss;

    /* 1st order high-pass filter */
    //g_HP(n) = g(n) - 0.5 * g(n-1) + 0.5 * g_HP(n-1);
    psEnc->HPLTPredCodGain = SKP_max_float( psEncCtrl->LTPredCodGain - 0.5 * psEnc->prevLTPredCodGain, 0.0f ) 
                            + 0.5f * psEnc->HPLTPredCodGain;
    psEnc->prevLTPredCodGain = psEncCtrl->LTPredCodGain;

    /* Only scale if first frame in packet */
    if( psEnc->sCmn.nFramesEncoded == 0 ) {
        round_loss = psEnc->sCmn.PacketLoss_perc + psEnc->sCmn.nFramesPerPacket;
        psEnc->sCmn.indices.LTP_scaleIndex = (opus_int8)SKP_LIMIT( round_loss * psEnc->HPLTPredCodGain * 0.1f, 0.0f, 2.0f );
    } else {
        /* Default is minimum scaling */
        psEnc->sCmn.indices.LTP_scaleIndex = 0;
    }
    psEncCtrl->LTP_scale = (SKP_float)silk_LTPScales_table_Q14[ psEnc->sCmn.indices.LTP_scaleIndex ] / 16384.0f;
}
void silk_find_pitch_lags_FLP(
    silk_encoder_state_FLP          *psEnc,             /* I/O  Encoder state FLP                       */
    silk_encoder_control_FLP        *psEncCtrl,         /* I/O  Encoder control FLP                     */
          SKP_float                 res[],              /* O    Residual                                */
    const SKP_float                 x[]                 /* I    Speech signal                           */
)
{
    opus_int   buf_len;
    SKP_float thrhld, res_nrg;
    const SKP_float *x_buf_ptr, *x_buf;
    SKP_float auto_corr[ MAX_FIND_PITCH_LPC_ORDER + 1 ];
    SKP_float A[         MAX_FIND_PITCH_LPC_ORDER ];
    SKP_float refl_coef[ MAX_FIND_PITCH_LPC_ORDER ];
    SKP_float Wsig[      FIND_PITCH_LPC_WIN_MAX ];
    SKP_float *Wsig_ptr;

    /******************************************/
    /* Setup buffer lengths etc based on Fs   */
    /******************************************/
    buf_len = psEnc->sCmn.la_pitch + psEnc->sCmn.frame_length + psEnc->sCmn.ltp_mem_length;

    /* Safty check */
    SKP_assert( buf_len >= psEnc->sCmn.pitch_LPC_win_length );

    x_buf = x - psEnc->sCmn.ltp_mem_length;

    /******************************************/
    /* Estimate LPC AR coeficients            */
    /******************************************/
    
    /* Calculate windowed signal */
    
    /* First LA_LTP samples */
    x_buf_ptr = x_buf + buf_len - psEnc->sCmn.pitch_LPC_win_length;
    Wsig_ptr  = Wsig;
    silk_apply_sine_window_FLP( Wsig_ptr, x_buf_ptr, 1, psEnc->sCmn.la_pitch );

    /* Middle non-windowed samples */
    Wsig_ptr  += psEnc->sCmn.la_pitch;
    x_buf_ptr += psEnc->sCmn.la_pitch;
    SKP_memcpy( Wsig_ptr, x_buf_ptr, ( psEnc->sCmn.pitch_LPC_win_length - ( psEnc->sCmn.la_pitch << 1 ) ) * sizeof( SKP_float ) );

    /* Last LA_LTP samples */
    Wsig_ptr  += psEnc->sCmn.pitch_LPC_win_length - ( psEnc->sCmn.la_pitch << 1 );
    x_buf_ptr += psEnc->sCmn.pitch_LPC_win_length - ( psEnc->sCmn.la_pitch << 1 );
    silk_apply_sine_window_FLP( Wsig_ptr, x_buf_ptr, 2, psEnc->sCmn.la_pitch );

    /* Calculate autocorrelation sequence */
    silk_autocorrelation_FLP( auto_corr, Wsig, psEnc->sCmn.pitch_LPC_win_length, psEnc->sCmn.pitchEstimationLPCOrder + 1 );

    /* Add white noise, as a fraction of the energy */
    auto_corr[ 0 ] += auto_corr[ 0 ] * FIND_PITCH_WHITE_NOISE_FRACTION + 1;

    /* Calculate the reflection coefficients using Schur */
    res_nrg = silk_schur_FLP( refl_coef, auto_corr, psEnc->sCmn.pitchEstimationLPCOrder );

    /* Prediction gain */
    psEncCtrl->predGain = auto_corr[ 0 ] / SKP_max_float( res_nrg, 1.0f );

    /* Convert reflection coefficients to prediction coefficients */
    silk_k2a_FLP( A, refl_coef, psEnc->sCmn.pitchEstimationLPCOrder );

    /* Bandwidth expansion */
    silk_bwexpander_FLP( A, psEnc->sCmn.pitchEstimationLPCOrder, FIND_PITCH_BANDWITH_EXPANSION );
    
    /*****************************************/
    /* LPC analysis filtering                */
    /*****************************************/
    silk_LPC_analysis_filter_FLP( res, A, x_buf, buf_len, psEnc->sCmn.pitchEstimationLPCOrder );

    if( psEnc->sCmn.indices.signalType != TYPE_NO_VOICE_ACTIVITY && psEnc->sCmn.first_frame_after_reset == 0 ) {
        /* Threshold for pitch estimator */
        thrhld  = 0.6f;
        thrhld -= 0.004f * psEnc->sCmn.pitchEstimationLPCOrder;
        thrhld -= 0.1f   * psEnc->sCmn.speech_activity_Q8 * ( 1.0f /  256.0f );
        thrhld -= 0.15f  * (psEnc->sCmn.prevSignalType >> 1);
        thrhld -= 0.1f   * psEnc->sCmn.input_tilt_Q15 * ( 1.0f / 32768.0f );

        /*****************************************/
        /* Call Pitch estimator                  */
        /*****************************************/
        if( silk_pitch_analysis_core_FLP( res, psEncCtrl->pitchL, &psEnc->sCmn.indices.lagIndex, 
            &psEnc->sCmn.indices.contourIndex, &psEnc->LTPCorr, psEnc->sCmn.prevLag, psEnc->sCmn.pitchEstimationThreshold_Q16 / 65536.0f,
            thrhld, psEnc->sCmn.fs_kHz, psEnc->sCmn.pitchEstimationComplexity, psEnc->sCmn.nb_subfr ) == 0 ) 
        {
            psEnc->sCmn.indices.signalType = TYPE_VOICED;
        } else {
            psEnc->sCmn.indices.signalType = TYPE_UNVOICED;
        }
    } else {