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