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;
	}
}
SKP_int SKP_Silk_decode_frame(
    SKP_Silk_decoder_state          *psDec,             /* I/O  Pointer to Silk decoder state               */
    SKP_int16                       pOut[],             /* O    Pointer to output speech frame              */
    SKP_int16                       *pN,                /* O    Pointer to size of output frame             */
    const SKP_uint8                 pCode[],            /* I    Pointer to payload                          */
    const SKP_int                   nBytes,             /* I    Payload length                              */
    SKP_int                         action,             /* I    Action from Jitter Buffer                   */
    SKP_int                         *decBytes           /* O    Used bytes to decode this frame             */
)
{
    SKP_Silk_decoder_control sDecCtrl;
    SKP_int         L, fs_Khz_old, ret = 0;
    SKP_int         Pulses[ MAX_FRAME_LENGTH ];


    L = psDec->frame_length;
    sDecCtrl.LTP_scale_Q14 = 0;
    
    /* Safety checks */
    SKP_assert( L > 0 && L <= MAX_FRAME_LENGTH );

    /********************************************/
    /* Decode Frame if packet is not lost  */
    /********************************************/
    *decBytes = 0;
    if( action == 0 ) {
        /********************************************/
        /* Initialize arithmetic coder              */
        /********************************************/
        fs_Khz_old    = psDec->fs_kHz;
        if( psDec->nFramesDecoded == 0 ) {
            /* Initialize range decoder state */
            SKP_Silk_range_dec_init( &psDec->sRC, pCode, nBytes );
        }

        /********************************************/
        /* Decode parameters and pulse signal       */
        /********************************************/
        SKP_Silk_decode_parameters( psDec, &sDecCtrl, Pulses, 1 );


        if( psDec->sRC.error ) {
            psDec->nBytesLeft = 0;

            action              = 1; /* PLC operation */
            /* revert fs if changed in decode_parameters */
            SKP_Silk_decoder_set_fs( psDec, fs_Khz_old );

            /* Avoid crashing */
            *decBytes = psDec->sRC.bufferLength;

            if( psDec->sRC.error == RANGE_CODER_DEC_PAYLOAD_TOO_LONG ) {
                ret = SKP_SILK_DEC_PAYLOAD_TOO_LARGE;
            } else {
                ret = SKP_SILK_DEC_PAYLOAD_ERROR;
            }
        } else {
            *decBytes = psDec->sRC.bufferLength - psDec->nBytesLeft;
            psDec->nFramesDecoded++;
        
            /* Update lengths. Sampling frequency could have changed */
            L = psDec->frame_length;

            /********************************************************/
            /* Run inverse NSQ                                      */
            /********************************************************/
            SKP_Silk_decode_core( psDec, &sDecCtrl, pOut, Pulses );

            /********************************************************/
            /* Update PLC state                                     */
            /********************************************************/
            SKP_Silk_PLC( psDec, &sDecCtrl, pOut, L, action );

            psDec->lossCnt = 0;
            psDec->prev_sigtype = sDecCtrl.sigtype;

            /* A frame has been decoded without errors */
            psDec->first_frame_after_reset = 0;
        }
    }
    /*************************************************************/
    /* Generate Concealment frame if packet is lost, or corrupt  */
    /*************************************************************/
    if( action == 1 ) {
        /* Handle packet loss by extrapolation */
        SKP_Silk_PLC( psDec, &sDecCtrl, pOut, L, action );
    }

    /*************************/
    /* Update output buffer. */
    /*************************/
    SKP_memcpy( psDec->outBuf, pOut, L * sizeof( SKP_int16 ) );

    /****************************************************************/
    /* Ensure smooth connection of extrapolated and good frames     */
    /****************************************************************/
    SKP_Silk_PLC_glue_frames( psDec, &sDecCtrl, pOut, L );

    /************************************************/
    /* Comfort noise generation / estimation        */
    /************************************************/
    SKP_Silk_CNG( psDec, &sDecCtrl, pOut , L );

    /********************************************/
    /* HP filter output                            */
    /********************************************/
    SKP_assert( ( ( psDec->fs_kHz == 12 ) && ( L % 3 ) == 0 ) || 
                ( ( psDec->fs_kHz != 12 ) && ( L % 2 ) == 0 ) );
    SKP_Silk_biquad( pOut, psDec->HP_B, psDec->HP_A, psDec->HPState, pOut, L );

    /********************************************/
    /* set output frame length                    */
    /********************************************/
    *pN = ( SKP_int16 )L;

    /* Update some decoder state variables */
    psDec->lagPrev = sDecCtrl.pitchL[ NB_SUBFR - 1 ];


    return ret;
}