Nsound  0.9.4
OrganPipe.cc
Go to the documentation of this file.
1 //-----------------------------------------------------------------------------
2 //
3 // $Id: OrganPipe.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/AudioStream.h>
35 #include <Nsound/Buffer.h>
36 #include <Nsound/OrganPipe.h>
38 #include <Nsound/FilterTone.h>
39 #include <Nsound/Sine.h>
40 
41 using namespace Nsound;
42 using std::cout;
43 using std::endl;
44 
45 //-----------------------------------------------------------------------------
47 OrganPipe(const float64 & sample_rate)
48  :
49  Instrument(sample_rate){}
50 
51 //-----------------------------------------------------------------------------
54 
58 {
60 
61  // Organ Intro to Bach's Toccata & Fugue in Dminor
62  // Start Dur Amp Fqc Pan OutCh1 OutCh2
63  // i4 26 .12 200 7.09 .9 1 2
64  // i4 + .1 300 7.07 .8 1 2
65  // i4 . .8 400 7.09 .7 1 2
66  // i4 27.2 .16 500 7.07 .6 1 2
67  // i4 + .14 600 7.05 .5 1 2
68  // i4 . .12 700 7.04 .4 1 2
69  // i4 . .12 800 7.02 .3 1 2
70  // i4 . .56 900 7.01 .4 1 2
71  // i4 . 1.2 1200 7.02 .5 1 2
72 
73  y << play(0.12, 219.98, 0.9)
74  << play(0.10, 195.99, 0.8)
75  << play(0.80, 219.98, 0.7);
76 
77  // Use AudioStream::add to insert the precise delay.
78  y.add(play(0.16, 195.99, 0.6), 1.20f);
79 
80  y << play(0.14, 174.61, 0.5)
81  << play(0.12, 164.80, 0.4)
82  << play(0.12, 146.83, 0.3)
83  << play(0.56, 138.58, 0.4)
84  << play(1.20, 146.83, 0.5);
85 
86  // i4 29.8 .12 1600 6.09 .5
87  // i4 + .1 . 6.07 .5
88  // i4 . .8 . 6.09 .5
89  // i4 31 .3 . 6.05 .5
90  // i4 + .3 . 6.07 .5
91  // i4 . .3 . 6.01 .5
92  // i4 . 1.2 . 6.02 .5
93 
94  y.add(play(0.12, 109.99), 2.80f);
95 
96  y << play(0.10, 97.99)
97  << play(0.80, 109.99);
98 
99  y.add(play(0.30, 87.30), 5.00f);
100 
101  y << play(0.30, 97.99)
102  << play(0.30, 69.29)
103  << play(1.20, 73.41);
104 
105  // i4 33.2 .12 3000 5.09 .5
106  // i4 + .1 . 5.07 .5
107  // i4 . .8 . 5.09 .5
108  // i4 34.4 .16 . 5.07 .5
109  // i4 + .14 . 5.05 .5
110  // i4 . .12 . 5.04 .5
111  // i4 . .12 . 5.02 .5
112  // i4 . .56 . 5.01 .5
113  // i4 . 1.2 . 5.02 .5
114 
115  y.add(play(0.12, 55.00), 7.20f);
116 
117  y << play(0.10, 49.00)
118  << play(0.80, 55.00);
119 
120  y.add(play(0.16, 49.00), 8.40f);
121 
122  y << play(0.14, 43.65)
123  << play(0.12, 41.20)
124  << play(0.12, 36.71)
125  << play(0.56, 34.65)
126  << play(1.20, 36.71);
127 
128  // i4 36.5 2.0 . 5.01 .5
129  // i4 36.7 1.8 . 5.04 .5
130  // i4 36.9 1.6 . 5.07 .5
131  // i4 37.1 1.4 . 5.10 .5
132  // i4 37.3 1.2 . 6.01 .5
133  // i4 38.7 3.2 . 5.02 .5
134  // i4 38.7 3.2 . 6.02 .5
135  // i4 38.7 0.8 . 5.07 .5
136  // i4 + 0.8 . 5.09 .5
137  // i4 . 1.6 . 5.06 .5
138 
139  y.add(play(2.00, 34.65), 10.5f);
140  y.add(play(1.80, 41.20), 10.7f);
141  y.add(play(1.60, 49.00), 10.9f);
142  y.add(play(1.40, 58.27), 11.1f);
143  y.add(play(1.20, 69.29), 11.3f);
144  y.add(play(3.20, 36.71), 12.7f);
145  y.add(play(3.20, 73.41), 12.7f);
146  y.add(play(0.08, 49.00), 12.7f);
147 
148  for(uint32 i = 0 ; i < sample_rate_ * 0.3; ++i) y << 0.0;
149 
150  y.normalize();
151 
152  return y;
153 }
154 
158  const float64 & duration,
159  const float64 & frequency)
160 {
161  return play(duration, frequency, 0.5);
162 }
163 
164 
168  const float64 & duration,
169  const float64 & frequency,
170  const float64 & pan)
171 {
172  M_ASSERT_VALUE(duration, >, 0);
173 
174  // The three phases of software development:
175  // 1. Make it work.
176  // 2. Make it work well.
177  // 3. Make it work well for others.
178 
179  float64 pan_left = pan;
180  float64 pan_right = 1.0 - pan_left;
181 
182  float64 op1f = 1.00 * frequency;
183  float64 op2f = 2.01 * frequency;
184  float64 op3f = 3.99 * frequency;
185  float64 op4f = 8.00 * frequency;
186  float64 op5f = 0.50 * frequency;
187  float64 op7f = 16.00 * frequency;
188 
189  Sine sin(sample_rate_);
190 
191  Buffer dclick;
192  Buffer amp1;
193  Buffer amp2;
194  Buffer amp3;
195  Buffer amp4;
196 
197  if(duration > 0.002)
198  {
199  dclick
200  << sin.drawLine(0.001, 0.0, 1.0)
201  << sin.drawLine(duration - 0.002, 1.0, 1.0)
202  << sin.drawLine(0.001, 1.0, 0.0);
203  }
204  else
205  {
206  dclick << sin.drawLine(duration, 1.0, 1.0);
207  }
208 
209  if(duration > 0.02)
210  {
211  amp1
212  << sin.drawLine(0.01, 0.0, 1.0)
213  << sin.drawLine(duration - 0.02, 1.0, 1.0)
214  << sin.drawLine(0.01, 1.0, 0.0);
215  }
216  else
217  {
218  amp1 = sin.drawLine(duration, 1.0, 1.0);
219  }
220 
221  if(duration > 0.16)
222  {
223  amp2
224  << sin.drawLine(0.05, 0.0, 1.0)
225  << sin.drawLine(0.1, 1.0, 0.7)
226  << sin.drawLine(duration - 0.16, 0.7, 0.7)
227  << sin.drawLine(0.01, 0.7, 0.0);
228  }
229  else
230  {
231  amp2 = sin.drawLine(duration, 1.0, 1.0);
232  }
233 
234  if(duration > 0.08)
235  {
236  amp3
237  << sin.drawLine(0.03, 0.0, 0.8)
238  << sin.drawLine(0.05, 0.8, 0.0)
239  << sin.drawLine(duration - 0.08, 0.0, 0.0);
240  }
241  else
242  {
243  amp3 = sin.drawLine(duration, 1.0, 1.0);
244  }
245 
246  if(duration > 0.21)
247  {
248  amp4
249  << sin.drawLine(0.1, 0.0, 0.3)
250  << sin.drawLine(0.1, 0.3, 0.05)
251  << sin.drawLine(duration -0.21, 0.05, 0.1)
252  << sin.drawLine(0.01, 0.1, 0.0);
253  }
254  else
255  {
256  amp4 = sin.drawLine(duration, 1.0, 1.0);
257  }
258 
259  Buffer op8 = amp4 * sin.generate(duration, op5f);
260 
261  Buffer p1 = op8 + 1.0;
262 
263  Buffer out = amp1 * sin.generate(duration, p1 * op1f);
264  out += amp2 * sin.generate(duration, p1 * op2f);
265  out += amp2 * sin.generate(duration, op3f);
266  out += amp2 * sin.generate(duration, op4f);
267  out += amp3 * sin.generate(duration, 5.0 * op5f);
268  out += amp2 * sin.generate(duration, op7f);
269 
271 
272  y[0] = out * dclick * pan_left;
273  y[1] = out * dclick * pan_right;
274 
275  return y;
276 }
277 
278 // :mode=c++: jEdit modeline
unsigned int uint32
Definition: Nsound.h:153
#define M_ASSERT_VALUE(a, op, value)
Definition: Macros.h:76
AudioStream play()
Plays a demo for this instrument.
Definition: OrganPipe.cc:57
double float64
Definition: Nsound.h:146
void normalize()
Multiplies the AudioStream by a constant gain so the peak sample has magnitude 1.0.
Definition: AudioStream.cc:285
virtual float64 generate(const float64 &frequency)
This is a real-time method for the wavetable oscillator.
Definition: Generator.cc:972
~OrganPipe()
Destructor.
Definition: OrganPipe.cc:53
The Nsound Instrument baseclass. All Nsound instruments extend this class.
Definition: Instrument.h:50
float64 sample_rate_
Definition: Instrument.h:76
A Buffer for storing audio samples.
Definition: Buffer.h:60
void add(const AudioStream &as, uint32 offset, uint32 n_samples=0)
This method adds the passed AudioStream to this AudioStream.
Definition: AudioStream.cc:121
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
DOXME.
Definition: Sine.h:43
OrganPipe(const float64 &sample_rate)
Creates an OrganPipe.
Definition: OrganPipe.cc:47