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