1 /* GSequencer - Advanced GTK Sequencer
2  * Copyright (C) 2005-2020 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/task/ags_cancel_audio.h>
21 
22 #include <ags/audio/ags_audio.h>
23 
24 #include <ags/i18n.h>
25 
26 void ags_cancel_audio_class_init(AgsCancelAudioClass *cancel_audio);
27 void ags_cancel_audio_init(AgsCancelAudio *cancel_audio);
28 void ags_cancel_audio_set_property(GObject *gobject,
29 				   guint prop_id,
30 				   const GValue *value,
31 				   GParamSpec *param_spec);
32 void ags_cancel_audio_get_property(GObject *gobject,
33 				   guint prop_id,
34 				   GValue *value,
35 				   GParamSpec *param_spec);
36 void ags_cancel_audio_dispose(GObject *gobject);
37 void ags_cancel_audio_finalize(GObject *gobject);
38 
39 void ags_cancel_audio_launch(AgsTask *task);
40 
41 /**
42  * SECTION:ags_cancel_audio
43  * @short_description: cancel audio task
44  * @title: AgsCancelAudio
45  * @section_id:
46  * @include: ags/audio/task/ags_cancel_audio.h
47  *
48  * The #AgsCancelAudio task cancels #AgsAudio playback.
49  */
50 
51 static gpointer ags_cancel_audio_parent_class = NULL;
52 
53 enum{
54   PROP_0,
55   PROP_AUDIO,
56   PROP_SOUND_SCOPE,
57 };
58 
59 GType
ags_cancel_audio_get_type()60 ags_cancel_audio_get_type()
61 {
62   static volatile gsize g_define_type_id__volatile = 0;
63 
64   if(g_once_init_enter (&g_define_type_id__volatile)){
65     GType ags_type_cancel_audio = 0;
66 
67     static const GTypeInfo ags_cancel_audio_info = {
68       sizeof(AgsCancelAudioClass),
69       NULL, /* base_init */
70       NULL, /* base_finalize */
71       (GClassInitFunc) ags_cancel_audio_class_init,
72       NULL, /* class_finalize */
73       NULL, /* class_data */
74       sizeof(AgsCancelAudio),
75       0,    /* n_preallocs */
76       (GInstanceInitFunc) ags_cancel_audio_init,
77     };
78 
79     ags_type_cancel_audio = g_type_register_static(AGS_TYPE_TASK,
80 						   "AgsCancelAudio",
81 						   &ags_cancel_audio_info,
82 						   0);
83 
84     g_once_init_leave(&g_define_type_id__volatile, ags_type_cancel_audio);
85   }
86 
87   return g_define_type_id__volatile;
88 }
89 
90 void
ags_cancel_audio_class_init(AgsCancelAudioClass * cancel_audio)91 ags_cancel_audio_class_init(AgsCancelAudioClass *cancel_audio)
92 {
93   GObjectClass *gobject;
94   AgsTaskClass *task;
95 
96   GParamSpec *param_spec;
97 
98   ags_cancel_audio_parent_class = g_type_class_peek_parent(cancel_audio);
99 
100   /* gobject */
101   gobject = (GObjectClass *) cancel_audio;
102 
103   gobject->set_property = ags_cancel_audio_set_property;
104   gobject->get_property = ags_cancel_audio_get_property;
105 
106   gobject->dispose = ags_cancel_audio_dispose;
107   gobject->finalize = ags_cancel_audio_finalize;
108 
109   /* properties */
110   /**
111    * AgsCancelAudio:audio:
112    *
113    * The assigned #AgsAudio
114    *
115    * Since: 3.0.0
116    */
117   param_spec = g_param_spec_object("audio",
118 				   i18n_pspec("audio of cancel audio"),
119 				   i18n_pspec("The audio of cancel audio task"),
120 				   AGS_TYPE_AUDIO,
121 				   G_PARAM_READABLE | G_PARAM_WRITABLE);
122   g_object_class_install_property(gobject,
123 				  PROP_AUDIO,
124 				  param_spec);
125 
126   /**
127    * AgsCancelAudio:sound-scope:
128    *
129    * The effects sound-scope.
130    *
131    * Since: 3.0.0
132    */
133   param_spec = g_param_spec_int("sound-scope",
134 				i18n_pspec("sound scope"),
135 				i18n_pspec("The sound scope"),
136 				 -1,
137 				AGS_SOUND_SCOPE_LAST,
138 				-1,
139 				G_PARAM_READABLE | G_PARAM_WRITABLE);
140   g_object_class_install_property(gobject,
141 				  PROP_SOUND_SCOPE,
142 				  param_spec);
143 
144   /* task */
145   task = (AgsTaskClass *) cancel_audio;
146 
147   task->launch = ags_cancel_audio_launch;
148 }
149 
150 void
ags_cancel_audio_init(AgsCancelAudio * cancel_audio)151 ags_cancel_audio_init(AgsCancelAudio *cancel_audio)
152 {
153   cancel_audio->audio = NULL;
154 
155   cancel_audio->sound_scope = -1;
156 }
157 
158 void
ags_cancel_audio_set_property(GObject * gobject,guint prop_id,const GValue * value,GParamSpec * param_spec)159 ags_cancel_audio_set_property(GObject *gobject,
160 			      guint prop_id,
161 			      const GValue *value,
162 			      GParamSpec *param_spec)
163 {
164   AgsCancelAudio *cancel_audio;
165 
166   cancel_audio = AGS_CANCEL_AUDIO(gobject);
167 
168   switch(prop_id){
169   case PROP_AUDIO:
170     {
171       AgsAudio *audio;
172 
173       audio = (AgsAudio *) g_value_get_object(value);
174 
175       if(cancel_audio->audio == audio){
176 	return;
177       }
178 
179       if(cancel_audio->audio != NULL){
180 	g_object_unref(cancel_audio->audio);
181       }
182 
183       if(audio != NULL){
184 	g_object_ref(audio);
185       }
186 
187       cancel_audio->audio = audio;
188     }
189     break;
190   case PROP_SOUND_SCOPE:
191     {
192       cancel_audio->sound_scope = g_value_get_int(value);
193     }
194     break;
195   default:
196     G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, prop_id, param_spec);
197     break;
198   }
199 }
200 
201 void
ags_cancel_audio_get_property(GObject * gobject,guint prop_id,GValue * value,GParamSpec * param_spec)202 ags_cancel_audio_get_property(GObject *gobject,
203 			      guint prop_id,
204 			      GValue *value,
205 			      GParamSpec *param_spec)
206 {
207   AgsCancelAudio *cancel_audio;
208 
209   cancel_audio = AGS_CANCEL_AUDIO(gobject);
210 
211   switch(prop_id){
212   case PROP_AUDIO:
213     {
214       g_value_set_object(value, cancel_audio->audio);
215     }
216     break;
217   case PROP_SOUND_SCOPE:
218     {
219       g_value_set_int(value, cancel_audio->sound_scope);
220     }
221     break;
222   default:
223     G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, prop_id, param_spec);
224     break;
225   }
226 }
227 
228 void
ags_cancel_audio_dispose(GObject * gobject)229 ags_cancel_audio_dispose(GObject *gobject)
230 {
231   AgsCancelAudio *cancel_audio;
232 
233   cancel_audio = AGS_CANCEL_AUDIO(gobject);
234 
235   if(cancel_audio->audio != NULL){
236     g_object_unref(cancel_audio->audio);
237 
238     cancel_audio->audio = NULL;
239   }
240 
241   /* call parent */
242   G_OBJECT_CLASS(ags_cancel_audio_parent_class)->dispose(gobject);
243 }
244 
245 void
ags_cancel_audio_finalize(GObject * gobject)246 ags_cancel_audio_finalize(GObject *gobject)
247 {
248   AgsCancelAudio *cancel_audio;
249 
250   cancel_audio = AGS_CANCEL_AUDIO(gobject);
251 
252   if(cancel_audio->audio != NULL){
253     g_object_unref(cancel_audio->audio);
254   }
255 
256   /* call parent */
257   G_OBJECT_CLASS(ags_cancel_audio_parent_class)->finalize(gobject);
258 }
259 
260 void
ags_cancel_audio_launch(AgsTask * task)261 ags_cancel_audio_launch(AgsTask *task)
262 {
263   AgsAudio *audio;
264 
265   AgsCancelAudio *cancel_audio;
266 
267   GList *start_recall_id;
268 
269   gint sound_scope;
270 
271   cancel_audio = AGS_CANCEL_AUDIO(task);
272 
273   g_return_if_fail(AGS_IS_AUDIO(cancel_audio->audio));
274 
275   g_object_get(cancel_audio,
276 	       "audio", &audio,
277 	       "sound-scope", &sound_scope,
278 	       NULL);
279 
280   start_recall_id = ags_audio_check_scope(audio, sound_scope);
281 
282   ags_audio_stop(audio,
283 		 start_recall_id, sound_scope);
284 
285   g_object_unref(audio);
286 
287   g_list_free_full(start_recall_id,
288 		   g_object_unref);
289 }
290 
291 
292 /**
293  * ags_cancel_audio_new:
294  * @audio: the #AgsAudio to cancel
295  * @sound_scope: the #AgsSoundScope-enum or -1 for all
296  *
297  * Create a new instance of #AgsCancelAudio.
298  *
299  * Returns: the new #AgsCancelAudio.
300  *
301  * Since: 3.0.0
302  */
303 AgsCancelAudio*
ags_cancel_audio_new(AgsAudio * audio,gint sound_scope)304 ags_cancel_audio_new(AgsAudio *audio,
305 		     gint sound_scope)
306 {
307   AgsCancelAudio *cancel_audio;
308 
309   cancel_audio = (AgsCancelAudio *) g_object_new(AGS_TYPE_CANCEL_AUDIO,
310 						 "audio", audio,
311 						 "sound-scope", sound_scope,
312 						 NULL);
313 
314 
315   return(cancel_audio);
316 }
317