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",