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/ags_preset.h>
21 
22 #include <stdlib.h>
23 #include <string.h>
24 
25 #include <ags/i18n.h>
26 
27 void ags_preset_class_init(AgsPresetClass *preset);
28 void ags_preset_init (AgsPreset *preset);
29 void ags_preset_set_property(GObject *gobject,
30 			     guint prop_id,
31 			     const GValue *value,
32 			     GParamSpec *param_spec);
33 void ags_preset_get_property(GObject *gobject,
34 			     guint prop_id,
35 			     GValue *value,
36 			     GParamSpec *param_spec);
37 void ags_preset_finalize(GObject *gobject);
38 
39 /**
40  * SECTION:ags_preset
41  * @short_description: presets
42  * @title: AgsPreset
43  * @section_id:
44  * @include: ags/audio/ags_preset.h
45  *
46  * The #AgsPreset stores presets.
47  */
48 
49 static gpointer ags_preset_parent_class = NULL;
50 
51 enum{
52   PROP_0,
53   PROP_AUDIO,
54   PROP_SCOPE,
55   PROP_PRESET_NAME,
56   PROP_AUDIO_CHANNEL_START,
57   PROP_AUDIO_CHANNEL_END,
58   PROP_PAD_START,
59   PROP_PAD_END,
60   PROP_X_START,
61   PROP_X_END,
62 };
63 
64 GType
ags_preset_get_type(void)65 ags_preset_get_type (void)
66 {
67   static volatile gsize g_define_type_id__volatile = 0;
68 
69   if(g_once_init_enter (&g_define_type_id__volatile)){
70     GType ags_type_preset = 0;
71 
72     static const GTypeInfo ags_preset_info = {
73       sizeof (AgsPresetClass),
74       NULL, /* base_init */
75       NULL, /* base_finalize */
76       (GClassInitFunc) ags_preset_class_init,
77       NULL, /* class_finalize */
78       NULL, /* class_data */
79       sizeof (AgsPreset),
80       0,    /* n_preallocs */
81       (GInstanceInitFunc) ags_preset_init,
82     };
83 
84     ags_type_preset = g_type_register_static(G_TYPE_OBJECT,
85 					     "AgsPreset",
86 					     &ags_preset_info,
87 					     0);
88 
89     g_once_init_leave(&g_define_type_id__volatile, ags_type_preset);
90   }
91 
92   return g_define_type_id__volatile;
93 }
94 
95 void
ags_preset_class_init(AgsPresetClass * preset)96 ags_preset_class_init(AgsPresetClass *preset)
97 {
98   GObjectClass *gobject;
99   GParamSpec *param_spec;
100 
101   ags_preset_parent_class = g_type_class_peek_parent(preset);
102 
103   /* GObjectClass */
104   gobject = (GObjectClass *) preset;
105 
106   gobject->set_property = ags_preset_set_property;
107   gobject->get_property = ags_preset_get_property;
108 
109   gobject->finalize = ags_preset_finalize;
110 
111   /* properties */
112   /**
113    * AgsPreset:audio:
114    *
115    * The #AgsAudio belonging to.
116    *
117    * Since: 3.0.0
118    */
119   param_spec = g_param_spec_object("audio",
120 				   i18n_pspec("audio"),
121 				   i18n_pspec("The audio belonging to"),
122 				   G_TYPE_OBJECT,
123 				   G_PARAM_READABLE | G_PARAM_WRITABLE);
124   g_object_class_install_property(gobject,
125 				  PROP_AUDIO,
126 				  param_spec);
127 
128   /**
129    * AgsPreset:scope:
130    *
131    * The preset's scope.
132    *
133    * Since: 3.0.0
134    */
135   param_spec = g_param_spec_string("scope",
136 				   i18n_pspec("scope"),
137 				   i18n_pspec("The preset's scope"),
138 				   NULL,
139 				   G_PARAM_READABLE | G_PARAM_WRITABLE);
140   g_object_class_install_property(gobject,
141 				  PROP_SCOPE,
142 				  param_spec);
143 
144   /**
145    * AgsPreset:preset-name:
146    *
147    * The preset name.
148    *
149    * Since: 3.0.0
150    */
151   param_spec = g_param_spec_string("preset-name",
152 				   i18n_pspec("preset-name"),
153 				   i18n_pspec("The preset name"),
154 				   NULL,
155 				   G_PARAM_READABLE | G_PARAM_WRITABLE);
156   g_object_class_install_property(gobject,
157 				  PROP_PRESET_NAME,
158 				  param_spec);
159 
160   /**
161    * AgsPreset:audio-channel-start:
162    *
163    * The start audio channel to apply.
164    *
165    * Since: 3.0.0
166    */
167   param_spec = g_param_spec_uint("audio-channel-start",
168 				 i18n_pspec("audio-channel-start"),
169 				 i18n_pspec("The start audio channel to apply"),
170 				 0,
171 				 G_MAXUINT32,
172 				 0,
173 				 G_PARAM_READABLE | G_PARAM_WRITABLE);
174   g_object_class_install_property(gobject,
175 				  PROP_AUDIO_CHANNEL_START,
176 				  param_spec);
177 
178   /**
179    * AgsPreset:audio-channel-end:
180    *
181    * The end audio channel to apply.
182    *
183    * Since: 3.0.0
184    */
185   param_spec = g_param_spec_uint("audio-channel-end",
186 				 i18n_pspec("audio-channel-end"),
187 				 i18n_pspec("The end audio channel to apply"),
188 				 0,
189 				 G_MAXUINT32,
190 				 0,
191 				 G_PARAM_READABLE | G_PARAM_WRITABLE);
192   g_object_class_install_property(gobject,
193 				  PROP_AUDIO_CHANNEL_END,
194 				  param_spec);
195 
196   /**
197    * AgsPreset:pad-start:
198    *
199    * The start pad to apply.
200    *
201    * Since: 3.0.0
202    */
203   param_spec = g_param_spec_uint("pad-start",
204 				 i18n_pspec("pad-start"),
205 				 i18n_pspec("The start pad to apply"),
206 				 0,
207 				 G_MAXUINT32,
208 				 0,
209 				 G_PARAM_READABLE | G_PARAM_WRITABLE);
210   g_object_class_install_property(gobject,
211 				  PROP_PAD_START,
212 				  param_spec);
213 
214   /**
215    * AgsPreset:pad-end:
216    *
217    * The end pad to apply.
218    *
219    * Since: 3.0.0
220    */
221   param_spec = g_param_spec_uint("pad-end",
222 				 i18n_pspec("pad-end"),
223 				 i18n_pspec("The end pad to apply"),
224 				 0,
225 				 G_MAXUINT32,
226 				 0,
227 				 G_PARAM_READABLE | G_PARAM_WRITABLE);
228   g_object_class_install_property(gobject,
229 				  PROP_PAD_END,
230 				  param_spec);
231 
232   /**
233    * AgsPreset:x-start:
234    *
235    * The start x to apply.
236    *
237    * Since: 3.0.0
238    */
239   param_spec = g_param_spec_uint("x-start",
240 				 i18n_pspec("x-start"),
241 				 i18n_pspec("The start x to apply"),
242 				 0,
243 				 G_MAXUINT32,
244 				 0,
245 				 G_PARAM_READABLE | G_PARAM_WRITABLE);
246   g_object_class_install_property(gobject,
247 				  PROP_X_START,
248 				  param_spec);
249 
250   /**
251    * AgsPreset:x-end:
252    *
253    * The end x to apply.
254    *
255    * Since: 3.0.0
256    */
257   param_spec = g_param_spec_uint("x-end",
258 				 i18n_pspec("x-end"),
259 				 i18n_pspec("The end x to apply"),
260 				 0,
261 				 G_MAXUINT32,
262 				 0,
263 				 G_PARAM_READABLE | G_PARAM_WRITABLE);
264   g_object_class_install_property(gobject,
265 				  PROP_X_END,
266 				  param_spec);
267 }
268 
269 GQuark
ags_preset_error_quark()270 ags_preset_error_quark()
271 {
272   return(g_quark_from_static_string("ags-preset-error-quark"));
273 }
274 
275 void
ags_preset_init(AgsPreset * preset)276 ags_preset_init(AgsPreset *preset)
277 {
278   preset->flags = 0;
279 
280   /* preset mutex */
281   g_rec_mutex_init(&(preset->obj_mutex));
282 
283   /* common fields */
284   preset->audio = NULL;
285 
286   preset->scope = NULL;
287   preset->preset_name = NULL;
288 
289   /* insets */
290   preset->audio_channel_start = 0;
291   preset->audio_channel_end = 0;
292 
293   preset->audio_channel_start = 0;
294   preset->audio_channel_end = 0;
295 
296   preset->pad_start = 0;
297   preset->pad_end = 0;
298 
299   preset->x_start = 0;
300   preset->x_end = 0;
301 
302   /* preset value */
303   preset->n_params = 0;
304   preset->parameter_name = NULL;
305   preset->value = NULL;
306 }
307 
308 void
ags_preset_set_property(GObject * gobject,guint prop_id,const GValue * value,GParamSpec * param_spec)309 ags_preset_set_property(GObject *gobject,
310 			guint prop_id,
311 			const GValue *value,
312 			GParamSpec *param_spec)
313 {
314   AgsPreset *preset;
315 
316   GRecMutex *preset_mutex;
317 
318   preset = AGS_PRESET(gobject);
319 
320   /* get preset mutex */
321   preset_mutex = AGS_PRESET_GET_OBJ_MUTEX(preset);
322 
323   switch(prop_id){
324   case PROP_AUDIO:
325     {
326       GObject *audio;
327 
328       audio = (GObject *) g_value_get_object(value);
329 
330       g_rec_mutex_lock(preset_mutex);
331 
332       if(preset->audio == audio){
333 	g_rec_mutex_unlock(preset_mutex);
334 
335 	return;
336       }
337 
338       if(preset->audio != NULL){
339 	g_object_unref(preset->audio);
340       }
341 
342       if(audio != NULL){
343 	g_object_ref(audio);
344       }
345 
346       preset->audio = audio;
347 
348       g_rec_mutex_unlock(preset_mutex);
349     }
350     break;
351   case PROP_SCOPE:
352     {
353       gchar *scope;
354 
355       scope = g_value_get_string(value);
356 
357       g_rec_mutex_lock(preset_mutex);
358 
359       if(preset->scope != NULL){
360 	g_free(preset->scope);
361       }
362 
363       preset->scope = g_strdup(scope);
364 
365       g_rec_mutex_unlock(preset_mutex);
366     }
367     break;
368   case PROP_PRESET_NAME:
369     {
370       gchar *preset_name;
371 
372       preset_name = g_value_get_string(value);
373 
374       g_rec_mutex_lock(preset_mutex);
375 
376       if(preset->preset_name != NULL){
377 	g_free(preset->preset_name);
378       }
379 
380       preset->preset_name = g_strdup(preset_name);
381 
382       g_rec_mutex_unlock(preset_mutex);
383     }
384     break;
385   case PROP_AUDIO_CHANNEL_START:
386     {
387       g_rec_mutex_lock(preset_mutex);
388 
389       preset->audio_channel_start = g_value_get_uint(value);
390 
391       g_rec_mutex_unlock(preset_mutex);
392     }
393     break;
394   case PROP_AUDIO_CHANNEL_END:
395     {
396       g_rec_mutex_lock(preset_mutex);
397 
398       preset->audio_channel_end = g_value_get_uint(value);
399 
400       g_rec_mutex_unlock(preset_mutex);
401     }
402     break;
403   case PROP_PAD_START:
404     {
405       g_rec_mutex_lock(preset_mutex);
406 
407       preset->pad_start = g_value_get_uint(value);
408 
409       g_rec_mutex_unlock(preset_mutex);
410     }
411     break;
412   case PROP_PAD_END:
413     {
414       g_rec_mutex_lock(preset_mutex);
415 
416       preset->pad_end = g_value_get_uint(value);
417 
418       g_rec_mutex_unlock(preset_mutex);
419     }
420     break;
421   case PROP_X_START:
422     {
423       g_rec_mutex_lock(preset_mutex);
424 
425       preset->x_start = g_value_get_uint(value);
426 
427       g_rec_mutex_unlock(preset_mutex);
428     }
429     break;
430   case PROP_X_END:
431     {
432       g_rec_mutex_lock(preset_mutex);
433 
434       preset->x_end = g_value_get_uint(value);
435 
436       g_rec_mutex_unlock(preset_mutex);
437     }
438     break;
439   default:
440     G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, prop_id, param_spec);
441   }
442 }
443 
444 void
ags_preset_get_property(GObject * gobject,guint prop_id,GValue * value,GParamSpec * param_spec)445 ags_preset_get_property(GObject *gobject,
446 			guint prop_id,
447 			GValue *value,
448 			GParamSpec *param_spec)
449 {
450   AgsPreset *preset;
451 
452   GRecMutex *preset_mutex;
453 
454   preset = AGS_PRESET(gobject);
455 
456   /* get preset mutex */
457   preset_mutex = AGS_PRESET_GET_OBJ_MUTEX(preset);
458 
459   switch(prop_id){
460   case PROP_AUDIO:
461     {
462       g_rec_mutex_lock(preset_mutex);
463 
464       g_value_set_object(value, preset->audio);
465 
466       g_rec_mutex_unlock(preset_mutex);
467     }
468     break;
469   case PROP_SCOPE:
470     {
471       g_rec_mutex_lock(preset_mutex);
472 
473       g_value_set_string(value,
474 			 preset->scope);
475 
476       g_rec_mutex_unlock(preset_mutex);
477     }
478     break;
479   case PROP_PRESET_NAME:
480     {
481       g_rec_mutex_lock(preset_mutex);
482 
483       g_value_set_string(value,
484 			 preset->preset_name);
485 
486       g_rec_mutex_unlock(preset_mutex);
487     }
488     break;
489   case PROP_AUDIO_CHANNEL_START:
490     {
491       g_rec_mutex_lock(preset_mutex);
492 
493       g_value_set_uint(value,
494 		       preset->audio_channel_start);
495 
496       g_rec_mutex_unlock(preset_mutex);
497     }
498     break;
499   case PROP_AUDIO_CHANNEL_END:
500     {
501       g_rec_mutex_lock(preset_mutex);
502 
503       g_value_set_uint(value,
504 		       preset->audio_channel_end);
505 
506       g_rec_mutex_unlock(preset_mutex);
507     }
508     break;
509   case PROP_PAD_START:
510     {
511       g_rec_mutex_lock(preset_mutex);
512 
513       g_value_set_uint(value,
514 		       preset->pad_start);
515 
516       g_rec_mutex_unlock(preset_mutex);
517     }
518     break;
519   case PROP_PAD_END:
520     {
521       g_rec_mutex_lock(preset_mutex);
522 
523       g_value_set_uint(value,
524 		       preset->pad_end);
525 
526       g_rec_mutex_unlock(preset_mutex);
527     }
528     break;
529   case PROP_X_START:
530     {
531       g_rec_mutex_lock(preset_mutex);
532 
533       g_value_set_uint(value,
534 		       preset->x_start);
535 
536       g_rec_mutex_unlock(preset_mutex);
537     }
538     break;
539   case PROP_X_END:
540     {
541       g_rec_mutex_lock(preset_mutex);
542 
543       g_value_set_uint(value,
544 		       preset->x_end);
545 
546       g_rec_mutex_unlock(preset_mutex);
547     }
548     break;
549   default:
550     G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, prop_id, param_spec);
551   }
552 }
553 
554 void
ags_preset_finalize(GObject * gobject)555 ags_preset_finalize(GObject *gobject)
556 {
557   AgsPreset *preset;
558 
559   guint i;
560 
561   preset = AGS_PRESET(gobject);
562 
563   if(preset->audio != NULL){
564     g_object_unref(preset->audio);
565   }
566 
567   g_free(preset->scope);
568   g_free(preset->preset_name);
569 
570   /* paramenter name */
571   g_strfreev(preset->parameter_name);
572 
573   /* unset value */
574   for(i = 0; i < preset->n_params; i++){
575     g_value_unset(&(preset->value[i]));
576   }
577 
578   g_free(preset->value);
579 
580   /* call parent */
581   G_OBJECT_CLASS(ags_preset_parent_class)->finalize(gobject);
582 }
583 
584 /**
585  * ags_preset_get_obj_mutex:
586  * @preset: the #AgsPreset
587  *
588  * Get object mutex.
589  *
590  * Returns: the #GRecMutex to lock @preset
591  *
592  * Since: 3.1.0
593  */
594 GRecMutex*
ags_preset_get_obj_mutex(AgsPreset * preset)595 ags_preset_get_obj_mutex(AgsPreset *preset)
596 {
597   if(!AGS_IS_PRESET(preset)){
598     return(NULL);
599   }
600 
601   return(AGS_PRESET_GET_OBJ_MUTEX(preset));
602 }
603 
604 /**
605  * ags_preset_test_flags:
606  * @preset: the #AgsPreset
607  * @flags: the flags
608  *
609  * Test @flags to be set on @preset.
610  *
611  * Returns: %TRUE if flags are set, else %FALSE
612  *
613  * Since: 3.0.0
614  */
615 gboolean
ags_preset_test_flags(AgsPreset * preset,guint flags)616 ags_preset_test_flags(AgsPreset *preset, guint flags)
617 {
618   gboolean retval;
619 
620   GRecMutex *preset_mutex;
621 
622   if(!AGS_IS_PRESET(preset)){
623     return(FALSE);
624   }
625 
626   /* get preset mutex */
627   preset_mutex = AGS_PRESET_GET_OBJ_MUTEX(preset);
628 
629   /* test */
630   g_rec_mutex_lock(preset_mutex);
631 
632   retval = (flags & (preset->flags)) ? TRUE: FALSE;
633 
634   g_rec_mutex_unlock(preset_mutex);
635 
636   return(retval);
637 }
638 
639 /**
640  * ags_preset_set_flags:
641  * @preset: the #AgsPreset
642  * @flags: the flags
643  *
644  * Set flags.
645  *
646  * Since: 3.0.0
647  */
648 void
ags_preset_set_flags(AgsPreset * preset,guint flags)649 ags_preset_set_flags(AgsPreset *preset, guint flags)
650 {
651   GRecMutex *preset_mutex;
652 
653   if(!AGS_IS_PRESET(preset)){
654     return;
655   }
656 
657   /* get preset mutex */
658   preset_mutex = AGS_PRESET_GET_OBJ_MUTEX(preset);
659 
660   /* set flags */
661   g_rec_mutex_lock(preset_mutex);
662 
663   preset->flags |= flags;
664 
665   g_rec_mutex_unlock(preset_mutex);
666 }
667 
668 /**
669  * ags_preset_unset_flags:
670  * @preset: the #AgsPreset
671  * @flags: the flags
672  *
673  * Unset flags.
674  *
675  * Since: 3.0.0
676  */
677 void
ags_preset_unset_flags(AgsPreset * preset,guint flags)678 ags_preset_unset_flags(AgsPreset *preset, guint flags)
679 {
680   GRecMutex *preset_mutex;
681 
682   if(!AGS_IS_PRESET(preset)){
683     return;
684   }
685 
686   /* get preset mutex */
687   preset_mutex = AGS_PRESET_GET_OBJ_MUTEX(preset);
688 
689   /* set flags */
690   g_rec_mutex_lock(preset_mutex);
691 
692   preset->flags &= (~flags);
693 
694   g_rec_mutex_unlock(preset_mutex);
695 }
696 
697 /**
698  * ags_preset_get_audio:
699  * @preset: the #AgsPreset
700  *
701  * Get audio.
702  *
703  * Returns: (transfer full): the #AgsAudio
704  *
705  * Since: 3.1.0
706  */
707 GObject*
ags_preset_get_audio(AgsPreset * preset)708 ags_preset_get_audio(AgsPreset *preset)
709 {
710   GObject *audio;
711 
712   if(!AGS_IS_PRESET(preset)){
713     return(NULL);
714   }
715 
716   g_object_get(preset,
717 	       "audio", &audio,
718 	       NULL);
719 
720   return(audio);
721 }
722 
723 /**
724  * ags_preset_set_audio:
725  * @preset: the #AgsPreset
726  * @audio: the #AgsAudio
727  *
728  * Set audio.
729  *
730  * Since: 3.1.0
731  */
732 void
ags_preset_set_audio(AgsPreset * preset,GObject * audio)733 ags_preset_set_audio(AgsPreset *preset, GObject *audio)
734 {
735   if(!AGS_IS_PRESET(preset)){
736     return;
737   }
738 
739   g_object_set(preset,
740 	       "audio", audio,
741 	       NULL);
742 }
743 
744 /**
745  * ags_preset_get_scope:
746  * @preset: the #AgsPreset
747  *
748  * Get scope.
749  *
750  * Returns: the scope
751  *
752  * Since: 3.1.0
753  */
754 gchar*
ags_preset_get_scope(AgsPreset * preset)755 ags_preset_get_scope(AgsPreset *preset)
756 {
757   gchar *scope;
758 
759   if(!AGS_IS_PRESET(preset)){
760     return(NULL);
761   }
762 
763   g_object_get(preset,
764 	       "scope", &scope,
765 	       NULL);
766 
767   return(scope);
768 }
769 
770 /**
771  * ags_preset_set_scope:
772  * @preset: the #AgsPreset
773  * @scope: the scope
774  *
775  * Set scope.
776  *
777  * Since: 3.1.0
778  */
779 void
ags_preset_set_scope(AgsPreset * preset,gchar * scope)780 ags_preset_set_scope(AgsPreset *preset,
781 		     gchar *scope)
782 {
783   if(!AGS_IS_PRESET(preset)){
784     return;
785   }
786 
787   g_object_set(preset,
788 	       "scope", scope,
789 	       NULL);
790 }
791 
792 /**
793  * ags_preset_get_preset_name:
794  * @preset: the #AgsPreset
795  *
796  * Get preset name.
797  *
798  * Returns: the preset name
799  *
800  * Since: 3.1.0
801  */
802 gchar*
ags_preset_get_preset_name(AgsPreset * preset)803 ags_preset_get_preset_name(AgsPreset *preset)
804 {
805   gchar *preset_name;
806 
807   if(!AGS_IS_PRESET(preset)){
808     return(NULL);
809   }
810 
811   g_object_get(preset,
812 	       "preset-name", &preset_name,
813 	       NULL);
814 
815   return(preset_name);
816 }
817 
818 /**
819  * ags_preset_set_preset_name:
820  * @preset: the #AgsPreset
821  * @preset_name: the preset name
822  *
823  * Set preset name.
824  *
825  * Since: 3.1.0
826  */
827 void
ags_preset_set_preset_name(AgsPreset * preset,gchar * preset_name)828 ags_preset_set_preset_name(AgsPreset *preset,
829 			   gchar *preset_name)
830 {
831   if(!AGS_IS_PRESET(preset)){
832     return;
833   }
834 
835   g_object_set(preset,
836 	       "preset-name", preset_name,
837 	       NULL);
838 }
839 
840 /**
841  * ags_preset_get_audio_channel_start:
842  * @preset: the #AgsPreset
843  *
844  * Gets audio channel start.
845  *
846  * Returns: the audio channel start
847  *
848  * Since: 3.1.0
849  */
850 guint
ags_preset_get_audio_channel_start(AgsPreset * preset)851 ags_preset_get_audio_channel_start(AgsPreset *preset)
852 {
853   guint audio_channel_start;
854 
855   if(!AGS_IS_PRESET(preset)){
856     return(0);
857   }
858 
859   g_object_get(preset,
860 	       "audio-channel-start", &audio_channel_start,
861 	       NULL);
862 
863   return(audio_channel_start);
864 }
865 
866 /**
867  * ags_preset_set_audio_channel_start:
868  * @preset: the #AgsPreset
869  * @audio_channel_start: the audio channel start
870  *
871  * Sets audio channel start.
872  *
873  * Since: 3.1.0
874  */
875 void
ags_preset_set_audio_channel_start(AgsPreset * preset,guint audio_channel_start)876 ags_preset_set_audio_channel_start(AgsPreset *preset, guint audio_channel_start)
877 {
878   if(!AGS_IS_PRESET(preset)){
879     return;
880   }
881 
882   g_object_set(preset,
883 	       "audio-channel-start", audio_channel_start,
884 	       NULL);
885 }
886 
887 /**
888  * ags_preset_get_audio_channel_end:
889  * @preset: the #AgsPreset
890  *
891  * Gets audio channel end.
892  *
893  * Returns: the audio channel end
894  *
895  * Since: 3.1.0
896  */
897 guint
ags_preset_get_audio_channel_end(AgsPreset * preset)898 ags_preset_get_audio_channel_end(AgsPreset *preset)
899 {
900   guint audio_channel_end;
901 
902   if(!AGS_IS_PRESET(preset)){
903     return(0);
904   }
905 
906   g_object_get(preset,
907 	       "audio-channel-end", &audio_channel_end,
908 	       NULL);
909 
910   return(audio_channel_end);
911 }
912 
913 /**
914  * ags_preset_set_audio_channel_end:
915  * @preset: the #AgsPreset
916  * @audio_channel_end: the audio channel end
917  *
918  * Sets audio channel end.
919  *
920  * Since: 3.1.0
921  */
922 void
ags_preset_set_audio_channel_end(AgsPreset * preset,guint audio_channel_end)923 ags_preset_set_audio_channel_end(AgsPreset *preset, guint audio_channel_end)
924 {
925   if(!AGS_IS_PRESET(preset)){
926     return;
927   }
928 
929   g_object_set(preset,
930 	       "audio-channel-end", audio_channel_end,
931 	       NULL);
932 }
933 
934 /**
935  * ags_preset_get_pad_start:
936  * @preset: the #AgsPreset
937  *
938  * Gets pad start.
939  *
940  * Returns: the pad start
941  *
942  * Since: 3.1.0
943  */
944 guint
ags_preset_get_pad_start(AgsPreset * preset)945 ags_preset_get_pad_start(AgsPreset *preset)
946 {
947   guint pad_start;
948 
949   if(!AGS_IS_PRESET(preset)){
950     return(0);
951   }
952 
953   g_object_get(preset,
954 	       "pad-start", &pad_start,
955 	       NULL);
956 
957   return(pad_start);
958 }
959 
960 /**
961  * ags_preset_set_pad_start:
962  * @preset: the #AgsPreset
963  * @pad_start: the pad start
964  *
965  * Sets pad start.
966  *
967  * Since: 3.1.0
968  */
969 void
ags_preset_set_pad_start(AgsPreset * preset,guint pad_start)970 ags_preset_set_pad_start(AgsPreset *preset, guint pad_start)
971 {
972   if(!AGS_IS_PRESET(preset)){
973     return;
974   }
975 
976   g_object_set(preset,
977 	       "pad-start", pad_start,
978 	       NULL);
979 }
980 
981 /**
982  * ags_preset_get_pad_end:
983  * @preset: the #AgsPreset
984  *
985  * Gets pad end.
986  *
987  * Returns: the pad end
988  *
989  * Since: 3.1.0
990  */
991 guint
ags_preset_get_pad_end(AgsPreset * preset)992 ags_preset_get_pad_end(AgsPreset *preset)
993 {
994   guint pad_end;
995 
996   if(!AGS_IS_PRESET(preset)){
997     return(0);
998   }
999 
1000   g_object_get(preset,
1001 	       "pad-end", &pad_end,
1002 	       NULL);
1003 
1004   return(pad_end);
1005 }
1006 
1007 /**
1008  * ags_preset_set_pad_end:
1009  * @preset: the #AgsPreset
1010  * @pad_end: the pad end
1011  *
1012  * Sets pad end.
1013  *
1014  * Since: 3.1.0
1015  */
1016 void
ags_preset_set_pad_end(AgsPreset * preset,guint pad_end)1017 ags_preset_set_pad_end(AgsPreset *preset, guint pad_end)
1018 {
1019   if(!AGS_IS_PRESET(preset)){
1020     return;
1021   }
1022 
1023   g_object_set(preset,
1024 	       "pad-end", pad_end,
1025 	       NULL);
1026 }
1027 
1028 /**
1029  * ags_preset_get_x_start:
1030  * @preset: the #AgsPreset
1031  *
1032  * Gets x start.
1033  *
1034  * Returns: the x start
1035  *
1036  * Since: 3.1.0
1037  */
1038 guint
ags_preset_get_x_start(AgsPreset * preset)1039 ags_preset_get_x_start(AgsPreset *preset)
1040 {
1041   guint x_start;
1042 
1043   if(!AGS_IS_PRESET(preset)){
1044     return(0);
1045   }
1046 
1047   g_object_get(preset,
1048 	       "x-start", &x_start,
1049 	       NULL);
1050 
1051   return(x_start);
1052 }
1053 
1054 /**
1055  * ags_preset_set_x_start:
1056  * @preset: the #AgsPreset
1057  * @x_start: the x start
1058  *
1059  * Sets x start.
1060  *
1061  * Since: 3.1.0
1062  */
1063 void
ags_preset_set_x_start(AgsPreset * preset,guint x_start)1064 ags_preset_set_x_start(AgsPreset *preset, guint x_start)
1065 {
1066   if(!AGS_IS_PRESET(preset)){
1067     return;
1068   }
1069 
1070   g_object_set(preset,
1071 	       "x-start", x_start,
1072 	       NULL);
1073 }
1074 
1075 /**
1076  * ags_preset_get_x_end:
1077  * @preset: the #AgsPreset
1078  *
1079  * Gets x end.
1080  *
1081  * Returns: the x end
1082  *
1083  * Since: 3.1.0
1084  */
1085 guint
ags_preset_get_x_end(AgsPreset * preset)1086 ags_preset_get_x_end(AgsPreset *preset)
1087 {
1088   guint x_end;
1089 
1090   if(!AGS_IS_PRESET(preset)){
1091     return(0);
1092   }
1093 
1094   g_object_get(preset,
1095 	       "x-end", &x_end,
1096 	       NULL);
1097 
1098   return(x_end);
1099 }
1100 
1101 /**
1102  * ags_preset_set_x_end:
1103  * @preset: the #AgsPreset
1104  * @x_end: the x end
1105  *
1106  * Sets x end.
1107  *
1108  * Since: 3.1.0
1109  */
1110 void
ags_preset_set_x_end(AgsPreset * preset,guint x_end)1111 ags_preset_set_x_end(AgsPreset *preset, guint x_end)
1112 {
1113   if(!AGS_IS_PRESET(preset)){
1114     return;
1115   }
1116 
1117   g_object_set(preset,
1118 	       "x-end", x_end,
1119 	       NULL);
1120 }
1121 
1122 /**
1123  * ags_preset_find_scope:
1124  * @preset: (element-type AgsAudio.Preset) (transfer none): the #GList-struct containing #AgsPreset
1125  * @scope: the preset's scope
1126  *
1127  * Find preset's scope in @preset.
1128  *
1129  * Returns: (element-type AgsAudio.Preset) (transfer none): the next matching #AgsPreset
1130  *
1131  * Since: 3.0.0
1132  */
1133 GList*
ags_preset_find_scope(GList * preset,gchar * scope)1134 ags_preset_find_scope(GList *preset,
1135 		      gchar *scope)
1136 {
1137   GRecMutex *preset_mutex;
1138 
1139   while(preset != NULL){
1140     /* get preset mutex */
1141     preset_mutex = AGS_PRESET_GET_OBJ_MUTEX(preset->data);
1142 
1143     /* compare scope */
1144     g_rec_mutex_lock(preset_mutex);
1145 
1146     if(!g_strcmp0(AGS_PRESET(preset->data)->scope,
1147 		  scope)){
1148       g_rec_mutex_unlock(preset_mutex);
1149 
1150       return(preset);
1151     }
1152 
1153     g_rec_mutex_unlock(preset_mutex);
1154 
1155     /* iterate */
1156     preset = preset->next;
1157   }
1158 
1159   return(NULL);
1160 }
1161 
1162 /**
1163  * ags_preset_find_name:
1164  * @preset: (element-type AgsAudio.Preset) (transfer none): the #GList-struct containing #AgsPreset
1165  * @preset_name: the preset's name
1166  *
1167  * Find preset name in @preset.
1168  *
1169  * Returns: (element-type AgsAudio.Preset) (transfer none): the next matching #AgsPreset
1170  *
1171  * Since: 3.0.0
1172  */
1173 GList*
ags_preset_find_name(GList * preset,gchar * preset_name)1174 ags_preset_find_name(GList *preset,
1175 		     gchar *preset_name)
1176 {
1177   GRecMutex *preset_mutex;
1178 
1179   while(preset != NULL){
1180     /* get preset mutex */
1181     preset_mutex = AGS_PRESET_GET_OBJ_MUTEX(preset->data);
1182 
1183     /* compare scope */
1184     g_rec_mutex_lock(preset_mutex);
1185 
1186     if(!g_strcmp0(AGS_PRESET(preset->data)->preset_name,
1187 		  preset_name)){
1188       g_rec_mutex_unlock(preset_mutex);
1189 
1190       return(preset);
1191     }
1192 
1193     g_rec_mutex_unlock(preset_mutex);
1194 
1195     /* iterate */
1196     preset = preset->next;
1197   }
1198 
1199   return(NULL);
1200 }
1201 
1202 /**
1203  * ags_preset_add_parameter:
1204  * @preset: the #AgsPreset
1205  * @param_name: the parameter name
1206  * @value: the value to add
1207  *
1208  * Add parameter to @preset.
1209  *
1210  * Since: 3.0.0
1211  */
1212 gboolean
ags_preset_add_parameter(AgsPreset * preset,gchar * param_name,GValue * value)1213 ags_preset_add_parameter(AgsPreset *preset,
1214 			 gchar *param_name, GValue *value)
1215 {
1216   guint nth;
1217   guint i;
1218   gboolean found;
1219 
1220   GRecMutex *preset_mutex;
1221 
1222   if(!AGS_IS_PRESET(preset)){
1223     return(FALSE);
1224   }
1225 
1226   /* get preset mutex */
1227   preset_mutex = AGS_PRESET_GET_OBJ_MUTEX(preset);
1228 
1229   /* match or allocate */
1230   g_rec_mutex_lock(preset_mutex);
1231 
1232   found = FALSE;
1233 
1234   if(preset->parameter_name == NULL){
1235     preset->parameter_name = (gchar **) malloc(2 * sizeof(gchar *));
1236 
1237     preset->parameter_name[0] = NULL;
1238     preset->parameter_name[1] = NULL;
1239 
1240     preset->value = g_new0(GValue,
1241 			   1);
1242     g_value_init(&(preset->value[0]),
1243 		 G_VALUE_TYPE(value));
1244 
1245     preset->n_params += 1;
1246     nth = 0;
1247   }else{
1248     for(i = 0; i < preset->n_params; i++){
1249       if(!g_strcmp0(preset->parameter_name[i],
1250 		    param_name)){
1251 	nth = i;
1252 	found = TRUE;
1253 
1254 	break;
1255       }
1256     }
1257 
1258     if(!found){
1259       preset->parameter_name = (gchar **) realloc(preset->parameter_name,
1260 						  (preset->n_params + 2) * sizeof(gchar *));
1261 
1262       preset->parameter_name[preset->n_params] = NULL;
1263       preset->parameter_name[preset->n_params + 1] = NULL;
1264 
1265       preset->value = g_renew(GValue,
1266 			      preset->value,
1267 			      preset->n_params + 1);
1268 
1269       memset(&(preset->value[preset->n_params]), 0, sizeof(GValue));
1270 
1271       g_value_init(&(preset->value[preset->n_params]),
1272 		   G_VALUE_TYPE(value));
1273 
1274       preset->n_params += 1;
1275       nth = i;
1276     }
1277   }
1278 
1279   /* set value */
1280   g_free(preset->parameter_name[nth]);
1281 
1282   preset->parameter_name[nth] = g_strdup(param_name);
1283   g_value_copy(value,
1284 	       &(preset->value[nth]));
1285 
1286   g_rec_mutex_unlock(preset_mutex);
1287 
1288   return(!found);
1289 }
1290 
1291 /**
1292  * ags_preset_remove_parameter:
1293  * @preset: the #AgsPreset
1294  * @nth: the nth parameter to remove
1295  *
1296  * Remove parameter of @preset.
1297  *
1298  * Since: 3.0.0
1299  */
1300 void
ags_preset_remove_parameter(AgsPreset * preset,guint nth)1301 ags_preset_remove_parameter(AgsPreset *preset,
1302 			    guint nth)
1303 {
1304   GValue *value;
1305 
1306   gchar **parameter_name;
1307 
1308   guint i;
1309 
1310   GRecMutex *preset_mutex;
1311 
1312   if(!AGS_IS_PRESET(preset)){
1313     return;
1314   }
1315 
1316   /* get preset mutex */
1317   preset_mutex = AGS_PRESET_GET_OBJ_MUTEX(preset);
1318 
1319   /* check boundaries */
1320   g_rec_mutex_lock(preset_mutex);
1321 
1322   if(preset->n_params == 0 ||
1323      nth >= preset->n_params){
1324     g_rec_mutex_unlock(preset_mutex);
1325 
1326     return;
1327   }
1328 
1329   parameter_name = preset->parameter_name;
1330   value = preset->value;
1331 
1332   if(preset->n_params == 1){
1333     preset->parameter_name = NULL;
1334     preset->n_params = 0;
1335   }else{
1336     preset->parameter_name = (gchar **) malloc((preset->n_params) * sizeof(gchar *));
1337     preset->value = g_new(GValue,
1338 			  preset->n_params - 1);
1339 
1340     if(nth > 0){
1341       memcpy(preset->parameter_name,
1342 	     parameter_name,
1343 	     nth * sizeof(gchar *));
1344 
1345       memcpy(preset->value,
1346 	     value,
1347 	     nth * sizeof(GValue));
1348     }
1349 
1350     if(nth + 1 < preset->n_params){
1351       memcpy(&(preset->parameter_name[nth]),
1352 	     &(parameter_name[nth + 1]),
1353 	     (preset->n_params - (nth + 1)) * sizeof(gchar *));
1354 
1355       memcpy(&(preset->value[nth]),
1356 	     &(value[nth + 1]),
1357 	     (preset->n_params - (nth + 1)) * sizeof(GValue));
1358     }
1359 
1360     preset->n_params -= 1;
1361 
1362     preset->parameter_name[preset->n_params] = NULL;
1363   }
1364 
1365   /* free old preset array */
1366   g_free(parameter_name[nth]);
1367   g_free(parameter_name);
1368 
1369   for(i = 0; i < preset->n_params + 1; i++){
1370     g_value_unset(&(value[i]));
1371   }
1372 
1373   g_free(value);
1374 
1375   g_rec_mutex_unlock(preset_mutex);
1376 }
1377 
1378 /**
1379  * ags_preset_get_parameter:
1380  * @preset: the #AgsPreset
1381  * @param_name: the parameter name
1382  * @value: the return location of value
1383  * @error: the #GError-struct
1384  *
1385  * Get parameter specified by @param_name. If parameter not available
1386  * the @error is set to indicate the failure.
1387  *
1388  * Since: 3.0.0
1389  */
1390 void
ags_preset_get_parameter(AgsPreset * preset,gchar * param_name,GValue * value,GError ** error)1391 ags_preset_get_parameter(AgsPreset *preset,
1392 			 gchar *param_name, GValue *value,
1393 			 GError **error)
1394 {
1395   guint i;
1396   gboolean success;
1397 
1398   GRecMutex *preset_mutex;
1399 
1400   if(!AGS_IS_PRESET(preset)){
1401     return;
1402   }
1403 
1404   /* get preset mutex */
1405   preset_mutex = AGS_PRESET_GET_OBJ_MUTEX(preset);
1406 
1407   /* find */
1408   g_rec_mutex_lock(preset_mutex);
1409 
1410   success = FALSE;
1411 
1412   if(preset->parameter_name != NULL){
1413     for(i = 0; i < preset->n_params; i++){
1414       if(!g_strcmp0(preset->parameter_name[i],
1415 		    param_name)){
1416 	g_value_copy(&(preset->value[i]),
1417 		     value);
1418 
1419 	success = TRUE;
1420 
1421 	break;
1422       }
1423     }
1424   }
1425 
1426   g_rec_mutex_unlock(preset_mutex);
1427 
1428   /* report error */
1429   if(!success && error != NULL){
1430     g_set_error(error,
1431 		AGS_PRESET_ERROR,
1432 		AGS_PRESET_ERROR_NO_SUCH_PARAMETER,
1433 		"unable to find parameter: %s",
1434 		param_name);
1435   }
1436 }
1437 
1438 /**
1439  * ags_preset_new:
1440  *
1441  * Create a new instance of #AgsPreset
1442  *
1443  * Returns: the new #AgsPreset
1444  *
1445  * Since: 3.0.0
1446  */
1447 AgsPreset*
ags_preset_new()1448 ags_preset_new()
1449 {
1450   AgsPreset *preset;
1451 
1452   preset = (AgsPreset *) g_object_new(AGS_TYPE_PRESET,
1453 				      NULL);
1454 
1455   return(preset);
1456 }
1457