Line data Source code
1 : /*====================================================================================
2 : EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0
3 : ====================================================================================*/
4 :
5 : #include <stdlib.h>
6 : #include <assert.h>
7 : #include "options.h" /* Compilation switches */
8 : #include "cnst.h" /* Common constants */
9 : #include "rom_com.h" /* Static table prototypes */
10 : #include "prot_fx.h" /* Function prototypes */
11 : #include "stl.h"
12 :
13 :
14 : #include "math_32.h"
15 :
16 1562 : static Word16 get_edxt_factor( Word16 length ) /* Returns value of sqrtf(2.f/length) in Q15 */
17 : {
18 : Word16 factor; /*Q15*/
19 1562 : factor = 0;
20 1562 : move16();
21 1562 : IF( EQ_16( length, 512 ) )
22 : {
23 262 : factor = 2048; /*0.0625 in Q15*/
24 262 : move16();
25 : }
26 1300 : ELSE IF( EQ_16( length, 256 ) )
27 : {
28 5 : factor = 2896; /*0.0883 in Q15*/
29 5 : move16();
30 : }
31 1295 : ELSE IF( EQ_16( length, 128 ) )
32 : {
33 7 : factor = 4096; /*0.125 in Q15*/
34 7 : move16();
35 : }
36 1288 : ELSE IF( EQ_16( length, 640 ) )
37 : {
38 361 : factor = 1832; /*0.0559 in Q15*/
39 361 : move16();
40 : }
41 927 : ELSE IF( EQ_16( length, 320 ) )
42 : {
43 634 : factor = 2590; /*0.079 in Q15*/
44 634 : move16();
45 : }
46 293 : ELSE IF( EQ_16( length, 160 ) )
47 : {
48 37 : factor = 3663; /*0.1117 in Q15*/
49 37 : move16();
50 : }
51 256 : ELSE IF( EQ_16( length, 80 ) )
52 : {
53 32 : factor = 5181; /*0.1581 in Q15*/
54 32 : move16();
55 : }
56 224 : ELSE IF( EQ_16( length, 40 ) )
57 : {
58 0 : factor = 7327; /*0.223 in Q15*/
59 0 : move16();
60 : }
61 224 : ELSE IF( EQ_16( length, 960 ) )
62 : {
63 224 : factor = 1496; /*0.0456 in Q15*/
64 224 : move16();
65 : }
66 0 : ELSE IF( EQ_16( length, 480 ) )
67 : {
68 0 : factor = 2115; /*0.0645 in Q15*/
69 0 : move16();
70 : }
71 0 : ELSE IF( EQ_16( length, 240 ) )
72 : {
73 0 : factor = 2991; /*0.0912 in Q15*/
74 0 : move16();
75 : }
76 0 : ELSE IF( EQ_16( length, 120 ) )
77 : {
78 0 : factor = 4230; /*0.1290 in Q15*/
79 0 : move16();
80 : }
81 0 : ELSE IF( EQ_16( length, 1200 ) )
82 : {
83 0 : factor = 1338; /*0.040 in Q15*/
84 0 : move16();
85 : }
86 0 : ELSE IF( EQ_16( length, 800 ) )
87 : {
88 0 : factor = 1638; /*0.05 in Q15*/
89 0 : move16();
90 : }
91 0 : ELSE IF( EQ_16( length, 400 ) )
92 : {
93 0 : factor = 2317; /*0.070 in Q15*/
94 0 : move16();
95 : }
96 0 : ELSE IF( EQ_16( length, 200 ) )
97 : {
98 0 : factor = 3277; /*0.1 in Q15*/
99 0 : move16();
100 : }
101 1562 : return factor; /*Q15*/
102 : }
103 :
104 4296144 : static Word16 const *get_edct_table( Word16 length /*Q0*/, Word16 *q )
105 : {
106 : Word16 const *edct_table;
107 4296144 : edct_table = NULL;
108 4296144 : SWITCH( length )
109 : {
110 21448 : case 1200:
111 21448 : edct_table = edct_table_600_fx; /*Q17*/
112 21448 : *q = add( *q, 2 );
113 21448 : move16();
114 21448 : BREAK;
115 1906960 : case 960:
116 1906960 : edct_table = edct_table_480_fx; /*Q16*/
117 1906960 : BREAK;
118 1035849 : case 640:
119 1035849 : edct_table = edct_table_320_fx; /*Q16*/
120 1035849 : BREAK;
121 514279 : case 320:
122 514279 : edct_table = edct_table_160_fx; /*Q16*/
123 514279 : BREAK;
124 316470 : case 256:
125 316470 : edct_table = edct_table_128_fx; /*Q16*/
126 316470 : BREAK;
127 72126 : case 240:
128 72126 : edct_table = edct_table_120_fx; /*Q16*/
129 72126 : BREAK;
130 0 : case 200:
131 0 : edct_table = edct_table_100_fx; /*Q16*/
132 0 : BREAK;
133 83752 : case 160:
134 83752 : edct_table = edct_table_80_fx; /*Q16*/
135 83752 : BREAK;
136 0 : case 40:
137 0 : edct_table = edct_table_20_fx; /*Q16*/
138 0 : BREAK;
139 5552 : case 800:
140 5552 : edct_table = edct_table_400_fx; /*Q17*/
141 5552 : *q = add( *q, 2 );
142 5552 : move16();
143 5552 : BREAK;
144 255758 : case 512:
145 255758 : edct_table = edct_table_256_fx; /*Q16*/
146 255758 : BREAK;
147 31719 : case 480:
148 31719 : edct_table = edct_table_240_fx; /*Q16*/
149 31719 : BREAK;
150 24590 : case 400:
151 24590 : edct_table = edct_table_200_fx; /*Q16*/
152 24590 : BREAK;
153 14511 : case 128:
154 14511 : edct_table = edct_table_64_fx; /*Q16*/
155 14511 : BREAK;
156 13130 : case 80:
157 13130 : edct_table = edct_table_40_fx; /*Q16*/
158 13130 : BREAK;
159 0 : default:
160 0 : BREAK;
161 : }
162 4296144 : return edct_table;
163 : }
164 :
165 : /*-------------------------------------------------------------------------*
166 : * FUNCTION : edct_fx()
167 : *
168 : * PURPOSE : DCT transform
169 : *
170 : * INPUT ARGUMENTS :
171 : * _ (Word16) length : length
172 : * _ (Word16*) x : input signal Qx
173 : * _ (Word16*) edct_table_128_fx : edct table Q16
174 : *
175 : * OUTPUT ARGUMENTS :
176 : * _ (Word16[]) y : output transform Qx
177 : *-------------------------------------------------------------------------*/
178 666427 : void edct_fx(
179 : const Word32 *x, /* i : input signal Qq */
180 : Word32 *y, /* o : output transform Qq */
181 : Word16 length, /* i : length Q0*/
182 : Word16 *q /* i : Q value of input signal */
183 : )
184 : {
185 : Word16 i;
186 : Word32 re;
187 : Word32 im;
188 : const Word16 *edct_table; /*Q16 */
189 : Word32 complex_buf[2 * ( L_FRAME48k / 2 + 240 )];
190 : Word32 L_tmp;
191 : Word16 tmp;
192 : Word16 len1;
193 :
194 666427 : edct_table = get_edct_table( length, q ); /*q*/
195 666427 : len1 = shr( length, 1 ); /*Q0*/
196 : /* Twiddling and Pre-rotate */
197 119321675 : FOR( i = 0; i < len1; i++ )
198 : {
199 118655248 : L_tmp = Mult_32_16( x[2 * i], edct_table[i] ); /*Q(q+1) */
200 118655248 : complex_buf[2 * i] = Madd_32_16( L_tmp, x[( length - ( 1 + ( i * 2 ) ) )], edct_table[( len1 - ( 1 + i ) )] ); /*Q(q+1) */
201 118655248 : move32();
202 :
203 118655248 : L_tmp = Mult_32_16( x[( length - ( 1 + ( i * 2 ) ) )], edct_table[i] ); /*Q(q+1) */
204 :
205 118655248 : complex_buf[( ( i * 2 ) + 1 )] = Msub_32_16( L_tmp, x[( i * 2 )], edct_table[( len1 - ( 1 + i ) )] ); /*Q(q+1) */
206 118655248 : move32();
207 : }
208 :
209 666427 : *q = sub( 15, *q );
210 666427 : move16();
211 666427 : BASOP_cfft( (cmplx *) complex_buf, len1, q, y );
212 :
213 666427 : tmp = div_s( 1, length ); /*Q15 */
214 666427 : tmp = round_fx( L_shl( L_mult( tmp, 19302 /*0.75f * EVS_PI in Q13*/ ), 2 ) ); /*Q15 */
215 119321675 : FOR( i = 0; i < len1; i++ )
216 : {
217 118655248 : re = Msub_32_16( complex_buf[2 * i], complex_buf[( ( i * 2 ) + 1 )], tmp ); /*Q(q+1) */
218 118655248 : im = Madd_32_16( complex_buf[( ( i * 2 ) + 1 )], complex_buf[2 * i], tmp ); /*Q(q+1) */
219 118655248 : y[2 * i] = L_add( Mult_32_16( re, edct_table[i] ), Mult_32_16( im, edct_table[( len1 - ( 1 + i ) )] ) ); /*Q(q+2)*/
220 118655248 : move32();
221 118655248 : y[( length - ( 1 + ( i * 2 ) ) )] = L_sub( Mult_32_16( re, edct_table[( len1 - ( 1 + i ) )] ), Mult_32_16( im, edct_table[i] ) ); /*Q(q+2)*/
222 118655248 : move32();
223 : } /*Q(q-2) */
224 :
225 666427 : *q = sub( 15 + 2, *q );
226 666427 : move16();
227 666427 : return;
228 : }
229 :
230 2711142 : void edct_ivas_fx(
231 : const Word32 *x, /* i : input signal Qq */
232 : Word32 *y, /* o : output transform Qq */
233 : Word16 length, /* i : length Q0*/
234 : Word16 *q /* i : Q value of input signal */
235 : )
236 : {
237 : Word16 i;
238 : const Word16 *edct_table; /*Q16 */
239 : Word32 re[L_FRAME_PLUS / 2];
240 : Word32 im[L_FRAME_PLUS / 2];
241 : Word32 L_tmp;
242 : Word16 tmp;
243 : Word16 len1;
244 :
245 2711142 : edct_table = get_edct_table( length, q ); /*q*/
246 2711142 : len1 = shr( length, 1 ); /*Q0*/
247 : /* Twiddling and Pre-rotate */
248 980086630 : FOR( i = 0; i < len1; i++ )
249 : {
250 977375488 : L_tmp = Mult_32_16( x[2 * i], edct_table[i] ); /*Q(q+1) */
251 977375488 : re[i] = Madd_32_16( L_tmp, x[( length - ( 1 + ( i * 2 ) ) )], edct_table[( len1 - ( 1 + i ) )] ); /*Q(q+1) */
252 977375488 : move32();
253 :
254 977375488 : L_tmp = Mult_32_16( x[( length - ( 1 + ( i * 2 ) ) )], edct_table[i] ); /*Q(q+1) */
255 977375488 : im[i] = Msub_32_16( L_tmp, x[( i * 2 )], edct_table[( len1 - ( 1 + i ) )] ); /*Q(q+1) */
256 977375488 : move32();
257 : }
258 :
259 2711142 : *q = sub( 31, *q );
260 2711142 : move16();
261 2711142 : tmp = sub( s_min( getScaleFactor32( re, len1 ), getScaleFactor32( im, len1 ) ), find_guarded_bits_fx( len1 ) );
262 2711142 : scale_sig32( re, len1, tmp );
263 2711142 : scale_sig32( im, len1, tmp );
264 :
265 2711142 : fft_fx( re, im, len1, 1 );
266 2711142 : *q = sub( *q, tmp );
267 2711142 : move16();
268 :
269 2711142 : tmp = div_s( 4, length ); /*Q17 */
270 2711142 : tmp = round_fx( L_mult( tmp, 19302 /*0.75f * EVS_PI in Q13*/ ) ); /*Q15 */
271 980086630 : FOR( i = 0; i < len1; i++ )
272 : {
273 977375488 : L_tmp = Msub_32_16( re[i], im[i], tmp );
274 977375488 : im[i] = Madd_32_16( im[i], re[i], tmp ); /*Q(q+1) */
275 977375488 : re[i] = L_tmp; /*Q(q+1) */
276 977375488 : move32();
277 977375488 : move32();
278 : }
279 980086630 : FOR( i = 0; i < len1; i++ )
280 : {
281 977375488 : y[2 * i] = L_add( Mult_32_16( re[i], edct_table[i] ), Mult_32_16( im[i], edct_table[( len1 - ( 1 + i ) )] ) ); /*Q(q+2)*/
282 977375488 : move32();
283 977375488 : y[( length - ( 1 + ( i * 2 ) ) )] = L_sub( Mult_32_16( re[i], edct_table[( len1 - ( 1 + i ) )] ), Mult_32_16( im[i], edct_table[i] ) ); /*Q(q+2)*/
284 977375488 : move32();
285 : } /*Q(q-2) */
286 :
287 2711142 : *q = sub( 31 + 2, *q );
288 2711142 : move16();
289 2711142 : return;
290 : }
291 : /*-------------------------------------------------------------------------*
292 : * FUNCTION : edst_fx()
293 : *
294 : * PURPOSE : DST_IV transform
295 : *
296 : * INPUT ARGUMENTS :
297 : * _ (Word16) length : length
298 : * _ (Word16*) x : input signal Qx
299 : * _ (Word16*) edct_table_128_fx : edct table Q16
300 : *
301 : * OUTPUT ARGUMENTS :
302 : * _ (Word16[]) y : output transform Qx
303 : *-------------------------------------------------------------------------*/
304 918575 : void edst_fx(
305 : const Word32 *x, /* i : input signal Qq */
306 : Word32 *y, /* o : output transform Qq */
307 : Word16 length, /* i : length */
308 : Word16 *q /* i : Q value of input signal */
309 : )
310 : {
311 : Word16 i;
312 : Word32 re;
313 : Word32 im;
314 : const Word16 *edct_table; /*Q16 */
315 : Word32 complex_buf[2 * ( L_FRAME48k / 2 + 240 )];
316 : Word32 L_tmp;
317 : Word16 tmp;
318 : Word16 len1;
319 :
320 918575 : edct_table = get_edct_table( length, q ); /*q*/
321 918575 : len1 = shr( length, 1 ); /*Q0*/
322 : /* Twiddling and Pre-rotate */
323 384396511 : FOR( i = 0; i < len1; i++ )
324 : {
325 383477936 : L_tmp = Mult_32_16( x[( length - ( 1 + ( i * 2 ) ) )], edct_table[i] ); /*Qq+1*/
326 383477936 : complex_buf[2 * i] = Madd_32_16( L_tmp, x[2 * i], edct_table[( len1 - ( 1 + i ) )] ); /*Qq+1*/
327 383477936 : move32();
328 :
329 383477936 : L_tmp = Mult_32_16( x[2 * i], edct_table[i] ); /*Qq+1*/
330 383477936 : complex_buf[( ( i * 2 ) + 1 )] = Msub_32_16( L_tmp, x[( length - ( 1 + ( i * 2 ) ) )], edct_table[( len1 - ( 1 + i ) )] ); /*Qq+1*/
331 383477936 : move32();
332 : }
333 :
334 918575 : *q = sub( 15, *q );
335 918575 : move16();
336 918575 : BASOP_cfft( (cmplx *) complex_buf, len1, q, y );
337 :
338 918575 : tmp = div_s( 1, length ); /*Q15 */
339 918575 : tmp = round_fx( L_shl( L_mult( tmp, 19302 /*0.75f * EVS_PI in Q13*/ ), 2 ) ); /*Q15 */
340 384396511 : FOR( i = 0; i < len1; i++ )
341 : {
342 383477936 : re = Msub_32_16( complex_buf[2 * i], complex_buf[( ( i * 2 ) + 1 )], tmp ); /*Qq+1*/
343 383477936 : im = Madd_32_16( complex_buf[( ( i * 2 ) + 1 )], complex_buf[2 * i], tmp ); /*Qq+1*/
344 383477936 : y[2 * i] = L_add( Mult_32_16( re, edct_table[i] ), Mult_32_16( im, edct_table[( len1 - ( 1 + i ) )] ) ); /*Qq+2*/
345 383477936 : move32();
346 383477936 : y[( length - ( 1 + ( i * 2 ) ) )] = L_sub( Mult_32_16( im, edct_table[i] ), Mult_32_16( re, edct_table[( len1 - ( 1 + i ) )] ) ); /*Qq+2*/
347 383477936 : move32();
348 : } /*Q(q) */
349 :
350 918575 : *q = sub( 15 + 2, *q );
351 918575 : move16();
352 :
353 918575 : return;
354 : }
355 : /*========================================================================*/
356 : /* FUNCTION : edct_fx() */
357 : /*------------------------------------------------------------------------*/
358 : /* PURPOSE : DCT transform */
359 : /*------------------------------------------------------------------------*/
360 : /* INPUT ARGUMENTS : */
361 : /* _ (Word16) length : length */
362 : /* _ (Word16*) x : input signal Qx */
363 : /* _ (Word16*) edct_table_128_fx : edct table Q15 */
364 : /*------------------------------------------------------------------------*/
365 : /* INPUT/OUTPUT ARGUMENTS : */
366 : /*------------------------------------------------------------------------*/
367 : /* OUTPUT ARGUMENTS : */
368 : /* _ (Word16[]) y : output transform Qx */
369 : /*------------------------------------------------------------------------*/
370 :
371 : /*------------------------------------------------------------------------*/
372 : /* RETURN ARGUMENTS : */
373 : /* _ None */
374 : /*========================================================================*/
375 299562 : void edct_16fx(
376 : const Word16 *x, /* i : input signal Qx */
377 : Word16 *y, /* o : output transform Qx */
378 : Word16 length, /* i : length */
379 : Word16 bh, /* bit-headroom */
380 : const Word16 element_mode
381 :
382 : )
383 : {
384 : Word16 i;
385 : Word16 re[L_FRAME48k / 2];
386 : Word16 im[L_FRAME48k / 2];
387 299562 : const Word16 *edct_table = NULL;
388 : Word16 re2[L_FRAME48k / 2];
389 : Word16 im2[L_FRAME48k / 2];
390 :
391 : Word32 L_tmp, Lacc, Lmax;
392 : Word16 tmp, fact;
393 : Word16 Q_edct;
394 : Word16 Len2, i2;
395 : const Word16 *px, *pt;
396 : Word16 *py;
397 : (void) element_mode;
398 : #ifndef ISSUE_1836_replace_overflow_libcom
399 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
400 : Flag Overflow;
401 : Overflow = 0;
402 : move32();
403 : #endif
404 : #endif
405 : /*COMPLETE: some eDCT sub function are missing */
406 :
407 299562 : IF( EQ_16( length, L_FRAME32k ) )
408 : {
409 18074 : edct_table = &edct_table_320_16fx[0]; /*Q15*/
410 : }
411 281488 : ELSE IF( EQ_16( length, L_FRAME ) )
412 : {
413 193308 : edct_table = &edct_table_128_16fx[0]; /*Q15*/
414 : }
415 88180 : ELSE IF( EQ_16( length, L_FRAME16k ) )
416 : {
417 88180 : edct_table = &edct_table_160_16fx[0]; /*Q15*/
418 : }
419 : ELSE
420 : {
421 : }
422 :
423 : /* Twiddling and Pre-rotate */
424 299562 : Lmax = L_deposit_l( 0 );
425 299562 : Len2 = shr( length, 1 );
426 299562 : px = x + sub( length, 1 ); /*Qx*/
427 299562 : pt = edct_table + sub( Len2, 1 ); /*Q16*/
428 44935466 : FOR( i = 0; i < Len2; i++ )
429 : {
430 44635904 : i2 = shl( i, 1 );
431 44635904 : L_tmp = L_mult( x[i2], edct_table[i] ); /*Q(Qx+16) */
432 :
433 44635904 : Lacc = L_mac( L_tmp, *px, *pt ); /*Q(Qx+16) */
434 :
435 44635904 : Lmax = L_max( Lmax, Lacc );
436 :
437 44635904 : L_tmp = L_mult( *px, edct_table[i] ); /*Q(Qx+16) */
438 44635904 : Lacc = L_msu( L_tmp, x[i2], *pt ); /*Q(Qx+16) */
439 44635904 : Lmax = L_max( Lmax, Lacc );
440 :
441 44635904 : px -= 2;
442 44635904 : pt--;
443 : }
444 :
445 299562 : tmp = 31;
446 299562 : move16();
447 299562 : if ( Lmax != 0 )
448 : {
449 283180 : tmp = norm_l( Lmax );
450 : }
451 299562 : Q_edct = sub( tmp, bh ); /*creating a bit-headroom */
452 :
453 299562 : px = x + sub( length, 1 ); /*Qx*/
454 299562 : pt = edct_table + sub( Len2, 1 ); /*Q15*/
455 44935466 : FOR( i = 0; i < Len2; i++ )
456 : {
457 44635904 : i2 = shl( i, 1 );
458 :
459 44635904 : L_tmp = L_mult( x[i2], edct_table[i] ); /*Q(Qx+16) */
460 : #ifdef ISSUE_1836_replace_overflow_libcom
461 44635904 : Lacc = L_mac_sat( L_tmp, *px, *pt ); /*Q(Qx+16) */
462 44635904 : re2[i] = round_fx_sat( L_shl_sat( Lacc, Q_edct ) ); /* Q(Qx+Q_edct) */
463 44635904 : move16();
464 44635904 : L_tmp = L_mult( *px, edct_table[i] ); /*Q(Qx+16) */
465 44635904 : Lacc = L_msu_sat( L_tmp, x[i2], *pt ); /*Q(Qx+16) */
466 44635904 : im2[i] = round_fx_sat( L_shl_sat( Lacc, Q_edct ) ); /* Q(Qx+Q_edct) */
467 : #else
468 : Lacc = L_mac_o( L_tmp, *px, *pt, &Overflow ); /*Q(Qx+16) */
469 : re2[i] = round_fx_o( L_shl_o( Lacc, Q_edct, &Overflow ), &Overflow ); /* Q(Qx+Q_edct) */
470 : move16();
471 : L_tmp = L_mult( *px, edct_table[i] ); /*Q(Qx+16) */
472 : Lacc = L_msu_o( L_tmp, x[i2], *pt, &Overflow ); /*Q(Qx+16) */
473 : im2[i] = round_fx_o( L_shl_o( Lacc, Q_edct, &Overflow ), &Overflow ); /* Q(Qx+Q_edct) */
474 : #endif
475 44635904 : move16();
476 44635904 : px -= 2;
477 44635904 : pt--;
478 : }
479 299562 : IF( EQ_16( length, L_FRAME32k ) )
480 : {
481 18074 : DoRTFT320_16fx( re2, im2 );
482 : }
483 281488 : ELSE IF( EQ_16( length, L_FRAME ) )
484 : {
485 193308 : DoRTFT128_16fx( re2, im2 );
486 : }
487 88180 : ELSE IF( EQ_16( length, L_FRAME16k ) )
488 : {
489 88180 : DoRTFT160_16fx( re2, im2 );
490 : }
491 : ELSE
492 : {
493 : }
494 299562 : tmp = div_s( 1, length ); /*Q15 */
495 299562 : L_tmp = L_mult( tmp, 19302 ); /*Q29, (3*PI/4) in Q13 */
496 299562 : fact = round_fx( L_shl( L_tmp, 2 ) ); /*Q15 */
497 44935466 : FOR( i = 0; i < shr( length, 1 ); i++ )
498 : {
499 44635904 : tmp = mult_r( im2[i], fact ); /*Q(Qx+Q_edct) */
500 : #ifdef ISSUE_1836_replace_overflow_libcom
501 44635904 : re[i] = sub_sat( re2[i], tmp ); /*Q(Qx+Q_edct) */
502 : #else
503 : re[i] = sub_o( re2[i], tmp, &Overflow ); /*Q(Qx+Q_edct) */
504 : #endif
505 44635904 : move16();
506 :
507 44635904 : tmp = mult_r( re2[i], fact ); /*Q(Qx+Q_edct) */
508 : #ifdef ISSUE_1836_replace_overflow_libcom
509 44635904 : im[i] = add_sat( im2[i], tmp ); /*Q(Qx+Q_edct) */
510 : #else
511 : im[i] = add_o( im2[i], tmp, &Overflow ); /*Q(Qx+Q_edct) */
512 : #endif
513 44635904 : move16();
514 : }
515 :
516 : /* Post-rotate and obtain the output data */
517 299562 : py = y + sub( length, 1 ); /*Qx*/
518 299562 : pt = edct_table + sub( Len2, 1 ); /*Q15*/
519 44935466 : FOR( i = 0; i < Len2; i++ )
520 : {
521 44635904 : i2 = shl( i, 1 );
522 :
523 44635904 : L_tmp = L_mult( re[i], edct_table[i] ); /*Q(Qx+Q_edct+16) */
524 : #ifdef ISSUE_1836_replace_overflow_libcom
525 44635904 : Lacc = L_mac_sat( L_tmp, im[i], *pt ); /*Q(Qx+Q_edct+16) */
526 44635904 : y[i2] = round_fx_sat( L_shr_sat( Lacc, Q_edct ) ); /* Q(Qx) */
527 44635904 : move16();
528 :
529 44635904 : L_tmp = L_mult( re[i], edct_table[sub( shr( length, 1 ), add( 1, i ) )] ); /*Q(Qx+Q_edct+16) */
530 44635904 : Lacc = L_msu( L_tmp, im[i], edct_table[i] ); /*Q(Qx+Q_edct+16) */
531 44635904 : *py = round_fx_sat( L_shr_sat( Lacc, Q_edct ) ); /* Q(Qx) */
532 : #else
533 : Lacc = L_mac_o( L_tmp, im[i], *pt, &Overflow ); /*Q(Qx+Q_edct+16) */
534 : y[i2] = round_fx_o( L_shr_o( Lacc, Q_edct, &Overflow ), &Overflow ); /* Q(Qx) */
535 : move16();
536 :
537 : L_tmp = L_mult( re[i], edct_table[sub( shr( length, 1 ), add( 1, i ) )] ); /*Q(Qx+Q_edct+16) */
538 : Lacc = L_msu( L_tmp, im[i], edct_table[i] ); /*Q(Qx+Q_edct+16) */
539 : *py = round_fx_o( L_shr_o( Lacc, Q_edct, &Overflow ), &Overflow ); /* Q(Qx) */
540 : #endif
541 44635904 : move16();
542 :
543 44635904 : py -= 2;
544 44635904 : pt--;
545 : }
546 299562 : return;
547 : }
548 :
549 :
550 : /*-----------------------------------------------------------------*
551 : * iedct_short_fx()
552 : *
553 : * Inverse EDCT for short frames
554 : *-----------------------------------------------------------------*/
555 :
556 5624 : void iedct_short_fx(
557 : const Word32 *in, /* i : input vector Q*/
558 : Word16 *Q, /* i/o: Q value of input */
559 : Word32 *out, /* o : output vector Q*/
560 : const Word16 segment_length /* i : length Q0*/
561 : )
562 : {
563 : Word32 alias[MAX_SEGMENT_LENGTH];
564 : Word16 seg_len_div2, seg_len_div4, seg_len_3mul_div4;
565 : Word16 i;
566 : Word16 qtmp, tmp;
567 :
568 5624 : qtmp = *Q;
569 5624 : move16();
570 5624 : tmp = 0;
571 5624 : move16();
572 5624 : seg_len_div2 = shr( segment_length, 1 ); /*Q0*/
573 5624 : seg_len_div4 = shr( segment_length, 2 ); /*Q0*/
574 5624 : seg_len_3mul_div4 = add( seg_len_div2, seg_len_div4 );
575 :
576 5624 : edct_fx( in, alias, seg_len_div2, Q );
577 8667 : FOR( i = 0; i < seg_len_div2; i++ )
578 : {
579 8629 : IF( alias[i] != 0 )
580 : {
581 5586 : tmp = 1;
582 5586 : move16();
583 5586 : BREAK;
584 : }
585 : }
586 5624 : if ( tmp == 0 )
587 : {
588 38 : *Q = qtmp;
589 38 : move16();
590 : }
591 380504 : FOR( i = 0; i < seg_len_div4; i++ )
592 : {
593 374880 : out[i] = alias[( seg_len_div4 + i )]; /*Q*/
594 374880 : move32();
595 374880 : out[( seg_len_div4 + i )] = L_negate( alias[( ( seg_len_div2 - 1 ) - i )] ); /*Q*/
596 374880 : move32();
597 374880 : out[( seg_len_div2 + i )] = L_negate( alias[( ( seg_len_div4 - 1 ) - i )] ); /*Q*/
598 374880 : move32();
599 374880 : out[( seg_len_3mul_div4 + i )] = L_negate( alias[i] ); /*Q*/
600 374880 : move32();
601 : }
602 :
603 5624 : return;
604 : }
605 :
606 : #define FAST_EDXT /* optimized FFT-based DCT/DST algorithm */
607 : /*-------------------------------------------------------------------------*
608 : * edxt_fx()
609 : *
610 : * DCT/DST-II or III transform (currently also calculates DCT-IV and DST-IV)
611 : *-------------------------------------------------------------------------*/
612 :
613 1562 : void edxt_fx(
614 : const Word32 *x, /* i : input signal Qx*/
615 : Word32 *y, /* o : output transform Qx*/
616 : const Word16 length, /* i : length Q0*/
617 : const UWord16 kernelType, /* i : kernel type (0 - 3) Q0*/
618 : const UWord16 synthesis /* i : nonzero for inverse Q0*/
619 : )
620 : {
621 1562 : Word16 k, m, fac, hdrm, tmp = 0;
622 : const Word16 *cosPtr, *sinPtr;
623 : Word16 n;
624 1562 : n = 0;
625 1562 : move16();
626 1562 : move16();
627 1562 : cosPtr = NULL;
628 1562 : sinPtr = NULL;
629 1562 : IF( EQ_16( length, 512 ) )
630 : {
631 262 : cosPtr = cos_scale_tbl_512; /*Q15*/
632 262 : sinPtr = sin_scale_tbl_512; /*Q15*/
633 262 : n = 1;
634 262 : move16();
635 : }
636 1300 : ELSE IF( EQ_16( length, 256 ) )
637 : {
638 5 : cosPtr = cos_scale_tbl_512; /*Q15*/
639 5 : sinPtr = sin_scale_tbl_512; /*Q15*/
640 5 : n = 2;
641 5 : move16();
642 : }
643 1295 : ELSE IF( EQ_16( length, 128 ) )
644 : {
645 7 : cosPtr = cos_scale_tbl_512; /*Q15*/
646 7 : sinPtr = sin_scale_tbl_512; /*Q15*/
647 7 : n = 4;
648 7 : move16();
649 : }
650 1288 : ELSE IF( EQ_16( length, 640 ) )
651 : {
652 361 : cosPtr = cos_scale_tbl_640; /*Q15*/
653 361 : sinPtr = sin_scale_tbl_640; /*Q15*/
654 361 : n = 1;
655 361 : move16();
656 : }
657 927 : ELSE IF( EQ_16( length, 320 ) )
658 : {
659 634 : cosPtr = cos_scale_tbl_640; /*Q15*/
660 634 : sinPtr = sin_scale_tbl_640; /*Q15*/
661 634 : n = 2;
662 634 : move16();
663 : }
664 293 : ELSE IF( EQ_16( length, 160 ) )
665 : {
666 37 : cosPtr = cos_scale_tbl_640; /*Q15*/
667 37 : sinPtr = sin_scale_tbl_640; /*Q15*/
668 37 : n = 4;
669 37 : move16();
670 : }
671 256 : ELSE IF( EQ_16( length, 80 ) )
672 : {
673 32 : cosPtr = cos_scale_tbl_640; /*Q15*/
674 32 : sinPtr = sin_scale_tbl_640; /*Q15*/
675 32 : n = 8;
676 32 : move16();
677 : }
678 224 : ELSE IF( EQ_16( length, 40 ) )
679 : {
680 0 : cosPtr = cos_scale_tbl_640; /*Q15*/
681 0 : sinPtr = sin_scale_tbl_640; /*Q15*/
682 0 : n = 16;
683 0 : move16();
684 : }
685 224 : ELSE IF( EQ_16( length, 960 ) )
686 : {
687 224 : cosPtr = cos_scale_tbl_960; /*Q15*/
688 224 : sinPtr = sin_scale_tbl_960; /*Q15*/
689 224 : n = 1;
690 224 : move16();
691 : }
692 0 : ELSE IF( EQ_16( length, 480 ) )
693 : {
694 0 : cosPtr = cos_scale_tbl_960; /*Q15*/
695 0 : sinPtr = sin_scale_tbl_960; /*Q15*/
696 0 : n = 2;
697 0 : move16();
698 : }
699 0 : ELSE IF( EQ_16( length, 240 ) )
700 : {
701 0 : cosPtr = cos_scale_tbl_960; /*Q15*/
702 0 : sinPtr = sin_scale_tbl_960; /*Q15*/
703 0 : n = 4;
704 0 : move16();
705 : }
706 0 : ELSE IF( EQ_16( length, 120 ) )
707 : {
708 0 : cosPtr = cos_scale_tbl_960; /*Q15*/
709 0 : sinPtr = sin_scale_tbl_960; /*Q15*/
710 0 : n = 8;
711 0 : move16();
712 : }
713 0 : ELSE IF( EQ_16( length, 1200 ) )
714 : {
715 0 : cosPtr = cos_scale_tbl_1200; /*Q15*/
716 0 : sinPtr = sin_scale_tbl_1200; /*Q15*/
717 0 : n = 1;
718 0 : move16();
719 : }
720 0 : ELSE IF( EQ_16( length, 800 ) )
721 : {
722 0 : cosPtr = cos_scale_tbl_800; /*Q15*/
723 0 : sinPtr = sin_scale_tbl_800; /*Q15*/
724 0 : n = 1;
725 0 : move16();
726 : }
727 0 : ELSE IF( EQ_16( length, 400 ) )
728 : {
729 0 : cosPtr = cos_scale_tbl_800; /*Q15*/
730 0 : sinPtr = sin_scale_tbl_800; /*Q15*/
731 0 : n = 2;
732 0 : move16();
733 : }
734 0 : ELSE IF( EQ_16( length, 200 ) )
735 : {
736 0 : cosPtr = cos_scale_tbl_800; /*Q15*/
737 0 : sinPtr = sin_scale_tbl_800; /*Q15*/
738 0 : n = 4;
739 0 : move16();
740 : }
741 :
742 : #ifdef FAST_EDXT
743 1562 : test();
744 1562 : IF( EQ_16( kernelType, MDST_II ) || EQ_16( kernelType, MDCT_II ) )
745 : {
746 1562 : const Word16 Nm1 = sub( length, 1 );
747 1562 : const Word16 xSign = sub( imult1616( 2, shr( kernelType, 1 ) ), 1 ); /*Q0*/
748 : Word32 re[L_FRAME_PLUS];
749 : Word32 im[L_FRAME_PLUS];
750 :
751 1562 : IF( !synthesis )
752 : {
753 147082 : FOR( k = ( Nm1 / 2 ); k >= 0; k-- ) /* pre-modulation of audio input */
754 : {
755 146560 : re[k] = x[2 * k]; /*Qx*/
756 146560 : re[( Nm1 - k )] = Mpy_32_16_1( x[( ( k * 2 ) + 1 )], shl_sat( xSign, 15 ) ); /*Qx*/
757 146560 : im[k] = im[( Nm1 - k )] = 0;
758 146560 : move32();
759 146560 : move32();
760 146560 : move32();
761 : }
762 :
763 522 : IF( EQ_16( length, 512 ) )
764 : {
765 : /* Scaling down re and im buffers to avoid overflow in DoRTFTn_fx if the minimum headroom is less than 4 bits */
766 0 : hdrm = s_min( L_norm_arr( re, 512 ), L_norm_arr( im, 512 ) );
767 0 : IF( LT_16( hdrm, 4 ) )
768 : {
769 0 : tmp = sub( hdrm, 4 );
770 0 : scale_sig32( re, 512, tmp );
771 0 : scale_sig32( im, 512, tmp );
772 : }
773 :
774 0 : DoRTFTn_fx( re, im, 512 );
775 :
776 0 : IF( LT_16( hdrm, 4 ) )
777 : {
778 0 : tmp = negate( tmp );
779 0 : scale_sig32( re, 512, tmp );
780 0 : scale_sig32( im, 512, tmp );
781 : }
782 : }
783 : ELSE /* fft() doesn't support 512 */
784 : {
785 522 : fft_fx( re, im, length, 1 );
786 : }
787 :
788 522 : IF( shr( kernelType, 1 ) )
789 : {
790 71760 : FOR( k = ( Nm1 / 2 ); k > 0; k-- )
791 : {
792 : // const float wRe = cosf( scale * k );
793 : // const float wIm = sinf( scale * k );
794 71500 : const Word16 wRe = cosPtr[( k * n )]; /*Q15*/
795 71500 : const Word16 wIm = sinPtr[( k * n )]; /*Q15*/
796 :
797 71500 : y[k] /*pt 1*/ = L_add( Mpy_32_16_1( re[k], wRe ), Mpy_32_16_1( im[k], wIm ) ); /*Qx*/
798 71500 : y[( length - k )] = L_sub( Mpy_32_16_1( re[k], wIm ), Mpy_32_16_1( im[k], wRe ) ); /*Qx*/
799 71500 : move32();
800 71500 : move32();
801 : }
802 260 : y[( length / 2 )] = Mpy_32_16_1( re[( length / 2 )], INV_SQRT_2_Q15 ); /*Qx*/
803 260 : move32();
804 : }
805 : ELSE /* forw. DST-II */
806 : {
807 74800 : FOR( k = ( Nm1 / 2 ); k > 0; k-- )
808 : {
809 : // const float wRe = cosf( scale * k );
810 : // const float wIm = sinf( scale * k );
811 74538 : const Word16 wRe = cosPtr[( k * n )]; /*Q15*/
812 74538 : const Word16 wIm = sinPtr[( k * n )]; /*Q15*/
813 :
814 74538 : y[( Nm1 - k )] = L_add( Mpy_32_16_1( re[k], wRe ), Mpy_32_16_1( im[k], wIm ) ); /*Qx*/
815 74538 : y[k - 1] = L_sub( Mpy_32_16_1( re[k], wIm ), Mpy_32_16_1( im[k], wRe ) ); /*Qx*/
816 74538 : move32();
817 74538 : move32();
818 : }
819 262 : y[( Nm1 / 2 )] = Mpy_32_16_1( re[( length / 2 )], INV_SQRT_2_Q15 ); /*Qx*/
820 262 : move32();
821 : }
822 :
823 522 : y[( Nm1 - ( Nm1 * ( kernelType / 2 ) ) )] = L_shr( re[0], 1 ); /*Qx*/
824 522 : move32();
825 : }
826 : ELSE /* inverse II = III */
827 : {
828 1040 : IF( shr( kernelType, 1 ) )
829 : {
830 121472 : FOR( k = ( Nm1 / 2 ); k > 0; k-- )
831 : {
832 : // const float wRe = cosf( scale * k ) * 0.5f;
833 : // const float wIm = sinf( scale * k ) * 0.5f;
834 120958 : const Word16 wRe = shr( cosPtr[imult1616( k, n )], 1 );
835 120958 : const Word16 wIm = shr( sinPtr[imult1616( k, n )], 1 );
836 :
837 120958 : re[k] = L_add( Mpy_32_16_1( x[k], wRe ), Mpy_32_16_1( x[( length - k )], wIm ) ); /*Qx*/
838 120958 : im[k] = L_sub( Mpy_32_16_1( x[( length - k )], wRe ), Mpy_32_16_1( x[k], wIm ) ); /*Qx*/
839 120958 : move32();
840 120958 : move32();
841 : }
842 514 : re[( length / 2 )] = Mpy_32_16_1( x[( length / 2 )], INV_SQRT_2_Q15 ); /*Qx*/
843 514 : move32();
844 : }
845 : ELSE /* DST type III */
846 : {
847 128848 : FOR( k = ( Nm1 / 2 ); k > 0; k-- )
848 : {
849 : // const float wRe = cosf( scale * k ) * 0.5f;
850 : // const float wIm = sinf( scale * k ) * 0.5f;
851 128322 : const Word16 wRe = shr( cosPtr[( k * n )], 1 ); /*Q15*/
852 128322 : const Word16 wIm = shr( sinPtr[( k * n )], 1 ); /*Q15*/
853 :
854 128322 : re[k] = L_add( Mpy_32_16_1( x[( Nm1 - k )], wRe ), Mpy_32_16_1( x[( k - 1 )], wIm ) ); /*Qx*/
855 128322 : im[k] = L_sub( Mpy_32_16_1( x[( k - 1 )], wRe ), Mpy_32_16_1( x[( Nm1 - k )], wIm ) ); /*Qx*/
856 128322 : move32();
857 128322 : move32();
858 : }
859 526 : re[( length / 2 )] = Mpy_32_16_1( x[( Nm1 / 2 )], INV_SQRT_2_Q15 ); /*Qx*/
860 526 : move32();
861 : }
862 :
863 1040 : re[0] = x[( Nm1 - ( Nm1 * ( kernelType / 2 ) ) )]; /*Qx*/
864 1040 : im[0] = im[( length / 2 )] = 0;
865 1040 : move32();
866 1040 : move32();
867 250320 : FOR( k = ( Nm1 / 2 ); k > 0; k-- )
868 : {
869 249280 : re[( length - k )] = re[k]; /*Qx*/
870 249280 : im[( length - k )] = L_negate( im[k] ); /*Qx*/
871 249280 : move32();
872 249280 : move32();
873 : }
874 :
875 1040 : IF( EQ_16( length, 512 ) )
876 : {
877 : /* Scaling down re and im buffers to avoid overflow in DoRTFTn_fx if the minimum headroom is less than 4 bits */
878 262 : hdrm = s_min( L_norm_arr( re, 512 ), L_norm_arr( im, 512 ) );
879 262 : IF( LT_16( hdrm, 4 ) )
880 : {
881 0 : tmp = sub( hdrm, 4 );
882 0 : scale_sig32( re, 512, tmp );
883 0 : scale_sig32( im, 512, tmp );
884 : }
885 :
886 262 : DoRTFTn_fx( re, im, 512 );
887 :
888 262 : IF( LT_16( hdrm, 4 ) )
889 : {
890 0 : tmp = negate( tmp );
891 0 : scale_sig32( re, 512, tmp );
892 0 : scale_sig32( im, 512, tmp );
893 : }
894 : }
895 : ELSE /* fft() doesn't support 512 */
896 : {
897 778 : fft_fx( re, im, length, 1 );
898 : }
899 :
900 251360 : FOR( k = ( Nm1 / 2 ); k >= 0; k-- ) /* post-modulation of FFT output */
901 : {
902 250320 : y[2 * k] = re[k]; /*Qx*/
903 250320 : move32();
904 250320 : IF( xSign != 0 )
905 : {
906 250320 : y[( ( k * 2 ) + 1 )] = Mpy_32_16_1( re[( Nm1 - k )], shl_sat( xSign, 15 ) ); /*Qx*/
907 : }
908 : ELSE
909 : {
910 0 : y[( ( k * 2 ) + 1 )] = 0; /*Qx*/
911 : }
912 250320 : move32();
913 : }
914 : }
915 : }
916 : #endif
917 : #ifdef IVAS_FLOAT_FIXED_TO_BE_DONE
918 : ELSE
919 : /* TODO: below IF and ELSE blocks are unreachable, verified on code coverage report */
920 : IF( s_and( kernelType, 1 ) ) /* DST */
921 : {
922 : const float offK = ( kernelType == MDST_II && synthesis ? 0.5f : 1.0f - 0.5f * ( kernelType >> 1 ) );
923 : const float offM = ( kernelType == MDST_II && synthesis ? 1.0f : 0.5f );
924 :
925 : FOR( k = 0; k < length; k++ )
926 : {
927 : y[k] = 0.f;
928 : FOR( m = 0; m < length; m++ )
929 : {
930 : y[k] += x[m] * sinf( pi_len * ( m + offM ) * ( k + offK ) );
931 : }
932 : }
933 : IF( offK == 1.f )
934 : {
935 : y[length - 1] *= 0.5f; /* scale Nyquist sample */
936 : }
937 : }
938 : ELSE /* kernelType 0, 2: DCT */
939 : {
940 : const float offK = ( EQ_16( kernelType, MDCT_II ) && synthesis ? 0.5f : 0.5f - shr( shr( kernelType, 1 ), 1 ) );
941 : const float offM = ( EQ_16( kernelType, MDCT_II ) && synthesis ? 0.0f : 0.5f );
942 :
943 : FOR( k = 0; k < length; k++ )
944 : {
945 : y[k] = 0.f;
946 : FOR( m = 0; m < length; m++ )
947 : {
948 : y[k] += x[m] * cosf( pi_len * ( m + offM ) * ( k + offK ) );
949 : }
950 : }
951 : IF( offK == 0.f )
952 : {
953 : y[0] *= 0.5f; /* scale lowest (i.e. DC) sample */
954 : }
955 : }
956 : #endif // IVAS_FLOAT_FIXED_TO_BE_DONE
957 : /*v_multc(y, (kernelType == MDCT_II ? -1.f : 1.f) * sqrtf(2.f / length), y, length);*/
958 1562 : fac = get_edxt_factor( length ); /* Q15 */
959 1562 : if ( EQ_16( kernelType, MDCT_II ) )
960 : {
961 774 : fac = negate( fac );
962 : }
963 :
964 795322 : FOR( m = 0; m < length; m++ )
965 : {
966 793760 : y[m] = Mpy_32_16_1( y[m], fac ); /*Qx*/
967 793760 : move32();
968 : }
969 1562 : return;
970 : }
|