r665: Merged the official release 2.0.
[cinelerra_cv.git] / cinelerra / audiodevice.C
blobbd36939cc3a919a048f6be5f92377bc94cf30473
1 #include "audio1394.h"
2 #include "audioalsa.h"
3 #include "audiodevice.h"
4 #include "audioesound.h"
5 #include "audiooss.h"
6 #include "condition.h"
7 #include "dcoffset.h"
8 #include "mutex.h"
9 #include "playbackconfig.h"
10 #include "preferences.h"
11 #include "recordconfig.h"
12 #include "sema.h"
16 AudioLowLevel::AudioLowLevel(AudioDevice *device)
18         this->device = device;
21 AudioLowLevel::~AudioLowLevel()
30 AudioDevice::AudioDevice()
31  : Thread(1, 0, 0)
33         initialize();
34         this->out_config = new AudioOutConfig(0);
35         this->in_config = new AudioInConfig;
36         this->vconfig = new VideoInConfig;
37         startup_lock = new Condition(0, "AudioDevice::startup_lock");
38         duplex_lock = new Condition(0, "AudioDevice::duplex_lock");
39         timer_lock = new Mutex("AudioDevice::timer_lock");
40         for(int i = 0; i < TOTAL_BUFFERS; i++)
41         {
42                 play_lock[i] = new Sema(0, "AudioDevice::play_lock");
43                 arm_lock[i] = new Sema(1, "AudioDevice::arm_lock");
44         }
45         dc_offset_thread = new DC_Offset;
48 AudioDevice::~AudioDevice()
50         delete out_config;
51         delete in_config;
52         delete vconfig;
53         delete startup_lock;
54         delete duplex_lock;
55         delete timer_lock;
56         for(int i = 0; i < TOTAL_BUFFERS; i++)
57         {
58                 delete play_lock[i];
59                 delete arm_lock[i];
60         }
61         delete dc_offset_thread;
64 int AudioDevice::initialize()
66         record_before_play = 0;
67         r = w = d = 0;
69         for(int i = 0; i < TOTAL_BUFFERS; i++)
70         {
71                 buffer[i] = 0;
72                 buffer_size[i] = 0;
73                 last_buffer[i] = 0;
74         }
76         input_buffer = 0;
77         duplex_init = 0;
78         rec_dither = play_dither = 0;
79         software_position_info = 0;
80         arm_buffer_num = 0;
81         is_playing_back = 0;
82         is_recording = 0;
83         last_buffer_size = total_samples = position_correction = 0;
84         last_position = 0;
85         interrupt = 0;
86         lowlevel_in = lowlevel_out = lowlevel_duplex = 0;
87         vdevice = 0;
88         sharing = 0;
89         total_samples_read = 0;
90         out_realtime = 0;
91         duplex_realtime = 0;
92         return 0;
95 int AudioDevice::create_lowlevel(AudioLowLevel* &lowlevel, int driver)
97         this->driver = driver;
100         if(!lowlevel)
101         {
102                 switch(driver)
103                 {
104 #ifdef HAVE_OSS
105                         case AUDIO_OSS:
106                         case AUDIO_OSS_ENVY24:
107                                 lowlevel = new AudioOSS(this);
108                                 break;
109 #endif
111 #ifdef HAVE_ESOUND
112                         case AUDIO_ESOUND:
113                                 lowlevel = new AudioESound(this);
114                                 break;
115 #endif
116                         case AUDIO_NAS:
117                                 break;
119 #ifdef HAVE_ALSA
120                         case AUDIO_ALSA:
121                                 lowlevel = new AudioALSA(this);
122                                 break;
123 #endif
125 #ifdef HAVE_FIREWIRE    
126                         case AUDIO_1394:
127                         case AUDIO_DV1394:
128                         case AUDIO_IEC61883:
129                                 lowlevel = new Audio1394(this);
130                                 break;
131 #endif
132                 }
133         }
134         return 0;
137 int AudioDevice::open_input(AudioInConfig *config, 
138         VideoInConfig *vconfig, 
139         int rate, 
140         int samples)
142         r = 1;
143         duplex_init = 0;
144         this->in_config->copy_from(config);
145         this->vconfig->copy_from(vconfig);
146 //printf("AudioDevice::open_input %s\n", this->in_config->oss_in_device[0]);
147         in_samplerate = rate;
148         in_samples = samples;
149         create_lowlevel(lowlevel_in, config->driver);
150         lowlevel_in->open_input();
151         record_timer.update();
152         return 0;
155 int AudioDevice::open_output(AudioOutConfig *config, 
156         int rate, 
157         int samples, 
158         int realtime)
160         w = 1;
161         duplex_init = 0;
162         *this->out_config = *config;
163         out_samplerate = rate;
164         out_samples = samples;
165         out_realtime = realtime;
166         create_lowlevel(lowlevel_out, config->driver);
167         lowlevel_out->open_output();
168         return 0;
171 int AudioDevice::open_duplex(AudioOutConfig *out_config, int rate, int samples, int realtime)
173         d = 1;
174         duplex_init = 1;        // notify playback routines to test the duplex lock
175         *this->out_config = *out_config;
176         duplex_samplerate = rate;
177         duplex_samples = samples;
178         duplex_channels = 0;
179         duplex_realtime = realtime;
180         for(int i = 0; i < MAXDEVICES; i++)
181         {
182                 duplex_channels += out_config->oss_out_channels[i];
183         }
184         create_lowlevel(lowlevel_duplex, out_config->driver);
185         lowlevel_duplex->open_duplex();
186         playback_timer.update();
187         record_timer.update();
188         return 0;
192 int AudioDevice::interrupt_crash()
194         if(lowlevel_in) return lowlevel_in->interrupt_crash();
195         return 0;
199 int AudioDevice::close_all()
201         if(lowlevel_in) lowlevel_in->close_all();
202         if(lowlevel_out) lowlevel_out->close_all();
203         if(lowlevel_duplex) lowlevel_duplex->close_all();
205         reset_output();
206         if(input_buffer) 
207         {
208                 delete [] input_buffer; 
209                 input_buffer = 0; 
210         }
211         
212         is_recording = 0;
213         rec_dither = play_dither = 0;
214         software_position_info = position_correction = last_buffer_size = 0;
215         r = w = d = 0;
216         duplex_init = 0;
217         vdevice = 0;
218         sharing = 0;
220         if(lowlevel_in)
221         {
222                 delete lowlevel_in;
223                 lowlevel_in = 0;
224         }
225         if(lowlevel_out)
226         {
227                 delete lowlevel_out;
228                 lowlevel_out = 0;
229         }
230         if(lowlevel_duplex)
231         {
232                 delete lowlevel_duplex;
233                 lowlevel_duplex = 0;
234         }
235         return 0;
238 int AudioDevice::set_vdevice(VideoDevice *vdevice)
240         this->vdevice = vdevice;
241         return 0;
245 int AudioDevice::get_ichannels()
247         if(r) return in_channels;
248         else if(d) return duplex_channels;
249         else return 0;
252 int AudioDevice::get_ibits()
254         if(r) return in_bits;
255         else if(d) return duplex_bits;
256         return 0;
260 int AudioDevice::get_obits()
262         if(w) return out_bits;
263         else if(d) return duplex_bits;
264         return 0;
267 int AudioDevice::get_ochannels()
269         if(w) return out_channels;
270         else if(d) return duplex_channels;
271         return 0;
274 AudioLowLevel* AudioDevice::get_lowlevel_out()
276         if(w) return lowlevel_out;
277         else if(d) return lowlevel_duplex;
278         return 0;
281 AudioLowLevel* AudioDevice::get_lowlevel_in()
283         if(r) return lowlevel_in;
284         else if(d) return lowlevel_duplex;
285         return 0;
288 int AudioDevice::get_irate()
290         if(r) return in_samplerate;
291         else
292         if(d) return duplex_samplerate;
295 int AudioDevice::get_orealtime()
297         if(w) return out_realtime;
298         else if(d) return duplex_realtime;
299         return 0;
303 int AudioDevice::get_orate()
305         if(w) return out_samplerate;
306         else if(d) return duplex_samplerate;
307         return 0;
310 int AudioDevice::get_interrupted()
312         return interrupt;
315 int AudioDevice::get_device_buffer()
317         return device_buffer;