encode_frame_FIX.c (24314B)
1 /*********************************************************************** 2 Copyright (c) 2006-2011, Skype Limited. All rights reserved. 3 Redistribution and use in source and binary forms, with or without 4 modification, are permitted provided that the following conditions 5 are met: 6 - Redistributions of source code must retain the above copyright notice, 7 this list of conditions and the following disclaimer. 8 - Redistributions in binary form must reproduce the above copyright 9 notice, this list of conditions and the following disclaimer in the 10 documentation and/or other materials provided with the distribution. 11 - Neither the name of Internet Society, IETF or IETF Trust, nor the 12 names of specific contributors, may be used to endorse or promote 13 products derived from this software without specific prior written 14 permission. 15 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 16 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 19 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 20 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 21 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 22 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 23 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 24 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 25 POSSIBILITY OF SUCH DAMAGE. 26 ***********************************************************************/ 27 28 #ifdef HAVE_CONFIG_H 29 #include "config.h" 30 #endif 31 32 #include <stdlib.h> 33 #include "main_FIX.h" 34 #include "stack_alloc.h" 35 #include "tuning_parameters.h" 36 37 /* Low Bitrate Redundancy (LBRR) encoding. Reuse all parameters but encode with lower bitrate */ 38 static OPUS_INLINE void silk_LBRR_encode_FIX( 39 silk_encoder_state_FIX *psEnc, /* I/O Pointer to Silk FIX encoder state */ 40 silk_encoder_control_FIX *psEncCtrl, /* I/O Pointer to Silk FIX encoder control struct */ 41 const opus_int16 x16[], /* I Input signal */ 42 opus_int condCoding /* I The type of conditional coding used so far for this frame */ 43 ); 44 45 void silk_encode_do_VAD_FIX( 46 silk_encoder_state_FIX *psEnc, /* I/O Pointer to Silk FIX encoder state */ 47 opus_int activity /* I Decision of Opus voice activity detector */ 48 ) 49 { 50 const opus_int activity_threshold = SILK_FIX_CONST( SPEECH_ACTIVITY_DTX_THRES, 8 ); 51 52 /****************************/ 53 /* Voice Activity Detection */ 54 /****************************/ 55 silk_VAD_GetSA_Q8( &psEnc->sCmn, psEnc->sCmn.inputBuf + 1, psEnc->sCmn.arch ); 56 /* If Opus VAD is inactive and Silk VAD is active: lower Silk VAD to just under the threshold */ 57 if( activity == VAD_NO_ACTIVITY && psEnc->sCmn.speech_activity_Q8 >= activity_threshold ) { 58 psEnc->sCmn.speech_activity_Q8 = activity_threshold - 1; 59 } 60 61 /**************************************************/ 62 /* Convert speech activity into VAD and DTX flags */ 63 /**************************************************/ 64 if( psEnc->sCmn.speech_activity_Q8 < activity_threshold ) { 65 psEnc->sCmn.indices.signalType = TYPE_NO_VOICE_ACTIVITY; 66 psEnc->sCmn.noSpeechCounter++; 67 if( psEnc->sCmn.noSpeechCounter <= NB_SPEECH_FRAMES_BEFORE_DTX ) { 68 psEnc->sCmn.inDTX = 0; 69 } else if( psEnc->sCmn.noSpeechCounter > MAX_CONSECUTIVE_DTX + NB_SPEECH_FRAMES_BEFORE_DTX ) { 70 psEnc->sCmn.noSpeechCounter = NB_SPEECH_FRAMES_BEFORE_DTX; 71 psEnc->sCmn.inDTX = 0; 72 } 73 psEnc->sCmn.VAD_flags[ psEnc->sCmn.nFramesEncoded ] = 0; 74 } else { 75 psEnc->sCmn.noSpeechCounter = 0; 76 psEnc->sCmn.inDTX = 0; 77 psEnc->sCmn.indices.signalType = TYPE_UNVOICED; 78 psEnc->sCmn.VAD_flags[ psEnc->sCmn.nFramesEncoded ] = 1; 79 } 80 } 81 82 /****************/ 83 /* Encode frame */ 84 /****************/ 85 opus_int silk_encode_frame_FIX( 86 silk_encoder_state_FIX *psEnc, /* I/O Pointer to Silk FIX encoder state */ 87 opus_int32 *pnBytesOut, /* O Pointer to number of payload bytes; */ 88 ec_enc *psRangeEnc, /* I/O compressor data structure */ 89 opus_int condCoding, /* I The type of conditional coding to use */ 90 opus_int maxBits, /* I If > 0: maximum number of output bits */ 91 opus_int useCBR /* I Flag to force constant-bitrate operation */ 92 ) 93 { 94 silk_encoder_control_FIX sEncCtrl; 95 opus_int i, iter, maxIter, found_upper, found_lower, ret = 0; 96 opus_int16 *x_frame; 97 ec_enc sRangeEnc_copy, sRangeEnc_copy2; 98 VARDECL(silk_nsq_state, sNSQ_copy); 99 opus_int32 seed_copy, nBits, nBits_lower, nBits_upper, gainMult_lower, gainMult_upper; 100 opus_int32 gainsID, gainsID_lower, gainsID_upper; 101 opus_int16 gainMult_Q8; 102 opus_int16 ec_prevLagIndex_copy; 103 opus_int ec_prevSignalType_copy; 104 opus_int8 LastGainIndex_copy2; 105 opus_int gain_lock[ MAX_NB_SUBFR ] = {0}; 106 opus_int16 best_gain_mult[ MAX_NB_SUBFR ]; 107 opus_int best_sum[ MAX_NB_SUBFR ]; 108 opus_int bits_margin; 109 SAVE_STACK; 110 111 /* Using ALLOC() instead of a regular stack allocation to minimize real stack use when using the pseudostack. 112 This is useful on some embedded systems. */ 113 ALLOC(sNSQ_copy, 2, silk_nsq_state); 114 115 /* For CBR, 5 bits below budget is close enough. For VBR, allow up to 25% below the cap if we initially busted the budget. */ 116 bits_margin = useCBR ? 5 : maxBits/4; 117 /* This is totally unnecessary but many compilers (including gcc) are too dumb to realise it */ 118 LastGainIndex_copy2 = nBits_lower = nBits_upper = gainMult_lower = gainMult_upper = 0; 119 120 psEnc->sCmn.indices.Seed = psEnc->sCmn.frameCounter++ & 3; 121 122 /**************************************************************/ 123 /* Set up Input Pointers, and insert frame in input buffer */ 124 /*************************************************************/ 125 /* start of frame to encode */ 126 x_frame = psEnc->x_buf + psEnc->sCmn.ltp_mem_length; 127 128 /***************************************/ 129 /* Ensure smooth bandwidth transitions */ 130 /***************************************/ 131 silk_LP_variable_cutoff( &psEnc->sCmn.sLP, psEnc->sCmn.inputBuf + 1, psEnc->sCmn.frame_length ); 132 133 /*******************************************/ 134 /* Copy new frame to front of input buffer */ 135 /*******************************************/ 136 silk_memcpy( x_frame + LA_SHAPE_MS * psEnc->sCmn.fs_kHz, psEnc->sCmn.inputBuf + 1, psEnc->sCmn.frame_length * sizeof( opus_int16 ) ); 137 138 if( !psEnc->sCmn.prefillFlag ) { 139 VARDECL( opus_int16, res_pitch ); 140 VARDECL( opus_uint8, ec_buf_copy ); 141 opus_int16 *res_pitch_frame; 142 143 ALLOC( res_pitch, 144 psEnc->sCmn.la_pitch + psEnc->sCmn.frame_length 145 + psEnc->sCmn.ltp_mem_length, opus_int16 ); 146 /* start of pitch LPC residual frame */ 147 res_pitch_frame = res_pitch + psEnc->sCmn.ltp_mem_length; 148 149 /*****************************************/ 150 /* Find pitch lags, initial LPC analysis */ 151 /*****************************************/ 152 silk_find_pitch_lags_FIX( psEnc, &sEncCtrl, res_pitch, x_frame - psEnc->sCmn.ltp_mem_length, psEnc->sCmn.arch ); 153 154 /************************/ 155 /* Noise shape analysis */ 156 /************************/ 157 silk_noise_shape_analysis_FIX( psEnc, &sEncCtrl, res_pitch_frame, x_frame, psEnc->sCmn.arch ); 158 159 /***************************************************/ 160 /* Find linear prediction coefficients (LPC + LTP) */ 161 /***************************************************/ 162 silk_find_pred_coefs_FIX( psEnc, &sEncCtrl, res_pitch_frame, x_frame, condCoding ); 163 164 /****************************************/ 165 /* Process gains */ 166 /****************************************/ 167 silk_process_gains_FIX( psEnc, &sEncCtrl, condCoding ); 168 169 /****************************************/ 170 /* Low Bitrate Redundant Encoding */ 171 /****************************************/ 172 silk_LBRR_encode_FIX( psEnc, &sEncCtrl, x_frame, condCoding ); 173 174 /* Loop over quantizer and entropy coding to control bitrate */ 175 maxIter = 6; 176 gainMult_Q8 = SILK_FIX_CONST( 1, 8 ); 177 found_lower = 0; 178 found_upper = 0; 179 gainsID = silk_gains_ID( psEnc->sCmn.indices.GainsIndices, psEnc->sCmn.nb_subfr ); 180 gainsID_lower = -1; 181 gainsID_upper = -1; 182 /* Copy part of the input state */ 183 silk_memcpy( &sRangeEnc_copy, psRangeEnc, sizeof( ec_enc ) ); 184 silk_memcpy( &sNSQ_copy[0], &psEnc->sCmn.sNSQ, sizeof( silk_nsq_state ) ); 185 seed_copy = psEnc->sCmn.indices.Seed; 186 ec_prevLagIndex_copy = psEnc->sCmn.ec_prevLagIndex; 187 ec_prevSignalType_copy = psEnc->sCmn.ec_prevSignalType; 188 ALLOC( ec_buf_copy, 1275, opus_uint8 ); 189 for( iter = 0; ; iter++ ) { 190 if( gainsID == gainsID_lower ) { 191 nBits = nBits_lower; 192 } else if( gainsID == gainsID_upper ) { 193 nBits = nBits_upper; 194 } else { 195 /* Restore part of the input state */ 196 if( iter > 0 ) { 197 silk_memcpy( psRangeEnc, &sRangeEnc_copy, sizeof( ec_enc ) ); 198 silk_memcpy( &psEnc->sCmn.sNSQ, &sNSQ_copy[0], sizeof( silk_nsq_state ) ); 199 psEnc->sCmn.indices.Seed = seed_copy; 200 psEnc->sCmn.ec_prevLagIndex = ec_prevLagIndex_copy; 201 psEnc->sCmn.ec_prevSignalType = ec_prevSignalType_copy; 202 } 203 204 /*****************************************/ 205 /* Noise shaping quantization */ 206 /*****************************************/ 207 if( psEnc->sCmn.nStatesDelayedDecision > 1 || psEnc->sCmn.warping_Q16 > 0 ) { 208 silk_NSQ_del_dec( &psEnc->sCmn, &psEnc->sCmn.sNSQ, &psEnc->sCmn.indices, x_frame, psEnc->sCmn.pulses, 209 sEncCtrl.PredCoef_Q12[ 0 ], sEncCtrl.LTPCoef_Q14, sEncCtrl.AR_Q13, sEncCtrl.HarmShapeGain_Q14, 210 sEncCtrl.Tilt_Q14, sEncCtrl.LF_shp_Q14, sEncCtrl.Gains_Q16, sEncCtrl.pitchL, sEncCtrl.Lambda_Q10, sEncCtrl.LTP_scale_Q14, 211 psEnc->sCmn.arch ); 212 } else { 213 silk_NSQ( &psEnc->sCmn, &psEnc->sCmn.sNSQ, &psEnc->sCmn.indices, x_frame, psEnc->sCmn.pulses, 214 sEncCtrl.PredCoef_Q12[ 0 ], sEncCtrl.LTPCoef_Q14, sEncCtrl.AR_Q13, sEncCtrl.HarmShapeGain_Q14, 215 sEncCtrl.Tilt_Q14, sEncCtrl.LF_shp_Q14, sEncCtrl.Gains_Q16, sEncCtrl.pitchL, sEncCtrl.Lambda_Q10, sEncCtrl.LTP_scale_Q14, 216 psEnc->sCmn.arch); 217 } 218 219 if ( iter == maxIter && !found_lower ) { 220 silk_memcpy( &sRangeEnc_copy2, psRangeEnc, sizeof( ec_enc ) ); 221 } 222 223 /****************************************/ 224 /* Encode Parameters */ 225 /****************************************/ 226 silk_encode_indices( &psEnc->sCmn, psRangeEnc, psEnc->sCmn.nFramesEncoded, 0, condCoding ); 227 228 /****************************************/ 229 /* Encode Excitation Signal */ 230 /****************************************/ 231 silk_encode_pulses( psRangeEnc, psEnc->sCmn.indices.signalType, psEnc->sCmn.indices.quantOffsetType, 232 psEnc->sCmn.pulses, psEnc->sCmn.frame_length ); 233 234 nBits = ec_tell( psRangeEnc ); 235 236 /* If we still bust after the last iteration, do some damage control. */ 237 if ( iter == maxIter && !found_lower && nBits > maxBits ) { 238 silk_memcpy( psRangeEnc, &sRangeEnc_copy2, sizeof( ec_enc ) ); 239 240 /* Keep gains the same as the last frame. */ 241 psEnc->sShape.LastGainIndex = sEncCtrl.lastGainIndexPrev; 242 for ( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) { 243 psEnc->sCmn.indices.GainsIndices[ i ] = 4; 244 } 245 if (condCoding != CODE_CONDITIONALLY) { 246 psEnc->sCmn.indices.GainsIndices[ 0 ] = sEncCtrl.lastGainIndexPrev; 247 } 248 psEnc->sCmn.ec_prevLagIndex = ec_prevLagIndex_copy; 249 psEnc->sCmn.ec_prevSignalType = ec_prevSignalType_copy; 250 /* Clear all pulses. */ 251 for ( i = 0; i < psEnc->sCmn.frame_length; i++ ) { 252 psEnc->sCmn.pulses[ i ] = 0; 253 } 254 255 silk_encode_indices( &psEnc->sCmn, psRangeEnc, psEnc->sCmn.nFramesEncoded, 0, condCoding ); 256 257 silk_encode_pulses( psRangeEnc, psEnc->sCmn.indices.signalType, psEnc->sCmn.indices.quantOffsetType, 258 psEnc->sCmn.pulses, psEnc->sCmn.frame_length ); 259 260 nBits = ec_tell( psRangeEnc ); 261 } 262 263 if( useCBR == 0 && iter == 0 && nBits <= maxBits ) { 264 break; 265 } 266 } 267 268 if( iter == maxIter ) { 269 if( found_lower && ( gainsID == gainsID_lower || nBits > maxBits ) ) { 270 /* Restore output state from earlier iteration that did meet the bitrate budget */ 271 silk_memcpy( psRangeEnc, &sRangeEnc_copy2, sizeof( ec_enc ) ); 272 celt_assert( sRangeEnc_copy2.offs <= 1275 ); 273 silk_memcpy( psRangeEnc->buf, ec_buf_copy, sRangeEnc_copy2.offs ); 274 silk_memcpy( &psEnc->sCmn.sNSQ, &sNSQ_copy[1], sizeof( silk_nsq_state ) ); 275 psEnc->sShape.LastGainIndex = LastGainIndex_copy2; 276 } 277 break; 278 } 279 280 if( nBits > maxBits ) { 281 if( found_lower == 0 && iter >= 2 ) { 282 /* Adjust the quantizer's rate/distortion tradeoff and discard previous "upper" results */ 283 sEncCtrl.Lambda_Q10 = silk_ADD_RSHIFT32( sEncCtrl.Lambda_Q10, sEncCtrl.Lambda_Q10, 1 ); 284 found_upper = 0; 285 gainsID_upper = -1; 286 } else { 287 found_upper = 1; 288 nBits_upper = nBits; 289 gainMult_upper = gainMult_Q8; 290 gainsID_upper = gainsID; 291 } 292 } else if( nBits < maxBits - bits_margin ) { 293 found_lower = 1; 294 nBits_lower = nBits; 295 gainMult_lower = gainMult_Q8; 296 if( gainsID != gainsID_lower ) { 297 gainsID_lower = gainsID; 298 /* Copy part of the output state */ 299 silk_memcpy( &sRangeEnc_copy2, psRangeEnc, sizeof( ec_enc ) ); 300 celt_assert( psRangeEnc->offs <= 1275 ); 301 silk_memcpy( ec_buf_copy, psRangeEnc->buf, psRangeEnc->offs ); 302 silk_memcpy( &sNSQ_copy[1], &psEnc->sCmn.sNSQ, sizeof( silk_nsq_state ) ); 303 LastGainIndex_copy2 = psEnc->sShape.LastGainIndex; 304 } 305 } else { 306 /* Close enough */ 307 break; 308 } 309 310 if ( !found_lower && nBits > maxBits ) { 311 int j; 312 for ( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) { 313 int sum=0; 314 for ( j = i*psEnc->sCmn.subfr_length; j < (i+1)*psEnc->sCmn.subfr_length; j++ ) { 315 sum += abs( psEnc->sCmn.pulses[j] ); 316 } 317 if ( iter == 0 || (sum < best_sum[i] && !gain_lock[i]) ) { 318 best_sum[i] = sum; 319 best_gain_mult[i] = gainMult_Q8; 320 } else { 321 gain_lock[i] = 1; 322 } 323 } 324 } 325 if( ( found_lower & found_upper ) == 0 ) { 326 /* Adjust gain according to high-rate rate/distortion curve */ 327 if( nBits > maxBits ) { 328 gainMult_Q8 = silk_min_32( 1024, gainMult_Q8*3/2 ); 329 } else { 330 gainMult_Q8 = silk_max_32( 64, gainMult_Q8*4/5 ); 331 } 332 } else { 333 /* Adjust gain by interpolating */ 334 gainMult_Q8 = gainMult_lower + silk_DIV32_16( silk_MUL( gainMult_upper - gainMult_lower, maxBits - nBits_lower ), nBits_upper - nBits_lower ); 335 /* New gain multiplier must be between 25% and 75% of old range (note that gainMult_upper < gainMult_lower) */ 336 if( gainMult_Q8 > silk_ADD_RSHIFT32( gainMult_lower, gainMult_upper - gainMult_lower, 2 ) ) { 337 gainMult_Q8 = silk_ADD_RSHIFT32( gainMult_lower, gainMult_upper - gainMult_lower, 2 ); 338 } else 339 if( gainMult_Q8 < silk_SUB_RSHIFT32( gainMult_upper, gainMult_upper - gainMult_lower, 2 ) ) { 340 gainMult_Q8 = silk_SUB_RSHIFT32( gainMult_upper, gainMult_upper - gainMult_lower, 2 ); 341 } 342 } 343 344 for( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) { 345 opus_int16 tmp; 346 if ( gain_lock[i] ) { 347 tmp = best_gain_mult[i]; 348 } else { 349 tmp = gainMult_Q8; 350 } 351 sEncCtrl.Gains_Q16[ i ] = silk_LSHIFT_SAT32( silk_SMULWB( sEncCtrl.GainsUnq_Q16[ i ], tmp ), 8 ); 352 } 353 354 /* Quantize gains */ 355 psEnc->sShape.LastGainIndex = sEncCtrl.lastGainIndexPrev; 356 silk_gains_quant( psEnc->sCmn.indices.GainsIndices, sEncCtrl.Gains_Q16, 357 &psEnc->sShape.LastGainIndex, condCoding == CODE_CONDITIONALLY, psEnc->sCmn.nb_subfr ); 358 359 /* Unique identifier of gains vector */ 360 gainsID = silk_gains_ID( psEnc->sCmn.indices.GainsIndices, psEnc->sCmn.nb_subfr ); 361 } 362 } 363 364 /* Update input buffer */ 365 silk_memmove( psEnc->x_buf, &psEnc->x_buf[ psEnc->sCmn.frame_length ], 366 ( psEnc->sCmn.ltp_mem_length + LA_SHAPE_MS * psEnc->sCmn.fs_kHz ) * sizeof( opus_int16 ) ); 367 368 /* Exit without entropy coding */ 369 if( psEnc->sCmn.prefillFlag ) { 370 /* No payload */ 371 *pnBytesOut = 0; 372 RESTORE_STACK; 373 return ret; 374 } 375 376 /* Parameters needed for next frame */ 377 psEnc->sCmn.prevLag = sEncCtrl.pitchL[ psEnc->sCmn.nb_subfr - 1 ]; 378 psEnc->sCmn.prevSignalType = psEnc->sCmn.indices.signalType; 379 380 /****************************************/ 381 /* Finalize payload */ 382 /****************************************/ 383 psEnc->sCmn.first_frame_after_reset = 0; 384 /* Payload size */ 385 *pnBytesOut = silk_RSHIFT( ec_tell( psRangeEnc ) + 7, 3 ); 386 387 RESTORE_STACK; 388 return ret; 389 } 390 391 /* Low-Bitrate Redundancy (LBRR) encoding. Reuse all parameters but encode excitation at lower bitrate */ 392 static OPUS_INLINE void silk_LBRR_encode_FIX( 393 silk_encoder_state_FIX *psEnc, /* I/O Pointer to Silk FIX encoder state */ 394 silk_encoder_control_FIX *psEncCtrl, /* I/O Pointer to Silk FIX encoder control struct */ 395 const opus_int16 x16[], /* I Input signal */ 396 opus_int condCoding /* I The type of conditional coding used so far for this frame */ 397 ) 398 { 399 opus_int32 TempGains_Q16[ MAX_NB_SUBFR ]; 400 SideInfoIndices *psIndices_LBRR = &psEnc->sCmn.indices_LBRR[ psEnc->sCmn.nFramesEncoded ]; 401 VARDECL(silk_nsq_state, sNSQ_LBRR); 402 SAVE_STACK; 403 404 /*******************************************/ 405 /* Control use of inband LBRR */ 406 /*******************************************/ 407 if( psEnc->sCmn.LBRR_enabled && psEnc->sCmn.speech_activity_Q8 > SILK_FIX_CONST( LBRR_SPEECH_ACTIVITY_THRES, 8 ) ) { 408 /* Using ALLOC() instead of a regular stack allocation to minimize real stack use when using the pseudostack. 409 This is useful on some embedded systems. */ 410 ALLOC(sNSQ_LBRR, 1, silk_nsq_state); 411 412 psEnc->sCmn.LBRR_flags[ psEnc->sCmn.nFramesEncoded ] = 1; 413 414 /* Copy noise shaping quantizer state and quantization indices from regular encoding */ 415 silk_memcpy( &sNSQ_LBRR[0], &psEnc->sCmn.sNSQ, sizeof( silk_nsq_state ) ); 416 silk_memcpy( psIndices_LBRR, &psEnc->sCmn.indices, sizeof( SideInfoIndices ) ); 417 418 /* Save original gains */ 419 silk_memcpy( TempGains_Q16, psEncCtrl->Gains_Q16, psEnc->sCmn.nb_subfr * sizeof( opus_int32 ) ); 420 421 if( psEnc->sCmn.nFramesEncoded == 0 || psEnc->sCmn.LBRR_flags[ psEnc->sCmn.nFramesEncoded - 1 ] == 0 ) { 422 /* First frame in packet or previous frame not LBRR coded */ 423 psEnc->sCmn.LBRRprevLastGainIndex = psEnc->sShape.LastGainIndex; 424 425 /* Increase Gains to get target LBRR rate */ 426 psIndices_LBRR->GainsIndices[ 0 ] = psIndices_LBRR->GainsIndices[ 0 ] + psEnc->sCmn.LBRR_GainIncreases; 427 psIndices_LBRR->GainsIndices[ 0 ] = silk_min_int( psIndices_LBRR->GainsIndices[ 0 ], N_LEVELS_QGAIN - 1 ); 428 } 429 430 /* Decode to get gains in sync with decoder */ 431 /* Overwrite unquantized gains with quantized gains */ 432 silk_gains_dequant( psEncCtrl->Gains_Q16, psIndices_LBRR->GainsIndices, 433 &psEnc->sCmn.LBRRprevLastGainIndex, condCoding == CODE_CONDITIONALLY, psEnc->sCmn.nb_subfr ); 434 435 /*****************************************/ 436 /* Noise shaping quantization */ 437 /*****************************************/ 438 if( psEnc->sCmn.nStatesDelayedDecision > 1 || psEnc->sCmn.warping_Q16 > 0 ) { 439 silk_NSQ_del_dec( &psEnc->sCmn, &sNSQ_LBRR[0], psIndices_LBRR, x16, 440 psEnc->sCmn.pulses_LBRR[ psEnc->sCmn.nFramesEncoded ], psEncCtrl->PredCoef_Q12[ 0 ], psEncCtrl->LTPCoef_Q14, 441 psEncCtrl->AR_Q13, psEncCtrl->HarmShapeGain_Q14, psEncCtrl->Tilt_Q14, psEncCtrl->LF_shp_Q14, 442 psEncCtrl->Gains_Q16, psEncCtrl->pitchL, psEncCtrl->Lambda_Q10, psEncCtrl->LTP_scale_Q14, psEnc->sCmn.arch ); 443 } else { 444 silk_NSQ( &psEnc->sCmn, &sNSQ_LBRR[0], psIndices_LBRR, x16, 445 psEnc->sCmn.pulses_LBRR[ psEnc->sCmn.nFramesEncoded ], psEncCtrl->PredCoef_Q12[ 0 ], psEncCtrl->LTPCoef_Q14, 446 psEncCtrl->AR_Q13, psEncCtrl->HarmShapeGain_Q14, psEncCtrl->Tilt_Q14, psEncCtrl->LF_shp_Q14, 447 psEncCtrl->Gains_Q16, psEncCtrl->pitchL, psEncCtrl->Lambda_Q10, psEncCtrl->LTP_scale_Q14, psEnc->sCmn.arch ); 448 } 449 450 /* Restore original gains */ 451 silk_memcpy( psEncCtrl->Gains_Q16, TempGains_Q16, psEnc->sCmn.nb_subfr * sizeof( opus_int32 ) ); 452 } 453 RESTORE_STACK; 454 }