FFmpeg
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
avfft.c
Go to the documentation of this file.
1 /*
2  * This file is part of FFmpeg.
3  *
4  * FFmpeg is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * FFmpeg is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with FFmpeg; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17  */
18 
19 #include "libavutil/attributes.h"
20 #include "libavutil/mem.h"
21 #include "avfft.h"
22 #include "fft.h"
23 #include "rdft.h"
24 #include "dct.h"
25 
26 /* FFT */
27 
28 FFTContext *av_fft_init(int nbits, int inverse)
29 {
30  FFTContext *s = av_mallocz(sizeof(*s));
31 
32  if (s && ff_fft_init(s, nbits, inverse))
33  av_freep(&s);
34 
35  return s;
36 }
37 
39 {
40  s->fft_permute(s, z);
41 }
42 
44 {
45  s->fft_calc(s, z);
46 }
47 
49 {
50  if (s) {
51  ff_fft_end(s);
52  av_free(s);
53  }
54 }
55 
56 #if CONFIG_MDCT
57 
58 FFTContext *av_mdct_init(int nbits, int inverse, double scale)
59 {
60  FFTContext *s = av_malloc(sizeof(*s));
61 
62  if (s && ff_mdct_init(s, nbits, inverse, scale))
63  av_freep(&s);
64 
65  return s;
66 }
67 
68 void av_imdct_calc(FFTContext *s, FFTSample *output, const FFTSample *input)
69 {
70  s->imdct_calc(s, output, input);
71 }
72 
73 void av_imdct_half(FFTContext *s, FFTSample *output, const FFTSample *input)
74 {
75  s->imdct_half(s, output, input);
76 }
77 
78 void av_mdct_calc(FFTContext *s, FFTSample *output, const FFTSample *input)
79 {
80  s->mdct_calc(s, output, input);
81 }
82 
84 {
85  if (s) {
86  ff_mdct_end(s);
87  av_free(s);
88  }
89 }
90 
91 #endif /* CONFIG_MDCT */
92 
93 #if CONFIG_RDFT
94 
95 RDFTContext *av_rdft_init(int nbits, enum RDFTransformType trans)
96 {
97  RDFTContext *s = av_malloc(sizeof(*s));
98 
99  if (s && ff_rdft_init(s, nbits, trans))
100  av_freep(&s);
101 
102  return s;
103 }
104 
106 {
107  s->rdft_calc(s, data);
108 }
109 
111 {
112  if (s) {
113  ff_rdft_end(s);
114  av_free(s);
115  }
116 }
117 
118 #endif /* CONFIG_RDFT */
119 
120 #if CONFIG_DCT
121 
122 DCTContext *av_dct_init(int nbits, enum DCTTransformType inverse)
123 {
124  DCTContext *s = av_malloc(sizeof(*s));
125 
126  if (s && ff_dct_init(s, nbits, inverse))
127  av_freep(&s);
128 
129  return s;
130 }
131 
132 void av_dct_calc(DCTContext *s, FFTSample *data)
133 {
134  s->dct_calc(s, data);
135 }
136 
138 {
139  if (s) {
140  ff_dct_end(s);
141  av_free(s);
142  }
143 }
144 
145 #ifdef TEST
146 int main(int argc, char **argv)
147 {
148  int i;
149 #define LEN 1024
150  FFTSample *ref = av_malloc_array(LEN, sizeof(*ref));
151  FFTSample *data = av_malloc_array(LEN, sizeof(*data));
152  RDFTContext *rdft_context = av_rdft_init(10, DFT_R2C);
153  RDFTContext *irdft_context = av_rdft_init(10, IDFT_C2R);
154 
155  if (!ref || !data || !rdft_context || !irdft_context)
156  return 2;
157  for (i=0; i<LEN; i++) {
158  ref[i] = data[i] = i*456 + 123 + i*i;
159  }
160  av_rdft_calc(rdft_context, data);
161  av_rdft_calc(irdft_context, data);
162 
163  for (i=0; i<LEN; i++) {
164  if (fabs(ref[i] - data[i]/LEN*2) > 1) {
165  fprintf(stderr, "Failed at %d (%f %f)\n", i, ref[i], data[i]/LEN*2);
166  return 1;
167  }
168  }
169 
170  av_rdft_end(rdft_context);
171  av_rdft_end(irdft_context);
172  av_free(data);
173  av_free(ref);
174 
175  return 0;
176 }
177 #endif
178 
179 #endif /* CONFIG_DCT */