2 #include "audiodevice.h"
6 #include "edlsession.h"
9 #include "filethread.h"
11 #include "meterpanel.h"
13 #include "mwindowgui.h"
14 #include "preferences.h"
16 #include "recordaudio.h"
17 #include "recordgui.h"
18 #include "recordengine.h"
19 #include "recordmonitor.h"
20 #include "recordthread.h"
21 #include "renderengine.h"
25 RecordAudio::RecordAudio(MWindow *mwindow,
27 RecordThread *record_thread)
30 this->mwindow = mwindow;
31 this->record = record;
32 this->record_thread = record_thread;
33 this->gui = record->record_gui;
34 fragment_position = 0;
37 RecordAudio::~RecordAudio()
41 void RecordAudio::reset_parameters()
43 fragment_position = 0;
48 int RecordAudio::arm_recording()
52 record->get_audio_write_length(buffer_size, fragment_size);
53 record_channels = record->default_asset->channels;
55 if(mwindow->edl->session->real_time_record) Thread::set_realtime();
63 void RecordAudio::start_recording()
65 trigger_lock.unlock();
68 int RecordAudio::stop_recording()
70 // Device won't exist if interrupting a cron job
73 //printf("RecordAudio::stop_recording 1\n");
74 record->adevice->interrupt_crash();
75 //printf("RecordAudio::stop_recording 2\n");
81 void RecordAudio::run()
85 int total_clipped_samples = 0;
86 int clipped_sample = 0;
90 over = new int[record_channels];
91 max = new double[record_channels];
94 if(!record_thread->monitor)
96 // Get a buffer from the file to record into.
97 input = record->file->get_audio_buffer();
101 // Make up a fake buffer.
102 input = new double*[record_channels];
104 for(int i = 0; i < record_channels; i++)
106 input[i] = new double[buffer_size];
110 //printf("RecordAudio::run 1\n");
111 gui->total_clipped_samples = 0;
112 gui->update_clipped_samples(0);
117 trigger_lock.unlock();
120 //printf("RecordAudio::run 2\n");
124 // Handle data from the audio device.
125 //printf("RecordAudio::run 3\n");
126 if(!record_thread->monitor)
128 // Read into file's buffer for recording.
129 // device needs to write buffer starting at fragment position
130 //printf("RecordAudio::run 2.1\n");
131 grab_result = record->adevice->read_buffer(input,
137 //printf("RecordAudio::run 2.2\n");
141 // Read into monitor buffer for monitoring.
142 //printf("RecordAudio::run 1\n");
143 grab_result = record->adevice->read_buffer(input, fragment_size, record_channels, over, max, 0);
144 //printf("RecordAudio::run 2 %d\n", grab_result);
146 //printf("RecordAudio::run 3 %d\n", fragment_size);
148 // Update timer for synchronization
151 if(!record_thread->monitor)
153 record->get_current_batch()->current_sample += fragment_size;
154 record->get_current_batch()->total_samples =
155 MAX(record->get_current_batch()->current_sample, record->get_current_batch()->total_samples);
158 record->get_current_batch()->session_samples += fragment_size;
162 //printf("RecordAudio::run 2\n");
163 // Get clipping status
164 if(record->monitor_audio || !record_thread->monitor)
167 for(channel = 0; channel < record_channels; channel++)
169 if(over[channel]) clipped_sample = 1;
173 // Update meters if monitoring
174 //printf("RecordAudio::run 2 %d %d %d %d\n", record->monitor_audio, record_thread->batch_done(), record_thread->loop_done(), grab_result);
175 if(record->monitor_audio &&
179 record->record_monitor->window->lock_window();
180 for(channel = 0; channel < record_channels; channel++)
182 record->record_monitor->window->meters->meters.values[channel]->update(max[channel], over[channel]);
184 record->record_monitor->window->unlock_window();
188 //printf("RecordAudio::run 2\n");
189 // Write file if writing
190 if(!record_thread->monitor)
192 fragment_position += fragment_size;
194 if(fragment_position >= buffer_size)
200 //printf("RecordAudio::run 2 %f\n", record->current_display_position());
201 if(!record->default_asset->video_data)
202 gui->update_position(record->current_display_position(),
203 record->current_display_length());
205 gui->update_clipped_samples(++total_clipped_samples);
207 if(!record_thread->monitor &&
210 !record->default_asset->video_data)
212 // handle different recording modes
213 switch(record->get_current_batch()->record_mode)
216 if(record->current_display_position() > *record->current_duration())
220 if(record->current_display_position() > *record->current_duration())
223 case RECORD_SCENETOSCENE:
228 //printf("RecordAudio::run 4 %d %d\n", batch_done, write_result);
231 //printf("RecordAudio::run 4\n");
232 if(write_result && !record->default_asset->video_data)
234 ErrorBox error_box(PROGRAM_NAME ": Error",
235 mwindow->gui->get_abs_cursor_x(),
236 mwindow->gui->get_abs_cursor_y());
237 error_box.create_objects(_("No space left on disk."));
238 error_box.run_window();
241 //printf("RecordAudio::run 10\n");
243 if(!record_thread->monitor)
250 // Delete the fake buffer.
251 for(int i = 0; i < record_channels; i++)
253 record->record_monitor->window->meters->meters.values[i]->reset();
259 //printf("RecordAudio::run 11\n");
263 for(channel = 0; channel < record_channels; channel++)
265 record->record_monitor->window->meters->meters.values[channel]->reset();
267 //printf("RecordAudio::run 12\n");
269 gui->unlock_window();
272 //printf("RecordAudio::run 5\n");
275 void RecordAudio::write_buffer(int skip_new)
277 // block until buffer is ready for writing
278 write_result = record->file->write_audio_buffer(fragment_position);
279 // Defeat errors if video
280 if(record->default_asset->video_data) write_result = 0;
281 fragment_position = 0;
282 if(!skip_new && !write_result) input = record->file->get_audio_buffer();
285 int64_t RecordAudio::sync_position()
290 //printf("RecordAudio::sync_position 1\n");
292 if(!mwindow->edl->session->record_software_position)
294 //printf("RecordAudio::sync_position 1\n");
295 result = record->adevice->current_position();
299 //printf("RecordAudio::sync_position 1 %d\n", record->get_current_batch()->session_samples);
300 result = record->get_current_batch()->session_samples +
301 timer.get_scaled_difference(record->default_asset->sample_rate);
304 //printf("RecordAudio::sync_position 2\n");