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()
66 void RecordAudio::reset_parameters()
75 fragment_position = 0;
78 write_buffer_samples = 0;
80 pause_record_lock->reset();
81 record_paused_lock->reset();
82 trigger_lock->reset();
86 int RecordAudio::arm_recording()
93 void RecordAudio::start_recording()
95 trigger_lock->unlock();
98 void RecordAudio::set_monitoring(int mode)
100 if( record->adevice )
101 record->adevice->set_monitoring(mode);
104 int RecordAudio::stop_recording()
107 if( record->adevice )
108 record->adevice->interrupt_crash();
113 void RecordAudio::delete_buffer()
116 for( int i=0; i<buffer_channels; ++i )
123 fragment_position = 0;
126 void RecordAudio::set_write_buffer_samples(int samples)
128 write_buffer_samples = samples;
131 Samples **RecordAudio::get_buffer()
133 Samples **result = 0;
134 fragment_position = 0;
135 record->file_lock->lock();
136 writing_file = record->writing_file > 0 && record->do_audio ? 1 : 0;
138 channels = record->file->asset->channels;
139 result = record->file->get_audio_buffer();
141 record->file_lock->unlock();
143 // when not writing, buffer is only one fragment
144 int new_fragment_samples = record->get_fragment_samples();
145 if( new_fragment_samples != buffer_samples )
147 int record_channels = record->default_asset->channels;
148 if( !buffer || buffer_channels != record_channels ) {
150 Samples **new_buffer = new Samples *[record_channels];
151 if( buffer_channels < record_channels ) {
152 for( ; i<buffer_channels; ++i )
153 new_buffer[i] = buffer[i];
154 while( i < record_channels ) // more channels
155 new_buffer[i++] = new Samples(new_fragment_samples);
158 for( ; i<record_channels; ++i )
159 new_buffer[i] = buffer[i];
160 while( i < buffer_channels ) // fewer channels
165 buffer_channels = record_channels;
166 fragment_samples = new_fragment_samples;
167 buffer_samples = new_fragment_samples;
169 set_write_buffer_samples(0);
170 channels = record->default_asset->channels;
177 void RecordAudio::config_update()
179 AudioDevice *adevice = record->adevice;
180 adevice->stop_audio(0);
181 adevice->config_update();
182 int channels = adevice->get_ichannels();
183 int sample_rate = adevice->get_irate();
184 int bits = adevice->get_ibits();
185 Asset *rf_asset = SESSION->recording_format;
186 Asset *df_asset = record->default_asset;
187 rf_asset->channels = df_asset->channels = channels;
188 rf_asset->sample_rate = df_asset->sample_rate = sample_rate;
189 rf_asset->bits = df_asset->bits = bits;
190 adevice->start_recording();
193 void RecordAudio::run()
198 trigger_lock->lock("RecordAudio::run");
200 while( !done && !write_result ) {
201 if( recording_paused ) {
205 pause_record_lock->unlock();
206 record_paused_lock->lock();
207 set_monitoring(record->monitor_audio);
210 AudioDevice *adevice = record->adevice;
212 input = get_buffer();
213 if( !input || !channels ) {
214 printf("RecordAudio::run: no input/channels\n");
218 int over[channels]; double max[channels];
219 grab_result = !input ? 1 :
220 adevice->read_buffer(input, channels,
221 fragment_samples, over, max, fragment_position);
223 if( adevice->config_updated() ) {
227 record->update_position();
228 set_monitoring(record->monitor_audio);
229 record->record_monitor->redraw();
234 int samplerate = record->default_asset->sample_rate;
235 int delay = samplerate ? (1000 * fragment_samples) / samplerate : 250;
236 if( delay > 250 ) delay = 250;
240 write_buffer(fragment_samples);
241 record->current_sample += fragment_samples;
242 record->total_samples += fragment_samples;
243 if( !record->writing_file || !record->is_behind() )
244 gui->update_audio(channels,max,over);
245 record->check_batch_complete();
248 if( write_result && !record->default_asset->video_data ) {
249 ErrorBox error_box(_(PROGRAM_NAME ": Error"),
250 mwindow->gui->get_abs_cursor_x(1),
251 mwindow->gui->get_abs_cursor_y(1));
252 error_box.create_objects(_("No space left on disk."));
253 error_box.run_window();
257 flush_buffer(); // write last buffer
261 int RecordAudio::flush_buffer()
263 record->file_lock->lock();
264 if( record->writing_file ) {
265 record->written_samples += fragment_position;
267 write_result = (record->file->write_audio_buffer(fragment_position), 0); // HACK
268 // defeat audio errors if recording video
269 if( record->default_asset->video_data ) write_result = 0;
272 record->file_lock->unlock();
274 fragment_position = 0;
278 int RecordAudio::write_buffer(int samples)
281 fragment_position += samples;
282 if( fragment_position >= write_buffer_samples )
283 result = flush_buffer();
288 void RecordAudio::pause_recording()
290 recording_paused = 1;
291 record->adevice->interrupt_recording();
292 pause_record_lock->lock();
295 void RecordAudio::resume_recording()
297 recording_paused = 0;
298 record->adevice->resume_recording();
299 record_paused_lock->unlock();