Big SILK update
[opus.git] / src_FIX / SKP_Silk_encode_frame_FIX.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_FIX.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_FIX( \r
35     SKP_Silk_encoder_state_FIX      *psEnc,             /* I/O  Encoder state FIX                       */\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_FIX sEncCtrl;\r
43     SKP_int     i, nBytes, ret = 0;\r
44     SKP_int16   *x_frame, *res_pitch_frame;\r
45     SKP_int16   xfw[ MAX_FRAME_LENGTH ];\r
46     SKP_int16   pIn_HP[ MAX_FRAME_LENGTH ];\r
47     SKP_int16   res_pitch[ 2 * MAX_FRAME_LENGTH + LA_PITCH_MAX ];\r
48     SKP_int     LBRR_idx, frame_terminator, SNR_dB_Q7;\r
49 \r
50     /* Low bitrate redundancy parameters */\r
51     SKP_uint8   LBRRpayload[ MAX_ARITHM_BYTES ];\r
52     SKP_int32   nBytesLBRR;\r
53 \r
54 TIC(ENCODE_FRAME)\r
55 \r
56     sEncCtrl.sCmn.Seed = psEnc->sCmn.frameCounter++ & 3;\r
57     /**************************************************************/\r
58     /* Setup Input Pointers, and insert frame in input buffer    */\r
59     /*************************************************************/\r
60     /* pointers aligned with start of frame to encode */\r
61     x_frame         = psEnc->x_buf + psEnc->sCmn.ltp_mem_length;    /* start of frame to encode */\r
62     res_pitch_frame = res_pitch    + psEnc->sCmn.ltp_mem_length;    /* start of pitch LPC residual frame */\r
63 \r
64     /****************************/\r
65     /* Voice Activity Detection */\r
66     /****************************/\r
67 TIC(VAD)\r
68     ret = SKP_Silk_VAD_GetSA_Q8( &psEnc->sCmn.sVAD, &psEnc->speech_activity_Q8, &SNR_dB_Q7, \r
69                                  sEncCtrl.input_quality_bands_Q15, &sEncCtrl.input_tilt_Q15,\r
70                                  pIn, psEnc->sCmn.frame_length, psEnc->sCmn.fs_kHz );\r
71 TOC(VAD)\r
72 \r
73     /*******************************************/\r
74     /* High-pass filtering of the input signal */\r
75     /*******************************************/\r
76 TIC(HP_IN)\r
77 #if HIGH_PASS_INPUT\r
78     /* Variable high-pass filter */\r
79     SKP_Silk_HP_variable_cutoff_FIX( psEnc, &sEncCtrl, pIn_HP, pIn );\r
80 #else\r
81     SKP_memcpy( pIn_HP, pIn, psEnc->sCmn.frame_length * sizeof( SKP_int16 ) );\r
82 #endif\r
83 TOC(HP_IN)\r
84 \r
85 #if SWITCH_TRANSITION_FILTERING\r
86     /* Ensure smooth bandwidth transitions */\r
87     SKP_Silk_LP_variable_cutoff( &psEnc->sCmn.sLP, x_frame + LA_SHAPE_MS * psEnc->sCmn.fs_kHz, pIn_HP, psEnc->sCmn.frame_length );\r
88 #else\r
89     SKP_memcpy( x_frame + LA_SHAPE_MS * psEnc->sCmn.fs_kHz, pIn_HP,psEnc->sCmn.frame_length * sizeof( SKP_int16 ) );\r
90 #endif\r
91     \r
92     /*****************************************/\r
93     /* Find pitch lags, initial LPC analysis */\r
94     /*****************************************/\r
95 TIC(FIND_PITCH)\r
96     SKP_Silk_find_pitch_lags_FIX( psEnc, &sEncCtrl, res_pitch, x_frame );\r
97 TOC(FIND_PITCH)\r
98 \r
99     /************************/\r
100     /* Noise shape analysis */\r
101     /************************/\r
102 TIC(NOISE_SHAPE_ANALYSIS)\r
103     SKP_Silk_noise_shape_analysis_FIX( psEnc, &sEncCtrl, res_pitch_frame, x_frame );\r
104 TOC(NOISE_SHAPE_ANALYSIS)\r
105 \r
106     /*****************************************/\r
107     /* Prefiltering for noise shaper         */\r
108     /*****************************************/\r
109 TIC(PREFILTER)\r
110     SKP_Silk_prefilter_FIX( psEnc, &sEncCtrl, xfw, x_frame );\r
111 TOC(PREFILTER)\r
112 \r
113     /***************************************************/\r
114     /* Find linear prediction coefficients (LPC + LTP) */\r
115     /***************************************************/\r
116 TIC(FIND_PRED_COEF)\r
117     SKP_Silk_find_pred_coefs_FIX( psEnc, &sEncCtrl, res_pitch, x_frame );\r
118 TOC(FIND_PRED_COEF)\r
119 \r
120     /****************************************/\r
121     /* Process gains                        */\r
122     /****************************************/\r
123 TIC(PROCESS_GAINS)\r
124     SKP_Silk_process_gains_FIX( psEnc, &sEncCtrl );\r
125 TOC(PROCESS_GAINS)\r
126     \r
127     psEnc->sCmn.sigtype[         psEnc->sCmn.nFramesInPayloadBuf ] = sEncCtrl.sCmn.sigtype;\r
128     psEnc->sCmn.QuantOffsetType[ psEnc->sCmn.nFramesInPayloadBuf ] = sEncCtrl.sCmn.QuantOffsetType;\r
129 \r
130     /****************************************/\r
131     /* Low Bitrate Redundant Encoding       */\r
132     /****************************************/\r
133     nBytesLBRR = MAX_ARITHM_BYTES;\r
134 TIC(LBRR)\r
135     //SKP_Silk_LBRR_encode_FIX( psEnc, &sEncCtrl, LBRRpayload, &nBytesLBRR, xfw );\r
136 TOC(LBRR)\r
137 \r
138     /*****************************************/\r
139     /* Noise shaping quantization            */\r
140     /*****************************************/\r
141 TIC(NSQ)\r
142     if( psEnc->sCmn.nStatesDelayedDecision > 1 || psEnc->sCmn.warping_Q16 > 0 ) {\r
143         SKP_Silk_NSQ_del_dec( &psEnc->sCmn, &sEncCtrl.sCmn, &psEnc->sNSQ, xfw,\r
144             psEnc->sCmn.q, sEncCtrl.sCmn.NLSFInterpCoef_Q2, \r
145             sEncCtrl.PredCoef_Q12[ 0 ], sEncCtrl.LTPCoef_Q14, sEncCtrl.AR2_Q13, sEncCtrl.HarmShapeGain_Q14, \r
146             sEncCtrl.Tilt_Q14, sEncCtrl.LF_shp_Q14, sEncCtrl.Gains_Q16, sEncCtrl.Lambda_Q10, \r
147             sEncCtrl.LTP_scale_Q14 );\r
148     } else {\r
149         SKP_Silk_NSQ( &psEnc->sCmn, &sEncCtrl.sCmn, &psEnc->sNSQ, xfw, \r
150             psEnc->sCmn.q, sEncCtrl.sCmn.NLSFInterpCoef_Q2, \r
151             sEncCtrl.PredCoef_Q12[ 0 ], sEncCtrl.LTPCoef_Q14, sEncCtrl.AR2_Q13, sEncCtrl.HarmShapeGain_Q14, \r
152             sEncCtrl.Tilt_Q14, sEncCtrl.LF_shp_Q14, sEncCtrl.Gains_Q16, sEncCtrl.Lambda_Q10, \r
153             sEncCtrl.LTP_scale_Q14 );\r
154     }\r
155 TOC(NSQ)\r
156 \r
157     /**************************************************/\r
158     /* Convert speech activity into VAD and DTX flags */\r
159     /**************************************************/\r
160     if( psEnc->speech_activity_Q8 < SKP_FIX_CONST( SPEECH_ACTIVITY_DTX_THRES, 8 ) ) {\r
161         psEnc->sCmn.vadFlag = NO_VOICE_ACTIVITY;\r
162         psEnc->sCmn.noSpeechCounter++;\r
163         if( psEnc->sCmn.noSpeechCounter > NO_SPEECH_FRAMES_BEFORE_DTX ) {\r
164             psEnc->sCmn.inDTX = 1;\r
165         }\r
166         if( psEnc->sCmn.noSpeechCounter > MAX_CONSECUTIVE_DTX ) {\r
167             psEnc->sCmn.noSpeechCounter = 0;\r
168             psEnc->sCmn.inDTX           = 0;\r
169         }\r
170     } else {\r
171         psEnc->sCmn.noSpeechCounter = 0;\r
172         psEnc->sCmn.inDTX           = 0;\r
173         psEnc->sCmn.vadFlag         = VOICE_ACTIVITY;\r
174     }\r
175 \r
176     /****************************************/\r
177     /* Initialize range coder               */\r
178     /****************************************/\r
179     if( psEnc->sCmn.nFramesInPayloadBuf == 0 ) {\r
180         psEnc->sCmn.nBytesInPayloadBuf = 0;\r
181     }\r
182 \r
183     /****************************************/\r
184     /* Encode Parameters                    */\r
185     /****************************************/\r
186 TIC(ENCODE_PARAMS)\r
187     SKP_Silk_encode_parameters( &psEnc->sCmn, &sEncCtrl.sCmn, psRangeEnc );\r
188 TOC(ENCODE_PARAMS)\r
189 \r
190     /****************************************/\r
191     /* Update Buffers and State             */\r
192     /****************************************/\r
193     /* Update input buffer */\r
194     SKP_memmove( psEnc->x_buf, &psEnc->x_buf[ psEnc->sCmn.frame_length ], \r
195         ( psEnc->sCmn.ltp_mem_length + LA_SHAPE_MS * psEnc->sCmn.fs_kHz ) * sizeof( SKP_int16 ) );\r
196     \r
197     /* Parameters needed for next frame */\r
198     psEnc->sCmn.prev_sigtype            = sEncCtrl.sCmn.sigtype;\r
199     psEnc->sCmn.prevLag                 = sEncCtrl.sCmn.pitchL[ psEnc->sCmn.nb_subfr - 1 ];\r
200     psEnc->sCmn.first_frame_after_reset = 0;\r
201 \r
202     if( 0 ) { //psEnc->sCmn.sRC.error ) {\r
203         /* Encoder returned error: clear payload buffer */\r
204         psEnc->sCmn.nFramesInPayloadBuf = 0;\r
205     } else {\r
206         psEnc->sCmn.nFramesInPayloadBuf++;\r
207     }\r
208 \r
209     /****************************************/\r
210     /* Finalize payload and copy to output  */\r
211     /****************************************/\r
212     if( psEnc->sCmn.nFramesInPayloadBuf * SUB_FRAME_LENGTH_MS * psEnc->sCmn.nb_subfr >= psEnc->sCmn.PacketSize_ms ) {\r
213 \r
214         LBRR_idx = ( psEnc->sCmn.oldest_LBRR_idx + 1 ) & LBRR_IDX_MASK;\r
215 \r
216         /* Check if FEC information should be added */\r
217         //frame_terminator = psEnc->sCmn.LBRR_buffer[ LBRR_idx ].usage;\r
218         frame_terminator = SKP_SILK_NO_LBRR;\r
219 \r
220         /* Add the frame termination info to stream */\r
221         ec_enc_icdf( psRangeEnc, frame_terminator, SKP_Silk_FrameTermination_iCDF, 8 );\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     SKP_assert(  ( 8 * 1000 * ( (SKP_int64)nBytes - (SKP_int64)psEnc->sCmn.nBytesInPayloadBuf ) ) == \r
297         SKP_SAT32( 8 * 1000 * ( (SKP_int64)nBytes - (SKP_int64)psEnc->sCmn.nBytesInPayloadBuf ) ) );\r
298     SKP_assert( psEnc->sCmn.TargetRate_bps > 0 );\r
299     psEnc->BufferedInChannel_ms   += SKP_DIV32( 8 * 1000 * ( nBytes - psEnc->sCmn.nBytesInPayloadBuf ), psEnc->sCmn.TargetRate_bps );\r
300     psEnc->BufferedInChannel_ms   -= SKP_SMULBB( SUB_FRAME_LENGTH_MS, psEnc->sCmn.nb_subfr );\r
301     psEnc->BufferedInChannel_ms    = SKP_LIMIT_int( psEnc->BufferedInChannel_ms, 0, 100 );\r
302     psEnc->sCmn.nBytesInPayloadBuf = nBytes;\r
303 \r
304     if( psEnc->speech_activity_Q8 > SKP_FIX_CONST( WB_DETECT_ACTIVE_SPEECH_LEVEL_THRES, 8 ) ) {\r
305         psEnc->sCmn.sSWBdetect.ActiveSpeech_ms = SKP_ADD_POS_SAT32( psEnc->sCmn.sSWBdetect.ActiveSpeech_ms, SKP_SMULBB( SUB_FRAME_LENGTH_MS, psEnc->sCmn.nb_subfr ) ); \r
306     }\r
307 \r
308 TOC(ENCODE_FRAME)\r
309 \r
310 #ifdef SAVE_ALL_INTERNAL_DATA\r
311     {\r
312         SKP_float tmp[ MAX_NB_SUBFR * LTP_ORDER ];\r
313         int i;\r
314         DEBUG_STORE_DATA( xf.dat,                   x_frame + LA_SHAPE_MS * psEnc->sCmn.fs_kHz, psEnc->sCmn.frame_length    * sizeof( SKP_int16 ) );\r
315         DEBUG_STORE_DATA( xfw.dat,                  xfw,                            psEnc->sCmn.frame_length    * sizeof( SKP_int16 ) );\r
316         DEBUG_STORE_DATA( pitchL.dat,               sEncCtrl.sCmn.pitchL,           psEnc->sCmn.nb_subfr            * sizeof( SKP_int ) );\r
317         for( i = 0; i < psEnc->sCmn.nb_subfr * LTP_ORDER; i++ ) {\r
318             tmp[ i ] = (SKP_float)sEncCtrl.LTPCoef_Q14[ i ] / 16384.0f;\r
319         }\r
320         DEBUG_STORE_DATA( pitchG_quantized.dat,     tmp,                            psEnc->sCmn.nb_subfr * LTP_ORDER * sizeof( SKP_float ) );\r
321         for( i = 0; i <psEnc->sCmn.predictLPCOrder; i++ ) {\r
322             tmp[ i ] = (SKP_float)sEncCtrl.PredCoef_Q12[ 1 ][ i ] / 4096.0f;\r
323         }\r
324         DEBUG_STORE_DATA( PredCoef.dat,             tmp,                            psEnc->sCmn.predictLPCOrder * sizeof( SKP_float ) );\r
325         \r
326         tmp[ 0 ] = (SKP_float)sEncCtrl.pitch_freq_low_Hz;\r
327         DEBUG_STORE_DATA( pitch_freq_low_Hz.dat,    tmp,                            sizeof( SKP_float ) );\r
328         tmp[ 0 ] = (SKP_float)sEncCtrl.LTPredCodGain_Q7 / 128.0f;\r
329         DEBUG_STORE_DATA( LTPredCodGain.dat,        tmp,                            sizeof( SKP_float ) );\r
330         tmp[ 0 ] = (SKP_float)psEnc->LTPCorr_Q15 / 32768.0f;\r
331         DEBUG_STORE_DATA( LTPcorr.dat,              tmp,                            sizeof( SKP_float ) );\r
332         tmp[ 0 ] = (SKP_float)sEncCtrl.input_tilt_Q15 / 32768.0f;\r
333         DEBUG_STORE_DATA( tilt.dat,                 tmp,                            sizeof( SKP_float ) );\r
334         for( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) {\r
335             tmp[ i ] = (SKP_float)sEncCtrl.Gains_Q16[ i ] / 65536.0f;\r
336         }\r
337         DEBUG_STORE_DATA( gains.dat,                tmp,                            psEnc->sCmn.nb_subfr * sizeof( SKP_float ) );\r
338         DEBUG_STORE_DATA( gains_indices.dat,        &sEncCtrl.sCmn.GainsIndices,    psEnc->sCmn.nb_subfr * sizeof( SKP_int ) );\r
339         DEBUG_STORE_DATA( nBytes.dat,               &nBytes,                        sizeof( SKP_int ) );\r
340         tmp[ 0 ] = (SKP_float)sEncCtrl.current_SNR_dB_Q7 / 128.0f;\r
341         DEBUG_STORE_DATA( current_SNR_db.dat,       tmp,                            sizeof( SKP_float ) );\r
342         DEBUG_STORE_DATA( QuantOffsetType.dat,      &sEncCtrl.sCmn.QuantOffsetType, sizeof( SKP_int ) );\r
343         tmp[ 0 ] = (SKP_float)psEnc->speech_activity_Q8 / 256.0f;\r
344         DEBUG_STORE_DATA( speech_activity.dat,      tmp,                            sizeof( SKP_float ) );\r
345         for( i = 0; i < VAD_N_BANDS; i++ ) {\r
346             tmp[ i ] = (SKP_float)sEncCtrl.input_quality_bands_Q15[ i ] / 32768.0f;\r
347         }\r
348         DEBUG_STORE_DATA( input_quality_bands.dat,  tmp,                            VAD_N_BANDS * sizeof( SKP_float ) );\r
349         DEBUG_STORE_DATA( sigtype.dat,              &sEncCtrl.sCmn.sigtype,         sizeof( SKP_int ) ); \r
350         DEBUG_STORE_DATA( ratelevel.dat,            &sEncCtrl.sCmn.RateLevelIndex,  sizeof( SKP_int ) ); \r
351         DEBUG_STORE_DATA( lag_index.dat,            &sEncCtrl.sCmn.lagIndex,        sizeof( SKP_int ) ); \r
352         DEBUG_STORE_DATA( contour_index.dat,        &sEncCtrl.sCmn.contourIndex,    sizeof( SKP_int ) ); \r
353         DEBUG_STORE_DATA( per_index.dat,            &sEncCtrl.sCmn.PERIndex,        sizeof( SKP_int ) ); \r
354     }\r
355 #endif\r
356     return( ret );\r
357 }\r
358 \r
359 #if 0  //tmp\r
360 /* Low BitRate Redundancy encoding functionality. Reuse all parameters but encode residual with lower bitrate */\r
361 void SKP_Silk_LBRR_encode_FIX(\r
362     SKP_Silk_encoder_state_FIX      *psEnc,         /* I/O  Pointer to Silk encoder state           */\r
363     SKP_Silk_encoder_control_FIX    *psEncCtrl,     /* I/O  Pointer to Silk encoder control struct  */\r
364     SKP_uint8                       *pCode,         /* O    Pointer to payload                      */\r
365     SKP_int16                       *pnBytesOut,    /* I/O  Pointer to number of payload bytes      */\r
366     SKP_int16                       xfw[]           /* I    Input signal                            */\r
367 )\r
368 {\r
369     SKP_int     i, TempGainsIndices[ MAX_NB_SUBFR ], frame_terminator;\r
370     SKP_int     nBytes, nFramesInPayloadBuf;\r
371     SKP_int32   TempGains_Q16[ MAX_NB_SUBFR ];\r
372     SKP_int     typeOffset, LTP_scaleIndex, Rate_only_parameters = 0;\r
373     ec_byte_buffer range_enc_celt_buf;\r
374 \r
375     /*******************************************/\r
376     /* Control use of inband LBRR              */\r
377     /*******************************************/\r
378     SKP_Silk_LBRR_ctrl_FIX( psEnc, &psEncCtrl->sCmn );\r
379 \r
380     if( psEnc->sCmn.LBRR_enabled ) {\r
381         /* Save original gains */\r
382         SKP_memcpy( TempGainsIndices, psEncCtrl->sCmn.GainsIndices, MAX_NB_SUBFR * sizeof( SKP_int   ) );\r
383         SKP_memcpy( TempGains_Q16,    psEncCtrl->Gains_Q16,         MAX_NB_SUBFR * sizeof( SKP_int32 ) );\r
384 \r
385         typeOffset     = psEnc->sCmn.typeOffsetPrev; // Temp save as cannot be overwritten\r
386         LTP_scaleIndex = psEncCtrl->sCmn.LTP_scaleIndex;\r
387 \r
388         /* Set max rate where quant signal is encoded */\r
389         if( psEnc->sCmn.fs_kHz == 8 ) {\r
390             Rate_only_parameters = 13500;\r
391         } else if( psEnc->sCmn.fs_kHz == 12 ) {\r
392             Rate_only_parameters = 15500;\r
393         } else if( psEnc->sCmn.fs_kHz == 16 ) {\r
394             Rate_only_parameters = 17500;\r
395         } else if( psEnc->sCmn.fs_kHz == 24 ) {\r
396             Rate_only_parameters = 19500;\r
397         } else {\r
398             SKP_assert( 0 );\r
399         }\r
400 \r
401         if( psEnc->sCmn.Complexity > 0 && psEnc->sCmn.TargetRate_bps > Rate_only_parameters ) {\r
402             if( psEnc->sCmn.nFramesInPayloadBuf == 0 ) {\r
403                 /* First frame in packet; copy everything */\r
404                 SKP_memcpy( &psEnc->sNSQ_LBRR, &psEnc->sNSQ, sizeof( SKP_Silk_nsq_state ) );\r
405 \r
406                 psEnc->sCmn.LBRRprevLastGainIndex = psEnc->sShape.LastGainIndex;\r
407                 /* Increase Gains to get target LBRR rate */\r
408                 psEncCtrl->sCmn.GainsIndices[ 0 ] = psEncCtrl->sCmn.GainsIndices[ 0 ] + psEnc->sCmn.LBRR_GainIncreases;\r
409                 psEncCtrl->sCmn.GainsIndices[ 0 ] = SKP_LIMIT_int( psEncCtrl->sCmn.GainsIndices[ 0 ], 0, N_LEVELS_QGAIN - 1 );\r
410             }\r
411             /* Decode to get gains in sync with decoder         */\r
412             /* Overwrite unquantized gains with quantized gains */\r
413             SKP_Silk_gains_dequant( psEncCtrl->Gains_Q16, psEncCtrl->sCmn.GainsIndices, \r
414                 &psEnc->sCmn.LBRRprevLastGainIndex, psEnc->sCmn.nFramesInPayloadBuf, psEnc->sCmn.nb_subfr );\r
415 \r
416             /*****************************************/\r
417             /* Noise shaping quantization            */\r
418             /*****************************************/\r
419             if( psEnc->sCmn.nStatesDelayedDecision > 1 || psEnc->sCmn.warping_Q16 > 0 ) {\r
420                 SKP_Silk_NSQ_del_dec( &psEnc->sCmn, &psEncCtrl->sCmn, &psEnc->sNSQ_LBRR, xfw, psEnc->sCmn.q_LBRR, \r
421                     psEncCtrl->sCmn.NLSFInterpCoef_Q2, psEncCtrl->PredCoef_Q12[ 0 ], psEncCtrl->LTPCoef_Q14, \r
422                     psEncCtrl->AR2_Q13, psEncCtrl->HarmShapeGain_Q14, psEncCtrl->Tilt_Q14, psEncCtrl->LF_shp_Q14, \r
423                     psEncCtrl->Gains_Q16, psEncCtrl->Lambda_Q10, psEncCtrl->LTP_scale_Q14 );\r
424             } else {\r
425                 SKP_Silk_NSQ( &psEnc->sCmn, &psEncCtrl->sCmn, &psEnc->sNSQ_LBRR, xfw, psEnc->sCmn.q_LBRR, \r
426                     psEncCtrl->sCmn.NLSFInterpCoef_Q2, psEncCtrl->PredCoef_Q12[ 0 ], psEncCtrl->LTPCoef_Q14, \r
427                     psEncCtrl->AR2_Q13, psEncCtrl->HarmShapeGain_Q14, psEncCtrl->Tilt_Q14, psEncCtrl->LF_shp_Q14, \r
428                     psEncCtrl->Gains_Q16, psEncCtrl->Lambda_Q10, psEncCtrl->LTP_scale_Q14 );\r
429             }\r
430         } else {\r
431             SKP_memset( psEnc->sCmn.q_LBRR, 0, psEnc->sCmn.frame_length * sizeof( SKP_int8 ) );\r
432             psEncCtrl->sCmn.LTP_scaleIndex = 0;\r
433         }\r
434         /****************************************/\r
435         /* Initialize arithmetic coder          */\r
436         /****************************************/\r
437         if( psEnc->sCmn.nFramesInPayloadBuf == 0 ) {\r
438             ec_byte_writeinit_buffer( &range_enc_celt_buf, psEnc->sCmn.sRC_LBRR.buffer, MAX_ARITHM_BYTES );\r
439             ec_enc_init( &psEnc->sCmn.sRC_LBRR.range_enc_celt_state, &range_enc_celt_buf );\r
440 \r
441             SKP_Silk_range_enc_init( &psEnc->sCmn.sRC_LBRR );\r
442             psEnc->sCmn.nBytesInPayloadBuf = 0;\r
443         }\r
444 \r
445         /****************************************/\r
446         /* Encode Parameters                    */\r
447         /****************************************/\r
448         SKP_Silk_encode_parameters( &psEnc->sCmn, &psEncCtrl->sCmn, \r
449             &psEnc->sCmn.sRC_LBRR );\r
450 \r
451         /****************************************/\r
452         /* Encode Parameters                    */\r
453         /****************************************/\r
454         if( psEnc->sCmn.sRC_LBRR.error ) {\r
455             /* Encoder returned error: clear payload buffer */\r
456             nFramesInPayloadBuf = 0;\r
457         } else {\r
458             nFramesInPayloadBuf = psEnc->sCmn.nFramesInPayloadBuf + 1;\r
459         }\r
460 \r
461         /****************************************/\r
462         /* Finalize payload and copy to output  */\r
463         /****************************************/\r
464         if( SKP_SMULBB( nFramesInPayloadBuf, SKP_SMULBB( SUB_FRAME_LENGTH_MS, psEnc->sCmn.nb_subfr ) ) >= psEnc->sCmn.PacketSize_ms ) {\r
465 \r
466             /* Check if FEC information should be added */\r
467             frame_terminator = SKP_SILK_LAST_FRAME;\r
468 \r
469             /* Add the frame termination info to stream */\r
470             ec_enc_icdf( psRangeEnc, frame_terminator, SKP_Silk_FrameTermination_iCDF, 8 );\r
471 \r
472             /*********************************************/\r
473             /* Encode quantization indices of excitation */\r
474             /*********************************************/\r
475             for( i = 0; i < nFramesInPayloadBuf; i++ ) {\r
476                 SKP_Silk_encode_pulses( &psEnc->sCmn.sRC_LBRR, psEnc->sCmn.sigtype[ i ], psEnc->sCmn.QuantOffsetType[ i ],\r
477                     &psEnc->sCmn.q_LBRR[ i * psEnc->sCmn.frame_length ], psEnc->sCmn.frame_length );\r
478             }\r
479 \r
480             /* Payload length so far */\r
481             nBytes = SKP_RSHIFT( ec_enc_tell( psRangeEnc_LBRR, 0 ) + 7, 3 );\r
482 \r
483             /* Check that there is enough space in external output buffer and move data */\r
484             if( *pnBytesOut >= nBytes ) {\r
485                 SKP_int bits_in_stream, mask;\r
486                 bits_in_stream = ec_enc_tell( &psEnc->sCmn.sRC_LBRR.range_enc_celt_state, 0 );\r
487                 ec_enc_done( &psEnc->sCmn.sRC_LBRR.range_enc_celt_state );\r
488 \r
489                 /* Fill up any remaining bits in the last byte with 1s */\r
490                 if( bits_in_stream & 7 ) {\r
491                     mask = SKP_RSHIFT( 0xFF, bits_in_stream & 7 );\r
492                     if( nBytes - 1 < *pnBytesOut ) {\r
493                         psEnc->sCmn.sRC_LBRR.range_enc_celt_state.buf->buf[ nBytes - 1 ] |= mask;\r
494                     }\r
495                 }\r
496                 SKP_memcpy( pCode, psEnc->sCmn.sRC_LBRR.range_enc_celt_state.buf->buf, nBytes * sizeof( SKP_uint8 ) );\r
497 \r
498                 *pnBytesOut = nBytes;\r
499             } else {\r
500                 /* Not enough space: payload will be discarded */\r
501                 *pnBytesOut = 0;\r
502                 SKP_assert( 0 );\r
503             }\r
504         } else {\r
505             /* No payload this time */\r
506             *pnBytesOut = 0;\r
507 \r
508             /* Encode that more frames follows */\r
509             frame_terminator = SKP_SILK_MORE_FRAMES;\r
510             ec_enc_icdf( psRangeEnc, frame_terminator, SKP_Silk_FrameTermination_iCDF, 8 );\r
511         }\r
512 \r
513         /* Restore original Gains */\r
514         SKP_memcpy( psEncCtrl->sCmn.GainsIndices, TempGainsIndices, psEnc->sCmn.nb_subfr * sizeof( SKP_int   ) );\r
515         SKP_memcpy( psEncCtrl->Gains_Q16,         TempGains_Q16,    psEnc->sCmn.nb_subfr * sizeof( SKP_int32 ) );\r
516     \r
517         /* Restore LTP scale index and typeoffset */\r
518         psEncCtrl->sCmn.LTP_scaleIndex = LTP_scaleIndex;\r
519         psEnc->sCmn.typeOffsetPrev     = typeOffset;\r
520     }\r
521 }\r
522 #endif\r