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     const SKP_uint16 *FrameTermination_CDF;\r
50 \r
51     /* Low bitrate redundancy parameters */\r
52     SKP_uint8   LBRRpayload[ MAX_ARITHM_BYTES ];\r
53     SKP_int32   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     ret = SKP_Silk_VAD_GetSA_Q8( &psEnc->sCmn.sVAD, &psEnc->speech_activity_Q8, &SNR_dB_Q7, \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 + LA_SHAPE_MS * psEnc->sCmn.fs_kHz, pIn_HP, psEnc->sCmn.frame_length );\r
89 #else\r
90     SKP_memcpy( x_frame + LA_SHAPE_MS * psEnc->sCmn.fs_kHz, 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 || psEnc->sCmn.warping_Q16 > 0 ) {\r
144         SKP_Silk_NSQ_del_dec( &psEnc->sCmn, &sEncCtrl.sCmn, &psEnc->sNSQ, xfw,\r
145             psEnc->sCmn.q, 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, 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 < SKP_FIX_CONST( SPEECH_ACTIVITY_DTX_THRES, 8 ) ) {\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 range coder               */\r
179     /****************************************/\r
180     if( psEnc->sCmn.nFramesInPayloadBuf == 0 ) {\r
181         psEnc->sCmn.nBytesInPayloadBuf = 0;\r
182     }\r
183 \r
184     /****************************************/\r
185     /* Encode Parameters                    */\r
186     /****************************************/\r
187 TIC(ENCODE_PARAMS)\r
188     SKP_Silk_encode_parameters( &psEnc->sCmn, &sEncCtrl.sCmn, psRangeEnc );\r
189     FrameTermination_CDF = SKP_Silk_FrameTermination_CDF;\r
190 TOC(ENCODE_PARAMS)\r
191 \r
192     /****************************************/\r
193     /* Update Buffers and State             */\r
194     /****************************************/\r
195     /* Update input buffer */\r
196     SKP_memmove( psEnc->x_buf, &psEnc->x_buf[ psEnc->sCmn.frame_length ], \r
197         ( psEnc->sCmn.ltp_mem_length + LA_SHAPE_MS * psEnc->sCmn.fs_kHz ) * sizeof( SKP_int16 ) );\r
198     \r
199     /* Parameters needed for next frame */\r
200     psEnc->sCmn.prev_sigtype            = sEncCtrl.sCmn.sigtype;\r
201     psEnc->sCmn.prevLag                 = sEncCtrl.sCmn.pitchL[ psEnc->sCmn.nb_subfr - 1 ];\r
202     psEnc->sCmn.first_frame_after_reset = 0;\r
203 \r
204     if( 0 ) { //psEnc->sCmn.sRC.error ) {\r
205         /* Encoder returned error: clear payload buffer */\r
206         psEnc->sCmn.nFramesInPayloadBuf = 0;\r
207     } else {\r
208         psEnc->sCmn.nFramesInPayloadBuf++;\r
209     }\r
210 \r
211     /****************************************/\r
212     /* Finalize payload and copy to output  */\r
213     /****************************************/\r
214     if( psEnc->sCmn.nFramesInPayloadBuf * SUB_FRAME_LENGTH_MS * psEnc->sCmn.nb_subfr >= psEnc->sCmn.PacketSize_ms ) {\r
215 \r
216         LBRR_idx = ( psEnc->sCmn.oldest_LBRR_idx + 1 ) & LBRR_IDX_MASK;\r
217 \r
218         /* Check if FEC information should be added */\r
219         //frame_terminator = psEnc->sCmn.LBRR_buffer[ LBRR_idx ].usage;\r
220         frame_terminator = SKP_SILK_NO_LBRR;\r
221 \r
222         /* Add the frame termination info to stream */\r
223         ec_encode_bin( psRangeEnc, FrameTermination_CDF[ frame_terminator ], \r
224             FrameTermination_CDF[ frame_terminator + 1 ], 16 );\r
225 \r
226         /* Code excitation signal */\r
227         for( i = 0; i < psEnc->sCmn.nFramesInPayloadBuf; i++ ) {\r
228             SKP_Silk_encode_pulses( psRangeEnc, psEnc->sCmn.sigtype[ i ], psEnc->sCmn.QuantOffsetType[ i ], \r
229                 &psEnc->sCmn.q[ i * psEnc->sCmn.frame_length ], psEnc->sCmn.frame_length );\r
230         }\r
231 \r
232         /* Payload length so far */\r
233         nBytes = SKP_RSHIFT( ec_enc_tell( psRangeEnc, 0 ) + 7, 3 );\r
234 \r
235         /* Check that there is enough space in external output buffer, and move data */\r
236         if( *pnBytesOut >= nBytes ) {\r
237             //SKP_int bits_in_stream, mask;\r
238             //bits_in_stream = ec_enc_tell( psRangeEnc, 0 );\r
239             //ec_enc_done( psRangeEnc );\r
240             \r
241 #if 0\r
242             /* Fill up any remaining bits in the last byte with 1s */\r
243             if( bits_in_stream & 7 ) {\r
244                 mask = SKP_RSHIFT( 0xFF, bits_in_stream & 7 );\r
245                 if( nBytes - 1 < *pnBytesOut ) {\r
246                     psEnc->sCmn.sRC.range_enc_celt_state.buf->buf[ nBytes - 1 ] |= mask;\r
247                 }\r
248             }\r
249             SKP_memcpy( pCode, psEnc->sCmn.sRC.range_enc_celt_state.buf->buf, nBytes * sizeof( SKP_uint8 ) );\r
250 #endif\r
251 \r
252 #if 0\r
253             if( frame_terminator > SKP_SILK_MORE_FRAMES && \r
254                     *pnBytesOut >= nBytes + psEnc->sCmn.LBRR_buffer[ LBRR_idx ].nBytes ) {\r
255                 /* Get old packet and add to payload. */\r
256                 SKP_memcpy( &pCode[ nBytes ],\r
257                     psEnc->sCmn.LBRR_buffer[ LBRR_idx ].payload,\r
258                     psEnc->sCmn.LBRR_buffer[ LBRR_idx ].nBytes * sizeof( SKP_uint8 ) );\r
259                 nBytes += psEnc->sCmn.LBRR_buffer[ LBRR_idx ].nBytes;\r
260             }\r
261 #endif\r
262             *pnBytesOut = nBytes;\r
263 \r
264             /* Update FEC buffer */\r
265             SKP_memcpy( psEnc->sCmn.LBRR_buffer[ psEnc->sCmn.oldest_LBRR_idx ].payload, LBRRpayload, \r
266                 nBytesLBRR * sizeof( SKP_uint8 ) );\r
267             psEnc->sCmn.LBRR_buffer[ psEnc->sCmn.oldest_LBRR_idx ].nBytes = nBytesLBRR;\r
268             /* The line below describes how FEC should be used */\r
269             psEnc->sCmn.LBRR_buffer[ psEnc->sCmn.oldest_LBRR_idx ].usage = sEncCtrl.sCmn.LBRR_usage;\r
270             psEnc->sCmn.oldest_LBRR_idx = ( psEnc->sCmn.oldest_LBRR_idx + 1 ) & LBRR_IDX_MASK;\r
271 \r
272         } else {\r
273             /* Not enough space: Payload will be discarded */\r
274             *pnBytesOut = 0;\r
275             nBytes      = 0;\r
276             ret = SKP_SILK_ENC_PAYLOAD_BUF_TOO_SHORT;\r
277         }\r
278 \r
279         /* Reset the number of frames in payload buffer */\r
280         psEnc->sCmn.nFramesInPayloadBuf = 0;\r
281     } else {\r
282         /* No payload this time */\r
283         *pnBytesOut = 0;\r
284 \r
285         /* Payload length so far */\r
286         nBytes = SKP_RSHIFT( ec_enc_tell( psRangeEnc, 0 ) + 7, 3 );\r
287 \r
288         /* Take into account the q signal that isn't in the bitstream yet */\r
289         nBytes += SKP_Silk_pulses_to_bytes( &psEnc->sCmn, \r
290             &psEnc->sCmn.q[ psEnc->sCmn.nFramesInPayloadBuf * psEnc->sCmn.frame_length ] );\r
291     }\r
292 \r
293     /* Check for arithmetic coder errors */\r
294     if( 0 ) { //psEnc->sCmn.sRC.error ) {\r
295         ret = SKP_SILK_ENC_INTERNAL_ERROR;\r
296     }\r
297 \r
298     /* Simulate number of ms buffered in channel because of exceeding TargetRate */\r
299     SKP_assert(  ( 8 * 1000 * ( (SKP_int64)nBytes - (SKP_int64)psEnc->sCmn.nBytesInPayloadBuf ) ) == \r
300         SKP_SAT32( 8 * 1000 * ( (SKP_int64)nBytes - (SKP_int64)psEnc->sCmn.nBytesInPayloadBuf ) ) );\r
301     SKP_assert( psEnc->sCmn.TargetRate_bps > 0 );\r
302     psEnc->BufferedInChannel_ms   += SKP_DIV32( 8 * 1000 * ( nBytes - psEnc->sCmn.nBytesInPayloadBuf ), psEnc->sCmn.TargetRate_bps );\r
303     psEnc->BufferedInChannel_ms   -= SKP_SMULBB( SUB_FRAME_LENGTH_MS, psEnc->sCmn.nb_subfr );\r
304     psEnc->BufferedInChannel_ms    = SKP_LIMIT_int( psEnc->BufferedInChannel_ms, 0, 100 );\r
305     psEnc->sCmn.nBytesInPayloadBuf = nBytes;\r
306 \r
307     if( psEnc->speech_activity_Q8 > SKP_FIX_CONST( WB_DETECT_ACTIVE_SPEECH_LEVEL_THRES, 8 ) ) {\r
308         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
309     }\r
310 \r
311 TOC(ENCODE_FRAME)\r
312 \r
313 #ifdef SAVE_ALL_INTERNAL_DATA\r
314     {\r
315         SKP_float tmp[ MAX_NB_SUBFR * LTP_ORDER ];\r
316         int i;\r
317         DEBUG_STORE_DATA( xf.dat,                   x_frame + LA_SHAPE_MS * psEnc->sCmn.fs_kHz, psEnc->sCmn.frame_length    * sizeof( SKP_int16 ) );\r
318         DEBUG_STORE_DATA( xfw.dat,                  xfw,                            psEnc->sCmn.frame_length    * sizeof( SKP_int16 ) );\r
319         //      DEBUG_STORE_DATA( q.dat,                    &psEnc->sCmn.q[ ( psEnc->sCmn.nFramesInPayloadBuf - 1)*psEnc->sCmn.frame_length ],  psEnc->sCmn.frame_length    * sizeof( SKP_int8 ) );\r
320         DEBUG_STORE_DATA( pitchL.dat,               sEncCtrl.sCmn.pitchL,           psEnc->sCmn.nb_subfr            * sizeof( SKP_int ) );\r
321         for( i = 0; i < psEnc->sCmn.nb_subfr * LTP_ORDER; i++ ) {\r
322             tmp[ i ] = (SKP_float)sEncCtrl.LTPCoef_Q14[ i ] / 16384.0f;\r
323         }\r
324         DEBUG_STORE_DATA( pitchG_quantized.dat,     tmp,                            psEnc->sCmn.nb_subfr * LTP_ORDER * sizeof( SKP_float ) );\r
325         for( i = 0; i <psEnc->sCmn.predictLPCOrder; i++ ) {\r
326             tmp[ i ] = (SKP_float)sEncCtrl.PredCoef_Q12[ 1 ][ i ] / 4096.0f;\r
327         }\r
328         DEBUG_STORE_DATA( PredCoef.dat,             tmp,                            psEnc->sCmn.predictLPCOrder * sizeof( SKP_float ) );\r
329         \r
330         tmp[ 0 ] = (SKP_float)sEncCtrl.pitch_freq_low_Hz;\r
331         DEBUG_STORE_DATA( pitch_freq_low_Hz.dat,    tmp,                            sizeof( SKP_float ) );\r
332         tmp[ 0 ] = (SKP_float)sEncCtrl.LTPredCodGain_Q7 / 128.0f;\r
333         DEBUG_STORE_DATA( LTPredCodGain.dat,        tmp,                            sizeof( SKP_float ) );\r
334         tmp[ 0 ] = (SKP_float)psEnc->LTPCorr_Q15 / 32768.0f;\r
335         DEBUG_STORE_DATA( LTPcorr.dat,              tmp,                            sizeof( SKP_float ) );\r
336         tmp[ 0 ] = (SKP_float)sEncCtrl.input_tilt_Q15 / 32768.0f;\r
337         DEBUG_STORE_DATA( tilt.dat,                 tmp,                            sizeof( SKP_float ) );\r
338         for( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) {\r
339             tmp[ i ] = (SKP_float)sEncCtrl.Gains_Q16[ i ] / 65536.0f;\r
340         }\r
341         DEBUG_STORE_DATA( gains.dat,                tmp,                            psEnc->sCmn.nb_subfr * sizeof( SKP_float ) );\r
342         DEBUG_STORE_DATA( gains_indices.dat,        &sEncCtrl.sCmn.GainsIndices,    psEnc->sCmn.nb_subfr * sizeof( SKP_int ) );\r
343         DEBUG_STORE_DATA( nBytes.dat,               &nBytes,                        sizeof( SKP_int ) );\r
344         tmp[ 0 ] = (SKP_float)sEncCtrl.current_SNR_dB_Q7 / 128.0f;\r
345         DEBUG_STORE_DATA( current_SNR_db.dat,       tmp,                            sizeof( SKP_float ) );\r
346         DEBUG_STORE_DATA( QuantOffsetType.dat,      &sEncCtrl.sCmn.QuantOffsetType, sizeof( SKP_int ) );\r
347         tmp[ 0 ] = (SKP_float)psEnc->speech_activity_Q8 / 256.0f;\r
348         DEBUG_STORE_DATA( speech_activity.dat,      tmp,                            sizeof( SKP_float ) );\r
349         for( i = 0; i < VAD_N_BANDS; i++ ) {\r
350             tmp[ i ] = (SKP_float)sEncCtrl.input_quality_bands_Q15[ i ] / 32768.0f;\r
351         }\r
352         DEBUG_STORE_DATA( input_quality_bands.dat,  tmp,                            VAD_N_BANDS * sizeof( SKP_float ) );\r
353         DEBUG_STORE_DATA( sigtype.dat,              &sEncCtrl.sCmn.sigtype,         sizeof( SKP_int ) ); \r
354         DEBUG_STORE_DATA( ratelevel.dat,            &sEncCtrl.sCmn.RateLevelIndex,  sizeof( SKP_int ) ); \r
355         DEBUG_STORE_DATA( lag_index.dat,            &sEncCtrl.sCmn.lagIndex,        sizeof( SKP_int ) ); \r
356         DEBUG_STORE_DATA( contour_index.dat,        &sEncCtrl.sCmn.contourIndex,    sizeof( SKP_int ) ); \r
357         DEBUG_STORE_DATA( per_index.dat,            &sEncCtrl.sCmn.PERIndex,        sizeof( SKP_int ) ); \r
358     }\r
359 #endif\r
360     return( ret );\r
361 }\r
362 \r
363 #if 0  //tmp\r
364 /* Low BitRate Redundancy encoding functionality. Reuse all parameters but encode residual with lower bitrate */\r
365 void SKP_Silk_LBRR_encode_FIX(\r
366     SKP_Silk_encoder_state_FIX      *psEnc,         /* I/O  Pointer to Silk encoder state           */\r
367     SKP_Silk_encoder_control_FIX    *psEncCtrl,     /* I/O  Pointer to Silk encoder control struct  */\r
368     SKP_uint8                       *pCode,         /* O    Pointer to payload                      */\r
369     SKP_int16                       *pnBytesOut,    /* I/O  Pointer to number of payload bytes      */\r
370     SKP_int16                       xfw[]           /* I    Input signal                            */\r
371 )\r
372 {\r
373     SKP_int     i, TempGainsIndices[ MAX_NB_SUBFR ], frame_terminator;\r
374     SKP_int     nBytes, nFramesInPayloadBuf;\r
375     SKP_int32   TempGains_Q16[ MAX_NB_SUBFR ];\r
376     SKP_int     typeOffset, LTP_scaleIndex, Rate_only_parameters = 0;\r
377     ec_byte_buffer range_enc_celt_buf;\r
378 \r
379     /*******************************************/\r
380     /* Control use of inband LBRR              */\r
381     /*******************************************/\r
382     SKP_Silk_LBRR_ctrl_FIX( psEnc, &psEncCtrl->sCmn );\r
383 \r
384     if( psEnc->sCmn.LBRR_enabled ) {\r
385         /* Save original gains */\r
386         SKP_memcpy( TempGainsIndices, psEncCtrl->sCmn.GainsIndices, MAX_NB_SUBFR * sizeof( SKP_int   ) );\r
387         SKP_memcpy( TempGains_Q16,    psEncCtrl->Gains_Q16,         MAX_NB_SUBFR * sizeof( SKP_int32 ) );\r
388 \r
389         typeOffset     = psEnc->sCmn.typeOffsetPrev; // Temp save as cannot be overwritten\r
390         LTP_scaleIndex = psEncCtrl->sCmn.LTP_scaleIndex;\r
391 \r
392         /* Set max rate where quant signal is encoded */\r
393         if( psEnc->sCmn.fs_kHz == 8 ) {\r
394             Rate_only_parameters = 13500;\r
395         } else if( psEnc->sCmn.fs_kHz == 12 ) {\r
396             Rate_only_parameters = 15500;\r
397         } else if( psEnc->sCmn.fs_kHz == 16 ) {\r
398             Rate_only_parameters = 17500;\r
399         } else if( psEnc->sCmn.fs_kHz == 24 ) {\r
400             Rate_only_parameters = 19500;\r
401         } else {\r
402             SKP_assert( 0 );\r
403         }\r
404 \r
405         if( psEnc->sCmn.Complexity > 0 && psEnc->sCmn.TargetRate_bps > Rate_only_parameters ) {\r
406             if( psEnc->sCmn.nFramesInPayloadBuf == 0 ) {\r
407                 /* First frame in packet; copy everything */\r
408                 SKP_memcpy( &psEnc->sNSQ_LBRR, &psEnc->sNSQ, sizeof( SKP_Silk_nsq_state ) );\r
409 \r
410                 psEnc->sCmn.LBRRprevLastGainIndex = psEnc->sShape.LastGainIndex;\r
411                 /* Increase Gains to get target LBRR rate */\r
412                 psEncCtrl->sCmn.GainsIndices[ 0 ] = psEncCtrl->sCmn.GainsIndices[ 0 ] + psEnc->sCmn.LBRR_GainIncreases;\r
413                 psEncCtrl->sCmn.GainsIndices[ 0 ] = SKP_LIMIT_int( psEncCtrl->sCmn.GainsIndices[ 0 ], 0, N_LEVELS_QGAIN - 1 );\r
414             }\r
415             /* Decode to get gains in sync with decoder         */\r
416             /* Overwrite unquantized gains with quantized gains */\r
417             SKP_Silk_gains_dequant( psEncCtrl->Gains_Q16, psEncCtrl->sCmn.GainsIndices, \r
418                 &psEnc->sCmn.LBRRprevLastGainIndex, psEnc->sCmn.nFramesInPayloadBuf, psEnc->sCmn.nb_subfr );\r
419 \r
420             /*****************************************/\r
421             /* Noise shaping quantization            */\r
422             /*****************************************/\r
423             if( psEnc->sCmn.nStatesDelayedDecision > 1 || psEnc->sCmn.warping_Q16 > 0 ) {\r
424                 SKP_Silk_NSQ_del_dec( &psEnc->sCmn, &psEncCtrl->sCmn, &psEnc->sNSQ_LBRR, xfw, psEnc->sCmn.q_LBRR, \r
425                     psEncCtrl->sCmn.NLSFInterpCoef_Q2, psEncCtrl->PredCoef_Q12[ 0 ], psEncCtrl->LTPCoef_Q14, \r
426                     psEncCtrl->AR2_Q13, psEncCtrl->HarmShapeGain_Q14, psEncCtrl->Tilt_Q14, psEncCtrl->LF_shp_Q14, \r
427                     psEncCtrl->Gains_Q16, psEncCtrl->Lambda_Q10, psEncCtrl->LTP_scale_Q14 );\r
428             } else {\r
429                 SKP_Silk_NSQ( &psEnc->sCmn, &psEncCtrl->sCmn, &psEnc->sNSQ_LBRR, xfw, psEnc->sCmn.q_LBRR, \r
430                     psEncCtrl->sCmn.NLSFInterpCoef_Q2, psEncCtrl->PredCoef_Q12[ 0 ], psEncCtrl->LTPCoef_Q14, \r
431                     psEncCtrl->AR2_Q13, psEncCtrl->HarmShapeGain_Q14, psEncCtrl->Tilt_Q14, psEncCtrl->LF_shp_Q14, \r
432                     psEncCtrl->Gains_Q16, psEncCtrl->Lambda_Q10, psEncCtrl->LTP_scale_Q14 );\r
433             }\r
434         } else {\r
435             SKP_memset( psEnc->sCmn.q_LBRR, 0, psEnc->sCmn.frame_length * sizeof( SKP_int8 ) );\r
436             psEncCtrl->sCmn.LTP_scaleIndex = 0;\r
437         }\r
438         /****************************************/\r
439         /* Initialize arithmetic coder          */\r
440         /****************************************/\r
441         if( psEnc->sCmn.nFramesInPayloadBuf == 0 ) {\r
442             ec_byte_writeinit_buffer( &range_enc_celt_buf, psEnc->sCmn.sRC_LBRR.buffer, MAX_ARITHM_BYTES );\r
443             ec_enc_init( &psEnc->sCmn.sRC_LBRR.range_enc_celt_state, &range_enc_celt_buf );\r
444 \r
445             SKP_Silk_range_enc_init( &psEnc->sCmn.sRC_LBRR );\r
446             psEnc->sCmn.nBytesInPayloadBuf = 0;\r
447         }\r
448 \r
449         /****************************************/\r
450         /* Encode Parameters                    */\r
451         /****************************************/\r
452         SKP_Silk_encode_parameters( &psEnc->sCmn, &psEncCtrl->sCmn, \r
453             &psEnc->sCmn.sRC_LBRR );\r
454 \r
455         /****************************************/\r
456         /* Encode Parameters                    */\r
457         /****************************************/\r
458         if( psEnc->sCmn.sRC_LBRR.error ) {\r
459             /* Encoder returned error: clear payload buffer */\r
460             nFramesInPayloadBuf = 0;\r
461         } else {\r
462             nFramesInPayloadBuf = psEnc->sCmn.nFramesInPayloadBuf + 1;\r
463         }\r
464 \r
465         /****************************************/\r
466         /* Finalize payload and copy to output  */\r
467         /****************************************/\r
468         if( SKP_SMULBB( nFramesInPayloadBuf, SKP_SMULBB( SUB_FRAME_LENGTH_MS, psEnc->sCmn.nb_subfr ) ) >= psEnc->sCmn.PacketSize_ms ) {\r
469 \r
470             /* Check if FEC information should be added */\r
471             frame_terminator = SKP_SILK_LAST_FRAME;\r
472 \r
473             /* Add the frame termination info to stream */\r
474             ec_encode_bin( psRangeEnc_LBRR, FrameTermination_CDF[ frame_terminator ], \r
475                 FrameTermination_CDF[ frame_terminator + 1 ], 16 );\r
476 \r
477             /*********************************************/\r
478             /* Encode quantization indices of excitation */\r
479             /*********************************************/\r
480             for( i = 0; i < nFramesInPayloadBuf; i++ ) {\r
481                 SKP_Silk_encode_pulses( &psEnc->sCmn.sRC_LBRR, psEnc->sCmn.sigtype[ i ], psEnc->sCmn.QuantOffsetType[ i ],\r
482                     &psEnc->sCmn.q_LBRR[ i * psEnc->sCmn.frame_length ], psEnc->sCmn.frame_length );\r
483             }\r
484 \r
485             /* Payload length so far */\r
486             nBytes = SKP_RSHIFT( ec_enc_tell( psRangeEnc_LBRR, 0 ) + 7, 3 );\r
487 \r
488             /* Check that there is enough space in external output buffer and move data */\r
489             if( *pnBytesOut >= nBytes ) {\r
490                 SKP_int bits_in_stream, mask;\r
491                 bits_in_stream = ec_enc_tell( &psEnc->sCmn.sRC_LBRR.range_enc_celt_state, 0 );\r
492                 ec_enc_done( &psEnc->sCmn.sRC_LBRR.range_enc_celt_state );\r
493 \r
494                 /* Fill up any remaining bits in the last byte with 1s */\r
495                 if( bits_in_stream & 7 ) {\r
496                     mask = SKP_RSHIFT( 0xFF, bits_in_stream & 7 );\r
497                     if( nBytes - 1 < *pnBytesOut ) {\r
498                         psEnc->sCmn.sRC_LBRR.range_enc_celt_state.buf->buf[ nBytes - 1 ] |= mask;\r
499                     }\r
500                 }\r
501                 SKP_memcpy( pCode, psEnc->sCmn.sRC_LBRR.range_enc_celt_state.buf->buf, nBytes * sizeof( SKP_uint8 ) );\r
502 \r
503                 *pnBytesOut = nBytes;\r
504             } else {\r
505                 /* Not enough space: payload will be discarded */\r
506                 *pnBytesOut = 0;\r
507                 SKP_assert( 0 );\r
508             }\r
509         } else {\r
510             /* No payload this time */\r
511             *pnBytesOut = 0;\r
512 \r
513             /* Encode that more frames follows */\r
514             frame_terminator = SKP_SILK_MORE_FRAMES;\r
515             ec_encode_bin( psRangeEnc_LBRR, FrameTermination_CDF[ frame_terminator ], \r
516                 FrameTermination_CDF[ frame_terminator + 1 ], 16 );\r
517         }\r
518 \r
519         /* Restore original Gains */\r
520         SKP_memcpy( psEncCtrl->sCmn.GainsIndices, TempGainsIndices, psEnc->sCmn.nb_subfr * sizeof( SKP_int   ) );\r
521         SKP_memcpy( psEncCtrl->Gains_Q16,         TempGains_Q16,    psEnc->sCmn.nb_subfr * sizeof( SKP_int32 ) );\r
522     \r
523         /* Restore LTP scale index and typeoffset */\r
524         psEncCtrl->sCmn.LTP_scaleIndex = LTP_scaleIndex;\r
525         psEnc->sCmn.typeOffsetPrev     = typeOffset;\r
526     }\r
527 }\r
528 #endif\r