/* Low-Bitrate Redundancy (LBRR) encoding. Reuse all parameters but encode excitation at lower bitrate */ static OPUS_INLINE void silk_LBRR_encode_FIX( silk_encoder_state_FIX *psEnc, /* I/O Pointer to Silk FIX encoder state */ silk_encoder_control_FIX *psEncCtrl, /* I/O Pointer to Silk FIX encoder control struct */ const opus_int32 xfw_Q3[], /* I Input signal */ opus_int condCoding /* I The type of conditional coding used so far for this frame */ ) { opus_int32 TempGains_Q16[ MAX_NB_SUBFR ]; SideInfoIndices *psIndices_LBRR = &psEnc->sCmn.indices_LBRR[ psEnc->sCmn.nFramesEncoded ]; silk_nsq_state sNSQ_LBRR; /*******************************************/ /* Control use of inband LBRR */ /*******************************************/ if( psEnc->sCmn.LBRR_enabled && psEnc->sCmn.speech_activity_Q8 > SILK_FIX_CONST( LBRR_SPEECH_ACTIVITY_THRES, 8 ) ) { psEnc->sCmn.LBRR_flags[ psEnc->sCmn.nFramesEncoded ] = 1; /* Copy noise shaping quantizer state and quantization indices from regular encoding */ silk_memcpy( &sNSQ_LBRR, &psEnc->sCmn.sNSQ, sizeof( silk_nsq_state ) ); silk_memcpy( psIndices_LBRR, &psEnc->sCmn.indices, sizeof( SideInfoIndices ) ); /* Save original gains */ silk_memcpy( TempGains_Q16, psEncCtrl->Gains_Q16, psEnc->sCmn.nb_subfr * sizeof( opus_int32 ) ); if( psEnc->sCmn.nFramesEncoded == 0 || psEnc->sCmn.LBRR_flags[ psEnc->sCmn.nFramesEncoded - 1 ] == 0 ) { /* First frame in packet or previous frame not LBRR coded */ psEnc->sCmn.LBRRprevLastGainIndex = psEnc->sShape.LastGainIndex; /* Increase Gains to get target LBRR rate */ psIndices_LBRR->GainsIndices[ 0 ] = psIndices_LBRR->GainsIndices[ 0 ] + psEnc->sCmn.LBRR_GainIncreases; psIndices_LBRR->GainsIndices[ 0 ] = silk_min_int( psIndices_LBRR->GainsIndices[ 0 ], N_LEVELS_QGAIN - 1 ); } /* Decode to get gains in sync with decoder */ /* Overwrite unquantized gains with quantized gains */ silk_gains_dequant( psEncCtrl->Gains_Q16, psIndices_LBRR->GainsIndices, &psEnc->sCmn.LBRRprevLastGainIndex, condCoding == CODE_CONDITIONALLY, psEnc->sCmn.nb_subfr ); /*****************************************/ /* Noise shaping quantization */ /*****************************************/ if( psEnc->sCmn.nStatesDelayedDecision > 1 || psEnc->sCmn.warping_Q16 > 0 ) { silk_NSQ_del_dec( &psEnc->sCmn, &sNSQ_LBRR, psIndices_LBRR, xfw_Q3, psEnc->sCmn.pulses_LBRR[ psEnc->sCmn.nFramesEncoded ], psEncCtrl->PredCoef_Q12[ 0 ], psEncCtrl->LTPCoef_Q14, psEncCtrl->AR2_Q13, psEncCtrl->HarmShapeGain_Q14, psEncCtrl->Tilt_Q14, psEncCtrl->LF_shp_Q14, psEncCtrl->Gains_Q16, psEncCtrl->pitchL, psEncCtrl->Lambda_Q10, psEncCtrl->LTP_scale_Q14 ); } else { silk_NSQ( &psEnc->sCmn, &sNSQ_LBRR, psIndices_LBRR, xfw_Q3, psEnc->sCmn.pulses_LBRR[ psEnc->sCmn.nFramesEncoded ], psEncCtrl->PredCoef_Q12[ 0 ], psEncCtrl->LTPCoef_Q14, psEncCtrl->AR2_Q13, psEncCtrl->HarmShapeGain_Q14, psEncCtrl->Tilt_Q14, psEncCtrl->LF_shp_Q14, psEncCtrl->Gains_Q16, psEncCtrl->pitchL, psEncCtrl->Lambda_Q10, psEncCtrl->LTP_scale_Q14 ); } /* Restore original gains */ silk_memcpy( psEncCtrl->Gains_Q16, TempGains_Q16, psEnc->sCmn.nb_subfr * sizeof( opus_int32 ) ); } }
/* Low-Bitrate Redundancy (LBRR) encoding. Reuse all parameters but encode excitation at lower bitrate */ static void silk_LBRR_encode_FLP( silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */ silk_encoder_control_FLP *psEncCtrl, /* I/O Encoder control FLP */ const silk_float xfw[], /* I Input signal */ opus_int condCoding /* I The type of conditional coding used so far for this frame */ ) { opus_int k; opus_int32 Gains_Q16[ MAX_NB_SUBFR ]; silk_float TempGains[ MAX_NB_SUBFR ]; SideInfoIndices *psIndices_LBRR = &psEnc->sCmn.indices_LBRR[ psEnc->sCmn.nFramesEncoded ]; silk_nsq_state sNSQ_LBRR; /*******************************************/ /* Control use of inband LBRR */ /*******************************************/ if( psEnc->sCmn.LBRR_enabled && psEnc->sCmn.speech_activity_Q8 > SILK_FIX_CONST( LBRR_SPEECH_ACTIVITY_THRES, 8 ) ) { psEnc->sCmn.LBRR_flags[ psEnc->sCmn.nFramesEncoded ] = 1; /* Copy noise shaping quantizer state and quantization indices from regular encoding */ silk_memcpy( &sNSQ_LBRR, &psEnc->sCmn.sNSQ, sizeof( silk_nsq_state ) ); silk_memcpy( psIndices_LBRR, &psEnc->sCmn.indices, sizeof( SideInfoIndices ) ); /* Save original gains */ silk_memcpy( TempGains, psEncCtrl->Gains, psEnc->sCmn.nb_subfr * sizeof( silk_float ) ); if( psEnc->sCmn.nFramesEncoded == 0 || psEnc->sCmn.LBRR_flags[ psEnc->sCmn.nFramesEncoded - 1 ] == 0 ) { /* First frame in packet or previous frame not LBRR coded */ psEnc->sCmn.LBRRprevLastGainIndex = psEnc->sShape.LastGainIndex; /* Increase Gains to get target LBRR rate */ psIndices_LBRR->GainsIndices[ 0 ] += psEnc->sCmn.LBRR_GainIncreases; psIndices_LBRR->GainsIndices[ 0 ] = silk_min_int( psIndices_LBRR->GainsIndices[ 0 ], N_LEVELS_QGAIN - 1 ); } /* Decode to get gains in sync with decoder */ silk_gains_dequant( Gains_Q16, psIndices_LBRR->GainsIndices, &psEnc->sCmn.LBRRprevLastGainIndex, condCoding == CODE_CONDITIONALLY, psEnc->sCmn.nb_subfr ); /* Overwrite unquantized gains with quantized gains and convert back to Q0 from Q16 */ for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) { psEncCtrl->Gains[ k ] = Gains_Q16[ k ] * ( 1.0f / 65536.0f ); } /*****************************************/ /* Noise shaping quantization */ /*****************************************/ silk_NSQ_wrapper_FLP( psEnc, psEncCtrl, psIndices_LBRR, &sNSQ_LBRR, psEnc->sCmn.pulses_LBRR[ psEnc->sCmn.nFramesEncoded ], xfw ); /* Restore original gains */ silk_memcpy( psEncCtrl->Gains, TempGains, psEnc->sCmn.nb_subfr * sizeof( silk_float ) ); } }
/* Decode parameters from payload */ void silk_decode_parameters( silk_decoder_state *psDec, /* I/O State */ silk_decoder_control *psDecCtrl /* I/O Decoder control */ ) { SKP_int i, k, Ix; SKP_int16 pNLSF_Q15[ MAX_LPC_ORDER ], pNLSF0_Q15[ MAX_LPC_ORDER ]; const SKP_int8 *cbk_ptr_Q7; /* Dequant Gains */ silk_gains_dequant( psDecCtrl->Gains_Q16, psDec->indices.GainsIndices, &psDec->LastGainIndex, psDec->nFramesDecoded, psDec->nb_subfr ); /****************/ /* Decode NLSFs */ /****************/ silk_NLSF_decode( pNLSF_Q15, psDec->indices.NLSFIndices, psDec->psNLSF_CB ); /* Convert NLSF parameters to AR prediction filter coefficients */ silk_NLSF2A_stable( psDecCtrl->PredCoef_Q12[ 1 ], pNLSF_Q15, psDec->LPC_order ); /* If just reset, e.g., because internal Fs changed, do not allow interpolation */ /* improves the case of packet loss in the first frame after a switch */ if( psDec->first_frame_after_reset == 1 ) { psDec->indices.NLSFInterpCoef_Q2 = 4; } if( psDec->indices.NLSFInterpCoef_Q2 < 4 ) { /* Calculation of the interpolated NLSF0 vector from the interpolation factor, */ /* the previous NLSF1, and the current NLSF1 */ for( i = 0; i < psDec->LPC_order; i++ ) { pNLSF0_Q15[ i ] = psDec->prevNLSF_Q15[ i ] + SKP_RSHIFT( SKP_MUL( psDec->indices.NLSFInterpCoef_Q2, pNLSF_Q15[ i ] - psDec->prevNLSF_Q15[ i ] ), 2 ); } /* Convert NLSF parameters to AR prediction filter coefficients */ silk_NLSF2A_stable( psDecCtrl->PredCoef_Q12[ 0 ], pNLSF0_Q15, psDec->LPC_order ); } else { /* Copy LPC coefficients for first half from second half */ SKP_memcpy( psDecCtrl->PredCoef_Q12[ 0 ], psDecCtrl->PredCoef_Q12[ 1 ], psDec->LPC_order * sizeof( SKP_int16 ) ); } SKP_memcpy( psDec->prevNLSF_Q15, pNLSF_Q15, psDec->LPC_order * sizeof( SKP_int16 ) ); /* After a packet loss do BWE of LPC coefs */ if( psDec->lossCnt ) { silk_bwexpander( psDecCtrl->PredCoef_Q12[ 0 ], psDec->LPC_order, BWE_AFTER_LOSS_Q16 ); silk_bwexpander( psDecCtrl->PredCoef_Q12[ 1 ], psDec->LPC_order, BWE_AFTER_LOSS_Q16 ); } if( psDec->indices.signalType == TYPE_VOICED ) { /*********************/ /* Decode pitch lags */ /*********************/ /* Decode pitch values */ silk_decode_pitch( psDec->indices.lagIndex, psDec->indices.contourIndex, psDecCtrl->pitchL, psDec->fs_kHz, psDec->nb_subfr ); /* Decode Codebook Index */ cbk_ptr_Q7 = silk_LTP_vq_ptrs_Q7[ psDec->indices.PERIndex ]; /* set pointer to start of codebook */ for( k = 0; k < psDec->nb_subfr; k++ ) { Ix = psDec->indices.LTPIndex[ k ]; for( i = 0; i < LTP_ORDER; i++ ) { psDecCtrl->LTPCoef_Q14[ k * LTP_ORDER + i ] = SKP_LSHIFT( cbk_ptr_Q7[ Ix * LTP_ORDER + i ], 7 ); } } /**********************/ /* Decode LTP scaling */ /**********************/ Ix = psDec->indices.LTP_scaleIndex; psDecCtrl->LTP_scale_Q14 = silk_LTPScales_table_Q14[ Ix ]; } else { SKP_memset( psDecCtrl->pitchL, 0, psDec->nb_subfr * sizeof( SKP_int ) ); SKP_memset( psDecCtrl->LTPCoef_Q14, 0, LTP_ORDER * psDec->nb_subfr * sizeof( SKP_int16 ) ); psDec->indices.PERIndex = 0; psDecCtrl->LTP_scale_Q14 = 0; } }