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 void Tracks::straighten_automation(double selectionstart, double selectionend)
69 for(current_track = first; current_track; current_track = current_track->next)
71 if(current_track->record)
73 current_track->straighten_automation(selectionstart,
79 int Tracks::clear_default_keyframe()
81 for(Track *current = first; current; current = NEXT)
84 current->clear_automation(0, 0, 0, 1);
89 int Tracks::clear_handle(double start,
91 double &longest_distance,
98 for(current_track = first; current_track; current_track = current_track->next)
100 if(current_track->record)
102 current_track->clear_handle(start,
107 if(distance > longest_distance) longest_distance = distance;
114 int Tracks::copy_automation(double selectionstart,
120 // called by MWindow::copy_automation for copying automation alone
121 Track* current_track;
123 file->tag.set_title("AUTO_CLIPBOARD");
124 file->tag.set_property("LENGTH", selectionend - selectionstart);
125 file->tag.set_property("FRAMERATE", edl->session->frame_rate);
126 file->tag.set_property("SAMPLERATE", edl->session->sample_rate);
128 file->append_newline();
129 file->append_newline();
131 for(current_track = first;
133 current_track = current_track->next)
135 if(current_track->record)
137 current_track->copy_automation(selectionstart,
145 file->tag.set_title("/AUTO_CLIPBOARD");
147 file->append_newline();
148 file->terminate_string();
152 int Tracks::copy_default_keyframe(FileXML *file)
154 copy_automation(0, 0, file, 1, 0);
158 int Tracks::delete_tracks()
160 int total_deleted = 0;
166 for (Track* current = first;
172 delete_track(current);
178 return total_deleted;
181 void Tracks::move_edits(ArrayList<Edit*> *edits,
184 int edit_labels, // Ignored
185 int edit_plugins, // Ignored
188 //printf("Tracks::move_edits 1\n");
189 for(Track *dest_track = track; dest_track; dest_track = dest_track->next)
191 if(dest_track->record)
193 // Need a local copy of the source edit since the original source edit may
194 // change in the editing operation.
195 Edit *source_edit = 0;
196 Track *source_track = 0;
200 if(dest_track->data_type == TRACK_AUDIO)
202 int current_aedit = 0;
204 while(current_aedit < edits->total &&
205 edits->values[current_aedit]->track->data_type != TRACK_AUDIO)
208 if(current_aedit < edits->total)
210 source_edit = edits->values[current_aedit];
211 source_track = source_edit->track;
212 edits->remove_number(current_aedit);
216 if(dest_track->data_type == TRACK_VIDEO)
218 int current_vedit = 0;
219 while(current_vedit < edits->total &&
220 edits->values[current_vedit]->track->data_type != TRACK_VIDEO)
223 if(current_vedit < edits->total)
225 source_edit = edits->values[current_vedit];
226 source_track = source_edit->track;
227 edits->remove_number(current_vedit);
231 //printf("Tracks::move_edits 2 %s %s %d\n", source_track->title, dest_track->title, source_edit->length);
234 int64_t position_i = source_track->to_units(position, 0);
235 // Source edit changes
236 int64_t source_length = source_edit->length;
237 int64_t source_startproject = source_edit->startproject;
241 // This works like this: CUT edit, INSERT edit at final position, keyframes also follow
242 // FIXME: there should be a GUI way to tell whenever user also wants to move autos or not
245 AutoConf temp_autoconf;
247 temp_autoconf.set_all(1);
249 source_track->automation->copy(source_edit->startproject,
250 source_edit->startproject + source_edit->length,
254 temp.terminate_string();
256 // Insert new keyframes
257 //printf("Tracks::move_edits 2 %d %p\n", result->startproject, result->asset);
258 source_track->automation->clear(source_edit->startproject,
259 source_edit->startproject + source_edit->length,
262 int64_t position_a = position_i;
263 if (dest_track == source_track)
265 if (position_a > source_edit->startproject)
266 position_a -= source_length;
269 dest_track->automation->paste_silence(position_a,
270 position_a + source_length);
271 while(!temp.read_tag())
272 dest_track->automation->paste(position_a,
280 Edit *dest_edit = dest_track->edits->shift(position_i,
282 Edit *result = dest_track->edits->insert_before(dest_edit,
283 dest_track->edits->create_edit());
284 result->copy_from(source_edit);
285 result->startproject = position_i;
286 result->length = source_length;
289 source_track->edits->clear(source_edit->startproject,
290 source_edit->startproject + source_length);
293 //this is outline for future thinking how it is supposed to be done trough C&P mechanisms
295 source_track->cut(source_edit->startproject,
296 source_edit->startproject + source_edit->length,
299 temp.terminate_string();
301 dest_track->paste_silence(position_a,
302 position_a + source_length,
304 while(!temp.read_tag())
305 dest_track->paste(position_a, // MISSING PIECE OF FUNCTIONALITY
316 // ONLY edit is moved, all other edits stay where they are
318 // Copy edit to temp, delete the edit, insert the edit
319 Edit *temp_edit = dest_track->edits->create_edit();
320 temp_edit->copy_from(source_edit);
321 // we call the edits directly since we do not want to move keyframes or anything else
322 source_track->edits->clear(source_startproject,
323 source_startproject + source_length);
324 source_track->edits->paste_silence(source_startproject,
325 source_startproject + source_length);
327 dest_track->edits->clear(position_i,
328 position_i + source_length);
329 Edit *dest_edit = dest_track->edits->shift(position_i, source_length);
330 Edit *result = dest_track->edits->insert_before(dest_edit,
331 dest_track->edits->create_edit());
332 result->copy_from(temp_edit);
333 result->startproject = position_i;
334 result->length = source_length;
337 source_track->optimize();
338 dest_track->optimize();
344 void Tracks::move_effect(Plugin *plugin,
345 PluginSet *dest_plugin_set,
347 int64_t dest_position)
349 Track *source_track = plugin->track;
352 // Insert on an existing plugin set
353 if(!dest_track && dest_plugin_set)
355 Track *dest_track = dest_plugin_set->track;
358 // Assume this operation never splits a plugin
359 // Shift destination plugins back
360 dest_plugin_set->shift(dest_position, plugin->length);
364 for(current = (Plugin*)dest_plugin_set->first; current; current = (Plugin*)NEXT)
365 if(current->startproject >= dest_position) break;
367 result = (Plugin*)dest_plugin_set->insert_before(current,
368 new Plugin(edl, dest_plugin_set, ""));
371 // Create a new plugin set
373 double start = dest_track->from_units(dest_position);
374 double length = dest_track->from_units(plugin->length);
376 result = dest_track->insert_effect("",
377 &plugin->shared_location,
382 plugin->plugin_type);
387 result->copy_from(plugin);
388 result->shift(dest_position - plugin->startproject);
390 // Clear new plugin from old set
391 plugin->plugin_set->clear(plugin->startproject, plugin->startproject + plugin->length);
394 source_track->optimize();
399 int Tracks::concatenate_tracks(int edit_plugins)
401 Track *output_track, *first_output_track, *input_track;
402 int i, data_type = TRACK_AUDIO;
406 IntAuto *play_keyframe = 0;
409 for(i = 0; i < 2; i++)
411 // Get first output track
412 for(output_track = first;
414 output_track = output_track->next)
415 if(output_track->data_type == data_type &&
416 output_track->record) break;
418 first_output_track = output_track;
420 // Get first input track
421 for(input_track = first;
423 input_track = input_track->next)
425 if(input_track->data_type == data_type &&
427 !input_track->record) break;
431 if(output_track && input_track)
433 // Transfer input track to end of output track one at a time
436 output_start = output_track->get_length();
437 output_track->insert_track(input_track,
442 // Get next source and destination
443 for(input_track = input_track->next;
445 input_track = input_track->next)
448 if(input_track->data_type == data_type &&
449 !input_track->record &&
450 input_track->play) break;
453 for(output_track = output_track->next;
455 output_track = output_track->next)
457 if(output_track->data_type == data_type &&
458 output_track->record) break;
463 output_track = first_output_track;
469 if(data_type == TRACK_AUDIO) data_type = TRACK_VIDEO;
475 int Tracks::delete_all_tracks()
477 while(last) delete last;
482 void Tracks::change_modules(int old_location, int new_location, int do_swap)
484 for(Track* current = first ; current; current = current->next)
486 current->change_modules(old_location, new_location, do_swap);
490 void Tracks::change_plugins(SharedLocation &old_location, SharedLocation &new_location, int do_swap)
492 for(Track* current = first ; current; current = current->next)
494 current->change_plugins(old_location, new_location, do_swap);
500 // =========================================== EDL editing
503 int Tracks::copy(double start,
510 if(start == end && !all) return 1;
518 if(current->record || all)
520 current->copy(start, end, file,output_path);
529 int Tracks::move_track_up(Track *track)
531 Track *next_track = track->previous;
532 if(!next_track) next_track = last;
534 change_modules(number_of(track), number_of(next_track), 1);
536 // printf("Tracks::move_track_up 1 %p %p\n", track, next_track);
538 // for(Track *current = first; current && count < 5; current = NEXT, count++)
539 // printf("Tracks::move_track_up %p %p %p\n", current->previous, current, current->next);
540 // printf("Tracks::move_track_up 2\n");
542 swap(track, next_track);
545 // for(Track *current = first; current && count < 5; current = NEXT, count++)
546 // printf("Tracks::move_track_up %p %p %p\n", current->previous, current, current->next);
547 // printf("Tracks::move_track_up 3\n");
552 int Tracks::move_track_down(Track *track)
554 Track *next_track = track->next;
555 if(!next_track) next_track = first;
557 change_modules(number_of(track), number_of(next_track), 1);
558 swap(track, next_track);
563 int Tracks::move_tracks_up()
565 Track *track, *next_track;
572 next_track = track->next;
578 change_modules(number_of(track->previous), number_of(track), 1);
580 swap(track->previous, track);
589 int Tracks::move_tracks_down()
591 Track *track, *previous_track;
596 track = previous_track)
598 previous_track = track->previous;
604 change_modules(number_of(track), number_of(track->next), 1);
606 swap(track, track->next);
617 void Tracks::paste_audio_transition(PluginServer *server)
619 for(Track *current = first; current; current = NEXT)
621 if(current->data_type == TRACK_AUDIO &&
624 int64_t position = current->to_units(
625 edl->local_session->get_selectionstart(), 0);
626 Edit *current_edit = current->edits->editof(position,
631 paste_transition(server, current_edit);
637 void Tracks::loaded_lengths_to_tracklengths(int includerecordtracks)
639 Track *current_track;
641 for(current_track = first;
643 current_track = current_track->next)
645 if(current_track->record || includerecordtracks)
647 // Reset the loaded_length value. (the last edit should always be a silence going to infinityish)
648 current_track->edits->loaded_length = current_track->edits->last->startproject;
653 void Tracks::paste_automation(double selectionstart,
657 Track* current_atrack = 0;
658 Track* current_vtrack = 0;
661 double frame_rate = edl->session->frame_rate;
662 int64_t sample_rate = edl->session->sample_rate;
663 char string[BCTEXTLEN];
668 result = file->read_tag();
670 !file->tag.title_is("AUTO_CLIPBOARD"));
674 length = file->tag.get_property("LENGTH", 0);
675 frame_rate = file->tag.get_property("FRAMERATE", frame_rate);
676 sample_rate = file->tag.get_property("SAMPLERATE", sample_rate);
681 result = file->read_tag();
685 if(file->tag.title_is("/AUTO_CLIPBOARD"))
690 if(file->tag.title_is("TRACK"))
692 file->tag.get_property("TYPE", string);
694 if(!strcmp(string, "AUDIO"))
696 // Get next audio track
698 current_atrack = first;
700 current_atrack = current_atrack->next;
702 while(current_atrack &&
703 (current_atrack->data_type != TRACK_AUDIO ||
704 !current_atrack->record))
705 current_atrack = current_atrack->next;
710 current_atrack->paste_automation(selectionstart,
720 // Get next video track
722 current_vtrack = first;
724 current_vtrack = current_vtrack->next;
726 while(current_vtrack &&
727 (current_vtrack->data_type != TRACK_VIDEO ||
728 !current_vtrack->record))
729 current_vtrack = current_vtrack->next;
734 //printf("Tracks::paste_automation 1 %s %d\n", current_vtrack->title, current_vtrack->record);
735 current_vtrack->paste_automation(selectionstart,
749 int Tracks::paste_default_keyframe(FileXML *file)
751 paste_automation(0, file, 1);
755 void Tracks::paste_transition(PluginServer *server, Edit *dest_edit)
757 dest_edit->insert_transition(server->title);
760 void Tracks::paste_video_transition(PluginServer *server, int first_track)
762 for(Track *current = first; current; current = NEXT)
764 if(current->data_type == TRACK_VIDEO &&
767 int64_t position = current->to_units(
768 edl->local_session->get_selectionstart(), 0);
769 Edit *current_edit = current->edits->editof(position,
774 paste_transition(server, current_edit);
776 if(first_track) break;
782 int Tracks::paste_silence(double start, double end, int edit_plugins)
784 Track* current_track;
786 for(current_track = first;
788 current_track = current_track->next)
790 if(current_track->record)
792 current_track->paste_silence(start, end, edit_plugins);
800 int Tracks::select_auto(int cursor_x, int cursor_y)
803 for(Track* current = first; current && !result; current = NEXT) { result = current->select_auto(&auto_conf, cursor_x, cursor_y); }
807 int Tracks::move_auto(int cursor_x, int cursor_y, int shift_down)
811 for(Track* current = first; current && !result; current = NEXT)
813 result = current->move_auto(&auto_conf, cursor_x, cursor_y, shift_down);
818 int Tracks::modify_edithandles(double &oldposition,
827 for(current = first; current; current = NEXT)
831 current->modify_edithandles(oldposition,
842 int Tracks::modify_pluginhandles(double &oldposition,
851 for(current = first; current; current = NEXT)
855 current->modify_pluginhandles(oldposition,
868 int Tracks::purge_asset(Asset *asset)
870 Track *current_track;
873 for(current_track = first; current_track; current_track = current_track->next)
875 result += current_track->purge_asset(asset);
880 int Tracks::asset_used(Asset *asset)
882 Track *current_track;
885 for(current_track = first; current_track; current_track = current_track->next)
887 result += current_track->asset_used(asset);
892 int Tracks::scale_time(float rate_scale, int ignore_record, int scale_edits, int scale_autos, int64_t start, int64_t end)
894 Track *current_track;
896 for(current_track = first;
898 current_track = current_track->next)
900 if((current_track->record || ignore_record) &&
901 current_track->data_type == TRACK_VIDEO)
903 current_track->scale_time(rate_scale, scale_edits, scale_autos, start, end);