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