1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150
|
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.
|