summaryrefslogtreecommitdiffstats
path: root/lib/reverb
diff options
context:
space:
mode:
authorRJ Ryan <rryan@mixxx.org>2015-06-09 22:50:53 -0400
committerRJ Ryan <rryan@mixxx.org>2015-06-09 22:52:10 -0400
commit2480715617c48bb2a351ea22880526fb24920c62 (patch)
treea6e72ca178b5b29b9989807ef0649a0b68274355 /lib/reverb
parent56f586470db4b88b2c812982da8ae119f541257d (diff)
Move reverb plugin to lib/reverb.
Diffstat (limited to 'lib/reverb')
-rw-r--r--lib/reverb/Reverb.cc161
-rw-r--r--lib/reverb/Reverb.h174
-rw-r--r--lib/reverb/basics.h161
-rw-r--r--lib/reverb/dsp/Delay.h150
-rw-r--r--lib/reverb/dsp/FPTruncateMode.h87
-rw-r--r--lib/reverb/dsp/OnePole.h118
-rw-r--r--lib/reverb/dsp/Sine.h116
-rw-r--r--lib/reverb/dsp/util.h70
8 files changed, 1037 insertions, 0 deletions
diff --git a/lib/reverb/Reverb.cc b/lib/reverb/Reverb.cc
new file mode 100644
index 0000000000..787e80a5af
--- /dev/null
+++ b/lib/reverb/Reverb.cc
@@ -0,0 +1,161 @@
+/*
+ Reverb.cc
+
+ Copyright 2002-13 Tim Goetze <tim@quitte.de>
+
+ Port from LADSPA to Mixxx 2014 by Owen Williams <owilliams@mixxx.org>,
+ Mostly just deleting excess code.
+
+ http://quitte.de/dsp/
+
+ Three reverb units: JVRev, Plate and PlateX2.
+
+ The former is a rewrite of STK's JVRev, a traditional design.
+
+ Original comment:
+
+ This is based on some of the famous
+ Stanford CCRMA reverbs (NRev, KipRev)
+ all based on the Chowning/Moorer/
+ Schroeder reverberators, which use
+ networks of simple allpass and comb
+ delay filters.
+
+ The algorithm is mostly unchanged in this implementation; the delay
+ line lengths have been fiddled with to make the stereo field more
+ evenly weighted, denormal protection and a bandwidth control have been
+ added as well.
+
+ The latter two are based on the circuit discussed in Jon Dattorro's
+ September 1997 JAES paper on effect design (part 1: reverb & filters).
+*/
+/*
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 3
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA or point your web browser to http://www.gnu.org.
+*/
+#include "Reverb.h"
+
+/* //////////////////////////////////////////////////////////////////////// */
+
+void
+PlateStub::init()
+{
+ f_lfo = -1;
+ // TODO(owilliams): use actual sample rate.
+ fs = 44100;
+
+# define L(i) ((int) (l[i] * fs))
+ static float l[] = {
+ 0.004771345048889486, 0.0035953092974026408,
+ 0.01273478713752898, 0.0093074829474816042,
+ 0.022579886428547427, 0.030509727495715868,
+ 0.14962534861059779, 0.060481838647894894, 0.12499579987231611,
+ 0.14169550754342933, 0.089244313027116023, 0.10628003091293972
+ };
+
+ /* lh */
+ input.lattice[0].init (L(0));
+ input.lattice[1].init (L(1));
+
+ /* rh */
+ input.lattice[2].init (L(2));
+ input.lattice[3].init (L(3));
+
+ /* modulated, width about 12 samples @ 44.1 */
+ tank.mlattice[0].init (L(4), (int) (0.000403221 * fs));
+ tank.mlattice[1].init (L(5), (int) (0.000403221 * fs));
+
+ /* lh */
+ tank.delay[0].init (L(6));
+ tank.lattice[0].init (L(7));
+ tank.delay[1].init (L(8));
+
+ /* rh */
+ tank.delay[2].init (L(9));
+ tank.lattice[1].init (L(10));
+ tank.delay[3].init (L(11));
+# undef L
+
+# define T(i) ((int) (t[i] * fs))
+ static float t[] = {
+ 0.0089378717113000241, 0.099929437854910791, 0.064278754074123853,
+ 0.067067638856221232, 0.066866032727394914, 0.006283391015086859,
+ 0.01186116057928161, 0.12187090487550822, 0.041262054366452743,
+ 0.089815530392123921, 0.070931756325392295, 0.011256342192802662
+ };
+
+ for (int i = 0; i < 12; ++i)
+ tank.taps[i] = T(i);
+# undef T
+
+ /* tuned for soft attack, ambience */
+ indiff1 = .742;
+ indiff2 = .712;
+
+ dediff1 = .723;
+ dediff2 = .729;
+}
+
+void
+PlateStub::process (sample_t x, sample_t decay, sample_t * _xl, sample_t * _xr)
+{
+ x = input.bandwidth.process (x);
+
+ /* lh */
+ x = input.lattice[0].process (x, indiff1);
+ x = input.lattice[1].process (x, indiff1);
+
+ /* rh */
+ x = input.lattice[2].process (x, indiff2);
+ x = input.lattice[3].process (x, indiff2);
+
+ /* summation point */
+ register double xl = x + decay * tank.delay[3].get();
+ register double xr = x + decay * tank.delay[1].get();
+
+ /* lh */
+ xl = tank.mlattice[0].process (xl, dediff1);
+ xl = tank.delay[0].putget (xl);
+ xl = tank.damping[0].process (xl);
+ xl *= decay;
+ xl = tank.lattice[0].process (xl, dediff2);
+ tank.delay[1].put (xl);
+
+ /* rh */
+ xr = tank.mlattice[1].process (xr, dediff1);
+ xr = tank.delay[2].putget (xr);
+ xr = tank.damping[1].process (xr);
+ xr *= decay;
+ xr = tank.lattice[1].process (xr, dediff2);
+ tank.delay[3].put (xr);
+
+ /* gather output */
+ xl = .6 * tank.delay[2] [tank.taps[0]];
+ xl += .6 * tank.delay[2] [tank.taps[1]];
+ xl -= .6 * tank.lattice[1] [tank.taps[2]];
+ xl += .6 * tank.delay[3] [tank.taps[3]];
+ xl -= .6 * tank.delay[0] [tank.taps[4]];
+ xl += .6 * tank.lattice[0] [tank.taps[5]];
+
+ xr = .6 * tank.delay[0] [tank.taps[6]];
+ xr += .6 * tank.delay[0] [tank.taps[7]];
+ xr -= .6 * tank.lattice[0] [tank.taps[8]];
+ xr += .6 * tank.delay[1] [tank.taps[9]];
+ xr -= .6 * tank.delay[2] [tank.taps[10]];
+ xr += .6 * tank.lattice[1] [tank.taps[11]];
+
+ *_xl = xl;
+ *_xr = xr;
+}
diff --git a/lib/reverb/Reverb.h b/lib/reverb/Reverb.h
new file mode 100644
index 0000000000..5a341e6835
--- /dev/null
+++ b/lib/reverb/Reverb.h
@@ -0,0 +1,174 @@
+/*
+ Reverb.h
+
+ Copyright 2002-13 Tim Goetze <tim@quitte.de>
+
+ http://quitte.de/dsp/
+
+ two reverb units: JVRev and Plate.
+
+ the former is a rewrite of STK's JVRev, a traditional design.
+
+ original comment:
+
+ This is based on some of the famous
+ Stanford CCRMA reverbs (NRev, KipRev)
+ all based on the Chowning/Moorer/
+ Schroeder reverberators, which use
+ networks of simple allpass and comb
+ delay filters.
+
+ (STK is an effort of Gary Scavone).
+
+ the algorithm is mostly unchanged in this implementation; the delay
+ line lengths have been fiddled with to make the stereo field more
+ evenly weighted, and denormal protection has been added.
+
+ the Plate reverb is based on the circuit discussed in Jon Dattorro's
+ september 1997 JAES paper on effect design (part 1: reverb & filters).
+*/
+/*
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 3
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA or point your web browser to http://www.gnu.org.
+*/
+
+#ifndef _REVERB_H_
+#define _REVERB_H_
+
+#include <stdio.h>
+
+#include "basics.h"
+#include "dsp/Delay.h"
+#include "dsp/OnePole.h"
+#include "dsp/Sine.h"
+#include "dsp/util.h"
+
+/* both reverbs use this */
+class Lattice
+: public DSP::Delay
+{
+ public:
+ inline sample_t
+ process (sample_t x, double d)
+ {
+ sample_t y = get();
+ x -= d * y;
+ put (x);
+ return d * x + y;
+ }
+};
+
+/* /////////////////////////////////////////////////////////////////////// */
+
+class ModLattice
+{
+ public:
+ float n0, width;
+
+ DSP::Delay delay;
+ DSP::Sine lfo;
+
+ void init (int n, int w)
+ {
+ n0 = n;
+ width = w;
+ delay.init (n + w);
+ }
+
+ void reset()
+ {
+ delay.reset();
+ }
+
+ inline sample_t
+ process (sample_t x, double d)
+ {
+ sample_t y = delay.get_linear (n0 + width * lfo.get());
+ x += d * y;
+ delay.put (x);
+ return y - d * x; /* note sign */
+ }
+};
+
+class PlateStub
+{
+ public:
+ sample_t f_lfo;
+
+ sample_t indiff1, indiff2, dediff1, dediff2;
+
+ struct {
+ DSP::OnePoleLP<sample_t> bandwidth;
+ Lattice lattice[4];
+ } input;
+
+ struct {
+ ModLattice mlattice[2];
+ Lattice lattice[2];
+ DSP::Delay delay[4];
+ DSP::OnePoleLP<sample_t> damping[2];
+ int taps[12];
+ } tank;
+
+ public:
+ void init();
+ void activate()
+ {
+ input.bandwidth.reset();
+
+ for (int i = 0; i < 4; ++i)
+ {
+ input.lattice[i].reset();
+ tank.delay[i].reset();
+ }
+
+ for (int i = 0; i < 2; ++i)
+ {
+ tank.mlattice[i].reset();
+ tank.lattice[i].reset();
+ tank.damping[i].reset();
+ }
+
+ tank.mlattice[0].lfo.set_f (1.2, fs, 0);
+ tank.mlattice[1].lfo.set_f (1.2, fs, .5 * M_PI);
+ }
+
+ // Process a single mono sample, returning a left and right reverbed
+ // sample.
+ void process (sample_t x, sample_t decay,
+ sample_t * xl, sample_t * xr);
+
+ private:
+ float fs; // sameple rate;
+};
+
+class MixxxPlateX2 : public PlateStub {
+ public:
+ void setBandwidth(double bandwidth) {
+ input.bandwidth.set(exp(-M_PI * (1. - bandwidth)));
+ }
+
+ void setDecay(double decay_control) {
+ double damp = exp(-M_PI * decay_control);
+ tank.damping[0].set(damp);
+ tank.damping[1].set(damp);
+ }
+
+ void process(sample_t x, sample_t decay, sample_t * xl, sample_t * xr) {
+ PlateStub::process(x, decay, xl, xr);
+ }
+};
+
+#endif /* _REVERB_H_ */
diff --git a/lib/reverb/basics.h b/lib/reverb/basics.h
new file mode 100644
index 0000000000..36275ae796
--- /dev/null
+++ b/lib/reverb/basics.h
@@ -0,0 +1,161 @@
+/*
+ basics.h
+
+ Copyright 2004-12 Tim Goetze <tim@quitte.de>
+
+ http://quitte.de/dsp/
+
+ Common constants, typedefs, utility functions
+ and simplified LADSPA #defines.
+
+ Some code removed by Owen Williams for port to Mixxx, mostly ladspa-specific
+ defines and i386 customizations.
+
+*/
+/*
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 3
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA or point your web browser to http://www.gnu.org.
+*/
+
+#ifndef _BASICS_H_
+#define _BASICS_H_
+
+// NOTE(rryan): 3/2014 Added for MSVC support. (missing M_PI)
+#define _USE_MATH_DEFINES
+#include <cmath>
+
+#include <stdlib.h>
+#include <string.h>
+
+#include <math.h>
+#include <float.h>
+
+#include <assert.h>
+#include <stdio.h>
+
+#include "util/types.h"
+typedef CSAMPLE sample_t;
+
+// NOTE(rryan): 3/2014 Added these for the MSVC build.
+#include <QtGlobal>
+typedef qint8 int8;
+typedef quint8 uint8;
+typedef qint16 int16;
+typedef quint16 uint16;
+typedef qint32 int32;
+typedef quint32 uint32;
+typedef qint64 int64;
+typedef quint64 uint64;
+
+#define MIN_GAIN .000001 /* -120 dB */
+/* smallest non-denormal 32 bit IEEE float is 1.18e-38 */
+#define NOISE_FLOOR .00000000000005 /* -266 dB */
+
+/* //////////////////////////////////////////////////////////////////////// */
+
+typedef unsigned int uint;
+typedef unsigned long ulong;
+
+/* prototype that takes a sample and yields a sample */
+typedef CSAMPLE (*clip_func_t) (CSAMPLE);
+
+/* flavours for sample store functions run() and run_adding() */
+typedef void (*yield_func_t) (CSAMPLE *, uint, CSAMPLE, CSAMPLE);
+
+inline void
+adding_func (CSAMPLE * s, uint i, CSAMPLE x, CSAMPLE gain)
+{
+ s[i] += gain * x;
+}
+
+#ifndef max
+
+template <class X, class Y>
+X min (X x, Y y)
+{
+ return x < y ? x : (X) y;
+}
+
+template <class X, class Y>
+X max (X x, Y y)
+{
+ return x > y ? x : (X) y;
+}
+
+#endif /* ! max */
+
+template <class T>
+T clamp (T value, T lower, T upper)
+{
+ if (value < lower) return lower;
+ if (value > upper) return upper;
+ return value;
+}
+
+static inline float
+frandom()
+{
+ return (float) rand() / (float) RAND_MAX;
+}
+
+/* NB: also true if 0 */
+inline bool
+is_denormal (float & f)
+{
+ int32 i = *((int32 *) &f);
+ return ((i & 0x7f800000) == 0);
+}
+
+/* not used, check validity before using */
+inline bool
+is_denormal (double & f)
+{
+ int64 i = *((int64 *) &f);
+ return ((i & 0x7fe0000000000000ll) == 0);
+}
+
+/* lovely algorithm from
+ http://graphics.stanford.edu/~seander/bithacks.html#RoundUpPowerOf2Float
+*/
+inline uint
+next_power_of_2 (uint n)
+{
+ assert (n <= 0x40000000);
+
+ --n;
+ n |= n >> 1;
+ n |= n >> 2;
+ n |= n >> 4;
+ n |= n >> 8;
+ n |= n >> 16;
+
+ return ++n;
+}
+
+inline double
+db2lin (double db)
+{
+ return pow(10, db*.05);
+}
+
+inline double
+lin2db (double lin)
+{
+ return 20*log10(lin);
+}
+
+/* //////////////////////////////////////////////////////////////////////// */
+
+#endif /* _BASICS_H_ */
diff --git a/lib/reverb/dsp/Delay.h b/lib/reverb/dsp/Delay.h
new file mode 100644
index 0000000000..47a6dfcdf5
--- /dev/null
+++ b/lib/reverb/dsp/Delay.h
@@ -0,0 +1,150 @@
+/*
+ dsp/Delay.h
+
+ Copyright 2003-13 Tim Goetze <tim@quitte.de>
+
+ http://quitte.de/dsp/
+
+ delay lines with fractional (linear or cubic interpolation) lookup
+ and an allpass interpolating tap (which needs more work).
+
+ delay line storage is aligned to powers of two for simplified wrapping
+ checks (no conditional or modulo, binary 'and' suffices instead).
+
+*/
+/*
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 3
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA or point your web browser to http://www.gnu.org.
+*/
+
+#ifndef _DSP_DELAY_H_
+#define _DSP_DELAY_H_
+
+#include "util.h"
+#include "FPTruncateMode.h"
+
+namespace DSP {
+
+class Delay
+{
+ public:
+ uint size;
+ sample_t * data;
+ uint read, write;
+
+ Delay() { read = write = 0; data = 0; }
+
+ ~Delay() { free (data); }
+
+ void init (uint n)
+ {
+ size = next_power_of_2 (n);
+ assert (size <= (1 << 20));
+ data = (sample_t *) calloc (sizeof (sample_t), size);
+ --size; /* used as mask for confining access */
+ write = n;
+ }
+
+ void reset()
+ {
+ memset (data, 0, (size + 1) * sizeof (sample_t));
+ }
+
+ sample_t & operator [] (int i) { return data [(write - i) & size]; }
+
+ inline void put (sample_t x)
+ {
+ data [write] = x;
+ write = (write + 1) & size;
+ }
+
+ inline sample_t get()
+ {
+ sample_t x = data [read];
+ read = (read + 1) & size;
+ return x;
+ }
+ inline sample_t peek() { return data [read]; }
+ inline sample_t putget (sample_t x) {put(x); return get();}
+
+ /* fractional lookup, linear interpolation */
+ inline sample_t get_linear (float f)
+ {
+ int n;
+ fistp (f, n); /* read: i = (int) f; relies on FPTruncateMode */
+ f -= n;
+
+ return (1 - f) * (*this) [n] + f * (*this) [n + 1];
+ }
+
+ /* fractional lookup, cubic interpolation */
+ inline sample_t get_cubic (float f)
+ {
+ int n;
+ fistp (f, n); /* see FPTruncateMode */
+ f -= n;
+
+ sample_t x_1 = (*this) [n - 1];
+ sample_t x0 = (*this) [n];
+ sample_t x1 = (*this) [n + 1];
+ sample_t x2 = (*this) [n + 2];
+
+ /* sample_t (32bit) quicker than double here */
+ register sample_t a =
+ (3 * (x0 - x1) - x_1 + x2) * .5;
+ register sample_t b =
+ 2 * x1 + x_1 - (5 * x0 + x2) * .5;
+ register sample_t c =
+ (x1 - x_1) * .5;
+
+ return x0 + (((a * f) + b) * f + c) * f;
+ }
+};
+
+class MovingAverage
+: public Delay
+{
+ public:
+ sample_t state, over_n;
+
+ void init (uint n)
+ {
+ this->Delay::init (n);
+ over_n = 1. / n;
+ /* adjust write pointer so we have a full history of zeros */
+ write = (write + size + 1) & size;
+ state = 0;
+ }
+
+ void reset()
+ {
+ this->Delay::reset();
+ state = 0;
+ }
+
+ void process (sample_t x)
+ {
+ x *= over_n;
+ state -= this->Delay::get();
+ state += x;
+ this->Delay::put (x);
+ }
+
+ sample_t get() { return state; }
+};
+
+}; /* namespace DSP */
+
+#endif /* _DSP_DELAY_H_ */
diff --git a/lib/reverb/dsp/FPTruncateMode.h b/lib/reverb/dsp/FPTruncateMode.h
new file mode 100644
index 0000000000..6ffe4e43da
--- /dev/null
+++ b/lib/reverb/dsp/FPTruncateMode.h
@@ -0,0 +1,87 @@
+/*
+ FPTruncateMode.h
+
+ Copyright 2001-11 Tim Goetze <tim@quitte.de>
+
+ http://quitte.de/dsp/
+
+ Sets the FP rounding mode to 'truncate' in the constructor
+ and loads the previous FP conrol word in the destructor.
+
+ By directly using the machine instruction to convert float to int
+ we avoid the performance hit that loading the control word twice for
+ every (int) cast causes on i386.
+
+ On other architectures this is a no-op.
+
+*/
+/*
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 3
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA or point your web browser to http://www.gnu.org.
+*/
+
+
+#ifndef _DSP_FP_TRUNCATE_MODE_H_
+#define _DSP_FP_TRUNCATE_MODE_H_
+
+#ifdef __i386__
+ #define fstcw(i) \
+ __asm__ __volatile__ ("fstcw %0" : "=m" (i))
+
+ #define fldcw(i) \
+ __asm__ __volatile__ ("fldcw %0" : : "m" (i))
+
+ /* gcc chokes on __volatile__ sometimes. */
+ #define fistp(f,i) \
+ __asm__ ("fistpl %0" : "=m" (i) : "t" (f) : "st")
+#else /* ! __i386__ */
+ #define fstcw(i)
+ #define fldcw(i)
+
+ #define fistp(f,i) \
+ i = (int) f
+#endif
+
+namespace DSP {
+
+static inline int
+fast_trunc (float f)
+{
+ int i;
+ fistp (f, i);
+ return i;
+}
+
+class FPTruncateMode
+{
+ public:
+ int cw0, cw1; /* fp control word */
+
+ FPTruncateMode()
+ {
+ fstcw (cw0);
+ cw1 = cw0 | 0xC00;
+ fldcw (cw1);
+ }
+
+ ~FPTruncateMode()
+ {
+ fldcw (cw0);
+ }
+};
+
+} /* namespace DSP */
+
+#endif /* _DSP_FP_TRUNCATE_MODE_H_ */
diff --git a/lib/reverb/dsp/OnePole.h b/lib/reverb/dsp/OnePole.h
new file mode 100644
index 0000000000..95262f9dc8
--- /dev/null
+++ b/lib/reverb/dsp/OnePole.h
@@ -0,0 +1,118 @@
+/*
+ dsp/OnePole.h
+
+ Copyright 2003-13 Tim Goetze <tim@quitte.de>
+
+ http://quitte.de/dsp/
+
+ one pole (or one zero, or one zero, one pole) hi- and lo-pass filters.
+
+*/
+/*
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 3
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA or point your web browser to http://www.gnu.org.
+*/
+
+#ifndef _ONE_POLE_H_
+#define _ONE_POLE_H_
+
+namespace DSP {
+
+template <class T>
+class OnePoleLP
+{
+ public:
+ T a0, b1, y1;
+
+ OnePoleLP (double d = 1.)
+ {
+ set (d);
+ y1 = 0.;
+ }
+
+ inline void reset()
+ {
+ y1 = 0.;
+ }
+
+ inline void set_f (T fc)
+ {
+ set (1 - exp(-2*M_PI*fc));
+ }
+
+ inline void set (T d)
+ {
+ a0 = d;
+ b1 = 1 - d;
+ }
+
+ inline T process (T x)
+ {
+ return y1 = a0*x + b1*y1;
+ }
+
+ inline void decay (T d)
+ {
+ a0 *= d;
+ b1 = 1. - a0;
+ }
+};
+
+template <class T>
+class OnePoleHP
+{
+ public:
+ T a0, a1, b1, x1, y1;
+
+ OnePoleHP (T d = 1.)
+ {
+ set (d);
+ x1 = y1 = 0.;
+ }
+
+ void set_f (T f)
+ {
+ set (exp (-2*M_PI*f));
+ }
+
+ inline void set (T d)
+ {
+ a0 = .5*(1. + d);
+ a1 = -.5*(1. + d);
+ b1 = d;
+ }
+
+ inline T process (T x)
+ {
+ y1 = a0*x + a1*x1 + b1*y1;
+ x1 = x;
+ return y1;
+ }
+
+ void identity()
+ {
+ a0=1;
+ a1=b1=0;
+ }
+
+ void reset()
+ {
+ x1 = y1 = 0;
+ }
+};
+
+} /* namespace DSP */
+
+#endif /* _ONE_POLE_H_ */
diff --git a/lib/reverb/dsp/Sine.h b/lib/reverb/dsp/Sine.h
new file mode 100644
index 0000000000..86c3a47c3b
--- /dev/null
+++ b/lib/reverb/dsp/Sine.h
@@ -0,0 +1,116 @@
+/*
+ dsp/Sine.h
+
+ Copyright 2003-13 Tim Goetze <tim@quitte.de>
+
+ http://quitte.de/dsp/
+
+ Direct form I recursive sin() generator. Utilising doubles
+ for stability.
+
+*/
+/*
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 3
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA or point your web browser to http://www.gnu.org.
+*/
+
+#ifndef _DSP_SINE_H_
+#define _DSP_SINE_H_
+
+namespace DSP {
+
+class Sine
+{
+ public:
+ int z;
+ double y[2];
+ double b;
+
+ public:
+ Sine()
+ {
+ b = 0;
+ y[0] = y[1] = 0;
+ z = 0;
+ }
+
+ Sine (double f, double fs, double phase)
+ {
+ set_f (f, fs, phase);
+ }
+
+ Sine (double w, double phase = 0.)
+ {
+ set_f (w, phase);
+ }
+
+ inline void set_f (double f, double fs, double phase)
+ {
+ set_f (f*2*M_PI/fs, phase);
+ }
+
+ inline void set_f (double w, double phase)
+ {
+ b = 2 * cos (w);
+ y[0] = sin (phase - w);
+ y[1] = sin (phase - w * 2);
+ z = 0;
+ }
+
+ /* advance and return 1 sample */
+ inline double get()
+ {
+ register double s = b * y[z];
+ z ^= 1;
+ s -= y[z];
+ return y[z] = s;
+ }
+
+ double get_phase()
+ {
+ double x0 = y[z], x1 = b * y[z] - y[z^1];
+ double phi = asin (x0);
+
+ /* slope is falling, we're into the 2nd half. */
+ if (x1 < x0)
+ return M_PI - phi;
+
+ return phi;
+ }
+};
+
+/* same as above but including a damping coefficient d */
+class DampedSine
+: public Sine
+{
+ public:
+ double d;
+
+ public:
+ DampedSine()
+ { d = 1; }
+
+ inline double get()
+ {
+ register double s = b * y[z];
+ z ^= 1;
+ s -= d * y[z];
+ return y[z] = d * s;
+ }
+};
+
+} /* namespace DSP */
+
+#endif /* _DSP_SINE_H_ */
diff --git a/lib/reverb/dsp/util.h b/lib/reverb/dsp/util.h
new file mode 100644
index 0000000000..afc6d48bad
--- /dev/null
+++ b/lib/reverb/dsp/util.h
@@ -0,0 +1,70 @@
+/*
+ dsp/util.h
+
+ Copyright 2002-12 Tim Goetze <tim@quitte.de>
+
+ http://quitte.de/dsp/
+
+ Common math utility functions.
+
+*/
+/*
+ This program is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ as published by the Free Software Foundation; either version 3
+ of the License, or (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA or point your web browser to http://www.gnu.org.
+*/
+
+#ifndef _DSP_UTIL_H_
+#define _DSP_UTIL_H_
+
+namespace DSP {
+
+inline float pow2 (float x) { return x * x; }
+inline float pow3 (float x) { return x * pow2(x); }
+inline float pow4 (float x) { return pow2 (pow2(x)); }
+inline float pow5 (float x) { return x * pow4(x); }
+inline float pow6 (float x) { return pow3 (pow2(x)); }
+inline float pow7 (float x) { return x * (pow6 (x)); }
+inline float pow8 (float x) { return pow2 (pow4 (x)); }
+
+inline float
+sgn (float x)
+{
+ union { float f; uint32 i; } u;
+ u.f = x;
+ u.i &= 0x80000000;
+ u.i |= 0x3F800000;
+ return u.f;
+}
+
+inline bool
+isprime (int v)
+{
+ if (v <= 3)
+ return true;
+
+ if (!(v & 1))
+ return false;
+
+ // NOTE(rryan): float cast added for MSVC.
+ for (int i = 3; i < (int) sqrt ((float)v) + 1; i += 2)
+ if ((v % i) == 0)
+ return false;
+
+ return true;
+}
+
+} /* namespace DSP */
+
+#endif /* _DSP_UTIL_H_ */