Update SILK code using the CELT range coder
[opus.git] / src_FLP / SKP_Silk_encode_frame_FLP.c
1 #include <stdlib.h>\r
2 #include "SKP_Silk_main_FLP.h"\r
3 \r
4 /****************/\r
5 /* Encode frame */\r
6 /****************/\r
7 SKP_int SKP_Silk_encode_frame_FLP( \r
8     SKP_Silk_encoder_state_FLP      *psEnc,             /* I/O  Encoder state FLP                       */\r
9           SKP_uint8                 *pCode,             /* O    Payload                                 */\r
10           SKP_int16                 *pnBytesOut,        /* I/O  Number of payload bytes;                */\r
11                                                         /*      input: max length; output: used         */\r
12     const SKP_int16                 *pIn                /* I    Input speech frame                      */\r
13 )\r
14 {\r
15     SKP_Silk_encoder_control_FLP sEncCtrl;\r
16     SKP_int     k, i, nBytes, ret = 0;\r
17     SKP_float   *x_frame, *res_pitch_frame;\r
18     SKP_int16   pIn_HP[    MAX_FRAME_LENGTH ];\r
19     SKP_int16   pIn_HP_LP[ MAX_FRAME_LENGTH ];\r
20     SKP_float   xfw[       MAX_FRAME_LENGTH ];\r
21     SKP_float   res_pitch[ 2 * MAX_FRAME_LENGTH + LA_PITCH_MAX ];\r
22     SKP_int     LBRR_idx, frame_terminator;\r
23 \r
24     /* Low bitrate redundancy parameters */\r
25     SKP_uint8   LBRRpayload[ MAX_ARITHM_BYTES ];\r
26     SKP_int16   nBytesLBRR;\r
27 \r
28     ec_byte_buffer range_enc_celt_buf;\r
29 \r
30     const SKP_uint16 *FrameTermination_CDF;\r
31 \r
32 TIC(ENCODE_FRAME)\r
33 \r
34     sEncCtrl.sCmn.Seed = psEnc->sCmn.frameCounter++ & 3;\r
35     /**************************************************************/\r
36     /* Setup Input Pointers, and insert frame in input buffer    */\r
37     /*************************************************************/\r
38     /* pointers aligned with start of frame to encode */\r
39     x_frame         = psEnc->x_buf + psEnc->sCmn.ltp_mem_length;    /* start of frame to encode */\r
40     res_pitch_frame = res_pitch    + psEnc->sCmn.ltp_mem_length;    /* start of pitch LPC residual frame */\r
41 \r
42     /****************************/\r
43     /* Voice Activity Detection */\r
44     /****************************/\r
45 TIC(VAD)\r
46     SKP_Silk_VAD_FLP( psEnc, &sEncCtrl, pIn );\r
47 TOC(VAD)\r
48 \r
49     /*******************************************/\r
50     /* High-pass filtering of the input signal */\r
51     /*******************************************/\r
52 TIC(HP_IN)\r
53 #if HIGH_PASS_INPUT\r
54     /* Variable high-pass filter */\r
55     SKP_Silk_HP_variable_cutoff_FLP( psEnc, &sEncCtrl, pIn_HP, pIn );\r
56 #else\r
57     SKP_memcpy( pIn_HP, pIn, psEnc->sCmn.frame_length * sizeof( SKP_int16 ) );\r
58 #endif\r
59 TOC(HP_IN)\r
60 \r
61 #if SWITCH_TRANSITION_FILTERING\r
62     /* Ensure smooth bandwidth transitions */\r
63     SKP_Silk_LP_variable_cutoff( &psEnc->sCmn.sLP, pIn_HP_LP, pIn_HP, psEnc->sCmn.frame_length );\r
64 #else\r
65     SKP_memcpy( pIn_HP_LP, pIn_HP, psEnc->sCmn.frame_length * sizeof( SKP_int16 ) );\r
66 #endif\r
67 \r
68     /*******************************************/\r
69     /* Copy new frame to front of input buffer */\r
70     /*******************************************/\r
71     SKP_short2float_array( x_frame + psEnc->sCmn.la_shape, pIn_HP_LP, psEnc->sCmn.frame_length );\r
72 \r
73     /* Add tiny signal to avoid high CPU load from denormalized floating point numbers */\r
74     for( k = 0; k < 8; k++ ) {\r
75         x_frame[ psEnc->sCmn.la_shape + k * ( psEnc->sCmn.frame_length >> 3 ) ] += ( 1 - ( k & 2 ) ) * 1e-6f;\r
76     }\r
77 \r
78     /*****************************************/\r
79     /* Find pitch lags, initial LPC analysis */\r
80     /*****************************************/\r
81 TIC(FIND_PITCH)\r
82     SKP_Silk_find_pitch_lags_FLP( psEnc, &sEncCtrl, res_pitch, x_frame );\r
83 TOC(FIND_PITCH)\r
84 \r
85     /************************/\r
86     /* Noise shape analysis */\r
87     /************************/\r
88 TIC(NOISE_SHAPE_ANALYSIS)\r
89     SKP_Silk_noise_shape_analysis_FLP( psEnc, &sEncCtrl, res_pitch_frame, x_frame );\r
90 TOC(NOISE_SHAPE_ANALYSIS)\r
91 \r
92     /*****************************************/\r
93     /* Prefiltering for noise shaper         */\r
94     /*****************************************/\r
95 TIC(PREFILTER)\r
96     SKP_Silk_prefilter_FLP( psEnc, &sEncCtrl, xfw, x_frame );\r
97 TOC(PREFILTER)\r
98 \r
99     /***************************************************/\r
100     /* Find linear prediction coefficients (LPC + LTP) */\r
101     /***************************************************/\r
102 TIC(FIND_PRED_COEF)\r
103     SKP_Silk_find_pred_coefs_FLP( psEnc, &sEncCtrl, res_pitch );\r
104 TOC(FIND_PRED_COEF)\r
105 \r
106     /****************************************/\r
107     /* Process gains                        */\r
108     /****************************************/\r
109 TIC(PROCESS_GAINS)\r
110     SKP_Silk_process_gains_FLP( psEnc, &sEncCtrl );\r
111 TOC(PROCESS_GAINS)\r
112     \r
113     psEnc->sCmn.sigtype[         psEnc->sCmn.nFramesInPayloadBuf ] = sEncCtrl.sCmn.sigtype;\r
114     psEnc->sCmn.QuantOffsetType[ psEnc->sCmn.nFramesInPayloadBuf ] = sEncCtrl.sCmn.QuantOffsetType;\r
115     /****************************************/\r
116     /* Low Bitrate Redundant Encoding       */\r
117     /****************************************/\r
118     nBytesLBRR = MAX_ARITHM_BYTES;\r
119 TIC(LBRR)\r
120     SKP_Silk_LBRR_encode_FLP( psEnc, &sEncCtrl, LBRRpayload, &nBytesLBRR, xfw );\r
121 TOC(LBRR)\r
122 \r
123     /*****************************************/\r
124     /* Noise shaping quantization            */\r
125     /*****************************************/\r
126 TIC(NSQ)\r
127     SKP_Silk_NSQ_wrapper_FLP( psEnc, &sEncCtrl, xfw,\r
128         &psEnc->sCmn.q[ psEnc->sCmn.nFramesInPayloadBuf * psEnc->sCmn.frame_length ], 0 );\r
129 TOC(NSQ)\r
130 \r
131     /**************************************************/\r
132     /* Convert speech activity into VAD and DTX flags */\r
133     /**************************************************/\r
134     if( psEnc->speech_activity < SPEECH_ACTIVITY_DTX_THRES ) {\r
135         psEnc->sCmn.vadFlag = NO_VOICE_ACTIVITY;\r
136         psEnc->sCmn.noSpeechCounter++;\r
137         if( psEnc->sCmn.noSpeechCounter > NO_SPEECH_FRAMES_BEFORE_DTX ) {\r
138             psEnc->sCmn.inDTX = 1;\r
139         }\r
140         if( psEnc->sCmn.noSpeechCounter > MAX_CONSECUTIVE_DTX ) {\r
141             psEnc->sCmn.noSpeechCounter = 0;\r
142             psEnc->sCmn.inDTX           = 0;\r
143         }\r
144     } else {\r
145         psEnc->sCmn.noSpeechCounter = 0;\r
146         psEnc->sCmn.inDTX           = 0;\r
147         psEnc->sCmn.vadFlag         = VOICE_ACTIVITY;\r
148     }\r
149 \r
150     /****************************************/\r
151     /* Initialize arithmetic coder          */\r
152     /****************************************/\r
153     if( psEnc->sCmn.nFramesInPayloadBuf == 0 ) {\r
154         ec_byte_writeinit_buffer( &range_enc_celt_buf, psEnc->sCmn.sRC.buffer, MAX_ARITHM_BYTES );\r
155         ec_enc_init( &psEnc->sCmn.sRC.range_enc_celt_state, &range_enc_celt_buf );\r
156 \r
157         SKP_Silk_range_enc_init( &psEnc->sCmn.sRC );\r
158         psEnc->sCmn.nBytesInPayloadBuf = 0;\r
159     }\r
160 \r
161     /****************************************/\r
162     /* Encode Parameters                    */\r
163     /****************************************/\r
164 TIC(ENCODE_PARAMS)\r
165     SKP_Silk_encode_parameters_v4( &psEnc->sCmn, &sEncCtrl.sCmn, &psEnc->sCmn.sRC );\r
166     FrameTermination_CDF = SKP_Silk_FrameTermination_v4_CDF;\r
167 TOC(ENCODE_PARAMS)\r
168 \r
169     /****************************************/\r
170     /* Update Buffers and State             */\r
171     /****************************************/\r
172     /* Update input buffer */\r
173     SKP_memmove( psEnc->x_buf, &psEnc->x_buf[ psEnc->sCmn.frame_length ], \r
174         ( psEnc->sCmn.ltp_mem_length + psEnc->sCmn.la_shape ) * sizeof( SKP_float ) );\r
175     \r
176     /* Parameters needed for next frame */\r
177     psEnc->sCmn.prev_sigtype = sEncCtrl.sCmn.sigtype;\r
178     psEnc->sCmn.prevLag      = sEncCtrl.sCmn.pitchL[ psEnc->sCmn.nb_subfr - 1 ];\r
179     psEnc->sCmn.first_frame_after_reset = 0;\r
180 \r
181     if( psEnc->sCmn.sRC.error ) {\r
182         /* Encoder returned error: Clear payload buffer */\r
183         psEnc->sCmn.nFramesInPayloadBuf = 0;\r
184     } else {\r
185         psEnc->sCmn.nFramesInPayloadBuf++;\r
186     }\r
187 \r
188     /****************************************/\r
189     /* Finalize payload and copy to output  */\r
190     /****************************************/\r
191     if( psEnc->sCmn.nFramesInPayloadBuf * SUB_FRAME_LENGTH_MS * psEnc->sCmn.nb_subfr >= psEnc->sCmn.PacketSize_ms ) {\r
192 \r
193         LBRR_idx = ( psEnc->sCmn.oldest_LBRR_idx + 1 ) & LBRR_IDX_MASK;\r
194 \r
195         /* Check if FEC information should be added */\r
196         frame_terminator = SKP_SILK_LAST_FRAME;\r
197         if( psEnc->sCmn.LBRR_buffer[ LBRR_idx ].usage == SKP_SILK_ADD_LBRR_TO_PLUS1 ) {\r
198             frame_terminator = SKP_SILK_LBRR_VER1;\r
199         }\r
200         if( psEnc->sCmn.LBRR_buffer[ psEnc->sCmn.oldest_LBRR_idx ].usage == SKP_SILK_ADD_LBRR_TO_PLUS2 ) {\r
201             frame_terminator = SKP_SILK_LBRR_VER2;\r
202             LBRR_idx = psEnc->sCmn.oldest_LBRR_idx;\r
203         }\r
204 \r
205         /* Add the frame termination info to stream */\r
206         SKP_Silk_range_encoder( &psEnc->sCmn.sRC, frame_terminator, FrameTermination_CDF );\r
207         for( i = 0; i < psEnc->sCmn.nFramesInPayloadBuf; i++ ) {\r
208             SKP_Silk_encode_pulses( &psEnc->sCmn.sRC, psEnc->sCmn.sigtype[ i ], psEnc->sCmn.QuantOffsetType[ i ], \r
209                 &psEnc->sCmn.q[ i * psEnc->sCmn.frame_length ], psEnc->sCmn.frame_length );\r
210         }\r
211 \r
212         /* Payload length so far */\r
213         SKP_Silk_range_encoder_get_length( &psEnc->sCmn.sRC, &nBytes );\r
214 \r
215         /* Check that there is enough space in external output buffer, and move data */\r
216         if( *pnBytesOut >= nBytes ) {\r
217             SKP_int bits_in_stream, mask;\r
218             bits_in_stream = ec_enc_tell( &psEnc->sCmn.sRC.range_enc_celt_state, 0 );\r
219             ec_enc_done( &psEnc->sCmn.sRC.range_enc_celt_state );\r
220             \r
221             /* Fill up any remaining bits in the last byte with 1s */\r
222             if( bits_in_stream & 7 ) {\r
223                 mask = SKP_RSHIFT( 0xFF, bits_in_stream & 7 );\r
224                 if( nBytes - 1 < *pnBytesOut ) {\r
225                     psEnc->sCmn.sRC.range_enc_celt_state.buf->buf[ nBytes - 1 ] |= mask;\r
226                 }\r
227             }\r
228             SKP_memcpy( pCode, psEnc->sCmn.sRC.range_enc_celt_state.buf->buf, nBytes * sizeof( SKP_uint8 ) );\r
229 \r
230             if( frame_terminator > SKP_SILK_MORE_FRAMES && \r
231                     *pnBytesOut >= nBytes + psEnc->sCmn.LBRR_buffer[ LBRR_idx ].nBytes ) {\r
232                 /* Get old packet and add to payload. */\r
233                 SKP_memcpy( &pCode[ nBytes ],\r
234                     psEnc->sCmn.LBRR_buffer[ LBRR_idx ].payload,\r
235                     psEnc->sCmn.LBRR_buffer[ LBRR_idx ].nBytes * sizeof( SKP_uint8 ) );\r
236                 nBytes += psEnc->sCmn.LBRR_buffer[ LBRR_idx ].nBytes;\r
237             }\r
238             *pnBytesOut = nBytes;\r
239         \r
240             /* Update FEC buffer */\r
241             SKP_memcpy( psEnc->sCmn.LBRR_buffer[ psEnc->sCmn.oldest_LBRR_idx ].payload, LBRRpayload, \r
242                 nBytesLBRR * sizeof( SKP_uint8 ) );\r
243             psEnc->sCmn.LBRR_buffer[ psEnc->sCmn.oldest_LBRR_idx ].nBytes = nBytesLBRR;\r
244             /* The below line describes how FEC should be used */ \r
245             psEnc->sCmn.LBRR_buffer[ psEnc->sCmn.oldest_LBRR_idx ].usage = sEncCtrl.sCmn.LBRR_usage;\r
246             psEnc->sCmn.oldest_LBRR_idx = ( ( psEnc->sCmn.oldest_LBRR_idx + 1 ) & LBRR_IDX_MASK );\r
247 \r
248             /* Reset the number of frames in payload buffer */\r
249             psEnc->sCmn.nFramesInPayloadBuf = 0;\r
250         } else {\r
251             /* Not enough space: Payload will be discarded */\r
252             *pnBytesOut = 0;\r
253             nBytes      = 0;\r
254             psEnc->sCmn.nFramesInPayloadBuf = 0;\r
255             ret = SKP_SILK_ENC_PAYLOAD_BUF_TOO_SHORT;\r
256         }\r
257     } else {\r
258         /* No payload for you this time */\r
259         *pnBytesOut = 0;\r
260 \r
261         /* Encode that more frames follows */\r
262         frame_terminator = SKP_SILK_MORE_FRAMES;\r
263         SKP_Silk_range_encoder( &psEnc->sCmn.sRC, frame_terminator, FrameTermination_CDF );\r
264 \r
265         /* Payload length so far */\r
266         SKP_Silk_range_encoder_get_length( &psEnc->sCmn.sRC, &nBytes );\r
267 \r
268         /* Take into account the q signal that isn't in the bitstream yet */\r
269         nBytes += SKP_Silk_pulses_to_bytes( &psEnc->sCmn, \r
270             &psEnc->sCmn.q[ psEnc->sCmn.nFramesInPayloadBuf * psEnc->sCmn.frame_length ] );\r
271     }\r
272 \r
273     /* Check for arithmetic coder errors */\r
274     if( psEnc->sCmn.sRC.error ) {\r
275         ret = SKP_SILK_ENC_INTERNAL_ERROR;\r
276     }\r
277 \r
278     /* simulate number of ms buffered in channel because of exceeding TargetRate */\r
279     psEnc->BufferedInChannel_ms   += ( 8.0f * 1000.0f * ( nBytes - psEnc->sCmn.nBytesInPayloadBuf ) ) / psEnc->sCmn.TargetRate_bps;\r
280     psEnc->BufferedInChannel_ms   -= SUB_FRAME_LENGTH_MS * psEnc->sCmn.nb_subfr;\r
281     psEnc->BufferedInChannel_ms    = SKP_LIMIT_float( psEnc->BufferedInChannel_ms, 0.0f, 100.0f );\r
282     psEnc->sCmn.nBytesInPayloadBuf = nBytes;\r
283 \r
284     if( psEnc->speech_activity > WB_DETECT_ACTIVE_SPEECH_LEVEL_THRES ) {\r
285         psEnc->sCmn.sSWBdetect.ActiveSpeech_ms = SKP_ADD_POS_SAT32( psEnc->sCmn.sSWBdetect.ActiveSpeech_ms, SUB_FRAME_LENGTH_MS * psEnc->sCmn.nb_subfr ); \r
286     }\r
287 \r
288 TOC(ENCODE_FRAME)\r
289 #ifdef SAVE_ALL_INTERNAL_DATA\r
290     DEBUG_STORE_DATA( xf.dat,                   pIn_HP_LP,                           psEnc->sCmn.frame_length * sizeof( SKP_int16 ) );\r
291     DEBUG_STORE_DATA( xfw.dat,                  xfw,                                 psEnc->sCmn.frame_length * sizeof( SKP_float ) );\r
292 //  DEBUG_STORE_DATA( q.dat,                    q,                                   psEnc->sCmn.frame_length * sizeof( SKP_int   ) );\r
293     DEBUG_STORE_DATA( pitchL.dat,               sEncCtrl.sCmn.pitchL,                            MAX_NB_SUBFR * sizeof( SKP_int   ) );\r
294     DEBUG_STORE_DATA( pitchG_quantized.dat,     sEncCtrl.LTPCoef,            psEnc->sCmn.nb_subfr * LTP_ORDER * sizeof( SKP_float ) );\r
295     DEBUG_STORE_DATA( pitch_freq_low_Hz.dat,    &sEncCtrl.pitch_freq_low_Hz,                                    sizeof( SKP_float ) );\r
296     DEBUG_STORE_DATA( LTPcorr.dat,              &psEnc->LTPCorr,                                                sizeof( SKP_float ) );\r
297     DEBUG_STORE_DATA( tilt.dat,                 &sEncCtrl.input_tilt,                                           sizeof( SKP_float ) );\r
298     DEBUG_STORE_DATA( gains.dat,                sEncCtrl.Gains,                          psEnc->sCmn.nb_subfr * sizeof( SKP_float ) );\r
299 //    DEBUG_STORE_DATA( gains_indices.dat,        sEncCtrl.sCmn.GainsIndices, MAX_LAYERS * psEnc->sCmn.nb_subfr * sizeof( SKP_int   ) );\r
300     DEBUG_STORE_DATA( nBytes.dat,               &nBytes,                                                        sizeof( SKP_int   ) );\r
301     DEBUG_STORE_DATA( current_SNR_db.dat,       &sEncCtrl.current_SNR_dB,                                       sizeof( SKP_float ) );\r
302     DEBUG_STORE_DATA( QuantOffsetType.dat,      &sEncCtrl.sCmn.QuantOffsetType,                                 sizeof( SKP_int   ) );\r
303     DEBUG_STORE_DATA( speech_activity.dat,      &psEnc->speech_activity,                                        sizeof( SKP_float ) );\r
304     DEBUG_STORE_DATA( input_quality_bands.dat,  sEncCtrl.input_quality_bands,                     VAD_N_BANDS * sizeof( SKP_float ) );\r
305     DEBUG_STORE_DATA( sigtype.dat,              &sEncCtrl.sCmn.sigtype,                                         sizeof( SKP_int   ) ); \r
306     DEBUG_STORE_DATA( ratelevel.dat,            &sEncCtrl.sCmn.RateLevelIndex,                                  sizeof( SKP_int   ) ); \r
307     DEBUG_STORE_DATA( lag_index.dat,            &sEncCtrl.sCmn.lagIndex,                                        sizeof( SKP_int   ) ); \r
308     DEBUG_STORE_DATA( contour_index.dat,        &sEncCtrl.sCmn.contourIndex,                                    sizeof( SKP_int   ) ); \r
309     DEBUG_STORE_DATA( per_index.dat,            &sEncCtrl.sCmn.PERIndex,                                        sizeof( SKP_int   ) );\r
310     DEBUG_STORE_DATA( PredCoef.dat,             &sEncCtrl.PredCoef[ 1 ],          psEnc->sCmn.predictLPCOrder * sizeof( SKP_float ) );\r
311     DEBUG_STORE_DATA( ltp_scale_idx.dat,        &sEncCtrl.sCmn.LTP_scaleIndex,                                  sizeof( SKP_int   ) );\r
312 //  DEBUG_STORE_DATA( xq.dat,                   psEnc->sNSQ.xqBuf,                   psEnc->sCmn.frame_length * sizeof( SKP_float ) );\r
313 #endif\r
314     return( ret );\r
315 }\r
316 \r
317 /* Low Bitrate Redundancy (LBRR) encoding. Reuse all parameters but encode with lower bitrate           */\r
318 void SKP_Silk_LBRR_encode_FLP(\r
319     SKP_Silk_encoder_state_FLP      *psEnc,             /* I/O  Encoder state FLP                       */\r
320     SKP_Silk_encoder_control_FLP    *psEncCtrl,         /* I/O  Encoder control FLP                     */\r
321           SKP_uint8                 *pCode,             /* O    Payload                                 */\r
322           SKP_int16                 *pnBytesOut,        /* I/O  Payload bytes; in: max; out: used       */\r
323     const SKP_float                 xfw[]               /* I    Input signal                            */\r
324 )\r
325 {\r
326     SKP_int32   Gains_Q16[ MAX_NB_SUBFR ];\r
327     SKP_int     i, k, TempGainsIndices[ MAX_NB_SUBFR ], frame_terminator;\r
328     SKP_int     nBytes, nFramesInPayloadBuf;\r
329     SKP_float   TempGains[ MAX_NB_SUBFR ];\r
330     SKP_int     typeOffset, LTP_scaleIndex, Rate_only_parameters = 0;\r
331     ec_byte_buffer range_enc_celt_buf;\r
332 \r
333     /* Control use of inband LBRR */\r
334     SKP_Silk_LBRR_ctrl_FLP( psEnc, &psEncCtrl->sCmn );\r
335 \r
336     if( psEnc->sCmn.LBRR_enabled ) {\r
337         /* Save original gains */\r
338         SKP_memcpy( TempGainsIndices, psEncCtrl->sCmn.GainsIndices, MAX_NB_SUBFR * sizeof( SKP_int   ) );\r
339         SKP_memcpy( TempGains,        psEncCtrl->Gains,             MAX_NB_SUBFR * sizeof( SKP_float ) );\r
340 \r
341         typeOffset     = psEnc->sCmn.typeOffsetPrev; // Temp save as cannot be overwritten\r
342         LTP_scaleIndex = psEncCtrl->sCmn.LTP_scaleIndex;\r
343 \r
344         /* Set max rate where quant signal is encoded */\r
345         if( psEnc->sCmn.fs_kHz == 8 ) {\r
346             Rate_only_parameters = 13500;\r
347         } else if( psEnc->sCmn.fs_kHz == 12 ) {\r
348             Rate_only_parameters = 15500;\r
349         } else if( psEnc->sCmn.fs_kHz == 16 ) {\r
350             Rate_only_parameters = 17500;\r
351         } else if( psEnc->sCmn.fs_kHz == 24 ) {\r
352             Rate_only_parameters = 19500;\r
353         } else {\r
354             SKP_assert( 0 );\r
355         }\r
356 \r
357         if( psEnc->sCmn.Complexity > 0 && psEnc->sCmn.TargetRate_bps > Rate_only_parameters ) {\r
358             if( psEnc->sCmn.nFramesInPayloadBuf == 0 ) {\r
359                 /* First frame in packet copy everything */\r
360                 SKP_memcpy( &psEnc->sNSQ_LBRR, &psEnc->sNSQ, sizeof( SKP_Silk_nsq_state ) );\r
361                 psEnc->sCmn.LBRRprevLastGainIndex = psEnc->sShape.LastGainIndex;\r
362                 /* Increase Gains to get target LBRR rate */\r
363                 psEncCtrl->sCmn.GainsIndices[ 0 ] += psEnc->sCmn.LBRR_GainIncreases;\r
364                 psEncCtrl->sCmn.GainsIndices[ 0 ]  = SKP_LIMIT( psEncCtrl->sCmn.GainsIndices[ 0 ], 0, N_LEVELS_QGAIN - 1 );\r
365             }\r
366             /* Decode to get Gains in sync with decoder */\r
367             SKP_Silk_gains_dequant( Gains_Q16, psEncCtrl->sCmn.GainsIndices, \r
368                 &psEnc->sCmn.LBRRprevLastGainIndex, psEnc->sCmn.nFramesInPayloadBuf, psEnc->sCmn.nb_subfr );\r
369 \r
370             /* Overwrite unquantized gains with quantized gains and convert back to Q0 from Q16 */\r
371             for( k = 0; k <  psEnc->sCmn.nb_subfr; k++ ) {\r
372                 psEncCtrl->Gains[ k ] = Gains_Q16[ k ] / 65536.0f;\r
373             }\r
374 \r
375             /*****************************************/\r
376             /* Noise shaping quantization            */\r
377             /*****************************************/\r
378             SKP_Silk_NSQ_wrapper_FLP( psEnc, psEncCtrl, xfw, \r
379                 &psEnc->sCmn.q_LBRR[ psEnc->sCmn.nFramesInPayloadBuf * psEnc->sCmn.frame_length ], 1 );\r
380         } else {\r
381             SKP_memset( &psEnc->sCmn.q_LBRR[ psEnc->sCmn.nFramesInPayloadBuf * psEnc->sCmn.frame_length ], 0, \r
382                 psEnc->sCmn.frame_length * sizeof( SKP_int ) );\r
383 \r
384             psEncCtrl->sCmn.LTP_scaleIndex = 0;\r
385         }\r
386         /****************************************/\r
387         /* Initialize arithmetic coder          */\r
388         /****************************************/\r
389         if( psEnc->sCmn.nFramesInPayloadBuf == 0 ) {\r
390             ec_byte_writeinit_buffer( &range_enc_celt_buf, psEnc->sCmn.sRC_LBRR.buffer, MAX_ARITHM_BYTES );\r
391             ec_enc_init( &psEnc->sCmn.sRC_LBRR.range_enc_celt_state, &range_enc_celt_buf );\r
392 \r
393             SKP_Silk_range_enc_init( &psEnc->sCmn.sRC_LBRR );\r
394             psEnc->sCmn.nBytesInPayloadBuf = 0;\r
395         }\r
396 \r
397         /****************************************/\r
398         /* Encode Parameters                    */\r
399         /****************************************/\r
400         SKP_Silk_encode_parameters_v4( &psEnc->sCmn, &psEncCtrl->sCmn, &psEnc->sCmn.sRC_LBRR );\r
401         \r
402         /****************************************/\r
403         /* Encode Parameters                    */\r
404         /****************************************/\r
405         if( psEnc->sCmn.sRC_LBRR.error ) {\r
406             /* Encoder returned error: Clear payload buffer */\r
407             nFramesInPayloadBuf = 0;\r
408         } else {\r
409             nFramesInPayloadBuf = psEnc->sCmn.nFramesInPayloadBuf + 1;\r
410         }\r
411 \r
412         /****************************************/\r
413         /* Finalize payload and copy to output  */\r
414         /****************************************/\r
415         if( psEnc->sCmn.nFramesInPayloadBuf * SUB_FRAME_LENGTH_MS * psEnc->sCmn.nb_subfr >= psEnc->sCmn.PacketSize_ms ) {\r
416 \r
417             /* Check if FEC information should be added */\r
418             frame_terminator = SKP_SILK_LAST_FRAME;\r
419 \r
420             /* Add the frame termination info to stream */\r
421             SKP_Silk_range_encoder( &psEnc->sCmn.sRC_LBRR, frame_terminator, SKP_Silk_FrameTermination_v4_CDF );\r
422 \r
423             /*********************************************/\r
424             /* Encode quantization indices of excitation */\r
425             /*********************************************/\r
426             for( i = 0; i < nFramesInPayloadBuf; i++ ) {\r
427                 SKP_Silk_encode_pulses( &psEnc->sCmn.sRC_LBRR, psEnc->sCmn.sigtype[ i ], psEnc->sCmn.QuantOffsetType[ i ],\r
428                     &psEnc->sCmn.q_LBRR[ i * psEnc->sCmn.frame_length ], psEnc->sCmn.frame_length );\r
429             }\r
430 \r
431             /* Payload length so far */\r
432             SKP_Silk_range_encoder_get_length( &psEnc->sCmn.sRC_LBRR, &nBytes );\r
433 \r
434             /* Check that there is enough space in external output buffer and move data */\r
435             if( *pnBytesOut >= nBytes ) {\r
436                 SKP_int bits_in_stream, mask;\r
437                 bits_in_stream = ec_enc_tell( &psEnc->sCmn.sRC_LBRR.range_enc_celt_state, 0 );\r
438                 ec_enc_done( &psEnc->sCmn.sRC_LBRR.range_enc_celt_state );\r
439 \r
440                 /* Fill up any remaining bits in the last byte with 1s */\r
441                 if( bits_in_stream & 7 ) {\r
442                     mask = SKP_RSHIFT( 0xFF, bits_in_stream & 7 );\r
443                     if( nBytes - 1 < *pnBytesOut ) {\r
444                         psEnc->sCmn.sRC_LBRR.range_enc_celt_state.buf->buf[ nBytes - 1 ] |= mask;\r
445                     }\r
446                 }\r
447                 SKP_memcpy( pCode, psEnc->sCmn.sRC_LBRR.range_enc_celt_state.buf->buf, nBytes * sizeof( SKP_uint8 ) );\r
448 \r
449                 *pnBytesOut = nBytes;               \r
450             } else {\r
451                 /* Not enough space: Payload will be discarded */\r
452                 *pnBytesOut = 0;\r
453                 SKP_assert( 0 );\r
454             }\r
455         } else {\r
456             /* No payload for you this time */\r
457             *pnBytesOut = 0;\r
458 \r
459             /* Encode that more frames follows */\r
460             frame_terminator = SKP_SILK_MORE_FRAMES;\r
461             SKP_Silk_range_encoder( &psEnc->sCmn.sRC_LBRR, frame_terminator, SKP_Silk_FrameTermination_v4_CDF );\r
462         }\r
463 \r
464         /* Restore original Gains */\r
465         SKP_memcpy( psEncCtrl->sCmn.GainsIndices, TempGainsIndices,  psEnc->sCmn.nb_subfr * sizeof( SKP_int   ) );\r
466         SKP_memcpy( psEncCtrl->Gains,             TempGains,         psEnc->sCmn.nb_subfr * sizeof( SKP_float ) );\r
467     \r
468         /* Restore LTP scale index and typeoffset */\r
469         psEncCtrl->sCmn.LTP_scaleIndex = LTP_scaleIndex;\r
470         psEnc->sCmn.typeOffsetPrev     = typeOffset;\r
471     }\r
472 }\r