Home Information Classes Download Usage Mail List Requirements Links FAQ Tutorial
00001 #ifndef STK_GUITAR_H 00002 #define STK_GUITAR_H 00003 00004 #include "Stk.h" 00005 #include "Twang.h" 00006 #include "OnePole.h" 00007 #include "OneZero.h" 00008 00009 namespace stk { 00010 00011 /***************************************************/ 00039 /***************************************************/ 00040 00041 class Guitar : public Stk 00042 { 00043 public: 00045 Guitar( unsigned int nStrings = 6, std::string bodyfile = "" ); 00046 00048 void clear( void ); 00049 00051 00056 void setBodyFile( std::string bodyfile = "" ); 00057 00059 00063 void setPluckPosition( StkFloat position, int string = -1 ); 00064 00066 00070 void setLoopGain( StkFloat gain, int string = -1 ); 00071 00073 void setFrequency( StkFloat frequency, unsigned int string = 0 ); 00074 00076 00080 void noteOn( StkFloat frequency, StkFloat amplitude, unsigned int string = 0 ); 00081 00083 void noteOff( StkFloat amplitude, unsigned int string = 0 ); 00084 00086 00090 void controlChange( int number, StkFloat value, int string = -1 ); 00091 00093 StkFloat lastOut( void ) { return lastFrame_[0]; }; 00094 00096 StkFloat tick( StkFloat input = 0.0 ); 00097 00099 00107 StkFrames& tick( StkFrames& frames, unsigned int channel = 0 ); 00108 00110 00118 StkFrames& tick( StkFrames& iFrames, StkFrames &oFrames, unsigned int iChannel = 0, unsigned int oChannel = 0 ); 00119 00120 protected: 00121 00122 std::vector< stk::Twang > strings_; 00123 std::vector< int > stringState_; // 0 = off, 1 = decaying, 2 = on 00124 std::vector< unsigned int > decayCounter_; 00125 std::vector< unsigned int > filePointer_; 00126 std::vector< StkFloat > pluckGains_; 00127 00128 OnePole pickFilter_; 00129 OnePole couplingFilter_; 00130 StkFloat couplingGain_; 00131 StkFrames excitation_; 00132 StkFrames lastFrame_; 00133 }; 00134 00135 inline StkFloat Guitar :: tick( StkFloat input ) 00136 { 00137 StkFloat temp, output = 0.0; 00138 lastFrame_[0] /= strings_.size(); // evenly spread coupling across strings 00139 for ( unsigned int i=0; i<strings_.size(); i++ ) { 00140 if ( stringState_[i] ) { 00141 temp = input; 00142 // If pluckGain < 0.2, let string ring but don't pluck it. 00143 if ( filePointer_[i] < excitation_.frames() && pluckGains_[i] > 0.2 ) 00144 temp += pluckGains_[i] * excitation_[filePointer_[i]++]; 00145 temp += couplingGain_ * couplingFilter_.tick( lastFrame_[0] ); // bridge coupling 00146 output += strings_[i].tick( temp ); 00147 // Check if string energy has decayed sufficiently to turn it off. 00148 if ( stringState_[i] == 1 ) { 00149 if ( fabs( strings_[i].lastOut() ) < 0.001 ) decayCounter_[i]++; 00150 else decayCounter_[i] = 0; 00151 if ( decayCounter_[i] > (unsigned int) floor( 0.1 * Stk::sampleRate() ) ) { 00152 stringState_[i] = 0; 00153 decayCounter_[i] = 0; 00154 } 00155 } 00156 } 00157 } 00158 00159 return lastFrame_[0] = output; 00160 } 00161 00162 inline StkFrames& Guitar :: tick( StkFrames& frames, unsigned int channel ) 00163 { 00164 #if defined(_STK_DEBUG_) 00165 if ( channel >= frames.channels() ) { 00166 oStream_ << "Guitar::tick(): channel and StkFrames arguments are incompatible!"; 00167 handleError( StkError::FUNCTION_ARGUMENT ); 00168 } 00169 #endif 00170 00171 StkFloat *samples = &frames[channel]; 00172 unsigned int hop = frames.channels(); 00173 for ( unsigned int i=0; i<frames.frames(); i++, samples += hop ) 00174 *samples = tick( *samples ); 00175 00176 return frames; 00177 } 00178 00179 inline StkFrames& Guitar :: tick( StkFrames& iFrames, StkFrames& oFrames, unsigned int iChannel, unsigned int oChannel ) 00180 { 00181 #if defined(_STK_DEBUG_) 00182 if ( iChannel >= iFrames.channels() || oChannel >= oFrames.channels() ) { 00183 oStream_ << "Guitar::tick(): channel and StkFrames arguments are incompatible!"; 00184 handleError( StkError::FUNCTION_ARGUMENT ); 00185 } 00186 #endif 00187 00188 StkFloat *iSamples = &iFrames[iChannel]; 00189 StkFloat *oSamples = &oFrames[oChannel]; 00190 unsigned int iHop = iFrames.channels(), oHop = oFrames.channels(); 00191 for ( unsigned int i=0; i<iFrames.frames(); i++, iSamples += iHop, oSamples += oHop ) 00192 *oSamples = tick( *iSamples ); 00193 00194 return iFrames; 00195 } 00196 00197 } // stk namespace 00198 00199 #endif
The Synthesis ToolKit in C++ (STK) |
©1995-2012 Perry R. Cook and Gary P. Scavone. All Rights Reserved. |