00001 #include "aattachmentpoint.h"
00002 #include "aedit.h"
00003 #include "amodule.h"
00004 #include "aplugin.h"
00005 #include "arender.h"
00006 #include "asset.h"
00007 #include "atrack.h"
00008 #include "bcsignals.h"
00009 #include "cache.h"
00010 #include "edits.h"
00011 #include "edl.h"
00012 #include "edlsession.h"
00013 #include "file.h"
00014 #include "filexml.h"
00015 #include "floatautos.h"
00016 #include "language.h"
00017 #include "module.h"
00018 #include "patch.h"
00019 #include "plugin.h"
00020 #include "pluginarray.h"
00021 #include "preferences.h"
00022 #include "renderengine.h"
00023 #include "mainsession.h"
00024 #include "sharedlocation.h"
00025 #include "theme.h"
00026 #include "transition.h"
00027 #include "transportque.h"
00028 #include <string.h>
00029
00030
00031
00032 AModule::AModule(RenderEngine *renderengine,
00033 CommonRender *commonrender,
00034 PluginArray *plugin_array,
00035 Track *track)
00036 : Module(renderengine, commonrender, plugin_array, track)
00037 {
00038 data_type = TRACK_AUDIO;
00039 transition_temp = 0;
00040 transition_temp_alloc = 0;
00041 level_history = 0;
00042 current_level = 0;
00043 }
00044
00045
00046
00047
00048 AModule::~AModule()
00049 {
00050 if(transition_temp) delete [] transition_temp;
00051 if(level_history)
00052 {
00053 delete [] level_history;
00054 delete [] level_samples;
00055 }
00056 }
00057
00058 AttachmentPoint* AModule::new_attachment(Plugin *plugin)
00059 {
00060 return new AAttachmentPoint(renderengine, plugin);
00061 }
00062
00063
00064 void AModule::create_objects()
00065 {
00066 Module::create_objects();
00067
00068 if(commonrender)
00069 {
00070 level_history = new double[((ARender*)commonrender)->total_peaks];
00071 level_samples = new int64_t[((ARender*)commonrender)->total_peaks];
00072 current_level = 0;
00073
00074 for(int i = 0; i < ((ARender*)commonrender)->total_peaks; i++)
00075 {
00076 level_history[i] = 0;
00077 level_samples[i] = -1;
00078 }
00079 }
00080 }
00081
00082 int AModule::get_buffer_size()
00083 {
00084 if(renderengine)
00085 return renderengine->fragment_len;
00086 else
00087 return plugin_array->get_bufsize();
00088 }
00089
00090 void AModule::reverse_buffer(double *buffer, int64_t len)
00091 {
00092 int start, end;
00093 double temp;
00094
00095 for(start = 0, end = len - 1; end > start; start++, end--)
00096 {
00097 temp = buffer[start];
00098 buffer[start] = buffer[end];
00099 buffer[end] = temp;
00100 }
00101 }
00102
00103
00104 CICache* AModule::get_cache()
00105 {
00106 if(renderengine)
00107 return renderengine->get_acache();
00108 else
00109 return cache;
00110 }
00111
00112 int AModule::render(double *buffer,
00113 int64_t input_position,
00114 int input_len,
00115 int direction,
00116 int sample_rate,
00117 int use_nudge)
00118 {
00119 int64_t edl_rate = get_edl()->session->sample_rate;
00120 if(use_nudge)
00121 input_position += track->nudge *
00122 sample_rate /
00123 edl_rate;
00124
00125 AEdit *playable_edit;
00126 int64_t start_project = input_position;
00127 int64_t end_project = input_position + input_len;
00128 int64_t buffer_offset = 0;
00129 int result = 0;
00130
00131
00132
00133 if(direction == PLAY_REVERSE)
00134 {
00135 start_project -= input_len;
00136 end_project -= input_len;
00137 }
00138
00139 SET_TRACE
00140
00141
00142 bzero(buffer, input_len * sizeof(double));
00143
00144 SET_TRACE
00145
00146
00147
00148
00149 for(playable_edit = (AEdit*)track->edits->first;
00150 playable_edit;
00151 playable_edit = (AEdit*)playable_edit->next)
00152 {
00153 int64_t edit_start = playable_edit->startproject;
00154 int64_t edit_end = playable_edit->startproject + playable_edit->length;
00155
00156 edit_start = edit_start * sample_rate / edl_rate;
00157 edit_end = edit_end * sample_rate / edl_rate;
00158
00159 if(start_project < edit_end && start_project + input_len > edit_start)
00160 {
00161 break;
00162 }
00163 }
00164
00165
00166
00167
00168 SET_TRACE
00169
00170
00171
00172
00173 while(start_project < end_project)
00174 {
00175 SET_TRACE
00176 int64_t fragment_len = input_len;
00177
00178
00179 if(fragment_len + start_project > end_project)
00180 fragment_len = end_project - start_project;
00181
00182 SET_TRACE
00183
00184 update_transition(start_project *
00185 edl_rate /
00186 sample_rate,
00187 PLAY_FORWARD);
00188
00189 SET_TRACE
00190 if(playable_edit)
00191 {
00192
00193 int64_t edit_startproject = playable_edit->startproject;
00194 int64_t edit_endproject = playable_edit->startproject + playable_edit->length;
00195 int64_t edit_startsource = playable_edit->startsource;
00196
00197
00198 edit_startproject = edit_startproject * sample_rate / edl_rate;
00199 edit_endproject = edit_endproject * sample_rate / edl_rate;
00200 edit_startsource = edit_startsource * sample_rate / edl_rate;
00201
00202
00203
00204
00205
00206 if(fragment_len + start_project > edit_endproject)
00207 fragment_len = edit_endproject - start_project;
00208
00209
00210 if(playable_edit->asset)
00211 {
00212 File *source;
00213 get_cache()->age();
00214
00215
00216
00217 if(!(source = get_cache()->check_out(playable_edit->asset)))
00218 {
00219
00220 result = 1;
00221 printf(_("VirtualAConsole::load_track Couldn't open %s.\n"), playable_edit->asset->path);
00222 }
00223 else
00224 {
00225 int result = 0;
00226
00227 source->set_channel(playable_edit->channel);
00228
00229 result = source->set_audio_position(start_project -
00230 edit_startproject +
00231 edit_startsource,
00232 sample_rate);
00233
00234
00235
00236
00237
00238 source->read_samples(buffer + buffer_offset,
00239 fragment_len,
00240 sample_rate);
00241
00242 get_cache()->check_in(playable_edit->asset);
00243 }
00244 }
00245
00246
00247
00248 SET_TRACE
00249
00250
00251
00252 AEdit *previous_edit = (AEdit*)playable_edit->previous;
00253 if(transition && previous_edit)
00254 {
00255 int64_t transition_len = transition->length *
00256 sample_rate /
00257 edl_rate;
00258 int64_t previous_startproject = previous_edit->startproject *
00259 sample_rate /
00260 edl_rate;
00261 int64_t previous_startsource = previous_edit->startsource *
00262 sample_rate /
00263 edl_rate;
00264
00265
00266
00267 if(transition_temp && transition_temp_alloc < fragment_len)
00268 {
00269 delete [] transition_temp;
00270 transition_temp = 0;
00271 }
00272
00273 if(!transition_temp)
00274 {
00275 transition_temp = new double[fragment_len];
00276 transition_temp_alloc = fragment_len;
00277 }
00278
00279
00280
00281
00282 int transition_fragment_len = fragment_len;
00283 if(fragment_len + start_project >
00284 edit_startproject + transition_len)
00285 fragment_len = edit_startproject + transition_len - start_project;
00286
00287
00288 if(transition_fragment_len > 0)
00289 {
00290 if(previous_edit->asset)
00291 {
00292 File *source;
00293 get_cache()->age();
00294 if(!(source = get_cache()->check_out(previous_edit->asset)))
00295 {
00296
00297 printf(_("VirtualAConsole::load_track Couldn't open %s.\n"), playable_edit->asset->path);
00298 result = 1;
00299 }
00300 else
00301 {
00302 int result = 0;
00303
00304 source->set_channel(previous_edit->channel);
00305
00306 result = source->set_audio_position(start_project -
00307 previous_startproject +
00308 previous_startsource,
00309 get_edl()->session->sample_rate);
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321 source->read_samples(transition_temp,
00322 transition_fragment_len,
00323 sample_rate);
00324
00325 get_cache()->check_in(previous_edit->asset);
00326 }
00327 }
00328 else
00329 {
00330 bzero(transition_temp, transition_fragment_len * sizeof(double));
00331 }
00332
00333 double *output = buffer + buffer_offset;
00334 transition_server->process_transition(
00335 transition_temp,
00336 output,
00337 start_project - edit_startproject,
00338 transition_fragment_len,
00339 transition->length);
00340 }
00341 }
00342 SET_TRACE
00343
00344 if(playable_edit && start_project + fragment_len >= edit_endproject)
00345 playable_edit = (AEdit*)playable_edit->next;
00346 }
00347
00348 SET_TRACE
00349 buffer_offset += fragment_len;
00350 start_project += fragment_len;
00351 }
00352
00353
00354
00355 if(direction == PLAY_REVERSE)
00356 reverse_buffer(buffer, input_len);
00357
00358 SET_TRACE
00359
00360 return result;
00361 }
00362
00363
00364
00365
00366
00367
00368
00369
00370