initial commit
[goodguy/history.git] / cinelerra-5.0 / cinelerra / audioesound.C
1
2 /*
3  * CINELERRA
4  * Copyright (C) 2008 Adam Williams <broadcast at earthling dot net>
5  * 
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.
10  * 
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.
15  * 
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
19  * 
20  */
21
22 #include "audioconfig.h"
23 #include "audiodevice.h"
24 #include "audioesound.h"
25 #include "playbackconfig.h"
26 #include "preferences.h"
27 #include "recordconfig.h"
28
29 #ifdef HAVE_ESOUND
30 #include <esd.h>
31 #include <string.h>
32
33 AudioESound::AudioESound(AudioDevice *device) : AudioLowLevel(device)
34 {
35         esd_in = esd_out = 0;
36         esd_in_fd = esd_out_fd = 0;
37 }
38
39 AudioESound::~AudioESound()
40 {
41 }
42
43
44 int AudioESound::get_bit_flag(int bits)
45 {
46         switch(bits)
47         {
48                 case 8: return ESD_BITS8;
49                 case 16: return ESD_BITS16;
50         }
51         return ESD_BITS16;
52 }
53
54 // No more than 2 channels in ESD
55 int AudioESound::get_channels_flag(int channels)
56 {
57         switch(channels)
58         {
59                 case 1: return ESD_MONO;
60                 case 2: return ESD_STEREO;
61         }
62         return ESD_STEREO;
63 }
64
65 char* AudioESound::translate_device_string(char *server, int port)
66 {
67 // ESD server
68         if(port > 0 && strlen(server))
69                 sprintf(device_string, "%s:%d", server, port);
70         else
71                 device_string[0] = 0;
72         return device_string;
73 }
74
75 int AudioESound::open_input()
76 {
77         esd_format_t format = ESD_STREAM | ESD_RECORD;
78         
79         device->in_channels = 2;
80         device->in_bits = 16;
81
82         format |= get_channels_flag(device->in_channels);
83         format |= get_bit_flag(device->in_bits);
84
85         if((esd_in = esd_open_sound(translate_device_string(device->in_config->esound_in_server, device->in_config->esound_in_port))) <= 0)
86         {
87                 fprintf(stderr, "AudioESound::open_input: open failed\n");
88                 return 1;
89         }
90         esd_in_fd = esd_record_stream_fallback(format, device->in_samplerate, 
91                                 translate_device_string(device->out_config->esound_out_server, device->out_config->esound_out_port), 
92                                                 "Cinelerra");
93         return 0;
94 }
95
96 int AudioESound::open_output()
97 {
98         esd_format_t format = ESD_STREAM | ESD_PLAY;
99
100         device->out_channels = 2;
101         device->out_bits = 16;
102
103         format |= get_channels_flag(device->out_channels);
104         format |= get_bit_flag(device->out_bits);
105
106         if((esd_out = esd_open_sound(translate_device_string(
107                 device->out_config->esound_out_server, 
108                 device->out_config->esound_out_port))) <= 0)
109         {
110                 fprintf(stderr, "AudioESound::open_output %s:%d: open failed\n",
111                         device->out_config->esound_out_server, 
112                 device->out_config->esound_out_port);
113                 return 1;
114         }
115
116         esd_out_fd = esd_play_stream_fallback(format, 
117                 device->out_samplerate, 
118                 translate_device_string(device->out_config->esound_out_server, 
119                         device->out_config->esound_out_port), 
120                 "Cinelerra");
121
122         device->device_buffer = esd_get_latency(esd_out);
123         device->device_buffer *= device->out_bits / 8 * device->out_channels;
124         return 0;
125 }
126
127 int AudioESound::close_all()
128 {
129         if(esd_in) { 
130                 close(esd_in_fd);
131                 esd_close(esd_in);
132                 esd_in = 0;
133         }
134
135         if(esd_out) {
136                 close(esd_out_fd);
137                 esd_close(esd_out);
138                 esd_out = 0;
139         }
140         return 0;
141 }
142
143 // No position on ESD
144 int64_t AudioESound::device_position()
145 {
146         return -1;
147 }
148
149 int AudioESound::read_buffer(char *buffer, int size)
150 {
151         return esd_in_fd>0 ? read(esd_in_fd, buffer, size) : 1;
152 }
153
154 int AudioESound::write_buffer(char *buffer, int size)
155 {
156         return esd_out_fd>0 ? write(esd_out_fd, buffer, size) : 0;
157 }
158
159 // No flushing in ESD
160 int AudioESound::flush_device()
161 {
162         return 0;
163 }
164
165 // No interrupting ESD
166 int AudioESound::interrupt_playback()
167 {
168         return 0;
169 }
170
171 #endif // HAVE_ESOUND