1 /*
2 * Copyright (C) 2018-2021 Alexandros Theodotou <alex and zrythm dot org>
3 *
4 * This file is part of Zrythm
5 *
6 * Zrythm is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU Affero 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 * Zrythm 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 Affero General Public License for more details.
15 *
16 * You should have received a copy of the GNU Affero General Public License
17 * along with Zrythm. If not, see <https://www.gnu.org/licenses/>.
18 */
19
20 #include <math.h>
21 #include <unistd.h>
22 #include <stdlib.h>
23
24 #include "zrythm-config.h"
25
26 #include "audio/audio_track.h"
27 #include "audio/automation_track.h"
28 #include "audio/automation_tracklist.h"
29 #include "audio/channel.h"
30 #include "audio/engine_jack.h"
31 #include "audio/engine_rtmidi.h"
32 #include "audio/ext_port.h"
33 #include "audio/group_target_track.h"
34 #include "audio/hardware_processor.h"
35 #include "audio/instrument_track.h"
36 #include "audio/master_track.h"
37 #include "audio/midi_event.h"
38 #include "audio/midi_track.h"
39 #include "audio/router.h"
40 #include "audio/pan.h"
41 #include "audio/port_connections_manager.h"
42 #include "audio/rtmidi_device.h"
43 #include "audio/track.h"
44 #include "audio/track_processor.h"
45 #include "audio/transport.h"
46 #include "audio/windows_mme_device.h"
47 #include "plugins/lv2_plugin.h"
48 #include "plugins/lv2/lv2_gtk.h"
49 #include "gui/backend/event.h"
50 #include "gui/backend/event_manager.h"
51 #include "gui/widgets/bot_dock_edge.h"
52 #include "gui/widgets/center_dock.h"
53 #include "gui/widgets/channel.h"
54 #include "gui/widgets/main_window.h"
55 #include "gui/widgets/track.h"
56 #include "gui/widgets/tracklist.h"
57 #include "project.h"
58 #include "utils/arrays.h"
59 #include "utils/dialogs.h"
60 #include "utils/error.h"
61 #include "utils/flags.h"
62 #include "utils/math.h"
63 #include "utils/mem.h"
64 #include "utils/object_utils.h"
65 #include "utils/objects.h"
66 #include "utils/stoat.h"
67 #include "zrythm_app.h"
68
69 #include <gtk/gtk.h>
70 #include <glib/gi18n.h>
71
72 /**
73 * Connect ports in the case of !prev && !next.
74 */
75 NONNULL
76 static void
connect_no_prev_no_next(Channel * ch,Plugin * pl)77 connect_no_prev_no_next (
78 Channel * ch,
79 Plugin * pl)
80 {
81 g_debug ("connect no prev no next");
82
83 Track * track = channel_get_track (ch);
84 g_return_if_fail (IS_TRACK_AND_NONNULL (track));
85
86 /* -----------------------------------------
87 * disconnect ports
88 * ----------------------------------------- */
89 /* channel stereo in is connected to channel
90 * stereo out. disconnect it */
91 track_processor_disconnect_from_prefader (
92 track->processor);
93
94 /* -------------------------------------------
95 * connect input ports
96 * ------------------------------------------- */
97
98 /* connect channel stereo in to plugin */
99 track_processor_connect_to_plugin (
100 track->processor, pl);
101
102 /* --------------------------------------
103 * connect output ports
104 * ------------------------------------*/
105
106 /* connect plugin to stereo out */
107 plugin_connect_to_prefader (pl, ch);
108 }
109
110 /**
111 * Connect ports in the case of !prev && next.
112 */
113 NONNULL
114 static void
connect_no_prev_next(Channel * ch,Plugin * pl,Plugin * next_pl)115 connect_no_prev_next (
116 Channel * ch,
117 Plugin * pl,
118 Plugin * next_pl)
119 {
120 g_debug ("connect no prev next");
121
122 Track * track = channel_get_track (ch);
123 g_return_if_fail (IS_TRACK_AND_NONNULL (track));
124
125 /* -----------------------------------------
126 * disconnect ports
127 * ----------------------------------------- */
128 /* channel stereo in is connected to next plugin.
129 * disconnect it */
130 track_processor_disconnect_from_plugin (
131 track->processor, next_pl);
132
133 /* -------------------------------------------
134 * connect input ports
135 * ------------------------------------------- */
136
137 /* connect channel stereo in to plugin */
138 track_processor_connect_to_plugin (
139 track->processor, pl);
140
141 /* --------------------------------------
142 * connect output ports
143 * ------------------------------------*/
144
145 /* connect plugin's audio outs to next
146 * plugin */
147 plugin_connect_to_plugin (pl, next_pl);
148 }
149
150 /**
151 * Connect ports in the case of prev && !next.
152 */
153 NONNULL
154 static void
connect_prev_no_next(Channel * ch,Plugin * prev_pl,Plugin * pl)155 connect_prev_no_next (
156 Channel * ch,
157 Plugin * prev_pl,
158 Plugin * pl)
159 {
160 g_debug ("connect prev no next");
161
162 /* -----------------------------------------
163 * disconnect ports
164 * ----------------------------------------- */
165 /* prev plugin is connected to channel stereo out.
166 * disconnect it */
167 plugin_disconnect_from_prefader (
168 prev_pl, ch);
169
170 /* -------------------------------------------
171 * connect input ports
172 * ------------------------------------------- */
173
174 /* connect previous plugin's outs to
175 * plugin */
176 plugin_connect_to_plugin (
177 prev_pl, pl);
178
179 /* --------------------------------------
180 * connect output ports
181 * ------------------------------------*/
182
183 /* connect plugin output ports to stereo_out */
184 plugin_connect_to_prefader (
185 pl, ch);
186 }
187
188 /**
189 * Connect ports in the case of prev && next.
190 */
191 NONNULL
192 static void
connect_prev_next(Channel * ch,Plugin * prev_pl,Plugin * pl,Plugin * next_pl)193 connect_prev_next (
194 Channel * ch,
195 Plugin * prev_pl,
196 Plugin * pl,
197 Plugin * next_pl)
198 {
199 g_debug ("connect prev next");
200
201 /* -----------------------------------------
202 * disconnect ports
203 * ----------------------------------------- */
204 /* prev plugin is connected to the next pl.
205 * disconnect them */
206 plugin_disconnect_from_plugin (
207 prev_pl, next_pl);
208
209 /* -------------------------------------------
210 * connect input ports
211 * ------------------------------------------- */
212
213 /* connect previous plugin's audio outs to
214 * plugin */
215 plugin_connect_to_plugin (
216 prev_pl, pl);
217
218 /* ------------------------------------------
219 * Connect output ports
220 * ------------------------------------------ */
221
222 /* connect plugin's audio outs to next
223 * plugin */
224 plugin_connect_to_plugin (
225 pl, next_pl);
226 }
227
228 /**
229 * Disconnect ports in the case of !prev && !next.
230 */
231 NONNULL
232 static void
disconnect_no_prev_no_next(Channel * ch,Plugin * pl)233 disconnect_no_prev_no_next (
234 Channel * ch,
235 Plugin * pl)
236 {
237 Track * track = channel_get_track (ch);
238
239 /* -------------------------------------------
240 * disconnect input ports
241 * ------------------------------------------- */
242
243 /* disconnect channel stereo in from plugin */
244 track_processor_disconnect_from_plugin (
245 track->processor, pl);
246
247 /* --------------------------------------
248 * disconnect output ports
249 * ------------------------------------*/
250
251 /* disconnect plugin from stereo out */
252 plugin_disconnect_from_prefader (
253 pl, ch);
254
255 /* -----------------------------------------
256 * connect ports
257 * ----------------------------------------- */
258 /* channel stereo in should be connected to
259 * channel stereo out. connect it */
260 track_processor_connect_to_prefader (
261 track->processor);
262 }
263
264 /**
265 * Disconnect ports in the case of !prev && next.
266 */
267 NONNULL
268 static void
disconnect_no_prev_next(Channel * ch,Plugin * pl,Plugin * next_pl)269 disconnect_no_prev_next (
270 Channel * ch,
271 Plugin * pl,
272 Plugin * next_pl)
273 {
274 Track * track = channel_get_track (ch);
275
276 /* -------------------------------------------
277 * Disconnect input ports
278 * ------------------------------------------- */
279
280 /* disconnect channel stereo in from plugin */
281 track_processor_disconnect_from_plugin (
282 track->processor, pl);
283
284 /* --------------------------------------
285 * Disconnect output ports
286 * ------------------------------------*/
287
288 /* disconnect plugin's midi & audio outs from next
289 * plugin */
290 plugin_disconnect_from_plugin (
291 pl, next_pl);
292
293 /* -----------------------------------------
294 * connect ports
295 * ----------------------------------------- */
296 /* channel stereo in should be connected to next
297 * plugin. connect it */
298 track_processor_connect_to_plugin (
299 track->processor, next_pl);
300 }
301
302 /**
303 * Connect ports in the case of prev && !next.
304 */
305 NONNULL
306 static void
disconnect_prev_no_next(Channel * ch,Plugin * prev_pl,Plugin * pl)307 disconnect_prev_no_next (
308 Channel * ch,
309 Plugin * prev_pl,
310 Plugin * pl)
311 {
312 /* -------------------------------------------
313 * disconnect input ports
314 * ------------------------------------------- */
315
316 /* disconnect previous plugin's audio outs from
317 * plugin */
318 plugin_disconnect_from_plugin (
319 prev_pl, pl);
320
321 /* --------------------------------------
322 * Disconnect output ports
323 * ------------------------------------*/
324
325 /* disconnect plugin output ports from stereo
326 * out */
327 plugin_disconnect_from_prefader (
328 pl, ch);
329
330 /* -----------------------------------------
331 * connect ports
332 * ----------------------------------------- */
333 /* prev plugin should be connected to channel
334 * stereo out. connect it */
335 plugin_connect_to_prefader (
336 prev_pl, ch);
337 }
338
339 /**
340 * Connect ports in the case of prev && next.
341 */
342 NONNULL
343 static void
disconnect_prev_next(Channel * ch,Plugin * prev_pl,Plugin * pl,Plugin * next_pl)344 disconnect_prev_next (
345 Channel * ch,
346 Plugin * prev_pl,
347 Plugin * pl,
348 Plugin * next_pl)
349 {
350 /* -------------------------------------------
351 * disconnect input ports
352 * ------------------------------------------- */
353
354 /* disconnect previous plugin's audio outs from
355 * plugin */
356 plugin_disconnect_from_plugin (
357 prev_pl, pl);
358
359 /* ------------------------------------------
360 * Disconnect output ports
361 * ------------------------------------------ */
362
363 /* disconnect plugin's audio outs from next
364 * plugin */
365 plugin_disconnect_from_plugin (
366 pl, next_pl);
367
368 /* -----------------------------------------
369 * connect ports
370 * ----------------------------------------- */
371 /* prev plugin should be connected to the next pl.
372 * connect them */
373 plugin_connect_to_plugin (
374 prev_pl, next_pl);
375 }
376
377 /**
378 * Prepares the channel for processing.
379 *
380 * To be called before the main cycle each time on
381 * all channels.
382 */
383 void
channel_prepare_process(Channel * self)384 channel_prepare_process (Channel * self)
385 {
386 Plugin * plugin;
387 int j;
388 Track * tr = channel_get_track (self);
389 PortType out_type = tr->out_signal_type;
390
391 /* clear buffers */
392 track_processor_clear_buffers (
393 tr->processor);
394 fader_clear_buffers (
395 self->prefader);
396 fader_clear_buffers (self->fader);
397
398 if (out_type == TYPE_AUDIO)
399 {
400 port_clear_buffer (self->stereo_out->l);
401 port_clear_buffer (self->stereo_out->r);
402 }
403 else if (out_type == TYPE_EVENT)
404 {
405 port_clear_buffer (self->midi_out);
406 }
407
408 for (j = 0; j < STRIP_SIZE; j++)
409 {
410 plugin = self->inserts[j];
411 if (plugin)
412 plugin_prepare_process (plugin);
413 plugin = self->midi_fx[j];
414 if (plugin)
415 plugin_prepare_process (plugin);
416 }
417 if (self->instrument)
418 plugin_prepare_process (self->instrument);
419
420 for (int i = 0; i < STRIP_SIZE; i++)
421 {
422 channel_send_prepare_process (self->sends[i]);
423 }
424
425 if (tr->in_signal_type == TYPE_EVENT)
426 {
427 #ifdef HAVE_RTMIDI
428 /* extract the midi events from the ring
429 * buffer */
430 if (midi_backend_is_rtmidi (
431 AUDIO_ENGINE->midi_backend))
432 {
433 port_prepare_rtmidi_events (
434 tr->processor->midi_in);
435 }
436 #endif
437
438 /* copy the cached MIDI events to the
439 * MIDI events in the MIDI in port */
440 midi_events_dequeue (
441 tr->processor->midi_in->midi_events);
442 }
443 }
444
445 void
channel_init_loaded(Channel * self,Track * track)446 channel_init_loaded (
447 Channel * self,
448 Track * track)
449 {
450 g_debug ("initing channel");
451
452 self->track = track;
453 self->magic = CHANNEL_MAGIC;
454
455 /* fader */
456 self->prefader->track = track;
457 self->fader->track = track;
458
459 fader_init_loaded (
460 self->prefader, track, NULL, NULL);
461 fader_init_loaded (
462 self->fader, track, NULL, NULL);
463
464 PortType out_type =
465 track->out_signal_type;
466
467 switch (out_type)
468 {
469 case TYPE_EVENT:
470 self->midi_out->midi_events =
471 midi_events_new ();
472 break;
473 case TYPE_AUDIO:
474 /* make sure master is expoed to backend */
475 if (track->type == TRACK_TYPE_MASTER)
476 {
477 self->stereo_out->l->exposed_to_backend =
478 true;
479 self->stereo_out->r->exposed_to_backend =
480 true;
481 }
482 break;
483 default:
484 break;
485 }
486
487 #define INIT_PLUGIN(pl,_slot,_slot_type) \
488 if (pl) \
489 { \
490 pl->id.track_name_hash = \
491 track_get_name_hash (self->track); \
492 pl->id.slot = _slot; \
493 pl->id.slot_type = _slot_type; \
494 plugin_init_loaded ( \
495 pl, self->track, NULL); \
496 }
497
498 /* init plugins */
499 Plugin * pl;
500 for (int i = 0; i < STRIP_SIZE; i++)
501 {
502 pl = self->inserts[i];
503 INIT_PLUGIN (pl, i, PLUGIN_SLOT_INSERT);
504 pl = self->midi_fx[i];
505 INIT_PLUGIN (pl, i, PLUGIN_SLOT_MIDI_FX);
506 }
507 if (self->instrument)
508 {
509 pl = self->instrument;
510 INIT_PLUGIN (pl, -1, PLUGIN_SLOT_INSTRUMENT);
511 }
512
513 #undef INIT_PLUGIN
514
515 /* init sends */
516 for (int i = 0; i < STRIP_SIZE; i++)
517 {
518 channel_send_init_loaded (
519 self->sends[i], self->track);
520 }
521 }
522
523 void
channel_set_magic(Channel * self)524 channel_set_magic (
525 Channel * self)
526 {
527 Plugin * plugins[120];
528 int num_plugins =
529 channel_get_plugins (self, plugins);
530
531 for (int i = 0; i < num_plugins; i++)
532 {
533 Plugin * pl = plugins[i];
534 pl->magic = PLUGIN_MAGIC;
535 }
536 }
537
538 /**
539 * Exposes the channel's ports to the backend.
540 */
541 void
channel_expose_ports_to_backend(Channel * ch)542 channel_expose_ports_to_backend (
543 Channel * ch)
544 {
545 Track * tr = channel_get_track (ch);
546
547 /* skip if auditioner */
548 if (track_is_auditioner (tr))
549 return;
550
551 g_message ("%s: %s", __func__, tr->name);
552
553 if (tr->in_signal_type ==
554 TYPE_AUDIO)
555 {
556 port_set_expose_to_backend (
557 tr->processor->stereo_in->l , true);
558 port_set_expose_to_backend (
559 tr->processor->stereo_in->r , true);
560 }
561 if (tr->in_signal_type ==
562 TYPE_EVENT)
563 {
564 port_set_expose_to_backend (
565 tr->processor->midi_in , true);
566 }
567 if (tr->out_signal_type ==
568 TYPE_AUDIO)
569 {
570 port_set_expose_to_backend (
571 ch->stereo_out->l , true);
572 port_set_expose_to_backend (
573 ch->stereo_out->r , true);
574 }
575 if (tr->out_signal_type ==
576 TYPE_EVENT)
577 {
578 port_set_expose_to_backend (
579 ch->midi_out , true);
580 }
581 }
582
583 /**
584 * Called when the input has changed for Midi,
585 * Instrument or Audio tracks.
586 */
587 void
channel_reconnect_ext_input_ports(Channel * self)588 channel_reconnect_ext_input_ports (
589 Channel * self)
590 {
591 Track * track = channel_get_track (self);
592 g_return_if_fail (IS_TRACK_AND_NONNULL (track));
593
594 /* skip if auditioner track */
595 if (track_is_auditioner (track))
596 return;
597
598 g_return_if_fail (
599 channel_is_in_active_project (self));
600
601 if (track->type == TRACK_TYPE_INSTRUMENT ||
602 track->type == TRACK_TYPE_MIDI)
603 {
604 Port * midi_in = track->processor->midi_in;
605
606 /* if the project was loaded with another
607 * backend, the port might not be exposed
608 * yet, so expose it */
609 port_set_expose_to_backend (midi_in, 1);
610
611 /* disconnect all connections to hardware */
612 port_disconnect_hw_inputs (midi_in);
613
614 if (self->all_midi_ins)
615 {
616 for (int i = 0;
617 i <
618 HW_IN_PROCESSOR->
619 num_selected_midi_ports;
620 i++)
621 {
622 char * port_id =
623 HW_IN_PROCESSOR->
624 selected_midi_ports[i];
625 Port * source =
626 hardware_processor_find_port (
627 HW_IN_PROCESSOR, port_id);
628 if (!source)
629 {
630 g_message (
631 "port for %s not found",
632 port_id);
633 continue;
634 }
635 port_connections_manager_ensure_connect (
636 PORT_CONNECTIONS_MGR,
637 &source->id, &midi_in->id,
638 1.f, F_LOCKED, F_ENABLE);
639 }
640 }
641 else
642 {
643 for (int i = 0;
644 i < self->num_ext_midi_ins; i++)
645 {
646 char * port_id =
647 ext_port_get_id (
648 self->ext_midi_ins[i]);
649 Port * source =
650 hardware_processor_find_port (
651 HW_IN_PROCESSOR, port_id);
652 if (!source)
653 {
654 g_message (
655 "port for %s not found",
656 port_id);
657 g_free (port_id);
658 continue;
659 }
660 g_free (port_id);
661 port_connections_manager_ensure_connect (
662 PORT_CONNECTIONS_MGR,
663 &source->id, &midi_in->id,
664 1.f, F_LOCKED, F_ENABLE);
665 }
666 }
667 }
668 else if (track->type == TRACK_TYPE_AUDIO)
669 {
670 /* if the project was loaded with another
671 * backend, the port might not be exposed
672 * yet, so expose it */
673 Port * l =
674 track->processor->stereo_in->l;
675 Port * r =
676 track->processor->stereo_in->r;
677 port_set_expose_to_backend (l, true);
678 port_set_expose_to_backend (r, true);
679
680 /* disconnect all connections to hardware */
681 port_disconnect_hw_inputs (l);
682 port_disconnect_hw_inputs (r);
683
684 for (int i = 0;
685 i < self->num_ext_stereo_l_ins; i++)
686 {
687 char * port_id =
688 ext_port_get_id (
689 self->ext_stereo_l_ins[i]);
690 Port * source =
691 hardware_processor_find_port (
692 HW_IN_PROCESSOR, port_id);
693 if (!source)
694 {
695 g_warning (
696 "port for %s not found",
697 port_id);
698 g_free (port_id);
699 continue;
700 }
701 g_free (port_id);
702 port_connections_manager_ensure_connect (
703 PORT_CONNECTIONS_MGR,
704 &source->id, &l->id,
705 1.f, F_LOCKED, F_ENABLE);
706 }
707 for (int i = 0;
708 i < self->num_ext_stereo_r_ins; i++)
709 {
710 char * port_id =
711 ext_port_get_id (
712 self->ext_stereo_r_ins[i]);
713 Port * source =
714 hardware_processor_find_port (
715 HW_IN_PROCESSOR, port_id);
716 if (!source)
717 {
718 g_warning (
719 "port for %s not found",
720 port_id);
721 g_free (port_id);
722 continue;
723 }
724 g_free (port_id);
725 port_connections_manager_ensure_connect (
726 PORT_CONNECTIONS_MGR,
727 &source->id, &r->id,
728 1.f, F_LOCKED, F_ENABLE);
729 }
730 }
731 }
732
733 /**
734 * Adds to (or subtracts from) the pan.
735 */
736 void
channel_add_balance_control(void * _channel,float pan)737 channel_add_balance_control (
738 void * _channel, float pan)
739 {
740 Channel * channel = (Channel *) _channel;
741
742 port_set_control_value (
743 channel->fader->balance,
744 CLAMP (
745 channel->fader->balance->control + pan,
746 0.f, 1.f),
747 0, 0);
748 }
749
750
751 /**
752 * Sets fader to 0.0.
753 */
754 void
channel_reset_fader(Channel * self,bool fire_events)755 channel_reset_fader (
756 Channel * self,
757 bool fire_events)
758 {
759 fader_set_amp (self->fader, 1.0f);
760
761 if (fire_events)
762 {
763 EVENTS_PUSH (
764 ET_CHANNEL_FADER_VAL_CHANGED, self);
765 }
766 }
767
768 /**
769 * Gets whether mono compatibility is enabled.
770 */
771 bool
channel_get_mono_compat_enabled(Channel * self)772 channel_get_mono_compat_enabled (
773 Channel * self)
774 {
775 return
776 fader_get_mono_compat_enabled (self->fader);
777 }
778
779 /**
780 * Sets whether mono compatibility is enabled.
781 */
782 void
channel_set_mono_compat_enabled(Channel * self,bool enabled,bool fire_events)783 channel_set_mono_compat_enabled (
784 Channel * self,
785 bool enabled,
786 bool fire_events)
787 {
788 fader_set_mono_compat_enabled (
789 self->fader, enabled, fire_events);
790 }
791
792 static void
channel_connect_plugins(Channel * self)793 channel_connect_plugins (
794 Channel * self)
795 {
796 g_return_if_fail (
797 channel_is_in_active_project (self));
798
799 for (int i = 0; i < 3; i++)
800 {
801 PluginSlotType slot_type;
802 for (int j = 0; j < STRIP_SIZE; j++)
803 {
804 Plugin * plugin = NULL;
805 int slot = j;
806 if (i == 0)
807 {
808 slot_type = PLUGIN_SLOT_MIDI_FX;
809 plugin = self->midi_fx[j];
810 }
811 else if (i == 1)
812 {
813 slot_type = PLUGIN_SLOT_INSTRUMENT;
814 plugin = self->instrument;
815 }
816 else
817 {
818 slot_type = PLUGIN_SLOT_INSERT;
819 plugin = self->inserts[j];
820 }
821 if (!plugin)
822 continue;
823
824 if (!plugin->instantiated
825 && !plugin->instantiation_failed)
826 {
827 /* TODO handle error */
828 plugin_instantiate (
829 plugin, NULL, NULL);
830 }
831
832 Plugin ** prev_plugins = NULL;
833 switch (slot_type)
834 {
835 case PLUGIN_SLOT_INSERT:
836 prev_plugins = self->inserts;
837 break;
838 case PLUGIN_SLOT_MIDI_FX:
839 prev_plugins = self->midi_fx;
840 break;
841 case PLUGIN_SLOT_INSTRUMENT:
842 prev_plugins = self->midi_fx;
843 break;
844 default:
845 g_return_if_reached ();
846 }
847 Plugin ** next_plugins = NULL;
848 switch (slot_type)
849 {
850 case PLUGIN_SLOT_INSERT:
851 next_plugins = self->inserts;
852 break;
853 case PLUGIN_SLOT_MIDI_FX:
854 next_plugins = self->midi_fx;
855 break;
856 case PLUGIN_SLOT_INSTRUMENT:
857 next_plugins = self->inserts;
858 break;
859 default:
860 g_return_if_reached ();
861 }
862
863 Plugin * next_pl = NULL;
864 for (int k =
865 (slot_type == PLUGIN_SLOT_INSTRUMENT ?
866 0 : slot + 1); k < STRIP_SIZE; k++)
867 {
868 next_pl = next_plugins[k];
869 if (next_pl)
870 break;
871 }
872 if (!next_pl &&
873 slot_type == PLUGIN_SLOT_MIDI_FX)
874 {
875 if (self->instrument)
876 next_pl = self->instrument;
877 else
878 {
879 for (int k = 0; k < STRIP_SIZE; k++)
880 {
881 next_pl = self->inserts[k];
882 if (next_pl)
883 break;
884 }
885 }
886 }
887
888 Plugin * prev_pl = NULL;
889 if (slot_type != PLUGIN_SLOT_INSTRUMENT)
890 {
891 for (int k = slot - 1; k >= 0; k--)
892 {
893 prev_pl = prev_plugins[k];
894 if (prev_pl)
895 break;
896 }
897 }
898 if (!prev_pl &&
899 slot_type == PLUGIN_SLOT_INSERT)
900 {
901 if (self->instrument)
902 prev_pl = self->instrument;
903 else
904 {
905 for (int k = STRIP_SIZE - 1; k >= 0; k--)
906 {
907 prev_pl = self->midi_fx[k];
908 if (prev_pl)
909 break;
910 }
911 }
912 }
913
914 if (prev_pl
915 && !prev_pl->instantiated
916 && !prev_pl->instantiation_failed)
917 {
918 plugin_instantiate (
919 prev_pl, NULL, NULL);
920 }
921 if (next_pl
922 && !next_pl->instantiated
923 && !next_pl->instantiation_failed)
924 {
925 plugin_instantiate (
926 next_pl, NULL, NULL);
927 }
928
929 if (!prev_pl && !next_pl)
930 {
931 connect_no_prev_no_next (
932 self, plugin);
933 }
934 else if (!prev_pl && next_pl)
935 {
936 connect_no_prev_next (
937 self, plugin, next_pl);
938 }
939 else if (prev_pl && !next_pl)
940 {
941 connect_prev_no_next (
942 self, prev_pl, plugin);
943 }
944 else if (prev_pl && next_pl)
945 {
946 connect_prev_next (
947 self, prev_pl, plugin, next_pl);
948 }
949
950 } /* end for each slot */
951
952 } /* end for each slot type */
953 }
954
955 /**
956 * Connects the channel's ports.
957 *
958 * This should only be called on project tracks.
959 */
960 void
channel_connect(Channel * ch)961 channel_connect (
962 Channel * ch)
963 {
964 Track * tr = channel_get_track (ch);
965 g_return_if_fail (tr);
966
967 g_return_if_fail (
968 track_is_in_active_project (tr)
969 || track_is_auditioner (tr));
970
971 g_message ("connecting channel...");
972
973 /* set default output */
974 if (tr->type == TRACK_TYPE_MASTER
975 && !track_is_auditioner (tr))
976 {
977 ch->output_name_hash = 0;
978 ch->has_output = 0;
979 port_connections_manager_ensure_connect (
980 PORT_CONNECTIONS_MGR,
981 &ch->stereo_out->l->id,
982 &MONITOR_FADER->stereo_in->l->id,
983 1.f, F_LOCKED, F_ENABLE);
984 port_connections_manager_ensure_connect (
985 PORT_CONNECTIONS_MGR,
986 &ch->stereo_out->r->id,
987 &MONITOR_FADER->stereo_in->r->id,
988 1.f, F_LOCKED, F_ENABLE);
989 }
990
991 if (tr->out_signal_type == TYPE_AUDIO)
992 {
993 /* connect stereo in to stereo out through
994 * fader */
995 port_connections_manager_ensure_connect (
996 PORT_CONNECTIONS_MGR,
997 &ch->prefader->stereo_out->l->id,
998 &ch->fader->stereo_in->l->id,
999 1.f, F_LOCKED, F_ENABLE);
1000 port_connections_manager_ensure_connect (
1001 PORT_CONNECTIONS_MGR,
1002 &ch->prefader->stereo_out->r->id,
1003 &ch->fader->stereo_in->r->id,
1004 1.f, F_LOCKED, F_ENABLE);
1005 port_connections_manager_ensure_connect (
1006 PORT_CONNECTIONS_MGR,
1007 &ch->fader->stereo_out->l->id,
1008 &ch->stereo_out->l->id,
1009 1.f, F_LOCKED, F_ENABLE);
1010 port_connections_manager_ensure_connect (
1011 PORT_CONNECTIONS_MGR,
1012 &ch->fader->stereo_out->r->id,
1013 &ch->stereo_out->r->id,
1014 1.f, F_LOCKED, F_ENABLE);
1015 }
1016 else if (tr->out_signal_type == TYPE_EVENT)
1017 {
1018 port_connections_manager_ensure_connect (
1019 PORT_CONNECTIONS_MGR,
1020 &ch->prefader->midi_out->id,
1021 &ch->fader->midi_in->id,
1022 1.f, F_LOCKED, F_ENABLE);
1023 port_connections_manager_ensure_connect (
1024 PORT_CONNECTIONS_MGR,
1025 &ch->fader->midi_out->id,
1026 &ch->midi_out->id,
1027 1.f, F_LOCKED, F_ENABLE);
1028 }
1029
1030 /** Connect MIDI in and piano roll to MIDI
1031 * out. */
1032 track_processor_connect_to_prefader (
1033 tr->processor);
1034
1035 /* connect plugins */
1036 channel_connect_plugins (ch);
1037
1038 /* expose ports to backend */
1039 if (AUDIO_ENGINE && AUDIO_ENGINE->setup)
1040 {
1041 channel_expose_ports_to_backend (ch);
1042 }
1043
1044 /* connect sends */
1045 for (int i = 0; i < STRIP_SIZE; i++)
1046 {
1047 ChannelSend * send = ch->sends[i];
1048 channel_send_connect_to_owner (send);
1049 }
1050
1051 /* connect the designated midi inputs */
1052 channel_reconnect_ext_input_ports (ch);
1053
1054 g_message ("done connecting channel");
1055 }
1056
1057 Track *
channel_get_track(Channel * self)1058 channel_get_track (
1059 Channel * self)
1060 {
1061 if (G_LIKELY (self->track))
1062 return self->track;
1063 else
1064 {
1065 g_return_val_if_fail (
1066 self->track_pos < TRACKLIST->num_tracks,
1067 NULL);
1068 Track * track =
1069 TRACKLIST->tracks[self->track_pos];
1070 g_return_val_if_fail (track, NULL);
1071 self->track = track;
1072
1073 return track;
1074 }
1075 }
1076
1077 Track *
channel_get_output_track(Channel * self)1078 channel_get_output_track (
1079 Channel * self)
1080 {
1081 if (!self->has_output)
1082 return NULL;
1083
1084 Track * track = channel_get_track (self);
1085 g_return_val_if_fail (track, NULL);
1086 Tracklist * tracklist =
1087 track_get_tracklist (track);
1088 Track * output_track =
1089 tracklist_find_track_by_name_hash (
1090 tracklist, self->output_name_hash);
1091 g_return_val_if_fail (
1092 output_track && track != output_track, NULL);
1093
1094 return output_track;
1095 }
1096
1097 /**
1098 * Appends all channel ports and optionally
1099 * plugin ports to the array.
1100 */
1101 void
channel_append_ports(Channel * self,GPtrArray * ports,bool include_plugins)1102 channel_append_ports (
1103 Channel * self,
1104 GPtrArray * ports,
1105 bool include_plugins)
1106 {
1107 g_return_if_fail (self->track);
1108
1109 #define _ADD(port) \
1110 g_warn_if_fail (port); \
1111 g_ptr_array_add (ports, port)
1112
1113 /* add channel ports */
1114 if (self->track->out_signal_type == TYPE_AUDIO)
1115 {
1116 _ADD (self->stereo_out->l);
1117 _ADD (self->stereo_out->r);
1118
1119 /* add fader ports */
1120 _ADD (self->fader->stereo_in->l);
1121 _ADD (self->fader->stereo_in->r);
1122 _ADD (self->fader->stereo_out->l);
1123 _ADD (self->fader->stereo_out->r);
1124
1125 /* add prefader ports */
1126 _ADD (self->prefader->stereo_in->l);
1127 _ADD (self->prefader->stereo_in->r);
1128 _ADD (self->prefader->stereo_out->l);
1129 _ADD (self->prefader->stereo_out->r);
1130 }
1131 else if (self->track->out_signal_type ==
1132 TYPE_EVENT)
1133 {
1134 _ADD (self->midi_out);
1135
1136 /* add fader ports */
1137 _ADD (self->fader->midi_in);
1138 _ADD (self->fader->midi_out);
1139
1140 /* add prefader ports */
1141 _ADD (self->prefader->midi_in);
1142 _ADD (self->prefader->midi_out);
1143 }
1144
1145 /* add fader amp and balance control */
1146 _ADD (self->prefader->amp);
1147 _ADD (self->prefader->balance);
1148 _ADD (self->prefader->mute);
1149 _ADD (self->prefader->solo);
1150 _ADD (self->prefader->listen);
1151 _ADD (self->prefader->mono_compat_enabled);
1152 _ADD (self->fader->amp);
1153 _ADD (self->fader->balance);
1154 _ADD (self->fader->mute);
1155 _ADD (self->fader->solo);
1156 _ADD (self->fader->listen);
1157 _ADD (self->fader->mono_compat_enabled);
1158
1159 if (include_plugins)
1160 {
1161 #define ADD_PLUGIN_PORTS(x) \
1162 if (x) \
1163 plugin_append_ports (x, ports)
1164
1165 /* add plugin ports */
1166 for (int j = 0; j < STRIP_SIZE; j++)
1167 {
1168 ADD_PLUGIN_PORTS (self->inserts[j]);
1169 ADD_PLUGIN_PORTS (self->midi_fx[j]);
1170 }
1171
1172 ADD_PLUGIN_PORTS (self->instrument);
1173 }
1174
1175 #undef ADD_PLUGIN_PORTS
1176
1177 for (int i = 0; i < STRIP_SIZE; i++)
1178 {
1179 channel_send_append_ports (
1180 self->sends[i], ports);
1181 }
1182 #undef _ADD
1183 }
1184
1185 /**
1186 * Inits the stereo ports of the Channel while
1187 * exposing them to the backend.
1188 *
1189 * This assumes the caller already checked that
1190 * this channel should have the given ports
1191 * enabled.
1192 *
1193 * @param in 1 for input, 0 for output.
1194 * @param loading 1 if loading a channel, 0 if
1195 * new.
1196 */
1197 static void
init_stereo_out_ports(Channel * self,bool loading)1198 init_stereo_out_ports (
1199 Channel * self,
1200 bool loading)
1201 {
1202 if (loading)
1203 {
1204 return;
1205 }
1206
1207 char str[80];
1208 strcpy (str, "Stereo out");
1209
1210 strcat (str, " L");
1211 Port * l =
1212 port_new_with_type_and_owner (
1213 TYPE_AUDIO, FLOW_OUTPUT, str,
1214 PORT_OWNER_TYPE_CHANNEL, self);
1215
1216 str[10] = '\0';
1217 strcat (str, " R");
1218 Port * r =
1219 port_new_with_type_and_owner (
1220 TYPE_AUDIO, FLOW_OUTPUT, str,
1221 PORT_OWNER_TYPE_CHANNEL, self);
1222
1223 self->stereo_out =
1224 stereo_ports_new_from_existing (l, r);
1225 }
1226
1227 /**
1228 * Inits the MIDI In port of the Channel while
1229 * exposing it to JACK.
1230 *
1231 * This assumes the caller already checked that
1232 * this channel should have the given MIDI port
1233 * enabled.
1234 *
1235 * @param in 1 for input, 0 for output.
1236 * @param loading 1 if loading a channel, 0 if
1237 * new.
1238 */
1239 static void
init_midi_port(Channel * self,int loading)1240 init_midi_port (
1241 Channel * self,
1242 int loading)
1243 {
1244 const char * str = "MIDI out";
1245 Port ** port =
1246 &self->midi_out;
1247 PortFlow flow = FLOW_OUTPUT;
1248
1249 *port =
1250 port_new_with_type_and_owner (
1251 TYPE_EVENT, flow, str,
1252 PORT_OWNER_TYPE_CHANNEL, self);
1253 }
1254
1255 /**
1256 * Creates a channel of the given type with the
1257 * given label.
1258 */
1259 Channel *
channel_new(Track * track)1260 channel_new (
1261 Track * track)
1262 {
1263 Channel * self = object_new (Channel);
1264
1265 track->channel = self;
1266 self->schema_version =
1267 CHANNEL_SCHEMA_VERSION;
1268 self->magic = CHANNEL_MAGIC;
1269 self->track_pos = track->pos;
1270 self->track = track;
1271
1272 /* autoconnect to all midi ins and midi chans */
1273 self->all_midi_ins = 1;
1274 self->all_midi_channels = 1;
1275
1276 /* create ports */
1277 switch (track->out_signal_type)
1278 {
1279 case TYPE_AUDIO:
1280 init_stereo_out_ports (self, 0);
1281 break;
1282 case TYPE_EVENT:
1283 init_midi_port (self, 0);
1284 break;
1285 default:
1286 break;
1287 }
1288
1289 FaderType fader_type =
1290 track_get_fader_type (track);
1291 FaderType prefader_type =
1292 track_type_get_prefader_type (track->type);
1293 self->fader =
1294 fader_new (
1295 fader_type, false, track, NULL, NULL);
1296 self->prefader =
1297 fader_new (
1298 prefader_type, true, track, NULL, NULL);
1299
1300 /* init sends */
1301 for (int i = 0; i < STRIP_SIZE; i++)
1302 {
1303 self->sends[i] =
1304 channel_send_new (
1305 track_get_name_hash (track), i, track);
1306 self->sends[i]->track = track;
1307 }
1308
1309 return self;
1310 }
1311
1312 void
channel_set_phase(void * _channel,float phase)1313 channel_set_phase (void * _channel, float phase)
1314 {
1315 Channel * channel = (Channel *) _channel;
1316 channel->fader->phase = phase;
1317
1318 /* FIXME use an event */
1319 /*if (channel->widget)*/
1320 /*gtk_label_set_text (channel->widget->phase_reading,*/
1321 /*g_strdup_printf ("%.1f", phase));*/
1322 }
1323
1324 float
channel_get_phase(void * _channel)1325 channel_get_phase (void * _channel)
1326 {
1327 Channel * channel = (Channel *) _channel;
1328 return channel->fader->phase;
1329 }
1330
1331 void
channel_set_balance_control(void * _channel,float pan)1332 channel_set_balance_control (
1333 void * _channel,
1334 float pan)
1335 {
1336 Channel * channel = (Channel *) _channel;
1337 port_set_control_value (
1338 channel->fader->balance, pan, 0, 0);
1339 }
1340
1341 float
channel_get_balance_control(void * _channel)1342 channel_get_balance_control (
1343 void * _channel)
1344 {
1345 Channel * channel = (Channel *) _channel;
1346 return
1347 port_get_control_value (
1348 channel->fader->balance, 0);
1349 }
1350
1351 static inline void
channel_disconnect_plugin_from_strip(Channel * ch,int pos,Plugin * pl)1352 channel_disconnect_plugin_from_strip (
1353 Channel * ch,
1354 int pos,
1355 Plugin * pl)
1356 {
1357 int i;
1358 PluginSlotType slot_type = pl->id.slot_type;
1359 Plugin ** prev_plugins = NULL;
1360 switch (slot_type)
1361 {
1362 case PLUGIN_SLOT_INSERT:
1363 prev_plugins = ch->inserts;
1364 break;
1365 case PLUGIN_SLOT_MIDI_FX:
1366 prev_plugins = ch->midi_fx;
1367 break;
1368 case PLUGIN_SLOT_INSTRUMENT:
1369 prev_plugins = ch->midi_fx;
1370 break;
1371 default:
1372 g_return_if_reached ();
1373 }
1374 Plugin ** next_plugins = NULL;
1375 switch (slot_type)
1376 {
1377 case PLUGIN_SLOT_INSERT:
1378 next_plugins = ch->inserts;
1379 break;
1380 case PLUGIN_SLOT_MIDI_FX:
1381 next_plugins = ch->midi_fx;
1382 break;
1383 case PLUGIN_SLOT_INSTRUMENT:
1384 next_plugins = ch->inserts;
1385 break;
1386 default:
1387 g_return_if_reached ();
1388 }
1389
1390 Plugin * next_plugin = NULL;
1391 for (i = pos + 1; i < STRIP_SIZE; i++)
1392 {
1393 next_plugin = next_plugins[i];
1394 if (next_plugin)
1395 break;
1396 }
1397 if (!next_plugin &&
1398 slot_type == PLUGIN_SLOT_MIDI_FX)
1399 {
1400 if (ch->instrument)
1401 next_plugin = ch->instrument;
1402 else
1403 {
1404 for (i = 0; i < STRIP_SIZE; i++)
1405 {
1406 next_plugin = ch->inserts[i];
1407 if (next_plugin)
1408 break;
1409 }
1410 }
1411 }
1412
1413 Plugin * prev_plugin = NULL;
1414 for (i = pos - 1; i >= 0; i--)
1415 {
1416 prev_plugin = prev_plugins[i];
1417 if (prev_plugin)
1418 break;
1419 }
1420 if (!prev_plugin &&
1421 slot_type == PLUGIN_SLOT_INSERT)
1422 {
1423 if (ch->instrument)
1424 prev_plugin = ch->instrument;
1425 else
1426 {
1427 for (i = STRIP_SIZE - 1; i >= 0; i--)
1428 {
1429 prev_plugin = ch->midi_fx[i];
1430 if (prev_plugin)
1431 break;
1432 }
1433 }
1434 }
1435
1436 if (!prev_plugin && !next_plugin)
1437 {
1438 disconnect_no_prev_no_next (ch, pl);
1439 }
1440 else if (!prev_plugin && next_plugin)
1441 {
1442 disconnect_no_prev_next (ch, pl, next_plugin);
1443 }
1444 else if (prev_plugin && !next_plugin)
1445 {
1446 disconnect_prev_no_next (ch, prev_plugin, pl);
1447 }
1448 else if (prev_plugin && next_plugin)
1449 {
1450 disconnect_prev_next (
1451 ch, prev_plugin, pl, next_plugin);
1452 }
1453
1454 /* unexpose all JACK ports */
1455 plugin_expose_ports (
1456 pl, F_NOT_EXPOSE, true, true);
1457 }
1458
1459 /**
1460 * Removes a plugin at pos from the channel.
1461 *
1462 * @param moving_plugin Whether or not we are
1463 * moving the plugin.
1464 * @param deleting_plugin Whether or not we are
1465 * deleting the plugin.
1466 * @param deleting_channel If true, the automation
1467 * tracks associated with the plugin are not
1468 * deleted at this time.
1469 * @param recalc_graph Recalculate mixer graph.
1470 */
1471 void
channel_remove_plugin(Channel * channel,PluginSlotType slot_type,int slot,bool moving_plugin,bool deleting_plugin,bool deleting_channel,bool recalc_graph)1472 channel_remove_plugin (
1473 Channel * channel,
1474 PluginSlotType slot_type,
1475 int slot,
1476 bool moving_plugin,
1477 bool deleting_plugin,
1478 bool deleting_channel,
1479 bool recalc_graph)
1480 {
1481 Plugin * plugin = NULL;
1482 switch (slot_type)
1483 {
1484 case PLUGIN_SLOT_INSERT:
1485 plugin = channel->inserts[slot];
1486 break;
1487 case PLUGIN_SLOT_MIDI_FX:
1488 plugin = channel->midi_fx[slot];
1489 break;
1490 case PLUGIN_SLOT_INSTRUMENT:
1491 plugin = channel->instrument;
1492 break;
1493 default:
1494 break;
1495 }
1496 g_return_if_fail (
1497 IS_PLUGIN_AND_NONNULL (plugin));
1498 g_return_if_fail (
1499 plugin->id.track_name_hash ==
1500 track_get_name_hash (channel->track));
1501
1502 Track * track = channel_get_track (channel);
1503 g_return_if_fail (IS_TRACK_AND_NONNULL (track));
1504 g_message (
1505 "Removing %s from %s:%s:%d",
1506 plugin->setting->descr->name, track->name,
1507 plugin_slot_type_strings[slot_type].str, slot);
1508
1509 /* if moving, the move is already handled in
1510 * plugin_move_automation() inside
1511 * plugin_move(). */
1512 if (!moving_plugin)
1513 {
1514 plugin_remove_ats_from_automation_tracklist (
1515 plugin, deleting_plugin,
1516 !deleting_channel && !deleting_plugin);
1517 }
1518
1519 if (channel_is_in_active_project (channel))
1520 channel_disconnect_plugin_from_strip (
1521 channel, slot, plugin);
1522
1523 /* if deleting plugin disconnect the plugin
1524 * entirely */
1525 if (deleting_plugin)
1526 {
1527 if (channel_is_in_active_project (channel)
1528 && plugin_is_selected (plugin))
1529 {
1530 mixer_selections_remove_slot (
1531 MIXER_SELECTIONS, plugin->id.slot,
1532 slot_type, F_PUBLISH_EVENTS);
1533 }
1534
1535 plugin_disconnect (plugin);
1536 object_free_w_func_and_null (
1537 plugin_free, plugin);
1538 }
1539
1540 switch (slot_type)
1541 {
1542 case PLUGIN_SLOT_INSERT:
1543 channel->inserts[slot] = NULL;
1544 break;
1545 case PLUGIN_SLOT_MIDI_FX:
1546 channel->midi_fx[slot] = NULL;
1547 break;
1548 case PLUGIN_SLOT_INSTRUMENT:
1549 channel->instrument = NULL;
1550 break;
1551 default:
1552 g_warn_if_reached ();
1553 break;
1554 }
1555
1556 /* if not deleting plugin (moving, etc.) just
1557 * disconnect its connections to the prev/
1558 * next slot or the channel if first/last */
1559 /*else*/
1560 /*{*/
1561 /*channel_disconnect_plugin_from_strip (*/
1562 /*channel, pos, plugin);*/
1563 /*}*/
1564
1565 if (track_is_in_active_project (track)
1566 && !track->disconnecting
1567 /* only verify if we are deleting the plugin.
1568 * if the plugin is moved to another slot
1569 * this check fails because the port
1570 * identifiers in the automation tracks are
1571 * already updated to point to the next
1572 * slot and the plugin is not found there
1573 * yet */
1574 && deleting_plugin
1575 && !moving_plugin)
1576 {
1577 track_validate (channel->track);
1578 }
1579
1580 if (recalc_graph)
1581 router_recalc_graph (ROUTER, F_NOT_SOFT);
1582 }
1583
1584 /**
1585 * Adds given plugin to given position in the
1586 * strip.
1587 *
1588 * The plugin must be already instantiated at this
1589 * point.
1590 *
1591 * @param channel The Channel.
1592 * @param slot The position in the strip starting
1593 * from 0.
1594 * @param plugin The plugin to add.
1595 * @param confirm Confirm if an existing plugin
1596 * will be overwritten.
1597 * @param moving_plugin Whether or not we are
1598 * moving the plugin.
1599 * @param gen_automatables Generatate plugin
1600 * automatables.
1601 * To be used when creating a new plugin only.
1602 * @param recalc_graph Recalculate mixer graph.
1603 * @param pub_events Publish events.
1604 *
1605 * @return true if plugin added, false if not.
1606 */
1607 bool
channel_add_plugin(Channel * self,PluginSlotType slot_type,int slot,Plugin * plugin,bool confirm,bool moving_plugin,bool gen_automatables,bool recalc_graph,bool pub_events)1608 channel_add_plugin (
1609 Channel * self,
1610 PluginSlotType slot_type,
1611 int slot,
1612 Plugin * plugin,
1613 bool confirm,
1614 bool moving_plugin,
1615 bool gen_automatables,
1616 bool recalc_graph,
1617 bool pub_events)
1618 {
1619 g_return_val_if_fail (
1620 plugin_identifier_validate_slot_type_slot_combo (
1621 slot_type, slot),
1622 false);
1623
1624 Track * track = channel_get_track (self);
1625 g_return_val_if_fail (
1626 IS_TRACK_AND_NONNULL (track), 0);
1627 bool prev_enabled = track->enabled;
1628 track->enabled = false;
1629
1630 Plugin ** plugins = NULL;
1631 switch (slot_type)
1632 {
1633 case PLUGIN_SLOT_INSERT:
1634 plugins = self->inserts;
1635 break;
1636 case PLUGIN_SLOT_MIDI_FX:
1637 plugins = self->midi_fx;
1638 break;
1639 case PLUGIN_SLOT_INSTRUMENT:
1640 break;
1641 default:
1642 g_return_val_if_reached (0);
1643 }
1644
1645 Plugin * existing_pl = NULL;
1646 if (slot_type == PLUGIN_SLOT_INSTRUMENT)
1647 existing_pl = self->instrument;
1648 else
1649 existing_pl = plugins[slot];
1650
1651 if (existing_pl)
1652 {
1653 g_message (
1654 "existing plugin exists at %s:%d",
1655 track->name, slot);
1656 }
1657 /* TODO move confirmation to widget */
1658 #if 0
1659 /* confirm if another plugin exists */
1660 if (confirm && existing_pl && ZRYTHM_HAVE_UI)
1661 {
1662 GtkDialog * dialog =
1663 dialogs_get_overwrite_plugin_dialog (
1664 GTK_WINDOW (MAIN_WINDOW));
1665 int result =
1666 gtk_dialog_run (dialog);
1667 gtk_widget_destroy (GTK_WIDGET (dialog));
1668
1669 /* do nothing if not accepted */
1670 if (result != GTK_RESPONSE_ACCEPT)
1671 return 0;
1672 }
1673 #endif
1674
1675 /* free current plugin */
1676 if (existing_pl)
1677 {
1678 channel_remove_plugin (
1679 self, slot_type, slot,
1680 moving_plugin, F_DELETING_PLUGIN,
1681 F_NOT_DELETING_CHANNEL,
1682 F_NO_RECALC_GRAPH);
1683 }
1684
1685 g_message (
1686 "Inserting %s %s at %s:%s:%d",
1687 plugin_slot_type_to_string (slot_type),
1688 plugin->setting->descr->name, track->name,
1689 plugin_slot_type_strings[slot_type].str, slot);
1690 if (slot_type == PLUGIN_SLOT_INSTRUMENT)
1691 {
1692 self->instrument = plugin;
1693 }
1694 else
1695 {
1696 plugins[slot] = plugin;
1697 }
1698 plugin->track = track;
1699 plugin_set_track_and_slot (
1700 plugin,
1701 track_get_name_hash (self->track),
1702 slot_type, slot);
1703 g_return_val_if_fail (plugin->track, false);
1704
1705 Plugin ** prev_plugins = NULL;
1706 switch (slot_type)
1707 {
1708 case PLUGIN_SLOT_INSERT:
1709 prev_plugins = self->inserts;
1710 break;
1711 case PLUGIN_SLOT_MIDI_FX:
1712 prev_plugins = self->midi_fx;
1713 break;
1714 case PLUGIN_SLOT_INSTRUMENT:
1715 prev_plugins = self->midi_fx;
1716 break;
1717 default:
1718 g_return_val_if_reached (0);
1719 }
1720 Plugin ** next_plugins = NULL;
1721 switch (slot_type)
1722 {
1723 case PLUGIN_SLOT_INSERT:
1724 next_plugins = self->inserts;
1725 break;
1726 case PLUGIN_SLOT_MIDI_FX:
1727 next_plugins = self->midi_fx;
1728 break;
1729 case PLUGIN_SLOT_INSTRUMENT:
1730 next_plugins = self->inserts;
1731 break;
1732 default:
1733 g_return_val_if_reached (0);
1734 }
1735
1736 Plugin * next_pl = NULL;
1737 for (int i =
1738 (slot_type == PLUGIN_SLOT_INSTRUMENT ?
1739 0 : slot + 1); i < STRIP_SIZE; i++)
1740 {
1741 next_pl = next_plugins[i];
1742 if (next_pl)
1743 break;
1744 }
1745 if (!next_pl &&
1746 slot_type == PLUGIN_SLOT_MIDI_FX)
1747 {
1748 if (self->instrument)
1749 next_pl = self->instrument;
1750 else
1751 {
1752 for (int i = 0; i < STRIP_SIZE; i++)
1753 {
1754 next_pl = self->inserts[i];
1755 if (next_pl)
1756 break;
1757 }
1758 }
1759 }
1760
1761 Plugin * prev_pl = NULL;
1762 if (slot_type != PLUGIN_SLOT_INSTRUMENT)
1763 {
1764 for (int i = slot - 1; i >= 0; i--)
1765 {
1766 prev_pl = prev_plugins[i];
1767 if (prev_pl)
1768 break;
1769 }
1770 }
1771 if (!prev_pl &&
1772 slot_type == PLUGIN_SLOT_INSERT)
1773 {
1774 if (self->instrument)
1775 prev_pl = self->instrument;
1776 else
1777 {
1778 for (int i = STRIP_SIZE - 1; i >= 0; i--)
1779 {
1780 prev_pl = self->midi_fx[i];
1781 if (prev_pl)
1782 break;
1783 }
1784 }
1785 }
1786
1787 /* ------------------------------------------
1788 * connect ports
1789 * ------------------------------------------ */
1790
1791 g_debug (
1792 "%s: connecting plugin ports...", __func__);
1793
1794 if (track_is_in_active_project (track))
1795 {
1796 channel_connect_plugins (self);
1797 }
1798
1799 track->enabled = prev_enabled;
1800
1801 if (gen_automatables)
1802 {
1803 plugin_generate_automation_tracks (
1804 plugin, track);
1805 }
1806
1807 if (pub_events)
1808 {
1809 EVENTS_PUSH (ET_PLUGIN_ADDED, plugin);
1810 }
1811
1812 if (recalc_graph)
1813 {
1814 router_recalc_graph (ROUTER, F_NOT_SOFT);
1815 }
1816
1817 return 1;
1818 }
1819
1820 /**
1821 * Updates the track name hash in the channel and
1822 * all related ports and identifiers.
1823 */
1824 NONNULL
1825 void
channel_update_track_name_hash(Channel * self,unsigned int old_name_hash,unsigned int new_name_hash)1826 channel_update_track_name_hash (
1827 Channel * self,
1828 unsigned int old_name_hash,
1829 unsigned int new_name_hash)
1830 {
1831 Track * track = self->track;
1832 g_return_if_fail (track);
1833
1834 /* update output */
1835 if (track_is_in_active_project (track)
1836 && self->has_output)
1837 {
1838 Track * out_track =
1839 channel_get_output_track (self);
1840 g_return_if_fail (
1841 IS_TRACK_AND_NONNULL (out_track));
1842 int child_idx =
1843 group_target_track_find_child (
1844 out_track, old_name_hash);
1845 g_return_if_fail (child_idx >= 0);
1846
1847 out_track->children[child_idx] =
1848 new_name_hash;
1849 g_debug (
1850 "%s: setting output of track '%s' to '%s'",
1851 __func__, self->track->name,
1852 out_track->name);
1853 }
1854
1855 for (int i = 0; i < STRIP_SIZE; i++)
1856 {
1857 ChannelSend * send = self->sends[i];
1858 send->track_name_hash = new_name_hash;
1859 }
1860
1861 #define SET_PLUGIN_NAME_HASH(pl) \
1862 if (pl) \
1863 plugin_set_track_name_hash ( \
1864 pl, new_name_hash)
1865
1866 for (int i = 0; i < STRIP_SIZE; i++)
1867 {
1868 SET_PLUGIN_NAME_HASH (self->inserts[i]);
1869 SET_PLUGIN_NAME_HASH (self->midi_fx[i]);
1870 }
1871 SET_PLUGIN_NAME_HASH (self->instrument);
1872 }
1873
1874 /**
1875 * Convenience function to get the automation track
1876 * of the given type for the channel.
1877 */
1878 AutomationTrack *
channel_get_automation_track(Channel * channel,PortFlags port_flags)1879 channel_get_automation_track (
1880 Channel * channel,
1881 PortFlags port_flags)
1882 {
1883 Track * track = channel_get_track (channel);
1884 AutomationTracklist * atl =
1885 track_get_automation_tracklist (track);
1886 for (int i = 0; i < atl->num_ats; i++)
1887 {
1888 AutomationTrack * at = atl->ats[i];
1889
1890 if (at->port_id.flags & port_flags)
1891 return at;
1892 }
1893 return NULL;
1894 }
1895
1896 /**
1897 * Clones the channel recursively.
1898 *
1899 * @note The given track is not cloned.
1900 *
1901 * @param error To be filled if an error occurred.
1902 * @param track The track to use for getting the
1903 * name.
1904 */
1905 Channel *
channel_clone(Channel * ch,Track * track,GError ** error)1906 channel_clone (
1907 Channel * ch,
1908 Track * track,
1909 GError ** error)
1910 {
1911 g_return_val_if_fail (!error || !*error, NULL);
1912
1913 Channel * clone = channel_new (track);
1914
1915 clone->fader->track = clone->track;
1916 clone->prefader->track = clone->track;
1917 fader_copy_values (ch->fader, clone->fader);
1918
1919 clone->has_output = ch->has_output;
1920 clone->output_name_hash = ch->output_name_hash;
1921
1922 for (int i = 0; i < STRIP_SIZE; i++)
1923 {
1924 ChannelSend * src_send = ch->sends[i];
1925 channel_send_copy_values (
1926 clone->sends[i], src_send);
1927 }
1928
1929 #define CLONE_AND_ADD_PL(pl,slot_type,slot) \
1930 { \
1931 GError * err = NULL; \
1932 Plugin * clone_pl = \
1933 plugin_clone (pl, &err); \
1934 if (!clone_pl) \
1935 { \
1936 PROPAGATE_PREFIXED_ERROR ( \
1937 error, err, "%s", \
1938 _("Failed to clone plugin")); \
1939 object_free_w_func_and_null ( \
1940 channel_free, clone); \
1941 return NULL; \
1942 } \
1943 channel_add_plugin ( \
1944 clone, slot_type, \
1945 slot, clone_pl, F_NO_CONFIRM, \
1946 F_NOT_MOVING_PLUGIN, \
1947 F_GEN_AUTOMATABLES, F_NO_RECALC_GRAPH, \
1948 F_NO_PUBLISH_EVENTS); \
1949 }
1950
1951 /* copy plugins */
1952 for (int i = 0; i < STRIP_SIZE; i++)
1953 {
1954 if (ch->inserts[i])
1955 {
1956 CLONE_AND_ADD_PL (
1957 ch->inserts[i], PLUGIN_SLOT_INSERT, i);
1958 }
1959 }
1960 for (int i = 0; i < STRIP_SIZE; i++)
1961 {
1962 if (ch->midi_fx[i])
1963 {
1964 CLONE_AND_ADD_PL (
1965 ch->midi_fx[i], PLUGIN_SLOT_MIDI_FX,
1966 i);
1967 }
1968 }
1969 if (ch->instrument)
1970 {
1971 CLONE_AND_ADD_PL (
1972 ch->instrument, PLUGIN_SLOT_INSTRUMENT,
1973 -1);
1974 }
1975
1976 #undef CLONE_AND_ADD_PL
1977
1978 /* copy port connection info (including
1979 * plugins) */
1980 GPtrArray * ports = g_ptr_array_new ();
1981 channel_append_ports (ch, ports, true);
1982 GPtrArray * ports_clone = g_ptr_array_new ();
1983 channel_append_ports (ch, ports_clone, true);
1984 g_return_val_if_fail (
1985 ports->len == ports_clone->len, NULL);
1986 for (size_t i = 0; i < ports->len; i++)
1987 {
1988 Port * port = g_ptr_array_index (ports, i);
1989 Port * clone_port =
1990 g_ptr_array_index (ports_clone, i);
1991 g_return_val_if_fail (
1992 port_identifier_is_equal (
1993 &port->id, &clone_port->id),
1994 NULL);
1995 port_copy_values (clone_port, port);
1996 }
1997 g_ptr_array_unref (ports);
1998 g_ptr_array_unref (ports_clone);
1999
2000 return clone;
2001 }
2002
2003 /**
2004 * Selects/deselects all plugins in the given slot
2005 * type.
2006 */
2007 void
channel_select_all(Channel * self,PluginSlotType type,bool select)2008 channel_select_all (
2009 Channel * self,
2010 PluginSlotType type,
2011 bool select)
2012 {
2013 mixer_selections_clear (
2014 MIXER_SELECTIONS, F_PUBLISH_EVENTS);
2015 if (!select)
2016 return;
2017
2018 switch (type)
2019 {
2020 case PLUGIN_SLOT_INSERT:
2021 for (int i = 0; i < STRIP_SIZE; i++)
2022 {
2023 if (self->inserts[i])
2024 {
2025 plugin_select (
2026 self->inserts[i], F_SELECT,
2027 F_NOT_EXCLUSIVE);
2028 }
2029 }
2030 break;
2031 case PLUGIN_SLOT_MIDI_FX:
2032 for (int i = 0; i < STRIP_SIZE; i++)
2033 {
2034 if (self->midi_fx[i])
2035 {
2036 plugin_select (
2037 self->midi_fx[i], F_SELECT,
2038 F_NOT_EXCLUSIVE);
2039 }
2040 }
2041 break;
2042 default:
2043 g_warning ("not implemented");
2044 break;
2045 }
2046 }
2047
2048 int
channel_get_plugins(Channel * ch,Plugin ** pls)2049 channel_get_plugins (
2050 Channel * ch,
2051 Plugin ** pls)
2052 {
2053 int size = 0;
2054 for (int i = 0; i < STRIP_SIZE; i++)
2055 {
2056 if (ch->inserts[i])
2057 {
2058 pls[size++] = ch->inserts[i];
2059 }
2060 }
2061 for (int i = 0; i < STRIP_SIZE; i++)
2062 {
2063 if (ch->midi_fx[i])
2064 {
2065 pls[size++] = ch->midi_fx[i];
2066 }
2067 }
2068 if (ch->instrument)
2069 {
2070 pls[size++] = ch->instrument;
2071 }
2072
2073 return size;
2074 }
2075
2076 /**
2077 * Disconnects the channel from the processing
2078 * chain.
2079 *
2080 * This should be called immediately when the
2081 * channel is getting deleted, and channel_free
2082 * should be designed to be called later after
2083 * an arbitrary delay.
2084 *
2085 * @param remove_pl Remove the Plugin from the
2086 * Channel. Useful when deleting the channel.
2087 * @param recalc_graph Recalculate mixer graph.
2088 */
2089 void
channel_disconnect(Channel * self,bool remove_pl)2090 channel_disconnect (
2091 Channel * self,
2092 bool remove_pl)
2093 {
2094 if (remove_pl)
2095 {
2096 FOREACH_STRIP
2097 {
2098 if (self->inserts[i])
2099 {
2100 channel_remove_plugin (
2101 self,
2102 PLUGIN_SLOT_INSERT,
2103 i, F_NOT_MOVING_PLUGIN,
2104 remove_pl, false,
2105 F_NO_RECALC_GRAPH);
2106 }
2107 if (self->midi_fx[i])
2108 {
2109 channel_remove_plugin (
2110 self,
2111 PLUGIN_SLOT_MIDI_FX,
2112 i, F_NOT_MOVING_PLUGIN,
2113 remove_pl, false,
2114 F_NO_RECALC_GRAPH);
2115 }
2116 }
2117 if (self->instrument)
2118 {
2119 channel_remove_plugin (
2120 self,
2121 PLUGIN_SLOT_INSTRUMENT,
2122 0, F_NOT_MOVING_PLUGIN,
2123 remove_pl, false,
2124 F_NO_RECALC_GRAPH);
2125 }
2126 }
2127
2128 /* disconnect from output */
2129 if (channel_is_in_active_project (self) &&
2130 self->has_output)
2131 {
2132 Track * out_track =
2133 channel_get_output_track (self);
2134 g_return_if_fail (
2135 IS_TRACK_AND_NONNULL (out_track));
2136 group_target_track_remove_child (
2137 out_track,
2138 track_get_name_hash (self->track),
2139 F_DISCONNECT,
2140 F_NO_RECALC_GRAPH, F_NO_PUBLISH_EVENTS);
2141 }
2142
2143 /* disconnect fader/prefader */
2144 fader_disconnect_all (self->prefader);
2145 fader_disconnect_all (self->fader);
2146
2147 /* disconnect all ports */
2148 GPtrArray * ports = g_ptr_array_new ();
2149 channel_append_ports (self, ports, true);
2150 for (size_t i = 0; i < ports->len; i++)
2151 {
2152 Port * port = g_ptr_array_index (ports, i);
2153 if (!IS_PORT (port)
2154 ||
2155 port_is_in_active_project (port) !=
2156 track_is_in_active_project (
2157 self->track))
2158 {
2159 g_critical ("invalid port");
2160 g_ptr_array_unref (ports);
2161 return;
2162 }
2163
2164 port_disconnect_all (port);
2165 }
2166 g_ptr_array_unref (ports);
2167 }
2168
2169 /**
2170 * Frees the channel.
2171 *
2172 * Channels should never be free'd by themselves
2173 * in normal circumstances. Use track_free to
2174 * free them.
2175 */
2176 void
channel_free(Channel * self)2177 channel_free (Channel * self)
2178 {
2179 object_free_w_func_and_null (
2180 fader_free, self->prefader);
2181 object_free_w_func_and_null (
2182 fader_free, self->fader);
2183
2184 object_free_w_func_and_null (
2185 stereo_ports_free, self->stereo_out);
2186 object_free_w_func_and_null (
2187 port_free, self->midi_out);
2188
2189 for (int i = 0; i < STRIP_SIZE; i++)
2190 {
2191 ChannelSend * send = self->sends[i];
2192 object_free_w_func_and_null (
2193 channel_send_free, send);
2194 }
2195
2196 if (GTK_IS_WIDGET (self->widget))
2197 {
2198 gtk_widget_destroy (
2199 GTK_WIDGET (self->widget));
2200 }
2201
2202 object_zero_and_free (self);
2203 }
2204
2205