Hardening silk/fixed
[opus.git] / silk / fixed / encode_frame_FIX.c
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 )
48 {
49     /****************************/
50     /* Voice Activity Detection */
51     /****************************/
52     silk_VAD_GetSA_Q8( &psEnc->sCmn, psEnc->sCmn.inputBuf + 1, psEnc->sCmn.arch );
53
54     /**************************************************/
55     /* Convert speech activity into VAD and DTX flags */
56     /**************************************************/
57     if( psEnc->sCmn.speech_activity_Q8 < SILK_FIX_CONST( SPEECH_ACTIVITY_DTX_THRES, 8 ) ) {
58         psEnc->sCmn.indices.signalType = TYPE_NO_VOICE_ACTIVITY;
59         psEnc->sCmn.noSpeechCounter++;
60         if( psEnc->sCmn.noSpeechCounter <= NB_SPEECH_FRAMES_BEFORE_DTX ) {
61             psEnc->sCmn.inDTX = 0;
62         } else if( psEnc->sCmn.noSpeechCounter > MAX_CONSECUTIVE_DTX + NB_SPEECH_FRAMES_BEFORE_DTX ) {
63             psEnc->sCmn.noSpeechCounter = NB_SPEECH_FRAMES_BEFORE_DTX;
64             psEnc->sCmn.inDTX           = 0;
65         }
66         psEnc->sCmn.VAD_flags[ psEnc->sCmn.nFramesEncoded ] = 0;
67     } else {
68         psEnc->sCmn.noSpeechCounter    = 0;
69         psEnc->sCmn.inDTX              = 0;
70         psEnc->sCmn.indices.signalType = TYPE_UNVOICED;
71         psEnc->sCmn.VAD_flags[ psEnc->sCmn.nFramesEncoded ] = 1;
72     }
73 }
74
75 /****************/
76 /* Encode frame */
77 /****************/
78 opus_int silk_encode_frame_FIX(
79     silk_encoder_state_FIX          *psEnc,                                 /* I/O  Pointer to Silk FIX encoder state                                           */
80     opus_int32                      *pnBytesOut,                            /* O    Pointer to number of payload bytes;                                         */
81     ec_enc                          *psRangeEnc,                            /* I/O  compressor data structure                                                   */
82     opus_int                        condCoding,                             /* I    The type of conditional coding to use                                       */
83     opus_int                        maxBits,                                /* I    If > 0: maximum number of output bits                                       */
84     opus_int                        useCBR                                  /* I    Flag to force constant-bitrate operation                                    */
85 )
86 {
87     silk_encoder_control_FIX sEncCtrl;
88     opus_int     i, iter, maxIter, found_upper, found_lower, ret = 0;
89     opus_int16   *x_frame;
90     ec_enc       sRangeEnc_copy, sRangeEnc_copy2;
91     silk_nsq_state sNSQ_copy, sNSQ_copy2;
92     opus_int32   seed_copy, nBits, nBits_lower, nBits_upper, gainMult_lower, gainMult_upper;
93     opus_int32   gainsID, gainsID_lower, gainsID_upper;
94     opus_int16   gainMult_Q8;
95     opus_int16   ec_prevLagIndex_copy;
96     opus_int     ec_prevSignalType_copy;
97     opus_int8    LastGainIndex_copy2;
98     opus_int     gain_lock[ MAX_NB_SUBFR ] = {0};
99     opus_int16   best_gain_mult[ MAX_NB_SUBFR ];
100     opus_int     best_sum[ MAX_NB_SUBFR ];
101     SAVE_STACK;
102
103     /* This is totally unnecessary but many compilers (including gcc) are too dumb to realise it */
104     LastGainIndex_copy2 = nBits_lower = nBits_upper = gainMult_lower = gainMult_upper = 0;
105
106     psEnc->sCmn.indices.Seed = psEnc->sCmn.frameCounter++ & 3;
107
108     /**************************************************************/
109     /* Set up Input Pointers, and insert frame in input buffer   */
110     /*************************************************************/
111     /* start of frame to encode */
112     x_frame = psEnc->x_buf + psEnc->sCmn.ltp_mem_length;
113
114     /***************************************/
115     /* Ensure smooth bandwidth transitions */
116     /***************************************/
117     silk_LP_variable_cutoff( &psEnc->sCmn.sLP, psEnc->sCmn.inputBuf + 1, psEnc->sCmn.frame_length );
118
119     /*******************************************/
120     /* Copy new frame to front of input buffer */
121     /*******************************************/
122     silk_memcpy( x_frame + LA_SHAPE_MS * psEnc->sCmn.fs_kHz, psEnc->sCmn.inputBuf + 1, psEnc->sCmn.frame_length * sizeof( opus_int16 ) );
123
124     if( !psEnc->sCmn.prefillFlag ) {
125         VARDECL( opus_int16, res_pitch );
126         VARDECL( opus_uint8, ec_buf_copy );
127         opus_int16 *res_pitch_frame;
128
129         ALLOC( res_pitch,
130                psEnc->sCmn.la_pitch + psEnc->sCmn.frame_length
131                    + psEnc->sCmn.ltp_mem_length, opus_int16 );
132         /* start of pitch LPC residual frame */
133         res_pitch_frame = res_pitch + psEnc->sCmn.ltp_mem_length;
134
135         /*****************************************/
136         /* Find pitch lags, initial LPC analysis */
137         /*****************************************/
138         silk_find_pitch_lags_FIX( psEnc, &sEncCtrl, res_pitch, x_frame - psEnc->sCmn.ltp_mem_length, psEnc->sCmn.arch );
139
140         /************************/
141         /* Noise shape analysis */
142         /************************/
143         silk_noise_shape_analysis_FIX( psEnc, &sEncCtrl, res_pitch_frame, x_frame, psEnc->sCmn.arch );
144
145         /***************************************************/
146         /* Find linear prediction coefficients (LPC + LTP) */
147         /***************************************************/
148         silk_find_pred_coefs_FIX( psEnc, &sEncCtrl, res_pitch_frame, x_frame, condCoding );
149
150         /****************************************/
151         /* Process gains                        */
152         /****************************************/
153         silk_process_gains_FIX( psEnc, &sEncCtrl, condCoding );
154
155         /****************************************/
156         /* Low Bitrate Redundant Encoding       */
157         /****************************************/
158         silk_LBRR_encode_FIX( psEnc, &sEncCtrl, x_frame, condCoding );
159
160         /* Loop over quantizer and entropy coding to control bitrate */
161         maxIter = 6;
162         gainMult_Q8 = SILK_FIX_CONST( 1, 8 );
163         found_lower = 0;
164         found_upper = 0;
165         gainsID = silk_gains_ID( psEnc->sCmn.indices.GainsIndices, psEnc->sCmn.nb_subfr );
166         gainsID_lower = -1;
167         gainsID_upper = -1;
168         /* Copy part of the input state */
169         silk_memcpy( &sRangeEnc_copy, psRangeEnc, sizeof( ec_enc ) );
170         silk_memcpy( &sNSQ_copy, &psEnc->sCmn.sNSQ, sizeof( silk_nsq_state ) );
171         seed_copy = psEnc->sCmn.indices.Seed;
172         ec_prevLagIndex_copy = psEnc->sCmn.ec_prevLagIndex;
173         ec_prevSignalType_copy = psEnc->sCmn.ec_prevSignalType;
174         ALLOC( ec_buf_copy, 1275, opus_uint8 );
175         for( iter = 0; ; iter++ ) {
176             if( gainsID == gainsID_lower ) {
177                 nBits = nBits_lower;
178             } else if( gainsID == gainsID_upper ) {
179                 nBits = nBits_upper;
180             } else {
181                 /* Restore part of the input state */
182                 if( iter > 0 ) {
183                     silk_memcpy( psRangeEnc, &sRangeEnc_copy, sizeof( ec_enc ) );
184                     silk_memcpy( &psEnc->sCmn.sNSQ, &sNSQ_copy, sizeof( silk_nsq_state ) );
185                     psEnc->sCmn.indices.Seed = seed_copy;
186                     psEnc->sCmn.ec_prevLagIndex = ec_prevLagIndex_copy;
187                     psEnc->sCmn.ec_prevSignalType = ec_prevSignalType_copy;
188                 }
189
190                 /*****************************************/
191                 /* Noise shaping quantization            */
192                 /*****************************************/
193                 if( psEnc->sCmn.nStatesDelayedDecision > 1 || psEnc->sCmn.warping_Q16 > 0 ) {
194                     silk_NSQ_del_dec( &psEnc->sCmn, &psEnc->sCmn.sNSQ, &psEnc->sCmn.indices, x_frame, psEnc->sCmn.pulses,
195                            sEncCtrl.PredCoef_Q12[ 0 ], sEncCtrl.LTPCoef_Q14, sEncCtrl.AR_Q13, sEncCtrl.HarmShapeGain_Q14,
196                            sEncCtrl.Tilt_Q14, sEncCtrl.LF_shp_Q14, sEncCtrl.Gains_Q16, sEncCtrl.pitchL, sEncCtrl.Lambda_Q10, sEncCtrl.LTP_scale_Q14,
197                            psEnc->sCmn.arch );
198                 } else {
199                     silk_NSQ( &psEnc->sCmn, &psEnc->sCmn.sNSQ, &psEnc->sCmn.indices, x_frame, psEnc->sCmn.pulses,
200                             sEncCtrl.PredCoef_Q12[ 0 ], sEncCtrl.LTPCoef_Q14, sEncCtrl.AR_Q13, sEncCtrl.HarmShapeGain_Q14,
201                             sEncCtrl.Tilt_Q14, sEncCtrl.LF_shp_Q14, sEncCtrl.Gains_Q16, sEncCtrl.pitchL, sEncCtrl.Lambda_Q10, sEncCtrl.LTP_scale_Q14,
202                             psEnc->sCmn.arch);
203                 }
204
205                 if ( iter == maxIter && !found_lower ) {
206                     silk_memcpy( &sRangeEnc_copy2, psRangeEnc, sizeof( ec_enc ) );
207                 }
208
209                 /****************************************/
210                 /* Encode Parameters                    */
211                 /****************************************/
212                 silk_encode_indices( &psEnc->sCmn, psRangeEnc, psEnc->sCmn.nFramesEncoded, 0, condCoding );
213
214                 /****************************************/
215                 /* Encode Excitation Signal             */
216                 /****************************************/
217                 silk_encode_pulses( psRangeEnc, psEnc->sCmn.indices.signalType, psEnc->sCmn.indices.quantOffsetType,
218                     psEnc->sCmn.pulses, psEnc->sCmn.frame_length );
219
220                 nBits = ec_tell( psRangeEnc );
221
222                 /* If we still bust after the last iteration, do some damage control. */
223                 if ( iter == maxIter && !found_lower && nBits > maxBits ) {
224                     silk_memcpy( psRangeEnc, &sRangeEnc_copy2, sizeof( ec_enc ) );
225
226                     /* Keep gains the same as the last frame. */
227                     psEnc->sShape.LastGainIndex = sEncCtrl.lastGainIndexPrev;
228                     for ( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) {
229                         psEnc->sCmn.indices.GainsIndices[ i ] = 4;
230                     }
231                     if (condCoding != CODE_CONDITIONALLY) {
232                        psEnc->sCmn.indices.GainsIndices[ 0 ] = sEncCtrl.lastGainIndexPrev;
233                     }
234                     psEnc->sCmn.ec_prevLagIndex = ec_prevLagIndex_copy;
235                     psEnc->sCmn.ec_prevSignalType = ec_prevSignalType_copy;
236                     /* Clear all pulses. */
237                     for ( i = 0; i < psEnc->sCmn.frame_length; i++ ) {
238                         psEnc->sCmn.pulses[ i ] = 0;
239                     }
240
241                     silk_encode_indices( &psEnc->sCmn, psRangeEnc, psEnc->sCmn.nFramesEncoded, 0, condCoding );
242
243                     silk_encode_pulses( psRangeEnc, psEnc->sCmn.indices.signalType, psEnc->sCmn.indices.quantOffsetType,
244                         psEnc->sCmn.pulses, psEnc->sCmn.frame_length );
245
246                     nBits = ec_tell( psRangeEnc );
247                 }
248
249                 if( useCBR == 0 && iter == 0 && nBits <= maxBits ) {
250                     break;
251                 }
252             }
253
254             if( iter == maxIter ) {
255                 if( found_lower && ( gainsID == gainsID_lower || nBits > maxBits ) ) {
256                     /* Restore output state from earlier iteration that did meet the bitrate budget */
257                     silk_memcpy( psRangeEnc, &sRangeEnc_copy2, sizeof( ec_enc ) );
258                     celt_assert( sRangeEnc_copy2.offs <= 1275 );
259                     silk_memcpy( psRangeEnc->buf, ec_buf_copy, sRangeEnc_copy2.offs );
260                     silk_memcpy( &psEnc->sCmn.sNSQ, &sNSQ_copy2, sizeof( silk_nsq_state ) );
261                     psEnc->sShape.LastGainIndex = LastGainIndex_copy2;
262                 }
263                 break;
264             }
265
266             if( nBits > maxBits ) {
267                 if( found_lower == 0 && iter >= 2 ) {
268                     /* Adjust the quantizer's rate/distortion tradeoff and discard previous "upper" results */
269                     sEncCtrl.Lambda_Q10 = silk_ADD_RSHIFT32( sEncCtrl.Lambda_Q10, sEncCtrl.Lambda_Q10, 1 );
270                     found_upper = 0;
271                     gainsID_upper = -1;
272                 } else {
273                     found_upper = 1;
274                     nBits_upper = nBits;
275                     gainMult_upper = gainMult_Q8;
276                     gainsID_upper = gainsID;
277                 }
278             } else if( nBits < maxBits - 5 ) {
279                 found_lower = 1;
280                 nBits_lower = nBits;
281                 gainMult_lower = gainMult_Q8;
282                 if( gainsID != gainsID_lower ) {
283                     gainsID_lower = gainsID;
284                     /* Copy part of the output state */
285                     silk_memcpy( &sRangeEnc_copy2, psRangeEnc, sizeof( ec_enc ) );
286                     celt_assert( psRangeEnc->offs <= 1275 );
287                     silk_memcpy( ec_buf_copy, psRangeEnc->buf, psRangeEnc->offs );
288                     silk_memcpy( &sNSQ_copy2, &psEnc->sCmn.sNSQ, sizeof( silk_nsq_state ) );
289                     LastGainIndex_copy2 = psEnc->sShape.LastGainIndex;
290                 }
291             } else {
292                 /* Within 5 bits of budget: close enough */
293                 break;
294             }
295
296             if ( !found_lower && nBits > maxBits ) {
297                 int j;
298                 for ( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) {
299                     int sum=0;
300                     for ( j = i*psEnc->sCmn.subfr_length; j < (i+1)*psEnc->sCmn.subfr_length; j++ ) {
301                         sum += abs( psEnc->sCmn.pulses[j] );
302                     }
303                     if ( iter == 0 || (sum < best_sum[i] && !gain_lock[i]) ) {
304                         best_sum[i] = sum;
305                         best_gain_mult[i] = gainMult_Q8;
306                     } else {
307                         gain_lock[i] = 1;
308                     }
309                 }
310             }
311             if( ( found_lower & found_upper ) == 0 ) {
312                 /* Adjust gain according to high-rate rate/distortion curve */
313                 if( nBits > maxBits ) {
314                     if (gainMult_Q8 < 16384) {
315                         gainMult_Q8 *= 2;
316                     } else {
317                         gainMult_Q8 = 32767;
318                     }
319                 } else {
320                     opus_int32 gain_factor_Q16;
321                     gain_factor_Q16 = silk_log2lin( silk_LSHIFT( nBits - maxBits, 7 ) / psEnc->sCmn.frame_length + SILK_FIX_CONST( 16, 7 ) );
322                     gainMult_Q8 = silk_SMULWB( gain_factor_Q16, gainMult_Q8 );
323                 }
324
325             } else {
326                 /* Adjust gain by interpolating */
327                 gainMult_Q8 = gainMult_lower + silk_DIV32_16( silk_MUL( gainMult_upper - gainMult_lower, maxBits - nBits_lower ), nBits_upper - nBits_lower );
328                 /* New gain multplier must be between 25% and 75% of old range (note that gainMult_upper < gainMult_lower) */
329                 if( gainMult_Q8 > silk_ADD_RSHIFT32( gainMult_lower, gainMult_upper - gainMult_lower, 2 ) ) {
330                     gainMult_Q8 = silk_ADD_RSHIFT32( gainMult_lower, gainMult_upper - gainMult_lower, 2 );
331                 } else
332                 if( gainMult_Q8 < silk_SUB_RSHIFT32( gainMult_upper, gainMult_upper - gainMult_lower, 2 ) ) {
333                     gainMult_Q8 = silk_SUB_RSHIFT32( gainMult_upper, gainMult_upper - gainMult_lower, 2 );
334                 }
335             }
336
337             for( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) {
338                 opus_int16 tmp;
339                 if ( gain_lock[i] ) {
340                     tmp = best_gain_mult[i];
341                 } else {
342                     tmp = gainMult_Q8;
343                 }
344                 sEncCtrl.Gains_Q16[ i ] = silk_LSHIFT_SAT32( silk_SMULWB( sEncCtrl.GainsUnq_Q16[ i ], tmp ), 8 );
345             }
346
347             /* Quantize gains */
348             psEnc->sShape.LastGainIndex = sEncCtrl.lastGainIndexPrev;
349             silk_gains_quant( psEnc->sCmn.indices.GainsIndices, sEncCtrl.Gains_Q16,
350                   &psEnc->sShape.LastGainIndex, condCoding == CODE_CONDITIONALLY, psEnc->sCmn.nb_subfr );
351
352             /* Unique identifier of gains vector */
353             gainsID = silk_gains_ID( psEnc->sCmn.indices.GainsIndices, psEnc->sCmn.nb_subfr );
354         }
355     }
356
357     /* Update input buffer */
358     silk_memmove( psEnc->x_buf, &psEnc->x_buf[ psEnc->sCmn.frame_length ],
359         ( psEnc->sCmn.ltp_mem_length + LA_SHAPE_MS * psEnc->sCmn.fs_kHz ) * sizeof( opus_int16 ) );
360
361     /* Exit without entropy coding */
362     if( psEnc->sCmn.prefillFlag ) {
363         /* No payload */
364         *pnBytesOut = 0;
365         RESTORE_STACK;
366         return ret;
367     }
368
369     /* Parameters needed for next frame */
370     psEnc->sCmn.prevLag        = sEncCtrl.pitchL[ psEnc->sCmn.nb_subfr - 1 ];
371     psEnc->sCmn.prevSignalType = psEnc->sCmn.indices.signalType;
372
373     /****************************************/
374     /* Finalize payload                     */
375     /****************************************/
376     psEnc->sCmn.first_frame_after_reset = 0;
377     /* Payload size */
378     *pnBytesOut = silk_RSHIFT( ec_tell( psRangeEnc ) + 7, 3 );
379
380     RESTORE_STACK;
381     return ret;
382 }
383
384 /* Low-Bitrate Redundancy (LBRR) encoding. Reuse all parameters but encode excitation at lower bitrate  */
385 static OPUS_INLINE void silk_LBRR_encode_FIX(
386     silk_encoder_state_FIX          *psEnc,                                 /* I/O  Pointer to Silk FIX encoder state                                           */
387     silk_encoder_control_FIX        *psEncCtrl,                             /* I/O  Pointer to Silk FIX encoder control struct                                  */
388     const opus_int16                x16[],                                  /* I    Input signal                                                                */
389     opus_int                        condCoding                              /* I    The type of conditional coding used so far for this frame                   */
390 )
391 {
392     opus_int32   TempGains_Q16[ MAX_NB_SUBFR ];
393     SideInfoIndices *psIndices_LBRR = &psEnc->sCmn.indices_LBRR[ psEnc->sCmn.nFramesEncoded ];
394     silk_nsq_state sNSQ_LBRR;
395
396     /*******************************************/
397     /* Control use of inband LBRR              */
398     /*******************************************/
399     if( psEnc->sCmn.LBRR_enabled && psEnc->sCmn.speech_activity_Q8 > SILK_FIX_CONST( LBRR_SPEECH_ACTIVITY_THRES, 8 ) ) {
400         psEnc->sCmn.LBRR_flags[ psEnc->sCmn.nFramesEncoded ] = 1;
401
402         /* Copy noise shaping quantizer state and quantization indices from regular encoding */
403         silk_memcpy( &sNSQ_LBRR, &psEnc->sCmn.sNSQ, sizeof( silk_nsq_state ) );
404         silk_memcpy( psIndices_LBRR, &psEnc->sCmn.indices, sizeof( SideInfoIndices ) );
405
406         /* Save original gains */
407         silk_memcpy( TempGains_Q16, psEncCtrl->Gains_Q16, psEnc->sCmn.nb_subfr * sizeof( opus_int32 ) );
408
409         if( psEnc->sCmn.nFramesEncoded == 0 || psEnc->sCmn.LBRR_flags[ psEnc->sCmn.nFramesEncoded - 1 ] == 0 ) {
410             /* First frame in packet or previous frame not LBRR coded */
411             psEnc->sCmn.LBRRprevLastGainIndex = psEnc->sShape.LastGainIndex;
412
413             /* Increase Gains to get target LBRR rate */
414             psIndices_LBRR->GainsIndices[ 0 ] = psIndices_LBRR->GainsIndices[ 0 ] + psEnc->sCmn.LBRR_GainIncreases;
415             psIndices_LBRR->GainsIndices[ 0 ] = silk_min_int( psIndices_LBRR->GainsIndices[ 0 ], N_LEVELS_QGAIN - 1 );
416         }
417
418         /* Decode to get gains in sync with decoder         */
419         /* Overwrite unquantized gains with quantized gains */
420         silk_gains_dequant( psEncCtrl->Gains_Q16, psIndices_LBRR->GainsIndices,
421             &psEnc->sCmn.LBRRprevLastGainIndex, condCoding == CODE_CONDITIONALLY, psEnc->sCmn.nb_subfr );
422
423         /*****************************************/
424         /* Noise shaping quantization            */
425         /*****************************************/
426         if( psEnc->sCmn.nStatesDelayedDecision > 1 || psEnc->sCmn.warping_Q16 > 0 ) {
427             silk_NSQ_del_dec( &psEnc->sCmn, &sNSQ_LBRR, psIndices_LBRR, x16,
428                 psEnc->sCmn.pulses_LBRR[ psEnc->sCmn.nFramesEncoded ], psEncCtrl->PredCoef_Q12[ 0 ], psEncCtrl->LTPCoef_Q14,
429                 psEncCtrl->AR_Q13, psEncCtrl->HarmShapeGain_Q14, psEncCtrl->Tilt_Q14, psEncCtrl->LF_shp_Q14,
430                 psEncCtrl->Gains_Q16, psEncCtrl->pitchL, psEncCtrl->Lambda_Q10, psEncCtrl->LTP_scale_Q14, psEnc->sCmn.arch );
431         } else {
432             silk_NSQ( &psEnc->sCmn, &sNSQ_LBRR, psIndices_LBRR, x16,
433                 psEnc->sCmn.pulses_LBRR[ psEnc->sCmn.nFramesEncoded ], psEncCtrl->PredCoef_Q12[ 0 ], psEncCtrl->LTPCoef_Q14,
434                 psEncCtrl->AR_Q13, psEncCtrl->HarmShapeGain_Q14, psEncCtrl->Tilt_Q14, psEncCtrl->LF_shp_Q14,
435                 psEncCtrl->Gains_Q16, psEncCtrl->pitchL, psEncCtrl->Lambda_Q10, psEncCtrl->LTP_scale_Q14, psEnc->sCmn.arch );
436         }
437
438         /* Restore original gains */
439         silk_memcpy( psEncCtrl->Gains_Q16, TempGains_Q16, psEnc->sCmn.nb_subfr * sizeof( opus_int32 ) );
440     }
441 }