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