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
28 #include <sys/ioctl.h>
32 #include "audioalsa.inc"
33 #include "audioconfig.inc"
34 #include "audiodevice.inc"
35 #include "audiodvb.inc"
36 #include "audioesound.inc"
37 #include "audiooss.inc"
38 #include "audiopulse.inc"
39 #include "audiov4l2mpeg.inc"
40 #include "bctimer.inc"
42 #include "condition.inc"
43 #include "dcoffset.inc"
44 #include "device1394output.inc"
45 #include "devicedvbinput.inc"
46 #include "devicempeginput.inc"
47 #include "maxchannels.h"
49 #include "mwindow.inc"
50 #include "preferences.inc"
51 #include "recordgui.inc"
52 #include "samples.inc"
55 #include "videodevice.inc"
57 #include "audio1394.inc"
58 #include "device1394output.inc"
59 #include "vdevice1394.inc"
62 class AudioThread : public Thread
65 void (AudioDevice::*arun)();
66 void (AudioDevice::*aend)();
67 Condition *startup_lock;
70 AudioThread(AudioDevice *device,
71 void (AudioDevice::*arun)(),
72 void (AudioDevice::*aend)());
82 friend class RecordAudio;
84 // MWindow is required where global input is used, to get the pointer.
85 AudioDevice(MWindow *mwindow = 0);
88 friend class AudioALSA;
89 friend class AudioMPEG;
90 friend class AudioDVB;
91 friend class AudioV4L2MPEG;
92 friend class AudioOSS;
93 friend class AudioPulse;
94 friend class AudioESound;
95 friend class Audio1394;
96 friend class VDevice1394;
97 friend class Device1394Output;
98 friend class DeviceMPEGInput;
99 friend class DeviceDVBInput;
100 friend class DeviceV4L2Input;
102 int open_input(AudioInConfig *config,
103 VideoInConfig *vconfig,
108 int open_output(AudioOutConfig *config,
113 int open_monitor(AudioOutConfig *config, int mode);
116 // ================================ recording
118 // read from the record device
119 // Conversion between double and int is done in AudioDevice
120 int read_buffer(Samples **input, int channels,
121 int samples, int *over, double *max, int input_offset = 0);
122 void start_recording();
123 // If a firewire device crashed
124 int interrupt_crash();
126 // ================================== dc offset
128 // writes to whichever buffer is free or blocks until one becomes free
129 int write_buffer(double **output, int channels, int samples, double bfr_time=-1.);
131 int stop_audio(int wait);
133 // After the last buffer is written call this to terminate.
134 // A separate buffer for termination is required since the audio device can be
135 // finished without writing a single byte
136 int set_last_buffer();
138 // start the thread processing buffers
139 int start_playback();
140 int is_monitoring() { return monitoring && monitor_open; }
141 void set_monitoring(int mode);
142 // record menu auto config update
143 void auto_update(int channels, int samplerate, int bits);
144 int config_updated();
145 void config_update();
146 // record raw stream on file descr fd, to close use fd=-1
147 // bsz records up to bsz bytes of past buffer data in first_write
148 int start_toc(const char *path, const char *toc_path);
149 int start_record(int fd, int bsz=0);
151 int total_audio_channels();
152 DeviceMPEGInput *mpeg_device();
154 // interrupt the playback thread
155 int interrupt_playback();
156 // drop the current record buffer and wait for resume
157 void interrupt_recording();
158 void resume_recording();
159 void set_play_dither(int status);
160 void set_rec_gain(double gain=1.);
161 void set_play_gain(double gain=1.);
162 // set software positioning on or off
163 void set_software_positioning(int status = 1);
164 // total samples played
165 // + audio offset from configuration if playback
166 int64_t current_position();
167 int64_t samples_output();
168 double get_itimestamp();
169 double get_otimestamp();
170 double device_timestamp();
171 void set_vdevice(VideoDevice *vdevice) { this->vdevice = vdevice; }
172 int get_interrupted() { return playback_interrupted; }
173 int get_ichannels() { return in_channels; }
174 int get_ochannels() { return out_channels; }
175 int get_ibits() { return in_bits; }
176 int get_obits() { return out_bits; }
177 int get_irate() { return in_samplerate; }
178 int get_orate() { return out_samplerate; }
179 int get_irealtime() { return in_realtime; }
180 int get_orealtime() { return out_realtime; }
181 int get_device_buffer() { return device_buffer; }
182 int64_t get_samples_written() { return total_samples_written; }
183 int64_t get_samples_output() { return total_samples_output; }
184 int64_t get_samples_read() { return total_samples_read; }
185 int64_t get_samples_input() { return total_samples_input; }
186 int get_idmix() { return in51_2; }
187 int get_odmix() { return out51_2; }
188 int get_play_gain() { return play_gain; }
189 int get_record_gain() { return rec_gain; }
194 // Create a lowlevel driver out of the driver ID
195 int create_lowlevel(AudioLowLevel* &lowlevel, int driver,int in);
196 int arm_buffer(int buffer, double **output, int channels,
197 int samples, int64_t sample_position, double bfr_time);
198 int read_inactive() {
199 int result = !is_recording || recording_interrupted || in_config_updated;
202 // Override configured parameters depending on the driver
203 int in_samplerate, out_samplerate;
204 int in_bits, out_bits;
205 int in_channels, out_channels;
206 int in_samples, out_samples;
207 int in_realtime, out_realtime;
209 int in_config_updated;
213 // Video device to pass data to if the same device handles video
214 VideoDevice *vdevice;
215 // bits in output file 1 or 0
216 int rec_dither, play_dither;
217 double rec_gain, play_gain;
221 // background loop for playback
222 AudioThread *audio_out;
225 void stop_output(int wait);
226 // background loop for recording
227 AudioThread *audio_in;
231 // writes input to output, follows input config
232 void monitor_buffer(Samples **input, int channels,
233 int samples, int ioffset, double bfr_time);
236 class input_buffer_t {
241 } input[TOTAL_AUDIO_BUFFERS];
242 class output_buffer_t {
247 int64_t sample_position;
249 Condition *play_lock;
251 } output[TOTAL_AUDIO_BUFFERS];
254 // Get buffer_lock to delay before locking to allow read_buffer to lock it.
256 Condition *polling_lock;
260 double last_buffer_time;
261 int position_correction;
263 // prevent the counter from going backwards
265 Timer *playback_timer;
270 int global_timer_started;
271 int software_position_info;
272 int playback_interrupted;
273 int recording_interrupted;
274 int idriver, odriver;
276 // Multiple data paths can be opened simultaneously by Record when monitoring
277 AudioLowLevel *lowlevel_in, *lowlevel_out;
278 AudioOutConfig *out_config;
279 AudioInConfig *in_config;
280 // Extra configuration if shared with video
281 VideoInConfig *vconfig;
283 // Buffer being used by the hardware
284 int input_buffer_count;
286 int input_buffer_out;
287 int input_buffer_offset;
288 int output_buffer_num;
289 // for position information
290 int64_t total_samples_read;
291 int64_t total_samples_input;
292 int64_t total_samples_written;
293 int64_t total_samples_output;
301 AudioLowLevel(AudioDevice *device);
302 virtual ~AudioLowLevel();
304 virtual int open_input() { return 1; };
305 virtual int open_output() { return 1; };
306 virtual int close_all() { return 1; };
307 virtual int interrupt_crash() { return 0; };
308 virtual int64_t device_position() { return -1; };
309 virtual int64_t samples_output() { return -1; };
310 virtual int write_buffer(char *buffer, int size) { return 1; };
311 virtual int read_buffer(char *buffer, int size) { return -1; };
312 virtual int flush_device() { return 1; };
313 virtual int interrupt_playback() { return 1; };
314 virtual double device_timestamp() {
315 struct timeval tv; gettimeofday(&tv, 0);
316 return tv.tv_sec + tv.tv_usec / 1000000.0;
318 virtual int start_toc(const char *path, const char *toc_path) { return -1; }
319 virtual int start_record(int fd, int bsz=0) { return -1; }
320 virtual int stop_record() { return -1; }
321 virtual int total_audio_channels() {
322 return device ? device->get_ichannels() : 0;
324 virtual DeviceMPEGInput *mpeg_device() { return 0; }