Coverage Report

Created: 2026-06-10 07:10

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/opus/silk/fixed/noise_shape_analysis_FIX.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_FIX.h"
33
#include "stack_alloc.h"
34
#include "tuning_parameters.h"
35
36
/* Compute gain to make warped filter coefficients have a zero mean log frequency response on a   */
37
/* non-warped frequency scale. (So that it can be implemented with a minimum-phase monic filter.) */
38
/* Note: A monic filter is one with the first coefficient equal to 1.0. In Silk we omit the first */
39
/* coefficient in an array of coefficients, for monic filters.                                    */
40
static OPUS_INLINE opus_int32 warped_gain( /* gain in Q16*/
41
    const opus_int32     *coefs_Q24,
42
    opus_int             lambda_Q16,
43
    opus_int             order
44
15.3M
) {
45
15.3M
    opus_int   i;
46
15.3M
    opus_int32 gain_Q24;
47
48
15.3M
    lambda_Q16 = -lambda_Q16;
49
15.3M
    gain_Q24 = coefs_Q24[ order - 1 ];
50
278M
    for( i = order - 2; i >= 0; i-- ) {
51
262M
        gain_Q24 = silk_SMLAWB( coefs_Q24[ i ], gain_Q24, lambda_Q16 );
52
262M
    }
53
15.3M
    gain_Q24  = silk_SMLAWB( SILK_FIX_CONST( 1.0, 24 ), gain_Q24, -lambda_Q16 );
54
15.3M
    return silk_INVERSE32_varQ( gain_Q24, 40 );
55
15.3M
}
56
57
/* Convert warped filter coefficients to monic pseudo-warped coefficients and limit maximum     */
58
/* amplitude of monic warped coefficients by using bandwidth expansion on the true coefficients */
59
static OPUS_INLINE void limit_warped_coefs(
60
    opus_int32           *coefs_Q24,
61
    opus_int             lambda_Q16,
62
    opus_int32           limit_Q24,
63
    opus_int             order
64
15.3M
) {
65
15.3M
    opus_int   i, iter, ind = 0;
66
15.3M
    opus_int32 tmp, maxabs_Q24, chirp_Q16, gain_Q16;
67
15.3M
    opus_int32 nom_Q16, den_Q24;
68
15.3M
    opus_int32 limit_Q20, maxabs_Q20;
69
70
    /* Convert to monic coefficients */
71
15.3M
    lambda_Q16 = -lambda_Q16;
72
278M
    for( i = order - 1; i > 0; i-- ) {
73
262M
        coefs_Q24[ i - 1 ] = silk_SMLAWB( coefs_Q24[ i - 1 ], coefs_Q24[ i ], lambda_Q16 );
74
262M
    }
75
15.3M
    lambda_Q16 = -lambda_Q16;
76
15.3M
    nom_Q16  = silk_SMLAWB( SILK_FIX_CONST( 1.0, 16 ), -(opus_int32)lambda_Q16, lambda_Q16 );
77
15.3M
    den_Q24  = silk_SMLAWB( SILK_FIX_CONST( 1.0, 24 ), coefs_Q24[ 0 ], lambda_Q16 );
78
15.3M
    gain_Q16 = silk_DIV32_varQ( nom_Q16, den_Q24, 24 );
79
293M
    for( i = 0; i < order; i++ ) {
80
278M
        coefs_Q24[ i ] = silk_SMULWW( gain_Q16, coefs_Q24[ i ] );
81
278M
    }
82
15.3M
    limit_Q20 = silk_RSHIFT(limit_Q24, 4);
83
15.3M
    for( iter = 0; iter < 10; iter++ ) {
84
        /* Find maximum absolute value */
85
15.3M
        maxabs_Q24 = -1;
86
293M
        for( i = 0; i < order; i++ ) {
87
278M
            tmp = silk_abs_int32( coefs_Q24[ i ] );
88
278M
            if( tmp > maxabs_Q24 ) {
89
15.8M
                maxabs_Q24 = tmp;
90
15.8M
                ind = i;
91
15.8M
            }
92
278M
        }
93
        /* Use Q20 to avoid any overflow when multiplying by (ind + 1) later. */
94
15.3M
        maxabs_Q20 = silk_RSHIFT(maxabs_Q24, 4);
95
15.3M
        if( maxabs_Q20 <= limit_Q20 ) {
96
            /* Coefficients are within range - done */
97
15.3M
            return;
98
15.3M
        }
99
100
        /* Convert back to true warped coefficients */
101
62.3k
        for( i = 1; i < order; i++ ) {
102
59.6k
            coefs_Q24[ i - 1 ] = silk_SMLAWB( coefs_Q24[ i - 1 ], coefs_Q24[ i ], lambda_Q16 );
103
59.6k
        }
104
2.71k
        gain_Q16 = silk_INVERSE32_varQ( gain_Q16, 32 );
105
65.1k
        for( i = 0; i < order; i++ ) {
106
62.3k
            coefs_Q24[ i ] = silk_SMULWW( gain_Q16, coefs_Q24[ i ] );
107
62.3k
        }
108
109
        /* Apply bandwidth expansion */
110
2.71k
        chirp_Q16 = SILK_FIX_CONST( 0.99, 16 ) - silk_DIV32_varQ(
111
2.71k
            silk_SMULWB( maxabs_Q20 - limit_Q20, silk_SMLABB( SILK_FIX_CONST( 0.8, 10 ), SILK_FIX_CONST( 0.1, 10 ), iter ) ),
112
2.71k
            silk_MUL( maxabs_Q20, ind + 1 ), 22 );
113
2.71k
        silk_bwexpander_32( coefs_Q24, order, chirp_Q16 );
114
115
        /* Convert to monic warped coefficients */
116
2.71k
        lambda_Q16 = -lambda_Q16;
117
62.3k
        for( i = order - 1; i > 0; i-- ) {
118
59.6k
            coefs_Q24[ i - 1 ] = silk_SMLAWB( coefs_Q24[ i - 1 ], coefs_Q24[ i ], lambda_Q16 );
119
59.6k
        }
120
2.71k
        lambda_Q16 = -lambda_Q16;
121
2.71k
        nom_Q16  = silk_SMLAWB( SILK_FIX_CONST( 1.0, 16 ), -(opus_int32)lambda_Q16,        lambda_Q16 );
122
2.71k
        den_Q24  = silk_SMLAWB( SILK_FIX_CONST( 1.0, 24 ), coefs_Q24[ 0 ], lambda_Q16 );
123
2.71k
        gain_Q16 = silk_DIV32_varQ( nom_Q16, den_Q24, 24 );
124
65.1k
        for( i = 0; i < order; i++ ) {
125
62.3k
            coefs_Q24[ i ] = silk_SMULWW( gain_Q16, coefs_Q24[ i ] );
126
62.3k
        }
127
2.71k
    }
128
0
    silk_assert( 0 );
129
0
}
130
131
/**************************************************************/
132
/* Compute noise shaping coefficients and initial gain values */
133
/**************************************************************/
134
void silk_noise_shape_analysis_FIX(
135
    silk_encoder_state_FIX          *psEnc,                                 /* I/O  Encoder state FIX                                                           */
136
    silk_encoder_control_FIX        *psEncCtrl,                             /* I/O  Encoder control FIX                                                         */
137
    const opus_int16                *pitch_res,                             /* I    LPC residual from pitch analysis                                            */
138
    const opus_int16                *x,                                     /* I    Input signal [ frame_length + la_shape ]                                    */
139
    int                              arch                                   /* I    Run-time architecture                                                       */
140
)
141
23.8M
{
142
23.8M
    silk_shape_state_FIX *psShapeSt = &psEnc->sShape;
143
23.8M
    opus_int     k, i, nSamples, nSegs, Qnrg, b_Q14, warping_Q16, scale = 0;
144
23.8M
    opus_int32   SNR_adj_dB_Q7, HarmShapeGain_Q16, Tilt_Q16, tmp32;
145
23.8M
    opus_int32   nrg, log_energy_Q7, log_energy_prev_Q7, energy_variation_Q7;
146
23.8M
    opus_int32   BWExp_Q16, gain_mult_Q16, gain_add_Q16, strength_Q16, b_Q8;
147
23.8M
    opus_int32   auto_corr[     MAX_SHAPE_LPC_ORDER + 1 ];
148
23.8M
    opus_int32   refl_coef_Q16[ MAX_SHAPE_LPC_ORDER ];
149
23.8M
    opus_int32   AR_Q24[       MAX_SHAPE_LPC_ORDER ];
150
23.8M
    VARDECL( opus_int16, x_windowed );
151
23.8M
    const opus_int16 *x_ptr, *pitch_res_ptr;
152
23.8M
    SAVE_STACK;
153
154
    /* Point to start of first LPC analysis block */
155
23.8M
    x_ptr = x - psEnc->sCmn.la_shape;
156
157
    /****************/
158
    /* GAIN CONTROL */
159
    /****************/
160
23.8M
    SNR_adj_dB_Q7 = psEnc->sCmn.SNR_dB_Q7;
161
162
    /* Input quality is the average of the quality in the lowest two VAD bands */
163
23.8M
    psEncCtrl->input_quality_Q14 = ( opus_int )silk_RSHIFT( (opus_int32)psEnc->sCmn.input_quality_bands_Q15[ 0 ]
164
23.8M
        + psEnc->sCmn.input_quality_bands_Q15[ 1 ], 2 );
165
166
    /* Coding quality level, between 0.0_Q0 and 1.0_Q0, but in Q14 */
167
23.8M
    psEncCtrl->coding_quality_Q14 = silk_RSHIFT( silk_sigm_Q15( silk_RSHIFT_ROUND( SNR_adj_dB_Q7 -
168
23.8M
        SILK_FIX_CONST( 20.0, 7 ), 4 ) ), 1 );
169
170
    /* Reduce coding SNR during low speech activity */
171
23.8M
    if( psEnc->sCmn.useCBR == 0 ) {
172
7.42M
        b_Q8 = SILK_FIX_CONST( 1.0, 8 ) - psEnc->sCmn.speech_activity_Q8;
173
7.42M
        b_Q8 = silk_SMULWB( silk_LSHIFT( b_Q8, 8 ), b_Q8 );
174
7.42M
        SNR_adj_dB_Q7 = silk_SMLAWB( SNR_adj_dB_Q7,
175
7.42M
            silk_SMULBB( SILK_FIX_CONST( -BG_SNR_DECR_dB, 7 ) >> ( 4 + 1 ), b_Q8 ),                                       /* Q11*/
176
7.42M
            silk_SMULWB( SILK_FIX_CONST( 1.0, 14 ) + psEncCtrl->input_quality_Q14, psEncCtrl->coding_quality_Q14 ) );     /* Q12*/
177
7.42M
    }
178
179
23.8M
    if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) {
180
        /* Reduce gains for periodic signals */
181
166k
        SNR_adj_dB_Q7 = silk_SMLAWB( SNR_adj_dB_Q7, SILK_FIX_CONST( HARM_SNR_INCR_dB, 8 ), psEnc->LTPCorr_Q15 );
182
23.6M
    } else {
183
        /* For unvoiced signals and low-quality input, adjust the quality slower than SNR_dB setting */
184
23.6M
        SNR_adj_dB_Q7 = silk_SMLAWB( SNR_adj_dB_Q7,
185
23.6M
            silk_SMLAWB( SILK_FIX_CONST( 6.0, 9 ), -SILK_FIX_CONST( 0.4, 18 ), psEnc->sCmn.SNR_dB_Q7 ),
186
23.6M
            SILK_FIX_CONST( 1.0, 14 ) - psEncCtrl->input_quality_Q14 );
187
23.6M
    }
188
189
    /*************************/
190
    /* SPARSENESS PROCESSING */
191
    /*************************/
192
    /* Set quantizer offset */
193
23.8M
    if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) {
194
        /* Initially set to 0; may be overruled in process_gains(..) */
195
166k
        psEnc->sCmn.indices.quantOffsetType = 0;
196
23.6M
    } else {
197
        /* Sparseness measure, based on relative fluctuations of energy per 2 milliseconds */
198
23.6M
        nSamples = silk_LSHIFT( psEnc->sCmn.fs_kHz, 1 );
199
23.6M
        energy_variation_Q7 = 0;
200
23.6M
        log_energy_prev_Q7  = 0;
201
23.6M
        pitch_res_ptr = pitch_res;
202
23.6M
        nSegs = silk_SMULBB( SUB_FRAME_LENGTH_MS, psEnc->sCmn.nb_subfr ) / 2;
203
226M
        for( k = 0; k < nSegs; k++ ) {
204
203M
            silk_sum_sqr_shift( &nrg, &scale, pitch_res_ptr, nSamples );
205
203M
            nrg += silk_RSHIFT( nSamples, scale );           /* Q(-scale)*/
206
207
203M
            log_energy_Q7 = silk_lin2log( nrg );
208
203M
            if( k > 0 ) {
209
179M
                energy_variation_Q7 += silk_abs( log_energy_Q7 - log_energy_prev_Q7 );
210
179M
            }
211
203M
            log_energy_prev_Q7 = log_energy_Q7;
212
203M
            pitch_res_ptr += nSamples;
213
203M
        }
214
215
        /* Set quantization offset depending on sparseness measure */
216
23.6M
        if( energy_variation_Q7 > SILK_FIX_CONST( ENERGY_VARIATION_THRESHOLD_QNT_OFFSET, 7 ) * (nSegs-1) ) {
217
275k
            psEnc->sCmn.indices.quantOffsetType = 0;
218
23.3M
        } else {
219
23.3M
            psEnc->sCmn.indices.quantOffsetType = 1;
220
23.3M
        }
221
23.6M
    }
222
223
    /*******************************/
224
    /* Control bandwidth expansion */
225
    /*******************************/
226
    /* More BWE for signals with high prediction gain */
227
23.8M
    strength_Q16 = silk_SMULWB( psEncCtrl->predGain_Q16, SILK_FIX_CONST( FIND_PITCH_WHITE_NOISE_FRACTION, 16 ) );
228
23.8M
    BWExp_Q16 = silk_DIV32_varQ( SILK_FIX_CONST( BANDWIDTH_EXPANSION, 16 ),
229
23.8M
        silk_SMLAWW( SILK_FIX_CONST( 1.0, 16 ), strength_Q16, strength_Q16 ), 16 );
230
231
23.8M
    if( psEnc->sCmn.warping_Q16 > 0 ) {
232
        /* Slightly more warping in analysis will move quantization noise up in frequency, where it's better masked */
233
3.97M
        warping_Q16 = silk_SMLAWB( psEnc->sCmn.warping_Q16, (opus_int32)psEncCtrl->coding_quality_Q14, SILK_FIX_CONST( 0.01, 18 ) );
234
19.8M
    } else {
235
19.8M
        warping_Q16 = 0;
236
19.8M
    }
237
238
    /********************************************/
239
    /* Compute noise shaping AR coefs and gains */
240
    /********************************************/
241
23.8M
    ALLOC( x_windowed, psEnc->sCmn.shapeWinLength, opus_int16 );
242
105M
    for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) {
243
        /* Apply window: sine slope followed by flat part followed by cosine slope */
244
81.8M
        opus_int shift, slope_part, flat_part;
245
81.8M
        flat_part = psEnc->sCmn.fs_kHz * 3;
246
81.8M
        slope_part = silk_RSHIFT( psEnc->sCmn.shapeWinLength - flat_part, 1 );
247
248
81.8M
        silk_apply_sine_window( x_windowed, x_ptr, 1, slope_part );
249
81.8M
        shift = slope_part;
250
81.8M
        silk_memcpy( x_windowed + shift, x_ptr + shift, flat_part * sizeof(opus_int16) );
251
81.8M
        shift += flat_part;
252
81.8M
        silk_apply_sine_window( x_windowed + shift, x_ptr + shift, 2, slope_part );
253
254
        /* Update pointer: next LPC analysis block */
255
81.8M
        x_ptr += psEnc->sCmn.subfr_length;
256
257
81.8M
        if( psEnc->sCmn.warping_Q16 > 0 ) {
258
            /* Calculate warped auto correlation */
259
15.3M
            silk_warped_autocorrelation_FIX( auto_corr, &scale, x_windowed, warping_Q16, psEnc->sCmn.shapeWinLength, psEnc->sCmn.shapingLPCOrder, arch );
260
66.4M
        } else {
261
            /* Calculate regular auto correlation */
262
66.4M
            silk_autocorr( auto_corr, &scale, x_windowed, psEnc->sCmn.shapeWinLength, psEnc->sCmn.shapingLPCOrder + 1, arch );
263
66.4M
        }
264
265
        /* Add white noise, as a fraction of energy */
266
81.8M
        auto_corr[0] = silk_ADD32( auto_corr[0], silk_max_32( silk_SMULWB( silk_RSHIFT( auto_corr[ 0 ], 4 ),
267
81.8M
            SILK_FIX_CONST( SHAPE_WHITE_NOISE_FRACTION, 20 ) ), 1 ) );
268
269
        /* Calculate the reflection coefficients using schur */
270
81.8M
        nrg = silk_schur64( refl_coef_Q16, auto_corr, psEnc->sCmn.shapingLPCOrder );
271
81.8M
        silk_assert( nrg >= 0 );
272
273
        /* Convert reflection coefficients to prediction coefficients */
274
81.8M
        silk_k2a_Q16( AR_Q24, refl_coef_Q16, psEnc->sCmn.shapingLPCOrder );
275
276
81.8M
        Qnrg = -scale;          /* range: -12...30*/
277
81.8M
        silk_assert( Qnrg >= -12 );
278
81.8M
        silk_assert( Qnrg <=  30 );
279
280
        /* Make sure that Qnrg is an even number */
281
81.8M
        if( Qnrg & 1 ) {
282
2.00M
            Qnrg -= 1;
283
2.00M
            nrg >>= 1;
284
2.00M
        }
285
286
81.8M
        tmp32 = silk_SQRT_APPROX( nrg );
287
81.8M
        Qnrg >>= 1;             /* range: -6...15*/
288
289
81.8M
        psEncCtrl->Gains_Q16[ k ] = silk_LSHIFT_SAT32( tmp32, 16 - Qnrg );
290
291
81.8M
        if( psEnc->sCmn.warping_Q16 > 0 ) {
292
            /* Adjust gain for warping */
293
15.3M
            gain_mult_Q16 = warped_gain( AR_Q24, warping_Q16, psEnc->sCmn.shapingLPCOrder );
294
15.3M
            silk_assert( psEncCtrl->Gains_Q16[ k ] > 0 );
295
15.3M
            if( psEncCtrl->Gains_Q16[ k ] < SILK_FIX_CONST( 0.25, 16 ) ) {
296
14.2M
                psEncCtrl->Gains_Q16[ k ] = silk_SMULWW( psEncCtrl->Gains_Q16[ k ], gain_mult_Q16 );
297
14.2M
            } else {
298
1.15M
                psEncCtrl->Gains_Q16[ k ] = silk_SMULWW( silk_RSHIFT_ROUND( psEncCtrl->Gains_Q16[ k ], 1 ), gain_mult_Q16 );
299
1.15M
                if ( psEncCtrl->Gains_Q16[ k ] >= ( silk_int32_MAX >> 1 ) ) {
300
156k
                    psEncCtrl->Gains_Q16[ k ] = silk_int32_MAX;
301
995k
                } else {
302
995k
                    psEncCtrl->Gains_Q16[ k ] = silk_LSHIFT32( psEncCtrl->Gains_Q16[ k ], 1 );
303
995k
                }
304
1.15M
            }
305
15.3M
            silk_assert( psEncCtrl->Gains_Q16[ k ] > 0 );
306
15.3M
        }
307
308
        /* Bandwidth expansion */
309
81.8M
        silk_bwexpander_32( AR_Q24, psEnc->sCmn.shapingLPCOrder, BWExp_Q16 );
310
311
81.8M
        if( psEnc->sCmn.warping_Q16 > 0 ) {
312
            /* Convert to monic warped prediction coefficients and limit absolute values */
313
15.3M
            limit_warped_coefs( AR_Q24, warping_Q16, SILK_FIX_CONST( 3.999, 24 ), psEnc->sCmn.shapingLPCOrder );
314
315
            /* Convert from Q24 to Q13 and store in int16 */
316
293M
            for( i = 0; i < psEnc->sCmn.shapingLPCOrder; i++ ) {
317
278M
                psEncCtrl->AR_Q13[ k * MAX_SHAPE_LPC_ORDER + i ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( AR_Q24[ i ], 11 ) );
318
278M
            }
319
66.4M
        } else {
320
66.4M
            silk_LPC_fit( &psEncCtrl->AR_Q13[ k * MAX_SHAPE_LPC_ORDER ], AR_Q24, 13, 24, psEnc->sCmn.shapingLPCOrder );
321
66.4M
        }
322
81.8M
    }
323
324
    /*****************/
325
    /* Gain tweaking */
326
    /*****************/
327
    /* Increase gains during low speech activity and put lower limit on gains */
328
23.8M
    gain_mult_Q16 = silk_log2lin( -silk_SMLAWB( -SILK_FIX_CONST( 16.0, 7 ), SNR_adj_dB_Q7, SILK_FIX_CONST( 0.16, 16 ) ) );
329
23.8M
    gain_add_Q16  = silk_log2lin(  silk_SMLAWB(  SILK_FIX_CONST( 16.0, 7 ), SILK_FIX_CONST( MIN_QGAIN_DB, 7 ), SILK_FIX_CONST( 0.16, 16 ) ) );
330
23.8M
    silk_assert( gain_mult_Q16 > 0 );
331
105M
    for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) {
332
81.8M
        psEncCtrl->Gains_Q16[ k ] = silk_SMULWW( psEncCtrl->Gains_Q16[ k ], gain_mult_Q16 );
333
81.8M
        silk_assert( psEncCtrl->Gains_Q16[ k ] >= 0 );
334
81.8M
        psEncCtrl->Gains_Q16[ k ] = silk_ADD_POS_SAT32( psEncCtrl->Gains_Q16[ k ], gain_add_Q16 );
335
81.8M
    }
336
337
338
    /************************************************/
339
    /* Control low-frequency shaping and noise tilt */
340
    /************************************************/
341
    /* Less low frequency shaping for noisy inputs */
342
23.8M
    strength_Q16 = silk_MUL( SILK_FIX_CONST( LOW_FREQ_SHAPING, 4 ), silk_SMLAWB( SILK_FIX_CONST( 1.0, 12 ),
343
23.8M
        SILK_FIX_CONST( LOW_QUALITY_LOW_FREQ_SHAPING_DECR, 13 ), psEnc->sCmn.input_quality_bands_Q15[ 0 ] - SILK_FIX_CONST( 1.0, 15 ) ) );
344
23.8M
    strength_Q16 = silk_RSHIFT( silk_MUL( strength_Q16, psEnc->sCmn.speech_activity_Q8 ), 8 );
345
23.8M
    if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) {
346
        /* Reduce low frequencies quantization noise for periodic signals, depending on pitch lag */
347
        /*f = 400; freqz([1, -0.98 + 2e-4 * f], [1, -0.97 + 7e-4 * f], 2^12, Fs); axis([0, 1000, -10, 1])*/
348
166k
        opus_int fs_kHz_inv = silk_DIV32_16( SILK_FIX_CONST( 0.2, 14 ), psEnc->sCmn.fs_kHz );
349
746k
        for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) {
350
580k
            b_Q14 = fs_kHz_inv + silk_DIV32_16( SILK_FIX_CONST( 3.0, 14 ), psEncCtrl->pitchL[ k ] );
351
            /* Pack two coefficients in one int32 */
352
580k
            psEncCtrl->LF_shp_Q14[ k ]  = silk_LSHIFT( SILK_FIX_CONST( 1.0, 14 ) - b_Q14 - silk_SMULWB( strength_Q16, b_Q14 ), 16 );
353
580k
            psEncCtrl->LF_shp_Q14[ k ] |= (opus_uint16)( b_Q14 - SILK_FIX_CONST( 1.0, 14 ) );
354
580k
        }
355
166k
        silk_assert( SILK_FIX_CONST( HARM_HP_NOISE_COEF, 24 ) < SILK_FIX_CONST( 0.5, 24 ) ); /* Guarantees that second argument to SMULWB() is within range of an opus_int16*/
356
166k
        Tilt_Q16 = - SILK_FIX_CONST( HP_NOISE_COEF, 16 ) -
357
166k
            silk_SMULWB( SILK_FIX_CONST( 1.0, 16 ) - SILK_FIX_CONST( HP_NOISE_COEF, 16 ),
358
166k
                silk_SMULWB( SILK_FIX_CONST( HARM_HP_NOISE_COEF, 24 ), psEnc->sCmn.speech_activity_Q8 ) );
359
23.6M
    } else {
360
23.6M
        b_Q14 = silk_DIV32_16( 21299, psEnc->sCmn.fs_kHz ); /* 1.3_Q0 = 21299_Q14*/
361
        /* Pack two coefficients in one int32 */
362
23.6M
        psEncCtrl->LF_shp_Q14[ 0 ]  = silk_LSHIFT( SILK_FIX_CONST( 1.0, 14 ) - b_Q14 -
363
23.6M
            silk_SMULWB( strength_Q16, silk_SMULWB( SILK_FIX_CONST( 0.6, 16 ), b_Q14 ) ), 16 );
364
23.6M
        psEncCtrl->LF_shp_Q14[ 0 ] |= (opus_uint16)( b_Q14 - SILK_FIX_CONST( 1.0, 14 ) );
365
81.2M
        for( k = 1; k < psEnc->sCmn.nb_subfr; k++ ) {
366
57.6M
            psEncCtrl->LF_shp_Q14[ k ] = psEncCtrl->LF_shp_Q14[ 0 ];
367
57.6M
        }
368
23.6M
        Tilt_Q16 = -SILK_FIX_CONST( HP_NOISE_COEF, 16 );
369
23.6M
    }
370
371
    /****************************/
372
    /* HARMONIC SHAPING CONTROL */
373
    /****************************/
374
23.8M
    if( USE_HARM_SHAPING && psEnc->sCmn.indices.signalType == TYPE_VOICED ) {
375
        /* More harmonic noise shaping for high bitrates or noisy input */
376
166k
        HarmShapeGain_Q16 = silk_SMLAWB( SILK_FIX_CONST( HARMONIC_SHAPING, 16 ),
377
166k
                SILK_FIX_CONST( 1.0, 16 ) - silk_SMULWB( SILK_FIX_CONST( 1.0, 18 ) - silk_LSHIFT( psEncCtrl->coding_quality_Q14, 4 ),
378
166k
                psEncCtrl->input_quality_Q14 ), SILK_FIX_CONST( HIGH_RATE_OR_LOW_QUALITY_HARMONIC_SHAPING, 16 ) );
379
380
        /* Less harmonic noise shaping for less periodic signals */
381
166k
        HarmShapeGain_Q16 = silk_SMULWB( silk_LSHIFT( HarmShapeGain_Q16, 1 ),
382
166k
            silk_SQRT_APPROX( silk_LSHIFT( psEnc->LTPCorr_Q15, 15 ) ) );
383
23.6M
    } else {
384
23.6M
        HarmShapeGain_Q16 = 0;
385
23.6M
    }
386
387
    /*************************/
388
    /* Smooth over subframes */
389
    /*************************/
390
119M
    for( k = 0; k < MAX_NB_SUBFR; k++ ) {
391
95.2M
        psShapeSt->HarmShapeGain_smth_Q16 =
392
95.2M
            silk_SMLAWB( psShapeSt->HarmShapeGain_smth_Q16, HarmShapeGain_Q16 - psShapeSt->HarmShapeGain_smth_Q16, SILK_FIX_CONST( SUBFR_SMTH_COEF, 16 ) );
393
95.2M
        psShapeSt->Tilt_smth_Q16 =
394
95.2M
            silk_SMLAWB( psShapeSt->Tilt_smth_Q16,          Tilt_Q16          - psShapeSt->Tilt_smth_Q16,          SILK_FIX_CONST( SUBFR_SMTH_COEF, 16 ) );
395
396
95.2M
        psEncCtrl->HarmShapeGain_Q14[ k ] = ( opus_int )silk_RSHIFT_ROUND( psShapeSt->HarmShapeGain_smth_Q16, 2 );
397
95.2M
        psEncCtrl->Tilt_Q14[ k ]          = ( opus_int )silk_RSHIFT_ROUND( psShapeSt->Tilt_smth_Q16,          2 );
398
95.2M
    }
399
23.8M
    RESTORE_STACK;
400
23.8M
}