Nsound  0.9.4
EnvelopeAdsr.cc
Go to the documentation of this file.
1 //
3 // $Id: EnvelopeAdsr.cc 833 2014-05-01 02:41:25Z weegreenblobbie $
4 //
5 // Copyright (c) 2005-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>
31 #include <Nsound/EnvelopeAdsr.h>
32 #include <Nsound/Generator.h>
33 
34 #include <iostream>
35 
36 using namespace Nsound;
37 
40  const float64 & sample_rate,
41  const float64 & attack_time,
42  const float64 & delay_time,
43  const float64 & sustain_amplitude,
44  const float64 & release_time)
45  :
46  sample_rate_(sample_rate),
47  attack_slope_(0.0),
48  attack_time_(attack_time),
49  delay_slope_(0.0),
50  delay_time_(delay_time),
51  sustain_amp_(sustain_amplitude),
52  release_slope_(0.0),
53  release_time_(release_time),
54  scale_(0.0),
55  mode_(attacking)
56 {
57  M_ASSERT_VALUE(sample_rate, >, 0.0);
58  M_ASSERT_VALUE(attack_time, >=, 0.0);
59  M_ASSERT_VALUE(delay_time, >=, 0.0);
60  M_ASSERT_VALUE(sustain_amplitude, >, 0.0);
61  M_ASSERT_VALUE(sustain_amplitude, <=, 1.0);
62  M_ASSERT_VALUE(release_time, >=, 0.0);
63 
64  M_ASSERT_VALUE(attack_time + delay_time + release_time, >, 0.0);
65 
66  setAttackTime(attack_time);
67  setDelayTime(delay_time);
68  setReleaseTime(release_time);
69 }
70 
71 void
74 {
75  mode_ = attacking;
76  scale_ = 0.0;
77 }
78 
79 void
81 setAttackTime(const float64 & time)
82 {
83  M_ASSERT_VALUE(time, >=, 0.0);
84 
85  uint32 n_samples = static_cast<uint32>(time * sample_rate_ + 0.5);
86 
87  n_samples -= 1;
88 
89  M_ASSERT_VALUE(n_samples, >, 0);
90 
91  attack_slope_ = 1.0 / static_cast<float64>(n_samples);
92  attack_time_ = time;
93 }
94 
95 void
97 setDelayTime(const float64 & time)
98 {
99  M_ASSERT_VALUE(time, >=, 0.0);
100 
101  uint32 n_samples = static_cast<uint32>(time * sample_rate_ + 0.5);
102 
103  n_samples -= 1;
104 
105  M_ASSERT_VALUE(n_samples, >, 0);
106 
107  delay_slope_ = -1.0 / static_cast<float64>(n_samples);
108  delay_time_ = time;
109 }
110 
111 void
114 {
115  M_ASSERT_VALUE(amp, >, 0.0);
116 
117  sustain_amp_ = amp;
118 }
119 
120 void
122 setReleaseTime(const float64 & time)
123 {
124  M_ASSERT_VALUE(time, >=, 0.0);
125 
126  uint32 n_samples = static_cast<uint32>(time * sample_rate_ + 0.5);
127 
128  n_samples -= 1;
129 
130  M_ASSERT_VALUE(n_samples, >, 0);
131 
132  release_slope_ = -1.0 / static_cast<float64>(n_samples);
133  release_time_ = time;
134 }
135 
138 shape(const AudioStream & as)
139 {
140  AudioStream out(as.getSampleRate(), as.getNChannels());
141 
142  for(uint32 i = 0; i < as.getNChannels(); ++i)
143  {
144  out[i] = shape(as[i]);
145  }
146 
147  return out;
148 }
149 
150 Buffer
152 shape(const Buffer & buf)
153 {
154  float64 duration = static_cast<float64>(buf.getLength()) / sample_rate_;
155 
156  float64 sustain_time =
157  duration - attack_time_ - delay_time_ - release_time_;
158 
159  if(sustain_time < 0) sustain_time = 0;
160 
161  uint32 sustain_samples = static_cast<uint32>(sustain_time * sample_rate_);
162 
163  mode_ = attacking;
164 
165  Buffer::const_iterator itor = buf.begin();
166  Buffer::const_iterator end = buf.end();
167 
168  Buffer out;
169 
170  // Attack
171 
172  while(mode_ != sustaining && itor != end)
173  {
174  out << shape(*itor, true);
175  ++itor;
176  }
177 
178  // Sustain
179 
180  uint32 count = 0;
181 
182  while(count < sustain_samples && itor != end)
183  {
184  out << shape(*itor, true);
185  ++itor;
186  ++count;
187  }
188 
189  // Relase
190 
191  while(!is_done() && itor != end)
192  {
193  out << shape(*itor, false);
194  ++itor;
195  }
196 
197  return out;
198 }
199 
200 float64
202 shape(float64 sample, bool key_on)
203 {
204  switch(mode_)
205  {
206  case attacking:
207  {
209  if(scale_ >= 1.0)
210  {
211  scale_ = 0.999;
212  mode_ = delaying;
213  }
214  if(!key_on) mode_ = releasing;
215 
216  break;
217  }
218 
219  case delaying:
220  {
221  scale_ += delay_slope_;
223  if(!key_on) mode_ = releasing;
224 
225  break;
226  }
227 
228  case sustaining:
229  {
231  if(!key_on) mode_ = releasing;
232 
233  break;
234  }
235 
236  case releasing:
237  {
239 
240  if(scale_ <= 0.0)
241  {
242  scale_ = 0.0;
243  mode_ = done;
244  }
245 
246  break;
247  }
248 
249  case done:
250  {
251  scale_ = 0.0;
252  }
253  }
254 
255  M_ASSERT_VALUE(scale_, <, 1.0);
256 
257  return sample * scale_;
258 }
259 
unsigned int uint32
Definition: Nsound.h:153
void setReleaseTime(const float64 &time)
#define M_ASSERT_VALUE(a, op, value)
Definition: Macros.h:76
float64 getSampleRate() const
Returns the sample rate of the stream.
Definition: AudioStream.h:217
void setSustainAmplitude(const float64 &amp)
double float64
Definition: Nsound.h:146
uint32 getLength() const
Returns the number of samples in the Buffer.
Definition: Buffer.h:587
iterator end()
Retruns the itreator at the end of the Buffer.
Definition: Buffer.h:348
uint32 getNChannels(void) const
Returns the number of audio channels in the stream.
Definition: AudioStream.h:212
EnvelopeAdsr(const float64 &sample_rate, const float64 &attack_time, const float64 &delay_time, const float64 &sustain_amplitude, const float64 &release_time)
Constructor.
Definition: EnvelopeAdsr.cc:39
FloatVector::const_iterator const_iterator
Definition: Buffer.h:70
iterator begin()
Retruns the itreator at the start of the Buffer.
Definition: Buffer.h:285
bool is_done() const
Definition: EnvelopeAdsr.h:96
AudioStream shape(const AudioStream &as)
Shapes the AudioStream inplace.
void setAttackTime(const float64 &time)
Definition: EnvelopeAdsr.cc:81
A Buffer for storing audio samples.
Definition: Buffer.h:60
void setDelayTime(const float64 &time)
Definition: EnvelopeAdsr.cc:97