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

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_conv.h"
  21. /* conversion tables */
  22. fluid_real_t fluid_ct2hz_tab[FLUID_CENTS_HZ_SIZE];
  23. fluid_real_t fluid_cb2amp_tab[FLUID_CB_AMP_SIZE];
  24. fluid_real_t fluid_atten2amp_tab[FLUID_ATTEN_AMP_SIZE];
  25. fluid_real_t fluid_posbp_tab[128];
  26. fluid_real_t fluid_concave_tab[128];
  27. fluid_real_t fluid_convex_tab[128];
  28. fluid_real_t fluid_pan_tab[FLUID_PAN_SIZE];
  29. /*
  30.  * void fluid_synth_init
  31.  *
  32.  * Does all the initialization for this module.
  33.  */
  34. void
  35. fluid_conversion_config(void)
  36. {
  37.   int i;
  38.   double x;
  39.   for (i = 0; i < FLUID_CENTS_HZ_SIZE; i++) {
  40.     fluid_ct2hz_tab[i] = (fluid_real_t) pow(2.0, (double) i / 1200.0);
  41.   }
  42.   /* centibels to amplitude conversion
  43.    * Note: SF2.01 section 8.1.3: Initial attenuation range is
  44.    * between 0 and 144 dB. Therefore a negative attenuation is
  45.    * not allowed.
  46.    */
  47.   for (i = 0; i < FLUID_CB_AMP_SIZE; i++) {
  48.     fluid_cb2amp_tab[i] = (fluid_real_t) pow(10.0, (double) i / -200.0);
  49.   }
  50.   /* NOTE: EMU8k and EMU10k devices don't conform to the SoundFont
  51.    * specification in regards to volume attenuation.  The below calculation
  52.    * is an approx. equation for generating a table equivelant to the
  53.    * cb_to_amp_table[] in tables.c of the TiMidity++ source, which I'm told
  54.    * was generated from device testing.  By the spec this should be centibels.
  55.    */
  56.   for (i = 0; i < FLUID_ATTEN_AMP_SIZE; i++) {
  57.     fluid_atten2amp_tab[i] = (fluid_real_t) pow(10.0, (double) i / FLUID_ATTEN_POWER_FACTOR);
  58.   }
  59.   /* initialize the conversion tables (see fluid_mod.c
  60.      fluid_mod_get_value cases 4 and 8) */
  61.   /* concave unipolar positive transform curve */
  62.   fluid_concave_tab[0] = 0.0;
  63.   fluid_concave_tab[127] = 1.0;
  64.   /* convex unipolar positive transform curve */
  65.   fluid_convex_tab[0] = 0;
  66.   fluid_convex_tab[127] = 1.0;
  67.   x = log10(128.0 / 127.0);
  68.   /* There seems to be an error in the specs. The equations are
  69.      implemented according to the pictures on SF2.01 page 73. */
  70.   for (i = 1; i < 127; i++) {
  71.     x = -20.0 / 96.0 * log((i * i) / (127.0 * 127.0)) / log(10.0);
  72.     fluid_convex_tab[i] = (fluid_real_t) (1.0 - x);
  73.     fluid_concave_tab[127 - i] = (fluid_real_t) x;
  74.   }
  75.   /* initialize the pan conversion table */
  76.   x = PI / 2.0 / (FLUID_PAN_SIZE - 1.0);
  77.   for (i = 0; i < FLUID_PAN_SIZE; i++) {
  78.     fluid_pan_tab[i] = (fluid_real_t) sin(i * x);
  79.   }
  80. }
  81. /*
  82.  * fluid_ct2hz
  83.  */
  84. fluid_real_t
  85. fluid_ct2hz_real(fluid_real_t cents)
  86. {
  87.   if (cents < 0)
  88.     return (fluid_real_t) 1.0;
  89.   else if (cents < 900) {
  90.     return (fluid_real_t) 6.875 * fluid_ct2hz_tab[(int) (cents + 300)];
  91.   } else if (cents < 2100) {
  92.     return (fluid_real_t) 13.75 * fluid_ct2hz_tab[(int) (cents - 900)];
  93.   } else if (cents < 3300) {
  94.     return (fluid_real_t) 27.5 * fluid_ct2hz_tab[(int) (cents - 2100)];
  95.   } else if (cents < 4500) {
  96.     return (fluid_real_t) 55.0 * fluid_ct2hz_tab[(int) (cents - 3300)];
  97.   } else if (cents < 5700) {
  98.     return (fluid_real_t) 110.0 * fluid_ct2hz_tab[(int) (cents - 4500)];
  99.   } else if (cents < 6900) {
  100.     return (fluid_real_t) 220.0 * fluid_ct2hz_tab[(int) (cents - 5700)];
  101.   } else if (cents < 8100) {
  102.     return (fluid_real_t) 440.0 * fluid_ct2hz_tab[(int) (cents - 6900)];
  103.   } else if (cents < 9300) {
  104.     return (fluid_real_t) 880.0 * fluid_ct2hz_tab[(int) (cents - 8100)];
  105.   } else if (cents < 10500) {
  106.     return (fluid_real_t) 1760.0 * fluid_ct2hz_tab[(int) (cents - 9300)];
  107.   } else if (cents < 11700) {
  108.     return (fluid_real_t) 3520.0 * fluid_ct2hz_tab[(int) (cents - 10500)];
  109.   } else if (cents < 12900) {
  110.     return (fluid_real_t) 7040.0 * fluid_ct2hz_tab[(int) (cents - 11700)];
  111.   } else if (cents < 14100) {
  112.     return (fluid_real_t) 14080.0 * fluid_ct2hz_tab[(int) (cents - 12900)];
  113.   } else {
  114.     return (fluid_real_t) 1.0; /* some loony trying to make you deaf */
  115.   }
  116. }
  117. /*
  118.  * fluid_ct2hz
  119.  */
  120. fluid_real_t
  121. fluid_ct2hz(fluid_real_t cents)
  122. {
  123.   /* Filter fc limit: SF2.01 page 48 # 8 */
  124.   if (cents >= 13500){
  125.     cents = 13500;             /* 20 kHz */
  126.   } else if (cents < 1500){
  127.     cents = 1500;              /* 20 Hz */
  128.   }
  129.   return fluid_ct2hz_real(cents);
  130. }
  131. /*
  132.  * fluid_cb2amp
  133.  *
  134.  * in: a value between 0 and 960, 0 is no attenuation
  135.  * out: a value between 1 and 0
  136.  */
  137. fluid_real_t
  138. fluid_cb2amp(fluid_real_t cb)
  139. {
  140.   /*
  141.    * cb: an attenuation in 'centibels' (1/10 dB)
  142.    * SF2.01 page 49 # 48 limits it to 144 dB.
  143.    * 96 dB is reasonable for 16 bit systems, 144 would make sense for 24 bit.
  144.    */
  145.   /* minimum attenuation: 0 dB */
  146.   if (cb < 0) {
  147.     return 1.0;
  148.   }
  149.   if (cb >= FLUID_CB_AMP_SIZE) {
  150.     return 0.0;
  151.   }
  152.   return fluid_cb2amp_tab[(int) cb];
  153. }
  154. /*
  155.  * fluid_atten2amp
  156.  *
  157.  * in: a value between 0 and 1440, 0 is no attenuation
  158.  * out: a value between 1 and 0
  159.  *
  160.  * Note: Volume attenuation is supposed to be centibels but EMU8k/10k don't
  161.  * follow this.  Thats the reason for separate fluid_cb2amp and fluid_atten2amp.
  162.  */
  163. fluid_real_t
  164. fluid_atten2amp(fluid_real_t atten)
  165. {
  166.   if (atten < 0) return 1.0;
  167.   else if (atten >= FLUID_ATTEN_AMP_SIZE) return 0.0;
  168.   else return fluid_atten2amp_tab[(int) atten];
  169. }
  170. /*
  171.  * fluid_tc2sec_delay
  172.  */
  173. fluid_real_t
  174. fluid_tc2sec_delay(fluid_real_t tc)
  175. {
  176.   /* SF2.01 section 8.1.2 items 21, 23, 25, 33
  177.    * SF2.01 section 8.1.3 items 21, 23, 25, 33
  178.    *
  179.    * The most negative number indicates a delay of 0. Range is limited
  180.    * from -12000 to 5000 */
  181.   if (tc <= -32768.0f) {
  182.   return (fluid_real_t) 0.0f;
  183.   };
  184.   if (tc < -12000.) {
  185.   tc = (fluid_real_t) -12000.0f;
  186.   }
  187.   if (tc > 5000.0f) {
  188.   tc = (fluid_real_t) 5000.0f;
  189.   }
  190.   return (fluid_real_t) pow(2.0, (double) tc / 1200.0);
  191. }
  192. /*
  193.  * fluid_tc2sec_attack
  194.  */
  195. fluid_real_t
  196. fluid_tc2sec_attack(fluid_real_t tc)
  197. {
  198.   /* SF2.01 section 8.1.2 items 26, 34
  199.    * SF2.01 section 8.1.3 items 26, 34
  200.    * The most negative number indicates a delay of 0
  201.    * Range is limited from -12000 to 8000 */
  202.   if (tc<=-32768.){return (fluid_real_t) 0.0;};
  203.   if (tc<-12000.){tc=(fluid_real_t) -12000.0;};
  204.   if (tc>8000.){tc=(fluid_real_t) 8000.0;};
  205.   return (fluid_real_t) pow(2.0, (double) tc / 1200.0);
  206. }
  207. /*
  208.  * fluid_tc2sec
  209.  */
  210. fluid_real_t
  211. fluid_tc2sec(fluid_real_t tc)
  212. {
  213.   /* No range checking here! */
  214.   return (fluid_real_t) pow(2.0, (double) tc / 1200.0);
  215. }
  216. /*
  217.  * fluid_tc2sec_release
  218.  */
  219. fluid_real_t
  220. fluid_tc2sec_release(fluid_real_t tc)
  221. {
  222.   /* SF2.01 section 8.1.2 items 30, 38
  223.    * SF2.01 section 8.1.3 items 30, 38
  224.    * No 'most negative number' rule here!
  225.    * Range is limited from -12000 to 8000 */
  226.   if (tc<=-32768.){return (fluid_real_t) 0.0;};
  227.   if (tc<-12000.){tc=(fluid_real_t) -12000.0;};
  228.   if (tc>8000.){tc=(fluid_real_t) 8000.0;};
  229.   return (fluid_real_t) pow(2.0, (double) tc / 1200.0);
  230. }
  231. /*
  232.  * fluid_act2hz
  233.  *
  234.  * Convert from absolute cents to Hertz
  235.  */
  236. fluid_real_t
  237. fluid_act2hz(fluid_real_t c)
  238. {
  239.   return (fluid_real_t) (8.176 * pow(2.0, (double) c / 1200.0));
  240. }
  241. /*
  242.  * fluid_hz2ct
  243.  *
  244.  * Convert from Hertz to cents
  245.  */
  246. fluid_real_t
  247. fluid_hz2ct(fluid_real_t f)
  248. {
  249.   return (fluid_real_t) (6900 + 1200 * log(f / 440.0) / log(2.0));
  250. }
  251. /*
  252.  * fluid_pan
  253.  */
  254. fluid_real_t
  255. fluid_pan(fluid_real_t c, int left)
  256. {
  257.   if (left) {
  258.     c = -c;
  259.   }
  260.   if (c < -500) {
  261.     return (fluid_real_t) 0.0;
  262.   } else if (c > 500) {
  263.     return (fluid_real_t) 1.0;
  264.   } else {
  265.     return fluid_pan_tab[(int) (c + 500)];
  266.   }
  267. }
  268. /*
  269.  * fluid_concave
  270.  */
  271. fluid_real_t
  272. fluid_concave(fluid_real_t val)
  273. {
  274.   if (val < 0) {
  275.     return 0;
  276.   } else if (val > 127) {
  277.     return 1;
  278.   }
  279.   return fluid_concave_tab[(int) val];
  280. }
  281. /*
  282.  * fluid_convex
  283.  */
  284. fluid_real_t
  285. fluid_convex(fluid_real_t val)
  286. {
  287.   if (val < 0) {
  288.     return 0;
  289.   } else if (val > 127) {
  290.     return 1;
  291.   }
  292.   return fluid_convex_tab[(int) val];
  293. }