Mercurial > libavcodec.hg
comparison fft-test.c @ 10847:177ebc61c3d6 libavcodec
fft-test: Add RDFT/IRDFT support.
author | alexc |
---|---|
date | Mon, 11 Jan 2010 16:41:03 +0000 |
parents | 8dbceaa5fa2f |
children | 0985f1f7ab72 |
comparison
equal
deleted
inserted
replaced
10846:8dbceaa5fa2f | 10847:177ebc61c3d6 |
---|---|
174 } | 174 } |
175 | 175 |
176 enum tf_transform { | 176 enum tf_transform { |
177 TRANSFORM_FFT, | 177 TRANSFORM_FFT, |
178 TRANSFORM_MDCT, | 178 TRANSFORM_MDCT, |
179 TRANSFORM_RDFT, | |
179 }; | 180 }; |
180 | 181 |
181 int main(int argc, char **argv) | 182 int main(int argc, char **argv) |
182 { | 183 { |
183 FFTComplex *tab, *tab1, *tab_ref; | 184 FFTComplex *tab, *tab1, *tab_ref; |
186 int do_speed = 0; | 187 int do_speed = 0; |
187 enum tf_transform transform = TRANSFORM_FFT; | 188 enum tf_transform transform = TRANSFORM_FFT; |
188 int do_inverse = 0; | 189 int do_inverse = 0; |
189 FFTContext s1, *s = &s1; | 190 FFTContext s1, *s = &s1; |
190 FFTContext m1, *m = &m1; | 191 FFTContext m1, *m = &m1; |
191 int fft_nbits, fft_size; | 192 RDFTContext r1, *r = &r1; |
193 int fft_nbits, fft_size, fft_size_2; | |
192 double scale = 1.0; | 194 double scale = 1.0; |
193 AVLFG prng; | 195 AVLFG prng; |
194 av_lfg_init(&prng, 1); | 196 av_lfg_init(&prng, 1); |
195 | 197 |
196 fft_nbits = 9; | 198 fft_nbits = 9; |
197 for(;;) { | 199 for(;;) { |
198 c = getopt(argc, argv, "hsimn:f:"); | 200 c = getopt(argc, argv, "hsimrn:f:"); |
199 if (c == -1) | 201 if (c == -1) |
200 break; | 202 break; |
201 switch(c) { | 203 switch(c) { |
202 case 'h': | 204 case 'h': |
203 help(); | 205 help(); |
209 do_inverse = 1; | 211 do_inverse = 1; |
210 break; | 212 break; |
211 case 'm': | 213 case 'm': |
212 transform = TRANSFORM_MDCT; | 214 transform = TRANSFORM_MDCT; |
213 break; | 215 break; |
216 case 'r': | |
217 transform = TRANSFORM_RDFT; | |
218 break; | |
214 case 'n': | 219 case 'n': |
215 fft_nbits = atoi(optarg); | 220 fft_nbits = atoi(optarg); |
216 break; | 221 break; |
217 case 'f': | 222 case 'f': |
218 scale = atof(optarg); | 223 scale = atof(optarg); |
219 break; | 224 break; |
220 } | 225 } |
221 } | 226 } |
222 | 227 |
223 fft_size = 1 << fft_nbits; | 228 fft_size = 1 << fft_nbits; |
229 fft_size_2 = fft_size >> 1; | |
224 tab = av_malloc(fft_size * sizeof(FFTComplex)); | 230 tab = av_malloc(fft_size * sizeof(FFTComplex)); |
225 tab1 = av_malloc(fft_size * sizeof(FFTComplex)); | 231 tab1 = av_malloc(fft_size * sizeof(FFTComplex)); |
226 tab_ref = av_malloc(fft_size * sizeof(FFTComplex)); | 232 tab_ref = av_malloc(fft_size * sizeof(FFTComplex)); |
227 tab2 = av_malloc(fft_size * sizeof(FFTSample)); | 233 tab2 = av_malloc(fft_size * sizeof(FFTSample)); |
228 | 234 |
241 else | 247 else |
242 av_log(NULL, AV_LOG_INFO,"FFT"); | 248 av_log(NULL, AV_LOG_INFO,"FFT"); |
243 ff_fft_init(s, fft_nbits, do_inverse); | 249 ff_fft_init(s, fft_nbits, do_inverse); |
244 fft_ref_init(fft_nbits, do_inverse); | 250 fft_ref_init(fft_nbits, do_inverse); |
245 break; | 251 break; |
252 case TRANSFORM_RDFT: | |
253 if (do_inverse) | |
254 av_log(NULL, AV_LOG_INFO,"IRDFT"); | |
255 else | |
256 av_log(NULL, AV_LOG_INFO,"RDFT"); | |
257 ff_rdft_init(r, fft_nbits, do_inverse ? IRDFT : RDFT); | |
258 fft_ref_init(fft_nbits, do_inverse); | |
259 break; | |
246 } | 260 } |
247 av_log(NULL, AV_LOG_INFO," %d test\n", fft_size); | 261 av_log(NULL, AV_LOG_INFO," %d test\n", fft_size); |
248 | 262 |
249 /* generate random data */ | 263 /* generate random data */ |
250 | 264 |
276 ff_fft_calc(s, tab); | 290 ff_fft_calc(s, tab); |
277 | 291 |
278 fft_ref(tab_ref, tab1, fft_nbits); | 292 fft_ref(tab_ref, tab1, fft_nbits); |
279 check_diff((float *)tab_ref, (float *)tab, fft_size * 2, 1.0); | 293 check_diff((float *)tab_ref, (float *)tab, fft_size * 2, 1.0); |
280 break; | 294 break; |
295 case TRANSFORM_RDFT: | |
296 if (do_inverse) { | |
297 tab1[ 0].im = 0; | |
298 tab1[fft_size_2].im = 0; | |
299 for (i = 1; i < fft_size_2; i++) { | |
300 tab1[fft_size_2+i].re = tab1[fft_size_2-i].re; | |
301 tab1[fft_size_2+i].im = -tab1[fft_size_2-i].im; | |
302 } | |
303 | |
304 memcpy(tab2, tab1, fft_size * sizeof(FFTSample)); | |
305 tab2[1] = tab1[fft_size_2].re; | |
306 | |
307 ff_rdft_calc(r, tab2); | |
308 fft_ref(tab_ref, tab1, fft_nbits); | |
309 for (i = 0; i < fft_size; i++) { | |
310 tab[i].re = tab2[i]; | |
311 tab[i].im = 0; | |
312 } | |
313 check_diff((float *)tab_ref, (float *)tab, fft_size * 2, 0.5); | |
314 } else { | |
315 for (i = 0; i < fft_size; i++) { | |
316 tab2[i] = tab1[i].re; | |
317 tab1[i].im = 0; | |
318 } | |
319 ff_rdft_calc(r, tab2); | |
320 fft_ref(tab_ref, tab1, fft_nbits); | |
321 tab_ref[0].im = tab_ref[fft_size_2].re; | |
322 check_diff((float *)tab_ref, (float *)tab2, fft_size, 1.0); | |
323 } | |
281 } | 324 } |
282 | 325 |
283 /* do a speed test */ | 326 /* do a speed test */ |
284 | 327 |
285 if (do_speed) { | 328 if (do_speed) { |
302 break; | 345 break; |
303 case TRANSFORM_FFT: | 346 case TRANSFORM_FFT: |
304 memcpy(tab, tab1, fft_size * sizeof(FFTComplex)); | 347 memcpy(tab, tab1, fft_size * sizeof(FFTComplex)); |
305 ff_fft_calc(s, tab); | 348 ff_fft_calc(s, tab); |
306 break; | 349 break; |
350 case TRANSFORM_RDFT: | |
351 memcpy(tab2, tab1, fft_size * sizeof(FFTSample)); | |
352 ff_rdft_calc(r, tab2); | |
353 break; | |
307 } | 354 } |
308 } | 355 } |
309 duration = gettime() - time_start; | 356 duration = gettime() - time_start; |
310 if (duration >= 1000000) | 357 if (duration >= 1000000) |
311 break; | 358 break; |
322 ff_mdct_end(m); | 369 ff_mdct_end(m); |
323 break; | 370 break; |
324 case TRANSFORM_FFT: | 371 case TRANSFORM_FFT: |
325 ff_fft_end(s); | 372 ff_fft_end(s); |
326 break; | 373 break; |
374 case TRANSFORM_RDFT: | |
375 ff_rdft_end(r); | |
376 break; | |
327 } | 377 } |
328 return 0; | 378 return 0; |
329 } | 379 } |