348f4d29bece285d6781cae0bda812a7991b9f0b
[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,        /*   O  Number of payload bytes                 */\r
37     ec_enc                          *psRangeEnc,        /* I/O  compressor data structure               */\r
38     const SKP_int16                 *pIn                /* I    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     frame_terminator, SNR_dB_Q7;\r
48 \r
49 TIC(ENCODE_FRAME)\r
50 \r
51     sEncCtrl.sCmn.Seed = psEnc->sCmn.frameCounter++ & 3;\r
52     /**************************************************************/\r
53     /* Setup Input Pointers, and insert frame in input buffer    */\r
54     /*************************************************************/\r
55     /* pointers aligned with start of frame to encode */\r
56     x_frame         = psEnc->x_buf + psEnc->sCmn.ltp_mem_length;    /* start of frame to encode */\r
57     res_pitch_frame = res_pitch    + psEnc->sCmn.ltp_mem_length;    /* start of pitch LPC residual frame */\r
58 \r
59     /****************************/\r
60     /* Voice Activity Detection */\r
61     /****************************/\r
62 TIC(VAD)\r
63     ret = SKP_Silk_VAD_GetSA_Q8( &psEnc->sCmn.sVAD, &psEnc->speech_activity_Q8, &SNR_dB_Q7, \r
64                                  sEncCtrl.input_quality_bands_Q15, &sEncCtrl.input_tilt_Q15,\r
65                                  pIn, psEnc->sCmn.frame_length, psEnc->sCmn.fs_kHz );\r
66 TOC(VAD)\r
67 \r
68     /**************************************************/\r
69     /* Convert speech activity into VAD and DTX flags */\r
70     /**************************************************/\r
71     if( psEnc->speech_activity_Q8 < SKP_FIX_CONST( SPEECH_ACTIVITY_DTX_THRES, 8 ) ) {\r
72         sEncCtrl.sCmn.signalType = TYPE_NO_VOICE_ACTIVITY;\r
73         psEnc->sCmn.noSpeechCounter++;\r
74         if( psEnc->sCmn.noSpeechCounter > NO_SPEECH_FRAMES_BEFORE_DTX ) {\r
75             psEnc->sCmn.inDTX = 1;\r
76         }\r
77         if( psEnc->sCmn.noSpeechCounter > MAX_CONSECUTIVE_DTX ) {\r
78             psEnc->sCmn.noSpeechCounter = 0;\r
79             psEnc->sCmn.inDTX           = 0;\r
80         }\r
81     } else {\r
82         psEnc->sCmn.noSpeechCounter = 0;\r
83         psEnc->sCmn.inDTX           = 0;\r
84         sEncCtrl.sCmn.signalType = TYPE_UNVOICED;\r
85     }\r
86 \r
87     /*******************************************/\r
88     /* High-pass filtering of the input signal */\r
89     /*******************************************/\r
90 TIC(HP_IN)\r
91 #if HIGH_PASS_INPUT\r
92     /* Variable high-pass filter */\r
93     SKP_Silk_HP_variable_cutoff_FIX( psEnc, &sEncCtrl, pIn_HP, pIn );\r
94 #else\r
95     SKP_memcpy( pIn_HP, pIn, psEnc->sCmn.frame_length * sizeof( SKP_int16 ) );\r
96 #endif\r
97 TOC(HP_IN)\r
98 \r
99 #if SWITCH_TRANSITION_FILTERING\r
100     /* Ensure smooth bandwidth transitions */\r
101     SKP_Silk_LP_variable_cutoff( &psEnc->sCmn.sLP, x_frame + LA_SHAPE_MS * psEnc->sCmn.fs_kHz, pIn_HP, psEnc->sCmn.frame_length );\r
102 #else\r
103     SKP_memcpy( x_frame + LA_SHAPE_MS * psEnc->sCmn.fs_kHz, pIn_HP,psEnc->sCmn.frame_length * sizeof( SKP_int16 ) );\r
104 #endif\r
105     \r
106     /*****************************************/\r
107     /* Find pitch lags, initial LPC analysis */\r
108     /*****************************************/\r
109 TIC(FIND_PITCH)\r
110     SKP_Silk_find_pitch_lags_FIX( psEnc, &sEncCtrl, res_pitch, x_frame );\r
111 TOC(FIND_PITCH)\r
112 \r
113     /************************/\r
114     /* Noise shape analysis */\r
115     /************************/\r
116 TIC(NOISE_SHAPE_ANALYSIS)\r
117     SKP_Silk_noise_shape_analysis_FIX( psEnc, &sEncCtrl, res_pitch_frame, x_frame );\r
118 TOC(NOISE_SHAPE_ANALYSIS)\r
119 \r
120     /*****************************************/\r
121     /* Prefiltering for noise shaper         */\r
122     /*****************************************/\r
123 TIC(PREFILTER)\r
124     SKP_Silk_prefilter_FIX( psEnc, &sEncCtrl, xfw, x_frame );\r
125 TOC(PREFILTER)\r
126 \r
127     /***************************************************/\r
128     /* Find linear prediction coefficients (LPC + LTP) */\r
129     /***************************************************/\r
130 TIC(FIND_PRED_COEF)\r
131     SKP_Silk_find_pred_coefs_FIX( psEnc, &sEncCtrl, res_pitch, x_frame );\r
132 TOC(FIND_PRED_COEF)\r
133 \r
134     /****************************************/\r
135     /* Process gains                        */\r
136     /****************************************/\r
137 TIC(PROCESS_GAINS)\r
138     SKP_Silk_process_gains_FIX( psEnc, &sEncCtrl );\r
139 TOC(PROCESS_GAINS)\r
140     \r
141     psEnc->sCmn.quantOffsetType[ psEnc->sCmn.nFramesInPayloadBuf ] = sEncCtrl.sCmn.quantOffsetType;\r
142     psEnc->sCmn.signalType[      psEnc->sCmn.nFramesInPayloadBuf ] = sEncCtrl.sCmn.signalType;\r
143 \r
144     /****************************************/\r
145     /* Low Bitrate Redundant Encoding       */\r
146     /****************************************/\r
147     psEnc->sCmn.LBRR_nBytes = MAX_ARITHM_BYTES;\r
148 TIC(LBRR)\r
149     //SKP_Silk_LBRR_encode_FIX( psEnc, &sEncCtrl, psEnc->sCmn.LBRR_payload, &psEnc->sCmn.LBRR_nBytes, xfw );\r
150 TOC(LBRR)\r
151 \r
152     /*****************************************/\r
153     /* Noise shaping quantization            */\r
154     /*****************************************/\r
155 TIC(NSQ)\r
156     if( psEnc->sCmn.nStatesDelayedDecision > 1 || psEnc->sCmn.warping_Q16 > 0 ) {\r
157         SKP_Silk_NSQ_del_dec( &psEnc->sCmn, &sEncCtrl.sCmn, &psEnc->sNSQ, xfw,\r
158             psEnc->sCmn.q, sEncCtrl.sCmn.NLSFInterpCoef_Q2, \r
159             sEncCtrl.PredCoef_Q12[ 0 ], sEncCtrl.LTPCoef_Q14, sEncCtrl.AR2_Q13, sEncCtrl.HarmShapeGain_Q14, \r
160             sEncCtrl.Tilt_Q14, sEncCtrl.LF_shp_Q14, sEncCtrl.Gains_Q16, sEncCtrl.Lambda_Q10, \r
161             sEncCtrl.LTP_scale_Q14 );\r
162     } else {\r
163         SKP_Silk_NSQ( &psEnc->sCmn, &sEncCtrl.sCmn, &psEnc->sNSQ, xfw, \r
164             psEnc->sCmn.q, sEncCtrl.sCmn.NLSFInterpCoef_Q2, \r
165             sEncCtrl.PredCoef_Q12[ 0 ], sEncCtrl.LTPCoef_Q14, sEncCtrl.AR2_Q13, sEncCtrl.HarmShapeGain_Q14, \r
166             sEncCtrl.Tilt_Q14, sEncCtrl.LF_shp_Q14, sEncCtrl.Gains_Q16, sEncCtrl.Lambda_Q10, \r
167             sEncCtrl.LTP_scale_Q14 );\r
168     }\r
169 TOC(NSQ)\r
170 \r
171     /****************************************/\r
172     /* Initialize range coder               */\r
173     /****************************************/\r
174     if( psEnc->sCmn.nFramesInPayloadBuf == 0 ) {\r
175         psEnc->sCmn.nBytesInPayloadBuf = 0;\r
176     }\r
177 \r
178     /****************************************/\r
179     /* Encode Parameters                    */\r
180     /****************************************/\r
181 TIC(ENCODE_PARAMS)\r
182     SKP_Silk_encode_indices( &psEnc->sCmn, &sEncCtrl.sCmn, psRangeEnc );\r
183 TOC(ENCODE_PARAMS)\r
184 \r
185     /****************************************/\r
186     /* Update Buffers and State             */\r
187     /****************************************/\r
188     /* Update input buffer */\r
189     SKP_memmove( psEnc->x_buf, &psEnc->x_buf[ psEnc->sCmn.frame_length ], \r
190         ( psEnc->sCmn.ltp_mem_length + LA_SHAPE_MS * psEnc->sCmn.fs_kHz ) * sizeof( SKP_int16 ) );\r
191     \r
192     /* Parameters needed for next frame */\r
193     psEnc->sCmn.prevLag                 = sEncCtrl.sCmn.pitchL[ psEnc->sCmn.nb_subfr - 1 ];\r
194     psEnc->sCmn.prevSignalType          = sEncCtrl.sCmn.signalType;\r
195     psEnc->sCmn.first_frame_after_reset = 0;\r
196     psEnc->sCmn.nFramesInPayloadBuf++;\r
197 \r
198     /****************************************/\r
199     /* Finalize payload and copy to output  */\r
200     /****************************************/\r
201     if( psEnc->sCmn.nFramesInPayloadBuf * SUB_FRAME_LENGTH_MS * psEnc->sCmn.nb_subfr >= psEnc->sCmn.PacketSize_ms ) {\r
202 \r
203         /* Check if FEC information should be added */\r
204         //frame_terminator = psEnc->sCmn.usage;\r
205         frame_terminator = SKP_SILK_NO_LBRR;\r
206 \r
207         /* Add the frame termination info to stream */\r
208         ec_enc_icdf( psRangeEnc, frame_terminator, SKP_Silk_LBRR_Present_iCDF, 8 );\r
209 \r
210         /* Code excitation signal */\r
211         for( i = 0; i < psEnc->sCmn.nFramesInPayloadBuf; i++ ) {\r
212             SKP_Silk_encode_pulses( psRangeEnc, psEnc->sCmn.signalType[ i ], psEnc->sCmn.quantOffsetType[ i ], \r
213                 &psEnc->sCmn.q[ i * psEnc->sCmn.frame_length ], psEnc->sCmn.frame_length );\r
214         }\r
215 \r
216         /* Payload length so far */\r
217         nBytes = SKP_RSHIFT( ec_tell( psRangeEnc ) + 7, 3 );\r
218         *pnBytesOut = nBytes;\r
219 \r
220         /* Reset the number of frames in payload buffer */\r
221         psEnc->sCmn.nFramesInPayloadBuf = 0;\r
222     } else {\r
223         /* No payload this time */\r
224         *pnBytesOut = 0;\r
225 \r
226         /* Payload length so far */\r
227         nBytes = SKP_RSHIFT( ec_tell( psRangeEnc ) + 7, 3 );\r
228 \r
229         /* Take into account the q signal that isn't in the bitstream yet */\r
230         nBytes += SKP_Silk_pulses_to_bytes( &psEnc->sCmn, \r
231             &psEnc->sCmn.q[ psEnc->sCmn.nFramesInPayloadBuf * psEnc->sCmn.frame_length ] );\r
232     }\r
233 \r
234     /* Simulate number of ms buffered in channel because of exceeding TargetRate */\r
235     SKP_assert(  ( 8 * 1000 * ( (SKP_int64)nBytes - (SKP_int64)psEnc->sCmn.nBytesInPayloadBuf ) ) == \r
236         SKP_SAT32( 8 * 1000 * ( (SKP_int64)nBytes - (SKP_int64)psEnc->sCmn.nBytesInPayloadBuf ) ) );\r
237     SKP_assert( psEnc->sCmn.TargetRate_bps > 0 );\r
238     psEnc->BufferedInChannel_ms   += SKP_DIV32( 8 * 1000 * ( nBytes - psEnc->sCmn.nBytesInPayloadBuf ), psEnc->sCmn.TargetRate_bps );\r
239     psEnc->BufferedInChannel_ms   -= SKP_SMULBB( SUB_FRAME_LENGTH_MS, psEnc->sCmn.nb_subfr );\r
240     psEnc->BufferedInChannel_ms    = SKP_LIMIT_int( psEnc->BufferedInChannel_ms, 0, 100 );\r
241     psEnc->sCmn.nBytesInPayloadBuf = nBytes;\r
242 \r
243 TOC(ENCODE_FRAME)\r
244 \r
245 #ifdef SAVE_ALL_INTERNAL_DATA\r
246     {\r
247         SKP_float tmp[ MAX_NB_SUBFR * LTP_ORDER ];\r
248         int i;\r
249         DEBUG_STORE_DATA( xf.dat,                   x_frame + LA_SHAPE_MS * psEnc->sCmn.fs_kHz, psEnc->sCmn.frame_length    * sizeof( SKP_int16 ) );\r
250         DEBUG_STORE_DATA( xfw.dat,                  xfw,                            psEnc->sCmn.frame_length    * sizeof( SKP_int16 ) );\r
251         DEBUG_STORE_DATA( pitchL.dat,               sEncCtrl.sCmn.pitchL,           psEnc->sCmn.nb_subfr            * sizeof( SKP_int ) );\r
252         for( i = 0; i < psEnc->sCmn.nb_subfr * LTP_ORDER; i++ ) {\r
253             tmp[ i ] = (SKP_float)sEncCtrl.LTPCoef_Q14[ i ] / 16384.0f;\r
254         }\r
255         DEBUG_STORE_DATA( pitchG_quantized.dat,     tmp,                            psEnc->sCmn.nb_subfr * LTP_ORDER * sizeof( SKP_float ) );\r
256         for( i = 0; i <psEnc->sCmn.predictLPCOrder; i++ ) {\r
257             tmp[ i ] = (SKP_float)sEncCtrl.PredCoef_Q12[ 1 ][ i ] / 4096.0f;\r
258         }\r
259         DEBUG_STORE_DATA( PredCoef.dat,             tmp,                            psEnc->sCmn.predictLPCOrder * sizeof( SKP_float ) );\r
260         \r
261         tmp[ 0 ] = (SKP_float)sEncCtrl.pitch_freq_low_Hz;\r
262         DEBUG_STORE_DATA( pitch_freq_low_Hz.dat,    tmp,                            sizeof( SKP_float ) );\r
263         tmp[ 0 ] = (SKP_float)sEncCtrl.LTPredCodGain_Q7 / 128.0f;\r
264         DEBUG_STORE_DATA( LTPredCodGain.dat,        tmp,                            sizeof( SKP_float ) );\r
265         tmp[ 0 ] = (SKP_float)psEnc->LTPCorr_Q15 / 32768.0f;\r
266         DEBUG_STORE_DATA( LTPcorr.dat,              tmp,                            sizeof( SKP_float ) );\r
267         tmp[ 0 ] = (SKP_float)sEncCtrl.input_tilt_Q15 / 32768.0f;\r
268         DEBUG_STORE_DATA( tilt.dat,                 tmp,                            sizeof( SKP_float ) );\r
269         for( i = 0; i < psEnc->sCmn.nb_subfr; i++ ) {\r
270             tmp[ i ] = (SKP_float)sEncCtrl.Gains_Q16[ i ] / 65536.0f;\r
271         }\r
272         DEBUG_STORE_DATA( gains.dat,                tmp,                            psEnc->sCmn.nb_subfr * sizeof( SKP_float ) );\r
273         DEBUG_STORE_DATA( gains_indices.dat,        &sEncCtrl.sCmn.GainsIndices,    psEnc->sCmn.nb_subfr * sizeof( SKP_int ) );\r
274         DEBUG_STORE_DATA( nBytes.dat,               &nBytes,                        sizeof( SKP_int ) );\r
275         tmp[ 0 ] = (SKP_float)sEncCtrl.current_SNR_dB_Q7 / 128.0f;\r
276         DEBUG_STORE_DATA( current_SNR_db.dat,       tmp,                            sizeof( SKP_float ) );\r
277         DEBUG_STORE_DATA( quantOffsetType.dat,      &sEncCtrl.sCmn.quantOffsetType, sizeof( SKP_int ) );\r
278         tmp[ 0 ] = (SKP_float)psEnc->speech_activity_Q8 / 256.0f;\r
279         DEBUG_STORE_DATA( speech_activity.dat,      tmp,                            sizeof( SKP_float ) );\r
280         for( i = 0; i < VAD_N_BANDS; i++ ) {\r
281             tmp[ i ] = (SKP_float)sEncCtrl.input_quality_bands_Q15[ i ] / 32768.0f;\r
282         }\r
283         DEBUG_STORE_DATA( input_quality_bands.dat,  tmp,                            VAD_N_BANDS * sizeof( SKP_float ) );\r
284         DEBUG_STORE_DATA( signalType.dat,           &sEncCtrl.sCmn.signalType,      sizeof( SKP_int ) ); \r
285         DEBUG_STORE_DATA( ratelevel.dat,            &sEncCtrl.sCmn.RateLevelIndex,  sizeof( SKP_int ) ); \r
286         DEBUG_STORE_DATA( lag_index.dat,            &sEncCtrl.sCmn.lagIndex,        sizeof( SKP_int ) ); \r
287         DEBUG_STORE_DATA( contour_index.dat,        &sEncCtrl.sCmn.contourIndex,    sizeof( SKP_int ) ); \r
288         DEBUG_STORE_DATA( per_index.dat,            &sEncCtrl.sCmn.PERIndex,        sizeof( SKP_int ) ); \r
289     }\r
290 #endif\r
291     return( ret );\r
292 }\r
293 \r
294 #if 0  //tmp\r
295 /* Low BitRate Redundancy encoding functionality. Reuse all parameters but encode residual with lower bitrate */\r
296 void SKP_Silk_LBRR_encode_FIX(\r
297     SKP_Silk_encoder_state_FIX      *psEnc,         /* I/O  Pointer to Silk encoder state           */\r
298     SKP_Silk_encoder_control_FIX    *psEncCtrl,     /* I/O  Pointer to Silk encoder control struct  */\r
299     SKP_uint8                       *pCode,         /* O    Pointer to payload                      */\r
300     SKP_int16                       *pnBytesOut,    /* I/O  Pointer to number of payload bytes      */\r
301     SKP_int16                       xfw[]           /* I    Input signal                            */\r
302 )\r
303 {\r
304     SKP_int     i, TempGainsIndices[ MAX_NB_SUBFR ], frame_terminator;\r
305     SKP_int     nBytes, nFramesInPayloadBuf;\r
306     SKP_int32   TempGains_Q16[ MAX_NB_SUBFR ];\r
307     SKP_int     typeOffset, LTP_scaleIndex, Rate_only_parameters = 0;\r
308 \r
309     /*******************************************/\r
310     /* Control use of inband LBRR              */\r
311     /*******************************************/\r
312     psEnc->sCmn.LBRR_usage = SKP_SILK_NO_LBRR;\r
313     if( psEnc->sCmn.LBRR_enabled ) {\r
314         /* Control LBRR */\r
315         /* Usage Control based on sensitivity and packet loss caracteristics */\r
316         if( psEnc->speech_activity_Q8 > SKP_FIX_CONST( LBRR_SPEECH_ACTIVITY_THRES, 8 ) && psEnc->sCmn.PacketLoss_perc > LBRR_LOSS_THRES ) {\r
317             psEnc->sCmn.LBRR_usage = SKP_SILK_LBRR;\r
318         }\r
319     }\r
320 \r
321     if( psEnc->sCmn.LBRR_enabled ) {\r
322         /* Save original gains */\r
323         SKP_memcpy( TempGainsIndices, psEncCtrl->sCmn.GainsIndices, MAX_NB_SUBFR * sizeof( SKP_int   ) );\r
324         SKP_memcpy( TempGains_Q16,    psEncCtrl->Gains_Q16,         MAX_NB_SUBFR * sizeof( SKP_int32 ) );\r
325 \r
326         typeOffset     = psEnc->sCmn.typeOffsetPrev; // Temp save as cannot be overwritten\r
327         LTP_scaleIndex = psEncCtrl->sCmn.LTP_scaleIndex;\r
328 \r
329         /* Set max rate where quant signal is encoded */\r
330         if( psEnc->sCmn.fs_kHz == 8 ) {\r
331             Rate_only_parameters = 13500;\r
332         } else if( psEnc->sCmn.fs_kHz == 12 ) {\r
333             Rate_only_parameters = 15500;\r
334         } else if( psEnc->sCmn.fs_kHz == 16 ) {\r
335             Rate_only_parameters = 17500;\r
336         } else {\r
337             SKP_assert( 0 );\r
338         }\r
339 \r
340         if( psEnc->sCmn.Complexity >= 4 && psEnc->sCmn.TargetRate_bps > Rate_only_parameters ) {\r
341             if( psEnc->sCmn.nFramesInPayloadBuf == 0 ) {\r
342                 /* First frame in packet; copy everything */\r
343                 SKP_memcpy( &psEnc->sNSQ_LBRR, &psEnc->sNSQ, sizeof( SKP_Silk_nsq_state ) );\r
344 \r
345                 psEnc->sCmn.LBRRprevLastGainIndex = psEnc->sShape.LastGainIndex;\r
346                 /* Increase Gains to get target LBRR rate */\r
347                 psEncCtrl->sCmn.GainsIndices[ 0 ] = psEncCtrl->sCmn.GainsIndices[ 0 ] + psEnc->sCmn.LBRR_GainIncreases;\r
348                 psEncCtrl->sCmn.GainsIndices[ 0 ] = SKP_LIMIT_int( psEncCtrl->sCmn.GainsIndices[ 0 ], 0, N_LEVELS_QGAIN - 1 );\r
349             }\r
350             /* Decode to get gains in sync with decoder         */\r
351             /* Overwrite unquantized gains with quantized gains */\r
352             SKP_Silk_gains_dequant( psEncCtrl->Gains_Q16, psEncCtrl->sCmn.GainsIndices, \r
353                 &psEnc->sCmn.LBRRprevLastGainIndex, psEnc->sCmn.nFramesInPayloadBuf, psEnc->sCmn.nb_subfr );\r
354 \r
355             /*****************************************/\r
356             /* Noise shaping quantization            */\r
357             /*****************************************/\r
358             if( psEnc->sCmn.nStatesDelayedDecision > 1 || psEnc->sCmn.warping_Q16 > 0 ) {\r
359                 SKP_Silk_NSQ_del_dec( &psEnc->sCmn, &psEncCtrl->sCmn, &psEnc->sNSQ_LBRR, xfw, psEnc->sCmn.q_LBRR, \r
360                     psEncCtrl->sCmn.NLSFInterpCoef_Q2, psEncCtrl->PredCoef_Q12[ 0 ], psEncCtrl->LTPCoef_Q14, \r
361                     psEncCtrl->AR2_Q13, psEncCtrl->HarmShapeGain_Q14, psEncCtrl->Tilt_Q14, psEncCtrl->LF_shp_Q14, \r
362                     psEncCtrl->Gains_Q16, psEncCtrl->Lambda_Q10, psEncCtrl->LTP_scale_Q14 );\r
363             } else {\r
364                 SKP_Silk_NSQ( &psEnc->sCmn, &psEncCtrl->sCmn, &psEnc->sNSQ_LBRR, xfw, psEnc->sCmn.q_LBRR, \r
365                     psEncCtrl->sCmn.NLSFInterpCoef_Q2, psEncCtrl->PredCoef_Q12[ 0 ], psEncCtrl->LTPCoef_Q14, \r
366                     psEncCtrl->AR2_Q13, psEncCtrl->HarmShapeGain_Q14, psEncCtrl->Tilt_Q14, psEncCtrl->LF_shp_Q14, \r
367                     psEncCtrl->Gains_Q16, psEncCtrl->Lambda_Q10, psEncCtrl->LTP_scale_Q14 );\r
368             }\r
369         } else {\r
370             SKP_memset( psEnc->sCmn.q_LBRR, 0, psEnc->sCmn.frame_length * sizeof( SKP_int8 ) );\r
371             psEncCtrl->sCmn.LTP_scaleIndex = 0;\r
372         }\r
373         /****************************************/\r
374         /* Initialize arithmetic coder          */\r
375         /****************************************/\r
376         if( psEnc->sCmn.nFramesInPayloadBuf == 0 ) {\r
377             ec_enc_init( &psEnc->sCmn.sRC_LBRR.range_enc_celt_state, psEnc->sCmn.sRC_LBRR.buffer, MAX_ARITHM_BYTES );\r
378 \r
379             SKP_Silk_range_enc_init( &psEnc->sCmn.sRC_LBRR );\r
380             psEnc->sCmn.nBytesInPayloadBuf = 0;\r
381         }\r
382 \r
383         /****************************************/\r
384         /* Encode Parameters                    */\r
385         /****************************************/\r
386         SKP_Silk_encode_indices( &psEnc->sCmn, &psEncCtrl->sCmn, &psEnc->sCmn.sRC_LBRR );\r
387 \r
388         /****************************************/\r
389         /* Encode Parameters                    */\r
390         /****************************************/\r
391         if( psEnc->sCmn.sRC_LBRR.error ) {\r
392             /* Encoder returned error: clear payload buffer */\r
393             nFramesInPayloadBuf = 0;\r
394         } else {\r
395             nFramesInPayloadBuf = psEnc->sCmn.nFramesInPayloadBuf + 1;\r
396         }\r
397 \r
398         /****************************************/\r
399         /* Finalize payload and copy to output  */\r
400         /****************************************/\r
401         if( SKP_SMULBB( nFramesInPayloadBuf, SKP_SMULBB( SUB_FRAME_LENGTH_MS, psEnc->sCmn.nb_subfr ) ) >= psEnc->sCmn.PacketSize_ms ) {\r
402 \r
403             /* Check if FEC information should be added */\r
404             frame_terminator = SKP_SILK_LAST_FRAME;\r
405 \r
406             /* Add the frame termination info to stream */\r
407             ec_enc_icdf( psRangeEnc, frame_terminator, SKP_Silk_LBRR_Present_iCDF, 8 );\r
408 \r
409             /*********************************************/\r
410             /* Encode quantization indices of excitation */\r
411             /*********************************************/\r
412             for( i = 0; i < nFramesInPayloadBuf; i++ ) {\r
413                 SKP_Silk_encode_pulses( &psEnc->sCmn.sRC_LBRR, psEnc->sCmn.signalType[ i ], psEnc->sCmn.quantOffsetType[ i ],\r
414                     &psEnc->sCmn.q_LBRR[ i * psEnc->sCmn.frame_length ], psEnc->sCmn.frame_length );\r
415             }\r
416 \r
417             /* Payload length so far */\r
418             nBytes = SKP_RSHIFT( ec_tell( psRangeEnc_LBRR ) + 7, 3 );\r
419 \r
420             /* Check that there is enough space in external output buffer and move data */\r
421             if( *pnBytesOut >= nBytes ) {\r
422                 SKP_int bits_in_stream, mask;\r
423                 bits_in_stream = ec_tell( &psEnc->sCmn.sRC_LBRR.range_enc_celt_state );\r
424                 ec_enc_done( &psEnc->sCmn.sRC_LBRR.range_enc_celt_state );\r
425 \r
426                 /* Fill up any remaining bits in the last byte with 1s */\r
427                 if( bits_in_stream & 7 ) {\r
428                     mask = SKP_RSHIFT( 0xFF, bits_in_stream & 7 );\r
429                     if( nBytes - 1 < *pnBytesOut ) {\r
430                         psEnc->sCmn.sRC_LBRR.range_enc_celt_state.buf->buf[ nBytes - 1 ] |= mask;\r
431                     }\r
432                 }\r
433                 SKP_memcpy( pCode, psEnc->sCmn.sRC_LBRR.range_enc_celt_state.buf->buf, nBytes * sizeof( SKP_uint8 ) );\r
434 \r
435                 *pnBytesOut = nBytes;\r
436             } else {\r
437                 /* Not enough space: payload will be discarded */\r
438                 *pnBytesOut = 0;\r
439                 SKP_assert( 0 );\r
440             }\r
441         } else {\r
442             /* No payload this time */\r
443             *pnBytesOut = 0;\r
444 \r
445             /* Encode that more frames follows */\r
446             frame_terminator = SKP_SILK_MORE_FRAMES;\r
447             ec_enc_icdf( psRangeEnc, frame_terminator, SKP_Silk_LBRR_Present_iCDF, 8 );\r
448         }\r
449 \r
450         /* Restore original Gains */\r
451         SKP_memcpy( psEncCtrl->sCmn.GainsIndices, TempGainsIndices, psEnc->sCmn.nb_subfr * sizeof( SKP_int   ) );\r
452         SKP_memcpy( psEncCtrl->Gains_Q16,         TempGains_Q16,    psEnc->sCmn.nb_subfr * sizeof( SKP_int32 ) );\r
453     \r
454         /* Restore LTP scale index and typeoffset */\r
455         psEncCtrl->sCmn.LTP_scaleIndex = LTP_scaleIndex;\r
456         psEnc->sCmn.typeOffsetPrev     = typeOffset;\r
457     }\r
458 }\r
459 #endif\r