Nsound  0.9.4
Generator_UnitTest.cc
Go to the documentation of this file.
1 //-----------------------------------------------------------------------------
2 //
3 // $Id: Generator_UnitTest.cc 874 2014-09-08 02:21:29Z weegreenblobbie $
4 //
5 // Copyright (c) 2008 Nick Hilton
6 //
7 // weegreenblobbie_yahoo_com (replace '_' with '@' and '.')
8 //
9 //-----------------------------------------------------------------------------
10 
11 //-----------------------------------------------------------------------------
12 //
13 // This program is free software; you can redistribute it and/or modify
14 // it under the terms of the GNU General Public License as published by
15 // the Free Software Foundation; either version 2 of the License, or
16 // (at your option) any later version.
17 //
18 // This program is distributed in the hope that it will be useful,
19 // but WITHOUT ANY WARRANTY; without even the implied warranty of
20 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 // GNU Library General Public License for more details.
22 //
23 // You should have received a copy of the GNU General Public License
24 // along with this program; if not, write to the Free Software
25 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
26 //
27 //-----------------------------------------------------------------------------
28 
29 #include <Nsound/Buffer.h>
30 #include <Nsound/Cosine.h>
31 #include <Nsound/Plotter.h>
32 #include <Nsound/Sine.h>
33 #include <Nsound/Wavefile.h>
34 
35 #include "UnitTest.h"
36 
37 #include <cmath>
38 #include <stdlib.h>
39 #include <iostream>
40 
41 using namespace Nsound;
42 
43 using std::cerr;
44 using std::cout;
45 using std::endl;
46 
47 // The __FILE__ macro includes the path, I don't want the whole path.
48 static const char * THIS_FILE = "Generator_UnitTest.cc";
49 
50 static const float64 GAMMA = 8e-7;
51 
53 {
54  cout << endl << THIS_FILE;
55 
58 
59  Generator gen(100);
60  Cosine cos(100);
61 
62  // Test 7 Hz wave
63  cout << TEST_HEADER << "Testing Generator::drawLine(1.0, 1.0, 0.0) ...";
64 
65  Buffer data = gen.drawLine(1.0, 1.0, 0.0);
66 
67  // Create the gold file
68 //~ data >> "gold/Generator_line1.wav";
69 
70  Buffer gold;
71 
72  gold << "gold/Generator_line1.wav";
73 
74  Buffer diff = data - gold;
75 
76  Buffer abs_diff(diff);
77  abs_diff.abs();
78 
79  if(abs_diff.getMax() > GAMMA)
80  {
81  cerr << TEST_ERROR_HEADER
82  << "Output did not match gold file!"
83  << endl;
84 
85  data.plot("data");
86  gold.plot("gold");
87  diff.plot("data - gold");
88  Plotter::show();
89 
90  exit(1);
91  }
92 
93  cout << SUCCESS;
94 
95  // Test 3.5 Hz wave
96  cout << TEST_HEADER << "Testing Generator::drawLine(1.26, -0.26, 0.26) ...";
97 
98  data = gen.drawLine(1.26, -0.26, 0.26);
99 
100  // Create the gold file
101 //~ data >> "gold/Generator_line2.wav";
102 
103  gold = Buffer();
104 
105  gold << "gold/Generator_line2.wav";
106 
107  diff = data - gold;
108 
109  abs_diff = diff;
110  abs_diff.abs();
111 
112  if(abs_diff.getMax() > GAMMA)
113  {
114  cerr << TEST_ERROR_HEADER
115  << "Output did not match gold file!"
116  << endl;
117 
118  data.plot("data");
119  gold.plot("gold");
120  diff.plot("data - gold");
121  Plotter::show();
122 
123  exit(1);
124  }
125 
126  cout << SUCCESS;
127 
128 
129  // Test 3.5 Hz wave
130  cout << TEST_HEADER << "Testing Generator::buzz(1.0, 4.0, 3, 0.0) ...";
131 
132  data = cos.buzz(1.0, 4.0, 3, 0.0);
133 
134  // Create the gold file
135 //~ data >> "gold/Generator_buzz1.wav";
136 
137  gold = Buffer();
138 
139  gold << "gold/Generator_buzz1.wav";
140 
141  diff = data - gold;
142 
143  abs_diff = diff;
144  abs_diff.abs();
145 
146  if(abs_diff.getMax() > GAMMA)
147  {
148  cerr << TEST_ERROR_HEADER
149  << "Output did not match gold file!"
150  << endl;
151 
152  data.plot("data");
153  gold.plot("gold");
154  diff.plot("data - gold");
155  Plotter::show();
156 
157  exit(1);
158  }
159 
160  cout << SUCCESS;
161 
162 
163  // Test 3.5 Hz wave
164  cout << TEST_HEADER << "Testing Generator::buzz(1.0, 4.0, 3, 0.5) ...";
165 
166  data = cos.buzz(1.0, 4.0, 3, 0.5);
167 
168  // Create the gold file
169 //~ data >> "gold/Generator_buzz2.wav";
170 
171  gold = Buffer();
172 
173  gold << "gold/Generator_buzz2.wav";
174 
175  diff = data - gold;
176 
177  abs_diff = diff;
178  abs_diff.abs();
179 
180  if(abs_diff.getMax() > GAMMA)
181  {
182  cerr << TEST_ERROR_HEADER
183  << "Output did not match gold file!"
184  << endl;
185 
186  data.plot("data");
187  gold.plot("gold");
188  diff.plot("data - gold");
189  Plotter::show();
190 
191  exit(1);
192  }
193 
194  cout << SUCCESS;
195 
196  // Test 3.5 Hz wave
197  cout << TEST_HEADER << "Testing Generator::buzz(1.0, 4.0, 4, 0.5) ...";
198 
199  data = cos.buzz(1.0, 4.0, 4, 0.5);
200 
201  // Create the gold file
202 //~ data >> "gold/Generator_buzz3.wav";
203 
204  gold = Buffer();
205 
206  gold << "gold/Generator_buzz3.wav";
207 
208  diff = data - gold;
209 
210  abs_diff = diff;
211  abs_diff.abs();
212 
213  if(abs_diff.getMax() > GAMMA)
214  {
215  cerr << TEST_ERROR_HEADER
216  << "Output did not match gold file!"
217  << endl;
218 
219  data.plot("data");
220  gold.plot("gold");
221  diff.plot("data - gold");
222  Plotter::show();
223 
224  exit(1);
225  }
226 
227  cout << SUCCESS;
228 
229  // Test drawSine
230  cout << TEST_HEADER << "Testing Generator::drawSine(1.0, 10.0) ...";
231 
232  gen = Generator(600.0);
233 
234  data = Buffer();
235  data << gen.drawSine(1.0, 10.0);
236 
237  // Create the gold file
238 //~ data >> "gold/Generator_sine1.wav";
239 
240  gold = Buffer("gold/Generator_sine1.wav");
241 
242  diff = data - gold;
243 
244  abs_diff = diff;
245  abs_diff.abs();
246 
247  if(abs_diff.getMax() > GAMMA)
248  {
249  cerr << TEST_ERROR_HEADER
250  << "Output did not match gold file!"
251  << endl;
252 
253  data.plot("data");
254  gold.plot("gold");
255  diff.plot("data - gold");
256  Plotter::show();
257 
258  exit(1);
259  }
260 
261  cout << SUCCESS;
262 
263  // Test drawSine
264  cout << TEST_HEADER << "Testing Generator::drawSine(1.0, freqs) ...";
265 
266  data = Buffer();
267 
268  Buffer freqs(gen.drawLine(1.0, 1.0, 10.0));
269 
270  data << gen.drawSine(1.0, freqs);
271 
272  // Create the gold file
273 //~ data >> "gold/Generator_sine2.wav";
274 
275  gold = Buffer("gold/Generator_sine2.wav");
276 
277  diff = data - gold;
278 
279  abs_diff = diff;
280  abs_diff.abs();
281 
282  if(abs_diff.getMax() > GAMMA)
283  {
284  cerr << TEST_ERROR_HEADER
285  << "Output did not match gold file!"
286  << endl;
287 
288  data.plot("data");
289  gold.plot("gold");
290  diff.plot("data - gold");
291  Plotter::show();
292 
293  exit(1);
294  }
295 
296  cout << SUCCESS;
297 
298  // Test drawSine
299  cout << TEST_HEADER << "Testing Generator::drawSine2(1.0, 3.0, 0.5) ...";
300 
301  data = Buffer();
302 
303  data << gen.drawSine2(1.0, 3.0, 0.5);
304 
305  // Create the gold file
306 //~ data >> "gold/Generator_sine3.wav";
307 
308  gold = Buffer("gold/Generator_sine3.wav");
309 
310  diff = data - gold;
311 
312  abs_diff = diff;
313  abs_diff.abs();
314 
315  if(abs_diff.getMax() > GAMMA)
316  {
317  cerr << TEST_ERROR_HEADER
318  << "Output did not match gold file!"
319  << endl;
320 
321  data.plot("data");
322  gold.plot("gold");
323  diff.plot("data - gold");
324  Plotter::show();
325 
326  exit(1);
327  }
328 
329  cout << SUCCESS;
330 
331  // Test drawSine
332  cout << TEST_HEADER << "Testing Generator::drawSine2(1.0, 3.0, phase) ...";
333 
334  data = Buffer();
335 
336  Buffer phase;
337  phase << gen.drawLine(1.0, 0.0, 1.0);
338 
339  data << gen.drawSine2(1.0, 3.0, phase);
340 
341  // Create the gold file
342 //~ data >> "gold/Generator_sine4.wav";
343 
344  gold = Buffer("gold/Generator_sine4.wav");
345 
346  diff = data - gold;
347 
348  abs_diff = diff;
349  abs_diff.abs();
350 
351  if(abs_diff.getMax() > GAMMA)
352  {
353  cerr << TEST_ERROR_HEADER
354  << "Output did not match gold file!"
355  << endl;
356 
357  data.plot("data");
358  gold.plot("gold");
359  diff.plot("data - gold");
360  Plotter::show();
361 
362  exit(1);
363  }
364 
365  cout << SUCCESS;
366 
367  // Test drawSine
368  cout << TEST_HEADER << "Testing Generator::drawSine2(1.0, freqs, 0.5) ...";
369 
370  data = Buffer();
371  freqs = Buffer();
372 
373  freqs << gen.drawLine(1.0, 0.0, 10.0);
374 
375  data << gen.drawSine2(1.0, freqs, 0.5);
376 
377  // Create the gold file
378 //~ data >> "gold/Generator_sine5.wav";
379 
380  gold = Buffer("gold/Generator_sine5.wav");
381 
382  diff = data - gold;
383 
384  abs_diff = diff;
385  abs_diff.abs();
386 
387  if(abs_diff.getMax() > GAMMA)
388  {
389  cerr << TEST_ERROR_HEADER
390  << "Output did not match gold file!"
391  << endl;
392 
393  data.plot("data");
394  gold.plot("gold");
395  diff.plot("data - gold");
396  Plotter::show();
397 
398  exit(1);
399  }
400 
401  cout << SUCCESS;
402 
403  // Test drawSine
404  cout << TEST_HEADER << "Testing Generator::drawSine2(1.0, freqs, phase) ...";
405 
406  data = Buffer();
407 
408  data << gen.drawSine2(1.0, freqs, phase);
409 
410  // Create the gold file
411 //~ data >> "gold/Generator_sine6.wav";
412 
413  gold = Buffer("gold/Generator_sine6.wav");
414 
415  diff = data - gold;
416 
417  abs_diff = diff;
418  abs_diff.abs();
419 
420  if(abs_diff.getMax() > GAMMA)
421  {
422  cerr << TEST_ERROR_HEADER
423  << "Output did not match gold file!"
424  << endl;
425 
426  data.plot("data");
427  gold.plot("gold");
428  diff.plot("data - gold");
429  Plotter::show();
430 
431  exit(1);
432  }
433 
434  cout << SUCCESS;
435 
436  // Test chorus
437  cout << TEST_HEADER << "Testing Generator::generate(1.0, freq) with chorus ...";
438 
439  data = Buffer();
440 
441  cos.setSeed(457745);
442 
443  cos.setChorus(2, 0.50);
444 
445  data << cos.generate(1.0, 5);
446 
447  // Create the gold file
448 //~ data >> "gold/Generator_chorus1.wav";
449 
450 //~ // Force a failure
451 //~ data[data.getLength() / 2] += data.getMax();
452 
453  gold = Buffer("gold/Generator_chorus1.wav");
454 
455  diff = data - gold;
456 
457  abs_diff = diff;
458  abs_diff.abs();
459 
460  if(abs_diff.getMax() > GAMMA)
461  {
462  cerr << TEST_ERROR_HEADER
463  << "Output did not match gold file!"
464  << endl;
465 
466  Plotter pylab;
467  pylab.plot(data, "r", "label='data'");
468  pylab.plot(gold, "b", "label='gold', lw=2");
469  pylab.grid(true);
470  pylab.legend();
471 
472  pylab.show();
473 
474  exit(1);
475  }
476 
477  cout << SUCCESS;
478 
479 
480  // Finish
481  cout << endl;
482 
483  Plotter::show();
484 }
485 
486 
Buffer drawSine2(const float64 &duration, const float64 &frequency, const float64 &phase)
This method draws a static sine wave.
Definition: Generator.cc:591
void grid(boolean flag)
Sets the grid state.
Definition: Plotter.cc:496
static void show()
Acutally draw the plots to the screen.
Definition: Plotter.cc:252
void plot(const Buffer &y, const std::string &fmt="", const std::string &kwargs="")
Plots the Buffer on the current figure.
Definition: Plotter.cc:765
static const char * THIS_FILE
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
void legend(const std::string &kwargs="")
Shows the legend on the current axes.
Definition: Plotter.cc:745
double float64
Definition: Nsound.h:146
Buffer drawSine(const float64 &duration, const float64 &frequency)
This method draws a static sine wave.
Definition: Generator.cc:544
#define TEST_ERROR_HEADER
Definition: Test.h:49
virtual float64 generate(const float64 &frequency)
This is a real-time method for the wavetable oscillator.
Definition: Generator.cc:972
void setChorus(const uint32 n_voices, const float64 &sigma=0.02)
Chorus or Unison.
Definition: Generator.cc:361
void Generator_UnitTest()
float64 buzz(const float64 &frequency, const float64 &n_harmonics, const float64 &delay)
Returns sample from a set of harmonics. Based on the Csound buzz opcode.
Definition: Generator.cc:260
static const float64 GAMMA
static void setIEEEFloat(boolean flag)
Definition: Wavefile.cc:98
void abs()
Modifies the Buffer by making any negative value positive.
Definition: Buffer.cc:119
#define SUCCESS
Definition: UnitTest.h:42
A Buffer for storing audio samples.
Definition: Buffer.h:60
static void setDefaultSampleSize(uint32 size)
Definition: Wavefile.cc:79
Buffer drawLine(const float64 &duration, const float64 &amplitude_start, const float64 &amplitude_finish) const
This method draws a linear line beteween 2 points.
Definition: Generator.cc:464
float64 getMax() const
Returns the maximum sample value in the Buffer.
Definition: Buffer.cc:951
void setSeed(const uint32 seed)
Sets the seed for the Generator's random number generator (rng).
Definition: Generator.cc:1303
A class the provides draw utilities and a wavetable oscillator.
Definition: Generator.h:50