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