r125: This commit was manufactured by cvs2svn to create tag 'r1_1_7-last'.
[cinelerra_cv/mob.git] / hvirtual / cinelerra / edl.C
blob70c647dee6fee0004e6709f8673e247bad48fe31
1 #include "assets.h"
2 #include "atrack.h"
3 #include "autoconf.h"
4 #include "automation.h"
5 #include "awindowgui.inc"
6 #include "clip.h"
7 #include "colormodels.h"
8 #include "defaults.h"
9 #include "edl.h"
10 #include "edlsession.h"
11 #include "filexml.h"
12 #include "guicast.h"
13 #include "labels.h"
14 #include "localsession.h"
15 #include "panauto.h"
16 #include "panautos.h"
17 #include "playbackconfig.h"
18 #include "plugin.h"
19 #include "preferences.h"
20 #include "recordconfig.h"
21 #include "recordlabel.h"
22 #include "sharedlocation.h"
23 #include "theme.h"
24 #include "tracks.h"
25 #include "transportque.inc"
26 #include "vtrack.h"
28 EDL::EDL(EDL *parent_edl)
30         this->parent_edl = parent_edl;
31         tracks = 0;
32         labels = 0;
33         local_session = 0;
34         presentations = 0;
35         vwindow_edl = 0;
37         folders.set_array_delete();
38         new_folder(CLIP_FOLDER);
39         new_folder(MEDIA_FOLDER);
40         id = next_id();
44 EDL::~EDL()
46 //printf("EDL::~EDL 1\n");
47         if(tracks)
48         {
49                 delete tracks;
50         }
51         if(labels)
52         {
53                 delete labels;
54         }
55         if(presentations)
56         {
57                 delete presentations;
58         }
60         if(local_session)
61         {
62                 delete local_session;
63         }
65         if(vwindow_edl)
66                 delete vwindow_edl;
68         if(!parent_edl)
69         {
70                 delete assets;
71                 delete session;
72         }
75         folders.remove_all_objects();
76         clips.remove_all_objects();
77 //printf("EDL::~EDL 2\n");
81 int EDL::create_objects()
83         tracks = new Tracks(this);
84         if(!parent_edl)
85         {
86                 assets = new Assets(this);
87                 session = new EDLSession(this);
88         }
89         else
90         {
91                 assets = parent_edl->assets;
92                 session = parent_edl->session;
93         }
94         
95         local_session = new LocalSession(this);
96         labels = new Labels(this, "LABELS");
97         presentations = new Presentations(this);
98 //      last_playback_position = 0;
99         return 0;
102 EDL& EDL::operator=(EDL &edl)
104 //printf("EDL::operator= 1\n");
105         copy_all(&edl);
106 //printf("EDL::operator= 2\n");
107         return *this;
110 int EDL::load_defaults(Defaults *defaults)
112         if(!parent_edl)
113                 session->load_defaults(defaults);
115         local_session->load_defaults(defaults);
116         return 0;
119 int EDL::save_defaults(Defaults *defaults)
121         if(!parent_edl)
122                 session->save_defaults(defaults);
123         
124         local_session->save_defaults(defaults);
125         return 0;
128 void EDL::boundaries()
130         session->boundaries();
131         local_session->boundaries();
134 int EDL::create_default_tracks()
137         for(int i = 0; i < session->video_tracks; i++)
138         {
139                 tracks->add_video_track(0, 0);
140         }
141         for(int i = 0; i < session->audio_tracks; i++)
142         {
143                 tracks->add_audio_track(0, 0);
144         }
145         return 0;
148 int EDL::load_xml(ArrayList<PluginServer*> *plugindb,
149         FileXML *file, 
150         uint32_t load_flags)
152         int result = 0;
153 // Track numbering offset for replacing undo data.
154         int track_offset = 0;
156         folders.remove_all_objects();
158 // Search for start of master EDL.
160 // The parent_edl test caused clip creation to fail since those XML files
161 // contained an EDL tag.
163 // The parent_edl test is required to make EDL loading work because
164 // when loading an EDL the EDL tag is already read by the parent.
166         if(!parent_edl /* && (load_flags & LOAD_ALL) == LOAD_ALL */)
167         {
168                 do{
169                   result = file->read_tag();
170                 }while(!result && 
171                         !file->tag.title_is("XML") && 
172                         !file->tag.title_is("EDL"));
173         }
175         if(!result)
176         {
177 // Erase everything
178                 if((load_flags & LOAD_ALL) == LOAD_ALL ||
179                         (load_flags & LOAD_EDITS) == LOAD_EDITS)
180                 {
181                         while(tracks->last) delete tracks->last;
182                 }
184                 if((load_flags & LOAD_ALL) == LOAD_ALL)
185                 {
186                         clips.remove_all_objects();
187                 }
189                 if(load_flags & LOAD_TIMEBAR)
190                 {
191                         while(labels->last) delete labels->last;
192                         local_session->in_point = -1;
193                         local_session->out_point = -1;
194                 }
196                 do{
197                         result = file->read_tag();
199                         if(!result)
200                         {
201                                 if(file->tag.title_is("/XML") ||
202                                         file->tag.title_is("/EDL") ||
203                                         file->tag.title_is("/CLIP_EDL") ||
204                                         file->tag.title_is("/VWINDOW_EDL"))
205                                 {
206                                         result = 1;
207                                 }
208                                 else
209                                 if(file->tag.title_is("CLIPBOARD"))
210                                 {
211                                         local_session->clipboard_length = file->tag.get_property("LENGTH", 0);
212                                 }
213                                 else
214                                 if(file->tag.title_is("VIDEO"))
215                                 {
216                                         if((load_flags & LOAD_VCONFIG) &&
217                                                 (load_flags & LOAD_SESSION))
218                                                 session->load_video_config(file, 0, load_flags);
219                                 }
220                                 else
221                                 if(file->tag.title_is("AUDIO"))
222                                 {
223                                         if((load_flags & LOAD_ACONFIG) &&
224                                                 (load_flags & LOAD_SESSION))
225                                                 session->load_audio_config(file, 0, load_flags);
226                                 }
227                                 else
228                                 if(file->tag.title_is("FOLDER"))
229                                 {
230                                         char folder[BCTEXTLEN];
231                                         strcpy(folder, file->read_text());
232                                         new_folder(folder);
233                                 }
234                                 else
235                                 if(file->tag.title_is("ASSETS"))
236                                 {
237                                         if(load_flags & LOAD_ASSETS)
238                                                 assets->load(plugindb, file, load_flags);
239                                 }
240                                 else
241                                 if(file->tag.title_is(labels->xml_tag))
242                                 {
243                                         if(load_flags & LOAD_TIMEBAR)
244                                                 labels->load(file, load_flags);
245                                 }
246                                 else
247                                 if(file->tag.title_is(presentations->xml_tag))
248                                 {
249                                         if(load_flags & LOAD_TIMEBAR)
250                                                 presentations->load(file, load_flags);
251                                 }
252                                 else
253                                 if(file->tag.title_is("LOCALSESSION"))
254                                 {
255                                         if((load_flags & LOAD_SESSION) ||
256                                                 (load_flags & LOAD_TIMEBAR))
257                                                 local_session->load_xml(file, load_flags);
258                                 }
259                                 else
260                                 if(file->tag.title_is("SESSION"))
261                                 {
262                                         if((load_flags & LOAD_SESSION) &&
263                                                 !parent_edl)
264                                                 session->load_xml(file, 0, load_flags);
265                                 }
266                                 else
267                                 if(file->tag.title_is("TRACK"))
268                                 {
269                                         tracks->load(file, track_offset, load_flags);
270                                 }
271                                 else
272 // Sub EDL.
273 // Causes clip creation to fail because that involves an opening EDL tag.
274                                 if(file->tag.title_is("CLIP_EDL") && !parent_edl)
275                                 {
276                                         EDL *new_edl = new EDL(this);
277                                         new_edl->create_objects();
278                                         new_edl->load_xml(plugindb, file, LOAD_ALL);
280                                         if((load_flags & LOAD_ALL) == LOAD_ALL)
281                                                 clips.append(new_edl);
282                                         else
283                                                 delete new_edl;
284                                 }
285                                 else
286                                 if(file->tag.title_is("VWINDOW_EDL") && !parent_edl)
287                                 {
288                                         EDL *new_edl = new EDL(this);
289                                         new_edl->create_objects();
290                                         new_edl->load_xml(plugindb, file, LOAD_ALL);
293                                         if((load_flags & LOAD_ALL) == LOAD_ALL)
294                                         {
295                                                 if(vwindow_edl) delete vwindow_edl;
296                                                 vwindow_edl = new_edl;
297                                         }
298                                         else
299                                         {
300                                                 delete new_edl;
301                                                 new_edl = 0;
302                                         }
303                                 }
304                         }
305                 }while(!result);
306 //printf("EDL::load_xml 4\n");
307         }
308 //printf("EDL::load_xml 6 %p\n", parent_edl);
309 //dump();
311         return 0;
314 // Output path is the path of the output file if name truncation is desired.
315 // It is a "" if complete names should be used.
316 // Called recursively by copy for clips, thus the string can't be terminated.
317 // The string is not terminated in this call.
318 int EDL::save_xml(ArrayList<PluginServer*> *plugindb,
319         FileXML *file, 
320         char *output_path,
321         int is_clip,
322         int is_vwindow)
324         copy(0, 
325                 tracks->total_length(), 
326                 1, 
327                 is_clip,
328                 is_vwindow,
329                 file, 
330                 plugindb, 
331                 output_path,
332                 0);
333         return 0;
336 int EDL::copy_all(EDL *edl)
338         copy_session(edl);
339         copy_assets(edl);
340         copy_clips(edl);
341         *this->tracks = *edl->tracks;
342         *this->labels = *edl->labels;
343         return 0;
346 void EDL::copy_clips(EDL *edl)
348         if(vwindow_edl) delete vwindow_edl;
349         vwindow_edl = 0;
350         if(edl->vwindow_edl)
351         {
352                 vwindow_edl = new EDL(this);
353                 vwindow_edl->create_objects();
354                 vwindow_edl->copy_all(edl->vwindow_edl);
355         }
356         clips.remove_all_objects();
357         for(int i = 0; i < edl->clips.total; i++)
358         {
359                 add_clip(edl->clips.values[i]);
360         }
363 void EDL::copy_assets(EDL *edl)
365         if(!parent_edl)
366                 *this->assets = *edl->assets;
369 void EDL::copy_session(EDL *edl)
371         folders.remove_all_objects();
372         for(int i = 0; i < edl->folders.total; i++)
373         {
374                 char *new_folder;
375                 folders.append(new_folder = new char[strlen(edl->folders.values[i]) + 1]);
376                 strcpy(new_folder, edl->folders.values[i]);
377         }
379         if(!parent_edl)
380         {
381                 session->copy(edl->session);
382         }
383         
384         local_session->copy_from(edl->local_session);
387 int EDL::copy_assets(double start, 
388         double end, 
389         FileXML *file, 
390         int all, 
391         ArrayList<PluginServer*> *plugindb,
392         char *output_path)
394         ArrayList<Asset*> asset_list;
395         Track* current;
397         file->tag.set_title("ASSETS");
398         file->append_tag();
399         file->append_newline();
401 // Copy everything for a save
402         if(all)
403         {
404                 for(Asset *asset = assets->first;
405                         asset;
406                         asset = asset->next)
407                 {
408                         asset_list.append(asset);
409                 }
410         }
411         else
412 // Copy just the ones being used.
413         {
414                 for(current = tracks->first; 
415                         current; 
416                         current = NEXT)
417                 {
418                         if(current->record)
419                         {
420                                 current->copy_assets(start, 
421                                         end, 
422                                         &asset_list);
423                         }
424                 }
425         }
427 // Paths relativised here
428         for(int i = 0; i < asset_list.total; i++)
429         {
430                 asset_list.values[i]->write(plugindb,
431                         file, 
432                         0, 
433                         output_path);
434         }
436         file->tag.set_title("/ASSETS");
437         file->append_tag();
438         file->append_newline();
439         file->append_newline();
440         return 0;
443 int EDL::copy(double start, 
444         double end, 
445         int all, 
446         int is_clip,
447         int is_vwindow,
448         FileXML *file, 
449         ArrayList<PluginServer*> *plugindb, 
450         char *output_path,
451         int rewind_it)
453 //printf("EDL::copy 1\n");
454 // begin file
455         if(is_clip)
456                 file->tag.set_title("CLIP_EDL");
457         else
458         if(is_vwindow)
459                 file->tag.set_title("VWINDOW_EDL");
460         else
461                 file->tag.set_title("EDL");
463         file->append_tag();
464         file->append_newline();
466 // Set clipboard samples only if copying to clipboard
467         if(!all)
468         {
469                 file->tag.set_title("CLIPBOARD");
470                 file->tag.set_property("LENGTH", end - start);
471                 file->append_tag();
472                 file->append_newline();
473                 file->append_newline();
474         }
475 //printf("EDL::copy 1\n");
477 // Sessions
478         local_session->save_xml(file, start);
480 //printf("EDL::copy 1\n");
482 // Top level stuff.
483 //      if(!parent_edl)
484         {
485 // Need to copy all this from child EDL if pasting is desired.
486 // Session
487                 session->save_xml(file);
488                 session->save_video_config(file);
489                 session->save_audio_config(file);
491 // Folders
492                 for(int i = 0; i < folders.total; i++)
493                 {
494                         file->tag.set_title("FOLDER");
495                         file->append_tag();
496                         file->append_text(folders.values[i]);
497                         file->tag.set_title("/FOLDER");
498                         file->append_tag();
499                         file->append_newline();
500                 }
502 // Media
503                 copy_assets(start, 
504                         end, 
505                         file, 
506                         all, 
507                         plugindb,
508                         output_path);
510 // Clips
511 // Don't want this if using clipboard
512                 if(all)
513                 {
514                         if(vwindow_edl)
515                         {
516                                 
517                                 vwindow_edl->save_xml(plugindb, 
518                                         file, 
519                                         output_path,
520                                         0,
521                                         1);
522                         }
524                         for(int i = 0; i < clips.total; i++)
525                                 clips.values[i]->save_xml(plugindb, 
526                                         file, 
527                                         output_path,
528                                         1,
529                                         0);
530                 }
532                 file->append_newline();
533                 file->append_newline();
534         }
537 //printf("EDL::copy 1\n");
539         labels->copy(start, end, file);
540 //printf("EDL::copy 1\n");
541         presentations->copy(start, end, file);
542 //printf("EDL::copy 1\n");
543         tracks->copy(start, end, all, file, output_path);
544 //printf("EDL::copy 2\n");
546 // terminate file
547         if(is_clip)
548                 file->tag.set_title("/CLIP_EDL");
549         else
550         if(is_vwindow)
551                 file->tag.set_title("/VWINDOW_EDL");
552         else
553                 file->tag.set_title("/EDL");
554         file->append_tag();
555         file->append_newline();
558 // For editing operations we want to rewind it for immediate pasting.
559 // For clips and saving to disk leave it alone.
560         if(rewind_it)
561         {
562                 file->terminate_string();
563                 file->rewind();
564         }
565         return 0;
568 void EDL::rechannel()
570         for(Track *current = tracks->first; current; current = NEXT)
571         {
572                 if(current->data_type == TRACK_AUDIO)
573                 {
574                         PanAutos *autos = current->automation->pan_autos;
575                         ((PanAuto*)autos->default_auto)->rechannel();
576                         for(PanAuto *keyframe = (PanAuto*)autos->first;
577                                 keyframe;
578                                 keyframe = (PanAuto*)keyframe->next)
579                         {
580                                 keyframe->rechannel();
581                         }
582                 }
583         }
586 void EDL::resample(double old_rate, double new_rate, int data_type)
588         for(Track *current = tracks->first; current; current = NEXT)
589         {
590                 if(current->data_type == data_type)
591                 {
592                         current->resample(old_rate, new_rate);
593                 }
594         }
598 void EDL::synchronize_params(EDL *edl)
600         local_session->synchronize_params(edl->local_session);
601         for(Track *this_track = tracks->first, *that_track = edl->tracks->first; 
602                 this_track && that_track; 
603                 this_track = this_track->next,
604                 that_track = that_track->next)
605         {
606                 this_track->synchronize_params(that_track);
607         }
610 int EDL::trim_selection(double start, 
611         double end,
612         int edit_labels,
613         int edit_plugins)
615         if(start != end)
616         {
617 // clear the data
618                 clear(0, 
619                         start,
620                         edit_labels,
621                         edit_plugins);
622                 clear(end - start, 
623                         tracks->total_length(),
624                         edit_labels,
625                         edit_plugins);
626         }
627         return 0;
631 int EDL::equivalent(double position1, double position2)
633         double half_frame = (double).5 / session->frame_rate;
634         if((session->cursor_on_frames && 
635                 fabs(position2 - position1) < half_frame) ||
636                 (fabs(position2 - position1) < half_frame))
637         return 1;
638     else
639         return 0;
642 double EDL::equivalent_output(EDL *edl)
644         double result = -1;
645 //printf("EDL::equivalent_output 1 %f\n", result);
646         session->equivalent_output(edl->session, &result);
647 //printf("EDL::equivalent_output 2 %f\n", result);
648         tracks->equivalent_output(edl->tracks, &result);
649 //printf("EDL::equivalent_output 3 %f\n", result);
650         return result;
654 void EDL::set_inpoint(double position)
656         if(equivalent(local_session->in_point, position) && local_session->in_point >= 0)
657         {
658                 local_session->in_point = -1;
659         }
660         else
661         {
662                 local_session->in_point = align_to_frame(position, 0);
663                 if(local_session->out_point <= local_session->in_point) local_session->out_point = -1;
664         }
667 void EDL::set_outpoint(double position)
669         if(equivalent(local_session->out_point, position) && local_session->out_point >= 0)
670         {
671                 local_session->out_point = -1;
672         }
673         else
674         {
675                 local_session->out_point = align_to_frame(position, 0);
676                 if(local_session->in_point >= local_session->out_point) local_session->in_point = -1;
677         }
681 int EDL::clear(double start, 
682         double end, 
683         int clear_labels,
684         int clear_plugins)
686         if(start == end)
687         {
688                 double distance = 0;
689                 tracks->clear_handle(start, 
690                         end,
691                         distance, 
692                         clear_labels,
693                         clear_plugins);
694                 if(clear_labels && distance > 0)
695                         labels->paste_silence(start, 
696                                 start + distance);
697         }
698         else
699         {
700                 tracks->clear(start, 
701                         end,
702                         clear_plugins);
703                 if(clear_labels) 
704                         labels->clear(start, 
705                                 end, 
706                                 1);
707                 presentations->clear(start, end);
708         }
710 // Need to put at beginning so a subsequent paste operation starts at the
711 // right position.
712         local_session->selectionend = 
713                 local_session->selectionstart = 
714                 local_session->get_selectionstart();
715         return 0;
718 void EDL::modify_edithandles(double oldposition, 
719         double newposition, 
720         int currentend, 
721         int handle_mode,
722         int edit_labels,
723         int edit_plugins)
725         tracks->modify_edithandles(oldposition, 
726                 newposition, 
727                 currentend, 
728                 handle_mode,
729                 edit_labels, 
730                 edit_plugins);
731         labels->modify_handles(oldposition, 
732                 newposition, 
733                 currentend,
734                 handle_mode,
735                 edit_labels);
738 void EDL::modify_pluginhandles(double oldposition, 
739         double newposition, 
740         int currentend, 
741         int handle_mode,
742         int edit_labels)
744         tracks->modify_pluginhandles(oldposition, 
745                 newposition, 
746                 currentend, 
747                 handle_mode,
748                 edit_labels);
749         optimize();
752 void EDL::paste_silence(double start, 
753         double end, 
754         int edit_labels, 
755         int edit_plugins)
757         if(edit_labels) 
758                 labels->paste_silence(start, end);
759         tracks->paste_silence(start, 
760                 end, 
761                 edit_plugins);
765 void EDL::remove_from_project(ArrayList<EDL*> *clips)
767         for(int i = 0; i < clips->total; i++)
768         {
769                 for(int j = 0; j < this->clips.total; j++)
770                 {
771                         if(this->clips.values[j] == clips->values[i])
772                         {
773                                 this->clips.remove_object(clips->values[i]);
774                         }
775                 }
776         }
779 void EDL::remove_from_project(ArrayList<Asset*> *assets)
781 // Remove from clips
782         if(!parent_edl)
783                 for(int j = 0; j < clips.total; j++)
784                 {
785                         clips.values[j]->remove_from_project(assets);
786                 }
788 // Remove from VWindow
789         if(vwindow_edl)
790                 vwindow_edl->remove_from_project(assets);
792         for(int i = 0; i < assets->total; i++)
793         {
794 // Remove from tracks
795                 for(Track *track = tracks->first; track; track = track->next)
796                 {
797                         track->remove_asset(assets->values[i]);
798                 }
800 // Remove from assets
801                 if(!parent_edl)
802                 {
803                         this->assets->remove_asset(assets->values[i]);
804                 }
805         }
808 void EDL::update_assets(EDL *src)
810         for(Asset *current = src->assets->first;
811                 current;
812                 current = NEXT)
813         {
814                 assets->update(current);
815         }
818 int EDL::get_tracks_height(Theme *theme)
820         int total_pixels = 0;
821         for(Track *current = tracks->first;
822                 current;
823                 current = NEXT)
824         {
825                 total_pixels += current->vertical_span(theme);
826         }
827         return total_pixels;
830 int64_t EDL::get_tracks_width()
832         int64_t total_pixels = 0;
833         for(Track *current = tracks->first;
834                 current;
835                 current = NEXT)
836         {
837                 int64_t pixels = current->horizontal_span();
838                 if(pixels > total_pixels) total_pixels = pixels;
839         }
840 //printf("EDL::get_tracks_width %d\n", total_pixels);
841         return total_pixels;
844 int EDL::calculate_output_w(int single_channel)
846         if(single_channel) return session->output_w;
848         int widest = 0;
849         for(int i = 0; i < session->video_channels; i++)
850         {
851                 if(session->vchannel_x[i] + session->output_w > widest) widest = session->vchannel_x[i] + session->output_w;
852         }
853         return widest;
856 int EDL::calculate_output_h(int single_channel)
858         if(single_channel) return session->output_h;
860         int tallest = 0;
861         for(int i = 0; i < session->video_channels; i++)
862         {
863                 if(session->vchannel_y[i] + session->output_h > tallest) tallest = session->vchannel_y[i] + session->output_h;
864         }
865         return tallest;
868 // Get the total output size scaled to aspect ratio
869 void EDL::calculate_conformed_dimensions(int single_channel, float &w, float &h)
871         w = calculate_output_w(single_channel);
872         h = calculate_output_h(single_channel);
874         if((float)session->output_w / session->output_h > get_aspect_ratio())
875         {
876                 h = (float)h * 
877                         (session->output_w / get_aspect_ratio() / session->output_h);
878         }
879         else
880         {
881                 w = (float)w * 
882                         (h * get_aspect_ratio() / session->output_w);
883         }
886 float EDL::get_aspect_ratio()
888         return session->aspect_w / session->aspect_h;
891 int EDL::dump()
893         if(parent_edl)
894                 printf("CLIP\n");
895         else
896                 printf("EDL\n");
897         printf("clip_title: %s parent_edl: %p\n", local_session->clip_title, parent_edl);
898         printf("selectionstart %f selectionend %f loop_start %f loop_end %f\n", 
899                 local_session->selectionstart, 
900                 local_session->selectionend,
901                 local_session->loop_start,
902                 local_session->loop_end);
904         if(!parent_edl)
905         {
906                 printf("audio_channels: %d "
907                         "audio_tracks: %d \n"
908                         "sample_rate: %d\n",
909                         session->audio_channels,
910                         session->audio_tracks,
911                         session->sample_rate);
912                 printf("video_channels: %d "
913                         "video_tracks: %d "
914                         "frame_rate: %.2f "
915                         "frames_per_foot: %.2f\n"
916                 "output_w: %d "
917                 "output_h: %d "
918                 "aspect_w: %f "
919                 "aspect_h %f "
920                         "color_model %d\n",
921                                 session->video_channels,
922                                 session->video_tracks,
923                                 session->frame_rate,
924                                 session->frames_per_foot,
925                         session->output_w,
926                         session->output_h,
927                         session->aspect_w,
928                         session->aspect_h,
929                                 session->color_model);
931                 printf(" EDLS\n");
932                 printf("  total: %d\n", clips.total);
933         
934                 for(int i = 0; i < clips.total; i++)
935                 {
936                         printf("\n\n");
937                         clips.values[i]->dump();
938                         printf("\n\n");
939                 }
941                 printf(" ASSETS\n");
942                 assets->dump();
943         }
944         printf(" LABELS\n");
945         labels->dump();
946         printf(" TRACKS\n");
947         tracks->dump();
948 //printf("EDL::dump 2\n");
949         return 0;
952 EDL* EDL::add_clip(EDL *edl)
954 // Copy argument.  New edls are deleted from MWindow::load_filenames.
955         EDL *new_edl = new EDL(this);
956         new_edl->create_objects();
957         new_edl->copy_all(edl);
958         clips.append(new_edl);
959         return new_edl;
962 void EDL::insert_asset(Asset *asset, 
963         double position, 
964         Track *first_track, 
965         RecordLabels *labels)
967 // Insert asset into asset table
968         Asset *new_asset = assets->update(asset);
970 // Paste video
971         int vtrack = 0;
972         Track *current = first_track ? first_track : tracks->first;
974 //printf("EDL::insert_asset 1\n");
976 // Fix length of single frame
977         double length;
978         
979         
980         if(new_asset->video_length < 0) 
981                 length = 1.0 / session->frame_rate; 
982         else
983         if(new_asset->frame_rate > 0)
984                 length = ((double)new_asset->video_length / new_asset->frame_rate);
985         else
986                 length = 1.0 / session->frame_rate;
988 //printf("EDL::insert_asset 2 %f\n", length);
989         for( ;
990                 current && vtrack < new_asset->layers;
991                 current = NEXT)
992         {
993                 if(!current->record || 
994                         current->data_type != TRACK_VIDEO)
995                         continue;
997 //printf("EDL::insert_asset 3\n");
998                 current->insert_asset(new_asset, 
999                         length, 
1000                         position, 
1001                         vtrack);
1003 //printf("EDL::insert_asset 4\n");
1004                 vtrack++;
1005         }
1007         int atrack = 0;
1008         for(current = tracks->first;
1009                 current && atrack < new_asset->channels;
1010                 current = NEXT)
1011         {
1012                 if(!current->record ||
1013                         current->data_type != TRACK_AUDIO)
1014                         continue;
1016 //printf("EDL::insert_asset 5\n");
1017                 current->insert_asset(new_asset, 
1018                         (double)new_asset->audio_length / 
1019                                 new_asset->sample_rate, 
1020                         position, 
1021                         atrack);
1023 //printf("EDL::insert_asset 6\n");
1025                 atrack++;
1026         }
1028         if(labels)
1029         {
1030                 for(RecordLabel *label = labels->first; label; label = label->next)
1031                 {
1032 //printf("EDL::insert_asset 1 %f\n", label->position);
1033                         this->labels->toggle_label(label->position, label->position);
1034                 }
1035         }
1037 //      optimize();
1042 void EDL::set_index_file(Asset *asset)
1044         assets->update_index(asset);
1047 void EDL::optimize()
1049 //printf("EDL::optimize 1\n");
1050         double length = tracks->total_length();
1051         if(local_session->preview_end > length) local_session->preview_end = length;
1052         if(local_session->preview_start > length ||
1053                 local_session->preview_start < 0) local_session->preview_start = 0;
1054         for(Track *current = tracks->first; current; current = NEXT)
1055                 current->optimize();
1058 int EDL::next_id()
1060         return EDLSession::current_id++;
1063 void EDL::get_shared_plugins(Track *source, 
1064         ArrayList<SharedLocation*> *plugin_locations)
1066         for(Track *track = tracks->first; track; track = track->next)
1067         {
1068                 if(track != source && 
1069                         track->data_type == source->data_type)
1070                 {
1071                         for(int i = 0; i < track->plugin_set.total; i++)
1072                         {
1073                                 Plugin *plugin = track->get_current_plugin(local_session->selectionstart, 
1074                                         i, 
1075                                         PLAY_FORWARD, 
1076                                         1);
1077                                 if(plugin && plugin->plugin_type == PLUGIN_STANDALONE)
1078                                 {
1079                                         plugin_locations->append(new SharedLocation(tracks->number_of(track), i));
1080                                 }
1081                         }
1082                 }
1083         }
1086 void EDL::get_shared_tracks(Track *track, ArrayList<SharedLocation*> *module_locations)
1088         for(Track *current = tracks->first; current; current = NEXT)
1089         {
1090                 if(current != track && 
1091                         current->data_type == track->data_type)
1092                 {
1093                         module_locations->append(new SharedLocation(tracks->number_of(current), 0));
1094                 }
1095         }
1098 // Convert position to frames if cursor alignment is enabled
1099 double EDL::align_to_frame(double position, int round)
1101 //printf("EDL::align_to_frame 1 %f\n", position);
1102         if(session->cursor_on_frames)
1103         {
1104 // Seconds -> Frames
1105                 double temp = (double)position * session->frame_rate;
1106 //printf("EDL::align_to_frame 2 %f\n", temp);
1108 // Assert some things
1109                 if(session->sample_rate == 0)
1110                         printf("EDL::align_to_frame: sample_rate == 0\n");
1112                 if(session->frame_rate == 0)
1113                         printf("EDL::align_to_frame: frame_rate == 0\n");
1115 // Round frames
1116 // Always round down negative numbers
1117 // but round up only if requested
1118                 if(round) 
1119                 {
1120                         temp = Units::round(temp);
1121                 }
1122                 else
1123                 {
1124 //                      if(temp < 0)
1125 //                      {
1126 //                              temp -= 0.5;
1127 //                      }
1128 //                      else
1129                                 temp = Units::to_int64(temp);
1130                 }
1131 //printf("EDL::align_to_frame 3 %f\n", temp);
1133 // Frames -> Seconds
1134                 temp /= session->frame_rate;
1136 //printf("EDL::align_to_frame 5 %f\n", temp);
1138                 return temp;
1139         }
1140 //printf("EDL::align_to_frame 3 %d\n", position);
1143         return position;
1147 void EDL::new_folder(char *folder)
1149         for(int i = 0; i < folders.total; i++)
1150         {
1151                 if(!strcasecmp(folders.values[i], folder)) return;
1152         }
1154         char *new_folder;
1155         folders.append(new_folder = new char[strlen(folder) + 1]);
1156         strcpy(new_folder, folder);
1159 void EDL::delete_folder(char *folder)
1161         int i;
1162         for(i = 0; i < folders.total; i++)
1163         {
1164                 if(!strcasecmp(folders.values[i], folder))
1165                 {
1166                         break;
1167                 }
1168         }
1170         if(i < folders.total) delete folders.values[i];
1172         for( ; i < folders.total - 1; i++)
1173         {
1174                 folders.values[i] = folders.values[i + 1];
1175         }