Arduino STK  4.6.2
FreeVerb.h
1 #ifndef STK_FREEVERB_H
2 #define STK_FREEVERB_H
3 
4 #include "Effect.h"
5 #include "Delay.h"
6 #include "OnePole.h"
7 
8 namespace stk {
9 
10 /***********************************************************************/
24 /***********************************************************************/
25 
26 class FreeVerb : public Effect
27 {
28  public:
30 
37 
40 
42  void setEffectMix( StkFloat mix );
43 
45  void setRoomSize( StkFloat value );
46 
48  StkFloat getRoomSize( void );
49 
51  void setDamping( StkFloat value );
52 
54  StkFloat getDamping( void );
55 
57  void setWidth( StkFloat value );
58 
60  StkFloat getWidth( void );
61 
63  void setMode( bool isFrozen );
64 
66  StkFloat getMode( void );
67 
69  void clear( void );
70 
72 
80  StkFloat lastOut( unsigned int channel = 0 );
81 
83 
90  StkFloat tick( StkFloat inputL, StkFloat inputR = 0.0, unsigned int channel = 0 );
91 
93 
103  StkFrames& tick( StkFrames& frames, unsigned int channel = 0 );
104 
106 
117  StkFrames& tick( StkFrames& iFrames, StkFrames &oFrames, unsigned int iChannel = 0, unsigned int oChannel = 0 );
118 
119  protected:
121  void update( void );
122 
123  // Clamp very small floats to zero, version from
124  // http://music.columbia.edu/pipermail/linux-audio-user/2004-July/013489.html .
125  // However, this is for 32-bit floats only.
126  //static inline StkFloat undenormalize( volatile StkFloat s ) {
127  // s += 9.8607615E-32f;
128  // return s - 9.8607615E-32f;
129  //}
130 
131  static const int nCombs = 8;
132  static const int nAllpasses = 4;
133  static const int stereoSpread = 23;
134  static const StkFloat fixedGain;
135  static const StkFloat scaleWet;
136  static const StkFloat scaleDry;
137  static const StkFloat scaleDamp;
138  static const StkFloat scaleRoom;
139  static const StkFloat offsetRoom;
140 
141  // Delay line lengths for 44100Hz sampling rate.
142  static int cDelayLengths[nCombs];
143  static int aDelayLengths[nAllpasses];
144 
145  StkFloat g_; // allpass coefficient
146  StkFloat gain_;
147  StkFloat roomSizeMem_, roomSize_;
148  StkFloat dampMem_, damp_;
149  StkFloat wet1_, wet2_;
150  StkFloat dry_;
151  StkFloat width_;
152  bool frozenMode_;
153 
154  // LBFC: Lowpass Feedback Comb Filters
155  Delay combDelayL_[nCombs];
156  Delay combDelayR_[nCombs];
157  OnePole combLPL_[nCombs];
158  OnePole combLPR_[nCombs];
159 
160  // AP: Allpass Filters
161  Delay allPassDelayL_[nAllpasses];
162  Delay allPassDelayR_[nAllpasses];
163 };
164 
165 inline StkFloat FreeVerb :: lastOut( unsigned int channel )
166 {
167 #if defined(_STK_DEBUG_)
168  if ( channel > 1 ) {
169  oStream_ << "FreeVerb::lastOut(): channel argument must be less than 2!";
170  handleError( StkError::FUNCTION_ARGUMENT );
171  }
172 #endif
173 
174  return lastFrame_[channel];
175 }
176 
177 inline StkFloat FreeVerb::tick( StkFloat inputL, StkFloat inputR, unsigned int channel )
178 {
179 #if defined(_STK_DEBUG_)
180  if ( channel > 1 ) {
181  oStream_ << "FreeVerb::tick(): channel argument must be less than 2!";
182  handleError(StkError::FUNCTION_ARGUMENT);
183  }
184 #endif
185 
186  StkFloat fInput = (inputL + inputR) * gain_;
187  StkFloat outL = 0.0;
188  StkFloat outR = 0.0;
189 
190  // Parallel LBCF filters
191  for ( int i = 0; i < nCombs; i++ ) {
192  // Left channel
193  //StkFloat yn = fInput + (roomSize_ * FreeVerb::undenormalize(combLPL_[i].tick(FreeVerb::undenormalize(combDelayL_[i].nextOut()))));
194  StkFloat yn = fInput + (roomSize_ * combLPL_[i].tick( combDelayL_[i].nextOut() ) );
195  combDelayL_[i].tick(yn);
196  outL += yn;
197 
198  // Right channel
199  //yn = fInput + (roomSize_ * FreeVerb::undenormalize(combLPR_[i].tick(FreeVerb::undenormalize(combDelayR_[i].nextOut()))));
200  yn = fInput + (roomSize_ * combLPR_[i].tick( combDelayR_[i].nextOut() ) );
201  combDelayR_[i].tick(yn);
202  outR += yn;
203  }
204 
205  // Series allpass filters
206  for ( int i = 0; i < nAllpasses; i++ ) {
207  // Left channel
208  //StkFloat vn_m = FreeVerb::undenormalize(allPassDelayL_[i].nextOut());
209  StkFloat vn_m = allPassDelayL_[i].nextOut();
210  StkFloat vn = outL + (g_ * vn_m);
211  allPassDelayL_[i].tick(vn);
212 
213  // calculate output
214  outL = -vn + (1.0 + g_)*vn_m;
215 
216  // Right channel
217  //vn_m = FreeVerb::undenormalize(allPassDelayR_[i].nextOut());
218  vn_m = allPassDelayR_[i].nextOut();
219  vn = outR + (g_ * vn_m);
220  allPassDelayR_[i].tick(vn);
221 
222  // calculate output
223  outR = -vn + (1.0 + g_)*vn_m;
224  }
225 
226  // Mix output
227  lastFrame_[0] = outL*wet1_ + outR*wet2_ + inputL*dry_;
228  lastFrame_[1] = outR*wet1_ + outL*wet2_ + inputR*dry_;
229 
230  /*
231  // Hard limiter ... there's not much else we can do at this point
232  if ( lastFrame_[0] >= 1.0 ) {
233  lastFrame_[0] = 0.9999;
234  }
235  if ( lastFrame_[0] <= -1.0 ) {
236  lastFrame_[0] = -0.9999;
237  }
238  if ( lastFrame_[1] >= 1.0 ) {
239  lastFrame_[1] = 0.9999;
240  }
241  if ( lastFrame_[1] <= -1.0 ) {
242  lastFrame_[1] = -0.9999;
243  }
244  */
245 
246  return lastFrame_[channel];
247 }
248 
249 }
250 
251 #endif
STK non-interpolating delay line class.
Definition: Delay.h:25
StkFloat nextOut(void)
Return the value that will be output by the next call to tick().
Definition: Delay.h:87
StkFloat tick(StkFloat input)
Input one sample to the filter and return one output.
Definition: Delay.h:124
STK abstract effects parent class.
Definition: Effect.h:22
Jezar at Dreampoint's FreeVerb, implemented in STK.
Definition: FreeVerb.h:27
StkFloat tick(StkFloat inputL, StkFloat inputR=0.0, unsigned int channel=0)
Input one or two samples to the effect and return the specified channel value of the computed stereo ...
Definition: FreeVerb.h:177
~FreeVerb()
Destructor.
void clear(void)
Clears delay lines, etc.
StkFrames & tick(StkFrames &frames, unsigned int channel=0)
Take two channels of the StkFrames object as inputs to the effect and replace with stereo outputs.
void update(void)
Update interdependent parameters.
StkFloat getDamping(void)
Get the damping parameter.
void setRoomSize(StkFloat value)
Set the room size (comb filter feedback gain) parameter [0,1].
StkFloat getMode(void)
Get the current freeze mode [frozen = 1, unfrozen = 0].
void setWidth(StkFloat value)
Set the width (left-right mixing) parameter [0,1].
void setDamping(StkFloat value)
Set the damping parameter [0=low damping, 1=higher damping].
StkFloat lastOut(unsigned int channel=0)
Return the specified channel value of the last computed stereo frame.
Definition: FreeVerb.h:165
FreeVerb()
FreeVerb Constructor.
StkFloat getWidth(void)
Get the width (left-right mixing) parameter.
void setMode(bool isFrozen)
Set the mode [frozen = 1, unfrozen = 0].
void setEffectMix(StkFloat mix)
Set the effect mix [0 = mostly dry, 1 = mostly wet].
StkFrames & tick(StkFrames &iFrames, StkFrames &oFrames, unsigned int iChannel=0, unsigned int oChannel=0)
Take one or two channels of the iFrames object as inputs to the effect and write stereo outputs to th...
StkFloat getRoomSize(void)
Get the room size (comb filter feedback gain) parameter.
STK one-pole filter class.
Definition: OnePole.h:21
StkFloat tick(StkFloat input)
Input one sample to the filter and return one output.
Definition: OnePole.h:80
An STK class to handle vectorized audio data.
Definition: Stk.h:287
static void handleError(const char *message, StkError::Type type)
Static function for error reporting and handling using c-strings.
The STK namespace.
Definition: ADSR.h:8