SKP_int SKP_Silk_init_decoder( SKP_Silk_decoder_state *psDec /* I/O Decoder state pointer */ ) { SKP_memset( psDec, 0, sizeof( SKP_Silk_decoder_state ) ); /* Set sampling rate to 24 kHz, and init non-zero values */ SKP_Silk_decoder_set_fs( psDec, 24 ); /* Used to deactivate e.g. LSF interpolation and fluctuation reduction */ psDec->first_frame_after_reset = 1; psDec->prev_inv_gain_Q16 = 65536; /* Reset CNG state */ SKP_Silk_CNG_Reset( psDec ); SKP_Silk_PLC_Reset( psDec ); return(0); }
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; }