/* LPC analysis */
void silk_find_LPC_FLP(
    silk_encoder_state              *psEncC,                            /* I/O  Encoder state                               */
    opus_int16                      NLSF_Q15[],                         /* O    NLSFs                                       */
    const silk_float                x[],                                /* I    Input signal                                */
    const silk_float                minInvGain                          /* I    Inverse of max prediction gain              */
)
{
    opus_int    k, subfr_length;
    silk_float  a[ MAX_LPC_ORDER ];

    /* Used only for NLSF interpolation */
    silk_float  res_nrg, res_nrg_2nd, res_nrg_interp;
    opus_int16  NLSF0_Q15[ MAX_LPC_ORDER ];
    silk_float  a_tmp[ MAX_LPC_ORDER ];
    silk_float  LPC_res[ MAX_FRAME_LENGTH + MAX_NB_SUBFR * MAX_LPC_ORDER ];

    subfr_length = psEncC->subfr_length + psEncC->predictLPCOrder;

    /* Default: No interpolation */
    psEncC->indices.NLSFInterpCoef_Q2 = 4;

    /* Burg AR analysis for the full frame */
    res_nrg = silk_burg_modified_FLP( a, x, minInvGain, subfr_length, psEncC->nb_subfr, psEncC->predictLPCOrder );

    if( psEncC->useInterpolatedNLSFs && !psEncC->first_frame_after_reset && psEncC->nb_subfr == MAX_NB_SUBFR ) {
        /* Optimal solution for last 10 ms; subtract residual energy here, as that's easier than        */
        /* adding it to the residual energy of the first 10 ms in each iteration of the search below    */
        res_nrg -= silk_burg_modified_FLP( a_tmp, x + ( MAX_NB_SUBFR / 2 ) * subfr_length, minInvGain, subfr_length, MAX_NB_SUBFR / 2, psEncC->predictLPCOrder );

        /* Convert to NLSFs */
        silk_A2NLSF_FLP( NLSF_Q15, a_tmp, psEncC->predictLPCOrder );

        /* Search over interpolation indices to find the one with lowest residual energy */
        res_nrg_2nd = silk_float_MAX;
        for( k = 3; k >= 0; k-- ) {
            /* Interpolate NLSFs for first half */
            silk_interpolate( NLSF0_Q15, psEncC->prev_NLSFq_Q15, NLSF_Q15, k, psEncC->predictLPCOrder );

            /* Convert to LPC for residual energy evaluation */
            silk_NLSF2A_FLP( a_tmp, NLSF0_Q15, psEncC->predictLPCOrder );

            /* Calculate residual energy with LSF interpolation */
            silk_LPC_analysis_filter_FLP( LPC_res, a_tmp, x, 2 * subfr_length, psEncC->predictLPCOrder );
            res_nrg_interp = (silk_float)(
                silk_energy_FLP( LPC_res + psEncC->predictLPCOrder,                subfr_length - psEncC->predictLPCOrder ) +
                silk_energy_FLP( LPC_res + psEncC->predictLPCOrder + subfr_length, subfr_length - psEncC->predictLPCOrder ) );

            /* Determine whether current interpolated NLSFs are best so far */
            if( res_nrg_interp < res_nrg ) {
                /* Interpolation has lower residual energy */
                res_nrg = res_nrg_interp;
                psEncC->indices.NLSFInterpCoef_Q2 = (opus_int8)k;
            } else if( res_nrg_interp > res_nrg_2nd ) {
                /* No reason to continue iterating - residual energies will continue to climb */
                break;
            }
            res_nrg_2nd = res_nrg_interp;
        }
    }

    if( psEncC->indices.NLSFInterpCoef_Q2 == 4 ) {
        /* NLSF interpolation is currently inactive, calculate NLSFs from full frame AR coefficients */
        silk_A2NLSF_FLP( NLSF_Q15, a, psEncC->predictLPCOrder );
    }

    silk_assert( psEncC->indices.NLSFInterpCoef_Q2 == 4 ||
        ( psEncC->useInterpolatedNLSFs && !psEncC->first_frame_after_reset && psEncC->nb_subfr == MAX_NB_SUBFR ) );
}
示例#2
0
/* Limit, stabilize, convert and quantize NLSFs */
void silk_process_NLSFs(
    silk_encoder_state          *psEncC,                            /* I/O  Encoder state                               */
    opus_int16                  PredCoef_Q12[ 2 ][ MAX_LPC_ORDER ], /* O    Prediction coefficients                     */
    opus_int16                  pNLSF_Q15[         MAX_LPC_ORDER ], /* I/O  Normalized LSFs (quant out) (0 - (2^15-1))  */
    const opus_int16            prev_NLSFq_Q15[    MAX_LPC_ORDER ]  /* I    Previous Normalized LSFs (0 - (2^15-1))     */
)
{
    opus_int     i, doInterpolate;
    opus_int     NLSF_mu_Q20;
    opus_int32   i_sqr_Q15;
    opus_int16   pNLSF0_temp_Q15[ MAX_LPC_ORDER ];
    opus_int16   pNLSFW_QW[ MAX_LPC_ORDER ];
    opus_int16   pNLSFW0_temp_QW[ MAX_LPC_ORDER ];

    silk_assert(psEncC->speech_activity_Q8 >=   0);
    silk_assert(psEncC->speech_activity_Q8 <= SILK_FIX_CONST(1.0, 8));
    silk_assert(psEncC->useInterpolatedNLSFs == 1 || psEncC->indices.NLSFInterpCoef_Q2 == (1 << 2));

    /***********************/
    /* Calculate mu values */
    /***********************/
    /* NLSF_mu  = 0.003 - 0.0015 * psEnc->speech_activity; */
    NLSF_mu_Q20 = silk_SMLAWB(SILK_FIX_CONST(0.003, 20), SILK_FIX_CONST(-0.001, 28), psEncC->speech_activity_Q8);
    if(psEncC->nb_subfr == 2) {
        /* Multiply by 1.5 for 10 ms packets */
        NLSF_mu_Q20 = silk_ADD_RSHIFT(NLSF_mu_Q20, NLSF_mu_Q20, 1);
    }

    silk_assert(NLSF_mu_Q20 >  0);
    silk_assert(NLSF_mu_Q20 <= SILK_FIX_CONST(0.005, 20));

    /* Calculate NLSF weights */
    silk_NLSF_VQ_weights_laroia(pNLSFW_QW, pNLSF_Q15, psEncC->predictLPCOrder);

    /* Update NLSF weights for interpolated NLSFs */
    doInterpolate = (psEncC->useInterpolatedNLSFs == 1) && (psEncC->indices.NLSFInterpCoef_Q2 < 4);
    if(doInterpolate) {
        /* Calculate the interpolated NLSF vector for the first half */
        silk_interpolate(pNLSF0_temp_Q15, prev_NLSFq_Q15, pNLSF_Q15,
            psEncC->indices.NLSFInterpCoef_Q2, psEncC->predictLPCOrder);

        /* Calculate first half NLSF weights for the interpolated NLSFs */
        silk_NLSF_VQ_weights_laroia(pNLSFW0_temp_QW, pNLSF0_temp_Q15, psEncC->predictLPCOrder);

        /* Update NLSF weights with contribution from first half */
        i_sqr_Q15 = silk_LSHIFT(silk_SMULBB(psEncC->indices.NLSFInterpCoef_Q2, psEncC->indices.NLSFInterpCoef_Q2), 11);
        for(i = 0; i < psEncC->predictLPCOrder; i++) {
            pNLSFW_QW[ i ] = silk_SMLAWB(silk_RSHIFT(pNLSFW_QW[ i ], 1), (opus_int32)pNLSFW0_temp_QW[ i ], i_sqr_Q15);
            silk_assert(pNLSFW_QW[ i ] >= 1);
        }
    }

    silk_NLSF_encode(psEncC->indices.NLSFIndices, pNLSF_Q15, psEncC->psNLSF_CB, pNLSFW_QW,
        NLSF_mu_Q20, psEncC->NLSF_MSVQ_Survivors, psEncC->indices.signalType);

    /* Convert quantized NLSFs back to LPC coefficients */
    silk_NLSF2A(PredCoef_Q12[ 1 ], pNLSF_Q15, psEncC->predictLPCOrder);

    if(doInterpolate) {
        /* Calculate the interpolated, quantized LSF vector for the first half */
        silk_interpolate(pNLSF0_temp_Q15, prev_NLSFq_Q15, pNLSF_Q15,
            psEncC->indices.NLSFInterpCoef_Q2, psEncC->predictLPCOrder);

        /* Convert back to LPC coefficients */
        silk_NLSF2A(PredCoef_Q12[ 0 ], pNLSF0_temp_Q15, psEncC->predictLPCOrder);

    } else {
        /* Copy LPC coefficients for first half from second half */
        silk_memcpy(PredCoef_Q12[ 0 ], PredCoef_Q12[ 1 ], psEncC->predictLPCOrder * sizeof(opus_int16));
    }
}
示例#3
0
文件: find_LPC_FIX.c 项目: a12n/godot
/* Finds LPC vector from correlations, and converts to NLSF */
void silk_find_LPC_FIX(
    silk_encoder_state              *psEncC,                                /* I/O  Encoder state                                                               */
    opus_int16                      NLSF_Q15[],                             /* O    NLSFs                                                                       */
    const opus_int16                x[],                                    /* I    Input signal                                                                */
    const opus_int32                minInvGain_Q30                          /* I    Inverse of max prediction gain                                              */
)
{
    opus_int     k, subfr_length;
    opus_int32   a_Q16[ MAX_LPC_ORDER ];
    opus_int     isInterpLower, shift;
    opus_int32   res_nrg0, res_nrg1;
    opus_int     rshift0, rshift1;

    /* Used only for LSF interpolation */
    opus_int32   a_tmp_Q16[ MAX_LPC_ORDER ], res_nrg_interp, res_nrg, res_tmp_nrg;
    opus_int     res_nrg_interp_Q, res_nrg_Q, res_tmp_nrg_Q;
    opus_int16   a_tmp_Q12[ MAX_LPC_ORDER ];
    opus_int16   NLSF0_Q15[ MAX_LPC_ORDER ];
    SAVE_STACK;

    subfr_length = psEncC->subfr_length + psEncC->predictLPCOrder;

    /* Default: no interpolation */
    psEncC->indices.NLSFInterpCoef_Q2 = 4;

    /* Burg AR analysis for the full frame */
    silk_burg_modified( &res_nrg, &res_nrg_Q, a_Q16, x, minInvGain_Q30, subfr_length, psEncC->nb_subfr, psEncC->predictLPCOrder, psEncC->arch );

    if( psEncC->useInterpolatedNLSFs && !psEncC->first_frame_after_reset && psEncC->nb_subfr == MAX_NB_SUBFR ) {
        VARDECL( opus_int16, LPC_res );

        /* Optimal solution for last 10 ms */
        silk_burg_modified( &res_tmp_nrg, &res_tmp_nrg_Q, a_tmp_Q16, x + 2 * subfr_length, minInvGain_Q30, subfr_length, 2, psEncC->predictLPCOrder, psEncC->arch );

        /* subtract residual energy here, as that's easier than adding it to the    */
        /* residual energy of the first 10 ms in each iteration of the search below */
        shift = res_tmp_nrg_Q - res_nrg_Q;
        if( shift >= 0 ) {
            if( shift < 32 ) {
                res_nrg = res_nrg - silk_RSHIFT( res_tmp_nrg, shift );
            }
        } else {
            silk_assert( shift > -32 );
            res_nrg   = silk_RSHIFT( res_nrg, -shift ) - res_tmp_nrg;
            res_nrg_Q = res_tmp_nrg_Q;
        }

        /* Convert to NLSFs */
        silk_A2NLSF( NLSF_Q15, a_tmp_Q16, psEncC->predictLPCOrder );

        ALLOC( LPC_res, 2 * subfr_length, opus_int16 );

        /* Search over interpolation indices to find the one with lowest residual energy */
        for( k = 3; k >= 0; k-- ) {
            /* Interpolate NLSFs for first half */
            silk_interpolate( NLSF0_Q15, psEncC->prev_NLSFq_Q15, NLSF_Q15, k, psEncC->predictLPCOrder );

            /* Convert to LPC for residual energy evaluation */
            silk_NLSF2A( a_tmp_Q12, NLSF0_Q15, psEncC->predictLPCOrder );

            /* Calculate residual energy with NLSF interpolation */
            silk_LPC_analysis_filter( LPC_res, x, a_tmp_Q12, 2 * subfr_length, psEncC->predictLPCOrder );

            silk_sum_sqr_shift( &res_nrg0, &rshift0, LPC_res + psEncC->predictLPCOrder,                subfr_length - psEncC->predictLPCOrder );
            silk_sum_sqr_shift( &res_nrg1, &rshift1, LPC_res + psEncC->predictLPCOrder + subfr_length, subfr_length - psEncC->predictLPCOrder );

            /* Add subframe energies from first half frame */
            shift = rshift0 - rshift1;
            if( shift >= 0 ) {
                res_nrg1         = silk_RSHIFT( res_nrg1, shift );
                res_nrg_interp_Q = -rshift0;
            } else {
                res_nrg0         = silk_RSHIFT( res_nrg0, -shift );
                res_nrg_interp_Q = -rshift1;
            }
            res_nrg_interp = silk_ADD32( res_nrg0, res_nrg1 );

            /* Compare with first half energy without NLSF interpolation, or best interpolated value so far */
            shift = res_nrg_interp_Q - res_nrg_Q;
            if( shift >= 0 ) {
                if( silk_RSHIFT( res_nrg_interp, shift ) < res_nrg ) {
                    isInterpLower = silk_TRUE;
                } else {
                    isInterpLower = silk_FALSE;
                }
            } else {
                if( -shift < 32 ) {
                    if( res_nrg_interp < silk_RSHIFT( res_nrg, -shift ) ) {
                        isInterpLower = silk_TRUE;
                    } else {
                        isInterpLower = silk_FALSE;
                    }
                } else {
                    isInterpLower = silk_FALSE;
                }
            }

            /* Determine whether current interpolated NLSFs are best so far */
            if( isInterpLower == silk_TRUE ) {
                /* Interpolation has lower residual energy */
                res_nrg   = res_nrg_interp;
                res_nrg_Q = res_nrg_interp_Q;
                psEncC->indices.NLSFInterpCoef_Q2 = (opus_int8)k;
            }
        }
    }

    if( psEncC->indices.NLSFInterpCoef_Q2 == 4 ) {
        /* NLSF interpolation is currently inactive, calculate NLSFs from full frame AR coefficients */
        silk_A2NLSF( NLSF_Q15, a_Q16, psEncC->predictLPCOrder );
    }

    silk_assert( psEncC->indices.NLSFInterpCoef_Q2 == 4 || ( psEncC->useInterpolatedNLSFs && !psEncC->first_frame_after_reset && psEncC->nb_subfr == MAX_NB_SUBFR ) );
    RESTORE_STACK;
}