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 <assert.h>
38 : #include <stdint.h>
39 : #include "options.h"
40 : #ifdef DEBUGGING
41 : #include "debug.h"
42 : #endif
43 : #include "prot.h"
44 : #include "rom_com.h"
45 : #include "wmc_auto.h"
46 :
47 : /*-------------------------------------------------------------------
48 : * Local constants
49 : *-------------------------------------------------------------------*/
50 :
51 : #define ALPHA 0.85f
52 :
53 : /*-------------------------------------------------------------------
54 : * tcx_ltp_get_lpc()
55 : *
56 : *
57 : *-------------------------------------------------------------------*/
58 :
59 9771 : static void tcx_ltp_get_lpc(
60 : float *input,
61 : const int16_t length,
62 : float *A,
63 : const int16_t lpcorder )
64 : {
65 : int16_t i, j;
66 : float s, r[TCXLTP_LTP_ORDER + 1];
67 :
68 254046 : for ( i = 0; i <= lpcorder; i++ )
69 : {
70 244275 : s = 0.0;
71 :
72 165696975 : for ( j = 0; j < length - i; j++ )
73 : {
74 165452700 : s += input[j] * input[j + i];
75 : }
76 244275 : r[i] = s;
77 : }
78 :
79 9771 : if ( r[0] < 100.0f )
80 : {
81 0 : r[0] = 100.0f;
82 : }
83 9771 : r[0] *= 1.0001f;
84 :
85 9771 : lev_dur( A, r, lpcorder, NULL );
86 :
87 9771 : return;
88 : }
89 :
90 :
91 : /*-------------------------------------------------------------------
92 : * tcx_ltp_get_zir()
93 : *
94 : *
95 : *-------------------------------------------------------------------*/
96 :
97 9771 : static void tcx_ltp_get_zir(
98 : float *zir,
99 : const int16_t length,
100 : float *synth_ltp,
101 : float *synth,
102 : float *A,
103 : const int16_t lpcorder,
104 : const float gain,
105 : const int16_t pitch_int,
106 : const int16_t pitch_fr,
107 : const int16_t pitres,
108 : const int16_t filtIdx )
109 : {
110 : float buf[TCXLTP_LTP_ORDER], alpha, step;
111 : float *x0, *x1, s;
112 : float *y0, *y1, s2;
113 : const float *w0, *w1, *v0, *v1;
114 : int16_t i, j, k, L;
115 :
116 9771 : x0 = &synth_ltp[-pitch_int];
117 9771 : x1 = x0 - 1;
118 9771 : y0 = synth;
119 9771 : y1 = y0 - 1;
120 :
121 9771 : assert( filtIdx >= 0 );
122 :
123 9771 : w0 = &tcxLtpFilters[filtIdx].filt[pitch_fr];
124 9771 : w1 = &tcxLtpFilters[filtIdx].filt[pitres - pitch_fr];
125 9771 : v0 = &tcxLtpFilters[filtIdx].filt[0];
126 9771 : v1 = &tcxLtpFilters[filtIdx].filt[pitres];
127 9771 : L = tcxLtpFilters[filtIdx].length;
128 :
129 244275 : for ( j = 0; j < lpcorder; j++ )
130 : {
131 234504 : s = 0;
132 234504 : s2 = 0;
133 1239528 : for ( i = 0, k = 0; i < L; i++, k += pitres )
134 : {
135 1005024 : s += w0[k] * x0[i] + w1[k] * x1[-i];
136 1005024 : s2 += v0[k] * y0[i] + v1[k] * y1[-i];
137 : }
138 234504 : s2 *= ALPHA;
139 :
140 234504 : buf[j] = ( synth[j] - gain * s2 ) - ( synth_ltp[j] - gain * s );
141 :
142 :
143 234504 : x0++;
144 234504 : x1++;
145 234504 : y0++;
146 234504 : y1++;
147 : }
148 :
149 9771 : set_f( zir, 0.0f, length );
150 :
151 9771 : syn_filt( A, lpcorder, zir, zir, length, buf, 0 );
152 :
153 9771 : alpha = 1.f;
154 9771 : step = 1.f / (float) ( length / 2 );
155 :
156 851691 : for ( j = length / 2; j < length; j++ )
157 : {
158 841920 : zir[j] *= alpha;
159 841920 : alpha -= step;
160 : }
161 :
162 9771 : return;
163 : }
164 :
165 :
166 : /*-------------------------------------------------------------------
167 : * predict_signal()
168 : *
169 : *
170 : *-------------------------------------------------------------------*/
171 :
172 13488207 : void predict_signal(
173 : const float excI[], /* i : input excitation buffer */
174 : float excO[], /* o : output excitation buffer */
175 : const int16_t T0, /* i : integer pitch lag */
176 : int16_t frac, /* i : fraction of lag */
177 : const int16_t frac_max, /* i : max fraction */
178 : const int16_t L_subfr /* i : subframe size */
179 : )
180 : {
181 : int16_t j;
182 : float s;
183 : const float *x0, *win;
184 :
185 13488207 : x0 = &excI[-T0 - 1];
186 13488207 : frac = -frac;
187 :
188 13488207 : if ( frac < 0 )
189 : {
190 6813459 : frac += frac_max;
191 6813459 : x0--;
192 : }
193 :
194 13488207 : if ( frac_max == 6 )
195 : {
196 2345477 : win = &inter6_2tcx2[frac][0];
197 : }
198 : else
199 : {
200 11142730 : win = &inter4_2tcx2[frac][0];
201 : }
202 :
203 3726372255 : for ( j = 0; j < L_subfr; j++ )
204 : {
205 3712884048 : s = win[1] * x0[1] + win[2] * x0[2];
206 3712884048 : excO[j] = s + win[0] * x0[0] + win[3] * x0[3];
207 3712884048 : x0++;
208 : }
209 :
210 13488207 : return;
211 : }
212 :
213 :
214 : /*-------------------------------------------------------------------
215 : * tcx_ltp_synth_filter()
216 : *
217 : *
218 : *-------------------------------------------------------------------*/
219 :
220 73803139 : static void tcx_ltp_synth_filter(
221 : float *synth_ltp,
222 : float *synth,
223 : const int16_t length,
224 : const int16_t pitch_int,
225 : const int16_t pitch_fr,
226 : const float gain,
227 : const int16_t pitch_res,
228 : const int16_t filtIdx )
229 : {
230 : float *x0, *x1, s;
231 : float *y0, *y1, s2;
232 : const float *v0, *v1;
233 : const float *w0, *w1;
234 : int16_t i, j, k, L;
235 :
236 73803139 : if ( gain > 0.f )
237 : {
238 14213445 : x0 = &synth_ltp[-pitch_int];
239 14213445 : x1 = x0 - 1;
240 14213445 : y0 = synth;
241 14213445 : y1 = y0 - 1;
242 :
243 14213445 : assert( filtIdx >= 0 );
244 :
245 14213445 : w0 = &tcxLtpFilters[filtIdx].filt[pitch_fr];
246 14213445 : w1 = &tcxLtpFilters[filtIdx].filt[pitch_res - pitch_fr];
247 14213445 : v0 = &tcxLtpFilters[filtIdx].filt[0];
248 14213445 : v1 = &tcxLtpFilters[filtIdx].filt[pitch_res];
249 :
250 14213445 : L = tcxLtpFilters[filtIdx].length;
251 :
252 :
253 3632468245 : for ( j = 0; j < length; j++ )
254 : {
255 3618254800 : s = 0;
256 3618254800 : s2 = 0;
257 26381668561 : for ( i = 0, k = 0; i < L; i++, k += pitch_res )
258 : {
259 22763413761 : s += w0[k] * x0[i] + w1[k] * x1[-i];
260 22763413761 : s2 += v0[k] * y0[i] + v1[k] * y1[-i];
261 : }
262 :
263 3618254800 : s2 *= ALPHA;
264 3618254800 : synth_ltp[j] = synth[j] - gain * s2 + gain * s;
265 :
266 3618254800 : x0++;
267 3618254800 : x1++;
268 3618254800 : y0++;
269 3618254800 : y1++;
270 : }
271 : }
272 : else
273 : {
274 59589694 : mvr2r( synth, synth_ltp, length );
275 : }
276 :
277 73803139 : return;
278 : }
279 :
280 :
281 : /*-------------------------------------------------------------------
282 : * tcx_ltp_synth_filter_zir()
283 : *
284 : *
285 : *-------------------------------------------------------------------*/
286 :
287 9771 : static void tcx_ltp_synth_filter_zir(
288 : float *synth_ltp,
289 : float *synth,
290 : const int16_t length,
291 : const int16_t pitch_int,
292 : const int16_t pitch_fr,
293 : const float gain,
294 : const int16_t pitch_res,
295 : float *zir,
296 : const int16_t filtIdx )
297 : {
298 : float *x0, *x1, s;
299 : float *y0, *y1, s2;
300 : const float *v0, *v1;
301 : const float *w0, *w1;
302 : int16_t i, j, k, L;
303 :
304 9771 : x0 = &synth_ltp[-pitch_int];
305 9771 : x1 = x0 - 1;
306 9771 : y0 = synth;
307 9771 : y1 = y0 - 1;
308 :
309 9771 : assert( filtIdx >= 0 );
310 :
311 9771 : w0 = &tcxLtpFilters[filtIdx].filt[pitch_fr];
312 9771 : w1 = &tcxLtpFilters[filtIdx].filt[pitch_res - pitch_fr];
313 9771 : v0 = &tcxLtpFilters[filtIdx].filt[0];
314 9771 : v1 = &tcxLtpFilters[filtIdx].filt[pitch_res];
315 9771 : L = tcxLtpFilters[filtIdx].length;
316 :
317 1693611 : for ( j = 0; j < length; j++ )
318 : {
319 1683840 : s = 0;
320 1683840 : s2 = 0;
321 :
322 9624480 : for ( i = 0, k = 0; i < L; i++, k += pitch_res )
323 : {
324 7940640 : s += w0[k] * x0[i] + w1[k] * x1[-i];
325 7940640 : s2 += v0[k] * y0[i] + v1[k] * y1[-i];
326 : }
327 :
328 1683840 : s2 *= ALPHA;
329 :
330 1683840 : synth_ltp[j] = ( synth[j] - gain * s2 + gain * s ) - zir[j];
331 :
332 1683840 : x0++;
333 1683840 : x1++;
334 1683840 : y0++;
335 1683840 : y1++;
336 : }
337 :
338 9771 : return;
339 : }
340 :
341 :
342 : /*-------------------------------------------------------------------
343 : * tcx_ltp_synth_filter_fadein()
344 : *
345 : *
346 : *-------------------------------------------------------------------*/
347 :
348 2698 : static void tcx_ltp_synth_filter_fadein(
349 : float *synth_ltp,
350 : float *synth,
351 : const int16_t length,
352 : const int16_t pitch_int,
353 : const int16_t pitch_fr,
354 : const float gain,
355 : const int16_t pitch_res,
356 : const int16_t filtIdx )
357 : {
358 : float *x0, *x1, s;
359 : float *y0, *y1, s2;
360 : const float *v0, *v1;
361 : const float *w0, *w1;
362 : int16_t i, j, k, L;
363 : float alpha, step;
364 :
365 2698 : if ( gain > 0.f )
366 : {
367 2698 : x0 = &synth_ltp[-pitch_int];
368 2698 : x1 = x0 - 1;
369 2698 : y0 = synth;
370 2698 : y1 = y0 - 1;
371 :
372 2698 : assert( filtIdx >= 0 );
373 :
374 2698 : w0 = &tcxLtpFilters[filtIdx].filt[pitch_fr];
375 2698 : w1 = &tcxLtpFilters[filtIdx].filt[pitch_res - pitch_fr];
376 2698 : v0 = &tcxLtpFilters[filtIdx].filt[0];
377 2698 : v1 = &tcxLtpFilters[filtIdx].filt[pitch_res];
378 2698 : L = tcxLtpFilters[filtIdx].length;
379 :
380 2698 : alpha = 0.f;
381 2698 : step = 1.f / (float) ( length );
382 :
383 :
384 449578 : for ( j = 0; j < length; j++ )
385 : {
386 446880 : s = 0;
387 446880 : s2 = 0;
388 :
389 2576160 : for ( i = 0, k = 0; i < L; i++, k += pitch_res )
390 : {
391 2129280 : s += w0[k] * x0[i] + w1[k] * x1[-i];
392 2129280 : s2 += v0[k] * y0[i] + v1[k] * y1[-i];
393 : }
394 :
395 446880 : s2 *= ALPHA;
396 :
397 446880 : synth_ltp[j] = synth[j] - alpha * gain * s2 + alpha * gain * s;
398 :
399 446880 : alpha += step;
400 :
401 446880 : x0++;
402 446880 : x1++;
403 446880 : y0++;
404 446880 : y1++;
405 : }
406 : }
407 : else
408 : {
409 0 : mvr2r( synth, synth_ltp, length );
410 : }
411 :
412 2698 : return;
413 : }
414 :
415 :
416 : /*-------------------------------------------------------------------
417 : * tcx_ltp_synth_filter_fadeout()
418 : *
419 : *
420 : *-------------------------------------------------------------------*/
421 :
422 2668 : static void tcx_ltp_synth_filter_fadeout(
423 : float *synth_ltp,
424 : float *synth,
425 : const int16_t length,
426 : const int16_t pitch_int,
427 : const int16_t pitch_fr,
428 : const float gain,
429 : const int16_t pitch_res,
430 : const int16_t filtIdx )
431 : {
432 : float *x0, *x1, s;
433 : float *y0, *y1, s2;
434 : const float *v0, *v1;
435 : const float *w0, *w1;
436 : int16_t i, j, k, L;
437 : float alpha, step;
438 :
439 2668 : if ( gain > 0.f )
440 : {
441 2668 : x0 = &synth_ltp[-pitch_int];
442 2668 : x1 = x0 - 1;
443 2668 : y0 = synth;
444 2668 : y1 = y0 - 1;
445 :
446 2668 : assert( filtIdx >= 0 );
447 :
448 2668 : w0 = &tcxLtpFilters[filtIdx].filt[pitch_fr];
449 2668 : w1 = &tcxLtpFilters[filtIdx].filt[pitch_res - pitch_fr];
450 2668 : v0 = &tcxLtpFilters[filtIdx].filt[0];
451 2668 : v1 = &tcxLtpFilters[filtIdx].filt[pitch_res];
452 2668 : L = tcxLtpFilters[filtIdx].length;
453 :
454 2668 : alpha = 1.f;
455 2668 : step = 1.f / (float) ( length );
456 :
457 445108 : for ( j = 0; j < length; j++ )
458 : {
459 442440 : s = 0;
460 442440 : s2 = 0;
461 :
462 2554040 : for ( i = 0, k = 0; i < L; i++, k += pitch_res )
463 : {
464 2111600 : s += w0[k] * x0[i] + w1[k] * x1[-i];
465 2111600 : s2 += v0[k] * y0[i] + v1[k] * y1[-i];
466 : }
467 :
468 442440 : s2 *= ALPHA;
469 442440 : synth_ltp[j] = synth[j] - alpha * gain * s2 + alpha * gain * s;
470 442440 : alpha -= step;
471 :
472 442440 : x0++;
473 442440 : x1++;
474 442440 : y0++;
475 442440 : y1++;
476 : }
477 : }
478 : else
479 : {
480 0 : mvr2r( synth, synth_ltp, length );
481 : }
482 :
483 2668 : return;
484 : }
485 :
486 :
487 : /*-------------------------------------------------------------------
488 : * tcx_ltp_decode_params()
489 : *
490 : *
491 : *-------------------------------------------------------------------*/
492 :
493 27406680 : int16_t tcx_ltp_decode_params(
494 : int16_t *ltp_param,
495 : int16_t *pitch_int,
496 : int16_t *pitch_fr,
497 : float *gain,
498 : const int16_t pitmin,
499 : const int16_t pitfr1,
500 : const int16_t pitfr2,
501 : const int16_t pitmax,
502 : const int16_t pitres )
503 : {
504 27406680 : int16_t gainbits = 2;
505 :
506 : /* Decode Pitch and Gain */
507 27406680 : if ( ( ltp_param ) && ( ltp_param[0] ) )
508 : {
509 16346640 : if ( ltp_param[1] < ( ( pitfr2 - pitmin ) * pitres ) )
510 : {
511 11729680 : *pitch_int = pitmin + ( ltp_param[1] / pitres );
512 11729680 : *pitch_fr = ltp_param[1] - ( *pitch_int - pitmin ) * pitres;
513 : }
514 4616960 : else if ( ltp_param[1] < ( ( pitfr2 - pitmin ) * pitres + ( pitfr1 - pitfr2 ) * ( pitres >> 1 ) ) )
515 : {
516 2235492 : *pitch_int = pitfr2 + ( ( ltp_param[1] - ( pitfr2 - pitmin ) * pitres ) / ( pitres >> 1 ) );
517 2235492 : *pitch_fr = ( ltp_param[1] - ( pitfr2 - pitmin ) * pitres ) - ( *pitch_int - pitfr2 ) * ( pitres >> 1 );
518 2235492 : *pitch_fr = *pitch_fr << 1; /* was *= (pitres>>1); */
519 : }
520 : else
521 : {
522 2381468 : *pitch_int = ltp_param[1] + pitfr1 - ( ( pitfr2 - pitmin ) * pitres ) - ( ( pitfr1 - pitfr2 ) * ( pitres >> 1 ) );
523 2381468 : *pitch_fr = 0;
524 : }
525 16346640 : *gain = (float) ( ltp_param[2] + 1 ) * 0.625f / (float) ( 1 << gainbits );
526 16346640 : if ( *pitch_int < PIT_MIN_SHORTER )
527 : {
528 : /*pitch out of range due to bit error */
529 0 : *pitch_int = PIT_MIN_SHORTER;
530 0 : return 1;
531 : }
532 16346640 : if ( *pitch_int > PIT_MAX_MAX )
533 : {
534 : /*pitch out of range due to bit error */
535 0 : *pitch_int = PIT_MAX_MAX;
536 0 : return 1;
537 : }
538 : }
539 : else
540 : {
541 11060040 : *pitch_int = pitmax;
542 11060040 : *pitch_fr = 0;
543 11060040 : *gain = 0.0f;
544 : }
545 :
546 27406680 : return 0;
547 : }
548 :
549 : /*-------------------------------------------------------------------
550 : *tcx_ltp_synth_filter_10()
551 : *
552 : *
553 : ---------------------------------------------------------------------*/
554 974300 : static void tcx_ltp_synth_filter_10(
555 : float *out,
556 : float *in,
557 : const int16_t length,
558 : const int16_t pitch_int,
559 : const int16_t pitch_fr,
560 : const float gain,
561 : const int16_t pitch_res,
562 : const int16_t filtIdx )
563 : {
564 : float *x0, *x1, s;
565 : float *y0, *y1, s2;
566 : const float *v0, *v1;
567 : const float *w0, *w1;
568 : int16_t i, j, k, L;
569 : float curr_gain, gain_step;
570 :
571 974300 : x0 = &out[-pitch_int];
572 974300 : x1 = x0 - 1;
573 974300 : y0 = in;
574 974300 : y1 = y0 - 1;
575 :
576 974300 : assert( filtIdx >= 0 );
577 :
578 974300 : w0 = &tcxLtpFilters[filtIdx].filt[pitch_fr];
579 974300 : w1 = &tcxLtpFilters[filtIdx].filt[pitch_res - pitch_fr];
580 974300 : v0 = &tcxLtpFilters[filtIdx].filt[0];
581 974300 : v1 = &tcxLtpFilters[filtIdx].filt[pitch_res];
582 974300 : L = tcxLtpFilters[filtIdx].length;
583 :
584 974300 : curr_gain = gain;
585 974300 : gain_step = -gain / length;
586 :
587 172510700 : for ( j = 0; j < length; j++ )
588 : {
589 171536400 : s = 0;
590 171536400 : s2 = 0;
591 :
592 1230494800 : for ( i = 0, k = 0; i < L; i++, k += pitch_res )
593 : {
594 1058958400 : s += w0[k] * x0[i] + w1[k] * x1[-i];
595 1058958400 : s2 += v0[k] * y0[i] + v1[k] * y1[-i];
596 : }
597 :
598 171536400 : out[j] = in[j] - curr_gain * s2 * ALPHA + curr_gain * s;
599 :
600 171536400 : x0++;
601 171536400 : x1++;
602 171536400 : y0++;
603 171536400 : y1++;
604 :
605 171536400 : curr_gain += gain_step;
606 : }
607 :
608 974300 : return;
609 : }
610 :
611 :
612 : /*-------------------------------------------------------------------
613 : *tcx_ltp_synth_filter_01()
614 : *
615 : *
616 : ---------------------------------------------------------------------*/
617 :
618 1032890 : static void tcx_ltp_synth_filter_01(
619 : float *out,
620 : float *in,
621 : const int16_t length,
622 : const int16_t pitch_int,
623 : const int16_t pitch_fr,
624 : const float gain,
625 : const int16_t pitch_res,
626 : const int16_t filtIdx )
627 : {
628 : float *x0, *x1, s;
629 : float *y0, *y1, s2;
630 : const float *v0, *v1;
631 : const float *w0, *w1;
632 : int16_t i, j, k, L;
633 : float curr_gain, gain_step;
634 :
635 1032890 : x0 = &out[-pitch_int];
636 1032890 : x1 = x0 - 1;
637 1032890 : y0 = in;
638 1032890 : y1 = y0 - 1;
639 :
640 1032890 : assert( filtIdx >= 0 );
641 :
642 1032890 : w0 = &tcxLtpFilters[filtIdx].filt[pitch_fr];
643 1032890 : w1 = &tcxLtpFilters[filtIdx].filt[pitch_res - pitch_fr];
644 1032890 : v0 = &tcxLtpFilters[filtIdx].filt[0];
645 1032890 : v1 = &tcxLtpFilters[filtIdx].filt[pitch_res];
646 1032890 : L = tcxLtpFilters[filtIdx].length;
647 :
648 1032890 : curr_gain = 0.0f;
649 1032890 : gain_step = gain / length;
650 :
651 182629370 : for ( j = 0; j < length; j++ )
652 : {
653 181596480 : s = 0;
654 181596480 : s2 = 0;
655 :
656 1302456960 : for ( i = 0, k = 0; i < L; i++, k += pitch_res )
657 : {
658 1120860480 : s += w0[k] * x0[i] + w1[k] * x1[-i];
659 1120860480 : s2 += v0[k] * y0[i] + v1[k] * y1[-i];
660 : }
661 :
662 181596480 : out[j] = in[j] - curr_gain * s2 * ALPHA + curr_gain * s;
663 :
664 181596480 : x0++;
665 181596480 : x1++;
666 181596480 : y0++;
667 181596480 : y1++;
668 :
669 181596480 : curr_gain += gain_step;
670 : }
671 :
672 1032890 : return;
673 : }
674 :
675 : #define MAX_TCX_LTP_FILTER_LEN 8
676 : #define MAX_TRANSITION_LEN 240 /* L_FRAME_48K / 4 */
677 :
678 : /*-------------------------------------------------------------------
679 : *tcx_ltp_synth_filter_11_unequal_pitch()
680 : *
681 : * blend between two filters by means of OAO
682 : * filter the input signal at the initial subinterval with
683 : * the first filter unit according to parameters associated to
684 : * the preceding update interval with scaling from non-zero gain towards 0
685 : * followed by the second filter unit according to parameters associated to
686 : * the current update interval with scaling from 0 towards non-zero gain
687 : ---------------------------------------------------------------------*/
688 :
689 4788174 : static void tcx_ltp_synth_filter_11_unequal_pitch(
690 : float *out,
691 : float *in,
692 : const int16_t length,
693 : const int16_t cur_pitch_int,
694 : const int16_t cur_pitch_fr,
695 : const float cur_gain,
696 : const int16_t pitch_res,
697 : const int16_t filtIdx,
698 : const int16_t prev_pitch_int,
699 : const int16_t prev_pitch_fr,
700 : const float prev_gain,
701 : const int16_t prev_pitch_res,
702 : const int16_t prev_filtIdx )
703 : {
704 : float *x0, *x1, s;
705 : float *y0, *y1, s2;
706 : float *l0, *l1, s3;
707 : float *m0, *m1, s4;
708 : const float *v0, *v1;
709 : const float *w0, *w1;
710 : const float *p0, *p1;
711 : const float *q0, *q1;
712 : int16_t i, j, k, L;
713 : int16_t prev_L;
714 : float temp_buf[MAX_TRANSITION_LEN + 2 * MAX_TCX_LTP_FILTER_LEN];
715 : float *temp_ptr;
716 : float gain, gain_step;
717 :
718 4788174 : x0 = &out[-prev_pitch_int];
719 4788174 : x1 = x0 - 1;
720 4788174 : y0 = in;
721 4788174 : y1 = y0 - 1;
722 :
723 4788174 : assert( filtIdx >= 0 && prev_filtIdx >= 0 );
724 :
725 4788174 : w0 = &tcxLtpFilters[prev_filtIdx].filt[prev_pitch_fr];
726 4788174 : w1 = &tcxLtpFilters[prev_filtIdx].filt[prev_pitch_res - prev_pitch_fr];
727 4788174 : v0 = &tcxLtpFilters[prev_filtIdx].filt[0];
728 4788174 : v1 = &tcxLtpFilters[prev_filtIdx].filt[prev_pitch_res];
729 :
730 4788174 : prev_L = tcxLtpFilters[prev_filtIdx].length;
731 :
732 4788174 : p0 = &tcxLtpFilters[filtIdx].filt[cur_pitch_fr];
733 4788174 : p1 = &tcxLtpFilters[filtIdx].filt[pitch_res - cur_pitch_fr];
734 4788174 : q0 = &tcxLtpFilters[filtIdx].filt[0];
735 4788174 : q1 = &tcxLtpFilters[filtIdx].filt[pitch_res];
736 :
737 4788174 : L = tcxLtpFilters[filtIdx].length;
738 :
739 : /* 1. decreasing gain filter. The first filter unit with the parameters associated to the previous interval and scaling towards 0 */
740 4788174 : gain = prev_gain;
741 4788174 : gain_step = -prev_gain / length;
742 :
743 846494734 : for ( j = 0; j < length; j++ )
744 : {
745 841706560 : s = 0;
746 841706560 : s2 = 0;
747 :
748 6142274480 : for ( i = 0, k = 0; i < prev_L; i++, k += prev_pitch_res )
749 : {
750 5300567920 : s += w0[k] * x0[i] + w1[k] * x1[-i];
751 5300567920 : s2 += v0[k] * y0[i] + v1[k] * y1[-i];
752 : }
753 :
754 841706560 : out[j] = in[j] - gain * s2 * ALPHA + gain * s;
755 :
756 841706560 : x0++;
757 841706560 : x1++;
758 841706560 : y0++;
759 841706560 : y1++;
760 :
761 841706560 : gain += gain_step;
762 : }
763 :
764 4788174 : mvr2r( out - L, temp_buf, length + L );
765 4788174 : mvr2r( in + length, temp_buf + length + L, L );
766 4788174 : temp_ptr = &temp_buf[0] + L;
767 :
768 4788174 : m0 = temp_ptr;
769 4788174 : m1 = temp_ptr - 1;
770 4788174 : l0 = &out[-cur_pitch_int];
771 4788174 : l1 = l0 - 1;
772 :
773 : /* 2. increasing gain filter. The second filter unit with the parameters associated to the current interval and scaling from 0 towards current gain */
774 4788174 : gain = 0.0f;
775 4788174 : gain_step = cur_gain / length;
776 :
777 846494734 : for ( j = 0; j < length; j++ )
778 : {
779 841706560 : s3 = 0;
780 841706560 : s4 = 0;
781 :
782 6142283520 : for ( i = 0, k = 0; i < L; i++, k += pitch_res )
783 : {
784 5300576960 : s3 += p0[k] * l0[i] + p1[k] * l1[-i];
785 5300576960 : s4 += q0[k] * m0[i] + q1[k] * m1[-i];
786 : }
787 :
788 841706560 : out[j] = *( temp_ptr + j ) - gain * s4 * ALPHA + gain * s3;
789 :
790 841706560 : l0++;
791 841706560 : l1++;
792 841706560 : m0++;
793 841706560 : m1++;
794 :
795 841706560 : gain += gain_step;
796 : }
797 :
798 4788174 : return;
799 : }
800 :
801 :
802 : /*-------------------------------------------------------------------
803 : * tcx_ltp_post()
804 : *
805 : *
806 : *-------------------------------------------------------------------*/
807 :
808 36467403 : void tcx_ltp_post(
809 : Decoder_State *st,
810 : TCX_LTP_DEC_HANDLE hTcxLtpDec,
811 : const int16_t core,
812 : const int16_t output_frame,
813 : const int16_t delay,
814 : float sig[],
815 : const float tcx_buf[] )
816 : {
817 : int16_t tmp, L_transition, lpcorder, filtIdx;
818 : int16_t bfi, L_frame_core, SideInfoOnly;
819 : float gain, gain2;
820 : float zir[L_FRAME_PLUS / 4], A[TCXLTP_LTP_ORDER + 1];
821 : float buf_in[TCXLTP_MAX_DELAY + L_FRAME48k + TCXLTP_MAX_DELAY], buf_out[2 * L_FRAME48k];
822 : float *sig_in, *sig_out;
823 : int16_t pitch_int, pitch_fr;
824 : int16_t tcx_buf_len;
825 : int32_t total_brate;
826 :
827 36467403 : total_brate = ( st->element_mode == IVAS_CPE_MDCT ? st->bits_frame_nominal * FRAMES_PER_SEC : st->total_brate );
828 36467403 : filtIdx = 0; /* just to avoid compilation warnings */
829 36467403 : tcx_buf_len = NS2SA( st->output_Fs, TCXLTP_DELAY_NS );
830 36467403 : SideInfoOnly = 0;
831 :
832 36467403 : if ( total_brate >= HQ_96k )
833 : {
834 14346475 : SideInfoOnly = 1;
835 : }
836 :
837 36467403 : L_frame_core = st->L_frame;
838 36467403 : if ( st->element_mode == IVAS_CPE_MDCT )
839 : {
840 25643348 : L_frame_core = L_FRAME;
841 : }
842 :
843 36467403 : if ( core == ACELP_CORE )
844 : {
845 4615281 : bfi = 0;
846 4615281 : pitch_int = 0;
847 4615281 : pitch_fr = 0;
848 4615281 : gain = 0.0f;
849 :
850 4615281 : L_frame_core = st->L_frame_past;
851 : }
852 : else
853 : {
854 31852122 : bfi = st->bfi;
855 31852122 : pitch_int = hTcxLtpDec->tcxltp_pitch_int;
856 31852122 : pitch_fr = hTcxLtpDec->tcxltp_pitch_fr;
857 31852122 : gain = hTcxLtpDec->tcxltp_gain;
858 : }
859 :
860 : /******** Init ********/
861 :
862 : /* Parameters */
863 36467403 : L_transition = output_frame / 4;
864 36467403 : lpcorder = TCXLTP_LTP_ORDER;
865 :
866 :
867 : /* Input buffer */
868 36467403 : sig_in = buf_in + tcx_buf_len;
869 36467403 : mvr2r( hTcxLtpDec->tcxltp_mem_in, buf_in, tcx_buf_len );
870 36467403 : mvr2r( sig, buf_in + tcx_buf_len, output_frame );
871 36467403 : if ( core > ACELP_CORE )
872 : {
873 31852122 : mvr2r( tcx_buf, sig_in + output_frame, tcx_buf_len );
874 : }
875 36467403 : mvr2r( sig + output_frame - tcx_buf_len, hTcxLtpDec->tcxltp_mem_in, tcx_buf_len );
876 :
877 : /* Output buffer */
878 36467403 : sig_out = buf_out + output_frame;
879 36467403 : mvr2r( hTcxLtpDec->tcxltp_mem_out, buf_out, output_frame );
880 :
881 : /* TCX-LTP parameters: integer pitch, fractional pitch, gain */
882 :
883 36467403 : if ( !( SideInfoOnly || hTcxLtpDec->tcxltp ) || core == ACELP_CORE )
884 : {
885 : /* No LTP */
886 13704429 : pitch_int = 0;
887 13704429 : pitch_fr = 0;
888 13704429 : gain = 0.f;
889 : }
890 22762974 : else if ( !bfi )
891 : {
892 : /* LTP and good frame */
893 21626597 : if ( output_frame != L_frame_core )
894 : {
895 20722530 : tmp = pitch_int * st->pit_res_max + pitch_fr;
896 20722530 : tmp = ( tmp * output_frame + L_frame_core / 2 ) / L_frame_core;
897 20722530 : pitch_int = tmp / st->pit_res_max;
898 20722530 : pitch_fr = tmp % st->pit_res_max;
899 : }
900 :
901 21626597 : if ( st->element_mode == EVS_MONO ) /* hard tunings for EVS_MONO, HQ_48k is TCX only */
902 : {
903 33121 : if ( total_brate == HQ_48k && L_frame_core == L_FRAME16k )
904 : {
905 1750 : gain *= 0.32f;
906 : }
907 31371 : else if ( total_brate == HQ_48k && L_frame_core == 512 )
908 : {
909 4250 : gain *= 0.40f;
910 : }
911 : else
912 : {
913 27121 : gain *= 0.64f;
914 : }
915 : }
916 21593476 : else if ( ( st->element_mode > IVAS_SCE ) && ( total_brate >= IVAS_96k ) )
917 : {
918 12840028 : gain *= 0.40f;
919 : }
920 : else
921 : {
922 8753448 : gain *= 0.64f;
923 : }
924 : }
925 : else
926 : {
927 : /* PLC: [TCX: Fade-out]
928 : * PLC: LTP and bad frame (concealment) */
929 1136377 : if ( st->pit_res_max == st->pit_res_max_past ) /* ensure consistent core SR to previous frame; otherwise, set gain to 0 */
930 : {
931 1136377 : pitch_int = hTcxLtpDec->tcxltp_pitch_int_post_prev;
932 1136377 : pitch_fr = hTcxLtpDec->tcxltp_pitch_fr_post_prev;
933 1136377 : gain = hTcxLtpDec->tcxltp_gain_post_prev * st->hTcxDec->damping;
934 : }
935 : else
936 : {
937 0 : gain = 0.f;
938 : }
939 : }
940 :
941 36467403 : if ( SideInfoOnly )
942 : {
943 14346475 : gain = 0.f;
944 14346475 : if ( bfi )
945 : {
946 692962 : hTcxLtpDec->tcxltp_gain_post_prev = 0.f;
947 : }
948 : }
949 36467403 : gain2 = gain;
950 :
951 36467403 : if ( L_frame_core == L_FRAME )
952 : {
953 27911849 : switch ( output_frame )
954 : {
955 8548 : case L_FRAME8k:
956 8548 : filtIdx = 0;
957 8548 : break;
958 5795603 : case L_FRAME16k:
959 5795603 : filtIdx = 1;
960 5795603 : break;
961 7579263 : case L_FRAME32k:
962 7579263 : filtIdx = 2;
963 7579263 : break;
964 14528435 : case L_FRAME48k:
965 14528435 : filtIdx = 3;
966 14528435 : break;
967 0 : default:
968 0 : assert( 0 );
969 : break;
970 : }
971 : }
972 8555554 : else if ( L_frame_core == L_FRAME16k )
973 : {
974 5978315 : switch ( output_frame )
975 : {
976 910 : case L_FRAME8k:
977 910 : filtIdx = 4;
978 910 : break;
979 1771489 : case L_FRAME16k:
980 1771489 : filtIdx = 5;
981 1771489 : break;
982 1578305 : case L_FRAME32k:
983 1578305 : filtIdx = 6;
984 1578305 : break;
985 2627611 : case L_FRAME48k:
986 2627611 : filtIdx = 7;
987 2627611 : break;
988 0 : default:
989 0 : assert( 0 );
990 : break;
991 : }
992 : }
993 2577239 : else if ( L_frame_core == 512 )
994 : {
995 496981 : switch ( output_frame )
996 : {
997 0 : case L_FRAME8k:
998 0 : filtIdx = 8;
999 0 : break;
1000 3168 : case L_FRAME16k:
1001 3168 : filtIdx = 9;
1002 3168 : break;
1003 186772 : case L_FRAME32k:
1004 186772 : filtIdx = 10;
1005 186772 : break;
1006 307041 : case L_FRAME48k:
1007 307041 : filtIdx = 11;
1008 307041 : break;
1009 0 : default:
1010 0 : assert( 0 );
1011 : break;
1012 : }
1013 : }
1014 : else
1015 : {
1016 2080258 : filtIdx = -1;
1017 : }
1018 :
1019 :
1020 : /******** Previous-frame part ********/
1021 36467403 : tcx_ltp_synth_filter( sig_out, sig_in, delay, hTcxLtpDec->tcxltp_pitch_int_post_prev, hTcxLtpDec->tcxltp_pitch_fr_post_prev, hTcxLtpDec->tcxltp_gain_post_prev, st->pit_res_max_past, hTcxLtpDec->tcxltp_filt_idx_prev );
1022 :
1023 : /******** Transition part - initial subinterval ********/
1024 :
1025 36467403 : if ( st->element_mode != EVS_MONO )
1026 : {
1027 36347219 : if ( gain == 0.f && hTcxLtpDec->tcxltp_gain_post_prev == 0.f )
1028 : {
1029 : /* The filtering is deactivated, just copy input to the output */
1030 28687409 : mvr2r( sig_in + delay, sig_out + delay, L_transition );
1031 : }
1032 7659810 : else if ( gain == 0.f && hTcxLtpDec->tcxltp_gain_post_prev != 0.f )
1033 : {
1034 : /* Filtering with the first filter unit */
1035 974300 : tcx_ltp_synth_filter_10( sig_out + delay, sig_in + delay, L_transition, hTcxLtpDec->tcxltp_pitch_int_post_prev, hTcxLtpDec->tcxltp_pitch_fr_post_prev, hTcxLtpDec->tcxltp_gain_post_prev, st->pit_res_max_past, hTcxLtpDec->tcxltp_filt_idx_prev );
1036 : }
1037 6685510 : else if ( gain != 0.f && hTcxLtpDec->tcxltp_gain_post_prev == 0.f )
1038 : {
1039 : /* Filtering with the second filter unit */
1040 1032890 : tcx_ltp_synth_filter_01( sig_out + delay, sig_in + delay, L_transition, pitch_int, pitch_fr, gain, st->pit_res_max, filtIdx );
1041 : }
1042 5652620 : else if ( gain == hTcxLtpDec->tcxltp_gain_post_prev && pitch_int == hTcxLtpDec->tcxltp_pitch_int_post_prev && pitch_fr == hTcxLtpDec->tcxltp_pitch_fr_post_prev && st->pit_res_max == st->pit_res_max_past && filtIdx == hTcxLtpDec->tcxltp_filt_idx_prev )
1043 : {
1044 864446 : tcx_ltp_synth_filter( sig_out + delay, sig_in + delay, L_transition, pitch_int, pitch_fr, gain, st->pit_res_max, filtIdx );
1045 : }
1046 : else
1047 : {
1048 : /* Filtering with the first filter unit, followed by the filtering with the second filter unit */
1049 4788174 : tcx_ltp_synth_filter_11_unequal_pitch( sig_out + delay, sig_in + delay, L_transition, pitch_int, pitch_fr, gain, st->pit_res_max, filtIdx,
1050 4788174 : hTcxLtpDec->tcxltp_pitch_int_post_prev, hTcxLtpDec->tcxltp_pitch_fr_post_prev, hTcxLtpDec->tcxltp_gain_post_prev, st->pit_res_max_past, hTcxLtpDec->tcxltp_filt_idx_prev );
1051 : }
1052 : }
1053 : else
1054 : {
1055 120184 : if ( gain == 0.f && hTcxLtpDec->tcxltp_gain_post_prev == 0.f )
1056 : {
1057 101160 : mvr2r( sig_in + delay, sig_out + delay, L_transition );
1058 : }
1059 19024 : else if ( hTcxLtpDec->tcxltp_gain_post_prev == 0.f )
1060 : {
1061 2698 : tcx_ltp_synth_filter_fadein( sig_out + delay, sig_in + delay, L_transition, pitch_int, pitch_fr, gain, st->pit_res_max, filtIdx );
1062 : }
1063 16326 : else if ( gain == 0.f )
1064 : {
1065 2668 : tcx_ltp_synth_filter_fadeout( sig_out + delay, sig_in + delay, L_transition, hTcxLtpDec->tcxltp_pitch_int_post_prev, hTcxLtpDec->tcxltp_pitch_fr_post_prev, hTcxLtpDec->tcxltp_gain_post_prev, st->pit_res_max_past, hTcxLtpDec->tcxltp_filt_idx_prev );
1066 : }
1067 13658 : else if ( gain == hTcxLtpDec->tcxltp_gain_post_prev && pitch_int == hTcxLtpDec->tcxltp_pitch_int_post_prev && pitch_fr == hTcxLtpDec->tcxltp_pitch_fr_post_prev )
1068 : {
1069 3887 : tcx_ltp_synth_filter( sig_out + delay, sig_in + delay, L_transition, pitch_int, pitch_fr, gain, st->pit_res_max, filtIdx );
1070 : }
1071 : else
1072 : {
1073 : {
1074 9771 : tcx_ltp_get_lpc( sig_out + delay - output_frame, output_frame, A, lpcorder );
1075 9771 : tcx_ltp_get_zir( zir, L_transition, sig_out + delay - lpcorder, sig_in + delay - lpcorder, A, lpcorder, gain, pitch_int, pitch_fr, st->pit_res_max, filtIdx );
1076 9771 : tcx_ltp_synth_filter_zir( sig_out + delay, sig_in + delay, L_transition, pitch_int, pitch_fr, gain, st->pit_res_max, zir, filtIdx );
1077 : }
1078 : }
1079 : }
1080 :
1081 : /******** Current-frame part - subsequent subinterval, filtered with the third filter unit ********/
1082 36467403 : tcx_ltp_synth_filter( sig_out + ( delay + L_transition ), sig_in + ( delay + L_transition ), output_frame - ( delay + L_transition ), pitch_int, pitch_fr, gain, st->pit_res_max, filtIdx );
1083 :
1084 : /******** Output ********/
1085 :
1086 : /* copy to output */
1087 36467403 : mvr2r( sig_out, sig, output_frame );
1088 :
1089 : /* Update */
1090 36467403 : hTcxLtpDec->tcxltp_pitch_int_post_prev = pitch_int;
1091 36467403 : hTcxLtpDec->tcxltp_pitch_fr_post_prev = pitch_fr;
1092 36467403 : hTcxLtpDec->tcxltp_gain_post_prev = gain2;
1093 36467403 : hTcxLtpDec->tcxltp_filt_idx_prev = filtIdx;
1094 36467403 : st->pit_res_max_past = st->pit_res_max;
1095 36467403 : mvr2r( sig_out, hTcxLtpDec->tcxltp_mem_out, output_frame );
1096 :
1097 36467403 : return;
1098 : }
|