CSL  6.0
Freeverb.cpp
Go to the documentation of this file.
1 //
2 // Reverb.h -- The CSL port of the public domain Freeverb reverberator
3 // Freeverb was written by Jezar at Dreampoint, June 2000 -- http://www.dreampoint.co.uk
4 // See the copyright notice and acknowledgment of authors in the file COPYRIGHT
5 //
6 
7 #include "Freeverb.h"
8 
9 //#undef GCC_AUTO_VECTORIZATION
10 
11 using namespace csl;
12 
13 // These values assume 44.1KHz sample rate
14 // they will probably be OK for 48KHz sample rate
15 // but would need scaling for 96KHz (or other) sample rates.
16 // The values were obtained by listening tests.
17 
18 const int kNumCombs = 8;
19 const int kNumAllpasses = 4;
20 const float kMuted = 0.0f;
21 const float kFixedGain = 0.015f;
22 //const float kFixedGain = 1.0f;
23 const float kScaleWet = 3.0f;
24 const float kScaleDry = 2.0f;
25 const float kScaleDamp = 0.4f;
26 const float kScaleRoom = 0.28f;
27 const float kOffsetRoom = 0.7f;
28 const float kInitialRoom = 0.95;
29 const float kInitialDamp = 0.5f;
30 const float kInitialWet = 0.5;
31 const float kInitialDry = 0.5;
32 const float kInitialWidth = 1.0f;
33 const float kInitialMode = 0.0f;
34 const float kFreezeMode = 1.0f;
35 const int kStereoSpread = 23;
36 
37 const int kCombBufferSizes[] = { 1116, 1188, 1277, 1356, 1422, 1491, 1557, 1617 };
38 const int kAllpassBufferSizes[] = { 556, 441, 341, 225 };
39 
40 // ~~~~~~ Comb implementation ~~~~~~~~~~ //
41 
42 void Comb::setBuffer(float *buf, int size) {
43  mBufferPtr = buf;
44  mBufSize = size;
45 }
46 
47 void Comb::mute() {
48  for (int i = 0; i < mBufSize; ++i)
49  mBufferPtr[i] = 0;
50 }
51 
52 void Comb::setDamp(float val) {
53  mDamp1 = val;
54  mDamp2 = 1 - val;
55 }
56 
57 // ~~~~~~ Allpass implementation ~~~~~~~~~~ //
58 
59 void FAllpass::setBuffer(float *buf, int size) {
60  mBufferPtr = buf;
61  mBufSize = size;
62 }
63 
65  for (int i = 0; i < mBufSize; i++)
66  mBufferPtr[i] = 0;
67 }
68 
69 // ~~~~~~~ Freeverb implementation ~~~~~~ //
70 
73 }
74 
76  for (unsigned i = 0; i < mCombFilters.size(); i++)
77  delete mCombBuffers[i];
78 
79  for (unsigned i = 0; i < mAllpassFilters.size(); i++)
80  delete mAllpassBuffers[i];
81 
82  std::vector<Comb*>::iterator iComb = mCombFilters.begin();
83  for (; iComb != mCombFilters.end(); ++iComb)
84  delete *iComb;
85 
86  std::vector<FAllpass*>::iterator iAllpass = mAllpassFilters.begin();
87  for (; iAllpass != mAllpassFilters.end(); ++iAllpass)
88  delete *iAllpass;
89 }
90 
92  int i, j;
93  int bufferSize;
94  sample * bufferPtr;
95  Comb *combFilter;
96  FAllpass *allpassFilter;
99 
100  // create buffers and combs
101  for (i = 0; i < kNumCombs; i++) {
102  bufferSize = kCombBufferSizes[i];
103  bufferPtr = new sample[bufferSize];
104  for (j = 0; j < bufferSize; j++)
105  bufferPtr[j] = 0.0f;
106  mCombBuffers[i] = bufferPtr;
107  combFilter = new Comb();
108  combFilter->setBuffer(bufferPtr, bufferSize);
109  mCombFilters.push_back(combFilter);
110  }
111  // create buffers and allpasses
112  for (i = 0; i < kNumAllpasses; i++) {
113  bufferSize = kAllpassBufferSizes[i];
114  bufferPtr = new sample[bufferSize];
115  for (j = 0; j < bufferSize; j++)
116  bufferPtr[j] = 0.0f;
117  mAllpassBuffers[i]= bufferPtr;
118  allpassFilter = new FAllpass();
119  allpassFilter->setBuffer(bufferPtr, bufferSize);
120  allpassFilter->setFeedback(0.5f);
121  mAllpassFilters.push_back(allpassFilter);
122  }
123  // Set default values
129  mGain = kFixedGain;
131 }
132 
134  for (std::vector<Comb*>::iterator iComb = mCombFilters.begin();
135  iComb != mCombFilters.end(); ++iComb) {
136  (*iComb)->setFeedback(mRoomSize);
137  (*iComb)->setDamp(mDampening);
138  }
139 }
140 
141 float Freeverb::roomSize() { return mRoomSize; }
142 
144  mRoomSize = size * kScaleRoom + kOffsetRoom;
146 }
147 
148 float Freeverb::dampening() { return (mDampening * 100.0f) / kScaleDamp; }
149 
150 /// The "damp" parameter can be thought as setting the material of the room walls.
151 
152 void Freeverb::setDampening(float damp) {
153  mDampening = (damp * 0.01f) * kScaleDamp;
155 }
156 
157 float Freeverb::wetLevel() { return mWetLevel; }
158 
159 void Freeverb::setWetLevel(float level) {
160  mWetLevel = level;
162 }
163 
164 float Freeverb::dryLevel() { return mDryLevel; }
165 
166 /// Amount of the original "dry" signal in the output.
167 
168 void Freeverb::setDryLevel(float level) { mDryLevel = level; }
169 
170 float Freeverb::width() { return (mWidth*100.0f); }
171 
172 void Freeverb::setWidth(float twidth) {
173  mWidth = (twidth*0.01f);
175 }
176 
177 // Do the work
178 
179 void Freeverb::nextBuffer(Buffer &outputBuffer, unsigned outBufNum) throw (CException) {
180  unsigned numFrames = outputBuffer.mNumFrames;
181  sample * fp = outputBuffer.buffer(outBufNum);
182  this->pullInput(outputBuffer);
183  sample * inputBuf = mInputPtr;
184  float out, input;
185  unsigned i;
186 #ifdef CSL_DEBUG
187  logMsg("Freeverb nextBuffer");
188 #endif
189  for (i = 0; i < numFrames; i++) {
190  out = 0;
191  input = inputBuf[i] * mGain;
192  // Accumulate comb filters in parallel
193  std::vector<Comb*>::iterator iComb = mCombFilters.begin();
194  for (; iComb != mCombFilters.end(); ++iComb)
195  out += (*iComb)->process(input);
196  // Feed through allpasses in series
197  std::vector<FAllpass*>::iterator iAllpass = mAllpassFilters.begin();
198  for (; iAllpass != mAllpassFilters.end(); ++iAllpass)
199  out = (*iAllpass)->process(out);
200  *fp++ = out * mWetLevel + inputBuf[i] * mDryLevel; // Calculate output REPLACING anything already there
201  }
202 }
203 
204 //// Stereoverb ////////////////////////////////
205 
206 // Constructor sets up splitter/joiner network
207 
209  split = new Splitter(input);
210 
211  leftRev = new Freeverb(* split); // 2 mono reverbs
215 
216  rightRev = new Freeverb(* split);
220 
221  join = new Joiner (* leftRev, * rightRev); // mono-to-stereo joiner
222 }
223 
225  delete split;
226  delete leftRev;
227  delete rightRev;
228  delete join;
229 }
230 
232  return(split->isActive());
233 }
234 
236  leftRev->setRoomSize(size);
237  rightRev->setRoomSize(size);
238 }
239 
240 void Stereoverb::setDampening(float damp) {
241  leftRev->setDampening(damp);
242  rightRev->setDampening(damp);
243 }
244 
245 void Stereoverb::setWetLevel(float level) {
246  leftRev->setWetLevel(level);
247  rightRev->setWetLevel(level);
248 }
249 
250 void Stereoverb::setDryLevel(float level) {
251  leftRev->setDryLevel(level);
252  rightRev->setDryLevel(level);
253 }
254 
255 void Stereoverb::setWidth(float width) {
256  leftRev->setWidth(width);
257  rightRev->setWidth(width);
258 }
259 
260 // next_buffer work-horse method
261 
262 void Stereoverb::nextBuffer(Buffer &outputBuffer) throw (CException) {
263  join->nextBuffer(outputBuffer);
264 }
sample * SampleBuffer
1-channel buffer data type, vector of (sample)
Definition: CSL_Types.h:194
Freeverb * rightRev
Definition: Freeverb.h:155
void constructReverbGraph()
Definition: Freeverb.cpp:91
void logMsg(const char *format,...)
These are the public logging messages.
Definition: CGestalt.cpp:292
float mDamp1
Definition: Freeverb.h:81
AdditiveInstrument.h – Sum-of-sines synthesis instrument class.
Definition: Accessor.h:17
Effect – mix-in for classes that have unit generators as inputs (like filters).
Definition: CSL_Core.h:466
void setWidth(float width)
Currently not used, as this reverb became mono in/out.
Definition: Freeverb.cpp:172
void setDampening(float damp)
Specified in percentage (from 0 to 100%).
Definition: Freeverb.cpp:152
void setDampening(float damp)
Definition: Freeverb.cpp:240
const float kInitialMode
Definition: Freeverb.cpp:33
Splitter * split
Definition: Freeverb.h:156
void setDamp(float val)
Definition: Freeverb.cpp:52
virtual bool isActive()
am I active?
Definition: CSL_Core.cpp:1105
void setBuffer(float *buf, int size)
Definition: Freeverb.cpp:42
void setDryLevel(float level)
Amount of the original "dry" signal in the output.
Definition: Freeverb.cpp:168
const int kAllpassBufferSizes[]
Definition: Freeverb.cpp:38
void setRoomSize(float size)
Setting the room size makes longer tails. The value has a range from 0 to 1.
Definition: Freeverb.cpp:143
std::vector< FAllpass * > mAllpassFilters
Definition: Freeverb.h:52
float roomSize()
Definition: Freeverb.cpp:141
float wetLevel()
Definition: Freeverb.cpp:157
const float kInitialDamp
Definition: Freeverb.cpp:29
void setBuffer(float *buf, int size)
Definition: Freeverb.cpp:59
float dampening()
Definition: Freeverb.cpp:148
const float kScaleWet
Definition: Freeverb.cpp:23
SampleBufferVector mAllpassBuffers
Definition: Freeverb.h:55
const float kInitialRoom
Definition: Freeverb.cpp:28
void setDryLevel(float level)
Definition: Freeverb.cpp:250
void setWetLevel(float level)
Amount of wet (reverberation) in the mixed output.
Definition: Freeverb.cpp:159
const int kStereoSpread
Definition: Freeverb.cpp:35
All-pass filter class.
Definition: Freeverb.h:92
void mute()
Definition: Freeverb.cpp:64
Comb filter class.
Definition: Freeverb.h:65
const float kFreezeMode
Definition: Freeverb.cpp:34
const int kNumAllpasses
Definition: Freeverb.cpp:19
float mRoomSize
Definition: Freeverb.h:43
const float kInitialDry
Definition: Freeverb.cpp:31
float sample
(could be changed to int, or double)
Definition: CSL_Types.h:191
float mWidth
Definition: Freeverb.h:47
void nextBuffer(Buffer &outputBuffer, unsigned outBufNum)
really compute the next buffer given an offset base channel; this is called by nextBuffer, possibly multiple times
Definition: Freeverb.cpp:179
const float kScaleDry
Definition: Freeverb.cpp:24
Freeverb * leftRev
Definition: Freeverb.h:155
void setFeedback(float val)
Definition: Freeverb.h:98
const float kMuted
Definition: Freeverb.cpp:20
void setRoomSize(float size)
Definition: Freeverb.cpp:235
static size_t size
Definition: fft_N.c:40
bool isActive()
am I active?
Definition: Freeverb.cpp:231
CSL port of the public domain Freeverb reverberator.
Definition: Freeverb.h:23
Stereoverb(UnitGenerator &input)
Definition: Freeverb.cpp:208
Splitter class – a de-multiplexer for multi-channel signals.
Definition: CSL_Core.h:633
void setWidth(float width)
Definition: Freeverb.cpp:255
void nextBuffer(Buffer &outputBuffer)
I'm stereo.
Definition: Freeverb.cpp:262
void updateParameters()
Definition: Freeverb.cpp:133
const float kScaleRoom
Definition: Freeverb.cpp:26
float * mBufferPtr
Definition: Freeverb.h:83
float mDryLevel
Definition: Freeverb.h:46
const float kScaleDamp
Definition: Freeverb.cpp:25
float width()
Definition: Freeverb.cpp:170
Buffer – the multi-channel sample buffer class (passed around between generators and IO guys)...
Definition: CSL_Core.h:106
const float kOffsetRoom
Definition: Freeverb.cpp:27
const float kFixedGain
Definition: Freeverb.cpp:21
float mDamp2
Definition: Freeverb.h:82
Joiner class – a multiplexer for multi-channel signals.
Definition: CSL_Core.h:648
Freeverb(UnitGenerator &input)
Definition: Freeverb.cpp:71
float mDampening
Definition: Freeverb.h:44
const float kInitialWet
Definition: Freeverb.cpp:30
std::vector< Comb * > mCombFilters
Definition: Freeverb.h:51
SampleBufferVector mCombBuffers
Definition: Freeverb.h:54
forward declaration
Definition: CSL_Core.h:241
const int kNumCombs
Definition: Freeverb.cpp:18
float mGain
Definition: Freeverb.h:49
float mWetLevel
Definition: Freeverb.h:45
int mBufSize
Definition: Freeverb.h:84
void mute()
Definition: Freeverb.cpp:47
float dryLevel()
Definition: Freeverb.cpp:164
void setWetLevel(float level)
Definition: Freeverb.cpp:245
const float kInitialWidth
Definition: Freeverb.cpp:32
Base class of CSL exceptions (written upper-case). Has a string message.
Joiner * join
Definition: Freeverb.h:157
const int kCombBufferSizes[]
Definition: Freeverb.cpp:37
float * mBufferPtr
Definition: Freeverb.h:105