Nsound  0.9.4
BufferWindowSearch.cc
Go to the documentation of this file.
1 //-----------------------------------------------------------------------------
2 //
3 // $Id: BufferWindowSearch.cc 874 2014-09-08 02:21:29Z weegreenblobbie $
4 //
5 // Nsound is a C++ library and Python module for audio synthesis featuring
6 // dynamic digital filters. Nsound lets you easily shape waveforms and write
7 // to disk or plot them. Nsound aims to be as powerful as Csound but easy to
8 // use.
9 //
10 // Copyright (c) 2009-Present Nick Hilton
11 //
12 // weegreenblobbie_yahoo_com (replace '_' with '@' and '.')
13 //
14 //-----------------------------------------------------------------------------
15 
16 //-----------------------------------------------------------------------------
17 //
18 // This program is free software; you can redistribute it and/or modify
19 // it under the terms of the GNU General Public License as published by
20 // the Free Software Foundation; either version 2 of the License, or
21 // (at your option) any later version.
22 //
23 // This program is distributed in the hope that it will be useful,
24 // but WITHOUT ANY WARRANTY; without even the implied warranty of
25 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26 // GNU Library General Public License for more details.
27 //
28 // You should have received a copy of the GNU General Public License
29 // along with this program; if not, write to the Free Software
30 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
31 //
32 //-----------------------------------------------------------------------------
33 
34 #include <Nsound/Buffer.h>
36 
37 #include <Nsound/Plotter.h>
38 
39 #include <cmath>
40 #include <iostream>
41 
42 using namespace Nsound;
43 
44 using std::cerr;
45 using std::endl;
46 
47 //-----------------------------------------------------------------------------
49 BufferWindowSearch(const Buffer & target, uint32 window_size)
50  :
51  target_buffer_(&target),
52  window_size_(window_size),
53  position_(0)
54 {
56 };
57 
58 //-----------------------------------------------------------------------------
61  :
62  target_buffer_(copy.target_buffer_),
63  window_size_(copy.window_size_),
64  position_(copy.position_)
65 {
66 };
67 
68 //-----------------------------------------------------------------------------
72 {
73  if(this == &rhs)
74  {
75  return *this;
76  }
77 
80  position_ = rhs.position_;
81 
82  return *this;
83 };
84 
85 Buffer
88 {
89  enum State
90  {
91  INIT,
92  POS,
93  NEG,
94  END,
95  DONE
96  };
97 
98  //~ std::string STRINGS[5] = { "init", "pos", "neg", "end", "done" };
99 
100  State s = INIT;
101 
102  uint32 next_pos = position_ + window_size_;
103 
104  //~ Plotter pylab;
105  //~
106  //~ boolean debug_plot = false;
107  //~
108  //~ if(next_pos == 0)
109  //~ {
110  //~ Buffer x_axis;
111  //~ for(uint32 i = next_pos; i < next_pos + 100; ++i)
112  //~ {
113  //~ x_axis << i;
114  //~ }
115  //~
116  //~ pylab.plot(x_axis, target_buffer_->subbuffer(next_pos, 100));
117  //~
118  //~ pylab.title("window 26303");
119  //~
120  //~ pylab.hold(true);
121  //~
122  //~ debug_plot = true;
123  //~ }
124 
125  //~ cerr << "position_ = " << position_
126  //~ << " start = " << next_pos;
127 
129 
130  // Are we off the end?
131  if(next_pos >= end)
132  {
134  position_ = end;
135  return w;
136  }
137 
138  // DEBUG
139  Buffer x(1);
140  Buffer y(1);
141  x << next_pos;
142  y << (*target_buffer_)[next_pos];
143 
144 
145  // Initalize the state.
146  if((*target_buffer_)[next_pos] > 0.0)
147  {
148  s = POS;
149  //~ if(debug_plot) pylab.plot(x,y, "g+");
150  }
151  else if((*target_buffer_)[next_pos] < 0.0)
152  {
153  s = NEG;
154  //~ if(debug_plot) pylab.plot(x,y, "r+");
155  }
156  else
157  {
158  s = DONE;
159  }
160 
161  //~ cerr << " state = " << STRINGS[s];
162 
163  State last_s = s;
164 
165  while(last_s == s)
166  {
167  last_s = s;
168 
169  ++next_pos;
170 
171  //~ if(next_pos > position_ + window_size_ + 200 ) debug_plot = false;
172  //~
173  //~ // DEBUG
174  //~ x = Buffer(1);
175  //~ y = Buffer(1);
176  //~ x << next_pos;
177  //~ y << (*target_buffer_)[next_pos];
178 
179  // Are we off the end?
180  if(next_pos >= end)
181  {
182  Buffer w = target_buffer_->subbuffer(position_);
183  position_ = end;
184  return w;
185  }
186 
187  // Update state.
188  if((*target_buffer_)[next_pos] > 0.0)
189  {
190  s = POS;
191  //~ if(debug_plot) pylab.plot(x,y, "g+");
192  }
193  else if((*target_buffer_)[next_pos] < 0.0)
194  {
195  s = NEG;
196  //~ if(debug_plot) pylab.plot(x,y, "r+");
197  }
198  else
199  {
200  break;
201  }
202  }
203 
204  // Pick the sample that is closest to zero.
205  if( std::fabs((*target_buffer_)[next_pos-1]) <
206  std::fabs((*target_buffer_)[next_pos]))
207  {
208  --next_pos;
209  }
210 
211  //~ cerr << " state = " << STRINGS[s];
212  //~ cerr << " n_samples_ = " << next_pos - position_ << endl;
213 
214  Buffer w = target_buffer_->subbuffer(position_, next_pos - position_);
215 
216  position_ = next_pos;
217 
218  return w;
219 }
220 
221 uint32
224 {
225  return target_buffer_->getLength() - position_;
226 }
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
uint32 getLength() const
Returns the number of samples in the Buffer.
Definition: Buffer.h:587
Buffer getNextWindow()
Searches the target Buffer for a zero crossing at or after the window_size position.
BufferWindowSearch & operator=(const BufferWindowSearch &rhs)
BufferWindowSearch(const Buffer &buffer, uint32 window_size=2048)
A Buffer for storing audio samples.
Definition: Buffer.h:60
Searches the target Buffer for zero crossings at or after the window_size position.
uint32 getSamplesLeft() const
Returns how many samples are left in the target Buffer.