Mercurial > sdl-ios-xcode
changeset 1567:12b6d331d82a
Good idea, renaming OpenBSD audio to BSD audio.
author | Sam Lantinga <slouken@libsdl.org> |
---|---|
date | Tue, 21 Mar 2006 09:33:54 +0000 |
parents | 5bc2a95f9dcf |
children | 1f3f39f9cfcf |
files | configure.in include/SDL_config.h.in src/audio/SDL_audio.c src/audio/SDL_audiodev.c src/audio/SDL_sysaudio.h src/audio/bsd/.cvsignore src/audio/bsd/SDL_bsdaudio.c src/audio/bsd/SDL_bsdaudio.h src/audio/openbsd/.cvsignore src/audio/openbsd/SDL_openbsdaudio.c src/audio/openbsd/SDL_openbsdaudio.h |
diffstat | 11 files changed, 476 insertions(+), 478 deletions(-) [+] |
line wrap: on
line diff
--- a/configure.in Tue Mar 21 09:24:10 2006 +0000 +++ b/configure.in Tue Mar 21 09:33:54 2006 +0000 @@ -2001,8 +2001,8 @@ have_audio=yes ;; netbsd|openbsd) - AC_DEFINE(SDL_AUDIO_DRIVER_OPENBSD) - SOURCES="$SOURCES $srcdir/src/audio/openbsd/*.c" + AC_DEFINE(SDL_AUDIO_DRIVER_BSD) + SOURCES="$SOURCES $srcdir/src/audio/bsd/*.c" have_audio=yes ;; aix)
--- a/include/SDL_config.h.in Tue Mar 21 09:24:10 2006 +0000 +++ b/include/SDL_config.h.in Tue Mar 21 09:33:54 2006 +0000 @@ -167,7 +167,7 @@ #undef SDL_AUDIO_DRIVER_MINT #undef SDL_AUDIO_DRIVER_MMEAUDIO #undef SDL_AUDIO_DRIVER_NAS -#undef SDL_AUDIO_DRIVER_OPENBSD +#undef SDL_AUDIO_DRIVER_BSD #undef SDL_AUDIO_DRIVER_OSS #undef SDL_AUDIO_DRIVER_OSS_SOUNDCARD_H #undef SDL_AUDIO_DRIVER_PAUD
--- a/src/audio/SDL_audio.c Tue Mar 21 09:24:10 2006 +0000 +++ b/src/audio/SDL_audio.c Tue Mar 21 09:33:54 2006 +0000 @@ -36,8 +36,8 @@ /* Available audio drivers */ static AudioBootStrap *bootstrap[] = { -#if SDL_AUDIO_DRIVER_OPENBSD - &OPENBSD_AUDIO_bootstrap, +#if SDL_AUDIO_DRIVER_BSD + &BSD_AUDIO_bootstrap, #endif #if SDL_AUDIO_DRIVER_OSS &DSP_bootstrap,
--- a/src/audio/SDL_audiodev.c Tue Mar 21 09:24:10 2006 +0000 +++ b/src/audio/SDL_audiodev.c Tue Mar 21 09:33:54 2006 +0000 @@ -23,7 +23,7 @@ /* Get the name of the audio device we use for output */ -#if SDL_AUDIO_DRIVER_OPENBSD || SDL_AUDIO_DRIVER_OSS || SDL_AUDIO_DRIVER_SUNAUDIO +#if SDL_AUDIO_DRIVER_BSD || SDL_AUDIO_DRIVER_OSS || SDL_AUDIO_DRIVER_SUNAUDIO #include <fcntl.h> #include <sys/types.h>
--- a/src/audio/SDL_sysaudio.h Tue Mar 21 09:24:10 2006 +0000 +++ b/src/audio/SDL_sysaudio.h Tue Mar 21 09:33:54 2006 +0000 @@ -100,8 +100,8 @@ SDL_AudioDevice *(*create)(int devindex); } AudioBootStrap; -#if SDL_AUDIO_DRIVER_OPENBSD -extern AudioBootStrap OPENBSD_AUDIO_bootstrap; +#if SDL_AUDIO_DRIVER_BSD +extern AudioBootStrap BSD_AUDIO_bootstrap; #endif #if SDL_AUDIO_DRIVER_OSS extern AudioBootStrap DSP_bootstrap;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/audio/bsd/.cvsignore Tue Mar 21 09:33:54 2006 +0000 @@ -0,0 +1,6 @@ +Makefile.in +Makefile +.libs +*.o +*.lo +*.la
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/audio/bsd/SDL_bsdaudio.c Tue Mar 21 09:33:54 2006 +0000 @@ -0,0 +1,404 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2004 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Sam Lantinga + slouken@libsdl.org +*/ +#include "SDL_config.h" + +/* + * Driver for native OpenBSD/NetBSD audio(4). + * vedge@vedge.com.ar. + */ + +#include <errno.h> +#include <unistd.h> +#include <fcntl.h> +#include <sys/time.h> +#include <sys/ioctl.h> +#include <sys/stat.h> +#include <sys/types.h> +#include <sys/audioio.h> + +#include "SDL_timer.h" +#include "SDL_audio.h" +#include "../SDL_audiomem.h" +#include "../SDL_audio_c.h" +#include "../SDL_audiodev_c.h" +#include "SDL_openbsdaudio.h" + +/* The tag name used by NetBSD/OpenBSD audio */ +#ifdef __NetBSD__ +#define BSD_AUDIO_DRIVER_NAME "netbsd" +#define BSD_AUDIO_DRIVER_DESC "Native NetBSD audio" +#else +#define BSD_AUDIO_DRIVER_NAME "openbsd" +#define BSD_AUDIO_DRIVER_DESC "Native OpenBSD audio" +#endif + +/* Open the audio device for playback, and don't block if busy */ +/* #define USE_BLOCKING_WRITES */ + +/* Use timer for synchronization */ +/* #define USE_TIMER_SYNC */ + +/* #define DEBUG_AUDIO */ +/* #define DEBUG_AUDIO_STREAM */ + +#ifdef USE_BLOCKING_WRITES +#define OPEN_FLAGS O_WRONLY +#else +#define OPEN_FLAGS (O_WRONLY|O_NONBLOCK) +#endif + +/* Audio driver functions */ +static void OBSD_WaitAudio(_THIS); +static int OBSD_OpenAudio(_THIS, SDL_AudioSpec *spec); +static void OBSD_PlayAudio(_THIS); +static Uint8 *OBSD_GetAudioBuf(_THIS); +static void OBSD_CloseAudio(_THIS); + +#ifdef DEBUG_AUDIO +static void OBSD_Status(_THIS); +#endif + +/* Audio driver bootstrap functions */ + +static int +Audio_Available(void) +{ + int fd; + int available; + + available = 0; + fd = SDL_OpenAudioPath(NULL, 0, OPEN_FLAGS, 0); + if(fd >= 0) { + available = 1; + close(fd); + } + return(available); +} + +static void +Audio_DeleteDevice(SDL_AudioDevice *device) +{ + SDL_free(device->hidden); + SDL_free(device); +} + +static SDL_AudioDevice +*Audio_CreateDevice(int devindex) +{ + SDL_AudioDevice *this; + + /* Initialize all variables that we clean on shutdown */ + this = (SDL_AudioDevice*)SDL_malloc(sizeof(SDL_AudioDevice)); + if(this) { + SDL_memset(this, 0, (sizeof *this)); + this->hidden = + (struct SDL_PrivateAudioData*)SDL_malloc((sizeof *this->hidden)); + } + if((this == NULL) || (this->hidden == NULL)) { + SDL_OutOfMemory(); + if(this) SDL_free(this); + return(0); + } + SDL_memset(this->hidden, 0, (sizeof *this->hidden)); + audio_fd = -1; + + /* Set the function pointers */ + this->OpenAudio = OBSD_OpenAudio; + this->WaitAudio = OBSD_WaitAudio; + this->PlayAudio = OBSD_PlayAudio; + this->GetAudioBuf = OBSD_GetAudioBuf; + this->CloseAudio = OBSD_CloseAudio; + + this->free = Audio_DeleteDevice; + + return this; +} + +AudioBootStrap OPENBSD_AUDIO_bootstrap = { + BSD_DRIVER_NAME, BSD_AUDIO_DRIVER_DESC, + Audio_Available, Audio_CreateDevice +}; + +/* This function waits until it is possible to write a full sound buffer */ +static void +OBSD_WaitAudio(_THIS) +{ +#ifndef USE_BLOCKING_WRITES /* Not necessary when using blocking writes */ + /* See if we need to use timed audio synchronization */ + if ( frame_ticks ) { + /* Use timer for general audio synchronization */ + Sint32 ticks; + + ticks = ((Sint32)(next_frame - SDL_GetTicks()))-FUDGE_TICKS; + if ( ticks > 0 ) { + SDL_Delay(ticks); + } + } else { + /* Use select() for audio synchronization */ + fd_set fdset; + struct timeval timeout; + + FD_ZERO(&fdset); + FD_SET(audio_fd, &fdset); + timeout.tv_sec = 10; + timeout.tv_usec = 0; +#ifdef DEBUG_AUDIO + fprintf(stderr, "Waiting for audio to get ready\n"); +#endif + if ( select(audio_fd+1, NULL, &fdset, NULL, &timeout) <= 0 ) { + const char *message = + "Audio timeout - buggy audio driver? (disabled)"; + /* In general we should never print to the screen, + but in this case we have no other way of letting + the user know what happened. + */ + fprintf(stderr, "SDL: %s\n", message); + this->enabled = 0; + /* Don't try to close - may hang */ + audio_fd = -1; +#ifdef DEBUG_AUDIO + fprintf(stderr, "Done disabling audio\n"); +#endif + } +#ifdef DEBUG_AUDIO + fprintf(stderr, "Ready!\n"); +#endif + } +#endif /* !USE_BLOCKING_WRITES */ +} + +static void +OBSD_PlayAudio(_THIS) +{ + int written, p=0; + + /* Write the audio data, checking for EAGAIN on broken audio drivers */ + do { + written = write(audio_fd, &mixbuf[p], mixlen-p); + if (written>0) + p += written; + if (written == -1 && errno != 0 && errno != EAGAIN && errno != EINTR) + { + /* Non recoverable error has occurred. It should be reported!!! */ + perror("audio"); + break; + } + + if ( p < written || ((written < 0) && ((errno == 0) || (errno == EAGAIN))) ) { + SDL_Delay(1); /* Let a little CPU time go by */ + } + } while ( p < written ); + + /* If timer synchronization is enabled, set the next write frame */ + if ( frame_ticks ) { + next_frame += frame_ticks; + } + + /* If we couldn't write, assume fatal error for now */ + if ( written < 0 ) { + this->enabled = 0; + } +#ifdef DEBUG_AUDIO + fprintf(stderr, "Wrote %d bytes of audio data\n", written); +#endif +} + +static Uint8 +*OBSD_GetAudioBuf(_THIS) +{ + return(mixbuf); +} + +static void +OBSD_CloseAudio(_THIS) +{ + if(mixbuf != NULL) { + SDL_FreeAudioMem(mixbuf); + mixbuf = NULL; + } + if(audio_fd >= 0) { + close(audio_fd); + audio_fd = -1; + } +} + +#ifdef DEBUG_AUDIO +void +OBSD_Status(_THIS) +{ + audio_info_t info; + + if(ioctl(audio_fd, AUDIO_GETINFO, &info) < 0) { + fprintf(stderr,"AUDIO_GETINFO failed.\n"); + return; + } + + fprintf(stderr,"\n" +"[play/record info]\n" +"buffer size : %d bytes\n" +"sample rate : %i Hz\n" +"channels : %i\n" +"precision : %i-bit\n" +"encoding : 0x%x\n" +"seek : %i\n" +"sample count : %i\n" +"EOF count : %i\n" +"paused : %s\n" +"error occured : %s\n" +"waiting : %s\n" +"active : %s\n" +"", + info.play.buffer_size, + info.play.sample_rate, + info.play.channels, + info.play.precision, + info.play.encoding, + info.play.seek, + info.play.samples, + info.play.eof, + info.play.pause ? "yes" : "no", + info.play.error ? "yes" : "no", + info.play.waiting ? "yes" : "no", + info.play.active ? "yes": "no"); + + fprintf(stderr,"\n" +"[audio info]\n" +"monitor_gain : %i\n" +"hw block size : %d bytes\n" +"hi watermark : %i\n" +"lo watermark : %i\n" +"audio mode : %s\n" +"", + info.monitor_gain, + info.blocksize, + info.hiwat, info.lowat, + (info.mode == AUMODE_PLAY) ? "PLAY" + : (info.mode = AUMODE_RECORD) ? "RECORD" + : (info.mode == AUMODE_PLAY_ALL ? "PLAY_ALL" + : "?")); +} +#endif /* DEBUG_AUDIO */ + +static int +OBSD_OpenAudio(_THIS, SDL_AudioSpec *spec) +{ + char audiodev[64]; + Uint16 format; + audio_info_t info; + + AUDIO_INITINFO(&info); + + /* Calculate the final parameters for this audio specification */ + SDL_CalculateAudioSpec(spec); + +#ifdef USE_TIMER_SYNC + frame_ticks = 0.0; +#endif + + /* Open the audio device */ + audio_fd = SDL_OpenAudioPath(audiodev, sizeof(audiodev), OPEN_FLAGS, 0); + if(audio_fd < 0) { + SDL_SetError("Couldn't open %s: %s", audiodev, strerror(errno)); + return(-1); + } + + /* Set to play mode */ + info.mode = AUMODE_PLAY; + if(ioctl(audio_fd, AUDIO_SETINFO, &info) < 0) { + SDL_SetError("Couldn't put device into play mode"); + return(-1); + } + + mixbuf = NULL; + AUDIO_INITINFO(&info); + for (format = SDL_FirstAudioFormat(spec->format); + format; format = SDL_NextAudioFormat()) + { + switch(format) { + case AUDIO_U8: + info.play.encoding = AUDIO_ENCODING_ULINEAR; + info.play.precision = 8; + break; + case AUDIO_S8: + info.play.encoding = AUDIO_ENCODING_SLINEAR; + info.play.precision = 8; + break; + case AUDIO_S16LSB: + info.play.encoding = AUDIO_ENCODING_SLINEAR_LE; + info.play.precision = 16; + break; + case AUDIO_S16MSB: + info.play.encoding = AUDIO_ENCODING_SLINEAR_BE; + info.play.precision = 16; + break; + case AUDIO_U16LSB: + info.play.encoding = AUDIO_ENCODING_ULINEAR_LE; + info.play.precision = 16; + break; + case AUDIO_U16MSB: + info.play.encoding = AUDIO_ENCODING_ULINEAR_BE; + info.play.precision = 16; + break; + default: + continue; + } + if (ioctl(audio_fd, AUDIO_SETINFO, &info) == 0) + break; + } + + if(!format) { + SDL_SetError("No supported encoding for 0x%x", spec->format); + return(-1); + } + + spec->format = format; + + AUDIO_INITINFO(&info); + info.play.channels = spec->channels; + if (ioctl(audio_fd, AUDIO_SETINFO, &info) == -1) + spec->channels = 1; + AUDIO_INITINFO(&info); + info.play.sample_rate = spec->freq; + info.blocksize = spec->size; + info.hiwat = 5; + info.lowat = 3; + (void)ioctl(audio_fd, AUDIO_SETINFO, &info); + (void)ioctl(audio_fd, AUDIO_GETINFO, &info); + spec->freq = info.play.sample_rate; + /* Allocate mixing buffer */ + mixlen = spec->size; + mixbuf = (Uint8*)SDL_AllocAudioMem(mixlen); + if(mixbuf == NULL) { + return(-1); + } + SDL_memset(mixbuf, spec->silence, spec->size); + + /* Get the parent process id (we're the parent of the audio thread) */ + parent = getpid(); + +#ifdef DEBUG_AUDIO + OBSD_Status(this); +#endif + + /* We're ready to rock and roll. :-) */ + return(0); +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/audio/bsd/SDL_bsdaudio.h Tue Mar 21 09:33:54 2006 +0000 @@ -0,0 +1,58 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 1997-2004 Sam Lantinga + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + Sam Lantinga + slouken@libsdl.org +*/ +#include "SDL_config.h" + +#ifndef _SDL_openbsdaudio_h +#define _SDL_openbsdaudio_h + +#include "../SDL_sysaudio.h" + +#define _THIS SDL_AudioDevice *this + +struct SDL_PrivateAudioData +{ + /* The file descriptor for the audio device */ + int audio_fd; + + /* The parent process id, to detect when application quits */ + pid_t parent; + + /* Raw mixing buffer */ + Uint8 *mixbuf; + int mixlen; + + /* Support for audio timing using a timer, in addition to select() */ + float frame_ticks; + float next_frame; +}; + +#define FUDGE_TICKS 10 /* The scheduler overhead ticks per frame */ + +/* Old variable names */ +#define audio_fd (this->hidden->audio_fd) +#define parent (this->hidden->parent) +#define mixbuf (this->hidden->mixbuf) +#define mixlen (this->hidden->mixlen) +#define frame_ticks (this->hidden->frame_ticks) +#define next_frame (this->hidden->next_frame) + +#endif /* _SDL_openbsdaudio_h */
--- a/src/audio/openbsd/.cvsignore Tue Mar 21 09:24:10 2006 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,6 +0,0 @@ -Makefile.in -Makefile -.libs -*.o -*.lo -*.la
--- a/src/audio/openbsd/SDL_openbsdaudio.c Tue Mar 21 09:24:10 2006 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,406 +0,0 @@ -/* - SDL - Simple DirectMedia Layer - Copyright (C) 1997-2004 Sam Lantinga - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this library; if not, write to the Free - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - - Sam Lantinga - slouken@libsdl.org -*/ -#include "SDL_config.h" - -/* - * Driver for native OpenBSD audio(4). - * vedge@vedge.com.ar. - */ - -#include <errno.h> -#include <unistd.h> -#include <fcntl.h> -#include <sys/time.h> -#include <sys/ioctl.h> -#include <sys/stat.h> -#include <sys/types.h> -#include <sys/audioio.h> - -#include "SDL_timer.h" -#include "SDL_audio.h" -#include "../SDL_audiomem.h" -#include "../SDL_audio_c.h" -#include "../SDL_audiodev_c.h" -#include "SDL_openbsdaudio.h" - -/* The tag name used by NetBSD/OpenBSD audio */ -#ifdef __NETBSD__ -#define OBSD_DRIVER_NAME "netbsd" -#else -#define OBSD_DRIVER_NAME "openbsd" -#endif - -/* Open the audio device for playback, and don't block if busy */ -/* #define USE_BLOCKING_WRITES */ - -/* Use timer for synchronization */ -/* #define USE_TIMER_SYNC */ - -/* #define DEBUG_AUDIO */ -/* #define DEBUG_AUDIO_STREAM */ - -#ifdef USE_BLOCKING_WRITES -#define OPEN_FLAGS O_WRONLY -#else -#define OPEN_FLAGS (O_WRONLY|O_NONBLOCK) -#endif - -/* Audio driver functions */ -static void OBSD_WaitAudio(_THIS); -static int OBSD_OpenAudio(_THIS, SDL_AudioSpec *spec); -static void OBSD_PlayAudio(_THIS); -static Uint8 *OBSD_GetAudioBuf(_THIS); -static void OBSD_CloseAudio(_THIS); - -#ifdef DEBUG_AUDIO -static void OBSD_Status(_THIS); -#endif - -/* Audio driver bootstrap functions */ - -static int -Audio_Available(void) -{ - int fd; - int available; - - available = 0; - fd = SDL_OpenAudioPath(NULL, 0, OPEN_FLAGS, 0); - if(fd >= 0) { - available = 1; - close(fd); - } - return(available); -} - -static void -Audio_DeleteDevice(SDL_AudioDevice *device) -{ - SDL_free(device->hidden); - SDL_free(device); -} - -static SDL_AudioDevice -*Audio_CreateDevice(int devindex) -{ - SDL_AudioDevice *this; - - /* Initialize all variables that we clean on shutdown */ - this = (SDL_AudioDevice*)SDL_malloc(sizeof(SDL_AudioDevice)); - if(this) { - SDL_memset(this, 0, (sizeof *this)); - this->hidden = - (struct SDL_PrivateAudioData*)SDL_malloc((sizeof *this->hidden)); - } - if((this == NULL) || (this->hidden == NULL)) { - SDL_OutOfMemory(); - if(this) SDL_free(this); - return(0); - } - SDL_memset(this->hidden, 0, (sizeof *this->hidden)); - audio_fd = -1; - - /* Set the function pointers */ - this->OpenAudio = OBSD_OpenAudio; - this->WaitAudio = OBSD_WaitAudio; - this->PlayAudio = OBSD_PlayAudio; - this->GetAudioBuf = OBSD_GetAudioBuf; - this->CloseAudio = OBSD_CloseAudio; - - this->free = Audio_DeleteDevice; - - return this; -} - -AudioBootStrap OPENBSD_AUDIO_bootstrap = { -#ifdef __NETBSD__ - OBSD_DRIVER_NAME, "Native NetBSD audio", -#else - OBSD_DRIVER_NAME, "Native OpenBSD audio", -#endif - Audio_Available, Audio_CreateDevice -}; - -/* This function waits until it is possible to write a full sound buffer */ -static void -OBSD_WaitAudio(_THIS) -{ -#ifndef USE_BLOCKING_WRITES /* Not necessary when using blocking writes */ - /* See if we need to use timed audio synchronization */ - if ( frame_ticks ) { - /* Use timer for general audio synchronization */ - Sint32 ticks; - - ticks = ((Sint32)(next_frame - SDL_GetTicks()))-FUDGE_TICKS; - if ( ticks > 0 ) { - SDL_Delay(ticks); - } - } else { - /* Use select() for audio synchronization */ - fd_set fdset; - struct timeval timeout; - - FD_ZERO(&fdset); - FD_SET(audio_fd, &fdset); - timeout.tv_sec = 10; - timeout.tv_usec = 0; -#ifdef DEBUG_AUDIO - fprintf(stderr, "Waiting for audio to get ready\n"); -#endif - if ( select(audio_fd+1, NULL, &fdset, NULL, &timeout) <= 0 ) { - const char *message = - "Audio timeout - buggy audio driver? (disabled)"; - /* In general we should never print to the screen, - but in this case we have no other way of letting - the user know what happened. - */ - fprintf(stderr, "SDL: %s\n", message); - this->enabled = 0; - /* Don't try to close - may hang */ - audio_fd = -1; -#ifdef DEBUG_AUDIO - fprintf(stderr, "Done disabling audio\n"); -#endif - } -#ifdef DEBUG_AUDIO - fprintf(stderr, "Ready!\n"); -#endif - } -#endif /* !USE_BLOCKING_WRITES */ -} - -static void -OBSD_PlayAudio(_THIS) -{ - int written, p=0; - - /* Write the audio data, checking for EAGAIN on broken audio drivers */ - do { - written = write(audio_fd, &mixbuf[p], mixlen-p); - if (written>0) - p += written; - if (written == -1 && errno != 0 && errno != EAGAIN && errno != EINTR) - { - /* Non recoverable error has occurred. It should be reported!!! */ - perror("audio"); - break; - } - - if ( p < written || ((written < 0) && ((errno == 0) || (errno == EAGAIN))) ) { - SDL_Delay(1); /* Let a little CPU time go by */ - } - } while ( p < written ); - - /* If timer synchronization is enabled, set the next write frame */ - if ( frame_ticks ) { - next_frame += frame_ticks; - } - - /* If we couldn't write, assume fatal error for now */ - if ( written < 0 ) { - this->enabled = 0; - } -#ifdef DEBUG_AUDIO - fprintf(stderr, "Wrote %d bytes of audio data\n", written); -#endif -} - -static Uint8 -*OBSD_GetAudioBuf(_THIS) -{ - return(mixbuf); -} - -static void -OBSD_CloseAudio(_THIS) -{ - if(mixbuf != NULL) { - SDL_FreeAudioMem(mixbuf); - mixbuf = NULL; - } - if(audio_fd >= 0) { - close(audio_fd); - audio_fd = -1; - } -} - -#ifdef DEBUG_AUDIO -void -OBSD_Status(_THIS) -{ - audio_info_t info; - - if(ioctl(audio_fd, AUDIO_GETINFO, &info) < 0) { - fprintf(stderr,"AUDIO_GETINFO failed.\n"); - return; - } - - fprintf(stderr,"\n" -"[play/record info]\n" -"buffer size : %d bytes\n" -"sample rate : %i Hz\n" -"channels : %i\n" -"precision : %i-bit\n" -"encoding : 0x%x\n" -"seek : %i\n" -"sample count : %i\n" -"EOF count : %i\n" -"paused : %s\n" -"error occured : %s\n" -"waiting : %s\n" -"active : %s\n" -"", - info.play.buffer_size, - info.play.sample_rate, - info.play.channels, - info.play.precision, - info.play.encoding, - info.play.seek, - info.play.samples, - info.play.eof, - info.play.pause ? "yes" : "no", - info.play.error ? "yes" : "no", - info.play.waiting ? "yes" : "no", - info.play.active ? "yes": "no"); - - fprintf(stderr,"\n" -"[audio info]\n" -"monitor_gain : %i\n" -"hw block size : %d bytes\n" -"hi watermark : %i\n" -"lo watermark : %i\n" -"audio mode : %s\n" -"", - info.monitor_gain, - info.blocksize, - info.hiwat, info.lowat, - (info.mode == AUMODE_PLAY) ? "PLAY" - : (info.mode = AUMODE_RECORD) ? "RECORD" - : (info.mode == AUMODE_PLAY_ALL ? "PLAY_ALL" - : "?")); -} -#endif /* DEBUG_AUDIO */ - -static int -OBSD_OpenAudio(_THIS, SDL_AudioSpec *spec) -{ - char audiodev[64]; - Uint16 format; - audio_info_t info; - - AUDIO_INITINFO(&info); - - /* Calculate the final parameters for this audio specification */ - SDL_CalculateAudioSpec(spec); - -#ifdef USE_TIMER_SYNC - frame_ticks = 0.0; -#endif - - /* Open the audio device */ - audio_fd = SDL_OpenAudioPath(audiodev, sizeof(audiodev), OPEN_FLAGS, 0); - if(audio_fd < 0) { - SDL_SetError("Couldn't open %s: %s", audiodev, strerror(errno)); - return(-1); - } - - /* Set to play mode */ - info.mode = AUMODE_PLAY; - if(ioctl(audio_fd, AUDIO_SETINFO, &info) < 0) { - SDL_SetError("Couldn't put device into play mode"); - return(-1); - } - - mixbuf = NULL; - AUDIO_INITINFO(&info); - for (format = SDL_FirstAudioFormat(spec->format); - format; format = SDL_NextAudioFormat()) - { - switch(format) { - case AUDIO_U8: - info.play.encoding = AUDIO_ENCODING_ULINEAR; - info.play.precision = 8; - break; - case AUDIO_S8: - info.play.encoding = AUDIO_ENCODING_SLINEAR; - info.play.precision = 8; - break; - case AUDIO_S16LSB: - info.play.encoding = AUDIO_ENCODING_SLINEAR_LE; - info.play.precision = 16; - break; - case AUDIO_S16MSB: - info.play.encoding = AUDIO_ENCODING_SLINEAR_BE; - info.play.precision = 16; - break; - case AUDIO_U16LSB: - info.play.encoding = AUDIO_ENCODING_ULINEAR_LE; - info.play.precision = 16; - break; - case AUDIO_U16MSB: - info.play.encoding = AUDIO_ENCODING_ULINEAR_BE; - info.play.precision = 16; - break; - default: - continue; - } - if (ioctl(audio_fd, AUDIO_SETINFO, &info) == 0) - break; - } - - if(!format) { - SDL_SetError("No supported encoding for 0x%x", spec->format); - return(-1); - } - - spec->format = format; - - AUDIO_INITINFO(&info); - info.play.channels = spec->channels; - if (ioctl(audio_fd, AUDIO_SETINFO, &info) == -1) - spec->channels = 1; - AUDIO_INITINFO(&info); - info.play.sample_rate = spec->freq; - info.blocksize = spec->size; - info.hiwat = 5; - info.lowat = 3; - (void)ioctl(audio_fd, AUDIO_SETINFO, &info); - (void)ioctl(audio_fd, AUDIO_GETINFO, &info); - spec->freq = info.play.sample_rate; - /* Allocate mixing buffer */ - mixlen = spec->size; - mixbuf = (Uint8*)SDL_AllocAudioMem(mixlen); - if(mixbuf == NULL) { - return(-1); - } - SDL_memset(mixbuf, spec->silence, spec->size); - - /* Get the parent process id (we're the parent of the audio thread) */ - parent = getpid(); - -#ifdef DEBUG_AUDIO - OBSD_Status(this); -#endif - - /* We're ready to rock and roll. :-) */ - return(0); -}
--- a/src/audio/openbsd/SDL_openbsdaudio.h Tue Mar 21 09:24:10 2006 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,58 +0,0 @@ -/* - SDL - Simple DirectMedia Layer - Copyright (C) 1997-2004 Sam Lantinga - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this library; if not, write to the Free - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - - Sam Lantinga - slouken@libsdl.org -*/ -#include "SDL_config.h" - -#ifndef _SDL_openbsdaudio_h -#define _SDL_openbsdaudio_h - -#include "../SDL_sysaudio.h" - -#define _THIS SDL_AudioDevice *this - -struct SDL_PrivateAudioData -{ - /* The file descriptor for the audio device */ - int audio_fd; - - /* The parent process id, to detect when application quits */ - pid_t parent; - - /* Raw mixing buffer */ - Uint8 *mixbuf; - int mixlen; - - /* Support for audio timing using a timer, in addition to select() */ - float frame_ticks; - float next_frame; -}; - -#define FUDGE_TICKS 10 /* The scheduler overhead ticks per frame */ - -/* Old variable names */ -#define audio_fd (this->hidden->audio_fd) -#define parent (this->hidden->parent) -#define mixbuf (this->hidden->mixbuf) -#define mixlen (this->hidden->mixlen) -#define frame_ticks (this->hidden->frame_ticks) -#define next_frame (this->hidden->next_frame) - -#endif /* _SDL_openbsdaudio_h */