Initial Skype commit taken from FreeSwitch, which got it from the IETF draft.
[opus.git] / src / SKP_Silk_control_codec_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 /* Control encoder SNR */\r
31 SKP_int SKP_Silk_control_encoder_FIX( \r
32     SKP_Silk_encoder_state_FIX  *psEnc,             /* I/O  Pointer to Silk encoder state                   */\r
33     const SKP_int               API_fs_kHz,         /* I    External (API) sampling rate (kHz)              */\r
34     const SKP_int               PacketSize_ms,      /* I    Packet length (ms)                              */\r
35     SKP_int32                   TargetRate_bps,     /* I    Target max bitrate (bps) (used if SNR_dB == 0)  */\r
36     const SKP_int               PacketLoss_perc,    /* I    Packet loss rate (in percent)                   */\r
37     const SKP_int               INBandFec_enabled,  /* I    Enable (1) / disable (0) inband FEC             */\r
38     const SKP_int               DTX_enabled,        /* I    Enable / disable DTX                            */\r
39     const SKP_int               InputFramesize_ms,  /* I    Inputframe in ms                                */\r
40     const SKP_int               Complexity          /* I    Complexity (0->low; 1->medium; 2->high)         */\r
41 )\r
42 {\r
43     SKP_int32 LBRRRate_thres_bps;\r
44     SKP_int   k, fs_kHz, ret = 0;\r
45     SKP_int32 frac_Q6;\r
46     const SKP_int32 *rateTable;\r
47 \r
48     /* State machine for the SWB/WB switching */\r
49     fs_kHz = psEnc->sCmn.fs_kHz;\r
50     \r
51     /* Only switch during low speech activity, when no frames are sitting in the payload buffer */\r
52     if( API_fs_kHz == 8 || fs_kHz == 0 || API_fs_kHz < fs_kHz ) {\r
53         // Switching is not possible, encoder just initialized, or internal mode higher than external\r
54         fs_kHz = API_fs_kHz;\r
55     } else {\r
56 \r
57         /* Resample all valid data in x_buf. Resampling the last part gets rid of a click, 5ms after switching  */\r
58         /* this is because the same state is used when downsampling in API.c and is then up to date             */\r
59         /* the click immidiatly after switching is most of the time still there                                 */\r
60 \r
61         if( psEnc->sCmn.fs_kHz == 24 ) {\r
62             /* Accumulate the difference between the target rate and limit */\r
63             if( psEnc->sCmn.fs_kHz_changed == 0 ) {\r
64                 psEnc->sCmn.bitrateDiff += SKP_MUL( InputFramesize_ms, TargetRate_bps - SWB2WB_BITRATE_BPS_INITIAL );\r
65             } else {\r
66                 psEnc->sCmn.bitrateDiff += SKP_MUL( InputFramesize_ms, TargetRate_bps - SWB2WB_BITRATE_BPS );\r
67             }\r
68             psEnc->sCmn.bitrateDiff = SKP_min( psEnc->sCmn.bitrateDiff, 0 );\r
69 \r
70             /* Check if we should switch from 24 to 16 kHz */\r
71 #if SWITCH_TRANSITION_FILTERING\r
72             if( ( psEnc->sCmn.sLP.transition_frame_no == 0 ) && /* Transition phase not active */\r
73                 ( psEnc->sCmn.bitrateDiff <= -ACCUM_BITS_DIFF_THRESHOLD || psEnc->sCmn.sSWBdetect.WB_detected == 1 ) &&\r
74                 ( psEnc->speech_activity_Q8 < 128 && psEnc->sCmn.nFramesInPayloadBuf == 0 ) ) {\r
75                 psEnc->sCmn.sLP.transition_frame_no = 1; /* Begin transition phase */\r
76                 psEnc->sCmn.sLP.mode = 0; /* Switch down */\r
77             }\r
78 \r
79             if( ( psEnc->sCmn.sLP.transition_frame_no >= TRANSITION_FRAMES_DOWN ) && ( psEnc->sCmn.sLP.mode == 0 ) && /* Transition phase complete, ready to switch */\r
80 #else\r
81             if( ( psEnc->sCmn.bitrateDiff <= -ACCUM_BITS_DIFF_THRESHOLD || psEnc->sCmn.sSWBdetect.WB_detected == 1 ) &&\r
82 #endif\r
83                 ( psEnc->speech_activity_Q8 < 128 && psEnc->sCmn.nFramesInPayloadBuf == 0 ) ) {\r
84 \r
85                     SKP_int16 x_buf[    2 * MAX_FRAME_LENGTH + LA_SHAPE_MAX ]; \r
86                     SKP_int16 x_bufout[ 2 * MAX_FRAME_LENGTH + LA_SHAPE_MAX ];\r
87                     \r
88                     psEnc->sCmn.bitrateDiff = 0;\r
89                     fs_kHz = 16;\r
90 \r
91                     SKP_memcpy( x_buf, psEnc->x_buf, ( 2 * MAX_FRAME_LENGTH + LA_SHAPE_MAX ) * sizeof( SKP_int16 ) );\r
92 \r
93                     SKP_memset( psEnc->sCmn.resample24To16state, 0, sizeof( psEnc->sCmn.resample24To16state ) );\r
94                     \r
95 #if LOW_COMPLEXITY_ONLY\r
96                     {\r
97                         SKP_int16 scratch[ ( 2 * MAX_FRAME_LENGTH + LA_SHAPE_MAX ) + SigProc_Resample_2_3_coarse_NUM_FIR_COEFS - 1 ];\r
98                         SKP_Silk_resample_2_3_coarse( &x_bufout[ 0 ], psEnc->sCmn.resample24To16state, &x_buf[ 0 ], SKP_LSHIFT( psEnc->sCmn.frame_length, 1 ) + psEnc->sCmn.la_shape, (SKP_int16*)scratch );\r
99                     }\r
100 #else\r
101                     SKP_Silk_resample_2_3( &x_bufout[ 0 ], psEnc->sCmn.resample24To16state, &x_buf[ 0 ], SKP_LSHIFT( psEnc->sCmn.frame_length, 1 ) + psEnc->sCmn.la_shape );\r
102 #endif\r
103 \r
104                     /* set the first frame to zero, no performance difference was noticed though */\r
105                     SKP_memset( x_bufout, 0, 320 * sizeof( SKP_int16 ) );\r
106                     SKP_memcpy( psEnc->x_buf, x_bufout, ( 2 * MAX_FRAME_LENGTH + LA_SHAPE_MAX ) * sizeof( SKP_int16 ) );\r
107 \r
108 #if SWITCH_TRANSITION_FILTERING\r
109                     psEnc->sCmn.sLP.transition_frame_no = 0; /* Transition phase complete */\r
110 #endif\r
111             }\r
112         } else if( psEnc->sCmn.fs_kHz == 16 ) {\r
113 \r
114             /* Check if we should switch from 16 to 24 kHz */\r
115 #if SWITCH_TRANSITION_FILTERING\r
116             if( ( psEnc->sCmn.sLP.transition_frame_no == 0 ) && /* No transition phase running, ready to switch */\r
117 #else\r
118             if(\r
119 #endif\r
120                 ( API_fs_kHz > psEnc->sCmn.fs_kHz && TargetRate_bps >= WB2SWB_BITRATE_BPS && psEnc->sCmn.sSWBdetect.WB_detected == 0 ) && \r
121                 ( psEnc->speech_activity_Q8 < 128 && psEnc->sCmn.nFramesInPayloadBuf == 0 ) ) {\r
122 \r
123                 SKP_int16 x_buf[          2 * MAX_FRAME_LENGTH + LA_SHAPE_MAX ]; \r
124                 SKP_int16 x_bufout[ 3 * ( 2 * MAX_FRAME_LENGTH + LA_SHAPE_MAX ) / 2 ]; \r
125                 SKP_int32 resample16To24state[ 11 ];\r
126 \r
127                 psEnc->sCmn.bitrateDiff = 0;\r
128                 fs_kHz = 24;\r
129                 \r
130                 SKP_memcpy( x_buf, psEnc->x_buf, ( 2 * MAX_FRAME_LENGTH + LA_SHAPE_MAX ) * sizeof( SKP_int16 ) );\r
131 \r
132                 SKP_memset( resample16To24state, 0, sizeof(resample16To24state) );\r
133                 \r
134                 SKP_Silk_resample_3_2( &x_bufout[ 0 ], resample16To24state, &x_buf[ 0 ], SKP_LSHIFT( psEnc->sCmn.frame_length, 1 ) + psEnc->sCmn.la_shape );\r
135 \r
136                 /* set the first frame to zero, no performance difference was noticed though */\r
137                 SKP_memset( x_bufout, 0, 480 * sizeof( SKP_int16 ) );\r
138                 SKP_memcpy( psEnc->x_buf, x_bufout, ( 2 * MAX_FRAME_LENGTH + LA_SHAPE_MAX ) * sizeof( SKP_int16 ) );\r
139 #if SWITCH_TRANSITION_FILTERING\r
140                 psEnc->sCmn.sLP.mode = 1; /* Switch up */\r
141 #endif\r
142             } else { \r
143                 /* accumulate the difference between the target rate and limit */\r
144                 psEnc->sCmn.bitrateDiff += SKP_MUL( InputFramesize_ms, TargetRate_bps - WB2MB_BITRATE_BPS );\r
145                 psEnc->sCmn.bitrateDiff = SKP_min( psEnc->sCmn.bitrateDiff, 0 );\r
146 \r
147                 /* Check if we should switch from 16 to 12 kHz */\r
148 #if SWITCH_TRANSITION_FILTERING\r
149                 if( ( psEnc->sCmn.sLP.transition_frame_no == 0 ) && /* Transition phase not active */\r
150                     ( psEnc->sCmn.bitrateDiff <= -ACCUM_BITS_DIFF_THRESHOLD ) &&\r
151                     ( psEnc->speech_activity_Q8 < 128 && psEnc->sCmn.nFramesInPayloadBuf == 0 ) ) {\r
152                     psEnc->sCmn.sLP.transition_frame_no = 1; /* Begin transition phase */\r
153                     psEnc->sCmn.sLP.mode = 0; /* Switch down */\r
154                 }\r
155 \r
156                 if( ( psEnc->sCmn.sLP.transition_frame_no >= TRANSITION_FRAMES_DOWN ) && ( psEnc->sCmn.sLP.mode == 0 ) && /* Transition phase complete, ready to switch */\r
157 #else\r
158                 if( ( psEnc->sCmn.bitrateDiff <= -ACCUM_BITS_DIFF_THRESHOLD ) &&\r
159 #endif\r
160                     ( psEnc->speech_activity_Q8 < 128 && psEnc->sCmn.nFramesInPayloadBuf == 0 ) ) {\r
161 \r
162                     SKP_int16 x_buf[ 2 * MAX_FRAME_LENGTH + LA_SHAPE_MAX ]; \r
163 \r
164                     SKP_memcpy( x_buf, psEnc->x_buf, ( 2 * MAX_FRAME_LENGTH + LA_SHAPE_MAX ) * sizeof( SKP_int16 ) );\r
165     \r
166                     psEnc->sCmn.bitrateDiff = 0;\r
167                     fs_kHz = 12;\r
168                     \r
169                     if( API_fs_kHz == 24 ) {\r
170 \r
171                         /* Intermediate upsampling of x_bufFIX from 16 to 24 kHz */\r
172                         SKP_int16 x_buf24[ 3 * ( 2 * MAX_FRAME_LENGTH + LA_SHAPE_MAX ) / 2 ]; \r
173                         SKP_int32 scratch[    3 * ( 2 * MAX_FRAME_LENGTH + LA_SHAPE_MAX ) ];\r
174                         SKP_int32 resample16To24state[ 11 ];\r
175 \r
176                         SKP_memset( resample16To24state, 0, sizeof( resample16To24state ) );\r
177                         SKP_Silk_resample_3_2( &x_buf24[ 0 ], resample16To24state, &x_buf[ 0 ], SKP_LSHIFT( psEnc->sCmn.frame_length, 1 ) + psEnc->sCmn.la_shape );\r
178 \r
179                         /* Update the state of the resampler used in API.c, from 24 to 12 kHz */\r
180                         SKP_memset( psEnc->sCmn.resample24To12state, 0, sizeof( psEnc->sCmn.resample24To12state ) );\r
181                         SKP_Silk_resample_1_2_coarse( &x_buf24[ 0 ], psEnc->sCmn.resample24To12state, &x_buf[ 0 ], scratch, SKP_RSHIFT( SKP_SMULBB( 3, SKP_LSHIFT( psEnc->sCmn.frame_length, 1 ) + psEnc->sCmn.la_shape ), 2 ) );\r
182 \r
183                         /* set the first frame to zero, no performance difference was noticed though */\r
184                         SKP_memset( x_buf, 0, 240 * sizeof( SKP_int16 ) );\r
185                         SKP_memcpy( psEnc->x_buf, x_buf, ( 2 * MAX_FRAME_LENGTH + LA_SHAPE_MAX ) * sizeof( SKP_int16 ) );\r
186 \r
187                     } else if( API_fs_kHz == 16 ) {\r
188                         SKP_int16 x_bufout[ 3 * ( 2 * MAX_FRAME_LENGTH + LA_SHAPE_MAX ) / 4 ]; \r
189                         SKP_memset( psEnc->sCmn.resample16To12state, 0, sizeof( psEnc->sCmn.resample16To12state ) );\r
190                         \r
191                         SKP_Silk_resample_3_4( &x_bufout[ 0 ], psEnc->sCmn.resample16To12state, &x_buf[ 0 ], SKP_LSHIFT( psEnc->sCmn.frame_length, 1 ) + psEnc->sCmn.la_shape );\r
192                     \r
193                         /* set the first frame to zero, no performance difference was noticed though */\r
194                         SKP_memset( x_bufout, 0, 240 * sizeof( SKP_int16 ) );\r
195                         SKP_memcpy( psEnc->x_buf, x_bufout, ( 2 * MAX_FRAME_LENGTH + LA_SHAPE_MAX ) * sizeof( SKP_int16 ) );\r
196                     }\r
197 #if SWITCH_TRANSITION_FILTERING\r
198                     psEnc->sCmn.sLP.transition_frame_no = 0; /* Transition phase complete */\r
199 #endif\r
200                 }\r
201             }\r
202         } else if( psEnc->sCmn.fs_kHz == 12 ) {\r
203         \r
204             /* Check if we should switch from 12 to 16 kHz */\r
205 #if SWITCH_TRANSITION_FILTERING\r
206             if( ( psEnc->sCmn.sLP.transition_frame_no == 0 ) && /* No transition phase running, ready to switch */\r
207 #else\r
208             if(\r
209 #endif\r
210                 ( API_fs_kHz > psEnc->sCmn.fs_kHz && TargetRate_bps >= MB2WB_BITRATE_BPS ) &&\r
211                 ( psEnc->speech_activity_Q8 < 128 && psEnc->sCmn.nFramesInPayloadBuf == 0 ) ) {\r
212 \r
213                 SKP_int16 x_buf[ 2 * MAX_FRAME_LENGTH + LA_SHAPE_MAX ]; \r
214 \r
215                 SKP_memcpy( x_buf, psEnc->x_buf, ( 2 * MAX_FRAME_LENGTH + LA_SHAPE_MAX ) * sizeof( SKP_int16 ) );\r
216 \r
217                 psEnc->sCmn.bitrateDiff = 0;\r
218                 fs_kHz = 16;\r
219 \r
220                 /* Reset state of the resampler to be used */\r
221                 if( API_fs_kHz == 24 ) {\r
222             \r
223                     SKP_int16 x_bufout[ 2 * 2 * ( 2 * MAX_FRAME_LENGTH + LA_SHAPE_MAX ) / 3 ]; \r
224 \r
225                     /* Intermediate upsampling of x_bufFIX from 12 to 24 kHz */\r
226                     SKP_int16 x_buf24[ 2 * ( 2 * MAX_FRAME_LENGTH + LA_SHAPE_MAX ) ]; \r
227                     SKP_int32 scratch[    3 * ( 2 * MAX_FRAME_LENGTH + LA_SHAPE_MAX ) ];\r
228                     SKP_int32 resample12To24state[6];\r
229 \r
230                     SKP_memset( resample12To24state, 0, sizeof( resample12To24state ) );\r
231                     SKP_Silk_resample_2_1_coarse( &x_buf[ 0 ], resample12To24state, &x_buf24[ 0 ], scratch, SKP_LSHIFT( psEnc->sCmn.frame_length, 1 ) + psEnc->sCmn.la_shape );\r
232 \r
233                     SKP_memset( psEnc->sCmn.resample24To16state, 0, sizeof( psEnc->sCmn.resample24To16state ) );\r
234                 \r
235 #if LOW_COMPLEXITY_ONLY\r
236                     SKP_assert( sizeof( SKP_int16 ) * ( 2 * ( 2 * MAX_FRAME_LENGTH + LA_SHAPE_MAX ) + SigProc_Resample_2_3_coarse_NUM_FIR_COEFS - 1 ) <= sizeof( scratch ) );\r
237                     SKP_Silk_resample_2_3_coarse( &x_bufout[ 0 ], psEnc->sCmn.resample24To16state, &x_buf24[ 0 ], SKP_LSHIFT( SKP_LSHIFT( psEnc->sCmn.frame_length, 1 ) + psEnc->sCmn.la_shape, 1 ), (SKP_int16*)scratch );\r
238 #else\r
239                     SKP_Silk_resample_2_3( &x_bufout[ 0 ], psEnc->sCmn.resample24To16state, &x_buf24[ 0 ], SKP_LSHIFT( SKP_LSHIFT( psEnc->sCmn.frame_length, 1 ) + psEnc->sCmn.la_shape, 1 ) );\r
240 #endif\r
241                 \r
242                     /* set the first frame to zero, no performance difference was noticed though */\r
243                     SKP_memset( x_bufout, 0, 320 * sizeof( SKP_int16 ) );\r
244                     SKP_memcpy( psEnc->x_buf, x_bufout, ( 2 * MAX_FRAME_LENGTH + LA_SHAPE_MAX ) * sizeof( SKP_int16 ) );\r
245                 }\r
246 #if SWITCH_TRANSITION_FILTERING\r
247                 psEnc->sCmn.sLP.mode = 1; /* Switch up */\r
248 #endif\r
249             } else { \r
250                 /* accumulate the difference between the target rate and limit */\r
251                 psEnc->sCmn.bitrateDiff += SKP_MUL( InputFramesize_ms, TargetRate_bps - MB2NB_BITRATE_BPS );\r
252                 psEnc->sCmn.bitrateDiff  = SKP_min( psEnc->sCmn.bitrateDiff, 0 );\r
253 \r
254                 /* Check if we should switch from 12 to 8 kHz */\r
255 #if SWITCH_TRANSITION_FILTERING\r
256                 if( ( psEnc->sCmn.sLP.transition_frame_no == 0 ) && /* Transition phase not active */\r
257                     ( psEnc->sCmn.bitrateDiff <= -ACCUM_BITS_DIFF_THRESHOLD ) &&\r
258                     ( psEnc->speech_activity_Q8 < 128 && psEnc->sCmn.nFramesInPayloadBuf == 0 ) ) {\r
259                     psEnc->sCmn.sLP.transition_frame_no = 1; /* Begin transition phase */\r
260                     psEnc->sCmn.sLP.mode = 0; /* Switch down */\r
261                 }\r
262 \r
263                 if( ( psEnc->sCmn.sLP.transition_frame_no >= TRANSITION_FRAMES_DOWN ) && ( psEnc->sCmn.sLP.mode == 0 ) &&\r
264 #else\r
265                 if( ( psEnc->sCmn.bitrateDiff <= -ACCUM_BITS_DIFF_THRESHOLD ) &&\r
266 #endif\r
267                     ( psEnc->speech_activity_Q8 < 128 && psEnc->sCmn.nFramesInPayloadBuf == 0 ) ) {\r
268                 \r
269                     SKP_int16 x_buf[ 2 * MAX_FRAME_LENGTH + LA_SHAPE_MAX ]; \r
270 \r
271                     SKP_memcpy( x_buf, psEnc->x_buf, ( 2 * MAX_FRAME_LENGTH + LA_SHAPE_MAX ) * sizeof( SKP_int16 ) );\r
272 \r
273                     psEnc->sCmn.bitrateDiff = 0;\r
274                     fs_kHz = 8;\r
275 \r
276                     if( API_fs_kHz == 24 ) {\r
277 \r
278                         SKP_int32 scratch[    3 * ( 2 * MAX_FRAME_LENGTH + LA_SHAPE_MAX ) ];\r
279                         /* Intermediate upsampling of x_buf from 12 to 24 kHz */\r
280                         SKP_int16 x_buf24[ 2 * ( 2 * MAX_FRAME_LENGTH + LA_SHAPE_MAX ) ];\r
281                         SKP_int32 resample12To24state[ 6 ];\r
282 \r
283                         SKP_memset( resample12To24state, 0, sizeof( resample12To24state ) );\r
284                         SKP_Silk_resample_2_1_coarse( &x_buf[ 0 ], resample12To24state, &x_buf24[ 0 ], scratch, SKP_LSHIFT( psEnc->sCmn.frame_length, 1 ) + psEnc->sCmn.la_shape );\r
285 \r
286                         /* Update the state of the resampler used in API.c, from 24 to 8 kHz */\r
287                         SKP_memset( psEnc->sCmn.resample24To8state, 0, sizeof( psEnc->sCmn.resample24To8state ) );\r
288                         SKP_Silk_resample_1_3( &x_buf[ 0 ], psEnc->sCmn.resample24To8state, &x_buf24[ 0 ], SKP_LSHIFT( SKP_LSHIFT( psEnc->sCmn.frame_length, 1 ) + psEnc->sCmn.la_shape, 1 ) );\r
289 \r
290                         /* set the first frame to zero, no performance difference was noticed though */\r
291                         SKP_memset( x_buf, 0, 160 * sizeof( SKP_int16 ) );\r
292                         SKP_memcpy( psEnc->x_buf, x_buf, ( 2 * MAX_FRAME_LENGTH + LA_SHAPE_MAX ) * sizeof( SKP_int16 ) );\r
293 \r
294                     } else if( API_fs_kHz == 16 ) {\r
295                         /* Intermediate upsampling of x_bufFIX from 12 to 16 kHz */\r
296                         SKP_int16 x_buf16[  3 * ( 2 * MAX_FRAME_LENGTH + LA_SHAPE_MAX ) / 2 ]; \r
297                         SKP_int32 resample12To16state[11];\r
298                         \r
299                         SKP_memset( resample12To16state, 0, sizeof( resample12To16state ) );\r
300                         SKP_Silk_resample_3_2( &x_buf16[ 0 ], resample12To16state, &x_buf[ 0 ], SKP_LSHIFT( psEnc->sCmn.frame_length, 1 ) + psEnc->sCmn.la_shape );\r
301                         \r
302                         /* set the first frame to zero, no performance difference was noticed though */\r
303                         SKP_memset( x_buf, 0, 160 * sizeof( SKP_int16 ) );\r
304                         SKP_memcpy( psEnc->x_buf, x_buf, ( 2 * MAX_FRAME_LENGTH + LA_SHAPE_MAX ) * sizeof( SKP_int16 ) );\r
305 \r
306                     } else if( API_fs_kHz == 12 ) {\r
307                         SKP_int16 x_bufout[ 2 * ( 2 * MAX_FRAME_LENGTH + LA_SHAPE_MAX ) / 3 ]; \r
308                         SKP_memset( psEnc->sCmn.resample12To8state, 0, sizeof( psEnc->sCmn.resample12To8state ) );\r
309 #if LOW_COMPLEXITY_ONLY\r
310                         {\r
311                             SKP_int16 scratch[ ( 2 * MAX_FRAME_LENGTH + LA_SHAPE_MAX ) + SigProc_Resample_2_3_coarse_NUM_FIR_COEFS - 1 ];\r
312                             SKP_Silk_resample_2_3_coarse( &x_bufout[ 0 ], psEnc->sCmn.resample12To8state, &x_buf[ 0 ], \r
313                                 SKP_LSHIFT( psEnc->sCmn.frame_length, 1 ) + psEnc->sCmn.la_shape, scratch );\r
314                         }\r
315 #else\r
316                         SKP_Silk_resample_2_3( &x_bufout[ 0 ], psEnc->sCmn.resample12To8state, &x_buf[ 0 ], SKP_LSHIFT( psEnc->sCmn.frame_length, 1 ) + psEnc->sCmn.la_shape );\r
317 #endif\r
318                         /* set the first frame to zero, no performance difference was noticed though */\r
319                         SKP_memset( x_bufout, 0, 160 * sizeof( SKP_int16 ) );\r
320                         SKP_memcpy( psEnc->x_buf, x_bufout, ( 2 * MAX_FRAME_LENGTH + LA_SHAPE_MAX ) * sizeof( SKP_int16 ) );\r
321                     }\r
322 #if SWITCH_TRANSITION_FILTERING\r
323                     psEnc->sCmn.sLP.transition_frame_no = 0; /* Transition phase complete */\r
324 #endif\r
325                 }\r
326             }\r
327         } else if( psEnc->sCmn.fs_kHz == 8 ) {\r
328 \r
329             /* Check if we should switch from 8 to 12 kHz */\r
330 #if SWITCH_TRANSITION_FILTERING\r
331             if( ( psEnc->sCmn.sLP.transition_frame_no == 0 ) && /* No transition phase running, ready to switch */\r
332 #else\r
333             if(\r
334 #endif\r
335                 ( API_fs_kHz > psEnc->sCmn.fs_kHz && TargetRate_bps >= NB2MB_BITRATE_BPS ) &&\r
336                 ( psEnc->speech_activity_Q8 < 128 && psEnc->sCmn.nFramesInPayloadBuf == 0 ) ) {\r
337 \r
338                 SKP_int16 x_buf[ 2 * MAX_FRAME_LENGTH + LA_SHAPE_MAX ]; \r
339 \r
340                 SKP_memcpy( x_buf, psEnc->x_buf, ( 2 * MAX_FRAME_LENGTH + LA_SHAPE_MAX ) * sizeof( SKP_int16 ) );\r
341 \r
342                 psEnc->sCmn.bitrateDiff = 0;\r
343                 fs_kHz = 12;\r
344 \r
345                 /* Reset state of the resampler to be used */\r
346                 if( API_fs_kHz == 24 ) {\r
347                     SKP_int16 x_buf24[  3 * ( 2 * MAX_FRAME_LENGTH + LA_SHAPE_MAX ) ]; \r
348                     SKP_int32 scratch[ 3 * 3 * ( 2 * MAX_FRAME_LENGTH + LA_SHAPE_MAX ) / 2 ];\r
349                     SKP_int32 resample8To24state[ 7 ];\r
350 \r
351                     /* Intermediate upsampling of x_bufFIX from 8 to 24 kHz */\r
352                     SKP_memset( resample8To24state, 0, sizeof( resample8To24state ) );\r
353                     SKP_Silk_resample_3_1( &x_buf24[ 0 ], resample8To24state, &x_buf[ 0 ], SKP_LSHIFT( psEnc->sCmn.frame_length, 1 ) + psEnc->sCmn.la_shape );\r
354 \r
355                     SKP_memset( psEnc->sCmn.resample24To12state, 0, sizeof( psEnc->sCmn.resample24To12state ) );\r
356                 \r
357                     SKP_Silk_resample_1_2_coarse( &x_buf24[ 0 ], psEnc->sCmn.resample24To12state, &x_buf[ 0 ], scratch, SKP_RSHIFT( SKP_SMULBB( 3, SKP_LSHIFT( psEnc->sCmn.frame_length, 1 ) + psEnc->sCmn.la_shape ), 1 ) );\r
358                 \r
359                     /* set the first frame to zero, no performance difference was noticed though */\r
360                     SKP_memset( x_buf, 0, 240 * sizeof( SKP_int16 ) );\r
361                     SKP_memcpy( psEnc->x_buf, x_buf, ( 2 * MAX_FRAME_LENGTH + LA_SHAPE_MAX ) * sizeof( SKP_int16 ) );\r
362                 \r
363                 } else if( API_fs_kHz == 16 ) {\r
364                     SKP_int16 x_buf16[ 2 * ( 2 * MAX_FRAME_LENGTH + LA_SHAPE_MAX ) ]; \r
365                     SKP_int32 scratch[ 3 * ( 2 * MAX_FRAME_LENGTH + LA_SHAPE_MAX ) ];\r
366                     SKP_int32 resample8To16state[ 6 ];\r
367 \r
368                     /* Intermediate upsampling of x_bufFIX from 8 to 16 kHz */\r
369                     SKP_memset( resample8To16state, 0, sizeof( resample8To16state ) );\r
370                     SKP_Silk_resample_2_1_coarse( &x_buf[ 0 ], resample8To16state, &x_buf16[ 0 ], scratch, SKP_LSHIFT( psEnc->sCmn.frame_length, 1 ) + psEnc->sCmn.la_shape );\r
371 \r
372                     SKP_memset( psEnc->sCmn.resample16To12state, 0, sizeof( psEnc->sCmn.resample16To12state ) );\r
373                 \r
374                     SKP_Silk_resample_3_4( &x_buf[ 0 ], psEnc->sCmn.resample16To12state, &x_buf16[ 0 ], SKP_LSHIFT( SKP_LSHIFT( psEnc->sCmn.frame_length, 1 ) + psEnc->sCmn.la_shape, 1 ) );\r
375                 \r
376                     /* set the first frame to zero, no performance difference was noticed though */\r
377                     SKP_memset( x_buf, 0, 240 * sizeof( SKP_int16 ) );\r
378                     SKP_memcpy( psEnc->x_buf, x_buf, ( 2 * MAX_FRAME_LENGTH + LA_SHAPE_MAX ) * sizeof( SKP_int16 ) );\r
379                 }\r
380 #if SWITCH_TRANSITION_FILTERING\r
381                 psEnc->sCmn.sLP.mode = 1; /* Switch up */\r
382 #endif\r
383             } \r
384         } else {\r
385             // Internal sample frequency not supported!\r
386             SKP_assert( 0 );\r
387         }\r
388     }\r
389 \r
390 #if SWITCH_TRANSITION_FILTERING\r
391     /* After switching up, stop transition filter during speech inactivity */\r
392     if( ( psEnc->sCmn.sLP.mode == 1 ) &&\r
393         ( psEnc->sCmn.sLP.transition_frame_no >= TRANSITION_FRAMES_UP ) && \r
394         ( psEnc->speech_activity_Q8 < 128 ) && \r
395         ( psEnc->sCmn.nFramesInPayloadBuf == 0 ) ) {\r
396         \r
397         psEnc->sCmn.sLP.transition_frame_no = 0;\r
398 \r
399         /* Reset transition filter state */\r
400         SKP_memset( psEnc->sCmn.sLP.In_LP_State, 0, 2 * sizeof( SKP_int32 ) );\r
401     }\r
402 #endif\r
403 \r
404 \r
405 \r
406     /* Set internal sampling frequency */\r
407     if( psEnc->sCmn.fs_kHz != fs_kHz ) {\r
408         /* reset part of the state */\r
409         SKP_memset( &psEnc->sShape,          0, sizeof( SKP_Silk_shape_state_FIX ) );\r
410         SKP_memset( &psEnc->sPrefilt,        0, sizeof( SKP_Silk_prefilter_state_FIX ) );\r
411         SKP_memset( &psEnc->sNSQ,            0, sizeof( SKP_Silk_nsq_state ) );\r
412         SKP_memset( &psEnc->sPred,           0, sizeof( SKP_Silk_predict_state_FIX ) );\r
413         SKP_memset( psEnc->sNSQ.xq,          0, ( 2 * MAX_FRAME_LENGTH ) * sizeof( SKP_int16 ) );\r
414         SKP_memset( psEnc->sNSQ_LBRR.xq,     0, ( 2 * MAX_FRAME_LENGTH ) * sizeof( SKP_int16 ) );\r
415         SKP_memset( psEnc->sCmn.LBRR_buffer, 0, MAX_LBRR_DELAY * sizeof( SKP_SILK_LBRR_struct ) );\r
416 #if SWITCH_TRANSITION_FILTERING\r
417         SKP_memset( psEnc->sCmn.sLP.In_LP_State, 0, 2 * sizeof( SKP_int32 ) );\r
418         if( psEnc->sCmn.sLP.mode == 1 ) {\r
419             /* Begin transition phase */\r
420             psEnc->sCmn.sLP.transition_frame_no = 1;\r
421         } else {\r
422             /* End transition phase */\r
423             psEnc->sCmn.sLP.transition_frame_no = 0;\r
424         }\r
425 #endif\r
426         psEnc->sCmn.inputBufIx          = 0;\r
427         psEnc->sCmn.nFramesInPayloadBuf = 0;\r
428         psEnc->sCmn.nBytesInPayloadBuf  = 0;\r
429         psEnc->sCmn.oldest_LBRR_idx     = 0;\r
430         psEnc->sCmn.TargetRate_bps      = 0; /* ensures that psEnc->SNR_dB is recomputed */\r
431 \r
432         SKP_memset( psEnc->sPred.prev_NLSFq_Q15, 0, MAX_LPC_ORDER * sizeof( SKP_int ) );\r
433 \r
434         /* Initialize non-zero parameters */\r
435         psEnc->sCmn.prevLag                 = 100;\r
436         psEnc->sCmn.prev_sigtype            = SIG_TYPE_UNVOICED;\r
437         psEnc->sCmn.first_frame_after_reset = 1;\r
438         psEnc->sPrefilt.lagPrev             = 100;\r
439         psEnc->sShape.LastGainIndex        = 1;\r
440         psEnc->sNSQ.lagPrev                = 100;\r
441         psEnc->sNSQ.prev_inv_gain_Q16      = 65536;\r
442         psEnc->sNSQ_LBRR.prev_inv_gain_Q16 = 65536;\r
443         psEnc->sCmn.fs_kHz = fs_kHz;\r
444         if( psEnc->sCmn.fs_kHz == 8 ) {\r
445             psEnc->sCmn.predictLPCOrder = MIN_LPC_ORDER;\r
446             psEnc->sCmn.psNLSF_CB[ 0 ]  = &SKP_Silk_NLSF_CB0_10;\r
447             psEnc->sCmn.psNLSF_CB[ 1 ]  = &SKP_Silk_NLSF_CB1_10;\r
448         } else {\r
449             psEnc->sCmn.predictLPCOrder = MAX_LPC_ORDER;\r
450             psEnc->sCmn.psNLSF_CB[ 0 ]  = &SKP_Silk_NLSF_CB0_16;\r
451             psEnc->sCmn.psNLSF_CB[ 1 ]  = &SKP_Silk_NLSF_CB1_16;\r
452         }\r
453         psEnc->sCmn.frame_length   = SKP_SMULBB( FRAME_LENGTH_MS, fs_kHz );\r
454         psEnc->sCmn.subfr_length   = SKP_DIV32_16( psEnc->sCmn.frame_length, NB_SUBFR );\r
455         psEnc->sCmn.la_pitch       = SKP_SMULBB( LA_PITCH_MS, fs_kHz );\r
456         psEnc->sCmn.la_shape       = SKP_SMULBB( LA_SHAPE_MS, fs_kHz );\r
457         psEnc->sPred.min_pitch_lag = SKP_SMULBB(  3, fs_kHz );\r
458         psEnc->sPred.max_pitch_lag = SKP_SMULBB( 18, fs_kHz );\r
459         psEnc->sPred.pitch_LPC_win_length = SKP_SMULBB( FIND_PITCH_LPC_WIN_MS, fs_kHz );\r
460         if( psEnc->sCmn.fs_kHz == 24 ) {\r
461             psEnc->mu_LTP_Q8 = MU_LTP_QUANT_SWB_Q8;\r
462         } else if( psEnc->sCmn.fs_kHz == 16 ) {\r
463             psEnc->mu_LTP_Q8 = MU_LTP_QUANT_WB_Q8;\r
464         } else if( psEnc->sCmn.fs_kHz == 12 ) {\r
465             psEnc->mu_LTP_Q8 = MU_LTP_QUANT_MB_Q8;\r
466         } else {\r
467             psEnc->mu_LTP_Q8 = MU_LTP_QUANT_NB_Q8;\r
468         }\r
469         psEnc->sCmn.fs_kHz_changed = 1;\r
470         \r
471         /* Check that settings are valid */\r
472         SKP_assert( ( psEnc->sCmn.subfr_length * NB_SUBFR ) == psEnc->sCmn.frame_length );\r
473     } \r
474    \r
475     /* Set encoding complexity */\r
476     if( Complexity == 0 || LOW_COMPLEXITY_ONLY ) {\r
477         /* Low complexity */\r
478         psEnc->sCmn.Complexity                  = 0;\r
479         psEnc->sCmn.pitchEstimationComplexity   = PITCH_EST_COMPLEXITY_LC_MODE;\r
480         psEnc->pitchEstimationThreshold_Q16     = FIND_PITCH_CORRELATION_THRESHOLD_Q16_LC_MODE;\r
481         psEnc->sCmn.pitchEstimationLPCOrder     = 8;\r
482         psEnc->sCmn.shapingLPCOrder             = 12;\r
483         psEnc->sCmn.nStatesDelayedDecision      = 1;\r
484         psEnc->NoiseShapingQuantizer            = SKP_Silk_NSQ;\r
485         psEnc->sCmn.useInterpolatedNLSFs        = 0;\r
486         psEnc->sCmn.LTPQuantLowComplexity       = 1;\r
487         psEnc->sCmn.NLSF_MSVQ_Survivors         = MAX_NLSF_MSVQ_SURVIVORS_LC_MODE;\r
488     } else if( Complexity == 1 ) {\r
489         /* Medium complexity */\r
490         psEnc->sCmn.Complexity                  = 1;\r
491         psEnc->sCmn.pitchEstimationComplexity   = PITCH_EST_COMPLEXITY_MC_MODE;\r
492         psEnc->pitchEstimationThreshold_Q16     = FIND_PITCH_CORRELATION_THRESHOLD_Q16_MC_MODE;\r
493         psEnc->sCmn.pitchEstimationLPCOrder     = 12;\r
494         psEnc->sCmn.shapingLPCOrder             = 16;\r
495         psEnc->sCmn.nStatesDelayedDecision      = 2;\r
496         psEnc->NoiseShapingQuantizer            = SKP_Silk_NSQ_del_dec;\r
497         psEnc->sCmn.useInterpolatedNLSFs        = 0;\r
498         psEnc->sCmn.LTPQuantLowComplexity       = 0;\r
499         psEnc->sCmn.NLSF_MSVQ_Survivors         = MAX_NLSF_MSVQ_SURVIVORS_MC_MODE;\r
500     } else if( Complexity == 2 ) {\r
501         /* High complexity */\r
502         psEnc->sCmn.Complexity                  = 2;\r
503         psEnc->sCmn.pitchEstimationComplexity   = PITCH_EST_COMPLEXITY_HC_MODE;\r
504         psEnc->pitchEstimationThreshold_Q16     = FIND_PITCH_CORRELATION_THRESHOLD_Q16_HC_MODE;\r
505         psEnc->sCmn.pitchEstimationLPCOrder     = 16;\r
506         psEnc->sCmn.shapingLPCOrder             = 16;\r
507         psEnc->sCmn.nStatesDelayedDecision      = 4;\r
508         psEnc->NoiseShapingQuantizer            = SKP_Silk_NSQ_del_dec;\r
509         psEnc->sCmn.useInterpolatedNLSFs        = 1;\r
510         psEnc->sCmn.LTPQuantLowComplexity       = 0;\r
511         psEnc->sCmn.NLSF_MSVQ_Survivors         = MAX_NLSF_MSVQ_SURVIVORS;\r
512     } else {\r
513         ret = SKP_SILK_ENC_WRONG_COMPLEXITY_SETTING;\r
514     }\r
515 \r
516     /* Dont have higher Pitch estimation LPC order than predict LPC order */\r
517     psEnc->sCmn.pitchEstimationLPCOrder = SKP_min_int( psEnc->sCmn.pitchEstimationLPCOrder, psEnc->sCmn.predictLPCOrder );\r
518 \r
519     SKP_assert( psEnc->sCmn.pitchEstimationLPCOrder <= FIND_PITCH_LPC_ORDER_MAX );\r
520     SKP_assert( psEnc->sCmn.shapingLPCOrder         <= SHAPE_LPC_ORDER_MAX );\r
521     SKP_assert( psEnc->sCmn.nStatesDelayedDecision  <= DEL_DEC_STATES_MAX );\r
522 \r
523     /* Set bitrate/coding quality */\r
524     TargetRate_bps = SKP_min( TargetRate_bps, 100000 );\r
525     if( psEnc->sCmn.fs_kHz == 8 ) {\r
526         TargetRate_bps = SKP_max( TargetRate_bps, MIN_TARGET_RATE_NB_BPS );\r
527     } else if( psEnc->sCmn.fs_kHz == 12 ) {\r
528         TargetRate_bps = SKP_max( TargetRate_bps, MIN_TARGET_RATE_MB_BPS );\r
529     } else if( psEnc->sCmn.fs_kHz == 16 ) {\r
530         TargetRate_bps = SKP_max( TargetRate_bps, MIN_TARGET_RATE_WB_BPS );\r
531     } else {\r
532         TargetRate_bps = SKP_max( TargetRate_bps, MIN_TARGET_RATE_SWB_BPS );\r
533     }\r
534     if( TargetRate_bps != psEnc->sCmn.TargetRate_bps ) {\r
535         psEnc->sCmn.TargetRate_bps = TargetRate_bps;\r
536 \r
537         /* if new TargetRate_bps, translate to SNR_dB value */\r
538         if( psEnc->sCmn.fs_kHz == 8 ) {\r
539             rateTable = TargetRate_table_NB;\r
540         } else if( psEnc->sCmn.fs_kHz == 12 ) {\r
541             rateTable = TargetRate_table_MB;\r
542         } else if( psEnc->sCmn.fs_kHz == 16 ) {\r
543             rateTable = TargetRate_table_WB;\r
544         } else {\r
545             rateTable = TargetRate_table_SWB;\r
546         }\r
547         for( k = 1; k < TARGET_RATE_TAB_SZ; k++ ) {\r
548             /* find bitrate interval in table and interpolate */\r
549             if( TargetRate_bps < rateTable[ k ] ) {\r
550                 frac_Q6 = SKP_DIV32( SKP_LSHIFT( TargetRate_bps - rateTable[ k - 1 ], 6 ), rateTable[ k ] - rateTable[ k - 1 ] );\r
551                 psEnc->SNR_dB_Q7 = SKP_LSHIFT( SNR_table_Q1[ k - 1 ], 6 ) + SKP_MUL( frac_Q6, SNR_table_Q1[ k ] - SNR_table_Q1[ k - 1 ] );\r
552                 break;\r
553             }\r
554         }\r
555     }\r
556 \r
557     /* Set packet size */\r
558     if( ( PacketSize_ms !=  20 ) && \r
559         ( PacketSize_ms !=  40 ) && \r
560         ( PacketSize_ms !=  60 ) && \r
561         ( PacketSize_ms !=  80 ) && \r
562         ( PacketSize_ms != 100 ) ) {\r
563         ret = SKP_SILK_ENC_PACKET_SIZE_NOT_SUPPORTED;\r
564     } else {\r
565         if( PacketSize_ms != psEnc->sCmn.PacketSize_ms ) {\r
566             psEnc->sCmn.PacketSize_ms = PacketSize_ms;\r
567 \r
568             /* Packet length changes. Reset LBRR buffer */\r
569             SKP_Silk_LBRR_reset( &psEnc->sCmn );\r
570         }\r
571     }\r
572 \r
573     /* Set packet loss rate measured by farend */\r
574     if( ( PacketLoss_perc < 0 ) || ( PacketLoss_perc > 100 ) ) {\r
575         ret = SKP_SILK_ENC_WRONG_LOSS_RATE;\r
576     }\r
577     psEnc->sCmn.PacketLoss_perc = PacketLoss_perc;\r
578 \r
579 #if USE_LBRR\r
580     if( INBandFec_enabled < 0 || INBandFec_enabled > 1 ) {\r
581         ret = SKP_SILK_ENC_WRONG_INBAND_FEC_SETTING;\r
582     }\r
583     \r
584     /* Only change settings if first frame in packet */\r
585     if( psEnc->sCmn.nFramesInPayloadBuf == 0 ) {\r
586         \r
587         psEnc->sCmn.LBRR_enabled = INBandFec_enabled;\r
588         if( psEnc->sCmn.fs_kHz == 8 ) {\r
589             LBRRRate_thres_bps = INBAND_FEC_MIN_RATE_BPS - 9000;\r
590         } else if( psEnc->sCmn.fs_kHz == 12 ) {\r
591             LBRRRate_thres_bps = INBAND_FEC_MIN_RATE_BPS - 6000;;\r
592         } else if( psEnc->sCmn.fs_kHz == 16 ) {\r
593             LBRRRate_thres_bps = INBAND_FEC_MIN_RATE_BPS - 3000;\r
594         } else {\r
595             LBRRRate_thres_bps = INBAND_FEC_MIN_RATE_BPS;\r
596         }\r
597 \r
598         if( psEnc->sCmn.TargetRate_bps >= LBRRRate_thres_bps ) {\r
599             /* Set gain increase / rate reduction for LBRR usage */\r
600             /* Coarse tuned with pesq for now. */\r
601             /* Linear regression coefs G = 8 - 0.5 * loss */\r
602             /* Meaning that at 16% loss main rate and redundant rate is the same, -> G = 0 */\r
603             psEnc->sCmn.LBRR_GainIncreases = SKP_max_int( 8 - SKP_RSHIFT( psEnc->sCmn.PacketLoss_perc, 1 ), 0 );\r
604 \r
605             /* Set main stream rate compensation */\r
606             if( psEnc->sCmn.LBRR_enabled && psEnc->sCmn.PacketLoss_perc > LBRR_LOSS_THRES ) {\r
607                 /* Tuned to give aprox same mean / weighted bitrate as no inband FEC */\r
608                 psEnc->inBandFEC_SNR_comp_Q8 = ( 6 << 8 ) - SKP_LSHIFT( psEnc->sCmn.LBRR_GainIncreases, 7 );\r
609             } else {\r
610                 psEnc->inBandFEC_SNR_comp_Q8 = 0;\r
611                 psEnc->sCmn.LBRR_enabled     = 0;\r
612             }\r
613         } else {\r
614             psEnc->inBandFEC_SNR_comp_Q8     = 0;\r
615             psEnc->sCmn.LBRR_enabled         = 0;\r
616         }\r
617     }\r
618 #else\r
619     psEnc->sCmn.LBRR_enabled = 0;\r
620 #endif\r
621 \r
622     /* Set DTX mode */\r
623     if( DTX_enabled < 0 || DTX_enabled > 1 ) {\r
624         ret = SKP_SILK_ENC_WRONG_DTX_SETTING;\r
625     }\r
626     psEnc->sCmn.useDTX = DTX_enabled;\r
627     \r
628     return ret;\r
629 }\r
630 \r
631 /* Control low bitrate redundancy usage */\r
632 void SKP_Silk_LBRR_ctrl_FIX(\r
633     SKP_Silk_encoder_state_FIX      *psEnc,     /* I/O  encoder state                               */\r
634     SKP_Silk_encoder_control_FIX    *psEncCtrl  /* I/O  encoder control                             */\r
635 )\r
636 {\r
637     SKP_int LBRR_usage;\r
638 \r
639     if( psEnc->sCmn.LBRR_enabled ) {\r
640         /* Control LBRR */\r
641 \r
642         /* Usage Control based on sensitivity and packet loss caracteristics */\r
643         /* For now only enable adding to next for active frames. Make more complex later */\r
644         LBRR_usage = SKP_SILK_NO_LBRR;\r
645         if( psEnc->speech_activity_Q8 > LBRR_SPEECH_ACTIVITY_THRES_Q8 && psEnc->sCmn.PacketLoss_perc > LBRR_LOSS_THRES ) { // nb! maybe multiply loss prob and speech activity \r
646             //if( psEnc->PacketLoss_burst > BURST_THRES )\r
647             //  psEncCtrl->LBRR_usage = SKP_SILK_ADD_LBRR_TO_PLUS2;\r
648             //} else {\r
649                 LBRR_usage = SKP_SILK_ADD_LBRR_TO_PLUS1;//SKP_SILK_NO_LBRR\r
650             //}\r
651         }\r
652         psEncCtrl->sCmn.LBRR_usage = LBRR_usage;\r
653     } else {\r
654         psEncCtrl->sCmn.LBRR_usage = SKP_SILK_NO_LBRR;\r
655     }\r
656 }\r