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/X/ags_navigation_callbacks.h>
21
22 #include <ags/X/ags_ui_provider.h>
23 #include <ags/X/ags_window.h>
24
25 void
ags_navigation_expander_callback(GtkWidget * widget,AgsNavigation * navigation)26 ags_navigation_expander_callback(GtkWidget *widget,
27 AgsNavigation *navigation)
28 {
29 GtkImage *image;
30
31 GList *start_list;
32
33 gchar *icon_name;
34
35 start_list = gtk_container_get_children((GtkContainer *) widget);
36 image = (GtkImage *) start_list->data;
37 g_list_free(start_list);
38
39 start_list = gtk_container_get_children((GtkContainer *) navigation);
40 widget = (GtkWidget *) start_list->next->data;
41 g_list_free(start_list);
42
43 g_object_get(image,
44 "icon-name", &icon_name,
45 NULL);
46
47 if(!g_strcmp0("down",
48 icon_name)){
49 gtk_widget_hide(widget);
50
51 g_object_set(image,
52 "icon-name", "up",
53 NULL);
54 }else{
55 gtk_widget_show_all(widget);
56
57 g_object_set(image,
58 "icon-name", "down",
59 NULL);
60 }
61 }
62
63 void
ags_navigation_bpm_callback(GtkWidget * widget,AgsNavigation * navigation)64 ags_navigation_bpm_callback(GtkWidget *widget,
65 AgsNavigation *navigation)
66 {
67 AgsApplyBpm *apply_bpm;
68
69 AgsApplicationContext *application_context;
70
71 application_context = ags_application_context_get_instance();
72
73 /* get task thread */
74 apply_bpm = ags_apply_bpm_new((GObject *) application_context,
75 gtk_spin_button_get_value(navigation->bpm));
76
77 ags_ui_provider_schedule_task(AGS_UI_PROVIDER(application_context),
78 (AgsTask *) apply_bpm);
79 }
80
81 void
ags_navigation_rewind_callback(GtkWidget * widget,AgsNavigation * navigation)82 ags_navigation_rewind_callback(GtkWidget *widget,
83 AgsNavigation *navigation)
84 {
85 AgsApplicationContext *application_context;
86
87 GObject *default_soundcard;
88
89 gdouble tact;
90
91 application_context = ags_application_context_get_instance();
92
93 default_soundcard = ags_sound_provider_get_default_soundcard(AGS_SOUND_PROVIDER(application_context));
94
95 tact = ags_soundcard_get_note_offset(AGS_SOUNDCARD(default_soundcard)) / 16.0;
96
97 gtk_spin_button_set_value(navigation->position_tact,
98 tact +
99 (-1.0 * AGS_NAVIGATION_DEFAULT_TACT_STEP));
100 }
101
102 void
ags_navigation_prev_callback(GtkWidget * widget,AgsNavigation * navigation)103 ags_navigation_prev_callback(GtkWidget *widget,
104 AgsNavigation *navigation)
105 {
106 AgsApplicationContext *application_context;
107
108 GObject *default_soundcard;
109
110 gdouble tact;
111
112 application_context = ags_application_context_get_instance();
113
114 default_soundcard = ags_sound_provider_get_default_soundcard(AGS_SOUND_PROVIDER(application_context));
115
116 tact = ags_soundcard_get_note_offset(AGS_SOUNDCARD(default_soundcard)) / 16.0;
117
118 gtk_spin_button_set_value(navigation->position_tact,
119 tact +
120 (-1.0 * AGS_NAVIGATION_REWIND_STEPS));
121 }
122
123 void
ags_navigation_play_callback(GtkWidget * widget,AgsNavigation * navigation)124 ags_navigation_play_callback(GtkWidget *widget,
125 AgsNavigation *navigation)
126 {
127 AgsWindow *window;
128 AgsMachine *machine;
129
130 AgsApplicationContext *application_context;
131
132 GObject *default_soundcard;
133
134 GList *machines, *machines_start;
135
136 gboolean initialized_time;
137
138 if((AGS_NAVIGATION_BLOCK_PLAY & (navigation->flags)) != 0){
139 return;
140 }
141
142 window = AGS_WINDOW(gtk_widget_get_toplevel(GTK_WIDGET(navigation)));
143
144 application_context = ags_application_context_get_instance();
145
146 default_soundcard = ags_sound_provider_get_default_soundcard(AGS_SOUND_PROVIDER(application_context));
147
148 machines_start =
149 machines = gtk_container_get_children(GTK_CONTAINER(window->machines));
150
151 initialized_time = FALSE;
152
153 while(machines != NULL){
154 machine = AGS_MACHINE(machines->data);
155
156 if((AGS_MACHINE_IS_SEQUENCER & (machine->flags)) != 0 ||
157 (AGS_MACHINE_IS_SYNTHESIZER & (machine->flags)) != 0){
158 #ifdef AGS_DEBUG
159 g_message("found machine to play!\n");
160 #endif
161
162 if(!initialized_time){
163 initialized_time = TRUE;
164 navigation->start_tact = ags_soundcard_get_note_offset(AGS_SOUNDCARD(default_soundcard));
165 }
166
167 ags_machine_set_run_extended(machine,
168 TRUE,
169 !gtk_toggle_button_get_active((GtkToggleButton *) navigation->exclude_sequencer), TRUE, FALSE, FALSE);
170 }else if((AGS_MACHINE_IS_WAVE_PLAYER & (machine->flags)) != 0){
171 #ifdef AGS_DEBUG
172 g_message("found machine to play!\n");
173 #endif
174
175 if(!initialized_time){
176 initialized_time = TRUE;
177 navigation->start_tact = ags_soundcard_get_note_offset(AGS_SOUNDCARD(default_soundcard));
178 }
179
180 ags_machine_set_run_extended(machine,
181 TRUE,
182 FALSE, FALSE, TRUE, FALSE);
183 }
184
185 machines = machines->next;
186 }
187
188 g_list_free(machines_start);
189 }
190
191 void
ags_navigation_stop_callback(GtkWidget * widget,AgsNavigation * navigation)192 ags_navigation_stop_callback(GtkWidget *widget,
193 AgsNavigation *navigation)
194 {
195 AgsWindow *window;
196 AgsMachine *machine;
197
198 AgsApplicationContext *application_context;
199
200 GObject *default_soundcard;
201
202 GList *machines,*machines_start;
203
204 gchar *timestr;
205
206 window = AGS_WINDOW(gtk_widget_get_toplevel(GTK_WIDGET(navigation)));
207
208 application_context = ags_application_context_get_instance();
209
210 default_soundcard = ags_sound_provider_get_default_soundcard(AGS_SOUND_PROVIDER(application_context));
211
212 machines_start =
213 machines = gtk_container_get_children(GTK_CONTAINER(window->machines));
214
215 while(machines != NULL){
216 machine = AGS_MACHINE(machines->data);
217
218 if((AGS_MACHINE_IS_SEQUENCER & (machine->flags)) != 0 ||
219 (AGS_MACHINE_IS_SYNTHESIZER & (machine->flags)) != 0){
220 #ifdef AGS_DEBUG
221 g_message("found machine to stop!");
222 #endif
223
224 ags_machine_set_run_extended(machine,
225 FALSE,
226 !gtk_toggle_button_get_active((GtkToggleButton *) navigation->exclude_sequencer), TRUE, FALSE, FALSE);
227 }else if((AGS_MACHINE_IS_WAVE_PLAYER & (machine->flags)) != 0){
228 #ifdef AGS_DEBUG
229 g_message("found machine to stop!");
230 #endif
231
232 ags_machine_set_run_extended(machine,
233 FALSE,
234 FALSE, FALSE, TRUE, FALSE);
235 }
236
237 machines = machines->next;
238 }
239
240 g_list_free(machines_start);
241
242 /* toggle play button */
243 navigation->flags |= AGS_NAVIGATION_BLOCK_PLAY;
244 gtk_toggle_button_set_active(navigation->play,
245 FALSE);
246
247 navigation->flags &= (~AGS_NAVIGATION_BLOCK_PLAY);
248
249 navigation->start_tact = 0.0;
250
251 timestr = ags_time_get_uptime_from_offset(0.0,
252 gtk_spin_button_get_value(navigation->bpm),
253 ags_soundcard_get_delay(AGS_SOUNDCARD(default_soundcard)),
254 ags_soundcard_get_delay_factor(AGS_SOUNDCARD(default_soundcard)));
255 gtk_label_set_text(navigation->duration_time, timestr);
256
257 g_free(timestr);
258 ags_soundcard_set_note_offset(AGS_SOUNDCARD(default_soundcard),
259 0);
260 }
261
262 void
ags_navigation_next_callback(GtkWidget * widget,AgsNavigation * navigation)263 ags_navigation_next_callback(GtkWidget *widget,
264 AgsNavigation *navigation)
265 {
266 AgsApplicationContext *application_context;
267
268 GObject *default_soundcard;
269
270 gdouble tact;
271
272 application_context = ags_application_context_get_instance();
273
274 default_soundcard = ags_sound_provider_get_default_soundcard(AGS_SOUND_PROVIDER(application_context));
275
276 tact = ags_soundcard_get_note_offset(AGS_SOUNDCARD(default_soundcard)) / 16.0;
277
278 gtk_spin_button_set_value(navigation->position_tact,
279 tact +
280 AGS_NAVIGATION_REWIND_STEPS);
281 }
282
283 void
ags_navigation_forward_callback(GtkWidget * widget,AgsNavigation * navigation)284 ags_navigation_forward_callback(GtkWidget *widget,
285 AgsNavigation *navigation)
286 {
287 AgsApplicationContext *application_context;
288
289 GObject *default_soundcard;
290
291 gdouble tact;
292
293 application_context = ags_application_context_get_instance();
294
295 default_soundcard = ags_sound_provider_get_default_soundcard(AGS_SOUND_PROVIDER(application_context));
296
297 tact = ags_soundcard_get_note_offset(AGS_SOUNDCARD(default_soundcard)) / 16.0;
298
299 gtk_spin_button_set_value(navigation->position_tact,
300 tact +
301 AGS_NAVIGATION_DEFAULT_TACT_STEP);
302 }
303
304 void
ags_navigation_loop_callback(GtkWidget * widget,AgsNavigation * navigation)305 ags_navigation_loop_callback(GtkWidget *widget,
306 AgsNavigation *navigation)
307 {
308 AgsWindow *window;
309 AgsMachine *machine;
310
311 AgsAudio *audio;
312 AgsRecall *recall;
313
314 AgsApplicationContext *application_context;
315
316 GObject *default_soundcard;
317
318 GList *machines, *machines_start;
319 GList *list, *list_start;
320
321 guint loop_left, loop_right;
322
323 GValue do_loop_value = {0,};
324
325 window = AGS_WINDOW(gtk_widget_get_toplevel(GTK_WIDGET(navigation)));
326
327 application_context = ags_application_context_get_instance();
328
329 default_soundcard = ags_sound_provider_get_default_soundcard(AGS_SOUND_PROVIDER(application_context));
330
331 machines_start =
332 machines = gtk_container_get_children(GTK_CONTAINER(window->machines));
333
334 loop_left = 16 * gtk_spin_button_get_value(navigation->loop_left_tact);
335 loop_right = 16 * gtk_spin_button_get_value(navigation->loop_right_tact);
336
337 ags_soundcard_set_loop(AGS_SOUNDCARD(default_soundcard),
338 loop_left, loop_right,
339 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)));
340
341 g_value_init(&do_loop_value, G_TYPE_BOOLEAN);
342 g_value_set_boolean(&do_loop_value,
343 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)));
344
345 while(machines != NULL){
346 machine = AGS_MACHINE(machines->data);
347
348 if((AGS_MACHINE_IS_SEQUENCER & (machine->flags)) != 0 ||
349 (AGS_MACHINE_IS_SYNTHESIZER & (machine->flags)) != 0){
350 #ifdef AGS_DEBUG
351 g_message("found machine to loop!");
352 #endif
353
354 audio = machine->audio;
355
356 /* do it so */
357 g_object_get(audio,
358 "play", &list_start,
359 NULL);
360
361 list = list_start;
362
363 while((list = ags_recall_find_type(list,
364 AGS_TYPE_FX_NOTATION_AUDIO)) != NULL){
365 AgsPort *port;
366
367 recall = AGS_RECALL(list->data);
368
369 g_object_get(recall,
370 "loop", &port,
371 NULL);
372
373 ags_port_safe_write(port,
374 &do_loop_value);
375
376 list = list->next;
377 }
378
379 g_list_free_full(list_start,
380 g_object_unref);
381
382 /* recall context */
383 g_object_get(audio,
384 "recall", &list_start,
385 NULL);
386
387 list = list_start;
388
389 while((list = ags_recall_find_type(list,
390 AGS_TYPE_FX_NOTATION_AUDIO)) != NULL){
391 AgsPort *port;
392
393 recall = AGS_RECALL(list->data);
394
395 g_object_get(recall,
396 "loop", &port,
397 NULL);
398
399 ags_port_safe_write(port,
400 &do_loop_value);
401
402 list = list->next;
403 }
404
405 g_list_free_full(list_start,
406 g_object_unref);
407 }else if((AGS_MACHINE_IS_WAVE_PLAYER & (machine->flags)) != 0){
408 #ifdef AGS_DEBUG
409 g_message("found machine to loop!\n");
410 #endif
411
412 audio = machine->audio;
413
414 /* do it so */
415 g_object_get(audio,
416 "play", &list_start,
417 NULL);
418
419 list = list_start;
420
421 while((list = ags_recall_find_type(list,
422 AGS_TYPE_FX_PLAYBACK_AUDIO)) != NULL){
423 AgsPort *port;
424
425 recall = AGS_RECALL(list->data);
426
427 g_object_get(recall,
428 "loop", &port,
429 NULL);
430
431 ags_port_safe_write(port,
432 &do_loop_value);
433
434 list = list->next;
435 }
436
437 g_list_free_full(list_start,
438 g_object_unref);
439
440 /* recall context */
441 g_object_get(audio,
442 "recall", &list_start,
443 NULL);
444
445 list = list_start;
446
447 while((list = ags_recall_find_type(list,
448 AGS_TYPE_FX_PLAYBACK_AUDIO)) != NULL){
449 AgsPort *port;
450
451 recall = AGS_RECALL(list->data);
452
453 g_object_get(recall,
454 "loop", &port,
455 NULL);
456
457 ags_port_safe_write(port,
458 &do_loop_value);
459
460 list = list->next;
461 }
462
463 g_list_free_full(list_start,
464 g_object_unref);
465 }
466
467 machines = machines->next;
468 }
469
470 g_list_free(machines_start);
471
472 /* enable fader */
473 //TODO:JK: implement me
474 }
475
476 void
ags_navigation_position_tact_callback(GtkWidget * widget,AgsNavigation * navigation)477 ags_navigation_position_tact_callback(GtkWidget *widget,
478 AgsNavigation *navigation)
479 {
480 ags_navigation_change_position(navigation,
481 gtk_spin_button_get_value((GtkSpinButton *) widget));
482 }
483
484 void
ags_navigation_duration_tact_callback(GtkWidget * widget,AgsNavigation * navigation)485 ags_navigation_duration_tact_callback(GtkWidget *widget,
486 AgsNavigation *navigation)
487 {
488 /* empty */
489 }
490
491 void
ags_navigation_loop_left_tact_callback(GtkWidget * widget,AgsNavigation * navigation)492 ags_navigation_loop_left_tact_callback(GtkWidget *widget,
493 AgsNavigation *navigation)
494 {
495 AgsWindow *window;
496 AgsMachine *machine;
497
498 AgsAudio *audio;
499 AgsRecall *recall;
500
501 AgsApplicationContext *application_context;
502
503 GObject *default_soundcard;
504
505 GList *machines, *machines_start;
506 GList *list, *list_start; // find AgsPlayNotationAudio and AgsCopyPatternAudio
507
508 guint loop_left, loop_right;
509
510 GValue value = {0,};
511
512 window = AGS_WINDOW(gtk_widget_get_toplevel(GTK_WIDGET(navigation)));
513
514 application_context = ags_application_context_get_instance();
515
516 default_soundcard = ags_sound_provider_get_default_soundcard(AGS_SOUND_PROVIDER(application_context));
517
518 machines_start =
519 machines = gtk_container_get_children(GTK_CONTAINER(window->machines));
520
521 loop_left = 16 * gtk_spin_button_get_value(navigation->loop_left_tact);
522 loop_right = 16 * gtk_spin_button_get_value(navigation->loop_right_tact);
523
524 ags_soundcard_set_loop(AGS_SOUNDCARD(default_soundcard),
525 loop_left, loop_right,
526 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(navigation->loop)));
527
528 g_value_init(&value, G_TYPE_UINT64);
529 g_value_set_uint64(&value,
530 (guint64) loop_left);
531
532 while(machines != NULL){
533 machine = AGS_MACHINE(machines->data);
534
535 if((AGS_MACHINE_IS_SEQUENCER & (machine->flags)) != 0 ||
536 (AGS_MACHINE_IS_SYNTHESIZER & (machine->flags)) != 0){
537 #ifdef AGS_DEBUG
538 g_message("found machine to loop!\n");
539 #endif
540
541 audio = machine->audio;
542
543 /* do it so */
544 g_object_get(audio,
545 "play", &list_start,
546 NULL);
547
548 list = list_start;
549
550 while((list = ags_recall_find_type(list,
551 AGS_TYPE_FX_NOTATION_AUDIO)) != NULL){
552 AgsPort *port;
553
554 recall = AGS_RECALL(list->data);
555
556 g_object_get(recall,
557 "loop-start", &port,
558 NULL);
559
560 ags_port_safe_write(port,
561 &value);
562
563 g_object_unref(port);
564
565 list = list->next;
566 }
567
568 g_list_free_full(list_start,
569 g_object_unref);
570
571 /* recall context */
572 g_object_get(audio,
573 "recall", &list_start,
574 NULL);
575
576 list = list_start;
577
578 while((list = ags_recall_find_type(list,
579 AGS_TYPE_FX_NOTATION_AUDIO)) != NULL){
580 AgsPort *port;
581
582 recall = AGS_RECALL(list->data);
583
584 g_object_get(recall,
585 "loop-start", &port,
586 NULL);
587
588 ags_port_safe_write(port,
589 &value);
590
591 g_object_unref(port);
592
593 list = list->next;
594 }
595
596 g_list_free_full(list_start,
597 g_object_unref);
598 }else if((AGS_MACHINE_IS_WAVE_PLAYER & (machine->flags)) != 0){
599 #ifdef AGS_DEBUG
600 g_message("found machine to loop!\n");
601 #endif
602
603 audio = machine->audio;
604
605 /* do it so */
606 g_object_get(audio,
607 "play", &list_start,
608 NULL);
609
610 list = list_start;
611
612 while((list = ags_recall_find_type(list,
613 AGS_TYPE_FX_PLAYBACK_AUDIO)) != NULL){
614 AgsPort *port;
615
616 recall = AGS_RECALL(list->data);
617
618 g_object_get(recall,
619 "loop-start", &port,
620 NULL);
621
622 ags_port_safe_write(port,
623 &value);
624
625 g_object_unref(port);
626
627 list = list->next;
628 }
629
630 g_list_free_full(list_start,
631 g_object_unref);
632
633 /* recall context */
634 g_object_get(audio,
635 "recall", &list_start,
636 NULL);
637
638 list = list_start;
639
640 while((list = ags_recall_find_type(list,
641 AGS_TYPE_FX_PLAYBACK_AUDIO)) != NULL){
642 AgsPort *port;
643
644 recall = AGS_RECALL(list->data);
645
646 g_object_get(recall,
647 "loop-start", &port,
648 NULL);
649
650 ags_port_safe_write(port,
651 &value);
652
653 g_object_unref(port);
654
655 list = list->next;
656 }
657
658 g_list_free_full(list_start,
659 g_object_unref);
660 }
661
662 machines = machines->next;
663 }
664
665 g_list_free(machines_start);
666 }
667
668 void
ags_navigation_loop_right_tact_callback(GtkWidget * widget,AgsNavigation * navigation)669 ags_navigation_loop_right_tact_callback(GtkWidget *widget,
670 AgsNavigation *navigation)
671 {
672 AgsWindow *window;
673 AgsMachine *machine;
674
675 AgsAudio *audio;
676 AgsRecall *recall;
677
678 AgsApplicationContext *application_context;
679
680 GObject *default_soundcard;
681
682 GList *machines, *machines_start;
683 GList *list, *list_start; // find AgsPlayNotationAudio and AgsCopyPatternAudio
684
685 guint loop_left, loop_right;
686
687 GValue value = {0,};
688
689 window = AGS_WINDOW(gtk_widget_get_toplevel(GTK_WIDGET(navigation)));
690
691 application_context = ags_application_context_get_instance();
692
693 default_soundcard = ags_sound_provider_get_default_soundcard(AGS_SOUND_PROVIDER(application_context));
694
695 machines_start =
696 machines = gtk_container_get_children(GTK_CONTAINER(window->machines));
697
698 loop_left = 16 * gtk_spin_button_get_value(navigation->loop_left_tact);
699 loop_right = 16 * gtk_spin_button_get_value(navigation->loop_right_tact);
700
701 ags_soundcard_set_loop(AGS_SOUNDCARD(default_soundcard),
702 loop_left, loop_right,
703 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(navigation->loop)));
704
705 g_value_init(&value, G_TYPE_UINT64);
706 g_value_set_uint64(&value,
707 (guint64) loop_right);
708
709 while(machines != NULL){
710 machine = AGS_MACHINE(machines->data);
711
712 if((AGS_MACHINE_IS_SEQUENCER & (machine->flags)) != 0 ||
713 (AGS_MACHINE_IS_SYNTHESIZER & (machine->flags)) != 0){
714 #ifdef AGS_DEBUG
715 g_message("found machine to loop!\n");
716 #endif
717
718 audio = machine->audio;
719
720 /* do it so */
721 g_object_get(audio,
722 "play", &list_start,
723 NULL);
724
725 list = list_start;
726
727 while((list = ags_recall_find_type(list,
728 AGS_TYPE_FX_NOTATION_AUDIO)) != NULL){
729 AgsPort *port;
730
731 recall = AGS_RECALL(list->data);
732
733 g_object_get(recall,
734 "loop-end", &port,
735 NULL);
736
737 ags_port_safe_write(port,
738 &value);
739
740 g_object_unref(port);
741
742 list = list->next;
743 }
744
745 g_list_free_full(list_start,
746 g_object_unref);
747
748 /* recall context */
749 g_object_get(audio,
750 "recall", &list_start,
751 NULL);
752
753 list = list_start;
754
755 while((list = ags_recall_find_type(list,
756 AGS_TYPE_FX_NOTATION_AUDIO)) != NULL){
757 AgsPort *port;
758
759 recall = AGS_RECALL(list->data);
760
761 g_object_get(recall,
762 "loop-end", &port,
763 NULL);
764
765 ags_port_safe_write(port,
766 &value);
767
768 g_object_unref(port);
769
770 list = list->next;
771 }
772
773 g_list_free_full(list_start,
774 g_object_unref);
775 }else if((AGS_MACHINE_IS_WAVE_PLAYER & (machine->flags)) != 0){
776 #ifdef AGS_DEBUG
777 g_message("found machine to loop!\n");
778 #endif
779
780 audio = machine->audio;
781
782 /* do it so */
783 g_object_get(audio,
784 "play", &list_start,
785 NULL);
786
787 list = list_start;
788
789 while((list = ags_recall_find_type(list,
790 AGS_TYPE_FX_PLAYBACK_AUDIO)) != NULL){
791 AgsPort *port;
792
793 recall = AGS_RECALL(list->data);
794
795 g_object_get(recall,
796 "loop-end", &port,
797 NULL);
798
799 ags_port_safe_write(port,
800 &value);
801
802 g_object_unref(port);
803
804 list = list->next;
805 }
806
807 g_list_free_full(list_start,
808 g_object_unref);
809
810 /* recall context */
811 g_object_get(audio,
812 "recall", &list_start,
813 NULL);
814
815 list = list_start;
816
817 while((list = ags_recall_find_type(list,
818 AGS_TYPE_FX_PLAYBACK_AUDIO)) != NULL){
819 AgsPort *port;
820
821 recall = AGS_RECALL(list->data);
822
823 g_object_get(recall,
824 "loop-end", &port,
825 NULL);
826
827 ags_port_safe_write(port,
828 &value);
829
830 g_object_unref(port);
831
832 list = list->next;
833 }
834
835 g_list_free_full(list_start,
836 g_object_unref);
837 }
838
839 machines = machines->next;
840 }
841
842 g_list_free(machines_start);
843 }
844
845 void
ags_navigation_soundcard_stop_callback(GObject * soundcard,AgsNavigation * navigation)846 ags_navigation_soundcard_stop_callback(GObject *soundcard,
847 AgsNavigation *navigation)
848 {
849 navigation->flags |= AGS_NAVIGATION_BLOCK_TIC;
850 }
851