1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/media/libopus/silk/fixed/encode_frame_FIX.c Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,385 @@ 1.4 +/*********************************************************************** 1.5 +Copyright (c) 2006-2011, Skype Limited. All rights reserved. 1.6 +Redistribution and use in source and binary forms, with or without 1.7 +modification, are permitted provided that the following conditions 1.8 +are met: 1.9 +- Redistributions of source code must retain the above copyright notice, 1.10 +this list of conditions and the following disclaimer. 1.11 +- Redistributions in binary form must reproduce the above copyright 1.12 +notice, this list of conditions and the following disclaimer in the 1.13 +documentation and/or other materials provided with the distribution. 1.14 +- Neither the name of Internet Society, IETF or IETF Trust, nor the 1.15 +names of specific contributors, may be used to endorse or promote 1.16 +products derived from this software without specific prior written 1.17 +permission. 1.18 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 1.19 +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1.20 +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1.21 +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 1.22 +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 1.23 +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 1.24 +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 1.25 +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 1.26 +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 1.27 +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 1.28 +POSSIBILITY OF SUCH DAMAGE. 1.29 +***********************************************************************/ 1.30 + 1.31 +#ifdef HAVE_CONFIG_H 1.32 +#include "config.h" 1.33 +#endif 1.34 + 1.35 +#include "main_FIX.h" 1.36 +#include "stack_alloc.h" 1.37 +#include "tuning_parameters.h" 1.38 + 1.39 +/* Low Bitrate Redundancy (LBRR) encoding. Reuse all parameters but encode with lower bitrate */ 1.40 +static OPUS_INLINE void silk_LBRR_encode_FIX( 1.41 + silk_encoder_state_FIX *psEnc, /* I/O Pointer to Silk FIX encoder state */ 1.42 + silk_encoder_control_FIX *psEncCtrl, /* I/O Pointer to Silk FIX encoder control struct */ 1.43 + const opus_int32 xfw_Q3[], /* I Input signal */ 1.44 + opus_int condCoding /* I The type of conditional coding used so far for this frame */ 1.45 +); 1.46 + 1.47 +void silk_encode_do_VAD_FIX( 1.48 + silk_encoder_state_FIX *psEnc /* I/O Pointer to Silk FIX encoder state */ 1.49 +) 1.50 +{ 1.51 + /****************************/ 1.52 + /* Voice Activity Detection */ 1.53 + /****************************/ 1.54 + silk_VAD_GetSA_Q8( &psEnc->sCmn, psEnc->sCmn.inputBuf + 1 ); 1.55 + 1.56 + /**************************************************/ 1.57 + /* Convert speech activity into VAD and DTX flags */ 1.58 + /**************************************************/ 1.59 + if( psEnc->sCmn.speech_activity_Q8 < SILK_FIX_CONST( SPEECH_ACTIVITY_DTX_THRES, 8 ) ) { 1.60 + psEnc->sCmn.indices.signalType = TYPE_NO_VOICE_ACTIVITY; 1.61 + psEnc->sCmn.noSpeechCounter++; 1.62 + if( psEnc->sCmn.noSpeechCounter < NB_SPEECH_FRAMES_BEFORE_DTX ) { 1.63 + psEnc->sCmn.inDTX = 0; 1.64 + } else if( psEnc->sCmn.noSpeechCounter > MAX_CONSECUTIVE_DTX + NB_SPEECH_FRAMES_BEFORE_DTX ) { 1.65 + psEnc->sCmn.noSpeechCounter = NB_SPEECH_FRAMES_BEFORE_DTX; 1.66 + psEnc->sCmn.inDTX = 0; 1.67 + } 1.68 + psEnc->sCmn.VAD_flags[ psEnc->sCmn.nFramesEncoded ] = 0; 1.69 + } else { 1.70 + psEnc->sCmn.noSpeechCounter = 0; 1.71 + psEnc->sCmn.inDTX = 0; 1.72 + psEnc->sCmn.indices.signalType = TYPE_UNVOICED; 1.73 + psEnc->sCmn.VAD_flags[ psEnc->sCmn.nFramesEncoded ] = 1; 1.74 + } 1.75 +} 1.76 + 1.77 +/****************/ 1.78 +/* Encode frame */ 1.79 +/****************/ 1.80 +opus_int silk_encode_frame_FIX( 1.81 + silk_encoder_state_FIX *psEnc, /* I/O Pointer to Silk FIX encoder state */ 1.82 + opus_int32 *pnBytesOut, /* O Pointer to number of payload bytes; */ 1.83 + ec_enc *psRangeEnc, /* I/O compressor data structure */ 1.84 + opus_int condCoding, /* I The type of conditional coding to use */ 1.85 + opus_int maxBits, /* I If > 0: maximum number of output bits */ 1.86 + opus_int useCBR /* I Flag to force constant-bitrate operation */ 1.87 +) 1.88 +{ 1.89 + silk_encoder_control_FIX sEncCtrl; 1.90 + opus_int i, iter, maxIter, found_upper, found_lower, ret = 0; 1.91 + opus_int16 *x_frame; 1.92 + ec_enc sRangeEnc_copy, sRangeEnc_copy2; 1.93 + silk_nsq_state sNSQ_copy, sNSQ_copy2; 1.94 + opus_int32 seed_copy, nBits, nBits_lower, nBits_upper, gainMult_lower, gainMult_upper; 1.95 + opus_int32 gainsID, gainsID_lower, gainsID_upper; 1.96 + opus_int16 gainMult_Q8; 1.97 + opus_int16 ec_prevLagIndex_copy; 1.98 + opus_int ec_prevSignalType_copy; 1.99 + opus_int8 LastGainIndex_copy2; 1.100 + SAVE_STACK; 1.101 + 1.102 + /* This is totally unnecessary but many compilers (including gcc) are too dumb to realise it */ 1.103 + LastGainIndex_copy2 = nBits_lower = nBits_upper = gainMult_lower = gainMult_upper = 0; 1.104 + 1.105 + psEnc->sCmn.indices.Seed = psEnc->sCmn.frameCounter++ & 3; 1.106 + 1.107 + /**************************************************************/ 1.108 + /* Set up Input Pointers, and insert frame in input buffer */ 1.109 + /*************************************************************/ 1.110 + /* start of frame to encode */ 1.111 + x_frame = psEnc->x_buf + psEnc->sCmn.ltp_mem_length; 1.112 + 1.113 + /***************************************/ 1.114 + /* Ensure smooth bandwidth transitions */ 1.115 + /***************************************/ 1.116 + silk_LP_variable_cutoff( &psEnc->sCmn.sLP, psEnc->sCmn.inputBuf + 1, psEnc->sCmn.frame_length ); 1.117 + 1.118 + /*******************************************/ 1.119 + /* Copy new frame to front of input buffer */ 1.120 + /*******************************************/ 1.121 + silk_memcpy( x_frame + LA_SHAPE_MS * psEnc->sCmn.fs_kHz, psEnc->sCmn.inputBuf + 1, psEnc->sCmn.frame_length * sizeof( opus_int16 ) ); 1.122 + 1.123 + if( !psEnc->sCmn.prefillFlag ) { 1.124 + VARDECL( opus_int32, xfw_Q3 ); 1.125 + VARDECL( opus_int16, res_pitch ); 1.126 + VARDECL( opus_uint8, ec_buf_copy ); 1.127 + opus_int16 *res_pitch_frame; 1.128 + 1.129 + ALLOC( res_pitch, 1.130 + psEnc->sCmn.la_pitch + psEnc->sCmn.frame_length 1.131 + + psEnc->sCmn.ltp_mem_length, opus_int16 ); 1.132 + /* start of pitch LPC residual frame */ 1.133 + res_pitch_frame = res_pitch + psEnc->sCmn.ltp_mem_length; 1.134 + 1.135 + /*****************************************/ 1.136 + /* Find pitch lags, initial LPC analysis */ 1.137 + /*****************************************/ 1.138 + silk_find_pitch_lags_FIX( psEnc, &sEncCtrl, res_pitch, x_frame, psEnc->sCmn.arch ); 1.139 + 1.140 + /************************/ 1.141 + /* Noise shape analysis */ 1.142 + /************************/ 1.143 + silk_noise_shape_analysis_FIX( psEnc, &sEncCtrl, res_pitch_frame, x_frame, psEnc->sCmn.arch ); 1.144 + 1.145 + /***************************************************/ 1.146 + /* Find linear prediction coefficients (LPC + LTP) */ 1.147 + /***************************************************/ 1.148 + silk_find_pred_coefs_FIX( psEnc, &sEncCtrl, res_pitch, x_frame, condCoding ); 1.149 + 1.150 + /****************************************/ 1.151 + /* Process gains */ 1.152 + /****************************************/ 1.153 + silk_process_gains_FIX( psEnc, &sEncCtrl, condCoding ); 1.154 + 1.155 + /*****************************************/ 1.156 + /* Prefiltering for noise shaper */ 1.157 + /*****************************************/ 1.158 + ALLOC( xfw_Q3, psEnc->sCmn.frame_length, opus_int32 ); 1.159 + silk_prefilter_FIX( psEnc, &sEncCtrl, xfw_Q3, x_frame ); 1.160 + 1.161 + /****************************************/ 1.162 + /* Low Bitrate Redundant Encoding */ 1.163 + /****************************************/ 1.164 + silk_LBRR_encode_FIX( psEnc, &sEncCtrl, xfw_Q3, condCoding ); 1.165 + 1.166 + /* Loop over quantizer and entropy coding to control bitrate */ 1.167 + maxIter = 6; 1.168 + gainMult_Q8 = SILK_FIX_CONST( 1, 8 ); 1.169 + found_lower = 0; 1.170 + found_upper = 0; 1.171 + gainsID = silk_gains_ID( psEnc->sCmn.indices.GainsIndices, psEnc->sCmn.nb_subfr ); 1.172 + gainsID_lower = -1; 1.173 + gainsID_upper = -1; 1.174 + /* Copy part of the input state */ 1.175 + silk_memcpy( &sRangeEnc_copy, psRangeEnc, sizeof( ec_enc ) ); 1.176 + silk_memcpy( &sNSQ_copy, &psEnc->sCmn.sNSQ, sizeof( silk_nsq_state ) ); 1.177 + seed_copy = psEnc->sCmn.indices.Seed; 1.178 + ec_prevLagIndex_copy = psEnc->sCmn.ec_prevLagIndex; 1.179 + ec_prevSignalType_copy = psEnc->sCmn.ec_prevSignalType; 1.180 + ALLOC( ec_buf_copy, 1275, opus_uint8 ); 1.181 + for( iter = 0; ; iter++ ) { 1.182 + if( gainsID == gainsID_lower ) { 1.183 + nBits = nBits_lower; 1.184 + } else if( gainsID == gainsID_upper ) { 1.185 + nBits = nBits_upper; 1.186 + } else { 1.187 + /* Restore part of the input state */ 1.188 + if( iter > 0 ) { 1.189 + silk_memcpy( psRangeEnc, &sRangeEnc_copy, sizeof( ec_enc ) ); 1.190 + silk_memcpy( &psEnc->sCmn.sNSQ, &sNSQ_copy, sizeof( silk_nsq_state ) ); 1.191 + psEnc->sCmn.indices.Seed = seed_copy; 1.192 + psEnc->sCmn.ec_prevLagIndex = ec_prevLagIndex_copy; 1.193 + psEnc->sCmn.ec_prevSignalType = ec_prevSignalType_copy; 1.194 + } 1.195 + 1.196 + /*****************************************/ 1.197 + /* Noise shaping quantization */ 1.198 + /*****************************************/ 1.199 + if( psEnc->sCmn.nStatesDelayedDecision > 1 || psEnc->sCmn.warping_Q16 > 0 ) { 1.200 + silk_NSQ_del_dec( &psEnc->sCmn, &psEnc->sCmn.sNSQ, &psEnc->sCmn.indices, xfw_Q3, psEnc->sCmn.pulses, 1.201 + sEncCtrl.PredCoef_Q12[ 0 ], sEncCtrl.LTPCoef_Q14, sEncCtrl.AR2_Q13, sEncCtrl.HarmShapeGain_Q14, 1.202 + sEncCtrl.Tilt_Q14, sEncCtrl.LF_shp_Q14, sEncCtrl.Gains_Q16, sEncCtrl.pitchL, sEncCtrl.Lambda_Q10, sEncCtrl.LTP_scale_Q14 ); 1.203 + } else { 1.204 + silk_NSQ( &psEnc->sCmn, &psEnc->sCmn.sNSQ, &psEnc->sCmn.indices, xfw_Q3, psEnc->sCmn.pulses, 1.205 + sEncCtrl.PredCoef_Q12[ 0 ], sEncCtrl.LTPCoef_Q14, sEncCtrl.AR2_Q13, sEncCtrl.HarmShapeGain_Q14, 1.206 + sEncCtrl.Tilt_Q14, sEncCtrl.LF_shp_Q14, sEncCtrl.Gains_Q16, sEncCtrl.pitchL, sEncCtrl.Lambda_Q10, sEncCtrl.LTP_scale_Q14 ); 1.207 + } 1.208 + 1.209 + /****************************************/ 1.210 + /* Encode Parameters */ 1.211 + /****************************************/ 1.212 + silk_encode_indices( &psEnc->sCmn, psRangeEnc, psEnc->sCmn.nFramesEncoded, 0, condCoding ); 1.213 + 1.214 + /****************************************/ 1.215 + /* Encode Excitation Signal */ 1.216 + /****************************************/ 1.217 + silk_encode_pulses( psRangeEnc, psEnc->sCmn.indices.signalType, psEnc->sCmn.indices.quantOffsetType, 1.218 + psEnc->sCmn.pulses, psEnc->sCmn.frame_length ); 1.219 + 1.220 + nBits = ec_tell( psRangeEnc ); 1.221 + 1.222 + if( useCBR == 0 && iter == 0 && nBits <= maxBits ) { 1.223 + break; 1.224 + } 1.225 + } 1.226 + 1.227 + if( iter == maxIter ) { 1.228 + if( found_lower && ( gainsID == gainsID_lower || nBits > maxBits ) ) { 1.229 + /* Restore output state from earlier iteration that did meet the bitrate budget */ 1.230 + silk_memcpy( psRangeEnc, &sRangeEnc_copy2, sizeof( ec_enc ) ); 1.231 + silk_assert( sRangeEnc_copy2.offs <= 1275 ); 1.232 + silk_memcpy( psRangeEnc->buf, ec_buf_copy, sRangeEnc_copy2.offs ); 1.233 + silk_memcpy( &psEnc->sCmn.sNSQ, &sNSQ_copy2, sizeof( silk_nsq_state ) ); 1.234 + psEnc->sShape.LastGainIndex = LastGainIndex_copy2; 1.235 + } 1.236 + break; 1.237 + } 1.238 + 1.239 + if( nBits > maxBits ) { 1.240 + if( found_lower == 0 && iter >= 2 ) { 1.241 + /* Adjust the quantizer's rate/distortion tradeoff and discard previous "upper" results */ 1.242 + sEncCtrl.Lambda_Q10 = silk_ADD_RSHIFT32( sEncCtrl.Lambda_Q10, sEncCtrl.Lambda_Q10, 1 ); 1.243 + found_upper = 0; 1.244 + gainsID_upper = -1; 1.245 + } else { 1.246 + found_upper = 1; 1.247 + nBits_upper = nBits; 1.248 + gainMult_upper = gainMult_Q8; 1.249 + gainsID_upper = gainsID; 1.250 + } 1.251 + } else if( nBits < maxBits - 5 ) { 1.252 + found_lower = 1; 1.253 + nBits_lower = nBits; 1.254 + gainMult_lower = gainMult_Q8; 1.255 + if( gainsID != gainsID_lower ) { 1.256 + gainsID_lower = gainsID; 1.257 + /* Copy part of the output state */ 1.258 + silk_memcpy( &sRangeEnc_copy2, psRangeEnc, sizeof( ec_enc ) ); 1.259 + silk_assert( psRangeEnc->offs <= 1275 ); 1.260 + silk_memcpy( ec_buf_copy, psRangeEnc->buf, psRangeEnc->offs ); 1.261 + silk_memcpy( &sNSQ_copy2, &psEnc->sCmn.sNSQ, sizeof( silk_nsq_state ) ); 1.262 + LastGainIndex_copy2 = psEnc->sShape.LastGainIndex; 1.263 + } 1.264 + } else { 1.265 + /* Within 5 bits of budget: close enough */ 1.266 + break; 1.267 + } 1.268 + 1.269 + if( ( found_lower & found_upper ) == 0 ) { 1.270 + /* Adjust gain according to high-rate rate/distortion curve */ 1.271 + opus_int32 gain_factor_Q16; 1.272 + gain_factor_Q16 = silk_log2lin( silk_LSHIFT( nBits - maxBits, 7 ) / psEnc->sCmn.frame_length + SILK_FIX_CONST( 16, 7 ) ); 1.273 + gain_factor_Q16 = silk_min_32( gain_factor_Q16, SILK_FIX_CONST( 2, 16 ) ); 1.274 + if( nBits > maxBits ) { 1.275 + gain_factor_Q16 = silk_max_32( gain_factor_Q16, SILK_FIX_CONST( 1.3, 16 ) ); 1.276 + } 1.277 + gainMult_Q8 = silk_SMULWB( gain_factor_Q16, gainMult_Q8 ); 1.278 + } else { 1.279 + /* Adjust gain by interpolating */ 1.280 + gainMult_Q8 = gainMult_lower + silk_DIV32_16( silk_MUL( gainMult_upper - gainMult_lower, maxBits - nBits_lower ), nBits_upper - nBits_lower ); 1.281 + /* New gain multplier must be between 25% and 75% of old range (note that gainMult_upper < gainMult_lower) */ 1.282 + if( gainMult_Q8 > silk_ADD_RSHIFT32( gainMult_lower, gainMult_upper - gainMult_lower, 2 ) ) { 1.283 + gainMult_Q8 = silk_ADD_RSHIFT32( gainMult_lower, gainMult_upper - gainMult_lower, 2 ); 1.284 + } else 1.285 + if( gainMult_Q8 < silk_SUB_RSHIFT32( gainMult_upper, gainMult_upper - gainMult_lower, 2 ) ) { 1.286 + gainMult_Q8 = silk_SUB_RSHIFT32( gainMult_upper, gainMult_upper - gainMult_lower, 2 ); 1.287 + } 1.288 + } 1.289 + 1.290 + for( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) { 1.291 + sEncCtrl.Gains_Q16[ i ] = silk_LSHIFT_SAT32( silk_SMULWB( sEncCtrl.GainsUnq_Q16[ i ], gainMult_Q8 ), 8 ); 1.292 + } 1.293 + 1.294 + /* Quantize gains */ 1.295 + psEnc->sShape.LastGainIndex = sEncCtrl.lastGainIndexPrev; 1.296 + silk_gains_quant( psEnc->sCmn.indices.GainsIndices, sEncCtrl.Gains_Q16, 1.297 + &psEnc->sShape.LastGainIndex, condCoding == CODE_CONDITIONALLY, psEnc->sCmn.nb_subfr ); 1.298 + 1.299 + /* Unique identifier of gains vector */ 1.300 + gainsID = silk_gains_ID( psEnc->sCmn.indices.GainsIndices, psEnc->sCmn.nb_subfr ); 1.301 + } 1.302 + } 1.303 + 1.304 + /* Update input buffer */ 1.305 + silk_memmove( psEnc->x_buf, &psEnc->x_buf[ psEnc->sCmn.frame_length ], 1.306 + ( psEnc->sCmn.ltp_mem_length + LA_SHAPE_MS * psEnc->sCmn.fs_kHz ) * sizeof( opus_int16 ) ); 1.307 + 1.308 + /* Exit without entropy coding */ 1.309 + if( psEnc->sCmn.prefillFlag ) { 1.310 + /* No payload */ 1.311 + *pnBytesOut = 0; 1.312 + RESTORE_STACK; 1.313 + return ret; 1.314 + } 1.315 + 1.316 + /* Parameters needed for next frame */ 1.317 + psEnc->sCmn.prevLag = sEncCtrl.pitchL[ psEnc->sCmn.nb_subfr - 1 ]; 1.318 + psEnc->sCmn.prevSignalType = psEnc->sCmn.indices.signalType; 1.319 + 1.320 + /****************************************/ 1.321 + /* Finalize payload */ 1.322 + /****************************************/ 1.323 + psEnc->sCmn.first_frame_after_reset = 0; 1.324 + /* Payload size */ 1.325 + *pnBytesOut = silk_RSHIFT( ec_tell( psRangeEnc ) + 7, 3 ); 1.326 + 1.327 + RESTORE_STACK; 1.328 + return ret; 1.329 +} 1.330 + 1.331 +/* Low-Bitrate Redundancy (LBRR) encoding. Reuse all parameters but encode excitation at lower bitrate */ 1.332 +static OPUS_INLINE void silk_LBRR_encode_FIX( 1.333 + silk_encoder_state_FIX *psEnc, /* I/O Pointer to Silk FIX encoder state */ 1.334 + silk_encoder_control_FIX *psEncCtrl, /* I/O Pointer to Silk FIX encoder control struct */ 1.335 + const opus_int32 xfw_Q3[], /* I Input signal */ 1.336 + opus_int condCoding /* I The type of conditional coding used so far for this frame */ 1.337 +) 1.338 +{ 1.339 + opus_int32 TempGains_Q16[ MAX_NB_SUBFR ]; 1.340 + SideInfoIndices *psIndices_LBRR = &psEnc->sCmn.indices_LBRR[ psEnc->sCmn.nFramesEncoded ]; 1.341 + silk_nsq_state sNSQ_LBRR; 1.342 + 1.343 + /*******************************************/ 1.344 + /* Control use of inband LBRR */ 1.345 + /*******************************************/ 1.346 + if( psEnc->sCmn.LBRR_enabled && psEnc->sCmn.speech_activity_Q8 > SILK_FIX_CONST( LBRR_SPEECH_ACTIVITY_THRES, 8 ) ) { 1.347 + psEnc->sCmn.LBRR_flags[ psEnc->sCmn.nFramesEncoded ] = 1; 1.348 + 1.349 + /* Copy noise shaping quantizer state and quantization indices from regular encoding */ 1.350 + silk_memcpy( &sNSQ_LBRR, &psEnc->sCmn.sNSQ, sizeof( silk_nsq_state ) ); 1.351 + silk_memcpy( psIndices_LBRR, &psEnc->sCmn.indices, sizeof( SideInfoIndices ) ); 1.352 + 1.353 + /* Save original gains */ 1.354 + silk_memcpy( TempGains_Q16, psEncCtrl->Gains_Q16, psEnc->sCmn.nb_subfr * sizeof( opus_int32 ) ); 1.355 + 1.356 + if( psEnc->sCmn.nFramesEncoded == 0 || psEnc->sCmn.LBRR_flags[ psEnc->sCmn.nFramesEncoded - 1 ] == 0 ) { 1.357 + /* First frame in packet or previous frame not LBRR coded */ 1.358 + psEnc->sCmn.LBRRprevLastGainIndex = psEnc->sShape.LastGainIndex; 1.359 + 1.360 + /* Increase Gains to get target LBRR rate */ 1.361 + psIndices_LBRR->GainsIndices[ 0 ] = psIndices_LBRR->GainsIndices[ 0 ] + psEnc->sCmn.LBRR_GainIncreases; 1.362 + psIndices_LBRR->GainsIndices[ 0 ] = silk_min_int( psIndices_LBRR->GainsIndices[ 0 ], N_LEVELS_QGAIN - 1 ); 1.363 + } 1.364 + 1.365 + /* Decode to get gains in sync with decoder */ 1.366 + /* Overwrite unquantized gains with quantized gains */ 1.367 + silk_gains_dequant( psEncCtrl->Gains_Q16, psIndices_LBRR->GainsIndices, 1.368 + &psEnc->sCmn.LBRRprevLastGainIndex, condCoding == CODE_CONDITIONALLY, psEnc->sCmn.nb_subfr ); 1.369 + 1.370 + /*****************************************/ 1.371 + /* Noise shaping quantization */ 1.372 + /*****************************************/ 1.373 + if( psEnc->sCmn.nStatesDelayedDecision > 1 || psEnc->sCmn.warping_Q16 > 0 ) { 1.374 + silk_NSQ_del_dec( &psEnc->sCmn, &sNSQ_LBRR, psIndices_LBRR, xfw_Q3, 1.375 + psEnc->sCmn.pulses_LBRR[ psEnc->sCmn.nFramesEncoded ], psEncCtrl->PredCoef_Q12[ 0 ], psEncCtrl->LTPCoef_Q14, 1.376 + psEncCtrl->AR2_Q13, psEncCtrl->HarmShapeGain_Q14, psEncCtrl->Tilt_Q14, psEncCtrl->LF_shp_Q14, 1.377 + psEncCtrl->Gains_Q16, psEncCtrl->pitchL, psEncCtrl->Lambda_Q10, psEncCtrl->LTP_scale_Q14 ); 1.378 + } else { 1.379 + silk_NSQ( &psEnc->sCmn, &sNSQ_LBRR, psIndices_LBRR, xfw_Q3, 1.380 + psEnc->sCmn.pulses_LBRR[ psEnc->sCmn.nFramesEncoded ], psEncCtrl->PredCoef_Q12[ 0 ], psEncCtrl->LTPCoef_Q14, 1.381 + psEncCtrl->AR2_Q13, psEncCtrl->HarmShapeGain_Q14, psEncCtrl->Tilt_Q14, psEncCtrl->LF_shp_Q14, 1.382 + psEncCtrl->Gains_Q16, psEncCtrl->pitchL, psEncCtrl->Lambda_Q10, psEncCtrl->LTP_scale_Q14 ); 1.383 + } 1.384 + 1.385 + /* Restore original gains */ 1.386 + silk_memcpy( psEncCtrl->Gains_Q16, TempGains_Q16, psEnc->sCmn.nb_subfr * sizeof( opus_int32 ) ); 1.387 + } 1.388 +}