00001 #ifdef HAVE_FIREWIRE
00002 #include "audio1394.h"
00003 #endif
00004 #include "audioalsa.h"
00005 #include "audiocine.h"
00006 #include "audiodevice.h"
00007 #include "audiodvb.h"
00008 #include "audioesound.h"
00009 #include "audiooss.h"
00010 #include "bctimer.h"
00011 #include "condition.h"
00012 #include "dcoffset.h"
00013 #include "mutex.h"
00014 #include "playbackconfig.h"
00015 #include "preferences.h"
00016 #include "recordconfig.h"
00017 #include "sema.h"
00018
00019
00020 AudioLowLevel::AudioLowLevel(AudioDevice *device)
00021 {
00022 this->device = device;
00023 }
00024
00025 AudioLowLevel::~AudioLowLevel()
00026 {
00027 }
00028
00029
00030
00031
00032
00033
00034 AudioDevice::AudioDevice(MWindow *mwindow)
00035 : Thread(1, 0, 0)
00036 {
00037 initialize();
00038 this->mwindow = mwindow;
00039 this->out_config = new AudioOutConfig(0);
00040 this->in_config = new AudioInConfig;
00041 this->vconfig = new VideoInConfig;
00042 startup_lock = new Condition(0, "AudioDevice::startup_lock");
00043 duplex_lock = new Condition(0, "AudioDevice::duplex_lock");
00044 timer_lock = new Mutex("AudioDevice::timer_lock");
00045 buffer_lock = new Mutex("AudioDevice::buffer_lock");
00046 polling_lock = new Condition(0, "AudioDevice::polling_lock");
00047 playback_timer = new Timer;
00048 record_timer = new Timer;
00049 for(int i = 0; i < TOTAL_BUFFERS; i++)
00050 {
00051 play_lock[i] = new Sema(0, "AudioDevice::play_lock");
00052 arm_lock[i] = new Sema(1, "AudioDevice::arm_lock");
00053 }
00054 }
00055
00056 AudioDevice::~AudioDevice()
00057 {
00058 delete out_config;
00059 delete in_config;
00060 delete vconfig;
00061 delete startup_lock;
00062 delete duplex_lock;
00063 delete timer_lock;
00064 for(int i = 0; i < TOTAL_BUFFERS; i++)
00065 {
00066 delete play_lock[i];
00067 delete arm_lock[i];
00068 }
00069 delete playback_timer;
00070 delete record_timer;
00071 delete buffer_lock;
00072 delete polling_lock;
00073 }
00074
00075 int AudioDevice::initialize()
00076 {
00077 record_before_play = 0;
00078 r = w = d = 0;
00079
00080 for(int i = 0; i < TOTAL_BUFFERS; i++)
00081 {
00082 output_buffer[i] = 0;
00083 input_buffer[i] = 0;
00084 buffer_size[i] = 0;
00085 last_buffer[i] = 0;
00086 }
00087
00088 duplex_init = 0;
00089 rec_dither = play_dither = 0;
00090 software_position_info = 0;
00091 arm_buffer_num = 0;
00092 is_playing_back = 0;
00093 is_recording = 0;
00094 last_buffer_size = 0;
00095 total_samples = 0;
00096 position_correction = 0;
00097 last_position = 0;
00098 interrupt = 0;
00099 lowlevel_in = lowlevel_out = lowlevel_duplex = 0;
00100 vdevice = 0;
00101 sharing = 0;
00102 total_samples_read = 0;
00103 out_realtime = 0;
00104 duplex_realtime = 0;
00105 in_realtime = 0;
00106 read_waiting = 0;
00107 return 0;
00108 }
00109
00110 int AudioDevice::create_lowlevel(AudioLowLevel* &lowlevel, int driver)
00111 {
00112 this->driver = driver;
00113
00114
00115 if(!lowlevel)
00116 {
00117 switch(driver)
00118 {
00119 #ifdef HAVE_OSS
00120 case AUDIO_OSS:
00121 case AUDIO_OSS_ENVY24:
00122 lowlevel = new AudioOSS(this);
00123 break;
00124 #endif
00125
00126 #ifdef HAVE_ESOUND
00127 case AUDIO_ESOUND:
00128 lowlevel = new AudioESound(this);
00129 break;
00130 #endif
00131 case AUDIO_NAS:
00132 break;
00133
00134 #ifdef HAVE_ALSA
00135 case AUDIO_ALSA:
00136 lowlevel = new AudioALSA(this);
00137 break;
00138 #endif
00139
00140 #ifdef HAVE_FIREWIRE
00141 case AUDIO_1394:
00142 case AUDIO_DV1394:
00143 case AUDIO_IEC61883:
00144 lowlevel = new Audio1394(this);
00145 break;
00146 #endif
00147
00148
00149
00150 case AUDIO_DVB:
00151 lowlevel = new AudioDVB(this);
00152 break;
00153
00154
00155
00156 case AUDIO_CINE:
00157 lowlevel = new AudioCine(this);
00158 break;
00159 }
00160 }
00161 return 0;
00162 }
00163
00164 int AudioDevice::open_input(AudioInConfig *config,
00165 VideoInConfig *vconfig,
00166 int rate,
00167 int samples,
00168 int channels,
00169 int realtime)
00170 {
00171 r = 1;
00172 duplex_init = 0;
00173 this->in_config->copy_from(config);
00174 this->vconfig->copy_from(vconfig);
00175 in_samplerate = rate;
00176 in_samples = samples;
00177 in_realtime = realtime;
00178 in_channels = channels;
00179 create_lowlevel(lowlevel_in, config->driver);
00180 lowlevel_in->open_input();
00181 record_timer->update();
00182 return 0;
00183 }
00184
00185 int AudioDevice::open_output(AudioOutConfig *config,
00186 int rate,
00187 int samples,
00188 int channels,
00189 int realtime)
00190 {
00191 w = 1;
00192 duplex_init = 0;
00193 *this->out_config = *config;
00194 out_samplerate = rate;
00195 out_samples = samples;
00196 out_channels = channels;
00197 out_realtime = realtime;
00198 create_lowlevel(lowlevel_out, config->driver);
00199 return lowlevel_out ? lowlevel_out->open_output() : 0;
00200 }
00201
00202
00203 int AudioDevice::interrupt_crash()
00204 {
00205 if(lowlevel_in) return lowlevel_in->interrupt_crash();
00206 return 0;
00207 }
00208
00209
00210 int AudioDevice::close_all()
00211 {
00212 if(is_recording)
00213 {
00214 is_recording = 0;
00215 read_waiting = 1;
00216 Thread::join();
00217 }
00218
00219
00220 if(lowlevel_in) lowlevel_in->close_all();
00221 if(lowlevel_out) lowlevel_out->close_all();
00222 if(lowlevel_duplex) lowlevel_duplex->close_all();
00223
00224 reset_output();
00225 for(int i = 0; i < TOTAL_BUFFERS; i++)
00226 {
00227 delete [] input_buffer[i];
00228 input_buffer[i] = 0;
00229 }
00230
00231 is_recording = 0;
00232 rec_dither = play_dither = 0;
00233 software_position_info = position_correction = last_buffer_size = 0;
00234 r = w = d = 0;
00235 duplex_init = 0;
00236 vdevice = 0;
00237 sharing = 0;
00238
00239 if(lowlevel_in)
00240 {
00241 delete lowlevel_in;
00242 lowlevel_in = 0;
00243 }
00244
00245 if(lowlevel_out)
00246 {
00247 delete lowlevel_out;
00248 lowlevel_out = 0;
00249 }
00250
00251 if(lowlevel_duplex)
00252 {
00253 delete lowlevel_duplex;
00254 lowlevel_duplex = 0;
00255 }
00256
00257 return 0;
00258 }
00259
00260 int AudioDevice::set_vdevice(VideoDevice *vdevice)
00261 {
00262 this->vdevice = vdevice;
00263 return 0;
00264 }
00265
00266
00267 int AudioDevice::get_ichannels()
00268 {
00269 if(r) return in_channels;
00270 else if(d) return duplex_channels;
00271 else return 0;
00272 }
00273
00274 int AudioDevice::get_ibits()
00275 {
00276 if(r) return in_bits;
00277 else if(d) return duplex_bits;
00278 return 0;
00279 }
00280
00281
00282 int AudioDevice::get_obits()
00283 {
00284 if(w) return out_bits;
00285 else if(d) return duplex_bits;
00286 return 0;
00287 }
00288
00289 int AudioDevice::get_ochannels()
00290 {
00291 if(w) return out_channels;
00292 else if(d) return duplex_channels;
00293 return 0;
00294 }
00295
00296 AudioLowLevel* AudioDevice::get_lowlevel_out()
00297 {
00298 if(w) return lowlevel_out;
00299 else if(d) return lowlevel_duplex;
00300 return 0;
00301 }
00302
00303 AudioLowLevel* AudioDevice::get_lowlevel_in()
00304 {
00305 if(r) return lowlevel_in;
00306 else if(d) return lowlevel_duplex;
00307 return 0;
00308 }
00309
00310 int AudioDevice::get_irate()
00311 {
00312 if(r) return in_samplerate;
00313 else
00314 if(d) return duplex_samplerate;
00315 }
00316
00317 int AudioDevice::get_orealtime()
00318 {
00319 if(w) return out_realtime;
00320 else
00321 if(d) return duplex_realtime;
00322 return 0;
00323 }
00324
00325 int AudioDevice::get_irealtime()
00326 {
00327 if(r) return in_realtime;
00328 else
00329 if(d) return duplex_realtime;
00330 return 0;
00331 }
00332
00333
00334 int AudioDevice::get_orate()
00335 {
00336 if(w) return out_samplerate;
00337 else if(d) return duplex_samplerate;
00338 return 0;
00339 }
00340
00341 int AudioDevice::get_interrupted()
00342 {
00343 return interrupt;
00344 }
00345
00346 int AudioDevice::get_device_buffer()
00347 {
00348 return device_buffer;
00349 }
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361 void AudioDevice::run()
00362 {
00363 if(w)
00364 run_output();
00365 else
00366 if(r)
00367 run_input();
00368 }
00369