Initial Skype commit taken from FreeSwitch, which got it from the IETF draft.
[opus.git] / src / SKP_Silk_noise_shape_analysis_FIX.c
1 /***********************************************************************\r
2 Copyright (c) 2006-2010, Skype Limited. All rights reserved. \r
3 Redistribution and use in source and binary forms, with or without \r
4 modification, (subject to the limitations in the disclaimer below) \r
5 are permitted provided that the following conditions are met:\r
6 - Redistributions of source code must retain the above copyright notice,\r
7 this list of conditions and the following disclaimer.\r
8 - Redistributions in binary form must reproduce the above copyright \r
9 notice, this list of conditions and the following disclaimer in the \r
10 documentation and/or other materials provided with the distribution.\r
11 - Neither the name of Skype Limited, nor the names of specific \r
12 contributors, may be used to endorse or promote products derived from \r
13 this software without specific prior written permission.\r
14 NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED \r
15 BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND \r
16 CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,\r
17 BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND \r
18 FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE \r
19 COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, \r
20 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\r
21 NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF \r
22 USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON \r
23 ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT \r
24 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE \r
25 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
26 ***********************************************************************/\r
27 \r
28 #include "SKP_Silk_main_FIX.h"\r
29 #include "SKP_Silk_perceptual_parameters_FIX.h"\r
30 \r
31 \r
32 /**************************************************************/\r
33 /* Compute noise shaping coefficients and initial gain values */\r
34 /**************************************************************/\r
35 void SKP_Silk_noise_shape_analysis_FIX(\r
36     SKP_Silk_encoder_state_FIX      *psEnc,         /* I/O  Encoder state FIX                           */\r
37     SKP_Silk_encoder_control_FIX    *psEncCtrl,     /* I/O  Encoder control FIX                         */\r
38     const SKP_int16                 *pitch_res,     /* I    LPC residual from pitch analysis            */\r
39     const SKP_int16                 *x              /* I    Input signal [ 2 * frame_length + la_shape ]*/\r
40 )\r
41 {\r
42     SKP_Silk_shape_state_FIX *psShapeSt = &psEnc->sShape;\r
43     SKP_int     k, nSamples, lz, Qnrg, b_Q14, scale = 0, sz;\r
44     SKP_int32   SNR_adj_dB_Q7, HarmBoost_Q16, HarmShapeGain_Q16, Tilt_Q16, tmp32;\r
45     SKP_int32   nrg, pre_nrg_Q30, log_energy_Q7, log_energy_prev_Q7, energy_variation_Q7;\r
46     SKP_int32   delta_Q16, BWExp1_Q16, BWExp2_Q16, gain_mult_Q16, gain_add_Q16, strength_Q16, b_Q8;\r
47     SKP_int32   auto_corr[     SHAPE_LPC_ORDER_MAX + 1 ];\r
48     SKP_int32   refl_coef_Q16[ SHAPE_LPC_ORDER_MAX ];\r
49     SKP_int32   AR_Q24[        SHAPE_LPC_ORDER_MAX ];\r
50     SKP_int16   x_windowed[    SHAPE_LPC_WIN_MAX ];\r
51     const SKP_int16 *x_ptr, *pitch_res_ptr;\r
52 \r
53     SKP_int32   sqrt_nrg[ NB_SUBFR ], Qnrg_vec[ NB_SUBFR ];\r
54 \r
55     /* Point to start of first LPC analysis block */\r
56     x_ptr = x + psEnc->sCmn.la_shape - SKP_SMULBB( SHAPE_LPC_WIN_MS, psEnc->sCmn.fs_kHz ) + psEnc->sCmn.frame_length / NB_SUBFR;\r
57 \r
58     /****************/\r
59     /* CONTROL SNR  */\r
60     /****************/\r
61     /* Reduce SNR_dB values if recent bitstream has exceeded TargetRate */\r
62     psEncCtrl->current_SNR_dB_Q7 = psEnc->SNR_dB_Q7 - SKP_SMULWB( SKP_LSHIFT( ( SKP_int32 )psEnc->BufferedInChannel_ms, 7 ), 3277 );\r
63 \r
64     /* Reduce SNR_dB if inband FEC used */\r
65     if( psEnc->speech_activity_Q8 > LBRR_SPEECH_ACTIVITY_THRES_Q8 ) {\r
66         psEncCtrl->current_SNR_dB_Q7 -= SKP_RSHIFT( psEnc->inBandFEC_SNR_comp_Q8, 1 );\r
67     }\r
68 \r
69     /****************/\r
70     /* GAIN CONTROL */\r
71     /****************/\r
72     /* Input quality is the average of the quality in the lowest two VAD bands */\r
73     psEncCtrl->input_quality_Q14 = ( SKP_int )SKP_RSHIFT( ( SKP_int32 )psEncCtrl->input_quality_bands_Q15[ 0 ] \r
74         + psEncCtrl->input_quality_bands_Q15[ 1 ], 2 );\r
75     /* Coding quality level, between 0.0_Q0 and 1.0_Q0, but in Q14 */\r
76     psEncCtrl->coding_quality_Q14 = SKP_RSHIFT( SKP_Silk_sigm_Q15( SKP_RSHIFT_ROUND( psEncCtrl->current_SNR_dB_Q7 - ( 18 << 7 ), 4 ) ), 1 );\r
77 \r
78     /* Reduce coding SNR during low speech activity */\r
79     b_Q8 = ( 1 << 8 ) - psEnc->speech_activity_Q8;\r
80     b_Q8 = SKP_SMULWB( SKP_LSHIFT( b_Q8, 8 ), b_Q8 );\r
81     SNR_adj_dB_Q7 = SKP_SMLAWB( psEncCtrl->current_SNR_dB_Q7,\r
82         SKP_SMULBB( -BG_SNR_DECR_dB_Q7 >> ( 4 + 1 ), b_Q8 ),                                            // Q11\r
83         SKP_SMULWB( ( 1 << 14 ) + psEncCtrl->input_quality_Q14, psEncCtrl->coding_quality_Q14 ) );      // Q12\r
84 \r
85     if( psEncCtrl->sCmn.sigtype == SIG_TYPE_VOICED ) {\r
86         /* Reduce gains for periodic signals */\r
87         SNR_adj_dB_Q7 = SKP_SMLAWB( SNR_adj_dB_Q7, HARM_SNR_INCR_dB_Q7 << 1, psEnc->LTPCorr_Q15 );\r
88     } else { \r
89         /* For unvoiced signals and low-quality input, adjust the quality slower than SNR_dB setting */\r
90         SNR_adj_dB_Q7 = SKP_SMLAWB( SNR_adj_dB_Q7, \r
91             SKP_SMLAWB( 6 << ( 7 + 2 ), -104856, psEncCtrl->current_SNR_dB_Q7 ),    //-104856_Q18 = -0.4_Q0, Q9\r
92             ( 1 << 14 ) - psEncCtrl->input_quality_Q14 );                           // Q14\r
93     }\r
94 \r
95     /*************************/\r
96     /* SPARSENESS PROCESSING */\r
97     /*************************/\r
98     /* Set quantizer offset */\r
99     if( psEncCtrl->sCmn.sigtype == SIG_TYPE_VOICED ) {\r
100         /* Initally set to 0; may be overruled in process_gains(..) */\r
101         psEncCtrl->sCmn.QuantOffsetType = 0;\r
102         psEncCtrl->sparseness_Q8 = 0;\r
103     } else {\r
104         /* Sparseness measure, based on relative fluctuations of energy per 2 milliseconds */\r
105         nSamples = SKP_LSHIFT( psEnc->sCmn.fs_kHz, 1 );\r
106         energy_variation_Q7 = 0;\r
107         log_energy_prev_Q7  = 0;\r
108         pitch_res_ptr = pitch_res;\r
109         for( k = 0; k < FRAME_LENGTH_MS / 2; k++ ) {    \r
110             SKP_Silk_sum_sqr_shift( &nrg, &scale, pitch_res_ptr, nSamples );\r
111             nrg += SKP_RSHIFT( nSamples, scale );           // Q(-scale)\r
112             \r
113             log_energy_Q7 = SKP_Silk_lin2log( nrg );\r
114             if( k > 0 ) {\r
115                 energy_variation_Q7 += SKP_abs( log_energy_Q7 - log_energy_prev_Q7 );\r
116             }\r
117             log_energy_prev_Q7 = log_energy_Q7;\r
118             pitch_res_ptr += nSamples;\r
119         }\r
120 \r
121         psEncCtrl->sparseness_Q8 = SKP_RSHIFT( SKP_Silk_sigm_Q15( SKP_SMULWB( energy_variation_Q7 - ( 5 << 7 ), 6554 ) ), 7 );    // 6554_Q16 = 0.1_Q0\r
122 \r
123         /* Set quantization offset depending on sparseness measure */\r
124         if( psEncCtrl->sparseness_Q8 > SPARSENESS_THRESHOLD_QNT_OFFSET_Q8 ) {\r
125             psEncCtrl->sCmn.QuantOffsetType = 0;\r
126         } else {\r
127             psEncCtrl->sCmn.QuantOffsetType = 1;\r
128         }\r
129         \r
130         /* Increase coding SNR for sparse signals */\r
131         SNR_adj_dB_Q7 = SKP_SMLAWB( SNR_adj_dB_Q7, SPARSE_SNR_INCR_dB_Q7 << 8, psEncCtrl->sparseness_Q8 - ( 1 << 7 ) );\r
132     }\r
133 \r
134     /*******************************/\r
135     /* Control bandwidth expansion */\r
136     /*******************************/\r
137     delta_Q16  = SKP_SMULWB( ( 1 << 16 ) - SKP_SMULBB( 3, psEncCtrl->coding_quality_Q14 ), LOW_RATE_BANDWIDTH_EXPANSION_DELTA_Q16 );\r
138     BWExp1_Q16 = BANDWIDTH_EXPANSION_Q16 - delta_Q16;\r
139     BWExp2_Q16 = BANDWIDTH_EXPANSION_Q16 + delta_Q16;\r
140     if( psEnc->sCmn.fs_kHz == 24 ) {\r
141         /* Less bandwidth expansion for super wideband */\r
142         BWExp1_Q16 = ( 1 << 16 ) - SKP_SMULWB( SWB_BANDWIDTH_EXPANSION_REDUCTION_Q16, ( 1 << 16 ) - BWExp1_Q16 );\r
143         BWExp2_Q16 = ( 1 << 16 ) - SKP_SMULWB( SWB_BANDWIDTH_EXPANSION_REDUCTION_Q16, ( 1 << 16 ) - BWExp2_Q16 );\r
144     }\r
145     /* BWExp1 will be applied after BWExp2, so make it relative */\r
146     BWExp1_Q16 = SKP_DIV32_16( SKP_LSHIFT( BWExp1_Q16, 14 ), SKP_RSHIFT( BWExp2_Q16, 2 ) );\r
147 \r
148     /********************************************/\r
149     /* Compute noise shaping AR coefs and gains */\r
150     /********************************************/\r
151     sz = ( SKP_int )SKP_SMULBB( SHAPE_LPC_WIN_MS, psEnc->sCmn.fs_kHz );\r
152     for( k = 0; k < NB_SUBFR; k++ ) {\r
153         /* Apply window */\r
154         SKP_Silk_apply_sine_window( x_windowed, x_ptr, 0, SHAPE_LPC_WIN_MS * psEnc->sCmn.fs_kHz );\r
155 \r
156         /* Update pointer: next LPC analysis block */\r
157         x_ptr += psEnc->sCmn.frame_length / NB_SUBFR;\r
158 \r
159         /* Calculate auto correlation */\r
160         SKP_Silk_autocorr( auto_corr, &scale, x_windowed, sz, psEnc->sCmn.shapingLPCOrder + 1 );\r
161 \r
162         /* Add white noise, as a fraction of energy */\r
163         auto_corr[0] = SKP_ADD32( auto_corr[0], SKP_max_32( SKP_SMULWB( SKP_RSHIFT( auto_corr[ 0 ], 4 ), SHAPE_WHITE_NOISE_FRACTION_Q20 ), 1 ) ); \r
164 \r
165         /* Calculate the reflection coefficients using schur */\r
166         nrg = SKP_Silk_schur64( refl_coef_Q16, auto_corr, psEnc->sCmn.shapingLPCOrder );\r
167 \r
168         /* Convert reflection coefficients to prediction coefficients */\r
169         SKP_Silk_k2a_Q16( AR_Q24, refl_coef_Q16, psEnc->sCmn.shapingLPCOrder );\r
170 \r
171         /* Bandwidth expansion for synthesis filter shaping */\r
172         SKP_Silk_bwexpander_32( AR_Q24, psEnc->sCmn.shapingLPCOrder, BWExp2_Q16 );\r
173 \r
174         /* Make sure to fit in Q13 SKP_int16 */\r
175         SKP_Silk_LPC_fit( &psEncCtrl->AR2_Q13[ k * SHAPE_LPC_ORDER_MAX ], AR_Q24, 13, psEnc->sCmn.shapingLPCOrder );\r
176 \r
177         /* Compute noise shaping filter coefficients */\r
178         SKP_memcpy(\r
179             &psEncCtrl->AR1_Q13[ k * SHAPE_LPC_ORDER_MAX ], \r
180             &psEncCtrl->AR2_Q13[ k * SHAPE_LPC_ORDER_MAX ], \r
181             psEnc->sCmn.shapingLPCOrder * sizeof( SKP_int16 ) );\r
182 \r
183         /* Bandwidth expansion for analysis filter shaping */\r
184         SKP_assert( BWExp1_Q16 <= ( 1 << 16 ) ); // If ever breaking, use LPC_stabilize() in these cases to stay within range\r
185         SKP_Silk_bwexpander( &psEncCtrl->AR1_Q13[ k * SHAPE_LPC_ORDER_MAX ], psEnc->sCmn.shapingLPCOrder, BWExp1_Q16 );\r
186 \r
187         /* Increase residual energy */\r
188         nrg = SKP_SMLAWB( nrg, SKP_RSHIFT( auto_corr[ 0 ], 8 ), SHAPE_MIN_ENERGY_RATIO_Q24 );\r
189 \r
190         Qnrg = -scale;          // range: -12...30\r
191         SKP_assert( Qnrg >= -12 );\r
192         SKP_assert( Qnrg <=  30 );\r
193 \r
194         /* Make sure that Qnrg is an even number */\r
195         if( Qnrg & 1 ) {\r
196             Qnrg -= 1;\r
197             nrg >>= 1;\r
198         }\r
199 \r
200         tmp32 = SKP_Silk_SQRT_APPROX( nrg );\r
201         Qnrg >>= 1;             // range: -6...15\r
202 \r
203         sqrt_nrg[ k ] = tmp32;\r
204         Qnrg_vec[ k ] = Qnrg;\r
205 \r
206         psEncCtrl->Gains_Q16[ k ] = SKP_LSHIFT_SAT32( tmp32, 16 - Qnrg );\r
207         /* Ratio of prediction gains, in energy domain */\r
208         SKP_Silk_LPC_inverse_pred_gain_Q13( &pre_nrg_Q30, &psEncCtrl->AR2_Q13[ k * SHAPE_LPC_ORDER_MAX ], psEnc->sCmn.shapingLPCOrder );\r
209         SKP_Silk_LPC_inverse_pred_gain_Q13( &nrg,         &psEncCtrl->AR1_Q13[ k * SHAPE_LPC_ORDER_MAX ], psEnc->sCmn.shapingLPCOrder );\r
210 \r
211         lz = SKP_min_32( SKP_Silk_CLZ32( pre_nrg_Q30 ) - 1, 19 );\r
212         pre_nrg_Q30 = SKP_DIV32( SKP_LSHIFT( pre_nrg_Q30, lz ), SKP_RSHIFT( nrg, 20 - lz ) + 1 ); // Q20\r
213         pre_nrg_Q30 = SKP_RSHIFT( SKP_LSHIFT_SAT32( pre_nrg_Q30, 9 ), 1 );  /* Q28 */\r
214         psEncCtrl->GainsPre_Q14[ k ] = ( SKP_int )SKP_Silk_SQRT_APPROX( pre_nrg_Q30 );\r
215     }\r
216 \r
217     /*****************/\r
218     /* Gain tweaking */\r
219     /*****************/\r
220     /* Increase gains during low speech activity and put lower limit on gains */\r
221     gain_mult_Q16 = SKP_Silk_log2lin( -SKP_SMLAWB( -16 << 7, SNR_adj_dB_Q7,           10486 ) ); // 10486_Q16 = 0.16_Q0\r
222     gain_add_Q16  = SKP_Silk_log2lin(  SKP_SMLAWB(  16 << 7, NOISE_FLOOR_dB_Q7,       10486 ) ); // 10486_Q16 = 0.16_Q0\r
223     tmp32         = SKP_Silk_log2lin(  SKP_SMLAWB(  16 << 7, RELATIVE_MIN_GAIN_dB_Q7, 10486 ) ); // 10486_Q16 = 0.16_Q0\r
224     tmp32 = SKP_SMULWW( psEnc->avgGain_Q16, tmp32 );\r
225     gain_add_Q16 = SKP_ADD_SAT32( gain_add_Q16, tmp32 );\r
226     SKP_assert( gain_mult_Q16 >= 0 );\r
227 \r
228     for( k = 0; k < NB_SUBFR; k++ ) {\r
229         psEncCtrl->Gains_Q16[ k ] = SKP_SMULWW( psEncCtrl->Gains_Q16[ k ], gain_mult_Q16 );\r
230         SKP_assert( psEncCtrl->Gains_Q16[ k ] >= 0 );\r
231     }\r
232 \r
233     for( k = 0; k < NB_SUBFR; k++ ) {\r
234         psEncCtrl->Gains_Q16[ k ] = SKP_ADD_POS_SAT32( psEncCtrl->Gains_Q16[ k ], gain_add_Q16 );\r
235         psEnc->avgGain_Q16 = SKP_ADD_SAT32( \r
236             psEnc->avgGain_Q16, \r
237             SKP_SMULWB(\r
238                 psEncCtrl->Gains_Q16[ k ] - psEnc->avgGain_Q16, \r
239                 SKP_RSHIFT_ROUND( SKP_SMULBB( psEnc->speech_activity_Q8, GAIN_SMOOTHING_COEF_Q10 ), 2 ) \r
240             ) );\r
241     }\r
242 \r
243     /************************************************/\r
244     /* Decrease level during fricatives (de-essing) */\r
245     /************************************************/\r
246     gain_mult_Q16 = ( 1 << 16 ) + SKP_RSHIFT_ROUND( SKP_MLA( INPUT_TILT_Q26, psEncCtrl->coding_quality_Q14, HIGH_RATE_INPUT_TILT_Q12 ), 10 );\r
247 \r
248     if( psEncCtrl->input_tilt_Q15 <= 0 && psEncCtrl->sCmn.sigtype == SIG_TYPE_UNVOICED ) {\r
249         if( psEnc->sCmn.fs_kHz == 24 ) {\r
250             SKP_int32 essStrength_Q15 = SKP_SMULWW( -psEncCtrl->input_tilt_Q15, \r
251                 SKP_SMULBB( psEnc->speech_activity_Q8, ( 1 << 8 ) - psEncCtrl->sparseness_Q8 ) );\r
252             tmp32 = SKP_Silk_log2lin( ( 16 << 7 ) - SKP_SMULWB( essStrength_Q15, \r
253                 SKP_SMULWB( DE_ESSER_COEF_SWB_dB_Q7, 20972 ) ) ); // 20972_Q17 = 0.16_Q0\r
254             gain_mult_Q16 = SKP_SMULWW( gain_mult_Q16, tmp32 );\r
255         } else if( psEnc->sCmn.fs_kHz == 16 ) {\r
256             SKP_int32 essStrength_Q15 = SKP_SMULWW(-psEncCtrl->input_tilt_Q15, \r
257                 SKP_SMULBB( psEnc->speech_activity_Q8, ( 1 << 8 ) - psEncCtrl->sparseness_Q8 ));\r
258             tmp32 = SKP_Silk_log2lin( ( 16 << 7 ) - SKP_SMULWB( essStrength_Q15, \r
259                 SKP_SMULWB( DE_ESSER_COEF_WB_dB_Q7, 20972 ) ) ); // 20972_Q17 = 0.16_Q0\r
260             gain_mult_Q16 = SKP_SMULWW( gain_mult_Q16, tmp32 );\r
261         } else {\r
262             SKP_assert( psEnc->sCmn.fs_kHz == 12 || psEnc->sCmn.fs_kHz == 8 );\r
263         }\r
264     }\r
265 \r
266     for( k = 0; k < NB_SUBFR; k++ ) {\r
267         psEncCtrl->GainsPre_Q14[ k ] = SKP_SMULWB( gain_mult_Q16, psEncCtrl->GainsPre_Q14[ k ] );\r
268     }\r
269 \r
270     /************************************************/\r
271     /* Control low-frequency shaping and noise tilt */\r
272     /************************************************/\r
273     /* Less low frequency shaping for noisy inputs */\r
274     strength_Q16 = SKP_MUL( LOW_FREQ_SHAPING_Q0, ( 1 << 16 ) + SKP_SMULBB( LOW_QUALITY_LOW_FREQ_SHAPING_DECR_Q1, psEncCtrl->input_quality_bands_Q15[ 0 ] - ( 1 << 15 ) ) );\r
275     if( psEncCtrl->sCmn.sigtype == SIG_TYPE_VOICED ) {\r
276         /* Reduce low frequencies quantization noise for periodic signals, depending on pitch lag */\r
277         /*f = 400; freqz([1, -0.98 + 2e-4 * f], [1, -0.97 + 7e-4 * f], 2^12, Fs); axis([0, 1000, -10, 1])*/\r
278         SKP_int fs_kHz_inv = SKP_DIV32_16( 3277, psEnc->sCmn.fs_kHz );      // 0.2_Q0 = 3277_Q14\r
279         for( k = 0; k < NB_SUBFR; k++ ) {\r
280             b_Q14 = fs_kHz_inv + SKP_DIV32_16( ( 3 << 14 ), psEncCtrl->sCmn.pitchL[ k ] ); \r
281             /* Pack two coefficients in one int32 */\r
282             psEncCtrl->LF_shp_Q14[ k ]  = SKP_LSHIFT( ( 1 << 14 ) - b_Q14 - SKP_SMULWB( strength_Q16, b_Q14 ), 16 );\r
283             psEncCtrl->LF_shp_Q14[ k ] |= (SKP_uint16)( b_Q14 - ( 1 << 14 ) );\r
284         }\r
285         SKP_assert( HARM_HP_NOISE_COEF_Q24 < ( 1 << 23 ) ); // Guarantees that second argument to SMULWB() is within range of an SKP_int16\r
286         Tilt_Q16 = - HP_NOISE_COEF_Q16 - \r
287             SKP_SMULWB( ( 1 << 16 ) - HP_NOISE_COEF_Q16, SKP_SMULWB( HARM_HP_NOISE_COEF_Q24, psEnc->speech_activity_Q8 ) );\r
288     } else {\r
289         b_Q14 = SKP_DIV32_16( 21299, psEnc->sCmn.fs_kHz ); // 1.3_Q0 = 21299_Q14\r
290         /* Pack two coefficients in one int32 */\r
291         psEncCtrl->LF_shp_Q14[ 0 ]  = SKP_LSHIFT( ( 1 << 14 ) - b_Q14 - SKP_SMULWB( strength_Q16, SKP_SMULWB( 39322, b_Q14 ) ), 16 ); // 0.6_Q0 = 39322_Q16\r
292         psEncCtrl->LF_shp_Q14[ 0 ] |= (SKP_uint16)( b_Q14 - ( 1 << 14 ) );\r
293         for( k = 1; k < NB_SUBFR; k++ ) {\r
294             psEncCtrl->LF_shp_Q14[ k ] = psEncCtrl->LF_shp_Q14[ k - 1 ];\r
295         }\r
296         Tilt_Q16 = -HP_NOISE_COEF_Q16;\r
297     }\r
298 \r
299     /****************************/\r
300     /* HARMONIC SHAPING CONTROL */\r
301     /****************************/\r
302     /* Control boosting of harmonic frequencies */\r
303     HarmBoost_Q16 = SKP_SMULWB( SKP_SMULWB( ( 1 << 17 ) - SKP_LSHIFT( psEncCtrl->coding_quality_Q14, 3 ), \r
304         psEnc->LTPCorr_Q15 ), LOW_RATE_HARMONIC_BOOST_Q16 );\r
305 \r
306     /* More harmonic boost for noisy input signals */\r
307     HarmBoost_Q16 = SKP_SMLAWB( HarmBoost_Q16, \r
308         ( 1 << 16 ) - SKP_LSHIFT( psEncCtrl->input_quality_Q14, 2 ), LOW_INPUT_QUALITY_HARMONIC_BOOST_Q16 );\r
309 \r
310     if( USE_HARM_SHAPING && psEncCtrl->sCmn.sigtype == SIG_TYPE_VOICED ) {\r
311         /* More harmonic noise shaping for high bitrates or noisy input */\r
312         HarmShapeGain_Q16 = SKP_SMLAWB( HARMONIC_SHAPING_Q16, \r
313                 ( 1 << 16 ) - SKP_SMULWB( ( 1 << 18 ) - SKP_LSHIFT( psEncCtrl->coding_quality_Q14, 4 ),\r
314                 psEncCtrl->input_quality_Q14 ), HIGH_RATE_OR_LOW_QUALITY_HARMONIC_SHAPING_Q16 );\r
315 \r
316         /* Less harmonic noise shaping for less periodic signals */\r
317         HarmShapeGain_Q16 = SKP_SMULWB( SKP_LSHIFT( HarmShapeGain_Q16, 1 ), \r
318             SKP_Silk_SQRT_APPROX( SKP_LSHIFT( psEnc->LTPCorr_Q15, 15 ) ) );\r
319     } else {\r
320         HarmShapeGain_Q16 = 0;\r
321     }\r
322 \r
323     /*************************/\r
324     /* Smooth over subframes */\r
325     /*************************/\r
326     for( k = 0; k < NB_SUBFR; k++ ) {\r
327         psShapeSt->HarmBoost_smth_Q16 =\r
328             SKP_SMLAWB( psShapeSt->HarmBoost_smth_Q16,     HarmBoost_Q16     - psShapeSt->HarmBoost_smth_Q16,     SUBFR_SMTH_COEF_Q16 );\r
329         psShapeSt->HarmShapeGain_smth_Q16 =\r
330             SKP_SMLAWB( psShapeSt->HarmShapeGain_smth_Q16, HarmShapeGain_Q16 - psShapeSt->HarmShapeGain_smth_Q16, SUBFR_SMTH_COEF_Q16 );\r
331         psShapeSt->Tilt_smth_Q16 =\r
332             SKP_SMLAWB( psShapeSt->Tilt_smth_Q16,          Tilt_Q16          - psShapeSt->Tilt_smth_Q16,          SUBFR_SMTH_COEF_Q16 );\r
333 \r
334         psEncCtrl->HarmBoost_Q14[ k ]     = ( SKP_int )SKP_RSHIFT_ROUND( psShapeSt->HarmBoost_smth_Q16,     2 );\r
335         psEncCtrl->HarmShapeGain_Q14[ k ] = ( SKP_int )SKP_RSHIFT_ROUND( psShapeSt->HarmShapeGain_smth_Q16, 2 );\r
336         psEncCtrl->Tilt_Q14[ k ]          = ( SKP_int )SKP_RSHIFT_ROUND( psShapeSt->Tilt_smth_Q16,          2 );\r
337     }\r
338 }\r