Home Information Classes Download Usage Mail List Requirements Links FAQ Tutorial
00001 #ifndef STK_CLARINET_H 00002 #define STK_CLARINET_H 00003 00004 #include "Instrmnt.h" 00005 #include "DelayL.h" 00006 #include "ReedTable.h" 00007 #include "OneZero.h" 00008 #include "Envelope.h" 00009 #include "Noise.h" 00010 #include "SineWave.h" 00011 00012 namespace stk { 00013 00014 /***************************************************/ 00036 /***************************************************/ 00037 00038 class Clarinet : public Instrmnt 00039 { 00040 public: 00042 00045 Clarinet( StkFloat lowestFrequency = 8.0 ); 00046 00048 ~Clarinet( void ); 00049 00051 void clear( void ); 00052 00054 void setFrequency( StkFloat frequency ); 00055 00057 void startBlowing( StkFloat amplitude, StkFloat rate ); 00058 00060 void stopBlowing( StkFloat rate ); 00061 00063 void noteOn( StkFloat frequency, StkFloat amplitude ); 00064 00066 void noteOff( StkFloat amplitude ); 00067 00069 void controlChange( int number, StkFloat value ); 00070 00072 StkFloat tick( unsigned int channel = 0 ); 00073 00075 00082 StkFrames& tick( StkFrames& frames, unsigned int channel = 0 ); 00083 00084 protected: 00085 00086 DelayL delayLine_; 00087 ReedTable reedTable_; 00088 OneZero filter_; 00089 Envelope envelope_; 00090 Noise noise_; 00091 SineWave vibrato_; 00092 00093 StkFloat outputGain_; 00094 StkFloat noiseGain_; 00095 StkFloat vibratoGain_; 00096 }; 00097 00098 inline StkFloat Clarinet :: tick( unsigned int ) 00099 { 00100 StkFloat pressureDiff; 00101 StkFloat breathPressure; 00102 00103 // Calculate the breath pressure (envelope + noise + vibrato) 00104 breathPressure = envelope_.tick(); 00105 breathPressure += breathPressure * noiseGain_ * noise_.tick(); 00106 breathPressure += breathPressure * vibratoGain_ * vibrato_.tick(); 00107 00108 // Perform commuted loss filtering. 00109 pressureDiff = -0.95 * filter_.tick( delayLine_.lastOut() ); 00110 00111 // Calculate pressure difference of reflected and mouthpiece pressures. 00112 pressureDiff = pressureDiff - breathPressure; 00113 00114 // Perform non-linear scattering using pressure difference in reed function. 00115 lastFrame_[0] = delayLine_.tick(breathPressure + pressureDiff * reedTable_.tick(pressureDiff)); 00116 00117 // Apply output gain. 00118 lastFrame_[0] *= outputGain_; 00119 00120 return lastFrame_[0]; 00121 } 00122 00123 inline StkFrames& Clarinet :: tick( StkFrames& frames, unsigned int channel ) 00124 { 00125 unsigned int nChannels = lastFrame_.channels(); 00126 #if defined(_STK_DEBUG_) 00127 if ( channel > frames.channels() - nChannels ) { 00128 oStream_ << "Clarinet::tick(): channel and StkFrames arguments are incompatible!"; 00129 handleError( StkError::FUNCTION_ARGUMENT ); 00130 } 00131 #endif 00132 00133 StkFloat *samples = &frames[channel]; 00134 unsigned int j, hop = frames.channels() - nChannels; 00135 if ( nChannels == 1 ) { 00136 for ( unsigned int i=0; i<frames.frames(); i++, samples += hop ) 00137 *samples++ = tick(); 00138 } 00139 else { 00140 for ( unsigned int i=0; i<frames.frames(); i++, samples += hop ) { 00141 *samples++ = tick(); 00142 for ( j=1; j<nChannels; j++ ) 00143 *samples++ = lastFrame_[j]; 00144 } 00145 } 00146 00147 return frames; 00148 } 00149 00150 } // stk namespace 00151 00152 #endif
The Synthesis ToolKit in C++ (STK) |
©1995-2012 Perry R. Cook and Gary P. Scavone. All Rights Reserved. |