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