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; }