Home   Information   Classes   Download   Usage   Mail List   Requirements   Links   FAQ   Tutorial


Chorus.h

00001 #ifndef STK_CHORUS_H
00002 #define STK_CHORUS_H
00003 
00004 #include "Effect.h"
00005 #include "DelayL.h"
00006 #include "SineWave.h"
00007 
00008 namespace stk {
00009 
00010 /***************************************************/
00019 /***************************************************/
00020 
00021 class Chorus : public Effect
00022 {
00023  public:
00025 
00028   Chorus( StkFloat baseDelay = 6000 );
00029 
00031   void clear( void );
00032 
00034   void setModDepth( StkFloat depth );
00035 
00037   void setModFrequency( StkFloat frequency );
00038 
00040 
00048   StkFloat lastOut( unsigned int channel = 0 );
00049 
00051 
00058   StkFloat tick( StkFloat input, unsigned int channel = 0 );
00059 
00061 
00070   StkFrames& tick( StkFrames& frames, unsigned int channel = 0 );
00071 
00073 
00082   StkFrames& tick( StkFrames& iFrames, StkFrames &oFrames, unsigned int iChannel = 0, unsigned int oChannel = 0 );
00083 
00084  protected:
00085 
00086   DelayL delayLine_[2];
00087   SineWave mods_[2];
00088   StkFloat baseLength_;
00089   StkFloat modDepth_;
00090 
00091 };
00092 
00093 inline StkFloat Chorus :: lastOut( unsigned int channel )
00094 {
00095 #if defined(_STK_DEBUG_)
00096   if ( channel > 1 ) {
00097     oStream_ << "Chorus::lastOut(): channel argument must be less than 2!";
00098     handleError( StkError::FUNCTION_ARGUMENT );
00099   }
00100 #endif
00101 
00102   return lastFrame_[channel];
00103 }
00104 
00105 inline StkFloat Chorus :: tick( StkFloat input, unsigned int channel )
00106 {
00107 #if defined(_STK_DEBUG_)
00108   if ( channel > 1 ) {
00109     oStream_ << "Chorus::tick(): channel argument must be less than 2!";
00110     handleError( StkError::FUNCTION_ARGUMENT );
00111   }
00112 #endif
00113 
00114   delayLine_[0].setDelay( baseLength_ * 0.707 * ( 1.0 + modDepth_ * mods_[0].tick() ) );
00115   delayLine_[1].setDelay( baseLength_  * 0.5 *  ( 1.0 - modDepth_ * mods_[1].tick() ) );
00116   lastFrame_[0] = effectMix_ * ( delayLine_[0].tick( input ) - input ) + input;
00117   lastFrame_[1] = effectMix_ * ( delayLine_[1].tick( input ) - input ) + input;
00118   return lastFrame_[channel];
00119 }
00120 
00121 inline StkFrames& Chorus :: tick( StkFrames& frames, unsigned int channel )
00122 {
00123 #if defined(_STK_DEBUG_)
00124   if ( channel >= frames.channels() - 1 ) {
00125     oStream_ << "Chorus::tick(): channel and StkFrames arguments are incompatible!";
00126     handleError( StkError::FUNCTION_ARGUMENT );
00127   }
00128 #endif
00129 
00130   StkFloat *samples = &frames[channel];
00131   unsigned int hop = frames.channels() - 1;
00132   for ( unsigned int i=0; i<frames.frames(); i++, samples += hop ) {
00133     delayLine_[0].setDelay( baseLength_ * 0.707 * ( 1.0 + modDepth_ * mods_[0].tick() ) );
00134     delayLine_[1].setDelay( baseLength_  * 0.5 *  ( 1.0 - modDepth_ * mods_[1].tick() ) );
00135     *samples = effectMix_ * ( delayLine_[0].tick( *samples ) - *samples ) + *samples;
00136     samples++;
00137     *samples = effectMix_ * ( delayLine_[1].tick( *samples ) - *samples ) + *samples;
00138   }
00139 
00140   lastFrame_[0] = *(samples-hop);
00141   lastFrame_[1] = *(samples-hop+1);
00142   return frames;
00143 }
00144 
00145 inline StkFrames& Chorus :: tick( StkFrames& iFrames, StkFrames& oFrames, unsigned int iChannel, unsigned int oChannel )
00146 {
00147 #if defined(_STK_DEBUG_)
00148   if ( iChannel >= iFrames.channels() || oChannel >= oFrames.channels() - 1 ) {
00149     oStream_ << "Chorus::tick(): channel and StkFrames arguments are incompatible!";
00150     handleError( StkError::FUNCTION_ARGUMENT );
00151   }
00152 #endif
00153 
00154   StkFloat *iSamples = &iFrames[iChannel];
00155   StkFloat *oSamples = &oFrames[oChannel];
00156   unsigned int iHop = iFrames.channels(), oHop = oFrames.channels();
00157   for ( unsigned int i=0; i<iFrames.frames(); i++, iSamples += iHop, oSamples += oHop ) {
00158     delayLine_[0].setDelay( baseLength_ * 0.707 * ( 1.0 + modDepth_ * mods_[0].tick() ) );
00159     delayLine_[1].setDelay( baseLength_  * 0.5 *  ( 1.0 - modDepth_ * mods_[1].tick() ) );
00160     *oSamples = effectMix_ * ( delayLine_[0].tick( *iSamples ) - *iSamples ) + *iSamples;
00161     *(oSamples+1) = effectMix_ * ( delayLine_[1].tick( *iSamples ) - *iSamples ) + *iSamples;
00162   }
00163 
00164   lastFrame_[0] = *(oSamples-oHop);
00165   lastFrame_[1] = *(oSamples-oHop+1);
00166   return iFrames;
00167 }
00168 
00169 } // stk namespace
00170 
00171 #endif
00172 

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