Line data Source code
1 : /*====================================================================================
2 : EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0
3 : ====================================================================================*/
4 :
5 : #include <stdint.h>
6 : #include <assert.h>
7 : #include "options.h"
8 : #include "prot_fx.h"
9 : #include "rom_com.h"
10 : #include "rom_basop_util.h"
11 : #include "basop_util.h"
12 :
13 : #define inv_int InvIntTable
14 :
15 : /*-------------------------------------------------------------------*
16 : * getInvFrameLen()
17 : *
18 : *
19 : *-------------------------------------------------------------------*/
20 3302886 : Word16 getInvFrameLen( /* returns 1/L_frame in Q21 format */
21 : const Word16 L_frame )
22 : {
23 : Word16 idx, s;
24 :
25 3302886 : s = norm_s( L_frame );
26 3302886 : idx = shl( L_frame, s );
27 :
28 3302886 : assert( ( idx == 0x4000 ) || ( idx == 0x4B00 ) || ( idx == 0x5000 ) || ( idx == 0x5A00 ) || ( idx == 0x6000 ) || ( idx == 0x6400 ) || ( idx == 0x7800 ) );
29 :
30 3302886 : idx = mult_r( idx, 0x10 ); /* idx = shr(add(idx, 0x0400), 11); */
31 3302886 : idx = s_and( idx, 7 );
32 :
33 :
34 3302886 : return shl( L_frame_inv[idx], sub( s, 7 ) );
35 : }
36 : /*-------------------------------------------------------------------*
37 : *tcx_get_windows()
38 : *
39 : *
40 : * ------------------------------------------------------------------ - */
41 479128 : void tcx_get_windows(
42 : TCX_CONFIG_HANDLE hTcxCfg, /* i : TCX configuration */
43 : const Word16 left_mode, /* i: overlap mode of left window half Q0*/
44 : const Word16 right_mode, /* i: overlap mode of right window half Q0*/
45 : Word16 *left_overlap, /* o: left overlap length Q0*/
46 : const PWord16 **left_win, /* o: left overlap window Q15*/
47 : Word16 *right_overlap, /* o: right overlap length Q0*/
48 : const PWord16 **right_win, /* o: right overlap window Q15*/
49 : const Word8 fullband /* i: fullband flag Q0*/
50 : )
51 : { /* LFE is only FULL_OVERLAP*/
52 479128 : IF( fullband == 0 )
53 : {
54 : /* Left part */
55 108948 : SWITCH( left_mode )
56 : {
57 322 : case TRANSITION_OVERLAP: /* ACELP->TCX transition */
58 322 : *left_overlap = hTcxCfg->tcx_mdct_window_trans_length; /*Q0*/
59 322 : move16();
60 322 : *left_win = hTcxCfg->tcx_mdct_window_trans; /*Q15*/
61 322 : BREAK;
62 2171 : case MIN_OVERLAP:
63 2171 : *left_overlap = hTcxCfg->tcx_mdct_window_min_length; /*Q0*/
64 2171 : move16();
65 2171 : *left_win = hTcxCfg->tcx_mdct_window_minimum; /*Q15*/
66 2171 : BREAK;
67 1711 : case HALF_OVERLAP:
68 1711 : *left_overlap = hTcxCfg->tcx_mdct_window_half_length; /*Q0*/
69 1711 : move16();
70 1711 : *left_win = hTcxCfg->tcx_mdct_window_half; /*Q15*/
71 1711 : BREAK;
72 104744 : case FULL_OVERLAP:
73 104744 : *left_overlap = hTcxCfg->tcx_mdct_window_length; /*Q0*/
74 104744 : move16();
75 104744 : *left_win = hTcxCfg->tcx_aldo_window_1_trunc; /*Q15*/
76 104744 : BREAK;
77 0 : default:
78 0 : assert( !"Not supported overlap" );
79 : }
80 :
81 : /* Right part */
82 108948 : SWITCH( right_mode )
83 : {
84 2185 : case MIN_OVERLAP:
85 2185 : *right_overlap = hTcxCfg->tcx_mdct_window_min_length; /*Q0*/
86 2185 : move16();
87 2185 : *right_win = hTcxCfg->tcx_mdct_window_minimum; /*Q15*/
88 2185 : BREAK;
89 1714 : case HALF_OVERLAP:
90 1714 : *right_overlap = hTcxCfg->tcx_mdct_window_half_length; /*Q0*/
91 1714 : move16();
92 1714 : *right_win = hTcxCfg->tcx_mdct_window_half; /*Q15*/
93 1714 : BREAK;
94 105049 : case FULL_OVERLAP:
95 105049 : *right_overlap = hTcxCfg->tcx_mdct_window_delay; /*Q0*/
96 105049 : move16();
97 105049 : *right_win = hTcxCfg->tcx_aldo_window_2; /*Q15*/
98 105049 : BREAK;
99 0 : default:
100 0 : assert( !"Not supported overlap" );
101 : }
102 : }
103 : ELSE
104 : {
105 : /* Left part */
106 370180 : SWITCH( left_mode )
107 : {
108 10830 : case TRANSITION_OVERLAP: /* ACELP->TCX transition */
109 10830 : *left_overlap = hTcxCfg->tcx_mdct_window_trans_lengthFB; /*Q0*/
110 10830 : move16();
111 10830 : *left_win = hTcxCfg->tcx_mdct_window_transFB; /*Q15*/
112 10830 : BREAK;
113 58764 : case MIN_OVERLAP:
114 58764 : *left_overlap = hTcxCfg->tcx_mdct_window_min_lengthFB; /*Q0*/
115 58764 : move16();
116 58764 : *left_win = hTcxCfg->tcx_mdct_window_minimumFB; /*Q15*/
117 58764 : BREAK;
118 14676 : case HALF_OVERLAP:
119 14676 : *left_overlap = hTcxCfg->tcx_mdct_window_half_lengthFB; /*Q0*/
120 14676 : move16();
121 14676 : *left_win = hTcxCfg->tcx_mdct_window_halfFB; /*Q15*/
122 14676 : BREAK;
123 32838 : case RECTANGULAR_OVERLAP:
124 32838 : *left_overlap = 0;
125 32838 : move16();
126 32838 : *left_win = NULL;
127 32838 : BREAK;
128 253072 : case FULL_OVERLAP:
129 253072 : *left_overlap = hTcxCfg->tcx_mdct_window_lengthFB; /*Q0*/
130 253072 : move16();
131 253072 : *left_win = hTcxCfg->tcx_aldo_window_1_FB_trunc; /*Q15*/
132 253072 : BREAK;
133 0 : default:
134 0 : assert( !"Not supported overlap" );
135 : }
136 :
137 : /* Right part */
138 370180 : SWITCH( right_mode )
139 : {
140 61788 : case MIN_OVERLAP:
141 61788 : *right_overlap = hTcxCfg->tcx_mdct_window_min_lengthFB; /*Q0*/
142 61788 : move16();
143 61788 : *right_win = hTcxCfg->tcx_mdct_window_minimumFB; /*Q15*/
144 61788 : BREAK;
145 15170 : case HALF_OVERLAP:
146 15170 : *right_overlap = hTcxCfg->tcx_mdct_window_half_lengthFB; /*Q0*/
147 15170 : move16();
148 15170 : *right_win = hTcxCfg->tcx_mdct_window_halfFB; /*Q15*/
149 15170 : BREAK;
150 32819 : case RECTANGULAR_OVERLAP:
151 32819 : *right_overlap = 0;
152 32819 : move16();
153 32819 : *right_win = NULL;
154 32819 : BREAK;
155 260403 : case FULL_OVERLAP:
156 260403 : *right_overlap = hTcxCfg->tcx_mdct_window_delayFB; /*Q0*/
157 260403 : move16();
158 260403 : *right_win = hTcxCfg->tcx_aldo_window_2_FB; /*Q15*/
159 260403 : BREAK;
160 0 : default:
161 0 : assert( !"Not supported overlap" );
162 : }
163 : }
164 479128 : }
165 :
166 479097 : static void tcx_windowing_analysis(
167 : Word16 const *signal, /* i: signal vector Qx*/
168 : Word16 L_frame, /* i: frame length Q0*/
169 : Word16 left_overlap, /* i: left overlap length Q0*/
170 : PWord16 const *left_win, /* i: left overlap window Q15*/
171 : Word16 right_overlap, /* i: right overlap length Q0*/
172 : PWord16 const *right_win, /* i: right overlap window Q15*/
173 : Word16 *output /* o: windowed signal vector Qx*/
174 : )
175 : {
176 : Word16 w, n;
177 :
178 : /* Left overlap */
179 479097 : n = shr( left_overlap, 1 ); /*Q0*/
180 68548319 : FOR( w = 0; w < n; w++ )
181 : {
182 68069222 : *output++ = mult_r( *signal++, left_win[w].v.im ); /*Qx*/
183 68069222 : move16();
184 : }
185 68548319 : FOR( w = 0; w < n; w++ )
186 : {
187 68069222 : *output++ = mult_r( *signal++, left_win[n - 1 - w].v.re ); /*Qx*/
188 68069222 : move16();
189 : }
190 :
191 : /* Non overlapping region */
192 479097 : n = sub( L_frame, shr( add( left_overlap, right_overlap ), 1 ) ); /*Q0*/
193 194454557 : FOR( w = 0; w < n; w++ )
194 : {
195 193975460 : *output++ = *signal++; /*Qx*/
196 193975460 : move16();
197 : }
198 :
199 : /* Right overlap */
200 479097 : n = shr( right_overlap, 1 ); /*Q0*/
201 69852207 : FOR( w = 0; w < n; w++ )
202 : {
203 69373110 : *output++ = mult_r( *signal++, right_win[w].v.re ); /*Qx*/
204 69373110 : move16();
205 : }
206 69852207 : FOR( w = 0; w < n; w++ )
207 : {
208 69373110 : *output++ = mult_r( *signal++, right_win[n - 1 - w].v.im ); /*Qx*/
209 69373110 : move16();
210 : }
211 479097 : }
212 : /*-------------------------------------------------------------------*
213 : * WindowSignal()
214 : *
215 : *
216 : *-------------------------------------------------------------------*/
217 479097 : void WindowSignal(
218 : TCX_CONFIG_HANDLE hTcxCfg, /* i : configuration of TCX */
219 : Word16 offset, /* i : left folding point offset relative to the input signal pointer Q0*/
220 : const Word16 left_overlap_mode, /* i : overlap mode of left window half Q0*/
221 : Word16 right_overlap_mode, /* i : overlap mode of right window half Q0*/
222 : Word16 *left_overlap_length, /* o : TCX window left overlap length Q0*/
223 : Word16 *right_overlap_length, /* o : TCX window right overlap length Q0*/
224 : const Word16 in[], /* i : input signal Qx*/
225 : Word16 *L_frame, /* i/o: frame length Q0*/
226 : Word16 out[], /* o : output windowed signal Qx*/
227 : const Word16 truncate_aldo, /* i : nonzero to truncate long ALDO slope Q0*/
228 : const Word8 fullband /* i : fullband flag Q0*/
229 : )
230 : {
231 : Word16 l, r;
232 : PWord16 const *left_win;
233 : PWord16 const *right_win;
234 :
235 :
236 : /*-----------------------------------------------------------*
237 : * Init *
238 : *-----------------------------------------------------------*/
239 :
240 479097 : tcx_get_windows( hTcxCfg, left_overlap_mode, right_overlap_mode, &l, &left_win, &r, &right_win, fullband );
241 :
242 : /* Init lengths */
243 :
244 : /* if past frame is ACELP */
245 479097 : IF( EQ_16( left_overlap_mode, TRANSITION_OVERLAP ) )
246 : {
247 : /* Increase frame size for 5ms */
248 11152 : IF( fullband == 0 )
249 : {
250 322 : *L_frame = add( *L_frame, hTcxCfg->tcx5Size ); /*Q0*/
251 322 : move16();
252 322 : offset = negate( shr( hTcxCfg->tcx_mdct_window_trans_length, 1 ) ); /*Q0*/
253 : }
254 : ELSE
255 : {
256 10830 : *L_frame = add( *L_frame, hTcxCfg->tcx5SizeFB ); /*Q0*/
257 10830 : move16();
258 10830 : offset = negate( shr( hTcxCfg->tcx_mdct_window_trans_lengthFB, 1 ) ); /*Q0*/
259 : }
260 : }
261 :
262 : /*-----------------------------------------------------------*
263 : * Windowing *
264 : *-----------------------------------------------------------*/
265 :
266 479097 : tcx_windowing_analysis( in - sub( shr( l, 1 ), offset ), *L_frame, l, left_win, r, right_win, out );
267 479097 : test();
268 479097 : test();
269 479097 : IF( EQ_16( left_overlap_mode, FULL_OVERLAP ) && truncate_aldo )
270 : {
271 : /* fade truncated ALDO window to avoid discontinuities */
272 : Word16 i, tmp;
273 : const PWord16 *p;
274 :
275 334565 : p = hTcxCfg->tcx_mdct_window_minimum; /*Q15*/
276 334565 : tmp = shr( hTcxCfg->tcx_mdct_window_min_length, 1 ); /*Q0*/
277 334565 : IF( fullband != 0 )
278 : {
279 229821 : p = hTcxCfg->tcx_mdct_window_minimumFB; /*Q15*/
280 229821 : tmp = shr( hTcxCfg->tcx_mdct_window_min_lengthFB, 1 ); /*Q0*/
281 : }
282 :
283 8983987 : FOR( i = 0; i < tmp; i++ )
284 : {
285 8649422 : out[i] = mult_r( out[i], p[i].v.im ); /*Qx*/
286 8649422 : move16();
287 : }
288 8983987 : FOR( i = 0; i < tmp; i++ )
289 : {
290 8649422 : out[i + tmp] = mult_r( out[i + tmp], p[tmp - 1 - i].v.re ); /*Qx*/
291 8649422 : move16();
292 : }
293 : }
294 :
295 479097 : *left_overlap_length = l;
296 479097 : move16();
297 479097 : *right_overlap_length = r;
298 479097 : move16();
299 479097 : }
300 : /*-------------------------------------------------------------------*
301 : * tcx_windowing_synthesis_current_frame()
302 : *
303 : *
304 : *-------------------------------------------------------------------*/
305 :
306 129873 : void tcx_windowing_synthesis_current_frame(
307 : Word16 *signal, /* i/o: signal vector Qx*/
308 : const PWord16 *window, /* i: TCX window vector Q15*/
309 : const PWord16 *window_half, /* i: TCX window vector for half-overlap window Q15*/
310 : const PWord16 *window_min, /* i: TCX minimum overlap window Q15*/
311 : const Word16 window_length, /* i: TCX window length Q0*/
312 : const Word16 window_half_length, /* i: TCX half window length Q0*/
313 : const Word16 window_min_length, /* i: TCX minimum overlap length Q0*/
314 : const Word16 left_rect, /* i: left part is rectangular Q0*/
315 : const Word16 left_mode, /* i: overlap mode of left window half Q0*/
316 : Word16 *acelp_zir, /* i: acelp ZIR Qx*/
317 : const Word16 *old_syn, /*Qx*/
318 : const Word16 *syn_overl, /*Qx*/
319 : const Word16 *A_zir, /*Q12*/
320 : const PWord16 *window_trans, /*Q15*/
321 : Word16 acelp_zir_len, /*Q0*/
322 : const Word16 acelp_mem_len, /*Q0*/
323 : const Word16 last_core_bfi, /* i : last core Q0*/
324 : const Word8 last_is_cng, /*Q0*/
325 : const Word16 fullbandScale /*Q0*/ )
326 : {
327 :
328 : Word16 i, overlap, n, tmp, tmp2;
329 : Word16 tmp_buf[L_FRAME_MAX / 2];
330 : Word32 L_tmp;
331 :
332 : /* Init */
333 :
334 129873 : overlap = shr( window_length, 1 ); /*Q0*/
335 :
336 : /* Past-frame is TCX concealed as CNG and current-frame is TCX */
337 129873 : test();
338 129873 : test();
339 129873 : test();
340 129873 : test();
341 129873 : IF( EQ_16( last_is_cng, 1 ) && left_rect == 0 )
342 : {
343 0 : IF( !fullbandScale )
344 : {
345 0 : set16_fx( acelp_zir, 0, acelp_zir_len );
346 0 : E_UTIL_synthesis( 0, A_zir, acelp_zir, acelp_zir, acelp_zir_len, signal + overlap + acelp_mem_len - M, 0, M );
347 : }
348 : ELSE
349 : {
350 0 : lerp( acelp_zir, tmp_buf, acelp_zir_len, idiv1616U( shl_sat( acelp_zir_len, LD_FSCALE_DENOM ), fullbandScale ) );
351 0 : acelp_zir = tmp_buf; /*Qx*/
352 : }
353 :
354 0 : FOR( i = 0; i < acelp_zir_len; i++ )
355 : {
356 : /*signal[i] *= (float)(i)/(float)(acelp_zir_len);
357 : signal[i] += acelp_zir[i]*(float)(acelp_zir_len-i)/(float)(acelp_zir_len);*/
358 0 : signal[i] = add( mult_r( signal[i], div_s( i, acelp_zir_len ) ), mult_r( acelp_zir[i], div_s( sub( acelp_zir_len, i ), acelp_zir_len ) ) ); /*Qx*/
359 0 : move16();
360 : }
361 : }
362 : /* Rectangular window (past-frame is ACELP) */
363 129873 : ELSE IF( EQ_16( left_rect, 1 ) && last_core_bfi == ACELP_CORE )
364 : {
365 25316 : tmp = sub( overlap, acelp_mem_len );
366 2404088 : FOR( i = 0; i < tmp; i++ )
367 : {
368 2378772 : move16();
369 2378772 : signal[i] = 0;
370 : }
371 :
372 25316 : IF( fullbandScale == 0 )
373 : {
374 :
375 16744 : tmp = shl( acelp_mem_len, 1 ); /*Qx*/
376 :
377 : /*OLA with ACELP*/
378 185126 : FOR( i = 0; i < acelp_mem_len; i++ )
379 : {
380 :
381 : /*window decoded TCX with aliasing*/
382 168382 : tmp2 = mult_r( signal[i + overlap - acelp_mem_len], window_trans[i].v.im ); /*Qx*/
383 :
384 : /*Time TDAC: 1)forward part of ACELP*/
385 168382 : tmp2 = add_sat( tmp2, mult_r( old_syn[acelp_zir_len - tmp + i], mult_r( window_trans[i].v.re, window_trans[i].v.re ) ) ); /*Qx*/
386 :
387 : /*Time TDAC: 1)reward part of ACELP*/
388 168382 : tmp2 = add_sat( tmp2, mult_r( old_syn[acelp_zir_len - i - 1], mult_r( window_trans[i].v.im, window_trans[i].v.re ) ) ); /*Qx*/
389 168382 : move16();
390 168382 : signal[i + overlap - acelp_mem_len] = tmp2; /*Qx*/
391 : }
392 185126 : FOR( ; i < tmp; i++ )
393 : {
394 :
395 : /*window decoded TCX with aliasing*/
396 168382 : tmp2 = mult_r( signal[i + overlap - acelp_mem_len], window_trans[tmp - 1 - i].v.re ); /*Qx*/
397 :
398 : /*Time TDAC: 1)forward part of ACELP*/
399 168382 : tmp2 = add_sat( tmp2, mult_r( old_syn[acelp_zir_len - tmp + i], mult_r( window_trans[tmp - 1 - i].v.im, window_trans[tmp - 1 - i].v.im ) ) ); /*Qx*/
400 : /*Time TDAC: 1)reward part of ACELP*/
401 168382 : tmp2 = add_sat( tmp2, mult_r( old_syn[acelp_zir_len - i - 1], mult_r( window_trans[tmp - 1 - i].v.re, window_trans[tmp - 1 - i].v.im ) ) ); /*Qx*/
402 168382 : move16();
403 168382 : signal[i + overlap - acelp_mem_len] = tmp2; /*Qx*/
404 : }
405 :
406 284648 : FOR( i = 0; i < M; i++ )
407 : {
408 267904 : move16();
409 267904 : signal[overlap + acelp_mem_len - M + i] = sub_sat( signal[overlap + acelp_mem_len - M + i], old_syn[acelp_zir_len - M + i] ); /*Qx*/
410 : }
411 : }
412 : /* ZIR at the end of the ACELP frame */
413 25316 : move16();
414 25316 : acelp_zir_len = 64;
415 :
416 25316 : IF( fullbandScale == 0 )
417 : {
418 16744 : set16_fx( acelp_zir, 0, acelp_zir_len );
419 16744 : E_UTIL_synthesis( 0, A_zir, acelp_zir, acelp_zir, acelp_zir_len, signal + overlap + acelp_mem_len - M, 0, M );
420 : }
421 : ELSE
422 : {
423 8572 : tmp = extract_l( L_shr( L_mult0( acelp_zir_len, fullbandScale ), LD_FSCALE_DENOM ) ); /*Q0*/
424 8572 : lerp( acelp_zir, tmp_buf, tmp, acelp_zir_len );
425 8572 : acelp_zir_len = tmp; /*Q0*/
426 8572 : move16();
427 8572 : acelp_zir = tmp_buf; /*Qx*/
428 :
429 :
430 8572 : IF( GE_16( acelp_zir_len, 2 * 64 ) )
431 : {
432 : /* apply a simple low-pass to the ZIR, to avoid potentially unmasked HF content */
433 1283234 : FOR( i = 2; i < acelp_zir_len; i++ )
434 : {
435 1276724 : L_tmp = L_mult( acelp_zir[i - 2], 8192 /*0.25 in Q15*/ );
436 1276724 : L_tmp = L_mac( L_tmp, acelp_zir[i - 1], 11469 /*0.35 in Q15*/ );
437 1276724 : acelp_zir[i] = mac_r( L_tmp, acelp_zir[i], 13107 /*0.40 in Q15*/ ); /*Qx*/
438 1276724 : move16();
439 : }
440 :
441 6510 : L_tmp = L_mult( acelp_zir[acelp_zir_len - 1], 13107 /*0.40 in Q15*/ );
442 6510 : L_tmp = L_mac( L_tmp, acelp_zir[acelp_zir_len - 1], 11469 /*0.35 in Q15*/ );
443 6510 : acelp_zir[acelp_zir_len - 1] = mac_r( L_tmp, acelp_zir[acelp_zir_len - 2], 8192 /*0.25 in Q15*/ ); /*Qx*/
444 6510 : move16();
445 6510 : L_tmp = L_mult( acelp_zir[acelp_zir_len - 2], 13107 );
446 6510 : L_tmp = L_mac( L_tmp, acelp_zir[acelp_zir_len - 1], 11469 );
447 6510 : acelp_zir[acelp_zir_len - 2] = mac_r( L_tmp, acelp_zir[acelp_zir_len - 1], 8192 ); /*Qx*/
448 6510 : move16();
449 1283234 : FOR( i = acelp_zir_len - 3; i >= 0; i-- )
450 : {
451 1276724 : L_tmp = L_mult( acelp_zir[i], 13107 );
452 1276724 : L_tmp = L_mac( L_tmp, acelp_zir[i + 1], 11469 );
453 1276724 : acelp_zir[i] = mac_r( L_tmp, acelp_zir[i + 2], 8192 ); /*Qx*/
454 1276724 : move16();
455 : }
456 : }
457 : }
458 :
459 2577308 : FOR( i = 0; i < acelp_zir_len; i++ )
460 : {
461 : /*remove reconstructed ZIR and add ACELP ZIR*/
462 2551992 : move16();
463 2551992 : signal[i + overlap + acelp_mem_len] = sub_sat( signal[i + overlap + acelp_mem_len], mult_r_sat( acelp_zir[i], div_s( sub_sat( acelp_zir_len, i ), acelp_zir_len ) ) ); /*Qx*/
464 : }
465 : }
466 : /* Rectangular window (past-frame is TCX) */
467 104557 : ELSE IF( left_rect == 1 && last_core_bfi != ACELP_CORE )
468 : {
469 312 : n = add( overlap, acelp_mem_len ); /*q0*/
470 39064 : FOR( i = 0; i < n; i++ )
471 : {
472 38752 : move16();
473 38752 : signal[i] = 0;
474 : }
475 :
476 312 : n = shr( window_length, 1 ); /*q0*/
477 34220 : FOR( i = 0; i < n; i++ )
478 : {
479 33908 : move16();
480 33908 : signal[i + overlap + acelp_mem_len] = mult_r( signal[i + overlap + acelp_mem_len], window[i].v.im ); /*Qx*/
481 : }
482 34220 : FOR( ; i < window_length; i++ )
483 : {
484 33908 : move16();
485 33908 : signal[i + overlap + acelp_mem_len] = mult_r( signal[i + overlap + acelp_mem_len], window[window_length - 1 - i].v.re ); /*Qx*/
486 : }
487 : }
488 : /* Normal window (past-frame is ACELP) */
489 104245 : ELSE IF( left_rect != 1 && last_core_bfi == ACELP_CORE )
490 : {
491 :
492 16 : n = shr( window_length, 1 ); /*q0*/
493 2438 : FOR( i = 0; i < n; i++ )
494 : {
495 2422 : move16();
496 2422 : signal[i] = mult_r( signal[i], window[i].v.im ); /*Qx*/
497 : }
498 2438 : FOR( ; i < window_length; i++ )
499 : {
500 2422 : move16();
501 2422 : signal[i] = mult_r( signal[i], window[window_length - 1 - i].v.re ); /*Qx*/
502 : }
503 :
504 4860 : FOR( i = 0; i < window_length /*acelp_zir_len*/; i++ )
505 : {
506 4844 : move16();
507 4844 : signal[i] = add( signal[i], syn_overl[i] ); /*Qx*/
508 : }
509 : }
510 : /* Normal window (past-frame is TCX) */
511 : ELSE
512 : {
513 104229 : IF( EQ_16( left_mode, 2 ) ) /* min. overlap */
514 : {
515 62647 : n = shr( sub( window_length, window_min_length ), 1 ); /*q0*/
516 2872719 : FOR( i = 0; i < n; i++ )
517 : {
518 2810072 : *signal++ = 0;
519 2810072 : move16();
520 : }
521 :
522 62647 : n = shr( window_min_length, 1 ); /*q0*/
523 1399887 : FOR( i = 0; i < n; i++ )
524 : {
525 1337240 : *signal = mult_r( *signal, window_min[i].v.im ); /*Qx*/
526 1337240 : move16();
527 1337240 : signal++;
528 : }
529 1399887 : FOR( i = 0; i < n; i++ )
530 : {
531 1337240 : *signal = mult_r( *signal, window_min[n - 1 - i].v.re ); /*Qx*/
532 1337240 : move16();
533 1337240 : signal++;
534 : }
535 : }
536 41582 : ELSE IF( EQ_16( left_mode, 3 ) ) /* half OL */
537 : {
538 : Word16 w;
539 :
540 15059 : n = shr( sub( window_length, window_half_length ), 1 );
541 363419 : FOR( i = 0; i < n; i++ )
542 : {
543 348360 : move16();
544 348360 : signal[i] = 0;
545 : }
546 15059 : n = shr( window_half_length, 1 );
547 977081 : FOR( w = 0; w < n; w++ )
548 : {
549 962022 : move16();
550 962022 : signal[i] = mult_r( signal[i], window_half[w].v.im ); /*Qx*/
551 962022 : i = add( i, 1 );
552 : }
553 977081 : FOR( w = 0; w < n; w++ )
554 : {
555 962022 : move16();
556 962022 : signal[i] = mult_r( signal[i], window_half[window_half_length / 2 - 1 - w].v.re ); /*Qx*/
557 962022 : i = add( i, 1 );
558 : }
559 : }
560 : ELSE
561 : { /* normal full/maximum overlap */
562 :
563 26523 : n = shr( window_length, 1 );
564 4019071 : FOR( i = 0; i < n; i++ )
565 : {
566 3992548 : move16();
567 3992548 : signal[i] = mult_r( signal[i], window[i].v.im ); /*Qx*/
568 : }
569 4019071 : FOR( ; i < window_length; i++ )
570 : {
571 3992548 : move16();
572 3992548 : signal[i] = mult_r( signal[i], window[window_length - 1 - i].v.re ); /*Qx*/
573 : }
574 : }
575 : }
576 :
577 : /* Right part asymmetric window : with ALDO do nothing->can be skipped*/
578 129873 : }
579 : /*-------------------------------------------------------------------*
580 : * tcx_windowing_synthesis_past_frame()
581 : *
582 : *
583 : *-------------------------------------------------------------------*/
584 131300 : void tcx_windowing_synthesis_past_frame(
585 : Word16 *signal, /* i/o: signal vector Qx*/
586 : const PWord16 *window, /* i: TCX window vector Q15*/
587 : const PWord16 *window_half, /* i: TCX window vector for half-overlap window Q15*/
588 : const PWord16 *window_min, /* i: TCX minimum overlap window Q15*/
589 : const Word16 window_length, /* i: TCX window length Q0*/
590 : const Word16 window_half_length, /* i: TCX half window length Q0*/
591 : const Word16 window_min_length, /* i: TCX minimum overlap length Q0*/
592 : const Word16 right_mode /* i: overlap mode (left_mode of current frame) Q0*/
593 : )
594 : {
595 :
596 : Word16 i, n;
597 :
598 131300 : IF( EQ_16( right_mode, 2 ) ) /* min. overlap */
599 : {
600 66544 : signal += shr( sub( window_length, window_min_length ), 1 ); /*Qx*/
601 :
602 66544 : n = shr( window_min_length, 1 );
603 1490252 : FOR( i = 0; i < n; i++ )
604 : {
605 1423708 : *signal = mult_r( *signal, window_min[i].v.re ); /*Qx*/
606 1423708 : move16();
607 1423708 : signal++;
608 : }
609 1490252 : FOR( i = 0; i < n; i++ )
610 : {
611 1423708 : *signal = mult_r( *signal, window_min[n - 1 - i].v.im ); /*Qx*/
612 1423708 : move16();
613 1423708 : signal++;
614 : }
615 :
616 66544 : n = shr( sub( window_length, window_min_length ), 1 ); /*Q0*/
617 4509504 : FOR( i = 0; i < n; i++ )
618 : {
619 4442960 : *signal = 0;
620 4442960 : move16();
621 4442960 : signal++;
622 : }
623 : }
624 64756 : ELSE IF( EQ_16( right_mode, 3 ) ) /* half OL */
625 : {
626 : Word16 w;
627 :
628 17106 : i = shr( sub( window_length, window_half_length ), 1 ); /*Q0*/
629 17106 : n = shr( window_half_length, 1 ); /*Q0*/
630 1095930 : FOR( w = 0; w < n; w++ )
631 : {
632 1078824 : signal[i] = mult_r( signal[i], window_half[w].v.re ); /*Qx*/
633 1078824 : move16();
634 1078824 : i = add( i, 1 );
635 : }
636 1095930 : FOR( w = 0; w < n; w++ )
637 : {
638 1078824 : signal[i] = mult_r( signal[i], window_half[window_half_length / 2 - 1 - w].v.im ); /*Qx*/
639 1078824 : move16();
640 1078824 : i = add( i, 1 );
641 : }
642 1455538 : FOR( ; i < window_length; i++ )
643 : {
644 1438432 : move16();
645 1438432 : signal[i] = 0;
646 : }
647 : }
648 : ELSE /* normal full/maximum overlap */
649 : {
650 :
651 47650 : n = shr( window_length, 1 ); /*Q0*/
652 6177424 : FOR( i = 0; i < n; i++ )
653 : {
654 6129774 : move16();
655 6129774 : signal[i] = mult_r( signal[i], window[i].v.re ); /*Qx*/
656 6129774 : move16();
657 6129774 : signal[window_length - 1 - i] = mult_r( signal[window_length - 1 - i], window[i].v.im ); /*Qx*/
658 : }
659 : }
660 131300 : }
661 : /*-------------------------------------------------------------------*
662 : * lpc2mdct()
663 : *
664 : *
665 : *-------------------------------------------------------------------*/
666 :
667 275727 : void lpc2mdct(
668 : Word16 *lpcCoeffs, /*Q12*/
669 : const Word16 lpcOrder, /*Q0*/
670 : Word16 *mdct_gains, /*Q15 - mdct_gains_exp*/
671 : Word16 *mdct_gains_exp,
672 : Word16 *mdct_inv_gains, /*Q15 - mdct_inv_gains_exp*/
673 : Word16 *mdct_inv_gains_exp,
674 : const Word16 length, /*Q0*/
675 : const Word16 noInverse /*Q0*/ )
676 : {
677 : Word32 ComplexData[2 * FDNS_NPTS];
678 : Word16 i, j, k, sizeN, step, scale, s, tmp16;
679 : Word16 g, g_e, ig, ig_e;
680 : Word32 tmp32;
681 : const PWord16 *ptwiddle;
682 : Word32 workBuffer[2 * BASOP_CFFT_MAX_LENGTH];
683 :
684 : #ifndef IVAS_CODE_TCX_UTIL
685 : (void) noInverse;
686 : #endif
687 :
688 275727 : assert( length <= FDNS_NPTS );
689 275727 : sizeN = shl( length, 1 ); /*Q0*/
690 :
691 275727 : BASOP_getTables( NULL, &ptwiddle, &step, sizeN );
692 : /*ODFT*/
693 275727 : assert( lpcOrder < FDNS_NPTS );
694 : /* pre-twiddle */
695 4980530 : FOR( i = 0; i <= lpcOrder; i++ )
696 : {
697 4704803 : ComplexData[2 * i] = L_mult( lpcCoeffs[i], ptwiddle->v.re ); /*Q12*/
698 4704803 : move32();
699 4704803 : ComplexData[2 * i + 1] = L_negate( L_mult( lpcCoeffs[i], ptwiddle->v.im ) ); /*Q12*/
700 4704803 : move32();
701 4704803 : ptwiddle += step;
702 : }
703 : /* zero padding */
704 13217452 : FOR( ; i < FDNS_NPTS; i++ )
705 : {
706 12941725 : ComplexData[2 * i] = L_deposit_l( 0 );
707 12941725 : move32();
708 12941725 : ComplexData[2 * i + 1] = L_deposit_l( 0 );
709 12941725 : move32();
710 : }
711 :
712 275727 : move16();
713 : #ifdef IVAS_CODE_TCX_UTIL
714 : if ( noInverse )
715 : {
716 : /* half length FFT */
717 : scale = add( norm_s( lpcCoeffs[0] ), 1 );
718 : BASOP_cfft( (cmplx *) ComplexData, FDNS_NPTS, &scale, workBuffer ); // tbv -> In float the fft type changes as well
719 : /*Get amplitude*/
720 : j = sub( length, 1 );
721 : k = 0;
722 : for ( i = 0; i < length; i++ )
723 : {
724 : mdct_gains[i] = (float) ( sqrt( RealData[i] * RealData[i] + ImagData[i] * ImagData[i] ) );
725 : }
726 : }
727 : else
728 : #endif
729 : {
730 : /* half length FFT */
731 275727 : scale = add( norm_s( lpcCoeffs[0] ), 1 );
732 275727 : BASOP_cfft( (cmplx *) ComplexData, FDNS_NPTS, &scale, workBuffer ); /*Q31 - scale*/
733 : /*Get amplitude*/
734 275727 : j = sub( length, 1 );
735 275727 : k = 0;
736 9098991 : FOR( i = 0; i < length / 2; i++ )
737 : {
738 8823264 : s = sub( norm_l( L_max( L_abs( ComplexData[2 * i] ), L_abs( ComplexData[2 * i + 1] ) ) ), 1 );
739 8823264 : tmp16 = extract_h( L_shl( ComplexData[2 * i], s ) ); /*Q15 - scale + s*/
740 8823264 : tmp32 = L_mult( tmp16, tmp16 ); /*Q15 - 2*(scale - s)*/
741 8823264 : tmp16 = extract_h( L_shl( ComplexData[2 * i + 1], s ) ); /*Q15 - scale + s*/
742 8823264 : tmp16 = mac_r( tmp32, tmp16, tmp16 ); /*Q15 - 2*(scale - s)*/
743 8823264 : s = shl( sub( scale, s ), 1 );
744 8823264 : if ( tmp16 == 0 )
745 : {
746 0 : s = -16;
747 0 : move16();
748 : }
749 8823264 : if ( tmp16 == 0 )
750 : {
751 0 : tmp16 = 1;
752 0 : move16();
753 : }
754 8823264 : BASOP_Util_Sqrt_InvSqrt_MantExp( tmp16, s, &g, &g_e, &ig, &ig_e ); /*Q15 - ig_e*/
755 8823264 : if ( mdct_gains != 0 )
756 : {
757 8244768 : mdct_gains[k] = g; /*Q15 - g_e*/
758 8244768 : move16();
759 : }
760 8823264 : if ( mdct_gains_exp != 0 )
761 : {
762 8244768 : mdct_gains_exp[k] = g_e;
763 8244768 : move16();
764 : }
765 8823264 : if ( mdct_inv_gains != 0 )
766 : {
767 8231456 : mdct_inv_gains[k] = ig; /*Q15 - ig_e*/
768 8231456 : move16();
769 : }
770 8823264 : if ( mdct_inv_gains_exp != 0 )
771 : {
772 8231456 : mdct_inv_gains_exp[k] = ig_e;
773 8231456 : move16();
774 : }
775 8823264 : k = add( k, 1 );
776 8823264 : s = sub( norm_l( L_max( L_abs( ComplexData[2 * j] ), L_abs( ComplexData[2 * j + 1] ) ) ), 1 );
777 8823264 : tmp16 = extract_h( L_shl( ComplexData[2 * j], s ) ); /*Q15 - scale + s*/
778 8823264 : tmp32 = L_mult( tmp16, tmp16 ); /*Q15 - 2*(scale - s)*/
779 8823264 : tmp16 = extract_h( L_shl( ComplexData[2 * j + 1], s ) ); /*Q15 - scale + s*/
780 8823264 : tmp16 = mac_r( tmp32, tmp16, tmp16 ); /*Q15 - 2*(scale - s)*/
781 8823264 : s = shl( sub( scale, s ), 1 );
782 8823264 : if ( tmp16 == 0 )
783 : {
784 0 : s = -16;
785 0 : move16();
786 : }
787 8823264 : if ( tmp16 == 0 )
788 : {
789 0 : tmp16 = 1;
790 0 : move16();
791 : }
792 8823264 : BASOP_Util_Sqrt_InvSqrt_MantExp( tmp16, s, &g, &g_e, &ig, &ig_e );
793 8823264 : if ( mdct_gains != 0 )
794 : {
795 8244768 : mdct_gains[k] = g; /*Q15 - g_e*/
796 8244768 : move16();
797 : }
798 8823264 : if ( mdct_gains_exp != 0 )
799 : {
800 8244768 : mdct_gains_exp[k] = g_e;
801 8244768 : move16();
802 : }
803 8823264 : if ( mdct_inv_gains != 0 )
804 : {
805 8231456 : mdct_inv_gains[k] = ig; /*Q15 - ig_e*/
806 8231456 : move16();
807 : }
808 8823264 : if ( mdct_inv_gains_exp != 0 )
809 : {
810 8231456 : mdct_inv_gains_exp[k] = ig_e;
811 8231456 : move16();
812 : }
813 8823264 : j = sub( j, 1 );
814 8823264 : k = add( k, 1 );
815 : }
816 : }
817 275727 : }
818 :
819 221261 : void lpc2mdct_2(
820 : Word16 *lpcCoeffs, /*Q12*/
821 : const Word16 lpcOrder, /*Q0*/
822 : Word16 mdct_gains_fx[], /*Q15 - mdct_gains_e*/
823 : Word16 mdct_gains_e[],
824 : Word16 mdct_inv_gains_fx[], /*Q15 - mdct_inv_gains_e*/
825 : Word16 mdct_inv_gains_e[],
826 : const Word16 length /*Q0*/ )
827 : {
828 : Word16 i, sizeN, j, k, step, scale, s, tmp16;
829 : Word16 g, g_e, ig, ig_e;
830 : Word32 tmp32;
831 : Word32 RealData_fx[2 * FDNS_NPTS], ImagData_fx[2 * FDNS_NPTS];
832 : const PWord16 *ptwiddle;
833 :
834 221261 : assert( length <= FDNS_NPTS );
835 221261 : sizeN = shl( length, 1 ); /*Q0*/
836 :
837 221261 : BASOP_getTables( NULL, &ptwiddle, &step, sizeN );
838 :
839 : /* ODFT */
840 3982698 : FOR( i = 0; i < lpcOrder + 1; i++ )
841 : {
842 3761437 : RealData_fx[i] = L_mult( lpcCoeffs[i], ptwiddle->v.re ); /*Q12*/
843 3761437 : move32();
844 3761437 : ImagData_fx[i] = L_negate( L_mult( lpcCoeffs[i], ptwiddle->v.im ) ); /*Q12*/
845 3761437 : move32();
846 3761437 : ptwiddle += step;
847 : }
848 :
849 24781232 : FOR( ; i < sizeN; i++ )
850 : {
851 24559971 : RealData_fx[i] = L_deposit_l( 0 );
852 24559971 : move32();
853 24559971 : ImagData_fx[i] = L_deposit_l( 0 );
854 24559971 : move32();
855 : }
856 :
857 : /* half length FFT */
858 221261 : scale = add( norm_s( lpcCoeffs[0] ), 1 );
859 221261 : BASOP_cfft_ivas( RealData_fx, ImagData_fx, 1, &scale ); /*Q31 - scale*/
860 :
861 : /*Get amplitude*/
862 221261 : j = sub( FDNS_NPTS, 1 );
863 221261 : move16();
864 221261 : k = 0;
865 221261 : move16();
866 :
867 7301613 : FOR( i = 0; i < FDNS_NPTS / 2; i++ )
868 : {
869 7080352 : s = sub( norm_l( L_max( L_abs( RealData_fx[i] ), L_abs( ImagData_fx[i] ) ) ), 1 );
870 :
871 7080352 : tmp16 = extract_h( L_shl( RealData_fx[i], s ) ); /*Q15 - scale + s*/
872 7080352 : tmp32 = L_mult( tmp16, tmp16 ); /*Q15 - 2*(scale - s)*/
873 :
874 7080352 : tmp16 = extract_h( L_shl( ImagData_fx[i], s ) ); /*Q15 - scale + s*/
875 7080352 : tmp16 = mac_r( tmp32, tmp16, tmp16 ); /*Q15 - 2*(scale - s)*/
876 :
877 7080352 : s = shl( sub( scale, s ), 1 );
878 :
879 7080352 : if ( tmp16 == 0 )
880 : {
881 0 : s = -16;
882 0 : move16();
883 : }
884 7080352 : if ( tmp16 == 0 )
885 : {
886 0 : tmp16 = 1;
887 0 : move16();
888 : }
889 :
890 7080352 : BASOP_Util_Sqrt_InvSqrt_MantExp( tmp16, s, &g, &g_e, &ig, &ig_e );
891 :
892 7080352 : if ( mdct_gains_fx != NULL )
893 : {
894 0 : mdct_gains_fx[k] = g; /*Q15 - g_e*/
895 0 : move16();
896 : }
897 :
898 7080352 : if ( mdct_gains_e != NULL )
899 : {
900 0 : mdct_gains_e[k] = g_e;
901 0 : move16();
902 : }
903 :
904 7080352 : if ( mdct_inv_gains_fx != NULL )
905 : {
906 7080352 : mdct_inv_gains_fx[k] = ig; /*Q15 - ig_e*/
907 7080352 : move16();
908 : }
909 :
910 7080352 : if ( mdct_inv_gains_e != NULL )
911 : {
912 7080352 : mdct_inv_gains_e[k] = ig_e;
913 7080352 : move16();
914 : }
915 :
916 7080352 : k = add( k, 1 );
917 :
918 :
919 7080352 : s = sub( norm_l( L_max( L_abs( RealData_fx[j] ), L_abs( ImagData_fx[j] ) ) ), 1 );
920 :
921 7080352 : tmp16 = extract_h( L_shl( RealData_fx[j], s ) ); /*Q15 - scale + s*/
922 7080352 : tmp32 = L_mult( tmp16, tmp16 ); /*Q15 - 2*(scale - s)*/
923 :
924 7080352 : tmp16 = extract_h( L_shl( ImagData_fx[j], s ) ); /*Q15 - scale + s*/
925 7080352 : tmp16 = mac_r( tmp32, tmp16, tmp16 ); /*Q15 - 2*(scale - s)*/
926 :
927 7080352 : s = shl( sub( scale, s ), 1 );
928 :
929 7080352 : if ( tmp16 == 0 )
930 : {
931 0 : s = -16;
932 0 : move16();
933 : }
934 7080352 : if ( tmp16 == 0 )
935 : {
936 0 : tmp16 = 1;
937 0 : move16();
938 : }
939 :
940 7080352 : BASOP_Util_Sqrt_InvSqrt_MantExp( tmp16, s, &g, &g_e, &ig, &ig_e );
941 :
942 7080352 : if ( mdct_gains_fx != NULL )
943 : {
944 0 : mdct_gains_fx[k] = g;
945 0 : move16();
946 : }
947 :
948 7080352 : if ( mdct_gains_e != NULL )
949 : {
950 0 : mdct_gains_e[k] = g_e;
951 0 : move16();
952 : }
953 :
954 7080352 : if ( mdct_inv_gains_fx != NULL )
955 : {
956 7080352 : mdct_inv_gains_fx[k] = ig;
957 7080352 : move16();
958 : }
959 :
960 7080352 : if ( mdct_inv_gains_e != NULL )
961 : {
962 7080352 : mdct_inv_gains_e[k] = ig_e;
963 7080352 : move16();
964 : }
965 :
966 7080352 : j = sub( j, 1 );
967 7080352 : k = add( k, 1 );
968 : }
969 :
970 221261 : return;
971 : }
972 : /**
973 : * \brief Perform mdct shaping. In the floating point software there are two functions,
974 : * mdct_noiseShaping and mdct_preShaping, which are combined here into a single function.
975 : * \param x spectrum mantissas
976 : * \param lg spectrum length
977 : * \param gains shaping gains mantissas
978 : * \param gains_exp shaping gains exponents
979 : */
980 582268 : void mdct_shaping(
981 : Word32 x[], /*Qx*/
982 : const Word16 lg, /*Q0*/
983 : const Word16 gains[], /*Q15 - gains_exp*/
984 : const Word16 gains_exp[]
985 : /*const Word16 nBands*/ /*Parameter added in IVAS, but always equal to FDNS_NPTS */
986 : )
987 : {
988 :
989 : Word16 i, k, l;
990 : Word16 m, n, k1, k2, j;
991 582268 : Word32 *px = x; /*Qx*/
992 582268 : Word16 const *pgains = gains;
993 582268 : Word16 const *pgainsexp = gains_exp;
994 : #ifndef ISSUE_1836_replace_overflow_libcom
995 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
996 : Flag Overflow = 0;
997 : #endif
998 : #endif
999 :
1000 : /* FDNS_NPTS = 64 */
1001 582268 : k = shr( lg, 6 ); /*Q0*/
1002 582268 : m = s_and( lg, 0x3F );
1003 :
1004 582268 : IF( m != 0 )
1005 : {
1006 19264 : IF( LE_16( m, FDNS_NPTS / 2 ) )
1007 : {
1008 19264 : n = idiv1616U( FDNS_NPTS, m ); /*Q0*/
1009 19264 : k1 = k;
1010 19264 : move16();
1011 19264 : k2 = add( k, 1 );
1012 : }
1013 : ELSE
1014 : {
1015 0 : n = idiv1616U( FDNS_NPTS, sub( FDNS_NPTS, m ) ); /*Q0*/
1016 0 : k1 = add( k, 1 );
1017 0 : k2 = k;
1018 0 : move16();
1019 : }
1020 :
1021 19264 : i = 0;
1022 19264 : move16();
1023 19264 : j = 0;
1024 19264 : move16();
1025 :
1026 1252160 : WHILE( LT_16( i, lg ) )
1027 : {
1028 :
1029 1232896 : k = k2;
1030 1232896 : move16();
1031 1232896 : if ( j != 0 )
1032 : {
1033 920592 : k = k1;
1034 920592 : move16();
1035 : }
1036 :
1037 1232896 : j = add( j, 1 );
1038 1232896 : if ( EQ_16( j, n ) )
1039 : {
1040 312304 : j = 0;
1041 312304 : move16();
1042 : }
1043 :
1044 : /* Limit number of loops, if end is reached */
1045 1232896 : k = s_min( k, sub( lg, i ) );
1046 :
1047 9022576 : FOR( l = 0; l < k; l++ )
1048 : {
1049 : #ifdef ISSUE_1836_replace_overflow_libcom
1050 7789680 : *x = L_shl_sat( Mpy_32_16_r( *x, *gains ), *gains_exp ); /*Qx*/
1051 : #else
1052 : *x = L_shl_o( Mpy_32_16_r( *x, *gains ), *gains_exp, &Overflow ); /*Qx*/
1053 : #endif
1054 7789680 : move32();
1055 7789680 : x++;
1056 : }
1057 1232896 : i = add( i, k );
1058 :
1059 1232896 : gains++;
1060 1232896 : gains_exp++;
1061 : }
1062 : }
1063 : ELSE
1064 : {
1065 3617533 : FOR( l = 0; l < k; l++ )
1066 : {
1067 3054529 : x = &px[l]; /*Qx*/
1068 3054529 : gains = pgains;
1069 3054529 : gains_exp = pgainsexp;
1070 198544385 : FOR( i = 0; i < FDNS_NPTS; i++ )
1071 : {
1072 : #ifdef ISSUE_1836_replace_overflow_libcom
1073 195489856 : *x = L_shl_sat( Mpy_32_16_r( *x, *gains ), *gains_exp ); /*Qx*/
1074 : #else
1075 : *x = L_shl_o( Mpy_32_16_r( *x, *gains ), *gains_exp, &Overflow ); /*Qx*/
1076 : #endif
1077 195489856 : move32();
1078 195489856 : x += k;
1079 195489856 : gains++;
1080 195489856 : gains_exp++;
1081 : }
1082 : }
1083 : }
1084 582268 : }
1085 :
1086 724 : void mdct_shaping_16(
1087 : const Word16 x[], /*Qx*/
1088 : const Word16 lg, /*Q0*/
1089 : const Word16 lg_total, /*Q0*/
1090 : const Word16 gains[], /*15 - gains_exp*/
1091 : const Word16 gains_exp[],
1092 : Word16 gains_max_exp,
1093 : Word32 y[] /*Qx*/ )
1094 : {
1095 : Word16 i, k, l;
1096 : Word16 m, gain_exp;
1097 : Word16 const *px;
1098 : Word32 *py;
1099 724 : Word16 const *pgains = gains;
1100 : Word16 gains_exp_loc[FDNS_NPTS];
1101 : Word16 const *pgains_exp;
1102 :
1103 : /* FDNS_NPTS = 64 */
1104 724 : k = shr( lg, 6 ); /*Q0*/
1105 724 : m = s_and( lg, 0x3F );
1106 :
1107 724 : assert( m == 0 );
1108 : {
1109 47060 : FOR( i = 0; i < FDNS_NPTS; i++ )
1110 : {
1111 46336 : gains_exp_loc[i] = sub( gains_exp[i], gains_max_exp );
1112 46336 : move16();
1113 : }
1114 5199 : FOR( l = 0; l < k; l++ )
1115 : {
1116 4475 : px = &x[l]; /*Qx*/
1117 4475 : py = &y[l]; /*Qx*/
1118 4475 : pgains = gains; /*15 - gains_exp*/
1119 4475 : pgains_exp = gains_exp_loc;
1120 290875 : FOR( i = 0; i < FDNS_NPTS; i++ )
1121 : {
1122 286400 : *py = L_shl( L_mult( *px, *pgains ), *pgains_exp ); /*Qx*/
1123 286400 : move32();
1124 286400 : px += k;
1125 286400 : py += k;
1126 286400 : pgains++;
1127 286400 : pgains_exp++;
1128 : }
1129 : }
1130 : }
1131 :
1132 724 : gain_exp = sub( gains_exp[FDNS_NPTS - 1], gains_max_exp );
1133 19998 : FOR( i = lg; i < lg_total; i++ )
1134 : {
1135 19274 : y[i] = L_shl( L_mult( x[i], gains[FDNS_NPTS - 1] ), gain_exp ); /*Qx*/
1136 19274 : move32();
1137 : }
1138 724 : }
1139 :
1140 773981 : void mdct_noiseShaping_ivas_fx(
1141 : Word32 x_fx[], /*Q31 - x_e*/
1142 : Word16 *x_e,
1143 : const Word16 lg, /*Q0*/
1144 : const Word16 gains_fx[], /*Q15 - gains_exp*/
1145 : const Word16 gains_exp[]
1146 : /*const Word16 nBands*/ /*Parameter added in IVAS, but always equal to FDNS_NPTS */
1147 : )
1148 : {
1149 : Word16 i, j, k, l;
1150 : Word16 m, n, k1, k2;
1151 :
1152 773981 : j = 0;
1153 773981 : move16();
1154 : /* FDNS_NPTS = 64 */
1155 773981 : k = shr( lg, 6 ); /*Q0*/
1156 773981 : m = s_and( lg, 0x3F );
1157 :
1158 773981 : Word16 max_e = MIN16B;
1159 773981 : move16();
1160 50308765 : FOR( i = 0; i < FDNS_NPTS; i++ )
1161 : {
1162 49534784 : max_e = s_max( max_e, add( *x_e, gains_exp[i] ) );
1163 : }
1164 :
1165 773981 : IF( m != 0 )
1166 : {
1167 8246 : IF( LE_16( m, FDNS_NPTS / 2 ) )
1168 : {
1169 8246 : n = idiv1616U( FDNS_NPTS, m ); /*Q0*/
1170 8246 : k1 = k;
1171 8246 : move16();
1172 8246 : k2 = add( k, 1 );
1173 : }
1174 : ELSE
1175 : {
1176 0 : n = idiv1616U( FDNS_NPTS, sub( FDNS_NPTS, m ) ); /*Q0*/
1177 0 : k1 = add( k, 1 );
1178 0 : k2 = k;
1179 0 : move16();
1180 : }
1181 :
1182 8246 : i = 0;
1183 8246 : move16();
1184 8246 : j = 0;
1185 8246 : move16();
1186 :
1187 535990 : WHILE( LT_16( i, lg ) )
1188 : {
1189 527744 : IF( j % n != 0 )
1190 : {
1191 387696 : k = k1;
1192 387696 : move16();
1193 : }
1194 : ELSE
1195 : {
1196 140048 : k = k2;
1197 140048 : move16();
1198 : }
1199 :
1200 : /* Limit number of loops, if end is reached */
1201 527744 : k = s_min( k, sub( lg, i ) );
1202 :
1203 3993104 : FOR( l = 0; l < k; l++ )
1204 : {
1205 3465360 : x_fx[i] = Mpy_32_16_1( x_fx[i], gains_fx[j] ); /*Q31 - x_e*/
1206 3465360 : move32();
1207 3465360 : x_fx[i] = L_shr( x_fx[i], sub( max_e, add( *x_e, gains_exp[j] ) ) ); /*Q31 - max_e*/
1208 3465360 : move32();
1209 3465360 : i = add( i, 1 );
1210 : }
1211 527744 : j = add( j, 1 );
1212 : }
1213 : }
1214 : ELSE
1215 : {
1216 49772775 : FOR( i = 0; i < lg; )
1217 : {
1218 337562880 : FOR( l = 0; l < k; l++ )
1219 : {
1220 288555840 : x_fx[i] = Mpy_32_16_1( x_fx[i], gains_fx[j] ); /*Q31 - x_e*/
1221 288555840 : move32();
1222 288555840 : x_fx[i] = L_shr( x_fx[i], sub( max_e, add( *x_e, gains_exp[j] ) ) ); /*Q31 - max_e*/
1223 288555840 : move32();
1224 288555840 : i = add( i, 1 );
1225 : }
1226 49007040 : j = add( j, 1 );
1227 : }
1228 : }
1229 :
1230 773981 : *x_e = max_e;
1231 773981 : move16();
1232 :
1233 773981 : return;
1234 : }
1235 :
1236 :
1237 17444 : void mdct_noiseShaping_interp(
1238 : Word32 x[], /*Qx*/
1239 : const Word16 lg, /*Q0*/
1240 : Word16 gains[], /*Q15 - gains_exp*/
1241 : Word16 gains_exp[] )
1242 : {
1243 : Word16 i, j, jp, jn, k, l;
1244 : Word16 g, pg, ng, e, tmp;
1245 :
1246 :
1247 17444 : assert( lg % FDNS_NPTS == 0 );
1248 17444 : k = shr( lg, 6 ); /* FDNS_NPTS = 64 Q0*/
1249 :
1250 17444 : IF( gains )
1251 : {
1252 : /* Linear interpolation */
1253 17444 : IF( EQ_16( k, 4 ) )
1254 : {
1255 15794 : jp = 0;
1256 15794 : move16();
1257 15794 : j = 0;
1258 15794 : move16();
1259 15794 : jn = 1;
1260 15794 : move16();
1261 :
1262 1026610 : FOR( i = 0; i < lg; i += 4 )
1263 : {
1264 1010816 : pg = gains[jp]; /*Q15 - gains_exp*/
1265 1010816 : move16();
1266 1010816 : g = gains[j]; /*Q15 - gains_exp*/
1267 1010816 : move16();
1268 1010816 : ng = gains[jn]; /*Q15 - gains_exp*/
1269 1010816 : move16();
1270 :
1271 : /* common exponent for pg and g */
1272 1010816 : tmp = sub( gains_exp[j], gains_exp[jp] );
1273 1010816 : if ( tmp > 0 )
1274 110930 : pg = shr( pg, tmp );
1275 1010816 : if ( tmp < 0 )
1276 66439 : g = shl( g, tmp );
1277 1010816 : e = s_max( gains_exp[j], gains_exp[jp] );
1278 :
1279 1010816 : tmp = mac_r( L_mult( pg, 12288 /*0.375f Q15*/ ), g, 20480 /*0.625f Q15*/ ); /*Q15 - gains_exp*/
1280 1010816 : x[i] = L_shl( Mpy_32_16_1( x[i], tmp ), e ); /*Qx*/
1281 1010816 : move32();
1282 :
1283 1010816 : tmp = mac_r( L_mult( pg, 4096 /*0.125f Q15*/ ), g, 28672 /*0.875f Q15*/ ); /*Q15 - gains_exp*/
1284 1010816 : x[i + 1] = L_shl( Mpy_32_16_1( x[i + 1], tmp ), e ); /*Qx*/
1285 1010816 : move32();
1286 :
1287 : /* common exponent for g and ng */
1288 1010816 : g = gains[j]; /*Q15 - gains_exp*/
1289 1010816 : move16();
1290 1010816 : tmp = sub( gains_exp[j], gains_exp[jn] );
1291 1010816 : if ( tmp > 0 )
1292 66439 : ng = shr( ng, tmp );
1293 1010816 : if ( tmp < 0 )
1294 110930 : g = shl( g, tmp );
1295 1010816 : e = s_max( gains_exp[j], gains_exp[jn] );
1296 :
1297 1010816 : tmp = mac_r( L_mult( g, 28672 /*0.875f Q15*/ ), ng, 4096 /*0.125f Q15*/ ); /*Q15 - gains_exp*/
1298 1010816 : x[i + 2] = L_shl( Mpy_32_16_1( x[i + 2], tmp ), e ); /*Qx*/
1299 1010816 : move32();
1300 :
1301 1010816 : tmp = mac_r( L_mult( g, 20480 /*0.625f Q15*/ ), ng, 12288 /*0.375f Q15*/ ); /*Q15 - gains_exp*/
1302 1010816 : x[i + 3] = L_shl( Mpy_32_16_1( x[i + 3], tmp ), e ); /*Qx*/
1303 1010816 : move32();
1304 :
1305 1010816 : jp = j;
1306 1010816 : move16();
1307 1010816 : j = jn;
1308 1010816 : move16();
1309 1010816 : jn = s_min( add( jn, 1 ), FDNS_NPTS - 1 );
1310 : }
1311 : }
1312 1650 : ELSE IF( EQ_16( k, 5 ) )
1313 : {
1314 1650 : jp = 0;
1315 1650 : move16();
1316 1650 : j = 0;
1317 1650 : move16();
1318 1650 : jn = 1;
1319 1650 : move16();
1320 :
1321 107250 : FOR( i = 0; i < lg; i += 5 )
1322 : {
1323 105600 : pg = gains[jp]; /*Q15 - gains_exp*/
1324 105600 : move16();
1325 105600 : g = gains[j]; /*Q15 - gains_exp*/
1326 105600 : move16();
1327 105600 : ng = gains[jn]; /*Q15 - gains_exp*/
1328 105600 : move16();
1329 :
1330 : /* common exponent for pg and g */
1331 105600 : tmp = sub( gains_exp[j], gains_exp[jp] );
1332 105600 : if ( tmp > 0 )
1333 11197 : pg = shr( pg, tmp );
1334 105600 : if ( tmp < 0 )
1335 6554 : g = shl( g, tmp );
1336 105600 : e = s_max( gains_exp[j], gains_exp[jp] );
1337 :
1338 105600 : tmp = mac_r( L_mult( pg, 13107 /*0.40f Q15*/ ), g, 19661 /*0.60f Q15*/ ); /*Q15 - gains_exp*/
1339 105600 : x[i] = L_shl( Mpy_32_16_1( x[i], tmp ), e ); /*Qx*/
1340 105600 : move32();
1341 :
1342 105600 : tmp = mac_r( L_mult( pg, 6554 /*0.20f Q15*/ ), g, 26214 /*0.80f Q15*/ ); /*Q15 - gains_exp*/
1343 105600 : x[i + 1] = L_shl( Mpy_32_16_1( x[i + 1], tmp ), e ); /*Qx*/
1344 105600 : move32();
1345 :
1346 :
1347 105600 : x[i + 2] = L_shl( Mpy_32_16_1( x[i + 2], gains[j] ), gains_exp[j] ); /*Qx*/
1348 105600 : move32();
1349 :
1350 : /* common exponent for g and ng */
1351 105600 : g = gains[j]; /*Q15 - gains_exp*/
1352 105600 : move16();
1353 105600 : tmp = sub( gains_exp[j], gains_exp[jn] );
1354 105600 : if ( tmp > 0 )
1355 6554 : ng = shr( ng, tmp );
1356 105600 : if ( tmp < 0 )
1357 11197 : g = shl( g, tmp );
1358 105600 : e = s_max( gains_exp[j], gains_exp[jn] );
1359 :
1360 105600 : tmp = mac_r( L_mult( g, 26214 /*0.80f Q15*/ ), ng, 6554 /*0.20f Q15*/ ); /*Q15 - gains_exp*/
1361 105600 : x[i + 3] = L_shl( Mpy_32_16_1( x[i + 3], tmp ), e ); /*Qx*/
1362 105600 : move32();
1363 :
1364 105600 : tmp = mac_r( L_mult( g, 19661 /*0.60f Q15*/ ), ng, 13107 /*0.40f Q15*/ ); /*Q15 - gains_exp*/
1365 105600 : x[i + 4] = L_shl( Mpy_32_16_1( x[i + 4], tmp ), e ); /*Qx*/
1366 105600 : move32();
1367 :
1368 105600 : jp = j;
1369 105600 : move16();
1370 105600 : j = jn;
1371 105600 : move16();
1372 105600 : jn = s_min( add( jn, 1 ), FDNS_NPTS - 1 );
1373 : }
1374 : }
1375 : ELSE /* no interpolation */
1376 : {
1377 0 : FOR( i = 0; i < FDNS_NPTS; i++ )
1378 : {
1379 0 : FOR( l = 0; l < k; l++ )
1380 : {
1381 0 : *x = L_shl( Mpy_32_16_1( *x, *gains ), *gains_exp ); /*Qx*/
1382 0 : move32();
1383 0 : x++;
1384 : }
1385 :
1386 0 : gains++;
1387 0 : gains_exp++;
1388 : }
1389 : }
1390 : }
1391 17444 : }
1392 :
1393 56333 : void PsychAdaptLowFreqDeemph(
1394 : Word32 x[], /*Qx*/
1395 : const Word16 lpcGains[], /*Q15 - lpcGains_e*/
1396 : const Word16 lpcGains_e[],
1397 : Word16 lf_deemph_factors[] /*Q15*/ )
1398 : {
1399 : Word16 i;
1400 : Word16 max_val, max_e, fac, min, min_e, tmp, tmp_e;
1401 : Word32 L_tmp;
1402 : #ifndef ISSUE_1836_replace_overflow_libcom
1403 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
1404 : Flag Overflow = 0;
1405 : #endif
1406 : #endif
1407 :
1408 :
1409 56333 : assert( lpcGains[0] >= 0x4000 );
1410 :
1411 56333 : max_val = lpcGains[0]; /*Q15 - lpcGains_e*/
1412 56333 : move16();
1413 56333 : max_e = lpcGains_e[0];
1414 56333 : move16();
1415 56333 : min = lpcGains[0]; /*Q15 - lpcGains_e*/
1416 56333 : move16();
1417 56333 : min_e = lpcGains_e[0];
1418 56333 : move16();
1419 :
1420 : /* find minimum (min) and maximum (max_val) of LPC gains in low frequencies */
1421 506997 : FOR( i = 1; i < 9; i++ )
1422 : {
1423 450664 : IF( compMantExp16Unorm( lpcGains[i], lpcGains_e[i], min, min_e ) < 0 )
1424 : {
1425 333414 : min = lpcGains[i]; /*Q15 - lpcGains_e*/
1426 333414 : move16();
1427 333414 : min_e = lpcGains_e[i];
1428 333414 : move16();
1429 : }
1430 :
1431 450664 : IF( compMantExp16Unorm( lpcGains[i], lpcGains_e[i], max_val, max_e ) > 0 )
1432 : {
1433 82499 : max_val = lpcGains[i]; /*Q15 - lpcGains_e*/
1434 82499 : move16();
1435 82499 : max_e = lpcGains_e[i];
1436 82499 : move16();
1437 : }
1438 : }
1439 :
1440 56333 : min_e = add( min_e, 5 ); /* min *= 32.0f; */
1441 :
1442 56333 : test();
1443 56333 : IF( ( compMantExp16Unorm( max_val, max_e, min, min_e ) < 0 ) && ( min > 0 ) )
1444 : {
1445 : /* fac = tmp = (float)pow(max_val / min, 0.0078125f); */
1446 56333 : tmp_e = min_e;
1447 56333 : move16();
1448 56333 : tmp = Inv16( min, &tmp_e ); /*Q15 - tmp_e*/
1449 : #ifdef FIX_1984_SAT_IN_PSYCHAD
1450 56333 : L_tmp = L_shl_sat( L_mult_sat( tmp, max_val ), add( tmp_e, max_e ) ); /* Q31 */
1451 : #else
1452 : L_tmp = L_shl( L_mult( tmp, max_val ), add( tmp_e, max_e ) ); /* Q31 */
1453 : #endif
1454 56333 : L_tmp = BASOP_Util_Log2( L_tmp ); /* Q25 */
1455 56333 : L_tmp = L_shr( L_tmp, 7 ); /* 0.0078125f = 1.f/(1<<7) */
1456 56333 : L_tmp = BASOP_Util_InvLog2( L_tmp ); /* Q31 */
1457 : #ifdef ISSUE_1836_replace_overflow_libcom
1458 56333 : tmp = round_fx_sat( L_tmp ); /* Q15 */
1459 : #else
1460 : tmp = round_fx_o( L_tmp, &Overflow ); /* Q15 */
1461 : #endif
1462 56333 : fac = tmp; /* Q15 */
1463 56333 : move16();
1464 :
1465 : /* gradual lowering of lowest 32 bins; DC is lowered by (max_val/tmp)^1/4 */
1466 1858989 : FOR( i = 31; i >= 0; i-- )
1467 : {
1468 1802656 : x[i] = Mpy_32_16_1( x[i], fac );
1469 1802656 : move32();
1470 1802656 : if ( lf_deemph_factors != NULL )
1471 : {
1472 1007552 : lf_deemph_factors[i] = mult_r( lf_deemph_factors[i], fac );
1473 1007552 : move16();
1474 : }
1475 1802656 : fac = mult_r( fac, tmp ); /* Q15 */
1476 : }
1477 : }
1478 56333 : }
1479 :
1480 264359 : void AdaptLowFreqDeemph(
1481 : Word32 x[], /*Q31 - x_e*/
1482 : Word16 x_e,
1483 : Word16 tcx_lpc_shaped_ari, /*Q0*/
1484 : Word16 lpcGains[], /*Q15 - lpcGains_e*/
1485 : Word16 lpcGains_e[],
1486 : const Word16 lg, /*Q0*/
1487 : Word16 lf_deemph_factors[] /*Q15*/ )
1488 : {
1489 :
1490 : Word16 i, i_max, i_max_old, lg_4;
1491 : Word32 v2, v4, tmp32;
1492 :
1493 264359 : tmp32 = 0; /* to avoid compilation warnings */
1494 264359 : move32();
1495 :
1496 264359 : IF( tcx_lpc_shaped_ari == 0 )
1497 : {
1498 215429 : v2 = L_shl( 2, sub( 31, x_e ) ); /* 2.0 */
1499 215429 : v4 = L_shl( v2, 1 ); /* 4.0 */
1500 215429 : lg_4 = shr( lg, 2 ); /* lg/4 */
1501 :
1502 : /* 1. find first magnitude maximum in lower quarter of spectrum */
1503 215429 : i_max = -1;
1504 215429 : move16();
1505 :
1506 1259123 : FOR( i = 0; i < lg_4; i++ )
1507 : {
1508 1251884 : IF( GE_32( L_abs( x[i] ), v4 ) )
1509 : {
1510 :
1511 : /* Debug initialization to catch illegal x[i] values. */
1512 208190 : tmp32 = 0;
1513 208190 : move32();
1514 :
1515 208190 : if ( x[i] < 0 )
1516 103932 : tmp32 = L_add( x[i], v2 ); /*Q31 - x_e*/
1517 208190 : if ( x[i] > 0 )
1518 104258 : tmp32 = L_sub( x[i], v2 ); /*Q31 - x_e*/
1519 :
1520 208190 : assert( tmp32 != 0 );
1521 :
1522 208190 : x[i] = tmp32; /*Q31 - x_e*/
1523 208190 : move32();
1524 208190 : i_max = i;
1525 208190 : move16();
1526 208190 : BREAK;
1527 : }
1528 : }
1529 :
1530 : /* 2. expand value range of all xi up to i_max: two extra steps */
1531 716243 : FOR( i = 0; i < i_max; i++ )
1532 : {
1533 500814 : x[i] = L_shr( x[i], 1 ); /*Q31 - x_e*/
1534 500814 : move32();
1535 500814 : lf_deemph_factors[i] = shr( lf_deemph_factors[i], 1 ); /*Q15*/
1536 500814 : move16();
1537 : }
1538 :
1539 : /* 3. find first magnitude maximum in lower quarter of spectrum */
1540 215429 : i_max_old = i_max; /*Q0*/
1541 215429 : move16();
1542 :
1543 215429 : IF( i_max_old >= 0 )
1544 : {
1545 208190 : i_max = -1;
1546 208190 : move16();
1547 :
1548 1048750 : FOR( i = 0; i < lg_4; i++ )
1549 : {
1550 1048738 : IF( GE_32( L_abs( x[i] ), v4 ) )
1551 : {
1552 208178 : assert( x[i] != 0 );
1553 208178 : if ( x[i] < 0 )
1554 104463 : tmp32 = L_add( x[i], v2 ); /*Q31 - x_e*/
1555 208178 : if ( x[i] >= 0 )
1556 103715 : tmp32 = L_sub( x[i], v2 ); /*Q31 - x_e*/
1557 208178 : x[i] = tmp32; /*Q31 - x_e*/
1558 208178 : move32();
1559 208178 : i_max = i;
1560 208178 : move16();
1561 208178 : BREAK;
1562 : }
1563 : }
1564 : }
1565 :
1566 : /* 4. expand value range of all xi up to i_max: two extra steps */
1567 1055189 : FOR( i = 0; i < i_max; i++ )
1568 : {
1569 839760 : x[i] = L_shr( x[i], 1 ); /*Q31 - x_e*/
1570 839760 : move32();
1571 839760 : lf_deemph_factors[i] = shr( lf_deemph_factors[i], 1 ); /*Q15*/
1572 839760 : move16();
1573 : }
1574 :
1575 : /* 5. always expand two lines; lines could be at index 0 and 1! */
1576 215429 : i_max = s_max( i_max, i_max_old ); /*Q0*/
1577 215429 : i = add( i_max, 1 );
1578 :
1579 215429 : IF( x[i] < 0 )
1580 : {
1581 95575 : tmp32 = L_sub( x[i], L_negate( v4 ) );
1582 :
1583 95575 : if ( tmp32 > 0 )
1584 : {
1585 34013 : lf_deemph_factors[i] = shr( lf_deemph_factors[i], 1 ); /*Q15*/
1586 34013 : move16();
1587 : }
1588 95575 : if ( tmp32 <= 0 )
1589 : {
1590 61562 : x[i] = L_add( x[i], v2 ); /*Q31 - x_e*/
1591 61562 : move32();
1592 : }
1593 95575 : if ( tmp32 > 0 )
1594 : {
1595 34013 : x[i] = L_shr( x[i], 1 ); /*Q31 - x_e*/
1596 34013 : move32();
1597 : }
1598 : }
1599 : ELSE
1600 : {
1601 119854 : tmp32 = L_sub( x[i], v4 );
1602 :
1603 119854 : if ( tmp32 < 0 )
1604 : {
1605 56422 : lf_deemph_factors[i] = shr( lf_deemph_factors[i], 1 ); /*Q15*/
1606 56422 : move16();
1607 : }
1608 119854 : if ( tmp32 >= 0 )
1609 : {
1610 63432 : x[i] = L_sub( x[i], v2 ); /*Q31 - x_e*/
1611 63432 : move32();
1612 : }
1613 119854 : if ( tmp32 < 0 )
1614 : {
1615 56422 : x[i] = L_shr( x[i], 1 ); /*Q31 - x_e*/
1616 56422 : move32();
1617 : }
1618 : }
1619 215429 : i = add( i, 1 );
1620 :
1621 215429 : IF( x[i] < 0 )
1622 : {
1623 92028 : tmp32 = L_sub( x[i], L_negate( v4 ) );
1624 :
1625 92028 : if ( tmp32 > 0 )
1626 : {
1627 35995 : lf_deemph_factors[i] = shr( lf_deemph_factors[i], 1 ); /*Q15*/
1628 35995 : move16();
1629 : }
1630 92028 : if ( tmp32 <= 0 )
1631 : {
1632 56033 : x[i] = L_add( x[i], v2 ); /*Q31 - x_e*/
1633 56033 : move32();
1634 : }
1635 92028 : if ( tmp32 > 0 )
1636 : {
1637 35995 : x[i] = L_shr( x[i], 1 ); /*Q31 - x_e*/
1638 35995 : move32();
1639 : }
1640 : }
1641 : ELSE
1642 : {
1643 123401 : tmp32 = L_sub( x[i], v4 );
1644 :
1645 123401 : if ( tmp32 < 0 )
1646 : {
1647 67511 : lf_deemph_factors[i] = shr( lf_deemph_factors[i], 1 ); /*Q15*/
1648 67511 : move16();
1649 : }
1650 123401 : if ( tmp32 >= 0 )
1651 : {
1652 55890 : x[i] = L_sub( x[i], v2 ); /*Q31 - x_e*/
1653 55890 : move32();
1654 : }
1655 123401 : if ( tmp32 < 0 )
1656 : {
1657 67511 : x[i] = L_shr( x[i], 1 ); /*Q31 - x_e*/
1658 67511 : move32();
1659 : }
1660 : }
1661 : }
1662 : ELSE /*if(!tcx_lpc_shaped_ari)*/
1663 : {
1664 48930 : PsychAdaptLowFreqDeemph( x, lpcGains, lpcGains_e, lf_deemph_factors );
1665 : } /*if(!tcx_lpc_shaped_ari)*/
1666 264359 : }
1667 :
1668 221178 : void tcx_noise_filling(
1669 : Word32 *Q, /*Q31 - Q_e*/
1670 : Word16 Q_e,
1671 : Word16 seed,
1672 : const Word16 iFirstLine, /*Q0*/
1673 : const Word16 lowpassLine, /*Q0*/
1674 : const Word16 nTransWidth, /*Q0*/
1675 : const Word16 L_frame, /*Q0*/
1676 : const Word16 tiltCompFactor, /*Q15*/
1677 : Word16 fac_ns, /*Q15*/
1678 : Word16 *infoTCXNoise, /*Q0*/
1679 : const Word16 element_mode /* i : IVAS element mode Q0*/
1680 : )
1681 : {
1682 : Word16 i, m, segmentOffset;
1683 : Word16 win; /* window coefficient */
1684 : Word16 tilt_factor;
1685 : Word32 nrg;
1686 : Word16 tmp1, tmp2, s;
1687 : Word32 tmp32;
1688 :
1689 :
1690 : /* get inverse frame length */
1691 221178 : tmp1 = getInvFrameLen( L_frame ); /*Q21*/
1692 :
1693 : /* tilt_factor = (float)pow(max_val(0.375f, tiltCompFactor), 1.0f/(float)L_frame); */
1694 221178 : tmp32 = BASOP_Util_Log2( L_deposit_h( s_max( 0x3000, tiltCompFactor ) ) ); /* 6Q25 */
1695 221178 : tmp32 = L_shr( Mpy_32_16_1( tmp32, tmp1 ), 6 ); /*Q25*/
1696 : BASOP_SATURATE_WARNING_OFF_EVS;
1697 221178 : tilt_factor = round_fx_sat( BASOP_Util_InvLog2( tmp32 ) ); /*Q15*/
1698 : BASOP_SATURATE_WARNING_ON_EVS;
1699 :
1700 : /* find last nonzero line below iFirstLine, use it as start offset */
1701 221178 : i = iFirstLine;
1702 221178 : move16();
1703 221178 : tmp1 = shr( iFirstLine, 1 ); /*Q0*/
1704 221178 : IF( EQ_16( element_mode, IVAS_CPE_MDCT ) ) /* ... but only in mono or parametric stereo since it may cause binaural unmasking in discrete stereo */
1705 : {
1706 0 : segmentOffset = i;
1707 0 : move16();
1708 : }
1709 : ELSE
1710 : {
1711 657831 : FOR( ; i > tmp1; i-- )
1712 : {
1713 656549 : IF( Q[i] != 0 )
1714 : {
1715 219896 : BREAK;
1716 : }
1717 : }
1718 : /* fac_ns *= (float)pow(tilt_factor, (float)i); */
1719 15124497 : FOR( m = 0; m < i; m++ )
1720 : {
1721 14903319 : fac_ns = mult_r( fac_ns, tilt_factor ); /*Q15*/
1722 : }
1723 221178 : i = add( i, 1 );
1724 221178 : segmentOffset = i;
1725 : }
1726 221178 : nrg = L_deposit_l( 1 );
1727 221178 : win = 0;
1728 221178 : move16();
1729 :
1730 66645995 : FOR( ; i < lowpassLine; i++ )
1731 : {
1732 66424817 : fac_ns = mult_r( fac_ns, tilt_factor ); /*Q15*/
1733 :
1734 66424817 : IF( Q[i] != 0 )
1735 : {
1736 18815257 : IF( win > 0 )
1737 : {
1738 : /* RMS-normalize current noise-filled segment */
1739 9441726 : tmp1 = BASOP_Util_Divide3216_Scale( nrg, sub( i, segmentOffset ), &s ); /* mean */
1740 9441726 : s = add( s, 9 - 15 ); /* scaling */
1741 9441726 : tmp1 = ISqrt16( tmp1, &s ); /* 1/RMS Q15 - s*/
1742 9441726 : tmp1 = mult_r( tmp1, inv_int[nTransWidth] ); /* compensate win Q15 - s*/
1743 9441726 : s = add( s, sub( 16, Q_e ) ); /* scaling */
1744 :
1745 9441726 : tmp2 = sub( i, win );
1746 9441726 : IF( LT_16( segmentOffset, tmp2 ) )
1747 : {
1748 10011092 : FOR( m = segmentOffset; m < tmp2; m++ )
1749 : {
1750 8807711 : Q[m] = L_shl( Mpy_32_16_1( Q[m], tmp1 ), s ); /*Q31 - Q_e*/
1751 8807711 : move32();
1752 : }
1753 : }
1754 :
1755 9441726 : tmp2 = mult( tmp1, inv_int[nTransWidth] );
1756 9441726 : tmp1 = extract_l( L_mult0( tmp2, win ) );
1757 36404104 : FOR( m = sub( i, win ); m < i; m++ )
1758 : {
1759 26962378 : Q[m] = L_shl( Mpy_32_16_1( Q[m], tmp1 ), s ); /*Q31 - Q_e*/
1760 26962378 : move32();
1761 26962378 : win = sub( win, 1 );
1762 26962378 : tmp1 = sub( tmp1, tmp2 );
1763 : }
1764 :
1765 9441726 : nrg = L_deposit_l( 1 ); /* start new segment: reset noise segment energy */
1766 : }
1767 18815257 : segmentOffset = add( i, 1 );
1768 : }
1769 : ELSE /* line is zero, so fill line and update window and energy */
1770 : {
1771 47609560 : if ( LT_16( win, nTransWidth ) )
1772 : {
1773 28283660 : win = add( win, 1 );
1774 : }
1775 :
1776 47609560 : Random( &seed );
1777 47609560 : Q[i] = L_mult0( mult( seed, fac_ns ), win ); /*Q31 - Q_e*/
1778 47609560 : move32();
1779 :
1780 47609560 : tmp1 = shr( seed, 4 );
1781 47609560 : nrg = L_mac0( nrg, tmp1, tmp1 ); /* sum up energy of current noise segment */
1782 :
1783 47609560 : if ( infoTCXNoise ) /* set noiseflags for IGF */
1784 : {
1785 116660 : infoTCXNoise[i] = 1;
1786 116660 : move16();
1787 : }
1788 : }
1789 : }
1790 :
1791 221178 : IF( win > 0 )
1792 : {
1793 : /* RMS-normalize uppermost noise-filled segment */
1794 205185 : tmp1 = BASOP_Util_Divide3216_Scale( nrg, sub( lowpassLine, segmentOffset ), &s ); /* mean */
1795 205185 : s = add( s, 9 - 15 ); /* compensate energy scaling */
1796 205185 : tmp1 = ISqrt16( tmp1, &s ); /* 1/RMS Q15 - s*/
1797 205185 : tmp1 = mult_r( tmp1, inv_int[nTransWidth] ); /* compensate win Q15 - s*/
1798 205185 : s = add( s, sub( 16, Q_e ) ); /* compensate noise scaling */
1799 :
1800 12044656 : FOR( m = segmentOffset; m < lowpassLine; m++ )
1801 : {
1802 11839471 : Q[m] = L_shl( Mpy_32_16_1( Q[m], tmp1 ), s ); /*Q31 - Q_e*/
1803 11839471 : move32();
1804 : }
1805 : }
1806 221178 : }
1807 :
1808 808896 : void tcx_noise_filling_with_shift(
1809 : Word32 *Q, /*Q31 - Q_e*/
1810 : Word16 *Q_e,
1811 : Word16 seed, /*Q0*/
1812 : const Word16 iFirstLine, /*Q0*/
1813 : const Word16 lowpassLine, /*Q0*/
1814 : const Word16 nTransWidth, /*Q0*/
1815 : const Word16 L_frame, /*Q0*/
1816 : const Word16 tiltCompFactor, /*Q0*/
1817 : Word16 fac_ns, /*Q15*/
1818 : Word16 *infoTCXNoise, /*Q0*/
1819 : const Word16 element_mode /* i : IVAS element mode Q0*/
1820 : )
1821 : {
1822 : Word16 i, m, segmentOffset;
1823 : Word16 win; /* window coefficient */
1824 : Word16 tilt_factor;
1825 : Word32 nrg;
1826 : Word16 tmp1, tmp2, s;
1827 : Word32 tmp32;
1828 : Word16 new_Q_e[N_MAX];
1829 :
1830 808896 : set16_fx( new_Q_e, *Q_e, N_MAX );
1831 :
1832 : /* get inverse frame length */
1833 808896 : tmp1 = getInvFrameLen( L_frame ); /*Q21*/
1834 :
1835 : /* tilt_factor = (float)pow(max_val(0.375f, tiltCompFactor), 1.0f/(float)L_frame); */
1836 808896 : tmp32 = BASOP_Util_Log2( L_deposit_h( s_max( 0x3000, tiltCompFactor ) ) ); /* 6Q25 */
1837 808896 : tmp32 = L_shr( Mpy_32_16_1( tmp32, tmp1 ), 6 ); /*Q25*/
1838 : BASOP_SATURATE_WARNING_OFF_EVS;
1839 808896 : tilt_factor = round_fx_sat( BASOP_Util_InvLog2( tmp32 ) ); /*Q15*/
1840 : BASOP_SATURATE_WARNING_ON_EVS;
1841 :
1842 : /* find last nonzero line below iFirstLine, use it as start offset */
1843 808896 : i = iFirstLine;
1844 808896 : move16();
1845 808896 : tmp1 = shr( iFirstLine, 1 );
1846 808896 : IF( EQ_16( element_mode, IVAS_CPE_MDCT ) ) /* ... but only in mono or parametric stereo since it may cause binaural unmasking in discrete stereo */
1847 : {
1848 603311 : segmentOffset = i;
1849 603311 : move16();
1850 : }
1851 : ELSE
1852 : {
1853 594390 : FOR( ; i > tmp1; i-- )
1854 : {
1855 593251 : IF( Q[i] != 0 )
1856 : {
1857 204446 : BREAK;
1858 : }
1859 : }
1860 : /* fac_ns *= (float)pow(tilt_factor, (float)i); */
1861 14449067 : FOR( m = 0; m < i; m++ )
1862 : {
1863 14243482 : fac_ns = mult_r( fac_ns, tilt_factor ); /*Q15*/
1864 : }
1865 205585 : i = add( i, 1 );
1866 205585 : segmentOffset = i;
1867 205585 : move16();
1868 : }
1869 808896 : nrg = L_deposit_l( 1 );
1870 808896 : win = 0;
1871 808896 : move16();
1872 :
1873 360697679 : FOR( ; i < lowpassLine; i++ )
1874 : {
1875 359888783 : fac_ns = mult_r( fac_ns, tilt_factor ); /*Q15*/
1876 :
1877 359888783 : IF( Q[i] != 0 )
1878 : {
1879 84875016 : IF( win > 0 )
1880 : {
1881 : /* RMS-normalize current noise-filled segment */
1882 39466260 : tmp1 = BASOP_Util_Divide3216_Scale( nrg, sub( i, segmentOffset ), &s ); /* mean */
1883 : // Q-factor of nrg is -8. exp = 31-(-8) = 39
1884 39466260 : s = add( s, 39 - 15 ); /* scaling */
1885 39466260 : tmp1 = ISqrt16( tmp1, &s ); /* 1/RMS Q15 - s*/
1886 39466260 : tmp1 = mult_r( tmp1, inv_int[nTransWidth] ); /* compensate win Q15 - s*/
1887 :
1888 39466260 : tmp2 = sub( i, win );
1889 39466260 : IF( LT_16( segmentOffset, tmp2 ) )
1890 : {
1891 69883587 : FOR( m = segmentOffset; m < tmp2; m++ )
1892 : {
1893 64475615 : Word16 nrm = 31;
1894 64475615 : move16();
1895 64475615 : Q[m] = Mpy_32_16_1( Q[m], tmp1 ); /*Q31 - Q_e*/
1896 64475615 : move32();
1897 64475615 : IF( Q[m] )
1898 : {
1899 64469316 : nrm = norm_l( Q[m] );
1900 : }
1901 64475615 : Q[m] = L_shl( Q[m], nrm ); /*Q31 - Q_e + nrm*/
1902 64475615 : move32();
1903 64475615 : new_Q_e[m] = sub( add( new_Q_e[m], s ), nrm );
1904 64475615 : move32();
1905 : }
1906 : }
1907 :
1908 39466260 : tmp2 = mult( tmp1, inv_int[nTransWidth] ); /*Q15 - s*/
1909 39466260 : tmp1 = extract_l( L_mult0( tmp2, win ) ); /*Q15 - s*/
1910 155134333 : FOR( m = sub( i, win ); m < i; m++ )
1911 : {
1912 115668073 : Word16 nrm = 31;
1913 :
1914 115668073 : Q[m] = Mpy_32_16_1( Q[m], tmp1 ); /*Q31 - Q_e*/
1915 115668073 : move32();
1916 115668073 : IF( Q[m] )
1917 : {
1918 115657965 : nrm = norm_l( Q[m] );
1919 : }
1920 115668073 : Q[m] = L_shl( Q[m], nrm ); /*Q31 - Q_e*/
1921 115668073 : move32();
1922 115668073 : new_Q_e[m] = sub( add( new_Q_e[m], s ), nrm );
1923 115668073 : move32();
1924 115668073 : win = sub( win, 1 );
1925 115668073 : tmp1 = sub( tmp1, tmp2 );
1926 : }
1927 :
1928 39466260 : nrg = L_deposit_l( 1 ); /* start new segment: reset noise segment energy */
1929 : }
1930 84875016 : segmentOffset = add( i, 1 );
1931 : }
1932 : ELSE /* line is zero, so fill line and update window and energy */
1933 : {
1934 275013767 : IF( LT_16( win, nTransWidth ) )
1935 : {
1936 120794935 : win = add( win, 1 );
1937 : }
1938 :
1939 275013767 : Word16 nrm = 31;
1940 275013767 : move16();
1941 :
1942 275013767 : Random( &seed );
1943 275013767 : Q[i] = L_mult0( mult( seed, fac_ns ), win );
1944 275013767 : move32();
1945 275013767 : IF( Q[i] )
1946 : {
1947 274984908 : nrm = norm_l( Q[i] );
1948 : }
1949 275013767 : Q[i] = L_shl( Q[i], nrm ); /*Q31 - Q_e*/
1950 275013767 : move32();
1951 275013767 : new_Q_e[i] = sub( 31, nrm );
1952 :
1953 275013767 : tmp1 = shr( seed, 4 );
1954 275013767 : nrg = L_mac0( nrg, tmp1, tmp1 ); /* sum up energy of current noise segment Q-8*/
1955 :
1956 275013767 : IF( infoTCXNoise ) /* set noiseflags for IGF */
1957 : {
1958 159418629 : infoTCXNoise[i] = 1;
1959 159418629 : move16();
1960 : }
1961 : }
1962 : }
1963 :
1964 808896 : IF( win > 0 )
1965 : {
1966 : /* RMS-normalize uppermost noise-filled segment */
1967 751613 : tmp1 = BASOP_Util_Divide3216_Scale( nrg, sub( lowpassLine, segmentOffset ), &s ); /* mean */
1968 : // Q-factor of nrg is -8. exp = 31-(-8) = 39
1969 751613 : s = add( s, 39 - 15 ); /* compensate energy scaling */
1970 751613 : tmp1 = ISqrt16( tmp1, &s ); /* 1/RMS Q15 - s*/
1971 751613 : tmp1 = mult_r( tmp1, inv_int[nTransWidth] ); /* compensate win Q15 - s*/
1972 :
1973 95621692 : FOR( m = segmentOffset; m < lowpassLine; m++ )
1974 : {
1975 94870079 : Word16 nrm = 31;
1976 94870079 : move16();
1977 : /*
1978 : at this point:
1979 : - flt Q[m] = (Q[m] * 2^(new_Q_e[m] - 31)) / (nTransWidth*nTransWidth)
1980 : - flt tmp1 = (tmp1 * 2^(s - 15)) * (nTransWidth*nTransWidth)
1981 : */
1982 94870079 : Q[m] = Mpy_32_16_1( Q[m], tmp1 ); /*Q15 - Q_e - s*/
1983 94870079 : move32();
1984 94870079 : IF( Q[m] )
1985 : {
1986 94857627 : nrm = norm_l( Q[m] );
1987 : }
1988 94870079 : Q[m] = L_shl( Q[m], nrm ); /*Q15 - Q_e - s + nrm*/
1989 94870079 : move32();
1990 94870079 : new_Q_e[m] = add( new_Q_e[m], s - nrm );
1991 94870079 : move32();
1992 : }
1993 : }
1994 :
1995 808896 : Word16 max_e = 0;
1996 808896 : move16();
1997 430138364 : FOR( i = 0; i < lowpassLine; i++ )
1998 : {
1999 429329468 : max_e = s_max( max_e, new_Q_e[i] );
2000 : }
2001 :
2002 430138364 : FOR( i = 0; i < lowpassLine; i++ )
2003 : {
2004 429329468 : Q[i] = L_shr( Q[i], sub( max_e, new_Q_e[i] ) ); /*Q31 - Q_e*/
2005 429329468 : move32();
2006 : }
2007 :
2008 808896 : *Q_e = max_e;
2009 808896 : move16();
2010 808896 : }
2011 :
2012 :
2013 : /*---------------------------------------------------------------
2014 : * InitTnsConfigs()
2015 : *--------------------------------------------------------------*/
2016 :
2017 :
2018 18151 : void InitTnsConfigs(
2019 : const Word16 bwidth, /*Q0*/
2020 : const Word16 L_frame, /*Q0*/
2021 : STnsConfig tnsConfig[2][2],
2022 : const Word16 igfStopFreq, /*Q0*/
2023 : const Word32 total_brate, /*Q0*/
2024 : const Word16 element_mode, /*Q0*/
2025 : const Word16 MCT_flag /*Q0*/ )
2026 : {
2027 18151 : IF( GT_32( total_brate, ACELP_32k ) )
2028 : {
2029 14766 : InitTnsConfiguration( bwidth, shr( L_frame, 1 ), &tnsConfig[0][0], igfStopFreq, total_brate, element_mode, MCT_flag );
2030 : }
2031 18151 : InitTnsConfiguration( bwidth, L_frame, &tnsConfig[1][0], igfStopFreq, total_brate, element_mode, MCT_flag );
2032 18151 : InitTnsConfiguration( bwidth, add( L_frame, shr( L_frame, 2 ) ), &tnsConfig[1][1], igfStopFreq, total_brate, element_mode, MCT_flag );
2033 18151 : }
2034 :
2035 32618 : void InitTnsConfigs_ivas_fx(
2036 : const Word16 bwidth, /*Q0*/
2037 : const Word16 L_frame, /*Q0*/
2038 : STnsConfig tnsConfig[2][2],
2039 : const Word16 igfStopFreq, /*Q0*/
2040 : const Word32 total_brate, /*Q0*/
2041 : const Word16 element_mode, /*Q0*/
2042 : const Word16 MCT_flag /*Q0*/ )
2043 : {
2044 32618 : IF( GT_32( total_brate, ACELP_32k ) )
2045 : {
2046 22649 : InitTnsConfiguration_ivas_fx( bwidth, shr( L_frame, 1 ), &tnsConfig[0][0], igfStopFreq, total_brate, element_mode, MCT_flag );
2047 : }
2048 32618 : InitTnsConfiguration_ivas_fx( bwidth, L_frame, &tnsConfig[1][0], igfStopFreq, total_brate, element_mode, MCT_flag );
2049 32618 : InitTnsConfiguration_ivas_fx( bwidth, add( L_frame, shr( L_frame, 2 ) ), &tnsConfig[1][1], igfStopFreq, total_brate, element_mode, MCT_flag );
2050 32618 : }
2051 :
2052 :
2053 1850408 : void SetTnsConfig(
2054 : TCX_CONFIG_HANDLE hTcxCfg, /* i : configuration of TCX */
2055 : const Word16 isTCX20, /*Q0*/
2056 : const Word16 isAfterACELP /*Q0*/ )
2057 : {
2058 1850408 : move16();
2059 1850408 : hTcxCfg->pCurrentTnsConfig = &hTcxCfg->tnsConfig[isTCX20][isAfterACELP];
2060 1850408 : assert( hTcxCfg->pCurrentTnsConfig != NULL );
2061 1850408 : }
2062 : #define IVAS_CODE_TCX_UTIL
2063 : #ifdef IVAS_CODE_TCX_UTIL
2064 : /*-------------------------------------------------------------------*
2065 : * SetAllowTnsOnWhite
2066 : *
2067 : * set TNS config flag for possible application of TNS in the whitened domain
2068 : *-------------------------------------------------------------------*/
2069 :
2070 50690 : void SetAllowTnsOnWhite(
2071 : STnsConfig tnsConfig[2][2], /* o : updated TNS configurations */
2072 : const Word8 allowTnsOnWhite /* i : flag for TNS in whiteded domain mode Q0*/
2073 : )
2074 : {
2075 50690 : tnsConfig[0][0].allowTnsOnWhite = allowTnsOnWhite; /*Q0*/
2076 50690 : move16();
2077 50690 : tnsConfig[0][1].allowTnsOnWhite = allowTnsOnWhite;
2078 50690 : move16();
2079 50690 : tnsConfig[1][0].allowTnsOnWhite = allowTnsOnWhite;
2080 50690 : move16();
2081 50690 : tnsConfig[1][1].allowTnsOnWhite = allowTnsOnWhite;
2082 50690 : move16();
2083 50690 : return;
2084 : }
2085 : #endif
2086 : #undef IVAS_CODE_TCX_UTIL
2087 :
2088 897934 : void tcx_get_gain(
2089 : Word32 *x, /* i: spectrum 1 Q31 - x_e*/
2090 : Word16 x_e, /* i: spectrum 1 exponent */
2091 : Word32 *y, /* i: spectrum 2 Q31 - y_e*/
2092 : Word16 y_e, /* i: spectrum 2 exponent */
2093 : Word16 n, /* i: length Q0*/
2094 : Word16 *gain, /* o: gain Q15 - gain_e*/
2095 : Word16 *gain_e, /* o: gain exponent */
2096 : Word32 *en_y, /* o: energy of y (optional) Q31 - en_y_e*/
2097 : Word16 *en_y_e /* o: energy of y exponent (optional) */
2098 : )
2099 : {
2100 : Word32 maxX, minX, maxY, minY;
2101 : Word32 corr, ener;
2102 : Word16 sx, sy, corr_e, ener_e;
2103 : Word16 i, tmp;
2104 : #ifndef ISSUE_1836_replace_overflow_libcom
2105 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
2106 : Flag Overflow = 0;
2107 : #endif
2108 : #endif
2109 :
2110 897934 : maxX = L_deposit_l( 1 );
2111 897934 : maxY = L_deposit_l( 1 );
2112 897934 : minX = L_deposit_l( -1 );
2113 897934 : minY = L_deposit_l( -1 );
2114 725579534 : FOR( i = 0; i < n; i++ )
2115 : {
2116 724681600 : if ( x[i] > 0 )
2117 236975260 : maxX = L_max( maxX, x[i] ); /*Q31 - x_e*/
2118 724681600 : if ( x[i] < 0 )
2119 237017887 : minX = L_min( minX, x[i] ); /*Q31 - x_e*/
2120 :
2121 724681600 : if ( y[i] > 0 )
2122 74366108 : maxY = L_max( maxY, y[i] ); /*Q31 - y_e*/
2123 724681600 : if ( y[i] < 0 )
2124 74527847 : minY = L_min( minY, y[i] ); /*Q31 - y_e*/
2125 : }
2126 897934 : sx = s_min( norm_l( maxX ), norm_l( minX ) );
2127 897934 : sy = s_min( norm_l( maxY ), norm_l( minY ) );
2128 897934 : sx = sub( sx, 4 );
2129 897934 : sy = sub( sy, 4 );
2130 :
2131 897934 : ener = L_deposit_l( 0 );
2132 897934 : corr = L_deposit_l( 0 );
2133 725579534 : FOR( i = 0; i < n; i++ )
2134 : {
2135 724681600 : tmp = round_fx( L_shl( y[i], sy ) ); /*Q15 - y_e + sy*/
2136 724681600 : ener = L_mac0( ener, tmp, tmp ); /*Q30 - 2*(y_e - sy)*/
2137 724681600 : corr = L_mac0( corr, tmp, round_fx( L_shl( x[i], sx ) ) ); /*Q30 - 2*(x_e - sx + y_e - sy)*/
2138 : }
2139 :
2140 897934 : if ( ener == 0 )
2141 2383 : ener = L_deposit_l( 1 );
2142 :
2143 897934 : ener_e = add( shl( sub( y_e, sy ), 1 ), 1 );
2144 897934 : corr_e = add( sub( add( x_e, y_e ), add( sx, sy ) ), 1 );
2145 :
2146 897934 : tmp = sub( norm_l( corr ), 1 );
2147 897934 : corr = L_shl( corr, tmp ); /*Q31 - corr_e + tmp*/
2148 897934 : corr_e = sub( corr_e, tmp );
2149 :
2150 897934 : tmp = norm_l( ener );
2151 897934 : ener = L_shl( ener, tmp ); /*Q31 - ener_e + tmp*/
2152 897934 : ener_e = sub( ener_e, tmp );
2153 :
2154 : #ifdef ISSUE_1836_replace_overflow_libcom
2155 897934 : tmp = div_s( abs_s( round_fx_sat( corr ) ), round_fx_sat( ener ) ); /*Q15 - (corr_e - ener_e)*/
2156 : #else
2157 : tmp = div_s( abs_s( round_fx_o( corr, &Overflow ) ), round_fx_o( ener, &Overflow ) ); /*Q15 - (corr_e - ener_e)*/
2158 : #endif
2159 897934 : if ( corr < 0 )
2160 0 : tmp = negate( tmp );
2161 :
2162 897934 : *gain = tmp;
2163 897934 : move16();
2164 897934 : *gain_e = sub( corr_e, ener_e );
2165 897934 : move16();
2166 :
2167 897934 : if ( en_y != NULL )
2168 : {
2169 897934 : *en_y = ener; /*Q31 - ener_e*/
2170 897934 : move32();
2171 : }
2172 897934 : if ( en_y_e != NULL )
2173 : {
2174 897934 : *en_y_e = ener_e;
2175 897934 : move16();
2176 : }
2177 897934 : }
2178 129 : void init_TCX_config(
2179 : TCX_CONFIG_HANDLE hTcxCfg,
2180 : Word16 L_frame, /*Q0*/
2181 : Word16 fscale, /*Q0*/
2182 : Word16 L_frameTCX, /*Q0*/
2183 : Word16 fscaleFB /*Q0*/ )
2184 : {
2185 : /* Initialize the TCX MDCT windows */
2186 129 : hTcxCfg->tcx_mdct_window_length = extract_l( L_shr( L_mult0( L_LOOK_12k8, fscale ), LD_FSCALE_DENOM ) ); /*Q0*/
2187 129 : move16();
2188 129 : hTcxCfg->tcx_mdct_window_delay = hTcxCfg->tcx_mdct_window_length; /*Q0*/
2189 129 : move16();
2190 :
2191 129 : hTcxCfg->tcx_mdct_window_half_length = extract_l( L_shr( L_mult0( L_LOOK_12k8 - NS2SA( 12800, 5000000L ), fscale ), LD_FSCALE_DENOM ) );
2192 129 : move16();
2193 129 : hTcxCfg->tcx_mdct_window_min_length = shr( L_frame, 4 ); /* 1.25ms Q0*/
2194 129 : move16();
2195 129 : hTcxCfg->tcx_mdct_window_trans_length = shr( L_frame, 4 ); /* 1.25ms Q0*/
2196 129 : move16();
2197 129 : hTcxCfg->tcx5Size = shr( L_frame, 2 ); /* 5ms Q0*/
2198 129 : move16();
2199 129 : hTcxCfg->tcx_mdct_window_lengthFB = extract_l( L_shr( L_mult0( L_LOOK_12k8, fscaleFB ), LD_FSCALE_DENOM ) ); /*Q0*/
2200 129 : move16();
2201 129 : hTcxCfg->tcx_mdct_window_delayFB = hTcxCfg->tcx_mdct_window_lengthFB; /*Q0*/
2202 129 : move16();
2203 :
2204 129 : hTcxCfg->tcx_mdct_window_half_lengthFB = extract_l( L_shr( L_mult0( L_LOOK_12k8 - NS2SA( 12800, 5000000L ), fscaleFB ), LD_FSCALE_DENOM ) ); /*Q0*/
2205 129 : move16();
2206 129 : hTcxCfg->tcx_mdct_window_min_lengthFB = shr( L_frameTCX, 4 ); /* 1.25ms Q0*/
2207 129 : move16();
2208 129 : hTcxCfg->tcx_mdct_window_trans_lengthFB = shr( L_frameTCX, 4 ); /* 1.25ms Q0*/
2209 129 : move16();
2210 129 : hTcxCfg->tcx5SizeFB = shr( L_frameTCX, 2 ); /* 5ms Q0*/
2211 129 : move16();
2212 129 : mdct_window_sine( hTcxCfg->tcx_mdct_window, hTcxCfg->tcx_mdct_window_length );
2213 129 : mdct_window_sine( hTcxCfg->tcx_mdct_window_half, hTcxCfg->tcx_mdct_window_half_length );
2214 129 : mdct_window_sine( hTcxCfg->tcx_mdct_window_minimum, hTcxCfg->tcx_mdct_window_min_length );
2215 129 : mdct_window_sine( hTcxCfg->tcx_mdct_window_trans, hTcxCfg->tcx_mdct_window_trans_length );
2216 :
2217 129 : mdct_window_sine( hTcxCfg->tcx_mdct_windowFB, hTcxCfg->tcx_mdct_window_lengthFB );
2218 129 : mdct_window_sine( hTcxCfg->tcx_mdct_window_halfFB, hTcxCfg->tcx_mdct_window_half_lengthFB );
2219 129 : mdct_window_sine( hTcxCfg->tcx_mdct_window_minimumFB, hTcxCfg->tcx_mdct_window_min_lengthFB );
2220 129 : mdct_window_sine( hTcxCfg->tcx_mdct_window_transFB, hTcxCfg->tcx_mdct_window_trans_lengthFB );
2221 :
2222 : /*ALDO windows for MODE2*/
2223 129 : mdct_window_aldo( hTcxCfg->tcx_aldo_window_1, hTcxCfg->tcx_aldo_window_1_trunc, hTcxCfg->tcx_aldo_window_2, L_frame );
2224 129 : mdct_window_aldo( hTcxCfg->tcx_aldo_window_1_FB, hTcxCfg->tcx_aldo_window_1_FB_trunc, hTcxCfg->tcx_aldo_window_2_FB, L_frameTCX );
2225 129 : }
|