media/libopus/silk/float/noise_shape_analysis_FLP.c

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

michael@0 1 /***********************************************************************
michael@0 2 Copyright (c) 2006-2011, Skype Limited. All rights reserved.
michael@0 3 Redistribution and use in source and binary forms, with or without
michael@0 4 modification, are permitted provided that the following conditions
michael@0 5 are met:
michael@0 6 - Redistributions of source code must retain the above copyright notice,
michael@0 7 this list of conditions and the following disclaimer.
michael@0 8 - Redistributions in binary form must reproduce the above copyright
michael@0 9 notice, this list of conditions and the following disclaimer in the
michael@0 10 documentation and/or other materials provided with the distribution.
michael@0 11 - Neither the name of Internet Society, IETF or IETF Trust, nor the
michael@0 12 names of specific contributors, may be used to endorse or promote
michael@0 13 products derived from this software without specific prior written
michael@0 14 permission.
michael@0 15 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
michael@0 16 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
michael@0 17 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
michael@0 18 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
michael@0 19 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
michael@0 20 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
michael@0 21 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
michael@0 22 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
michael@0 23 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
michael@0 24 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
michael@0 25 POSSIBILITY OF SUCH DAMAGE.
michael@0 26 ***********************************************************************/
michael@0 27
michael@0 28 #ifdef HAVE_CONFIG_H
michael@0 29 #include "config.h"
michael@0 30 #endif
michael@0 31
michael@0 32 #include "main_FLP.h"
michael@0 33 #include "tuning_parameters.h"
michael@0 34
michael@0 35 /* Compute gain to make warped filter coefficients have a zero mean log frequency response on a */
michael@0 36 /* non-warped frequency scale. (So that it can be implemented with a minimum-phase monic filter.) */
michael@0 37 /* Note: A monic filter is one with the first coefficient equal to 1.0. In Silk we omit the first */
michael@0 38 /* coefficient in an array of coefficients, for monic filters. */
michael@0 39 static OPUS_INLINE silk_float warped_gain(
michael@0 40 const silk_float *coefs,
michael@0 41 silk_float lambda,
michael@0 42 opus_int order
michael@0 43 ) {
michael@0 44 opus_int i;
michael@0 45 silk_float gain;
michael@0 46
michael@0 47 lambda = -lambda;
michael@0 48 gain = coefs[ order - 1 ];
michael@0 49 for( i = order - 2; i >= 0; i-- ) {
michael@0 50 gain = lambda * gain + coefs[ i ];
michael@0 51 }
michael@0 52 return (silk_float)( 1.0f / ( 1.0f - lambda * gain ) );
michael@0 53 }
michael@0 54
michael@0 55 /* Convert warped filter coefficients to monic pseudo-warped coefficients and limit maximum */
michael@0 56 /* amplitude of monic warped coefficients by using bandwidth expansion on the true coefficients */
michael@0 57 static OPUS_INLINE void warped_true2monic_coefs(
michael@0 58 silk_float *coefs_syn,
michael@0 59 silk_float *coefs_ana,
michael@0 60 silk_float lambda,
michael@0 61 silk_float limit,
michael@0 62 opus_int order
michael@0 63 ) {
michael@0 64 opus_int i, iter, ind = 0;
michael@0 65 silk_float tmp, maxabs, chirp, gain_syn, gain_ana;
michael@0 66
michael@0 67 /* Convert to monic coefficients */
michael@0 68 for( i = order - 1; i > 0; i-- ) {
michael@0 69 coefs_syn[ i - 1 ] -= lambda * coefs_syn[ i ];
michael@0 70 coefs_ana[ i - 1 ] -= lambda * coefs_ana[ i ];
michael@0 71 }
michael@0 72 gain_syn = ( 1.0f - lambda * lambda ) / ( 1.0f + lambda * coefs_syn[ 0 ] );
michael@0 73 gain_ana = ( 1.0f - lambda * lambda ) / ( 1.0f + lambda * coefs_ana[ 0 ] );
michael@0 74 for( i = 0; i < order; i++ ) {
michael@0 75 coefs_syn[ i ] *= gain_syn;
michael@0 76 coefs_ana[ i ] *= gain_ana;
michael@0 77 }
michael@0 78
michael@0 79 /* Limit */
michael@0 80 for( iter = 0; iter < 10; iter++ ) {
michael@0 81 /* Find maximum absolute value */
michael@0 82 maxabs = -1.0f;
michael@0 83 for( i = 0; i < order; i++ ) {
michael@0 84 tmp = silk_max( silk_abs_float( coefs_syn[ i ] ), silk_abs_float( coefs_ana[ i ] ) );
michael@0 85 if( tmp > maxabs ) {
michael@0 86 maxabs = tmp;
michael@0 87 ind = i;
michael@0 88 }
michael@0 89 }
michael@0 90 if( maxabs <= limit ) {
michael@0 91 /* Coefficients are within range - done */
michael@0 92 return;
michael@0 93 }
michael@0 94
michael@0 95 /* Convert back to true warped coefficients */
michael@0 96 for( i = 1; i < order; i++ ) {
michael@0 97 coefs_syn[ i - 1 ] += lambda * coefs_syn[ i ];
michael@0 98 coefs_ana[ i - 1 ] += lambda * coefs_ana[ i ];
michael@0 99 }
michael@0 100 gain_syn = 1.0f / gain_syn;
michael@0 101 gain_ana = 1.0f / gain_ana;
michael@0 102 for( i = 0; i < order; i++ ) {
michael@0 103 coefs_syn[ i ] *= gain_syn;
michael@0 104 coefs_ana[ i ] *= gain_ana;
michael@0 105 }
michael@0 106
michael@0 107 /* Apply bandwidth expansion */
michael@0 108 chirp = 0.99f - ( 0.8f + 0.1f * iter ) * ( maxabs - limit ) / ( maxabs * ( ind + 1 ) );
michael@0 109 silk_bwexpander_FLP( coefs_syn, order, chirp );
michael@0 110 silk_bwexpander_FLP( coefs_ana, order, chirp );
michael@0 111
michael@0 112 /* Convert to monic warped coefficients */
michael@0 113 for( i = order - 1; i > 0; i-- ) {
michael@0 114 coefs_syn[ i - 1 ] -= lambda * coefs_syn[ i ];
michael@0 115 coefs_ana[ i - 1 ] -= lambda * coefs_ana[ i ];
michael@0 116 }
michael@0 117 gain_syn = ( 1.0f - lambda * lambda ) / ( 1.0f + lambda * coefs_syn[ 0 ] );
michael@0 118 gain_ana = ( 1.0f - lambda * lambda ) / ( 1.0f + lambda * coefs_ana[ 0 ] );
michael@0 119 for( i = 0; i < order; i++ ) {
michael@0 120 coefs_syn[ i ] *= gain_syn;
michael@0 121 coefs_ana[ i ] *= gain_ana;
michael@0 122 }
michael@0 123 }
michael@0 124 silk_assert( 0 );
michael@0 125 }
michael@0 126
michael@0 127 /* Compute noise shaping coefficients and initial gain values */
michael@0 128 void silk_noise_shape_analysis_FLP(
michael@0 129 silk_encoder_state_FLP *psEnc, /* I/O Encoder state FLP */
michael@0 130 silk_encoder_control_FLP *psEncCtrl, /* I/O Encoder control FLP */
michael@0 131 const silk_float *pitch_res, /* I LPC residual from pitch analysis */
michael@0 132 const silk_float *x /* I Input signal [frame_length + la_shape] */
michael@0 133 )
michael@0 134 {
michael@0 135 silk_shape_state_FLP *psShapeSt = &psEnc->sShape;
michael@0 136 opus_int k, nSamples;
michael@0 137 silk_float SNR_adj_dB, HarmBoost, HarmShapeGain, Tilt;
michael@0 138 silk_float nrg, pre_nrg, log_energy, log_energy_prev, energy_variation;
michael@0 139 silk_float delta, BWExp1, BWExp2, gain_mult, gain_add, strength, b, warping;
michael@0 140 silk_float x_windowed[ SHAPE_LPC_WIN_MAX ];
michael@0 141 silk_float auto_corr[ MAX_SHAPE_LPC_ORDER + 1 ];
michael@0 142 const silk_float *x_ptr, *pitch_res_ptr;
michael@0 143
michael@0 144 /* Point to start of first LPC analysis block */
michael@0 145 x_ptr = x - psEnc->sCmn.la_shape;
michael@0 146
michael@0 147 /****************/
michael@0 148 /* GAIN CONTROL */
michael@0 149 /****************/
michael@0 150 SNR_adj_dB = psEnc->sCmn.SNR_dB_Q7 * ( 1 / 128.0f );
michael@0 151
michael@0 152 /* Input quality is the average of the quality in the lowest two VAD bands */
michael@0 153 psEncCtrl->input_quality = 0.5f * ( psEnc->sCmn.input_quality_bands_Q15[ 0 ] + psEnc->sCmn.input_quality_bands_Q15[ 1 ] ) * ( 1.0f / 32768.0f );
michael@0 154
michael@0 155 /* Coding quality level, between 0.0 and 1.0 */
michael@0 156 psEncCtrl->coding_quality = silk_sigmoid( 0.25f * ( SNR_adj_dB - 20.0f ) );
michael@0 157
michael@0 158 if( psEnc->sCmn.useCBR == 0 ) {
michael@0 159 /* Reduce coding SNR during low speech activity */
michael@0 160 b = 1.0f - psEnc->sCmn.speech_activity_Q8 * ( 1.0f / 256.0f );
michael@0 161 SNR_adj_dB -= BG_SNR_DECR_dB * psEncCtrl->coding_quality * ( 0.5f + 0.5f * psEncCtrl->input_quality ) * b * b;
michael@0 162 }
michael@0 163
michael@0 164 if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) {
michael@0 165 /* Reduce gains for periodic signals */
michael@0 166 SNR_adj_dB += HARM_SNR_INCR_dB * psEnc->LTPCorr;
michael@0 167 } else {
michael@0 168 /* For unvoiced signals and low-quality input, adjust the quality slower than SNR_dB setting */
michael@0 169 SNR_adj_dB += ( -0.4f * psEnc->sCmn.SNR_dB_Q7 * ( 1 / 128.0f ) + 6.0f ) * ( 1.0f - psEncCtrl->input_quality );
michael@0 170 }
michael@0 171
michael@0 172 /*************************/
michael@0 173 /* SPARSENESS PROCESSING */
michael@0 174 /*************************/
michael@0 175 /* Set quantizer offset */
michael@0 176 if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) {
michael@0 177 /* Initially set to 0; may be overruled in process_gains(..) */
michael@0 178 psEnc->sCmn.indices.quantOffsetType = 0;
michael@0 179 psEncCtrl->sparseness = 0.0f;
michael@0 180 } else {
michael@0 181 /* Sparseness measure, based on relative fluctuations of energy per 2 milliseconds */
michael@0 182 nSamples = 2 * psEnc->sCmn.fs_kHz;
michael@0 183 energy_variation = 0.0f;
michael@0 184 log_energy_prev = 0.0f;
michael@0 185 pitch_res_ptr = pitch_res;
michael@0 186 for( k = 0; k < silk_SMULBB( SUB_FRAME_LENGTH_MS, psEnc->sCmn.nb_subfr ) / 2; k++ ) {
michael@0 187 nrg = ( silk_float )nSamples + ( silk_float )silk_energy_FLP( pitch_res_ptr, nSamples );
michael@0 188 log_energy = silk_log2( nrg );
michael@0 189 if( k > 0 ) {
michael@0 190 energy_variation += silk_abs_float( log_energy - log_energy_prev );
michael@0 191 }
michael@0 192 log_energy_prev = log_energy;
michael@0 193 pitch_res_ptr += nSamples;
michael@0 194 }
michael@0 195 psEncCtrl->sparseness = silk_sigmoid( 0.4f * ( energy_variation - 5.0f ) );
michael@0 196
michael@0 197 /* Set quantization offset depending on sparseness measure */
michael@0 198 if( psEncCtrl->sparseness > SPARSENESS_THRESHOLD_QNT_OFFSET ) {
michael@0 199 psEnc->sCmn.indices.quantOffsetType = 0;
michael@0 200 } else {
michael@0 201 psEnc->sCmn.indices.quantOffsetType = 1;
michael@0 202 }
michael@0 203
michael@0 204 /* Increase coding SNR for sparse signals */
michael@0 205 SNR_adj_dB += SPARSE_SNR_INCR_dB * ( psEncCtrl->sparseness - 0.5f );
michael@0 206 }
michael@0 207
michael@0 208 /*******************************/
michael@0 209 /* Control bandwidth expansion */
michael@0 210 /*******************************/
michael@0 211 /* More BWE for signals with high prediction gain */
michael@0 212 strength = FIND_PITCH_WHITE_NOISE_FRACTION * psEncCtrl->predGain; /* between 0.0 and 1.0 */
michael@0 213 BWExp1 = BWExp2 = BANDWIDTH_EXPANSION / ( 1.0f + strength * strength );
michael@0 214 delta = LOW_RATE_BANDWIDTH_EXPANSION_DELTA * ( 1.0f - 0.75f * psEncCtrl->coding_quality );
michael@0 215 BWExp1 -= delta;
michael@0 216 BWExp2 += delta;
michael@0 217 /* BWExp1 will be applied after BWExp2, so make it relative */
michael@0 218 BWExp1 /= BWExp2;
michael@0 219
michael@0 220 if( psEnc->sCmn.warping_Q16 > 0 ) {
michael@0 221 /* Slightly more warping in analysis will move quantization noise up in frequency, where it's better masked */
michael@0 222 warping = (silk_float)psEnc->sCmn.warping_Q16 / 65536.0f + 0.01f * psEncCtrl->coding_quality;
michael@0 223 } else {
michael@0 224 warping = 0.0f;
michael@0 225 }
michael@0 226
michael@0 227 /********************************************/
michael@0 228 /* Compute noise shaping AR coefs and gains */
michael@0 229 /********************************************/
michael@0 230 for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) {
michael@0 231 /* Apply window: sine slope followed by flat part followed by cosine slope */
michael@0 232 opus_int shift, slope_part, flat_part;
michael@0 233 flat_part = psEnc->sCmn.fs_kHz * 3;
michael@0 234 slope_part = ( psEnc->sCmn.shapeWinLength - flat_part ) / 2;
michael@0 235
michael@0 236 silk_apply_sine_window_FLP( x_windowed, x_ptr, 1, slope_part );
michael@0 237 shift = slope_part;
michael@0 238 silk_memcpy( x_windowed + shift, x_ptr + shift, flat_part * sizeof(silk_float) );
michael@0 239 shift += flat_part;
michael@0 240 silk_apply_sine_window_FLP( x_windowed + shift, x_ptr + shift, 2, slope_part );
michael@0 241
michael@0 242 /* Update pointer: next LPC analysis block */
michael@0 243 x_ptr += psEnc->sCmn.subfr_length;
michael@0 244
michael@0 245 if( psEnc->sCmn.warping_Q16 > 0 ) {
michael@0 246 /* Calculate warped auto correlation */
michael@0 247 silk_warped_autocorrelation_FLP( auto_corr, x_windowed, warping,
michael@0 248 psEnc->sCmn.shapeWinLength, psEnc->sCmn.shapingLPCOrder );
michael@0 249 } else {
michael@0 250 /* Calculate regular auto correlation */
michael@0 251 silk_autocorrelation_FLP( auto_corr, x_windowed, psEnc->sCmn.shapeWinLength, psEnc->sCmn.shapingLPCOrder + 1 );
michael@0 252 }
michael@0 253
michael@0 254 /* Add white noise, as a fraction of energy */
michael@0 255 auto_corr[ 0 ] += auto_corr[ 0 ] * SHAPE_WHITE_NOISE_FRACTION;
michael@0 256
michael@0 257 /* Convert correlations to prediction coefficients, and compute residual energy */
michael@0 258 nrg = silk_levinsondurbin_FLP( &psEncCtrl->AR2[ k * MAX_SHAPE_LPC_ORDER ], auto_corr, psEnc->sCmn.shapingLPCOrder );
michael@0 259 psEncCtrl->Gains[ k ] = ( silk_float )sqrt( nrg );
michael@0 260
michael@0 261 if( psEnc->sCmn.warping_Q16 > 0 ) {
michael@0 262 /* Adjust gain for warping */
michael@0 263 psEncCtrl->Gains[ k ] *= warped_gain( &psEncCtrl->AR2[ k * MAX_SHAPE_LPC_ORDER ], warping, psEnc->sCmn.shapingLPCOrder );
michael@0 264 }
michael@0 265
michael@0 266 /* Bandwidth expansion for synthesis filter shaping */
michael@0 267 silk_bwexpander_FLP( &psEncCtrl->AR2[ k * MAX_SHAPE_LPC_ORDER ], psEnc->sCmn.shapingLPCOrder, BWExp2 );
michael@0 268
michael@0 269 /* Compute noise shaping filter coefficients */
michael@0 270 silk_memcpy(
michael@0 271 &psEncCtrl->AR1[ k * MAX_SHAPE_LPC_ORDER ],
michael@0 272 &psEncCtrl->AR2[ k * MAX_SHAPE_LPC_ORDER ],
michael@0 273 psEnc->sCmn.shapingLPCOrder * sizeof( silk_float ) );
michael@0 274
michael@0 275 /* Bandwidth expansion for analysis filter shaping */
michael@0 276 silk_bwexpander_FLP( &psEncCtrl->AR1[ k * MAX_SHAPE_LPC_ORDER ], psEnc->sCmn.shapingLPCOrder, BWExp1 );
michael@0 277
michael@0 278 /* Ratio of prediction gains, in energy domain */
michael@0 279 pre_nrg = silk_LPC_inverse_pred_gain_FLP( &psEncCtrl->AR2[ k * MAX_SHAPE_LPC_ORDER ], psEnc->sCmn.shapingLPCOrder );
michael@0 280 nrg = silk_LPC_inverse_pred_gain_FLP( &psEncCtrl->AR1[ k * MAX_SHAPE_LPC_ORDER ], psEnc->sCmn.shapingLPCOrder );
michael@0 281 psEncCtrl->GainsPre[ k ] = 1.0f - 0.7f * ( 1.0f - pre_nrg / nrg );
michael@0 282
michael@0 283 /* Convert to monic warped prediction coefficients and limit absolute values */
michael@0 284 warped_true2monic_coefs( &psEncCtrl->AR2[ k * MAX_SHAPE_LPC_ORDER ], &psEncCtrl->AR1[ k * MAX_SHAPE_LPC_ORDER ],
michael@0 285 warping, 3.999f, psEnc->sCmn.shapingLPCOrder );
michael@0 286 }
michael@0 287
michael@0 288 /*****************/
michael@0 289 /* Gain tweaking */
michael@0 290 /*****************/
michael@0 291 /* Increase gains during low speech activity */
michael@0 292 gain_mult = (silk_float)pow( 2.0f, -0.16f * SNR_adj_dB );
michael@0 293 gain_add = (silk_float)pow( 2.0f, 0.16f * MIN_QGAIN_DB );
michael@0 294 for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) {
michael@0 295 psEncCtrl->Gains[ k ] *= gain_mult;
michael@0 296 psEncCtrl->Gains[ k ] += gain_add;
michael@0 297 }
michael@0 298
michael@0 299 gain_mult = 1.0f + INPUT_TILT + psEncCtrl->coding_quality * HIGH_RATE_INPUT_TILT;
michael@0 300 for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) {
michael@0 301 psEncCtrl->GainsPre[ k ] *= gain_mult;
michael@0 302 }
michael@0 303
michael@0 304 /************************************************/
michael@0 305 /* Control low-frequency shaping and noise tilt */
michael@0 306 /************************************************/
michael@0 307 /* Less low frequency shaping for noisy inputs */
michael@0 308 strength = LOW_FREQ_SHAPING * ( 1.0f + LOW_QUALITY_LOW_FREQ_SHAPING_DECR * ( psEnc->sCmn.input_quality_bands_Q15[ 0 ] * ( 1.0f / 32768.0f ) - 1.0f ) );
michael@0 309 strength *= psEnc->sCmn.speech_activity_Q8 * ( 1.0f / 256.0f );
michael@0 310 if( psEnc->sCmn.indices.signalType == TYPE_VOICED ) {
michael@0 311 /* Reduce low frequencies quantization noise for periodic signals, depending on pitch lag */
michael@0 312 /*f = 400; freqz([1, -0.98 + 2e-4 * f], [1, -0.97 + 7e-4 * f], 2^12, Fs); axis([0, 1000, -10, 1])*/
michael@0 313 for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) {
michael@0 314 b = 0.2f / psEnc->sCmn.fs_kHz + 3.0f / psEncCtrl->pitchL[ k ];
michael@0 315 psEncCtrl->LF_MA_shp[ k ] = -1.0f + b;
michael@0 316 psEncCtrl->LF_AR_shp[ k ] = 1.0f - b - b * strength;
michael@0 317 }
michael@0 318 Tilt = - HP_NOISE_COEF -
michael@0 319 (1 - HP_NOISE_COEF) * HARM_HP_NOISE_COEF * psEnc->sCmn.speech_activity_Q8 * ( 1.0f / 256.0f );
michael@0 320 } else {
michael@0 321 b = 1.3f / psEnc->sCmn.fs_kHz;
michael@0 322 psEncCtrl->LF_MA_shp[ 0 ] = -1.0f + b;
michael@0 323 psEncCtrl->LF_AR_shp[ 0 ] = 1.0f - b - b * strength * 0.6f;
michael@0 324 for( k = 1; k < psEnc->sCmn.nb_subfr; k++ ) {
michael@0 325 psEncCtrl->LF_MA_shp[ k ] = psEncCtrl->LF_MA_shp[ 0 ];
michael@0 326 psEncCtrl->LF_AR_shp[ k ] = psEncCtrl->LF_AR_shp[ 0 ];
michael@0 327 }
michael@0 328 Tilt = -HP_NOISE_COEF;
michael@0 329 }
michael@0 330
michael@0 331 /****************************/
michael@0 332 /* HARMONIC SHAPING CONTROL */
michael@0 333 /****************************/
michael@0 334 /* Control boosting of harmonic frequencies */
michael@0 335 HarmBoost = LOW_RATE_HARMONIC_BOOST * ( 1.0f - psEncCtrl->coding_quality ) * psEnc->LTPCorr;
michael@0 336
michael@0 337 /* More harmonic boost for noisy input signals */
michael@0 338 HarmBoost += LOW_INPUT_QUALITY_HARMONIC_BOOST * ( 1.0f - psEncCtrl->input_quality );
michael@0 339
michael@0 340 if( USE_HARM_SHAPING && psEnc->sCmn.indices.signalType == TYPE_VOICED ) {
michael@0 341 /* Harmonic noise shaping */
michael@0 342 HarmShapeGain = HARMONIC_SHAPING;
michael@0 343
michael@0 344 /* More harmonic noise shaping for high bitrates or noisy input */
michael@0 345 HarmShapeGain += HIGH_RATE_OR_LOW_QUALITY_HARMONIC_SHAPING *
michael@0 346 ( 1.0f - ( 1.0f - psEncCtrl->coding_quality ) * psEncCtrl->input_quality );
michael@0 347
michael@0 348 /* Less harmonic noise shaping for less periodic signals */
michael@0 349 HarmShapeGain *= ( silk_float )sqrt( psEnc->LTPCorr );
michael@0 350 } else {
michael@0 351 HarmShapeGain = 0.0f;
michael@0 352 }
michael@0 353
michael@0 354 /*************************/
michael@0 355 /* Smooth over subframes */
michael@0 356 /*************************/
michael@0 357 for( k = 0; k < psEnc->sCmn.nb_subfr; k++ ) {
michael@0 358 psShapeSt->HarmBoost_smth += SUBFR_SMTH_COEF * ( HarmBoost - psShapeSt->HarmBoost_smth );
michael@0 359 psEncCtrl->HarmBoost[ k ] = psShapeSt->HarmBoost_smth;
michael@0 360 psShapeSt->HarmShapeGain_smth += SUBFR_SMTH_COEF * ( HarmShapeGain - psShapeSt->HarmShapeGain_smth );
michael@0 361 psEncCtrl->HarmShapeGain[ k ] = psShapeSt->HarmShapeGain_smth;
michael@0 362 psShapeSt->Tilt_smth += SUBFR_SMTH_COEF * ( Tilt - psShapeSt->Tilt_smth );
michael@0 363 psEncCtrl->Tilt[ k ] = psShapeSt->Tilt_smth;
michael@0 364 }
michael@0 365 }

mercurial