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