1 /*
2  * libInstPatch
3  * Copyright (C) 1999-2014 Element Green <element@elementsofsound.org>
4  *
5  * Author of this file: (C) 2012 BALATON Zoltan <balaton@eik.bme.hu>
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public License
9  * as published by the Free Software Foundation; version 2.1
10  * of the License only.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20  * 02110-1301, USA or on the web at http://www.gnu.org.
21  */
22 /**
23  * SECTION: IpatchConvert_SLI
24  * @short_description: Spectralis conversion handlers
25  * @see_also: #IpatchConverter
26  *
27  * Conversion handlers for Spectralis objects.
28  */
29 #include <stdio.h>
30 #include <string.h>
31 #include <glib.h>
32 #include <glib-object.h>
33 #include "misc.h"
34 #include "IpatchConvert_SLI.h"
35 #include "IpatchConverter.h"
36 #include "IpatchConverter_priv.h"
37 #include "IpatchSndFile.h"
38 #include "IpatchSLI.h"
39 #include "IpatchSLIWriter.h"
40 #include "IpatchSLIReader.h"
41 #include "IpatchSample.h"
42 #include "IpatchSampleData.h"
43 #include "IpatchSampleStoreSndFile.h"
44 #include "IpatchBase.h"
45 #include "IpatchFile.h"
46 #include "i18n.h"
47 
48 enum
49 {
50     PROP_0,
51     PROP_SLI_TO_FILE_CREATE_STORES
52 };
53 
54 /*
55  * Spectralis conversion handlers
56  * IpatchSLI <==> IpatchSLIFile
57  * IpatchSndFile => IpatchSLISample
58  */
59 
60 static void _sli_to_file_get_property(GObject *object, guint property_id,
61                                       GValue *value, GParamSpec *pspec);
62 static void _sli_to_file_set_property(GObject *object, guint property_id,
63                                       const GValue *value, GParamSpec *pspec);
64 
65 /**
66  * _ipatch_convert_SLI_init: (skip)
67  *
68  * Init routine for SLI conversion types
69  */
70 void
_ipatch_convert_SLI_init(void)71 _ipatch_convert_SLI_init(void)
72 {
73     g_type_class_ref(IPATCH_TYPE_CONVERTER_SLI_TO_FILE);
74     g_type_class_ref(IPATCH_TYPE_CONVERTER_FILE_TO_SLI);
75     g_type_class_ref(IPATCH_TYPE_CONVERTER_FILE_TO_SLI_SAMPLE);
76 
77     ipatch_register_converter_map(IPATCH_TYPE_CONVERTER_SLI_TO_FILE, 0, 0,
78                                   IPATCH_TYPE_SLI, 0, 1,
79                                   IPATCH_TYPE_SLI_FILE, IPATCH_TYPE_FILE, 1);
80     ipatch_register_converter_map(IPATCH_TYPE_CONVERTER_FILE_TO_SLI, 0, 0,
81                                   IPATCH_TYPE_SLI_FILE, 0, 1,
82                                   IPATCH_TYPE_SLI, IPATCH_TYPE_BASE, 0);
83     ipatch_register_converter_map(IPATCH_TYPE_CONVERTER_FILE_TO_SLI_SAMPLE, 0, 0,
84                                   IPATCH_TYPE_SND_FILE, 0, 1,
85                                   IPATCH_TYPE_SLI_SAMPLE, 0, 1);
86 }
87 
88 /* ===============
89  * Convert methods
90  * =============== */
91 
92 static gboolean
_sli_to_file_convert(IpatchConverter * converter,GError ** err)93 _sli_to_file_convert(IpatchConverter *converter, GError **err)
94 {
95     IpatchSLI *sli;
96     IpatchSLIFile *file;
97     IpatchFileHandle *handle;
98     IpatchSLIWriter *writer;
99     gboolean create_stores;
100     IpatchList *stores;
101     int retval;
102 
103     sli = IPATCH_SLI(IPATCH_CONVERTER_INPUT(converter));
104     file = IPATCH_SLI_FILE(IPATCH_CONVERTER_OUTPUT(converter));
105 
106     handle = ipatch_file_open(IPATCH_FILE(file), NULL, "w", err);
107 
108     if(!handle)
109     {
110         return (FALSE);
111     }
112 
113     writer = ipatch_sli_writer_new(handle, sli);  /* ++ ref new writer */
114     retval = ipatch_sli_writer_save(writer, err);
115 
116     g_object_get(converter, "create-stores", &create_stores, NULL);
117 
118     if(retval && create_stores)
119     {
120         /* ++ reference sample stores */
121         stores = ipatch_sli_writer_create_stores(writer);
122 
123         if(stores)
124         {
125             ipatch_converter_add_output(converter, G_OBJECT(stores));
126             g_object_unref(stores);  /* -- unref sample stores */
127         }
128     }
129 
130     g_object_unref(writer);  /* -- unref writer */
131 
132     return (retval);
133 }
134 
135 static gboolean
_file_to_sli_convert(IpatchConverter * converter,GError ** err)136 _file_to_sli_convert(IpatchConverter *converter, GError **err)
137 {
138     IpatchSLI *sli;
139     IpatchSLIFile *file;
140     IpatchFileHandle *handle;
141     IpatchSLIReader *reader;
142 
143     file = IPATCH_SLI_FILE(IPATCH_CONVERTER_INPUT(converter));
144 
145     handle = ipatch_file_open(IPATCH_FILE(file), NULL, "r", err);
146 
147     if(!handle)
148     {
149         return (FALSE);
150     }
151 
152     reader = ipatch_sli_reader_new(handle);  /* ++ ref new reader */
153     sli = ipatch_sli_reader_load(reader, err);  /* ++ ref loaded SLI object */
154     g_object_unref(reader);	/* -- unref reader */
155 
156     if(sli)
157     {
158         ipatch_converter_add_output(converter, G_OBJECT(sli));
159         g_object_unref(sli);	/* -- unref loaded SLI */
160         return (TRUE);
161     }
162     else
163     {
164         return (FALSE);
165     }
166 }
167 
168 static gboolean
_file_to_sli_sample_convert(IpatchConverter * converter,GError ** err)169 _file_to_sli_sample_convert(IpatchConverter *converter, GError **err)
170 {
171     IpatchSndFile *file;
172     IpatchSLISample *slisample;
173     IpatchSampleStoreSndFile *store;
174     IpatchSampleData *sampledata;
175     int format, rate, loop_type, root_note, fine_tune;
176     guint length, loop_start, loop_end;
177     char *filename, *title;
178 
179     file = IPATCH_SND_FILE(IPATCH_CONVERTER_INPUT(converter));
180     slisample = IPATCH_SLI_SAMPLE(IPATCH_CONVERTER_OUTPUT(converter));
181 
182     filename = ipatch_file_get_name(IPATCH_FILE(file));   /* ++ alloc file name */
183 
184     if(!filename)
185     {
186         g_set_error(err, IPATCH_ERROR, IPATCH_ERROR_PROGRAM,
187                     _("Sample file object must have a file name"));
188         return (FALSE);
189     }
190 
191     /* ++ ref store */
192     store = IPATCH_SAMPLE_STORE_SND_FILE(ipatch_sample_store_snd_file_new(filename));
193 
194     if(!ipatch_sample_store_snd_file_init_read(store))
195     {
196         g_set_error(err, IPATCH_ERROR, IPATCH_ERROR_UNSUPPORTED,
197                     _("Sample file '%s' is invalid or unsupported"), filename);
198         g_free(filename);     /* -- free filename */
199         g_object_unref(store);      /* -- unref store */
200         return (FALSE);
201     }
202 
203     g_free(filename);     /* -- free filename */
204 
205     g_object_get(store,
206                  "title", &title, /* ++ alloc title */
207                  "sample-size", &length,
208                  "sample-format", &format,
209                  "sample-rate", &rate,
210                  "loop-type", &loop_type,
211                  "loop-start", &loop_start,
212                  "loop-end", &loop_end,
213                  "root-note", &root_note,
214                  "fine-tune", &fine_tune,
215                  NULL);
216 
217     if(length < 4)
218     {
219         g_set_error(err, IPATCH_ERROR, IPATCH_ERROR_INVALID,
220                     _("Sample '%s' is too small"),
221                     title ? title : _("<no name>"));
222         goto bad;
223     }
224 
225     sampledata = ipatch_sample_data_new();  /* ++ ref sampledata */
226     ipatch_sample_data_add(sampledata, IPATCH_SAMPLE_STORE(store));
227     g_object_unref(store);  /* -- unref store */
228 
229     g_object_set(slisample,
230                  "name", title,
231                  "sample-data", sampledata,
232                  "sample-rate", rate,
233                  "root-note", (root_note != -1) ? root_note : 60,
234                  "fine-tune", fine_tune,
235                  "loop-start", loop_start,
236                  "loop-end", loop_end,
237                  NULL);
238 
239     g_object_unref(sampledata);   /* -- unref sampledata */
240     g_free(title);                /* -- free title */
241 
242     return (TRUE);
243 
244 bad:
245     g_free(title);              /* -- free title */
246     g_object_unref(store);      /* -- unref store */
247     return (FALSE);
248 }
249 
250 /* SLI -> File class is handled manually to install properties */
251 static void
_sli_to_file_class_init(IpatchConverterClass * klass)252 _sli_to_file_class_init(IpatchConverterClass *klass)
253 {
254     GObjectClass *obj_class = G_OBJECT_CLASS(klass);
255 
256     obj_class->get_property = _sli_to_file_get_property;
257     obj_class->set_property = _sli_to_file_set_property;
258 
259     klass->verify = NULL;
260     klass->notes = NULL;
261     klass->convert = _sli_to_file_convert;
262 
263     g_object_class_install_property(obj_class, PROP_SLI_TO_FILE_CREATE_STORES,
264                                     g_param_spec_boolean("create-stores",
265                                             "Create stores",
266                                             "Create sample stores",
267                                             FALSE,
268                                             G_PARAM_READWRITE));
269 }
270 
271 static void
_sli_to_file_get_property(GObject * object,guint property_id,GValue * value,GParamSpec * pspec)272 _sli_to_file_get_property(GObject *object, guint property_id,
273                           GValue *value, GParamSpec *pspec)
274 {
275     IpatchConverterSLIToFile *converter = (IpatchConverterSLIToFile *)object;
276 
277     switch(property_id)
278     {
279     case PROP_SLI_TO_FILE_CREATE_STORES:
280         g_value_set_boolean(value, converter->create_stores);
281         break;
282 
283     default:
284         G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
285         break;
286     }
287 }
288 
289 static void
_sli_to_file_set_property(GObject * object,guint property_id,const GValue * value,GParamSpec * pspec)290 _sli_to_file_set_property(GObject *object, guint property_id,
291                           const GValue *value, GParamSpec *pspec)
292 {
293     IpatchConverterSLIToFile *converter = (IpatchConverterSLIToFile *)object;
294 
295     switch(property_id)
296     {
297     case PROP_SLI_TO_FILE_CREATE_STORES:
298         converter->create_stores = g_value_get_boolean(value);
299         break;
300 
301     default:
302         G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
303         break;
304     }
305 }
306 
307 CONVERTER_CLASS_INIT(file_to_sli)
308 CONVERTER_CLASS_INIT(file_to_sli_sample)
309 
310 
311 CONVERTER_GET_TYPE(sli_to_file, SLIToFile)
312 CONVERTER_GET_TYPE(file_to_sli, FileToSLI)
313 CONVERTER_GET_TYPE(file_to_sli_sample, FileToSLISample)
314