5 #include "audiodevice.h"
12 #include "edlsession.h"
13 #include "levelwindow.h"
14 #include "mainsession.h"
15 #include "playabletracks.h"
16 #include "playbackengine.h"
17 #include "preferences.h"
18 #include "renderengine.h"
20 #include "transportque.h"
21 #include "virtualaconsole.h"
22 #include "virtualconsole.h"
23 #include "virtualnode.h"
25 ARender::ARender(RenderEngine *renderengine)
26 : CommonRender(renderengine)
28 // Clear output buffers
29 for(int i = 0; i < MAXCHANNELS; i++)
37 data_type = TRACK_AUDIO;
42 for(int i = 0; i < MAXCHANNELS; i++)
44 if(audio_out[i]) delete [] audio_out[i];
45 if(level_history[i]) delete [] level_history[i];
47 if(level_samples) delete [] level_samples;
50 void ARender::arm_command()
52 // Need the meter history now so AModule can allocate its own history
53 calculate_history_size();
54 CommonRender::arm_command();
60 int ARender::get_total_tracks()
62 return renderengine->edl->tracks->total_audio_tracks();
65 Module* ARender::new_module(Track *track)
67 return new AModule(renderengine, this, 0, track);
70 int ARender::calculate_history_size()
76 meter_render_fragment = renderengine->fragment_len;
77 // This number and the timer in tracking.C determine the rate
78 while(meter_render_fragment >
79 renderengine->edl->session->sample_rate / TRACKING_RATE)
80 meter_render_fragment /= 2;
82 renderengine->fragment_len /
83 meter_render_fragment;
88 int ARender::init_meters()
90 // not providing enough peaks results in peaks that are ahead of the sound
91 if(level_samples) delete [] level_samples;
92 calculate_history_size();
93 level_samples = new int64_t[total_peaks];
94 for(int i = 0; i < MAXCHANNELS;i++)
97 if(audio_out[i] && !level_history[i]) level_history[i] = new double[total_peaks];
100 for(int i = 0; i < total_peaks; i++)
102 level_samples[i] = -1;
105 for(int j = 0; j < MAXCHANNELS; j++)
108 for(int i = 0; i < total_peaks; i++)
109 level_history[j][i] = 0;
114 void ARender::init_output_buffers()
116 if(renderengine->command->realtime)
118 for(int i = 0; i < MAXCHANNELS; i++)
120 // Reset the output buffers in case speed changed
123 delete [] audio_out[i];
127 if(renderengine->config->aconfig->do_channel[i])
129 audio_out[i] = new double[renderengine->adjusted_fragment_len];
136 VirtualConsole* ARender::new_vconsole_object()
138 return new VirtualAConsole(renderengine, this);
141 int64_t ARender::tounits(double position, int round)
144 return Units::round(position * renderengine->edl->session->sample_rate);
146 return (int64_t)(position * renderengine->edl->session->sample_rate);
149 double ARender::fromunits(int64_t position)
151 return (double)position / renderengine->edl->session->sample_rate;
155 int ARender::process_buffer(double **buffer_out,
157 int64_t input_position,
162 this->last_playback = last_buffer;
163 int64_t fragment_position = 0;
164 int64_t fragment_len = input_len;
166 current_position = input_position;
168 while(fragment_position < input_len)
170 for(int i = 0; i < MAXCHANNELS; i++)
173 this->audio_out[i] = buffer_out[i] + fragment_position;
175 this->audio_out[i] = 0;
178 fragment_len = input_len;
179 if(fragment_position + fragment_len > input_len)
180 fragment_len = input_len - fragment_position;
182 reconfigure = vconsole->test_reconfigure(input_position,
186 //printf("ARender::process_buffer 1 %lld %d\n", input_position, reconfigure);
188 if(reconfigure) restart_playback();
190 result = process_buffer(fragment_len, input_position);
192 fragment_position += fragment_len;
193 input_position += fragment_len;
194 current_position = input_position;
197 // Don't delete audio_out on completion
198 bzero(this->audio_out, sizeof(double*) * MAXCHANNELS);
207 int ARender::process_buffer(int64_t input_len, int64_t input_position)
209 int result = ((VirtualAConsole*)vconsole)->process_buffer(input_len,
217 session_position += input_len;
221 // int ARender::restart_playback()
223 // // Use for rebuilding the virtual console during playback.
224 // // Send last buffer to old thread.
227 // send_reconfigure_buffer();
228 // vconsole->wait_for_completion();
231 // CommonRender::restart_playback();
235 int ARender::get_history_number(int64_t *table, int64_t position)
237 // Get the entry closest to position
239 int64_t min_difference = 0x7fffffff;
240 for(int i = 0; i < total_peaks; i++)
242 //printf("%d %d ", i, table[i]);
243 if(labs(table[i] - position) < min_difference)
246 min_difference = labs(table[i] - position);
251 //printf("ARender::get_history_number %ld %d %d\n", position, result, min_difference);
255 void ARender::send_last_buffer()
257 renderengine->audio->set_last_buffer();
260 int ARender::wait_device_completion()
262 // audio device should be entirely cleaned up by vconsole
263 renderengine->audio->wait_for_completion();
269 int64_t current_input_length;
274 start_lock->unlock();
275 //printf("ARender::run 1 %d\n", Thread::calculate_realtime());
277 while(!done && !interrupt && !last_playback)
279 current_input_length = renderengine->fragment_len;
281 get_boundaries(current_input_length);
283 //printf("ARender::run 10 %lld %lld\n", current_position, current_input_length);
284 if(current_input_length)
286 reconfigure = vconsole->test_reconfigure(current_position,
287 current_input_length,
289 if(reconfigure) restart_playback();
291 //printf("ARender::run 20 %lld %lld\n", current_position, current_input_length);
294 // Update tracking if no video is playing.
295 if(renderengine->command->realtime &&
296 renderengine->playback_engine &&
297 !renderengine->do_video)
299 double position = (double)renderengine->audio->current_position() /
300 renderengine->edl->session->sample_rate *
301 renderengine->command->get_speed();
303 if(renderengine->command->get_direction() == PLAY_FORWARD)
304 position += renderengine->command->playbackstart;
306 position = renderengine->command->playbackstart - position;
308 // This number is not compensated for looping. It's compensated in
309 // PlaybackEngine::get_tracking_position when interpolation also happens.
310 renderengine->playback_engine->update_tracking(position);
315 //printf("ARender::run 30 %lld\n", current_input_length);
319 process_buffer(current_input_length, current_position);
320 //printf("ARender::run 40\n");
323 advance_position(get_render_length(current_input_length));
324 //printf("ARender::run 50\n");
327 if(vconsole->interrupt) interrupt = 1;
330 if(!interrupt) send_last_buffer();
331 if(renderengine->command->realtime) wait_device_completion();
332 vconsole->stop_rendering(0);
352 int ARender::get_datatype()
357 int ARender::arm_playback(int64_t current_position,
358 int64_t input_length,
359 int64_t amodule_render_fragment,
360 int64_t playback_buffer,
361 int64_t output_length)
363 this->current_position = current_position;
364 this->input_length = input_length;
365 session_position = 0;
367 source_length = renderengine->end_position - renderengine->start_position;
370 if(renderengine->command->realtime)
372 Thread::set_realtime(renderengine->edl->session->real_time_playback);
377 // start reading input and sending to arenderthread
378 // only if there's an audio device
379 if(renderengine->command->realtime)
387 // int ARender::send_reconfigure_buffer()
389 // if(renderengine->command->realtime)
391 // vconsole->output_lock[vconsole->current_input_buffer]->lock("ARender::send_reconfigure_buffer");
393 // vconsole->input_len[vconsole->current_input_buffer] = 0;
394 // vconsole->input_position[vconsole->current_input_buffer] = 0;
395 // vconsole->last_playback[vconsole->current_input_buffer] = 0;
396 // vconsole->last_reconfigure[vconsole->current_input_buffer] = 1;
398 // vconsole->input_lock[vconsole->current_input_buffer]->unlock();
399 // vconsole->swap_input_buffer();
404 int ARender::reverse_buffer(double *buffer, int64_t len)
406 register int64_t start, end;
409 for(start = 0, end = len - 1; end > start; start++, end--)
411 temp = buffer[start];
412 buffer[start] = buffer[end];
417 int ARender::get_next_peak(int current_peak)
420 if(current_peak >= total_peaks) current_peak = 0;
424 int64_t ARender::get_render_length(int64_t current_render_length)
426 return current_render_length;