tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

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 }