Coverage Report

Created: 2026-08-31 07:11

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
401k
{
50
401k
    opus_int   SA_Q15, pSNR_dB_Q7, input_tilt;
51
401k
    opus_int   decimated_framelength1, decimated_framelength2;
52
401k
    opus_int   decimated_framelength;
53
401k
    opus_int   dec_subframe_length, dec_subframe_offset, SNR_Q7, i, b, s;
54
401k
    opus_int32 sumSquared, smooth_coef_Q16;
55
401k
    opus_int16 HPstateTmp;
56
401k
    VARDECL( opus_int16, X );
57
401k
    opus_int32 Xnrg[ VAD_N_BANDS ];
58
401k
    opus_int32 NrgToNoiseRatio_Q8[ VAD_N_BANDS ];
59
401k
    opus_int32 speech_nrg, x_tmp;
60
401k
    opus_int   X_offset[ VAD_N_BANDS ];
61
401k
    opus_int   ret = 0;
62
401k
    silk_VAD_state *psSilk_VAD = &psEncC->sVAD;
63
64
401k
    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
401k
    silk_assert( VAD_N_BANDS == 4 );
76
401k
    celt_assert( MAX_FRAME_LENGTH >= psEncC->frame_length );
77
401k
    celt_assert( psEncC->frame_length <= 512 );
78
401k
    celt_assert( psEncC->frame_length == 8 * silk_RSHIFT( psEncC->frame_length, 3 ) );
79
80
    /***********************/
81
    /* Filter and Decimate */
82
    /***********************/
83
401k
    decimated_framelength1 = silk_RSHIFT( psEncC->frame_length, 1 );
84
401k
    decimated_framelength2 = silk_RSHIFT( psEncC->frame_length, 2 );
85
401k
    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
401k
    X_offset[ 0 ] = 0;
96
401k
    X_offset[ 1 ] = decimated_framelength + decimated_framelength2;
97
401k
    X_offset[ 2 ] = X_offset[ 1 ] + decimated_framelength;
98
401k
    X_offset[ 3 ] = X_offset[ 2 ] + decimated_framelength2;
99
401k
    ALLOC( X, X_offset[ 3 ] + decimated_framelength1, opus_int16 );
100
101
    /* 0-8 kHz to 0-4 kHz and 4-8 kHz */
102
401k
    silk_ana_filt_bank_1( pIn, &psSilk_VAD->AnaState[  0 ],
103
401k
        X, &X[ X_offset[ 3 ] ], psEncC->frame_length );
104
105
    /* 0-4 kHz to 0-2 kHz and 2-4 kHz */
106
401k
    silk_ana_filt_bank_1( X, &psSilk_VAD->AnaState1[ 0 ],
107
401k
        X, &X[ X_offset[ 2 ] ], decimated_framelength1 );
108
109
    /* 0-2 kHz to 0-1 kHz and 1-2 kHz */
110
401k
    silk_ana_filt_bank_1( X, &psSilk_VAD->AnaState2[ 0 ],
111
401k
        X, &X[ X_offset[ 1 ] ], decimated_framelength2 );
112
113
    /*********************************************/
114
    /* HP filter on lowest band (differentiator) */
115
    /*********************************************/
116
401k
    X[ decimated_framelength - 1 ] = silk_RSHIFT( X[ decimated_framelength - 1 ], 1 );
117
401k
    HPstateTmp = X[ decimated_framelength - 1 ];
118
8.69M
    for( i = decimated_framelength - 1; i > 0; i-- ) {
119
8.29M
        X[ i - 1 ]  = silk_RSHIFT( X[ i - 1 ], 1 );
120
8.29M
        X[ i ]     -= X[ i - 1 ];
121
8.29M
    }
122
401k
    X[ 0 ] -= psSilk_VAD->HPstate;
123
401k
    psSilk_VAD->HPstate = HPstateTmp;
124
125
    /*************************************/
126
    /* Calculate the energy in each band */
127
    /*************************************/
128
2.00M
    for( b = 0; b < VAD_N_BANDS; b++ ) {
129
        /* Find the decimated framelength in the non-uniformly divided bands */
130
1.60M
        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.60M
        dec_subframe_length = silk_RSHIFT( decimated_framelength, VAD_INTERNAL_SUBFRAMES_LOG2 );
134
1.60M
        dec_subframe_offset = 0;
135
136
        /* Compute energy per sub-frame */
137
        /* initialize with summed energy of last subframe */
138
1.60M
        Xnrg[ b ] = psSilk_VAD->XnrgSubfr[ b ];
139
8.03M
        for( s = 0; s < VAD_INTERNAL_SUBFRAMES; s++ ) {
140
6.43M
            __m128i xmm_X, xmm_acc;
141
6.43M
            sumSquared = 0;
142
143
6.43M
            xmm_acc = _mm_setzero_si128();
144
145
12.0M
            for( i = 0; i < dec_subframe_length - 7; i += 8 )
146
5.66M
            {
147
5.66M
                xmm_X   = _mm_loadu_si128( (__m128i *)(void*)&(X[ X_offset[ b ] + i + dec_subframe_offset ] ) );
148
5.66M
                xmm_X   = _mm_srai_epi16( xmm_X, 3 );
149
5.66M
                xmm_X   = _mm_madd_epi16( xmm_X, xmm_X );
150
5.66M
                xmm_acc = _mm_add_epi32( xmm_acc, xmm_X );
151
5.66M
            }
152
153
6.43M
            xmm_acc = _mm_add_epi32( xmm_acc, _mm_unpackhi_epi64( xmm_acc, xmm_acc ) );
154
6.43M
            xmm_acc = _mm_add_epi32( xmm_acc, _mm_shufflelo_epi16( xmm_acc, 0x0E ) );
155
156
6.43M
            sumSquared += _mm_cvtsi128_si32( xmm_acc );
157
158
30.2M
            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.7M
                x_tmp = silk_RSHIFT(
162
23.7M
                    X[ X_offset[ b ] + i + dec_subframe_offset ], 3 );
163
23.7M
                sumSquared = silk_SMLABB( sumSquared, x_tmp, x_tmp );
164
165
                /* Safety check */
166
23.7M
                silk_assert( sumSquared >= 0 );
167
23.7M
            }
168
169
            /* Add/saturate summed energy of current subframe */
170
6.43M
            if( s < VAD_INTERNAL_SUBFRAMES - 1 ) {
171
4.82M
                Xnrg[ b ] = silk_ADD_POS_SAT32( Xnrg[ b ], sumSquared );
172
4.82M
            } else {
173
                /* Look-ahead subframe */
174
1.60M
                Xnrg[ b ] = silk_ADD_POS_SAT32( Xnrg[ b ], silk_RSHIFT( sumSquared, 1 ) );
175
1.60M
            }
176
177
6.43M
            dec_subframe_offset += dec_subframe_length;
178
6.43M
        }
179
1.60M
        psSilk_VAD->XnrgSubfr[ b ] = sumSquared;
180
1.60M
    }
181
182
    /********************/
183
    /* Noise estimation */
184
    /********************/
185
401k
    silk_VAD_GetNoiseLevels( &Xnrg[ 0 ], psSilk_VAD );
186
187
    /***********************************************/
188
    /* Signal-plus-noise to noise ratio estimation */
189
    /***********************************************/
190
228k
    sumSquared = 0;
191
228k
    input_tilt = 0;
192
2.00M
    for( b = 0; b < VAD_N_BANDS; b++ ) {
193
1.60M
        speech_nrg = Xnrg[ b ] - psSilk_VAD->NL[ b ];
194
1.60M
        if( speech_nrg > 0 ) {
195
            /* Divide, with sufficient resolution */
196
1.15M
            if( ( Xnrg[ b ] & 0xFF800000 ) == 0 ) {
197
907k
                NrgToNoiseRatio_Q8[ b ] = silk_DIV32( silk_LSHIFT( Xnrg[ b ], 8 ), psSilk_VAD->NL[ b ] + 1 );
198
907k
            } else {
199
247k
                NrgToNoiseRatio_Q8[ b ] = silk_DIV32( Xnrg[ b ], silk_RSHIFT( psSilk_VAD->NL[ b ], 8 ) + 1 );
200
247k
            }
201
202
            /* Convert to log domain */
203
1.15M
            SNR_Q7 = silk_lin2log( NrgToNoiseRatio_Q8[ b ] ) - 8 * 128;
204
205
            /* Sum-of-squares */
206
1.15M
            sumSquared = silk_SMLABB( sumSquared, SNR_Q7, SNR_Q7 );          /* Q14 */
207
208
            /* Tilt measure */
209
1.15M
            if( speech_nrg < ( (opus_int32)1 << 20 ) ) {
210
                /* Scale down SNR value for small subband speech energies */
211
582k
                SNR_Q7 = silk_SMULWB( silk_LSHIFT( silk_SQRT_APPROX( speech_nrg ), 6 ), SNR_Q7 );
212
582k
            }
213
1.15M
            input_tilt = silk_SMLAWB( input_tilt, tiltWeights[ b ], SNR_Q7 );
214
1.15M
        } else {
215
451k
            NrgToNoiseRatio_Q8[ b ] = 256;
216
451k
        }
217
1.60M
    }
218
219
    /* Mean-of-squares */
220
401k
    sumSquared = silk_DIV32_16( sumSquared, VAD_N_BANDS ); /* Q14 */
221
222
    /* Root-mean-square approximation, scale to dBs, and write to output pointer */
223
228k
    pSNR_dB_Q7 = (opus_int16)( 3 * silk_SQRT_APPROX( sumSquared ) ); /* Q7 */
224
225
    /*********************************/
226
    /* Speech Probability Estimation */
227
    /*********************************/
228
401k
    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
401k
    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
228k
    speech_nrg = 0;
239
2.00M
    for( b = 0; b < VAD_N_BANDS; b++ ) {
240
        /* Accumulate signal-without-noise energies, higher frequency bands have more weight */
241
1.60M
        speech_nrg += ( b + 1 ) * silk_RSHIFT( Xnrg[ b ] - psSilk_VAD->NL[ b ], 4 );
242
1.60M
    }
243
244
401k
    if( psEncC->frame_length == 20 * psEncC->fs_kHz ) {
245
304k
        speech_nrg = silk_RSHIFT32( speech_nrg, 1 );
246
304k
    }
247
    /* Power scaling */
248
401k
    if( speech_nrg <= 0 ) {
249
85.1k
        SA_Q15 = silk_RSHIFT( SA_Q15, 1 );
250
316k
    } 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
401k
    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
401k
    smooth_coef_Q16 = silk_SMULWB( VAD_SNR_SMOOTH_COEF_Q18, silk_SMULWB( (opus_int32)SA_Q15, SA_Q15 ) );
266
267
401k
    if( psEncC->frame_length == 10 * psEncC->fs_kHz ) {
268
97.1k
        smooth_coef_Q16 >>= 1;
269
97.1k
    }
270
271
2.00M
    for( b = 0; b < VAD_N_BANDS; b++ ) {
272
        /* compute smoothed energy-to-noise ratio per band */
273
1.60M
        psSilk_VAD->NrgRatioSmth_Q8[ b ] = silk_SMLAWB( psSilk_VAD->NrgRatioSmth_Q8[ b ],
274
1.60M
            NrgToNoiseRatio_Q8[ b ] - psSilk_VAD->NrgRatioSmth_Q8[ b ], smooth_coef_Q16 );
275
276
        /* signal to noise ratio in dB per band */
277
1.60M
        SNR_Q7 = 3 * ( silk_lin2log( psSilk_VAD->NrgRatioSmth_Q8[b] ) - 8 * 128 );
278
        /* quality = sigmoid( 0.25 * ( SNR_dB - 16 ) ); */
279
1.60M
        psEncC->input_quality_bands_Q15[ b ] = silk_sigm_Q15( silk_RSHIFT( SNR_Q7 - 16 * 128, 4 ) );
280
1.60M
    }
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.69M
    for( i = decimated_framelength - 1; i > 0; i-- ) {
119
3.52M
        X[ i - 1 ]  = silk_RSHIFT( X[ i - 1 ], 1 );
120
3.52M
        X[ i ]     -= X[ i - 1 ];
121
3.52M
    }
122
173k
    X[ 0 ] -= psSilk_VAD->HPstate;
123
173k
    psSilk_VAD->HPstate = HPstateTmp;
124
125
    /*************************************/
126
    /* Calculate the energy in each band */
127
    /*************************************/
128
865k
    for( b = 0; b < VAD_N_BANDS; b++ ) {
129
        /* Find the decimated framelength in the non-uniformly divided bands */
130
692k
        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
692k
        dec_subframe_length = silk_RSHIFT( decimated_framelength, VAD_INTERNAL_SUBFRAMES_LOG2 );
134
692k
        dec_subframe_offset = 0;
135
136
        /* Compute energy per sub-frame */
137
        /* initialize with summed energy of last subframe */
138
692k
        Xnrg[ b ] = psSilk_VAD->XnrgSubfr[ b ];
139
3.46M
        for( s = 0; s < VAD_INTERNAL_SUBFRAMES; s++ ) {
140
2.77M
            __m128i xmm_X, xmm_acc;
141
2.77M
            sumSquared = 0;
142
143
2.77M
            xmm_acc = _mm_setzero_si128();
144
145
5.17M
            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.77M
            xmm_acc = _mm_add_epi32( xmm_acc, _mm_unpackhi_epi64( xmm_acc, xmm_acc ) );
154
2.77M
            xmm_acc = _mm_add_epi32( xmm_acc, _mm_shufflelo_epi16( xmm_acc, 0x0E ) );
155
156
2.77M
            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.1M
                x_tmp = silk_RSHIFT(
162
10.1M
                    X[ X_offset[ b ] + i + dec_subframe_offset ], 3 );
163
10.1M
                sumSquared = silk_SMLABB( sumSquared, x_tmp, x_tmp );
164
165
                /* Safety check */
166
10.1M
                silk_assert( sumSquared >= 0 );
167
10.1M
            }
168
169
            /* Add/saturate summed energy of current subframe */
170
2.77M
            if( s < VAD_INTERNAL_SUBFRAMES - 1 ) {
171
2.07M
                Xnrg[ b ] = silk_ADD_POS_SAT32( Xnrg[ b ], sumSquared );
172
2.07M
            } else {
173
                /* Look-ahead subframe */
174
692k
                Xnrg[ b ] = silk_ADD_POS_SAT32( Xnrg[ b ], silk_RSHIFT( sumSquared, 1 ) );
175
692k
            }
176
177
2.77M
            dec_subframe_offset += dec_subframe_length;
178
2.77M
        }
179
692k
        psSilk_VAD->XnrgSubfr[ b ] = sumSquared;
180
692k
    }
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
865k
    for( b = 0; b < VAD_N_BANDS; b++ ) {
193
692k
        speech_nrg = Xnrg[ b ] - psSilk_VAD->NL[ b ];
194
692k
        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
252k
                SNR_Q7 = silk_SMULWB( silk_LSHIFT( silk_SQRT_APPROX( speech_nrg ), 6 ), SNR_Q7 );
212
252k
            }
213
491k
            input_tilt = silk_SMLAWB( input_tilt, tiltWeights[ b ], SNR_Q7 );
214
491k
        } else {
215
201k
            NrgToNoiseRatio_Q8[ b ] = 256;
216
201k
        }
217
692k
    }
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
865k
    for( b = 0; b < VAD_N_BANDS; b++ ) {
240
        /* Accumulate signal-without-noise energies, higher frequency bands have more weight */
241
692k
        speech_nrg += ( b + 1 ) * silk_RSHIFT( Xnrg[ b ] - psSilk_VAD->NL[ b ], 4 );
242
692k
    }
243
244
173k
    if( psEncC->frame_length == 20 * psEncC->fs_kHz ) {
245
131k
        speech_nrg = silk_RSHIFT32( speech_nrg, 1 );
246
131k
    }
247
    /* Power scaling */
248
173k
    if( speech_nrg <= 0 ) {
249
38.1k
        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.2k
        smooth_coef_Q16 >>= 1;
269
41.2k
    }
270
271
865k
    for( b = 0; b < VAD_N_BANDS; b++ ) {
272
        /* compute smoothed energy-to-noise ratio per band */
273
692k
        psSilk_VAD->NrgRatioSmth_Q8[ b ] = silk_SMLAWB( psSilk_VAD->NrgRatioSmth_Q8[ b ],
274
692k
            NrgToNoiseRatio_Q8[ b ] - psSilk_VAD->NrgRatioSmth_Q8[ b ], smooth_coef_Q16 );
275
276
        /* signal to noise ratio in dB per band */
277
692k
        SNR_Q7 = 3 * ( silk_lin2log( psSilk_VAD->NrgRatioSmth_Q8[b] ) - 8 * 128 );
278
        /* quality = sigmoid( 0.25 * ( SNR_dB - 16 ) ); */
279
692k
        psEncC->input_quality_bands_Q15[ b ] = silk_sigm_Q15( silk_RSHIFT( SNR_Q7 - 16 * 128, 4 ) );
280
692k
    }
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
228k
{
50
228k
    opus_int   SA_Q15, pSNR_dB_Q7, input_tilt;
51
228k
    opus_int   decimated_framelength1, decimated_framelength2;
52
228k
    opus_int   decimated_framelength;
53
228k
    opus_int   dec_subframe_length, dec_subframe_offset, SNR_Q7, i, b, s;
54
228k
    opus_int32 sumSquared, smooth_coef_Q16;
55
228k
    opus_int16 HPstateTmp;
56
228k
    VARDECL( opus_int16, X );
57
228k
    opus_int32 Xnrg[ VAD_N_BANDS ];
58
228k
    opus_int32 NrgToNoiseRatio_Q8[ VAD_N_BANDS ];
59
228k
    opus_int32 speech_nrg, x_tmp;
60
228k
    opus_int   X_offset[ VAD_N_BANDS ];
61
228k
    opus_int   ret = 0;
62
228k
    silk_VAD_state *psSilk_VAD = &psEncC->sVAD;
63
64
228k
    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
228k
    silk_assert( VAD_N_BANDS == 4 );
76
228k
    celt_assert( MAX_FRAME_LENGTH >= psEncC->frame_length );
77
228k
    celt_assert( psEncC->frame_length <= 512 );
78
228k
    celt_assert( psEncC->frame_length == 8 * silk_RSHIFT( psEncC->frame_length, 3 ) );
79
80
    /***********************/
81
    /* Filter and Decimate */
82
    /***********************/
83
228k
    decimated_framelength1 = silk_RSHIFT( psEncC->frame_length, 1 );
84
228k
    decimated_framelength2 = silk_RSHIFT( psEncC->frame_length, 2 );
85
228k
    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
228k
    X_offset[ 0 ] = 0;
96
228k
    X_offset[ 1 ] = decimated_framelength + decimated_framelength2;
97
228k
    X_offset[ 2 ] = X_offset[ 1 ] + decimated_framelength;
98
228k
    X_offset[ 3 ] = X_offset[ 2 ] + decimated_framelength2;
99
228k
    ALLOC( X, X_offset[ 3 ] + decimated_framelength1, opus_int16 );
100
101
    /* 0-8 kHz to 0-4 kHz and 4-8 kHz */
102
228k
    silk_ana_filt_bank_1( pIn, &psSilk_VAD->AnaState[  0 ],
103
228k
        X, &X[ X_offset[ 3 ] ], psEncC->frame_length );
104
105
    /* 0-4 kHz to 0-2 kHz and 2-4 kHz */
106
228k
    silk_ana_filt_bank_1( X, &psSilk_VAD->AnaState1[ 0 ],
107
228k
        X, &X[ X_offset[ 2 ] ], decimated_framelength1 );
108
109
    /* 0-2 kHz to 0-1 kHz and 1-2 kHz */
110
228k
    silk_ana_filt_bank_1( X, &psSilk_VAD->AnaState2[ 0 ],
111
228k
        X, &X[ X_offset[ 1 ] ], decimated_framelength2 );
112
113
    /*********************************************/
114
    /* HP filter on lowest band (differentiator) */
115
    /*********************************************/
116
228k
    X[ decimated_framelength - 1 ] = silk_RSHIFT( X[ decimated_framelength - 1 ], 1 );
117
228k
    HPstateTmp = X[ decimated_framelength - 1 ];
118
5.00M
    for( i = decimated_framelength - 1; i > 0; i-- ) {
119
4.77M
        X[ i - 1 ]  = silk_RSHIFT( X[ i - 1 ], 1 );
120
4.77M
        X[ i ]     -= X[ i - 1 ];
121
4.77M
    }
122
228k
    X[ 0 ] -= psSilk_VAD->HPstate;
123
228k
    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
914k
        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
914k
        dec_subframe_length = silk_RSHIFT( decimated_framelength, VAD_INTERNAL_SUBFRAMES_LOG2 );
134
914k
        dec_subframe_offset = 0;
135
136
        /* Compute energy per sub-frame */
137
        /* initialize with summed energy of last subframe */
138
914k
        Xnrg[ b ] = psSilk_VAD->XnrgSubfr[ b ];
139
4.57M
        for( s = 0; s < VAD_INTERNAL_SUBFRAMES; s++ ) {
140
3.65M
            __m128i xmm_X, xmm_acc;
141
3.65M
            sumSquared = 0;
142
143
3.65M
            xmm_acc = _mm_setzero_si128();
144
145
6.92M
            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.65M
            xmm_acc = _mm_add_epi32( xmm_acc, _mm_unpackhi_epi64( xmm_acc, xmm_acc ) );
154
3.65M
            xmm_acc = _mm_add_epi32( xmm_acc, _mm_shufflelo_epi16( xmm_acc, 0x0E ) );
155
156
3.65M
            sumSquared += _mm_cvtsi128_si32( xmm_acc );
157
158
17.2M
            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.65M
            if( s < VAD_INTERNAL_SUBFRAMES - 1 ) {
171
2.74M
                Xnrg[ b ] = silk_ADD_POS_SAT32( Xnrg[ b ], sumSquared );
172
2.74M
            } else {
173
                /* Look-ahead subframe */
174
914k
                Xnrg[ b ] = silk_ADD_POS_SAT32( Xnrg[ b ], silk_RSHIFT( sumSquared, 1 ) );
175
914k
            }
176
177
3.65M
            dec_subframe_offset += dec_subframe_length;
178
3.65M
        }
179
914k
        psSilk_VAD->XnrgSubfr[ b ] = sumSquared;
180
914k
    }
181
182
    /********************/
183
    /* Noise estimation */
184
    /********************/
185
228k
    silk_VAD_GetNoiseLevels( &Xnrg[ 0 ], psSilk_VAD );
186
187
    /***********************************************/
188
    /* Signal-plus-noise to noise ratio estimation */
189
    /***********************************************/
190
228k
    sumSquared = 0;
191
228k
    input_tilt = 0;
192
1.14M
    for( b = 0; b < VAD_N_BANDS; b++ ) {
193
914k
        speech_nrg = Xnrg[ b ] - psSilk_VAD->NL[ b ];
194
914k
        if( speech_nrg > 0 ) {
195
            /* Divide, with sufficient resolution */
196
664k
            if( ( Xnrg[ b ] & 0xFF800000 ) == 0 ) {
197
518k
                NrgToNoiseRatio_Q8[ b ] = silk_DIV32( silk_LSHIFT( Xnrg[ b ], 8 ), psSilk_VAD->NL[ b ] + 1 );
198
518k
            } else {
199
145k
                NrgToNoiseRatio_Q8[ b ] = silk_DIV32( Xnrg[ b ], silk_RSHIFT( psSilk_VAD->NL[ b ], 8 ) + 1 );
200
145k
            }
201
202
            /* Convert to log domain */
203
664k
            SNR_Q7 = silk_lin2log( NrgToNoiseRatio_Q8[ b ] ) - 8 * 128;
204
205
            /* Sum-of-squares */
206
664k
            sumSquared = silk_SMLABB( sumSquared, SNR_Q7, SNR_Q7 );          /* Q14 */
207
208
            /* Tilt measure */
209
664k
            if( speech_nrg < ( (opus_int32)1 << 20 ) ) {
210
                /* Scale down SNR value for small subband speech energies */
211
329k
                SNR_Q7 = silk_SMULWB( silk_LSHIFT( silk_SQRT_APPROX( speech_nrg ), 6 ), SNR_Q7 );
212
329k
            }
213
664k
            input_tilt = silk_SMLAWB( input_tilt, tiltWeights[ b ], SNR_Q7 );
214
664k
        } else {
215
250k
            NrgToNoiseRatio_Q8[ b ] = 256;
216
250k
        }
217
914k
    }
218
219
    /* Mean-of-squares */
220
228k
    sumSquared = silk_DIV32_16( sumSquared, VAD_N_BANDS ); /* Q14 */
221
222
    /* Root-mean-square approximation, scale to dBs, and write to output pointer */
223
228k
    pSNR_dB_Q7 = (opus_int16)( 3 * silk_SQRT_APPROX( sumSquared ) ); /* Q7 */
224
225
    /*********************************/
226
    /* Speech Probability Estimation */
227
    /*********************************/
228
228k
    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
228k
    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
228k
    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
914k
        speech_nrg += ( b + 1 ) * silk_RSHIFT( Xnrg[ b ] - psSilk_VAD->NL[ b ], 4 );
242
914k
    }
243
244
228k
    if( psEncC->frame_length == 20 * psEncC->fs_kHz ) {
245
172k
        speech_nrg = silk_RSHIFT32( speech_nrg, 1 );
246
172k
    }
247
    /* Power scaling */
248
228k
    if( speech_nrg <= 0 ) {
249
47.0k
        SA_Q15 = silk_RSHIFT( SA_Q15, 1 );
250
181k
    } else if( speech_nrg < 16384 ) {
251
23.2k
        speech_nrg = silk_LSHIFT32( speech_nrg, 16 );
252
253
        /* square-root */
254
23.2k
        speech_nrg = silk_SQRT_APPROX( speech_nrg );
255
23.2k
        SA_Q15 = silk_SMULWB( 32768 + speech_nrg, SA_Q15 );
256
23.2k
    }
257
258
    /* Copy the resulting speech activity in Q8 */
259
228k
    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
228k
    smooth_coef_Q16 = silk_SMULWB( VAD_SNR_SMOOTH_COEF_Q18, silk_SMULWB( (opus_int32)SA_Q15, SA_Q15 ) );
266
267
228k
    if( psEncC->frame_length == 10 * psEncC->fs_kHz ) {
268
55.8k
        smooth_coef_Q16 >>= 1;
269
55.8k
    }
270
271
1.14M
    for( b = 0; b < VAD_N_BANDS; b++ ) {
272
        /* compute smoothed energy-to-noise ratio per band */
273
914k
        psSilk_VAD->NrgRatioSmth_Q8[ b ] = silk_SMLAWB( psSilk_VAD->NrgRatioSmth_Q8[ b ],
274
914k
            NrgToNoiseRatio_Q8[ b ] - psSilk_VAD->NrgRatioSmth_Q8[ b ], smooth_coef_Q16 );
275
276
        /* signal to noise ratio in dB per band */
277
914k
        SNR_Q7 = 3 * ( silk_lin2log( psSilk_VAD->NrgRatioSmth_Q8[b] ) - 8 * 128 );
278
        /* quality = sigmoid( 0.25 * ( SNR_dB - 16 ) ); */
279
914k
        psEncC->input_quality_bands_Q15[ b ] = silk_sigm_Q15( silk_RSHIFT( SNR_Q7 - 16 * 128, 4 ) );
280
914k
    }
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
228k
    RESTORE_STACK;
288
228k
    return( ret );
289
228k
}