SKP_int16 SKP_Silk_int16_array_maxabs(    /* O    Maximum absolute value, max: 2^15-1   */
    const SKP_int16        *vec,            /* I    Input vector  [len]                   */
    const SKP_int32        len              /* I    Length of input vector                */
)                    
{
    SKP_int32 max = 0, i, lvl = 0, ind;
	if( len == 0 ) return 0;

    ind = len - 1;
    max = SKP_SMULBB( vec[ ind ], vec[ ind ] );
    for( i = len - 2; i >= 0; i-- ) {
        lvl = SKP_SMULBB( vec[ i ], vec[ i ] );
        if( lvl > max ) {
            max = lvl;
            ind = i;
        }
    }

    /* Do not return 32768, as it will not fit in an int16 so may lead to problems later on */
    if( max >= 1073676289 ) { // (2^15-1)^2 = 1073676289
        return( SKP_int16_MAX );
    } else {
        if( vec[ ind ] < 0 ) {
            return( -vec[ ind ] );
        } else {
            return(  vec[ ind ] );
        }
    }
}
Esempio n. 2
0
/* Function that returns the maximum absolut value of the input vector */
int16_t SKP_Silk_int16_array_maxabs(	/* O    Maximum absolute value, max: 2^15-1   */
					   const int16_t * vec,	/* I    Input vector  [len]                   */
					   const int32_t len	/* I    Length of input vector                */
    )
{
	int32_t max = 0, i, lvl = 0, ind;

	ind = len - 1;
	max = SKP_SMULBB(vec[ind], vec[ind]);
	for (i = len - 2; i >= 0; i--) {
		lvl = SKP_SMULBB(vec[i], vec[i]);
		if (lvl > max) {
			max = lvl;
			ind = i;
		}
	}

	/* Do not return 32768, as it will not fit in an int16 so may lead to problems later on */
	lvl = SKP_abs(vec[ind]);
	if (lvl > int16_t_MAX) {
		return (int16_t_MAX);
	} else {
		return ((int16_t) lvl);
	}
}
Esempio n. 3
0
SKP_int SKP_Silk_sigm_Q15( SKP_int in_Q5 )
{
    SKP_int ind;

    if( in_Q5 < 0 ) {
        /* Negative input */
        in_Q5 = -in_Q5;
        if( in_Q5 >= 6 * 32 ) {
            return 0;        /* Clip */
        } else {
            /* Linear interpolation of look up table */
            ind = SKP_RSHIFT( in_Q5, 5 );
            return( sigm_LUT_neg_Q15[ ind ] - SKP_SMULBB( sigm_LUT_slope_Q10[ ind ], in_Q5 & 0x1F ) );
        }
    } else {
        /* Positive input */
        if( in_Q5 >= 6 * 32 ) {
            return 32767;        /* clip */
        } else {
            /* Linear interpolation of look up table */
            ind = SKP_RSHIFT( in_Q5, 5 );
            return( sigm_LUT_pos_Q15[ ind ] + SKP_SMULBB( sigm_LUT_slope_Q10[ ind ], in_Q5 & 0x1F ) );
        }
    }
}
/* Resamples by a factor 3/1 */
void SKP_Silk_resample_3_1(
    SKP_int16           *out,       /* O:   Fs_high signal [inLen*3]        */
    SKP_int32           *S,         /* I/O: State vector   [7]              */
    const SKP_int16     *in,        /* I:   Fs_low signal  [inLen]          */
    const SKP_int32     inLen       /* I:   Input length                    */
)
{
    SKP_int     k, LSubFrameIn, LSubFrameOut;
    SKP_int32   out_tmp, idx, inLenTmp = inLen;
    SKP_int32   scratch00[    IN_SUBFR_LEN_RESAMPLE_3_1 ];
    SKP_int32   scratch0[ 3 * IN_SUBFR_LEN_RESAMPLE_3_1 ];
    SKP_int32   scratch1[ 3 * IN_SUBFR_LEN_RESAMPLE_3_1 ];
    
    /* Coefficients for 3-fold resampling */
    const SKP_int16 A30[ 2 ] = {  1773, 17818 };
    const SKP_int16 A31[ 2 ] = {  4942, 25677 };
    const SKP_int16 A32[ 2 ] = { 11786, 29304 };

    while( inLenTmp > 0 ) {
        LSubFrameIn  = SKP_min_int( IN_SUBFR_LEN_RESAMPLE_3_1, inLenTmp );
        LSubFrameOut = SKP_SMULBB( 3, LSubFrameIn );

        /* Convert Q15 -> Q25 */
        for( k = 0; k < LSubFrameIn; k++ ) {
            scratch00[k] = SKP_LSHIFT( (SKP_int32)in[ k ], 10 );
        }

        /* Allpass filtering */
        /* Scratch size: 2 * 3* LSubFrame * sizeof(SKP_int32) */
        SKP_Silk_allpass_int( scratch00, S + 1, A30[ 0 ], scratch1, LSubFrameIn );
        SKP_Silk_allpass_int( scratch1,  S + 2, A30[ 1 ], scratch0, LSubFrameIn );

        SKP_Silk_allpass_int( scratch00, S + 3, A31[ 0 ], scratch1, LSubFrameIn );
        SKP_Silk_allpass_int( scratch1,  S + 4, A31[ 1 ], scratch0 +     IN_SUBFR_LEN_RESAMPLE_3_1, LSubFrameIn );

        SKP_Silk_allpass_int( scratch00, S + 5, A32[ 0 ], scratch1, LSubFrameIn );
        SKP_Silk_allpass_int( scratch1,  S + 6, A32[ 1 ], scratch0 + 2 * IN_SUBFR_LEN_RESAMPLE_3_1, LSubFrameIn );

        /* Interleave three allpass outputs */
        for( k = 0; k < LSubFrameIn; k++ ) {
            idx = SKP_SMULBB( 3, k );
            scratch1[ idx     ] = scratch0[ k ];
            scratch1[ idx + 1 ] = scratch0[ k +     IN_SUBFR_LEN_RESAMPLE_3_1 ];
            scratch1[ idx + 2 ] = scratch0[ k + 2 * IN_SUBFR_LEN_RESAMPLE_3_1 ];
        }

        /* Low-pass filtering */
        SKP_Silk_lowpass_int( scratch1, S, scratch0, LSubFrameOut );

        /* Saturate and convert to SKP_int16 */
        for( k = 0; k < LSubFrameOut; k++ ) {
            out_tmp  = scratch0[ k ];
            out[ k ] = (SKP_int16) SKP_SAT16( SKP_RSHIFT_ROUND( out_tmp, 10 ) );
        }

        in       += LSubFrameIn;
        inLenTmp -= LSubFrameIn;
        out      += LSubFrameOut;
    }
}
Esempio n. 5
0
/* Inverse filter of SKP_Silk_LPC_synthesis_filter */
void SKP_Silk_LPC_analysis_filter(
    const SKP_int16      *in,            /* I:   Input signal                                */
    const SKP_int16      *B,             /* I:   MA prediction coefficients, Q12 [order]     */
    SKP_int16            *S,             /* I/O: State vector [order]                        */
    SKP_int16            *out,           /* O:   Output signal                               */
    const SKP_int32      len,            /* I:   Signal length                               */
    const SKP_int32      Order           /* I:   Filter order                                */
)
{
    SKP_int   k, j, idx, Order_half = SKP_RSHIFT( Order, 1 );
    SKP_int32 Btmp, B_align_Q12[ SigProc_MAX_ORDER_LPC >> 1 ], out32_Q12, out32;
    SKP_int16 SA, SB;
    /* Order must be even */
    SKP_assert( 2 * Order_half == Order );

    /* Combine two A_Q12 values and ensure 32-bit alignment */
    for( k = 0; k < Order_half; k++ ) {
        idx = SKP_SMULBB( 2, k );
        B_align_Q12[ k ] = ( ( (SKP_int32)B[ idx ] ) & 0x0000ffff ) | SKP_LSHIFT( (SKP_int32)B[ idx + 1 ], 16 );
    }

    /* S[] values are in Q0 */
    for( k = 0; k < len; k++ ) {
        SA = S[ 0 ];
        out32_Q12 = 0;
        for( j = 0; j < ( Order_half - 1 ); j++ ) {
            idx = SKP_SMULBB( 2, j ) + 1;
            /* Multiply-add two prediction coefficients for each loop */
            Btmp = B_align_Q12[ j ];
            SB = S[ idx ];
            S[ idx ] = SA;
            out32_Q12 = SKP_SMLABB( out32_Q12, SA, Btmp );
            out32_Q12 = SKP_SMLABT( out32_Q12, SB, Btmp );
            SA = S[ idx + 1 ];
            S[ idx + 1 ] = SB;
        }

        /* Unrolled loop: epilog */
        Btmp = B_align_Q12[ Order_half - 1 ];
        SB = S[ Order - 1 ];
        S[ Order - 1 ] = SA;
        out32_Q12 = SKP_SMLABB( out32_Q12, SA, Btmp );
        out32_Q12 = SKP_SMLABT( out32_Q12, SB, Btmp );

        /* Subtract prediction */
        out32_Q12 = SKP_SUB_SAT32( SKP_LSHIFT( (SKP_int32)in[ k ], 12 ), out32_Q12 );

        /* Scale to Q0 */
        out32 = SKP_RSHIFT_ROUND( out32_Q12, 12 );

        /* Saturate output */
        out[ k ] = (SKP_int16)SKP_SAT16( out32 );

        /* Move input line */
        S[ 0 ] = in[ k ];
    }
}
/* Compute weighted quantization errors for an LPC_order element input vector, over one codebook stage */
void SKP_Silk_NLSF_VQ_sum_error_FIX(int32_t * err_Q20,	/* O    Weighted quantization errors  [N*K]         */
				    const int *in_Q15,	/* I    Input vectors to be quantized [N*LPC_order] */
				    const int *w_Q6,	/* I    Weighting vectors             [N*LPC_order] */
				    const int16_t * pCB_Q15,	/* I    Codebook vectors              [K*LPC_order] */
				    const int N,	/* I    Number of input vectors                     */
				    const int K,	/* I    Number of codebook vectors                  */
				    const int LPC_order	/* I    Number of LPCs                              */
    )
{
	int i, n, m;
	int32_t diff_Q15, sum_error, Wtmp_Q6;
	int32_t Wcpy_Q6[MAX_LPC_ORDER / 2];
	const int16_t *cb_vec_Q15;

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

	memzero(Wcpy_Q6, (MAX_LPC_ORDER / 2) * sizeof(int32_t));

	/* Copy to local stack and pack two weights per int32 */
	for (m = 0; m < SKP_RSHIFT(LPC_order, 1); m++) {
		Wcpy_Q6[m] =
		    w_Q6[2 * m] | SKP_LSHIFT((int32_t) w_Q6[2 * m + 1], 16);
	}

	/* Loop over input vectors */
	for (n = 0; n < N; n++) {
		/* Loop over codebook */
		cb_vec_Q15 = pCB_Q15;
		for (i = 0; i < K; i++) {
			sum_error = 0;
			for (m = 0; m < LPC_order; m += 2) {
				/* Get two weights packed in an int32 */
				Wtmp_Q6 = Wcpy_Q6[SKP_RSHIFT(m, 1)];

				/* Compute weighted squared quantization error for index m */
				diff_Q15 = in_Q15[m] - *cb_vec_Q15++;	// range: [ -32767 : 32767 ]
				sum_error =
				    SKP_SMLAWB(sum_error,
					       SKP_SMULBB(diff_Q15, diff_Q15),
					       Wtmp_Q6);

				/* Compute weighted squared quantization error for index m + 1 */
				diff_Q15 = in_Q15[m + 1] - *cb_vec_Q15++;	// range: [ -32767 : 32767 ]
				sum_error =
				    SKP_SMLAWT(sum_error,
					       SKP_SMULBB(diff_Q15, diff_Q15),
					       Wtmp_Q6);
			}
			assert(sum_error >= 0);
			err_Q20[i] = sum_error;
		}
		err_Q20 += K;
		in_Q15 += LPC_order;
	}
}
/* Set decoder sampling rate */
void SKP_Silk_decoder_set_fs(SKP_Silk_decoder_state * psDec,	/* I/O  Decoder state pointer                       */
			     int fs_kHz	/* I    Sampling frequency (kHz)                    */
    )
{
	if (psDec->fs_kHz != fs_kHz) {
		psDec->fs_kHz = fs_kHz;
		psDec->frame_length = SKP_SMULBB(FRAME_LENGTH_MS, fs_kHz);
		psDec->subfr_length =
		    SKP_SMULBB(FRAME_LENGTH_MS / NB_SUBFR, fs_kHz);
		if (psDec->fs_kHz == 8) {
			psDec->LPC_order = MIN_LPC_ORDER;
			psDec->psNLSF_CB[0] = &SKP_Silk_NLSF_CB0_10;
			psDec->psNLSF_CB[1] = &SKP_Silk_NLSF_CB1_10;
		} else {
			psDec->LPC_order = MAX_LPC_ORDER;
			psDec->psNLSF_CB[0] = &SKP_Silk_NLSF_CB0_16;
			psDec->psNLSF_CB[1] = &SKP_Silk_NLSF_CB1_16;
		}
		/* Reset part of the decoder state */
		SKP_memset(psDec->sLPC_Q14, 0, MAX_LPC_ORDER * sizeof(int32_t));
		SKP_memset(psDec->outBuf, 0,
			   MAX_FRAME_LENGTH * sizeof(int16_t));
		SKP_memset(psDec->prevNLSF_Q15, 0, MAX_LPC_ORDER * sizeof(int));

		psDec->sLTP_buf_idx = 0;
		psDec->lagPrev = 100;
		psDec->LastGainIndex = 1;
		psDec->prev_sigtype = 0;
		psDec->first_frame_after_reset = 1;

		if (fs_kHz == 24) {
			psDec->HP_A = SKP_Silk_Dec_A_HP_24;
			psDec->HP_B = SKP_Silk_Dec_B_HP_24;
		} else if (fs_kHz == 16) {
			psDec->HP_A = SKP_Silk_Dec_A_HP_16;
			psDec->HP_B = SKP_Silk_Dec_B_HP_16;
		} else if (fs_kHz == 12) {
			psDec->HP_A = SKP_Silk_Dec_A_HP_12;
			psDec->HP_B = SKP_Silk_Dec_B_HP_12;
		} else if (fs_kHz == 8) {
			psDec->HP_A = SKP_Silk_Dec_A_HP_8;
			psDec->HP_B = SKP_Silk_Dec_B_HP_8;
		} else {
			/* unsupported sampling rate */
			assert(0);
		}
	}

	/* Check that settings are valid */
	assert(psDec->frame_length > 0
		   && psDec->frame_length <= MAX_FRAME_LENGTH);
}
/* Convert adaptive Mid/Side representation to Left/Right stereo signal */
void silk_stereo_MS_to_LR( 
    stereo_dec_state    *state,                         /* I/O  State                                       */
    opus_int16           x1[],                           /* I/O  Left input signal, becomes mid signal       */
    opus_int16           x2[],                           /* I/O  Right input signal, becomes side signal     */
    const opus_int32     pred_Q13[],                     /* I    Predictors                                  */
    opus_int             fs_kHz,                         /* I    Samples rate (kHz)                          */
    opus_int             frame_length                    /* I    Number of samples                           */
)
{
    opus_int   n, denom_Q16, delta0_Q13, delta1_Q13;
    opus_int32 sum, diff, pred0_Q13, pred1_Q13;

    /* Buffering */
    SKP_memcpy( x1, state->sMid,  2 * sizeof( opus_int16 ) );
    SKP_memcpy( x2, state->sSide, 2 * sizeof( opus_int16 ) );
    SKP_memcpy( state->sMid,  &x1[ frame_length ], 2 * sizeof( opus_int16 ) );
    SKP_memcpy( state->sSide, &x2[ frame_length ], 2 * sizeof( opus_int16 ) );

    /* Interpolate predictors and add prediction to side channel */
    pred0_Q13  = state->pred_prev_Q13[ 0 ];
    pred1_Q13  = state->pred_prev_Q13[ 1 ];
    denom_Q16  = SKP_DIV32_16( 1 << 16, STEREO_INTERP_LEN_MS * fs_kHz );
    delta0_Q13 = SKP_RSHIFT_ROUND( SKP_SMULBB( pred_Q13[ 0 ] - state->pred_prev_Q13[ 0 ], denom_Q16 ), 16 );
    delta1_Q13 = SKP_RSHIFT_ROUND( SKP_SMULBB( pred_Q13[ 1 ] - state->pred_prev_Q13[ 1 ], denom_Q16 ), 16 );
    for( n = 0; n < STEREO_INTERP_LEN_MS * fs_kHz; n++ ) {
        pred0_Q13 += delta0_Q13;
        pred1_Q13 += delta1_Q13;
        sum = SKP_LSHIFT( SKP_ADD_LSHIFT( x1[ n ] + x1[ n + 2 ], x1[ n + 1 ], 1 ), 9 );         /* Q11 */ 
        sum = SKP_SMLAWB( SKP_LSHIFT( ( opus_int32 )x2[ n + 1 ], 8 ), sum, pred0_Q13 );          /* Q8  */
        sum = SKP_SMLAWB( sum, SKP_LSHIFT( ( opus_int32 )x1[ n + 1 ], 11 ), pred1_Q13 );         /* Q8  */
        x2[ n + 1 ] = (opus_int16)SKP_SAT16( SKP_RSHIFT_ROUND( sum, 8 ) );
    }
    pred0_Q13 = pred_Q13[ 0 ];
    pred1_Q13 = pred_Q13[ 1 ];
    for( n = STEREO_INTERP_LEN_MS * fs_kHz; n < frame_length; n++ ) {
        sum = SKP_LSHIFT( SKP_ADD_LSHIFT( x1[ n ] + x1[ n + 2 ], x1[ n + 1 ], 1 ), 9 );         /* Q11 */ 
        sum = SKP_SMLAWB( SKP_LSHIFT( ( opus_int32 )x2[ n + 1 ], 8 ), sum, pred0_Q13 );          /* Q8  */
        sum = SKP_SMLAWB( sum, SKP_LSHIFT( ( opus_int32 )x1[ n + 1 ], 11 ), pred1_Q13 );         /* Q8  */
        x2[ n + 1 ] = (opus_int16)SKP_SAT16( SKP_RSHIFT_ROUND( sum, 8 ) );
    }
    state->pred_prev_Q13[ 0 ] = pred_Q13[ 0 ];
    state->pred_prev_Q13[ 1 ] = pred_Q13[ 1 ];

    /* Convert to left/right signals */
    for( n = 0; n < frame_length; n++ ) {
        sum  = x1[ n + 1 ] + (opus_int32)x2[ n + 1 ];
        diff = x1[ n + 1 ] - (opus_int32)x2[ n + 1 ];
        x1[ n + 1 ] = (opus_int16)SKP_SAT16( sum );
        x2[ n + 1 ] = (opus_int16)SKP_SAT16( diff );
    }
}
Esempio n. 9
0
/* Encodes signs of excitation */
void silk_encode_signs(
    ec_enc                      *psRangeEnc,                        /* I/O  Compressor data structure                   */
    const SKP_int8              pulses[],                           /* I    pulse signal                                */
    SKP_int                     length,                             /* I    length of input                             */
    const SKP_int               signalType,                         /* I    Signal type                                 */
    const SKP_int               quantOffsetType,                    /* I    Quantization offset type                    */
    const SKP_int               sum_pulses[ MAX_NB_SHELL_BLOCKS ]   /* I    Sum of absolute pulses per block            */
)
{
    SKP_int         i, j, p;
    SKP_uint8       icdf[ 2 ];
    const SKP_int8  *q_ptr;
    const SKP_uint8 *icdf_ptr;

    icdf[ 1 ] = 0;
    q_ptr = pulses;
    i = SKP_SMULBB( 6, SKP_ADD_LSHIFT( quantOffsetType, signalType, 1 ) );
    icdf_ptr = &silk_sign_iCDF[ i ];
    length = SKP_RSHIFT( length + SHELL_CODEC_FRAME_LENGTH/2, LOG2_SHELL_CODEC_FRAME_LENGTH );
    for( i = 0; i < length; i++ ) {
        p = sum_pulses[ i ];
        if( p > 0 ) {
            icdf[ 0 ] = icdf_ptr[ SKP_min( p - 1, 5 ) ];
            for( j = 0; j < SHELL_CODEC_FRAME_LENGTH; j++ ) {
                if( q_ptr[ j ] != 0 ) {
                    ec_enc_icdf( psRangeEnc, SKP_enc_map( q_ptr[ j ]), icdf, 8 );
                }
            }
        }
        q_ptr += SHELL_CODEC_FRAME_LENGTH;
    }
}
Esempio n. 10
0
/* Variable order MA filter */
void SKP_Silk_MA(
    const SKP_int16      *in,            /* I:   input signal                                */
    const SKP_int16      *B,             /* I:   MA coefficients, Q13 [order+1]              */
    SKP_int32            *S,             /* I/O: state vector [order]                        */
    SKP_int16            *out,           /* O:   output signal                               */
    const SKP_int32      len,            /* I:   signal length                               */
    const SKP_int32      order           /* I:   filter order                                */
)
{
    SKP_int   k, d, in16;
    SKP_int32 out32;
    
    for( k = 0; k < len; k++ ) {
        in16 = in[ k ];
        out32 = SKP_SMLABB( S[ 0 ], in16, B[ 0 ] );
        out32 = SKP_RSHIFT_ROUND( out32, 13 );
        
        for( d = 1; d < order; d++ ) {
            S[ d - 1 ] = SKP_SMLABB( S[ d ], in16, B[ d ] );
        }
        S[ order - 1 ] = SKP_SMULBB( in16, B[ order ] );

        /* Limit */
        out[ k ] = (SKP_int16)SKP_SAT16( out32 );
    }
}
Esempio n. 11
0
/* Decodes signs of excitation */
void SKP_Silk_decode_signs(SKP_Silk_range_coder_state * sRC,	/* I/O  Range coder state                           */
			   int q[],	/* I/O  pulse signal                                */
			   const int length,	/* I    length of output                            */
			   const int sigtype,	/* I    Signal type                                 */
			   const int QuantOffsetType,	/* I    Quantization offset type                    */
			   const int RateLevelIndex	/* I    Rate Level Index                            */
    )
{
	int i;
	int data;
	const uint16_t *cdf;

	i = SKP_SMULBB(N_RATE_LEVELS - 1,
		       SKP_LSHIFT(sigtype,
				  1) + QuantOffsetType) + RateLevelIndex;
	cdf = SKP_Silk_sign_CDF[i];

	for (i = 0; i < length; i++) {
		if (q[i] > 0) {
			SKP_Silk_range_decoder(&data, sRC, cdf, 1);
			/* attach sign */
			/* implementation with shift, subtraction, multiplication */
			q[i] *= SKP_dec_map(data);
		}
	}
}
/* Convert NLSF parameters to stable AR prediction filter coefficients */
void SKP_Silk_NLSF2A_stable(
    SKP_int16                       pAR_Q12[ MAX_LPC_ORDER ],   /* O    Stabilized AR coefs [LPC_order]     */ 
    const SKP_int                   pNLSF[ MAX_LPC_ORDER ],     /* I    NLSF vector         [LPC_order]     */
    const SKP_int                   LPC_order                   /* I    LPC/LSF order                       */
)
{
    SKP_int   i;
    SKP_int32 invGain_Q30;

    SKP_Silk_NLSF2A( pAR_Q12, pNLSF, LPC_order );

    /* Ensure stable LPCs */
    for( i = 0; i < MAX_LPC_STABILIZE_ITERATIONS; i++ ) {
        if( SKP_Silk_LPC_inverse_pred_gain( &invGain_Q30, pAR_Q12, LPC_order ) == 1 ) {
            SKP_Silk_bwexpander( pAR_Q12, LPC_order, 65536 - SKP_SMULBB( 10 + i, i ) );		/* 10_Q16 = 0.00015 */
        } else {
            break;
        }
    }

    /* Reached the last iteration */
    if( i == MAX_LPC_STABILIZE_ITERATIONS ) {
        SKP_assert( 0 );
        for( i = 0; i < LPC_order; i++ ) {
            pAR_Q12[ i ] = 0;
        }
    }
}
Esempio n. 13
0
/* Calculates correlation vector X'*t */
void SKP_Silk_corrVector_FIX(
    const SKP_int16                 *x,         /* I    x vector [L + order - 1] used to form data matrix X */
    const SKP_int16                 *t,         /* I    target vector [L]                                   */
    const SKP_int                   L,          /* I    Length of vectors                                   */
    const SKP_int                   order,      /* I    Max lag for correlation                             */
    SKP_int32                       *Xt,        /* O    Pointer to X'*t correlation vector [order]          */
    const SKP_int                   rshifts     /* I    Right shifts of correlations                        */
)
{
    SKP_int         lag, i;
    const SKP_int16 *ptr1, *ptr2;
    SKP_int32       inner_prod;

    ptr1 = &x[ order - 1 ]; /* Points to first sample of column 0 of X: X[:,0] */
    ptr2 = t;
    /* Calculate X'*t */
    if( rshifts > 0 ) {
        /* Right shifting used */
        for( lag = 0; lag < order; lag++ ) {
            inner_prod = 0;
            for( i = 0; i < L; i++ ) {
                inner_prod += SKP_RSHIFT32( SKP_SMULBB( ptr1[ i ], ptr2[i] ), rshifts );
            }
            Xt[ lag ] = inner_prod; /* X[:,lag]'*t */
            ptr1--; /* Go to next column of X */
        }
    } else {
        SKP_assert( rshifts == 0 );
        for( lag = 0; lag < order; lag++ ) {
            Xt[ lag ] = SKP_Silk_inner_prod_aligned( ptr1, ptr2, L ); /* X[:,lag]'*t */
            ptr1--; /* Go to next column of X */
        }
    }
}
Esempio n. 14
0
/* Variable order MA prediction error filter */
void SKP_Silk_MA_Prediction(
    const SKP_int16      *in,            /* I:   Input signal                                */
    const SKP_int16      *B,             /* I:   MA prediction coefficients, Q12 [order]     */
    SKP_int32            *S,             /* I/O: State vector [order]                        */
    SKP_int16            *out,           /* O:   Output signal                               */
    const SKP_int32      len,            /* I:   Signal length                               */
    const SKP_int32      order           /* I:   Filter order                                */
)
{
    SKP_int   k, d, in16;
    SKP_int32 out32;

    for( k = 0; k < len; k++ ) {
        in16 = in[ k ];
        out32 = SKP_LSHIFT( in16, 12 ) - S[ 0 ];
        out32 = SKP_RSHIFT_ROUND( out32, 12 );
        
        for( d = 0; d < order - 1; d++ ) {
            S[ d ] = SKP_SMLABB_ovflw( S[ d + 1 ], in16, B[ d ] );
        }
        S[ order - 1 ] = SKP_SMULBB( in16, B[ order - 1 ] );

        /* Limit */
        out[ k ] = (SKP_int16)SKP_SAT16( out32 );
    }
}
Esempio n. 15
0
/* Encodes signs of excitation */
void SKP_Silk_encode_signs(
    SKP_Silk_range_coder_state      *sRC,               /* I/O  Range coder state                       */
    const SKP_int8                  q[],                /* I    Pulse signal                            */
    const SKP_int                   length,             /* I    Length of input                         */
    const SKP_int                   sigtype,            /* I    Signal type                             */
    const SKP_int                   QuantOffsetType,    /* I    Quantization offset type                */
    const SKP_int                   RateLevelIndex      /* I    Rate level index                        */
)
{
    SKP_int i;
    SKP_int inData;
    SKP_uint16 cdf[ 3 ];

    i = SKP_SMULBB( N_RATE_LEVELS - 1, SKP_LSHIFT( sigtype, 1 ) + QuantOffsetType ) + RateLevelIndex;
    cdf[ 0 ] = 0;
    cdf[ 1 ] = SKP_Silk_sign_CDF[ i ];
    cdf[ 2 ] = 65535;
    
    for( i = 0; i < length; i++ ) {
        if( q[ i ] != 0 ) {
            inData = SKP_enc_map( q[ i ] ); /* - = 0, + = 1 */
            SKP_Silk_range_encoder( sRC, inData, cdf );
        }
    }
}
Esempio n. 16
0
/* Compute quantization errors for an LPC_order element input vector for a VQ codebook */
void silk_NLSF_VQ(
    SKP_int32                   err_Q26[],              /* O    Quantization errors [K]                     */
    const SKP_int16             in_Q15[],               /* I    Input vectors to be quantized [LPC_order]   */
    const SKP_uint8             pCB_Q8[],               /* I    Codebook vectors [K*LPC_order]              */
    const SKP_int               K,                      /* I    Number of codebook vectors                  */
    const SKP_int               LPC_order               /* I    Number of LPCs                              */
)
{
    SKP_int        i, m;
    SKP_int32      diff_Q15, sum_error_Q30, sum_error_Q26;

    SKP_assert( LPC_order <= 16 );
    SKP_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 = SKP_SUB_LSHIFT32( in_Q15[ m ], ( SKP_int32 )*pCB_Q8++, 7 ); // range: [ -32767 : 32767 ]
            sum_error_Q30 = SKP_SMULBB( diff_Q15, diff_Q15 );

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

            sum_error_Q26 = SKP_ADD_RSHIFT32( sum_error_Q26, sum_error_Q30, 4 );

            SKP_assert( sum_error_Q26 >= 0 );
            SKP_assert( sum_error_Q30 >= 0 );
        }
        err_Q26[ i ] = sum_error_Q26;
    }
}
/* Upsample using a combination of allpass-based 2x upsampling and FIR interpolation */
void SKP_Silk_resampler_private_IIR_FIR(
	void	                        *SS,		    /* I/O: Resampler state 						*/
	SKP_int16						out[],		    /* O:	Output signal 							*/
	const SKP_int16					in[],		    /* I:	Input signal							*/
	SKP_int32					    inLen		    /* I:	Number of input samples					*/
)
{
    SKP_Silk_resampler_state_struct *S = (SKP_Silk_resampler_state_struct *)SS;
	SKP_int32 nSamplesIn, table_index;
	SKP_int32 max_index_Q16, index_Q16, index_increment_Q16, res_Q15;
	SKP_int16 buf[ 2 * RESAMPLER_MAX_BATCH_SIZE_IN + RESAMPLER_ORDER_FIR_144 ];
    SKP_int16 *buf_ptr;

	/* Copy buffered samples to start of buffer */	
	SKP_memcpy( buf, S->sFIR, RESAMPLER_ORDER_FIR_144 * sizeof( SKP_int32 ) );

	/* Iterate over blocks of frameSizeIn input samples */
    index_increment_Q16 = S->invRatio_Q16;
	while( 1 ) {
		nSamplesIn = SKP_min( inLen, S->batchSize );

        if( S->input2x == 1 ) {
		    /* Upsample 2x */
            S->up2_function( S->sIIR, &buf[ RESAMPLER_ORDER_FIR_144 ], in, nSamplesIn );
        } else {
		    /* Fourth-order ARMA filter */
            SKP_Silk_resampler_private_ARMA4( S->sIIR, &buf[ RESAMPLER_ORDER_FIR_144 ], in, S->Coefs, nSamplesIn );
        }

        max_index_Q16 = SKP_LSHIFT32( nSamplesIn, 16 + S->input2x );         /* +1 if 2x upsampling */

		/* Interpolate upsampled signal and store in output array */
	    for( index_Q16 = 0; index_Q16 < max_index_Q16; index_Q16 += index_increment_Q16 ) {
            table_index = SKP_SMULWB( index_Q16 & 0xFFFF, 144 );
            buf_ptr = &buf[ index_Q16 >> 16 ];
            res_Q15 = SKP_SMULBB(          buf_ptr[ 0 ], SKP_Silk_resampler_frac_FIR_144[       table_index ][ 0 ] );
            res_Q15 = SKP_SMLABB( res_Q15, buf_ptr[ 1 ], SKP_Silk_resampler_frac_FIR_144[       table_index ][ 1 ] );
            res_Q15 = SKP_SMLABB( res_Q15, buf_ptr[ 2 ], SKP_Silk_resampler_frac_FIR_144[       table_index ][ 2 ] );
            res_Q15 = SKP_SMLABB( res_Q15, buf_ptr[ 3 ], SKP_Silk_resampler_frac_FIR_144[ 143 - table_index ][ 2 ] );
            res_Q15 = SKP_SMLABB( res_Q15, buf_ptr[ 4 ], SKP_Silk_resampler_frac_FIR_144[ 143 - table_index ][ 1 ] );
            res_Q15 = SKP_SMLABB( res_Q15, buf_ptr[ 5 ], SKP_Silk_resampler_frac_FIR_144[ 143 - table_index ][ 0 ] );
			*out++ = (SKP_int16)SKP_SAT16( SKP_RSHIFT_ROUND( res_Q15, 15 ) );
	    }
		in += nSamplesIn;
		inLen -= nSamplesIn;

		if( inLen > 0 ) {
			/* More iterations to do; copy last part of filtered signal to beginning of buffer */
			SKP_memcpy( buf, &buf[ nSamplesIn << S->input2x ], RESAMPLER_ORDER_FIR_144 * sizeof( SKP_int32 ) );
		} else {
			break;
		}
	}

	/* Copy last part of filtered signal to the state for the next call */
	SKP_memcpy( S->sFIR, &buf[nSamplesIn << S->input2x ], RESAMPLER_ORDER_FIR_144 * sizeof( SKP_int32 ) );
}
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;
    }
}
Esempio n. 19
0
/* Variable order MA prediction error filter */
void SKP_Silk_MA_Prediction(
    const SKP_int16      *in,            /* I:   Input signal                                */
    const SKP_int16      *B,             /* I:   MA prediction coefficients, Q12 [order]     */
    SKP_int32            *S,             /* I/O: State vector [order]                        */
    SKP_int16            *out,           /* O:   Output signal                               */
    const SKP_int32      len,            /* I:   Signal length                               */
    const SKP_int32      order           /* I:   Filter order                                */
)
{
    SKP_int   k, d, in16;
    SKP_int32 out32;
    SKP_int32 B32;

    if( ( order & 1 ) == 0 && (SKP_int32)( (SKP_int_ptr_size)B & 3 ) == 0 ) {
        /* Even order and 4-byte aligned coefficient array */

        /* NOTE: the code below loads two int16 values in an int32, and multiplies each using the    */
        /* SMLABB and SMLABT instructions. On a big-endian CPU the two int16 variables would be      */
        /* loaded in reverse order and the code will give the wrong result. In that case swapping    */
        /* the SMLABB and SMLABT instructions should solve the problem.                              */
        for( k = 0; k < len; k++ ) {
            in16 = in[ k ];
            out32 = SKP_LSHIFT( in16, 12 ) - S[ 0 ];
            out32 = SKP_RSHIFT_ROUND( out32, 12 );
            
            for( d = 0; d < order - 2; d += 2 ) {
                B32 = *( (SKP_int32*)&B[ d ] );                /* read two coefficients at once */
                S[ d ]     = SKP_SMLABB_ovflw( S[ d + 1 ], in16, B32 );
                S[ d + 1 ] = SKP_SMLABT_ovflw( S[ d + 2 ], in16, B32 );
            }
            B32 = *( (SKP_int32*)&B[ d ] );                    /* read two coefficients at once */
            S[ order - 2 ] = SKP_SMLABB_ovflw( S[ order - 1 ], in16, B32 );
            S[ order - 1 ] = SKP_SMULBT( in16, B32 );

            /* Limit */
            out[ k ] = (SKP_int16)SKP_SAT16( out32 );
        }
    } else {
        /* Odd order or not 4-byte aligned coefficient array */
        for( k = 0; k < len; k++ ) {
            in16 = in[ k ];
            out32 = SKP_LSHIFT( in16, 12 ) - S[ 0 ];
            out32 = SKP_RSHIFT_ROUND( out32, 12 );
            
            for( d = 0; d < order - 1; d++ ) {
                S[ d ] = SKP_SMLABB_ovflw( S[ d + 1 ], in16, B[ d ] );
            }
            S[ order - 1 ] = SKP_SMULBB( in16, B[ order - 1 ] );

            /* Limit */
            out[ k ] = (SKP_int16)SKP_SAT16( out32 );
        }
    }
}
void SKP_Silk_noise_shape_analysis_FIX(
    SKP_Silk_encoder_state_FIX      *psEnc,         /* I/O  Encoder state FIX                           */
    SKP_Silk_encoder_control_FIX    *psEncCtrl,     /* I/O  Encoder control FIX                         */
    const SKP_int16                 *pitch_res,     /* I    LPC residual from pitch analysis            */
    const SKP_int16                 *x              /* I    Input signal [ frame_length + la_shape ]    */
)
{
    SKP_Silk_shape_state_FIX *psShapeSt = &psEnc->sShape;
    SKP_int     k, i, nSamples, Qnrg, b_Q14, warping_Q16, scale = 0;
    SKP_int32   SNR_adj_dB_Q7, HarmBoost_Q16, HarmShapeGain_Q16, Tilt_Q16, tmp32;
    SKP_int32   nrg, pre_nrg_Q30, log_energy_Q7, log_energy_prev_Q7, energy_variation_Q7;
    SKP_int32   delta_Q16, BWExp1_Q16, BWExp2_Q16, gain_mult_Q16, gain_add_Q16, strength_Q16, b_Q8;
    SKP_int32   auto_corr[     MAX_SHAPE_LPC_ORDER + 1 ];
    SKP_int32   refl_coef_Q16[ MAX_SHAPE_LPC_ORDER ];
    SKP_int32   AR1_Q24[       MAX_SHAPE_LPC_ORDER ];
    SKP_int32   AR2_Q24[       MAX_SHAPE_LPC_ORDER ];
    SKP_int16   x_windowed[    SHAPE_LPC_WIN_MAX ];
    SKP_int32   sqrt_nrg[ MAX_NB_SUBFR ], Qnrg_vec[ MAX_NB_SUBFR ];
    const SKP_int16 *x_ptr, *pitch_res_ptr;

    /* Point to start of first LPC analysis block */
    x_ptr = x - psEnc->sCmn.la_shape;

    /****************/
    /* CONTROL SNR  */
    /****************/
    /* Reduce SNR_dB values if recent bitstream has exceeded TargetRate */
    psEncCtrl->current_SNR_dB_Q7 = psEnc->SNR_dB_Q7 - SKP_SMULBB( psEnc->BufferedInChannel_ms, SKP_FIX_CONST( 0.1, 7 ) );

    /* Reduce SNR_dB because of any inband FEC used */
    psEncCtrl->current_SNR_dB_Q7 -= psEnc->inBandFEC_SNR_comp_Q7;

    /****************/
    /* GAIN CONTROL */
    /****************/
    /* Input quality is the average of the quality in the lowest two VAD bands */
    psEncCtrl->input_quality_Q14 = ( SKP_int )SKP_RSHIFT( ( SKP_int32 )psEnc->sCmn.input_quality_bands_Q15[ 0 ] 
        + psEnc->sCmn.input_quality_bands_Q15[ 1 ], 2 );

    /* Coding quality level, between 0.0_Q0 and 1.0_Q0, but in Q14 */
    psEncCtrl->coding_quality_Q14 = SKP_RSHIFT( SKP_Silk_sigm_Q15( SKP_RSHIFT_ROUND( psEncCtrl->current_SNR_dB_Q7 - 
        SKP_FIX_CONST( 18.0, 7 ), 4 ) ), 1 );

    /* Reduce coding SNR during low speech activity */
    SNR_adj_dB_Q7 = psEncCtrl->current_SNR_dB_Q7;
    if( psEnc->sCmn.useCBR == 0 ) {
        b_Q8 = SKP_FIX_CONST( 1.0, 8 ) - psEnc->sCmn.speech_activity_Q8;
        b_Q8 = SKP_SMULWB( SKP_LSHIFT( b_Q8, 8 ), b_Q8 );
        SNR_adj_dB_Q7 = SKP_SMLAWB( SNR_adj_dB_Q7,
            SKP_SMULBB( SKP_FIX_CONST( -BG_SNR_DECR_dB, 7 ) >> ( 4 + 1 ), b_Q8 ),                                       // Q11
            SKP_SMULWB( SKP_FIX_CONST( 1.0, 14 ) + psEncCtrl->input_quality_Q14, psEncCtrl->coding_quality_Q14 ) );     // Q12
    }
/* SKP_Silk_prefilter. Prefilter for finding Quantizer input signal                           */
SKP_INLINE void SKP_Silk_prefilt_FIX(
    SKP_Silk_prefilter_state_FIX *P,                    /* I/O state                          */
    SKP_int32   st_res_Q12[],                           /* I short term residual signal       */
    SKP_int16   xw[],                                   /* O prefiltered signal               */
    SKP_int32   HarmShapeFIRPacked_Q12,                 /* I Harmonic shaping coeficients     */
    SKP_int     Tilt_Q14,                               /* I Tilt shaping coeficient          */
    SKP_int32   LF_shp_Q14,                             /* I Low-frequancy shaping coeficients*/
    SKP_int     lag,                                    /* I Lag for harmonic shaping         */
    SKP_int     length                                  /* I Length of signals                */
)
{
    SKP_int   i, idx, LTP_shp_buf_idx;
    SKP_int32 n_LTP_Q12, n_Tilt_Q10, n_LF_Q10;
    SKP_int32 sLF_MA_shp_Q12, sLF_AR_shp_Q12;
    SKP_int16 *LTP_shp_buf;

    /* To speed up use temp variables instead of using the struct */
    LTP_shp_buf     = P->sLTP_shp;
    LTP_shp_buf_idx = P->sLTP_shp_buf_idx;
    sLF_AR_shp_Q12  = P->sLF_AR_shp_Q12;
    sLF_MA_shp_Q12  = P->sLF_MA_shp_Q12;

    for( i = 0; i < length; i++ ) {
        if( lag > 0 ) {
            /* unrolled loop */
            SKP_assert( HARM_SHAPE_FIR_TAPS == 3 );
            idx = lag + LTP_shp_buf_idx;
            n_LTP_Q12 = SKP_SMULBB(            LTP_shp_buf[ ( idx - HARM_SHAPE_FIR_TAPS / 2 - 1) & LTP_MASK ], HarmShapeFIRPacked_Q12 );
            n_LTP_Q12 = SKP_SMLABT( n_LTP_Q12, LTP_shp_buf[ ( idx - HARM_SHAPE_FIR_TAPS / 2    ) & LTP_MASK ], HarmShapeFIRPacked_Q12 );
            n_LTP_Q12 = SKP_SMLABB( n_LTP_Q12, LTP_shp_buf[ ( idx - HARM_SHAPE_FIR_TAPS / 2 + 1) & LTP_MASK ], HarmShapeFIRPacked_Q12 );
        } else {
            n_LTP_Q12 = 0;
        }

        n_Tilt_Q10 = SKP_SMULWB( sLF_AR_shp_Q12, Tilt_Q14 );
        n_LF_Q10   = SKP_SMLAWB( SKP_SMULWT( sLF_AR_shp_Q12, LF_shp_Q14 ), sLF_MA_shp_Q12, LF_shp_Q14 );

        sLF_AR_shp_Q12 = SKP_SUB32( st_res_Q12[ i ], SKP_LSHIFT( n_Tilt_Q10, 2 ) );
        sLF_MA_shp_Q12 = SKP_SUB32( sLF_AR_shp_Q12,  SKP_LSHIFT( n_LF_Q10,   2 ) );

        LTP_shp_buf_idx = ( LTP_shp_buf_idx - 1 ) & LTP_MASK;
        LTP_shp_buf[ LTP_shp_buf_idx ] = ( SKP_int16 )SKP_SAT16( SKP_RSHIFT_ROUND( sLF_MA_shp_Q12, 12 ) );

        xw[i] = ( SKP_int16 )SKP_SAT16( SKP_RSHIFT_ROUND( SKP_SUB32( sLF_MA_shp_Q12, n_LTP_Q12 ), 12 ) );
    }

    /* Copy temp variable back to state */
    P->sLF_AR_shp_Q12   = sLF_AR_shp_Q12;
    P->sLF_MA_shp_Q12   = sLF_MA_shp_Q12;
    P->sLTP_shp_buf_idx = LTP_shp_buf_idx;
}
opus_int32 silk_inner_prod_aligned_scale(
    const opus_int16 *const  inVec1,     /*    I input vector 1          */
    const opus_int16 *const  inVec2,     /*    I input vector 2          */
    const opus_int           scale,      /*    I number of bits to shift */
    const opus_int           len         /*    I vector lengths          */
)
{
    opus_int   i; 
    opus_int32 sum = 0;
    for( i = 0; i < len; i++ ) {
        sum = SKP_ADD_RSHIFT32( sum, SKP_SMULBB( inVec1[ i ], inVec2[ i ] ), scale );
    }
    return sum;
}
Esempio n. 23
0
SKP_int SKP_Silk_SDK_QueryEncoder(
    const void *encState,                       /* I:   State Vector                                    */
    SKP_Silk_EncodeControlStruct *encStatus     /* O:   Control Structure                               */
)
{
    SKP_Silk_encoder_state_Fxx *psEnc;
    SKP_int ret = SKP_SILK_NO_ERROR;

    psEnc = ( SKP_Silk_encoder_state_Fxx* )encState;

    encStatus->API_sampleRate        = psEnc->sCmn.API_fs_Hz;
    encStatus->maxInternalSampleRate = SKP_SMULBB( psEnc->sCmn.maxInternal_fs_kHz, 1000 );
    encStatus->minInternalSampleRate = SKP_SMULBB( psEnc->sCmn.minInternal_fs_kHz, 1000 );
    encStatus->payloadSize_ms        = psEnc->sCmn.PacketSize_ms;
    encStatus->bitRate               = psEnc->sCmn.TargetRate_bps;
    encStatus->packetLossPercentage  = psEnc->sCmn.PacketLoss_perc;
    encStatus->complexity            = psEnc->sCmn.Complexity;
    encStatus->useInBandFEC          = psEnc->sCmn.useInBandFEC;
    encStatus->useDTX                = psEnc->sCmn.useDTX;
    encStatus->useCBR                = psEnc->sCmn.useCBR;
    encStatus->internalSampleRate    = SKP_SMULBB( psEnc->sCmn.fs_kHz, 1000 );
    return ret;
}
/* Predict number of bytes used to encode q */
int SKP_Silk_pulses_to_bytes(	/* O  Return value, predicted number of bytes used to encode q */
				    SKP_Silk_encoder_state * psEncC,	/* I/O  Encoder State */
				    int q[]	/* I    Pulse signal  */
    )
{
	int i, j, iter, *q_ptr;
	int32_t sum_abs_val, nBytes, acc_nBytes;
	/* Take the absolute value of the pulses */
	iter = psEncC->frame_length / SHELL_CODEC_FRAME_LENGTH;

	/* Calculate rate as a nonlinaer mapping of sum abs value of each Shell block */
	q_ptr = q;
	acc_nBytes = 0;
	for (j = 0; j < iter; j++) {
		sum_abs_val = 0;
		for (i = 0; i < SHELL_CODEC_FRAME_LENGTH; i += 4) {
			sum_abs_val += SKP_abs(q_ptr[i + 0]);
			sum_abs_val += SKP_abs(q_ptr[i + 1]);
			sum_abs_val += SKP_abs(q_ptr[i + 2]);
			sum_abs_val += SKP_abs(q_ptr[i + 3]);
		}
		/* Calculate nBytes used for thi sshell frame */
		nBytes = SKP_SMULWB(SKP_SMULBB(sum_abs_val, sum_abs_val), POLY_FIT_2_Q20);	// Q4
		nBytes = SKP_LSHIFT_SAT32(nBytes, 11);	// Q15
		nBytes += SKP_SMULBB(sum_abs_val, POLY_FIT_1_Q15);	// Q15
		nBytes += POLY_FIT_0_Q15;	// Q15

		acc_nBytes += nBytes;

		q_ptr += SHELL_CODEC_FRAME_LENGTH;	/* update pointer */
	}

	acc_nBytes = SKP_RSHIFT_ROUND(acc_nBytes, 15);	// Q0
	acc_nBytes = SKP_SAT16(acc_nBytes);	// just to be sure                            // Q0

	return ((int)acc_nBytes);
}
/* even order AR filter */
void SKP_Silk_LPC_synthesis_filter(
    const SKP_int16 *in,        /* I:   excitation signal */
    const SKP_int16 *A_Q12,     /* I:   AR coefficients [Order], between -8_Q0 and 8_Q0 */
    const SKP_int32 Gain_Q26,   /* I:   gain */
    SKP_int32 *S,               /* I/O: state vector [Order] */
    SKP_int16 *out,             /* O:   output signal */
    const SKP_int32 len,        /* I:   signal length */
    const SKP_int Order         /* I:   filter order, must be even */
)
{
    SKP_int   k, j, idx, Order_half = SKP_RSHIFT( Order, 1 );
    SKP_int32 SA, SB, out32_Q10, out32;

    /* Order must be even */
    SKP_assert( 2 * Order_half == Order );

    /* S[] values are in Q14 */
    for( k = 0; k < len; k++ ) {
        SA = S[ Order - 1 ];
        out32_Q10 = 0;
        for( j = 0; j < ( Order_half - 1 ); j++ ) {
            idx = SKP_SMULBB( 2, j ) + 1;
            SB = S[ Order - 1 - idx ];
            S[ Order - 1 - idx ] = SA;
            out32_Q10 = SKP_SMLAWB( out32_Q10, SA, A_Q12[ ( j << 1 ) ] );
            out32_Q10 = SKP_SMLAWB( out32_Q10, SB, A_Q12[ ( j << 1 ) + 1 ] );
            SA = S[ Order - 2 - idx ];
            S[ Order - 2 - idx ] = SB;
        }

        /* unrolled loop: epilog */
        SB = S[ 0 ];
        S[ 0 ] = SA;
        out32_Q10 = SKP_SMLAWB( out32_Q10, SA, A_Q12[ Order - 2 ] );
        out32_Q10 = SKP_SMLAWB( out32_Q10, SB, A_Q12[ Order - 1 ] );
        /* apply gain to excitation signal and add to prediction */
        out32_Q10 = SKP_ADD_SAT32( out32_Q10, SKP_SMULWB( Gain_Q26, in[ k ] ) );

        /* scale to Q0 */
        out32 = SKP_RSHIFT_ROUND( out32_Q10, 10 );

        /* saturate output */
        out[ k ] = ( SKP_int16 )SKP_SAT16( out32 );

        /* move result into delay line */
        S[ Order - 1 ] = SKP_LSHIFT_SAT32( out32_Q10, 4 );
    }
}
void SKP_Silk_detect_SWB_input(SKP_Silk_detect_SWB_state * psSWBdetect,	/* (I/O) encoder state  */
			       const int16_t samplesIn[],	/* (I) input to encoder */
			       int nSamplesIn	/* (I) length of input */
    )
{
	int HP_8_kHz_len, i;
	int16_t in_HP_8_kHz[MAX_FRAME_LENGTH];
	int32_t energy_32, shift;

	/* High pass filter with cutoff at 8 khz */
	HP_8_kHz_len = SKP_min_int(nSamplesIn, MAX_FRAME_LENGTH);
	HP_8_kHz_len = SKP_max_int(HP_8_kHz_len, 0);

	/* Cutoff around 9 khz */
	/* A = conv(conv([8192,14613, 6868], [8192,12883, 7337]), [8192,11586, 7911]); */
	/* B = conv(conv([575, -948, 575], [575, -221, 575]), [575, 104, 575]); */
	SKP_Silk_biquad(samplesIn, SKP_Silk_SWB_detect_B_HP_Q13[0],
			SKP_Silk_SWB_detect_A_HP_Q13[0],
			psSWBdetect->S_HP_8_kHz[0], in_HP_8_kHz, HP_8_kHz_len);
	for (i = 1; i < NB_SOS; i++) {
		SKP_Silk_biquad(in_HP_8_kHz, SKP_Silk_SWB_detect_B_HP_Q13[i],
				SKP_Silk_SWB_detect_A_HP_Q13[i],
				psSWBdetect->S_HP_8_kHz[i], in_HP_8_kHz,
				HP_8_kHz_len);
	}

	/* Calculate energy in HP signal */
	SKP_Silk_sum_sqr_shift(&energy_32, &shift, in_HP_8_kHz, HP_8_kHz_len);

	/* Count concecutive samples above threshold, after adjusting threshold for number of input samples and shift */
	if (energy_32 >
	    SKP_RSHIFT(SKP_SMULBB(HP_8_KHZ_THRES, HP_8_kHz_len), shift)) {
		psSWBdetect->ConsecSmplsAboveThres += nSamplesIn;
		if (psSWBdetect->ConsecSmplsAboveThres > CONCEC_SWB_SMPLS_THRES) {
			psSWBdetect->SWB_detected = 1;
		}
	} else {
		psSWBdetect->ConsecSmplsAboveThres -= nSamplesIn;
		psSWBdetect->ConsecSmplsAboveThres =
		    SKP_max(psSWBdetect->ConsecSmplsAboveThres, 0);
	}

	/* If sufficient speech activity and no SWB detected, we detect the signal as being WB */
	if ((psSWBdetect->ActiveSpeech_ms > WB_DETECT_ACTIVE_SPEECH_MS_THRES)
	    && (psSWBdetect->SWB_detected == 0)) {
		psSWBdetect->WB_detected = 1;
	}
}
/* Solve L^t*x = b, where L is lower triangular with ones on the diagonal */
SKP_INLINE void SKP_Silk_LS_SolveLast_FIX(
    const SKP_int32     *L_Q16,     /* I Pointer to Lower Triangular Matrix */
    const SKP_int       M,          /* I Dim of Matrix equation */
    const SKP_int32     *b,         /* I b Vector */
    SKP_int32           *x_Q16      /* O x Vector */  
)
{
    SKP_int i, j;
    const SKP_int32 *ptr32;
    SKP_int32 tmp_32;

    for( i = M - 1; i >= 0; i-- ) {
        ptr32 = matrix_adr( L_Q16, 0, i, M );
        tmp_32 = 0;
        for( j = M - 1; j > i; j-- ) {
            tmp_32 = SKP_SMLAWW( tmp_32, ptr32[ SKP_SMULBB( j, M ) ], x_Q16[ j ] );
        }
        x_Q16[ i ] = SKP_SUB32( b[ i ], tmp_32 );
    }
}
SKP_INLINE SKP_int16 *SKP_Silk_resampler_private_IIR_FIR_INTERPOL( 
			SKP_int16 * out, SKP_int16 * buf, SKP_int32 max_index_Q16 , SKP_int32 index_increment_Q16 ){
	SKP_int32 index_Q16, res_Q15;
	SKP_int16 *buf_ptr;
	SKP_int32 table_index;
	/* Interpolate upsampled signal and store in output array */
	for( index_Q16 = 0; index_Q16 < max_index_Q16; index_Q16 += index_increment_Q16 ) {
        table_index = SKP_SMULWB( index_Q16 & 0xFFFF, 144 );
        buf_ptr = &buf[ index_Q16 >> 16 ];
            
        res_Q15 = SKP_SMULBB(          buf_ptr[ 0 ], SKP_Silk_resampler_frac_FIR_144[       table_index ][ 0 ] );
        res_Q15 = SKP_SMLABB( res_Q15, buf_ptr[ 1 ], SKP_Silk_resampler_frac_FIR_144[       table_index ][ 1 ] );
        res_Q15 = SKP_SMLABB( res_Q15, buf_ptr[ 2 ], SKP_Silk_resampler_frac_FIR_144[       table_index ][ 2 ] );
        res_Q15 = SKP_SMLABB( res_Q15, buf_ptr[ 3 ], SKP_Silk_resampler_frac_FIR_144[ 143 - table_index ][ 2 ] );
        res_Q15 = SKP_SMLABB( res_Q15, buf_ptr[ 4 ], SKP_Silk_resampler_frac_FIR_144[ 143 - table_index ][ 1 ] );
        res_Q15 = SKP_SMLABB( res_Q15, buf_ptr[ 5 ], SKP_Silk_resampler_frac_FIR_144[ 143 - table_index ][ 0 ] );          
		*out++ = (SKP_int16)SKP_SAT16( SKP_RSHIFT_ROUND( res_Q15, 15 ) );
	}
	return out;	
}
Esempio n. 29
0
/* Decodes signs of excitation */
void silk_decode_signs(
    ec_dec                      *psRangeDec,                        /* I/O  Compressor data structure                   */
    SKP_int                     pulses[],                           /* I/O  pulse signal                                */
    SKP_int                     length,                             /* I    length of input                             */
    const SKP_int               signalType,                         /* I    Signal type                                 */
    const SKP_int               quantOffsetType,                    /* I    Quantization offset type                    */
    const SKP_int               sum_pulses[ MAX_NB_SHELL_BLOCKS ]   /* I    Sum of absolute pulses per block            */
)
{
    SKP_int         i, j, p;
    SKP_uint8       icdf[ 2 ];
    SKP_int         *q_ptr;
    const SKP_uint8 *icdf_ptr;

    icdf[ 1 ] = 0;
    q_ptr = pulses;
    i = SKP_SMULBB( 6, SKP_ADD_LSHIFT( quantOffsetType, signalType, 1 ) );
    icdf_ptr = &silk_sign_iCDF[ i ];
    length = SKP_RSHIFT( length + SHELL_CODEC_FRAME_LENGTH/2, LOG2_SHELL_CODEC_FRAME_LENGTH );
    for( i = 0; i < length; i++ ) {
        p = sum_pulses[ i ];
        if( p > 0 ) {
            icdf[ 0 ] = icdf_ptr[ SKP_min( p - 1, 5 ) ];
            for( j = 0; j < SHELL_CODEC_FRAME_LENGTH; j++ ) {
                if( q_ptr[ j ] > 0 ) {
                    /* attach sign */
#if 0
                    /* conditional implementation */
                    if( ec_dec_icdf( psRangeDec, icdf, 8 ) == 0 ) {
                        q_ptr[ j ] = -q_ptr[ j ];
                    }
#else
                    /* implementation with shift, subtraction, multiplication */
                    q_ptr[ j ] *= SKP_dec_map( ec_dec_icdf( psRangeDec, icdf, 8 ) );
#endif
                }
            }
        }
        q_ptr += SHELL_CODEC_FRAME_LENGTH;
    }
}
Esempio n. 30
0
/* Generic filter loop. Runs about 10..25% faster than the unrolled
   C implementation. */
SKP_INLINE void FILTER_LOOP_ORDER_ANY(SKP_int32 * S, const SKP_int16 * B,
		SKP_int16 in16, SKP_int32 order)
{
	SKP_int d;

	/* Unroll for 4 elements */
	for(d = 0; d < order - 4; d += 4) {
		S[d + 0] = SKP_SMLABB(S[d + 1], in16, B[d + 0]);
		S[d + 1] = SKP_SMLABB(S[d + 2], in16, B[d + 1]);
		S[d + 2] = SKP_SMLABB(S[d + 3], in16, B[d + 2]);
		S[d + 3] = SKP_SMLABB(S[d + 4], in16, B[d + 3]);
	}
	if(d < order - 2) {
		S[d + 0] = SKP_SMLABB(S[d + 1], in16, B[d + 0]);
		S[d + 1] = SKP_SMLABB(S[d + 2], in16, B[d + 1]);
		d += 2;
	}
	if(d == order - 2)
		S[d] = SKP_SMLABB(S[d + 1], in16, B[d]);
	S[order - 1] = SKP_SMULBB(in16, B[order - 1]);
}