3 * Copyright (C) 2010 Adam Williams <broadcast at earthling dot net>
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 #include "automation.h"
25 #include "bcsignals.h"
29 #include "edlsession.h"
34 #include "localsession.h"
37 #include "mainsession.h"
38 #include "pluginserver.h"
39 #include "pluginset.h"
42 #include "trackcanvas.h"
44 #include "trackscroll.h"
45 #include "transition.h"
46 #include "transportque.h"
50 int Tracks::blade(double position)
52 for( Track *track=first; track!=0; track=track->next ) {
53 if( !track->is_armed() ) continue;
54 track->blade(position);
59 int Tracks::clear(double start, double end, int clear_plugins, int edit_autos)
63 for(current_track = first;
65 current_track = current_track->next)
67 if(current_track->is_armed())
69 current_track->clear(start,
73 clear_plugins, // edit_plugins
81 void Tracks::clear_automation(double selectionstart, double selectionend)
85 for(current_track = first; current_track; current_track = current_track->next)
87 if(current_track->is_armed())
89 current_track->clear_automation(selectionstart,
97 void Tracks::clear_transitions(double start, double end)
99 for(Track *current_track = first;
101 current_track = current_track->next)
103 if(current_track->is_armed())
105 int64_t start_units = current_track->to_units(start, 0);
106 int64_t end_units = current_track->to_units(end, 0);
108 for(Edit *current_edit = current_track->edits->first;
110 current_edit = current_edit->next)
112 if(current_edit->startproject >= start_units &&
113 current_edit->startproject < end_units &&
114 current_edit->transition)
116 current_edit->detach_transition();
123 int Tracks::clear_hard_edges(double start, double end)
125 for( Track *track=first; track; track=track->next ) {
126 if( !track->is_armed() ) continue;
127 int64_t start_units = track->to_units(start, 0);
128 int64_t end_units = track->to_units(end, 0);
130 for( Edit *edit=track->edits->first; edit; edit=edit->next ) {
131 int64_t pos = edit->startproject;
132 if( pos > end_units ) break;
133 if( pos >= start_units ) {
136 edit->previous->hard_right = 0;
139 if( pos > end_units ) break;
140 if( pos >= start_units ) {
141 edit->hard_right = 0;
143 edit->next->hard_left = 0;
150 void Tracks::shuffle_edits(double start, double end)
152 // This doesn't affect automation or effects
153 // Labels follow the first track.
155 for(Track *current_track = first;
157 current_track = current_track->next)
159 if(current_track->is_armed())
161 current_track->shuffle_edits(start, end, first_track);
168 void Tracks::reverse_edits(double start, double end)
170 // This doesn't affect automation or effects
171 // Labels follow the first track.
173 for(Track *current_track = first;
175 current_track = current_track->next)
177 if(current_track->is_armed())
179 current_track->reverse_edits(start, end, first_track);
186 void Tracks::align_edits(double start, double end)
188 // This doesn't affect automation or effects
189 Track *master_track = 0;
190 for( Track *track=first; track; track=track->next ) {
191 if( !track->is_armed() ) continue;
193 master_track = track;
195 track->align_edits(start, end, master_track);
199 void Tracks::set_edit_length(double start, double end, double length)
202 for(Track *current_track = first;
204 current_track = current_track->next)
206 if(current_track->is_armed())
208 #define USE_FLOATING_LENGTHS
210 #ifdef USE_FLOATING_LENGTHS
213 // The first edit anchors the length offsets.
214 // Round edits up & down so they end where they would if they all had floating point lengths.
215 //int first_edit = 1;
216 int64_t start_units = current_track->to_units(start, 0);
217 int64_t end_units = current_track->to_units(end, 0);
218 // Total time of edits accumulated, in track units
219 int64_t total_units = 0;
220 // Number of length offsets added so far
221 int total_lengths = 0;
223 for(Edit *current_edit = current_track->edits->last;
225 current_edit = current_edit->previous)
227 if(current_edit->startproject >= start_units &&
228 current_edit->startproject + current_edit->length <= end_units)
230 // Calculate true length based on number of length offsets & total time
231 double end_time = (1 + total_lengths) * length;
232 int64_t length_units = current_track->to_units(end_time, 0) -
234 if(length_units < 1) length_units = 1;
235 //printf("Tracks::set_edit_length %d %f %f\n", __LINE__,
236 // end_time, current_track->from_units(total_units));
237 total_units += length_units;
239 // Go in using the edit handle interface
240 int64_t starting_length = current_edit->length;
242 current_edit->shift_end(MOVE_RIPPLE,
243 current_edit->startproject + length_units,
244 current_edit->startproject + current_edit->length,
246 edl->session->autos_follow_edits,
247 edl->session->plugins_follow_edits,
250 int64_t ending_length = current_edit->length;
252 if(edl->session->labels_follow_edits && first_track)
254 // printf("Tracks::set_edit_length %d %f %f\n",
256 // current_track->from_units(current_edit->startproject + starting_length),
257 // current_track->from_units(current_edit->startproject + ending_length));
258 edl->labels->modify_handles(
259 current_track->from_units(current_edit->startproject + starting_length),
260 current_track->from_units(current_edit->startproject + ending_length),
272 #else // USE_FLOATING_LENGTHS
274 // The first edit anchors the length offsets.
275 // The idea was to round edits up & down so they end where they should
276 // if they all had floating point lengths. It's easier just to make sure the framerate
277 // is divisible by the required length.
278 // int first_edit = 1;
279 int64_t start_units = current_track->to_units(start, 0);
280 int64_t end_units = current_track->to_units(end, 0);
281 int64_t length_units = current_track->to_units(length, 1);
282 // Starting time of the length offsets in seconds
283 // double start_time = 0;
284 // Number of length offsets added so far
285 // int total_lengths = 0;
287 for(Edit *current_edit = current_track->edits->last;
289 current_edit = current_edit->previous)
291 if(current_edit->startproject >= start_units &&
292 current_edit->startproject + current_edit->length <= end_units)
294 // Calculate starting time of length offsets
297 // start_time = current_track->from_units(current_edit->startproject);
300 // Calculate true length based on number of length offsets
301 // double end_time = start_time + (1 + total_lengths) * length;
302 // int64_t length_units = current_track->to_units(end_time, 0) -
303 // current_edit->startproject;
304 // if(length_units < 1) length_units = 1;
306 // Go in using the edit handle interface
307 int64_t starting_length = current_edit->length;
309 current_edit->shift_end(MOVE_RIPPLE,
310 current_edit->startproject + length_units,
311 current_edit->startproject + current_edit->length,
313 edl->session->autos_follow_edits,
314 edl->session->plugins_follow_edits,
317 int64_t ending_length = current_edit->length;
319 if(edl->session->labels_follow_edits && first_track) {
320 // printf("Tracks::set_edit_length %d %f %f\n", __LINE__,
321 // current_track->from_units(current_edit->startproject + starting_length),
322 // current_track->from_units(current_edit->startproject + ending_length));
323 edl->labels->modify_handles(
324 current_track->from_units(current_edit->startproject + starting_length),
325 current_track->from_units(current_edit->startproject + ending_length),
334 #endif // !USE_FLOATING_LENGTHS
341 void Tracks::set_transition_length(double start, double end, double length)
343 for(Track *current_track = first;
345 current_track = current_track->next)
347 if(current_track->is_armed())
349 int64_t start_units = current_track->to_units(start, 0);
350 int64_t end_units = current_track->to_units(end, 0);
352 for(Edit *current_edit = current_track->edits->first;
354 current_edit = current_edit->next)
356 if(current_edit->startproject >= start_units &&
357 current_edit->startproject < end_units &&
358 current_edit->transition)
360 current_edit->transition->length =
361 current_track->to_units(length, 1);
362 if( current_edit == current_track->edits->last &&
363 current_edit->silence() ) {
364 current_edit->length = current_edit->transition->length;
372 void Tracks::set_transition_length(Transition *transition, double length)
374 // Must verify existence of transition
376 if( !transition ) return;
377 for( Track *track=first; track && !found; track=track->next ) {
378 for( Edit *edit=track->edits->first; edit && !found; edit = edit->next ) {
379 if( edit->transition == transition ) {
380 transition->length = track->to_units(length, 1);
381 if( edit == track->edits->last && edit->silence() ) {
382 edit->length = edit->transition->length;
389 if( edl->session->gang_tracks == GANG_NONE ) return;
390 Track *track = transition->edit->track;
391 double pos = track->from_units(transition->edit->startproject);
392 Track *current = edl->tracks->first;
393 for( ; current; current=current->next ) {
394 if( current == track ) continue;
395 if( current->data_type != track->data_type ) continue;
396 if( !current->armed_gang(track) ) continue;
397 int64_t track_pos = current->to_units(pos, 1);
398 Edit *edit = current->edits->editof(track_pos, PLAY_FORWARD, 0);
399 if( !edit || !edit->transition ) continue;
400 double edit_pos = track->from_units(edit->startproject);
401 if( !edl->equivalent(pos, edit_pos) ) continue;
402 // modify gang same transitions at same position
403 if( edit->transition->Plugin::identical(transition) ) {
404 edit->transition->length = transition->length;
406 if( edit == track->edits->last && edit->silence() ) {
407 edit->length = edit->transition->length;
412 void Tracks::paste_transitions(double start, double end, int track_type, char* title)
415 for( Track *track=first; track; track=track->next ) {
416 if( !track->is_armed() || track->data_type != track_type ) continue;
417 for( Edit *edit=track->edits->first; edit; edit=edit->next ) {
418 if( !edit->is_selected ) continue;
419 edit->insert_transition(title);
424 clear_selected_edits();
428 for( Track *track=first; track; track=track->next ) {
429 if( !track->is_armed() || track->data_type != track_type ) continue;
430 int64_t start_units = track->to_units(start, 0);
431 int64_t end_units = track->to_units(end, 0);
432 if( start_units == end_units ) {
433 for( Edit *edit = track->edits->first; edit; edit = edit->next) {
434 int64_t edit_start = edit->startproject;
435 int64_t edit_end = edit_start + edit->length;
436 if( edit_start > start_units ) continue;
437 if( start_units == track->edits->length() ) {
438 double length = edl->session->default_transition_length;
439 int64_t units = track->to_units(length, 1);
440 edit = track->edits->
441 create_silence(start_units, start_units+units);
443 else if( start_units >= edit_end ) continue;
444 edit->insert_transition(title);
448 for( Edit *edit=track->edits->first; edit; edit=edit->next) {
449 int64_t edit_start = edit->startproject;
450 if( !edit_start ) continue;
451 if( edit_start >= start_units && edit_start < end_units ) {
452 edit->insert_transition(title);
459 void Tracks::set_automation_mode(double selectionstart,
463 Track* current_track;
465 for(current_track = first; current_track; current_track = current_track->next)
467 if(current_track->is_armed())
469 current_track->set_automation_mode(selectionstart,
476 int Tracks::clear_default_keyframe()
478 for(Track *current = first; current; current = NEXT)
480 if(current->is_armed())
481 current->clear_automation(0, 0, 0, 1);
486 int Tracks::clear_handle(double start,
488 double &longest_distance,
493 Track* current_track;
496 for(current_track = first; current_track; current_track = current_track->next)
498 if(current_track->is_armed())
500 current_track->clear_handle(start,
506 if(distance > longest_distance) longest_distance = distance;
513 int Tracks::copy_automation(double selectionstart,
519 // called by MWindow::copy_automation for copying automation alone
520 Track* current_track;
522 file->tag.set_title("AUTO_CLIPBOARD");
523 file->tag.set_property("LENGTH", selectionend - selectionstart);
524 file->tag.set_property("FRAMERATE", edl->session->frame_rate);
525 file->tag.set_property("SAMPLERATE", edl->session->sample_rate);
527 file->append_newline();
528 file->append_newline();
530 for(current_track = first;
532 current_track = current_track->next)
534 if(current_track->is_armed())
536 current_track->copy_automation(selectionstart,
544 file->tag.set_title("/AUTO_CLIPBOARD");
546 file->append_newline();
547 file->terminate_string();
551 // int Tracks::copy_default_keyframe(FileXML *file)
553 // copy_automation(0, 0, file, 1, 0);
557 int Tracks::delete_tracks()
559 int total_deleted = 0;
561 int gang = edl->session->gang_tracks != GANG_NONE ? 1 : 0;
565 for( Track* track=first, *nxt=0; done && track; track=nxt ) {
568 while( nxt && !nxt->master ) nxt = nxt->next;
570 if( !track->is_armed() ) continue;
575 return total_deleted;
578 void Tracks::move_edits(ArrayList<Edit*> *in_edits, Track *track, double position,
579 int edit_labels, int edit_plugins, int edit_autos, int mode)
581 // have to make a copy, optimize kills edits
582 ArrayList<Edit*> edits;
583 for( int i=0; i<in_edits->size(); ++i ) {
584 Edit *edit = in_edits->get(i);
585 Edit *new_edit = new Edit(edit->edl, edit->track);
586 new_edit->copy_from(edit);
587 edits.append(new_edit);
590 int current_aedit = 0, current_vedit = 0;
591 //printf("Tracks::move_edits 1\n");
592 for( Track *dest_track=track; dest_track; dest_track=dest_track->next ) {
593 if( !dest_track->is_armed() ) continue;
594 // Need a local copy of the source edit since the original source edit may
595 // change in the editing operation.
597 Edit *source_edit = 0;
598 Track *clip_track = 0;
599 switch( dest_track->data_type ) {
601 while( current_aedit < edits.size() ) {
602 Edit *edit = edits[current_aedit++];
603 if( edit->track->data_type == TRACK_AUDIO ) {
605 ATrack *atrack = new ATrack(dest_track->edl, 0);
606 atrack->create_objects();
613 while( current_vedit < edits.size() ) {
614 Edit *edit = edits[current_vedit++];
615 if( edit->track->data_type == TRACK_VIDEO ) {
617 VTrack *vtrack = new VTrack(dest_track->edl, 0);
618 vtrack->create_objects();
625 if( !source_edit ) continue;
627 Track *source_track = source_edit->track;
628 int64_t start = source_edit->startproject;
629 int64_t length = source_edit->length, end = start + length;
630 double source_start = source_track->from_units(start);
631 double source_end = source_track->from_units(start+length);
632 double len = source_end - source_start;
633 double dest_start = position;
634 double dest_end = dest_start + len;
636 if( edit_labels && dest_track == track ) {
638 Labels labels(0, "LABELS");
639 source_edit->edl->labels->copy(source_start, source_end, &label_xml);
640 source_edit->edl->labels->clear(source_start, source_end, mode);
641 if( !label_xml.read_tag() )
642 labels.load(&label_xml, LOAD_ALL);
643 double pos = dest_start;
644 if( mode && source_start < dest_start ) pos -= len;
645 edl->labels->insert_labels(&labels, pos, len, mode);
650 source_track->copy(COPY_TRACKS, source_start, source_end, &track_xml, "");
651 if( !track_xml.read_tag() )
652 clip_track->load(&track_xml, 0, LOAD_ALL);
654 if( !mode ) { // mute and overwrite
655 source_track->clear(start, end, 1, 0,
656 edit_plugins, edit_autos, 0);
657 source_track->edits->paste_silence(start, end);
659 source_track->shift_keyframes(start, length);
661 int n = source_track->plugin_set.size();
662 if( n > 0 ) dest_track->expand_view = 1;
663 for( int k=0; k<n; ++k )
664 source_track->plugin_set[k]->paste_silence(start, end, 1);
666 dest_track->clear(dest_start, dest_end, 1, 0,
667 edit_plugins, edit_autos, 0);
668 dest_track->insert_track(clip_track, dest_start, 0,
669 edit_plugins, edit_autos, len);
671 else { // cut and paste
672 dest_track->insert_track(clip_track, dest_start, 0,
673 edit_plugins, edit_autos, len);
674 if( source_track == dest_track && dest_start < source_start ) {
675 source_start += len; source_end += len;
677 source_track->clear(source_start, source_end, 1, 0,
678 edit_plugins, edit_autos, 0);
682 dest_track->optimize();
685 edits.remove_all_objects();
688 void Tracks::move_effect(Plugin *plugin, Track *track, int64_t position)
690 Track *source_track = plugin->track;
692 // Create a new plugin set
693 double start = track->from_units(position);
694 double length = track->from_units(plugin->length);
696 result = track->insert_effect("", &plugin->shared_location, 0, 0,
697 start, length, plugin->plugin_type);
698 result->copy_from(plugin);
699 result->shift(position - plugin->startproject);
701 // Clear new plugin from old set
702 plugin->plugin_set->clear(plugin->startproject,
703 plugin->startproject + plugin->length,
704 edl->session->autos_follow_edits);
706 source_track->optimize();
709 void Tracks::move_effect(Plugin *plugin, PluginSet *plugin_set, int64_t position)
711 // src/dest track must be the same
712 // replace plugin in source plugin_set with silence
713 PluginSet *src_plugin_set = plugin->plugin_set;
714 Plugin *silent = new Plugin(edl, src_plugin_set, "");
715 silent->startproject = plugin->startproject;
716 silent->length = plugin->length;
717 src_plugin_set->insert_after(plugin, silent);
718 src_plugin_set->remove_pointer(plugin);
719 // truncate previous plugin
720 Plugin *dest = (Plugin *)plugin_set->editof(position, PLAY_FORWARD, 0);
721 // add plugin after dest
722 plugin_set->insert_after(dest, plugin);
724 dest->length = position - dest->startproject;
725 if( dest->length < 0 ) dest->length = 0;
727 // update plugin position
728 plugin->startproject = position;
729 plugin->plugin_set = plugin_set;
730 plugin->edits = plugin_set;
731 src_plugin_set->track->optimize();
734 int Tracks::concatenate_tracks(int edit_plugins, int edit_autos)
736 Track *output_track, *first_output_track, *input_track;
737 int i, data_type = TRACK_AUDIO;
742 for(i = 0; i < 2; i++)
744 // Get first output track
745 for(output_track = first;
747 output_track = output_track->next)
748 if(output_track->data_type == data_type &&
749 output_track->is_armed()) break;
751 first_output_track = output_track;
753 // Get first input track
754 for(input_track = first;
756 input_track = input_track->next)
758 if(input_track->data_type == data_type &&
760 !input_track->is_armed()) break;
764 if(output_track && input_track)
766 // Transfer input track to end of output track one at a time
769 output_start = output_track->get_length();
770 output_track->insert_track(input_track,
777 // Get next source and destination
778 for(input_track = input_track->next;
780 input_track = input_track->next)
783 if(input_track->data_type == data_type &&
784 !input_track->is_armed() &&
785 input_track->play) break;
788 for(output_track = output_track->next;
790 output_track = output_track->next)
792 if(output_track->data_type == data_type &&
793 output_track->is_armed()) break;
798 output_track = first_output_track;
804 if(data_type == TRACK_AUDIO) data_type = TRACK_VIDEO;
810 int Tracks::delete_all_tracks()
812 while(last) delete last;
817 void Tracks::change_modules(int old_location, int new_location, int do_swap)
819 for(Track* current = first ; current; current = current->next)
821 current->change_modules(old_location, new_location, do_swap);
825 void Tracks::change_plugins(SharedLocation &old_location, SharedLocation &new_location, int do_swap)
827 for(Track* current = first ; current; current = current->next)
829 current->change_plugins(old_location, new_location, do_swap);
835 // =========================================== EDL editing
838 int Tracks::copy(int copy_flags, double start, double end,
839 FileXML *file, const char *output_path)
841 int all = (copy_flags & COPY_ALL) ? 1 : 0;
842 // if nothing selected
843 if( start == end && !all ) return 1;
844 for( Track *track=first; track; track=track->next ) {
845 if( track->is_armed() || all )
846 track->copy(copy_flags, start, end, file, output_path);
853 int Tracks::move_track_up(Track *track)
855 if( first == last ) return 1;
857 Track *src = track, *dst = src->previous;
858 if( edl->session->gang_tracks != GANG_NONE ) {
859 while( src && !src->master ) src = src->previous;
860 if( !src ) src = first;
861 Track *nxt = src->next;
862 while( nxt && !nxt->master ) { ++n; nxt = nxt->next; }
864 while( dst && !dst->master ) { dst = dst->previous; }
866 if( src == dst ) return 1;
867 move_tracks(src, dst, n);
871 int Tracks::move_track_down(Track *track)
873 if( first == last ) return 1;
875 Track *src = track, *dst = src->next;
876 if( edl->session->gang_tracks != GANG_NONE ) {
877 while( src && !src->master ) src = src->previous;
878 if( !src ) src = first;
879 Track *nxt = src->next;
880 while( nxt && !nxt->master ) { ++n; nxt = nxt->next; }
883 while( nxt && !nxt->master ) { nxt = nxt->next; }
890 dst = !dst ? first : dst->next;
891 if( src == dst ) return 1;
892 move_tracks(src, dst, n);
897 int Tracks::move_tracks_up()
899 if( first == last ) return 1;
901 Track *src = first, *dst = 0;
902 if( edl->session->gang_tracks != GANG_NONE ) {
903 Track *nxt = src->next;
904 while( nxt && !nxt->master ) { ++n; nxt = nxt->next; }
906 if( src == dst ) return 1;
907 move_tracks(src, dst, n);
911 int Tracks::move_tracks_down()
913 if( first == last ) return 1;
915 Track *src = last, *dst = first;
916 if( edl->session->gang_tracks != GANG_NONE ) {
917 while( src && !src->master ) { ++n; src = src->previous; }
919 if( src == dst ) return 1;
920 move_tracks(src, dst, n);
925 int Tracks::swap_track_up(Track *track)
927 Track *next_track = track->previous;
928 if(!next_track) next_track = last;
930 change_modules(number_of(track), number_of(next_track), 1);
931 swap(track, next_track);
935 int Tracks::swap_track_down(Track *track)
937 Track *next_track = track->next;
938 if(!next_track) next_track = first;
940 change_modules(number_of(track), number_of(next_track), 1);
941 swap(track, next_track);
946 int Tracks::swap_tracks_up()
951 Track *track = next; next = track->next;
952 if( !track->armed ) continue;
953 if( track->previous ) {
954 change_modules(number_of(track->previous), number_of(track), 1);
955 swap(track->previous, track);
963 int Tracks::swap_tracks_down()
968 Track *track = prev; prev = track->previous;
969 if( !track->armed ) continue;
971 change_modules(number_of(track), number_of(track->next), 1);
972 swap(track, track->next);
980 void Tracks::paste_audio_transition(PluginServer *server)
982 for(Track *current = first; current; current = NEXT)
984 if(current->data_type == TRACK_AUDIO &&
987 int64_t position = current->to_units(
988 edl->local_session->get_selectionstart(), 0);
989 Edit *current_edit = current->edits->editof(position,
992 if( !current_edit && position == current->edits->length() ) {
993 double length = edl->session->default_transition_length;
994 int64_t units = current->to_units(length, 1);
995 current_edit = current->edits->create_silence(position, position+units);
999 paste_transition(server, current_edit);
1005 void Tracks::paste_automation(double selectionstart,
1011 Track* current_track = 0;
1012 Track* current_atrack = 0;
1013 Track* current_vtrack = 0;
1014 Track* dst_track = 0;
1018 double frame_rate = edl->session->frame_rate;
1019 int64_t sample_rate = edl->session->sample_rate;
1020 char string[BCTEXTLEN];
1025 result = file->read_tag();
1027 !file->tag.title_is("AUTO_CLIPBOARD"));
1031 length = file->tag.get_property("LENGTH", 0);
1032 frame_rate = file->tag.get_property("FRAMERATE", frame_rate);
1033 sample_rate = file->tag.get_property("SAMPLERATE", sample_rate);
1038 result = file->read_tag();
1042 if(file->tag.title_is("/AUTO_CLIPBOARD"))
1047 if(file->tag.title_is("TRACK"))
1049 file->tag.get_property("TYPE", string);
1050 if(!strcmp(string, "AUDIO"))
1052 src_type = TRACK_AUDIO;
1056 src_type = TRACK_VIDEO;
1059 // paste to any media type
1062 if(!current_track) current_track = first;
1063 while(current_track && !current_track->is_armed())
1064 current_track = current_track->next;
1065 dst_track = current_track;
1068 if(!strcmp(string, "AUDIO"))
1070 // Get next audio track
1072 current_atrack = first;
1074 current_atrack = current_atrack->next;
1076 while(current_atrack &&
1077 (current_atrack->data_type != TRACK_AUDIO ||
1078 !current_atrack->is_armed()))
1079 current_atrack = current_atrack->next;
1080 dst_track = current_atrack;
1084 // Get next video track
1086 current_vtrack = first;
1088 current_vtrack = current_vtrack->next;
1090 while(current_vtrack &&
1091 (current_vtrack->data_type != TRACK_VIDEO ||
1092 !current_vtrack->is_armed()))
1093 current_vtrack = current_vtrack->next;
1095 dst_track = current_vtrack;
1100 double frame_rate2 = frame_rate;
1101 double sample_rate2 = sample_rate;
1103 if(src_type != dst_track->data_type)
1105 frame_rate2 = sample_rate;
1106 sample_rate2 = frame_rate;
1109 dst_track->paste_automation(selectionstart,
1123 // int Tracks::paste_default_keyframe(FileXML *file)
1125 // paste_automation(0, file, 1, 0);
1129 void Tracks::paste_transition(PluginServer *server, Edit *dest_edit)
1131 dest_edit->insert_transition(server->title);
1132 if( edl->session->gang_tracks == GANG_NONE ) return;
1133 Track *track = dest_edit->track;
1134 double pos = track->from_units(dest_edit->startproject);
1135 for( Track *current=first; current; current=current->next ) {
1136 if( current == track ) continue;
1137 if( current->data_type != track->data_type ) continue;
1138 if( !current->armed_gang(track) ) continue;
1139 int64_t track_pos = current->to_units(pos, 1);
1140 Edit *edit = current->edits->editof(track_pos, PLAY_FORWARD, 0);
1141 if( !edit ) continue;
1142 double edit_pos = track->from_units(edit->startproject);
1143 if( !edl->equivalent(pos, edit_pos) ) continue;
1144 edit->insert_transition(server->title);
1148 void Tracks::paste_video_transition(PluginServer *server, int first_track)
1150 for(Track *current = first; current; current = NEXT)
1152 if(current->data_type == TRACK_VIDEO &&
1153 current->is_armed())
1155 int64_t position = current->to_units(
1156 edl->local_session->get_selectionstart(), 0);
1157 Edit *current_edit = current->edits->editof(position,
1160 if( !current_edit && position == current->edits->length() ) {
1161 double length = edl->session->default_transition_length;
1162 int64_t units = current->to_units(length, 1);
1163 current_edit = current->edits->create_silence(position, position+units);
1167 paste_transition(server, current_edit);
1169 if(first_track) break;
1175 int Tracks::paste_silence(double start,
1180 Track* current_track;
1182 for(current_track = first;
1184 current_track = current_track->next)
1186 if(current_track->is_armed())
1188 current_track->paste_silence(start,
1199 int Tracks::select_auto(int cursor_x, int cursor_y)
1202 for(Track* current = first; current && !result; current = NEXT) { result = current->select_auto(&auto_conf, cursor_x, cursor_y); }
1206 int Tracks::move_auto(int cursor_x, int cursor_y, int shift_down)
1210 for(Track* current = first; current && !result; current = NEXT)
1212 result = current->move_auto(&auto_conf, cursor_x, cursor_y, shift_down);
1217 int Tracks::modify_edithandles(double &oldposition, double &newposition,
1218 int currentend, int handle_mode, int edit_labels,
1219 int edit_plugins, int edit_autos, int group_id)
1221 for( Track *track=first; track; track=track->next ) {
1222 if( !track->is_armed() ) continue;
1223 track->modify_edithandles(oldposition, newposition,
1224 currentend, handle_mode, edit_labels,
1225 edit_plugins, edit_autos, group_id);
1226 // labels follow first armed track
1232 int Tracks::modify_pluginhandles(double &oldposition, double &newposition,
1233 int currentend, int handle_mode, int edit_labels,
1234 int edit_autos, Edits *trim_edits)
1236 for( Track *track=first; track; track=track->next ) {
1237 if( !track->is_armed() ) continue;
1238 track->modify_pluginhandles(oldposition, newposition,
1239 currentend, handle_mode, edit_labels,
1240 edit_autos, trim_edits);
1246 int Tracks::purge_asset(Asset *asset)
1248 Track *current_track;
1251 for(current_track = first; current_track; current_track = current_track->next)
1253 result += current_track->purge_asset(asset);
1258 int Tracks::asset_used(Asset *asset)
1260 Track *current_track;
1263 for(current_track = first; current_track; current_track = current_track->next)
1265 result += current_track->asset_used(asset);
1270 int Tracks::scale_time(float rate_scale, int ignore_record, int scale_edits, int scale_autos, int64_t start, int64_t end)
1272 Track *current_track;
1274 for(current_track = first;
1276 current_track = current_track->next)
1278 if((current_track->is_armed() || ignore_record) &&
1279 current_track->data_type == TRACK_VIDEO)
1281 current_track->scale_time(rate_scale, scale_edits, scale_autos, start, end);