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