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