Coverage Report

Created: 2024-03-26 07:23

/src/opus/silk/VAD.c
Line
Count
Source
1
/***********************************************************************
2
Copyright (c) 2006-2011, Skype Limited. All rights reserved.
3
Redistribution and use in source and binary forms, with or without
4
modification, are permitted provided that the following conditions
5
are met:
6
- Redistributions of source code must retain the above copyright notice,
7
this list of conditions and the following disclaimer.
8
- Redistributions in binary form must reproduce the above copyright
9
notice, this list of conditions and the following disclaimer in the
10
documentation and/or other materials provided with the distribution.
11
- Neither the name of Internet Society, IETF or IETF Trust, nor the
12
names of specific contributors, may be used to endorse or promote
13
products derived from this software without specific prior written
14
permission.
15
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25
POSSIBILITY OF SUCH DAMAGE.
26
***********************************************************************/
27
28
#ifdef HAVE_CONFIG_H
29
#include "config.h"
30
#endif
31
32
#include "main.h"
33
#include "stack_alloc.h"
34
35
/* Silk VAD noise level estimation */
36
# if !defined(OPUS_X86_MAY_HAVE_SSE4_1)
37
static OPUS_INLINE void silk_VAD_GetNoiseLevels(
38
    const opus_int32             pX[ VAD_N_BANDS ], /* I    subband energies                            */
39
    silk_VAD_state              *psSilk_VAD         /* I/O  Pointer to Silk VAD state                   */
40
);
41
#endif
42
43
/**********************************/
44
/* Initialization of the Silk VAD */
45
/**********************************/
46
opus_int silk_VAD_Init(                                         /* O    Return value, 0 if success                  */
47
    silk_VAD_state              *psSilk_VAD                     /* I/O  Pointer to Silk VAD state                   */
48
)
49
9.69k
{
50
9.69k
    opus_int b, ret = 0;
51
52
    /* reset state memory */
53
9.69k
    silk_memset( psSilk_VAD, 0, sizeof( silk_VAD_state ) );
54
55
    /* init noise levels */
56
    /* Initialize array with approx pink noise levels (psd proportional to inverse of frequency) */
57
48.4k
    for( b = 0; b < VAD_N_BANDS; b++ ) {
58
38.7k
        psSilk_VAD->NoiseLevelBias[ b ] = silk_max_32( silk_DIV32_16( VAD_NOISE_LEVELS_BIAS, b + 1 ), 1 );
59
38.7k
    }
60
61
    /* Initialize state */
62
48.4k
    for( b = 0; b < VAD_N_BANDS; b++ ) {
63
38.7k
        psSilk_VAD->NL[ b ]     = silk_MUL( 100, psSilk_VAD->NoiseLevelBias[ b ] );
64
38.7k
        psSilk_VAD->inv_NL[ b ] = silk_DIV32( silk_int32_MAX, psSilk_VAD->NL[ b ] );
65
38.7k
    }
66
9.69k
    psSilk_VAD->counter = 15;
67
68
    /* init smoothed energy-to-noise ratio*/
69
48.4k
    for( b = 0; b < VAD_N_BANDS; b++ ) {
70
38.7k
        psSilk_VAD->NrgRatioSmth_Q8[ b ] = 100 * 256;       /* 100 * 256 --> 20 dB SNR */
71
38.7k
    }
72
73
9.69k
    return( ret );
74
9.69k
}
75
76
/* Weighting factors for tilt measure */
77
static const opus_int32 tiltWeights[ VAD_N_BANDS ] = { 30000, 6000, -12000, -12000 };
78
79
/***************************************/
80
/* Get the speech activity level in Q8 */
81
/***************************************/
82
opus_int silk_VAD_GetSA_Q8_c(                                   /* O    Return value, 0 if success                  */
83
    silk_encoder_state          *psEncC,                        /* I/O  Encoder state                               */
84
    const opus_int16            pIn[]                           /* I    PCM input                                   */
85
)
86
19.7M
{
87
19.7M
    opus_int   SA_Q15, pSNR_dB_Q7, input_tilt;
88
19.7M
    opus_int   decimated_framelength1, decimated_framelength2;
89
19.7M
    opus_int   decimated_framelength;
90
19.7M
    opus_int   dec_subframe_length, dec_subframe_offset, SNR_Q7, i, b, s;
91
19.7M
    opus_int32 sumSquared, smooth_coef_Q16;
92
19.7M
    opus_int16 HPstateTmp;
93
19.7M
    VARDECL( opus_int16, X );
94
19.7M
    opus_int32 Xnrg[ VAD_N_BANDS ];
95
19.7M
    opus_int32 NrgToNoiseRatio_Q8[ VAD_N_BANDS ];
96
19.7M
    opus_int32 speech_nrg, x_tmp;
97
19.7M
    opus_int   X_offset[ VAD_N_BANDS ];
98
19.7M
    opus_int   ret = 0;
99
19.7M
    silk_VAD_state *psSilk_VAD = &psEncC->sVAD;
100
19.7M
    SAVE_STACK;
101
102
    /* Safety checks */
103
19.7M
    silk_assert( VAD_N_BANDS == 4 );
104
19.7M
    celt_assert( MAX_FRAME_LENGTH >= psEncC->frame_length );
105
19.7M
    celt_assert( psEncC->frame_length <= 512 );
106
19.7M
    celt_assert( psEncC->frame_length == 8 * silk_RSHIFT( psEncC->frame_length, 3 ) );
107
108
    /***********************/
109
    /* Filter and Decimate */
110
    /***********************/
111
19.7M
    decimated_framelength1 = silk_RSHIFT( psEncC->frame_length, 1 );
112
19.7M
    decimated_framelength2 = silk_RSHIFT( psEncC->frame_length, 2 );
113
19.7M
    decimated_framelength = silk_RSHIFT( psEncC->frame_length, 3 );
114
    /* Decimate into 4 bands:
115
       0       L      3L       L              3L                             5L
116
               -      --       -              --                             --
117
               8       8       2               4                              4
118
119
       [0-1 kHz| temp. |1-2 kHz|    2-4 kHz    |            4-8 kHz           |
120
121
       They're arranged to allow the minimal ( frame_length / 4 ) extra
122
       scratch space during the downsampling process */
123
19.7M
    X_offset[ 0 ] = 0;
124
19.7M
    X_offset[ 1 ] = decimated_framelength + decimated_framelength2;
125
19.7M
    X_offset[ 2 ] = X_offset[ 1 ] + decimated_framelength;
126
19.7M
    X_offset[ 3 ] = X_offset[ 2 ] + decimated_framelength2;
127
19.7M
    ALLOC( X, X_offset[ 3 ] + decimated_framelength1, opus_int16 );
128
129
    /* 0-8 kHz to 0-4 kHz and 4-8 kHz */
130
19.7M
    silk_ana_filt_bank_1( pIn, &psSilk_VAD->AnaState[  0 ],
131
19.7M
        X, &X[ X_offset[ 3 ] ], psEncC->frame_length );
132
133
    /* 0-4 kHz to 0-2 kHz and 2-4 kHz */
134
19.7M
    silk_ana_filt_bank_1( X, &psSilk_VAD->AnaState1[ 0 ],
135
19.7M
        X, &X[ X_offset[ 2 ] ], decimated_framelength1 );
136
137
    /* 0-2 kHz to 0-1 kHz and 1-2 kHz */
138
19.7M
    silk_ana_filt_bank_1( X, &psSilk_VAD->AnaState2[ 0 ],
139
19.7M
        X, &X[ X_offset[ 1 ] ], decimated_framelength2 );
140
141
    /*********************************************/
142
    /* HP filter on lowest band (differentiator) */
143
    /*********************************************/
144
19.7M
    X[ decimated_framelength - 1 ] = silk_RSHIFT( X[ decimated_framelength - 1 ], 1 );
145
19.7M
    HPstateTmp = X[ decimated_framelength - 1 ];
146
433M
    for( i = decimated_framelength - 1; i > 0; i-- ) {
147
413M
        X[ i - 1 ]  = silk_RSHIFT( X[ i - 1 ], 1 );
148
413M
        X[ i ]     -= X[ i - 1 ];
149
413M
    }
150
19.7M
    X[ 0 ] -= psSilk_VAD->HPstate;
151
19.7M
    psSilk_VAD->HPstate = HPstateTmp;
152
153
    /*************************************/
154
    /* Calculate the energy in each band */
155
    /*************************************/
156
98.9M
    for( b = 0; b < VAD_N_BANDS; b++ ) {
157
        /* Find the decimated framelength in the non-uniformly divided bands */
158
79.1M
        decimated_framelength = silk_RSHIFT( psEncC->frame_length, silk_min_int( VAD_N_BANDS - b, VAD_N_BANDS - 1 ) );
159
160
        /* Split length into subframe lengths */
161
79.1M
        dec_subframe_length = silk_RSHIFT( decimated_framelength, VAD_INTERNAL_SUBFRAMES_LOG2 );
162
79.1M
        dec_subframe_offset = 0;
163
164
        /* Compute energy per sub-frame */
165
        /* initialize with summed energy of last subframe */
166
79.1M
        Xnrg[ b ] = psSilk_VAD->XnrgSubfr[ b ];
167
395M
        for( s = 0; s < VAD_INTERNAL_SUBFRAMES; s++ ) {
168
316M
            sumSquared = 0;
169
3.74G
            for( i = 0; i < dec_subframe_length; i++ ) {
170
                /* The energy will be less than dec_subframe_length * ( silk_int16_MIN / 8 ) ^ 2.            */
171
                /* Therefore we can accumulate with no risk of overflow (unless dec_subframe_length > 128)  */
172
3.42G
                x_tmp = silk_RSHIFT(
173
3.42G
                    X[ X_offset[ b ] + i + dec_subframe_offset ], 3 );
174
3.42G
                sumSquared = silk_SMLABB( sumSquared, x_tmp, x_tmp );
175
176
                /* Safety check */
177
3.42G
                silk_assert( sumSquared >= 0 );
178
3.42G
            }
179
180
            /* Add/saturate summed energy of current subframe */
181
316M
            if( s < VAD_INTERNAL_SUBFRAMES - 1 ) {
182
237M
                Xnrg[ b ] = silk_ADD_POS_SAT32( Xnrg[ b ], sumSquared );
183
237M
            } else {
184
                /* Look-ahead subframe */
185
79.1M
                Xnrg[ b ] = silk_ADD_POS_SAT32( Xnrg[ b ], silk_RSHIFT( sumSquared, 1 ) );
186
79.1M
            }
187
188
316M
            dec_subframe_offset += dec_subframe_length;
189
316M
        }
190
79.1M
        psSilk_VAD->XnrgSubfr[ b ] = sumSquared;
191
79.1M
    }
192
193
    /********************/
194
    /* Noise estimation */
195
    /********************/
196
19.7M
    silk_VAD_GetNoiseLevels( &Xnrg[ 0 ], psSilk_VAD );
197
198
    /***********************************************/
199
    /* Signal-plus-noise to noise ratio estimation */
200
    /***********************************************/
201
19.7M
    sumSquared = 0;
202
19.7M
    input_tilt = 0;
203
98.9M
    for( b = 0; b < VAD_N_BANDS; b++ ) {
204
79.1M
        speech_nrg = Xnrg[ b ] - psSilk_VAD->NL[ b ];
205
79.1M
        if( speech_nrg > 0 ) {
206
            /* Divide, with sufficient resolution */
207
1.85M
            if( ( Xnrg[ b ] & 0xFF800000 ) == 0 ) {
208
1.07M
                NrgToNoiseRatio_Q8[ b ] = silk_DIV32( silk_LSHIFT( Xnrg[ b ], 8 ), psSilk_VAD->NL[ b ] + 1 );
209
1.07M
            } else {
210
777k
                NrgToNoiseRatio_Q8[ b ] = silk_DIV32( Xnrg[ b ], silk_RSHIFT( psSilk_VAD->NL[ b ], 8 ) + 1 );
211
777k
            }
212
213
            /* Convert to log domain */
214
1.85M
            SNR_Q7 = silk_lin2log( NrgToNoiseRatio_Q8[ b ] ) - 8 * 128;
215
216
            /* Sum-of-squares */
217
1.85M
            sumSquared = silk_SMLABB( sumSquared, SNR_Q7, SNR_Q7 );          /* Q14 */
218
219
            /* Tilt measure */
220
1.85M
            if( speech_nrg < ( (opus_int32)1 << 20 ) ) {
221
                /* Scale down SNR value for small subband speech energies */
222
684k
                SNR_Q7 = silk_SMULWB( silk_LSHIFT( silk_SQRT_APPROX( speech_nrg ), 6 ), SNR_Q7 );
223
684k
            }
224
1.85M
            input_tilt = silk_SMLAWB( input_tilt, tiltWeights[ b ], SNR_Q7 );
225
77.3M
        } else {
226
77.3M
            NrgToNoiseRatio_Q8[ b ] = 256;
227
77.3M
        }
228
79.1M
    }
229
230
    /* Mean-of-squares */
231
19.7M
    sumSquared = silk_DIV32_16( sumSquared, VAD_N_BANDS ); /* Q14 */
232
233
    /* Root-mean-square approximation, scale to dBs, and write to output pointer */
234
19.7M
    pSNR_dB_Q7 = (opus_int16)( 3 * silk_SQRT_APPROX( sumSquared ) ); /* Q7 */
235
236
    /*********************************/
237
    /* Speech Probability Estimation */
238
    /*********************************/
239
19.7M
    SA_Q15 = silk_sigm_Q15( silk_SMULWB( VAD_SNR_FACTOR_Q16, pSNR_dB_Q7 ) - VAD_NEGATIVE_OFFSET_Q5 );
240
241
    /**************************/
242
    /* Frequency Tilt Measure */
243
    /**************************/
244
19.7M
    psEncC->input_tilt_Q15 = silk_LSHIFT( silk_sigm_Q15( input_tilt ) - 16384, 1 );
245
246
    /**************************************************/
247
    /* Scale the sigmoid output based on power levels */
248
    /**************************************************/
249
19.7M
    speech_nrg = 0;
250
98.9M
    for( b = 0; b < VAD_N_BANDS; b++ ) {
251
        /* Accumulate signal-without-noise energies, higher frequency bands have more weight */
252
79.1M
        speech_nrg += ( b + 1 ) * silk_RSHIFT( Xnrg[ b ] - psSilk_VAD->NL[ b ], 4 );
253
79.1M
    }
254
255
19.7M
    if( psEncC->frame_length == 20 * psEncC->fs_kHz ) {
256
12.1M
        speech_nrg = silk_RSHIFT32( speech_nrg, 1 );
257
12.1M
    }
258
    /* Power scaling */
259
19.7M
    if( speech_nrg <= 0 ) {
260
19.2M
        SA_Q15 = silk_RSHIFT( SA_Q15, 1 );
261
19.2M
    } else if( speech_nrg < 16384 ) {
262
39.8k
        speech_nrg = silk_LSHIFT32( speech_nrg, 16 );
263
264
        /* square-root */
265
39.8k
        speech_nrg = silk_SQRT_APPROX( speech_nrg );
266
39.8k
        SA_Q15 = silk_SMULWB( 32768 + speech_nrg, SA_Q15 );
267
39.8k
    }
268
269
    /* Copy the resulting speech activity in Q8 */
270
19.7M
    psEncC->speech_activity_Q8 = silk_min_int( silk_RSHIFT( SA_Q15, 7 ), silk_uint8_MAX );
271
272
    /***********************************/
273
    /* Energy Level and SNR estimation */
274
    /***********************************/
275
    /* Smoothing coefficient */
276
19.7M
    smooth_coef_Q16 = silk_SMULWB( VAD_SNR_SMOOTH_COEF_Q18, silk_SMULWB( (opus_int32)SA_Q15, SA_Q15 ) );
277
278
19.7M
    if( psEncC->frame_length == 10 * psEncC->fs_kHz ) {
279
7.64M
        smooth_coef_Q16 >>= 1;
280
7.64M
    }
281
282
98.9M
    for( b = 0; b < VAD_N_BANDS; b++ ) {
283
        /* compute smoothed energy-to-noise ratio per band */
284
79.1M
        psSilk_VAD->NrgRatioSmth_Q8[ b ] = silk_SMLAWB( psSilk_VAD->NrgRatioSmth_Q8[ b ],
285
79.1M
            NrgToNoiseRatio_Q8[ b ] - psSilk_VAD->NrgRatioSmth_Q8[ b ], smooth_coef_Q16 );
286
287
        /* signal to noise ratio in dB per band */
288
79.1M
        SNR_Q7 = 3 * ( silk_lin2log( psSilk_VAD->NrgRatioSmth_Q8[b] ) - 8 * 128 );
289
        /* quality = sigmoid( 0.25 * ( SNR_dB - 16 ) ); */
290
79.1M
        psEncC->input_quality_bands_Q15[ b ] = silk_sigm_Q15( silk_RSHIFT( SNR_Q7 - 16 * 128, 4 ) );
291
79.1M
    }
292
293
19.7M
    RESTORE_STACK;
294
19.7M
    return( ret );
295
19.7M
}
296
297
/**************************/
298
/* Noise level estimation */
299
/**************************/
300
# if  !defined(OPUS_X86_MAY_HAVE_SSE4_1)
301
static OPUS_INLINE
302
#endif
303
void silk_VAD_GetNoiseLevels(
304
    const opus_int32            pX[ VAD_N_BANDS ],  /* I    subband energies                            */
305
    silk_VAD_state              *psSilk_VAD         /* I/O  Pointer to Silk VAD state                   */
306
)
307
39.5M
{
308
39.5M
    opus_int   k;
309
39.5M
    opus_int32 nl, nrg, inv_nrg;
310
39.5M
    opus_int   coef, min_coef;
311
312
    /* Initially faster smoothing */
313
39.5M
    if( psSilk_VAD->counter < 1000 ) { /* 1000 = 20 sec */
314
5.44M
        min_coef = silk_DIV32_16( silk_int16_MAX, silk_RSHIFT( psSilk_VAD->counter, 4 ) + 1 );
315
        /* Increment frame counter */
316
5.44M
        psSilk_VAD->counter++;
317
34.1M
    } else {
318
34.1M
        min_coef = 0;
319
34.1M
    }
320
321
197M
    for( k = 0; k < VAD_N_BANDS; k++ ) {
322
        /* Get old noise level estimate for current band */
323
158M
        nl = psSilk_VAD->NL[ k ];
324
158M
        silk_assert( nl >= 0 );
325
326
        /* Add bias */
327
158M
        nrg = silk_ADD_POS_SAT32( pX[ k ], psSilk_VAD->NoiseLevelBias[ k ] );
328
158M
        silk_assert( nrg > 0 );
329
330
        /* Invert energies */
331
158M
        inv_nrg = silk_DIV32( silk_int32_MAX, nrg );
332
158M
        silk_assert( inv_nrg >= 0 );
333
334
        /* Less update when subband energy is high */
335
158M
        if( nrg > silk_LSHIFT( nl, 3 ) ) {
336
2.06M
            coef = VAD_NOISE_LEVEL_SMOOTH_COEF_Q16 >> 3;
337
156M
        } else if( nrg < nl ) {
338
2.53M
            coef = VAD_NOISE_LEVEL_SMOOTH_COEF_Q16;
339
153M
        } else {
340
153M
            coef = silk_SMULWB( silk_SMULWW( inv_nrg, nl ), VAD_NOISE_LEVEL_SMOOTH_COEF_Q16 << 1 );
341
153M
        }
342
343
        /* Initially faster smoothing */
344
158M
        coef = silk_max_int( coef, min_coef );
345
346
        /* Smooth inverse energies */
347
158M
        psSilk_VAD->inv_NL[ k ] = silk_SMLAWB( psSilk_VAD->inv_NL[ k ], inv_nrg - psSilk_VAD->inv_NL[ k ], coef );
348
158M
        silk_assert( psSilk_VAD->inv_NL[ k ] >= 0 );
349
350
        /* Compute noise level by inverting again */
351
158M
        nl = silk_DIV32( silk_int32_MAX, psSilk_VAD->inv_NL[ k ] );
352
158M
        silk_assert( nl >= 0 );
353
354
        /* Limit noise levels (guarantee 7 bits of head room) */
355
158M
        nl = silk_min( nl, 0x00FFFFFF );
356
357
        /* Store as part of state */
358
158M
        psSilk_VAD->NL[ k ] = nl;
359
158M
    }
360
39.5M
}