2 #include "audiodevice.h"
8 #include "edlsession.h"
11 #include "filethread.h"
13 #include "meterpanel.h"
16 #include "mwindowgui.h"
17 #include "preferences.h"
19 #include "recordaudio.h"
20 #include "recordgui.h"
21 #include "recordengine.h"
22 #include "recordmonitor.h"
23 #include "recordthread.h"
24 #include "renderengine.h"
28 RecordAudio::RecordAudio(MWindow *mwindow,
30 RecordThread *record_thread)
33 this->mwindow = mwindow;
34 this->record = record;
35 this->record_thread = record_thread;
36 this->gui = record->record_gui;
37 fragment_position = 0;
38 timer_lock = new Mutex("RecordAudio::timer_lock");
39 trigger_lock = new Condition(1, "RecordAudio::trigger_lock");
42 RecordAudio::~RecordAudio()
48 void RecordAudio::reset_parameters()
50 fragment_position = 0;
55 int RecordAudio::arm_recording()
59 record->get_audio_write_length(buffer_size, fragment_size);
60 record_channels = record->default_asset->channels;
62 // Realtime is set in the audio driver
63 // if(mwindow->edl->session->real_time_record) Thread::set_realtime();
66 trigger_lock->lock("RecordAudio::arm_recording");
70 void RecordAudio::start_recording()
72 trigger_lock->unlock();
75 int RecordAudio::stop_recording()
77 // Device won't exist if interrupting a cron job
80 record->adevice->interrupt_crash();
81 // Joined in RecordThread
87 void RecordAudio::run()
91 int total_clipped_samples = 0;
92 int clipped_sample = 0;
96 //printf("RecordAudio::run 1 %d\n", Thread::calculate_realtime());
97 over = new int[record_channels];
98 max = new double[record_channels];
101 if(!record_thread->monitor)
103 // Get a buffer from the file to record into.
104 input = record->file->get_audio_buffer();
108 // Make up a fake buffer.
109 input = new double*[record_channels];
111 for(int i = 0; i < record_channels; i++)
113 input[i] = new double[buffer_size];
117 //printf("RecordAudio::run 1\n");
118 gui->total_clipped_samples = 0;
119 gui->update_clipped_samples(0);
123 trigger_lock->lock("RecordAudio::run");
124 trigger_lock->unlock();
127 //printf("RecordAudio::run 2\n");
131 // Handle data from the audio device.
132 //printf("RecordAudio::run 3\n");
133 if(!record_thread->monitor)
135 // Read into file's buffer for recording.
136 // device needs to write buffer starting at fragment position
137 //printf("RecordAudio::run 2.1\n");
138 grab_result = record->adevice->read_buffer(input,
143 //printf("RecordAudio::run 2.2\n");
147 // Read into monitor buffer for monitoring.
148 //printf("RecordAudio::run 1\n");
149 grab_result = record->adevice->read_buffer(input,
154 //printf("RecordAudio::run 2 %d\n", grab_result);
156 //printf("RecordAudio::run 3 %d %f\n", fragment_size, max);
158 // Update timer for synchronization
159 timer_lock->lock("RecordAudio::run");
161 if(!record_thread->monitor)
163 record->get_current_batch()->current_sample += fragment_size;
164 record->get_current_batch()->total_samples =
165 MAX(record->get_current_batch()->current_sample, record->get_current_batch()->total_samples);
168 record->get_current_batch()->session_samples += fragment_size;
170 timer_lock->unlock();
172 //printf("RecordAudio::run 2\n");
173 // Get clipping status
174 if(record->monitor_audio || !record_thread->monitor)
177 for(channel = 0; channel < record_channels; channel++)
179 if(over[channel]) clipped_sample = 1;
183 // Update meters if monitoring
184 //printf("RecordAudio::run 2 %d %d %d %d\n", record->monitor_audio, record_thread->batch_done(), record_thread->loop_done(), grab_result);
185 if(record->monitor_audio &&
189 record->record_monitor->window->lock_window("RecordAudio::run 1");
190 for(channel = 0; channel < record_channels; channel++)
192 record->record_monitor->window->meters->meters.values[channel]->update(
196 record->record_monitor->window->unlock_window();
200 //printf("RecordAudio::run 2\n");
201 // Write file if writing
202 if(!record_thread->monitor)
204 fragment_position += fragment_size;
206 if(fragment_position >= buffer_size)
212 //printf("RecordAudio::run 2 %f\n", record->current_display_position());
213 if(!record->default_asset->video_data)
214 gui->update_position(record->current_display_position());
216 gui->update_clipped_samples(++total_clipped_samples);
218 if(!record_thread->monitor &&
221 !record->default_asset->video_data)
223 // handle different recording modes
224 switch(record->get_current_batch()->record_mode)
227 if(record->current_display_position() > *record->current_duration())
231 if(record->current_display_position() > *record->current_duration())
234 case RECORD_SCENETOSCENE:
239 //printf("RecordAudio::run 4 %d %d\n", batch_done, write_result);
242 TRACE("RecordAudio::run 4");
243 if(write_result && !record->default_asset->video_data)
245 ErrorBox error_box(PROGRAM_NAME ": Error",
246 mwindow->gui->get_abs_cursor_x(1),
247 mwindow->gui->get_abs_cursor_y(1));
248 error_box.create_objects(_("No space left on disk."));
249 error_box.run_window();
252 TRACE("RecordAudio::run 10");
254 if(!record_thread->monitor)
261 // Delete the fake buffer.
262 for(int i = 0; i < record_channels; i++)
264 record->record_monitor->window->meters->meters.values[i]->reset();
270 TRACE("RecordAudio::run 11");
273 gui->lock_window("RecordAudio::run 2");
274 for(channel = 0; channel < record_channels; channel++)
276 record->record_monitor->window->meters->meters.values[channel]->reset();
278 TRACE("RecordAudio::run 12");
280 gui->unlock_window();
283 TRACE("RecordAudio::run 100");
286 void RecordAudio::write_buffer(int skip_new)
288 // block until buffer is ready for writing
289 write_result = record->file->write_audio_buffer(fragment_position);
290 // Defeat errors if video
291 if(record->default_asset->video_data) write_result = 0;
292 fragment_position = 0;
293 if(!skip_new && !write_result) input = record->file->get_audio_buffer();
296 int64_t RecordAudio::sync_position()
301 //printf("RecordAudio::sync_position 1\n");
302 timer_lock->lock("RecordAudio::sync_position");
303 if(!mwindow->edl->session->record_software_position)
305 //printf("RecordAudio::sync_position 1\n");
306 result = record->adevice->current_position();
310 //printf("RecordAudio::sync_position 1 %d\n", record->get_current_batch()->session_samples);
311 result = record->get_current_batch()->session_samples +
312 timer.get_scaled_difference(record->default_asset->sample_rate);
314 timer_lock->unlock();
315 //printf("RecordAudio::sync_position 2\n");