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