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_play_audio.h>
21
22 #include <ags/plugin/ags_plugin_port.h>
23
24 #include <ags/i18n.h>
25
26 void ags_play_audio_class_init(AgsPlayAudioClass *play_audio);
27 void ags_play_audio_mutable_interface_init(AgsMutableInterface *mutable);
28 void ags_play_audio_init(AgsPlayAudio *play_audio);
29 void ags_play_audio_set_property(GObject *gobject,
30 guint prop_id,
31 const GValue *value,
32 GParamSpec *param_spec);
33 void ags_play_audio_get_property(GObject *gobject,
34 guint prop_id,
35 GValue *value,
36 GParamSpec *param_spec);
37 void ags_play_audio_dispose(GObject *gobject);
38 void ags_play_audio_finalize(GObject *gobject);
39
40 void ags_play_audio_set_muted(AgsMutable *mutable, gboolean muted);
41
42 static AgsPluginPort* ags_play_audio_get_muted_plugin_port();
43
44 /**
45 * SECTION:ags_play_audio
46 * @short_description: play audio
47 * @title: AgsPlayAudio
48 * @section_id:
49 * @include: ags/audio/recall/ags_play_audio.h
50 *
51 * The #AgsPlayAudio class provides ports to the effect processor.
52 */
53
54 enum{
55 PROP_0,
56 PROP_MUTED,
57 };
58
59 static gpointer ags_play_audio_parent_class = NULL;
60
61 const gchar *ags_play_audio_plugin_name = "ags-play";
62 const gchar *ags_play_audio_specifier[] = {
63 "./muted[0]",
64 };
65 const gchar *ags_play_audio_control_port[] = {
66 "1/1",
67 };
68
69 GType
ags_play_audio_get_type()70 ags_play_audio_get_type()
71 {
72 static volatile gsize g_define_type_id__volatile = 0;
73
74 if(g_once_init_enter (&g_define_type_id__volatile)){
75 GType ags_type_play_audio = 0;
76
77 static const GTypeInfo ags_play_audio_info = {
78 sizeof (AgsPlayAudioClass),
79 NULL, /* base_init */
80 NULL, /* base_finalize */
81 (GClassInitFunc) ags_play_audio_class_init,
82 NULL, /* class_finalize */
83 NULL, /* class_audio */
84 sizeof (AgsPlayAudio),
85 0, /* n_preallocs */
86 (GInstanceInitFunc) ags_play_audio_init,
87 };
88
89 static const GInterfaceInfo ags_mutable_interface_info = {
90 (GInterfaceInitFunc) ags_play_audio_mutable_interface_init,
91 NULL, /* interface_finalize */
92 NULL, /* interface_data */
93 };
94
95 ags_type_play_audio = g_type_register_static(AGS_TYPE_RECALL_AUDIO,
96 "AgsPlayAudio",
97 &ags_play_audio_info,
98 0);
99
100 g_type_add_interface_static(ags_type_play_audio,
101 AGS_TYPE_MUTABLE,
102 &ags_mutable_interface_info);
103
104 g_once_init_leave(&g_define_type_id__volatile, ags_type_play_audio);
105 }
106
107 return g_define_type_id__volatile;
108 }
109
110 void
ags_play_audio_mutable_interface_init(AgsMutableInterface * mutable)111 ags_play_audio_mutable_interface_init(AgsMutableInterface *mutable)
112 {
113 mutable->set_muted = ags_play_audio_set_muted;
114 }
115
116 void
ags_play_audio_class_init(AgsPlayAudioClass * play_audio)117 ags_play_audio_class_init(AgsPlayAudioClass *play_audio)
118 {
119 GObjectClass *gobject;
120
121 GParamSpec *param_spec;
122
123 ags_play_audio_parent_class = g_type_class_peek_parent(play_audio);
124
125 /* GObjectClass */
126 gobject = (GObjectClass *) play_audio;
127
128 gobject->set_property = ags_play_audio_set_property;
129 gobject->get_property = ags_play_audio_get_property;
130
131 gobject->dispose = ags_play_audio_dispose;
132 gobject->finalize = ags_play_audio_finalize;
133
134 /* properties */
135 /**
136 * AgsPlayAudio: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 audio"),
144 i18n_pspec("Mute the audio"),
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_play_audio_init(AgsPlayAudio * play_audio)153 ags_play_audio_init(AgsPlayAudio *play_audio)
154 {
155 GList *port;
156
157 AGS_RECALL(play_audio)->name = "ags-play";
158 AGS_RECALL(play_audio)->version = AGS_RECALL_DEFAULT_VERSION;
159 AGS_RECALL(play_audio)->build_id = AGS_RECALL_DEFAULT_BUILD_ID;
160 AGS_RECALL(play_audio)->xml_type = "ags-play-audio";
161
162 port = NULL;
163
164 /* muted */
165 play_audio->muted = g_object_new(AGS_TYPE_PORT,
166 "plugin-name", ags_play_audio_plugin_name,
167 "specifier", ags_play_audio_specifier[0],
168 "control-port", ags_play_audio_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(play_audio->muted);
175
176 play_audio->muted->port_value.ags_port_float = (float) 0.0;
177
178 /* plugin port */
179 g_object_set(play_audio->muted,
180 "plugin-port", ags_play_audio_get_muted_plugin_port(),
181 NULL);
182
183 /* add to port */
184 port = g_list_prepend(port, play_audio->muted);
185 g_object_ref(play_audio->muted);
186
187 /* set port */
188 AGS_RECALL(play_audio)->port = port;
189 }
190
191 void
ags_play_audio_set_property(GObject * gobject,guint prop_id,const GValue * value,GParamSpec * param_spec)192 ags_play_audio_set_property(GObject *gobject,
193 guint prop_id,
194 const GValue *value,
195 GParamSpec *param_spec)
196 {
197 AgsPlayAudio *play_audio;
198
199 GRecMutex *recall_mutex;
200
201 play_audio = AGS_PLAY_AUDIO(gobject);
202
203 /* get recall mutex */
204 recall_mutex = AGS_RECALL_GET_OBJ_MUTEX(play_audio);
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 == play_audio->muted){
216 g_rec_mutex_unlock(recall_mutex);
217
218 return;
219 }
220
221 if(play_audio->muted != NULL){
222 g_object_unref(G_OBJECT(play_audio->muted));
223 }
224
225 if(port != NULL){
226 g_object_ref(G_OBJECT(port));
227 }
228
229 play_audio->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_play_audio_get_property(GObject * gobject,guint prop_id,GValue * value,GParamSpec * param_spec)241 ags_play_audio_get_property(GObject *gobject,
242 guint prop_id,
243 GValue *value,
244 GParamSpec *param_spec)
245 {
246 AgsPlayAudio *play_audio;
247
248 GRecMutex *recall_mutex;
249
250 play_audio = AGS_PLAY_AUDIO(gobject);
251
252 /* get recall mutex */
253 recall_mutex = AGS_RECALL_GET_OBJ_MUTEX(play_audio);
254
255 switch(prop_id){
256 case PROP_MUTED:
257 {
258 g_rec_mutex_lock(recall_mutex);
259
260 g_value_set_object(value, play_audio->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_play_audio_dispose(GObject * gobject)272 ags_play_audio_dispose(GObject *gobject)
273 {
274 AgsPlayAudio *play_audio;
275
276 play_audio = AGS_PLAY_AUDIO(gobject);
277
278 /* muted */
279 if(play_audio->muted != NULL){
280 g_object_unref(G_OBJECT(play_audio->muted));
281
282 play_audio->muted = NULL;
283 }
284
285 /* call parent */
286 G_OBJECT_CLASS(ags_play_audio_parent_class)->dispose(gobject);
287 }
288
289 void
ags_play_audio_finalize(GObject * gobject)290 ags_play_audio_finalize(GObject *gobject)
291 {
292 AgsPlayAudio *play_audio;
293
294 play_audio = AGS_PLAY_AUDIO(gobject);
295
296 /* muted */
297 if(play_audio->muted != NULL){
298 g_object_unref(G_OBJECT(play_audio->muted));
299 }
300
301 /* call parent */
302 G_OBJECT_CLASS(ags_play_audio_parent_class)->finalize(gobject);
303 }
304
305 void
ags_play_audio_set_muted(AgsMutable * mutable,gboolean muted)306 ags_play_audio_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
327 g_object_unref(port);
328 }
329
330 static AgsPluginPort*
ags_play_audio_get_muted_plugin_port()331 ags_play_audio_get_muted_plugin_port()
332 {
333 static AgsPluginPort *plugin_port = NULL;
334
335 static GMutex mutex;
336
337 g_mutex_lock(&mutex);
338
339 if(plugin_port == NULL){
340 plugin_port = ags_plugin_port_new();
341 g_object_ref(plugin_port);
342
343 plugin_port->flags |= (AGS_PLUGIN_PORT_INPUT |
344 AGS_PLUGIN_PORT_CONTROL |
345 AGS_PLUGIN_PORT_TOGGLED);
346
347 plugin_port->port_index = 0;
348
349 /* range */
350 g_value_init(plugin_port->default_value,
351 G_TYPE_FLOAT);
352 g_value_init(plugin_port->lower_value,
353 G_TYPE_FLOAT);
354 g_value_init(plugin_port->upper_value,
355 G_TYPE_FLOAT);
356
357 g_value_set_float(plugin_port->default_value,
358 0.0);
359 g_value_set_float(plugin_port->lower_value,
360 0.0);
361 g_value_set_float(plugin_port->upper_value,
362 1.0);
363 }
364
365 g_mutex_unlock(&mutex);
366
367 return(plugin_port);
368 }
369
370 /**
371 * ags_play_audio_new:
372 * @audio: the #AgsAudio
373 *
374 * Creates an #AgsPlayAudio
375 *
376 * Returns: a new #AgsPlayAudio
377 *
378 * Since: 3.0.0
379 */
380 AgsPlayAudio*
ags_play_audio_new(AgsAudio * audio)381 ags_play_audio_new(AgsAudio *audio)
382 {
383 AgsPlayAudio *play_audio;
384
385 play_audio = (AgsPlayAudio *) g_object_new(AGS_TYPE_PLAY_AUDIO,
386 "audio", audio,
387 NULL);
388
389 return(play_audio);
390 }
391