Coverage Report

Created: 2026-01-09 07:33

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