diff options
author | RJ Ryan <rryan@mixxx.org> | 2015-06-09 22:50:53 -0400 |
---|---|---|
committer | RJ Ryan <rryan@mixxx.org> | 2015-06-09 22:52:10 -0400 |
commit | 2480715617c48bb2a351ea22880526fb24920c62 (patch) | |
tree | a6e72ca178b5b29b9989807ef0649a0b68274355 /lib/reverb | |
parent | 56f586470db4b88b2c812982da8ae119f541257d (diff) |
Move reverb plugin to lib/reverb.
Diffstat (limited to 'lib/reverb')
-rw-r--r-- | lib/reverb/Reverb.cc | 161 | ||||
-rw-r--r-- | lib/reverb/Reverb.h | 174 | ||||
-rw-r--r-- | lib/reverb/basics.h | 161 | ||||
-rw-r--r-- | lib/reverb/dsp/Delay.h | 150 | ||||
-rw-r--r-- | lib/reverb/dsp/FPTruncateMode.h | 87 | ||||
-rw-r--r-- | lib/reverb/dsp/OnePole.h | 118 | ||||
-rw-r--r-- | lib/reverb/dsp/Sine.h | 116 | ||||
-rw-r--r-- | lib/reverb/dsp/util.h | 70 |
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_ */ |