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