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