Main Page | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Class Members | File Members

amodule.C

Go to the documentation of this file.
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 // Not needed in pluginarray
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 // Flip range around so start_project < end_project
00133         if(direction == PLAY_REVERSE)
00134         {
00135                 start_project -= input_len;
00136                 end_project -= input_len;
00137         }
00138 
00139 SET_TRACE
00140 
00141 // Clear buffer
00142         bzero(buffer, input_len * sizeof(double));
00143 
00144 SET_TRACE
00145 // The EDL is normalized to the requested sample rate because the requested rate may
00146 // be the project sample rate and a sample rate 
00147 // might as well be directly from the source rate to the requested rate.
00148 // Get first edit containing the range
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 // Normalize to requested rate
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 // Fill output one fragment at a time
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 // Normalize position here since update_transition is a boolean operation.
00184                 update_transition(start_project * 
00185                                 edl_rate / 
00186                                 sample_rate, 
00187                         PLAY_FORWARD);
00188 
00189 SET_TRACE
00190                 if(playable_edit)
00191                 {
00192 // Normalize EDL positions to requested rate
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 //printf("AModule::render 52 %lld\n", fragment_len);
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 //printf("AModule::render 53 %lld\n", fragment_len);
00202 
00203 
00204 
00205 // Trim fragment_len
00206                         if(fragment_len + start_project > edit_endproject)
00207                                 fragment_len = edit_endproject - start_project;
00208 //printf("AModule::render 56 %lld\n", fragment_len);
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 // couldn't open source file / skip the edit
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 //                                      if(result) printf("AModule::render start_project=%d playable_edit->startproject=%d playable_edit->startsource=%d\n"
00235 //                                              "source=%p playable_edit=%p edl=%p edlsession=%p sample_rate=%d\n",
00236 //                                              start_project, playable_edit->startproject, playable_edit->startsource, 
00237 //                                              source, playable_edit, get_edl(), get_edl()->session, get_edl()->session->sample_rate);
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 // Read transition into temp and render
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 // Read into temp buffers
00266 // Temp + master or temp + temp ? temp + master
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 // Trim transition_len
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 //printf("AModule::render 54 %lld\n", fragment_len);
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 // couldn't open source file / skip the edit
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 //                                                      if(result) printf("AModule::render start_project=%d playable_edit->startproject=%d playable_edit->startsource=%d\n"
00312 //                                                              "source=%p playable_edit=%p edl=%p edlsession=%p sample_rate=%d\n",
00313 //                                                              start_project, 
00314 //                                                              previous_edit->startproject, 
00315 //                                                              previous_edit->startsource, 
00316 //                                                              source, 
00317 //                                                              playable_edit, 
00318 //                                                              get_edl(), 
00319 //                                                              get_edl()->session, 
00320 //                                                              get_edl()->session->sample_rate);
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 // Reverse buffer here so plugins always render forward.
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 

Generated on Sun Jan 8 13:38:49 2006 for Cinelerra-svn by  doxygen 1.4.4