00001 #include "asset.h"
00002 #include "autoconf.h"
00003 #include "automation.h"
00004 #include "bcsignals.h"
00005 #include "clip.h"
00006 #include "edit.h"
00007 #include "edits.h"
00008 #include "edl.h"
00009 #include "edlsession.h"
00010 #include "filexml.h"
00011 #include "floatauto.h"
00012 #include "floatautos.h"
00013 #include "keyframe.h"
00014 #include "localsession.h"
00015 #include "module.h"
00016 #include "patch.h"
00017 #include "patchbay.h"
00018 #include "plugin.h"
00019 #include "pluginset.h"
00020 #include "mainsession.h"
00021 #include "theme.h"
00022 #include "intautos.h"
00023 #include "track.h"
00024 #include "trackcanvas.h"
00025 #include "tracks.h"
00026 #include "transition.h"
00027 #include "transportque.inc"
00028 #include "vedit.h"
00029 #include "vframe.h"
00030 #include <string.h>
00031
00032
00033 Track::Track(EDL *edl, Tracks *tracks) : ListItem<Track>()
00034 {
00035 this->edl = edl;
00036 this->tracks = tracks;
00037 y_pixel = 0;
00038 expand_view = 0;
00039 draw = 1;
00040 gang = 1;
00041 title[0] = 0;
00042 record = 1;
00043 play = 1;
00044 nudge = 0;
00045 track_w = edl->session->output_w;
00046 track_h = edl->session->output_h;
00047 id = EDL::next_id();
00048 }
00049
00050 Track::~Track()
00051 {
00052 delete automation;
00053 delete edits;
00054 plugin_set.remove_all_objects();
00055 }
00056
00057 int Track::create_objects()
00058 {
00059 return 0;
00060 }
00061
00062
00063 int Track::copy_settings(Track *track)
00064 {
00065 this->expand_view = track->expand_view;
00066 this->draw = track->draw;
00067 this->gang = track->gang;
00068 this->record = track->record;
00069 this->nudge = track->nudge;
00070 this->play = track->play;
00071 this->track_w = track->track_w;
00072 this->track_h = track->track_h;
00073 strcpy(this->title, track->title);
00074 return 0;
00075 }
00076
00077 int Track::get_id()
00078 {
00079 return id;
00080 }
00081
00082
00083 int Track::load_defaults(BC_Hash *defaults)
00084 {
00085 return 0;
00086 }
00087
00088 void Track::equivalent_output(Track *track, double *result)
00089 {
00090 if(data_type != track->data_type ||
00091 track_w != track->track_w ||
00092 track_h != track->track_h ||
00093 play != track->play ||
00094 nudge != track->nudge)
00095 *result = 0;
00096
00097
00098 int64_t result2 = -1;
00099 automation->equivalent_output(track->automation, &result2);
00100 edits->equivalent_output(track->edits, &result2);
00101
00102 int plugin_sets = MIN(plugin_set.total, track->plugin_set.total);
00103
00104 for(int i = 0; i < plugin_sets; i++)
00105 {
00106 plugin_set.values[i]->equivalent_output(
00107 track->plugin_set.values[i],
00108 &result2);
00109 }
00110
00111
00112 for(int i = plugin_sets; i < plugin_set.total; i++)
00113 {
00114 Plugin *current = plugin_set.values[i]->get_first_plugin();
00115 if(current)
00116 {
00117 if(result2 < 0 || current->startproject < result2)
00118 result2 = current->startproject;
00119 }
00120 }
00121
00122
00123 for(int i = plugin_sets; i < track->plugin_set.total; i++)
00124 {
00125 Plugin *current = track->plugin_set.values[i]->get_first_plugin();
00126 if(current)
00127 {
00128 if(result2 < 0 || current->startproject < result2)
00129 result2 = current->startproject;
00130 }
00131 }
00132
00133
00134
00135 if(track->plugin_set.total != plugin_set.total && result2 < 0)
00136 result2 = 0;
00137
00138 if(result2 >= 0 &&
00139 (*result < 0 || from_units(result2) < *result))
00140 *result = from_units(result2);
00141 }
00142
00143
00144 int Track::is_synthesis(RenderEngine *renderengine,
00145 int64_t position,
00146 int direction)
00147 {
00148 int is_synthesis = 0;
00149 for(int i = 0; i < plugin_set.total; i++)
00150 {
00151 Plugin *plugin = get_current_plugin(position,
00152 i,
00153 direction,
00154 0,
00155 0);
00156 if(plugin)
00157 {
00158
00159 if(plugin->plugin_type == PLUGIN_SHAREDMODULE)
00160 is_synthesis = 1;
00161 else
00162 is_synthesis = plugin->is_synthesis(renderengine,
00163 position,
00164 direction);
00165 if(is_synthesis) break;
00166 }
00167 }
00168 return is_synthesis;
00169 }
00170
00171 void Track::copy_from(Track *track)
00172 {
00173 copy_settings(track);
00174 edits->copy_from(track->edits);
00175 for(int i = 0; i < this->plugin_set.total; i++)
00176 delete this->plugin_set.values[i];
00177 this->plugin_set.remove_all_objects();
00178
00179 for(int i = 0; i < track->plugin_set.total; i++)
00180 {
00181 PluginSet *new_plugin_set = plugin_set.append(new PluginSet(edl, this));
00182 new_plugin_set->copy_from(track->plugin_set.values[i]);
00183 }
00184 automation->copy_from(track->automation);
00185 this->track_w = track->track_w;
00186 this->track_h = track->track_h;
00187 }
00188
00189 Track& Track::operator=(Track& track)
00190 {
00191 printf("Track::operator= 1\n");
00192 copy_from(&track);
00193 return *this;
00194 }
00195
00196 int Track::vertical_span(Theme *theme)
00197 {
00198 int result = 0;
00199 if(expand_view)
00200 result = edl->local_session->zoom_track +
00201 plugin_set.total *
00202 theme->get_image("plugin_bg_data")->get_h();
00203 else
00204 result = edl->local_session->zoom_track;
00205
00206 if(edl->session->show_titles)
00207 result += theme->get_image("title_bg_data")->get_h();
00208
00209 return result;
00210 }
00211
00212 double Track::get_length()
00213 {
00214 double total_length = 0;
00215 double length = 0;
00216
00217
00218 int64_t unit_end;
00219 unit_end = edits->last->startproject;
00220 if (edits->last->transition)
00221 unit_end += edits->last->transition->length + 1;
00222 length = from_units(unit_end);
00223 if(length > total_length) total_length = length;
00224
00225
00226 for(int i = 0; i < plugin_set.total; i++)
00227 {
00228 length = from_units(plugin_set.values[i]->last->startproject);
00229 if(length > total_length) total_length = length;
00230 }
00231
00232
00233 length = from_units(automation->get_length());
00234 if(length > total_length) total_length = length;
00235
00236
00237 return total_length;
00238 }
00239
00240
00241
00242 void Track::get_source_dimensions(double position, int &w, int &h)
00243 {
00244 int64_t native_position = to_units(position, 0);
00245 for(Edit *current = edits->first; current; current = NEXT)
00246 {
00247 if(current->startproject <= native_position &&
00248 current->startproject + current->length > native_position &&
00249 current->asset)
00250 {
00251 w = current->asset->width;
00252 h = current->asset->height;
00253 return;
00254 }
00255 }
00256 }
00257
00258
00259 int64_t Track::horizontal_span()
00260 {
00261 return (int64_t)(get_length() *
00262 edl->session->sample_rate /
00263 edl->local_session->zoom_sample +
00264 0.5);
00265 }
00266
00267
00268 int Track::load(FileXML *file, int track_offset, uint32_t load_flags)
00269 {
00270 int result = 0;
00271 int current_channel = 0;
00272 int current_plugin = 0;
00273
00274
00275 record = file->tag.get_property("RECORD", record);
00276 play = file->tag.get_property("PLAY", play);
00277 gang = file->tag.get_property("GANG", gang);
00278 draw = file->tag.get_property("DRAW", draw);
00279 nudge = file->tag.get_property("NUDGE", nudge);
00280 expand_view = file->tag.get_property("EXPAND", expand_view);
00281 track_w = file->tag.get_property("TRACK_W", track_w);
00282 track_h = file->tag.get_property("TRACK_H", track_h);
00283
00284 load_header(file, load_flags);
00285
00286 do{
00287 result = file->read_tag();
00288
00289 if(!result)
00290 {
00291 if(file->tag.title_is("/TRACK"))
00292 {
00293 result = 1;
00294 }
00295 else
00296 if(file->tag.title_is("TITLE"))
00297 {
00298 file->read_text_until("/TITLE", title, BCTEXTLEN);
00299 }
00300 else
00301 if(load_flags && automation->load(file)
00302 )
00303 {
00304 ;
00305 }
00306 else
00307 if(file->tag.title_is("EDITS"))
00308 {
00309 if(load_flags & LOAD_EDITS)
00310 edits->load(file, track_offset);
00311 }
00312 else
00313 if(file->tag.title_is("PLUGINSET"))
00314 {
00315 if(load_flags & LOAD_EDITS)
00316 {
00317 PluginSet *plugin_set = new PluginSet(edl, this);
00318 this->plugin_set.append(plugin_set);
00319 plugin_set->load(file, load_flags);
00320 }
00321 else
00322 if(load_flags & LOAD_AUTOMATION)
00323 {
00324 if(current_plugin < this->plugin_set.total)
00325 {
00326 PluginSet *plugin_set = this->plugin_set.values[current_plugin];
00327 plugin_set->load(file, load_flags);
00328 current_plugin++;
00329 }
00330 }
00331 }
00332 else
00333 load_derived(file, load_flags);
00334 }
00335 }while(!result);
00336
00337
00338
00339 return 0;
00340 }
00341
00342 void Track::insert_asset(Asset *asset,
00343 double length,
00344 double position,
00345 int track_number)
00346 {
00347
00348 edits->insert_asset(asset,
00349 to_units(length, 1),
00350 to_units(position, 0),
00351 track_number);
00352 edits->loaded_length += to_units(length, 1);
00353 }
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369 void Track::insert_track(Track *track,
00370 double position,
00371 int replace_default,
00372 int edit_plugins)
00373 {
00374
00375
00376 if(replace_default) copy_settings(track);
00377
00378 edits->insert_edits(track->edits, to_units(position, 0));
00379
00380 if(edit_plugins)
00381 insert_plugin_set(track, position);
00382
00383 automation->insert_track(track->automation,
00384 to_units(position, 0),
00385 to_units(track->get_length(), 1),
00386 replace_default);
00387
00388 optimize();
00389
00390 }
00391
00392
00393 void Track::insert_plugin_set(Track *track, double position)
00394 {
00395
00396 if(!track->plugin_set.total)
00397 {
00398 shift_effects(position,
00399 track->get_length(),
00400 1);
00401 }
00402 else
00403 for(int i = 0; i < track->plugin_set.total; i++)
00404 {
00405 if(i >= plugin_set.total)
00406 plugin_set.append(new PluginSet(edl, this));
00407
00408 plugin_set.values[i]->insert_edits(track->plugin_set.values[i],
00409 to_units(position, 0));
00410 }
00411 }
00412
00413
00414 Plugin* Track::insert_effect(char *title,
00415 SharedLocation *shared_location,
00416 KeyFrame *default_keyframe,
00417 PluginSet *plugin_set,
00418 double start,
00419 double length,
00420 int plugin_type)
00421 {
00422 if(!plugin_set)
00423 {
00424 plugin_set = new PluginSet(edl, this);
00425 this->plugin_set.append(plugin_set);
00426 }
00427
00428 Plugin *plugin = 0;
00429
00430
00431 if(plugin_type == PLUGIN_SHAREDPLUGIN)
00432 {
00433 Track *source_track = tracks->get_item_number(shared_location->module);
00434 if(source_track)
00435 {
00436 Plugin *source_plugin = source_track->get_current_plugin(
00437 edl->local_session->get_selectionstart(),
00438 shared_location->plugin,
00439 PLAY_FORWARD,
00440 1,
00441 0);
00442
00443
00444 if(source_plugin)
00445 {
00446 plugin = plugin_set->insert_plugin(title,
00447 source_plugin->startproject,
00448 source_plugin->length,
00449 plugin_type,
00450 shared_location,
00451 default_keyframe,
00452 1);
00453 }
00454 else
00455
00456 {
00457 plugin = plugin_set->insert_plugin(title,
00458 to_units(start, 0),
00459 to_units(length, 1),
00460 plugin_type,
00461 shared_location,
00462 default_keyframe,
00463 1);
00464 }
00465 }
00466 }
00467 else
00468 {
00469
00470 if(EQUIV(length, 0))
00471 {
00472 if(edl->local_session->get_selectionend() >
00473 edl->local_session->get_selectionstart())
00474 {
00475 start = edl->local_session->get_selectionstart();
00476 length = edl->local_session->get_selectionend() - start;
00477 }
00478 else
00479 {
00480 start = 0;
00481 length = get_length();
00482 }
00483 }
00484
00485
00486
00487 plugin = plugin_set->insert_plugin(title,
00488 to_units(start, 0),
00489 to_units(length, 1),
00490 plugin_type,
00491 shared_location,
00492 default_keyframe,
00493 1);
00494 }
00495
00496
00497 expand_view = 1;
00498 return plugin;
00499 }
00500
00501 void Track::move_plugins_up(PluginSet *plugin_set)
00502 {
00503 for(int i = 0; i < this->plugin_set.total; i++)
00504 {
00505 if(this->plugin_set.values[i] == plugin_set)
00506 {
00507 if(i == 0) break;
00508
00509 PluginSet *temp = this->plugin_set.values[i - 1];
00510 this->plugin_set.values[i - 1] = this->plugin_set.values[i];
00511 this->plugin_set.values[i] = temp;
00512
00513 SharedLocation old_location, new_location;
00514 new_location.module = old_location.module = tracks->number_of(this);
00515 old_location.plugin = i;
00516 new_location.plugin = i - 1;
00517 tracks->change_plugins(old_location, new_location, 1);
00518 break;
00519 }
00520 }
00521 }
00522
00523 void Track::move_plugins_down(PluginSet *plugin_set)
00524 {
00525 for(int i = 0; i < this->plugin_set.total; i++)
00526 {
00527 if(this->plugin_set.values[i] == plugin_set)
00528 {
00529 if(i == this->plugin_set.total - 1) break;
00530
00531 PluginSet *temp = this->plugin_set.values[i + 1];
00532 this->plugin_set.values[i + 1] = this->plugin_set.values[i];
00533 this->plugin_set.values[i] = temp;
00534
00535 SharedLocation old_location, new_location;
00536 new_location.module = old_location.module = tracks->number_of(this);
00537 old_location.plugin = i;
00538 new_location.plugin = i + 1;
00539 tracks->change_plugins(old_location, new_location, 1);
00540 break;
00541 }
00542 }
00543 }
00544
00545
00546 void Track::remove_asset(Asset *asset)
00547 {
00548 for(Edit *edit = edits->first; edit; edit = edit->next)
00549 {
00550 if(edit->asset && edit->asset == asset)
00551 {
00552 edit->asset = 0;
00553 }
00554 }
00555 optimize();
00556 }
00557
00558 void Track::remove_pluginset(PluginSet *plugin_set)
00559 {
00560 int i;
00561 for(i = 0; i < this->plugin_set.total; i++)
00562 if(plugin_set == this->plugin_set.values[i]) break;
00563
00564 this->plugin_set.remove_object(plugin_set);
00565 for(i++ ; i < this->plugin_set.total; i++)
00566 {
00567 SharedLocation old_location, new_location;
00568 new_location.module = old_location.module = tracks->number_of(this);
00569 old_location.plugin = i;
00570 new_location.plugin = i - 1;
00571 tracks->change_plugins(old_location, new_location, 0);
00572 }
00573 }
00574
00575 void Track::shift_keyframes(double position, double length, int convert_units)
00576 {
00577 if(convert_units)
00578 {
00579 position = to_units(position, 0);
00580 length = to_units(length, 1);
00581 }
00582
00583 automation->paste_silence(Units::to_int64(position),
00584 Units::to_int64(position + length));
00585
00586 }
00587
00588 void Track::shift_effects(double position, double length, int convert_units)
00589 {
00590 if(convert_units)
00591 {
00592 position = to_units(position, 0);
00593 length = to_units(length, 1);
00594 }
00595
00596 for(int i = 0; i < plugin_set.total; i++)
00597 {
00598 plugin_set.values[i]->shift_effects(Units::to_int64(position), Units::to_int64(length));
00599 }
00600 }
00601
00602 void Track::detach_effect(Plugin *plugin)
00603 {
00604
00605 for(int i = 0; i < plugin_set.total; i++)
00606 {
00607 PluginSet *plugin_set = this->plugin_set.values[i];
00608 for(Plugin *dest = (Plugin*)plugin_set->first;
00609 dest;
00610 dest = (Plugin*)dest->next)
00611 {
00612 if(dest == plugin)
00613 {
00614 int64_t start = plugin->startproject;
00615 int64_t end = plugin->startproject + plugin->length;
00616
00617 plugin_set->clear(start, end);
00618 plugin_set->paste_silence(start, end);
00619
00620
00621 plugin_set->optimize();
00622
00623 if(plugin_set->last == plugin_set->first && plugin_set->last->silence())
00624 remove_pluginset(plugin_set);
00625 return;
00626 }
00627 }
00628 }
00629 }
00630
00631 void Track::resample(double old_rate, double new_rate)
00632 {
00633 edits->resample(old_rate, new_rate);
00634 automation->resample(old_rate, new_rate);
00635 for(int i = 0; i < plugin_set.total; i++)
00636 plugin_set.values[i]->resample(old_rate, new_rate);
00637 nudge = (int64_t)(nudge * new_rate / old_rate);
00638 }
00639
00640 void Track::detach_shared_effects(int module)
00641 {
00642 for(int i = 0; i < plugin_set.total; i++)
00643 {
00644 PluginSet *plugin_set = this->plugin_set.values[i];
00645 for(Plugin *dest = (Plugin*)plugin_set->first;
00646 dest;
00647 dest = (Plugin*)dest->next)
00648 {
00649 if ((dest->plugin_type == PLUGIN_SHAREDPLUGIN ||
00650 dest->plugin_type == PLUGIN_SHAREDMODULE)
00651 &&
00652 dest->shared_location.module == module)
00653 {
00654 int64_t start = dest->startproject;
00655 int64_t end = dest->startproject + dest->length;
00656
00657 plugin_set->clear(start, end);
00658 plugin_set->paste_silence(start, end);
00659
00660
00661 plugin_set->optimize();
00662 if(plugin_set->last == plugin_set->first && plugin_set->last->silence())
00663 {
00664 this->plugin_set.remove_object_number(i);
00665 --i;
00666 }
00667 }
00668 }
00669 }
00670 }
00671
00672
00673 void Track::optimize()
00674 {
00675 edits->optimize();
00676 for(int i = 0; i < plugin_set.total; i++)
00677 {
00678 PluginSet *plugin_set = this->plugin_set.values[i];
00679 plugin_set->optimize();
00680
00681
00682 if(plugin_set->last == plugin_set->first && plugin_set->last->silence())
00683 {
00684 remove_pluginset(plugin_set);
00685 i--;
00686 }
00687 }
00688 }
00689
00690 Plugin* Track::get_current_plugin(double position,
00691 int plugin_set,
00692 int direction,
00693 int convert_units,
00694 int use_nudge)
00695 {
00696 Plugin *current;
00697 if(convert_units) position = to_units(position, 0);
00698 if(use_nudge) position += nudge;
00699
00700 if(plugin_set >= this->plugin_set.total || plugin_set < 0) return 0;
00701
00702
00703 if(direction == PLAY_FORWARD)
00704 {
00705 for(current = (Plugin*)this->plugin_set.values[plugin_set]->last;
00706 current;
00707 current = (Plugin*)PREVIOUS)
00708 {
00709
00710
00711
00712
00713 if(current->startproject <= position &&
00714 current->startproject + current->length > position)
00715 {
00716 return current;
00717 }
00718 }
00719 }
00720 else
00721 if(direction == PLAY_REVERSE)
00722 {
00723 for(current = (Plugin*)this->plugin_set.values[plugin_set]->first;
00724 current;
00725 current = (Plugin*)NEXT)
00726 {
00727 if(current->startproject < position &&
00728 current->startproject + current->length >= position)
00729 {
00730 return current;
00731 }
00732 }
00733 }
00734
00735 return 0;
00736 }
00737
00738 Plugin* Track::get_current_transition(double position,
00739 int direction,
00740 int convert_units,
00741 int use_nudge)
00742 {
00743 Edit *current;
00744 Plugin *result = 0;
00745 if(convert_units) position = to_units(position, 0);
00746 if(use_nudge) position += nudge;
00747
00748 if(direction == PLAY_FORWARD)
00749 {
00750 for(current = edits->last; current; current = PREVIOUS)
00751 {
00752 if(current->startproject <= position && current->startproject + current->length > position)
00753 {
00754
00755 if(current->transition && position < current->startproject + current->transition->length)
00756 {
00757 result = current->transition;
00758 break;
00759 }
00760 }
00761 }
00762 }
00763 else
00764 if(direction == PLAY_REVERSE)
00765 {
00766 for(current = edits->first; current; current = NEXT)
00767 {
00768 if(current->startproject < position && current->startproject + current->length >= position)
00769 {
00770 if(current->transition && position <= current->startproject + current->transition->length)
00771 {
00772 result = current->transition;
00773 break;
00774 }
00775 }
00776 }
00777 }
00778
00779 return result;
00780 }
00781
00782 void Track::synchronize_params(Track *track)
00783 {
00784 for(Edit *this_edit = edits->first, *that_edit = track->edits->first;
00785 this_edit && that_edit;
00786 this_edit = this_edit->next, that_edit = that_edit->next)
00787 {
00788 this_edit->synchronize_params(that_edit);
00789 }
00790
00791 for(int i = 0; i < plugin_set.total && i < track->plugin_set.total; i++)
00792 plugin_set.values[i]->synchronize_params(track->plugin_set.values[i]);
00793
00794 automation->copy_from(track->automation);
00795 this->nudge = track->nudge;
00796 }
00797
00798
00799
00800
00801
00802 int Track::dump()
00803 {
00804 printf(" Data type %d\n", data_type);
00805 printf(" Title %s\n", title);
00806 printf(" Edits:\n");
00807 for(Edit* current = edits->first; current; current = NEXT)
00808 {
00809 current->dump();
00810 }
00811 automation->dump();
00812 printf(" Plugin Sets: %d\n", plugin_set.total);
00813
00814 for(int i = 0; i < plugin_set.total; i++)
00815 plugin_set.values[i]->dump();
00816
00817 return 0;
00818 }
00819
00820
00821
00822
00823
00824
00825
00826
00827
00828
00829
00830
00831
00832
00833
00834
00835
00836
00837
00838
00839
00840 Track::Track() : ListItem<Track>()
00841 {
00842 y_pixel = 0;
00843 }
00844
00845
00846
00847 int Track::number_of()
00848 {
00849 return tracks->number_of(this);
00850 }
00851
00852
00853
00854
00855
00856
00857
00858
00859
00860
00861
00862
00863
00864
00865
00866 int Track::select_auto(AutoConf *auto_conf, int cursor_x, int cursor_y)
00867 {
00868 return 0;
00869 }
00870
00871 int Track::move_auto(AutoConf *auto_conf, int cursor_x, int cursor_y, int shift_down)
00872 {
00873 return 0;
00874 }
00875
00876 int Track::release_auto()
00877 {
00878 return 0;
00879 }
00880
00881
00882 int Track::copy_automation(double selectionstart,
00883 double selectionend,
00884 FileXML *file,
00885 int default_only,
00886 int autos_only)
00887 {
00888 int64_t start = to_units(selectionstart, 0);
00889 int64_t end = to_units(selectionend, 1);
00890
00891 file->tag.set_title("TRACK");
00892
00893 save_header(file);
00894 file->append_tag();
00895 file->append_newline();
00896
00897 automation->copy(start, end, file, default_only, autos_only);
00898
00899 if(edl->session->auto_conf->plugins)
00900 {
00901 file->tag.set_title("PLUGINSETS");
00902 file->append_tag();
00903 file->append_newline();
00904 for(int i = 0; i < plugin_set.total; i++)
00905 {
00906
00907 plugin_set.values[i]->copy_keyframes(start,
00908 end,
00909 file,
00910 default_only,
00911 autos_only);
00912 }
00913 file->tag.set_title("/PLUGINSETS");
00914 file->append_tag();
00915 file->append_newline();
00916 }
00917
00918 file->tag.set_title("/TRACK");
00919 file->append_tag();
00920 file->append_newline();
00921 file->append_newline();
00922 file->append_newline();
00923 file->append_newline();
00924
00925 return 0;
00926 }
00927
00928 int Track::paste_automation(double selectionstart,
00929 double total_length,
00930 double frame_rate,
00931 int64_t sample_rate,
00932 FileXML *file,
00933 int default_only)
00934 {
00935
00936 int64_t start;
00937 int64_t length;
00938 int result;
00939 double scale;
00940
00941 if(data_type == TRACK_AUDIO)
00942 scale = edl->session->sample_rate / sample_rate;
00943 else
00944 scale = edl->session->frame_rate / frame_rate;
00945
00946 total_length *= scale;
00947 start = to_units(selectionstart, 0);
00948 length = to_units(total_length, 1);
00949 result = 0;
00950
00951
00952 while(!result)
00953 {
00954 result = file->read_tag();
00955
00956 if(!result)
00957 {
00958 if(file->tag.title_is("/TRACK"))
00959 result = 1;
00960 else
00961 if(automation->paste(start,
00962 length,
00963 scale,
00964 file,
00965 default_only,
00966 0))
00967
00968 {
00969 ;
00970 }
00971 else
00972 if(file->tag.title_is("PLUGINSETS"))
00973 {
00974
00975 PluginSet::paste_keyframes(start,
00976 length,
00977 file,
00978 default_only,
00979 this);
00980 }
00981 }
00982 }
00983
00984
00985
00986 return 0;
00987 }
00988
00989 void Track::clear_automation(double selectionstart,
00990 double selectionend,
00991 int shift_autos,
00992 int default_only)
00993 {
00994 int64_t start = to_units(selectionstart, 0);
00995 int64_t end = to_units(selectionend, 1);
00996
00997 automation->clear(start, end, edl->session->auto_conf, 0);
00998
00999 if(edl->session->auto_conf->plugins)
01000 {
01001 for(int i = 0; i < plugin_set.total; i++)
01002 {
01003 plugin_set.values[i]->clear_keyframes(start, end);
01004 }
01005 }
01006
01007 }
01008
01009 void Track::straighten_automation(double selectionstart,
01010 double selectionend)
01011 {
01012 int64_t start = to_units(selectionstart, 0);
01013 int64_t end = to_units(selectionend, 1);
01014
01015 automation->straighten(start, end, edl->session->auto_conf);
01016 }
01017
01018
01019
01020
01021 int Track::copy(double start,
01022 double end,
01023 FileXML *file,
01024 char *output_path)
01025 {
01026
01027
01028 int64_t start_unit = to_units(start, 0);
01029 int64_t end_unit = to_units(end, 1);
01030
01031
01032
01033
01034 file->tag.set_title("TRACK");
01035 file->tag.set_property("RECORD", record);
01036 file->tag.set_property("NUDGE", nudge);
01037 file->tag.set_property("PLAY", play);
01038 file->tag.set_property("GANG", gang);
01039 file->tag.set_property("DRAW", draw);
01040 file->tag.set_property("EXPAND", expand_view);
01041 file->tag.set_property("TRACK_W", track_w);
01042 file->tag.set_property("TRACK_H", track_h);
01043 save_header(file);
01044 file->append_tag();
01045 file->append_newline();
01046 save_derived(file);
01047
01048 file->tag.set_title("TITLE");
01049 file->append_tag();
01050 file->append_text(title);
01051 file->tag.set_title("/TITLE");
01052 file->append_tag();
01053 file->append_newline();
01054
01055
01056
01057
01058
01059
01060
01061
01062
01063 edits->copy(start_unit, end_unit, file, output_path);
01064
01065 AutoConf auto_conf;
01066 auto_conf.set_all(1);
01067 automation->copy(start_unit, end_unit, file, 0, 0);
01068
01069
01070 for(int i = 0; i < plugin_set.total; i++)
01071 {
01072 plugin_set.values[i]->copy(start_unit, end_unit, file);
01073 }
01074
01075 copy_derived(start_unit, end_unit, file);
01076
01077 file->tag.set_title("/TRACK");
01078 file->append_tag();
01079 file->append_newline();
01080 file->append_newline();
01081 file->append_newline();
01082 file->append_newline();
01083
01084 return 0;
01085 }
01086
01087 int Track::copy_assets(double start,
01088 double end,
01089 ArrayList<Asset*> *asset_list)
01090 {
01091 int i, result = 0;
01092
01093 start = to_units(start, 0);
01094 end = to_units(end, 1);
01095
01096 Edit *current = edits->editof((int64_t)start, PLAY_FORWARD, 0);
01097
01098
01099 while(current && current->startproject < end)
01100 {
01101
01102 if(current->asset)
01103 {
01104 for(i = 0, result = 0; i < asset_list->total; i++)
01105 {
01106 if(asset_list->values[i] == current->asset) result = 1;
01107 }
01108
01109 if(!result) asset_list->append(current->asset);
01110 }
01111
01112 current = NEXT;
01113 }
01114
01115 return 0;
01116 }
01117
01118
01119
01120
01121
01122 int Track::clear(double start,
01123 double end,
01124 int edit_edits,
01125 int edit_labels,
01126 int edit_plugins,
01127 int convert_units,
01128 Edits *trim_edits)
01129 {
01130
01131
01132
01133 if(convert_units)
01134 {
01135 start = to_units(start, 0);
01136 end = to_units(end, 1);
01137 }
01138
01139 if(edit_edits)
01140 automation->clear((int64_t)start, (int64_t)end, 0, 1);
01141
01142 if(edit_plugins)
01143 for(int i = 0; i < plugin_set.total; i++)
01144 {
01145 if(!trim_edits || trim_edits == (Edits*)plugin_set.values[i])
01146 plugin_set.values[i]->clear((int64_t)start, (int64_t)end);
01147 }
01148
01149 if(edit_edits)
01150 edits->clear((int64_t)start, (int64_t)end);
01151 return 0;
01152 }
01153
01154 int Track::clear_handle(double start,
01155 double end,
01156 int clear_labels,
01157 int clear_plugins,
01158 double &distance)
01159 {
01160 edits->clear_handle(start, end, clear_plugins, distance);
01161 }
01162
01163 int Track::popup_transition(int cursor_x, int cursor_y)
01164 {
01165 return 0;
01166 }
01167
01168
01169
01170 int Track::modify_edithandles(double oldposition,
01171 double newposition,
01172 int currentend,
01173 int handle_mode,
01174 int edit_labels,
01175 int edit_plugins)
01176 {
01177 edits->modify_handles(oldposition,
01178 newposition,
01179 currentend,
01180 handle_mode,
01181 1,
01182 edit_labels,
01183 edit_plugins,
01184 0);
01185
01186
01187 return 0;
01188 }
01189
01190 int Track::modify_pluginhandles(double oldposition,
01191 double newposition,
01192 int currentend,
01193 int handle_mode,
01194 int edit_labels,
01195 Edits *trim_edits)
01196 {
01197 for(int i = 0; i < plugin_set.total; i++)
01198 {
01199 if(!trim_edits || trim_edits == (Edits*)plugin_set.values[i])
01200 plugin_set.values[i]->modify_handles(oldposition,
01201 newposition,
01202 currentend,
01203 handle_mode,
01204
01205 0,
01206 edit_labels,
01207 1,
01208 trim_edits);
01209 }
01210 return 0;
01211 }
01212
01213
01214 int Track::paste_silence(double start, double end, int edit_plugins)
01215 {
01216 start = to_units(start, 0);
01217 end = to_units(end, 1);
01218
01219 edits->paste_silence((int64_t)start, (int64_t)end);
01220 shift_keyframes(start, end - start, 0);
01221 if(edit_plugins) shift_effects(start, end - start, 0);
01222
01223 edits->optimize();
01224 return 0;
01225 }
01226
01227 int Track::select_edit(int cursor_x,
01228 int cursor_y,
01229 double &new_start,
01230 double &new_end)
01231 {
01232 return 0;
01233 }
01234
01235 int Track::scale_time(float rate_scale, int scale_edits, int scale_autos, int64_t start, int64_t end)
01236 {
01237 return 0;
01238 }
01239
01240 void Track::change_plugins(SharedLocation &old_location, SharedLocation &new_location, int do_swap)
01241 {
01242 for(int i = 0; i < plugin_set.total; i++)
01243 {
01244 for(Plugin *plugin = (Plugin*)plugin_set.values[i]->first;
01245 plugin;
01246 plugin = (Plugin*)plugin->next)
01247 {
01248 if(plugin->plugin_type == PLUGIN_SHAREDPLUGIN)
01249 {
01250 if(plugin->shared_location == old_location)
01251 plugin->shared_location = new_location;
01252 else
01253 if(do_swap && plugin->shared_location == new_location)
01254 plugin->shared_location = old_location;
01255 }
01256 }
01257 }
01258 }
01259
01260 void Track::change_modules(int old_location, int new_location, int do_swap)
01261 {
01262 for(int i = 0; i < plugin_set.total; i++)
01263 {
01264 for(Plugin *plugin = (Plugin*)plugin_set.values[i]->first;
01265 plugin;
01266 plugin = (Plugin*)plugin->next)
01267 {
01268 if(plugin->plugin_type == PLUGIN_SHAREDPLUGIN ||
01269 plugin->plugin_type == PLUGIN_SHAREDMODULE)
01270 {
01271 if(plugin->shared_location.module == old_location)
01272 plugin->shared_location.module = new_location;
01273 else
01274 if(do_swap && plugin->shared_location.module == new_location)
01275 plugin->shared_location.module = old_location;
01276 }
01277 }
01278 }
01279 }
01280
01281
01282 int Track::playable_edit(int64_t position, int direction)
01283 {
01284 int result = 0;
01285 if(direction == PLAY_REVERSE) position--;
01286 for(Edit *current = edits->first; current && !result; current = NEXT)
01287 {
01288 if(current->startproject <= position &&
01289 current->startproject + current->length > position)
01290 {
01291
01292 if(current->transition || current->asset) result = 1;
01293 }
01294 }
01295 return result;
01296 }
01297
01298
01299 int Track::need_edit(Edit *current, int test_transitions)
01300 {
01301 return ((test_transitions && current->transition) ||
01302 (!test_transitions && current->asset));
01303 }
01304
01305 int64_t Track::plugin_change_duration(int64_t input_position,
01306 int64_t input_length,
01307 int reverse,
01308 int use_nudge)
01309 {
01310 if(use_nudge) input_position += nudge;
01311 for(int i = 0; i < plugin_set.total; i++)
01312 {
01313 int64_t new_duration = plugin_set.values[i]->plugin_change_duration(
01314 input_position,
01315 input_length,
01316 reverse);
01317 if(new_duration < input_length) input_length = new_duration;
01318 }
01319 return input_length;
01320 }
01321
01322 int64_t Track::edit_change_duration(int64_t input_position,
01323 int64_t input_length,
01324 int reverse,
01325 int test_transitions,
01326 int use_nudge)
01327 {
01328 Edit *current;
01329 int64_t edit_length = input_length;
01330 if(use_nudge) input_position += nudge;
01331
01332 if(reverse)
01333 {
01334
01335
01336 for(current = edits->first;
01337 current && current->startproject + current->length <= input_position;
01338 current = NEXT)
01339 ;
01340
01341 if(current)
01342 {
01343 if(current->startproject > input_position)
01344 {
01345
01346 ;
01347 }
01348 else
01349 if(need_edit(current, test_transitions))
01350 {
01351
01352 if(input_position - current->startproject < input_length)
01353 edit_length = input_position - current->startproject + 1;
01354 }
01355 else
01356 {
01357
01358
01359 for(current = PREVIOUS ;
01360 current &&
01361 current->startproject + current->length > input_position - input_length &&
01362 !need_edit(current, test_transitions);
01363 current = PREVIOUS)
01364 ;
01365
01366 if(current &&
01367 need_edit(current, test_transitions) &&
01368 current->startproject + current->length > input_position - input_length)
01369 edit_length = input_position - current->startproject - current->length + 1;
01370 }
01371 }
01372 else
01373 {
01374
01375 current = edits->last;
01376 if(current &&
01377 ((test_transitions && current->transition) ||
01378 (!test_transitions && current->asset)))
01379 edit_length = input_position - edits->length() + 1;
01380 }
01381 }
01382 else
01383 {
01384
01385
01386 for(current = edits->last;
01387 current && current->startproject > input_position;
01388 current = PREVIOUS)
01389 ;
01390
01391 if(current)
01392 {
01393 if(current->startproject + current->length <= input_position)
01394 {
01395
01396 ;
01397 }
01398 else
01399 if(need_edit(current, test_transitions))
01400 {
01401
01402
01403 if(current->length + current->startproject - input_position < input_length)
01404 edit_length = current->startproject + current->length - input_position;
01405 }
01406 else
01407 {
01408
01409
01410 for(current = NEXT ;
01411 current &&
01412 current->startproject < input_position + input_length &&
01413 !need_edit(current, test_transitions);
01414 current = NEXT)
01415 ;
01416
01417 if(current &&
01418 need_edit(current, test_transitions) &&
01419 current->startproject < input_position + input_length)
01420 edit_length = current->startproject - input_position;
01421 }
01422 }
01423 else
01424 {
01425
01426 current = edits->first;
01427 if(current &&
01428 ((test_transitions && current->transition) ||
01429 (!test_transitions && current->asset)))
01430 edit_length = edits->first->startproject - input_position;
01431 }
01432 }
01433
01434 if(edit_length < input_length)
01435 return edit_length;
01436 else
01437 return input_length;
01438 }
01439
01440 int Track::purge_asset(Asset *asset)
01441 {
01442 return 0;
01443 }
01444
01445 int Track::asset_used(Asset *asset)
01446 {
01447 Edit* current_edit;
01448 int result = 0;
01449
01450 for(current_edit = edits->first; current_edit; current_edit = current_edit->next)
01451 {
01452 if(current_edit->asset == asset)
01453 {
01454 result++;
01455 }
01456 }
01457 return result;
01458 }
01459
01460 int Track::is_playable(int64_t position, int direction)
01461 {
01462 return 1;
01463 }
01464
01465
01466 int Track::plugin_used(int64_t position, int64_t direction)
01467 {
01468
01469 for(int i = 0; i < this->plugin_set.total; i++)
01470 {
01471 Plugin *current_plugin = get_current_plugin(position,
01472 i,
01473 direction,
01474 0,
01475 0);
01476
01477
01478 if(current_plugin &&
01479 (current_plugin->on &&
01480 current_plugin->plugin_type != PLUGIN_NONE))
01481 {
01482 return 1;
01483 }
01484 }
01485
01486 return 0;
01487 }
01488
01489
01490 int Track::direct_copy_possible(int64_t start, int direction, int use_nudge)
01491 {
01492 return 1;
01493 }
01494
01495 int64_t Track::to_units(double position, int round)
01496 {
01497 return (int64_t)position;
01498 }
01499
01500 double Track::to_doubleunits(double position)
01501 {
01502 return position;
01503 }
01504
01505 double Track::from_units(int64_t position)
01506 {
01507 return (double)position;
01508 }