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