The Synthesis ToolKit in C++ (STK)

Home Information Classes Download Usage Mail List Requirements Links FAQ Tutorial

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
8namespace stk {
9
10/***********************************************************************/
24/***********************************************************************/
25
26 class FreeVerb : public Effect
27{
28 public:
30
36 FreeVerb();
37
39 ~FreeVerb();
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::Delay
STK non-interpolating delay line class.
Definition Delay.h:25
stk::Effect::Effect
Effect(void)
Class constructor.
Definition Effect.h:25
stk::FreeVerb::tick
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
stk::FreeVerb::~FreeVerb
~FreeVerb()
Destructor.
stk::FreeVerb::clear
void clear(void)
Clears delay lines, etc.
stk::FreeVerb::update
void update(void)
Update interdependent parameters.
stk::FreeVerb::tick
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.
stk::FreeVerb::getDamping
StkFloat getDamping(void)
Get the damping parameter.
stk::FreeVerb::setRoomSize
void setRoomSize(StkFloat value)
Set the room size (comb filter feedback gain) parameter [0,1].
stk::FreeVerb::getMode
StkFloat getMode(void)
Get the current freeze mode [frozen = 1, unfrozen = 0].
stk::FreeVerb::setWidth
void setWidth(StkFloat value)
Set the width (left-right mixing) parameter [0,1].
stk::FreeVerb::setDamping
void setDamping(StkFloat value)
Set the damping parameter [0=low damping, 1=higher damping].
stk::FreeVerb::tick
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...
stk::FreeVerb::lastOut
StkFloat lastOut(unsigned int channel=0)
Return the specified channel value of the last computed stereo frame.
Definition FreeVerb.h:165
stk::FreeVerb::FreeVerb
FreeVerb()
FreeVerb Constructor.
stk::FreeVerb::getWidth
StkFloat getWidth(void)
Get the width (left-right mixing) parameter.
stk::FreeVerb::setMode
void setMode(bool isFrozen)
Set the mode [frozen = 1, unfrozen = 0].
stk::FreeVerb::setEffectMix
void setEffectMix(StkFloat mix)
Set the effect mix [0 = mostly dry, 1 = mostly wet].
stk::FreeVerb::getRoomSize
StkFloat getRoomSize(void)
Get the room size (comb filter feedback gain) parameter.
stk::OnePole
STK one-pole filter class.
Definition OnePole.h:21
stk::StkFrames
An STK class to handle vectorized audio data.
Definition Stk.h:279
stk::Stk::handleError
static void handleError(const char *message, StkError::Type type)
Static function for error reporting and handling using c-strings.
stk
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.