aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/autowah.cc130
-rw-r--r--src/autowah.h52
-rw-r--r--src/autowah_lv2.cc56
-rw-r--r--src/blvco.cc354
-rw-r--r--src/blvco.h92
-rw-r--r--src/blvco_lv2.cc90
-rw-r--r--src/cs_chorus.cc406
-rw-r--r--src/cs_chorus.h106
-rw-r--r--src/cs_chorus_if.cc247
-rw-r--r--src/cs_chorus_lv2.cc90
-rw-r--r--src/cs_phaser.cc191
-rw-r--r--src/cs_phaser.h66
-rw-r--r--src/cs_phaser_if.cc236
-rw-r--r--src/cs_phaser_lv2.cc73
-rw-r--r--src/exp2ap.h28
-rw-r--r--src/filters.cc113
-rw-r--r--src/filters.h130
-rw-r--r--src/filters_lv2.cc56
-rw-r--r--src/ladspaplugin.h59
-rw-r--r--src/mvchpf24.cc126
-rw-r--r--src/mvchpf24.h46
-rw-r--r--src/mvchpf24_if.cc150
-rw-r--r--src/mvchpf24_lv2.cc87
-rw-r--r--src/mvclpf24.cc439
-rw-r--r--src/mvclpf24.h110
-rw-r--r--src/mvclpf24_if.cc299
-rw-r--r--src/mvclpf24_lv2.cc136
-rw-r--r--src/pareq.cc199
-rw-r--r--src/pareq.h74
-rw-r--r--src/plugin_lv2.h55
-rw-r--r--src/reverbs.cc125
-rw-r--r--src/reverbs.h134
-rw-r--r--src/reverbs_lv2.cc73
-rw-r--r--src/zreverb.cc425
-rw-r--r--src/zreverb.h244
35 files changed, 5297 insertions, 0 deletions
diff --git a/src/autowah.cc b/src/autowah.cc
new file mode 100644
index 0000000..a18c8d3
--- /dev/null
+++ b/src/autowah.cc
@@ -0,0 +1,130 @@
+/*
+ Copyright (C) 2009 Fons Adriaensen <fons@kokkinizita.net>
+
+ 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 2 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+
+#include <math.h>
+#include <string.h>
+#include "autowah.h"
+
+
+void Ladspa_Autowah::setport (PortIndex port, PortData *data)
+{
+ _port [port] = (float*)data;
+}
+
+
+#define G_RES 4.0f
+#define F_MIN 300.0f
+#define F_RAT 10
+#define B_MIN 0.03f
+#define B_RAT 4
+#define T_MIN 0.05f
+#define T_LOG 2
+
+
+void Ladspa_Autowah::active (bool act)
+{
+ if (! act) return;
+
+ _wbase = F_MIN * 6.28f / _fsam;
+ _bbase = B_MIN;
+ _rfact = 64.0f / (_fsam * T_MIN);
+ _z1 = _z2 = 0;
+ _s1 = _s2 = 0;
+ _gx = _gy = 0;
+ _dr = 0;
+}
+
+
+void Ladspa_Autowah::runproc (SampleCount len, bool add)
+{
+ int i, k;
+ float *inp = _port [A_INP];
+ float *out = _port [A_OUT];
+ float z1, z2, s1, s2, gx, gy;
+ float ds1, ds2, dgx, dgy;
+ float gd, rf, md, fr, dr;
+ float b, p, t, w, x, y;
+
+ gx = _gx;
+ gy = _gy;
+ t = _port [C_OPMIX][0];
+ _gy = G_RES * t;
+ _gx = _gy + 1 - t;
+ dgx = (_gx - gx) / len;
+ dgy = (_gy - gy) / len;
+
+ gd = 10 * powf (10.0f, 0.05f * _port [C_DRIVE][0]);
+ rf = 1.0f - _rfact / powf (10.0f, T_LOG * _port [C_DECAY][0]);
+ md = _port [C_RANGE][0];
+ fr = _port [C_FREQ][0];
+
+ z1 = _z1;
+ z2 = _z2;
+ s1 = _s1;
+ s2 = _s2;
+ dr = _dr;
+
+ while (len)
+ {
+ k = (len > 80) ? 64 : len;
+
+ p = 0;
+ for (i = 0; i < k; i++)
+ {
+ x = inp [i];
+ p += x * x;
+ }
+ p = gd * sqrtf (p / k);
+
+ if (p > dr) dr += 0.1f *(p - dr);
+ if (dr > md) dr = md;
+ t = dr + fr;
+ dr = dr * rf + 1e-10f;
+ w = _wbase * (1 + (F_RAT - 1) * t * t);
+ b = w * _bbase * (1 + (B_RAT - 1) * t);
+ if (w > 0.7f) w = 0.7f;
+
+ _s1 = -cosf (w);
+ _s2 = (1 - b) / (1 + b);
+ ds1 = (_s1 - s1) / k;
+ ds2 = (_s2 - s2) / k;
+
+ for (i = 0; i < k; i++)
+ {
+ s1 += ds1;
+ s2 += ds2;
+ gx += dgx;
+ gy += dgy;
+ x = inp [i];
+ y = x - s2 * z2;
+ out [i] = gx * x - gy * (z2 + s2 * y);
+ y -= s1 * z1;
+ z2 = z1 + s1 * y;
+ z1 = y + 1e-10f;
+ }
+ inp += k;
+ out += k;
+ len -= k;
+ }
+
+ _z1 = z1;
+ _z2 = z2;
+ _dr = dr;
+}
+
diff --git a/src/autowah.h b/src/autowah.h
new file mode 100644
index 0000000..79a3d9c
--- /dev/null
+++ b/src/autowah.h
@@ -0,0 +1,52 @@
+/*
+ Copyright (C) 2009 Fons Adriaensen <fons@kokkinizita.net>
+
+ 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 2 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+
+#ifndef __AUTOWAH_H
+#define __AUTOWAH_H
+
+
+#include "ladspaplugin.h"
+
+
+class Ladspa_Autowah : public LadspaPlugin
+{
+public:
+
+ enum { A_INP, A_OUT, C_DRIVE, C_DECAY, C_RANGE, C_FREQ, C_OPMIX, NPORT };
+
+ Ladspa_Autowah (SampleRate fsam) : LadspaPlugin (fsam) {}
+ virtual void setport (PortIndex port, PortData *data);
+ virtual void active (bool act);
+ virtual void runproc (SampleCount len, bool add);
+ virtual ~Ladspa_Autowah (void) {}
+
+private:
+
+ float *_port [NPORT];
+ float _wbase;
+ float _bbase;
+ float _rfact;
+ float _z1, _z2;
+ float _s1, _s2;
+ float _gx, _gy;
+ float _dr;
+};
+
+
+#endif
diff --git a/src/autowah_lv2.cc b/src/autowah_lv2.cc
new file mode 100644
index 0000000..29a64ee
--- /dev/null
+++ b/src/autowah_lv2.cc
@@ -0,0 +1,56 @@
+/*
+ Copyright (C) 2012 David Robillard <d@drobilla.net>
+
+ 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 2 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include <stddef.h>
+
+#include "autowah.h"
+#include "plugin_lv2.h"
+
+extern "C" {
+
+static LV2_Handle
+instantiate(const LV2_Descriptor* descriptor,
+ double rate,
+ const char* bundle_path,
+ const LV2_Feature* const* features)
+{
+ return new Ladspa_Autowah(rate);
+}
+
+static const LV2_Descriptor descriptor = {
+ "http://drobilla.net/plugins/fomp/autowah",
+ instantiate,
+ connect_port,
+ activate,
+ run,
+ deactivate,
+ cleanup,
+ NULL
+};
+
+LV2_SYMBOL_EXPORT
+const LV2_Descriptor*
+lv2_descriptor(uint32_t index)
+{
+ switch (index) {
+ case 0: return &descriptor;
+ default: return NULL;
+ }
+}
+
+} // extern "C"
diff --git a/src/blvco.cc b/src/blvco.cc
new file mode 100644
index 0000000..328f4b0
--- /dev/null
+++ b/src/blvco.cc
@@ -0,0 +1,354 @@
+/*
+ Copyright (C) 2003 Fons Adriaensen
+
+ 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 2 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+
+#include <stdio.h>
+#include <string.h>
+#include <math.h>
+#include "blvco.h"
+#include "exp2ap.h"
+
+extern float exp2ap (float x);
+
+
+static float _pulse [] =
+{
+ 0.000000, 0.000366, 0.001458, 0.003117, 0.005028, 0.006756, 0.007806, 0.007704,
+ 0.006086, 0.002778, -0.002139, -0.008292, -0.015022, -0.021434, -0.026492, -0.029153,
+ -0.028511, -0.023957, -0.015297, -0.002869, 0.012417, 0.029105, 0.045302, 0.058853,
+ 0.067578, 0.069533, 0.063273, 0.048113, 0.024337, -0.006682, -0.042487, -0.079654,
+ -0.114036, -0.141088, -0.156243, -0.155364, -0.135210, -0.093843, -0.030932, 0.052092,
+ 0.152049, 0.264172, 0.382359, 0.499585, 0.608450, 0.701808, 0.773391, 0.818353,
+ 0.833670, 0.818353, 0.773391, 0.701808, 0.608450, 0.499585, 0.382359, 0.264172,
+ 0.152049, 0.052092, -0.030932, -0.093843, -0.135210, -0.155364, -0.156243, -0.141088,
+ -0.114036, -0.079654, -0.042487, -0.006682, 0.024337, 0.048113, 0.063273, 0.069533,
+ 0.067578, 0.058853, 0.045302, 0.029105, 0.012417, -0.002869, -0.015297, -0.023957,
+ -0.028511, -0.029153, -0.026492, -0.021434, -0.015022, -0.008292, -0.002139, 0.002778,
+ 0.006086, 0.007704, 0.007806, 0.006756, 0.005028, 0.003117, 0.001458, 0.000366,
+ 0.000000
+};
+
+
+static const float lg2midc = log2f(261.63f);
+
+
+void Ladspa_VCO_pulse1::setport (PortIndex port, PortData *data)
+{
+ _port [port] = (float*)data;
+}
+
+
+void Ladspa_VCO_pulse1::active (bool act)
+{
+ _p = 0.5;
+ _w = _y = _z = 0;
+ _j = 0;
+ memset (_f, 0, (FILLEN + NCOEFF) * sizeof (float));
+}
+
+
+void Ladspa_VCO_pulse1::runproc (SampleCount len, bool add)
+{
+ int i, j, n;
+ float *outp, *freq, *expm, *linm;
+ float a, p, r, t, w, dw, y, z, *f;
+
+ outp = _port[OUTP];
+ freq = _port[FREQ] - 1;
+ expm = _port[EXPM] - 1;
+ linm = _port[LINM] - 1;
+
+ p = _p;
+ w = _w;
+ y = _y;
+ z = _z;
+ j = _j;
+
+ a = 0.2 + 0.8 * _port [FILT][0];
+ do
+ {
+ n = (len > 24) ? 16 : len;
+ freq += n;
+ expm += n;
+ linm += n;
+ len -= n;
+
+ t = (exp2ap (log2f(*freq) - lg2midc + _port[OCTN][0] + _port[TUNE][0] + *expm * _port[EXPG][0] + 8.03136)
+ + 1e3 * *linm * _port[LING][0]) / _fsam;
+ if (t < 1e-5) t = 1e-5;
+ if (t > 0.5) t = 0.5;
+ dw = (t - w) / n;
+
+ while (n--)
+ {
+ w += dw;
+ p += w;
+ if (p >= 1.0)
+ {
+ p -= 1.0;
+ r = NPHASE * p / w;
+ i = (int) r;
+ r -= i;
+ f = _f + j;
+ while (i < NPHASE * NCOEFF)
+ {
+ *f++ += r * _pulse [i + 1 ] + (1 - r) * _pulse [i];
+ i += NPHASE;
+ }
+ }
+
+ y = _f [j];
+ z += a * (y - z);
+ *outp++ = z;
+ if (++j == FILLEN)
+ {
+ j = 0;
+ memcpy (_f, _f + FILLEN, NCOEFF * sizeof (float));
+ memset (_f + NCOEFF, 0, FILLEN * sizeof (float));
+ }
+ }
+ }
+ while (len);
+
+ _p = p;
+ _w = w;
+ _y = y;
+ _z = z;
+ _j = j;
+}
+
+
+
+void Ladspa_VCO_saw1::setport (PortIndex port, PortData *data)
+{
+ _port [port] = (float*)data;
+}
+
+
+void Ladspa_VCO_saw1::active (bool act)
+{
+ _p = 0.5;
+ _w = _x = _y = _z = _d = 0;
+ _j = 0;
+ memset (_f, 0, (FILLEN + NCOEFF) * sizeof (float));
+}
+
+
+void Ladspa_VCO_saw1::runproc (SampleCount len, bool add)
+{
+ int i, j, n;
+ float *outp, *freq, *expm, *linm, *sync;
+ float a, d, p, r, t, w, dw, x, y, z, *f;
+
+ outp = _port[OUTP];
+ freq = _port[FREQ] - 1;
+ expm = _port[EXPM] - 1;
+ linm = _port[LINM] - 1;
+ sync = _port[SYNC];
+
+ p = _p;
+ w = _w;
+ x = _x;
+ y = _y;
+ z = _z;
+ d = _d;
+ j = _j;
+
+ a = 0.2 + 0.8 * _port [FILT][0];
+ do
+ {
+ n = (len > 24) ? 16 : len;
+ freq += n;
+ expm += n;
+ linm += n;
+ len -= n;
+
+ t = (exp2ap (log2f(*freq) - lg2midc + _port[OCTN][0] + _port[TUNE][0] + *expm * _port[EXPG][0] + 8.03136 + d)
+ + 1e3 * *linm * _port[LING][0]) / _fsam;
+ if (t < 1e-5) t = 1e-5;
+ if (t > 0.5) t = 0.5;
+ dw = (t - w) / n;
+
+ while (n--)
+ {
+ w += dw;
+ p += w;
+ if (p >= 1.0)
+ {
+ p -= 1.0;
+ r = NPHASE * p / w;
+ i = (int) r;
+ r -= i;
+ f = _f + j;
+ while (i < NPHASE * NCOEFF)
+ {
+ *f++ += r * _pulse [i + 1 ] + (1 - r) * _pulse [i];
+ i += NPHASE;
+ }
+ }
+
+ x += _f [j] - w * (0.01 * y + 0.2 * x + 1);
+ y += 6.3 * w * x;
+ z += a * (x - z);
+ *outp++ = z;
+ d += 0.01 * (y * *sync++ - d);
+ if (++j == FILLEN)
+ {
+ j = 0;
+ memcpy (_f, _f + FILLEN, NCOEFF * sizeof (float));
+ memset (_f + NCOEFF, 0, FILLEN * sizeof (float));
+ }
+ }
+ }
+ while (len);
+
+ _p = p;
+ _w = w;
+ _x = x;
+ _y = y;
+ _z = z;
+ _d = d;
+ _j = j;
+}
+
+
+
+void Ladspa_VCO_rec1::setport (PortIndex port, PortData *data)
+{
+ _port [port] = (float*)data;
+}
+
+
+void Ladspa_VCO_rec1::active (bool act)
+{
+ _p = 0.0;
+ _x = _y = _z = _d = 0;
+ _w = 0;
+ _b = 0.5;
+ _j = _k = 0;
+ memset (_f, 0, (FILLEN + NCOEFF) * sizeof (float));
+}
+
+
+void Ladspa_VCO_rec1::runproc (SampleCount len, bool add)
+{
+ int i, j, k, n;
+ float *outp, *freq, *expm, *linm, *wavm, *sync;
+ float a, b, db, d, p, r, t, w, dw, x, y, z, *f;
+
+ outp = _port[OUTP];
+ freq = _port[FREQ] - 1;
+ expm = _port[EXPM] - 1;
+ linm = _port[LINM] - 1;
+ wavm = _port[WAVM] - 1;
+ sync = _port[SYNC];
+
+ p = _p;
+ w = _w;
+ b = _b;
+ x = _x;
+ y = _y;
+ z = _z;
+ d = _d;
+ j = _j;
+ k = _k;
+
+ a = 0.2 + 0.8 * _port [FILT][0];
+ do
+ {
+ n = (len > 24) ? 16 : len;
+ freq += n;
+ expm += n;
+ linm += n;
+ wavm += n;
+ len -= n;
+
+ t = (exp2ap (log2f(*freq) - lg2midc + _port[OCTN][0] + _port[TUNE][0] + *expm * _port[EXPG][0] + 8.03136 + d)
+ + 1e3 * *linm * _port[LING][0]) / _fsam;
+ if (t < 1e-5) t = 1e-5;
+ if (t > 0.5) t = 0.5;
+ dw = (t - w) / n;
+ t = 0.5 * (1.0 + _port [WAVE][0] + *wavm * _port [WMOD][0]);
+ if (t < 0.02) t = 0.02;
+ if (t > 0.98) t = 0.98;
+ db = (t - b) / n;
+
+ while (n--)
+ {
+ w += dw;
+ b += db;
+ p += w;
+ t = k ? 1.0 : b;
+ while (p >= t)
+ {
+ if (k)
+ {
+ k = 0;
+ p -= 1.0;
+ r = NPHASE * p / w;
+ t = b;
+ i = (int) r;
+ r -= i;
+ f = _f + j;
+ while (i < NPHASE * NCOEFF)
+ {
+ *f++ += r * _pulse [i + 1 ] + (1 - r) * _pulse [i];
+ i += NPHASE;
+ }
+ }
+ else
+ {
+ k = 1;
+ r = NPHASE * (p - t) / w;
+ t = 1.0;
+ i = (int) r;
+ r -= i;
+ f = _f + j;
+ while (i < NPHASE * NCOEFF)
+ {
+ *f++ -= r * _pulse [i + 1 ] + (1 - r) * _pulse [i];
+ i += NPHASE;
+ }
+ }
+ }
+ x -= w * (0.01 * y + 0.2 * x);
+ x += _f [j];
+ y += 6.3 * w * x;
+ z += a * (x - z);
+ *outp++ = z;
+ d += 0.01 * (y * *sync++ - d);
+ if (++j == FILLEN)
+ {
+ j = 0;
+ memcpy (_f, _f + FILLEN, NCOEFF * sizeof (float));
+ memset (_f + NCOEFF, 0, FILLEN * sizeof (float));
+ }
+ }
+ }
+ while (len);
+
+ _p = p;
+ _w = w;
+ _b = b;
+ _x = x;
+ _y = y;
+ _z = z;
+ _d = d;
+ _j = j;
+ _k = k;
+}
diff --git a/src/blvco.h b/src/blvco.h
new file mode 100644
index 0000000..c56a33e
--- /dev/null
+++ b/src/blvco.h
@@ -0,0 +1,92 @@
+/*
+ Copyright (C) 2003 Fons Adriaensen
+
+ 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 2 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+
+#ifndef __VCOSAWPULSE_H
+#define __VCOSAWPULSE_H
+
+#include "ladspaplugin.h"
+
+
+class Ladspa_VCO_pulse1 : public LadspaPlugin
+{
+public:
+
+ enum { NPHASE = 8, NCOEFF = 12, FILLEN = 256 };
+ enum { OUTP, FREQ, EXPM, LINM, OCTN, TUNE, EXPG, LING, FILT, NPORT };
+
+ Ladspa_VCO_pulse1 (SampleRate fsam) : LadspaPlugin (fsam) {}
+ virtual void setport (PortIndex port, PortData *data);
+ virtual void active (bool act);
+ virtual void runproc (SampleCount len, bool add);
+ virtual ~Ladspa_VCO_pulse1 (void) {}
+
+private:
+
+ float *_port [NPORT];
+ float _p, _w, _y, _z;
+ float _f [FILLEN + NCOEFF];
+ int _j;
+};
+
+
+class Ladspa_VCO_saw1 : public LadspaPlugin
+{
+public:
+
+ enum { NPHASE = 8, NCOEFF = 12, FILLEN = 256 };
+ enum { OUTP, FREQ, EXPM, LINM, SYNC, OCTN, TUNE, EXPG, LING, FILT, NPORT };
+
+ Ladspa_VCO_saw1 (SampleRate fsam) : LadspaPlugin (fsam) {}
+ virtual void setport (PortIndex port, PortData *data);
+ virtual void active (bool act);
+ virtual void runproc (SampleCount len, bool add);
+ virtual ~Ladspa_VCO_saw1 (void) {}
+
+private:
+
+ float *_port [NPORT];
+ float _p, _w, _x, _y, _z, _d;
+ float _f [FILLEN + NCOEFF];
+ int _j;
+};
+
+
+class Ladspa_VCO_rec1 : public LadspaPlugin
+{
+public:
+
+ enum { NPHASE = 8, NCOEFF = 12, FILLEN = 256 };
+ enum { OUTP, FREQ, EXPM, LINM, WAVM, SYNC, OCTN, TUNE, EXPG, LING, WAVE, WMOD, FILT, NPORT };
+
+ Ladspa_VCO_rec1 (SampleRate fsam) : LadspaPlugin (fsam) {}
+ virtual void setport (PortIndex port, PortData *data);
+ virtual void active (bool act);
+ virtual void runproc (SampleCount len, bool add);
+ virtual ~Ladspa_VCO_rec1 (void) {}
+
+private:
+
+ float *_port [NPORT];
+ float _p, _w, _b, _x, _y, _z, _d;
+ float _f [FILLEN + NCOEFF];
+ int _j, _k;
+};
+
+
+#endif
diff --git a/src/blvco_lv2.cc b/src/blvco_lv2.cc
new file mode 100644
index 0000000..1e539e6
--- /dev/null
+++ b/src/blvco_lv2.cc
@@ -0,0 +1,90 @@
+/*
+ Copyright (C) 2012 David Robillard <d@drobilla.net>
+
+ 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 2 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include <stddef.h>
+
+#include "blvco.h"
+#include "plugin_lv2.h"
+
+extern "C" {
+
+static LV2_Handle
+instantiate1(const LV2_Descriptor* descriptor,
+ double rate,
+ const char* bundle_path,
+ const LV2_Feature* const* features)
+{
+ return new Ladspa_VCO_pulse1(rate);
+}
+
+static LV2_Handle
+instantiate2(const LV2_Descriptor* descriptor,
+ double rate,
+ const char* bundle_path,
+ const LV2_Feature* const* features)
+{
+ return new Ladspa_VCO_saw1(rate);
+}
+
+static LV2_Handle
+instantiate3(const LV2_Descriptor* descriptor,
+ double rate,
+ const char* bundle_path,
+ const LV2_Feature* const* features)
+{
+ return new Ladspa_VCO_rec1(rate);
+}
+
+static const LV2_Descriptor descriptors[3] = {
+ { "http://drobilla.net/plugins/fomp/pulse_vco",
+ instantiate1,
+ connect_port,
+ activate,
+ run,
+ deactivate,
+ cleanup,
+ NULL },
+ { "http://drobilla.net/plugins/fomp/saw_vco",
+ instantiate2,
+ connect_port,
+ activate,
+ run,
+ deactivate,
+ cleanup,
+ NULL },
+ { "http://drobilla.net/plugins/fomp/rec_vco",
+ instantiate3,
+ connect_port,
+ activate,
+ run,
+ deactivate,
+ cleanup,
+ NULL },
+};
+
+LV2_SYMBOL_EXPORT
+const LV2_Descriptor*
+lv2_descriptor(uint32_t index)
+{
+ if (index < 3) {
+ return &descriptors[index];
+ }
+ return NULL;
+}
+
+} // extern "C"
diff --git a/src/cs_chorus.cc b/src/cs_chorus.cc
new file mode 100644
index 0000000..5cb28c5
--- /dev/null
+++ b/src/cs_chorus.cc
@@ -0,0 +1,406 @@
+/*
+ Copyright (C) 2003-2008 Fons Adriaensen <fons@kokkinizita.net>
+
+ 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 2 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+
+#include <math.h>
+#include <string.h>
+#include "cs_chorus.h"
+
+
+
+Ladspa_CS_chorus1::Ladspa_CS_chorus1 (SampleRate fsam) : LadspaPlugin (fsam)
+{
+ _size = (unsigned long)(ceil (30 * fsam / 1000.0)) + 64;
+ _size = (_size >> 6) << 6;
+ _line = new float [_size + 1];
+}
+
+
+Ladspa_CS_chorus1::~Ladspa_CS_chorus1 (void)
+{
+ delete[] _line;
+}
+
+
+void Ladspa_CS_chorus1::setport (PortIndex port, PortData *data)
+{
+ _port [port] = (float*)data;
+}
+
+
+void Ladspa_CS_chorus1::active (bool act)
+{
+ unsigned int i;
+
+ if (act)
+ {
+ _wi = _gi = 0;
+ _x1 = _x2 = 1;
+ _y1 = _y2 = 0;
+ memset (_line, 0, (_size + 1) * sizeof (float));
+ for (i = 0; i < 3; i++) _ri [i] = _dr [i] = 0;
+ }
+}
+
+
+void Ladspa_CS_chorus1::runproc (SampleCount len, bool add)
+{
+ unsigned long i, k, wi;
+ int j;
+ float *p0, *p1;
+ float t, x, y;
+ p0 = _port [INPUT];
+ p1 = _port [OUTPUT];
+
+ wi = _wi;
+ do
+ {
+ if (_gi == 0)
+ {
+ _gi = 64;
+
+ t = 402.12f * _port [FREQ1][0] / _fsam;
+ x = _x1 - t * _y1;
+ y = _y1 + t * _x1;
+ t = sqrtf (x * x + y * y);
+ _x1 = x / t;
+ _y1 = y / t;
+
+ t = 402.12f * _port [FREQ2][0] / _fsam;
+ x = _x2 - t * _y2;
+ y = _y2 + t * _x2;
+ t = sqrtf (x * x + y * y);
+ _x2 = x / t;
+ _y2 = y / t;
+
+ x = _port [TMOD1][0] * _x1 + _port [TMOD2][0] * _x2;
+ y = _port [TMOD1][0] * _y1 + _port [TMOD2][0] * _y2;
+
+ _dr [0] = x;
+ _dr [1] = -0.500f * x + 0.866f * y;
+ _dr [2] = -0.500f * x - 0.866f * y;
+
+ for (j = 0; j < 3; j++)
+ {
+ t = _port [DELAY][0] + _dr [j];
+ if (t < 0) t = 0;
+ if (t > 30) t = 30;
+ t *= _fsam / 1000.0f;
+ _dr [j] = (t - _ri [j]) / 64;
+ }
+ }
+
+ k = (_gi < len) ? _gi : len;
+ _gi -= k;
+ len -= k;
+
+ while (k--)
+ {
+ _line [++wi] = *p0++;
+ y = 0;
+ for (j = 0; j < 3; j++)
+ {
+ x = wi - _ri [j];
+ _ri [j] += _dr [j];
+ if (x < 0) x += _size;
+ i = (int)(floorf (x));
+ x -= i;
+ y += (1 - x) * _line [i] + x * _line [i + 1];
+ }
+ y *= 0.333f;
+ if (add) *p1++ += y * _gain;
+ else *p1++ = y;
+
+ }
+ if (wi == _size) _line [wi = 0] = _line [_size];
+ }
+ while (len);
+
+ _wi = wi;
+}
+
+
+
+
+Ladspa_CS_chorus2::Ladspa_CS_chorus2 (SampleRate fsam) : LadspaPlugin (fsam)
+{
+ _size = (unsigned long)(ceil (30 * fsam / 500.0)) + 192;
+ _size = (_size >> 6) << 6;
+ _line = new float [_size + 1];
+}
+
+
+Ladspa_CS_chorus2::~Ladspa_CS_chorus2 (void)
+{
+ delete[] _line;
+}
+
+
+void Ladspa_CS_chorus2::setport (PortIndex port, PortData *data)
+{
+ _port [port] = (float*)data;
+}
+
+
+void Ladspa_CS_chorus2::active (bool act)
+{
+ unsigned int i;
+
+ if (act)
+ {
+ _wi = _gi = 0;
+ _x1 = _x2 = 1;
+ _y1 = _y2 = 0;
+ _a = _b = 0;
+ memset (_line, 0, (_size + 1) * sizeof (float));
+ for (i = 0; i < 3; i++) _ri [i] = _dr [i] = 0;
+ }
+}
+
+
+void Ladspa_CS_chorus2::runproc (SampleCount len, bool add)
+{
+ unsigned long i, k, wi;
+ int j;
+ float *p0, *p1;
+ float a, b, t, x, y;
+
+ p0 = _port [INPUT];
+ p1 = _port [OUTPUT];
+
+ wi = _wi;
+ a = _a;
+ b = _b;
+ do
+ {
+ if (_gi == 0)
+ {
+ _gi = 64;
+
+ t = 402.12f * _port [FREQ1][0] / _fsam;
+ x = _x1 - t * _y1;
+ y = _y1 + t * _x1;
+ t = sqrtf (x * x + y * y);
+ _x1 = x / t;
+ _y1 = y / t;
+
+ t = 402.12f * _port [FREQ2][0] / _fsam;
+ x = _x2 - t * _y2;
+ y = _y2 + t * _x2;
+ t = sqrtf (x * x + y * y);
+ _x2 = x / t;
+ _y2 = y / t;
+
+ x = _port [TMOD1][0] * _x1 + _port [TMOD2][0] * _x2;
+ y = _port [TMOD1][0] * _y1 + _port [TMOD2][0] * _y2;
+
+ _dr [0] = x;
+ _dr [1] = -0.500f * x + 0.866f * y;
+ _dr [2] = -0.500f * x - 0.866f * y;
+
+ for (j = 0; j < 3; j++)
+ {
+ t = _port [DELAY][0] + _dr [j];
+ if (t < 0) t = 0;
+ if (t > 30) t = 30;
+ t *= _fsam / 500.0f;
+ _dr [j] = (t - _ri [j]) / 64;
+ }
+ }
+
+ k = (_gi < len) ? _gi : len;
+ _gi -= k;
+ len -= k;
+
+ while (k--)
+ {
+ x = *p0++ + 0.52f * a - 0.25f * b;
+ _line [++wi] = 0.5f * (x + b) + a;
+ b = a;
+ a = x;
+ x = 0.52f * a - 0.25f * b;
+ _line [++wi] = 0.5f * (x + b) + a;
+ b = a;
+ a = x;
+
+ y = 0;
+ for (j = 0; j < 3; j++)
+ {
+ x = wi - _ri [j];
+ _ri [j] += _dr [j];
+ if (x < 0) x += _size;
+ i = (int)(floorf (x));
+ x -= i;
+ y += (1 - x) * _line [i] + x * _line [i + 1];
+ }
+ y *= 0.333f;
+ if (add) *p1++ += y * _gain;
+ else *p1++ = y;
+
+ }
+ if (wi == _size) _line [wi = 0] = _line [_size];
+ }
+ while (len);
+
+ _wi = wi;
+ _a = a;
+ _b = b;
+}
+
+
+
+
+Ladspa_CS_chorus3::Ladspa_CS_chorus3 (SampleRate fsam) : LadspaPlugin (fsam)
+{
+ _size = (unsigned long)(ceil (30 * fsam / 500.0)) + 192;
+ _size = (_size >> 6) << 6;
+ _line = new float [_size + 1];
+}
+
+
+Ladspa_CS_chorus3::~Ladspa_CS_chorus3 (void)
+{
+ delete[] _line;
+}
+
+
+void Ladspa_CS_chorus3::setport (PortIndex port, PortData *data)
+{
+ _port [port] = (float*)data;
+}
+
+
+void Ladspa_CS_chorus3::active (bool act)
+{
+ unsigned int i;
+
+ if (act)
+ {
+ _wi = _gi = 0;
+ _x1 = _x2 = 1;
+ _y1 = _y2 = 0;
+ _a = _b = 0;
+ memset (_line, 0, (_size + 1) * sizeof (float));
+ for (i = 0; i < 3; i++) _ri [i] = _dr [i] = 0;
+ }
+}
+
+
+void Ladspa_CS_chorus3::runproc (SampleCount len, bool add)
+{
+ unsigned long i, k, wi;
+ int j;
+ float *p0, *p1, *p2, *p3;
+ float a, b, t, x, y;
+
+ p0 = _port [INPUT];
+ p1 = _port [OUTPUT1];
+ p2 = _port [OUTPUT2];
+ p3 = _port [OUTPUT3];
+
+ wi = _wi;
+ a = _a;
+ b = _b;
+ do
+ {
+ if (_gi == 0)
+ {
+ _gi = 64;
+
+ t = 402.12f * _port [FREQ1][0] / _fsam;
+ x = _x1 - t * _y1;
+ y = _y1 + t * _x1;
+ t = sqrtf (x * x + y * y);
+ _x1 = x / t;
+ _y1 = y / t;
+
+ t = 402.12f * _port [FREQ2][0] / _fsam;
+ x = _x2 - t * _y2;
+ y = _y2 + t * _x2;
+ t = sqrtf (x * x + y * y);
+ _x2 = x / t;
+ _y2 = y / t;
+
+ x = _port [TMOD1][0] * _x1 + _port [TMOD2][0] * _x2;
+ y = _port [TMOD1][0] * _y1 + _port [TMOD2][0] * _y2;
+
+ _dr [0] = x;
+ _dr [1] = -0.500f * x + 0.866f * y;
+ _dr [2] = -0.500f * x - 0.866f * y;
+
+ for (j = 0; j < 3; j++)
+ {
+ t = _port [DELAY][0] + _dr [j];
+ if (t < 0) t = 0;
+ if (t > 30) t = 30;
+ t *= _fsam / 500.0f;
+ _dr [j] = (t - _ri [j]) / 64;
+ }
+ }
+
+ k = (_gi < len) ? _gi : len;
+ _gi -= k;
+ len -= k;
+
+ while (k--)
+ {
+ x = *p0++ + 0.52f * a - 0.25f * b;
+ _line [++wi] = 0.5f * (x + b) + a;
+ b = a;
+ a = x;
+ x = 0.52f * a - 0.25f * b;
+ _line [++wi] = 0.5f * (x + b) + a;
+ b = a;
+ a = x;
+
+ x = wi - _ri [0];
+ _ri [0] += _dr [0];
+ if (x < 0) x += _size;
+ i = (int)(floorf (x));
+ x -= i;
+ y = (1 - x) * _line [i] + x * _line [i + 1];
+ if (add) *p1++ += y * _gain;
+ else *p1++ = y;
+
+ x = wi - _ri [1];
+ _ri [1] += _dr [1];
+ if (x < 0) x += _size;
+ i = (int)(floorf (x));
+ x -= i;
+ y = (1 - x) * _line [i] + x * _line [i + 1];
+ if (add) *p2++ += y * _gain;
+ else *p2++ = y;
+
+ x = wi - _ri [2];
+ _ri [2] += _dr [2];
+ if (x < 0) x += _size;
+ i = (int)(floorf (x));
+ x -= i;
+ y = (1 - x) * _line [i] + x * _line [i + 1];
+ if (add) *p3++ += y * _gain;
+ else *p3++ = y;
+ }
+ if (wi == _size) _line [wi = 0] = _line [_size];
+ }
+ while (len);
+
+ _wi = wi;
+ _a = a;
+ _b = b;
+}
+
diff --git a/src/cs_chorus.h b/src/cs_chorus.h
new file mode 100644
index 0000000..9228ffa
--- /dev/null
+++ b/src/cs_chorus.h
@@ -0,0 +1,106 @@
+/*
+ Copyright (C) 2003-2008 Fons Adriaensen <fons@kokkinizita.net>
+
+ 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 2 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+
+#ifndef __CS_CHORUS_H
+#define __CS_CHORUS_H
+
+#include "ladspaplugin.h"
+
+
+class Ladspa_CS_chorus1 : public LadspaPlugin
+{
+public:
+
+ enum { INPUT, OUTPUT, DELAY, FREQ1, TMOD1, FREQ2, TMOD2, NPORT };
+
+ Ladspa_CS_chorus1 (SampleRate fsam);
+ virtual void setport (PortIndex port, PortData *data);
+ virtual void active (bool act);
+ virtual void runproc (SampleCount len, bool add);
+ virtual ~Ladspa_CS_chorus1 (void);
+
+private:
+
+ float *_port [NPORT];
+ unsigned long _size;
+ unsigned long _wi;
+ unsigned long _gi;
+ float _ri [3];
+ float _dr [3];
+ float _x1, _y1;
+ float _x2, _y2;
+ float *_line;
+};
+
+
+class Ladspa_CS_chorus2 : public LadspaPlugin
+{
+public:
+
+ enum { INPUT, OUTPUT, DELAY, FREQ1, TMOD1, FREQ2, TMOD2, NPORT };
+
+ Ladspa_CS_chorus2 (SampleRate fsam);
+ virtual void setport (PortIndex port, PortData *data);
+ virtual void active (bool act);
+ virtual void runproc (SampleCount len, bool add);
+ virtual ~Ladspa_CS_chorus2 (void);
+
+private:
+
+ float *_port [NPORT];
+ unsigned long _size;
+ unsigned long _wi;
+ unsigned long _gi;
+ float _ri [3];
+ float _dr [3];
+ float _x1, _y1;
+ float _x2, _y2;
+ float _a, _b;
+ float *_line;
+};
+
+
+class Ladspa_CS_chorus3 : public LadspaPlugin
+{
+public:
+
+ enum { INPUT, OUTPUT1, OUTPUT2, OUTPUT3, DELAY, FREQ1, TMOD1, FREQ2, TMOD2, NPORT };
+
+ Ladspa_CS_chorus3 (SampleRate fsam);
+ virtual void setport (PortIndex port, PortData *data);
+ virtual void active (bool act);
+ virtual void runproc (SampleCount len, bool add);
+ virtual ~Ladspa_CS_chorus3 (void);
+
+private:
+
+ float *_port [NPORT];
+ unsigned long _size;
+ unsigned long _wi;
+ unsigned long _gi;
+ float _ri [3];
+ float _dr [3];
+ float _x1, _y1;
+ float _x2, _y2;
+ float _a, _b;
+ float *_line;
+};
+
+
+#endif
diff --git a/src/cs_chorus_if.cc b/src/cs_chorus_if.cc
new file mode 100644
index 0000000..4b5c270
--- /dev/null
+++ b/src/cs_chorus_if.cc
@@ -0,0 +1,247 @@
+/*
+ Copyright (C) 2003-2008 Fons Adriaensen <fons@kokkinizita.net>
+
+ 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 2 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+//-----------------------------------------------------------------------------------
+// Common definitions
+
+
+#include "cs_chorus.h"
+
+#define NMODS 3
+#define VERSION "0.4.0"
+
+
+static const char* maker = "Fons Adriaensen <fons@kokkinizita.net>";
+static const char* copyr = "(C) 2003-2008 Fons Adriaensen - License: GPL2";
+
+
+static void pconnect (LADSPA_Handle H, PortIndex port, LADSPA_Data *data)
+{
+ ((LadspaPlugin *)H)->setport (port, data);
+}
+
+static void activate (LADSPA_Handle H)
+{
+ ((LadspaPlugin *)H)->active (true);
+}
+
+static void runplugin (LADSPA_Handle H, unsigned long k)
+{
+ ((LadspaPlugin *)H)->runproc (k, false);
+}
+
+static void runadding (LADSPA_Handle H, unsigned long k)
+{
+ ((LadspaPlugin *)H)->runproc (k, true);
+}
+
+static void setadding (LADSPA_Handle H, LADSPA_Data gain)
+{
+ ((LadspaPlugin *)H)->setgain (gain);
+}
+
+static void deactivate (LADSPA_Handle H)
+{
+ ((LadspaPlugin *)H)->active (false);
+}
+
+static void cleanup (LADSPA_Handle H)
+{
+ delete (LadspaPlugin *) H;
+}
+
+//-----------------------------------------------------------------------------------
+// Plugin definitions
+
+
+static const char* name1 = "Chorus1 - Based on CSound orchestra by Sean Costello";
+static const char* label1 = "Chorus1";
+
+static LADSPA_Handle instant1 (const struct _LADSPA_Descriptor *desc, unsigned long rate)
+{
+ return new Ladspa_CS_chorus1 (rate);
+}
+
+
+static const char* name2 = "Chorus2 - Based on CSound orchestra by Sean Costello";
+static const char* label2 = "Chorus2";
+
+static LADSPA_Handle instant2 (const struct _LADSPA_Descriptor *desc, unsigned long rate)
+{
+ return new Ladspa_CS_chorus2 (rate);
+}
+
+
+static const char* name3 = "Triple chorus";
+static const char* label3 = "TripleChorus";
+
+static LADSPA_Handle instant3 (const struct _LADSPA_Descriptor *desc, unsigned long rate)
+{
+ return new Ladspa_CS_chorus3 (rate);
+}
+
+
+
+static const LADSPA_PortDescriptor pdesc12 [Ladspa_CS_chorus1::NPORT] =
+{
+ LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO,
+ LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO,
+ LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL,
+ LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL,
+ LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL,
+ LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL,
+ LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL
+};
+
+static const char * const pname12 [Ladspa_CS_chorus1::NPORT] =
+{
+ "Input",
+ "Output",
+ "Delay (ms)",
+ "Mod Frequency 1 (Hz)",
+ "Mod Amplitude 1 (ms)",
+ "Mod Frequency 2 (Hz)",
+ "Mod Amplitude 2 (ms)"
+};
+
+static const LADSPA_PortRangeHint phint12 [Ladspa_CS_chorus1::NPORT] =
+{
+ { 0, 0, 0 },
+ { 0, 0, 0 },
+ { LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_DEFAULT_0, 0, 30 },
+ { LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_LOGARITHMIC, 0.003, 10 },
+ { LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_DEFAULT_0, 0, 10 },
+ { LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_LOGARITHMIC, 0.01, 30 },
+ { LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_DEFAULT_0, 0, 3 }
+};
+
+
+static const LADSPA_PortDescriptor pdesc3 [Ladspa_CS_chorus3::NPORT] =
+{
+ LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO,
+ LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO,
+ LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO,
+ LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO,
+ LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL,
+ LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL,
+ LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL,
+ LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL,
+ LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL
+};
+
+static const char * const pname3 [Ladspa_CS_chorus3::NPORT] =
+{
+ "Input",
+ "Output1",
+ "Output2",
+ "Output3",
+ "Delay (ms)",
+ "Mod Frequency 1 (Hz)",
+ "Mod Amplitude 1 (ms)",
+ "Mod Frequency 2 (Hz)",
+ "Mod Amplitude 2 (ms)"
+};
+
+static const LADSPA_PortRangeHint phint3 [Ladspa_CS_chorus3::NPORT] =
+{
+ { 0, 0, 0 },
+ { 0, 0, 0 },
+ { 0, 0, 0 },
+ { 0, 0, 0 },
+ { LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_DEFAULT_0, 0, 30 },
+ { LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_LOGARITHMIC, 0.003, 10 },
+ { LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_DEFAULT_0, 0, 10 },
+ { LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_LOGARITHMIC, 0.01, 30 },
+ { LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_DEFAULT_0, 0, 3 }
+};
+
+
+static const LADSPA_Descriptor moddescr [NMODS] =
+{
+ {
+ 1944,
+ label1,
+ LADSPA_PROPERTY_REALTIME | LADSPA_PROPERTY_HARD_RT_CAPABLE,
+ name1,
+ maker,
+ copyr,
+ Ladspa_CS_chorus1::NPORT,
+ pdesc12,
+ pname12,
+ phint12,
+ 0,
+ instant1,
+ pconnect,
+ activate,
+ runplugin,
+ runadding,
+ setadding,
+ deactivate,
+ cleanup
+ },
+ {
+ 1945,
+ label2,
+ LADSPA_PROPERTY_REALTIME | LADSPA_PROPERTY_HARD_RT_CAPABLE,
+ name2,
+ maker,
+ copyr,
+ Ladspa_CS_chorus1::NPORT,
+ pdesc12,
+ pname12,
+ phint12,
+ 0,
+ instant2,
+ pconnect,
+ activate,
+ runplugin,
+ runadding,
+ setadding,
+ deactivate,
+ cleanup
+ },
+ {
+ 1951,
+ label3,
+ LADSPA_PROPERTY_REALTIME | LADSPA_PROPERTY_HARD_RT_CAPABLE,
+ name3,
+ maker,
+ copyr,
+ Ladspa_CS_chorus3::NPORT,
+ pdesc3,
+ pname3,
+ phint3,
+ 0,
+ instant3,
+ pconnect,
+ activate,
+ runplugin,
+ runadding,
+ setadding,
+ deactivate,
+ cleanup
+ }
+};
+
+extern "C" const LADSPA_Descriptor *ladspa_descriptor (unsigned long i)
+{
+ if (i >= NMODS) return 0;
+ return moddescr + i;
+}
+
+//-----------------------------------------------------------------------------------
diff --git a/src/cs_chorus_lv2.cc b/src/cs_chorus_lv2.cc
new file mode 100644
index 0000000..bb58b6c
--- /dev/null
+++ b/src/cs_chorus_lv2.cc
@@ -0,0 +1,90 @@
+/*
+ Copyright (C) 2012 David Robillard <d@drobilla.net>
+
+ 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 2 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include <stddef.h>
+
+#include "cs_chorus.h"
+#include "plugin_lv2.h"
+
+extern "C" {
+
+static LV2_Handle
+instantiate1(const LV2_Descriptor* descriptor,
+ double rate,
+ const char* bundle_path,
+ const LV2_Feature* const* features)
+{
+ return new Ladspa_CS_chorus1(rate);
+}
+
+static LV2_Handle
+instantiate2(const LV2_Descriptor* descriptor,
+ double rate,
+ const char* bundle_path,
+ const LV2_Feature* const* features)
+{
+ return new Ladspa_CS_chorus2(rate);
+}
+
+static LV2_Handle
+instantiate3(const LV2_Descriptor* descriptor,
+ double rate,
+ const char* bundle_path,
+ const LV2_Feature* const* features)
+{
+ return new Ladspa_CS_chorus3(rate);
+}
+
+static const LV2_Descriptor descriptors[3] = {
+ { "http://drobilla.net/plugins/fomp/cs_chorus1",
+ instantiate1,
+ connect_port,
+ activate,
+ run,
+ deactivate,
+ cleanup,
+ NULL },
+ { "http://drobilla.net/plugins/fomp/cs_chorus2",
+ instantiate2,
+ connect_port,
+ activate,
+ run,
+ deactivate,
+ cleanup,
+ NULL },
+ { "http://drobilla.net/plugins/fomp/triple_chorus",
+ instantiate3,
+ connect_port,
+ activate,
+ run,
+ deactivate,
+ cleanup,
+ NULL },
+};
+
+LV2_SYMBOL_EXPORT
+const LV2_Descriptor*
+lv2_descriptor(uint32_t index)
+{
+ if (index < 3) {
+ return &descriptors[index];
+ }
+ return NULL;
+}
+
+} // extern "C"
diff --git a/src/cs_phaser.cc b/src/cs_phaser.cc
new file mode 100644
index 0000000..099c90c
--- /dev/null
+++ b/src/cs_phaser.cc
@@ -0,0 +1,191 @@
+/*
+ Copyright (C) 2003-2008 Fons Adriaensen <fons@kokkinizita.net>
+
+ 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 2 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+
+#include <stdio.h>
+#include <math.h>
+#include "cs_phaser.h"
+#include "exp2ap.h"
+
+
+void Ladspa_CS_phaser1::setport (PortIndex port, PortData *data)
+{
+ _port [port] = (float*)data;
+}
+
+
+void Ladspa_CS_phaser1::active (bool act)
+{
+ if (act)
+ {
+ _w = _z = 0;
+ for (int i = 0; i < NSECT; i++) _c [i] = 0;
+ }
+}
+
+
+void Ladspa_CS_phaser1::runproc (SampleCount len, bool add)
+{
+ int i, k, ns;
+ float *p0, *p1, *p2, *p3, *p4;
+ float g0, gf, gi, gm;
+ float d, t, w, dw, x, z;
+
+ p0 = _port [0];
+ p1 = _port [1];
+ p2 = _port [2] - 1;
+ p3 = _port [3] - 1;
+ p4 = _port [4] - 1;
+
+ ns = (int)(floor (_port [6][0] + 0.5));
+ g0 = exp2ap (0.1661f * _port [5][0]);
+ gf = _port [10][0];
+ gm = _port [11][0];
+ gi = 1 - fabs (gm);
+
+ w = _w;
+ z = _z + 1e-10f;
+
+ do
+ {
+ k = (len > 24) ? 16 : len;
+ p2 += k;
+ p3 += k;
+ p4 += k;
+ len -= k;
+
+ t = (exp2ap (_port [8][0] * *p3 + _port [7][0] + *p2 + 9.683f) + _port [9][0] * *p4 * 1000.0f) / _fsam;
+ if (t < 0.0f) t = 0.0f;
+ if (t > 1.5f) t = 1.5f;
+ t = (sinf (t) - 1) / cosf (t) + 1;
+ dw = (t - w) / k;
+
+ while (k--)
+ {
+ w += dw;
+ x = g0 * *p0++;
+ z = gf * z + x;
+ z = 4 * tanhf (0.25f * z);
+ for (i = 0; i < ns; i++)
+ {
+ t = _c [i];
+ d = w * (2 * z - t);
+ t += d;
+ _c [i] = t + d;
+ z = t - z;
+ }
+ t = gm * z + gi * x;
+ if (add) *p1++ += t * _gain;
+ else *p1++ = t;
+ }
+ }
+ while (len);
+
+ _w = w;
+ _z = z;
+}
+
+
+
+void Ladspa_CS_phaser1lfo::setport (PortIndex port, PortData *data)
+{
+ _port [port] = (float*)data;
+}
+
+
+void Ladspa_CS_phaser1lfo::active (bool act)
+{
+ if (act)
+ {
+ _gi = 0;
+ _z = _w = _v = _p = 0;
+ for (int i = 0; i < NSECT; i++) _c [i] = 0;
+ }
+}
+
+
+
+
+void Ladspa_CS_phaser1lfo::runproc (SampleCount len, bool add)
+{
+ int i, k, ns;
+ float *p0, *p1;
+ float g0, gf, gi, gm;
+ float d, t, w, v, x, z;
+
+ p0 = _port [0];
+ p1 = _port [1];
+
+ ns = (int)(floor (_port [3][0] + 0.5));
+ g0 = exp2ap (0.1661f * _port [2][0]);
+ gf = _port [8][0];
+ gm = _port [9][0];
+ gi = 1 - fabs (gm);
+
+ z = _z + 1e-10f;
+ w = _w;
+ v = _v;
+
+ do
+ {
+ if (_gi == 0)
+ {
+ _gi = DSUB;
+ _p += 2 * DSUB * _port [5][0] / _fsam;
+ if (_p > 1) _p -= 2;
+ x = 0.999f * _port [6][0];
+ d = _p - x;
+ if (d < 0) t = 0.5f + d / (1 + x);
+ else t = 0.5f - d / (1 - x);
+ t = exp2ap (_port [7][0] * t + _port [4][0] + 9.683f) / _fsam;
+ if (t < 0.0f) t = 0.0f;
+ if (t > 1.5f) t = 1.5f;
+ t = (sinf (t) - 1) / cosf (t) + 1;
+ v = (t - w) / DSUB;
+ }
+
+ k = (_gi < len) ? _gi : len;
+ _gi -= k;
+ len -= k;
+ while (k--)
+ {
+ x = g0 * *p0++;
+ z = gf * z + x;
+ z = 4 * tanhf (0.25f * z);
+ for (i = 0; i < ns; i++)
+ {
+ t = _c [i];
+ d = w * (2 * z - t);
+ t += d;
+ _c [i] = t + d;
+ z = t - z;
+ }
+ t = gm * z + gi * x;
+ if (add) *p1++ += t * _gain;
+ else *p1++ = t;
+ w += v;
+ }
+ }
+ while (len);
+
+ _z = z;
+ _w = w;
+ _v = v;
+}
+
+
diff --git a/src/cs_phaser.h b/src/cs_phaser.h
new file mode 100644
index 0000000..d0e0f3c
--- /dev/null
+++ b/src/cs_phaser.h
@@ -0,0 +1,66 @@
+/*
+ Copyright (C) 2003-2008 Fons Adriaensen <fons@kokkinizita.net>
+
+ 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 2 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+
+#ifndef __CS_PHASER_H
+#define __CS_PHASER_H
+
+#include "ladspaplugin.h"
+
+
+class Ladspa_CS_phaser1 : public LadspaPlugin
+{
+public:
+
+ enum { NPORT = 12, NSECT = 30 };
+
+ Ladspa_CS_phaser1 (SampleRate fsam) : LadspaPlugin (fsam) {}
+ virtual void setport (PortIndex port, PortData *data);
+ virtual void active (bool act);
+ virtual void runproc (SampleCount len, bool add);
+ virtual ~Ladspa_CS_phaser1 (void) {}
+
+private:
+
+ float *_port [NPORT];
+ float _w, _z, _c [NSECT];
+};
+
+
+class Ladspa_CS_phaser1lfo : public LadspaPlugin
+{
+public:
+
+ enum { NPORT = 10, NSECT = 30 };
+
+ Ladspa_CS_phaser1lfo (SampleRate fsam) : LadspaPlugin (fsam) {}
+ virtual void setport (PortIndex port, PortData *data);
+ virtual void active (bool act);
+ virtual void runproc (SampleCount len, bool add);
+ virtual ~Ladspa_CS_phaser1lfo (void) {}
+
+private:
+
+ enum { DSUB = 32 };
+
+ float *_port [NPORT];
+ float _z, _w, _v, _p, _c [NSECT];
+ unsigned int _gi;
+};
+
+#endif
diff --git a/src/cs_phaser_if.cc b/src/cs_phaser_if.cc
new file mode 100644
index 0000000..d1ef98c
--- /dev/null
+++ b/src/cs_phaser_if.cc
@@ -0,0 +1,236 @@
+/*
+ Copyright (C) 2003-2008 Fons Adriaensen <fons@kokkinizita.net>
+
+ 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 2 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+//-----------------------------------------------------------------------------------
+// Common definitions
+
+
+#include "cs_phaser.h"
+
+#define VERSION "0.4.0"
+#define NMODS 2
+
+
+static const char* maker = "Fons Adriaensen <fons@kokkinizita.net>";
+static const char* copyr = "(C) 2003-2008 Fons Adriaensen - License: GPL2";
+
+
+static void pconnect (LADSPA_Handle H, unsigned long port, LADSPA_Data *data)
+{
+ ((LadspaPlugin *)H)->setport (port, data);
+}
+
+static void activate (LADSPA_Handle H)
+{
+ ((LadspaPlugin *)H)->active (true);
+}
+
+static void runplugin (LADSPA_Handle H, unsigned long k)
+{
+ ((LadspaPlugin *)H)->runproc (k, false);
+}
+
+static void runadding (LADSPA_Handle H, unsigned long k)
+{
+ ((LadspaPlugin *)H)->runproc (k, true);
+}
+
+static void setadding (LADSPA_Handle H, LADSPA_Data gain)
+{
+ ((LadspaPlugin *)H)->setgain (gain);
+}
+
+static void deactivate (LADSPA_Handle H)
+{
+ ((LadspaPlugin *)H)->active (false);
+}
+
+static void cleanup (LADSPA_Handle H)
+{
+ delete (LadspaPlugin *) H;
+}
+
+//-----------------------------------------------------------------------------------
+
+static const char* name0 = "Phaser1 - Similar to CSound's phaser1 by Sean Costello";
+static const char* label0 = "Phaser1";
+
+static LADSPA_Handle instant0 (const struct _LADSPA_Descriptor *desc, unsigned long rate)
+{
+ return new Ladspa_CS_phaser1 (rate);
+}
+
+
+static const LADSPA_PortDescriptor pdesc0 [Ladspa_CS_phaser1::NPORT] =
+{
+ LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO,
+ LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO,
+ LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO,
+ LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO,
+ LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO,
+ LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL,
+ LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL,
+ LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL,
+ LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL,
+ LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL,
+ LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL,
+ LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL
+};
+
+static const char * const pname0 [Ladspa_CS_phaser1::NPORT] =
+{
+ "Input",
+ "Output",
+ "Frequency",
+ "Exp FM",
+ "Lin FM",
+ "Input gain (dB)",
+ "Sections",
+ "Frequency",
+ "Exp FM gain",
+ "Lin FM gain",
+ "Feedback gain",
+ "Output mix"
+};
+
+static const LADSPA_PortRangeHint phint0 [Ladspa_CS_phaser1::NPORT] =
+{
+ { 0, 0, 0 },
+ { 0, 0, 0 },
+ { 0, 0, 0 },
+ { 0, 0, 0 },
+ { 0, 0, 0 },
+ { LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_DEFAULT_0, -40, 10 },
+ { LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_INTEGER, 1, Ladspa_CS_phaser1::NSECT },
+ { LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_DEFAULT_0, -6, 6 },
+ { LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE, 0, 10 },
+ { LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE, 0, 10 },
+ { LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_DEFAULT_0, -1, 1 },
+ { LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_DEFAULT_0, -1, 1 },
+};
+
+
+//-----------------------------------------------------------------------------------
+
+static const char* name1 = "Phaser1 with LFO";
+static const char* label1 = "Phaser1+LFO";
+
+static LADSPA_Handle instant1 (const struct _LADSPA_Descriptor *desc, unsigned long rate)
+{
+ return new Ladspa_CS_phaser1lfo (rate);
+}
+
+
+static const LADSPA_PortDescriptor pdesc1 [Ladspa_CS_phaser1lfo::NPORT] =
+{
+ LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO,
+ LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO,
+ LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL,
+ LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL,
+ LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL,
+ LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL,
+ LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL,
+ LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL,
+ LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL,
+ LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL
+};
+
+static const char * const pname1 [Ladspa_CS_phaser1lfo::NPORT] =
+{
+ "Input",
+ "Output",
+ "Input gain (dB)",
+ "Sections",
+ "Frequency",
+ "LFO frequency (Hz)",
+ "LFO waveform",
+ "Modulation gain",
+ "Feedback gain",
+ "Output mix"
+};
+
+static const LADSPA_PortRangeHint phint1 [Ladspa_CS_phaser1lfo::NPORT] =
+{
+ { 0, 0, 0 },
+ { 0, 0, 0 },
+ { LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_DEFAULT_0, -40, 10 },
+ { LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_INTEGER, 1, Ladspa_CS_phaser1lfo::NSECT },
+ { LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_DEFAULT_0, -6, 6 },
+ { LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_LOGARITHMIC, 0.01, 30 },
+ { LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_DEFAULT_0, -1, 1 },
+ { LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE, 0, 10 },
+ { LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_DEFAULT_0, -1, 1 },
+ { LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_DEFAULT_0, -1, 1 },
+};
+
+
+//-----------------------------------------------------------------------------------
+
+static const LADSPA_Descriptor moddescr [NMODS] =
+{
+ {
+ 1946,
+ label0,
+ LADSPA_PROPERTY_REALTIME | LADSPA_PROPERTY_HARD_RT_CAPABLE,
+ name0,
+ maker,
+ copyr,
+ Ladspa_CS_phaser1::NPORT,
+ pdesc0,
+ pname0,
+ phint0,
+ 0,
+ instant0,
+ pconnect,
+ activate,
+ runplugin,
+ runadding,
+ setadding,
+ deactivate,
+ cleanup
+ },
+ {
+ 1947,
+ label1,
+ LADSPA_PROPERTY_REALTIME | LADSPA_PROPERTY_HARD_RT_CAPABLE,
+ name1,
+ maker,
+ copyr,
+ Ladspa_CS_phaser1lfo::NPORT,
+ pdesc1,
+ pname1,
+ phint1,
+ 0,
+ instant1,
+ pconnect,
+ activate,
+ runplugin,
+ runadding,
+ setadding,
+ deactivate,
+ cleanup
+ }
+};
+
+extern "C" const LADSPA_Descriptor *ladspa_descriptor (unsigned long i)
+{
+ if (i >= NMODS) return 0;
+ return moddescr + i;
+}
+
+//-----------------------------------------------------------------------------------
diff --git a/src/cs_phaser_lv2.cc b/src/cs_phaser_lv2.cc
new file mode 100644
index 0000000..576d4a2
--- /dev/null
+++ b/src/cs_phaser_lv2.cc
@@ -0,0 +1,73 @@
+/*
+ Copyright (C) 2012 David Robillard <d@drobilla.net>
+
+ 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 2 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include <stddef.h>
+
+#include "cs_phaser.h"
+#include "plugin_lv2.h"
+
+extern "C" {
+
+static LV2_Handle
+instantiate1(const LV2_Descriptor* descriptor,
+ double rate,
+ const char* bundle_path,
+ const LV2_Feature* const* features)
+{
+ return new Ladspa_CS_phaser1(rate);
+}
+
+static LV2_Handle
+instantiate2(const LV2_Descriptor* descriptor,
+ double rate,
+ const char* bundle_path,
+ const LV2_Feature* const* features)
+{
+ return new Ladspa_CS_phaser1lfo(rate);
+}
+
+static const LV2_Descriptor descriptors[3] = {
+ { "http://drobilla.net/plugins/fomp/cs_phaser1",
+ instantiate1,
+ connect_port,
+ activate,
+ run,
+ deactivate,
+ cleanup,
+ NULL },
+ { "http://drobilla.net/plugins/fomp/cs_phaser1_lfo",
+ instantiate2,
+ connect_port,
+ activate,
+ run,
+ deactivate,
+ cleanup,
+ NULL },
+};
+
+LV2_SYMBOL_EXPORT
+const LV2_Descriptor*
+lv2_descriptor(uint32_t index)
+{
+ if (index < 2) {
+ return &descriptors[index];
+ }
+ return NULL;
+}
+
+} // extern "C"
diff --git a/src/exp2ap.h b/src/exp2ap.h
new file mode 100644
index 0000000..2485539
--- /dev/null
+++ b/src/exp2ap.h
@@ -0,0 +1,28 @@
+/*
+ Copyright (C) 2003-2008 Fons Adriaensen <fons@kokkinizita.net>
+
+ 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 2 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include <math.h>
+
+static inline float exp2ap (float x)
+{
+ const int i = (int)(floorf (x));
+ x -= i;
+ return ldexpf (1 + x * (0.6930f + x * (0.2416f + x * (0.0517f + x * 0.0137f))), i);
+}
+
+
diff --git a/src/filters.cc b/src/filters.cc
new file mode 100644
index 0000000..8c93696
--- /dev/null
+++ b/src/filters.cc
@@ -0,0 +1,113 @@
+/*
+ Copyright (C) 2004-2009 Fons Adriaensen <fons@kokkinizita.net>
+
+ 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 2 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+
+#include <string.h>
+#include "filters.h"
+#include "exp2ap.h"
+
+
+void Ladspa_Paramfilt::setport (PortIndex port, PortData *data)
+{
+ _port [port] = (float*)data;
+}
+
+
+void Ladspa_Paramfilt::active (bool act)
+{
+ int j;
+
+ if (! act) return;
+ _fade = 0;
+ _gain = 1;
+ for (j = 0; j < NSECT; j++) _sect [j].init ();
+}
+
+
+void Ladspa_Paramfilt::runproc (SampleCount len, bool add)
+{
+ int i, j, k;
+ float *aip = _port [AIP];
+ float *aop = _port [AOP];
+ float *p, sig [48];
+ float t, g, d;
+ float fgain;
+ float sfreq [NSECT];
+ float sband [NSECT];
+ float sgain [NSECT];
+
+ fgain = exp2ap (0.1661 * _port [GAIN][0]);
+ for (j = 0; j < NSECT; j++)
+ {
+ t = _port [SECT + 4 * j + Paramsect::FREQ][0] / _fsam;
+ if (t < 0.0002) t = 0.0002;
+ if (t > 0.4998) t = 0.4998;
+ sfreq [j] = t;
+ sband [j] = _port [SECT + 4 * j + Paramsect::BAND][0];
+ if (_port [SECT + 4 * j + Paramsect::SECT][0] > 0) sgain [j] = exp2ap (0.1661 * _port [SECT + 4 * j + Paramsect::GAIN][0]);
+ else sgain [j] = 1.0;
+ }
+
+ while (len)
+ {
+ k = (len > 48) ? 32 : len;
+
+ t = fgain;
+ g = _gain;
+ if (t > 1.25 * g) t = 1.25 * g;
+ else if (t < 0.80 * g) t = 0.80 * g;
+ _gain = t;
+ d = (t - g) / k;
+ for (i = 0; i < k; i++)
+ {
+ g += d;
+ sig [i] = g * aip [i];
+ }
+
+ for (j = 0; j < NSECT; j++) _sect [j].proc (k, sig, sfreq [j], sband [j], sgain [j]);
+
+ j = _fade;
+ g = j / 16.0;
+ p = 0;
+ if (_port [FILT][0] > 0)
+ {
+ if (j == 16) p = sig;
+ else ++j;
+ }
+ else
+ {
+ if (j == 0) p = aip;
+ else --j;
+ }
+ _fade = j;
+ if (p) memcpy (aop, p, k * sizeof (float));
+ else
+ {
+ d = (j / 16.0 - g) / k;
+ for (i = 0; i < k; i++)
+ {
+ g += d;
+ aop [i] = g * sig [i] + (1 - g) * aip [i];
+ }
+ }
+ aip += k;
+ aop += k;
+ len -= k;
+ }
+}
+
diff --git a/src/filters.h b/src/filters.h
new file mode 100644
index 0000000..3000870
--- /dev/null
+++ b/src/filters.h
@@ -0,0 +1,130 @@
+/*
+ Copyright (C) 2004-2009 Fons Adriaensen <fons@kokkinizita.net>
+
+ 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 2 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+
+#ifndef __FILTERS_H
+#define __FILTERS_H
+
+#include <math.h>
+#include "ladspaplugin.h"
+
+
+class Paramsect
+{
+public:
+
+ enum { SECT, FREQ, BAND, GAIN };
+
+ void init (void)
+ {
+ _f = 0.25f;
+ _b = _g = 1.0f;
+ _a = _s1 = _s2 = _z1 = _z2 = 0.0f;
+ }
+
+ void proc (int k, float *sig, float f, float b, float g)
+ {
+ float s1, s2, d1, d2, a, da, x, y;
+ bool u2 = false;
+
+ s1 = _s1;
+ s2 = _s2;
+ a = _a;
+ d1 = 0;
+ d2 = 0;
+ da = 0;
+
+ if (f != _f)
+ {
+ if (f < 0.5f * _f) f = 0.5f * _f;
+ else if (f > 2.0f * _f) f = 2.0f * _f;
+ _f = f;
+ _s1 = -cosf (6.283185f * f);
+ d1 = (_s1 - s1) / k;
+ u2 = true;
+ }
+
+ if (g != _g)
+ {
+ if (g < 0.5f * _g) g = 0.5f * _g;
+ else if (g > 2.0f * _g) g = 2.0f * _g;
+ _g = g;
+ _a = 0.5f * (g - 1.0f);
+ da = (_a - a) / k;
+ u2 = true;
+ }
+
+ if (b != _b)
+ {
+ if (b < 0.5f * _b) b = 0.5f * _b;
+ else if (b > 2.0f * _b) b = 2.0f * _b;
+ _b = b;
+ u2 = true;
+ }
+
+ if (u2)
+ {
+ b *= 7 * f / sqrtf (g);
+ _s2 = (1 - b) / (1 + b);
+ d2 = (_s2 - s2) / k;
+ }
+
+ while (k--)
+ {
+ s1 += d1;
+ s2 += d2;
+ a += da;
+ x = *sig;
+ y = x - s2 * _z2;
+ *sig++ -= a * (_z2 + s2 * y - x);
+ y -= s1 * _z1;
+ _z2 = _z1 + s1 * y;
+ _z1 = y + 1e-10f;
+ }
+ }
+
+private:
+
+ float _f, _b, _g;
+ float _s1, _s2, _a;
+ float _z1, _z2;
+};
+
+
+class Ladspa_Paramfilt : public LadspaPlugin
+{
+public:
+
+ enum { AIP, AOP, FILT, GAIN, SECT, NSECT = 4, NPORT = 20 };
+
+ Ladspa_Paramfilt (SampleRate fsam) : LadspaPlugin (fsam) {}
+ virtual void setport (PortIndex port, PortData *data);
+ virtual void active (bool act);
+ virtual void runproc (SampleCount len, bool add);
+ virtual ~Ladspa_Paramfilt (void) {}
+
+private:
+
+ float *_port [NPORT];
+ float _gain;
+ int _fade;
+ Paramsect _sect [NSECT];
+};
+
+
+#endif
diff --git a/src/filters_lv2.cc b/src/filters_lv2.cc
new file mode 100644
index 0000000..0696c38
--- /dev/null
+++ b/src/filters_lv2.cc
@@ -0,0 +1,56 @@
+/*
+ Copyright (C) 2012 David Robillard <d@drobilla.net>
+
+ 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 2 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include <stddef.h>
+
+#include "filters.h"
+#include "plugin_lv2.h"
+
+extern "C" {
+
+static LV2_Handle
+instantiate(const LV2_Descriptor* descriptor,
+ double rate,
+ const char* bundle_path,
+ const LV2_Feature* const* features)
+{
+ return new Ladspa_Paramfilt(rate);
+}
+
+static const LV2_Descriptor descriptor = {
+ "http://drobilla.net/plugins/fomp/parametric1",
+ instantiate,
+ connect_port,
+ activate,
+ run,
+ deactivate,
+ cleanup,
+ NULL
+};
+
+LV2_SYMBOL_EXPORT
+const LV2_Descriptor*
+lv2_descriptor(uint32_t index)
+{
+ switch (index) {
+ case 0: return &descriptor;
+ default: return NULL;
+ }
+}
+
+} // extern "C"
diff --git a/src/ladspaplugin.h b/src/ladspaplugin.h
new file mode 100644
index 0000000..61d1210
--- /dev/null
+++ b/src/ladspaplugin.h
@@ -0,0 +1,59 @@
+/*
+ Copyright (C) 2003-2008 Fons Adriaensen <fons@kokkinizita.net>
+
+ 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 2 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+
+#ifndef __LADSPAPLUGIN_H
+#define __LADSPAPLUGIN_H
+
+#include <lv2/lv2plug.in/ns/lv2core/lv2.h>
+
+
+/* This class name is now a misnomer but I have left it as-is to minimize
+ fragmentation. The following typedefs serve the same purpose, so the
+ plugins can be built with the correct LV2 type (e.g. uint32_t instead of
+ unsigned long) without 'hard' switching the DSP code to the new type. This
+ way, it should be straightforward to make the same code build as both LADSPA
+ and LV2 plugins, should the packages merge. ~ David Robillard, Aug. 2012 */
+
+typedef double SampleRate;
+typedef uint32_t SampleCount;
+typedef uint32_t PortIndex;
+typedef void PortData;
+
+class LadspaPlugin
+{
+public:
+
+ LadspaPlugin (SampleRate fsam) : _gain (1.0), _fsam (fsam) {}
+
+ virtual void setport (PortIndex port, PortData *data) = 0;
+ virtual void active (bool act) = 0;
+ virtual void runproc (SampleCount len, bool add) = 0;
+ virtual ~LadspaPlugin (void) {}
+
+ void setgain (float gain) { _gain = gain; }
+
+protected:
+
+ float _gain;
+ float _fsam;
+};
+
+
+
+#endif
diff --git a/src/mvchpf24.cc b/src/mvchpf24.cc
new file mode 100644
index 0000000..96d3097
--- /dev/null
+++ b/src/mvchpf24.cc
@@ -0,0 +1,126 @@
+/*
+ Copyright (C) 2003-2008 Fons Adriaensen <fons@kokkinizita.net>
+
+ 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 2 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+
+#include <stdio.h>
+#include <math.h>
+#include "mvchpf24.h"
+#include "exp2ap.h"
+
+
+static const float lg2midc = log2f(261.63f);
+
+
+void Ladspa_Mvchpf1::setport (PortIndex port, PortData *data)
+{
+ _port [port] = (float*)data;
+}
+
+
+void Ladspa_Mvchpf1::active (bool act)
+{
+ _c1 = _c2 = _c3 = _c4 = _x = 0;
+ _w = 1e5;
+}
+
+
+void Ladspa_Mvchpf1::runproc (SampleCount len, bool add)
+{
+ int k;
+ float *p0, *p1, *p2, *p3;
+ float c1, c2, c3, c4;
+ float g0, g1, d, w, dw, t, x, y;
+
+ p0 = _port [AINP];
+ p1 = _port [AOUT];
+ p2 = _port [AFREQ] - 1;
+ p3 = _port [AFMOD] - 1;
+ g0 = exp2ap (0.1661f * _port [CINP][0]) / 4;
+ g1 = exp2ap (0.1661f * _port [COUT][0]) * 4;
+ if (add) g1 *= _gain;
+
+ c1 = _c1;
+ c2 = _c2;
+ c3 = _c3;
+ c4 = _c4;
+ w = _w;
+ x = _x;
+
+ do
+ {
+ k = (len > 24) ? 16 : len;
+ p2 += k;
+ p3 += k;
+ len -= k;
+
+ t = _fsam / exp2ap (_port [CFMOD][0] * *p3 + *p2 + log2f(_port [CFREQ][0]) - lg2midc + 9.2f);
+ if (t < 2) t = 2;
+ dw = (t - w) / k;
+
+ while (k--)
+ {
+ w += dw;
+
+ x = y = *p0++ * g0 - 0.3f * x;
+
+ d = x - c1 + 1e-10f;
+ t = d * d;
+ d *= (1 + t) / (w + t);
+ c1 += d;
+ x -= c1;
+ c1 += d;
+
+ d = x - c2 + 1e-10f;
+ t = d * d;
+ d *= (1 + t) / (w + t);
+ c2 += d;
+ x -= c2;
+ c2 += d;
+
+ d = x - c3 + 1e-10f;
+ t = d * d;
+ d *= (1 + t) / (w + t);
+ c3 += d;
+ x -= c3;
+ c3 += d;
+
+ d = x - c4 + 1e-10f;
+ t = d * d;
+ d *= (1 + t) / (w + t);
+ c4 += d;
+ x -= c4;
+ c4 += d;
+
+ if (add) *p1++ += g1 * x;
+ else *p1++ = g1 * x;
+
+ x -= y;
+ }
+ }
+ while (len);
+
+ _c1 = c1;
+ _c2 = c2;
+ _c3 = c3;
+ _c4 = c4;
+ _w = w;
+ _x = x;
+}
+
+
+
diff --git a/src/mvchpf24.h b/src/mvchpf24.h
new file mode 100644
index 0000000..3fbaee4
--- /dev/null
+++ b/src/mvchpf24.h
@@ -0,0 +1,46 @@
+/*
+ Copyright (C) 2003-2008 Fons Adriaensen <fons@kokkinizita.net>
+
+ 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 2 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+
+#ifndef __MVCHPF24_H
+#define __MVCHPF24_H
+
+#include "ladspaplugin.h"
+
+
+class Ladspa_Mvchpf1 : public LadspaPlugin
+{
+public:
+
+ enum { AINP, AOUT, AFREQ, AFMOD, CINP, CFREQ, CFMOD, COUT, NPORT };
+
+ Ladspa_Mvchpf1 (SampleRate fsam) : LadspaPlugin (fsam) {}
+ virtual void setport (PortIndex port, PortData *data);
+ virtual void active (bool act);
+ virtual void runproc (SampleCount len, bool add);
+ virtual ~Ladspa_Mvchpf1 (void) {}
+
+private:
+
+ float *_port [NPORT];
+ float _c1, _c2, _c3, _c4, _w, _x;
+
+};
+
+
+#endif
diff --git a/src/mvchpf24_if.cc b/src/mvchpf24_if.cc
new file mode 100644
index 0000000..337f6ae
--- /dev/null
+++ b/src/mvchpf24_if.cc
@@ -0,0 +1,150 @@
+/*
+ Copyright (C) 2003-2008 Fons Adriaensen <fons@kokkinizita.net>
+
+ 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 2 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+//-----------------------------------------------------------------------------------
+// Common definitions
+
+
+#include "mvchpf24.h"
+
+#define NMODS 1
+#define VERSION "0.4.0"
+
+
+static const char* maker = "Fons Adriaensen <fons@kokkinizita.net>";
+static const char* copyr = "(C) 2003-2008 Fons Adriaensen - License: GPL2";
+
+
+static void pconnect (LADSPA_Handle H, unsigned long port, LADSPA_Data *data)
+{
+ ((LadspaPlugin *)H)->setport (port, data);
+}
+
+static void activate (LADSPA_Handle H)
+{
+ ((LadspaPlugin *)H)->active (true);
+}
+
+static void runplugin (LADSPA_Handle H, unsigned long k)
+{
+ ((LadspaPlugin *)H)->runproc (k, false);
+}
+
+static void runadding (LADSPA_Handle H, unsigned long k)
+{
+ ((LadspaPlugin *)H)->runproc (k, true);
+}
+
+static void setadding (LADSPA_Handle H, LADSPA_Data gain)
+{
+ ((LadspaPlugin *)H)->setgain (gain);
+}
+
+static void deactivate (LADSPA_Handle H)
+{
+ ((LadspaPlugin *)H)->active (false);
+}
+
+static void cleanup (LADSPA_Handle H)
+{
+ delete (LadspaPlugin *) H;
+}
+
+//-----------------------------------------------------------------------------------
+// Plugin definitions
+
+
+static const char* name1 = "Mvchpf-1 Digital implementation of the VC HP filter invented by R.A. Moog";
+static const char* label1 = "Mvchpf-1";
+
+
+static LADSPA_Handle instant1 (const struct _LADSPA_Descriptor *desc, unsigned long rate)
+{
+ return new Ladspa_Mvchpf1 (rate);
+}
+
+
+static const char * const pname1 [Ladspa_Mvchpf1::NPORT] =
+{
+ "Input",
+ "Output",
+ "Frequency",
+ "Exp FM",
+ "Input gain (dB)",
+ "Frequency",
+ "Exp FM gain",
+ "Output gain (dB)"
+};
+
+static const LADSPA_PortDescriptor pdesc1 [Ladspa_Mvchpf1::NPORT] =
+{
+ LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO,
+ LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO,
+ LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO,
+ LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO,
+ LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL,
+ LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL,
+ LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL,
+ LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL
+};
+
+static const LADSPA_PortRangeHint phint1 [Ladspa_Mvchpf1::NPORT] =
+{
+ { 0, 0, 0 },
+ { 0, 0, 0 },
+ { 0, 0, 0 },
+ { 0, 0, 0 },
+ { LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_DEFAULT_0, -60, 10 },
+ { LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_DEFAULT_0, -6, 6 },
+ { LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE, 0, 10 },
+ { LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_DEFAULT_0, -15, 15 },
+};
+
+
+static const LADSPA_Descriptor moddescr [NMODS] =
+{
+ {
+ 1960,
+ label1,
+ LADSPA_PROPERTY_REALTIME | LADSPA_PROPERTY_HARD_RT_CAPABLE,
+ name1,
+ maker,
+ copyr,
+ Ladspa_Mvchpf1::NPORT,
+ pdesc1,
+ pname1,
+ phint1,
+ 0,
+ instant1,
+ pconnect,
+ activate,
+ runplugin,
+ runadding,
+ setadding,
+ deactivate,
+ cleanup
+ }
+};
+
+extern "C" const LADSPA_Descriptor *ladspa_descriptor (unsigned long i)
+{
+ if (i >= NMODS) return 0;
+ return moddescr + i;
+}
+
+//-----------------------------------------------------------------------------------
diff --git a/src/mvchpf24_lv2.cc b/src/mvchpf24_lv2.cc
new file mode 100644
index 0000000..c34fca3
--- /dev/null
+++ b/src/mvchpf24_lv2.cc
@@ -0,0 +1,87 @@
+/*
+ Copyright (C) 2012 David Robillard <d@drobilla.net>
+
+ 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 2 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include <stddef.h>
+
+#include "mvchpf24.h"
+
+extern "C" {
+
+static void
+connect_port(LV2_Handle instance,
+ uint32_t port,
+ void* data)
+{
+ ((LadspaPlugin*)instance)->setport(port, data);
+}
+
+static void
+activate(LV2_Handle instance)
+{
+ ((LadspaPlugin*)instance)->active(true);
+}
+
+static void
+run(LV2_Handle instance, uint32_t n_samples)
+{
+ ((LadspaPlugin*)instance)->runproc(n_samples, false);
+}
+
+static void
+deactivate(LV2_Handle instance)
+{
+ ((LadspaPlugin*)instance)->active(false);
+}
+
+static void
+cleanup(LV2_Handle instance)
+{
+ delete ((LadspaPlugin*)instance);
+}
+
+static LV2_Handle
+instantiate(const LV2_Descriptor* descriptor,
+ double rate,
+ const char* bundle_path,
+ const LV2_Feature* const* features)
+{
+ return new Ladspa_Mvchpf1(rate);
+}
+
+static const LV2_Descriptor descriptor = {
+ "http://drobilla.net/plugins/fomp/mvchpf1",
+ instantiate,
+ connect_port,
+ activate,
+ run,
+ deactivate,
+ cleanup,
+ NULL
+};
+
+LV2_SYMBOL_EXPORT
+const LV2_Descriptor*
+lv2_descriptor(uint32_t index)
+{
+ switch (index) {
+ case 0: return &descriptor;
+ default: return NULL;
+ }
+}
+
+} // extern "C"
diff --git a/src/mvclpf24.cc b/src/mvclpf24.cc
new file mode 100644
index 0000000..357fd7c
--- /dev/null
+++ b/src/mvclpf24.cc
@@ -0,0 +1,439 @@
+/*
+ Copyright (C) 2003-2008 Fons Adriaensen <fons@kokkinizita.net>
+
+ 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 2 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+
+#include <stdio.h>
+#include <math.h>
+#include "mvclpf24.h"
+#include "exp2ap.h"
+
+
+static const float lg2midc = log2f(261.63f);
+
+
+void Ladspa_Moogvcf1::setport (PortIndex port, PortData *data)
+{
+ _port [port] = (float*)data;
+}
+
+
+void Ladspa_Moogvcf1::active (bool act)
+{
+ _c1 = _c2 = _c3 = _c4 = _c5 = _w = _r = 0;
+}
+
+
+void Ladspa_Moogvcf1::runproc (SampleCount len, bool add)
+{
+ int k;
+ float *p0, *p1, *p2, *p3, *p4;
+ float c1, c2, c3, c4, c5;
+ float g0, g1, r, dr, w, dw, x, t;
+
+ p0 = _port [A_INPUT];
+ p1 = _port [A_OUTPUT];
+ p2 = _port [A_FREQ] - 1;
+ p3 = _port [A_FMOD] - 1;
+ p4 = _port [A_RESO] - 1;
+ g0 = exp2ap (0.1661f * _port [C_IPGAIN][0]) / 4;
+ g1 = exp2ap (0.1661f * _port [C_OPGAIN][0]) * 4;
+ if (add) g1 *= _gain;
+
+ c1 = _c1 + 1e-6f;
+ c2 = _c2;
+ c3 = _c3;
+ c4 = _c4;
+ c5 = _c5;
+ w = _w;
+ r = _r;
+
+ do
+ {
+ k = (len > 24) ? 16 : len;
+ p2 += k;
+ p3 += k;
+ p4 += k;
+ len -= k;
+
+ t = exp2ap (_port [C_FMODG][0] * *p3 + log2f(_port [C_FREQ][0]) - lg2midc + *p2 + 10.82f) / _fsam;
+ if (t < 0.8f) t *= 1 - 0.4f * t - 0.125f * t * t;
+ else
+ {
+ t *= 0.6f;
+ if (t > 0.92f) t = 0.92f;
+ }
+ dw = (t - w) / k;
+
+ t = _port [C_RESOG][0] * *p4 + _port [C_RESO][0];
+ if (r > 1) r = 1;
+ if (r < 0) r = 0;
+ dr = (t - r) / k;
+
+ while (k--)
+ {
+ w += dw;
+ r += dr;
+ x = -4.2 * r * c5 + *p0++ * g0 + 1e-10f;
+ t = c1 / (1 + fabsf (c1));
+ c1 += w * (x - t);
+ x = c1 / (1 + fabsf (c1));
+ c2 += w * (x - c2);
+ c3 += w * (c2 - c3);
+ c4 += w * (c3 - c4);
+ if (add) *p1++ += g1 * c4;
+ else *p1++ = g1 * c4;
+ c5 += 0.5f * (c4 - c5);
+ }
+ }
+ while (len);
+
+ _c1 = c1;
+ _c2 = c2;
+ _c3 = c3;
+ _c4 = c4;
+ _c5 = c5;
+ _w = w;
+ _r = r;
+}
+
+
+
+void Ladspa_Moogvcf2::setport (PortIndex port, PortData *data)
+{
+ _port [port] = (float*)data;
+}
+
+
+void Ladspa_Moogvcf2::active (bool act)
+{
+ _c1 = _c2 = _c3 = _c4 = _c5 = _w = _r = 0;
+}
+
+
+void Ladspa_Moogvcf2::runproc (SampleCount len, bool add)
+{
+ int k;
+ float *p0, *p1, *p2, *p3, *p4;
+ float c1, c2, c3, c4, c5;
+ float g0, g1, r, dr, w, dw, x, t;
+
+ p0 = _port [A_INPUT];
+ p1 = _port [A_OUTPUT];
+ p2 = _port [A_FREQ] - 1;
+ p3 = _port [A_FMOD] - 1;
+ p4 = _port [A_RESO] - 1;
+ g0 = exp2ap (0.1661f * _port [C_IPGAIN][0]) / 4;
+ g1 = exp2ap (0.1661f * _port [C_OPGAIN][0]) * 4;
+ if (add) g1 *= _gain;
+
+ c1 = _c1 + 1e-6f;
+ c2 = _c2;
+ c3 = _c3;
+ c4 = _c4;
+ c5 = _c5;
+ w = _w;
+ r = _r;
+
+ do
+ {
+ k = (len > 24) ? 16 : len;
+ p2 += k;
+ p3 += k;
+ p4 += k;
+ len -= k;
+
+ t = exp2ap (_port [C_FMODG][0] * *p3 + log2f(_port [C_FREQ][0]) - lg2midc + *p2 + 10.71f) / _fsam;
+ if (t < 0.8f) t *= 1 - 0.4f * t - 0.125f * t * t;
+ else
+ {
+ t *= 0.6f;
+ if (t > 0.92f) t = 0.92f;
+ }
+ dw = (t - w) / k;
+
+ t = _port [C_RESOG][0] * *p4 + _port [C_RESO][0];
+ if (t > 1) t = 1;
+ if (t < 0) t = 0;
+ dr = (t - r) / k;
+
+ while (k--)
+ {
+ w += dw;
+ r += dr;
+
+ x = -4.5f * r * c5 + *p0++ * g0 + 1e-10f;
+// x = tanhf (x);
+ x /= sqrtf (1 + x * x);
+ c1 += w * (x - c1) / (1 + c1 * c1);
+ c2 += w * (c1 - c2) / (1 + c2 * c2);
+ c3 += w * (c2 - c3) / (1 + c3 * c3);
+ c4 += w * (c3 - c4) / (1 + c4 * c4);
+
+ if (add) *p1++ += g1 * (c4);
+ else *p1++ = g1 * (c4);
+ c5 += 0.5f * (c4 - c5);
+ }
+ }
+ while (len);
+
+ _c1 = c1;
+ _c2 = c2;
+ _c3 = c3;
+ _c4 = c4;
+ _c5 = c5;
+ _w = w;
+ _r = r;
+}
+
+
+
+void Ladspa_Moogvcf3::setport (PortIndex port, PortData *data)
+{
+ _port [port] = (float*)data;
+}
+
+
+void Ladspa_Moogvcf3::active (bool act)
+{
+ _c1 = _c2 = _c3 = _c4 = _c5 = _w = _r = 0;
+}
+
+
+void Ladspa_Moogvcf3::runproc (SampleCount len, bool add)
+{
+ int k;
+ float *p0, *p1, *p2, *p3, *p4;
+ float c1, c2, c3, c4, c5;
+ float g0, g1, r, dr, w, dw, x, t, d;
+
+ p0 = _port [A_INPUT];
+ p1 = _port [A_OUTPUT];
+ p2 = _port [A_FREQ] - 1;
+ p3 = _port [A_FMOD] - 1;
+ p4 = _port [A_RESO] - 1;
+ g0 = exp2ap (0.1661f * _port [C_IPGAIN][0]) / 4;
+ g1 = exp2ap (0.1661f * _port [C_OPGAIN][0]) * 4;
+ if (add) g1 *= _gain;
+
+ c1 = _c1;
+ c2 = _c2;
+ c3 = _c3;
+ c4 = _c4;
+ c5 = _c5;
+ w = _w;
+ r = _r;
+
+ do
+ {
+ k = (len > 24) ? 16 : len;
+ p2 += k;
+ p3 += k;
+ p4 += k;
+ len -= k;
+
+ t = exp2ap (_port [C_FMODG][0] * *p3 + log2f(_port [C_FREQ][0]) - lg2midc + *p2 + 9.70f) / _fsam;
+ if (t < 0.75f) t *= 1.005f - t * (0.624f - t * (0.65f - t * 0.54f));
+ else
+ {
+ t *= 0.6748f;
+ if (t > 0.82f) t = 0.82f;
+ }
+ dw = (t - w) / k;
+
+ t = _port [C_RESOG][0] * *p4 + _port [C_RESO][0];
+ if (t > 1) t = 1;
+ if (t < 0) t = 0;
+ dr = (t - r) / k;
+
+ while (k--)
+ {
+ w += dw;
+ r += dr;
+
+ x = *p0 * g0 - (4.3f - 0.2f * w) * r * c5 + 1e-10f;
+// x = tanhf (x);
+ x /= sqrtf (1 + x * x);
+ d = w * (x - c1) / (1 + c1 * c1);
+ x = c1 + 0.77f * d;
+ c1 = x + 0.23f * d;
+ d = w * (x - c2) / (1 + c2 * c2);
+ x = c2 + 0.77f * d;
+ c2 = x + 0.23f * d;
+ d = w * (x - c3) / (1 + c3 * c3);
+ x = c3 + 0.77f * d;
+ c3 = x + 0.23f * d;
+ d = w * (x - c4);
+ x = c4 + 0.77f * d;
+ c4 = x + 0.23f * d;
+ c5 += 0.85f * (c4 - c5);
+
+ x = *p0++ * g0 -(4.3f - 0.2f * w) * r * c5;
+// x = tanhf (x);
+ x /= sqrtf (1 + x * x);
+ d = w * (x - c1) / (1 + c1 * c1);
+ x = c1 + 0.77f * d;
+ c1 = x + 0.23f * d;
+ d = w * (x - c2) / (1 + c2 * c2);
+ x = c2 + 0.77f * d;
+ c2 = x + 0.23f * d;
+ d = w * (x - c3) / (1 + c3 * c3);
+ x = c3 + 0.77f * d;
+ c3 = x + 0.23f * d;
+ d = w * (x - c4);
+ x = c4 + 0.77f * d;
+ c4 = x + 0.23f * d;
+ c5 += 0.85f * (c4 - c5);
+
+ if (add) *p1++ += g1 * c4;
+ else *p1++ = g1 * c4;
+ }
+ }
+ while (len);
+
+ _c1 = c1;
+ _c2 = c2;
+ _c3 = c3;
+ _c4 = c4;
+ _c5 = c5;
+ _w = w;
+ _r = r;
+}
+
+
+void Ladspa_Moogvcf4::setport (PortIndex port, PortData *data)
+{
+ _port [port] = (float*)data;
+}
+
+
+void Ladspa_Moogvcf4::active (bool act)
+{
+ _c1 = _c2 = _c3 = _c4 = _c5 = _w = _r = 0;
+}
+
+
+void Ladspa_Moogvcf4::runproc (SampleCount len, bool add)
+{
+ int k, op;
+ float *p0, *p1, *p2, *p3, *p4;
+ float c1, c2, c3, c4, c5;
+ float g0, g1, r, dr, w, dw, x, t, d, y;
+
+ p0 = _port [A_INPUT];
+ p1 = _port [A_OUTPUT];
+ p2 = _port [A_FREQ] - 1;
+ p3 = _port [A_FMOD] - 1;
+ p4 = _port [A_RESO] - 1;
+ g0 = exp2ap (0.1661f * _port [C_IPGAIN][0]) / 4;
+ g1 = exp2ap (0.1661f * _port [C_OPGAIN][0]) * 4;
+ op = (int)(floorf (_port [C_LPFILT][0] + 0.5));
+ if (add) g1 *= _gain;
+
+ c1 = _c1 + 1e-6f;
+ c2 = _c2;
+ c3 = _c3;
+ c4 = _c4;
+ c5 = _c5;
+ w = _w;
+ r = _r;
+
+ do
+ {
+ k = (len > 24) ? 16 : len;
+ p2 += k;
+ p3 += k;
+ p4 += k;
+ len -= k;
+
+ t = exp2ap (_port [C_FMODG][0] * *p3 + log2f(_port [C_FREQ][0]) - lg2midc + *p2 + 9.70f) / _fsam;
+ if (t < 0.75f) t *= 1.005f - t * (0.624f - t * (0.65f - t * 0.54f));
+ else
+ {
+ t *= 0.6748f;
+ if (t > 0.82f) t = 0.82f;
+ }
+ dw = (t - w) / k;
+
+ t = _port [C_RESOG][0] * *p4 + _port [C_RESO][0];
+ if (t > 1) t = 1;
+ if (t < 0) t = 0;
+ dr = (t - r) / k;
+
+ while (k--)
+ {
+ w += dw;
+ r += dr;
+
+ x = *p0 * g0 - (4.3f - 0.2f * w) * r * c5 + 1e-10f;
+// x = tanhf (x);
+ x /= sqrtf (1 + x * x);
+ d = w * (x - c1) / (1 + c1 * c1);
+ x = c1 + 0.77f * d;
+ c1 = x + 0.23f * d;
+ d = w * (x - c2) / (1 + c2 * c2);
+ x = c2 + 0.77f * d;
+ c2 = x + 0.23f * d;
+ d = w * (x - c3) / (1 + c3 * c3);
+ x = c3 + 0.77f * d;
+ c3 = x + 0.23f * d;
+ d = w * (x - c4);
+ x = c4 + 0.77f * d;
+ c4 = x + 0.23f * d;
+ c5 += 0.85f * (c4 - c5);
+
+ x = y = *p0++ * g0 -(4.3f - 0.2f * w) * r * c5;
+// x = tanhf (x);
+ x /= sqrtf (1 + x * x);
+ d = w * (x - c1) / (1 + c1 * c1);
+ x = c1 + 0.77f * d;
+ c1 = x + 0.23f * d;
+ d = w * (x - c2) / (1 + c2 * c2);
+ x = c2 + 0.77f * d;
+ c2 = x + 0.23f * d;
+ d = w * (x - c3) / (1 + c3 * c3);
+ x = c3 + 0.77f * d;
+ c3 = x + 0.23f * d;
+ d = w * (x - c4);
+ x = c4 + 0.77f * d;
+ c4 = x + 0.23f * d;
+ c5 += 0.85f * (c4 - c5);
+
+ switch (op)
+ {
+ case 1: y = c1; break;
+ case 2: y = c2; break;
+ case 3: y = c3; break;
+ case 4: y = c4; break;
+ }
+
+ if (add) *p1++ += g1 * y;
+ else *p1++ = g1 * y;
+ }
+ }
+ while (len);
+
+ _c1 = c1;
+ _c2 = c2;
+ _c3 = c3;
+ _c4 = c4;
+ _c5 = c5;
+ _w = w;
+ _r = r;
+}
+
+
diff --git a/src/mvclpf24.h b/src/mvclpf24.h
new file mode 100644
index 0000000..f1132d3
--- /dev/null
+++ b/src/mvclpf24.h
@@ -0,0 +1,110 @@
+/*
+ Copyright (C) 2003-2008 Fons Adriaensen <fons@kokkinizita.net>
+
+ 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 2 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+
+#ifndef __MOOGVCF_H
+#define __MOOGVCF_H
+
+#include "ladspaplugin.h"
+
+
+class Ladspa_Moogvcf1 : public LadspaPlugin
+{
+public:
+
+ enum { A_INPUT, A_OUTPUT, A_FREQ, A_FMOD, A_RESO,
+ C_IPGAIN, C_FREQ, C_FMODG, C_RESO, C_RESOG, C_OPGAIN, NPORT };
+
+ Ladspa_Moogvcf1 (SampleRate fsam) : LadspaPlugin (fsam) {}
+ virtual void setport (PortIndex port, PortData *data);
+ virtual void active (bool act);
+ virtual void runproc (SampleCount len, bool add);
+ virtual ~Ladspa_Moogvcf1 (void) {}
+
+private:
+
+ float *_port [NPORT];
+ float _c1, _c2, _c3, _c4, _c5, _w, _r;
+
+};
+
+
+class Ladspa_Moogvcf2 : public LadspaPlugin
+{
+public:
+
+ enum { A_INPUT, A_OUTPUT, A_FREQ, A_FMOD, A_RESO,
+ C_IPGAIN, C_FREQ, C_FMODG, C_RESO, C_RESOG, C_OPGAIN, NPORT };
+
+ Ladspa_Moogvcf2 (SampleRate fsam) : LadspaPlugin (fsam) {}
+ virtual void setport (PortIndex port, PortData *data);
+ virtual void active (bool act);
+ virtual void runproc (SampleCount len, bool add);
+ virtual ~Ladspa_Moogvcf2 (void) {}
+
+private:
+
+ float *_port [NPORT];
+ float _c1, _c2, _c3, _c4, _c5, _w, _r;
+
+};
+
+
+class Ladspa_Moogvcf3 : public LadspaPlugin
+{
+public:
+
+ enum { A_INPUT, A_OUTPUT, A_FREQ, A_FMOD, A_RESO,
+ C_IPGAIN, C_FREQ, C_FMODG, C_RESO, C_RESOG, C_OPGAIN, NPORT };
+
+ Ladspa_Moogvcf3 (SampleRate fsam) : LadspaPlugin (fsam) {}
+ virtual void setport (PortIndex port, PortData *data);
+ virtual void active (bool act);
+ virtual void runproc (SampleCount len, bool add);
+ virtual ~Ladspa_Moogvcf3 (void) {}
+
+private:
+
+ float *_port [NPORT];
+ float _c1, _c2, _c3, _c4, _c5, _w, _r;
+
+};
+
+
+class Ladspa_Moogvcf4 : public LadspaPlugin
+{
+public:
+
+ enum { A_INPUT, A_OUTPUT, A_FREQ, A_FMOD, A_RESO,
+ C_IPGAIN, C_FREQ, C_FMODG, C_RESO, C_RESOG,
+ C_LPFILT, C_OPGAIN, NPORT, NLABEL = 5 };
+
+ Ladspa_Moogvcf4 (SampleRate fsam) : LadspaPlugin (fsam) {}
+ virtual void setport (PortIndex port, PortData *data);
+ virtual void active (bool act);
+ virtual void runproc (SampleCount len, bool add);
+ virtual ~Ladspa_Moogvcf4 (void) {}
+
+private:
+
+ float *_port [NPORT];
+ float _c1, _c2, _c3, _c4, _c5, _w, _r;
+
+};
+
+#endif
diff --git a/src/mvclpf24_if.cc b/src/mvclpf24_if.cc
new file mode 100644
index 0000000..301ae92
--- /dev/null
+++ b/src/mvclpf24_if.cc
@@ -0,0 +1,299 @@
+/*
+ Copyright (C) 2003-2008 Fons Adriaensen <fons@kokkinizita.net>
+
+ 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 2 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+//-----------------------------------------------------------------------------------
+// Common definitions
+
+
+#include "mvclpf24.h"
+
+#define NMODS 4
+#define VERSION "0.4.0"
+
+
+static const char* maker = "Fons Adriaensen <fons@kokkinizita.net>";
+static const char* copyr = "(C) 2003-2008 Fons Adriaensen - License: GPL2";
+
+
+static void pconnect (LADSPA_Handle H, unsigned long port, LADSPA_Data *data)
+{
+ ((LadspaPlugin *)H)->setport (port, data);
+}
+
+static void activate (LADSPA_Handle H)
+{
+ ((LadspaPlugin *)H)->active (true);
+}
+
+static void runplugin (LADSPA_Handle H, unsigned long k)
+{
+ ((LadspaPlugin *)H)->runproc (k, false);
+}
+
+static void runadding (LADSPA_Handle H, unsigned long k)
+{
+ ((LadspaPlugin *)H)->runproc (k, true);
+}
+
+static void setadding (LADSPA_Handle H, LADSPA_Data gain)
+{
+ ((LadspaPlugin *)H)->setgain (gain);
+}
+
+static void deactivate (LADSPA_Handle H)
+{
+ ((LadspaPlugin *)H)->active (false);
+}
+
+static void cleanup (LADSPA_Handle H)
+{
+ delete (LadspaPlugin *) H;
+}
+
+//-----------------------------------------------------------------------------------
+// Plugin definitions
+
+
+static const char* name1 = "Mvclpf-1 Digital implementation of the VC filter invented by R.A.Moog";
+static const char* label1 = "Mvclpf-1";
+
+static LADSPA_Handle instant1 (const struct _LADSPA_Descriptor *desc, unsigned long rate)
+{
+ return new Ladspa_Moogvcf1 (rate);
+}
+
+static const char* name2 = "Mvclpf-2 Digital implementation of the VC filter invented by R.A.Moog";
+static const char* label2 = "Mvclpf-2";
+
+static LADSPA_Handle instant2 (const struct _LADSPA_Descriptor *desc, unsigned long rate)
+{
+ return new Ladspa_Moogvcf2 (rate);
+}
+
+static const char* name3 = "Mvclpf-3 Digital implementation of the VC filter invented by R.A.Moog";
+static const char* label3 = "Mvclpf-3";
+
+static LADSPA_Handle instant3 (const struct _LADSPA_Descriptor *desc, unsigned long rate)
+{
+ return new Ladspa_Moogvcf3 (rate);
+}
+
+static const char* name4 = "Mvclpf-4 Digital implementation of the VC filter invented by R.A.Moog";
+static const char* label4 = "Mvclpf-4";
+
+static LADSPA_Handle instant4 (const struct _LADSPA_Descriptor *desc, unsigned long rate)
+{
+ return new Ladspa_Moogvcf4 (rate);
+}
+
+
+static const char * const pname1 [Ladspa_Moogvcf1::NPORT] =
+{
+ "Input",
+ "Output",
+ "Frequency",
+ "Exp FM",
+ "Resonance",
+ "Input gain (dB)",
+ "Frequency",
+ "Exp FM gain",
+ "Resonance",
+ "Resonance gain",
+ "Output gain (dB)"
+};
+
+static const LADSPA_PortDescriptor pdesc1 [Ladspa_Moogvcf1::NPORT] =
+{
+ LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO,
+ LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO,
+ LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO,
+ LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO,
+ LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO,
+ LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL,
+ LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL,
+ LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL,
+ LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL,
+ LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL,
+ LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL
+};
+
+static const LADSPA_PortRangeHint phint1 [Ladspa_Moogvcf1::NPORT] =
+{
+ { 0, 0, 0 },
+ { 0, 0, 0 },
+ { 0, 0, 0 },
+ { 0, 0, 0 },
+ { 0, 0, 0 },
+ { LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_DEFAULT_0, -60, 10 },
+ { LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_DEFAULT_0, -6, 6 },
+ { LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE, 0, 10 },
+ { LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE, 0, 1 },
+ { LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE, 0, 1 },
+ { LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_DEFAULT_0, -15, 15 },
+};
+
+
+static const char * const pname4 [Ladspa_Moogvcf4::NPORT + Ladspa_Moogvcf4::NLABEL] =
+{
+ "Input",
+ "Output",
+ "Frequency",
+ "Exp FM",
+ "Resonance",
+ "Input gain (dB)",
+ "Frequency",
+ "Exp FM gain",
+ "Resonance",
+ "Resonance gain",
+ "Filter poles",
+ "Output gain (dB)",
+ "No lowpass",
+ " 6 dB/oct",
+ "12 dB/oct",
+ "18 dB/oct",
+ "24 dB/oct"
+};
+
+static const LADSPA_PortDescriptor pdesc4 [Ladspa_Moogvcf4::NPORT] =
+{
+ LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO,
+ LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO,
+ LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO,
+ LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO,
+ LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO,
+ LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL,
+ LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL,
+ LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL,
+ LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL,
+ LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL,
+ LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL,
+ LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL
+};
+
+static const LADSPA_PortRangeHint phint4 [Ladspa_Moogvcf4::NPORT] =
+{
+ { 0, 0, 0 },
+ { 0, 0, 0 },
+ { 0, 0, 0 },
+ { 0, 0, 0 },
+ { 0, 0, 0 },
+ { LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_DEFAULT_0, -60, 10 },
+ { LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_DEFAULT_0, -6, 6 },
+ { LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE, 0, 10 },
+ { LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE, 0, 1 },
+ { LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE, 0, 1 },
+ { LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_INTEGER /*| LADSPA_HINT_SWITCHED*/, 0, 4 },
+ { LADSPA_HINT_BOUNDED_BELOW | LADSPA_HINT_BOUNDED_ABOVE | LADSPA_HINT_DEFAULT_0, -15, 15 },
+};
+
+
+static const LADSPA_Descriptor moddescr [NMODS] =
+{
+ {
+ 1941,
+ label1,
+ LADSPA_PROPERTY_REALTIME | LADSPA_PROPERTY_HARD_RT_CAPABLE,
+ name1,
+ maker,
+ copyr,
+ Ladspa_Moogvcf1::NPORT,
+ pdesc1,
+ pname1,
+ phint1,
+ 0,
+ instant1,
+ pconnect,
+ activate,
+ runplugin,
+ runadding,
+ setadding,
+ deactivate,
+ cleanup
+ },
+ {
+ 1942,
+ label2,
+ LADSPA_PROPERTY_REALTIME | LADSPA_PROPERTY_HARD_RT_CAPABLE,
+ name2,
+ maker,
+ copyr,
+ Ladspa_Moogvcf2::NPORT,
+ pdesc1,
+ pname1,
+ phint1,
+ 0,
+ instant2,
+ pconnect,
+ activate,
+ runplugin,
+ runadding,
+ setadding,
+ deactivate,
+ cleanup
+ },
+ {
+ 1943,
+ label3,
+ LADSPA_PROPERTY_REALTIME | LADSPA_PROPERTY_HARD_RT_CAPABLE,
+ name3,
+ maker,
+ copyr,
+ Ladspa_Moogvcf3::NPORT,
+ pdesc1,
+ pname1,
+ phint1,
+ 0,
+ instant3,
+ pconnect,
+ activate,
+ runplugin,
+ runadding,
+ setadding,
+ deactivate,
+ cleanup
+ },
+ {
+ 1948,
+ label4,
+ LADSPA_PROPERTY_REALTIME | LADSPA_PROPERTY_HARD_RT_CAPABLE,
+ name4,
+ maker,
+ copyr,
+ Ladspa_Moogvcf4::NPORT,
+ pdesc4,
+ pname4,
+ phint4,
+ 0,
+ instant4,
+ pconnect,
+ activate,
+ runplugin,
+ runadding,
+ setadding,
+ deactivate,
+ cleanup
+ }
+};
+
+extern "C" const LADSPA_Descriptor *ladspa_descriptor (unsigned long i)
+{
+ if (i >= NMODS) return 0;
+ return moddescr + i;
+}
+
+//-----------------------------------------------------------------------------------
diff --git a/src/mvclpf24_lv2.cc b/src/mvclpf24_lv2.cc
new file mode 100644
index 0000000..dbd8b51
--- /dev/null
+++ b/src/mvclpf24_lv2.cc
@@ -0,0 +1,136 @@
+/*
+ Copyright (C) 2012 David Robillard <d@drobilla.net>
+
+ 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 2 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include <stddef.h>
+
+#include "mvclpf24.h"
+
+extern "C" {
+
+static void
+connect_port(LV2_Handle instance,
+ uint32_t port,
+ void* data)
+{
+ ((LadspaPlugin*)instance)->setport(port, data);
+}
+
+static void
+activate(LV2_Handle instance)
+{
+ ((LadspaPlugin*)instance)->active(true);
+}
+
+static void
+run(LV2_Handle instance, uint32_t n_samples)
+{
+ ((LadspaPlugin*)instance)->runproc(n_samples, false);
+}
+
+static void
+deactivate(LV2_Handle instance)
+{
+ ((LadspaPlugin*)instance)->active(false);
+}
+
+static void
+cleanup(LV2_Handle instance)
+{
+ delete ((LadspaPlugin*)instance);
+}
+
+static LV2_Handle
+instantiate1(const LV2_Descriptor* descriptor,
+ double rate,
+ const char* bundle_path,
+ const LV2_Feature* const* features)
+{
+ return new Ladspa_Moogvcf1(rate);
+}
+
+static LV2_Handle
+instantiate2(const LV2_Descriptor* descriptor,
+ double rate,
+ const char* bundle_path,
+ const LV2_Feature* const* features)
+{
+ return new Ladspa_Moogvcf2(rate);
+}
+static LV2_Handle
+instantiate3(const LV2_Descriptor* descriptor,
+ double rate,
+ const char* bundle_path,
+ const LV2_Feature* const* features)
+{
+ return new Ladspa_Moogvcf3(rate);
+}
+static LV2_Handle
+instantiate4(const LV2_Descriptor* descriptor,
+ double rate,
+ const char* bundle_path,
+ const LV2_Feature* const* features)
+{
+ return new Ladspa_Moogvcf4(rate);
+}
+
+static const LV2_Descriptor descriptors[4] = {
+ { "http://drobilla.net/plugins/fomp/mvclpf1",
+ instantiate1,
+ connect_port,
+ activate,
+ run,
+ deactivate,
+ cleanup,
+ NULL },
+ { "http://drobilla.net/plugins/fomp/mvclpf2",
+ instantiate2,
+ connect_port,
+ activate,
+ run,
+ deactivate,
+ cleanup,
+ NULL },
+ { "http://drobilla.net/plugins/fomp/mvclpf3",
+ instantiate3,
+ connect_port,
+ activate,
+ run,
+ deactivate,
+ cleanup,
+ NULL },
+ { "http://drobilla.net/plugins/fomp/mvclpf4",
+ instantiate4,
+ connect_port,
+ activate,
+ run,
+ deactivate,
+ cleanup,
+ NULL }
+};
+
+LV2_SYMBOL_EXPORT
+const LV2_Descriptor*
+lv2_descriptor(uint32_t index)
+{
+ if (index < 4) {
+ return &descriptors[index];
+ }
+ return NULL;
+}
+
+} // extern "C"
diff --git a/src/pareq.cc b/src/pareq.cc
new file mode 100644
index 0000000..4feb991
--- /dev/null
+++ b/src/pareq.cc
@@ -0,0 +1,199 @@
+// ----------------------------------------------------------------------
+//
+// Copyright (C) 2010-2013 Fons Adriaensen <fons@linuxaudio.org>
+//
+// 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 2 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+//
+// ----------------------------------------------------------------------
+
+
+#include <math.h>
+#include <string.h>
+#include "pareq.h"
+
+
+Pareq::Pareq (void) :
+ _touch0 (0),
+ _touch1 (0),
+ _state (BYPASS),
+ _g0 (1),
+ _g1 (1),
+ _f0 (1e3f),
+ _f1 (1e3f)
+{
+ setfsamp (0.0f);
+}
+
+
+Pareq::~Pareq (void)
+{
+}
+
+
+void Pareq::setfsamp (float fsamp)
+{
+ _fsamp = fsamp;
+ reset ();
+}
+
+
+void Pareq::reset (void)
+{
+ memset (_z1, 0, sizeof (float) * MAXCH);
+ memset (_z2, 0, sizeof (float) * MAXCH);
+}
+
+
+void Pareq::prepare (int nsamp)
+{
+ bool upd = false;
+ float g, f;
+
+ if (_touch1 != _touch0)
+ {
+ if (_g0 < 0.1f) _g0 = 0.1f;
+ if (_g0 > 10.0f) _g0 = 10.0f;
+ if (_f0 < 20.0f) _f0 = 20.0f;
+ if (_f0 > 20e3f) _f0 = 20e3f;
+ g = _g0;
+ f = _f0;
+ if (g != _g1)
+ {
+ upd = true;
+ if (g > 2 * _g1) _g1 *= 2;
+ else if (_g1 > 2 * g) _g1 /= 2;
+ else _g1 = g;
+ }
+ if (f != _f1)
+ {
+ upd = true;
+ if (f > 2 * _f1) _f1 *= 2;
+ else if (_f1 > 2 * f) _f1 /= 2;
+ else _f1 = f;
+ }
+ if (upd)
+ {
+ if ((_state == BYPASS) && (_g1 == 1))
+ {
+ calcpar1 (0, _g1, _f1);
+ }
+ else
+ {
+ _state = SMOOTH;
+ calcpar1 (nsamp, _g1, _f1);
+ }
+ }
+ else
+ {
+ _touch1 = _touch0;
+ if (fabs (_g1 - 1) < 0.001f)
+ {
+ _state = BYPASS;
+ reset ();
+ }
+ else
+ {
+ _state = STATIC;
+ }
+ }
+ }
+}
+
+
+void Pareq::calcpar1 (int nsamp, float g, float f)
+{
+ float b, c1, c2, gg;
+
+ f *= float (M_PI) / _fsamp;
+ b = 2 * f / sqrtf (g);
+ gg = 0.5f * (g - 1);
+ c1 = -cosf (2 * f);
+ c2 = (1 - b) / (1 + b);
+ if (nsamp)
+ {
+ _dc1 = (c1 - _c1) / nsamp + 1e-30f;
+ _dc2 = (c2 - _c2) / nsamp + 1e-30f;
+ _dgg = (gg - _gg) / nsamp + 1e-30f;
+ }
+ else
+ {
+ _c1 = c1;
+ _c2 = c2;
+ _gg = gg;
+ }
+}
+
+
+void Pareq::process1 (int nsamp, int nchan, float *data[])
+{
+ int i, j;
+ float c1, c2, gg;
+ float x, y, z1, z2;
+ float *p;
+
+ c1 = _c1;
+ c2 = _c2;
+ gg = _gg;
+ if (_state == SMOOTH)
+ {
+ for (i = 0; i < nchan; i++)
+ {
+ p = data [i];
+ z1 = _z1 [i];
+ z2 = _z2 [i];
+ c1 = _c1;
+ c2 = _c2;
+ gg = _gg;
+ for (j = 0; j < nsamp; j++)
+ {
+ c1 += _dc1;
+ c2 += _dc2;
+ gg += _dgg;
+ x = *p;
+ y = x - c2 * z2;
+ *p++ = x - gg * (z2 + c2 * y - x);
+ y -= c1 * z1;
+ z2 = z1 + c1 * y;
+ z1 = y + 1e-20f;
+ }
+ _z1 [i] = z1;
+ _z2 [i] = z2;
+ }
+ _c1 = c1;
+ _c2 = c2;
+ _gg = gg;
+ }
+ else
+ {
+ for (i = 0; i < nchan; i++)
+ {
+ p = data [i];
+ z1 = _z1 [i];
+ z2 = _z2 [i];
+ for (j = 0; j < nsamp; j++)
+ {
+ x = *p;
+ y = x - c2 * z2;
+ *p++ = x - gg * (z2 + c2 * y - x);
+ y -= c1 * z1;
+ z2 = z1 + c1 * y;
+ z1 = y + 1e-20f;
+ }
+ _z1 [i] = z1;
+ _z2 [i] = z2;
+ }
+ }
+}
+
diff --git a/src/pareq.h b/src/pareq.h
new file mode 100644
index 0000000..b2448be
--- /dev/null
+++ b/src/pareq.h
@@ -0,0 +1,74 @@
+// ----------------------------------------------------------------------
+//
+// Copyright (C) 2010-2013 Fons Adriaensen <fons@linuxaudio.org>
+//
+// 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 2 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+//
+// ----------------------------------------------------------------------
+
+
+#ifndef __PAREQ_H
+#define __PAREQ_H
+
+
+#include <stdint.h>
+#include <math.h>
+
+
+class Pareq
+{
+public:
+
+ Pareq (void);
+ ~Pareq (void);
+
+ void setfsamp (float fsamp);
+ void setparam (float f, float g)
+ {
+ _f0 = f;
+ _g0 = powf (10.0f, 0.05f * g);
+ _touch0++;
+ }
+ void reset (void);
+ void prepare (int nsamp);
+ void process (int nsamp, int nchan, float *data[])
+ {
+ if (_state != BYPASS) process1 (nsamp, nchan, data);
+ }
+
+private:
+
+ enum { BYPASS, STATIC, SMOOTH, MAXCH = 4 };
+
+ void calcpar1 (int nsamp, float g, float f);
+ void process1 (int nsamp, int nchan, float *data[]);
+
+ volatile int16_t _touch0;
+ volatile int16_t _touch1;
+ int _state;
+ float _fsamp;
+
+ float _g0, _g1;
+ float _f0, _f1;
+ float _c1, _dc1;
+ float _c2, _dc2;
+ float _gg, _dgg;
+
+ float _z1 [MAXCH];
+ float _z2 [MAXCH];
+};
+
+
+#endif
diff --git a/src/plugin_lv2.h b/src/plugin_lv2.h
new file mode 100644
index 0000000..4014b59
--- /dev/null
+++ b/src/plugin_lv2.h
@@ -0,0 +1,55 @@
+/*
+ Copyright (C) 2012 David Robillard <d@drobilla.net>
+
+ 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 2 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "ladspaplugin.h"
+
+extern "C" {
+
+static void
+connect_port(LV2_Handle instance,
+ uint32_t port,
+ void* data)
+{
+ ((LadspaPlugin*)instance)->setport(port, data);
+}
+
+static void
+activate(LV2_Handle instance)
+{
+ ((LadspaPlugin*)instance)->active(true);
+}
+
+static void
+run(LV2_Handle instance, uint32_t n_samples)
+{
+ ((LadspaPlugin*)instance)->runproc(n_samples, false);
+}
+
+static void
+deactivate(LV2_Handle instance)
+{
+ ((LadspaPlugin*)instance)->active(false);
+}
+
+static void
+cleanup(LV2_Handle instance)
+{
+ delete ((LadspaPlugin*)instance);
+}
+
+} // extern "C"
diff --git a/src/reverbs.cc b/src/reverbs.cc
new file mode 100644
index 0000000..9e8e5af
--- /dev/null
+++ b/src/reverbs.cc
@@ -0,0 +1,125 @@
+// -----------------------------------------------------------------------
+//
+// Copyright (C) 2003-2014 Fons Adriaensen <fons@linuxaudio.org>
+//
+// 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 2 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+//
+// -----------------------------------------------------------------------
+
+
+#include <stdio.h>
+#include <math.h>
+#include "reverbs.h"
+
+
+void Ladspa_zita_reverb::setport (PortIndex port, PortData *data)
+{
+ _port [port] = (float*)data;
+}
+
+
+void Ladspa_zita_reverb::active (bool act)
+{
+ if (! act)
+ {
+ _zreverb->reset ();
+ _nprep = 0;
+ }
+}
+
+
+void Ladspa_zita_reverb::runproc (SampleCount frames, bool add)
+{
+ unsigned long k;
+ float *inp [2] = { _port [A_INPL], _port [A_INPR] };
+ float *out [2] = { _port [A_OUTL], _port [A_OUTR] };
+
+ _zreverb->set_delay (_port [C_DELAY][0]);
+ _zreverb->set_xover (_port [C_XOVER][0]);
+ _zreverb->set_rtlow (_port [C_RTLOW][0]);
+ _zreverb->set_rtmid (_port [C_RTMID][0]);
+ _zreverb->set_fdamp (_port [C_FDAMP][0]);
+ _zreverb->set_eq1 (_port [C_FREQ1][0], _port [C_GAIN1][0]);
+ _zreverb->set_eq2 (_port [C_FREQ2][0], _port [C_GAIN2][0]);
+ _zreverb->set_opmix (_port [C_OPMIX][0]);
+ while (frames)
+ {
+ if (!_nprep)
+ {
+ _zreverb->prepare (FRAGM);
+ _nprep = FRAGM;
+ }
+ k = (_nprep < frames) ? _nprep : frames;
+ _zreverb->process (k, inp, out);
+ inp [0] += k;
+ inp [1] += k;
+ out [0] += k;
+ out [1] += k;
+ frames -= k;
+ _nprep -= k;
+ }
+}
+
+
+
+void Ladspa_zita_reverb_amb::setport (PortIndex port, PortData *data)
+{
+ _port [port] = (float*)data;
+}
+
+
+void Ladspa_zita_reverb_amb::active (bool act)
+{
+ if (! act)
+ {
+ _zreverb->reset ();
+ _nprep = 0;
+ }
+}
+
+
+void Ladspa_zita_reverb_amb::runproc (SampleCount frames, bool add)
+{
+ unsigned long k;
+ float *inp [2] = { _port [A_INPL], _port [A_INPR] };
+ float *out [4] = { _port [A_OUTW], _port [A_OUTX], _port [A_OUTY], _port [A_OUTZ] };
+
+ _zreverb->set_delay (_port [C_DELAY][0]);
+ _zreverb->set_xover (_port [C_XOVER][0]);
+ _zreverb->set_rtlow (_port [C_RTLOW][0]);
+ _zreverb->set_rtmid (_port [C_RTMID][0]);
+ _zreverb->set_fdamp (_port [C_FDAMP][0]);
+ _zreverb->set_eq1 (_port [C_FREQ1][0], _port [C_GAIN1][0]);
+ _zreverb->set_eq2 (_port [C_FREQ2][0], _port [C_GAIN2][0]);
+ _zreverb->set_rgxyz (_port [C_RGXYZ][0]);
+ while (frames)
+ {
+ if (!_nprep)
+ {
+ _zreverb->prepare (FRAGM);
+ _nprep = FRAGM;
+ }
+ k = (_nprep < frames) ? _nprep : frames;
+ _zreverb->process (k, inp, out);
+ inp [0] += k;
+ inp [1] += k;
+ out [0] += k;
+ out [1] += k;
+ out [2] += k;
+ out [3] += k;
+ frames -= k;
+ _nprep -= k;
+ }
+}
diff --git a/src/reverbs.h b/src/reverbs.h
new file mode 100644
index 0000000..2650856
--- /dev/null
+++ b/src/reverbs.h
@@ -0,0 +1,134 @@
+// -----------------------------------------------------------------------
+//
+// Copyright (C) 2003-2014 Fons Adriaensen <fons@linuxaudio.org>
+//
+// 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 2 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+//
+// -----------------------------------------------------------------------
+
+
+#ifndef __REVERBS_H
+#define __REVERBS_H
+
+#include "ladspaplugin.h"
+#include "zreverb.h"
+
+
+// -----------------------------------------------------------------------
+
+
+class Ladspa_zita_reverb : public LadspaPlugin
+{
+public:
+
+ enum
+ {
+ A_INPL,
+ A_INPR,
+ A_OUTL,
+ A_OUTR,
+ C_DELAY,
+ C_XOVER,
+ C_RTLOW,
+ C_RTMID,
+ C_FDAMP,
+ C_FREQ1,
+ C_GAIN1,
+ C_FREQ2,
+ C_GAIN2,
+ C_OPMIX,
+ NPORT
+ };
+
+ Ladspa_zita_reverb (SampleRate fsam) : LadspaPlugin (fsam)
+ {
+ _zreverb = new Zreverb ();
+ _zreverb->init (fsam, false);
+ _nprep = 0;
+ }
+ virtual void setport (PortIndex port, PortData *data);
+ virtual void active (bool act);
+ virtual void runproc (SampleCount len, bool add);
+ virtual ~Ladspa_zita_reverb (void)
+ {
+ delete _zreverb;
+ }
+
+private:
+
+ enum { FRAGM = 2048 };
+
+ float *_port [NPORT];
+ Zreverb *_zreverb;
+ unsigned long _nprep;
+};
+
+
+// -----------------------------------------------------------------------
+
+
+class Ladspa_zita_reverb_amb : public LadspaPlugin
+{
+public:
+
+ enum
+ {
+ A_INPL,
+ A_INPR,
+ A_OUTW,
+ A_OUTX,
+ A_OUTY,
+ A_OUTZ,
+ C_DELAY,
+ C_XOVER,
+ C_RTLOW,
+ C_RTMID,
+ C_FDAMP,
+ C_FREQ1,
+ C_GAIN1,
+ C_FREQ2,
+ C_GAIN2,
+ C_RGXYZ,
+ NPORT
+ };
+
+ Ladspa_zita_reverb_amb (unsigned long fsam) : LadspaPlugin (fsam)
+ {
+ _zreverb = new Zreverb ();
+ _zreverb->init (fsam, true);
+ _nprep = 0;
+ }
+ virtual void setport (PortIndex port, PortData *data);
+ virtual void active (bool act);
+ virtual void runproc (SampleCount len, bool add);
+ virtual ~Ladspa_zita_reverb_amb (void)
+ {
+ delete _zreverb;
+ }
+
+private:
+
+ enum { FRAGM = 2048 };
+
+ float *_port [NPORT];
+ Zreverb *_zreverb;
+ unsigned long _nprep;
+};
+
+
+// -----------------------------------------------------------------------
+
+
+#endif
diff --git a/src/reverbs_lv2.cc b/src/reverbs_lv2.cc
new file mode 100644
index 0000000..e6eb9f0
--- /dev/null
+++ b/src/reverbs_lv2.cc
@@ -0,0 +1,73 @@
+/*
+ Copyright (C) 2014 David Robillard <d@drobilla.net>
+
+ 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 2 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include <stddef.h>
+
+#include "reverbs.h"
+#include "plugin_lv2.h"
+
+extern "C" {
+
+static LV2_Handle
+instantiate(const LV2_Descriptor* descriptor,
+ double rate,
+ const char* bundle_path,
+ const LV2_Feature* const* features)
+{
+ return new Ladspa_zita_reverb(rate);
+}
+
+static LV2_Handle
+instantiate_amb(const LV2_Descriptor* descriptor,
+ double rate,
+ const char* bundle_path,
+ const LV2_Feature* const* features)
+{
+ return new Ladspa_zita_reverb_amb(rate);
+}
+
+static const LV2_Descriptor descriptors[] = {
+ {
+ "http://drobilla.net/plugins/fomp/reverb",
+ instantiate,
+ connect_port,
+ activate,
+ run,
+ deactivate,
+ cleanup,
+ NULL
+ } , {
+ "http://drobilla.net/plugins/fomp/reverb_amb",
+ instantiate_amb,
+ connect_port,
+ activate,
+ run,
+ deactivate,
+ cleanup,
+ NULL
+ }
+};
+
+LV2_SYMBOL_EXPORT
+const LV2_Descriptor*
+lv2_descriptor(uint32_t index)
+{
+ return (index < 2) ? &descriptors[index] : NULL;
+}
+
+} // extern "C"
diff --git a/src/zreverb.cc b/src/zreverb.cc
new file mode 100644
index 0000000..98055a2
--- /dev/null
+++ b/src/zreverb.cc
@@ -0,0 +1,425 @@
+// -----------------------------------------------------------------------
+//
+// Copyright (C) 2003-2013 Fons Adriaensen <fons@linuxaudio.org>
+//
+// 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 2 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+//
+// -----------------------------------------------------------------------
+
+
+#include <stdio.h>
+#include <string.h>
+#include <math.h>
+#include "zreverb.h"
+
+
+// -----------------------------------------------------------------------
+
+
+Diff1::Diff1 (void) :
+ _size (0),
+ _line (0)
+{
+}
+
+
+Diff1::~Diff1 (void)
+{
+ fini ();
+}
+
+
+void Diff1::init (int size, float c)
+{
+ _size = size;
+ _line = new float [size];
+ _c = c;
+ reset ();
+}
+
+
+void Diff1::fini (void)
+{
+ delete[] _line;
+ _size = 0;
+ _line = 0;
+}
+
+
+void Diff1::reset (void)
+{
+ memset (_line, 0, _size * sizeof (float));
+ _i = 0;
+}
+
+
+// -----------------------------------------------------------------------
+
+
+Delay::Delay (void) :
+ _size (0),
+ _line (0)
+{
+}
+
+
+Delay::~Delay (void)
+{
+ fini ();
+}
+
+
+void Delay::init (int size)
+{
+ _size = size;
+ _line = new float [size];
+ reset ();
+}
+
+
+void Delay::fini (void)
+{
+ delete[] _line;
+ _size = 0;
+ _line = 0;
+}
+
+
+void Delay::reset (void)
+{
+ memset (_line, 0, _size * sizeof (float));
+ _i = 0;
+}
+
+
+// -----------------------------------------------------------------------
+
+
+Vdelay::Vdelay (void) :
+ _size (0),
+ _line (0)
+{
+}
+
+
+Vdelay::~Vdelay (void)
+{
+ fini ();
+}
+
+
+void Vdelay::init (int size)
+{
+ _size = size;
+ _line = new float [size];
+ reset ();
+}
+
+
+void Vdelay::fini (void)
+{
+ delete[] _line;
+ _size = 0;
+ _line = 0;
+}
+
+
+void Vdelay::reset (void)
+{
+ memset (_line, 0, _size * sizeof (float));
+ _iwr = 0;
+ _ir0 = 0;
+ _ir1 = 0;
+}
+
+
+void Vdelay::set_delay (int del)
+{
+ _ir1 = _iwr - del;
+ if (_ir1 < 0) _ir1 += _size;
+}
+
+
+// -----------------------------------------------------------------------
+
+
+void Filt1::set_params (float del, float tmf, float tlo, float wlo, float thi, float chi)
+{
+ float g, t;
+
+ _gmf = powf (0.001f, del / tmf);
+ _glo = powf (0.001f, del / tlo) / _gmf - 1.0f;
+ _wlo = wlo;
+ g = powf (0.001f, del / thi) / _gmf;
+ t = (1 - g * g) / (2 * g * g * chi);
+ _whi = (sqrtf (1 + 4 * t) - 1) / (2 * t);
+}
+
+
+// -----------------------------------------------------------------------
+
+
+float Zreverb::_tdiff1 [8] =
+{
+ 20346e-6f,
+ 24421e-6f,
+ 31604e-6f,
+ 27333e-6f,
+ 22904e-6f,
+ 29291e-6f,
+ 13458e-6f,
+ 19123e-6f
+};
+
+
+float Zreverb::_tdelay [8] =
+{
+ 153129e-6f,
+ 210389e-6f,
+ 127837e-6f,
+ 256891e-6f,
+ 174713e-6f,
+ 192303e-6f,
+ 125000e-6f,
+ 219991e-6f
+};
+
+
+Zreverb::Zreverb (void)
+{
+}
+
+
+Zreverb::~Zreverb (void)
+{
+ fini ();
+}
+
+
+void Zreverb::init (float fsamp, bool ambis)
+{
+ int i, k1, k2;
+
+ _fsamp = fsamp;
+ _ambis = ambis;
+ _cntA1 = 1;
+ _cntA2 = 0;
+ _cntB1 = 1;
+ _cntB2 = 0;
+ _cntC1 = 1;
+ _cntC2 = 0;
+
+ _ipdel = 0.04f;
+ _xover = 200.0f;
+ _rtlow = 3.0f;
+ _rtmid = 2.0f;
+ _fdamp = 3e3f;
+ _opmix = 1.0f;
+ _rgxyz = 0.0f;
+
+ _g0 = _d0 = 0;
+ _g1 = _d1 = 0;
+
+ _vdelay0.init ((int)(0.1f * _fsamp));
+ _vdelay1.init ((int)(0.1f * _fsamp));
+ for (i = 0; i < 8; i++)
+ {
+ k1 = (int)(floorf (_tdiff1 [i] * _fsamp + 0.5f));
+ k2 = (int)(floorf (_tdelay [i] * _fsamp + 0.5f));
+ _diff1 [i].init (k1, (i & 1) ? -0.6f : 0.6f);
+ _delay [i].init (k2 - k1);
+ }
+
+ _pareq1.setfsamp (fsamp);
+ _pareq2.setfsamp (fsamp);
+}
+
+
+void Zreverb::fini (void)
+{
+}
+
+
+void Zreverb::reset (void)
+{
+ int i;
+
+ _vdelay0.reset ();
+ _vdelay1.reset ();
+ for (i = 0; i < 8; i++)
+ {
+ _diff1 [i].reset ();
+ _filt1 [i].reset ();
+ _delay [i].reset ();
+ }
+}
+
+
+void Zreverb::prepare (int nfram)
+{
+ int a, b, c, i, k;
+ float t0, t1, wlo, chi;
+
+ a = _cntA1;
+ b = _cntB1;
+ c = _cntC1;
+ _d0 = _d1 = 0;
+
+ if (a != _cntA2)
+ {
+ if (_ipdel < 0.02f) _ipdel = 0.02f;
+ if (_ipdel > 0.10f) _ipdel = 0.10f;
+ k = (int)(floorf ((_ipdel - 0.02f) * _fsamp + 0.5f));
+ _vdelay0.set_delay (k);
+ _vdelay1.set_delay (k);
+ _cntA2 = a;
+ }
+
+ if (b != _cntB2)
+ {
+ if (_xover < 50.0f) _xover = 50.0f;
+ if (_xover > 1.0e3f) _xover = 1.0e3f;
+ if (_rtlow < 1.0f) _rtlow = 1.0f;
+ if (_rtlow > 8.0f) _rtlow = 8.0f;
+ if (_rtmid < 1.0f) _rtmid = 1.0f;
+ if (_rtmid > 8.0f) _rtmid = 8.0f;
+ if (_fdamp < 1.5e3f) _fdamp = 1.5e3f;
+ if (_fdamp > 24.0e3f) _fdamp = 24.0e3f;
+ wlo = 6.2832f * _xover / _fsamp;
+ if (_fdamp > 0.49f * _fsamp) chi = 2;
+ else chi = 1 - cosf (6.2832f * _fdamp / _fsamp);
+ for (i = 0; i < 8; i++)
+ {
+ _filt1 [i].set_params (_tdelay [i], _rtmid, _rtlow, wlo, 0.5f * _rtmid, chi);
+ }
+ _cntB2 = b;
+ }
+
+ if (c != _cntC2)
+ {
+ if (_rtmid < 1.0f) _rtmid = 1.0f;
+ if (_rtmid > 8.0f) _rtmid = 8.0f;
+ if (_ambis)
+ {
+ if (_rgxyz < -9.0f) _rgxyz = -9.0f;
+ if (_rgxyz > 9.0f) _rgxyz = 9.0f;
+ t0 = 1.0f / sqrtf (_rtmid);
+ t1 = t0 * powf (10.0f, 0.05f * _rgxyz);
+ }
+ else
+ {
+ if (_opmix < 0.0f) _opmix = 0.0f;
+ if (_opmix > 1.0f) _opmix = 1.0f;
+ t0 = (1 - _opmix) * (1 + _opmix);
+ t1 = 0.7f * _opmix * (2 - _opmix) / sqrtf (_rtmid);
+ }
+ _d0 = (t0 - _g0) / nfram;
+ _d1 = (t1 - _g1) / nfram;
+ _cntC2 = c;
+ }
+
+ _pareq1.prepare (nfram);
+ _pareq2.prepare (nfram);
+}
+
+
+void Zreverb::process (int nfram, float *inp [], float *out [])
+{
+ int i, n;
+ float *p0, *p1;
+ float *q0, *q1, *q2, *q3;
+ float t, g, x0, x1, x2, x3, x4, x5, x6, x7;
+
+ g = sqrtf (0.125f);
+
+ p0 = inp [0];
+ p1 = inp [1];
+ q0 = out [0];
+ q1 = out [1];
+ q2 = out [2];
+ q3 = out [3];
+
+ for (i = 0; i < nfram; i++)
+ {
+ _vdelay0.write (p0 [i]);
+ _vdelay1.write (p1 [i]);
+
+ t = 0.3f * _vdelay0.read1 ();
+ x0 = _diff1 [0].process (_delay [0].read () + t);
+ x1 = _diff1 [1].process (_delay [1].read () + t);
+ x2 = _diff1 [2].process (_delay [2].read () - t);
+ x3 = _diff1 [3].process (_delay [3].read () - t);
+ t = 0.3f * _vdelay1.read1 ();
+ x4 = _diff1 [4].process (_delay [4].read () + t);
+ x5 = _diff1 [5].process (_delay [5].read () + t);
+ x6 = _diff1 [6].process (_delay [6].read () - t);
+ x7 = _diff1 [7].process (_delay [7].read () - t);
+
+ t = x0 - x1; x0 += x1; x1 = t;
+ t = x2 - x3; x2 += x3; x3 = t;
+ t = x4 - x5; x4 += x5; x5 = t;
+ t = x6 - x7; x6 += x7; x7 = t;
+ t = x0 - x2; x0 += x2; x2 = t;
+ t = x1 - x3; x1 += x3; x3 = t;
+ t = x4 - x6; x4 += x6; x6 = t;
+ t = x5 - x7; x5 += x7; x7 = t;
+ t = x0 - x4; x0 += x4; x4 = t;
+ t = x1 - x5; x1 += x5; x5 = t;
+ t = x2 - x6; x2 += x6; x6 = t;
+ t = x3 - x7; x3 += x7; x7 = t;
+
+ if (_ambis)
+ {
+ _g0 += _d0;
+ _g1 += _d1;
+ q0 [i] = _g0 * x0;
+ q1 [i] = _g1 * x1;
+ q2 [i] = _g1 * x4;
+ q3 [i] = _g1 * x2;
+ }
+ else
+ {
+ _g1 += _d1;
+ q0 [i] = _g1 * (x1 + x2);
+ q1 [i] = _g1 * (x1 - x2);
+ }
+
+ _delay [0].write (_filt1 [0].process (g * x0));
+ _delay [1].write (_filt1 [1].process (g * x1));
+ _delay [2].write (_filt1 [2].process (g * x2));
+ _delay [3].write (_filt1 [3].process (g * x3));
+ _delay [4].write (_filt1 [4].process (g * x4));
+ _delay [5].write (_filt1 [5].process (g * x5));
+ _delay [6].write (_filt1 [6].process (g * x6));
+ _delay [7].write (_filt1 [7].process (g * x7));
+ }
+
+ n = _ambis ? 4 : 2;
+ _pareq1.process (nfram, n, out);
+ _pareq2.process (nfram, n, out);
+ if (!_ambis)
+ {
+ for (i = 0; i < nfram; i++)
+ {
+ _g0 += _d0;
+ q0 [i] += _g0 * _vdelay0.read0 ();
+ q1 [i] += _g0 * _vdelay1.read0 ();
+ }
+ }
+}
+
+
+// -----------------------------------------------------------------------
+
diff --git a/src/zreverb.h b/src/zreverb.h
new file mode 100644
index 0000000..2f9b905
--- /dev/null
+++ b/src/zreverb.h
@@ -0,0 +1,244 @@
+// -----------------------------------------------------------------------
+//
+// Copyright (C) 2003-2013 Fons Adriaensen <fons@linuxaudio.org>
+//
+// 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 2 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+//
+// -----------------------------------------------------------------------
+
+
+#ifndef __ZREVERB_H
+#define __ZREVERB_H
+
+#include "pareq.h"
+
+
+// -----------------------------------------------------------------------
+
+
+class Diff1
+{
+private:
+
+ friend class Zreverb;
+
+ Diff1 (void);
+ ~Diff1 (void);
+
+ void init (int size, float c);
+ void fini (void);
+ void reset (void);
+
+ float process (float x)
+ {
+ float z = _line [_i];
+ x -= _c * z;
+ _line [_i] = x;
+ if (++_i == _size) _i = 0;
+ return z + _c * x;
+ }
+
+ int _i;
+ float _c;
+ int _size;
+ float *_line;
+};
+
+
+// -----------------------------------------------------------------------
+
+
+class Filt1
+{
+private:
+
+ friend class Zreverb;
+
+ Filt1 (void) : _slo (0), _shi (0) {}
+ ~Filt1 (void) {}
+
+ void set_params (float del, float tmf, float tlo, float wlo, float thi, float chi);
+
+ float process (float x)
+ {
+ _slo += _wlo * (x - _slo) + 1e-10f;
+ x += _glo * _slo;
+ _shi += _whi * (x - _shi);
+ return _gmf * _shi;
+ }
+
+ void reset (void)
+ {
+ _slo = 0;
+ _shi = 0;
+ }
+
+ float _gmf;
+ float _glo;
+ float _wlo;
+ float _whi;
+ float _slo;
+ float _shi;
+};
+
+
+
+
+// -----------------------------------------------------------------------
+
+
+class Delay
+{
+private:
+
+ friend class Zreverb;
+
+ Delay (void);
+ ~Delay (void);
+
+ void init (int size);
+ void fini (void);
+ void reset (void);
+
+ float read (void)
+ {
+ return _line [_i];
+ }
+
+ void write (float x)
+ {
+ _line [_i++] = x;
+ if (_i == _size) _i = 0;
+ }
+
+ int _i;
+ int _size;
+ float *_line;
+};
+
+
+// -----------------------------------------------------------------------
+
+
+class Vdelay
+{
+private:
+
+ friend class Zreverb;
+
+ Vdelay (void);
+ ~Vdelay (void);
+
+ void init (int size);
+ void fini (void);
+ void reset (void);
+ void set_delay (int del);
+
+ void write (float x)
+ {
+ _line [_iwr++] = x;
+ if (_iwr == _size) _iwr = 0;
+ }
+
+ float read0 (void)
+ {
+ float x = _line [_ir0++];
+ if (_ir0 == _size) _ir0 = 0;
+ return x;
+ }
+
+ float read1 (void)
+ {
+ float x = _line [_ir1++];
+ if (_ir1 == _size) _ir1 = 0;
+ return x;
+ }
+
+ int _iwr;
+ int _ir0;
+ int _ir1;
+ int _size;
+ float *_line;
+};
+
+
+// -----------------------------------------------------------------------
+
+
+class Zreverb
+{
+public:
+
+ Zreverb (void);
+ ~Zreverb (void);
+
+ void init (float fsamp, bool ambis);
+ void fini (void);
+
+ void reset (void);
+ void prepare (int n);
+ void process (int n, float *inp [], float *out []);
+
+ void set_delay (float v) { _ipdel = v; _cntA1++; }
+ void set_xover (float v) { _xover = v; _cntB1++; }
+ void set_rtlow (float v) { _rtlow = v; _cntB1++; }
+ void set_rtmid (float v) { _rtmid = v; _cntB1++; _cntC1++; }
+ void set_fdamp (float v) { _fdamp = v; _cntB1++; }
+ void set_opmix (float v) { _opmix = v; _cntC1++; }
+ void set_rgxyz (float v) { _rgxyz = v; _cntC1++; }
+ void set_eq1 (float f, float g) { _pareq1.setparam (f, g); }
+ void set_eq2 (float f, float g) { _pareq2.setparam (f, g); }
+
+private:
+
+
+ float _fsamp;
+ bool _ambis;
+
+ Vdelay _vdelay0;
+ Vdelay _vdelay1;
+ Diff1 _diff1 [8];
+ Filt1 _filt1 [8];
+ Delay _delay [8];
+
+ volatile int _cntA1;
+ volatile int _cntB1;
+ volatile int _cntC1;
+ int _cntA2;
+ int _cntB2;
+ int _cntC2;
+ float _ipdel;
+ float _xover;
+ float _rtlow;
+ float _rtmid;
+ float _fdamp;
+ float _opmix;
+ float _rgxyz;
+
+ float _g0, _d0;
+ float _g1, _d1;
+
+ Pareq _pareq1;
+ Pareq _pareq2;
+
+ static float _tdiff1 [8];
+ static float _tdelay [8];
+};
+
+
+// -----------------------------------------------------------------------
+
+
+#endif