コード例 #1
0
/* Resamples by a factor 3/2 */
void SKP_Silk_resample_3_2(int16_t * out,	/*   O: Fs_high signal  [inLen*3/2]             */
			   int32_t * S,	/* I/O: State vector    [7+4]                   */
			   const int16_t * in,	/* I:   Fs_low signal   [inLen]                 */
			   int inLen	/* I:   Input length, must be a multiple of 2   */
    )
{
	int LSubFrameIn, LSubFrameOut;
	int16_t outH[3 * IN_SUBFR_LEN_RESAMPLE_3_2];
	int32_t scratch[(9 * IN_SUBFR_LEN_RESAMPLE_3_2) / 2];

	/* Check that input is multiple of 2 */
	assert(inLen % 2 == 0);

	while (inLen > 0) {
		LSubFrameIn = SKP_min_int(IN_SUBFR_LEN_RESAMPLE_3_2, inLen);
		LSubFrameOut = SKP_SMULWB(98304, LSubFrameIn);

		/* Upsample by a factor 3 */
		SKP_Silk_resample_3_1(outH, &S[0], in, LSubFrameIn);

		/* Downsample by a factor 2 */
		/* Scratch size needs to be: 3 * LSubFrameOut * sizeof( int32_t ) */
		SKP_Silk_resample_1_2_coarse(outH, &S[7], out, scratch,
					     LSubFrameOut);

		in += LSubFrameIn;
		out += LSubFrameOut;
		inLen -= LSubFrameIn;
	}
}
コード例 #2
0
/* 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;
    }
}
コード例 #3
0
void SKP_Silk_LTP_scale_ctrl_FIX(
    SKP_Silk_encoder_state_FIX      *psEnc,     /* I/O  encoder state FIX                           */
    SKP_Silk_encoder_control_FIX    *psEncCtrl  /* I/O  encoder control FIX                         */
)
{
    SKP_int round_loss, frames_per_packet;
    SKP_int g_out_Q5, g_limit_Q15, thrld1_Q15, thrld2_Q15;

    /* 1st order high-pass filter */
    psEnc->HPLTPredCodGain_Q7 = SKP_max_int( psEncCtrl->LTPredCodGain_Q7 - psEnc->prevLTPredCodGain_Q7, 0 ) 
        + SKP_RSHIFT_ROUND( psEnc->HPLTPredCodGain_Q7, 1 );
    
    psEnc->prevLTPredCodGain_Q7 = psEncCtrl->LTPredCodGain_Q7;

    /* combine input and filtered input */
    g_out_Q5    = SKP_RSHIFT_ROUND( SKP_RSHIFT( psEncCtrl->LTPredCodGain_Q7, 1 ) + SKP_RSHIFT( psEnc->HPLTPredCodGain_Q7, 1 ), 3 );
    g_limit_Q15 = SKP_Silk_sigm_Q15( g_out_Q5 - ( 3 << 5 ) );
            
    /* Default is minimum scaling */
    psEncCtrl->sCmn.LTP_scaleIndex = 0;

    /* Round the loss measure to whole pct */
    round_loss = ( SKP_int )psEnc->sCmn.PacketLoss_perc;

    /* Only scale if first frame in packet 0% */
    if( psEnc->sCmn.nFramesInPayloadBuf == 0 ) {
        
        frames_per_packet = SKP_DIV32_16( psEnc->sCmn.PacketSize_ms, FRAME_LENGTH_MS );

        round_loss += frames_per_packet - 1;
        thrld1_Q15 = LTPScaleThresholds_Q15[ SKP_min_int( round_loss,     NB_THRESHOLDS - 1 ) ];
        thrld2_Q15 = LTPScaleThresholds_Q15[ SKP_min_int( round_loss + 1, NB_THRESHOLDS - 1 ) ];
    
        if( g_limit_Q15 > thrld1_Q15 ) {
            /* Maximum scaling */
            psEncCtrl->sCmn.LTP_scaleIndex = 2;
        } else if( g_limit_Q15 > thrld2_Q15 ) {
            /* Medium scaling */
            psEncCtrl->sCmn.LTP_scaleIndex = 1;
        }
    }
    psEncCtrl->LTP_scale_Q14 = SKP_Silk_LTPScales_table_Q14[ psEncCtrl->sCmn.LTP_scaleIndex ];
}
コード例 #4
0
/* Laroia low complexity NLSF weights */
void SKP_Silk_NLSF_VQ_weights_laroia(
    SKP_int             *pNLSFW_Q6,         /* O: Pointer to input vector weights           [D x 1]     */
    const SKP_int       *pNLSF_Q15,         /* I: Pointer to input vector                   [D x 1]     */
    const SKP_int       D                   /* I: Input vector dimension (even)                         */
)
{
    SKP_int   k;
    SKP_int32 tmp1_int, tmp2_int;

    /* Check that we are guaranteed to end up within the required range */
    SKP_assert( D > 0 );
    SKP_assert( ( D & 1 ) == 0 );

    /* First value */
    tmp1_int = SKP_max_int( pNLSF_Q15[ 0 ], MIN_NDELTA );
    tmp1_int = SKP_DIV32_16( 1 << ( 15 + Q_OUT ), tmp1_int );
    tmp2_int = SKP_max_int( pNLSF_Q15[ 1 ] - pNLSF_Q15[ 0 ], MIN_NDELTA );
    tmp2_int = SKP_DIV32_16( 1 << ( 15 + Q_OUT ), tmp2_int );
    pNLSFW_Q6[ 0 ] = (SKP_int)SKP_min_int( tmp1_int + tmp2_int, SKP_int16_MAX );
    SKP_assert( pNLSFW_Q6[ 0 ] > 0 );

    /* Main loop */
    for( k = 1; k < D - 1; k += 2 ) {
        tmp1_int = SKP_max_int( pNLSF_Q15[ k + 1 ] - pNLSF_Q15[ k ], MIN_NDELTA );
        tmp1_int = SKP_DIV32_16( 1 << ( 15 + Q_OUT ), tmp1_int );
        pNLSFW_Q6[ k ] = (SKP_int)SKP_min_int( tmp1_int + tmp2_int, SKP_int16_MAX );
        SKP_assert( pNLSFW_Q6[ k ] > 0 );

        tmp2_int = SKP_max_int( pNLSF_Q15[ k + 2 ] - pNLSF_Q15[ k + 1 ], MIN_NDELTA );
        tmp2_int = SKP_DIV32_16( 1 << ( 15 + Q_OUT ), tmp2_int );
        pNLSFW_Q6[ k + 1 ] = (SKP_int)SKP_min_int( tmp1_int + tmp2_int, SKP_int16_MAX );
        SKP_assert( pNLSFW_Q6[ k + 1 ] > 0 );
    }

    /* Last value */
    tmp1_int = SKP_max_int( ( 1 << 15 ) - pNLSF_Q15[ D - 1 ], MIN_NDELTA );
    tmp1_int = SKP_DIV32_16( 1 << ( 15 + Q_OUT ), tmp1_int );
    pNLSFW_Q6[ D - 1 ] = (SKP_int)SKP_min_int( tmp1_int + tmp2_int, SKP_int16_MAX );
    SKP_assert( pNLSFW_Q6[ D - 1 ] > 0 );
}
コード例 #5
0
/* Laroia low complexity NLSF weights */
void SKP_Silk_NLSF_VQ_weights_laroia(
    SKP_int16           *pNLSFW_Q5,         /* O: Pointer to input vector weights           [D x 1]     */
    const SKP_int16     *pNLSF_Q15,         /* I: Pointer to input vector                   [D x 1]     */ 
    const SKP_int       D                   /* I: Input vector dimension (even)                         */
)
{
    SKP_int   k;
    SKP_int32 tmp1_int, tmp2_int;
    
    SKP_assert( D > 0 );
    SKP_assert( ( D & 1 ) == 0 );
    
    /* First value */
    tmp1_int = SKP_max_int( pNLSF_Q15[ 0 ], 1 );
    tmp1_int = SKP_DIV32_16( 1 << ( 15 + Q_OUT ), tmp1_int );
    tmp2_int = SKP_max_int( pNLSF_Q15[ 1 ] - pNLSF_Q15[ 0 ], 1 );
    tmp2_int = SKP_DIV32_16( 1 << ( 15 + Q_OUT ), tmp2_int );
    pNLSFW_Q5[ 0 ] = (SKP_int16)SKP_min_int( tmp1_int + tmp2_int, SKP_int16_MAX );
    SKP_assert( pNLSFW_Q5[ 0 ] > 0 );
    
    /* Main loop */
    for( k = 1; k < D - 1; k += 2 ) {
        tmp1_int = SKP_max_int( pNLSF_Q15[ k + 1 ] - pNLSF_Q15[ k ], 1 );
        tmp1_int = SKP_DIV32_16( 1 << ( 15 + Q_OUT ), tmp1_int );
        pNLSFW_Q5[ k ] = (SKP_int16)SKP_min_int( tmp1_int + tmp2_int, SKP_int16_MAX );
        SKP_assert( pNLSFW_Q5[ k ] > 0 );

        tmp2_int = SKP_max_int( pNLSF_Q15[ k + 2 ] - pNLSF_Q15[ k + 1 ], 1 );
        tmp2_int = SKP_DIV32_16( 1 << ( 15 + Q_OUT ), tmp2_int );
        pNLSFW_Q5[ k + 1 ] = (SKP_int16)SKP_min_int( tmp1_int + tmp2_int, SKP_int16_MAX );
        SKP_assert( pNLSFW_Q5[ k + 1 ] > 0 );
    }
    
    /* Last value */
    tmp1_int = SKP_max_int( ( 1 << 15 ) - pNLSF_Q15[ D - 1 ], 1 );
    tmp1_int = SKP_DIV32_16( 1 << ( 15 + Q_OUT ), tmp1_int );
    pNLSFW_Q5[ D - 1 ] = (SKP_int16)SKP_min_int( tmp1_int + tmp2_int, SKP_int16_MAX );
    SKP_assert( pNLSFW_Q5[ D - 1 ] > 0 );
}
コード例 #6
0
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;
	}
}
コード例 #7
0
/* Compute autocorrelation */
void SKP_Silk_autocorr( 
    SKP_int32        *results,                   /* O    Result (length correlationCount)            */
    SKP_int          *scale,                     /* O    Scaling of the correlation vector           */
    const SKP_int16  *inputData,                 /* I    Input data to correlate                     */
    const SKP_int    inputDataSize,              /* I    Length of input                             */
    const SKP_int    correlationCount            /* I    Number of correlation taps to compute       */
)
{
    SKP_int   i, lz, nRightShifts, corrCount;
    SKP_int64 corr64;

    corrCount = SKP_min_int( inputDataSize, correlationCount );

    /* compute energy (zero-lag correlation) */
    corr64 = SKP_Silk_inner_prod16_aligned_64( inputData, inputData, inputDataSize );

    /* deal with all-zero input data */
    corr64 += 1;

    /* number of leading zeros */
    lz = SKP_Silk_CLZ64( corr64 );

    /* scaling: number of right shifts applied to correlations */
    nRightShifts = 35 - lz;
    *scale = nRightShifts;

    if( nRightShifts <= 0 ) {
        results[ 0 ] = SKP_LSHIFT( (SKP_int32)SKP_CHECK_FIT32( corr64 ), -nRightShifts );

        /* compute remaining correlations based on int32 inner product */
          for( i = 1; i < corrCount; i++ ) {
            results[ i ] = SKP_LSHIFT( SKP_Silk_inner_prod_aligned( inputData, inputData + i, inputDataSize - i ), -nRightShifts );
        }
    } else {
        results[ 0 ] = (SKP_int32)SKP_CHECK_FIT32( SKP_RSHIFT64( corr64, nRightShifts ) );

        /* compute remaining correlations based on int64 inner product */
          for( i = 1; i < corrCount; i++ ) {
            results[ i ] =  (SKP_int32)SKP_CHECK_FIT32( SKP_RSHIFT64( SKP_Silk_inner_prod16_aligned_64( inputData, inputData + i, inputDataSize - i ), nRightShifts ) );
        }
    }
}
コード例 #8
0
/* Resamples by a factor 3/4 */
void SKP_Silk_resample_3_4(int16_t * out,	/* O:   Fs_high signal  [inLen*3/4]              */
			   int32_t * S,	/* I/O: State vector    [7+2+6]                  */
			   const int16_t * in,	/* I:   Fs_low signal   [inLen]                  */
			   int inLen	/* I:   Input length, must be a multiple of 4    */
    )
{
	int LSubFrameIn, LSubFrameOut;
	int16_t outH[3 * IN_SUBFR_LEN_RESAMPLE_3_4];
	int16_t outL[(3 * IN_SUBFR_LEN_RESAMPLE_3_4) / 2];
	int32_t scratch[(9 * IN_SUBFR_LEN_RESAMPLE_3_4) / 2];

	/* Check that input is multiple of 4 */
	assert(inLen % 4 == 0);

	while (inLen > 0) {
		LSubFrameIn = SKP_min_int(IN_SUBFR_LEN_RESAMPLE_3_4, inLen);
		LSubFrameOut = SKP_SMULWB(49152, LSubFrameIn);

		/* Upsample by a factor 3 */
		SKP_Silk_resample_3_1(outH, &S[0], in, LSubFrameIn);

		/* Downsample by a factor 2 twice */
		/* Scratch size needs to be: 3 * 2 * LSubFrameOut * sizeof( int32_t ) */
		/* I: state vector [2], scratch memory [3*len] */
		SKP_Silk_resample_1_2_coarsest(outH, &S[7], outL, scratch,
					       SKP_LSHIFT(LSubFrameOut, 1));

		/* Scratch size needs to be: 3 * LSubFrameOut * sizeof( int32_t ) */
		/* I: state vector [6], scratch memory [3*len]    */
		SKP_Silk_resample_1_2_coarse(outL, &S[9], out, scratch,
					     LSubFrameOut);

		in += LSubFrameIn;
		out += LSubFrameOut;
		inLen -= LSubFrameIn;
	}
}
コード例 #9
0
ファイル: SKP_Silk_VAD.c プロジェクト: khoapham23/silk-fix-pc
SKP_int SKP_Silk_VAD_GetSA_Q8(                      /* O    Return value, 0 if success                  */
    SKP_Silk_encoder_state      *psEncC,            /* I/O  Encoder state                               */
    const SKP_int16             pIn[]               /* I    PCM input                                   */
)
{
    SKP_int   SA_Q15, pSNR_dB_Q7, input_tilt;
    SKP_int   decimated_framelength, dec_subframe_length, dec_subframe_offset, SNR_Q7, i, b, s;
    SKP_int32 sumSquared, smooth_coef_Q16;
    SKP_int16 HPstateTmp;
    SKP_int16 X[ VAD_N_BANDS ][ MAX_FRAME_LENGTH / 2 ];
    SKP_int32 Xnrg[ VAD_N_BANDS ];
    SKP_int32 NrgToNoiseRatio_Q8[ VAD_N_BANDS ];
    SKP_int32 speech_nrg, x_tmp;
    SKP_int   ret = 0;
    SKP_Silk_VAD_state *psSilk_VAD = &psEncC->sVAD;

    /* Safety checks */
    SKP_assert( VAD_N_BANDS == 4 );
    SKP_assert( MAX_FRAME_LENGTH >= psEncC->frame_length );
    SKP_assert( psEncC->frame_length <= 512 );
    SKP_assert( psEncC->frame_length == 8 * SKP_RSHIFT( psEncC->frame_length, 3 ) );

    /***********************/
    /* Filter and Decimate */
    /***********************/
    /* 0-8 kHz to 0-4 kHz and 4-8 kHz */
    SKP_Silk_ana_filt_bank_1( pIn,          &psSilk_VAD->AnaState[  0 ], &X[ 0 ][ 0 ], &X[ 3 ][ 0 ], psEncC->frame_length );        
    
    /* 0-4 kHz to 0-2 kHz and 2-4 kHz */
    SKP_Silk_ana_filt_bank_1( &X[ 0 ][ 0 ], &psSilk_VAD->AnaState1[ 0 ], &X[ 0 ][ 0 ], &X[ 2 ][ 0 ], SKP_RSHIFT( psEncC->frame_length, 1 ) );
    
    /* 0-2 kHz to 0-1 kHz and 1-2 kHz */
    SKP_Silk_ana_filt_bank_1( &X[ 0 ][ 0 ], &psSilk_VAD->AnaState2[ 0 ], &X[ 0 ][ 0 ], &X[ 1 ][ 0 ], SKP_RSHIFT( psEncC->frame_length, 2 ) );

    /*********************************************/
    /* HP filter on lowest band (differentiator) */
    /*********************************************/
    decimated_framelength = SKP_RSHIFT( psEncC->frame_length, 3 );
    X[ 0 ][ decimated_framelength - 1 ] = SKP_RSHIFT( X[ 0 ][ decimated_framelength - 1 ], 1 );
    HPstateTmp = X[ 0 ][ decimated_framelength - 1 ];
    for( i = decimated_framelength - 1; i > 0; i-- ) {
        X[ 0 ][ i - 1 ]  = SKP_RSHIFT( X[ 0 ][ i - 1 ], 1 );
        X[ 0 ][ i ]     -= X[ 0 ][ i - 1 ];
    }
    X[ 0 ][ 0 ] -= psSilk_VAD->HPstate;
    psSilk_VAD->HPstate = HPstateTmp;

    /*************************************/
    /* Calculate the energy in each band */
    /*************************************/
    for( b = 0; b < VAD_N_BANDS; b++ ) {        
        /* Find the decimated framelength in the non-uniformly divided bands */
        decimated_framelength = SKP_RSHIFT( psEncC->frame_length, SKP_min_int( VAD_N_BANDS - b, VAD_N_BANDS - 1 ) );

        /* Split length into subframe lengths */
        dec_subframe_length = SKP_RSHIFT( decimated_framelength, VAD_INTERNAL_SUBFRAMES_LOG2 );
        dec_subframe_offset = 0;

        /* Compute energy per sub-frame */
        /* initialize with summed energy of last subframe */
        Xnrg[ b ] = psSilk_VAD->XnrgSubfr[ b ];
        for( s = 0; s < VAD_INTERNAL_SUBFRAMES; s++ ) {
            sumSquared = 0;
            for( i = 0; i < dec_subframe_length; i++ ) {
                /* The energy will be less than dec_subframe_length * ( SKP_int16_MIN / 8 ) ^ 2.            */
                /* Therefore we can accumulate with no risk of overflow (unless dec_subframe_length > 128)  */
                x_tmp = SKP_RSHIFT( X[ b ][ i + dec_subframe_offset ], 3 );
                sumSquared = SKP_SMLABB( sumSquared, x_tmp, x_tmp );

                /* Safety check */
                SKP_assert( sumSquared >= 0 );
            }

            /* Add/saturate summed energy of current subframe */
            if( s < VAD_INTERNAL_SUBFRAMES - 1 ) {
                Xnrg[ b ] = SKP_ADD_POS_SAT32( Xnrg[ b ], sumSquared );
            } else {
                /* Look-ahead subframe */
                Xnrg[ b ] = SKP_ADD_POS_SAT32( Xnrg[ b ], SKP_RSHIFT( sumSquared, 1 ) );
            }

            dec_subframe_offset += dec_subframe_length;
        }
        psSilk_VAD->XnrgSubfr[ b ] = sumSquared; 
    }

    /********************/
    /* Noise estimation */
    /********************/
    SKP_Silk_VAD_GetNoiseLevels( &Xnrg[ 0 ], psSilk_VAD );

    /***********************************************/
    /* Signal-plus-noise to noise ratio estimation */
    /***********************************************/
    sumSquared = 0;
    input_tilt = 0;
    for( b = 0; b < VAD_N_BANDS; b++ ) {
        speech_nrg = Xnrg[ b ] - psSilk_VAD->NL[ b ];
        if( speech_nrg > 0 ) {
            /* Divide, with sufficient resolution */
            if( ( Xnrg[ b ] & 0xFF800000 ) == 0 ) {
                NrgToNoiseRatio_Q8[ b ] = SKP_DIV32( SKP_LSHIFT( Xnrg[ b ], 8 ), psSilk_VAD->NL[ b ] + 1 );
            } else {
                NrgToNoiseRatio_Q8[ b ] = SKP_DIV32( Xnrg[ b ], SKP_RSHIFT( psSilk_VAD->NL[ b ], 8 ) + 1 );
            }

            /* Convert to log domain */
            SNR_Q7 = SKP_Silk_lin2log( NrgToNoiseRatio_Q8[ b ] ) - 8 * 128;

            /* Sum-of-squares */
            sumSquared = SKP_SMLABB( sumSquared, SNR_Q7, SNR_Q7 );          /* Q14 */

            /* Tilt measure */
            if( speech_nrg < ( 1 << 20 ) ) {
                /* Scale down SNR value for small subband speech energies */
                SNR_Q7 = SKP_SMULWB( SKP_LSHIFT( SKP_Silk_SQRT_APPROX( speech_nrg ), 6 ), SNR_Q7 );
            }
            input_tilt = SKP_SMLAWB( input_tilt, tiltWeights[ b ], SNR_Q7 );
        } else {
            NrgToNoiseRatio_Q8[ b ] = 256;
        }
    }

    /* Mean-of-squares */
    sumSquared = SKP_DIV32_16( sumSquared, VAD_N_BANDS ); /* Q14 */

    /* Root-mean-square approximation, scale to dBs, and write to output pointer */
    pSNR_dB_Q7 = ( SKP_int16 )( 3 * SKP_Silk_SQRT_APPROX( sumSquared ) ); /* Q7 */

    /*********************************/
    /* Speech Probability Estimation */
    /*********************************/
    SA_Q15 = SKP_Silk_sigm_Q15( SKP_SMULWB( VAD_SNR_FACTOR_Q16, pSNR_dB_Q7 ) - VAD_NEGATIVE_OFFSET_Q5 );

    /**************************/
    /* Frequency Tilt Measure */
    /**************************/
    psEncC->input_tilt_Q15 = SKP_LSHIFT( SKP_Silk_sigm_Q15( input_tilt ) - 16384, 1 );

    /**************************************************/
    /* Scale the sigmoid output based on power levels */
    /**************************************************/
    speech_nrg = 0;
    for( b = 0; b < VAD_N_BANDS; b++ ) {
        /* Accumulate signal-without-noise energies, higher frequency bands have more weight */
        speech_nrg += ( b + 1 ) * SKP_RSHIFT( Xnrg[ b ] - psSilk_VAD->NL[ b ], 4 );
    }

    /* Power scaling */
    if( speech_nrg <= 0 ) {
        SA_Q15 = SKP_RSHIFT( SA_Q15, 1 ); 
    } else if( speech_nrg < 32768 ) {
        if( psEncC->frame_length == 10 * psEncC->fs_kHz ) {
            speech_nrg = SKP_LSHIFT_SAT32( speech_nrg, 16 );
        } else {
            speech_nrg = SKP_LSHIFT_SAT32( speech_nrg, 15 );
        }

        /* square-root */
        speech_nrg = SKP_Silk_SQRT_APPROX( speech_nrg );
        SA_Q15 = SKP_SMULWB( 32768 + speech_nrg, SA_Q15 ); 
    }

    /* Copy the resulting speech activity in Q8 */
    psEncC->speech_activity_Q8 = SKP_min_int( SKP_RSHIFT( SA_Q15, 7 ), SKP_uint8_MAX );

    /***********************************/
    /* Energy Level and SNR estimation */
    /***********************************/
    /* Smoothing coefficient */
    smooth_coef_Q16 = SKP_SMULWB( VAD_SNR_SMOOTH_COEF_Q18, SKP_SMULWB( SA_Q15, SA_Q15 ) );
    
    if( psEncC->frame_length == 10 * psEncC->fs_kHz ) {
        smooth_coef_Q16 >>= 1;
    }
コード例 #10
0
/* NLSF stabilizer, for a single input data vector */
void SKP_Silk_NLSF_stabilize(
          SKP_int    *NLSF_Q15,            /* I/O:  Unstable/stabilized normalized LSF vector in Q15 [L]                    */
    const SKP_int    *NDeltaMin_Q15,       /* I:    Normalized delta min vector in Q15, NDeltaMin_Q15[L] must be >= 1 [L+1] */
    const SKP_int     L                    /* I:    Number of NLSF parameters in the input vector                           */
)
{
    SKP_int        center_freq_Q15, diff_Q15, min_center_Q15, max_center_Q15;
    SKP_int32    min_diff_Q15;
    SKP_int        loops;
    SKP_int        i, I=0, k;

    /* This is necessary to ensure an output within range of a SKP_int16 */
    SKP_assert( NDeltaMin_Q15[L] >= 1 );

    for( loops = 0; loops < MAX_LOOPS; loops++ ) {
        /**************************/
        /* Find smallest distance */
        /**************************/
        /* First element */
        min_diff_Q15 = NLSF_Q15[0] - NDeltaMin_Q15[0];
        I = 0;
        /* Middle elements */
        for( i = 1; i <= L-1; i++ ) {
            diff_Q15 = NLSF_Q15[i] - ( NLSF_Q15[i-1] + NDeltaMin_Q15[i] );
            if( diff_Q15 < min_diff_Q15 ) {
                min_diff_Q15 = diff_Q15;
                I = i;
            }
        }
        /* Last element */
        diff_Q15 = (1<<15) - ( NLSF_Q15[L-1] + NDeltaMin_Q15[L] );
        if( diff_Q15 < min_diff_Q15 ) {
            min_diff_Q15 = diff_Q15;
            I = L;
        }

        /***************************************************/
        /* Now check if the smallest distance non-negative */
        /***************************************************/
        if (min_diff_Q15 >= 0) {
            return;
        }

        if( I == 0 ) {
            /* Move away from lower limit */
            NLSF_Q15[0] = NDeltaMin_Q15[0];
        
        } else if( I == L) {
            /* Move away from higher limit */
            NLSF_Q15[L-1] = (1<<15) - NDeltaMin_Q15[L];
        
        } else {
            /* Find the lower extreme for the location of the current center frequency */ 
            min_center_Q15 = 0;
            for( k = 0; k < I; k++ ) {
                min_center_Q15 += NDeltaMin_Q15[k];
            }
            min_center_Q15 += SKP_RSHIFT( NDeltaMin_Q15[I], 1 );

            /* Find the upper extreme for the location of the current center frequency */
            max_center_Q15 = (1<<15);
            for( k = L; k > I; k-- ) {
                max_center_Q15 -= NDeltaMin_Q15[k];
            }
            max_center_Q15 -= ( NDeltaMin_Q15[I] - SKP_RSHIFT( NDeltaMin_Q15[I], 1 ) );

            /* Move apart, sorted by value, keeping the same center frequency */
            center_freq_Q15 = SKP_LIMIT( SKP_RSHIFT_ROUND( (SKP_int32)NLSF_Q15[I-1] + (SKP_int32)NLSF_Q15[I], 1 ),
                min_center_Q15, max_center_Q15 );
            NLSF_Q15[I-1] = center_freq_Q15 - SKP_RSHIFT( NDeltaMin_Q15[I], 1 );
            NLSF_Q15[I] = NLSF_Q15[I-1] + NDeltaMin_Q15[I];
        }
    }

    /* Safe and simple fall back method, which is less ideal than the above */
    if( loops == MAX_LOOPS )
    {
        /* Insertion sort (fast for already almost sorted arrays):   */
        /* Best case:  O(n)   for an already sorted array            */
        /* Worst case: O(n^2) for an inversely sorted array          */
        SKP_Silk_insertion_sort_increasing_all_values(&NLSF_Q15[0], L);
            
        /* First NLSF should be no less than NDeltaMin[0] */
        NLSF_Q15[0] = SKP_max_int( NLSF_Q15[0], NDeltaMin_Q15[0] );
        
        /* Keep delta_min distance between the NLSFs */
        for( i = 1; i < L; i++ )
            NLSF_Q15[i] = SKP_max_int( NLSF_Q15[i], NLSF_Q15[i-1] + NDeltaMin_Q15[i] );

        /* Last NLSF should be no higher than 1 - NDeltaMin[L] */
        NLSF_Q15[L-1] = SKP_min_int( NLSF_Q15[L-1], (1<<15) - NDeltaMin_Q15[L] );

        /* Keep NDeltaMin distance between the NLSFs */
        for( i = L-2; i >= 0; i-- ) 
            NLSF_Q15[i] = SKP_min_int( NLSF_Q15[i], NLSF_Q15[i+1] - NDeltaMin_Q15[i+1] );
    }
}
コード例 #11
0
ファイル: SKP_Silk_PLC.c プロジェクト: Carymax1988/Android
void SKP_Silk_PLC_conceal(
    SKP_Silk_decoder_state      *psDec,             /* I/O Decoder state */
    SKP_Silk_decoder_control    *psDecCtrl,         /* I/O Decoder control */
    SKP_int16                   signal[],           /* O concealed signal */
    SKP_int                     length              /* I length of residual */
)
{
    SKP_int   i, j, k;
    SKP_int16 *B_Q14, exc_buf[ MAX_FRAME_LENGTH ], *exc_buf_ptr;
    SKP_int16 rand_scale_Q14, A_Q12_tmp[ MAX_LPC_ORDER ];
    SKP_int32 rand_seed, harm_Gain_Q15, rand_Gain_Q15;
    SKP_int   lag, idx, shift1, shift2;
    SKP_int32 energy1, energy2, *rand_ptr, *pred_lag_ptr, Atmp;
    SKP_int32 sig_Q10[ MAX_FRAME_LENGTH ], *sig_Q10_ptr, LPC_exc_Q10, LPC_pred_Q10,  LTP_pred_Q14;
    SKP_Silk_PLC_struct *psPLC;

    psPLC = &psDec->sPLC;

    /* Update LTP buffer */
    SKP_memcpy( psDec->sLTP_Q16, &psDec->sLTP_Q16[ psDec->frame_length ], psDec->frame_length * sizeof( SKP_int32 ) );

    /* LPC concealment. Apply BWE to previous LPC */
    SKP_Silk_bwexpander( psPLC->prevLPC_Q12, psDec->LPC_order, BWE_COEF_Q16 );

    /* Find random noise component */
    /* Scale previous excitation signal */
    exc_buf_ptr = exc_buf;
    for( k = ( NB_SUBFR >> 1 ); k < NB_SUBFR; k++ ) {
        for( i = 0; i < psDec->subfr_length; i++ ) {
            exc_buf_ptr[ i ] = ( SKP_int16 )SKP_RSHIFT( 
                SKP_SMULWW( psDec->exc_Q10[ i + k * psDec->subfr_length ], psPLC->prevGain_Q16[ k ] ), 10 );
        }
        exc_buf_ptr += psDec->subfr_length;
    }
    /* Find the subframe with lowest energy of the last two and use that as random noise generator */ 
    SKP_Silk_sum_sqr_shift( &energy1, &shift1, exc_buf,                         psDec->subfr_length );
    SKP_Silk_sum_sqr_shift( &energy2, &shift2, &exc_buf[ psDec->subfr_length ], psDec->subfr_length );
        
    if( SKP_RSHIFT( energy1, shift2 ) < SKP_RSHIFT( energy1, shift2 ) ) {
        /* First sub-frame has lowest energy */
        rand_ptr = &psDec->exc_Q10[ SKP_max_int( 0, 3 * psDec->subfr_length - RAND_BUF_SIZE ) ];
    } else {
        /* Second sub-frame has lowest energy */
        rand_ptr = &psDec->exc_Q10[ SKP_max_int( 0, psDec->frame_length - RAND_BUF_SIZE ) ];
    }

    /* Setup Gain to random noise component */ 
    B_Q14          = psPLC->LTPCoef_Q14;
    rand_scale_Q14 = psPLC->randScale_Q14;

    /* Setup attenuation gains */
    harm_Gain_Q15 = HARM_ATT_Q15[ SKP_min_int( NB_ATT - 1, psDec->lossCnt ) ];
    if( psDec->prev_sigtype == SIG_TYPE_VOICED ) {
        rand_Gain_Q15 = PLC_RAND_ATTENUATE_V_Q15[  SKP_min_int( NB_ATT - 1, psDec->lossCnt ) ];
    } else {
        rand_Gain_Q15 = PLC_RAND_ATTENUATE_UV_Q15[ SKP_min_int( NB_ATT - 1, psDec->lossCnt ) ];
    }

    /* First Lost frame */
    if( psDec->lossCnt == 0 ) {
        rand_scale_Q14 = (1 << 14 );
    
        /* Reduce random noise Gain for voiced frames */
        if( psDec->prev_sigtype == SIG_TYPE_VOICED ) {
            for( i = 0; i < LTP_ORDER; i++ ) {
                rand_scale_Q14 -= B_Q14[ i ];
            }
            rand_scale_Q14 = SKP_max_16( 3277, rand_scale_Q14 ); /* 0.2 */
            rand_scale_Q14 = ( SKP_int16 )SKP_RSHIFT( SKP_SMULBB( rand_scale_Q14, psPLC->prevLTP_scale_Q14 ), 14 );
        }

        /* Reduce random noise for unvoiced frames with high LPC gain */
        if( psDec->prev_sigtype == SIG_TYPE_UNVOICED ) {
            SKP_int32 invGain_Q30, down_scale_Q30;
            
            SKP_Silk_LPC_inverse_pred_gain( &invGain_Q30, psPLC->prevLPC_Q12, psDec->LPC_order );
            
            down_scale_Q30 = SKP_min_32( SKP_RSHIFT( ( 1 << 30 ), LOG2_INV_LPC_GAIN_HIGH_THRES ), invGain_Q30 );
            down_scale_Q30 = SKP_max_32( SKP_RSHIFT( ( 1 << 30 ), LOG2_INV_LPC_GAIN_LOW_THRES ), down_scale_Q30 );
            down_scale_Q30 = SKP_LSHIFT( down_scale_Q30, LOG2_INV_LPC_GAIN_HIGH_THRES );
            
            rand_Gain_Q15 = SKP_RSHIFT( SKP_SMULWB( down_scale_Q30, rand_Gain_Q15 ), 14 );
        }
    }

    rand_seed           = psPLC->rand_seed;
    lag                 = SKP_RSHIFT_ROUND( psPLC->pitchL_Q8, 8 );
    psDec->sLTP_buf_idx = psDec->frame_length;

    /***************************/
    /* LTP synthesis filtering */
    /***************************/
    sig_Q10_ptr = sig_Q10;
    for( k = 0; k < NB_SUBFR; k++ ) {
        /* Setup pointer */
        pred_lag_ptr = &psDec->sLTP_Q16[ psDec->sLTP_buf_idx - lag + LTP_ORDER / 2 ];
        for( i = 0; i < psDec->subfr_length; i++ ) {
            rand_seed = SKP_RAND( rand_seed );
            idx = SKP_RSHIFT( rand_seed, 25 ) & RAND_BUF_MASK;

            /* Unrolled loop */
            LTP_pred_Q14 = SKP_SMULWB(               pred_lag_ptr[  0 ], B_Q14[ 0 ] );
            LTP_pred_Q14 = SKP_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ -1 ], B_Q14[ 1 ] );
            LTP_pred_Q14 = SKP_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ -2 ], B_Q14[ 2 ] );
            LTP_pred_Q14 = SKP_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ -3 ], B_Q14[ 3 ] );
            LTP_pred_Q14 = SKP_SMLAWB( LTP_pred_Q14, pred_lag_ptr[ -4 ], B_Q14[ 4 ] );
            pred_lag_ptr++;
            
            /* Generate LPC residual */
            LPC_exc_Q10 = SKP_LSHIFT( SKP_SMULWB( rand_ptr[ idx ], rand_scale_Q14 ), 2 ); /* Random noise part */
            LPC_exc_Q10 = SKP_ADD32( LPC_exc_Q10, SKP_RSHIFT_ROUND( LTP_pred_Q14, 4 ) );  /* Harmonic part */
            
            /* Update states */
            psDec->sLTP_Q16[ psDec->sLTP_buf_idx ] = SKP_LSHIFT( LPC_exc_Q10, 6 );
            psDec->sLTP_buf_idx++;
                
            /* Save LPC residual */
            sig_Q10_ptr[ i ] = LPC_exc_Q10;
        }
        sig_Q10_ptr += psDec->subfr_length;
        /* Gradually reduce LTP gain */
        for( j = 0; j < LTP_ORDER; j++ ) {
            B_Q14[ j ] = SKP_RSHIFT( SKP_SMULBB( harm_Gain_Q15, B_Q14[ j ] ), 15 );
        }
        /* Gradually reduce excitation gain */
        rand_scale_Q14 = SKP_RSHIFT( SKP_SMULBB( rand_scale_Q14, rand_Gain_Q15 ), 15 );

        /* Slowly increase pitch lag */
        psPLC->pitchL_Q8 += SKP_SMULWB( psPLC->pitchL_Q8, PITCH_DRIFT_FAC_Q16 );
        psPLC->pitchL_Q8 = SKP_min_32( psPLC->pitchL_Q8, SKP_LSHIFT( SKP_SMULBB( MAX_PITCH_LAG_MS, psDec->fs_kHz ), 8 ) );
        lag = SKP_RSHIFT_ROUND( psPLC->pitchL_Q8, 8 );
    }

    /***************************/
    /* LPC synthesis filtering */
    /***************************/
    sig_Q10_ptr = sig_Q10;
    /* Preload LPC coeficients to array on stack. Gives small performance gain */
    SKP_memcpy( A_Q12_tmp, psPLC->prevLPC_Q12, psDec->LPC_order * sizeof( SKP_int16 ) );
    SKP_assert( psDec->LPC_order >= 10 ); /* check that unrolling works */
    for( k = 0; k < NB_SUBFR; k++ ) {
        for( i = 0; i < psDec->subfr_length; i++ ){
            /* unrolled */
            Atmp = *( ( SKP_int32* )&A_Q12_tmp[ 0 ] );    /* read two coefficients at once */
            LPC_pred_Q10 = SKP_SMULWB(               psDec->sLPC_Q14[ MAX_LPC_ORDER + i -  1 ], Atmp );
            LPC_pred_Q10 = SKP_SMLAWT( LPC_pred_Q10, psDec->sLPC_Q14[ MAX_LPC_ORDER + i -  2 ], Atmp );
            Atmp = *( ( SKP_int32* )&A_Q12_tmp[ 2 ] );
            LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psDec->sLPC_Q14[ MAX_LPC_ORDER + i -  3 ], Atmp );
            LPC_pred_Q10 = SKP_SMLAWT( LPC_pred_Q10, psDec->sLPC_Q14[ MAX_LPC_ORDER + i -  4 ], Atmp );
            Atmp = *( ( SKP_int32* )&A_Q12_tmp[ 4 ] );
            LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psDec->sLPC_Q14[ MAX_LPC_ORDER + i -  5 ], Atmp );
            LPC_pred_Q10 = SKP_SMLAWT( LPC_pred_Q10, psDec->sLPC_Q14[ MAX_LPC_ORDER + i -  6 ], Atmp );
            Atmp = *( ( SKP_int32* )&A_Q12_tmp[ 6 ] );
            LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psDec->sLPC_Q14[ MAX_LPC_ORDER + i -  7 ], Atmp );
            LPC_pred_Q10 = SKP_SMLAWT( LPC_pred_Q10, psDec->sLPC_Q14[ MAX_LPC_ORDER + i -  8 ], Atmp );
            Atmp = *( ( SKP_int32* )&A_Q12_tmp[ 8 ] );
            LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psDec->sLPC_Q14[ MAX_LPC_ORDER + i -  9 ], Atmp );
            LPC_pred_Q10 = SKP_SMLAWT( LPC_pred_Q10, psDec->sLPC_Q14[ MAX_LPC_ORDER + i - 10 ], Atmp );
            for( j = 10 ; j < psDec->LPC_order ; j+=2 ) {
                Atmp = *( ( SKP_int32* )&A_Q12_tmp[ j ] );
                LPC_pred_Q10 = SKP_SMLAWB( LPC_pred_Q10, psDec->sLPC_Q14[ MAX_LPC_ORDER + i -  1 - j ], Atmp );
                LPC_pred_Q10 = SKP_SMLAWT( LPC_pred_Q10, psDec->sLPC_Q14[ MAX_LPC_ORDER + i -  2 - j ], Atmp );
            }

            /* Add prediction to LPC residual */
            sig_Q10_ptr[ i ] = SKP_ADD32( sig_Q10_ptr[ i ], LPC_pred_Q10 );
                
            /* Update states */
            psDec->sLPC_Q14[ MAX_LPC_ORDER + i ] = SKP_LSHIFT( sig_Q10_ptr[ i ], 4 );
        }
        sig_Q10_ptr += psDec->subfr_length;
        /* Update LPC filter state */
        SKP_memcpy( psDec->sLPC_Q14, &psDec->sLPC_Q14[ psDec->subfr_length ], MAX_LPC_ORDER * sizeof( SKP_int32 ) );
    }

    /* Scale with Gain */
    for( i = 0; i < psDec->frame_length; i++ ) {
        signal[ i ] = ( SKP_int16 )SKP_SAT16( SKP_RSHIFT_ROUND( SKP_SMULWW( sig_Q10[ i ], psPLC->prevGain_Q16[ NB_SUBFR - 1 ] ), 10 ) );
    }

    /**************************************/
    /* Update states                      */
    /**************************************/
    psPLC->rand_seed     = rand_seed;
    psPLC->randScale_Q14 = rand_scale_Q14;
    for( i = 0; i < NB_SUBFR; i++ ) {
        psDecCtrl->pitchL[ i ] = lag;
    }
}
コード例 #12
0
/* Downsamples by a factor 3 */
void SKP_Silk_resample_1_3(
    SKP_int16            *out,       /* O:   Fs_low signal  [inLen/3]                */
    SKP_int32            *S,         /* I/O: State vector   [7]                      */
    const SKP_int16      *in,        /* I:   Fs_high signal [inLen]                  */
    const SKP_int32      inLen       /* I:   Input length, must be a multiple of 3   */
)
{
    SKP_int      k, outLen, LSubFrameIn, LSubFrameOut;
    SKP_int32    out_tmp, limit = 102258000; // (102258000 + 1560) * 21 * 2^(-16) = 32767.5
    SKP_int32    scratch0[ 3 * OUT_SUBFR_LEN ];
    SKP_int32    scratch10[ OUT_SUBFR_LEN ], scratch11[ OUT_SUBFR_LEN ], scratch12[ OUT_SUBFR_LEN ];
    /* 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 };

    /* Check that input is multiple of 3 */
    SKP_assert( inLen % 3 == 0 );

    outLen = SKP_DIV32_16( inLen, 3 );
    while( outLen > 0 ) {
        LSubFrameOut = SKP_min_int( OUT_SUBFR_LEN, outLen );
        LSubFrameIn  = SKP_SMULBB( 3, LSubFrameOut );

        /* Low-pass filter, Q15 -> Q25 */
        SKP_Silk_lowpass_short( in, S, scratch0, LSubFrameIn );

        /* De-interleave three allpass inputs */
        for( k = 0; k < LSubFrameOut; k++ ) {
            scratch10[ k ] = scratch0[ 3 * k     ];
            scratch11[ k ] = scratch0[ 3 * k + 1 ];
            scratch12[ k ] = scratch0[ 3 * k + 2 ];
        }

        /* Allpass filters */
        SKP_Silk_allpass_int( scratch10, S + 1, A32[ 0 ], scratch0,  LSubFrameOut );
        SKP_Silk_allpass_int( scratch0,  S + 2, A32[ 1 ], scratch10, LSubFrameOut );

        SKP_Silk_allpass_int( scratch11, S + 3, A31[ 0 ], scratch0,  LSubFrameOut );
        SKP_Silk_allpass_int( scratch0,  S + 4, A31[ 1 ], scratch11, LSubFrameOut );

        SKP_Silk_allpass_int( scratch12, S + 5, A30[ 0 ], scratch0,  LSubFrameOut );
        SKP_Silk_allpass_int( scratch0,  S + 6, A30[ 1 ], scratch12, LSubFrameOut );

        /* Add three allpass outputs */
        for( k = 0; k < LSubFrameOut; k++ ) {
            out_tmp = scratch10[ k ] + scratch11[ k ] + scratch12[ k ];
            if( out_tmp - limit > 0 ) {
                out[ k ] = SKP_int16_MAX;
            } else if( out_tmp + limit < 0 ) {
                out[ k ] = SKP_int16_MIN;
            } else {
                out[ k ] = (SKP_int16) SKP_SMULWB( out_tmp + 1560, 21 );
            }
        }

        in     += LSubFrameIn;
        out    += LSubFrameOut;
        outLen -= LSubFrameOut;
    }
}
コード例 #13
0
SKP_int SKP_Silk_SDK_Encode( 
    void                                *encState,      /* I/O: State                                           */
    SKP_Silk_EncodeControlStruct        *encControl,    /* I:   Control structure                               */
    const SKP_int16                     *samplesIn,     /* I:   Speech sample input vector                      */
    SKP_int                             nSamplesIn,     /* I:   Number of samples in input vector               */
    ec_enc                              *psRangeEnc,    /* I/O  Compressor data structure                       */
    SKP_int32                           *nBytesOut,     /* I/O: Number of bytes in payload (input: Max bytes)   */
    const SKP_int                       prefillFlag     /* I:   Flag to indicate prefilling buffers no coding   */
)
{
    SKP_int   tmp_payloadSize_ms, tmp_complexity, ret = 0;
    SKP_int   nSamplesToBuffer, nBlocksOf10ms, nSamplesFromInput = 0;
    SKP_Silk_encoder_state_Fxx *psEnc = ( SKP_Silk_encoder_state_Fxx* )encState;

    ret = process_enc_control_struct( psEnc, encControl );

    nBlocksOf10ms = SKP_DIV32( 100 * nSamplesIn, psEnc->sCmn.API_fs_Hz );
    if( prefillFlag ) {
        /* Only accept input length of 10 ms */
        if( nBlocksOf10ms != 1 ) {
            ret = SKP_SILK_ENC_INPUT_INVALID_NO_OF_SAMPLES;
            SKP_assert( 0 );
            return( ret );
        }
        /* Reset Encoder */
        if( ret = SKP_Silk_init_encoder_Fxx( psEnc ) ) {
            SKP_assert( 0 );
        }
        tmp_payloadSize_ms = encControl->payloadSize_ms;
        encControl->payloadSize_ms = 10;
        tmp_complexity = encControl->complexity;
        encControl->complexity = 0;
        ret = process_enc_control_struct( psEnc, encControl );
        psEnc->sCmn.prefillFlag = 1;
    } else {
        /* Only accept input lengths that are a multiple of 10 ms */
        if( nBlocksOf10ms * psEnc->sCmn.API_fs_Hz != 100 * nSamplesIn || nSamplesIn < 0 ) {
            ret = SKP_SILK_ENC_INPUT_INVALID_NO_OF_SAMPLES;
            SKP_assert( 0 );
            return( ret );
        }
        /* Make sure no more than one packet can be produced */
        if( 1000 * (SKP_int32)nSamplesIn > psEnc->sCmn.PacketSize_ms * psEnc->sCmn.API_fs_Hz ) {
            ret = SKP_SILK_ENC_INPUT_INVALID_NO_OF_SAMPLES;
            SKP_assert( 0 );
            return( ret );
        }
    }

    /* Input buffering/resampling and encoding */
    while( 1 ) {
        nSamplesToBuffer = psEnc->sCmn.frame_length - psEnc->sCmn.inputBufIx;
        if( psEnc->sCmn.API_fs_Hz == SKP_SMULBB( 1000, psEnc->sCmn.fs_kHz ) ) { 
            nSamplesToBuffer  = SKP_min_int( nSamplesToBuffer, nSamplesIn );
            nSamplesFromInput = nSamplesToBuffer;
            /* Copy to buffer */
            SKP_memcpy( &psEnc->sCmn.inputBuf[ psEnc->sCmn.inputBufIx ], samplesIn, nSamplesFromInput * sizeof( SKP_int16 ) );
        } else {  
            nSamplesToBuffer  = SKP_min( nSamplesToBuffer, 10 * nBlocksOf10ms * psEnc->sCmn.fs_kHz );
            nSamplesFromInput = SKP_DIV32_16( nSamplesToBuffer * psEnc->sCmn.API_fs_Hz, psEnc->sCmn.fs_kHz * 1000 );
            /* Resample and write to buffer */
            ret += SKP_Silk_resampler( &psEnc->sCmn.resampler_state, &psEnc->sCmn.inputBuf[ psEnc->sCmn.inputBufIx ], samplesIn, nSamplesFromInput );
        } 
        samplesIn              += nSamplesFromInput;
        nSamplesIn             -= nSamplesFromInput;
        psEnc->sCmn.inputBufIx += nSamplesToBuffer;

        /* Silk encoder */
        if( psEnc->sCmn.inputBufIx >= psEnc->sCmn.frame_length ) {
            SKP_assert( psEnc->sCmn.inputBufIx == psEnc->sCmn.frame_length );

            /* Enough data in input buffer, so encode */
            if( ( ret = SKP_Silk_encode_frame_Fxx( psEnc, nBytesOut, psRangeEnc ) ) != 0 ) {
                SKP_assert( 0 );
            }
            psEnc->sCmn.inputBufIx = 0;
            psEnc->sCmn.controlled_since_last_payload = 0;

            if( nSamplesIn == 0 ) {
                break;
            }
        } else {
            break;
        }
    }

    if( prefillFlag ) {
        encControl->payloadSize_ms = tmp_payloadSize_ms;
        encControl->complexity = tmp_complexity;
        ret = process_enc_control_struct( psEnc, encControl );
        psEnc->sCmn.prefillFlag = 0;
    }

    return ret;
}
コード例 #14
0
opus_int silk_setup_complexity(
    silk_encoder_state              *psEncC,            /* I/O                      */
    opus_int                         Complexity          /* I                        */
)
{
    opus_int ret = 0;

    /* Set encoding complexity */
    SKP_assert( Complexity >= 0 && Complexity <= 10 );
    if( Complexity < 2 ) {
        psEncC->pitchEstimationComplexity       = SILK_PE_MIN_COMPLEX;
        psEncC->pitchEstimationThreshold_Q16    = SILK_FIX_CONST( 0.8, 16 );
        psEncC->pitchEstimationLPCOrder         = 6;
        psEncC->shapingLPCOrder                 = 8;
        psEncC->la_shape                        = 3 * psEncC->fs_kHz;
        psEncC->nStatesDelayedDecision          = 1;
        psEncC->useInterpolatedNLSFs            = 0;
        psEncC->LTPQuantLowComplexity           = 1;
        psEncC->NLSF_MSVQ_Survivors             = 2;
        psEncC->warping_Q16                     = 0;
    } else if( Complexity < 4 ) {
        psEncC->pitchEstimationComplexity       = SILK_PE_MID_COMPLEX;
        psEncC->pitchEstimationThreshold_Q16    = SILK_FIX_CONST( 0.76, 16 );
        psEncC->pitchEstimationLPCOrder         = 8;
        psEncC->shapingLPCOrder                 = 10;
        psEncC->la_shape                        = 5 * psEncC->fs_kHz;
        psEncC->nStatesDelayedDecision          = 1;
        psEncC->useInterpolatedNLSFs            = 1;
        psEncC->LTPQuantLowComplexity           = 0;
        psEncC->NLSF_MSVQ_Survivors             = 4;
        psEncC->warping_Q16                     = 0;
    } else if( Complexity < 6 ) {
        psEncC->pitchEstimationComplexity       = SILK_PE_MID_COMPLEX;
        psEncC->pitchEstimationThreshold_Q16    = SILK_FIX_CONST( 0.74, 16 );
        psEncC->pitchEstimationLPCOrder         = 10;
        psEncC->shapingLPCOrder                 = 12;
        psEncC->la_shape                        = 5 * psEncC->fs_kHz;
        psEncC->nStatesDelayedDecision          = 2;
        psEncC->useInterpolatedNLSFs            = 0;
        psEncC->LTPQuantLowComplexity           = 0;
        psEncC->NLSF_MSVQ_Survivors             = 8;
        psEncC->warping_Q16                     = psEncC->fs_kHz * SILK_FIX_CONST( WARPING_MULTIPLIER, 16 );
    } else if( Complexity < 8 ) {
        psEncC->pitchEstimationComplexity       = SILK_PE_MID_COMPLEX;
        psEncC->pitchEstimationThreshold_Q16    = SILK_FIX_CONST( 0.72, 16 );
        psEncC->pitchEstimationLPCOrder         = 12;
        psEncC->shapingLPCOrder                 = 14;
        psEncC->la_shape                        = 5 * psEncC->fs_kHz;
        psEncC->nStatesDelayedDecision          = 3;
        psEncC->useInterpolatedNLSFs            = 0;
        psEncC->LTPQuantLowComplexity           = 0;
        psEncC->NLSF_MSVQ_Survivors             = 16;
        psEncC->warping_Q16                     = psEncC->fs_kHz * SILK_FIX_CONST( WARPING_MULTIPLIER, 16 );
    } else {
        psEncC->pitchEstimationComplexity       = SILK_PE_MAX_COMPLEX;
        psEncC->pitchEstimationThreshold_Q16    = SILK_FIX_CONST( 0.7, 16 );
        psEncC->pitchEstimationLPCOrder         = 16;
        psEncC->shapingLPCOrder                 = 16;
        psEncC->la_shape                        = 5 * psEncC->fs_kHz;
        psEncC->nStatesDelayedDecision          = MAX_DEL_DEC_STATES;
        psEncC->useInterpolatedNLSFs            = 1;
        psEncC->LTPQuantLowComplexity           = 0;
        psEncC->NLSF_MSVQ_Survivors             = 32;
        psEncC->warping_Q16                     = psEncC->fs_kHz * SILK_FIX_CONST( WARPING_MULTIPLIER, 16 );
    }

    /* Do not allow higher pitch estimation LPC order than predict LPC order */
    psEncC->pitchEstimationLPCOrder = SKP_min_int( psEncC->pitchEstimationLPCOrder, psEncC->predictLPCOrder );
    psEncC->shapeWinLength          = SUB_FRAME_LENGTH_MS * psEncC->fs_kHz + 2 * psEncC->la_shape;
    psEncC->Complexity              = Complexity;

    SKP_assert( psEncC->pitchEstimationLPCOrder <= MAX_FIND_PITCH_LPC_ORDER );
    SKP_assert( psEncC->shapingLPCOrder         <= MAX_SHAPE_LPC_ORDER      );
    SKP_assert( psEncC->nStatesDelayedDecision  <= MAX_DEL_DEC_STATES       );
    SKP_assert( psEncC->warping_Q16             <= 32767                    );
    SKP_assert( psEncC->la_shape                <= LA_SHAPE_MAX             );
    SKP_assert( psEncC->shapeWinLength          <= SHAPE_LPC_WIN_MAX        );
    SKP_assert( psEncC->NLSF_MSVQ_Survivors     <= NLSF_VQ_MAX_SURVIVORS    );

    return ret;
}