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