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 486728 : 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 486728 : if ( !fullband )
66 : {
67 : /* Left part */
68 :
69 108975 : if ( left_mode == TRANSITION_OVERLAP )
70 : {
71 : /* ACELP->TCX transition */
72 318 : *left_overlap = hTcxCfg->tcx_mdct_window_trans_length;
73 318 : *left_win = hTcxCfg->tcx_mdct_window_trans;
74 : }
75 108657 : else if ( left_mode == MIN_OVERLAP )
76 : {
77 2173 : *left_overlap = hTcxCfg->tcx_mdct_window_min_length;
78 2173 : *left_win = hTcxCfg->tcx_mdct_window_minimum;
79 : }
80 106484 : else if ( left_mode == HALF_OVERLAP )
81 : {
82 1744 : *left_overlap = hTcxCfg->tcx_mdct_window_half_length;
83 1744 : *left_win = hTcxCfg->tcx_mdct_window_half;
84 : }
85 104740 : else if ( left_mode == FULL_OVERLAP )
86 : {
87 104740 : *left_overlap = hTcxCfg->tcx_mdct_window_length;
88 104740 : *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 108975 : if ( right_mode == MIN_OVERLAP )
98 : {
99 2187 : *right_overlap = hTcxCfg->tcx_mdct_window_min_length;
100 2187 : *right_win = hTcxCfg->tcx_mdct_window_minimum;
101 : }
102 106788 : else if ( right_mode == HALF_OVERLAP )
103 : {
104 1747 : *right_overlap = hTcxCfg->tcx_mdct_window_half_length;
105 1747 : *right_win = hTcxCfg->tcx_mdct_window_half;
106 : }
107 105041 : else if ( right_mode == FULL_OVERLAP )
108 : {
109 105041 : *right_overlap = hTcxCfg->tcx_mdct_window_delay;
110 105041 : *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 377753 : if ( left_mode == TRANSITION_OVERLAP )
122 : {
123 : /* ACELP->TCX transition */
124 10968 : *left_overlap = hTcxCfg->tcx_mdct_window_trans_lengthFB;
125 10968 : *left_win = hTcxCfg->tcx_mdct_window_transFB;
126 : }
127 366785 : else if ( left_mode == MIN_OVERLAP )
128 : {
129 58742 : *left_overlap = hTcxCfg->tcx_mdct_window_min_lengthFB;
130 58742 : *left_win = hTcxCfg->tcx_mdct_window_minimumFB;
131 : }
132 308043 : else if ( left_mode == HALF_OVERLAP )
133 : {
134 14719 : *left_overlap = hTcxCfg->tcx_mdct_window_half_lengthFB;
135 14719 : *left_win = hTcxCfg->tcx_mdct_window_halfFB;
136 : }
137 293324 : else if ( left_mode == RECTANGULAR_OVERLAP )
138 : {
139 32860 : *left_overlap = 0;
140 32860 : *left_win = NULL;
141 : }
142 260464 : else if ( left_mode == FULL_OVERLAP )
143 : {
144 260464 : *left_overlap = hTcxCfg->tcx_mdct_window_lengthFB;
145 260464 : *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 377753 : if ( right_mode == MIN_OVERLAP )
155 : {
156 61754 : *right_overlap = hTcxCfg->tcx_mdct_window_min_lengthFB;
157 61754 : *right_win = hTcxCfg->tcx_mdct_window_minimumFB;
158 : }
159 315999 : else if ( right_mode == HALF_OVERLAP )
160 : {
161 15236 : *right_overlap = hTcxCfg->tcx_mdct_window_half_lengthFB;
162 15236 : *right_win = hTcxCfg->tcx_mdct_window_halfFB;
163 : }
164 300763 : else if ( right_mode == RECTANGULAR_OVERLAP )
165 : {
166 32841 : *right_overlap = 0;
167 32841 : *right_win = NULL;
168 : }
169 267922 : else if ( right_mode == FULL_OVERLAP )
170 : {
171 267922 : *right_overlap = hTcxCfg->tcx_mdct_window_delayFB;
172 267922 : *right_win = hTcxCfg->tcx_aldo_window_2_FB;
173 : }
174 : else
175 : {
176 0 : assert( !"Not supported overlap" );
177 : }
178 : }
179 :
180 486728 : return;
181 : }
182 :
183 : /*-------------------------------------------------------------------*
184 : * tcx_windowing_analysis()
185 : *
186 : *
187 : *-------------------------------------------------------------------*/
188 :
189 486697 : 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 139071869 : for ( w = 0; w < left_overlap; w++ )
203 : {
204 138585172 : *output++ = *signal++ * left_win[w];
205 : }
206 :
207 : /* Non overlapping region */
208 197677497 : for ( w = 0; w < L_frame - ( left_overlap + right_overlap ) / 2; w++ )
209 : {
210 197190800 : *output++ = *signal++;
211 : }
212 :
213 : /* Right overlap */
214 141706965 : for ( w = 0; w < right_overlap; w++ )
215 : {
216 141220268 : *output++ = *signal++ * right_win[right_overlap - 1 - w];
217 : }
218 :
219 486697 : return;
220 : }
221 :
222 :
223 : /*-------------------------------------------------------------------*
224 : * WindowSignal()
225 : *
226 : *
227 : *-------------------------------------------------------------------*/
228 :
229 486697 : 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 486697 : 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 486697 : if ( left_overlap_mode == TRANSITION_OVERLAP )
257 : {
258 : /* Increase frame size for 5ms */
259 11286 : if ( !fullband )
260 : {
261 318 : *L_frame += hTcxCfg->tcx5Size;
262 318 : offset = -hTcxCfg->tcx_mdct_window_trans_length / 2;
263 : }
264 : else
265 : {
266 10968 : *L_frame += hTcxCfg->tcx5SizeFB;
267 10968 : offset = -hTcxCfg->tcx_mdct_window_trans_lengthFB / 2;
268 : }
269 : }
270 :
271 : /*-----------------------------------------------------------*
272 : * Windowing *
273 : *-----------------------------------------------------------*/
274 :
275 486697 : tcx_windowing_analysis( in - l / 2 + offset, *L_frame, l, left_win, r, right_win, out );
276 :
277 486697 : if ( left_overlap_mode == FULL_OVERLAP && truncate_aldo )
278 : {
279 : /* fade truncated ALDO window to avoid discontinuities */
280 341967 : if ( !fullband )
281 : {
282 104740 : v_mult( out, hTcxCfg->tcx_mdct_window_minimum, out, hTcxCfg->tcx_mdct_window_min_length );
283 : }
284 : else
285 : {
286 237227 : v_mult( out, hTcxCfg->tcx_mdct_window_minimumFB, out, hTcxCfg->tcx_mdct_window_min_lengthFB );
287 : }
288 : }
289 :
290 486697 : *left_overlap_length = l;
291 486697 : *right_overlap_length = r;
292 :
293 486697 : return;
294 : }
295 :
296 :
297 : /*-------------------------------------------------------------------*
298 : * tcx_windowing_synthesis_current_frame()
299 : *
300 : *
301 : *-------------------------------------------------------------------*/
302 :
303 374967 : 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 374967 : overlap = window_length >> 1;
329 :
330 : /* Past-frame is TCX concealed as CNG and current-frame is TCX */
331 374967 : 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 374967 : else if ( left_rect == 1 && last_core_bfi == ACELP_CORE ) /* Rectangular window (past-frame is ACELP) */
351 : {
352 6765020 : for ( i = 0; i < overlap - acelp_mem_len; i++ )
353 : {
354 6701076 : signal[i] = 0;
355 : }
356 :
357 63944 : if ( fullbandScale == 0 )
358 : {
359 : /*OLA with ACELP*/
360 777617 : for ( i = 0; i < 2 * acelp_mem_len; i++ )
361 : {
362 : /*window decoded TCX with aliasing*/
363 741552 : signal[i + overlap - acelp_mem_len] *= window_trans[i];
364 : /*Time TDAC: 1)forward part of ACELP*/
365 741552 : 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 741552 : 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 613105 : for ( i = 0; i < M; i++ )
372 : {
373 577040 : 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 63944 : acelp_zir_len = 64;
379 :
380 63944 : if ( !fullbandScale )
381 : {
382 36065 : set_zero( acelp_zir, acelp_zir_len );
383 36065 : syn_filt( A_zir, M, acelp_zir, acelp_zir, acelp_zir_len, signal + overlap + acelp_mem_len - M, 0 );
384 : }
385 : else
386 : {
387 27879 : lerp( acelp_zir, tmp, acelp_zir_len * fullbandScale / FSCALE_DENOM, acelp_zir_len );
388 27879 : acelp_zir_len = acelp_zir_len * fullbandScale / FSCALE_DENOM;
389 27879 : acelp_zir = tmp;
390 :
391 27879 : if ( acelp_zir_len >= 2.0f * 64 )
392 : {
393 : /* apply a simple low-pass to the ZIR, to avoid potentially unmasked HF content */
394 4272789 : for ( i = 2; i < acelp_zir_len; i++ )
395 : {
396 4251402 : acelp_zir[i] = 0.25f * acelp_zir[i - 2] + 0.35f * acelp_zir[i - 1] + 0.40f * acelp_zir[i];
397 : }
398 21387 : 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 21387 : 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 4272789 : for ( i = acelp_zir_len - 3; i >= 0; i-- )
401 : {
402 4251402 : 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 7268488 : for ( i = 0; i < acelp_zir_len; i++ )
408 : {
409 : /*remove reconstructed ZIR and add ACELP ZIR*/
410 7204544 : signal[i + overlap + acelp_mem_len] -= acelp_zir[i] * (float) ( acelp_zir_len - i ) / (float) acelp_zir_len;
411 : }
412 : }
413 311023 : else if ( left_rect == 1 && last_core_bfi != 0 ) /* Rectangular window (past-frame is TCX) */
414 : {
415 271968 : for ( i = 0; i < overlap + acelp_mem_len; i++ )
416 : {
417 270048 : signal[i] = 0;
418 : }
419 474504 : for ( i = 0; i < window_length; i++ )
420 : {
421 472584 : signal[i + overlap + acelp_mem_len] *= window[i];
422 : }
423 : }
424 309103 : else if ( left_rect != 1 && last_core_bfi == 0 ) /* Normal window (past-frame is ACELP) */
425 : {
426 36348 : for ( i = 0; i < window_length; i++ )
427 : {
428 36204 : signal[i] *= window[i];
429 : }
430 :
431 36348 : for ( i = 0; i < window_length; i++ )
432 : {
433 36204 : signal[i] += syn_overl[i];
434 : }
435 : }
436 : else /* Normal window (past-frame is TCX) */
437 : {
438 308959 : if ( left_mode == 2 )
439 : {
440 : /* min. overlap */
441 8593525 : for ( i = 0; i < ( window_length - window_min_length ) / 2; i++ )
442 : {
443 8408196 : signal[i] = 0.0f;
444 : }
445 8159873 : for ( w = 0; w < window_min_length; i++, w++ )
446 : {
447 7974544 : signal[i] *= window_min[w];
448 : }
449 : }
450 123630 : else if ( left_mode == 3 )
451 : {
452 : /* half OL */
453 1069179 : for ( i = 0; i < ( window_length - window_half_length ) / 2; i++ )
454 : {
455 1024688 : signal[i] = 0.0f;
456 : }
457 5762515 : for ( w = 0; w < window_half_length; i++, w++ )
458 : {
459 5718024 : signal[i] *= window_half[w];
460 : }
461 : }
462 : else
463 : {
464 : /* normal full/maximum overlap */
465 24092051 : for ( i = 0; i < window_length; i++ )
466 : {
467 24012912 : signal[i] *= window[i];
468 : }
469 : }
470 : }
471 :
472 374967 : return;
473 : }
474 :
475 :
476 : /*-------------------------------------------------------------------*
477 : * tcx_windowing_synthesis_past_frame()
478 : *
479 : *
480 : *-------------------------------------------------------------------*/
481 :
482 379656 : 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 379656 : if ( right_mode == MIN_OVERLAP )
496 : {
497 : /* min. overlap */
498 8690694 : for ( i = ( window_length - window_min_length ) / 2, w = 0; w < window_min_length; i++, w++ )
499 : {
500 8493824 : signal[i] *= window_min[window_min_length - 1 - w];
501 : }
502 13438910 : for ( ; i < window_length; i++ )
503 : {
504 13242040 : signal[i] = 0.0f;
505 : }
506 : }
507 182786 : else if ( right_mode == HALF_OVERLAP )
508 : {
509 : /* half OL */
510 6518639 : for ( i = ( window_length - window_half_length ) / 2, w = 0; w < window_half_length; i++, w++ )
511 : {
512 6467736 : signal[i] *= window_half[window_half_length - 1 - w];
513 : }
514 4362727 : for ( ; i < window_length; i++ )
515 : {
516 4311824 : signal[i] = 0.0f;
517 : }
518 : }
519 131883 : else if ( right_mode == FULL_OVERLAP )
520 : {
521 : /* normal full/maximum overlap */
522 36256783 : for ( i = 0; i < window_length; i++ )
523 : {
524 36124900 : signal[i] *= window[window_length - 1 - i];
525 : }
526 : }
527 :
528 379656 : return;
529 : }
530 :
531 :
532 : /*-------------------------------------------------------------------*
533 : * lpc2mdct()
534 : *
535 : *
536 : *-------------------------------------------------------------------*/
537 :
538 1287206 : 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 1287206 : assert( length <= FDNS_NPTS );
550 :
551 1287206 : sizeN = 2 * length;
552 :
553 : /* ODFT */
554 23169708 : for ( i = 0; i < lpcOrder + 1; i++ )
555 : {
556 21882502 : tmp = (float) ( ( (float) i ) * EVS_PI / (float) ( sizeN ) );
557 21882502 : RealData[i] = (float) ( lpcCoeffs[i] * cos( tmp ) );
558 21882502 : ImagData[i] = (float) ( -lpcCoeffs[i] * sin( tmp ) );
559 : }
560 :
561 144167072 : for ( ; i < sizeN; i++ )
562 : {
563 142879866 : RealData[i] = 0.f;
564 142879866 : ImagData[i] = 0.f;
565 : }
566 :
567 1287206 : DoFFT( RealData, ImagData, sizeN );
568 :
569 1287206 : 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 83668390 : for ( i = 0; i < length; i++ )
580 : {
581 82381184 : mdct_gains[i] = (float) ( 1.0f / max( EPSILON, sqrt( RealData[i] * RealData[i] + ImagData[i] * ImagData[i] ) ) );
582 : }
583 : }
584 :
585 1287206 : return;
586 : }
587 :
588 :
589 : /*-------------------------------------------------------------------*
590 : * mdct_noiseShaping()
591 : *
592 : *
593 : *-------------------------------------------------------------------*/
594 :
595 1264517 : 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 1264517 : j = 0;
606 1264517 : assert( nBands != 0 );
607 1264517 : k = lg / nBands;
608 1264517 : m = lg % nBands;
609 :
610 1264517 : if ( m )
611 : {
612 17014 : if ( m <= ( FDNS_NPTS / 2 ) )
613 : {
614 17014 : n = FDNS_NPTS / m;
615 17014 : k1 = k;
616 17014 : 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 1105910 : for ( i = 0; i < lg; )
626 : {
627 1088896 : if ( j % n )
628 : {
629 800608 : k = k1;
630 : }
631 : else
632 : {
633 288288 : k = k2;
634 : }
635 1088896 : g = gains[j++];
636 :
637 : /* Limit number of loops, if end is reached */
638 1088896 : k = min( k, lg - i );
639 :
640 8224416 : for ( l = 0; l < k; l++ )
641 : {
642 7135520 : x[i++] *= g;
643 : }
644 : }
645 : }
646 : else
647 : {
648 81087695 : for ( i = 0; i < lg; )
649 : {
650 79840192 : g = gains[j++];
651 :
652 581903040 : for ( l = 0; l < k; l++ )
653 : {
654 502062848 : x[i++] *= g;
655 : }
656 : }
657 : }
658 :
659 1264517 : return;
660 : }
661 :
662 :
663 : /*-------------------------------------------------------------------*
664 : * PsychAdaptLowFreqDeemph()
665 : *
666 : *
667 : *-------------------------------------------------------------------*/
668 :
669 83034 : 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 83034 : max_val = tmp = lpcGains[0];
678 :
679 : /* find minimum (tmp) and maximum (max) of LPC gains in low frequencies */
680 747306 : for ( i = 1; i < 9; i++ )
681 : {
682 664272 : if ( tmp > lpcGains[i] )
683 : {
684 497470 : tmp = lpcGains[i];
685 : }
686 664272 : if ( max_val < lpcGains[i] )
687 : {
688 117559 : max_val = lpcGains[i];
689 : }
690 : }
691 :
692 83034 : tmp *= 32.0f;
693 :
694 83034 : if ( ( max_val < tmp ) && ( tmp > FLT_MIN ) )
695 : {
696 83034 : fac = tmp = (float) pow( max_val / tmp, 0.0078125f );
697 :
698 83034 : if ( lf_deemph_factors )
699 : {
700 : /* gradual lowering of lowest 32 bins; DC is lowered by (max/tmp)^1/4 */
701 2257695 : for ( i = 31; i >= 0; i-- )
702 : {
703 2189280 : x[i] *= fac;
704 2189280 : lf_deemph_factors[i] *= fac;
705 2189280 : fac *= tmp;
706 : }
707 : }
708 : else
709 : {
710 : /* gradual lowering of lowest 32 bins; DC is lowered by (max/tmp)^1/4 */
711 482427 : for ( i = 31; i >= 0; i-- )
712 : {
713 467808 : x[i] *= fac;
714 467808 : fac *= tmp;
715 : }
716 : }
717 : }
718 :
719 83034 : return;
720 : }
721 :
722 :
723 : /*-------------------------------------------------------------------*
724 : * AdaptLowFreqDeemph()
725 : *
726 : *
727 : *-------------------------------------------------------------------*/
728 :
729 505316 : 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 505316 : if ( !tcx_lpc_shaped_ari )
739 : {
740 : /* 1. find first magnitude maximum in lower quarter of spectrum */
741 436901 : i_max = -1;
742 :
743 2674371 : for ( i = 0; i < lg / 4; i++ )
744 : {
745 2658455 : if ( ( x[i] <= -4.0f ) || ( x[i] >= 4.0f ) )
746 : {
747 420985 : x[i] += ( x[i] < 0.0f ) ? 2.0f : -2.0f;
748 420985 : i_max = i;
749 420985 : break;
750 : }
751 : }
752 : /* 2. expand value range of all xi up to i_max: two extra steps */
753 :
754 1475987 : for ( i = 0; i < i_max; i++ )
755 : {
756 1039086 : x[i] *= 0.5f;
757 1039086 : lf_deemph_factors[i] *= 0.5f;
758 : }
759 : /* 3. find first magnitude maximum in lower quarter of spectrum */
760 436901 : i_max_old = i_max;
761 :
762 436901 : if ( i_max_old > -1 )
763 : {
764 420985 : i_max = -1;
765 :
766 2156611 : for ( i = 0; i < lg / 4; i++ )
767 : {
768 2156547 : if ( ( x[i] <= -4.0f ) || ( x[i] >= 4.0f ) )
769 : {
770 420921 : x[i] += ( x[i] < 0.0f ) ? 2.0f : -2.0f;
771 420921 : i_max = i;
772 420921 : break;
773 : }
774 : }
775 : }
776 : /* 4. expand value range of all xi up to i_max: two extra steps */
777 2167663 : for ( i = 0; i < i_max; i++ )
778 : {
779 1730762 : x[i] *= 0.5f;
780 1730762 : lf_deemph_factors[i] *= 0.5f;
781 : }
782 : /* 5. always expand two lines; lines could be at index 0 and 1! */
783 436901 : if ( i_max < i_max_old )
784 : {
785 64 : i_max = i_max_old;
786 : }
787 436901 : i = i_max + 1;
788 436901 : if ( x[i] < 0.0f )
789 : {
790 192945 : if ( x[i] > -4.0f )
791 : {
792 68881 : lf_deemph_factors[i] *= 0.5f;
793 : }
794 192945 : x[i] = ( x[i] <= -4.0f ) ? x[i] + 2.0f : x[i] * 0.5f;
795 : }
796 : else
797 : {
798 243956 : if ( x[i] < 4.0f )
799 : {
800 115928 : lf_deemph_factors[i] *= 0.5f;
801 : }
802 243956 : x[i] = ( x[i] >= 4.0f ) ? x[i] - 2.0f : x[i] * 0.5f;
803 : }
804 436901 : i++;
805 436901 : if ( x[i] < 0.0f )
806 : {
807 186233 : if ( x[i] > -4.0f )
808 : {
809 73570 : lf_deemph_factors[i] *= 0.5f;
810 : }
811 186233 : x[i] = ( x[i] <= -4.0f ) ? x[i] + 2.0f : x[i] * 0.5f;
812 : }
813 : else
814 : {
815 250668 : if ( x[i] < 4.0f )
816 : {
817 139102 : lf_deemph_factors[i] *= 0.5f;
818 : }
819 250668 : x[i] = ( x[i] >= 4.0f ) ? x[i] - 2.0f : x[i] * 0.5f;
820 : }
821 : }
822 : else
823 : {
824 68415 : PsychAdaptLowFreqDeemph( x, lpcGains, lf_deemph_factors );
825 : }
826 :
827 505316 : return;
828 : }
829 :
830 :
831 : /*-------------------------------------------------------------------*
832 : * tcx_noise_filling()
833 : *
834 : *
835 : *-------------------------------------------------------------------*/
836 :
837 2709633 : 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 2709633 : seed = (Word16) noiseFillSeed;
857 :
858 2709633 : tilt_factor = (float) pow( max( 0.375f, tiltCompFactor ), 1.0f / (float) L_frame );
859 2709633 : fac_ns /= (float) ( nTransWidth * nTransWidth );
860 :
861 : /* find last nonzero line below iFirstLine, use it as start offset */
862 2709633 : i = iFirstLine;
863 :
864 2709633 : if ( element_mode == IVAS_CPE_MDCT ) /* ... but only in mono or parametric stereo since it may cause binaural unmasking in discrete stereo */
865 : {
866 1846692 : segmentOffset = i;
867 : }
868 : else
869 : {
870 2557853 : for ( ; i > ( iFirstLine >> 1 ); i-- )
871 : {
872 2552950 : if ( Q[i] != 0.0f )
873 : {
874 858038 : break;
875 : }
876 : }
877 :
878 862941 : fac_ns *= (float) pow( tilt_factor, (float) i );
879 862941 : segmentOffset = ++i;
880 : }
881 :
882 2709633 : nrg = 1e-9f;
883 2709633 : win = 0;
884 :
885 1173140130 : for ( ; i < lowpassLine; i++ )
886 : {
887 1170430497 : fac_ns *= tilt_factor;
888 :
889 1170430497 : if ( Q[i] != 0.0f )
890 : {
891 276622291 : if ( win > 0 )
892 : {
893 : /* RMS-normalize current noise-filled segment */
894 129466023 : tmp1 = (float) sqrt( ( i - segmentOffset ) / nrg );
895 129466023 : tmp2 = tmp1 * (float) nTransWidth;
896 :
897 330629923 : for ( m = segmentOffset; m < i - win; m++ )
898 : {
899 201163900 : Q[m] *= tmp2;
900 : }
901 :
902 511679503 : for ( ; win > 0; win-- )
903 : {
904 382213480 : Q[m++] *= tmp1 * (float) win;
905 : }
906 129466023 : nrg = 1e-9f; /* start new segment: reset noise segment energy */
907 : }
908 276622291 : segmentOffset = i + 1;
909 : }
910 : else
911 : {
912 : /* line is zero, so fill line and update window and energy */
913 893808206 : if ( win < nTransWidth )
914 : {
915 399779644 : win++;
916 : }
917 893808206 : tmp1 = (float) own_random( &seed );
918 893808206 : nrg += tmp1 * tmp1; /* sum up energy of current noise segment */
919 893808206 : Q[i] = tmp1 * (float) win * fac_ns;
920 :
921 893808206 : if ( infoTCXNoise )
922 : {
923 : /* set noiseflags for IGF */
924 498873828 : infoTCXNoise[i] = 1;
925 : }
926 : }
927 : }
928 :
929 2709633 : if ( win > 0 )
930 : {
931 : /* RMS-normalize uppermost noise-filled segment */
932 2516728 : tmp1 = (float) sqrt( ( lowpassLine - segmentOffset ) / nrg );
933 2516728 : tmp2 = tmp1 * (float) nTransWidth;
934 :
935 312947554 : for ( m = segmentOffset; m < lowpassLine; m++ )
936 : {
937 310430826 : Q[m] *= tmp2;
938 : }
939 : }
940 :
941 2709633 : return;
942 : }
943 :
944 :
945 : /*-------------------------------------------------------------------*
946 : * InitTnsConfigs()
947 : *
948 : *
949 : *-------------------------------------------------------------------*/
950 :
951 89048 : 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 89048 : if ( total_brate > ACELP_32k )
961 : {
962 68408 : InitTnsConfiguration( bwidth, L_frame / 2, &tnsConfig[0][0], igfStopFreq, total_brate, element_mode, MCT_flag );
963 : }
964 :
965 89048 : InitTnsConfiguration( bwidth, L_frame, &tnsConfig[1][0], igfStopFreq, total_brate, element_mode, MCT_flag );
966 :
967 89048 : InitTnsConfiguration( bwidth, L_frame + L_frame / 4, &tnsConfig[1][1], igfStopFreq, total_brate, element_mode, MCT_flag );
968 :
969 89048 : 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 89048 : 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 89048 : tnsConfig[0][0].allowTnsOnWhite = allowTnsOnWhite;
985 89048 : tnsConfig[0][1].allowTnsOnWhite = allowTnsOnWhite;
986 89048 : tnsConfig[1][0].allowTnsOnWhite = allowTnsOnWhite;
987 89048 : tnsConfig[1][1].allowTnsOnWhite = allowTnsOnWhite;
988 :
989 89048 : return;
990 : }
991 :
992 :
993 : /*-------------------------------------------------------------------*
994 : * SetTnsConfig()
995 : *
996 : *
997 : *-------------------------------------------------------------------*/
998 :
999 3642774 : void SetTnsConfig(
1000 : TCX_CONFIG_HANDLE hTcxCfg,
1001 : const int16_t isTCX20,
1002 : const int16_t isAfterACELP )
1003 : {
1004 3642774 : hTcxCfg->pCurrentTnsConfig = &hTcxCfg->tnsConfig[isTCX20][isAfterACELP];
1005 3642774 : assert( hTcxCfg->pCurrentTnsConfig != NULL );
1006 :
1007 3642774 : return;
1008 : }
|