Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/openal-0.0.8/src/backends/alc_backend_esd.c @ 17

Last change on this file since 17 was 17, checked in by landauf, 16 years ago

added openal

File size: 7.4 KB
Line 
1/* -*- mode: C; tab-width:8; c-basic-offset:8 -*-
2 * vi:set ts=8:
3 *
4 * esd.c
5 *
6 * esd backend.
7 */
8#include "al_siteconfig.h"
9
10#include <AL/al.h>
11#include <assert.h>
12#include <fcntl.h>
13#include <stdio.h>
14#include <stdlib.h>
15#include <string.h>
16#include <sys/ioctl.h>
17#include <sys/mman.h>
18#include <sys/stat.h>
19#include <sys/time.h>
20#include <sys/types.h>
21#include <unistd.h>
22
23#include "al_main.h"
24#include "al_debug.h"
25
26#include "backends/alc_backend.h"
27
28#include "alc/alc_context.h"
29
30#ifdef OPENAL_DLOPEN_ESD
31#include <dlfcn.h>
32#endif
33
34#include <esd.h>
35
36#define DEF_SPEED       _ALC_CANON_SPEED
37#define DEF_SIZE        _AL_DEF_BUFSIZ
38#define DEF_SAMPLES     (DEF_SIZE / 2)
39#define DEF_CHANNELS    2
40#define DEF_FORMAT      AL_FORMAT_STEREO16
41
42#define ESD_KEY        "openal"
43#define ESD_NAMELEN    1024
44
45static const char *genesdkey(void);
46static int openal_load_esd_library(void);
47
48
49/*
50 * ESD library functions.
51 */
52static int (*pesd_open_sound)( const char *host );
53static int (*pesd_play_stream)( esd_format_t format, int rate, 
54                     const char *host, const char *name );
55static int (*pesd_standby)( int esd );
56static int (*pesd_resume)( int esd );
57static int (*pesd_close)( int esd );
58
59/*
60 * ESD library handle.
61 */
62static void * esd_lib_handle = NULL;
63
64static int openal_load_esd_library(void)
65{
66#ifdef OPENAL_DLOPEN_ESD
67        char * error = NULL;
68#endif
69   
70        if (esd_lib_handle != NULL)
71                return 1;  /* already loaded. */
72
73        #ifdef OPENAL_DLOPEN_ESD
74                #define OPENAL_LOAD_ESD_SYMBOL(x) p##x = dlsym(esd_lib_handle, #x); \
75                                                   error = dlerror(); \
76                                                   if (p##x == NULL) { \
77                                                           fprintf(stderr,"Could not resolve ESoundD symbol %s: %s\n", #x, ((error!=NULL)?(error):("(null)"))); \
78                                                           dlclose(esd_lib_handle); esd_lib_handle = NULL; \
79                                                           return 0; }
80                dlerror(); /* clear error state */
81                esd_lib_handle = dlopen("libesd.so", RTLD_LAZY | RTLD_GLOBAL);
82                error = dlerror();
83                if (esd_lib_handle == NULL) {
84                        fprintf(stderr,"Could not open ESoundD library: %s\n",((error!=NULL)?(error):("(null)")));
85                        return 0;
86                }
87        #else
88                #define OPENAL_LOAD_ESD_SYMBOL(x) p##x = x;
89                esd_lib_handle = (void *) 0xF00DF00D;
90        #endif
91
92        OPENAL_LOAD_ESD_SYMBOL(esd_open_sound);
93        OPENAL_LOAD_ESD_SYMBOL(esd_standby);
94        OPENAL_LOAD_ESD_SYMBOL(esd_resume);
95        OPENAL_LOAD_ESD_SYMBOL(esd_play_stream);
96        OPENAL_LOAD_ESD_SYMBOL(esd_close);
97               
98        return 1;
99}
100
101static fd_set esd_fd_set;
102
103typedef struct esd_info_s {
104        esd_format_t fmt;
105        ALuint speed;
106        const char *espeaker;
107        char name[ESD_NAMELEN];
108        int socket;
109
110        ALboolean paused;
111        int esdhandle; /* esd handle */
112} esd_openal_info_t;
113
114static esd_openal_info_t esd_info;
115
116static void *grab_write_esd(void) {
117        esd_format_t fmt;
118        int socket;
119        const char *esdkey = genesdkey();
120        const char *espeaker = getenv("ESPEAKER");
121        int esd;
122
123        if (!openal_load_esd_library()) {
124                return NULL;
125        }
126   
127        esd = pesd_open_sound(espeaker);
128        if(esd < 0) {
129                fprintf(stderr, "esd open sound failed.\n");
130                return NULL;
131        }
132
133        fmt = ESD_STREAM | ESD_PLAY;
134
135        switch(DEF_CHANNELS) {
136                case 1: fmt |= ESD_MONO; break;
137                case 2: fmt |= ESD_STEREO; break;
138                default: break;
139        }
140
141        switch(_alGetBitsFromFormat(DEF_FORMAT)) {
142                case 8:  fmt |= ESD_BITS8; break;
143                case 16: fmt |= ESD_BITS16; break;
144                default: break;
145        }
146
147        socket = pesd_play_stream(fmt, DEF_SPEED, espeaker, esdkey);
148
149        if(socket < 0) {
150                fprintf(stderr, "esd play stream failed.\n");
151                return NULL;
152        }
153
154        fprintf(stderr, "esd grab audio ok\n");
155
156        _alDebug(ALD_CONTEXT, __FILE__, __LINE__,
157                "esd grab audio ok");
158
159        esd_info.speed     = DEF_SPEED;
160        esd_info.fmt       = fmt;
161        esd_info.socket    = socket;
162        esd_info.espeaker  = espeaker;
163        esd_info.paused    = AL_FALSE;
164        esd_info.esdhandle = esd;
165
166        strncpy(esd_info.name, esdkey, ESD_NAMELEN);
167
168        return &esd_info;
169}
170
171static void *grab_read_esd(void) {
172        return NULL;
173}
174
175void *
176alcBackendOpenESD_( ALC_OpenMode mode )
177{
178        return mode == ALC_OPEN_INPUT_ ? grab_read_esd() : grab_write_esd();
179}
180
181void esd_blitbuffer(void *handle, void *dataptr, int bytes_to_write)  {
182        esd_openal_info_t *eh;
183        struct timeval tv = { 0, 9000000 };
184        int iterator = 0;
185        int err;
186        int fd;
187
188        if(handle == NULL) {
189                return;
190        }
191
192        eh = (esd_openal_info_t *) handle;
193
194        if(eh->paused == AL_TRUE) {
195                /* don't write to paused audio devices, just sleep */
196                tv.tv_usec = 10000;
197
198                select(0, NULL, NULL, NULL, &tv);
199
200                return;
201        }
202
203        fd = eh->socket;
204
205        for(iterator = bytes_to_write; iterator > 0; ) {
206                FD_ZERO(&esd_fd_set);
207                FD_SET(fd, &esd_fd_set);
208
209                err = select(fd + 1, NULL, &esd_fd_set, NULL, &tv);
210                if(FD_ISSET(fd, &esd_fd_set) == 0) {
211                        /* timeout occured, don't try and write */
212                        fprintf(stderr, "esd_blitbuffer: timeout occured\n");
213
214                        assert(0);
215                        return;
216                }
217
218                assert(iterator > 0);
219                assert(iterator <= bytes_to_write);
220
221                err = write(fd,
222                            (char *) dataptr + bytes_to_write - iterator,
223                            iterator);
224                if(err < 0) {
225                        assert(0);
226#ifdef DEBUG_MAXIMUS
227                        perror("write");
228#endif
229                        return;
230                }
231
232                iterator -= err;
233        };
234
235        return;
236}
237
238void release_esd(void *handle) {
239        esd_openal_info_t *eh;
240
241        if(handle == NULL) {
242                return;
243        }
244
245        eh = (esd_openal_info_t *) handle;
246
247        pesd_close(eh->esdhandle);
248
249        return;
250}
251
252static const char *genesdkey(void) {
253        static char retval[ESD_NAMELEN];
254
255        snprintf(retval, sizeof(retval), "openal-%d\n", (int) getpid());
256
257        return retval;
258}
259
260void pause_esd(void *handle) {
261        esd_openal_info_t *eh;
262
263        if(handle == NULL) {
264                return;
265        }
266
267        eh = (esd_openal_info_t *) handle;
268
269        eh->paused = AL_TRUE;
270        pesd_standby(eh->esdhandle);
271
272        return;
273}
274
275void resume_esd(void *handle) {
276        esd_openal_info_t *eh;
277
278        if(handle == NULL) {
279                return;
280        }
281
282        eh = (esd_openal_info_t *) handle;
283
284        eh->paused = AL_FALSE;
285        pesd_resume(eh->esdhandle);
286
287        return;
288}
289
290static ALboolean set_write_esd(UNUSED(void *handle),
291                               UNUSED(ALuint *bufsiz),
292                               ALenum *fmt,
293                               ALuint *speed) {
294        esd_openal_info_t *eh;
295        int socket;
296        ALuint chans = _alGetChannelsFromFormat(*fmt);
297
298        if(handle == NULL) {
299                return AL_FALSE;
300        }
301
302        eh = (esd_openal_info_t *) handle;
303
304        close(eh->socket);
305
306        eh->fmt = ESD_STREAM | ESD_PLAY;
307
308        switch(chans) {
309                case 1: eh->fmt |= ESD_MONO; break;
310                case 2: eh->fmt |= ESD_STEREO; break;
311                default: break;
312        }
313
314        switch(_alGetBitsFromFormat(*fmt)) {
315                case 8:  eh->fmt |= ESD_BITS8; break;
316                case 16: eh->fmt |= ESD_BITS16; break;
317                default: break;
318        }
319
320        eh->speed = *speed;
321
322        socket = pesd_play_stream(eh->fmt,
323                                 eh->speed,
324                                 eh->espeaker,
325                                 eh->name);
326        if(socket < 0) {
327                return AL_FALSE;
328        }
329
330        eh->socket = socket;
331        eh->paused = AL_FALSE;
332
333        return AL_TRUE;
334}
335
336static ALboolean set_read_esd(UNUSED(void *handle),
337                              UNUSED(ALuint *bufsiz),
338                              UNUSED(ALenum *fmt),
339                              UNUSED(ALuint *speed)) {
340        return AL_FALSE;
341}
342
343ALboolean
344alcBackendSetAttributesESD_(ALC_OpenMode mode, void *handle, ALuint *bufsiz, ALenum *fmt, ALuint *speed)
345{
346        return mode == ALC_OPEN_INPUT_ ?
347                set_read_esd(handle, bufsiz, fmt, speed) :
348                set_write_esd(handle, bufsiz, fmt, speed);
349}
350
351ALsizei
352capture_esd( UNUSED(void *handle), UNUSED(void *capture_buffer), UNUSED(int bufsiz) )
353{
354        return 0;
355}
356
357ALfloat
358get_esdchannel( UNUSED(void *handle), UNUSED(ALuint channel) )
359{
360        return 0.0;
361}
362
363int
364set_esdchannel( UNUSED(void *handle), UNUSED(ALuint channel), UNUSED(ALfloat volume) )
365{
366        return 0;
367}
Note: See TracBrowser for help on using the repository browser.