1 /*
2  * libInstPatch
3  * Copyright (C) 1999-2014 Element Green <element@elementsofsound.org>
4  *
5  * This program 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; version 2.1
8  * of the License only.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
18  * 02110-1301, USA or on the web at http://www.gnu.org.
19  */
20 /**
21  * SECTION: IpatchUnit_SF2
22  * @short_description: Unit types and conversions for SoundFont
23  * @see_also:
24  * @stability: Stable
25  */
26 #include <stdio.h>
27 #include <math.h>
28 #include <glib.h>
29 #include <glib-object.h>
30 #include "IpatchUnit_SF2.h"
31 #include "IpatchUnit.h"
32 #include "i18n.h"
33 
34 
35 static void
36 ipatch_unit_sf2_abs_pitch_to_dls_abs_pitch_value(const GValue *src_val,
37         GValue *dest_val);
38 static void
39 ipatch_unit_dls_abs_pitch_to_sf2_abs_pitch_value(const GValue *src_val,
40         GValue *dest_val);
41 static void
42 ipatch_unit_sf2_abs_pitch_to_hertz_value(const GValue *src_val,
43         GValue *dest_val);
44 static void
45 ipatch_unit_hertz_to_sf2_abs_pitch_value(const GValue *src_val,
46         GValue *dest_val);
47 static void
48 ipatch_unit_sf2_abs_time_to_dls_abs_time_value(const GValue *src_val,
49         GValue *dest_val);
50 static void
51 ipatch_unit_dls_abs_time_to_sf2_abs_time_value(const GValue *src_val,
52         GValue *dest_val);
53 static void
54 ipatch_unit_sf2_abs_time_to_seconds_value(const GValue *src_val,
55         GValue *dest_val);
56 static void
57 ipatch_unit_seconds_to_sf2_abs_time_value(const GValue *src_val,
58         GValue *dest_val);
59 static void
60 ipatch_unit_centibels_to_dls_gain_value(const GValue *src_val,
61                                         GValue *dest_val);
62 static void
63 ipatch_unit_dls_gain_to_centibels_value(const GValue *src_val,
64                                         GValue *dest_val);
65 static void
66 ipatch_unit_centibels_to_decibels_value(const GValue *src_val,
67                                         GValue *dest_val);
68 static void
69 ipatch_unit_decibels_to_centibels_value(const GValue *src_val,
70                                         GValue *dest_val);
71 static void
72 ipatch_unit_tenth_percent_to_percent_value(const GValue *src_val,
73         GValue *dest_val);
74 static void
75 ipatch_unit_percent_to_tenth_percent_value(const GValue *src_val,
76         GValue *dest_val);
77 
78 
79 /**
80  * _ipatch_unit_sf2_init: (skip)
81  */
82 void
_ipatch_unit_sf2_init(void)83 _ipatch_unit_sf2_init(void)
84 {
85     IpatchUnitInfo *info;
86 
87     info = ipatch_unit_info_new();
88     info->digits = 0;
89     info->label = NULL;
90     info->descr = NULL;
91     info->value_type = G_TYPE_INT;
92 
93     /* FIXME - SoundFont absolute pitch is the same as cents.. */
94     info->id = IPATCH_UNIT_TYPE_SF2_ABS_PITCH;
95     info->name = "SF2AbsPitch";
96     ipatch_unit_register(info);
97 
98     info->id = IPATCH_UNIT_TYPE_SF2_OFS_PITCH;
99     info->name = "SF2OfsPitch";
100     ipatch_unit_register(info);
101 
102     info->id = IPATCH_UNIT_TYPE_SF2_ABS_TIME;
103     info->name = "SF2AbsTime";
104     ipatch_unit_register(info);
105 
106     info->id = IPATCH_UNIT_TYPE_SF2_OFS_TIME;
107     info->name = "SF2OfsTime";
108     ipatch_unit_register(info);
109 
110     info->id = IPATCH_UNIT_TYPE_CENTIBELS;
111     info->flags = IPATCH_UNIT_LOGARITHMIC;
112     info->name = "Centibels";
113     ipatch_unit_register(info);
114     info->flags = 0;
115 
116     info->id = IPATCH_UNIT_TYPE_32K_SAMPLES;
117     info->name = "32kSamples";
118     ipatch_unit_register(info);
119 
120     info->id = IPATCH_UNIT_TYPE_TENTH_PERCENT;
121     info->name = "TenthPercent";
122     ipatch_unit_register(info);
123 
124     ipatch_unit_info_free(info);	/* done with info structure, free it */
125 
126     /* SF2 absolute pitch <==> DLS absolute pitch */
127     ipatch_unit_conversion_register
128     (IPATCH_UNIT_TYPE_SF2_ABS_PITCH, IPATCH_UNIT_TYPE_DLS_ABS_PITCH,
129      ipatch_unit_sf2_abs_pitch_to_dls_abs_pitch_value);
130     ipatch_unit_conversion_register
131     (IPATCH_UNIT_TYPE_DLS_ABS_PITCH, IPATCH_UNIT_TYPE_SF2_ABS_PITCH,
132      ipatch_unit_dls_abs_pitch_to_sf2_abs_pitch_value);
133 
134     /* SF2 absolute pitch <==> Hertz */
135     ipatch_unit_conversion_register
136     (IPATCH_UNIT_TYPE_SF2_ABS_PITCH, IPATCH_UNIT_TYPE_HERTZ,
137      ipatch_unit_sf2_abs_pitch_to_hertz_value);
138     ipatch_unit_conversion_register
139     (IPATCH_UNIT_TYPE_HERTZ, IPATCH_UNIT_TYPE_SF2_ABS_PITCH,
140      ipatch_unit_hertz_to_sf2_abs_pitch_value);
141 
142     /* SF2 offset pitch <==> multiplier (reuse ABS time to seconds - same equation) */
143     ipatch_unit_conversion_register
144     (IPATCH_UNIT_TYPE_SF2_OFS_PITCH, IPATCH_UNIT_TYPE_MULTIPLIER,
145      ipatch_unit_sf2_abs_time_to_seconds_value);
146     ipatch_unit_conversion_register
147     (IPATCH_UNIT_TYPE_MULTIPLIER, IPATCH_UNIT_TYPE_SF2_OFS_PITCH,
148      ipatch_unit_seconds_to_sf2_abs_time_value);
149 
150     /* SF2 absolute time <==> DLS absolute time */
151     ipatch_unit_conversion_register
152     (IPATCH_UNIT_TYPE_SF2_ABS_TIME, IPATCH_UNIT_TYPE_DLS_ABS_TIME,
153      ipatch_unit_sf2_abs_time_to_dls_abs_time_value);
154     ipatch_unit_conversion_register
155     (IPATCH_UNIT_TYPE_DLS_ABS_TIME, IPATCH_UNIT_TYPE_SF2_ABS_TIME,
156      ipatch_unit_dls_abs_time_to_sf2_abs_time_value);
157 
158     /* SF2 absolute time <==> Seconds */
159     ipatch_unit_conversion_register
160     (IPATCH_UNIT_TYPE_SF2_ABS_TIME, IPATCH_UNIT_TYPE_SECONDS,
161      ipatch_unit_sf2_abs_time_to_seconds_value);
162     ipatch_unit_conversion_register
163     (IPATCH_UNIT_TYPE_SECONDS, IPATCH_UNIT_TYPE_SF2_ABS_TIME,
164      ipatch_unit_seconds_to_sf2_abs_time_value);
165 
166     /* SF2 offset time <==> multiplier (reuse ABS time to seconds - same equation)  */
167     ipatch_unit_conversion_register
168     (IPATCH_UNIT_TYPE_SF2_OFS_TIME, IPATCH_UNIT_TYPE_MULTIPLIER,
169      ipatch_unit_sf2_abs_time_to_seconds_value);
170     ipatch_unit_conversion_register
171     (IPATCH_UNIT_TYPE_MULTIPLIER, IPATCH_UNIT_TYPE_SF2_OFS_TIME,
172      ipatch_unit_seconds_to_sf2_abs_time_value);
173 
174     /* Centibels <==> DLS gain */
175     ipatch_unit_conversion_register
176     (IPATCH_UNIT_TYPE_CENTIBELS, IPATCH_UNIT_TYPE_DLS_GAIN,
177      ipatch_unit_centibels_to_dls_gain_value);
178     ipatch_unit_conversion_register
179     (IPATCH_UNIT_TYPE_DLS_GAIN, IPATCH_UNIT_TYPE_CENTIBELS,
180      ipatch_unit_dls_gain_to_centibels_value);
181 
182     /* Centibels <==> Decibels */
183     ipatch_unit_conversion_register
184     (IPATCH_UNIT_TYPE_CENTIBELS, IPATCH_UNIT_TYPE_DECIBELS,
185      ipatch_unit_centibels_to_decibels_value);
186     ipatch_unit_conversion_register
187     (IPATCH_UNIT_TYPE_DECIBELS, IPATCH_UNIT_TYPE_CENTIBELS,
188      ipatch_unit_decibels_to_centibels_value);
189 
190     /* TenthPercent <==> Percent */
191     ipatch_unit_conversion_register
192     (IPATCH_UNIT_TYPE_TENTH_PERCENT, IPATCH_UNIT_TYPE_PERCENT,
193      ipatch_unit_tenth_percent_to_percent_value);
194     ipatch_unit_conversion_register
195     (IPATCH_UNIT_TYPE_PERCENT, IPATCH_UNIT_TYPE_TENTH_PERCENT,
196      ipatch_unit_percent_to_tenth_percent_value);
197 
198     /* Register converter for IPATCH_UNIT_TYPE_SEMITONES and
199        IPATCH_UNIT_TYPE_CENTS. These mapping must be registered
200        in the unit domain IPATCH_UNIT_CLASS_USER.
201     */
202     /*  semitones => semitones */
203     ipatch_unit_class_register_map(IPATCH_UNIT_CLASS_USER,
204                                    IPATCH_UNIT_TYPE_SEMITONES,
205                                    IPATCH_UNIT_TYPE_SEMITONES);
206     ipatch_unit_conversion_register
207     (IPATCH_UNIT_TYPE_SEMITONES, IPATCH_UNIT_TYPE_SEMITONES,
208      NULL);
209 
210     /* Cents => Cents */
211     ipatch_unit_class_register_map (IPATCH_UNIT_CLASS_USER,
212                                     IPATCH_UNIT_TYPE_CENTS,
213                                     IPATCH_UNIT_TYPE_CENTS);
214     ipatch_unit_conversion_register
215     (IPATCH_UNIT_TYPE_CENTS, IPATCH_UNIT_TYPE_CENTS,
216      NULL);
217 
218     ipatch_unit_class_register_map(IPATCH_UNIT_CLASS_USER,
219                                    IPATCH_UNIT_TYPE_SF2_ABS_PITCH,
220                                    IPATCH_UNIT_TYPE_HERTZ);
221     ipatch_unit_class_register_map(IPATCH_UNIT_CLASS_DLS,
222                                    IPATCH_UNIT_TYPE_SF2_ABS_PITCH,
223                                    IPATCH_UNIT_TYPE_DLS_ABS_PITCH);
224     ipatch_unit_class_register_map(IPATCH_UNIT_CLASS_USER,
225                                    IPATCH_UNIT_TYPE_SF2_OFS_PITCH,
226                                    IPATCH_UNIT_TYPE_MULTIPLIER);
227 
228     ipatch_unit_class_register_map(IPATCH_UNIT_CLASS_USER,
229                                    IPATCH_UNIT_TYPE_SF2_ABS_TIME,
230                                    IPATCH_UNIT_TYPE_SECONDS);
231     ipatch_unit_class_register_map(IPATCH_UNIT_CLASS_DLS,
232                                    IPATCH_UNIT_TYPE_SF2_ABS_TIME,
233                                    IPATCH_UNIT_TYPE_DLS_ABS_TIME);
234     ipatch_unit_class_register_map(IPATCH_UNIT_CLASS_USER,
235                                    IPATCH_UNIT_TYPE_SF2_OFS_TIME,
236                                    IPATCH_UNIT_TYPE_MULTIPLIER);
237 
238     ipatch_unit_class_register_map(IPATCH_UNIT_CLASS_USER,
239                                    IPATCH_UNIT_TYPE_CENTIBELS,
240                                    IPATCH_UNIT_TYPE_DECIBELS);
241     ipatch_unit_class_register_map(IPATCH_UNIT_CLASS_DLS,
242                                    IPATCH_UNIT_TYPE_CENTIBELS,
243                                    IPATCH_UNIT_TYPE_DLS_GAIN);
244 
245     ipatch_unit_class_register_map(IPATCH_UNIT_CLASS_USER,
246                                    IPATCH_UNIT_TYPE_TENTH_PERCENT,
247                                    IPATCH_UNIT_TYPE_PERCENT);
248 }
249 
250 /**
251  * ipatch_unit_sf2_abs_pitch_to_dls_abs_pitch:
252  * @sf2_abs_pitch: Value in SF2 absolute pitch
253  *
254  * Converts a value from SF2 absolute pitch to DLS absolute pitch.
255  *
256  * sf2_abs_pitch = 1200 * log2(f/8.176)
257  * f = 8.176 * 2^(sf2_abs_pitch/1200)
258  *
259  * dls_abs_pitch = (1200 * log2(f/440) + 6900) * 65536
260  * f = 440 * 2^((dls_abs_pitch / 65536 - 6900) / 1200)
261  *
262  * Returns: Value converted to DLS absolute pitch
263  */
264 int
ipatch_unit_sf2_abs_pitch_to_dls_abs_pitch(int sf2_abs_pitch)265 ipatch_unit_sf2_abs_pitch_to_dls_abs_pitch(int sf2_abs_pitch)
266 {
267     double hz;
268 
269     hz = 8.176 * pow(2.0, ((double)sf2_abs_pitch) / 1200.0);
270     return (int)((1200.0 * (log(hz / 440.0) / log(2.0)) + 6900.0)
271                  * 65536.0 + 0.5);	/* +0.5 for rounding */
272 }
273 
274 /**
275  * ipatch_unit_dls_abs_pitch_to_sf2_abs_pitch:
276  * @dls_abs_pitch: Value in DLS absolute pitch
277  *
278  * Converts a value from DLS absolute pitch to SF2 absolute pitch.
279  * See ipatch_unit_sf2_abs_pitch_to_dls_abs_pitch()
280  *
281  * Returns: Value converted to SF2 absolute pitch
282  */
283 int
ipatch_unit_dls_abs_pitch_to_sf2_abs_pitch(int dls_abs_pitch)284 ipatch_unit_dls_abs_pitch_to_sf2_abs_pitch(int dls_abs_pitch)
285 {
286     double hz;
287 
288     hz = 440.0 * pow(2.0, (((double)dls_abs_pitch / 65536.0 - 6900.0)
289                            / 1200.0));
290     return (int)(1200.0 * (log(hz / 8.176) / log(2.0)) + 0.5);   /* +0.5 to round */
291 }
292 
293 /**
294  * ipatch_unit_sf2_abs_pitch_to_hertz:
295  * @sf2_abs_pitch: Value in SoundFont absolute pitch
296  *
297  * Convert SoundFont absolute pitch to frequency in Hertz.
298  *
299  * Returns: Value in Hertz (cycles per second)
300  */
301 double
ipatch_unit_sf2_abs_pitch_to_hertz(int sf2_abs_pitch)302 ipatch_unit_sf2_abs_pitch_to_hertz(int sf2_abs_pitch)
303 {
304     return (8.176 * pow(2.0, ((double)sf2_abs_pitch) / 1200.0));
305 }
306 
307 /**
308  * ipatch_unit_hertz_to_sf2_abs_pitch:
309  * @hz: Hertz (cycles per second) value
310  *
311  * Convert frequency in Hertz to SoundFont absolute pitch.
312  *
313  * Returns: Converted value in SoundFont absolute pitch.
314  */
315 int
ipatch_unit_hertz_to_sf2_abs_pitch(double hz)316 ipatch_unit_hertz_to_sf2_abs_pitch(double hz)
317 {
318     return (int)(log(hz / 8.176) / log(2) * 1200 + 0.5);   /* +0.5 for rounding */
319 }
320 
321 /**
322  * ipatch_unit_sf2_ofs_pitch_to_multiplier:
323  * @sf2_ofs_pitch: Value in SoundFont offset pitch
324  *
325  * Convert SoundFont offset pitch (cents) to multiplier factor.
326  *
327  * Returns: Multiplier factor
328  */
329 double
ipatch_unit_sf2_ofs_pitch_to_multiplier(int sf2_ofs_pitch)330 ipatch_unit_sf2_ofs_pitch_to_multiplier(int sf2_ofs_pitch)
331 {
332     return (pow(2.0, ((double)sf2_ofs_pitch) / 1200.0));
333 }
334 
335 /**
336  * ipatch_unit_multiplier_to_sf2_ofs_pitch:
337  * @multiplier: Multiplier factor
338  *
339  * Convert multiplier factor to SoundFont offset pitch (cents).
340  *
341  * Returns: Converted value in SoundFont offset pitch (cents).
342  */
343 int
ipatch_unit_multiplier_to_sf2_ofs_pitch(double multiplier)344 ipatch_unit_multiplier_to_sf2_ofs_pitch(double multiplier)
345 {
346     return (int)(log(multiplier) / log(2) * 1200 + 0.5);   /* +0.5 for rounding */
347 }
348 
349 /**
350  * ipatch_unit_sf2_abs_time_to_dls_abs_time:
351  * @sf2_abs_time: Value in SF2 absolute time (timecents)
352  *
353  * Convert a value from SF2 absolute time to DLS absolute time.
354  *
355  * sf2_abs_time = 1200 * log2 (seconds)
356  * seconds = 2^(sf2_abs_time / 1200)
357  *
358  * dls_abs_time = 1200 * log2 (seconds) * 65536
359  * seconds = 2^(dls_abs_time / (1200 * 65536))
360  *
361  * Returns: Value converted to DLS absolute time.
362  */
363 int
ipatch_unit_sf2_abs_time_to_dls_abs_time(int sf2_abs_time)364 ipatch_unit_sf2_abs_time_to_dls_abs_time(int sf2_abs_time)
365 {
366     return (sf2_abs_time * 65536);
367 }
368 
369 /**
370  * ipatch_unit_dls_abs_time_to_sf2_abs_time:
371  * @dls_abs_time: Value in DLS absolute time
372  *
373  * Convert a value from DLS absolute time to SF2 absolute time.
374  * See ipatch_unit_sf2_abs_time_to_dls_abs_time()
375  *
376  * Returns: Value converted to SF2 absolute time
377  */
378 int
ipatch_unit_dls_abs_time_to_sf2_abs_time(int dls_abs_time)379 ipatch_unit_dls_abs_time_to_sf2_abs_time(int dls_abs_time)
380 {
381     return ((dls_abs_time + 32768) / 65536); /* +32768 for rounding */
382 }
383 
384 /**
385  * ipatch_unit_sf2_abs_time_to_seconds:
386  * @sf2_abs_time: Value in SoundFont absolute time
387  *
388  * Convert a value from SoundFont absolute time (timecents) to seconds.
389  *
390  * Returns: Value in seconds
391  */
392 double
ipatch_unit_sf2_abs_time_to_seconds(int sf2_abs_time)393 ipatch_unit_sf2_abs_time_to_seconds(int sf2_abs_time)
394 {
395     return (pow(2.0, (double)sf2_abs_time / 1200.0));
396 }
397 
398 /**
399  * ipatch_unit_seconds_to_sf2_abs_time:
400  * @sec: Value in seconds
401  *
402  * Convert value from seconds to SoundFont absolute time (timecents).
403  *
404  * Returns: Value in SoundFont absolute time
405  */
406 int
ipatch_unit_seconds_to_sf2_abs_time(double sec)407 ipatch_unit_seconds_to_sf2_abs_time(double sec)
408 {
409     return (int)(log(sec) / log(2) * 1200 + 0.5);   /* +0.5 for rounding */
410 }
411 
412 /**
413  * ipatch_unit_sf2_ofs_time_to_multiplier:
414  * @sf2_ofs_time: Value in SoundFont offset time (timecents)
415  *
416  * Convert a value from SoundFont offset time (timecents) to a multiplier.
417  *
418  * Returns: Multiplier factor
419  */
420 double
ipatch_unit_sf2_ofs_time_to_multiplier(int sf2_ofs_time)421 ipatch_unit_sf2_ofs_time_to_multiplier(int sf2_ofs_time)
422 {
423     return (pow(2.0, (double)sf2_ofs_time / 1200.0));
424 }
425 
426 /**
427  * ipatch_unit_multiplier_to_sf2_ofs_time:
428  * @multiplier: Multiplier factor
429  *
430  * Convert value from a multiplier to SoundFont offset time (timecents).
431  *
432  * Returns: Value in SoundFont offset time (timecents)
433  */
434 int
ipatch_unit_multiplier_to_sf2_ofs_time(double multiplier)435 ipatch_unit_multiplier_to_sf2_ofs_time(double multiplier)
436 {
437     return (int)(log(multiplier) / log(2) * 1200 + 0.5);   /* +0.5 for rounding */
438 }
439 
440 /**
441  * ipatch_unit_centibels_to_dls_gain:
442  * @centibel: Value in centibels (10th of a Decibel)
443  *
444  * Convert a value from centibels to DLS gain (1/655360th of a dB).
445  *
446  * V = target amplitude, v = original amplitude
447  * centibel = 200 * log10 (v / V)
448  * dls_gain = 200 * 65536 * log10 (V / v)
449  *
450  * Returns: Value converted to DLS gain
451  */
452 int
ipatch_unit_centibels_to_dls_gain(int centibel)453 ipatch_unit_centibels_to_dls_gain(int centibel)
454 {
455     return (centibel * 65536);
456 }
457 
458 /**
459  * ipatch_unit_dls_gain_to_centibels:
460  * @dls_gain: Value in DLS gain (1/655360th of a dB)
461  *
462  * Convert a value from DLS gain to centibels.
463  *
464  * Returns: Value converted to centibels.
465  */
466 int
ipatch_unit_dls_gain_to_centibels(int dls_gain)467 ipatch_unit_dls_gain_to_centibels(int dls_gain)
468 {
469     return ((dls_gain + 32768) / 65536); /* +32768 for rounding */
470 }
471 
472 /**
473  * ipatch_unit_centibels_to_decibels:
474  * @cb: Value in Centibels (10th of a Decibel)
475  *
476  * Convert a value from Centibels to Decibels.
477  *
478  * Returns: Value in Decibels
479  */
480 double
ipatch_unit_centibels_to_decibels(int cb)481 ipatch_unit_centibels_to_decibels(int cb)
482 {
483     return ((double) cb / 10.0);
484 }
485 
486 /**
487  * ipatch_unit_decibels_to_centibels:
488  * @db: Value in Decibels
489  *
490  * Convert Decibels to Centibels (10ths of a dB)
491  *
492  * Returns: Converted value in Centibels (10ths of a Decibel)
493  */
494 int
ipatch_unit_decibels_to_centibels(double db)495 ipatch_unit_decibels_to_centibels(double db)
496 {
497     return (int)(db * 10.0 + 0.5);	/* +0.5 for rounding */
498 }
499 
500 /**
501  * ipatch_unit_tenth_percent_to_percent:
502  * @tenth_percent: Value in 10ths of a Percent (Percent * 10)
503  *
504  * Convert a value from 10ths of a Percent to Percent.
505  *
506  * Returns: Value in Percent
507  */
508 double
ipatch_unit_tenth_percent_to_percent(int tenth_percent)509 ipatch_unit_tenth_percent_to_percent(int tenth_percent)
510 {
511     return ((double) tenth_percent / 10.0);
512 }
513 
514 /**
515  * ipatch_unit_percent_to_tenth_percent:
516  * @percent: Value in Percent
517  *
518  * Convert Percent to 10ths of a Percent (Percent * 10)
519  *
520  * Returns: Converted value in 10ths of a Percent
521  */
522 int
ipatch_unit_percent_to_tenth_percent(double percent)523 ipatch_unit_percent_to_tenth_percent(double percent)
524 {
525     return (int)(percent * 10.0 + 0.5);	/* +0.5 for rounding */
526 }
527 
528 /* =================================================
529    GValue conversion functions, duplicated for speed
530    ================================================= */
531 
532 
533 static void
ipatch_unit_sf2_abs_pitch_to_dls_abs_pitch_value(const GValue * src_val,GValue * dest_val)534 ipatch_unit_sf2_abs_pitch_to_dls_abs_pitch_value(const GValue *src_val,
535         GValue *dest_val)
536 {
537     int sf2_abs_pitch = g_value_get_int(src_val);
538     int dls_abs_pitch;
539     double hz;
540 
541     hz = 8.176 * pow(2.0, ((double)sf2_abs_pitch) / 1200.0);
542     dls_abs_pitch = (int)((1200.0 * (log(hz / 440.0) / log(2.0)) + 6900.0)
543                           * 65536.0 + 0.5);
544     g_value_set_int(dest_val, dls_abs_pitch);
545 }
546 
547 static void
ipatch_unit_dls_abs_pitch_to_sf2_abs_pitch_value(const GValue * src_val,GValue * dest_val)548 ipatch_unit_dls_abs_pitch_to_sf2_abs_pitch_value(const GValue *src_val,
549         GValue *dest_val)
550 {
551     int dls_abs_pitch = g_value_get_int(src_val);
552     int sf2_abs_pitch;
553     double hz;
554 
555     hz = 440.0 * pow(2.0, (((double)dls_abs_pitch / 65536.0 - 6900.0)
556                            / 1200.0));
557     sf2_abs_pitch = (int)(1200.0 * (log(hz / 8.176) / log(2.0)) + 0.5);
558     g_value_set_int(dest_val, sf2_abs_pitch);
559 }
560 
561 static void
ipatch_unit_sf2_abs_pitch_to_hertz_value(const GValue * src_val,GValue * dest_val)562 ipatch_unit_sf2_abs_pitch_to_hertz_value(const GValue *src_val,
563         GValue *dest_val)
564 {
565     int sf2_abs_pitch = g_value_get_int(src_val);
566     g_value_set_double(dest_val, 8.176 * pow(2.0, ((double) sf2_abs_pitch)
567                        / 1200.0));
568 }
569 
570 static void
ipatch_unit_hertz_to_sf2_abs_pitch_value(const GValue * src_val,GValue * dest_val)571 ipatch_unit_hertz_to_sf2_abs_pitch_value(const GValue *src_val,
572         GValue *dest_val)
573 {
574     double hz = g_value_get_double(src_val);
575     g_value_set_int(dest_val, (gint)(log(hz / 8.176) / log(2) * 1200 + 0.5));
576 }
577 
578 static void
ipatch_unit_sf2_abs_time_to_dls_abs_time_value(const GValue * src_val,GValue * dest_val)579 ipatch_unit_sf2_abs_time_to_dls_abs_time_value(const GValue *src_val,
580         GValue *dest_val)
581 {
582     int sf2_abs_time = g_value_get_int(src_val);
583     g_value_set_int(dest_val, sf2_abs_time * 65536);
584 }
585 
586 static void
ipatch_unit_dls_abs_time_to_sf2_abs_time_value(const GValue * src_val,GValue * dest_val)587 ipatch_unit_dls_abs_time_to_sf2_abs_time_value(const GValue *src_val,
588         GValue *dest_val)
589 {
590     int dls_abs_time = g_value_get_int(src_val);
591     g_value_set_int(dest_val, (dls_abs_time + 32768) / 65536);
592 }
593 
594 static void
ipatch_unit_sf2_abs_time_to_seconds_value(const GValue * src_val,GValue * dest_val)595 ipatch_unit_sf2_abs_time_to_seconds_value(const GValue *src_val,
596         GValue *dest_val)
597 {
598     int sf2_abs_time = g_value_get_int(src_val);
599     g_value_set_double(dest_val, pow(2.0, (double)sf2_abs_time / 1200.0));
600 }
601 
602 static void
ipatch_unit_seconds_to_sf2_abs_time_value(const GValue * src_val,GValue * dest_val)603 ipatch_unit_seconds_to_sf2_abs_time_value(const GValue *src_val,
604         GValue *dest_val)
605 {
606     double sec = g_value_get_double(src_val);
607     g_value_set_int(dest_val, (gint)(log(sec) / log(2) * 1200 + 0.5));
608 }
609 
610 static void
ipatch_unit_centibels_to_dls_gain_value(const GValue * src_val,GValue * dest_val)611 ipatch_unit_centibels_to_dls_gain_value(const GValue *src_val,
612                                         GValue *dest_val)
613 {
614     int centibels = g_value_get_int(src_val);
615     g_value_set_int(dest_val, centibels * 65536);
616 }
617 
618 static void
ipatch_unit_dls_gain_to_centibels_value(const GValue * src_val,GValue * dest_val)619 ipatch_unit_dls_gain_to_centibels_value(const GValue *src_val,
620                                         GValue *dest_val)
621 {
622     int dls_gain = g_value_get_int(src_val);
623     g_value_set_int(dest_val, (dls_gain + 32768) / 65536);
624 }
625 
626 static void
ipatch_unit_centibels_to_decibels_value(const GValue * src_val,GValue * dest_val)627 ipatch_unit_centibels_to_decibels_value(const GValue *src_val,
628                                         GValue *dest_val)
629 {
630     int cb = g_value_get_int(src_val);
631     g_value_set_double(dest_val, (double)cb / 10.0);
632 }
633 
634 static void
ipatch_unit_decibels_to_centibels_value(const GValue * src_val,GValue * dest_val)635 ipatch_unit_decibels_to_centibels_value(const GValue *src_val,
636                                         GValue *dest_val)
637 {
638     double db = g_value_get_double(src_val);
639     g_value_set_int(dest_val, (gint)(db * 10.0 + 0.5));
640 }
641 
642 static void
ipatch_unit_tenth_percent_to_percent_value(const GValue * src_val,GValue * dest_val)643 ipatch_unit_tenth_percent_to_percent_value(const GValue *src_val,
644         GValue *dest_val)
645 {
646     int tenthperc = g_value_get_int(src_val);
647     g_value_set_double(dest_val, (double)tenthperc / 10.0);
648 }
649 
650 static void
ipatch_unit_percent_to_tenth_percent_value(const GValue * src_val,GValue * dest_val)651 ipatch_unit_percent_to_tenth_percent_value(const GValue *src_val,
652         GValue *dest_val)
653 {
654     double percent = g_value_get_double(src_val);
655     g_value_set_int(dest_val, (gint)(percent * 10.0 + 0.5));
656 }
657