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 1333738 : 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 1333738 : if ( !fullband )
66 : {
67 : /* Left part */
68 :
69 210537 : if ( left_mode == TRANSITION_OVERLAP )
70 : {
71 : /* ACELP->TCX transition */
72 426 : *left_overlap = hTcxCfg->tcx_mdct_window_trans_length;
73 426 : *left_win = hTcxCfg->tcx_mdct_window_trans;
74 : }
75 210111 : else if ( left_mode == MIN_OVERLAP )
76 : {
77 3793 : *left_overlap = hTcxCfg->tcx_mdct_window_min_length;
78 3793 : *left_win = hTcxCfg->tcx_mdct_window_minimum;
79 : }
80 206318 : else if ( left_mode == HALF_OVERLAP )
81 : {
82 2932 : *left_overlap = hTcxCfg->tcx_mdct_window_half_length;
83 2932 : *left_win = hTcxCfg->tcx_mdct_window_half;
84 : }
85 203386 : else if ( left_mode == FULL_OVERLAP )
86 : {
87 203386 : *left_overlap = hTcxCfg->tcx_mdct_window_length;
88 203386 : *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 210537 : if ( right_mode == MIN_OVERLAP )
98 : {
99 3808 : *right_overlap = hTcxCfg->tcx_mdct_window_min_length;
100 3808 : *right_win = hTcxCfg->tcx_mdct_window_minimum;
101 : }
102 206729 : else if ( right_mode == HALF_OVERLAP )
103 : {
104 3080 : *right_overlap = hTcxCfg->tcx_mdct_window_half_length;
105 3080 : *right_win = hTcxCfg->tcx_mdct_window_half;
106 : }
107 203649 : else if ( right_mode == FULL_OVERLAP )
108 : {
109 203649 : *right_overlap = hTcxCfg->tcx_mdct_window_delay;
110 203649 : *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 1123201 : if ( left_mode == TRANSITION_OVERLAP )
122 : {
123 : /* ACELP->TCX transition */
124 20930 : *left_overlap = hTcxCfg->tcx_mdct_window_trans_lengthFB;
125 20930 : *left_win = hTcxCfg->tcx_mdct_window_transFB;
126 : }
127 1102271 : else if ( left_mode == MIN_OVERLAP )
128 : {
129 214753 : *left_overlap = hTcxCfg->tcx_mdct_window_min_lengthFB;
130 214753 : *left_win = hTcxCfg->tcx_mdct_window_minimumFB;
131 : }
132 887518 : else if ( left_mode == HALF_OVERLAP )
133 : {
134 73281 : *left_overlap = hTcxCfg->tcx_mdct_window_half_lengthFB;
135 73281 : *left_win = hTcxCfg->tcx_mdct_window_halfFB;
136 : }
137 814237 : else if ( left_mode == RECTANGULAR_OVERLAP )
138 : {
139 133509 : *left_overlap = 0;
140 133509 : *left_win = NULL;
141 : }
142 680728 : else if ( left_mode == FULL_OVERLAP )
143 : {
144 680728 : *left_overlap = hTcxCfg->tcx_mdct_window_lengthFB;
145 680728 : *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 1123201 : if ( right_mode == MIN_OVERLAP )
155 : {
156 214738 : *right_overlap = hTcxCfg->tcx_mdct_window_min_lengthFB;
157 214738 : *right_win = hTcxCfg->tcx_mdct_window_minimumFB;
158 : }
159 908463 : else if ( right_mode == HALF_OVERLAP )
160 : {
161 121599 : *right_overlap = hTcxCfg->tcx_mdct_window_half_lengthFB;
162 121599 : *right_win = hTcxCfg->tcx_mdct_window_halfFB;
163 : }
164 786864 : else if ( right_mode == RECTANGULAR_OVERLAP )
165 : {
166 133488 : *right_overlap = 0;
167 133488 : *right_win = NULL;
168 : }
169 653376 : else if ( right_mode == FULL_OVERLAP )
170 : {
171 653376 : *right_overlap = hTcxCfg->tcx_mdct_window_delayFB;
172 653376 : *right_win = hTcxCfg->tcx_aldo_window_2_FB;
173 : }
174 : else
175 : {
176 0 : assert( !"Not supported overlap" );
177 : }
178 : }
179 :
180 1333738 : return;
181 : }
182 :
183 : /*-------------------------------------------------------------------*
184 : * tcx_windowing_analysis()
185 : *
186 : *
187 : *-------------------------------------------------------------------*/
188 :
189 1333693 : 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 330738507 : for ( w = 0; w < left_overlap; w++ )
203 : {
204 329404814 : *output++ = *signal++ * left_win[w];
205 : }
206 :
207 : /* Non overlapping region */
208 471888769 : for ( w = 0; w < L_frame - ( left_overlap + right_overlap ) / 2; w++ )
209 : {
210 470555076 : *output++ = *signal++;
211 : }
212 :
213 : /* Right overlap */
214 326979639 : for ( w = 0; w < right_overlap; w++ )
215 : {
216 325645946 : *output++ = *signal++ * right_win[right_overlap - 1 - w];
217 : }
218 :
219 1333693 : return;
220 : }
221 :
222 :
223 : /*-------------------------------------------------------------------*
224 : * WindowSignal()
225 : *
226 : *
227 : *-------------------------------------------------------------------*/
228 :
229 1333693 : 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 1333693 : 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 1333693 : if ( left_overlap_mode == TRANSITION_OVERLAP )
257 : {
258 : /* Increase frame size for 5ms */
259 21356 : if ( !fullband )
260 : {
261 426 : *L_frame += hTcxCfg->tcx5Size;
262 426 : offset = -hTcxCfg->tcx_mdct_window_trans_length / 2;
263 : }
264 : else
265 : {
266 20930 : *L_frame += hTcxCfg->tcx5SizeFB;
267 20930 : offset = -hTcxCfg->tcx_mdct_window_trans_lengthFB / 2;
268 : }
269 : }
270 :
271 : /*-----------------------------------------------------------*
272 : * Windowing *
273 : *-----------------------------------------------------------*/
274 :
275 1333693 : tcx_windowing_analysis( in - l / 2 + offset, *L_frame, l, left_win, r, right_win, out );
276 :
277 1333693 : if ( left_overlap_mode == FULL_OVERLAP && truncate_aldo )
278 : {
279 : /* fade truncated ALDO window to avoid discontinuities */
280 774585 : if ( !fullband )
281 : {
282 203386 : v_mult( out, hTcxCfg->tcx_mdct_window_minimum, out, hTcxCfg->tcx_mdct_window_min_length );
283 : }
284 : else
285 : {
286 571199 : v_mult( out, hTcxCfg->tcx_mdct_window_minimumFB, out, hTcxCfg->tcx_mdct_window_min_lengthFB );
287 : }
288 : }
289 :
290 1333693 : *left_overlap_length = l;
291 1333693 : *right_overlap_length = r;
292 :
293 1333693 : return;
294 : }
295 :
296 :
297 : /*-------------------------------------------------------------------*
298 : * tcx_windowing_synthesis_current_frame()
299 : *
300 : *
301 : *-------------------------------------------------------------------*/
302 :
303 2640126 : 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 2640126 : overlap = window_length >> 1;
329 :
330 : /* Past-frame is TCX concealed as CNG and current-frame is TCX */
331 2640126 : 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 2640126 : else if ( left_rect == 1 && last_core_bfi == ACELP_CORE ) /* Rectangular window (past-frame is ACELP) */
351 : {
352 22184638 : for ( i = 0; i < overlap - acelp_mem_len; i++ )
353 : {
354 21948336 : signal[i] = 0;
355 : }
356 :
357 236302 : if ( fullbandScale == 0 )
358 : {
359 : /*OLA with ACELP*/
360 2574141 : for ( i = 0; i < 2 * acelp_mem_len; i++ )
361 : {
362 : /*window decoded TCX with aliasing*/
363 2447072 : signal[i + overlap - acelp_mem_len] *= window_trans[i];
364 : /*Time TDAC: 1)forward part of ACELP*/
365 2447072 : 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 2447072 : 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 2160173 : for ( i = 0; i < M; i++ )
372 : {
373 2033104 : 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 236302 : acelp_zir_len = 64;
379 :
380 236302 : if ( !fullbandScale )
381 : {
382 127069 : set_zero( acelp_zir, acelp_zir_len );
383 127069 : syn_filt( A_zir, M, acelp_zir, acelp_zir, acelp_zir_len, signal + overlap + acelp_mem_len - M, 0 );
384 : }
385 : else
386 : {
387 109233 : lerp( acelp_zir, tmp, acelp_zir_len * fullbandScale / FSCALE_DENOM, acelp_zir_len );
388 109233 : acelp_zir_len = acelp_zir_len * fullbandScale / FSCALE_DENOM;
389 109233 : acelp_zir = tmp;
390 :
391 109233 : if ( acelp_zir_len >= 2.0f * 64 )
392 : {
393 : /* apply a simple low-pass to the ZIR, to avoid potentially unmasked HF content */
394 14058108 : for ( i = 2; i < acelp_zir_len; i++ )
395 : {
396 13981688 : acelp_zir[i] = 0.25f * acelp_zir[i - 2] + 0.35f * acelp_zir[i - 1] + 0.40f * acelp_zir[i];
397 : }
398 76420 : 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 76420 : 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 14058108 : for ( i = acelp_zir_len - 3; i >= 0; i-- )
401 : {
402 13981688 : 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 25014150 : for ( i = 0; i < acelp_zir_len; i++ )
408 : {
409 : /*remove reconstructed ZIR and add ACELP ZIR*/
410 24777848 : signal[i + overlap + acelp_mem_len] -= acelp_zir[i] * (float) ( acelp_zir_len - i ) / (float) acelp_zir_len;
411 : }
412 : }
413 2403824 : else if ( left_rect == 1 && last_core_bfi != 0 ) /* Rectangular window (past-frame is TCX) */
414 : {
415 3761946 : for ( i = 0; i < overlap + acelp_mem_len; i++ )
416 : {
417 3734496 : signal[i] = 0;
418 : }
419 6562818 : for ( i = 0; i < window_length; i++ )
420 : {
421 6535368 : signal[i + overlap + acelp_mem_len] *= window[i];
422 : }
423 : }
424 2376374 : else if ( left_rect != 1 && last_core_bfi == 0 ) /* Normal window (past-frame is ACELP) */
425 : {
426 47976 : for ( i = 0; i < window_length; i++ )
427 : {
428 47796 : signal[i] *= window[i];
429 : }
430 :
431 47976 : for ( i = 0; i < window_length; i++ )
432 : {
433 47796 : signal[i] += syn_overl[i];
434 : }
435 : }
436 : else /* Normal window (past-frame is TCX) */
437 : {
438 2376194 : if ( left_mode == 2 )
439 : {
440 : /* min. overlap */
441 66354925 : for ( i = 0; i < ( window_length - window_min_length ) / 2; i++ )
442 : {
443 64970392 : signal[i] = 0.0f;
444 : }
445 53228225 : for ( w = 0; w < window_min_length; i++, w++ )
446 : {
447 51843692 : signal[i] *= window_min[w];
448 : }
449 : }
450 991661 : else if ( left_mode == 3 )
451 : {
452 : /* half OL */
453 1863147 : for ( i = 0; i < ( window_length - window_half_length ) / 2; i++ )
454 : {
455 1620632 : signal[i] = 0.0f;
456 : }
457 28083643 : for ( w = 0; w < window_half_length; i++, w++ )
458 : {
459 27841128 : signal[i] *= window_half[w];
460 : }
461 : }
462 : else
463 : {
464 : /* normal full/maximum overlap */
465 195937594 : for ( i = 0; i < window_length; i++ )
466 : {
467 195188448 : signal[i] *= window[i];
468 : }
469 : }
470 : }
471 :
472 2640126 : return;
473 : }
474 :
475 :
476 : /*-------------------------------------------------------------------*
477 : * tcx_windowing_synthesis_past_frame()
478 : *
479 : *
480 : *-------------------------------------------------------------------*/
481 :
482 2651630 : 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 2651630 : if ( right_mode == MIN_OVERLAP )
496 : {
497 : /* min. overlap */
498 54947248 : for ( i = ( window_length - window_min_length ) / 2, w = 0; w < window_min_length; i++, w++ )
499 : {
500 53514704 : signal[i] *= window_min[window_min_length - 1 - w];
501 : }
502 81203376 : for ( ; i < window_length; i++ )
503 : {
504 79770832 : signal[i] = 0.0f;
505 : }
506 : }
507 1219086 : else if ( right_mode == HALF_OVERLAP )
508 : {
509 : /* half OL */
510 48433064 : for ( i = ( window_length - window_half_length ) / 2, w = 0; w < window_half_length; i++, w++ )
511 : {
512 48007500 : signal[i] *= window_half[window_half_length - 1 - w];
513 : }
514 32430564 : for ( ; i < window_length; i++ )
515 : {
516 32005000 : signal[i] = 0.0f;
517 : }
518 : }
519 793522 : else if ( right_mode == FULL_OVERLAP )
520 : {
521 : /* normal full/maximum overlap */
522 198395598 : for ( i = 0; i < window_length; i++ )
523 : {
524 197602076 : signal[i] *= window[window_length - 1 - i];
525 : }
526 : }
527 :
528 2651630 : return;
529 : }
530 :
531 :
532 : /*-------------------------------------------------------------------*
533 : * lpc2mdct()
534 : *
535 : *
536 : *-------------------------------------------------------------------*/
537 :
538 4821851 : 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 4821851 : assert( length <= FDNS_NPTS );
550 :
551 4821851 : sizeN = 2 * length;
552 :
553 : /* ODFT */
554 86793318 : for ( i = 0; i < lpcOrder + 1; i++ )
555 : {
556 81971467 : tmp = (float) ( ( (float) i ) * EVS_PI / (float) ( sizeN ) );
557 81971467 : RealData[i] = (float) ( lpcCoeffs[i] * cos( tmp ) );
558 81971467 : ImagData[i] = (float) ( -lpcCoeffs[i] * sin( tmp ) );
559 : }
560 :
561 540047312 : for ( ; i < sizeN; i++ )
562 : {
563 535225461 : RealData[i] = 0.f;
564 535225461 : ImagData[i] = 0.f;
565 : }
566 :
567 4821851 : DoFFT( RealData, ImagData, sizeN );
568 :
569 4821851 : if ( noInverse )
570 : {
571 0 : assert( !"not supported option in lpc2mdct()" );
572 : }
573 : else
574 : {
575 : /* Get amplitude */
576 313420315 : for ( i = 0; i < length; i++ )
577 : {
578 308598464 : mdct_gains[i] = (float) ( 1.0f / max( EPSILON, sqrt( RealData[i] * RealData[i] + ImagData[i] * ImagData[i] ) ) );
579 : }
580 : }
581 :
582 4821851 : return;
583 : }
584 :
585 :
586 : /*-------------------------------------------------------------------*
587 : * mdct_noiseShaping()
588 : *
589 : *
590 : *-------------------------------------------------------------------*/
591 :
592 4851613 : 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 4851613 : j = 0;
603 4851613 : assert( nBands != 0 );
604 4851613 : k = lg / nBands;
605 4851613 : m = lg % nBands;
606 :
607 4851613 : if ( m )
608 : {
609 109086 : if ( m <= ( FDNS_NPTS / 2 ) )
610 : {
611 109086 : n = FDNS_NPTS / m;
612 109086 : k1 = k;
613 109086 : 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 7090590 : for ( i = 0; i < lg; )
623 : {
624 6981504 : if ( j % n )
625 : {
626 4709632 : k = k1;
627 : }
628 : else
629 : {
630 2271872 : k = k2;
631 : }
632 6981504 : g = gains[j++];
633 :
634 : /* Limit number of loops, if end is reached */
635 6981504 : k = min( k, lg - i );
636 :
637 43600384 : for ( l = 0; l < k; l++ )
638 : {
639 36618880 : x[i++] *= g;
640 : }
641 : }
642 : }
643 : else
644 : {
645 308264255 : for ( i = 0; i < lg; )
646 : {
647 303521728 : g = gains[j++];
648 :
649 2152036992 : for ( l = 0; l < k; l++ )
650 : {
651 1848515264 : x[i++] *= g;
652 : }
653 : }
654 : }
655 :
656 4851613 : return;
657 : }
658 :
659 :
660 : /*-------------------------------------------------------------------*
661 : * PsychAdaptLowFreqDeemph()
662 : *
663 : *
664 : *-------------------------------------------------------------------*/
665 :
666 543301 : 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 543301 : max_val = tmp = lpcGains[0];
675 :
676 : /* find minimum (tmp) and maximum (max) of LPC gains in low frequencies */
677 4889709 : for ( i = 1; i < 9; i++ )
678 : {
679 4346408 : if ( tmp > lpcGains[i] )
680 : {
681 2931994 : tmp = lpcGains[i];
682 : }
683 4346408 : if ( max_val < lpcGains[i] )
684 : {
685 893530 : max_val = lpcGains[i];
686 : }
687 : }
688 :
689 543301 : tmp *= 32.0f;
690 :
691 543301 : if ( ( max_val < tmp ) && ( tmp > FLT_MIN ) )
692 : {
693 543301 : fac = tmp = (float) pow( max_val / tmp, 0.0078125f );
694 :
695 543301 : if ( lf_deemph_factors )
696 : {
697 : /* gradual lowering of lowest 32 bins; DC is lowered by (max/tmp)^1/4 */
698 6592509 : for ( i = 31; i >= 0; i-- )
699 : {
700 6392736 : x[i] *= fac;
701 6392736 : lf_deemph_factors[i] *= fac;
702 6392736 : fac *= tmp;
703 : }
704 : }
705 : else
706 : {
707 : /* gradual lowering of lowest 32 bins; DC is lowered by (max/tmp)^1/4 */
708 11336424 : for ( i = 31; i >= 0; i-- )
709 : {
710 10992896 : x[i] *= fac;
711 10992896 : fac *= tmp;
712 : }
713 : }
714 : }
715 :
716 543301 : return;
717 : }
718 :
719 :
720 : /*-------------------------------------------------------------------*
721 : * AdaptLowFreqDeemph()
722 : *
723 : *
724 : *-------------------------------------------------------------------*/
725 :
726 2214952 : 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 2214952 : if ( !tcx_lpc_shaped_ari )
736 : {
737 : /* 1. find first magnitude maximum in lower quarter of spectrum */
738 2015179 : i_max = -1;
739 :
740 8500207 : for ( i = 0; i < lg / 4; i++ )
741 : {
742 8463738 : if ( ( x[i] <= -4.0f ) || ( x[i] >= 4.0f ) )
743 : {
744 1978710 : x[i] += ( x[i] < 0.0f ) ? 2.0f : -2.0f;
745 1978710 : i_max = i;
746 1978710 : break;
747 : }
748 : }
749 : /* 2. expand value range of all xi up to i_max: two extra steps */
750 :
751 5688531 : for ( i = 0; i < i_max; i++ )
752 : {
753 3673352 : x[i] *= 0.5f;
754 3673352 : lf_deemph_factors[i] *= 0.5f;
755 : }
756 : /* 3. find first magnitude maximum in lower quarter of spectrum */
757 2015179 : i_max_old = i_max;
758 :
759 2015179 : if ( i_max_old > -1 )
760 : {
761 1978710 : i_max = -1;
762 :
763 8546652 : for ( i = 0; i < lg / 4; i++ )
764 : {
765 8546585 : if ( ( x[i] <= -4.0f ) || ( x[i] >= 4.0f ) )
766 : {
767 1978643 : x[i] += ( x[i] < 0.0f ) ? 2.0f : -2.0f;
768 1978643 : i_max = i;
769 1978643 : break;
770 : }
771 : }
772 : }
773 : /* 4. expand value range of all xi up to i_max: two extra steps */
774 8578017 : for ( i = 0; i < i_max; i++ )
775 : {
776 6562838 : x[i] *= 0.5f;
777 6562838 : lf_deemph_factors[i] *= 0.5f;
778 : }
779 : /* 5. always expand two lines; lines could be at index 0 and 1! */
780 2015179 : if ( i_max < i_max_old )
781 : {
782 67 : i_max = i_max_old;
783 : }
784 2015179 : i = i_max + 1;
785 2015179 : if ( x[i] < 0.0f )
786 : {
787 888099 : if ( x[i] > -4.0f )
788 : {
789 323789 : lf_deemph_factors[i] *= 0.5f;
790 : }
791 888099 : x[i] = ( x[i] <= -4.0f ) ? x[i] + 2.0f : x[i] * 0.5f;
792 : }
793 : else
794 : {
795 1127080 : if ( x[i] < 4.0f )
796 : {
797 522631 : lf_deemph_factors[i] *= 0.5f;
798 : }
799 1127080 : x[i] = ( x[i] >= 4.0f ) ? x[i] - 2.0f : x[i] * 0.5f;
800 : }
801 2015179 : i++;
802 2015179 : if ( x[i] < 0.0f )
803 : {
804 877879 : if ( x[i] > -4.0f )
805 : {
806 390414 : lf_deemph_factors[i] *= 0.5f;
807 : }
808 877879 : x[i] = ( x[i] <= -4.0f ) ? x[i] + 2.0f : x[i] * 0.5f;
809 : }
810 : else
811 : {
812 1137300 : if ( x[i] < 4.0f )
813 : {
814 684123 : lf_deemph_factors[i] *= 0.5f;
815 : }
816 1137300 : x[i] = ( x[i] >= 4.0f ) ? x[i] - 2.0f : x[i] * 0.5f;
817 : }
818 : }
819 : else
820 : {
821 199773 : PsychAdaptLowFreqDeemph( x, lpcGains, lf_deemph_factors );
822 : }
823 :
824 2214952 : return;
825 : }
826 :
827 :
828 : /*-------------------------------------------------------------------*
829 : * tcx_noise_filling()
830 : *
831 : *
832 : *-------------------------------------------------------------------*/
833 :
834 12723812 : 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 12723812 : seed = (Word16) noiseFillSeed;
854 :
855 12723812 : tilt_factor = (float) pow( max( 0.375f, tiltCompFactor ), 1.0f / (float) L_frame );
856 12723812 : fac_ns /= (float) ( nTransWidth * nTransWidth );
857 :
858 : /* find last nonzero line below iFirstLine, use it as start offset */
859 12723812 : i = iFirstLine;
860 :
861 12723812 : if ( element_mode == IVAS_CPE_MDCT ) /* ... but only in mono or parametric stereo since it may cause binaural unmasking in discrete stereo */
862 : {
863 9306666 : segmentOffset = i;
864 : }
865 : else
866 : {
867 9171325 : for ( ; i > ( iFirstLine >> 1 ); i-- )
868 : {
869 9151366 : if ( Q[i] != 0.0f )
870 : {
871 3397187 : break;
872 : }
873 : }
874 :
875 3417146 : fac_ns *= (float) pow( tilt_factor, (float) i );
876 3417146 : segmentOffset = ++i;
877 : }
878 :
879 12723812 : nrg = 1e-9f;
880 12723812 : win = 0;
881 :
882 5100558654 : for ( ; i < lowpassLine; i++ )
883 : {
884 5087834842 : fac_ns *= tilt_factor;
885 :
886 5087834842 : if ( Q[i] != 0.0f )
887 : {
888 1197703065 : if ( win > 0 )
889 : {
890 : /* RMS-normalize current noise-filled segment */
891 541026553 : tmp1 = (float) sqrt( ( i - segmentOffset ) / nrg );
892 541026553 : tmp2 = tmp1 * (float) nTransWidth;
893 :
894 1422060518 : for ( m = segmentOffset; m < i - win; m++ )
895 : {
896 881033965 : Q[m] *= tmp2;
897 : }
898 :
899 2133887167 : for ( ; win > 0; win-- )
900 : {
901 1592860614 : Q[m++] *= tmp1 * (float) win;
902 : }
903 541026553 : nrg = 1e-9f; /* start new segment: reset noise segment energy */
904 : }
905 1197703065 : segmentOffset = i + 1;
906 : }
907 : else
908 : {
909 : /* line is zero, so fill line and update window and energy */
910 3890131777 : if ( win < nTransWidth )
911 : {
912 1672130970 : win++;
913 : }
914 3890131777 : tmp1 = (float) own_random( &seed );
915 3890131777 : nrg += tmp1 * tmp1; /* sum up energy of current noise segment */
916 3890131777 : Q[i] = tmp1 * (float) win * fac_ns;
917 :
918 3890131777 : if ( infoTCXNoise )
919 : {
920 : /* set noiseflags for IGF */
921 1925715993 : infoTCXNoise[i] = 1;
922 : }
923 : }
924 : }
925 :
926 12723812 : if ( win > 0 )
927 : {
928 : /* RMS-normalize uppermost noise-filled segment */
929 11514598 : tmp1 = (float) sqrt( ( lowpassLine - segmentOffset ) / nrg );
930 11514598 : tmp2 = tmp1 * (float) nTransWidth;
931 :
932 1427751796 : for ( m = segmentOffset; m < lowpassLine; m++ )
933 : {
934 1416237198 : Q[m] *= tmp2;
935 : }
936 : }
937 :
938 12723812 : return;
939 : }
940 :
941 :
942 : /*-------------------------------------------------------------------*
943 : * InitTnsConfigs()
944 : *
945 : *
946 : *-------------------------------------------------------------------*/
947 :
948 422214 : 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 422214 : if ( total_brate > ACELP_32k )
958 : {
959 364276 : InitTnsConfiguration( bwidth, L_frame / 2, &tnsConfig[0][0], igfStopFreq, total_brate, element_mode, MCT_flag );
960 : }
961 :
962 422214 : InitTnsConfiguration( bwidth, L_frame, &tnsConfig[1][0], igfStopFreq, total_brate, element_mode, MCT_flag );
963 :
964 422214 : InitTnsConfiguration( bwidth, L_frame + L_frame / 4, &tnsConfig[1][1], igfStopFreq, total_brate, element_mode, MCT_flag );
965 :
966 422214 : 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 422214 : 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 422214 : tnsConfig[0][0].allowTnsOnWhite = allowTnsOnWhite;
982 422214 : tnsConfig[0][1].allowTnsOnWhite = allowTnsOnWhite;
983 422214 : tnsConfig[1][0].allowTnsOnWhite = allowTnsOnWhite;
984 422214 : tnsConfig[1][1].allowTnsOnWhite = allowTnsOnWhite;
985 :
986 422214 : return;
987 : }
988 :
989 :
990 : /*-------------------------------------------------------------------*
991 : * SetTnsConfig()
992 : *
993 : *
994 : *-------------------------------------------------------------------*/
995 :
996 16266992 : void SetTnsConfig(
997 : TCX_CONFIG_HANDLE hTcxCfg,
998 : const int16_t isTCX20,
999 : const int16_t isAfterACELP )
1000 : {
1001 16266992 : hTcxCfg->pCurrentTnsConfig = &hTcxCfg->tnsConfig[isTCX20][isAfterACELP];
1002 16266992 : assert( hTcxCfg->pCurrentTnsConfig != NULL );
1003 :
1004 16266992 : return;
1005 : }
|