00001 #include "aattachmentpoint.h"
00002 #include "amodule.h"
00003 #include "arender.h"
00004 #include "atrack.h"
00005 #include "automation.h"
00006 #include "edl.h"
00007 #include "edlsession.h"
00008 #include "clip.h"
00009 #include "floatautos.h"
00010 #include "mwindow.h"
00011 #include "module.h"
00012 #include "panauto.h"
00013 #include "plugin.h"
00014 #include "renderengine.h"
00015 #include "track.h"
00016 #include "transition.h"
00017 #include "transportque.h"
00018 #include "virtualaconsole.h"
00019 #include "virtualanode.h"
00020
00021
00022 #include <string.h>
00023
00024 VirtualANode::VirtualANode(RenderEngine *renderengine,
00025 VirtualConsole *vconsole,
00026 Module *real_module,
00027 Plugin *real_plugin,
00028 Track *track,
00029 VirtualNode *parent_module)
00030 : VirtualNode(renderengine,
00031 vconsole,
00032 real_module,
00033 real_plugin,
00034 track,
00035 parent_module)
00036 {
00037 for(int i = 0; i < MAXCHANNELS; i++)
00038 {
00039 pan_before[i] = pan_after[i] = 0;
00040 }
00041 }
00042
00043 VirtualANode::~VirtualANode()
00044 {
00045 }
00046
00047
00048
00049
00050
00051 VirtualNode* VirtualANode::create_module(Plugin *real_plugin,
00052 Module *real_module,
00053 Track *track)
00054 {
00055 return new VirtualANode(renderengine,
00056 vconsole,
00057 real_module,
00058 0,
00059 track,
00060 this);
00061 }
00062
00063
00064 VirtualNode* VirtualANode::create_plugin(Plugin *real_plugin)
00065 {
00066 return new VirtualANode(renderengine,
00067 vconsole,
00068 0,
00069 real_plugin,
00070 track,
00071 this);
00072 }
00073
00074
00075
00076 int VirtualANode::read_data(double *output_temp,
00077 int64_t start_position,
00078 int64_t len,
00079 int64_t sample_rate)
00080 {
00081 VirtualNode *previous_plugin = 0;
00082
00083
00084
00085 if(parent_node &&
00086 (previous_plugin = parent_node->get_previous_plugin(this)))
00087 {
00088 ((VirtualANode*)previous_plugin)->render(output_temp,
00089 start_position,
00090 len,
00091 sample_rate);
00092 }
00093 else
00094
00095
00096 if(parent_node)
00097 {
00098 ((VirtualANode*)parent_node)->read_data(output_temp,
00099 start_position,
00100 len,
00101 sample_rate);
00102 }
00103 else
00104
00105 {
00106 ((AModule*)real_module)->render(output_temp,
00107 start_position,
00108 len,
00109 renderengine->command->get_direction(),
00110 sample_rate,
00111 0);
00112 }
00113 return 0;
00114 }
00115
00116 int VirtualANode::render(double *output_temp,
00117 int64_t start_position,
00118 int64_t len,
00119 int64_t sample_rate)
00120 {
00121 ARender *arender = ((VirtualAConsole*)vconsole)->arender;
00122 if(real_module)
00123 {
00124 render_as_module(arender->audio_out,
00125 output_temp,
00126 start_position,
00127 len,
00128 sample_rate);
00129 }
00130 else
00131 if(real_plugin)
00132 {
00133 render_as_plugin(output_temp,
00134 start_position,
00135 len,
00136 sample_rate);
00137 }
00138 return 0;
00139 }
00140
00141 void VirtualANode::render_as_plugin(double *output_temp,
00142 int64_t start_position,
00143 int64_t len,
00144 int64_t sample_rate)
00145 {
00146 if(!attachment ||
00147 !real_plugin ||
00148 !real_plugin->on) return;
00149
00150
00151
00152
00153 ((AAttachmentPoint*)attachment)->render(
00154 output_temp,
00155 plugin_buffer_number,
00156 start_position,
00157 len,
00158 sample_rate);
00159 }
00160
00161 int VirtualANode::render_as_module(double **audio_out,
00162 double *output_temp,
00163 int64_t start_position,
00164 int64_t len,
00165 int64_t sample_rate)
00166 {
00167 int in_output = 0;
00168 int direction = renderengine->command->get_direction();
00169 EDL *edl = vconsole->renderengine->edl;
00170
00171
00172
00173
00174 if(subnodes.total)
00175 {
00176 VirtualANode *node = (VirtualANode*)subnodes.values[subnodes.total - 1];
00177 node->render(output_temp,
00178 start_position,
00179 len,
00180 sample_rate);
00181 }
00182 else
00183
00184 {
00185 read_data(output_temp,
00186 start_position,
00187 len,
00188 sample_rate);
00189 }
00190
00191
00192 render_fade(output_temp,
00193 len,
00194 start_position,
00195 sample_rate,
00196 track->automation->autos[AUTOMATION_FADE],
00197 direction,
00198 0);
00199
00200
00201
00202 int64_t project_sample_rate = edl->session->sample_rate;
00203 int64_t start_position_project = start_position *
00204 project_sample_rate /
00205 sample_rate;
00206 if(real_module && renderengine->command->realtime)
00207 {
00208 ARender *arender = ((VirtualAConsole*)vconsole)->arender;
00209
00210 int64_t meter_render_start;
00211
00212 int64_t meter_render_end;
00213
00214 int meter_render_fragment = arender->meter_render_fragment *
00215 sample_rate /
00216 project_sample_rate;
00217
00218
00219
00220 for(int i = 0; i < len; )
00221 {
00222 int current_level = ((AModule*)real_module)->current_level;
00223 double peak = 0;
00224 meter_render_start = i;
00225 meter_render_end = i + meter_render_fragment;
00226 if(meter_render_end > len)
00227 meter_render_end = len;
00228
00229
00230 int64_t meter_render_start_project = meter_render_start *
00231 project_sample_rate /
00232 sample_rate;
00233
00234
00235 for( ; i < meter_render_end; i++)
00236 {
00237 double sample = fabs(output_temp[i]);
00238 if(sample > peak) peak = sample;
00239 }
00240
00241 ((AModule*)real_module)->level_history[current_level] =
00242 peak;
00243 ((AModule*)real_module)->level_samples[current_level] =
00244 (direction == PLAY_FORWARD) ?
00245 (start_position_project + meter_render_start_project) :
00246 (start_position_project - meter_render_start_project);
00247 ((AModule*)real_module)->current_level =
00248 arender->get_next_peak(current_level);
00249 }
00250 }
00251
00252
00253
00254 int mute_position = 0;
00255
00256 for(int i = 0; i < len; )
00257 {
00258 int mute_constant;
00259 int mute_fragment = len - i;
00260 int mute_fragment_project = mute_fragment *
00261 project_sample_rate /
00262 sample_rate;
00263 start_position_project = start_position +
00264 ((direction == PLAY_FORWARD) ? i : -i);
00265 start_position_project = start_position_project *
00266 project_sample_rate /
00267 sample_rate;
00268
00269
00270 get_mute_fragment(start_position_project,
00271 mute_constant,
00272 mute_fragment_project,
00273 (Autos*)track->automation->autos[AUTOMATION_MUTE],
00274 direction,
00275 0);
00276
00277 if(!mute_constant)
00278 {
00279 for(int j = 0;
00280 j < MAX_CHANNELS;
00281 j++)
00282 {
00283 if(audio_out[j])
00284 {
00285 double *buffer = audio_out[j];
00286
00287 render_pan(output_temp + mute_position,
00288 buffer + mute_position,
00289 mute_fragment,
00290 start_position,
00291 sample_rate,
00292 (Autos*)track->automation->autos[AUTOMATION_PAN],
00293 j,
00294 direction,
00295 0);
00296 }
00297 }
00298 }
00299
00300 len -= mute_fragment;
00301 i += mute_fragment;
00302 mute_position += mute_fragment;
00303 }
00304
00305 return 0;
00306 }
00307
00308 int VirtualANode::render_fade(double *buffer,
00309 int64_t len,
00310 int64_t input_position,
00311 int64_t sample_rate,
00312 Autos *autos,
00313 int direction,
00314 int use_nudge)
00315 {
00316 double value, fade_value;
00317 FloatAuto *previous = 0;
00318 FloatAuto *next = 0;
00319 EDL *edl = vconsole->renderengine->edl;
00320 int64_t project_sample_rate = edl->session->sample_rate;
00321 if(use_nudge) input_position += track->nudge *
00322 sample_rate /
00323 project_sample_rate;
00324
00325
00326
00327
00328 int64_t input_position_project = input_position *
00329 project_sample_rate /
00330 sample_rate;
00331 int64_t len_project = len *
00332 project_sample_rate /
00333 sample_rate;
00334
00335 if(((FloatAutos*)autos)->automation_is_constant(input_position_project,
00336 len_project,
00337 direction,
00338 fade_value))
00339 {
00340 if(fade_value <= INFINITYGAIN)
00341 value = 0;
00342 else
00343 value = DB::fromdb(fade_value);
00344 for(int64_t i = 0; i < len; i++)
00345 {
00346 buffer[i] *= value;
00347 }
00348 }
00349 else
00350 {
00351 for(int64_t i = 0; i < len; i++)
00352 {
00353 int64_t slope_len = len - i;
00354 input_position_project = input_position *
00355 project_sample_rate /
00356 sample_rate;
00357
00358 fade_value = ((FloatAutos*)autos)->get_value(input_position_project,
00359 direction,
00360 previous,
00361 next);
00362
00363 if(fade_value <= INFINITYGAIN)
00364 value = 0;
00365 else
00366 value = DB::fromdb(fade_value);
00367
00368 buffer[i] *= value;
00369
00370 if(direction == PLAY_FORWARD)
00371 input_position++;
00372 else
00373 input_position--;
00374 }
00375 }
00376
00377 return 0;
00378 }
00379
00380 int VirtualANode::render_pan(double *input,
00381 double *output,
00382 int64_t fragment_len,
00383 int64_t input_position,
00384 int64_t sample_rate,
00385 Autos *autos,
00386 int channel,
00387 int direction,
00388 int use_nudge)
00389 {
00390 double slope = 0.0;
00391 double intercept = 1.0;
00392 EDL *edl = vconsole->renderengine->edl;
00393 int64_t project_sample_rate = edl->session->sample_rate;
00394 if(use_nudge) input_position += track->nudge *
00395 sample_rate /
00396 project_sample_rate;
00397
00398 for(int i = 0; i < fragment_len; )
00399 {
00400 int64_t slope_len = (fragment_len - i) *
00401 project_sample_rate /
00402 sample_rate;
00403
00404
00405 get_pan_automation(slope,
00406 intercept,
00407 input_position *
00408 project_sample_rate /
00409 sample_rate,
00410 slope_len,
00411 autos,
00412 channel,
00413 direction);
00414
00415 slope_len = slope_len * sample_rate / project_sample_rate;
00416 slope = slope * sample_rate / project_sample_rate;
00417 slope_len = MIN(slope_len, fragment_len - i);
00418
00419
00420 if(!EQUIV(slope, 0))
00421 {
00422 for(double j = 0; j < slope_len; j++, i++)
00423 {
00424 value = slope * j + intercept;
00425 output[i] += input[i] * value;
00426 }
00427 }
00428 else
00429 {
00430 for(int j = 0; j < slope_len; j++, i++)
00431 {
00432 output[i] += input[i] * intercept;
00433 }
00434 }
00435
00436
00437 if(direction == PLAY_FORWARD)
00438 input_position += slope_len;
00439 else
00440 input_position -= slope_len;
00441
00442
00443 }
00444
00445 return 0;
00446 }
00447
00448
00449 void VirtualANode::get_pan_automation(double &slope,
00450 double &intercept,
00451 int64_t input_position,
00452 int64_t &slope_len,
00453 Autos *autos,
00454 int channel,
00455 int direction)
00456 {
00457 intercept = 0;
00458 slope = 0;
00459
00460 PanAuto *prev_keyframe = 0;
00461 PanAuto *next_keyframe = 0;
00462 prev_keyframe = (PanAuto*)autos->get_prev_auto(input_position,
00463 direction,
00464 (Auto* &)prev_keyframe);
00465 next_keyframe = (PanAuto*)autos->get_next_auto(input_position,
00466 direction,
00467 (Auto* &)next_keyframe);
00468
00469 if(direction == PLAY_FORWARD)
00470 {
00471
00472 if(next_keyframe->position > prev_keyframe->position)
00473 {
00474 slope = ((double)next_keyframe->values[channel] - prev_keyframe->values[channel]) /
00475 ((double)next_keyframe->position - prev_keyframe->position);
00476 intercept = ((double)input_position - prev_keyframe->position) * slope +
00477 prev_keyframe->values[channel];
00478
00479 if(next_keyframe->position < input_position + slope_len)
00480 slope_len = next_keyframe->position - input_position;
00481 }
00482 else
00483
00484 {
00485 slope = 0;
00486 intercept = prev_keyframe->values[channel];
00487 }
00488 }
00489 else
00490 {
00491
00492 if(next_keyframe->position < prev_keyframe->position)
00493 {
00494 slope = ((double)next_keyframe->values[channel] - prev_keyframe->values[channel]) /
00495 ((double)next_keyframe->position - prev_keyframe->position);
00496 intercept = ((double)input_position - prev_keyframe->position) * slope +
00497 prev_keyframe->values[channel];
00498
00499 if(next_keyframe->position > input_position - slope_len)
00500 slope_len = input_position - next_keyframe->position;
00501 }
00502 else
00503
00504 {
00505 slope = 0;
00506 intercept = next_keyframe->values[channel];
00507 }
00508 }
00509 }