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