3 #include "automation.h"
8 #include "edlsession.h"
12 #include "localsession.h"
15 #include "mainsession.h"
16 #include "pluginserver.h"
17 #include "pluginset.h"
19 #include "trackcanvas.h"
21 #include "trackscroll.h"
22 #include "transition.h"
23 #include "transportque.h"
27 int Tracks::clear(double start, double end, int clear_plugins)
31 for(current_track = first;
33 current_track = current_track->next)
35 if(current_track->record)
37 current_track->clear(start,
49 void Tracks::clear_automation(double selectionstart, double selectionend)
53 for(current_track = first; current_track; current_track = current_track->next)
55 if(current_track->record)
57 current_track->clear_automation(selectionstart,
65 int Tracks::clear_default_keyframe()
67 for(Track *current = first; current; current = NEXT)
70 current->clear_automation(0, 0, 0, 1);
75 int Tracks::clear_handle(double start,
77 double &longest_distance,
84 for(current_track = first; current_track; current_track = current_track->next)
86 if(current_track->record)
88 current_track->clear_handle(start,
93 if(distance > longest_distance) longest_distance = distance;
100 int Tracks::copy_automation(double selectionstart,
106 // called by MWindow::copy_automation for copying automation alone
107 Track* current_track;
109 file->tag.set_title("AUTO_CLIPBOARD");
110 file->tag.set_property("LENGTH", selectionend - selectionstart);
111 file->tag.set_property("FRAMERATE", edl->session->frame_rate);
112 file->tag.set_property("SAMPLERATE", edl->session->sample_rate);
114 file->append_newline();
115 file->append_newline();
117 for(current_track = first;
119 current_track = current_track->next)
121 if(current_track->record)
123 current_track->copy_automation(selectionstart,
131 file->tag.set_title("/AUTO_CLIPBOARD");
133 file->append_newline();
134 file->terminate_string();
138 int Tracks::copy_default_keyframe(FileXML *file)
140 copy_automation(0, 0, file, 1, 0);
144 int Tracks::delete_tracks()
146 int total_deleted = 0;
148 for (Track* current = first;
154 delete_track(current);
156 // this has garbled the linked list
157 // scan the shorter list again
161 return total_deleted;
164 void Tracks::move_edits(ArrayList<Edit*> *edits,
167 int edit_labels, // Ignored
168 int edit_plugins) // Ignored
170 //printf("Tracks::move_edits 1\n");
171 for(Track *dest_track = track; dest_track; dest_track = dest_track->next)
173 if(dest_track->record)
175 // Need a local copy of the source edit since the original source edit may
176 // change in the editing operation.
177 Edit *source_edit = 0;
178 Track *source_track = 0;
182 if(dest_track->data_type == TRACK_AUDIO)
184 int current_aedit = 0;
186 while(current_aedit < edits->total &&
187 edits->values[current_aedit]->track->data_type != TRACK_AUDIO)
190 if(current_aedit < edits->total)
192 source_edit = edits->values[current_aedit];
193 source_track = source_edit->track;
194 edits->remove_number(current_aedit);
198 if(dest_track->data_type == TRACK_VIDEO)
200 int current_vedit = 0;
201 while(current_vedit < edits->total &&
202 edits->values[current_vedit]->track->data_type != TRACK_VIDEO)
205 if(current_vedit < edits->total)
207 source_edit = edits->values[current_vedit];
208 source_track = source_edit->track;
209 edits->remove_number(current_vedit);
213 //printf("Tracks::move_edits 2 %s %s %d\n", source_track->title, dest_track->title, source_edit->length);
218 AutoConf temp_autoconf;
219 int64_t position_i = source_track->to_units(position, 0);
220 // Source edit changes
221 int64_t source_length = source_edit->length;
223 temp_autoconf.set_all();
225 source_track->automation->copy(source_edit->startproject,
226 source_edit->startproject + source_edit->length,
230 temp.terminate_string();
232 // Insert new keyframes
233 //printf("Tracks::move_edits 2 %d %p\n", result->startproject, result->asset);
234 source_track->automation->clear(source_edit->startproject,
235 source_edit->startproject + source_edit->length,
238 int64_t position_a = position_i;
239 if (dest_track == source_track)
241 if (position_a > source_edit->startproject)
242 position_a -= source_length;
245 dest_track->automation->paste_silence(position_a,
246 position_a + source_length);
247 while(!temp.read_tag())
248 dest_track->automation->paste(position_a,
257 //printf("Tracks::move_edits 1 %d\n", source_edit->length);
259 Edit *dest_edit = dest_track->edits->shift(position_i,
261 Edit *result = dest_track->edits->insert_before(dest_edit,
262 new Edit(edl, dest_track));
263 result->copy_from(source_edit);
264 result->startproject = position_i;
265 result->length = source_length;
267 //printf("Tracks::move_edits 5\n");
268 //dest_track->dump();
271 //printf("Tracks::move_edits 7 %d %d\n", clear_start, clear_end);
272 source_track->edits->clear(source_edit->startproject,
273 source_edit->startproject + source_length);
277 //printf("Tracks::move_edits 8 %d %d\n", clear_start, source_edit->length);
278 //dest_track->dump();
279 //printf("Tracks::move_edits 9\n");
280 source_track->optimize();
281 dest_track->optimize();
282 //printf("Tracks::move_edits 10\n");
284 // delete source_edit;
291 void Tracks::move_effect(Plugin *plugin,
292 PluginSet *dest_plugin_set,
294 int64_t dest_position)
296 Track *source_track = plugin->track;
299 // Insert on an existing plugin set
300 if(!dest_track && dest_plugin_set)
302 Track *dest_track = dest_plugin_set->track;
305 // Assume this operation never splits a plugin
306 // Shift destination plugins back
307 dest_plugin_set->shift(dest_position, plugin->length);
311 for(current = (Plugin*)dest_plugin_set->first; current; current = (Plugin*)NEXT)
312 if(current->startproject >= dest_position) break;
314 result = (Plugin*)dest_plugin_set->insert_before(current,
315 new Plugin(edl, dest_plugin_set, ""));
318 // Create a new plugin set
322 if(edl->local_session->get_selectionend() >
323 edl->local_session->get_selectionstart())
325 start = edl->local_session->get_selectionstart();
326 length = edl->local_session->get_selectionend() -
330 if(dest_track->get_length() > 0)
333 length = dest_track->get_length();
338 length = dest_track->from_units(plugin->length);
342 result = dest_track->insert_effect("",
343 &plugin->shared_location,
348 plugin->plugin_type);
353 result->copy_from(plugin);
354 result->shift(dest_position - plugin->startproject);
356 // Clear new plugin from old set
357 plugin->plugin_set->clear(plugin->startproject, plugin->startproject + plugin->length);
360 source_track->optimize();
365 int Tracks::concatenate_tracks(int edit_plugins)
367 Track *output_track, *first_output_track, *input_track;
368 int i, data_type = TRACK_AUDIO;
372 IntAuto *play_keyframe = 0;
375 for(i = 0; i < 2; i++)
377 // Get first output track
378 for(output_track = first;
380 output_track = output_track->next)
381 if(output_track->data_type == data_type &&
382 output_track->record) break;
384 first_output_track = output_track;
386 // Get first input track
387 for(input_track = first;
389 input_track = input_track->next)
391 if(input_track->data_type == data_type &&
393 !input_track->record) break;
397 if(output_track && input_track)
399 // Transfer input track to end of output track one at a time
402 output_start = output_track->get_length();
403 output_track->insert_track(input_track,
408 // Get next source and destination
409 for(input_track = input_track->next;
411 input_track = input_track->next)
414 if(input_track->data_type == data_type &&
415 !input_track->record &&
416 input_track->play) break;
419 for(output_track = output_track->next;
421 output_track = output_track->next)
423 if(output_track->data_type == data_type &&
424 output_track->record) break;
429 output_track = first_output_track;
435 if(data_type == TRACK_AUDIO) data_type = TRACK_VIDEO;
441 int Tracks::delete_all_tracks()
443 while(last) delete last;
448 void Tracks::change_modules(int old_location, int new_location, int do_swap)
450 for(Track* current = first ; current; current = current->next)
452 current->change_modules(old_location, new_location, do_swap);
456 void Tracks::change_plugins(SharedLocation &old_location, SharedLocation &new_location, int do_swap)
458 for(Track* current = first ; current; current = current->next)
460 current->change_plugins(old_location, new_location, do_swap);
466 // =========================================== EDL editing
469 int Tracks::copy(double start,
476 if(start == end && !all) return 1;
484 if(current->record || all)
486 current->copy(start, end, file,output_path);
495 int Tracks::move_track_up(Track *track)
497 Track *next_track = track->previous;
498 if(!next_track) next_track = last;
500 change_modules(number_of(track), number_of(next_track), 1);
502 // printf("Tracks::move_track_up 1 %p %p\n", track, next_track);
504 // for(Track *current = first; current && count < 5; current = NEXT, count++)
505 // printf("Tracks::move_track_up %p %p %p\n", current->previous, current, current->next);
506 // printf("Tracks::move_track_up 2\n");
508 swap(track, next_track);
511 // for(Track *current = first; current && count < 5; current = NEXT, count++)
512 // printf("Tracks::move_track_up %p %p %p\n", current->previous, current, current->next);
513 // printf("Tracks::move_track_up 3\n");
518 int Tracks::move_track_down(Track *track)
520 Track *next_track = track->next;
521 if(!next_track) next_track = first;
523 change_modules(number_of(track), number_of(next_track), 1);
524 swap(track, next_track);
529 int Tracks::move_tracks_up()
531 Track *track, *next_track;
538 next_track = track->next;
544 change_modules(number_of(track->previous), number_of(track), 1);
546 swap(track->previous, track);
555 int Tracks::move_tracks_down()
557 Track *track, *previous_track;
562 track = previous_track)
564 previous_track = track->previous;
570 change_modules(number_of(track), number_of(track->next), 1);
572 swap(track, track->next);
583 void Tracks::paste_audio_transition(PluginServer *server)
585 for(Track *current = first; current; current = NEXT)
587 if(current->data_type == TRACK_AUDIO &&
590 int64_t position = current->to_units(
591 edl->local_session->get_selectionstart(), 0);
592 Edit *current_edit = current->edits->editof(position,
597 paste_transition(server, current_edit);
603 void Tracks::paste_automation(double selectionstart,
607 Track* current_atrack = 0;
608 Track* current_vtrack = 0;
611 double frame_rate = edl->session->frame_rate;
612 int64_t sample_rate = edl->session->sample_rate;
613 char string[BCTEXTLEN];
618 result = file->read_tag();
620 !file->tag.title_is("AUTO_CLIPBOARD"));
624 length = file->tag.get_property("LENGTH", 0);
625 frame_rate = file->tag.get_property("FRAMERATE", frame_rate);
626 sample_rate = file->tag.get_property("SAMPLERATE", sample_rate);
631 result = file->read_tag();
635 if(file->tag.title_is("/AUTO_CLIPBOARD"))
640 if(file->tag.title_is("TRACK"))
642 file->tag.get_property("TYPE", string);
644 if(!strcmp(string, "AUDIO"))
646 // Get next audio track
648 current_atrack = first;
650 current_atrack = current_atrack->next;
652 while(current_atrack &&
653 (current_atrack->data_type != TRACK_AUDIO ||
654 !current_atrack->record))
655 current_atrack = current_atrack->next;
660 current_atrack->paste_automation(selectionstart,
670 // Get next video track
672 current_vtrack = first;
674 current_vtrack = current_vtrack->next;
676 while(current_vtrack &&
677 (current_vtrack->data_type != TRACK_VIDEO ||
678 !current_vtrack->record))
679 current_vtrack = current_vtrack->next;
684 //printf("Tracks::paste_automation 1 %s %d\n", current_vtrack->title, current_vtrack->record);
685 current_vtrack->paste_automation(selectionstart,
699 int Tracks::paste_default_keyframe(FileXML *file)
701 paste_automation(0, file, 1);
705 void Tracks::paste_transition(PluginServer *server, Edit *dest_edit)
707 dest_edit->insert_transition(server->title);
710 void Tracks::paste_video_transition(PluginServer *server, int first_track)
712 for(Track *current = first; current; current = NEXT)
714 if(current->data_type == TRACK_VIDEO &&
717 int64_t position = current->to_units(
718 edl->local_session->get_selectionstart(), 0);
719 Edit *current_edit = current->edits->editof(position,
724 paste_transition(server, current_edit);
726 if(first_track) break;
732 int Tracks::paste_silence(double start, double end, int edit_plugins)
734 Track* current_track;
736 for(current_track = first;
738 current_track = current_track->next)
740 if(current_track->record)
742 current_track->paste_silence(start, end, edit_plugins);
750 int Tracks::select_auto(int cursor_x, int cursor_y)
753 for(Track* current = first; current && !result; current = NEXT) { result = current->select_auto(&auto_conf, cursor_x, cursor_y); }
757 int Tracks::move_auto(int cursor_x, int cursor_y, int shift_down)
761 for(Track* current = first; current && !result; current = NEXT)
763 result = current->move_auto(&auto_conf, cursor_x, cursor_y, shift_down);
768 int Tracks::modify_edithandles(double &oldposition,
777 for(current = first; current; current = NEXT)
781 current->modify_edithandles(oldposition,
792 int Tracks::modify_pluginhandles(double &oldposition,
801 for(current = first; current; current = NEXT)
805 current->modify_pluginhandles(oldposition,
818 int Tracks::purge_asset(Asset *asset)
820 Track *current_track;
823 for(current_track = first; current_track; current_track = current_track->next)
825 result += current_track->purge_asset(asset);
830 int Tracks::asset_used(Asset *asset)
832 Track *current_track;
835 for(current_track = first; current_track; current_track = current_track->next)
837 result += current_track->asset_used(asset);
842 int Tracks::scale_time(float rate_scale, int ignore_record, int scale_edits, int scale_autos, int64_t start, int64_t end)
844 Track *current_track;
846 for(current_track = first;
848 current_track = current_track->next)
850 if((current_track->record || ignore_record) &&
851 current_track->data_type == TRACK_VIDEO)
853 current_track->scale_time(rate_scale, scale_edits, scale_autos, start, end);