4 * Copyright (C) 2008 Adam Williams <broadcast at earthling dot net>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
27 #include "audiodevice.h"
28 #include "bcsignals.h"
29 #include "condition.h"
33 #include "edlsession.h"
36 #include "levelwindow.h"
37 #include "playabletracks.h"
39 #include "preferences.h"
40 #include "renderengine.h"
44 #include "transportque.h"
45 #include "virtualaconsole.h"
46 #include "virtualanode.h"
47 #include "virtualnode.h"
50 VirtualAConsole::VirtualAConsole(RenderEngine *renderengine, ARender *arender)
51 : VirtualConsole(renderengine, arender, TRACK_AUDIO)
53 this->arender = arender;
55 output_allocation = 0;
58 VirtualAConsole::~VirtualAConsole()
60 if(output_temp) delete output_temp;
64 void VirtualAConsole::get_playable_tracks()
67 playable_tracks = new PlayableTracks(renderengine->get_edl(),
68 commonrender->current_position,
69 renderengine->command->get_direction(),
75 VirtualNode* VirtualAConsole::new_entry_node(Track *track,
79 return new VirtualANode(renderengine,
80 this, module, 0, track, 0);
86 int VirtualAConsole::process_buffer(int64_t len,
87 int64_t start_position)
91 if(debug) printf("VirtualAConsole::process_buffer %d this=%p len=" _LD "\n",
95 // clear output buffers
96 for(int i = 0; i < MAX_CHANNELS; i++)
98 // if(debug) printf("VirtualAConsole::process_buffer 2 %d %p " _LD "\n",
100 // arender->audio_out[i],
103 if(arender->audio_out[i])
105 bzero(arender->audio_out[i]->get_data(), len * sizeof(double));
109 // Create temporary output
110 if(output_temp && output_allocation < len)
118 output_temp = new Samples(len);
119 output_allocation = len;
121 if(debug) printf("VirtualAConsole::process_buffer %d\n", __LINE__);
124 // Reset plugin rendering status
126 //printf("VirtualAConsole::process_buffer 1 %p\n", output_temp);
128 if(debug) printf("VirtualAConsole::process_buffer %d\n", __LINE__);
132 for(int i = 0; i < exit_nodes.total; i++)
134 VirtualANode *node = (VirtualANode*)exit_nodes.values[i];
135 Track *track = node->track;
137 result |= node->render(output_temp,
139 start_position + track->nudge,
140 renderengine->get_edl()->session->sample_rate);
142 if(debug) printf("VirtualAConsole::process_buffer %d\n", __LINE__);
146 // get peaks and limit volume in the fragment
147 for(int i = 0; i < MAX_CHANNELS; i++)
149 if(arender->audio_out[i])
151 double *current_buffer = arender->audio_out[i]->get_data();
154 for(int j = 0; j < len; )
156 int meter_render_end;
157 // Get length to test for meter and limit
158 if(renderengine->command->realtime)
159 meter_render_end = j + arender->meter_render_fragment;
161 meter_render_end = len;
163 if(meter_render_end > len)
164 meter_render_end = len;
168 for( ; j < meter_render_end; j++)
170 // Level history comes before clipping to get over status
171 double *sample = ¤t_buffer[j];
174 if(fabs(*sample) > peak) peak = fabs(*sample);
175 // Make the output device clip it
176 // if(*sample > 1) *sample = 1;
178 // if(*sample < -1) *sample = -1;
182 if(renderengine->command->realtime)
184 arender->level_history[i][arender->current_level[i]] = peak;
185 arender->level_samples[arender->current_level[i]] =
186 renderengine->command->get_direction() == PLAY_REVERSE ?
189 arender->current_level[i] = arender->get_next_peak(arender->current_level[i]);
195 if(debug) printf("VirtualAConsole::process_buffer %d\n", __LINE__);
201 // Pack channels, fix speed and send to device.
202 if(!renderengine->is_nested &&
203 renderengine->command->realtime &&
207 // length compensated for speed
208 int real_output_len = 0;
212 double *audio_out_packed[MAX_CHANNELS];
213 int audio_channels = renderengine->get_edl()->session->audio_channels;
215 for(int i = 0, j = 0;
219 audio_out_packed[j++] = arender->audio_out[i]->get_data();
227 double *current_buffer = audio_out_packed[i];
229 // Time stretch the fragment to the real_output size
230 if(renderengine->command->get_speed() > 1)
232 // Number of samples in real output buffer for each to sample rendered.
233 int interpolate_len = (int)renderengine->command->get_speed();
234 for(in = 0, out = 0; in < len; )
237 for(k = 0; k < interpolate_len; k++)
239 sample += current_buffer[in++];
242 sample /= renderengine->command->get_speed();
243 current_buffer[out++] = sample;
245 real_output_len = out;
248 if(renderengine->command->get_speed() < 1)
250 // number of samples to skip
251 int interpolate_len = (int)(1.0 / renderengine->command->get_speed());
252 real_output_len = len * interpolate_len;
254 for(in = len - 1, out = real_output_len - 1; in >= 0; )
256 for(k = 0; k < interpolate_len; k++)
258 current_buffer[out--] = current_buffer[in];
264 real_output_len = len;
267 // Wait until video is ready
268 if(arender->first_buffer)
270 renderengine->first_frame_lock->lock("VirtualAConsole::process_buffer");
271 arender->first_buffer = 0;
273 if(!renderengine->audio->get_interrupted())
275 renderengine->audio->write_buffer(audio_out_packed, audio_channels,
279 if(renderengine->audio->get_interrupted()) interrupt = 1;
282 if(debug) printf("VirtualAConsole::process_buffer %d\n", __LINE__);
315 int VirtualAConsole::init_rendering(int duplicate)
321 int VirtualAConsole::send_last_output_buffer()
323 renderengine->audio->set_last_buffer();