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

virtualaconsole.C

Go to the documentation of this file.
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 // clear output buffers
00074         for(int i = 0; i < MAX_CHANNELS; i++)
00075         {
00076 // printf("VirtualAConsole::process_buffer 2 %d %p %lld\n", 
00077 // i, 
00078 // arender->audio_out[i],
00079 // len);
00080                 if(arender->audio_out[i])
00081                 {
00082                         bzero(arender->audio_out[i], len * sizeof(double));
00083                 }
00084         }
00085 
00086 // Create temporary output
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 // Reset plugin rendering status
00100         reset_attachments();
00101 //printf("VirtualAConsole::process_buffer 1 %p\n", output_temp);
00102 
00103 // Render exit nodes
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 //printf("VirtualAConsole::process_buffer 2 %d %p\n", i, output_temp);
00110                 result |= node->render(output_temp, 
00111                         start_position + track->nudge,
00112                         len,
00113                         renderengine->edl->session->sample_rate);
00114 //printf("VirtualAConsole::process_buffer 3 %p\n", output_temp);
00115         }
00116 //printf("VirtualAConsole::process_buffer 4\n");
00117 
00118 
00119 // get peaks and limit volume in the fragment
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 // Get length to test for meter and limit
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 // Level history comes before clipping to get over status
00143                                         double *sample = &current_buffer[j];
00144 
00145 
00146                                         if(fabs(*sample) > peak) peak = fabs(*sample);
00147 // Make the output device clip it
00148 //                                      if(*sample > 1) *sample = 1;
00149 //                                      else
00150 //                                      if(*sample < -1) *sample = -1;
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 //printf("VirtualAConsole::process_buffer 5\n");
00170 
00171 
00172 // Pack channels, fix speed and send to device.
00173         if(renderengine->command->realtime && !interrupt)
00174         {
00175 // speed parameters
00176 // length compensated for speed
00177                 int real_output_len;
00178 // output sample
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 // Time stretch the fragment to the real_output size
00201                         if(renderengine->command->get_speed() > 1)
00202                         {
00203 // Number of samples in real output buffer for each to sample rendered.
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 // number of samples to skip
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 // Wait until video is ready
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 //printf("VirtualAConsole::process_buffer 100\n");
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 

Generated on Sun Jan 8 13:39:02 2006 for Cinelerra-svn by  doxygen 1.4.4