4 * Copyright (C) 2008 Adam Williams <broadcast at earthling dot net>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 #include "bcsignals.h"
24 #include "edlsession.h"
28 #include "keyframes.h"
29 #include "localsession.h"
33 #include "pluginpopup.h"
34 #include "pluginset.h"
35 #include "pluginserver.h"
38 #include "virtualnode.h"
41 Plugin::Plugin(EDL *edl,
49 strcpy(this->title, title);
50 plugin_type = PLUGIN_NONE;
55 keyframes = new KeyFrames(edl, track);
56 keyframes->create_objects();
60 Plugin::Plugin(EDL *edl,
61 PluginSet *plugin_set,
63 : Edit(edl, plugin_set)
66 this->track = plugin_set->track;
67 this->plugin_set = plugin_set;
68 strcpy(this->title, title);
69 plugin_type = PLUGIN_NONE;
74 keyframes = new KeyFrames(edl, track);
75 keyframes->create_objects();
80 while(keyframes->last) delete keyframes->last;
84 Edit& Plugin::operator=(Edit& edit)
90 Plugin& Plugin::operator=(Plugin& edit)
96 int Plugin::operator==(Plugin& that)
98 return identical(&that);
101 int Plugin::operator==(Edit& that)
103 return identical((Plugin*)&that);
106 int Plugin::silence()
108 if(plugin_type != PLUGIN_NONE)
114 void Plugin::clear_keyframes(int64_t start, int64_t end)
116 keyframes->clear(start, end, 0);
120 void Plugin::copy_from(Edit *edit)
122 Plugin *plugin = (Plugin*)edit;
124 this->startsource = edit->startsource;
125 this->startproject = edit->startproject;
126 this->length = edit->length;
129 this->plugin_type = plugin->plugin_type;
130 this->in = plugin->in;
131 this->out = plugin->out;
132 this->show = plugin->show;
133 this->on = plugin->on;
134 // Should reconfigure this based on where the first track is now.
135 this->shared_location = plugin->shared_location;
136 strcpy(this->title, plugin->title);
138 copy_keyframes(plugin);
141 void Plugin::copy_keyframes(Plugin *plugin)
144 keyframes->copy_from(plugin->keyframes);
147 void Plugin::copy_keyframes(int64_t start,
153 // Only 1 default is copied from where the start position is
154 int64_t endproject = startproject + length;
157 start < endproject &&
158 start >= startproject))
159 keyframes->copy(start, end, file, default_only, active_only);
162 void Plugin::synchronize_params(Edit *edit)
164 Plugin *plugin = (Plugin*)edit;
165 this->in = plugin->in;
166 this->out = plugin->out;
167 this->show = plugin->show;
168 this->on = plugin->on;
169 strcpy(this->title, plugin->title);
170 copy_keyframes(plugin);
173 void Plugin::shift_keyframes(int64_t position)
175 for(KeyFrame *keyframe = (KeyFrame*)keyframes->first;
177 keyframe = (KeyFrame*)keyframe->next)
179 keyframe->position += position;
184 void Plugin::equivalent_output(Edit *edit, int64_t *result)
186 Plugin *plugin = (Plugin*)edit;
187 // End of plugin changed
188 if(startproject + length != plugin->startproject + plugin->length)
190 if(*result < 0 || startproject + length < *result)
191 *result = startproject + length;
194 // Start of plugin changed
196 startproject != plugin->startproject ||
197 plugin_type != plugin->plugin_type ||
199 !(shared_location == plugin->shared_location) ||
200 strcmp(title, plugin->title)
203 if(*result < 0 || startproject < *result)
204 *result = startproject;
208 keyframes->equivalent_output(plugin->keyframes, startproject, result);
213 int Plugin::is_synthesis(int64_t position,
218 case PLUGIN_STANDALONE:
222 printf("Plugin::is_synthesis track not defined\n");
227 PluginServer *plugin_server = MWindow::scan_plugindb(title,
229 //printf("Plugin::is_synthesis %d %p %d\n", __LINE__, plugin_server, plugin_server->get_synthesis());
230 //plugin_server->dump();
231 return plugin_server->get_synthesis();
235 // Dereference real plugin and descend another level
236 case PLUGIN_SHAREDPLUGIN:
238 int real_module_number = shared_location.module;
239 int real_plugin_number = shared_location.plugin;
240 Track *track = edl->tracks->number(real_module_number);
241 // Get shared plugin from master track
242 Plugin *plugin = track->get_current_plugin(position,
249 return plugin->is_synthesis(position, direction);
253 // Dereference the real track and descend
254 case PLUGIN_SHAREDMODULE:
256 int real_module_number = shared_location.module;
257 Track *track = edl->tracks->number(real_module_number);
258 return track->is_synthesis(position, direction);
267 int Plugin::identical(Plugin *that)
270 if(plugin_type != that->plugin_type) return 0;
272 // Test title or location
275 case PLUGIN_STANDALONE:
276 if(strcmp(title, that->title)) return 0;
278 case PLUGIN_SHAREDPLUGIN:
279 if(shared_location.module != that->shared_location.module ||
280 shared_location.plugin != that->shared_location.plugin) return 0;
282 case PLUGIN_SHAREDMODULE:
283 if(shared_location.module != that->shared_location.module) return 0;
287 // Test remaining fields
288 return (this->on == that->on &&
289 ((KeyFrame*)keyframes->default_auto)->identical(
290 ((KeyFrame*)that->keyframes->default_auto)));
293 int Plugin::identical_location(Plugin *that)
295 if(!plugin_set || !plugin_set->track) return 0;
296 if(!that->plugin_set || !that->plugin_set->track) return 0;
298 if(plugin_set->track->number_of() == that->plugin_set->track->number_of() &&
299 plugin_set->get_number() == that->plugin_set->get_number() &&
300 startproject == that->startproject) return 1;
306 int Plugin::keyframe_exists(KeyFrame *ptr)
308 for(KeyFrame *current = (KeyFrame*)keyframes->first;
310 current = (KeyFrame*)NEXT)
312 if(current == ptr) return 1;
318 void Plugin::change_plugin(char *title,
319 SharedLocation *shared_location,
322 strcpy(this->title, title);
323 this->shared_location = *shared_location;
324 this->plugin_type = plugin_type;
329 KeyFrame* Plugin::get_prev_keyframe(int64_t position,
332 return keyframes->get_prev_keyframe(position, direction);
335 KeyFrame* Plugin::get_next_keyframe(int64_t position,
340 // This doesn't work for playback because edl->selectionstart doesn't
341 // change during playback at the same rate as PluginClient::source_position.
344 //printf("Plugin::get_next_keyframe position < 0\n");
345 position = track->to_units(edl->local_session->get_selectionstart(1), 0);
348 // Get keyframe after current position
349 for(current = (KeyFrame*)keyframes->first;
351 current = (KeyFrame*)NEXT)
353 if(direction == PLAY_FORWARD && current->position > position) break;
355 if(direction == PLAY_REVERSE && current->position >= position) break;
358 // Nothing after current position
359 if(!current && keyframes->last)
361 current = (KeyFrame*)keyframes->last;
367 current = (KeyFrame*)keyframes->default_auto;
373 KeyFrame* Plugin::get_keyframe()
375 return keyframes->get_keyframe();
378 void Plugin::copy(int64_t start, int64_t end, FileXML *file)
380 int64_t endproject = startproject + length;
382 if((startproject >= start && startproject <= end) || // startproject in range
383 (endproject <= end && endproject >= start) || // endproject in range
384 (startproject <= start && endproject >= end)) // range in project
387 int64_t startproject_in_selection = startproject; // start of edit in selection in project
388 int64_t startsource_in_selection = startsource; // start of source in selection in source
389 //int64_t endsource_in_selection = startsource + length; // end of source in selection
390 int64_t length_in_selection = length; // length of edit in selection
392 if(startproject < start)
393 { // start is after start of edit in project
394 int64_t length_difference = start - startproject;
396 startsource_in_selection += length_difference;
397 startproject_in_selection += length_difference;
398 length_in_selection -= length_difference;
401 // end is before end of edit in project
404 length_in_selection = end - startproject_in_selection;
407 // Plugins don't store silence
408 file->tag.set_title("PLUGIN");
409 // file->tag.set_property("STARTPROJECT", startproject_in_selection - start);
410 file->tag.set_property("LENGTH", length_in_selection);
411 file->tag.set_property("TYPE", plugin_type);
412 file->tag.set_property("TITLE", title);
414 file->append_newline();
417 if(plugin_type == PLUGIN_SHAREDPLUGIN ||
418 plugin_type == PLUGIN_SHAREDMODULE)
420 shared_location.save(file);
427 file->tag.set_title("IN");
432 file->tag.set_title("OUT");
437 file->tag.set_title("SHOW");
442 file->tag.set_title("ON");
445 file->append_newline();
448 keyframes->copy(start, end, file, 0, 0);
450 file->tag.set_title("/PLUGIN");
452 file->append_newline();
456 void Plugin::load(FileXML *file)
459 int first_keyframe = 1;
462 // Currently show is ignored when loading
465 while(keyframes->last) delete keyframes->last;
468 result = file->read_tag();
470 //printf("Plugin::load 1 %s\n", file->tag.get_title());
473 if(file->tag.title_is("/PLUGIN"))
478 if(file->tag.title_is("SHARED_LOCATION"))
480 shared_location.load(file);
483 if(file->tag.title_is("IN"))
488 if(file->tag.title_is("OUT"))
493 if(file->tag.title_is("SHOW"))
498 if(file->tag.title_is("ON"))
503 if(file->tag.title_is("KEYFRAME"))
508 keyframes->default_auto->load(file);
512 // Override default keyframe
514 KeyFrame *keyframe = (KeyFrame*)keyframes->append(new KeyFrame(edl, keyframes));
515 keyframe->position = file->tag.get_property("POSITION", (int64_t)0);
516 keyframe->load(file);
523 void Plugin::get_shared_location(SharedLocation *result)
525 if(plugin_type == PLUGIN_STANDALONE && plugin_set)
527 result->module = edl->tracks->number_of(track);
528 result->plugin = track->plugin_set.number_of(plugin_set);
532 *result = this->shared_location;
536 Track* Plugin::get_shared_track()
538 return edl->tracks->get_item_number(shared_location.module);
542 void Plugin::calculate_title(char *string, int use_nudge)
544 if(plugin_type == PLUGIN_STANDALONE || plugin_type == PLUGIN_NONE)
546 strcpy(string, _(title));
549 if(plugin_type == PLUGIN_SHAREDPLUGIN || plugin_type == PLUGIN_SHAREDMODULE)
551 shared_location.calculate_title(string,
561 void Plugin::paste(FileXML *file)
563 length = file->tag.get_property("LENGTH", (int64_t)0);
566 void Plugin::resample(double old_rate, double new_rate)
568 // Resample keyframes in here
569 keyframes->resample(old_rate, new_rate);
572 void Plugin::shift(int64_t difference)
574 Edit::shift(difference);
576 if(edl->session->autos_follow_edits)
577 shift_keyframes(difference);
580 void Plugin::dump(FILE *fp)
582 fprintf(fp," PLUGIN: type=%d title=\"%s\" on=%d track=%d plugin=%d\n",
586 shared_location.module,
587 shared_location.plugin);
588 fprintf(fp," startproject " _LD " length " _LD "\n", startproject, length);