r136: This commit was manufactured by cvs2svn to create tag 'hv_1_1_8'.
[cinelerra_cv/mob.git] / hvirtual / cinelerra / edl.C
blob93c7feecb5c03eee1d72fa4bd1ae03afe03eeb99
1 #include "asset.h"
2 #include "assets.h"
3 #include "atrack.h"
4 #include "autoconf.h"
5 #include "automation.h"
6 #include "awindowgui.inc"
7 #include "clip.h"
8 #include "colormodels.h"
9 #include "defaults.h"
10 #include "edl.h"
11 #include "edlsession.h"
12 #include "filexml.h"
13 #include "guicast.h"
14 #include "labels.h"
15 #include "localsession.h"
16 #include "panauto.h"
17 #include "panautos.h"
18 #include "playbackconfig.h"
19 #include "plugin.h"
20 #include "preferences.h"
21 #include "recordconfig.h"
22 #include "recordlabel.h"
23 #include "sharedlocation.h"
24 #include "theme.h"
25 #include "tracks.h"
26 #include "transportque.inc"
27 #include "vtrack.h"
29 EDL::EDL(EDL *parent_edl)
31         this->parent_edl = parent_edl;
32         tracks = 0;
33         labels = 0;
34         local_session = 0;
35         presentations = 0;
36         vwindow_edl = 0;
38         folders.set_array_delete();
39         new_folder(CLIP_FOLDER);
40         new_folder(MEDIA_FOLDER);
41         id = next_id();
45 EDL::~EDL()
47 //printf("EDL::~EDL 1\n");
48         if(tracks)
49         {
50                 delete tracks;
51         }
52         if(labels)
53         {
54                 delete labels;
55         }
56         if(presentations)
57         {
58                 delete presentations;
59         }
61         if(local_session)
62         {
63                 delete local_session;
64         }
66         if(vwindow_edl)
67                 delete vwindow_edl;
69         if(!parent_edl)
70         {
71                 delete assets;
72                 delete session;
73         }
76         folders.remove_all_objects();
77         clips.remove_all_objects();
78 //printf("EDL::~EDL 2\n");
82 int EDL::create_objects()
84         tracks = new Tracks(this);
85         if(!parent_edl)
86         {
87                 assets = new Assets(this);
88                 session = new EDLSession(this);
89         }
90         else
91         {
92                 assets = parent_edl->assets;
93                 session = parent_edl->session;
94         }
95         
96         local_session = new LocalSession(this);
97         labels = new Labels(this, "LABELS");
98         presentations = new Presentations(this);
99 //      last_playback_position = 0;
100         return 0;
103 EDL& EDL::operator=(EDL &edl)
105 //printf("EDL::operator= 1\n");
106         copy_all(&edl);
107 //printf("EDL::operator= 2\n");
108         return *this;
111 int EDL::load_defaults(Defaults *defaults)
113         if(!parent_edl)
114                 session->load_defaults(defaults);
116         local_session->load_defaults(defaults);
117         return 0;
120 int EDL::save_defaults(Defaults *defaults)
122         if(!parent_edl)
123                 session->save_defaults(defaults);
124         
125         local_session->save_defaults(defaults);
126         return 0;
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++)
139         {
140                 tracks->add_video_track(0, 0);
141         }
142         for(int i = 0; i < session->audio_tracks; i++)
143         {
144                 tracks->add_audio_track(0, 0);
145         }
146         return 0;
149 int EDL::load_xml(ArrayList<PluginServer*> *plugindb,
150         FileXML *file, 
151         uint32_t load_flags)
153         int result = 0;
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.
167         if(!parent_edl /* && (load_flags & LOAD_ALL) == LOAD_ALL */)
168         {
169                 do{
170                   result = file->read_tag();
171                 }while(!result && 
172                         !file->tag.title_is("XML") && 
173                         !file->tag.title_is("EDL"));
174         }
176         if(!result)
177         {
178 // Erase everything
179                 if((load_flags & LOAD_ALL) == LOAD_ALL ||
180                         (load_flags & LOAD_EDITS) == LOAD_EDITS)
181                 {
182                         while(tracks->last) delete tracks->last;
183                 }
185                 if((load_flags & LOAD_ALL) == LOAD_ALL)
186                 {
187                         clips.remove_all_objects();
188                 }
190                 if(load_flags & LOAD_TIMEBAR)
191                 {
192                         while(labels->last) delete labels->last;
193                         local_session->in_point = -1;
194                         local_session->out_point = -1;
195                 }
197                 do{
198                         result = file->read_tag();
200                         if(!result)
201                         {
202                                 if(file->tag.title_is("/XML") ||
203                                         file->tag.title_is("/EDL") ||
204                                         file->tag.title_is("/CLIP_EDL") ||
205                                         file->tag.title_is("/VWINDOW_EDL"))
206                                 {
207                                         result = 1;
208                                 }
209                                 else
210                                 if(file->tag.title_is("CLIPBOARD"))
211                                 {
212                                         local_session->clipboard_length = file->tag.get_property("LENGTH", 0);
213                                 }
214                                 else
215                                 if(file->tag.title_is("VIDEO"))
216                                 {
217                                         if((load_flags & LOAD_VCONFIG) &&
218                                                 (load_flags & LOAD_SESSION))
219                                                 session->load_video_config(file, 0, load_flags);
220                                 }
221                                 else
222                                 if(file->tag.title_is("AUDIO"))
223                                 {
224                                         if((load_flags & LOAD_ACONFIG) &&
225                                                 (load_flags & LOAD_SESSION))
226                                                 session->load_audio_config(file, 0, load_flags);
227                                 }
228                                 else
229                                 if(file->tag.title_is("FOLDER"))
230                                 {
231                                         char folder[BCTEXTLEN];
232                                         strcpy(folder, file->read_text());
233                                         new_folder(folder);
234                                 }
235                                 else
236                                 if(file->tag.title_is("ASSETS"))
237                                 {
238                                         if(load_flags & LOAD_ASSETS)
239                                                 assets->load(plugindb, file, load_flags);
240                                 }
241                                 else
242                                 if(file->tag.title_is(labels->xml_tag))
243                                 {
244                                         if(load_flags & LOAD_TIMEBAR)
245                                                 labels->load(file, load_flags);
246                                 }
247                                 else
248                                 if(file->tag.title_is(presentations->xml_tag))
249                                 {
250                                         if(load_flags & LOAD_TIMEBAR)
251                                                 presentations->load(file, load_flags);
252                                 }
253                                 else
254                                 if(file->tag.title_is("LOCALSESSION"))
255                                 {
256                                         if((load_flags & LOAD_SESSION) ||
257                                                 (load_flags & LOAD_TIMEBAR))
258                                                 local_session->load_xml(file, load_flags);
259                                 }
260                                 else
261                                 if(file->tag.title_is("SESSION"))
262                                 {
263                                         if((load_flags & LOAD_SESSION) &&
264                                                 !parent_edl)
265                                                 session->load_xml(file, 0, load_flags);
266                                 }
267                                 else
268                                 if(file->tag.title_is("TRACK"))
269                                 {
270                                         tracks->load(file, track_offset, load_flags);
271                                 }
272                                 else
273 // Sub EDL.
274 // Causes clip creation to fail because that involves an opening EDL tag.
275                                 if(file->tag.title_is("CLIP_EDL") && !parent_edl)
276                                 {
277                                         EDL *new_edl = new EDL(this);
278                                         new_edl->create_objects();
279                                         new_edl->load_xml(plugindb, file, LOAD_ALL);
281                                         if((load_flags & LOAD_ALL) == LOAD_ALL)
282                                                 clips.append(new_edl);
283                                         else
284                                                 delete new_edl;
285                                 }
286                                 else
287                                 if(file->tag.title_is("VWINDOW_EDL") && !parent_edl)
288                                 {
289                                         EDL *new_edl = new EDL(this);
290                                         new_edl->create_objects();
291                                         new_edl->load_xml(plugindb, file, LOAD_ALL);
294                                         if((load_flags & LOAD_ALL) == LOAD_ALL)
295                                         {
296                                                 if(vwindow_edl) delete vwindow_edl;
297                                                 vwindow_edl = new_edl;
298                                         }
299                                         else
300                                         {
301                                                 delete new_edl;
302                                                 new_edl = 0;
303                                         }
304                                 }
305                         }
306                 }while(!result);
307 //printf("EDL::load_xml 4\n");
308         }
309         boundaries();
310 //printf("EDL::load_xml 6 %p\n", parent_edl);
311 //dump();
313         return 0;
316 // Output path is the path of the output file if name truncation is desired.
317 // It is a "" if complete names should be used.
318 // Called recursively by copy for clips, thus the string can't be terminated.
319 // The string is not terminated in this call.
320 int EDL::save_xml(ArrayList<PluginServer*> *plugindb,
321         FileXML *file, 
322         char *output_path,
323         int is_clip,
324         int is_vwindow)
326         copy(0, 
327                 tracks->total_length(), 
328                 1, 
329                 is_clip,
330                 is_vwindow,
331                 file, 
332                 plugindb, 
333                 output_path,
334                 0);
335         return 0;
338 int EDL::copy_all(EDL *edl)
340         copy_session(edl);
341         copy_assets(edl);
342         copy_clips(edl);
343         *this->tracks = *edl->tracks;
344         *this->labels = *edl->labels;
345         return 0;
348 void EDL::copy_clips(EDL *edl)
350         if(vwindow_edl) delete vwindow_edl;
351         vwindow_edl = 0;
352         if(edl->vwindow_edl)
353         {
354                 vwindow_edl = new EDL(this);
355                 vwindow_edl->create_objects();
356                 vwindow_edl->copy_all(edl->vwindow_edl);
357         }
358         clips.remove_all_objects();
359         for(int i = 0; i < edl->clips.total; i++)
360         {
361                 add_clip(edl->clips.values[i]);
362         }
365 void EDL::copy_assets(EDL *edl)
367         if(!parent_edl)
368                 *this->assets = *edl->assets;
371 void EDL::copy_session(EDL *edl)
373         folders.remove_all_objects();
374         for(int i = 0; i < edl->folders.total; i++)
375         {
376                 char *new_folder;
377                 folders.append(new_folder = new char[strlen(edl->folders.values[i]) + 1]);
378                 strcpy(new_folder, edl->folders.values[i]);
379         }
381         if(!parent_edl)
382         {
383                 session->copy(edl->session);
384         }
385         
386         local_session->copy_from(edl->local_session);
389 int EDL::copy_assets(double start, 
390         double end, 
391         FileXML *file, 
392         int all, 
393         ArrayList<PluginServer*> *plugindb,
394         char *output_path)
396         ArrayList<Asset*> asset_list;
397         Track* current;
399         file->tag.set_title("ASSETS");
400         file->append_tag();
401         file->append_newline();
403 // Copy everything for a save
404         if(all)
405         {
406                 for(Asset *asset = assets->first;
407                         asset;
408                         asset = asset->next)
409                 {
410                         asset_list.append(asset);
411                 }
412         }
413         else
414 // Copy just the ones being used.
415         {
416                 for(current = tracks->first; 
417                         current; 
418                         current = NEXT)
419                 {
420                         if(current->record)
421                         {
422                                 current->copy_assets(start, 
423                                         end, 
424                                         &asset_list);
425                         }
426                 }
427         }
429 // Paths relativised here
430         for(int i = 0; i < asset_list.total; i++)
431         {
432                 asset_list.values[i]->write(plugindb,
433                         file, 
434                         0, 
435                         output_path);
436         }
438         file->tag.set_title("/ASSETS");
439         file->append_tag();
440         file->append_newline();
441         file->append_newline();
442         return 0;
445 int EDL::copy(double start, 
446         double end, 
447         int all, 
448         int is_clip,
449         int is_vwindow,
450         FileXML *file, 
451         ArrayList<PluginServer*> *plugindb, 
452         char *output_path,
453         int rewind_it)
455 //printf("EDL::copy 1\n");
456 // begin file
457         if(is_clip)
458                 file->tag.set_title("CLIP_EDL");
459         else
460         if(is_vwindow)
461                 file->tag.set_title("VWINDOW_EDL");
462         else
463                 file->tag.set_title("EDL");
465         file->append_tag();
466         file->append_newline();
468 // Set clipboard samples only if copying to clipboard
469         if(!all)
470         {
471                 file->tag.set_title("CLIPBOARD");
472                 file->tag.set_property("LENGTH", end - start);
473                 file->append_tag();
474                 file->append_newline();
475                 file->append_newline();
476         }
477 //printf("EDL::copy 1\n");
479 // Sessions
480         local_session->save_xml(file, start);
482 //printf("EDL::copy 1\n");
484 // Top level stuff.
485 //      if(!parent_edl)
486         {
487 // Need to copy all this from child EDL if pasting is desired.
488 // Session
489                 session->save_xml(file);
490                 session->save_video_config(file);
491                 session->save_audio_config(file);
493 // Folders
494                 for(int i = 0; i < folders.total; i++)
495                 {
496                         file->tag.set_title("FOLDER");
497                         file->append_tag();
498                         file->append_text(folders.values[i]);
499                         file->tag.set_title("/FOLDER");
500                         file->append_tag();
501                         file->append_newline();
502                 }
504 // Media
505                 copy_assets(start, 
506                         end, 
507                         file, 
508                         all, 
509                         plugindb,
510                         output_path);
512 // Clips
513 // Don't want this if using clipboard
514                 if(all)
515                 {
516                         if(vwindow_edl)
517                         {
518                                 
519                                 vwindow_edl->save_xml(plugindb, 
520                                         file, 
521                                         output_path,
522                                         0,
523                                         1);
524                         }
526                         for(int i = 0; i < clips.total; i++)
527                                 clips.values[i]->save_xml(plugindb, 
528                                         file, 
529                                         output_path,
530                                         1,
531                                         0);
532                 }
534                 file->append_newline();
535                 file->append_newline();
536         }
539 //printf("EDL::copy 1\n");
541         labels->copy(start, end, file);
542 //printf("EDL::copy 1\n");
543         presentations->copy(start, end, file);
544 //printf("EDL::copy 1\n");
545         tracks->copy(start, end, all, file, output_path);
546 //printf("EDL::copy 2\n");
548 // terminate file
549         if(is_clip)
550                 file->tag.set_title("/CLIP_EDL");
551         else
552         if(is_vwindow)
553                 file->tag.set_title("/VWINDOW_EDL");
554         else
555                 file->tag.set_title("/EDL");
556         file->append_tag();
557         file->append_newline();
560 // For editing operations we want to rewind it for immediate pasting.
561 // For clips and saving to disk leave it alone.
562         if(rewind_it)
563         {
564                 file->terminate_string();
565                 file->rewind();
566         }
567         return 0;
570 void EDL::rechannel()
572         for(Track *current = tracks->first; current; current = NEXT)
573         {
574                 if(current->data_type == TRACK_AUDIO)
575                 {
576                         PanAutos *autos = current->automation->pan_autos;
577                         ((PanAuto*)autos->default_auto)->rechannel();
578                         for(PanAuto *keyframe = (PanAuto*)autos->first;
579                                 keyframe;
580                                 keyframe = (PanAuto*)keyframe->next)
581                         {
582                                 keyframe->rechannel();
583                         }
584                 }
585         }
588 void EDL::resample(double old_rate, double new_rate, int data_type)
590         for(Track *current = tracks->first; current; current = NEXT)
591         {
592                 if(current->data_type == data_type)
593                 {
594                         current->resample(old_rate, new_rate);
595                 }
596         }
600 void EDL::synchronize_params(EDL *edl)
602         local_session->synchronize_params(edl->local_session);
603         for(Track *this_track = tracks->first, *that_track = edl->tracks->first; 
604                 this_track && that_track; 
605                 this_track = this_track->next,
606                 that_track = that_track->next)
607         {
608                 this_track->synchronize_params(that_track);
609         }
612 int EDL::trim_selection(double start, 
613         double end,
614         int edit_labels,
615         int edit_plugins)
617         if(start != end)
618         {
619 // clear the data
620                 clear(0, 
621                         start,
622                         edit_labels,
623                         edit_plugins);
624                 clear(end - start, 
625                         tracks->total_length(),
626                         edit_labels,
627                         edit_plugins);
628         }
629         return 0;
633 int EDL::equivalent(double position1, double position2)
635         double half_frame = (double).5 / session->frame_rate;
636         if((session->cursor_on_frames && 
637                 fabs(position2 - position1) < half_frame) ||
638                 (fabs(position2 - position1) < half_frame))
639         return 1;
640     else
641         return 0;
644 double EDL::equivalent_output(EDL *edl)
646         double result = -1;
647 //printf("EDL::equivalent_output 1 %f\n", result);
648         session->equivalent_output(edl->session, &result);
649 //printf("EDL::equivalent_output 2 %f\n", result);
650         tracks->equivalent_output(edl->tracks, &result);
651 //printf("EDL::equivalent_output 3 %f\n", result);
652         return result;
656 void EDL::set_inpoint(double position)
658         if(equivalent(local_session->in_point, position) && local_session->in_point >= 0)
659         {
660                 local_session->in_point = -1;
661         }
662         else
663         {
664                 local_session->in_point = align_to_frame(position, 0);
665                 if(local_session->out_point <= local_session->in_point) local_session->out_point = -1;
666         }
669 void EDL::set_outpoint(double position)
671         if(equivalent(local_session->out_point, position) && local_session->out_point >= 0)
672         {
673                 local_session->out_point = -1;
674         }
675         else
676         {
677                 local_session->out_point = align_to_frame(position, 0);
678                 if(local_session->in_point >= local_session->out_point) local_session->in_point = -1;
679         }
683 int EDL::clear(double start, 
684         double end, 
685         int clear_labels,
686         int clear_plugins)
688         if(start == end)
689         {
690                 double distance = 0;
691                 tracks->clear_handle(start, 
692                         end,
693                         distance, 
694                         clear_labels,
695                         clear_plugins);
696                 if(clear_labels && distance > 0)
697                         labels->paste_silence(start, 
698                                 start + distance);
699         }
700         else
701         {
702                 tracks->clear(start, 
703                         end,
704                         clear_plugins);
705                 if(clear_labels) 
706                         labels->clear(start, 
707                                 end, 
708                                 1);
709                 presentations->clear(start, end);
710         }
712 // Need to put at beginning so a subsequent paste operation starts at the
713 // right position.
714         local_session->selectionend = 
715                 local_session->selectionstart = 
716                 local_session->get_selectionstart();
717         return 0;
720 void EDL::modify_edithandles(double oldposition, 
721         double newposition, 
722         int currentend, 
723         int handle_mode,
724         int edit_labels,
725         int edit_plugins)
727         tracks->modify_edithandles(oldposition, 
728                 newposition, 
729                 currentend, 
730                 handle_mode,
731                 edit_labels, 
732                 edit_plugins);
733         labels->modify_handles(oldposition, 
734                 newposition, 
735                 currentend,
736                 handle_mode,
737                 edit_labels);
740 void EDL::modify_pluginhandles(double oldposition, 
741         double newposition, 
742         int currentend, 
743         int handle_mode,
744         int edit_labels)
746         tracks->modify_pluginhandles(oldposition, 
747                 newposition, 
748                 currentend, 
749                 handle_mode,
750                 edit_labels);
751         optimize();
754 void EDL::paste_silence(double start, 
755         double end, 
756         int edit_labels, 
757         int edit_plugins)
759         if(edit_labels) 
760                 labels->paste_silence(start, end);
761         tracks->paste_silence(start, 
762                 end, 
763                 edit_plugins);
767 void EDL::remove_from_project(ArrayList<EDL*> *clips)
769         for(int i = 0; i < clips->total; i++)
770         {
771                 for(int j = 0; j < this->clips.total; j++)
772                 {
773                         if(this->clips.values[j] == clips->values[i])
774                         {
775                                 this->clips.remove_object(clips->values[i]);
776                         }
777                 }
778         }
781 void EDL::remove_from_project(ArrayList<Asset*> *assets)
783 // Remove from clips
784         if(!parent_edl)
785                 for(int j = 0; j < clips.total; j++)
786                 {
787                         clips.values[j]->remove_from_project(assets);
788                 }
790 // Remove from VWindow
791         if(vwindow_edl)
792                 vwindow_edl->remove_from_project(assets);
794         for(int i = 0; i < assets->total; i++)
795         {
796 // Remove from tracks
797                 for(Track *track = tracks->first; track; track = track->next)
798                 {
799                         track->remove_asset(assets->values[i]);
800                 }
802 // Remove from assets
803                 if(!parent_edl)
804                 {
805                         this->assets->remove_asset(assets->values[i]);
806                 }
807         }
810 void EDL::update_assets(EDL *src)
812         for(Asset *current = src->assets->first;
813                 current;
814                 current = NEXT)
815         {
816                 assets->update(current);
817         }
820 int EDL::get_tracks_height(Theme *theme)
822         int total_pixels = 0;
823         for(Track *current = tracks->first;
824                 current;
825                 current = NEXT)
826         {
827                 total_pixels += current->vertical_span(theme);
828         }
829         return total_pixels;
832 int64_t EDL::get_tracks_width()
834         int64_t total_pixels = 0;
835         for(Track *current = tracks->first;
836                 current;
837                 current = NEXT)
838         {
839                 int64_t pixels = current->horizontal_span();
840                 if(pixels > total_pixels) total_pixels = pixels;
841         }
842 //printf("EDL::get_tracks_width %d\n", total_pixels);
843         return total_pixels;
846 int EDL::calculate_output_w(int single_channel)
848         if(single_channel) return session->output_w;
850         int widest = 0;
851         for(int i = 0; i < session->video_channels; i++)
852         {
853                 if(session->vchannel_x[i] + session->output_w > widest) widest = session->vchannel_x[i] + session->output_w;
854         }
855         return widest;
858 int EDL::calculate_output_h(int single_channel)
860         if(single_channel) return session->output_h;
862         int tallest = 0;
863         for(int i = 0; i < session->video_channels; i++)
864         {
865                 if(session->vchannel_y[i] + session->output_h > tallest) tallest = session->vchannel_y[i] + session->output_h;
866         }
867         return tallest;
870 // Get the total output size scaled to aspect ratio
871 void EDL::calculate_conformed_dimensions(int single_channel, float &w, float &h)
873         w = calculate_output_w(single_channel);
874         h = calculate_output_h(single_channel);
876         if((float)session->output_w / session->output_h > get_aspect_ratio())
877         {
878                 h = (float)h * 
879                         (session->output_w / get_aspect_ratio() / session->output_h);
880         }
881         else
882         {
883                 w = (float)w * 
884                         (h * get_aspect_ratio() / session->output_w);
885         }
888 float EDL::get_aspect_ratio()
890         return session->aspect_w / session->aspect_h;
893 int EDL::dump()
895         if(parent_edl)
896                 printf("CLIP\n");
897         else
898                 printf("EDL\n");
899         printf("clip_title: %s parent_edl: %p\n", local_session->clip_title, parent_edl);
900         printf("selectionstart %f selectionend %f loop_start %f loop_end %f\n", 
901                 local_session->selectionstart, 
902                 local_session->selectionend,
903                 local_session->loop_start,
904                 local_session->loop_end);
906         if(!parent_edl)
907         {
908                 printf("audio_channels: %d "
909                         "audio_tracks: %d \n"
910                         "sample_rate: %d\n",
911                         session->audio_channels,
912                         session->audio_tracks,
913                         session->sample_rate);
914                 printf("video_channels: %d "
915                         "video_tracks: %d "
916                         "frame_rate: %.2f "
917                         "frames_per_foot: %.2f\n"
918                 "output_w: %d "
919                 "output_h: %d "
920                 "aspect_w: %f "
921                 "aspect_h %f "
922                         "color_model %d\n",
923                                 session->video_channels,
924                                 session->video_tracks,
925                                 session->frame_rate,
926                                 session->frames_per_foot,
927                         session->output_w,
928                         session->output_h,
929                         session->aspect_w,
930                         session->aspect_h,
931                                 session->color_model);
933                 printf(" EDLS\n");
934                 printf("  total: %d\n", clips.total);
935         
936                 for(int i = 0; i < clips.total; i++)
937                 {
938                         printf("\n\n");
939                         clips.values[i]->dump();
940                         printf("\n\n");
941                 }
943                 printf(" ASSETS\n");
944                 assets->dump();
945         }
946         printf(" LABELS\n");
947         labels->dump();
948         printf(" TRACKS\n");
949         tracks->dump();
950 //printf("EDL::dump 2\n");
951         return 0;
954 EDL* EDL::add_clip(EDL *edl)
956 // Copy argument.  New edls are deleted from MWindow::load_filenames.
957         EDL *new_edl = new EDL(this);
958         new_edl->create_objects();
959         new_edl->copy_all(edl);
960         clips.append(new_edl);
961         return new_edl;
964 void EDL::insert_asset(Asset *asset, 
965         double position, 
966         Track *first_track, 
967         RecordLabels *labels)
969 // Insert asset into asset table
970         Asset *new_asset = assets->update(asset);
972 // Paste video
973         int vtrack = 0;
974         Track *current = first_track ? first_track : tracks->first;
976 //printf("EDL::insert_asset 1\n");
978 // Fix length of single frame
979         double length;
980         
981         
982         if(new_asset->video_length < 0) 
983                 length = 1.0 / session->frame_rate; 
984         else
985         if(new_asset->frame_rate > 0)
986                 length = ((double)new_asset->video_length / new_asset->frame_rate);
987         else
988                 length = 1.0 / session->frame_rate;
990 //printf("EDL::insert_asset 2 %f\n", length);
991         for( ;
992                 current && vtrack < new_asset->layers;
993                 current = NEXT)
994         {
995                 if(!current->record || 
996                         current->data_type != TRACK_VIDEO)
997                         continue;
999 //printf("EDL::insert_asset 3\n");
1000                 current->insert_asset(new_asset, 
1001                         length, 
1002                         position, 
1003                         vtrack);
1005 //printf("EDL::insert_asset 4\n");
1006                 vtrack++;
1007         }
1009         int atrack = 0;
1010         for(current = tracks->first;
1011                 current && atrack < new_asset->channels;
1012                 current = NEXT)
1013         {
1014                 if(!current->record ||
1015                         current->data_type != TRACK_AUDIO)
1016                         continue;
1018 //printf("EDL::insert_asset 5\n");
1019                 current->insert_asset(new_asset, 
1020                         (double)new_asset->audio_length / 
1021                                 new_asset->sample_rate, 
1022                         position, 
1023                         atrack);
1025 //printf("EDL::insert_asset 6\n");
1027                 atrack++;
1028         }
1030         if(labels)
1031         {
1032                 for(RecordLabel *label = labels->first; label; label = label->next)
1033                 {
1034 //printf("EDL::insert_asset 1 %f\n", label->position);
1035                         this->labels->toggle_label(label->position, label->position);
1036                 }
1037         }
1039 //      optimize();
1044 void EDL::set_index_file(Asset *asset)
1046         assets->update_index(asset);
1049 void EDL::optimize()
1051 //printf("EDL::optimize 1\n");
1052         double length = tracks->total_length();
1053         if(local_session->preview_end > length) local_session->preview_end = length;
1054         if(local_session->preview_start > length ||
1055                 local_session->preview_start < 0) local_session->preview_start = 0;
1056         for(Track *current = tracks->first; current; current = NEXT)
1057                 current->optimize();
1060 int EDL::next_id()
1062         return EDLSession::current_id++;
1065 void EDL::get_shared_plugins(Track *source, 
1066         ArrayList<SharedLocation*> *plugin_locations)
1068         for(Track *track = tracks->first; track; track = track->next)
1069         {
1070                 if(track != source && 
1071                         track->data_type == source->data_type)
1072                 {
1073                         for(int i = 0; i < track->plugin_set.total; i++)
1074                         {
1075                                 Plugin *plugin = track->get_current_plugin(local_session->selectionstart, 
1076                                         i, 
1077                                         PLAY_FORWARD, 
1078                                         1,
1079                                         0);
1080                                 if(plugin && plugin->plugin_type == PLUGIN_STANDALONE)
1081                                 {
1082                                         plugin_locations->append(new SharedLocation(tracks->number_of(track), i));
1083                                 }
1084                         }
1085                 }
1086         }
1089 void EDL::get_shared_tracks(Track *track, ArrayList<SharedLocation*> *module_locations)
1091         for(Track *current = tracks->first; current; current = NEXT)
1092         {
1093                 if(current != track && 
1094                         current->data_type == track->data_type)
1095                 {
1096                         module_locations->append(new SharedLocation(tracks->number_of(current), 0));
1097                 }
1098         }
1101 // Convert position to frames if cursor alignment is enabled
1102 double EDL::align_to_frame(double position, int round)
1104 //printf("EDL::align_to_frame 1 %f\n", position);
1105         if(session->cursor_on_frames)
1106         {
1107 // Seconds -> Frames
1108                 double temp = (double)position * session->frame_rate;
1109 //printf("EDL::align_to_frame 2 %f\n", temp);
1111 // Assert some things
1112                 if(session->sample_rate == 0)
1113                         printf("EDL::align_to_frame: sample_rate == 0\n");
1115                 if(session->frame_rate == 0)
1116                         printf("EDL::align_to_frame: frame_rate == 0\n");
1118 // Round frames
1119 // Always round down negative numbers
1120 // but round up only if requested
1121                 if(round) 
1122                 {
1123                         temp = Units::round(temp);
1124                 }
1125                 else
1126                 {
1127 //                      if(temp < 0)
1128 //                      {
1129 //                              temp -= 0.5;
1130 //                      }
1131 //                      else
1132                                 temp = Units::to_int64(temp);
1133                 }
1134 //printf("EDL::align_to_frame 3 %f\n", temp);
1136 // Frames -> Seconds
1137                 temp /= session->frame_rate;
1139 //printf("EDL::align_to_frame 5 %f\n", temp);
1141                 return temp;
1142         }
1143 //printf("EDL::align_to_frame 3 %d\n", position);
1146         return position;
1150 void EDL::new_folder(char *folder)
1152         for(int i = 0; i < folders.total; i++)
1153         {
1154                 if(!strcasecmp(folders.values[i], folder)) return;
1155         }
1157         char *new_folder;
1158         folders.append(new_folder = new char[strlen(folder) + 1]);
1159         strcpy(new_folder, folder);
1162 void EDL::delete_folder(char *folder)
1164         int i;
1165         for(i = 0; i < folders.total; i++)
1166         {
1167                 if(!strcasecmp(folders.values[i], folder))
1168                 {
1169                         break;
1170                 }
1171         }
1173         if(i < folders.total) delete folders.values[i];
1175         for( ; i < folders.total - 1; i++)
1176         {
1177                 folders.values[i] = folders.values[i + 1];
1178         }