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 3038 : 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 78988 : for ( i = 0; i <= lpcorder; i++ )
69 : {
70 75950 : s = 0.0;
71 :
72 56816550 : for ( j = 0; j < length - i; j++ )
73 : {
74 56740600 : s += input[j] * input[j + i];
75 : }
76 75950 : r[i] = s;
77 : }
78 :
79 3038 : if ( r[0] < 100.0f )
80 : {
81 0 : r[0] = 100.0f;
82 : }
83 3038 : r[0] *= 1.0001f;
84 :
85 3038 : lev_dur( A, r, lpcorder, NULL );
86 :
87 3038 : return;
88 : }
89 :
90 :
91 : /*-------------------------------------------------------------------
92 : * tcx_ltp_get_zir()
93 : *
94 : *
95 : *-------------------------------------------------------------------*/
96 :
97 3038 : 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 3038 : x0 = &synth_ltp[-pitch_int];
117 3038 : x1 = x0 - 1;
118 3038 : y0 = synth;
119 3038 : y1 = y0 - 1;
120 :
121 3038 : assert( filtIdx >= 0 );
122 :
123 3038 : w0 = &tcxLtpFilters[filtIdx].filt[pitch_fr];
124 3038 : w1 = &tcxLtpFilters[filtIdx].filt[pitres - pitch_fr];
125 3038 : v0 = &tcxLtpFilters[filtIdx].filt[0];
126 3038 : v1 = &tcxLtpFilters[filtIdx].filt[pitres];
127 3038 : L = tcxLtpFilters[filtIdx].length;
128 :
129 75950 : for ( j = 0; j < lpcorder; j++ )
130 : {
131 72912 : s = 0;
132 72912 : s2 = 0;
133 427464 : for ( i = 0, k = 0; i < L; i++, k += pitres )
134 : {
135 354552 : s += w0[k] * x0[i] + w1[k] * x1[-i];
136 354552 : s2 += v0[k] * y0[i] + v1[k] * y1[-i];
137 : }
138 72912 : s2 *= ALPHA;
139 :
140 72912 : buf[j] = ( synth[j] - gain * s2 ) - ( synth_ltp[j] - gain * s );
141 :
142 :
143 72912 : x0++;
144 72912 : x1++;
145 72912 : y0++;
146 72912 : y1++;
147 : }
148 :
149 3038 : set_f( zir, 0.0f, length );
150 :
151 3038 : syn_filt( A, lpcorder, zir, zir, length, buf, 0 );
152 :
153 3038 : alpha = 1.f;
154 3038 : step = 1.f / (float) ( length / 2 );
155 :
156 291298 : for ( j = length / 2; j < length; j++ )
157 : {
158 288260 : zir[j] *= alpha;
159 288260 : alpha -= step;
160 : }
161 :
162 3038 : return;
163 : }
164 :
165 :
166 : /*-------------------------------------------------------------------
167 : * predict_signal()
168 : *
169 : *
170 : *-------------------------------------------------------------------*/
171 :
172 2557711 : 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 2557711 : x0 = &excI[-T0 - 1];
186 2557711 : frac = -frac;
187 :
188 2557711 : if ( frac < 0 )
189 : {
190 1358809 : frac += frac_max;
191 1358809 : x0--;
192 : }
193 :
194 2557711 : if ( frac_max == 6 )
195 : {
196 394191 : win = &inter6_2tcx2[frac][0];
197 : }
198 : else
199 : {
200 2163520 : win = &inter4_2tcx2[frac][0];
201 : }
202 :
203 709255183 : for ( j = 0; j < L_subfr; j++ )
204 : {
205 706697472 : s = win[1] * x0[1] + win[2] * x0[2];
206 706697472 : excO[j] = s + win[0] * x0[0] + win[3] * x0[3];
207 706697472 : x0++;
208 : }
209 :
210 2557711 : return;
211 : }
212 :
213 :
214 : /*-------------------------------------------------------------------
215 : * tcx_ltp_synth_filter()
216 : *
217 : *
218 : *-------------------------------------------------------------------*/
219 :
220 36350408 : 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 36350408 : if ( gain > 0.f )
237 : {
238 8493169 : x0 = &synth_ltp[-pitch_int];
239 8493169 : x1 = x0 - 1;
240 8493169 : y0 = synth;
241 8493169 : y1 = y0 - 1;
242 :
243 8493169 : assert( filtIdx >= 0 );
244 :
245 8493169 : w0 = &tcxLtpFilters[filtIdx].filt[pitch_fr];
246 8493169 : w1 = &tcxLtpFilters[filtIdx].filt[pitch_res - pitch_fr];
247 8493169 : v0 = &tcxLtpFilters[filtIdx].filt[0];
248 8493169 : v1 = &tcxLtpFilters[filtIdx].filt[pitch_res];
249 :
250 8493169 : L = tcxLtpFilters[filtIdx].length;
251 :
252 :
253 2106641246 : for ( j = 0; j < length; j++ )
254 : {
255 2098148077 : s = 0;
256 2098148077 : s2 = 0;
257 14952308751 : for ( i = 0, k = 0; i < L; i++, k += pitch_res )
258 : {
259 12854160674 : s += w0[k] * x0[i] + w1[k] * x1[-i];
260 12854160674 : s2 += v0[k] * y0[i] + v1[k] * y1[-i];
261 : }
262 :
263 2098148077 : s2 *= ALPHA;
264 2098148077 : synth_ltp[j] = synth[j] - gain * s2 + gain * s;
265 :
266 2098148077 : x0++;
267 2098148077 : x1++;
268 2098148077 : y0++;
269 2098148077 : y1++;
270 : }
271 : }
272 : else
273 : {
274 27857239 : mvr2r( synth, synth_ltp, length );
275 : }
276 :
277 36350408 : return;
278 : }
279 :
280 :
281 : /*-------------------------------------------------------------------
282 : * tcx_ltp_synth_filter_zir()
283 : *
284 : *
285 : *-------------------------------------------------------------------*/
286 :
287 3038 : 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 3038 : x0 = &synth_ltp[-pitch_int];
305 3038 : x1 = x0 - 1;
306 3038 : y0 = synth;
307 3038 : y1 = y0 - 1;
308 :
309 3038 : assert( filtIdx >= 0 );
310 :
311 3038 : w0 = &tcxLtpFilters[filtIdx].filt[pitch_fr];
312 3038 : w1 = &tcxLtpFilters[filtIdx].filt[pitch_res - pitch_fr];
313 3038 : v0 = &tcxLtpFilters[filtIdx].filt[0];
314 3038 : v1 = &tcxLtpFilters[filtIdx].filt[pitch_res];
315 3038 : L = tcxLtpFilters[filtIdx].length;
316 :
317 579558 : for ( j = 0; j < length; j++ )
318 : {
319 576520 : s = 0;
320 576520 : s2 = 0;
321 :
322 3664440 : for ( i = 0, k = 0; i < L; i++, k += pitch_res )
323 : {
324 3087920 : s += w0[k] * x0[i] + w1[k] * x1[-i];
325 3087920 : s2 += v0[k] * y0[i] + v1[k] * y1[-i];
326 : }
327 :
328 576520 : s2 *= ALPHA;
329 :
330 576520 : synth_ltp[j] = ( synth[j] - gain * s2 + gain * s ) - zir[j];
331 :
332 576520 : x0++;
333 576520 : x1++;
334 576520 : y0++;
335 576520 : y1++;
336 : }
337 :
338 3038 : return;
339 : }
340 :
341 :
342 : /*-------------------------------------------------------------------
343 : * tcx_ltp_synth_filter_fadein()
344 : *
345 : *
346 : *-------------------------------------------------------------------*/
347 :
348 991 : 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 991 : if ( gain > 0.f )
366 : {
367 991 : x0 = &synth_ltp[-pitch_int];
368 991 : x1 = x0 - 1;
369 991 : y0 = synth;
370 991 : y1 = y0 - 1;
371 :
372 991 : assert( filtIdx >= 0 );
373 :
374 991 : w0 = &tcxLtpFilters[filtIdx].filt[pitch_fr];
375 991 : w1 = &tcxLtpFilters[filtIdx].filt[pitch_res - pitch_fr];
376 991 : v0 = &tcxLtpFilters[filtIdx].filt[0];
377 991 : v1 = &tcxLtpFilters[filtIdx].filt[pitch_res];
378 991 : L = tcxLtpFilters[filtIdx].length;
379 :
380 991 : alpha = 0.f;
381 991 : step = 1.f / (float) ( length );
382 :
383 :
384 180951 : for ( j = 0; j < length; j++ )
385 : {
386 179960 : s = 0;
387 179960 : s2 = 0;
388 :
389 1145800 : for ( i = 0, k = 0; i < L; i++, k += pitch_res )
390 : {
391 965840 : s += w0[k] * x0[i] + w1[k] * x1[-i];
392 965840 : s2 += v0[k] * y0[i] + v1[k] * y1[-i];
393 : }
394 :
395 179960 : s2 *= ALPHA;
396 :
397 179960 : synth_ltp[j] = synth[j] - alpha * gain * s2 + alpha * gain * s;
398 :
399 179960 : alpha += step;
400 :
401 179960 : x0++;
402 179960 : x1++;
403 179960 : y0++;
404 179960 : y1++;
405 : }
406 : }
407 : else
408 : {
409 0 : mvr2r( synth, synth_ltp, length );
410 : }
411 :
412 991 : return;
413 : }
414 :
415 :
416 : /*-------------------------------------------------------------------
417 : * tcx_ltp_synth_filter_fadeout()
418 : *
419 : *
420 : *-------------------------------------------------------------------*/
421 :
422 967 : 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 967 : if ( gain > 0.f )
440 : {
441 967 : x0 = &synth_ltp[-pitch_int];
442 967 : x1 = x0 - 1;
443 967 : y0 = synth;
444 967 : y1 = y0 - 1;
445 :
446 967 : assert( filtIdx >= 0 );
447 :
448 967 : w0 = &tcxLtpFilters[filtIdx].filt[pitch_fr];
449 967 : w1 = &tcxLtpFilters[filtIdx].filt[pitch_res - pitch_fr];
450 967 : v0 = &tcxLtpFilters[filtIdx].filt[0];
451 967 : v1 = &tcxLtpFilters[filtIdx].filt[pitch_res];
452 967 : L = tcxLtpFilters[filtIdx].length;
453 :
454 967 : alpha = 1.f;
455 967 : step = 1.f / (float) ( length );
456 :
457 177047 : for ( j = 0; j < length; j++ )
458 : {
459 176080 : s = 0;
460 176080 : s2 = 0;
461 :
462 1125680 : for ( i = 0, k = 0; i < L; i++, k += pitch_res )
463 : {
464 949600 : s += w0[k] * x0[i] + w1[k] * x1[-i];
465 949600 : s2 += v0[k] * y0[i] + v1[k] * y1[-i];
466 : }
467 :
468 176080 : s2 *= ALPHA;
469 176080 : synth_ltp[j] = synth[j] - alpha * gain * s2 + alpha * gain * s;
470 176080 : alpha -= step;
471 :
472 176080 : x0++;
473 176080 : x1++;
474 176080 : y0++;
475 176080 : y1++;
476 : }
477 : }
478 : else
479 : {
480 0 : mvr2r( synth, synth_ltp, length );
481 : }
482 :
483 967 : return;
484 : }
485 :
486 :
487 : /*-------------------------------------------------------------------
488 : * tcx_ltp_decode_params()
489 : *
490 : *
491 : *-------------------------------------------------------------------*/
492 :
493 13289826 : 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 13289826 : int16_t gainbits = 2;
505 :
506 : /* Decode Pitch and Gain */
507 13289826 : if ( ( ltp_param ) && ( ltp_param[0] ) )
508 : {
509 9323694 : if ( ltp_param[1] < ( ( pitfr2 - pitmin ) * pitres ) )
510 : {
511 6949074 : *pitch_int = pitmin + ( ltp_param[1] / pitres );
512 6949074 : *pitch_fr = ltp_param[1] - ( *pitch_int - pitmin ) * pitres;
513 : }
514 2374620 : else if ( ltp_param[1] < ( ( pitfr2 - pitmin ) * pitres + ( pitfr1 - pitfr2 ) * ( pitres >> 1 ) ) )
515 : {
516 1211128 : *pitch_int = pitfr2 + ( ( ltp_param[1] - ( pitfr2 - pitmin ) * pitres ) / ( pitres >> 1 ) );
517 1211128 : *pitch_fr = ( ltp_param[1] - ( pitfr2 - pitmin ) * pitres ) - ( *pitch_int - pitfr2 ) * ( pitres >> 1 );
518 1211128 : *pitch_fr = *pitch_fr << 1; /* was *= (pitres>>1); */
519 : }
520 : else
521 : {
522 1163492 : *pitch_int = ltp_param[1] + pitfr1 - ( ( pitfr2 - pitmin ) * pitres ) - ( ( pitfr1 - pitfr2 ) * ( pitres >> 1 ) );
523 1163492 : *pitch_fr = 0;
524 : }
525 9323694 : *gain = (float) ( ltp_param[2] + 1 ) * 0.625f / (float) ( 1 << gainbits );
526 9323694 : 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 9323694 : 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 3966132 : *pitch_int = pitmax;
542 3966132 : *pitch_fr = 0;
543 3966132 : *gain = 0.0f;
544 : }
545 :
546 13289826 : return 0;
547 : }
548 :
549 : /*-------------------------------------------------------------------
550 : *tcx_ltp_synth_filter_10()
551 : *
552 : *
553 : ---------------------------------------------------------------------*/
554 572036 : 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 572036 : x0 = &out[-pitch_int];
572 572036 : x1 = x0 - 1;
573 572036 : y0 = in;
574 572036 : y1 = y0 - 1;
575 :
576 572036 : assert( filtIdx >= 0 );
577 :
578 572036 : w0 = &tcxLtpFilters[filtIdx].filt[pitch_fr];
579 572036 : w1 = &tcxLtpFilters[filtIdx].filt[pitch_res - pitch_fr];
580 572036 : v0 = &tcxLtpFilters[filtIdx].filt[0];
581 572036 : v1 = &tcxLtpFilters[filtIdx].filt[pitch_res];
582 572036 : L = tcxLtpFilters[filtIdx].length;
583 :
584 572036 : curr_gain = gain;
585 572036 : gain_step = -gain / length;
586 :
587 98022596 : for ( j = 0; j < length; j++ )
588 : {
589 97450560 : s = 0;
590 97450560 : s2 = 0;
591 :
592 681387520 : for ( i = 0, k = 0; i < L; i++, k += pitch_res )
593 : {
594 583936960 : s += w0[k] * x0[i] + w1[k] * x1[-i];
595 583936960 : s2 += v0[k] * y0[i] + v1[k] * y1[-i];
596 : }
597 :
598 97450560 : out[j] = in[j] - curr_gain * s2 * ALPHA + curr_gain * s;
599 :
600 97450560 : x0++;
601 97450560 : x1++;
602 97450560 : y0++;
603 97450560 : y1++;
604 :
605 97450560 : curr_gain += gain_step;
606 : }
607 :
608 572036 : return;
609 : }
610 :
611 :
612 : /*-------------------------------------------------------------------
613 : *tcx_ltp_synth_filter_01()
614 : *
615 : *
616 : ---------------------------------------------------------------------*/
617 :
618 619913 : 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 619913 : x0 = &out[-pitch_int];
636 619913 : x1 = x0 - 1;
637 619913 : y0 = in;
638 619913 : y1 = y0 - 1;
639 :
640 619913 : assert( filtIdx >= 0 );
641 :
642 619913 : w0 = &tcxLtpFilters[filtIdx].filt[pitch_fr];
643 619913 : w1 = &tcxLtpFilters[filtIdx].filt[pitch_res - pitch_fr];
644 619913 : v0 = &tcxLtpFilters[filtIdx].filt[0];
645 619913 : v1 = &tcxLtpFilters[filtIdx].filt[pitch_res];
646 619913 : L = tcxLtpFilters[filtIdx].length;
647 :
648 619913 : curr_gain = 0.0f;
649 619913 : gain_step = gain / length;
650 :
651 105919913 : for ( j = 0; j < length; j++ )
652 : {
653 105300000 : s = 0;
654 105300000 : s2 = 0;
655 :
656 736350720 : for ( i = 0, k = 0; i < L; i++, k += pitch_res )
657 : {
658 631050720 : s += w0[k] * x0[i] + w1[k] * x1[-i];
659 631050720 : s2 += v0[k] * y0[i] + v1[k] * y1[-i];
660 : }
661 :
662 105300000 : out[j] = in[j] - curr_gain * s2 * ALPHA + curr_gain * s;
663 :
664 105300000 : x0++;
665 105300000 : x1++;
666 105300000 : y0++;
667 105300000 : y1++;
668 :
669 105300000 : curr_gain += gain_step;
670 : }
671 :
672 619913 : 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 3148242 : 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 3148242 : x0 = &out[-prev_pitch_int];
719 3148242 : x1 = x0 - 1;
720 3148242 : y0 = in;
721 3148242 : y1 = y0 - 1;
722 :
723 3148242 : assert( filtIdx >= 0 && prev_filtIdx >= 0 );
724 :
725 3148242 : w0 = &tcxLtpFilters[prev_filtIdx].filt[prev_pitch_fr];
726 3148242 : w1 = &tcxLtpFilters[prev_filtIdx].filt[prev_pitch_res - prev_pitch_fr];
727 3148242 : v0 = &tcxLtpFilters[prev_filtIdx].filt[0];
728 3148242 : v1 = &tcxLtpFilters[prev_filtIdx].filt[prev_pitch_res];
729 :
730 3148242 : prev_L = tcxLtpFilters[prev_filtIdx].length;
731 :
732 3148242 : p0 = &tcxLtpFilters[filtIdx].filt[cur_pitch_fr];
733 3148242 : p1 = &tcxLtpFilters[filtIdx].filt[pitch_res - cur_pitch_fr];
734 3148242 : q0 = &tcxLtpFilters[filtIdx].filt[0];
735 3148242 : q1 = &tcxLtpFilters[filtIdx].filt[pitch_res];
736 :
737 3148242 : 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 3148242 : gain = prev_gain;
741 3148242 : gain_step = -prev_gain / length;
742 :
743 537606482 : for ( j = 0; j < length; j++ )
744 : {
745 534458240 : s = 0;
746 534458240 : s2 = 0;
747 :
748 3818214720 : for ( i = 0, k = 0; i < prev_L; i++, k += prev_pitch_res )
749 : {
750 3283756480 : s += w0[k] * x0[i] + w1[k] * x1[-i];
751 3283756480 : s2 += v0[k] * y0[i] + v1[k] * y1[-i];
752 : }
753 :
754 534458240 : out[j] = in[j] - gain * s2 * ALPHA + gain * s;
755 :
756 534458240 : x0++;
757 534458240 : x1++;
758 534458240 : y0++;
759 534458240 : y1++;
760 :
761 534458240 : gain += gain_step;
762 : }
763 :
764 3148242 : mvr2r( out - L, temp_buf, length + L );
765 3148242 : mvr2r( in + length, temp_buf + length + L, L );
766 3148242 : temp_ptr = &temp_buf[0] + L;
767 :
768 3148242 : m0 = temp_ptr;
769 3148242 : m1 = temp_ptr - 1;
770 3148242 : l0 = &out[-cur_pitch_int];
771 3148242 : 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 3148242 : gain = 0.0f;
775 3148242 : gain_step = cur_gain / length;
776 :
777 537606482 : for ( j = 0; j < length; j++ )
778 : {
779 534458240 : s3 = 0;
780 534458240 : s4 = 0;
781 :
782 3818208480 : for ( i = 0, k = 0; i < L; i++, k += pitch_res )
783 : {
784 3283750240 : s3 += p0[k] * l0[i] + p1[k] * l1[-i];
785 3283750240 : s4 += q0[k] * m0[i] + q1[k] * m1[-i];
786 : }
787 :
788 534458240 : out[j] = *( temp_ptr + j ) - gain * s4 * ALPHA + gain * s3;
789 :
790 534458240 : l0++;
791 534458240 : l1++;
792 534458240 : m0++;
793 534458240 : m1++;
794 :
795 534458240 : gain += gain_step;
796 : }
797 :
798 3148242 : return;
799 : }
800 :
801 :
802 : /*-------------------------------------------------------------------
803 : * tcx_ltp_post()
804 : *
805 : *
806 : *-------------------------------------------------------------------*/
807 :
808 18009087 : 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 18009087 : total_brate = ( st->element_mode == IVAS_CPE_MDCT ? st->bits_frame_nominal * FRAMES_PER_SEC : st->total_brate );
828 18009087 : filtIdx = 0; /* just to avoid compilation warnings */
829 18009087 : tcx_buf_len = NS2SA( st->output_Fs, TCXLTP_DELAY_NS );
830 18009087 : SideInfoOnly = 0;
831 :
832 18009087 : if ( total_brate >= HQ_96k )
833 : {
834 7358298 : SideInfoOnly = 1;
835 : }
836 :
837 18009087 : L_frame_core = st->L_frame;
838 18009087 : if ( st->element_mode == IVAS_CPE_MDCT )
839 : {
840 12188826 : L_frame_core = L_FRAME;
841 : }
842 :
843 18009087 : if ( core == ACELP_CORE )
844 : {
845 2281683 : bfi = 0;
846 2281683 : pitch_int = 0;
847 2281683 : pitch_fr = 0;
848 2281683 : gain = 0.0f;
849 :
850 2281683 : L_frame_core = st->L_frame_past;
851 : }
852 : else
853 : {
854 15727404 : bfi = st->bfi;
855 15727404 : pitch_int = hTcxLtpDec->tcxltp_pitch_int;
856 15727404 : pitch_fr = hTcxLtpDec->tcxltp_pitch_fr;
857 15727404 : gain = hTcxLtpDec->tcxltp_gain;
858 : }
859 :
860 : /******** Init ********/
861 :
862 : /* Parameters */
863 18009087 : L_transition = output_frame / 4;
864 18009087 : lpcorder = TCXLTP_LTP_ORDER;
865 :
866 :
867 : /* Input buffer */
868 18009087 : sig_in = buf_in + tcx_buf_len;
869 18009087 : mvr2r( hTcxLtpDec->tcxltp_mem_in, buf_in, tcx_buf_len );
870 18009087 : mvr2r( sig, buf_in + tcx_buf_len, output_frame );
871 18009087 : if ( core > ACELP_CORE )
872 : {
873 15727404 : mvr2r( tcx_buf, sig_in + output_frame, tcx_buf_len );
874 : }
875 18009087 : mvr2r( sig + output_frame - tcx_buf_len, hTcxLtpDec->tcxltp_mem_in, tcx_buf_len );
876 :
877 : /* Output buffer */
878 18009087 : sig_out = buf_out + output_frame;
879 18009087 : mvr2r( hTcxLtpDec->tcxltp_mem_out, buf_out, output_frame );
880 :
881 : /* TCX-LTP parameters: integer pitch, fractional pitch, gain */
882 :
883 18009087 : if ( !( SideInfoOnly || hTcxLtpDec->tcxltp ) || core == ACELP_CORE )
884 : {
885 : /* No LTP */
886 5464659 : pitch_int = 0;
887 5464659 : pitch_fr = 0;
888 5464659 : gain = 0.f;
889 : }
890 12544428 : else if ( !bfi )
891 : {
892 : /* LTP and good frame */
893 11762690 : if ( output_frame != L_frame_core )
894 : {
895 11050150 : tmp = pitch_int * st->pit_res_max + pitch_fr;
896 11050150 : tmp = ( tmp * output_frame + L_frame_core / 2 ) / L_frame_core;
897 11050150 : pitch_int = tmp / st->pit_res_max;
898 11050150 : pitch_fr = tmp % st->pit_res_max;
899 : }
900 :
901 11762690 : if ( st->element_mode == EVS_MONO ) /* hard tunings for EVS_MONO, HQ_48k is TCX only */
902 : {
903 9479 : if ( total_brate == HQ_48k && L_frame_core == L_FRAME16k )
904 : {
905 500 : gain *= 0.32f;
906 : }
907 8979 : else if ( total_brate == HQ_48k && L_frame_core == 512 )
908 : {
909 942 : gain *= 0.40f;
910 : }
911 : else
912 : {
913 8037 : gain *= 0.64f;
914 : }
915 : }
916 11753211 : else if ( ( st->element_mode > IVAS_SCE ) && ( total_brate >= IVAS_96k ) )
917 : {
918 6296948 : gain *= 0.40f;
919 : }
920 : else
921 : {
922 5456263 : gain *= 0.64f;
923 : }
924 : }
925 : else
926 : {
927 : /* PLC: [TCX: Fade-out]
928 : * PLC: LTP and bad frame (concealment) */
929 781738 : if ( st->pit_res_max == st->pit_res_max_past ) /* ensure consistent core SR to previous frame; otherwise, set gain to 0 */
930 : {
931 781738 : pitch_int = hTcxLtpDec->tcxltp_pitch_int_post_prev;
932 781738 : pitch_fr = hTcxLtpDec->tcxltp_pitch_fr_post_prev;
933 781738 : gain = hTcxLtpDec->tcxltp_gain_post_prev * st->hTcxDec->damping;
934 : }
935 : else
936 : {
937 0 : gain = 0.f;
938 : }
939 : }
940 :
941 18009087 : if ( SideInfoOnly )
942 : {
943 7358298 : gain = 0.f;
944 7358298 : if ( bfi )
945 : {
946 479765 : hTcxLtpDec->tcxltp_gain_post_prev = 0.f;
947 : }
948 : }
949 18009087 : gain2 = gain;
950 :
951 18009087 : if ( L_frame_core == L_FRAME )
952 : {
953 13509751 : switch ( output_frame )
954 : {
955 1584 : case L_FRAME8k:
956 1584 : filtIdx = 0;
957 1584 : break;
958 3474714 : case L_FRAME16k:
959 3474714 : filtIdx = 1;
960 3474714 : break;
961 3792345 : case L_FRAME32k:
962 3792345 : filtIdx = 2;
963 3792345 : break;
964 6241108 : case L_FRAME48k:
965 6241108 : filtIdx = 3;
966 6241108 : break;
967 0 : default:
968 0 : assert( 0 );
969 : break;
970 : }
971 : }
972 4499336 : else if ( L_frame_core == L_FRAME16k )
973 : {
974 2978926 : switch ( output_frame )
975 : {
976 0 : case L_FRAME8k:
977 0 : filtIdx = 4;
978 0 : break;
979 1156202 : case L_FRAME16k:
980 1156202 : filtIdx = 5;
981 1156202 : break;
982 740428 : case L_FRAME32k:
983 740428 : filtIdx = 6;
984 740428 : break;
985 1082296 : case L_FRAME48k:
986 1082296 : filtIdx = 7;
987 1082296 : break;
988 0 : default:
989 0 : assert( 0 );
990 : break;
991 : }
992 : }
993 1520410 : else if ( L_frame_core == 512 )
994 : {
995 318063 : switch ( output_frame )
996 : {
997 0 : case L_FRAME8k:
998 0 : filtIdx = 8;
999 0 : break;
1000 405 : case L_FRAME16k:
1001 405 : filtIdx = 9;
1002 405 : break;
1003 122191 : case L_FRAME32k:
1004 122191 : filtIdx = 10;
1005 122191 : break;
1006 195467 : case L_FRAME48k:
1007 195467 : filtIdx = 11;
1008 195467 : break;
1009 0 : default:
1010 0 : assert( 0 );
1011 : break;
1012 : }
1013 : }
1014 : else
1015 : {
1016 1202347 : filtIdx = -1;
1017 : }
1018 :
1019 :
1020 : /******** Previous-frame part ********/
1021 18009087 : 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 18009087 : if ( st->element_mode != EVS_MONO )
1026 : {
1027 17969877 : if ( gain == 0.f && hTcxLtpDec->tcxltp_gain_post_prev == 0.f )
1028 : {
1029 : /* The filtering is deactivated, just copy input to the output */
1030 13298598 : mvr2r( sig_in + delay, sig_out + delay, L_transition );
1031 : }
1032 4671279 : else if ( gain == 0.f && hTcxLtpDec->tcxltp_gain_post_prev != 0.f )
1033 : {
1034 : /* Filtering with the first filter unit */
1035 572036 : 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 4099243 : else if ( gain != 0.f && hTcxLtpDec->tcxltp_gain_post_prev == 0.f )
1038 : {
1039 : /* Filtering with the second filter unit */
1040 619913 : 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 3479330 : 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 331088 : 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 3148242 : 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 3148242 : 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 39210 : if ( gain == 0.f && hTcxLtpDec->tcxltp_gain_post_prev == 0.f )
1056 : {
1057 33068 : mvr2r( sig_in + delay, sig_out + delay, L_transition );
1058 : }
1059 6142 : else if ( hTcxLtpDec->tcxltp_gain_post_prev == 0.f )
1060 : {
1061 991 : 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 5151 : else if ( gain == 0.f )
1064 : {
1065 967 : 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 4184 : 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 1146 : 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 3038 : tcx_ltp_get_lpc( sig_out + delay - output_frame, output_frame, A, lpcorder );
1075 3038 : 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 3038 : 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 18009087 : 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 18009087 : mvr2r( sig_out, sig, output_frame );
1088 :
1089 : /* Update */
1090 18009087 : hTcxLtpDec->tcxltp_pitch_int_post_prev = pitch_int;
1091 18009087 : hTcxLtpDec->tcxltp_pitch_fr_post_prev = pitch_fr;
1092 18009087 : hTcxLtpDec->tcxltp_gain_post_prev = gain2;
1093 18009087 : hTcxLtpDec->tcxltp_filt_idx_prev = filtIdx;
1094 18009087 : st->pit_res_max_past = st->pit_res_max;
1095 18009087 : mvr2r( sig_out, hTcxLtpDec->tcxltp_mem_out, output_frame );
1096 :
1097 18009087 : return;
1098 : }
|