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_wave_channel.h>
21
22 #include <ags/i18n.h>
23
24 void ags_play_wave_channel_class_init(AgsPlayWaveChannelClass *play_wave_channel);
25 void ags_play_wave_channel_init(AgsPlayWaveChannel *play_wave_channel);
26 void ags_play_wave_channel_set_property(GObject *gobject,
27 guint prop_id,
28 const GValue *value,
29 GParamSpec *param_spec);
30 void ags_play_wave_channel_get_property(GObject *gobject,
31 guint prop_id,
32 GValue *value,
33 GParamSpec *param_spec);
34 void ags_play_wave_channel_dispose(GObject *gobject);
35 void ags_play_wave_channel_finalize(GObject *gobject);
36
37 /**
38 * SECTION:ags_play_wave_channel
39 * @short_description: play channel wave
40 * @title: AgsPlayWaveChannel
41 * @section_id:
42 * @include: ags/audio/recall/ags_play_wave_channel.h
43 *
44 * The #AgsPlayWaveChannel class provides ports to the effect processor.
45 */
46
47 static gpointer ags_play_wave_channel_parent_class = NULL;
48
49 const gchar *ags_play_wave_channel_plugin_name = "ags-play-wave";
50 const gchar *ags_play_wave_channel_specifier[] = {
51 "./do-playback[0]",
52 "./x-offset[0]",
53 };
54 const gchar *ags_play_wave_channel_control_port[] = {
55 "1/2",
56 "2/2",
57 };
58
59 enum{
60 PROP_0,
61 PROP_WAVE,
62 PROP_DO_PLAYBACK,
63 PROP_X_OFFSET,
64 };
65
66 GType
ags_play_wave_channel_get_type()67 ags_play_wave_channel_get_type()
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_play_wave_channel = 0;
73
74 static const GTypeInfo ags_play_wave_channel_info = {
75 sizeof (AgsPlayWaveChannelClass),
76 NULL, /* base_init */
77 NULL, /* base_finalize */
78 (GClassInitFunc) ags_play_wave_channel_class_init,
79 NULL, /* class_finalize */
80 NULL, /* class_channel */
81 sizeof (AgsPlayWaveChannel),
82 0, /* n_preallocs */
83 (GInstanceInitFunc) ags_play_wave_channel_init,
84 };
85
86 ags_type_play_wave_channel = g_type_register_static(AGS_TYPE_RECALL_CHANNEL,
87 "AgsPlayWaveChannel",
88 &ags_play_wave_channel_info,
89 0);
90
91 g_once_init_leave(&g_define_type_id__volatile, ags_type_play_wave_channel);
92 }
93
94 return g_define_type_id__volatile;
95 }
96
97 void
ags_play_wave_channel_class_init(AgsPlayWaveChannelClass * play_wave_channel)98 ags_play_wave_channel_class_init(AgsPlayWaveChannelClass *play_wave_channel)
99 {
100 GObjectClass *gobject;
101 GParamSpec *param_spec;
102
103 ags_play_wave_channel_parent_class = g_type_class_peek_parent(play_wave_channel);
104
105 /* GObjectClass */
106 gobject = (GObjectClass *) play_wave_channel;
107
108 gobject->set_property = ags_play_wave_channel_set_property;
109 gobject->get_property = ags_play_wave_channel_get_property;
110
111 gobject->dispose = ags_play_wave_channel_dispose;
112 gobject->finalize = ags_play_wave_channel_finalize;
113
114 /* properties */
115 /**
116 * AgsPlayWaveChannel:wave:
117 *
118 * The wave containing the notes.
119 *
120 * Since: 3.0.0
121 */
122 param_spec = g_param_spec_object("wave",
123 i18n_pspec("assigned AgsWave"),
124 i18n_pspec("The AgsWave containing notes"),
125 AGS_TYPE_WAVE,
126 G_PARAM_READABLE | G_PARAM_WRITABLE);
127 g_object_class_install_property(gobject,
128 PROP_WAVE,
129 param_spec);
130
131 /**
132 * AgsPlayWaveChannel:do-playback:
133 *
134 * The do-playback port.
135 *
136 * Since: 3.0.0
137 */
138 param_spec = g_param_spec_object("do-playback",
139 i18n_pspec("do playback"),
140 i18n_pspec("The do playback control"),
141 AGS_TYPE_PORT,
142 G_PARAM_READABLE | G_PARAM_WRITABLE);
143 g_object_class_install_property(gobject,
144 PROP_DO_PLAYBACK,
145 param_spec);
146
147 /**
148 * AgsPlayWaveChannel:x-offset:
149 *
150 * The x-offset port.
151 *
152 * Since: 3.0.0
153 */
154 param_spec = g_param_spec_object("x-offset",
155 i18n_pspec("x offset"),
156 i18n_pspec("The x offset control"),
157 AGS_TYPE_PORT,
158 G_PARAM_READABLE | G_PARAM_WRITABLE);
159 g_object_class_install_property(gobject,
160 PROP_X_OFFSET,
161 param_spec);
162 }
163
164 void
ags_play_wave_channel_init(AgsPlayWaveChannel * play_wave_channel)165 ags_play_wave_channel_init(AgsPlayWaveChannel *play_wave_channel)
166 {
167 GList *port;
168
169 AGS_RECALL(play_wave_channel)->name = "ags-play-wave";
170 AGS_RECALL(play_wave_channel)->version = AGS_RECALL_DEFAULT_VERSION;
171 AGS_RECALL(play_wave_channel)->build_id = AGS_RECALL_DEFAULT_BUILD_ID;
172 AGS_RECALL(play_wave_channel)->xml_type = "ags-play-wave-channel";
173
174 /* fields */
175 play_wave_channel->wave = NULL;
176
177 /* port */
178 port = NULL;
179
180 /* do playback */
181 play_wave_channel->do_playback = g_object_new(AGS_TYPE_PORT,
182 "plugin-name", ags_play_wave_channel_plugin_name,
183 "specifier", ags_play_wave_channel_specifier[0],
184 "control-port", ags_play_wave_channel_control_port[0],
185 "port-value-is-pointer", FALSE,
186 "port-value-type", G_TYPE_BOOLEAN,
187 NULL);
188 g_object_ref(play_wave_channel->do_playback);
189
190 play_wave_channel->do_playback->port_value.ags_port_boolean = TRUE;
191
192 /* add to port */
193 port = g_list_prepend(port, play_wave_channel->do_playback);
194 g_object_ref(play_wave_channel->do_playback);
195
196 /* x offset */
197 play_wave_channel->x_offset = g_object_new(AGS_TYPE_PORT,
198 "plugin-name", ags_play_wave_channel_plugin_name,
199 "specifier", ags_play_wave_channel_specifier[1],
200 "control-port", ags_play_wave_channel_control_port[1],
201 "port-value-is-pointer", FALSE,
202 "port-value-type", G_TYPE_UINT64,
203 NULL);
204 g_object_ref(play_wave_channel->x_offset);
205
206 play_wave_channel->x_offset->port_value.ags_port_boolean = FALSE;
207
208 /* add to port */
209 port = g_list_prepend(port, play_wave_channel->x_offset);
210 g_object_ref(play_wave_channel->x_offset);
211
212 /* set port */
213 AGS_RECALL(play_wave_channel)->port = port;
214 }
215
216 void
ags_play_wave_channel_set_property(GObject * gobject,guint prop_id,const GValue * value,GParamSpec * param_spec)217 ags_play_wave_channel_set_property(GObject *gobject,
218 guint prop_id,
219 const GValue *value,
220 GParamSpec *param_spec)
221 {
222 AgsPlayWaveChannel *play_wave_channel;
223
224 GRecMutex *recall_mutex;
225
226 play_wave_channel = AGS_PLAY_WAVE_CHANNEL(gobject);
227
228 /* get recall mutex */
229 recall_mutex = AGS_RECALL_GET_OBJ_MUTEX(play_wave_channel);
230
231 switch(prop_id){
232 case PROP_WAVE:
233 {
234 AgsWave *wave;
235
236 wave = (AgsWave *) g_value_get_object(value);
237
238 g_rec_mutex_lock(recall_mutex);
239
240 if(play_wave_channel->wave == wave){
241 g_rec_mutex_unlock(recall_mutex);
242
243 return;
244 }
245
246 if(play_wave_channel->wave != NULL){
247 g_object_unref(play_wave_channel->wave);
248 }
249
250 if(wave != NULL){
251 g_object_ref(wave);
252 }
253
254 play_wave_channel->wave = wave;
255
256 g_rec_mutex_unlock(recall_mutex);
257 }
258 break;
259 case PROP_DO_PLAYBACK:
260 {
261 AgsPort *do_playback;
262
263 do_playback = (AgsPort *) g_value_get_object(value);
264
265 g_rec_mutex_lock(recall_mutex);
266
267 if(play_wave_channel->do_playback == do_playback){
268 g_rec_mutex_unlock(recall_mutex);
269
270 return;
271 }
272
273 if(play_wave_channel->do_playback != NULL){
274 g_object_unref(G_OBJECT(play_wave_channel->do_playback));
275 }
276
277 if(do_playback != NULL){
278 g_object_ref(G_OBJECT(do_playback));
279 }
280
281 play_wave_channel->do_playback = do_playback;
282
283 g_rec_mutex_unlock(recall_mutex);
284 }
285 break;
286 case PROP_X_OFFSET:
287 {
288 AgsPort *x_offset;
289
290 x_offset = (AgsPort *) g_value_get_object(value);
291
292 g_rec_mutex_lock(recall_mutex);
293
294 if(play_wave_channel->x_offset == x_offset){
295 g_rec_mutex_unlock(recall_mutex);
296
297 return;
298 }
299
300 if(play_wave_channel->x_offset != NULL){
301 g_object_unref(G_OBJECT(play_wave_channel->x_offset));
302 }
303
304 if(x_offset != NULL){
305 g_object_ref(G_OBJECT(x_offset));
306 }
307
308 play_wave_channel->x_offset = x_offset;
309
310 g_rec_mutex_unlock(recall_mutex);
311 }
312 break;
313 default:
314 G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, prop_id, param_spec);
315 break;
316 };
317 }
318
319 void
ags_play_wave_channel_get_property(GObject * gobject,guint prop_id,GValue * value,GParamSpec * param_spec)320 ags_play_wave_channel_get_property(GObject *gobject,
321 guint prop_id,
322 GValue *value,
323 GParamSpec *param_spec)
324 {
325 AgsPlayWaveChannel *play_wave_channel;
326
327 GRecMutex *recall_mutex;
328
329 play_wave_channel = AGS_PLAY_WAVE_CHANNEL(gobject);
330
331 /* get recall mutex */
332 recall_mutex = AGS_RECALL_GET_OBJ_MUTEX(play_wave_channel);
333
334 switch(prop_id){
335 case PROP_WAVE:
336 {
337 g_rec_mutex_lock(recall_mutex);
338
339 g_value_set_object(value, play_wave_channel->wave);
340
341 g_rec_mutex_unlock(recall_mutex);
342 }
343 break;
344 case PROP_DO_PLAYBACK:
345 {
346 g_rec_mutex_lock(recall_mutex);
347
348 g_value_set_object(value, play_wave_channel->do_playback);
349
350 g_rec_mutex_unlock(recall_mutex);
351 }
352 break;
353 case PROP_X_OFFSET:
354 {
355 g_rec_mutex_lock(recall_mutex);
356
357 g_value_set_object(value, play_wave_channel->x_offset);
358
359 g_rec_mutex_unlock(recall_mutex);
360 }
361 break;
362 default:
363 G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, prop_id, param_spec);
364 break;
365 };
366 }
367
368 void
ags_play_wave_channel_dispose(GObject * gobject)369 ags_play_wave_channel_dispose(GObject *gobject)
370 {
371 AgsPlayWaveChannel *play_wave_channel;
372
373 play_wave_channel = AGS_PLAY_WAVE_CHANNEL(gobject);
374
375 /* wave */
376 if(play_wave_channel->wave != NULL){
377 g_object_unref(G_OBJECT(play_wave_channel->wave));
378
379 play_wave_channel->wave = NULL;
380 }
381
382 /* do playback */
383 if(play_wave_channel->do_playback != NULL){
384 g_object_unref(play_wave_channel->do_playback);
385
386 play_wave_channel->do_playback = NULL;
387 }
388
389 /* x-offset */
390 if(play_wave_channel->x_offset != NULL){
391 g_object_unref(play_wave_channel->x_offset);
392
393 play_wave_channel->x_offset = NULL;
394 }
395
396 /* call parent */
397 G_OBJECT_CLASS(ags_play_wave_channel_parent_class)->dispose(gobject);
398 }
399
400 void
ags_play_wave_channel_finalize(GObject * gobject)401 ags_play_wave_channel_finalize(GObject *gobject)
402 {
403 AgsPlayWaveChannel *play_wave_channel;
404
405 play_wave_channel = AGS_PLAY_WAVE_CHANNEL(gobject);
406
407 /* wave */
408 if(play_wave_channel->wave != NULL){
409 g_object_unref(G_OBJECT(play_wave_channel->wave));
410 }
411
412 /* do playback */
413 if(play_wave_channel->do_playback != NULL){
414 g_object_unref(play_wave_channel->do_playback);
415 }
416
417 /* x-offset */
418 if(play_wave_channel->x_offset != NULL){
419 g_object_unref(play_wave_channel->x_offset);
420 }
421
422 /* call parent */
423 G_OBJECT_CLASS(ags_play_wave_channel_parent_class)->finalize(gobject);
424 }
425
426 /**
427 * ags_play_wave_channel_new:
428 * @source: the #AgsChannel
429 *
430 * Create a new instance of #AgsPlayWaveChannel
431 *
432 * Returns: the new #AgsPlayWaveChannel
433 *
434 * Since: 3.0.0
435 */
436 AgsPlayWaveChannel*
ags_play_wave_channel_new(AgsChannel * source)437 ags_play_wave_channel_new(AgsChannel *source)
438 {
439 AgsPlayWaveChannel *play_wave_channel;
440
441 play_wave_channel = (AgsPlayWaveChannel *) g_object_new(AGS_TYPE_PLAY_WAVE_CHANNEL,
442 "source", source,
443 NULL);
444
445 return(play_wave_channel);
446 }
447