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