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