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; }
SKP_int SKP_Silk_decode_frame( SKP_Silk_decoder_state *psDec, /* I/O Pointer to Silk decoder state */ ec_dec *psRangeDec, /* I/O Compressor data structure */ SKP_int16 pOut[], /* O Pointer to output speech frame */ SKP_int32 *pN, /* O Pointer to size of output frame */ const SKP_int nBytes, /* I Payload length */ SKP_int lostFlag /* I 0: no loss, 1 loss, 2 decode fec */ ) { SKP_Silk_decoder_control sDecCtrl; SKP_int i, L, mv_len, ret = 0; SKP_int8 flags; SKP_int32 LBRR_symbol; SKP_int pulses[ MAX_FRAME_LENGTH ]; TIC(DECODE_FRAME) 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 */ /********************************************/ if( lostFlag != PACKET_LOST && psDec->nFramesDecoded == 0 ) { /* First decoder call for this payload */ /* Decode VAD flags and LBRR flag */ flags = SKP_RSHIFT( psRangeDec->buf[ 0 ], 7 - psDec->nFramesPerPacket ) & ( SKP_LSHIFT( 1, psDec->nFramesPerPacket + 1 ) - 1 ); psDec->LBRR_flag = flags & 1; for( i = psDec->nFramesPerPacket - 1; i >= 0 ; i-- ) { flags = SKP_RSHIFT( flags, 1 ); psDec->VAD_flags[ i ] = flags & 1; } for( i = 0; i < psDec->nFramesPerPacket + 1; i++ ) { ec_dec_icdf( psRangeDec, SKP_Silk_uniform2_iCDF, 8 ); } /* Decode LBRR flags */ SKP_memset( psDec->LBRR_flags, 0, sizeof( psDec->LBRR_flags ) ); if( psDec->LBRR_flag ) { if( psDec->nFramesPerPacket == 1 ) { psDec->LBRR_flags[ 0 ] = 1; } else { LBRR_symbol = ec_dec_icdf( psRangeDec, SKP_Silk_LBRR_flags_iCDF_ptr[ psDec->nFramesPerPacket - 2 ], 8 ) + 1; for( i = 0; i < psDec->nFramesPerPacket; i++ ) { psDec->LBRR_flags[ i ] = SKP_RSHIFT( LBRR_symbol, i ) & 1; } } } if( lostFlag == DECODE_NORMAL ) { /* Regular decoding: skip all LBRR data */ for( i = 0; i < psDec->nFramesPerPacket; i++ ) { if( psDec->LBRR_flags[ i ] ) { SKP_Silk_decode_indices( psDec, psRangeDec, i, 1 ); SKP_Silk_decode_pulses( psRangeDec, pulses, psDec->indices.signalType, psDec->indices.quantOffsetType, psDec->frame_length ); } } } } if( lostFlag == DECODE_LBRR && psDec->LBRR_flags[ psDec->nFramesDecoded ] == 0 ) { /* Treat absent LBRR data as lost frame */ lostFlag = PACKET_LOST; psDec->nFramesDecoded++; } if( lostFlag != PACKET_LOST ) { /*********************************************/ /* Decode quantization indices of side info */ /*********************************************/ TIC(decode_indices) SKP_Silk_decode_indices( psDec, psRangeDec, psDec->nFramesDecoded, lostFlag ); TOC(decode_indices) /*********************************************/ /* Decode quantization indices of excitation */ /*********************************************/ TIC(decode_pulses) SKP_Silk_decode_pulses( psRangeDec, pulses, psDec->indices.signalType, psDec->indices.quantOffsetType, psDec->frame_length ); TOC(decode_pulses) /********************************************/ /* Decode parameters and pulse signal */ /********************************************/ TIC(decode_params) SKP_Silk_decode_parameters( psDec, &sDecCtrl ); TOC(decode_params) /* Update length. Sampling frequency may have changed */ L = psDec->frame_length; /********************************************************/ /* Run inverse NSQ */ /********************************************************/ TIC(decode_core) SKP_Silk_decode_core( psDec, &sDecCtrl, pOut, pulses ); TOC(decode_core) /********************************************************/ /* Update PLC state */ /********************************************************/ SKP_Silk_PLC( psDec, &sDecCtrl, pOut, L, 0 ); psDec->lossCnt = 0; psDec->prevSignalType = psDec->indices.signalType; SKP_assert( psDec->prevSignalType >= 0 && psDec->prevSignalType <= 2 ); /* A frame has been decoded without errors */ psDec->first_frame_after_reset = 0; psDec->nFramesDecoded++; } else { /* Handle packet loss by extrapolation */ SKP_Silk_PLC( psDec, &sDecCtrl, pOut, L, 1 ); } /*************************/ /* Update output buffer. */ /*************************/ SKP_assert( psDec->ltp_mem_length >= psDec->frame_length ); mv_len = psDec->ltp_mem_length - psDec->frame_length; SKP_memmove( psDec->outBuf, &psDec->outBuf[ psDec->frame_length ], mv_len * sizeof(SKP_int16) ); SKP_memcpy( &psDec->outBuf[ mv_len ], pOut, psDec->frame_length * 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 */ /********************************************/ TIC(HP_out) SKP_Silk_biquad_alt( pOut, psDec->HP_B, psDec->HP_A, psDec->HPState, pOut, L ); TOC(HP_out) /* Update some decoder state variables */ psDec->lagPrev = sDecCtrl.pitchL[ psDec->nb_subfr - 1 ]; /********************************************/ /* set output frame length */ /********************************************/ *pN = ( SKP_int16 )L; TOC(DECODE_FRAME) return ret; }