Allolib  1.0
C++ Components For Interactive Multimedia
al_Reverb.hpp
1 #ifndef INCLUDE_AL_REVERB_HPP
2 #define INCLUDE_AL_REVERB_HPP
3 
4 /* Allocore --
5  Multimedia / virtual environment application class library
6 
7  Copyright (C) 2009. AlloSphere Research Group, Media Arts & Technology,
8  UCSB. Copyright (C) 2012. The Regents of the University of California. All
9  rights reserved.
10 
11  Redistribution and use in source and binary forms, with or without
12  modification, are permitted provided that the following conditions are
13  met:
14 
15  Redistributions of source code must retain the above copyright
16  notice, this list of conditions and the following disclaimer.
17 
18  Redistributions in binary form must reproduce the above
19  copyright notice, this list of conditions and the following disclaimer in the
20  documentation and/or other materials provided with the
21  distribution.
22 
23  Neither the name of the University of California nor the names
24  of its contributors may be used to endorse or promote products derived from
25  this software without specific prior written permission.
26 
27  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
28  IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
29  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
30  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
31  CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
32  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
33  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
34  OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
35  WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
36  OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
37  ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
38 
39  File description:
40  Mono-to-stereo reverberator
41 
42  File author(s):
43  Lance Putnam, 2010, putnam.lance@gmail.com
44 */
45 
46 #include <stdlib.h>
47 #include <string.h>
48 
49 #include <cmath>
50 
51 namespace al {
52 
54 
61 template <int N, class T>
63  public:
64  StaticDelayLine() : mPos(0) { zero(); }
65 
67  static int size() { return N; }
68 
70  const T& back() const { return mBuf[indexBack()]; }
71 
73  int indexBack() const {
74  int i = pos() + 1;
75  return (i < size()) ? i : 0;
76  }
77 
79  int pos() const { return mPos; }
80 
82  const T& read(int i) const {
83  int ind = pos() - i;
84  if (ind < 0) ind += size();
85  // else if(ind >= size()) ind -= size();
86  return mBuf[ind];
87  }
88 
90  void write(const T& v) {
91  mBuf[pos()] = v;
92  ++mPos;
93  if (mPos >= size()) mPos = 0;
94  }
95 
97  T operator()(const T& v) {
98  T r = mBuf[pos()];
99  write(v);
100  return r;
101  }
102 
105  T comb(const T& v, const T& ffd, const T& fbk) {
106  T d = mBuf[pos()];
107  T r = v + d * fbk;
108  write(r);
109  return d + r * ffd;
110  }
111 
114  T allpass(const T& v, const T& ffd) { return comb(v, ffd, -ffd); }
115 
117  void zero() { ::memset(&mBuf, 0, sizeof(mBuf)); }
118 
119  protected:
120  int mPos;
121  T mBuf[N];
122 };
123 
125 
132 template <class T = float>
133 class Reverb {
134  public:
135  Reverb() {
136  bandwidth(0.9995);
137  decay(0.85);
138  damping(0.4);
139  diffusion(0.76, 0.666, 0.707, 0.571);
140  }
141 
143 
147  mOPIn.damping(T(1) - v);
148  return *this;
149  }
150 
152 
156  Reverb& damping(T v) {
157  mOP1.damping(v);
158  mOP2.damping(v);
159  return *this;
160  }
161 
163  Reverb& decay(T v) {
164  mDecay = v;
165  return *this;
166  }
167 
169 
172  Reverb& diffusion(T in1, T in2, T decay1, T decay2) {
173  mDfIn1 = in1;
174  mDfIn2 = in2;
175  mDfDcy1 = decay1;
176  mDfDcy2 = decay2;
177  return *this;
178  }
179 
182  mDfIn1 = v;
183  return *this;
184  }
185 
188  mDfIn2 = v;
189  return *this;
190  }
191 
194  mDfDcy1 = v;
195  return *this;
196  }
197 
200  mDfDcy2 = v;
201  return *this;
202  }
203 
205 
210  void operator()(T in, T& out1, T& out2, T gain = T(0.6)) {
211  T v = mPreDelay(in * T(0.5));
212  v = mOPIn(v);
213  v = mAPIn1.allpass(v, mDfIn1);
214  v = mAPIn2.allpass(v, mDfIn1);
215  v = mAPIn3.allpass(v, mDfIn2);
216  v = mAPIn4.allpass(v, mDfIn2);
217 
218  T a = v + mDly22.back() * mDecay;
219  T b = v + mDly12.back() * mDecay;
220 
221  a = mAPDecay11.allpass(a, -mDfDcy1);
222  a = mDly11(a);
223  a = mOP1(a) * mDecay;
224  a = mAPDecay12.allpass(a, mDfDcy2);
225  mDly12.write(a);
226 
227  b = mAPDecay21.allpass(b, -mDfDcy1);
228  b = mDly21(b);
229  b = mOP2(b) * mDecay;
230  b = mAPDecay22.allpass(b, mDfDcy2);
231  mDly22.write(b);
232 
233  out1 = (mDly21.read(266) + mDly21.read(2974) - mAPDecay22.read(1913) +
234  mDly22.read(1996) - mDly11.read(1990) - mAPDecay12.read(187) -
235  mDly12.read(1066)) *
236  gain;
237 
238  out2 = (mDly11.read(353) + mDly11.read(3627) - mAPDecay12.read(1228) +
239  mDly12.read(2673) - mDly21.read(2111) - mAPDecay22.read(335) -
240  mDly22.read(121)) *
241  gain;
242  }
243 
245 
250  T mix(T& inout1, T& out2, T wetAmt) {
251  T s = inout1;
252  (*this)(s, inout1, out2, wetAmt * T(0.6));
253  inout1 += s;
254  out2 += s;
255  return s;
256  }
257 
258  void zero() {
259  mPreDelay.zero();
260  mAPIn1.zero();
261  mAPIn2.zero();
262  mAPIn3.zero();
263  mAPIn4.zero();
264  mAPDecay11.zero();
265  mAPDecay12.zero();
266  mDly11.zero();
267  mDly12.zero();
268  mAPDecay21.zero();
269  mAPDecay22.zero();
270  mDly21.zero();
271  mDly22.zero();
272  mOPIn.zero();
273  mOP1.zero();
274  mOP2.zero();
275  }
276 
277  protected:
278  class OnePole {
279  public:
280  OnePole() : mO1(0), mA0(1), mB1(0) {}
281  void damping(T v) { coef(v); }
282  void coef(T v) {
283  mA0 = T(1) - std::abs(v);
284  mB1 = v;
285  }
286  T operator()(T i0) { return mO1 = i0 * mA0 + mO1 * mB1; }
287  void zero() { mO1 = 0.0; }
288 
289  protected:
290  T mO1, mA0, mB1;
291  };
292 
293  T mDfIn1, mDfIn2, mDfDcy1, mDfDcy2, mDecay;
294 
295  StaticDelayLine<10, T> mPreDelay;
296  OnePole mOPIn;
301  StaticDelayLine<672, T> mAPDecay11;
302  StaticDelayLine<1800, T> mAPDecay12;
305  OnePole mOP1;
306  StaticDelayLine<908, T> mAPDecay21;
307  StaticDelayLine<2656, T> mAPDecay22;
310  OnePole mOP2;
311 };
312 
313 } // namespace al
314 #endif
Plate reverberator.
Definition: al_Reverb.hpp:133
Reverb & diffusionIn2(T v)
Set input diffusion 2 amount, [0,1)
Definition: al_Reverb.hpp:187
void operator()(T in, T &out1, T &out2, T gain=T(0.6))
Compute wet stereo output from dry mono input.
Definition: al_Reverb.hpp:210
Reverb & diffusion(T in1, T in2, T decay1, T decay2)
Set diffusion amounts, in [0, 1)
Definition: al_Reverb.hpp:172
Reverb & bandwidth(T v)
Set input signal bandwidth, in [0,1].
Definition: al_Reverb.hpp:146
Reverb & damping(T v)
Set high-frequency damping amount, in [0, 1].
Definition: al_Reverb.hpp:156
Reverb & diffusionDecay2(T v)
Set tank decay diffusion 2 amount, [0,1)
Definition: al_Reverb.hpp:199
Reverb & decay(T v)
Set decay factor, in [0, 1)
Definition: al_Reverb.hpp:163
T mix(T &inout1, T &out2, T wetAmt)
Compute wet/dry mix stereo output from dry mono input.
Definition: al_Reverb.hpp:250
Reverb & diffusionDecay1(T v)
Set tank decay diffusion 1 amount, [0,1)
Definition: al_Reverb.hpp:193
Reverb & diffusionIn1(T v)
Set input diffusion 1 amount, [0,1)
Definition: al_Reverb.hpp:181
Delay-line whose maximum size is fixed.
Definition: al_Reverb.hpp:62
const T & read(int i) const
Read value at delay i.
Definition: al_Reverb.hpp:82
void zero()
Zeroes all elements (byte-wise)
Definition: al_Reverb.hpp:117
int pos() const
Get absolute index of write tap.
Definition: al_Reverb.hpp:79
T allpass(const T &v, const T &ffd)
Definition: al_Reverb.hpp:114
static int size()
Get size of delay-line.
Definition: al_Reverb.hpp:67
T operator()(const T &v)
Write new value and return oldest value.
Definition: al_Reverb.hpp:97
int indexBack() const
Get index of back element.
Definition: al_Reverb.hpp:73
const T & back() const
Get element at back.
Definition: al_Reverb.hpp:70
T comb(const T &v, const T &ffd, const T &fbk)
Definition: al_Reverb.hpp:105
void write(const T &v)
Write value to delay.
Definition: al_Reverb.hpp:90
Definition: al_App.hpp:23