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