void SKP_Silk_LTP_analysis_filter_FIX( SKP_int16 *LTP_res, /* O: LTP residual signal of length NB_SUBFR * ( pre_length + subfr_length ) */ const SKP_int16 *x, /* I: Pointer to input signal with at least max( pitchL ) preceeding samples */ const SKP_int16 LTPCoef_Q14[ LTP_ORDER * NB_SUBFR ],/* I: LTP_ORDER LTP coefficients for each NB_SUBFR subframe */ const SKP_int pitchL[ NB_SUBFR ], /* I: Pitch lag, one for each subframe */ const SKP_int32 invGains_Qxx[ NB_SUBFR ], /* I: Inverse quantization gains, one for each subframe */ const SKP_int Qxx, /* I: Inverse quantization gains Q domain */ const SKP_int subfr_length, /* I: Length of each subframe */ const SKP_int pre_length /* I: Length of the preceeding samples starting at &x[0] for each subframe */ ) { const SKP_int16 *x_ptr, *x_lag_ptr; SKP_int16 Btmp_Q14[ LTP_ORDER ]; SKP_int16 *LTP_res_ptr; SKP_int k, i, j; SKP_int32 LTP_est; x_ptr = x; LTP_res_ptr = LTP_res; for( k = 0; k < NB_SUBFR; k++ ) { x_lag_ptr = x_ptr - pitchL[ k ]; for( i = 0; i < LTP_ORDER; i++ ) { Btmp_Q14[ i ] = LTPCoef_Q14[ k * LTP_ORDER + i ]; } /* LTP analysis FIR filter */ for( i = 0; i < subfr_length + pre_length; i++ ) { LTP_res_ptr[ i ] = x_ptr[ i ]; /* Long-term prediction */ LTP_est = SKP_SMULBB( x_lag_ptr[ LTP_ORDER / 2 ], Btmp_Q14[ 0 ] ); for( j = 1; j < LTP_ORDER; j++ ) { LTP_est = SKP_SMLABB_ovflw( LTP_est, x_lag_ptr[ LTP_ORDER / 2 - j ], Btmp_Q14[ j ] ); } LTP_est = SKP_RSHIFT_ROUND( LTP_est, 14 ); // round and -> Q0 /* Subtract long-term prediction */ LTP_res_ptr[ i ] = ( SKP_int16 )SKP_SAT16( ( SKP_int32 )x_ptr[ i ] - LTP_est ); /* Scale residual */ if( Qxx == 16 ) { LTP_res_ptr[ i ] = SKP_SMULWB( invGains_Qxx[ k ], LTP_res_ptr[ i ] ); } else { LTP_res_ptr[ i ] = ( SKP_int16 )SKP_CHECK_FIT16( SKP_RSHIFT64( SKP_SMULL( invGains_Qxx[ k ], LTP_res_ptr[ i ] ), Qxx ) ); } x_lag_ptr++; } /* Update pointers */ LTP_res_ptr += subfr_length + pre_length; x_ptr += subfr_length; } }
/* Copy and multiply a vector by a constant */ void silk_scale_copy_vector16( SKP_int16 *data_out, const SKP_int16 *data_in, SKP_int32 gain_Q16, /* (I): gain in Q16 */ const SKP_int dataSize /* (I): length */ ) { SKP_int i; SKP_int32 tmp32; for( i = 0; i < dataSize; i++ ) { tmp32 = SKP_SMULWB( gain_Q16, data_in[ i ] ); data_out[ i ] = (SKP_int16)SKP_CHECK_FIT16( tmp32 ); } }
/* Convert LSF parameters to AR prediction filter coefficients */ void SKP_Silk_NLSF2A_stable_FLP( SKP_float *pAR, /* O LPC coefficients [ LPC_order ] */ const SKP_float *pNLSF, /* I NLSF vector [ LPC_order ] */ const SKP_int LPC_order /* I LPC order */ ) { SKP_int i; SKP_int NLSF_fix[ MAX_LPC_ORDER ]; SKP_int16 a_fix_Q12[ MAX_LPC_ORDER ]; for( i = 0; i < LPC_order; i++ ) { NLSF_fix[ i ] = ( SKP_int )SKP_CHECK_FIT16( SKP_float2int( pNLSF[ i ] * 32768.0f ) ); } SKP_Silk_NLSF2A_stable( a_fix_Q12, NLSF_fix, LPC_order ); for( i = 0; i < LPC_order; i++ ) { pAR[ i ] = ( SKP_float )a_fix_Q12[ i ] / 4096.0f; } }