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