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--2014 Perry R. Cook and Gary P. Scavone. All Rights Reserved.