Home Information Classes Download Usage Mail List Requirements Links FAQ Tutorial

Guitar.h
1 #ifndef STK_GUITAR_H
2 #define STK_GUITAR_H
3
4 #include "Stk.h"
5 #include "Twang.h"
6 #include "OnePole.h"
7 #include "OneZero.h"
8
9 namespace stk {
10
11 /***************************************************/
39 /***************************************************/
40
41 class Guitar : public Stk
42 {
43 public:
45 Guitar( unsigned int nStrings = 6, std::string bodyfile = "" );
46
48 void clear( void );
49
51
56 void setBodyFile( std::string bodyfile = "" );
57
59
63 void setPluckPosition( StkFloat position, int string = -1 );
64
66
70 void setLoopGain( StkFloat gain, int string = -1 );
71
73 void setFrequency( StkFloat frequency, unsigned int string = 0 );
74
76
80 void noteOn( StkFloat frequency, StkFloat amplitude, unsigned int string = 0 );
81
83 void noteOff( StkFloat amplitude, unsigned int string = 0 );
84
86
90 void controlChange( int number, StkFloat value, int string = -1 );
91
93 StkFloat lastOut( void ) { return lastFrame_[0]; };
94
96 StkFloat tick( StkFloat input = 0.0 );
97
99
107 StkFrames& tick( StkFrames& frames, unsigned int channel = 0 );
108
110
118 StkFrames& tick( StkFrames& iFrames, StkFrames &oFrames, unsigned int iChannel = 0, unsigned int oChannel = 0 );
119
120 protected:
121
122 std::vector< stk::Twang > strings_;
123 std::vector< int > stringState_; // 0 = off, 1 = decaying, 2 = on
124 std::vector< unsigned int > decayCounter_;
125 std::vector< unsigned int > filePointer_;
126 std::vector< StkFloat > pluckGains_;
127
128 OnePole pickFilter_;
129 OnePole couplingFilter_;
130 StkFloat couplingGain_;
131 StkFrames excitation_;
132 StkFrames lastFrame_;
133 };
134
135 inline StkFloat Guitar :: tick( StkFloat input )
136 {
137 StkFloat temp, output = 0.0;
138 lastFrame_[0] /= strings_.size(); // evenly spread coupling across strings
139 for ( unsigned int i=0; i<strings_.size(); i++ ) {
140 if ( stringState_[i] ) {
141 temp = input;
142 // If pluckGain < 0.2, let string ring but don't pluck it.
143 if ( filePointer_[i] < excitation_.frames() && pluckGains_[i] > 0.2 )
144 temp += pluckGains_[i] * excitation_[filePointer_[i]++];
145 temp += couplingGain_ * couplingFilter_.tick( lastFrame_[0] ); // bridge coupling
146 output += strings_[i].tick( temp );
147 // Check if string energy has decayed sufficiently to turn it off.
148 if ( stringState_[i] == 1 ) {
149 if ( fabs( strings_[i].lastOut() ) < 0.001 ) decayCounter_[i]++;
150 else decayCounter_[i] = 0;
151 if ( decayCounter_[i] > (unsigned int) floor( 0.1 * Stk::sampleRate() ) ) {
152 stringState_[i] = 0;
153 decayCounter_[i] = 0;
154 }
155 }
156 }
157 }
158
159 return lastFrame_[0] = output;
160 }
161
162 inline StkFrames& Guitar :: tick( StkFrames& frames, unsigned int channel )
163 {
164 #if defined(_STK_DEBUG_)
165 if ( channel >= frames.channels() ) {
166 oStream_ << "Guitar::tick(): channel and StkFrames arguments are incompatible!";
167 handleError( StkError::FUNCTION_ARGUMENT );
168 }
169 #endif
170
171 StkFloat *samples = &frames[channel];
172 unsigned int hop = frames.channels();
173 for ( unsigned int i=0; i<frames.frames(); i++, samples += hop )
174 *samples = tick( *samples );
175
176 return frames;
177 }
178
179 inline StkFrames& Guitar :: tick( StkFrames& iFrames, StkFrames& oFrames, unsigned int iChannel, unsigned int oChannel )
180 {
181 #if defined(_STK_DEBUG_)
182 if ( iChannel >= iFrames.channels() || oChannel >= oFrames.channels() ) {
183 oStream_ << "Guitar::tick(): channel and StkFrames arguments are incompatible!";
184 handleError( StkError::FUNCTION_ARGUMENT );
185 }
186 #endif
187
188 StkFloat *iSamples = &iFrames[iChannel];
189 StkFloat *oSamples = &oFrames[oChannel];
190 unsigned int iHop = iFrames.channels(), oHop = oFrames.channels();
191 for ( unsigned int i=0; i<iFrames.frames(); i++, iSamples += iHop, oSamples += oHop )
192 *oSamples = tick( *iSamples );
193
194 return iFrames;
195 }
196
197 } // stk namespace
198
199 #endif

The Synthesis ToolKit in C++ (STK)
©1995--2017 Perry R. Cook and Gary P. Scavone. All Rights Reserved.