The Synthesis ToolKit in C++ (STK)

Home Information Classes Download Usage Mail List Requirements Links FAQ Tutorial

# Guitar.h

    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.