Optimization of the CBR loop
[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, (subject to the limitations in the disclaimer below)
5 are permitted provided that the following conditions 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 Skype Limited, nor the names of specific
12 contributors, may be used to endorse or promote products derived from
13 this software without specific prior written permission.
14 NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
15 BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
16 CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
17 BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
18 FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
19 COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
20 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
22 USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
23 ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25 OF THIS SOFTWARE, EVEN IF ADVISED OF THE 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 "tuning_parameters.h"
34
35 /* Low Bitrate Redundancy (LBRR) encoding. Reuse all parameters but encode with lower bitrate           */
36 static inline void silk_LBRR_encode_FIX(
37     silk_encoder_state_FIX          *psEnc,             /* I/O  Pointer to Silk FIX encoder state           */
38     silk_encoder_control_FIX        *psEncCtrl,         /* I/O  Pointer to Silk FIX encoder control struct  */
39     const opus_int16                 xfw[],              /* I    Input signal                                */
40     opus_int                         condCoding         /* I    The type of conditional coding used so far for this frame */
41 );
42
43 void silk_encode_do_VAD_FIX(
44     silk_encoder_state_FIX          *psEnc              /* I/O  Encoder state FIX                       */
45 )
46 {
47     /****************************/
48     /* Voice Activity Detection */
49     /****************************/
50 TIC(VAD)
51     silk_VAD_GetSA_Q8( &psEnc->sCmn, psEnc->sCmn.inputBuf + 1 );
52 TOC(VAD)
53
54     /**************************************************/
55     /* Convert speech activity into VAD and DTX flags */
56     /**************************************************/
57     if( psEnc->sCmn.speech_activity_Q8 < SILK_FIX_CONST( SPEECH_ACTIVITY_DTX_THRES, 8 ) ) {
58         psEnc->sCmn.indices.signalType = TYPE_NO_VOICE_ACTIVITY;
59         psEnc->sCmn.noSpeechCounter++;
60         if( psEnc->sCmn.noSpeechCounter < NB_SPEECH_FRAMES_BEFORE_DTX ) {
61             psEnc->sCmn.inDTX = 0;
62         } else if( psEnc->sCmn.noSpeechCounter > MAX_CONSECUTIVE_DTX + NB_SPEECH_FRAMES_BEFORE_DTX ) {
63             psEnc->sCmn.noSpeechCounter = NB_SPEECH_FRAMES_BEFORE_DTX;
64             psEnc->sCmn.inDTX           = 0;
65         }
66         psEnc->sCmn.VAD_flags[ psEnc->sCmn.nFramesEncoded ] = 0;
67     } else {
68         psEnc->sCmn.noSpeechCounter    = 0;
69         psEnc->sCmn.inDTX              = 0;
70         psEnc->sCmn.indices.signalType = TYPE_UNVOICED;
71         psEnc->sCmn.VAD_flags[ psEnc->sCmn.nFramesEncoded ] = 1;
72     }
73 }
74
75 /****************/
76 /* Encode frame */
77 /****************/
78 opus_int silk_encode_frame_FIX(
79     silk_encoder_state_FIX          *psEnc,             /* I/O  Encoder state FIX                       */
80     opus_int32                       *pnBytesOut,        /*   O  Number of payload bytes                 */
81     ec_enc                          *psRangeEnc,        /* I/O  compressor data structure               */
82     opus_int                         condCoding,        /* I    The type of conditional coding to use   */
83     opus_int                         maxBits,           /* I    If > 0: maximum number of output bits   */
84     opus_int                         useCBR             /* I    Flag to force constant-bitrate operation */
85 )
86 {
87     silk_encoder_control_FIX sEncCtrl;
88     opus_int     i, iter, maxIter, found_upper, found_lower, ret = 0;
89     opus_int16   *x_frame, *res_pitch_frame;
90     opus_int16   xfw[ MAX_FRAME_LENGTH ];
91     opus_int16   res_pitch[ 2 * MAX_FRAME_LENGTH + LA_PITCH_MAX ];
92     ec_enc       sRangeEnc_copy, sRangeEnc_copy2;
93     silk_nsq_state sNSQ_copy, sNSQ_copy2;
94     opus_int32   seed_copy, nBits, nBits_lower, nBits_upper, gainMult_lower, gainMult_upper;
95     opus_int32   gainsID, gainsID_lower, gainsID_upper;
96     opus_int16   gainMult_Q8;
97     opus_int16   ec_prevLagIndex_copy;
98     opus_int     ec_prevSignalType_copy;
99     opus_int8    LastGainIndex_copy2;
100     opus_uint8   ec_buf_copy[ 1275 ];
101
102 TIC(ENCODE_FRAME)
103
104     /* This is totally unnecessary but many compilers (including gcc) are too dumb
105        to realise it */
106     LastGainIndex_copy2 = nBits_lower = nBits_upper = gainMult_lower = gainMult_upper = 0;
107
108     psEnc->sCmn.indices.Seed = psEnc->sCmn.frameCounter++ & 3;
109
110     /**************************************************************/
111     /* Setup Input Pointers, and insert frame in input buffer    */
112     /*************************************************************/
113     /* pointers aligned with start of frame to encode */
114     x_frame         = psEnc->x_buf + psEnc->sCmn.ltp_mem_length;    /* start of frame to encode */
115     res_pitch_frame = res_pitch    + psEnc->sCmn.ltp_mem_length;    /* start of pitch LPC residual frame */
116
117     /***************************************/
118     /* Ensure smooth bandwidth transitions */
119     /***************************************/
120     silk_LP_variable_cutoff( &psEnc->sCmn.sLP, psEnc->sCmn.inputBuf + 1, psEnc->sCmn.frame_length );
121
122     /*******************************************/
123     /* Copy new frame to front of input buffer */
124     /*******************************************/
125     silk_memcpy( x_frame + LA_SHAPE_MS * psEnc->sCmn.fs_kHz, psEnc->sCmn.inputBuf + 1, psEnc->sCmn.frame_length * sizeof( opus_int16 ) );
126
127     /*****************************************/
128     /* Find pitch lags, initial LPC analysis */
129     /*****************************************/
130 TIC(FIND_PITCH)
131     silk_find_pitch_lags_FIX( psEnc, &sEncCtrl, res_pitch, x_frame );
132 TOC(FIND_PITCH)
133
134     /************************/
135     /* Noise shape analysis */
136     /************************/
137 TIC(NOISE_SHAPE_ANALYSIS)
138     silk_noise_shape_analysis_FIX( psEnc, &sEncCtrl, res_pitch_frame, x_frame );
139 TOC(NOISE_SHAPE_ANALYSIS)
140
141     /***************************************************/
142     /* Find linear prediction coefficients (LPC + LTP) */
143     /***************************************************/
144 TIC(FIND_PRED_COEF)
145     silk_find_pred_coefs_FIX( psEnc, &sEncCtrl, res_pitch, x_frame, condCoding );
146 TOC(FIND_PRED_COEF)
147
148     /****************************************/
149     /* Process gains                        */
150     /****************************************/
151 TIC(PROCESS_GAINS)
152     silk_process_gains_FIX( psEnc, &sEncCtrl, condCoding );
153 TOC(PROCESS_GAINS)
154
155     /*****************************************/
156     /* Prefiltering for noise shaper         */
157     /*****************************************/
158 TIC(PREFILTER)
159     silk_prefilter_FIX( psEnc, &sEncCtrl, xfw, x_frame );
160 TOC(PREFILTER)
161
162     /****************************************/
163     /* Low Bitrate Redundant Encoding       */
164     /****************************************/
165 TIC(LBRR)
166     silk_LBRR_encode_FIX( psEnc, &sEncCtrl, xfw, condCoding );
167 TOC(LBRR)
168
169     if( psEnc->sCmn.prefillFlag ) {
170 TIC(NSQ)
171         if( psEnc->sCmn.nStatesDelayedDecision > 1 || psEnc->sCmn.warping_Q16 > 0 ) {
172             silk_NSQ_del_dec( &psEnc->sCmn, &psEnc->sCmn.sNSQ, &psEnc->sCmn.indices, xfw, psEnc->sCmn.pulses,
173                    sEncCtrl.PredCoef_Q12[ 0 ], sEncCtrl.LTPCoef_Q14, sEncCtrl.AR2_Q13, sEncCtrl.HarmShapeGain_Q14,
174                    sEncCtrl.Tilt_Q14, sEncCtrl.LF_shp_Q14, sEncCtrl.Gains_Q16, sEncCtrl.pitchL, sEncCtrl.Lambda_Q10, sEncCtrl.LTP_scale_Q14 );
175         } else {
176             silk_NSQ( &psEnc->sCmn, &psEnc->sCmn.sNSQ, &psEnc->sCmn.indices, xfw, psEnc->sCmn.pulses,
177                    sEncCtrl.PredCoef_Q12[ 0 ], sEncCtrl.LTPCoef_Q14, sEncCtrl.AR2_Q13, sEncCtrl.HarmShapeGain_Q14,
178                    sEncCtrl.Tilt_Q14, sEncCtrl.LF_shp_Q14, sEncCtrl.Gains_Q16, sEncCtrl.pitchL, sEncCtrl.Lambda_Q10, sEncCtrl.LTP_scale_Q14 );
179         }
180 TOC(NSQ)
181     } else {
182         /* Loop over quantizer and entropy coding to control bitrate */
183         maxIter = 5;
184         gainMult_Q8 = SILK_FIX_CONST( 1, 8 );
185         found_lower = 0;
186         found_upper = 0;
187         gainsID = silk_gains_ID( psEnc->sCmn.indices.GainsIndices, psEnc->sCmn.nb_subfr );
188         gainsID_lower = -1;
189         gainsID_upper = -1;
190         /* Copy part of the input state */
191         silk_memcpy( &sRangeEnc_copy, psRangeEnc, sizeof( ec_enc ) );
192         silk_memcpy( &sNSQ_copy, &psEnc->sCmn.sNSQ, sizeof( silk_nsq_state ) );
193         seed_copy = psEnc->sCmn.indices.Seed;
194         ec_prevLagIndex_copy = psEnc->sCmn.ec_prevLagIndex;
195         ec_prevSignalType_copy = psEnc->sCmn.ec_prevSignalType;
196         for( iter = 0; ; iter++ ) {
197             if( gainsID == gainsID_lower ) {
198                 nBits = nBits_lower;
199             } else if( gainsID == gainsID_upper ) {
200                 nBits = nBits_upper;
201             } else {
202                 /*****************************************/
203                 /* Noise shaping quantization            */
204                 /*****************************************/
205 TIC(NSQ)
206                 if( psEnc->sCmn.nStatesDelayedDecision > 1 || psEnc->sCmn.warping_Q16 > 0 ) {
207                     silk_NSQ_del_dec( &psEnc->sCmn, &psEnc->sCmn.sNSQ, &psEnc->sCmn.indices, xfw, psEnc->sCmn.pulses,
208                            sEncCtrl.PredCoef_Q12[ 0 ], sEncCtrl.LTPCoef_Q14, sEncCtrl.AR2_Q13, sEncCtrl.HarmShapeGain_Q14,
209                            sEncCtrl.Tilt_Q14, sEncCtrl.LF_shp_Q14, sEncCtrl.Gains_Q16, sEncCtrl.pitchL, sEncCtrl.Lambda_Q10, sEncCtrl.LTP_scale_Q14 );
210                 } else {
211                     silk_NSQ( &psEnc->sCmn, &psEnc->sCmn.sNSQ, &psEnc->sCmn.indices, xfw, psEnc->sCmn.pulses,
212                             sEncCtrl.PredCoef_Q12[ 0 ], sEncCtrl.LTPCoef_Q14, sEncCtrl.AR2_Q13, sEncCtrl.HarmShapeGain_Q14,
213                             sEncCtrl.Tilt_Q14, sEncCtrl.LF_shp_Q14, sEncCtrl.Gains_Q16, sEncCtrl.pitchL, sEncCtrl.Lambda_Q10, sEncCtrl.LTP_scale_Q14 );
214                 }
215 TOC(NSQ)
216
217                 /****************************************/
218                 /* Encode Parameters                    */
219                 /****************************************/
220 TIC(ENCODE_PARAMS)
221                 silk_encode_indices( &psEnc->sCmn, psRangeEnc, psEnc->sCmn.nFramesEncoded, 0, condCoding );
222 TOC(ENCODE_PARAMS)
223
224                 /****************************************/
225                 /* Encode Excitation Signal             */
226                 /****************************************/
227 TIC(ENCODE_PULSES)
228                 silk_encode_pulses( psRangeEnc, psEnc->sCmn.indices.signalType, psEnc->sCmn.indices.quantOffsetType,
229                     psEnc->sCmn.pulses, psEnc->sCmn.frame_length );
230 TOC(ENCODE_PULSES)
231
232                 nBits = ec_tell( psRangeEnc );
233
234                 if( useCBR == 0 && iter == 0 && nBits <= maxBits ) {
235                     break;
236                 }
237             }
238
239             if( iter == maxIter ) {
240                 if( found_lower && ( gainsID == gainsID_lower || nBits > maxBits ) ) {
241                     /* Restore output state from earlier iteration that did meet the bitrate budget */
242                     silk_memcpy( psRangeEnc, &sRangeEnc_copy2, sizeof( ec_enc ) );
243                     silk_assert( sRangeEnc_copy2.offs <= 1275 );
244                     silk_memcpy( psRangeEnc->buf, ec_buf_copy, sRangeEnc_copy2.offs );
245                     silk_memcpy( &psEnc->sCmn.sNSQ, &sNSQ_copy2, sizeof( silk_nsq_state ) );
246                     psEnc->sShape.LastGainIndex = LastGainIndex_copy2;
247                 }
248                 break;
249             }
250
251             if( nBits > maxBits ) {
252                 found_upper = 1;
253                 nBits_upper = nBits;
254                 gainMult_upper = gainMult_Q8;
255                 gainsID_upper = gainsID;
256                 if( found_lower == 0 && iter >= 2 ) {
257                     /* Adjust the quantizer's rate/distortion tradeoff */
258                     sEncCtrl.Lambda_Q10 = silk_ADD_RSHIFT32( sEncCtrl.Lambda_Q10, sEncCtrl.Lambda_Q10, 1 );
259                 }
260             } else if( nBits < maxBits - 5 ) {
261                 found_lower = 1;
262                 nBits_lower = nBits;
263                 gainMult_lower = gainMult_Q8;
264                 if( gainsID != gainsID_lower ) {
265                     gainsID_lower = gainsID;
266                     /* Copy part of the output state */
267                     silk_memcpy( &sRangeEnc_copy2, psRangeEnc, sizeof( ec_enc ) );
268                     silk_assert( psRangeEnc->offs <= 1275 );
269                     silk_memcpy( ec_buf_copy, psRangeEnc->buf, psRangeEnc->offs );
270                     silk_memcpy( &sNSQ_copy2, &psEnc->sCmn.sNSQ, sizeof( silk_nsq_state ) );
271                     LastGainIndex_copy2 = psEnc->sShape.LastGainIndex;
272                 }
273             } else {
274                 /* Within 5 bits of budget: close enough */
275                 break;
276             }
277
278             if( ( found_lower & found_upper ) == 0 ) {
279                 /* Adjust gain according to high-rate rate/distortion curve */
280                 opus_int32 gain_factor_Q16;
281                 gain_factor_Q16 = silk_log2lin( silk_LSHIFT( nBits - maxBits, 7 ) / psEnc->sCmn.frame_length + SILK_FIX_CONST( 16, 7 ) );
282                 gain_factor_Q16 = silk_min_32(gain_factor_Q16, SILK_FIX_CONST( 2, 16 ) );
283                 if( nBits > maxBits ) {
284                     gain_factor_Q16 = silk_max_32( gain_factor_Q16, SILK_FIX_CONST( 1.3, 16 ) );
285                 }
286                 gainMult_Q8 = silk_SMULWB( gain_factor_Q16, gainMult_Q8 );
287             } else {
288                 /* Adjust gain by interpolating */
289                 gainMult_Q8 = gainMult_lower + silk_DIV32_16( silk_MUL( gainMult_upper - gainMult_lower, maxBits - nBits_lower ), nBits_upper - nBits_lower );
290                 /* New gain multplier must be between 25% and 75% of old range (note that gainMult_upper < gainMult_lower) */
291                 if( gainMult_Q8 > silk_ADD_RSHIFT32( gainMult_lower, gainMult_upper - gainMult_lower, 2 ) ) {
292                     gainMult_Q8 = silk_ADD_RSHIFT32( gainMult_lower, gainMult_upper - gainMult_lower, 2 );
293                 } else
294                 if( gainMult_Q8 < silk_SUB_RSHIFT32( gainMult_upper, gainMult_upper - gainMult_lower, 2 ) ) {
295                     gainMult_Q8 = silk_SUB_RSHIFT32( gainMult_upper, gainMult_upper - gainMult_lower, 2 );
296                 }
297             }
298
299             for( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) {
300                 sEncCtrl.Gains_Q16[ i ] = silk_LSHIFT_SAT32( silk_SMULWB( sEncCtrl.GainsUnq_Q16[ i ], gainMult_Q8 ), 8 );
301             }
302  
303             /* Quantize gains */
304             psEnc->sShape.LastGainIndex = sEncCtrl.lastGainIndexPrev;
305             silk_gains_quant( psEnc->sCmn.indices.GainsIndices, sEncCtrl.Gains_Q16,
306                   &psEnc->sShape.LastGainIndex, condCoding == CODE_CONDITIONALLY, psEnc->sCmn.nb_subfr );
307
308             /* Unique identifier of gains vector */
309             gainsID = silk_gains_ID( psEnc->sCmn.indices.GainsIndices, psEnc->sCmn.nb_subfr );
310
311             /* Restore part of the input state */
312             silk_memcpy( psRangeEnc, &sRangeEnc_copy, sizeof( ec_enc ) );
313             silk_memcpy( &psEnc->sCmn.sNSQ, &sNSQ_copy, sizeof( silk_nsq_state ) );
314             psEnc->sCmn.indices.Seed = seed_copy;
315             psEnc->sCmn.ec_prevLagIndex = ec_prevLagIndex_copy;
316             psEnc->sCmn.ec_prevSignalType = ec_prevSignalType_copy;
317         }
318     }
319
320     /* Update input buffer */
321     silk_memmove( psEnc->x_buf, &psEnc->x_buf[ psEnc->sCmn.frame_length ],
322         ( psEnc->sCmn.ltp_mem_length + LA_SHAPE_MS * psEnc->sCmn.fs_kHz ) * sizeof( opus_int16 ) );
323
324     /* Parameters needed for next frame */
325     psEnc->sCmn.prevLag        = sEncCtrl.pitchL[ psEnc->sCmn.nb_subfr - 1 ];
326     psEnc->sCmn.prevSignalType = psEnc->sCmn.indices.signalType;
327
328     /* Exit without entropy coding */
329     if( psEnc->sCmn.prefillFlag ) {
330         /* No payload */
331         *pnBytesOut = 0;
332         return ret;
333     }
334
335     /****************************************/
336     /* Finalize payload                     */
337     /****************************************/
338     psEnc->sCmn.first_frame_after_reset = 0;
339     /* Payload size */
340     *pnBytesOut = silk_RSHIFT( ec_tell( psRangeEnc ) + 7, 3 );
341
342     TOC(ENCODE_FRAME)
343
344 #ifdef SAVE_ALL_INTERNAL_DATA
345     {
346         silk_float tmp[ MAX_NB_SUBFR * LTP_ORDER ];
347         int i;
348         DEBUG_STORE_DATA( xf.dat,                   x_frame + LA_SHAPE_MS * psEnc->sCmn.fs_kHz, psEnc->sCmn.frame_length * sizeof( opus_int16 ) );
349         DEBUG_STORE_DATA( xfw.dat,                  xfw,                            psEnc->sCmn.frame_length    * sizeof( opus_int16 ) );
350         DEBUG_STORE_DATA( pitchL.dat,               sEncCtrl.pitchL,                psEnc->sCmn.nb_subfr        * sizeof( opus_int ) );
351         for( i = 0; i < psEnc->sCmn.nb_subfr * LTP_ORDER; i++ ) {
352             tmp[ i ] = (silk_float)sEncCtrl.LTPCoef_Q14[ i ] / 16384.0f;
353         }
354         DEBUG_STORE_DATA( pitchG_quantized.dat,     tmp,                            psEnc->sCmn.nb_subfr * LTP_ORDER * sizeof( silk_float ) );
355         for( i = 0; i <psEnc->sCmn.predictLPCOrder; i++ ) {
356             tmp[ i ] = (silk_float)sEncCtrl.PredCoef_Q12[ 1 ][ i ] / 4096.0f;
357         }
358         DEBUG_STORE_DATA( PredCoef.dat,             tmp,                            psEnc->sCmn.predictLPCOrder * sizeof( silk_float ) );
359
360         tmp[ 0 ] = (silk_float)sEncCtrl.LTPredCodGain_Q7 / 128.0f;
361         DEBUG_STORE_DATA( LTPredCodGain.dat,        tmp,                            sizeof( silk_float ) );
362         tmp[ 0 ] = (silk_float)psEnc->LTPCorr_Q15 / 32768.0f;
363         DEBUG_STORE_DATA( LTPcorr.dat,              tmp,                            sizeof( silk_float ) );
364         tmp[ 0 ] = (silk_float)psEnc->sCmn.input_tilt_Q15 / 32768.0f;
365         DEBUG_STORE_DATA( tilt.dat,                 tmp,                            sizeof( silk_float ) );
366         for( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) {
367             tmp[ i ] = (silk_float)sEncCtrl.Gains_Q16[ i ] / 65536.0f;
368         }
369         DEBUG_STORE_DATA( gains.dat,                tmp,                            psEnc->sCmn.nb_subfr * sizeof( silk_float ) );
370         DEBUG_STORE_DATA( gains_indices.dat,        &psEnc->sCmn.indices.GainsIndices, psEnc->sCmn.nb_subfr * sizeof( opus_int ) );
371         tmp[ 0 ] = (silk_float)sEncCtrl.current_SNR_dB_Q7 / 128.0f;
372         DEBUG_STORE_DATA( current_SNR_db.dat,       tmp,                            sizeof( silk_float ) );
373         DEBUG_STORE_DATA( quantOffsetType.dat,      &psEnc->sCmn.indices.quantOffsetType, sizeof( opus_int ) );
374         tmp[ 0 ] = (silk_float)psEnc->sCmn.speech_activity_Q8 / 256.0f;
375         DEBUG_STORE_DATA( speech_activity.dat,      tmp,                            sizeof( silk_float ) );
376         for( i = 0; i < VAD_N_BANDS; i++ ) {
377             tmp[ i ] = (silk_float)psEnc->sCmn.input_quality_bands_Q15[ i ] / 32768.0f;
378         }
379         DEBUG_STORE_DATA( input_quality_bands.dat,  tmp,                       VAD_N_BANDS * sizeof( silk_float ) );
380         DEBUG_STORE_DATA( signalType.dat,           &psEnc->sCmn.indices.signalType,         sizeof( opus_int8) );
381         DEBUG_STORE_DATA( lag_index.dat,            &psEnc->sCmn.indices.lagIndex,           sizeof( opus_int16 ) );
382         DEBUG_STORE_DATA( contour_index.dat,        &psEnc->sCmn.indices.contourIndex,       sizeof( opus_int8 ) );
383         DEBUG_STORE_DATA( per_index.dat,            &psEnc->sCmn.indices.PERIndex,           sizeof( opus_int8) );
384     }
385 #endif
386     return ret;
387 }
388
389 /* Low-Bitrate Redundancy (LBRR) encoding. Reuse all parameters but encode excitation at lower bitrate  */
390 void silk_LBRR_encode_FIX(
391     silk_encoder_state_FIX          *psEnc,         /* I/O  Pointer to Silk FIX encoder state           */
392     silk_encoder_control_FIX        *psEncCtrl,     /* I/O  Pointer to Silk FIX encoder control struct  */
393     const opus_int16                 xfw[],          /* I    Input signal                                */
394     opus_int                         condCoding     /* I    The type of conditional coding used so far for this frame */
395 )
396 {
397     opus_int32   TempGains_Q16[ MAX_NB_SUBFR ];
398     SideInfoIndices *psIndices_LBRR = &psEnc->sCmn.indices_LBRR[ psEnc->sCmn.nFramesEncoded ];
399     silk_nsq_state sNSQ_LBRR;
400
401     /*******************************************/
402     /* Control use of inband LBRR              */
403     /*******************************************/
404     if( psEnc->sCmn.LBRR_enabled && psEnc->sCmn.speech_activity_Q8 > SILK_FIX_CONST( LBRR_SPEECH_ACTIVITY_THRES, 8 ) ) {
405         psEnc->sCmn.LBRR_flags[ psEnc->sCmn.nFramesEncoded ] = 1;
406
407         /* Copy noise shaping quantizer state and quantization indices from regular encoding */
408         silk_memcpy( &sNSQ_LBRR, &psEnc->sCmn.sNSQ, sizeof( silk_nsq_state ) );
409         silk_memcpy( psIndices_LBRR, &psEnc->sCmn.indices, sizeof( SideInfoIndices ) );
410
411         /* Save original gains */
412         silk_memcpy( TempGains_Q16, psEncCtrl->Gains_Q16, psEnc->sCmn.nb_subfr * sizeof( opus_int32 ) );
413
414         if( psEnc->sCmn.nFramesEncoded == 0 || psEnc->sCmn.LBRR_flags[ psEnc->sCmn.nFramesEncoded - 1 ] == 0 ) {
415             /* First frame in packet or previous frame not LBRR coded */
416             psEnc->sCmn.LBRRprevLastGainIndex = psEnc->sShape.LastGainIndex;
417
418             /* Increase Gains to get target LBRR rate */
419             psIndices_LBRR->GainsIndices[ 0 ] = psIndices_LBRR->GainsIndices[ 0 ] + psEnc->sCmn.LBRR_GainIncreases;
420             psIndices_LBRR->GainsIndices[ 0 ] = silk_min_int( psIndices_LBRR->GainsIndices[ 0 ], N_LEVELS_QGAIN - 1 );
421         }
422
423         /* Decode to get gains in sync with decoder         */
424         /* Overwrite unquantized gains with quantized gains */
425         silk_gains_dequant( psEncCtrl->Gains_Q16, psIndices_LBRR->GainsIndices,
426             &psEnc->sCmn.LBRRprevLastGainIndex, condCoding == CODE_CONDITIONALLY, psEnc->sCmn.nb_subfr );
427
428         /*****************************************/
429         /* Noise shaping quantization            */
430         /*****************************************/
431         if( psEnc->sCmn.nStatesDelayedDecision > 1 || psEnc->sCmn.warping_Q16 > 0 ) {
432             silk_NSQ_del_dec( &psEnc->sCmn, &sNSQ_LBRR, psIndices_LBRR, xfw,
433                 psEnc->sCmn.pulses_LBRR[ psEnc->sCmn.nFramesEncoded ], psEncCtrl->PredCoef_Q12[ 0 ], psEncCtrl->LTPCoef_Q14,
434                 psEncCtrl->AR2_Q13, psEncCtrl->HarmShapeGain_Q14, psEncCtrl->Tilt_Q14, psEncCtrl->LF_shp_Q14,
435                 psEncCtrl->Gains_Q16, psEncCtrl->pitchL, psEncCtrl->Lambda_Q10, psEncCtrl->LTP_scale_Q14 );
436         } else {
437             silk_NSQ( &psEnc->sCmn, &sNSQ_LBRR, psIndices_LBRR, xfw,
438                 psEnc->sCmn.pulses_LBRR[ psEnc->sCmn.nFramesEncoded ], psEncCtrl->PredCoef_Q12[ 0 ], psEncCtrl->LTPCoef_Q14,
439                 psEncCtrl->AR2_Q13, psEncCtrl->HarmShapeGain_Q14, psEncCtrl->Tilt_Q14, psEncCtrl->LF_shp_Q14,
440                 psEncCtrl->Gains_Q16, psEncCtrl->pitchL, psEncCtrl->Lambda_Q10, psEncCtrl->LTP_scale_Q14 );
441         }
442
443         /* Restore original gains */
444         silk_memcpy( psEncCtrl->Gains_Q16, TempGains_Q16, psEnc->sCmn.nb_subfr * sizeof( opus_int32 ) );
445     }
446 }