00001 #include "asset.h"
00002 #include "audiodevice.h"
00003 #include "batch.h"
00004 #include "bcsignals.h"
00005 #include "clip.h"
00006 #include "condition.h"
00007 #include "edl.h"
00008 #include "edlsession.h"
00009 #include "errorbox.h"
00010 #include "file.h"
00011 #include "filethread.h"
00012 #include "language.h"
00013 #include "meterpanel.h"
00014 #include "mutex.h"
00015 #include "mwindow.h"
00016 #include "mwindowgui.h"
00017 #include "preferences.h"
00018 #include "record.h"
00019 #include "recordaudio.h"
00020 #include "recordgui.h"
00021 #include "recordengine.h"
00022 #include "recordmonitor.h"
00023 #include "recordthread.h"
00024 #include "renderengine.h"
00025
00026
00027
00028 RecordAudio::RecordAudio(MWindow *mwindow,
00029 Record *record,
00030 RecordThread *record_thread)
00031 : Thread(1, 0, 0)
00032 {
00033 this->mwindow = mwindow;
00034 this->record = record;
00035 this->record_thread = record_thread;
00036 this->gui = record->record_gui;
00037 fragment_position = 0;
00038 timer_lock = new Mutex("RecordAudio::timer_lock");
00039 trigger_lock = new Condition(1, "RecordAudio::trigger_lock");
00040 }
00041
00042 RecordAudio::~RecordAudio()
00043 {
00044 delete timer_lock;
00045 delete trigger_lock;
00046 }
00047
00048 void RecordAudio::reset_parameters()
00049 {
00050 fragment_position = 0;
00051 batch_done = 0;
00052 }
00053
00054
00055 int RecordAudio::arm_recording()
00056 {
00057 reset_parameters();
00058
00059 record->get_audio_write_length(buffer_size, fragment_size);
00060 record_channels = record->default_asset->channels;
00061
00062 if(mwindow->edl->session->real_time_record) Thread::set_realtime();
00063
00064 timer.update();
00065 trigger_lock->lock("RecordAudio::arm_recording");
00066 Thread::start();
00067 }
00068
00069 void RecordAudio::start_recording()
00070 {
00071 trigger_lock->unlock();
00072 }
00073
00074 int RecordAudio::stop_recording()
00075 {
00076
00077 if(record->adevice)
00078 {
00079 record->adevice->interrupt_crash();
00080
00081 }
00082 return 0;
00083 }
00084
00085 void RecordAudio::run()
00086 {
00087 int channel, buffer;
00088 Timer delayer;
00089 int total_clipped_samples = 0;
00090 int clipped_sample = 0;
00091 write_result = 0;
00092 grab_result = 0;
00093
00094
00095 over = new int[record_channels];
00096 max = new double[record_channels];
00097
00098
00099 if(!record_thread->monitor)
00100 {
00101
00102 input = record->file->get_audio_buffer();
00103 }
00104 else
00105 {
00106
00107 input = new double*[record_channels];
00108
00109 for(int i = 0; i < record_channels; i++)
00110 {
00111 input[i] = new double[buffer_size];
00112 }
00113 }
00114
00115
00116 gui->total_clipped_samples = 0;
00117 gui->update_clipped_samples(0);
00118
00119
00120
00121 trigger_lock->lock("RecordAudio::run");
00122 trigger_lock->unlock();
00123
00124
00125
00126 while(!batch_done &&
00127 !write_result)
00128 {
00129
00130
00131 if(!record_thread->monitor)
00132 {
00133
00134
00135
00136 grab_result = record->adevice->read_buffer(input,
00137 fragment_size,
00138 record_channels,
00139 over,
00140 max,
00141 fragment_position);
00142
00143 }
00144 else
00145 {
00146
00147
00148 grab_result = record->adevice->read_buffer(input,
00149 fragment_size,
00150 record_channels,
00151 over,
00152 max,
00153 0);
00154
00155 }
00156
00157
00158
00159 timer_lock->lock("RecordAudio::run");
00160
00161 if(!record_thread->monitor)
00162 {
00163 record->get_current_batch()->current_sample += fragment_size;
00164 record->get_current_batch()->total_samples =
00165 MAX(record->get_current_batch()->current_sample, record->get_current_batch()->total_samples);
00166 }
00167
00168 record->get_current_batch()->session_samples += fragment_size;
00169 timer.update();
00170 timer_lock->unlock();
00171
00172
00173
00174 if(record->monitor_audio || !record_thread->monitor)
00175 {
00176 clipped_sample = 0;
00177 for(channel = 0; channel < record_channels; channel++)
00178 {
00179 if(over[channel]) clipped_sample = 1;
00180 }
00181 }
00182
00183
00184
00185 if(record->monitor_audio &&
00186 !batch_done &&
00187 !grab_result)
00188 {
00189 record->record_monitor->window->lock_window("RecordAudio::run 1");
00190 for(channel = 0; channel < record_channels; channel++)
00191 {
00192 record->record_monitor->window->meters->meters.values[channel]->update(
00193 max[channel],
00194 over[channel]);
00195 }
00196 record->record_monitor->window->unlock_window();
00197 }
00198
00199
00200
00201
00202 if(!record_thread->monitor)
00203 {
00204 fragment_position += fragment_size;
00205
00206 if(fragment_position >= buffer_size)
00207 {
00208 write_buffer(0);
00209 }
00210
00211
00212
00213 if(!record->default_asset->video_data)
00214 gui->update_position(record->current_display_position());
00215 if(clipped_sample)
00216 gui->update_clipped_samples(++total_clipped_samples);
00217
00218 if(!record_thread->monitor &&
00219 !batch_done &&
00220 !write_result &&
00221 !record->default_asset->video_data)
00222 {
00223
00224 switch(record->get_current_batch()->record_mode)
00225 {
00226 case RECORD_TIMED:
00227 if(record->current_display_position() > *record->current_duration())
00228 batch_done = 1;
00229 break;
00230 case RECORD_LOOP:
00231 if(record->current_display_position() > *record->current_duration())
00232 batch_done = 1;
00233 break;
00234 case RECORD_SCENETOSCENE:
00235 break;
00236 }
00237 }
00238 }
00239
00240 }
00241
00242 TRACE("RecordAudio::run 4");
00243 if(write_result && !record->default_asset->video_data)
00244 {
00245 ErrorBox error_box(PROGRAM_NAME ": Error",
00246 mwindow->gui->get_abs_cursor_x(1),
00247 mwindow->gui->get_abs_cursor_y(1));
00248 error_box.create_objects(_("No space left on disk."));
00249 error_box.run_window();
00250 batch_done = 1;
00251 }
00252 TRACE("RecordAudio::run 10\n");
00253
00254 if(!record_thread->monitor)
00255 {
00256
00257 write_buffer(1);
00258 }
00259 else
00260 {
00261
00262 for(int i = 0; i < record_channels; i++)
00263 {
00264 record->record_monitor->window->meters->meters.values[i]->reset();
00265 delete [] input[i];
00266 }
00267 delete [] input;
00268 input = 0;
00269 }
00270 TRACE("RecordAudio::run 11\n");
00271
00272
00273 gui->lock_window("RecordAudio::run 2");
00274 for(channel = 0; channel < record_channels; channel++)
00275 {
00276 record->record_monitor->window->meters->meters.values[channel]->reset();
00277 }
00278 TRACE("RecordAudio::run 12\n");
00279
00280 gui->unlock_window();
00281 delete [] max;
00282 delete [] over;
00283 TRACE("RecordAudio::run 100\n");
00284 }
00285
00286 void RecordAudio::write_buffer(int skip_new)
00287 {
00288
00289 write_result = record->file->write_audio_buffer(fragment_position);
00290
00291 if(record->default_asset->video_data) write_result = 0;
00292 fragment_position = 0;
00293 if(!skip_new && !write_result) input = record->file->get_audio_buffer();
00294 }
00295
00296 int64_t RecordAudio::sync_position()
00297 {
00298 int64_t result;
00299 if(!batch_done)
00300 {
00301
00302 timer_lock->lock("RecordAudio::sync_position");
00303 if(!mwindow->edl->session->record_software_position)
00304 {
00305
00306 result = record->adevice->current_position();
00307 }
00308 else
00309 {
00310
00311 result = record->get_current_batch()->session_samples +
00312 timer.get_scaled_difference(record->default_asset->sample_rate);
00313 }
00314 timer_lock->unlock();
00315
00316 return result;
00317 }
00318 else
00319 return -1;
00320 }
00321