aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2012-08-20 05:16:04 +0000
committerDavid Robillard <d@drobilla.net>2012-08-20 05:16:04 +0000
commit734a9f490f2f8cb4552c71bfac8fc779f836c436 (patch)
tree34d286b3e8cbd291267ebe3ae6804ba52959c68b /src
downloadfomp.lv2-734a9f490f2f8cb4552c71bfac8fc779f836c436.tar.gz
fomp.lv2-734a9f490f2f8cb4552c71bfac8fc779f836c436.tar.bz2
fomp.lv2-734a9f490f2f8cb4552c71bfac8fc779f836c436.zip
Add fomp.lv2, a port of Fons' modular-oriented LADSPA plugins to LV2.
git-svn-id: http://svn.drobilla.net/lad/trunk/plugins/fomp.lv2@4727 a436a847-0d15-0410-975c-d299462d15a1
Diffstat (limited to 'src')
-rw-r--r--src/blvco.cc352
-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/ladspaplugin.h61
-rw-r--r--src/mvchpf24.cc123
-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.cc436
-rw-r--r--src/mvclpf24.h110
-rw-r--r--src/mvclpf24_if.cc299
-rw-r--r--src/mvclpf24_lv2.cc136
-rw-r--r--src/plugin_lv2.h55
22 files changed, 3480 insertions, 0 deletions
diff --git a/src/blvco.cc b/src/blvco.cc
new file mode 100644
index 0000000..8f1c65c
--- /dev/null
+++ b/src/blvco.cc
@@ -0,0 +1,352 @@
+/*
+ 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
+};
+
+
+
+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 (*freq + _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 (*freq + _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 (*freq + _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/ladspaplugin.h b/src/ladspaplugin.h
new file mode 100644
index 0000000..08de649
--- /dev/null
+++ b/src/ladspaplugin.h
@@ -0,0 +1,61 @@
+/*
+ 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) but the actual DSP code has only been changed to use the
+ typedef rather than 'hard' switching it to the new type. This way, it
+ should be straightforward to make the same code build as both LADSPA and LV2
+ plugins, though since the upstream situation is unclear I have not done
+ done so. ~ David Robillard, Aug. 2012 */
+
+typedef unsigned long SampleRate;
+typedef unsigned long SampleCount;
+typedef unsigned long 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..d63155b
--- /dev/null
+++ b/src/mvchpf24.cc
@@ -0,0 +1,123 @@
+/*
+ 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"
+
+
+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 + _port [CFREQ][0] + 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..ae0a287
--- /dev/null
+++ b/src/mvclpf24.cc
@@ -0,0 +1,436 @@
+/*
+ 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"
+
+
+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 + _port [C_FREQ][0] + *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 + _port [C_FREQ][0] + *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 + _port [C_FREQ][0] + *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 + _port [C_FREQ][0] + *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..1c36a54
--- /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_Moogvcf1(rate);
+}
+static LV2_Handle
+instantiate3(const LV2_Descriptor* descriptor,
+ double rate,
+ const char* bundle_path,
+ const LV2_Feature* const* features)
+{
+ return new Ladspa_Moogvcf1(rate);
+}
+static LV2_Handle
+instantiate4(const LV2_Descriptor* descriptor,
+ double rate,
+ const char* bundle_path,
+ const LV2_Feature* const* features)
+{
+ return new Ladspa_Moogvcf1(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/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"