1 /* GSequencer - Advanced GTK Sequencer
2 * Copyright (C) 2005-2020 Joël Krähemann
3 *
4 * This file is part of GSequencer.
5 *
6 * GSequencer is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * GSequencer is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with GSequencer. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20 #include <ags/audio/file/ags_audio_container_manager.h>
21
22 #include <ags/libags.h>
23 #include <ags/libags-audio.h>
24
25 #include <stdlib.h>
26
27 #include <ags/i18n.h>
28
29 void ags_audio_container_manager_class_init(AgsAudioContainerManagerClass *audio_container_manager);
30 void ags_audio_container_manager_init(AgsAudioContainerManager *audio_container_manager);
31 void ags_audio_container_manager_set_property(GObject *gobject,
32 guint prop_id,
33 const GValue *value,
34 GParamSpec *param_spec);
35 void ags_audio_container_manager_get_property(GObject *gobject,
36 guint prop_id,
37 GValue *value,
38 GParamSpec *param_spec);
39 void ags_audio_container_manager_finalize(GObject *gobject);
40
41 /**
42 * SECTION:ags_audio_container_manager
43 * @short_description: The audio container manager
44 * @title: AgsAudioContainerManager
45 * @section_id:
46 * @include: ags/audio_container/ags_audio_container_manager.h
47 *
48 * #AgsAudioContainerManager stores audio containers.
49 */
50
51 enum{
52 PROP_0,
53 PROP_AUDIO_CONTAINER,
54 };
55
56 static gpointer ags_audio_container_manager_parent_class = NULL;
57
58 AgsAudioContainerManager *ags_audio_container_manager = NULL;
59
60 GType
ags_audio_container_manager_get_type()61 ags_audio_container_manager_get_type()
62 {
63 static volatile gsize g_define_type_id__volatile = 0;
64
65 if(g_once_init_enter (&g_define_type_id__volatile)){
66 GType ags_type_audio_container_manager = 0;
67
68 static const GTypeInfo ags_audio_container_manager_info = {
69 sizeof (AgsAudioContainerManagerClass),
70 NULL, /* base_init */
71 NULL, /* base_finalize */
72 (GClassInitFunc) ags_audio_container_manager_class_init,
73 NULL, /* class_finalize */
74 NULL, /* class_data */
75 sizeof (AgsAudioContainerManager),
76 0, /* n_preallocs */
77 (GInstanceInitFunc) ags_audio_container_manager_init,
78 };
79
80 ags_type_audio_container_manager = g_type_register_static(G_TYPE_OBJECT,
81 "AgsAudioContainerManager", &ags_audio_container_manager_info,
82 0);
83
84 g_once_init_leave(&g_define_type_id__volatile, ags_type_audio_container_manager);
85 }
86
87 return g_define_type_id__volatile;
88 }
89
90 void
ags_audio_container_manager_class_init(AgsAudioContainerManagerClass * audio_container_manager)91 ags_audio_container_manager_class_init(AgsAudioContainerManagerClass *audio_container_manager)
92 {
93 GObjectClass *gobject;
94
95 GParamSpec *param_spec;
96
97 ags_audio_container_manager_parent_class = g_type_class_peek_parent(audio_container_manager);
98
99 /* GObjectClass */
100 gobject = (GObjectClass *) audio_container_manager;
101
102 gobject->set_property = ags_audio_container_manager_set_property;
103 gobject->get_property = ags_audio_container_manager_get_property;
104
105 gobject->finalize = ags_audio_container_manager_finalize;
106
107 /* properties */
108 /**
109 * AgsAudioContainerManager:audio-container:
110 *
111 * The #GList-struct containing #AgsAudioContainer.
112 *
113 * Since: 3.4.0
114 */
115 param_spec = g_param_spec_pointer("audio-container",
116 i18n_pspec("containing audio_container"),
117 i18n_pspec("The audio_container it contains"),
118 G_PARAM_READABLE | G_PARAM_WRITABLE);
119 g_object_class_install_property(gobject,
120 PROP_AUDIO_CONTAINER,
121 param_spec);
122
123 /* AgsModel */
124 }
125
126 void
ags_audio_container_manager_init(AgsAudioContainerManager * audio_container_manager)127 ags_audio_container_manager_init(AgsAudioContainerManager *audio_container_manager)
128 {
129 /* add audio container manager mutex */
130 g_rec_mutex_init(&(audio_container_manager->obj_mutex));
131
132 audio_container_manager->audio_container = NULL;
133 }
134
135 void
ags_audio_container_manager_set_property(GObject * gobject,guint prop_id,const GValue * value,GParamSpec * param_spec)136 ags_audio_container_manager_set_property(GObject *gobject,
137 guint prop_id,
138 const GValue *value,
139 GParamSpec *param_spec)
140 {
141 AgsAudioContainerManager *audio_container_manager;
142
143 GRecMutex *audio_container_manager_mutex;
144
145 audio_container_manager = AGS_AUDIO_CONTAINER_MANAGER(gobject);
146
147 /* get audio container manager mutex */
148 audio_container_manager_mutex = AGS_AUDIO_CONTAINER_MANAGER_GET_OBJ_MUTEX(audio_container_manager);
149
150 switch(prop_id){
151 case PROP_AUDIO_CONTAINER:
152 {
153 AgsAudioContainer *audio_container;
154
155 /* */
156 audio_container = (AgsAudioContainer *) g_value_get_pointer(value);
157
158 ags_audio_container_manager_add_audio_container(audio_container_manager,
159 (GObject *) audio_container);
160 }
161 break;
162 default:
163 G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, prop_id, param_spec);
164 break;
165 }
166 }
167
168 void
ags_audio_container_manager_get_property(GObject * gobject,guint prop_id,GValue * value,GParamSpec * param_spec)169 ags_audio_container_manager_get_property(GObject *gobject,
170 guint prop_id,
171 GValue *value,
172 GParamSpec *param_spec)
173 {
174 AgsAudioContainerManager *audio_container_manager;
175
176 GRecMutex *audio_container_manager_mutex;
177
178 audio_container_manager = AGS_AUDIO_CONTAINER_MANAGER(gobject);
179
180 /* get audio container manager mutex */
181 audio_container_manager_mutex = AGS_AUDIO_CONTAINER_MANAGER_GET_OBJ_MUTEX(audio_container_manager);
182
183 switch(prop_id){
184 case PROP_AUDIO_CONTAINER:
185 {
186 g_rec_mutex_lock(audio_container_manager_mutex);
187
188 g_value_set_pointer(value,
189 g_list_copy_deep(audio_container_manager->audio_container,
190 (GCopyFunc) g_object_ref,
191 NULL));
192
193 g_rec_mutex_unlock(audio_container_manager_mutex);
194 }
195 break;
196 default:
197 G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, prop_id, param_spec);
198 break;
199 }
200 }
201
202 void
ags_audio_container_manager_finalize(GObject * gobject)203 ags_audio_container_manager_finalize(GObject *gobject)
204 {
205 AgsAudioContainerManager *audio_container_manager;
206
207 audio_container_manager = (AgsAudioContainerManager *) gobject;
208
209 /* call parent */
210 G_OBJECT_CLASS(ags_audio_container_manager_parent_class)->finalize(gobject);
211 }
212
213 /**
214 * ags_audio_container_manager_add_audio_container:
215 * @audio_container_manager: the #AgsAudioContainerManager
216 * @audio_container: the #AgsAudioContainer
217 *
218 * Add @audio_container to @audio_container_manager.
219 *
220 * Since: 3.4.0
221 */
222 void
ags_audio_container_manager_add_audio_container(AgsAudioContainerManager * audio_container_manager,GObject * audio_container)223 ags_audio_container_manager_add_audio_container(AgsAudioContainerManager *audio_container_manager,
224 GObject *audio_container)
225 {
226 GRecMutex *audio_container_manager_mutex;
227
228 if(!AGS_IS_AUDIO_CONTAINER_MANAGER(audio_container_manager) ||
229 !AGS_IS_AUDIO_CONTAINER(audio_container)){
230 return;
231 }
232
233 /* get audio container manager mutex */
234 audio_container_manager_mutex = AGS_AUDIO_CONTAINER_MANAGER_GET_OBJ_MUTEX(audio_container_manager);
235
236 g_rec_mutex_lock(audio_container_manager_mutex);
237
238 if(g_list_find(audio_container_manager->audio_container,
239 audio_container) == NULL){
240 g_object_ref(audio_container);
241 audio_container_manager->audio_container = g_list_prepend(audio_container_manager->audio_container,
242 audio_container);
243 }
244
245 g_rec_mutex_unlock(audio_container_manager_mutex);
246 }
247
248 /**
249 * ags_audio_container_manager_remove_audio_container:
250 * @audio_container_manager: the #AgsAudioContainerManager
251 * @audio_container: the #AgsAudioContainer
252 *
253 * Remove @audio_container from @audio_container_manager.
254 *
255 * Since: 3.4.0
256 */
257 void
ags_audio_container_manager_remove_audio_container(AgsAudioContainerManager * audio_container_manager,GObject * audio_container)258 ags_audio_container_manager_remove_audio_container(AgsAudioContainerManager *audio_container_manager,
259 GObject *audio_container)
260 {
261 GRecMutex *audio_container_manager_mutex;
262
263 if(!AGS_IS_AUDIO_CONTAINER_MANAGER(audio_container_manager) ||
264 !AGS_IS_AUDIO_CONTAINER(audio_container)){
265 return;
266 }
267
268 /* get audio container manager mutex */
269 audio_container_manager_mutex = AGS_AUDIO_CONTAINER_MANAGER_GET_OBJ_MUTEX(audio_container_manager);
270
271 g_rec_mutex_lock(audio_container_manager_mutex);
272
273 if(g_list_find(audio_container_manager->audio_container,
274 audio_container) != NULL){
275 g_object_unref(audio_container);
276 audio_container_manager->audio_container = g_list_remove(audio_container_manager->audio_container,
277 audio_container);
278 }
279
280 g_rec_mutex_unlock(audio_container_manager_mutex);
281 }
282
283 /**
284 * ags_audio_container_manager_find_audio_container:
285 * @audio_container_manager: the #AgsAudioContainerManager
286 * @filename: the string identifier
287 *
288 * Find audio container by @filename.
289 *
290 * Returns: (transfer none): the matching #AgsAudioContainer if found, otherwise %NULL
291 *
292 * Since: 3.4.0
293 */
294 GObject*
ags_audio_container_manager_find_audio_container(AgsAudioContainerManager * audio_container_manager,gchar * filename)295 ags_audio_container_manager_find_audio_container(AgsAudioContainerManager *audio_container_manager,
296 gchar *filename)
297 {
298 AgsAudioContainer *audio_container;
299
300 GList *start_list, *list;
301
302 gchar *current_filename;
303
304 gboolean success;
305
306 if(!AGS_IS_AUDIO_CONTAINER_MANAGER(audio_container_manager) ||
307 filename == NULL){
308 return(NULL);
309 }
310
311 g_object_get(audio_container_manager,
312 "audio-container", &start_list,
313 NULL);
314
315 audio_container = NULL;
316
317 list = start_list;
318
319 success = FALSE;
320
321 while(list != NULL){
322 current_filename = NULL;
323
324 g_object_get(AGS_AUDIO_CONTAINER(list->data),
325 "filename", ¤t_filename,
326 NULL);
327
328 success = (!g_strcmp0(current_filename,
329 filename)) ? TRUE: FALSE;
330
331 g_free(current_filename);
332
333 if(success){
334 audio_container = list->data;
335
336 break;
337 }
338
339 list = list->next;
340 }
341
342 g_list_free_full(start_list,
343 (GDestroyNotify) g_object_unref);
344
345 return(audio_container);
346 }
347
348 /**
349 * ags_audio_container_manager_get_instance:
350 *
351 * Get ags audio container manager instance.
352 *
353 * Returns: (transfer none): the #AgsAudioContainerManager singleton
354 *
355 * Since: 3.4.0
356 */
357 AgsAudioContainerManager*
ags_audio_container_manager_get_instance()358 ags_audio_container_manager_get_instance()
359 {
360 static GMutex mutex = {0,};
361
362 g_mutex_lock(&mutex);
363
364 if(ags_audio_container_manager == NULL){
365 ags_audio_container_manager = ags_audio_container_manager_new();
366 }
367
368 g_mutex_unlock(&mutex);
369
370 return(ags_audio_container_manager);
371 }
372
373 /**
374 * ags_audio_container_manager_new:
375 *
376 * Creates an #AgsAudioContainerManager
377 *
378 * Returns: a new #AgsAudioContainerManager
379 *
380 * Since: 3.4.0
381 */
382 AgsAudioContainerManager*
ags_audio_container_manager_new()383 ags_audio_container_manager_new()
384 {
385 AgsAudioContainerManager *audio_container_manager;
386
387 audio_container_manager = (AgsAudioContainerManager *) g_object_new(AGS_TYPE_AUDIO_CONTAINER_MANAGER,
388 NULL);
389
390 return(audio_container_manager);
391 }
392