00001 #include "aedit.h"
00002 #include "amodule.h"
00003 #include "arender.h"
00004 #include "assets.h"
00005 #include "atrack.h"
00006 #include "audiodevice.h"
00007 #include "condition.h"
00008 #include "edit.h"
00009 #include "edits.h"
00010 #include "edl.h"
00011 #include "edlsession.h"
00012 #include "file.h"
00013 #include "levelwindow.h"
00014 #include "playabletracks.h"
00015 #include "plugin.h"
00016 #include "preferences.h"
00017 #include "renderengine.h"
00018 #include "thread.h"
00019 #include "tracks.h"
00020 #include "transportque.h"
00021 #include "virtualaconsole.h"
00022 #include "virtualanode.h"
00023 #include "virtualnode.h"
00024
00025
00026 VirtualAConsole::VirtualAConsole(RenderEngine *renderengine, ARender *arender)
00027 : VirtualConsole(renderengine, arender, TRACK_AUDIO)
00028 {
00029 this->arender = arender;
00030 output_temp = 0;
00031 output_allocation = 0;
00032 }
00033
00034 VirtualAConsole::~VirtualAConsole()
00035 {
00036 if(output_temp) delete [] output_temp;
00037 }
00038
00039
00040 void VirtualAConsole::get_playable_tracks()
00041 {
00042 if(!playable_tracks)
00043 playable_tracks = new PlayableTracks(renderengine,
00044 commonrender->current_position,
00045 TRACK_AUDIO,
00046 1);
00047 }
00048
00049
00050 VirtualNode* VirtualAConsole::new_entry_node(Track *track,
00051 Module *module,
00052 int track_number)
00053 {
00054 return new VirtualANode(renderengine,
00055 this,
00056 module,
00057 0,
00058 track,
00059 0);
00060 return 0;
00061 }
00062
00063
00064
00065 int VirtualAConsole::process_buffer(int64_t len,
00066 int64_t start_position,
00067 int last_buffer,
00068 int64_t absolute_position)
00069 {
00070 int result = 0;
00071
00072
00073
00074 for(int i = 0; i < MAX_CHANNELS; i++)
00075 {
00076
00077
00078
00079
00080 if(arender->audio_out[i])
00081 {
00082 bzero(arender->audio_out[i], len * sizeof(double));
00083 }
00084 }
00085
00086
00087 if(output_temp && output_allocation < len)
00088 {
00089 delete [] output_temp;
00090 output_temp = 0;
00091 }
00092
00093 if(!output_temp)
00094 {
00095 output_temp = new double[len];
00096 output_allocation = len;
00097 }
00098
00099
00100 reset_attachments();
00101
00102
00103
00104 for(int i = 0; i < exit_nodes.total; i++)
00105 {
00106 VirtualANode *node = (VirtualANode*)exit_nodes.values[i];
00107 Track *track = node->track;
00108
00109
00110 result |= node->render(output_temp,
00111 start_position + track->nudge,
00112 len,
00113 renderengine->edl->session->sample_rate);
00114
00115 }
00116
00117
00118
00119
00120 for(int i = 0; i < MAX_CHANNELS; i++)
00121 {
00122 double *current_buffer = arender->audio_out[i];
00123 if(current_buffer)
00124 {
00125
00126 for(int j = 0; j < len; )
00127 {
00128 int meter_render_end;
00129
00130 if(renderengine->command->realtime)
00131 meter_render_end = j + arender->meter_render_fragment;
00132 else
00133 meter_render_end = len;
00134
00135 if(meter_render_end > len)
00136 meter_render_end = len;
00137
00138 double peak = 0;
00139
00140 for( ; j < meter_render_end; j++)
00141 {
00142
00143 double *sample = ¤t_buffer[j];
00144
00145
00146 if(fabs(*sample) > peak) peak = fabs(*sample);
00147
00148
00149
00150
00151 }
00152
00153
00154 if(renderengine->command->realtime)
00155 {
00156 arender->level_history[i][arender->current_level[i]] = peak;
00157 arender->level_samples[arender->current_level[i]] =
00158 renderengine->command->get_direction() == PLAY_REVERSE ?
00159 start_position - j :
00160 start_position + j;
00161 arender->current_level[i] = arender->get_next_peak(arender->current_level[i]);
00162 }
00163 }
00164 }
00165 }
00166
00167
00168
00169
00170
00171
00172
00173 if(renderengine->command->realtime && !interrupt)
00174 {
00175
00176
00177 int real_output_len;
00178
00179 double sample;
00180 int k;
00181 double *audio_out_packed[MAX_CHANNELS];
00182
00183 for(int i = 0, j = 0; i < MAX_CHANNELS; i++)
00184 {
00185 if(renderengine->config->aconfig->do_channel[i])
00186 {
00187 audio_out_packed[j++] = arender->audio_out[i];
00188 }
00189 }
00190
00191 for(int i = 0;
00192 i < renderengine->config->aconfig->total_playable_channels();
00193 i++)
00194 {
00195 int in, out;
00196 int fragment_end;
00197
00198 double *current_buffer = audio_out_packed[i];
00199
00200
00201 if(renderengine->command->get_speed() > 1)
00202 {
00203
00204 int interpolate_len = (int)renderengine->command->get_speed();
00205 for(in = 0, out = 0; in < len; )
00206 {
00207 sample = 0;
00208 for(k = 0; k < interpolate_len; k++)
00209 {
00210 sample += current_buffer[in++];
00211 }
00212 sample /= renderengine->command->get_speed();
00213 current_buffer[out++] = sample;
00214 }
00215 real_output_len = out;
00216 }
00217 else
00218 if(renderengine->command->get_speed() < 1)
00219 {
00220
00221 int interpolate_len = (int)(1.0 / renderengine->command->get_speed());
00222 real_output_len = len * interpolate_len;
00223
00224 for(in = len - 1, out = real_output_len - 1; in >= 0; )
00225 {
00226 for(k = 0; k < interpolate_len; k++)
00227 {
00228 current_buffer[out--] = current_buffer[in];
00229 }
00230 in--;
00231 }
00232 }
00233 else
00234 real_output_len = len;
00235 }
00236
00237
00238 if(arender->first_buffer)
00239 {
00240 renderengine->first_frame_lock->lock("VirtualAConsole::process_buffer");
00241 arender->first_buffer = 0;
00242 }
00243 if(!renderengine->audio->get_interrupted())
00244 {
00245 renderengine->audio->write_buffer(audio_out_packed,
00246 real_output_len,
00247 renderengine->config->aconfig->total_playable_channels());
00248 }
00249
00250 if(renderengine->audio->get_interrupted()) interrupt = 1;
00251 }
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261 return result;
00262 }
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288 int VirtualAConsole::init_rendering(int duplicate)
00289 {
00290 return 0;
00291 }
00292
00293
00294 int VirtualAConsole::send_last_output_buffer()
00295 {
00296 renderengine->audio->set_last_buffer();
00297 return 0;
00298 }
00299