4 * Copyright (C) 2008 Adam Williams <broadcast at earthling dot net>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 #include "audiodevice.h"
25 #include "bcsignals.h"
27 #include "condition.h"
29 #include "edlsession.h"
32 #include "filethread.h"
34 #include "meterpanel.h"
37 #include "mwindowgui.h"
38 #include "preferences.h"
40 #include "recordaudio.h"
41 #include "recordconfig.h"
42 #include "recordgui.h"
43 #include "recordmonitor.h"
44 #include "renderengine.h"
48 RecordAudio::RecordAudio(MWindow *mwindow, Record *record)
51 this->mwindow = mwindow;
52 this->record = record;
53 this->gui = record->record_gui;
54 trigger_lock = new Condition(0, "RecordAudio::trigger_lock");
55 pause_record_lock = new Condition(0, "RecordAudio::pause_record_lock");
56 record_paused_lock = new Condition(0, "RecordAudio::record_paused_lock");
60 RecordAudio::~RecordAudio()
64 delete pause_record_lock;
65 delete record_paused_lock;
68 void RecordAudio::reset_parameters()
77 fragment_position = 0;
80 write_buffer_samples = 0;
82 pause_record_lock->reset();
83 record_paused_lock->reset();
84 trigger_lock->reset();
88 void RecordAudio::arm_recording()
94 void RecordAudio::start_recording()
96 trigger_lock->unlock();
99 void RecordAudio::set_monitoring(int mode)
101 if( record->adevice )
102 record->adevice->set_monitoring(mode);
105 int RecordAudio::stop_recording()
108 if( record->adevice )
109 record->adevice->interrupt_crash();
114 void RecordAudio::delete_buffer()
117 for( int i=0; i<buffer_channels; ++i )
124 fragment_position = 0;
127 void RecordAudio::set_write_buffer_samples(int samples)
129 write_buffer_samples = samples;
132 Samples **RecordAudio::get_buffer()
134 Samples **result = 0;
135 fragment_position = 0;
136 record->file_lock->lock();
137 writing_file = record->writing_file > 0 && record->do_audio ? 1 : 0;
139 channels = record->file->asset->channels;
140 result = record->file->get_audio_buffer();
142 record->file_lock->unlock();
144 // when not writing, buffer is only one fragment
145 int new_fragment_samples = record->get_fragment_samples();
146 if( new_fragment_samples != buffer_samples )
148 int record_channels = record->default_asset->channels;
149 if( !buffer || buffer_channels != record_channels ) {
151 Samples **new_buffer = new Samples *[record_channels];
152 if( buffer_channels < record_channels ) {
153 for( ; i<buffer_channels; ++i )
154 new_buffer[i] = buffer[i];
155 while( i < record_channels ) // more channels
156 new_buffer[i++] = new Samples(new_fragment_samples);
159 for( ; i<record_channels; ++i )
160 new_buffer[i] = buffer[i];
161 while( i < buffer_channels ) // fewer channels
166 buffer_channels = record_channels;
167 fragment_samples = new_fragment_samples;
168 buffer_samples = new_fragment_samples;
170 set_write_buffer_samples(0);
171 channels = record->default_asset->channels;
178 void RecordAudio::config_update()
180 AudioDevice *adevice = record->adevice;
181 adevice->stop_audio(0);
182 adevice->config_update();
183 int channels = adevice->get_ichannels();
184 int sample_rate = adevice->get_irate();
185 int bits = adevice->get_ibits();
186 Asset *rf_asset = SESSION->recording_format;
187 Asset *df_asset = record->default_asset;
188 rf_asset->channels = df_asset->channels = channels;
189 rf_asset->sample_rate = df_asset->sample_rate = sample_rate;
190 rf_asset->bits = df_asset->bits = bits;
191 adevice->start_recording();
194 void RecordAudio::run()
199 trigger_lock->lock("RecordAudio::run");
201 while( !done && !write_result ) {
202 if( recording_paused ) {
206 pause_record_lock->unlock();
207 record_paused_lock->lock();
208 set_monitoring(record->monitor_audio);
211 AudioDevice *adevice = record->adevice;
213 input = get_buffer();
214 if( !input || !channels ) {
215 printf("RecordAudio::run: no input/channels\n");
219 int over[channels]; double max[channels];
220 grab_result = !input ? 1 :
221 adevice->read_buffer(input, channels,
222 fragment_samples, over, max, fragment_position);
224 if( adevice->config_updated() ) {
228 record->update_position();
229 set_monitoring(record->monitor_audio);
230 record->record_monitor->redraw();
235 int samplerate = record->default_asset->sample_rate;
236 int delay = samplerate ? (1000 * fragment_samples) / samplerate : 250;
237 if( delay > 250 ) delay = 250;
241 write_buffer(fragment_samples);
242 record->current_sample += fragment_samples;
243 record->total_samples += fragment_samples;
244 if( !record->writing_file || !record->is_behind() )
245 gui->update_audio(channels,max,over);
246 record->check_batch_complete();
249 if( write_result && !record->default_asset->video_data ) {
250 ErrorBox error_box(_(PROGRAM_NAME ": Error"),
251 mwindow->gui->get_abs_cursor_x(1),
252 mwindow->gui->get_abs_cursor_y(1));
253 error_box.create_objects(_("No space left on disk."));
254 error_box.run_window();
258 flush_buffer(); // write last buffer
262 int RecordAudio::flush_buffer()
264 record->file_lock->lock();
265 if( record->writing_file ) {
266 record->written_samples += fragment_position;
268 write_result = (record->file->write_audio_buffer(fragment_position), 0); // HACK
269 // defeat audio errors if recording video
270 if( record->default_asset->video_data ) write_result = 0;
273 record->file_lock->unlock();
275 fragment_position = 0;
279 int RecordAudio::write_buffer(int samples)
282 fragment_position += samples;
283 if( fragment_position >= write_buffer_samples )
284 result = flush_buffer();
289 void RecordAudio::pause_recording()
291 recording_paused = 1;
292 record->adevice->interrupt_recording();
293 pause_record_lock->lock();
296 void RecordAudio::resume_recording()
298 recording_paused = 0;
299 record->adevice->resume_recording();
300 record_paused_lock->unlock();