Nsound  0.9.4
Buffer_UnitTest.cc
Go to the documentation of this file.
1 //-----------------------------------------------------------------------------
2 //
3 // $Id: Buffer_UnitTest.cc 874 2014-09-08 02:21:29Z weegreenblobbie $
4 //
5 // Copyright (c) 2005-2006 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/NsoundAll.h>
30 #include "UnitTest.h"
31 
32 #include <stdlib.h>
33 #include <iostream>
34 
35 using namespace Nsound;
36 
37 using std::cout;
38 using std::cerr;
39 using std::endl;
40 
41 static const char * THIS_FILE = "Buffer_UnitTest.cc";
42 
43 static const float64 GAMMA = 1.5e-12;
44 
45 void testBufferAdd();
46 
47 //-----------------------------------------------------------------------------
49 {
50  cout << endl << THIS_FILE;
51 
53 
54  cout << TEST_HEADER << "Testing Buffer::operator<<(float64) ...";
55 
56  Buffer b1(29);
57 
58  for(float64 i = 0.0; i < 100.0; i += 1.1)
59  {
60  b1 << i;
61  }
62 
63  uint32 index = 0;
64  for(float64 i = 0.0; i < 100.0; i += 1.1)
65  {
66  if( ::fabs(b1[index++] - i) > GAMMA)
67  {
68  cerr << TEST_ERROR_HEADER
69  << "Output did not match expected values!"
70  << endl;
71 
72  exit(1);
73  }
74  }
75 
76  cout << SUCCESS;
77 
78  cout << TEST_HEADER << "Testing Buffer::Buffer(const Buffer &) ...";
79 
80  Buffer b2(b1);
81 
82  if(b1 != b2 || b2 != b1)
83  {
84  cerr << TEST_ERROR_HEADER
85  << "Output did not match expected values!"
86  << endl;
87 
88  Buffer diff(b1 - b2);
89  diff.plot("data - gold");
90  b1.plot("b1");
91  b2.plot("b2");
92 
93  Plotter::show();
94 
95  exit(1);
96  }
97 
98  cout << SUCCESS;
99 
100  cout << TEST_HEADER << "Testing Buffer::operator=(const Buffer &) ...";
101 
102  Buffer b3;
103 
104  b3 = b1;
105 
106  if(b3 != b1 || b1 != b3)
107  {
108  cerr << TEST_ERROR_HEADER
109  << "Output did not match expected values!"
110  << endl;
111 
112  Buffer diff(b3 - b1);
113  diff.plot("data - gold");
114  b3.plot("b3");
115  b1.plot("b1");
116 
117  Plotter::show();
118 
119  exit(1);
120  }
121 
122  cout << SUCCESS;
123 
124  cout << TEST_HEADER << "Testing Buffer::operator<<(const Buffer &) ...";
125 
126  Buffer b4(b3);
127 
128  b4 << b1;
129  b3 << b1;
130 
131  if(!(b4 == b3) || !(b3 == b4))
132  {
133  cerr << TEST_ERROR_HEADER
134  << "Output did not match expected values!"
135  << endl;
136 
137  Buffer diff(b4 - b3);
138  diff.plot("data - gold");
139  b4.plot("b4");
140  b3.plot("b3");
141 
142  Plotter::show();
143 
144  exit(1);
145  }
146 
147  cout << SUCCESS;
148 
149  cout << TEST_HEADER << "Testing Buffer::operator[](uint32) ...";
150 
151  uint32 size = b4.getLength();
152 
153  for(uint32 i = 0; i < size; ++i)
154  {
155  if(::fabs(b4[i] - b3[i]) > GAMMA)
156  {
157  cerr << TEST_ERROR_HEADER
158  << "Output did not match expected values!"
159  << endl;
160 
161  Buffer diff(b4 - b3);
162  diff.plot("data - gold");
163  b4.plot("b4");
164  b3.plot("b3");
165 
166  Plotter::show();
167 
168  exit(1);
169  }
170  }
171 
172  cout << SUCCESS;
173 
174  cout << TEST_HEADER << "Testing Buffer::operator+,-,*,/ ...";
175 
176  b4 = b3;
177 
178  if(1 + b4 * 2 != 2 * b3 + 1)
179  {
180  cerr << TEST_ERROR_HEADER
181  << "Output did not match expected values!"
182  << endl;
183 
184  exit(1);
185  }
186 
187  if(1 - b4 / 2 != -1 * b3 / 2 + 1)
188  {
189  cerr << TEST_ERROR_HEADER
190  << "Output did not match expected values!"
191  << endl;
192 
193  exit(1);
194  }
195 
196  if(2.0 / b4 != 4.0 * (0.5 / b4))
197  {
198  cerr << TEST_ERROR_HEADER
199  << "Output did not match expected values!"
200  << endl;
201 
202  exit(1);
203  }
204 
205  b3 = -1.0 * b4;
206 
207  b4 += b3;
208 
209  uint32 n_samples = b4.getLength();
210  for(uint32 i = 0; i < n_samples; ++i)
211  {
212  if(b4[i] != 0.0)
213  {
214  cerr << TEST_ERROR_HEADER
215  << "b4 += b3 _SHOULD_ be all zeros!"
216  << endl;
217  exit(1);
218  }
219  }
220 
221  cout << SUCCESS;
222 
223  cout << TEST_HEADER << "Testing Buffer::abs() ...";
224 
225  b4 = Buffer();
226 
227  if(b4.getLength() != 0)
228  {
229  cerr << TEST_ERROR_HEADER
230  << "b4.getLength() != 0"
231  << endl;
232  exit(1);
233  }
234 
235  float64 neg = -1.0;
236  float64 sum = 1.0;
237  for(uint32 i = 0; i < 100; ++i)
238  {
239  sum *= neg;
240  b4 << sum;
241  }
242 
243  b4.abs();
244 
245  float64 m = b4.getMin();
246  if(m < 0.0)
247  {
248  cerr << TEST_ERROR_HEADER
249  << "b4.abs() is broken"
250  << endl;
251  exit(1);
252  }
253 
254  cout << SUCCESS;
255 
256  cout << TEST_HEADER << "Testing Buffer::reverse() ...";
257 
258  b4 = Buffer();
259 
260  if(b4.getLength() != 0)
261  {
262  cerr << TEST_ERROR_HEADER
263  << "b4.getLength() != 0"
264  << endl;
265  exit(1);
266  }
267 
268  for(float64 f = 0.0; f < 100.0; f += 1.0)
269  {
270  b4 << f;
271  }
272 
273  b4.reverse();
274 
275  index = 0;
276  for(float64 f = 99.0; f >= 0.0; f -= 1.0)
277  {
278  if(::fabs(b4[index++] - f) > GAMMA)
279  {
280  cerr << TEST_ERROR_HEADER
281  << "b4.reverse() borken"
282  << endl;
283 
284  b4.plot("b4");
285 
286  Plotter::show();
287  exit(1);
288  }
289  }
290 
291  cout << SUCCESS;
292 
293  cout << TEST_HEADER << "Testing Buffer::subbuffer() ...";
294 
295  b3 = Buffer();
296 
297  uint32 chunk = 100;
298 
299  for(uint32 i = 0; i < chunk * 2 + 1; ++i)
300  {
301  b3 << i;
302  }
303 
304  uint32 test_size = 99;
305 
306  Buffer subbuf = b3.subbuffer(0, test_size);
307 
308  if (subbuf.getLength() != test_size)
309  {
310  cerr << TEST_ERROR_HEADER
311  << "subbuf.getLength() = "
312  << subbuf.getLength()
313  << " != "
314  << test_size
315  << endl;
316  exit(1);
317  }
318 
319  test_size = chunk;
320 
321  subbuf = b3.subbuffer(0,test_size);
322 
323  if (subbuf.getLength() != test_size)
324  {
325  cerr << TEST_ERROR_HEADER
326  << "subbuf.getLength() = "
327  << subbuf.getLength()
328  << " != "
329  << test_size
330  << endl;
331  exit(1);
332  }
333 
334  test_size = b3.getLength() + 1;
335 
336  subbuf = b3.subbuffer(0, test_size);
337 
338  if (subbuf.getLength() != b3.getLength())
339  {
340  cerr << TEST_ERROR_HEADER
341  << "subbuf.getLength() = "
342  << subbuf.getLength()
343  << " != "
344  << b3.getLength()
345  << endl;
346  exit(1);
347  }
348 
349  test_size = chunk + 10;
350 
351  for(uint32 i = 0; i < 10; ++i)
352  {
353  subbuf = b3.subbuffer(i, test_size);
354 
355  if (subbuf.getLength() != test_size)
356  {
357  cerr << TEST_ERROR_HEADER
358  << "subbuf.getLength() = "
359  << subbuf.getLength()
360  << " != "
361  << test_size
362  << endl;
363  exit(1);
364  }
365  }
366 
367  subbuf = b3.subbuffer(0,10);
368 
369  for(uint32 i = 0; i < 10; ++i)
370  {
371  if(static_cast<uint32>(subbuf[i]) != i)
372  {
373  cerr << TEST_ERROR_HEADER
374  << "b3.subbuffer() error!"
375  << endl;
376  exit(1);
377  }
378  }
379 
380  // Try with offset
381 
382  subbuf = b3.subbuffer(3,3);
383 
384  for(uint32 i = 0; i < 3; ++i)
385  {
386  if(static_cast<uint32>(subbuf[i]) != i + 3)
387  {
388  cerr << TEST_ERROR_HEADER
389  << "b3.subbuffer() error!"
390  << endl;
391  exit(1);
392  }
393  }
394 
395  // Try using default value for n_samples
396 
397  subbuf = b3.subbuffer(3);
398 
399  if(subbuf.getLength() != b3.getLength() - 3)
400  {
401  cerr << TEST_ERROR_HEADER
402  << "subbuf.getLength() = "
403  << subbuf.getLength()
404  << " != "
405  << b3.getLength() - 3
406  << endl;
407  exit(1);
408  }
409 
410  // Try using default value for n_samples
411 
412  subbuf = b3.subbuffer(0);
413 
414  if(subbuf.getLength() != b3.getLength())
415  {
416  cerr << TEST_ERROR_HEADER
417  << "subbuf.getLength() _SHOULD_ be 10, found "
418  << subbuf.getLength()
419  << endl;
420  exit(1);
421  }
422 
423  for(uint32 i = 0; i < 10; ++i)
424  {
425  if(static_cast<uint32>(subbuf[i]) != i)
426  {
427  cerr << TEST_ERROR_HEADER
428  << "b3.subbuffer() error!"
429  << endl;
430  exit(1);
431  }
432  }
433 
434  subbuf = b3.subbuffer(5,5);
435 
436  if(subbuf.getLength() != 5)
437  {
438  cerr << TEST_ERROR_HEADER
439  << "subbuf.getLength() = "
440  << subbuf.getLength()
441  << " != 5"
442  << endl;
443  exit(1);
444  }
445 
446  for(uint32 i = 0; i < 5; ++i)
447  {
448  if(static_cast<uint32>(subbuf[i]) != i + 5)
449  {
450  cerr << TEST_ERROR_HEADER
451  << "subbuf["
452  << i
453  << "] = "
454  << subbuf[i]
455  << " != "
456  << i + 5
457  << endl;
458  exit(1);
459  }
460  }
461 
462  cout << SUCCESS;
463 
464  cout << TEST_HEADER << "Testing Buffer::smooth() ...";
465 
466  Sine sine(100);
467 
468  b4 << "gold/Filter_noise.wav";
469 
470  uint32 b4_length = b4.getLength();
471  float64 b4_max = b4.getMax();
472 
473  b4.smooth(1, 16);
474 
475  if(b4.getLength() != b4_length)
476  {
477  cerr << TEST_ERROR_HEADER
478  << "b4.smooth() error!"
479  << endl;
480  exit(1);
481  }
482 
483  if(b4.getMax() > b4_max)
484  {
485  cerr << TEST_ERROR_HEADER
486  << "b4.smooth() error!"
487  << endl;
488  exit(1);
489  }
490 
491  cout << SUCCESS;
492 
493  cout << TEST_HEADER << "Testing Buffer::pow() ...";
494 
495  b4 = 2 * Buffer::ones(5);
496 
497  b4 ^= 2.0;
498 
499  for(uint32 i = 0; i < 5; ++i)
500  {
501  if(b4[i] != 4.0)
502  {
503  cerr << TEST_ERROR_HEADER
504  << "Buffer::pow() error!"
505  << " 4.0 != " << b4[i]
506  << endl;
507  exit(1);
508  }
509  }
510 
511  b4 ^= 0.50;
512 
513  for(uint32 i = 0; i < 5; ++i)
514  {
515  if(b4[i] != 2.0)
516  {
517  cerr << TEST_ERROR_HEADER
518  << "Buffer::pow() error!"
519  << " 2.0 != " << b4[i]
520  << endl;
521  exit(1);
522  }
523  }
524 
525  b4 = (b4 ^ 2.0) + (b4 ^ 2.0);
526 
527  for(uint32 i = 0; i < 5; ++i)
528  {
529  if(b4[i] != 8.0)
530  {
531  cerr << TEST_ERROR_HEADER
532  << "Buffer::pow() error!"
533  << " 8.0 != " << b4[i]
534  << endl;
535  exit(1);
536  }
537  }
538 
539  cout << SUCCESS;
540 
541  cout << TEST_HEADER << "Testing Buffer operators with different length ...";
542 
543  Buffer b5(100);
544  b5 = sine.drawLine(1.0, 2.0, 2.0);
545 
546  Buffer b6(100);
547  b6 = sine.drawLine(2.0, 3.0, 3.0);
548 
549  Buffer result = b5 * b6;
550 
551  if(result.getLength() != b5.getLength())
552  {
553  cerr << TEST_ERROR_HEADER
554  << "result.getLength() != b5.getLength(), "
555  << result.getLength()
556  << " != "
557  << b5.getLength()
558  << endl;
559  exit(1);
560  }
561 
562  for(uint32 i = 0; i < result.getLength(); ++i)
563  {
564  if(result[i] != 6.0)
565  {
566  cerr << TEST_ERROR_HEADER
567  << "result["
568  << i
569  << "] != 6.0"
570  << endl;
571  exit(1);
572  }
573  }
574 
575  result = b6 * b5;
576 
577  if(result.getLength() != b6.getLength())
578  {
579  cerr << TEST_ERROR_HEADER
580  << "result.getLength() != b6.getLength(), "
581  << result.getLength()
582  << " != "
583  << b6.getLength()
584  << endl;
585  exit(1);
586  }
587 
588  for(uint32 i = 0; i < b5.getLength(); ++i)
589  {
590  if(result[i] != 6.0)
591  {
592  cerr << TEST_ERROR_HEADER
593  << "result["
594  << i
595  << "] != 6.0"
596  << endl;
597  exit(1);
598  }
599  }
600 
601  for(uint32 i = b5.getLength(); i < result.getLength(); ++i)
602  {
603  if(result[i] != 3.0)
604  {
605  cerr << TEST_ERROR_HEADER
606  << "result["
607  << i
608  << "] != 3.0"
609  << endl;
610  exit(1);
611  }
612  }
613 
614  cout << SUCCESS;
615 
616  cout << TEST_HEADER << "Testing Buffer::add() ...";
617 
618  testBufferAdd();
619 
620  cout << SUCCESS;
621 
622  cout << TEST_HEADER << "Testing Buffer::circular_iterator ...";
623 
624  b5 = sine.drawLine(1.0, 1.0, 100.0);
625 
626  Buffer::circular_iterator itor = b5.cbegin();
627 
628  for(uint32 i = 0; i < b5.getLength(); ++i)
629  {
630  ++itor;
631  }
632 
633  if(itor != b5.cbegin())
634  {
635  cerr << TEST_ERROR_HEADER
636  << "circular_iterator::operator++ is broken!"
637  << endl;
638  exit(1);
639  }
640 
641  itor.reset();
642 
643  for(uint32 i = 0; i < b5.getLength(); ++i)
644  {
645  --itor;
646  }
647 
648  if(itor != b5.cbegin())
649  {
650  cerr << TEST_ERROR_HEADER
651  << "circular_iterator::operator-- is broken!"
652  << endl;
653  exit(1);
654  }
655 
656  itor.reset();
657 
658  for(uint32 i = 0; i < 3; ++i)
659  {
660  ++itor;
661  }
662 
663  if(itor != (b5.cbegin() + 3))
664  {
665  cerr << TEST_ERROR_HEADER
666  << "circular_iterator::operator++ is broken!"
667  << endl;
668  exit(1);
669  }
670 
671  itor.reset();
672 
673  for(uint32 i = 0; i < 3; ++i)
674  {
675  --itor;
676  }
677 
678  if(itor != (b5.cbegin() - 3))
679  {
680  cerr << TEST_ERROR_HEADER
681  << "circular_iterator::operator-- is broken!"
682  << endl;
683  exit(1);
684  }
685 
686  cout << SUCCESS;
687 
688  cout << TEST_HEADER << "Testing Buffer advanced operators ...";
689 
690  Buffer b7 = sine.generate(1.0, 2.0);
691 
692  Buffer data = b7;
693 
694  data(data > 0.5) = 0.5;
695  data(data < -0.5) = -0.5;
696 
697 //~ // Create gold file
698 //~ data >> "gold/Buffer_out1.wav";
699 
700  // Read in gold
701  Buffer gold("gold/Buffer_out1.wav");
702 
703  Buffer diff(gold - data);
704 
705  if(diff.getAbs().getMax() > GAMMA)
706  {
707  cerr << TEST_ERROR_HEADER
708  << "Output did not match expected values!"
709  << endl;
710 
711  diff.plot("gold - data");
712  data.plot("data");
713  gold.plot("gold");
714 
715  Plotter::show();
716 
717  exit(1);
718  }
719 
720  data = b7;
721 
722  BooleanVector bv1 = data > 0.5;
723  BooleanVector bv2 = data < -0.5;
724 
725  data(bv1) *= 0.1;
726  data(bv2) *= 0.1;
727 
728  data(bv1) += 0.45;
729  data(bv2) -= 0.45;
730 
731 //~ // Create gold file
732 //~ data >> "gold/Buffer_out2.wav";
733 
734  // Read in gold
735  gold = Buffer("gold/Buffer_out2.wav");
736 
737  diff = gold - data;
738 
739  if(diff.getAbs().getMax() > GAMMA)
740  {
741  cerr << TEST_ERROR_HEADER
742  << "Output did not match expected values!"
743  << endl;
744 
745  diff.plot("gold - data");
746  data.plot("data");
747  gold.plot("gold");
748 
749  Plotter::show();
750 
751  exit(1);
752  }
753 
754  cout << SUCCESS << endl;
755 }
756 
757 
758 //-----------------------------------------------------------------------------
760  const std::string & filename,
761  unsigned int line_number,
762  unsigned int n_samples,
763  unsigned int offset,
764  unsigned int a_length,
765  unsigned int b_length,
766  const std::string & message)
767 {
768  cerr << endl
769  << filename.c_str()
770  << ":"
771  << line_number
772  << ": n_samples = "
773  << n_samples
774  << " : offset = "
775  << offset
776  << " : a_length = "
777  << a_length
778  << " : b_length = "
779  << b_length
780  << " : "
781  << message.c_str()
782  << endl;
783  exit(1);
784 }
785 
786 //-----------------------------------------------------------------------------
787 // Exhaustively test the Buffer::add() method
788 //
789 // There are 11 cases to consider.
790 //
791 // c = a + b
792 //
793 // Case 1: n_samples == 0
794 // && a_length < offset
795 //
796 // [aaaaaaa]
797 // + |--offset--|[bbbbbbbbbbbbbbbbbbbbbb]
798 // result = |aaaaaaaa---bbbbbbbbbbbbbbbbbbbbbbb|
799 //
800 // Case 2: n_samples != 0
801 // && a_length < offset
802 // && n_samples <= b_length
803 //
804 // [aaaaaaa]
805 // + |--offset--|[bbbbbbbbbbbbbbbbbbbbbb]
806 // |---n_samples---|
807 // result = |aaaaaaaa---bbbbbbbbbbbbbbbb|
808 //
809 // Case 3: n_samples != 0
810 // && a_length < offset
811 // && n_samples > b_length
812 //
813 // [aaaaaaa]
814 // + |--offset--|[bbbbbbbbbbbbbbbbbbbbbb]
815 // |---n_samples----------------|
816 // result = |aaaaaaaa---bbbbbbbbbbbbbbbbbbbbbbbb-----|
817 //
818 //
819 // Case 4: n_samples == 0
820 // && a_length >= offset
821 // && a_length < offset + b_length
822 //
823 // [aaaaaaaaaaaaaaaaaaaaaaaaaaaa]
824 // + |--offset--|[bbbbbbbbbbbbbbbbbbbbbb]
825 // result = |aaaaaaaaaaaccccccccccccccccccbbbbb|
826 //
827 //
828 // Case 5: n_samples != 0
829 // && a_length >= offset
830 // && n_samples <= b_length
831 // && a_length <= offset + n_samples
832 //
833 // [aaaaaaaaaaaaaaaaaaaa]
834 // + |--offset--|[bbbbbbbbbbbbbbbbbbbbbb]
835 // |----n_samples----|
836 // result = |aaaaaaaaaacccccccccccbbbbbbb|
837 //
838 //
839 // Case 6: n_samples != 0
840 // && a_length >= offset
841 // && n_samples < b_length
842 // && a_length > offset + n_samples
843 //
844 // [aaaaaaaaaaaaaaaaaaaaaaaaaaaa]
845 // + |--offset--|[bbbbbbbbbbbbbbbbbbbbbb]
846 // |--n_samples--|
847 // result = |aaaaaaaaaacccccccccccccccaaa|
848 //
849 // Case 7: n_samples != 0
850 // && a_length >= offset
851 // && n_samples > b_length
852 // && a_length <= offset + b_length
853 //
854 // [aaaaaaaaaaaaaaaaaaaa]
855 // + |--offset--|[bbbbbbbbbbbbbbbbbbbbbb]
856 // |----n_samples---------------|
857 // result = |aaaaaaaaaaaccccccccccbbbbbbbbbbbbbb----|
858 //
859 //
860 // Case 8: n_samples == 0
861 // && a_length >= offset + b_length
862 //
863 // [aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa]
864 // + |--offset--|[bbbbbbbbbbbbbbbbbbbbbb]
865 // result = |aaaaaaaaaaaccccccccccccccccccccccccaaaaaa|
866 //
867 // Case 9: n_samples != 0
868 // && a_length >= offset + n_samples
869 // && n_samples < b_length
870 //
871 // [aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa]
872 // + |--offset--|[bbbbbbbbbbbbbbbbbbbb]
873 // |----n_samples----|
874 // result = |aaaaaaaaaaaccccccccccccccccccaaaaaaaaaaaa|
875 //
876 // Case 10: n_samples != 0
877 // && a_length >= offset + n_samples
878 // && n_samples >= b_length
879 //
880 // [aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa]
881 // + |--offset--|[bbbbbbbbbbbbbbbbbbbbb]
882 // |----n_samples---------------|
883 // result = |aaaaaaaaaaacccccccccccccccccccccccaaaaaaa|
884 //
885 // Case 11: n_samples != 0
886 // && a_length > offset + b_length
887 // && a_length < offset + n_samples
888 //
889 // [aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa]
890 // + |--offset--|[bbbbbbbbbbbbbbbbbbbbb]
891 // |----n_samples----------------------|
892 // result = |aaaaaaaaaaacccccccccccccccccccccccaaaaaaaa----|
893 //
894 //-----------------------------------------------------------------------------
896 {
897  bool final_case[12];
898 
899  for(uint32 i = 0; i < 12; ++i)
900  {
901  final_case[i] = false;
902  }
903 
904  for(uint32 run = 0; run < 2; ++run)
905  {
906  Buffer b;
907  Buffer a;
908 
909  uint32 test_size = 15;
910 
911  if(run == 0)
912  {
913  for(uint32 i = 0; i < test_size; ++i)
914  {
915  b << 1.0;
916  }
917 
918  a = b;
919 
920  // Make buffer a longer.
921  for(uint32 i = 0; i < test_size * 5 + 7; ++i)
922  {
923  a << 1.0;
924  }
925  }
926  else
927  {
928  for(uint32 i = 0; i < test_size; ++i)
929  {
930  a << 1.0;
931  }
932 
933  b = a;
934 
935  // Make buffer a longer.
936  for(uint32 i = 0; i < test_size * 5 + 7; ++i)
937  {
938  b << 1.0;
939  }
940  }
941 
942  uint32 a_length = a.getLength();
943  uint32 b_length = b.getLength();
944 
945  // Brute force test the add() method.
946 
947  uint32 offset_end = a_length + test_size * 6 + 7;
948 
949  for(uint32 n_samples = 0; n_samples < offset_end; ++n_samples)
950  {
951  for(uint32 offset = 0; offset < offset_end; ++offset)
952  {
953  bool current_run[12];
954 
955  for(uint32 i = 0; i < 12; ++i)
956  {
957  current_run[i] = false;
958  }
959 
960  Buffer result(a);
961  result.add(b,offset,n_samples);
962 
963  uint32 result_length = result.getLength();
964 
966  // Case 1:
967  // result = [aaaaaaa]
968  // + |--offset--|[bbbbbbbbbbbbbbbbbbbbbb]
969  // = |----------------------------------|
971  if(n_samples == 0 && a_length < offset)
972  {
973  current_run[0] = true;
974 
975  // Verify result length
976  if(result_length != offset + b_length)
977  {
978  reportError(__FILE__,__LINE__,
979  n_samples, offset, a_length, b_length,
980  "result length error");
981  }
982 
983  // Check prefix values.
984  for(uint32 i = 0; i < a_length; ++i)
985  {
986  if(result[i] != 1.0)
987  {
988  reportError(__FILE__,__LINE__,
989  n_samples, offset, a_length, b_length,
990  "result prefix error");
991  }
992  }
993 
994  // Check gap values
995  for(uint32 i = a_length + 1; i < offset; ++i)
996  {
997  if(result[i] != 0.0)
998  {
999  reportError(__FILE__,__LINE__,
1000  n_samples, offset, a_length, b_length,
1001  "result gap error");
1002  }
1003  }
1004 
1005  // Check b values
1006  for(uint32 i = offset + 1; i < result_length; ++i)
1007  {
1008  if(result[i] != 1.0)
1009  {
1010  reportError(__FILE__,__LINE__,
1011  n_samples, offset, a_length, b_length,
1012  "result b value error");
1013  }
1014  }
1015  }
1016 
1018  // Case 2: n_samples != 0
1019  // && a_length < offset
1020  // && n_samples <= b_length
1021  //
1022  // result = [aaaaaaa]
1023  // + |--offset--|[bbbbbbbbbbbbbbbbbbbbbb]
1024  // |---n_samples---|
1025  // = |---------------------------|
1027  else if(n_samples != 0
1028  && a_length < offset
1029  && n_samples <= b_length)
1030  {
1031  current_run[1] = true;
1032  // Verify result length
1033  if(result_length != offset + n_samples)
1034  {
1035  reportError(__FILE__,__LINE__,
1036  n_samples, offset, a_length, b_length,
1037  "result length error");
1038  }
1039 
1040  // Check prefix values.
1041  for(uint32 i = 0; i < a_length; ++i)
1042  {
1043  if(result[i] != 1.0)
1044  {
1045  reportError(__FILE__,__LINE__,
1046  n_samples, offset, a_length, b_length,
1047  "result prefix error");
1048  }
1049  }
1050 
1051  // Check gap values
1052  for(uint32 i = a_length + 1; i < offset; ++i)
1053  {
1054  if(result[i] != 0.0)
1055  {
1056  reportError(__FILE__,__LINE__,
1057  n_samples, offset, a_length, b_length,
1058  "result gap error");
1059  }
1060  }
1061 
1062  // Check b values
1063  for(uint32 i = offset + 1; i < result_length; ++i)
1064  {
1065  if(result[i] != 1.0)
1066  {
1067  reportError(__FILE__,__LINE__,
1068  n_samples, offset, a_length, b_length,
1069  "result b value error");
1070  }
1071  }
1072  }
1073 
1075  // Case 3: n_samples != 0
1076  // && a_length < offset
1077  // && n_samples > b_length
1078  //
1079  // result = [aaaaaaa]
1080  // + |--offset--|[bbbbbbbbbbbbbbbbbbbbbb]
1081  // |---n_samples----------------|
1082  // = |----------------------------------------|
1084  else if(n_samples != 0
1085  && a_length < offset
1086  && n_samples > b_length)
1087  {
1088  current_run[2] = true;
1089 
1090  // Verify result length
1091  if(result_length != offset + n_samples)
1092  {
1093  reportError(__FILE__,__LINE__,
1094  n_samples, offset, a_length, b_length,
1095  "result length error");
1096  }
1097 
1098  // Check prefix values.
1099  for(uint32 i = 0; i < a_length; ++i)
1100  {
1101  if(result[i] != 1.0)
1102  {
1103  reportError(__FILE__,__LINE__,
1104  n_samples, offset, a_length, b_length,
1105  "result prefix error");
1106  }
1107  }
1108 
1109  // Check gap values
1110  for(uint32 i = a_length + 1; i < offset; ++i)
1111  {
1112  if(result[i] != 0.0)
1113  {
1114  reportError(__FILE__,__LINE__,
1115  n_samples, offset, a_length, b_length,
1116  "result gap error");
1117  }
1118  }
1119 
1120  // Check b values
1121  for(uint32 i = offset + 1; i < offset + b_length; ++i)
1122  {
1123  if(result[i] != 1.0)
1124  {
1125  reportError(__FILE__,__LINE__,
1126  n_samples, offset, a_length, b_length,
1127  "result b value error");
1128  }
1129  }
1130 
1131  // Check tail values
1132  for(uint32 i = offset + b_length + 1; i < result_length; ++i)
1133  {
1134  if(result[i] != 0.0)
1135  {
1136  reportError(__FILE__,__LINE__,
1137  n_samples, offset, a_length, b_length,
1138  "result tail error");
1139  }
1140  }
1141  }
1142 
1144  // Case 4: n_samples == 0
1145  // && a_length >= offset
1146  // && a_length < offset + b_length
1147  //
1148  // result = [aaaaaaaaaaaaaaaaaaaaaaaaaaaa]
1149  // + |--offset--|[bbbbbbbbbbbbbbbbbbbbbb]
1150  // = |----------------------------------|
1152  else if(n_samples == 0
1153  && a_length >= offset
1154  && a_length < offset + b_length)
1155  {
1156  current_run[3] = true;
1157 
1158  // Verify result length
1159  if(result_length != offset + b_length)
1160  {
1161  reportError(__FILE__,__LINE__,
1162  n_samples, offset, a_length, b_length,
1163  "result length error");
1164  }
1165 
1166  // Check prefix values.
1167  for(uint32 i = 0; i < offset; ++i)
1168  {
1169  if(result[i] != 1.0)
1170  {
1171  reportError(__FILE__,__LINE__,
1172  n_samples, offset, a_length, b_length,
1173  "result prefix error");
1174  }
1175  }
1176 
1177  // Check overlap values
1178  for(uint32 i = offset + 1; i < a_length; ++i)
1179  {
1180  if(result[i] != 2.0)
1181  {
1182  reportError(__FILE__,__LINE__,
1183  n_samples, offset, a_length, b_length,
1184  "result overlap error");
1185  }
1186  }
1187 
1188  // Check tail values
1189  for(uint32 i = a_length + 1; i < result_length; ++i)
1190  {
1191  if(result[i] != 1.0)
1192  {
1193  reportError(__FILE__,__LINE__,
1194  n_samples, offset, a_length, b_length,
1195  "result tail error");
1196  }
1197  }
1198  }
1199 
1201  // Case 5: n_samples != 0
1202  // && a_length >= offset
1203  // && n_samples <= b_length
1204  // && a_length <= offset + n_samples
1205  //
1206  // result = [aaaaaaaaaaaaaaaaaaaa]
1207  // + |--offset--|[bbbbbbbbbbbbbbbbbbbbbb]
1208  // |----n_samples----|
1209  // = |----------------------------|
1211  else if(n_samples != 0
1212  && a_length >= offset
1213  && a_length <= offset + n_samples
1214  && n_samples <= b_length)
1215  {
1216  current_run[4] = true;
1217 
1218  // Verify result length
1219  if(result_length != offset + n_samples)
1220  {
1221  reportError(__FILE__,__LINE__,
1222  n_samples, offset, a_length, b_length,
1223  "result length error");
1224  }
1225 
1226  // Check prefix values.
1227  for(uint32 i = 0; i < offset; ++i)
1228  {
1229  if(result[i] != 1.0)
1230  {
1231  reportError(__FILE__,__LINE__,
1232  n_samples, offset, a_length, b_length,
1233  "result prefix error");
1234  }
1235  }
1236 
1237  // Check overlap values
1238  for(uint32 i = offset + 1; i < a_length; ++i)
1239  {
1240  if(result[i] != 2.0)
1241  {
1242  reportError(__FILE__,__LINE__,
1243  n_samples, offset, a_length, b_length,
1244  "result overlap error");
1245  }
1246  }
1247 
1248  // Check tail values
1249  for(uint32 i = a_length + 1; i < result_length; ++i)
1250  {
1251  if(result[i] != 1.0)
1252  {
1253  reportError(__FILE__,__LINE__,
1254  n_samples, offset, a_length, b_length,
1255  "result tail error");
1256  }
1257  }
1258  }
1260  // Case 6: n_samples != 0
1261  // && a_length >= offset
1262  // && n_samples < b_length
1263  // && a_length > offset + n_samples
1264  //
1265  // result = [aaaaaaaaaaaaaaaaaaaaaaaaaaaa]
1266  // + |--offset--|[bbbbbbbbbbbbbbbbbbbbbb]
1267  // |--n_samples--|
1268  // = |----------------------------|
1270  else if(n_samples != 0
1271  && a_length >= offset
1272  && a_length > offset + n_samples
1273  && n_samples < b_length)
1274  {
1275  current_run[5] = true;
1276 
1277  // Verify result length
1278  if(result_length != a_length)
1279  {
1280  reportError(__FILE__,__LINE__,
1281  n_samples, offset, a_length, b_length,
1282  "result length error");
1283  }
1284 
1285  // Check prefix values.
1286  for(uint32 i = 0; i < offset; ++i)
1287  {
1288  if(result[i] != 1.0)
1289  {
1290  reportError(__FILE__,__LINE__,
1291  n_samples, offset, a_length, b_length,
1292  "result prefix error");
1293  }
1294  }
1295 
1296  // Check overlap values
1297  for(uint32 i = offset + 1; i < offset + n_samples; ++i)
1298  {
1299  if(result[i] != 2.0)
1300  {
1301  reportError(__FILE__,__LINE__,
1302  n_samples, offset, a_length, b_length,
1303  "result overlap error");
1304  }
1305  }
1306 
1307  // Check tail values
1308  for(uint32 i = a_length + 1; i < result_length; ++i)
1309  {
1310  if(result[i] != 1.0)
1311  {
1312  reportError(__FILE__,__LINE__,
1313  n_samples, offset, a_length, b_length,
1314  "result tail error");
1315  }
1316  }
1317  }
1319  // Case 7: n_samples != 0
1320  // && a_length >= offset
1321  // && n_samples > b_length
1322  // && a_length <= offset + b_length
1323  //
1324  // result = [aaaaaaaaaaaaaaaaaaaa]
1325  // + |--offset--|[bbbbbbbbbbbbbbbbbbbbbb]
1326  // |----n_samples---------------|
1327  // = |---------------------------------------|
1329  else if(n_samples != 0
1330  && a_length >= offset
1331  && a_length <= offset + b_length
1332  && n_samples > b_length)
1333  {
1334  current_run[6] = true;
1335 
1336  // Verify result length
1337  if(result_length != offset + n_samples)
1338  {
1339  reportError(__FILE__,__LINE__,
1340  n_samples, offset, a_length, b_length,
1341  "result length error");
1342  }
1343 
1344  // Check prefix values.
1345  for(uint32 i = 0; i < offset; ++i)
1346  {
1347  if(result[i] != 1.0)
1348  {
1349  reportError(__FILE__,__LINE__,
1350  n_samples, offset, a_length, b_length,
1351  "result prefix error");
1352  }
1353  }
1354 
1355  // Check overlap values
1356  for(uint32 i = offset + 1; i < a_length; ++i)
1357  {
1358  if(result[i] != 2.0)
1359  {
1360  reportError(__FILE__,__LINE__,
1361  n_samples, offset, a_length, b_length,
1362  "result overlap error");
1363  }
1364  }
1365 
1366  // Check b values
1367  for(uint32 i = a_length + 1; i < offset + b_length; ++i)
1368  {
1369  if(result[i] != 1.0)
1370  {
1371  reportError(__FILE__,__LINE__,
1372  n_samples, offset, a_length, b_length,
1373  "result b value error");
1374  }
1375  }
1376 
1377  // Check tail values
1378  for(uint32 i = offset + b_length + 1; i < result_length; ++i)
1379  {
1380  if(result[i] != 0.0)
1381  {
1382  reportError(__FILE__,__LINE__,
1383  n_samples, offset, a_length, b_length,
1384  "result tail error");
1385  }
1386  }
1387  }
1389  // Case 8: n_samples == 0
1390  // && a_length >= offset + b_length
1391  //
1392  // result = [aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa]
1393  // + |--offset--|[bbbbbbbbbbbbbbbbbbbbbb]
1394  // = |-----------------------------------------|
1396  else if(n_samples == 0
1397  && a_length >= offset + b_length)
1398  {
1399  current_run[7] = true;
1400 
1401  // Verify result length
1402  if(result_length != a_length)
1403  {
1404  reportError(__FILE__,__LINE__,
1405  n_samples, offset, a_length, b_length,
1406  "result length error");
1407  }
1408 
1409  // Check prefix values.
1410  for(uint32 i = 0; i < offset; ++i)
1411  {
1412  if(result[i] != 1.0)
1413  {
1414  reportError(__FILE__,__LINE__,
1415  n_samples, offset, a_length, b_length,
1416  "result prefix error");
1417  }
1418  }
1419 
1420  // Check overlap values
1421  for(uint32 i = offset + 1; i < offset + b_length; ++i)
1422  {
1423  if(result[i] != 2.0)
1424  {
1425  reportError(__FILE__,__LINE__,
1426  n_samples, offset, a_length, b_length,
1427  "result overlap error");
1428  }
1429  }
1430 
1431  // Check a values
1432  for(uint32 i = offset + b_length + 1; i < result_length; ++i)
1433  {
1434  if(result[i] != 1.0)
1435  {
1436  reportError(__FILE__,__LINE__,
1437  n_samples, offset, a_length, b_length,
1438  "result a value error");
1439  }
1440  }
1441  }
1443  // Case 9: n_samples != 0
1444  // && a_length >= offset + n_samples
1445  // && n_samples < b_length
1446  //
1447  // result = [aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa]
1448  // + |--offset--|[bbbbbbbbbbbbbbbbbbbb]
1449  // |----n_samples----|
1450  // = |-----------------------------------------|
1452  else if(n_samples != 0
1453  && a_length >= offset + n_samples
1454  && n_samples < b_length)
1455  {
1456  current_run[8] = true;
1457 
1458  // Verify result length
1459  if(result_length != a_length)
1460  {
1461  reportError(__FILE__,__LINE__,
1462  n_samples, offset, a_length, b_length,
1463  "result length error");
1464  }
1465 
1466  // Check prefix values.
1467  for(uint32 i = 0; i < offset; ++i)
1468  {
1469  if(result[i] != 1.0)
1470  {
1471  reportError(__FILE__,__LINE__,
1472  n_samples, offset, a_length, b_length,
1473  "result prefix error");
1474  }
1475  }
1476 
1477  // Check overlap values
1478  for(uint32 i = offset + 1; i < offset + n_samples; ++i)
1479  {
1480  if(result[i] != 2.0)
1481  {
1482  reportError(__FILE__,__LINE__,
1483  n_samples, offset, a_length, b_length,
1484  "result overlap error");
1485  }
1486  }
1487 
1488  // Check a values
1489  for(uint32 i = offset + n_samples + 1; i < result_length; ++i)
1490  {
1491  if(result[i] != 1.0)
1492  {
1493  reportError(__FILE__,__LINE__,
1494  n_samples, offset, a_length, b_length,
1495  "result a value error");
1496  }
1497  }
1498  }
1500  // Case 10: n_samples != 0
1501  // && a_length >= offset + n_samples
1502  // && n_samples >= b_length
1503  //
1504  // result = [aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa]
1505  // + |--offset--|[bbbbbbbbbbbbbbbbbbbbb]
1506  // |----n_samples------------|
1507  // = |-----------------------------------------|
1509  else if(n_samples != 0
1510  && a_length >= offset + n_samples
1511  && n_samples >= b_length)
1512  {
1513  current_run[9] = true;
1514 
1515  // Verify result length
1516  if(result_length != a_length)
1517  {
1518  reportError(__FILE__,__LINE__,
1519  n_samples, offset, a_length, b_length,
1520  "result length error");
1521  }
1522 
1523  // Check prefix values.
1524  for(uint32 i = 0; i < offset; ++i)
1525  {
1526  if(result[i] != 1.0)
1527  {
1528  reportError(__FILE__,__LINE__,
1529  n_samples, offset, a_length, b_length,
1530  "result prefix error");
1531  }
1532  }
1533 
1534  // Check overlap values
1535  for(uint32 i = offset + 1; i < offset + b_length; ++i)
1536  {
1537  if(result[i] != 2.0)
1538  {
1539  reportError(__FILE__,__LINE__,
1540  n_samples, offset, a_length, b_length,
1541  "result overlap error");
1542  }
1543  }
1544 
1545  // Check a values
1546  for(uint32 i = offset + b_length + 1; i < result_length; ++i)
1547  {
1548  if(result[i] != 1.0)
1549  {
1550  a.plot("a");
1551  result.plot("result");
1552  Plotter::show();
1553  reportError(__FILE__,__LINE__,
1554  n_samples, offset, a_length, b_length,
1555  "result a value error");
1556  }
1557  }
1558  }
1560  // Case 11: n_samples != 0
1561  // && a_length > offset + b_length
1562  // && a_length < offset + n_samples
1563  //
1564  // result = [aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa]
1565  // + |--offset--|[bbbbbbbbbbbbbbbbbbbbb]
1566  // |----n_samples----------------------|
1567  // = |----------------------------------------------|
1569  else if(n_samples != 0
1570  && a_length > offset + b_length
1571  && a_length < offset + n_samples)
1572  {
1573  current_run[10] = true;
1574 
1575  // Verify result length
1576  if(result_length != offset + n_samples)
1577  {
1578  reportError(__FILE__,__LINE__,
1579  n_samples, offset, a_length, b_length,
1580  "result length error");
1581  }
1582 
1583  // Check prefix values.
1584  for(uint32 i = 0; i < offset; ++i)
1585  {
1586  if(result[i] != 1.0)
1587  {
1588  reportError(__FILE__,__LINE__,
1589  n_samples, offset, a_length, b_length,
1590  "result prefix error");
1591  }
1592  }
1593 
1594  // Check overlap values
1595  for(uint32 i = offset + 1; i < offset + b_length; ++i)
1596  {
1597  if(result[i] != 2.0)
1598  {
1599  reportError(__FILE__,__LINE__,
1600  n_samples, offset, a_length, b_length,
1601  "result overlap error");
1602  }
1603  }
1604 
1605  // Check a values
1606  for(uint32 i = offset + b_length + 1; i < a_length; ++i)
1607  {
1608  if(result[i] != 1.0)
1609  {
1610  reportError(__FILE__,__LINE__,
1611  n_samples, offset, a_length, b_length,
1612  "result a value error");
1613  }
1614  }
1615 
1616  // Check tail values
1617  for(uint32 i = a_length + 1; i < result_length; ++i)
1618  {
1619  if(result[i] != 0.0)
1620  {
1621  reportError(__FILE__,__LINE__,
1622  n_samples, offset, a_length, b_length,
1623  "result tail error");
1624  }
1625  }
1626  }
1627  else
1628  {
1629  reportError(
1630  __FILE__,
1631  __LINE__,
1632  n_samples,
1633  offset,
1634  a_length,
1635  b_length,
1636  "unhandled case");
1637  exit(1);
1638  }
1639 
1640  for(uint32 i = 0; i < 11; ++i)
1641  {
1642  if(current_run[i])
1643  final_case[i] = true;
1644  }
1645  }
1646  }
1647  }
1648 
1649  cout << "cases not hit: ";
1650 
1651  for(uint32 i = 0; i < 11; ++i)
1652  {
1653  if(!final_case[i])
1654  cout << i + 1 << " ";
1655  }
1656 
1657  cout << ": ";
1658 
1659 }
Buffer subbuffer(uint32 start_index, uint32 n_samples=0) const
Slice the Buffer.
Definition: Buffer.cc:2073
unsigned int uint32
Definition: Nsound.h:153
void Buffer_UnitTest()
static void show()
Acutally draw the plots to the screen.
Definition: Plotter.cc:252
void reportError(const std::string &filename, unsigned int line_number, unsigned int n_samples, unsigned int offset, unsigned int a_length, unsigned int b_length, const std::string &message)
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
A circulator iterator for class Buffer.
Buffer getAbs() const
Modifies a copy of the Buffer by making any negative value positive.
Definition: Buffer.h:174
double float64
Definition: Nsound.h:146
uint32 getLength() const
Returns the number of samples in the Buffer.
Definition: Buffer.h:587
#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 smooth(uint32 n_passes, uint32 n_samples_per_average)
Applies a moving average filter to smooth this Buffer.
Definition: Buffer.cc:1981
static Buffer ones(const uint32 n_samples)
Returns a Buffer full of ones of length n_samples.
Definition: Buffer.cc:2239
void reverse()
Reverses the samples in this Buffer.
Definition: Buffer.cc:1850
void abs()
Modifies the Buffer by making any negative value positive.
Definition: Buffer.cc:119
#define SUCCESS
Definition: UnitTest.h:42
void testBufferAdd()
A Buffer for storing audio samples.
Definition: Buffer.h:60
std::vector< boolean > BooleanVector
float64 getMin() const
Returns the minimum sample value in the Buffer.
Definition: Buffer.cc:1004
static const char * THIS_FILE
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 add(const Buffer &buffer, uint32 offset=0, uint32 n_samples=0)
This method adds buffer to *this.
Definition: Buffer.cc:225
DOXME.
Definition: Sine.h:43
static const float64 GAMMA