1 /*
2     Copyright (C) 2003-2008 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 #include "rankwave.h"
20 
21 #define DEBUG
22 
23 extern float exp2ap (float);
24 
25 
26 Rngen   Pipewave::_rgen;
27 float  *Pipewave::_arg = 0;
28 float  *Pipewave::_att = 0;
29 
initstatic(float fsamp)30 void Pipewave::initstatic(float fsamp)
31       {
32       if (_arg)
33             return;
34       int k = (int)(fsamp);
35       _arg  = new float [k];
36       k     = (int)(0.5f * fsamp);
37       _att  = new float [k];
38       }
39 
40 //---------------------------------------------------------
41 //   play
42 //---------------------------------------------------------
43 
play()44 void Pipewave::play()
45       {
46       int     i, d, k1, k2;
47       float   g, dg, y, dy, t;
48       float   *q;
49 
50       float* p = _p_p;
51       float* r = _p_r;
52 
53       if (_sdel & 1) {
54             if (!p) {
55                   p    = _p0;
56                   _y_p = 0.0f;
57                   _z_p = 0.0f;
58                   }
59             }
60       else
61     {
62         if (! r)
63 	{
64   	    r = p;
65             p = 0;
66             _g_r = 1.0f;
67             _y_r = _y_p;
68             _i_r = _k_r;
69 	}
70     }
71 
72     if (r)
73     {
74         k1 = PERIOD;
75         q = _out;
76 	g = _g_r;
77         i = _i_r - 1;
78         dg = g / PERIOD;
79         if (i) dg *= _m_r ;
80 
81         if (r < _p1)
82         {
83             while (k1--)
84             {
85 	        *q++ += g * *r++;
86                 g -= dg;
87             }
88         }
89         else
90 	{
91             y = _y_r;
92             dy = _d_r;
93             while (k1)
94 	    {
95                 t = y + k1 * dy;
96                 d = 0;
97                 k2 = k1;
98                 if (t > 1.0f)
99 	        {
100 		    d = 1;
101                     k2 = (int)((1.0f - y) / dy);
102                 }
103                 else if (t < 0.0f)
104 	        {
105 		    d = -1;
106                     k2 = (int)(-y / dy);
107 	        }
108                 k1 -= k2;
109                 if (k2<0)
110                   k2 = 0;
111                 while (k2--)
112        	        {
113                     *q++ += g * (r [0] + y * (r [1] - r [0]));
114                     g -= dg;
115                     y += dy;
116                     r += _k_s;
117 	        }
118                 y -= d;
119                 r += d;
120 	    }
121             _y_r = y;
122 	}
123 
124         if (i)
125 	{
126 	    _g_r = g;
127             _i_r = i;
128             if (r >= _p2) r -= _l1;
129 	}
130         else r = 0;
131     }
132 
133     if (p)
134     {
135         k1 = PERIOD;
136         q = _out;
137         if (p < _p1)
138         {
139             while (k1--)
140             {
141 		*q++ += *p++;
142 	    }
143         }
144         else
145 	{
146             y = _y_p;
147             _z_p += _d_p * 0.0005f * (0.05f * _d_p * (_rgen.urandf () - 0.5f) - _z_p);
148             dy = _z_p * _k_s;
149             while (k1)
150 	    {
151                 t = y + k1 * dy;
152                 d = 0;
153                 k2 = k1;
154                 if (t > 1.0f)
155 	        {
156 		    d = 1;
157                     k2 = (int)((1.0f - y) / dy);
158                 }
159                 else if (t < 0.0f)
160 	        {
161 		    d = -1;
162                     k2 = (int)(-y / dy);
163 	        }
164                 k1 -= k2;
165                 if (k2<0)
166                   k2 = 0;
167                 while (k2--)
168        	        {
169                     *q++ += p [0] + y * (p [1] - p [0]);
170                     y += dy;
171                     p += _k_s;
172 	        }
173                 y -= d;
174                 p += d;
175 	    }
176             if (p >= _p2) p -= _l1;
177             _y_p = y;
178 	}
179     }
180 
181     _p_p = p;
182     _p_r = r;
183 }
184 
185 
genwave(Addsynth * D,int n,float fsamp,float fpipe)186 void Pipewave::genwave (Addsynth *D, int n, float fsamp, float fpipe)
187 {
188     int    h, i, k, nc;
189     float  f0, f1, f, m, t, v, v0;
190 
191     m = D->_n_att.vi (n);
192     for (h = 0; h < N_HARM; h++)
193     {
194 	t = D->_h_att.vi (h, n);
195         if (t > m) m = t;
196     }
197     _l0 = (int)(fsamp * m + 0.5);
198     _l0 = (_l0 + PERIOD - 1) & ~(PERIOD - 1);
199 
200     f1 = (fpipe + D->_n_off.vi (n) + D->_n_ran.vi (n) * (2 * _rgen.urand () - 1)) / fsamp;
201     f0 = f1 * exp2ap (D->_n_atd.vi (n) / 1200.0f);
202 
203     for (h = N_HARM - 1; h >= 0; h--)
204     {
205         f = (h + 1) * f1;
206 	if ((f < 0.45f) && (D->_h_lev.vi (h, n) >= -40.0f)) break;
207     }
208     if      (f > 0.250f) _k_s = 3;
209     else if (f > 0.125f) _k_s = 2;
210     else                 _k_s = 1;
211 
212     looplen (f1 * fsamp, _k_s * fsamp, (int)(fsamp / 6.0f), &_l1, &nc);
213     if (_l1 < _k_s * PERIOD)
214     {
215         k = (_k_s * PERIOD - 1) / _l1 + 1;
216         _l1 *= k;
217         nc *= k;
218     }
219 
220     k = _l0 + _l1 + _k_s * (PERIOD + 4);
221 
222     delete[] _p0;
223     _p0 = new float [k];
224     _p1 = _p0 + _l0;
225     _p2 = _p1 + _l1;
226     memset (_p0, 0, k * sizeof (float));
227 
228     _k_r = (int)(ceilf (D->_n_dct.vi (n) * fsamp / PERIOD) + 1);
229     _m_r = 1.0f - powf (0.1, 1.0 / _k_r);
230     _d_r = _k_s * (exp2ap (D->_n_dcd.vi (n) / 1200.0f) - 1.0f);
231     _d_p = D->_n_ins.vi (n);
232 
233     t = 0.0f;
234     k = (int)(fsamp * D->_n_att.vi (n) + 0.5);
235     for (i = 0; i <= _l0; i++)
236     {
237         _arg [i] = t - floorf (t + 0.5);
238 	t += (i < k) ? (((k - i) * f0 + i * f1) / k) : f1;
239     }
240 
241     for (i = 1; i < _l1; i++)
242     {
243 	t = _arg [_l0]+ (float) i * nc / _l1;
244         _arg [i + _l0] = t - floorf (t + 0.5);
245     }
246 
247     v0 = exp2ap (0.1661 * D->_n_vol.vi (n));
248     for (h = 0; h < N_HARM; h++)
249     {
250         if ((h + 1) * f1 > 0.45) break;
251         v = D->_h_lev.vi (h, n);
252         if (v < -80.0) continue;
253 
254         v = v0 * exp2ap (0.1661 * (v + D->_h_ran.vi (h, n) * (2 * _rgen.urand () - 1)));
255         k = (int)(fsamp * D->_h_att.vi (h, n) + 0.5);
256         attgain (k, D->_h_atp.vi (h, n));
257 
258         for (i = 0; i < _l0 + _l1; i++)
259         {
260 	    t = _arg [i] * (h + 1);
261             t -= floorf (t);
262             m = v * sinf (2 * M_PI * t);
263             if (i < k) m *= _att [i];
264             _p0 [i] += m;
265         }
266     }
267     for (i = 0; i < _k_s * (PERIOD + 4); i++) _p0 [i + _l0 + _l1] = _p0 [i + _l0];
268 }
269 
270 
looplen(float f,float fsamp,int lmax,int * aa,int * bb)271 void Pipewave::looplen (float f, float fsamp, int lmax, int *aa, int *bb)
272 {
273     int     i, j, a, b, t;
274     int     z [8];
275     double  g, d;
276 
277     g = fsamp / f;
278     for (i = 0; i < 8; i++)
279     {
280 	a = z [i] = (int)(floor (g + 0.5));
281         g -= a;
282         b = 1;
283         j = i;
284         while (j > 0)
285 	{
286             t = a;
287   	    a = z [--j] * a + b;
288 	    b = t;
289 	}
290         if (a < 0)
291 	{
292 	    a = -a;
293             b = -b;
294 	}
295         if (a <= lmax)
296 	{
297 	    d = fsamp * b / a - f;
298 	    if ((fabs (d) < 0.1) && (fabs (d) < 3e-4 * f)) break;
299 	    g = (fabs (g) < 1e-6) ? 1e6 : 1.0 / g;
300 	}
301         else
302 	{
303 	    b = (int)(lmax * f / fsamp);
304             a = (int)(b * fsamp / f + 0.5);
305             d = fsamp * b / a - f;
306             break;
307 	}
308     }
309     *aa = a;
310     *bb = b;
311 }
312 
313 
attgain(int n,float p)314 void Pipewave::attgain (int n, float p)
315 {
316     int    i, j, k;
317     float  d, m, w, x, y, z;
318 
319     w = 0.05;
320     x = 0.0;
321     y = 0.6;
322     if (p > 0) y += 0.11 * p;
323     z = 0.0;
324     j = 0;
325     for (i = 1; i <= 24; i++)
326     {
327         k = n * i / 24;
328         x =  1.0 - z - 1.5 * y;
329         y += w * x;
330         d = w * y * p / (k - j);
331         while (j < k)
332 	{
333             m = (double) j / n;
334             _att [j++] = (1.0 - m) * z + m;
335             z += d;
336 	}
337     }
338 }
339 
340 
save(FILE * F)341 void Pipewave::save (FILE *F)
342 {
343     int  k;
344     union
345     {
346         int16_t i16 [16];
347         int32_t i32 [8];
348 	float   flt [8];
349     } d;
350 
351     d.i32 [0] = _l0;
352     d.i32 [1] = _l1;
353     d.i16 [4] = _k_s;
354     d.i16 [5] = _k_r;
355     d.flt [3] = _m_r;
356     d.i32 [4] = 0;
357     d.i32 [5] = 0;
358     d.i32 [6] = 0;
359     d.i32 [7] = 0;
360     fwrite (&d, 1, 32, F);
361     k = _l0 +_l1 + _k_s * (PERIOD + 4);
362     fwrite (_p0, k, sizeof (float), F);
363 }
364 
365 
load(FILE * F)366 void Pipewave::load (FILE *F)
367 {
368     int  k;
369     union
370     {
371         int16_t i16 [16];
372         int32_t i32 [8];
373 	float   flt [8];
374     } d;
375 
376     fread (&d, 1, 32, F);
377     _l0  = d.i32 [0];
378     _l1  = d.i32 [1];
379     _k_s = d.i16 [4];
380     _k_r = d.i16 [5];
381     _m_r = d.flt [3];
382     k = _l0 +_l1 + _k_s * (PERIOD + 4);
383     delete[] _p0;
384     _p0 = new float [k];
385     _p1 = _p0 + _l0;
386     _p2 = _p1 + _l1;
387     fread (_p0, k, sizeof (float), F);
388 }
389 
390 
391 
392 
Rankwave(int n0,int n1)393 Rankwave::Rankwave (int n0, int n1) : _n0 (n0), _n1 (n1), _list (0), _modif (false)
394 {
395     _pipes = new Pipewave [n1 - n0 + 1];
396 }
397 
398 
~Rankwave(void)399 Rankwave::~Rankwave (void)
400 {
401     delete[] _pipes;
402 }
403 
404 
gen_waves(Addsynth * D,float fsamp,float fbase,float * scale)405 void Rankwave::gen_waves (Addsynth *D, float fsamp, float fbase, float *scale)
406 {
407     Pipewave::initstatic (fsamp);
408 
409     fbase *=  D->_fn / (D->_fd * scale [9]);
410     for (int i = _n0; i <= _n1; i++)
411     {
412 	_pipes [i - _n0].genwave (D, i - _n0, fsamp, ldexpf (fbase * scale [i % 12], i / 12 - 5));
413     }
414     _modif = true;
415 }
416 
417 
set_param(float * out,int del,int pan)418 void Rankwave::set_param (float *out, int del, int pan)
419 {
420     int         n, a, b;
421     Pipewave   *P;
422 
423     _sbit = 1 << del;
424     switch (pan)
425     {
426     case 'L': a = 2, b = 0; break;
427     case 'C': a = 2, b = 1; break;
428     case 'R': a = 2, b = 2; break;
429     default:  a = 4, b = 0;
430     }
431     for (n = _n0, P = _pipes; n <= _n1; n++, P++) P->_out = out + ((n % a) + b) * PERIOD;
432 }
433 
434 
play(int shift)435 void Rankwave::play (int shift)
436 {
437     Pipewave *P, *Q;
438 
439     for (P = 0, Q = _list; Q; Q = Q->_link)
440     {
441 	Q->play ();
442         if (shift) Q->_sdel = (Q->_sdel >> 1) | Q->_sbit;
443         if (Q->_sdel || Q->_p_p || Q->_p_r) P = Q;
444         else
445 	{
446   	    if (P) P->_link = Q->_link;
447             else      _list = Q->_link;
448 	}
449     }
450 }
451 
452 
save(const char * path,Addsynth * D,float fsamp,float fbase,float * scale)453 int Rankwave::save (const char *path, Addsynth *D, float fsamp, float fbase, float *scale)
454 {
455     FILE      *F;
456     Pipewave  *P;
457     int        i;
458     char       name [1024];
459     char       data [64];
460     char      *p;
461 
462     sprintf (name, "%s/%s", path, D->_filename);
463     if ((p = strrchr (name, '.'))) strcpy (p, ".ae1");
464     else strcat (name, ".ae1");
465 
466     F = fopen (name, "wb");
467     if (F == NULL)
468     {
469 	fprintf (stderr, "Can't open waveform file '%s' for writing\n", name);
470         return 1;
471     }
472 
473     memset (data, 0, 16);
474     strcpy (data, "ae1");
475     data [4] = 1;
476     fwrite (data, 1, 16, F);
477 
478     memset (data, 0, 64);
479     data [0] = 0;
480     data [1] = 0;
481     data [2] = 0;
482     data [3] = 0;
483     data [4] = _n0;
484     data [5] = _n1;
485     data [6] = 0;
486     data [7] = 0;
487     *((float *)(data +  8)) = fsamp;
488     *((float *)(data + 12)) = fbase;
489     memcpy (data + 16, scale, 12 * sizeof (float));
490     fwrite (data, 1, 64, F);
491 
492     for (i = _n0, P = _pipes; i <= _n1; i++, P++) P->save (F);
493 
494     fclose (F);
495 
496     _modif = false;
497     return 0;
498 }
499 
500 
load(const char * path,Addsynth * D,float fsamp,float fbase,float * scale)501 int Rankwave::load (const char *path, Addsynth *D, float fsamp, float fbase, float *scale)
502 {
503     FILE      *F;
504     Pipewave  *P;
505     int        i;
506     char       name [1024];
507     char       data [64];
508     char      *p;
509     float      f;
510 
511     sprintf (name, "%s/%s", path, D->_filename);
512     if ((p = strrchr (name, '.'))) strcpy (p, ".ae1");
513     else strcat (name, ".ae1");
514 
515     F = fopen (name, "rb");
516     if (F == NULL)
517     {
518 #ifdef DEBUG
519 	fprintf (stderr, "Can't open waveform file '%s' for reading\n", name);
520 #endif
521         return 1;
522     }
523 
524     fread (data, 1, 16, F);
525     if (strcmp (data, "ae1"))
526     {
527 #ifdef DEBUG
528 	fprintf (stderr, "File '%s' is not an Aeolus waveform file\n", name);
529 #endif
530         fclose (F);
531         return 1;
532     }
533 
534     if (data [4] != 1)
535     {
536 #ifdef DEBUG
537 	fprintf (stderr, "File '%s' has an incompatible version tag (%d)\n", name, data [4]);
538 #endif
539         fclose (F);
540         return 1;
541     }
542 
543     fread (data, 1, 64, F);
544     if (_n0 != data [4] || _n1 != data [5])
545     {
546 #ifdef DEBUG
547 	fprintf (stderr, "File '%s' has an incompatible note range (%d %d), (%d %d)\n", name, _n0, _n1, data [4], data [5]);
548 #endif
549         fclose (F);
550         return 1;
551     }
552 
553     f = *((float *)(data + 8));
554     if (fabsf (f - fsamp) > 0.1f)
555     {
556 #ifdef DEBUG
557 	fprintf (stderr, "File '%s' has a different sample frequency (%3.1lf)\n", name, f);
558 #endif
559         fclose (F);
560         return 1;
561     }
562 
563     f = *((float *)(data + 12));
564     if (fabsf (f - fbase) > 0.1f)
565     {
566 #ifdef DEBUG
567 	fprintf (stderr, "File '%s' has a different tuning (%3.1lf)\n", name, f);
568 #endif
569         fclose (F);
570         return 1;
571     }
572 
573     for (i = 0; i < 12; i++)
574     {
575         f = *((float *)(data + 16 + 4 * i));
576         if (fabsf (f /  scale [i] - 1.0f) > 6e-5f)
577         {
578 #ifdef DEBUG
579 	    fprintf (stderr, "File '%s' has a different temperament\n", name);
580 #endif
581             fclose (F);
582             return 1;
583         }
584     }
585 
586     for (i = _n0, P = _pipes; i <= _n1; i++, P++) P->load (F);
587 
588     fclose (F);
589 
590     _modif = false;
591     return 0;
592 }
593