r499: This commit was manufactured by cvs2svn to create tag 'r1_2_1-last'.
[cinelerra_cv/mob.git] / hvirtual / cinelerra / audiodevice.C
blob2b3a86faa0572800dbbb2d1a742089f86e7a477c
1 #include "audio1394.h"
2 #include "audioalsa.h"
3 #include "audioconfig.h"
4 #include "audiodevice.h"
5 #include "audioesound.h"
6 #include "audiooss.h"
7 #include "condition.h"
8 #include "dcoffset.h"
9 #include "mutex.h"
10 #include "playbackconfig.h"
11 #include "preferences.h"
12 #include "recordconfig.h"
13 #include "sema.h"
17 AudioLowLevel::AudioLowLevel(AudioDevice *device)
19         this->device = device;
22 AudioLowLevel::~AudioLowLevel()
31 AudioDevice::AudioDevice()
32  : Thread(1, 0, 0)
34         initialize();
35         this->out_config = new AudioOutConfig(0);
36         this->in_config = new AudioInConfig;
37         this->vconfig = new VideoInConfig;
38         startup_lock = new Condition(0, "AudioDevice::startup_lock");
39         duplex_lock = new Condition(0, "AudioDevice::duplex_lock");
40         timer_lock = new Mutex("AudioDevice::timer_lock");
41         for(int i = 0; i < TOTAL_BUFFERS; i++)
42         {
43                 play_lock[i] = new Sema(0, "AudioDevice::play_lock");
44                 arm_lock[i] = new Sema(1, "AudioDevice::arm_lock");
45         }
46         dc_offset_thread = new DC_Offset;
49 AudioDevice::~AudioDevice()
51         delete out_config;
52         delete in_config;
53         delete vconfig;
54         delete startup_lock;
55         delete duplex_lock;
56         delete timer_lock;
57         for(int i = 0; i < TOTAL_BUFFERS; i++)
58         {
59                 delete play_lock[i];
60                 delete arm_lock[i];
61         }
62         delete dc_offset_thread;
65 int AudioDevice::initialize()
67         record_before_play = 0;
68         r = w = d = 0;
70         for(int i = 0; i < TOTAL_BUFFERS; i++)
71         {
72                 buffer[i] = 0;
73                 buffer_size[i] = 0;
74                 last_buffer[i] = 0;
75         }
77         input_buffer = 0;
78         duplex_init = 0;
79         rec_dither = play_dither = 0;
80         software_position_info = 0;
81         arm_buffer_num = 0;
82         is_playing_back = 0;
83         is_recording = 0;
84         last_buffer_size = total_samples = position_correction = 0;
85         last_position = 0;
86         interrupt = 0;
87         lowlevel_in = lowlevel_out = lowlevel_duplex = 0;
88         vdevice = 0;
89         sharing = 0;
90         total_samples_read = 0;
91         out_realtime = 0;
92         duplex_realtime = 0;
93         return 0;
96 int AudioDevice::create_lowlevel(AudioLowLevel* &lowlevel, int driver)
98         this->driver = driver;
101         if(!lowlevel)
102         {
103                 switch(driver)
104                 {
105 #ifdef HAVE_OSS
106                         case AUDIO_OSS:
107                         case AUDIO_OSS_ENVY24:
108                                 lowlevel = new AudioOSS(this);
109                                 break;
110 #endif
112 #ifdef HAVE_ESOUND
113                         case AUDIO_ESOUND:
114                                 lowlevel = new AudioESound(this);
115                                 break;
116 #endif
117                         case AUDIO_NAS:
118                                 break;
120 #ifdef HAVE_ALSA
121                         case AUDIO_ALSA:
122                                 lowlevel = new AudioALSA(this);
123                                 break;
124 #endif
126 #ifdef HAVE_FIREWIRE    
127                         case AUDIO_1394:
128                         case AUDIO_DV1394:
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, int rate, int samples, int realtime)
157         w = 1;
158         duplex_init = 0;
159         *this->out_config = *config;
160         out_samplerate = rate;
161         out_samples = samples;
162         out_realtime = realtime;
163         create_lowlevel(lowlevel_out, config->driver);
164         lowlevel_out->open_output();
165         return 0;
168 int AudioDevice::open_duplex(AudioOutConfig *out_config, int rate, int samples, int realtime)
170         d = 1;
171         duplex_init = 1;        // notify playback routines to test the duplex lock
172         *this->out_config = *out_config;
173         duplex_samplerate = rate;
174         duplex_samples = samples;
175         duplex_channels = 0;
176         duplex_realtime = realtime;
177         for(int i = 0; i < MAXDEVICES; i++)
178         {
179                 duplex_channels += out_config->oss_out_channels[i];
180         }
181         create_lowlevel(lowlevel_duplex, out_config->driver);
182         lowlevel_duplex->open_duplex();
183         playback_timer.update();
184         record_timer.update();
185         return 0;
189 int AudioDevice::interrupt_crash()
191         if(lowlevel_in) return lowlevel_in->interrupt_crash();
192         return 0;
196 int AudioDevice::close_all()
198         if(lowlevel_in) lowlevel_in->close_all();
199         if(lowlevel_out) lowlevel_out->close_all();
200         if(lowlevel_duplex) lowlevel_duplex->close_all();
202         reset_output();
203         if(input_buffer) 
204         {
205                 delete [] input_buffer; 
206                 input_buffer = 0; 
207         }
208         
209         is_recording = 0;
210         rec_dither = play_dither = 0;
211         software_position_info = position_correction = last_buffer_size = 0;
212         r = w = d = 0;
213         duplex_init = 0;
214         vdevice = 0;
215         sharing = 0;
217         if(lowlevel_in)
218         {
219                 delete lowlevel_in;
220                 lowlevel_in = 0;
221         }
222         if(lowlevel_out)
223         {
224                 delete lowlevel_out;
225                 lowlevel_out = 0;
226         }
227         if(lowlevel_duplex)
228         {
229                 delete lowlevel_duplex;
230                 lowlevel_duplex = 0;
231         }
232         return 0;
235 int AudioDevice::set_vdevice(VideoDevice *vdevice)
237         this->vdevice = vdevice;
238         return 0;
242 int AudioDevice::get_ichannels()
244         if(r) return in_channels;
245         else if(d) return duplex_channels;
246         else return 0;
249 int AudioDevice::get_ibits()
251         if(r) return in_bits;
252         else if(d) return duplex_bits;
253         return 0;
257 int AudioDevice::get_obits()
259         if(w) return out_bits;
260         else if(d) return duplex_bits;
261         return 0;
264 int AudioDevice::get_ochannels()
266         if(w) return out_channels;
267         else if(d) return duplex_channels;
268         return 0;
271 AudioLowLevel* AudioDevice::get_lowlevel_out()
273         if(w) return lowlevel_out;
274         else if(d) return lowlevel_duplex;
275         return 0;
278 AudioLowLevel* AudioDevice::get_lowlevel_in()
280         if(r) return lowlevel_in;
281         else if(d) return lowlevel_duplex;
282         return 0;
285 int AudioDevice::get_irate()
287         if(r) return in_samplerate;
288         else
289         if(d) return duplex_samplerate;
292 int AudioDevice::get_orealtime()
294         if(w) return out_realtime;
295         else if(d) return duplex_realtime;
296         return 0;
300 int AudioDevice::get_orate()
302         if(w) return out_samplerate;
303         else if(d) return duplex_samplerate;
304         return 0;
307 int AudioDevice::get_interrupted()
309         return interrupt;
312 int AudioDevice::get_device_buffer()
314         return device_buffer;