1 /*
2 Copyright (C) 2003 Fons Adriaensen
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 "blvco.h"
21 #include "exp2ap.h"
22
23 #include <cmath>
24 #include <cstring>
25
26
27 static float _pulse [] =
28 {
29 0.000000, 0.000366, 0.001458, 0.003117, 0.005028, 0.006756, 0.007806, 0.007704,
30 0.006086, 0.002778, -0.002139, -0.008292, -0.015022, -0.021434, -0.026492, -0.029153,
31 -0.028511, -0.023957, -0.015297, -0.002869, 0.012417, 0.029105, 0.045302, 0.058853,
32 0.067578, 0.069533, 0.063273, 0.048113, 0.024337, -0.006682, -0.042487, -0.079654,
33 -0.114036, -0.141088, -0.156243, -0.155364, -0.135210, -0.093843, -0.030932, 0.052092,
34 0.152049, 0.264172, 0.382359, 0.499585, 0.608450, 0.701808, 0.773391, 0.818353,
35 0.833670, 0.818353, 0.773391, 0.701808, 0.608450, 0.499585, 0.382359, 0.264172,
36 0.152049, 0.052092, -0.030932, -0.093843, -0.135210, -0.155364, -0.156243, -0.141088,
37 -0.114036, -0.079654, -0.042487, -0.006682, 0.024337, 0.048113, 0.063273, 0.069533,
38 0.067578, 0.058853, 0.045302, 0.029105, 0.012417, -0.002869, -0.015297, -0.023957,
39 -0.028511, -0.029153, -0.026492, -0.021434, -0.015022, -0.008292, -0.002139, 0.002778,
40 0.006086, 0.007704, 0.007806, 0.006756, 0.005028, 0.003117, 0.001458, 0.000366,
41 0.000000
42 };
43
44
45 static const float lg2midc = log2f(261.63f);
46
47
setport(PortIndex port,PortData * data)48 void Ladspa_VCO_pulse1::setport (PortIndex port, PortData *data)
49 {
50 _port [port] = (float*)data;
51 }
52
53
active(bool act)54 void Ladspa_VCO_pulse1::active (bool act)
55 {
56 _p = 0.5;
57 _w = _y = _z = 0;
58 _j = 0;
59 memset (_f, 0, (FILLEN + NCOEFF) * sizeof (float));
60 }
61
62
runproc(SampleCount len,bool add)63 void Ladspa_VCO_pulse1::runproc (SampleCount len, bool add)
64 {
65 int i, j, n;
66 float *outp, *freq, *expm, *linm;
67 float a, p, r, t, w, dw, y, z, *f;
68
69 outp = _port[OUTP];
70 freq = _port[FREQ] - 1;
71 expm = _port[EXPM] - 1;
72 linm = _port[LINM] - 1;
73
74 p = _p;
75 w = _w;
76 y = _y;
77 z = _z;
78 j = _j;
79
80 a = 0.2 + 0.8 * _port [FILT][0];
81 do
82 {
83 n = (len > 24) ? 16 : len;
84 freq += n;
85 expm += n;
86 linm += n;
87 len -= n;
88
89 t = (exp2ap (log2f(*freq) - lg2midc + _port[OCTN][0] + _port[TUNE][0] + *expm * _port[EXPG][0] + 8.03136)
90 + 1e3 * *linm * _port[LING][0]) / _fsam;
91 if (t < 1e-5) t = 1e-5;
92 if (t > 0.5) t = 0.5;
93 dw = (t - w) / n;
94
95 while (n--)
96 {
97 w += dw;
98 p += w;
99 if (p >= 1.0)
100 {
101 p -= 1.0;
102 r = NPHASE * p / w;
103 i = (int) r;
104 r -= i;
105 f = _f + j;
106 while (i < NPHASE * NCOEFF)
107 {
108 *f++ += r * _pulse [i + 1 ] + (1 - r) * _pulse [i];
109 i += NPHASE;
110 }
111 }
112
113 y = _f [j];
114 z += a * (y - z);
115 *outp++ = z;
116 if (++j == FILLEN)
117 {
118 j = 0;
119 memcpy (_f, _f + FILLEN, NCOEFF * sizeof (float));
120 memset (_f + NCOEFF, 0, FILLEN * sizeof (float));
121 }
122 }
123 }
124 while (len);
125
126 _p = p;
127 _w = w;
128 _y = y;
129 _z = z;
130 _j = j;
131 }
132
133
134
setport(PortIndex port,PortData * data)135 void Ladspa_VCO_saw1::setport (PortIndex port, PortData *data)
136 {
137 _port [port] = (float*)data;
138 }
139
140
active(bool act)141 void Ladspa_VCO_saw1::active (bool act)
142 {
143 _p = 0.5;
144 _w = _x = _y = _z = _d = 0;
145 _j = 0;
146 memset (_f, 0, (FILLEN + NCOEFF) * sizeof (float));
147 }
148
149
runproc(SampleCount len,bool add)150 void Ladspa_VCO_saw1::runproc (SampleCount len, bool add)
151 {
152 int i, j, n;
153 float *outp, *freq, *expm, *linm, *sync;
154 float a, d, p, r, t, w, dw, x, y, z, *f;
155
156 outp = _port[OUTP];
157 freq = _port[FREQ] - 1;
158 expm = _port[EXPM] - 1;
159 linm = _port[LINM] - 1;
160 sync = _port[SYNC];
161
162 p = _p;
163 w = _w;
164 x = _x;
165 y = _y;
166 z = _z;
167 d = _d;
168 j = _j;
169
170 a = 0.2 + 0.8 * _port [FILT][0];
171 do
172 {
173 n = (len > 24) ? 16 : len;
174 freq += n;
175 expm += n;
176 linm += n;
177 len -= n;
178
179 t = (exp2ap (log2f(*freq) - lg2midc + _port[OCTN][0] + _port[TUNE][0] + *expm * _port[EXPG][0] + 8.03136 + d)
180 + 1e3 * *linm * _port[LING][0]) / _fsam;
181 if (t < 1e-5) t = 1e-5;
182 if (t > 0.5) t = 0.5;
183 dw = (t - w) / n;
184
185 while (n--)
186 {
187 w += dw;
188 p += w;
189 if (p >= 1.0)
190 {
191 p -= 1.0;
192 r = NPHASE * p / w;
193 i = (int) r;
194 r -= i;
195 f = _f + j;
196 while (i < NPHASE * NCOEFF)
197 {
198 *f++ += r * _pulse [i + 1 ] + (1 - r) * _pulse [i];
199 i += NPHASE;
200 }
201 }
202
203 x += _f [j] - w * (0.01 * y + 0.2 * x + 1);
204 y += 6.3 * w * x;
205 z += a * (x - z);
206 *outp++ = z;
207 d += 0.01 * (y * *sync++ - d);
208 if (++j == FILLEN)
209 {
210 j = 0;
211 memcpy (_f, _f + FILLEN, NCOEFF * sizeof (float));
212 memset (_f + NCOEFF, 0, FILLEN * sizeof (float));
213 }
214 }
215 }
216 while (len);
217
218 _p = p;
219 _w = w;
220 _x = x;
221 _y = y;
222 _z = z;
223 _d = d;
224 _j = j;
225 }
226
227
228
setport(PortIndex port,PortData * data)229 void Ladspa_VCO_rec1::setport (PortIndex port, PortData *data)
230 {
231 _port [port] = (float*)data;
232 }
233
234
active(bool act)235 void Ladspa_VCO_rec1::active (bool act)
236 {
237 _p = 0.0;
238 _x = _y = _z = _d = 0;
239 _w = 0;
240 _b = 0.5;
241 _j = _k = 0;
242 memset (_f, 0, (FILLEN + NCOEFF) * sizeof (float));
243 }
244
245
runproc(SampleCount len,bool add)246 void Ladspa_VCO_rec1::runproc (SampleCount len, bool add)
247 {
248 int i, j, k, n;
249 float *outp, *freq, *expm, *linm, *wavm, *sync;
250 float a, b, db, d, p, r, t, w, dw, x, y, z, *f;
251
252 outp = _port[OUTP];
253 freq = _port[FREQ] - 1;
254 expm = _port[EXPM] - 1;
255 linm = _port[LINM] - 1;
256 wavm = _port[WAVM] - 1;
257 sync = _port[SYNC];
258
259 p = _p;
260 w = _w;
261 b = _b;
262 x = _x;
263 y = _y;
264 z = _z;
265 d = _d;
266 j = _j;
267 k = _k;
268
269 a = 0.2 + 0.8 * _port [FILT][0];
270 do
271 {
272 n = (len > 24) ? 16 : len;
273 freq += n;
274 expm += n;
275 linm += n;
276 wavm += n;
277 len -= n;
278
279 t = (exp2ap (log2f(*freq) - lg2midc + _port[OCTN][0] + _port[TUNE][0] + *expm * _port[EXPG][0] + 8.03136 + d)
280 + 1e3 * *linm * _port[LING][0]) / _fsam;
281 if (t < 1e-5) t = 1e-5;
282 if (t > 0.5) t = 0.5;
283 dw = (t - w) / n;
284 t = 0.5 * (1.0 + _port [WAVE][0] + *wavm * _port [WMOD][0]);
285 if (t < 0.02) t = 0.02;
286 if (t > 0.98) t = 0.98;
287 db = (t - b) / n;
288
289 while (n--)
290 {
291 w += dw;
292 b += db;
293 p += w;
294 t = k ? 1.0 : b;
295 while (p >= t)
296 {
297 if (k)
298 {
299 k = 0;
300 p -= 1.0;
301 r = NPHASE * p / w;
302 t = b;
303 i = (int) r;
304 r -= i;
305 f = _f + j;
306 while (i < NPHASE * NCOEFF)
307 {
308 *f++ += r * _pulse [i + 1 ] + (1 - r) * _pulse [i];
309 i += NPHASE;
310 }
311 }
312 else
313 {
314 k = 1;
315 r = NPHASE * (p - t) / w;
316 t = 1.0;
317 i = (int) r;
318 r -= i;
319 f = _f + j;
320 while (i < NPHASE * NCOEFF)
321 {
322 *f++ -= r * _pulse [i + 1 ] + (1 - r) * _pulse [i];
323 i += NPHASE;
324 }
325 }
326 }
327 x -= w * (0.01 * y + 0.2 * x);
328 x += _f [j];
329 y += 6.3 * w * x;
330 z += a * (x - z);
331 *outp++ = z;
332 d += 0.01 * (y * *sync++ - d);
333 if (++j == FILLEN)
334 {
335 j = 0;
336 memcpy (_f, _f + FILLEN, NCOEFF * sizeof (float));
337 memset (_f + NCOEFF, 0, FILLEN * sizeof (float));
338 }
339 }
340 }
341 while (len);
342
343 _p = p;
344 _w = w;
345 _b = b;
346 _x = x;
347 _y = y;
348 _z = z;
349 _d = d;
350 _j = j;
351 _k = k;
352 }
353