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
9namespace stk {
10
11/***************************************************/
39/***************************************************/
40
41class 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// NOTE: It is not possible to implement the Smith coupled string model here because the Twang class does
136// not currently offer the chance to have access to a traveling-wave component. Thus, the coupling
137// implemented here is approximate.
138inline StkFloat Guitar :: tick( StkFloat input )
139{
140 StkFloat temp, output = 0.0;
141 lastFrame_[0] = couplingGain_ * couplingFilter_.tick( lastFrame_[0] ) / strings_.size();
142 for ( unsigned int i=0; i<strings_.size(); i++ ) {
143 if ( stringState_[i] ) {
144 temp = input;
145 // If pluckGain < 0.2, let string ring but don't pluck it.
146 if ( filePointer_[i] < excitation_.frames() && pluckGains_[i] > 0.2 )
147 temp += pluckGains_[i] * excitation_[filePointer_[i]++];
148 temp += lastFrame_[0]; // bridge coupling
149 output += strings_[i].tick( temp );
150 // Check if string energy has decayed sufficiently to turn it off.
151 if ( stringState_[i] == 1 ) {
152 if ( fabs( strings_[i].lastOut() ) < 0.001 ) decayCounter_[i]++;
153 else decayCounter_[i] = 0;
154 if ( decayCounter_[i] > (unsigned int) floor( 0.1 * Stk::sampleRate() ) ) {
155 stringState_[i] = 0;
156 decayCounter_[i] = 0;
157 }
158 }
159 }
160 }
161
162 return lastFrame_[0] = output;
163}
164
165inline StkFrames& Guitar :: tick( StkFrames& frames, unsigned int channel )
166{
167#if defined(_STK_DEBUG_)
168 if ( channel >= frames.channels() ) {
169 oStream_ << "Guitar::tick(): channel and StkFrames arguments are incompatible!";
170 handleError( StkError::FUNCTION_ARGUMENT );
171 }
172#endif
173
174 StkFloat *samples = &frames[channel];
175 unsigned int hop = frames.channels();
176 for ( unsigned int i=0; i<frames.frames(); i++, samples += hop )
177 *samples = tick( *samples );
178
179 return frames;
180}
181
182inline StkFrames& Guitar :: tick( StkFrames& iFrames, StkFrames& oFrames, unsigned int iChannel, unsigned int oChannel )
183{
184#if defined(_STK_DEBUG_)
185 if ( iChannel >= iFrames.channels() || oChannel >= oFrames.channels() ) {
186 oStream_ << "Guitar::tick(): channel and StkFrames arguments are incompatible!";
187 handleError( StkError::FUNCTION_ARGUMENT );
188 }
189#endif
190
191 StkFloat *iSamples = &iFrames[iChannel];
192 StkFloat *oSamples = &oFrames[oChannel];
193 unsigned int iHop = iFrames.channels(), oHop = oFrames.channels();
194 for ( unsigned int i=0; i<iFrames.frames(); i++, iSamples += iHop, oSamples += oHop )
195 *oSamples = tick( *iSamples );
196
197 return iFrames;
198}
199
200} // stk namespace
201
202#endif
STK guitar model class.
Definition Guitar.h:42
StkFloat tick(StkFloat input=0.0)
Take an optional input sample and compute one output sample.
Definition Guitar.h:138
void setPluckPosition(StkFloat position, int string=-1)
Set the pluck position for one or all strings.
Guitar(unsigned int nStrings=6, std::string bodyfile="")
Class constructor, specifying an arbitrary number of strings (default = 6).
void setFrequency(StkFloat frequency, unsigned int string=0)
Set instrument parameters for a particular frequency.
void setBodyFile(std::string bodyfile="")
Set the string excitation, using either a soundfile or computed noise.
void noteOn(StkFloat frequency, StkFloat amplitude, unsigned int string=0)
Start a note with the given frequency and amplitude.
void noteOff(StkFloat amplitude, unsigned int string=0)
Stop a note with the given amplitude (speed of decay).
void clear(void)
Reset and clear all internal state.
void setLoopGain(StkFloat gain, int string=-1)
Set the loop gain for one or all strings.
void controlChange(int number, StkFloat value, int string=-1)
Perform the control change specified by number and value (0.0 - 128.0).
StkFloat lastOut(void)
Return the last computed output value.
Definition Guitar.h:93
STK one-pole filter class.
Definition OnePole.h:21
An STK class to handle vectorized audio data.
Definition Stk.h:279
unsigned int channels(void) const
Return the number of channels represented by the data.
Definition Stk.h:416
unsigned int frames(void) const
Return the number of sample frames represented by the data.
Definition Stk.h:419
size_t size() const
Returns the total number of audio samples represented by the object.
Definition Stk.h:374
STK base class.
Definition Stk.h:136
static StkFloat sampleRate(void)
Static method that returns the current STK sample rate.
Definition Stk.h:148
The STK namespace.
Definition ADSR.h:6

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