1 /*
2 Copyright (C) 2009 Fons Adriaensen <fons@kokkinizita.net>
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
8
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
13
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17 */
18
19
20 #include "autowah.h"
21
22 #include <cmath>
23
24
setport(PortIndex port,PortData * data)25 void Ladspa_Autowah::setport (PortIndex port, PortData *data)
26 {
27 _port [port] = (float*)data;
28 }
29
30
31 #define G_RES 4.0f
32 #define F_MIN 300.0f
33 #define F_RAT 10
34 #define B_MIN 0.03f
35 #define B_RAT 4
36 #define T_MIN 0.05f
37 #define T_LOG 2
38
39
active(bool act)40 void Ladspa_Autowah::active (bool act)
41 {
42 if (! act) return;
43
44 _wbase = F_MIN * 6.28f / _fsam;
45 _bbase = B_MIN;
46 _rfact = 64.0f / (_fsam * T_MIN);
47 _z1 = _z2 = 0;
48 _s1 = _s2 = 0;
49 _gx = _gy = 0;
50 _dr = 0;
51 }
52
53
runproc(SampleCount len,bool add)54 void Ladspa_Autowah::runproc (SampleCount len, bool add)
55 {
56 int i, k;
57 float *inp = _port [A_INP];
58 float *out = _port [A_OUT];
59 float z1, z2, s1, s2, gx, gy;
60 float ds1, ds2, dgx, dgy;
61 float gd, rf, md, fr, dr;
62 float b, p, t, w, x, y;
63
64 gx = _gx;
65 gy = _gy;
66 t = _port [C_OPMIX][0];
67 _gy = G_RES * t;
68 _gx = _gy + 1 - t;
69 dgx = (_gx - gx) / len;
70 dgy = (_gy - gy) / len;
71
72 gd = 10 * powf (10.0f, 0.05f * _port [C_DRIVE][0]);
73 rf = 1.0f - _rfact / powf (10.0f, T_LOG * _port [C_DECAY][0]);
74 md = _port [C_RANGE][0];
75 fr = _port [C_FREQ][0];
76
77 z1 = _z1;
78 z2 = _z2;
79 s1 = _s1;
80 s2 = _s2;
81 dr = _dr;
82
83 while (len)
84 {
85 k = (len > 80) ? 64 : len;
86
87 p = 0;
88 for (i = 0; i < k; i++)
89 {
90 x = inp [i];
91 p += x * x;
92 }
93 p = gd * sqrtf (p / k);
94
95 if (p > dr) dr += 0.1f *(p - dr);
96 if (dr > md) dr = md;
97 t = dr + fr;
98 dr = dr * rf + 1e-10f;
99 w = _wbase * (1 + (F_RAT - 1) * t * t);
100 b = w * _bbase * (1 + (B_RAT - 1) * t);
101 if (w > 0.7f) w = 0.7f;
102
103 _s1 = -cosf (w);
104 _s2 = (1 - b) / (1 + b);
105 ds1 = (_s1 - s1) / k;
106 ds2 = (_s2 - s2) / k;
107
108 for (i = 0; i < k; i++)
109 {
110 s1 += ds1;
111 s2 += ds2;
112 gx += dgx;
113 gy += dgy;
114 x = inp [i];
115 y = x - s2 * z2;
116 out [i] = gx * x - gy * (z2 + s2 * y);
117 y -= s1 * z1;
118 z2 = z1 + s1 * y;
119 z1 = y + 1e-10f;
120 }
121 inp += k;
122 out += k;
123 len -= k;
124 }
125
126 _z1 = z1;
127 _z2 = z2;
128 _dr = dr;
129 }
130
131