@@ -33,6 +33,7 @@
#include < signal.h>
#endif
#include < poll.h>
#include < unistd.h>
#include " SDL_audio.h"
@@ -47,6 +48,9 @@ static struct sio_hdl * (*SNDIO_sio_open)(const char *, unsigned int, int);
static void (*SNDIO_sio_close)(struct sio_hdl *);
static int (*SNDIO_sio_setpar)(struct sio_hdl *, struct sio_par *);
static int (*SNDIO_sio_getpar)(struct sio_hdl *, struct sio_par *);
static int (*SNDIO_sio_pollfd)(struct sio_hdl *, struct pollfd *, int );
static int (*SNDIO_sio_revents)(struct sio_hdl *, struct pollfd *);
static int (*SNDIO_sio_nfds)(struct sio_hdl *);
static int (*SNDIO_sio_start)(struct sio_hdl *);
static int (*SNDIO_sio_stop)(struct sio_hdl *);
static size_t (*SNDIO_sio_read)(struct sio_hdl *, void *, size_t );
@@ -83,6 +87,9 @@ load_sndio_syms(void)
SDL_SNDIO_SYM (sio_close);
SDL_SNDIO_SYM (sio_setpar);
SDL_SNDIO_SYM (sio_getpar);
SDL_SNDIO_SYM (sio_pollfd);
SDL_SNDIO_SYM (sio_nfds);
SDL_SNDIO_SYM (sio_revents);
SDL_SNDIO_SYM (sio_start);
SDL_SNDIO_SYM (sio_stop);
SDL_SNDIO_SYM (sio_read);
@@ -164,6 +171,44 @@ SNDIO_PlayDevice(_THIS)
#endif
}
static int
SNDIO_CaptureFromDevice (_THIS, void *buffer, int buflen)
{
int revents;
int nfds;
int i;
int r;
/* Emulate a blocking read */
for (i = SNDIO_sio_read (this->hidden ->dev , buffer, buflen); i < buflen;) {
if ((nfds = SNDIO_sio_pollfd (this->hidden ->dev , this->hidden ->pfd , POLLIN)) <= 0
|| poll (this->hidden ->pfd , nfds, INFTIM) <= 0 ) {
break ;
}
revents = SNDIO_sio_revents (this->hidden ->dev , this->hidden ->pfd );
if (revents & POLLIN) {
if ((r = SNDIO_sio_read (this->hidden ->dev , (char *)buffer + i, buflen - i)) == 0 ) {
break ;
}
i += r;
}
if (revents & POLLHUP) {
break ;
}
}
return i;
}
static void
SNDIO_FlushCapture (_THIS)
{
char buf[512 ];
while (SNDIO_sio_read (this->hidden ->dev , buf, sizeof (buf)) != 0 ) {
/* do nothing */ ;
}
}
static Uint8 *
SNDIO_GetDeviceBuf (_THIS)
{
@@ -173,6 +218,9 @@ SNDIO_GetDeviceBuf(_THIS)
static void
SNDIO_CloseDevice (_THIS)
{
if ( this->hidden ->pfd != NULL ) {
SDL_free (this->hidden ->pfd );
}
if ( this->hidden ->dev != NULL ) {
SNDIO_sio_stop (this->hidden ->dev );
SNDIO_sio_close (this->hidden ->dev );
@@ -197,11 +245,19 @@ SNDIO_OpenDevice(_THIS, void *handle, const char *devname, int iscapture)
this->hidden ->mixlen = this->spec .size ;
/* !!! FIXME: SIO_DEVANY can be a specific device... */
if ((this->hidden ->dev = SNDIO_sio_open (SIO_DEVANY, SIO_PLAY, 0 )) == NULL ) {
/* Capture devices must be non-blocking for SNDIO_FlushCapture */
if ((this->hidden ->dev =
SNDIO_sio_open (devname != NULL ? SIO_DEVANY : devname ,
iscapture ? SIO_REC : SIO_PLAY, iscapture)) == NULL ) {
return SDL_SetError (" sio_open() failed" );
}
/* Allocate the pollfd array for capture devices */
if (iscapture && (this->hidden ->pfd =
SDL_malloc (sizeof (struct pollfd) * SNDIO_sio_nfds (this->hidden ->dev ))) == NULL ) {
return SDL_OutOfMemory ();
}
SNDIO_sio_initpar (&par);
par.rate = this->spec .freq ;
@@ -300,8 +356,12 @@ SNDIO_Init(SDL_AudioDriverImpl * impl)
impl->PlayDevice = SNDIO_PlayDevice;
impl->GetDeviceBuf = SNDIO_GetDeviceBuf;
impl->CloseDevice = SNDIO_CloseDevice;
impl->CaptureFromDevice = SNDIO_CaptureFromDevice;
impl->FlushCapture = SNDIO_FlushCapture;
impl->Deinitialize = SNDIO_Deinitialize;
impl->OnlyHasDefaultOutputDevice = 1 ; /* !!! FIXME: sndio can handle multiple devices. */
impl->AllowsArbitraryDeviceNames = 1 ;
impl->HasCaptureSupport = SDL_TRUE;
return 1 ; /* this audio target is available. */
}