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 1048 : static Word16 get_edxt_factor( Word16 length ) /* Returns value of sqrtf(2.f/length) in Q15 */
17 : {
18 : Word16 factor; /*Q15*/
19 1048 : factor = 0;
20 1048 : move16();
21 1048 : IF( EQ_16( length, 512 ) )
22 : {
23 266 : factor = 2048; /*0.0625 in Q15*/
24 266 : move16();
25 : }
26 782 : ELSE IF( EQ_16( length, 256 ) )
27 : {
28 5 : factor = 2896; /*0.0883 in Q15*/
29 5 : move16();
30 : }
31 777 : ELSE IF( EQ_16( length, 128 ) )
32 : {
33 7 : factor = 4096; /*0.125 in Q15*/
34 7 : move16();
35 : }
36 770 : ELSE IF( EQ_16( length, 640 ) )
37 : {
38 184 : factor = 1832; /*0.0559 in Q15*/
39 184 : move16();
40 : }
41 586 : ELSE IF( EQ_16( length, 320 ) )
42 : {
43 432 : factor = 2590; /*0.079 in Q15*/
44 432 : move16();
45 : }
46 154 : ELSE IF( EQ_16( length, 160 ) )
47 : {
48 22 : factor = 3663; /*0.1117 in Q15*/
49 22 : move16();
50 : }
51 132 : ELSE IF( EQ_16( length, 80 ) )
52 : {
53 22 : factor = 5181; /*0.1581 in Q15*/
54 22 : move16();
55 : }
56 110 : ELSE IF( EQ_16( length, 40 ) )
57 : {
58 0 : factor = 7327; /*0.223 in Q15*/
59 0 : move16();
60 : }
61 110 : ELSE IF( EQ_16( length, 960 ) )
62 : {
63 110 : factor = 1496; /*0.0456 in Q15*/
64 110 : 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 1048 : return factor; /*Q15*/
102 : }
103 :
104 1809424 : static Word16 const *get_edct_table( Word16 length /*Q0*/, Word16 *q )
105 : {
106 : Word16 const *edct_table;
107 1809424 : edct_table = NULL;
108 1809424 : SWITCH( length )
109 : {
110 6342 : case 1200:
111 6342 : edct_table = edct_table_600_fx; /*Q17*/
112 6342 : *q = add( *q, 2 );
113 6342 : move16();
114 6342 : BREAK;
115 605947 : case 960:
116 605947 : edct_table = edct_table_480_fx; /*Q16*/
117 605947 : BREAK;
118 579714 : case 640:
119 579714 : edct_table = edct_table_320_fx; /*Q16*/
120 579714 : BREAK;
121 215394 : case 320:
122 215394 : edct_table = edct_table_160_fx; /*Q16*/
123 215394 : BREAK;
124 50046 : case 256:
125 50046 : edct_table = edct_table_128_fx; /*Q16*/
126 50046 : BREAK;
127 23682 : case 240:
128 23682 : edct_table = edct_table_120_fx; /*Q16*/
129 23682 : BREAK;
130 0 : case 200:
131 0 : edct_table = edct_table_100_fx; /*Q16*/
132 0 : BREAK;
133 44922 : case 160:
134 44922 : edct_table = edct_table_80_fx; /*Q16*/
135 44922 : BREAK;
136 0 : case 40:
137 0 : edct_table = edct_table_20_fx; /*Q16*/
138 0 : BREAK;
139 2458 : case 800:
140 2458 : edct_table = edct_table_400_fx; /*Q17*/
141 2458 : *q = add( *q, 2 );
142 2458 : move16();
143 2458 : BREAK;
144 243562 : case 512:
145 243562 : edct_table = edct_table_256_fx; /*Q16*/
146 243562 : BREAK;
147 10083 : case 480:
148 10083 : edct_table = edct_table_240_fx; /*Q16*/
149 10083 : BREAK;
150 4769 : case 400:
151 4769 : edct_table = edct_table_200_fx; /*Q16*/
152 4769 : BREAK;
153 14465 : case 128:
154 14465 : edct_table = edct_table_64_fx; /*Q16*/
155 14465 : BREAK;
156 8040 : case 80:
157 8040 : edct_table = edct_table_40_fx; /*Q16*/
158 8040 : BREAK;
159 0 : default:
160 0 : BREAK;
161 : }
162 1809424 : 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 197251 : 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 197251 : edct_table = get_edct_table( length, q ); /*q*/
195 197251 : len1 = shr( length, 1 ); /*Q0*/
196 : /* Twiddling and Pre-rotate */
197 44001787 : FOR( i = 0; i < len1; i++ )
198 : {
199 43804536 : L_tmp = Mult_32_16( x[2 * i], edct_table[i] ); /*Q(q+1) */
200 43804536 : complex_buf[2 * i] = Madd_32_16( L_tmp, x[( length - ( 1 + ( i * 2 ) ) )], edct_table[( len1 - ( 1 + i ) )] ); /*Q(q+1) */
201 43804536 : move32();
202 :
203 43804536 : L_tmp = Mult_32_16( x[( length - ( 1 + ( i * 2 ) ) )], edct_table[i] ); /*Q(q+1) */
204 :
205 43804536 : complex_buf[( ( i * 2 ) + 1 )] = Msub_32_16( L_tmp, x[( i * 2 )], edct_table[( len1 - ( 1 + i ) )] ); /*Q(q+1) */
206 43804536 : move32();
207 : }
208 :
209 197251 : *q = sub( 15, *q );
210 197251 : move16();
211 197251 : BASOP_cfft( (cmplx *) complex_buf, len1, q, y );
212 :
213 197251 : tmp = div_s( 1, length ); /*Q15 */
214 197251 : tmp = round_fx( L_shl( L_mult( tmp, 19302 /*0.75f * EVS_PI in Q13*/ ), 2 ) ); /*Q15 */
215 44001787 : FOR( i = 0; i < len1; i++ )
216 : {
217 43804536 : re = Msub_32_16( complex_buf[2 * i], complex_buf[( ( i * 2 ) + 1 )], tmp ); /*Q(q+1) */
218 43804536 : im = Madd_32_16( complex_buf[( ( i * 2 ) + 1 )], complex_buf[2 * i], tmp ); /*Q(q+1) */
219 43804536 : 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 43804536 : move32();
221 43804536 : 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 43804536 : move32();
223 : } /*Q(q-2) */
224 :
225 197251 : *q = sub( 15 + 2, *q );
226 197251 : move16();
227 197251 : return;
228 : }
229 :
230 1610056 : 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 1610056 : edct_table = get_edct_table( length, q ); /*q*/
246 1610056 : len1 = shr( length, 1 ); /*Q0*/
247 : /* Twiddling and Pre-rotate */
248 552502504 : FOR( i = 0; i < len1; i++ )
249 : {
250 550892448 : L_tmp = Mult_32_16( x[2 * i], edct_table[i] ); /*Q(q+1) */
251 550892448 : re[i] = Madd_32_16( L_tmp, x[( length - ( 1 + ( i * 2 ) ) )], edct_table[( len1 - ( 1 + i ) )] ); /*Q(q+1) */
252 550892448 : move32();
253 :
254 550892448 : L_tmp = Mult_32_16( x[( length - ( 1 + ( i * 2 ) ) )], edct_table[i] ); /*Q(q+1) */
255 550892448 : im[i] = Msub_32_16( L_tmp, x[( i * 2 )], edct_table[( len1 - ( 1 + i ) )] ); /*Q(q+1) */
256 550892448 : move32();
257 : }
258 :
259 1610056 : *q = sub( 31, *q );
260 1610056 : move16();
261 1610056 : tmp = sub( s_min( getScaleFactor32( re, len1 ), getScaleFactor32( im, len1 ) ), find_guarded_bits_fx( len1 ) );
262 1610056 : scale_sig32( re, len1, tmp );
263 1610056 : scale_sig32( im, len1, tmp );
264 :
265 1610056 : fft_fx( re, im, len1, 1 );
266 1610056 : *q = sub( *q, tmp );
267 1610056 : move16();
268 :
269 1610056 : tmp = div_s( 4, length ); /*Q17 */
270 1610056 : tmp = round_fx( L_mult( tmp, 19302 /*0.75f * EVS_PI in Q13*/ ) ); /*Q15 */
271 552502504 : FOR( i = 0; i < len1; i++ )
272 : {
273 550892448 : L_tmp = Msub_32_16( re[i], im[i], tmp );
274 550892448 : im[i] = Madd_32_16( im[i], re[i], tmp ); /*Q(q+1) */
275 550892448 : re[i] = L_tmp; /*Q(q+1) */
276 550892448 : move32();
277 550892448 : move32();
278 : }
279 552502504 : FOR( i = 0; i < len1; i++ )
280 : {
281 550892448 : 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 550892448 : move32();
283 550892448 : 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 550892448 : move32();
285 : } /*Q(q-2) */
286 :
287 1610056 : *q = sub( 31 + 2, *q );
288 1610056 : move16();
289 1610056 : 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 2117 : 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 2117 : edct_table = get_edct_table( length, q ); /*q*/
321 2117 : len1 = shr( length, 1 ); /*Q0*/
322 : /* Twiddling and Pre-rotate */
323 734053 : FOR( i = 0; i < len1; i++ )
324 : {
325 731936 : L_tmp = Mult_32_16( x[( length - ( 1 + ( i * 2 ) ) )], edct_table[i] ); /*Qq+1*/
326 731936 : complex_buf[2 * i] = Madd_32_16( L_tmp, x[2 * i], edct_table[( len1 - ( 1 + i ) )] ); /*Qq+1*/
327 731936 : move32();
328 :
329 731936 : L_tmp = Mult_32_16( x[2 * i], edct_table[i] ); /*Qq+1*/
330 731936 : complex_buf[( ( i * 2 ) + 1 )] = Msub_32_16( L_tmp, x[( length - ( 1 + ( i * 2 ) ) )], edct_table[( len1 - ( 1 + i ) )] ); /*Qq+1*/
331 731936 : move32();
332 : }
333 :
334 2117 : *q = sub( 15, *q );
335 2117 : move16();
336 2117 : BASOP_cfft( (cmplx *) complex_buf, len1, q, y );
337 :
338 2117 : tmp = div_s( 1, length ); /*Q15 */
339 2117 : tmp = round_fx( L_shl( L_mult( tmp, 19302 /*0.75f * EVS_PI in Q13*/ ), 2 ) ); /*Q15 */
340 734053 : FOR( i = 0; i < len1; i++ )
341 : {
342 731936 : re = Msub_32_16( complex_buf[2 * i], complex_buf[( ( i * 2 ) + 1 )], tmp ); /*Qq+1*/
343 731936 : im = Madd_32_16( complex_buf[( ( i * 2 ) + 1 )], complex_buf[2 * i], tmp ); /*Qq+1*/
344 731936 : y[2 * i] = L_add( Mult_32_16( re, edct_table[i] ), Mult_32_16( im, edct_table[( len1 - ( 1 + i ) )] ) ); /*Qq+2*/
345 731936 : move32();
346 731936 : 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 731936 : move32();
348 : } /*Q(q) */
349 :
350 2117 : *q = sub( 15 + 2, *q );
351 2117 : move16();
352 :
353 2117 : 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 217551 : 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 217551 : 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 217551 : IF( EQ_16( length, L_FRAME32k ) )
408 : {
409 18654 : edct_table = &edct_table_320_16fx[0]; /*Q15*/
410 : }
411 198897 : ELSE IF( EQ_16( length, L_FRAME ) )
412 : {
413 121189 : edct_table = &edct_table_128_16fx[0]; /*Q15*/
414 : }
415 77708 : ELSE IF( EQ_16( length, L_FRAME16k ) )
416 : {
417 77708 : edct_table = &edct_table_160_16fx[0]; /*Q15*/
418 : }
419 : ELSE
420 : {
421 : }
422 :
423 : /* Twiddling and Pre-rotate */
424 217551 : Lmax = L_deposit_l( 0 );
425 217551 : Len2 = shr( length, 1 );
426 217551 : px = x + sub( length, 1 ); /*Qx*/
427 217551 : pt = edct_table + sub( Len2, 1 ); /*Q16*/
428 34132303 : FOR( i = 0; i < Len2; i++ )
429 : {
430 33914752 : i2 = shl( i, 1 );
431 33914752 : L_tmp = L_mult( x[i2], edct_table[i] ); /*Q(Qx+16) */
432 :
433 33914752 : Lacc = L_mac( L_tmp, *px, *pt ); /*Q(Qx+16) */
434 :
435 33914752 : Lmax = L_max( Lmax, Lacc );
436 :
437 33914752 : L_tmp = L_mult( *px, edct_table[i] ); /*Q(Qx+16) */
438 33914752 : Lacc = L_msu( L_tmp, x[i2], *pt ); /*Q(Qx+16) */
439 33914752 : Lmax = L_max( Lmax, Lacc );
440 :
441 33914752 : px -= 2;
442 33914752 : pt--;
443 : }
444 :
445 217551 : tmp = 31;
446 217551 : move16();
447 217551 : if ( Lmax != 0 )
448 : {
449 209254 : tmp = norm_l( Lmax );
450 : }
451 217551 : Q_edct = sub( tmp, bh ); /*creating a bit-headroom */
452 :
453 217551 : px = x + sub( length, 1 ); /*Qx*/
454 217551 : pt = edct_table + sub( Len2, 1 ); /*Q15*/
455 34132303 : FOR( i = 0; i < Len2; i++ )
456 : {
457 33914752 : i2 = shl( i, 1 );
458 :
459 33914752 : L_tmp = L_mult( x[i2], edct_table[i] ); /*Q(Qx+16) */
460 : #ifdef ISSUE_1836_replace_overflow_libcom
461 33914752 : Lacc = L_mac_sat( L_tmp, *px, *pt ); /*Q(Qx+16) */
462 33914752 : re2[i] = round_fx_sat( L_shl_sat( Lacc, Q_edct ) ); /* Q(Qx+Q_edct) */
463 33914752 : move16();
464 33914752 : L_tmp = L_mult( *px, edct_table[i] ); /*Q(Qx+16) */
465 33914752 : Lacc = L_msu_sat( L_tmp, x[i2], *pt ); /*Q(Qx+16) */
466 33914752 : 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 33914752 : move16();
476 33914752 : px -= 2;
477 33914752 : pt--;
478 : }
479 217551 : IF( EQ_16( length, L_FRAME32k ) )
480 : {
481 18654 : DoRTFT320_16fx( re2, im2 );
482 : }
483 198897 : ELSE IF( EQ_16( length, L_FRAME ) )
484 : {
485 121189 : DoRTFT128_16fx( re2, im2 );
486 : }
487 77708 : ELSE IF( EQ_16( length, L_FRAME16k ) )
488 : {
489 77708 : DoRTFT160_16fx( re2, im2 );
490 : }
491 : ELSE
492 : {
493 : }
494 217551 : tmp = div_s( 1, length ); /*Q15 */
495 217551 : L_tmp = L_mult( tmp, 19302 ); /*Q29, (3*PI/4) in Q13 */
496 217551 : fact = round_fx( L_shl( L_tmp, 2 ) ); /*Q15 */
497 34132303 : FOR( i = 0; i < shr( length, 1 ); i++ )
498 : {
499 33914752 : tmp = mult_r( im2[i], fact ); /*Q(Qx+Q_edct) */
500 : #ifdef ISSUE_1836_replace_overflow_libcom
501 33914752 : 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 33914752 : move16();
506 :
507 33914752 : tmp = mult_r( re2[i], fact ); /*Q(Qx+Q_edct) */
508 : #ifdef ISSUE_1836_replace_overflow_libcom
509 33914752 : 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 33914752 : move16();
514 : }
515 :
516 : /* Post-rotate and obtain the output data */
517 217551 : py = y + sub( length, 1 ); /*Qx*/
518 217551 : pt = edct_table + sub( Len2, 1 ); /*Q15*/
519 34132303 : FOR( i = 0; i < Len2; i++ )
520 : {
521 33914752 : i2 = shl( i, 1 );
522 :
523 33914752 : L_tmp = L_mult( re[i], edct_table[i] ); /*Q(Qx+Q_edct+16) */
524 : #ifdef ISSUE_1836_replace_overflow_libcom
525 33914752 : Lacc = L_mac_sat( L_tmp, im[i], *pt ); /*Q(Qx+Q_edct+16) */
526 33914752 : y[i2] = round_fx_sat( L_shr_sat( Lacc, Q_edct ) ); /* Q(Qx) */
527 33914752 : move16();
528 :
529 33914752 : L_tmp = L_mult( re[i], edct_table[sub( shr( length, 1 ), add( 1, i ) )] ); /*Q(Qx+Q_edct+16) */
530 33914752 : Lacc = L_msu( L_tmp, im[i], edct_table[i] ); /*Q(Qx+Q_edct+16) */
531 33914752 : *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 33914752 : move16();
542 :
543 33914752 : py -= 2;
544 33914752 : pt--;
545 : }
546 217551 : return;
547 : }
548 :
549 :
550 : /*-----------------------------------------------------------------*
551 : * iedct_short_fx()
552 : *
553 : * Inverse EDCT for short frames
554 : *-----------------------------------------------------------------*/
555 :
556 4312 : 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 4312 : qtmp = *Q;
569 4312 : move16();
570 4312 : tmp = 0;
571 4312 : move16();
572 4312 : seg_len_div2 = shr( segment_length, 1 ); /*Q0*/
573 4312 : seg_len_div4 = shr( segment_length, 2 ); /*Q0*/
574 4312 : seg_len_3mul_div4 = add( seg_len_div2, seg_len_div4 );
575 :
576 4312 : edct_fx( in, alias, seg_len_div2, Q );
577 4312 : FOR( i = 0; i < seg_len_div2; i++ )
578 : {
579 4312 : IF( alias[i] != 0 )
580 : {
581 4312 : tmp = 1;
582 4312 : move16();
583 4312 : BREAK;
584 : }
585 : }
586 4312 : if ( tmp == 0 )
587 : {
588 0 : *Q = qtmp;
589 0 : move16();
590 : }
591 344312 : FOR( i = 0; i < seg_len_div4; i++ )
592 : {
593 340000 : out[i] = alias[( seg_len_div4 + i )]; /*Q*/
594 340000 : move32();
595 340000 : out[( seg_len_div4 + i )] = L_negate( alias[( ( seg_len_div2 - 1 ) - i )] ); /*Q*/
596 340000 : move32();
597 340000 : out[( seg_len_div2 + i )] = L_negate( alias[( ( seg_len_div4 - 1 ) - i )] ); /*Q*/
598 340000 : move32();
599 340000 : out[( seg_len_3mul_div4 + i )] = L_negate( alias[i] ); /*Q*/
600 340000 : move32();
601 : }
602 :
603 4312 : 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 1048 : 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 1048 : Word16 k, m, fac, hdrm, tmp = 0;
622 : const Word16 *cosPtr, *sinPtr;
623 : Word16 n;
624 1048 : n = 0;
625 1048 : move16();
626 1048 : move16();
627 1048 : cosPtr = NULL;
628 1048 : sinPtr = NULL;
629 1048 : IF( EQ_16( length, 512 ) )
630 : {
631 266 : cosPtr = cos_scale_tbl_512; /*Q15*/
632 266 : sinPtr = sin_scale_tbl_512; /*Q15*/
633 266 : n = 1;
634 266 : move16();
635 : }
636 782 : 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 777 : 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 770 : ELSE IF( EQ_16( length, 640 ) )
651 : {
652 184 : cosPtr = cos_scale_tbl_640; /*Q15*/
653 184 : sinPtr = sin_scale_tbl_640; /*Q15*/
654 184 : n = 1;
655 184 : move16();
656 : }
657 586 : ELSE IF( EQ_16( length, 320 ) )
658 : {
659 432 : cosPtr = cos_scale_tbl_640; /*Q15*/
660 432 : sinPtr = sin_scale_tbl_640; /*Q15*/
661 432 : n = 2;
662 432 : move16();
663 : }
664 154 : ELSE IF( EQ_16( length, 160 ) )
665 : {
666 22 : cosPtr = cos_scale_tbl_640; /*Q15*/
667 22 : sinPtr = sin_scale_tbl_640; /*Q15*/
668 22 : n = 4;
669 22 : move16();
670 : }
671 132 : ELSE IF( EQ_16( length, 80 ) )
672 : {
673 22 : cosPtr = cos_scale_tbl_640; /*Q15*/
674 22 : sinPtr = sin_scale_tbl_640; /*Q15*/
675 22 : n = 8;
676 22 : move16();
677 : }
678 110 : 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 110 : ELSE IF( EQ_16( length, 960 ) )
686 : {
687 110 : cosPtr = cos_scale_tbl_960; /*Q15*/
688 110 : sinPtr = sin_scale_tbl_960; /*Q15*/
689 110 : n = 1;
690 110 : 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 1048 : test();
744 1048 : IF( EQ_16( kernelType, MDST_II ) || EQ_16( kernelType, MDCT_II ) )
745 : {
746 1048 : const Word16 Nm1 = sub( length, 1 );
747 1048 : 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 1048 : IF( !synthesis )
752 : {
753 0 : FOR( k = ( Nm1 / 2 ); k >= 0; k-- ) /* pre-modulation of audio input */
754 : {
755 0 : re[k] = x[2 * k]; /*Qx*/
756 0 : re[( Nm1 - k )] = Mpy_32_16_1( x[( ( k * 2 ) + 1 )], shl_sat( xSign, 15 ) ); /*Qx*/
757 0 : im[k] = im[( Nm1 - k )] = 0;
758 0 : move32();
759 0 : move32();
760 0 : move32();
761 : }
762 :
763 0 : 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 0 : fft_fx( re, im, length, 1 );
786 : }
787 :
788 0 : IF( shr( kernelType, 1 ) )
789 : {
790 0 : FOR( k = ( Nm1 / 2 ); k > 0; k-- )
791 : {
792 : // const float wRe = cosf( scale * k );
793 : // const float wIm = sinf( scale * k );
794 0 : const Word16 wRe = cosPtr[( k * n )]; /*Q15*/
795 0 : const Word16 wIm = sinPtr[( k * n )]; /*Q15*/
796 :
797 0 : y[k] /*pt 1*/ = L_add( Mpy_32_16_1( re[k], wRe ), Mpy_32_16_1( im[k], wIm ) ); /*Qx*/
798 0 : y[( length - k )] = L_sub( Mpy_32_16_1( re[k], wIm ), Mpy_32_16_1( im[k], wRe ) ); /*Qx*/
799 0 : move32();
800 0 : move32();
801 : }
802 0 : y[( length / 2 )] = Mpy_32_16_1( re[( length / 2 )], INV_SQRT_2_Q15 ); /*Qx*/
803 0 : move32();
804 : }
805 : ELSE /* forw. DST-II */
806 : {
807 0 : FOR( k = ( Nm1 / 2 ); k > 0; k-- )
808 : {
809 : // const float wRe = cosf( scale * k );
810 : // const float wIm = sinf( scale * k );
811 0 : const Word16 wRe = cosPtr[( k * n )]; /*Q15*/
812 0 : const Word16 wIm = sinPtr[( k * n )]; /*Q15*/
813 :
814 0 : y[( Nm1 - k )] = L_add( Mpy_32_16_1( re[k], wRe ), Mpy_32_16_1( im[k], wIm ) ); /*Qx*/
815 0 : y[k - 1] = L_sub( Mpy_32_16_1( re[k], wIm ), Mpy_32_16_1( im[k], wRe ) ); /*Qx*/
816 0 : move32();
817 0 : move32();
818 : }
819 0 : y[( Nm1 / 2 )] = Mpy_32_16_1( re[( length / 2 )], INV_SQRT_2_Q15 ); /*Qx*/
820 0 : move32();
821 : }
822 :
823 0 : y[( Nm1 - ( Nm1 * ( kernelType / 2 ) ) )] = L_shr( re[0], 1 ); /*Qx*/
824 0 : move32();
825 : }
826 : ELSE /* inverse II = III */
827 : {
828 1048 : IF( shr( kernelType, 1 ) )
829 : {
830 122624 : 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 122106 : const Word16 wRe = shr( cosPtr[imult1616( k, n )], 1 );
835 122106 : const Word16 wIm = shr( sinPtr[imult1616( k, n )], 1 );
836 :
837 122106 : re[k] = L_add( Mpy_32_16_1( x[k], wRe ), Mpy_32_16_1( x[( length - k )], wIm ) ); /*Qx*/
838 122106 : im[k] = L_sub( Mpy_32_16_1( x[( length - k )], wRe ), Mpy_32_16_1( x[k], wIm ) ); /*Qx*/
839 122106 : move32();
840 122106 : move32();
841 : }
842 518 : re[( length / 2 )] = Mpy_32_16_1( x[( length / 2 )], INV_SQRT_2_Q15 ); /*Qx*/
843 518 : move32();
844 : }
845 : ELSE /* DST type III */
846 : {
847 130000 : 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 129470 : const Word16 wRe = shr( cosPtr[( k * n )], 1 ); /*Q15*/
852 129470 : const Word16 wIm = shr( sinPtr[( k * n )], 1 ); /*Q15*/
853 :
854 129470 : re[k] = L_add( Mpy_32_16_1( x[( Nm1 - k )], wRe ), Mpy_32_16_1( x[( k - 1 )], wIm ) ); /*Qx*/
855 129470 : im[k] = L_sub( Mpy_32_16_1( x[( k - 1 )], wRe ), Mpy_32_16_1( x[( Nm1 - k )], wIm ) ); /*Qx*/
856 129470 : move32();
857 129470 : move32();
858 : }
859 530 : re[( length / 2 )] = Mpy_32_16_1( x[( Nm1 / 2 )], INV_SQRT_2_Q15 ); /*Qx*/
860 530 : move32();
861 : }
862 :
863 1048 : re[0] = x[( Nm1 - ( Nm1 * ( kernelType / 2 ) ) )]; /*Qx*/
864 1048 : im[0] = im[( length / 2 )] = 0;
865 1048 : move32();
866 1048 : move32();
867 252624 : FOR( k = ( Nm1 / 2 ); k > 0; k-- )
868 : {
869 251576 : re[( length - k )] = re[k]; /*Qx*/
870 251576 : im[( length - k )] = L_negate( im[k] ); /*Qx*/
871 251576 : move32();
872 251576 : move32();
873 : }
874 :
875 1048 : 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 266 : hdrm = s_min( L_norm_arr( re, 512 ), L_norm_arr( im, 512 ) );
879 266 : 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 266 : DoRTFTn_fx( re, im, 512 );
887 :
888 266 : 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 782 : fft_fx( re, im, length, 1 );
898 : }
899 :
900 253672 : FOR( k = ( Nm1 / 2 ); k >= 0; k-- ) /* post-modulation of FFT output */
901 : {
902 252624 : y[2 * k] = re[k]; /*Qx*/
903 252624 : move32();
904 252624 : IF( xSign != 0 )
905 : {
906 252624 : 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 252624 : 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 1048 : fac = get_edxt_factor( length ); /* Q15 */
959 1048 : if ( EQ_16( kernelType, MDCT_II ) )
960 : {
961 518 : fac = negate( fac );
962 : }
963 :
964 506296 : FOR( m = 0; m < length; m++ )
965 : {
966 505248 : y[m] = Mpy_32_16_1( y[m], fac ); /*Qx*/
967 505248 : move32();
968 : }
969 1048 : return;
970 : }
|