Libav
fft-test.c
Go to the documentation of this file.
1 /*
2  * (c) 2002 Fabrice Bellard
3  *
4  * This file is part of Libav.
5  *
6  * Libav 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  * Libav 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 Libav; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19  */
20 
26 #include "config.h"
27 
28 #include <math.h>
29 #if HAVE_UNISTD_H
30 #include <unistd.h>
31 #endif
32 #include <stdio.h>
33 #include <stdlib.h>
34 #include <string.h>
35 
36 #include "libavutil/cpu.h"
37 #include "libavutil/lfg.h"
38 #include "libavutil/log.h"
39 #include "libavutil/mathematics.h"
40 #include "libavutil/time.h"
41 
42 #include "fft.h"
43 #if FFT_FLOAT
44 #include "dct.h"
45 #include "rdft.h"
46 #endif
47 
48 /* reference fft */
49 
50 #define MUL16(a, b) ((a) * (b))
51 
52 #define CMAC(pre, pim, are, aim, bre, bim) \
53  { \
54  pre += (MUL16(are, bre) - MUL16(aim, bim)); \
55  pim += (MUL16(are, bim) + MUL16(bre, aim)); \
56  }
57 
58 #if FFT_FLOAT
59 #define RANGE 1.0
60 #define REF_SCALE(x, bits) (x)
61 #define FMT "%10.6f"
62 #else
63 #define RANGE 16384
64 #define REF_SCALE(x, bits) ((x) / (1 << (bits)))
65 #define FMT "%6d"
66 #endif
67 
68 static struct {
69  float re, im;
70 } *exptab;
71 
72 static int fft_ref_init(int nbits, int inverse)
73 {
74  int i, n = 1 << nbits;
75 
76  exptab = av_malloc((n / 2) * sizeof(*exptab));
77  if (!exptab)
78  return AVERROR(ENOMEM);
79 
80  for (i = 0; i < (n / 2); i++) {
81  double alpha = 2 * M_PI * (float) i / (float) n;
82  double c1 = cos(alpha), s1 = sin(alpha);
83  if (!inverse)
84  s1 = -s1;
85  exptab[i].re = c1;
86  exptab[i].im = s1;
87  }
88  return 0;
89 }
90 
91 static void fft_ref(FFTComplex *tabr, FFTComplex *tab, int nbits)
92 {
93  int i, j;
94  int n = 1 << nbits;
95  int n2 = n >> 1;
96 
97  for (i = 0; i < n; i++) {
98  double tmp_re = 0, tmp_im = 0;
99  FFTComplex *q = tab;
100  for (j = 0; j < n; j++) {
101  double s, c;
102  int k = (i * j) & (n - 1);
103  if (k >= n2) {
104  c = -exptab[k - n2].re;
105  s = -exptab[k - n2].im;
106  } else {
107  c = exptab[k].re;
108  s = exptab[k].im;
109  }
110  CMAC(tmp_re, tmp_im, c, s, q->re, q->im);
111  q++;
112  }
113  tabr[i].re = REF_SCALE(tmp_re, nbits);
114  tabr[i].im = REF_SCALE(tmp_im, nbits);
115  }
116 }
117 
118 #if CONFIG_MDCT
119 static void imdct_ref(FFTSample *out, FFTSample *in, int nbits)
120 {
121  int i, k, n = 1 << nbits;
122 
123  for (i = 0; i < n; i++) {
124  double sum = 0;
125  for (k = 0; k < n / 2; k++) {
126  int a = (2 * i + 1 + (n / 2)) * (2 * k + 1);
127  double f = cos(M_PI * a / (double) (2 * n));
128  sum += f * in[k];
129  }
130  out[i] = REF_SCALE(-sum, nbits - 2);
131  }
132 }
133 
134 /* NOTE: no normalisation by 1 / N is done */
135 static void mdct_ref(FFTSample *output, FFTSample *input, int nbits)
136 {
137  int i, k, n = 1 << nbits;
138 
139  /* do it by hand */
140  for (k = 0; k < n / 2; k++) {
141  double s = 0;
142  for (i = 0; i < n; i++) {
143  double a = (2 * M_PI * (2 * i + 1 + n / 2) * (2 * k + 1) / (4 * n));
144  s += input[i] * cos(a);
145  }
146  output[k] = REF_SCALE(s, nbits - 1);
147  }
148 }
149 #endif /* CONFIG_MDCT */
150 
151 #if FFT_FLOAT
152 #if CONFIG_DCT
153 static void idct_ref(float *output, float *input, int nbits)
154 {
155  int i, k, n = 1 << nbits;
156 
157  /* do it by hand */
158  for (i = 0; i < n; i++) {
159  double s = 0.5 * input[0];
160  for (k = 1; k < n; k++) {
161  double a = M_PI * k * (i + 0.5) / n;
162  s += input[k] * cos(a);
163  }
164  output[i] = 2 * s / n;
165  }
166 }
167 
168 static void dct_ref(float *output, float *input, int nbits)
169 {
170  int i, k, n = 1 << nbits;
171 
172  /* do it by hand */
173  for (k = 0; k < n; k++) {
174  double s = 0;
175  for (i = 0; i < n; i++) {
176  double a = M_PI * k * (i + 0.5) / n;
177  s += input[i] * cos(a);
178  }
179  output[k] = s;
180  }
181 }
182 #endif /* CONFIG_DCT */
183 #endif /* FFT_FLOAT */
184 
185 static FFTSample frandom(AVLFG *prng)
186 {
187  return (int16_t) av_lfg_get(prng) / 32768.0 * RANGE;
188 }
189 
190 static int check_diff(FFTSample *tab1, FFTSample *tab2, int n, double scale)
191 {
192  int i, err = 0;
193  double error = 0, max = 0;
194 
195  for (i = 0; i < n; i++) {
196  double e = fabsf(tab1[i] - (tab2[i] / scale)) / RANGE;
197  if (e >= 1e-3) {
198  av_log(NULL, AV_LOG_ERROR, "ERROR %5d: "FMT" "FMT"\n",
199  i, tab1[i], tab2[i]);
200  err = 1;
201  }
202  error += e * e;
203  if (e > max)
204  max = e;
205  }
206  av_log(NULL, AV_LOG_INFO, "max:%f e:%g\n", max, sqrt(error) / n);
207  return err;
208 }
209 
210 static void help(void)
211 {
213  "usage: fft-test [-h] [-s] [-i] [-n b]\n"
214  "-h print this help\n"
215  "-s speed test\n"
216  "-m (I)MDCT test\n"
217  "-d (I)DCT test\n"
218  "-r (I)RDFT test\n"
219  "-i inverse transform test\n"
220  "-n b set the transform size to 2^b\n"
221  "-f x set scale factor for output data of (I)MDCT to x\n");
222 }
223 
229 };
230 
231 #if !HAVE_GETOPT
232 #include "compat/getopt.c"
233 #endif
234 
235 int main(int argc, char **argv)
236 {
237  FFTComplex *tab, *tab1, *tab_ref;
238  FFTSample *tab2;
240  FFTContext m, s;
241 #if FFT_FLOAT
242  RDFTContext r;
243  DCTContext d;
244 #endif /* FFT_FLOAT */
245  int it, i, err = 1;
246  int do_speed = 0, do_inverse = 0;
247  int fft_nbits = 9, fft_size;
248  double scale = 1.0;
249  AVLFG prng;
250 
251  av_lfg_init(&prng, 1);
252 
253  for (;;) {
254  int c = getopt(argc, argv, "hsimrdn:f:c:");
255  if (c == -1)
256  break;
257  switch (c) {
258  case 'h':
259  help();
260  return 1;
261  case 's':
262  do_speed = 1;
263  break;
264  case 'i':
265  do_inverse = 1;
266  break;
267  case 'm':
268  transform = TRANSFORM_MDCT;
269  break;
270  case 'r':
271  transform = TRANSFORM_RDFT;
272  break;
273  case 'd':
274  transform = TRANSFORM_DCT;
275  break;
276  case 'n':
277  fft_nbits = atoi(optarg);
278  break;
279  case 'f':
280  scale = atof(optarg);
281  break;
282  case 'c':
283  {
284  int cpuflags = av_parse_cpu_flags(optarg);
285  if (cpuflags < 0)
286  return 1;
287  av_set_cpu_flags_mask(cpuflags);
288  break;
289  }
290  }
291  }
292 
293  fft_size = 1 << fft_nbits;
294  tab = av_malloc(fft_size * sizeof(FFTComplex));
295  tab1 = av_malloc(fft_size * sizeof(FFTComplex));
296  tab_ref = av_malloc(fft_size * sizeof(FFTComplex));
297  tab2 = av_malloc(fft_size * sizeof(FFTSample));
298 
299  if (!(tab && tab1 && tab_ref && tab2))
300  goto cleanup;
301 
302  switch (transform) {
303 #if CONFIG_MDCT
304  case TRANSFORM_MDCT:
305  av_log(NULL, AV_LOG_INFO, "Scale factor is set to %f\n", scale);
306  if (do_inverse)
307  av_log(NULL, AV_LOG_INFO, "IMDCT");
308  else
309  av_log(NULL, AV_LOG_INFO, "MDCT");
310  ff_mdct_init(&m, fft_nbits, do_inverse, scale);
311  break;
312 #endif /* CONFIG_MDCT */
313  case TRANSFORM_FFT:
314  if (do_inverse)
315  av_log(NULL, AV_LOG_INFO, "IFFT");
316  else
317  av_log(NULL, AV_LOG_INFO, "FFT");
318  ff_fft_init(&s, fft_nbits, do_inverse);
319  if (err = fft_ref_init(fft_nbits, do_inverse) < 0)
320  goto cleanup;
321  break;
322 #if FFT_FLOAT
323 #if CONFIG_RDFT
324  case TRANSFORM_RDFT:
325  if (do_inverse)
326  av_log(NULL, AV_LOG_INFO, "IDFT_C2R");
327  else
328  av_log(NULL, AV_LOG_INFO, "DFT_R2C");
329  ff_rdft_init(&r, fft_nbits, do_inverse ? IDFT_C2R : DFT_R2C);
330  if (err = fft_ref_init(fft_nbits, do_inverse) < 0)
331  goto cleanup;
332  break;
333 #endif /* CONFIG_RDFT */
334 #if CONFIG_DCT
335  case TRANSFORM_DCT:
336  if (do_inverse)
337  av_log(NULL, AV_LOG_INFO, "DCT_III");
338  else
339  av_log(NULL, AV_LOG_INFO, "DCT_II");
340  ff_dct_init(&d, fft_nbits, do_inverse ? DCT_III : DCT_II);
341  break;
342 #endif /* CONFIG_DCT */
343 #endif /* FFT_FLOAT */
344  default:
345  av_log(NULL, AV_LOG_ERROR, "Requested transform not supported\n");
346  goto cleanup;
347  }
348  av_log(NULL, AV_LOG_INFO, " %d test\n", fft_size);
349 
350  /* generate random data */
351 
352  for (i = 0; i < fft_size; i++) {
353  tab1[i].re = frandom(&prng);
354  tab1[i].im = frandom(&prng);
355  }
356 
357  /* checking result */
358  av_log(NULL, AV_LOG_INFO, "Checking...\n");
359 
360  switch (transform) {
361 #if CONFIG_MDCT
362  case TRANSFORM_MDCT:
363  if (do_inverse) {
364  imdct_ref(&tab_ref->re, &tab1->re, fft_nbits);
365  m.imdct_calc(&m, tab2, &tab1->re);
366  err = check_diff(&tab_ref->re, tab2, fft_size, scale);
367  } else {
368  mdct_ref(&tab_ref->re, &tab1->re, fft_nbits);
369  m.mdct_calc(&m, tab2, &tab1->re);
370  err = check_diff(&tab_ref->re, tab2, fft_size / 2, scale);
371  }
372  break;
373 #endif /* CONFIG_MDCT */
374  case TRANSFORM_FFT:
375  memcpy(tab, tab1, fft_size * sizeof(FFTComplex));
376  s.fft_permute(&s, tab);
377  s.fft_calc(&s, tab);
378 
379  fft_ref(tab_ref, tab1, fft_nbits);
380  err = check_diff(&tab_ref->re, &tab->re, fft_size * 2, 1.0);
381  break;
382 #if FFT_FLOAT
383 #if CONFIG_RDFT
384  case TRANSFORM_RDFT:
385  {
386  int fft_size_2 = fft_size >> 1;
387  if (do_inverse) {
388  tab1[0].im = 0;
389  tab1[fft_size_2].im = 0;
390  for (i = 1; i < fft_size_2; i++) {
391  tab1[fft_size_2 + i].re = tab1[fft_size_2 - i].re;
392  tab1[fft_size_2 + i].im = -tab1[fft_size_2 - i].im;
393  }
394 
395  memcpy(tab2, tab1, fft_size * sizeof(FFTSample));
396  tab2[1] = tab1[fft_size_2].re;
397 
398  r.rdft_calc(&r, tab2);
399  fft_ref(tab_ref, tab1, fft_nbits);
400  for (i = 0; i < fft_size; i++) {
401  tab[i].re = tab2[i];
402  tab[i].im = 0;
403  }
404  err = check_diff(&tab_ref->re, &tab->re, fft_size * 2, 0.5);
405  } else {
406  for (i = 0; i < fft_size; i++) {
407  tab2[i] = tab1[i].re;
408  tab1[i].im = 0;
409  }
410  r.rdft_calc(&r, tab2);
411  fft_ref(tab_ref, tab1, fft_nbits);
412  tab_ref[0].im = tab_ref[fft_size_2].re;
413  err = check_diff(&tab_ref->re, tab2, fft_size, 1.0);
414  }
415  break;
416  }
417 #endif /* CONFIG_RDFT */
418 #if CONFIG_DCT
419  case TRANSFORM_DCT:
420  memcpy(tab, tab1, fft_size * sizeof(FFTComplex));
421  d.dct_calc(&d, &tab->re);
422  if (do_inverse)
423  idct_ref(&tab_ref->re, &tab1->re, fft_nbits);
424  else
425  dct_ref(&tab_ref->re, &tab1->re, fft_nbits);
426  err = check_diff(&tab_ref->re, &tab->re, fft_size, 1.0);
427  break;
428 #endif /* CONFIG_DCT */
429 #endif /* FFT_FLOAT */
430  }
431 
432  /* do a speed test */
433 
434  if (do_speed) {
435  int64_t time_start, duration;
436  int nb_its;
437 
438  av_log(NULL, AV_LOG_INFO, "Speed test...\n");
439  /* we measure during about 1 seconds */
440  nb_its = 1;
441  for (;;) {
442  time_start = av_gettime();
443  for (it = 0; it < nb_its; it++) {
444  switch (transform) {
445  case TRANSFORM_MDCT:
446  if (do_inverse)
447  m.imdct_calc(&m, &tab->re, &tab1->re);
448  else
449  m.mdct_calc(&m, &tab->re, &tab1->re);
450  break;
451  case TRANSFORM_FFT:
452  memcpy(tab, tab1, fft_size * sizeof(FFTComplex));
453  s.fft_calc(&s, tab);
454  break;
455 #if FFT_FLOAT
456  case TRANSFORM_RDFT:
457  memcpy(tab2, tab1, fft_size * sizeof(FFTSample));
458  r.rdft_calc(&r, tab2);
459  break;
460  case TRANSFORM_DCT:
461  memcpy(tab2, tab1, fft_size * sizeof(FFTSample));
462  d.dct_calc(&d, tab2);
463  break;
464 #endif /* FFT_FLOAT */
465  }
466  }
467  duration = av_gettime() - time_start;
468  if (duration >= 1000000)
469  break;
470  nb_its *= 2;
471  }
473  "time: %0.1f us/transform [total time=%0.2f s its=%d]\n",
474  (double) duration / nb_its,
475  (double) duration / 1000000.0,
476  nb_its);
477  }
478 
479  switch (transform) {
480 #if CONFIG_MDCT
481  case TRANSFORM_MDCT:
482  ff_mdct_end(&m);
483  break;
484 #endif /* CONFIG_MDCT */
485  case TRANSFORM_FFT:
486  ff_fft_end(&s);
487  break;
488 #if FFT_FLOAT
489 #if CONFIG_RDFT
490  case TRANSFORM_RDFT:
491  ff_rdft_end(&r);
492  break;
493 #endif /* CONFIG_RDFT */
494 #if CONFIG_DCT
495  case TRANSFORM_DCT:
496  ff_dct_end(&d);
497  break;
498 #endif /* CONFIG_DCT */
499 #endif /* FFT_FLOAT */
500  }
501 
502 cleanup:
503  av_free(tab);
504  av_free(tab1);
505  av_free(tab2);
506  av_free(tab_ref);
507  av_free(exptab);
508 
509  if (err)
510  printf("Error: %d.\n", err);
511 
512  return !!err;
513 }
Definition: lfg.h:25
av_cold void ff_rdft_end(RDFTContext *s)
Definition: rdft.c:130
void * av_malloc(size_t size)
Allocate a block of size bytes with alignment suitable for all memory accesses (including vectors if ...
Definition: mem.c:62
void(* dct_calc)(struct DCTContext *s, FFTSample *data)
Definition: dct.h:37
void(* mdct_calc)(struct FFTContext *s, FFTSample *output, const FFTSample *input)
Definition: fft.h:94
Definition: avfft.h:95
static struct @16 * exptab
void av_set_cpu_flags_mask(int mask)
Set a mask on flags returned by av_get_cpu_flags().
Definition: cpu.c:69
uint8_t pi<< 24) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_U8, uint8_t,(*(constuint8_t *) pi-0x80)*(1.0f/(1<< 7))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_U8, uint8_t,(*(constuint8_t *) pi-0x80)*(1.0/(1<< 7))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S16, int16_t,(*(constint16_t *) pi >>8)+0x80) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S16, int16_t,*(constint16_t *) pi *(1.0f/(1<< 15))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S16, int16_t,*(constint16_t *) pi *(1.0/(1<< 15))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S32, int32_t,(*(constint32_t *) pi >>24)+0x80) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S32, int32_t,*(constint32_t *) pi *(1.0f/(1U<< 31))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S32, int32_t,*(constint32_t *) pi *(1.0/(1U<< 31))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_FLT, float, av_clip_uint8(lrintf(*(constfloat *) pi *(1<< 7))+0x80)) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_FLT, float, av_clip_int16(lrintf(*(constfloat *) pi *(1<< 15)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_FLT, float, av_clipl_int32(llrintf(*(constfloat *) pi *(1U<< 31)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_DBL, double, av_clip_uint8(lrint(*(constdouble *) pi *(1<< 7))+0x80)) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_DBL, double, av_clip_int16(lrint(*(constdouble *) pi *(1<< 15)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_DBL, double, av_clipl_int32(llrint(*(constdouble *) pi *(1U<< 31))))#defineSET_CONV_FUNC_GROUP(ofmt, ifmt) staticvoidset_generic_function(AudioConvert *ac){}voidff_audio_convert_free(AudioConvert **ac){if(!*ac) return;ff_dither_free(&(*ac) ->dc);av_freep(ac);}AudioConvert *ff_audio_convert_alloc(AVAudioResampleContext *avr, enumAVSampleFormatout_fmt, enumAVSampleFormatin_fmt, intchannels, intsample_rate, intapply_map){AudioConvert *ac;intin_planar, out_planar;ac=av_mallocz(sizeof(*ac));if(!ac) returnNULL;ac->avr=avr;ac->out_fmt=out_fmt;ac->in_fmt=in_fmt;ac->channels=channels;ac->apply_map=apply_map;if(avr->dither_method!=AV_RESAMPLE_DITHER_NONE &&av_get_packed_sample_fmt(out_fmt)==AV_SAMPLE_FMT_S16 &&av_get_bytes_per_sample(in_fmt)>2){ac->dc=ff_dither_alloc(avr, out_fmt, in_fmt, channels, sample_rate, apply_map);if(!ac->dc){av_free(ac);returnNULL;}returnac;}in_planar=ff_sample_fmt_is_planar(in_fmt, channels);out_planar=ff_sample_fmt_is_planar(out_fmt, channels);if(in_planar==out_planar){ac->func_type=CONV_FUNC_TYPE_FLAT;ac->planes=in_planar?ac->channels:1;}elseif(in_planar) ac->func_type=CONV_FUNC_TYPE_INTERLEAVE;elseac->func_type=CONV_FUNC_TYPE_DEINTERLEAVE;set_generic_function(ac);if(ARCH_AARCH64) ff_audio_convert_init_aarch64(ac);if(ARCH_ARM) ff_audio_convert_init_arm(ac);if(ARCH_X86) ff_audio_convert_init_x86(ac);returnac;}intff_audio_convert(AudioConvert *ac, AudioData *out, AudioData *in){intuse_generic=1;intlen=in->nb_samples;intp;if(ac->dc){av_dlog(ac->avr,"%dsamples-audio_convert:%sto%s(dithered)\n", len, av_get_sample_fmt_name(ac->in_fmt), av_get_sample_fmt_name(ac->out_fmt));returnff_convert_dither(ac-> in
void(* fft_permute)(struct FFTContext *s, FFTComplex *z)
Do the permutation needed BEFORE calling fft_calc().
Definition: fft.h:86
FFTSample re
Definition: avfft.h:38
static int64_t duration
Definition: avplay.c:246
tf_transform
Definition: fft-test.c:224
static void fft_ref(FFTComplex *tabr, FFTComplex *tab, int nbits)
Definition: fft-test.c:91
int av_parse_cpu_flags(const char *s)
Parse CPU flags from a string.
Definition: cpu.c:75
static void help(void)
Definition: fft-test.c:210
#define r
Definition: input.c:51
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:123
void av_free(void *ptr)
Free a memory block which has been allocated with av_malloc(z)() or av_realloc(). ...
Definition: mem.c:186
#define AVERROR(e)
Definition: error.h:43
static FFTSample frandom(AVLFG *prng)
Definition: fft-test.c:185
void av_log(void *avcl, int level, const char *fmt,...)
Definition: log.c:169
Definition: avfft.h:73
#define ff_mdct_init
Definition: fft.h:151
float FFTSample
Definition: avfft.h:35
void(* rdft_calc)(struct RDFTContext *s, FFTSample *z)
Definition: rdft.h:60
void(* imdct_calc)(struct FFTContext *s, FFTSample *output, const FFTSample *input)
Definition: fft.h:92
Definition: fft.h:73
#define CMAC(pre, pim, are, aim, bre, bim)
Definition: fft-test.c:52
#define ff_fft_init
Definition: fft.h:132
Definition: dct.h:31
Definition: avfft.h:72
int64_t av_gettime(void)
Get the current time in microseconds.
Definition: time.c:37
#define REF_SCALE(x, bits)
Definition: fft-test.c:60
static const int8_t transform[32][32]
Definition: hevcdsp.c:25
NULL
Definition: eval.c:55
#define AV_LOG_INFO
Standard information.
Definition: log.h:134
float im
Definition: fft-test.c:69
static int getopt(int argc, char *argv[], char *opts)
Definition: getopt.c:41
static unsigned int av_lfg_get(AVLFG *c)
Get the next random unsigned 32-bit number using an ALFG.
Definition: lfg.h:38
const int16_t * tab1
Definition: mace.c:144
av_cold int ff_dct_init(DCTContext *s, int nbits, enum DCTTransformType inverse)
Set up DCT.
Definition: dct.c:177
av_cold void av_lfg_init(AVLFG *c, unsigned int seed)
Definition: lfg.c:30
#define FMT
Definition: fft-test.c:61
#define RANGE
Definition: fft-test.c:59
int main(int argc, char **argv)
Definition: fft-test.c:235
uint8_t pi<< 24) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_U8, uint8_t,(*(constuint8_t *) pi-0x80)*(1.0f/(1<< 7))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_U8, uint8_t,(*(constuint8_t *) pi-0x80)*(1.0/(1<< 7))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S16, int16_t,(*(constint16_t *) pi >>8)+0x80) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S16, int16_t,*(constint16_t *) pi *(1.0f/(1<< 15))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S16, int16_t,*(constint16_t *) pi *(1.0/(1<< 15))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S32, int32_t,(*(constint32_t *) pi >>24)+0x80) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S32, int32_t,*(constint32_t *) pi *(1.0f/(1U<< 31))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S32, int32_t,*(constint32_t *) pi *(1.0/(1U<< 31))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_FLT, float, av_clip_uint8(lrintf(*(constfloat *) pi *(1<< 7))+0x80)) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_FLT, float, av_clip_int16(lrintf(*(constfloat *) pi *(1<< 15)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_FLT, float, av_clipl_int32(llrintf(*(constfloat *) pi *(1U<< 31)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_DBL, double, av_clip_uint8(lrint(*(constdouble *) pi *(1<< 7))+0x80)) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_DBL, double, av_clip_int16(lrint(*(constdouble *) pi *(1<< 15)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_DBL, double, av_clipl_int32(llrint(*(constdouble *) pi *(1U<< 31))))#defineSET_CONV_FUNC_GROUP(ofmt, ifmt) staticvoidset_generic_function(AudioConvert *ac){}voidff_audio_convert_free(AudioConvert **ac){if(!*ac) return;ff_dither_free(&(*ac) ->dc);av_freep(ac);}AudioConvert *ff_audio_convert_alloc(AVAudioResampleContext *avr, enumAVSampleFormatout_fmt, enumAVSampleFormatin_fmt, intchannels, intsample_rate, intapply_map){AudioConvert *ac;intin_planar, out_planar;ac=av_mallocz(sizeof(*ac));if(!ac) returnNULL;ac->avr=avr;ac->out_fmt=out_fmt;ac->in_fmt=in_fmt;ac->channels=channels;ac->apply_map=apply_map;if(avr->dither_method!=AV_RESAMPLE_DITHER_NONE &&av_get_packed_sample_fmt(out_fmt)==AV_SAMPLE_FMT_S16 &&av_get_bytes_per_sample(in_fmt)>2){ac->dc=ff_dither_alloc(avr, out_fmt, in_fmt, channels, sample_rate, apply_map);if(!ac->dc){av_free(ac);returnNULL;}returnac;}in_planar=ff_sample_fmt_is_planar(in_fmt, channels);out_planar=ff_sample_fmt_is_planar(out_fmt, channels);if(in_planar==out_planar){ac->func_type=CONV_FUNC_TYPE_FLAT;ac->planes=in_planar?ac->channels:1;}elseif(in_planar) ac->func_type=CONV_FUNC_TYPE_INTERLEAVE;elseac->func_type=CONV_FUNC_TYPE_DEINTERLEAVE;set_generic_function(ac);if(ARCH_AARCH64) ff_audio_convert_init_aarch64(ac);if(ARCH_ARM) ff_audio_convert_init_arm(ac);if(ARCH_X86) ff_audio_convert_init_x86(ac);returnac;}intff_audio_convert(AudioConvert *ac, AudioData *out, AudioData *in){intuse_generic=1;intlen=in->nb_samples;intp;if(ac->dc){av_dlog(ac->avr,"%dsamples-audio_convert:%sto%s(dithered)\n", len, av_get_sample_fmt_name(ac->in_fmt), av_get_sample_fmt_name(ac->out_fmt));returnff_convert_dither(ac-> out
FFTSample im
Definition: avfft.h:38
#define ff_mdct_end
Definition: fft.h:152
#define ff_fft_end
Definition: fft.h:133
void(* fft_calc)(struct FFTContext *s, FFTComplex *z)
Do a complex FFT with the parameters defined in ff_fft_init().
Definition: fft.h:91
Definition: avfft.h:94
static char * optarg
Definition: getopt.c:39
static int check_diff(FFTSample *tab1, FFTSample *tab2, int n, double scale)
Definition: fft-test.c:190
float re
Definition: fft-test.c:69
av_cold void ff_dct_end(DCTContext *s)
Definition: dct.c:218
static const struct twinvq_data tab
static int fft_ref_init(int nbits, int inverse)
Definition: fft-test.c:72
static uint32_t inverse(uint32_t v)
find multiplicative inverse modulo 2 ^ 32
Definition: asfcrypt.c:35
av_cold int ff_rdft_init(RDFTContext *s, int nbits, enum RDFTransformType trans)
Set up a real FFT.
Definition: rdft.c:99
const int16_t * tab2
Definition: mace.c:144