The Synthesis ToolKit in C++ (STK)

Home Information Classes Download Usage Mail List Requirements Links FAQ Tutorial

# FreeVerb.h

    00001 #ifndef STK_FREEVERB_H
    00002 #define STK_FREEVERB_H
    00003
    00004 #include "Effect.h"
    00005 #include "Delay.h"
    00006 #include "OnePole.h"
    00007
    00008 namespace stk {
    00009
    00010 /***********************************************************************/
    00024 /***********************************************************************/
    00025
    00026 class FreeVerb : public Effect
    00027 {
    00028  public:
    00030
    00036   FreeVerb();
    00037
    00039   ~FreeVerb();
    00040
    00042   void setEffectMix( StkFloat mix );
    00043
    00045   void setRoomSize( StkFloat value );
    00046
    00048   StkFloat getRoomSize( void );
    00049
    00051   void setDamping( StkFloat value );
    00052
    00054   StkFloat getDamping( void );
    00055
    00057   void setWidth( StkFloat value );
    00058
    00060   StkFloat getWidth( void );
    00061
    00063   void setMode( bool isFrozen );
    00064
    00066   StkFloat getMode( void );
    00067
    00069   void clear( void );
    00070
    00072
    00080   StkFloat lastOut( unsigned int channel = 0 );
    00081
    00083
    00090   StkFloat tick( StkFloat inputL, StkFloat inputR = 0.0, unsigned int channel = 0 );
    00091
    00093
    00103   StkFrames& tick( StkFrames& frames, unsigned int channel = 0 );
    00104
    00106
    00117   StkFrames& tick( StkFrames& iFrames, StkFrames &oFrames, unsigned int iChannel = 0, unsigned int oChannel = 0 );
    00118
    00119  protected:
    00121   void update( void );
    00122
    00123   // Clamp very small floats to zero, version from
    00124   // http://music.columbia.edu/pipermail/linux-audio-user/2004-July/013489.html .
    00125   // However, this is for 32-bit floats only.
    00126   //static inline StkFloat undenormalize( volatile StkFloat s ) {
    00127   //  s += 9.8607615E-32f;
    00128   //  return s - 9.8607615E-32f;
    00129   //}
    00130
    00131   static const int nCombs = 8;
    00132   static const int nAllpasses = 4;
    00133   static const int stereoSpread = 23;
    00134   static const StkFloat fixedGain;
    00135   static const StkFloat scaleWet;
    00136   static const StkFloat scaleDry;
    00137   static const StkFloat scaleDamp;
    00138   static const StkFloat scaleRoom;
    00139   static const StkFloat offsetRoom;
    00140
    00141   // Delay line lengths for 44100Hz sampling rate.
    00142   static int cDelayLengths[nCombs];
    00143   static int aDelayLengths[nAllpasses];
    00144
    00145   StkFloat g_;        // allpass coefficient
    00146   StkFloat gain_;
    00147   StkFloat roomSizeMem_, roomSize_;
    00148   StkFloat dampMem_, damp_;
    00149   StkFloat wet1_, wet2_;
    00150   StkFloat dry_;
    00151   StkFloat width_;
    00152   bool frozenMode_;
    00153
    00154   // LBFC: Lowpass Feedback Comb Filters
    00155   Delay combDelayL_[nCombs];
    00156   Delay combDelayR_[nCombs];
    00157   OnePole combLPL_[nCombs];
    00158   OnePole combLPR_[nCombs];
    00159
    00160   // AP: Allpass Filters
    00161   Delay allPassDelayL_[nAllpasses];
    00162   Delay allPassDelayR_[nAllpasses];
    00163 };
    00164
    00165 inline StkFloat FreeVerb :: lastOut( unsigned int channel )
    00166 {
    00167 #if defined(_STK_DEBUG_)
    00168   if ( channel > 1 ) {
    00169     oStream_ << "FreeVerb::lastOut(): channel argument must be less than 2!";
    00170     handleError( StkError::FUNCTION_ARGUMENT );
    00171   }
    00172 #endif
    00173
    00174   return lastFrame_[channel];
    00175 }
    00176
    00177 inline StkFloat FreeVerb::tick( StkFloat inputL, StkFloat inputR, unsigned int channel )
    00178 {
    00179 #if defined(_STK_DEBUG_)
    00180   if ( channel > 1 ) {
    00181     oStream_ << "FreeVerb::tick(): channel argument must be less than 2!";
    00182     handleError(StkError::FUNCTION_ARGUMENT);
    00183   }
    00184 #endif
    00185
    00186   if ( !inputR ) {
    00187     inputR = inputL;
    00188   }
    00189
    00190   StkFloat fInput = (inputL + inputR) * gain_;
    00191   StkFloat outL = 0.0;
    00192   StkFloat outR = 0.0;
    00193
    00194   // Parallel LBCF filters
    00195   for ( int i = 0; i < nCombs; i++ ) {
    00196     // Left channel
    00197     //StkFloat yn = fInput + (roomSize_ * FreeVerb::undenormalize(combLPL_[i].tick(FreeVerb::undenormalize(combDelayL_[i].nextOut()))));
    00198     StkFloat yn = fInput + (roomSize_ * combLPL_[i].tick( combDelayL_[i].nextOut() ) );
    00199     combDelayL_[i].tick(yn);
    00200     outL += yn;
    00201
    00202     // Right channel
    00203     //yn = fInput + (roomSize_ * FreeVerb::undenormalize(combLPR_[i].tick(FreeVerb::undenormalize(combDelayR_[i].nextOut()))));
    00204     yn = fInput + (roomSize_ * combLPR_[i].tick( combDelayR_[i].nextOut() ) );
    00205     combDelayR_[i].tick(yn);
    00206     outR += yn;
    00207   }
    00208
    00209   // Series allpass filters
    00210   for ( int i = 0; i < nAllpasses; i++ ) {
    00211     // Left channel
    00212     //StkFloat vn_m = FreeVerb::undenormalize(allPassDelayL_[i].nextOut());
    00213     StkFloat vn_m = allPassDelayL_[i].nextOut();
    00214     StkFloat vn = outL + (g_ * vn_m);
    00215     allPassDelayL_[i].tick(vn);
    00216
    00217     // calculate output
    00218     outL = -vn + (1.0 + g_)*vn_m;
    00219
    00220     // Right channel
    00221     //vn_m = FreeVerb::undenormalize(allPassDelayR_[i].nextOut());
    00222     vn_m = allPassDelayR_[i].nextOut();
    00223     vn = outR + (g_ * vn_m);
    00224     allPassDelayR_[i].tick(vn);
    00225
    00226     // calculate output
    00227     outR = -vn + (1.0 + g_)*vn_m;
    00228   }
    00229
    00230   // Mix output
    00231   lastFrame_[0] = outL*wet1_ + outR*wet2_ + inputL*dry_;
    00232   lastFrame_[1] = outR*wet1_ + outL*wet2_ + inputR*dry_;
    00233
    00234   /*
    00235   // Hard limiter ... there's not much else we can do at this point
    00236   if ( lastFrame_[0] >= 1.0 ) {
    00237     lastFrame_[0] = 0.9999;
    00238   }
    00239   if ( lastFrame_[0] <= -1.0 ) {
    00240     lastFrame_[0] = -0.9999;
    00241   }
    00242   if ( lastFrame_[1] >= 1.0 ) {
    00243     lastFrame_[1] = 0.9999;
    00244   }
    00245   if ( lastFrame_[1] <= -1.0 ) {
    00246     lastFrame_[1] = -0.9999;
    00247   }
    00248   */
    00249
    00250   return lastFrame_[channel];
    00251 }
    00252
    00253 }
    00254
    00255 #endif

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