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