Nsound  0.9.4
Buffer.cc
Go to the documentation of this file.
1 //
3 // $Id: Buffer.cc 913 2015-08-08 16:41:22Z weegreenblobbie $
4 //
5 // Copyright (c) 2004-2006 Nick Hilton
6 //
7 // weegreenblobbie_yahoo_com (replace '_' with '@' and '.')
8 //
10 
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 //
28 
29 #include <Nsound/AudioStream.h>
30 #include <Nsound/Buffer.h>
32 #include <Nsound/DelayLine.h>
33 #include <Nsound/FFTransform.h>
37 #include <Nsound/Generator.h>
38 #include <Nsound/Nsound.h>
39 #include <Nsound/Plotter.h>
40 #include <Nsound/StreamOperators.h>
41 #include <Nsound/Wavefile.h>
42 
43 
44 #include <algorithm>
45 #include <iostream>
46 #include <fstream>
47 #include <sstream>
48 
49 using std::cerr;
50 using std::cout;
51 using std::endl;
52 using std::flush;
53 using std::ofstream;
54 using std::ostream;
55 using std::string;
56 
57 namespace Nsound
58 {
59 
60 
63  :
64  data_()
65 {
66  data_.reserve(4096);
67 }
68 
70 Buffer(uint32 chunk_size)
71  :
72  data_()
73 {
74  data_.reserve(chunk_size);
75 }
76 
78 Buffer(const FloatVector & list)
79  :
80  data_(list) // Copies contents
81 {
82 }
83 
85 Buffer(const std::string & filename, uint32 chunk_size)
86  :
87  data_()
88 {
89  data_.reserve(chunk_size);
90 
91  // This function is defined in Wavefile.h.
92  *this << filename.c_str();
93 }
94 
96 Buffer(const Buffer & copy)
97  :
98  data_(copy.data_)
99 {
100 }
101 
102 Buffer::
103 Buffer(Buffer && move)
104  :
105  data_()
106 {
107  std::swap(data_, move.data_);
108 }
109 
110 
111 Buffer::
113 {
114 }
115 
116 
117 void
118 Buffer::
120 {
121  for(uint32 i = 0; i < data_.size(); ++i)
122  {
123  data_[i] = ::fabs(data_[i]);
124  }
125 }
126 
127 // There are 11 cases to consider.
128 //
129 // c = a + b
130 //
131 // Case 1: n_samples == 0
132 // && a_length < offset
133 //
134 // [aaaaaaa]
135 // + |--offset--|[bbbbbbbbbbbbbbbbbbbbbb]
136 // result = |aaaaaaaa---bbbbbbbbbbbbbbbbbbbbbbb|
137 //
138 // Case 2: n_samples != 0
139 // && a_length < offset
140 // && n_samples <= b_length
141 //
142 // [aaaaaaa]
143 // + |--offset--|[bbbbbbbbbbbbbbbbbbbbbb]
144 // |---n_samples---|
145 // result = |aaaaaaaa---bbbbbbbbbbbbbbbb|
146 //
147 // Case 3: n_samples != 0
148 // && a_length < offset
149 // && n_samples > b_length
150 //
151 // [aaaaaaa]
152 // + |--offset--|[bbbbbbbbbbbbbbbbbbbbbb]
153 // |---n_samples----------------|
154 // result = |aaaaaaaa---bbbbbbbbbbbbbbbbbbbbbbbb-----|
155 //
156 //
157 // Case 4: n_samples == 0
158 // && a_length >= offset
159 // && a_length < offset + b_length
160 //
161 // [aaaaaaaaaaaaaaaaaaaaaaaaaaaa]
162 // + |--offset--|[bbbbbbbbbbbbbbbbbbbbbb]
163 // result = |aaaaaaaaaaaccccccccccccccccccbbbbb|
164 //
165 //
166 // Case 5: n_samples != 0
167 // && a_length >= offset
168 // && n_samples <= b_length
169 // && a_length <= offset + n_samples
170 //
171 // [aaaaaaaaaaaaaaaaaaaa]
172 // + |--offset--|[bbbbbbbbbbbbbbbbbbbbbb]
173 // |----n_samples----|
174 // result = |aaaaaaaaaacccccccccccbbbbbbb|
175 //
176 //
177 // Case 6: n_samples != 0
178 // && a_length >= offset
179 // && n_samples < b_length
180 // && a_length > offset + n_samples
181 //
182 // [aaaaaaaaaaaaaaaaaaaaaaaaaaaa]
183 // + |--offset--|[bbbbbbbbbbbbbbbbbbbbbb]
184 // |--n_samples--|
185 // result = |aaaaaaaaaacccccccccccccccaaa|
186 //
187 // Case 7: n_samples != 0
188 // && a_length >= offset
189 // && n_samples > b_length
190 // && a_length <= offset + b_length
191 //
192 // [aaaaaaaaaaaaaaaaaaaa]
193 // + |--offset--|[bbbbbbbbbbbbbbbbbbbbbb]
194 // |----n_samples---------------|
195 // result = |aaaaaaaaaaaccccccccccbbbbbbbbbbbbbb----|
196 //
197 //
198 // Case 8: n_samples == 0
199 // && a_length >= offset + b_length
200 //
201 // [aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa]
202 // + |--offset--|[bbbbbbbbbbbbbbbbbbbbbb]
203 // result = |aaaaaaaaaaaccccccccccccccccccccccccaaaaaa|
204 //
205 // Case 10: n_samples != 0
206 // && a_length >= offset + n_samples
207 // && n_samples >= b_length
208 //
209 // [aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa]
210 // + |--offset--|[bbbbbbbbbbbbbbbbbbbbb]
211 // |----n_samples---------------|
212 // result = |aaaaaaaaaaacccccccccccccccccccccccaaaaaaa|
213 //
214 // Case 11: n_samples != 0
215 // && a_length > offset + b_length
216 // && a_length < offset + n_samples
217 //
218 // [aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa]
219 // + |--offset--|[bbbbbbbbbbbbbbbbbbbbb]
220 // |----n_samples----------------------|
221 // result = |aaaaaaaaaaacccccccccccccccccccccccaaaaaaaa----|
222 //
223 void
224 Buffer::
225 add(const Buffer & b,
226  uint32 offset,
227  uint32 n_samples)
228 {
229  uint32 a_length = getLength();
230  uint32 b_length = b.getLength();
231 
232  // Case 1: n_samples == 0
233  // && a_length < offset
234  //
235  // [aaaaaaa]
236  // + |--offset--|[bbbbbbbbbbbbbbbbbbbbbb]
237  // result = |aaaaaaaa---bbbbbbbbbbbbbbbbbbbbbbb|
238  if(n_samples == 0 && a_length < offset)
239  {
240  // Append zeros
241  for(uint32 i = a_length; i < offset; ++i)
242  {
243  *this << 0.0;
244  }
245 
246  // Append b
247  *this << b;
248  }
249 
250  // Case 2: n_samples != 0
251  // && a_length < offset
252  // && n_samples <= b_length
253  //
254  // [aaaaaaa]
255  // + |--offset--|[bbbbbbbbbbbbbbbbbbbbbb]
256  // |---n_samples---|
257  // result = |aaaaaaaa---bbbbbbbbbbbbbbbb|
258  else if(n_samples != 0
259  && a_length < offset
260  && n_samples <= b_length)
261  {
262  // Append zeros
263  for(uint32 i = a_length; i < offset; ++i)
264  {
265  *this << 0.0;
266  }
267 
268  for(uint32 i = 0; i < n_samples; ++i)
269  {
270  *this << b[i];
271  }
272  }
273 
274  // Case 3: n_samples != 0
275  // && a_length < offset
276  // && n_samples > b_length
277  //
278  // [aaaaaaa]
279  // + |--offset--|[bbbbbbbbbbbbbbbbbbbbbb]
280  // |---n_samples----------------|
281  // result = |aaaaaaaa---bbbbbbbbbbbbbbbbbbbbbbbb-----|
282  else if(n_samples != 0
283  && a_length < offset
284  && n_samples > b_length)
285  {
286  // Append zeros
287  for(uint32 i = a_length; i < offset; ++i)
288  {
289  *this << 0.0;
290  }
291 
292  // Append b samples
293 
294  *this << b;
295 
296  // Append zeros
297 
298  for(uint32 i = b_length; i < n_samples; ++i)
299  {
300  *this << 0.0;
301  }
302  }
303 
304  // Case 4: n_samples == 0
305  // && a_length >= offset
306  // && a_length < offset + b_length
307  //
308  // [aaaaaaaaaaaaaaaaaaaaaaaaaaaa]
309  // + |--offset--|[bbbbbbbbbbbbbbbbbbbbbb]
310  // result = |aaaaaaaaaaaccccccccccccccccccbbbbb|
311  else if(n_samples == 0
312  && a_length >= offset
313  && a_length < offset + b_length)
314  {
315  uint32 b_index = 0;
316  for(uint32 i = offset; i < a_length; ++i)
317  {
318  data_[i] += b[b_index++];
319  }
320 
321  for(uint32 i = b_index; i < b_length; ++i)
322  {
323  *this << b[i];
324  }
325  }
326 
327  // Case 5: n_samples != 0
328  // && a_length >= offset
329  // && n_samples <= b_length
330  // && a_length <= offset + n_samples
331  //
332  // [aaaaaaaaaaaaaaaaaaaa]
333  // + |--offset--|[bbbbbbbbbbbbbbbbbbbbbb]
334  // |----n_samples----|
335  // result = |aaaaaaaaaacccccccccccbbbbbbb|
336  else if(n_samples != 0
337  && a_length >= offset
338  && a_length <= offset + n_samples
339  && n_samples <= b_length)
340  {
341  uint32 b_index = 0;
342  for(uint32 i = offset; i < a_length; ++i)
343  {
344  data_[i] += b[b_index++];
345  }
346 
347  for(uint32 i = b_index; i < n_samples; ++i)
348  {
349  *this << b[i];
350  }
351  }
352  // Case 6: n_samples != 0
353  // && a_length >= offset
354  // && n_samples < b_length
355  // && a_length > offset + n_samples
356  //
357  // [aaaaaaaaaaaaaaaaaaaaaaaaaaaa]
358  // + |--offset--|[bbbbbbbbbbbbbbbbbbbbbb]
359  // |--n_samples--|
360  // result = |aaaaaaaaaacccccccccccccccaaa|
361  else if(n_samples != 0
362  && a_length >= offset
363  && a_length > offset + n_samples
364  && n_samples < b_length)
365  {
366  uint32 b_index = 0;
367  for(uint32 i = offset; i < offset + n_samples; ++i)
368  {
369  data_[i] += b[b_index++];
370  }
371  }
372 
373  // Case 7: a_length >= offset
374  // && n_samples > b_length
375  // && a_length <= offset + b_length
376  //
377  // [aaaaaaaaaaaaaaaaaaaa]
378  // + |--offset--|[bbbbbbbbbbbbbbbbbbbbbb]
379  // |----n_samples---------------|
380  // result = |aaaaaaaaaaaccccccccccbbbbbbbbbbbbbb----|
381  else if(a_length >= offset
382  && a_length <= offset + b_length
383  && n_samples > b_length)
384  {
385  uint32 b_index = 0;
386  for(uint32 i = offset; i < a_length; ++i)
387  {
388  data_[i] += b[b_index++];
389  }
390 
391  for(uint32 i = b_index; i < b_length; ++i)
392  {
393  *this << b[i];
394  }
395 
396  for(uint32 i = b_length; i < n_samples; ++i)
397  {
398  *this << 0.0;
399  }
400  }
401  // Case 8: n_samples == 0
402  // && a_length >= offset + b_length
403  //
404  // [aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa]
405  // + |--offset--|[bbbbbbbbbbbbbbbbbbbbbb]
406  // result = |aaaaaaaaaaaccccccccccccccccccccccccaaaaaa|
407  else if(n_samples == 0
408  && a_length >= offset + b_length)
409  {
410  uint32 b_index = 0;
411  for(uint32 i = offset; i < offset + b_length; ++i)
412  {
413  data_[i] += b[b_index++];
414  }
415  }
416 
417  // Case 9: a_length >= offset + n_samples
418  // && n_samples >= b_length
419  //
420  // result = [aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa]
421  // + |--offset--|[bbbbbbbbbbbbbbbbbbbbb]
422  // |----n_samples------------|
423  // = |aaaaaaaaaaaacccccccccccccccccccccaaaaaaaa|
424  else if( a_length >= offset + n_samples
425  && n_samples >= b_length)
426  {
427  uint32 b_index = 0;
428  for(uint32 i = offset; i < offset + b_length; ++i)
429  {
430  data_[i] += b[b_index++];
431  }
432  }
433  // Case 10: n_samples != 0
434  // && a_length > offset + b_length
435  // && a_length < offset + n_samples
436  //
437  // result = [aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa]
438  // + |--offset--|[bbbbbbbbbbbbbbbbbbbbb]
439  // |----n_samples----------------------|
440  // = |aaaaaaaaaaaccccccccccccccccccccccaaaaaaa------|
441  else if(n_samples != 0
442  && a_length > offset + b_length
443  && a_length < offset + n_samples)
444  {
445  uint32 b_index = 0;
446  for(uint32 i = offset; i < offset + b_length; ++i)
447  {
448  data_[i] += b[b_index++];
449  }
450 
451  for(uint32 i = a_length; i < offset + n_samples; ++i)
452  {
453  *this << 0.0;
454  }
455  }
456 }
457 
458 uint32
459 Buffer::
460 argmax() const
461 {
462  uint32 index = 0;
463 
464  Buffer::const_iterator itor = begin();
465  Buffer::const_iterator tend = end();
466 
467  float64 max = *itor;
468 
469  uint32 i = 0;
470  while(itor != tend)
471  {
472  if(*itor > max)
473  {
474  max = *itor;
475  index = i;
476  }
477  ++i;
478  ++itor;
479  }
480  return index;
481 }
482 
483 uint32
484 Buffer::
485 argmin() const
486 {
487  uint32 index = 0;
488 
489  Buffer::const_iterator itor = begin();
490  Buffer::const_iterator tend = end();
491 
492  float64 min = *itor;
493 
494  uint32 i = 0;
495  while(itor != tend)
496  {
497  if(*itor < min)
498  {
499  min = *itor;
500  index = i;
501  }
502  ++i;
503  ++itor;
504  }
505  return index;
506 }
507 
508 void
509 Buffer::
511 {
512  for(uint32 i = 0; i < getLength(); ++i)
513  {
514  data_[i] = ::exp(data_[i]);
515  }
516 }
517 
518 void
519 Buffer::
520 convolve(const Buffer & H)
521 {
522  *this = getConvolve(H);
523 }
524 
525 Buffer
526 Buffer::
527 getConvolve(const Buffer & H) const
528 {
529  // Alocate the output Buffer will all zeros.
530  Buffer y = *this * 0.0;
531 
532  // Pad y with H.getLength() samples.
533  for(uint32 i = 0; i < H.getLength(); ++i)
534  {
535  y << 0.0;
536  }
537 
538 //~ uint32 N = getLength() / 1000;
539 
540 //~ printf("%6.2f", 0.0);
541 
542  // For each sample in this Buffer.
543  for(uint32 i = 0; i < getLength(); ++i)
544  {
545 //~ // DEBUG
546 //~ if(i % N == 0)
547 //~ {
548 //~ float64 p_done = 100.0 * i / float64(getLength());
549 //~ printf("\b\b\b\b\b\b%6.2f", p_done);
550 //~ fflush(stdout);
551 //~ }
552 
553  // For each sample in H.
554  for(uint32 j = 0; j < H.getLength(); ++j)
555  {
556  y[i + j] += (*this)[i] * H[j];
557  }
558  }
559 
560 //~ printf("\b\b\b\b\b\b%6.2f\n", 100.0);
561 
562  return y;
563 }
564 
565 void
566 Buffer::
567 dB()
568 {
569 //~ FloatVector::iterator itor = data_.begin();
570 //~ FloatVector::iterator end = data_.end();
571 
572 //~ while(itor != end)
573 //~ {
574 //~ if(*itor == 0.0)
575 //~ {
576 //~ *itor = -150.0;
577 //~ }
578 //~ else
579 //~ {
580 //~ *itor = 20.0 * ::log10(*itor);
581 //~ }
582 
583 //~ ++itor;
584 //~ }
585 
586  log10();
587  *this *= 20.0;
588 }
589 
590 void
591 Buffer::
593 {
594  for(uint32 pass = 0; pass < n; ++pass)
595  {
596  for(uint32 i = 1; i < data_.size(); ++i)
597  {
598  data_[i - 1] = (data_[i] - data_[i - 1]);
599  }
600  }
601 }
602 
603 void
604 Buffer::
606 {
607  *this = getDownSample(n);
608 }
609 
610 // This is based on the downsampling description in "Descrete-Time Signal
611 // Processing" 2nd Eddition aka "the Oppenheim book". Section 4.6.2 page 172.
612 //
613 Buffer
614 Buffer::
616 {
617  M_ASSERT_VALUE(M, >, 0);
618  return getResample(static_cast<uint32>(1),M);
619 }
620 
622 Buffer::
624  uint32 window_size,
625  float64 min_height) const
626 {
627  Uint32Vector peaks;
628  peaks.reserve(128);
629 
630  uint32 h_window_size = window_size / 2 + 1; // half window size
631 
632  uint32 n_samples = getLength();
633 
634  for(uint32 i = 1; i < n_samples - 1; ++i)
635  {
636  boolean is_peak = false;
637 
638  float64 sample = data_[i];
639 
640  if(window_size <= 2)
641  {
642  if( sample > data_[i - 1] &&
643  sample > data_[i + 1])
644  {
645  is_peak = true;
646  }
647  }
648  else
649  {
650  // Assume it's a peak.
651 
652  is_peak = true;
653 
654  for(uint32 j = 1; j < h_window_size; ++j)
655  {
656  if(j < i)
657  {
658  if(data_[i - j] > sample)
659  {
660  is_peak = false;
661  break;
662  }
663  }
664 
665  if(i + j < n_samples)
666  {
667  if(data_[i + j] > sample)
668  {
669  is_peak = false;
670  break;
671  }
672  }
673  }
674  }
675 
676  if(is_peak && sample > min_height)
677  {
678  peaks.push_back(i);
679  }
680  }
681 
682  return peaks;
683 }
684 
685 
686 /*
687 
688 Buffer
689 Buffer::
690 findPitch(float64 sample_rate)
691 {
692  // This is based on the YIN pitch estimation algorithm.
693 
694  // Create a window size that will fit 2 cycles of 20 Hz, our minimum
695  // detectable frequency.
696 
697  uint32 window_size = static_cast<uint32>(2.0 * sample_rate / 20.0);
698 
699  Buffer::const_iterator input = this->begin();
700  Buffer::const_iterator end = this->end();
701 
702  DelayLine dl(1, window_size);
703 
704  // First time, write window_size /2 zeros.
705  for(uint32 i = 0; i < window_size / 2; ++i)
706  {
707  dl.write(0.0);
708  }
709 
710  // FIXME: what if window_size > getLength()?
711  // write window_size / 2 samples.
712  for(uint32 i = 0; i < window_size / 2; ++i)
713  {
714  dl.write(*input);
715  ++input;
716  }
717 
718  uint32 input_done_count = 0;
719  boolean input_done = false;
720 
721  Generator gen(1);
722  FFTransform fft(1);
723 
724  Buffer window = gen.drawFatGaussian(window_size, 0.95);
725 
726  Buffer y(window_size);
727 
728  uint32 i = 0;
729  while(true)
730  {
731  // Grab a window of samples.
732  Buffer temp(window_size);
733 
734  // Read the delay line.
735  for(uint32 j = 0; j < window_size; ++j)
736  {
737  temp << dl.read();
738  }
739 
740  // Apply window.
741  temp *= window;
742 
744  // Calculate Autocorreletion using the FFT.
745 
746  // Perform the FFT.
747  FFTChunkVector vec = fft.fft(temp, 2 * window_size);
748 
749  Buffer power(2 * window_size);
750  for(uint32 j = 0; j < 2 * window_size; ++j)
751  {
752  float64 r = (*vec[0].real_)[j];
753  float64 i = (*vec[0].imag_)[j];
754 
755  power[j] = r*r + i*i;
756  }
757 
758  // Inverse fft to get autocorrelation.
759  *vec[0].real_ = power;
760  *vec[0].imag_ = gen.silence(2*window_size);
761 
762  Buffer acf = fft.ifft(vec);
763 
765  // Calculate the difference.
766  Buffer d(window_size);
767 
768  float64 rtTau = acf[0];
769 
770  uint32 hs = window_size / 2;
771 
772  for(uint32 j = 0; j < hs; ++j)
773  {
774  d << acf[0] + rtTau - (2.0 * acf[j]);
775 
776  rtTau += (temp[hs + j] * temp[hs + j]) - (temp[j] * temp[j]);
777  }
778 
780  // Calculate the cumlative normal.
781 
782  Buffer d_primes(window_size);
783 
784  float64 denom = d[0];
785 
786  d_primes << 1.0;
787 
788  for(uint32 j = 1; j < hs; ++j)
789  {
790  denom += d[j];
791 
792  d_primes << ((j-1) * d[j]) / (denom + 1e-20);
793  }
794 
796  // Calculate max period
797 
798  float64 f0 = 0.0;
799  float64 min = 1000.0;
800  for(uint32 j = 44; j < 540; ++j)
801  {
802  if(d_primes[j] < min)
803  {
804  min = d_primes[j];
805  f0 = j + 1;
806  }
807  }
808 
809  if(min >= 1000.0)
810  {
811  f0 = 0.0;
812  }
813  else
814  {
815  // Convert from samples to time, then frequency.
816  f0 *= (1.0 / sample_rate);
817  f0 = 1.0 / f0;
818  }
819 
820  y << f0;
821 
822  // Read data for next loop.
823  if(input_done)
824  {
825  ++input_done_count;
826 
827  if(input_done_count > 2) break;
828  }
829 
830  // Read in next chunk of input samples.
831  for(uint32 j = 0; j < window_size; ++j)
832  {
833  if(input == end)
834  {
835  input_done = true;
836 
837  dl.read();
838  dl.write(0.0);
839  }
840  else
841  {
842  dl.read(); // move the read pointer.
843  dl.write(*input);
844  ++input;
845  }
846  }
847  }
848 
849  return y;
850 }
851 */
852 
853 //~float64
854 //~Buffer::
855 //~get_at_index(int32 index) const
856 //~{
857 //~ int32 len = getLength();
858 
859 //~ if(index >= 0 && index < len)
860 //~ {
861 //~ return data_[index];
862 //~ }
863 //~ else if(index < 0 && index >= -len)
864 //~ {
865 //~ return data_[len + index];
866 //~ }
867 
868 //~ M_THROW(
869 //~ "IndexError: " << index << " is out of bounds (0 : " << len << ")");
870 
871 //~ return 0.0; // keep compiler quiet
872 //~}
873 
874 void
875 Buffer::
877 {
878  Buffer::iterator itor = this->begin();
879  Buffer::iterator end = this->end();
880 
881  while(itor != end)
882  {
883  float64 s = *itor;
884 
885  if(s > max) s = max;
886  if(s < min) s = min;
887 
888  *itor = s;
889 
890  ++itor;
891  }
892 }
893 
894 void
895 Buffer::
896 limit(const Buffer & min, const Buffer & max)
897 {
900 
901  Buffer::iterator itor = this->begin();
902  Buffer::iterator end = this->end();
903 
904  while(itor != end)
905  {
906  float64 s = *itor;
907 
908  if(s > *imax) s = *imax;
909  if(s < *imin) s = *imin;
910 
911  *itor = s;
912 
913  ++itor;
914  ++imax;
915  ++imin;
916  }
917 }
918 
919 #define LM_MAX(a,b) ((a) > (b)) ? (a) : (b)
920 
921 void
922 Buffer::
924 {
925  for(uint32 i = 0; i < getLength(); ++i)
926  {
927  // Avoid taking log of really tiny numbers.
928  float64 t = LM_MAX(data_[i], 1e-9);
929 
930  data_[i] = ::log(t);
931  }
932 }
933 
934 void
935 Buffer::
937 {
938  for(uint32 i = 0; i < getLength(); ++i)
939  {
940  // Avoid taking log of really tiny numbers.
941  float64 t = LM_MAX(data_[i], 1e-9);
942 
943  data_[i] = ::log10(t);
944  }
945 }
946 
947 #undef LM_MAX
948 
949 float64
950 Buffer::
951 getMax() const
952 {
953  M_ASSERT_VALUE(data_.size(), >=, 1);
954 
955  float64 max = data_[0];
956 
957  for(const_iterator itor = data_.begin();
958  itor != data_.end();
959  ++itor)
960  {
961  float64 t = *itor;
962  if(t > max)
963  {
964  max = t;
965  }
966  }
967 
968  return max;
969 }
970 
971 float64
972 Buffer::
974 {
975  M_ASSERT_VALUE(data_.size(), >=, 1);
976 
977  float64 max = data_[0];
978 
979  for(const_iterator itor = data_.begin();
980  itor != data_.end();
981  ++itor)
982  {
983  float64 t = std::fabs(*itor);
984  if( t > max)
985  {
986  max = t;
987  }
988  }
989 
990  return max;
991 }
992 
993 float64
994 Buffer::
995 getMean() const
996 {
997  float64 sum = getSum();
998 
999  return sum / static_cast<float64>(getLength());
1000 }
1001 
1002 float64
1003 Buffer::
1004 getMin() const
1005 {
1006  M_ASSERT_VALUE(data_.size(), >=, 1);
1007 
1008  float64 min = data_[0];
1009 
1010  for(const_iterator itor = data_.begin();
1011  itor != data_.end();
1012  ++itor)
1013  {
1014  if(*itor < min)
1015  {
1016  min = *itor;
1017  }
1018  }
1019 
1020  return min;
1021 }
1022 
1023 void
1024 Buffer::
1025 mul(const Buffer & buffer, uint32 offset, uint32 n_samples)
1026 {
1027  M_ASSERT_VALUE(offset, >=, 0);
1028  M_ASSERT_VALUE(offset, <, getLength());
1029 
1030  uint32 b0 = offset;
1031  uint32 b1 = 0;
1032 
1033  uint32 n = n_samples;
1034 
1035  if(n_samples == 0)
1036  {
1037  n = buffer.getLength();
1038  }
1039 
1040  b1 = b0 + n;
1041 
1042  if(b1 > getLength())
1043  {
1044  b1 = getLength();
1045  n = b1 - b0;
1046  }
1047 
1048  // Limit
1049  if(n > buffer.getLength())
1050  {
1051  b1 = b0 + buffer.getLength();
1052  }
1053 
1054  uint32 k = 0;
1055  for(uint32 i = b0; i < b1; ++i)
1056  {
1057  (*this)[i] *= buffer[k];
1058  ++k;
1059  }
1060 }
1061 
1062 void
1063 Buffer::
1065 {
1066  float64 peak = getMaxMagnitude();
1067 
1068  float64 scale = 1.0;
1069 
1070  if(peak != 0.0) scale = 1.0 / peak;
1071 
1072  *this *= scale;
1073 }
1074 
1075 Buffer
1076 Buffer::
1078 {
1079  float64 n = static_cast<float64>(N);
1080 
1081  Buffer y;
1082 
1083  uint32 length = getLength();
1084 
1085  for(uint32 i = 0; i < length; ++i)
1086  {
1087  float64 sum = 0.0;
1088 
1089  for(uint32 j = 0; j < N; ++j)
1090  {
1091  if(i + j < length - 1)
1092  {
1093  sum += ::fabs(data_[i + j]);
1094  }
1095  }
1096  sum /= n;
1097 
1098  y << sum;
1099 
1100  }
1101 
1102  return y;
1103 }
1104 
1105 float64
1106 Buffer::
1107 getStd() const
1108 {
1109  Buffer diff = *this - getMean();
1110 
1111  diff ^= 2.0;
1112 
1113  return ::sqrt(diff.getSum() / static_cast<float64>(getLength()));
1114 }
1115 
1116 float64
1117 Buffer::
1118 getSum() const
1119 {
1120  float64 sum = 0.0;
1121 
1122  for(const_iterator itor = data_.begin();
1123  itor != data_.end();
1124  ++itor)
1125  {
1126  sum += *itor;
1127  }
1128 
1129  return sum;
1130 }
1131 
1132 void
1133 Buffer::
1135 {
1136  // z = (x - mean(x)) / std(x)
1137 
1138  // We won't call getStd() to avoid calculatig the diff and mean twice.
1139 
1140  // z = (x - mean(x)) / sqrt( sum((x - mean(x))^2) / N)
1141 
1142  float64 mean = getMean();
1143 
1144  Buffer diff = *this - mean;
1145 
1146  float64 std = (diff*diff).getSum() / static_cast<float64>(getLength());
1147 
1148  std = ::sqrt(std);
1149 
1150  *this = diff / (std + 1e-20);
1151 }
1152 
1153 
1154 Buffer &
1155 Buffer::
1156 operator=(const Buffer & rhs_buffer)
1157 {
1158  if(this == &rhs_buffer) // If it is the same object, return it.
1159  {
1160  return *this;
1161  }
1162 
1163  data_ = rhs_buffer.data_;
1164 
1165  return *this;
1166 }
1167 
1169 Buffer::
1171 {
1172  BufferSelection bs(*this, bv);
1173 
1174  return bs;
1175 }
1176 
1177 boolean
1178 Buffer::
1179 operator==(const Buffer & rhs_buffer) const
1180 {
1181  if(data_.size() != rhs_buffer.data_.size())
1182  {
1183  return false;
1184  }
1185 
1186  for(uint32 i = 0; i < data_.size(); ++i)
1187  {
1188  if(data_[i] != rhs_buffer.data_[i])
1189  {
1190  return false;
1191  }
1192  }
1193 
1194  return true;
1195 }
1196 
1197 boolean
1198 Buffer::
1199 operator!=(const Buffer & rhs_buffer) const
1200 {
1201  if(data_.size() != rhs_buffer.data_.size())
1202  {
1203  return true;
1204  }
1205 
1206  for(uint32 i = 0; i < data_.size(); ++i)
1207  {
1208  if(data_[i] != rhs_buffer.data_[i])
1209  {
1210  return true;
1211  }
1212  }
1213 
1214  return false;
1215 }
1216 
1217 Buffer &
1218 Buffer::
1220 {
1221  return (*this) << rhs.getMono()[0];
1222 }
1223 
1224 Buffer &
1225 Buffer::
1226 operator<<(const Buffer & rhs_buffer)
1227 {
1228  if(this == & rhs_buffer)
1229  {
1230  uint32 size = getLength();
1231 
1232  for(uint32 i = 0; i < size; ++i)
1233  {
1234  data_.push_back(data_[i]);
1235  }
1236 
1237  return *this;
1238  }
1239 
1240  std::vector<float64>::const_iterator itor = rhs_buffer.data_.begin();
1241  std::vector<float64>::const_iterator end = rhs_buffer.data_.end();
1242 
1243  while(itor != end)
1244  {
1245  data_.push_back(*itor);
1246  ++itor;
1247  }
1248 
1249  return *this;
1250 }
1251 
1252 Buffer &
1253 Buffer::
1254 operator+=(const Buffer & rhs)
1255 {
1256  std::size_t N = std::min(getLength(), rhs.getLength());
1257  for(std::size_t i = 0; i < N; ++i) data_[i] += rhs.data_[i];
1258  return *this;
1259 }
1260 
1261 Buffer &
1262 Buffer::
1263 operator-=(const Buffer & rhs)
1264 {
1265  std::size_t N = std::min(getLength(), rhs.getLength());
1266  for(std::size_t i = 0; i < N; ++i) data_[i] -= rhs.data_[i];
1267  return *this;
1268 }
1269 
1270 Buffer &
1271 Buffer::
1272 operator*=(const Buffer & rhs)
1273 {
1274  std::size_t N = std::min(getLength(), rhs.getLength());
1275  for(std::size_t i = 0; i < N; ++i) data_[i] *= rhs.data_[i];
1276  return *this;
1277 }
1278 
1279 Buffer &
1280 Buffer::
1281 operator/=(const Buffer & rhs)
1282 {
1283  std::size_t N = std::min(getLength(), rhs.getLength());
1284  for(std::size_t i = 0; i < N; ++i) data_[i] /= rhs.data_[i];
1285  return *this;
1286 }
1287 
1288 Buffer &
1289 Buffer::
1290 operator^=(const Buffer & rhs)
1291 {
1292  std::size_t N = std::min(getLength(), rhs.getLength());
1293  for(std::size_t i = 0; i < N; ++i) data_[i] = std::pow(data_[i], rhs.data_[i]);
1294  return *this;
1295 }
1296 
1297 Buffer &
1298 Buffer::
1300 {
1301  for(auto & x : data_) x += d;
1302  return *this;
1303 }
1304 
1305 Buffer &
1306 Buffer::
1308 {
1309  for(auto & x : data_) x -= d;
1310  return *this;
1311 }
1312 
1313 Buffer &
1314 Buffer::
1316 {
1317  for(auto & x : data_) x *= d;
1318  return *this;
1319 }
1320 
1321 Buffer &
1322 Buffer::
1324 {
1325  for(auto & x : data_) x /= d;
1326  return *this;
1327 }
1328 
1329 Buffer &
1330 Buffer::
1332 {
1333  for(auto & x : data_) x = std::pow(x, d);
1334  return *this;
1335 }
1336 
1337 std::ostream &
1338 operator<<(std::ostream & out, const Buffer & rhs_buffer)
1339 {
1340  std::vector<float64>::const_iterator rhs = rhs_buffer.data_.begin();
1341  std::vector<float64>::const_iterator end = rhs_buffer.data_.end();
1342 
1343  while(rhs != end)
1344  {
1345  out << *rhs << endl;
1346  ++rhs;
1347  }
1348 
1349  return out;
1350 }
1351 
1352 //~ ///////////////////////////////////////////////////////////////////////////////
1353 //~ void
1354 //~ Buffer::
1355 //~ pitchShift(uint32 window_size, uint32 overlap_size, int32 n_bins_to_shift )
1356 //~ {
1357 //~ int32 length = this->getLength();
1358 //~
1359 //~ uint32 fft_size = FFTransform::roundUp2(window_size);
1360 //~
1361 //~ Buffer::const_iterator input = this->begin();
1362 //~ Buffer::const_iterator end = this->end();
1363 //~
1364 //~ DelayLine dl(1, window_size);
1365 //~
1366 //~ // First time, write window_size /2 zeros.
1367 //~ for(uint32 i = 0; i < window_size / 2; ++i)
1368 //~ {
1369 //~ dl.write(0.0);
1370 //~ }
1371 //~
1372 //~ // FIXME: what if window_size > getLength()?
1373 //~ // write window_size / 2 samples.
1374 //~ for(uint32 i = 0; i < window_size / 2; ++i)
1375 //~ {
1376 //~ dl.write(*input);
1377 //~ ++input;
1378 //~ }
1379 //~
1380 //~ uint32 input_done_count = 0;
1381 //~ boolean input_done = false;
1382 //~
1383 //~ Generator gen(1);
1384 //~ FFTransform fft(1);
1385 //~
1386 //~ //~ Buffer window = gen.drawWindowHanning(window_size);
1387 //~ Buffer window = gen.drawFatGaussian(window_size, 0.95);
1388 //~
1389 //~ Buffer y(length);
1390 //~
1391 //~ uint32 i = 0;
1392 //~ while(true)
1393 //~ {
1394 //~ // Grab a window of samples.
1395 //~ Buffer temp(window_size);
1396 //~
1397 //~ // Read the delay line.
1398 //~ for(uint32 j = 0; j < window_size; ++j)
1399 //~ {
1400 //~ temp << dl.read();
1401 //~ }
1402 //~
1403 //~ // Apply window.
1404 //~ temp *= window;
1405 //~
1406 //~ // Perform the FFT.
1407 //~ FFTChunkVector vec = fft.fft(temp, fft_size);
1408 //~
1409 //~ uint32 fft_length = vec[0].real_->getLength();
1410 //~
1411 //~ // Frequency Domain signal:
1412 //~ // xxxxxxxxxxxxxxxxxxxxxxxxx-yyyyyyyyyyyyyyyyyyyyyyyyyy
1413 //~ // ^
1414 //~ // the center
1415 //~
1416 //~ int32 center = fft_length / 2;
1417 //~
1418 //~ // Shift all the bins by n_bins_to_shift.
1419 //~ if(n_bins_to_shift >= 0)
1420 //~ {
1421 //~ // Shift the left half bins...
1422 //~ for(uint32 j = center - n_bins_to_shift;
1423 //~ j > 0;
1424 //~ --j)
1425 //~ {
1426 //~ vec[0].real_->operator[](j + n_bins_to_shift) =
1427 //~ vec[0].real_->operator[](j);
1428 //~
1429 //~ vec[0].imag_ ->operator[](j + n_bins_to_shift) =
1430 //~ vec[0].imag_->operator[](j);
1431 //~ }
1432 //~ }
1433 //~ else
1434 //~ {
1435 //~ // Shift the left half bins...
1436 //~ for(int32 j = 0; j < center + n_bins_to_shift; ++j)
1437 //~ {
1438 //~ vec[0].real_->operator[](j) =
1439 //~ vec[0].real_->operator[](j - n_bins_to_shift);
1440 //~
1441 //~ vec[0].imag_ ->operator[](j) =
1442 //~ vec[0].imag_->operator[](j - n_bins_to_shift);
1443 //~ }
1444 //~ }
1445 //~
1446 //~ --fft_length;
1447 //~ // Copy the left half into the right half.
1448 //~ for(int32 j = 0; j < center; ++j)
1449 //~ {
1450 //~ vec[0].real_->operator[](fft_length - j) =
1451 //~ vec[0].real_->operator[](j);
1452 //~
1453 //~ vec[0].imag_ ->operator[](fft_length - j) =
1454 //~ -1.0 * vec[0].imag_->operator[](j);
1455 //~ }
1456 //~
1457 //~ temp = fft.ifft(vec);
1458 //~
1459 //~ temp = temp.subbuffer(0, window_size);
1460 //~ temp *= window;
1461 //~
1462 //~ //~ if(i == 4096)
1463 //~ //~ {
1464 //~ //~ char title[1024];
1465 //~ //~
1466 //~ //~ sprintf(title, "i = %4d: y", i);
1467 //~ //~ y.plot(title);
1468 //~ //~
1469 //~ //~ sprintf(title, "i = %4d: temp", i);
1470 //~ //~ temp.plot(title);
1471 //~ //~ }
1472 //~
1473 //~ if(i >= overlap_size)
1474 //~ {
1475 //~ y.add(temp, y.getLength() - overlap_size);
1476 //~ }
1477 //~ else
1478 //~ {
1479 //~ y << temp;
1480 //~ }
1481 //~
1482 //~ static int nick = 0;
1483 //~
1484 //~ if(nick < 3)
1485 //~ {
1486 //~ ++nick;
1487 //~ y.plot();
1488 //~ }
1489 //~
1490 //~ //~ if(i == 4096)
1491 //~ //~ {
1492 //~ //~ char title[1024];
1493 //~ //~
1494 //~ //~ sprintf(title, "i = %4d: y + temp", i);
1495 //~ //~ y.plot(title);
1496 //~ //~ }
1497 //~
1498 //~ i += window_size;
1499 //~
1500 //~ // Read data for next loop.
1501 //~ if(input_done)
1502 //~ {
1503 //~ ++input_done_count;
1504 //~
1505 //~ if(input_done_count > 2) break;
1506 //~ }
1507 //~
1508 //~ // Read in next chunk of input samples.
1509 //~ for(uint32 j = 0; j < (window_size - overlap_size); ++j)
1510 //~ {
1511 //~ if(input == end)
1512 //~ {
1513 //~ input_done = true;
1514 //~
1515 //~ dl.read();
1516 //~ dl.write(0.0);
1517 //~ }
1518 //~ else
1519 //~ {
1520 //~ dl.read(); // move the read pointer.
1521 //~ dl.write(*input);
1522 //~ ++input;
1523 //~ }
1524 //~ }
1525 //~ }
1526 //~ //~
1527 //~ //~ float64 ratio = static_cast<float64>(this->getLength())
1528 //~ //~ / static_cast<float64>(y.getLength());
1529 //~ //~
1530 //~ //~ uint32 r = static_cast<uint32>((ratio + 0.005) * 100.0);
1531 //~ //~
1532 //~ //~ ratio = static_cast<float64>(r) / 100.0;
1533 //~ //~
1534 //~ //~ cout << "ratio = " << ratio << endl;
1535 //~
1536 //~ cout << "this->getLength() = " << this->getLength() << endl
1537 //~ << "y.getLength() = " << y.getLength() << endl;
1538 //~
1539 //~ *this = y;
1540 //~ }
1541 
1542 void
1543 Buffer::
1545 {
1546  data_.reserve(data_.size() + n);
1547 }
1548 
1549 void
1550 Buffer::
1551 plot(const string & title) const
1552 {
1553  Plotter pylab;
1554 
1555  pylab.figure();
1556  pylab.plot(*this);
1557  pylab.title(title);
1558 }
1559 
1560 void
1561 Buffer::
1562 readWavefile(const char * filename)
1563 {
1564  M_CHECK_PTR(filename);
1565 
1566  *this << filename;
1567 }
1568 
1569 void
1571  float64 fraction,
1572  float64 gamma,
1573  uint32 & a,
1574  uint32 & b)
1575 {
1576  float64 num = 1.0;
1577  float64 den = 1.0;
1578 
1579  float64 f = 1.0;
1580 
1581  float64 diff = f - fraction;
1582 
1583  while( fabs(diff) > gamma )
1584  {
1585  if(f > fraction)
1586  {
1587  den += 1.0;
1588  }
1589  else
1590  {
1591  num += 1.0;
1592  }
1593 
1594  f = num / den;
1595  diff = f - fraction;
1596  }
1597 
1598  a = static_cast<uint32>(num);
1599  b = static_cast<uint32>(den);
1600 }
1601 
1602 // Implementation based on the "Discrete-Time Signal Processing" book
1603 // Figure 4.28 on page 177 (Second Edition).
1604 //
1605 Buffer
1606 Buffer::
1608  float64 factor,
1609  const uint32 N,
1610  float64 beta) const
1611 {
1612  uint32 L = 0;
1613  uint32 M = 0;
1614 
1615  find_fraction(factor, 0.0001, L, M);
1616 
1617  return getResample(L,M,N,beta);
1618 }
1619 
1620 Buffer
1621 Buffer::
1623  const Buffer & factor,
1624  const uint32 N,
1625  float64 beta) const
1626 {
1627  BufferWindowSearch search(*this, 1024);
1628 
1629  uint32 pos = 0;
1630 
1631  Buffer y;
1632 
1633  while(search.getSamplesLeft() > 0)
1634  {
1635  Buffer window = search.getNextWindow();
1636 
1637  uint32 Lw = window.getLength();
1638 
1639  Buffer ratio = factor.subbuffer(pos, Lw);
1640 
1641  float64 r = ratio.getMean();
1642 
1643  y << window.getResample(r,N,beta);
1644 
1645  pos += Lw;
1646  }
1647 
1648  return y;
1649 }
1650 
1651 Buffer
1652 Buffer::
1654  const uint32 L,
1655  const uint32 M,
1656  const uint32 N,
1657  float64 beta) const
1658 {
1659  Buffer y;
1660 
1661  // If the Buffer is really long, break it up into window to reduce memory
1662  // usage.
1663  if(getLength() > 40000)
1664  {
1665  BufferWindowSearch search(*this, 2048);
1666 
1667  while(search.getSamplesLeft() > 0)
1668  {
1669  Buffer window = search.getNextWindow();
1670 
1671  y << window._get_resample(L,M,N,beta);
1672  }
1673  }
1674  else
1675  {
1676  y << _get_resample(L,M,N,beta);
1677  }
1678 
1679  return y;
1680 }
1681 
1682 Buffer
1683 Buffer::
1685  const uint32 L,
1686  const uint32 M,
1687  const uint32 N,
1688  float64 beta) const
1689 {
1690  if(L == 1 && M == 1)
1691  {
1692  return *this;
1693  }
1694 
1695  M_ASSERT_VALUE(L, !=, 0);
1696  M_ASSERT_VALUE(M, !=, 0);
1697  M_ASSERT_VALUE(N, !=, 0);
1698  M_ASSERT_VALUE(beta, >=, 0.0);
1699 
1700  uint32 LMmax = (L > M) ? L : M;
1701 
1702  float64 fc = 1.0 / 2.0 / static_cast<float64>(LMmax);
1703 
1704  // ensure kernel length is a multiple of L
1705  uint32 Lh = 2 * N * LMmax;
1706 
1707  float64 sr = 1000.0; // arbitrary, but usefull if the filter is plotted.
1708 
1709  Buffer f(4);
1710  Buffer a(4);
1711 
1712  f << 0.0 << sr * fc << sr * fc << sr * 0.5;
1713  a << 1.0 << 1.0 << 0.0 << 0.0;
1714 
1715  FilterLeastSquaresFIR lpf(sr, Lh, f, a, beta);
1716 
1717  uint32 delay = (Lh-1)/2;
1718 
1719  // Create Polyphase filter bank if interpolating
1720  std::vector<FilterLeastSquaresFIR> bank;
1721  if(L > 1)
1722  {
1723  // Get the kernel.
1724  Buffer h = lpf.getKernel();
1725 
1726  Buffer pseudo_f(2);
1727  Buffer pseudo_a(2);
1728 
1729  pseudo_f << 0.0 << 0.5;
1730  pseudo_a << 0.0 << 0.0;
1731 
1732  for(uint32 i = 0; i < L; ++i)
1733  {
1734  FilterLeastSquaresFIR poly_f(1.0, L, pseudo_f, pseudo_a, beta);
1735 
1736  Buffer poly_h(Lh / L);
1737 
1738  // Pull out cooefficents for the polyphase filter
1739  for(int32 j = Lh - L; j >= 0 && j < static_cast<int32>(Lh); j -= L)
1740  {
1741  poly_h << h[j + i];
1742  }
1743 
1744  poly_f.setKernel(poly_h.getReverse());
1745 
1746  bank.push_back(poly_f);
1747  }
1748  }
1749 
1750  uint32 n_filters = static_cast<uint32>(bank.size());
1751 
1752  // Interpolation
1753 
1754  Buffer::const_iterator x = data_.begin();
1755  Buffer::const_iterator x_end = data_.end();
1756 
1757  uint32 Lx = getLength();
1758  uint32 Ly = getLength() * L / M;
1759 
1760  Buffer y(Ly);
1761 
1762  if(L > 1)
1763  {
1764 //~ cerr << "Interpolation by " << L << endl << flush;
1765 
1766  float64 scale = static_cast<float64>(L);
1767 
1768  // Loop over all the samples
1769  while(x != x_end)
1770  {
1771  // Polyphase filter the input, for all L-1 samples
1772  for(uint32 j = 0; j < L; ++j)
1773  {
1774  float64 sample = *x * scale;
1775 
1776  for(uint32 k = 0; k < n_filters; ++k)
1777  {
1778  y << bank[k].filter(sample);
1779  }
1780  ++x;
1781  if(x == x_end) break;
1782  }
1783 
1784  // Add some samples to the end for filter delay compansation.
1785  if(x == x_end)
1786  {
1787  float64 x_n = data_[Lx - 1] * scale;
1788 
1789  for(uint32 j = 0; j < Lh/L; ++j)
1790  {
1791  for(uint32 k = 0; k < n_filters; ++k)
1792  {
1793  y << bank[k].filter(x_n);
1794  }
1795  }
1796  break;
1797  }
1798  }
1799  }
1800 
1801  // Only down sampling, still need to filter.
1802  else
1803  {
1804  for(uint32 i = 0; i < Lx; ++i)
1805  {
1806  y << lpf.filter(data_[i]);
1807  }
1808 
1809  // Add some samples to the end for filter delay compansation.
1810  float64 x_n = data_[Lx - 1];
1811  for(uint32 i = 0; i < Lh; ++i)
1812  {
1813  y << lpf.filter(x_n);
1814  }
1815  }
1816 
1817  // Compensate for filter delay.
1818  y = y.subbuffer(delay, Lx*L);
1819 
1820  // Decimation
1821  if(M > 1)
1822  {
1823 //~ cerr << "Decimation by " << M << endl << flush;
1824 
1825  x = y.begin();
1826  x_end = y.end();
1827 
1828  Buffer y2(Ly / M);
1829 
1830  uint32 i = 0;
1831  while(x != x_end)
1832  {
1833  if(i % M == 0)
1834  {
1835  y2 << *x;
1836  }
1837 
1838  ++x;
1839  ++i;
1840  }
1841 
1842  y = y2;
1843  }
1844 
1845  return y;
1846 }
1847 
1848 void
1849 Buffer::
1851 {
1852  for(uint32 front = 0, back = getLength() - 1;
1853  front < back;
1854  ++front, --back)
1855  {
1856  float64 temp = data_[front];
1857  data_[front] = data_[back];
1858  data_[back] = temp;
1859  }
1860 }
1861 
1862 void
1863 Buffer::
1865 {
1866  for(Buffer::iterator i = this->begin();
1867  i != this->end();
1868  ++i)
1869  {
1870  *i = std::floor(*i + 0.5);
1871  }
1872 }
1873 
1874 void
1875 Buffer::
1877 {
1878  int32 len = getLength();
1879 
1880  if(index >= 0 && index < len)
1881  {
1882  data_[index] = d;
1883  }
1884  else if(index < 0 && index >= -len)
1885  {
1886  data_[len + index] = d;
1887  }
1888  else
1889  {
1890  M_THROW(
1891  "IndexError: " << index << " is out of bounds (0 : " << len << ")");
1892  }
1893 }
1894 
1896 Buffer::
1897 select(const uint32 start_index, const uint32 stop_index)
1898 {
1899  uint32 n_samples = getLength();
1900 
1901  BooleanVector bv;
1902 
1903  bv.reserve(n_samples);
1904 
1905  for(uint32 i = 0; i < n_samples; ++i)
1906  {
1907  if( i >= start_index && i <= stop_index)
1908  {
1909  bv.push_back(true);
1910  }
1911  else
1912  {
1913  bv.push_back(false);
1914  }
1915  }
1916 
1917  return BufferSelection(*this, bv);
1918 }
1919 
1920 std::ostream &
1921 Buffer::
1922 write(std::ostream & out) const
1923 {
1924  out & 'b' & 'u' & 'f' & 'f' & getLength();
1925 
1926  for(uint32 i = 0; i < getLength(); ++i)
1927  {
1928  out & data_[i];
1929  }
1930 
1931  return out;
1932 }
1933 
1934 std::string
1935 Buffer::
1936 write() const
1937 {
1938  std::stringstream ss;
1939  write(ss);
1940  return ss.str();
1941 }
1942 
1943 std::istream &
1944 Buffer::
1945 read(std::istream & in)
1946 {
1947  char id[4];
1948  uint32 size = 0;
1949 
1950  in & id[0] & id[1] & id[2] & id[3] & size;
1951 
1952  if(id[0] != 'b' || id[1] != 'u' || id[2] != 'f' || id[3] != 'f')
1953  {
1954  M_THROW("Did not find any Nsound Buffer data in input stream!");
1955  }
1956 
1957  data_.clear();
1958  data_.reserve(size);
1959 
1960  for(uint32 i = 0; i < size; ++i)
1961  {
1962  float64 d;
1963  in & d;
1964  data_.push_back(d);
1965  }
1966 
1967  return in;
1968 }
1969 
1970 void
1971 Buffer::
1972 read(const std::string & in)
1973 {
1974  std::stringstream ss(in);
1975 
1976  read(ss);
1977 }
1978 
1979 void
1980 Buffer::
1981 smooth(uint32 n_passes, uint32 n_samples_to_average)
1982 {
1983  if(n_samples_to_average < 2)
1984  {
1985  return;
1986  }
1987 
1988  FilterMovingAverage maf(n_samples_to_average);
1989 
1990  Buffer::iterator end = this->end();
1991 
1992  for(uint32 i = 0; i < n_passes; ++i)
1993  {
1994  maf.reset();
1995 
1996  Buffer::iterator itor = this->begin();
1997 
1998  while(itor != end)
1999  {
2000  *itor = maf.filter(*itor);
2001  ++itor;
2002  }
2003  }
2004 }
2005 
2006 void
2007 Buffer::
2008 speedUp(float64 step_size)
2009 {
2010  Buffer new_buffer;
2011 
2012  float64 n_samples = static_cast<float64>(data_.size());
2013 
2014  for(float64 i = 0.0; i < n_samples; i += step_size)
2015  {
2016  new_buffer << data_[static_cast<uint32>(i)];
2017  }
2018 
2019  *this = new_buffer;
2020 }
2021 
2022 void
2023 Buffer::
2024 speedUp(const Buffer & step_buffer)
2025 {
2026  Buffer new_buffer;
2027 
2028  float64 n_samples = static_cast<float64>(getLength());
2029  uint32 step_buffer_size = step_buffer.getLength();
2030 
2031  uint32 step_buffer_index = 0;
2032  float64 step_size = 0.0;
2033 
2034  for(float64 i = 0.0; i < n_samples; i += step_size)
2035  {
2036  new_buffer << data_[static_cast<size_t>(i)];
2037 
2038  step_size = step_buffer[step_buffer_index++];
2039 
2040  if(step_buffer_index >= step_buffer_size)
2041  {
2042  step_buffer_index -= step_buffer_size;
2043  }
2044  }
2045 
2046  *this = new_buffer;
2047 }
2048 
2049 void
2050 Buffer::
2052 {
2053  Buffer::iterator itor = this->begin();
2054  Buffer::iterator end = this->end();
2055 
2056  while(itor != end)
2057  {
2058  float64 v = *itor;
2059  if(v > 0.0)
2060  {
2061  *itor = std::sqrt(v);
2062  }
2063  else if(v < 0.0)
2064  {
2065  *itor = -std::sqrt(-v);
2066  }
2067  ++itor;
2068  }
2069 }
2070 
2071 Buffer
2072 Buffer::
2073 subbuffer(uint32 start_index, uint32 n_samples) const
2074 {
2075  uint32 n = n_samples;
2076 
2077  if(n > getLength()) n = getLength();
2078 
2079  Buffer new_buffer(n);
2080 
2081  if(start_index >= getLength())
2082  return new_buffer;
2083 
2084  uint32 stop_index = start_index + n;
2085 
2086  if(n == 0 || stop_index >= getLength())
2087  {
2088  stop_index = getLength();
2089  }
2090 
2091  for(uint32 i = start_index; i < stop_index; ++i)
2092  {
2093  new_buffer << data_[i];
2094  }
2095 
2096  return new_buffer;
2097 }
2098 
2099 void
2100 Buffer::
2102 {
2103  *this = getUpSample(n);
2104 }
2105 
2106 // This is based on the upsampling description in "Descrete-Time Signal
2107 // Processing" 2nd Eddition aka "the Oppenheim book". Section 4.6.2 page 172.
2108 //
2109 Buffer
2110 Buffer::
2112 {
2113  return getResample(L,static_cast<uint32>(1));
2114 }
2115 
2116 void
2117 Buffer::
2118 writeWavefile(const char * filename) const
2119 {
2120  M_CHECK_PTR(filename);
2121 
2122  operator>>(*this, filename);
2123 }
2124 
2126 Buffer::
2128 {
2129  BooleanVector bv;
2130 
2131  Buffer::const_iterator itor = this->begin();
2132  Buffer::const_iterator end = this->end();
2133 
2134  while(itor != end)
2135  {
2136  if(*itor > rhs) bv.push_back(true);
2137  else bv.push_back(false);
2138  ++itor;
2139  }
2140 
2141  return bv;
2142 }
2143 
2145 Buffer::
2147 {
2148  BooleanVector bv;
2149 
2150  Buffer::const_iterator itor = this->begin();
2151  Buffer::const_iterator end = this->end();
2152 
2153  while(itor != end)
2154  {
2155  if(*itor >= rhs) bv.push_back(true);
2156  else bv.push_back(false);
2157  ++itor;
2158  }
2159 
2160  return bv;
2161 }
2162 
2164 Buffer::
2166 {
2167  BooleanVector bv;
2168 
2169  Buffer::const_iterator itor = this->begin();
2170  Buffer::const_iterator end = this->end();
2171 
2172  while(itor != end)
2173  {
2174  if(*itor < rhs) bv.push_back(true);
2175  else bv.push_back(false);
2176  ++itor;
2177  }
2178 
2179  return bv;
2180 }
2181 
2183 Buffer::
2185 {
2186  BooleanVector bv;
2187 
2188  Buffer::const_iterator itor = this->begin();
2189  Buffer::const_iterator end = this->end();
2190 
2191  while(itor != end)
2192  {
2193  if(*itor <= rhs) bv.push_back(true);
2194  else bv.push_back(false);
2195  ++itor;
2196  }
2197 
2198  return bv;
2199 }
2200 
2202 Buffer::
2204 {
2205  BooleanVector bv;
2206 
2207  Buffer::const_iterator itor = this->begin();
2208  Buffer::const_iterator end = this->end();
2209 
2210  while(itor != end)
2211  {
2212  bv.push_back(*itor == rhs);
2213  ++itor;
2214  }
2215 
2216  return bv;
2217 }
2218 
2220 Buffer::
2222 {
2223  BooleanVector bv;
2224 
2225  Buffer::const_iterator itor = this->begin();
2226  Buffer::const_iterator end = this->end();
2227 
2228  while(itor != end)
2229  {
2230  bv.push_back(*itor != rhs);
2231  ++itor;
2232  }
2233 
2234  return bv;
2235 }
2236 
2237 Buffer
2238 Buffer::
2239 ones(const uint32 n_samples)
2240 {
2241  Buffer b(n_samples);
2242 
2243  Generator g(1);
2244 
2245  b << g.drawLine(n_samples, 1.0, 1.0);
2246 
2247  return b;
2248 }
2249 
2250 Buffer
2251 Buffer::
2252 rand(const uint32 n_samples)
2253 {
2254  Buffer b(n_samples);
2255 
2256  Generator g(1);
2257 
2258  b << g.whiteNoise(n_samples);
2259 
2260  return b;
2261 }
2262 
2263 Buffer
2264 Buffer::
2265 zeros(const uint32 n_samples)
2266 {
2267  Buffer b(n_samples);
2268 
2269  Generator g(1);
2270 
2271  b << g.drawLine(n_samples, 0.0, 0.0);
2272 
2273  return b;
2274 }
2275 
2276 } // namespace
Buffer subbuffer(uint32 start_index, uint32 n_samples=0) const
Slice the Buffer.
Definition: Buffer.cc:2073
unsigned int uint32
Definition: Nsound.h:153
#define M_ASSERT_VALUE(a, op, value)
Definition: Macros.h:76
std::ostream & operator<<(std::ostream &out, const Buffer &rhs_buffer)
Definition: Buffer.cc:1338
float64 getStd() const
Returns the standard deviation of the Buffer.
Definition: Buffer.cc:1107
boolean operator!=(const Buffer &rhs) const
Tests of inequality.
Definition: Buffer.cc:1199
void readWavefile(const char *filename)
Sets this Buffer to the contents of the wavefile on the disk.
Definition: Buffer.cc:1562
boolean operator==(const Buffer &rhs) const
Tests of equality.
Definition: Buffer.cc:1179
void dB()
Modifies the Buffer so each sample is converted to dB, 20 * log10(sample).
Definition: Buffer.cc:567
Buffer getConvolve(const Buffer &H) const
Convolves a copy of the Buffer with another Buffer.
Definition: Buffer.cc:527
Buffer()
Creates an empty Buffer that also calss std::vector::reserve() to preallocate memory for samples...
Definition: Buffer.cc:62
void plot(const Buffer &y, const std::string &fmt="", const std::string &kwargs="")
Plots the Buffer on the current figure.
Definition: Plotter.cc:765
AudioStream filter(const AudioStream &x)
Buffer getDownSample(uint32 n) const
Returns a copy of this Buffer downsampled by a integral factor. N must be > 1.
Definition: Buffer.cc:615
std::vector< float64 > FloatVector
Buffer getSignalEnergy(uint32 window_size) const
Returns the signal energy: E = 1 / N * sum(|x(i)|) over the window of N samples.
Definition: Buffer.cc:1077
void log10()
Sets each sample in the Buffer to log base 10.
Definition: Buffer.cc:936
void preallocate(uint32 n)
Preallocates memory to hold an additional n samples.
Definition: Buffer.cc:1544
void downSample(uint32 n)
Downsample this Buffer by a integral factor. N must be > 1.
Definition: Buffer.cc:605
static Buffer zeros(const uint32 n_samples)
Returns a Buffer full of zeros of length n_samples.
Definition: Buffer.cc:2265
Buffer & operator/=(const Buffer &rhs)
Divides each sample in this Buffer with the right hand side (rhs) Buffer.
Definition: Buffer.cc:1281
BufferSelection operator()(const BooleanVector &bv)
Returns a BufferSelection object used for manipulation of a selected region of samples.
Definition: Buffer.cc:1170
void figure(const std::string &kwargs="") const
Creates a new figure window to plot in.
Definition: Plotter.cc:455
Buffer & operator=(const Buffer &rhs)
The assignment operator. C++ only, for Python, use the copy constructor.
Definition: Buffer.cc:1156
void plot(const std::string &title="Buffer") const
Requires matplotlib. Creates a plot of this Buffer.
Definition: Buffer.cc:1551
void title(const std::string &title, const std::string &kwargs="")
Add a title to the plot at the top and centered.
Definition: Plotter.cc:1127
#define M_CHECK_PTR(ptr)
Definition: Macros.h:64
float64 getMean() const
Returns the mean sample value in the Buffer.
Definition: Buffer.cc:995
std::istream & read(std::istream &stream_in)
Constructs a Buffer from seralized data in the inputstream.
Definition: Buffer.cc:1945
void limit(float64 min, float64 max)
Limits the Buffer to min and max.
Definition: Buffer.cc:876
double float64
Definition: Nsound.h:146
void writeWavefile(const char *filename) const
Writes the Buffer to a Wavefile.
Definition: Buffer.cc:2118
circular_iterator cbegin()
Retruns the itreator at the start of the Buffer.
Definition: Buffer.h:318
float64 getMaxMagnitude() const
Returns the maximum magnitude value in the Buffer, i.e. max(abs(samples)).
Definition: Buffer.cc:973
void _set_at_index(int32 index, float64 x)
SWIG helper function function to shadow.
Definition: Buffer.cc:1876
uint32 getLength() const
Returns the number of samples in the Buffer.
Definition: Buffer.h:587
#define LM_MAX(a, b)
Definition: Buffer.cc:919
Buffer getNextWindow()
Searches the target Buffer for a zero crossing at or after the window_size position.
void find_fraction(float64 fraction, float64 gamma, uint32 &a, uint32 &b)
Definition: Buffer.cc:1570
void convolve(const Buffer &H)
Convolves the Buffer with another Buffer.
Definition: Buffer.cc:520
iterator end()
Retruns the itreator at the end of the Buffer.
Definition: Buffer.h:348
void operator>>(const AudioStream &lhs, AudioPlayback &rhs)
FloatVector::const_iterator const_iterator
Definition: Buffer.h:70
void zNorm()
Normalized the Buffer using Z score normalizing.
Definition: Buffer.cc:1134
std::string write() const
Definition: Buffer.cc:1936
void smooth(uint32 n_passes, uint32 n_samples_per_average)
Applies a moving average filter to smooth this Buffer.
Definition: Buffer.cc:1981
iterator begin()
Retruns the itreator at the start of the Buffer.
Definition: Buffer.h:285
BooleanVector operator<(float64 rhs)
Creates a BooleanVector where each value is true iff Buffer[n] < rhs.
Definition: Buffer.cc:2165
static Buffer ones(const uint32 n_samples)
Returns a Buffer full of ones of length n_samples.
Definition: Buffer.cc:2239
void speedUp(float64 step_size)
Resamples this Buffer by the step_size, no interpolation.
Definition: Buffer.cc:2008
void reverse()
Reverses the samples in this Buffer.
Definition: Buffer.cc:1850
void normalize()
Multiplies the Buffer by a constant gain so the peak sample has magnitude 1.0.
Definition: Buffer.cc:1064
std::vector< uint32 > Uint32Vector
#define M_THROW(message)
Definition: Macros.h:108
static Buffer rand(const uint32 n_samples)
Returns a Buffer full of random values of length n_samples.
Definition: Buffer.cc:2252
void exp()
Each sample in the Buffer becomes the power e^x.
Definition: Buffer.cc:510
Buffer & operator^=(const Buffer &powers)
Each sample in the Buffer becomes the power x^n.
Definition: Buffer.cc:1290
uint32 argmin() const
Retruns the index of the minimum value in the Buffer.
Definition: Buffer.cc:485
Buffer & operator*=(const Buffer &rhs)
Multiplies each sample from the right hand side (rhs) with this Buffer.
Definition: Buffer.cc:1272
void abs()
Modifies the Buffer by making any negative value positive.
Definition: Buffer.cc:119
BufferSelection select(const uint32 start_index, const uint32 stop_index)
Returns a BufferSelection for the range of indicies.
Definition: Buffer.cc:1897
AudioStream filter(const AudioStream &x)
float64 getSum() const
Returns the sum of all samples.
Definition: Buffer.cc:1118
void sqrt()
Takes the square root of each sample in this Buffer.
Definition: Buffer.cc:2051
A Buffer for storing audio samples.
Definition: Buffer.h:60
Buffer getUpSample(uint32 n) const
Upsample a copy of this Buffer by a integral factor. N must be > 1.
Definition: Buffer.cc:2111
BooleanVector operator<=(float64 rhs)
Creates a BooleanVector where each value is true iff Buffer[n] <= rhs.
Definition: Buffer.cc:2184
std::vector< boolean > BooleanVector
Buffer whiteNoise(const float64 &duration) const
This method generates noise from a uniform distribution.
Definition: Generator.cc:1325
signed int int32
Definition: Nsound.h:142
float64 getMin() const
Returns the minimum sample value in the Buffer.
Definition: Buffer.cc:1004
void round()
Rounds the samples in this Buffer to the nearest integer value.
Definition: Buffer.cc:1864
Buffer _get_resample(const uint32 L, const uint32 M, const uint32 N, float64 beta) const
Definition: Buffer.cc:1684
A FIR filter that is defined as the least square error to the desired requency response.
Buffer getResample(float64 factor, const uint32 N=10, float64 beta=5.0) const
Resamples a copy of this Buffer using discrete-time resampling.
Definition: Buffer.cc:1607
AudioStream getMono() const
Collapses all channels into one Buffer making it mono.
Definition: AudioStream.cc:265
Buffer & operator-=(const Buffer &rhs)
Subracts each sample from the right hand side (rhs) Buffer from this Buffer.
Definition: Buffer.cc:1263
void upSample(uint32 n)
Upsample this Buffer by a integral factor. N must be > 1.
Definition: Buffer.cc:2101
FloatVector::iterator iterator
Definition: Buffer.h:69
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
Buffer & operator+=(const Buffer &rhs)
Adds each sample from the right hand side (rhs) Buffer with this Buffer.
Definition: Buffer.cc:1254
Searches the target Buffer for zero crossings at or after the window_size position.
void add(const Buffer &buffer, uint32 offset=0, uint32 n_samples=0)
This method adds buffer to *this.
Definition: Buffer.cc:225
uint32 getSamplesLeft() const
Returns how many samples are left in the target Buffer.
Buffer getReverse() const
Reverses the samples in a copy of this Buffer.
Definition: Buffer.h:1558
BooleanVector operator>=(float64 rhs)
Creates a BooleanVector where each value is true iff Buffer[n] >= rhs.
Definition: Buffer.cc:2146
~Buffer()
Destroys the Buffer.
Definition: Buffer.cc:112
Uint32Vector findPeaks(uint32 window_size=0, float64 min_height=0.0) const
Find the peaks in the Buffer and return a vector of indicies.
Definition: Buffer.cc:623
BooleanVector operator>(float64 rhs)
Creates a BooleanVector where each value is true iff Buffer[n] > rhs.
Definition: Buffer.cc:2127
A helper class for advance operators.
Buffer & operator<<(const AudioStream &rhs)
Concatenates Buffers and AudioStreams together.
Definition: Buffer.cc:1219
FloatVector data_
Definition: Buffer.h:1874
A class the provides draw utilities and a wavetable oscillator.
Definition: Generator.h:50
float64 sr
Definition: example3.cc:24
void derivative(uint32 n)
Calculates the nth derivative of the Buffer.
Definition: Buffer.cc:592
uint32 argmax() const
Retruns the index of the maximum value in the Buffer.
Definition: Buffer.cc:460
void mul(const Buffer &buffer, uint32 offset=0, uint32 n_samples=0)
This method multiplies a Buffer to *this over a sub range.
Definition: Buffer.cc:1025
void log()
Sets each sample in the Buffer to the natural log.
Definition: Buffer.cc:923