aboutsummaryrefslogtreecommitdiffstats
path: root/src/autowah.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/autowah.cc')
-rw-r--r--src/autowah.cc130
1 files changed, 130 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;
+}
+