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 Library General Public License
7  * as published by the Free Software Foundation; either version 2 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  * Library General Public License for more details.
14  *
15  * You should have received a copy of the GNU Library General Public
16  * License along with this library; if not, write to the Free
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
18  * 02111-1307, USA
19  */
20 
21 #include "fluid.h"
22 #include "conv.h"
23 #include "voice.h"
24 
25 namespace FluidS {
26 
27 #undef FLUID_LOG
28 #define FLUID_LOG(a, ...)
29 
30 //---------------------------------------------------------
31 //   clone
32 //---------------------------------------------------------
33 
clone(Mod * mod) const34 void Mod::clone(Mod* mod) const
35       {
36       mod->dest   = dest;
37       mod->src1   = src1;
38       mod->flags1 = flags1;
39       mod->src2   = src2;
40       mod->flags2 = flags2;
41       mod->amount = amount;
42       }
43 
44 /*
45  * fluid_mod_set_source1
46  */
set_source1(int src,int flags)47 void Mod::set_source1(int src, int flags)
48       {
49       src1   = src;
50       flags1 = flags;
51       }
52 
53 /*
54  * fluid_mod_set_source2
55  */
set_source2(int src,int flags)56 void Mod::set_source2(int src, int flags)
57       {
58       src2 = src;
59       flags2 = flags;
60       }
61 
62 /*
63  * fluid_mod_get_value
64  */
get_value(Channel * chan,Voice * voice)65 float Mod::get_value(Channel* chan, Voice* voice)
66       {
67       Mod* mod = this;
68       float v1 = 0.0, v2 = 1.0;
69       float range1 = 127.0, range2 = 127.0;
70 
71       if (chan == 0)
72             return 0.0f;
73 
74       /* 'special treatment' for default controller
75        *
76        *  Reference: SF2.01 section 8.4.2
77        *
78        * The GM default controller 'vel-to-filter cut off' is not clearly
79        * defined: If implemented according to the specs, the filter
80        * frequency jumps between vel=63 and vel=64.  To maintain
81        * compatibility with existing sound fonts, the implementation is
82        * 'hardcoded', it is impossible to implement using only one
83        * modulator otherwise.
84        *
85        * I assume here, that the 'intention' of the paragraph is one
86        * octave (1200 cents) filter frequency shift between vel=127 and
87        * vel=64.  'amount' is (-2400), at least as long as the controller
88        * is set to default.
89        *
90        * Further, the 'appearance' of the modulator (source enumerator,
91        * destination enumerator, flags etc) is different from that
92        * described in section 8.4.2, but it matches the definition used in
93        * several SF2.1 sound fonts (where it is used only to turn it off).
94        */
95 
96       if ((mod->src2 == FLUID_MOD_VELOCITY) &&
97          (mod->src1 == FLUID_MOD_VELOCITY) &&
98          (mod->flags1 == (FLUID_MOD_GC | FLUID_MOD_UNIPOLAR
99             | FLUID_MOD_NEGATIVE | FLUID_MOD_LINEAR)) &&
100          (mod->flags2 == (FLUID_MOD_GC | FLUID_MOD_UNIPOLAR
101             | FLUID_MOD_POSITIVE | FLUID_MOD_SWITCH)) &&
102          (mod->dest == GEN_FILTERFC)) {
103 // Disable default vel-to-filter cutoff modulator per upstream FluidSynth
104 /*
105             if (voice->vel < 64)
106                   return (float) mod->amount / 2.0;
107             else
108                   return (float) mod->amount * (127 - voice->vel) / 127;
109             }
110 */
111      return 0; // (float) mod->amount / 2.0;
112   }
113 // end vel-to-filter cutoff mod
114 
115       /* get the initial value of the first source */
116       if (mod->src1 > 0) {
117             if (mod->flags1 & FLUID_MOD_CC) {
118                   v1 = chan->getCC(mod->src1);
119                   }
120             else {  /* source 1 is one of the direct controllers */
121                   switch (mod->src1) {
122                         case FLUID_MOD_NONE:         /* SF 2.01 8.2.1 item 0: src enum=0 => value is 1 */
123                               v1 = range1;
124                               break;
125                         case FLUID_MOD_VELOCITY:
126                               v1 = voice->vel;
127                               break;
128                         case FLUID_MOD_KEY:
129                               v1 = voice->key;
130                               break;
131                         case FLUID_MOD_KEYPRESSURE:
132                               v1 = chan->keyPressure(voice->key);
133                               break;
134                         case FLUID_MOD_CHANNELPRESSURE:
135                               v1 = chan->channel_pressure;
136                               break;
137                         case FLUID_MOD_PITCHWHEEL:
138                               v1 = chan->pitch_bend;
139                               range1 = 0x4000;
140                               break;
141                         case FLUID_MOD_PITCHWHEELSENS:
142                               v1 = chan->pitch_wheel_sensitivity;
143                               break;
144                         default:
145                               v1 = 0.0;
146                         }
147                   }
148 
149             /* transform the input value */
150             switch (mod->flags1 & 0x0f) {
151                   case 0: /* linear, unipolar, positive */
152                         v1 /= range1;
153                         break;
154                   case 1: /* linear, unipolar, negative */
155                         v1 = 1.0f - v1 / range1;
156                         break;
157                   case 2: /* linear, bipolar, positive */
158                         v1 = -1.0f + 2.0f * v1 / range1;
159                         break;
160                   case 3: /* linear, bipolar, negative */
161                         v1 = 1.0f - 2.0f * v1 / range1;
162                         break;
163                   case 4: /* concave, unipolar, positive */
164                         v1 = fluid_concave(v1);
165                         break;
166                   case 5: /* concave, unipolar, negative */
167                         v1 = fluid_concave(127 - v1);
168                         break;
169                   case 6: /* concave, bipolar, positive */
170                         v1 = (v1 > 64)? fluid_concave(2 * (v1 - 64)) : -fluid_concave(2 * (64 - v1));
171                         break;
172                   case 7: /* concave, bipolar, negative */
173                         v1 = (v1 > 64)? -fluid_concave(2 * (v1 - 64)) : fluid_concave(2 * (64 - v1));
174                         break;
175                   case 8: /* convex, unipolar, positive */
176                         v1 = fluid_convex(v1);
177                         break;
178                   case 9: /* convex, unipolar, negative */
179                         v1 = fluid_convex(127 - v1);
180                         break;
181                   case 10: /* convex, bipolar, positive */
182                         v1 = (v1 > 64) ? fluid_convex(2 * (v1 - 64)) : -fluid_convex(2 * (64 - v1));
183                         break;
184                   case 11: /* convex, bipolar, negative */
185                         v1 = (v1 > 64)? -fluid_convex(2 * (v1 - 64)) : fluid_convex(2 * (64 - v1));
186                         break;
187                   case 12: /* switch, unipolar, positive */
188                         v1 = (v1 >= 64)? 1.0f : 0.0f;
189                         break;
190                   case 13: /* switch, unipolar, negative */
191                         v1 = (v1 >= 64)? 0.0f : 1.0f;
192                         break;
193                   case 14: /* switch, bipolar, positive */
194                         v1 = (v1 >= 64)? 1.0f : -1.0f;
195                         break;
196                   case 15: /* switch, bipolar, negative */
197                         v1 = (v1 >= 64)? -1.0f : 1.0f;
198                         break;
199                   }
200             }
201       else
202             return 0.0;
203 
204       /* no need to go further */
205       if (v1 == 0.0f)
206             return 0.0f;
207 
208       /* get the second input source */
209       if (mod->src2 > 0) {
210             if (mod->flags2 & FLUID_MOD_CC) {
211                   v2 = chan->getCC(mod->src2);
212                   }
213             else {
214                   switch (mod->src2) {
215                         case FLUID_MOD_NONE:         /* SF 2.01 8.2.1 item 0: src enum=0 => value is 1 */
216                               v2 = range2;
217                               break;
218                         case FLUID_MOD_VELOCITY:
219                               v2 = voice->vel;
220                               break;
221                         case FLUID_MOD_KEY:
222                               v2 = voice->key;
223                               break;
224                         case FLUID_MOD_KEYPRESSURE:
225                               v2 = chan->keyPressure(voice->key);
226                               break;
227                         case FLUID_MOD_CHANNELPRESSURE:
228                               v2 = chan->channel_pressure;
229                               break;
230                         case FLUID_MOD_PITCHWHEEL:
231                               v2 = chan->pitch_bend;
232                               break;
233                         case FLUID_MOD_PITCHWHEELSENS:
234                               v2 = chan->pitch_wheel_sensitivity;
235                               break;
236                         default:
237                               v1 = 0.0f;
238                         }
239                   }
240 
241             /* transform the second input value */
242             switch (mod->flags2 & 0x0f) {
243                   case 0: /* linear, unipolar, positive */
244                         v2 /= range2;
245                         break;
246                   case 1: /* linear, unipolar, negative */
247                         v2 = 1.0f - v2 / range2;
248                         break;
249                   case 2: /* linear, bipolar, positive */
250                         v2 = -1.0f + 2.0f * v2 / range2;
251                         break;
252                   case 3: /* linear, bipolar, negative */
253                         v2 = -1.0f + 2.0f * v2 / range2;
254                         break;
255                   case 4: /* concave, unipolar, positive */
256                         v2 = fluid_concave(v2);
257                         break;
258                   case 5: /* concave, unipolar, negative */
259                         v2 = fluid_concave(127 - v2);
260                         break;
261                   case 6: /* concave, bipolar, positive */
262                         v2 = (v2 > 64)? fluid_concave(2 * (v2 - 64)) : -fluid_concave(2 * (64 - v2));
263                         break;
264                   case 7: /* concave, bipolar, negative */
265                         v2 = (v2 > 64)? -fluid_concave(2 * (v2 - 64)) : fluid_concave(2 * (64 - v2));
266                         break;
267                   case 8: /* convex, unipolar, positive */
268                         v2 = fluid_convex(v2);
269                         break;
270                   case 9: /* convex, unipolar, negative */
271                         v2 = 1.0f - fluid_convex(v2);
272                         break;
273                   case 10: /* convex, bipolar, positive */
274                         v2 = (v2 > 64)? -fluid_convex(2 * (v2 - 64)) : fluid_convex(2 * (64 - v2));
275                         break;
276                   case 11: /* convex, bipolar, negative */
277                         v2 = (v2 > 64)? -fluid_convex(2 * (v2 - 64)) : fluid_convex(2 * (64 - v2));
278                         break;
279                   case 12: /* switch, unipolar, positive */
280                         v2 = (v2 >= 64)? 1.0f : 0.0f;
281                         break;
282                   case 13: /* switch, unipolar, negative */
283                         v2 = (v2 >= 64)? 0.0f : 1.0f;
284                         break;
285                   case 14: /* switch, bipolar, positive */
286                         v2 = (v2 >= 64)? 1.0f : -1.0f;
287                         break;
288                   case 15: /* switch, bipolar, negative */
289                         v2 = (v2 >= 64)? -1.0f : 1.0f;
290                         break;
291                   }
292             }
293       else
294             v2 = 1.0f;
295 
296       /* it's as simple as that: */
297       return mod->amount * v1 * v2;
298       }
299 
300 /*
301  * test_identity
302  */
303 /* Purpose:
304  * Checks, if two modulators are identical.
305  *  SF2.01 section 9.5.1 page 69, 'bullet' 3 defines 'identical'.
306  */
test_identity(const Mod * mod1,const Mod * mod2)307 bool test_identity(const Mod * mod1, const Mod * mod2)
308       {
309       return (mod1->dest == mod2->dest)
310             && (mod1->src1 == mod2->src1)
311             && (mod1->src2 == mod2->src2)
312             && (mod1->flags1 == mod2->flags1)
313             && (mod1->flags2 == mod2->flags2);
314       }
315 
316 //---------------------------------------------------------
317 //   dump
318 //    debug function: Prints the contents of a modulator
319 //---------------------------------------------------------
320 
dump() const321 void Mod::dump() const
322       {
323       const Mod* mod = this;
324 
325       int lsrc1     = mod->src1;
326       int ldest     = mod->dest;
327       int lsrc2     = mod->src2;
328       int lflags1   = mod->flags1;
329       int lflags2   = mod->flags2;
330       float lamount = (float)mod->amount;
331 
332       printf("Src: ");
333       if (flags1 & FLUID_MOD_CC){
334             printf("MIDI CC=%i",lsrc1);
335             }
336       else {
337             switch(lsrc1){
338                   case FLUID_MOD_NONE:
339                         printf("None");
340                         break;
341                   case FLUID_MOD_VELOCITY:
342                         printf("note-on velocity");
343                         break;
344                   case FLUID_MOD_KEY:
345                         printf("Key nr");
346                         break;
347                   case FLUID_MOD_KEYPRESSURE:
348                         printf("Poly pressure");
349                         break;
350                   case FLUID_MOD_CHANNELPRESSURE:
351                         printf("Chan pressure");
352                         break;
353                   case FLUID_MOD_PITCHWHEEL:
354                         printf("Pitch Wheel");
355                         break;
356                   case FLUID_MOD_PITCHWHEELSENS:
357                         printf("Pitch Wheel sens");
358                         break;
359                   default:
360                         printf("(unknown: %i)", lsrc1);
361                   } /* switch src1 */
362             } /* if not CC */
363       if (lflags1 & FLUID_MOD_NEGATIVE)
364             printf("- ");
365       else
366             printf("+ ");
367       if (lflags1 & FLUID_MOD_BIPOLAR)
368             printf("bip ");
369       else
370             printf("unip ");
371       printf("-> ");
372       switch(ldest){
373             case GEN_FILTERQ:
374                   printf("Q");
375                   break;
376             case GEN_FILTERFC:
377                   printf("fc");
378                   break;
379             case GEN_VIBLFOTOPITCH:
380                   printf("VibLFO-to-pitch");
381                   break;
382             case GEN_MODENVTOPITCH:
383                   printf("ModEnv-to-pitch");
384                   break;
385             case GEN_MODLFOTOPITCH:
386                   printf("ModLFO-to-pitch");
387                   break;
388             case GEN_CHORUSSEND:
389                   printf("Chorus send");
390                   break;
391             case GEN_REVERBSEND:
392                   printf("Reverb send");
393                   break;
394             case GEN_PAN:
395                   printf("pan");
396                   break;
397             case GEN_ATTENUATION:
398                   printf("att");
399                   break;
400             default:
401                   printf("dest %i", ldest);
402                   break;
403             } /* switch dest */
404       printf(", amount %f flags %i src2 %i flags2 %i\n",lamount, lflags1, lsrc2, lflags2);
405       }
406 
407 }
408