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 * connify it under the terms of the GNU Conneral 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 Conneral Public License for more details.
14 *
15 * You should have received a copy of the GNU Conneral 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: IpatchDLS2Conn
22 * @short_description: DLS version 2 connection structures and functions
23 * @see_also:
24 * @stability: Stable
25 *
26 * Defines structures and functions used for DLS version 2 instrument
27 * parameters (called connections in DLS terminology).
28 */
29 #include <glib.h>
30 #include <glib-object.h>
31 #include "IpatchDLS2Conn.h"
32 #include "ipatch_priv.h"
33
34
35 /**
36 * ipatch_dls2_conn_get_type:
37 *
38 * Get the #IpatchDLS2Conn boxed type
39 *
40 * Returns: Boxed GType of the #IpatchDLS2Conn structure
41 */
42 GType
ipatch_dls2_conn_get_type(void)43 ipatch_dls2_conn_get_type(void)
44 {
45 static GType type = 0;
46
47 if(!type)
48 type = g_boxed_type_register_static("IpatchDLS2Conn",
49 (GBoxedCopyFunc)ipatch_dls2_conn_duplicate,
50 (GBoxedFreeFunc)ipatch_dls2_conn_free);
51
52 return (type);
53 }
54
55 /**
56 * ipatch_dls2_conn_new: (skip)
57 *
58 * Create a new connection
59 *
60 * Returns: New connection
61 */
62 IpatchDLS2Conn *
ipatch_dls2_conn_new(void)63 ipatch_dls2_conn_new(void)
64 {
65 return (g_slice_new0(IpatchDLS2Conn));
66 }
67
68 /**
69 * ipatch_dls2_conn_free: (skip)
70 * @conn: Connection to free, should not be referenced by any zones.
71 *
72 * Free an #IpatchDLS2Conn structure
73 */
74 void
ipatch_dls2_conn_free(IpatchDLS2Conn * conn)75 ipatch_dls2_conn_free(IpatchDLS2Conn *conn)
76 {
77 g_slice_free(IpatchDLS2Conn, conn);
78 }
79
80 /**
81 * ipatch_dls2_conn_duplicate: (skip)
82 * @conn: DLS connection to duplicate
83 *
84 * Duplicate a connection
85 *
86 * Returns: New duplicate connection
87 */
88 IpatchDLS2Conn *
ipatch_dls2_conn_duplicate(const IpatchDLS2Conn * conn)89 ipatch_dls2_conn_duplicate(const IpatchDLS2Conn *conn)
90 {
91 IpatchDLS2Conn *newconn;
92
93 g_return_val_if_fail(conn != NULL, NULL);
94
95 newconn = ipatch_dls2_conn_new();
96
97 newconn->src = conn->src;
98 newconn->ctrlsrc = conn->ctrlsrc;
99 newconn->dest = conn->dest;
100 newconn->trans = conn->trans;
101 newconn->scale = conn->scale;
102
103 return (newconn);
104 }
105
106 /**
107 * ipatch_dls2_conn_list_set:
108 * @list: (element-type IpatchDLS2Conn) (transfer none): Pointer to the root pointer of a
109 * connection list
110 * @conn: DLS connection to set in @list
111 *
112 * Set a connection in a connection list. The connection list is searched for
113 * any existing identical connection (same source, control and destination).
114 * If an identical connection is found, its values are overwritten with the
115 * new values, otherwise a new connection is added to the list and the values
116 * copied to it.
117 */
118 void
ipatch_dls2_conn_list_set(GSList ** list,const IpatchDLS2Conn * conn)119 ipatch_dls2_conn_list_set(GSList **list, const IpatchDLS2Conn *conn)
120 {
121 GSList *p, *last = NULL;
122 IpatchDLS2Conn *c;
123
124 g_return_if_fail(list != NULL);
125 g_return_if_fail(conn != NULL);
126
127 p = *list;
128
129 while(p)
130 {
131 c = (IpatchDLS2Conn *)(p->data);
132
133 if(IPATCH_DLS2_CONN_ARE_IDENTICAL(c, conn))
134 {
135 break;
136 }
137
138 last = p;
139 p = g_slist_next(p);
140 }
141
142 if(!p) /* duplicate not found? */
143 {
144 c = ipatch_dls2_conn_duplicate(conn);
145
146 if(last)
147 {
148 last = g_slist_append(last, c); /* assign to supress gcc warning */
149 }
150 else
151 {
152 *list = g_slist_append(NULL, c);
153 }
154 }
155 else
156 {
157 *c = *conn; /* overwrite old connection values */
158 }
159 }
160
161 /**
162 * ipatch_dls2_conn_list_unset:
163 * @list: (element-type IpatchDLS2Conn) (transfer none): Pointer to the root pointer of a
164 * connection list
165 * @conn: DLS connection to remove from @list
166 *
167 * Remove a connection from a connection list. The connection list is
168 * searched for an identical connection to @conn (same source,
169 * control and destination). If a match is found, it is removed, otherwise
170 * nothing. This essentially sets a connection to its default value, for
171 * those connections which are defined.
172 */
173 void
ipatch_dls2_conn_list_unset(GSList ** list,const IpatchDLS2Conn * conn)174 ipatch_dls2_conn_list_unset(GSList **list, const IpatchDLS2Conn *conn)
175 {
176 IpatchDLS2Conn *c;
177 GSList *p, *prev = NULL;
178
179 g_return_if_fail(list != NULL);
180 g_return_if_fail(conn != NULL);
181
182 p = *list;
183
184 while(p)
185 {
186 c = (IpatchDLS2Conn *)(p->data);
187
188 if(IPATCH_DLS2_CONN_ARE_IDENTICAL(c, conn))
189 {
190 /* free and remove connection */
191 ipatch_dls2_conn_free(c);
192
193 if(!prev)
194 {
195 *list = p->next;
196 }
197 else
198 {
199 prev->next = p->next;
200 }
201
202 g_slist_free_1(p);
203 return;
204 }
205
206 prev = p;
207 p = g_slist_next(p);
208 }
209 }
210
211 /**
212 * ipatch_dls2_conn_list_duplicate:
213 * @list: (element-type IpatchDLS2Conn) (transfer none): GSList of #IpatchDLS2Conn structures
214 * to duplicate
215 *
216 * Duplicates a connection list (GSList and connection data).
217 *
218 * Returns: (element-type IpatchDLS2Conn) (transfer full): New duplicate connection list which
219 * should be freed with ipatch_dls2_conn_list_free() when finished with it.
220 */
221 GSList *
ipatch_dls2_conn_list_duplicate(const GSList * list)222 ipatch_dls2_conn_list_duplicate(const GSList *list)
223 {
224 GSList *newlist = NULL;
225
226 while(list)
227 {
228 newlist = g_slist_prepend(newlist, ipatch_dls2_conn_duplicate
229 ((IpatchDLS2Conn *)(list->data)));
230 list = list->next;
231 }
232
233 return (g_slist_reverse(newlist));
234 }
235
236 /**
237 * ipatch_dls2_conn_list_duplicate_fast: (skip)
238 * @list: (element-type IpatchDLS2Conn): GSList of #IpatchDLS2Conn structures
239 * to duplicate
240 *
241 * Like ipatch_dls2_conn_list_duplicate() but optimized for speed, new list
242 * is backwards from original.
243 *
244 * Returns: (element-type IpatchDLS2Conn) (transfer full): New duplicate connection list which
245 * should be freed with ipatch_dls2_conn_list_free() when finished with it.
246 */
247 GSList *
ipatch_dls2_conn_list_duplicate_fast(const GSList * list)248 ipatch_dls2_conn_list_duplicate_fast(const GSList *list)
249 {
250 GSList *newlist = NULL;
251
252 while(list)
253 {
254 newlist = g_slist_prepend(newlist, ipatch_dls2_conn_duplicate
255 ((IpatchDLS2Conn *)(list->data)));
256 list = list->next;
257 }
258
259 return (newlist);
260 }
261
262 /**
263 * ipatch_dls2_conn_list_free: (skip)
264 * @list: (element-type IpatchDLS2Conn): GSList of #IpatchDLS2Conn structures
265 * to free
266 * @free_conns: If %TRUE then the connections themselves are freed, %FALSE
267 * makes this function act just like g_slist_free() (only the list is
268 * freed not the connections).
269 *
270 * Free a list of connections
271 */
272 void
ipatch_dls2_conn_list_free(GSList * list,gboolean free_conns)273 ipatch_dls2_conn_list_free(GSList *list, gboolean free_conns)
274 {
275 GSList *p;
276
277 if(free_conns)
278 {
279 p = list;
280
281 while(p)
282 {
283 ipatch_dls2_conn_free((IpatchDLS2Conn *)(p->data));
284 p = g_slist_delete_link(p, p);
285 }
286 }
287 else
288 {
289 g_slist_free(list);
290 }
291 }
292