LCOV - code coverage report
Current view: top level - media/libopus/silk/float - encode_frame_FLP.c (source / functions) Hit Total Coverage
Test: output.info Lines: 0 168 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 3 0.0 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.13