Update Fluidsynth to v2.0.2
[ardour.git] / libs / fluidsynth / src / fluid_chorus.c
1 /* FluidSynth - A Software Synthesizer
2  *
3  * Copyright (C) 2003  Peter Hanappe, Markus Nentwig and others.
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public License
7  * as published by the Free Software Foundation; either version 2.1 of
8  * the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free
17  * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
18  * 02110-1301, USA
19  */
20
21 /*
22   based on a chrous implementation made by Juergen Mueller And Sundry Contributors in 1998
23
24   CHANGES
25
26   - Adapted for fluidsynth, Peter Hanappe, March 2002
27
28   - Variable delay line implementation using bandlimited
29     interpolation, code reorganization: Markus Nentwig May 2002
30
31  */
32
33
34 /*
35  *      Chorus effect.
36  *
37  * Flow diagram scheme for n delays ( 1 <= n <= MAX_CHORUS ):
38  *
39  *        * gain-in                                           ___
40  * ibuff -----+--------------------------------------------->|   |
41  *            |      _________                               |   |
42  *            |     |         |                   * level 1  |   |
43  *            +---->| delay 1 |----------------------------->|   |
44  *            |     |_________|                              |   |
45  *            |        /|\                                   |   |
46  *            :         |                                    |   |
47  *            : +-----------------+   +--------------+       | + |
48  *            : | Delay control 1 |<--| mod. speed 1 |       |   |
49  *            : +-----------------+   +--------------+       |   |
50  *            |      _________                               |   |
51  *            |     |         |                   * level n  |   |
52  *            +---->| delay n |----------------------------->|   |
53  *                  |_________|                              |   |
54  *                     /|\                                   |___|
55  *                      |                                      |
56  *              +-----------------+   +--------------+         | * gain-out
57  *              | Delay control n |<--| mod. speed n |         |
58  *              +-----------------+   +--------------+         +----->obuff
59  *
60  *
61  * The delay i is controlled by a sine or triangle modulation i ( 1 <= i <= n).
62  *
63  * The delay of each block is modulated between 0..depth ms
64  *
65  */
66
67
68 /* Variable delay line implementation
69  * ==================================
70  *
71  * The modulated delay needs the value of the delayed signal between
72  * samples.  A lowpass filter is used to obtain intermediate values
73  * between samples (bandlimited interpolation).  The sample pulse
74  * train is convoluted with the impulse response of the low pass
75  * filter (sinc function).  To make it work with a small number of
76  * samples, the sinc function is windowed (Hamming window).
77  *
78  */
79
80 #include "fluid_chorus.h"
81 #include "fluid_sys.h"
82
83 #define MAX_CHORUS      99
84 #define MAX_DELAY       100
85 #define MAX_DEPTH       10
86 #define MIN_SPEED_HZ    0.29
87 #define MAX_SPEED_HZ    5
88
89 /* Length of one delay line in samples:
90  * Set through MAX_SAMPLES_LN2.
91  * For example:
92  * MAX_SAMPLES_LN2=12
93  * => MAX_SAMPLES=pow(2,12-1)=2048
94  * => MAX_SAMPLES_ANDMASK=2047
95  */
96 #define MAX_SAMPLES_LN2 12
97
98 #define MAX_SAMPLES (1 << (MAX_SAMPLES_LN2-1))
99 #define MAX_SAMPLES_ANDMASK (MAX_SAMPLES-1)
100
101
102 /* Interpolate how many steps between samples? Must be power of two
103    For example: 8 => use a resolution of 256 steps between any two
104    samples
105 */
106 #define INTERPOLATION_SUBSAMPLES_LN2 8
107 #define INTERPOLATION_SUBSAMPLES (1 << (INTERPOLATION_SUBSAMPLES_LN2-1))
108 #define INTERPOLATION_SUBSAMPLES_ANDMASK (INTERPOLATION_SUBSAMPLES-1)
109
110 /* Use how many samples for interpolation? Must be odd.  '7' sounds
111    relatively clean, when listening to the modulated delay signal
112    alone.  For a demo on aliasing try '1' With '3', the aliasing is
113    still quite pronounced for some input frequencies
114 */
115 #define INTERPOLATION_SAMPLES 5
116
117 /* Private data for SKEL file */
118 struct _fluid_chorus_t
119 {
120     int type;
121     fluid_real_t depth_ms;
122     fluid_real_t level;
123     fluid_real_t speed_Hz;
124     int number_blocks;
125
126     fluid_real_t *chorusbuf;
127     int counter;
128     long phase[MAX_CHORUS];
129     long modulation_period_samples;
130     int *lookup_tab;
131     fluid_real_t sample_rate;
132
133     /* sinc lookup table */
134     fluid_real_t sinc_table[INTERPOLATION_SAMPLES][INTERPOLATION_SUBSAMPLES];
135 };
136
137 static void fluid_chorus_triangle(int *buf, int len, int depth);
138 static void fluid_chorus_sine(int *buf, int len, int depth);
139
140
141 fluid_chorus_t *
142 new_fluid_chorus(fluid_real_t sample_rate)
143 {
144     int i;
145     int ii;
146     fluid_chorus_t *chorus;
147
148     chorus = FLUID_NEW(fluid_chorus_t);
149
150     if(chorus == NULL)
151     {
152         FLUID_LOG(FLUID_PANIC, "chorus: Out of memory");
153         return NULL;
154     }
155
156     FLUID_MEMSET(chorus, 0, sizeof(fluid_chorus_t));
157
158     chorus->sample_rate = sample_rate;
159
160     /* Lookup table for the SI function (impulse response of an ideal low pass) */
161
162     /* i: Offset in terms of whole samples */
163     for(i = 0; i < INTERPOLATION_SAMPLES; i++)
164     {
165
166         /* ii: Offset in terms of fractional samples ('subsamples') */
167         for(ii = 0; ii < INTERPOLATION_SUBSAMPLES; ii++)
168         {
169             /* Move the origin into the center of the table */
170             double i_shifted = ((double) i - ((double) INTERPOLATION_SAMPLES) / 2.
171                                 + (double) ii / (double) INTERPOLATION_SUBSAMPLES);
172
173             if(fabs(i_shifted) < 0.000001)
174             {
175                 /* sinc(0) cannot be calculated straightforward (limit needed
176                    for 0/0) */
177                 chorus->sinc_table[i][ii] = (fluid_real_t)1.;
178
179             }
180             else
181             {
182                 chorus->sinc_table[i][ii] = (fluid_real_t)sin(i_shifted * M_PI) / (M_PI * i_shifted);
183                 /* Hamming window */
184                 chorus->sinc_table[i][ii] *= (fluid_real_t)0.5 * (1.0 + cos(2.0 * M_PI * i_shifted / (fluid_real_t)INTERPOLATION_SAMPLES));
185             };
186         };
187     };
188
189     /* allocate lookup tables */
190     chorus->lookup_tab = FLUID_ARRAY(int, (int)(chorus->sample_rate / MIN_SPEED_HZ));
191
192     if(chorus->lookup_tab == NULL)
193     {
194         FLUID_LOG(FLUID_PANIC, "chorus: Out of memory");
195         goto error_recovery;
196     }
197
198     /* allocate sample buffer */
199
200     chorus->chorusbuf = FLUID_ARRAY(fluid_real_t, MAX_SAMPLES);
201
202     if(chorus->chorusbuf == NULL)
203     {
204         FLUID_LOG(FLUID_PANIC, "chorus: Out of memory");
205         goto error_recovery;
206     }
207
208     if(fluid_chorus_init(chorus) != FLUID_OK)
209     {
210         goto error_recovery;
211     };
212
213     return chorus;
214
215 error_recovery:
216     delete_fluid_chorus(chorus);
217
218     return NULL;
219 }
220
221 void
222 delete_fluid_chorus(fluid_chorus_t *chorus)
223 {
224     fluid_return_if_fail(chorus != NULL);
225
226     FLUID_FREE(chorus->chorusbuf);
227     FLUID_FREE(chorus->lookup_tab);
228     FLUID_FREE(chorus);
229 }
230
231 int
232 fluid_chorus_init(fluid_chorus_t *chorus)
233 {
234     int i;
235
236     for(i = 0; i < MAX_SAMPLES; i++)
237     {
238         chorus->chorusbuf[i] = 0.0;
239     }
240
241     return FLUID_OK;
242 }
243
244 void
245 fluid_chorus_reset(fluid_chorus_t *chorus)
246 {
247     fluid_chorus_init(chorus);
248 }
249
250 /**
251  * Set one or more chorus parameters.
252  * @param chorus Chorus instance
253  * @param set Flags indicating which chorus parameters to set (#fluid_chorus_set_t)
254  * @param nr Chorus voice count (0-99, CPU time consumption proportional to
255  *   this value)
256  * @param level Chorus level (0.0-10.0)
257  * @param speed Chorus speed in Hz (0.29-5.0)
258  * @param depth_ms Chorus depth (max value depends on synth sample rate,
259  *   0.0-21.0 is safe for sample rate values up to 96KHz)
260  * @param type Chorus waveform type (#fluid_chorus_mod)
261  */
262 void
263 fluid_chorus_set(fluid_chorus_t *chorus, int set, int nr, fluid_real_t level,
264                  fluid_real_t speed, fluid_real_t depth_ms, int type)
265 {
266     int modulation_depth_samples;
267     int i;
268
269     if(set & FLUID_CHORUS_SET_NR)
270     {
271         chorus->number_blocks = nr;
272     }
273
274     if(set & FLUID_CHORUS_SET_LEVEL)
275     {
276         chorus->level = level;
277     }
278
279     if(set & FLUID_CHORUS_SET_SPEED)
280     {
281         chorus->speed_Hz = speed;
282     }
283
284     if(set & FLUID_CHORUS_SET_DEPTH)
285     {
286         chorus->depth_ms = depth_ms;
287     }
288
289     if(set & FLUID_CHORUS_SET_TYPE)
290     {
291         chorus->type = type;
292     }
293
294     if(chorus->number_blocks < 0)
295     {
296         FLUID_LOG(FLUID_WARN, "chorus: number blocks must be >=0! Setting value to 0.");
297         chorus->number_blocks = 0;
298     }
299     else if(chorus->number_blocks > MAX_CHORUS)
300     {
301         FLUID_LOG(FLUID_WARN, "chorus: number blocks larger than max. allowed! Setting value to %d.",
302                   MAX_CHORUS);
303         chorus->number_blocks = MAX_CHORUS;
304     }
305
306     if(chorus->speed_Hz < MIN_SPEED_HZ)
307     {
308         FLUID_LOG(FLUID_WARN, "chorus: speed is too low (min %f)! Setting value to min.",
309                   (double) MIN_SPEED_HZ);
310         chorus->speed_Hz = MIN_SPEED_HZ;
311     }
312     else if(chorus->speed_Hz > MAX_SPEED_HZ)
313     {
314         FLUID_LOG(FLUID_WARN, "chorus: speed must be below %f Hz! Setting value to max.",
315                   (double) MAX_SPEED_HZ);
316         chorus->speed_Hz = MAX_SPEED_HZ;
317     }
318
319     if(chorus->depth_ms < 0.0)
320     {
321         FLUID_LOG(FLUID_WARN, "chorus: depth must be positive! Setting value to 0.");
322         chorus->depth_ms = 0.0;
323     }
324
325     /* Depth: Check for too high value through modulation_depth_samples. */
326
327     if(chorus->level < 0.0)
328     {
329         FLUID_LOG(FLUID_WARN, "chorus: level must be positive! Setting value to 0.");
330         chorus->level = 0.0;
331     }
332     else if(chorus->level > 10)
333     {
334         FLUID_LOG(FLUID_WARN, "chorus: level must be < 10. A reasonable level is << 1! "
335                   "Setting it to 0.1.");
336         chorus->level = 0.1;
337     }
338
339     /* The modulating LFO goes through a full period every x samples: */
340     chorus->modulation_period_samples = chorus->sample_rate / chorus->speed_Hz;
341
342     /* The variation in delay time is x: */
343     modulation_depth_samples = (int)
344                                (chorus->depth_ms / 1000.0  /* convert modulation depth in ms to s*/
345                                 * chorus->sample_rate);
346
347     if(modulation_depth_samples > MAX_SAMPLES)
348     {
349         FLUID_LOG(FLUID_WARN, "chorus: Too high depth. Setting it to max (%d).", MAX_SAMPLES);
350         modulation_depth_samples = MAX_SAMPLES;
351         // set depth to maximum to avoid spamming console with above warning
352         chorus->depth_ms = (modulation_depth_samples * 1000) / chorus->sample_rate;
353     }
354
355     /* initialize LFO table */
356     switch(chorus->type)
357     {
358     default:
359         FLUID_LOG(FLUID_WARN, "chorus: Unknown modulation type. Using sinewave.");
360         chorus->type = FLUID_CHORUS_MOD_SINE;
361         /* fall-through */
362         
363     case FLUID_CHORUS_MOD_SINE:
364         fluid_chorus_sine(chorus->lookup_tab, chorus->modulation_period_samples,
365                           modulation_depth_samples);
366         break;
367
368     case FLUID_CHORUS_MOD_TRIANGLE:
369         fluid_chorus_triangle(chorus->lookup_tab, chorus->modulation_period_samples,
370                               modulation_depth_samples);
371         break;
372     }
373
374     for(i = 0; i < chorus->number_blocks; i++)
375     {
376         /* Set the phase of the chorus blocks equally spaced */
377         chorus->phase[i] = (int)((double) chorus->modulation_period_samples
378                                  * (double) i / (double) chorus->number_blocks);
379     }
380
381     /* Start of the circular buffer */
382     chorus->counter = 0;
383 }
384
385
386 void fluid_chorus_processmix(fluid_chorus_t *chorus, const fluid_real_t *in,
387                              fluid_real_t *left_out, fluid_real_t *right_out)
388 {
389     int sample_index;
390     int i;
391     fluid_real_t d_in, d_out;
392
393     for(sample_index = 0; sample_index < FLUID_BUFSIZE; sample_index++)
394     {
395
396         d_in = in[sample_index];
397         d_out = 0.0f;
398
399 # if 0
400         /* Debug: Listen to the chorus signal only */
401         left_out[sample_index] = 0;
402         right_out[sample_index] = 0;
403 #endif
404
405         /* Write the current sample into the circular buffer */
406         chorus->chorusbuf[chorus->counter] = d_in;
407
408         for(i = 0; i < chorus->number_blocks; i++)
409         {
410             int ii;
411             /* Calculate the delay in subsamples for the delay line of chorus block nr. */
412
413             /* The value in the lookup table is so, that this expression
414              * will always be positive.  It will always include a number of
415              * full periods of MAX_SAMPLES*INTERPOLATION_SUBSAMPLES to
416              * remain positive at all times. */
417             int pos_subsamples = (INTERPOLATION_SUBSAMPLES * chorus->counter
418                                   - chorus->lookup_tab[chorus->phase[i]]);
419
420             int pos_samples = pos_subsamples / INTERPOLATION_SUBSAMPLES;
421
422             /* modulo divide by INTERPOLATION_SUBSAMPLES */
423             pos_subsamples &= INTERPOLATION_SUBSAMPLES_ANDMASK;
424
425             for(ii = 0; ii < INTERPOLATION_SAMPLES; ii++)
426             {
427                 /* Add the delayed signal to the chorus sum d_out Note: The
428                  * delay in the delay line moves backwards for increasing
429                  * delay!*/
430
431                 /* The & in chorusbuf[...] is equivalent to a division modulo
432                    MAX_SAMPLES, only faster. */
433                 d_out += chorus->chorusbuf[pos_samples & MAX_SAMPLES_ANDMASK]
434                          * chorus->sinc_table[ii][pos_subsamples];
435
436                 pos_samples--;
437             };
438
439             /* Cycle the phase of the modulating LFO */
440             chorus->phase[i]++;
441
442             chorus->phase[i] %= (chorus->modulation_period_samples);
443         } /* foreach chorus block */
444
445         d_out *= chorus->level;
446
447         /* Add the chorus sum d_out to output */
448         left_out[sample_index] += d_out;
449         right_out[sample_index] += d_out;
450
451         /* Move forward in circular buffer */
452         chorus->counter++;
453         chorus->counter %= MAX_SAMPLES;
454
455     } /* foreach sample */
456 }
457
458 /* Duplication of code ... (replaces sample data instead of mixing) */
459 void fluid_chorus_processreplace(fluid_chorus_t *chorus, const fluid_real_t *in,
460                                  fluid_real_t *left_out, fluid_real_t *right_out)
461 {
462     int sample_index;
463     int i;
464     fluid_real_t d_in, d_out;
465
466     for(sample_index = 0; sample_index < FLUID_BUFSIZE; sample_index++)
467     {
468
469         d_in = in[sample_index];
470         d_out = 0.0f;
471
472 # if 0
473         /* Debug: Listen to the chorus signal only */
474         left_out[sample_index] = 0;
475         right_out[sample_index] = 0;
476 #endif
477
478         /* Write the current sample into the circular buffer */
479         chorus->chorusbuf[chorus->counter] = d_in;
480
481         for(i = 0; i < chorus->number_blocks; i++)
482         {
483             int ii;
484             /* Calculate the delay in subsamples for the delay line of chorus block nr. */
485
486             /* The value in the lookup table is so, that this expression
487              * will always be positive.  It will always include a number of
488              * full periods of MAX_SAMPLES*INTERPOLATION_SUBSAMPLES to
489              * remain positive at all times. */
490             int pos_subsamples = (INTERPOLATION_SUBSAMPLES * chorus->counter
491                                   - chorus->lookup_tab[chorus->phase[i]]);
492
493             int pos_samples = pos_subsamples / INTERPOLATION_SUBSAMPLES;
494
495             /* modulo divide by INTERPOLATION_SUBSAMPLES */
496             pos_subsamples &= INTERPOLATION_SUBSAMPLES_ANDMASK;
497
498             for(ii = 0; ii < INTERPOLATION_SAMPLES; ii++)
499             {
500                 /* Add the delayed signal to the chorus sum d_out Note: The
501                  * delay in the delay line moves backwards for increasing
502                  * delay!*/
503
504                 /* The & in chorusbuf[...] is equivalent to a division modulo
505                    MAX_SAMPLES, only faster. */
506                 d_out += chorus->chorusbuf[pos_samples & MAX_SAMPLES_ANDMASK]
507                          * chorus->sinc_table[ii][pos_subsamples];
508
509                 pos_samples--;
510             };
511
512             /* Cycle the phase of the modulating LFO */
513             chorus->phase[i]++;
514
515             chorus->phase[i] %= (chorus->modulation_period_samples);
516         } /* foreach chorus block */
517
518         d_out *= chorus->level;
519
520         /* Store the chorus sum d_out to output */
521         left_out[sample_index] = d_out;
522         right_out[sample_index] = d_out;
523
524         /* Move forward in circular buffer */
525         chorus->counter++;
526         chorus->counter %= MAX_SAMPLES;
527
528     } /* foreach sample */
529 }
530
531 /* Purpose:
532  *
533  * Calculates a modulation waveform (sine) Its value ( modulo
534  * MAXSAMPLES) varies between 0 and depth*INTERPOLATION_SUBSAMPLES.
535  * Its period length is len.  The waveform data will be used modulo
536  * MAXSAMPLES only.  Since MAXSAMPLES is substracted from the waveform
537  * a couple of times here, the resulting (current position in
538  * buffer)-(waveform sample) will always be positive.
539  */
540 static void
541 fluid_chorus_sine(int *buf, int len, int depth)
542 {
543     int i;
544     double angle, incr, mult;
545
546     /* Pre-calculate increment between angles. */
547     incr = (2. * M_PI) / (double)len;
548
549     /* Pre-calculate 'depth' multiplier. */
550     mult = (double) depth / 2.0 * (double) INTERPOLATION_SUBSAMPLES;
551
552     /* Initialize to zero degrees. */
553     angle = 0.;
554
555     /* Build sine modulation waveform */
556     for(i = 0; i < len; i++)
557     {
558         buf[i] = (int)((1. + sin(angle)) * mult) - 3 * MAX_SAMPLES * INTERPOLATION_SUBSAMPLES;
559
560         angle += incr;
561     }
562 }
563
564 /* Purpose:
565  * Calculates a modulation waveform (triangle)
566  * See fluid_chorus_sine for comments.
567  */
568 static void
569 fluid_chorus_triangle(int *buf, int len, int depth)
570 {
571     int *il = buf;
572     int *ir = buf + len - 1;
573     int ival;
574     double val, incr;
575
576     /* Pre-calculate increment for the ramp. */
577     incr = 2.0 / len * (double)depth * (double) INTERPOLATION_SUBSAMPLES;
578
579     /* Initialize first value */
580     val = 0. - 3. * MAX_SAMPLES * INTERPOLATION_SUBSAMPLES;
581
582     /* Build triangular modulation waveform */
583     while(il <= ir)
584     {
585         /* Assume 'val' to be always negative for rounding mode */
586         ival = (int)(val - 0.5);
587
588         *il++ = ival;
589         *ir-- = ival;
590
591         val += incr;
592     }
593 }