1 /*
2 * (c) 2002 Fabrice Bellard
3 *
4 * This file is part of FFmpeg.
5 *
6 * FFmpeg is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * FFmpeg is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with FFmpeg; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 /**
22 * @file
23 * FFT and MDCT tests.
24 */
25
26 #include "config.h"
27
28 #ifndef AVFFT
30 #endif
31
32 #include <math.h>
33 #if HAVE_UNISTD_H
34 #include <unistd.h>
35 #endif
36 #include <stdio.h>
37 #include <stdlib.h>
38 #include <string.h>
39
46
47 #if AVFFT
49 #else
51 #endif
52
53 #if FFT_FLOAT
56 #endif
57
58 /* reference fft */
59
60 #define MUL16(a, b) ((a) * (b))
61
62 #define CMAC(pre, pim, are, aim, bre, bim) \
63 { \
64 pre += (MUL16(are, bre) - MUL16(aim, bim)); \
65 pim += (MUL16(are, bim) + MUL16(bre, aim)); \
66 }
67
68 #if FFT_FLOAT || AVFFT
69 #define RANGE 1.0
70 #define REF_SCALE(x, bits) (x)
71 #define FMT "%10.6f"
72 #else
74 #define REF_SCALE(x, bits) (x)
76 #endif
77
78 static struct {
81
83 {
84 int i, n = 1 << nbits;
85
89
90 for (
i = 0;
i < (n / 2);
i++) {
97 }
98 return 0;
99 }
100
102 {
104 int n = 1 << nbits;
105 int n2 = n >> 1;
106
107 for (
i = 0;
i < n;
i++) {
108 double tmp_re = 0, tmp_im = 0;
110 for (j = 0; j < n; j++) {
112 int k = (
i * j) & (n - 1);
113 if (k >= n2) {
116 } else {
119 }
121 q++;
122 }
125 }
126 }
127
128 #if CONFIG_MDCT
130 {
131 int i, k, n = 1 << nbits;
132
133 for (
i = 0;
i < n;
i++) {
134 double sum = 0;
135 for (k = 0; k < n / 2; k++) {
136 int a = (2 *
i + 1 + (n / 2)) * (2 * k + 1);
137 double f = cos(
M_PI *
a / (
double) (2 * n));
139 }
141 }
142 }
143
144 /* NOTE: no normalisation by 1 / N is done */
146 {
147 int i, k, n = 1 << nbits;
148
149 /* do it by hand */
150 for (k = 0; k < n / 2; k++) {
152 for (
i = 0;
i < n;
i++) {
153 double a = (2 *
M_PI * (2 *
i + 1 + n / 2) * (2 * k + 1) / (4 * n));
155 }
157 }
158 }
159 #endif /* CONFIG_MDCT */
160
161 #if FFT_FLOAT
162 #if CONFIG_DCT
164 {
165 int i, k, n = 1 << nbits;
166
167 /* do it by hand */
168 for (
i = 0;
i < n;
i++) {
169 double s = 0.5 *
input[0];
170 for (k = 1; k < n; k++) {
171 double a =
M_PI * k * (
i + 0.5) / n;
173 }
175 }
176 }
177
179 {
180 int i, k, n = 1 << nbits;
181
182 /* do it by hand */
183 for (k = 0; k < n; k++) {
185 for (
i = 0;
i < n;
i++) {
186 double a =
M_PI * k * (
i + 0.5) / n;
188 }
190 }
191 }
192 #endif /* CONFIG_DCT */
193 #endif /* FFT_FLOAT */
194
196 {
198 }
199
201 {
204
205 for (
i = 0;
i < n;
i++) {
207 if (e >= 1e-3) {
210 err = 1;
211 }
215 }
217 return err;
218 }
219
221 {
222 #if AVFFT
224 #else
226 #endif
227 }
228
229 #if CONFIG_MDCT
231 {
232 #if AVFFT
234 #else
236 #endif
237 }
238
240 {
241 #if AVFFT
243 #else
245 #endif
246 }
247
249 {
250 #if AVFFT
252 #else
254 #endif
255 }
256 #endif
257
259 {
260 #if AVFFT
262 #else
263 s->fft_permute(
s, z);
264 #endif
265 }
266
268 {
269 #if AVFFT
271 #else
273 #endif
274 }
275
277 {
278 #if AVFFT
280 #else
282 #endif
283 }
284
286 {
287 #if AVFFT
289 #else
291 #endif
292 }
293
294 #if FFT_FLOAT
296 {
297 #if AVFFT
299 #else
301 #endif
302 }
303
305 {
306 #if AVFFT
308 #else
310 #endif
311 }
312
314 {
315 #if AVFFT
317 #else
318 r->rdft_calc(
r,
tab);
319 #endif
320 }
321
323 {
324 #if AVFFT
326 #else
328 #endif
329 }
330
332 {
333 #if AVFFT
335 #else
337 #endif
338 }
339
341 {
342 #if AVFFT
344 #else
346 #endif
347 }
348 #endif /* FFT_FLOAT */
349
351 {
353 "usage: fft-test [-h] [-s] [-i] [-n b]\n"
354 "-h print this help\n"
355 "-s speed test\n"
356 "-m (I)MDCT test\n"
357 "-d (I)DCT test\n"
358 "-r (I)RDFT test\n"
359 "-i inverse transform test\n"
360 "-n b set the transform size to 2^b\n"
361 "-f x set scale factor for output data of (I)MDCT to x\n");
362 }
363
369 };
370
371 #if !HAVE_GETOPT
373 #endif
374
375 int main(
int argc,
char **argv)
376 {
381 #if FFT_FLOAT
384 #endif /* FFT_FLOAT */
386 int do_speed = 0, do_inverse = 0;
387 int fft_nbits = 9, fft_size;
390
391 #if !AVFFT
394 #endif
395
396 #if !AVFFT && FFT_FLOAT
399 #endif
400
402
403 for (;;) {
404 int c =
getopt(argc, argv,
"hsimrdn:f:c:");
406 break;
408 case 'h':
410 return 1;
411 case 's':
412 do_speed = 1;
413 break;
414 case 'i':
415 do_inverse = 1;
416 break;
417 case 'm':
419 break;
420 case 'r':
422 break;
423 case 'd':
425 break;
426 case 'n':
428 break;
429 case 'f':
431 break;
432 case 'c':
433 {
435
437 return 1;
438
440 break;
441 }
442 }
443 }
444
445 fft_size = 1 << fft_nbits;
450
453
455 #if CONFIG_MDCT
458 if (do_inverse)
460 else
462 mdct_init(&m, fft_nbits, do_inverse,
scale);
463 break;
464 #endif /* CONFIG_MDCT */
466 if (do_inverse)
468 else
473 break;
474 #if FFT_FLOAT
475 # if CONFIG_RDFT
477 if (do_inverse)
479 else
484 break;
485 # endif /* CONFIG_RDFT */
486 # if CONFIG_DCT
488 if (do_inverse)
490 else
493 break;
494 # endif /* CONFIG_DCT */
495 #endif /* FFT_FLOAT */
496 default:
499 }
501
502 /* generate random data */
503
504 for (
i = 0;
i < fft_size;
i++) {
507 }
508
509 /* checking result */
511
513 #if CONFIG_MDCT
515 if (do_inverse) {
516 imdct_ref(&tab_ref->
re, &
tab1->re, fft_nbits);
519 } else {
520 mdct_ref(&tab_ref->
re, &
tab1->re, fft_nbits);
523 }
524 break;
525 #endif /* CONFIG_MDCT */
530
533 break;
534 #if FFT_FLOAT
535 #if CONFIG_RDFT
537 {
538 int fft_size_2 = fft_size >> 1;
539 if (do_inverse) {
541 tab1[fft_size_2].im = 0;
542 for (
i = 1;
i < fft_size_2;
i++) {
543 tab1[fft_size_2 +
i].re =
tab1[fft_size_2 -
i].re;
544 tab1[fft_size_2 +
i].im = -
tab1[fft_size_2 -
i].im;
545 }
546
549
552 for (
i = 0;
i < fft_size;
i++) {
555 }
557 } else {
558 for (
i = 0;
i < fft_size;
i++) {
561 }
564 tab_ref[0].
im = tab_ref[fft_size_2].
re;
566 }
567 break;
568 }
569 #endif /* CONFIG_RDFT */
570 #if CONFIG_DCT
573 dct_calc(
d, &
tab->re);
574 if (do_inverse)
575 idct_ref(&tab_ref->
re, &
tab1->re, fft_nbits);
576 else
577 dct_ref(&tab_ref->
re, &
tab1->re, fft_nbits);
579 break;
580 #endif /* CONFIG_DCT */
581 #endif /* FFT_FLOAT */
582 }
583
584 /* do a speed test */
585
586 if (do_speed) {
588 int nb_its;
589
591 /* we measure during about 1 seconds */
592 nb_its = 1;
593 for (;;) {
595 for (
it = 0;
it < nb_its;
it++) {
597 #if CONFIG_MDCT
599 if (do_inverse)
601 else
602 mdct_calc(m, &
tab->re, &
tab1->re);
603 break;
604 #endif
608 break;
609 #if FFT_FLOAT
613 break;
617 break;
618 #endif /* FFT_FLOAT */
619 }
620 }
623 break;
624 nb_its *= 2;
625 }
627 "time: %0.1f us/transform [total time=%0.2f s its=%d]\n",
630 nb_its);
631 }
632
634 #if CONFIG_MDCT
637 break;
638 #endif /* CONFIG_MDCT */
641 break;
642 #if FFT_FLOAT
643 # if CONFIG_RDFT
646 break;
647 # endif /* CONFIG_RDFT */
648 # if CONFIG_DCT
651 break;
652 # endif /* CONFIG_DCT */
653 #endif /* FFT_FLOAT */
654 }
655
662
663 #if !AVFFT
666 #endif
667
668 #if !AVFFT && FFT_FLOAT
671 #endif
672
673 if (err)
674 printf(
"Error: %d.\n", err);
675
676 return !!err;
677 }