fluid_mod.c
上传用户:tjmskj2
上传日期:2020-08-17
资源大小:577k
文件大小:13k
源码类别:

midi

开发平台:

C/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 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. #include "fluid_mod.h"
  21. #include "fluid_chan.h"
  22. #include "fluid_voice.h"
  23. /*
  24.  * fluid_mod_clone
  25.  */
  26. void
  27. fluid_mod_clone(fluid_mod_t* mod, fluid_mod_t* src)
  28. {
  29.   mod->dest = src->dest;
  30.   mod->src1 = src->src1;
  31.   mod->flags1 = src->flags1;
  32.   mod->src2 = src->src2;
  33.   mod->flags2 = src->flags2;
  34.   mod->amount = src->amount;
  35. }
  36. /**
  37.  * Set a modulator's primary source controller and flags.
  38.  * @param mod Modulator
  39.  * @param src Modulator source (#fluid_mod_src or a MIDI controller number)
  40.  * @param flags Flags determining mapping function and whether the source
  41.  *   controller is a general controller (#FLUID_MOD_GC) or a MIDI CC controller
  42.  *   (#FLUID_MOD_CC), see #fluid_mod_flags.
  43.  */
  44. void
  45. fluid_mod_set_source1(fluid_mod_t* mod, int src, int flags)
  46. {
  47.   mod->src1 = src;
  48.   mod->flags1 = flags;
  49. }
  50. /**
  51.  * Set a modulator's secondary source controller and flags.
  52.  * @param mod Modulator
  53.  * @param src Modulator source (#fluid_mod_src or a MIDI controller number)
  54.  * @param flags Flags determining mapping function and whether the source
  55.  *   controller is a general controller (#FLUID_MOD_GC) or a MIDI CC controller
  56.  *   (#FLUID_MOD_CC), see #fluid_mod_flags.
  57.  */
  58. void
  59. fluid_mod_set_source2(fluid_mod_t* mod, int src, int flags)
  60. {
  61.   mod->src2 = src;
  62.   mod->flags2 = flags;
  63. }
  64. /**
  65.  * Set the destination effect of a modulator.
  66.  * @param mod Modulator
  67.  * @param dest Destination generator (#fluid_gen_type)
  68.  */
  69. void
  70. fluid_mod_set_dest(fluid_mod_t* mod, int dest)
  71. {
  72.   mod->dest = dest;
  73. }
  74. /**
  75.  * Set the scale amount of a modulator.
  76.  * @param mod Modulator
  77.  * @param amount Scale amount to assign
  78.  */
  79. void
  80. fluid_mod_set_amount(fluid_mod_t* mod, double amount)
  81. {
  82.   mod->amount = (double) amount;
  83. }
  84. /**
  85.  * Get the primary source value from a modulator.
  86.  * @param mod Modulator
  87.  * @return The primary source value (#fluid_mod_src or a MIDI CC controller value).
  88.  */
  89. int
  90. fluid_mod_get_source1(fluid_mod_t* mod)
  91. {
  92.   return mod->src1;
  93. }
  94. /**
  95.  * Get primary source flags from a modulator.
  96.  * @param mod Modulator
  97.  * @return The primary source flags (#fluid_mod_flags).
  98.  */
  99. int
  100. fluid_mod_get_flags1(fluid_mod_t* mod)
  101. {
  102.   return mod->flags1;
  103. }
  104. /**
  105.  * Get the secondary source value from a modulator.
  106.  * @param mod Modulator
  107.  * @return The secondary source value (#fluid_mod_src or a MIDI CC controller value).
  108.  */
  109. int
  110. fluid_mod_get_source2(fluid_mod_t* mod)
  111. {
  112.   return mod->src2;
  113. }
  114. /**
  115.  * Get secondary source flags from a modulator.
  116.  * @param mod Modulator
  117.  * @return The secondary source flags (#fluid_mod_flags).
  118.  */
  119. int
  120. fluid_mod_get_flags2(fluid_mod_t* mod)
  121. {
  122.   return mod->flags2;
  123. }
  124. /**
  125.  * Get destination effect from a modulator.
  126.  * @param mod Modulator
  127.  * @return Destination generator (#fluid_gen_type)
  128.  */
  129. int
  130. fluid_mod_get_dest(fluid_mod_t* mod)
  131. {
  132.   return mod->dest;
  133. }
  134. /**
  135.  * Get the scale amount from a modulator.
  136.  * @param mod Modulator
  137.  * @return Scale amount
  138.  */
  139. double
  140. fluid_mod_get_amount(fluid_mod_t* mod)
  141. {
  142.   return (fluid_real_t) mod->amount;
  143. }
  144. /*
  145.  * fluid_mod_get_value
  146.  */
  147. fluid_real_t
  148. fluid_mod_get_value(fluid_mod_t* mod, fluid_channel_t* chan, fluid_voice_t* voice)
  149. {
  150.   fluid_real_t v1 = 0.0, v2 = 1.0;
  151.   fluid_real_t range1 = 127.0, range2 = 127.0;
  152.   if (chan == NULL) {
  153.     return 0.0f;
  154.   }
  155.   /* 'special treatment' for default controller
  156.    *
  157.    *  Reference: SF2.01 section 8.4.2
  158.    *
  159.    * The GM default controller 'vel-to-filter cut off' is not clearly
  160.    * defined: If implemented according to the specs, the filter
  161.    * frequency jumps between vel=63 and vel=64.  To maintain
  162.    * compatibility with existing sound fonts, the implementation is
  163.    * 'hardcoded', it is impossible to implement using only one
  164.    * modulator otherwise.
  165.    *
  166.    * I assume here, that the 'intention' of the paragraph is one
  167.    * octave (1200 cents) filter frequency shift between vel=127 and
  168.    * vel=64.  'amount' is (-2400), at least as long as the controller
  169.    * is set to default.
  170.    *
  171.    * Further, the 'appearance' of the modulator (source enumerator,
  172.    * destination enumerator, flags etc) is different from that
  173.    * described in section 8.4.2, but it matches the definition used in
  174.    * several SF2.1 sound fonts (where it is used only to turn it off).
  175.    * */
  176.   if ((mod->src2 == FLUID_MOD_VELOCITY) &&
  177.       (mod->src1 == FLUID_MOD_VELOCITY) &&
  178.       (mod->flags1 == (FLUID_MOD_GC | FLUID_MOD_UNIPOLAR
  179.        | FLUID_MOD_NEGATIVE | FLUID_MOD_LINEAR)) &&
  180.       (mod->flags2 == (FLUID_MOD_GC | FLUID_MOD_UNIPOLAR
  181.        | FLUID_MOD_POSITIVE | FLUID_MOD_SWITCH)) &&
  182.       (mod->dest == GEN_FILTERFC)) {
  183. // S. Christian Collins' mod, to stop forcing velocity based filtering
  184. /*
  185.     if (voice->vel < 64){
  186.       return (fluid_real_t) mod->amount / 2.0;
  187.     } else {
  188.       return (fluid_real_t) mod->amount * (127 - voice->vel) / 127;
  189.     }
  190. */
  191.      return 0; // (fluid_real_t) mod->amount / 2.0;
  192.   }
  193. // end S. Christian Collins' mod
  194.   /* get the initial value of the first source */
  195.   if (mod->src1 > 0) {
  196.     if (mod->flags1 & FLUID_MOD_CC) {
  197.       v1 = fluid_channel_get_cc(chan, mod->src1);
  198.     } else {  /* source 1 is one of the direct controllers */
  199.       switch (mod->src1) {
  200.       case FLUID_MOD_NONE:         /* SF 2.01 8.2.1 item 0: src enum=0 => value is 1 */
  201. v1 = range1;
  202. break;
  203.       case FLUID_MOD_VELOCITY:
  204. v1 = voice->vel;
  205. break;
  206.       case FLUID_MOD_KEY:
  207. v1 = voice->key;
  208. break;
  209.       case FLUID_MOD_KEYPRESSURE:
  210. v1 = fluid_channel_get_key_pressure (chan);
  211. break;
  212.       case FLUID_MOD_CHANNELPRESSURE:
  213. v1 = fluid_channel_get_channel_pressure (chan);
  214. break;
  215.       case FLUID_MOD_PITCHWHEEL:
  216. v1 = fluid_channel_get_pitch_bend (chan);
  217. range1 = 0x4000;
  218. break;
  219.       case FLUID_MOD_PITCHWHEELSENS:
  220. v1 = fluid_channel_get_pitch_wheel_sensitivity (chan);
  221. break;
  222.       default:
  223. v1 = 0.0;
  224.       }
  225.     }
  226.     /* transform the input value */
  227.     switch (mod->flags1 & 0x0f) {
  228.     case 0: /* linear, unipolar, positive */
  229.       v1 /= range1;
  230.       break;
  231.     case 1: /* linear, unipolar, negative */
  232.       v1 = 1.0f - v1 / range1;
  233.       break;
  234.     case 2: /* linear, bipolar, positive */
  235.       v1 = -1.0f + 2.0f * v1 / range1;
  236.       break;
  237.     case 3: /* linear, bipolar, negative */
  238.       v1 = 1.0f - 2.0f * v1 / range1;
  239.       break;
  240.     case 4: /* concave, unipolar, positive */
  241.       v1 = fluid_concave(v1);
  242.       break;
  243.     case 5: /* concave, unipolar, negative */
  244.       v1 = fluid_concave(127 - v1);
  245.       break;
  246.     case 6: /* concave, bipolar, positive */
  247.       v1 = (v1 > 64)? fluid_concave(2 * (v1 - 64)) : -fluid_concave(2 * (64 - v1));
  248.       break;
  249.     case 7: /* concave, bipolar, negative */
  250.       v1 = (v1 > 64)? -fluid_concave(2 * (v1 - 64)) : fluid_concave(2 * (64 - v1));
  251.       break;
  252.     case 8: /* convex, unipolar, positive */
  253.       v1 = fluid_convex(v1);
  254.       break;
  255.     case 9: /* convex, unipolar, negative */
  256.       v1 = fluid_convex(127 - v1);
  257.       break;
  258.     case 10: /* convex, bipolar, positive */
  259.       v1 = (v1 > 64)? fluid_convex(2 * (v1 - 64)) : -fluid_convex(2 * (64 - v1));
  260.       break;
  261.     case 11: /* convex, bipolar, negative */
  262.       v1 = (v1 > 64)? -fluid_convex(2 * (v1 - 64)) : fluid_convex(2 * (64 - v1));
  263.       break;
  264.     case 12: /* switch, unipolar, positive */
  265.       v1 = (v1 >= 64)? 1.0f : 0.0f;
  266.       break;
  267.     case 13: /* switch, unipolar, negative */
  268.       v1 = (v1 >= 64)? 0.0f : 1.0f;
  269.       break;
  270.     case 14: /* switch, bipolar, positive */
  271.       v1 = (v1 >= 64)? 1.0f : -1.0f;
  272.       break;
  273.     case 15: /* switch, bipolar, negative */
  274.       v1 = (v1 >= 64)? -1.0f : 1.0f;
  275.       break;
  276.     }
  277.   } else {
  278.     return 0.0;
  279.   }
  280.   /* no need to go further */
  281.   if (v1 == 0.0f) {
  282.     return 0.0f;
  283.   }
  284.   /* get the second input source */
  285.   if (mod->src2 > 0) {
  286.     if (mod->flags2 & FLUID_MOD_CC) {
  287.       v2 = fluid_channel_get_cc(chan, mod->src2);
  288.     } else {
  289.       switch (mod->src2) {
  290.       case FLUID_MOD_NONE:         /* SF 2.01 8.2.1 item 0: src enum=0 => value is 1 */
  291. v2 = range2;
  292. break;
  293.       case FLUID_MOD_VELOCITY:
  294. v2 = voice->vel;
  295. break;
  296.       case FLUID_MOD_KEY:
  297. v2 = voice->key;
  298. break;
  299.       case FLUID_MOD_KEYPRESSURE:
  300. v2 = fluid_channel_get_key_pressure (chan);
  301. break;
  302.       case FLUID_MOD_CHANNELPRESSURE:
  303. v2 = fluid_channel_get_channel_pressure (chan);
  304. break;
  305.       case FLUID_MOD_PITCHWHEEL:
  306. v2 = fluid_channel_get_pitch_bend (chan);
  307. break;
  308.       case FLUID_MOD_PITCHWHEELSENS:
  309. v2 = fluid_channel_get_pitch_wheel_sensitivity (chan);
  310. break;
  311.       default:
  312. v1 = 0.0f;
  313.       }
  314.     }
  315.     /* transform the second input value */
  316.     switch (mod->flags2 & 0x0f) {
  317.     case 0: /* linear, unipolar, positive */
  318.       v2 /= range2;
  319.       break;
  320.     case 1: /* linear, unipolar, negative */
  321.       v2 = 1.0f - v2 / range2;
  322.       break;
  323.     case 2: /* linear, bipolar, positive */
  324.       v2 = -1.0f + 2.0f * v2 / range2;
  325.       break;
  326.     case 3: /* linear, bipolar, negative */
  327.       v2 = -1.0f + 2.0f * v2 / range2;
  328.       break;
  329.     case 4: /* concave, unipolar, positive */
  330.       v2 = fluid_concave(v2);
  331.       break;
  332.     case 5: /* concave, unipolar, negative */
  333.       v2 = fluid_concave(127 - v2);
  334.       break;
  335.     case 6: /* concave, bipolar, positive */
  336.       v2 = (v2 > 64)? fluid_concave(2 * (v2 - 64)) : -fluid_concave(2 * (64 - v2));
  337.       break;
  338.     case 7: /* concave, bipolar, negative */
  339.       v2 = (v2 > 64)? -fluid_concave(2 * (v2 - 64)) : fluid_concave(2 * (64 - v2));
  340.       break;
  341.     case 8: /* convex, unipolar, positive */
  342.       v2 = fluid_convex(v2);
  343.       break;
  344.     case 9: /* convex, unipolar, negative */
  345.       v2 = 1.0f - fluid_convex(v2);
  346.       break;
  347.     case 10: /* convex, bipolar, positive */
  348.       v2 = (v2 > 64)? -fluid_convex(2 * (v2 - 64)) : fluid_convex(2 * (64 - v2));
  349.       break;
  350.     case 11: /* convex, bipolar, negative */
  351.       v2 = (v2 > 64)? -fluid_convex(2 * (v2 - 64)) : fluid_convex(2 * (64 - v2));
  352.       break;
  353.     case 12: /* switch, unipolar, positive */
  354.       v2 = (v2 >= 64)? 1.0f : 0.0f;
  355.       break;
  356.     case 13: /* switch, unipolar, negative */
  357.       v2 = (v2 >= 64)? 0.0f : 1.0f;
  358.       break;
  359.     case 14: /* switch, bipolar, positive */
  360.       v2 = (v2 >= 64)? 1.0f : -1.0f;
  361.       break;
  362.     case 15: /* switch, bipolar, negative */
  363.       v2 = (v2 >= 64)? -1.0f : 1.0f;
  364.       break;
  365.     }
  366.   } else {
  367.     v2 = 1.0f;
  368.   }
  369.   /* it's as simple as that: */
  370.   return (fluid_real_t) mod->amount * v1 * v2;
  371. }
  372. /**
  373.  * Create a new uninitialized modulator structure.
  374.  * @return New allocated modulator or NULL if out of memory
  375.  */
  376. fluid_mod_t*
  377. fluid_mod_new()
  378. {
  379.   fluid_mod_t* mod = FLUID_NEW (fluid_mod_t);
  380.   if (mod == NULL) {
  381.     FLUID_LOG(FLUID_ERR, "Out of memory");
  382.     return NULL;
  383.   }
  384.   return mod;
  385. }
  386. /**
  387.  * Free a modulator structure.
  388.  * @param mod Modulator to free
  389.  */
  390. void
  391. fluid_mod_delete (fluid_mod_t *mod)
  392. {
  393.   FLUID_FREE(mod);
  394. }
  395. /**
  396.  * Checks if two modulators are identical in sources, flags and destination.
  397.  * @param mod1 First modulator
  398.  * @param mod2 Second modulator
  399.  * @return TRUE if identical, FALSE otherwise
  400.  *
  401.  * SF2.01 section 9.5.1 page 69, 'bullet' 3 defines 'identical'.
  402.  */
  403. int
  404. fluid_mod_test_identity (fluid_mod_t *mod1, fluid_mod_t *mod2)
  405. {
  406.   return mod1->dest == mod2->dest
  407.     && mod1->src1 == mod2->src1
  408.     && mod1->src2 == mod2->src2
  409.     && mod1->flags1 == mod2->flags1
  410.     && mod1->flags2 == mod2->flags2;
  411. }
  412. /* debug function: Prints the contents of a modulator */
  413. void fluid_dump_modulator(fluid_mod_t * mod){
  414.   int src1=mod->src1;
  415.   int dest=mod->dest;
  416.   int src2=mod->src2;
  417.   int flags1=mod->flags1;
  418.   int flags2=mod->flags2;
  419.   fluid_real_t amount=(fluid_real_t)mod->amount;
  420.   printf("Src: ");
  421.   if (flags1 & FLUID_MOD_CC){
  422.     printf("MIDI CC=%i",src1);
  423.   } else {
  424.     switch(src1){
  425. case FLUID_MOD_NONE:
  426.   printf("None"); break;
  427. case FLUID_MOD_VELOCITY:
  428.   printf("note-on velocity"); break;
  429. case FLUID_MOD_KEY:
  430.   printf("Key nr"); break;
  431.   case FLUID_MOD_KEYPRESSURE:
  432.     printf("Poly pressure"); break;
  433. case FLUID_MOD_CHANNELPRESSURE:
  434.   printf("Chan pressure"); break;
  435. case FLUID_MOD_PITCHWHEEL:
  436.   printf("Pitch Wheel"); break;
  437. case FLUID_MOD_PITCHWHEELSENS:
  438.   printf("Pitch Wheel sens"); break;
  439. default:
  440.   printf("(unknown: %i)", src1);
  441.     }; /* switch src1 */
  442.   }; /* if not CC */
  443.   if (flags1 & FLUID_MOD_NEGATIVE){printf("- ");} else {printf("+ ");};
  444.   if (flags1 & FLUID_MOD_BIPOLAR){printf("bip ");} else {printf("unip ");};
  445.   printf("-> ");
  446.   switch(dest){
  447.       case GEN_FILTERQ: printf("Q"); break;
  448.       case GEN_FILTERFC: printf("fc"); break;
  449.       case GEN_VIBLFOTOPITCH: printf("VibLFO-to-pitch"); break;
  450.       case GEN_MODENVTOPITCH: printf("ModEnv-to-pitch"); break;
  451.       case GEN_MODLFOTOPITCH: printf("ModLFO-to-pitch"); break;
  452.       case GEN_CHORUSSEND: printf("Chorus send"); break;
  453.       case GEN_REVERBSEND: printf("Reverb send"); break;
  454.       case GEN_PAN: printf("pan"); break;
  455.       case GEN_ATTENUATION: printf("att"); break;
  456.       default: printf("dest %i",dest);
  457.   }; /* switch dest */
  458.   printf(", amount %f flags %i src2 %i flags2 %in",amount, flags1, src2, flags2);
  459. };