1 /*
2  * Copyright (C) 2018-2021 Alexandros Theodotou <alex at 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 <stdlib.h>
21 
22 #include "actions/tracklist_selections.h"
23 #include "actions/undo_manager.h"
24 #include "audio/audio_group_track.h"
25 #include "audio/audio_region.h"
26 #include "audio/audio_track.h"
27 #include "audio/automation_point.h"
28 #include "audio/automation_track.h"
29 #include "audio/audio_bus_track.h"
30 #include "audio/channel.h"
31 #include "audio/chord_track.h"
32 #include "audio/control_port.h"
33 #include "audio/exporter.h"
34 #include "audio/foldable_track.h"
35 #include "audio/group_target_track.h"
36 #include "audio/instrument_track.h"
37 #include "audio/marker_track.h"
38 #include "audio/master_track.h"
39 #include "audio/midi_bus_track.h"
40 #include "audio/midi_event.h"
41 #include "audio/midi_group_track.h"
42 #include "audio/midi_track.h"
43 #include "audio/modulator_track.h"
44 #include "audio/instrument_track.h"
45 #include "audio/router.h"
46 #include "audio/stretcher.h"
47 #include "audio/tempo_track.h"
48 #include "audio/track.h"
49 #include "gui/backend/event.h"
50 #include "gui/backend/event_manager.h"
51 #include "gui/widgets/arranger.h"
52 #include "gui/widgets/channel.h"
53 #include "gui/widgets/center_dock.h"
54 #include "gui/widgets/dialogs/export_progress_dialog.h"
55 #include "gui/widgets/main_window.h"
56 #include "gui/widgets/midi_region.h"
57 #include "gui/widgets/timeline_arranger.h"
58 #include "gui/widgets/track.h"
59 #include "project.h"
60 #include "utils/arrays.h"
61 #include "utils/debug.h"
62 #include "utils/error.h"
63 #include "utils/flags.h"
64 #include "utils/io.h"
65 #include "utils/mem.h"
66 #include "utils/object_utils.h"
67 #include "utils/objects.h"
68 #include "utils/string.h"
69 #include "zrythm_app.h"
70 
71 #include <glib/gi18n.h>
72 
73 void
track_init_loaded(Track * self,Tracklist * tracklist,TracklistSelections * ts)74 track_init_loaded (
75   Track *               self,
76   Tracklist *           tracklist,
77   TracklistSelections * ts)
78 {
79   self->magic = TRACK_MAGIC;
80   self->tracklist = tracklist;
81   self->ts = ts;
82 
83   if (TRACK_CAN_BE_GROUP_TARGET (self))
84     {
85       group_target_track_init_loaded (self);
86     }
87   else if (self->type == TRACK_TYPE_MODULATOR)
88     {
89       for (int i = 0; i < self->num_modulators; i++)
90         {
91           plugin_init_loaded (
92             self->modulators[i], self, NULL);
93         }
94     }
95 
96   TrackLane * lane;
97   for (int j = 0; j < self->num_lanes; j++)
98     {
99       lane = self->lanes[j];
100       track_lane_init_loaded (lane, self);
101     }
102   ScaleObject * scale;
103   for (int i = 0; i < self->num_scales; i++)
104     {
105       scale = self->scales[i];
106       arranger_object_init_loaded (
107         (ArrangerObject *) scale);
108     }
109   Marker * marker;
110   for (int i = 0; i < self->num_markers; i++)
111     {
112       marker = self->markers[i];
113       arranger_object_init_loaded (
114         (ArrangerObject *) marker);
115     }
116   ZRegion * region;
117   for (int i = 0; i < self->num_chord_regions; i++)
118     {
119       region = self->chord_regions[i];
120       region->id.track_name_hash =
121         track_get_name_hash (self);
122       arranger_object_init_loaded (
123         (ArrangerObject *) region);
124     }
125 
126   /* init loaded track processor */
127   if (self->processor)
128     {
129       self->processor->track = self;
130       track_processor_init_loaded (
131         self->processor, self);
132     }
133 
134   /* init loaded channel */
135   if (self->channel)
136     {
137       self->channel->track = self;
138       channel_init_loaded (
139         self->channel, self);
140     }
141 
142   /* set track to automation tracklist */
143   AutomationTracklist * atl =
144     track_get_automation_tracklist (self);
145   if (atl)
146     {
147       automation_tracklist_init_loaded (
148         atl, self);
149     }
150 
151   if (self->type == TRACK_TYPE_AUDIO)
152     {
153       self->rt_stretcher =
154         stretcher_new_rubberband (
155           AUDIO_ENGINE->sample_rate, 2, 1.0,
156           1.0, true);
157     }
158 
159   for (int i = 0; i < self->num_modulator_macros;
160        i++)
161     {
162       ModulatorMacroProcessor * mmp =
163         self->modulator_macros[i];
164       modulator_macro_processor_init_loaded (
165         mmp, self);
166     }
167 
168   /** set magic to all track ports */
169   GPtrArray * ports = g_ptr_array_new ();
170   track_append_ports (self, ports, true);
171   unsigned int name_hash =
172     track_get_name_hash (self);
173   for (size_t i = 0; i < ports->len; i++)
174     {
175       Port * port = g_ptr_array_index (ports, i);
176       port->magic = PORT_MAGIC;
177       port->track = self;
178       if (track_is_in_active_project (self))
179         {
180           g_return_if_fail (
181             port->id.track_name_hash == name_hash);
182 
183           /* set automation tracks on ports */
184           if (port->id.flags &
185                 PORT_FLAG_AUTOMATABLE)
186             {
187               AutomationTrack * at =
188                 automation_track_find_from_port (
189                   port, self, true);
190               g_return_if_fail (at);
191               port->at = at;
192             }
193         }
194     }
195   object_free_w_func_and_null (
196     g_ptr_array_unref, ports);
197 }
198 
199 /**
200  * Adds a new TrackLane to the Track.
201  */
202 NONNULL
203 static void
track_add_lane(Track * self,int fire_events)204 track_add_lane (
205   Track * self,
206   int     fire_events)
207 {
208   g_return_if_fail (IS_TRACK (self));
209 
210   array_double_size_if_full (
211     self->lanes, self->num_lanes,
212     self->lanes_size, TrackLane *);
213   TrackLane * lane =
214     track_lane_new (self, self->num_lanes);
215   g_return_if_fail (lane);
216   self->lanes[self->num_lanes++] = lane;
217 
218   if (fire_events)
219     {
220       EVENTS_PUSH (
221         ET_TRACK_LANE_ADDED,
222         self->lanes[self->num_lanes - 1]);
223     }
224 }
225 
226 /**
227  * Inits the Track, optionally adding a single
228  * lane.
229  *
230  * @param add_lane Add a lane. This should be used
231  *   for new Tracks. When cloning, the lanes should
232  *   be cloned so this should be 0.
233  */
234 void
track_init(Track * self,const int add_lane)235 track_init (
236   Track *   self,
237   const int add_lane)
238 {
239   self->schema_version = TRACK_SCHEMA_VERSION;
240   self->visible = true;
241   self->main_height = TRACK_DEF_HEIGHT;
242   self->midi_ch = 1;
243   self->magic = TRACK_MAGIC;
244   self->enabled = true;
245   self->comment = g_strdup ("");
246   self->size = 1;
247   track_add_lane (self, 0);
248 }
249 
250 /**
251  * Creates a track with the given label and returns
252  * it.
253  *
254  * If the TrackType is one that needs a Channel,
255  * then a Channel is also created for the track.
256  *
257  * @param pos Position in the Tracklist.
258  * @param with_lane Init the Track with a lane.
259  */
260 Track *
track_new(TrackType type,int pos,const char * label,const int with_lane)261 track_new (
262   TrackType    type,
263   int          pos,
264   const char * label,
265   const int    with_lane)
266 {
267   Track * self = object_new (Track);
268 
269   g_debug ("creating track '%s'", label);
270 
271   self->pos = pos;
272   self->type = type;
273   track_init (self, with_lane);
274 
275   self->name = g_strdup (label);
276 
277   switch (type)
278     {
279     case TRACK_TYPE_INSTRUMENT:
280       self->in_signal_type =
281         TYPE_EVENT;
282       self->out_signal_type =
283         TYPE_AUDIO;
284       instrument_track_init (self);
285       break;
286     case TRACK_TYPE_AUDIO:
287       self->in_signal_type =
288         TYPE_AUDIO;
289       self->out_signal_type =
290         TYPE_AUDIO;
291       audio_track_init (self);
292       break;
293     case TRACK_TYPE_MASTER:
294       self->in_signal_type =
295         TYPE_AUDIO;
296       self->out_signal_type =
297         TYPE_AUDIO;
298       master_track_init (self);
299       break;
300     case TRACK_TYPE_AUDIO_BUS:
301       self->in_signal_type =
302         TYPE_AUDIO;
303       self->out_signal_type =
304         TYPE_AUDIO;
305       audio_bus_track_init (self);
306       break;
307     case TRACK_TYPE_MIDI_BUS:
308       self->in_signal_type =
309         TYPE_EVENT;
310       self->out_signal_type =
311         TYPE_EVENT;
312       midi_bus_track_init (self);
313       break;
314     case TRACK_TYPE_AUDIO_GROUP:
315       self->in_signal_type =
316         TYPE_AUDIO;
317       self->out_signal_type =
318         TYPE_AUDIO;
319       audio_group_track_init (self);
320       break;
321     case TRACK_TYPE_MIDI_GROUP:
322       self->in_signal_type =
323         TYPE_EVENT;
324       self->out_signal_type =
325         TYPE_EVENT;
326       midi_group_track_init (self);
327       break;
328     case TRACK_TYPE_MIDI:
329       self->in_signal_type =
330         TYPE_EVENT;
331       self->out_signal_type =
332         TYPE_EVENT;
333       midi_track_init (self);
334       break;
335     case TRACK_TYPE_CHORD:
336       self->in_signal_type =
337         TYPE_EVENT;
338       self->out_signal_type =
339         TYPE_EVENT;
340       chord_track_init (self);
341       break;
342     case TRACK_TYPE_MARKER:
343       self->in_signal_type =
344         TYPE_UNKNOWN;
345       self->out_signal_type =
346         TYPE_UNKNOWN;
347       marker_track_init (self);
348       break;
349     case TRACK_TYPE_TEMPO:
350       self->in_signal_type =
351         TYPE_UNKNOWN;
352       self->out_signal_type =
353         TYPE_UNKNOWN;
354       tempo_track_init (self);
355       break;
356     case TRACK_TYPE_MODULATOR:
357       self->in_signal_type =
358         TYPE_UNKNOWN;
359       self->out_signal_type =
360         TYPE_UNKNOWN;
361       modulator_track_init (self);
362       break;
363     case TRACK_TYPE_FOLDER:
364       self->in_signal_type =
365         TYPE_UNKNOWN;
366       self->out_signal_type =
367         TYPE_UNKNOWN;
368       break;
369     default:
370       g_return_val_if_reached (NULL);
371     }
372 
373   if (track_type_is_foldable (type))
374     {
375       foldable_track_init (self);
376     }
377 
378   if (TRACK_CAN_BE_GROUP_TARGET (self))
379     {
380       group_target_track_init (self);
381     }
382 
383   if (track_type_can_record (type))
384     {
385       self->recording =
386         port_new_with_type_and_owner (
387           TYPE_CONTROL, FLOW_INPUT,
388           _("Track record"),
389           PORT_OWNER_TYPE_TRACK, self);
390       control_port_set_toggled (
391         self->recording, F_NO_TOGGLE,
392         F_NO_PUBLISH_EVENTS);
393       self->recording->id.flags2 |=
394         PORT_FLAG2_TRACK_RECORDING;
395       self->recording->id.flags |=
396         PORT_FLAG_TOGGLE;
397     }
398 
399   self->processor = track_processor_new (self);
400 
401   automation_tracklist_init (
402     &self->automation_tracklist, self);
403 
404   if (track_type_has_channel (self->type))
405     {
406       self->channel = channel_new (self);
407     }
408 
409   track_generate_automation_tracks (self);
410 
411   return self;
412 }
413 
414 /**
415  * Returns if the given TrackType is a type of
416  * Track that has a Channel.
417  */
418 bool
track_type_has_channel(TrackType type)419 track_type_has_channel (
420   TrackType type)
421 {
422   switch (type)
423     {
424     case TRACK_TYPE_MARKER:
425     case TRACK_TYPE_TEMPO:
426     case TRACK_TYPE_MODULATOR:
427     case TRACK_TYPE_FOLDER:
428       return false;
429     default:
430       break;
431     }
432 
433   return true;
434 }
435 
436 /**
437  * Returns whether the track type is deletable
438  * by the user.
439  */
440 bool
track_type_is_deletable(TrackType type)441 track_type_is_deletable (
442   TrackType type)
443 {
444   return
445     type != TRACK_TYPE_MASTER &&
446     type != TRACK_TYPE_TEMPO &&
447     type != TRACK_TYPE_CHORD &&
448     type != TRACK_TYPE_MODULATOR &&
449     type != TRACK_TYPE_MARKER;
450 }
451 
452 /**
453  * Clones the track and returns the clone.
454  *
455  * @param error To be filled if an error occurred.
456  */
457 Track *
track_clone(Track * track,GError ** error)458 track_clone (
459   Track *   track,
460   GError ** error)
461 {
462   g_return_val_if_fail (!error || !*error, NULL);
463 
464   /* set the track on the given track's channel
465    * if not set */
466   if (!track_is_in_active_project (track)
467       && track->channel
468       && !track->channel->track)
469     track->channel->track = track;
470 
471   Track * new_track =
472     track_new (
473       track->type, track->pos, track->name,
474       F_WITHOUT_LANE);
475   g_return_val_if_fail (
476     IS_TRACK_AND_NONNULL (new_track), NULL);
477 
478   new_track->icon_name =
479     g_strdup (track->icon_name);
480   new_track->comment =
481     g_strdup (track->comment);
482 
483 #define COPY_MEMBER(a) \
484   new_track->a = track->a
485 
486   COPY_MEMBER (type);
487   COPY_MEMBER (automation_visible);
488   COPY_MEMBER (visible);
489   COPY_MEMBER (main_height);
490   COPY_MEMBER (enabled);
491   COPY_MEMBER (color);
492   COPY_MEMBER (pos);
493   COPY_MEMBER (midi_ch);
494   COPY_MEMBER (size);
495   COPY_MEMBER (folded);
496   COPY_MEMBER (record_set_automatically);
497   COPY_MEMBER (drum_mode);
498 
499 #undef COPY_MEMBER
500 
501   if (track->recording)
502     {
503       control_port_set_toggled (
504         new_track->recording,
505         control_port_is_toggled (track->recording),
506         F_NO_PUBLISH_EVENTS);
507     }
508 
509   if (track->channel)
510     {
511       object_free_w_func_and_null (
512         channel_free, new_track->channel);
513 
514       /* set the given channel's track if not
515        * set */
516       GError * err = NULL;
517       new_track->channel =
518         channel_clone (
519           track->channel, new_track, &err);
520       if (new_track->channel == NULL)
521         {
522           PROPAGATE_PREFIXED_ERROR (
523             error, err, "%s",
524             _("Failed to clone channel"));
525           object_free_w_func_and_null (
526             track_free, new_track);
527           return NULL;
528         }
529       new_track->channel->track = new_track;
530     }
531 
532   /* --- copy objects --- */
533 
534   new_track->num_lanes = track->num_lanes;
535   new_track->lanes =
536     g_realloc (
537       new_track->lanes,
538       sizeof (TrackLane *) *
539         (size_t) track->num_lanes);
540   for (int j = 0; j < track->num_lanes; j++)
541     {
542        TrackLane * lane = track->lanes[j];
543        TrackLane * new_lane =
544          track_lane_clone (lane, new_track);
545        new_track->lanes[j] = new_lane;
546     }
547 
548   new_track->num_scales = track->num_scales;
549   new_track->scales =
550     g_realloc (
551       new_track->scales,
552       sizeof (ScaleObject *) *
553         (size_t) track->num_scales);
554   for (int j = 0; j < track->num_scales; j++)
555     {
556        ScaleObject * s = track->scales[j];
557        new_track->scales[j] =
558          (ScaleObject *)
559          arranger_object_clone (
560            (ArrangerObject *) s);
561     }
562 
563   new_track->num_markers = track->num_markers;
564   new_track->markers =
565     g_realloc (
566       new_track->markers,
567       sizeof (Marker *) *
568         (size_t) track->num_markers);
569   for (int j = 0; j < track->num_markers; j++)
570     {
571        Marker * m = track->markers[j];
572        new_track->markers[j] =
573          (Marker *)
574          arranger_object_clone (
575            (ArrangerObject *) m);
576     }
577 
578   new_track->num_chord_regions =
579     track->num_chord_regions;
580   new_track->chord_regions =
581     g_realloc (
582       new_track->chord_regions,
583       sizeof (ZRegion *) *
584         (size_t) track->num_chord_regions);
585   for (int j = 0; j < track->num_chord_regions; j++)
586     {
587        ZRegion * r = track->chord_regions[j];
588        new_track->chord_regions[j] =
589          (ZRegion *)
590          arranger_object_clone (
591            (ArrangerObject *) r);
592     }
593 
594   new_track->automation_tracklist.track =
595     new_track;
596   automation_tracklist_clone (
597     &track->automation_tracklist,
598     &new_track->automation_tracklist);
599 
600   /* --- end copy objects --- */
601 
602   if (TRACK_CAN_BE_GROUP_TARGET (track))
603     {
604       for (int i = 0; i < track->num_children; i++)
605         {
606           group_target_track_add_child (
607             new_track, track->children[i],
608             false, F_NO_RECALC_GRAPH,
609             F_NO_PUBLISH_EVENTS);
610         }
611     }
612 
613   /* copy processor values */
614   if (track->processor)
615     {
616       track_processor_copy_values (
617         new_track->processor, track->processor);
618     }
619 
620 #define COPY_PORT_VALUES(x) \
621   if (track->x) \
622     port_copy_values (new_track->x, track->x)
623 
624   /* copy own values */
625   COPY_PORT_VALUES (recording);
626   COPY_PORT_VALUES (bpm_port);
627   COPY_PORT_VALUES (beats_per_bar_port);
628   COPY_PORT_VALUES (beat_unit_port);
629 
630 #undef COPY_PORT_VALUES
631 
632   /* check that source track is not affected
633    * during unit tests */
634   if (ZRYTHM_TESTING &&
635       track_is_in_active_project (track))
636     {
637       track_validate (track);
638     }
639 
640   return new_track;
641 }
642 
643 /**
644  * Sets magic on objects recursively.
645  */
646 void
track_set_magic(Track * self)647 track_set_magic (
648   Track * self)
649 {
650   self->magic = TRACK_MAGIC;
651 
652   if (track_type_has_channel (self->type))
653     {
654       Channel * ch = self->channel;
655       g_return_if_fail (ch);
656 
657       channel_set_magic (ch);
658     }
659 }
660 
661 Tracklist *
track_get_tracklist(Track * self)662 track_get_tracklist (
663   Track * self)
664 {
665   if (track_is_auditioner (self))
666     {
667       return SAMPLE_PROCESSOR->tracklist;
668     }
669   else
670     {
671       return TRACKLIST;
672     }
673 }
674 
675 /**
676  * Appends the Track to the selections.
677  *
678  * @param exclusive Select only this track.
679  * @param fire_events Fire events to update the
680  *   UI.
681  */
682 void
track_select(Track * self,bool select,bool exclusive,bool fire_events)683 track_select (
684   Track * self,
685   bool    select,
686   bool    exclusive,
687   bool    fire_events)
688 {
689   g_return_if_fail (IS_TRACK (self));
690 
691   if (select)
692     {
693       if (exclusive)
694         {
695           tracklist_selections_select_single (
696             TRACKLIST_SELECTIONS, self,
697             fire_events);
698         }
699       else
700         {
701           tracklist_selections_add_track (
702             TRACKLIST_SELECTIONS, self, fire_events);
703         }
704     }
705   else
706     {
707       tracklist_selections_remove_track (
708         TRACKLIST_SELECTIONS, self, fire_events);
709     }
710 
711   if (fire_events)
712     {
713       EVENTS_PUSH (
714         ET_TRACK_CHANGED, self);
715     }
716 }
717 
718 /**
719  * Returns if the track is soloed.
720  */
721 bool
track_get_soloed(Track * self)722 track_get_soloed (
723   Track * self)
724 {
725   if (G_UNLIKELY (self->type == TRACK_TYPE_FOLDER))
726     {
727       return
728         foldable_track_is_status (
729           self,
730           FOLDABLE_TRACK_MIXER_STATUS_SOLOED);
731     }
732 
733   g_return_val_if_fail (self->channel, false);
734   return fader_get_soloed (self->channel->fader);
735 }
736 
737 /**
738  * Returns whether the track is not soloed on its
739  * own but its direct out (or its direct out's direct
740  * out, etc.) is soloed.
741  */
742 bool
track_get_implied_soloed(Track * self)743 track_get_implied_soloed (
744   Track * self)
745 {
746   if (self->type == TRACK_TYPE_FOLDER)
747     {
748       return
749         foldable_track_is_status (
750           self,
751           FOLDABLE_TRACK_MIXER_STATUS_IMPLIED_SOLOED);
752     }
753 
754   g_return_val_if_fail (self->channel, false);
755   return
756     fader_get_implied_soloed (self->channel->fader);
757 }
758 
759 /**
760  * Returns if the track is muted.
761  */
762 bool
track_get_muted(Track * self)763 track_get_muted (
764   Track * self)
765 {
766   if (self->type == TRACK_TYPE_FOLDER)
767     {
768       return
769         foldable_track_is_status (
770           self,
771           FOLDABLE_TRACK_MIXER_STATUS_MUTED);
772     }
773 
774   g_return_val_if_fail (self->channel, false);
775   return fader_get_muted (self->channel->fader);
776 }
777 
778 /**
779  * Returns if the track is listened.
780  */
781 bool
track_get_listened(Track * self)782 track_get_listened (
783   Track * self)
784 {
785   if (self->type == TRACK_TYPE_FOLDER)
786     {
787       return
788         foldable_track_is_status (
789           self,
790           FOLDABLE_TRACK_MIXER_STATUS_LISTENED);
791     }
792 
793   g_return_val_if_fail (self->channel, false);
794   return fader_get_listened (self->channel->fader);
795 }
796 
797 /**
798  * Returns whether monitor audio is on.
799  */
800 bool
track_get_monitor_audio(Track * self)801 track_get_monitor_audio (
802   Track * self)
803 {
804   g_return_val_if_fail (
805     IS_TRACK (self) && self->processor &&
806     IS_PORT_AND_NONNULL (
807       self->processor->monitor_audio),
808     false);
809 
810   return
811     control_port_is_toggled (
812       self->processor->monitor_audio);
813 }
814 
815 /**
816  * Sets whether monitor audio is on.
817  */
818 void
track_set_monitor_audio(Track * self,bool monitor,bool auto_select,bool fire_events)819 track_set_monitor_audio (
820   Track * self,
821   bool    monitor,
822   bool    auto_select,
823   bool    fire_events)
824 {
825   g_return_if_fail (
826     IS_TRACK (self) && self->processor &&
827     IS_PORT_AND_NONNULL (
828       self->processor->monitor_audio));
829 
830   if (auto_select)
831     {
832       track_select (
833         self, F_SELECT, F_EXCLUSIVE, fire_events);
834     }
835 
836   control_port_set_toggled (
837     self->processor->monitor_audio,
838     monitor, fire_events);
839 }
840 
841 TrackType
track_get_type_from_plugin_descriptor(PluginDescriptor * descr)842 track_get_type_from_plugin_descriptor (
843   PluginDescriptor * descr)
844 {
845   if (plugin_descriptor_is_instrument (descr))
846     return TRACK_TYPE_INSTRUMENT;
847   else if (plugin_descriptor_is_midi_modifier (
848              descr))
849     return TRACK_TYPE_MIDI;
850   else
851     return TRACK_TYPE_AUDIO_BUS;
852 }
853 
854 bool
track_get_recording(const Track * const track)855 track_get_recording (
856   const Track * const track)
857 {
858   g_return_val_if_fail (
859     IS_TRACK (track) &&
860       track_type_can_record (track->type) &&
861       IS_PORT_AND_NONNULL (track->recording),
862     false);
863 
864   return
865     control_port_is_toggled (track->recording);
866 }
867 
868 /**
869  * Sets recording and connects/disconnects the
870  * JACK ports.
871  */
872 void
track_set_recording(Track * track,bool recording,bool fire_events)873 track_set_recording (
874   Track *   track,
875   bool      recording,
876   bool      fire_events)
877 {
878   g_return_if_fail (IS_TRACK (track));
879 
880   g_debug (
881     "%s: setting recording %d (fire events: %d)",
882     track->name, recording, fire_events);
883 
884   Channel * channel =
885     track_get_channel (track);
886 
887   if (!channel)
888     {
889       g_message (
890         "Recording not implemented yet for this "
891         "track.");
892       return;
893     }
894 
895   control_port_set_toggled (
896     track->recording, recording,
897     F_NO_PUBLISH_EVENTS);
898 
899   if (recording)
900     {
901       g_message (
902         "enabled recording on %s", track->name);
903     }
904   else
905     {
906       /*g_warn_if_reached ();*/
907       g_message (
908         "disabled recording on %s", track->name);
909     }
910 
911   if (fire_events)
912     {
913       EVENTS_PUSH (
914         ET_TRACK_STATE_CHANGED, track);
915     }
916 }
917 
918 /**
919  * Sets track muted and optionally adds the action
920  * to the undo stack.
921  */
922 void
track_set_muted(Track * self,bool mute,bool trigger_undo,bool auto_select,bool fire_events)923 track_set_muted (
924   Track * self,
925   bool    mute,
926   bool    trigger_undo,
927   bool    auto_select,
928   bool    fire_events)
929 {
930   g_message (
931     "Setting track %s muted (%d)",
932     self->name, mute);
933 
934   if (auto_select)
935     {
936       track_select (
937         self, F_SELECT, F_EXCLUSIVE, fire_events);
938     }
939 
940   if (trigger_undo)
941     {
942       /* this is only supported if the fader track
943        * is the only track selected */
944       g_return_if_fail (
945         TRACKLIST_SELECTIONS->num_tracks == 1 &&
946         TRACKLIST_SELECTIONS->tracks[0] == self);
947 
948       GError * err = NULL;
949       bool ret =
950         tracklist_selections_action_perform_edit_mute (
951           TRACKLIST_SELECTIONS, mute, &err);
952       if (!ret)
953         {
954           HANDLE_ERROR (
955             err, "%s",
956             _("Cannot set track muted"));
957           return;
958         }
959     }
960   else
961     {
962       fader_set_muted (
963         self->channel->fader, mute, fire_events);
964     }
965 }
966 
967 /**
968  * Sets track folded and optionally adds the action
969  * to the undo stack.
970  */
971 void
track_set_folded(Track * self,bool folded,bool trigger_undo,bool auto_select,bool fire_events)972 track_set_folded (
973   Track * self,
974   bool    folded,
975   bool    trigger_undo,
976   bool    auto_select,
977   bool    fire_events)
978 {
979   g_return_if_fail (
980     track_type_is_foldable (self->type));
981 
982   g_message (
983     "Setting track %s folded (%d)",
984     self->name, folded);
985   if (auto_select)
986     {
987       track_select (
988         self, F_SELECT, F_EXCLUSIVE, fire_events);
989     }
990 
991   if (trigger_undo)
992     {
993       g_return_if_fail (
994         TRACKLIST_SELECTIONS->num_tracks == 1 &&
995         TRACKLIST_SELECTIONS->tracks[0] == self);
996 
997       GError * err = NULL;
998       bool ret =
999         tracklist_selections_action_perform_edit_fold (
1000           TRACKLIST_SELECTIONS, folded, &err);
1001       if (!ret)
1002         {
1003           HANDLE_ERROR (
1004             err, "%s",
1005             _("Cannot set track folded"));
1006           return;
1007         }
1008     }
1009   else
1010     {
1011       self->folded = folded;
1012 
1013       if (fire_events)
1014         {
1015           EVENTS_PUSH (ET_TRACK_FOLD_CHANGED, self);
1016         }
1017     }
1018 }
1019 
1020 /**
1021  * Returns the Track from the Project matching
1022  * \p name.
1023  *
1024  * @param name Name to search for.
1025  */
1026 Track *
track_get_from_name(const char * name)1027 track_get_from_name (
1028   const char * name)
1029 {
1030   g_return_val_if_fail (name, NULL);
1031 
1032   for (int i = 0; i < TRACKLIST->num_tracks; i++)
1033     {
1034       Track * track = TRACKLIST->tracks[i];
1035       if (string_is_equal (track->name, name))
1036         {
1037           return track;
1038         }
1039     }
1040 
1041   g_return_val_if_reached (NULL);
1042 }
1043 
1044 Track *
track_find_by_name(const char * name)1045 track_find_by_name (
1046   const char * name)
1047 {
1048   Track * track;
1049   for (int i = 0; i < TRACKLIST->num_tracks; i++)
1050     {
1051       track = TRACKLIST->tracks[i];
1052       if (g_strcmp0 (track->name, name) == 0)
1053         return track;
1054     }
1055   return NULL;
1056 }
1057 
1058 /**
1059  * Fills in the array with all the velocities in
1060  * the project that are within or outside the
1061  * range given.
1062  *
1063  * @param inside Whether to find velocities inside
1064  *   the range (1) or outside (0).
1065  */
1066 void
track_get_velocities_in_range(const Track * track,const Position * start_pos,const Position * end_pos,Velocity *** velocities,int * num_velocities,size_t * velocities_size,int inside)1067 track_get_velocities_in_range (
1068   const Track *    track,
1069   const Position * start_pos,
1070   const Position * end_pos,
1071   Velocity ***     velocities,
1072   int *            num_velocities,
1073   size_t *         velocities_size,
1074   int              inside)
1075 {
1076   if (track->type != TRACK_TYPE_MIDI &&
1077       track->type != TRACK_TYPE_INSTRUMENT)
1078     return;
1079 
1080   for (int i = 0; i < track->num_lanes; i++)
1081     {
1082       TrackLane * lane = track->lanes[i];
1083       for (int j = 0; j < lane->num_regions; j++)
1084         {
1085           ZRegion * r = lane->regions[j];
1086           midi_region_get_velocities_in_range (
1087             r, start_pos, end_pos, velocities,
1088             num_velocities, velocities_size,
1089             inside);
1090         }
1091     }
1092 }
1093 
1094 /**
1095  * Verifies the identifiers on a live Track
1096  * (in the project, not a clone).
1097  *
1098  * @return True if pass.
1099  */
1100 bool
track_validate(Track * self)1101 track_validate (
1102   Track * self)
1103 {
1104   g_return_val_if_fail (self, false);
1105 
1106   g_debug (
1107     "validating track '%s'...", self->name);
1108 
1109   if (self->channel)
1110     g_return_val_if_fail (
1111       self->channel->sends[0]->track_name_hash ==
1112       self->channel->sends[0]->amount->
1113         id.track_name_hash,
1114       false);
1115 
1116   if (ZRYTHM_TESTING)
1117     {
1118       /* verify port identifiers */
1119       GPtrArray * ports = g_ptr_array_new ();
1120       track_append_ports (
1121         self, ports, F_INCLUDE_PLUGINS);
1122       AutomationTracklist * atl =
1123         track_get_automation_tracklist (self);
1124       unsigned int name_hash =
1125         track_get_name_hash (self);
1126       for (size_t i = 0; i < ports->len; i++)
1127         {
1128           Port * port = g_ptr_array_index (ports, i);
1129           g_return_val_if_fail (
1130             port->id.track_name_hash == name_hash,
1131             false);
1132           if (port->id.owner_type ==
1133                 PORT_OWNER_TYPE_PLUGIN)
1134             {
1135               PluginIdentifier * pid =
1136                 &port->id.plugin_id;
1137               g_return_val_if_fail (
1138                 pid->track_name_hash == name_hash,
1139                 false);
1140               Plugin * pl = plugin_find (pid);
1141               g_return_val_if_fail (
1142                 plugin_identifier_validate (pid),
1143                 false);
1144               g_return_val_if_fail (
1145                 plugin_identifier_validate (&pl->id),
1146                 false);
1147               g_return_val_if_fail (
1148                 plugin_identifier_is_equal (
1149                   &pl->id, pid), false);
1150               if (pid->slot_type ==
1151                     PLUGIN_SLOT_INSTRUMENT)
1152                 {
1153                   g_return_val_if_fail (
1154                     pl == self->channel->instrument,
1155                     false);
1156                 }
1157             }
1158 
1159           /* check that the automation track is
1160            * there */
1161           if (atl &&
1162               port->id.flags & PORT_FLAG_AUTOMATABLE)
1163             {
1164               /*g_message ("checking %s", port->id.label);*/
1165               AutomationTrack * at =
1166                 automation_track_find_from_port (
1167                   port, self, true);
1168               if (!at)
1169                 {
1170                   char full_str[600];
1171                   port_get_full_designation (
1172                     port, full_str);
1173                   g_critical (
1174                     "Could not find automation track "
1175                     "for port '%s'",
1176                     full_str);
1177                   return false;
1178                 }
1179               g_return_val_if_fail (
1180                 automation_track_find_from_port (
1181                   port, self, false), false);
1182               g_return_val_if_fail (
1183                 port->at == at, false);
1184 
1185               automation_track_verify (at);
1186             }
1187         }
1188       object_free_w_func_and_null (
1189         g_ptr_array_unref, ports);
1190     }
1191 
1192   /* verify output and sends */
1193   if (self->channel)
1194     {
1195       Channel * ch = self->channel;
1196       Track * out_track =
1197         channel_get_output_track (ch);
1198       g_return_val_if_fail (
1199         out_track != self, false);
1200 
1201       if (TRACK_CAN_BE_GROUP_TARGET (self))
1202         {
1203           group_target_track_validate (self);
1204         }
1205 
1206       /* verify plugins */
1207       Plugin * plugins[60];
1208       int num_plugins =
1209         channel_get_plugins (
1210           self->channel, plugins);
1211       for (int i = 0; i < num_plugins; i++)
1212         {
1213           Plugin * pl = plugins[i];
1214           g_return_val_if_fail (
1215             plugin_validate (pl), false);
1216         }
1217 
1218       /* verify sends */
1219       for (int i = 0; i < STRIP_SIZE; i++)
1220         {
1221           ChannelSend * send = ch->sends[i];
1222           channel_send_validate (send);
1223         }
1224     }
1225 
1226   /* verify tracklist identifiers */
1227   AutomationTracklist * atl =
1228     track_get_automation_tracklist (self);
1229   if (atl)
1230     {
1231       g_return_val_if_fail (
1232         automation_tracklist_validate (atl),
1233         false);
1234     }
1235 
1236   /* verify regions */
1237   for (int i = 0; i < self->num_lanes; i++)
1238     {
1239       TrackLane * lane = self->lanes[i];
1240 
1241       for (int j = 0; j < lane->num_regions; j++)
1242         {
1243           ZRegion * region = lane->regions[j];
1244           region_validate (
1245             region,
1246             track_is_in_active_project (self));
1247         }
1248     }
1249 
1250   for (int i = 0; i < self->num_chord_regions; i++)
1251     {
1252       ZRegion * r = self->chord_regions[i];
1253       region_validate (
1254         r, track_is_in_active_project (self));
1255     }
1256 
1257   g_debug (
1258     "done validating track '%s'", self->name);
1259 
1260   return true;
1261 }
1262 
1263 /**
1264  * Adds the track's folder parents to the given
1265  * array.
1266  *
1267  * @param prepend Whether to prepend instead of
1268  *   append.
1269  */
1270 void
track_add_folder_parents(Track * self,GPtrArray * parents,bool prepend)1271 track_add_folder_parents (
1272   Track *     self,
1273   GPtrArray * parents,
1274   bool        prepend)
1275 {
1276   for (int i = 0; i < TRACKLIST->num_tracks; i++)
1277     {
1278       Track * cur_track = TRACKLIST->tracks[i];
1279       if (!track_type_is_foldable (
1280              cur_track->type))
1281         continue;
1282 
1283       /* last position covered by the foldable
1284        * track cur_track */
1285       int last_covered_pos =
1286         cur_track->pos + (cur_track->size - 1);
1287 
1288       if (cur_track->pos < self->pos &&
1289           self->pos <= last_covered_pos)
1290         {
1291           g_ptr_array_insert (
1292             parents, prepend ? 0 : -1, cur_track);
1293         }
1294     }
1295 }
1296 
1297 /**
1298  * Returns the closest foldable parent or NULL.
1299  */
1300 Track *
track_get_direct_folder_parent(Track * track)1301 track_get_direct_folder_parent (
1302   Track * track)
1303 {
1304   GPtrArray * parents = g_ptr_array_new ();
1305   track_add_folder_parents (
1306     track, parents, true);
1307   Track * parent = NULL;
1308   if (parents->len > 0)
1309     {
1310       parent = g_ptr_array_index (parents, 0);
1311     }
1312   g_ptr_array_unref (parents);
1313 
1314   return parent;
1315 }
1316 
1317 /**
1318  * Remove the track from all folders.
1319  *
1320  * Used when deleting tracks.
1321  */
1322 void
track_remove_from_folder_parents(Track * self)1323 track_remove_from_folder_parents (
1324   Track * self)
1325 {
1326   GPtrArray * parents = g_ptr_array_new ();
1327   track_add_folder_parents (
1328     self, parents, false);
1329   for (size_t j = 0; j < parents->len; j++)
1330     {
1331       Track * parent =
1332         g_ptr_array_index (parents, j);
1333       parent->size--;
1334     }
1335   g_ptr_array_unref (parents);
1336 }
1337 
1338 /**
1339  * Returns if the given TrackType can host the
1340  * given RegionType.
1341  */
1342 int
track_type_can_host_region_type(const TrackType tt,const RegionType rt)1343 track_type_can_host_region_type (
1344   const TrackType  tt,
1345   const RegionType rt)
1346 {
1347   switch (rt)
1348     {
1349     case REGION_TYPE_MIDI:
1350       return
1351         tt == TRACK_TYPE_MIDI ||
1352         tt == TRACK_TYPE_INSTRUMENT;
1353     case REGION_TYPE_AUDIO:
1354       return
1355         tt == TRACK_TYPE_AUDIO;
1356     case REGION_TYPE_AUTOMATION:
1357       return
1358         tt != TRACK_TYPE_CHORD &&
1359         tt != TRACK_TYPE_MARKER;
1360     case REGION_TYPE_CHORD:
1361       return
1362         tt == TRACK_TYPE_CHORD;
1363     }
1364   g_return_val_if_reached (-1);
1365 }
1366 
1367 /**
1368  * Returns whether the track should be visible.
1369  *
1370  * Takes into account Track.visible and whether
1371  * any of the track's foldable parents are folded.
1372  */
1373 NONNULL
1374 bool
track_get_should_be_visible(Track * self)1375 track_get_should_be_visible (
1376   Track * self)
1377 {
1378   if (!self->visible)
1379     return false;
1380 
1381   GPtrArray * parents = g_ptr_array_new ();
1382   track_add_folder_parents (
1383     self, parents, false);
1384   for (size_t i = 0; i < parents->len; i++)
1385     {
1386       Track * parent =
1387         g_ptr_array_index (parents, i);
1388       if (!parent->visible || parent->folded)
1389         return false;
1390     }
1391   g_ptr_array_unref (parents);
1392 
1393   return true;
1394 }
1395 
1396 /**
1397  * Returns the full visible height (main height +
1398  * height of all visible automation tracks + height
1399  * of all visible lanes).
1400  */
1401 double
track_get_full_visible_height(Track * const self)1402 track_get_full_visible_height (
1403   Track * const self)
1404 {
1405   double height = self->main_height;
1406 
1407   if (self->lanes_visible)
1408     {
1409       for (int i = 0; i < self->num_lanes; i++)
1410         {
1411           TrackLane * lane = self->lanes[i];
1412           g_warn_if_fail (lane->height > 0);
1413           height += lane->height;
1414         }
1415     }
1416   if (self->automation_visible)
1417     {
1418       AutomationTracklist * atl =
1419         track_get_automation_tracklist (self);
1420       if (atl)
1421         {
1422           for (int i = 0; i < atl->num_ats; i++)
1423             {
1424               AutomationTrack * at = atl->ats[i];
1425               g_warn_if_fail (at->height > 0);
1426               if (at->visible)
1427                 height += at->height;
1428             }
1429         }
1430     }
1431   return height;
1432 }
1433 
1434 bool
track_multiply_heights(Track * self,double multiplier,bool visible_only,bool check_only)1435 track_multiply_heights (
1436   Track * self,
1437   double  multiplier,
1438   bool    visible_only,
1439   bool    check_only)
1440 {
1441   if (self->main_height * multiplier <
1442         TRACK_MIN_HEIGHT)
1443     return false;
1444 
1445   if (!check_only)
1446     {
1447       self->main_height *= multiplier;
1448     }
1449 
1450   if (!visible_only || self->lanes_visible)
1451     {
1452       for (int i = 0; i < self->num_lanes; i++)
1453         {
1454           TrackLane * lane = self->lanes[i];
1455 
1456           if (lane->height * multiplier <
1457                 TRACK_MIN_HEIGHT)
1458             {
1459               return false;
1460             }
1461 
1462           if (!check_only)
1463             {
1464               lane->height *= multiplier;
1465             }
1466         }
1467     }
1468   if (!visible_only || self->automation_visible)
1469     {
1470       AutomationTracklist * atl =
1471         track_get_automation_tracklist (self);
1472       if (atl)
1473         {
1474           for (int i = 0; i < atl->num_ats; i++)
1475             {
1476               AutomationTrack * at = atl->ats[i];
1477 
1478               if (visible_only && !at->visible)
1479                 continue;
1480 
1481               if (at->height * multiplier <
1482                     TRACK_MIN_HEIGHT)
1483                 {
1484                   return false;
1485                 }
1486 
1487               if (!check_only)
1488                 {
1489                   at->height *= multiplier;
1490                 }
1491             }
1492         }
1493     }
1494 
1495   return true;
1496 }
1497 
1498 /**
1499  * Sets track soloed, updates UI and optionally
1500  * adds the action to the undo stack.
1501  *
1502  * @param auto_select Makes this track the only
1503  *   selection in the tracklist. Useful when soloing
1504  *   a single track.
1505  * @param trigger_undo Create and perform an
1506  *   undoable action.
1507  * @param fire_events Fire UI events.
1508  */
1509 void
track_set_soloed(Track * self,bool solo,bool trigger_undo,bool auto_select,bool fire_events)1510 track_set_soloed (
1511   Track * self,
1512   bool    solo,
1513   bool    trigger_undo,
1514   bool    auto_select,
1515   bool    fire_events)
1516 {
1517 #if 0
1518   if (self->type == TRACK_TYPE_FOLDER)
1519     {
1520       /* TODO */
1521       return;
1522     }
1523 #endif
1524 
1525   if (auto_select)
1526     {
1527       track_select (
1528         self, F_SELECT, F_EXCLUSIVE, fire_events);
1529     }
1530 
1531   if (trigger_undo)
1532     {
1533       /* this is only supported if the fader track
1534        * is the only track selected */
1535       g_return_if_fail (
1536         TRACKLIST_SELECTIONS->num_tracks == 1 &&
1537         TRACKLIST_SELECTIONS->tracks[0] == self);
1538 
1539       GError * err = NULL;
1540       bool ret =
1541         tracklist_selections_action_perform_edit_solo (
1542           TRACKLIST_SELECTIONS, solo, &err);
1543       if (!ret)
1544         {
1545           HANDLE_ERROR (
1546             err, "%s",
1547             _("Cannot set track soloed"));
1548           return;
1549         }
1550     }
1551   else
1552     {
1553       fader_set_soloed (
1554         self->channel->fader, solo, fire_events);
1555     }
1556 }
1557 
1558 /**
1559  * Sets track soloed, updates UI and optionally
1560  * adds the action to the undo stack.
1561  *
1562  * @param auto_select Makes this track the only
1563  *   selection in the tracklist. Useful when
1564  *   listening to a single track.
1565  * @param trigger_undo Create and perform an
1566  *   undoable action.
1567  * @param fire_events Fire UI events.
1568  */
1569 void
track_set_listened(Track * self,bool listen,bool trigger_undo,bool auto_select,bool fire_events)1570 track_set_listened (
1571   Track * self,
1572   bool    listen,
1573   bool    trigger_undo,
1574   bool    auto_select,
1575   bool    fire_events)
1576 {
1577   if (auto_select)
1578     {
1579       track_select (
1580         self, F_SELECT, F_EXCLUSIVE, fire_events);
1581     }
1582 
1583   if (trigger_undo)
1584     {
1585       /* this is only supported if the fader track
1586        * is the only track selected */
1587       g_return_if_fail (
1588         TRACKLIST_SELECTIONS->num_tracks == 1 &&
1589         TRACKLIST_SELECTIONS->tracks[0] == self);
1590 
1591       GError * err = NULL;
1592       bool ret =
1593         tracklist_selections_action_perform_edit_listen (
1594           TRACKLIST_SELECTIONS, listen, &err);
1595       if (!ret)
1596         {
1597           HANDLE_ERROR (
1598             err, "%s",
1599             _("Cannot set track listened"));
1600           return;
1601         }
1602     }
1603   else
1604     {
1605       fader_set_listened (
1606         self->channel->fader, listen, fire_events);
1607     }
1608 }
1609 
1610 /**
1611  * Writes the track to the given MIDI file.
1612  */
1613 void
track_write_to_midi_file(Track * self,MIDI_FILE * mf)1614 track_write_to_midi_file (
1615   Track *     self,
1616   MIDI_FILE * mf)
1617 {
1618   g_return_if_fail (
1619     track_type_has_piano_roll (self->type));
1620 
1621   TrackLane * lane;
1622   for (int i = 0; i < self->num_lanes; i++)
1623     {
1624       lane = self->lanes[i];
1625 
1626       track_lane_write_to_midi_file (
1627         lane, mf);
1628     }
1629 }
1630 
1631 /**
1632  * Returns if Track is in TracklistSelections.
1633  */
1634 int
track_is_selected(Track * self)1635 track_is_selected (Track * self)
1636 {
1637   if (tracklist_selections_contains_track (
1638         TRACKLIST_SELECTIONS, self))
1639     return 1;
1640 
1641   return 0;
1642 }
1643 
1644 /**
1645  * Returns the last region in the track, or NULL.
1646  *
1647  * FIXME cache.
1648  */
1649 ZRegion *
track_get_last_region(Track * track)1650 track_get_last_region (
1651   Track * track)
1652 {
1653   int i, j;
1654   ZRegion * last_region = NULL, * r;
1655   ArrangerObject * r_obj;
1656   Position tmp;
1657   position_init (&tmp);
1658 
1659   if (track->type == TRACK_TYPE_AUDIO ||
1660       track->type == TRACK_TYPE_INSTRUMENT)
1661     {
1662       TrackLane * lane;
1663       for (i = 0; i < track->num_lanes; i++)
1664         {
1665           lane = track->lanes[i];
1666 
1667           for (j = 0; j < lane->num_regions; j++)
1668             {
1669               r = lane->regions[j];
1670               r_obj = (ArrangerObject *) r;
1671               if (position_is_after (
1672                     &r_obj->end_pos, &tmp))
1673                 {
1674                   last_region = r;
1675                   position_set_to_pos (
1676                     &tmp, &r_obj->end_pos);
1677                 }
1678             }
1679         }
1680     }
1681 
1682   AutomationTracklist * atl =
1683     &track->automation_tracklist;
1684   AutomationTrack * at;
1685   for (i = 0; i < atl->num_ats; i++)
1686     {
1687       at = atl->ats[i];
1688       r = automation_track_get_last_region (at);
1689       r_obj = (ArrangerObject *) r;
1690 
1691       if (!r)
1692         continue;
1693 
1694       if (position_is_after (
1695             &r_obj->end_pos, &tmp))
1696         {
1697           last_region = r;
1698           position_set_to_pos (
1699             &tmp, &r_obj->end_pos);
1700         }
1701     }
1702 
1703   return last_region;
1704 }
1705 
1706 /**
1707  * Generates automatables for the track.
1708  *
1709  * Should be called as soon as the track is
1710  * created.
1711  */
1712 void
track_generate_automation_tracks(Track * track)1713 track_generate_automation_tracks (
1714   Track * track)
1715 {
1716   g_message (
1717     "generating automation tracks for '%s'",
1718     track->name);
1719 
1720   AutomationTracklist * atl =
1721     track_get_automation_tracklist (track);
1722   AutomationTrack * at;
1723 
1724   if (track_type_has_channel (track->type))
1725     {
1726       Channel * ch = track->channel;
1727 
1728       /* -- fader -- */
1729 
1730       /* volume */
1731       at =
1732         automation_track_new (ch->fader->amp);
1733       automation_tracklist_add_at (atl, at);
1734       at->created = 1;
1735       at->visible = 1;
1736 
1737       /* balance */
1738       at =
1739         automation_track_new (ch->fader->balance);
1740       automation_tracklist_add_at (atl, at);
1741 
1742       /* mute */
1743       at =
1744         automation_track_new (ch->fader->mute);
1745       automation_tracklist_add_at (atl, at);
1746 
1747       /* --- end fader --- */
1748 
1749       /* sends */
1750       for (int i = 0; i < STRIP_SIZE; i++)
1751         {
1752           at =
1753             automation_track_new (
1754               ch->sends[i]->amount);
1755           automation_tracklist_add_at (atl, at);
1756         }
1757     }
1758 
1759   if (track_type_has_piano_roll (track->type))
1760     {
1761       /* midi automatables */
1762       for (int i = 0; i < 16; i++)
1763         {
1764           Port * cc = NULL;
1765           for (int j = 0; j < 128; j++)
1766             {
1767               cc =
1768                 track->processor->midi_cc[
1769                   i * 128 + j];
1770               at = automation_track_new (cc);
1771               automation_tracklist_add_at (atl, at);
1772             }
1773 
1774           cc =
1775             track->processor->pitch_bend[i];
1776           at = automation_track_new (cc);
1777           automation_tracklist_add_at (atl, at);
1778 
1779           cc =
1780             track->processor->poly_key_pressure[i];
1781           at = automation_track_new (cc);
1782           automation_tracklist_add_at (atl, at);
1783 
1784           cc =
1785             track->processor->channel_pressure[i];
1786           at = automation_track_new (cc);
1787           automation_tracklist_add_at (atl, at);
1788         }
1789     }
1790 
1791   switch (track->type)
1792     {
1793     case TRACK_TYPE_TEMPO:
1794     /* create special BPM and time sig automation
1795      * tracks for tempo track */
1796       at = automation_track_new (track->bpm_port);
1797       at->created = true;
1798       at->visible = true;
1799       automation_tracklist_add_at (atl, at);
1800       at =
1801         automation_track_new (
1802           track->beats_per_bar_port);
1803       automation_tracklist_add_at (atl, at);
1804       at =
1805         automation_track_new (
1806           track->beat_unit_port);
1807       automation_tracklist_add_at (atl, at);
1808       break;
1809     case TRACK_TYPE_MODULATOR:
1810       for (int i = 0;
1811            i < track->num_modulator_macros; i++)
1812         {
1813           at =
1814             automation_track_new (
1815               track->modulator_macros[i]->macro);
1816           if (i == 0)
1817             {
1818               at->created = true;
1819               at->visible = true;
1820             }
1821           automation_tracklist_add_at (atl, at);
1822         }
1823       break;
1824     case TRACK_TYPE_AUDIO:
1825       at =
1826         automation_track_new (
1827           track->processor->output_gain);
1828       break;
1829     default:
1830       break;
1831     }
1832 
1833   g_message ("done");
1834 }
1835 
1836 /**
1837  * Wrapper.
1838  */
1839 void
track_setup(Track * track)1840 track_setup (Track * track)
1841 {
1842 #define SETUP_TRACK(uc,sc) \
1843   case TRACK_TYPE_##uc: \
1844     sc##_track_setup (track); \
1845     break;
1846 
1847   switch (track->type)
1848     {
1849     SETUP_TRACK (INSTRUMENT, instrument);
1850     SETUP_TRACK (MASTER, master);
1851     SETUP_TRACK (AUDIO, audio);
1852     SETUP_TRACK (AUDIO_BUS, audio_bus);
1853     SETUP_TRACK (AUDIO_GROUP, audio_group);
1854     case TRACK_TYPE_CHORD:
1855     /* TODO */
1856     default:
1857       break;
1858     }
1859 
1860 #undef SETUP_TRACK
1861 }
1862 
1863 /**
1864  * Adds a ZRegion to the given lane of the track.
1865  *
1866  * The ZRegion must be the main region (see
1867  * ArrangerObjectInfo).
1868  *
1869  * @param at The AutomationTrack of this ZRegion, if
1870  *   automation region.
1871  * @param lane_pos The position of the lane to add
1872  *   to, if applicable.
1873  * @param gen_name Generate a unique region name or
1874  *   not. This will be 0 if the caller already
1875  *   generated a unique name.
1876  */
1877 void
track_add_region(Track * track,ZRegion * region,AutomationTrack * at,int lane_pos,int gen_name,int fire_events)1878 track_add_region (
1879   Track * track,
1880   ZRegion * region,
1881   AutomationTrack * at,
1882   int      lane_pos,
1883   int      gen_name,
1884   int      fire_events)
1885 {
1886   track_insert_region (
1887     track, region, at, lane_pos, -1, gen_name,
1888     fire_events);
1889 }
1890 
1891 /**
1892  * Inserts a ZRegion to the given lane or
1893  * AutomationTrack of the track, at the given
1894  * index.
1895  *
1896  * The ZRegion must be the main region (see
1897  * ArrangerObjectInfo).
1898  *
1899  * @param at The AutomationTrack of this ZRegion, if
1900  *   automation region.
1901  * @param lane_pos The position of the lane to add
1902  *   to, if applicable.
1903  * @param idx The index to insert the region at
1904  *   inside its parent, or -1 to append.
1905  * @param gen_name Generate a unique region name or
1906  *   not. This will be 0 if the caller already
1907  *   generated a unique name.
1908  */
1909 void
track_insert_region(Track * track,ZRegion * region,AutomationTrack * at,int lane_pos,int idx,int gen_name,int fire_events)1910 track_insert_region (
1911   Track *           track,
1912   ZRegion *         region,
1913   AutomationTrack * at,
1914   int               lane_pos,
1915   int               idx,
1916   int               gen_name,
1917   int               fire_events)
1918 {
1919   if (region->id.type == REGION_TYPE_AUTOMATION)
1920     {
1921       track = automation_track_get_track (at);
1922     }
1923   g_return_if_fail (IS_TRACK (track));
1924   g_return_if_fail (
1925     region_validate (region, false));
1926   g_return_if_fail (
1927     track_type_can_have_region_type (
1928       track->type, region->id.type));
1929 
1930   if (gen_name)
1931     {
1932       region_gen_name (region, NULL, at, track);
1933     }
1934 
1935   g_return_if_fail (region->name);
1936   g_message (
1937     "inserting region '%s' to track '%s' "
1938     "at lane %d (idx %d)",
1939     region->name, track->name, lane_pos, idx);
1940 
1941   int add_lane = 0, add_at = 0, add_chord = 0;
1942   switch (region->id.type)
1943     {
1944     case REGION_TYPE_MIDI:
1945       add_lane = 1;
1946       break;
1947     case REGION_TYPE_AUDIO:
1948       add_lane = 1;
1949       break;
1950     case REGION_TYPE_AUTOMATION:
1951       add_at = 1;
1952       break;
1953     case REGION_TYPE_CHORD:
1954       add_chord = 1;
1955       break;
1956     }
1957 
1958   if (add_lane)
1959     {
1960       /* enable extra lane if necessary */
1961       track_create_missing_lanes (track, lane_pos);
1962 
1963       g_warn_if_fail (track->lanes[lane_pos]);
1964       if (idx == -1)
1965         {
1966           track_lane_add_region (
1967             track->lanes[lane_pos], region);
1968         }
1969       else
1970         {
1971           track_lane_insert_region (
1972             track->lanes[lane_pos], region, idx);
1973         }
1974       g_warn_if_fail (region->id.idx >= 0);
1975     }
1976 
1977   if (add_at)
1978     {
1979       if (idx == -1)
1980         {
1981           automation_track_add_region (at, region);
1982         }
1983       else
1984         {
1985           automation_track_insert_region (
1986             at, region, idx);
1987         }
1988     }
1989 
1990   if (add_chord)
1991     {
1992       g_warn_if_fail (track == P_CHORD_TRACK);
1993 
1994       if (idx == -1)
1995         {
1996           chord_track_insert_chord_region (
1997             track, region,
1998             track->num_chord_regions);
1999         }
2000       else
2001         {
2002           chord_track_insert_chord_region (
2003             track, region, idx);
2004         }
2005     }
2006 
2007   /* write clip if audio region */
2008   if (region->id.type == REGION_TYPE_AUDIO &&
2009       !track_is_auditioner (track))
2010     {
2011       AudioClip * clip =
2012         audio_region_get_clip (region);
2013       audio_clip_write_to_pool (
2014         clip, false, F_NOT_BACKUP);
2015     }
2016 
2017   g_message ("inserted:");
2018   region_print (region);
2019 
2020   if (fire_events)
2021     {
2022       EVENTS_PUSH (
2023         ET_ARRANGER_OBJECT_CREATED, region);
2024 
2025       if (add_lane)
2026         {
2027           EVENTS_PUSH (
2028             ET_TRACK_LANE_ADDED, NULL);
2029         }
2030     }
2031 }
2032 
2033 /**
2034  * Creates missing TrackLane's until pos.
2035  */
2036 void
track_create_missing_lanes(Track * track,const int pos)2037 track_create_missing_lanes (
2038   Track *   track,
2039   const int pos)
2040 {
2041   while (track->num_lanes < pos + 2)
2042     {
2043       track_add_lane (track, 0);
2044     }
2045 }
2046 
2047 /**
2048  * Removes the empty last lanes of the Track
2049  * (except the last one).
2050  */
2051 void
track_remove_empty_last_lanes(Track * track)2052 track_remove_empty_last_lanes (
2053   Track * track)
2054 {
2055   g_return_if_fail (track);
2056   g_message ("removing empty last lanes from %s",
2057              track->name);
2058   int removed = 0;
2059   for (int i = track->num_lanes - 1; i >= 1; i--)
2060     {
2061       TrackLane * lane = track->lanes[i];
2062       TrackLane * prev_lane = track->lanes[i - 1];
2063       g_return_if_fail (lane && prev_lane);
2064 
2065       if (lane->num_regions > 0)
2066         break;
2067 
2068       if (lane->num_regions == 0 &&
2069           prev_lane->num_regions == 0)
2070         {
2071           g_message ("removing lane %d", i);
2072           track->num_lanes--;
2073           object_free_w_func_and_null (
2074             track_lane_free, track->lanes[i]);
2075           track->lanes[i] = NULL;
2076           removed = 1;
2077         }
2078     }
2079 
2080   if (removed)
2081     {
2082       EVENTS_PUSH (ET_TRACK_LANE_REMOVED, NULL);
2083     }
2084 }
2085 
2086 /**
2087  * Returns if the Track should have a piano roll.
2088  */
2089 bool
track_type_has_piano_roll(const TrackType type)2090 track_type_has_piano_roll (
2091   const TrackType type)
2092 {
2093   return type == TRACK_TYPE_MIDI ||
2094     type == TRACK_TYPE_INSTRUMENT;
2095 }
2096 
2097 /**
2098  * Updates the track's children.
2099  *
2100  * Used when changing track positions.
2101  */
2102 void
track_update_children(Track * self)2103 track_update_children (
2104   Track * self)
2105 {
2106   unsigned int name_hash =
2107     track_get_name_hash (self);
2108   for (int i = 0; i < self->num_children; i++)
2109     {
2110       Track * child =
2111         tracklist_find_track_by_name_hash (
2112           TRACKLIST, self->children[i]);
2113       g_warn_if_fail (
2114         IS_TRACK (child) &&
2115         child->out_signal_type ==
2116           self->in_signal_type);
2117       child->channel->output_name_hash = name_hash;
2118       g_debug (
2119         "%s: setting output of track %s [%d] to "
2120         "%s [%d]",
2121         __func__, child->name, child->pos,
2122         self->name, self->pos);
2123     }
2124 }
2125 
2126 /**
2127  * Freezes or unfreezes the track.
2128  *
2129  * When a track is frozen, it is bounced with
2130  * effects to a temporary file in the pool, which
2131  * is played back directly from disk.
2132  *
2133  * When the track is unfrozen, this file will be
2134  * removed from the pool and the track will be
2135  * played normally again.
2136  */
2137 void
track_freeze(Track * self,bool freeze)2138 track_freeze (
2139   Track * self,
2140   bool    freeze)
2141 {
2142   g_message (
2143     "%sfreezing %s...",
2144     freeze ? "" : "un", self->name);
2145 
2146   if (freeze)
2147     {
2148       ExportSettings settings;
2149       track_mark_for_bounce (
2150         self, F_BOUNCE, F_MARK_REGIONS,
2151         F_NO_MARK_CHILDREN, F_NO_MARK_PARENTS);
2152       settings.mode = EXPORT_MODE_TRACKS;
2153       export_settings_set_bounce_defaults (
2154         &settings, NULL, self->name);
2155 
2156       /* start exporting in a new thread */
2157       GThread * thread =
2158         g_thread_new (
2159           "bounce_thread",
2160           (GThreadFunc)
2161             exporter_generic_export_thread,
2162           &settings);
2163 
2164       /* create a progress dialog and block */
2165       ExportProgressDialogWidget * progress_dialog =
2166         export_progress_dialog_widget_new (
2167           &settings, true, false, F_CANCELABLE);
2168       gtk_window_set_transient_for (
2169         GTK_WINDOW (progress_dialog),
2170         GTK_WINDOW (MAIN_WINDOW));
2171       gtk_dialog_run (GTK_DIALOG (progress_dialog));
2172       gtk_widget_destroy (
2173         GTK_WIDGET (progress_dialog));
2174 
2175       g_thread_join (thread);
2176 
2177       /* assert exporting is finished */
2178       g_return_if_fail (!AUDIO_ENGINE->exporting);
2179 
2180       if (!settings.progress_info.has_error &&
2181           !settings.progress_info.cancelled)
2182         {
2183           /* move the temporary file to the pool */
2184           AudioClip * clip =
2185             audio_clip_new_from_file (
2186               settings.file_uri);
2187           audio_pool_add_clip (AUDIO_POOL, clip);
2188           audio_clip_write_to_pool (
2189             clip, F_NO_PARTS, F_NOT_BACKUP);
2190           self->pool_id = clip->pool_id;
2191         }
2192 
2193       if (g_file_test (
2194             settings.file_uri,
2195             G_FILE_TEST_IS_REGULAR))
2196         {
2197           io_remove (settings.file_uri);
2198         }
2199 
2200       export_settings_free_members (&settings);
2201     }
2202   else
2203     {
2204       /* FIXME */
2205       /*audio_pool_remove_clip (*/
2206         /*AUDIO_POOL, self->pool_id, true);*/
2207     }
2208 
2209   self->frozen = freeze;
2210   EVENTS_PUSH (ET_TRACK_FREEZE_CHANGED, self);
2211 }
2212 
2213 /**
2214  * Wrapper over channel_add_plugin() and
2215  * modulator_track_insert_modulator().
2216  *
2217  * @param instantiate_plugin Whether to attempt to
2218  *   instantiate the plugin.
2219  */
2220 void
track_insert_plugin(Track * self,Plugin * pl,PluginSlotType slot_type,int slot,bool instantiate_plugin,bool replacing_plugin,bool moving_plugin,bool confirm,bool gen_automatables,bool recalc_graph,bool fire_events)2221 track_insert_plugin (
2222   Track *        self,
2223   Plugin *       pl,
2224   PluginSlotType slot_type,
2225   int            slot,
2226   bool           instantiate_plugin,
2227   bool           replacing_plugin,
2228   bool           moving_plugin,
2229   bool           confirm,
2230   bool           gen_automatables,
2231   bool           recalc_graph,
2232   bool           fire_events)
2233 {
2234   g_return_if_fail (
2235     plugin_identifier_validate_slot_type_slot_combo (
2236       slot_type, slot));
2237 
2238   if (slot_type == PLUGIN_SLOT_MODULATOR)
2239     {
2240       modulator_track_insert_modulator (
2241         self, slot, pl, replacing_plugin,
2242         confirm, gen_automatables,
2243         recalc_graph, fire_events);
2244     }
2245   else
2246     {
2247       channel_add_plugin (
2248         self->channel, slot_type, slot, pl,
2249         confirm, moving_plugin, gen_automatables,
2250         recalc_graph, fire_events);
2251     }
2252 
2253   if (!pl->instantiated &&
2254       !pl->instantiation_failed)
2255     {
2256       GError * err = NULL;
2257       int ret =
2258         plugin_instantiate (pl, NULL, &err);
2259       if (ret != 0)
2260         {
2261           HANDLE_ERROR (
2262             err, "%s",
2263             _("Failed to instantiate plugin"));
2264         }
2265     }
2266 }
2267 
2268 /**
2269  * Wrapper over channel_remove_plugin() and
2270  * modulator_track_remove_modulator().
2271  */
2272 void
track_remove_plugin(Track * self,PluginSlotType slot_type,int slot,bool replacing_plugin,bool moving_plugin,bool deleting_plugin,bool deleting_track,bool recalc_graph)2273 track_remove_plugin (
2274   Track *        self,
2275   PluginSlotType slot_type,
2276   int            slot,
2277   bool           replacing_plugin,
2278   bool           moving_plugin,
2279   bool           deleting_plugin,
2280   bool           deleting_track,
2281   bool           recalc_graph)
2282 {
2283   if (slot_type == PLUGIN_SLOT_MODULATOR)
2284     {
2285       modulator_track_remove_modulator (
2286         self, slot, replacing_plugin,
2287         deleting_plugin, deleting_track,
2288         recalc_graph);
2289     }
2290   else
2291     {
2292       channel_remove_plugin (
2293         self->channel, slot_type, slot,
2294         moving_plugin, deleting_plugin,
2295         deleting_track, recalc_graph);
2296     }
2297 }
2298 
2299 /**
2300  * Disconnects the track from the processing
2301  * chain.
2302  *
2303  * This should be called immediately when the
2304  * track is getting deleted, and track_free
2305  * should be designed to be called later after
2306  * an arbitrary delay.
2307  *
2308  * @param remove_pl Remove the Plugin from the
2309  *   Channel. Useful when deleting the channel.
2310  * @param recalc_graph Recalculate mixer graph.
2311  */
2312 void
track_disconnect(Track * self,bool remove_pl,bool recalc_graph)2313 track_disconnect (
2314   Track * self,
2315   bool    remove_pl,
2316   bool    recalc_graph)
2317 {
2318   g_message ("disconnecting track '%s' (%d)...",
2319     self->name, self->pos);
2320 
2321   self->disconnecting = true;
2322 
2323   /* if this is a group track and has children,
2324    * remove them */
2325   if (track_is_in_active_project (self)
2326       && !track_is_auditioner (self)
2327       && TRACK_CAN_BE_GROUP_TARGET (self))
2328     {
2329       group_target_track_remove_all_children (
2330         self, F_DISCONNECT,
2331         F_NO_RECALC_GRAPH,
2332         F_NO_PUBLISH_EVENTS);
2333     }
2334 
2335   /* disconnect all ports and free buffers */
2336   GPtrArray * ports = g_ptr_array_new ();
2337   track_append_ports (
2338     self, ports, F_INCLUDE_PLUGINS);
2339   for (size_t i = 0; i < ports->len; i++)
2340     {
2341       Port * port = g_ptr_array_index (ports, i);
2342       if (!IS_PORT (port) ||
2343           port_is_in_active_project (port) !=
2344             track_is_in_active_project (self))
2345         {
2346           g_critical ("invalid port");
2347           object_free_w_func_and_null (
2348             g_ptr_array_unref, ports);
2349           return;
2350         }
2351 
2352       port_disconnect_all (port);
2353       port_free_bufs (port);
2354     }
2355   object_free_w_func_and_null (
2356     g_ptr_array_unref, ports);
2357 
2358   if (track_is_in_active_project (self)
2359       && !track_is_auditioner (self))
2360     {
2361       /* disconnect from folders */
2362       track_remove_from_folder_parents (self);
2363     }
2364 
2365   if (recalc_graph)
2366     {
2367       router_recalc_graph (ROUTER, F_NOT_SOFT);
2368     }
2369 
2370   if (track_type_has_channel (self->type))
2371     {
2372       channel_disconnect (
2373         self->channel, remove_pl);
2374     }
2375 
2376   self->disconnecting = false;
2377 
2378   g_debug ("done");
2379 }
2380 
2381 /**
2382  * Set track lanes visible and fire events.
2383  */
2384 void
track_set_lanes_visible(Track * track,const int visible)2385 track_set_lanes_visible (
2386   Track *   track,
2387   const int visible)
2388 {
2389   track->lanes_visible = visible;
2390 
2391   EVENTS_PUSH (
2392     ET_TRACK_LANES_VISIBILITY_CHANGED, track);
2393 }
2394 
2395 /**
2396  * Set automation visible and fire events.
2397  */
2398 void
track_set_automation_visible(Track * self,const bool visible)2399 track_set_automation_visible (
2400   Track *    self,
2401   const bool visible)
2402 {
2403   self->automation_visible = visible;
2404 
2405   if (visible)
2406     {
2407       /* if no visible automation tracks, set the
2408        * first one visible */
2409       AutomationTracklist * atl =
2410         track_get_automation_tracklist (self);
2411       int num_visible =
2412         automation_tracklist_get_num_visible (atl);
2413 
2414       if (num_visible == 0)
2415         {
2416           AutomationTrack * at =
2417             automation_tracklist_get_first_invisible_at (
2418               atl);
2419           if (at)
2420             {
2421               at->created = true;
2422               at->visible = true;
2423             }
2424           else
2425             {
2426               g_message (
2427                 "no automation tracks found for %s",
2428                 self->name);
2429             }
2430         }
2431     }
2432 
2433   EVENTS_PUSH (
2434     ET_TRACK_AUTOMATION_VISIBILITY_CHANGED, self);
2435 }
2436 
2437 /**
2438  * Unselects all arranger objects in the track.
2439  */
2440 void
track_unselect_all(Track * self)2441 track_unselect_all (
2442   Track * self)
2443 {
2444   if (track_is_auditioner (self))
2445     return;
2446 
2447   /* unselect lane regions */
2448   for (int i = 0; i < self->num_lanes; i++)
2449     {
2450       TrackLane * lane = self->lanes[i];
2451       track_lane_unselect_all (lane);
2452     }
2453 
2454   /* unselect automation regions */
2455   AutomationTracklist * atl =
2456     track_get_automation_tracklist (self);
2457   if (atl)
2458     {
2459       automation_tracklist_unselect_all (atl);
2460     }
2461 }
2462 
2463 /**
2464  * Removes all arranger objects recursively.
2465  */
2466 void
track_clear(Track * self)2467 track_clear (
2468   Track * self)
2469 {
2470   g_return_if_fail (IS_TRACK (self));
2471 
2472   /* remove lane regions */
2473   for (int i = self->num_lanes - 1; i >= 0; i--)
2474     {
2475       TrackLane * lane = self->lanes[i];
2476       track_lane_clear (lane);
2477     }
2478 
2479   /* remove automation regions */
2480   AutomationTracklist * atl =
2481     track_get_automation_tracklist (self);
2482   if (atl)
2483     {
2484       automation_tracklist_clear (atl);
2485     }
2486 }
2487 
2488 /**
2489  * Only removes the region from the track.
2490  *
2491  * @pararm free Also free the Region.
2492  */
2493 void
track_remove_region(Track * self,ZRegion * region,bool fire_events,bool free)2494 track_remove_region (
2495   Track *   self,
2496   ZRegion * region,
2497   bool      fire_events,
2498   bool      free)
2499 {
2500   g_return_if_fail (
2501     IS_TRACK (self) && IS_REGION (region));
2502 
2503   g_message (
2504     "removing region from track '%s':",
2505     self->name);
2506   if (!track_is_auditioner (self))
2507     region_print (region);
2508 
2509   /* check if region type matches track type */
2510   g_return_if_fail (
2511     track_type_can_have_region_type (
2512       self->type, region->id.type));
2513 
2514   if (!track_is_auditioner (self))
2515     region_disconnect (region);
2516 
2517   g_warn_if_fail (region->id.lane_pos >= 0);
2518 
2519   bool has_lane = false;
2520   if (region_type_has_lane (region->id.type))
2521     {
2522       has_lane = true;
2523       TrackLane * lane =
2524         self->lanes[region->id.lane_pos];
2525       track_lane_remove_region (lane, region);
2526     }
2527   else if (region->id.type == REGION_TYPE_CHORD)
2528     {
2529       chord_track_remove_region (self, region);
2530     }
2531   else if (region->id.type ==
2532              REGION_TYPE_AUTOMATION)
2533     {
2534       AutomationTracklist * atl =
2535         &self->automation_tracklist;
2536       for (int i = 0; i < atl->num_ats; i++)
2537         {
2538           AutomationTrack * at = atl->ats[i];
2539           if (at->index == region->id.at_idx)
2540             {
2541               automation_track_remove_region (
2542                 at, region);
2543             }
2544         }
2545     }
2546 
2547   if (ZRYTHM_HAVE_UI && MAIN_WINDOW &&
2548       !track_is_auditioner (self))
2549     {
2550       ArrangerObject * obj =
2551         (ArrangerObject *) region;
2552       ArrangerWidget * arranger =
2553         arranger_object_get_arranger (obj);
2554       if (arranger->hovered_object == obj)
2555         {
2556           arranger->hovered_object = NULL;
2557         }
2558     }
2559 
2560   if (free)
2561     {
2562       arranger_object_free (
2563         (ArrangerObject *) region);
2564     }
2565 
2566   if (fire_events)
2567     {
2568       EVENTS_PUSH (
2569         ET_ARRANGER_OBJECT_REMOVED,
2570         ARRANGER_OBJECT_TYPE_REGION);
2571 
2572       if (has_lane)
2573         {
2574           track_remove_empty_last_lanes (self);
2575         }
2576     }
2577 }
2578 
2579 /**
2580  * Returns the automation tracklist if the track type has one,
2581  * or NULL if it doesn't (like chord tracks).
2582  */
2583 AutomationTracklist *
track_get_automation_tracklist(Track * const track)2584 track_get_automation_tracklist (
2585   Track * const track)
2586 {
2587   g_return_val_if_fail (IS_TRACK (track), NULL);
2588 
2589   switch (track->type)
2590     {
2591     case TRACK_TYPE_MARKER:
2592     case TRACK_TYPE_FOLDER:
2593       break;
2594     case TRACK_TYPE_CHORD:
2595     case TRACK_TYPE_AUDIO_BUS:
2596     case TRACK_TYPE_AUDIO_GROUP:
2597     case TRACK_TYPE_MIDI_BUS:
2598     case TRACK_TYPE_MIDI_GROUP:
2599     case TRACK_TYPE_INSTRUMENT:
2600     case TRACK_TYPE_AUDIO:
2601     case TRACK_TYPE_MASTER:
2602     case TRACK_TYPE_MIDI:
2603     case TRACK_TYPE_TEMPO:
2604     case TRACK_TYPE_MODULATOR:
2605       return &track->automation_tracklist;
2606     default:
2607       g_warn_if_reached ();
2608       break;
2609     }
2610 
2611   return NULL;
2612 }
2613 
2614 /**
2615  * Returns the region at the given position, or
2616  * NULL.
2617  *
2618  * @param include_region_end Whether to include the
2619  *   region's end in the calculation.
2620  */
2621 ZRegion *
track_get_region_at_pos(const Track * track,const Position * pos,bool include_region_end)2622 track_get_region_at_pos (
2623   const Track *    track,
2624   const Position * pos,
2625   bool             include_region_end)
2626 {
2627   int i, j;
2628 
2629   if (track->type == TRACK_TYPE_INSTRUMENT ||
2630       track->type == TRACK_TYPE_AUDIO ||
2631       track->type == TRACK_TYPE_MIDI)
2632     {
2633       TrackLane * lane;
2634       ZRegion * r;
2635       ArrangerObject * r_obj;
2636       for (i = 0; i < track->num_lanes; i++)
2637         {
2638           lane = track->lanes[i];
2639 
2640           for (j = 0; j < lane->num_regions; j++)
2641             {
2642               r = lane->regions[j];
2643               r_obj = (ArrangerObject *) r;
2644               if (pos->frames >=
2645                     r_obj->pos.frames &&
2646                   pos->frames <
2647                     r_obj->end_pos.frames +
2648                       (include_region_end ? 1 : 0))
2649                 {
2650                   return r;
2651                 }
2652             }
2653         }
2654     }
2655   else if (track->type == TRACK_TYPE_CHORD)
2656     {
2657       ZRegion * r;
2658       ArrangerObject * r_obj;
2659       for (j = 0; j < track->num_chord_regions; j++)
2660         {
2661           r = track->chord_regions[j];
2662           r_obj = (ArrangerObject *) r;
2663           if (position_is_after_or_equal (
2664                 pos, &r_obj->pos) &&
2665               pos->frames <
2666                 r_obj->end_pos.frames +
2667                   (include_region_end ? 1 : 0))
2668             {
2669               return r;
2670             }
2671         }
2672     }
2673 
2674   return NULL;
2675 }
2676 
2677 const char *
track_stringize_type(TrackType type)2678 track_stringize_type (
2679   TrackType type)
2680 {
2681   return _(track_type_strings[type].str);
2682 }
2683 
2684 /**
2685  * Returns the Fader (if applicable).
2686  *
2687  * @param post_fader True to get post fader,
2688  *   false to get pre fader.
2689  */
2690 Fader *
track_get_fader(Track * self,bool post_fader)2691 track_get_fader (
2692   Track * self,
2693   bool    post_fader)
2694 {
2695   Channel * ch = track_get_channel (self);
2696   if (ch)
2697     {
2698       if (post_fader)
2699         {
2700           return ch->fader;
2701         }
2702       else
2703         {
2704           return ch->prefader;
2705         }
2706     }
2707 
2708   return NULL;
2709 }
2710 
2711 /**
2712  * Returns the FaderType corresponding to the given
2713  * Track.
2714  */
2715 FaderType
track_get_fader_type(const Track * track)2716 track_get_fader_type (
2717   const Track * track)
2718 {
2719   switch (track->type)
2720     {
2721     case TRACK_TYPE_MIDI:
2722     case TRACK_TYPE_MIDI_BUS:
2723     case TRACK_TYPE_CHORD:
2724     case TRACK_TYPE_MIDI_GROUP:
2725       return FADER_TYPE_MIDI_CHANNEL;
2726     case TRACK_TYPE_INSTRUMENT:
2727     case TRACK_TYPE_AUDIO:
2728     case TRACK_TYPE_AUDIO_BUS:
2729     case TRACK_TYPE_MASTER:
2730     case TRACK_TYPE_AUDIO_GROUP:
2731       return FADER_TYPE_AUDIO_CHANNEL;
2732     case TRACK_TYPE_MARKER:
2733       return FADER_TYPE_NONE;
2734     default:
2735       g_return_val_if_reached (FADER_TYPE_NONE);
2736     }
2737 }
2738 
2739 /**
2740  * Returns the prefader type
2741  * corresponding to the given Track.
2742  */
2743 FaderType
track_type_get_prefader_type(TrackType type)2744 track_type_get_prefader_type (
2745   TrackType type)
2746 {
2747   switch (type)
2748     {
2749     case TRACK_TYPE_MIDI:
2750     case TRACK_TYPE_MIDI_BUS:
2751     case TRACK_TYPE_CHORD:
2752     case TRACK_TYPE_MIDI_GROUP:
2753       return FADER_TYPE_MIDI_CHANNEL;
2754     case TRACK_TYPE_INSTRUMENT:
2755     case TRACK_TYPE_AUDIO:
2756     case TRACK_TYPE_AUDIO_BUS:
2757     case TRACK_TYPE_MASTER:
2758     case TRACK_TYPE_AUDIO_GROUP:
2759       return FADER_TYPE_AUDIO_CHANNEL;
2760     case TRACK_TYPE_MARKER:
2761       return FADER_TYPE_NONE;
2762     default:
2763       g_return_val_if_reached (FADER_TYPE_NONE);
2764     }
2765 }
2766 
2767 /**
2768  * Updates the frames/ticks of each position in
2769  * each child of the track recursively.
2770  *
2771  * @param from_ticks Whether to update the
2772  *   positions based on ticks (true) or frames
2773  *   (false).
2774  */
2775 void
track_update_positions(Track * self,bool from_ticks)2776 track_update_positions (
2777   Track * self,
2778   bool    from_ticks)
2779 {
2780   int i;
2781   for (i = 0; i < self->num_lanes; i++)
2782     {
2783       track_lane_update_positions (
2784         self->lanes[i], from_ticks);
2785     }
2786   for (i = 0; i < self->num_chord_regions; i++)
2787     {
2788       arranger_object_update_positions (
2789         (ArrangerObject *)
2790         self->chord_regions[i], from_ticks);
2791     }
2792   for (i = 0; i < self->num_scales; i++)
2793     {
2794       arranger_object_update_positions (
2795         (ArrangerObject *)
2796         self->scales[i], from_ticks);
2797     }
2798   for (i = 0; i < self->num_markers; i++)
2799     {
2800       arranger_object_update_positions (
2801         (ArrangerObject *)
2802         self->markers[i], from_ticks);
2803     }
2804 
2805   automation_tracklist_update_positions (
2806     &self->automation_tracklist, from_ticks);
2807 }
2808 
2809 /**
2810  * Wrapper for audio and MIDI/instrument tracks
2811  * to fill in MidiEvents or StereoPorts from the
2812  * timeline data.
2813  *
2814  * @note The engine splits the cycle so transport
2815  *   loop related logic is not needed.
2816  *
2817  * @param stereo_ports StereoPorts to fill.
2818  * @param midi_events MidiEvents to fill (from
2819  *   Piano Roll Port for example).
2820  */
2821 void
track_fill_events(const Track * self,const EngineProcessTimeInfo * const time_nfo,MidiEvents * midi_events,StereoPorts * stereo_ports)2822 track_fill_events (
2823   const Track *                       self,
2824   const EngineProcessTimeInfo * const time_nfo,
2825   MidiEvents *                        midi_events,
2826   StereoPorts *                       stereo_ports)
2827 {
2828 #define g_start_frames (time_nfo->g_start_frames)
2829 #define local_offset (time_nfo->local_offset)
2830 #define nframes (time_nfo->nframes)
2831 
2832   if (!track_is_auditioner (self)
2833       && !TRANSPORT_IS_ROLLING)
2834     return;
2835 
2836   const long g_end_frames =
2837     g_start_frames + nframes;
2838 
2839   if (midi_events)
2840     {
2841       zix_sem_wait (&midi_events->access_sem);
2842     }
2843 
2844 #if 0
2845   g_message (
2846     "%s: TRACK %s STARTING from %ld, "
2847     "local start frame %u, nframes %u",
2848     __func__, track->name, g_start_frames,
2849     local_start_frame, nframes);
2850 #endif
2851 
2852   TrackType tt = self->type;
2853 
2854   /* go through each lane */
2855   const int num_loops =
2856     (tt == TRACK_TYPE_CHORD ?
2857      1 : self->num_lanes);
2858   for (int j = 0; j < num_loops; j++)
2859     {
2860       TrackLane * lane = NULL;
2861       if (tt != TRACK_TYPE_CHORD)
2862         {
2863           lane = self->lanes[j];
2864           g_return_if_fail (lane);
2865         }
2866 
2867       /* go through each region */
2868       const int num_regions =
2869         (tt == TRACK_TYPE_CHORD ?
2870          self->num_chord_regions :
2871          lane->num_regions);
2872       for (int i = 0; i < num_regions; i++)
2873         {
2874           ZRegion * r =
2875             tt == TRACK_TYPE_CHORD ?
2876             self->chord_regions[i] :
2877             lane->regions[i];
2878           ArrangerObject * r_obj =
2879             (ArrangerObject *) r;
2880           g_return_if_fail (IS_REGION (r));
2881 
2882           /* skip region if muted */
2883           if (arranger_object_get_muted (r_obj))
2884             {
2885               continue;
2886             }
2887 
2888           /* skip if in bounce mode and the
2889            * region should not be bounced */
2890           if (AUDIO_ENGINE->bounce_mode !=
2891                 BOUNCE_OFF &&
2892               (!r->bounce || !self->bounce))
2893             {
2894               continue;
2895             }
2896 
2897           /* skip if region is not hit
2898            * (inclusive of its last point) */
2899           if (!region_is_hit_by_range (
2900                  r, g_start_frames,
2901                  midi_events ?
2902                    g_end_frames :
2903                    (g_end_frames - 1),
2904                  F_INCLUSIVE))
2905             {
2906               continue;
2907             }
2908 
2909           long num_frames_to_process =
2910             MIN (
2911               r_obj->end_pos.frames -
2912                 g_start_frames,
2913               nframes);
2914           nframes_t frames_processed = 0;
2915 
2916           while (num_frames_to_process > 0)
2917             {
2918               long cur_g_start_frame =
2919                 g_start_frames + frames_processed;
2920               nframes_t cur_local_start_frame =
2921                 local_offset + frames_processed;
2922 
2923               bool is_end_loop;
2924               long cur_num_frames_till_next_r_loop_or_end;
2925               region_get_frames_till_next_loop_or_end (
2926                 r, cur_g_start_frame,
2927                 &cur_num_frames_till_next_r_loop_or_end,
2928                 &is_end_loop);
2929 
2930 #if 0
2931               g_message (
2932                 "%s: cur num frames till next r "
2933                 "loop or end %ld, "
2934                 "num_frames_to_process %ld, "
2935                 "cur local start frame %u",
2936                 __func__, cur_num_frames_till_next_r_loop_or_end,
2937                 num_frames_to_process,
2938                 cur_local_start_frame);
2939 #endif
2940 
2941               /* whether we need a note off */
2942               bool need_note_off =
2943                 (cur_num_frames_till_next_r_loop_or_end <
2944                    num_frames_to_process) ||
2945                 (cur_num_frames_till_next_r_loop_or_end ==
2946                    num_frames_to_process &&
2947                  !is_end_loop) ||
2948                 /* region end */
2949                 (g_start_frames +
2950                    num_frames_to_process ==
2951                      r_obj->end_pos.frames) ||
2952                 /* transport end */
2953                 (TRANSPORT_IS_LOOPING &&
2954                  g_start_frames +
2955                    num_frames_to_process ==
2956                      TRANSPORT->loop_end_pos.frames);
2957 
2958               /* number of frames to process this
2959                * time */
2960               cur_num_frames_till_next_r_loop_or_end =
2961                 MIN (
2962                   cur_num_frames_till_next_r_loop_or_end,
2963                   num_frames_to_process);
2964 
2965               if (midi_events)
2966                 {
2967                   midi_region_fill_midi_events (
2968                     r, cur_g_start_frame,
2969                     cur_local_start_frame,
2970                     cur_num_frames_till_next_r_loop_or_end, need_note_off,
2971                     midi_events);
2972                 }
2973               else if (stereo_ports)
2974                 {
2975                   audio_region_fill_stereo_ports (
2976                     r, cur_g_start_frame,
2977                     cur_local_start_frame,
2978                     cur_num_frames_till_next_r_loop_or_end, stereo_ports);
2979                 }
2980 
2981               frames_processed += cur_num_frames_till_next_r_loop_or_end;
2982               num_frames_to_process -=
2983                 cur_num_frames_till_next_r_loop_or_end;
2984             } /* end while frames left */
2985         }
2986     }
2987 
2988 #if 0
2989   g_message ("TRACK %s ENDING", self->name);
2990 #endif
2991 
2992   if (midi_events)
2993     {
2994       midi_events_clear_duplicates (
2995         midi_events, F_QUEUED);
2996 
2997       /* sort events */
2998       midi_events_sort (midi_events, F_QUEUED);
2999 
3000       zix_sem_post (&midi_events->access_sem);
3001     }
3002 
3003 #undef g_start_frames
3004 #undef local_offset
3005 #undef nframes
3006 }
3007 
3008 /**
3009  * Wrapper to get the track name.
3010  */
3011 const char *
track_get_name(Track * track)3012 track_get_name (Track * track)
3013 {
3014 #if 0
3015   if (DEBUGGING)
3016     {
3017       return
3018         g_strdup_printf (
3019           "%s%s",
3020           track_is_selected (track) ? "* " : "",
3021           track->name);
3022     }
3023 #endif
3024   return track->name;
3025 }
3026 
3027 /**
3028  * Internally called by
3029  * track_set_name_with_action().
3030  */
3031 bool
track_set_name_with_action_full(Track * track,const char * name)3032 track_set_name_with_action_full (
3033   Track *      track,
3034   const char * name)
3035 {
3036   g_return_val_if_fail (IS_TRACK (track), false);
3037 
3038   GError * err = NULL;
3039   bool ret =
3040     tracklist_selections_action_perform_edit_rename (
3041       track, PORT_CONNECTIONS_MGR, name, &err);
3042   if (!ret)
3043     {
3044       HANDLE_ERROR (
3045         err, "%s",
3046         _("Failed to rename track"));
3047       return false;
3048     }
3049   return true;
3050 }
3051 
3052 /**
3053  * Setter to be used by the UI to create an
3054  * undoable action.
3055  */
3056 void
track_set_name_with_action(Track * track,const char * name)3057 track_set_name_with_action (
3058   Track *      track,
3059   const char * name)
3060 {
3061   track_set_name_with_action_full (
3062     track, name);
3063 }
3064 
3065 static void
add_region_if_in_range(Track * track,Position * p1,Position * p2,ZRegion ** regions,int * count,ZRegion * region)3066 add_region_if_in_range (
3067   Track *    track,
3068   Position * p1,
3069   Position * p2,
3070   ZRegion ** regions,
3071   int *      count,
3072   ZRegion *  region)
3073 {
3074   ArrangerObject * r_obj =
3075     (ArrangerObject *) region;
3076 
3077   if (!p1 && !p2)
3078     {
3079       regions[(*count)++] = region;
3080       return;
3081     }
3082 
3083   /* start inside */
3084   if ((position_is_before_or_equal (
3085          p1, &r_obj->pos) &&
3086        position_is_after (
3087          p2, &r_obj->pos)) ||
3088       /* end inside */
3089       (position_is_before_or_equal (
3090          p1, &r_obj->end_pos) &&
3091        position_is_after (
3092          p2, &r_obj->end_pos)) ||
3093       /* start before and end after */
3094       (position_is_before_or_equal (
3095          &r_obj->pos, p1) &&
3096        position_is_after (
3097          &r_obj->end_pos, p2)))
3098     {
3099       regions[(*count)++] = region;
3100     }
3101 }
3102 
3103 /**
3104  * Returns all the regions inside the given range,
3105  * or all the regions if both @ref p1 and @ref p2
3106  * are NULL.
3107  *
3108  * @return The number of regions returned.
3109  */
3110 int
track_get_regions_in_range(Track * track,Position * p1,Position * p2,ZRegion ** regions)3111 track_get_regions_in_range (
3112   Track *    track,
3113   Position * p1,
3114   Position * p2,
3115   ZRegion ** regions)
3116 {
3117   int count = 0;
3118 
3119   if (track->type == TRACK_TYPE_INSTRUMENT ||
3120       track->type == TRACK_TYPE_AUDIO ||
3121       track->type == TRACK_TYPE_MIDI)
3122     {
3123       for (int i = 0; i < track->num_lanes; i++)
3124         {
3125           TrackLane * lane = track->lanes[i];
3126 
3127           for (int j = 0; j < lane->num_regions;
3128                j++)
3129             {
3130               ZRegion * r = lane->regions[j];
3131               add_region_if_in_range (
3132                 track, p1, p2, regions, &count,
3133                 r);
3134             }
3135         }
3136     }
3137   else if (track->type == TRACK_TYPE_CHORD)
3138     {
3139       for (int j = 0; j < track->num_chord_regions;
3140            j++)
3141         {
3142           ZRegion * r = track->chord_regions[j];
3143           add_region_if_in_range (
3144             track, p1, p2, regions, &count, r);
3145         }
3146     }
3147 
3148   AutomationTracklist * atl =
3149     track_get_automation_tracklist (track);
3150   if (atl)
3151     {
3152       for (int i = 0; i < atl->num_ats; i++)
3153         {
3154           AutomationTrack * at = atl->ats[i];
3155 
3156           for (int j = 0; j < at->num_regions; j++)
3157             {
3158               ZRegion * r = at->regions[j];
3159               add_region_if_in_range (
3160                 track, p1, p2, regions, &count, r);
3161             }
3162         }
3163     }
3164 
3165   return count;
3166 }
3167 
3168 /**
3169  * Returns a unique name for a new track based on
3170  * the given name.
3171  */
3172 char *
track_get_unique_name(Track * track_to_skip,const char * _name)3173 track_get_unique_name (
3174   Track *      track_to_skip,
3175   const char * _name)
3176 {
3177   char name[strlen (_name) + 1];
3178   strcpy (name, _name);
3179   while (!tracklist_track_name_is_unique (
3180             TRACKLIST, name, track_to_skip))
3181     {
3182       char name_without_num[780];
3183       int ending_num =
3184         string_get_int_after_last_space (
3185           name, name_without_num);
3186       if (ending_num == -1)
3187         {
3188           /* append 1 at the end */
3189           strcat (name, " 1");
3190         }
3191       else
3192         {
3193           /* add 1 to the number at the end */
3194           sprintf (
3195             name, "%s %d",
3196             name_without_num, ending_num + 1);
3197         }
3198     }
3199 
3200   return g_strdup (name);
3201 }
3202 
3203 /**
3204  * Setter for the track name.
3205  *
3206  * If a track with that name already exists, it
3207  * adds a number at the end.
3208  *
3209  * Must only be called from the GTK thread.
3210  */
3211 void
track_set_name(Track * self,const char * name,bool pub_events)3212 track_set_name (
3213   Track *      self,
3214   const char * name,
3215   bool         pub_events)
3216 {
3217   char * new_name =
3218     track_get_unique_name (self, name);
3219   g_return_if_fail (new_name);
3220 
3221   unsigned int old_hash =
3222     self->name ? track_get_name_hash (self) : 0;
3223 
3224   if (self->name)
3225     {
3226       old_hash = track_get_name_hash (self);
3227       g_free (self->name);
3228     }
3229   self->name = new_name;
3230 
3231   unsigned int new_hash =
3232     track_get_name_hash (self);
3233 
3234   if (old_hash != 0)
3235     {
3236       for (int i = 0; i < self->num_lanes; i++)
3237         {
3238           track_lane_update_track_name_hash (
3239             self->lanes[i]);
3240         }
3241       automation_tracklist_update_track_name_hash (
3242         &self->automation_tracklist, self);
3243 
3244       for (int i = 0; i < self->num_markers; i++)
3245         {
3246           marker_set_track_name_hash (
3247             self->markers[i], new_hash);
3248         }
3249 
3250       for (int i = 0; i < self->num_chord_regions; i++)
3251         {
3252           ZRegion * r = self->chord_regions[i];
3253           r->id.track_name_hash = new_hash;
3254           region_update_identifier (r);
3255         }
3256 
3257       self->processor->track = self;
3258 
3259       /* update sends */
3260       if (self->channel)
3261         channel_update_track_name_hash (
3262           self->channel, old_hash, new_hash);
3263 
3264       GPtrArray * ports = g_ptr_array_new ();
3265       track_append_ports (self, ports, true);
3266       for (size_t i = 0; i < ports->len; i++)
3267         {
3268           Port * port = g_ptr_array_index (ports, i);
3269           g_return_if_fail (
3270             IS_PORT_AND_NONNULL (port));
3271           port_update_track_name_hash (
3272             port, self, new_hash);
3273 
3274           if (port_is_exposed_to_backend (
3275                 port))
3276             {
3277               port_rename_backend (port);
3278             }
3279         }
3280       object_free_w_func_and_null (
3281         g_ptr_array_unref, ports);
3282     }
3283 
3284   if (track_is_in_active_project (self))
3285     {
3286       /* update children */
3287       track_update_children (self);
3288 
3289       /* update mixer selections */
3290       if (MIXER_SELECTIONS->has_any &&
3291           MIXER_SELECTIONS->track_name_hash ==
3292             old_hash)
3293         {
3294           MIXER_SELECTIONS->track_name_hash =
3295             new_hash;
3296         }
3297 
3298       /* change the clip editor region */
3299       if (CLIP_EDITOR->has_region &&
3300           CLIP_EDITOR->region_id.track_name_hash ==
3301             old_hash)
3302         {
3303           g_message (
3304             "updating clip editor region track to "
3305             "%s",
3306             self->name);
3307           CLIP_EDITOR->region_id.track_name_hash =
3308             new_hash;
3309         }
3310     }
3311 
3312   if (pub_events)
3313     {
3314       EVENTS_PUSH (
3315         ET_TRACK_NAME_CHANGED, self);
3316     }
3317 }
3318 
3319 void
track_activate_all_plugins(Track * track,bool activate)3320 track_activate_all_plugins (
3321   Track * track,
3322   bool    activate)
3323 {
3324   if (!track_type_has_channel (track->type))
3325     return;
3326 
3327   Channel * ch = track_get_channel (track);
3328   g_return_if_fail (ch);
3329 
3330   for (int i = 0; i < STRIP_SIZE * 2 + 1; i++)
3331     {
3332       Plugin * pl = NULL;
3333       if (i < STRIP_SIZE)
3334         pl = track->channel->midi_fx[i];
3335       else if (i == STRIP_SIZE)
3336         pl = track->channel->instrument;
3337       else
3338         pl =
3339           track->channel->inserts[
3340             i - (STRIP_SIZE + 1)];
3341 
3342       if (!pl)
3343         continue;
3344 
3345       if (!pl->instantiated &&
3346           !pl->instantiation_failed)
3347         {
3348           GError * err = NULL;
3349           int ret =
3350             plugin_instantiate (pl, NULL, &err);
3351           if (ret != 0)
3352             {
3353               HANDLE_ERROR (
3354                 err, "%s",
3355                 _("Failed to instantiate plugin"));
3356             }
3357         }
3358 
3359       if (pl->instantiated)
3360         {
3361           plugin_activate (pl, activate);
3362         }
3363     }
3364 }
3365 
3366 /**
3367  * Comment setter.
3368  *
3369  * @note This creates an undoable action.
3370  */
3371 void
track_comment_setter(void * track,const char * comment)3372 track_comment_setter (
3373   void *        track,
3374   const char *  comment)
3375 {
3376   Track * self = (Track *) track;
3377   g_return_if_fail (IS_TRACK (self));
3378 
3379   track_set_comment (self, comment, F_UNDOABLE);
3380 }
3381 
3382 /**
3383  * @param undoable Create an undable action.
3384  */
3385 void
track_set_comment(Track * self,const char * comment,bool undoable)3386 track_set_comment (
3387   Track *       self,
3388   const char *  comment,
3389   bool          undoable)
3390 {
3391   if (undoable)
3392     {
3393       track_select (
3394         self, F_SELECT, F_EXCLUSIVE,
3395         F_NO_PUBLISH_EVENTS);
3396 
3397       GError * err = NULL;
3398       bool ret =
3399         tracklist_selections_action_perform_edit_comment (
3400           TRACKLIST_SELECTIONS, comment, &err);
3401       if (!ret)
3402         {
3403           HANDLE_ERROR (
3404             err, "%s",
3405             _("Cannot set track comment"));
3406           return;
3407         }
3408     }
3409   else
3410     {
3411       g_free_and_null (self->comment);
3412       self->comment = g_strdup (comment);
3413     }
3414 }
3415 
3416 /**
3417  * Comment getter.
3418  */
3419 const char *
track_get_comment(void * track)3420 track_get_comment (
3421   void *  track)
3422 {
3423   Track * self = (Track *) track;
3424   g_return_val_if_fail (IS_TRACK (self), NULL);
3425 
3426   return self->comment;
3427 }
3428 
3429 /**
3430  * Sets the track color.
3431  */
3432 void
track_set_color(Track * self,const GdkRGBA * color,bool undoable,bool fire_events)3433 track_set_color (
3434   Track *         self,
3435   const GdkRGBA * color,
3436   bool            undoable,
3437   bool            fire_events)
3438 {
3439   if (undoable)
3440     {
3441       track_select (
3442         self, F_SELECT, F_EXCLUSIVE,
3443         F_NO_PUBLISH_EVENTS);
3444 
3445       GError * err = NULL;
3446       bool ret =
3447         tracklist_selections_action_perform_edit_color (
3448           TRACKLIST_SELECTIONS, color, &err);
3449       if (!ret)
3450         {
3451           HANDLE_ERROR (
3452             err, "%s",
3453             _("Cannot set track comment"));
3454           return;
3455         }
3456     }
3457   else
3458     {
3459       self->color = *color;
3460 
3461       if (fire_events)
3462         {
3463           EVENTS_PUSH (
3464             ET_TRACK_COLOR_CHANGED, self);
3465         }
3466     }
3467 }
3468 
3469 /**
3470  * Sets the track icon.
3471  */
3472 void
track_set_icon(Track * self,const char * icon_name,bool undoable,bool fire_events)3473 track_set_icon (
3474   Track *      self,
3475   const char * icon_name,
3476   bool         undoable,
3477   bool         fire_events)
3478 {
3479   if (undoable)
3480     {
3481       track_select (
3482         self, F_SELECT, F_EXCLUSIVE,
3483         F_NO_PUBLISH_EVENTS);
3484 
3485       GError * err = NULL;
3486       bool ret =
3487         tracklist_selections_action_perform_edit_icon (
3488           TRACKLIST_SELECTIONS, icon_name, &err);
3489       if (!ret)
3490         {
3491           HANDLE_ERROR (
3492             err, "%s",
3493             _("Cannot set track icon"));
3494           return;
3495         }
3496     }
3497   else
3498     {
3499       self->icon_name = g_strdup (icon_name);
3500 
3501       if (fire_events)
3502         {
3503           /* TODO */
3504         }
3505     }
3506 }
3507 
3508 TrackType
track_type_get_from_string(const char * str)3509 track_type_get_from_string (
3510   const char * str)
3511 {
3512   for (int i = 0; i <= TRACK_TYPE_MIDI_GROUP; i++)
3513     {
3514       if (string_is_equal (
3515             track_type_strings[i].str, str))
3516         {
3517           return (TrackType) i;
3518         }
3519     }
3520   g_return_val_if_reached (-1);
3521 }
3522 
3523 /**
3524  * Returns the plugin at the given slot, if any.
3525  *
3526  * @param slot The slot (ignored if instrument is
3527  *   selected.
3528  */
3529 Plugin *
track_get_plugin_at_slot(Track * self,PluginSlotType slot_type,int slot)3530 track_get_plugin_at_slot (
3531   Track *           self,
3532   PluginSlotType    slot_type,
3533   int               slot)
3534 {
3535   switch (slot_type)
3536     {
3537     case PLUGIN_SLOT_MIDI_FX:
3538       return self->channel->midi_fx[slot];
3539     case PLUGIN_SLOT_INSTRUMENT:
3540       return self->channel->instrument;
3541     case PLUGIN_SLOT_INSERT:
3542       return self->channel->inserts[slot];
3543     case PLUGIN_SLOT_MODULATOR:
3544       if (self->modulators &&
3545           slot < self->num_modulators)
3546         {
3547           return self->modulators[slot];
3548         }
3549       break;
3550     default:
3551       g_return_val_if_reached (NULL);
3552       break;
3553     }
3554 
3555   return NULL;
3556 }
3557 
3558 /**
3559  * Marks the track for bouncing.
3560  *
3561  * @param mark_children Whether to mark all
3562  *   children tracks as well. Used when exporting
3563  *   stems on the specific track stem only.
3564  * @param mark_parents Whether to mark all parent
3565  *   tracks as well.
3566  */
3567 void
track_mark_for_bounce(Track * self,bool bounce,bool mark_regions,bool mark_children,bool mark_parents)3568 track_mark_for_bounce (
3569   Track * self,
3570   bool    bounce,
3571   bool    mark_regions,
3572   bool    mark_children,
3573   bool    mark_parents)
3574 {
3575   if (!track_type_has_channel (self->type))
3576     {
3577       return;
3578     }
3579 
3580   g_debug (
3581     "marking %s for bounce %d, mark regions %d",
3582     self->name, bounce, mark_regions);
3583 
3584   self->bounce = bounce;
3585 
3586   /* bounce directly to master if not marking
3587    * parents*/
3588   self->bounce_to_master = !mark_parents;
3589 
3590   if (mark_regions)
3591     {
3592       for (int j = 0; j < self->num_lanes; j++)
3593         {
3594           TrackLane * lane = self->lanes[j];
3595 
3596           for (int k = 0; k < lane->num_regions;
3597                k++)
3598             {
3599               ZRegion * r = lane->regions[k];
3600               if (r->id.type != REGION_TYPE_MIDI &&
3601                   r->id.type != REGION_TYPE_AUDIO)
3602                 continue;
3603 
3604               r->bounce = bounce;
3605             }
3606         }
3607     }
3608 
3609   /* also mark all parents */
3610   g_return_if_fail (
3611     track_type_has_channel (self->type));
3612   Track * direct_out =
3613     channel_get_output_track (self->channel);
3614   if (direct_out && mark_parents)
3615     {
3616       track_mark_for_bounce (
3617         direct_out, bounce, F_NO_MARK_REGIONS,
3618         F_NO_MARK_CHILDREN, F_MARK_PARENTS);
3619     }
3620 
3621   if (mark_children)
3622     {
3623       for (int i = 0; i < self->num_children; i++)
3624         {
3625           Track * child =
3626             tracklist_find_track_by_name_hash (
3627               TRACKLIST, self->children[i]);
3628 
3629           track_mark_for_bounce (
3630             child, bounce, mark_regions,
3631             F_MARK_CHILDREN, F_NO_MARK_PARENTS);
3632         }
3633     }
3634 }
3635 
3636 /**
3637  * Appends all channel ports and optionally
3638  * plugin ports to the array.
3639  */
3640 void
track_append_ports(Track * self,GPtrArray * ports,bool include_plugins)3641 track_append_ports (
3642   Track *     self,
3643   GPtrArray * ports,
3644   bool        include_plugins)
3645 {
3646   if (track_type_has_channel (self->type))
3647     {
3648       g_return_if_fail (self->channel);
3649       channel_append_ports (
3650         self->channel, ports, include_plugins);
3651       track_processor_append_ports (
3652         self->processor, ports);
3653     }
3654 
3655 #define _ADD(port) \
3656   g_warn_if_fail (port); \
3657   g_ptr_array_add (ports, port)
3658 
3659   if (track_type_can_record (self->type))
3660     {
3661       _ADD (self->recording);
3662     }
3663 
3664   if (self->type == TRACK_TYPE_TEMPO)
3665     {
3666       /* add bpm/time sig ports */
3667       _ADD (self->bpm_port);
3668       _ADD (self->beats_per_bar_port);
3669       _ADD (self->beat_unit_port);
3670     }
3671   else if (self->type == TRACK_TYPE_MODULATOR)
3672     {
3673       for (int j = 0;
3674            j < self->num_modulators; j++)
3675         {
3676           Plugin * pl = self->modulators[j];
3677 
3678           plugin_append_ports (pl, ports);
3679         }
3680       for (int j = 0;
3681            j < self->num_modulator_macros; j++)
3682         {
3683           _ADD (self->modulator_macros[j]->macro);
3684           _ADD (self->modulator_macros[j]->cv_in);
3685           _ADD (self->modulator_macros[j]->cv_out);
3686         }
3687     }
3688 
3689 #undef _ADD
3690 }
3691 
3692 bool
track_is_enabled(Track * self)3693 track_is_enabled (
3694   Track * self)
3695 {
3696   return self->enabled;
3697 }
3698 
3699 void
track_set_enabled(Track * self,bool enabled,bool trigger_undo,bool auto_select,bool fire_events)3700 track_set_enabled (
3701   Track * self,
3702   bool    enabled,
3703   bool    trigger_undo,
3704   bool    auto_select,
3705   bool    fire_events)
3706 {
3707   self->enabled = enabled;
3708 
3709   g_message (
3710     "Setting track %s enabled (%d)",
3711     self->name, enabled);
3712   if (auto_select)
3713     {
3714       track_select (
3715         self, F_SELECT, F_EXCLUSIVE, fire_events);
3716     }
3717 
3718   if (trigger_undo)
3719     {
3720       GError * err = NULL;
3721       bool ret =
3722         tracklist_selections_action_perform_edit_enable (
3723           TRACKLIST_SELECTIONS, enabled, &err);
3724       if (!ret)
3725         {
3726           HANDLE_ERROR (
3727             err, "%s",
3728             _("Cannot set track enabled"));
3729           return;
3730         }
3731     }
3732   else
3733     {
3734       self->enabled = enabled;
3735 
3736       if (fire_events)
3737         {
3738           EVENTS_PUSH (
3739             ET_TRACK_STATE_CHANGED, self);
3740         }
3741     }
3742 }
3743 
3744 static void
get_end_pos_from_objs(ArrangerObject ** objs,int num_objs,Position * pos)3745 get_end_pos_from_objs (
3746   ArrangerObject ** objs,
3747   int               num_objs,
3748   Position *        pos)
3749 {
3750   for (int i = 0; i < num_objs; i++)
3751     {
3752       ArrangerObject * obj = objs[i];
3753       Position end_pos;
3754       if (arranger_object_type_has_length (
3755             obj->type))
3756         {
3757           arranger_object_get_end_pos (
3758             obj, &end_pos);
3759         }
3760       else
3761         {
3762           arranger_object_get_pos (obj, &end_pos);
3763         }
3764       if (position_is_after (&end_pos, pos))
3765         {
3766           position_set_to_pos (pos, &end_pos);
3767         }
3768     }
3769 }
3770 
3771 void
track_get_total_bars(Track * self,int * total_bars)3772 track_get_total_bars (
3773   Track * self,
3774   int *   total_bars)
3775 {
3776   Position pos;
3777   position_from_bars (&pos, *total_bars);
3778 
3779   for (int i = 0; i < self->num_lanes; i++)
3780     {
3781       TrackLane * lane = self->lanes[i];
3782       get_end_pos_from_objs (
3783         (ArrangerObject **) lane->regions,
3784         lane->num_regions, &pos);
3785     }
3786 
3787   get_end_pos_from_objs (
3788     (ArrangerObject **) self->chord_regions,
3789     self->num_chord_regions,
3790     &pos);
3791   get_end_pos_from_objs (
3792     (ArrangerObject **) self->scales,
3793     self->num_scales, &pos);
3794   get_end_pos_from_objs (
3795     (ArrangerObject **) self->markers,
3796     self->num_markers, &pos);
3797 
3798   int track_total_bars =
3799     position_get_total_bars (&pos, true);
3800   if (track_total_bars > *total_bars)
3801     {
3802       *total_bars = track_total_bars;
3803     }
3804 }
3805 
3806 Track *
track_create_with_action(TrackType type,PluginSetting * pl_setting,SupportedFile * file_descr,Position * pos,int index,int num_tracks,GError ** error)3807 track_create_with_action (
3808   TrackType       type,
3809   PluginSetting * pl_setting,
3810   SupportedFile * file_descr,
3811   Position *      pos,
3812   int             index,
3813   int             num_tracks,
3814   GError **       error)
3815 {
3816   GError * err = NULL;
3817   bool ret =
3818     tracklist_selections_action_perform_create (
3819       type, pl_setting, file_descr,
3820       index, pos, num_tracks, -1, &err);
3821   if (!ret)
3822     {
3823       PROPAGATE_PREFIXED_ERROR (
3824         error, err, "%s",
3825         _("Failed to create track"));
3826       return NULL;
3827     }
3828 
3829   Track * track =
3830     tracklist_get_track (TRACKLIST, index);
3831   g_return_val_if_fail (
3832     IS_TRACK_AND_NONNULL (track), NULL);
3833   z_return_val_if_fail_cmp (
3834     track->type, ==, type, NULL);
3835   z_return_val_if_fail_cmp (
3836     track->pos, ==, index, NULL);
3837   return track;
3838 }
3839 
3840 unsigned int
track_get_name_hash(Track * self)3841 track_get_name_hash (
3842   Track * self)
3843 {
3844   return g_str_hash (self->name);
3845 }
3846 
3847 /**
3848  * Removes the AutomationTrack's associated with
3849  * this channel from the AutomationTracklist in the
3850  * corresponding Track.
3851  */
3852 static void
remove_ats_from_automation_tracklist(Track * track,bool fire_events)3853 remove_ats_from_automation_tracklist (
3854   Track * track,
3855   bool    fire_events)
3856 {
3857   AutomationTracklist * atl =
3858     track_get_automation_tracklist (track);
3859   g_return_if_fail (atl);
3860 
3861   for (int i = 0; i < atl->num_ats; i++)
3862     {
3863       AutomationTrack * at = atl->ats[i];
3864       if (at->port_id.flags &
3865             PORT_FLAG_CHANNEL_FADER ||
3866           at->port_id.flags &
3867             PORT_FLAG_FADER_MUTE ||
3868           at->port_id.flags &
3869             PORT_FLAG_STEREO_BALANCE)
3870         {
3871           automation_tracklist_remove_at (
3872             atl, at, F_NO_FREE, fire_events);
3873         }
3874     }
3875 }
3876 
3877 void
track_set_caches(Track * self)3878 track_set_caches (
3879   Track * self)
3880 {
3881   AutomationTracklist * atl =
3882     track_get_automation_tracklist (self);
3883 
3884   /* update name hash */
3885   self->name_hash = track_get_name_hash (self);
3886 
3887   if (atl)
3888     automation_tracklist_set_caches (atl);
3889 }
3890 
3891 /**
3892  * Wrapper for each track type.
3893  */
3894 void
track_free(Track * self)3895 track_free (Track * self)
3896 {
3897   g_debug ("freeing track '%s' (pos %d)...",
3898     self->name, self->pos);
3899 
3900   if (self->widget &&
3901       GTK_IS_WIDGET (self->widget))
3902     gtk_widget_destroy (
3903       GTK_WIDGET (self->widget));
3904 
3905   /* remove regions */
3906   for (int i = 0; i < self->num_lanes; i++)
3907     {
3908       object_free_w_func_and_null (
3909         track_lane_free, self->lanes[i]);
3910     }
3911 
3912   /* remove automation points, curves, tracks,
3913    * lanes*/
3914   automation_tracklist_free_members (
3915     &self->automation_tracklist);
3916 
3917   /* remove chords */
3918   for (int i = 0; i < self->num_chord_regions; i++)
3919     {
3920       arranger_object_free (
3921         (ArrangerObject *) self->chord_regions[i]);
3922       self->chord_regions[i] = NULL;
3923     }
3924 
3925   if (self->bpm_port)
3926     {
3927       port_disconnect_all (self->bpm_port);
3928       object_free_w_func_and_null (
3929         port_free, self->bpm_port);
3930     }
3931   if (self->beats_per_bar_port)
3932     {
3933       port_disconnect_all (self->beats_per_bar_port);
3934       object_free_w_func_and_null (
3935         port_free, self->beats_per_bar_port);
3936     }
3937   if (self->beats_per_bar_port)
3938     {
3939       port_disconnect_all (self->beat_unit_port);
3940       object_free_w_func_and_null (
3941         port_free, self->beat_unit_port);
3942     }
3943 
3944 #undef _FREE_TRACK
3945 
3946   if (self->channel)
3947     {
3948       /* remove automation tracks - they are
3949        * already free'd by now */
3950       remove_ats_from_automation_tracklist (
3951         self, F_NO_PUBLISH_EVENTS);
3952       object_free_w_func_and_null (
3953         track_processor_free, self->processor);
3954       object_free_w_func_and_null (
3955         channel_free, self->channel);
3956     }
3957 
3958   g_free_and_null (self->name);
3959   g_free_and_null (self->comment);
3960   g_free_and_null (self->icon_name);
3961 
3962   for (int i = 0; i < self->num_modulator_macros;
3963        i++)
3964     {
3965       modulator_macro_processor_free (
3966         self->modulator_macros[i]);
3967     }
3968 
3969   object_zero_and_free (self);
3970 
3971   g_debug ("done freeing track");
3972 }
3973