|
1 program testapp; |
|
2 {$APPTYPE CONSOLE} |
|
3 uses |
|
4 SysUtils, |
|
5 fftreal in 'fftreal.pas', |
|
6 Math, |
|
7 Windows; |
|
8 |
|
9 var |
|
10 nbr_points : longint; |
|
11 x, f : pflt_array; |
|
12 fft : TFFTReal; |
|
13 i : longint; |
|
14 PI : double; |
|
15 areal, img : double; |
|
16 f_abs : double; |
|
17 buffer_size : longint; |
|
18 nbr_tests : longint; |
|
19 time0, time1, time2 : int64; |
|
20 timereso : int64; |
|
21 offset : longint; |
|
22 t0, t1 : double; |
|
23 nbr_s_chn : longint; |
|
24 tempp1, tempp2 : pflt_array; |
|
25 |
|
26 begin |
|
27 (*______________________________________________ |
|
28 * |
|
29 * Exactness test |
|
30 *______________________________________________ |
|
31 *) |
|
32 |
|
33 WriteLn('Accuracy test:'); |
|
34 WriteLn; |
|
35 |
|
36 nbr_points := 16; // Power of 2 |
|
37 GetMem(x, nbr_points * sizeof_flt); |
|
38 GetMem(f, nbr_points * sizeof_flt); |
|
39 fft := TFFTReal.Create(nbr_points); // FFT object initialized here |
|
40 |
|
41 // Test signal |
|
42 PI := ArcTan(1) * 4; |
|
43 for i := 0 to nbr_points-1 do |
|
44 begin |
|
45 x^[i] := -1 + sin (3*2*PI*i/nbr_points) |
|
46 + cos (5*2*PI*i/nbr_points) * 2 |
|
47 - sin (7*2*PI*i/nbr_points) * 3 |
|
48 + cos (8*2*PI*i/nbr_points) * 5; |
|
49 end; |
|
50 |
|
51 // Compute FFT and IFFT |
|
52 fft.do_fft(f, x); |
|
53 fft.do_ifft(f, x); |
|
54 fft.rescale(x); |
|
55 |
|
56 // Display the result |
|
57 WriteLn('FFT:'); |
|
58 for i := 0 to nbr_points div 2 do |
|
59 begin |
|
60 areal := f^[i]; |
|
61 if (i > 0) and (i < nbr_points div 2) then |
|
62 img := f^[i + nbr_points div 2] |
|
63 else |
|
64 img := 0; |
|
65 |
|
66 f_abs := Sqrt(areal * areal + img * img); |
|
67 WriteLn(Format('%5d: %12.6f %12.6f (%12.6f)', [i, areal, img, f_abs])); |
|
68 end; |
|
69 |
|
70 WriteLn; |
|
71 WriteLn('IFFT:'); |
|
72 for i := 0 to nbr_points-1 do |
|
73 WriteLn(Format('%5d: %f', [i, x^[i]])); |
|
74 |
|
75 WriteLn; |
|
76 |
|
77 FreeMem(x); |
|
78 FreeMem(f); |
|
79 fft.Free; |
|
80 |
|
81 |
|
82 (*______________________________________________ |
|
83 * |
|
84 * Speed test |
|
85 *______________________________________________ |
|
86 *) |
|
87 |
|
88 WriteLn('Speed test:'); |
|
89 WriteLn('Please wait...'); |
|
90 WriteLn; |
|
91 |
|
92 nbr_points := 1024; // Power of 2 |
|
93 buffer_size := 256*nbr_points; // Number of flt_t (float or double) |
|
94 nbr_tests := 10000; |
|
95 |
|
96 assert(nbr_points <= buffer_size); |
|
97 GetMem(x, buffer_size * sizeof_flt); |
|
98 GetMem(f, buffer_size * sizeof_flt); |
|
99 fft := TFFTReal.Create(nbr_points); // FFT object initialized here |
|
100 |
|
101 // Test signal: noise |
|
102 for i := 0 to nbr_points-1 do |
|
103 x^[i] := Random($7fff) - ($7fff shr 1); |
|
104 |
|
105 // timing |
|
106 QueryPerformanceFrequency(timereso); |
|
107 QueryPerformanceCounter(time0); |
|
108 |
|
109 for i := 0 to nbr_tests-1 do |
|
110 begin |
|
111 offset := (i * nbr_points) and (buffer_size - 1); |
|
112 tempp1 := f; |
|
113 inc(tempp1, offset); |
|
114 tempp2 := x; |
|
115 inc(tempp2, offset); |
|
116 fft.do_fft(tempp1, tempp2); |
|
117 end; |
|
118 |
|
119 QueryPerformanceCounter(time1); |
|
120 |
|
121 for i := 0 to nbr_tests-1 do |
|
122 begin |
|
123 offset := (i * nbr_points) and (buffer_size - 1); |
|
124 tempp1 := f; |
|
125 inc(tempp1, offset); |
|
126 tempp2 := x; |
|
127 inc(tempp2, offset); |
|
128 fft.do_ifft(tempp1, tempp2); |
|
129 fft.rescale(x); |
|
130 end; |
|
131 |
|
132 QueryPerformanceCounter(time2); |
|
133 |
|
134 t0 := ((time1-time0) / timereso) / nbr_tests; |
|
135 t1 := ((time2-time1) / timereso) / nbr_tests; |
|
136 |
|
137 WriteLn(Format('%d-points FFT : %.0f us.', [nbr_points, t0 * 1000000])); |
|
138 WriteLn(Format('%d-points IFFT + scaling: %.0f us.', [nbr_points, t1 * 1000000])); |
|
139 |
|
140 nbr_s_chn := Floor(nbr_points / ((t0 + t1) * 44100 * 2)); |
|
141 WriteLn(Format('Peak performance: FFT+IFFT on %d mono channels at 44.1 KHz (with overlapping)', [nbr_s_chn])); |
|
142 WriteLn; |
|
143 |
|
144 FreeMem(x); |
|
145 FreeMem(f); |
|
146 fft.Free; |
|
147 |
|
148 WriteLn('Press [Return] key to terminate...'); |
|
149 ReadLn; |
|
150 end. |