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: IpatchGigDimension
22  * @short_description: GigaSampler dimension object
23  * @see_also: #IpatchGigInst
24  * @stability: Stable
25  *
26  * Defines a GigaSampler dimension object which are the children of
27  * #IpatchGigInst objects.
28  */
29 #include <glib.h>
30 #include <glib-object.h>
31 #include "IpatchGigDimension.h"
32 #include "IpatchRange.h"
33 #include "IpatchTypeProp.h"
34 #include "ipatch_priv.h"
35 #include "builtin_enums.h"
36 
37 enum
38 {
39     PROP_0,
40 
41     PROP_NAME,
42     PROP_TYPE,
43     PROP_SPLIT_COUNT
44 };
45 
46 static void ipatch_gig_dimension_class_init(IpatchGigDimensionClass *klass);
47 static void ipatch_gig_dimension_set_property(GObject *object,
48         guint property_id,
49         const GValue *value,
50         GParamSpec *pspec);
51 static void ipatch_gig_dimension_get_property(GObject *object,
52         guint property_id,
53         GValue *value,
54         GParamSpec *pspec);
55 
56 static void ipatch_gig_dimension_init(IpatchGigDimension *gig_dimension);
57 static void ipatch_gig_dimension_finalize(GObject *gobject);
58 static void ipatch_gig_dimension_item_copy(IpatchItem *dest, IpatchItem *src,
59         IpatchItemCopyLinkFunc link_func,
60         gpointer user_data);
61 
62 static GObjectClass *parent_class = NULL;
63 
64 
65 GType
ipatch_gig_dimension_get_type(void)66 ipatch_gig_dimension_get_type(void)
67 {
68     static GType item_type = 0;
69 
70     if(!item_type)
71     {
72         static const GTypeInfo item_info =
73         {
74             sizeof(IpatchGigDimensionClass), NULL, NULL,
75             (GClassInitFunc)ipatch_gig_dimension_class_init, NULL, NULL,
76             sizeof(IpatchGigDimension), 0,
77             (GInstanceInitFunc)ipatch_gig_dimension_init,
78         };
79 
80         item_type = g_type_register_static(IPATCH_TYPE_ITEM,
81                                            "IpatchGigDimension", &item_info, 0);
82     }
83 
84     return (item_type);
85 }
86 
87 static void
ipatch_gig_dimension_class_init(IpatchGigDimensionClass * klass)88 ipatch_gig_dimension_class_init(IpatchGigDimensionClass *klass)
89 {
90     GObjectClass *obj_class = G_OBJECT_CLASS(klass);
91     IpatchItemClass *item_class = IPATCH_ITEM_CLASS(klass);
92 
93     parent_class = g_type_class_peek_parent(klass);
94 
95     obj_class->finalize = ipatch_gig_dimension_finalize;
96     obj_class->get_property = ipatch_gig_dimension_get_property;
97 
98     item_class->item_set_property = ipatch_gig_dimension_set_property;
99     item_class->copy = ipatch_gig_dimension_item_copy;
100 
101     /* use parent's mutex (IpatchGigRegion) */
102     item_class->mutex_slave = TRUE;
103 
104     g_object_class_override_property(obj_class, PROP_NAME, "title");
105 
106     g_object_class_install_property(obj_class, PROP_NAME,
107                                     g_param_spec_string("name", _("Name"),
108                                             _("Dimension name"),
109                                             NULL, G_PARAM_READWRITE));
110     g_object_class_install_property(obj_class, PROP_TYPE,
111                                     g_param_spec_enum("type", _("Type"),
112                                             _("Dimension type"),
113                                             IPATCH_TYPE_GIG_DIMENSION_TYPE,
114                                             IPATCH_GIG_DIMENSION_NONE,
115                                             G_PARAM_READWRITE));
116     g_object_class_install_property(obj_class, PROP_TYPE,
117                                     g_param_spec_int("split-count", _("Split count"),
118                                             _("Number of split bits"),
119                                             1, 5, 1, G_PARAM_READWRITE));
120 }
121 
122 static void
ipatch_gig_dimension_set_property(GObject * object,guint property_id,const GValue * value,GParamSpec * pspec)123 ipatch_gig_dimension_set_property(GObject *object, guint property_id,
124                                   const GValue *value, GParamSpec *pspec)
125 {
126     IpatchGigDimension *dimension = IPATCH_GIG_DIMENSION(object);
127 
128     switch(property_id)
129     {
130     case PROP_NAME:
131         IPATCH_ITEM_WLOCK(dimension);
132         g_free(dimension->name);
133         dimension->name = g_value_dup_string(value);
134         IPATCH_ITEM_WUNLOCK(dimension);
135 
136         /* title property notify */
137         ipatch_item_prop_notify((IpatchItem *)dimension, ipatch_item_pspec_title,
138                                 value, NULL);
139         break;
140 
141     case PROP_TYPE:
142         dimension->type = g_value_get_enum(value);
143         break;
144 
145     case PROP_SPLIT_COUNT:
146         dimension->split_count = g_value_get_int(value);
147         break;
148 
149     default:
150         G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
151         return;
152     }
153 }
154 
155 static void
ipatch_gig_dimension_get_property(GObject * object,guint property_id,GValue * value,GParamSpec * pspec)156 ipatch_gig_dimension_get_property(GObject *object, guint property_id,
157                                   GValue *value, GParamSpec *pspec)
158 {
159     IpatchGigDimension *dimension = IPATCH_GIG_DIMENSION(object);
160 
161     switch(property_id)
162     {
163     case PROP_NAME:
164         IPATCH_ITEM_RLOCK(dimension);
165         g_value_set_string(value, dimension->name);
166         IPATCH_ITEM_RUNLOCK(dimension);
167         break;
168 
169     case PROP_TYPE:
170         g_value_set_enum(value, dimension->type);
171         break;
172 
173     case PROP_SPLIT_COUNT:
174         g_value_set_int(value, dimension->split_count);
175         break;
176 
177     default:
178         G_OBJECT_WARN_INVALID_PROPERTY_ID(object, property_id, pspec);
179         break;
180     }
181 }
182 
183 static void
ipatch_gig_dimension_init(IpatchGigDimension * dimension)184 ipatch_gig_dimension_init(IpatchGigDimension *dimension)
185 {
186 }
187 
188 static void
ipatch_gig_dimension_finalize(GObject * gobject)189 ipatch_gig_dimension_finalize(GObject *gobject)
190 {
191     IpatchGigDimension *dimension = IPATCH_GIG_DIMENSION(gobject);
192 
193     IPATCH_ITEM_WLOCK(dimension);
194     g_free(dimension->name);
195     dimension->name = NULL;
196     IPATCH_ITEM_WUNLOCK(dimension);
197 
198     if(parent_class->finalize)
199     {
200         parent_class->finalize(gobject);
201     }
202 }
203 
204 static void
ipatch_gig_dimension_item_copy(IpatchItem * dest,IpatchItem * src,IpatchItemCopyLinkFunc link_func,gpointer user_data)205 ipatch_gig_dimension_item_copy(IpatchItem *dest, IpatchItem *src,
206                                IpatchItemCopyLinkFunc link_func,
207                                gpointer user_data)
208 {
209     IpatchGigDimension *src_dim, *dest_dim;
210 
211     src_dim = IPATCH_GIG_DIMENSION(src);
212     dest_dim = IPATCH_GIG_DIMENSION(dest);
213 
214     IPATCH_ITEM_RLOCK(src_dim);
215 
216     dest_dim->name = g_strdup(src_dim->name);
217     dest_dim->type = src_dim->type;
218     dest_dim->split_count = src_dim->split_count;
219     dest_dim->split_mask = src_dim->split_mask;
220     dest_dim->split_shift = src_dim->split_shift;
221 
222     IPATCH_ITEM_RUNLOCK(src_dim);
223 }
224 
225 /**
226  * ipatch_gig_dimension_new:
227  *
228  * Create a new GigaSampler instrument dimension.
229  *
230  * Returns: New GigaSampler dimension with a ref count of 1 which the caller
231  * owns.
232  */
233 IpatchGigDimension *
ipatch_gig_dimension_new(void)234 ipatch_gig_dimension_new(void)
235 {
236     return (IPATCH_GIG_DIMENSION(g_object_new(IPATCH_TYPE_GIG_DIMENSION, NULL)));
237 }
238 
239 /**
240  * ipatch_gig_dimension_first: (skip)
241  * @iter: Patch item iterator containing #IpatchGigDimension items
242  *
243  * Gets the first item in a dimension iterator. A convenience
244  * wrapper for ipatch_iter_first().
245  *
246  * Returns: The first dimension in @iter or %NULL if empty.
247  */
248 IpatchGigDimension *
ipatch_gig_dimension_first(IpatchIter * iter)249 ipatch_gig_dimension_first(IpatchIter *iter)
250 {
251     GObject *obj;
252     g_return_val_if_fail(iter != NULL, NULL);
253 
254     obj = ipatch_iter_first(iter);
255 
256     if(obj)
257     {
258         return (IPATCH_GIG_DIMENSION(obj));
259     }
260     else
261     {
262         return (NULL);
263     }
264 }
265 
266 /**
267  * ipatch_gig_dimension_next: (skip)
268  * @iter: Patch item iterator containing #IpatchGigDimension items
269  *
270  * Gets the next item in a dimension iterator. A convenience wrapper
271  * for ipatch_iter_next().
272  *
273  * Returns: The next dimension in @iter or %NULL if at the end of
274  *   the list.
275  */
276 IpatchGigDimension *
ipatch_gig_dimension_next(IpatchIter * iter)277 ipatch_gig_dimension_next(IpatchIter *iter)
278 {
279     GObject *obj;
280     g_return_val_if_fail(iter != NULL, NULL);
281 
282     obj = ipatch_iter_next(iter);
283 
284     if(obj)
285     {
286         return (IPATCH_GIG_DIMENSION(obj));
287     }
288     else
289     {
290         return (NULL);
291     }
292 }
293