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
00140
00141 bzero(buffer, input_len * sizeof(double));
00142
00143
00144
00145
00146
00147 for(playable_edit = (AEdit*)track->edits->first;
00148 playable_edit;
00149 playable_edit = (AEdit*)playable_edit->next)
00150 {
00151 int64_t edit_start = playable_edit->startproject;
00152 int64_t edit_end = playable_edit->startproject + playable_edit->length;
00153
00154 edit_start = edit_start * sample_rate / edl_rate;
00155 edit_end = edit_end * sample_rate / edl_rate;
00156
00157 if(start_project < edit_end && start_project + input_len > edit_start)
00158 {
00159 break;
00160 }
00161 }
00162
00163
00164
00165
00166
00167
00168
00169
00170 while(start_project < end_project)
00171 {
00172 int64_t fragment_len = input_len;
00173
00174
00175 if(fragment_len + start_project > end_project)
00176 fragment_len = end_project - start_project;
00177
00178
00179 update_transition(start_project *
00180 edl_rate /
00181 sample_rate,
00182 PLAY_FORWARD);
00183
00184 if(playable_edit)
00185 {
00186
00187 int64_t edit_startproject = playable_edit->startproject;
00188 int64_t edit_endproject = playable_edit->startproject + playable_edit->length;
00189 int64_t edit_startsource = playable_edit->startsource;
00190
00191
00192 edit_startproject = edit_startproject * sample_rate / edl_rate;
00193 edit_endproject = edit_endproject * sample_rate / edl_rate;
00194 edit_startsource = edit_startsource * sample_rate / edl_rate;
00195
00196
00197
00198
00199
00200 if(fragment_len + start_project > edit_endproject)
00201 fragment_len = edit_endproject - start_project;
00202
00203
00204 if(playable_edit->asset)
00205 {
00206 File *source;
00207 get_cache()->age();
00208
00209
00210
00211 if(!(source = get_cache()->check_out(playable_edit->asset,
00212 get_edl())))
00213 {
00214
00215 result = 1;
00216 printf(_("VirtualAConsole::load_track Couldn't open %s.\n"), playable_edit->asset->path);
00217 }
00218 else
00219 {
00220 int result = 0;
00221
00222
00223 result = source->set_audio_position(start_project -
00224 edit_startproject +
00225 edit_startsource,
00226 sample_rate);
00227
00228
00229
00230
00231
00232
00233 source->set_channel(playable_edit->channel);
00234
00235 source->read_samples(buffer + buffer_offset,
00236 fragment_len,
00237 sample_rate);
00238
00239 get_cache()->check_in(playable_edit->asset);
00240 }
00241 }
00242
00243
00244
00245
00246
00247
00248 AEdit *previous_edit = (AEdit*)playable_edit->previous;
00249 if(transition && previous_edit)
00250 {
00251 int64_t transition_len = transition->length *
00252 sample_rate /
00253 edl_rate;
00254 int64_t previous_startproject = previous_edit->startproject *
00255 sample_rate /
00256 edl_rate;
00257 int64_t previous_startsource = previous_edit->startsource *
00258 sample_rate /
00259 edl_rate;
00260
00261
00262
00263 if(transition_temp && transition_temp_alloc < fragment_len)
00264 {
00265 delete [] transition_temp;
00266 transition_temp = 0;
00267 }
00268
00269 if(!transition_temp)
00270 {
00271 transition_temp = new double[fragment_len];
00272 transition_temp_alloc = fragment_len;
00273 }
00274
00275
00276
00277
00278 int transition_fragment_len = fragment_len;
00279 if(fragment_len + start_project >
00280 edit_startproject + transition_len)
00281 fragment_len = edit_startproject + transition_len - start_project;
00282
00283
00284 if(transition_fragment_len > 0)
00285 {
00286 if(previous_edit->asset)
00287 {
00288 File *source;
00289 get_cache()->age();
00290 if(!(source = get_cache()->check_out(
00291 previous_edit->asset,
00292 get_edl())))
00293 {
00294
00295 printf(_("VirtualAConsole::load_track Couldn't open %s.\n"), playable_edit->asset->path);
00296 result = 1;
00297 }
00298 else
00299 {
00300 int result = 0;
00301
00302 result = source->set_audio_position(start_project -
00303 previous_startproject +
00304 previous_startsource,
00305 get_edl()->session->sample_rate);
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318 source->set_channel(previous_edit->channel);
00319
00320 source->read_samples(transition_temp,
00321 transition_fragment_len,
00322 sample_rate);
00323
00324 get_cache()->check_in(previous_edit->asset);
00325 }
00326 }
00327 else
00328 {
00329 bzero(transition_temp, transition_fragment_len * sizeof(double));
00330 }
00331
00332 double *output = buffer + buffer_offset;
00333 transition_server->process_transition(
00334 transition_temp,
00335 output,
00336 start_project - edit_startproject,
00337 transition_fragment_len,
00338 transition->length);
00339 }
00340 }
00341
00342 if(playable_edit && start_project + fragment_len >= edit_endproject)
00343 playable_edit = (AEdit*)playable_edit->next;
00344 }
00345
00346 buffer_offset += fragment_len;
00347 start_project += fragment_len;
00348 }
00349
00350
00351
00352 if(direction == PLAY_REVERSE)
00353 reverse_buffer(buffer, input_len);
00354
00355
00356 return result;
00357 }
00358
00359
00360
00361
00362
00363
00364
00365
00366