/* 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 ) ); } }
void silk_NSQ_wrapper_FLP( silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */ silk_encoder_control_FLP *psEncCtrl, /* I/O Encoder control FLP */ SideInfoIndices *psIndices, /* I/O Quantization indices */ silk_nsq_state *psNSQ, /* I/O Noise Shaping Quantzation state */ opus_int8 pulses[], /* O Quantized pulse signal */ const silk_float x[] /* I Prefiltered input signal */ ) { opus_int i, j; opus_int32 x_Q3[ MAX_FRAME_LENGTH ]; opus_int32 Gains_Q16[ MAX_NB_SUBFR ]; silk_DWORD_ALIGN opus_int16 PredCoef_Q12[ 2 ][ MAX_LPC_ORDER ]; opus_int16 LTPCoef_Q14[ LTP_ORDER * MAX_NB_SUBFR ]; opus_int LTP_scale_Q14; /* Noise shaping parameters */ opus_int16 AR2_Q13[ MAX_NB_SUBFR * MAX_SHAPE_LPC_ORDER ]; opus_int32 LF_shp_Q14[ MAX_NB_SUBFR ]; /* Packs two int16 coefficients per int32 value */ opus_int Lambda_Q10; opus_int Tilt_Q14[ MAX_NB_SUBFR ]; opus_int HarmShapeGain_Q14[ MAX_NB_SUBFR ]; /* Convert control struct to fix control struct */ /* Noise shape parameters */ for( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) { for( j = 0; j < psEnc->sCmn.shapingLPCOrder; j++ ) { AR2_Q13[ i * MAX_SHAPE_LPC_ORDER + j ] = silk_float2int( psEncCtrl->AR2[ i * MAX_SHAPE_LPC_ORDER + j ] * 8192.0f ); } } for( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) { LF_shp_Q14[ i ] = silk_LSHIFT32( silk_float2int( psEncCtrl->LF_AR_shp[ i ] * 16384.0f ), 16 ) | (opus_uint16)silk_float2int( psEncCtrl->LF_MA_shp[ i ] * 16384.0f ); Tilt_Q14[ i ] = (opus_int)silk_float2int( psEncCtrl->Tilt[ i ] * 16384.0f ); HarmShapeGain_Q14[ i ] = (opus_int)silk_float2int( psEncCtrl->HarmShapeGain[ i ] * 16384.0f ); } Lambda_Q10 = ( opus_int )silk_float2int( psEncCtrl->Lambda * 1024.0f ); /* prediction and coding parameters */ for( i = 0; i < psEnc->sCmn.nb_subfr * LTP_ORDER; i++ ) { LTPCoef_Q14[ i ] = (opus_int16)silk_float2int( psEncCtrl->LTPCoef[ i ] * 16384.0f ); } for( j = 0; j < 2; j++ ) { for( i = 0; i < psEnc->sCmn.predictLPCOrder; i++ ) { PredCoef_Q12[ j ][ i ] = (opus_int16)silk_float2int( psEncCtrl->PredCoef[ j ][ i ] * 4096.0f ); } } for( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) { Gains_Q16[ i ] = silk_float2int( psEncCtrl->Gains[ i ] * 65536.0f ); silk_assert( Gains_Q16[ i ] > 0 ); } if( psIndices->signalType == TYPE_VOICED ) { LTP_scale_Q14 = silk_LTPScales_table_Q14[ psIndices->LTP_scaleIndex ]; } else { LTP_scale_Q14 = 0; } /* Convert input to fix */ for( i = 0; i < psEnc->sCmn.frame_length; i++ ) { x_Q3[ i ] = silk_float2int( 8.0f * x[ i ] ); } /* Call NSQ */ if( psEnc->sCmn.nStatesDelayedDecision > 1 || psEnc->sCmn.warping_Q16 > 0 ) { silk_NSQ_del_dec( &psEnc->sCmn, psNSQ, psIndices, x_Q3, pulses, PredCoef_Q12[ 0 ], LTPCoef_Q14, AR2_Q13, HarmShapeGain_Q14, Tilt_Q14, LF_shp_Q14, Gains_Q16, psEncCtrl->pitchL, Lambda_Q10, LTP_scale_Q14 ); } else { silk_NSQ( &psEnc->sCmn, psNSQ, psIndices, x_Q3, pulses, PredCoef_Q12[ 0 ], LTPCoef_Q14, AR2_Q13, HarmShapeGain_Q14, Tilt_Q14, LF_shp_Q14, Gains_Q16, psEncCtrl->pitchL, Lambda_Q10, LTP_scale_Q14 ); } }
int silk_encode_frame_FIX(silk_encoder_state_FIX * psEnc, /* I/O Pointer to Silk FIX encoder state */ int32_t * pnBytesOut, /* O Pointer to number of payload bytes; */ ec_enc * psRangeEnc, /* I/O compressor data structure */ int condCoding, /* I The type of conditional coding to use */ int maxBits, /* I If > 0: maximum number of output bits */ int useCBR /* I Flag to force constant-bitrate operation */ ) { silk_encoder_control_FIX sEncCtrl; int i, iter, maxIter, found_upper, found_lower, ret = 0; int16_t *x_frame; ec_enc sRangeEnc_copy, sRangeEnc_copy2; silk_nsq_state sNSQ_copy, sNSQ_copy2; int32_t seed_copy, nBits, nBits_lower, nBits_upper, gainMult_lower, gainMult_upper; int32_t gainsID, gainsID_lower, gainsID_upper; int16_t gainMult_Q8; int16_t ec_prevLagIndex_copy; int ec_prevSignalType_copy; int8_t LastGainIndex_copy2; /* This is totally unnecessary but many compilers (including gcc) are too dumb to realise it */ LastGainIndex_copy2 = nBits_lower = nBits_upper = gainMult_lower = gainMult_upper = 0; psEnc->sCmn.indices.Seed = psEnc->sCmn.frameCounter++ & 3; /**************************************************************/ /* Set up Input Pointers, and insert frame in input buffer */ /*************************************************************/ /* start of frame to encode */ x_frame = psEnc->x_buf + psEnc->sCmn.ltp_mem_length; /***************************************/ /* Ensure smooth bandwidth transitions */ /***************************************/ silk_LP_variable_cutoff(&psEnc->sCmn.sLP, psEnc->sCmn.inputBuf + 1, psEnc->sCmn.frame_length); /*******************************************/ /* Copy new frame to front of input buffer */ /*******************************************/ memcpy(x_frame + LA_SHAPE_MS * psEnc->sCmn.fs_kHz, psEnc->sCmn.inputBuf + 1, psEnc->sCmn.frame_length * sizeof(int16_t)); if (!psEnc->sCmn.prefillFlag) { int16_t *res_pitch_frame; int16_t res_pitch[psEnc->sCmn.la_pitch + psEnc->sCmn.frame_length + psEnc->sCmn.ltp_mem_length]; /* start of pitch LPC residual frame */ res_pitch_frame = res_pitch + psEnc->sCmn.ltp_mem_length; /*****************************************/ /* Find pitch lags, initial LPC analysis */ /*****************************************/ silk_find_pitch_lags_FIX(psEnc, &sEncCtrl, res_pitch, x_frame, psEnc->sCmn.arch); /************************/ /* Noise shape analysis */ /************************/ silk_noise_shape_analysis_FIX(psEnc, &sEncCtrl, res_pitch_frame, x_frame, psEnc->sCmn.arch); /***************************************************/ /* Find linear prediction coefficients (LPC + LTP) */ /***************************************************/ silk_find_pred_coefs_FIX(psEnc, &sEncCtrl, res_pitch, x_frame, condCoding); /****************************************/ /* Process gains */ /****************************************/ silk_process_gains_FIX(psEnc, &sEncCtrl, condCoding); /*****************************************/ /* Prefiltering for noise shaper */ /*****************************************/ int32_t xfw_Q3[psEnc->sCmn.frame_length]; silk_prefilter_FIX(psEnc, &sEncCtrl, xfw_Q3, x_frame); /****************************************/ /* Low Bitrate Redundant Encoding */ /****************************************/ silk_LBRR_encode_FIX(psEnc, &sEncCtrl, xfw_Q3, condCoding); /* Loop over quantizer and entropy coding to control bitrate */ maxIter = 6; gainMult_Q8 = SILK_FIX_CONST(1, 8); found_lower = 0; found_upper = 0; gainsID = silk_gains_ID(psEnc->sCmn.indices.GainsIndices, psEnc->sCmn.nb_subfr); gainsID_lower = -1; gainsID_upper = -1; /* Copy part of the input state */ memcpy(&sRangeEnc_copy, psRangeEnc, sizeof(ec_enc)); memcpy(&sNSQ_copy, &psEnc->sCmn.sNSQ, sizeof(silk_nsq_state)); seed_copy = psEnc->sCmn.indices.Seed; ec_prevLagIndex_copy = psEnc->sCmn.ec_prevLagIndex; ec_prevSignalType_copy = psEnc->sCmn.ec_prevSignalType; uint8_t ec_buf_copy[1275]; for (iter = 0;; iter++) { if (gainsID == gainsID_lower) { nBits = nBits_lower; } else if (gainsID == gainsID_upper) { nBits = nBits_upper; } else { /* Restore part of the input state */ if (iter > 0) { memcpy(psRangeEnc, &sRangeEnc_copy, sizeof(ec_enc)); memcpy(&psEnc->sCmn.sNSQ, &sNSQ_copy, sizeof(silk_nsq_state)); psEnc->sCmn.indices.Seed = seed_copy; psEnc->sCmn.ec_prevLagIndex = ec_prevLagIndex_copy; psEnc->sCmn.ec_prevSignalType = ec_prevSignalType_copy; } /*****************************************/ /* Noise shaping quantization */ /*****************************************/ if (psEnc->sCmn.nStatesDelayedDecision > 1 || psEnc->sCmn.warping_Q16 > 0) { silk_NSQ_del_dec(&psEnc->sCmn, &psEnc->sCmn.sNSQ, &psEnc->sCmn.indices, xfw_Q3, psEnc->sCmn.pulses, sEncCtrl. PredCoef_Q12[0], sEncCtrl.LTPCoef_Q14, sEncCtrl.AR2_Q13, sEncCtrl. HarmShapeGain_Q14, sEncCtrl.Tilt_Q14, sEncCtrl.LF_shp_Q14, sEncCtrl.Gains_Q16, sEncCtrl.pitchL, sEncCtrl.Lambda_Q10, sEncCtrl. LTP_scale_Q14); } else { silk_NSQ(&psEnc->sCmn, &psEnc->sCmn.sNSQ, &psEnc->sCmn.indices, xfw_Q3, psEnc->sCmn.pulses, sEncCtrl.PredCoef_Q12[0], sEncCtrl.LTPCoef_Q14, sEncCtrl.AR2_Q13, sEncCtrl.HarmShapeGain_Q14, sEncCtrl.Tilt_Q14, sEncCtrl.LF_shp_Q14, sEncCtrl.Gains_Q16, sEncCtrl.pitchL, sEncCtrl.Lambda_Q10, sEncCtrl.LTP_scale_Q14); } /****************************************/ /* Encode Parameters */ /****************************************/ silk_encode_indices(&psEnc->sCmn, psRangeEnc, psEnc->sCmn.nFramesEncoded, 0, condCoding); /****************************************/ /* Encode Excitation Signal */ /****************************************/ silk_encode_pulses(psRangeEnc, psEnc->sCmn.indices. signalType, psEnc->sCmn.indices. quantOffsetType, psEnc->sCmn.pulses, psEnc->sCmn.frame_length); nBits = ec_tell(psRangeEnc); if (useCBR == 0 && iter == 0 && nBits <= maxBits) { break; } } if (iter == maxIter) { if (found_lower && (gainsID == gainsID_lower || nBits > maxBits)) { /* Restore output state from earlier iteration that did meet the bitrate budget */ memcpy(psRangeEnc, &sRangeEnc_copy2, sizeof(ec_enc)); assert(sRangeEnc_copy2.offs <= 1275); memcpy(psRangeEnc->buf, ec_buf_copy, sRangeEnc_copy2.offs); memcpy(&psEnc->sCmn.sNSQ, &sNSQ_copy2, sizeof(silk_nsq_state)); psEnc->sShape.LastGainIndex = LastGainIndex_copy2; } break; } if (nBits > maxBits) { if (found_lower == 0 && iter >= 2) { /* Adjust the quantizer's rate/distortion tradeoff and discard previous "upper" results */ sEncCtrl.Lambda_Q10 = silk_ADD_RSHIFT32(sEncCtrl. Lambda_Q10, sEncCtrl. Lambda_Q10, 1); found_upper = 0; gainsID_upper = -1; } else { found_upper = 1; nBits_upper = nBits; gainMult_upper = gainMult_Q8; gainsID_upper = gainsID; } } else if (nBits < maxBits - 5) { found_lower = 1; nBits_lower = nBits; gainMult_lower = gainMult_Q8; if (gainsID != gainsID_lower) { gainsID_lower = gainsID; /* Copy part of the output state */ memcpy(&sRangeEnc_copy2, psRangeEnc, sizeof(ec_enc)); assert(psRangeEnc->offs <= 1275); memcpy(ec_buf_copy, psRangeEnc->buf, psRangeEnc->offs); memcpy(&sNSQ_copy2, &psEnc->sCmn.sNSQ, sizeof(silk_nsq_state)); LastGainIndex_copy2 = psEnc->sShape.LastGainIndex; } } else { /* Within 5 bits of budget: close enough */ break; } if ((found_lower & found_upper) == 0) { /* Adjust gain according to high-rate rate/distortion curve */ int32_t gain_factor_Q16; gain_factor_Q16 = silk_log2lin(silk_LSHIFT(nBits - maxBits, 7) / psEnc->sCmn.frame_length + SILK_FIX_CONST(16, 7)); gain_factor_Q16 = silk_min_32(gain_factor_Q16, SILK_FIX_CONST(2, 16)); if (nBits > maxBits) { gain_factor_Q16 = silk_max_32(gain_factor_Q16, SILK_FIX_CONST(1.3, 16)); } gainMult_Q8 = silk_SMULWB(gain_factor_Q16, gainMult_Q8); } else { /* Adjust gain by interpolating */ assert(nBits_upper != nBits_lower); gainMult_Q8 = gainMult_lower + silk_DIV32_16(silk_MUL (gainMult_upper - gainMult_lower, maxBits - nBits_lower), nBits_upper - nBits_lower); /* New gain multplier must be between 25% and 75% of old range (note that gainMult_upper < gainMult_lower) */ if (gainMult_Q8 > silk_ADD_RSHIFT32(gainMult_lower, gainMult_upper - gainMult_lower, 2)) { gainMult_Q8 = silk_ADD_RSHIFT32(gainMult_lower, gainMult_upper - gainMult_lower, 2); } else if (gainMult_Q8 < silk_SUB_RSHIFT32(gainMult_upper, gainMult_upper - gainMult_lower, 2)) { gainMult_Q8 = silk_SUB_RSHIFT32(gainMult_upper, gainMult_upper - gainMult_lower, 2); } } for (i = 0; i < psEnc->sCmn.nb_subfr; i++) { sEncCtrl.Gains_Q16[i] = silk_LSHIFT_SAT32(silk_SMULWB (sEncCtrl.GainsUnq_Q16[i], gainMult_Q8), 8); } /* Quantize gains */ psEnc->sShape.LastGainIndex = sEncCtrl.lastGainIndexPrev; silk_gains_quant(psEnc->sCmn.indices.GainsIndices, sEncCtrl.Gains_Q16, &psEnc->sShape.LastGainIndex, condCoding == CODE_CONDITIONALLY, psEnc->sCmn.nb_subfr); /* Unique identifier of gains vector */ gainsID = silk_gains_ID(psEnc->sCmn.indices.GainsIndices, psEnc->sCmn.nb_subfr); } } /* Update input buffer */ memmove(psEnc->x_buf, &psEnc->x_buf[psEnc->sCmn.frame_length], (psEnc->sCmn.ltp_mem_length + LA_SHAPE_MS * psEnc->sCmn.fs_kHz) * sizeof(int16_t)); /* Exit without entropy coding */ if (psEnc->sCmn.prefillFlag) { /* No payload */ *pnBytesOut = 0; return ret; } /* Parameters needed for next frame */ psEnc->sCmn.prevLag = sEncCtrl.pitchL[psEnc->sCmn.nb_subfr - 1]; psEnc->sCmn.prevSignalType = psEnc->sCmn.indices.signalType; /****************************************/ /* Finalize payload */ /****************************************/ psEnc->sCmn.first_frame_after_reset = 0; /* Payload size */ *pnBytesOut = silk_RSHIFT(ec_tell(psRangeEnc) + 7, 3); return ret; }