00001 #include "edl.h"
00002 #include "edlsession.h"
00003 #include "filexml.h"
00004 #include "keyframe.h"
00005 #include "keyframes.h"
00006 #include "plugin.h"
00007 #include "pluginautos.h"
00008 #include "pluginset.h"
00009 #include "track.h"
00010
00011 #include <string.h>
00012
00013 PluginSet::PluginSet(EDL *edl, Track *track)
00014 : Edits(edl, track)
00015 {
00016 record = 1;
00017 }
00018
00019 PluginSet::~PluginSet()
00020 {
00021 while(last) delete last;
00022 }
00023
00024
00025 PluginSet& PluginSet::operator=(PluginSet& plugins)
00026 {
00027 printf("PluginSet::operator= 1\n");
00028 copy_from(&plugins);
00029 return *this;
00030 }
00031
00032 void PluginSet::copy_from(PluginSet *src)
00033 {
00034 while(last) delete last;
00035 for(Plugin *current = (Plugin*)src->first; current; current = (Plugin*)NEXT)
00036 {
00037 Plugin *new_plugin;
00038 append(new_plugin = (Plugin*)create_edit());
00039 new_plugin->copy_from(current);
00040 }
00041 this->record = src->record;
00042 }
00043
00044 Plugin* PluginSet::get_first_plugin()
00045 {
00046
00047
00048 for(Plugin *current = (Plugin*)first; current; current = (Plugin*)NEXT)
00049 {
00050 if(current && current->plugin_type != PLUGIN_NONE)
00051 {
00052 return current;
00053 }
00054 }
00055 return 0;
00056 }
00057
00058 int64_t PluginSet::plugin_change_duration(int64_t input_position,
00059 int64_t input_length,
00060 int reverse)
00061 {
00062 int result = input_length;
00063 Edit *current;
00064
00065 if(reverse)
00066 {
00067 int input_start = input_position - input_length;
00068 for(current = last; current; current = PREVIOUS)
00069 {
00070 int start = current->startproject;
00071 int end = start + current->length;
00072 if(end > input_start && end < input_position)
00073 {
00074 result = input_position - end;
00075 return result;
00076 }
00077 else
00078 if(start > input_start && start < input_position)
00079 {
00080 result = input_position - start;
00081 return result;
00082 }
00083 }
00084 }
00085 else
00086 {
00087 int input_end = input_position + input_length;
00088 for(current = first; current; current = NEXT)
00089 {
00090 int start = current->startproject;
00091 int end = start + current->length;
00092 if(start > input_position && start < input_end)
00093 {
00094 result = start - input_position;
00095 return result;
00096 }
00097 else
00098 if(end > input_position && end < input_end)
00099 {
00100 result = end - input_position;
00101 return result;
00102 }
00103 }
00104 }
00105 return input_length;
00106 }
00107
00108 void PluginSet::synchronize_params(PluginSet *plugin_set)
00109 {
00110 for(Plugin *this_plugin = (Plugin*)first, *that_plugin = (Plugin*)plugin_set->first;
00111 this_plugin && that_plugin;
00112 this_plugin = (Plugin*)this_plugin->next, that_plugin = (Plugin*)that_plugin->next)
00113 {
00114 this_plugin->synchronize_params(that_plugin);
00115 }
00116 }
00117
00118 Plugin* PluginSet::insert_plugin(char *title,
00119 int64_t unit_position,
00120 int64_t unit_length,
00121 int plugin_type,
00122 SharedLocation *shared_location,
00123 KeyFrame *default_keyframe,
00124 int do_optimize)
00125 {
00126 Plugin *plugin = (Plugin*)create_and_insert_edit(unit_position,
00127 unit_position + unit_length);
00128
00129
00130 if(title) strcpy(plugin->title, title);
00131
00132 if(shared_location) plugin->shared_location = *shared_location;
00133
00134 plugin->plugin_type = plugin_type;
00135
00136 if(default_keyframe)
00137 *plugin->keyframes->default_auto = *default_keyframe;
00138 plugin->keyframes->default_auto->position = unit_position;
00139
00140
00141 if(do_optimize) optimize();
00142 return plugin;
00143 }
00144
00145 Edit* PluginSet::create_edit()
00146 {
00147 Plugin* result = new Plugin(edl, this, "");
00148 return result;
00149 }
00150
00151 Edit* PluginSet::insert_edit_after(Edit *previous_edit)
00152 {
00153 Plugin *current = new Plugin(edl, this, "");
00154 List<Edit>::insert_after(previous_edit, current);
00155 return (Edit*)current;
00156 }
00157
00158
00159 int PluginSet::get_number()
00160 {
00161 return track->plugin_set.number_of(this);
00162 }
00163
00164 void PluginSet::clear(int64_t start, int64_t end)
00165 {
00166
00167 for(Plugin *current = (Plugin*)first;
00168 current;
00169 current = (Plugin*)NEXT)
00170 {
00171 current->keyframes->clear(start, end, 1);
00172 }
00173
00174
00175 Edits::clear(start, end);
00176 }
00177
00178 void PluginSet::clear_recursive(int64_t start, int64_t end)
00179 {
00180
00181 clear(start, end);
00182 }
00183
00184 void PluginSet::shift_keyframes_recursive(int64_t position, int64_t length)
00185 {
00186
00187 }
00188
00189 void PluginSet::shift_effects_recursive(int64_t position, int64_t length)
00190 {
00191
00192
00193 }
00194
00195
00196 void PluginSet::clear_keyframes(int64_t start, int64_t end)
00197 {
00198 for(Plugin *current = (Plugin*)first; current; current = (Plugin*)NEXT)
00199 {
00200 current->clear_keyframes(start, end);
00201 }
00202 }
00203
00204 void PluginSet::copy_keyframes(int64_t start,
00205 int64_t end,
00206 FileXML *file,
00207 int default_only,
00208 int autos_only)
00209 {
00210 file->tag.set_title("PLUGINSET");
00211 file->append_tag();
00212 file->append_newline();
00213
00214 for(Plugin *current = (Plugin*)first;
00215 current;
00216 current = (Plugin*)NEXT)
00217 {
00218 current->copy_keyframes(start, end, file, default_only, autos_only);
00219 }
00220
00221 file->tag.set_title("/PLUGINSET");
00222 file->append_tag();
00223 file->append_newline();
00224 }
00225
00226
00227 void PluginSet::paste_keyframes(int64_t start,
00228 int64_t length,
00229 FileXML *file,
00230 int default_only,
00231 Track *track)
00232 {
00233 int result = 0;
00234 Plugin *current;
00235
00236 PluginSet *target_pluginset;
00237 Plugin *first_target_plugin = 0;
00238
00239 ArrayList<PluginSet*> unused_pluginsets;
00240
00241
00242 for (int i = 0; i < track->plugin_set.total; i++)
00243 {
00244 unused_pluginsets.append(track->plugin_set.values[i]);
00245 }
00246
00247 char data[MESSAGESIZE];
00248 char data_default_keyframe[MESSAGESIZE];
00249 int default_keyframe;
00250 int do_default_keyframe = 0;
00251
00252 while(!result)
00253 {
00254 result = file->read_tag();
00255
00256 if(!result)
00257 {
00258 if(file->tag.title_is("/PLUGINSETS"))
00259 result = 1;
00260 else
00261 if(file->tag.title_is("PLUGINSET"))
00262 {
00263 target_pluginset = 0;
00264 first_target_plugin = 0;
00265 }
00266 else
00267 if(file->tag.title_is("KEYFRAME"))
00268 {
00269 int64_t position = file->tag.get_property("POSITION", 0);
00270 position += start;
00271 if(file->tag.get_property("DEFAULT", 0))
00272 {
00273
00274 default_keyframe = 1;
00275 do_default_keyframe = 1;
00276 file->read_text_until("/KEYFRAME", data_default_keyframe, MESSAGESIZE);
00277 }
00278 else
00279 {
00280 default_keyframe = 0;
00281 file->read_text_until("/KEYFRAME", data, MESSAGESIZE);
00282
00283 }
00284
00285
00286 Plugin *picked_first_target = 0;
00287 if (!target_pluginset && default_keyframe && default_only && strlen(data_default_keyframe) > 0)
00288 {
00289 strcpy(data, data_default_keyframe);
00290 }
00291 if ((!target_pluginset && !default_keyframe && strlen(data) > 0) ||
00292 (!target_pluginset && default_keyframe && default_only && strlen(data_default_keyframe) > 0))
00293 {
00294
00295 int name_len = strchr(data, ' ') - data + 1;
00296
00297 PluginSet *second_choice = 0;
00298 Plugin *second_choice_first_target_plugin = 0;
00299 for (int i = 0; i < unused_pluginsets.total && !target_pluginset; i++)
00300 {
00301 PluginSet *pluginset = unused_pluginsets.values[i];
00302 Plugin *current;
00303 for(current = (Plugin*)(pluginset->last);
00304 current;
00305 current = (Plugin*)PREVIOUS)
00306 {
00307 if(position >= current->startproject
00308 && position <= current->length + current->startproject
00309 && !strncmp(((KeyFrame *)current->keyframes->default_auto)->data, data, name_len))
00310 {
00311 target_pluginset = pluginset;
00312 first_target_plugin = current;
00313 break;
00314 }
00315 if(position >= current->startproject
00316 && !strncmp(((KeyFrame *)current->keyframes->default_auto)->data, data, name_len))
00317 {
00318 second_choice = pluginset;
00319 second_choice_first_target_plugin = current;
00320 break;
00321 }
00322
00323 }
00324 }
00325 if (!target_pluginset)
00326 {
00327 target_pluginset = second_choice;
00328 first_target_plugin = second_choice_first_target_plugin;
00329 }
00330 }
00331
00332 if (target_pluginset)
00333 {
00334 unused_pluginsets.remove(target_pluginset);
00335 if (do_default_keyframe)
00336 {
00337
00338 KeyFrame *keyframe = (KeyFrame*)first_target_plugin->keyframes->default_auto;
00339 strcpy(keyframe->data, data_default_keyframe);
00340 keyframe->position = position;
00341 do_default_keyframe = 0;
00342 }
00343 if (!default_only && !default_keyframe)
00344 {
00345 for(current = (Plugin*)target_pluginset->last;
00346 current;
00347 current = (Plugin*)PREVIOUS)
00348 {
00349 if(position >= current->startproject)
00350 {
00351 KeyFrame *keyframe;
00352 keyframe = (KeyFrame*)current->keyframes->insert_auto(position);
00353 strcpy(keyframe->data, data);
00354 keyframe->position = position;
00355 break;
00356 }
00357 }
00358 }
00359 }
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388 }
00389 }
00390 }
00391 }
00392
00393 void PluginSet::shift_effects(int64_t start, int64_t length)
00394 {
00395 for(Plugin *current = (Plugin*)first;
00396 current;
00397 current = (Plugin*)NEXT)
00398 {
00399
00400 if(current->startproject >= start)
00401 {
00402 current->startproject += length;
00403 }
00404 else
00405
00406
00407
00408
00409 if(current->startproject + current->length >= start)
00410 {
00411 current->length += length;
00412 }
00413
00414
00415
00416
00417 if(current->keyframes->default_auto->position >= start)
00418 current->keyframes->default_auto->position += length;
00419
00420 current->keyframes->paste_silence(start, start + length);
00421 }
00422 }
00423
00424 void PluginSet::copy(int64_t start, int64_t end, FileXML *file)
00425 {
00426 file->tag.set_title("PLUGINSET");
00427 file->tag.set_property("RECORD", record);
00428 file->append_tag();
00429 file->append_newline();
00430
00431 for(Plugin *current = (Plugin*)first; current; current = (Plugin*)NEXT)
00432 {
00433 current->copy(start, end, file);
00434 }
00435
00436 file->tag.set_title("/PLUGINSET");
00437 file->append_tag();
00438 file->append_newline();
00439 }
00440
00441 void PluginSet::save(FileXML *file)
00442 {
00443 copy(0, length(), file);
00444 }
00445
00446 void PluginSet::load(FileXML *file, uint32_t load_flags)
00447 {
00448 int result = 0;
00449
00450 Plugin *plugin = (Plugin*)first;
00451 int64_t startproject = 0;
00452
00453 record = file->tag.get_property("RECORD", record);
00454 do{
00455 result = file->read_tag();
00456
00457
00458 if(!result)
00459 {
00460 if(file->tag.title_is("/PLUGINSET"))
00461 {
00462 result = 1;
00463 }
00464 else
00465 if(file->tag.title_is("PLUGIN"))
00466 {
00467 int64_t length = file->tag.get_property("LENGTH", (int64_t)0);
00468 int plugin_type = file->tag.get_property("TYPE", 1);
00469 char title[BCTEXTLEN];
00470 title[0] = 0;
00471 file->tag.get_property("TITLE", title);
00472 SharedLocation shared_location;
00473 shared_location.load(file);
00474
00475
00476 if(load_flags & LOAD_EDITS)
00477 {
00478 plugin = insert_plugin(title,
00479 startproject,
00480 length,
00481 plugin_type,
00482 &shared_location,
00483 0,
00484 0);
00485 plugin->load(file);
00486 startproject += length;
00487 }
00488 else
00489 if(load_flags & LOAD_AUTOMATION)
00490 {
00491 if(plugin)
00492 {
00493 plugin->load(file);
00494 plugin = (Plugin*)plugin->next;
00495 }
00496 }
00497 }
00498 }
00499 }while(!result);
00500 }
00501
00502
00503
00504 int PluginSet::optimize()
00505 {
00506 int result = 1;
00507 Plugin *current_edit;
00508
00509
00510
00511 for(current_edit = (Plugin*)first;
00512 current_edit;
00513 current_edit = (Plugin*)current_edit->next)
00514 {
00515 current_edit->keyframes->default_auto->position = 0;
00516 for(KeyFrame *current_keyframe = (KeyFrame*)current_edit->keyframes->last;
00517 current_keyframe; )
00518 {
00519 KeyFrame *previous_keyframe = (KeyFrame*)current_keyframe->previous;
00520 if(current_keyframe->position >
00521 current_edit->startproject + current_edit->length ||
00522 current_keyframe->position < current_edit->startproject)
00523 {
00524 delete current_keyframe;
00525 }
00526 current_keyframe = previous_keyframe;
00527 }
00528 }
00529
00530
00531 for(Plugin *current = (Plugin*)last; current; current = (Plugin*)PREVIOUS)
00532 {
00533 if(current->previous)
00534 {
00535 Plugin *previous = (Plugin*)PREVIOUS;
00536
00537 if(current->startproject -
00538 previous->startproject -
00539 previous->length > 0)
00540 {
00541 Plugin *new_plugin = (Plugin*)create_edit();
00542 insert_before(current, new_plugin);
00543 new_plugin->startproject = previous->startproject +
00544 previous->length;
00545 new_plugin->length = current->startproject -
00546 previous->startproject -
00547 previous->length;
00548 }
00549 }
00550 else
00551 if(current->startproject > 0)
00552 {
00553 Plugin *new_plugin = (Plugin*)create_edit();
00554 insert_before(current, new_plugin);
00555 new_plugin->length = current->startproject;
00556 }
00557 }
00558
00559
00560
00561 while(result)
00562 {
00563 result = 0;
00564
00565 for(current_edit = (Plugin*)first;
00566 current_edit && !result; )
00567 {
00568 if(current_edit->length == 0)
00569 {
00570 Plugin* next = (Plugin*)current_edit->next;
00571 delete current_edit;
00572 result = 1;
00573 current_edit = next;
00574 }
00575 else
00576 current_edit = (Plugin*)current_edit->next;
00577 }
00578
00579
00580
00581 for(current_edit = (Plugin*)first;
00582 current_edit && current_edit->next && !result; )
00583 {
00584 Plugin *next_edit = (Plugin*)current_edit->next;
00585
00586
00587
00588 if(next_edit->identical(current_edit))
00589 {
00590 current_edit->length += next_edit->length;
00591
00592 for(KeyFrame *source = (KeyFrame*)next_edit->keyframes->first;
00593 source;
00594 source = (KeyFrame*)source->next)
00595 {
00596 KeyFrame *dest = new KeyFrame(edl, current_edit->keyframes);
00597 *dest = *source;
00598 current_edit->keyframes->append(dest);
00599 }
00600 remove(next_edit);
00601 result = 1;
00602 }
00603
00604 current_edit = (Plugin*)current_edit->next;
00605 }
00606
00607
00608 if(last)
00609 {
00610 if(last->silence() || !last->length)
00611 {
00612 delete last;
00613 result = 1;
00614 }
00615 }
00616 }
00617
00618 return 0;
00619 }
00620
00621
00622
00623
00624
00625 void PluginSet::dump()
00626 {
00627 printf(" PLUGIN_SET:\n");
00628 for(Plugin *current = (Plugin*)first; current; current = (Plugin*)NEXT)
00629 current->dump();
00630 }