program testapp; {$APPTYPE CONSOLE} uses SysUtils, fftreal in 'fftreal.pas', Math, Windows; var nbr_points : longint; x, f : pflt_array; fft : TFFTReal; i : longint; PI : double; areal, img : double; f_abs : double; buffer_size : longint; nbr_tests : longint; time0, time1, time2 : int64; timereso : int64; offset : longint; t0, t1 : double; nbr_s_chn : longint; tempp1, tempp2 : pflt_array; begin (*______________________________________________ * * Exactness test *______________________________________________ *) WriteLn('Accuracy test:'); WriteLn; nbr_points := 16; // Power of 2 GetMem(x, nbr_points * sizeof_flt); GetMem(f, nbr_points * sizeof_flt); fft := TFFTReal.Create(nbr_points); // FFT object initialized here // Test signal PI := ArcTan(1) * 4; for i := 0 to nbr_points-1 do begin x^[i] := -1 + sin (3*2*PI*i/nbr_points) + cos (5*2*PI*i/nbr_points) * 2 - sin (7*2*PI*i/nbr_points) * 3 + cos (8*2*PI*i/nbr_points) * 5; end; // Compute FFT and IFFT fft.do_fft(f, x); fft.do_ifft(f, x); fft.rescale(x); // Display the result WriteLn('FFT:'); for i := 0 to nbr_points div 2 do begin areal := f^[i]; if (i > 0) and (i < nbr_points div 2) then img := f^[i + nbr_points div 2] else img := 0; f_abs := Sqrt(areal * areal + img * img); WriteLn(Format('%5d: %12.6f %12.6f (%12.6f)', [i, areal, img, f_abs])); end; WriteLn; WriteLn('IFFT:'); for i := 0 to nbr_points-1 do WriteLn(Format('%5d: %f', [i, x^[i]])); WriteLn; FreeMem(x); FreeMem(f); fft.Free; (*______________________________________________ * * Speed test *______________________________________________ *) WriteLn('Speed test:'); WriteLn('Please wait...'); WriteLn; nbr_points := 1024; // Power of 2 buffer_size := 256*nbr_points; // Number of flt_t (float or double) nbr_tests := 10000; assert(nbr_points <= buffer_size); GetMem(x, buffer_size * sizeof_flt); GetMem(f, buffer_size * sizeof_flt); fft := TFFTReal.Create(nbr_points); // FFT object initialized here // Test signal: noise for i := 0 to nbr_points-1 do x^[i] := Random($7fff) - ($7fff shr 1); // timing QueryPerformanceFrequency(timereso); QueryPerformanceCounter(time0); for i := 0 to nbr_tests-1 do begin offset := (i * nbr_points) and (buffer_size - 1); tempp1 := f; inc(tempp1, offset); tempp2 := x; inc(tempp2, offset); fft.do_fft(tempp1, tempp2); end; QueryPerformanceCounter(time1); for i := 0 to nbr_tests-1 do begin offset := (i * nbr_points) and (buffer_size - 1); tempp1 := f; inc(tempp1, offset); tempp2 := x; inc(tempp2, offset); fft.do_ifft(tempp1, tempp2); fft.rescale(x); end; QueryPerformanceCounter(time2); t0 := ((time1-time0) / timereso) / nbr_tests; t1 := ((time2-time1) / timereso) / nbr_tests; WriteLn(Format('%d-points FFT : %.0f us.', [nbr_points, t0 * 1000000])); WriteLn(Format('%d-points IFFT + scaling: %.0f us.', [nbr_points, t1 * 1000000])); nbr_s_chn := Floor(nbr_points / ((t0 + t1) * 44100 * 2)); WriteLn(Format('Peak performance: FFT+IFFT on %d mono channels at 44.1 KHz (with overlapping)', [nbr_s_chn])); WriteLn; FreeMem(x); FreeMem(f); fft.Free; WriteLn('Press [Return] key to terminate...'); ReadLn; end.