1 /* GSequencer - Advanced GTK Sequencer
2  * Copyright (C) 2005-2019 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/recall/ags_lfo_channel.h>
21 
22 #include <ags/plugin/ags_plugin_port.h>
23 
24 #include <ags/audio/ags_synth_enums.h>
25 
26 #include <ags/i18n.h>
27 
28 void ags_lfo_channel_class_init(AgsLfoChannelClass *lfo_channel);
29 void ags_lfo_channel_init(AgsLfoChannel *lfo_channel);
30 void ags_lfo_channel_set_property(GObject *gobject,
31 				  guint prop_id,
32 				  const GValue *value,
33 				  GParamSpec *param_spec);
34 void ags_lfo_channel_get_property(GObject *gobject,
35 				  guint prop_id,
36 				  GValue *value,
37 				  GParamSpec *param_spec);
38 void ags_lfo_channel_dispose(GObject *gobject);
39 void ags_lfo_channel_finalize(GObject *gobject);
40 
41 static AgsPluginPort* ags_lfo_channel_get_enabled_plugin_port();
42 static AgsPluginPort* ags_lfo_channel_get_lfo_wave_plugin_port();
43 static AgsPluginPort* ags_lfo_channel_get_lfo_freq_plugin_port();
44 static AgsPluginPort* ags_lfo_channel_get_lfo_phase_plugin_port();
45 static AgsPluginPort* ags_lfo_channel_get_lfo_depth_plugin_port();
46 static AgsPluginPort* ags_lfo_channel_get_lfo_tuning_plugin_port();
47 
48 /**
49  * SECTION:ags_lfo_channel
50  * @short_description: lfos channel
51  * @title: AgsLfoChannel
52  * @section_id:
53  * @include: ags/audio/recall/ags_lfo_channel.h
54  *
55  * The #AgsLfoChannel class provides ports to the effect processor.
56  */
57 
58 enum{
59   PROP_0,
60   PROP_ENABLED,
61   PROP_LFO_WAVE,
62   PROP_LFO_FREQ,
63   PROP_LFO_PHASE,
64   PROP_LFO_DEPTH,
65   PROP_LFO_TUNING,
66 };
67 
68 static gpointer ags_lfo_channel_parent_class = NULL;
69 
70 const gchar *ags_lfo_channel_plugin_name = "ags-lfo";
71 const gchar *ags_lfo_channel_specifier[] = {
72   "./enabled[0]",
73   "./lfo-wave[0]",
74   "./lfo-freq[0]",
75   "./lfo-phase[0]",
76   "./lfo-depth[0]",
77   "./lfo-tuning[0]"
78 };
79 const gchar *ags_lfo_channel_control_port[] = {
80   "1/6",
81   "2/6",
82   "3/6",
83   "4/6",
84   "5/6",
85   "6/6"
86 };
87 
88 GType
ags_lfo_channel_get_type()89 ags_lfo_channel_get_type()
90 {
91   static volatile gsize g_define_type_id__volatile = 0;
92 
93   if(g_once_init_enter (&g_define_type_id__volatile)){
94     GType ags_type_lfo_channel = 0;
95 
96     static const GTypeInfo ags_lfo_channel_info = {
97       sizeof (AgsLfoChannelClass),
98       NULL, /* base_init */
99       NULL, /* base_finalize */
100       (GClassInitFunc) ags_lfo_channel_class_init,
101       NULL, /* class_finalize */
102       NULL, /* class_data */
103       sizeof (AgsLfoChannel),
104       0,    /* n_preallocs */
105       (GInstanceInitFunc) ags_lfo_channel_init,
106     };
107 
108     ags_type_lfo_channel = g_type_register_static(AGS_TYPE_RECALL_CHANNEL,
109 						  "AgsLfoChannel",
110 						  &ags_lfo_channel_info,
111 						  0);
112 
113     g_once_init_leave(&g_define_type_id__volatile, ags_type_lfo_channel);
114   }
115 
116   return g_define_type_id__volatile;
117 }
118 
119 void
ags_lfo_channel_class_init(AgsLfoChannelClass * lfo_channel)120 ags_lfo_channel_class_init(AgsLfoChannelClass *lfo_channel)
121 {
122   GObjectClass *gobject;
123   AgsRecallClass *recall;
124   GParamSpec *param_spec;
125 
126   ags_lfo_channel_parent_class = g_type_class_peek_parent(lfo_channel);
127 
128   /* GObjectClass */
129   gobject = (GObjectClass *) lfo_channel;
130 
131   gobject->set_property = ags_lfo_channel_set_property;
132   gobject->get_property = ags_lfo_channel_get_property;
133 
134   gobject->dispose = ags_lfo_channel_dispose;
135   gobject->finalize = ags_lfo_channel_finalize;
136 
137   /* properties */
138   /**
139    * AgsLfoChannel:enabled:
140    *
141    * The enabled port.
142    *
143    * Since: 3.0.0
144    */
145   param_spec = g_param_spec_object("enabled",
146 				   i18n_pspec("enabled"),
147 				   i18n_pspec("If LFO is enabled"),
148 				   AGS_TYPE_PORT,
149 				   G_PARAM_READABLE | G_PARAM_WRITABLE);
150   g_object_class_install_property(gobject,
151 				  PROP_ENABLED,
152 				  param_spec);
153 
154   /**
155    * AgsLfoChannel:lfo-wave:
156    *
157    * The lfo-wave port.
158    *
159    * Since: 3.0.0
160    */
161   param_spec = g_param_spec_object("lfo-wave",
162 				   i18n_pspec("lfo wave to apply"),
163 				   i18n_pspec("The lfo wave to apply on the channel"),
164 				   AGS_TYPE_PORT,
165 				   G_PARAM_READABLE | G_PARAM_WRITABLE);
166   g_object_class_install_property(gobject,
167 				  PROP_LFO_WAVE,
168 				  param_spec);
169 
170   /**
171    * AgsLfoChannel:lfo-freq:
172    *
173    * The lfo-freq port.
174    *
175    * Since: 3.0.0
176    */
177   param_spec = g_param_spec_object("lfo-freq",
178 				   i18n_pspec("lfo frequency to apply"),
179 				   i18n_pspec("The lfo frequency to apply on the channel"),
180 				   AGS_TYPE_PORT,
181 				   G_PARAM_READABLE | G_PARAM_WRITABLE);
182   g_object_class_install_property(gobject,
183 				  PROP_LFO_FREQ,
184 				  param_spec);
185 
186   /**
187    * AgsLfoChannel:lfo-phase:
188    *
189    * The lfo-phase port.
190    *
191    * Since: 3.0.0
192    */
193   param_spec = g_param_spec_object("lfo-phase",
194 				   i18n_pspec("lfo phase to apply"),
195 				   i18n_pspec("The lfo phase to apply on the channel"),
196 				   AGS_TYPE_PORT,
197 				   G_PARAM_READABLE | G_PARAM_WRITABLE);
198   g_object_class_install_property(gobject,
199 				  PROP_LFO_PHASE,
200 				  param_spec);
201 
202   /**
203    * AgsLfoChannel:lfo-depth:
204    *
205    * The lfo-depth port.
206    *
207    * Since: 3.0.0
208    */
209   param_spec = g_param_spec_object("lfo-depth",
210 				   i18n_pspec("lfo depth to apply"),
211 				   i18n_pspec("The lfo depth to apply on the channel"),
212 				   AGS_TYPE_PORT,
213 				   G_PARAM_READABLE | G_PARAM_WRITABLE);
214   g_object_class_install_property(gobject,
215 				  PROP_LFO_DEPTH,
216 				  param_spec);
217 
218   /**
219    * AgsLfoChannel:lfo-tuning:
220    *
221    * The lfo-tuning port.
222    *
223    * Since: 3.0.0
224    */
225   param_spec = g_param_spec_object("lfo-tuning",
226 				   i18n_pspec("lfo tuning to apply"),
227 				   i18n_pspec("The lfo tuning to apply on the channel"),
228 				   AGS_TYPE_PORT,
229 				   G_PARAM_READABLE | G_PARAM_WRITABLE);
230   g_object_class_install_property(gobject,
231 				  PROP_LFO_TUNING,
232 				  param_spec);
233 }
234 
235 void
ags_lfo_channel_init(AgsLfoChannel * lfo_channel)236 ags_lfo_channel_init(AgsLfoChannel *lfo_channel)
237 {
238   GList *port;
239 
240   AGS_RECALL(lfo_channel)->name = "ags-lfo";
241   AGS_RECALL(lfo_channel)->version = AGS_RECALL_DEFAULT_VERSION;
242   AGS_RECALL(lfo_channel)->build_id = AGS_RECALL_DEFAULT_BUILD_ID;
243   AGS_RECALL(lfo_channel)->xml_type = "ags-lfo-channel";
244 
245   /* initialize the port */
246   port = NULL;
247 
248   /* enabled */
249   lfo_channel->enabled = g_object_new(AGS_TYPE_PORT,
250 				      "plugin-name", "ags-lfo",
251 				      "specifier", "./enabled[0]",
252 				      "control-port", "1/5",
253 				      "port-value-is-pointer", FALSE,
254 				      "port-value-type", G_TYPE_FLOAT,
255 				      "port-value-size", sizeof(gfloat),
256 				      "port-value-length", 1,
257 				      NULL);
258   g_object_ref(lfo_channel->enabled);
259 
260   lfo_channel->enabled->port_value.ags_port_float = 0.0;
261 
262   /* port descriptor */
263   g_object_set(lfo_channel->enabled,
264 	       "plugin-port", ags_lfo_channel_get_enabled_plugin_port(),
265 	       NULL);
266 
267   /* add to port */
268   port = g_list_prepend(port, lfo_channel->enabled);
269   g_object_ref(lfo_channel->enabled);
270 
271   /* lfo wave */
272   lfo_channel->lfo_wave = g_object_new(AGS_TYPE_PORT,
273 				       "plugin-name", "ags-lfo",
274 				       "specifier", "./lfo-wave[0]",
275 				       "control-port", "4/5",
276 				       "port-value-is-pointer", FALSE,
277 				       "port-value-type", G_TYPE_FLOAT,
278 				       "port-value-size", sizeof(gfloat),
279 				       "port-value-length", 1,
280 				       NULL);
281   g_object_ref(lfo_channel->lfo_wave);
282 
283   lfo_channel->lfo_wave->port_value.ags_port_float = 0.0;
284 
285   /* port descriptor */
286   g_object_set(lfo_channel->lfo_wave,
287 	       "plugin-port", ags_lfo_channel_get_lfo_wave_plugin_port(),
288 	       NULL);
289 
290   /* add to port */
291   port = g_list_prepend(port, lfo_channel->lfo_wave);
292   g_object_ref(lfo_channel->lfo_wave);
293 
294   /* lfo-freq */
295   lfo_channel->lfo_freq = g_object_new(AGS_TYPE_PORT,
296 				       "plugin-name", "ags-lfo",
297 				       "specifier", "./lfo-freq[0]",
298 				       "control-port", "2/5",
299 				       "port-value-is-pointer", FALSE,
300 				       "port-value-type", G_TYPE_FLOAT,
301 				       "port-value-size", sizeof(gfloat),
302 				       "port-value-length", 1,
303 				       NULL);
304   g_object_ref(lfo_channel->lfo_freq);
305 
306   lfo_channel->lfo_freq->port_value.ags_port_float = 0.0;
307 
308   /* port descriptor */
309   g_object_set(lfo_channel->lfo_freq,
310 	       "plugin-port", ags_lfo_channel_get_lfo_freq_plugin_port(),
311 	       NULL);
312 
313   /* add to port */
314   port = g_list_prepend(port, lfo_channel->lfo_freq);
315   g_object_ref(lfo_channel->lfo_freq);
316 
317   /* lfo phase */
318   lfo_channel->lfo_phase = g_object_new(AGS_TYPE_PORT,
319 					"plugin-name", "ags-lfo",
320 					"specifier", "./lfo-phase[0]",
321 					"control-port", "3/5",
322 					"port-value-is-pointer", FALSE,
323 					"port-value-type", G_TYPE_FLOAT,
324 					"port-value-size", sizeof(gfloat),
325 					"port-value-length", 1,
326 					NULL);
327   g_object_ref(lfo_channel->lfo_phase);
328 
329   lfo_channel->lfo_phase->port_value.ags_port_float = 0.0;
330 
331   /* port descriptor */
332   g_object_set(lfo_channel->lfo_phase,
333 	       "plugin-port", ags_lfo_channel_get_lfo_phase_plugin_port(),
334 	       NULL);
335 
336   /* add to port */
337   port = g_list_prepend(port, lfo_channel->lfo_phase);
338   g_object_ref(lfo_channel->lfo_phase);
339 
340   /* lfo depth */
341   lfo_channel->lfo_depth = g_object_new(AGS_TYPE_PORT,
342 					"plugin-name", "ags-lfo",
343 					"specifier", "./lfo-depth[0]",
344 					"control-port", "4/5",
345 					"port-value-is-pointer", FALSE,
346 					"port-value-type", G_TYPE_FLOAT,
347 					"port-value-size", sizeof(gfloat),
348 					"port-value-length", 1,
349 					NULL);
350   g_object_ref(lfo_channel->lfo_depth);
351 
352   lfo_channel->lfo_depth->port_value.ags_port_float = 0.0;
353 
354   /* port descriptor */
355   g_object_set(lfo_channel->lfo_depth,
356 	       "plugin-port", ags_lfo_channel_get_lfo_depth_plugin_port(),
357 	       NULL);
358 
359   /* add to port */
360   port = g_list_prepend(port, lfo_channel->lfo_depth);
361   g_object_ref(lfo_channel->lfo_depth);
362 
363   /* lfo tuning */
364   lfo_channel->lfo_tuning = g_object_new(AGS_TYPE_PORT,
365 					 "plugin-name", "ags-lfo",
366 					 "specifier", "./lfo-tuning[0]",
367 					 "control-port", "5/5",
368 					 "port-value-is-pointer", FALSE,
369 					 "port-value-type", G_TYPE_FLOAT,
370 					 "port-value-size", sizeof(gfloat),
371 					 "port-value-length", 1,
372 					 NULL);
373   g_object_ref(lfo_channel->lfo_tuning);
374 
375   lfo_channel->lfo_tuning->port_value.ags_port_float = 0.0;
376 
377   /* port descriptor */
378   g_object_set(lfo_channel->lfo_tuning,
379 	       "plugin-port", ags_lfo_channel_get_lfo_tuning_plugin_port(),
380 	       NULL);
381 
382   /* add to port */
383   port = g_list_prepend(port, lfo_channel->lfo_tuning);
384   g_object_ref(lfo_channel->lfo_tuning);
385 
386   /* set port */
387   AGS_RECALL(lfo_channel)->port = port;
388 }
389 
390 void
ags_lfo_channel_set_property(GObject * gobject,guint prop_id,const GValue * value,GParamSpec * param_spec)391 ags_lfo_channel_set_property(GObject *gobject,
392 			     guint prop_id,
393 			     const GValue *value,
394 			     GParamSpec *param_spec)
395 {
396   AgsLfoChannel *lfo_channel;
397 
398   GRecMutex *recall_mutex;
399 
400   lfo_channel = AGS_LFO_CHANNEL(gobject);
401 
402   /* get recall mutex */
403   recall_mutex = AGS_RECALL_GET_OBJ_MUTEX(lfo_channel);
404 
405   switch(prop_id){
406   case PROP_ENABLED:
407   {
408     AgsPort *port;
409 
410     port = (AgsPort *) g_value_get_object(value);
411 
412     g_rec_mutex_lock(recall_mutex);
413 
414     if(port == lfo_channel->enabled){
415       g_rec_mutex_unlock(recall_mutex);
416 
417       return;
418     }
419 
420     if(lfo_channel->enabled != NULL){
421       g_object_unref(G_OBJECT(lfo_channel->enabled));
422     }
423 
424     if(port != NULL){
425       g_object_ref(G_OBJECT(port));
426     }
427 
428     lfo_channel->enabled = port;
429 
430     g_rec_mutex_unlock(recall_mutex);
431   }
432   break;
433   case PROP_LFO_WAVE:
434   {
435     AgsPort *port;
436 
437     port = (AgsPort *) g_value_get_object(value);
438 
439     g_rec_mutex_lock(recall_mutex);
440 
441     if(port == lfo_channel->lfo_wave){
442       g_rec_mutex_unlock(recall_mutex);
443 
444       return;
445     }
446 
447     if(lfo_channel->lfo_wave != NULL){
448       g_object_unref(G_OBJECT(lfo_channel->lfo_wave));
449     }
450 
451     if(port != NULL){
452       g_object_ref(G_OBJECT(port));
453     }
454 
455     lfo_channel->lfo_wave = port;
456 
457     g_rec_mutex_unlock(recall_mutex);
458   }
459   break;
460   case PROP_LFO_FREQ:
461   {
462     AgsPort *port;
463 
464     port = (AgsPort *) g_value_get_object(value);
465 
466     g_rec_mutex_lock(recall_mutex);
467 
468     if(port == lfo_channel->lfo_freq){
469       g_rec_mutex_unlock(recall_mutex);
470 
471       return;
472     }
473 
474     if(lfo_channel->lfo_freq != NULL){
475       g_object_unref(G_OBJECT(lfo_channel->lfo_freq));
476     }
477 
478     if(port != NULL){
479       g_object_ref(G_OBJECT(port));
480     }
481 
482     lfo_channel->lfo_freq = port;
483 
484     g_rec_mutex_unlock(recall_mutex);
485   }
486   break;
487   case PROP_LFO_PHASE:
488   {
489     AgsPort *port;
490 
491     port = (AgsPort *) g_value_get_object(value);
492 
493     g_rec_mutex_lock(recall_mutex);
494 
495     if(port == lfo_channel->lfo_phase){
496       g_rec_mutex_unlock(recall_mutex);
497 
498       return;
499     }
500 
501     if(lfo_channel->lfo_phase != NULL){
502       g_object_unref(G_OBJECT(lfo_channel->lfo_phase));
503     }
504 
505     if(port != NULL){
506       g_object_ref(G_OBJECT(port));
507     }
508 
509     lfo_channel->lfo_phase = port;
510 
511     g_rec_mutex_unlock(recall_mutex);
512   }
513   break;
514   case PROP_LFO_DEPTH:
515   {
516     AgsPort *port;
517 
518     port = (AgsPort *) g_value_get_object(value);
519 
520     g_rec_mutex_lock(recall_mutex);
521 
522     if(port == lfo_channel->lfo_depth){
523       g_rec_mutex_unlock(recall_mutex);
524 
525       return;
526     }
527 
528     if(lfo_channel->lfo_depth != NULL){
529       g_object_unref(G_OBJECT(lfo_channel->lfo_depth));
530     }
531 
532     if(port != NULL){
533       g_object_ref(G_OBJECT(port));
534     }
535 
536     lfo_channel->lfo_depth = port;
537 
538     g_rec_mutex_unlock(recall_mutex);
539   }
540   break;
541   case PROP_LFO_TUNING:
542   {
543     AgsPort *port;
544 
545     port = (AgsPort *) g_value_get_object(value);
546 
547     g_rec_mutex_lock(recall_mutex);
548 
549     if(port == lfo_channel->lfo_tuning){
550       g_rec_mutex_unlock(recall_mutex);
551 
552       return;
553     }
554 
555     if(lfo_channel->lfo_tuning != NULL){
556       g_object_unref(G_OBJECT(lfo_channel->lfo_tuning));
557     }
558 
559     if(port != NULL){
560       g_object_ref(G_OBJECT(port));
561     }
562 
563     lfo_channel->lfo_tuning = port;
564 
565     g_rec_mutex_unlock(recall_mutex);
566   }
567   break;
568   default:
569     G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, prop_id, param_spec);
570     break;
571   }
572 }
573 
574 void
ags_lfo_channel_get_property(GObject * gobject,guint prop_id,GValue * value,GParamSpec * param_spec)575 ags_lfo_channel_get_property(GObject *gobject,
576 			     guint prop_id,
577 			     GValue *value,
578 			     GParamSpec *param_spec)
579 {
580   AgsLfoChannel *lfo_channel;
581 
582   GRecMutex *recall_mutex;
583 
584   lfo_channel = AGS_LFO_CHANNEL(gobject);
585 
586   /* get recall mutex */
587   recall_mutex = AGS_RECALL_GET_OBJ_MUTEX(lfo_channel);
588 
589   switch(prop_id){
590   case PROP_ENABLED:
591   {
592     g_rec_mutex_lock(recall_mutex);
593 
594     g_value_set_object(value, lfo_channel->enabled);
595 
596     g_rec_mutex_unlock(recall_mutex);
597   }
598   break;
599   case PROP_LFO_WAVE:
600   {
601     g_rec_mutex_lock(recall_mutex);
602 
603     g_value_set_object(value, lfo_channel->lfo_wave);
604 
605     g_rec_mutex_unlock(recall_mutex);
606   }
607   break;
608   case PROP_LFO_FREQ:
609   {
610     g_rec_mutex_lock(recall_mutex);
611 
612     g_value_set_object(value, lfo_channel->lfo_freq);
613 
614     g_rec_mutex_unlock(recall_mutex);
615   }
616   break;
617   case PROP_LFO_PHASE:
618   {
619     g_rec_mutex_lock(recall_mutex);
620 
621     g_value_set_object(value, lfo_channel->lfo_phase);
622 
623     g_rec_mutex_unlock(recall_mutex);
624   }
625   break;
626   case PROP_LFO_DEPTH:
627   {
628     g_rec_mutex_lock(recall_mutex);
629 
630     g_value_set_object(value, lfo_channel->lfo_depth);
631 
632     g_rec_mutex_unlock(recall_mutex);
633   }
634   break;
635   case PROP_LFO_TUNING:
636   {
637     g_rec_mutex_lock(recall_mutex);
638 
639     g_value_set_object(value, lfo_channel->lfo_tuning);
640 
641     g_rec_mutex_unlock(recall_mutex);
642   }
643   break;
644   default:
645     G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, prop_id, param_spec);
646     break;
647   }
648 }
649 
650 void
ags_lfo_channel_dispose(GObject * gobject)651 ags_lfo_channel_dispose(GObject *gobject)
652 {
653   AgsLfoChannel *lfo_channel;
654 
655   lfo_channel = AGS_LFO_CHANNEL(gobject);
656 
657   /* enabled */
658   if(lfo_channel->enabled != NULL){
659     g_object_unref(G_OBJECT(lfo_channel->enabled));
660   }
661 
662   /* lfo wave */
663   if(lfo_channel->lfo_wave != NULL){
664     g_object_unref(G_OBJECT(lfo_channel->lfo_wave));
665   }
666 
667   /* lfo freq */
668   if(lfo_channel->lfo_freq != NULL){
669     g_object_unref(G_OBJECT(lfo_channel->lfo_freq));
670   }
671 
672   /* lfo phase */
673   if(lfo_channel->lfo_phase != NULL){
674     g_object_unref(G_OBJECT(lfo_channel->lfo_phase));
675   }
676 
677   /* lfo depth */
678   if(lfo_channel->lfo_depth != NULL){
679     g_object_unref(G_OBJECT(lfo_channel->lfo_depth));
680   }
681 
682   /* lfo tuning */
683   if(lfo_channel->lfo_tuning != NULL){
684     g_object_unref(G_OBJECT(lfo_channel->lfo_tuning));
685   }
686 
687   /* call parent */
688   G_OBJECT_CLASS(ags_lfo_channel_parent_class)->dispose(gobject);
689 }
690 
691 void
ags_lfo_channel_finalize(GObject * gobject)692 ags_lfo_channel_finalize(GObject *gobject)
693 {
694   AgsLfoChannel *lfo_channel;
695 
696   lfo_channel = AGS_LFO_CHANNEL(gobject);
697 
698   /* enabled */
699   if(lfo_channel->enabled != NULL){
700     g_object_unref(G_OBJECT(lfo_channel->enabled));
701   }
702 
703   /* lfo wave */
704   if(lfo_channel->lfo_wave != NULL){
705     g_object_unref(G_OBJECT(lfo_channel->lfo_wave));
706   }
707 
708   /* lfo freq */
709   if(lfo_channel->lfo_freq != NULL){
710     g_object_unref(G_OBJECT(lfo_channel->lfo_freq));
711   }
712 
713   /* lfo phase */
714   if(lfo_channel->lfo_phase != NULL){
715     g_object_unref(G_OBJECT(lfo_channel->lfo_phase));
716   }
717 
718   /* lfo depth */
719   if(lfo_channel->lfo_depth != NULL){
720     g_object_unref(G_OBJECT(lfo_channel->lfo_depth));
721   }
722 
723   /* lfo tuning */
724   if(lfo_channel->lfo_tuning != NULL){
725     g_object_unref(G_OBJECT(lfo_channel->lfo_tuning));
726   }
727 
728   /* call parent */
729   G_OBJECT_CLASS(ags_lfo_channel_parent_class)->finalize(gobject);
730 }
731 
732 static AgsPluginPort*
ags_lfo_channel_get_enabled_plugin_port()733 ags_lfo_channel_get_enabled_plugin_port()
734 {
735   static AgsPluginPort *plugin_port = NULL;
736 
737   static GMutex mutex;
738 
739   g_mutex_lock(&mutex);
740 
741   if(plugin_port == NULL){
742     plugin_port = ags_plugin_port_new();
743     g_object_ref(plugin_port);
744 
745     plugin_port->flags |= (AGS_PLUGIN_PORT_INPUT |
746 			   AGS_PLUGIN_PORT_CONTROL |
747 			   AGS_PLUGIN_PORT_TOGGLED);
748 
749     plugin_port->port_index = 0;
750 
751     /* range */
752     g_value_init(plugin_port->default_value,
753 		 G_TYPE_FLOAT);
754     g_value_init(plugin_port->lower_value,
755 		 G_TYPE_FLOAT);
756     g_value_init(plugin_port->upper_value,
757 		 G_TYPE_FLOAT);
758 
759     g_value_set_float(plugin_port->default_value,
760 		      1.0);
761     g_value_set_float(plugin_port->lower_value,
762 		      0.0);
763     g_value_set_float(plugin_port->upper_value,
764 		      1.0);
765   }
766 
767   g_mutex_unlock(&mutex);
768 
769   return(plugin_port);
770 }
771 
772 static AgsPluginPort*
ags_lfo_channel_get_lfo_wave_plugin_port()773 ags_lfo_channel_get_lfo_wave_plugin_port()
774 {
775   static AgsPluginPort *plugin_port = NULL;
776 
777   static GMutex mutex;
778 
779   g_mutex_lock(&mutex);
780 
781   if(plugin_port == NULL){
782     plugin_port = ags_plugin_port_new();
783     g_object_ref(plugin_port);
784 
785     plugin_port->flags |= (AGS_PLUGIN_PORT_INPUT |
786 			   AGS_PLUGIN_PORT_CONTROL |
787 			   AGS_PLUGIN_PORT_ENUMERATION);
788 
789     plugin_port->port_index = 1;
790 
791     /* range */
792     g_value_init(plugin_port->default_value,
793 		 G_TYPE_FLOAT);
794     g_value_init(plugin_port->lower_value,
795 		 G_TYPE_FLOAT);
796     g_value_init(plugin_port->upper_value,
797 		 G_TYPE_FLOAT);
798 
799     g_value_set_float(plugin_port->default_value,
800 		      0.0);
801     g_value_set_float(plugin_port->lower_value,
802 		      0.0);
803     g_value_set_float(plugin_port->upper_value,
804 		      (gdouble) AGS_SYNTH_OSCILLATOR_LAST - 1.0);
805   }
806 
807   g_mutex_unlock(&mutex);
808 
809   return(plugin_port);
810 }
811 
812 static AgsPluginPort*
ags_lfo_channel_get_lfo_freq_plugin_port()813 ags_lfo_channel_get_lfo_freq_plugin_port()
814 {
815   static AgsPluginPort *plugin_port = NULL;
816 
817   static GMutex mutex;
818 
819   g_mutex_lock(&mutex);
820 
821   if(plugin_port == NULL){
822     plugin_port = ags_plugin_port_new();
823     g_object_ref(plugin_port);
824 
825     plugin_port->flags |= (AGS_PLUGIN_PORT_INPUT |
826 			   AGS_PLUGIN_PORT_CONTROL);
827 
828     plugin_port->port_index = 2;
829 
830     /* range */
831     g_value_init(plugin_port->default_value,
832 		 G_TYPE_FLOAT);
833     g_value_init(plugin_port->lower_value,
834 		 G_TYPE_FLOAT);
835     g_value_init(plugin_port->upper_value,
836 		 G_TYPE_FLOAT);
837 
838     g_value_set_float(plugin_port->default_value,
839 		      6.0);
840     g_value_set_float(plugin_port->lower_value,
841 		      0.0);
842     g_value_set_float(plugin_port->upper_value,
843 		      20.0);
844   }
845 
846   g_mutex_unlock(&mutex);
847 
848   return(plugin_port);
849 }
850 
851 static AgsPluginPort*
ags_lfo_channel_get_lfo_phase_plugin_port()852 ags_lfo_channel_get_lfo_phase_plugin_port()
853 {
854   static AgsPluginPort *plugin_port = NULL;
855 
856   static GMutex mutex;
857 
858   g_mutex_lock(&mutex);
859 
860   if(plugin_port == NULL){
861     plugin_port = ags_plugin_port_new();
862     g_object_ref(plugin_port);
863 
864     plugin_port->flags |= (AGS_PLUGIN_PORT_INPUT |
865 			   AGS_PLUGIN_PORT_CONTROL);
866 
867     plugin_port->port_index = 3;
868 
869     /* range */
870     g_value_init(plugin_port->default_value,
871 		 G_TYPE_FLOAT);
872     g_value_init(plugin_port->lower_value,
873 		 G_TYPE_FLOAT);
874     g_value_init(plugin_port->upper_value,
875 		 G_TYPE_FLOAT);
876 
877     g_value_set_float(plugin_port->default_value,
878 		      0.0);
879     g_value_set_float(plugin_port->lower_value,
880 		      0.0);
881     g_value_set_float(plugin_port->upper_value,
882 		      G_MAXDOUBLE);
883   }
884 
885   g_mutex_unlock(&mutex);
886 
887   return(plugin_port);
888 }
889 
890 static AgsPluginPort*
ags_lfo_channel_get_lfo_depth_plugin_port()891 ags_lfo_channel_get_lfo_depth_plugin_port()
892 {
893   static AgsPluginPort *plugin_port = NULL;
894 
895   static GMutex mutex;
896 
897   g_mutex_lock(&mutex);
898 
899   if(plugin_port == NULL){
900     plugin_port = ags_plugin_port_new();
901     g_object_ref(plugin_port);
902 
903     plugin_port->flags |= (AGS_PLUGIN_PORT_INPUT |
904 			   AGS_PLUGIN_PORT_CONTROL);
905 
906     plugin_port->port_index = 4;
907 
908     /* range */
909     g_value_init(plugin_port->default_value,
910 		 G_TYPE_FLOAT);
911     g_value_init(plugin_port->lower_value,
912 		 G_TYPE_FLOAT);
913     g_value_init(plugin_port->upper_value,
914 		 G_TYPE_FLOAT);
915 
916     g_value_set_float(plugin_port->default_value,
917 		      0.0);
918     g_value_set_float(plugin_port->lower_value,
919 		      -1200.0);
920     g_value_set_float(plugin_port->upper_value,
921 		      1200.0);
922   }
923 
924   g_mutex_unlock(&mutex);
925 
926   return(plugin_port);
927 }
928 
929 static AgsPluginPort*
ags_lfo_channel_get_lfo_tuning_plugin_port()930 ags_lfo_channel_get_lfo_tuning_plugin_port()
931 {
932   static AgsPluginPort *plugin_port = NULL;
933 
934   static GMutex mutex;
935 
936   g_mutex_lock(&mutex);
937 
938   if(plugin_port == NULL){
939     plugin_port = ags_plugin_port_new();
940     g_object_ref(plugin_port);
941 
942     plugin_port->flags |= (AGS_PLUGIN_PORT_INPUT |
943 			   AGS_PLUGIN_PORT_CONTROL);
944 
945     plugin_port->port_index = 5;
946 
947     /* range */
948     g_value_init(plugin_port->default_value,
949 		 G_TYPE_FLOAT);
950     g_value_init(plugin_port->lower_value,
951 		 G_TYPE_FLOAT);
952     g_value_init(plugin_port->upper_value,
953 		 G_TYPE_FLOAT);
954 
955     g_value_set_float(plugin_port->default_value,
956 		      0.0);
957     g_value_set_float(plugin_port->lower_value,
958 		      -1200.0);
959     g_value_set_float(plugin_port->upper_value,
960 		      -1200.0);
961   }
962 
963   g_mutex_unlock(&mutex);
964 
965   return(plugin_port);
966 }
967 
968 /**
969  * ags_lfo_channel_new:
970  * @source: the #AgsAudioSignal
971  *
972  * Create a new instance of #AgsLfoChannel
973  *
974  * Returns: the new #AgsLfoChannel
975  *
976  * Since: 3.0.0
977  */
978 AgsLfoChannel*
ags_lfo_channel_new(AgsChannel * source)979 ags_lfo_channel_new(AgsChannel *source)
980 {
981   AgsLfoChannel *lfo_channel;
982 
983   lfo_channel = (AgsLfoChannel *) g_object_new(AGS_TYPE_LFO_CHANNEL,
984 					       "source", source,
985 					       NULL);
986 
987   return(lfo_channel);
988 }
989