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/plugin/ags_plugin_port.h>
21 
22 #include <stdlib.h>
23 #include <string.h>
24 
25 #include <ags/i18n.h>
26 
27 void ags_plugin_port_class_init(AgsPluginPortClass *plugin_port);
28 void ags_plugin_port_init(AgsPluginPort *plugin_port);
29 void ags_plugin_port_set_property(GObject *gobject,
30 				  guint prop_id,
31 				  const GValue *value,
32 				  GParamSpec *param_spec);
33 void ags_plugin_port_get_property(GObject *gobject,
34 				  guint prop_id,
35 				  GValue *value,
36 				  GParamSpec *param_spec);
37 void ags_plugin_port_dispose(GObject *gobject);
38 void ags_plugin_port_finalize(GObject *gobject);
39 
40 /**
41  * SECTION:ags_plugin_port
42  * @short_description: The plugin port class
43  * @title: AgsPluginPort
44  * @section_id:
45  * @include: ags/plugin/ags_plugin_port.h
46  *
47  * The #AgsPluginPort describes a plugin's port. For real ports used by the
48  * processing tree please take a look at #AgsPort.
49  */
50 
51 enum{
52   PROP_0,
53   PROP_PORT_INDEX,
54   PROP_PORT_NAME,
55   PROP_PORT_SYMBOL,
56   PROP_SCALE_STEPS,
57   PROP_SCALE_POINT,
58   PROP_SCALE_VALUE,
59   PROP_LOWER_VALUE,
60   PROP_UPPER_VALUE,
61   PROP_DEFAULT_VALUE,
62 };
63 
64 static gpointer ags_plugin_port_parent_class = NULL;
65 
66 GType
ags_plugin_port_get_type(void)67 ags_plugin_port_get_type (void)
68 {
69   static volatile gsize g_define_type_id__volatile = 0;
70 
71   if(g_once_init_enter (&g_define_type_id__volatile)){
72     GType ags_type_plugin_port = 0;
73 
74     static const GTypeInfo ags_plugin_port_info = {
75       sizeof(AgsPluginPortClass),
76       NULL, /* base_init */
77       NULL, /* base_finalize */
78       (GClassInitFunc) ags_plugin_port_class_init,
79       NULL, /* class_finalize */
80       NULL, /* class_data */
81       sizeof(AgsPluginPort),
82       0,    /* n_preallocs */
83       (GInstanceInitFunc) ags_plugin_port_init,
84     };
85 
86     ags_type_plugin_port = g_type_register_static(G_TYPE_OBJECT,
87 						  "AgsPluginPort",
88 						  &ags_plugin_port_info,
89 						  0);
90 
91     g_once_init_leave(&g_define_type_id__volatile, ags_type_plugin_port);
92   }
93 
94   return g_define_type_id__volatile;
95 }
96 
97 GType
ags_plugin_port_flags_get_type()98 ags_plugin_port_flags_get_type()
99 {
100   static volatile gsize g_flags_type_id__volatile;
101 
102   if(g_once_init_enter (&g_flags_type_id__volatile)){
103     static const GFlagsValue values[] = {
104       { AGS_PLUGIN_PORT_ATOM, "AGS_PLUGIN_PORT_ATOM", "plugin-port-atom" },
105       { AGS_PLUGIN_PORT_AUDIO, "AGS_PLUGIN_PORT_AUDIO", "plugin-port-audio" },
106       { AGS_PLUGIN_PORT_CONTROL, "AGS_PLUGIN_PORT_CONTROL", "plugin-port-control" },
107       { AGS_PLUGIN_PORT_MIDI, "AGS_PLUGIN_PORT_MIDI", "plugin-port-midi" },
108       { AGS_PLUGIN_PORT_EVENT, "AGS_PLUGIN_PORT_EVENT", "plugin-port-event" },
109       { AGS_PLUGIN_PORT_OUTPUT, "AGS_PLUGIN_PORT_OUTPUT", "plugin-port-output" },
110       { AGS_PLUGIN_PORT_INPUT, "AGS_PLUGIN_PORT_INPUT", "plugin-port-input" },
111       { AGS_PLUGIN_PORT_TOGGLED, "AGS_PLUGIN_PORT_TOGGLED", "plugin-port-toggled" },
112       { AGS_PLUGIN_PORT_ENUMERATION, "AGS_PLUGIN_PORT_ENUMERATION", "plugin-port-enumeration" },
113       { AGS_PLUGIN_PORT_LOGARITHMIC, "AGS_PLUGIN_PORT_LOGARITHMIC", "plugin-port-logarithmic" },
114       { AGS_PLUGIN_PORT_INTEGER, "AGS_PLUGIN_PORT_INTEGER", "plugin-port-integer" },
115       { AGS_PLUGIN_PORT_SAMPLERATE, "AGS_PLUGIN_PORT_SAMPLERATE", "plugin-port-samplerate" },
116       { AGS_PLUGIN_PORT_BOUNDED_BELOW, "AGS_PLUGIN_PORT_BOUNDED_BELOW", "plugin-port-bounded-below" },
117       { AGS_PLUGIN_PORT_BOUNDED_ABOVE, "AGS_PLUGIN_PORT_BOUNDED_ABOVE", "plugin-port-bounded-above" },
118       { AGS_PLUGIN_PORT_UI_NOTIFICATION, "AGS_PLUGIN_PORT_UI_NOTIFICATION", "plugin-port-ui-notification" },
119       { 0, NULL, NULL }
120     };
121 
122     GType g_flags_type_id = g_flags_register_static(g_intern_static_string("AgsPluginPortFlags"), values);
123 
124     g_once_init_leave (&g_flags_type_id__volatile, g_flags_type_id);
125   }
126 
127   return g_flags_type_id__volatile;
128 }
129 
130 void
ags_plugin_port_class_init(AgsPluginPortClass * plugin_port)131 ags_plugin_port_class_init(AgsPluginPortClass *plugin_port)
132 {
133   GObjectClass *gobject;
134   GParamSpec *param_spec;
135 
136   ags_plugin_port_parent_class = g_type_class_peek_parent(plugin_port);
137 
138   /* GObjectClass */
139   gobject = (GObjectClass *) plugin_port;
140 
141   gobject->set_property = ags_plugin_port_set_property;
142   gobject->get_property = ags_plugin_port_get_property;
143 
144   gobject->dispose = ags_plugin_port_dispose;
145   gobject->finalize = ags_plugin_port_finalize;
146 
147   /* properties */
148   /**
149    * AgsPluginPort:port-index:
150    *
151    * The assigned port-index.
152    *
153    * Since: 3.0.0
154    */
155   param_spec = g_param_spec_uint("port-index",
156 				 i18n_pspec("port index of the plugin"),
157 				 i18n_pspec("The port's index of the plugin"),
158 				 0,
159 				 G_MAXUINT32,
160 				 0,
161 				 G_PARAM_READABLE | G_PARAM_WRITABLE);
162   g_object_class_install_property(gobject,
163 				  PROP_PORT_INDEX,
164 				  param_spec);
165 
166   /**
167    * AgsPluginPort:port-name:
168    *
169    * The port's name.
170    *
171    * Since: 3.0.0
172    */
173   param_spec = g_param_spec_string("port-name",
174 				   i18n_pspec("name of the port"),
175 				   i18n_pspec("The port's name"),
176 				   NULL,
177 				   G_PARAM_READABLE | G_PARAM_WRITABLE);
178   g_object_class_install_property(gobject,
179 				  PROP_PORT_NAME,
180 				  param_spec);
181 
182   /**
183    * AgsPluginPort:port-symbol:
184    *
185    * The port's symbol.
186    *
187    * Since: 3.0.0
188    */
189   param_spec = g_param_spec_string("port-symbol",
190 				   i18n_pspec("symbol of the port"),
191 				   i18n_pspec("The port's symbol"),
192 				   NULL,
193 				   G_PARAM_READABLE | G_PARAM_WRITABLE);
194   g_object_class_install_property(gobject,
195 				  PROP_PORT_SYMBOL,
196 				  param_spec);
197 
198   /**
199    * AgsPluginPort:scale-steps:
200    *
201    * The number of scale steps.
202    *
203    * Since: 3.0.0
204    */
205   param_spec = g_param_spec_int("scale-steps",
206 				i18n_pspec("port index of the plugin"),
207 				i18n_pspec("The port's index of the plugin"),
208 				-1,
209 				G_MAXINT32,
210 				0,
211 				G_PARAM_READABLE | G_PARAM_WRITABLE);
212   g_object_class_install_property(gobject,
213 				  PROP_SCALE_STEPS,
214 				  param_spec);
215 
216   /**
217    * AgsPluginPort:scale-point:
218    *
219    * The scale point string vector.
220    *
221    * Since: 3.0.0
222    */
223   param_spec = g_param_spec_pointer("scale-point",
224 				    i18n_pspec("string vector of scale points"),
225 				    i18n_pspec("The string vector of scale points"),
226 				    G_PARAM_READABLE);
227   g_object_class_install_property(gobject,
228 				  PROP_SCALE_POINT,
229 				  param_spec);
230 
231   /**
232    * AgsPluginPort:scale-value:
233    *
234    * The scale value array.
235    *
236    * Since: 3.0.0
237    */
238   param_spec = g_param_spec_pointer("scale-value",
239 				    i18n_pspec("array of scale values"),
240 				    i18n_pspec("The array of scale values"),
241 				    G_PARAM_READABLE);
242   g_object_class_install_property(gobject,
243 				  PROP_SCALE_VALUE,
244 				  param_spec);
245 
246   /**
247    * AgsPluginPort:lower-value:
248    *
249    * The lower value.
250    *
251    * Since: 3.0.0
252    */
253   param_spec = g_param_spec_pointer("lower-value",
254 				    i18n_pspec("lower value"),
255 				    i18n_pspec("The lower value"),
256 				    G_PARAM_READABLE | G_PARAM_WRITABLE);
257   g_object_class_install_property(gobject,
258 				  PROP_LOWER_VALUE,
259 				  param_spec);
260 
261   /**
262    * AgsPluginPort:upper-value:
263    *
264    * The upper value.
265    *
266    * Since: 3.0.0
267    */
268   param_spec = g_param_spec_pointer("upper-value",
269 				    i18n_pspec("upper value"),
270 				    i18n_pspec("The upper value"),
271 				    G_PARAM_READABLE | G_PARAM_WRITABLE);
272   g_object_class_install_property(gobject,
273 				  PROP_UPPER_VALUE,
274 				  param_spec);
275 
276   /**
277    * AgsPluginPort:default-value:
278    *
279    * The default value.
280    *
281    * Since: 3.0.0
282    */
283   param_spec = g_param_spec_pointer("default-value",
284 				    i18n_pspec("default value"),
285 				    i18n_pspec("The default value"),
286 				    G_PARAM_READABLE | G_PARAM_WRITABLE);
287   g_object_class_install_property(gobject,
288 				  PROP_DEFAULT_VALUE,
289 				  param_spec);
290 }
291 
292 void
ags_plugin_port_init(AgsPluginPort * plugin_port)293 ags_plugin_port_init(AgsPluginPort *plugin_port)
294 {
295   plugin_port->flags = 0;
296 
297   /* add base plugin mutex */
298   g_rec_mutex_init(&(plugin_port->obj_mutex));
299 
300   plugin_port->port_index = 0;
301 
302   plugin_port->port_name = NULL;
303   plugin_port->port_symbol = NULL;
304 
305   plugin_port->scale_steps = -1;
306   plugin_port->scale_point = NULL;
307   plugin_port->scale_value = NULL;
308 
309   plugin_port->lower_value = g_new0(GValue,
310 				    1);
311   plugin_port->upper_value = g_new0(GValue,
312 				    1);
313 
314   plugin_port->default_value = g_new0(GValue,
315 				      1);
316 
317   plugin_port->user_data = NULL;
318 }
319 
320 void
ags_plugin_port_set_property(GObject * gobject,guint prop_id,const GValue * value,GParamSpec * param_spec)321 ags_plugin_port_set_property(GObject *gobject,
322 			     guint prop_id,
323 			     const GValue *value,
324 			     GParamSpec *param_spec)
325 {
326   AgsPluginPort *plugin_port;
327 
328   GRecMutex *plugin_port_mutex;
329 
330   plugin_port = AGS_PLUGIN_PORT(gobject);
331 
332   /* get plugin port mutex */
333   plugin_port_mutex = AGS_PLUGIN_PORT_GET_OBJ_MUTEX(plugin_port);
334 
335   switch(prop_id){
336   case PROP_PORT_INDEX:
337     {
338       g_rec_mutex_lock(plugin_port_mutex);
339 
340       plugin_port->port_index = g_value_get_uint(value);
341 
342       g_rec_mutex_unlock(plugin_port_mutex);
343     }
344     break;
345   case PROP_PORT_NAME:
346     {
347       gchar *port_name;
348 
349       port_name = g_value_get_string(value);
350 
351       g_rec_mutex_lock(plugin_port_mutex);
352 
353       if(port_name == plugin_port->port_name){
354 	g_rec_mutex_unlock(plugin_port_mutex);
355 
356 	return;
357       }
358 
359       plugin_port->port_name = g_strdup(port_name);
360 
361       g_rec_mutex_unlock(plugin_port_mutex);
362     }
363     break;
364   case PROP_PORT_SYMBOL:
365     {
366       gchar *port_symbol;
367 
368       port_symbol = g_value_get_string(value);
369 
370       g_rec_mutex_lock(plugin_port_mutex);
371 
372       if(port_symbol == plugin_port->port_symbol){
373 	g_rec_mutex_unlock(plugin_port_mutex);
374 
375 	return;
376       }
377 
378       plugin_port->port_symbol = g_strdup(port_symbol);
379 
380       g_rec_mutex_unlock(plugin_port_mutex);
381     }
382     break;
383   case PROP_SCALE_STEPS:
384     {
385       gint scale_steps;
386       guint i;
387 
388       scale_steps = g_value_get_int(value);
389 
390       g_rec_mutex_lock(plugin_port_mutex);
391 
392       if(scale_steps == plugin_port->scale_steps){
393 	g_rec_mutex_unlock(plugin_port_mutex);
394 
395 	return;
396       }
397 
398       if(scale_steps > 0){
399 	/* scale point */
400 	if(plugin_port->scale_point == NULL){
401 	  plugin_port->scale_point = (gchar **) malloc((scale_steps + 1) * sizeof(gchar *));
402 	}else{
403 	  plugin_port->scale_point = (gchar **) realloc(plugin_port->scale_point,
404 							(scale_steps + 1) * sizeof(gchar *));
405 	}
406 
407 	for(i = scale_steps; i < plugin_port->scale_steps; i++){
408 	  plugin_port->scale_point[i] = NULL;
409 	}
410 
411 	plugin_port->scale_point[scale_steps] = NULL;
412 
413 	/* scale value */
414 	if(plugin_port->scale_value == NULL){
415 	  plugin_port->scale_value = (gdouble *) malloc(scale_steps * sizeof(gdouble));
416 	}else{
417 	  plugin_port->scale_value = (gdouble *) realloc(plugin_port->scale_value,
418 							 scale_steps * sizeof(gdouble));
419 	}
420 
421 	for(i = scale_steps; i < plugin_port->scale_steps; i++){
422 	  plugin_port->scale_value[i] = 0.0;
423 	}
424       }else{
425 	g_free(plugin_port->scale_point);
426 	g_free(plugin_port->scale_value);
427 
428 	plugin_port->scale_point = NULL;
429 	plugin_port->scale_value = NULL;
430       }
431 
432       plugin_port->scale_steps = scale_steps;
433 
434       g_rec_mutex_unlock(plugin_port_mutex);
435     }
436     break;
437   case PROP_LOWER_VALUE:
438     {
439       GValue *lower_value;
440 
441       lower_value = (GValue *) g_value_get_pointer(value);
442 
443       g_rec_mutex_lock(plugin_port_mutex);
444 
445       g_value_copy(plugin_port->lower_value,
446 		   lower_value);
447 
448       g_rec_mutex_unlock(plugin_port_mutex);
449     }
450     break;
451   case PROP_UPPER_VALUE:
452     {
453       GValue *upper_value;
454 
455       upper_value = (GValue *) g_value_get_pointer(value);
456 
457       g_rec_mutex_lock(plugin_port_mutex);
458 
459       g_value_copy(plugin_port->upper_value,
460 		   upper_value);
461 
462       g_rec_mutex_unlock(plugin_port_mutex);
463     }
464     break;
465   case PROP_DEFAULT_VALUE:
466     {
467       GValue *default_value;
468 
469       default_value = (GValue *) g_value_get_pointer(value);
470 
471       g_rec_mutex_lock(plugin_port_mutex);
472 
473       g_value_copy(plugin_port->default_value,
474 		   default_value);
475 
476       g_rec_mutex_unlock(plugin_port_mutex);
477     }
478     break;
479   default:
480     G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, prop_id, param_spec);
481     break;
482   }
483 }
484 
485 void
ags_plugin_port_get_property(GObject * gobject,guint prop_id,GValue * value,GParamSpec * param_spec)486 ags_plugin_port_get_property(GObject *gobject,
487 			     guint prop_id,
488 			     GValue *value,
489 			     GParamSpec *param_spec)
490 {
491   AgsPluginPort *plugin_port;
492 
493   GRecMutex *plugin_port_mutex;
494 
495   plugin_port = AGS_PLUGIN_PORT(gobject);
496 
497   /* get plugin port mutex */
498   plugin_port_mutex = AGS_PLUGIN_PORT_GET_OBJ_MUTEX(plugin_port);
499 
500   switch(prop_id){
501   case PROP_PORT_INDEX:
502     {
503       g_rec_mutex_lock(plugin_port_mutex);
504 
505       g_value_set_uint(value,
506 		       plugin_port->port_index);
507 
508       g_rec_mutex_unlock(plugin_port_mutex);
509     }
510     break;
511   case PROP_PORT_NAME:
512     {
513       g_rec_mutex_lock(plugin_port_mutex);
514 
515       g_value_set_string(value,
516 			 plugin_port->port_name);
517 
518       g_rec_mutex_unlock(plugin_port_mutex);
519     }
520     break;
521   case PROP_PORT_SYMBOL:
522     {
523       g_rec_mutex_lock(plugin_port_mutex);
524 
525       g_value_set_string(value,
526 			 plugin_port->port_symbol);
527 
528       g_rec_mutex_unlock(plugin_port_mutex);
529     }
530     break;
531   case PROP_SCALE_STEPS:
532     {
533       g_rec_mutex_lock(plugin_port_mutex);
534 
535       g_value_set_int(value,
536 		      plugin_port->scale_steps);
537 
538       g_rec_mutex_unlock(plugin_port_mutex);
539     }
540     break;
541   case PROP_SCALE_POINT:
542     {
543       g_rec_mutex_lock(plugin_port_mutex);
544 
545       g_value_set_pointer(value,
546 			  g_strdupv(plugin_port->scale_point));
547 
548       g_rec_mutex_unlock(plugin_port_mutex);
549     }
550     break;
551   case PROP_SCALE_VALUE:
552     {
553       gdouble *scale_value;
554 
555       g_rec_mutex_lock(plugin_port_mutex);
556 
557       scale_value = (gdouble *) malloc(plugin_port->scale_steps * sizeof(gdouble));
558       memcpy(scale_value, plugin_port->scale_value, plugin_port->scale_steps * sizeof(gdouble));
559 
560       g_value_set_pointer(value,
561 			  scale_value);
562 
563       g_rec_mutex_unlock(plugin_port_mutex);
564     }
565     break;
566   case PROP_LOWER_VALUE:
567     {
568       GValue *lower_value;
569 
570       g_rec_mutex_lock(plugin_port_mutex);
571 
572       lower_value = g_new0(GValue,
573 			   1);
574       g_value_init(lower_value,
575 		   G_VALUE_TYPE(plugin_port->lower_value));
576 
577       g_value_copy(plugin_port->lower_value,
578 		   lower_value);
579 
580       g_value_set_pointer(value,
581 			  lower_value);
582 
583       g_rec_mutex_unlock(plugin_port_mutex);
584     }
585     break;
586   case PROP_UPPER_VALUE:
587     {
588       GValue *upper_value;
589 
590       g_rec_mutex_lock(plugin_port_mutex);
591 
592       upper_value = g_new0(GValue,
593 			   1);
594       g_value_init(upper_value,
595 		   G_VALUE_TYPE(plugin_port->upper_value));
596 
597       g_value_copy(plugin_port->upper_value,
598 		   upper_value);
599 
600       g_value_set_pointer(value,
601 			  upper_value);
602 
603       g_rec_mutex_unlock(plugin_port_mutex);
604     }
605     break;
606   case PROP_DEFAULT_VALUE:
607     {
608       GValue *default_value;
609 
610       g_rec_mutex_lock(plugin_port_mutex);
611 
612       default_value = g_new0(GValue,
613 			   1);
614       g_value_init(default_value,
615 		   G_VALUE_TYPE(plugin_port->default_value));
616 
617       g_value_copy(plugin_port->default_value,
618 		   default_value);
619 
620       g_value_set_pointer(value,
621 			  default_value);
622 
623       g_rec_mutex_unlock(plugin_port_mutex);
624     }
625     break;
626   default:
627     G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, prop_id, param_spec);
628     break;
629   }
630 }
631 
632 void
ags_plugin_port_dispose(GObject * gobject)633 ags_plugin_port_dispose(GObject *gobject)
634 {
635   AgsPluginPort *plugin_port;
636 
637   plugin_port = AGS_PLUGIN_PORT(gobject);
638 
639   /* call parent */
640   G_OBJECT_CLASS(ags_plugin_port_parent_class)->dispose(gobject);
641 }
642 
643 void
ags_plugin_port_finalize(GObject * gobject)644 ags_plugin_port_finalize(GObject *gobject)
645 {
646   AgsPluginPort *plugin_port;
647 
648   plugin_port = AGS_PLUGIN_PORT(gobject);
649 
650   if(plugin_port->port_name != NULL){
651     g_free(plugin_port->port_name);
652   }
653 
654   if(plugin_port->port_symbol != NULL){
655     g_free(plugin_port->port_symbol);
656   }
657 
658   if(plugin_port->scale_point != NULL){
659     g_free(plugin_port->scale_point);
660   }
661 
662   g_free(plugin_port->lower_value);
663   g_free(plugin_port->upper_value);
664 
665   g_free(plugin_port->default_value);
666 
667   /* call parent */
668   G_OBJECT_CLASS(ags_plugin_port_parent_class)->finalize(gobject);
669 }
670 
671 /**
672  * ags_plugin_port_get_obj_mutex:
673  * @plugin_port: the #AgsPluginPort
674  *
675  * Get object mutex.
676  *
677  * Returns: the #GRecMutex to lock @plugin_port
678  *
679  * Since: 3.1.0
680  */
681 GRecMutex*
ags_plugin_port_get_obj_mutex(AgsPluginPort * plugin_port)682 ags_plugin_port_get_obj_mutex(AgsPluginPort *plugin_port)
683 {
684   if(!AGS_IS_PLUGIN_PORT(plugin_port)){
685     return(NULL);
686   }
687 
688   return(AGS_PLUGIN_PORT_GET_OBJ_MUTEX(plugin_port));
689 }
690 
691 /**
692  * ags_plugin_port_test_flags:
693  * @plugin_port: the #AgsPluginPort
694  * @flags: the flags
695  *
696  * Test @flags to be set on @plugin_port.
697  *
698  * Returns: %TRUE if flags are set, else %FALSE
699  *
700  * Since: 3.0.0
701  */
702 gboolean
ags_plugin_port_test_flags(AgsPluginPort * plugin_port,guint flags)703 ags_plugin_port_test_flags(AgsPluginPort *plugin_port, guint flags)
704 {
705   gboolean retval;
706 
707   GRecMutex *plugin_port_mutex;
708 
709   if(!AGS_IS_PLUGIN_PORT(plugin_port)){
710     return(FALSE);
711   }
712 
713   /* get plugin_port mutex */
714   plugin_port_mutex = AGS_PLUGIN_PORT_GET_OBJ_MUTEX(plugin_port);
715 
716   /* test */
717   g_rec_mutex_lock(plugin_port_mutex);
718 
719   retval = (flags & (plugin_port->flags)) ? TRUE: FALSE;
720 
721   g_rec_mutex_unlock(plugin_port_mutex);
722 
723   return(retval);
724 }
725 
726 /**
727  * ags_plugin_port_set_flags:
728  * @plugin_port: the #AgsPluginPort
729  * @flags: the flags
730  *
731  * Set @flags on @plugin_port.
732  *
733  * Since: 3.0.0
734  */
735 void
ags_plugin_port_set_flags(AgsPluginPort * plugin_port,guint flags)736 ags_plugin_port_set_flags(AgsPluginPort *plugin_port, guint flags)
737 {
738   GRecMutex *plugin_port_mutex;
739 
740   if(!AGS_IS_PLUGIN_PORT(plugin_port)){
741     return;
742   }
743 
744   /* get plugin_port mutex */
745   plugin_port_mutex = AGS_PLUGIN_PORT_GET_OBJ_MUTEX(plugin_port);
746 
747   /* set */
748   g_rec_mutex_lock(plugin_port_mutex);
749 
750   plugin_port->flags |= flags;
751 
752   g_rec_mutex_unlock(plugin_port_mutex);
753 }
754 
755 /**
756  * ags_plugin_port_unset_flags:
757  * @plugin_port: the #AgsPluginPort
758  * @flags: the flags
759  *
760  * Unset @flags on @plugin_port.
761  *
762  * Since: 3.0.0
763  */
764 void
ags_plugin_port_unset_flags(AgsPluginPort * plugin_port,guint flags)765 ags_plugin_port_unset_flags(AgsPluginPort *plugin_port, guint flags)
766 {
767   GRecMutex *plugin_port_mutex;
768 
769   if(!AGS_IS_PLUGIN_PORT(plugin_port)){
770     return;
771   }
772 
773   /* get plugin_port mutex */
774   plugin_port_mutex = AGS_PLUGIN_PORT_GET_OBJ_MUTEX(plugin_port);
775 
776   /* unset */
777   g_rec_mutex_lock(plugin_port_mutex);
778 
779   plugin_port->flags &= (~flags);
780 
781   g_rec_mutex_unlock(plugin_port_mutex);
782 }
783 
784 /**
785  * ags_plugin_port_get_port_index:
786  * @plugin_port: the #AgsPluginPort
787  *
788  * Get port index.
789  *
790  * Returns: the port index
791  *
792  * Since: 3.1.0
793  */
794 guint
ags_plugin_port_get_port_index(AgsPluginPort * plugin_port)795 ags_plugin_port_get_port_index(AgsPluginPort *plugin_port)
796 {
797   guint port_index;
798 
799   if(!AGS_IS_PLUGIN_PORT(plugin_port)){
800     return(NULL);
801   }
802 
803   g_object_get(plugin_port,
804 	       "port-index", &port_index,
805 	       NULL);
806 
807   return(port_index);
808 }
809 
810 /**
811  * ags_plugin_port_set_port_index:
812  * @plugin_port: the #AgsPluginPort
813  * @port_index: the port index
814  *
815  * Set port index.
816  *
817  * Since: 3.1.0
818  */
819 void
ags_plugin_port_set_port_index(AgsPluginPort * plugin_port,guint port_index)820 ags_plugin_port_set_port_index(AgsPluginPort *plugin_port,
821 			       guint port_index)
822 {
823   if(!AGS_IS_PLUGIN_PORT(plugin_port)){
824     return;
825   }
826 
827   g_object_set(plugin_port,
828 	       "port-index", port_index,
829 	       NULL);
830 }
831 
832 /**
833  * ags_plugin_port_get_port_name:
834  * @plugin_port: the #AgsPluginPort
835  *
836  * Get port name.
837  *
838  * Returns: the port name
839  *
840  * Since: 3.1.0
841  */
842 gchar*
ags_plugin_port_get_port_name(AgsPluginPort * plugin_port)843 ags_plugin_port_get_port_name(AgsPluginPort *plugin_port)
844 {
845   gchar *port_name;
846 
847   if(!AGS_IS_PLUGIN_PORT(plugin_port)){
848     return(NULL);
849   }
850 
851   g_object_get(plugin_port,
852 	       "port-name", &port_name,
853 	       NULL);
854 
855   return(port_name);
856 }
857 
858 /**
859  * ags_plugin_port_set_port_name:
860  * @plugin_port: the #AgsPluginPort
861  * @port_name: the port name
862  *
863  * Set port name.
864  *
865  * Since: 3.1.0
866  */
867 void
ags_plugin_port_set_port_name(AgsPluginPort * plugin_port,gchar * port_name)868 ags_plugin_port_set_port_name(AgsPluginPort *plugin_port,
869 			     gchar *port_name)
870 {
871   if(!AGS_IS_PLUGIN_PORT(plugin_port)){
872     return;
873   }
874 
875   g_object_set(plugin_port,
876 	       "port-name", port_name,
877 	       NULL);
878 }
879 
880 /**
881  * ags_plugin_port_get_port_symbol:
882  * @plugin_port: the #AgsPluginPort
883  *
884  * Get port symbol.
885  *
886  * Returns: the port symbol
887  *
888  * Since: 3.1.0
889  */
890 gchar*
ags_plugin_port_get_port_symbol(AgsPluginPort * plugin_port)891 ags_plugin_port_get_port_symbol(AgsPluginPort *plugin_port)
892 {
893   gchar *port_symbol;
894 
895   if(!AGS_IS_PLUGIN_PORT(plugin_port)){
896     return(NULL);
897   }
898 
899   g_object_get(plugin_port,
900 	       "port-symbol", &port_symbol,
901 	       NULL);
902 
903   return(port_symbol);
904 }
905 
906 /**
907  * ags_plugin_port_set_port_symbol:
908  * @plugin_port: the #AgsPluginPort
909  * @port_symbol: the port symbol
910  *
911  * Set port symbol.
912  *
913  * Since: 3.1.0
914  */
915 void
ags_plugin_port_set_port_symbol(AgsPluginPort * plugin_port,gchar * port_symbol)916 ags_plugin_port_set_port_symbol(AgsPluginPort *plugin_port,
917 				gchar *port_symbol)
918 {
919   if(!AGS_IS_PLUGIN_PORT(plugin_port)){
920     return;
921   }
922 
923   g_object_set(plugin_port,
924 	       "port-symbol", port_symbol,
925 	       NULL);
926 }
927 
928 
929 /**
930  * ags_plugin_port_get_scale_steps:
931  * @plugin_port: the #AgsPluginPort
932  *
933  * Get scale steps.
934  *
935  * Returns: the scale steps
936  *
937  * Since: 3.1.0
938  */
939 gint
ags_plugin_port_get_scale_steps(AgsPluginPort * plugin_port)940 ags_plugin_port_get_scale_steps(AgsPluginPort *plugin_port)
941 {
942   guint scale_steps;
943 
944   if(!AGS_IS_PLUGIN_PORT(plugin_port)){
945     return(NULL);
946   }
947 
948   g_object_get(plugin_port,
949 	       "scale-steps", &scale_steps,
950 	       NULL);
951 
952   return(scale_steps);
953 }
954 
955 /**
956  * ags_plugin_port_set_scale_steps:
957  * @plugin_port: the #AgsPluginPort
958  * @scale_steps: the scale steps
959  *
960  * Set scale steps.
961  *
962  * Since: 3.1.0
963  */
964 void
ags_plugin_port_set_scale_steps(AgsPluginPort * plugin_port,gint scale_steps)965 ags_plugin_port_set_scale_steps(AgsPluginPort *plugin_port,
966 				gint scale_steps)
967 {
968   if(!AGS_IS_PLUGIN_PORT(plugin_port)){
969     return;
970   }
971 
972   g_object_set(plugin_port,
973 	       "scale-steps", scale_steps,
974 	       NULL);
975 }
976 
977 /**
978  * ags_plugin_port_get_scale_point:
979  * @plugin_port: the #AgsPluginPort
980  *
981  * Get scale point.
982  *
983  * Returns: the scale point
984  *
985  * Since: 3.1.0
986  */
987 gchar**
ags_plugin_port_get_scale_point(AgsPluginPort * plugin_port)988 ags_plugin_port_get_scale_point(AgsPluginPort *plugin_port)
989 {
990   gchar **scale_point;
991 
992   if(!AGS_IS_PLUGIN_PORT(plugin_port)){
993     return(NULL);
994   }
995 
996   g_object_get(plugin_port,
997 	       "scale-point", &scale_point,
998 	       NULL);
999 
1000   return(scale_point);
1001 }
1002 
1003 /**
1004  * ags_plugin_port_set_scale_point:
1005  * @plugin_port: the #AgsPluginPort
1006  * @scale_point: the scale point
1007  *
1008  * Set scale point.
1009  *
1010  * Since: 3.1.0
1011  */
1012 void
ags_plugin_port_set_scale_point(AgsPluginPort * plugin_port,gchar ** scale_point)1013 ags_plugin_port_set_scale_point(AgsPluginPort *plugin_port,
1014 				gchar **scale_point)
1015 {
1016   GRecMutex *plugin_port_mutex;
1017 
1018   if(!AGS_IS_PLUGIN_PORT(plugin_port)){
1019     return;
1020   }
1021 
1022   /* get plugin port mutex */
1023   plugin_port_mutex = AGS_PLUGIN_PORT_GET_OBJ_MUTEX(plugin_port);
1024 
1025   g_rec_mutex_lock(plugin_port_mutex);
1026 
1027   g_strfreev(plugin_port->scale_point);
1028 
1029   plugin_port->scale_point = scale_point;
1030 
1031   g_rec_mutex_unlock(plugin_port_mutex);
1032 }
1033 
1034 /**
1035  * ags_plugin_port_get_scale_value:
1036  * @plugin_port: the #AgsPluginPort
1037  *
1038  * Get scale value.
1039  *
1040  * Returns: the scale value
1041  *
1042  * Since: 3.1.0
1043  */
1044 gdouble*
ags_plugin_port_get_scale_value(AgsPluginPort * plugin_port)1045 ags_plugin_port_get_scale_value(AgsPluginPort *plugin_port)
1046 {
1047   gdouble *scale_value;
1048 
1049   if(!AGS_IS_PLUGIN_PORT(plugin_port)){
1050     return(NULL);
1051   }
1052 
1053   g_object_get(plugin_port,
1054 	       "scale-value", &scale_value,
1055 	       NULL);
1056 
1057   return(scale_value);
1058 }
1059 
1060 /**
1061  * ags_plugin_port_set_scale_value:
1062  * @plugin_port: the #AgsPluginPort
1063  * @scale_value: the scale value
1064  *
1065  * Set scale value.
1066  *
1067  * Since: 3.1.0
1068  */
1069 void
ags_plugin_port_set_scale_value(AgsPluginPort * plugin_port,gdouble * scale_value)1070 ags_plugin_port_set_scale_value(AgsPluginPort *plugin_port,
1071 				gdouble *scale_value)
1072 {
1073   GRecMutex *plugin_port_mutex;
1074 
1075   if(!AGS_IS_PLUGIN_PORT(plugin_port)){
1076     return;
1077   }
1078 
1079   /* get plugin port mutex */
1080   plugin_port_mutex = AGS_PLUGIN_PORT_GET_OBJ_MUTEX(plugin_port);
1081 
1082   g_rec_mutex_lock(plugin_port_mutex);
1083 
1084   if(plugin_port->scale_value != NULL){
1085     free(plugin_port->scale_value);
1086   }
1087 
1088   plugin_port->scale_value = scale_value;
1089 
1090   g_rec_mutex_unlock(plugin_port_mutex);
1091 }
1092 
1093 /**
1094  * ags_plugin_port_get_lower_value:
1095  * @plugin_port: the #AgsPluginPort
1096  *
1097  * Get lower value.
1098  *
1099  * Returns: the lower value
1100  *
1101  * Since: 3.1.0
1102  */
1103 GValue*
ags_plugin_port_get_lower_value(AgsPluginPort * plugin_port)1104 ags_plugin_port_get_lower_value(AgsPluginPort *plugin_port)
1105 {
1106   GValue *lower_value;
1107 
1108   if(!AGS_IS_PLUGIN_PORT(plugin_port)){
1109     return(NULL);
1110   }
1111 
1112   g_object_get(plugin_port,
1113 	       "lower-value", &lower_value,
1114 	       NULL);
1115 
1116   return(lower_value);
1117 }
1118 
1119 /**
1120  * ags_plugin_port_set_lower_value:
1121  * @plugin_port: the #AgsPluginPort
1122  * @lower_value: the lower value
1123  *
1124  * Set lower value.
1125  *
1126  * Since: 3.1.0
1127  */
1128 void
ags_plugin_port_set_lower_value(AgsPluginPort * plugin_port,GValue * lower_value)1129 ags_plugin_port_set_lower_value(AgsPluginPort *plugin_port,
1130 				GValue *lower_value)
1131 {
1132   if(!AGS_IS_PLUGIN_PORT(plugin_port)){
1133     return;
1134   }
1135 
1136   g_object_set(plugin_port,
1137 	       "lower-value", lower_value,
1138 	       NULL);
1139 }
1140 
1141 /**
1142  * ags_plugin_port_get_upper_value:
1143  * @plugin_port: the #AgsPluginPort
1144  *
1145  * Get upper value.
1146  *
1147  * Returns: the upper value
1148  *
1149  * Since: 3.1.0
1150  */
1151 GValue*
ags_plugin_port_get_upper_value(AgsPluginPort * plugin_port)1152 ags_plugin_port_get_upper_value(AgsPluginPort *plugin_port)
1153 {
1154   GValue *upper_value;
1155 
1156   if(!AGS_IS_PLUGIN_PORT(plugin_port)){
1157     return(NULL);
1158   }
1159 
1160   g_object_get(plugin_port,
1161 	       "upper-value", &upper_value,
1162 	       NULL);
1163 
1164   return(upper_value);
1165 }
1166 
1167 /**
1168  * ags_plugin_port_set_upper_value:
1169  * @plugin_port: the #AgsPluginPort
1170  * @upper_value: the upper value
1171  *
1172  * Set upper value.
1173  *
1174  * Since: 3.1.0
1175  */
1176 void
ags_plugin_port_set_upper_value(AgsPluginPort * plugin_port,GValue * upper_value)1177 ags_plugin_port_set_upper_value(AgsPluginPort *plugin_port,
1178 				GValue *upper_value)
1179 {
1180   if(!AGS_IS_PLUGIN_PORT(plugin_port)){
1181     return;
1182   }
1183 
1184   g_object_set(plugin_port,
1185 	       "upper-value", upper_value,
1186 	       NULL);
1187 }
1188 
1189 /**
1190  * ags_plugin_port_get_default_value:
1191  * @plugin_port: the #AgsPluginPort
1192  *
1193  * Get default value.
1194  *
1195  * Returns: the default value
1196  *
1197  * Since: 3.1.0
1198  */
1199 GValue*
ags_plugin_port_get_default_value(AgsPluginPort * plugin_port)1200 ags_plugin_port_get_default_value(AgsPluginPort *plugin_port)
1201 {
1202   GValue *default_value;
1203 
1204   if(!AGS_IS_PLUGIN_PORT(plugin_port)){
1205     return(NULL);
1206   }
1207 
1208   g_object_get(plugin_port,
1209 	       "default-value", &default_value,
1210 	       NULL);
1211 
1212   return(default_value);
1213 }
1214 
1215 /**
1216  * ags_plugin_port_set_default_value:
1217  * @plugin_port: the #AgsPluginPort
1218  * @default_value: the default value
1219  *
1220  * Set default value.
1221  *
1222  * Since: 3.1.0
1223  */
1224 void
ags_plugin_port_set_default_value(AgsPluginPort * plugin_port,GValue * default_value)1225 ags_plugin_port_set_default_value(AgsPluginPort *plugin_port,
1226 				  GValue *default_value)
1227 {
1228   if(!AGS_IS_PLUGIN_PORT(plugin_port)){
1229     return;
1230   }
1231 
1232   g_object_set(plugin_port,
1233 	       "default-value", default_value,
1234 	       NULL);
1235 }
1236 
1237 /**
1238  * ags_plugin_port_find_symbol:
1239  * @plugin_port: (element-type AgsAudio.PluginPort) (transfer none): the #GList-struct containing #AgsPluginPort
1240  * @port_symbol: the port symbol
1241  *
1242  * Find @port_symbol within @plugin_port.
1243  *
1244  * Returns: (element-type AgsAudio.PluginPort) (transfer none): the matching #GList-struct containing #AgsPluginPort
1245  *
1246  * Since: 3.0.0
1247  */
1248 GList*
ags_plugin_port_find_symbol(GList * plugin_port,gchar * port_symbol)1249 ags_plugin_port_find_symbol(GList *plugin_port,
1250 			    gchar *port_symbol)
1251 {
1252   AgsPluginPort *current_plugin_port;
1253 
1254   gboolean success;
1255 
1256   GRecMutex *plugin_port_mutex;
1257 
1258   if(port_symbol == NULL){
1259     return(NULL);
1260   }
1261 
1262   while(plugin_port != NULL){
1263     current_plugin_port = AGS_PLUGIN_PORT(plugin_port->data);
1264 
1265     /* get plugin port mutex */
1266     plugin_port_mutex = AGS_PLUGIN_PORT_GET_OBJ_MUTEX(current_plugin_port);
1267 
1268     /* check port symbol */
1269     g_rec_mutex_lock(plugin_port_mutex);
1270 
1271     success = (!g_strcmp0(port_symbol,
1272 			  current_plugin_port->port_symbol)) ? TRUE: FALSE;
1273 
1274     g_rec_mutex_unlock(plugin_port_mutex);
1275 
1276     if(success){
1277       return(plugin_port);
1278     }
1279 
1280     plugin_port = plugin_port->next;
1281   }
1282 
1283   return(NULL);
1284 }
1285 
1286 /**
1287  * ags_plugin_port_find_port_index:
1288  * @plugin_port: (element-type AgsAudio.PluginPort) (transfer none): the #GList-struct containing #AgsPluginPort
1289  * @port_index: the port index
1290  *
1291  * Find @port_index within @plugin_port.
1292  *
1293  * Returns: (element-type AgsAudio.PluginPort) (transfer none): the matching #GList-struct containing #AgsPluginPort
1294  *
1295  * Since: 3.0.0
1296  */
1297 GList*
ags_plugin_port_find_port_index(GList * plugin_port,guint port_index)1298 ags_plugin_port_find_port_index(GList *plugin_port,
1299 				guint port_index)
1300 {
1301   AgsPluginPort *current_plugin_port;
1302 
1303   gboolean success;
1304 
1305   GRecMutex *plugin_port_mutex;
1306 
1307   while(plugin_port != NULL){
1308     current_plugin_port = AGS_PLUGIN_PORT(plugin_port->data);
1309 
1310     /* get plugin port mutex */
1311     plugin_port_mutex = AGS_PLUGIN_PORT_GET_OBJ_MUTEX(current_plugin_port);
1312 
1313     /* check port symbol */
1314     g_rec_mutex_lock(plugin_port_mutex);
1315 
1316     success = (port_index == current_plugin_port->port_index) ? TRUE: FALSE;
1317 
1318     g_rec_mutex_unlock(plugin_port_mutex);
1319 
1320     if(success){
1321       return(plugin_port);
1322     }
1323 
1324     plugin_port = plugin_port->next;
1325   }
1326 
1327   return(NULL);
1328 }
1329 
1330 /**
1331  * ags_plugin_port_new:
1332  *
1333  * Creates an #AgsPluginPort
1334  *
1335  * Returns: a new #AgsPluginPort
1336  *
1337  * Since: 3.0.0
1338  */
1339 AgsPluginPort*
ags_plugin_port_new()1340 ags_plugin_port_new()
1341 {
1342   AgsPluginPort *plugin_port;
1343 
1344   plugin_port = (AgsPluginPort *) g_object_new(AGS_TYPE_PLUGIN_PORT,
1345 					       NULL);
1346 
1347   return(plugin_port);
1348 }
1349