Exemplo n.º 1
0
/* Compute quantization errors for an LPC_order element input vector for a VQ codebook */
void silk_NLSF_VQ(
    opus_int32                  err_Q26[],                      /* O    Quantization errors [K]                     */
    const opus_int16            in_Q15[],                       /* I    Input vectors to be quantized [LPC_order]   */
    const opus_uint8            pCB_Q8[],                       /* I    Codebook vectors [K*LPC_order]              */
    const opus_int              K,                              /* I    Number of codebook vectors                  */
    const opus_int              LPC_order                       /* I    Number of LPCs                              */
)
{
    opus_int        i, m;
    opus_int32      diff_Q15, sum_error_Q30, sum_error_Q26;

    silk_assert( LPC_order <= 16 );
    silk_assert( ( LPC_order & 1 ) == 0 );

    /* Loop over codebook */
    for( i = 0; i < K; i++ ) {
        sum_error_Q26 = 0;
        for( m = 0; m < LPC_order; m += 2 ) {
            /* Compute weighted squared quantization error for index m */
            diff_Q15 = silk_SUB_LSHIFT32( in_Q15[ m ], (opus_int32)*pCB_Q8++, 7 ); /* range: [ -32767 : 32767 ]*/
            sum_error_Q30 = silk_SMULBB( diff_Q15, diff_Q15 );

            /* Compute weighted squared quantization error for index m + 1 */
            diff_Q15 = silk_SUB_LSHIFT32( in_Q15[m + 1], (opus_int32)*pCB_Q8++, 7 ); /* range: [ -32767 : 32767 ]*/
            sum_error_Q30 = silk_SMLABB( sum_error_Q30, diff_Q15, diff_Q15 );

            sum_error_Q26 = silk_ADD_RSHIFT32( sum_error_Q26, sum_error_Q30, 4 );

            silk_assert( sum_error_Q26 >= 0 );
            silk_assert( sum_error_Q30 >= 0 );
        }
        err_Q26[ i ] = sum_error_Q26;
    }
}
Exemplo n.º 2
0
/* Find least-squares prediction gain for one signal based on another and quantize it */
int32_t silk_stereo_find_predictor(	/* O    Returns predictor in Q13                    */
					     int32_t * ratio_Q14,	/* O    Ratio of residual and mid energies          */
					     const int16_t x[],	/* I    Basis signal                                */
					     const int16_t y[],	/* I    Target signal                               */
					     int32_t mid_res_amp_Q0[],	/* I/O  Smoothed mid, residual norms                */
					     int length,	/* I    Number of samples                           */
					     int smooth_coef_Q16	/* I    Smoothing coefficient                       */
    )
{
	int scale, scale1, scale2;
	int32_t nrgx, nrgy, corr, pred_Q13, pred2_Q10;

	/* Find  predictor */
	silk_sum_sqr_shift(&nrgx, &scale1, x, length);
	silk_sum_sqr_shift(&nrgy, &scale2, y, length);
	scale = silk_max_int(scale1, scale2);
	scale = scale + (scale & 1);	/* make even */
	nrgy = silk_RSHIFT32(nrgy, scale - scale2);
	nrgx = silk_RSHIFT32(nrgx, scale - scale1);
	nrgx = silk_max_int(nrgx, 1);
	corr = silk_inner_prod_aligned_scale(x, y, scale, length);
	pred_Q13 = silk_DIV32_varQ(corr, nrgx, 13);
	pred_Q13 = silk_LIMIT(pred_Q13, -(1 << 14), 1 << 14);
	pred2_Q10 = silk_SMULWB(pred_Q13, pred_Q13);

	/* Faster update for signals with large prediction parameters */
	smooth_coef_Q16 =
	    (int) silk_max_int(smooth_coef_Q16, silk_abs(pred2_Q10));

	/* Smoothed mid and residual norms */
	assert(smooth_coef_Q16 < 32768);
	scale = silk_RSHIFT(scale, 1);
	mid_res_amp_Q0[0] =
	    silk_SMLAWB(mid_res_amp_Q0[0],
			silk_LSHIFT(silk_SQRT_APPROX(nrgx),
				    scale) - mid_res_amp_Q0[0],
			smooth_coef_Q16);
	/* Residual energy = nrgy - 2 * pred * corr + pred^2 * nrgx */
	nrgy = silk_SUB_LSHIFT32(nrgy, silk_SMULWB(corr, pred_Q13), 3 + 1);
	nrgy = silk_ADD_LSHIFT32(nrgy, silk_SMULWB(nrgx, pred2_Q10), 6);
	mid_res_amp_Q0[1] =
	    silk_SMLAWB(mid_res_amp_Q0[1],
			silk_LSHIFT(silk_SQRT_APPROX(nrgy),
				    scale) - mid_res_amp_Q0[1],
			smooth_coef_Q16);

	/* Ratio of smoothed residual and mid norms */
	*ratio_Q14 =
	    silk_DIV32_varQ(mid_res_amp_Q0[1], silk_max(mid_res_amp_Q0[0], 1),
			    14);
	*ratio_Q14 = silk_LIMIT(*ratio_Q14, 0, 32767);

	return pred_Q13;
}