Line data Source code
1 : /******************************************************************************************************
2 :
3 : (C) 2022-2025 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 80268345 : 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 80268345 : if ( frac_max == 6 )
72 : {
73 4451082 : win = E_ROM_inter6_1;
74 : }
75 : else
76 : {
77 75817263 : win = E_ROM_inter4_1;
78 : }
79 :
80 80268345 : x1 = &x[0];
81 80268345 : x2 = &x[1];
82 80268345 : c1 = &win[frac];
83 80268345 : c2 = &win[frac_max - frac];
84 80268345 : s = 0.0f;
85 401341725 : for ( i = 0; i < 4; i++, c1 += frac_max, c2 += frac_max )
86 : {
87 321073380 : s += ( *x1-- ) * ( *c1 ) + ( *x2++ ) * ( *c2 );
88 : }
89 :
90 80268345 : return s;
91 : }
92 :
93 :
94 : /*---------------------------------------------------------------------*
95 : * tcx_ltp_pitch_search()
96 : *
97 : *
98 : *---------------------------------------------------------------------*/
99 :
100 15649208 : 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 : #ifdef FIX_2272_OOB_INDEXING_IN_LTP_PIT_SEARCH
118 : int16_t cor_idx_ini, cor_idx;
119 : #endif
120 : float temp, cor_max, cor[256], *pt_cor;
121 :
122 15649208 : if ( pitres == 6 )
123 : {
124 1759090 : delta = 8;
125 : }
126 : else
127 : {
128 13890118 : delta = 16;
129 : }
130 :
131 15649208 : t0_min = (int16_t) pitch_ol - ( delta >> 1 );
132 15649208 : t0_max = (int16_t) pitch_ol + ( delta >> 1 ) - 1;
133 :
134 15649208 : if ( t0_min < pitmin )
135 : {
136 1391929 : t0_min = pitmin;
137 1391929 : t0_max = t0_min + delta - 1;
138 : }
139 15649208 : if ( t0_max > pitmax )
140 : {
141 362832 : t0_max = pitmax;
142 362832 : t0_min = t0_max - delta + 1;
143 : }
144 :
145 :
146 15649208 : t_min = t0_min - L_INTERPOL1;
147 15649208 : t_max = t0_max + L_INTERPOL1;
148 :
149 15649208 : pt_cor = cor;
150 377157480 : for ( t = t_min; t <= t_max; t++ )
151 : {
152 361508272 : *pt_cor++ = dotp( wsp, wsp - t, len );
153 : }
154 :
155 15649208 : pt_cor = cor + L_INTERPOL1;
156 15649208 : cor_max = *pt_cor++;
157 15649208 : t1 = t0_min;
158 236314608 : for ( t = t0_min + 1; t <= t0_max; t++ )
159 : {
160 220665400 : if ( *pt_cor > cor_max )
161 : {
162 70419993 : cor_max = *pt_cor;
163 70419993 : t1 = t;
164 : }
165 220665400 : pt_cor++;
166 : }
167 15649208 : temp = dotp( wsp, wsp, len ) * dotp( wsp - t1, wsp - t1, len );
168 15649208 : *norm_corr = cor_max / (float) sqrt( temp + 0.1f );
169 :
170 : /* check for border cases at the low lag border */
171 : /*pt_cor=cor;*/
172 15649208 : if ( check_border_case && t1 == t0_min )
173 : {
174 : float tmpCor;
175 5469866 : for ( t = t1 - L_INTERPOL1; t < t1; t++ )
176 : {
177 4697230 : tmpCor = dotp( wsp, wsp - t, len );
178 4697230 : if ( tmpCor > cor_max )
179 : {
180 : /* no real maximum but still on a rising slope */
181 : /* keep t1 but set norm_corr to zero to avoid activating the LTP here */
182 1022112 : *border_case = 1;
183 1022112 : break;
184 : }
185 : }
186 : }
187 :
188 15649208 : if ( t1 >= pitfr1 )
189 : {
190 2643360 : *pitch_int = t1;
191 2643360 : *pitch_fr = 0;
192 2643360 : *index = t1 - pitfr1 + ( ( pitfr2 - pitmin ) * pitres ) + ( ( pitfr1 - pitfr2 ) * ( pitres >> 1 ) );
193 2643360 : return;
194 : }
195 :
196 : /*------------------------------------------------------------------*
197 : * Search fractional pitch with 1/4 subsample resolution.
198 : * search the fractions around t0 and choose the one which maximizes
199 : * the interpolated normalized correlation.
200 : *-----------------------------------------------------------------*/
201 :
202 : #ifdef FIX_2272_OOB_INDEXING_IN_LTP_PIT_SEARCH
203 13005848 : cor_idx_ini = L_INTERPOL1 - t0_min;
204 : #else
205 : pt_cor = cor + L_INTERPOL1 - t0_min;
206 : #endif
207 13005848 : t0 = t1;
208 13005848 : if ( t0 >= pitfr2 )
209 : {
210 2453095 : step = 2;
211 2453095 : fraction = 2;
212 : }
213 : else
214 : {
215 10552753 : step = 1;
216 10552753 : fraction = 1;
217 : }
218 :
219 13005848 : if ( t0 == t0_min ) /* Limit case */
220 : {
221 1611520 : fraction = 0;
222 : #ifdef FIX_2272_OOB_INDEXING_IN_LTP_PIT_SEARCH
223 1611520 : cor_idx = cor_idx_ini + t0;
224 1611520 : cor_max = interpolate_corr( &cor[cor_idx], fraction, pitres );
225 : #else
226 : cor_max = interpolate_corr( &pt_cor[t0], fraction, pitres );
227 : #endif
228 : }
229 : else /* Process negative fractions */
230 : {
231 11394328 : t0--;
232 : #ifdef FIX_2272_OOB_INDEXING_IN_LTP_PIT_SEARCH
233 11394328 : cor_idx = cor_idx_ini + t0;
234 11394328 : cor_max = interpolate_corr( &cor[cor_idx], fraction, pitres );
235 : #else
236 : cor_max = interpolate_corr( &pt_cor[t0], fraction, pitres );
237 : #endif
238 30603872 : for ( i = ( fraction + step ); i <= pitres - 1; i = i + step )
239 : {
240 : #ifdef FIX_2272_OOB_INDEXING_IN_LTP_PIT_SEARCH
241 19209544 : temp = interpolate_corr( &cor[cor_idx], i, pitres );
242 : #else
243 : temp = interpolate_corr( &pt_cor[t0], i, pitres );
244 : #endif
245 19209544 : if ( temp > cor_max )
246 : {
247 18075482 : cor_max = temp;
248 18075482 : fraction = i;
249 : }
250 : }
251 : }
252 :
253 : #ifdef FIX_2272_OOB_INDEXING_IN_LTP_PIT_SEARCH
254 13005848 : cor_idx = cor_idx_ini + t1;
255 : #endif
256 61058801 : for ( i = 0; i <= pitres - 1; i = i + step ) /* Process positive fractions */
257 : {
258 : #ifdef FIX_2272_OOB_INDEXING_IN_LTP_PIT_SEARCH
259 48052953 : temp = interpolate_corr( &cor[cor_idx], i, pitres );
260 : #else
261 : temp = interpolate_corr( &pt_cor[t1], i, pitres );
262 : #endif
263 48052953 : if ( temp > cor_max )
264 : {
265 13593014 : cor_max = temp;
266 13593014 : fraction = i;
267 13593014 : t0 = t1;
268 : }
269 : }
270 13005848 : *pitch_int = t0;
271 13005848 : *pitch_fr = fraction;
272 13005848 : if ( t0 >= pitfr2 )
273 : {
274 2438813 : *index = t0 * ( pitres >> 1 ) + ( fraction >> 1 ) - ( pitfr2 * ( pitres >> 1 ) ) + ( ( pitfr2 - pitmin ) * pitres );
275 : }
276 : else
277 : {
278 10567035 : *index = t0 * pitres + fraction - ( pitmin * pitres );
279 : }
280 :
281 13005848 : return;
282 : }
283 :
284 :
285 : /*---------------------------------------------------------------------*
286 : * tcx_ltp_find_gain()
287 : *
288 : *
289 : *---------------------------------------------------------------------*/
290 :
291 11607868 : static void tcx_ltp_find_gain(
292 : const float *speech,
293 : float *pred_speech,
294 : const int16_t L_frame,
295 : float *gain,
296 : int16_t *gain_index )
297 : {
298 11607868 : int16_t gainbits = 2;
299 :
300 : /* Find gain */
301 11607868 : *gain = get_gain( speech, pred_speech, L_frame, NULL );
302 :
303 : /* Quantize gain */
304 11607868 : if ( *gain >= 0.875f )
305 : {
306 2113329 : *gain_index = 3; /* 1.00/2 */
307 : }
308 9494539 : else if ( *gain >= 0.625f )
309 : {
310 2390659 : *gain_index = 2; /* 0.75/2 */
311 : }
312 7103880 : else if ( *gain >= 0.375f )
313 : {
314 2966363 : *gain_index = 1; /* 0.50/2 */
315 : }
316 4137517 : else if ( *gain >= 0.125f )
317 : {
318 3354956 : *gain_index = 0; /* 0.25/2 */
319 : }
320 : else
321 : {
322 782561 : *gain_index = -1; /* escape */
323 : }
324 : /* Dequantize gain */
325 11607868 : *gain = (float) ( *gain_index + 1 ) * 0.625f / (float) ( 1 << gainbits );
326 :
327 11607868 : return;
328 : }
329 :
330 : /*---------------------------------------------------------------------*
331 : * tcx_ltp_encode()
332 : *
333 : *
334 : *---------------------------------------------------------------------*/
335 :
336 11607868 : void tcx_ltp_encode(
337 : Encoder_State *st,
338 : const int16_t tcxMode,
339 : const int16_t L_frame,
340 : const float *speech,
341 : float *speech_ltp,
342 : const float *wsp,
343 : const int16_t Top[],
344 : int16_t *ltp_param,
345 : int16_t *ltp_bits,
346 : float *A,
347 : const int16_t disable_ltp,
348 : const int16_t element_mode )
349 : {
350 : int16_t i, j, n;
351 : int16_t ltp_on, tcxOnly, L_subfr, SideInfoOnly, delta;
352 : float s;
353 : float norm_corr;
354 : float pred_speech[L_FRAME_PLUS];
355 : float tempFlatness;
356 : float maxEnergyChange;
357 : float buf_zir[M + L_FRAME_PLUS / 4], *zir;
358 : float r[M + 1], Aest[M + 1];
359 : float alpha, step;
360 : float si_gain;
361 : int16_t border_case;
362 :
363 11607868 : TCX_ENC_HANDLE hTcxEnc = st->hTcxEnc;
364 :
365 11607868 : tcxOnly = st->tcxonly;
366 11607868 : L_subfr = L_SUBFR;
367 11607868 : SideInfoOnly = st->sr_core > 25600;
368 :
369 : /* Reset memory if past frame is acelp */
370 11607868 : if ( st->last_core == ACELP_CORE )
371 : {
372 105999 : hTcxEnc->tcxltp_pitch_int_past = L_frame;
373 105999 : hTcxEnc->tcxltp_pitch_fr_past = 0;
374 105999 : hTcxEnc->tcxltp_gain_past = 0.f;
375 : }
376 :
377 : /* By default, LTP is off */
378 11607868 : ltp_param[0] = 0;
379 11607868 : norm_corr = 0.0f;
380 11607868 : border_case = 0;
381 :
382 11607868 : if ( hTcxEnc->tcxltp || SideInfoOnly )
383 : {
384 : /* Find pitch lag */
385 11607868 : if ( st->pit_res_max == 6 )
386 : {
387 1759090 : delta = 8;
388 : }
389 : else
390 : {
391 9848778 : delta = 16;
392 : }
393 :
394 11607868 : if ( st->element_mode == IVAS_CPE_MDCT )
395 : {
396 9215540 : if ( abs( Top[0] - Top[1] ) < ( delta / 2 ) )
397 : {
398 : /* estimates are close enough and stable, take the artihmetic mean as estimate */
399 5174200 : 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 );
400 : }
401 : else
402 : {
403 : /* pitch jumps between half frames, calc ltp for both estimates, choose the better one */
404 : int16_t pitch_int_2[2];
405 : int16_t pitch_fr_2[2];
406 : float norm_corr_2[2];
407 : int16_t pit_param_2[2];
408 :
409 12124020 : for ( i = 0; i < 2; i++ )
410 : {
411 8082680 : 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 );
412 : }
413 :
414 4041340 : i = ( norm_corr_2[1] > norm_corr_2[0] ) ? 1 : 0;
415 4041340 : hTcxEnc->tcxltp_pitch_int = pitch_int_2[i];
416 4041340 : hTcxEnc->tcxltp_pitch_fr = pitch_fr_2[i];
417 4041340 : ltp_param[1] = pit_param_2[i];
418 4041340 : norm_corr = norm_corr_2[i];
419 : }
420 : }
421 : else
422 : {
423 2392328 : 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 );
424 : }
425 :
426 11607868 : if ( border_case )
427 : {
428 954331 : norm_corr = 0.0f;
429 : }
430 11607868 : if ( st->element_mode == IVAS_CPE_DFT )
431 : {
432 319841 : 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 ) ) ) );
433 :
434 319841 : 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 ) ) );
435 : }
436 : else
437 : {
438 11288027 : tempFlatness = GetTCXAvgTemporalFlatnessMeasure( st->hTranDet, NSUBBLOCKS, 1 + min( NSUBBLOCKS, (int16_t) ceil( 0.5f + NSUBBLOCKS * ( 1.0f * ( hTcxEnc->tcxltp_pitch_int ) / L_frame ) ) ) );
439 :
440 11288027 : 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 ) ) );
441 : }
442 :
443 : /* Switch LTP on */
444 11607868 : if ( ( tcxOnly == 0 && tcxMode == TCX_20 && norm_corr * hTcxEnc->tcxltp_norm_corr_past > 0.25f && tempFlatness < 3.5f ) ||
445 10928683 : ( tcxOnly == 1 && tcxMode == TCX_10 && max( norm_corr, hTcxEnc->tcxltp_norm_corr_past ) > 0.5f && maxEnergyChange < 3.5f ) ||
446 : /* 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 */
447 10917894 : ( tcxOnly == 1 && norm_corr > 0.44f && L_frame * ( 1.2f - norm_corr ) < hTcxEnc->tcxltp_pitch_int ) ||
448 9093931 : ( tcxOnly == 1 && tcxMode == TCX_20 && norm_corr > 0.44f && ( tempFlatness < 6.0f || ( tempFlatness < 7.0f && maxEnergyChange < 22.0f ) ) ) )
449 : {
450 5172382 : if ( disable_ltp == 0 )
451 : {
452 5171518 : ltp_param[0] = 1;
453 : }
454 : }
455 :
456 : /* hysteresis for stable ltp prediction */
457 11607868 : ltp_on = 0;
458 11607868 : 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 ) ) ) )
459 : {
460 4062131 : ltp_on = 1;
461 : }
462 :
463 11607868 : if ( tcxOnly == 1 && ltp_param[0] == 1 )
464 : {
465 : /* increase ltp counter */
466 4493197 : hTcxEnc->tcxltp_on_mem = min( 5, hTcxEnc->tcxltp_on_mem + 1 );
467 : }
468 7114671 : else if ( ltp_on == 1 )
469 : {
470 : /* hysteresis takes effect, decrease counter */
471 472882 : hTcxEnc->tcxltp_on_mem = max( 0, hTcxEnc->tcxltp_on_mem - 1 );
472 472882 : ltp_param[0] = ltp_on;
473 : }
474 : else
475 : {
476 : /* no ltp in this frame, reset counter */
477 6641789 : hTcxEnc->tcxltp_on_mem = 0;
478 : }
479 : }
480 :
481 : /* Find predicted signal */
482 11607868 : predict_signal( speech, pred_speech, hTcxEnc->tcxltp_pitch_int, hTcxEnc->tcxltp_pitch_fr, st->pit_res_max, L_frame );
483 :
484 : /* Find gain */
485 11607868 : tcx_ltp_find_gain( speech, pred_speech, L_frame, &hTcxEnc->tcxltp_gain, <p_param[2] );
486 :
487 11607868 : if ( ltp_param[0] )
488 : {
489 : /* Total number of bits for LTP */
490 5644400 : if ( ltp_param[2] + 1 ) /* hTcxEnc->tcxltp_gain > 0 */
491 : {
492 5642261 : *ltp_bits = 12;
493 : }
494 : else /* hTcxEnc->tcxltp_gain <= 0 -> turn off LTP */
495 : {
496 2139 : ltp_param[0] = 0;
497 : }
498 : }
499 :
500 11607868 : if ( !ltp_param[0] )
501 : {
502 : /* No LTP -> set everything to zero */
503 5965607 : hTcxEnc->tcxltp_pitch_int = L_frame;
504 5965607 : hTcxEnc->tcxltp_pitch_fr = 0;
505 5965607 : ltp_param[1] = 0;
506 5965607 : set_zero( pred_speech, L_frame );
507 5965607 : hTcxEnc->tcxltp_gain = 0.f;
508 5965607 : ltp_param[2] = 0;
509 5965607 : if ( hTcxEnc->tcxltp || SideInfoOnly )
510 : {
511 5965607 : *ltp_bits = 1;
512 : }
513 : else
514 : {
515 0 : *ltp_bits = 0;
516 : }
517 : }
518 :
519 11607868 : si_gain = 0;
520 11607868 : if ( SideInfoOnly )
521 : {
522 4334469 : si_gain = hTcxEnc->tcxltp_gain;
523 4334469 : hTcxEnc->tcxltp_gain = 0.f;
524 : }
525 :
526 11607868 : if ( speech_ltp != NULL )
527 : {
528 2072487 : if ( hTcxEnc->tcxltp_gain_past == 0.f && hTcxEnc->tcxltp_gain == 0.f )
529 : {
530 1423258 : mvr2r( speech, speech_ltp, L_subfr );
531 : }
532 649229 : else if ( hTcxEnc->tcxltp_gain_past == 0.f )
533 : {
534 95361 : alpha = 0.f;
535 95361 : step = 1.f / (float) ( L_subfr );
536 6198465 : for ( n = 0; n < L_subfr; n++ )
537 : {
538 6103104 : speech_ltp[n] = speech[n] - alpha * hTcxEnc->tcxltp_gain * pred_speech[n];
539 6103104 : alpha += step;
540 : }
541 : }
542 : else
543 : {
544 553868 : if ( A == NULL )
545 : {
546 9799290 : for ( i = 0; i <= M; i++ )
547 : {
548 9254885 : s = 0.0;
549 2756738173 : for ( j = 0; j < L_frame - i; j++ )
550 : {
551 2747483288 : s += speech[j - L_frame] * speech[j + i - L_frame];
552 : }
553 9254885 : r[i] = s;
554 : }
555 544405 : if ( r[0] < 100.0f )
556 : {
557 3432 : r[0] = 100.0f;
558 : }
559 544405 : r[0] *= 1.0001f;
560 544405 : lev_dur( Aest, r, M, NULL );
561 544405 : A = Aest;
562 : }
563 :
564 553868 : if ( hTcxEnc->tcxltp_gain > 0.f )
565 : {
566 487629 : predict_signal( speech - M, buf_zir, hTcxEnc->tcxltp_pitch_int, hTcxEnc->tcxltp_pitch_fr, st->pit_res_max, M );
567 : }
568 : else
569 : {
570 66239 : set_f( buf_zir, 0.0f, M );
571 : }
572 :
573 9415756 : for ( n = 0; n < M; n++ )
574 : {
575 8861888 : buf_zir[n] = speech_ltp[n - M] - speech[n - M] + hTcxEnc->tcxltp_gain * buf_zir[n];
576 : }
577 :
578 553868 : zir = buf_zir + M;
579 553868 : set_f( zir, 0.0f, L_subfr );
580 553868 : syn_filt( A, M, zir, zir, L_subfr, buf_zir, 0 );
581 553868 : alpha = 1.f;
582 553868 : step = 1.f / (float) ( L_subfr / 2 );
583 :
584 18277644 : for ( n = L_subfr / 2; n < L_subfr; n++ )
585 : {
586 17723776 : zir[n] *= alpha;
587 17723776 : alpha -= step;
588 : }
589 :
590 36001420 : for ( n = 0; n < L_subfr; n++ )
591 : {
592 35447552 : speech_ltp[n] = ( speech[n] - hTcxEnc->tcxltp_gain * pred_speech[n] ) + zir[n];
593 : }
594 : }
595 :
596 2072487 : if ( SideInfoOnly || hTcxEnc->tcxltp_gain == 0.0f )
597 : {
598 583546585 : for ( n = L_subfr; n < L_frame; n++ )
599 : {
600 582057088 : speech_ltp[n] = speech[n];
601 : }
602 : }
603 : else
604 : {
605 140860302 : for ( n = L_subfr; n < L_frame; n++ )
606 : {
607 140277312 : speech_ltp[n] = speech[n] - hTcxEnc->tcxltp_gain * pred_speech[n];
608 : }
609 : }
610 : }
611 :
612 : /* Update */
613 11607868 : hTcxEnc->tcxltp_pitch_int_past = hTcxEnc->tcxltp_pitch_int;
614 11607868 : hTcxEnc->tcxltp_pitch_fr_past = hTcxEnc->tcxltp_pitch_fr;
615 11607868 : hTcxEnc->tcxltp_gain_past = hTcxEnc->tcxltp_gain;
616 :
617 11607868 : if ( SideInfoOnly )
618 : {
619 4334469 : hTcxEnc->tcxltp_gain = si_gain;
620 : }
621 :
622 11607868 : hTcxEnc->tcxltp_norm_corr_past = norm_corr;
623 :
624 11607868 : return;
625 : }
|