Home Information Classes Download Usage Mail List Requirements Links FAQ Tutorial

BlowHole.h
1 #ifndef STK_BLOWHOLE_H
2 #define STK_BLOWHOLE_H
3
4 #include "Instrmnt.h"
5 #include "DelayL.h"
6 #include "ReedTable.h"
7 #include "OneZero.h"
8 #include "PoleZero.h"
9 #include "Envelope.h"
10 #include "Noise.h"
11 #include "SineWave.h"
12
13 namespace stk {
14
15 /***************************************************/
48 /***************************************************/
49
50 class BlowHole : public Instrmnt
51 {
52 public:
54
57 BlowHole( StkFloat lowestFrequency );
58
60 ~BlowHole( void );
61
63 void clear( void );
64
66 void setFrequency( StkFloat frequency );
67
69 void setTonehole( StkFloat newValue );
70
72 void setVent( StkFloat newValue );
73
75 void startBlowing( StkFloat amplitude, StkFloat rate );
76
78 void stopBlowing( StkFloat rate );
79
81 void noteOn( StkFloat frequency, StkFloat amplitude );
82
84 void noteOff( StkFloat amplitude );
85
87 void controlChange( int number, StkFloat value );
88
90 StkFloat tick( unsigned int channel = 0 );
91
93
100 StkFrames& tick( StkFrames& frames, unsigned int channel = 0 );
101
102 protected:
103
104 DelayL delays_[3];
105 ReedTable reedTable_;
106 OneZero filter_;
107 PoleZero tonehole_;
108 PoleZero vent_;
109 Envelope envelope_;
110 Noise noise_;
111 SineWave vibrato_;
112
113 StkFloat scatter_;
114 StkFloat thCoeff_;
115 StkFloat rhGain_;
116 StkFloat outputGain_;
117 StkFloat noiseGain_;
118 StkFloat vibratoGain_;
119 };
120
121 inline StkFloat BlowHole :: tick( unsigned int )
122 {
123 StkFloat pressureDiff;
124 StkFloat breathPressure;
125 StkFloat temp;
126
127 // Calculate the breath pressure (envelope + noise + vibrato)
128 breathPressure = envelope_.tick();
129 breathPressure += breathPressure * noiseGain_ * noise_.tick();
130 breathPressure += breathPressure * vibratoGain_ * vibrato_.tick();
131
132 // Calculate the differential pressure = reflected - mouthpiece pressures
133 pressureDiff = delays_[0].lastOut() - breathPressure;
134
135 // Do two-port junction scattering for register vent
136 StkFloat pa = breathPressure + pressureDiff * reedTable_.tick( pressureDiff );
137 StkFloat pb = delays_[1].lastOut();
138 vent_.tick( pa+pb );
139
140 lastFrame_[0] = delays_[0].tick( vent_.lastOut()+pb );
141 lastFrame_[0] *= outputGain_;
142
143 // Do three-port junction scattering (under tonehole)
144 pa += vent_.lastOut();
145 pb = delays_[2].lastOut();
146 StkFloat pth = tonehole_.lastOut();
147 temp = scatter_ * (pa + pb - 2 * pth);
148
149 delays_[2].tick( filter_.tick(pa + temp) * -0.95 );
150 delays_[1].tick( pb + temp );
151 tonehole_.tick( pa + pb - pth + temp );
152
153 return lastFrame_[0];
154 }
155
156 inline StkFrames& BlowHole :: tick( StkFrames& frames, unsigned int channel )
157 {
158 unsigned int nChannels = lastFrame_.channels();
159 #if defined(_STK_DEBUG_)
160 if ( channel > frames.channels() - nChannels ) {
161 oStream_ << "BlowHole::tick(): channel and StkFrames arguments are incompatible!";
162 handleError( StkError::FUNCTION_ARGUMENT );
163 }
164 #endif
165
166 StkFloat *samples = &frames[channel];
167 unsigned int j, hop = frames.channels() - nChannels;
168 if ( nChannels == 1 ) {
169 for ( unsigned int i=0; i<frames.frames(); i++, samples += hop )
170 *samples++ = tick();
171 }
172 else {
173 for ( unsigned int i=0; i<frames.frames(); i++, samples += hop ) {
174 *samples++ = tick();
175 for ( j=1; j<nChannels; j++ )
176 *samples++ = lastFrame_[j];
177 }
178 }
179
180 return frames;
181 }
182
183 } // stk namespace
184
185 #endif

The Synthesis ToolKit in C++ (STK)
©1995--2017 Perry R. Cook and Gary P. Scavone. All Rights Reserved.