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 100857870 : 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 100857870 : if ( frac_max == 6 )
72 : {
73 5551161 : win = E_ROM_inter6_1;
74 : }
75 : else
76 : {
77 95306709 : win = E_ROM_inter4_1;
78 : }
79 :
80 100857870 : x1 = &x[0];
81 100857870 : x2 = &x[1];
82 100857870 : c1 = &win[frac];
83 100857870 : c2 = &win[frac_max - frac];
84 100857870 : s = 0.0f;
85 504289350 : for ( i = 0; i < 4; i++, c1 += frac_max, c2 += frac_max )
86 : {
87 403431480 : s += ( *x1-- ) * ( *c1 ) + ( *x2++ ) * ( *c2 );
88 : }
89 :
90 100857870 : return s;
91 : }
92 :
93 :
94 : /*---------------------------------------------------------------------*
95 : * tcx_ltp_pitch_search()
96 : *
97 : *
98 : *---------------------------------------------------------------------*/
99 :
100 19649769 : 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 19649769 : if ( pitres == 6 )
123 : {
124 2258732 : delta = 8;
125 : }
126 : else
127 : {
128 17391037 : delta = 16;
129 : }
130 :
131 19649769 : t0_min = (int16_t) pitch_ol - ( delta >> 1 );
132 19649769 : t0_max = (int16_t) pitch_ol + ( delta >> 1 ) - 1;
133 :
134 19649769 : if ( t0_min < pitmin )
135 : {
136 1725710 : t0_min = pitmin;
137 1725710 : t0_max = t0_min + delta - 1;
138 : }
139 19649769 : if ( t0_max > pitmax )
140 : {
141 447576 : t0_max = pitmax;
142 447576 : t0_min = t0_max - delta + 1;
143 : }
144 :
145 :
146 19649769 : t_min = t0_min - L_INTERPOL1;
147 19649769 : t_max = t0_max + L_INTERPOL1;
148 :
149 19649769 : pt_cor = cor;
150 473174369 : for ( t = t_min; t <= t_max; t++ )
151 : {
152 453524600 : *pt_cor++ = dotp( wsp, wsp - t, len );
153 : }
154 :
155 19649769 : pt_cor = cor + L_INTERPOL1;
156 19649769 : cor_max = *pt_cor++;
157 19649769 : t1 = t0_min;
158 296326448 : for ( t = t0_min + 1; t <= t0_max; t++ )
159 : {
160 276676679 : if ( *pt_cor > cor_max )
161 : {
162 92402143 : cor_max = *pt_cor;
163 92402143 : t1 = t;
164 : }
165 276676679 : pt_cor++;
166 : }
167 19649769 : temp = dotp( wsp, wsp, len ) * dotp( wsp - t1, wsp - t1, len );
168 19649769 : *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 19649769 : if ( check_border_case && t1 == t0_min )
173 : {
174 : float tmpCor;
175 6644437 : for ( t = t1 - L_INTERPOL1; t < t1; t++ )
176 : {
177 5741586 : tmpCor = dotp( wsp, wsp - t, len );
178 5741586 : 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 1415011 : *border_case = 1;
183 1415011 : break;
184 : }
185 : }
186 : }
187 :
188 19649769 : if ( t1 >= pitfr1 )
189 : {
190 3369671 : *pitch_int = t1;
191 3369671 : *pitch_fr = 0;
192 3369671 : *index = t1 - pitfr1 + ( ( pitfr2 - pitmin ) * pitres ) + ( ( pitfr1 - pitfr2 ) * ( pitres >> 1 ) );
193 3369671 : 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 16280098 : cor_idx_ini = L_INTERPOL1 - t0_min;
204 : #else
205 : pt_cor = cor + L_INTERPOL1 - t0_min;
206 : #endif
207 16280098 : t0 = t1;
208 16280098 : if ( t0 >= pitfr2 )
209 : {
210 2962800 : step = 2;
211 2962800 : fraction = 2;
212 : }
213 : else
214 : {
215 13317298 : step = 1;
216 13317298 : fraction = 1;
217 : }
218 :
219 16280098 : if ( t0 == t0_min ) /* Limit case */
220 : {
221 2049619 : fraction = 0;
222 : #ifdef FIX_2272_OOB_INDEXING_IN_LTP_PIT_SEARCH
223 2049619 : cor_idx = cor_idx_ini + t0;
224 2049619 : 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 14230479 : t0--;
232 : #ifdef FIX_2272_OOB_INDEXING_IN_LTP_PIT_SEARCH
233 14230479 : cor_idx = cor_idx_ini + t0;
234 14230479 : cor_max = interpolate_corr( &cor[cor_idx], fraction, pitres );
235 : #else
236 : cor_max = interpolate_corr( &pt_cor[t0], fraction, pitres );
237 : #endif
238 38444584 : for ( i = ( fraction + step ); i <= pitres - 1; i = i + step )
239 : {
240 : #ifdef FIX_2272_OOB_INDEXING_IN_LTP_PIT_SEARCH
241 24214105 : temp = interpolate_corr( &cor[cor_idx], i, pitres );
242 : #else
243 : temp = interpolate_corr( &pt_cor[t0], i, pitres );
244 : #endif
245 24214105 : if ( temp > cor_max )
246 : {
247 22745173 : cor_max = temp;
248 22745173 : fraction = i;
249 : }
250 : }
251 : }
252 :
253 : #ifdef FIX_2272_OOB_INDEXING_IN_LTP_PIT_SEARCH
254 16280098 : cor_idx = cor_idx_ini + t1;
255 : #endif
256 76643765 : for ( i = 0; i <= pitres - 1; i = i + step ) /* Process positive fractions */
257 : {
258 : #ifdef FIX_2272_OOB_INDEXING_IN_LTP_PIT_SEARCH
259 60363667 : temp = interpolate_corr( &cor[cor_idx], i, pitres );
260 : #else
261 : temp = interpolate_corr( &pt_cor[t1], i, pitres );
262 : #endif
263 60363667 : if ( temp > cor_max )
264 : {
265 17249758 : cor_max = temp;
266 17249758 : fraction = i;
267 17249758 : t0 = t1;
268 : }
269 : }
270 16280098 : *pitch_int = t0;
271 16280098 : *pitch_fr = fraction;
272 16280098 : if ( t0 >= pitfr2 )
273 : {
274 2946388 : *index = t0 * ( pitres >> 1 ) + ( fraction >> 1 ) - ( pitfr2 * ( pitres >> 1 ) ) + ( ( pitfr2 - pitmin ) * pitres );
275 : }
276 : else
277 : {
278 13333710 : *index = t0 * pitres + fraction - ( pitmin * pitres );
279 : }
280 :
281 16280098 : return;
282 : }
283 :
284 :
285 : /*---------------------------------------------------------------------*
286 : * tcx_ltp_find_gain()
287 : *
288 : *
289 : *---------------------------------------------------------------------*/
290 :
291 14829334 : 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 14829334 : int16_t gainbits = 2;
299 :
300 : /* Find gain */
301 14829334 : *gain = get_gain( speech, pred_speech, L_frame, NULL );
302 :
303 : /* Quantize gain */
304 14829334 : if ( *gain >= 0.875f )
305 : {
306 2767045 : *gain_index = 3; /* 1.00/2 */
307 : }
308 12062289 : else if ( *gain >= 0.625f )
309 : {
310 3440813 : *gain_index = 2; /* 0.75/2 */
311 : }
312 8621476 : else if ( *gain >= 0.375f )
313 : {
314 3838130 : *gain_index = 1; /* 0.50/2 */
315 : }
316 4783346 : else if ( *gain >= 0.125f )
317 : {
318 3808660 : *gain_index = 0; /* 0.25/2 */
319 : }
320 : else
321 : {
322 974686 : *gain_index = -1; /* escape */
323 : }
324 : /* Dequantize gain */
325 14829334 : *gain = (float) ( *gain_index + 1 ) * 0.625f / (float) ( 1 << gainbits );
326 :
327 14829334 : return;
328 : }
329 :
330 : /*---------------------------------------------------------------------*
331 : * tcx_ltp_encode()
332 : *
333 : *
334 : *---------------------------------------------------------------------*/
335 :
336 14829334 : 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 14829334 : TCX_ENC_HANDLE hTcxEnc = st->hTcxEnc;
364 :
365 14829334 : tcxOnly = st->tcxonly;
366 14829334 : L_subfr = L_SUBFR;
367 14829334 : SideInfoOnly = st->sr_core > 25600;
368 :
369 : /* Reset memory if past frame is acelp */
370 14829334 : if ( st->last_core == ACELP_CORE )
371 : {
372 144922 : hTcxEnc->tcxltp_pitch_int_past = L_frame;
373 144922 : hTcxEnc->tcxltp_pitch_fr_past = 0;
374 144922 : hTcxEnc->tcxltp_gain_past = 0.f;
375 : }
376 :
377 : /* By default, LTP is off */
378 14829334 : ltp_param[0] = 0;
379 14829334 : norm_corr = 0.0f;
380 14829334 : border_case = 0;
381 :
382 14829334 : if ( hTcxEnc->tcxltp || SideInfoOnly )
383 : {
384 : /* Find pitch lag */
385 14829334 : if ( st->pit_res_max == 6 )
386 : {
387 2258732 : delta = 8;
388 : }
389 : else
390 : {
391 12570602 : delta = 16;
392 : }
393 :
394 14829334 : if ( st->element_mode == IVAS_CPE_MDCT )
395 : {
396 11723026 : if ( abs( Top[0] - Top[1] ) < ( delta / 2 ) )
397 : {
398 : /* estimates are close enough and stable, take the artihmetic mean as estimate */
399 6902591 : 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 14461305 : for ( i = 0; i < 2; i++ )
410 : {
411 9640870 : 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 4820435 : i = ( norm_corr_2[1] > norm_corr_2[0] ) ? 1 : 0;
415 4820435 : hTcxEnc->tcxltp_pitch_int = pitch_int_2[i];
416 4820435 : hTcxEnc->tcxltp_pitch_fr = pitch_fr_2[i];
417 4820435 : ltp_param[1] = pit_param_2[i];
418 4820435 : norm_corr = norm_corr_2[i];
419 : }
420 : }
421 : else
422 : {
423 3106308 : 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 14829334 : if ( border_case )
427 : {
428 1309962 : norm_corr = 0.0f;
429 : }
430 14829334 : if ( st->element_mode == IVAS_CPE_DFT )
431 : {
432 379768 : 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 379768 : 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 14449566 : tempFlatness = GetTCXAvgTemporalFlatnessMeasure( st->hTranDet, NSUBBLOCKS, 1 + min( NSUBBLOCKS, (int16_t) ceil( 0.5f + NSUBBLOCKS * ( 1.0f * ( hTcxEnc->tcxltp_pitch_int ) / L_frame ) ) ) );
439 :
440 14449566 : 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 14829334 : if ( ( tcxOnly == 0 && tcxMode == TCX_20 && norm_corr * hTcxEnc->tcxltp_norm_corr_past > 0.25f && tempFlatness < 3.5f ) ||
445 13971426 : ( 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 13950121 : ( tcxOnly == 1 && norm_corr > 0.44f && L_frame * ( 1.2f - norm_corr ) < hTcxEnc->tcxltp_pitch_int ) ||
448 11579239 : ( tcxOnly == 1 && tcxMode == TCX_20 && norm_corr > 0.44f && ( tempFlatness < 6.0f || ( tempFlatness < 7.0f && maxEnergyChange < 22.0f ) ) ) )
449 : {
450 7054167 : if ( disable_ltp == 0 )
451 : {
452 7053112 : ltp_param[0] = 1;
453 : }
454 : }
455 :
456 : /* hysteresis for stable ltp prediction */
457 14829334 : ltp_on = 0;
458 14829334 : 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 5582972 : ltp_on = 1;
461 : }
462 :
463 14829334 : if ( tcxOnly == 1 && ltp_param[0] == 1 )
464 : {
465 : /* increase ltp counter */
466 6196259 : hTcxEnc->tcxltp_on_mem = min( 5, hTcxEnc->tcxltp_on_mem + 1 );
467 : }
468 8633075 : else if ( ltp_on == 1 )
469 : {
470 : /* hysteresis takes effect, decrease counter */
471 643845 : hTcxEnc->tcxltp_on_mem = max( 0, hTcxEnc->tcxltp_on_mem - 1 );
472 643845 : ltp_param[0] = ltp_on;
473 : }
474 : else
475 : {
476 : /* no ltp in this frame, reset counter */
477 7989230 : hTcxEnc->tcxltp_on_mem = 0;
478 : }
479 : }
480 :
481 : /* Find predicted signal */
482 14829334 : predict_signal( speech, pred_speech, hTcxEnc->tcxltp_pitch_int, hTcxEnc->tcxltp_pitch_fr, st->pit_res_max, L_frame );
483 :
484 : /* Find gain */
485 14829334 : tcx_ltp_find_gain( speech, pred_speech, L_frame, &hTcxEnc->tcxltp_gain, <p_param[2] );
486 :
487 14829334 : if ( ltp_param[0] )
488 : {
489 : /* Total number of bits for LTP */
490 7696957 : if ( ltp_param[2] + 1 ) /* hTcxEnc->tcxltp_gain > 0 */
491 : {
492 7694497 : *ltp_bits = 12;
493 : }
494 : else /* hTcxEnc->tcxltp_gain <= 0 -> turn off LTP */
495 : {
496 2460 : ltp_param[0] = 0;
497 : }
498 : }
499 :
500 14829334 : if ( !ltp_param[0] )
501 : {
502 : /* No LTP -> set everything to zero */
503 7134837 : hTcxEnc->tcxltp_pitch_int = L_frame;
504 7134837 : hTcxEnc->tcxltp_pitch_fr = 0;
505 7134837 : ltp_param[1] = 0;
506 7134837 : set_zero( pred_speech, L_frame );
507 7134837 : hTcxEnc->tcxltp_gain = 0.f;
508 7134837 : ltp_param[2] = 0;
509 7134837 : if ( hTcxEnc->tcxltp || SideInfoOnly )
510 : {
511 7134837 : *ltp_bits = 1;
512 : }
513 : else
514 : {
515 0 : *ltp_bits = 0;
516 : }
517 : }
518 :
519 14829334 : si_gain = 0;
520 14829334 : if ( SideInfoOnly )
521 : {
522 5896036 : si_gain = hTcxEnc->tcxltp_gain;
523 5896036 : hTcxEnc->tcxltp_gain = 0.f;
524 : }
525 :
526 14829334 : if ( speech_ltp != NULL )
527 : {
528 2726540 : if ( hTcxEnc->tcxltp_gain_past == 0.f && hTcxEnc->tcxltp_gain == 0.f )
529 : {
530 1845065 : mvr2r( speech, speech_ltp, L_subfr );
531 : }
532 881475 : else if ( hTcxEnc->tcxltp_gain_past == 0.f )
533 : {
534 138016 : alpha = 0.f;
535 138016 : step = 1.f / (float) ( L_subfr );
536 8971040 : for ( n = 0; n < L_subfr; n++ )
537 : {
538 8833024 : speech_ltp[n] = speech[n] - alpha * hTcxEnc->tcxltp_gain * pred_speech[n];
539 8833024 : alpha += step;
540 : }
541 : }
542 : else
543 : {
544 743459 : if ( A == NULL )
545 : {
546 13163544 : for ( i = 0; i <= M; i++ )
547 : {
548 12432236 : s = 0.0;
549 3771775244 : for ( j = 0; j < L_frame - i; j++ )
550 : {
551 3759343008 : s += speech[j - L_frame] * speech[j + i - L_frame];
552 : }
553 12432236 : r[i] = s;
554 : }
555 731308 : if ( r[0] < 100.0f )
556 : {
557 5890 : r[0] = 100.0f;
558 : }
559 731308 : r[0] *= 1.0001f;
560 731308 : lev_dur( Aest, r, M, NULL );
561 731308 : A = Aest;
562 : }
563 :
564 743459 : if ( hTcxEnc->tcxltp_gain > 0.f )
565 : {
566 647114 : predict_signal( speech - M, buf_zir, hTcxEnc->tcxltp_pitch_int, hTcxEnc->tcxltp_pitch_fr, st->pit_res_max, M );
567 : }
568 : else
569 : {
570 96345 : set_f( buf_zir, 0.0f, M );
571 : }
572 :
573 12638803 : for ( n = 0; n < M; n++ )
574 : {
575 11895344 : buf_zir[n] = speech_ltp[n - M] - speech[n - M] + hTcxEnc->tcxltp_gain * buf_zir[n];
576 : }
577 :
578 743459 : zir = buf_zir + M;
579 743459 : set_f( zir, 0.0f, L_subfr );
580 743459 : syn_filt( A, M, zir, zir, L_subfr, buf_zir, 0 );
581 743459 : alpha = 1.f;
582 743459 : step = 1.f / (float) ( L_subfr / 2 );
583 :
584 24534147 : for ( n = L_subfr / 2; n < L_subfr; n++ )
585 : {
586 23790688 : zir[n] *= alpha;
587 23790688 : alpha -= step;
588 : }
589 :
590 48324835 : for ( n = 0; n < L_subfr; n++ )
591 : {
592 47581376 : speech_ltp[n] = ( speech[n] - hTcxEnc->tcxltp_gain * pred_speech[n] ) + zir[n];
593 : }
594 : }
595 :
596 2726540 : if ( SideInfoOnly || hTcxEnc->tcxltp_gain == 0.0f )
597 : {
598 770607778 : for ( n = L_subfr; n < L_frame; n++ )
599 : {
600 768666368 : speech_ltp[n] = speech[n];
601 : }
602 : }
603 : else
604 : {
605 193717098 : for ( n = L_subfr; n < L_frame; n++ )
606 : {
607 192931968 : speech_ltp[n] = speech[n] - hTcxEnc->tcxltp_gain * pred_speech[n];
608 : }
609 : }
610 : }
611 :
612 : /* Update */
613 14829334 : hTcxEnc->tcxltp_pitch_int_past = hTcxEnc->tcxltp_pitch_int;
614 14829334 : hTcxEnc->tcxltp_pitch_fr_past = hTcxEnc->tcxltp_pitch_fr;
615 14829334 : hTcxEnc->tcxltp_gain_past = hTcxEnc->tcxltp_gain;
616 :
617 14829334 : if ( SideInfoOnly )
618 : {
619 5896036 : hTcxEnc->tcxltp_gain = si_gain;
620 : }
621 :
622 14829334 : hTcxEnc->tcxltp_norm_corr_past = norm_corr;
623 :
624 14829334 : return;
625 : }
|