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 "conv.h"
22 
23 namespace FluidS {
24 
25 /* conversion tables */
26 static float fluid_cb2amp_tab[FLUID_CB_AMP_SIZE];
27 static float fluid_atten2amp_tab[FLUID_ATTEN_AMP_SIZE];
28 static float fluid_concave_tab[128];
29 static float fluid_convex_tab[128];
30 static float fluid_pan_tab[FLUID_PAN_SIZE];
31 
32 /*
33  * void fluid_synth_init
34  *
35  * Does all the initialization for this module.
36  */
fluid_conversion_config()37 void fluid_conversion_config()
38       {
39       /* centibels to amplitude conversion
40        * Note: SF2.01 section 8.1.3: Initial attenuation range is
41        * between 0 and 144 dB. Therefore a negative attenuation is
42        * not allowed.
43        */
44       for (int i = 0; i < FLUID_CB_AMP_SIZE; i++)
45             fluid_cb2amp_tab[i] = (float) pow(10.0, (double) i / -200.0);
46 
47       /* NOTE: EMU8k and EMU10k devices don't conform to the SoundFont
48        * specification in regards to volume attenuation.  The below calculation
49        * is an approx. equation for generating a table equivalent to the
50        * cb_to_amp_table[] in tables.c of the TiMidity++ source, which I'm told
51        * was generated from device testing.  By the spec this should be centibels.
52        */
53       for (int i = 0; i < FLUID_ATTEN_AMP_SIZE; i++)
54             fluid_atten2amp_tab[i] = (float) pow(10.0, (double) i / FLUID_ATTEN_POWER_FACTOR);
55 
56       /* initialize the conversion tables (see fluid_mod.c
57          fluid_mod_get_value cases 4 and 8) */
58 
59       /* concave unipolar positive transform curve */
60       fluid_concave_tab[0] = 0.0;
61       fluid_concave_tab[127] = 1.0;
62 
63       /* convex unipolar positive transform curve */
64       fluid_convex_tab[0] = 0;
65       fluid_convex_tab[127] = 1.0;
66 
67       /* There seems to be an error in the specs. The equations are
68          implemented according to the pictures on SF2.01 page 73. */
69 
70       for (int i = 1; i < 127; i++) {
71             double x = -20.0 / 96.0 * log((i * i) / (127.0 * 127.0)) / log(10.0);
72             fluid_convex_tab[i] = (float) (1.0 - x);
73             fluid_concave_tab[127 - i] = (float) x;
74             }
75 
76       /* initialize the pan conversion table */
77       double x = M_PI / 2.0 / (FLUID_PAN_SIZE - 1.0);
78       for (int i = 0; i < FLUID_PAN_SIZE; i++)
79             fluid_pan_tab[i] = (float) sin(i * x);
80       }
81 
82 /*
83  * fluid_cb2amp
84  *
85  * in: a value between 0 and 960, 0 is no attenuation
86  * out: a value between 1 and 0
87  */
fluid_cb2amp(float cb)88 float fluid_cb2amp(float cb)
89       {
90       /*
91        * cb: an attenuation in 'centibels' (1/10 dB)
92        * SF2.01 page 49 # 48 limits it to 144 dB.
93        * 96 dB is reasonable for 16 bit systems, 144 would make sense for 24 bit.
94        */
95 
96       /* minimum attenuation: 0 dB */
97       if (cb < 0)
98             return 1.0;
99       if (cb >= FLUID_CB_AMP_SIZE)
100             return 0.0;
101       return fluid_cb2amp_tab[(int) cb];
102       }
103 
104 /*
105  * fluid_atten2amp
106  *
107  * in: a value between 0 and 1440, 0 is no attenuation
108  * out: a value between 1 and 0
109  *
110  * Note: Volume attenuation is supposed to be centibels but EMU8k/10k don't
111  * follow this.  That's the reason for separate fluid_cb2amp and fluid_atten2amp.
112  */
fluid_atten2amp(float atten)113 float fluid_atten2amp(float atten)
114       {
115       if (atten < 0)
116             return 1.0;
117       else if (atten >= FLUID_ATTEN_AMP_SIZE)
118             return 0.0;
119       else
120             return fluid_atten2amp_tab[(int) atten];
121       }
122 
123 /*
124  * fluid_tc2sec_delay
125  */
fluid_tc2sec_delay(float tc)126 float fluid_tc2sec_delay(float tc)
127       {
128       /* SF2.01 section 8.1.2 items 21, 23, 25, 33
129        * SF2.01 section 8.1.3 items 21, 23, 25, 33
130        *
131        * The most negative number indicates a delay of 0. Range is limited
132        * from -12000 to 5000
133        */
134       if (tc <= -32768.0f)
135             return (float) 0.0f;
136       if (tc < -12000.)
137             tc = (float) -12000.0f;
138       if (tc > 5000.0f)
139             tc = (float) 5000.0f;
140       return (float) pow(2.0, (double) tc / 1200.0);
141       }
142 
143 /*
144  * fluid_tc2sec_attack
145  */
fluid_tc2sec_attack(float tc)146 float fluid_tc2sec_attack(float tc)
147       {
148       /* SF2.01 section 8.1.2 items 26, 34
149       * SF2.01 section 8.1.3 items 26, 34
150       * The most negative number indicates a delay of 0
151       * Range is limited from -12000 to 8000 */
152       if (tc<=-32768.)
153             return (float) 0.0;
154       if (tc<-12000.)
155             tc=(float) -12000.0;
156       if (tc>8000.)
157             tc=(float) 8000.0;
158       return (float) pow(2.0, (double) tc / 1200.0);
159       }
160 
161 /*
162  * fluid_tc2sec
163  */
fluid_tc2sec(float tc)164 float fluid_tc2sec(float tc)
165       {
166       /* No range checking here! */
167       return (float) pow(2.0, (double) tc / 1200.0);
168       }
169 
170 /*
171  * fluid_tc2sec_release
172  */
fluid_tc2sec_release(float tc)173 float fluid_tc2sec_release(float tc)
174       {
175       /* SF2.01 section 8.1.2 items 30, 38
176        * SF2.01 section 8.1.3 items 30, 38
177        * No 'most negative number' rule here!
178        * Range is limited from -12000 to 8000
179        */
180       if (tc<=-32768.)
181             return (float) 0.0;
182       if (tc<-12000.)
183             tc=(float) -12000.0;
184       if (tc>8000.)
185             tc=(float) 8000.0;
186       return (float) pow(2.0, (double) tc / 1200.0);
187       }
188 
189 /*
190  * fluid_act2hz
191  *
192  * Convert from absolute cents to Hertz
193  */
fluid_act2hz(float c)194 float fluid_act2hz(float c)
195       {
196       return (float) (8.176 * pow(2.0, (double) c / 1200.0));
197       }
198 
199 /*
200  * fluid_pan
201  */
fluid_pan(float c,int left)202 float fluid_pan(float c, int left)
203       {
204       if (left)
205             c = -c;
206       if (c < -500)
207             return (float) 0.0;
208       else if (c > 500)
209             return (float) 1.0;
210       else
211             return fluid_pan_tab[(int) (c + 500)];
212       }
213 
214 /*
215  * fluid_concave
216  */
fluid_concave(float val)217 float fluid_concave(float val)
218       {
219       if (val < 0)
220             return 0;
221       else if (val > 127)
222             return 1;
223       return fluid_concave_tab[(int) val];
224       }
225 
226 /*
227  * fluid_convex
228  */
fluid_convex(float val)229 float fluid_convex(float val)
230       {
231       if (val < 0)
232             return 0;
233       else if (val > 127)
234             return 1;
235       return fluid_convex_tab[(int) val];
236       }
237 }
238 
239