Home Information Classes Download Usage Mail List Requirements Links FAQ Tutorial
00001 #ifndef STK_BLOWHOLE_H 00002 #define STK_BLOWHOLE_H 00003 00004 #include "Instrmnt.h" 00005 #include "DelayL.h" 00006 #include "ReedTable.h" 00007 #include "OneZero.h" 00008 #include "PoleZero.h" 00009 #include "Envelope.h" 00010 #include "Noise.h" 00011 #include "SineWave.h" 00012 00013 namespace stk { 00014 00015 /***************************************************/ 00048 /***************************************************/ 00049 00050 class BlowHole : public Instrmnt 00051 { 00052 public: 00054 00057 BlowHole( StkFloat lowestFrequency ); 00058 00060 ~BlowHole( void ); 00061 00063 void clear( void ); 00064 00066 void setFrequency( StkFloat frequency ); 00067 00069 void setTonehole( StkFloat newValue ); 00070 00072 void setVent( StkFloat newValue ); 00073 00075 void startBlowing( StkFloat amplitude, StkFloat rate ); 00076 00078 void stopBlowing( StkFloat rate ); 00079 00081 void noteOn( StkFloat frequency, StkFloat amplitude ); 00082 00084 void noteOff( StkFloat amplitude ); 00085 00087 void controlChange( int number, StkFloat value ); 00088 00090 StkFloat tick( unsigned int channel = 0 ); 00091 00093 00100 StkFrames& tick( StkFrames& frames, unsigned int channel = 0 ); 00101 00102 protected: 00103 00104 DelayL delays_[3]; 00105 ReedTable reedTable_; 00106 OneZero filter_; 00107 PoleZero tonehole_; 00108 PoleZero vent_; 00109 Envelope envelope_; 00110 Noise noise_; 00111 SineWave vibrato_; 00112 00113 StkFloat scatter_; 00114 StkFloat thCoeff_; 00115 StkFloat rhGain_; 00116 StkFloat outputGain_; 00117 StkFloat noiseGain_; 00118 StkFloat vibratoGain_; 00119 }; 00120 00121 inline StkFloat BlowHole :: tick( unsigned int ) 00122 { 00123 StkFloat pressureDiff; 00124 StkFloat breathPressure; 00125 StkFloat temp; 00126 00127 // Calculate the breath pressure (envelope + noise + vibrato) 00128 breathPressure = envelope_.tick(); 00129 breathPressure += breathPressure * noiseGain_ * noise_.tick(); 00130 breathPressure += breathPressure * vibratoGain_ * vibrato_.tick(); 00131 00132 // Calculate the differential pressure = reflected - mouthpiece pressures 00133 pressureDiff = delays_[0].lastOut() - breathPressure; 00134 00135 // Do two-port junction scattering for register vent 00136 StkFloat pa = breathPressure + pressureDiff * reedTable_.tick( pressureDiff ); 00137 StkFloat pb = delays_[1].lastOut(); 00138 vent_.tick( pa+pb ); 00139 00140 lastFrame_[0] = delays_[0].tick( vent_.lastOut()+pb ); 00141 lastFrame_[0] *= outputGain_; 00142 00143 // Do three-port junction scattering (under tonehole) 00144 pa += vent_.lastOut(); 00145 pb = delays_[2].lastOut(); 00146 StkFloat pth = tonehole_.lastOut(); 00147 temp = scatter_ * (pa + pb - 2 * pth); 00148 00149 delays_[2].tick( filter_.tick(pa + temp) * -0.95 ); 00150 delays_[1].tick( pb + temp ); 00151 tonehole_.tick( pa + pb - pth + temp ); 00152 00153 return lastFrame_[0]; 00154 } 00155 00156 inline StkFrames& BlowHole :: tick( StkFrames& frames, unsigned int channel ) 00157 { 00158 unsigned int nChannels = lastFrame_.channels(); 00159 #if defined(_STK_DEBUG_) 00160 if ( channel > frames.channels() - nChannels ) { 00161 oStream_ << "BlowHole::tick(): channel and StkFrames arguments are incompatible!"; 00162 handleError( StkError::FUNCTION_ARGUMENT ); 00163 } 00164 #endif 00165 00166 StkFloat *samples = &frames[channel]; 00167 unsigned int j, hop = frames.channels() - nChannels; 00168 if ( nChannels == 1 ) { 00169 for ( unsigned int i=0; i<frames.frames(); i++, samples += hop ) 00170 *samples++ = tick(); 00171 } 00172 else { 00173 for ( unsigned int i=0; i<frames.frames(); i++, samples += hop ) { 00174 *samples++ = tick(); 00175 for ( j=1; j<nChannels; j++ ) 00176 *samples++ = lastFrame_[j]; 00177 } 00178 } 00179 00180 return frames; 00181 } 00182 00183 } // stk namespace 00184 00185 #endif
The Synthesis ToolKit in C++ (STK) |
©1995-2012 Perry R. Cook and Gary P. Scavone. All Rights Reserved. |