Beispiel #1
0
/* Convert LSF parameters to AR prediction filter coefficients */
void silk_NLSF2A_FLP(
    silk_float                      *pAR,                               /* O    LPC coefficients [ LPC_order ]              */
    const opus_int16                *NLSF_Q15,                          /* I    NLSF vector      [ LPC_order ]              */
    const opus_int                  LPC_order                           /* I    LPC order                                   */
)
{
    opus_int   i;
    opus_int16 a_fix_Q12[ MAX_LPC_ORDER ];

    silk_NLSF2A( a_fix_Q12, NLSF_Q15, LPC_order );

    for( i = 0; i < LPC_order; i++ ) {
        pAR[ i ] = ( silk_float )a_fix_Q12[ i ] * ( 1.0f / 4096.0f );
    }
}
Beispiel #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));
    }
}
Beispiel #3
0
/* 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;
}
Beispiel #4
0
/* Decode parameters from payload */
void silk_decode_parameters(silk_decoder_state * psDec,	/* I/O  State                                       */
			    silk_decoder_control * psDecCtrl,	/* I/O  Decoder control                             */
			    int condCoding	/* I    The type of conditional coding to use       */
    )
{
	int i, k, Ix;
	int16_t pNLSF_Q15[MAX_LPC_ORDER], pNLSF0_Q15[MAX_LPC_ORDER];
	const int8_t *cbk_ptr_Q7;

	/* Dequant Gains */
	silk_gains_dequant(psDecCtrl->Gains_Q16, psDec->indices.GainsIndices,
			   &psDec->LastGainIndex,
			   condCoding == CODE_CONDITIONALLY, psDec->nb_subfr);

    /****************/
	/* Decode NLSFs */
    /****************/
	silk_NLSF_decode(pNLSF_Q15, psDec->indices.NLSFIndices,
			 psDec->psNLSF_CB);

	/* Convert NLSF parameters to AR prediction filter coefficients */
	silk_NLSF2A(psDecCtrl->PredCoef_Q12[1], pNLSF_Q15, psDec->LPC_order);

	/* If just reset, e.g., because internal Fs changed, do not allow interpolation */
	/* improves the case of packet loss in the first frame after a switch           */
	if (psDec->first_frame_after_reset == 1) {
		psDec->indices.NLSFInterpCoef_Q2 = 4;
	}

	if (psDec->indices.NLSFInterpCoef_Q2 < 4) {
		/* Calculation of the interpolated NLSF0 vector from the interpolation factor, */
		/* the previous NLSF1, and the current NLSF1                                   */
		for (i = 0; i < psDec->LPC_order; i++) {
			pNLSF0_Q15[i] =
			    psDec->prevNLSF_Q15[i] +
			    silk_RSHIFT(silk_MUL
					(psDec->indices.NLSFInterpCoef_Q2,
					 pNLSF_Q15[i] - psDec->prevNLSF_Q15[i]),
					2);
		}

		/* Convert NLSF parameters to AR prediction filter coefficients */
		silk_NLSF2A(psDecCtrl->PredCoef_Q12[0], pNLSF0_Q15,
			    psDec->LPC_order);
	} else {
		/* Copy LPC coefficients for first half from second half */
		memcpy(psDecCtrl->PredCoef_Q12[0],
			    psDecCtrl->PredCoef_Q12[1],
			    psDec->LPC_order * sizeof(int16_t));
	}

	memcpy(psDec->prevNLSF_Q15, pNLSF_Q15,
		    psDec->LPC_order * sizeof(int16_t));

	/* After a packet loss do BWE of LPC coefs */
	if (psDec->lossCnt) {
		silk_bwexpander(psDecCtrl->PredCoef_Q12[0], psDec->LPC_order,
				BWE_AFTER_LOSS_Q16);
		silk_bwexpander(psDecCtrl->PredCoef_Q12[1], psDec->LPC_order,
				BWE_AFTER_LOSS_Q16);
	}

	if (psDec->indices.signalType == TYPE_VOICED) {
	/*********************/
		/* Decode pitch lags */
	/*********************/

		/* Decode pitch values */
		silk_decode_pitch(psDec->indices.lagIndex,
				  psDec->indices.contourIndex,
				  psDecCtrl->pitchL, psDec->fs_kHz,
				  psDec->nb_subfr);

		/* Decode Codebook Index */
		cbk_ptr_Q7 = silk_LTP_vq_ptrs_Q7[psDec->indices.PERIndex];	/* set pointer to start of codebook */

		for (k = 0; k < psDec->nb_subfr; k++) {
			Ix = psDec->indices.LTPIndex[k];
			for (i = 0; i < LTP_ORDER; i++) {
				psDecCtrl->LTPCoef_Q14[k * LTP_ORDER + i] =
				    silk_LSHIFT(cbk_ptr_Q7[Ix * LTP_ORDER + i],
						7);
			}
		}

	/**********************/
		/* Decode LTP scaling */
	/**********************/
		Ix = psDec->indices.LTP_scaleIndex;
		psDecCtrl->LTP_scale_Q14 = silk_LTPScales_table_Q14[Ix];
	} else {
		memzero(psDecCtrl->pitchL, psDec->nb_subfr * sizeof(int));
		memzero(psDecCtrl->LTPCoef_Q14,
			LTP_ORDER * psDec->nb_subfr * sizeof(int16_t));
		psDec->indices.PERIndex = 0;
		psDecCtrl->LTP_scale_Q14 = 0;
	}
}