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_count_beats_audio.h>
21 
22 #include <ags/audio/recall/ags_count_beats_audio_run.h>
23 
24 #include <ags/i18n.h>
25 
26 void ags_count_beats_audio_class_init(AgsCountBeatsAudioClass *count_beats_audio);
27 void ags_count_beats_audio_tactable_interface_init(AgsTactableInterface *tactable);
28 void ags_count_beats_audio_init(AgsCountBeatsAudio *count_beats_audio);
29 void ags_count_beats_audio_set_property(GObject *gobject,
30 					guint prop_id,
31 					const GValue *value,
32 					GParamSpec *param_spec);
33 void ags_count_beats_audio_get_property(GObject *gobject,
34 					guint prop_id,
35 					GValue *value,
36 					GParamSpec *param_spec);
37 void ags_count_beats_audio_dispose(GObject *gobject);
38 void ags_count_beats_audio_finalize(GObject *gobject);
39 
40 void ags_count_beats_audio_notify_output_soundcard_callback(GObject *gobject,
41 							    GParamSpec *pspec,
42 							    gpointer user_data);
43 
44 void ags_count_beats_audio_change_sequencer_duration(AgsTactable *tactable, guint64 duration);
45 void ags_count_beats_audio_change_notation_duration(AgsTactable *tactable, guint64 duration);
46 void ags_count_beats_audio_change_wave_duration(AgsTactable *tactable, guint64 duration);
47 void ags_count_beats_audio_change_midi_duration(AgsTactable *tactable, guint64 duration);
48 
49 /**
50  * SECTION:ags_count_beats_audio
51  * @short_description: count audio beats
52  * @title: AgsCountBeatsAudio
53  * @section_id:
54  * @include: ags/audio/recall/ags_count_beats_audio.h
55  *
56  * The #AgsCountBeatsAudio class provides ports to the effect processor.
57  */
58 
59 enum{
60   PROP_0,
61   PROP_SEQUENCER_LOOP,
62   PROP_SEQUENCER_LOOP_START,
63   PROP_SEQUENCER_LOOP_END,
64   PROP_NOTATION_LOOP,
65   PROP_NOTATION_LOOP_START,
66   PROP_NOTATION_LOOP_END,
67   PROP_WAVE_LOOP,
68   PROP_WAVE_LOOP_START,
69   PROP_WAVE_LOOP_END,
70   PROP_MIDI_LOOP,
71   PROP_MIDI_LOOP_START,
72   PROP_MIDI_LOOP_END,
73 };
74 
75 static gpointer ags_count_beats_audio_parent_class = NULL;
76 
77 const gchar *ags_count_beats_audio_plugin_name = "ags-count-beats";
78 const gchar *ags_count_beats_audio_specifier[] = {
79   "./sequencer_loop[0]",
80   "./sequencer_loop_start[0]",
81   "./sequencer_loop_end[0]",
82   "./notation-loop[0]",
83   "./notation_loop_end[0]"
84   "./notation_loop_start[0]",
85   "./wave_loop[0]",
86   "./wave_loop_start[0]",
87   "./wave_loop_end[0]",
88   "./midi_loop[0]",
89   "./midi_loop_start[0]",
90   "./midi_loop_end[0]",
91 };
92 const gchar *ags_count_beats_audio_control_port[] = {
93   "1/12",
94   "2/12",
95   "3/12",
96   "4/12",
97   "5/12",
98   "6/12",
99   "7/12",
100   "8/12",
101   "9/12",
102   "10/12",
103   "11/12",
104   "12/12",
105 };
106 
107 GType
ags_count_beats_audio_get_type()108 ags_count_beats_audio_get_type()
109 {
110   static volatile gsize g_define_type_id__volatile = 0;
111 
112   if(g_once_init_enter (&g_define_type_id__volatile)){
113     GType ags_type_count_beats_audio = 0;
114 
115     static const GTypeInfo ags_count_beats_audio_info = {
116       sizeof (AgsCountBeatsAudioClass),
117       NULL, /* base_init */
118       NULL, /* base_finalize */
119       (GClassInitFunc) ags_count_beats_audio_class_init,
120       NULL, /* class_finalize */
121       NULL, /* class_data */
122       sizeof (AgsCountBeatsAudio),
123       0,    /* n_preallocs */
124       (GInstanceInitFunc) ags_count_beats_audio_init,
125     };
126 
127     static const GInterfaceInfo ags_tactable_interface_info = {
128       (GInterfaceInitFunc) ags_count_beats_audio_tactable_interface_init,
129       NULL, /* interface_finalize */
130       NULL, /* interface_data */
131     };
132 
133     ags_type_count_beats_audio = g_type_register_static(AGS_TYPE_RECALL_AUDIO,
134 							"AgsCountBeatsAudio",
135 							&ags_count_beats_audio_info,
136 							0);
137 
138     g_type_add_interface_static(ags_type_count_beats_audio,
139 				AGS_TYPE_TACTABLE,
140 				&ags_tactable_interface_info);
141 
142     g_once_init_leave(&g_define_type_id__volatile, ags_type_count_beats_audio);
143   }
144 
145   return g_define_type_id__volatile;
146 }
147 
148 void
ags_count_beats_audio_tactable_interface_init(AgsTactableInterface * tactable)149 ags_count_beats_audio_tactable_interface_init(AgsTactableInterface *tactable)
150 {
151   tactable->get_sequencer_duration = NULL;
152   tactable->get_notation_duration = NULL;
153   tactable->get_wave_duration = NULL;
154   tactable->get_midi_duration = NULL;
155 
156   tactable->get_bpm = NULL;
157   tactable->get_tact = NULL;
158 
159   tactable->change_sequencer_duration = ags_count_beats_audio_change_sequencer_duration;
160   tactable->change_notation_duration = ags_count_beats_audio_change_notation_duration;
161   tactable->change_wave_duration = ags_count_beats_audio_change_wave_duration;
162   tactable->change_midi_duration = ags_count_beats_audio_change_midi_duration;
163 
164   tactable->change_bpm = NULL;
165   tactable->change_tact = NULL;
166 }
167 
168 void
ags_count_beats_audio_class_init(AgsCountBeatsAudioClass * count_beats_audio)169 ags_count_beats_audio_class_init(AgsCountBeatsAudioClass *count_beats_audio)
170 {
171   GObjectClass *gobject;
172 
173   GParamSpec *param_spec;
174 
175   ags_count_beats_audio_parent_class = g_type_class_peek_parent(count_beats_audio);
176 
177   gobject = (GObjectClass *) count_beats_audio;
178 
179   gobject->set_property = ags_count_beats_audio_set_property;
180   gobject->get_property = ags_count_beats_audio_get_property;
181 
182   gobject->dispose = ags_count_beats_audio_dispose;
183   gobject->finalize = ags_count_beats_audio_finalize;
184 
185   /* properties */
186   /**
187    * AgsCountBeatsAudio:sequencer-loop:
188    *
189    * Count until loop-end and start at loop-start.
190    *
191    * Since: 3.0.0
192    */
193   param_spec = g_param_spec_object("sequencer-loop",
194 				   i18n_pspec("sequencer loop playing"),
195 				   i18n_pspec("Play sequencer in a endless loop"),
196 				   AGS_TYPE_PORT,
197 				   G_PARAM_READABLE | G_PARAM_WRITABLE);
198   g_object_class_install_property(gobject,
199 				  PROP_SEQUENCER_LOOP,
200 				  param_spec);
201 
202   /**
203    * AgsCountBeatsAudio:sequencer-loop-start:
204    *
205    * The sequencer's loop-start.
206    *
207    * Since: 3.0.0
208    */
209   param_spec = g_param_spec_object("sequencer_loop_start",
210 				   i18n_pspec("start beat of loop"),
211 				   i18n_pspec("The start beat of the sequencer loop"),
212 				   AGS_TYPE_PORT,
213 				   G_PARAM_READABLE | G_PARAM_WRITABLE);
214   g_object_class_install_property(gobject,
215 				  PROP_SEQUENCER_LOOP_START,
216 				  param_spec);
217 
218   /**
219    * AgsCountBeatsAudio:sequencer-loop-end:
220    *
221    * The sequencer's loop-end.
222    *
223    * Since: 3.0.0
224    */
225   param_spec = g_param_spec_object("sequencer-loop-end",
226 				   i18n_pspec("end beat of sequencer loop"),
227 				   i18n_pspec("The end beat of the sequencer loop"),
228 				   AGS_TYPE_PORT,
229 				   G_PARAM_READABLE | G_PARAM_WRITABLE);
230   g_object_class_install_property(gobject,
231 				  PROP_SEQUENCER_LOOP_END,
232 				  param_spec);
233 
234   /**
235    * AgsCountBeatsAudio:notation-loop:
236    *
237    * Count until notation-loop-end and start at notation-loop-start.
238    *
239    * Since: 3.0.0
240    */
241   param_spec = g_param_spec_object("notation-loop",
242 				   i18n_pspec("notation-loop playing"),
243 				   i18n_pspec("Play in a endless notation_loop"),
244 				   AGS_TYPE_PORT,
245 				   G_PARAM_READABLE | G_PARAM_WRITABLE);
246   g_object_class_install_property(gobject,
247 				  PROP_NOTATION_LOOP,
248 				  param_spec);
249 
250   /**
251    * AgsCountBeatsAudio:notation-loop-start:
252    *
253    * The notation's notation-loop-start.
254    *
255    * Since: 3.0.0
256    */
257   param_spec = g_param_spec_object("notation-loop-start",
258 				   i18n_pspec("start beat of notation loop"),
259 				   i18n_pspec("The start beat of the notation loop"),
260 				   AGS_TYPE_PORT,
261 				   G_PARAM_READABLE | G_PARAM_WRITABLE);
262   g_object_class_install_property(gobject,
263 				  PROP_NOTATION_LOOP_START,
264 				  param_spec);
265 
266   /**
267    * AgsCountBeatsAudio:notation-loop-end:
268    *
269    * The notation's loop-end.
270    *
271    * Since: 3.0.0
272    */
273   param_spec = g_param_spec_object("notation-loop-end",
274 				   i18n_pspec("end beat of notation loop"),
275 				   i18n_pspec("The end beat of the notation loop"),
276 				   AGS_TYPE_PORT,
277 				   G_PARAM_READABLE | G_PARAM_WRITABLE);
278   g_object_class_install_property(gobject,
279 				  PROP_NOTATION_LOOP_END,
280 				  param_spec);
281 
282   /**
283    * AgsCountBeatsAudio:wave-loop:
284    *
285    * Count until loop-end and start at loop-start.
286    *
287    * Since: 3.0.0
288    */
289   param_spec = g_param_spec_object("wave-loop",
290 				   i18n_pspec("wave loop playing"),
291 				   i18n_pspec("Play wave in a endless loop"),
292 				   AGS_TYPE_PORT,
293 				   G_PARAM_READABLE | G_PARAM_WRITABLE);
294   g_object_class_install_property(gobject,
295 				  PROP_WAVE_LOOP,
296 				  param_spec);
297 
298   /**
299    * AgsCountBeatsAudio:wave-loop-start:
300    *
301    * The wave's loop-start.
302    *
303    * Since: 3.0.0
304    */
305   param_spec = g_param_spec_object("wave_loop_start",
306 				   i18n_pspec("start beat of loop"),
307 				   i18n_pspec("The start beat of the wave loop"),
308 				   AGS_TYPE_PORT,
309 				   G_PARAM_READABLE | G_PARAM_WRITABLE);
310   g_object_class_install_property(gobject,
311 				  PROP_WAVE_LOOP_START,
312 				  param_spec);
313 
314   /**
315    * AgsCountBeatsAudio:wave-loop-end:
316    *
317    * The wave's loop-end.
318    *
319    * Since: 3.0.0
320    */
321   param_spec = g_param_spec_object("wave-loop-end",
322 				   i18n_pspec("end beat of wave loop"),
323 				   i18n_pspec("The end beat of the wave loop"),
324 				   AGS_TYPE_PORT,
325 				   G_PARAM_READABLE | G_PARAM_WRITABLE);
326   g_object_class_install_property(gobject,
327 				  PROP_WAVE_LOOP_END,
328 				  param_spec);
329 
330   /**
331    * AgsCountBeatsAudio:midi-loop:
332    *
333    * Count until loop-end and start at loop-start.
334    *
335    * Since: 3.0.0
336    */
337   param_spec = g_param_spec_object("midi-loop",
338 				   i18n_pspec("midi loop playing"),
339 				   i18n_pspec("Play midi in a endless loop"),
340 				   AGS_TYPE_PORT,
341 				   G_PARAM_READABLE | G_PARAM_WRITABLE);
342   g_object_class_install_property(gobject,
343 				  PROP_MIDI_LOOP,
344 				  param_spec);
345 
346   /**
347    * AgsCountBeatsAudio:midi-loop-start:
348    *
349    * The midi's loop-start.
350    *
351    * Since: 3.0.0
352    */
353   param_spec = g_param_spec_object("midi_loop_start",
354 				   i18n_pspec("start beat of loop"),
355 				   i18n_pspec("The start beat of the midi loop"),
356 				   AGS_TYPE_PORT,
357 				   G_PARAM_READABLE | G_PARAM_WRITABLE);
358   g_object_class_install_property(gobject,
359 				  PROP_MIDI_LOOP_START,
360 				  param_spec);
361 
362   /**
363    * AgsCountBeatsAudio:midi-loop-end:
364    *
365    * The midi's loop-end.
366    *
367    * Since: 3.0.0
368    */
369   param_spec = g_param_spec_object("midi-loop-end",
370 				   i18n_pspec("end beat of midi loop"),
371 				   i18n_pspec("The end beat of the midi loop"),
372 				   AGS_TYPE_PORT,
373 				   G_PARAM_READABLE | G_PARAM_WRITABLE);
374   g_object_class_install_property(gobject,
375 				  PROP_MIDI_LOOP_END,
376 				  param_spec);
377 }
378 
379 void
ags_count_beats_audio_init(AgsCountBeatsAudio * count_beats_audio)380 ags_count_beats_audio_init(AgsCountBeatsAudio *count_beats_audio)
381 {
382   GList *port;
383 
384   g_signal_connect_after(count_beats_audio, "notify::output-soundcard",
385 			 G_CALLBACK(ags_count_beats_audio_notify_output_soundcard_callback), NULL);
386 
387   AGS_RECALL(count_beats_audio)->name = "ags-count-beats";
388   AGS_RECALL(count_beats_audio)->version = AGS_RECALL_DEFAULT_VERSION;
389   AGS_RECALL(count_beats_audio)->build_id = AGS_RECALL_DEFAULT_BUILD_ID;
390   AGS_RECALL(count_beats_audio)->xml_type = "ags-count-beats-audio";
391 
392   port = NULL;
393 
394   /* sequencer loop */
395   count_beats_audio->sequencer_loop = g_object_new(AGS_TYPE_PORT,
396 						   "plugin-name", ags_count_beats_audio_plugin_name,
397 						   "specifier", ags_count_beats_audio_specifier[0],
398 						   "control-port", ags_count_beats_audio_control_port[0],
399 						   "port-value-is-pointer", FALSE,
400 						   "port-value-type", G_TYPE_BOOLEAN,
401 						   "port-value-size", sizeof(gboolean),
402 						   "port-value-length", 1,
403 						   NULL);
404   g_object_ref(count_beats_audio->sequencer_loop);
405 
406   count_beats_audio->sequencer_loop->port_value.ags_port_boolean = FALSE;
407 
408   /* add to port */
409   port = g_list_prepend(port, count_beats_audio->sequencer_loop);
410   g_object_ref(count_beats_audio->sequencer_loop);
411 
412   /* sequencer-loop-start  */
413   count_beats_audio->sequencer_loop_start = g_object_new(AGS_TYPE_PORT,
414 							 "plugin-name", ags_count_beats_audio_plugin_name,
415 							 "specifier", ags_count_beats_audio_specifier[1],
416 							 "control-port", ags_count_beats_audio_control_port[1],
417 							 "port-value-is-pointer", FALSE,
418 							 "port-value-type", G_TYPE_UINT64,
419 							 "port-value-size", sizeof(guint64),
420 							 "port-value-length", 1,
421 							 NULL);
422   g_object_ref(count_beats_audio->sequencer_loop_start);
423 
424   count_beats_audio->sequencer_loop_start->port_value.ags_port_uint = 0;
425 
426   /* add to port */
427   port = g_list_prepend(port, count_beats_audio->sequencer_loop_start);
428   g_object_ref(count_beats_audio->sequencer_loop_start);
429 
430   /* sequencer-loop-end */
431   count_beats_audio->sequencer_loop_end = g_object_new(AGS_TYPE_PORT,
432 						       "plugin-name", ags_count_beats_audio_plugin_name,
433 						       "specifier", ags_count_beats_audio_specifier[3],
434 						       "control-port", ags_count_beats_audio_control_port[3],
435 						       "port-value-is-pointer", FALSE,
436 						       "port-value-type", G_TYPE_UINT64,
437 						       "port-value-size", sizeof(guint64),
438 						       "port-value-length", 1,
439 						       NULL);
440   g_object_ref(count_beats_audio->sequencer_loop_end);
441 
442   count_beats_audio->sequencer_loop_end->port_value.ags_port_uint = 16;
443 
444   /* add to port */
445   port = g_list_prepend(port, count_beats_audio->sequencer_loop_end);
446   g_object_ref(count_beats_audio->sequencer_loop_end);
447 
448   /* notation loop */
449   count_beats_audio->notation_loop = g_object_new(AGS_TYPE_PORT,
450 						  "plugin-name", ags_count_beats_audio_plugin_name,
451 						  "specifier", ags_count_beats_audio_specifier[0],
452 						  "control-port", ags_count_beats_audio_control_port[0],
453 						  "port-value-is-pointer", FALSE,
454 						  "port-value-type", G_TYPE_BOOLEAN,
455 						  "port-value-size", sizeof(gboolean),
456 						  "port-value-length", 1,
457 						  NULL);
458   g_object_ref(count_beats_audio->notation_loop);
459 
460   count_beats_audio->notation_loop->port_value.ags_port_boolean = FALSE;
461 
462   /* add to port */
463   port = g_list_prepend(port, count_beats_audio->notation_loop);
464   g_object_ref(count_beats_audio->notation_loop);
465 
466   /* notation-loop-start */
467   count_beats_audio->notation_loop_start = g_object_new(AGS_TYPE_PORT,
468 							"plugin-name", ags_count_beats_audio_plugin_name,
469 							"specifier", ags_count_beats_audio_specifier[2],
470 							"control-port", ags_count_beats_audio_control_port[2],
471 							"port-value-is-pointer", FALSE,
472 							"port-value-type", G_TYPE_UINT64,
473 							"port-value-size", sizeof(guint64),
474 							"port-value-length", 1,
475 							NULL);
476   g_object_ref(count_beats_audio->notation_loop_start);
477 
478   count_beats_audio->notation_loop_start->port_value.ags_port_uint = 0;
479 
480   /* add to port */
481   port = g_list_prepend(port, count_beats_audio->notation_loop_start);
482   g_object_ref(count_beats_audio->notation_loop_start);
483 
484   /* notation-loop-end */
485   count_beats_audio->notation_loop_end = g_object_new(AGS_TYPE_PORT,
486 						      "plugin-name", ags_count_beats_audio_plugin_name,
487 						      "specifier", ags_count_beats_audio_specifier[4],
488 						      "control-port", ags_count_beats_audio_control_port[4],
489 						      "port-value-is-pointer", FALSE,
490 						      "port-value-type", G_TYPE_UINT64,
491 						      "port-value-size", sizeof(guint64),
492 						      "port-value-length", 1,
493 						      NULL);
494   g_object_ref(count_beats_audio->notation_loop_end);
495 
496   count_beats_audio->notation_loop_end->port_value.ags_port_uint = 64;
497 
498   /* add to port */
499   port = g_list_prepend(port, count_beats_audio->notation_loop_end);
500   g_object_ref(count_beats_audio->notation_loop_end);
501 
502   /* wave loop */
503   count_beats_audio->wave_loop = g_object_new(AGS_TYPE_PORT,
504 					      "plugin-name", ags_count_beats_audio_plugin_name,
505 					      "specifier", ags_count_beats_audio_specifier[0],
506 					      "control-port", ags_count_beats_audio_control_port[0],
507 					      "port-value-is-pointer", FALSE,
508 					      "port-value-type", G_TYPE_BOOLEAN,
509 					      "port-value-size", sizeof(gboolean),
510 					      "port-value-length", 1,
511 					      NULL);
512   g_object_ref(count_beats_audio->wave_loop);
513 
514   count_beats_audio->wave_loop->port_value.ags_port_boolean = FALSE;
515 
516   /* add to port */
517   port = g_list_prepend(port, count_beats_audio->wave_loop);
518   g_object_ref(count_beats_audio->wave_loop);
519 
520   /* wave-loop-start  */
521   count_beats_audio->wave_loop_start = g_object_new(AGS_TYPE_PORT,
522 						    "plugin-name", ags_count_beats_audio_plugin_name,
523 						    "specifier", ags_count_beats_audio_specifier[1],
524 						    "control-port", ags_count_beats_audio_control_port[1],
525 						    "port-value-is-pointer", FALSE,
526 						    "port-value-type", G_TYPE_UINT64,
527 						    "port-value-size", sizeof(guint64),
528 						    "port-value-length", 1,
529 						    NULL);
530   g_object_ref(count_beats_audio->wave_loop_start);
531 
532   count_beats_audio->wave_loop_start->port_value.ags_port_uint = 0;
533 
534   /* add to port */
535   port = g_list_prepend(port, count_beats_audio->wave_loop_start);
536   g_object_ref(count_beats_audio->wave_loop_start);
537 
538   /* wave-loop-end */
539   count_beats_audio->wave_loop_end = g_object_new(AGS_TYPE_PORT,
540 						  "plugin-name", ags_count_beats_audio_plugin_name,
541 						  "specifier", ags_count_beats_audio_specifier[3],
542 						  "control-port", ags_count_beats_audio_control_port[3],
543 						  "port-value-is-pointer", FALSE,
544 						  "port-value-type", G_TYPE_UINT64,
545 						  "port-value-size", sizeof(guint64),
546 						  "port-value-length", 1,
547 						  NULL);
548   g_object_ref(count_beats_audio->wave_loop_end);
549 
550   count_beats_audio->wave_loop_end->port_value.ags_port_uint = 16;
551 
552   /* add to port */
553   port = g_list_prepend(port, count_beats_audio->wave_loop_end);
554   g_object_ref(count_beats_audio->wave_loop_end);
555 
556   /* midi loop */
557   count_beats_audio->midi_loop = g_object_new(AGS_TYPE_PORT,
558 					      "plugin-name", ags_count_beats_audio_plugin_name,
559 					      "specifier", ags_count_beats_audio_specifier[0],
560 					      "control-port", ags_count_beats_audio_control_port[0],
561 					      "port-value-is-pointer", FALSE,
562 					      "port-value-type", G_TYPE_BOOLEAN,
563 					      "port-value-size", sizeof(gboolean),
564 					      "port-value-length", 1,
565 					      NULL);
566   g_object_ref(count_beats_audio->midi_loop);
567 
568   count_beats_audio->midi_loop->port_value.ags_port_boolean = FALSE;
569 
570   /* add to port */
571   port = g_list_prepend(port, count_beats_audio->midi_loop);
572   g_object_ref(count_beats_audio->midi_loop);
573 
574   /* midi-loop-start  */
575   count_beats_audio->midi_loop_start = g_object_new(AGS_TYPE_PORT,
576 						    "plugin-name", ags_count_beats_audio_plugin_name,
577 						    "specifier", ags_count_beats_audio_specifier[1],
578 						    "control-port", ags_count_beats_audio_control_port[1],
579 						    "port-value-is-pointer", FALSE,
580 						    "port-value-type", G_TYPE_UINT64,
581 						    "port-value-size", sizeof(guint64),
582 						    "port-value-length", 1,
583 						    NULL);
584   g_object_ref(count_beats_audio->midi_loop_start);
585 
586   count_beats_audio->midi_loop_start->port_value.ags_port_uint = 0;
587 
588   /* add to port */
589   port = g_list_prepend(port, count_beats_audio->midi_loop_start);
590   g_object_ref(count_beats_audio->midi_loop_start);
591 
592   /* midi-loop-end */
593   count_beats_audio->midi_loop_end = g_object_new(AGS_TYPE_PORT,
594 						  "plugin-name", ags_count_beats_audio_plugin_name,
595 						  "specifier", ags_count_beats_audio_specifier[3],
596 						  "control-port", ags_count_beats_audio_control_port[3],
597 						  "port-value-is-pointer", FALSE,
598 						  "port-value-type", G_TYPE_UINT64,
599 						  "port-value-size", sizeof(guint64),
600 						  "port-value-length", 1,
601 						  NULL);
602   g_object_ref(count_beats_audio->midi_loop_end);
603 
604   count_beats_audio->midi_loop_end->port_value.ags_port_uint = 16;
605 
606   /* add to port */
607   port = g_list_prepend(port, count_beats_audio->midi_loop_end);
608   g_object_ref(count_beats_audio->midi_loop_end);
609 
610   /* port */
611   AGS_RECALL(count_beats_audio)->port = port;
612 }
613 
614 void
ags_count_beats_audio_set_property(GObject * gobject,guint prop_id,const GValue * value,GParamSpec * param_spec)615 ags_count_beats_audio_set_property(GObject *gobject,
616 				   guint prop_id,
617 				   const GValue *value,
618 				   GParamSpec *param_spec)
619 {
620   AgsCountBeatsAudio *count_beats_audio;
621 
622   GRecMutex *recall_mutex;
623 
624   count_beats_audio = AGS_COUNT_BEATS_AUDIO(gobject);
625 
626   /* get recall mutex */
627   recall_mutex = AGS_RECALL_GET_OBJ_MUTEX(count_beats_audio);
628 
629   switch(prop_id){
630   case PROP_SEQUENCER_LOOP:
631     {
632       AgsPort *port;
633 
634       port = (AgsPort *) g_value_get_object(value);
635 
636       g_rec_mutex_lock(recall_mutex);
637 
638       if(port == count_beats_audio->sequencer_loop){
639 	g_rec_mutex_unlock(recall_mutex);
640 
641 	return;
642       }
643 
644       if(count_beats_audio->sequencer_loop != NULL){
645 	g_object_unref(G_OBJECT(count_beats_audio->sequencer_loop));
646       }
647 
648       if(port != NULL){
649 	g_object_ref(G_OBJECT(port));
650       }
651 
652       count_beats_audio->sequencer_loop = port;
653 
654       g_rec_mutex_unlock(recall_mutex);
655     }
656     break;
657   case PROP_SEQUENCER_LOOP_START:
658     {
659       AgsPort *port;
660 
661       port = (AgsPort *) g_value_get_object(value);
662 
663       g_rec_mutex_lock(recall_mutex);
664 
665       if(port == count_beats_audio->sequencer_loop_start){
666 	g_rec_mutex_unlock(recall_mutex);
667 
668 	return;
669       }
670 
671       if(count_beats_audio->sequencer_loop_start != NULL){
672 	g_object_unref(G_OBJECT(count_beats_audio->sequencer_loop_start));
673       }
674 
675       if(port != NULL){
676 	g_object_ref(G_OBJECT(port));
677       }
678 
679       count_beats_audio->sequencer_loop_start = port;
680 
681       g_rec_mutex_unlock(recall_mutex);
682     }
683     break;
684   case PROP_SEQUENCER_LOOP_END:
685     {
686       AgsPort *port;
687 
688       port = (AgsPort *) g_value_get_object(value);
689 
690       g_rec_mutex_lock(recall_mutex);
691 
692       if(port == count_beats_audio->sequencer_loop_end){
693 	g_rec_mutex_unlock(recall_mutex);
694 
695 	return;
696       }
697 
698       if(count_beats_audio->sequencer_loop_end != NULL){
699 	g_object_unref(G_OBJECT(count_beats_audio->sequencer_loop_end));
700       }
701 
702       if(port != NULL){
703 	g_object_ref(G_OBJECT(port));
704       }
705 
706       count_beats_audio->sequencer_loop_end = port;
707 
708       g_rec_mutex_unlock(recall_mutex);
709     }
710     break;
711   case PROP_NOTATION_LOOP:
712     {
713       AgsPort *port;
714 
715       port = (AgsPort *) g_value_get_object(value);
716 
717       g_rec_mutex_lock(recall_mutex);
718 
719       if(port == count_beats_audio->notation_loop){
720 	g_rec_mutex_unlock(recall_mutex);
721 
722 	return;
723       }
724 
725       if(count_beats_audio->notation_loop != NULL){
726 	g_object_unref(G_OBJECT(count_beats_audio->notation_loop));
727       }
728 
729       if(port != NULL){
730 	g_object_ref(G_OBJECT(port));
731       }
732 
733       count_beats_audio->notation_loop = port;
734 
735       g_rec_mutex_unlock(recall_mutex);
736     }
737     break;
738   case PROP_NOTATION_LOOP_START:
739     {
740       AgsPort *port;
741 
742       port = (AgsPort *) g_value_get_object(value);
743 
744       g_rec_mutex_lock(recall_mutex);
745 
746       if(port == count_beats_audio->notation_loop_start){
747 	g_rec_mutex_unlock(recall_mutex);
748 
749 	return;
750       }
751 
752       if(count_beats_audio->notation_loop_start != NULL){
753 	g_object_unref(G_OBJECT(count_beats_audio->notation_loop_start));
754       }
755 
756       if(port != NULL){
757 	g_object_ref(G_OBJECT(port));
758       }
759 
760       count_beats_audio->notation_loop_start = port;
761 
762       g_rec_mutex_unlock(recall_mutex);
763     }
764     break;
765   case PROP_NOTATION_LOOP_END:
766     {
767       AgsPort *port;
768 
769       port = (AgsPort *) g_value_get_object(value);
770 
771       g_rec_mutex_lock(recall_mutex);
772 
773       if(port == count_beats_audio->notation_loop_end){
774 	g_rec_mutex_unlock(recall_mutex);
775 
776 	return;
777       }
778 
779       if(count_beats_audio->notation_loop_end != NULL){
780 	g_object_unref(G_OBJECT(count_beats_audio->notation_loop_end));
781       }
782 
783       if(port != NULL){
784 	g_object_ref(G_OBJECT(port));
785       }
786 
787       count_beats_audio->notation_loop_end = port;
788 
789       g_rec_mutex_unlock(recall_mutex);
790     }
791     break;
792   case PROP_WAVE_LOOP:
793     {
794       AgsPort *port;
795 
796       port = (AgsPort *) g_value_get_object(value);
797 
798       g_rec_mutex_lock(recall_mutex);
799 
800       if(port == count_beats_audio->wave_loop){
801 	g_rec_mutex_unlock(recall_mutex);
802 
803 	return;
804       }
805 
806       if(count_beats_audio->wave_loop != NULL){
807 	g_object_unref(G_OBJECT(count_beats_audio->wave_loop));
808       }
809 
810       if(port != NULL){
811 	g_object_ref(G_OBJECT(port));
812       }
813 
814       count_beats_audio->wave_loop = port;
815 
816       g_rec_mutex_unlock(recall_mutex);
817     }
818     break;
819   case PROP_WAVE_LOOP_START:
820     {
821       AgsPort *port;
822 
823       port = (AgsPort *) g_value_get_object(value);
824 
825       g_rec_mutex_lock(recall_mutex);
826 
827       if(port == count_beats_audio->wave_loop_start){
828 	g_rec_mutex_unlock(recall_mutex);
829 
830 	return;
831       }
832 
833       if(count_beats_audio->wave_loop_start != NULL){
834 	g_object_unref(G_OBJECT(count_beats_audio->wave_loop_start));
835       }
836 
837       if(port != NULL){
838 	g_object_ref(G_OBJECT(port));
839       }
840 
841       count_beats_audio->wave_loop_start = port;
842 
843       g_rec_mutex_unlock(recall_mutex);
844     }
845     break;
846   case PROP_WAVE_LOOP_END:
847     {
848       AgsPort *port;
849 
850       port = (AgsPort *) g_value_get_object(value);
851 
852       g_rec_mutex_lock(recall_mutex);
853 
854       if(port == count_beats_audio->wave_loop_end){
855 	g_rec_mutex_unlock(recall_mutex);
856 
857 	return;
858       }
859 
860       if(count_beats_audio->wave_loop_end != NULL){
861 	g_object_unref(G_OBJECT(count_beats_audio->wave_loop_end));
862       }
863 
864       if(port != NULL){
865 	g_object_ref(G_OBJECT(port));
866       }
867 
868       count_beats_audio->wave_loop_end = port;
869 
870       g_rec_mutex_unlock(recall_mutex);
871     }
872     break;
873   case PROP_MIDI_LOOP:
874     {
875       AgsPort *port;
876 
877       port = (AgsPort *) g_value_get_object(value);
878 
879       g_rec_mutex_lock(recall_mutex);
880 
881       if(port == count_beats_audio->midi_loop){
882 	g_rec_mutex_unlock(recall_mutex);
883 
884 	return;
885       }
886 
887       if(count_beats_audio->midi_loop != NULL){
888 	g_object_unref(G_OBJECT(count_beats_audio->midi_loop));
889       }
890 
891       if(port != NULL){
892 	g_object_ref(G_OBJECT(port));
893       }
894 
895       count_beats_audio->midi_loop = port;
896 
897       g_rec_mutex_unlock(recall_mutex);
898     }
899     break;
900   case PROP_MIDI_LOOP_START:
901     {
902       AgsPort *port;
903 
904       port = (AgsPort *) g_value_get_object(value);
905 
906       g_rec_mutex_lock(recall_mutex);
907 
908       if(port == count_beats_audio->midi_loop_start){
909 	g_rec_mutex_unlock(recall_mutex);
910 
911 	return;
912       }
913 
914       if(count_beats_audio->midi_loop_start != NULL){
915 	g_object_unref(G_OBJECT(count_beats_audio->midi_loop_start));
916       }
917 
918       if(port != NULL){
919 	g_object_ref(G_OBJECT(port));
920       }
921 
922       count_beats_audio->midi_loop_start = port;
923 
924       g_rec_mutex_unlock(recall_mutex);
925     }
926     break;
927   case PROP_MIDI_LOOP_END:
928     {
929       AgsPort *port;
930 
931       port = (AgsPort *) g_value_get_object(value);
932 
933       g_rec_mutex_lock(recall_mutex);
934 
935       if(port == count_beats_audio->midi_loop_end){
936 	g_rec_mutex_unlock(recall_mutex);
937 
938 	return;
939       }
940 
941       if(count_beats_audio->midi_loop_end != NULL){
942 	g_object_unref(G_OBJECT(count_beats_audio->midi_loop_end));
943       }
944 
945       if(port != NULL){
946 	g_object_ref(G_OBJECT(port));
947       }
948 
949       count_beats_audio->midi_loop_end = port;
950 
951       g_rec_mutex_unlock(recall_mutex);
952     }
953     break;
954   default:
955     G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, prop_id, param_spec);
956     break;
957   };
958 }
959 
960 void
ags_count_beats_audio_get_property(GObject * gobject,guint prop_id,GValue * value,GParamSpec * param_spec)961 ags_count_beats_audio_get_property(GObject *gobject,
962 				   guint prop_id,
963 				   GValue *value,
964 				   GParamSpec *param_spec)
965 {
966   AgsCountBeatsAudio *count_beats_audio;
967 
968   GRecMutex *recall_mutex;
969 
970   count_beats_audio = AGS_COUNT_BEATS_AUDIO(gobject);
971 
972   /* get recall mutex */
973   recall_mutex = AGS_RECALL_GET_OBJ_MUTEX(count_beats_audio);
974 
975   switch(prop_id){
976   case PROP_SEQUENCER_LOOP:
977     {
978       g_rec_mutex_lock(recall_mutex);
979 
980       g_value_set_object(value, count_beats_audio->sequencer_loop);
981 
982       g_rec_mutex_unlock(recall_mutex);
983     }
984     break;
985   case PROP_SEQUENCER_LOOP_START:
986     {
987       g_rec_mutex_lock(recall_mutex);
988 
989       g_value_set_object(value, count_beats_audio->sequencer_loop_start);
990 
991       g_rec_mutex_unlock(recall_mutex);
992     }
993     break;
994   case PROP_SEQUENCER_LOOP_END:
995     {
996       g_rec_mutex_lock(recall_mutex);
997 
998       g_value_set_object(value, count_beats_audio->sequencer_loop_end);
999 
1000       g_rec_mutex_unlock(recall_mutex);
1001     }
1002     break;
1003   case PROP_NOTATION_LOOP:
1004     {
1005       g_rec_mutex_lock(recall_mutex);
1006 
1007       g_value_set_object(value, count_beats_audio->notation_loop);
1008 
1009       g_rec_mutex_unlock(recall_mutex);
1010     }
1011     break;
1012   case PROP_NOTATION_LOOP_START:
1013     {
1014       g_rec_mutex_lock(recall_mutex);
1015 
1016       g_value_set_object(value, count_beats_audio->notation_loop_start);
1017 
1018       g_rec_mutex_unlock(recall_mutex);
1019     }
1020     break;
1021   case PROP_NOTATION_LOOP_END:
1022     {
1023       g_rec_mutex_lock(recall_mutex);
1024 
1025       g_value_set_object(value, count_beats_audio->notation_loop_end);
1026 
1027       g_rec_mutex_unlock(recall_mutex);
1028     }
1029     break;
1030   case PROP_WAVE_LOOP:
1031     {
1032       g_rec_mutex_lock(recall_mutex);
1033 
1034       g_value_set_object(value, count_beats_audio->wave_loop);
1035 
1036       g_rec_mutex_unlock(recall_mutex);
1037     }
1038     break;
1039   case PROP_WAVE_LOOP_START:
1040     {
1041       g_rec_mutex_lock(recall_mutex);
1042 
1043       g_value_set_object(value, count_beats_audio->wave_loop_start);
1044 
1045       g_rec_mutex_unlock(recall_mutex);
1046     }
1047     break;
1048   case PROP_WAVE_LOOP_END:
1049     {
1050       g_rec_mutex_lock(recall_mutex);
1051 
1052       g_value_set_object(value, count_beats_audio->wave_loop_end);
1053 
1054       g_rec_mutex_unlock(recall_mutex);
1055     }
1056     break;
1057   case PROP_MIDI_LOOP:
1058     {
1059       g_rec_mutex_lock(recall_mutex);
1060 
1061       g_value_set_object(value, count_beats_audio->midi_loop);
1062 
1063       g_rec_mutex_unlock(recall_mutex);
1064     }
1065     break;
1066   case PROP_MIDI_LOOP_START:
1067     {
1068       g_rec_mutex_lock(recall_mutex);
1069 
1070       g_value_set_object(value, count_beats_audio->midi_loop_start);
1071 
1072       g_rec_mutex_unlock(recall_mutex);
1073     }
1074     break;
1075   case PROP_MIDI_LOOP_END:
1076     {
1077       g_rec_mutex_lock(recall_mutex);
1078 
1079       g_value_set_object(value, count_beats_audio->midi_loop_end);
1080 
1081       g_rec_mutex_unlock(recall_mutex);
1082     }
1083     break;
1084   default:
1085     G_OBJECT_WARN_INVALID_PROPERTY_ID(gobject, prop_id, param_spec);
1086     break;
1087   };
1088 }
1089 
1090 void
ags_count_beats_audio_dispose(GObject * gobject)1091 ags_count_beats_audio_dispose(GObject *gobject)
1092 {
1093   AgsCountBeatsAudio *count_beats_audio;
1094 
1095   count_beats_audio = AGS_COUNT_BEATS_AUDIO(gobject);
1096 
1097   /* sequencer */
1098   if(count_beats_audio->sequencer_loop != NULL){
1099     g_object_unref(G_OBJECT(count_beats_audio->sequencer_loop));
1100 
1101     count_beats_audio->sequencer_loop = NULL;
1102   }
1103 
1104   if(count_beats_audio->sequencer_loop_start != NULL){
1105     g_object_unref(G_OBJECT(count_beats_audio->sequencer_loop_start));
1106 
1107     count_beats_audio->sequencer_loop_start = NULL;
1108   }
1109 
1110   if(count_beats_audio->sequencer_loop_end != NULL){
1111     g_object_unref(G_OBJECT(count_beats_audio->sequencer_loop_end));
1112 
1113     count_beats_audio->sequencer_loop_end = NULL;
1114   }
1115 
1116   /* notation */
1117   if(count_beats_audio->notation_loop != NULL){
1118     g_object_unref(G_OBJECT(count_beats_audio->notation_loop));
1119 
1120     count_beats_audio->notation_loop = NULL;
1121   }
1122 
1123   if(count_beats_audio->notation_loop_start != NULL){
1124     g_object_unref(G_OBJECT(count_beats_audio->notation_loop_start));
1125 
1126     count_beats_audio->notation_loop_start = NULL;
1127   }
1128 
1129   if(count_beats_audio->notation_loop_end != NULL){
1130     g_object_unref(G_OBJECT(count_beats_audio->notation_loop_end));
1131 
1132     count_beats_audio->notation_loop_end = NULL;
1133   }
1134 
1135   /* wave */
1136   if(count_beats_audio->wave_loop != NULL){
1137     g_object_unref(G_OBJECT(count_beats_audio->wave_loop));
1138 
1139     count_beats_audio->wave_loop = NULL;
1140   }
1141 
1142   if(count_beats_audio->wave_loop_start != NULL){
1143     g_object_unref(G_OBJECT(count_beats_audio->wave_loop_start));
1144 
1145     count_beats_audio->wave_loop_start = NULL;
1146   }
1147 
1148   if(count_beats_audio->wave_loop_end != NULL){
1149     g_object_unref(G_OBJECT(count_beats_audio->wave_loop_end));
1150 
1151     count_beats_audio->wave_loop_end = NULL;
1152   }
1153 
1154   /* midi */
1155   if(count_beats_audio->midi_loop != NULL){
1156     g_object_unref(G_OBJECT(count_beats_audio->midi_loop));
1157 
1158     count_beats_audio->midi_loop = NULL;
1159   }
1160 
1161   if(count_beats_audio->midi_loop_start != NULL){
1162     g_object_unref(G_OBJECT(count_beats_audio->midi_loop_start));
1163 
1164     count_beats_audio->midi_loop_start = NULL;
1165   }
1166 
1167   if(count_beats_audio->midi_loop_end != NULL){
1168     g_object_unref(G_OBJECT(count_beats_audio->midi_loop_end));
1169 
1170     count_beats_audio->midi_loop_end = NULL;
1171   }
1172 
1173   /* call parent */
1174   G_OBJECT_CLASS(ags_count_beats_audio_parent_class)->dispose(gobject);
1175 }
1176 
1177 void
ags_count_beats_audio_finalize(GObject * gobject)1178 ags_count_beats_audio_finalize(GObject *gobject)
1179 {
1180   AgsCountBeatsAudio *count_beats_audio;
1181 
1182   count_beats_audio = AGS_COUNT_BEATS_AUDIO(gobject);
1183 
1184   /* sequencer */
1185   if(count_beats_audio->sequencer_loop != NULL){
1186     g_object_unref(G_OBJECT(count_beats_audio->sequencer_loop));
1187   }
1188 
1189   if(count_beats_audio->sequencer_loop_start != NULL){
1190     g_object_unref(G_OBJECT(count_beats_audio->sequencer_loop_start));
1191   }
1192 
1193   if(count_beats_audio->sequencer_loop_end != NULL){
1194     g_object_unref(G_OBJECT(count_beats_audio->sequencer_loop_end));
1195   }
1196 
1197   /* notation */
1198   if(count_beats_audio->notation_loop_start != NULL){
1199     g_object_unref(G_OBJECT(count_beats_audio->notation_loop_start));
1200   }
1201 
1202   if(count_beats_audio->notation_loop_end != NULL){
1203     g_object_unref(G_OBJECT(count_beats_audio->notation_loop_end));
1204   }
1205 
1206   if(count_beats_audio->notation_loop != NULL){
1207     g_object_unref(G_OBJECT(count_beats_audio->notation_loop));
1208   }
1209 
1210   /* wave */
1211   if(count_beats_audio->wave_loop != NULL){
1212     g_object_unref(G_OBJECT(count_beats_audio->wave_loop));
1213   }
1214 
1215   if(count_beats_audio->wave_loop_start != NULL){
1216     g_object_unref(G_OBJECT(count_beats_audio->wave_loop_start));
1217   }
1218 
1219   if(count_beats_audio->wave_loop_end != NULL){
1220     g_object_unref(G_OBJECT(count_beats_audio->wave_loop_end));
1221   }
1222 
1223   /* midi */
1224   if(count_beats_audio->midi_loop != NULL){
1225     g_object_unref(G_OBJECT(count_beats_audio->midi_loop));
1226   }
1227 
1228   if(count_beats_audio->midi_loop_start != NULL){
1229     g_object_unref(G_OBJECT(count_beats_audio->midi_loop_start));
1230   }
1231 
1232   if(count_beats_audio->midi_loop_end != NULL){
1233     g_object_unref(G_OBJECT(count_beats_audio->midi_loop_end));
1234   }
1235 
1236   /* call parent */
1237   G_OBJECT_CLASS(ags_count_beats_audio_parent_class)->finalize(gobject);
1238 }
1239 
1240 void
ags_count_beats_audio_notify_output_soundcard_callback(GObject * gobject,GParamSpec * pspec,gpointer user_data)1241 ags_count_beats_audio_notify_output_soundcard_callback(GObject *gobject,
1242 						       GParamSpec *pspec,
1243 						       gpointer user_data)
1244 {
1245   AgsCountBeatsAudio *count_beats_audio;
1246   AgsPort *notation_loop;
1247   AgsPort *notation_loop_start;
1248   AgsPort *notation_loop_end;
1249   AgsPort *wave_loop;
1250   AgsPort *wave_loop_start;
1251   AgsPort *wave_loop_end;
1252   AgsPort *midi_loop;
1253   AgsPort *midi_loop_start;
1254   AgsPort *midi_loop_end;
1255 
1256   GObject *output_soundcard;
1257 
1258   guint loop_start, loop_end;
1259   gboolean do_loop;
1260 
1261   GValue loop_start_value = {0,};
1262   GValue loop_end_value = {0,};
1263   GValue do_loop_value = {0,};
1264 
1265   count_beats_audio = AGS_COUNT_BEATS_AUDIO(gobject);
1266 
1267   g_object_get(gobject,
1268 	       "output-soundcard", &output_soundcard,
1269 	       NULL);
1270 
1271   if(output_soundcard == NULL){
1272     return;
1273   }
1274 
1275   /* retrieve loop information */
1276   ags_soundcard_get_loop(AGS_SOUNDCARD(output_soundcard),
1277 			 &loop_start, &loop_end,
1278 			 &do_loop);
1279 
1280   /* set loop information on ports */
1281   g_object_get(gobject,
1282 	       "notation-loop", &notation_loop,
1283 	       "notation-loop-start", &notation_loop_start,
1284 	       "notation-loop-end", &notation_loop_end,
1285 	       "wave-loop", &wave_loop,
1286 	       "wave-loop-start", &wave_loop_start,
1287 	       "wave-loop-end", &wave_loop_end,
1288 	       "midi-loop", &midi_loop,
1289 	       "midi-loop-start", &midi_loop_start,
1290 	       "midi-loop-end", &midi_loop_end,
1291 	       NULL);
1292 
1293   g_value_init(&do_loop_value, G_TYPE_BOOLEAN);
1294   g_value_init(&loop_start_value, G_TYPE_UINT64);
1295   g_value_init(&loop_end_value, G_TYPE_UINT64);
1296 
1297   g_value_set_uint64(&loop_start_value,
1298 		     (guint64) loop_start);
1299   g_value_set_uint64(&loop_end_value,
1300 		     (guint64) loop_end);
1301   g_value_set_boolean(&do_loop_value,
1302 		      do_loop);
1303 
1304   /* notation */
1305   ags_port_safe_write(notation_loop,
1306  		      &do_loop_value);
1307   ags_port_safe_write(notation_loop_start,
1308 		      &loop_start_value);
1309   ags_port_safe_write(notation_loop_end,
1310 		      &loop_end_value);
1311 
1312   /* wave */
1313   ags_port_safe_write(wave_loop,
1314 		      &do_loop_value);
1315   ags_port_safe_write(wave_loop_start,
1316 		      &loop_start_value);
1317   ags_port_safe_write(wave_loop_end,
1318 		      &loop_end_value);
1319 
1320   /* midi */
1321   ags_port_safe_write(midi_loop,
1322 		      &do_loop_value);
1323   ags_port_safe_write(midi_loop_start,
1324 		      &loop_start_value);
1325   ags_port_safe_write(midi_loop_end,
1326 		      &loop_end_value);
1327 
1328   /* unset value */
1329   g_value_unset(&do_loop_value);
1330   g_value_unset(&loop_start_value);
1331   g_value_unset(&loop_end_value);
1332 
1333   /* unref */
1334   g_object_unref(output_soundcard);
1335 
1336   g_object_unref(notation_loop);
1337   g_object_unref(notation_loop_start);
1338   g_object_unref(notation_loop_end);
1339 
1340   g_object_unref(wave_loop);
1341   g_object_unref(wave_loop_start);
1342   g_object_unref(wave_loop_end);
1343 
1344   g_object_unref(midi_loop);
1345   g_object_unref(midi_loop_start);
1346   g_object_unref(midi_loop_end);
1347 }
1348 
1349 void
ags_count_beats_audio_change_sequencer_duration(AgsTactable * tactable,guint64 duration)1350 ags_count_beats_audio_change_sequencer_duration(AgsTactable *tactable, guint64 duration)
1351 {
1352   AgsPort *port;
1353   AgsCountBeatsAudio *count_beats_audio;
1354 
1355   GValue value = {0,};
1356 
1357   count_beats_audio = AGS_COUNT_BEATS_AUDIO(tactable);
1358 
1359   /* get port */
1360   g_object_get(count_beats_audio,
1361 	       "sequencer-loop-end", &port,
1362 	       NULL);
1363 
1364   /* safe write */
1365   g_value_init(&value,
1366 	       G_TYPE_UINT64);
1367 
1368   g_value_set_uint64(&value,
1369 		     duration);
1370   ags_port_safe_write(port,
1371 		      &value);
1372 
1373   g_value_unset(&value);
1374 
1375   g_object_unref(port);
1376 }
1377 
1378 void
ags_count_beats_audio_change_notation_duration(AgsTactable * tactable,guint64 duration)1379 ags_count_beats_audio_change_notation_duration(AgsTactable *tactable, guint64 duration)
1380 {
1381   AgsPort *port;
1382   AgsCountBeatsAudio *count_beats_audio;
1383 
1384   GValue value = {0,};
1385 
1386   count_beats_audio = AGS_COUNT_BEATS_AUDIO(tactable);
1387 
1388   /* get port */
1389   g_object_get(count_beats_audio,
1390 	       "notation-loop-end", &port,
1391 	       NULL);
1392 
1393   /* safe write */
1394   g_value_init(&value,
1395 	       G_TYPE_UINT64);
1396 
1397   g_value_set_uint64(&value,
1398 		     duration);
1399 
1400   ags_port_safe_write(port,
1401 		      &value);
1402 
1403   g_value_unset(&value);
1404 
1405   g_object_unref(port);
1406 }
1407 
1408 void
ags_count_beats_audio_change_wave_duration(AgsTactable * tactable,guint64 duration)1409 ags_count_beats_audio_change_wave_duration(AgsTactable *tactable, guint64 duration)
1410 {
1411   AgsPort *port;
1412   AgsCountBeatsAudio *count_beats_audio;
1413 
1414   GValue value = {0,};
1415 
1416   count_beats_audio = AGS_COUNT_BEATS_AUDIO(tactable);
1417 
1418   /* get port */
1419   g_object_get(count_beats_audio,
1420 	       "wave-loop-end", &port,
1421 	       NULL);
1422 
1423   /* safe write */
1424   g_value_init(&value,
1425 	       G_TYPE_UINT64);
1426 
1427   g_value_set_uint64(&value,
1428 		     duration);
1429 
1430   ags_port_safe_write(port,
1431 		      &value);
1432 
1433   g_value_unset(&value);
1434 
1435   g_object_unref(port);
1436 }
1437 
1438 void
ags_count_beats_audio_change_midi_duration(AgsTactable * tactable,guint64 duration)1439 ags_count_beats_audio_change_midi_duration(AgsTactable *tactable, guint64 duration)
1440 {
1441   AgsPort *port;
1442   AgsCountBeatsAudio *count_beats_audio;
1443 
1444   GValue value = {0,};
1445 
1446   count_beats_audio = AGS_COUNT_BEATS_AUDIO(tactable);
1447 
1448   /* get port */
1449   g_object_get(count_beats_audio,
1450 	       "midi-loop-end", &port,
1451 	       NULL);
1452 
1453   /* safe write */
1454   g_value_init(&value,
1455 	       G_TYPE_UINT64);
1456 
1457   g_value_set_uint64(&value,
1458 		     duration);
1459 
1460   ags_port_safe_write(port,
1461 		      &value);
1462 
1463   g_value_unset(&value);
1464 
1465   g_object_unref(port);
1466 }
1467 
1468 /**
1469  * ags_count_beats_audio_new:
1470  * @audio: the #AgsAudio
1471  *
1472  * Create a new instance of #AgsCountBeatsAudio
1473  *
1474  * Returns: the new #AgsCountBeatsAudio
1475  *
1476  * Since: 3.0.0
1477  */
1478 AgsCountBeatsAudio*
ags_count_beats_audio_new(AgsAudio * audio)1479 ags_count_beats_audio_new(AgsAudio *audio)
1480 {
1481   AgsCountBeatsAudio *count_beats_audio;
1482 
1483   count_beats_audio = (AgsCountBeatsAudio *) g_object_new(AGS_TYPE_COUNT_BEATS_AUDIO,
1484 							  "audio", audio,
1485 							  NULL);
1486 
1487   return(count_beats_audio);
1488 }
1489