blob: 54f2eb99a1614478be642e95b7b1c2949ada068f [file] [log] [blame]
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.