Credit Andrew R for finding the direct copy mods for exr and ppm sequences
[goodguy/cinelerra.git] / cinelerra-5.1 / 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         device_string[0] = 0;
69         if(port > 0 && strlen(server))
70                 sprintf(device_string, "%s:%d", server, port);
71         return device_string;
72 }
73
74 int AudioESound::open_input()
75 {
76         esd_format_t format = ESD_STREAM | ESD_RECORD;
77
78         device->in_channels = 2;
79         device->in_bits = 16;
80
81         format |= get_channels_flag(device->in_channels);
82         format |= get_bit_flag(device->in_bits);
83
84         if((esd_in = esd_open_sound(translate_device_string(device->in_config->esound_in_server, device->in_config->esound_in_port))) <= 0)
85         {
86                 fprintf(stderr, "AudioESound::open_input: open failed\n");
87                 return 1;
88         }
89         esd_in_fd = esd_record_stream_fallback(format, device->in_samplerate,
90                                 translate_device_string(device->out_config->esound_out_server, device->out_config->esound_out_port),
91                                                 "Cinelerra");
92         return 0;
93 }
94
95 int AudioESound::open_output()
96 {
97         esd_format_t format = ESD_STREAM | ESD_PLAY;
98
99         device->out_channels = 2;
100         device->out_bits = 16;
101
102         format |= get_channels_flag(device->out_channels);
103         format |= get_bit_flag(device->out_bits);
104
105         if((esd_out = esd_open_sound(translate_device_string(
106                 device->out_config->esound_out_server,
107                 device->out_config->esound_out_port))) <= 0)
108         {
109                 fprintf(stderr, "AudioESound::open_output %s:%d: open failed\n",
110                         device->out_config->esound_out_server,
111                 device->out_config->esound_out_port);
112                 return 1;
113         }
114
115         esd_out_fd = esd_play_stream_fallback(format,
116                 device->out_samplerate,
117                 translate_device_string(device->out_config->esound_out_server,
118                         device->out_config->esound_out_port),
119                 "Cinelerra");
120
121         device->device_buffer = esd_get_latency(esd_out);
122         device->device_buffer *= device->out_bits / 8 * device->out_channels;
123         return 0;
124 }
125
126 int AudioESound::close_all()
127 {
128         if(esd_in) {
129                 close(esd_in_fd);
130                 esd_close(esd_in);
131                 esd_in = 0;
132         }
133
134         if(esd_out) {
135                 close(esd_out_fd);
136                 esd_close(esd_out);
137                 esd_out = 0;
138         }
139         return 0;
140 }
141
142 // No position on ESD
143 int64_t AudioESound::device_position()
144 {
145         return -1;
146 }
147
148 int AudioESound::read_buffer(char *buffer, int size)
149 {
150         return esd_in_fd>0 ? read(esd_in_fd, buffer, size) : 1;
151 }
152
153 int AudioESound::write_buffer(char *buffer, int size)
154 {
155         return esd_out_fd>0 && write(esd_out_fd, buffer, size) > 0 ? 0 : -1;
156 }
157
158 // No flushing in ESD
159 int AudioESound::flush_device()
160 {
161         return 0;
162 }
163
164 // No interrupting ESD
165 int AudioESound::interrupt_playback()
166 {
167         return 0;
168 }
169
170 #endif // HAVE_ESOUND