summaryrefslogtreecommitdiff
path: root/lib/rbcodec/codecs/libopus/silk/fixed/encode_frame_FIX.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/rbcodec/codecs/libopus/silk/fixed/encode_frame_FIX.c')
-rw-r--r--lib/rbcodec/codecs/libopus/silk/fixed/encode_frame_FIX.c448
1 files changed, 448 insertions, 0 deletions
diff --git a/lib/rbcodec/codecs/libopus/silk/fixed/encode_frame_FIX.c b/lib/rbcodec/codecs/libopus/silk/fixed/encode_frame_FIX.c
new file mode 100644
index 0000000000..a02bf87dbb
--- /dev/null
+++ b/lib/rbcodec/codecs/libopus/silk/fixed/encode_frame_FIX.c
@@ -0,0 +1,448 @@
1/***********************************************************************
2Copyright (c) 2006-2011, Skype Limited. All rights reserved.
3Redistribution and use in source and binary forms, with or without
4modification, are permitted provided that the following conditions
5are met:
6- Redistributions of source code must retain the above copyright notice,
7this list of conditions and the following disclaimer.
8- Redistributions in binary form must reproduce the above copyright
9notice, this list of conditions and the following disclaimer in the
10documentation and/or other materials provided with the distribution.
11- Neither the name of Internet Society, IETF or IETF Trust, nor the
12names of specific contributors, may be used to endorse or promote
13products derived from this software without specific prior written
14permission.
15THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25POSSIBILITY 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 */
38static 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
45void 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/****************/
85opus_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 silk_nsq_state sNSQ_copy, sNSQ_copy2;
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 SAVE_STACK;
109
110 /* This is totally unnecessary but many compilers (including gcc) are too dumb to realise it */
111 LastGainIndex_copy2 = nBits_lower = nBits_upper = gainMult_lower = gainMult_upper = 0;
112
113 psEnc->sCmn.indices.Seed = psEnc->sCmn.frameCounter++ & 3;
114
115 /**************************************************************/
116 /* Set up Input Pointers, and insert frame in input buffer */
117 /*************************************************************/
118 /* start of frame to encode */
119 x_frame = psEnc->x_buf + psEnc->sCmn.ltp_mem_length;
120
121 /***************************************/
122 /* Ensure smooth bandwidth transitions */
123 /***************************************/
124 silk_LP_variable_cutoff( &psEnc->sCmn.sLP, psEnc->sCmn.inputBuf + 1, psEnc->sCmn.frame_length );
125
126 /*******************************************/
127 /* Copy new frame to front of input buffer */
128 /*******************************************/
129 silk_memcpy( x_frame + LA_SHAPE_MS * psEnc->sCmn.fs_kHz, psEnc->sCmn.inputBuf + 1, psEnc->sCmn.frame_length * sizeof( opus_int16 ) );
130
131 if( !psEnc->sCmn.prefillFlag ) {
132 VARDECL( opus_int16, res_pitch );
133 VARDECL( opus_uint8, ec_buf_copy );
134 opus_int16 *res_pitch_frame;
135
136 ALLOC( res_pitch,
137 psEnc->sCmn.la_pitch + psEnc->sCmn.frame_length
138 + psEnc->sCmn.ltp_mem_length, opus_int16 );
139 /* start of pitch LPC residual frame */
140 res_pitch_frame = res_pitch + psEnc->sCmn.ltp_mem_length;
141
142 /*****************************************/
143 /* Find pitch lags, initial LPC analysis */
144 /*****************************************/
145 silk_find_pitch_lags_FIX( psEnc, &sEncCtrl, res_pitch, x_frame - psEnc->sCmn.ltp_mem_length, psEnc->sCmn.arch );
146
147 /************************/
148 /* Noise shape analysis */
149 /************************/
150 silk_noise_shape_analysis_FIX( psEnc, &sEncCtrl, res_pitch_frame, x_frame, psEnc->sCmn.arch );
151
152 /***************************************************/
153 /* Find linear prediction coefficients (LPC + LTP) */
154 /***************************************************/
155 silk_find_pred_coefs_FIX( psEnc, &sEncCtrl, res_pitch_frame, x_frame, condCoding );
156
157 /****************************************/
158 /* Process gains */
159 /****************************************/
160 silk_process_gains_FIX( psEnc, &sEncCtrl, condCoding );
161
162 /****************************************/
163 /* Low Bitrate Redundant Encoding */
164 /****************************************/
165 silk_LBRR_encode_FIX( psEnc, &sEncCtrl, x_frame, condCoding );
166
167 /* Loop over quantizer and entropy coding to control bitrate */
168 maxIter = 6;
169 gainMult_Q8 = SILK_FIX_CONST( 1, 8 );
170 found_lower = 0;
171 found_upper = 0;
172 gainsID = silk_gains_ID( psEnc->sCmn.indices.GainsIndices, psEnc->sCmn.nb_subfr );
173 gainsID_lower = -1;
174 gainsID_upper = -1;
175 /* Copy part of the input state */
176 silk_memcpy( &sRangeEnc_copy, psRangeEnc, sizeof( ec_enc ) );
177 silk_memcpy( &sNSQ_copy, &psEnc->sCmn.sNSQ, sizeof( silk_nsq_state ) );
178 seed_copy = psEnc->sCmn.indices.Seed;
179 ec_prevLagIndex_copy = psEnc->sCmn.ec_prevLagIndex;
180 ec_prevSignalType_copy = psEnc->sCmn.ec_prevSignalType;
181 ALLOC( ec_buf_copy, 1275, opus_uint8 );
182 for( iter = 0; ; iter++ ) {
183 if( gainsID == gainsID_lower ) {
184 nBits = nBits_lower;
185 } else if( gainsID == gainsID_upper ) {
186 nBits = nBits_upper;
187 } else {
188 /* Restore part of the input state */
189 if( iter > 0 ) {
190 silk_memcpy( psRangeEnc, &sRangeEnc_copy, sizeof( ec_enc ) );
191 silk_memcpy( &psEnc->sCmn.sNSQ, &sNSQ_copy, sizeof( silk_nsq_state ) );
192 psEnc->sCmn.indices.Seed = seed_copy;
193 psEnc->sCmn.ec_prevLagIndex = ec_prevLagIndex_copy;
194 psEnc->sCmn.ec_prevSignalType = ec_prevSignalType_copy;
195 }
196
197 /*****************************************/
198 /* Noise shaping quantization */
199 /*****************************************/
200 if( psEnc->sCmn.nStatesDelayedDecision > 1 || psEnc->sCmn.warping_Q16 > 0 ) {
201 silk_NSQ_del_dec( &psEnc->sCmn, &psEnc->sCmn.sNSQ, &psEnc->sCmn.indices, x_frame, psEnc->sCmn.pulses,
202 sEncCtrl.PredCoef_Q12[ 0 ], sEncCtrl.LTPCoef_Q14, sEncCtrl.AR_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 psEnc->sCmn.arch );
205 } else {
206 silk_NSQ( &psEnc->sCmn, &psEnc->sCmn.sNSQ, &psEnc->sCmn.indices, x_frame, psEnc->sCmn.pulses,
207 sEncCtrl.PredCoef_Q12[ 0 ], sEncCtrl.LTPCoef_Q14, sEncCtrl.AR_Q13, sEncCtrl.HarmShapeGain_Q14,
208 sEncCtrl.Tilt_Q14, sEncCtrl.LF_shp_Q14, sEncCtrl.Gains_Q16, sEncCtrl.pitchL, sEncCtrl.Lambda_Q10, sEncCtrl.LTP_scale_Q14,
209 psEnc->sCmn.arch);
210 }
211
212 if ( iter == maxIter && !found_lower ) {
213 silk_memcpy( &sRangeEnc_copy2, psRangeEnc, sizeof( ec_enc ) );
214 }
215
216 /****************************************/
217 /* Encode Parameters */
218 /****************************************/
219 silk_encode_indices( &psEnc->sCmn, psRangeEnc, psEnc->sCmn.nFramesEncoded, 0, condCoding );
220
221 /****************************************/
222 /* Encode Excitation Signal */
223 /****************************************/
224 silk_encode_pulses( psRangeEnc, psEnc->sCmn.indices.signalType, psEnc->sCmn.indices.quantOffsetType,
225 psEnc->sCmn.pulses, psEnc->sCmn.frame_length );
226
227 nBits = ec_tell( psRangeEnc );
228
229 /* If we still bust after the last iteration, do some damage control. */
230 if ( iter == maxIter && !found_lower && nBits > maxBits ) {
231 silk_memcpy( psRangeEnc, &sRangeEnc_copy2, sizeof( ec_enc ) );
232
233 /* Keep gains the same as the last frame. */
234 psEnc->sShape.LastGainIndex = sEncCtrl.lastGainIndexPrev;
235 for ( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) {
236 psEnc->sCmn.indices.GainsIndices[ i ] = 4;
237 }
238 if (condCoding != CODE_CONDITIONALLY) {
239 psEnc->sCmn.indices.GainsIndices[ 0 ] = sEncCtrl.lastGainIndexPrev;
240 }
241 psEnc->sCmn.ec_prevLagIndex = ec_prevLagIndex_copy;
242 psEnc->sCmn.ec_prevSignalType = ec_prevSignalType_copy;
243 /* Clear all pulses. */
244 for ( i = 0; i < psEnc->sCmn.frame_length; i++ ) {
245 psEnc->sCmn.pulses[ i ] = 0;
246 }
247
248 silk_encode_indices( &psEnc->sCmn, psRangeEnc, psEnc->sCmn.nFramesEncoded, 0, condCoding );
249
250 silk_encode_pulses( psRangeEnc, psEnc->sCmn.indices.signalType, psEnc->sCmn.indices.quantOffsetType,
251 psEnc->sCmn.pulses, psEnc->sCmn.frame_length );
252
253 nBits = ec_tell( psRangeEnc );
254 }
255
256 if( useCBR == 0 && iter == 0 && nBits <= maxBits ) {
257 break;
258 }
259 }
260
261 if( iter == maxIter ) {
262 if( found_lower && ( gainsID == gainsID_lower || nBits > maxBits ) ) {
263 /* Restore output state from earlier iteration that did meet the bitrate budget */
264 silk_memcpy( psRangeEnc, &sRangeEnc_copy2, sizeof( ec_enc ) );
265 celt_assert( sRangeEnc_copy2.offs <= 1275 );
266 silk_memcpy( psRangeEnc->buf, ec_buf_copy, sRangeEnc_copy2.offs );
267 silk_memcpy( &psEnc->sCmn.sNSQ, &sNSQ_copy2, sizeof( silk_nsq_state ) );
268 psEnc->sShape.LastGainIndex = LastGainIndex_copy2;
269 }
270 break;
271 }
272
273 if( nBits > maxBits ) {
274 if( found_lower == 0 && iter >= 2 ) {
275 /* Adjust the quantizer's rate/distortion tradeoff and discard previous "upper" results */
276 sEncCtrl.Lambda_Q10 = silk_ADD_RSHIFT32( sEncCtrl.Lambda_Q10, sEncCtrl.Lambda_Q10, 1 );
277 found_upper = 0;
278 gainsID_upper = -1;
279 } else {
280 found_upper = 1;
281 nBits_upper = nBits;
282 gainMult_upper = gainMult_Q8;
283 gainsID_upper = gainsID;
284 }
285 } else if( nBits < maxBits - 5 ) {
286 found_lower = 1;
287 nBits_lower = nBits;
288 gainMult_lower = gainMult_Q8;
289 if( gainsID != gainsID_lower ) {
290 gainsID_lower = gainsID;
291 /* Copy part of the output state */
292 silk_memcpy( &sRangeEnc_copy2, psRangeEnc, sizeof( ec_enc ) );
293 celt_assert( psRangeEnc->offs <= 1275 );
294 silk_memcpy( ec_buf_copy, psRangeEnc->buf, psRangeEnc->offs );
295 silk_memcpy( &sNSQ_copy2, &psEnc->sCmn.sNSQ, sizeof( silk_nsq_state ) );
296 LastGainIndex_copy2 = psEnc->sShape.LastGainIndex;
297 }
298 } else {
299 /* Within 5 bits of budget: close enough */
300 break;
301 }
302
303 if ( !found_lower && nBits > maxBits ) {
304 int j;
305 for ( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) {
306 int sum=0;
307 for ( j = i*psEnc->sCmn.subfr_length; j < (i+1)*psEnc->sCmn.subfr_length; j++ ) {
308 sum += abs( psEnc->sCmn.pulses[j] );
309 }
310 if ( iter == 0 || (sum < best_sum[i] && !gain_lock[i]) ) {
311 best_sum[i] = sum;
312 best_gain_mult[i] = gainMult_Q8;
313 } else {
314 gain_lock[i] = 1;
315 }
316 }
317 }
318 if( ( found_lower & found_upper ) == 0 ) {
319 /* Adjust gain according to high-rate rate/distortion curve */
320 if( nBits > maxBits ) {
321 if (gainMult_Q8 < 16384) {
322 gainMult_Q8 *= 2;
323 } else {
324 gainMult_Q8 = 32767;
325 }
326 } else {
327 opus_int32 gain_factor_Q16;
328 gain_factor_Q16 = silk_log2lin( silk_LSHIFT( nBits - maxBits, 7 ) / psEnc->sCmn.frame_length + SILK_FIX_CONST( 16, 7 ) );
329 gainMult_Q8 = silk_SMULWB( gain_factor_Q16, gainMult_Q8 );
330 }
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 multplier 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 */
392static 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 silk_nsq_state sNSQ_LBRR;
402
403 /*******************************************/
404 /* Control use of inband LBRR */
405 /*******************************************/
406 if( psEnc->sCmn.LBRR_enabled && psEnc->sCmn.speech_activity_Q8 > SILK_FIX_CONST( LBRR_SPEECH_ACTIVITY_THRES, 8 ) ) {
407 psEnc->sCmn.LBRR_flags[ psEnc->sCmn.nFramesEncoded ] = 1;
408
409 /* Copy noise shaping quantizer state and quantization indices from regular encoding */
410 silk_memcpy( &sNSQ_LBRR, &psEnc->sCmn.sNSQ, sizeof( silk_nsq_state ) );
411 silk_memcpy( psIndices_LBRR, &psEnc->sCmn.indices, sizeof( SideInfoIndices ) );
412
413 /* Save original gains */
414 silk_memcpy( TempGains_Q16, psEncCtrl->Gains_Q16, psEnc->sCmn.nb_subfr * sizeof( opus_int32 ) );
415
416 if( psEnc->sCmn.nFramesEncoded == 0 || psEnc->sCmn.LBRR_flags[ psEnc->sCmn.nFramesEncoded - 1 ] == 0 ) {
417 /* First frame in packet or previous frame not LBRR coded */
418 psEnc->sCmn.LBRRprevLastGainIndex = psEnc->sShape.LastGainIndex;
419
420 /* Increase Gains to get target LBRR rate */
421 psIndices_LBRR->GainsIndices[ 0 ] = psIndices_LBRR->GainsIndices[ 0 ] + psEnc->sCmn.LBRR_GainIncreases;
422 psIndices_LBRR->GainsIndices[ 0 ] = silk_min_int( psIndices_LBRR->GainsIndices[ 0 ], N_LEVELS_QGAIN - 1 );
423 }
424
425 /* Decode to get gains in sync with decoder */
426 /* Overwrite unquantized gains with quantized gains */
427 silk_gains_dequant( psEncCtrl->Gains_Q16, psIndices_LBRR->GainsIndices,
428 &psEnc->sCmn.LBRRprevLastGainIndex, condCoding == CODE_CONDITIONALLY, psEnc->sCmn.nb_subfr );
429
430 /*****************************************/
431 /* Noise shaping quantization */
432 /*****************************************/
433 if( psEnc->sCmn.nStatesDelayedDecision > 1 || psEnc->sCmn.warping_Q16 > 0 ) {
434 silk_NSQ_del_dec( &psEnc->sCmn, &sNSQ_LBRR, psIndices_LBRR, x16,
435 psEnc->sCmn.pulses_LBRR[ psEnc->sCmn.nFramesEncoded ], psEncCtrl->PredCoef_Q12[ 0 ], psEncCtrl->LTPCoef_Q14,
436 psEncCtrl->AR_Q13, psEncCtrl->HarmShapeGain_Q14, psEncCtrl->Tilt_Q14, psEncCtrl->LF_shp_Q14,
437 psEncCtrl->Gains_Q16, psEncCtrl->pitchL, psEncCtrl->Lambda_Q10, psEncCtrl->LTP_scale_Q14, psEnc->sCmn.arch );
438 } else {
439 silk_NSQ( &psEnc->sCmn, &sNSQ_LBRR, 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 }
444
445 /* Restore original gains */
446 silk_memcpy( psEncCtrl->Gains_Q16, TempGains_Q16, psEnc->sCmn.nb_subfr * sizeof( opus_int32 ) );
447 }
448}