Line data Source code
1 : /*====================================================================================
2 : EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0
3 : ====================================================================================*/
4 :
5 : #include <assert.h>
6 : #include "options.h"
7 : //#include "prot_fx.h"
8 : #include "stl.h"
9 : #include "cnst.h"
10 : #include "basop_util.h"
11 : #include "rom_com.h"
12 : #include "prot_fx.h" /* Function prototypes */
13 : #include "prot_fx_enc.h" /* Function prototypes */
14 :
15 :
16 27129804 : static Word32 dot(
17 : const Word16 *X,
18 : const Word16 *Y,
19 : Word16 n )
20 : {
21 : Word32 acc;
22 : Word16 i;
23 :
24 : Word64 acc_64;
25 27129804 : acc_64 = 0;
26 27129804 : move64();
27 7814126860 : FOR( i = 0; i < n; i++ )
28 : {
29 7786997056 : acc_64 = W_mac0_16_16( acc_64, X[i], Y[i] );
30 : }
31 27129804 : acc = W_sat_l( acc_64 );
32 :
33 27129804 : return acc;
34 : }
35 :
36 :
37 : /* o : interpolated value */
38 5367969 : static Word32 interpolate_corr(
39 : const Word32 *x, /* i : input vector */
40 : const Word16 frac, /* i : fraction of lag */
41 : const Word16 frac_max /* i : max fraction */
42 : )
43 : {
44 : Word32 s;
45 : const Word16 *c, *win;
46 :
47 5367969 : win = E_ROM_inter4_1_fx;
48 5367969 : if ( EQ_16( frac_max, 6 ) )
49 : {
50 287726 : win = E_ROM_inter6_1_fx;
51 : }
52 :
53 5367969 : s = L_deposit_l( 0 );
54 :
55 5367969 : c = &win[frac];
56 5367969 : s = L_add( s, Mpy_32_16_1( x[0], *c ) );
57 5367969 : c += frac_max;
58 5367969 : s = L_add( s, Mpy_32_16_1( x[-1], *c ) );
59 5367969 : c += frac_max;
60 5367969 : s = L_add( s, Mpy_32_16_1( x[-2], *c ) );
61 5367969 : c += frac_max;
62 5367969 : s = L_add( s, Mpy_32_16_1( x[-3], *c ) );
63 :
64 5367969 : c = &win[frac_max - frac];
65 5367969 : s = L_add( s, Mpy_32_16_1( x[1], *c ) );
66 5367969 : c += frac_max;
67 5367969 : s = L_add( s, Mpy_32_16_1( x[2], *c ) );
68 5367969 : c += frac_max;
69 5367969 : s = L_add( s, Mpy_32_16_1( x[3], *c ) );
70 5367969 : c += frac_max;
71 5367969 : s = L_add( s, Mpy_32_16_1( x[4], *c ) );
72 :
73 :
74 5367969 : return s;
75 : }
76 :
77 1312 : static void tcx_ltp_pitch_search(
78 : Word16 pitch_ol,
79 : Word16 *pitch_int,
80 : Word16 *pitch_fr,
81 : Word16 *index,
82 : Word16 *norm_corr,
83 : const Word16 len,
84 : Word16 *wsp,
85 : Word16 pitmin,
86 : Word16 pitfr1,
87 : Word16 pitfr2,
88 : Word16 pitmax,
89 : Word16 pitres )
90 : {
91 : Word16 i, t, t0, t1, step, fraction, t0_min, t0_max, t_min, t_max, delta, temp_m, temp_e, s, s_wsp;
92 : Word32 cor_max, cor[256], *pt_cor, temp;
93 : Word16 wsp2[L_FRAME_PLUS + PIT_MAX_MAX + L_INTERPOL1];
94 :
95 1312 : delta = 16;
96 1312 : move16();
97 1312 : if ( EQ_16( pitres, 6 ) )
98 : {
99 1050 : delta = 8;
100 1050 : move16();
101 : }
102 :
103 1312 : t0_min = sub( pitch_ol, shr( delta, 1 ) );
104 1312 : t0_max = sub( add( t0_min, delta ), 1 );
105 :
106 1312 : IF( LT_16( t0_min, pitmin ) )
107 : {
108 40 : t0_min = pitmin;
109 40 : move16();
110 40 : t0_max = sub( add( t0_min, delta ), 1 );
111 : }
112 :
113 1312 : IF( GT_16( t0_max, pitmax ) )
114 : {
115 18 : t0_max = pitmax;
116 18 : move16();
117 18 : t0_min = add( sub( t0_max, delta ), 1 );
118 : }
119 :
120 1312 : t_min = sub( t0_min, L_INTERPOL1 );
121 1312 : t_max = add( t0_max, L_INTERPOL1 );
122 :
123 : /* normalize wsp */
124 1312 : assert( len + t_max <= L_FRAME_PLUS + PIT_MAX_MAX + L_INTERPOL1 );
125 1312 : s_wsp = getScaleFactor16( wsp - t_max, add( len, t_max ) );
126 1312 : s_wsp = sub( s_wsp, 4 );
127 541679 : FOR( t = negate( t_max ); t < len; t++ )
128 : {
129 540367 : wsp2[t + t_max] = shl( wsp[t], s_wsp );
130 540367 : move16();
131 : }
132 1312 : wsp = wsp2 + t_max;
133 1312 : move16();
134 :
135 1312 : pt_cor = cor;
136 1312 : move32();
137 :
138 24400 : FOR( t = t_min; t <= t_max; t++ )
139 : {
140 23088 : *pt_cor = dot( wsp, wsp - t, len );
141 23088 : move32();
142 23088 : pt_cor++;
143 : }
144 :
145 1312 : pt_cor = cor + L_INTERPOL1;
146 1312 : cor_max = L_add( *pt_cor++, 0 );
147 1312 : t1 = t0_min;
148 1312 : move16();
149 1312 : move32();
150 :
151 12592 : FOR( t = t0_min + 1; t <= t0_max; t++ )
152 : {
153 11280 : IF( GT_32( *pt_cor, cor_max ) )
154 : {
155 4954 : cor_max = *pt_cor;
156 4954 : move32();
157 4954 : t1 = t;
158 4954 : move16();
159 : }
160 11280 : pt_cor++;
161 : }
162 :
163 1312 : temp = dot( wsp, wsp, len );
164 1312 : s = norm_l( temp );
165 1312 : temp_m = extract_h( L_shl( temp, s ) );
166 1312 : temp_e = negate( s );
167 :
168 1312 : temp = dot( wsp - t1, wsp - t1, len );
169 1312 : s = norm_l( temp );
170 1312 : temp_m = mult( temp_m, extract_h( L_shl( temp, s ) ) );
171 1312 : temp_e = sub( temp_e, s );
172 :
173 1312 : temp_m = Sqrt16( temp_m, &temp_e );
174 :
175 1312 : if ( temp_m == 0 )
176 : {
177 0 : temp_m = 1;
178 0 : move16();
179 : }
180 1312 : s = sub( norm_l( cor_max ), 1 );
181 1312 : temp_m = divide1616( extract_h( L_shl( cor_max, s ) ), temp_m );
182 1312 : temp_e = sub( negate( s ), temp_e );
183 :
184 1312 : *norm_corr = shl_sat( temp_m, temp_e );
185 :
186 1312 : IF( GE_16( t1, pitfr1 ) )
187 : {
188 188 : *pitch_int = t1;
189 188 : move16();
190 188 : *pitch_fr = 0;
191 188 : move16();
192 :
193 188 : *index = add( sub( t1, pitfr1 ), extract_l( L_mac0( L_mult0( sub( pitfr2, pitmin ), pitres ),
194 188 : sub( pitfr1, pitfr2 ), shr( pitres, 1 ) ) ) );
195 188 : move16();
196 :
197 188 : return;
198 : }
199 :
200 : /*------------------------------------------------------------------*
201 : * Search fractional pitch with 1/4 subsample resolution.
202 : * search the fractions around t0 and choose the one which maximizes
203 : * the interpolated normalized correlation.
204 : *-----------------------------------------------------------------*/
205 :
206 1124 : pt_cor = cor + sub( L_INTERPOL1, t0_min );
207 1124 : t0 = t1;
208 1124 : move16();
209 :
210 1124 : step = 1;
211 1124 : move16();
212 1124 : if ( GE_16( t0, pitfr2 ) )
213 : {
214 896 : step = 2;
215 896 : move16();
216 : }
217 1124 : fraction = step;
218 1124 : move16();
219 :
220 1124 : IF( EQ_16( t0, t0_min ) ) /* Limit case */
221 : {
222 127 : fraction = 0;
223 127 : move16();
224 127 : cor_max = interpolate_corr( &pt_cor[t0], fraction, pitres );
225 : }
226 : ELSE /* Process negative fractions */
227 : {
228 997 : t0 = sub( t0, 1 );
229 997 : cor_max = interpolate_corr( &pt_cor[t0], fraction, pitres );
230 :
231 2192 : FOR( i = fraction + step; i < pitres; i += step )
232 : {
233 1195 : temp = interpolate_corr( &pt_cor[t0], i, pitres );
234 :
235 1195 : IF( GT_32( temp, cor_max ) )
236 : {
237 1165 : cor_max = L_add( temp, 0 );
238 1165 : fraction = i;
239 1165 : move16();
240 : }
241 : }
242 : }
243 :
244 1124 : i = 0;
245 1124 : move16();
246 4711 : FOR( i = 0; i < pitres; i += step ) /* Process positive fractions */
247 : {
248 3587 : temp = interpolate_corr( &pt_cor[t1], i, pitres );
249 :
250 3587 : IF( GT_32( temp, cor_max ) )
251 : {
252 1100 : cor_max = L_add( temp, 0 );
253 1100 : fraction = i;
254 1100 : move16();
255 1100 : t0 = t1;
256 1100 : move16();
257 : }
258 : }
259 :
260 1124 : *pitch_int = t0;
261 1124 : move16();
262 1124 : *pitch_fr = fraction;
263 1124 : move16();
264 :
265 1124 : IF( GE_16( t0, pitfr2 ) )
266 : {
267 896 : *index = add( extract_l( L_mac0( L_mult0( sub( t0, pitfr2 ), shr( pitres, 1 ) ),
268 896 : sub( pitfr2, pitmin ), pitres ) ),
269 896 : shr( fraction, 1 ) );
270 896 : move16();
271 : }
272 : ELSE
273 : {
274 228 : *index = add( imult1616( sub( t0, pitmin ), pitres ), fraction );
275 228 : move16();
276 : }
277 : }
278 :
279 1083424 : static void tcx_ltp_pitch_search_ivas_fx(
280 : const Word16 pitch_ol,
281 : Word16 *pitch_int,
282 : Word16 *pitch_fr,
283 : Word16 *index,
284 : Word16 *norm_corr,
285 : const Word16 len,
286 : const Word16 *wsp, // Qx
287 : const Word16 pitmin,
288 : const Word16 pitfr1,
289 : const Word16 pitfr2,
290 : const Word16 pitmax,
291 : const Word16 pitres,
292 : const Word16 check_border_case,
293 : Word16 *border_case )
294 : {
295 : Word16 i, t, t0, t1, step, fraction, t0_min, t0_max, t_min, t_max, delta, temp_m, temp_e, s, s_wsp;
296 : Word32 cor_max, cor[256], *pt_cor, temp;
297 : Word16 wsp2[L_FRAME_PLUS + PIT_MAX_MAX + L_INTERPOL1];
298 :
299 1083424 : delta = 16;
300 1083424 : move16();
301 1083424 : if ( EQ_16( pitres, 6 ) )
302 : {
303 174580 : delta = 8;
304 174580 : move16();
305 : }
306 :
307 1083424 : t0_min = sub( pitch_ol, shr( delta, 1 ) );
308 1083424 : t0_max = sub( add( t0_min, delta ), 1 );
309 :
310 1083424 : IF( LT_16( t0_min, pitmin ) )
311 : {
312 87031 : t0_min = pitmin;
313 87031 : move16();
314 87031 : t0_max = sub( add( t0_min, delta ), 1 );
315 : }
316 :
317 1083424 : IF( GT_16( t0_max, pitmax ) )
318 : {
319 21975 : t0_max = pitmax;
320 21975 : move16();
321 21975 : t0_min = add( sub( t0_max, delta ), 1 );
322 : }
323 :
324 1083424 : t_min = sub( t0_min, L_INTERPOL1 );
325 1083424 : t_max = add( t0_max, L_INTERPOL1 );
326 :
327 : /* normalize wsp */
328 1083424 : s_wsp = getScaleFactor16( wsp - t_max, add( len, t_max ) );
329 1083424 : s_wsp = sub( s_wsp, 4 );
330 444257573 : FOR( t = negate( t_max ); t < len; t++ )
331 : {
332 443174149 : wsp2[t + t_max] = shl( wsp[t], s_wsp ); // Q(x + s_wsp)
333 443174149 : move16();
334 : }
335 1083424 : wsp = wsp2 + t_max;
336 :
337 1083424 : pt_cor = cor;
338 :
339 25688960 : FOR( t = t_min; t <= t_max; t++ )
340 : {
341 24605536 : *pt_cor = dot( wsp, wsp - t, len ); // 2*(x + s_wsp)
342 24605536 : move32();
343 24605536 : pt_cor++;
344 : }
345 :
346 1083424 : pt_cor = cor + L_INTERPOL1;
347 1083424 : cor_max = L_add( *pt_cor++, 0 );
348 1083424 : t1 = t0_min;
349 1083424 : move16();
350 :
351 15938144 : FOR( t = t0_min + 1; t <= t0_max; t++ )
352 : {
353 14854720 : IF( GT_32( *pt_cor, cor_max ) )
354 : {
355 5705553 : cor_max = *pt_cor;
356 5705553 : move32();
357 5705553 : t1 = t;
358 5705553 : move16();
359 : }
360 14854720 : pt_cor++;
361 : }
362 :
363 1083424 : temp = dot( wsp, wsp, len ); // 2*(x + s_wsp)
364 1083424 : s = norm_l( temp );
365 1083424 : temp_e = negate( s );
366 1083424 : temp_m = extract_h( L_shl( temp, s ) ); // Q(2*(x + s_wsp) - temp_e - 16)
367 :
368 1083424 : temp = dot( wsp - t1, wsp - t1, len ); // 2*(x + s_wsp)
369 1083424 : s = norm_l( temp );
370 1083424 : temp_m = mult( temp_m, extract_h( L_shl( temp, s ) ) ); // //Q = 4*(x + s_wsp) + s - temp_e - 47
371 1083424 : temp_e = sub( temp_e, s );
372 :
373 1083424 : temp_m = Sqrt16( temp_m, &temp_e );
374 :
375 1083424 : if ( temp_m == 0 )
376 : {
377 14285 : temp_m = 1;
378 14285 : move16();
379 : }
380 1083424 : s = sub( norm_l( cor_max ), 1 );
381 1083424 : temp_m = divide1616( extract_h( L_shl( cor_max, s ) ), temp_m );
382 1083424 : temp_e = sub( negate( s ), temp_e );
383 :
384 1083424 : *norm_corr = shl_sat( temp_m, temp_e );
385 :
386 1083424 : test();
387 1083424 : IF( check_border_case && EQ_16( t1, t0_min ) )
388 : {
389 : Word32 tmpCor;
390 383916 : FOR( t = t1 - L_INTERPOL1; t < t1; t++ )
391 : {
392 331708 : tmpCor = dot( wsp, wsp - t, len );
393 331708 : IF( GT_32( tmpCor, cor_max ) )
394 : {
395 86740 : *border_case = 1;
396 86740 : move16();
397 86740 : break;
398 : }
399 : }
400 : }
401 :
402 1083424 : IF( GE_16( t1, pitfr1 ) )
403 : {
404 232891 : *pitch_int = t1;
405 232891 : move16();
406 232891 : *pitch_fr = 0;
407 232891 : move16();
408 :
409 232891 : *index = add( sub( t1, pitfr1 ), extract_l( L_mac0( L_mult0( sub( pitfr2, pitmin ), pitres ),
410 232891 : sub( pitfr1, pitfr2 ), shr( pitres, 1 ) ) ) );
411 232891 : move16();
412 :
413 232891 : return;
414 : }
415 :
416 : /*------------------------------------------------------------------*
417 : * Search fractional pitch with 1/4 subsample resolution.
418 : * search the fractions around t0 and choose the one which maximizes
419 : * the interpolated normalized correlation.
420 : *-----------------------------------------------------------------*/
421 :
422 850533 : pt_cor = cor + sub( L_INTERPOL1, t0_min );
423 850533 : t0 = t1;
424 850533 : move16();
425 :
426 850533 : step = 1;
427 850533 : move16();
428 850533 : if ( GE_16( t0, pitfr2 ) )
429 : {
430 128800 : step = 2;
431 128800 : move16();
432 : }
433 850533 : fraction = step;
434 850533 : move16();
435 :
436 850533 : IF( EQ_16( t0, t0_min ) ) /* Limit case */
437 : {
438 111956 : fraction = 0;
439 111956 : move16();
440 111956 : cor_max = interpolate_corr( &pt_cor[t0], fraction, pitres );
441 : }
442 : ELSE /* Process negative fractions */
443 : {
444 738577 : t0 = sub( t0, 1 );
445 738577 : cor_max = interpolate_corr( &pt_cor[t0], fraction, pitres );
446 :
447 2045428 : FOR( i = fraction + step; i < pitres; i += step )
448 : {
449 1306851 : temp = interpolate_corr( &pt_cor[t0], i, pitres );
450 :
451 1306851 : IF( GT_32( temp, cor_max ) )
452 : {
453 1223268 : cor_max = L_add( temp, 0 );
454 1223268 : fraction = i;
455 1223268 : move16();
456 : }
457 : }
458 : }
459 :
460 4055212 : FOR( i = 0; i < pitres; i += step ) /* Process positive fractions */
461 : {
462 3204679 : temp = interpolate_corr( &pt_cor[t1], i, pitres );
463 :
464 3204679 : IF( GT_32( temp, cor_max ) )
465 : {
466 912655 : cor_max = L_add( temp, 0 );
467 912655 : fraction = i;
468 912655 : move16();
469 912655 : t0 = t1;
470 912655 : move16();
471 : }
472 : }
473 :
474 850533 : *pitch_int = t0;
475 850533 : move16();
476 850533 : *pitch_fr = fraction;
477 850533 : move16();
478 :
479 850533 : IF( GE_16( t0, pitfr2 ) )
480 : {
481 127958 : *index = add( extract_l( L_mac0( L_mult0( sub( t0, pitfr2 ), shr( pitres, 1 ) ),
482 127958 : sub( pitfr2, pitmin ), pitres ) ),
483 127958 : shr( fraction, 1 ) );
484 127958 : move16();
485 : }
486 : ELSE
487 : {
488 722575 : *index = add( imult1616( sub( t0, pitmin ), pitres ), fraction );
489 722575 : move16();
490 : }
491 : }
492 :
493 :
494 943 : static void tcx_ltp_find_gain( Word16 *speech, Word16 *pred_speech, Word16 L_frame, Word16 *gain, Word16 *gain_index )
495 : {
496 : Word32 corr, ener;
497 : Word16 i, g, s1, s2, tmp;
498 :
499 943 : s1 = sub( getScaleFactor16( speech, L_frame ), 4 );
500 943 : s2 = sub( getScaleFactor16( pred_speech, L_frame ), 4 );
501 :
502 : /* Find gain */
503 943 : corr = L_deposit_l( 0 );
504 943 : ener = L_deposit_l( 1 );
505 :
506 289711 : FOR( i = 0; i < L_frame; i++ )
507 : {
508 288768 : tmp = shl_sat( pred_speech[i], s2 );
509 288768 : corr = L_mac0_sat( corr, shl( speech[i], s1 ), tmp );
510 288768 : ener = L_mac0_sat( ener, tmp, tmp );
511 : }
512 :
513 943 : s1 = sub( 1, add( s1, s2 ) );
514 943 : s2 = sub( 1, shl( s2, 1 ) );
515 :
516 943 : tmp = sub( norm_l( corr ), 1 );
517 943 : corr = L_shl( corr, tmp );
518 943 : s1 = sub( s1, tmp );
519 :
520 943 : tmp = norm_l( ener );
521 943 : ener = L_shl( ener, tmp );
522 943 : s2 = sub( s2, tmp );
523 :
524 943 : g = divide1616( round_fx_sat( corr ), round_fx_sat( ener ) );
525 : BASOP_SATURATE_WARNING_OFF_EVS
526 943 : g = shl_sat( g, sub( s1, s2 ) );
527 : BASOP_SATURATE_WARNING_ON_EVS
528 :
529 : /* Quantize gain */
530 943 : g = shr( sub_sat( g, 0x1000 ), 13 );
531 943 : g = s_max( g, -1 );
532 :
533 943 : *gain_index = g;
534 943 : move16();
535 :
536 : /* Dequantize gain */
537 943 : *gain = imult1616( add( g, 1 ), 0x1400 );
538 943 : move16();
539 943 : }
540 :
541 888815 : static void tcx_ltp_find_gain_ivas_fx( Word16 *speech /*Qx*/, Word16 *pred_speech /*Qx*/, Word16 L_frame, Word16 *gain, Word16 *gain_index )
542 : {
543 : Word32 corr, ener;
544 : Word16 i, g, s1, s2, tmp;
545 :
546 888815 : s1 = sub( getScaleFactor16( speech, L_frame ), 4 );
547 888815 : s2 = sub( getScaleFactor16( pred_speech, L_frame ), 4 );
548 :
549 : /* Find gain */
550 888815 : corr = L_deposit_l( 0 );
551 888815 : ener = L_deposit_l( 1 );
552 :
553 273176751 : FOR( i = 0; i < L_frame; i++ )
554 : {
555 272287936 : tmp = shl_sat( pred_speech[i], s2 ); // Qx + s2
556 272287936 : corr = L_mac0_sat( corr, shl( speech[i], s1 ), tmp ); // 2*Qx + s1 + s2
557 272287936 : ener = L_mac0_sat( ener, tmp, tmp ); // 2*(Qx+s2)
558 : }
559 :
560 888815 : s1 = sub( 1, add( s1, s2 ) );
561 888815 : s2 = sub( 1, shl( s2, 1 ) );
562 :
563 888815 : tmp = sub( norm_l( corr ), 1 );
564 888815 : corr = L_shl( corr, tmp );
565 888815 : s1 = sub( s1, tmp );
566 :
567 888815 : tmp = norm_l( ener );
568 888815 : ener = L_shl( ener, tmp );
569 888815 : s2 = sub( s2, tmp );
570 :
571 888815 : g = divide1616( round_fx_sat( corr ), round_fx_sat( ener ) );
572 : BASOP_SATURATE_WARNING_OFF_EVS
573 888815 : g = shl_sat( g, sub( s1, s2 ) ); /*Q15*/
574 : BASOP_SATURATE_WARNING_ON_EVS
575 :
576 : /* Quantize gain */
577 888815 : g = shr_sat( sub_sat( g /*Q15*/, 0x1000 ), 13 ); // Q0
578 888815 : g = s_max( g, -1 );
579 :
580 888815 : *gain_index = g;
581 888815 : move16();
582 :
583 : /* Dequantize gain */
584 888815 : *gain = imult1616( add( g, 1 ), 0x1400 ); /*Q15*/
585 888815 : move16();
586 :
587 888815 : return;
588 : }
589 :
590 1312 : void tcx_ltp_encode_fx(
591 : Word16 tcxltp_on,
592 : Word8 tcxOnly,
593 : Word16 tcxMode,
594 : Word16 L_frame,
595 : Word16 L_subfr,
596 : Word16 *speech,
597 : Word16 *speech_ltp,
598 : Word16 *wsp,
599 : Word16 Top,
600 : Word16 *ltp_param,
601 : Word16 *ltp_bits,
602 : Word16 *pitch_int,
603 : Word16 *pitch_fr,
604 : Word16 *gain,
605 : Word16 *pitch_int_past,
606 : Word16 *pitch_fr_past,
607 : Word16 *gain_past,
608 : Word16 *norm_corr_past,
609 : Word16 last_core,
610 : Word16 pitmin,
611 : Word16 pitfr1,
612 : Word16 pitfr2,
613 : Word16 pitmax,
614 : Word16 pitres,
615 : TRAN_DET_HANDLE hTranDet,
616 : Word8 SideInfoOnly,
617 : Word16 *A,
618 : Word16 lpcorder )
619 : {
620 : Word16 n;
621 : Word16 norm_corr;
622 : Word16 pred_speech[L_FRAME32k];
623 : Word16 tempFlatness;
624 : Word16 maxEnergyChange;
625 : Word16 buf_zir[M + L_SUBFR], *zir;
626 : Word16 Aest[M + 1];
627 : Word16 alpha, step;
628 :
629 1312 : norm_corr = 0;
630 1312 : move16();
631 :
632 : /* Reset memory if past frame is acelp */
633 1312 : IF( last_core == ACELP_CORE )
634 : {
635 627 : *pitch_int_past = L_frame;
636 627 : move16();
637 627 : *pitch_fr_past = 0;
638 627 : move16();
639 627 : *gain_past = 0;
640 627 : move16();
641 : }
642 :
643 : /* By default, LTP is off */
644 1312 : ltp_param[0] = 0;
645 1312 : move16();
646 :
647 1312 : test();
648 1312 : IF( tcxltp_on != 0 || SideInfoOnly != 0 )
649 : {
650 : Word16 nPrevSubblocks;
651 1312 : Word8 isTCX10 = 0;
652 :
653 1312 : if ( EQ_16( tcxMode, TCX_10 ) )
654 : {
655 0 : isTCX10 = 1;
656 0 : move16();
657 : }
658 :
659 : /* Find pitch lag */
660 1312 : tcx_ltp_pitch_search( Top, pitch_int, pitch_fr, <p_param[1], &norm_corr, L_frame, wsp, pitmin, pitfr1, pitfr2, pitmax, pitres );
661 :
662 1312 : nPrevSubblocks = extract_h( L_mac( 0x17fff, NSUBBLOCKS, div_s( *pitch_int, L_frame ) ) );
663 1312 : nPrevSubblocks = add( s_min( nPrevSubblocks, NSUBBLOCKS ), 1 );
664 :
665 1312 : tempFlatness = GetTCXAvgTemporalFlatnessMeasure_fx( hTranDet, NSUBBLOCKS, nPrevSubblocks );
666 :
667 1312 : maxEnergyChange = GetTCXMaxenergyChange_fx( hTranDet, (const Word8) isTCX10, NSUBBLOCKS, nPrevSubblocks );
668 :
669 : /* Switch LTP on */
670 1312 : test();
671 1312 : test();
672 1312 : test();
673 1312 : test();
674 1312 : test();
675 1312 : test();
676 1312 : test();
677 1312 : test();
678 1312 : test();
679 1312 : test();
680 1312 : test();
681 1312 : test();
682 1312 : test();
683 1312 : test();
684 1312 : test();
685 1312 : test();
686 : BASOP_SATURATE_WARNING_OFF_EVS;
687 1312 : if ( (
688 1312 : tcxOnly == 0 &&
689 2624 : EQ_16( tcxMode, TCX_20 ) &&
690 2327 : GT_16( mult( norm_corr, *norm_corr_past ), 0x2000 ) &&
691 1384 : LT_16( tempFlatness, 448 /*3.5f Q7*/ ) ) ||
692 0 : ( tcxOnly != 0 &&
693 0 : EQ_16( tcxMode, TCX_10 ) &&
694 0 : GT_16( s_max( norm_corr, *norm_corr_past ), 0x4000 ) &&
695 369 : LT_16( maxEnergyChange, 448 /*3.5f Q7*/ ) ) ||
696 : ( /* Use LTP for lower correlation when pitch lag is big, L_frame*(1.2f-norm_corr) < pitch_int <=> norm_corr > 1.2f-pitch_int/L_frame */
697 0 : tcxOnly != 0 &&
698 0 : GT_16( norm_corr, 14418 /*0.44f Q15*/ ) &&
699 0 : L_msu( L_mult( L_frame, sub( 19661 /*1.2f Q14*/, shr( norm_corr, 1 ) ) ), *pitch_int, 1 << 14 ) < 0 /* L_frame*(1.2f-norm_corr) < pitch_int */
700 369 : ) ||
701 0 : ( tcxOnly != 0 &&
702 0 : EQ_16( tcxMode, TCX_20 ) &&
703 0 : GT_16( norm_corr, 14418 /*0.44f Q15*/ ) &&
704 0 : ( LT_16( tempFlatness, 768 /*6.0f Q7*/ ) ||
705 0 : ( LT_16( tempFlatness, 896 /*7.0f Q7*/ ) &&
706 0 : LT_16( maxEnergyChange, 2816 /*22.0f Q7*/ ) ) ) ) )
707 : {
708 943 : ltp_param[0] = 1;
709 943 : move16();
710 : }
711 : BASOP_SATURATE_WARNING_ON_EVS;
712 : }
713 :
714 1312 : IF( ltp_param[0] != 0 )
715 : {
716 : /* Find predicted signal */
717 943 : predict_signal( speech, pred_speech, *pitch_int, *pitch_fr, pitres, L_frame );
718 :
719 : /* Find gain */
720 943 : tcx_ltp_find_gain( speech, pred_speech, L_frame, gain, <p_param[2] );
721 :
722 : /* Total number of bits for LTP */
723 943 : IF( NE_16( ltp_param[2], -1 ) ) /* gain > 0 */
724 : {
725 943 : *ltp_bits = 12;
726 943 : move16();
727 : }
728 : ELSE /* gain <= 0 -> turn off LTP */
729 : {
730 0 : ltp_param[0] = 0;
731 0 : move16();
732 : }
733 : }
734 :
735 1312 : IF( ltp_param[0] == 0 )
736 : {
737 : /* No LTP -> set everything to zero */
738 369 : *pitch_int = L_frame;
739 369 : move16();
740 369 : *pitch_fr = 0;
741 369 : move16();
742 369 : ltp_param[1] = 0;
743 369 : move16();
744 369 : set16_fx( pred_speech, 0, L_frame );
745 369 : *gain = 0;
746 369 : move16();
747 369 : ltp_param[2] = 0;
748 369 : move16();
749 :
750 369 : *ltp_bits = 0;
751 369 : move16();
752 369 : test();
753 369 : IF( tcxltp_on != 0 || SideInfoOnly != 0 )
754 : {
755 369 : *ltp_bits = 1;
756 369 : move16();
757 : }
758 : }
759 :
760 1312 : IF( SideInfoOnly != 0 )
761 : {
762 0 : *gain = 0;
763 0 : move16();
764 : }
765 :
766 1312 : test();
767 1312 : IF( *gain_past == 0 && *gain == 0 )
768 : {
769 301 : Copy( speech, speech_ltp, L_subfr );
770 : }
771 1011 : ELSE IF( *gain_past == 0 )
772 : {
773 532 : alpha = 0;
774 532 : move16();
775 :
776 : /* step = 1.f/(float)(L_subfr); */
777 532 : step = shl( 2, norm_s( L_subfr ) );
778 532 : IF( s_and( L_subfr, sub( L_subfr, 1 ) ) != 0 )
779 : {
780 0 : step = mult_r( step, 26214 /*64.f/80.f Q15*/ );
781 : }
782 :
783 34580 : FOR( n = 0; n < L_subfr; n++ )
784 : {
785 34048 : speech_ltp[n] = sub_sat( speech[n], mult_r_sat( *gain, mult_r_sat( alpha, pred_speech[n] ) ) );
786 34048 : move16();
787 : BASOP_SATURATE_WARNING_OFF_EVS;
788 34048 : alpha = add_sat( alpha, step );
789 : BASOP_SATURATE_WARNING_ON_EVS;
790 : }
791 : }
792 : ELSE
793 : {
794 479 : IF( A == NULL )
795 : {
796 0 : tcx_ltp_get_lpc( speech - L_frame, L_frame, Aest, lpcorder );
797 0 : A = Aest;
798 : }
799 :
800 479 : IF( *gain > 0 )
801 : {
802 411 : predict_signal( speech - lpcorder, buf_zir, *pitch_int, *pitch_fr, pitres, lpcorder );
803 : }
804 : ELSE
805 : {
806 68 : set16_fx( buf_zir, 0, lpcorder );
807 : }
808 :
809 8143 : FOR( n = 0; n < lpcorder; n++ )
810 : {
811 7664 : buf_zir[n] = add_sat( sub_sat( speech_ltp[n - lpcorder], speech[n - lpcorder] ), mult_r( *gain, buf_zir[n] ) );
812 7664 : move16();
813 : }
814 :
815 479 : zir = buf_zir + lpcorder;
816 :
817 479 : set16_fx( zir, 0, L_subfr );
818 :
819 479 : E_UTIL_synthesis( 0, A, zir, zir, L_subfr, buf_zir, 0, lpcorder );
820 :
821 479 : alpha = 0x7FFF;
822 479 : move16();
823 : /* step = 1.f/(float)(L_subfr/2); */
824 479 : step = shl( 4, norm_s( L_subfr ) );
825 479 : IF( s_and( L_subfr, sub( L_subfr, 1 ) ) != 0 )
826 : {
827 0 : step = mult_r( step, 26214 /*64.f/80.f Q15*/ );
828 : }
829 :
830 15807 : FOR( n = ( L_subfr >> 1 ); n < L_subfr; n++ )
831 : {
832 15328 : zir[n] = mult_r( zir[n], alpha );
833 15328 : move16();
834 15328 : alpha = sub( alpha, step );
835 : }
836 :
837 31135 : FOR( n = 0; n < L_subfr; n++ )
838 : {
839 30656 : speech_ltp[n] = add_sat( sub_sat( speech[n], mult_r_sat( *gain, pred_speech[n] ) ), zir[n] );
840 30656 : move16();
841 : }
842 : }
843 :
844 1312 : test();
845 1312 : IF( SideInfoOnly || *gain == 0 )
846 : {
847 91057 : FOR( n = L_subfr; n < L_frame; n++ )
848 : {
849 90688 : speech_ltp[n] = speech[n];
850 90688 : move16();
851 : }
852 : }
853 : ELSE
854 : {
855 229359 : FOR( n = L_subfr; n < L_frame; n++ )
856 : {
857 228416 : speech_ltp[n] = sub_sat( speech[n], mult( *gain, pred_speech[n] ) );
858 228416 : move16();
859 : }
860 : }
861 :
862 : /* Update */
863 1312 : *pitch_int_past = *pitch_int;
864 1312 : move16();
865 1312 : *pitch_fr_past = *pitch_fr;
866 1312 : move16();
867 1312 : *gain_past = *gain;
868 1312 : move16();
869 1312 : *norm_corr_past = norm_corr;
870 1312 : move16();
871 :
872 1312 : return;
873 : }
874 :
875 :
876 888815 : void tcx_ltp_encode_ivas_fx(
877 : Encoder_State *st,
878 : const Word16 tcxMode,
879 : const Word16 L_frame,
880 : Word16 *speech_fx,
881 : Word16 *speech_ltp_fx,
882 : const Word16 *wsp_fx,
883 : const Word16 Top[],
884 : Word16 *ltp_param,
885 : Word16 *ltp_bits,
886 : Word16 *A_fx,
887 : const Word16 disable_ltp,
888 : const Word16 element_mode )
889 : {
890 : Word16 i, n;
891 : Word16 ltp_on, tcxOnly, L_subfr, SideInfoOnly, delta;
892 : Word16 si_gain_fx; // Q15
893 : Word16 alpha_fx, step_fx; // Q15
894 : Word16 norm_corr_fx; // Q15
895 : Word16 border_case;
896 : Word16 tempFlatness_fx; // Q7
897 : Word16 maxEnergyChange_fx; // Q3
898 : Word16 pred_speech_fx[L_FRAME_PLUS]; // Qspeech
899 : Word16 buf_zir_fx[M + L_FRAME_PLUS / 4], *zir_fx; // Qspeech
900 : Word16 Aest_fx[M + 1];
901 : Word16 exponent;
902 : Word16 sqr;
903 888815 : TCX_ENC_HANDLE hTcxEnc = st->hTcxEnc;
904 :
905 888815 : tcxOnly = st->tcxonly;
906 888815 : move16();
907 888815 : L_subfr = L_SUBFR;
908 888815 : move16();
909 888815 : SideInfoOnly = extract_l( GT_32( st->sr_core, 25600 ) );
910 888815 : move16();
911 :
912 : /* Reset memory if past frame is acelp */
913 888815 : IF( st->last_core == ACELP_CORE )
914 : {
915 9260 : hTcxEnc->tcxltp_pitch_int_past = L_frame;
916 9260 : move16();
917 9260 : hTcxEnc->tcxltp_pitch_fr_past = 0;
918 9260 : move16();
919 9260 : hTcxEnc->tcxltp_gain_past = 0;
920 9260 : move16();
921 : }
922 :
923 : /* By default, LTP is off */
924 888815 : ltp_param[0] = 0;
925 888815 : move16();
926 888815 : norm_corr_fx = 0;
927 888815 : move16();
928 888815 : border_case = 0;
929 888815 : move16();
930 :
931 888815 : test();
932 888815 : IF( hTcxEnc->tcxltp || SideInfoOnly )
933 : {
934 : Word16 nPrevSubblocks;
935 888815 : Word8 isTCX10 = 0;
936 888815 : move16();
937 :
938 : /* Find pitch lag */
939 888815 : IF( EQ_16( st->pit_res_max, 6 ) )
940 : {
941 174580 : delta = 8;
942 174580 : move16();
943 : }
944 : ELSE
945 : {
946 714235 : delta = 16;
947 714235 : move16();
948 : }
949 :
950 888815 : IF( EQ_16( st->element_mode, IVAS_CPE_MDCT ) )
951 : {
952 652353 : IF( LT_16( abs_s( sub( Top[0], Top[1] ) ), shr( delta, 1 ) ) )
953 : {
954 : /* estimates are close enough and stable, take the artihmetic mean as estimate */
955 457744 : tcx_ltp_pitch_search_ivas_fx( shr( add( Top[0], Top[1] ), 1 ), &hTcxEnc->tcxltp_pitch_int, &hTcxEnc->tcxltp_pitch_fr, <p_param[1], &norm_corr_fx, L_frame, wsp_fx, st->pit_min, st->pit_fr1, st->pit_fr2, st->pit_max, st->pit_res_max, 1, &border_case );
956 : }
957 : ELSE
958 : {
959 : /* pitch jumps between half frames, calc ltp for both estimates, choose the better one */
960 : Word16 pitch_int_2[2];
961 : Word16 pitch_fr_2[2];
962 : Word16 norm_corr_2_fx[2];
963 : Word16 pit_param_2[2];
964 :
965 583827 : FOR( i = 0; i < 2; i++ )
966 : {
967 389218 : tcx_ltp_pitch_search_ivas_fx( Top[i], &pitch_int_2[i], &pitch_fr_2[i], &pit_param_2[i], &norm_corr_2_fx[i], L_frame, wsp_fx, st->pit_min, st->pit_fr1, st->pit_fr2, st->pit_max, st->pit_res_max, 1, &border_case );
968 : }
969 :
970 194609 : IF( GT_16( norm_corr_2_fx[1], norm_corr_2_fx[0] ) )
971 : {
972 125128 : i = 1;
973 : }
974 : ELSE
975 : {
976 69481 : i = 0;
977 : }
978 194609 : move16();
979 :
980 194609 : hTcxEnc->tcxltp_pitch_int = pitch_int_2[i];
981 194609 : move16();
982 194609 : hTcxEnc->tcxltp_pitch_fr = pitch_fr_2[i];
983 194609 : move16();
984 194609 : ltp_param[1] = pit_param_2[i];
985 194609 : move16();
986 194609 : norm_corr_fx = norm_corr_2_fx[i];
987 194609 : move16();
988 : }
989 : }
990 : ELSE
991 : {
992 : Word16 tmp;
993 236462 : IF( GT_16( element_mode, EVS_MONO ) )
994 : {
995 236462 : tmp = 1;
996 : }
997 : ELSE
998 : {
999 0 : tmp = 0;
1000 : }
1001 236462 : move16();
1002 236462 : tcx_ltp_pitch_search_ivas_fx( Top[1], &hTcxEnc->tcxltp_pitch_int, &hTcxEnc->tcxltp_pitch_fr, <p_param[1], &norm_corr_fx, L_frame, wsp_fx, st->pit_min, st->pit_fr1, st->pit_fr2, st->pit_max, st->pit_res_max, tmp, &border_case );
1003 : }
1004 :
1005 888815 : if ( border_case )
1006 : {
1007 82639 : norm_corr_fx = 0;
1008 82639 : move16();
1009 : }
1010 :
1011 : // nPrevSubblocks = ( 1 + min( NSUBBLOCKS, (int16_t) ceil( 0.5f + NSUBBLOCKS * ( 1.0f * ( hTcxEnc->tcxltp_pitch_int ) / L_frame ) ) ) );
1012 888815 : nPrevSubblocks = extract_h( L_add( L_mac( 32768, NSUBBLOCKS, div_s( hTcxEnc->tcxltp_pitch_int, L_frame ) ), 65535 ) ); // 0.5f Q16 //65535( 1.Q16 - 1) added to get the ceil
1013 888815 : nPrevSubblocks = add( s_min( nPrevSubblocks, NSUBBLOCKS ), 1 );
1014 :
1015 888815 : IF( EQ_16( st->element_mode, IVAS_CPE_DFT ) )
1016 : {
1017 14333 : tempFlatness_fx = extract_l( L_shr( GetTCXAvgTemporalFlatnessMeasure_ivas_fx( st->hTranDet, NSUBBLOCKS - NSUBBLOCKS_SHIFT, add( nPrevSubblocks, NSUBBLOCKS_SHIFT ) ), 14 ) ); // Q7
1018 14333 : maxEnergyChange_fx = GetTCXMaxenergyChange_ivas_fx( st->hTranDet, (const Word8) isTCX10, NSUBBLOCKS - NSUBBLOCKS_SHIFT, add( nPrevSubblocks, NSUBBLOCKS_SHIFT ) ); // Q3
1019 : }
1020 : ELSE
1021 : {
1022 874482 : tempFlatness_fx = extract_l( L_shr( ( GetTCXAvgTemporalFlatnessMeasure_ivas_fx( st->hTranDet, NSUBBLOCKS, nPrevSubblocks ) ), 14 ) ); // Q7
1023 874482 : maxEnergyChange_fx = GetTCXMaxenergyChange_ivas_fx( st->hTranDet, (const Word8) isTCX10, NSUBBLOCKS, nPrevSubblocks ); // Q3
1024 : }
1025 :
1026 : /* Switch LTP on */
1027 888815 : test();
1028 888815 : test();
1029 888815 : test();
1030 888815 : test();
1031 888815 : test();
1032 888815 : test();
1033 888815 : test();
1034 888815 : test();
1035 888815 : test();
1036 888815 : test();
1037 888815 : test();
1038 888815 : test();
1039 888815 : test();
1040 888815 : test();
1041 888815 : test();
1042 888815 : test();
1043 888815 : IF( (
1044 : ( tcxOnly == 0 ) &&
1045 : EQ_16( tcxMode, TCX_20 ) &&
1046 : GT_16( mult( norm_corr_fx, hTcxEnc->tcxltp_norm_corr_past ), 0x2000 ) && /*mult returns Q15*/
1047 : LT_16( tempFlatness_fx, 448 /*3.5f Q7*/ ) ) ||
1048 : ( EQ_16( tcxOnly, 1 ) &&
1049 : EQ_16( tcxMode, TCX_10 ) &&
1050 : GT_16( s_max( norm_corr_fx, hTcxEnc->tcxltp_norm_corr_past ), 0x4000 ) &&
1051 : LT_16( maxEnergyChange_fx, 28 /*3.5f Q3*/ ) ) ||
1052 : ( /* Use LTP for lower correlation when pitch lag is big, L_frame*(1.2f-norm_corr) < pitch_int <=> norm_corr > 1.2f-pitch_int/L_frame */
1053 : EQ_16( tcxOnly, 1 ) &&
1054 : GT_16( norm_corr_fx, 14418 /*0.44f Q15*/ ) &&
1055 : L_msu( L_mult( L_frame, sub( 19661 /*1.2f Q14*/, shr( norm_corr_fx, 1 ) ) ), hTcxEnc->tcxltp_pitch_int, 1 << 14 ) < 0 /* L_frame*(1.2f-norm_corr) < pitch_int */
1056 : ) ||
1057 : ( EQ_16( tcxOnly, 1 ) &&
1058 : EQ_16( tcxMode, TCX_20 ) &&
1059 : GT_16( norm_corr_fx, 14418 /*0.44f Q15*/ ) &&
1060 : ( LT_16( tempFlatness_fx, 768 /*6.0f Q7*/ ) ||
1061 : ( LT_16( tempFlatness_fx, 896 /*7.0f Q7*/ ) &&
1062 : LT_16( maxEnergyChange_fx, 176 /*22.0f Q3*/ ) ) ) ) )
1063 : {
1064 543009 : IF( disable_ltp == 0 )
1065 : {
1066 542953 : ltp_param[0] = 1;
1067 542953 : move16();
1068 : }
1069 : }
1070 :
1071 : /* hysteresis for stable ltp prediction */
1072 888815 : ltp_on = 0;
1073 888815 : move16();
1074 :
1075 888815 : test();
1076 888815 : test();
1077 888815 : test();
1078 888815 : test();
1079 888815 : test();
1080 :
1081 888815 : exponent = 15;
1082 888815 : move16();
1083 888815 : sqr = Sqrt16( hTcxEnc->tcxltp_on_mem, &exponent );
1084 888815 : move16();
1085 888815 : IF( ( EQ_16( tcxOnly, 1 ) && EQ_16( st->element_mode, IVAS_CPE_MDCT ) && ( GT_16( ( mult( sqr, mult( ( norm_corr_fx ), 29492 ) ) ), shr( 14419, exponent ) ) && ( LT_16( tempFlatness_fx, 768 ) || ( LT_16( tempFlatness_fx, 896 ) && LT_16( maxEnergyChange_fx, 176 ) ) ) ) ) ) // 0.9f Q15, 6.0f Q7, 7.0f Q7, 22.0f Q3
1086 : {
1087 421193 : ltp_on = 1;
1088 421193 : move16();
1089 : }
1090 :
1091 888815 : test();
1092 888815 : IF( EQ_16( tcxOnly, 1 ) && EQ_16( ltp_param[0], 1 ) )
1093 : {
1094 : /* increase ltp counter */
1095 481798 : hTcxEnc->tcxltp_on_mem = s_min( 5, add( hTcxEnc->tcxltp_on_mem, 1 ) );
1096 481798 : move16();
1097 : }
1098 407017 : ELSE IF( EQ_16( ltp_on, 1 ) )
1099 : {
1100 : /* hysteresis takes effect, decrease counter */
1101 46339 : hTcxEnc->tcxltp_on_mem = s_max( 0, sub( hTcxEnc->tcxltp_on_mem, 1 ) );
1102 46339 : move16();
1103 46339 : ltp_param[0] = ltp_on;
1104 46339 : move16();
1105 : }
1106 : ELSE
1107 : {
1108 : /* no ltp in this frame, reset counter */
1109 360678 : hTcxEnc->tcxltp_on_mem = 0;
1110 360678 : move16();
1111 : }
1112 : }
1113 :
1114 : /* Find predicted signal */
1115 888815 : predict_signal( speech_fx, pred_speech_fx, hTcxEnc->tcxltp_pitch_int, hTcxEnc->tcxltp_pitch_fr, st->pit_res_max, L_frame );
1116 :
1117 : /* Find gain */
1118 888815 : tcx_ltp_find_gain_ivas_fx( speech_fx, pred_speech_fx, L_frame, &hTcxEnc->tcxltp_gain, <p_param[2] );
1119 :
1120 888815 : IF( ltp_param[0] )
1121 : {
1122 : /* Total number of bits for LTP */
1123 589292 : IF( add( ltp_param[2], 1 ) ) /* hTcxEnc->tcxltp_gain > 0 */
1124 : {
1125 589220 : *ltp_bits = 12;
1126 589220 : move16();
1127 : }
1128 : ELSE /* hTcxEnc->tcxltp_gain <= 0 -> turn off LTP */
1129 : {
1130 72 : ltp_param[0] = 0;
1131 72 : move16();
1132 : }
1133 : }
1134 :
1135 888815 : IF( !ltp_param[0] )
1136 : {
1137 : /* No LTP -> set everything to zero */
1138 299595 : hTcxEnc->tcxltp_pitch_int = L_frame;
1139 299595 : move16();
1140 299595 : hTcxEnc->tcxltp_pitch_fr = 0;
1141 299595 : move16();
1142 299595 : ltp_param[1] = 0;
1143 299595 : move16();
1144 299595 : set16_fx( pred_speech_fx, 0, L_frame );
1145 299595 : hTcxEnc->tcxltp_gain = 0;
1146 299595 : move16();
1147 299595 : ltp_param[2] = 0;
1148 299595 : move16();
1149 :
1150 299595 : test();
1151 299595 : IF( hTcxEnc->tcxltp || SideInfoOnly )
1152 : {
1153 299595 : *ltp_bits = 1;
1154 299595 : move16();
1155 : }
1156 : ELSE
1157 : {
1158 0 : *ltp_bits = 0;
1159 0 : move16();
1160 : }
1161 : }
1162 :
1163 888815 : si_gain_fx = 0;
1164 888815 : move16();
1165 :
1166 888815 : IF( SideInfoOnly )
1167 : {
1168 426181 : si_gain_fx = hTcxEnc->tcxltp_gain;
1169 426181 : move16();
1170 426181 : hTcxEnc->tcxltp_gain = 0;
1171 426181 : move16();
1172 : }
1173 :
1174 888815 : IF( speech_ltp_fx != NULL )
1175 : {
1176 222129 : test();
1177 222129 : IF( hTcxEnc->tcxltp_gain_past == 0 && hTcxEnc->tcxltp_gain == 0 )
1178 : {
1179 150844 : Copy( speech_fx, speech_ltp_fx, L_subfr );
1180 : }
1181 71285 : ELSE IF( hTcxEnc->tcxltp_gain_past == 0 )
1182 : {
1183 11609 : alpha_fx = 0;
1184 11609 : move16();
1185 :
1186 11609 : step_fx = shl( 2, norm_s( L_subfr ) );
1187 11609 : IF( s_and( L_subfr, sub( L_subfr, 1 ) ) != 0 )
1188 : {
1189 0 : step_fx = mult_r( step_fx, 26214 /*64.f/80.f Q15*/ );
1190 : }
1191 :
1192 754585 : FOR( n = 0; n < L_subfr; n++ )
1193 : {
1194 742976 : speech_ltp_fx[n] = sub_sat( speech_fx[n], mult_r_sat( hTcxEnc->tcxltp_gain, mult_r_sat( alpha_fx, pred_speech_fx[n] ) ) );
1195 742976 : move16();
1196 742976 : alpha_fx = add_sat( alpha_fx, step_fx );
1197 : }
1198 : }
1199 : ELSE
1200 : {
1201 59676 : IF( A_fx == NULL )
1202 : {
1203 59676 : tcx_ltp_get_lpc( speech_fx - L_frame, L_frame, Aest_fx, M );
1204 59676 : A_fx = Aest_fx;
1205 : }
1206 :
1207 59676 : IF( hTcxEnc->tcxltp_gain > 0 )
1208 : {
1209 50666 : predict_signal( speech_fx - M, buf_zir_fx, hTcxEnc->tcxltp_pitch_int, hTcxEnc->tcxltp_pitch_fr, st->pit_res_max, M );
1210 : }
1211 : ELSE
1212 : {
1213 9010 : set16_fx( buf_zir_fx, 0, M );
1214 : }
1215 :
1216 1014492 : FOR( n = 0; n < M; n++ )
1217 : {
1218 954816 : buf_zir_fx[n] = add_sat( sub_sat( speech_ltp_fx[n - M], speech_fx[n - M] ), mult_r( hTcxEnc->tcxltp_gain, buf_zir_fx[n] ) );
1219 954816 : move16();
1220 : }
1221 :
1222 59676 : zir_fx = buf_zir_fx + M;
1223 59676 : set16_fx( zir_fx, 0, L_subfr );
1224 :
1225 59676 : Syn_filt_s( 0, A_fx, M, zir_fx, zir_fx, L_subfr, buf_zir_fx, 0 );
1226 :
1227 59676 : alpha_fx = 0x7FFF; // 1.f Q15
1228 59676 : move16();
1229 59676 : step_fx = shl( 4, norm_s( L_subfr ) );
1230 59676 : IF( s_and( L_subfr, sub( L_subfr, 1 ) ) != 0 )
1231 : {
1232 0 : step_fx = mult_r( step_fx, 26214 /*64.f/80.f Q15*/ );
1233 : }
1234 :
1235 1969308 : FOR( n = L_subfr >> 1; n < L_subfr; n++ )
1236 : {
1237 1909632 : zir_fx[n] = mult_r( zir_fx[n], alpha_fx );
1238 1909632 : move16();
1239 1909632 : alpha_fx = sub( alpha_fx, step_fx );
1240 : }
1241 :
1242 3878940 : FOR( n = 0; n < L_subfr; n++ )
1243 : {
1244 3819264 : speech_ltp_fx[n] = add_sat( sub_sat( speech_fx[n], mult_r_sat( hTcxEnc->tcxltp_gain, pred_speech_fx[n] ) ), zir_fx[n] );
1245 3819264 : move16();
1246 : }
1247 : }
1248 :
1249 222129 : test();
1250 222129 : IF( SideInfoOnly || hTcxEnc->tcxltp_gain == 0 )
1251 : {
1252 71975214 : FOR( n = L_subfr; n < L_frame; n++ )
1253 : {
1254 71815360 : speech_ltp_fx[n] = speech_fx[n];
1255 71815360 : move16();
1256 : }
1257 : }
1258 : ELSE
1259 : {
1260 15033027 : FOR( n = L_subfr; n < L_frame; n++ )
1261 : {
1262 14970752 : speech_ltp_fx[n] = sub_sat( speech_fx[n], mult( hTcxEnc->tcxltp_gain, pred_speech_fx[n] ) );
1263 14970752 : move16();
1264 : }
1265 : }
1266 : }
1267 :
1268 : /* Update */
1269 888815 : hTcxEnc->tcxltp_pitch_int_past = hTcxEnc->tcxltp_pitch_int;
1270 888815 : move16();
1271 888815 : hTcxEnc->tcxltp_pitch_fr_past = hTcxEnc->tcxltp_pitch_fr;
1272 888815 : move16();
1273 888815 : hTcxEnc->tcxltp_gain_past = hTcxEnc->tcxltp_gain;
1274 888815 : move16();
1275 :
1276 888815 : IF( SideInfoOnly )
1277 : {
1278 426181 : hTcxEnc->tcxltp_gain = si_gain_fx;
1279 426181 : move16();
1280 : }
1281 :
1282 888815 : hTcxEnc->tcxltp_norm_corr_past = norm_corr_fx;
1283 888815 : move16();
1284 :
1285 888815 : return;
1286 : }
|