Line data Source code
1 : /******************************************************************************************************
2 :
3 : (C) 2022-2026 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB,
4 : Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
5 : Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
6 : Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
7 : contributors to this repository. All Rights Reserved.
8 :
9 : This software is protected by copyright law and by international treaties.
10 : The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB,
11 : Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
12 : Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
13 : Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
14 : contributors to this repository retain full ownership rights in their respective contributions in
15 : the software. This notice grants no license of any kind, including but not limited to patent
16 : license, nor is any license granted by implication, estoppel or otherwise.
17 :
18 : Contributors are required to enter into the IVAS codec Public Collaboration agreement before making
19 : contributions.
20 :
21 : This software is provided "AS IS", without any express or implied warranties. The software is in the
22 : development stage. It is intended exclusively for experts who have experience with such software and
23 : solely for the purpose of inspection. All implied warranties of non-infringement, merchantability
24 : and fitness for a particular purpose are hereby disclaimed and excluded.
25 :
26 : Any dispute, controversy or claim arising under or in relation to providing this software shall be
27 : submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in
28 : accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and
29 : the United Nations Convention on Contracts on the International Sales of Goods.
30 :
31 : *******************************************************************************************************/
32 :
33 : /*====================================================================================
34 : EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0
35 : ====================================================================================*/
36 :
37 : #include "cnst.h"
38 : #include <stdint.h>
39 : #include "options.h"
40 : #ifdef DEBUGGING
41 : #include "debug.h"
42 : #endif
43 : #include <math.h>
44 : #include "prot.h"
45 : #include "rom_enc.h"
46 : #include "rom_com.h"
47 : #include "wmc_auto.h"
48 : #ifdef DEBUG_PLOT
49 : #include "deb_out.h"
50 : #endif
51 :
52 :
53 : /*---------------------------------------------------------------------*
54 : * interpolate_corr()
55 : *
56 : *
57 : *---------------------------------------------------------------------*/
58 :
59 : /*! r: interpolated value */
60 16596328 : static float interpolate_corr(
61 : const float *x, /* i : input vector */
62 : const int16_t frac, /* i : fraction of lag */
63 : const int16_t frac_max /* i : max fraction */
64 : )
65 : {
66 : int16_t i;
67 : float s;
68 : const float *c1, *c2, *x1, *x2, *win;
69 :
70 :
71 16596328 : if ( frac_max == 6 )
72 : {
73 838328 : win = E_ROM_inter6_1;
74 : }
75 : else
76 : {
77 15758000 : win = E_ROM_inter4_1;
78 : }
79 :
80 16596328 : x1 = &x[0];
81 16596328 : x2 = &x[1];
82 16596328 : c1 = &win[frac];
83 16596328 : c2 = &win[frac_max - frac];
84 16596328 : s = 0.0f;
85 82981640 : for ( i = 0; i < 4; i++, c1 += frac_max, c2 += frac_max )
86 : {
87 66385312 : s += ( *x1-- ) * ( *c1 ) + ( *x2++ ) * ( *c2 );
88 : }
89 :
90 16596328 : return s;
91 : }
92 :
93 :
94 : /*---------------------------------------------------------------------*
95 : * tcx_ltp_pitch_search()
96 : *
97 : *
98 : *---------------------------------------------------------------------*/
99 :
100 3189721 : static void tcx_ltp_pitch_search(
101 : const int16_t pitch_ol,
102 : int16_t *pitch_int,
103 : int16_t *pitch_fr,
104 : int16_t *index,
105 : float *norm_corr,
106 : const int16_t len,
107 : const float *wsp,
108 : const int16_t pitmin,
109 : const int16_t pitfr1,
110 : const int16_t pitfr2,
111 : const int16_t pitmax,
112 : const int16_t pitres,
113 : const int16_t check_border_case,
114 : int16_t *border_case )
115 : {
116 : int16_t i, t, t0, t1, step, fraction, t0_min, t0_max, t_min, t_max, delta;
117 : int16_t cor_idx_ini, cor_idx;
118 : float temp, cor_max, cor[256], *pt_cor;
119 :
120 3189721 : if ( pitres == 6 )
121 : {
122 371084 : delta = 8;
123 : }
124 : else
125 : {
126 2818637 : delta = 16;
127 : }
128 :
129 3189721 : t0_min = (int16_t) pitch_ol - ( delta >> 1 );
130 3189721 : t0_max = (int16_t) pitch_ol + ( delta >> 1 ) - 1;
131 :
132 3189721 : if ( t0_min < pitmin )
133 : {
134 265248 : t0_min = pitmin;
135 265248 : t0_max = t0_min + delta - 1;
136 : }
137 3189721 : if ( t0_max > pitmax )
138 : {
139 67159 : t0_max = pitmax;
140 67159 : t0_min = t0_max - delta + 1;
141 : }
142 :
143 :
144 3189721 : t_min = t0_min - L_INTERPOL1;
145 3189721 : t_max = t0_max + L_INTERPOL1;
146 :
147 3189721 : pt_cor = cor;
148 76774353 : for ( t = t_min; t <= t_max; t++ )
149 : {
150 73584632 : *pt_cor++ = dotp( wsp, wsp - t, len );
151 : }
152 :
153 3189721 : pt_cor = cor + L_INTERPOL1;
154 3189721 : cor_max = *pt_cor++;
155 3189721 : t1 = t0_min;
156 48066864 : for ( t = t0_min + 1; t <= t0_max; t++ )
157 : {
158 44877143 : if ( *pt_cor > cor_max )
159 : {
160 17778248 : cor_max = *pt_cor;
161 17778248 : t1 = t;
162 : }
163 44877143 : pt_cor++;
164 : }
165 3189721 : temp = dotp( wsp, wsp, len ) * dotp( wsp - t1, wsp - t1, len );
166 3189721 : *norm_corr = cor_max / (float) sqrt( temp + 0.1f );
167 :
168 : /* check for border cases at the low lag border */
169 : /*pt_cor=cor;*/
170 3189721 : if ( check_border_case && t1 == t0_min )
171 : {
172 : float tmpCor;
173 916301 : for ( t = t1 - L_INTERPOL1; t < t1; t++ )
174 : {
175 818611 : tmpCor = dotp( wsp, wsp - t, len );
176 818611 : if ( tmpCor > cor_max )
177 : {
178 : /* no real maximum but still on a rising slope */
179 : /* keep t1 but set norm_corr to zero to avoid activating the LTP here */
180 324562 : *border_case = 1;
181 324562 : break;
182 : }
183 : }
184 : }
185 :
186 3189721 : if ( t1 >= pitfr1 )
187 : {
188 556204 : *pitch_int = t1;
189 556204 : *pitch_fr = 0;
190 556204 : *index = t1 - pitfr1 + ( ( pitfr2 - pitmin ) * pitres ) + ( ( pitfr1 - pitfr2 ) * ( pitres >> 1 ) );
191 556204 : return;
192 : }
193 :
194 : /*------------------------------------------------------------------*
195 : * Search fractional pitch with 1/4 subsample resolution.
196 : * search the fractions around t0 and choose the one which maximizes
197 : * the interpolated normalized correlation.
198 : *-----------------------------------------------------------------*/
199 :
200 2633517 : cor_idx_ini = L_INTERPOL1 - t0_min;
201 2633517 : t0 = t1;
202 2633517 : if ( t0 >= pitfr2 )
203 : {
204 394511 : step = 2;
205 394511 : fraction = 2;
206 : }
207 : else
208 : {
209 2239006 : step = 1;
210 2239006 : fraction = 1;
211 : }
212 :
213 2633517 : if ( t0 == t0_min ) /* Limit case */
214 : {
215 354519 : fraction = 0;
216 354519 : cor_idx = cor_idx_ini + t0;
217 354519 : cor_max = interpolate_corr( &cor[cor_idx], fraction, pitres );
218 : }
219 : else /* Process negative fractions */
220 : {
221 2278998 : t0--;
222 2278998 : cor_idx = cor_idx_ini + t0;
223 2278998 : cor_max = interpolate_corr( &cor[cor_idx], fraction, pitres );
224 6319216 : for ( i = ( fraction + step ); i <= pitres - 1; i = i + step )
225 : {
226 4040218 : temp = interpolate_corr( &cor[cor_idx], i, pitres );
227 4040218 : if ( temp > cor_max )
228 : {
229 3767587 : cor_max = temp;
230 3767587 : fraction = i;
231 : }
232 : }
233 : }
234 :
235 2633517 : cor_idx = cor_idx_ini + t1;
236 12556110 : for ( i = 0; i <= pitres - 1; i = i + step ) /* Process positive fractions */
237 : {
238 9922593 : temp = interpolate_corr( &cor[cor_idx], i, pitres );
239 9922593 : if ( temp > cor_max )
240 : {
241 2974276 : cor_max = temp;
242 2974276 : fraction = i;
243 2974276 : t0 = t1;
244 : }
245 : }
246 2633517 : *pitch_int = t0;
247 2633517 : *pitch_fr = fraction;
248 2633517 : if ( t0 >= pitfr2 )
249 : {
250 392930 : *index = t0 * ( pitres >> 1 ) + ( fraction >> 1 ) - ( pitfr2 * ( pitres >> 1 ) ) + ( ( pitfr2 - pitmin ) * pitres );
251 : }
252 : else
253 : {
254 2240587 : *index = t0 * pitres + fraction - ( pitmin * pitres );
255 : }
256 :
257 2633517 : return;
258 : }
259 :
260 :
261 : /*---------------------------------------------------------------------*
262 : * tcx_ltp_find_gain()
263 : *
264 : *
265 : *---------------------------------------------------------------------*/
266 :
267 2564694 : static void tcx_ltp_find_gain(
268 : const float *speech,
269 : float *pred_speech,
270 : const int16_t L_frame,
271 : float *gain,
272 : int16_t *gain_index )
273 : {
274 2564694 : int16_t gainbits = 2;
275 :
276 : /* Find gain */
277 2564694 : *gain = get_gain( speech, pred_speech, L_frame, NULL );
278 :
279 : /* Quantize gain */
280 2564694 : if ( *gain >= 0.875f )
281 : {
282 519463 : *gain_index = 3; /* 1.00/2 */
283 : }
284 2045231 : else if ( *gain >= 0.625f )
285 : {
286 853113 : *gain_index = 2; /* 0.75/2 */
287 : }
288 1192118 : else if ( *gain >= 0.375f )
289 : {
290 700509 : *gain_index = 1; /* 0.50/2 */
291 : }
292 491609 : else if ( *gain >= 0.125f )
293 : {
294 340527 : *gain_index = 0; /* 0.25/2 */
295 : }
296 : else
297 : {
298 151082 : *gain_index = -1; /* escape */
299 : }
300 : /* Dequantize gain */
301 2564694 : *gain = (float) ( *gain_index + 1 ) * 0.625f / (float) ( 1 << gainbits );
302 :
303 2564694 : return;
304 : }
305 :
306 : /*---------------------------------------------------------------------*
307 : * tcx_ltp_encode()
308 : *
309 : *
310 : *---------------------------------------------------------------------*/
311 :
312 2564694 : void tcx_ltp_encode(
313 : Encoder_State *st,
314 : const int16_t tcxMode,
315 : const int16_t L_frame,
316 : const float *speech,
317 : float *speech_ltp,
318 : const float *wsp,
319 : const int16_t Top[],
320 : int16_t *ltp_param,
321 : int16_t *ltp_bits,
322 : float *A,
323 : const int16_t disable_ltp,
324 : const int16_t element_mode )
325 : {
326 : int16_t i, j, n;
327 : int16_t ltp_on, tcxOnly, L_subfr, SideInfoOnly, delta;
328 : float s;
329 : float norm_corr;
330 : float pred_speech[L_FRAME_PLUS];
331 : float tempFlatness;
332 : float maxEnergyChange;
333 : float buf_zir[M + L_FRAME_PLUS / 4], *zir;
334 : float r[M + 1], Aest[M + 1];
335 : float alpha, step;
336 : float si_gain;
337 : int16_t border_case;
338 :
339 2564694 : TCX_ENC_HANDLE hTcxEnc = st->hTcxEnc;
340 :
341 2564694 : tcxOnly = st->tcxonly;
342 2564694 : L_subfr = L_SUBFR;
343 2564694 : SideInfoOnly = st->sr_core > 25600;
344 :
345 : /* Reset memory if past frame is acelp */
346 2564694 : if ( st->last_core == ACELP_CORE )
347 : {
348 28436 : hTcxEnc->tcxltp_pitch_int_past = L_frame;
349 28436 : hTcxEnc->tcxltp_pitch_fr_past = 0;
350 28436 : hTcxEnc->tcxltp_gain_past = 0.f;
351 : }
352 :
353 : /* By default, LTP is off */
354 2564694 : ltp_param[0] = 0;
355 2564694 : norm_corr = 0.0f;
356 2564694 : border_case = 0;
357 :
358 2564694 : if ( hTcxEnc->tcxltp || SideInfoOnly )
359 : {
360 : /* Find pitch lag */
361 2564694 : if ( st->pit_res_max == 6 )
362 : {
363 371084 : delta = 8;
364 : }
365 : else
366 : {
367 2193610 : delta = 16;
368 : }
369 :
370 2564694 : if ( st->element_mode == IVAS_CPE_MDCT )
371 : {
372 2031269 : if ( abs( Top[0] - Top[1] ) < ( delta / 2 ) )
373 : {
374 : /* estimates are close enough and stable, take the artihmetic mean as estimate */
375 1406242 : tcx_ltp_pitch_search( ( Top[0] + Top[1] ) / 2, &hTcxEnc->tcxltp_pitch_int, &hTcxEnc->tcxltp_pitch_fr, <p_param[1], &norm_corr, L_frame, wsp, st->pit_min, st->pit_fr1, st->pit_fr2, st->pit_max, st->pit_res_max, 1, &border_case );
376 : }
377 : else
378 : {
379 : /* pitch jumps between half frames, calc ltp for both estimates, choose the better one */
380 : int16_t pitch_int_2[2];
381 : int16_t pitch_fr_2[2];
382 : float norm_corr_2[2];
383 : int16_t pit_param_2[2];
384 :
385 1875081 : for ( i = 0; i < 2; i++ )
386 : {
387 1250054 : tcx_ltp_pitch_search( Top[i], &pitch_int_2[i], &pitch_fr_2[i], &pit_param_2[i], &norm_corr_2[i], L_frame, wsp, st->pit_min, st->pit_fr1, st->pit_fr2, st->pit_max, st->pit_res_max, 1, &border_case );
388 : }
389 :
390 625027 : i = ( norm_corr_2[1] > norm_corr_2[0] ) ? 1 : 0;
391 625027 : hTcxEnc->tcxltp_pitch_int = pitch_int_2[i];
392 625027 : hTcxEnc->tcxltp_pitch_fr = pitch_fr_2[i];
393 625027 : ltp_param[1] = pit_param_2[i];
394 625027 : norm_corr = norm_corr_2[i];
395 : }
396 : }
397 : else
398 : {
399 533425 : tcx_ltp_pitch_search( Top[1], &hTcxEnc->tcxltp_pitch_int, &hTcxEnc->tcxltp_pitch_fr, <p_param[1], &norm_corr, L_frame, wsp, st->pit_min, st->pit_fr1, st->pit_fr2, st->pit_max, st->pit_res_max, ( element_mode > EVS_MONO ) ? 1 : 0, &border_case );
400 : }
401 :
402 2564694 : if ( border_case )
403 : {
404 290930 : norm_corr = 0.0f;
405 : }
406 2564694 : if ( st->element_mode == IVAS_CPE_DFT )
407 : {
408 43663 : tempFlatness = GetTCXAvgTemporalFlatnessMeasure( st->hTranDet, NSUBBLOCKS - NSUBBLOCKS_SHIFT, ( NSUBBLOCKS_SHIFT + 1 ) + min( NSUBBLOCKS, (int16_t) ceil( 0.5f + NSUBBLOCKS * ( 1.0f * ( hTcxEnc->tcxltp_pitch_int ) / L_frame ) ) ) );
409 :
410 43663 : maxEnergyChange = GetTCXMaxenergyChange( st->hTranDet, tcxMode == TCX_10, NSUBBLOCKS - NSUBBLOCKS_SHIFT, ( NSUBBLOCKS_SHIFT + 1 ) + min( NSUBBLOCKS, (int16_t) ceil( 0.5f + NSUBBLOCKS * (float) ( hTcxEnc->tcxltp_pitch_int ) / (float) L_frame ) ) );
411 : }
412 : else
413 : {
414 2521031 : tempFlatness = GetTCXAvgTemporalFlatnessMeasure( st->hTranDet, NSUBBLOCKS, 1 + min( NSUBBLOCKS, (int16_t) ceil( 0.5f + NSUBBLOCKS * ( 1.0f * ( hTcxEnc->tcxltp_pitch_int ) / L_frame ) ) ) );
415 :
416 2521031 : maxEnergyChange = GetTCXMaxenergyChange( st->hTranDet, tcxMode == TCX_10, NSUBBLOCKS, 1 + min( NSUBBLOCKS, (int16_t) ceil( 0.5f + NSUBBLOCKS * (float) ( hTcxEnc->tcxltp_pitch_int ) / (float) L_frame ) ) );
417 : }
418 :
419 : /* Switch LTP on */
420 2564694 : if ( ( tcxOnly == 0 && tcxMode == TCX_20 && norm_corr * hTcxEnc->tcxltp_norm_corr_past > 0.25f && tempFlatness < 3.5f ) ||
421 2434213 : ( tcxOnly == 1 && tcxMode == TCX_10 && max( norm_corr, hTcxEnc->tcxltp_norm_corr_past ) > 0.5f && maxEnergyChange < 3.5f ) ||
422 : /* Use LTP for lower correlation when pitch lag is big, L_frame*(1.2f-norm_corr) < hTcxEnc->tcxltp_pitch_int <=> norm_corr > 1.2f-hTcxEnc->/L_frame */
423 2424673 : ( tcxOnly == 1 && norm_corr > 0.44f && L_frame * ( 1.2f - norm_corr ) < hTcxEnc->tcxltp_pitch_int ) ||
424 2012957 : ( tcxOnly == 1 && tcxMode == TCX_20 && norm_corr > 0.44f && ( tempFlatness < 6.0f || ( tempFlatness < 7.0f && maxEnergyChange < 22.0f ) ) ) )
425 : {
426 1505405 : if ( disable_ltp == 0 )
427 : {
428 1505279 : ltp_param[0] = 1;
429 : }
430 : }
431 :
432 : /* hysteresis for stable ltp prediction */
433 2564694 : ltp_on = 0;
434 2564694 : if ( tcxOnly == 1 && st->element_mode == IVAS_CPE_MDCT && ( ( sqrt( (float) ( hTcxEnc->tcxltp_on_mem ) ) * (norm_corr) *0.9f ) > 0.44f && ( tempFlatness < 6.0f || ( tempFlatness < 7.0f && maxEnergyChange < 22.0f ) ) ) )
435 : {
436 1233058 : ltp_on = 1;
437 : }
438 :
439 2564694 : if ( tcxOnly == 1 && ltp_param[0] == 1 )
440 : {
441 : /* increase ltp counter */
442 1374924 : hTcxEnc->tcxltp_on_mem = min( 5, hTcxEnc->tcxltp_on_mem + 1 );
443 : }
444 1189770 : else if ( ltp_on == 1 )
445 : {
446 : /* hysteresis takes effect, decrease counter */
447 139006 : hTcxEnc->tcxltp_on_mem = max( 0, hTcxEnc->tcxltp_on_mem - 1 );
448 139006 : ltp_param[0] = ltp_on;
449 : }
450 : else
451 : {
452 : /* no ltp in this frame, reset counter */
453 1050764 : hTcxEnc->tcxltp_on_mem = 0;
454 : }
455 : }
456 :
457 : /* Find predicted signal */
458 2564694 : predict_signal( speech, pred_speech, hTcxEnc->tcxltp_pitch_int, hTcxEnc->tcxltp_pitch_fr, st->pit_res_max, L_frame );
459 :
460 : /* Find gain */
461 2564694 : tcx_ltp_find_gain( speech, pred_speech, L_frame, &hTcxEnc->tcxltp_gain, <p_param[2] );
462 :
463 2564694 : if ( ltp_param[0] )
464 : {
465 : /* Total number of bits for LTP */
466 1644285 : if ( ltp_param[2] + 1 ) /* hTcxEnc->tcxltp_gain > 0 */
467 : {
468 1644030 : *ltp_bits = 12;
469 : }
470 : else /* hTcxEnc->tcxltp_gain <= 0 -> turn off LTP */
471 : {
472 255 : ltp_param[0] = 0;
473 : }
474 : }
475 :
476 2564694 : if ( !ltp_param[0] )
477 : {
478 : /* No LTP -> set everything to zero */
479 920664 : hTcxEnc->tcxltp_pitch_int = L_frame;
480 920664 : hTcxEnc->tcxltp_pitch_fr = 0;
481 920664 : ltp_param[1] = 0;
482 920664 : set_zero( pred_speech, L_frame );
483 920664 : hTcxEnc->tcxltp_gain = 0.f;
484 920664 : ltp_param[2] = 0;
485 920664 : if ( hTcxEnc->tcxltp || SideInfoOnly )
486 : {
487 920664 : *ltp_bits = 1;
488 : }
489 : else
490 : {
491 0 : *ltp_bits = 0;
492 : }
493 : }
494 :
495 2564694 : si_gain = 0;
496 2564694 : if ( SideInfoOnly )
497 : {
498 1252128 : si_gain = hTcxEnc->tcxltp_gain;
499 1252128 : hTcxEnc->tcxltp_gain = 0.f;
500 : }
501 :
502 2564694 : if ( speech_ltp != NULL )
503 : {
504 489762 : if ( hTcxEnc->tcxltp_gain_past == 0.f && hTcxEnc->tcxltp_gain == 0.f )
505 : {
506 311681 : mvr2r( speech, speech_ltp, L_subfr );
507 : }
508 178081 : else if ( hTcxEnc->tcxltp_gain_past == 0.f )
509 : {
510 33291 : alpha = 0.f;
511 33291 : step = 1.f / (float) ( L_subfr );
512 2163915 : for ( n = 0; n < L_subfr; n++ )
513 : {
514 2130624 : speech_ltp[n] = speech[n] - alpha * hTcxEnc->tcxltp_gain * pred_speech[n];
515 2130624 : alpha += step;
516 : }
517 : }
518 : else
519 : {
520 144790 : if ( A == NULL )
521 : {
522 2575152 : for ( i = 0; i <= M; i++ )
523 : {
524 2432088 : s = 0.0;
525 790014616 : for ( j = 0; j < L_frame - i; j++ )
526 : {
527 787582528 : s += speech[j - L_frame] * speech[j + i - L_frame];
528 : }
529 2432088 : r[i] = s;
530 : }
531 143064 : if ( r[0] < 100.0f )
532 : {
533 2316 : r[0] = 100.0f;
534 : }
535 143064 : r[0] *= 1.0001f;
536 143064 : lev_dur( Aest, r, M, NULL );
537 143064 : A = Aest;
538 : }
539 :
540 144790 : if ( hTcxEnc->tcxltp_gain > 0.f )
541 : {
542 121346 : predict_signal( speech - M, buf_zir, hTcxEnc->tcxltp_pitch_int, hTcxEnc->tcxltp_pitch_fr, st->pit_res_max, M );
543 : }
544 : else
545 : {
546 23444 : set_f( buf_zir, 0.0f, M );
547 : }
548 :
549 2461430 : for ( n = 0; n < M; n++ )
550 : {
551 2316640 : buf_zir[n] = speech_ltp[n - M] - speech[n - M] + hTcxEnc->tcxltp_gain * buf_zir[n];
552 : }
553 :
554 144790 : zir = buf_zir + M;
555 144790 : set_f( zir, 0.0f, L_subfr );
556 144790 : syn_filt( A, M, zir, zir, L_subfr, buf_zir, 0 );
557 144790 : alpha = 1.f;
558 144790 : step = 1.f / (float) ( L_subfr / 2 );
559 :
560 4778070 : for ( n = L_subfr / 2; n < L_subfr; n++ )
561 : {
562 4633280 : zir[n] *= alpha;
563 4633280 : alpha -= step;
564 : }
565 :
566 9411350 : for ( n = 0; n < L_subfr; n++ )
567 : {
568 9266560 : speech_ltp[n] = ( speech[n] - hTcxEnc->tcxltp_gain * pred_speech[n] ) + zir[n];
569 : }
570 : }
571 :
572 489762 : if ( SideInfoOnly || hTcxEnc->tcxltp_gain == 0.0f )
573 : {
574 139140821 : for ( n = L_subfr; n < L_frame; n++ )
575 : {
576 138805696 : speech_ltp[n] = speech[n];
577 : }
578 : }
579 : else
580 : {
581 41184077 : for ( n = L_subfr; n < L_frame; n++ )
582 : {
583 41029440 : speech_ltp[n] = speech[n] - hTcxEnc->tcxltp_gain * pred_speech[n];
584 : }
585 : }
586 : }
587 :
588 : /* Update */
589 2564694 : hTcxEnc->tcxltp_pitch_int_past = hTcxEnc->tcxltp_pitch_int;
590 2564694 : hTcxEnc->tcxltp_pitch_fr_past = hTcxEnc->tcxltp_pitch_fr;
591 2564694 : hTcxEnc->tcxltp_gain_past = hTcxEnc->tcxltp_gain;
592 :
593 2564694 : if ( SideInfoOnly )
594 : {
595 1252128 : hTcxEnc->tcxltp_gain = si_gain;
596 : }
597 :
598 2564694 : hTcxEnc->tcxltp_norm_corr_past = norm_corr;
599 :
600 2564694 : return;
601 : }
|