Home | History | Annotate | Download | only in fixed
      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_int32                xfw_Q3[],                               /* 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 );
     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     SAVE_STACK;
     98 
     99     /* This is totally unnecessary but many compilers (including gcc) are too dumb to realise it */
    100     LastGainIndex_copy2 = nBits_lower = nBits_upper = gainMult_lower = gainMult_upper = 0;
    101 
    102     psEnc->sCmn.indices.Seed = psEnc->sCmn.frameCounter++ & 3;
    103 
    104     /**************************************************************/
    105     /* Set up Input Pointers, and insert frame in input buffer   */
    106     /*************************************************************/
    107     /* start of frame to encode */
    108     x_frame = psEnc->x_buf + psEnc->sCmn.ltp_mem_length;
    109 
    110     /***************************************/
    111     /* Ensure smooth bandwidth transitions */
    112     /***************************************/
    113     silk_LP_variable_cutoff( &psEnc->sCmn.sLP, psEnc->sCmn.inputBuf + 1, psEnc->sCmn.frame_length );
    114 
    115     /*******************************************/
    116     /* Copy new frame to front of input buffer */
    117     /*******************************************/
    118     silk_memcpy( x_frame + LA_SHAPE_MS * psEnc->sCmn.fs_kHz, psEnc->sCmn.inputBuf + 1, psEnc->sCmn.frame_length * sizeof( opus_int16 ) );
    119 
    120     if( !psEnc->sCmn.prefillFlag ) {
    121         VARDECL( opus_int32, xfw_Q3 );
    122         VARDECL( opus_int16, res_pitch );
    123         VARDECL( opus_uint8, ec_buf_copy );
    124         opus_int16 *res_pitch_frame;
    125 
    126         ALLOC( res_pitch,
    127                psEnc->sCmn.la_pitch + psEnc->sCmn.frame_length
    128                    + psEnc->sCmn.ltp_mem_length, opus_int16 );
    129         /* start of pitch LPC residual frame */
    130         res_pitch_frame = res_pitch + psEnc->sCmn.ltp_mem_length;
    131 
    132         /*****************************************/
    133         /* Find pitch lags, initial LPC analysis */
    134         /*****************************************/
    135         silk_find_pitch_lags_FIX( psEnc, &sEncCtrl, res_pitch, x_frame, psEnc->sCmn.arch );
    136 
    137         /************************/
    138         /* Noise shape analysis */
    139         /************************/
    140         silk_noise_shape_analysis_FIX( psEnc, &sEncCtrl, res_pitch_frame, x_frame, psEnc->sCmn.arch );
    141 
    142         /***************************************************/
    143         /* Find linear prediction coefficients (LPC + LTP) */
    144         /***************************************************/
    145         silk_find_pred_coefs_FIX( psEnc, &sEncCtrl, res_pitch, x_frame, condCoding );
    146 
    147         /****************************************/
    148         /* Process gains                        */
    149         /****************************************/
    150         silk_process_gains_FIX( psEnc, &sEncCtrl, condCoding );
    151 
    152         /*****************************************/
    153         /* Prefiltering for noise shaper         */
    154         /*****************************************/
    155         ALLOC( xfw_Q3, psEnc->sCmn.frame_length, opus_int32 );
    156         silk_prefilter_FIX( psEnc, &sEncCtrl, xfw_Q3, x_frame );
    157 
    158         /****************************************/
    159         /* Low Bitrate Redundant Encoding       */
    160         /****************************************/
    161         silk_LBRR_encode_FIX( psEnc, &sEncCtrl, xfw_Q3, condCoding );
    162 
    163         /* Loop over quantizer and entropy coding to control bitrate */
    164         maxIter = 6;
    165         gainMult_Q8 = SILK_FIX_CONST( 1, 8 );
    166         found_lower = 0;
    167         found_upper = 0;
    168         gainsID = silk_gains_ID( psEnc->sCmn.indices.GainsIndices, psEnc->sCmn.nb_subfr );
    169         gainsID_lower = -1;
    170         gainsID_upper = -1;
    171         /* Copy part of the input state */
    172         silk_memcpy( &sRangeEnc_copy, psRangeEnc, sizeof( ec_enc ) );
    173         silk_memcpy( &sNSQ_copy, &psEnc->sCmn.sNSQ, sizeof( silk_nsq_state ) );
    174         seed_copy = psEnc->sCmn.indices.Seed;
    175         ec_prevLagIndex_copy = psEnc->sCmn.ec_prevLagIndex;
    176         ec_prevSignalType_copy = psEnc->sCmn.ec_prevSignalType;
    177         ALLOC( ec_buf_copy, 1275, opus_uint8 );
    178         for( iter = 0; ; iter++ ) {
    179             if( gainsID == gainsID_lower ) {
    180                 nBits = nBits_lower;
    181             } else if( gainsID == gainsID_upper ) {
    182                 nBits = nBits_upper;
    183             } else {
    184                 /* Restore part of the input state */
    185                 if( iter > 0 ) {
    186                     silk_memcpy( psRangeEnc, &sRangeEnc_copy, sizeof( ec_enc ) );
    187                     silk_memcpy( &psEnc->sCmn.sNSQ, &sNSQ_copy, sizeof( silk_nsq_state ) );
    188                     psEnc->sCmn.indices.Seed = seed_copy;
    189                     psEnc->sCmn.ec_prevLagIndex = ec_prevLagIndex_copy;
    190                     psEnc->sCmn.ec_prevSignalType = ec_prevSignalType_copy;
    191                 }
    192 
    193                 /*****************************************/
    194                 /* Noise shaping quantization            */
    195                 /*****************************************/
    196                 if( psEnc->sCmn.nStatesDelayedDecision > 1 || psEnc->sCmn.warping_Q16 > 0 ) {
    197                     silk_NSQ_del_dec( &psEnc->sCmn, &psEnc->sCmn.sNSQ, &psEnc->sCmn.indices, xfw_Q3, psEnc->sCmn.pulses,
    198                            sEncCtrl.PredCoef_Q12[ 0 ], sEncCtrl.LTPCoef_Q14, sEncCtrl.AR2_Q13, sEncCtrl.HarmShapeGain_Q14,
    199                            sEncCtrl.Tilt_Q14, sEncCtrl.LF_shp_Q14, sEncCtrl.Gains_Q16, sEncCtrl.pitchL, sEncCtrl.Lambda_Q10, sEncCtrl.LTP_scale_Q14 );
    200                 } else {
    201                     silk_NSQ( &psEnc->sCmn, &psEnc->sCmn.sNSQ, &psEnc->sCmn.indices, xfw_Q3, psEnc->sCmn.pulses,
    202                             sEncCtrl.PredCoef_Q12[ 0 ], sEncCtrl.LTPCoef_Q14, sEncCtrl.AR2_Q13, sEncCtrl.HarmShapeGain_Q14,
    203                             sEncCtrl.Tilt_Q14, sEncCtrl.LF_shp_Q14, sEncCtrl.Gains_Q16, sEncCtrl.pitchL, sEncCtrl.Lambda_Q10, sEncCtrl.LTP_scale_Q14 );
    204                 }
    205 
    206                 /****************************************/
    207                 /* Encode Parameters                    */
    208                 /****************************************/
    209                 silk_encode_indices( &psEnc->sCmn, psRangeEnc, psEnc->sCmn.nFramesEncoded, 0, condCoding );
    210 
    211                 /****************************************/
    212                 /* Encode Excitation Signal             */
    213                 /****************************************/
    214                 silk_encode_pulses( psRangeEnc, psEnc->sCmn.indices.signalType, psEnc->sCmn.indices.quantOffsetType,
    215                     psEnc->sCmn.pulses, psEnc->sCmn.frame_length );
    216 
    217                 nBits = ec_tell( psRangeEnc );
    218 
    219                 if( useCBR == 0 && iter == 0 && nBits <= maxBits ) {
    220                     break;
    221                 }
    222             }
    223 
    224             if( iter == maxIter ) {
    225                 if( found_lower && ( gainsID == gainsID_lower || nBits > maxBits ) ) {
    226                     /* Restore output state from earlier iteration that did meet the bitrate budget */
    227                     silk_memcpy( psRangeEnc, &sRangeEnc_copy2, sizeof( ec_enc ) );
    228                     silk_assert( sRangeEnc_copy2.offs <= 1275 );
    229                     silk_memcpy( psRangeEnc->buf, ec_buf_copy, sRangeEnc_copy2.offs );
    230                     silk_memcpy( &psEnc->sCmn.sNSQ, &sNSQ_copy2, sizeof( silk_nsq_state ) );
    231                     psEnc->sShape.LastGainIndex = LastGainIndex_copy2;
    232                 }
    233                 break;
    234             }
    235 
    236             if( nBits > maxBits ) {
    237                 if( found_lower == 0 && iter >= 2 ) {
    238                     /* Adjust the quantizer's rate/distortion tradeoff and discard previous "upper" results */
    239                     sEncCtrl.Lambda_Q10 = silk_ADD_RSHIFT32( sEncCtrl.Lambda_Q10, sEncCtrl.Lambda_Q10, 1 );
    240                     found_upper = 0;
    241                     gainsID_upper = -1;
    242                 } else {
    243                     found_upper = 1;
    244                     nBits_upper = nBits;
    245                     gainMult_upper = gainMult_Q8;
    246                     gainsID_upper = gainsID;
    247                 }
    248             } else if( nBits < maxBits - 5 ) {
    249                 found_lower = 1;
    250                 nBits_lower = nBits;
    251                 gainMult_lower = gainMult_Q8;
    252                 if( gainsID != gainsID_lower ) {
    253                     gainsID_lower = gainsID;
    254                     /* Copy part of the output state */
    255                     silk_memcpy( &sRangeEnc_copy2, psRangeEnc, sizeof( ec_enc ) );
    256                     silk_assert( psRangeEnc->offs <= 1275 );
    257                     silk_memcpy( ec_buf_copy, psRangeEnc->buf, psRangeEnc->offs );
    258                     silk_memcpy( &sNSQ_copy2, &psEnc->sCmn.sNSQ, sizeof( silk_nsq_state ) );
    259                     LastGainIndex_copy2 = psEnc->sShape.LastGainIndex;
    260                 }
    261             } else {
    262                 /* Within 5 bits of budget: close enough */
    263                 break;
    264             }
    265 
    266             if( ( found_lower & found_upper ) == 0 ) {
    267                 /* Adjust gain according to high-rate rate/distortion curve */
    268                 opus_int32 gain_factor_Q16;
    269                 gain_factor_Q16 = silk_log2lin( silk_LSHIFT( nBits - maxBits, 7 ) / psEnc->sCmn.frame_length + SILK_FIX_CONST( 16, 7 ) );
    270                 gain_factor_Q16 = silk_min_32( gain_factor_Q16, SILK_FIX_CONST( 2, 16 ) );
    271                 if( nBits > maxBits ) {
    272                     gain_factor_Q16 = silk_max_32( gain_factor_Q16, SILK_FIX_CONST( 1.3, 16 ) );
    273                 }
    274                 gainMult_Q8 = silk_SMULWB( gain_factor_Q16, gainMult_Q8 );
    275             } else {
    276                 /* Adjust gain by interpolating */
    277                 gainMult_Q8 = gainMult_lower + silk_DIV32_16( silk_MUL( gainMult_upper - gainMult_lower, maxBits - nBits_lower ), nBits_upper - nBits_lower );
    278                 /* New gain multplier must be between 25% and 75% of old range (note that gainMult_upper < gainMult_lower) */
    279                 if( gainMult_Q8 > silk_ADD_RSHIFT32( gainMult_lower, gainMult_upper - gainMult_lower, 2 ) ) {
    280                     gainMult_Q8 = silk_ADD_RSHIFT32( gainMult_lower, gainMult_upper - gainMult_lower, 2 );
    281                 } else
    282                 if( gainMult_Q8 < silk_SUB_RSHIFT32( gainMult_upper, gainMult_upper - gainMult_lower, 2 ) ) {
    283                     gainMult_Q8 = silk_SUB_RSHIFT32( gainMult_upper, gainMult_upper - gainMult_lower, 2 );
    284                 }
    285             }
    286 
    287             for( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) {
    288                 sEncCtrl.Gains_Q16[ i ] = silk_LSHIFT_SAT32( silk_SMULWB( sEncCtrl.GainsUnq_Q16[ i ], gainMult_Q8 ), 8 );
    289             }
    290 
    291             /* Quantize gains */
    292             psEnc->sShape.LastGainIndex = sEncCtrl.lastGainIndexPrev;
    293             silk_gains_quant( psEnc->sCmn.indices.GainsIndices, sEncCtrl.Gains_Q16,
    294                   &psEnc->sShape.LastGainIndex, condCoding == CODE_CONDITIONALLY, psEnc->sCmn.nb_subfr );
    295 
    296             /* Unique identifier of gains vector */
    297             gainsID = silk_gains_ID( psEnc->sCmn.indices.GainsIndices, psEnc->sCmn.nb_subfr );
    298         }
    299     }
    300 
    301     /* Update input buffer */
    302     silk_memmove( psEnc->x_buf, &psEnc->x_buf[ psEnc->sCmn.frame_length ],
    303         ( psEnc->sCmn.ltp_mem_length + LA_SHAPE_MS * psEnc->sCmn.fs_kHz ) * sizeof( opus_int16 ) );
    304 
    305     /* Exit without entropy coding */
    306     if( psEnc->sCmn.prefillFlag ) {
    307         /* No payload */
    308         *pnBytesOut = 0;
    309         RESTORE_STACK;
    310         return ret;
    311     }
    312 
    313     /* Parameters needed for next frame */
    314     psEnc->sCmn.prevLag        = sEncCtrl.pitchL[ psEnc->sCmn.nb_subfr - 1 ];
    315     psEnc->sCmn.prevSignalType = psEnc->sCmn.indices.signalType;
    316 
    317     /****************************************/
    318     /* Finalize payload                     */
    319     /****************************************/
    320     psEnc->sCmn.first_frame_after_reset = 0;
    321     /* Payload size */
    322     *pnBytesOut = silk_RSHIFT( ec_tell( psRangeEnc ) + 7, 3 );
    323 
    324     RESTORE_STACK;
    325     return ret;
    326 }
    327 
    328 /* Low-Bitrate Redundancy (LBRR) encoding. Reuse all parameters but encode excitation at lower bitrate  */
    329 static OPUS_INLINE void silk_LBRR_encode_FIX(
    330     silk_encoder_state_FIX          *psEnc,                                 /* I/O  Pointer to Silk FIX encoder state                                           */
    331     silk_encoder_control_FIX        *psEncCtrl,                             /* I/O  Pointer to Silk FIX encoder control struct                                  */
    332     const opus_int32                xfw_Q3[],                               /* I    Input signal                                                                */
    333     opus_int                        condCoding                              /* I    The type of conditional coding used so far for this frame                   */
    334 )
    335 {
    336     opus_int32   TempGains_Q16[ MAX_NB_SUBFR ];
    337     SideInfoIndices *psIndices_LBRR = &psEnc->sCmn.indices_LBRR[ psEnc->sCmn.nFramesEncoded ];
    338     silk_nsq_state sNSQ_LBRR;
    339 
    340     /*******************************************/
    341     /* Control use of inband LBRR              */
    342     /*******************************************/
    343     if( psEnc->sCmn.LBRR_enabled && psEnc->sCmn.speech_activity_Q8 > SILK_FIX_CONST( LBRR_SPEECH_ACTIVITY_THRES, 8 ) ) {
    344         psEnc->sCmn.LBRR_flags[ psEnc->sCmn.nFramesEncoded ] = 1;
    345 
    346         /* Copy noise shaping quantizer state and quantization indices from regular encoding */
    347         silk_memcpy( &sNSQ_LBRR, &psEnc->sCmn.sNSQ, sizeof( silk_nsq_state ) );
    348         silk_memcpy( psIndices_LBRR, &psEnc->sCmn.indices, sizeof( SideInfoIndices ) );
    349 
    350         /* Save original gains */
    351         silk_memcpy( TempGains_Q16, psEncCtrl->Gains_Q16, psEnc->sCmn.nb_subfr * sizeof( opus_int32 ) );
    352 
    353         if( psEnc->sCmn.nFramesEncoded == 0 || psEnc->sCmn.LBRR_flags[ psEnc->sCmn.nFramesEncoded - 1 ] == 0 ) {
    354             /* First frame in packet or previous frame not LBRR coded */
    355             psEnc->sCmn.LBRRprevLastGainIndex = psEnc->sShape.LastGainIndex;
    356 
    357             /* Increase Gains to get target LBRR rate */
    358             psIndices_LBRR->GainsIndices[ 0 ] = psIndices_LBRR->GainsIndices[ 0 ] + psEnc->sCmn.LBRR_GainIncreases;
    359             psIndices_LBRR->GainsIndices[ 0 ] = silk_min_int( psIndices_LBRR->GainsIndices[ 0 ], N_LEVELS_QGAIN - 1 );
    360         }
    361 
    362         /* Decode to get gains in sync with decoder         */
    363         /* Overwrite unquantized gains with quantized gains */
    364         silk_gains_dequant( psEncCtrl->Gains_Q16, psIndices_LBRR->GainsIndices,
    365             &psEnc->sCmn.LBRRprevLastGainIndex, condCoding == CODE_CONDITIONALLY, psEnc->sCmn.nb_subfr );
    366 
    367         /*****************************************/
    368         /* Noise shaping quantization            */
    369         /*****************************************/
    370         if( psEnc->sCmn.nStatesDelayedDecision > 1 || psEnc->sCmn.warping_Q16 > 0 ) {
    371             silk_NSQ_del_dec( &psEnc->sCmn, &sNSQ_LBRR, psIndices_LBRR, xfw_Q3,
    372                 psEnc->sCmn.pulses_LBRR[ psEnc->sCmn.nFramesEncoded ], psEncCtrl->PredCoef_Q12[ 0 ], psEncCtrl->LTPCoef_Q14,
    373                 psEncCtrl->AR2_Q13, psEncCtrl->HarmShapeGain_Q14, psEncCtrl->Tilt_Q14, psEncCtrl->LF_shp_Q14,
    374                 psEncCtrl->Gains_Q16, psEncCtrl->pitchL, psEncCtrl->Lambda_Q10, psEncCtrl->LTP_scale_Q14 );
    375         } else {
    376             silk_NSQ( &psEnc->sCmn, &sNSQ_LBRR, psIndices_LBRR, xfw_Q3,
    377                 psEnc->sCmn.pulses_LBRR[ psEnc->sCmn.nFramesEncoded ], psEncCtrl->PredCoef_Q12[ 0 ], psEncCtrl->LTPCoef_Q14,
    378                 psEncCtrl->AR2_Q13, psEncCtrl->HarmShapeGain_Q14, psEncCtrl->Tilt_Q14, psEncCtrl->LF_shp_Q14,
    379                 psEncCtrl->Gains_Q16, psEncCtrl->pitchL, psEncCtrl->Lambda_Q10, psEncCtrl->LTP_scale_Q14 );
    380         }
    381 
    382         /* Restore original gains */
    383         silk_memcpy( psEncCtrl->Gains_Q16, TempGains_Q16, psEnc->sCmn.nb_subfr * sizeof( opus_int32 ) );
    384     }
    385 }
    386