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 <math.h>
44 : #include "cnst.h"
45 : #include "rom_com.h"
46 : #include "prot.h"
47 : #include "wmc_auto.h"
48 :
49 : /*-------------------------------------------------------------------*
50 : * tcx_get_windows()
51 : *
52 : *
53 : *-------------------------------------------------------------------*/
54 5235052 : void tcx_get_windows(
55 : TCX_CONFIG_HANDLE hTcxCfg, /* i : TCX configuration */
56 : const int16_t left_mode, /* i : overlap mode of left window half */
57 : const int16_t right_mode, /* i : overlap mode of right window half */
58 : int16_t *left_overlap, /* o : left overlap length */
59 : const float **left_win, /* o : left overlap window */
60 : int16_t *right_overlap, /* o : right overlap length */
61 : const float **right_win, /* o : right overlap window */
62 : const int16_t fullband /* i : fullband flag */
63 : )
64 : {
65 5235052 : if ( !fullband )
66 : {
67 : /* Left part */
68 :
69 737047 : if ( left_mode == TRANSITION_OVERLAP )
70 : {
71 : /* ACELP->TCX transition */
72 3429 : *left_overlap = hTcxCfg->tcx_mdct_window_trans_length;
73 3429 : *left_win = hTcxCfg->tcx_mdct_window_trans;
74 : }
75 733618 : else if ( left_mode == MIN_OVERLAP )
76 : {
77 10510 : *left_overlap = hTcxCfg->tcx_mdct_window_min_length;
78 10510 : *left_win = hTcxCfg->tcx_mdct_window_minimum;
79 : }
80 723108 : else if ( left_mode == HALF_OVERLAP )
81 : {
82 5605 : *left_overlap = hTcxCfg->tcx_mdct_window_half_length;
83 5605 : *left_win = hTcxCfg->tcx_mdct_window_half;
84 : }
85 717503 : else if ( left_mode == FULL_OVERLAP )
86 : {
87 717503 : *left_overlap = hTcxCfg->tcx_mdct_window_length;
88 717503 : *left_win = hTcxCfg->tcx_aldo_window_1_trunc;
89 : }
90 : else
91 : {
92 0 : assert( !"Not supported overlap" );
93 : }
94 :
95 : /* Right part */
96 :
97 737047 : if ( right_mode == MIN_OVERLAP )
98 : {
99 10612 : *right_overlap = hTcxCfg->tcx_mdct_window_min_length;
100 10612 : *right_win = hTcxCfg->tcx_mdct_window_minimum;
101 : }
102 726435 : else if ( right_mode == HALF_OVERLAP )
103 : {
104 5741 : *right_overlap = hTcxCfg->tcx_mdct_window_half_length;
105 5741 : *right_win = hTcxCfg->tcx_mdct_window_half;
106 : }
107 720694 : else if ( right_mode == FULL_OVERLAP )
108 : {
109 720694 : *right_overlap = hTcxCfg->tcx_mdct_window_delay;
110 720694 : *right_win = hTcxCfg->tcx_aldo_window_2;
111 : }
112 : else
113 : {
114 0 : assert( !"Not supported overlap" );
115 : }
116 : }
117 : else
118 : {
119 : /* Left part */
120 :
121 4498005 : if ( left_mode == TRANSITION_OVERLAP )
122 : {
123 : /* ACELP->TCX transition */
124 116085 : *left_overlap = hTcxCfg->tcx_mdct_window_trans_lengthFB;
125 116085 : *left_win = hTcxCfg->tcx_mdct_window_transFB;
126 : }
127 4381920 : else if ( left_mode == MIN_OVERLAP )
128 : {
129 790053 : *left_overlap = hTcxCfg->tcx_mdct_window_min_lengthFB;
130 790053 : *left_win = hTcxCfg->tcx_mdct_window_minimumFB;
131 : }
132 3591867 : else if ( left_mode == HALF_OVERLAP )
133 : {
134 170684 : *left_overlap = hTcxCfg->tcx_mdct_window_half_lengthFB;
135 170684 : *left_win = hTcxCfg->tcx_mdct_window_halfFB;
136 : }
137 3421183 : else if ( left_mode == RECTANGULAR_OVERLAP )
138 : {
139 438934 : *left_overlap = 0;
140 438934 : *left_win = NULL;
141 : }
142 2982249 : else if ( left_mode == FULL_OVERLAP )
143 : {
144 2982249 : *left_overlap = hTcxCfg->tcx_mdct_window_lengthFB;
145 2982249 : *left_win = hTcxCfg->tcx_aldo_window_1_FB_trunc;
146 : }
147 : else
148 : {
149 0 : assert( !"Not supported overlap" );
150 : }
151 :
152 : /* Right part */
153 :
154 4498005 : if ( right_mode == MIN_OVERLAP )
155 : {
156 831524 : *right_overlap = hTcxCfg->tcx_mdct_window_min_lengthFB;
157 831524 : *right_win = hTcxCfg->tcx_mdct_window_minimumFB;
158 : }
159 3666481 : else if ( right_mode == HALF_OVERLAP )
160 : {
161 210309 : *right_overlap = hTcxCfg->tcx_mdct_window_half_lengthFB;
162 210309 : *right_win = hTcxCfg->tcx_mdct_window_halfFB;
163 : }
164 3456172 : else if ( right_mode == RECTANGULAR_OVERLAP )
165 : {
166 438859 : *right_overlap = 0;
167 438859 : *right_win = NULL;
168 : }
169 3017313 : else if ( right_mode == FULL_OVERLAP )
170 : {
171 3017313 : *right_overlap = hTcxCfg->tcx_mdct_window_delayFB;
172 3017313 : *right_win = hTcxCfg->tcx_aldo_window_2_FB;
173 : }
174 : else
175 : {
176 0 : assert( !"Not supported overlap" );
177 : }
178 : }
179 :
180 5235052 : return;
181 : }
182 :
183 : /*-------------------------------------------------------------------*
184 : * tcx_windowing_analysis()
185 : *
186 : *
187 : *-------------------------------------------------------------------*/
188 :
189 5234893 : void tcx_windowing_analysis(
190 : const float *signal, /* i : signal vector */
191 : const int16_t L_frame, /* i : frame length */
192 : const int16_t left_overlap, /* i : left overlap length */
193 : const float *left_win, /* i : left overlap window */
194 : const int16_t right_overlap, /* i : right overlap length */
195 : const float *right_win, /* i : right overlap window */
196 : float *output /* o : windowed signal vector */
197 : )
198 : {
199 : int16_t w;
200 :
201 : /* Left overlap */
202 1388013745 : for ( w = 0; w < left_overlap; w++ )
203 : {
204 1382778852 : *output++ = *signal++ * left_win[w];
205 : }
206 :
207 : /* Non overlapping region */
208 2000810025 : for ( w = 0; w < L_frame - ( left_overlap + right_overlap ) / 2; w++ )
209 : {
210 1995575132 : *output++ = *signal++;
211 : }
212 :
213 : /* Right overlap */
214 1405546193 : for ( w = 0; w < right_overlap; w++ )
215 : {
216 1400311300 : *output++ = *signal++ * right_win[right_overlap - 1 - w];
217 : }
218 :
219 5234893 : return;
220 : }
221 :
222 :
223 : /*-------------------------------------------------------------------*
224 : * WindowSignal()
225 : *
226 : *
227 : *-------------------------------------------------------------------*/
228 :
229 5234893 : void WindowSignal(
230 : TCX_CONFIG_HANDLE hTcxCfg, /* i : configuration of TCX */
231 : int16_t offset, /* i : left folding point offset relative to the input signal pointer */
232 : const int16_t left_overlap_mode, /* i : overlap mode of left window half */
233 : const int16_t right_overlap_mode, /* i : overlap mode of right window half */
234 : int16_t *left_overlap_length, /* o : TCX window left overlap length */
235 : int16_t *right_overlap_length, /* o : TCX window right overlap length */
236 : const float in[], /* i : input signal */
237 : int16_t *L_frame, /* i/o: frame length */
238 : float out[], /* o : output windowed signal */
239 : const int16_t truncate_aldo, /* i : nonzero to truncate long ALDO slope */
240 : const int16_t fullband /* i : fullband flag */
241 : )
242 : {
243 : int16_t l, r;
244 : const float *left_win;
245 : const float *right_win;
246 :
247 : /*-----------------------------------------------------------*
248 : * Init *
249 : *-----------------------------------------------------------*/
250 :
251 5234893 : tcx_get_windows( hTcxCfg, left_overlap_mode, right_overlap_mode, &l, &left_win, &r, &right_win, fullband );
252 :
253 : /* Init lengths */
254 :
255 : /* if past frame is ACELP */
256 5234893 : if ( left_overlap_mode == TRANSITION_OVERLAP )
257 : {
258 : /* Increase frame size for 5ms */
259 119514 : if ( !fullband )
260 : {
261 3429 : *L_frame += hTcxCfg->tcx5Size;
262 3429 : offset = -hTcxCfg->tcx_mdct_window_trans_length / 2;
263 : }
264 : else
265 : {
266 116085 : *L_frame += hTcxCfg->tcx5SizeFB;
267 116085 : offset = -hTcxCfg->tcx_mdct_window_trans_lengthFB / 2;
268 : }
269 : }
270 :
271 : /*-----------------------------------------------------------*
272 : * Windowing *
273 : *-----------------------------------------------------------*/
274 :
275 5234893 : tcx_windowing_analysis( in - l / 2 + offset, *L_frame, l, left_win, r, right_win, out );
276 :
277 5234893 : if ( left_overlap_mode == FULL_OVERLAP && truncate_aldo )
278 : {
279 : /* fade truncated ALDO window to avoid discontinuities */
280 3371834 : if ( !fullband )
281 : {
282 717503 : v_mult( out, hTcxCfg->tcx_mdct_window_minimum, out, hTcxCfg->tcx_mdct_window_min_length );
283 : }
284 : else
285 : {
286 2654331 : v_mult( out, hTcxCfg->tcx_mdct_window_minimumFB, out, hTcxCfg->tcx_mdct_window_min_lengthFB );
287 : }
288 : }
289 :
290 5234893 : *left_overlap_length = l;
291 5234893 : *right_overlap_length = r;
292 :
293 5234893 : return;
294 : }
295 :
296 :
297 : /*-------------------------------------------------------------------*
298 : * tcx_windowing_synthesis_current_frame()
299 : *
300 : *
301 : *-------------------------------------------------------------------*/
302 :
303 4597706 : void tcx_windowing_synthesis_current_frame(
304 : float *signal, /* i/o: signal vector */
305 : const float *window, /* i : TCX window vector */
306 : const float *window_half, /* i : TCX window vector for half-overlap window */
307 : const float *window_min, /* i : TCX minimum overlap window */
308 : const int16_t window_length, /* i : TCX window length */
309 : const int16_t window_half_length, /* i : TCX half window length */
310 : const int16_t window_min_length, /* i : TCX minimum overlap length */
311 : const int16_t left_rect, /* i : left part is rectangular */
312 : const int16_t left_mode, /* i : overlap mode of left window half */
313 : float *acelp_zir, /* i/o: acelp ZIR */
314 : const float *old_syn, /* i : old synthesis */
315 : const float *syn_overl, /* i : overlap synthesis */
316 : const float *A_zir,
317 : const float *window_trans,
318 : int16_t acelp_zir_len,
319 : const int16_t acelp_mem_len,
320 : const int16_t last_core_bfi, /* i : last mode */
321 : const int16_t last_is_cng,
322 : const int16_t fullbandScale )
323 : {
324 : int16_t i, w, overlap;
325 : float tmp[L_FRAME_MAX / 2];
326 :
327 : /* Init */
328 4597706 : overlap = window_length >> 1;
329 :
330 : /* Past-frame is TCX concealed as CNG and current-frame is TCX */
331 4597706 : if ( last_is_cng == 1 && left_rect == 0 )
332 : {
333 0 : if ( !fullbandScale )
334 : {
335 0 : set_zero( acelp_zir, acelp_zir_len );
336 0 : syn_filt( A_zir, M, acelp_zir, acelp_zir, acelp_zir_len, signal + overlap + acelp_mem_len - M, 0 );
337 : }
338 : else
339 : {
340 0 : lerp( acelp_zir, tmp, acelp_zir_len, acelp_zir_len * FSCALE_DENOM / fullbandScale );
341 0 : acelp_zir = tmp;
342 : }
343 :
344 0 : for ( i = 0; i < acelp_zir_len; i++ )
345 : {
346 0 : signal[i] *= (float) ( i ) / (float) ( acelp_zir_len );
347 0 : signal[i] += acelp_zir[i] * (float) ( acelp_zir_len - i ) / (float) ( acelp_zir_len );
348 : }
349 : }
350 4597706 : else if ( left_rect == 1 && last_core_bfi == ACELP_CORE ) /* Rectangular window (past-frame is ACELP) */
351 : {
352 65317137 : for ( i = 0; i < overlap - acelp_mem_len; i++ )
353 : {
354 64702578 : signal[i] = 0;
355 : }
356 :
357 614559 : if ( fullbandScale == 0 )
358 : {
359 : /*OLA with ACELP*/
360 7910708 : for ( i = 0; i < 2 * acelp_mem_len; i++ )
361 : {
362 : /*window decoded TCX with aliasing*/
363 7565216 : signal[i + overlap - acelp_mem_len] *= window_trans[i];
364 : /*Time TDAC: 1)forward part of ACELP*/
365 7565216 : signal[i + overlap - acelp_mem_len] += old_syn[acelp_zir_len - 2 * acelp_mem_len + i] * window_trans[2 * acelp_mem_len - i - 1] * window_trans[2 * acelp_mem_len - i - 1];
366 :
367 : /*Time TDAC: 1)reward part of ACELP*/
368 7565216 : signal[i + overlap - acelp_mem_len] += old_syn[acelp_zir_len - i - 1] * window_trans[i] * window_trans[2 * acelp_mem_len - i - 1];
369 : }
370 :
371 5873364 : for ( i = 0; i < M; i++ )
372 : {
373 5527872 : signal[overlap + acelp_mem_len - M + i] -= old_syn[acelp_zir_len - M + i];
374 : }
375 : }
376 :
377 : /* ZIR at the end of the ACELP frame */
378 614559 : acelp_zir_len = 64;
379 :
380 614559 : if ( !fullbandScale )
381 : {
382 345492 : set_zero( acelp_zir, acelp_zir_len );
383 345492 : syn_filt( A_zir, M, acelp_zir, acelp_zir, acelp_zir_len, signal + overlap + acelp_mem_len - M, 0 );
384 : }
385 : else
386 : {
387 269067 : lerp( acelp_zir, tmp, acelp_zir_len * fullbandScale / FSCALE_DENOM, acelp_zir_len );
388 269067 : acelp_zir_len = acelp_zir_len * fullbandScale / FSCALE_DENOM;
389 269067 : acelp_zir = tmp;
390 :
391 269067 : if ( acelp_zir_len >= 2.0f * 64 )
392 : {
393 : /* apply a simple low-pass to the ZIR, to avoid potentially unmasked HF content */
394 34696553 : for ( i = 2; i < acelp_zir_len; i++ )
395 : {
396 34515794 : acelp_zir[i] = 0.25f * acelp_zir[i - 2] + 0.35f * acelp_zir[i - 1] + 0.40f * acelp_zir[i];
397 : }
398 180759 : acelp_zir[acelp_zir_len - 1] = 0.40f * acelp_zir[acelp_zir_len - 1] + 0.35f * acelp_zir[acelp_zir_len - 1] + 0.25f * acelp_zir[acelp_zir_len - 2];
399 180759 : acelp_zir[acelp_zir_len - 2] = 0.40f * acelp_zir[acelp_zir_len - 2] + 0.35f * acelp_zir[acelp_zir_len - 1] + 0.25f * acelp_zir[acelp_zir_len - 1];
400 34696553 : for ( i = acelp_zir_len - 3; i >= 0; i-- )
401 : {
402 34515794 : acelp_zir[i] = 0.40f * acelp_zir[i] + 0.35f * acelp_zir[i + 1] + 0.25f * acelp_zir[i + 2];
403 : }
404 : }
405 : }
406 :
407 65805127 : for ( i = 0; i < acelp_zir_len; i++ )
408 : {
409 : /*remove reconstructed ZIR and add ACELP ZIR*/
410 65190568 : signal[i + overlap + acelp_mem_len] -= acelp_zir[i] * (float) ( acelp_zir_len - i ) / (float) acelp_zir_len;
411 : }
412 : }
413 3983147 : else if ( left_rect == 1 && last_core_bfi != 0 ) /* Rectangular window (past-frame is TCX) */
414 : {
415 3095686 : for ( i = 0; i < overlap + acelp_mem_len; i++ )
416 : {
417 3072448 : signal[i] = 0;
418 : }
419 5400022 : for ( i = 0; i < window_length; i++ )
420 : {
421 5376784 : signal[i + overlap + acelp_mem_len] *= window[i];
422 : }
423 : }
424 3959909 : else if ( left_rect != 1 && last_core_bfi == 0 ) /* Normal window (past-frame is ACELP) */
425 : {
426 680858 : for ( i = 0; i < window_length; i++ )
427 : {
428 678328 : signal[i] *= window[i];
429 : }
430 :
431 680858 : for ( i = 0; i < window_length; i++ )
432 : {
433 678328 : signal[i] += syn_overl[i];
434 : }
435 : }
436 : else /* Normal window (past-frame is TCX) */
437 : {
438 3957379 : if ( left_mode == 2 )
439 : {
440 : /* min. overlap */
441 104967957 : for ( i = 0; i < ( window_length - window_min_length ) / 2; i++ )
442 : {
443 102565728 : signal[i] = 0.0f;
444 : }
445 104155773 : for ( w = 0; w < window_min_length; i++, w++ )
446 : {
447 101753544 : signal[i] *= window_min[w];
448 : }
449 : }
450 1555150 : else if ( left_mode == 3 )
451 : {
452 : /* half OL */
453 9996445 : for ( i = 0; i < ( window_length - window_half_length ) / 2; i++ )
454 : {
455 9464080 : signal[i] = 0.0f;
456 : }
457 67237353 : for ( w = 0; w < window_half_length; i++, w++ )
458 : {
459 66704988 : signal[i] *= window_half[w];
460 : }
461 : }
462 : else
463 : {
464 : /* normal full/maximum overlap */
465 305222121 : for ( i = 0; i < window_length; i++ )
466 : {
467 304199336 : signal[i] *= window[i];
468 : }
469 : }
470 : }
471 :
472 4597706 : return;
473 : }
474 :
475 :
476 : /*-------------------------------------------------------------------*
477 : * tcx_windowing_synthesis_past_frame()
478 : *
479 : *
480 : *-------------------------------------------------------------------*/
481 :
482 4660551 : void tcx_windowing_synthesis_past_frame(
483 : float *signal, /* i/o: signal vector */
484 : const float *window, /* i : TCX window vector */
485 : const float *window_half, /* i : TCX window vector for half-overlap window */
486 : const float *window_min, /* i : TCX minimum overlap window */
487 : const int16_t window_length, /* i : TCX window length */
488 : const int16_t window_half_length, /* i : TCX half window length */
489 : const int16_t window_min_length, /* i : TCX minimum overlap length */
490 : const int16_t right_mode /* i : overlap mode (left_mode of current frame) */
491 : )
492 : {
493 : int16_t i, w;
494 :
495 4660551 : if ( right_mode == MIN_OVERLAP )
496 : {
497 : /* min. overlap */
498 110406653 : for ( i = ( window_length - window_min_length ) / 2, w = 0; w < window_min_length; i++, w++ )
499 : {
500 107857212 : signal[i] *= window_min[window_min_length - 1 - w];
501 : }
502 172064661 : for ( ; i < window_length; i++ )
503 : {
504 169515220 : signal[i] = 0.0f;
505 : }
506 : }
507 2111110 : else if ( right_mode == HALF_OVERLAP )
508 : {
509 : /* half OL */
510 86752744 : for ( i = ( window_length - window_half_length ) / 2, w = 0; w < window_half_length; i++, w++ )
511 : {
512 86065548 : signal[i] *= window_half[window_half_length - 1 - w];
513 : }
514 58064228 : for ( ; i < window_length; i++ )
515 : {
516 57377032 : signal[i] = 0.0f;
517 : }
518 : }
519 1423914 : else if ( right_mode == FULL_OVERLAP )
520 : {
521 : /* normal full/maximum overlap */
522 392189848 : for ( i = 0; i < window_length; i++ )
523 : {
524 390766306 : signal[i] *= window[window_length - 1 - i];
525 : }
526 : }
527 :
528 4660551 : return;
529 : }
530 :
531 :
532 : /*-------------------------------------------------------------------*
533 : * lpc2mdct()
534 : *
535 : *
536 : *-------------------------------------------------------------------*/
537 :
538 12521923 : void lpc2mdct(
539 : float *lpcCoeffs,
540 : const int16_t lpcOrder,
541 : float mdct_gains[],
542 : const int16_t length,
543 : const int16_t noInverse )
544 : {
545 : float RealData[2 * FDNS_NPTS], ImagData[2 * FDNS_NPTS];
546 : float tmp;
547 : int16_t i, sizeN;
548 :
549 12521923 : assert( length <= FDNS_NPTS );
550 :
551 12521923 : sizeN = 2 * length;
552 :
553 : /* ODFT */
554 225394614 : for ( i = 0; i < lpcOrder + 1; i++ )
555 : {
556 212872691 : tmp = (float) ( ( (float) i ) * EVS_PI / (float) ( sizeN ) );
557 212872691 : RealData[i] = (float) ( lpcCoeffs[i] * cos( tmp ) );
558 212872691 : ImagData[i] = (float) ( -lpcCoeffs[i] * sin( tmp ) );
559 : }
560 :
561 1402455376 : for ( ; i < sizeN; i++ )
562 : {
563 1389933453 : RealData[i] = 0.f;
564 1389933453 : ImagData[i] = 0.f;
565 : }
566 :
567 12521923 : DoFFT( RealData, ImagData, sizeN );
568 :
569 12521923 : if ( noInverse )
570 : {
571 0 : assert( !"not supported option in lpc2mdct()" );
572 : }
573 : else
574 : {
575 : /* Get amplitude */
576 813924995 : for ( i = 0; i < length; i++ )
577 : {
578 801403072 : mdct_gains[i] = (float) ( 1.0f / max( EPSILON, sqrt( RealData[i] * RealData[i] + ImagData[i] * ImagData[i] ) ) );
579 : }
580 : }
581 :
582 12521923 : return;
583 : }
584 :
585 :
586 : /*-------------------------------------------------------------------*
587 : * mdct_noiseShaping()
588 : *
589 : *
590 : *-------------------------------------------------------------------*/
591 :
592 12036420 : void mdct_noiseShaping(
593 : float x[],
594 : const int16_t lg,
595 : const float gains[],
596 : const int16_t nBands )
597 : {
598 : int16_t i, j, k, l;
599 : float g;
600 : int16_t m, n, k1, k2;
601 :
602 12036420 : j = 0;
603 12036420 : assert( nBands != 0 );
604 12036420 : k = lg / nBands;
605 12036420 : m = lg % nBands;
606 :
607 12036420 : if ( m )
608 : {
609 189624 : if ( m <= ( FDNS_NPTS / 2 ) )
610 : {
611 189624 : n = FDNS_NPTS / m;
612 189624 : k1 = k;
613 189624 : k2 = k + 1;
614 : }
615 : else
616 : {
617 0 : n = FDNS_NPTS / ( FDNS_NPTS - m );
618 0 : k1 = k + 1;
619 0 : k2 = k;
620 : }
621 :
622 12325560 : for ( i = 0; i < lg; )
623 : {
624 12135936 : if ( j % n )
625 : {
626 8940160 : k = k1;
627 : }
628 : else
629 : {
630 3195776 : k = k2;
631 : }
632 12135936 : g = gains[j++];
633 :
634 : /* Limit number of loops, if end is reached */
635 12135936 : k = min( k, lg - i );
636 :
637 91652736 : for ( l = 0; l < k; l++ )
638 : {
639 79516800 : x[i++] *= g;
640 : }
641 : }
642 : }
643 : else
644 : {
645 770041740 : for ( i = 0; i < lg; )
646 : {
647 758194944 : g = gains[j++];
648 :
649 5169099904 : for ( l = 0; l < k; l++ )
650 : {
651 4410904960 : x[i++] *= g;
652 : }
653 : }
654 : }
655 :
656 12036420 : return;
657 : }
658 :
659 :
660 : /*-------------------------------------------------------------------*
661 : * PsychAdaptLowFreqDeemph()
662 : *
663 : *
664 : *-------------------------------------------------------------------*/
665 :
666 1001710 : void PsychAdaptLowFreqDeemph(
667 : float x[],
668 : const float lpcGains[],
669 : float lf_deemph_factors[] )
670 : {
671 : int16_t i;
672 : float max_val, fac, tmp;
673 :
674 1001710 : max_val = tmp = lpcGains[0];
675 :
676 : /* find minimum (tmp) and maximum (max) of LPC gains in low frequencies */
677 9015390 : for ( i = 1; i < 9; i++ )
678 : {
679 8013680 : if ( tmp > lpcGains[i] )
680 : {
681 4940267 : tmp = lpcGains[i];
682 : }
683 8013680 : if ( max_val < lpcGains[i] )
684 : {
685 2341680 : max_val = lpcGains[i];
686 : }
687 : }
688 :
689 1001710 : tmp *= 32.0f;
690 :
691 1001710 : if ( ( max_val < tmp ) && ( tmp > FLT_MIN ) )
692 : {
693 997148 : fac = tmp = (float) pow( max_val / tmp, 0.0078125f );
694 :
695 997148 : if ( lf_deemph_factors )
696 : {
697 : /* gradual lowering of lowest 32 bins; DC is lowered by (max/tmp)^1/4 */
698 29527806 : for ( i = 31; i >= 0; i-- )
699 : {
700 28633024 : x[i] *= fac;
701 28633024 : lf_deemph_factors[i] *= fac;
702 28633024 : fac *= tmp;
703 : }
704 : }
705 : else
706 : {
707 : /* gradual lowering of lowest 32 bins; DC is lowered by (max/tmp)^1/4 */
708 3378078 : for ( i = 31; i >= 0; i-- )
709 : {
710 3275712 : x[i] *= fac;
711 3275712 : fac *= tmp;
712 : }
713 : }
714 : }
715 :
716 1001710 : return;
717 : }
718 :
719 :
720 : /*-------------------------------------------------------------------*
721 : * AdaptLowFreqDeemph()
722 : *
723 : *
724 : *-------------------------------------------------------------------*/
725 :
726 6252289 : void AdaptLowFreqDeemph(
727 : float x[],
728 : int16_t tcx_lpc_shaped_ari,
729 : const float lpcGains[],
730 : const int16_t lg,
731 : float lf_deemph_factors[] )
732 : {
733 : int16_t i, i_max_old, i_max;
734 :
735 6252289 : if ( !tcx_lpc_shaped_ari )
736 : {
737 : /* 1. find first magnitude maximum in lower quarter of spectrum */
738 5357507 : i_max = -1;
739 :
740 95202221 : for ( i = 0; i < lg / 4; i++ )
741 : {
742 94199733 : if ( ( x[i] <= -4.0f ) || ( x[i] >= 4.0f ) )
743 : {
744 4355019 : x[i] += ( x[i] < 0.0f ) ? 2.0f : -2.0f;
745 4355019 : i_max = i;
746 4355019 : break;
747 : }
748 : }
749 : /* 2. expand value range of all xi up to i_max: two extra steps */
750 :
751 18492225 : for ( i = 0; i < i_max; i++ )
752 : {
753 13134718 : x[i] *= 0.5f;
754 13134718 : lf_deemph_factors[i] *= 0.5f;
755 : }
756 : /* 3. find first magnitude maximum in lower quarter of spectrum */
757 5357507 : i_max_old = i_max;
758 :
759 5357507 : if ( i_max_old > -1 )
760 : {
761 4355019 : i_max = -1;
762 :
763 25665819 : for ( i = 0; i < lg / 4; i++ )
764 : {
765 25656531 : if ( ( x[i] <= -4.0f ) || ( x[i] >= 4.0f ) )
766 : {
767 4345731 : x[i] += ( x[i] < 0.0f ) ? 2.0f : -2.0f;
768 4345731 : i_max = i;
769 4345731 : break;
770 : }
771 : }
772 : }
773 : /* 4. expand value range of all xi up to i_max: two extra steps */
774 26004327 : for ( i = 0; i < i_max; i++ )
775 : {
776 20646820 : x[i] *= 0.5f;
777 20646820 : lf_deemph_factors[i] *= 0.5f;
778 : }
779 : /* 5. always expand two lines; lines could be at index 0 and 1! */
780 5357507 : if ( i_max < i_max_old )
781 : {
782 9288 : i_max = i_max_old;
783 : }
784 5357507 : i = i_max + 1;
785 5357507 : if ( x[i] < 0.0f )
786 : {
787 2013285 : if ( x[i] > -4.0f )
788 : {
789 719571 : lf_deemph_factors[i] *= 0.5f;
790 : }
791 2013285 : x[i] = ( x[i] <= -4.0f ) ? x[i] + 2.0f : x[i] * 0.5f;
792 : }
793 : else
794 : {
795 3344222 : if ( x[i] < 4.0f )
796 : {
797 2023505 : lf_deemph_factors[i] *= 0.5f;
798 : }
799 3344222 : x[i] = ( x[i] >= 4.0f ) ? x[i] - 2.0f : x[i] * 0.5f;
800 : }
801 5357507 : i++;
802 5357507 : if ( x[i] < 0.0f )
803 : {
804 1964299 : if ( x[i] > -4.0f )
805 : {
806 806209 : lf_deemph_factors[i] *= 0.5f;
807 : }
808 1964299 : x[i] = ( x[i] <= -4.0f ) ? x[i] + 2.0f : x[i] * 0.5f;
809 : }
810 : else
811 : {
812 3393208 : if ( x[i] < 4.0f )
813 : {
814 2218541 : lf_deemph_factors[i] *= 0.5f;
815 : }
816 3393208 : x[i] = ( x[i] >= 4.0f ) ? x[i] - 2.0f : x[i] * 0.5f;
817 : }
818 : }
819 : else
820 : {
821 894782 : PsychAdaptLowFreqDeemph( x, lpcGains, lf_deemph_factors );
822 : }
823 :
824 6252289 : return;
825 : }
826 :
827 :
828 : /*-------------------------------------------------------------------*
829 : * tcx_noise_filling()
830 : *
831 : *
832 : *-------------------------------------------------------------------*/
833 :
834 32547162 : void tcx_noise_filling(
835 : float *Q,
836 : const int16_t noiseFillSeed,
837 : const int16_t iFirstLine,
838 : const int16_t lowpassLine,
839 : const int16_t nTransWidth,
840 : const int16_t L_frame,
841 : const float tiltCompFactor,
842 : float fac_ns,
843 : uint8_t *infoTCXNoise,
844 : const int16_t element_mode /* i : IVAS element mode */
845 : )
846 : {
847 : int16_t i, m, segmentOffset;
848 : int16_t win; /* window coefficient */
849 : Word16 seed;
850 : float tilt_factor, nrg, tmp1, tmp2;
851 :
852 : /* 16-bit random number generator seed for generating filled lines */
853 32547162 : seed = (Word16) noiseFillSeed;
854 :
855 32547162 : tilt_factor = (float) pow( max( 0.375f, tiltCompFactor ), 1.0f / (float) L_frame );
856 32547162 : fac_ns /= (float) ( nTransWidth * nTransWidth );
857 :
858 : /* find last nonzero line below iFirstLine, use it as start offset */
859 32547162 : i = iFirstLine;
860 :
861 32547162 : if ( element_mode == IVAS_CPE_MDCT ) /* ... but only in mono or parametric stereo since it may cause binaural unmasking in discrete stereo */
862 : {
863 25033011 : segmentOffset = i;
864 : }
865 : else
866 : {
867 33082670 : for ( ; i > ( iFirstLine >> 1 ); i-- )
868 : {
869 32855494 : if ( Q[i] != 0.0f )
870 : {
871 7286975 : break;
872 : }
873 : }
874 :
875 7514151 : fac_ns *= (float) pow( tilt_factor, (float) i );
876 7514151 : segmentOffset = ++i;
877 : }
878 :
879 32547162 : nrg = 1e-9f;
880 32547162 : win = 0;
881 :
882 13352017926 : for ( ; i < lowpassLine; i++ )
883 : {
884 13319470764 : fac_ns *= tilt_factor;
885 :
886 13319470764 : if ( Q[i] != 0.0f )
887 : {
888 3104484014 : if ( win > 0 )
889 : {
890 : /* RMS-normalize current noise-filled segment */
891 1395921593 : tmp1 = (float) sqrt( ( i - segmentOffset ) / nrg );
892 1395921593 : tmp2 = tmp1 * (float) nTransWidth;
893 :
894 4285477697 : for ( m = segmentOffset; m < i - win; m++ )
895 : {
896 2889556104 : Q[m] *= tmp2;
897 : }
898 :
899 5303780527 : for ( ; win > 0; win-- )
900 : {
901 3907858934 : Q[m++] *= tmp1 * (float) win;
902 : }
903 1395921593 : nrg = 1e-9f; /* start new segment: reset noise segment energy */
904 : }
905 3104484014 : segmentOffset = i + 1;
906 : }
907 : else
908 : {
909 : /* line is zero, so fill line and update window and energy */
910 10214986750 : if ( win < nTransWidth )
911 : {
912 4090762678 : win++;
913 : }
914 10214986750 : tmp1 = (float) own_random( &seed );
915 10214986750 : nrg += tmp1 * tmp1; /* sum up energy of current noise segment */
916 10214986750 : Q[i] = tmp1 * (float) win * fac_ns;
917 :
918 10214986750 : if ( infoTCXNoise )
919 : {
920 : /* set noiseflags for IGF */
921 6186223052 : infoTCXNoise[i] = 1;
922 : }
923 : }
924 : }
925 :
926 32547162 : if ( win > 0 )
927 : {
928 : /* RMS-normalize uppermost noise-filled segment */
929 29928045 : tmp1 = (float) sqrt( ( lowpassLine - segmentOffset ) / nrg );
930 29928045 : tmp2 = tmp1 * (float) nTransWidth;
931 :
932 3447499757 : for ( m = segmentOffset; m < lowpassLine; m++ )
933 : {
934 3417571712 : Q[m] *= tmp2;
935 : }
936 : }
937 :
938 32547162 : return;
939 : }
940 :
941 :
942 : /*-------------------------------------------------------------------*
943 : * InitTnsConfigs()
944 : *
945 : *
946 : *-------------------------------------------------------------------*/
947 :
948 1205206 : void InitTnsConfigs(
949 : const int16_t bwidth,
950 : const int16_t L_frame,
951 : STnsConfig tnsConfig[2][2],
952 : const int16_t igfStopFreq,
953 : const int32_t total_brate,
954 : const int16_t element_mode,
955 : const int16_t MCT_flag )
956 : {
957 1205206 : if ( total_brate > ACELP_32k )
958 : {
959 926816 : InitTnsConfiguration( bwidth, L_frame / 2, &tnsConfig[0][0], igfStopFreq, total_brate, element_mode, MCT_flag );
960 : }
961 :
962 1205206 : InitTnsConfiguration( bwidth, L_frame, &tnsConfig[1][0], igfStopFreq, total_brate, element_mode, MCT_flag );
963 :
964 1205206 : InitTnsConfiguration( bwidth, L_frame + L_frame / 4, &tnsConfig[1][1], igfStopFreq, total_brate, element_mode, MCT_flag );
965 :
966 1205206 : return;
967 : }
968 :
969 :
970 : /*-------------------------------------------------------------------*
971 : * SetAllowTnsOnWhite
972 : *
973 : * set TNS config flag for possible application of TNS in the whitened domain
974 : *-------------------------------------------------------------------*/
975 :
976 1205206 : void SetAllowTnsOnWhite(
977 : STnsConfig tnsConfig[2][2], /* o : updated TNS configurations */
978 : const int8_t allowTnsOnWhite /* i : flag for TNS in whiteded domain mode */
979 : )
980 : {
981 1205206 : tnsConfig[0][0].allowTnsOnWhite = allowTnsOnWhite;
982 1205206 : tnsConfig[0][1].allowTnsOnWhite = allowTnsOnWhite;
983 1205206 : tnsConfig[1][0].allowTnsOnWhite = allowTnsOnWhite;
984 1205206 : tnsConfig[1][1].allowTnsOnWhite = allowTnsOnWhite;
985 :
986 1205206 : return;
987 : }
988 :
989 :
990 : /*-------------------------------------------------------------------*
991 : * SetTnsConfig()
992 : *
993 : *
994 : *-------------------------------------------------------------------*/
995 :
996 45955139 : void SetTnsConfig(
997 : TCX_CONFIG_HANDLE hTcxCfg,
998 : const int16_t isTCX20,
999 : const int16_t isAfterACELP )
1000 : {
1001 45955139 : hTcxCfg->pCurrentTnsConfig = &hTcxCfg->tnsConfig[isTCX20][isAfterACELP];
1002 45955139 : assert( hTcxCfg->pCurrentTnsConfig != NULL );
1003 :
1004 45955139 : return;
1005 : }
|