Update SILK code using the CELT range coder
[opus.git] / src_common / SKP_Silk_VAD.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 /*\r
29  * File Name:   SKP_Silk_VAD.c\r
30  * Description: Silk VAD.\r
31  */\r
32 \r
33 #include <stdlib.h>\r
34 #include "SKP_Silk_main.h"\r
35 \r
36 #define SKP_SILK_VAD_HANDLE_10MS_FRAMES     1\r
37 \r
38 /**********************************/\r
39 /* Initialization of the Silk VAD */\r
40 /**********************************/\r
41 SKP_int SKP_Silk_VAD_Init(                              /* O    Return value, 0 if success                  */ \r
42     SKP_Silk_VAD_state              *psSilk_VAD         /* I/O  Pointer to Silk VAD state                   */ \r
43 )\r
44 {\r
45     SKP_int b, ret = 0;\r
46 \r
47     /* reset state memory */\r
48     SKP_memset( psSilk_VAD, 0, sizeof( SKP_Silk_VAD_state ) );\r
49 \r
50     /* init noise levels */\r
51     /* Initialize array with approx pink noise levels (psd proportional to inverse of frequency) */\r
52     for( b = 0; b < VAD_N_BANDS; b++ ) {\r
53         psSilk_VAD->NoiseLevelBias[ b ] = SKP_max_32( SKP_DIV32_16( VAD_NOISE_LEVELS_BIAS, b + 1 ), 1 );\r
54     }\r
55 \r
56     /* Initialize state */\r
57     for( b = 0; b < VAD_N_BANDS; b++ ) {\r
58         psSilk_VAD->NL[ b ]     = SKP_MUL( 100, psSilk_VAD->NoiseLevelBias[ b ] );\r
59         psSilk_VAD->inv_NL[ b ] = SKP_DIV32( SKP_int32_MAX, psSilk_VAD->NL[ b ] );\r
60     }\r
61     psSilk_VAD->counter = 15;\r
62 \r
63     /* init smoothed energy-to-noise ratio*/\r
64     for( b = 0; b < VAD_N_BANDS; b++ ) {\r
65         psSilk_VAD->NrgRatioSmth_Q8[ b ] = 100 * 256;       /* 100 * 256 --> 20 dB SNR */\r
66     }\r
67 \r
68     return( ret );\r
69 }\r
70 \r
71 /* Weighting factors for tilt measure */\r
72 const static SKP_int32 tiltWeights[ VAD_N_BANDS ] = { 30000, 6000, -12000, -12000 };\r
73 \r
74 /***************************************/\r
75 /* Get the speech activity level in Q8 */\r
76 /***************************************/\r
77 SKP_int SKP_Silk_VAD_GetSA_Q8(                                  /* O    Return value, 0 if success      */\r
78     SKP_Silk_VAD_state          *psSilk_VAD,                    /* I/O  Silk VAD state                  */\r
79     SKP_int                     *pSA_Q8,                        /* O    Speech activity level in Q8     */\r
80     SKP_int                     pQuality_Q15[ VAD_N_BANDS ],    /* O    Smoothed SNR for each band      */\r
81     SKP_int                     *pTilt_Q15,                     /* O    current frame's frequency tilt  */\r
82     const SKP_int16             pIn[],                          /* I    PCM input       [framelength]   */\r
83     const SKP_int               framelength,                    /* I    Input frame length              */\r
84     const SKP_int               fs_kHz                          /* I    Input frame sample frequency    */\r
85 )\r
86 {\r
87     SKP_int   SA_Q15, input_tilt;\r
88     SKP_int32 scratch[ 3 * MAX_FRAME_LENGTH / 2 ];\r
89     SKP_int   decimated_framelength, dec_subframe_length, dec_subframe_offset, SNR_Q7, i, b, s;\r
90     SKP_int32 sumSquared, smooth_coef_Q16;\r
91     SKP_int16 HPstateTmp, SNR_dB_Q7;\r
92 \r
93     SKP_int16 X[ VAD_N_BANDS ][ MAX_FRAME_LENGTH / 2 ];\r
94     SKP_int32 Xnrg[ VAD_N_BANDS ];\r
95     SKP_int32 NrgToNoiseRatio_Q8[ VAD_N_BANDS ];\r
96     SKP_int32 speech_nrg, x_tmp;\r
97     SKP_int   ret = 0;\r
98     \r
99 #if SKP_SILK_VAD_HANDLE_10MS_FRAMES\r
100     SKP_int   normalizer;\r
101 #endif\r
102 \r
103     /* Safety checks */\r
104     SKP_assert( VAD_N_BANDS == 4 );\r
105     SKP_assert( MAX_FRAME_LENGTH >= framelength );\r
106     SKP_assert( framelength <= 512 );\r
107     SKP_assert( framelength == 8 * SKP_RSHIFT( framelength, 3 ) );\r
108 \r
109     /***********************/\r
110     /* Filter and Decimate */\r
111     /***********************/\r
112     /* 0-8 kHz to 0-4 kHz and 4-8 kHz */\r
113     SKP_Silk_ana_filt_bank_1( pIn,          &psSilk_VAD->AnaState[  0 ], &X[ 0 ][ 0 ], &X[ 3 ][ 0 ], &scratch[ 0 ], framelength );        \r
114     \r
115     /* 0-4 kHz to 0-2 kHz and 2-4 kHz */\r
116     SKP_Silk_ana_filt_bank_1( &X[ 0 ][ 0 ], &psSilk_VAD->AnaState1[ 0 ], &X[ 0 ][ 0 ], &X[ 2 ][ 0 ], &scratch[ 0 ], SKP_RSHIFT( framelength, 1 ) );\r
117     \r
118     /* 0-2 kHz to 0-1 kHz and 1-2 kHz */\r
119     SKP_Silk_ana_filt_bank_1( &X[ 0 ][ 0 ], &psSilk_VAD->AnaState2[ 0 ], &X[ 0 ][ 0 ], &X[ 1 ][ 0 ], &scratch[ 0 ], SKP_RSHIFT( framelength, 2 ) );\r
120 \r
121     /*********************************************/\r
122     /* HP filter on lowest band (differentiator) */\r
123     /*********************************************/\r
124     // y( n ) = 0.5 * x( n ) - 0.5 * x( n - 1 )\r
125     decimated_framelength = SKP_RSHIFT( framelength, 3 );\r
126     X[ 0 ][ decimated_framelength - 1 ] = SKP_RSHIFT( X[ 0 ][ decimated_framelength - 1 ], 1 );\r
127     HPstateTmp = X[ 0 ][ decimated_framelength - 1 ];\r
128     for( i = decimated_framelength - 1; i > 0; i-- ) {\r
129         X[ 0 ][ i - 1 ]  = SKP_RSHIFT( X[ 0 ][ i - 1 ], 1 );\r
130         X[ 0 ][ i ]     -= X[ 0 ][ i - 1 ];\r
131     }\r
132     X[ 0 ][ 0 ] -= psSilk_VAD->HPstate;\r
133     psSilk_VAD->HPstate = HPstateTmp;\r
134 \r
135     /*************************************/\r
136     /* Calculate the energy in each band */\r
137     /*************************************/\r
138     for( b = 0; b < VAD_N_BANDS; b++ ) {        \r
139         /* Find the decimated framelength in the non-uniformly divided bands */\r
140         decimated_framelength = SKP_RSHIFT( framelength, SKP_min_int( VAD_N_BANDS - b, VAD_N_BANDS - 1 ) );\r
141 \r
142         /* Split length into subframe lengths */\r
143         dec_subframe_length = SKP_RSHIFT( decimated_framelength, VAD_INTERNAL_SUBFRAMES_LOG2 );\r
144         dec_subframe_offset = 0;\r
145 \r
146         /* Compute energy per sub-frame */\r
147         /* initialize with summed energy of last subframe */\r
148         Xnrg[ b ] = psSilk_VAD->XnrgSubfr[ b ];\r
149         for( s = 0; s < VAD_INTERNAL_SUBFRAMES; s++ ) {\r
150             sumSquared = 0;\r
151             for( i = 0; i < dec_subframe_length; i++ ) {\r
152                 /* The energy will be less than dec_subframe_length * ( SKP_int16_MIN / 8 ) ^ 2.            */\r
153                 /* Therefore we can accumulate with no risk of overflow (unless dec_subframe_length > 128)  */\r
154                 x_tmp = SKP_RSHIFT( X[ b ][ i + dec_subframe_offset ], 3 );\r
155                 sumSquared = SKP_SMLABB( sumSquared, x_tmp, x_tmp );\r
156 \r
157                 /* Safety check */\r
158                 SKP_assert( sumSquared >= 0 );\r
159             }\r
160 \r
161             /* Add/saturate summed energy of current subframe */\r
162             if( s < VAD_INTERNAL_SUBFRAMES - 1 ) {\r
163                 Xnrg[ b ] = SKP_ADD_POS_SAT32( Xnrg[ b ], sumSquared );\r
164             } else {\r
165                 /* Look-ahead subframe */\r
166                 Xnrg[ b ] = SKP_ADD_POS_SAT32( Xnrg[ b ], SKP_RSHIFT( sumSquared, 1 ) );\r
167             }\r
168 \r
169             dec_subframe_offset += dec_subframe_length;\r
170         }\r
171         psSilk_VAD->XnrgSubfr[ b ] = sumSquared; \r
172     }\r
173 \r
174     /********************/\r
175     /* Noise estimation */\r
176     /********************/\r
177     SKP_Silk_VAD_GetNoiseLevels( &Xnrg[ 0 ], psSilk_VAD );\r
178 \r
179     /***********************************************/\r
180     /* Signal-plus-noise to noise ratio estimation */\r
181     /***********************************************/\r
182     sumSquared = 0;\r
183     input_tilt = 0;\r
184     for( b = 0; b < VAD_N_BANDS; b++ ) {\r
185         speech_nrg = Xnrg[ b ] - psSilk_VAD->NL[ b ];\r
186         if( speech_nrg > 0 ) {\r
187             /* Divide, with sufficient resolution */\r
188             if( ( Xnrg[ b ] & 0xFF800000 ) == 0 ) {\r
189                 NrgToNoiseRatio_Q8[ b ] = SKP_DIV32( SKP_LSHIFT( Xnrg[ b ], 8 ), psSilk_VAD->NL[ b ] + 1 );\r
190             } else {\r
191                 NrgToNoiseRatio_Q8[ b ] = SKP_DIV32( Xnrg[ b ], SKP_RSHIFT( psSilk_VAD->NL[ b ], 8 ) + 1 );\r
192             }\r
193 \r
194             /* Convert to log domain */\r
195             SNR_Q7 = SKP_Silk_lin2log( NrgToNoiseRatio_Q8[ b ] ) - 8 * 128;\r
196 \r
197             /* Sum-of-squares */\r
198             sumSquared = SKP_SMLABB( sumSquared, SNR_Q7, SNR_Q7 );          /* Q14 */\r
199 \r
200             /* Tilt measure */\r
201             if( speech_nrg < ( 1 << 20 ) ) {\r
202                 /* Scale down SNR value for small subband speech energies */\r
203                 SNR_Q7 = SKP_SMULWB( SKP_LSHIFT( SKP_Silk_SQRT_APPROX( speech_nrg ), 6 ), SNR_Q7 );\r
204             }\r
205             input_tilt = SKP_SMLAWB( input_tilt, tiltWeights[ b ], SNR_Q7 );\r
206         } else {\r
207             NrgToNoiseRatio_Q8[ b ] = 256;\r
208         }\r
209     }\r
210 \r
211     /* Mean-of-squares */\r
212     sumSquared = SKP_DIV32_16( sumSquared, VAD_N_BANDS ); /* Q14 */\r
213 \r
214     /* Root-mean-square approximation, scale to dBs, and write to output pointer */\r
215     SNR_dB_Q7 = ( SKP_int16 )( 3 * SKP_Silk_SQRT_APPROX( sumSquared ) ); /* Q7 */\r
216 \r
217     /*********************************/\r
218     /* Speech Probability Estimation */\r
219     /*********************************/\r
220     SA_Q15 = SKP_Silk_sigm_Q15( SKP_SMULWB( VAD_SNR_FACTOR_Q16, SNR_dB_Q7 ) - VAD_NEGATIVE_OFFSET_Q5 );\r
221 \r
222     /**************************/\r
223     /* Frequency Tilt Measure */\r
224     /**************************/\r
225     *pTilt_Q15 = SKP_LSHIFT( SKP_Silk_sigm_Q15( input_tilt ) - 16384, 1 );\r
226 \r
227     /**************************************************/\r
228     /* Scale the sigmoid output based on power levels */\r
229     /**************************************************/\r
230     speech_nrg = 0;\r
231     for( b = 0; b < VAD_N_BANDS; b++ ) {\r
232         /* Accumulate signal-without-noise energies, higher frequency bands have more weight */\r
233         speech_nrg += ( b + 1 ) * SKP_RSHIFT( Xnrg[ b ] - psSilk_VAD->NL[ b ], 4 );\r
234     }\r
235 \r
236     /* Power scaling */\r
237     if( speech_nrg <= 0 ) {\r
238         SA_Q15 = SKP_RSHIFT( SA_Q15, 1 ); \r
239     } else if( speech_nrg < 32768 ) {\r
240         \r
241 #if SKP_SILK_VAD_HANDLE_10MS_FRAMES\r
242         /* Energy normalization of frames shorter than 320 samples */\r
243         normalizer = 0;\r
244         while( SKP_LSHIFT( framelength, normalizer ) < 320 ) {\r
245             normalizer++;\r
246         }\r
247         speech_nrg = SKP_LSHIFT_SAT32( speech_nrg, 15 + normalizer );\r
248 #else\r
249         speech_nrg = SKP_LSHIFT_SAT32( speech_nrg, 15 );\r
250 #endif\r
251         /* square-root */\r
252         speech_nrg = SKP_Silk_SQRT_APPROX( speech_nrg );\r
253         SA_Q15 = SKP_SMULWB( 32768 + speech_nrg, SA_Q15 ); \r
254     }\r
255 \r
256     /* Copy the resulting speech activity in Q8 to *pSA_Q8 */\r
257     *pSA_Q8 = SKP_min_int( SKP_RSHIFT( SA_Q15, 7 ), SKP_uint8_MAX );\r
258 \r
259     /***********************************/\r
260     /* Energy Level and SNR estimation */\r
261     /***********************************/\r
262     /* Smoothing coefficient */\r
263     smooth_coef_Q16 = SKP_SMULWB( VAD_SNR_SMOOTH_COEF_Q18, SKP_SMULWB( SA_Q15, SA_Q15 ) );\r
264     \r
265 #if SKP_SILK_VAD_HANDLE_10MS_FRAMES\r
266     if( framelength == 10 * fs_kHz ) {\r
267         smooth_coef_Q16 >>= 1;\r
268     } else {\r
269        SKP_assert( framelength == 20 * fs_kHz );\r
270     }\r
271 #endif\r
272 \r
273     for( b = 0; b < VAD_N_BANDS; b++ ) {\r
274         /* compute smoothed energy-to-noise ratio per band */\r
275         psSilk_VAD->NrgRatioSmth_Q8[ b ] = SKP_SMLAWB( psSilk_VAD->NrgRatioSmth_Q8[ b ], \r
276             NrgToNoiseRatio_Q8[ b ] - psSilk_VAD->NrgRatioSmth_Q8[ b ], smooth_coef_Q16 );\r
277 \r
278         /* signal to noise ratio in dB per band */\r
279         SNR_Q7 = 3 * ( SKP_Silk_lin2log( psSilk_VAD->NrgRatioSmth_Q8[b] ) - 8 * 128 );\r
280         /* quality = sigmoid( 0.25 * ( SNR_dB - 16 ) ); */\r
281         pQuality_Q15[ b ] = SKP_Silk_sigm_Q15( SKP_RSHIFT( SNR_Q7 - 16 * 128, 4 ) );\r
282     }\r
283 \r
284     return( ret );\r
285 }\r
286 \r
287 /**************************/\r
288 /* Noise level estimation */\r
289 /**************************/\r
290 void SKP_Silk_VAD_GetNoiseLevels(\r
291     const SKP_int32                 pX[ VAD_N_BANDS ],  /* I    subband energies                            */\r
292     SKP_Silk_VAD_state              *psSilk_VAD         /* I/O  Pointer to Silk VAD state                   */ \r
293 )\r
294 {\r
295     SKP_int   k;\r
296     SKP_int32 nl, nrg, inv_nrg;\r
297     SKP_int   coef, min_coef;\r
298 \r
299     /* Initially faster smoothing */\r
300     if( psSilk_VAD->counter < 1000 ) { /* 1000 = 20 sec */\r
301         min_coef = SKP_DIV32_16( SKP_int16_MAX, SKP_RSHIFT( psSilk_VAD->counter, 4 ) + 1 );  \r
302     } else {\r
303         min_coef = 0;\r
304     }\r
305 \r
306     for( k = 0; k < VAD_N_BANDS; k++ ) {\r
307         /* Get old noise level estimate for current band */\r
308         nl = psSilk_VAD->NL[ k ];\r
309         SKP_assert( nl >= 0 );\r
310         \r
311         /* Add bias */\r
312         nrg = SKP_ADD_POS_SAT32( pX[ k ], psSilk_VAD->NoiseLevelBias[ k ] ); \r
313         SKP_assert( nrg > 0 );\r
314         \r
315         /* Invert energies */\r
316         inv_nrg = SKP_DIV32( SKP_int32_MAX, nrg );\r
317         SKP_assert( inv_nrg >= 0 );\r
318         \r
319         /* Less update when subband energy is high */\r
320         if( nrg > SKP_LSHIFT( nl, 3 ) ) {\r
321             coef = VAD_NOISE_LEVEL_SMOOTH_COEF_Q16 >> 3;\r
322         } else if( nrg < nl ) {\r
323             coef = VAD_NOISE_LEVEL_SMOOTH_COEF_Q16;\r
324         } else {\r
325             coef = SKP_SMULWB( SKP_SMULWW( inv_nrg, nl ), VAD_NOISE_LEVEL_SMOOTH_COEF_Q16 << 1 );\r
326         }\r
327 \r
328         /* Initially faster smoothing */\r
329         coef = SKP_max_int( coef, min_coef );\r
330 \r
331         /* Smooth inverse energies */\r
332         psSilk_VAD->inv_NL[ k ] = SKP_SMLAWB( psSilk_VAD->inv_NL[ k ], inv_nrg - psSilk_VAD->inv_NL[ k ], coef );\r
333         SKP_assert( psSilk_VAD->inv_NL[ k ] >= 0 );\r
334 \r
335         /* Compute noise level by inverting again */\r
336         nl = SKP_DIV32( SKP_int32_MAX, psSilk_VAD->inv_NL[ k ] );\r
337         SKP_assert( nl >= 0 );\r
338 \r
339         /* Limit noise levels (guarantee 7 bits of head room) */\r
340         nl = SKP_min( nl, 0x00FFFFFF );\r
341 \r
342         /* Store as part of state */\r
343         psSilk_VAD->NL[ k ] = nl;\r
344     }\r
345 \r
346     /* Increment frame counter */\r
347     psSilk_VAD->counter++;\r
348 }\r