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 #include <stdio.h>
21 #include <string.h>
22 #include <glib.h>
23 #include <glib-object.h>
24
25 #include "IpatchSF2VoiceCache_DLS.h"
26 #include "IpatchConverter.h"
27 #include "IpatchConverterSF2VoiceCache.h"
28 #include "IpatchConverter_priv.h"
29
30 #include "IpatchDLS2Inst.h"
31 #include "IpatchDLS2Region.h"
32 #include "IpatchDLS2Sample.h"
33 #include "IpatchSF2VoiceCache.h"
34 #include "IpatchSample.h"
35
36 /**
37 * _ipatch_sf2_voice_cache_init_DLS: (skip)
38 */
39 void
_ipatch_sf2_voice_cache_init_DLS(void)40 _ipatch_sf2_voice_cache_init_DLS(void)
41 {
42 g_type_class_ref(IPATCH_TYPE_CONVERTER_DLS2_INST_TO_SF2_VOICE_CACHE);
43 g_type_class_ref(IPATCH_TYPE_CONVERTER_DLS2_REGION_TO_SF2_VOICE_CACHE);
44 g_type_class_ref(IPATCH_TYPE_CONVERTER_DLS2_SAMPLE_TO_SF2_VOICE_CACHE);
45
46 ipatch_register_converter_map
47 (IPATCH_TYPE_CONVERTER_DLS2_INST_TO_SF2_VOICE_CACHE, 0, 0,
48 IPATCH_TYPE_DLS2_INST, 0, 1, IPATCH_TYPE_SF2_VOICE_CACHE, 0, 1);
49 ipatch_register_converter_map
50 (IPATCH_TYPE_CONVERTER_DLS2_REGION_TO_SF2_VOICE_CACHE, 0, 0,
51 IPATCH_TYPE_DLS2_REGION, 0, 1, IPATCH_TYPE_SF2_VOICE_CACHE, 0, 1);
52 ipatch_register_converter_map
53 (IPATCH_TYPE_CONVERTER_DLS2_SAMPLE_TO_SF2_VOICE_CACHE, 0, 0,
54 IPATCH_TYPE_DLS2_SAMPLE, 0, 1, IPATCH_TYPE_SF2_VOICE_CACHE, 0, 1);
55 }
56
57 static gboolean
_dls2_inst_to_sf2_voice_cache_convert(IpatchConverter * converter,GError ** err)58 _dls2_inst_to_sf2_voice_cache_convert(IpatchConverter *converter, GError **err)
59 {
60 IpatchDLS2Inst *inst;
61 IpatchSF2VoiceCache *cache;
62 IpatchSF2Voice *voice;
63 IpatchDLS2Region *region;
64 IpatchDLS2Sample *sample;
65 IpatchDLS2SampleInfo *sample_info;
66 IpatchItem *solo_item;
67 GObject *obj;
68 GSList *p;
69 int looptype;
70
71 obj = IPATCH_CONVERTER_INPUT(converter);
72 cache = IPATCH_SF2_VOICE_CACHE(IPATCH_CONVERTER_OUTPUT(converter));
73 solo_item = ((IpatchConverterSF2VoiceCache *)converter)->solo_item;
74
75 /* check if its an instrument or a region */
76 if(IPATCH_IS_DLS2_REGION(obj)) /* ++ ref parent instrument */
77 {
78 inst = IPATCH_DLS2_INST(ipatch_item_get_parent(IPATCH_ITEM(obj)));
79 }
80 else
81 {
82 inst = IPATCH_DLS2_INST(obj);
83 }
84
85 ipatch_sf2_voice_cache_declare_item(cache, (GObject *)inst);
86
87 IPATCH_ITEM_RLOCK(inst); /* ++ LOCK instrument */
88
89 for(p = inst->regions; p; p = p->next)
90 {
91 region = (IpatchDLS2Region *)(p->data);
92
93 if(solo_item && (IpatchItem *)region != solo_item)
94 {
95 continue;
96 }
97
98 ipatch_sf2_voice_cache_declare_item(cache, (GObject *)region);
99
100 voice = ipatch_sf2_voice_cache_add_voice(cache);
101
102 IPATCH_ITEM_RLOCK(region); /* ++ LOCK region */
103
104 /* convert DLS parameters to SoundFont generator array and modulators */
105 // ipatch_dls2_region_load_sf2_gen_mods (region, &voice->gen_array,
106 // &voice->mod_list);
107
108 voice->mod_list = ipatch_sf2_mod_list_override(cache->default_mods,
109 cache->override_mods, TRUE);
110
111 /* set MIDI note and velocity ranges */
112 ipatch_sf2_voice_cache_set_voice_range(cache, voice, 0,
113 region->note_range_low, region->note_range_high);
114 ipatch_sf2_voice_cache_set_voice_range(cache, voice, 1,
115 region->velocity_range_low, region->velocity_range_high);
116
117 sample = (IpatchDLS2Sample *)(region->sample);
118 ipatch_sf2_voice_cache_declare_item(cache, (GObject *)sample);
119
120 ipatch_sf2_voice_set_sample_data(voice, sample->sample_data);
121
122 voice->rate = sample->rate;
123
124 if(region->sample_info)
125 {
126 sample_info = region->sample_info;
127 }
128 else
129 {
130 sample_info = sample->sample_info;
131 }
132
133 if(sample_info)
134 {
135 voice->loop_start = sample_info->loop_start;
136 voice->loop_end = sample_info->loop_end;
137 voice->root_note = sample_info->root_note;
138 voice->fine_tune = (guint8)sample_info->fine_tune;
139
140 switch(sample_info->options & IPATCH_DLS2_SAMPLE_LOOP_MASK)
141 {
142 case IPATCH_SAMPLE_LOOP_NONE:
143 looptype = IPATCH_SF2_GEN_SAMPLE_MODE_NOLOOP;
144 break;
145
146 case IPATCH_SAMPLE_LOOP_RELEASE:
147 looptype = IPATCH_SF2_GEN_SAMPLE_MODE_LOOP_RELEASE;
148 break;
149
150 default: /* default to standard loop */
151 looptype = IPATCH_SF2_GEN_SAMPLE_MODE_LOOP;
152 break;
153 }
154
155 /* set loop mode */
156 voice->gen_array.values[IPATCH_SF2_GEN_SAMPLE_MODES].sword = looptype;
157 IPATCH_SF2_GEN_ARRAY_SET_FLAG(&voice->gen_array,
158 IPATCH_SF2_GEN_SAMPLE_MODES);
159 }
160
161 IPATCH_ITEM_RUNLOCK(region); /* -- UNLOCK region */
162 }
163
164 IPATCH_ITEM_RUNLOCK(inst); /* -- UNLOCK instrument */
165
166 /* if convert object was region, unref parent instrument */
167 if((void *)obj != (void *)inst)
168 {
169 g_object_unref(inst); /* -- unref parent instrument */
170 }
171
172 return (TRUE);
173 }
174
175 /* use the instrument converter for regions also */
176 #define _dls2_region_to_sf2_voice_cache_convert \
177 _dls2_inst_to_sf2_voice_cache_convert
178
179 /**
180 * _dls2_sample_to_sf2_voice_cache_convert: (skip)
181 *
182 * DLS2Sample voice cache converter - Not declared static, since used by
183 * IpatchSF2VoiceCache_Gig.c
184 */
185 gboolean
_dls2_sample_to_sf2_voice_cache_convert(IpatchConverter * converter,GError ** err)186 _dls2_sample_to_sf2_voice_cache_convert(IpatchConverter *converter,
187 GError **err)
188 {
189 IpatchDLS2Sample *sample;
190 IpatchSF2VoiceCache *cache;
191 IpatchSF2Voice *voice;
192 IpatchSF2GenAmount *amt;
193 int loopmode;
194
195 sample = IPATCH_DLS2_SAMPLE(IPATCH_CONVERTER_INPUT(converter));
196 cache = IPATCH_SF2_VOICE_CACHE(IPATCH_CONVERTER_OUTPUT(converter));
197
198 ipatch_sf2_voice_cache_declare_item(cache, (GObject *)sample);
199
200 voice = ipatch_sf2_voice_cache_add_voice(cache);
201 voice->mod_list = ipatch_sf2_mod_list_duplicate(cache->default_mods);
202
203 /* set MIDI note and velocity ranges */
204 amt = &voice->gen_array.values[IPATCH_SF2_GEN_NOTE_RANGE];
205 ipatch_sf2_voice_cache_set_voice_range(cache, voice, 0,
206 amt->range.low, amt->range.high);
207 amt = &voice->gen_array.values[IPATCH_SF2_GEN_VELOCITY_RANGE];
208 ipatch_sf2_voice_cache_set_voice_range(cache, voice, 1,
209 amt->range.low, amt->range.high);
210
211 voice->mod_list = ipatch_sf2_mod_list_override(cache->default_mods,
212 cache->override_mods, TRUE);
213
214 ipatch_sf2_voice_set_sample_data(voice, sample->sample_data);
215
216 voice->rate = sample->rate;
217
218 if(sample->sample_info)
219 {
220 voice->loop_start = sample->sample_info->loop_start;
221 voice->loop_end = sample->sample_info->loop_end;
222 voice->root_note = sample->sample_info->root_note;
223 voice->fine_tune = (guint8)sample->sample_info->fine_tune;
224
225 switch(sample->sample_info->options & IPATCH_DLS2_SAMPLE_LOOP_MASK)
226 {
227 case IPATCH_SAMPLE_LOOP_NONE:
228 loopmode = IPATCH_SF2_GEN_SAMPLE_MODE_NOLOOP;
229 break;
230
231 case IPATCH_SAMPLE_LOOP_RELEASE:
232 loopmode = IPATCH_SF2_GEN_SAMPLE_MODE_LOOP_RELEASE;
233 break;
234
235 default: /* default to standard loop */
236 loopmode = IPATCH_SF2_GEN_SAMPLE_MODE_LOOP;
237 break;
238 }
239
240 /* set loop mode */
241 voice->gen_array.values[IPATCH_SF2_GEN_SAMPLE_MODES].sword = loopmode;
242 IPATCH_SF2_GEN_ARRAY_SET_FLAG(&voice->gen_array,
243 IPATCH_SF2_GEN_SAMPLE_MODES);
244 }
245
246 return (TRUE);
247 }
248
249 CONVERTER_CLASS_INIT(dls2_inst_to_sf2_voice_cache)
250 CONVERTER_CLASS_INIT(dls2_region_to_sf2_voice_cache)
251 CONVERTER_CLASS_INIT(dls2_sample_to_sf2_voice_cache)
252
253 CONVERTER_SF2_VOICE_CACHE_GET_TYPE(dls2_inst_to_sf2_voice_cache, DLS2InstToSF2VoiceCache)
254 CONVERTER_SF2_VOICE_CACHE_GET_TYPE(dls2_region_to_sf2_voice_cache, DLS2RegionToSF2VoiceCache)
255 CONVERTER_SF2_VOICE_CACHE_GET_TYPE(dls2_sample_to_sf2_voice_cache, DLS2SampleToSF2VoiceCache)
256