Home Information Classes Download Usage Mail List Requirements Links FAQ Tutorial
00001 #ifndef STK_SHAKERS_H 00002 #define STK_SHAKERS_H 00003 00004 #include "Instrmnt.h" 00005 #include <cmath> 00006 #include <stdlib.h> 00007 00008 namespace stk { 00009 00010 /***************************************************/ 00058 /***************************************************/ 00059 00060 class Shakers : public Instrmnt 00061 { 00062 public: 00064 Shakers( int type = 0 ); 00065 00067 00071 void noteOn( StkFloat instrument, StkFloat amplitude ); 00072 00074 void noteOff( StkFloat amplitude ); 00075 00077 void controlChange( int number, StkFloat value ); 00078 00080 StkFloat tick( unsigned int channel = 0 ); 00081 00083 00090 StkFrames& tick( StkFrames& frames, unsigned int channel = 0 ); 00091 00092 struct BiQuad { 00093 StkFloat gain; 00094 StkFloat b[3]; 00095 StkFloat a[3]; // a0 term assumed equal to 1.0 00096 StkFloat inputs[3]; 00097 StkFloat outputs[3]; 00098 00099 // Default constructor. 00100 BiQuad() 00101 { 00102 gain = 0.0; 00103 for ( int i=0; i<3; i++ ) { 00104 b[i] = 0.0; 00105 a[i] = 0.0; 00106 inputs[i] = 0.0; 00107 outputs[i] = 0.0; 00108 } 00109 } 00110 }; 00111 00112 protected: 00113 00114 void setType( int type ); 00115 void setResonance( BiQuad &filter, StkFloat frequency, StkFloat radius ); 00116 StkFloat tickResonance( BiQuad &filter, StkFloat input ); 00117 void setEqualization( StkFloat b0, StkFloat b1, StkFloat b2 ); 00118 StkFloat tickEqualize( StkFloat input ); 00119 int randomInt( int max ); 00120 StkFloat randomFloat( StkFloat max = 1.0 ); 00121 StkFloat noise( void ); 00122 void waterDrop( void ); 00123 00124 int shakerType_; 00125 unsigned int nResonances_; 00126 StkFloat shakeEnergy_; 00127 StkFloat soundDecay_; 00128 StkFloat systemDecay_; 00129 StkFloat nObjects_; 00130 StkFloat sndLevel_; 00131 StkFloat baseGain_; 00132 StkFloat currentGain_; 00133 StkFloat baseDecay_; 00134 StkFloat baseObjects_; 00135 StkFloat decayScale_; 00136 BiQuad equalizer_; 00137 StkFloat ratchetCount_; 00138 StkFloat ratchetDelta_; 00139 StkFloat baseRatchetDelta_; 00140 int lastRatchetValue_; 00141 00142 std::vector< BiQuad > filters_; 00143 std::vector< StkFloat > baseFrequencies_; 00144 std::vector< StkFloat > baseRadii_; 00145 std::vector< bool > doVaryFrequency_; 00146 std::vector< StkFloat > tempFrequencies_; 00147 StkFloat varyFactor_; 00148 }; 00149 00150 inline void Shakers :: setResonance( BiQuad &filter, StkFloat frequency, StkFloat radius ) 00151 { 00152 filter.a[1] = -2.0 * radius * cos( TWO_PI * frequency / Stk::sampleRate()); 00153 filter.a[2] = radius * radius; 00154 } 00155 00156 inline StkFloat Shakers :: tickResonance( BiQuad &filter, StkFloat input ) 00157 { 00158 filter.outputs[0] = input * filter.gain * currentGain_; 00159 filter.outputs[0] -= filter.a[1] * filter.outputs[1] + filter.a[2] * filter.outputs[2]; 00160 filter.outputs[2] = filter.outputs[1]; 00161 filter.outputs[1] = filter.outputs[0]; 00162 return filter.outputs[0]; 00163 } 00164 00165 inline void Shakers :: setEqualization( StkFloat b0, StkFloat b1, StkFloat b2 ) 00166 { 00167 equalizer_.b[0] = b0; 00168 equalizer_.b[1] = b1; 00169 equalizer_.b[2] = b2; 00170 } 00171 00172 inline StkFloat Shakers :: tickEqualize( StkFloat input ) 00173 { 00174 equalizer_.inputs[0] = input; 00175 equalizer_.outputs[0] = equalizer_.b[0] * equalizer_.inputs[0] + equalizer_.b[1] * equalizer_.inputs[1] + equalizer_.b[2] * equalizer_.inputs[2]; 00176 equalizer_.inputs[2] = equalizer_.inputs[1]; 00177 equalizer_.inputs[1] = equalizer_.inputs[0]; 00178 return equalizer_.outputs[0]; 00179 } 00180 00181 inline int Shakers :: randomInt( int max ) // Return random integer between 0 and max-1 00182 { 00183 return (int) ((float)max * rand() / (RAND_MAX + 1.0) ); 00184 } 00185 00186 inline StkFloat Shakers :: randomFloat( StkFloat max ) // Return random float between 0.0 and max 00187 { 00188 return (StkFloat) (max * rand() / (RAND_MAX + 1.0) ); 00189 } 00190 00191 inline StkFloat Shakers :: noise( void ) // Return random StkFloat float between -1.0 and 1.0 00192 { 00193 return ( (StkFloat) ( 2.0 * rand() / (RAND_MAX + 1.0) ) - 1.0 ); 00194 } 00195 00196 const StkFloat MIN_ENERGY = 0.001; 00197 const StkFloat WATER_FREQ_SWEEP = 1.0001; 00198 00199 inline void Shakers :: waterDrop( void ) 00200 { 00201 if ( randomInt( 32767 ) < nObjects_) { 00202 sndLevel_ = shakeEnergy_; 00203 unsigned int j = randomInt( 3 ); 00204 if ( j == 0 && filters_[0].gain == 0.0 ) { // don't change unless fully decayed 00205 tempFrequencies_[0] = baseFrequencies_[1] * (0.75 + (0.25 * noise())); 00206 filters_[0].gain = fabs( noise() ); 00207 } 00208 else if (j == 1 && filters_[1].gain == 0.0) { 00209 tempFrequencies_[1] = baseFrequencies_[1] * (1.0 + (0.25 * noise())); 00210 filters_[1].gain = fabs( noise() ); 00211 } 00212 else if ( filters_[2].gain == 0.0 ) { 00213 tempFrequencies_[2] = baseFrequencies_[1] * (1.25 + (0.25 * noise())); 00214 filters_[2].gain = fabs( noise() ); 00215 } 00216 } 00217 00218 // Sweep center frequencies. 00219 for ( unsigned int i=0; i<3; i++ ) { // WATER_RESONANCES = 3 00220 filters_[i].gain *= baseRadii_[i]; 00221 if ( filters_[i].gain > 0.001 ) { 00222 tempFrequencies_[i] *= WATER_FREQ_SWEEP; 00223 filters_[i].a[1] = -2.0 * baseRadii_[i] * cos( TWO_PI * tempFrequencies_[i] / Stk::sampleRate() ); 00224 } 00225 else 00226 filters_[i].gain = 0.0; 00227 } 00228 } 00229 00230 inline StkFloat Shakers :: tick( unsigned int ) 00231 { 00232 unsigned int iTube = 0; 00233 StkFloat input = 0.0; 00234 if ( shakerType_ == 19 || shakerType_ == 20 ) { 00235 if ( ratchetCount_ <= 0 ) return lastFrame_[0] = 0.0; 00236 00237 shakeEnergy_ -= ( ratchetDelta_ + ( 0.002 * shakeEnergy_ ) ); 00238 if ( shakeEnergy_ < 0.0 ) { 00239 shakeEnergy_ = 1.0; 00240 ratchetCount_--; 00241 } 00242 00243 if ( randomFloat( 1024 ) < nObjects_ ) 00244 sndLevel_ += shakeEnergy_ * shakeEnergy_; 00245 00246 // Sound is enveloped noise 00247 input = sndLevel_ * noise() * shakeEnergy_; 00248 } 00249 else { 00250 if ( shakeEnergy_ < MIN_ENERGY ) return lastFrame_[0] = 0.0; 00251 00252 // Exponential system decay 00253 shakeEnergy_ *= systemDecay_; 00254 00255 // Random events 00256 if ( shakerType_ == 21 ) { 00257 waterDrop(); 00258 input = sndLevel_; 00259 } 00260 else { 00261 if ( randomFloat( 1024.0 ) < nObjects_ ) { 00262 sndLevel_ += shakeEnergy_; 00263 input = sndLevel_; 00264 // Vary resonance frequencies if specified. 00265 for ( unsigned int i=0; i<nResonances_; i++ ) { 00266 if ( doVaryFrequency_[i] ) { 00267 StkFloat tempRand = baseFrequencies_[i] * ( 1.0 + ( varyFactor_ * noise() ) ); 00268 filters_[i].a[1] = -2.0 * baseRadii_[i] * cos( TWO_PI * tempRand / Stk::sampleRate() ); 00269 } 00270 } 00271 if ( shakerType_ == 22 ) iTube = randomInt( 7 ); // ANGKLUNG_RESONANCES 00272 } 00273 } 00274 } 00275 00276 // Exponential sound decay 00277 sndLevel_ *= soundDecay_; 00278 00279 // Do resonance filtering 00280 lastFrame_[0] = 0.0; 00281 if ( shakerType_ == 22 ) { 00282 for ( unsigned int i=0; i<nResonances_; i++ ) { 00283 if ( i == iTube ) 00284 lastFrame_[0] += tickResonance( filters_[i], input ); 00285 else 00286 lastFrame_[0] += tickResonance( filters_[i], 0.0 ); 00287 } 00288 } 00289 else { 00290 for ( unsigned int i=0; i<nResonances_; i++ ) 00291 lastFrame_[0] += tickResonance( filters_[i], input ); 00292 } 00293 00294 // Do final FIR filtering (lowpass or highpass) 00295 lastFrame_[0] = tickEqualize( lastFrame_[0] ); 00296 00297 //if ( std::abs(lastFrame_[0]) > 1.0 ) 00298 // std::cout << "lastOutput = " << lastFrame_[0] << std::endl; 00299 00300 return lastFrame_[0]; 00301 } 00302 00303 inline StkFrames& Shakers :: tick( StkFrames& frames, unsigned int channel ) 00304 { 00305 unsigned int nChannels = lastFrame_.channels(); 00306 #if defined(_STK_DEBUG_) 00307 if ( channel > frames.channels() - nChannels ) { 00308 oStream_ << "Shakers::tick(): channel and StkFrames arguments are incompatible!"; 00309 handleError( StkError::FUNCTION_ARGUMENT ); 00310 } 00311 #endif 00312 00313 StkFloat *samples = &frames[channel]; 00314 unsigned int j, hop = frames.channels() - nChannels; 00315 if ( nChannels == 1 ) { 00316 for ( unsigned int i=0; i<frames.frames(); i++, samples += hop ) 00317 *samples++ = tick(); 00318 } 00319 else { 00320 for ( unsigned int i=0; i<frames.frames(); i++, samples += hop ) { 00321 *samples++ = tick(); 00322 for ( j=1; j<nChannels; j++ ) 00323 *samples++ = lastFrame_[j]; 00324 } 00325 } 00326 00327 return frames; 00328 } 00329 00330 } // stk namespace 00331 00332 #endif
The Synthesis ToolKit in C++ (STK) |
©1995-2012 Perry R. Cook and Gary P. Scavone. All Rights Reserved. |