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 5966587 : 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 5966587 : if ( !fullband )
66 : {
67 : /* Left part */
68 :
69 900008 : if ( left_mode == TRANSITION_OVERLAP )
70 : {
71 : /* ACELP->TCX transition */
72 3801 : *left_overlap = hTcxCfg->tcx_mdct_window_trans_length;
73 3801 : *left_win = hTcxCfg->tcx_mdct_window_trans;
74 : }
75 896207 : else if ( left_mode == MIN_OVERLAP )
76 : {
77 13933 : *left_overlap = hTcxCfg->tcx_mdct_window_min_length;
78 13933 : *left_win = hTcxCfg->tcx_mdct_window_minimum;
79 : }
80 882274 : else if ( left_mode == HALF_OVERLAP )
81 : {
82 8195 : *left_overlap = hTcxCfg->tcx_mdct_window_half_length;
83 8195 : *left_win = hTcxCfg->tcx_mdct_window_half;
84 : }
85 874079 : else if ( left_mode == FULL_OVERLAP )
86 : {
87 874079 : *left_overlap = hTcxCfg->tcx_mdct_window_length;
88 874079 : *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 900008 : if ( right_mode == MIN_OVERLAP )
98 : {
99 14049 : *right_overlap = hTcxCfg->tcx_mdct_window_min_length;
100 14049 : *right_win = hTcxCfg->tcx_mdct_window_minimum;
101 : }
102 885959 : else if ( right_mode == HALF_OVERLAP )
103 : {
104 8478 : *right_overlap = hTcxCfg->tcx_mdct_window_half_length;
105 8478 : *right_win = hTcxCfg->tcx_mdct_window_half;
106 : }
107 877481 : else if ( right_mode == FULL_OVERLAP )
108 : {
109 877481 : *right_overlap = hTcxCfg->tcx_mdct_window_delay;
110 877481 : *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 5066579 : if ( left_mode == TRANSITION_OVERLAP )
122 : {
123 : /* ACELP->TCX transition */
124 131164 : *left_overlap = hTcxCfg->tcx_mdct_window_trans_lengthFB;
125 131164 : *left_win = hTcxCfg->tcx_mdct_window_transFB;
126 : }
127 4935415 : else if ( left_mode == MIN_OVERLAP )
128 : {
129 888092 : *left_overlap = hTcxCfg->tcx_mdct_window_min_lengthFB;
130 888092 : *left_win = hTcxCfg->tcx_mdct_window_minimumFB;
131 : }
132 4047323 : else if ( left_mode == HALF_OVERLAP )
133 : {
134 193485 : *left_overlap = hTcxCfg->tcx_mdct_window_half_lengthFB;
135 193485 : *left_win = hTcxCfg->tcx_mdct_window_halfFB;
136 : }
137 3853838 : else if ( left_mode == RECTANGULAR_OVERLAP )
138 : {
139 494713 : *left_overlap = 0;
140 494713 : *left_win = NULL;
141 : }
142 3359125 : else if ( left_mode == FULL_OVERLAP )
143 : {
144 3359125 : *left_overlap = hTcxCfg->tcx_mdct_window_lengthFB;
145 3359125 : *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 5066579 : if ( right_mode == MIN_OVERLAP )
155 : {
156 934231 : *right_overlap = hTcxCfg->tcx_mdct_window_min_lengthFB;
157 934231 : *right_win = hTcxCfg->tcx_mdct_window_minimumFB;
158 : }
159 4132348 : else if ( right_mode == HALF_OVERLAP )
160 : {
161 240140 : *right_overlap = hTcxCfg->tcx_mdct_window_half_lengthFB;
162 240140 : *right_win = hTcxCfg->tcx_mdct_window_halfFB;
163 : }
164 3892208 : else if ( right_mode == RECTANGULAR_OVERLAP )
165 : {
166 494619 : *right_overlap = 0;
167 494619 : *right_win = NULL;
168 : }
169 3397589 : else if ( right_mode == FULL_OVERLAP )
170 : {
171 3397589 : *right_overlap = hTcxCfg->tcx_mdct_window_delayFB;
172 3397589 : *right_win = hTcxCfg->tcx_aldo_window_2_FB;
173 : }
174 : else
175 : {
176 0 : assert( !"Not supported overlap" );
177 : }
178 : }
179 :
180 5966587 : return;
181 : }
182 :
183 : /*-------------------------------------------------------------------*
184 : * tcx_windowing_analysis()
185 : *
186 : *
187 : *-------------------------------------------------------------------*/
188 :
189 5966385 : 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 1570544623 : for ( w = 0; w < left_overlap; w++ )
203 : {
204 1564578238 : *output++ = *signal++ * left_win[w];
205 : }
206 :
207 : /* Non overlapping region */
208 2260625465 : for ( w = 0; w < L_frame - ( left_overlap + right_overlap ) / 2; w++ )
209 : {
210 2254659080 : *output++ = *signal++;
211 : }
212 :
213 : /* Right overlap */
214 1590425971 : for ( w = 0; w < right_overlap; w++ )
215 : {
216 1584459586 : *output++ = *signal++ * right_win[right_overlap - 1 - w];
217 : }
218 :
219 5966385 : return;
220 : }
221 :
222 :
223 : /*-------------------------------------------------------------------*
224 : * WindowSignal()
225 : *
226 : *
227 : *-------------------------------------------------------------------*/
228 :
229 5966385 : 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 5966385 : 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 5966385 : if ( left_overlap_mode == TRANSITION_OVERLAP )
257 : {
258 : /* Increase frame size for 5ms */
259 134965 : if ( !fullband )
260 : {
261 3801 : *L_frame += hTcxCfg->tcx5Size;
262 3801 : offset = -hTcxCfg->tcx_mdct_window_trans_length / 2;
263 : }
264 : else
265 : {
266 131164 : *L_frame += hTcxCfg->tcx5SizeFB;
267 131164 : offset = -hTcxCfg->tcx_mdct_window_trans_lengthFB / 2;
268 : }
269 : }
270 :
271 : /*-----------------------------------------------------------*
272 : * Windowing *
273 : *-----------------------------------------------------------*/
274 :
275 5966385 : tcx_windowing_analysis( in - l / 2 + offset, *L_frame, l, left_win, r, right_win, out );
276 :
277 5966385 : if ( left_overlap_mode == FULL_OVERLAP && truncate_aldo )
278 : {
279 : /* fade truncated ALDO window to avoid discontinuities */
280 3861015 : if ( !fullband )
281 : {
282 874079 : v_mult( out, hTcxCfg->tcx_mdct_window_minimum, out, hTcxCfg->tcx_mdct_window_min_length );
283 : }
284 : else
285 : {
286 2986936 : v_mult( out, hTcxCfg->tcx_mdct_window_minimumFB, out, hTcxCfg->tcx_mdct_window_min_lengthFB );
287 : }
288 : }
289 :
290 5966385 : *left_overlap_length = l;
291 5966385 : *right_overlap_length = r;
292 :
293 5966385 : return;
294 : }
295 :
296 :
297 : /*-------------------------------------------------------------------*
298 : * tcx_windowing_synthesis_current_frame()
299 : *
300 : *
301 : *-------------------------------------------------------------------*/
302 :
303 4441873 : 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 4441873 : overlap = window_length >> 1;
329 :
330 : /* Past-frame is TCX concealed as CNG and current-frame is TCX */
331 4441873 : 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 4441873 : else if ( left_rect == 1 && last_core_bfi == ACELP_CORE ) /* Rectangular window (past-frame is ACELP) */
351 : {
352 48916948 : for ( i = 0; i < overlap - acelp_mem_len; i++ )
353 : {
354 48402642 : signal[i] = 0;
355 : }
356 :
357 514306 : if ( fullbandScale == 0 )
358 : {
359 : /*OLA with ACELP*/
360 6433313 : for ( i = 0; i < 2 * acelp_mem_len; i++ )
361 : {
362 : /*window decoded TCX with aliasing*/
363 6131884 : signal[i + overlap - acelp_mem_len] *= window_trans[i];
364 : /*Time TDAC: 1)forward part of ACELP*/
365 6131884 : 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 6131884 : 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 5124293 : for ( i = 0; i < M; i++ )
372 : {
373 4822864 : 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 514306 : acelp_zir_len = 64;
379 :
380 514306 : if ( !fullbandScale )
381 : {
382 301429 : set_zero( acelp_zir, acelp_zir_len );
383 301429 : syn_filt( A_zir, M, acelp_zir, acelp_zir, acelp_zir_len, signal + overlap + acelp_mem_len - M, 0 );
384 : }
385 : else
386 : {
387 212877 : lerp( acelp_zir, tmp, acelp_zir_len * fullbandScale / FSCALE_DENOM, acelp_zir_len );
388 212877 : acelp_zir_len = acelp_zir_len * fullbandScale / FSCALE_DENOM;
389 212877 : acelp_zir = tmp;
390 :
391 212877 : if ( acelp_zir_len >= 2.0f * 64 )
392 : {
393 : /* apply a simple low-pass to the ZIR, to avoid potentially unmasked HF content */
394 26693941 : for ( i = 2; i < acelp_zir_len; i++ )
395 : {
396 26548938 : acelp_zir[i] = 0.25f * acelp_zir[i - 2] + 0.35f * acelp_zir[i - 1] + 0.40f * acelp_zir[i];
397 : }
398 145003 : 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 145003 : 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 26693941 : for ( i = acelp_zir_len - 3; i >= 0; i-- )
401 : {
402 26548938 : 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 52240154 : for ( i = 0; i < acelp_zir_len; i++ )
408 : {
409 : /*remove reconstructed ZIR and add ACELP ZIR*/
410 51725848 : signal[i + overlap + acelp_mem_len] -= acelp_zir[i] * (float) ( acelp_zir_len - i ) / (float) acelp_zir_len;
411 : }
412 : }
413 3927567 : else if ( left_rect == 1 && last_core_bfi != 0 ) /* Rectangular window (past-frame is TCX) */
414 : {
415 5653966 : for ( i = 0; i < overlap + acelp_mem_len; i++ )
416 : {
417 5611552 : signal[i] = 0;
418 : }
419 9862630 : for ( i = 0; i < window_length; i++ )
420 : {
421 9820216 : signal[i + overlap + acelp_mem_len] *= window[i];
422 : }
423 : }
424 3885153 : else if ( left_rect != 1 && last_core_bfi == 0 ) /* Normal window (past-frame is ACELP) */
425 : {
426 506454 : for ( i = 0; i < window_length; i++ )
427 : {
428 504476 : signal[i] *= window[i];
429 : }
430 :
431 506454 : for ( i = 0; i < window_length; i++ )
432 : {
433 504476 : signal[i] += syn_overl[i];
434 : }
435 : }
436 : else /* Normal window (past-frame is TCX) */
437 : {
438 3883175 : if ( left_mode == 2 )
439 : {
440 : /* min. overlap */
441 102397923 : for ( i = 0; i < ( window_length - window_min_length ) / 2; i++ )
442 : {
443 100086036 : signal[i] = 0.0f;
444 : }
445 91495883 : for ( w = 0; w < window_min_length; i++, w++ )
446 : {
447 89183996 : signal[i] *= window_min[w];
448 : }
449 : }
450 1571288 : else if ( left_mode == 3 )
451 : {
452 : /* half OL */
453 6192419 : for ( i = 0; i < ( window_length - window_half_length ) / 2; i++ )
454 : {
455 5735840 : signal[i] = 0.0f;
456 : }
457 52853967 : for ( w = 0; w < window_half_length; i++, w++ )
458 : {
459 52397388 : signal[i] *= window_half[w];
460 : }
461 : }
462 : else
463 : {
464 : /* normal full/maximum overlap */
465 299031349 : for ( i = 0; i < window_length; i++ )
466 : {
467 297916640 : signal[i] *= window[i];
468 : }
469 : }
470 : }
471 :
472 4441873 : return;
473 : }
474 :
475 :
476 : /*-------------------------------------------------------------------*
477 : * tcx_windowing_synthesis_past_frame()
478 : *
479 : *
480 : *-------------------------------------------------------------------*/
481 :
482 4489113 : 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 4489113 : if ( right_mode == MIN_OVERLAP )
496 : {
497 : /* min. overlap */
498 96264394 : for ( i = ( window_length - window_min_length ) / 2, w = 0; w < window_min_length; i++, w++ )
499 : {
500 93830248 : signal[i] *= window_min[window_min_length - 1 - w];
501 : }
502 146756350 : for ( ; i < window_length; i++ )
503 : {
504 144322204 : signal[i] = 0.0f;
505 : }
506 : }
507 2054967 : else if ( right_mode == HALF_OVERLAP )
508 : {
509 : /* half OL */
510 76377766 : for ( i = ( window_length - window_half_length ) / 2, w = 0; w < window_half_length; i++, w++ )
511 : {
512 75703080 : signal[i] *= window_half[window_half_length - 1 - w];
513 : }
514 51143406 : for ( ; i < window_length; i++ )
515 : {
516 50468720 : signal[i] = 0.0f;
517 : }
518 : }
519 1380281 : else if ( right_mode == FULL_OVERLAP )
520 : {
521 : /* normal full/maximum overlap */
522 348258787 : for ( i = 0; i < window_length; i++ )
523 : {
524 346878854 : signal[i] *= window[window_length - 1 - i];
525 : }
526 : }
527 :
528 4489113 : return;
529 : }
530 :
531 :
532 : /*-------------------------------------------------------------------*
533 : * lpc2mdct()
534 : *
535 : *
536 : *-------------------------------------------------------------------*/
537 :
538 12831197 : 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 12831197 : assert( length <= FDNS_NPTS );
550 :
551 12831197 : sizeN = 2 * length;
552 :
553 : /* ODFT */
554 230961546 : for ( i = 0; i < lpcOrder + 1; i++ )
555 : {
556 218130349 : tmp = (float) ( ( (float) i ) * EVS_PI / (float) ( sizeN ) );
557 218130349 : RealData[i] = (float) ( lpcCoeffs[i] * cos( tmp ) );
558 218130349 : ImagData[i] = (float) ( -lpcCoeffs[i] * sin( tmp ) );
559 : }
560 :
561 1437094064 : for ( ; i < sizeN; i++ )
562 : {
563 1424262867 : RealData[i] = 0.f;
564 1424262867 : ImagData[i] = 0.f;
565 : }
566 :
567 12831197 : DoFFT( RealData, ImagData, sizeN );
568 :
569 12831197 : if ( noInverse )
570 : {
571 0 : for ( i = 0; i < length; i++ )
572 : {
573 0 : mdct_gains[i] = (float) ( sqrt( RealData[i] * RealData[i] + ImagData[i] * ImagData[i] ) );
574 : }
575 : }
576 : else
577 : /* Get amplitude */
578 : {
579 834027805 : for ( i = 0; i < length; i++ )
580 : {
581 821196608 : mdct_gains[i] = (float) ( 1.0f / max( EPSILON, sqrt( RealData[i] * RealData[i] + ImagData[i] * ImagData[i] ) ) );
582 : }
583 : }
584 :
585 12831197 : return;
586 : }
587 :
588 :
589 : /*-------------------------------------------------------------------*
590 : * mdct_noiseShaping()
591 : *
592 : *
593 : *-------------------------------------------------------------------*/
594 :
595 12336262 : void mdct_noiseShaping(
596 : float x[],
597 : const int16_t lg,
598 : const float gains[],
599 : const int16_t nBands )
600 : {
601 : int16_t i, j, k, l;
602 : float g;
603 : int16_t m, n, k1, k2;
604 :
605 12336262 : j = 0;
606 12336262 : assert( nBands != 0 );
607 12336262 : k = lg / nBands;
608 12336262 : m = lg % nBands;
609 :
610 12336262 : if ( m )
611 : {
612 218706 : if ( m <= ( FDNS_NPTS / 2 ) )
613 : {
614 218706 : n = FDNS_NPTS / m;
615 218706 : k1 = k;
616 218706 : k2 = k + 1;
617 : }
618 : else
619 : {
620 0 : n = FDNS_NPTS / ( FDNS_NPTS - m );
621 0 : k1 = k + 1;
622 0 : k2 = k;
623 : }
624 :
625 14215890 : for ( i = 0; i < lg; )
626 : {
627 13997184 : if ( j % n )
628 : {
629 9889504 : k = k1;
630 : }
631 : else
632 : {
633 4107680 : k = k2;
634 : }
635 13997184 : g = gains[j++];
636 :
637 : /* Limit number of loops, if end is reached */
638 13997184 : k = min( k, lg - i );
639 :
640 96195104 : for ( l = 0; l < k; l++ )
641 : {
642 82197920 : x[i++] *= g;
643 : }
644 : }
645 : }
646 : else
647 : {
648 787641140 : for ( i = 0; i < lg; )
649 : {
650 775523584 : g = gains[j++];
651 :
652 5219947648 : for ( l = 0; l < k; l++ )
653 : {
654 4444424064 : x[i++] *= g;
655 : }
656 : }
657 : }
658 :
659 12336262 : return;
660 : }
661 :
662 :
663 : /*-------------------------------------------------------------------*
664 : * PsychAdaptLowFreqDeemph()
665 : *
666 : *
667 : *-------------------------------------------------------------------*/
668 :
669 1016198 : void PsychAdaptLowFreqDeemph(
670 : float x[],
671 : const float lpcGains[],
672 : float lf_deemph_factors[] )
673 : {
674 : int16_t i;
675 : float max_val, fac, tmp;
676 :
677 1016198 : max_val = tmp = lpcGains[0];
678 :
679 : /* find minimum (tmp) and maximum (max) of LPC gains in low frequencies */
680 9145782 : for ( i = 1; i < 9; i++ )
681 : {
682 8129584 : if ( tmp > lpcGains[i] )
683 : {
684 5322174 : tmp = lpcGains[i];
685 : }
686 8129584 : if ( max_val < lpcGains[i] )
687 : {
688 1968183 : max_val = lpcGains[i];
689 : }
690 : }
691 :
692 1016198 : tmp *= 32.0f;
693 :
694 1016198 : if ( ( max_val < tmp ) && ( tmp > FLT_MIN ) )
695 : {
696 1013910 : fac = tmp = (float) pow( max_val / tmp, 0.0078125f );
697 :
698 1013910 : if ( lf_deemph_factors )
699 : {
700 : /* gradual lowering of lowest 32 bins; DC is lowered by (max/tmp)^1/4 */
701 20957937 : for ( i = 31; i >= 0; i-- )
702 : {
703 20322848 : x[i] *= fac;
704 20322848 : lf_deemph_factors[i] *= fac;
705 20322848 : fac *= tmp;
706 : }
707 : }
708 : else
709 : {
710 : /* gradual lowering of lowest 32 bins; DC is lowered by (max/tmp)^1/4 */
711 12501093 : for ( i = 31; i >= 0; i-- )
712 : {
713 12122272 : x[i] *= fac;
714 12122272 : fac *= tmp;
715 : }
716 : }
717 : }
718 :
719 1016198 : return;
720 : }
721 :
722 :
723 : /*-------------------------------------------------------------------*
724 : * AdaptLowFreqDeemph()
725 : *
726 : *
727 : *-------------------------------------------------------------------*/
728 :
729 5683595 : void AdaptLowFreqDeemph(
730 : float x[],
731 : int16_t tcx_lpc_shaped_ari,
732 : const float lpcGains[],
733 : const int16_t lg,
734 : float lf_deemph_factors[] )
735 : {
736 : int16_t i, i_max_old, i_max;
737 :
738 5683595 : if ( !tcx_lpc_shaped_ari )
739 : {
740 : /* 1. find first magnitude maximum in lower quarter of spectrum */
741 5048506 : i_max = -1;
742 :
743 57195007 : for ( i = 0; i < lg / 4; i++ )
744 : {
745 56665398 : if ( ( x[i] <= -4.0f ) || ( x[i] >= 4.0f ) )
746 : {
747 4518897 : x[i] += ( x[i] < 0.0f ) ? 2.0f : -2.0f;
748 4518897 : i_max = i;
749 4518897 : break;
750 : }
751 : }
752 : /* 2. expand value range of all xi up to i_max: two extra steps */
753 :
754 16710927 : for ( i = 0; i < i_max; i++ )
755 : {
756 11662421 : x[i] *= 0.5f;
757 11662421 : lf_deemph_factors[i] *= 0.5f;
758 : }
759 : /* 3. find first magnitude maximum in lower quarter of spectrum */
760 5048506 : i_max_old = i_max;
761 :
762 5048506 : if ( i_max_old > -1 )
763 : {
764 4518897 : i_max = -1;
765 :
766 23831310 : for ( i = 0; i < lg / 4; i++ )
767 : {
768 23826079 : if ( ( x[i] <= -4.0f ) || ( x[i] >= 4.0f ) )
769 : {
770 4513666 : x[i] += ( x[i] < 0.0f ) ? 2.0f : -2.0f;
771 4513666 : i_max = i;
772 4513666 : break;
773 : }
774 : }
775 : }
776 : /* 4. expand value range of all xi up to i_max: two extra steps */
777 23985379 : for ( i = 0; i < i_max; i++ )
778 : {
779 18936873 : x[i] *= 0.5f;
780 18936873 : lf_deemph_factors[i] *= 0.5f;
781 : }
782 : /* 5. always expand two lines; lines could be at index 0 and 1! */
783 5048506 : if ( i_max < i_max_old )
784 : {
785 5231 : i_max = i_max_old;
786 : }
787 5048506 : i = i_max + 1;
788 5048506 : if ( x[i] < 0.0f )
789 : {
790 2056876 : if ( x[i] > -4.0f )
791 : {
792 745702 : lf_deemph_factors[i] *= 0.5f;
793 : }
794 2056876 : x[i] = ( x[i] <= -4.0f ) ? x[i] + 2.0f : x[i] * 0.5f;
795 : }
796 : else
797 : {
798 2991630 : if ( x[i] < 4.0f )
799 : {
800 1619448 : lf_deemph_factors[i] *= 0.5f;
801 : }
802 2991630 : x[i] = ( x[i] >= 4.0f ) ? x[i] - 2.0f : x[i] * 0.5f;
803 : }
804 5048506 : i++;
805 5048506 : if ( x[i] < 0.0f )
806 : {
807 2027843 : if ( x[i] > -4.0f )
808 : {
809 857683 : lf_deemph_factors[i] *= 0.5f;
810 : }
811 2027843 : x[i] = ( x[i] <= -4.0f ) ? x[i] + 2.0f : x[i] * 0.5f;
812 : }
813 : else
814 : {
815 3020663 : if ( x[i] < 4.0f )
816 : {
817 1882577 : lf_deemph_factors[i] *= 0.5f;
818 : }
819 3020663 : x[i] = ( x[i] >= 4.0f ) ? x[i] - 2.0f : x[i] * 0.5f;
820 : }
821 : }
822 : else
823 : {
824 635089 : PsychAdaptLowFreqDeemph( x, lpcGains, lf_deemph_factors );
825 : }
826 :
827 5683595 : return;
828 : }
829 :
830 :
831 : /*-------------------------------------------------------------------*
832 : * tcx_noise_filling()
833 : *
834 : *
835 : *-------------------------------------------------------------------*/
836 :
837 27877808 : void tcx_noise_filling(
838 : float *Q,
839 : const int16_t noiseFillSeed,
840 : const int16_t iFirstLine,
841 : const int16_t lowpassLine,
842 : const int16_t nTransWidth,
843 : const int16_t L_frame,
844 : const float tiltCompFactor,
845 : float fac_ns,
846 : uint8_t *infoTCXNoise,
847 : const int16_t element_mode /* i : IVAS element mode */
848 : )
849 : {
850 : int16_t i, m, segmentOffset;
851 : int16_t win; /* window coefficient */
852 : Word16 seed;
853 : float tilt_factor, nrg, tmp1, tmp2;
854 :
855 : /* 16-bit random number generator seed for generating filled lines */
856 27877808 : seed = (Word16) noiseFillSeed;
857 :
858 27877808 : tilt_factor = (float) pow( max( 0.375f, tiltCompFactor ), 1.0f / (float) L_frame );
859 27877808 : fac_ns /= (float) ( nTransWidth * nTransWidth );
860 :
861 : /* find last nonzero line below iFirstLine, use it as start offset */
862 27877808 : i = iFirstLine;
863 :
864 27877808 : if ( element_mode == IVAS_CPE_MDCT ) /* ... but only in mono or parametric stereo since it may cause binaural unmasking in discrete stereo */
865 : {
866 20378182 : segmentOffset = i;
867 : }
868 : else
869 : {
870 26980848 : for ( ; i > ( iFirstLine >> 1 ); i-- )
871 : {
872 26853741 : if ( Q[i] != 0.0f )
873 : {
874 7372519 : break;
875 : }
876 : }
877 :
878 7499626 : fac_ns *= (float) pow( tilt_factor, (float) i );
879 7499626 : segmentOffset = ++i;
880 : }
881 :
882 27877808 : nrg = 1e-9f;
883 27877808 : win = 0;
884 :
885 11002705241 : for ( ; i < lowpassLine; i++ )
886 : {
887 10974827433 : fac_ns *= tilt_factor;
888 :
889 10974827433 : if ( Q[i] != 0.0f )
890 : {
891 2720785640 : if ( win > 0 )
892 : {
893 : /* RMS-normalize current noise-filled segment */
894 1192789546 : tmp1 = (float) sqrt( ( i - segmentOffset ) / nrg );
895 1192789546 : tmp2 = tmp1 * (float) nTransWidth;
896 :
897 3297385214 : for ( m = segmentOffset; m < i - win; m++ )
898 : {
899 2104595668 : Q[m] *= tmp2;
900 : }
901 :
902 4593140815 : for ( ; win > 0; win-- )
903 : {
904 3400351269 : Q[m++] *= tmp1 * (float) win;
905 : }
906 1192789546 : nrg = 1e-9f; /* start new segment: reset noise segment energy */
907 : }
908 2720785640 : segmentOffset = i + 1;
909 : }
910 : else
911 : {
912 : /* line is zero, so fill line and update window and energy */
913 8254041793 : if ( win < nTransWidth )
914 : {
915 3562005362 : win++;
916 : }
917 8254041793 : tmp1 = (float) own_random( &seed );
918 8254041793 : nrg += tmp1 * tmp1; /* sum up energy of current noise segment */
919 8254041793 : Q[i] = tmp1 * (float) win * fac_ns;
920 :
921 8254041793 : if ( infoTCXNoise )
922 : {
923 : /* set noiseflags for IGF */
924 4179483879 : infoTCXNoise[i] = 1;
925 : }
926 : }
927 : }
928 :
929 27877808 : if ( win > 0 )
930 : {
931 : /* RMS-normalize uppermost noise-filled segment */
932 25147850 : tmp1 = (float) sqrt( ( lowpassLine - segmentOffset ) / nrg );
933 25147850 : tmp2 = tmp1 * (float) nTransWidth;
934 :
935 2774242706 : for ( m = segmentOffset; m < lowpassLine; m++ )
936 : {
937 2749094856 : Q[m] *= tmp2;
938 : }
939 : }
940 :
941 27877808 : return;
942 : }
943 :
944 :
945 : /*-------------------------------------------------------------------*
946 : * InitTnsConfigs()
947 : *
948 : *
949 : *-------------------------------------------------------------------*/
950 :
951 1069972 : void InitTnsConfigs(
952 : const int16_t bwidth,
953 : const int16_t L_frame,
954 : STnsConfig tnsConfig[2][2],
955 : const int16_t igfStopFreq,
956 : const int32_t total_brate,
957 : const int16_t element_mode,
958 : const int16_t MCT_flag )
959 : {
960 1069972 : if ( total_brate > ACELP_32k )
961 : {
962 834186 : InitTnsConfiguration( bwidth, L_frame / 2, &tnsConfig[0][0], igfStopFreq, total_brate, element_mode, MCT_flag );
963 : }
964 :
965 1069972 : InitTnsConfiguration( bwidth, L_frame, &tnsConfig[1][0], igfStopFreq, total_brate, element_mode, MCT_flag );
966 :
967 1069972 : InitTnsConfiguration( bwidth, L_frame + L_frame / 4, &tnsConfig[1][1], igfStopFreq, total_brate, element_mode, MCT_flag );
968 :
969 1069972 : return;
970 : }
971 :
972 :
973 : /*-------------------------------------------------------------------*
974 : * SetAllowTnsOnWhite
975 : *
976 : * set TNS config flag for possible application of TNS in the whitened domain
977 : *-------------------------------------------------------------------*/
978 :
979 1069972 : void SetAllowTnsOnWhite(
980 : STnsConfig tnsConfig[2][2], /* o : updated TNS configurations */
981 : const int8_t allowTnsOnWhite /* i : flag for TNS in whiteded domain mode */
982 : )
983 : {
984 1069972 : tnsConfig[0][0].allowTnsOnWhite = allowTnsOnWhite;
985 1069972 : tnsConfig[0][1].allowTnsOnWhite = allowTnsOnWhite;
986 1069972 : tnsConfig[1][0].allowTnsOnWhite = allowTnsOnWhite;
987 1069972 : tnsConfig[1][1].allowTnsOnWhite = allowTnsOnWhite;
988 :
989 1069972 : return;
990 : }
991 :
992 :
993 : /*-------------------------------------------------------------------*
994 : * SetTnsConfig()
995 : *
996 : *
997 : *-------------------------------------------------------------------*/
998 :
999 41707384 : void SetTnsConfig(
1000 : TCX_CONFIG_HANDLE hTcxCfg,
1001 : const int16_t isTCX20,
1002 : const int16_t isAfterACELP )
1003 : {
1004 41707384 : hTcxCfg->pCurrentTnsConfig = &hTcxCfg->tnsConfig[isTCX20][isAfterACELP];
1005 41707384 : assert( hTcxCfg->pCurrentTnsConfig != NULL );
1006 :
1007 41707384 : return;
1008 : }
|