2 #include "audiodevice.h"
6 #include "edlsession.h"
9 #include "filethread.h"
10 #include "meterpanel.h"
12 #include "mwindowgui.h"
13 #include "preferences.h"
15 #include "recordaudio.h"
16 #include "recordgui.h"
17 #include "recordengine.h"
18 #include "recordmonitor.h"
19 #include "recordthread.h"
20 #include "renderengine.h"
24 #define _(String) gettext(String)
25 #define gettext_noop(String) String
26 #define N_(String) gettext_noop (String)
29 RecordAudio::RecordAudio(MWindow *mwindow,
31 RecordThread *record_thread)
34 this->mwindow = mwindow;
35 this->record = record;
36 this->record_thread = record_thread;
37 this->gui = record->record_gui;
38 fragment_position = 0;
41 RecordAudio::~RecordAudio()
45 void RecordAudio::reset_parameters()
47 fragment_position = 0;
52 int RecordAudio::arm_recording()
56 record->get_audio_write_length(buffer_size, fragment_size);
57 record_channels = record->default_asset->channels;
59 if(mwindow->edl->session->real_time_record) Thread::set_realtime();
67 void RecordAudio::start_recording()
69 trigger_lock.unlock();
72 int RecordAudio::stop_recording()
74 // Device won't exist if interrupting a cron job
77 //printf("RecordAudio::stop_recording 1\n");
78 record->adevice->interrupt_crash();
79 //printf("RecordAudio::stop_recording 2\n");
85 void RecordAudio::run()
89 int total_clipped_samples = 0;
90 int clipped_sample = 0;
94 over = new int[record_channels];
95 max = new double[record_channels];
98 if(!record_thread->monitor)
100 // Get a buffer from the file to record into.
101 input = record->file->get_audio_buffer();
105 // Make up a fake buffer.
106 input = new double*[record_channels];
108 for(int i = 0; i < record_channels; i++)
110 input[i] = new double[buffer_size];
114 //printf("RecordAudio::run 1\n");
115 gui->total_clipped_samples = 0;
116 gui->update_clipped_samples(0);
121 trigger_lock.unlock();
124 //printf("RecordAudio::run 2\n");
128 // Handle data from the audio device.
129 //printf("RecordAudio::run 3\n");
130 if(!record_thread->monitor)
132 // Read into file's buffer for recording.
133 // device needs to write buffer starting at fragment position
134 //printf("RecordAudio::run 2.1\n");
135 grab_result = record->adevice->read_buffer(input,
141 //printf("RecordAudio::run 2.2\n");
145 // Read into monitor buffer for monitoring.
146 //printf("RecordAudio::run 1\n");
147 grab_result = record->adevice->read_buffer(input, fragment_size, record_channels, over, max, 0);
148 //printf("RecordAudio::run 2 %d\n", grab_result);
150 //printf("RecordAudio::run 3 %d\n", fragment_size);
152 // Update timer for synchronization
155 if(!record_thread->monitor)
157 record->get_current_batch()->current_sample += fragment_size;
158 record->get_current_batch()->total_samples =
159 MAX(record->get_current_batch()->current_sample, record->get_current_batch()->total_samples);
162 record->get_current_batch()->session_samples += fragment_size;
166 //printf("RecordAudio::run 2\n");
167 // Get clipping status
168 if(record->monitor_audio || !record_thread->monitor)
171 for(channel = 0; channel < record_channels; channel++)
173 if(over[channel]) clipped_sample = 1;
177 // Update meters if monitoring
178 //printf("RecordAudio::run 2 %d %d %d %d\n", record->monitor_audio, record_thread->batch_done(), record_thread->loop_done(), grab_result);
179 if(record->monitor_audio &&
183 record->record_monitor->window->lock_window();
184 for(channel = 0; channel < record_channels; channel++)
186 record->record_monitor->window->meters->meters.values[channel]->update(max[channel], over[channel]);
188 record->record_monitor->window->unlock_window();
192 //printf("RecordAudio::run 2\n");
193 // Write file if writing
194 if(!record_thread->monitor)
196 fragment_position += fragment_size;
198 if(fragment_position >= buffer_size)
204 //printf("RecordAudio::run 2 %f\n", record->current_display_position());
205 if(!record->default_asset->video_data)
206 gui->update_position(record->current_display_position(),
207 record->current_display_length());
209 gui->update_clipped_samples(++total_clipped_samples);
211 if(!record_thread->monitor &&
214 !record->default_asset->video_data)
216 // handle different recording modes
217 switch(record->get_current_batch()->record_mode)
220 if(record->current_display_position() > *record->current_duration())
224 if(record->current_display_position() > *record->current_duration())
227 case RECORD_SCENETOSCENE:
232 //printf("RecordAudio::run 4 %d %d\n", batch_done, write_result);
235 //printf("RecordAudio::run 4\n");
236 if(write_result && !record->default_asset->video_data)
238 ErrorBox error_box(PROGRAM_NAME ": Error",
239 mwindow->gui->get_abs_cursor_x(),
240 mwindow->gui->get_abs_cursor_y());
241 error_box.create_objects(_("No space left on disk."));
242 error_box.run_window();
245 //printf("RecordAudio::run 10\n");
247 if(!record_thread->monitor)
254 // Delete the fake buffer.
255 for(int i = 0; i < record_channels; i++)
257 record->record_monitor->window->meters->meters.values[i]->reset();
263 //printf("RecordAudio::run 11\n");
267 for(channel = 0; channel < record_channels; channel++)
269 record->record_monitor->window->meters->meters.values[channel]->reset();
271 //printf("RecordAudio::run 12\n");
273 gui->unlock_window();
276 //printf("RecordAudio::run 5\n");
279 void RecordAudio::write_buffer(int skip_new)
281 // block until buffer is ready for writing
282 write_result = record->file->write_audio_buffer(fragment_position);
283 // Defeat errors if video
284 if(record->default_asset->video_data) write_result = 0;
285 fragment_position = 0;
286 if(!skip_new && !write_result) input = record->file->get_audio_buffer();
289 int64_t RecordAudio::sync_position()
294 //printf("RecordAudio::sync_position 1\n");
296 if(!mwindow->edl->session->record_software_position)
298 //printf("RecordAudio::sync_position 1\n");
299 result = record->adevice->current_position();
303 //printf("RecordAudio::sync_position 1 %d\n", record->get_current_batch()->session_samples);
304 result = record->get_current_batch()->session_samples +
305 timer.get_scaled_difference(record->default_asset->sample_rate);
308 //printf("RecordAudio::sync_position 2\n");