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_mute_channel.h>
21
22 #include <ags/plugin/ags_plugin_port.h>
23
24 #include <ags/i18n.h>
25
26 void ags_mute_channel_class_init(AgsMuteChannelClass *mute_channel);
27 void ags_mute_channel_mutable_interface_init(AgsMutableInterface *mutable);
28 void ags_mute_channel_init(AgsMuteChannel *mute_channel);
29 void ags_mute_channel_set_property(GObject *gobject,
30 guint prop_id,
31 const GValue *value,
32 GParamSpec *param_spec);
33 void ags_mute_channel_get_property(GObject *gobject,
34 guint prop_id,
35 GValue *value,
36 GParamSpec *param_spec);
37 void ags_mute_channel_dispose(GObject *gobject);
38 void ags_mute_channel_finalize(GObject *gobject);
39
40 void ags_mute_channel_set_muted(AgsMutable *mutable, gboolean muted);
41
42 static AgsPluginPort* ags_mute_channel_get_muted_plugin_port();
43
44 /**
45 * SECTION:ags_mute_channel
46 * @short_description: mutes channel
47 * @title: AgsMuteChannel
48 * @section_id:
49 * @include: ags/audio/recall/ags_mute_channel.h
50 *
51 * The #AgsMuteChannel class provides ports to the effect processor.
52 */
53
54 enum{
55 PROP_0,
56 PROP_MUTED,
57 };
58
59 static gpointer ags_mute_channel_parent_class = NULL;
60 static AgsPluginInterface *ags_mute_channel_parent_plugin_interface;
61
62 const gchar *ags_mute_channel_plugin_name = "ags-mute";
63 const gchar *ags_mute_channel_specifier[] = {
64 "./muted[0]",
65 };
66 const gchar *ags_mute_channel_control_port[] = {
67 "1/1",
68 };
69
70 GType
ags_mute_channel_get_type()71 ags_mute_channel_get_type()
72 {
73 static volatile gsize g_define_type_id__volatile = 0;
74
75 if(g_once_init_enter (&g_define_type_id__volatile)){
76 GType ags_type_mute_channel = 0;
77
78 static const GTypeInfo ags_mute_channel_info = {
79 sizeof (AgsMuteChannelClass),
80 NULL, /* base_init */
81 NULL, /* base_finalize */
82 (GClassInitFunc) ags_mute_channel_class_init,
83 NULL, /* class_finalize */
84 NULL, /* class_data */
85 sizeof (AgsMuteChannel),
86 0, /* n_preallocs */
87 (GInstanceInitFunc) ags_mute_channel_init,
88 };
89
90 static const GInterfaceInfo ags_mutable_interface_info = {
91 (GInterfaceInitFunc) ags_mute_channel_mutable_interface_init,
92 NULL, /* interface_finalize */
93 NULL, /* interface_data */
94 };
95
96 ags_type_mute_channel = g_type_register_static(AGS_TYPE_RECALL_CHANNEL,
97 "AgsMuteChannel",
98 &ags_mute_channel_info,
99 0);
100
101 g_type_add_interface_static(ags_type_mute_channel,
102 AGS_TYPE_MUTABLE,
103 &ags_mutable_interface_info);
104
105 g_once_init_leave(&g_define_type_id__volatile, ags_type_mute_channel);
106 }
107
108 return g_define_type_id__volatile;
109 }
110
111 void
ags_mute_channel_mutable_interface_init(AgsMutableInterface * mutable)112 ags_mute_channel_mutable_interface_init(AgsMutableInterface *mutable)
113 {
114 mutable->set_muted = ags_mute_channel_set_muted;
115 }
116
117 void
ags_mute_channel_class_init(AgsMuteChannelClass * mute_channel)118 ags_mute_channel_class_init(AgsMuteChannelClass *mute_channel)
119 {
120 GObjectClass *gobject;
121 GParamSpec *param_spec;
122
123 ags_mute_channel_parent_class = g_type_class_peek_parent(mute_channel);
124
125 /* GObjectClass */
126 gobject = (GObjectClass *) mute_channel;
127
128 gobject->set_property = ags_mute_channel_set_property;
129 gobject->get_property = ags_mute_channel_get_property;
130
131 gobject->dispose = ags_mute_channel_dispose;
132 gobject->finalize = ags_mute_channel_finalize;
133
134 /* properties */
135 /**
136 * AgsMuteChannel:muted:
137 *
138 * The mute port.
139 *
140 * Since: 3.0.0
141 */
142 param_spec = g_param_spec_object("muted",
143 i18n_pspec("mute channel"),
144 i18n_pspec("Mute the channel"),
145 AGS_TYPE_PORT,
146 G_PARAM_READABLE | G_PARAM_WRITABLE);
147 g_object_class_install_property(gobject,
148 PROP_MUTED,
149 param_spec);
150 }
151
152 void
ags_mute_channel_init(AgsMuteChannel * mute_channel)153 ags_mute_channel_init(AgsMuteChannel *mute_channel)
154 {
155 GList *port;
156
157 AGS_RECALL(mute_channel)->name = "ags-mute";
158 AGS_RECALL(mute_channel)->version = AGS_RECALL_DEFAULT_VERSION;
159 AGS_RECALL(mute_channel)->build_id = AGS_RECALL_DEFAULT_BUILD_ID;
160 AGS_RECALL(mute_channel)->xml_type = "ags-mute-channel";
161
162 port = NULL;
163
164 /* muted */
165 mute_channel->muted = g_object_new(AGS_TYPE_PORT,
166 "plugin-name", ags_mute_channel_plugin_name,
167 "specifier", ags_mute_channel_specifier[0],
168 "control-port", ags_mute_channel_control_port[0],
169 "port-value-is-pointer", FALSE,
170 "port-value-type", G_TYPE_FLOAT,
171 "port-value-size", sizeof(gfloat),
172 "port-value-length", 1,
173 NULL);
174 g_object_ref(mute_channel->muted);
175
176 mute_channel->muted->port_value.ags_port_float = 0.0;
177
178 /* plugin port */
179 g_object_set(mute_channel->muted,
180 "plugin-port", ags_mute_channel_get_muted_plugin_port(),
181 NULL);
182
183 /* add to port */
184 port = g_list_prepend(port, mute_channel->muted);
185 g_object_ref(mute_channel->muted);
186
187 /* set port */
188 AGS_RECALL(mute_channel)->port = port;
189 }
190
191 void
ags_mute_channel_set_property(GObject * gobject,guint prop_id,const GValue * value,GParamSpec * param_spec)192 ags_mute_channel_set_property(GObject *gobject,
193 guint prop_id,
194 const GValue *value,
195 GParamSpec *param_spec)
196 {
197 AgsMuteChannel *mute_channel;
198
199 GRecMutex *recall_mutex;
200
201 mute_channel = AGS_MUTE_CHANNEL(gobject);
202
203 /* get recall mutex */
204 recall_mutex = AGS_RECALL_GET_OBJ_MUTEX(mute_channel);
205
206 switch(prop_id){
207 case PROP_MUTED:
208 {
209 AgsPort *port;
210
211 port = (AgsPort *) g_value_get_object(value);
212
213 g_rec_mutex_lock(recall_mutex);
214
215 if(port == mute_channel->muted){
216 g_rec_mutex_unlock(recall_mutex);
217
218 return;
219 }
220
221 if(mute_channel->muted != NULL){
222 g_object_unref(G_OBJECT(mute_channel->muted));
223 }
224
225 if(port != NULL){
226 g_object_ref(G_OBJECT(port));
227 }
228
229 mute_channel->muted = port;
230
231 g_rec_mutex_unlock(recall_mutex);
232 }
233 break;
234 default:
235 G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, prop_id, param_spec);
236 break;
237 }
238 }
239
240 void
ags_mute_channel_get_property(GObject * gobject,guint prop_id,GValue * value,GParamSpec * param_spec)241 ags_mute_channel_get_property(GObject *gobject,
242 guint prop_id,
243 GValue *value,
244 GParamSpec *param_spec)
245 {
246 AgsMuteChannel *mute_channel;
247
248 GRecMutex *recall_mutex;
249
250 mute_channel = AGS_MUTE_CHANNEL(gobject);
251
252 /* get recall mutex */
253 recall_mutex = AGS_RECALL_GET_OBJ_MUTEX(mute_channel);
254
255 switch(prop_id){
256 case PROP_MUTED:
257 {
258 g_rec_mutex_lock(recall_mutex);
259
260 g_value_set_object(value, mute_channel->muted);
261
262 g_rec_mutex_unlock(recall_mutex);
263 }
264 break;
265 default:
266 G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, prop_id, param_spec);
267 break;
268 }
269 }
270
271 void
ags_mute_channel_dispose(GObject * gobject)272 ags_mute_channel_dispose(GObject *gobject)
273 {
274 AgsMuteChannel *mute_channel;
275
276 mute_channel = AGS_MUTE_CHANNEL(gobject);
277
278 /* muted */
279 if(mute_channel->muted != NULL){
280 g_object_unref(G_OBJECT(mute_channel->muted));
281
282 mute_channel->muted = NULL;
283 }
284
285 /* call parent */
286 G_OBJECT_CLASS(ags_mute_channel_parent_class)->dispose(gobject);
287 }
288
289 void
ags_mute_channel_finalize(GObject * gobject)290 ags_mute_channel_finalize(GObject *gobject)
291 {
292 AgsMuteChannel *mute_channel;
293
294 mute_channel = AGS_MUTE_CHANNEL(gobject);
295
296 /* muted */
297 if(mute_channel->muted != NULL){
298 g_object_unref(G_OBJECT(mute_channel->muted));
299 }
300
301 /* call parent */
302 G_OBJECT_CLASS(ags_mute_channel_parent_class)->finalize(gobject);
303 }
304
305 void
ags_mute_channel_set_muted(AgsMutable * mutable,gboolean muted)306 ags_mute_channel_set_muted(AgsMutable *mutable, gboolean muted)
307 {
308 AgsPort *port;
309
310 GValue value = {0,};
311
312 g_object_get(G_OBJECT(mutable),
313 "muted", &port,
314 NULL);
315
316 g_value_init(&value,
317 G_TYPE_FLOAT);
318
319 g_value_set_float(&value,
320 (muted ? 1.0: 0.0));
321
322 ags_port_safe_write(port,
323 &value);
324
325 g_value_unset(&value);
326 g_object_unref(port);
327 }
328
329 static AgsPluginPort*
ags_mute_channel_get_muted_plugin_port()330 ags_mute_channel_get_muted_plugin_port()
331 {
332 static AgsPluginPort *plugin_port = NULL;
333
334 static GMutex mutex;
335
336 g_mutex_lock(&mutex);
337
338 if(plugin_port == NULL){
339 plugin_port = ags_plugin_port_new();
340 g_object_ref(plugin_port);
341
342 plugin_port->flags |= (AGS_PLUGIN_PORT_INPUT |
343 AGS_PLUGIN_PORT_CONTROL |
344 AGS_PLUGIN_PORT_TOGGLED);
345
346 plugin_port->port_index = 0;
347
348 /* range */
349 g_value_init(plugin_port->default_value,
350 G_TYPE_FLOAT);
351 g_value_init(plugin_port->lower_value,
352 G_TYPE_FLOAT);
353 g_value_init(plugin_port->upper_value,
354 G_TYPE_FLOAT);
355
356 g_value_set_float(plugin_port->default_value,
357 0.0);
358 g_value_set_float(plugin_port->lower_value,
359 0.0);
360 g_value_set_float(plugin_port->upper_value,
361 1.0);
362 }
363
364 g_mutex_unlock(&mutex);
365
366 return(plugin_port);
367 }
368
369 /**
370 * ags_mute_channel_new:
371 * @source: the #AgsChannel
372 *
373 * Create a new instance of #AgsMuteChannel
374 *
375 * Returns: the new #AgsMuteChannel
376 *
377 * Since: 3.0.0
378 */
379 AgsMuteChannel*
ags_mute_channel_new(AgsChannel * source)380 ags_mute_channel_new(AgsChannel *source)
381 {
382 AgsMuteChannel *mute_channel;
383
384 mute_channel = (AgsMuteChannel *) g_object_new(AGS_TYPE_MUTE_CHANNEL,
385 "source", source,
386 NULL);
387
388 return(mute_channel);
389 }
390