1 #include "aattachmentpoint.h"
5 #include "automation.h"
7 #include "edlsession.h"
8 #include "floatautos.h"
12 #include "renderengine.h"
14 #include "transition.h"
15 #include "transportque.h"
16 #include "virtualaconsole.h"
17 #include "virtualanode.h"
22 VirtualANode::VirtualANode(RenderEngine *renderengine,
23 VirtualConsole *vconsole,
27 VirtualNode *parent_module,
34 : VirtualNode(renderengine,
45 for(int i = 0; i < RING_BUFFERS; i++)
47 this->buffer_in[i] = buffer_in[i];
48 this->buffer_out[i] = buffer_out[i];
51 for(int i = 0; i < MAXCHANNELS; i++)
53 pan_before[i] = pan_after[i] = 0;
57 VirtualANode::~VirtualANode()
59 if(!shared_output) delete [] buffer_out[0];
60 if(!shared_input) delete [] buffer_in[0];
70 VirtualNode* VirtualANode::create_module(Plugin *real_plugin,
74 return new VirtualANode(renderengine,
80 data_in_input ? buffer_in : buffer_out,
82 data_in_input ? input_is_master : output_is_master,
89 VirtualNode* VirtualANode::create_plugin(Plugin *real_plugin)
91 return new VirtualANode(renderengine,
97 data_in_input ? buffer_in : buffer_out,
99 data_in_input ? input_is_master : output_is_master,
106 void VirtualANode::new_output_buffer()
108 buffer_out[0] = new double[renderengine->edl->session->audio_module_fragment];
111 void VirtualANode::new_input_buffer()
113 buffer_in[0] = new double[renderengine->edl->session->audio_module_fragment];
116 double* VirtualANode::get_module_input(int ring_buffer, int64_t fragment_offset)
122 result = buffer_in[ring_buffer] + fragment_offset;
124 result = buffer_in[0];
129 result = buffer_out[ring_buffer] + fragment_offset;
131 result = buffer_out[0];
136 double* VirtualANode::get_module_output(int ring_buffer, int64_t fragment_position)
141 result = buffer_out[ring_buffer] + fragment_position;
143 result = buffer_out[0];
148 int VirtualANode::render(double **audio_out,
149 int64_t audio_out_position,
151 int64_t fragment_position,
152 int64_t fragment_len,
153 int64_t real_position,
154 int64_t source_length,
160 render_as_module(audio_out,
171 //printf("VirtualANode::render 1\n");
172 render_as_plugin(real_position,
180 void VirtualANode::render_as_plugin(int64_t real_position,
181 int64_t fragment_position,
182 int64_t fragment_len,
185 //printf("VirtualANode::render_as_plugin 1\n");
186 ((AAttachmentPoint*)attachment)->render(buffer_in[ring_buffer] + fragment_position,
187 buffer_out[ring_buffer] + fragment_position,
192 int VirtualANode::render_as_module(double **audio_out,
193 int64_t audio_out_position,
195 int64_t fragment_position,
196 int64_t fragment_len,
197 int64_t real_position,
201 double *buffer_in = get_module_input(ring_buffer, fragment_position);
202 double *buffer_out = get_module_output(ring_buffer, fragment_position);
203 int direction = renderengine->command->get_direction();
205 //printf("VirtualANode::render_as_module 1 %p\n", this->buffer_in[ring_buffer] + fragment_position);
207 // for(int i = 0; i < fragment_len; i++)
209 // int16_t value = (int16_t)(buffer_in[i] * 32767);
210 // fwrite(&value, 2, 1, stdout);
213 //printf("VirtualANode::render_as_module 1 %d\n", ring_buffer);
215 render_fade(buffer_in,
219 track->automation->fade_autos);
221 // Get the peak but don't limit
222 //printf("VirtualANode::render_as_module 1 %p %d\n", real_module, renderengine->command->realtime);
223 if(real_module && renderengine->command->realtime)
225 ARender *arender = ((VirtualAConsole*)vconsole)->arender;
226 double max = 0, min = 0, peak;
227 int64_t meter_render_start; // Starting sample of meter block
228 int64_t meter_render_end; // Ending sample of meter block
229 int64_t current_level = ((AModule*)real_module)->current_level;
231 //printf("VirtualANode::render_as_module 1 %p %p\n", ((AModule*)real_module), ((AModule*)real_module)->level_samples);
232 // Scan fragment in meter sized fragments
233 for(int i = 0; i < fragment_len; )
235 meter_render_start = i;
236 meter_render_end = i + arender->meter_render_fragment;
237 if(meter_render_end > fragment_len) meter_render_end = fragment_len;
241 for( ; i < meter_render_end; i++)
243 if(buffer_out[i] > max) max = buffer_out[i];
245 if(buffer_out[i] < min) min = buffer_out[i];
248 if(fabs(max) > fabs(min))
253 ((AModule*)real_module)->level_history[current_level] =
255 ((AModule*)real_module)->level_samples[current_level] =
256 (renderengine->command->get_direction() == PLAY_FORWARD) ?
257 (real_position + meter_render_start) :
258 (real_position - meter_render_start);
259 //printf("VirtualANode::render_as_module 2 %d\n", ((AModule*)real_module)->level_samples[current_level]);
260 ((AModule*)real_module)->current_level =
261 arender->get_next_peak(((AModule*)real_module)->current_level);
265 //printf("VirtualANode::render_as_module 1\n");
266 // process pans and copy the output to the output channels
267 // Keep rendering unmuted fragments until finished.
269 int64_t mute_fragment;
270 int64_t mute_position = 0;
272 for(int i = 0; i < fragment_len; )
274 mute_fragment = fragment_len - i;
276 // How many samples until the next mute?
277 get_mute_fragment(real_position,
280 (Autos*)track->automation->mute_autos);
281 //printf("VirtualANode::render_as_module 1\n");
283 // Fragment is playable
290 //printf("VirtualANode::render_as_module %d\n", i);
293 double *buffer = audio_out[i];
295 render_pan(buffer_out + mute_position,
296 buffer + audio_out_position + mute_position,
299 (Autos*)track->automation->pan_autos,
305 fragment_len -= mute_fragment;
306 real_position += (direction == PLAY_REVERSE) ? -mute_fragment : mute_fragment;
307 mute_position += mute_fragment;
309 //printf("VirtualANode::render_as_module 2\n");
313 int VirtualANode::render_fade(double *input, // start of input fragment
314 double *output, // start of output fragment
315 int64_t fragment_len, // fragment length in input scale
316 int64_t input_position, // starting sample of input buffer in project
319 double value, fade_value;
320 int direction = renderengine->command->get_direction();
321 FloatAuto *previous = 0;
325 if(((FloatAutos*)autos)->automation_is_constant(input_position,
330 //printf("VirtualANode::render_fade 1 %d %f\n", input_position, fade_value);
331 if(fade_value <= INFINITYGAIN)
334 value = DB::fromdb(fade_value);
335 for(int64_t i = 0; i < fragment_len; i++)
337 output[i] = input[i] * value;
342 //printf("VirtualANode::render_fade 10 %d\n", input_position);
343 for(int64_t i = 0; i < fragment_len; i++)
345 int64_t slope_len = fragment_len - i;
347 fade_value = ((FloatAutos*)autos)->get_value(input_position,
352 if(fade_value <= INFINITYGAIN)
355 value = DB::fromdb(fade_value);
357 output[i] = input[i] * value;
359 if(direction == PLAY_FORWARD)
367 // Get slope intercept formula for next fragment
368 // get_fade_automation(slope,
380 // value = slope * j + intercept;
381 // value = DB::fromdb(value);
382 // output[i] = input[i] * value;
387 // double value = DB::fromdb(intercept);
392 // output[i] = input[i] * value;
397 // if(direction == PLAY_FORWARD)
398 // input_position += slope_len;
400 // input_position -= slope_len;
406 int VirtualANode::render_pan(double *input, // start of input fragment
407 double *output, // start of output fragment
408 int64_t fragment_len, // fragment length in input scale
409 int64_t input_position, // starting sample of input buffer in project
413 double slope, intercept;
414 int direction = renderengine->command->get_direction();
416 for(int64_t i = 0; i < fragment_len; )
418 int64_t slope_len = fragment_len - i;
420 // Get slope intercept formula for next fragment
421 get_pan_automation(slope,
430 for(double j = 0; j < slope_len; j++, i++)
432 value = slope * j + intercept;
433 output[i] += input[i] * value;
438 for(int j = 0; j < slope_len; j++, i++)
440 output[i] += input[i] * intercept;
445 if(direction == PLAY_FORWARD)
446 input_position += slope_len;
448 input_position -= slope_len;
452 // for(int i = 0; i < fragment_len; i++)
454 // int16_t value = (int16_t)(input[i] * 32767);
455 // fwrite(&value, 2, 1, stdout);