Coverage Report

Created: 2026-09-28 07:55

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
414k
) {
45
414k
    opus_int   i;
46
414k
    opus_int32 gain_Q24;
47
48
414k
    lambda_Q16 = -lambda_Q16;
49
414k
    gain_Q24 = coefs_Q24[ order - 1 ];
50
9.24M
    for( i = order - 2; i >= 0; i-- ) {
51
8.83M
        gain_Q24 = silk_SMLAWB( coefs_Q24[ i ], gain_Q24, lambda_Q16 );
52
8.83M
    }
53
414k
    gain_Q24  = silk_SMLAWB( SILK_FIX_CONST( 1.0, 24 ), gain_Q24, -lambda_Q16 );
54
414k
    return silk_INVERSE32_varQ( gain_Q24, 40 );
55
414k
}
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
414k
) {
65
414k
    opus_int   i, iter, ind = 0;
66
414k
    opus_int32 tmp, maxabs_Q24, chirp_Q16, gain_Q16;
67
414k
    opus_int32 nom_Q16, den_Q24;
68
414k
    opus_int32 limit_Q20, maxabs_Q20;
69
70
    /* Convert to monic coefficients */
71
414k
    lambda_Q16 = -lambda_Q16;
72
9.24M
    for( i = order - 1; i > 0; i-- ) {
73
8.83M
        coefs_Q24[ i - 1 ] = silk_SMLAWB( coefs_Q24[ i - 1 ], coefs_Q24[ i ], lambda_Q16 );
74
8.83M
    }
75
414k
    lambda_Q16 = -lambda_Q16;
76
414k
    nom_Q16  = silk_SMLAWB( SILK_FIX_CONST( 1.0, 16 ), -(opus_int32)lambda_Q16, lambda_Q16 );
77
414k
    den_Q24  = silk_SMLAWB( SILK_FIX_CONST( 1.0, 24 ), coefs_Q24[ 0 ], lambda_Q16 );
78
414k
    gain_Q16 = silk_DIV32_varQ( nom_Q16, den_Q24, 24 );
79
9.65M
    for( i = 0; i < order; i++ ) {
80
9.24M
        coefs_Q24[ i ] = silk_SMULWW( gain_Q16, coefs_Q24[ i ] );
81
9.24M
    }
82
414k
    limit_Q20 = silk_RSHIFT(limit_Q24, 4);
83
416k
    for( iter = 0; iter < 10; iter++ ) {
84
        /* Find maximum absolute value */
85
416k
        maxabs_Q24 = -1;
86
9.70M
        for( i = 0; i < order; i++ ) {
87
9.29M
            tmp = silk_abs_int32( coefs_Q24[ i ] );
88
9.29M
            if( tmp > maxabs_Q24 ) {
89
645k
                maxabs_Q24 = tmp;
90
645k
                ind = i;
91
645k
            }
92
9.29M
        }
93
        /* Use Q20 to avoid any overflow when multiplying by (ind + 1) later. */
94
416k
        maxabs_Q20 = silk_RSHIFT(maxabs_Q24, 4);
95
416k
        if( maxabs_Q20 <= limit_Q20 ) {
96
            /* Coefficients are within range - done */
97
414k
            return;
98
414k
        }
99
100
        /* Convert back to true warped coefficients */
101
45.1k
        for( i = 1; i < order; i++ ) {
102
43.2k
            coefs_Q24[ i - 1 ] = silk_SMLAWB( coefs_Q24[ i - 1 ], coefs_Q24[ i ], lambda_Q16 );
103
43.2k
        }
104
1.93k
        gain_Q16 = silk_INVERSE32_varQ( gain_Q16, 32 );
105
47.1k
        for( i = 0; i < order; i++ ) {
106
45.1k
            coefs_Q24[ i ] = silk_SMULWW( gain_Q16, coefs_Q24[ i ] );
107
45.1k
        }
108
109
        /* Apply bandwidth expansion */
110
1.93k
        chirp_Q16 = SILK_FIX_CONST( 0.99, 16 ) - silk_DIV32_varQ(
111
1.93k
            silk_SMULWB( maxabs_Q20 - limit_Q20, silk_SMLABB( SILK_FIX_CONST( 0.8, 10 ), SILK_FIX_CONST( 0.1, 10 ), iter ) ),
112
1.93k
            silk_MUL( maxabs_Q20, ind + 1 ), 22 );
113
1.93k
        silk_bwexpander_32( coefs_Q24, order, chirp_Q16 );
114
115
        /* Convert to monic warped coefficients */
116
1.93k
        lambda_Q16 = -lambda_Q16;
117
45.1k
        for( i = order - 1; i > 0; i-- ) {
118
43.2k
            coefs_Q24[ i - 1 ] = silk_SMLAWB( coefs_Q24[ i - 1 ], coefs_Q24[ i ], lambda_Q16 );
119
43.2k
        }
120
1.93k
        lambda_Q16 = -lambda_Q16;
121
1.93k
        nom_Q16  = silk_SMLAWB( SILK_FIX_CONST( 1.0, 16 ), -(opus_int32)lambda_Q16,        lambda_Q16 );
122
1.93k
        den_Q24  = silk_SMLAWB( SILK_FIX_CONST( 1.0, 24 ), coefs_Q24[ 0 ], lambda_Q16 );
123
1.93k
        gain_Q16 = silk_DIV32_varQ( nom_Q16, den_Q24, 24 );
124
47.1k
        for( i = 0; i < order; i++ ) {
125
45.1k
            coefs_Q24[ i ] = silk_SMULWW( gain_Q16, coefs_Q24[ i ] );
126
45.1k
        }
127
1.93k
    }
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
172k
{
142
172k
    silk_shape_state_FIX *psShapeSt = &psEnc->sShape;
143
172k
    opus_int     k, i, nSamples, nSegs, Qnrg, b_Q14, warping_Q16, scale = 0;
144
172k
    opus_int32   SNR_adj_dB_Q7, HarmShapeGain_Q16, Tilt_Q16, tmp32;
145
172k
    opus_int32   nrg, log_energy_Q7, log_energy_prev_Q7, energy_variation_Q7;
146
172k
    opus_int32   BWExp_Q16, gain_mult_Q16, gain_add_Q16, strength_Q16, b_Q8;
147
172k
    opus_int32   auto_corr[     MAX_SHAPE_LPC_ORDER + 1 ];
148
172k
    opus_int32   refl_coef_Q16[ MAX_SHAPE_LPC_ORDER ];
149
172k
    opus_int32   AR_Q24[       MAX_SHAPE_LPC_ORDER ];
150
172k
    VARDECL( opus_int16, x_windowed );
151
172k
    const opus_int16 *x_ptr, *pitch_res_ptr;
152
172k
    SAVE_STACK;
153
154
    /* Point to start of first LPC analysis block */
155
172k
    x_ptr = x - psEnc->sCmn.la_shape;
156
157
    /****************/
158
    /* GAIN CONTROL */
159
    /****************/
160
172k
    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
172k
    psEncCtrl->input_quality_Q14 = ( opus_int )silk_RSHIFT( (opus_int32)psEnc->sCmn.input_quality_bands_Q15[ 0 ]
164
172k
        + 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
172k
    psEncCtrl->coding_quality_Q14 = silk_RSHIFT( silk_sigm_Q15( silk_RSHIFT_ROUND( SNR_adj_dB_Q7 -
168
172k
        SILK_FIX_CONST( 20.0, 7 ), 4 ) ), 1 );
169
170
    /* Reduce coding SNR during low speech activity */
171
172k
    if( psEnc->sCmn.useCBR == 0 ) {
172
79.8k
        b_Q8 = SILK_FIX_CONST( 1.0, 8 ) - psEnc->sCmn.speech_activity_Q8;
173
79.8k
        b_Q8 = silk_SMULWB( silk_LSHIFT( b_Q8, 8 ), b_Q8 );
174
79.8k
        SNR_adj_dB_Q7 = silk_SMLAWB( SNR_adj_dB_Q7,
175
79.8k
            silk_SMULBB( SILK_FIX_CONST( -BG_SNR_DECR_dB, 7 ) >> ( 4 + 1 ), b_Q8 ),                                       /* Q11*/
176
79.8k
            silk_SMULWB( SILK_FIX_CONST( 1.0, 14 ) + psEncCtrl->input_quality_Q14, psEncCtrl->coding_quality_Q14 ) );     /* Q12*/
177
79.8k
    }
178
179
172k
    if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) {
180
        /* Reduce gains for periodic signals */
181
19.0k
        SNR_adj_dB_Q7 = silk_SMLAWB( SNR_adj_dB_Q7, SILK_FIX_CONST( HARM_SNR_INCR_dB, 8 ), psEnc->LTPCorr_Q15 );
182
153k
    } else {
183
        /* For unvoiced signals and low-quality input, adjust the quality slower than SNR_dB setting */
184
153k
        SNR_adj_dB_Q7 = silk_SMLAWB( SNR_adj_dB_Q7,
185
153k
            silk_SMLAWB( SILK_FIX_CONST( 6.0, 9 ), -SILK_FIX_CONST( 0.4, 18 ), psEnc->sCmn.SNR_dB_Q7 ),
186
153k
            SILK_FIX_CONST( 1.0, 14 ) - psEncCtrl->input_quality_Q14 );
187
153k
    }
188
189
    /*************************/
190
    /* SPARSENESS PROCESSING */
191
    /*************************/
192
    /* Set quantizer offset */
193
172k
    if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) {
194
        /* Initially set to 0; may be overruled in process_gains(..) */
195
19.0k
        psEnc->sCmn.indices.quantOffsetType = 0;
196
153k
    } else {
197
        /* Sparseness measure, based on relative fluctuations of energy per 2 milliseconds */
198
153k
        nSamples = silk_LSHIFT( psEnc->sCmn.fs_kHz, 1 );
199
153k
        energy_variation_Q7 = 0;
200
153k
        log_energy_prev_Q7  = 0;
201
153k
        pitch_res_ptr = pitch_res;
202
153k
        nSegs = silk_SMULBB( SUB_FRAME_LENGTH_MS, psEnc->sCmn.nb_subfr ) / 2;
203
1.47M
        for( k = 0; k < nSegs; k++ ) {
204
1.32M
            silk_sum_sqr_shift( &nrg, &scale, pitch_res_ptr, nSamples );
205
1.32M
            nrg += silk_RSHIFT( nSamples, scale );           /* Q(-scale)*/
206
207
1.32M
            log_energy_Q7 = silk_lin2log( nrg );
208
1.32M
            if( k > 0 ) {
209
1.17M
                energy_variation_Q7 += silk_abs( log_energy_Q7 - log_energy_prev_Q7 );
210
1.17M
            }
211
1.32M
            log_energy_prev_Q7 = log_energy_Q7;
212
1.32M
            pitch_res_ptr += nSamples;
213
1.32M
        }
214
215
        /* Set quantization offset depending on sparseness measure */
216
153k
        if( energy_variation_Q7 > SILK_FIX_CONST( ENERGY_VARIATION_THRESHOLD_QNT_OFFSET, 7 ) * (nSegs-1) ) {
217
110k
            psEnc->sCmn.indices.quantOffsetType = 0;
218
110k
        } else {
219
42.2k
            psEnc->sCmn.indices.quantOffsetType = 1;
220
42.2k
        }
221
153k
    }
222
223
    /*******************************/
224
    /* Control bandwidth expansion */
225
    /*******************************/
226
    /* More BWE for signals with high prediction gain */
227
172k
    strength_Q16 = silk_SMULWB( psEncCtrl->predGain_Q16, SILK_FIX_CONST( FIND_PITCH_WHITE_NOISE_FRACTION, 16 ) );
228
172k
    BWExp_Q16 = silk_DIV32_varQ( SILK_FIX_CONST( BANDWIDTH_EXPANSION, 16 ),
229
172k
        silk_SMLAWW( SILK_FIX_CONST( 1.0, 16 ), strength_Q16, strength_Q16 ), 16 );
230
231
172k
    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
114k
        warping_Q16 = silk_SMLAWB( psEnc->sCmn.warping_Q16, (opus_int32)psEncCtrl->coding_quality_Q14, SILK_FIX_CONST( 0.01, 18 ) );
234
114k
    } else {
235
57.6k
        warping_Q16 = 0;
236
57.6k
    }
237
238
    /********************************************/
239
    /* Compute noise shaping AR coefs and gains */
240
    /********************************************/
241
172k
    ALLOC( x_windowed, psEnc->sCmn.shapeWinLength, opus_int16 );
242
778k
    for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) {
243
        /* Apply window: sine slope followed by flat part followed by cosine slope */
244
606k
        opus_int shift, slope_part, flat_part;
245
606k
        flat_part = psEnc->sCmn.fs_kHz * 3;
246
606k
        slope_part = silk_RSHIFT( psEnc->sCmn.shapeWinLength - flat_part, 1 );
247
248
606k
        silk_apply_sine_window( x_windowed, x_ptr, 1, slope_part );
249
606k
        shift = slope_part;
250
606k
        silk_memcpy( x_windowed + shift, x_ptr + shift, flat_part * sizeof(opus_int16) );
251
606k
        shift += flat_part;
252
606k
        silk_apply_sine_window( x_windowed + shift, x_ptr + shift, 2, slope_part );
253
254
        /* Update pointer: next LPC analysis block */
255
606k
        x_ptr += psEnc->sCmn.subfr_length;
256
257
606k
        if( psEnc->sCmn.warping_Q16 > 0 ) {
258
            /* Calculate warped auto correlation */
259
414k
            silk_warped_autocorrelation_FIX( auto_corr, &scale, x_windowed, warping_Q16, psEnc->sCmn.shapeWinLength, psEnc->sCmn.shapingLPCOrder, arch );
260
414k
        } else {
261
            /* Calculate regular auto correlation */
262
191k
            silk_autocorr( auto_corr, &scale, x_windowed, psEnc->sCmn.shapeWinLength, psEnc->sCmn.shapingLPCOrder + 1, arch );
263
191k
        }
264
265
        /* Add white noise, as a fraction of energy */
266
606k
        auto_corr[0] = silk_ADD32( auto_corr[0], silk_max_32( silk_SMULWB( silk_RSHIFT( auto_corr[ 0 ], 4 ),
267
606k
            SILK_FIX_CONST( SHAPE_WHITE_NOISE_FRACTION, 20 ) ), 1 ) );
268
269
        /* Calculate the reflection coefficients using schur */
270
606k
        nrg = silk_schur64( refl_coef_Q16, auto_corr, psEnc->sCmn.shapingLPCOrder );
271
606k
        silk_assert( nrg >= 0 );
272
273
        /* Convert reflection coefficients to prediction coefficients */
274
606k
        silk_k2a_Q16( AR_Q24, refl_coef_Q16, psEnc->sCmn.shapingLPCOrder );
275
276
606k
        Qnrg = -scale;          /* range: -12...30*/
277
606k
        silk_assert( Qnrg >= -12 );
278
606k
        silk_assert( Qnrg <=  30 );
279
280
        /* Make sure that Qnrg is an even number */
281
606k
        if( Qnrg & 1 ) {
282
257k
            Qnrg -= 1;
283
257k
            nrg >>= 1;
284
257k
        }
285
286
606k
        tmp32 = silk_SQRT_APPROX( nrg );
287
606k
        Qnrg >>= 1;             /* range: -6...15*/
288
289
606k
        psEncCtrl->Gains_Q16[ k ] = silk_LSHIFT_SAT32( tmp32, 16 - Qnrg );
290
291
606k
        if( psEnc->sCmn.warping_Q16 > 0 ) {
292
            /* Adjust gain for warping */
293
414k
            gain_mult_Q16 = warped_gain( AR_Q24, warping_Q16, psEnc->sCmn.shapingLPCOrder );
294
414k
            silk_assert( psEncCtrl->Gains_Q16[ k ] > 0 );
295
414k
            if( psEncCtrl->Gains_Q16[ k ] < SILK_FIX_CONST( 0.25, 16 ) ) {
296
54.8k
                psEncCtrl->Gains_Q16[ k ] = silk_SMULWW( psEncCtrl->Gains_Q16[ k ], gain_mult_Q16 );
297
359k
            } else {
298
359k
                psEncCtrl->Gains_Q16[ k ] = silk_SMULWW( silk_RSHIFT_ROUND( psEncCtrl->Gains_Q16[ k ], 1 ), gain_mult_Q16 );
299
359k
                if ( psEncCtrl->Gains_Q16[ k ] >= ( silk_int32_MAX >> 1 ) ) {
300
58.5k
                    psEncCtrl->Gains_Q16[ k ] = silk_int32_MAX;
301
300k
                } else {
302
300k
                    psEncCtrl->Gains_Q16[ k ] = silk_LSHIFT32( psEncCtrl->Gains_Q16[ k ], 1 );
303
300k
                }
304
359k
            }
305
414k
            silk_assert( psEncCtrl->Gains_Q16[ k ] > 0 );
306
414k
        }
307
308
        /* Bandwidth expansion */
309
606k
        silk_bwexpander_32( AR_Q24, psEnc->sCmn.shapingLPCOrder, BWExp_Q16 );
310
311
606k
        if( psEnc->sCmn.warping_Q16 > 0 ) {
312
            /* Convert to monic warped prediction coefficients and limit absolute values */
313
414k
            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
9.65M
            for( i = 0; i < psEnc->sCmn.shapingLPCOrder; i++ ) {
317
9.24M
                psEncCtrl->AR_Q13[ k * MAX_SHAPE_LPC_ORDER + i ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( AR_Q24[ i ], 11 ) );
318
9.24M
            }
319
414k
        } else {
320
191k
            silk_LPC_fit( &psEncCtrl->AR_Q13[ k * MAX_SHAPE_LPC_ORDER ], AR_Q24, 13, 24, psEnc->sCmn.shapingLPCOrder );
321
191k
        }
322
606k
    }
323
324
    /*****************/
325
    /* Gain tweaking */
326
    /*****************/
327
    /* Increase gains during low speech activity and put lower limit on gains */
328
172k
    gain_mult_Q16 = silk_log2lin( -silk_SMLAWB( -SILK_FIX_CONST( 16.0, 7 ), SNR_adj_dB_Q7, SILK_FIX_CONST( 0.16, 16 ) ) );
329
172k
    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
172k
    silk_assert( gain_mult_Q16 > 0 );
331
778k
    for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) {
332
606k
        psEncCtrl->Gains_Q16[ k ] = silk_SMULWW( psEncCtrl->Gains_Q16[ k ], gain_mult_Q16 );
333
606k
        silk_assert( psEncCtrl->Gains_Q16[ k ] >= 0 );
334
606k
        psEncCtrl->Gains_Q16[ k ] = silk_ADD_POS_SAT32( psEncCtrl->Gains_Q16[ k ], gain_add_Q16 );
335
606k
    }
336
337
338
    /************************************************/
339
    /* Control low-frequency shaping and noise tilt */
340
    /************************************************/
341
    /* Less low frequency shaping for noisy inputs */
342
172k
    strength_Q16 = silk_MUL( SILK_FIX_CONST( LOW_FREQ_SHAPING, 4 ), silk_SMLAWB( SILK_FIX_CONST( 1.0, 12 ),
343
172k
        SILK_FIX_CONST( LOW_QUALITY_LOW_FREQ_SHAPING_DECR, 13 ), psEnc->sCmn.input_quality_bands_Q15[ 0 ] - SILK_FIX_CONST( 1.0, 15 ) ) );
344
172k
    strength_Q16 = silk_RSHIFT( silk_MUL( strength_Q16, psEnc->sCmn.speech_activity_Q8 ), 8 );
345
172k
    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
19.0k
        opus_int fs_kHz_inv = silk_DIV32_16( SILK_FIX_CONST( 0.2, 14 ), psEnc->sCmn.fs_kHz );
349
95.1k
        for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) {
350
76.1k
            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
76.1k
            psEncCtrl->LF_shp_Q14[ k ]  = silk_LSHIFT( SILK_FIX_CONST( 1.0, 14 ) - b_Q14 - silk_SMULWB( strength_Q16, b_Q14 ), 16 );
353
76.1k
            psEncCtrl->LF_shp_Q14[ k ] |= (opus_uint16)( b_Q14 - SILK_FIX_CONST( 1.0, 14 ) );
354
76.1k
        }
355
19.0k
        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
19.0k
        Tilt_Q16 = - SILK_FIX_CONST( HP_NOISE_COEF, 16 ) -
357
19.0k
            silk_SMULWB( SILK_FIX_CONST( 1.0, 16 ) - SILK_FIX_CONST( HP_NOISE_COEF, 16 ),
358
19.0k
                silk_SMULWB( SILK_FIX_CONST( HARM_HP_NOISE_COEF, 24 ), psEnc->sCmn.speech_activity_Q8 ) );
359
153k
    } else {
360
153k
        b_Q14 = silk_DIV32_16( 21299, psEnc->sCmn.fs_kHz ); /* 1.3_Q0 = 21299_Q14*/
361
        /* Pack two coefficients in one int32 */
362
153k
        psEncCtrl->LF_shp_Q14[ 0 ]  = silk_LSHIFT( SILK_FIX_CONST( 1.0, 14 ) - b_Q14 -
363
153k
            silk_SMULWB( strength_Q16, silk_SMULWB( SILK_FIX_CONST( 0.6, 16 ), b_Q14 ) ), 16 );
364
153k
        psEncCtrl->LF_shp_Q14[ 0 ] |= (opus_uint16)( b_Q14 - SILK_FIX_CONST( 1.0, 14 ) );
365
529k
        for( k = 1; k < psEnc->sCmn.nb_subfr; k++ ) {
366
376k
            psEncCtrl->LF_shp_Q14[ k ] = psEncCtrl->LF_shp_Q14[ 0 ];
367
376k
        }
368
153k
        Tilt_Q16 = -SILK_FIX_CONST( HP_NOISE_COEF, 16 );
369
153k
    }
370
371
    /****************************/
372
    /* HARMONIC SHAPING CONTROL */
373
    /****************************/
374
172k
    if( USE_HARM_SHAPING && psEnc->sCmn.indices.signalType == TYPE_VOICED ) {
375
        /* More harmonic noise shaping for high bitrates or noisy input */
376
19.0k
        HarmShapeGain_Q16 = silk_SMLAWB( SILK_FIX_CONST( HARMONIC_SHAPING, 16 ),
377
19.0k
                SILK_FIX_CONST( 1.0, 16 ) - silk_SMULWB( SILK_FIX_CONST( 1.0, 18 ) - silk_LSHIFT( psEncCtrl->coding_quality_Q14, 4 ),
378
19.0k
                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
19.0k
        HarmShapeGain_Q16 = silk_SMULWB( silk_LSHIFT( HarmShapeGain_Q16, 1 ),
382
19.0k
            silk_SQRT_APPROX( silk_LSHIFT( psEnc->LTPCorr_Q15, 15 ) ) );
383
153k
    } else {
384
153k
        HarmShapeGain_Q16 = 0;
385
153k
    }
386
387
    /*************************/
388
    /* Smooth over subframes */
389
    /*************************/
390
860k
    for( k = 0; k < MAX_NB_SUBFR; k++ ) {
391
688k
        psShapeSt->HarmShapeGain_smth_Q16 =
392
688k
            silk_SMLAWB( psShapeSt->HarmShapeGain_smth_Q16, HarmShapeGain_Q16 - psShapeSt->HarmShapeGain_smth_Q16, SILK_FIX_CONST( SUBFR_SMTH_COEF, 16 ) );
393
688k
        psShapeSt->Tilt_smth_Q16 =
394
688k
            silk_SMLAWB( psShapeSt->Tilt_smth_Q16,          Tilt_Q16          - psShapeSt->Tilt_smth_Q16,          SILK_FIX_CONST( SUBFR_SMTH_COEF, 16 ) );
395
396
688k
        psEncCtrl->HarmShapeGain_Q14[ k ] = ( opus_int )silk_RSHIFT_ROUND( psShapeSt->HarmShapeGain_smth_Q16, 2 );
397
688k
        psEncCtrl->Tilt_Q14[ k ]          = ( opus_int )silk_RSHIFT_ROUND( psShapeSt->Tilt_smth_Q16,          2 );
398
688k
    }
399
172k
    RESTORE_STACK;
400
172k
}