Coverage Report

Created: 2026-09-03 08:13

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/opus/silk/x86/VAD_sse4_1.c
Line
Count
Source
1
/* Copyright (c) 2014-2020, Cisco Systems, INC
2
   Written by XiangMingZhu WeiZhou MinPeng YanWang FrancisQuiers
3
4
   Redistribution and use in source and binary forms, with or without
5
   modification, are permitted provided that the following conditions
6
   are met:
7
8
   - Redistributions of source code must retain the above copyright
9
   notice, this list of conditions and the following disclaimer.
10
11
   - Redistributions in binary form must reproduce the above copyright
12
   notice, this list of conditions and the following disclaimer in the
13
   documentation and/or other materials provided with the distribution.
14
15
   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16
   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17
   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18
   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
19
   OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20
   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21
   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
22
   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
23
   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
24
   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25
   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26
*/
27
28
#ifdef HAVE_CONFIG_H
29
#include "config.h"
30
#endif
31
32
#include <xmmintrin.h>
33
#include <emmintrin.h>
34
#include <smmintrin.h>
35
36
#include "main.h"
37
#include "stack_alloc.h"
38
39
/* Weighting factors for tilt measure */
40
static const opus_int32 tiltWeights[ VAD_N_BANDS ] = { 30000, 6000, -12000, -12000 };
41
42
/***************************************/
43
/* Get the speech activity level in Q8 */
44
/***************************************/
45
opus_int silk_VAD_GetSA_Q8_sse4_1(                  /* O    Return value, 0 if success                  */
46
    silk_encoder_state          *psEncC,            /* I/O  Encoder state                               */
47
    const opus_int16            pIn[]               /* I    PCM input                                   */
48
)
49
403k
{
50
403k
    opus_int   SA_Q15, pSNR_dB_Q7, input_tilt;
51
403k
    opus_int   decimated_framelength1, decimated_framelength2;
52
403k
    opus_int   decimated_framelength;
53
403k
    opus_int   dec_subframe_length, dec_subframe_offset, SNR_Q7, i, b, s;
54
403k
    opus_int32 sumSquared, smooth_coef_Q16;
55
403k
    opus_int16 HPstateTmp;
56
403k
    VARDECL( opus_int16, X );
57
403k
    opus_int32 Xnrg[ VAD_N_BANDS ];
58
403k
    opus_int32 NrgToNoiseRatio_Q8[ VAD_N_BANDS ];
59
403k
    opus_int32 speech_nrg, x_tmp;
60
403k
    opus_int   X_offset[ VAD_N_BANDS ];
61
403k
    opus_int   ret = 0;
62
403k
    silk_VAD_state *psSilk_VAD = &psEncC->sVAD;
63
64
403k
    SAVE_STACK;
65
66
#ifdef OPUS_CHECK_ASM
67
    silk_encoder_state psEncC_c;
68
173k
    opus_int ret_c;
69
70
173k
    silk_memcpy( &psEncC_c, psEncC, sizeof( psEncC_c ) );
71
    ret_c = silk_VAD_GetSA_Q8_c( &psEncC_c, pIn );
72
#endif
73
74
    /* Safety checks */
75
403k
    silk_assert( VAD_N_BANDS == 4 );
76
403k
    celt_assert( MAX_FRAME_LENGTH >= psEncC->frame_length );
77
403k
    celt_assert( psEncC->frame_length <= 512 );
78
403k
    celt_assert( psEncC->frame_length == 8 * silk_RSHIFT( psEncC->frame_length, 3 ) );
79
80
    /***********************/
81
    /* Filter and Decimate */
82
    /***********************/
83
403k
    decimated_framelength1 = silk_RSHIFT( psEncC->frame_length, 1 );
84
403k
    decimated_framelength2 = silk_RSHIFT( psEncC->frame_length, 2 );
85
403k
    decimated_framelength = silk_RSHIFT( psEncC->frame_length, 3 );
86
    /* Decimate into 4 bands:
87
       0       L      3L       L              3L                             5L
88
               -      --       -              --                             --
89
               8       8       2               4                              4
90
91
       [0-1 kHz| temp. |1-2 kHz|    2-4 kHz    |            4-8 kHz           |
92
93
       They're arranged to allow the minimal ( frame_length / 4 ) extra
94
       scratch space during the downsampling process */
95
403k
    X_offset[ 0 ] = 0;
96
403k
    X_offset[ 1 ] = decimated_framelength + decimated_framelength2;
97
403k
    X_offset[ 2 ] = X_offset[ 1 ] + decimated_framelength;
98
403k
    X_offset[ 3 ] = X_offset[ 2 ] + decimated_framelength2;
99
403k
    ALLOC( X, X_offset[ 3 ] + decimated_framelength1, opus_int16 );
100
101
    /* 0-8 kHz to 0-4 kHz and 4-8 kHz */
102
403k
    silk_ana_filt_bank_1( pIn, &psSilk_VAD->AnaState[  0 ],
103
403k
        X, &X[ X_offset[ 3 ] ], psEncC->frame_length );
104
105
    /* 0-4 kHz to 0-2 kHz and 2-4 kHz */
106
403k
    silk_ana_filt_bank_1( X, &psSilk_VAD->AnaState1[ 0 ],
107
403k
        X, &X[ X_offset[ 2 ] ], decimated_framelength1 );
108
109
    /* 0-2 kHz to 0-1 kHz and 1-2 kHz */
110
403k
    silk_ana_filt_bank_1( X, &psSilk_VAD->AnaState2[ 0 ],
111
403k
        X, &X[ X_offset[ 1 ] ], decimated_framelength2 );
112
113
    /*********************************************/
114
    /* HP filter on lowest band (differentiator) */
115
    /*********************************************/
116
403k
    X[ decimated_framelength - 1 ] = silk_RSHIFT( X[ decimated_framelength - 1 ], 1 );
117
403k
    HPstateTmp = X[ decimated_framelength - 1 ];
118
8.72M
    for( i = decimated_framelength - 1; i > 0; i-- ) {
119
8.31M
        X[ i - 1 ]  = silk_RSHIFT( X[ i - 1 ], 1 );
120
8.31M
        X[ i ]     -= X[ i - 1 ];
121
8.31M
    }
122
403k
    X[ 0 ] -= psSilk_VAD->HPstate;
123
403k
    psSilk_VAD->HPstate = HPstateTmp;
124
125
    /*************************************/
126
    /* Calculate the energy in each band */
127
    /*************************************/
128
2.01M
    for( b = 0; b < VAD_N_BANDS; b++ ) {
129
        /* Find the decimated framelength in the non-uniformly divided bands */
130
1.61M
        decimated_framelength = silk_RSHIFT( psEncC->frame_length, silk_min_int( VAD_N_BANDS - b, VAD_N_BANDS - 1 ) );
131
132
        /* Split length into subframe lengths */
133
1.61M
        dec_subframe_length = silk_RSHIFT( decimated_framelength, VAD_INTERNAL_SUBFRAMES_LOG2 );
134
1.61M
        dec_subframe_offset = 0;
135
136
        /* Compute energy per sub-frame */
137
        /* initialize with summed energy of last subframe */
138
1.61M
        Xnrg[ b ] = psSilk_VAD->XnrgSubfr[ b ];
139
8.07M
        for( s = 0; s < VAD_INTERNAL_SUBFRAMES; s++ ) {
140
6.45M
            __m128i xmm_X, xmm_acc;
141
6.45M
            sumSquared = 0;
142
143
6.45M
            xmm_acc = _mm_setzero_si128();
144
145
12.1M
            for( i = 0; i < dec_subframe_length - 7; i += 8 )
146
5.67M
            {
147
5.67M
                xmm_X   = _mm_loadu_si128( (__m128i *)(void*)&(X[ X_offset[ b ] + i + dec_subframe_offset ] ) );
148
5.67M
                xmm_X   = _mm_srai_epi16( xmm_X, 3 );
149
5.67M
                xmm_X   = _mm_madd_epi16( xmm_X, xmm_X );
150
5.67M
                xmm_acc = _mm_add_epi32( xmm_acc, xmm_X );
151
5.67M
            }
152
153
6.45M
            xmm_acc = _mm_add_epi32( xmm_acc, _mm_unpackhi_epi64( xmm_acc, xmm_acc ) );
154
6.45M
            xmm_acc = _mm_add_epi32( xmm_acc, _mm_shufflelo_epi16( xmm_acc, 0x0E ) );
155
156
6.45M
            sumSquared += _mm_cvtsi128_si32( xmm_acc );
157
158
30.3M
            for( ; i < dec_subframe_length; i++ ) {
159
                /* The energy will be less than dec_subframe_length * ( silk_int16_MIN / 8 ) ^ 2.            */
160
                /* Therefore we can accumulate with no risk of overflow (unless dec_subframe_length > 128)  */
161
23.9M
                x_tmp = silk_RSHIFT(
162
23.9M
                    X[ X_offset[ b ] + i + dec_subframe_offset ], 3 );
163
23.9M
                sumSquared = silk_SMLABB( sumSquared, x_tmp, x_tmp );
164
165
                /* Safety check */
166
23.9M
                silk_assert( sumSquared >= 0 );
167
23.9M
            }
168
169
            /* Add/saturate summed energy of current subframe */
170
6.45M
            if( s < VAD_INTERNAL_SUBFRAMES - 1 ) {
171
4.84M
                Xnrg[ b ] = silk_ADD_POS_SAT32( Xnrg[ b ], sumSquared );
172
4.84M
            } else {
173
                /* Look-ahead subframe */
174
1.61M
                Xnrg[ b ] = silk_ADD_POS_SAT32( Xnrg[ b ], silk_RSHIFT( sumSquared, 1 ) );
175
1.61M
            }
176
177
6.45M
            dec_subframe_offset += dec_subframe_length;
178
6.45M
        }
179
1.61M
        psSilk_VAD->XnrgSubfr[ b ] = sumSquared;
180
1.61M
    }
181
182
    /********************/
183
    /* Noise estimation */
184
    /********************/
185
403k
    silk_VAD_GetNoiseLevels( &Xnrg[ 0 ], psSilk_VAD );
186
187
    /***********************************************/
188
    /* Signal-plus-noise to noise ratio estimation */
189
    /***********************************************/
190
229k
    sumSquared = 0;
191
229k
    input_tilt = 0;
192
2.01M
    for( b = 0; b < VAD_N_BANDS; b++ ) {
193
1.61M
        speech_nrg = Xnrg[ b ] - psSilk_VAD->NL[ b ];
194
1.61M
        if( speech_nrg > 0 ) {
195
            /* Divide, with sufficient resolution */
196
1.16M
            if( ( Xnrg[ b ] & 0xFF800000 ) == 0 ) {
197
911k
                NrgToNoiseRatio_Q8[ b ] = silk_DIV32( silk_LSHIFT( Xnrg[ b ], 8 ), psSilk_VAD->NL[ b ] + 1 );
198
911k
            } else {
199
248k
                NrgToNoiseRatio_Q8[ b ] = silk_DIV32( Xnrg[ b ], silk_RSHIFT( psSilk_VAD->NL[ b ], 8 ) + 1 );
200
248k
            }
201
202
            /* Convert to log domain */
203
1.16M
            SNR_Q7 = silk_lin2log( NrgToNoiseRatio_Q8[ b ] ) - 8 * 128;
204
205
            /* Sum-of-squares */
206
1.16M
            sumSquared = silk_SMLABB( sumSquared, SNR_Q7, SNR_Q7 );          /* Q14 */
207
208
            /* Tilt measure */
209
1.16M
            if( speech_nrg < ( (opus_int32)1 << 20 ) ) {
210
                /* Scale down SNR value for small subband speech energies */
211
584k
                SNR_Q7 = silk_SMULWB( silk_LSHIFT( silk_SQRT_APPROX( speech_nrg ), 6 ), SNR_Q7 );
212
584k
            }
213
1.16M
            input_tilt = silk_SMLAWB( input_tilt, tiltWeights[ b ], SNR_Q7 );
214
1.16M
        } else {
215
454k
            NrgToNoiseRatio_Q8[ b ] = 256;
216
454k
        }
217
1.61M
    }
218
219
    /* Mean-of-squares */
220
403k
    sumSquared = silk_DIV32_16( sumSquared, VAD_N_BANDS ); /* Q14 */
221
222
    /* Root-mean-square approximation, scale to dBs, and write to output pointer */
223
229k
    pSNR_dB_Q7 = (opus_int16)( 3 * silk_SQRT_APPROX( sumSquared ) ); /* Q7 */
224
225
    /*********************************/
226
    /* Speech Probability Estimation */
227
    /*********************************/
228
403k
    SA_Q15 = silk_sigm_Q15( silk_SMULWB( VAD_SNR_FACTOR_Q16, pSNR_dB_Q7 ) - VAD_NEGATIVE_OFFSET_Q5 );
229
230
    /**************************/
231
    /* Frequency Tilt Measure */
232
    /**************************/
233
403k
    psEncC->input_tilt_Q15 = silk_LSHIFT( silk_sigm_Q15( input_tilt ) - 16384, 1 );
234
235
    /**************************************************/
236
    /* Scale the sigmoid output based on power levels */
237
    /**************************************************/
238
229k
    speech_nrg = 0;
239
2.01M
    for( b = 0; b < VAD_N_BANDS; b++ ) {
240
        /* Accumulate signal-without-noise energies, higher frequency bands have more weight */
241
1.61M
        speech_nrg += ( b + 1 ) * silk_RSHIFT( Xnrg[ b ] - psSilk_VAD->NL[ b ], 4 );
242
1.61M
    }
243
244
403k
    if( psEncC->frame_length == 20 * psEncC->fs_kHz ) {
245
306k
        speech_nrg = silk_RSHIFT32( speech_nrg, 1 );
246
306k
    }
247
    /* Power scaling */
248
403k
    if( speech_nrg <= 0 ) {
249
85.6k
        SA_Q15 = silk_RSHIFT( SA_Q15, 1 );
250
318k
    } else if( speech_nrg < 16384 ) {
251
41.3k
        speech_nrg = silk_LSHIFT32( speech_nrg, 16 );
252
253
        /* square-root */
254
41.3k
        speech_nrg = silk_SQRT_APPROX( speech_nrg );
255
41.3k
        SA_Q15 = silk_SMULWB( 32768 + speech_nrg, SA_Q15 );
256
41.3k
    }
257
258
    /* Copy the resulting speech activity in Q8 */
259
403k
    psEncC->speech_activity_Q8 = silk_min_int( silk_RSHIFT( SA_Q15, 7 ), silk_uint8_MAX );
260
261
    /***********************************/
262
    /* Energy Level and SNR estimation */
263
    /***********************************/
264
    /* Smoothing coefficient */
265
403k
    smooth_coef_Q16 = silk_SMULWB( VAD_SNR_SMOOTH_COEF_Q18, silk_SMULWB( (opus_int32)SA_Q15, SA_Q15 ) );
266
267
403k
    if( psEncC->frame_length == 10 * psEncC->fs_kHz ) {
268
97.5k
        smooth_coef_Q16 >>= 1;
269
97.5k
    }
270
271
2.01M
    for( b = 0; b < VAD_N_BANDS; b++ ) {
272
        /* compute smoothed energy-to-noise ratio per band */
273
1.61M
        psSilk_VAD->NrgRatioSmth_Q8[ b ] = silk_SMLAWB( psSilk_VAD->NrgRatioSmth_Q8[ b ],
274
1.61M
            NrgToNoiseRatio_Q8[ b ] - psSilk_VAD->NrgRatioSmth_Q8[ b ], smooth_coef_Q16 );
275
276
        /* signal to noise ratio in dB per band */
277
1.61M
        SNR_Q7 = 3 * ( silk_lin2log( psSilk_VAD->NrgRatioSmth_Q8[b] ) - 8 * 128 );
278
        /* quality = sigmoid( 0.25 * ( SNR_dB - 16 ) ); */
279
1.61M
        psEncC->input_quality_bands_Q15[ b ] = silk_sigm_Q15( silk_RSHIFT( SNR_Q7 - 16 * 128, 4 ) );
280
1.61M
    }
281
282
#ifdef OPUS_CHECK_ASM
283
173k
    silk_assert( ret == ret_c );
284
173k
    silk_assert( !memcmp( &psEncC_c, psEncC, sizeof( psEncC_c ) ) );
285
173k
#endif
286
287
173k
    RESTORE_STACK;
288
173k
    return( ret );
289
173k
}
silk_VAD_GetSA_Q8_sse4_1
Line
Count
Source
49
173k
{
50
173k
    opus_int   SA_Q15, pSNR_dB_Q7, input_tilt;
51
173k
    opus_int   decimated_framelength1, decimated_framelength2;
52
173k
    opus_int   decimated_framelength;
53
173k
    opus_int   dec_subframe_length, dec_subframe_offset, SNR_Q7, i, b, s;
54
173k
    opus_int32 sumSquared, smooth_coef_Q16;
55
173k
    opus_int16 HPstateTmp;
56
173k
    VARDECL( opus_int16, X );
57
173k
    opus_int32 Xnrg[ VAD_N_BANDS ];
58
173k
    opus_int32 NrgToNoiseRatio_Q8[ VAD_N_BANDS ];
59
173k
    opus_int32 speech_nrg, x_tmp;
60
173k
    opus_int   X_offset[ VAD_N_BANDS ];
61
173k
    opus_int   ret = 0;
62
173k
    silk_VAD_state *psSilk_VAD = &psEncC->sVAD;
63
64
173k
    SAVE_STACK;
65
66
173k
#ifdef OPUS_CHECK_ASM
67
173k
    silk_encoder_state psEncC_c;
68
173k
    opus_int ret_c;
69
70
173k
    silk_memcpy( &psEncC_c, psEncC, sizeof( psEncC_c ) );
71
173k
    ret_c = silk_VAD_GetSA_Q8_c( &psEncC_c, pIn );
72
173k
#endif
73
74
    /* Safety checks */
75
173k
    silk_assert( VAD_N_BANDS == 4 );
76
173k
    celt_assert( MAX_FRAME_LENGTH >= psEncC->frame_length );
77
173k
    celt_assert( psEncC->frame_length <= 512 );
78
173k
    celt_assert( psEncC->frame_length == 8 * silk_RSHIFT( psEncC->frame_length, 3 ) );
79
80
    /***********************/
81
    /* Filter and Decimate */
82
    /***********************/
83
173k
    decimated_framelength1 = silk_RSHIFT( psEncC->frame_length, 1 );
84
173k
    decimated_framelength2 = silk_RSHIFT( psEncC->frame_length, 2 );
85
173k
    decimated_framelength = silk_RSHIFT( psEncC->frame_length, 3 );
86
    /* Decimate into 4 bands:
87
       0       L      3L       L              3L                             5L
88
               -      --       -              --                             --
89
               8       8       2               4                              4
90
91
       [0-1 kHz| temp. |1-2 kHz|    2-4 kHz    |            4-8 kHz           |
92
93
       They're arranged to allow the minimal ( frame_length / 4 ) extra
94
       scratch space during the downsampling process */
95
173k
    X_offset[ 0 ] = 0;
96
173k
    X_offset[ 1 ] = decimated_framelength + decimated_framelength2;
97
173k
    X_offset[ 2 ] = X_offset[ 1 ] + decimated_framelength;
98
173k
    X_offset[ 3 ] = X_offset[ 2 ] + decimated_framelength2;
99
173k
    ALLOC( X, X_offset[ 3 ] + decimated_framelength1, opus_int16 );
100
101
    /* 0-8 kHz to 0-4 kHz and 4-8 kHz */
102
173k
    silk_ana_filt_bank_1( pIn, &psSilk_VAD->AnaState[  0 ],
103
173k
        X, &X[ X_offset[ 3 ] ], psEncC->frame_length );
104
105
    /* 0-4 kHz to 0-2 kHz and 2-4 kHz */
106
173k
    silk_ana_filt_bank_1( X, &psSilk_VAD->AnaState1[ 0 ],
107
173k
        X, &X[ X_offset[ 2 ] ], decimated_framelength1 );
108
109
    /* 0-2 kHz to 0-1 kHz and 1-2 kHz */
110
173k
    silk_ana_filt_bank_1( X, &psSilk_VAD->AnaState2[ 0 ],
111
173k
        X, &X[ X_offset[ 1 ] ], decimated_framelength2 );
112
113
    /*********************************************/
114
    /* HP filter on lowest band (differentiator) */
115
    /*********************************************/
116
173k
    X[ decimated_framelength - 1 ] = silk_RSHIFT( X[ decimated_framelength - 1 ], 1 );
117
173k
    HPstateTmp = X[ decimated_framelength - 1 ];
118
3.70M
    for( i = decimated_framelength - 1; i > 0; i-- ) {
119
3.53M
        X[ i - 1 ]  = silk_RSHIFT( X[ i - 1 ], 1 );
120
3.53M
        X[ i ]     -= X[ i - 1 ];
121
3.53M
    }
122
173k
    X[ 0 ] -= psSilk_VAD->HPstate;
123
173k
    psSilk_VAD->HPstate = HPstateTmp;
124
125
    /*************************************/
126
    /* Calculate the energy in each band */
127
    /*************************************/
128
869k
    for( b = 0; b < VAD_N_BANDS; b++ ) {
129
        /* Find the decimated framelength in the non-uniformly divided bands */
130
695k
        decimated_framelength = silk_RSHIFT( psEncC->frame_length, silk_min_int( VAD_N_BANDS - b, VAD_N_BANDS - 1 ) );
131
132
        /* Split length into subframe lengths */
133
695k
        dec_subframe_length = silk_RSHIFT( decimated_framelength, VAD_INTERNAL_SUBFRAMES_LOG2 );
134
695k
        dec_subframe_offset = 0;
135
136
        /* Compute energy per sub-frame */
137
        /* initialize with summed energy of last subframe */
138
695k
        Xnrg[ b ] = psSilk_VAD->XnrgSubfr[ b ];
139
3.47M
        for( s = 0; s < VAD_INTERNAL_SUBFRAMES; s++ ) {
140
2.78M
            __m128i xmm_X, xmm_acc;
141
2.78M
            sumSquared = 0;
142
143
2.78M
            xmm_acc = _mm_setzero_si128();
144
145
5.18M
            for( i = 0; i < dec_subframe_length - 7; i += 8 )
146
2.40M
            {
147
2.40M
                xmm_X   = _mm_loadu_si128( (__m128i *)(void*)&(X[ X_offset[ b ] + i + dec_subframe_offset ] ) );
148
2.40M
                xmm_X   = _mm_srai_epi16( xmm_X, 3 );
149
2.40M
                xmm_X   = _mm_madd_epi16( xmm_X, xmm_X );
150
2.40M
                xmm_acc = _mm_add_epi32( xmm_acc, xmm_X );
151
2.40M
            }
152
153
2.78M
            xmm_acc = _mm_add_epi32( xmm_acc, _mm_unpackhi_epi64( xmm_acc, xmm_acc ) );
154
2.78M
            xmm_acc = _mm_add_epi32( xmm_acc, _mm_shufflelo_epi16( xmm_acc, 0x0E ) );
155
156
2.78M
            sumSquared += _mm_cvtsi128_si32( xmm_acc );
157
158
12.9M
            for( ; i < dec_subframe_length; i++ ) {
159
                /* The energy will be less than dec_subframe_length * ( silk_int16_MIN / 8 ) ^ 2.            */
160
                /* Therefore we can accumulate with no risk of overflow (unless dec_subframe_length > 128)  */
161
10.2M
                x_tmp = silk_RSHIFT(
162
10.2M
                    X[ X_offset[ b ] + i + dec_subframe_offset ], 3 );
163
10.2M
                sumSquared = silk_SMLABB( sumSquared, x_tmp, x_tmp );
164
165
                /* Safety check */
166
10.2M
                silk_assert( sumSquared >= 0 );
167
10.2M
            }
168
169
            /* Add/saturate summed energy of current subframe */
170
2.78M
            if( s < VAD_INTERNAL_SUBFRAMES - 1 ) {
171
2.08M
                Xnrg[ b ] = silk_ADD_POS_SAT32( Xnrg[ b ], sumSquared );
172
2.08M
            } else {
173
                /* Look-ahead subframe */
174
695k
                Xnrg[ b ] = silk_ADD_POS_SAT32( Xnrg[ b ], silk_RSHIFT( sumSquared, 1 ) );
175
695k
            }
176
177
2.78M
            dec_subframe_offset += dec_subframe_length;
178
2.78M
        }
179
695k
        psSilk_VAD->XnrgSubfr[ b ] = sumSquared;
180
695k
    }
181
182
    /********************/
183
    /* Noise estimation */
184
    /********************/
185
173k
    silk_VAD_GetNoiseLevels( &Xnrg[ 0 ], psSilk_VAD );
186
187
    /***********************************************/
188
    /* Signal-plus-noise to noise ratio estimation */
189
    /***********************************************/
190
173k
    sumSquared = 0;
191
173k
    input_tilt = 0;
192
869k
    for( b = 0; b < VAD_N_BANDS; b++ ) {
193
695k
        speech_nrg = Xnrg[ b ] - psSilk_VAD->NL[ b ];
194
695k
        if( speech_nrg > 0 ) {
195
            /* Divide, with sufficient resolution */
196
491k
            if( ( Xnrg[ b ] & 0xFF800000 ) == 0 ) {
197
389k
                NrgToNoiseRatio_Q8[ b ] = silk_DIV32( silk_LSHIFT( Xnrg[ b ], 8 ), psSilk_VAD->NL[ b ] + 1 );
198
389k
            } else {
199
101k
                NrgToNoiseRatio_Q8[ b ] = silk_DIV32( Xnrg[ b ], silk_RSHIFT( psSilk_VAD->NL[ b ], 8 ) + 1 );
200
101k
            }
201
202
            /* Convert to log domain */
203
491k
            SNR_Q7 = silk_lin2log( NrgToNoiseRatio_Q8[ b ] ) - 8 * 128;
204
205
            /* Sum-of-squares */
206
491k
            sumSquared = silk_SMLABB( sumSquared, SNR_Q7, SNR_Q7 );          /* Q14 */
207
208
            /* Tilt measure */
209
491k
            if( speech_nrg < ( (opus_int32)1 << 20 ) ) {
210
                /* Scale down SNR value for small subband speech energies */
211
253k
                SNR_Q7 = silk_SMULWB( silk_LSHIFT( silk_SQRT_APPROX( speech_nrg ), 6 ), SNR_Q7 );
212
253k
            }
213
491k
            input_tilt = silk_SMLAWB( input_tilt, tiltWeights[ b ], SNR_Q7 );
214
491k
        } else {
215
203k
            NrgToNoiseRatio_Q8[ b ] = 256;
216
203k
        }
217
695k
    }
218
219
    /* Mean-of-squares */
220
173k
    sumSquared = silk_DIV32_16( sumSquared, VAD_N_BANDS ); /* Q14 */
221
222
    /* Root-mean-square approximation, scale to dBs, and write to output pointer */
223
173k
    pSNR_dB_Q7 = (opus_int16)( 3 * silk_SQRT_APPROX( sumSquared ) ); /* Q7 */
224
225
    /*********************************/
226
    /* Speech Probability Estimation */
227
    /*********************************/
228
173k
    SA_Q15 = silk_sigm_Q15( silk_SMULWB( VAD_SNR_FACTOR_Q16, pSNR_dB_Q7 ) - VAD_NEGATIVE_OFFSET_Q5 );
229
230
    /**************************/
231
    /* Frequency Tilt Measure */
232
    /**************************/
233
173k
    psEncC->input_tilt_Q15 = silk_LSHIFT( silk_sigm_Q15( input_tilt ) - 16384, 1 );
234
235
    /**************************************************/
236
    /* Scale the sigmoid output based on power levels */
237
    /**************************************************/
238
173k
    speech_nrg = 0;
239
869k
    for( b = 0; b < VAD_N_BANDS; b++ ) {
240
        /* Accumulate signal-without-noise energies, higher frequency bands have more weight */
241
695k
        speech_nrg += ( b + 1 ) * silk_RSHIFT( Xnrg[ b ] - psSilk_VAD->NL[ b ], 4 );
242
695k
    }
243
244
173k
    if( psEncC->frame_length == 20 * psEncC->fs_kHz ) {
245
132k
        speech_nrg = silk_RSHIFT32( speech_nrg, 1 );
246
132k
    }
247
    /* Power scaling */
248
173k
    if( speech_nrg <= 0 ) {
249
38.6k
        SA_Q15 = silk_RSHIFT( SA_Q15, 1 );
250
135k
    } else if( speech_nrg < 16384 ) {
251
18.1k
        speech_nrg = silk_LSHIFT32( speech_nrg, 16 );
252
253
        /* square-root */
254
18.1k
        speech_nrg = silk_SQRT_APPROX( speech_nrg );
255
18.1k
        SA_Q15 = silk_SMULWB( 32768 + speech_nrg, SA_Q15 );
256
18.1k
    }
257
258
    /* Copy the resulting speech activity in Q8 */
259
173k
    psEncC->speech_activity_Q8 = silk_min_int( silk_RSHIFT( SA_Q15, 7 ), silk_uint8_MAX );
260
261
    /***********************************/
262
    /* Energy Level and SNR estimation */
263
    /***********************************/
264
    /* Smoothing coefficient */
265
173k
    smooth_coef_Q16 = silk_SMULWB( VAD_SNR_SMOOTH_COEF_Q18, silk_SMULWB( (opus_int32)SA_Q15, SA_Q15 ) );
266
267
173k
    if( psEncC->frame_length == 10 * psEncC->fs_kHz ) {
268
41.3k
        smooth_coef_Q16 >>= 1;
269
41.3k
    }
270
271
869k
    for( b = 0; b < VAD_N_BANDS; b++ ) {
272
        /* compute smoothed energy-to-noise ratio per band */
273
695k
        psSilk_VAD->NrgRatioSmth_Q8[ b ] = silk_SMLAWB( psSilk_VAD->NrgRatioSmth_Q8[ b ],
274
695k
            NrgToNoiseRatio_Q8[ b ] - psSilk_VAD->NrgRatioSmth_Q8[ b ], smooth_coef_Q16 );
275
276
        /* signal to noise ratio in dB per band */
277
695k
        SNR_Q7 = 3 * ( silk_lin2log( psSilk_VAD->NrgRatioSmth_Q8[b] ) - 8 * 128 );
278
        /* quality = sigmoid( 0.25 * ( SNR_dB - 16 ) ); */
279
695k
        psEncC->input_quality_bands_Q15[ b ] = silk_sigm_Q15( silk_RSHIFT( SNR_Q7 - 16 * 128, 4 ) );
280
695k
    }
281
282
173k
#ifdef OPUS_CHECK_ASM
283
173k
    silk_assert( ret == ret_c );
284
173k
    silk_assert( !memcmp( &psEncC_c, psEncC, sizeof( psEncC_c ) ) );
285
173k
#endif
286
287
173k
    RESTORE_STACK;
288
173k
    return( ret );
289
173k
}
silk_VAD_GetSA_Q8_sse4_1
Line
Count
Source
49
229k
{
50
229k
    opus_int   SA_Q15, pSNR_dB_Q7, input_tilt;
51
229k
    opus_int   decimated_framelength1, decimated_framelength2;
52
229k
    opus_int   decimated_framelength;
53
229k
    opus_int   dec_subframe_length, dec_subframe_offset, SNR_Q7, i, b, s;
54
229k
    opus_int32 sumSquared, smooth_coef_Q16;
55
229k
    opus_int16 HPstateTmp;
56
229k
    VARDECL( opus_int16, X );
57
229k
    opus_int32 Xnrg[ VAD_N_BANDS ];
58
229k
    opus_int32 NrgToNoiseRatio_Q8[ VAD_N_BANDS ];
59
229k
    opus_int32 speech_nrg, x_tmp;
60
229k
    opus_int   X_offset[ VAD_N_BANDS ];
61
229k
    opus_int   ret = 0;
62
229k
    silk_VAD_state *psSilk_VAD = &psEncC->sVAD;
63
64
229k
    SAVE_STACK;
65
66
#ifdef OPUS_CHECK_ASM
67
    silk_encoder_state psEncC_c;
68
    opus_int ret_c;
69
70
    silk_memcpy( &psEncC_c, psEncC, sizeof( psEncC_c ) );
71
    ret_c = silk_VAD_GetSA_Q8_c( &psEncC_c, pIn );
72
#endif
73
74
    /* Safety checks */
75
229k
    silk_assert( VAD_N_BANDS == 4 );
76
229k
    celt_assert( MAX_FRAME_LENGTH >= psEncC->frame_length );
77
229k
    celt_assert( psEncC->frame_length <= 512 );
78
229k
    celt_assert( psEncC->frame_length == 8 * silk_RSHIFT( psEncC->frame_length, 3 ) );
79
80
    /***********************/
81
    /* Filter and Decimate */
82
    /***********************/
83
229k
    decimated_framelength1 = silk_RSHIFT( psEncC->frame_length, 1 );
84
229k
    decimated_framelength2 = silk_RSHIFT( psEncC->frame_length, 2 );
85
229k
    decimated_framelength = silk_RSHIFT( psEncC->frame_length, 3 );
86
    /* Decimate into 4 bands:
87
       0       L      3L       L              3L                             5L
88
               -      --       -              --                             --
89
               8       8       2               4                              4
90
91
       [0-1 kHz| temp. |1-2 kHz|    2-4 kHz    |            4-8 kHz           |
92
93
       They're arranged to allow the minimal ( frame_length / 4 ) extra
94
       scratch space during the downsampling process */
95
229k
    X_offset[ 0 ] = 0;
96
229k
    X_offset[ 1 ] = decimated_framelength + decimated_framelength2;
97
229k
    X_offset[ 2 ] = X_offset[ 1 ] + decimated_framelength;
98
229k
    X_offset[ 3 ] = X_offset[ 2 ] + decimated_framelength2;
99
229k
    ALLOC( X, X_offset[ 3 ] + decimated_framelength1, opus_int16 );
100
101
    /* 0-8 kHz to 0-4 kHz and 4-8 kHz */
102
229k
    silk_ana_filt_bank_1( pIn, &psSilk_VAD->AnaState[  0 ],
103
229k
        X, &X[ X_offset[ 3 ] ], psEncC->frame_length );
104
105
    /* 0-4 kHz to 0-2 kHz and 2-4 kHz */
106
229k
    silk_ana_filt_bank_1( X, &psSilk_VAD->AnaState1[ 0 ],
107
229k
        X, &X[ X_offset[ 2 ] ], decimated_framelength1 );
108
109
    /* 0-2 kHz to 0-1 kHz and 1-2 kHz */
110
229k
    silk_ana_filt_bank_1( X, &psSilk_VAD->AnaState2[ 0 ],
111
229k
        X, &X[ X_offset[ 1 ] ], decimated_framelength2 );
112
113
    /*********************************************/
114
    /* HP filter on lowest band (differentiator) */
115
    /*********************************************/
116
229k
    X[ decimated_framelength - 1 ] = silk_RSHIFT( X[ decimated_framelength - 1 ], 1 );
117
229k
    HPstateTmp = X[ decimated_framelength - 1 ];
118
5.01M
    for( i = decimated_framelength - 1; i > 0; i-- ) {
119
4.78M
        X[ i - 1 ]  = silk_RSHIFT( X[ i - 1 ], 1 );
120
4.78M
        X[ i ]     -= X[ i - 1 ];
121
4.78M
    }
122
229k
    X[ 0 ] -= psSilk_VAD->HPstate;
123
229k
    psSilk_VAD->HPstate = HPstateTmp;
124
125
    /*************************************/
126
    /* Calculate the energy in each band */
127
    /*************************************/
128
1.14M
    for( b = 0; b < VAD_N_BANDS; b++ ) {
129
        /* Find the decimated framelength in the non-uniformly divided bands */
130
919k
        decimated_framelength = silk_RSHIFT( psEncC->frame_length, silk_min_int( VAD_N_BANDS - b, VAD_N_BANDS - 1 ) );
131
132
        /* Split length into subframe lengths */
133
919k
        dec_subframe_length = silk_RSHIFT( decimated_framelength, VAD_INTERNAL_SUBFRAMES_LOG2 );
134
919k
        dec_subframe_offset = 0;
135
136
        /* Compute energy per sub-frame */
137
        /* initialize with summed energy of last subframe */
138
919k
        Xnrg[ b ] = psSilk_VAD->XnrgSubfr[ b ];
139
4.59M
        for( s = 0; s < VAD_INTERNAL_SUBFRAMES; s++ ) {
140
3.67M
            __m128i xmm_X, xmm_acc;
141
3.67M
            sumSquared = 0;
142
143
3.67M
            xmm_acc = _mm_setzero_si128();
144
145
6.94M
            for( i = 0; i < dec_subframe_length - 7; i += 8 )
146
3.26M
            {
147
3.26M
                xmm_X   = _mm_loadu_si128( (__m128i *)(void*)&(X[ X_offset[ b ] + i + dec_subframe_offset ] ) );
148
3.26M
                xmm_X   = _mm_srai_epi16( xmm_X, 3 );
149
3.26M
                xmm_X   = _mm_madd_epi16( xmm_X, xmm_X );
150
3.26M
                xmm_acc = _mm_add_epi32( xmm_acc, xmm_X );
151
3.26M
            }
152
153
3.67M
            xmm_acc = _mm_add_epi32( xmm_acc, _mm_unpackhi_epi64( xmm_acc, xmm_acc ) );
154
3.67M
            xmm_acc = _mm_add_epi32( xmm_acc, _mm_shufflelo_epi16( xmm_acc, 0x0E ) );
155
156
3.67M
            sumSquared += _mm_cvtsi128_si32( xmm_acc );
157
158
17.3M
            for( ; i < dec_subframe_length; i++ ) {
159
                /* The energy will be less than dec_subframe_length * ( silk_int16_MIN / 8 ) ^ 2.            */
160
                /* Therefore we can accumulate with no risk of overflow (unless dec_subframe_length > 128)  */
161
13.6M
                x_tmp = silk_RSHIFT(
162
13.6M
                    X[ X_offset[ b ] + i + dec_subframe_offset ], 3 );
163
13.6M
                sumSquared = silk_SMLABB( sumSquared, x_tmp, x_tmp );
164
165
                /* Safety check */
166
13.6M
                silk_assert( sumSquared >= 0 );
167
13.6M
            }
168
169
            /* Add/saturate summed energy of current subframe */
170
3.67M
            if( s < VAD_INTERNAL_SUBFRAMES - 1 ) {
171
2.75M
                Xnrg[ b ] = silk_ADD_POS_SAT32( Xnrg[ b ], sumSquared );
172
2.75M
            } else {
173
                /* Look-ahead subframe */
174
919k
                Xnrg[ b ] = silk_ADD_POS_SAT32( Xnrg[ b ], silk_RSHIFT( sumSquared, 1 ) );
175
919k
            }
176
177
3.67M
            dec_subframe_offset += dec_subframe_length;
178
3.67M
        }
179
919k
        psSilk_VAD->XnrgSubfr[ b ] = sumSquared;
180
919k
    }
181
182
    /********************/
183
    /* Noise estimation */
184
    /********************/
185
229k
    silk_VAD_GetNoiseLevels( &Xnrg[ 0 ], psSilk_VAD );
186
187
    /***********************************************/
188
    /* Signal-plus-noise to noise ratio estimation */
189
    /***********************************************/
190
229k
    sumSquared = 0;
191
229k
    input_tilt = 0;
192
1.14M
    for( b = 0; b < VAD_N_BANDS; b++ ) {
193
919k
        speech_nrg = Xnrg[ b ] - psSilk_VAD->NL[ b ];
194
919k
        if( speech_nrg > 0 ) {
195
            /* Divide, with sufficient resolution */
196
668k
            if( ( Xnrg[ b ] & 0xFF800000 ) == 0 ) {
197
521k
                NrgToNoiseRatio_Q8[ b ] = silk_DIV32( silk_LSHIFT( Xnrg[ b ], 8 ), psSilk_VAD->NL[ b ] + 1 );
198
521k
            } else {
199
146k
                NrgToNoiseRatio_Q8[ b ] = silk_DIV32( Xnrg[ b ], silk_RSHIFT( psSilk_VAD->NL[ b ], 8 ) + 1 );
200
146k
            }
201
202
            /* Convert to log domain */
203
668k
            SNR_Q7 = silk_lin2log( NrgToNoiseRatio_Q8[ b ] ) - 8 * 128;
204
205
            /* Sum-of-squares */
206
668k
            sumSquared = silk_SMLABB( sumSquared, SNR_Q7, SNR_Q7 );          /* Q14 */
207
208
            /* Tilt measure */
209
668k
            if( speech_nrg < ( (opus_int32)1 << 20 ) ) {
210
                /* Scale down SNR value for small subband speech energies */
211
331k
                SNR_Q7 = silk_SMULWB( silk_LSHIFT( silk_SQRT_APPROX( speech_nrg ), 6 ), SNR_Q7 );
212
331k
            }
213
668k
            input_tilt = silk_SMLAWB( input_tilt, tiltWeights[ b ], SNR_Q7 );
214
668k
        } else {
215
250k
            NrgToNoiseRatio_Q8[ b ] = 256;
216
250k
        }
217
919k
    }
218
219
    /* Mean-of-squares */
220
229k
    sumSquared = silk_DIV32_16( sumSquared, VAD_N_BANDS ); /* Q14 */
221
222
    /* Root-mean-square approximation, scale to dBs, and write to output pointer */
223
229k
    pSNR_dB_Q7 = (opus_int16)( 3 * silk_SQRT_APPROX( sumSquared ) ); /* Q7 */
224
225
    /*********************************/
226
    /* Speech Probability Estimation */
227
    /*********************************/
228
229k
    SA_Q15 = silk_sigm_Q15( silk_SMULWB( VAD_SNR_FACTOR_Q16, pSNR_dB_Q7 ) - VAD_NEGATIVE_OFFSET_Q5 );
229
230
    /**************************/
231
    /* Frequency Tilt Measure */
232
    /**************************/
233
229k
    psEncC->input_tilt_Q15 = silk_LSHIFT( silk_sigm_Q15( input_tilt ) - 16384, 1 );
234
235
    /**************************************************/
236
    /* Scale the sigmoid output based on power levels */
237
    /**************************************************/
238
229k
    speech_nrg = 0;
239
1.14M
    for( b = 0; b < VAD_N_BANDS; b++ ) {
240
        /* Accumulate signal-without-noise energies, higher frequency bands have more weight */
241
919k
        speech_nrg += ( b + 1 ) * silk_RSHIFT( Xnrg[ b ] - psSilk_VAD->NL[ b ], 4 );
242
919k
    }
243
244
229k
    if( psEncC->frame_length == 20 * psEncC->fs_kHz ) {
245
173k
        speech_nrg = silk_RSHIFT32( speech_nrg, 1 );
246
173k
    }
247
    /* Power scaling */
248
229k
    if( speech_nrg <= 0 ) {
249
47.0k
        SA_Q15 = silk_RSHIFT( SA_Q15, 1 );
250
182k
    } else if( speech_nrg < 16384 ) {
251
23.1k
        speech_nrg = silk_LSHIFT32( speech_nrg, 16 );
252
253
        /* square-root */
254
23.1k
        speech_nrg = silk_SQRT_APPROX( speech_nrg );
255
23.1k
        SA_Q15 = silk_SMULWB( 32768 + speech_nrg, SA_Q15 );
256
23.1k
    }
257
258
    /* Copy the resulting speech activity in Q8 */
259
229k
    psEncC->speech_activity_Q8 = silk_min_int( silk_RSHIFT( SA_Q15, 7 ), silk_uint8_MAX );
260
261
    /***********************************/
262
    /* Energy Level and SNR estimation */
263
    /***********************************/
264
    /* Smoothing coefficient */
265
229k
    smooth_coef_Q16 = silk_SMULWB( VAD_SNR_SMOOTH_COEF_Q18, silk_SMULWB( (opus_int32)SA_Q15, SA_Q15 ) );
266
267
229k
    if( psEncC->frame_length == 10 * psEncC->fs_kHz ) {
268
56.1k
        smooth_coef_Q16 >>= 1;
269
56.1k
    }
270
271
1.14M
    for( b = 0; b < VAD_N_BANDS; b++ ) {
272
        /* compute smoothed energy-to-noise ratio per band */
273
919k
        psSilk_VAD->NrgRatioSmth_Q8[ b ] = silk_SMLAWB( psSilk_VAD->NrgRatioSmth_Q8[ b ],
274
919k
            NrgToNoiseRatio_Q8[ b ] - psSilk_VAD->NrgRatioSmth_Q8[ b ], smooth_coef_Q16 );
275
276
        /* signal to noise ratio in dB per band */
277
919k
        SNR_Q7 = 3 * ( silk_lin2log( psSilk_VAD->NrgRatioSmth_Q8[b] ) - 8 * 128 );
278
        /* quality = sigmoid( 0.25 * ( SNR_dB - 16 ) ); */
279
919k
        psEncC->input_quality_bands_Q15[ b ] = silk_sigm_Q15( silk_RSHIFT( SNR_Q7 - 16 * 128, 4 ) );
280
919k
    }
281
282
#ifdef OPUS_CHECK_ASM
283
    silk_assert( ret == ret_c );
284
    silk_assert( !memcmp( &psEncC_c, psEncC, sizeof( psEncC_c ) ) );
285
#endif
286
287
229k
    RESTORE_STACK;
288
229k
    return( ret );
289
229k
}