00001 #include "assets.h"
00002 #include "atrack.h"
00003 #include "automation.h"
00004 #include "aedits.h"
00005 #include "edit.h"
00006 #include "edits.h"
00007 #include "edl.h"
00008 #include "edlsession.h"
00009 #include "filexml.h"
00010 #include "intauto.h"
00011 #include "intautos.h"
00012 #include "localsession.h"
00013 #include "mainundo.h"
00014 #include "module.h"
00015 #include "mainsession.h"
00016 #include "pluginserver.h"
00017 #include "pluginset.h"
00018 #include "timebar.h"
00019 #include "trackcanvas.h"
00020 #include "tracks.h"
00021 #include "trackscroll.h"
00022 #include "transition.h"
00023 #include "transportque.h"
00024 #include "vtrack.h"
00025 #include <string.h>
00026
00027 int Tracks::clear(double start, double end, int clear_plugins)
00028 {
00029 Track *current_track;
00030
00031 for(current_track = first;
00032 current_track;
00033 current_track = current_track->next)
00034 {
00035 if(current_track->record)
00036 {
00037 current_track->clear(start,
00038 end,
00039 1,
00040 1,
00041 clear_plugins,
00042 1,
00043 0);
00044 }
00045 }
00046 return 0;
00047 }
00048
00049 void Tracks::clear_automation(double selectionstart, double selectionend)
00050 {
00051 Track* current_track;
00052
00053 for(current_track = first; current_track; current_track = current_track->next)
00054 {
00055 if(current_track->record)
00056 {
00057 current_track->clear_automation(selectionstart,
00058 selectionend,
00059 0,
00060 0);
00061 }
00062 }
00063 }
00064
00065 void Tracks::straighten_automation(double selectionstart, double selectionend)
00066 {
00067 Track* current_track;
00068
00069 for(current_track = first; current_track; current_track = current_track->next)
00070 {
00071 if(current_track->record)
00072 {
00073 current_track->straighten_automation(selectionstart,
00074 selectionend);
00075 }
00076 }
00077 }
00078
00079 int Tracks::clear_default_keyframe()
00080 {
00081 for(Track *current = first; current; current = NEXT)
00082 {
00083 if(current->record)
00084 current->clear_automation(0, 0, 0, 1);
00085 }
00086 return 0;
00087 }
00088
00089 int Tracks::clear_handle(double start,
00090 double end,
00091 double &longest_distance,
00092 int clear_labels,
00093 int clear_plugins)
00094 {
00095 Track* current_track;
00096 double distance;
00097
00098 for(current_track = first; current_track; current_track = current_track->next)
00099 {
00100 if(current_track->record)
00101 {
00102 current_track->clear_handle(start,
00103 end,
00104 clear_labels,
00105 clear_plugins,
00106 distance);
00107 if(distance > longest_distance) longest_distance = distance;
00108 }
00109 }
00110
00111 return 0;
00112 }
00113
00114 int Tracks::copy_automation(double selectionstart,
00115 double selectionend,
00116 FileXML *file,
00117 int default_only,
00118 int autos_only)
00119 {
00120
00121 Track* current_track;
00122
00123 file->tag.set_title("AUTO_CLIPBOARD");
00124 file->tag.set_property("LENGTH", selectionend - selectionstart);
00125 file->tag.set_property("FRAMERATE", edl->session->frame_rate);
00126 file->tag.set_property("SAMPLERATE", edl->session->sample_rate);
00127 file->append_tag();
00128 file->append_newline();
00129 file->append_newline();
00130
00131 for(current_track = first;
00132 current_track;
00133 current_track = current_track->next)
00134 {
00135 if(current_track->record)
00136 {
00137 current_track->copy_automation(selectionstart,
00138 selectionend,
00139 file,
00140 default_only,
00141 autos_only);
00142 }
00143 }
00144
00145 file->tag.set_title("/AUTO_CLIPBOARD");
00146 file->append_tag();
00147 file->append_newline();
00148 file->terminate_string();
00149 return 0;
00150 }
00151
00152 int Tracks::copy_default_keyframe(FileXML *file)
00153 {
00154 copy_automation(0, 0, file, 1, 0);
00155 return 0;
00156 }
00157
00158 int Tracks::delete_tracks()
00159 {
00160 int total_deleted = 0;
00161 int done = 0;
00162
00163 while(!done)
00164 {
00165 done = 1;
00166 for (Track* current = first;
00167 current && done;
00168 current = NEXT)
00169 {
00170 if(current->record)
00171 {
00172 delete_track(current);
00173 total_deleted++;
00174 done = 0;
00175 }
00176 }
00177 }
00178 return total_deleted;
00179 }
00180
00181 void Tracks::move_edits(ArrayList<Edit*> *edits,
00182 Track *track,
00183 double position,
00184 int edit_labels,
00185 int edit_plugins,
00186 int behaviour)
00187 {
00188
00189 for(Track *dest_track = track; dest_track; dest_track = dest_track->next)
00190 {
00191 if(dest_track->record)
00192 {
00193
00194
00195 Edit *source_edit = 0;
00196 Track *source_track = 0;
00197
00198
00199
00200 if(dest_track->data_type == TRACK_AUDIO)
00201 {
00202 int current_aedit = 0;
00203
00204 while(current_aedit < edits->total &&
00205 edits->values[current_aedit]->track->data_type != TRACK_AUDIO)
00206 current_aedit++;
00207
00208 if(current_aedit < edits->total)
00209 {
00210 source_edit = edits->values[current_aedit];
00211 source_track = source_edit->track;
00212 edits->remove_number(current_aedit);
00213 }
00214 }
00215 else
00216 if(dest_track->data_type == TRACK_VIDEO)
00217 {
00218 int current_vedit = 0;
00219 while(current_vedit < edits->total &&
00220 edits->values[current_vedit]->track->data_type != TRACK_VIDEO)
00221 current_vedit++;
00222
00223 if(current_vedit < edits->total)
00224 {
00225 source_edit = edits->values[current_vedit];
00226 source_track = source_edit->track;
00227 edits->remove_number(current_vedit);
00228 }
00229 }
00230
00231
00232 if(source_edit)
00233 {
00234 int64_t position_i = source_track->to_units(position, 0);
00235
00236 int64_t source_length = source_edit->length;
00237 int64_t source_startproject = source_edit->startproject;
00238
00239 if (behaviour == 0)
00240 {
00241
00242
00243
00244 FileXML temp;
00245 AutoConf temp_autoconf;
00246
00247 temp_autoconf.set_all(1);
00248
00249 source_track->automation->copy(source_edit->startproject,
00250 source_edit->startproject + source_edit->length,
00251 &temp,
00252 0,
00253 0);
00254 temp.terminate_string();
00255 temp.rewind();
00256
00257
00258 source_track->automation->clear(source_edit->startproject,
00259 source_edit->startproject + source_edit->length,
00260 &temp_autoconf,
00261 1);
00262 int64_t position_a = position_i;
00263 if (dest_track == source_track)
00264 {
00265 if (position_a > source_edit->startproject)
00266 position_a -= source_length;
00267 }
00268
00269 dest_track->automation->paste_silence(position_a,
00270 position_a + source_length);
00271 while(!temp.read_tag())
00272 dest_track->automation->paste(position_a,
00273 source_length,
00274 1.0,
00275 &temp,
00276 0,
00277 &temp_autoconf);
00278
00279
00280 Edit *dest_edit = dest_track->edits->shift(position_i,
00281 source_length);
00282 Edit *result = dest_track->edits->insert_before(dest_edit,
00283 dest_track->edits->create_edit());
00284 result->copy_from(source_edit);
00285 result->startproject = position_i;
00286 result->length = source_length;
00287
00288
00289 source_track->edits->clear(source_edit->startproject,
00290 source_edit->startproject + source_length);
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314 } else
00315 if (behaviour == 1)
00316
00317 {
00318
00319 Edit *temp_edit = dest_track->edits->create_edit();
00320 temp_edit->copy_from(source_edit);
00321
00322 source_track->edits->clear(source_startproject,
00323 source_startproject + source_length);
00324 source_track->edits->paste_silence(source_startproject,
00325 source_startproject + source_length);
00326
00327 dest_track->edits->clear(position_i,
00328 position_i + source_length);
00329 Edit *dest_edit = dest_track->edits->shift(position_i, source_length);
00330 Edit *result = dest_track->edits->insert_before(dest_edit,
00331 dest_track->edits->create_edit());
00332 result->copy_from(temp_edit);
00333 result->startproject = position_i;
00334 result->length = source_length;
00335 delete temp_edit;
00336 }
00337 source_track->optimize();
00338 dest_track->optimize();
00339 }
00340 }
00341 }
00342 }
00343
00344 void Tracks::move_effect(Plugin *plugin,
00345 PluginSet *dest_plugin_set,
00346 Track *dest_track,
00347 int64_t dest_position)
00348 {
00349 Track *source_track = plugin->track;
00350 Plugin *result = 0;
00351
00352
00353 if(!dest_track && dest_plugin_set)
00354 {
00355 Track *dest_track = dest_plugin_set->track;
00356
00357
00358
00359
00360 dest_plugin_set->shift(dest_position, plugin->length);
00361
00362
00363 Plugin *current = 0;
00364 for(current = (Plugin*)dest_plugin_set->first; current; current = (Plugin*)NEXT)
00365 if(current->startproject >= dest_position) break;
00366
00367 result = (Plugin*)dest_plugin_set->insert_before(current,
00368 new Plugin(edl, dest_plugin_set, ""));
00369 }
00370 else
00371
00372 {
00373 double start = dest_track->from_units(dest_position);
00374 double length = dest_track->from_units(plugin->length);
00375
00376 result = dest_track->insert_effect("",
00377 &plugin->shared_location,
00378 0,
00379 0,
00380 start,
00381 length,
00382 plugin->plugin_type);
00383
00384 }
00385
00386
00387 result->copy_from(plugin);
00388 result->shift(dest_position - plugin->startproject);
00389
00390
00391 plugin->plugin_set->clear(plugin->startproject, plugin->startproject + plugin->length);
00392
00393
00394 source_track->optimize();
00395 }
00396
00397
00398
00399 int Tracks::concatenate_tracks(int edit_plugins)
00400 {
00401 Track *output_track, *first_output_track, *input_track;
00402 int i, data_type = TRACK_AUDIO;
00403 double output_start;
00404 FileXML *clipboard;
00405 int result = 0;
00406 IntAuto *play_keyframe = 0;
00407
00408
00409 for(i = 0; i < 2; i++)
00410 {
00411
00412 for(output_track = first;
00413 output_track;
00414 output_track = output_track->next)
00415 if(output_track->data_type == data_type &&
00416 output_track->record) break;
00417
00418 first_output_track = output_track;
00419
00420
00421 for(input_track = first;
00422 input_track;
00423 input_track = input_track->next)
00424 {
00425 if(input_track->data_type == data_type &&
00426 input_track->play &&
00427 !input_track->record) break;
00428 }
00429
00430
00431 if(output_track && input_track)
00432 {
00433
00434 while(input_track)
00435 {
00436 output_start = output_track->get_length();
00437 output_track->insert_track(input_track,
00438 output_start,
00439 0,
00440 edit_plugins);
00441
00442
00443 for(input_track = input_track->next;
00444 input_track;
00445 input_track = input_track->next)
00446 {
00447
00448 if(input_track->data_type == data_type &&
00449 !input_track->record &&
00450 input_track->play) break;
00451 }
00452
00453 for(output_track = output_track->next;
00454 output_track;
00455 output_track = output_track->next)
00456 {
00457 if(output_track->data_type == data_type &&
00458 output_track->record) break;
00459 }
00460
00461 if(!output_track)
00462 {
00463 output_track = first_output_track;
00464 }
00465 }
00466 result = 1;
00467 }
00468
00469 if(data_type == TRACK_AUDIO) data_type = TRACK_VIDEO;
00470 }
00471
00472 return result;
00473 }
00474
00475 int Tracks::delete_all_tracks()
00476 {
00477 while(last) delete last;
00478 return 0;
00479 }
00480
00481
00482 void Tracks::change_modules(int old_location, int new_location, int do_swap)
00483 {
00484 for(Track* current = first ; current; current = current->next)
00485 {
00486 current->change_modules(old_location, new_location, do_swap);
00487 }
00488 }
00489
00490 void Tracks::change_plugins(SharedLocation &old_location, SharedLocation &new_location, int do_swap)
00491 {
00492 for(Track* current = first ; current; current = current->next)
00493 {
00494 current->change_plugins(old_location, new_location, do_swap);
00495 }
00496 }
00497
00498
00499
00500
00501
00502
00503 int Tracks::copy(double start,
00504 double end,
00505 int all,
00506 FileXML *file,
00507 char *output_path)
00508 {
00509
00510 if(start == end && !all) return 1;
00511
00512 Track* current;
00513
00514 for(current = first;
00515 current;
00516 current = NEXT)
00517 {
00518 if(current->record || all)
00519 {
00520 current->copy(start, end, file,output_path);
00521 }
00522 }
00523
00524 return 0;
00525 }
00526
00527
00528
00529 int Tracks::move_track_up(Track *track)
00530 {
00531 Track *next_track = track->previous;
00532 if(!next_track) next_track = last;
00533
00534 change_modules(number_of(track), number_of(next_track), 1);
00535
00536
00537
00538
00539
00540
00541
00542 swap(track, next_track);
00543
00544
00545
00546
00547
00548
00549 return 0;
00550 }
00551
00552 int Tracks::move_track_down(Track *track)
00553 {
00554 Track *next_track = track->next;
00555 if(!next_track) next_track = first;
00556
00557 change_modules(number_of(track), number_of(next_track), 1);
00558 swap(track, next_track);
00559 return 0;
00560 }
00561
00562
00563 int Tracks::move_tracks_up()
00564 {
00565 Track *track, *next_track;
00566 int result = 0;
00567
00568 for(track = first;
00569 track;
00570 track = next_track)
00571 {
00572 next_track = track->next;
00573
00574 if(track->record)
00575 {
00576 if(track->previous)
00577 {
00578 change_modules(number_of(track->previous), number_of(track), 1);
00579
00580 swap(track->previous, track);
00581 result = 1;
00582 }
00583 }
00584 }
00585
00586 return result;
00587 }
00588
00589 int Tracks::move_tracks_down()
00590 {
00591 Track *track, *previous_track;
00592 int result = 0;
00593
00594 for(track = last;
00595 track;
00596 track = previous_track)
00597 {
00598 previous_track = track->previous;
00599
00600 if(track->record)
00601 {
00602 if(track->next)
00603 {
00604 change_modules(number_of(track), number_of(track->next), 1);
00605
00606 swap(track, track->next);
00607 result = 1;
00608 }
00609 }
00610 }
00611
00612 return result;
00613 }
00614
00615
00616
00617 void Tracks::paste_audio_transition(PluginServer *server)
00618 {
00619 for(Track *current = first; current; current = NEXT)
00620 {
00621 if(current->data_type == TRACK_AUDIO &&
00622 current->record)
00623 {
00624 int64_t position = current->to_units(
00625 edl->local_session->get_selectionstart(), 0);
00626 Edit *current_edit = current->edits->editof(position,
00627 PLAY_FORWARD,
00628 0);
00629 if(current_edit)
00630 {
00631 paste_transition(server, current_edit);
00632 }
00633 }
00634 }
00635 }
00636
00637 void Tracks::loaded_lengths_to_tracklengths(int includerecordtracks)
00638 {
00639 Track *current_track;
00640
00641 for(current_track = first;
00642 current_track;
00643 current_track = current_track->next)
00644 {
00645 if(current_track->record || includerecordtracks)
00646 {
00647
00648 current_track->edits->loaded_length = current_track->edits->last->startproject;
00649 }
00650 }
00651 }
00652
00653 void Tracks::paste_automation(double selectionstart,
00654 FileXML *file,
00655 int default_only)
00656 {
00657 Track* current_atrack = 0;
00658 Track* current_vtrack = 0;
00659 int result = 0;
00660 double length;
00661 double frame_rate = edl->session->frame_rate;
00662 int64_t sample_rate = edl->session->sample_rate;
00663 char string[BCTEXTLEN];
00664 sprintf(string, "");
00665
00666
00667 do{
00668 result = file->read_tag();
00669 }while(!result &&
00670 !file->tag.title_is("AUTO_CLIPBOARD"));
00671
00672 if(!result)
00673 {
00674 length = file->tag.get_property("LENGTH", 0);
00675 frame_rate = file->tag.get_property("FRAMERATE", frame_rate);
00676 sample_rate = file->tag.get_property("SAMPLERATE", sample_rate);
00677
00678
00679 do
00680 {
00681 result = file->read_tag();
00682
00683 if(!result)
00684 {
00685 if(file->tag.title_is("/AUTO_CLIPBOARD"))
00686 {
00687 result = 1;
00688 }
00689 else
00690 if(file->tag.title_is("TRACK"))
00691 {
00692 file->tag.get_property("TYPE", string);
00693
00694 if(!strcmp(string, "AUDIO"))
00695 {
00696
00697 if(!current_atrack)
00698 current_atrack = first;
00699 else
00700 current_atrack = current_atrack->next;
00701
00702 while(current_atrack &&
00703 (current_atrack->data_type != TRACK_AUDIO ||
00704 !current_atrack->record))
00705 current_atrack = current_atrack->next;
00706
00707
00708 if(current_atrack)
00709 {
00710 current_atrack->paste_automation(selectionstart,
00711 length,
00712 frame_rate,
00713 sample_rate,
00714 file,
00715 default_only);
00716 }
00717 }
00718 else
00719 {
00720
00721 if(!current_vtrack)
00722 current_vtrack = first;
00723 else
00724 current_vtrack = current_vtrack->next;
00725
00726 while(current_vtrack &&
00727 (current_vtrack->data_type != TRACK_VIDEO ||
00728 !current_vtrack->record))
00729 current_vtrack = current_vtrack->next;
00730
00731
00732 if(current_vtrack)
00733 {
00734
00735 current_vtrack->paste_automation(selectionstart,
00736 length,
00737 frame_rate,
00738 sample_rate,
00739 file,
00740 default_only);
00741 }
00742 }
00743 }
00744 }
00745 }while(!result);
00746 }
00747 }
00748
00749 int Tracks::paste_default_keyframe(FileXML *file)
00750 {
00751 paste_automation(0, file, 1);
00752 return 0;
00753 }
00754
00755 void Tracks::paste_transition(PluginServer *server, Edit *dest_edit)
00756 {
00757 dest_edit->insert_transition(server->title);
00758 }
00759
00760 void Tracks::paste_video_transition(PluginServer *server, int first_track)
00761 {
00762 for(Track *current = first; current; current = NEXT)
00763 {
00764 if(current->data_type == TRACK_VIDEO &&
00765 current->record)
00766 {
00767 int64_t position = current->to_units(
00768 edl->local_session->get_selectionstart(), 0);
00769 Edit *current_edit = current->edits->editof(position,
00770 PLAY_FORWARD,
00771 0);
00772 if(current_edit)
00773 {
00774 paste_transition(server, current_edit);
00775 }
00776 if(first_track) break;
00777 }
00778 }
00779 }
00780
00781
00782 int Tracks::paste_silence(double start, double end, int edit_plugins)
00783 {
00784 Track* current_track;
00785
00786 for(current_track = first;
00787 current_track;
00788 current_track = current_track->next)
00789 {
00790 if(current_track->record)
00791 {
00792 current_track->paste_silence(start, end, edit_plugins);
00793 }
00794 }
00795 return 0;
00796 }
00797
00798
00799
00800 int Tracks::select_auto(int cursor_x, int cursor_y)
00801 {
00802 int result = 0;
00803 for(Track* current = first; current && !result; current = NEXT) { result = current->select_auto(&auto_conf, cursor_x, cursor_y); }
00804 return result;
00805 }
00806
00807 int Tracks::move_auto(int cursor_x, int cursor_y, int shift_down)
00808 {
00809 int result = 0;
00810
00811 for(Track* current = first; current && !result; current = NEXT)
00812 {
00813 result = current->move_auto(&auto_conf, cursor_x, cursor_y, shift_down);
00814 }
00815 return 0;
00816 }
00817
00818 int Tracks::modify_edithandles(double &oldposition,
00819 double &newposition,
00820 int currentend,
00821 int handle_mode,
00822 int edit_labels,
00823 int edit_plugins)
00824 {
00825 Track *current;
00826
00827 for(current = first; current; current = NEXT)
00828 {
00829 if(current->record)
00830 {
00831 current->modify_edithandles(oldposition,
00832 newposition,
00833 currentend,
00834 handle_mode,
00835 edit_labels,
00836 edit_plugins);
00837 }
00838 }
00839 return 0;
00840 }
00841
00842 int Tracks::modify_pluginhandles(double &oldposition,
00843 double &newposition,
00844 int currentend,
00845 int handle_mode,
00846 int edit_labels,
00847 Edits *trim_edits)
00848 {
00849 Track *current;
00850
00851 for(current = first; current; current = NEXT)
00852 {
00853 if(current->record)
00854 {
00855 current->modify_pluginhandles(oldposition,
00856 newposition,
00857 currentend,
00858 handle_mode,
00859 edit_labels,
00860 trim_edits);
00861 }
00862 }
00863 return 0;
00864 }
00865
00866
00867
00868 int Tracks::purge_asset(Asset *asset)
00869 {
00870 Track *current_track;
00871 int result = 0;
00872
00873 for(current_track = first; current_track; current_track = current_track->next)
00874 {
00875 result += current_track->purge_asset(asset);
00876 }
00877 return result;
00878 }
00879
00880 int Tracks::asset_used(Asset *asset)
00881 {
00882 Track *current_track;
00883 int result = 0;
00884
00885 for(current_track = first; current_track; current_track = current_track->next)
00886 {
00887 result += current_track->asset_used(asset);
00888 }
00889 return result;
00890 }
00891
00892 int Tracks::scale_time(float rate_scale, int ignore_record, int scale_edits, int scale_autos, int64_t start, int64_t end)
00893 {
00894 Track *current_track;
00895
00896 for(current_track = first;
00897 current_track;
00898 current_track = current_track->next)
00899 {
00900 if((current_track->record || ignore_record) &&
00901 current_track->data_type == TRACK_VIDEO)
00902 {
00903 current_track->scale_time(rate_scale, scale_edits, scale_autos, start, end);
00904 }
00905 }
00906 return 0;
00907 }
00908