Nsound  0.9.4
Functions | Variables
FFTransform_UnitTest.cc File Reference
#include <Nsound/Buffer.h>
#include <Nsound/Cosine.h>
#include <Nsound/FFTransform.h>
#include <Nsound/Plotter.h>
#include <Nsound/Sine.h>
#include <Nsound/Wavefile.h>
#include "UnitTest.h"
#include <stdlib.h>
#include <iostream>
Include dependency graph for FFTransform_UnitTest.cc:

Go to the source code of this file.

Functions

void FFTransform_UnitTest ()
 

Variables

static const char * THIS_FILE = "FFTransform_UnitTest.cc"
 
static const float64 GAMMA = 1.0e-11
 

Function Documentation

void FFTransform_UnitTest ( )

Definition at line 53 of file FFTransform_UnitTest.cc.

References Nsound::Buffer::abs(), Nsound::Generator::buzz(), Nsound::FFTransform::fft(), GAMMA, Nsound::Buffer::getAbs(), Nsound::FFTChunk::getImaginary(), Nsound::Buffer::getLength(), Nsound::Buffer::getMax(), Nsound::FFTChunk::getReal(), Nsound::FFTransform::ifft(), M_PI, Nsound::Buffer::plot(), Nsound::FFTChunk::setCartesian(), Nsound::Wavefile::setDefaultSampleSize(), Nsound::Wavefile::setIEEEFloat(), Nsound::FFTChunk::setPolar(), Nsound::Plotter::show(), SUCCESS, TEST_ERROR_HEADER, TEST_HEADER, and THIS_FILE.

Referenced by main().

54 {
55  cout << endl << THIS_FILE;
56 
57  Wavefile::setDefaultSampleSize(64);
58  Wavefile::setIEEEFloat(true);
59 
60  Cosine cos(512);
61 
62  Buffer input = cos.buzz(1.0, 8.0, 2.0, 0.0);
63 
64  FFTransform fft(512);
65 
66  FFTChunkVector vec;
67 
68  Buffer gold;
69 
70  cout << TEST_HEADER << "Testing FFTransform::fft(), ifft() ..." << flush;
71 
72  vec = fft.fft(input, 128, 0);
73 
74  if(vec.size() != 512 / 128)
75  {
76  cerr << TEST_ERROR_HEADER
77  << "Output did not match!"
78  << endl
79  << "vec.size() = " << vec.size() << " != " << 512 / 128
80  << endl;
81 
82  exit(1);
83  }
84 
85  Buffer data = fft.ifft(vec);
86 
87 //~ input.plot("input");
88 //~ data.plot("fft,ifft");
89 
90  if(data.getLength() != input.getLength())
91  {
92  cerr << TEST_ERROR_HEADER
93  << "Output did not match!"
94  << endl
95  << "result.getLength() = " << data.getLength() << " != "
96  << input.getLength()
97  << endl;
98 
99  exit(1);
100  }
101 
102  // Create gold file
103 //~ data >> "gold/FFTransform_out1.wav";
104 
105  gold = Buffer("gold/FFTransform_out1.wav");
106 
107  Buffer diff = data - gold;
108 
109  if(diff.getAbs().getMax() > GAMMA)
110  {
111  cerr << TEST_ERROR_HEADER
112  << "Output did not match gold file!"
113  << endl;
114 
115  diff.plot("input - gold");
116  data.plot("data");
117  gold.plot("gold");
118 
119  Plotter::show();
120  exit(1);
121  }
122 
123  cout << SUCCESS;
124 
125  cout << TEST_HEADER << "Testing FFTChunk::getReal(), getImaginary() ..." << flush;
126 
127  vec = fft.fft(input, 128, 0);
128 
129  Buffer real = vec[0].getReal();
130  Buffer img = vec[0].getImaginary();
131 
132  // Create gold files.
133 //~ real >> "gold/FFTransform_out2.wav";
134 //~ img >> "gold/FFTransform_out3.wav";
135 
136  gold = Buffer("gold/FFTransform_out2.wav");
137 
138  diff = real - gold;
139  diff.abs();
140  if(diff.getMax() > GAMMA)
141  {
142  cerr << TEST_ERROR_HEADER
143  << "Output did not match gold file!"
144  << endl;
145 
146  diff.plot("real - gold");
147  real.plot("real");
148  gold.plot("gold");
149 
150  Plotter::show();
151  exit(1);
152  }
153 
154  gold = Buffer("gold/FFTransform_out3.wav");
155 
156  diff = img - gold;
157  diff.abs();
158 
159  if(diff.getMax() > GAMMA)
160  {
161  cerr << TEST_ERROR_HEADER
162  << "Output did not match gold file!"
163  << endl;
164 
165  diff.plot("img - gold");
166  img.plot("img");
167  gold.plot("gold");
168 
169  Plotter::show();
170  exit(1);
171  }
172 
173  cout << SUCCESS;
174 
175  cout << TEST_HEADER << "Testing FFTChunk::getMagnitude(), getPhase() ..." << flush;
176 
177  vec = fft.fft(input, 128, 0);
178 
179  Buffer mag = vec[0].getMagnitude();
180  Buffer phase = vec[0].getPhase();
181 
182  // Create gold files.
183 //~ mag >> "gold/FFTransform_out4.wav";
184 //~ phase >> "gold/FFTransform_out5.wav";
185 
186  gold = Buffer("gold/FFTransform_out4.wav");
187 
188  diff = mag - gold;
189 
190  if(diff.getAbs().getMax() > GAMMA)
191  {
192  cerr << TEST_ERROR_HEADER
193  << "Output did not match gold file!"
194  << endl;
195 
196  diff.plot("data - gold");
197  mag.plot("data");
198  gold.plot("gold");
199 
200  Plotter::show();
201  exit(1);
202  }
203 
204  gold = Buffer("gold/FFTransform_out5.wav");
205 
206  diff = phase - gold;
207 
208  diff(diff > 2.0 * M_PI - 0.01) = 0.0;
209  diff(diff < 2.0 * M_PI - 0.01) = 0.0;
210 
211  if(diff.getAbs().getMax() > GAMMA)
212  {
213  cerr << TEST_ERROR_HEADER
214  << "Output did not match gold file!"
215  << endl;
216 
217  diff.plot("phase - gold");
218  phase.plot("phase");
219  gold.plot("gold");
220 
221  Plotter::show();
222  exit(1);
223  }
224 
225  cout << SUCCESS;
226 
227  cout << TEST_HEADER << "Testing FFTChunk::toCartesian(), toPolar() ..." << flush;
228 
229  vec[0].toPolar();
230 
231  mag = vec[0].getMagnitude();
232  phase = vec[0].getPhase();
233 
234  gold = Buffer("gold/FFTransform_out4.wav");
235 
236  diff = mag - gold;
237 
238  if(diff.getAbs().getMax() > GAMMA)
239  {
240  cerr << TEST_ERROR_HEADER
241  << "Output did not match gold file!"
242  << endl;
243 
244  diff.plot("data - gold");
245  mag.plot("data");
246  gold.plot("gold");
247 
248  Plotter::show();
249  exit(1);
250  }
251 
252  gold = Buffer("gold/FFTransform_out5.wav");
253 
254  diff = phase - gold;
255  diff.abs();
256  if(diff.getMax() > 2*M_PI)
257  {
258  cerr << TEST_ERROR_HEADER
259  << "Output did not match gold file!"
260  << endl;
261 
262  diff.plot("phase - gold");
263  phase.plot("phase");
264  gold.plot("gold");
265 
266  Plotter::show();
267  exit(1);
268  }
269 
270  cout << SUCCESS;
271 
272  cout << TEST_HEADER << "Testing FFTChunk::setCartesian(), setPolar() ..." << flush;
273 
274  vec = fft.fft(input, 512, 0);
275 
276  mag = vec[0].getMagnitude();
277  phase = vec[0].getPhase();
278 
279  FFTChunk orig(vec[0]);
280  FFTChunk chunk(512, 512);
281 
282  chunk.setPolar(mag, phase);
283 
284  vec[0] = chunk;
285 
286  data = fft.ifft(vec);
287 
288  diff = data - input;
289 
290  if(diff.getAbs().getMax() > 0.005)
291  {
292  cerr << TEST_ERROR_HEADER
293  << "Output did not match gold file!"
294  << endl;
295 
296  diff.plot("data - gold");
297  data.plot("data");
298  input.plot("gold");
299 
300  Plotter::show();
301  exit(1);
302  }
303 
304  chunk.setCartesian(orig.getReal(), orig.getImaginary());
305 
306  vec[0] = chunk;
307 
308  data = fft.ifft(vec);
309 
310  diff = data - input;
311 
312  if(diff.getAbs().getMax() > 2*GAMMA)
313  {
314  cerr << TEST_ERROR_HEADER
315  << "Output did not match gold file!"
316  << endl;
317 
318  diff.plot("data - gold");
319  data.plot("data");
320  input.plot("gold");
321 
322  Plotter::show();
323  exit(1);
324  }
325 
326  cout << SUCCESS;
327 
328  cout << TEST_HEADER << "Testing FFTChunk::getFrequencyAxis() ..." << flush;
329 
330  data = vec[0].getFrequencyAxis();
331 
332 //~ // Create gold files.
333 //~ data >> "gold/FFTransform_out6.wav";
334 
335  gold = Buffer("gold/FFTransform_out6.wav");
336 
337  diff = data - gold;
338 
339  if(diff.getAbs().getMax() > 1e-16)
340  {
341  cerr << TEST_ERROR_HEADER
342  << "Output did not match gold file!"
343  << endl;
344 
345  diff.plot("data - gold");
346  data.plot("data");
347  gold.plot("gold");
348 
349  Plotter::show();
350  exit(1);
351  }
352 
353  cout << SUCCESS << endl;
354 }
Results of performing an FFT are stored in this class.
Definition: FFTChunk.h:49
#define M_PI
Definition: Nsound.h:121
DOXME.
Definition: Cosine.h:44
void plot(const std::string &title="Buffer") const
Requires matplotlib. Creates a plot of this Buffer.
Definition: Buffer.cc:1551
#define TEST_HEADER
Definition: Test.h:45
static const char * THIS_FILE
Buffer getAbs() const
Modifies a copy of the Buffer by making any negative value positive.
Definition: Buffer.h:174
uint32 getLength() const
Returns the number of samples in the Buffer.
Definition: Buffer.h:587
#define TEST_ERROR_HEADER
Definition: Test.h:49
void abs()
Modifies the Buffer by making any negative value positive.
Definition: Buffer.cc:119
A Class that performes the Fast Fouier Transfrom on a Buffer.
Definition: FFTransform.h:57
#define SUCCESS
Definition: UnitTest.h:42
A Buffer for storing audio samples.
Definition: Buffer.h:60
static const float64 GAMMA
float64 getMax() const
Returns the maximum sample value in the Buffer.
Definition: Buffer.cc:951
std::vector< FFTChunk > FFTChunkVector
Definition: FFTChunk.h:119

Variable Documentation

const char* THIS_FILE = "FFTransform_UnitTest.cc"
static

Definition at line 48 of file FFTransform_UnitTest.cc.

Referenced by FFTransform_UnitTest().

const float64 GAMMA = 1.0e-11
static

Definition at line 50 of file FFTransform_UnitTest.cc.

Referenced by FFTransform_UnitTest().