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