6 #include "audiodevice.h"
11 #include "edlsession.h"
13 #include "levelwindow.h"
14 #include "playabletracks.h"
16 #include "preferences.h"
17 #include "renderengine.h"
20 #include "transportque.h"
21 #include "virtualaconsole.h"
22 #include "virtualanode.h"
23 #include "virtualnode.h"
26 VirtualAConsole::VirtualAConsole(RenderEngine *renderengine, ARender *arender)
27 : VirtualConsole(renderengine, arender, TRACK_AUDIO)
29 this->arender = arender;
32 VirtualAConsole::~VirtualAConsole()
34 //printf("VirtualAConsole::~VirtualAConsole 1\n");
37 int VirtualAConsole::total_ring_buffers()
39 return renderengine->command->realtime ? 2 : 1;
42 void VirtualAConsole::get_playable_tracks()
45 playable_tracks = new PlayableTracks(renderengine,
46 commonrender->current_position,
50 void VirtualAConsole::new_input_buffer(int ring_buffer)
52 buffer_in[ring_buffer] = new double*[total_tracks];
53 for(int i = 0; i < total_tracks; i++)
55 buffer_in[ring_buffer][i] = new double[renderengine->edl->session->audio_read_length];
59 void VirtualAConsole::delete_input_buffer(int ring_buffer)
61 for(int i = 0; i < total_tracks; i++)
63 delete [] buffer_in[ring_buffer][i];
65 delete [] buffer_in[ring_buffer];
68 VirtualNode* VirtualAConsole::new_toplevel_node(Track *track,
72 double *track_buffer[RING_BUFFERS];
73 //printf("VirtualAConsole::new_toplevel_node %p\n", module);
74 for(int i = 0; i < total_ring_buffers(); i++)
75 track_buffer[i] = buffer_in[i][track_number];
76 return new VirtualANode(renderengine,
91 int VirtualAConsole::stop_rendering(int duplicate)
93 if(renderengine->command->realtime)
101 int VirtualAConsole::process_buffer(int64_t input_len,
102 int64_t input_position,
104 int64_t absolute_position)
107 // wait for an input_buffer to become available
108 if(renderengine->command->realtime)
109 output_lock[current_input_buffer]->lock();
114 double **buffer_in = this->buffer_in[current_input_buffer];
116 for(int i = 0; i < total_tracks; i++)
118 result |= ((AModule*)virtual_modules[i]->real_module)->render(buffer_in[i],
121 renderengine->command->get_direction());
126 this->input_len[current_input_buffer] = input_len;
127 this->input_position[current_input_buffer] = input_position;
128 this->last_playback[current_input_buffer] = last_buffer;
129 this->last_reconfigure[current_input_buffer] = 0;
130 this->absolute_position[current_input_buffer] = absolute_position;
132 if(renderengine->command->realtime)
133 input_lock[current_input_buffer]->unlock();
138 //printf("VirtualAConsole::process_buffer 5 %p\n", buffer_in[0]);
139 // for(int i = 0; i < input_len; i++)
141 // int16_t value = (int16_t)(buffer_in[0][i] * 32767);
142 // fwrite(&value, 2, 1, stdout);
151 void VirtualAConsole::process_console()
154 // length and lowest numbered sample of fragment in input buffer
155 int buffer = current_vconsole_buffer;
156 int64_t fragment_len, fragment_position;
158 double *current_buffer;
159 // starting sample of fragment in project
160 int64_t real_position;
162 double min, max, peak;
163 int64_t meter_render_end; // end of current meter fragment for getting levels
164 int64_t current_fragment_peak; // first meter peak in fragment
165 int64_t input_len = this->input_len[buffer];
166 int64_t input_position = this->input_position[buffer];
167 int64_t absolute_position = this->absolute_position[buffer];
171 //printf("VirtualAConsole::process_console 1 %p\n", this->buffer_in[buffer][0]);
173 // process entire input buffer by filling one output buffer at a time
174 for(fragment_position = 0;
175 fragment_position < input_len && !interrupt; )
178 // test for end of input buffer
179 fragment_len = renderengine->edl->session->audio_module_fragment;
180 if(fragment_position + fragment_len > input_len)
181 fragment_len = input_len - fragment_position;
186 // clear output buffers
187 for(i = 0; i < MAX_CHANNELS; i++)
189 if(arender->audio_out[i])
191 bzero(arender->audio_out[i], fragment_len * sizeof(double));
199 // get the start of the fragment in the project
201 (renderengine->command->get_direction() == PLAY_REVERSE) ?
202 input_position - fragment_position :
203 input_position + fragment_position;
205 // render nodes in sorted list
206 for(i = 0; i < render_list.total; i++)
208 //printf("VirtualAConsole::process_console 1 %p\n", this->buffer_in[buffer][i] + fragment_position);
209 ((VirtualANode*)render_list.values[i])->render(arender->audio_out,
215 arender->source_length,
216 renderengine->reverse,
220 // get peaks and limit volume in the fragment
221 for(i = 0; i < MAX_CHANNELS; i++)
223 current_buffer = arender->audio_out[i];
227 for(j = 0; j < fragment_len; )
229 // Get length to test for meter
230 if(renderengine->command->realtime)
231 meter_render_end = j + arender->meter_render_fragment;
233 meter_render_end = fragment_len;
235 if(meter_render_end > fragment_len)
236 meter_render_end = fragment_len;
240 for( ; j < meter_render_end; j++)
242 // Level history comes before clipping to get over status
243 if(current_buffer[j] > max) max = current_buffer[j];
245 if(current_buffer[j] < min) min = current_buffer[j];
247 if(current_buffer[j] > 1) current_buffer[j] = 1;
249 if(current_buffer[j] < -1) current_buffer[j] = -1;
253 if(fabs(max) > fabs(min))
258 if(renderengine->command->realtime)
260 arender->level_history[i][arender->current_level[i]] = peak;
261 arender->level_samples[arender->current_level[i]] =
262 (renderengine->command->get_direction() == PLAY_REVERSE) ?
265 arender->current_level[i] = arender->get_next_peak(arender->current_level[i]);
274 fragment_position += fragment_len;
276 // Pack channels, fix speed and send to device.
277 if(renderengine->command->realtime && !interrupt)
280 int64_t real_output_len; // length compensated for speed
281 double sample; // output sample
283 double *audio_out_packed[MAX_CHANNELS];
285 for(i = 0, j = 0; i < MAX_CHANNELS; i++)
287 if(renderengine->config->aconfig->do_channel[i])
289 audio_out_packed[j++] = arender->audio_out[i];
294 i < renderengine->config->aconfig->total_playable_channels();
298 int64_t fragment_end;
300 current_buffer = audio_out_packed[i];
302 // Time stretch the fragment to the real_output size
303 if(renderengine->command->get_speed() > 1)
305 // Number of samples in real output buffer for each to sample rendered.
306 int interpolate_len = (int)renderengine->command->get_speed();
307 for(in = 0, out = 0; in < fragment_len; )
310 for(k = 0; k < interpolate_len; k++)
312 sample += current_buffer[in++];
314 sample /= renderengine->command->get_speed();
315 current_buffer[out++] = sample;
317 real_output_len = out;
320 if(renderengine->command->get_speed() < 1)
322 int interpolate_len = (int)(1 / renderengine->command->get_speed()); // number of samples to skip
323 real_output_len = fragment_len * interpolate_len;
325 for(in = fragment_len - 1, out = real_output_len - 1; in >= 0; )
327 for(k = 0; k < interpolate_len; k++)
329 current_buffer[out--] = current_buffer[in];
335 real_output_len = fragment_len;
338 if(!renderengine->audio->get_interrupted())
340 renderengine->audio->write_buffer(audio_out_packed,
342 renderengine->config->aconfig->total_playable_channels());
345 if(renderengine->audio->get_interrupted()) interrupt = 1;
349 // for(int i = 0; i < fragment_len; i++)
351 // int16_t value = (int16_t)(arender->audio_out[0][i] * 32767);
352 // fwrite(&value, 2, 1, stdout);
358 void VirtualAConsole::run()
360 startup_lock->unlock();
362 while(!done && !interrupt)
364 // wait for a buffer to render through console
365 input_lock[current_vconsole_buffer]->lock();
367 if(!done && !interrupt && !last_reconfigure[current_vconsole_buffer])
369 // render it if not last buffer
370 // send to output device or the previously set output buffer
373 // test for exit conditions tied to the buffer
374 if(last_playback[current_vconsole_buffer]) done = 1;
376 // free up buffer for reading from disk
377 output_lock[current_vconsole_buffer]->unlock();
380 if(!done) swap_thread_buffer();
383 if(last_reconfigure[current_vconsole_buffer])
389 for(int i = 0; i < total_ring_buffers(); i++)
391 output_lock[i]->unlock();
395 if(!last_reconfigure[current_vconsole_buffer])
397 if(renderengine->command->realtime)
398 send_last_output_buffer();
427 int VirtualAConsole::init_rendering(int duplicate)
433 int VirtualAConsole::send_last_output_buffer()
435 renderengine->audio->set_last_buffer();