1 #include "attachmentpoint.h"
3 #include "automation.h"
6 #include "floatautos.h"
15 #include "pluginserver.h"
16 #include "renderengine.h"
18 #include "transition.h"
19 #include "transportque.h"
20 #include "virtualconsole.h"
21 #include "virtualnode.h"
23 VirtualNode::VirtualNode(RenderEngine *renderengine,
24 VirtualConsole *vconsole,
28 VirtualNode *parent_module,
34 this->renderengine = renderengine;
35 this->vconsole = vconsole;
36 this->real_module = real_module;
37 this->real_plugin = real_plugin;
39 this->parent_module = parent_module;
40 this->ring_buffers = vconsole->total_ring_buffers();
41 this->input_is_master = input_is_master;
42 this->output_is_master = output_is_master;
49 waiting_real_plugin = 0;
50 plugin_buffer_number = 0;
52 plugin_auto_before = plugin_auto_after = 0;
54 //printf("VirtualNode::VirtualNode 1\n");
57 VirtualNode::~VirtualNode()
59 vplugins.remove_all_objects();
60 //printf("VirtualNode::VirtualNode 2\n");
63 #define PRINT_INDENT for(int j = 0; j < indent; j++) printf(" ");
65 void VirtualNode::dump(int indent)
68 printf("VirtualNode title=%s\n", track->title);
72 printf(" Plugins total=%d\n", vplugins.total);
73 for(int i = 0; i < vplugins.total; i++)
75 vplugins.values[i]->dump(indent + 2);
81 printf(" Plugin %s\n", real_plugin->title);
85 int VirtualNode::expand(int persistant_plugins, int64_t current_position)
89 //printf("VirtualNode::expand 1 %p\n", this);
90 // module needs to know where the input data for the next process is
94 //printf("VirtualNode::expand 3\n");
95 expand_as_module(persistant_plugins, current_position);
96 //printf("VirtualNode::expand 4\n");
101 // attach to a real plugin for a plugin
102 // plugin always takes data from input to output
103 //printf("VirtualNode::expand 5\n");
104 expand_as_plugin(persistant_plugins);
106 //printf("VirtualNode::expand 6\n");
111 int VirtualNode::expand_buffers()
113 // temp needed for the output
118 output_is_master = 0;
121 // temp needed for the output
132 int VirtualNode::expand_as_module(int duplicate, int64_t current_position)
134 Transition *transition = 0;
136 // create the plugins for this module
137 for(int i = 0; i < track->plugin_set.total; i++)
139 Plugin *plugin = track->get_current_plugin(current_position,
141 renderengine->command->get_direction(),
144 // printf("VirtualNode::expand_as_module 1 %d %d %p %p\n",
146 // track->plugin_set.total,
150 // Switch off if circular reference. This happens if a plugin set or a track is deleted.
151 if(plugin == real_plugin) continue;
154 //printf("VirtualNode::expand_as_module 2 %d %p\n", i, plugin);
159 int plugin_type = plugin->plugin_type;
160 if(plugin_type == PLUGIN_SHAREDMODULE)
162 // plugin is a module
163 //printf("VirtualNode::expand_as_module 3\n");
164 attach_virtual_module(plugin,
168 //printf("VirtualNode::expand_as_module 4\n");
171 if(plugin_type == PLUGIN_SHAREDPLUGIN ||
172 plugin_type == PLUGIN_STANDALONE)
174 // plugin is a plugin
175 //printf("VirtualNode::expand_as_module 5\n");
176 attach_virtual_plugin(plugin,
180 //printf("VirtualNode::expand_as_module 6\n");
184 //printf("VirtualNode::expand_as_module 7\n");
189 int VirtualNode::expand_as_plugin(int duplicate)
191 plugin_type = real_plugin->plugin_type;
193 if(plugin_type == PLUGIN_SHAREDPLUGIN)
195 // Attached to a shared plugin.
196 // Get the real real plugin it's attached to.
198 // Redirect the real_plugin to the shared plugin.
199 int real_module_number = real_plugin->shared_location.module;
200 int real_plugin_number = real_plugin->shared_location.plugin;
201 Module *real_module = 0;
204 real_module = vconsole->module_number(real_module_number);
205 // module references are absolute so may get the wrong data type track.
207 real_plugin_number < real_module->total_attachments)
209 attachment = real_module->attachments[real_plugin_number];
210 // Attachment is NULL if off
213 real_plugin = attachment->plugin;
215 // Real plugin not on then null it.
216 if(!real_plugin->on) real_plugin = 0;
230 if(plugin_type == PLUGIN_STANDALONE)
233 Module *module = vconsole->module_of(track);
235 attachment = module->attachment_of(real_plugin);
236 //printf("VirtualNode::expand_as_plugin 1 %p %p\n", attachment, real_plugin);
244 // Add to real plugin's list of virtual plugins for configuration updates
245 // and plugin_server initializations.
246 // Input and output are taken care of when the parent module creates this plugin.
247 // Get number for passing to render.
248 // real_plugin may become NULL after shared plugin test.
249 if(real_plugin && attachment)
253 plugin_buffer_number = attachment->attach_virtual_plugin(this);
262 int VirtualNode::attach_virtual_module(Plugin *plugin,
265 int64_t current_position)
269 //printf("VirtualNode::attach_virtual_module 1 %p\n", plugin);
270 int real_module_number = plugin->shared_location.module;
271 //printf("VirtualNode::attach_virtual_module 1\n");
272 Module *real_module = vconsole->module_number(real_module_number);
273 //printf("VirtualNode::attach_virtual_module 1\n");
274 Track *track = real_module->track;
276 // Switch off if circular reference. This happens if a track is deleted.
277 if(track == this->real_module->track) return 1;
282 // working data is now in output
283 if(plugin->out) data_in_input = 0;
284 //printf("VirtualNode::attach_virtual_module 1\n");
285 VirtualNode *virtual_module = create_module(plugin,
288 //printf("VirtualNode::attach_virtual_module 1\n");
290 vplugins.append(virtual_module);
291 //printf("VirtualNode::attach_virtual_module 1\n");
292 virtual_module->expand(duplicate, current_position);
293 //printf("VirtualNode::attach_virtual_module 2\n");
299 int VirtualNode::attach_virtual_plugin(Plugin *plugin,
302 int64_t current_position)
306 // working data is now in output
307 if(plugin->out) data_in_input = 0;
309 VirtualNode *virtual_plugin = create_plugin(plugin);
310 vplugins.append(virtual_plugin);
311 virtual_plugin->expand(duplicate, current_position);
316 int VirtualNode::sort(ArrayList<VirtualNode*>*render_list)
318 int result = 0, total_result = 0;
321 //printf("VirtualNode::sort %p %p\n", real_module, real_plugin);
324 sort_as_module(render_list, result, total_result);
329 sort_as_plugin(render_list, result, total_result);
332 if(!result && total_result) result = total_result;
333 // if a plugin that wasn't patched out couldn't be rendered, try again
338 int VirtualNode::sort_as_module(ArrayList<VirtualNode*>*render_list, int &result, int &total_result)
341 // Render plugins first.
342 for(int i = 0; i < vplugins.total && !result; i++)
344 // stop when rendering can't continue without another higher level module
345 result = vplugins.values[i]->sort(render_list);
347 if(result && !vplugins.values[i]->out)
351 // couldn't render the last plugin but it wasn't patched out so continue to next plugin
354 //printf("VirtualNode::sort_as_module 3\n");
356 // All plugins rendered.
357 // Render this module.
358 if(render_count == 0 && !result)
360 render_list->append(this);
364 //printf("VirtualNode::sort_as_module 4\n");
368 int VirtualNode::sort_as_plugin(ArrayList<VirtualNode*>*render_list,
372 // Plugin server does not exist at this point.
373 // need to know if plugin requires all inputs to be armed before rendering
374 //printf("VirtualNode::sort_as_plugin 1\n");
375 int multichannel = 0, singlechannel = 0;
379 // Referenced plugin is off
380 if(!attachment) return 0;
382 //printf("VirtualNode::sort_as_plugin 2 %p\n", attachment);
383 if(plugin_type == PLUGIN_STANDALONE || plugin_type == PLUGIN_SHAREDPLUGIN)
385 multichannel = attachment->multichannel_shared(1);
386 singlechannel = attachment->singlechannel();
389 //printf("VirtualNode::sort_as_plugin 3\n");
390 if(plugin_type == PLUGIN_STANDALONE && !multichannel)
392 // unshared single channel plugin
394 //printf("VirtualNode::sort_as_plugin 4\n");
397 render_list->append(this);
401 //printf("VirtualNode::sort_as_plugin 5\n");
404 if(plugin_type == PLUGIN_SHAREDPLUGIN || multichannel)
408 //printf("VirtualNode::sort_as_plugin 6\n");
413 // shared single channel plugin
415 //printf("VirtualNode::sort_as_plugin 7\n");
416 render_list->append(this);
417 //printf("VirtualNode::sort_as_plugin 8\n");
423 // shared multichannel plugin
424 // all buffers must be armed before rendering at the same time
425 if(!waiting_real_plugin)
427 //printf("VirtualNode::sort_as_plugin 9 %p\n", attachment);
428 waiting_real_plugin = 1;
430 result = attachment->sort(this);
431 //printf("VirtualNode::sort_as_plugin 10\n");
433 render_list->append(this);
434 //printf("VirtualNode::sort_as_plugin 11\n");
439 // Assume it was rendered later in the first pass
445 //printf("VirtualNode::sort_as_plugin 12\n");
449 int VirtualNode::get_plugin_input(int &ring_buffer_in, int64_t &fragment_position_in,
450 int &ring_buffer_out, int64_t &fragment_position_out,
451 int ring_buffer, int64_t fragment_position)
455 ring_buffer_in = ring_buffer;
456 fragment_position_in = fragment_position;
461 fragment_position_in = 0;
466 ring_buffer_out = ring_buffer;
467 fragment_position_out = fragment_position;
472 fragment_position_out = 0;
476 int VirtualNode::render_as_plugin(int64_t source_len,
477 int64_t source_position,
479 int64_t fragment_position,
480 int64_t fragment_len)
482 // need numbers for actual buffers
483 int direction = renderengine->command->get_direction();
484 int ring_buffer_in, ring_buffer_out;
485 int64_t fragment_position_in, fragment_position_out;
486 int multichannel = 0;
487 //printf("VirtualNode::render_as_plugin 1 %p\n", attachment);
489 // Abort if no plugin
492 !real_plugin->on) return 0;
494 //printf("VirtualNode::render_as_plugin 2\n");
499 void VirtualNode::get_mute_fragment(int64_t input_position,
501 int64_t &fragment_len,
505 int direction = renderengine->command->get_direction();
507 IntAuto *prev_keyframe = 0;
508 IntAuto *next_keyframe = 0;
509 prev_keyframe = (IntAuto*)autos->get_prev_auto(input_position, direction, (Auto*)prev_keyframe);
510 next_keyframe = (IntAuto*)autos->get_next_auto(input_position, direction, (Auto*)next_keyframe);
512 if(direction == PLAY_FORWARD)
514 // Two distinct keyframes within range
515 if(next_keyframe->position > prev_keyframe->position)
517 mute_constant = prev_keyframe->value;
519 if(next_keyframe->position < input_position + fragment_len)
520 fragment_len = next_keyframe->position - input_position;
523 // One keyframe within range
525 mute_constant = prev_keyframe->value;
530 // Two distinct keyframes within range
531 if(next_keyframe->position < prev_keyframe->position)
533 mute_constant = next_keyframe->value;
535 if(next_keyframe->position > input_position - fragment_len)
536 fragment_len = input_position - next_keyframe->position;
539 // One keyframe within range
541 mute_constant = next_keyframe->value;
548 void VirtualNode::get_fade_automation(double &slope,
550 int64_t input_position,
554 int direction = renderengine->command->get_direction();
555 ((FloatAutos*)autos)->get_fade_automation(slope,
562 void VirtualNode::get_pan_automation(double &slope,
564 int64_t input_position,
569 int direction = renderengine->command->get_direction();
573 PanAuto *prev_keyframe = 0;
574 PanAuto *next_keyframe = 0;
575 prev_keyframe = (PanAuto*)autos->get_prev_auto(input_position, direction, (Auto*)prev_keyframe);
576 next_keyframe = (PanAuto*)autos->get_next_auto(input_position, direction, (Auto*)next_keyframe);
578 if(direction == PLAY_FORWARD)
580 // Two distinct automation points within range
581 if(next_keyframe->position > prev_keyframe->position)
583 slope = ((double)next_keyframe->values[channel] - prev_keyframe->values[channel]) /
584 ((double)next_keyframe->position - prev_keyframe->position);
585 intercept = ((double)input_position - prev_keyframe->position) * slope +
586 prev_keyframe->values[channel];
588 if(next_keyframe->position < input_position + slope_len)
589 slope_len = next_keyframe->position - input_position;
592 // One automation point within range
595 intercept = prev_keyframe->values[channel];
600 // Two distinct automation points within range
601 if(next_keyframe->position < prev_keyframe->position)
603 slope = ((double)next_keyframe->values[channel] - prev_keyframe->values[channel]) /
604 ((double)next_keyframe->position - prev_keyframe->position);
605 intercept = ((double)input_position - prev_keyframe->position) * slope +
606 prev_keyframe->values[channel];
608 if(next_keyframe->position > input_position - slope_len)
609 slope_len = input_position - next_keyframe->position;
612 // One automation point within range
615 intercept = next_keyframe->values[channel];
621 int VirtualNode::init_automation(int &automate,
623 int64_t input_position,
631 return autos->init_automation(buffer_position,
643 int VirtualNode::init_slope(Autos *autos, Auto **before, Auto **after)
645 return autos->init_slope(¤t_auto,
656 int VirtualNode::get_slope(Autos *autos, int64_t buffer_len, int64_t buffer_position)
658 return autos->get_slope(¤t_auto,
668 int VirtualNode::advance_slope(Autos *autos)
670 return autos->advance_slope(¤t_auto,