Update SILK code using the CELT range coder
[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 \r
30 /****************/\r
31 /* Encode frame */\r
32 /****************/\r
33 SKP_int SKP_Silk_encode_frame_FIX( \r
34     SKP_Silk_encoder_state_FIX      *psEnc,             /* I/O  Pointer to Silk FIX encoder state           */\r
35     SKP_uint8                       *pCode,             /* O    Pointer to payload                          */\r
36     SKP_int16                       *pnBytesOut,        /* I/O  Pointer to number of payload bytes          */\r
37                                                         /*      input: max length; output: used             */\r
38     const SKP_int16                 *pIn                /* I    Pointer to input speech frame               */\r
39 )\r
40 {\r
41     SKP_Silk_encoder_control_FIX sEncCtrl;\r
42     SKP_int     i, nBytes, ret = 0;\r
43     SKP_int16   *x_frame, *res_pitch_frame;\r
44     SKP_int16   xfw[ MAX_FRAME_LENGTH ];\r
45     SKP_int16   pIn_HP[ MAX_FRAME_LENGTH ];\r
46     SKP_int16   res_pitch[ 2 * MAX_FRAME_LENGTH + LA_PITCH_MAX ];\r
47     SKP_int     LBRR_idx, frame_terminator;\r
48     const SKP_uint16 *FrameTermination_CDF;\r
49 \r
50     /* Low bitrate redundancy parameters */\r
51     SKP_uint8   LBRRpayload[ MAX_ARITHM_BYTES ];\r
52     SKP_int16   nBytesLBRR;\r
53     ec_byte_buffer range_enc_celt_buf;\r
54 \r
55     sEncCtrl.sCmn.Seed = psEnc->sCmn.frameCounter++ & 3;\r
56 \r
57 TIC(ENCODE_FRAME)\r
58 \r
59     /**************************************************************/\r
60     /* Setup Input Pointers, and insert frame in input buffer    */\r
61     /*************************************************************/\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     ret = SKP_Silk_VAD_GetSA_Q8( &psEnc->sCmn.sVAD, &psEnc->speech_activity_Q8, \r
70                                  sEncCtrl.input_quality_bands_Q15, &sEncCtrl.input_tilt_Q15,\r
71                                  pIn, psEnc->sCmn.frame_length, psEnc->sCmn.fs_kHz );\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_FIX( 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, x_frame + psEnc->sCmn.la_shape, pIn_HP, psEnc->sCmn.frame_length );\r
89 #else\r
90     SKP_memcpy( x_frame + psEnc->sCmn.la_shape, pIn_HP,psEnc->sCmn.frame_length * sizeof( SKP_int16 ) );\r
91 #endif\r
92     \r
93     /*****************************************/\r
94     /* Find pitch lags, initial LPC analysis */\r
95     /*****************************************/\r
96 TIC(FIND_PITCH)\r
97     SKP_Silk_find_pitch_lags_FIX( psEnc, &sEncCtrl, res_pitch, x_frame );\r
98 TOC(FIND_PITCH)\r
99 \r
100     /************************/\r
101     /* Noise shape analysis */\r
102     /************************/\r
103 TIC(NOISE_SHAPE_ANALYSIS)\r
104     SKP_Silk_noise_shape_analysis_FIX( psEnc, &sEncCtrl, res_pitch_frame, x_frame );\r
105 TOC(NOISE_SHAPE_ANALYSIS)\r
106 \r
107     /*****************************************/\r
108     /* Prefiltering for noise shaper         */\r
109     /*****************************************/\r
110 TIC(PREFILTER)\r
111     SKP_Silk_prefilter_FIX( psEnc, &sEncCtrl, xfw, x_frame );\r
112 TOC(PREFILTER)\r
113 \r
114     /***************************************************/\r
115     /* Find linear prediction coefficients (LPC + LTP) */\r
116     /***************************************************/\r
117 TIC(FIND_PRED_COEF)\r
118     SKP_Silk_find_pred_coefs_FIX( psEnc, &sEncCtrl, res_pitch );\r
119 TOC(FIND_PRED_COEF)\r
120 \r
121     /****************************************/\r
122     /* Process gains                        */\r
123     /****************************************/\r
124 TIC(PROCESS_GAINS)\r
125     SKP_Silk_process_gains_FIX( psEnc, &sEncCtrl );\r
126 TOC(PROCESS_GAINS)\r
127  \r
128     psEnc->sCmn.sigtype[         psEnc->sCmn.nFramesInPayloadBuf ] = sEncCtrl.sCmn.sigtype;\r
129     psEnc->sCmn.QuantOffsetType[ psEnc->sCmn.nFramesInPayloadBuf ] = sEncCtrl.sCmn.QuantOffsetType;\r
130 \r
131     /****************************************/\r
132     /* Low Bitrate Redundant Encoding       */\r
133     /****************************************/\r
134     nBytesLBRR = MAX_ARITHM_BYTES;\r
135 TIC(LBRR)\r
136     SKP_Silk_LBRR_encode_FIX( psEnc, &sEncCtrl, LBRRpayload, &nBytesLBRR, xfw );\r
137 TOC(LBRR)\r
138 \r
139     /*****************************************/\r
140     /* Noise shaping quantization            */\r
141     /*****************************************/\r
142 TIC(NSQ)\r
143     if( psEnc->sCmn.nStatesDelayedDecision > 1 ) {\r
144         SKP_Silk_NSQ_del_dec( &psEnc->sCmn, &sEncCtrl.sCmn, &psEnc->sNSQ, xfw,\r
145             &psEnc->sCmn.q[ psEnc->sCmn.nFramesInPayloadBuf *psEnc->sCmn.frame_length ], sEncCtrl.sCmn.NLSFInterpCoef_Q2, \r
146             sEncCtrl.PredCoef_Q12[ 0 ], sEncCtrl.LTPCoef_Q14, sEncCtrl.AR2_Q13, sEncCtrl.HarmShapeGain_Q14, \r
147             sEncCtrl.Tilt_Q14, sEncCtrl.LF_shp_Q14, sEncCtrl.Gains_Q16, sEncCtrl.Lambda_Q10, \r
148             sEncCtrl.LTP_scale_Q14 );\r
149     } else {\r
150         SKP_Silk_NSQ( &psEnc->sCmn, &sEncCtrl.sCmn, &psEnc->sNSQ, xfw, \r
151                 &psEnc->sCmn.q[ psEnc->sCmn.nFramesInPayloadBuf *psEnc->sCmn.frame_length ], sEncCtrl.sCmn.NLSFInterpCoef_Q2, \r
152                 sEncCtrl.PredCoef_Q12[ 0 ], sEncCtrl.LTPCoef_Q14, sEncCtrl.AR2_Q13, sEncCtrl.HarmShapeGain_Q14, \r
153                 sEncCtrl.Tilt_Q14, sEncCtrl.LF_shp_Q14, sEncCtrl.Gains_Q16, sEncCtrl.Lambda_Q10, \r
154             sEncCtrl.LTP_scale_Q14 );\r
155     }\r
156 TOC(NSQ)\r
157 \r
158     /**************************************************/\r
159     /* Convert speech activity into VAD and DTX flags */\r
160     /**************************************************/\r
161     if( psEnc->speech_activity_Q8 < SPEECH_ACTIVITY_DTX_THRES_Q8 ) {\r
162         psEnc->sCmn.vadFlag = NO_VOICE_ACTIVITY;\r
163         psEnc->sCmn.noSpeechCounter++;\r
164         if( psEnc->sCmn.noSpeechCounter > NO_SPEECH_FRAMES_BEFORE_DTX ) {\r
165             psEnc->sCmn.inDTX = 1;\r
166         }\r
167         if( psEnc->sCmn.noSpeechCounter > MAX_CONSECUTIVE_DTX ) {\r
168             psEnc->sCmn.noSpeechCounter = 0;\r
169             psEnc->sCmn.inDTX           = 0;\r
170         }\r
171     } else {\r
172         psEnc->sCmn.noSpeechCounter = 0;\r
173         psEnc->sCmn.inDTX           = 0;\r
174         psEnc->sCmn.vadFlag         = VOICE_ACTIVITY;\r
175     }\r
176 \r
177     /****************************************/\r
178     /* Initialize arithmetic coder          */\r
179     /****************************************/\r
180     if( psEnc->sCmn.nFramesInPayloadBuf == 0 ) {\r
181         ec_byte_writeinit_buffer( &range_enc_celt_buf, psEnc->sCmn.sRC.buffer, MAX_ARITHM_BYTES );\r
182         ec_enc_init( &psEnc->sCmn.sRC.range_enc_celt_state, &range_enc_celt_buf );\r
183 \r
184         SKP_Silk_range_enc_init( &psEnc->sCmn.sRC );\r
185         psEnc->sCmn.nBytesInPayloadBuf = 0;\r
186     }\r
187 \r
188     /****************************************/\r
189     /* Encode Parameters                    */\r
190     /****************************************/\r
191 TIC(ENCODE_PARAMS)\r
192     SKP_Silk_encode_parameters_v4( &psEnc->sCmn, &sEncCtrl.sCmn, &psEnc->sCmn.sRC );\r
193     FrameTermination_CDF = SKP_Silk_FrameTermination_v4_CDF;\r
194 TOC(ENCODE_PARAMS)\r
195 \r
196     /****************************************/\r
197     /* Update Buffers and State             */\r
198     /****************************************/\r
199     /* Update Input buffer */\r
200     SKP_memmove( psEnc->x_buf, &psEnc->x_buf[ psEnc->sCmn.frame_length ], ( psEnc->sCmn.ltp_mem_length + psEnc->sCmn.la_shape ) * sizeof( SKP_int16 ) );\r
201     \r
202     /* parameters needed for next frame */\r
203     psEnc->sCmn.prev_sigtype            = sEncCtrl.sCmn.sigtype;\r
204     psEnc->sCmn.prevLag                 = sEncCtrl.sCmn.pitchL[  psEnc->sCmn.nb_subfr - 1 ];\r
205     psEnc->sCmn.first_frame_after_reset = 0;\r
206 \r
207     if( psEnc->sCmn.sRC.error ) {\r
208         /* encoder returned error: clear payload buffer */\r
209         psEnc->sCmn.nFramesInPayloadBuf = 0;\r
210     } else {\r
211         psEnc->sCmn.nFramesInPayloadBuf++;\r
212     }\r
213 \r
214     /****************************************/\r
215     /* finalize payload and copy to output  */\r
216     /****************************************/\r
217     if( psEnc->sCmn.nFramesInPayloadBuf * SUB_FRAME_LENGTH_MS * psEnc->sCmn.nb_subfr >= psEnc->sCmn.PacketSize_ms ) {\r
218 \r
219         LBRR_idx = ( psEnc->sCmn.oldest_LBRR_idx + 1 ) & LBRR_IDX_MASK;\r
220 \r
221         /* Check if FEC information should be added */\r
222         frame_terminator = SKP_SILK_LAST_FRAME;\r
223         if( psEnc->sCmn.LBRR_buffer[ LBRR_idx ].usage == SKP_SILK_ADD_LBRR_TO_PLUS1 ) {\r
224             frame_terminator = SKP_SILK_LBRR_VER1;\r
225         }\r
226         if( psEnc->sCmn.LBRR_buffer[ psEnc->sCmn.oldest_LBRR_idx ].usage == SKP_SILK_ADD_LBRR_TO_PLUS2 ) {\r
227             frame_terminator = SKP_SILK_LBRR_VER2;\r
228             LBRR_idx = psEnc->sCmn.oldest_LBRR_idx;\r
229         }\r
230 \r
231         /* Add the frame termination info to stream */\r
232         SKP_Silk_range_encoder( &psEnc->sCmn.sRC, frame_terminator, FrameTermination_CDF );\r
233 \r
234         /* Code excitation signal */\r
235         for( i = 0; i <psEnc->sCmn.nFramesInPayloadBuf; i++ ) {\r
236             SKP_Silk_encode_pulses( &psEnc->sCmn.sRC, psEnc->sCmn.sigtype[ i ],psEnc->sCmn.QuantOffsetType[ i ], \r
237                 &psEnc->sCmn.q[ i * psEnc->sCmn.frame_length],psEnc->sCmn.frame_length );\r
238         }\r
239         /* payload length so far */\r
240         SKP_Silk_range_encoder_get_length( &psEnc->sCmn.sRC, &nBytes );\r
241 \r
242         /* check that there is enough space in external output buffer, and move data */\r
243         if( *pnBytesOut >= nBytes ) {\r
244             SKP_int bits_in_stream, mask;\r
245             bits_in_stream = ec_enc_tell( &psEnc->sCmn.sRC.range_enc_celt_state, 0 );\r
246             ec_enc_done( &psEnc->sCmn.sRC.range_enc_celt_state );\r
247             \r
248             /* Fill up any remaining bits in the last byte with 1s */\r
249             if( bits_in_stream & 7 ) {\r
250                 mask = SKP_RSHIFT( 0xFF, bits_in_stream & 7 );\r
251                 if( nBytes - 1 < *pnBytesOut ) {\r
252                     psEnc->sCmn.sRC.range_enc_celt_state.buf->buf[ nBytes - 1 ] |= mask;\r
253                 }\r
254             }\r
255             SKP_memcpy( pCode, psEnc->sCmn.sRC.range_enc_celt_state.buf->buf, nBytes * sizeof( SKP_uint8 ) );\r
256 \r
257             if( frame_terminator > SKP_SILK_MORE_FRAMES && \r
258                     *pnBytesOut >= nBytes + psEnc->sCmn.LBRR_buffer[ LBRR_idx ].nBytes ) {\r
259                 /* Get old packet and add to payload. */\r
260                 SKP_memcpy( &pCode[ nBytes ],\r
261                     psEnc->sCmn.LBRR_buffer[ LBRR_idx ].payload,\r
262                     psEnc->sCmn.LBRR_buffer[ LBRR_idx ].nBytes * sizeof( SKP_uint8 ) );\r
263                 nBytes += psEnc->sCmn.LBRR_buffer[ LBRR_idx ].nBytes;\r
264             }\r
265                         \r
266             *pnBytesOut = nBytes;\r
267         \r
268             /* Update FEC buffer */\r
269             SKP_memcpy( psEnc->sCmn.LBRR_buffer[ psEnc->sCmn.oldest_LBRR_idx ].payload, LBRRpayload, \r
270                 nBytesLBRR * sizeof( SKP_uint8 ) );\r
271             psEnc->sCmn.LBRR_buffer[ psEnc->sCmn.oldest_LBRR_idx ].nBytes = nBytesLBRR;\r
272             /* This line tells describes how FEC should be used */\r
273             psEnc->sCmn.LBRR_buffer[ psEnc->sCmn.oldest_LBRR_idx ].usage = sEncCtrl.sCmn.LBRR_usage;\r
274             psEnc->sCmn.oldest_LBRR_idx = ( psEnc->sCmn.oldest_LBRR_idx + 1 ) & LBRR_IDX_MASK;\r
275 \r
276             /* Reset number of frames in payload buffer */\r
277             psEnc->sCmn.nFramesInPayloadBuf = 0;\r
278         } else {\r
279             /* Not enough space: Payload will be discarded */\r
280             *pnBytesOut = 0;\r
281             nBytes      = 0;\r
282             psEnc->sCmn.nFramesInPayloadBuf = 0;\r
283             ret = SKP_SILK_ENC_PAYLOAD_BUF_TOO_SHORT;\r
284         }\r
285     } else {\r
286         /* no payload for you this time */\r
287         *pnBytesOut = 0;\r
288 \r
289         /* Encode that more frames follows */\r
290         frame_terminator = SKP_SILK_MORE_FRAMES;\r
291         SKP_Silk_range_encoder( &psEnc->sCmn.sRC, frame_terminator, FrameTermination_CDF );\r
292 \r
293         /* payload length so far */\r
294         SKP_Silk_range_encoder_get_length( &psEnc->sCmn.sRC, &nBytes );\r
295 \r
296         /* Take into account the q signal that isnt in the bitstream yet */\r
297         nBytes +=  SKP_Silk_pulses_to_bytes( &psEnc->sCmn, \r
298             &psEnc->sCmn.q[ (psEnc->sCmn.nFramesInPayloadBuf - 1) * psEnc->sCmn.frame_length ] );\r
299     }\r
300 \r
301     /* Check for arithmetic coder errors */\r
302     if( psEnc->sCmn.sRC.error ) {\r
303         ret = SKP_SILK_ENC_INTERNAL_ERROR;\r
304     }\r
305 \r
306     /* simulate number of ms buffered in channel because of exceeding TargetRate */\r
307     SKP_assert(  ( 8 * 1000 * ( (SKP_int64)nBytes - (SKP_int64)psEnc->sCmn.nBytesInPayloadBuf ) ) == \r
308         SKP_SAT32( 8 * 1000 * ( (SKP_int64)nBytes - (SKP_int64)psEnc->sCmn.nBytesInPayloadBuf ) ) );\r
309     SKP_assert( psEnc->sCmn.TargetRate_bps > 0 );\r
310     psEnc->BufferedInChannel_ms   += SKP_DIV32( 8 * 1000 * ( nBytes -psEnc->sCmn.nBytesInPayloadBuf ),psEnc->sCmn.TargetRate_bps );\r
311     psEnc->BufferedInChannel_ms   -= SKP_SMULBB( SUB_FRAME_LENGTH_MS, psEnc->sCmn.nb_subfr );\r
312     psEnc->BufferedInChannel_ms    = SKP_LIMIT_int( psEnc->BufferedInChannel_ms, 0, 100 );\r
313     psEnc->sCmn.nBytesInPayloadBuf = nBytes;\r
314 \r
315     if( psEnc->speech_activity_Q8 > WB_DETECT_ACTIVE_SPEECH_LEVEL_THRES_Q8 ) {\r
316         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
317     }\r
318 \r
319 TOC(ENCODE_FRAME)\r
320 \r
321 #ifdef SAVE_ALL_INTERNAL_DATA\r
322     {\r
323         SKP_float tmp[ MAX_NB_SUBFR * LTP_ORDER ];\r
324         int i;\r
325         DEBUG_STORE_DATA( xf.dat,                   x_frame +psEnc->sCmn.la_shape,  psEnc->sCmn.frame_length    * sizeof( SKP_int16 ) );\r
326         DEBUG_STORE_DATA( xfw.dat,                  xfw,                            psEnc->sCmn.frame_length    * sizeof( SKP_int16 ) );\r
327         //      DEBUG_STORE_DATA( q.dat,                    &psEnc->sCmn.q[ ( psEnc->sCmn.nFramesInPayloadBuf - 1)*psEnc->sCmn.frame_length ],  psEnc->sCmn.frame_length    * sizeof( SKP_int8 ) );\r
328         DEBUG_STORE_DATA( pitchL.dat,               sEncCtrl.sCmn.pitchL,           psEnc->sCmn.nb_subfr            * sizeof( SKP_int ) );\r
329         for( i = 0; i < psEnc->sCmn.nb_subfr * LTP_ORDER; i++ ) {\r
330             tmp[ i ] = (SKP_float)sEncCtrl.LTPCoef_Q14[ i ] / 16384.0f;\r
331         }\r
332         DEBUG_STORE_DATA( pitchG_quantized.dat,     tmp,                            psEnc->sCmn.nb_subfr * LTP_ORDER * sizeof( SKP_float ) );\r
333         for( i = 0; i <psEnc->sCmn.predictLPCOrder; i++ ) {\r
334             tmp[ i ] = (SKP_float)sEncCtrl.PredCoef_Q12[ 1 ][ i ] / 4096.0f;\r
335         }\r
336         DEBUG_STORE_DATA( PredCoef.dat,             tmp,                            psEnc->sCmn.predictLPCOrder * sizeof( SKP_float ) );\r
337         \r
338         tmp[ 0 ] = (SKP_float)sEncCtrl.pitch_freq_low_Hz;\r
339         DEBUG_STORE_DATA( pitch_freq_low_Hz.dat,    tmp,                            sizeof( SKP_float ) );\r
340         tmp[ 0 ] = (SKP_float)sEncCtrl.LTPredCodGain_Q7 / 128.0f;\r
341         DEBUG_STORE_DATA( LTPredCodGain.dat,        tmp,                            sizeof( SKP_float ) );\r
342         tmp[ 0 ] = (SKP_float)psEnc->LTPCorr_Q15 / 32768.0f;\r
343         DEBUG_STORE_DATA( LTPcorr.dat,              tmp,                            sizeof( SKP_float ) );\r
344         tmp[ 0 ] = (SKP_float)sEncCtrl.input_tilt_Q15 / 32768.0f;\r
345         DEBUG_STORE_DATA( tilt.dat,                 tmp,                            sizeof( SKP_float ) );\r
346         for( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) {\r
347             tmp[ i ] = (SKP_float)sEncCtrl.Gains_Q16[ i ] / 65536.0f;\r
348         }\r
349         DEBUG_STORE_DATA( gains.dat,                tmp,                            psEnc->sCmn.nb_subfr * sizeof( SKP_float ) );\r
350         DEBUG_STORE_DATA( gains_indices.dat,        &sEncCtrl.sCmn.GainsIndices,    psEnc->sCmn.nb_subfr * sizeof( SKP_int ) );\r
351         DEBUG_STORE_DATA( nBytes.dat,               &nBytes,                        sizeof( SKP_int ) );\r
352         tmp[ 0 ] = (SKP_float)sEncCtrl.current_SNR_dB_Q7 / 128.0f;\r
353         DEBUG_STORE_DATA( current_SNR_db.dat,       tmp,                            sizeof( SKP_float ) );\r
354         DEBUG_STORE_DATA( QuantOffsetType.dat,      &sEncCtrl.sCmn.QuantOffsetType, sizeof( SKP_int ) );\r
355         tmp[ 0 ] = (SKP_float)psEnc->speech_activity_Q8 / 256.0f;\r
356         DEBUG_STORE_DATA( speech_activity.dat,      tmp,                            sizeof( SKP_float ) );\r
357         for( i = 0; i < VAD_N_BANDS; i++ ) {\r
358             tmp[ i ] = (SKP_float)sEncCtrl.input_quality_bands_Q15[ i ] / 32768.0f;\r
359         }\r
360         DEBUG_STORE_DATA( input_quality_bands.dat,  tmp,                            VAD_N_BANDS * sizeof( SKP_float ) );\r
361         DEBUG_STORE_DATA( sigtype.dat,              &sEncCtrl.sCmn.sigtype,         sizeof( SKP_int ) ); \r
362         DEBUG_STORE_DATA( ratelevel.dat,            &sEncCtrl.sCmn.RateLevelIndex,  sizeof( SKP_int ) ); \r
363         DEBUG_STORE_DATA( lag_index.dat,            &sEncCtrl.sCmn.lagIndex,        sizeof( SKP_int ) ); \r
364         DEBUG_STORE_DATA( contour_index.dat,        &sEncCtrl.sCmn.contourIndex,    sizeof( SKP_int ) ); \r
365         DEBUG_STORE_DATA( per_index.dat,            &sEncCtrl.sCmn.PERIndex,        sizeof( SKP_int ) ); \r
366     }\r
367 #endif\r
368     return( ret );\r
369 }\r
370 \r
371 /* Low BitRate Redundancy encoding functionality. Reuse all parameters but encode residual with lower bitrate */\r
372 void SKP_Silk_LBRR_encode_FIX(\r
373     SKP_Silk_encoder_state_FIX      *psEnc,         /* I/O  Pointer to Silk encoder state           */\r
374     SKP_Silk_encoder_control_FIX    *psEncCtrl,     /* I/O  Pointer to Silk encoder control struct  */\r
375     SKP_uint8                       *pCode,         /* O    Pointer to payload                      */\r
376     SKP_int16                       *pnBytesOut,    /* I/O  Pointer to number of payload bytes      */\r
377     SKP_int16                       xfw[]           /* I    Input signal                            */\r
378 )\r
379 {\r
380     SKP_int     i, TempGainsIndices[ MAX_NB_SUBFR ], frame_terminator;\r
381     SKP_int     nBytes, nFramesInPayloadBuf;\r
382     SKP_int32   TempGains_Q16[ MAX_NB_SUBFR ];\r
383     SKP_int     typeOffset, LTP_scaleIndex, Rate_only_parameters = 0;\r
384     ec_byte_buffer range_enc_celt_buf;\r
385 \r
386     /*******************************************/\r
387     /* Control use of inband LBRR              */\r
388     /*******************************************/\r
389     SKP_Silk_LBRR_ctrl_FIX( psEnc, psEncCtrl );\r
390 \r
391     if( psEnc->sCmn.LBRR_enabled ) {\r
392         /* Save original Gains */\r
393         SKP_memcpy( TempGainsIndices, psEncCtrl->sCmn.GainsIndices, MAX_NB_SUBFR * sizeof( SKP_int   ) );\r
394         SKP_memcpy( TempGains_Q16,    psEncCtrl->Gains_Q16,         MAX_NB_SUBFR * sizeof( SKP_int32 ) );\r
395 \r
396         typeOffset     = psEnc->sCmn.typeOffsetPrev; // Temp save as cannot be overwritten\r
397         LTP_scaleIndex = psEncCtrl->sCmn.LTP_scaleIndex;\r
398 \r
399         /* Set max rate where quant signal is encoded */\r
400         if( psEnc->sCmn.fs_kHz == 8 ) {\r
401             Rate_only_parameters = 13500;\r
402         } else if( psEnc->sCmn.fs_kHz == 12 ) {\r
403             Rate_only_parameters = 15500;\r
404         } else if( psEnc->sCmn.fs_kHz == 16 ) {\r
405             Rate_only_parameters = 17500;\r
406         } else if( psEnc->sCmn.fs_kHz == 24 ) {\r
407             Rate_only_parameters = 19500;\r
408         } else {\r
409             SKP_assert( 0 );\r
410         }\r
411 \r
412         if( psEnc->sCmn.Complexity > 0 && psEnc->sCmn.TargetRate_bps > Rate_only_parameters ) {\r
413             if( psEnc->sCmn.nFramesInPayloadBuf == 0 ) {\r
414                 /* First frame in packet copy Everything */\r
415                 SKP_memcpy( &psEnc->sNSQ_LBRR, &psEnc->sNSQ, sizeof( SKP_Silk_nsq_state ) );\r
416             \r
417                 psEnc->sCmn.LBRRprevLastGainIndex = psEnc->sShape.LastGainIndex;\r
418                 /* Increase Gains to get target LBRR rate */\r
419                 psEncCtrl->sCmn.GainsIndices[ 0 ] = psEncCtrl->sCmn.GainsIndices[ 0 ] + psEnc->sCmn.LBRR_GainIncreases;\r
420                 psEncCtrl->sCmn.GainsIndices[ 0 ] = SKP_LIMIT_int( psEncCtrl->sCmn.GainsIndices[ 0 ], 0, N_LEVELS_QGAIN - 1 );\r
421             }\r
422             /* Decode to get Gains in sync with decoder         */\r
423             /* Overwrite unquantized gains with quantized gains */\r
424             SKP_Silk_gains_dequant( psEncCtrl->Gains_Q16, psEncCtrl->sCmn.GainsIndices, \r
425                 &psEnc->sCmn.LBRRprevLastGainIndex, psEnc->sCmn.nFramesInPayloadBuf, psEnc->sCmn.nb_subfr );\r
426             /*****************************************/\r
427             /* Noise shaping quantization            */\r
428             /*****************************************/\r
429             if( psEnc->sCmn.nStatesDelayedDecision > 1 ) {\r
430                 SKP_Silk_NSQ_del_dec( &psEnc->sCmn, &psEncCtrl->sCmn,\r
431                     &psEnc->sNSQ_LBRR, xfw, &psEnc->sCmn.q_LBRR[ psEnc->sCmn.nFramesInPayloadBuf * psEnc->sCmn.frame_length ], \r
432                     psEncCtrl->sCmn.NLSFInterpCoef_Q2, psEncCtrl->PredCoef_Q12[ 0 ], psEncCtrl->LTPCoef_Q14, \r
433                     psEncCtrl->AR2_Q13, psEncCtrl->HarmShapeGain_Q14, psEncCtrl->Tilt_Q14, psEncCtrl->LF_shp_Q14, \r
434                     psEncCtrl->Gains_Q16, psEncCtrl->Lambda_Q10, psEncCtrl->LTP_scale_Q14 );\r
435             } else {\r
436                 SKP_Silk_NSQ( &psEnc->sCmn, &psEncCtrl->sCmn,\r
437                     &psEnc->sNSQ_LBRR, xfw, &psEnc->sCmn.q_LBRR[ psEnc->sCmn.nFramesInPayloadBuf * psEnc->sCmn.frame_length ], \r
438                     psEncCtrl->sCmn.NLSFInterpCoef_Q2, psEncCtrl->PredCoef_Q12[ 0 ], psEncCtrl->LTPCoef_Q14, \r
439                     psEncCtrl->AR2_Q13, psEncCtrl->HarmShapeGain_Q14, psEncCtrl->Tilt_Q14, psEncCtrl->LF_shp_Q14, \r
440                     psEncCtrl->Gains_Q16, psEncCtrl->Lambda_Q10, psEncCtrl->LTP_scale_Q14 );\r
441             }\r
442         } else {\r
443             SKP_memset( &psEnc->sCmn.q_LBRR[ psEnc->sCmn.nFramesInPayloadBuf *psEnc->sCmn.frame_length ], 0,\r
444                 psEnc->sCmn.frame_length * sizeof( SKP_int ) );\r
445             psEncCtrl->sCmn.LTP_scaleIndex = 0;\r
446         }\r
447         /****************************************/\r
448         /* Initialize arithmetic coder          */\r
449         /****************************************/\r
450         if( psEnc->sCmn.nFramesInPayloadBuf == 0 ) {\r
451             ec_byte_writeinit_buffer( &range_enc_celt_buf, psEnc->sCmn.sRC_LBRR.buffer, MAX_ARITHM_BYTES );\r
452             ec_enc_init( &psEnc->sCmn.sRC_LBRR.range_enc_celt_state, &range_enc_celt_buf );\r
453 \r
454             SKP_Silk_range_enc_init( &psEnc->sCmn.sRC_LBRR );\r
455             psEnc->sCmn.nBytesInPayloadBuf = 0;\r
456         }\r
457 \r
458         /****************************************/\r
459         /* Encode Parameters                    */\r
460         /****************************************/\r
461         SKP_Silk_encode_parameters_v4( &psEnc->sCmn, &psEncCtrl->sCmn, &psEnc->sCmn.sRC_LBRR );\r
462 \r
463         if( psEnc->sCmn.sRC_LBRR.error ) {\r
464             /* encoder returned error: clear payload buffer */\r
465             nFramesInPayloadBuf = 0;\r
466         } else {\r
467             nFramesInPayloadBuf = psEnc->sCmn.nFramesInPayloadBuf + 1;\r
468         }\r
469 \r
470         /****************************************/\r
471         /* finalize payload and copy to output  */\r
472         /****************************************/\r
473         if( SKP_SMULBB( nFramesInPayloadBuf, SKP_SMULBB( SUB_FRAME_LENGTH_MS, psEnc->sCmn.nb_subfr ) ) >= psEnc->sCmn.PacketSize_ms ) {\r
474 \r
475             /* Check if FEC information should be added */\r
476             frame_terminator = SKP_SILK_LAST_FRAME;\r
477 \r
478             /* Add the frame termination info to stream */\r
479             SKP_Silk_range_encoder( &psEnc->sCmn.sRC_LBRR, frame_terminator, SKP_Silk_FrameTermination_v4_CDF );\r
480             \r
481             /*********************************************/\r
482             /* Encode quantization indices of excitation */\r
483             /*********************************************/\r
484             for( i = 0; i < nFramesInPayloadBuf; i++ ) {\r
485                 SKP_Silk_encode_pulses( &psEnc->sCmn.sRC_LBRR, psEnc->sCmn.sigtype[ i ], psEnc->sCmn.QuantOffsetType[ i ],\r
486                     &psEnc->sCmn.q_LBRR[ i * psEnc->sCmn.frame_length ], psEnc->sCmn.frame_length );\r
487             }\r
488             /* payload length so far */\r
489             SKP_Silk_range_encoder_get_length( &psEnc->sCmn.sRC_LBRR, &nBytes );\r
490 \r
491             /* check that there is enough space in external output buffer, and move data */\r
492             if( *pnBytesOut >= nBytes ) {\r
493                 SKP_int bits_in_stream, mask;\r
494                 bits_in_stream = ec_enc_tell( &psEnc->sCmn.sRC_LBRR.range_enc_celt_state, 0 );\r
495                 ec_enc_done( &psEnc->sCmn.sRC_LBRR.range_enc_celt_state );\r
496 \r
497                 /* Fill up any remaining bits in the last byte with 1s */\r
498                 if( bits_in_stream & 7 ) {\r
499                     mask = SKP_RSHIFT( 0xFF, bits_in_stream & 7 );\r
500                     if( nBytes - 1 < *pnBytesOut ) {\r
501                         psEnc->sCmn.sRC_LBRR.range_enc_celt_state.buf->buf[ nBytes - 1 ] |= mask;\r
502                     }\r
503                 }\r
504                 SKP_memcpy( pCode, psEnc->sCmn.sRC_LBRR.range_enc_celt_state.buf->buf, nBytes * sizeof( SKP_uint8 ) );\r
505 //#endif\r
506                 *pnBytesOut = nBytes;\r
507             } else {\r
508                 /* not enough space: payload will be discarded */\r
509                 *pnBytesOut = 0;\r
510                 SKP_assert( 0 );\r
511             }\r
512         } else {\r
513             /* no payload for you this time */\r
514             *pnBytesOut = 0;\r
515 \r
516             /* Encode that more frames follows */\r
517             frame_terminator = SKP_SILK_MORE_FRAMES;\r
518             SKP_Silk_range_encoder( &psEnc->sCmn.sRC_LBRR, frame_terminator, SKP_Silk_FrameTermination_v4_CDF );\r
519         }\r
520 \r
521         /* Restore original Gains */\r
522         SKP_memcpy( psEncCtrl->sCmn.GainsIndices, TempGainsIndices, MAX_NB_SUBFR * sizeof( SKP_int   ) );\r
523         SKP_memcpy( psEncCtrl->Gains_Q16,         TempGains_Q16,    MAX_NB_SUBFR * sizeof( SKP_int32 ) );\r
524     \r
525         /* Restore LTP scale index and typeoffset */\r
526         psEncCtrl->sCmn.LTP_scaleIndex = LTP_scaleIndex;\r
527         psEnc->sCmn.typeOffsetPrev = typeOffset;\r
528     }\r
529 }\r