5 #include "automation.h"
6 #include "awindowgui.inc"
8 #include "colormodels.h"
11 #include "edlsession.h"
15 #include "localsession.h"
18 #include "playbackconfig.h"
20 #include "preferences.h"
21 #include "recordconfig.h"
22 #include "recordlabel.h"
23 #include "sharedlocation.h"
26 #include "transportque.inc"
29 EDL::EDL(EDL *parent_edl)
31 this->parent_edl = parent_edl;
38 folders.set_array_delete();
39 new_folder(CLIP_FOLDER);
40 new_folder(MEDIA_FOLDER);
48 //printf("EDL::~EDL 1\n");
77 folders.remove_all_objects();
78 clips.remove_all_objects();
79 //printf("EDL::~EDL 2\n");
83 int EDL::create_objects()
85 tracks = new Tracks(this);
88 assets = new Assets(this);
89 session = new EDLSession(this);
93 assets = parent_edl->assets;
94 session = parent_edl->session;
97 local_session = new LocalSession(this);
98 labels = new Labels(this, "LABELS");
99 presentations = new Presentations(this);
100 // last_playback_position = 0;
104 EDL& EDL::operator=(EDL &edl)
106 printf("EDL::operator= 1\n");
111 int EDL::load_defaults(Defaults *defaults)
114 session->load_defaults(defaults);
116 local_session->load_defaults(defaults);
120 int EDL::save_defaults(Defaults *defaults)
123 session->save_defaults(defaults);
125 local_session->save_defaults(defaults);
129 void EDL::boundaries()
131 session->boundaries();
132 local_session->boundaries();
135 int EDL::create_default_tracks()
138 for(int i = 0; i < session->video_tracks; i++)
140 tracks->add_video_track(0, 0);
142 for(int i = 0; i < session->audio_tracks; i++)
144 tracks->add_audio_track(0, 0);
149 int EDL::load_xml(ArrayList<PluginServer*> *plugindb,
154 // Track numbering offset for replacing undo data.
155 int track_offset = 0;
157 folders.remove_all_objects();
159 // Search for start of master EDL.
161 // The parent_edl test caused clip creation to fail since those XML files
162 // contained an EDL tag.
164 // The parent_edl test is required to make EDL loading work because
165 // when loading an EDL the EDL tag is already read by the parent.
170 result = file->read_tag();
172 !file->tag.title_is("XML") &&
173 !file->tag.title_is("EDL"));
178 // Get path for backups
180 file->tag.get_property("PROJECT_PATH", project_path);
183 if((load_flags & LOAD_ALL) == LOAD_ALL ||
184 (load_flags & LOAD_EDITS) == LOAD_EDITS)
186 while(tracks->last) delete tracks->last;
189 if((load_flags & LOAD_ALL) == LOAD_ALL)
191 clips.remove_all_objects();
194 if(load_flags & LOAD_TIMEBAR)
196 while(labels->last) delete labels->last;
197 local_session->in_point = -1;
198 local_session->out_point = -1;
202 result = file->read_tag();
206 if(file->tag.title_is("/XML") ||
207 file->tag.title_is("/EDL") ||
208 file->tag.title_is("/CLIP_EDL") ||
209 file->tag.title_is("/VWINDOW_EDL"))
214 if(file->tag.title_is("CLIPBOARD"))
216 local_session->clipboard_length = file->tag.get_property("LENGTH", 0);
219 if(file->tag.title_is("VIDEO"))
221 if((load_flags & LOAD_VCONFIG) &&
222 (load_flags & LOAD_SESSION))
223 session->load_video_config(file, 0, load_flags);
226 if(file->tag.title_is("AUDIO"))
228 if((load_flags & LOAD_ACONFIG) &&
229 (load_flags & LOAD_SESSION))
230 session->load_audio_config(file, 0, load_flags);
233 if(file->tag.title_is("FOLDER"))
235 char folder[BCTEXTLEN];
236 strcpy(folder, file->read_text());
240 if(file->tag.title_is("ASSETS"))
242 if(load_flags & LOAD_ASSETS)
243 assets->load(plugindb, file, load_flags);
246 if(file->tag.title_is(labels->xml_tag))
248 if(load_flags & LOAD_TIMEBAR)
249 labels->load(file, load_flags);
252 if(file->tag.title_is(presentations->xml_tag))
254 if(load_flags & LOAD_TIMEBAR)
255 presentations->load(file, load_flags);
258 if(file->tag.title_is("LOCALSESSION"))
260 if((load_flags & LOAD_SESSION) ||
261 (load_flags & LOAD_TIMEBAR))
262 local_session->load_xml(file, load_flags);
265 if(file->tag.title_is("SESSION"))
267 if((load_flags & LOAD_SESSION) &&
269 session->load_xml(file, 0, load_flags);
272 if(file->tag.title_is("TRACK"))
274 tracks->load(file, track_offset, load_flags);
278 // Causes clip creation to fail because that involves an opening EDL tag.
279 if(file->tag.title_is("CLIP_EDL") && !parent_edl)
281 EDL *new_edl = new EDL(this);
282 new_edl->create_objects();
283 new_edl->load_xml(plugindb, file, LOAD_ALL);
285 if((load_flags & LOAD_ALL) == LOAD_ALL)
286 clips.append(new_edl);
291 if(file->tag.title_is("VWINDOW_EDL") && !parent_edl)
293 EDL *new_edl = new EDL(this);
294 new_edl->create_objects();
295 new_edl->load_xml(plugindb, file, LOAD_ALL);
298 if((load_flags & LOAD_ALL) == LOAD_ALL)
300 if(vwindow_edl) delete vwindow_edl;
301 vwindow_edl = new_edl;
311 //printf("EDL::load_xml 4\n");
314 //printf("EDL::load_xml 6 %p\n", parent_edl);
320 // Output path is the path of the output file if name truncation is desired.
321 // It is a "" if complete names should be used.
322 // Called recursively by copy for clips, thus the string can't be terminated.
323 // The string is not terminated in this call.
324 int EDL::save_xml(ArrayList<PluginServer*> *plugindb,
331 tracks->total_length(),
342 int EDL::copy_all(EDL *edl)
347 tracks->copy_from(edl->tracks);
348 labels->copy_from(edl->labels);
352 void EDL::copy_clips(EDL *edl)
354 if(vwindow_edl) delete vwindow_edl;
358 vwindow_edl = new EDL(this);
359 vwindow_edl->create_objects();
360 vwindow_edl->copy_all(edl->vwindow_edl);
362 clips.remove_all_objects();
363 for(int i = 0; i < edl->clips.total; i++)
365 add_clip(edl->clips.values[i]);
369 void EDL::copy_assets(EDL *edl)
373 assets->copy_from(edl->assets);
377 void EDL::copy_session(EDL *edl)
379 strcpy(this->project_path, edl->project_path);
381 folders.remove_all_objects();
382 for(int i = 0; i < edl->folders.total; i++)
385 folders.append(new_folder = new char[strlen(edl->folders.values[i]) + 1]);
386 strcpy(new_folder, edl->folders.values[i]);
391 session->copy(edl->session);
394 local_session->copy_from(edl->local_session);
397 int EDL::copy_assets(double start,
401 ArrayList<PluginServer*> *plugindb,
404 ArrayList<Asset*> asset_list;
407 file->tag.set_title("ASSETS");
409 file->append_newline();
411 // Copy everything for a save
414 for(Asset *asset = assets->first;
418 asset_list.append(asset);
422 // Copy just the ones being used.
424 for(current = tracks->first;
430 current->copy_assets(start,
437 // Paths relativised here
438 for(int i = 0; i < asset_list.total; i++)
440 asset_list.values[i]->write(plugindb,
446 file->tag.set_title("/ASSETS");
448 file->append_newline();
449 file->append_newline();
453 int EDL::copy(double start,
459 ArrayList<PluginServer*> *plugindb,
463 //printf("EDL::copy 1\n");
466 file->tag.set_title("CLIP_EDL");
469 file->tag.set_title("VWINDOW_EDL");
472 file->tag.set_title("EDL");
473 // Save path for restoration of the project title from a backup.
474 if(this->project_path[0])
476 file->tag.set_property("PROJECT_PATH", project_path);
481 file->append_newline();
483 // Set clipboard samples only if copying to clipboard
486 file->tag.set_title("CLIPBOARD");
487 file->tag.set_property("LENGTH", end - start);
489 file->append_newline();
490 file->append_newline();
492 //printf("EDL::copy 1\n");
495 local_session->save_xml(file, start);
497 //printf("EDL::copy 1\n");
502 // Need to copy all this from child EDL if pasting is desired.
504 session->save_xml(file);
505 session->save_video_config(file);
506 session->save_audio_config(file);
509 for(int i = 0; i < folders.total; i++)
511 file->tag.set_title("FOLDER");
513 file->append_text(folders.values[i]);
514 file->tag.set_title("/FOLDER");
516 file->append_newline();
528 // Don't want this if using clipboard
534 vwindow_edl->save_xml(plugindb,
541 for(int i = 0; i < clips.total; i++)
542 clips.values[i]->save_xml(plugindb,
549 file->append_newline();
550 file->append_newline();
554 //printf("EDL::copy 1\n");
556 labels->copy(start, end, file);
557 //printf("EDL::copy 1\n");
558 presentations->copy(start, end, file);
559 //printf("EDL::copy 1\n");
560 tracks->copy(start, end, all, file, output_path);
561 //printf("EDL::copy 2\n");
565 file->tag.set_title("/CLIP_EDL");
568 file->tag.set_title("/VWINDOW_EDL");
570 file->tag.set_title("/EDL");
572 file->append_newline();
575 // For editing operations we want to rewind it for immediate pasting.
576 // For clips and saving to disk leave it alone.
579 file->terminate_string();
585 void EDL::rechannel()
587 for(Track *current = tracks->first; current; current = NEXT)
589 if(current->data_type == TRACK_AUDIO)
591 PanAutos *autos = current->automation->pan_autos;
592 ((PanAuto*)autos->default_auto)->rechannel();
593 for(PanAuto *keyframe = (PanAuto*)autos->first;
595 keyframe = (PanAuto*)keyframe->next)
597 keyframe->rechannel();
603 void EDL::resample(double old_rate, double new_rate, int data_type)
605 for(Track *current = tracks->first; current; current = NEXT)
607 if(current->data_type == data_type)
609 current->resample(old_rate, new_rate);
615 void EDL::synchronize_params(EDL *edl)
617 local_session->synchronize_params(edl->local_session);
618 for(Track *this_track = tracks->first, *that_track = edl->tracks->first;
619 this_track && that_track;
620 this_track = this_track->next,
621 that_track = that_track->next)
623 this_track->synchronize_params(that_track);
627 int EDL::trim_selection(double start,
640 tracks->total_length(),
648 int EDL::equivalent(double position1, double position2)
650 double half_frame = (double).5 / session->frame_rate;
651 if((session->cursor_on_frames &&
652 fabs(position2 - position1) < half_frame) ||
653 (fabs(position2 - position1) < half_frame))
659 double EDL::equivalent_output(EDL *edl)
662 session->equivalent_output(edl->session, &result);
663 tracks->equivalent_output(edl->tracks, &result);
668 void EDL::set_project_path(char *path)
670 strcpy(this->project_path, path);
673 void EDL::set_inpoint(double position)
675 if(equivalent(local_session->in_point, position) && local_session->in_point >= 0)
677 local_session->in_point = -1;
681 local_session->in_point = align_to_frame(position, 0);
682 if(local_session->out_point <= local_session->in_point) local_session->out_point = -1;
686 void EDL::set_outpoint(double position)
688 if(equivalent(local_session->out_point, position) && local_session->out_point >= 0)
690 local_session->out_point = -1;
694 local_session->out_point = align_to_frame(position, 0);
695 if(local_session->in_point >= local_session->out_point) local_session->in_point = -1;
700 int EDL::clear(double start,
708 tracks->clear_handle(start,
713 if(clear_labels && distance > 0)
714 labels->paste_silence(start,
726 presentations->clear(start, end);
729 // Need to put at beginning so a subsequent paste operation starts at the
731 local_session->selectionend =
732 local_session->selectionstart =
733 local_session->get_selectionstart();
737 void EDL::modify_edithandles(double oldposition,
744 tracks->modify_edithandles(oldposition,
750 labels->modify_handles(oldposition,
757 void EDL::modify_pluginhandles(double oldposition,
763 tracks->modify_pluginhandles(oldposition,
771 void EDL::paste_silence(double start,
777 labels->paste_silence(start, end);
778 tracks->paste_silence(start,
784 void EDL::remove_from_project(ArrayList<EDL*> *clips)
786 for(int i = 0; i < clips->total; i++)
788 for(int j = 0; j < this->clips.total; j++)
790 if(this->clips.values[j] == clips->values[i])
792 this->clips.remove_object(clips->values[i]);
798 void EDL::remove_from_project(ArrayList<Asset*> *assets)
802 for(int j = 0; j < clips.total; j++)
804 clips.values[j]->remove_from_project(assets);
807 // Remove from VWindow
809 vwindow_edl->remove_from_project(assets);
811 for(int i = 0; i < assets->total; i++)
813 // Remove from tracks
814 for(Track *track = tracks->first; track; track = track->next)
816 track->remove_asset(assets->values[i]);
819 // Remove from assets
822 this->assets->remove_asset(assets->values[i]);
827 void EDL::update_assets(EDL *src)
829 for(Asset *current = src->assets->first;
833 assets->update(current);
837 int EDL::get_tracks_height(Theme *theme)
839 int total_pixels = 0;
840 for(Track *current = tracks->first;
844 total_pixels += current->vertical_span(theme);
849 int64_t EDL::get_tracks_width()
851 int64_t total_pixels = 0;
852 for(Track *current = tracks->first;
856 int64_t pixels = current->horizontal_span();
857 if(pixels > total_pixels) total_pixels = pixels;
859 //printf("EDL::get_tracks_width %d\n", total_pixels);
863 int EDL::calculate_output_w(int single_channel)
865 if(single_channel) return session->output_w;
868 for(int i = 0; i < session->video_channels; i++)
870 if(session->vchannel_x[i] + session->output_w > widest) widest = session->vchannel_x[i] + session->output_w;
875 int EDL::calculate_output_h(int single_channel)
877 if(single_channel) return session->output_h;
880 for(int i = 0; i < session->video_channels; i++)
882 if(session->vchannel_y[i] + session->output_h > tallest) tallest = session->vchannel_y[i] + session->output_h;
887 // Get the total output size scaled to aspect ratio
888 void EDL::calculate_conformed_dimensions(int single_channel, float &w, float &h)
890 w = calculate_output_w(single_channel);
891 h = calculate_output_h(single_channel);
893 if((float)session->output_w / session->output_h > get_aspect_ratio())
896 (session->output_w / get_aspect_ratio() / session->output_h);
901 (h * get_aspect_ratio() / session->output_w);
905 float EDL::get_aspect_ratio()
907 return session->aspect_w / session->aspect_h;
916 printf("clip_title: %s parent_edl: %p\n", local_session->clip_title, parent_edl);
917 printf("selectionstart %f selectionend %f loop_start %f loop_end %f\n",
918 local_session->selectionstart,
919 local_session->selectionend,
920 local_session->loop_start,
921 local_session->loop_end);
925 printf("audio_channels: %d "
926 "audio_tracks: %d \n"
928 session->audio_channels,
929 session->audio_tracks,
930 session->sample_rate);
931 printf("video_channels: %d "
934 "frames_per_foot: %.2f\n"
940 session->video_channels,
941 session->video_tracks,
943 session->frames_per_foot,
948 session->color_model);
951 printf(" total: %d\n", clips.total);
953 for(int i = 0; i < clips.total; i++)
956 clips.values[i]->dump();
967 //printf("EDL::dump 2\n");
971 EDL* EDL::add_clip(EDL *edl)
973 // Copy argument. New edls are deleted from MWindow::load_filenames.
974 EDL *new_edl = new EDL(this);
975 new_edl->create_objects();
976 new_edl->copy_all(edl);
977 clips.append(new_edl);
981 void EDL::insert_asset(Asset *asset,
984 RecordLabels *labels)
986 // Insert asset into asset table
987 Asset *new_asset = assets->update(asset);
992 Track *current = first_track ? first_track : tracks->first;
995 // Fix length of single frame
999 if(new_asset->video_length < 0)
1000 length = 1.0 / session->frame_rate;
1002 if(new_asset->frame_rate > 0)
1003 length = ((double)new_asset->video_length / new_asset->frame_rate);
1005 length = 1.0 / session->frame_rate;
1008 current && vtrack < new_asset->layers;
1011 if(!current->record ||
1012 current->data_type != TRACK_VIDEO)
1015 current->insert_asset(new_asset,
1024 for(current = tracks->first;
1025 current && atrack < new_asset->channels;
1028 if(!current->record ||
1029 current->data_type != TRACK_AUDIO)
1032 current->insert_asset(new_asset,
1033 (double)new_asset->audio_length /
1034 new_asset->sample_rate,
1044 for(RecordLabel *label = labels->first; label; label = label->next)
1046 this->labels->toggle_label(label->position, label->position);
1053 void EDL::set_index_file(Asset *asset)
1055 assets->update_index(asset);
1058 void EDL::optimize()
1060 //printf("EDL::optimize 1\n");
1061 double length = tracks->total_length();
1062 if(local_session->preview_end > length) local_session->preview_end = length;
1063 if(local_session->preview_start > length ||
1064 local_session->preview_start < 0) local_session->preview_start = 0;
1065 for(Track *current = tracks->first; current; current = NEXT)
1066 current->optimize();
1071 return EDLSession::current_id++;
1074 void EDL::get_shared_plugins(Track *source,
1075 ArrayList<SharedLocation*> *plugin_locations)
1077 for(Track *track = tracks->first; track; track = track->next)
1079 if(track != source &&
1080 track->data_type == source->data_type)
1082 for(int i = 0; i < track->plugin_set.total; i++)
1084 Plugin *plugin = track->get_current_plugin(local_session->selectionstart,
1089 if(plugin && plugin->plugin_type == PLUGIN_STANDALONE)
1091 plugin_locations->append(new SharedLocation(tracks->number_of(track), i));
1098 void EDL::get_shared_tracks(Track *track, ArrayList<SharedLocation*> *module_locations)
1100 for(Track *current = tracks->first; current; current = NEXT)
1102 if(current != track &&
1103 current->data_type == track->data_type)
1105 module_locations->append(new SharedLocation(tracks->number_of(current), 0));
1110 // Convert position to frames if cursor alignment is enabled
1111 double EDL::align_to_frame(double position, int round)
1113 //printf("EDL::align_to_frame 1 %f\n", position);
1114 if(session->cursor_on_frames)
1116 // Seconds -> Frames
1117 double temp = (double)position * session->frame_rate;
1118 //printf("EDL::align_to_frame 2 %f\n", temp);
1120 // Assert some things
1121 if(session->sample_rate == 0)
1122 printf("EDL::align_to_frame: sample_rate == 0\n");
1124 if(session->frame_rate == 0)
1125 printf("EDL::align_to_frame: frame_rate == 0\n");
1128 // Always round down negative numbers
1129 // but round up only if requested
1132 temp = Units::round(temp);
1141 temp = Units::to_int64(temp);
1143 //printf("EDL::align_to_frame 3 %f\n", temp);
1145 // Frames -> Seconds
1146 temp /= session->frame_rate;
1148 //printf("EDL::align_to_frame 5 %f\n", temp);
1152 //printf("EDL::align_to_frame 3 %d\n", position);
1159 void EDL::new_folder(char *folder)
1161 for(int i = 0; i < folders.total; i++)
1163 if(!strcasecmp(folders.values[i], folder)) return;
1167 folders.append(new_folder = new char[strlen(folder) + 1]);
1168 strcpy(new_folder, folder);
1171 void EDL::delete_folder(char *folder)
1174 for(i = 0; i < folders.total; i++)
1176 if(!strcasecmp(folders.values[i], folder))
1182 if(i < folders.total) delete folders.values[i];
1184 for( ; i < folders.total - 1; i++)
1186 folders.values[i] = folders.values[i + 1];