Nsound  0.9.4
Clarinet.cc
Go to the documentation of this file.
1 //-----------------------------------------------------------------------------
2 //
3 // $Id: Clarinet.cc 874 2014-09-08 02:21:29Z weegreenblobbie $
4 //
5 // Copyright (c) 2004-2008 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/AudioStream.h>
30 #include <Nsound/Buffer.h>
31 #include <Nsound/Clarinet.h>
32 #include <Nsound/DelayLine.h>
35 #include <Nsound/FilterTone.h>
36 #include <Nsound/Sine.h>
37 
38 using namespace Nsound;
39 
40 //-----------------------------------------------------------------------------
42 Clarinet(const float64 & sample_rate)
43  :
44  Instrument(sample_rate)
45 {
46 }
47 
48 //-----------------------------------------------------------------------------
51 {
52 }
53 
57 {
59 
60  // duration, freq
61  y << play(0.600, 261.616)
62  << play(0.600, 293.656)
63  << play(0.600, 329.609)
64  << play(0.600, 349.218)
65  << play(0.600, 391.973)
66  << play(1.800, 445.000);
67 
68  return y;
69 }
70 
73 play(const float64 & duration, const float64 & frequency)
74 {
75  return play(duration, frequency, 1.8, 1000.0, 0.2);
76 }
77 
81  const float64 & duration,
82  const float64 & frequency,
83  const float64 & pressure,
84  const float64 & filter,
85  const float64 & reed_stiffness)
86 {
87  DelayLine delay1(sample_rate_, (1.0 / frequency));
88  DelayLine delay2(sample_rate_, (1.0 / frequency));
89  Sine sin(sample_rate_);
90  FilterLowPassIIR tone(sample_rate_, 2, filter, 0.0);
91  FilterHighPassIIR atone(sample_rate_, 2, filter, 0.0);
92 
93  Buffer reed_wave = sin.drawLine( 80.0 / 256.0, 1.0, 1.0)
94  << sin.drawLine(156.0 / 256.0, 1.0, -1.0)
95  << sin.drawLine( 20.0 / 256.0, -1.0, -1.0);
96 
97  float64 env_peak = (0.55 + 0.3 * pressure);
98 
99  Buffer env1 = sin.drawLine(0.005, 0.0, env_peak)
100  << sin.drawLine(duration - 0.015, env_peak, env_peak)
101  << sin.drawLine(0.01, env_peak, 0.0);
102 
103  Buffer vibrato_env = sin.drawLine(duration, 0.0, 0.1);
104 
105  Buffer pressurem = vibrato_env * sin.generate(duration, 5.0) + 1.0;
106 
107  pressurem *= (0.3 * env1);
108 
109  float64 reed_bell = 0.0;
110 
111  uint32 n_samples = pressurem.getLength();
112 
114 
115  Buffer xxx;
116 
117  for(uint32 n = 0; n < n_samples; ++n)
118  {
119  float64 filter_out = tone.filter(reed_bell);
120 
121  float64 x = -1.0 * pressurem[n] - 0.95 * filter_out - reed_stiffness;
122 
123  xxx << x;
124 
125  uint32 reed_index = static_cast<uint32>((0.25 * x + 0.5) * sample_rate_);
126 
127  x *= reed_wave[reed_index];
128 
129  x += pressurem[n];
130 
131  delay2.write(x);
132  reed_bell = delay2.read();
133 
134  x = atone.filter(reed_bell);
135 
136  y << x;
137 
138  }
139 
140  y.normalize();
141 
142  float64 dt = 1.0 / frequency;
143 
144  // Declick, at the very beginning and ends, the reed_wave values goes crazy
145 
146  y = y.substream(dt, duration - dt);
147 
148  Buffer out_env = sin.drawLine(0.01, 0.0, 1.0)
149  << sin.drawLine(duration - 0.02, 1.0, 1.0)
150  << sin.drawLine(0.01, 1.0, 0.0);
151 
152  y *= out_env;
153 
154  return y;
155 }
156 
157 
158 // :mode=c++: jEdit modeline
unsigned int uint32
Definition: Nsound.h:153
AudioStream play()
Plays a demo for this instrument.
Definition: Clarinet.cc:56
AudioStream filter(const AudioStream &x)
AudioStream substream(uint32 start_index, uint32 n_samples=0) const
Definition: AudioStream.cc:825
double float64
Definition: Nsound.h:146
A class for filtering audio in the frequecy domain.
uint32 getLength() const
Returns the number of samples in the Buffer.
Definition: Buffer.h:587
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
A class for filtering audio in the frequecy domain.
float64 read()
Definition: DelayLine.cc:97
Clarinet(const float64 &sample_rate)
Creates a Bass Kick Drum.
Definition: Clarinet.cc:42
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
~Clarinet()
Destructor.
Definition: Clarinet.cc:50
AudioStream filter(const AudioStream &x)
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
void write(float64 x)
Definition: DelayLine.cc:133