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 }