Update Fluidsynth to 2.0.1
[ardour.git] / libs / fluidsynth / src / fluid_mod.c
1 /* FluidSynth - A Software Synthesizer
2  *
3  * Copyright (C) 2003  Peter Hanappe 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 #include "fluid_mod.h"
22 #include "fluid_chan.h"
23 #include "fluid_voice.h"
24
25 /**
26  * Clone the modulators destination, sources, flags and amount.
27  * @param mod the modulator to store the copy to
28  * @param src the source modulator to retrieve the information from
29  * @note The \c next member of \c mod will be left unchanged.
30  */
31 void
32 fluid_mod_clone(fluid_mod_t *mod, const fluid_mod_t *src)
33 {
34     mod->dest = src->dest;
35     mod->src1 = src->src1;
36     mod->flags1 = src->flags1;
37     mod->src2 = src->src2;
38     mod->flags2 = src->flags2;
39     mod->amount = src->amount;
40 }
41
42 /**
43  * Set a modulator's primary source controller and flags.
44  * @param mod The modulator instance
45  * @param src Modulator source (#fluid_mod_src or a MIDI controller number)
46  * @param flags Flags determining mapping function and whether the source
47  *   controller is a general controller (#FLUID_MOD_GC) or a MIDI CC controller
48  *   (#FLUID_MOD_CC), see #fluid_mod_flags.
49  */
50 void
51 fluid_mod_set_source1(fluid_mod_t *mod, int src, int flags)
52 {
53     mod->src1 = src;
54     mod->flags1 = flags;
55 }
56
57 /**
58  * Set a modulator's secondary source controller and flags.
59  * @param mod The modulator instance
60  * @param src Modulator source (#fluid_mod_src or a MIDI controller number)
61  * @param flags Flags determining mapping function and whether the source
62  *   controller is a general controller (#FLUID_MOD_GC) or a MIDI CC controller
63  *   (#FLUID_MOD_CC), see #fluid_mod_flags.
64  */
65 void
66 fluid_mod_set_source2(fluid_mod_t *mod, int src, int flags)
67 {
68     mod->src2 = src;
69     mod->flags2 = flags;
70 }
71
72 /**
73  * Set the destination effect of a modulator.
74  * @param mod The modulator instance
75  * @param dest Destination generator (#fluid_gen_type)
76  */
77 void
78 fluid_mod_set_dest(fluid_mod_t *mod, int dest)
79 {
80     mod->dest = dest;
81 }
82
83 /**
84  * Set the scale amount of a modulator.
85  * @param mod The modulator instance
86  * @param amount Scale amount to assign
87  */
88 void
89 fluid_mod_set_amount(fluid_mod_t *mod, double amount)
90 {
91     mod->amount = (double) amount;
92 }
93
94 /**
95  * Get the primary source value from a modulator.
96  * @param mod The modulator instance
97  * @return The primary source value (#fluid_mod_src or a MIDI CC controller value).
98  */
99 int
100 fluid_mod_get_source1(const fluid_mod_t *mod)
101 {
102     return mod->src1;
103 }
104
105 /**
106  * Get primary source flags from a modulator.
107  * @param mod The modulator instance
108  * @return The primary source flags (#fluid_mod_flags).
109  */
110 int
111 fluid_mod_get_flags1(const fluid_mod_t *mod)
112 {
113     return mod->flags1;
114 }
115
116 /**
117  * Get the secondary source value from a modulator.
118  * @param mod The modulator instance
119  * @return The secondary source value (#fluid_mod_src or a MIDI CC controller value).
120  */
121 int
122 fluid_mod_get_source2(const fluid_mod_t *mod)
123 {
124     return mod->src2;
125 }
126
127 /**
128  * Get secondary source flags from a modulator.
129  * @param mod The modulator instance
130  * @return The secondary source flags (#fluid_mod_flags).
131  */
132 int
133 fluid_mod_get_flags2(const fluid_mod_t *mod)
134 {
135     return mod->flags2;
136 }
137
138 /**
139  * Get destination effect from a modulator.
140  * @param mod The modulator instance
141  * @return Destination generator (#fluid_gen_type)
142  */
143 int
144 fluid_mod_get_dest(const fluid_mod_t *mod)
145 {
146     return mod->dest;
147 }
148
149 /**
150  * Get the scale amount from a modulator.
151  * @param mod The modulator instance
152  * @return Scale amount
153  */
154 double
155 fluid_mod_get_amount(const fluid_mod_t *mod)
156 {
157     return (double) mod->amount;
158 }
159
160 /*
161  * retrieves the initial value from the given source of the modulator
162  */
163 static fluid_real_t
164 fluid_mod_get_source_value(const unsigned char mod_src,
165                            const unsigned char mod_flags,
166                            fluid_real_t *range,
167                            const fluid_voice_t *voice
168                           )
169 {
170     const fluid_channel_t *chan = voice->channel;
171     fluid_real_t val;
172
173     if(mod_flags & FLUID_MOD_CC)
174     {
175         /* From MIDI Recommended Practice (RP-036) Default Pan Formula:
176          * "Since MIDI controller values range from 0 to 127, the exact center
177          * of the range, 63.5, cannot be represented. Therefore, the effective
178          * range for CC#10 is modified to be 1 to 127, and values 0 and 1 both
179          * pan hard left. The recommended method is to subtract 1 from the
180          * value of CC#10, and saturate the result to be non-negative."
181          *
182          * We treat the balance control in exactly the same way, as the same
183          * problem applies here as well.
184          */
185         if(mod_src == PAN_MSB || mod_src == BALANCE_MSB)
186         {
187             *range = 126;
188             val = fluid_channel_get_cc(chan, mod_src) - 1;
189
190             if(val < 0)
191             {
192                 val = 0;
193             }
194         }
195         else
196         {
197             val = fluid_channel_get_cc(chan, mod_src);
198         }
199     }
200     else
201     {
202         switch(mod_src)
203         {
204         case FLUID_MOD_NONE:         /* SF 2.01 8.2.1 item 0: src enum=0 => value is 1 */
205             val = *range;
206             break;
207
208         case FLUID_MOD_VELOCITY:
209             val = fluid_voice_get_actual_velocity(voice);
210             break;
211
212         case FLUID_MOD_KEY:
213             val = fluid_voice_get_actual_key(voice);
214             break;
215
216         case FLUID_MOD_KEYPRESSURE:
217             val = fluid_channel_get_key_pressure(chan, voice->key);
218             break;
219
220         case FLUID_MOD_CHANNELPRESSURE:
221             val = fluid_channel_get_channel_pressure(chan);
222             break;
223
224         case FLUID_MOD_PITCHWHEEL:
225             val = fluid_channel_get_pitch_bend(chan);
226             *range = 0x4000;
227             break;
228
229         case FLUID_MOD_PITCHWHEELSENS:
230             val = fluid_channel_get_pitch_wheel_sensitivity(chan);
231             break;
232
233         default:
234             FLUID_LOG(FLUID_ERR, "Unknown modulator source '%d', disabling modulator.", mod_src);
235             val = 0.0;
236         }
237     }
238
239     return val;
240 }
241
242 /**
243  * transforms the initial value retrieved by \c fluid_mod_get_source_value into [0.0;1.0]
244  */
245 static fluid_real_t
246 fluid_mod_transform_source_value(fluid_real_t val, unsigned char mod_flags, const fluid_real_t range)
247 {
248     /* normalized value, i.e. usually in the range [0;1]
249      *
250      * if val was retrieved from pitch_bend then [-0.5;0.5]
251      */
252     const fluid_real_t val_norm = val / range;
253
254     /* we could also only switch case the lower nibble of mod_flags, however
255      * this would keep us from adding further mod types in the future
256      *
257      * instead just remove the flag(s) we already took care of
258      */
259     mod_flags &= ~FLUID_MOD_CC;
260
261     switch(mod_flags/* & 0x0f*/)
262     {
263     case FLUID_MOD_LINEAR | FLUID_MOD_UNIPOLAR | FLUID_MOD_POSITIVE: /* =0 */
264         val = val_norm;
265         break;
266
267     case FLUID_MOD_LINEAR | FLUID_MOD_UNIPOLAR | FLUID_MOD_NEGATIVE: /* =1 */
268         val = 1.0f - val_norm;
269         break;
270
271     case FLUID_MOD_LINEAR | FLUID_MOD_BIPOLAR | FLUID_MOD_POSITIVE: /* =2 */
272         val = -1.0f + 2.0f * val_norm;
273         break;
274
275     case FLUID_MOD_LINEAR | FLUID_MOD_BIPOLAR | FLUID_MOD_NEGATIVE: /* =3 */
276         val = 1.0f - 2.0f * val_norm;
277         break;
278
279     case FLUID_MOD_CONCAVE | FLUID_MOD_UNIPOLAR | FLUID_MOD_POSITIVE: /* =4 */
280         val = fluid_concave(127 * (val_norm));
281         break;
282
283     case FLUID_MOD_CONCAVE | FLUID_MOD_UNIPOLAR | FLUID_MOD_NEGATIVE: /* =5 */
284         val = fluid_concave(127 * (1.0f - val_norm));
285         break;
286
287     case FLUID_MOD_CONCAVE | FLUID_MOD_BIPOLAR | FLUID_MOD_POSITIVE: /* =6 */
288         val = (val_norm > 0.5f) ?  fluid_concave(127 * 2 * (val_norm - 0.5f))
289               : -fluid_concave(127 * 2 * (0.5f - val_norm));
290         break;
291
292     case FLUID_MOD_CONCAVE | FLUID_MOD_BIPOLAR | FLUID_MOD_NEGATIVE: /* =7 */
293         val = (val_norm > 0.5f) ? -fluid_concave(127 * 2 * (val_norm - 0.5f))
294               :  fluid_concave(127 * 2 * (0.5f - val_norm));
295         break;
296
297     case FLUID_MOD_CONVEX | FLUID_MOD_UNIPOLAR | FLUID_MOD_POSITIVE: /* =8 */
298         val = fluid_convex(127 * (val_norm));
299         break;
300
301     case FLUID_MOD_CONVEX | FLUID_MOD_UNIPOLAR | FLUID_MOD_NEGATIVE: /* =9 */
302         val = fluid_convex(127 * (1.0f - val_norm));
303         break;
304
305     case FLUID_MOD_CONVEX | FLUID_MOD_BIPOLAR | FLUID_MOD_POSITIVE: /* =10 */
306         val = (val_norm > 0.5f) ?  fluid_convex(127 * 2 * (val_norm - 0.5f))
307               : -fluid_convex(127 * 2 * (0.5f - val_norm));
308         break;
309
310     case FLUID_MOD_CONVEX | FLUID_MOD_BIPOLAR | FLUID_MOD_NEGATIVE: /* =11 */
311         val = (val_norm > 0.5f) ? -fluid_convex(127 * 2 * (val_norm - 0.5f))
312               :  fluid_convex(127 * 2 * (0.5f - val_norm));
313         break;
314
315     case FLUID_MOD_SWITCH | FLUID_MOD_UNIPOLAR | FLUID_MOD_POSITIVE: /* =12 */
316         val = (val_norm >= 0.5f) ? 1.0f : 0.0f;
317         break;
318
319     case FLUID_MOD_SWITCH | FLUID_MOD_UNIPOLAR | FLUID_MOD_NEGATIVE: /* =13 */
320         val = (val_norm >= 0.5f) ? 0.0f : 1.0f;
321         break;
322
323     case FLUID_MOD_SWITCH | FLUID_MOD_BIPOLAR | FLUID_MOD_POSITIVE: /* =14 */
324         val = (val_norm >= 0.5f) ? 1.0f : -1.0f;
325         break;
326
327     case FLUID_MOD_SWITCH | FLUID_MOD_BIPOLAR | FLUID_MOD_NEGATIVE: /* =15 */
328         val = (val_norm >= 0.5f) ? -1.0f : 1.0f;
329         break;
330
331     /*
332      * MIDI CCs only have a resolution of 7 bits. The closer val_norm gets to 1,
333      * the less will be the resulting change of the sinus. When using this sin()
334      * for scaling the cutoff frequency, there will be no audible difference between
335      * MIDI CCs 118 to 127. To avoid this waste of CCs multiply with 0.87
336      * (at least for unipolar) which makes sin() never get to 1.0 but to 0.98 which
337      * is close enough.
338      */
339     case FLUID_MOD_SIN | FLUID_MOD_UNIPOLAR | FLUID_MOD_POSITIVE: /* custom sin(x) */
340         val = sin(M_PI / 2 * val_norm * 0.87);
341         break;
342
343     case FLUID_MOD_SIN | FLUID_MOD_UNIPOLAR | FLUID_MOD_NEGATIVE: /* custom */
344         val = sin(M_PI / 2 * (1.0f - val_norm) * 0.87);
345         break;
346
347     case FLUID_MOD_SIN | FLUID_MOD_BIPOLAR | FLUID_MOD_POSITIVE: /* custom */
348         val = (val_norm > 0.5f) ?  sin(M_PI / 2 * 2 * (val_norm - 0.5f))
349               : -sin(M_PI / 2 * 2 * (0.5f - val_norm));
350         break;
351
352     case FLUID_MOD_SIN | FLUID_MOD_BIPOLAR | FLUID_MOD_NEGATIVE: /* custom */
353         val = (val_norm > 0.5f) ? -sin(M_PI / 2 * 2 * (val_norm - 0.5f))
354               :  sin(M_PI / 2 * 2 * (0.5f - val_norm));
355         break;
356
357     default:
358         FLUID_LOG(FLUID_ERR, "Unknown modulator type '%d', disabling modulator.", mod_flags);
359         val = 0.0f;
360         break;
361     }
362
363     return val;
364 }
365
366 /*
367  * fluid_mod_get_value
368  */
369 fluid_real_t
370 fluid_mod_get_value(fluid_mod_t *mod, fluid_voice_t *voice)
371 {
372     extern fluid_mod_t default_vel2filter_mod;
373
374     fluid_real_t v1 = 0.0, v2 = 1.0;
375     fluid_real_t range1 = 127.0, range2 = 127.0;
376
377     /* 'special treatment' for default controller
378      *
379      *  Reference: SF2.01 section 8.4.2
380      *
381      * The GM default controller 'vel-to-filter cut off' is not clearly
382      * defined: If implemented according to the specs, the filter
383      * frequency jumps between vel=63 and vel=64.  To maintain
384      * compatibility with existing sound fonts, the implementation is
385      * 'hardcoded', it is impossible to implement using only one
386      * modulator otherwise.
387      *
388      * I assume here, that the 'intention' of the paragraph is one
389      * octave (1200 cents) filter frequency shift between vel=127 and
390      * vel=64.  'amount' is (-2400), at least as long as the controller
391      * is set to default.
392      *
393      * Further, the 'appearance' of the modulator (source enumerator,
394      * destination enumerator, flags etc) is different from that
395      * described in section 8.4.2, but it matches the definition used in
396      * several SF2.1 sound fonts (where it is used only to turn it off).
397      * */
398     if(fluid_mod_test_identity(mod, &default_vel2filter_mod))
399     {
400 // S. Christian Collins' mod, to stop forcing velocity based filtering
401         /*
402             if (voice->vel < 64){
403               return (fluid_real_t) mod->amount / 2.0;
404             } else {
405               return (fluid_real_t) mod->amount * (127 - voice->vel) / 127;
406             }
407         */
408         return 0; // (fluid_real_t) mod->amount / 2.0;
409     }
410
411 // end S. Christian Collins' mod
412
413     /* get the initial value of the first source */
414     if(mod->src1 > 0)
415     {
416         v1 = fluid_mod_get_source_value(mod->src1, mod->flags1, &range1, voice);
417
418         /* transform the input value */
419         v1 = fluid_mod_transform_source_value(v1, mod->flags1, range1);
420     }
421     else
422     {
423         return 0.0;
424     }
425
426     /* no need to go further */
427     if(v1 == 0.0f)
428     {
429         return 0.0f;
430     }
431
432     /* get the second input source */
433     if(mod->src2 > 0)
434     {
435         v2 = fluid_mod_get_source_value(mod->src2, mod->flags2, &range2, voice);
436
437         /* transform the second input value */
438         v2 = fluid_mod_transform_source_value(v2, mod->flags2, range2);
439     }
440     else
441     {
442         v2 = 1.0f;
443     }
444
445     /* it's as simple as that: */
446     return (fluid_real_t) mod->amount * v1 * v2;
447 }
448
449 /**
450  * Create a new uninitialized modulator structure.
451  * @return New allocated modulator or NULL if out of memory
452  */
453 fluid_mod_t *
454 new_fluid_mod()
455 {
456     fluid_mod_t *mod = FLUID_NEW(fluid_mod_t);
457
458     if(mod == NULL)
459     {
460         FLUID_LOG(FLUID_ERR, "Out of memory");
461         return NULL;
462     }
463
464     return mod;
465 }
466
467 /**
468  * Free a modulator structure.
469  * @param mod Modulator to free
470  */
471 void
472 delete_fluid_mod(fluid_mod_t *mod)
473 {
474     FLUID_FREE(mod);
475 }
476
477 /**
478  * Returns the size of the fluid_mod_t structure.
479  *
480  * Useful in low latency scenarios e.g. to allocate a modulator on the stack.
481  *
482  * @return Size of fluid_mod_t in bytes
483  */
484 size_t fluid_mod_sizeof()
485 {
486     return sizeof(fluid_mod_t);
487 }
488
489 /**
490  * Checks if two modulators are identical in sources, flags and destination.
491  * @param mod1 First modulator
492  * @param mod2 Second modulator
493  * @return TRUE if identical, FALSE otherwise
494  *
495  * SF2.01 section 9.5.1 page 69, 'bullet' 3 defines 'identical'.
496  */
497 int
498 fluid_mod_test_identity(const fluid_mod_t *mod1, const fluid_mod_t *mod2)
499 {
500     return mod1->dest == mod2->dest
501            && mod1->src1 == mod2->src1
502            && mod1->src2 == mod2->src2
503            && mod1->flags1 == mod2->flags1
504            && mod1->flags2 == mod2->flags2;
505 }
506
507 /**
508  * Check if the modulator has the given source.
509  *
510  * @param mod The modulator instance
511  * @param cc Boolean value indicating if ctrl is a CC controller or not
512  * @param ctrl The source to check for (if \c cc == FALSE : a value of type #fluid_mod_src, else the value of the MIDI CC to check for)
513  *
514  * @return TRUE if the modulator has the given source, FALSE otherwise.
515  */
516 int fluid_mod_has_source(const fluid_mod_t *mod, int cc, int ctrl)
517 {
518     return
519         (
520             (
521                 ((mod->src1 == ctrl) && ((mod->flags1 & FLUID_MOD_CC) != 0) && (cc != 0))
522                 || ((mod->src1 == ctrl) && ((mod->flags1 & FLUID_MOD_CC) == 0) && (cc == 0))
523             )
524             ||
525             (
526                 ((mod->src2 == ctrl) && ((mod->flags2 & FLUID_MOD_CC) != 0) && (cc != 0))
527                 || ((mod->src2 == ctrl) && ((mod->flags2 & FLUID_MOD_CC) == 0) && (cc == 0))
528             )
529         );
530 }
531
532 /**
533  * Check if the modulator has the given destination.
534  * @param mod The modulator instance
535  * @param gen The destination generator of type #fluid_gen_type to check for
536  * @return TRUE if the modulator has the given destination, FALSE otherwise.
537  */
538 int fluid_mod_has_dest(const fluid_mod_t *mod, int gen)
539 {
540     return mod->dest == gen;
541 }
542
543
544 /* debug function: Prints the contents of a modulator */
545 #ifdef DEBUG
546 void fluid_dump_modulator(fluid_mod_t *mod)
547 {
548     int src1 = mod->src1;
549     int dest = mod->dest;
550     int src2 = mod->src2;
551     int flags1 = mod->flags1;
552     int flags2 = mod->flags2;
553     fluid_real_t amount = (fluid_real_t)mod->amount;
554
555     printf("Src: ");
556
557     if(flags1 & FLUID_MOD_CC)
558     {
559         printf("MIDI CC=%i", src1);
560     }
561     else
562     {
563         switch(src1)
564         {
565         case FLUID_MOD_NONE:
566             printf("None");
567             break;
568
569         case FLUID_MOD_VELOCITY:
570             printf("note-on velocity");
571             break;
572
573         case FLUID_MOD_KEY:
574             printf("Key nr");
575             break;
576
577         case FLUID_MOD_KEYPRESSURE:
578             printf("Poly pressure");
579             break;
580
581         case FLUID_MOD_CHANNELPRESSURE:
582             printf("Chan pressure");
583             break;
584
585         case FLUID_MOD_PITCHWHEEL:
586             printf("Pitch Wheel");
587             break;
588
589         case FLUID_MOD_PITCHWHEELSENS:
590             printf("Pitch Wheel sens");
591             break;
592
593         default:
594             printf("(unknown: %i)", src1);
595         }; /* switch src1 */
596     }; /* if not CC */
597
598     if(flags1 & FLUID_MOD_NEGATIVE)
599     {
600         printf("- ");
601     }
602     else
603     {
604         printf("+ ");
605     };
606
607     if(flags1 & FLUID_MOD_BIPOLAR)
608     {
609         printf("bip ");
610     }
611     else
612     {
613         printf("unip ");
614     };
615
616     printf("-> ");
617
618     switch(dest)
619     {
620     case GEN_FILTERQ:
621         printf("Q");
622         break;
623
624     case GEN_FILTERFC:
625         printf("fc");
626         break;
627
628     case GEN_CUSTOM_FILTERQ:
629         printf("custom-Q");
630         break;
631
632     case GEN_CUSTOM_FILTERFC:
633         printf("custom-fc");
634         break;
635
636     case GEN_VIBLFOTOPITCH:
637         printf("VibLFO-to-pitch");
638         break;
639
640     case GEN_MODENVTOPITCH:
641         printf("ModEnv-to-pitch");
642         break;
643
644     case GEN_MODLFOTOPITCH:
645         printf("ModLFO-to-pitch");
646         break;
647
648     case GEN_CHORUSSEND:
649         printf("Chorus send");
650         break;
651
652     case GEN_REVERBSEND:
653         printf("Reverb send");
654         break;
655
656     case GEN_PAN:
657         printf("pan");
658         break;
659
660     case GEN_CUSTOM_BALANCE:
661         printf("balance");
662         break;
663
664     case GEN_ATTENUATION:
665         printf("att");
666         break;
667
668     default:
669         printf("dest %i", dest);
670     }; /* switch dest */
671
672     printf(", amount %f flags %i src2 %i flags2 %i\n", amount, flags1, src2, flags2);
673 };
674 #endif
675