1/*********************************************************************** 2Copyright (c) 2006-2011, Skype Limited. All rights reserved. 3Redistribution and use in source and binary forms, with or without 4modification, are permitted provided that the following conditions 5are met: 6- Redistributions of source code must retain the above copyright notice, 7this list of conditions and the following disclaimer. 8- Redistributions in binary form must reproduce the above copyright 9notice, this list of conditions and the following disclaimer in the 10documentation and/or other materials provided with the distribution. 11- Neither the name of Internet Society, IETF or IETF Trust, nor the 12names of specific contributors, may be used to endorse or promote 13products derived from this software without specific prior written 14permission. 15THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 16AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 19LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 20CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 21SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 22INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 23CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 24ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 25POSSIBILITY 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. */ 40static 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 */ 59static 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/* Disable MIPS version until it's updated. */ 132#if 0 && defined(MIPSr1_ASM) 133#include "mips/noise_shape_analysis_FIX_mipsr1.h" 134#endif 135 136/**************************************************************/ 137/* Compute noise shaping coefficients and initial gain values */ 138/**************************************************************/ 139#ifndef OVERRIDE_silk_noise_shape_analysis_FIX 140void silk_noise_shape_analysis_FIX( 141 silk_encoder_state_FIX *psEnc, /* I/O Encoder state FIX */ 142 silk_encoder_control_FIX *psEncCtrl, /* I/O Encoder control FIX */ 143 const opus_int16 *pitch_res, /* I LPC residual from pitch analysis */ 144 const opus_int16 *x, /* I Input signal [ frame_length + la_shape ] */ 145 int arch /* I Run-time architecture */ 146) 147{ 148 silk_shape_state_FIX *psShapeSt = &psEnc->sShape; 149 opus_int k, i, nSamples, nSegs, Qnrg, b_Q14, warping_Q16, scale = 0; 150 opus_int32 SNR_adj_dB_Q7, HarmShapeGain_Q16, Tilt_Q16, tmp32; 151 opus_int32 nrg, log_energy_Q7, log_energy_prev_Q7, energy_variation_Q7; 152 opus_int32 BWExp_Q16, gain_mult_Q16, gain_add_Q16, strength_Q16, b_Q8; 153 opus_int32 auto_corr[ MAX_SHAPE_LPC_ORDER + 1 ]; 154 opus_int32 refl_coef_Q16[ MAX_SHAPE_LPC_ORDER ]; 155 opus_int32 AR_Q24[ MAX_SHAPE_LPC_ORDER ]; 156 VARDECL( opus_int16, x_windowed ); 157 const opus_int16 *x_ptr, *pitch_res_ptr; 158 SAVE_STACK; 159 160 /* Point to start of first LPC analysis block */ 161 x_ptr = x - psEnc->sCmn.la_shape; 162 163 /****************/ 164 /* GAIN CONTROL */ 165 /****************/ 166 SNR_adj_dB_Q7 = psEnc->sCmn.SNR_dB_Q7; 167 168 /* Input quality is the average of the quality in the lowest two VAD bands */ 169 psEncCtrl->input_quality_Q14 = ( opus_int )silk_RSHIFT( (opus_int32)psEnc->sCmn.input_quality_bands_Q15[ 0 ] 170 + psEnc->sCmn.input_quality_bands_Q15[ 1 ], 2 ); 171 172 /* Coding quality level, between 0.0_Q0 and 1.0_Q0, but in Q14 */ 173 psEncCtrl->coding_quality_Q14 = silk_RSHIFT( silk_sigm_Q15( silk_RSHIFT_ROUND( SNR_adj_dB_Q7 - 174 SILK_FIX_CONST( 20.0, 7 ), 4 ) ), 1 ); 175 176 /* Reduce coding SNR during low speech activity */ 177 if( psEnc->sCmn.useCBR == 0 ) { 178 b_Q8 = SILK_FIX_CONST( 1.0, 8 ) - psEnc->sCmn.speech_activity_Q8; 179 b_Q8 = silk_SMULWB( silk_LSHIFT( b_Q8, 8 ), b_Q8 ); 180 SNR_adj_dB_Q7 = silk_SMLAWB( SNR_adj_dB_Q7, 181 silk_SMULBB( SILK_FIX_CONST( -BG_SNR_DECR_dB, 7 ) >> ( 4 + 1 ), b_Q8 ), /* Q11*/ 182 silk_SMULWB( SILK_FIX_CONST( 1.0, 14 ) + psEncCtrl->input_quality_Q14, psEncCtrl->coding_quality_Q14 ) ); /* Q12*/ 183 } 184 185 if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) { 186 /* Reduce gains for periodic signals */ 187 SNR_adj_dB_Q7 = silk_SMLAWB( SNR_adj_dB_Q7, SILK_FIX_CONST( HARM_SNR_INCR_dB, 8 ), psEnc->LTPCorr_Q15 ); 188 } else { 189 /* For unvoiced signals and low-quality input, adjust the quality slower than SNR_dB setting */ 190 SNR_adj_dB_Q7 = silk_SMLAWB( SNR_adj_dB_Q7, 191 silk_SMLAWB( SILK_FIX_CONST( 6.0, 9 ), -SILK_FIX_CONST( 0.4, 18 ), psEnc->sCmn.SNR_dB_Q7 ), 192 SILK_FIX_CONST( 1.0, 14 ) - psEncCtrl->input_quality_Q14 ); 193 } 194 195 /*************************/ 196 /* SPARSENESS PROCESSING */ 197 /*************************/ 198 /* Set quantizer offset */ 199 if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) { 200 /* Initially set to 0; may be overruled in process_gains(..) */ 201 psEnc->sCmn.indices.quantOffsetType = 0; 202 } else { 203 /* Sparseness measure, based on relative fluctuations of energy per 2 milliseconds */ 204 nSamples = silk_LSHIFT( psEnc->sCmn.fs_kHz, 1 ); 205 energy_variation_Q7 = 0; 206 log_energy_prev_Q7 = 0; 207 pitch_res_ptr = pitch_res; 208 nSegs = silk_SMULBB( SUB_FRAME_LENGTH_MS, psEnc->sCmn.nb_subfr ) / 2; 209 for( k = 0; k < nSegs; k++ ) { 210 silk_sum_sqr_shift( &nrg, &scale, pitch_res_ptr, nSamples ); 211 nrg += silk_RSHIFT( nSamples, scale ); /* Q(-scale)*/ 212 213 log_energy_Q7 = silk_lin2log( nrg ); 214 if( k > 0 ) { 215 energy_variation_Q7 += silk_abs( log_energy_Q7 - log_energy_prev_Q7 ); 216 } 217 log_energy_prev_Q7 = log_energy_Q7; 218 pitch_res_ptr += nSamples; 219 } 220 221 /* Set quantization offset depending on sparseness measure */ 222 if( energy_variation_Q7 > SILK_FIX_CONST( ENERGY_VARIATION_THRESHOLD_QNT_OFFSET, 7 ) * (nSegs-1) ) { 223 psEnc->sCmn.indices.quantOffsetType = 0; 224 } else { 225 psEnc->sCmn.indices.quantOffsetType = 1; 226 } 227 } 228 229 /*******************************/ 230 /* Control bandwidth expansion */ 231 /*******************************/ 232 /* More BWE for signals with high prediction gain */ 233 strength_Q16 = silk_SMULWB( psEncCtrl->predGain_Q16, SILK_FIX_CONST( FIND_PITCH_WHITE_NOISE_FRACTION, 16 ) ); 234 BWExp_Q16 = silk_DIV32_varQ( SILK_FIX_CONST( BANDWIDTH_EXPANSION, 16 ), 235 silk_SMLAWW( SILK_FIX_CONST( 1.0, 16 ), strength_Q16, strength_Q16 ), 16 ); 236 237 if( psEnc->sCmn.warping_Q16 > 0 ) { 238 /* Slightly more warping in analysis will move quantization noise up in frequency, where it's better masked */ 239 warping_Q16 = silk_SMLAWB( psEnc->sCmn.warping_Q16, (opus_int32)psEncCtrl->coding_quality_Q14, SILK_FIX_CONST( 0.01, 18 ) ); 240 } else { 241 warping_Q16 = 0; 242 } 243 244 /********************************************/ 245 /* Compute noise shaping AR coefs and gains */ 246 /********************************************/ 247 ALLOC( x_windowed, psEnc->sCmn.shapeWinLength, opus_int16 ); 248 for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) { 249 /* Apply window: sine slope followed by flat part followed by cosine slope */ 250 opus_int shift, slope_part, flat_part; 251 flat_part = psEnc->sCmn.fs_kHz * 3; 252 slope_part = silk_RSHIFT( psEnc->sCmn.shapeWinLength - flat_part, 1 ); 253 254 silk_apply_sine_window( x_windowed, x_ptr, 1, slope_part ); 255 shift = slope_part; 256 silk_memcpy( x_windowed + shift, x_ptr + shift, flat_part * sizeof(opus_int16) ); 257 shift += flat_part; 258 silk_apply_sine_window( x_windowed + shift, x_ptr + shift, 2, slope_part ); 259 260 /* Update pointer: next LPC analysis block */ 261 x_ptr += psEnc->sCmn.subfr_length; 262 263 if( psEnc->sCmn.warping_Q16 > 0 ) { 264 /* Calculate warped auto correlation */ 265 silk_warped_autocorrelation_FIX( auto_corr, &scale, x_windowed, warping_Q16, psEnc->sCmn.shapeWinLength, psEnc->sCmn.shapingLPCOrder, arch ); 266 } else { 267 /* Calculate regular auto correlation */ 268 silk_autocorr( auto_corr, &scale, x_windowed, psEnc->sCmn.shapeWinLength, psEnc->sCmn.shapingLPCOrder + 1, arch ); 269 } 270 271 /* Add white noise, as a fraction of energy */ 272 auto_corr[0] = silk_ADD32( auto_corr[0], silk_max_32( silk_SMULWB( silk_RSHIFT( auto_corr[ 0 ], 4 ), 273 SILK_FIX_CONST( SHAPE_WHITE_NOISE_FRACTION, 20 ) ), 1 ) ); 274 275 /* Calculate the reflection coefficients using schur */ 276 nrg = silk_schur64( refl_coef_Q16, auto_corr, psEnc->sCmn.shapingLPCOrder ); 277 silk_assert( nrg >= 0 ); 278 279 /* Convert reflection coefficients to prediction coefficients */ 280 silk_k2a_Q16( AR_Q24, refl_coef_Q16, psEnc->sCmn.shapingLPCOrder ); 281 282 Qnrg = -scale; /* range: -12...30*/ 283 silk_assert( Qnrg >= -12 ); 284 silk_assert( Qnrg <= 30 ); 285 286 /* Make sure that Qnrg is an even number */ 287 if( Qnrg & 1 ) { 288 Qnrg -= 1; 289 nrg >>= 1; 290 } 291 292 tmp32 = silk_SQRT_APPROX( nrg ); 293 Qnrg >>= 1; /* range: -6...15*/ 294 295 psEncCtrl->Gains_Q16[ k ] = silk_LSHIFT_SAT32( tmp32, 16 - Qnrg ); 296 297 if( psEnc->sCmn.warping_Q16 > 0 ) { 298 /* Adjust gain for warping */ 299 gain_mult_Q16 = warped_gain( AR_Q24, warping_Q16, psEnc->sCmn.shapingLPCOrder ); 300 silk_assert( psEncCtrl->Gains_Q16[ k ] > 0 ); 301 if( psEncCtrl->Gains_Q16[ k ] < SILK_FIX_CONST( 0.25, 16 ) ) { 302 psEncCtrl->Gains_Q16[ k ] = silk_SMULWW( psEncCtrl->Gains_Q16[ k ], gain_mult_Q16 ); 303 } else { 304 psEncCtrl->Gains_Q16[ k ] = silk_SMULWW( silk_RSHIFT_ROUND( psEncCtrl->Gains_Q16[ k ], 1 ), gain_mult_Q16 ); 305 if ( psEncCtrl->Gains_Q16[ k ] >= ( silk_int32_MAX >> 1 ) ) { 306 psEncCtrl->Gains_Q16[ k ] = silk_int32_MAX; 307 } else { 308 psEncCtrl->Gains_Q16[ k ] = silk_LSHIFT32( psEncCtrl->Gains_Q16[ k ], 1 ); 309 } 310 } 311 silk_assert( psEncCtrl->Gains_Q16[ k ] > 0 ); 312 } 313 314 /* Bandwidth expansion */ 315 silk_bwexpander_32( AR_Q24, psEnc->sCmn.shapingLPCOrder, BWExp_Q16 ); 316 317 if( psEnc->sCmn.warping_Q16 > 0 ) { 318 /* Convert to monic warped prediction coefficients and limit absolute values */ 319 limit_warped_coefs( AR_Q24, warping_Q16, SILK_FIX_CONST( 3.999, 24 ), psEnc->sCmn.shapingLPCOrder ); 320 321 /* Convert from Q24 to Q13 and store in int16 */ 322 for( i = 0; i < psEnc->sCmn.shapingLPCOrder; i++ ) { 323 psEncCtrl->AR_Q13[ k * MAX_SHAPE_LPC_ORDER + i ] = (opus_int16)silk_SAT16( silk_RSHIFT_ROUND( AR_Q24[ i ], 11 ) ); 324 } 325 } else { 326 silk_LPC_fit( &psEncCtrl->AR_Q13[ k * MAX_SHAPE_LPC_ORDER ], AR_Q24, 13, 24, psEnc->sCmn.shapingLPCOrder ); 327 } 328 } 329 330 /*****************/ 331 /* Gain tweaking */ 332 /*****************/ 333 /* Increase gains during low speech activity and put lower limit on gains */ 334 gain_mult_Q16 = silk_log2lin( -silk_SMLAWB( -SILK_FIX_CONST( 16.0, 7 ), SNR_adj_dB_Q7, SILK_FIX_CONST( 0.16, 16 ) ) ); 335 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 ) ) ); 336 silk_assert( gain_mult_Q16 > 0 ); 337 for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) { 338 psEncCtrl->Gains_Q16[ k ] = silk_SMULWW( psEncCtrl->Gains_Q16[ k ], gain_mult_Q16 ); 339 silk_assert( psEncCtrl->Gains_Q16[ k ] >= 0 ); 340 psEncCtrl->Gains_Q16[ k ] = silk_ADD_POS_SAT32( psEncCtrl->Gains_Q16[ k ], gain_add_Q16 ); 341 } 342 343 344 /************************************************/ 345 /* Control low-frequency shaping and noise tilt */ 346 /************************************************/ 347 /* Less low frequency shaping for noisy inputs */ 348 strength_Q16 = silk_MUL( SILK_FIX_CONST( LOW_FREQ_SHAPING, 4 ), silk_SMLAWB( SILK_FIX_CONST( 1.0, 12 ), 349 SILK_FIX_CONST( LOW_QUALITY_LOW_FREQ_SHAPING_DECR, 13 ), psEnc->sCmn.input_quality_bands_Q15[ 0 ] - SILK_FIX_CONST( 1.0, 15 ) ) ); 350 strength_Q16 = silk_RSHIFT( silk_MUL( strength_Q16, psEnc->sCmn.speech_activity_Q8 ), 8 ); 351 if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) { 352 /* Reduce low frequencies quantization noise for periodic signals, depending on pitch lag */ 353 /*f = 400; freqz([1, -0.98 + 2e-4 * f], [1, -0.97 + 7e-4 * f], 2^12, Fs); axis([0, 1000, -10, 1])*/ 354 opus_int fs_kHz_inv = silk_DIV32_16( SILK_FIX_CONST( 0.2, 14 ), psEnc->sCmn.fs_kHz ); 355 for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) { 356 b_Q14 = fs_kHz_inv + silk_DIV32_16( SILK_FIX_CONST( 3.0, 14 ), psEncCtrl->pitchL[ k ] ); 357 /* Pack two coefficients in one int32 */ 358 psEncCtrl->LF_shp_Q14[ k ] = silk_LSHIFT( SILK_FIX_CONST( 1.0, 14 ) - b_Q14 - silk_SMULWB( strength_Q16, b_Q14 ), 16 ); 359 psEncCtrl->LF_shp_Q14[ k ] |= (opus_uint16)( b_Q14 - SILK_FIX_CONST( 1.0, 14 ) ); 360 } 361 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*/ 362 Tilt_Q16 = - SILK_FIX_CONST( HP_NOISE_COEF, 16 ) - 363 silk_SMULWB( SILK_FIX_CONST( 1.0, 16 ) - SILK_FIX_CONST( HP_NOISE_COEF, 16 ), 364 silk_SMULWB( SILK_FIX_CONST( HARM_HP_NOISE_COEF, 24 ), psEnc->sCmn.speech_activity_Q8 ) ); 365 } else { 366 b_Q14 = silk_DIV32_16( 21299, psEnc->sCmn.fs_kHz ); /* 1.3_Q0 = 21299_Q14*/ 367 /* Pack two coefficients in one int32 */ 368 psEncCtrl->LF_shp_Q14[ 0 ] = silk_LSHIFT( SILK_FIX_CONST( 1.0, 14 ) - b_Q14 - 369 silk_SMULWB( strength_Q16, silk_SMULWB( SILK_FIX_CONST( 0.6, 16 ), b_Q14 ) ), 16 ); 370 psEncCtrl->LF_shp_Q14[ 0 ] |= (opus_uint16)( b_Q14 - SILK_FIX_CONST( 1.0, 14 ) ); 371 for( k = 1; k < psEnc->sCmn.nb_subfr; k++ ) { 372 psEncCtrl->LF_shp_Q14[ k ] = psEncCtrl->LF_shp_Q14[ 0 ]; 373 } 374 Tilt_Q16 = -SILK_FIX_CONST( HP_NOISE_COEF, 16 ); 375 } 376 377 /****************************/ 378 /* HARMONIC SHAPING CONTROL */ 379 /****************************/ 380 if( USE_HARM_SHAPING && psEnc->sCmn.indices.signalType == TYPE_VOICED ) { 381 /* More harmonic noise shaping for high bitrates or noisy input */ 382 HarmShapeGain_Q16 = silk_SMLAWB( SILK_FIX_CONST( HARMONIC_SHAPING, 16 ), 383 SILK_FIX_CONST( 1.0, 16 ) - silk_SMULWB( SILK_FIX_CONST( 1.0, 18 ) - silk_LSHIFT( psEncCtrl->coding_quality_Q14, 4 ), 384 psEncCtrl->input_quality_Q14 ), SILK_FIX_CONST( HIGH_RATE_OR_LOW_QUALITY_HARMONIC_SHAPING, 16 ) ); 385 386 /* Less harmonic noise shaping for less periodic signals */ 387 HarmShapeGain_Q16 = silk_SMULWB( silk_LSHIFT( HarmShapeGain_Q16, 1 ), 388 silk_SQRT_APPROX( silk_LSHIFT( psEnc->LTPCorr_Q15, 15 ) ) ); 389 } else { 390 HarmShapeGain_Q16 = 0; 391 } 392 393 /*************************/ 394 /* Smooth over subframes */ 395 /*************************/ 396 for( k = 0; k < MAX_NB_SUBFR; k++ ) { 397 psShapeSt->HarmShapeGain_smth_Q16 = 398 silk_SMLAWB( psShapeSt->HarmShapeGain_smth_Q16, HarmShapeGain_Q16 - psShapeSt->HarmShapeGain_smth_Q16, SILK_FIX_CONST( SUBFR_SMTH_COEF, 16 ) ); 399 psShapeSt->Tilt_smth_Q16 = 400 silk_SMLAWB( psShapeSt->Tilt_smth_Q16, Tilt_Q16 - psShapeSt->Tilt_smth_Q16, SILK_FIX_CONST( SUBFR_SMTH_COEF, 16 ) ); 401 402 psEncCtrl->HarmShapeGain_Q14[ k ] = ( opus_int )silk_RSHIFT_ROUND( psShapeSt->HarmShapeGain_smth_Q16, 2 ); 403 psEncCtrl->Tilt_Q14[ k ] = ( opus_int )silk_RSHIFT_ROUND( psShapeSt->Tilt_smth_Q16, 2 ); 404 } 405 RESTORE_STACK; 406} 407#endif /* OVERRIDE_silk_noise_shape_analysis_FIX */ 408