Merged SDL-ryan-multiple-audio-device branch r2803:2871 into the trunk.
--- a/configure.in Sun Oct 01 16:10:41 2006 +0000
+++ b/configure.in Tue Oct 17 09:15:21 2006 +0000
@@ -511,9 +511,17 @@
AC_HELP_STRING([--enable-nas], [support the NAS audio API [[default=yes]]]),
, enable_nas=yes)
if test x$enable_audio = xyes -a x$enable_nas = xyes; then
+ AC_CHECK_HEADER(audio/audiolib.h, have_nas_hdr=yes)
+ AC_CHECK_LIB(audio, AuOpenServer, have_nas_lib=yes)
+
AC_MSG_CHECKING(for NAS audio support)
have_nas=no
- if test -r /usr/X11R6/include/audio/audiolib.h; then
+
+ if test x$have_nas_hdr = xyes -a x$have_nas_lib = xyes; then
+ have_nas=yes
+ NAS_LIBS="-laudio"
+
+ elif test -r /usr/X11R6/include/audio/audiolib.h; then
have_nas=yes
NAS_CFLAGS="-I/usr/X11R6/include/"
NAS_LIBS="-L/usr/X11R6/lib -laudio -lXt"
@@ -525,12 +533,40 @@
have_nas=yes
NAS_LIBS="-lnas -lXt"
fi
+
AC_MSG_RESULT($have_nas)
+
if test x$have_nas = xyes; then
+ AC_ARG_ENABLE(nas-shared,
+AC_HELP_STRING([--enable-nas-shared], [dynamically load NAS audio support [[default=yes]]]),
+ , enable_nas_shared=yes)
+ if test "x`echo $NAS_LIBS | grep -- -L`" = "x"; then
+ if test "x`ls /lib/libaudio.so.* 2> /dev/null`" != "x"; then
+ NAS_LIBS="-L/lib $NAS_LIBS"
+ elif test "x`ls /usr/lib/libaudio.so.* 2> /dev/null`" != "x"; then
+ NAS_LIBS="-L/usr/lib $NAS_LIBS"
+ elif test "x`ls /usr/local/lib/libaudio.so.* 2> /dev/null`" != "x"; then
+ NAS_LIBS="-L/usr/local/lib $NAS_LIBS"
+ fi
+ fi
+ nas_lib_spec=`echo $NAS_LIBS | sed 's/.*-L\([[^ ]]*\).*/\1\/libaudio.so.*/'`
+ nas_lib=`ls -- $nas_lib_spec | sed 's/.*\/\(.*\)/\1/; q'`
+ echo "-- $nas_lib_spec -> $nas_lib"
+
+ if test x$have_loadso != xyes && \
+ test x$enable_nas_shared = xyes; then
+ AC_MSG_WARN([You must have SDL_LoadObject() support for dynamic NAS loading])
+ fi
+ if test x$have_loadso = xyes && \
+ test x$enable_nas_shared = xyes && test x$alsa_lib != x; then
+ AC_DEFINE_UNQUOTED(SDL_AUDIO_DRIVER_NAS_DYNAMIC, "$nas_lib")
+ else
+ EXTRA_LDFLAGS="$EXTRA_LDFLAGS $NAS_LIBS"
+ fi
+
AC_DEFINE(SDL_AUDIO_DRIVER_NAS)
SOURCES="$SOURCES $srcdir/src/audio/nas/*.c"
EXTRA_CFLAGS="$EXTRA_CFLAGS $NAS_CFLAGS"
- EXTRA_LDFLAGS="$EXTRA_LDFLAGS $NAS_LIBS"
have_audio=yes
fi
fi
@@ -2006,7 +2042,7 @@
have_audio=yes
;;
aix)
- AC_DEFINE(SDL_AUDIO_DRIVER_PAUD)
+ AC_DEFINE(SDL_AUDIO_DRIVER_PAUDIO)
SOURCES="$SOURCES $srcdir/src/audio/paudio/*.c"
have_audio=yes
;;
@@ -2206,7 +2242,7 @@
CheckBeGL
# Set up files for the audio library
if test x$enable_audio = xyes; then
- AC_DEFINE(SDL_AUDIO_DRIVER_BAUDIO)
+ AC_DEFINE(SDL_AUDIO_DRIVER_BEOSAUDIO)
SOURCES="$SOURCES $srcdir/src/audio/baudio/*.cc"
have_audio=yes
fi
@@ -2323,7 +2359,7 @@
EXTRA_LDFLAGS="$EXTRA_LDFLAGS -Wl,-framework,Carbon"
# If either the audio or CD driver is used, add the AudioUnit framework
if test x$enable_audio = xyes -o x$enable_cdrom = xyes; then
- EXTRA_LDFLAGS="$EXTRA_LDFLAGS -Wl,-framework,AudioToolbox -Wl,-framework,AudioUnit"
+ EXTRA_LDFLAGS="$EXTRA_LDFLAGS -Wl,-framework,CoreAudio -framework,AudioToolbox -Wl,-framework,AudioUnit"
fi
;;
*-*-mint*)
--- a/include/SDL_audio.h Sun Oct 01 16:10:41 2006 +0000
+++ b/include/SDL_audio.h Tue Oct 17 09:15:21 2006 +0000
@@ -153,7 +153,7 @@
/* Function prototypes */
-/* These functions return the list of built in video drivers, in the
+/* These functions return the list of built in audio drivers, in the
* order that they are normally initialized by default.
*/
extern DECLSPEC int SDLCALL SDL_GetNumAudioDrivers(void);
@@ -212,7 +212,7 @@
* may modify the requested size of the audio buffer, you should allocate
* any local mixing buffers after you open the audio device.
*/
-extern DECLSPEC int SDLCALL SDL_OpenAudio(SDL_AudioSpec * desired,
+extern DECLSPEC int SDLCALL SDL_OpenAudio(const SDL_AudioSpec * desired,
SDL_AudioSpec * obtained);
/*
@@ -228,6 +228,13 @@
/*
* Get the number of available devices exposed by the current driver.
* Only valid after a successfully initializing the audio subsystem.
+ * Returns -1 if an explicit list of devices can't be determined; this is
+ * not an error. For example, if SDL is set up to talk to a remote audio
+ * server, it can't list every one available on the Internet, but it will
+ * still allow a specific host to be specified to SDL_OpenAudioDevice().
+ * In many common cases, when this function returns a value <= 0, it can still
+ * successfully open the default device (NULL for first argument of
+ * SDL_OpenAudioDevice()).
*/
extern DECLSPEC int SDLCALL SDL_GetNumAudioDevices(int iscapture);
@@ -235,15 +242,28 @@
* Get the human-readable name of a specific audio device.
* Must be a value between 0 and (number of audio devices-1).
* Only valid after a successfully initializing the audio subsystem.
+ * The values returned by this function reflect the latest call to
+ * SDL_GetNumAudioDevices(); recall that function to redetect available
+ * hardware.
+ *
+ * The string returned by this function is UTF-8 encoded, read-only, and
+ * managed internally. You are not to free it. If you need to keep the
+ * string for any length of time, you should make your own copy of it, as it
+ * will be invalid next time any of several other SDL functions is called.
*/
-extern DECLSPEC const char *SDLCALL SDL_GetAudioDevice(int index,
- int iscapture);
+extern DECLSPEC const char *SDLCALL SDL_GetAudioDeviceName(int index,
+ int iscapture);
/*
- * Open a specific audio device. Passing in a device name of NULL is
- * equivalent to SDL_OpenAudio(). Returns 0 on error, a valid device ID
- * on success.
+ * Open a specific audio device. Passing in a device name of NULL requests
+ * the most reasonable default (and is equivalent to calling SDL_OpenAudio()).
+ * The device name is a UTF-8 string reported by SDL_GetAudioDevice(), but
+ * some drivers allow arbitrary and driver-specific strings, such as a
+ * hostname/IP address for a remote audio server, or a filename in the
+ * diskaudio driver.
+ * Returns 0 on error, a valid device ID that is >= 2 on success.
+ * SDL_OpenAudio(), unlike this function, always acts on device ID 1.
*/
extern DECLSPEC SDL_AudioDeviceID SDLCALL SDL_OpenAudioDevice(const char
*device,
--- a/include/SDL_config.h.in Sun Oct 01 16:10:41 2006 +0000
+++ b/include/SDL_config.h.in Tue Oct 17 09:15:21 2006 +0000
@@ -154,7 +154,7 @@
#undef SDL_AUDIO_DRIVER_ALSA_DYNAMIC
#undef SDL_AUDIO_DRIVER_ARTS
#undef SDL_AUDIO_DRIVER_ARTS_DYNAMIC
-#undef SDL_AUDIO_DRIVER_BAUDIO
+#undef SDL_AUDIO_DRIVER_BEOSAUDIO
#undef SDL_AUDIO_DRIVER_BSD
#undef SDL_AUDIO_DRIVER_COREAUDIO
#undef SDL_AUDIO_DRIVER_DART
@@ -168,9 +168,10 @@
#undef SDL_AUDIO_DRIVER_MINT
#undef SDL_AUDIO_DRIVER_MMEAUDIO
#undef SDL_AUDIO_DRIVER_NAS
+#undef SDL_AUDIO_DRIVER_NAS_DYNAMIC
#undef SDL_AUDIO_DRIVER_OSS
#undef SDL_AUDIO_DRIVER_OSS_SOUNDCARD_H
-#undef SDL_AUDIO_DRIVER_PAUD
+#undef SDL_AUDIO_DRIVER_PAUDIO
#undef SDL_AUDIO_DRIVER_QNXNTO
#undef SDL_AUDIO_DRIVER_SNDMGR
#undef SDL_AUDIO_DRIVER_SUNAUDIO
--- a/include/SDL_thread.h Sun Oct 01 16:10:41 2006 +0000
+++ b/include/SDL_thread.h Tue Oct 17 09:15:21 2006 +0000
@@ -91,7 +91,7 @@
typedef void (__cdecl * pfnSDL_CurrentEndThread) (unsigned code);
#endif
-extern DECLSPEC SDL_Thread *SDLCALL SDL_CreateThread(int (*fn) (void *),
+extern DECLSPEC SDL_Thread *SDLCALL SDL_CreateThread(int (SDLCALL * f) (void *),
void *data,
pfnSDL_CurrentBeginThread
pfnBeginThread,
--- a/src/SDL_error.c Sun Oct 01 16:10:41 2006 +0000
+++ b/src/SDL_error.c Tue Oct 17 09:15:21 2006 +0000
@@ -28,6 +28,7 @@
/* Routine to get the thread-specific error variable */
#if SDL_THREADS_DISABLED
+/* !!! FIXME: what does this comment mean? Victim of Search and Replace? */
/* The SDL_arraysize(The ),default (non-thread-safe) global error variable */
static SDL_error SDL_global_error;
#define SDL_GetErrBuf() (&SDL_global_error)
--- a/src/audio/SDL_audio.c Sun Oct 01 16:10:41 2006 +0000
+++ b/src/audio/SDL_audio.c Tue Oct 17 09:15:21 2006 +0000
@@ -28,11 +28,48 @@
#include "SDL_audiomem.h"
#include "SDL_sysaudio.h"
-#ifdef __OS2__
-/* We'll need the DosSetPriority() API! */
-#define INCL_DOSPROCESS
-#include <os2.h>
-#endif
+#define _THIS SDL_AudioDevice *this
+
+static SDL_AudioDriver current_audio;
+static SDL_AudioDevice *open_devices[16];
+
+/* !!! FIXME: These are wordy and unlocalized... */
+#define DEFAULT_OUTPUT_DEVNAME "System audio output device"
+#define DEFAULT_INPUT_DEVNAME "System audio capture device"
+
+
+/*
+ * Not all of these will be compiled and linked in, but it's convenient
+ * to have a complete list here and saves yet-another block of #ifdefs...
+ * Please see bootstrap[], below, for the actual #ifdef mess.
+ */
+extern AudioBootStrap BSD_AUDIO_bootstrap;
+extern AudioBootStrap DSP_bootstrap;
+extern AudioBootStrap DMA_bootstrap;
+extern AudioBootStrap ALSA_bootstrap;
+extern AudioBootStrap QNXNTOAUDIO_bootstrap;
+extern AudioBootStrap SUNAUDIO_bootstrap;
+extern AudioBootStrap DMEDIA_bootstrap;
+extern AudioBootStrap ARTS_bootstrap;
+extern AudioBootStrap ESD_bootstrap;
+extern AudioBootStrap NAS_bootstrap;
+extern AudioBootStrap DSOUND_bootstrap;
+extern AudioBootStrap WAVEOUT_bootstrap;
+extern AudioBootStrap PAUDIO_bootstrap;
+extern AudioBootStrap BEOSAUDIO_bootstrap;
+extern AudioBootStrap COREAUDIO_bootstrap;
+extern AudioBootStrap SNDMGR_bootstrap;
+extern AudioBootStrap MINTAUDIO_GSXB_bootstrap;
+extern AudioBootStrap MINTAUDIO_MCSN_bootstrap;
+extern AudioBootStrap MINTAUDIO_STFA_bootstrap;
+extern AudioBootStrap MINTAUDIO_XBIOS_bootstrap;
+extern AudioBootStrap MINTAUDIO_DMA8_bootstrap;
+extern AudioBootStrap DISKAUD_bootstrap;
+extern AudioBootStrap DUMMYAUD_bootstrap;
+extern AudioBootStrap DCAUD_bootstrap;
+extern AudioBootStrap MMEAUDIO_bootstrap;
+extern AudioBootStrap DART_bootstrap;
+
/* Available audio drivers */
static AudioBootStrap *bootstrap[] = {
@@ -70,11 +107,11 @@
#if SDL_AUDIO_DRIVER_WAVEOUT
&WAVEOUT_bootstrap,
#endif
-#if SDL_AUDIO_DRIVER_PAUD
- &Paud_bootstrap,
+#if SDL_AUDIO_DRIVER_PAUDIO
+ &PAUDIO_bootstrap,
#endif
-#if SDL_AUDIO_DRIVER_BAUDIO
- &BAUDIO_bootstrap,
+#if SDL_AUDIO_DRIVER_BEOSAUDIO
+ &BEOSAUDIO_bootstrap,
#endif
#if SDL_AUDIO_DRIVER_COREAUDIO
&COREAUDIO_bootstrap,
@@ -82,9 +119,6 @@
#if SDL_AUDIO_DRIVER_SNDMGR
&SNDMGR_bootstrap,
#endif
-#if SDL_AUDIO_DRIVER_AHI
- &AHI_bootstrap,
-#endif
#if SDL_AUDIO_DRIVER_MINT
&MINTAUDIO_GSXB_bootstrap,
&MINTAUDIO_MCSN_bootstrap,
@@ -109,227 +143,201 @@
#endif
NULL
};
-SDL_AudioDevice *current_audio = NULL;
+
+static SDL_AudioDevice *get_audio_device(SDL_AudioDeviceID id)
+{
+ id--;
+ if ( (id >= SDL_arraysize(open_devices)) || (open_devices[id] == NULL) ) {
+ SDL_SetError("Invalid audio device ID");
+ return NULL;
+ }
+
+ return open_devices[id];
+}
+
+
+/* stubs for audio drivers that don't need a specific entry point... */
+static int SDL_AudioDetectDevices_Default(int iscapture) { return -1; }
+static void SDL_AudioThreadInit_Default(_THIS) { /* no-op. */ }
+static void SDL_AudioWaitDevice_Default(_THIS) { /* no-op. */ }
+static void SDL_AudioPlayDevice_Default(_THIS) { /* no-op. */ }
+static Uint8 *SDL_AudioGetDeviceBuf_Default(_THIS) { return NULL; }
+static void SDL_AudioWaitDone_Default(_THIS) { /* no-op. */ }
+static void SDL_AudioCloseDevice_Default(_THIS) { /* no-op. */ }
+static void SDL_AudioDeinitialize_Default(void) { /* no-op. */ }
+
+static int
+SDL_AudioOpenDevice_Default(_THIS, const char *devname, int iscapture)
+{
+ return 0;
+}
+
+static const char *SDL_AudioGetDeviceName_Default(int index, int iscapture)
+{
+ SDL_SetError("No such device");
+ return NULL;
+}
-/* Various local functions */
-int SDL_AudioInit(const char *driver_name);
-void SDL_AudioQuit(void);
+static void
+SDL_AudioLockDevice_Default(SDL_AudioDevice * device)
+{
+ if (device->thread && (SDL_ThreadID() == device->threadid)) {
+ return;
+ }
+ SDL_mutexP(device->mixer_lock);
+}
+
+static void
+SDL_AudioUnlockDevice_Default(SDL_AudioDevice * device)
+{
+ if (device->thread && (SDL_ThreadID() == device->threadid)) {
+ return;
+ }
+ SDL_mutexV(device->mixer_lock);
+}
+
-#if SDL_AUDIO_DRIVER_AHI
-static int audio_configured = 0;
-#endif
+static void finalize_audio_entry_points(void)
+{
+ /*
+ * Fill in stub functions for unused driver entry points. This lets us
+ * blindly call them without having to check for validity first.
+ */
+
+ #define FILL_STUB(x) \
+ if (current_audio.impl.x == NULL) { \
+ current_audio.impl.x = SDL_Audio##x##_Default; \
+ }
+ FILL_STUB(DetectDevices);
+ FILL_STUB(GetDeviceName);
+ FILL_STUB(OpenDevice);
+ FILL_STUB(ThreadInit);
+ FILL_STUB(WaitDevice);
+ FILL_STUB(PlayDevice);
+ FILL_STUB(GetDeviceBuf);
+ FILL_STUB(WaitDone);
+ FILL_STUB(CloseDevice);
+ FILL_STUB(LockDevice);
+ FILL_STUB(UnlockDevice);
+ FILL_STUB(Deinitialize);
+ #undef FILL_STUB
+}
+
/* The general mixing thread function */
int SDLCALL
-SDL_RunAudio(void *audiop)
+SDL_RunAudio(void *devicep)
{
- SDL_AudioDevice *audio = (SDL_AudioDevice *) audiop;
+ SDL_AudioDevice *device = (SDL_AudioDevice *) devicep;
+ const int legacy_device = (device == open_devices[0]);
Uint8 *stream;
int stream_len;
void *udata;
void (SDLCALL * fill) (void *userdata, Uint8 * stream, int len);
int silence;
-#if SDL_AUDIO_DRIVER_AHI
- int started = 0;
-
-/* AmigaOS NEEDS that the audio driver is opened in the thread that uses it! */
-
- D(bug("Task audio started audio struct:<%lx>...\n", audiop));
-
- D(bug("Before Openaudio..."));
- if (audio->OpenAudio(audio, &audio->spec) == -1) {
- D(bug("Open audio failed...\n"));
- return (-1);
- }
- D(bug("OpenAudio...OK\n"));
-#endif
/* Perform any thread setup */
- if (audio->ThreadInit) {
- audio->ThreadInit(audio);
- }
- audio->threadid = SDL_ThreadID();
+ device->threadid = SDL_ThreadID();
+ current_audio.impl.ThreadInit(device);
/* Set up the mixing function */
- fill = audio->spec.callback;
- udata = audio->spec.userdata;
-
-#if SDL_AUDIO_DRIVER_AHI
- audio_configured = 1;
+ fill = device->spec.callback;
+ udata = device->spec.userdata;
- D(bug("Audio configured... Checking for conversion\n"));
- SDL_mutexP(audio->mixer_lock);
- D(bug("Semaphore obtained...\n"));
-#endif
-
- if (audio->convert.needed) {
- if (audio->convert.src_format == AUDIO_U8) {
+ if (device->convert.needed) {
+ if (device->convert.src_format == AUDIO_U8) {
silence = 0x80;
} else {
silence = 0;
}
- stream_len = audio->convert.len;
+ stream_len = device->convert.len;
} else {
- silence = audio->spec.silence;
- stream_len = audio->spec.size;
+ silence = device->spec.silence;
+ stream_len = device->spec.size;
}
-#if SDL_AUDIO_DRIVER_AHI
- SDL_mutexV(audio->mixer_lock);
- D(bug("Entering audio loop...\n"));
-#endif
-
-#ifdef __OS2__
- /* Increase the priority of this thread to make sure that
- the audio will be continuous all the time! */
-#ifdef USE_DOSSETPRIORITY
- if (SDL_getenv("SDL_USE_TIMECRITICAL_AUDIO")) {
-#ifdef DEBUG_BUILD
- printf
- ("[SDL_RunAudio] : Setting priority to TimeCritical+0! (TID%d)\n",
- SDL_ThreadID());
-#endif
- DosSetPriority(PRTYS_THREAD, PRTYC_TIMECRITICAL, 0, 0);
- } else {
-#ifdef DEBUG_BUILD
- printf
- ("[SDL_RunAudio] : Setting priority to ForegroundServer+0! (TID%d)\n",
- SDL_ThreadID());
-#endif
- DosSetPriority(PRTYS_THREAD, PRTYC_FOREGROUNDSERVER, 0, 0);
- }
-#endif
-#endif
-
/* Loop, filling the audio buffers */
- while (audio->enabled) {
+ while (device->enabled) {
/* Fill the current buffer with sound */
- if (audio->convert.needed) {
- if (audio->convert.buf) {
- stream = audio->convert.buf;
+ if (device->convert.needed) {
+ if (device->convert.buf) {
+ stream = device->convert.buf;
} else {
continue;
}
} else {
- stream = audio->GetAudioBuf(audio);
+ stream = current_audio.impl.GetDeviceBuf(device);
if (stream == NULL) {
- stream = audio->fake_stream;
+ stream = device->fake_stream;
}
}
- SDL_memset(stream, silence, stream_len);
- if (!audio->paused) {
- SDL_mutexP(audio->mixer_lock);
+ /* New code should fill buffer or set it to silence themselves. */
+ if (legacy_device) {
+ SDL_memset(stream, silence, stream_len);
+ }
+
+ if (!device->paused) {
+ SDL_mutexP(device->mixer_lock);
(*fill) (udata, stream, stream_len);
- SDL_mutexV(audio->mixer_lock);
+ SDL_mutexV(device->mixer_lock);
}
/* Convert the audio if necessary */
- if (audio->convert.needed) {
- SDL_ConvertAudio(&audio->convert);
- stream = audio->GetAudioBuf(audio);
+ if (device->convert.needed) {
+ SDL_ConvertAudio(&device->convert);
+ stream = current_audio.impl.GetDeviceBuf(device);
if (stream == NULL) {
- stream = audio->fake_stream;
+ stream = device->fake_stream;
}
- SDL_memcpy(stream, audio->convert.buf, audio->convert.len_cvt);
+ SDL_memcpy(stream, device->convert.buf, device->convert.len_cvt);
}
/* Ready current buffer for play and change current buffer */
- if (stream != audio->fake_stream) {
- audio->PlayAudio(audio);
+ if (stream != device->fake_stream) {
+ current_audio.impl.PlayDevice(device);
}
/* Wait for an audio buffer to become available */
- if (stream == audio->fake_stream) {
- SDL_Delay((audio->spec.samples * 1000) / audio->spec.freq);
+ if (stream == device->fake_stream) {
+ SDL_Delay((device->spec.samples * 1000) / device->spec.freq);
} else {
- audio->WaitAudio(audio);
+ current_audio.impl.WaitDevice(device);
}
}
/* Wait for the audio to drain.. */
- if (audio->WaitDone) {
- audio->WaitDone(audio);
- }
-#if SDL_AUDIO_DRIVER_AHI
- D(bug("WaitAudio...Done\n"));
-
- audio->CloseAudio(audio);
+ current_audio.impl.WaitDone(device);
- D(bug("CloseAudio..Done, subtask exiting...\n"));
- audio_configured = 0;
-#endif
-#ifdef __OS2__
-#ifdef DEBUG_BUILD
- printf("[SDL_RunAudio] : Task exiting. (TID%d)\n", SDL_ThreadID());
-#endif
-#endif
return (0);
}
-static void
-SDL_LockAudio_Default(SDL_AudioDevice * audio)
-{
- if (audio->thread && (SDL_ThreadID() == audio->threadid)) {
- return;
- }
- SDL_mutexP(audio->mixer_lock);
-}
-
-static void
-SDL_UnlockAudio_Default(SDL_AudioDevice * audio)
-{
- if (audio->thread && (SDL_ThreadID() == audio->threadid)) {
- return;
- }
- SDL_mutexV(audio->mixer_lock);
-}
static SDL_AudioFormat
SDL_ParseAudioFormat(const char *string)
{
- SDL_AudioFormat format = 0;
-
- switch (*string) {
- case 'U':
- ++string;
- format |= 0x0000;
- break;
- case 'S':
- ++string;
- format |= 0x8000;
- break;
- default:
- return 0;
- }
- switch (SDL_atoi(string)) {
- case 8:
- string += 1;
- format |= 8;
- break;
- case 16:
- string += 2;
- format |= 16;
- if (SDL_strcmp(string, "LSB") == 0
-#if SDL_BYTEORDER == SDL_LIL_ENDIAN
- || SDL_strcmp(string, "SYS") == 0
-#endif
- ) {
- format |= 0x0000;
- }
- if (SDL_strcmp(string, "MSB") == 0
-#if SDL_BYTEORDER == SDL_BIG_ENDIAN
- || SDL_strcmp(string, "SYS") == 0
-#endif
- ) {
- format |= 0x1000;
- }
- break;
- default:
- return 0;
- }
- return format;
+ #define CHECK_FMT_STRING(x) if (strcmp(string, #x) == 0) return AUDIO_##x
+ CHECK_FMT_STRING(U8);
+ CHECK_FMT_STRING(S8);
+ CHECK_FMT_STRING(U16LSB);
+ CHECK_FMT_STRING(S16LSB);
+ CHECK_FMT_STRING(U16MSB);
+ CHECK_FMT_STRING(S16MSB);
+ CHECK_FMT_STRING(U16SYS);
+ CHECK_FMT_STRING(S16SYS);
+ CHECK_FMT_STRING(U16);
+ CHECK_FMT_STRING(S16);
+ CHECK_FMT_STRING(S32LSB);
+ CHECK_FMT_STRING(S32MSB);
+ CHECK_FMT_STRING(S32SYS);
+ CHECK_FMT_STRING(S32);
+ CHECK_FMT_STRING(F32LSB);
+ CHECK_FMT_STRING(F32MSB);
+ CHECK_FMT_STRING(F32SYS);
+ CHECK_FMT_STRING(F32);
+ #undef CHECK_FMT_STRING
+ return 0;
}
int
@@ -350,92 +358,53 @@
int
SDL_AudioInit(const char *driver_name)
{
- SDL_AudioDevice *audio;
- int i = 0, idx;
+ int i = 0;
+ int initialized = 0;
+ int tried_to_init = 0;
- /* Check to make sure we don't overwrite 'current_audio' */
- if (current_audio != NULL) {
- SDL_AudioQuit();
+ if (SDL_WasInit(SDL_INIT_AUDIO)) {
+ SDL_AudioQuit(); /* shutdown driver if already running. */
}
+ SDL_memset(¤t_audio, '\0', sizeof (current_audio));
+ SDL_memset(open_devices, '\0', sizeof (open_devices));
+
/* Select the proper audio driver */
- audio = NULL;
- idx = 0;
if (driver_name == NULL) {
driver_name = SDL_getenv("SDL_AUDIODRIVER");
}
-#if SDL_AUDIO_DRIVER_ESD
- if ((driver_name == NULL) && (SDL_getenv("ESPEAKER") != NULL)) {
- /* Ahem, we know that if ESPEAKER is set, user probably wants
- to use ESD, but don't start it if it's not already running.
- This probably isn't the place to do this, but... Shh! :)
- */
- for (i = 0; bootstrap[i]; ++i) {
- if (SDL_strcasecmp(bootstrap[i]->name, "esd") == 0) {
-#ifdef HAVE_PUTENV
- const char *esd_no_spawn;
+
+ for (i = 0; (!initialized) && (bootstrap[i]); ++i) {
+ /* make sure we should even try this driver before doing so... */
+ const AudioBootStrap *backend = bootstrap[i];
+ if ( ((driver_name) && (SDL_strcasecmp(backend->name, driver_name))) ||
+ ((!driver_name) && (backend->demand_only)) ) {
+ continue;
+ }
- /* Don't start ESD if it's not running */
- esd_no_spawn = getenv("ESD_NO_SPAWN");
- if (esd_no_spawn == NULL) {
- putenv("ESD_NO_SPAWN=1");
- }
-#endif
- if (bootstrap[i]->available()) {
- audio = bootstrap[i]->create(0);
- break;
- }
-#ifdef HAVE_UNSETENV
- if (esd_no_spawn == NULL) {
- unsetenv("ESD_NO_SPAWN");
- }
-#endif
- }
- }
+ tried_to_init = 1;
+ SDL_memset(¤t_audio, 0, sizeof (current_audio));
+ current_audio.name = backend->name;
+ current_audio.desc = backend->desc;
+ initialized = backend->init(¤t_audio.impl);
}
-#endif /* SDL_AUDIO_DRIVER_ESD */
- if (audio == NULL) {
- if (driver_name != NULL) {
- for (i = 0; bootstrap[i]; ++i) {
- if (SDL_strcasecmp(bootstrap[i]->name, driver_name) == 0) {
- if (bootstrap[i]->available()) {
- audio = bootstrap[i]->create(idx);
- }
- break;
- }
- }
- } else {
- for (i = 0; bootstrap[i]; ++i) {
- if (bootstrap[i]->available()) {
- audio = bootstrap[i]->create(idx);
- if (audio != NULL) {
- break;
- }
- }
- }
- }
- if (audio == NULL) {
+
+ if (!initialized) {
+ /* specific drivers will set the error message if they fail... */
+ if (!tried_to_init) {
if (driver_name) {
SDL_SetError("%s not available", driver_name);
} else {
SDL_SetError("No available audio device");
}
-#if 0
- /* Don't fail SDL_Init() if audio isn't available.
- SDL_OpenAudio() will handle it at that point. *sigh*
- */
- return (-1);
-#endif
}
+
+ SDL_memset(¤t_audio, 0, sizeof (current_audio));
+ return (-1); /* No driver was available, so fail. */
}
- current_audio = audio;
- if (current_audio) {
- current_audio->name = bootstrap[i]->name;
- if (!current_audio->LockAudio && !current_audio->UnlockAudio) {
- current_audio->LockAudio = SDL_LockAudio_Default;
- current_audio->UnlockAudio = SDL_UnlockAudio_Default;
- }
- }
+
+ finalize_audio_entry_points();
+
return (0);
}
@@ -445,222 +414,369 @@
const char *
SDL_GetCurrentAudioDriver()
{
- if (current_audio) {
- return current_audio->name;
- }
- return (NULL);
+ return current_audio.name;
}
+
int
-SDL_OpenAudio(SDL_AudioSpec * desired, SDL_AudioSpec * obtained)
+SDL_GetNumAudioDevices(int iscapture)
{
- SDL_AudioDevice *audio;
- const char *env;
+ if (!SDL_WasInit(SDL_INIT_AUDIO)) {
+ return -1;
+ }
+ if ((iscapture) && (!current_audio.impl.HasCaptureSupport)) {
+ return 0;
+ }
+
+ if ((iscapture) && (current_audio.impl.OnlyHasDefaultInputDevice)) {
+ return 1;
+ }
+
+ if ((!iscapture) && (current_audio.impl.OnlyHasDefaultOutputDevice)) {
+ return 1;
+ }
+
+ return current_audio.impl.DetectDevices(iscapture);
+}
+
- /* Start up the audio driver, if necessary */
- if (!current_audio) {
- if ((SDL_InitSubSystem(SDL_INIT_AUDIO) < 0) ||
- (current_audio == NULL)) {
- return (-1);
- }
+const char *
+SDL_GetAudioDeviceName(int index, int iscapture)
+{
+ if (!SDL_WasInit(SDL_INIT_AUDIO)) {
+ SDL_SetError("Audio subsystem is not initialized");
+ return NULL;
+ }
+
+ if ((iscapture) && (!current_audio.impl.HasCaptureSupport)) {
+ SDL_SetError("No capture support");
+ return NULL;
}
- audio = current_audio;
+
+ if (index < 0) {
+ SDL_SetError("No such device");
+ return NULL;
+ }
- if (audio->opened) {
- SDL_SetError("Audio device is already opened");
- return (-1);
+ if ((iscapture) && (current_audio.impl.OnlyHasDefaultInputDevice)) {
+ return DEFAULT_INPUT_DEVNAME;
+ }
+
+ if ((!iscapture) && (current_audio.impl.OnlyHasDefaultOutputDevice)) {
+ return DEFAULT_OUTPUT_DEVNAME;
}
- /* Verify some parameters */
- if (desired->freq == 0) {
- env = SDL_getenv("SDL_AUDIO_FREQUENCY");
- if (env) {
- desired->freq = SDL_atoi(env);
+ return current_audio.impl.GetDeviceName(index, iscapture);
+}
+
+
+static void
+close_audio_device(SDL_AudioDevice *device)
+{
+ device->enabled = 0;
+ if (device->thread != NULL) {
+ SDL_WaitThread(device->thread, NULL);
+ }
+ if (device->mixer_lock != NULL) {
+ SDL_DestroyMutex(device->mixer_lock);
+ }
+ if (device->fake_stream != NULL) {
+ SDL_FreeAudioMem(device->fake_stream);
+ }
+ if (device->convert.needed) {
+ SDL_FreeAudioMem(device->convert.buf);
+ }
+ if (device->opened) {
+ current_audio.impl.CloseDevice(device);
+ device->opened = 0;
+ }
+ SDL_FreeAudioMem(device);
+}
+
+
+/*
+ * Sanity check desired AudioSpec for SDL_OpenAudio() in (orig).
+ * Fills in a sanitized copy in (prepared).
+ * Returns non-zero if okay, zero on fatal parameters in (orig).
+ */
+static int
+prepare_audiospec(const SDL_AudioSpec *orig, SDL_AudioSpec *prepared)
+{
+ SDL_memcpy(prepared, orig, sizeof (SDL_AudioSpec));
+
+ if (orig->callback == NULL) {
+ SDL_SetError("SDL_OpenAudio() passed a NULL callback");
+ return 0;
+ }
+
+ if (orig->freq == 0) {
+ const char *env = SDL_getenv("SDL_AUDIO_FREQUENCY");
+ if ( (!env) || ((prepared->freq = SDL_atoi(env)) == 0) ) {
+ prepared->freq = 22050; /* a reasonable default */
}
}
- if (desired->freq == 0) {
- /* Pick some default audio frequency */
- desired->freq = 22050;
- }
- if (desired->format == 0) {
- env = SDL_getenv("SDL_AUDIO_FORMAT");
- if (env) {
- desired->format = SDL_ParseAudioFormat(env);
+
+ if (orig->format == 0) {
+ const char *env = SDL_getenv("SDL_AUDIO_FORMAT");
+ if ((!env) || ((prepared->format = SDL_ParseAudioFormat(env)) == 0)) {
+ prepared->format = AUDIO_S16; /* a reasonable default */
}
}
- if (desired->format == 0) {
- /* Pick some default audio format */
- desired->format = AUDIO_S16;
+
+ switch (orig->channels) {
+ case 0: {
+ const char *env = SDL_getenv("SDL_AUDIO_CHANNELS");
+ if ( (!env) || ((prepared->channels = SDL_atoi(env)) == 0) ) {
+ prepared->channels = 2; /* a reasonable default */
+ }
+ break;
}
- if (desired->channels == 0) {
- env = SDL_getenv("SDL_AUDIO_CHANNELS");
- if (env) {
- desired->channels = (Uint8) SDL_atoi(env);
- }
- }
- if (desired->channels == 0) {
- /* Pick a default number of channels */
- desired->channels = 2;
- }
- switch (desired->channels) {
case 1: /* Mono */
case 2: /* Stereo */
case 4: /* surround */
case 6: /* surround with center and lfe */
break;
default:
- SDL_SetError("1 (mono) and 2 (stereo) channels supported");
- return (-1);
+ SDL_SetError("Unsupported number of audio channels.");
+ return 0;
}
- if (desired->samples == 0) {
- env = SDL_getenv("SDL_AUDIO_SAMPLES");
- if (env) {
- desired->samples = (Uint16) SDL_atoi(env);
+
+ if (orig->samples == 0) {
+ const char *env = SDL_getenv("SDL_AUDIO_SAMPLES");
+ if ( (!env) || ((prepared->samples = (Uint16) SDL_atoi(env)) == 0) ) {
+ /* Pick a default of ~46 ms at desired frequency */
+ /* !!! FIXME: remove this when the non-Po2 resampling is in. */
+ const int samples = (prepared->freq / 1000) * 46;
+ int power2 = 1;
+ while (power2 < samples) {
+ power2 *= 2;
+ }
+ prepared->samples = power2;
}
}
- if (desired->samples == 0) {
- /* Pick a default of ~46 ms at desired frequency */
- int samples = (desired->freq / 1000) * 46;
- int power2 = 1;
- while (power2 < samples) {
- power2 *= 2;
- }
- desired->samples = power2;
- }
- if (desired->callback == NULL) {
- SDL_SetError("SDL_OpenAudio() passed a NULL callback");
- return (-1);
- }
-#if defined(__MINT__) && SDL_THREADS_DISABLED
- /* Uses interrupt driven audio, without thread */
-#else
- /* Create a semaphore for locking the sound buffers */
- audio->mixer_lock = SDL_CreateMutex();
- if (audio->mixer_lock == NULL) {
- SDL_SetError("Couldn't create mixer lock");
- SDL_CloseAudio();
- return (-1);
- }
-#endif /* __MINT__ */
/* Calculate the silence and size of the audio specification */
- SDL_CalculateAudioSpec(desired);
-
- /* Open the audio subsystem */
- SDL_memcpy(&audio->spec, desired, sizeof(audio->spec));
- audio->convert.needed = 0;
- audio->enabled = 1;
- audio->paused = 1;
-
-#if !SDL_AUDIO_DRIVER_AHI
+ SDL_CalculateAudioSpec(prepared);
-/* AmigaOS opens audio inside the main loop */
- audio->opened = audio->OpenAudio(audio, &audio->spec) + 1;
-
- if (!audio->opened) {
- SDL_CloseAudio();
- return (-1);
- }
-#else
- D(bug("Locking semaphore..."));
- SDL_mutexP(audio->mixer_lock);
+ return 1;
+}
- audio->thread = SDL_CreateThread(SDL_RunAudio, audio);
- D(bug("Created thread...\n"));
+static SDL_AudioDeviceID
+open_audio_device(const char *devname, int iscapture,
+ const SDL_AudioSpec *_desired, SDL_AudioSpec *obtained,
+ int min_id)
+{
+ SDL_AudioDeviceID id = 0;
+ SDL_AudioSpec desired;
+ SDL_AudioDevice *device;
+ int i = 0;
- if (audio->thread == NULL) {
- SDL_mutexV(audio->mixer_lock);
- SDL_CloseAudio();
- SDL_SetError("Couldn't create audio thread");
- return (-1);
+ if (!SDL_WasInit(SDL_INIT_AUDIO)) {
+ SDL_SetError("Audio subsystem is not initialized");
+ return 0;
+ }
+
+ if ((iscapture) && (!current_audio.impl.HasCaptureSupport)) {
+ SDL_SetError("No capture support");
+ return 0;
+ }
+
+ if (!prepare_audiospec(_desired, &desired)) {
+ return 0;
+ }
+
+ /* If app doesn't care about a specific device, let the user override. */
+ if (devname == NULL) {
+ devname = SDL_getenv("SDL_AUDIO_DEVICE_NAME");
}
- while (!audio_configured)
- SDL_Delay(100);
-#endif
+ /*
+ * Catch device names at the high level for the simple case...
+ * This lets us have a basic "device enumeration" for systems that
+ * don't have multiple devices, but makes sure the device name is
+ * always NULL when it hits the low level.
+ *
+ * Also make sure that the simple case prevents multiple simultaneous
+ * opens of the default system device.
+ */
+
+ if ((iscapture) && (current_audio.impl.OnlyHasDefaultInputDevice)) {
+ if ((devname) && (SDL_strcmp(devname, DEFAULT_INPUT_DEVNAME) != 0)) {
+ SDL_SetError("No such device");
+ return 0;
+ }
+ devname = NULL;
+
+ for (i = 0; i < SDL_arraysize(open_devices); i++) {
+ if ((open_devices[i]) && (open_devices[i]->iscapture)) {
+ SDL_SetError("Audio device already open");
+ return 0;
+ }
+ }
+ }
+
+ if ((!iscapture) && (current_audio.impl.OnlyHasDefaultOutputDevice)) {
+ if ((devname) && (SDL_strcmp(devname, DEFAULT_OUTPUT_DEVNAME) != 0)) {
+ SDL_SetError("No such device");
+ return 0;
+ }
+ devname = NULL;
+
+ for (i = 0; i < SDL_arraysize(open_devices); i++) {
+ if ((open_devices[i]) && (!open_devices[i]->iscapture)) {
+ SDL_SetError("Audio device already open");
+ return 0;
+ }
+ }
+ }
+
+ device = (SDL_AudioDevice *) SDL_AllocAudioMem(sizeof (SDL_AudioDevice));
+ if (device == NULL) {
+ SDL_OutOfMemory();
+ return 0;
+ }
+ SDL_memset(device, '\0', sizeof (SDL_AudioDevice));
+ SDL_memcpy(&device->spec, &desired, sizeof (SDL_AudioSpec));
+ device->enabled = 1;
+ device->paused = 1;
+ device->iscapture = iscapture;
+
+ /* Create a semaphore for locking the sound buffers */
+ if (!current_audio.impl.SkipMixerLock) {
+ device->mixer_lock = SDL_CreateMutex();
+ if (device->mixer_lock == NULL) {
+ close_audio_device(device);
+ SDL_SetError("Couldn't create mixer lock");
+ return 0;
+ }
+ }
+
+ if (!current_audio.impl.OpenDevice(device, devname, iscapture)) {
+ close_audio_device(device);
+ return 0;
+ }
+ device->opened = 1;
/* If the audio driver changes the buffer size, accept it */
- if (audio->spec.samples != desired->samples) {
- desired->samples = audio->spec.samples;
- SDL_CalculateAudioSpec(desired);
+ if (device->spec.samples != desired.samples) {
+ desired.samples = device->spec.samples;
+ SDL_CalculateAudioSpec(&device->spec);
}
/* Allocate a fake audio memory buffer */
- audio->fake_stream = SDL_AllocAudioMem(audio->spec.size);
- if (audio->fake_stream == NULL) {
- SDL_CloseAudio();
+ device->fake_stream = SDL_AllocAudioMem(device->spec.size);
+ if (device->fake_stream == NULL) {
+ close_audio_device(device);
SDL_OutOfMemory();
- return (-1);
+ return 0;
}
/* See if we need to do any conversion */
if (obtained != NULL) {
- SDL_memcpy(obtained, &audio->spec, sizeof(audio->spec));
- } else if (desired->freq != audio->spec.freq ||
- desired->format != audio->spec.format ||
- desired->channels != audio->spec.channels) {
+ SDL_memcpy(obtained, &device->spec, sizeof(SDL_AudioSpec));
+ } else if (desired.freq != device->spec.freq ||
+ desired.format != device->spec.format ||
+ desired.channels != device->spec.channels) {
/* Build an audio conversion block */
- if (SDL_BuildAudioCVT(&audio->convert,
- desired->format, desired->channels,
- desired->freq,
- audio->spec.format, audio->spec.channels,
- audio->spec.freq) < 0) {
- SDL_CloseAudio();
- return (-1);
+ if (SDL_BuildAudioCVT(&device->convert,
+ desired.format, desired.channels,
+ desired.freq,
+ device->spec.format, device->spec.channels,
+ device->spec.freq) < 0) {
+ close_audio_device(device);
+ return 0;
}
- if (audio->convert.needed) {
- audio->convert.len = desired->size;
- audio->convert.buf =
- (Uint8 *) SDL_AllocAudioMem(audio->convert.len *
- audio->convert.len_mult);
- if (audio->convert.buf == NULL) {
- SDL_CloseAudio();
+ if (device->convert.needed) {
+ device->convert.len = desired.size;
+ device->convert.buf =
+ (Uint8 *) SDL_AllocAudioMem(device->convert.len *
+ device->convert.len_mult);
+ if (device->convert.buf == NULL) {
+ close_audio_device(device);
SDL_OutOfMemory();
- return (-1);
+ return 0;
}
}
}
-#if !SDL_AUDIO_DRIVER_AHI
+
+ /* Find an available device ID and store the structure... */
+ for (id = min_id-1; id < SDL_arraysize(open_devices); id++) {
+ if (open_devices[id] == NULL) {
+ open_devices[id] = device;
+ break;
+ }
+ }
+
+ if (id == SDL_arraysize(open_devices)) {
+ SDL_SetError("Too many open audio devices");
+ close_audio_device(device);
+ return 0;
+ }
+
/* Start the audio thread if necessary */
- switch (audio->opened) {
- case 1:
+ if (!current_audio.impl.ProvidesOwnCallbackThread) {
/* Start the audio thread */
+/* !!! FIXME: this is nasty. */
#if (defined(__WIN32__) && !defined(_WIN32_WCE)) && !defined(HAVE_LIBC)
#undef SDL_CreateThread
- audio->thread = SDL_CreateThread(SDL_RunAudio, audio, NULL, NULL);
+ device->thread = SDL_CreateThread(SDL_RunAudio, device, NULL, NULL);
#else
- audio->thread = SDL_CreateThread(SDL_RunAudio, audio);
+ device->thread = SDL_CreateThread(SDL_RunAudio, device);
#endif
- if (audio->thread == NULL) {
- SDL_CloseAudio();
+ if (device->thread == NULL) {
+ SDL_CloseAudioDevice(id+1);
SDL_SetError("Couldn't create audio thread");
+ return 0;
+ }
+ }
+
+ return id+1;
+}
+
+
+int
+SDL_OpenAudio(const SDL_AudioSpec * desired, SDL_AudioSpec * obtained)
+{
+ SDL_AudioDeviceID id = 0;
+
+ /* Start up the audio driver, if necessary. This is legacy behaviour! */
+ if (!SDL_WasInit(SDL_INIT_AUDIO)) {
+ if (SDL_InitSubSystem(SDL_INIT_AUDIO) < 0) {
return (-1);
}
- break;
+ }
- default:
- /* The audio is now playing */
- break;
+ /* SDL_OpenAudio() is legacy and can only act on Device ID #1. */
+ if (open_devices[0] != NULL) {
+ SDL_SetError("Audio device is already opened");
+ return (-1);
}
-#else
- SDL_mutexV(audio->mixer_lock);
- D(bug("SDL_OpenAudio USCITA...\n"));
+
+ id = open_audio_device(NULL, 0, desired, obtained, 1);
+ if (id > 1) { /* this should never happen in theory... */
+ SDL_CloseAudioDevice(id);
+ SDL_SetError("Internal error"); /* MUST be Device ID #1! */
+ return (-1);
+ }
-#endif
+ return ((id == 0) ? -1 : 0);
+}
- return (0);
+SDL_AudioDeviceID
+SDL_OpenAudioDevice(const char *device, int iscapture,
+ const SDL_AudioSpec *desired, SDL_AudioSpec *obtained)
+{
+ return open_audio_device(device, iscapture, desired, obtained, 2);
}
SDL_audiostatus
-SDL_GetAudioStatus(void)
+SDL_GetAudioDeviceStatus(SDL_AudioDeviceID devid)
{
- SDL_AudioDevice *audio = current_audio;
- SDL_audiostatus status;
-
- status = SDL_AUDIO_STOPPED;
- if (audio && audio->enabled) {
- if (audio->paused) {
+ SDL_AudioDevice *device = get_audio_device(devid);
+ SDL_audiostatus status = SDL_AUDIO_STOPPED;
+ if (device && device->enabled) {
+ if (device->paused) {
status = SDL_AUDIO_PAUSED;
} else {
status = SDL_AUDIO_PLAYING;
@@ -669,74 +785,89 @@
return (status);
}
+
+SDL_audiostatus
+SDL_GetAudioStatus(void)
+{
+ return SDL_GetAudioDeviceStatus(1);
+}
+
+void
+SDL_PauseAudioDevice(SDL_AudioDeviceID devid, int pause_on)
+{
+ SDL_AudioDevice *device = get_audio_device(devid);
+ if (device) {
+ device->paused = pause_on;
+ }
+}
+
void
SDL_PauseAudio(int pause_on)
{
- SDL_AudioDevice *audio = current_audio;
+ SDL_PauseAudioDevice(1, pause_on);
+}
+
- if (audio) {
- audio->paused = pause_on;
+void
+SDL_LockAudioDevice(SDL_AudioDeviceID devid)
+{
+ /* Obtain a lock on the mixing buffers */
+ SDL_AudioDevice *device = get_audio_device(devid);
+ if (device) {
+ current_audio.impl.LockDevice(device);
}
}
void
SDL_LockAudio(void)
{
- SDL_AudioDevice *audio = current_audio;
+ SDL_LockAudioDevice(1);
+}
+void
+SDL_UnlockAudioDevice(SDL_AudioDeviceID devid)
+{
/* Obtain a lock on the mixing buffers */
- if (audio && audio->LockAudio) {
- audio->LockAudio(audio);
+ SDL_AudioDevice *device = get_audio_device(devid);
+ if (device) {
+ current_audio.impl.UnlockDevice(device);
}
}
void
SDL_UnlockAudio(void)
{
- SDL_AudioDevice *audio = current_audio;
+ SDL_UnlockAudioDevice(1);
+}
- /* Release lock on the mixing buffers */
- if (audio && audio->UnlockAudio) {
- audio->UnlockAudio(audio);
+void
+SDL_CloseAudioDevice(SDL_AudioDeviceID devid)
+{
+ SDL_AudioDevice *device = get_audio_device(devid);
+ if (device) {
+ close_audio_device(device);
+ open_devices[devid-1] = NULL;
}
}
void
SDL_CloseAudio(void)
{
- SDL_QuitSubSystem(SDL_INIT_AUDIO);
+ SDL_CloseAudioDevice(1);
}
void
SDL_AudioQuit(void)
{
- SDL_AudioDevice *audio = current_audio;
+ SDL_AudioDeviceID i;
+ for (i = 0; i < SDL_arraysize(open_devices); i++) {
+ SDL_CloseAudioDevice(i);
+ }
- if (audio) {
- audio->enabled = 0;
- if (audio->thread != NULL) {
- SDL_WaitThread(audio->thread, NULL);
- }
- if (audio->mixer_lock != NULL) {
- SDL_DestroyMutex(audio->mixer_lock);
- }
- if (audio->fake_stream != NULL) {
- SDL_FreeAudioMem(audio->fake_stream);
- }
- if (audio->convert.needed) {
- SDL_FreeAudioMem(audio->convert.buf);
-
- }
-#if !SDL_AUDIO_DRIVER_AHI
- if (audio->opened) {
- audio->CloseAudio(audio);
- audio->opened = 0;
- }
-#endif
- /* Free the driver data */
- audio->free(audio);
- current_audio = NULL;
- }
+ /* Free the driver data */
+ current_audio.impl.Deinitialize();
+ SDL_memset(¤t_audio, '\0', sizeof (current_audio));
+ SDL_memset(open_devices, '\0', sizeof (open_devices));
}
#define NUM_FORMATS 10
@@ -797,9 +928,30 @@
spec->silence = 0x00;
break;
}
- spec->size = (spec->format & 0xFF) / 8;
+ spec->size = SDL_AUDIO_BITSIZE(spec->format) / 8;
spec->size *= spec->channels;
spec->size *= spec->samples;
}
+
+/*
+ * Moved here from SDL_mixer.c, since it relies on internals of an opened
+ * audio device (and is deprecated, by the way!).
+ */
+void
+SDL_MixAudio(Uint8 * dst, const Uint8 * src, Uint32 len, int volume)
+{
+ /* Mix the user-level audio format */
+ SDL_AudioDevice *device = get_audio_device(1);
+ if (device != NULL) {
+ SDL_AudioFormat format;
+ if (device->convert.needed) {
+ format = device->convert.src_format;
+ } else {
+ format = device->spec.format;
+ }
+ SDL_MixAudioFormat(dst, src, format, len, volume);
+ }
+}
+
/* vi: set ts=4 sw=4 expandtab: */
--- a/src/audio/SDL_audiocvt.c Sun Oct 01 16:10:41 2006 +0000
+++ b/src/audio/SDL_audiocvt.c Tue Oct 17 09:15:21 2006 +0000
@@ -159,21 +159,19 @@
float *dst = (float *) cvt->buf;
if (SDL_AUDIO_ISBIGENDIAN(format)) {
for (i = cvt->len_cvt / 8; i; --i, src += 2) {
- float src1, src2;
- src1 = SDL_SwapFloatBE(src[0]);
- src2 = SDL_SwapFloatBE(src[1]);
+ const float src1 = SDL_SwapFloatBE(src[0]);
+ const float src2 = SDL_SwapFloatBE(src[1]);
const double added = ((double) src1) + ((double) src2);
- src1 = (float) (added * 0.5);
- *(dst++) = SDL_SwapFloatBE(src1);
+ const float halved = (float) (added * 0.5);
+ *(dst++) = SDL_SwapFloatBE(halved);
}
} else {
for (i = cvt->len_cvt / 8; i; --i, src += 2) {
- float src1, src2;
- src1 = SDL_SwapFloatLE(src[0]);
- src2 = SDL_SwapFloatLE(src[1]);
+ const float src1 = SDL_SwapFloatLE(src[0]);
+ const float src2 = SDL_SwapFloatLE(src[1]);
const double added = ((double) src1) + ((double) src2);
- src1 = (float) (added * 0.5);
- *(dst++) = SDL_SwapFloatLE(src1);
+ const float halved = (float) (added * 0.5);
+ *(dst++) = SDL_SwapFloatLE(halved);
}
}
}
--- a/src/audio/SDL_audiodev.c Sun Oct 01 16:10:41 2006 +0000
+++ b/src/audio/SDL_audiodev.c Tue Oct 17 09:15:21 2006 +0000
@@ -46,14 +46,63 @@
#define _PATH_DEV_AUDIO "/dev/audio"
#endif
+static inline void
+test_device(const char *fname, int flags, int (*test)(int fd),
+ char ***devices, int *devCount)
+{
+ struct stat sb;
+ if ( (stat(fname, &sb) == 0) && (S_ISCHR(sb.st_mode)) ) {
+ int audio_fd = open(fname, flags, 0);
+ if ( (audio_fd >= 0) && (test(audio_fd)) ) {
+ void *p = SDL_realloc(*devices, ((*devCount)+1) * sizeof (char *));
+ if (p != NULL) {
+ size_t len = strlen(fname) + 1;
+ char *str = (char *) SDL_malloc(len);
+ *devices = (char **) p;
+ if (str != NULL) {
+ SDL_strlcpy(str, fname, len);
+ (*devices)[(*devCount)++] = str;
+ }
+ }
+ close(audio_fd);
+ }
+ }
+}
-int
-SDL_OpenAudioPath(char *path, int maxlen, int flags, int classic)
+void
+SDL_FreeUnixAudioDevices(char ***devices, int *devCount)
+{
+ int i = *devCount;
+ if ((i > 0) && (*devices != NULL)) {
+ while (i--) {
+ SDL_free( (*devices)[*devCount] );
+ }
+ }
+
+ if (*devices != NULL) {
+ SDL_free(*devices);
+ }
+
+ *devices = NULL;
+ *devCount = 0;
+}
+
+static int
+test_stub(int fd)
+{
+ return 1;
+}
+
+void
+SDL_EnumUnixAudioDevices(int flags, int classic, int (*test)(int fd),
+ char ***devices, int *devCount)
{
const char *audiodev;
- int audio_fd;
char audiopath[1024];
+ if (test == NULL)
+ test = test_stub;
+
/* Figure out what our audio device is */
if (((audiodev = SDL_getenv("SDL_PATH_DSP")) == NULL) &&
((audiodev = SDL_getenv("AUDIODEV")) == NULL)) {
@@ -72,111 +121,16 @@
}
}
}
- audio_fd = open(audiodev, flags, 0);
-
- /* If the first open fails, look for other devices */
- if ((audio_fd < 0) && (SDL_strlen(audiodev) < (sizeof(audiopath) - 3))) {
- int exists, instance;
- struct stat sb;
-
- instance = 1;
- do { /* Don't use errno ENOENT - it may not be thread-safe */
- SDL_snprintf(audiopath, SDL_arraysize(audiopath),
- "%s%d", audiodev, instance++);
- exists = 0;
- if (stat(audiopath, &sb) == 0) {
- exists = 1;
- audio_fd = open(audiopath, flags, 0);
- }
- }
- while (exists && (audio_fd < 0));
- audiodev = audiopath;
- }
- if (path != NULL) {
- SDL_strlcpy(path, audiodev, maxlen);
- path[maxlen - 1] = '\0';
- }
- return (audio_fd);
-}
-
-#elif SDL_AUDIO_DRIVER_PAUD
-
-/* Get the name of the audio device we use for output */
-
-#include <sys/types.h>
-#include <sys/stat.h>
-
-#include "SDL_stdinc.h"
-#include "SDL_audiodev_c.h"
-
-#ifndef _PATH_DEV_DSP
-#define _PATH_DEV_DSP "/dev/%caud%c/%c"
-#endif
+ test_device(audiodev, flags, test, devices, devCount);
-char devsettings[][3] = {
- {'p', '0', '1'}, {'p', '0', '2'}, {'p', '0', '3'}, {'p', '0', '4'},
- {'p', '1', '1'}, {'p', '1', '2'}, {'p', '1', '3'}, {'p', '1', '4'},
- {'p', '2', '1'}, {'p', '2', '2'}, {'p', '2', '3'}, {'p', '2', '4'},
- {'p', '3', '1'}, {'p', '3', '2'}, {'p', '3', '3'}, {'p', '3', '4'},
- {'b', '0', '1'}, {'b', '0', '2'}, {'b', '0', '3'}, {'b', '0', '4'},
- {'b', '1', '1'}, {'b', '1', '2'}, {'b', '1', '3'}, {'b', '1', '4'},
- {'b', '2', '1'}, {'b', '2', '2'}, {'b', '2', '3'}, {'b', '2', '4'},
- {'b', '3', '1'}, {'b', '3', '2'}, {'b', '3', '3'}, {'b', '3', '4'},
- {'\0', '\0', '\0'}
-};
-
-static int
-OpenUserDefinedDevice(char *path, int maxlen, int flags)
-{
- const char *audiodev;
- int audio_fd;
-
- /* Figure out what our audio device is */
- if ((audiodev = SDL_getenv("SDL_PATH_DSP")) == NULL) {
- audiodev = SDL_getenv("AUDIODEV");
- }
- if (audiodev == NULL) {
- return -1;
- }
- audio_fd = open(audiodev, flags, 0);
- if (path != NULL) {
- SDL_strlcpy(path, audiodev, maxlen);
- path[maxlen - 1] = '\0';
- }
- return audio_fd;
-}
-
-int
-SDL_OpenAudioPath(char *path, int maxlen, int flags, int classic)
-{
- struct stat sb;
- int audio_fd;
- char audiopath[1024];
- int cycle;
-
- audio_fd = OpenUserDefinedDevice(path, maxlen, flags);
- if (audio_fd != -1) {
- return audio_fd;
- }
-
- cycle = 0;
- while (devsettings[cycle][0] != '\0') {
- SDL_snprintf(audiopath, SDL_arraysize(audiopath),
- _PATH_DEV_DSP,
- devsettings[cycle][0],
- devsettings[cycle][1], devsettings[cycle][2]);
-
- if (stat(audiopath, &sb) == 0) {
- audio_fd = open(audiopath, flags, 0);
- if (audio_fd > 0) {
- if (path != NULL) {
- SDL_strlcpy(path, audiopath, maxlen);
- }
- return audio_fd;
- }
+ if (SDL_strlen(audiodev) < (sizeof(audiopath) - 3)) {
+ int instance = 0;
+ while (instance++ <= 64) {
+ SDL_snprintf(audiopath, SDL_arraysize(audiopath),
+ "%s%d", audiodev, instance);
+ test_device(audiopath, flags, test, devices, devCount);
}
}
- return -1;
}
#endif /* Audio driver selection */
--- a/src/audio/SDL_audiodev_c.h Sun Oct 01 16:10:41 2006 +0000
+++ b/src/audio/SDL_audiodev_c.h Tue Oct 17 09:15:21 2006 +0000
@@ -21,6 +21,8 @@
*/
#include "SDL_config.h"
-/* Open the audio device, storing the pathname in 'path' */
-extern int SDL_OpenAudioPath(char *path, int maxlen, int flags, int classic);
+void SDL_EnumUnixAudioDevices(int flags, int classic, int (*test)(int fd),
+ char ***devs, int *count);
+void SDL_FreeUnixAudioDevices(char ***devices, int *devCount);
+
/* vi: set ts=4 sw=4 expandtab: */
--- a/src/audio/SDL_mixer.c Sun Oct 01 16:10:41 2006 +0000
+++ b/src/audio/SDL_mixer.c Tue Oct 17 09:15:21 2006 +0000
@@ -89,21 +89,6 @@
#define ADJUST_VOLUME(s, v) (s = (s*v)/SDL_MIX_MAXVOLUME)
#define ADJUST_VOLUME_U8(s, v) (s = (((s-128)*v)/SDL_MIX_MAXVOLUME)+128)
-void
-SDL_MixAudio(Uint8 * dst, const Uint8 * src, Uint32 len, int volume)
-{
- /* Mix the user-level audio format */
- if (current_audio) {
- SDL_AudioFormat format;
- if (current_audio->convert.needed) {
- format = current_audio->convert.src_format;
- } else {
- format = current_audio->spec.format;
- }
- SDL_MixAudioFormat(dst, src, format, len, volume);
- }
-}
-
void
SDL_MixAudioFormat(Uint8 * dst, const Uint8 * src, SDL_AudioFormat format,
--- a/src/audio/SDL_sysaudio.h Sun Oct 01 16:10:41 2006 +0000
+++ b/src/audio/SDL_sysaudio.h Tue Oct 17 09:15:21 2006 +0000
@@ -29,13 +29,33 @@
/* The SDL audio driver */
typedef struct SDL_AudioDevice SDL_AudioDevice;
+#define _THIS SDL_AudioDevice *_this
-/* Define the SDL audio driver structure */
-#define _THIS SDL_AudioDevice *_this
-#ifndef _STATUS
-#define _STATUS SDL_status *status
-#endif
-struct SDL_AudioDevice
+typedef struct SDL_AudioDriverImpl
+{
+ int (*DetectDevices)(int iscapture);
+ const char *(*GetDeviceName)(int index, int iscapture);
+ int (*OpenDevice) (_THIS, const char *devname, int iscapture);
+ void (*ThreadInit) (_THIS); /* Called by audio thread at start */
+ void (*WaitDevice) (_THIS);
+ void (*PlayDevice) (_THIS);
+ Uint8 *(*GetDeviceBuf) (_THIS);
+ void (*WaitDone) (_THIS);
+ void (*CloseDevice) (_THIS);
+ void (*LockDevice) (_THIS);
+ void (*UnlockDevice) (_THIS);
+ void (*Deinitialize) (void);
+
+ /* Some flags to push duplicate code into the core and reduce #ifdefs. */
+ int ProvidesOwnCallbackThread:1;
+ int SkipMixerLock:1;
+ int HasCaptureSupport:1;
+ int OnlyHasDefaultOutputDevice:1;
+ int OnlyHasDefaultInputDevice:1;
+} SDL_AudioDriverImpl;
+
+
+typedef struct SDL_AudioDriver
{
/* * * */
/* The name of this audio driver */
@@ -45,21 +65,13 @@
/* The description of this audio driver */
const char *desc;
- /* * * */
- /* Public driver functions */
- int (*OpenAudio) (_THIS, SDL_AudioSpec * spec);
- void (*ThreadInit) (_THIS); /* Called by audio thread at start */
- void (*WaitAudio) (_THIS);
- void (*PlayAudio) (_THIS);
- Uint8 *(*GetAudioBuf) (_THIS);
- void (*WaitDone) (_THIS);
- void (*CloseAudio) (_THIS);
+ SDL_AudioDriverImpl impl;
+} SDL_AudioDriver;
+
- /* * * */
- /* Lock / Unlock functions added for the Mac port */
- void (*LockAudio) (_THIS);
- void (*UnlockAudio) (_THIS);
-
+/* Define the SDL audio driver structure */
+struct SDL_AudioDevice
+{
/* * * */
/* Data common to all devices */
@@ -70,6 +82,7 @@
SDL_AudioCVT convert;
/* Current state flags */
+ int iscapture;
int enabled;
int paused;
int opened;
@@ -87,10 +100,6 @@
/* * * */
/* Data private to this driver */
struct SDL_PrivateAudioData *hidden;
-
- /* * * */
- /* The function used to dispose of this structure */
- void (*free) (_THIS);
};
#undef _THIS
@@ -98,84 +107,10 @@
{
const char *name;
const char *desc;
- int (*available) (void);
- SDL_AudioDevice *(*create) (int devindex);
+ int (*init) (SDL_AudioDriverImpl *impl);
+ int demand_only:1; /* 1==request explicitly, or it won't be available. */
} AudioBootStrap;
-#if SDL_AUDIO_DRIVER_BSD
-extern AudioBootStrap BSD_AUDIO_bootstrap;
-#endif
-#if SDL_AUDIO_DRIVER_OSS
-extern AudioBootStrap DSP_bootstrap;
-extern AudioBootStrap DMA_bootstrap;
-#endif
-#if SDL_AUDIO_DRIVER_ALSA
-extern AudioBootStrap ALSA_bootstrap;
-#endif
-#if SDL_AUDIO_DRIVER_QNXNTO
-extern AudioBootStrap QNXNTOAUDIO_bootstrap;
-#endif
-#if SDL_AUDIO_DRIVER_SUNAUDIO
-extern AudioBootStrap SUNAUDIO_bootstrap;
-#endif
-#if SDL_AUDIO_DRIVER_DMEDIA
-extern AudioBootStrap DMEDIA_bootstrap;
-#endif
-#if SDL_AUDIO_DRIVER_ARTS
-extern AudioBootStrap ARTS_bootstrap;
-#endif
-#if SDL_AUDIO_DRIVER_ESD
-extern AudioBootStrap ESD_bootstrap;
-#endif
-#if SDL_AUDIO_DRIVER_NAS
-extern AudioBootStrap NAS_bootstrap;
-#endif
-#if SDL_AUDIO_DRIVER_DSOUND
-extern AudioBootStrap DSOUND_bootstrap;
-#endif
-#if SDL_AUDIO_DRIVER_WAVEOUT
-extern AudioBootStrap WAVEOUT_bootstrap;
-#endif
-#if SDL_AUDIO_DRIVER_PAUD
-extern AudioBootStrap Paud_bootstrap;
-#endif
-#if SDL_AUDIO_DRIVER_BAUDIO
-extern AudioBootStrap BAUDIO_bootstrap;
-#endif
-#if SDL_AUDIO_DRIVER_COREAUDIO
-extern AudioBootStrap COREAUDIO_bootstrap;
-#endif
-#if SDL_AUDIO_DRIVER_SNDMGR
-extern AudioBootStrap SNDMGR_bootstrap;
-#endif
-#if SDL_AUDIO_DRIVER_AHI
-extern AudioBootStrap AHI_bootstrap;
-#endif
-#if SDL_AUDIO_DRIVER_MINT
-extern AudioBootStrap MINTAUDIO_GSXB_bootstrap;
-extern AudioBootStrap MINTAUDIO_MCSN_bootstrap;
-extern AudioBootStrap MINTAUDIO_STFA_bootstrap;
-extern AudioBootStrap MINTAUDIO_XBIOS_bootstrap;
-extern AudioBootStrap MINTAUDIO_DMA8_bootstrap;
-#endif
-#if SDL_AUDIO_DRIVER_DISK
-extern AudioBootStrap DISKAUD_bootstrap;
-#endif
-#if SDL_AUDIO_DRIVER_DUMMY
-extern AudioBootStrap DUMMYAUD_bootstrap;
-#endif
-#if SDL_AUDIO_DRIVER_DC
-extern AudioBootStrap DCAUD_bootstrap;
-#endif
-#if SDL_AUDIO_DRIVER_MMEAUDIO
-extern AudioBootStrap MMEAUDIO_bootstrap;
-#endif
-#if SDL_AUDIO_DRIVER_DART
-extern AudioBootStrap DART_bootstrap;
-#endif
+#endif /* _SDL_sysaudio_h */
-/* This is the current audio device */
-extern SDL_AudioDevice *current_audio;
-
-#endif /* _SDL_sysaudio_h */
/* vi: set ts=4 sw=4 expandtab: */
--- a/src/audio/alsa/SDL_alsa_audio.c Sun Oct 01 16:10:41 2006 +0000
+++ b/src/audio/alsa/SDL_alsa_audio.c Tue Oct 17 09:15:21 2006 +0000
@@ -25,6 +25,9 @@
#include <sys/types.h>
#include <signal.h> /* For kill() */
+#include <dlfcn.h>
+#include <errno.h>
+#include <string.h>
#include "SDL_timer.h"
#include "SDL_audio.h"
@@ -32,14 +35,6 @@
#include "../SDL_audio_c.h"
#include "SDL_alsa_audio.h"
-#ifdef SDL_AUDIO_DRIVER_ALSA_DYNAMIC
-#include <dlfcn.h>
-#include "SDL_name.h"
-#include "SDL_loadso.h"
-#else
-#define SDL_NAME(X) X
-#endif
-
/* The tag name used by ALSA audio */
#define DRIVER_NAME "alsa"
@@ -47,182 +42,138 @@
/* The default ALSA audio driver */
#define DEFAULT_DEVICE "default"
-/* Audio driver functions */
-static int ALSA_OpenAudio(_THIS, SDL_AudioSpec * spec);
-static void ALSA_WaitAudio(_THIS);
-static void ALSA_PlayAudio(_THIS);
-static Uint8 *ALSA_GetAudioBuf(_THIS);
-static void ALSA_CloseAudio(_THIS);
+static int (*ALSA_snd_pcm_open)
+ (snd_pcm_t **, const char *, snd_pcm_stream_t, int);
+static int (*ALSA_snd_pcm_close)(snd_pcm_t * pcm);
+static snd_pcm_sframes_t(*ALSA_snd_pcm_writei)
+ (snd_pcm_t *,const void *, snd_pcm_uframes_t);
+static int (*ALSA_snd_pcm_resume)(snd_pcm_t *);
+static int (*ALSA_snd_pcm_prepare)(snd_pcm_t *);
+static int (*ALSA_snd_pcm_drain)(snd_pcm_t *);
+static const char *(*ALSA_snd_strerror)(int);
+static size_t(*ALSA_snd_pcm_hw_params_sizeof)(void);
+static size_t(*ALSA_snd_pcm_sw_params_sizeof)(void);
+static int (*ALSA_snd_pcm_hw_params_any)(snd_pcm_t *, snd_pcm_hw_params_t *);
+static int (*ALSA_snd_pcm_hw_params_set_access)
+ (snd_pcm_t *, snd_pcm_hw_params_t *, snd_pcm_access_t);
+static int (*ALSA_snd_pcm_hw_params_set_format)
+ (snd_pcm_t *, snd_pcm_hw_params_t *, snd_pcm_format_t);
+static int (*ALSA_snd_pcm_hw_params_set_channels)
+ (snd_pcm_t *, snd_pcm_hw_params_t *, unsigned int);
+static int (*ALSA_snd_pcm_hw_params_get_channels)(const snd_pcm_hw_params_t *);
+static unsigned int (*ALSA_snd_pcm_hw_params_set_rate_near)
+ (snd_pcm_t *, snd_pcm_hw_params_t *, unsigned int, int *);
+static snd_pcm_uframes_t (*ALSA_snd_pcm_hw_params_set_period_size_near)
+ (snd_pcm_t *, snd_pcm_hw_params_t *, snd_pcm_uframes_t, int *);
+static snd_pcm_sframes_t (*ALSA_snd_pcm_hw_params_get_period_size)
+ (const snd_pcm_hw_params_t *);
+static unsigned int (*ALSA_snd_pcm_hw_params_set_periods_near)
+ (snd_pcm_t *,snd_pcm_hw_params_t *, unsigned int, int *);
+static int (*ALSA_snd_pcm_hw_params_get_periods)(snd_pcm_hw_params_t *);
+static int (*ALSA_snd_pcm_hw_params)(snd_pcm_t *, snd_pcm_hw_params_t *);
+static int (*ALSA_snd_pcm_sw_params_current)(snd_pcm_t*, snd_pcm_sw_params_t*);
+static int (*ALSA_snd_pcm_sw_params_set_start_threshold)
+ (snd_pcm_t *, snd_pcm_sw_params_t *, snd_pcm_uframes_t);
+static int (*ALSA_snd_pcm_sw_params_set_avail_min)
+ (snd_pcm_t *, snd_pcm_sw_params_t *, snd_pcm_uframes_t);
+static int (*ALSA_snd_pcm_sw_params)(snd_pcm_t *, snd_pcm_sw_params_t *);
+static int (*ALSA_snd_pcm_nonblock)(snd_pcm_t *, int);
+#define snd_pcm_hw_params_sizeof ALSA_snd_pcm_hw_params_sizeof
+#define snd_pcm_sw_params_sizeof ALSA_snd_pcm_sw_params_sizeof
+
#ifdef SDL_AUDIO_DRIVER_ALSA_DYNAMIC
static const char *alsa_library = SDL_AUDIO_DRIVER_ALSA_DYNAMIC;
static void *alsa_handle = NULL;
-static int alsa_loaded = 0;
+
+static int
+load_alsa_sym(const char *fn, void **addr)
+{
+ /*
+ * !!! FIXME:
+ * Eventually, this will deal with fallbacks, version changes, and
+ * missing symbols we can workaround. But for now, it doesn't.
+ */
-static int (*SDL_snd_pcm_open) (snd_pcm_t ** pcm, const char *name,
- snd_pcm_stream_t stream, int mode);
-static int (*SDL_NAME(snd_pcm_open)) (snd_pcm_t ** pcm, const char *name,
- snd_pcm_stream_t stream, int mode);
-static int (*SDL_NAME(snd_pcm_close)) (snd_pcm_t * pcm);
-static snd_pcm_sframes_t(*SDL_NAME(snd_pcm_writei)) (snd_pcm_t * pcm,
- const void *buffer,
- snd_pcm_uframes_t size);
-static int (*SDL_NAME(snd_pcm_resume)) (snd_pcm_t * pcm);
-static int (*SDL_NAME(snd_pcm_prepare)) (snd_pcm_t * pcm);
-static int (*SDL_NAME(snd_pcm_drain)) (snd_pcm_t * pcm);
-static const char *(*SDL_NAME(snd_strerror)) (int errnum);
-static size_t(*SDL_NAME(snd_pcm_hw_params_sizeof)) (void);
-static size_t(*SDL_NAME(snd_pcm_sw_params_sizeof)) (void);
-static int (*SDL_NAME(snd_pcm_hw_params_any)) (snd_pcm_t * pcm,
- snd_pcm_hw_params_t * params);
-static int (*SDL_NAME(snd_pcm_hw_params_set_access)) (snd_pcm_t * pcm,
- snd_pcm_hw_params_t *
- params,
- snd_pcm_access_t
- access);
-static int (*SDL_NAME(snd_pcm_hw_params_set_format)) (snd_pcm_t * pcm,
- snd_pcm_hw_params_t *
- params,
- snd_pcm_format_t val);
-static int (*SDL_NAME(snd_pcm_hw_params_set_channels)) (snd_pcm_t * pcm,
- snd_pcm_hw_params_t *
- params,
- unsigned int val);
-static int (*SDL_NAME(snd_pcm_hw_params_get_channels)) (const
- snd_pcm_hw_params_t *
- params);
-static unsigned int
- (*SDL_NAME(snd_pcm_hw_params_set_rate_near)) (snd_pcm_t *
- pcm,
- snd_pcm_hw_params_t
- * params,
- unsigned int val, int *dir);
-static snd_pcm_uframes_t
- (*SDL_NAME(snd_pcm_hw_params_set_period_size_near)) (snd_pcm_t * pcm,
- snd_pcm_hw_params_t
- * params,
- snd_pcm_uframes_t
- val, int *dir);
-static snd_pcm_sframes_t
- (*SDL_NAME(snd_pcm_hw_params_get_period_size)) (const
- snd_pcm_hw_params_t
- * params);
-static unsigned int
- (*SDL_NAME(snd_pcm_hw_params_set_periods_near)) (snd_pcm_t * pcm,
- snd_pcm_hw_params_t
- * params,
- unsigned int val,
- int *dir);
-static int (*SDL_NAME(snd_pcm_hw_params_get_periods)) (snd_pcm_hw_params_t *
- params);
-static int (*SDL_NAME(snd_pcm_hw_params)) (snd_pcm_t * pcm,
- snd_pcm_hw_params_t * params);
-/*
-*/
-static int (*SDL_NAME(snd_pcm_sw_params_current)) (snd_pcm_t * pcm,
- snd_pcm_sw_params_t *
- swparams);
-static int (*SDL_NAME(snd_pcm_sw_params_set_start_threshold)) (snd_pcm_t *
- pcm,
- snd_pcm_sw_params_t
- * params,
- snd_pcm_uframes_t
- val);
-static int (*SDL_NAME(snd_pcm_sw_params_set_avail_min)) (snd_pcm_t * pcm,
- snd_pcm_sw_params_t
- * params,
- snd_pcm_uframes_t
- val);
-static int (*SDL_NAME(snd_pcm_sw_params)) (snd_pcm_t * pcm,
- snd_pcm_sw_params_t * params);
-static int (*SDL_NAME(snd_pcm_nonblock)) (snd_pcm_t * pcm, int nonblock);
-#define snd_pcm_hw_params_sizeof SDL_NAME(snd_pcm_hw_params_sizeof)
-#define snd_pcm_sw_params_sizeof SDL_NAME(snd_pcm_sw_params_sizeof)
+#if HAVE_DLVSYM
+ *addr = dlvsym(alsa_handle, fn, "ALSA_0.9");
+ if (*addr == NULL)
+#endif
+ {
+ *addr = dlsym(alsa_handle, fn);
+ if (*addr == NULL) {
+ SDL_SetError("dlsym('%s') failed: %s", fn, strerror(errno));
+ return 0;
+ }
+ }
+
+ return 1;
+}
/* cast funcs to char* first, to please GCC's strict aliasing rules. */
-static struct
+#define SDL_ALSA_SYM(x) \
+ if (!load_alsa_sym(#x, (void **) (char *) &ALSA_##x)) return -1
+#else
+#define SDL_ALSA_SYM(x) ALSA_##x = x
+#endif
+
+static int load_alsa_syms(void)
{
- const char *name;
- void **func;
-} alsa_functions[] = {
- {
- "snd_pcm_open", (void **) (char *) &SDL_NAME(snd_pcm_open)}, {
- "snd_pcm_close", (void **) (char *) &SDL_NAME(snd_pcm_close)}, {
- "snd_pcm_writei", (void **) (char *) &SDL_NAME(snd_pcm_writei)}, {
- "snd_pcm_resume", (void **) (char *) &SDL_NAME(snd_pcm_resume)}, {
- "snd_pcm_prepare", (void **) (char *) &SDL_NAME(snd_pcm_prepare)}, {
- "snd_pcm_drain", (void **) (char *) &SDL_NAME(snd_pcm_drain)}, {
- "snd_strerror", (void **) (char *) &SDL_NAME(snd_strerror)}, {
- "snd_pcm_hw_params_sizeof",
- (void **) (char *) &SDL_NAME(snd_pcm_hw_params_sizeof)}, {
- "snd_pcm_sw_params_sizeof",
- (void **) (char *) &SDL_NAME(snd_pcm_sw_params_sizeof)}, {
- "snd_pcm_hw_params_any",
- (void **) (char *) &SDL_NAME(snd_pcm_hw_params_any)}, {
- "snd_pcm_hw_params_set_access",
- (void **) (char *) &SDL_NAME(snd_pcm_hw_params_set_access)}, {
- "snd_pcm_hw_params_set_format",
- (void **) (char *) &SDL_NAME(snd_pcm_hw_params_set_format)}, {
- "snd_pcm_hw_params_set_channels",
- (void **) (char *) &SDL_NAME(snd_pcm_hw_params_set_channels)}, {
- "snd_pcm_hw_params_get_channels",
- (void **) (char *) &SDL_NAME(snd_pcm_hw_params_get_channels)}, {
- "snd_pcm_hw_params_set_rate_near",
- (void **) (char *) &SDL_NAME(snd_pcm_hw_params_set_rate_near)}, {
- "snd_pcm_hw_params_set_period_size_near", (void **) (char *)
- &SDL_NAME(snd_pcm_hw_params_set_period_size_near)}, {
- "snd_pcm_hw_params_get_period_size",
- (void **) (char *) &SDL_NAME(snd_pcm_hw_params_get_period_size)},
- {
- "snd_pcm_hw_params_set_periods_near", (void **) (char *)
- &SDL_NAME(snd_pcm_hw_params_set_periods_near)}, {
- "snd_pcm_hw_params_get_periods",
- (void **) (char *) &SDL_NAME(snd_pcm_hw_params_get_periods)}, {
- "snd_pcm_hw_params", (void **) (char *) &SDL_NAME(snd_pcm_hw_params)}, {
- "snd_pcm_sw_params_current",
- (void **) (char *) &SDL_NAME(snd_pcm_sw_params_current)}, {
- "snd_pcm_sw_params_set_start_threshold", (void **) (char *)
- &SDL_NAME(snd_pcm_sw_params_set_start_threshold)}, {
- "snd_pcm_sw_params_set_avail_min",
- (void **) (char *) &SDL_NAME(snd_pcm_sw_params_set_avail_min)}, {
- "snd_pcm_sw_params", (void **) (char *) &SDL_NAME(snd_pcm_sw_params)}, {
-"snd_pcm_nonblock", (void **) (char *) &SDL_NAME(snd_pcm_nonblock)},};
+ SDL_ALSA_SYM(snd_pcm_open);
+ SDL_ALSA_SYM(snd_pcm_close);
+ SDL_ALSA_SYM(snd_pcm_writei);
+ SDL_ALSA_SYM(snd_pcm_resume);
+ SDL_ALSA_SYM(snd_pcm_prepare);
+ SDL_ALSA_SYM(snd_pcm_drain);
+ SDL_ALSA_SYM(snd_strerror);
+ SDL_ALSA_SYM(snd_pcm_hw_params_sizeof);
+ SDL_ALSA_SYM(snd_pcm_sw_params_sizeof);
+ SDL_ALSA_SYM(snd_pcm_hw_params_any);
+ SDL_ALSA_SYM(snd_pcm_hw_params_set_access);
+ SDL_ALSA_SYM(snd_pcm_hw_params_set_format);
+ SDL_ALSA_SYM(snd_pcm_hw_params_set_channels);
+ SDL_ALSA_SYM(snd_pcm_hw_params_get_channels);
+ SDL_ALSA_SYM(snd_pcm_hw_params_set_rate_near);
+ SDL_ALSA_SYM(snd_pcm_hw_params_set_period_size_near);
+ SDL_ALSA_SYM(snd_pcm_hw_params_get_period_size);
+ SDL_ALSA_SYM(snd_pcm_hw_params_set_periods_near);
+ SDL_ALSA_SYM(snd_pcm_hw_params_get_periods);
+ SDL_ALSA_SYM(snd_pcm_hw_params);
+ SDL_ALSA_SYM(snd_pcm_sw_params_current);
+ SDL_ALSA_SYM(snd_pcm_sw_params_set_start_threshold);
+ SDL_ALSA_SYM(snd_pcm_sw_params_set_avail_min);
+ SDL_ALSA_SYM(snd_pcm_sw_params);
+ SDL_ALSA_SYM(snd_pcm_nonblock);
+ return 0;
+}
+#undef SDL_ALSA_SYM
+
+#ifdef SDL_AUDIO_DRIVER_ALSA_DYNAMIC
static void
UnloadALSALibrary(void)
{
- if (alsa_loaded) {
-/* SDL_UnloadObject(alsa_handle);*/
+ if (alsa_handle != NULL) {
dlclose(alsa_handle);
alsa_handle = NULL;
- alsa_loaded = 0;
}
}
static int
LoadALSALibrary(void)
{
- int i, retval = -1;
-
-/* alsa_handle = SDL_LoadObject(alsa_library);*/
- alsa_handle = dlopen(alsa_library, RTLD_NOW);
- if (alsa_handle) {
- alsa_loaded = 1;
- retval = 0;
- for (i = 0; i < SDL_arraysize(alsa_functions); i++) {
-/* *alsa_functions[i].func = SDL_LoadFunction(alsa_handle,alsa_functions[i].name);*/
-#if HAVE_DLVSYM
- *alsa_functions[i].func =
- dlvsym(alsa_handle, alsa_functions[i].name, "ALSA_0.9");
- if (!*alsa_functions[i].func)
-#endif
- *alsa_functions[i].func =
- dlsym(alsa_handle, alsa_functions[i].name);
- if (!*alsa_functions[i].func) {
- retval = -1;
+ int retval = 0;
+ if (alsa_handle == NULL) {
+ alsa_handle = dlopen(alsa_library, RTLD_NOW);
+ if (alsa_handle == NULL) {
+ retval = -1;
+ SDL_SetError("ALSA: dlopen('%s') failed: %s\n",
+ alsa_library, strerror(errno));
+ } else {
+ retval = load_alsa_syms();
+ if (retval < 0) {
UnloadALSALibrary();
- break;
}
}
}
@@ -234,12 +185,12 @@
static void
UnloadALSALibrary(void)
{
- return;
}
static int
LoadALSALibrary(void)
{
+ load_alsa_syms();
return 0;
}
@@ -262,80 +213,10 @@
return device;
}
-/* Audio driver bootstrap functions */
-
-static int
-Audio_Available(void)
-{
- int available;
- int status;
- snd_pcm_t *handle;
-
- available = 0;
- if (LoadALSALibrary() < 0) {
- return available;
- }
- status =
- SDL_NAME(snd_pcm_open) (&handle, get_audio_device(2),
- SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK);
- if (status >= 0) {
- available = 1;
- SDL_NAME(snd_pcm_close) (handle);
- }
- UnloadALSALibrary();
- return (available);
-}
-
-static void
-Audio_DeleteDevice(SDL_AudioDevice * device)
-{
- SDL_free(device->hidden);
- SDL_free(device);
- UnloadALSALibrary();
-}
-
-static SDL_AudioDevice *
-Audio_CreateDevice(int devindex)
-{
- SDL_AudioDevice *this;
-
- /* Initialize all variables that we clean on shutdown */
- LoadALSALibrary();
- 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));
-
- /* Set the function pointers */
- this->OpenAudio = ALSA_OpenAudio;
- this->WaitAudio = ALSA_WaitAudio;
- this->PlayAudio = ALSA_PlayAudio;
- this->GetAudioBuf = ALSA_GetAudioBuf;
- this->CloseAudio = ALSA_CloseAudio;
-
- this->free = Audio_DeleteDevice;
-
- return this;
-}
-
-AudioBootStrap ALSA_bootstrap = {
- DRIVER_NAME, "ALSA 0.9 PCM audio",
- Audio_Available, Audio_CreateDevice
-};
/* This function waits until it is possible to write a full sound buffer */
static void
-ALSA_WaitAudio(_THIS)
+ALSA_WaitDevice(_THIS)
{
/* Check to see if the thread-parent process is still alive */
{
@@ -343,8 +224,9 @@
/* Note that this only works with thread implementations
that use a different process id for each thread.
*/
- if (parent && (((++cnt) % 10) == 0)) { /* Check every 10 loops */
- if (kill(parent, 0) < 0) {
+ /* Check every 10 loops */
+ if (this->hidden->parent && (((++cnt) % 10) == 0)) {
+ if (kill(this->hidden->parent, 0) < 0) {
this->enabled = 0;
}
}
@@ -352,13 +234,14 @@
}
+/* !!! FIXME: is there a channel swizzler in alsalib instead? */
/*
* http://bugzilla.libsdl.org/show_bug.cgi?id=110
* "For Linux ALSA, this is FL-FR-RL-RR-C-LFE
* and for Windows DirectX [and CoreAudio], this is FL-FR-C-LFE-RL-RR"
*/
#define SWIZ6(T) \
- T *ptr = (T *) mixbuf; \
+ T *ptr = (T *) this->hidden->mixbuf; \
const Uint32 count = (this->spec.samples / 6); \
Uint32 i; \
for (i = 0; i < count; i++, ptr += 6) { \
@@ -392,8 +275,8 @@
/*
- * Called right before feeding this->mixbuf to the hardware. Swizzle channels
- * from Windows/Mac order to the format alsalib will want.
+ * Called right before feeding this->hidden->mixbuf to the hardware. Swizzle
+ * channels from Windows/Mac order to the format alsalib will want.
*/
static __inline__ void
swizzle_alsa_channels(_THIS)
@@ -415,7 +298,7 @@
static void
-ALSA_PlayAudio(_THIS)
+ALSA_PlayDevice(_THIS)
{
int status;
int sample_len;
@@ -424,11 +307,12 @@
swizzle_alsa_channels(this);
sample_len = this->spec.samples;
- sample_buf = (signed short *) mixbuf;
+ sample_buf = (signed short *) this->hidden->mixbuf;
while (sample_len > 0) {
- status =
- SDL_NAME(snd_pcm_writei) (pcm_handle, sample_buf, sample_len);
+ status = ALSA_snd_pcm_writei(this->hidden->pcm_handle,
+ sample_buf, sample_len);
+
if (status < 0) {
if (status == -EAGAIN) {
SDL_Delay(1);
@@ -437,11 +321,11 @@
if (status == -ESTRPIPE) {
do {
SDL_Delay(1);
- status = SDL_NAME(snd_pcm_resume) (pcm_handle);
+ status = ALSA_snd_pcm_resume(this->hidden->pcm_handle);
} while (status == -EAGAIN);
}
if (status < 0) {
- status = SDL_NAME(snd_pcm_prepare) (pcm_handle);
+ status = ALSA_snd_pcm_prepare(this->hidden->pcm_handle);
}
if (status < 0) {
/* Hmm, not much we can do - abort */
@@ -456,74 +340,89 @@
}
static Uint8 *
-ALSA_GetAudioBuf(_THIS)
+ALSA_GetDeviceBuf(_THIS)
{
- return (mixbuf);
+ return (this->hidden->mixbuf);
}
static void
-ALSA_CloseAudio(_THIS)
+ALSA_CloseDevice(_THIS)
{
- if (mixbuf != NULL) {
- SDL_FreeAudioMem(mixbuf);
- mixbuf = NULL;
- }
- if (pcm_handle) {
- SDL_NAME(snd_pcm_drain) (pcm_handle);
- SDL_NAME(snd_pcm_close) (pcm_handle);
- pcm_handle = NULL;
+ if (this->hidden != NULL) {
+ if (this->hidden->mixbuf != NULL) {
+ SDL_FreeAudioMem(this->hidden->mixbuf);
+ this->hidden->mixbuf = NULL;
+ }
+ if (this->hidden->pcm_handle) {
+ ALSA_snd_pcm_drain(this->hidden->pcm_handle);
+ ALSA_snd_pcm_close(this->hidden->pcm_handle);
+ this->hidden->pcm_handle = NULL;
+ }
+ SDL_free(this->hidden);
+ this->hidden = NULL;
}
}
static int
-ALSA_OpenAudio(_THIS, SDL_AudioSpec * spec)
+ALSA_OpenDevice(_THIS, const char *devname, int iscapture)
{
- int status;
- snd_pcm_hw_params_t *hwparams;
- snd_pcm_sw_params_t *swparams;
- snd_pcm_format_t format;
- snd_pcm_uframes_t frames;
- SDL_AudioFormat test_format;
+ int status = 0;
+ snd_pcm_t *pcm_handle = NULL;
+ snd_pcm_hw_params_t *hwparams = NULL;
+ snd_pcm_sw_params_t *swparams = NULL;
+ snd_pcm_format_t format = 0;
+ snd_pcm_uframes_t frames = 0;
+ SDL_AudioFormat test_format = 0;
+
+ /* Initialize all variables that we clean on shutdown */
+ this->hidden = (struct SDL_PrivateAudioData *)
+ SDL_malloc((sizeof *this->hidden));
+ if (this->hidden == NULL) {
+ SDL_OutOfMemory();
+ return 0;
+ }
+ SDL_memset(this->hidden, 0, (sizeof *this->hidden));
/* Open the audio device */
/* Name of device should depend on # channels in spec */
- status =
- SDL_NAME(snd_pcm_open) (&pcm_handle,
- get_audio_device(spec->channels),
- SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK);
+ status = ALSA_snd_pcm_open(&pcm_handle,
+ get_audio_device(this->spec.channels),
+ SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK);
if (status < 0) {
- SDL_SetError("Couldn't open audio device: %s",
- SDL_NAME(snd_strerror) (status));
- return (-1);
+ ALSA_CloseDevice(this);
+ SDL_SetError("ALSA: Couldn't open audio device: %s",
+ ALSA_snd_strerror(status));
+ return 0;
}
+ this->hidden->pcm_handle = pcm_handle;
+
/* Figure out what the hardware is capable of */
snd_pcm_hw_params_alloca(&hwparams);
- status = SDL_NAME(snd_pcm_hw_params_any) (pcm_handle, hwparams);
+ status = ALSA_snd_pcm_hw_params_any(pcm_handle, hwparams);
if (status < 0) {
- SDL_SetError("Couldn't get hardware config: %s",
- SDL_NAME(snd_strerror) (status));
- ALSA_CloseAudio(this);
- return (-1);
+ ALSA_CloseDevice(this);
+ SDL_SetError("ALSA: Couldn't get hardware config: %s",
+ ALSA_snd_strerror(status));
+ return 0;
}
/* SDL only uses interleaved sample output */
- status =
- SDL_NAME(snd_pcm_hw_params_set_access) (pcm_handle, hwparams,
- SND_PCM_ACCESS_RW_INTERLEAVED);
+ status = ALSA_snd_pcm_hw_params_set_access(pcm_handle, hwparams,
+ SND_PCM_ACCESS_RW_INTERLEAVED);
if (status < 0) {
- SDL_SetError("Couldn't set interleaved access: %s",
- SDL_NAME(snd_strerror) (status));
- ALSA_CloseAudio(this);
- return (-1);
+ ALSA_CloseDevice(this);
+ SDL_SetError("ALSA: Couldn't set interleaved access: %s",
+ ALSA_snd_strerror(status));
+ return 0;
}
/* Try for a closest match on audio format */
status = -1;
- for (test_format = SDL_FirstAudioFormat(spec->format);
+ for (test_format = SDL_FirstAudioFormat(this->spec.format);
test_format && (status < 0);) {
- status = 0; /* if we can't support a format, it'll become -1. */
+ status = 0; /* if we can't support a format, it'll become -1. */
switch (test_format) {
case AUDIO_U8:
format = SND_PCM_FORMAT_U8;
@@ -560,131 +459,151 @@
break;
}
if (status >= 0) {
- status =
- SDL_NAME(snd_pcm_hw_params_set_format) (pcm_handle,
- hwparams, format);
+ status = ALSA_snd_pcm_hw_params_set_format(pcm_handle,
+ hwparams, format);
}
if (status < 0) {
test_format = SDL_NextAudioFormat();
}
}
if (status < 0) {
- SDL_SetError("Couldn't find any hardware audio formats");
- ALSA_CloseAudio(this);
- return (-1);
+ ALSA_CloseDevice(this);
+ SDL_SetError("ALSA: Couldn't find any hardware audio formats");
+ return 0;
}
- spec->format = test_format;
+ this->spec.format = test_format;
/* Set the number of channels */
- status =
- SDL_NAME(snd_pcm_hw_params_set_channels) (pcm_handle, hwparams,
- spec->channels);
+ status = ALSA_snd_pcm_hw_params_set_channels(pcm_handle, hwparams,
+ this->spec.channels);
if (status < 0) {
- status = SDL_NAME(snd_pcm_hw_params_get_channels) (hwparams);
+ status = ALSA_snd_pcm_hw_params_get_channels(hwparams);
if ((status <= 0) || (status > 2)) {
- SDL_SetError("Couldn't set audio channels");
- ALSA_CloseAudio(this);
- return (-1);
+ ALSA_CloseDevice(this);
+ SDL_SetError("ALSA: Couldn't set audio channels");
+ return 0;
}
- spec->channels = status;
+ this->spec.channels = status;
}
/* Set the audio rate */
- status =
- SDL_NAME(snd_pcm_hw_params_set_rate_near) (pcm_handle, hwparams,
- spec->freq, NULL);
+ status = ALSA_snd_pcm_hw_params_set_rate_near(pcm_handle, hwparams,
+ this->spec.freq, NULL);
if (status < 0) {
- SDL_SetError("Couldn't set audio frequency: %s",
- SDL_NAME(snd_strerror) (status));
- ALSA_CloseAudio(this);
- return (-1);
+ ALSA_CloseDevice(this);
+ SDL_SetError("ALSA: Couldn't set audio frequency: %s",
+ ALSA_snd_strerror(status));
+ return 0;
}
- spec->freq = status;
+ this->spec.freq = status;
/* Set the buffer size, in samples */
- frames = spec->samples;
- frames =
- SDL_NAME(snd_pcm_hw_params_set_period_size_near) (pcm_handle,
- hwparams, frames,
- NULL);
- spec->samples = frames;
- SDL_NAME(snd_pcm_hw_params_set_periods_near) (pcm_handle, hwparams, 2,
- NULL);
+ frames = this->spec.samples;
+ frames = ALSA_snd_pcm_hw_params_set_period_size_near(pcm_handle, hwparams,
+ frames, NULL);
+ this->spec.samples = frames;
+ ALSA_snd_pcm_hw_params_set_periods_near(pcm_handle, hwparams, 2, NULL);
/* "set" the hardware with the desired parameters */
- status = SDL_NAME(snd_pcm_hw_params) (pcm_handle, hwparams);
+ status = ALSA_snd_pcm_hw_params(pcm_handle, hwparams);
if (status < 0) {
- SDL_SetError("Couldn't set hardware audio parameters: %s",
- SDL_NAME(snd_strerror) (status));
- ALSA_CloseAudio(this);
- return (-1);
+ ALSA_CloseDevice(this);
+ SDL_SetError("ALSA: Couldn't set hardware audio parameters: %s",
+ ALSA_snd_strerror(status));
+ return 0;
}
-/* This is useful for debugging... */
-/*
-{ snd_pcm_sframes_t bufsize; int fragments;
- bufsize = SDL_NAME(snd_pcm_hw_params_get_period_size)(hwparams);
- fragments = SDL_NAME(snd_pcm_hw_params_get_periods)(hwparams);
-
- fprintf(stderr, "ALSA: bufsize = %ld, fragments = %d\n", bufsize, fragments);
+#if AUDIO_DEBUG
+{
+ snd_pcm_sframes_t bufsize;
+ int fragments;
+ bufsize = ALSA_snd_pcm_hw_params_get_period_size(hwparams);
+ fragments = ALSA_snd_pcm_hw_params_get_periods(hwparams);
+ fprintf(stderr,"ALSA: bufsize = %ld, fragments = %d\n",bufsize,fragments);
}
-*/
+#endif
/* Set the software parameters */
snd_pcm_sw_params_alloca(&swparams);
- status = SDL_NAME(snd_pcm_sw_params_current) (pcm_handle, swparams);
+ status = ALSA_snd_pcm_sw_params_current(pcm_handle, swparams);
if (status < 0) {
- SDL_SetError("Couldn't get software config: %s",
- SDL_NAME(snd_strerror) (status));
- ALSA_CloseAudio(this);
- return (-1);
- }
- status =
- SDL_NAME(snd_pcm_sw_params_set_start_threshold) (pcm_handle,
- swparams, 0);
- if (status < 0) {
- SDL_SetError("Couldn't set start threshold: %s",
- SDL_NAME(snd_strerror) (status));
- ALSA_CloseAudio(this);
- return (-1);
+ ALSA_CloseDevice(this);
+ SDL_SetError("ALSA: Couldn't get software config: %s",
+ ALSA_snd_strerror(status));
+ return 0;
}
- status =
- SDL_NAME(snd_pcm_sw_params_set_avail_min) (pcm_handle, swparams,
- frames);
+ status = ALSA_snd_pcm_sw_params_set_start_threshold(pcm_handle,swparams,0);
+ if (status < 0) {
+ ALSA_CloseDevice(this);
+ SDL_SetError("ALSA: Couldn't set start threshold: %s",
+ ALSA_snd_strerror(status));
+ return 0;
+ }
+ status = ALSA_snd_pcm_sw_params_set_avail_min(pcm_handle, swparams, frames);
if (status < 0) {
- SDL_SetError("Couldn't set avail min: %s",
- SDL_NAME(snd_strerror) (status));
- ALSA_CloseAudio(this);
- return (-1);
+ ALSA_CloseDevice(this);
+ SDL_SetError("Couldn't set avail min: %s", ALSA_snd_strerror(status));
+ return 0;
}
- status = SDL_NAME(snd_pcm_sw_params) (pcm_handle, swparams);
+ status = ALSA_snd_pcm_sw_params(pcm_handle, swparams);
if (status < 0) {
+ ALSA_CloseDevice(this);
SDL_SetError("Couldn't set software audio parameters: %s",
- SDL_NAME(snd_strerror) (status));
- ALSA_CloseAudio(this);
- return (-1);
+ ALSA_snd_strerror(status));
+ return 0;
}
/* Calculate the final parameters for this audio specification */
- SDL_CalculateAudioSpec(spec);
+ SDL_CalculateAudioSpec(&this->spec);
/* Allocate mixing buffer */
- mixlen = spec->size;
- mixbuf = (Uint8 *) SDL_AllocAudioMem(mixlen);
- if (mixbuf == NULL) {
- ALSA_CloseAudio(this);
- return (-1);
+ this->hidden->mixlen = this->spec.size;
+ this->hidden->mixbuf = (Uint8 *) SDL_AllocAudioMem(this->hidden->mixlen);
+ if (this->hidden->mixbuf == NULL) {
+ ALSA_CloseDevice(this);
+ SDL_OutOfMemory();
+ return 0;
}
- SDL_memset(mixbuf, spec->silence, spec->size);
+ SDL_memset(this->hidden->mixbuf, this->spec.silence, this->spec.size);
/* Get the parent process id (we're the parent of the audio thread) */
- parent = getpid();
+ this->hidden->parent = getpid();
/* Switch to blocking mode for playback */
- SDL_NAME(snd_pcm_nonblock) (pcm_handle, 0);
+ ALSA_snd_pcm_nonblock(pcm_handle, 0);
/* We're ready to rock and roll. :-) */
- return (0);
+ return 1;
+}
+
+static void
+ALSA_Deinitialize(void)
+{
+ UnloadALSALibrary();
}
+static int
+ALSA_Init(SDL_AudioDriverImpl *impl)
+{
+ if (LoadALSALibrary() < 0) {
+ return 0;
+ }
+
+ /* Set the function pointers */
+ impl->OpenDevice = ALSA_OpenDevice;
+ impl->WaitDevice = ALSA_WaitDevice;
+ impl->GetDeviceBuf = ALSA_GetDeviceBuf;
+ impl->PlayDevice = ALSA_PlayDevice;
+ impl->CloseDevice = ALSA_CloseDevice;
+ impl->Deinitialize = ALSA_Deinitialize;
+ impl->OnlyHasDefaultOutputDevice = 1; /* !!! FIXME: Add device enum! */
+
+ return 1;
+}
+
+
+AudioBootStrap ALSA_bootstrap = {
+ DRIVER_NAME, "ALSA 0.9 PCM audio", ALSA_Init, 0
+};
+
/* vi: set ts=4 sw=4 expandtab: */
--- a/src/audio/alsa/SDL_alsa_audio.h Sun Oct 01 16:10:41 2006 +0000
+++ b/src/audio/alsa/SDL_alsa_audio.h Tue Oct 17 09:15:21 2006 +0000
@@ -30,7 +30,7 @@
#include "../SDL_sysaudio.h"
-/* Hidden "this" pointer for the video functions */
+/* Hidden "this" pointer for the audio functions */
#define _THIS SDL_AudioDevice *this
struct SDL_PrivateAudioData
@@ -46,11 +46,5 @@
int mixlen;
};
-/* Old variable names */
-#define pcm_handle (this->hidden->pcm_handle)
-#define parent (this->hidden->parent)
-#define mixbuf (this->hidden->mixbuf)
-#define mixlen (this->hidden->mixlen)
-
#endif /* _ALSA_PCM_audio_h */
/* vi: set ts=4 sw=4 expandtab: */
--- a/src/audio/amigaos/SDL_ahiaudio.c Sun Oct 01 16:10:41 2006 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,360 +0,0 @@
-/*
- SDL - Simple DirectMedia Layer
- Copyright (C) 1997-2006 Sam Lantinga
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 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
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with this library; if not, write to the Free Software
- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-
- Sam Lantinga
- slouken@libsdl.org
-*/
-#include "SDL_config.h"
-
-/* Allow access to a raw mixing buffer (for AmigaOS) */
-
-#include "SDL_audio.h"
-#include "../SDL_audio_c.h"
-#include "SDL_ahiaudio.h"
-
-/* Audio driver functions */
-static int AHI_OpenAudio(_THIS, SDL_AudioSpec * spec);
-static void AHI_WaitAudio(_THIS);
-static void AHI_PlayAudio(_THIS);
-static Uint8 *AHI_GetAudioBuf(_THIS);
-static void AHI_CloseAudio(_THIS);
-
-#ifndef __SASC
-#define mymalloc(x) AllocVec(x,MEMF_PUBLIC)
-#define myfree FreeVec
-#else
-#define mymalloc malloc
-#define myfree free
-#endif
-
-/* Audio driver bootstrap functions */
-
-static int
-Audio_Available(void)
-{
- int ok = 0;
- struct MsgPort *p;
- struct AHIRequest *req;
-
- if (p = CreateMsgPort()) {
- if (req =
- (struct AHIRequest *) CreateIORequest(p,
- sizeof(struct
- AHIRequest))) {
- req->ahir_Version = 4;
-
- if (!OpenDevice(AHINAME, 0, (struct IORequest *) req, NULL)) {
- D(bug("AHI available.\n"));
- ok = 1;
- CloseDevice((struct IORequest *) req);
- }
- DeleteIORequest((struct IORequest *) req);
- }
- DeleteMsgPort(p);
- }
-
- D(if (!ok) bug("AHI not available\n"));
- return ok;
-}
-
-static void
-Audio_DeleteDevice(SDL_AudioDevice * device)
-{
- SDL_free(device->hidden);
- SDL_free(device);
-}
-
-static SDL_AudioDevice *
-Audio_CreateDevice(int devindex)
-{
- SDL_AudioDevice *this;
-
-#ifndef NO_AMIGADEBUG
- D(bug("AHI created...\n"));
-#endif
-
- /* 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));
-
- /* Set the function pointers */
- this->OpenAudio = AHI_OpenAudio;
- this->WaitAudio = AHI_WaitAudio;
- this->PlayAudio = AHI_PlayAudio;
- this->GetAudioBuf = AHI_GetAudioBuf;
- this->CloseAudio = AHI_CloseAudio;
-
- this->free = Audio_DeleteDevice;
-
- return this;
-}
-
-AudioBootStrap AHI_bootstrap = {
- "AHI", Audio_Available, Audio_CreateDevice
-};
-
-
-void static
-AHI_WaitAudio(_THIS)
-{
- if (!CheckIO((struct IORequest *) audio_req[current_buffer])) {
- WaitIO((struct IORequest *) audio_req[current_buffer]);
-// AbortIO((struct IORequest *)audio_req[current_buffer]);
- }
-}
-
-static void
-AHI_PlayAudio(_THIS)
-{
- if (playing > 1)
- WaitIO((struct IORequest *) audio_req[current_buffer]);
-
- /* Write the audio data out */
- audio_req[current_buffer]->ahir_Std.io_Message.mn_Node.ln_Pri = 60;
- audio_req[current_buffer]->ahir_Std.io_Data = mixbuf[current_buffer];
- audio_req[current_buffer]->ahir_Std.io_Length = this->hidden->size;
- audio_req[current_buffer]->ahir_Std.io_Offset = 0;
- audio_req[current_buffer]->ahir_Std.io_Command = CMD_WRITE;
- audio_req[current_buffer]->ahir_Frequency = this->hidden->freq;
- audio_req[current_buffer]->ahir_Volume = 0x10000;
- audio_req[current_buffer]->ahir_Type = this->hidden->type;
- audio_req[current_buffer]->ahir_Position = 0x8000;
- audio_req[current_buffer]->ahir_Link =
- (playing > 0 ? audio_req[current_buffer ^ 1] : NULL);
-
- SendIO((struct IORequest *) audio_req[current_buffer]);
- current_buffer ^= 1;
-
- playing++;
-}
-
-static Uint8 *
-AHI_GetAudioBuf(_THIS)
-{
- return (mixbuf[current_buffer]);
-}
-
-static void
-AHI_CloseAudio(_THIS)
-{
- D(bug("Closing audio...\n"));
-
- playing = 0;
-
- if (audio_req[0]) {
- if (audio_req[1]) {
- D(bug("Break req[1]...\n"));
-
- AbortIO((struct IORequest *) audio_req[1]);
- WaitIO((struct IORequest *) audio_req[1]);
- }
-
- D(bug("Break req[0]...\n"));
-
- AbortIO((struct IORequest *) audio_req[0]);
- WaitIO((struct IORequest *) audio_req[0]);
-
- if (audio_req[1]) {
- D(bug("Break AGAIN req[1]...\n"));
- AbortIO((struct IORequest *) audio_req[1]);
- WaitIO((struct IORequest *) audio_req[1]);
- }
-// Double abort to be sure to break the dbuffering process.
-
- SDL_Delay(200);
-
- D(bug("Reqs breaked, closing device...\n"));
- CloseDevice((struct IORequest *) audio_req[0]);
- D(bug("Device closed, freeing memory...\n"));
- myfree(audio_req[1]);
- D(bug("Memory freed, deleting IOReq...\n"));
- DeleteIORequest((struct IORequest *) audio_req[0]);
- audio_req[0] = audio_req[1] = NULL;
- }
-
- D(bug("Freeing mixbuf[0]...\n"));
- if (mixbuf[0] != NULL) {
- myfree(mixbuf[0]);
-// SDL_FreeAudioMem(mixbuf[0]);
- mixbuf[0] = NULL;
- }
-
- D(bug("Freeing mixbuf[1]...\n"));
- if (mixbuf[1] != NULL) {
- myfree(mixbuf[1]);
-// SDL_FreeAudioMem(mixbuf[1]);
- mixbuf[1] = NULL;
- }
-
- D(bug("Freeing audio_port...\n"));
-
- if (audio_port != NULL) {
- DeleteMsgPort(audio_port);
- audio_port = NULL;
- }
- D(bug("...done!\n"));
-}
-
-static int
-AHI_OpenAudio(_THIS, SDL_AudioSpec * spec)
-{
-// int width;
- SDL_AudioFormat test_format = SDL_FirstAudioFormat(spec->format);
- int valid_datatype = 1;
-
- D(bug("AHI opening...\n"));
-
- /* Determine the audio parameters from the AudioSpec */
- while ((!valid_datatype) && (test_format)) {
- valid_datatype = 1;
- switch (test_format) {
- case AUDIO_S8:
- D(bug("AUDIO_S8...\n"));
- spec->format = AUDIO_S8;
- this->hidden->bytespersample = 1;
- if (spec->channels < 2)
- this->hidden->type = AHIST_M8S;
- else
- this->hidden->type = AHIST_S8S;
- break;
-
- case AUDIO_S16MSB:
- D(bug("AUDIO_S16MSB...\n"));
- spec->format = AUDIO_S16MSB;
- this->hidden->bytespersample = 2;
- if (spec->channels < 2)
- this->hidden->type = AHIST_M16S;
- else
- this->hidden->type = AHIST_S16S;
- break;
-
- case AUDIO_S32MSB:
- D(bug("AUDIO_S32MSB...\n"));
- spec->format = AUDIO_S32MSB;
- this->hidden->bytespersample = 4;
- if (spec->channels < 2)
- this->hidden->type = AHIST_M32S;
- else
- this->hidden->type = AHIST_S32S;
- break;
-
- default:
- valid_datatype = 0;
- test_format = SDL_NextAudioFormat();
- break;
- }
- }
-
- if (!valid_datatype) { /* shouldn't happen, but just in case... */
- SDL_SetError("Unsupported audio format");
- return (-1);
- }
-
- if (spec->channels > 2) {
- spec->channels = 2; /* will convert at higher level. */
- }
-
- D(bug("Before CalculateAudioSpec\n"));
- /* Update the fragment size as size in bytes */
- SDL_CalculateAudioSpec(spec);
-
- D(bug("Before CreateMsgPort\n"));
-
- if (!(audio_port = CreateMsgPort())) {
- SDL_SetError("Unable to create a MsgPort");
- return -1;
- }
-
- D(bug("Before CreateIORequest\n"));
-
- if (!
- (audio_req[0] =
- (struct AHIRequest *) CreateIORequest(audio_port,
- sizeof(struct AHIRequest)))) {
- SDL_SetError("Unable to create an AHIRequest");
- DeleteMsgPort(audio_port);
- return -1;
- }
-
- audio_req[0]->ahir_Version = 4;
-
- if (OpenDevice(AHINAME, 0, (struct IORequest *) audio_req[0], NULL)) {
- SDL_SetError("Unable to open AHI device!\n");
- DeleteIORequest((struct IORequest *) audio_req[0]);
- DeleteMsgPort(audio_port);
- return -1;
- }
-
- D(bug("AFTER opendevice\n"));
-
- /* Set output frequency and size */
- this->hidden->freq = spec->freq;
- this->hidden->size = spec->size;
-
- D(bug("Before buffer allocation\n"));
-
- /* Allocate mixing buffer */
- mixbuf[0] = (Uint8 *) mymalloc(spec->size);
- mixbuf[1] = (Uint8 *) mymalloc(spec->size);
-
- D(bug("Before audio_req allocation\n"));
-
- if (!(audio_req[1] = mymalloc(sizeof(struct AHIRequest)))) {
- SDL_OutOfMemory();
- return (-1);
- }
-
- D(bug("Before audio_req memcpy\n"));
-
- SDL_memcpy(audio_req[1], audio_req[0], sizeof(struct AHIRequest));
-
- if (mixbuf[0] == NULL || mixbuf[1] == NULL) {
- SDL_OutOfMemory();
- return (-1);
- }
-
- D(bug("Before mixbuf memset\n"));
-
- SDL_memset(mixbuf[0], spec->silence, spec->size);
- SDL_memset(mixbuf[1], spec->silence, spec->size);
-
- current_buffer = 0;
- playing = 0;
-
- D(bug
- ("AHI opened: freq:%ld mixbuf:%lx/%lx buflen:%ld bits:%ld channels:%ld\n",
- spec->freq, mixbuf[0], mixbuf[1], spec->size,
- this->hidden->bytespersample * 8, spec->channels));
-
- /* We're ready to rock and roll. :-) */
- return (0);
-}
-
-/* vi: set ts=4 sw=4 expandtab: */
--- a/src/audio/amigaos/SDL_ahiaudio.h Sun Oct 01 16:10:41 2006 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,62 +0,0 @@
-/*
- SDL - Simple DirectMedia Layer
- Copyright (C) 1997-2006 Sam Lantinga
-
- This library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 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
- Lesser General Public License for more details.
-
- You should have received a copy of the GNU Lesser General Public
- License along with this library; if not, write to the Free Software
- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-
- Sam Lantinga
- slouken@libsdl.org
-*/
-#include "SDL_config.h"
-
-#ifndef _SDL_ahiaudio_h
-#define _SDL_ahiaudio_h
-
-#include <exec/exec.h>
-#include <dos/dos.h>
-#ifdef __SASC
-#include <proto/exec.h>
-#else
-#include <inline/exec.h>
-#endif
-
-#include <devices/ahi.h>
-#include "mydebug.h"
-
-#include "../SDL_sysaudio.h"
-
-/* Hidden "this" pointer for the audio functions */
-#define _THIS SDL_AudioDevice *this
-
-struct SDL_PrivateAudioData
-{
- /* The handle for the audio device */
- struct AHIRequest *audio_req[2];
- struct MsgPort *audio_port;
- Sint32 freq, type, bytespersample, size;
- Uint8 *mixbuf[2]; /* The app mixing buffer */
- int current_buffer;
- Uint32 playing;
-};
-
-/* Old variable names */
-#define audio_port (this->hidden->audio_port)
-#define audio_req (this->hidden->audio_req)
-#define mixbuf (this->hidden->mixbuf)
-#define current_buffer (this->hidden->current_buffer)
-#define playing (this->hidden->playing)
-
-#endif /* _SDL_ahiaudio_h */
-/* vi: set ts=4 sw=4 expandtab: */
--- a/src/audio/arts/SDL_artsaudio.c Sun Oct 01 16:10:41 2006 +0000
+++ b/src/audio/arts/SDL_artsaudio.c Tue Oct 17 09:15:21 2006 +0000
@@ -27,7 +27,6 @@
#include "SDL_audio.h"
#include "../SDL_audiomem.h"
#include "../SDL_audio_c.h"
-#include "../SDL_audiodev_c.h"
#include "SDL_artsaudio.h"
#ifdef SDL_AUDIO_DRIVER_ARTS_DYNAMIC
@@ -40,19 +39,12 @@
/* The tag name used by artsc audio */
#define ARTS_DRIVER_NAME "arts"
-/* Audio driver functions */
-static int ARTS_OpenAudio(_THIS, SDL_AudioSpec * spec);
-static void ARTS_WaitAudio(_THIS);
-static void ARTS_PlayAudio(_THIS);
-static Uint8 *ARTS_GetAudioBuf(_THIS);
-static void ARTS_CloseAudio(_THIS);
-
#ifdef SDL_AUDIO_DRIVER_ARTS_DYNAMIC
static const char *arts_library = SDL_AUDIO_DRIVER_ARTS_DYNAMIC;
static void *arts_handle = NULL;
-static int arts_loaded = 0;
+/* !!! FIXME: I hate this SDL_NAME clutter...it makes everything so messy! */
static int (*SDL_NAME(arts_init)) (void);
static void (*SDL_NAME(arts_free)) (void);
static arts_stream_t(*SDL_NAME(arts_play_stream)) (int rate, int bits,
@@ -65,28 +57,32 @@
static int (*SDL_NAME(arts_write)) (arts_stream_t s, const void *buffer,
int count);
static void (*SDL_NAME(arts_close_stream)) (arts_stream_t s);
+static void (*SDL_NAME(arts_close_stream)) (arts_stream_t s);
+static const char *(*SDL_NAME(arts_error_text)) (int errorcode);
+#define SDL_ARTS_SYM(x) { #x, (void **) (char *) &SDL_NAME(x) }
static struct
{
const char *name;
void **func;
} arts_functions[] = {
- {
- "arts_init", (void **) &SDL_NAME(arts_init)}, {
- "arts_free", (void **) &SDL_NAME(arts_free)}, {
- "arts_play_stream", (void **) &SDL_NAME(arts_play_stream)}, {
- "arts_stream_set", (void **) &SDL_NAME(arts_stream_set)}, {
- "arts_stream_get", (void **) &SDL_NAME(arts_stream_get)}, {
- "arts_write", (void **) &SDL_NAME(arts_write)}, {
-"arts_close_stream", (void **) &SDL_NAME(arts_close_stream)},};
+ SDL_ARTS_SYM(arts_init),
+ SDL_ARTS_SYM(arts_free),
+ SDL_ARTS_SYM(arts_play_stream),
+ SDL_ARTS_SYM(arts_stream_set),
+ SDL_ARTS_SYM(arts_stream_get),
+ SDL_ARTS_SYM(arts_write),
+ SDL_ARTS_SYM(arts_close_stream),
+ SDL_ARTS_SYM(arts_error_text),
+};
+#undef SDL_ARTS_SYM
static void
UnloadARTSLibrary()
{
- if (arts_loaded) {
+ if (arts_handle != NULL) {
SDL_UnloadObject(arts_handle);
arts_handle = NULL;
- arts_loaded = 0;
}
}
@@ -95,20 +91,22 @@
{
int i, retval = -1;
- arts_handle = SDL_LoadObject(arts_library);
- if (arts_handle) {
- arts_loaded = 1;
- retval = 0;
- for (i = 0; i < SDL_arraysize(arts_functions); ++i) {
- *arts_functions[i].func =
- SDL_LoadFunction(arts_handle, arts_functions[i].name);
- if (!*arts_functions[i].func) {
- retval = -1;
- UnloadARTSLibrary();
- break;
+ if (arts_handle == NULL) {
+ arts_handle = SDL_LoadObject(arts_library);
+ if (arts_handle != NULL) {
+ retval = 0;
+ for (i = 0; i < SDL_arraysize(arts_functions); ++i) {
+ *arts_functions[i].func =
+ SDL_LoadFunction(arts_handle, arts_functions[i].name);
+ if (!*arts_functions[i].func) {
+ retval = -1;
+ UnloadARTSLibrary();
+ break;
+ }
}
}
}
+
return retval;
}
@@ -128,117 +126,45 @@
#endif /* SDL_AUDIO_DRIVER_ARTS_DYNAMIC */
-/* Audio driver bootstrap functions */
-
-static int
-Audio_Available(void)
-{
- int available = 0;
-
- if (LoadARTSLibrary() < 0) {
- return available;
- }
- if (SDL_NAME(arts_init) () == 0) {
-#define ARTS_CRASH_HACK /* Play a stream so aRts doesn't crash */
-#ifdef ARTS_CRASH_HACK
- arts_stream_t stream2;
- stream2 = SDL_NAME(arts_play_stream) (44100, 16, 2, "SDL");
- SDL_NAME(arts_write) (stream2, "", 0);
- SDL_NAME(arts_close_stream) (stream2);
-#endif
- available = 1;
- SDL_NAME(arts_free) ();
- }
- UnloadARTSLibrary();
-
- return available;
-}
-
-static void
-Audio_DeleteDevice(SDL_AudioDevice * device)
-{
- SDL_free(device->hidden);
- SDL_free(device);
- UnloadARTSLibrary();
-}
-
-static SDL_AudioDevice *
-Audio_CreateDevice(int devindex)
-{
- SDL_AudioDevice *this;
-
- /* Initialize all variables that we clean on shutdown */
- LoadARTSLibrary();
- 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));
- stream = 0;
-
- /* Set the function pointers */
- this->OpenAudio = ARTS_OpenAudio;
- this->WaitAudio = ARTS_WaitAudio;
- this->PlayAudio = ARTS_PlayAudio;
- this->GetAudioBuf = ARTS_GetAudioBuf;
- this->CloseAudio = ARTS_CloseAudio;
-
- this->free = Audio_DeleteDevice;
-
- return this;
-}
-
-AudioBootStrap ARTS_bootstrap = {
- ARTS_DRIVER_NAME, "Analog Realtime Synthesizer",
- Audio_Available, Audio_CreateDevice
-};
-
/* This function waits until it is possible to write a full sound buffer */
static void
-ARTS_WaitAudio(_THIS)
+ARTS_WaitDevice(_THIS)
{
Sint32 ticks;
/* Check to see if the thread-parent process is still alive */
{
static int cnt = 0;
- /* Note that this only works with thread implementations
+ /* Note that this only works with thread implementations
that use a different process id for each thread.
*/
- if (parent && (((++cnt) % 10) == 0)) { /* Check every 10 loops */
- if (kill(parent, 0) < 0) {
+ /* Check every 10 loops */
+ if (this->hidden->parent && (((++cnt) % 10) == 0)) {
+ if (kill(this->hidden->parent, 0) < 0) {
this->enabled = 0;
}
}
}
/* Use timer for general audio synchronization */
- ticks = ((Sint32) (next_frame - SDL_GetTicks())) - FUDGE_TICKS;
+ ticks = ((Sint32) (this->hidden->next_frame-SDL_GetTicks())) - FUDGE_TICKS;
if (ticks > 0) {
SDL_Delay(ticks);
}
}
static void
-ARTS_PlayAudio(_THIS)
+ARTS_PlayDevice(_THIS)
{
- int written;
-
/* Write the audio data */
- written = SDL_NAME(arts_write) (stream, mixbuf, mixlen);
+ int written = SDL_NAME(arts_write) (
+ this->hidden->stream,
+ this->hidden->mixbuf,
+ this->hidden->mixlen);
/* If timer synchronization is enabled, set the next write frame */
- if (frame_ticks) {
- next_frame += frame_ticks;
+ if (this->hidden->frame_ticks) {
+ this->hidden->next_frame += this->hidden->frame_ticks;
}
/* If we couldn't write, assume fatal error for now */
@@ -250,41 +176,57 @@
#endif
}
-static Uint8 *
-ARTS_GetAudioBuf(_THIS)
+static void
+ARTS_WaitDone(_THIS)
{
- return (mixbuf);
+ /* !!! FIXME: camp here until buffer drains... SDL_Delay(???); */
}
+
+static Uint8 *
+ARTS_GetDeviceBuf(_THIS)
+{
+ return (this->hidden->mixbuf);
+}
+
+
static void
-ARTS_CloseAudio(_THIS)
+ARTS_CloseDevice(_THIS)
{
- if (mixbuf != NULL) {
- SDL_FreeAudioMem(mixbuf);
- mixbuf = NULL;
+ if (this->hidden != NULL) {
+ if (this->hidden->mixbuf != NULL) {
+ SDL_FreeAudioMem(this->hidden->mixbuf);
+ this->hidden->mixbuf = NULL;
+ }
+ if (this->hidden->stream) {
+ SDL_NAME(arts_close_stream) (this->hidden->stream);
+ this->hidden->stream = 0;
+ }
+ SDL_NAME(arts_free) ();
+ SDL_free(this->hidden);
+ this->hidden = NULL;
}
- if (stream) {
- SDL_NAME(arts_close_stream) (stream);
- stream = 0;
- }
- SDL_NAME(arts_free) ();
}
+
static int
-ARTS_OpenAudio(_THIS, SDL_AudioSpec * spec)
+ARTS_OpenDevice(_THIS, const char *devname, int iscapture)
{
- int bits, frag_spec;
- SDL_AudioFormat test_format, format;
+ int rc = 0;
+ int bits = 0, frag_spec = 0;
+ SDL_AudioFormat test_format = 0, format = 0;
- /* Reset the timer synchronization flag */
- frame_ticks = 0.0;
-
- mixbuf = NULL;
+ /* Initialize all variables that we clean on shutdown */
+ this->hidden = (struct SDL_PrivateAudioData *)
+ SDL_malloc((sizeof *this->hidden));
+ if (this->hidden == NULL) {
+ SDL_OutOfMemory();
+ return 0;
+ }
+ SDL_memset(this->hidden, 0, (sizeof *this->hidden));
/* Try for a closest match on audio format */
- format = 0;
- bits = 0;
- for (test_format = SDL_FirstAudioFormat(spec->format);
+ for (test_format = SDL_FirstAudioFormat(this->spec.format);
!format && test_format;) {
#ifdef DEBUG_AUDIO
fprintf(stderr, "Trying format 0x%4.4x\n", test_format);
@@ -307,51 +249,108 @@
}
}
if (format == 0) {
+ ARTS_CloseDevice(this);
SDL_SetError("Couldn't find any hardware audio formats");
- return (-1);
+ return 0;
}
- spec->format = test_format;
+ this->spec.format = test_format;
- if (SDL_NAME(arts_init) () != 0) {
- SDL_SetError("Unable to initialize ARTS");
- return (-1);
+ if ((rc = SDL_NAME(arts_init) ()) != 0) {
+ ARTS_CloseDevice(this);
+ SDL_SetError( "Unable to initialize ARTS: %s",
+ SDL_NAME(arts_error_text)(rc) );
+ return 0;
}
- stream =
- SDL_NAME(arts_play_stream) (spec->freq, bits, spec->channels, "SDL");
+ this->hidden->stream = SDL_NAME(arts_play_stream) (
+ this->spec.freq,
+ bits, this->spec.channels,
+ "SDL");
/* Calculate the final parameters for this audio specification */
- SDL_CalculateAudioSpec(spec);
+ SDL_CalculateAudioSpec(&this->spec);
/* Determine the power of two of the fragment size */
- for (frag_spec = 0; (0x01 << frag_spec) < spec->size; ++frag_spec);
- if ((0x01 << frag_spec) != spec->size) {
+ for (frag_spec = 0; (0x01 << frag_spec) < this->spec.size; ++frag_spec);
+ if ((0x01 << frag_spec) != this->spec.size) {
+ ARTS_CloseDevice(this);
SDL_SetError("Fragment size must be a power of two");
- return (-1);
+ return 0;
}
frag_spec |= 0x00020000; /* two fragments, for low latency */
#ifdef ARTS_P_PACKET_SETTINGS
- SDL_NAME(arts_stream_set) (stream, ARTS_P_PACKET_SETTINGS, frag_spec);
+ SDL_NAME(arts_stream_set) (this->hidden->stream,
+ ARTS_P_PACKET_SETTINGS, frag_spec);
#else
- SDL_NAME(arts_stream_set) (stream, ARTS_P_PACKET_SIZE,
+ SDL_NAME(arts_stream_set) (this->hidden->stream, ARTS_P_PACKET_SIZE,
frag_spec & 0xffff);
- SDL_NAME(arts_stream_set) (stream, ARTS_P_PACKET_COUNT, frag_spec >> 16);
+ SDL_NAME(arts_stream_set) (this->hidden->stream, ARTS_P_PACKET_COUNT,
+ frag_spec >> 16);
#endif
- spec->size = SDL_NAME(arts_stream_get) (stream, ARTS_P_PACKET_SIZE);
+ this->spec.size = SDL_NAME(arts_stream_get) (this->hidden->stream,
+ ARTS_P_PACKET_SIZE);
/* Allocate mixing buffer */
- mixlen = spec->size;
- mixbuf = (Uint8 *) SDL_AllocAudioMem(mixlen);
- if (mixbuf == NULL) {
- return (-1);
+ this->hidden->mixlen = this->spec.size;
+ this->hidden->mixbuf = (Uint8 *) SDL_AllocAudioMem(this->hidden->mixlen);
+ if (this->hidden->mixbuf == NULL) {
+ ARTS_CloseDevice(this);
+ SDL_OutOfMemory();
+ return 0;
}
- SDL_memset(mixbuf, spec->silence, spec->size);
+ SDL_memset(this->hidden->mixbuf, this->spec.silence, this->spec.size);
/* Get the parent process id (we're the parent of the audio thread) */
- parent = getpid();
+ this->hidden->parent = getpid();
/* We're ready to rock and roll. :-) */
- return (0);
+ return 1;
+}
+
+
+static void
+ARTS_Deinitialize(void)
+{
+ UnloadARTSLibrary();
}
+
+static int
+ARTS_Init(SDL_AudioDriverImpl *impl)
+{
+ if (LoadARTSLibrary() < 0) {
+ return 0;
+ } else {
+ if (SDL_NAME(arts_init) () != 0) {
+ UnloadARTSLibrary();
+ SDL_SetError("ARTS: arts_init failed (no audio server?)");
+ return 0;
+ }
+
+ /* Play a stream so aRts doesn't crash */
+ arts_stream_t stream;
+ stream = SDL_NAME(arts_play_stream) (44100, 16, 2, "SDL");
+ SDL_NAME(arts_write) (stream, "", 0);
+ SDL_NAME(arts_close_stream) (stream);
+ SDL_NAME(arts_free) ();
+ }
+
+ /* Set the function pointers */
+ impl->OpenDevice = ARTS_OpenDevice;
+ impl->PlayDevice = ARTS_PlayDevice;
+ impl->WaitDevice = ARTS_WaitDevice;
+ impl->GetDeviceBuf = ARTS_GetDeviceBuf;
+ impl->CloseDevice = ARTS_CloseDevice;
+ impl->WaitDone = ARTS_WaitDone;
+ impl->Deinitialize = ARTS_Deinitialize;
+ impl->OnlyHasDefaultOutputDevice = 1;
+
+ return 1;
+}
+
+
+AudioBootStrap ARTS_bootstrap = {
+ ARTS_DRIVER_NAME, "Analog RealTime Synthesizer", ARTS_Init, 0
+};
+
/* vi: set ts=4 sw=4 expandtab: */
--- a/src/audio/arts/SDL_artsaudio.h Sun Oct 01 16:10:41 2006 +0000
+++ b/src/audio/arts/SDL_artsaudio.h Tue Oct 17 09:15:21 2006 +0000
@@ -28,7 +28,7 @@
#include "../SDL_sysaudio.h"
-/* Hidden "this" pointer for the video functions */
+/* Hidden "this" pointer for the audio functions */
#define _THIS SDL_AudioDevice *this
struct SDL_PrivateAudioData
@@ -49,13 +49,5 @@
};
#define FUDGE_TICKS 10 /* The scheduler overhead ticks per frame */
-/* Old variable names */
-#define stream (this->hidden->stream)
-#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_artscaudio_h */
/* vi: set ts=4 sw=4 expandtab: */
--- a/src/audio/baudio/SDL_beaudio.cc Sun Oct 01 16:10:41 2006 +0000
+++ b/src/audio/baudio/SDL_beaudio.cc Tue Oct 17 09:15:21 2006 +0000
@@ -36,138 +36,81 @@
#include "../../thread/beos/SDL_systhread_c.h"
#include "SDL_beaudio.h"
+}
-/* Audio driver functions */
- static int BE_OpenAudio(_THIS, SDL_AudioSpec * spec);
- static void BE_WaitAudio(_THIS);
- static void BE_PlayAudio(_THIS);
- static Uint8 *BE_GetAudioBuf(_THIS);
- static void BE_CloseAudio(_THIS);
-
-/* Audio driver bootstrap functions */
- static int Audio_Available(void)
- {
- return (1);
- }
-
- static void Audio_DeleteDevice(SDL_AudioDevice * device)
- {
- SDL_free(device->hidden);
- SDL_free(device);
- }
-
- static SDL_AudioDevice *Audio_CreateDevice(int devindex)
- {
- SDL_AudioDevice *device;
+/* !!! FIXME: have the callback call the higher level to avoid code dupe. */
+/* The BeOS callback for handling the audio buffer */
+static void
+FillSound(void *device, void *stream, size_t len,
+ const media_raw_audio_format & format)
+{
+ SDL_AudioDevice *audio = (SDL_AudioDevice *) device;
- /* Initialize all variables that we clean on shutdown */
- device = (SDL_AudioDevice *) SDL_malloc(sizeof(SDL_AudioDevice));
- if (device) {
- SDL_memset(device, 0, (sizeof *device));
- device->hidden = (struct SDL_PrivateAudioData *)
- SDL_malloc((sizeof *device->hidden));
- }
- if ((device == NULL) || (device->hidden == NULL)) {
- SDL_OutOfMemory();
- if (device) {
- SDL_free(device);
- }
- return (0);
- }
- SDL_memset(device->hidden, 0, (sizeof *device->hidden));
-
- /* Set the function pointers */
- device->OpenAudio = BE_OpenAudio;
- device->WaitAudio = BE_WaitAudio;
- device->PlayAudio = BE_PlayAudio;
- device->GetAudioBuf = BE_GetAudioBuf;
- device->CloseAudio = BE_CloseAudio;
-
- device->free = Audio_DeleteDevice;
+ /* Silence the buffer, since it's ours */
+ SDL_memset(stream, audio->spec.silence, len);
- return device;
- }
-
- AudioBootStrap BAUDIO_bootstrap = {
- "baudio", "BeOS BSoundPlayer",
- Audio_Available, Audio_CreateDevice
- };
+ /* Only do soemthing if audio is enabled */
+ if (!audio->enabled)
+ return;
-/* The BeOS callback for handling the audio buffer */
- static void FillSound(void *device, void *stream, size_t len,
- const media_raw_audio_format & format)
- {
- SDL_AudioDevice *audio = (SDL_AudioDevice *) device;
-
- /* Silence the buffer, since it's ours */
- SDL_memset(stream, audio->spec.silence, len);
-
- /* Only do soemthing if audio is enabled */
- if (!audio->enabled)
- return;
-
- if (!audio->paused) {
- if (audio->convert.needed) {
- SDL_mutexP(audio->mixer_lock);
- (*audio->spec.callback) (audio->spec.userdata,
+ if (!audio->paused) {
+ if (audio->convert.needed) {
+ SDL_mutexP(audio->mixer_lock);
+ (*audio->spec.callback) (audio->spec.userdata,
(Uint8 *) audio->convert.buf,
audio->convert.len);
- SDL_mutexV(audio->mixer_lock);
- SDL_ConvertAudio(&audio->convert);
- SDL_memcpy(stream, audio->convert.buf,
- audio->convert.len_cvt);
- } else {
- SDL_mutexP(audio->mixer_lock);
- (*audio->spec.callback) (audio->spec.userdata,
- (Uint8 *) stream, len);
- SDL_mutexV(audio->mixer_lock);
- }
+ SDL_mutexV(audio->mixer_lock);
+ SDL_ConvertAudio(&audio->convert);
+ SDL_memcpy(stream, audio->convert.buf, audio->convert.len_cvt);
+ } else {
+ SDL_mutexP(audio->mixer_lock);
+ (*audio->spec.callback) (audio->spec.userdata,
+ (Uint8 *) stream, len);
+ SDL_mutexV(audio->mixer_lock);
}
- return;
}
+}
-/* Dummy functions -- we don't use thread-based audio */
- void BE_WaitAudio(_THIS)
- {
- return;
- }
- void BE_PlayAudio(_THIS)
- {
- return;
- }
- Uint8 *BE_GetAudioBuf(_THIS)
- {
- return (NULL);
- }
-
- void BE_CloseAudio(_THIS)
- {
- if (audio_obj) {
- audio_obj->Stop();
- delete audio_obj;
- audio_obj = NULL;
+static void
+BEOSAUDIO_CloseDevice(_THIS)
+{
+ if (_this->hidden != NULL) {
+ if (_this->hidden->audio_obj) {
+ _this->hidden->audio_obj->Stop();
+ delete _this->hidden->audio_obj;
+ _this->hidden->audio_obj = NULL;
}
- /* Quit the Be Application, if there's nothing left to do */
- SDL_QuitBeApp();
+ delete _this->hidden;
+ _this->hidden = NULL;
}
+}
- int BE_OpenAudio(_THIS, SDL_AudioSpec * spec)
- {
- int valid_datatype = 0;
- media_raw_audio_format format;
- SDL_AudioFormat test_format = SDL_FirstAudioFormat(spec->format);
+static int
+BEOSAUDIO_OpenDevice(_THIS, const char *devname, int iscapture)
+{
+ int valid_datatype = 0;
+ media_raw_audio_format format;
+ SDL_AudioFormat test_format = SDL_FirstAudioFormat(_this->spec.format);
- /* Parse the audio format and fill the Be raw audio format */
- memset(&format, '\0', sizeof(media_raw_audio_format));
- format.byte_order = B_MEDIA_LITTLE_ENDIAN;
- format.frame_rate = (float) spec->freq;
- format.channel_count = spec->channels; /* !!! FIXME: support > 2? */
- while ((!valid_datatype) && (test_format)) {
- valid_datatype = 1;
- spec->format = test_format;
- switch (test_format) {
+ /* Initialize all variables that we clean on shutdown */
+ _this->hidden = new SDL_PrivateAudioData;
+ if (_this->hidden == NULL) {
+ SDL_OutOfMemory();
+ return 0;
+ }
+ SDL_memset(_this->hidden, 0, (sizeof *_this->hidden));
+
+ /* Parse the audio format and fill the Be raw audio format */
+ SDL_memset(&format, '\0', sizeof(media_raw_audio_format));
+ format.byte_order = B_MEDIA_LITTLE_ENDIAN;
+ format.frame_rate = (float) _this->spec.freq;
+ format.channel_count = _this->spec.channels; /* !!! FIXME: support > 2? */
+ while ((!valid_datatype) && (test_format)) {
+ valid_datatype = 1;
+ _this->spec.format = test_format;
+ switch (test_format) {
case AUDIO_S8:
format.format = media_raw_audio_format::B_AUDIO_CHAR;
break;
@@ -207,43 +150,67 @@
valid_datatype = 0;
test_format = SDL_NextAudioFormat();
break;
- }
}
+ }
- format.buffer_size = spec->samples;
+ format.buffer_size = _this->spec.samples;
- if (!valid_datatype) { /* shouldn't happen, but just in case... */
- SDL_SetError("Unsupported audio format");
- return (-1);
- }
+ if (!valid_datatype) { /* shouldn't happen, but just in case... */
+ BEOSAUDIO_CloseDevice(_this);
+ SDL_SetError("Unsupported audio format");
+ return 0;
+ }
- /* Initialize the Be Application, if it's not already started */
- if (SDL_InitBeApp() < 0) {
- return (-1);
- }
-
- /* Calculate the final parameters for this audio specification */
- SDL_CalculateAudioSpec(spec);
+ /* Calculate the final parameters for this audio specification */
+ SDL_CalculateAudioSpec(&_this->spec);
- /* Subscribe to the audio stream (creates a new thread) */
- {
- sigset_t omask;
- SDL_MaskSignals(&omask);
- audio_obj = new BSoundPlayer(&format, "SDL Audio", FillSound,
- NULL, _this);
- SDL_UnmaskSignals(&omask);
- }
- if (audio_obj->Start() == B_NO_ERROR) {
- audio_obj->SetHasData(true);
- } else {
- SDL_SetError("Unable to start Be audio");
- return (-1);
- }
+ /* Subscribe to the audio stream (creates a new thread) */
+ sigset_t omask;
+ SDL_MaskSignals(&omask);
+ _this->hidden->audio_obj = new BSoundPlayer(&format, "SDL Audio",
+ FillSound, NULL, _this);
+ SDL_UnmaskSignals(&omask);
- /* We're running! */
- return (1);
+ if (_this->hidden->audio_obj->Start() == B_NO_ERROR) {
+ _this->hidden->audio_obj->SetHasData(true);
+ } else {
+ BEOSAUDIO_CloseDevice(_this);
+ SDL_SetError("Unable to start Be audio");
+ return 0;
}
-}; /* Extern C */
+ /* We're running! */
+ return 1;
+}
+
+static void
+BEOSAUDIO_Deinitialize(void)
+{
+ SDL_QuitBeApp();
+}
+
+static int
+BEOSAUDIO_Init(SDL_AudioDriverImpl *impl)
+{
+ /* Initialize the Be Application, if it's not already started */
+ if (SDL_InitBeApp() < 0) {
+ return 0;
+ }
+
+ /* Set the function pointers */
+ impl->OpenDevice = BEOSAUDIO_OpenDevice;
+ impl->CloseDevice = BEOSAUDIO_CloseDevice;
+ impl->Deinitialize = BEOSAUDIO_Deinitialize;
+ impl->ProvidesOwnCallbackThread = 1;
+ impl->OnlyHasDefaultOutputDevice = 1;
+
+ return 1;
+}
+
+extern "C" { extern AudioBootStrap BEOSAUDIO_bootstrap; }
+AudioBootStrap BEOSAUDIO_bootstrap = {
+ "baudio", "BeOS BSoundPlayer", BEOSAUDIO_Init, 0
+};
/* vi: set ts=4 sw=4 expandtab: */
+
--- a/src/audio/baudio/SDL_beaudio.h Sun Oct 01 16:10:41 2006 +0000
+++ b/src/audio/baudio/SDL_beaudio.h Tue Oct 17 09:15:21 2006 +0000
@@ -21,12 +21,12 @@
*/
#include "SDL_config.h"
-#ifndef _SDL_lowaudio_h
-#define _SDL_lowaudio_h
+#ifndef _SDL_beaudio_h
+#define _SDL_beaudio_h
#include "../SDL_sysaudio.h"
-/* Hidden "this" pointer for the video functions */
+/* Hidden "this" pointer for the audio functions */
#define _THIS SDL_AudioDevice *_this
struct SDL_PrivateAudioData
@@ -34,8 +34,6 @@
BSoundPlayer *audio_obj;
};
-/* Old variable names */
-#define audio_obj (_this->hidden->audio_obj)
+#endif /* _SDL_beaudio_h */
-#endif /* _SDL_lowaudio_h */
/* vi: set ts=4 sw=4 expandtab: */
--- a/src/audio/bsd/SDL_bsdaudio.c Sun Oct 01 16:10:41 2006 +0000
+++ b/src/audio/bsd/SDL_bsdaudio.c Tue Oct 17 09:15:21 2006 +0000
@@ -61,195 +61,91 @@
/* #define DEBUG_AUDIO_STREAM */
#ifdef USE_BLOCKING_WRITES
-#define OPEN_FLAGS O_WRONLY
+#define OPEN_FLAGS_OUTPUT O_WRONLY
+#define OPEN_FLAGS_INPUT O_RDONLY
#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);
+#define OPEN_FLAGS_OUTPUT (O_WRONLY|O_NONBLOCK)
+#define OPEN_FLAGS_INPUT (O_RDONLY|O_NONBLOCK)
#endif
-/* Audio driver bootstrap functions */
-
-static int
-Audio_Available(void)
-{
- int fd;
- int available;
+/* !!! FIXME: so much cut and paste with dsp/dma drivers... */
+static char **outputDevices = NULL;
+static int outputDeviceCount = 0;
+static char **inputDevices = NULL;
+static int inputDeviceCount = 0;
- available = 0;
- fd = SDL_OpenAudioPath(NULL, 0, OPEN_FLAGS, 0);
- if (fd >= 0) {
- available = 1;
- close(fd);
- }
- return (available);
+static inline void
+free_device_list(char ***devs, int *count)
+{
+ SDL_FreeUnixAudioDevices(devs, count);
}
-static void
-Audio_DeleteDevice(SDL_AudioDevice * device)
+static inline void
+build_device_list(int iscapture, char ***devs, int *count)
{
- SDL_free(device->hidden);
- SDL_free(device);
+ const int flags = ((iscapture) ? OPEN_FLAGS_INPUT : OPEN_FLAGS_OUTPUT);
+ free_device_list(devs, count);
+ SDL_EnumUnixAudioDevices(flags, 0, NULL, devs, count);
}
-static SDL_AudioDevice *
-Audio_CreateDevice(int devindex)
+static inline void
+build_device_lists(void)
{
- SDL_AudioDevice *this;
+ build_device_list(0, &outputDevices, &outputDeviceCount);
+ build_device_list(1, &inputDevices, &inputDeviceCount);
+}
- /* 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;
+static inline void
+free_device_lists(void)
+{
+ free_device_list(&outputDevices, &outputDeviceCount);
+ free_device_list(&inputDevices, &inputDeviceCount);
}
-AudioBootStrap BSD_AUDIO_bootstrap = {
- BSD_AUDIO_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)
+BSDAUDIO_Deinitialize(void)
{
- int written, p = 0;
+ free_device_lists();
+}
+
- /* 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;
+static int
+BSDAUDIO_DetectDevices(int iscapture)
+{
+ if (iscapture) {
+ build_device_list(1, &inputDevices, &inputDeviceCount);
+ return inputDeviceCount;
+ } else {
+ build_device_list(0, &outputDevices, &outputDeviceCount);
+ return outputDeviceCount;
}
- /* 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
+ return 0; /* shouldn't ever hit this. */
}
-static Uint8 *
-OBSD_GetAudioBuf(_THIS)
+static const char *
+BSDAUDIO_GetDeviceName(int index, int iscapture)
{
- return (mixbuf);
+ if ((iscapture) && (index < inputDeviceCount)) {
+ return inputDevices[index];
+ } else if ((!iscapture) && (index < outputDeviceCount)) {
+ return outputDevices[index];
+ }
+
+ SDL_SetError("No such device");
+ return NULL;
}
+
static void
-OBSD_CloseAudio(_THIS)
+BSDAUDIO_Status(_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) {
+ if (ioctl(this->hidden->audio_fd, AUDIO_GETINFO, &info) < 0) {
fprintf(stderr, "AUDIO_GETINFO failed.\n");
return;
}
@@ -269,46 +165,18 @@
"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");
+ 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"
@@ -324,42 +192,170 @@
(info.mode == AUMODE_PLAY) ? "PLAY"
: (info.mode = AUMODE_RECORD) ? "RECORD"
: (info.mode == AUMODE_PLAY_ALL ? "PLAY_ALL" : "?"));
+#endif /* DEBUG_AUDIO */
}
-#endif /* DEBUG_AUDIO */
+
+
+/* This function waits until it is possible to write a full sound buffer */
+static void
+BSDAUDIO_WaitDevice(_THIS)
+{
+#ifndef USE_BLOCKING_WRITES /* Not necessary when using blocking writes */
+ /* See if we need to use timed audio synchronization */
+ if (this->hidden->frame_ticks) {
+ /* Use timer for general audio synchronization */
+ Sint32 ticks;
+
+ ticks = ((Sint32)(this->hidden->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(this->hidden->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(this->hidden->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 */
+ this->hidden->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
+BSDAUDIO_PlayDevice(_THIS)
+{
+ int written, p = 0;
+
+ /* Write the audio data, checking for EAGAIN on broken audio drivers */
+ do {
+ written = write(this->hidden->audio_fd,
+ &this->hidden->mixbuf[p],
+ this->hidden->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 (this->hidden->frame_ticks) {
+ this->hidden->next_frame += this->hidden->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 *
+BSDAUDIO_GetDeviceBuf(_THIS)
+{
+ return (this->hidden->mixbuf);
+}
+
+static void
+BSDAUDIO_CloseDevice(_THIS)
+{
+ if (this->hidden != NULL) {
+ if (this->hidden->mixbuf != NULL) {
+ SDL_FreeAudioMem(this->hidden->mixbuf);
+ this->hidden->mixbuf = NULL;
+ }
+ if (this->hidden->audio_fd >= 0) {
+ close(this->hidden->audio_fd);
+ this->hidden->audio_fd = -1;
+ }
+ SDL_free(this->hidden);
+ this->hidden = NULL;
+ }
+}
static int
-OBSD_OpenAudio(_THIS, SDL_AudioSpec * spec)
+BSDAUDIO_OpenDevice(_THIS, const char *devname, int iscapture)
{
- char audiodev[64];
- SDL_AudioFormat format;
+ const int flags = ((iscapture) ? OPEN_FLAGS_INPUT : OPEN_FLAGS_OUTPUT);
+ SDL_AudioFormat format = 0;
audio_info_t info;
+ /* We don't care what the devname is...we'll try to open anything. */
+ /* ...but default to first name in the list... */
+ if (devname == NULL) {
+ if ( ((iscapture) && (inputDeviceCount == 0)) ||
+ ((!iscapture) && (outputDeviceCount == 0)) ) {
+ SDL_SetError("No such audio device");
+ return 0;
+ }
+ devname = ((iscapture) ? inputDevices[0] : outputDevices[0]);
+ }
+
+ /* Initialize all variables that we clean on shutdown */
+ this->hidden = (struct SDL_PrivateAudioData *)
+ SDL_malloc((sizeof *this->hidden));
+ if (this->hidden == NULL) {
+ SDL_OutOfMemory();
+ return 0;
+ }
+ SDL_memset(this->hidden, 0, (sizeof *this->hidden));
+
+ /* Open the audio device */
+ this->hidden->audio_fd = open(devname, flags, 0);
+ if (this->hidden->audio_fd < 0) {
+ SDL_SetError("Couldn't open %s: %s", devname, strerror(errno));
+ return 0;
+ }
+
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);
- }
+ SDL_CalculateAudioSpec(&this->spec);
/* Set to play mode */
info.mode = AUMODE_PLAY;
- if (ioctl(audio_fd, AUDIO_SETINFO, &info) < 0) {
+ if (ioctl(this->hidden->audio_fd, AUDIO_SETINFO, &info) < 0) {
+ BSDAUDIO_CloseDevice(this);
SDL_SetError("Couldn't put device into play mode");
- return (-1);
+ return 0;
}
- mixbuf = NULL;
AUDIO_INITINFO(&info);
- for (format = SDL_FirstAudioFormat(spec->format);
+ for (format = SDL_FirstAudioFormat(this->spec.format);
format; format = SDL_NextAudioFormat()) {
switch (format) {
case AUDIO_U8:
@@ -389,46 +385,69 @@
default:
continue;
}
- if (ioctl(audio_fd, AUDIO_SETINFO, &info) == 0)
+
+ if (ioctl(this->hidden->audio_fd, AUDIO_SETINFO, &info) == 0) {
break;
+ }
}
if (!format) {
- SDL_SetError("No supported encoding for 0x%x", spec->format);
- return (-1);
+ BSDAUDIO_CloseDevice(this);
+ SDL_SetError("No supported encoding for 0x%x", this->spec.format);
+ return 0;
}
- spec->format = format;
+ this->spec.format = format;
AUDIO_INITINFO(&info);
- info.play.channels = spec->channels;
- if (ioctl(audio_fd, AUDIO_SETINFO, &info) == -1)
- spec->channels = 1;
+ info.play.channels = this->spec.channels;
+ if (ioctl(this->hidden->audio_fd, AUDIO_SETINFO, &info) == -1) {
+ this->spec.channels = 1;
+ }
AUDIO_INITINFO(&info);
- info.play.sample_rate = spec->freq;
- info.blocksize = spec->size;
+ info.play.sample_rate = this->spec.freq;
+ info.blocksize = this->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;
+ (void) ioctl(this->hidden->audio_fd, AUDIO_SETINFO, &info);
+ (void) ioctl(this->hidden->audio_fd, AUDIO_GETINFO, &info);
+ this->spec.freq = info.play.sample_rate;
/* Allocate mixing buffer */
- mixlen = spec->size;
- mixbuf = (Uint8 *) SDL_AllocAudioMem(mixlen);
- if (mixbuf == NULL) {
- return (-1);
+ this->hidden->mixlen = this->spec.size;
+ this->hidden->mixbuf = (Uint8 *) SDL_AllocAudioMem(this->hidden->mixlen);
+ if (this->hidden->mixbuf == NULL) {
+ BSDAUDIO_CloseDevice(this);
+ SDL_OutOfMemory();
+ return 0;
}
- SDL_memset(mixbuf, spec->silence, spec->size);
+ SDL_memset(this->hidden->mixbuf, this->spec.silence, this->spec.size);
- /* Get the parent process id (we're the parent of the audio thread) */
- parent = getpid();
-
-#ifdef DEBUG_AUDIO
- OBSD_Status(this);
-#endif
+ BSDAUDIO_Status(this);
/* We're ready to rock and roll. :-) */
return (0);
}
+static int
+BSDAUDIO_Init(SDL_AudioDriverImpl *impl)
+{
+ /* Set the function pointers */
+ impl->DetectDevices = BSDAUDIO_DetectDevices;
+ impl->GetDeviceName = BSDAUDIO_GetDeviceName;
+ impl->OpenDevice = BSDAUDIO_OpenDevice;
+ impl->PlayDevice = BSDAUDIO_PlayDevice;
+ impl->WaitDevice = BSDAUDIO_WaitDevice;
+ impl->GetDeviceBuf = BSDAUDIO_GetDeviceBuf;
+ impl->CloseDevice = BSDAUDIO_CloseDevice;
+ impl->Deinitialize = BSDAUDIO_Deinitialize;
+
+ build_device_lists();
+ return 1;
+}
+
+
+AudioBootStrap BSD_AUDIO_bootstrap = {
+ BSD_AUDIO_DRIVER_NAME, BSD_AUDIO_DRIVER_DESC, BSDAUDIO_Init, 0
+};
+
/* vi: set ts=4 sw=4 expandtab: */
--- a/src/audio/bsd/SDL_bsdaudio.h Sun Oct 01 16:10:41 2006 +0000
+++ b/src/audio/bsd/SDL_bsdaudio.h Tue Oct 17 09:15:21 2006 +0000
@@ -21,8 +21,8 @@
*/
#include "SDL_config.h"
-#ifndef _SDL_openbsdaudio_h
-#define _SDL_openbsdaudio_h
+#ifndef _SDL_bsdaudio_h
+#define _SDL_bsdaudio_h
#include "../SDL_sysaudio.h"
@@ -47,13 +47,6 @@
#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_bsdaudio_h */
-#endif /* _SDL_openbsdaudio_h */
/* vi: set ts=4 sw=4 expandtab: */
--- a/src/audio/dart/SDL_dart.c Sun Oct 01 16:10:41 2006 +0000
+++ b/src/audio/dart/SDL_dart.c Tue Oct 17 09:15:21 2006 +0000
@@ -42,10 +42,10 @@
//---------------------------------------------------------------------
// DARTEventFunc
//
-// This function is called by DART, when an event occures, like end of
+// This function is called by DART, when an event occurs, like end of
// playback of a buffer, etc...
//---------------------------------------------------------------------
-LONG APIENTRY
+static LONG APIENTRY
DARTEventFunc(ULONG ulStatus, PMCI_MIX_BUFFER pBuffer, ULONG ulFlags)
{
if (ulFlags && MIX_WRITE_COMPLETE) { // Playback of buffer completed!
@@ -71,13 +71,12 @@
}
-int
-DART_OpenAudio(_THIS, SDL_AudioSpec * spec)
+static int
+DART_OpenDevice(_THIS, const char *devname, int iscapture)
{
- SDL_AudioFormat test_format = SDL_FirstAudioFormat(spec->format);
+ SDL_AudioFormat test_format = SDL_FirstAudioFormat(_this->spec.format);
int valid_datatype = 0;
MCI_AMP_OPEN_PARMS AmpOpenParms;
- MCI_GENERIC_PARMS GenericParms;
int iDeviceOrd = 0; // Default device to be used
int bOpenShared = 1; // Try opening it shared
int iBits = 16; // Default is 16 bits signed
@@ -89,6 +88,15 @@
int iSilence;
int rc;
+ /* Initialize all variables that we clean on shutdown */
+ _this->hidden = (struct SDL_PrivateAudioData *)
+ SDL_malloc((sizeof *_this->hidden));
+ if (_this->hidden == NULL) {
+ SDL_OutOfMemory();
+ return 0;
+ }
+ SDL_memset(_this->hidden, 0, (sizeof *_this->hidden));
+
// First thing is to try to open a given DART device!
SDL_memset(&AmpOpenParms, 0, sizeof(MCI_AMP_OPEN_PARMS));
// pszDeviceType should contain the device type in low word, and device ordinal in high word!
@@ -100,30 +108,34 @@
iOpenMode |= MCI_OPEN_SHAREABLE;
rc = mciSendCommand(0, MCI_OPEN, iOpenMode, (PVOID) & AmpOpenParms, 0);
- if (rc != MCIERR_SUCCESS) // No audio available??
- return (-1);
+ if (rc != MCIERR_SUCCESS) { // No audio available??
+ DART_CloseDevice(_this);
+ SDL_SetError("DART: Couldn't open audio device.");
+ return 0;
+ }
+
// Save the device ID we got from DART!
// We will use this in the next calls!
- iDeviceOrd = AmpOpenParms.usDeviceID;
+ _this->hidden->iCurrDeviceOrd = iDeviceOrd = AmpOpenParms.usDeviceID;
// Determine the audio parameters from the AudioSpec
- if (spec->channels > 2)
- spec->channels = 2; // !!! FIXME: more than stereo support in OS/2?
+ if (_this->spec.channels > 4)
+ _this->spec.channels = 4;
while ((!valid_datatype) && (test_format)) {
- spec->format = test_format;
+ _this->spec.format = test_format;
valid_datatype = 1;
switch (test_format) {
case AUDIO_U8:
// Unsigned 8 bit audio data
iSilence = 0x80;
- iBits = 8;
+ _this->hidden->iCurrBits = iBits = 8;
break;
case AUDIO_S16LSB:
// Signed 16 bit audio data
iSilence = 0x00;
- iBits = 16;
+ _this->hidden->iCurrBits = iBits = 16;
break;
// !!! FIXME: int32?
@@ -137,16 +149,16 @@
if (!valid_datatype) { // shouldn't happen, but just in case...
// Close DART, and exit with error code!
- mciSendCommand(iDeviceOrd, MCI_CLOSE, MCI_WAIT, &GenericParms, 0);
+ DART_CloseDevice(_this);
SDL_SetError("Unsupported audio format");
- return (-1);
+ return 0;
}
- iFreq = spec->freq;
- iChannels = spec->channels;
+ _this->hidden->iCurrFreq = iFreq = _this->spec.freq;
+ _this->hidden->iCurrChannels = iChannels = _this->spec.channels;
/* Update the fragment size as size in bytes */
- SDL_CalculateAudioSpec(spec);
- iBufSize = spec->size;
+ SDL_CalculateAudioSpec(&_this->spec);
+ _this->hidden->iCurrBufSize = iBufSize = _this->spec.size;
// Now query this device if it supports the given freq/bits/channels!
SDL_memset(&(_this->hidden->MixSetupParms), 0,
@@ -163,9 +175,9 @@
&(_this->hidden->MixSetupParms), 0);
if (rc != MCIERR_SUCCESS) { // The device cannot handle this format!
// Close DART, and exit with error code!
- mciSendCommand(iDeviceOrd, MCI_CLOSE, MCI_WAIT, &GenericParms, 0);
+ DART_CloseDevice(_this);
SDL_SetError("Audio device doesn't support requested audio format");
- return (-1);
+ return 0;
}
// The device can handle this format, so initialize!
rc = mciSendCommand(iDeviceOrd, MCI_MIXSETUP,
@@ -173,9 +185,9 @@
&(_this->hidden->MixSetupParms), 0);
if (rc != MCIERR_SUCCESS) { // The device could not be opened!
// Close DART, and exit with error code!
- mciSendCommand(iDeviceOrd, MCI_CLOSE, MCI_WAIT, &GenericParms, 0);
+ DART_CloseDevice(_this);
SDL_SetError("Audio device could not be set up");
- return (-1);
+ return 0;
}
// Ok, the device is initialized.
// Now we should allocate buffers. For this, we need a place where
@@ -184,9 +196,9 @@
(MCI_MIX_BUFFER *) SDL_malloc(sizeof(MCI_MIX_BUFFER) * iNumBufs);
if (!(_this->hidden->pMixBuffers)) { // Not enough memory!
// Close DART, and exit with error code!
- mciSendCommand(iDeviceOrd, MCI_CLOSE, MCI_WAIT, &GenericParms, 0);
- SDL_SetError("Not enough memory for audio buffer descriptors");
- return (-1);
+ DART_CloseDevice(_this);
+ SDL_OutOfMemory();
+ return 0;
}
// Now that we have the place for buffer list, we can ask DART for the
// buffers!
@@ -201,12 +213,12 @@
|| (iNumBufs != _this->hidden->BufferParms.ulNumBuffers)
|| (_this->hidden->BufferParms.ulBufferSize == 0)) { // Could not allocate memory!
// Close DART, and exit with error code!
- SDL_free(_this->hidden->pMixBuffers);
- _this->hidden->pMixBuffers = NULL;
- mciSendCommand(iDeviceOrd, MCI_CLOSE, MCI_WAIT, &GenericParms, 0);
+ DART_CloseDevice(_this);
SDL_SetError("DART could not allocate buffers");
- return (-1);
+ return 0;
}
+ _this->hidden->iCurrNumBufs = iNumBufs;
+
// Ok, we have all the buffers allocated, let's mark them!
{
int i;
@@ -216,24 +228,9 @@
// Check if this buffer was really allocated by DART
if ((!(_this->hidden->pMixBuffers[i].pBuffer))
|| (!pBufferDesc)) { // Wrong buffer!
- // Close DART, and exit with error code!
- // Free buffer descriptions
- {
- int j;
- for (j = 0; j < i; j++)
- SDL_free((void *) (_this->hidden->pMixBuffers[j].
- ulUserParm));
- }
- // and cleanup
- mciSendCommand(iDeviceOrd, MCI_BUFFER,
- MCI_WAIT | MCI_DEALLOCATE_MEMORY,
- &(_this->hidden->BufferParms), 0);
- SDL_free(_this->hidden->pMixBuffers);
- _this->hidden->pMixBuffers = NULL;
- mciSendCommand(iDeviceOrd, MCI_CLOSE, MCI_WAIT,
- &GenericParms, 0);
+ DART_CloseDevice(_this);
SDL_SetError("Error at internal buffer check");
- return (-1);
+ return 0;
}
pBufferDesc->iBufferUsage = BUFFER_EMPTY;
pBufferDesc->pSDLAudioDevice = _this;
@@ -254,43 +251,41 @@
if (DosCreateEventSem
(NULL, &(_this->hidden->hevAudioBufferPlayed), 0, FALSE) != NO_ERROR)
{
- // Could not create event semaphore!
- {
- int i;
- for (i = 0; i < iNumBufs; i++)
- SDL_free((void *) (_this->hidden->pMixBuffers[i].ulUserParm));
- }
- mciSendCommand(iDeviceOrd, MCI_BUFFER,
- MCI_WAIT | MCI_DEALLOCATE_MEMORY,
- &(_this->hidden->BufferParms), 0);
- SDL_free(_this->hidden->pMixBuffers);
- _this->hidden->pMixBuffers = NULL;
- mciSendCommand(iDeviceOrd, MCI_CLOSE, MCI_WAIT, &GenericParms, 0);
+ DART_CloseDevice(_this);
SDL_SetError("Could not create event semaphore");
- return (-1);
+ return 0;
}
- // Store the new settings in global variables
- _this->hidden->iCurrDeviceOrd = iDeviceOrd;
- _this->hidden->iCurrFreq = iFreq;
- _this->hidden->iCurrBits = iBits;
- _this->hidden->iCurrChannels = iChannels;
- _this->hidden->iCurrNumBufs = iNumBufs;
- _this->hidden->iCurrBufSize = iBufSize;
- return (0);
+ return 1;
}
-
-
-void
+static void
DART_ThreadInit(_THIS)
{
- return;
+ /* Increase the priority of this thread to make sure that
+ the audio will be continuous all the time! */
+#ifdef USE_DOSSETPRIORITY
+ if (SDL_getenv("SDL_USE_TIMECRITICAL_AUDIO")) {
+#ifdef DEBUG_BUILD
+ printf
+ ("[DART_ThreadInit] : Setting priority to TimeCritical+0! (TID%d)\n",
+ SDL_ThreadID());
+#endif
+ DosSetPriority(PRTYS_THREAD, PRTYC_TIMECRITICAL, 0, 0);
+ } else {
+#ifdef DEBUG_BUILD
+ printf
+ ("[DART_ThreadInit] : Setting priority to ForegroundServer+0! (TID%d)\n",
+ SDL_ThreadID());
+#endif
+ DosSetPriority(PRTYS_THREAD, PRTYC_FOREGROUNDSERVER, 0, 0);
+ }
+#endif
}
/* This function waits until it is possible to write a full sound buffer */
-void
-DART_WaitAudio(_THIS)
+static void
+DART_WaitDevice(_THIS)
{
int i;
pMixBufferDesc pBufDesc;
@@ -308,8 +303,8 @@
return;
}
-void
-DART_PlayAudio(_THIS)
+static void
+DART_PlayDevice(_THIS)
{
int iFreeBuf = _this->hidden->iNextFreeBuffer;
pMixBufferDesc pBufDesc;
@@ -328,8 +323,8 @@
_this->hidden->iNextFreeBuffer = iFreeBuf;
}
-Uint8 *
-DART_GetAudioBuf(_THIS)
+static Uint8 *
+DART_GetDeviceBuf(_THIS)
{
int iFreeBuf;
Uint8 *pResult;
@@ -348,125 +343,110 @@
return pResult;
}
} else
- printf("[DART_GetAudioBuf] : ERROR! pBufDesc = %p\n",
+ printf("[DART_GetDeviceBuf] : ERROR! pBufDesc = %p\n",
pBufDesc);
} else
- printf("[DART_GetAudioBuf] : ERROR! _this->hidden = %p\n",
+ printf("[DART_GetDeviceBuf] : ERROR! _this->hidden = %p\n",
_this->hidden);
} else
- printf("[DART_GetAudioBuf] : ERROR! _this = %p\n", _this);
+ printf("[DART_GetDeviceBuf] : ERROR! _this = %p\n", _this);
return NULL;
}
-void
+static void
DART_WaitDone(_THIS)
{
pMixBufferDesc pBufDesc;
- ULONG ulPostCount;
- APIRET rc;
+ ULONG ulPostCount = 0;
+ APIRET rc = NO_ERROR;
- pBufDesc =
- (pMixBufferDesc) _this->hidden->pMixBuffers[_this->hidden->
- iLastPlayedBuf].
- ulUserParm;
- rc = NO_ERROR;
+ pBufDesc = (pMixBufferDesc)
+ _this->hidden->pMixBuffers[_this->hidden->iLastPlayedBuf].ulUserParm;
+
while ((pBufDesc->iBufferUsage != BUFFER_EMPTY) && (rc == NO_ERROR)) {
DosResetEventSem(_this->hidden->hevAudioBufferPlayed, &ulPostCount);
rc = DosWaitEventSem(_this->hidden->hevAudioBufferPlayed, 1000); // 1 sec timeout! Important!
}
}
-void
-DART_CloseAudio(_THIS)
+static void
+DART_CloseDevice(_THIS)
{
MCI_GENERIC_PARMS GenericParms;
int rc;
+ int i;
- // Stop DART playback
- rc = mciSendCommand(_this->hidden->iCurrDeviceOrd, MCI_STOP, MCI_WAIT,
- &GenericParms, 0);
- if (rc != MCIERR_SUCCESS) {
+ if (_this->hidden != NULL) {
+ // Stop DART playback
+ if (_this->hidden->iCurrDeviceOrd) {
+ rc = mciSendCommand(_this->hidden->iCurrDeviceOrd, MCI_STOP,
+ MCI_WAIT, &GenericParms, 0);
#ifdef SFX_DEBUG_BUILD
- printf("Could not stop DART playback!\n");
- fflush(stdout);
+ if (rc != MCIERR_SUCCESS) {
+ printf("Could not stop DART playback!\n");
+ fflush(stdout);
+ }
#endif
- }
- // Close event semaphore
- DosCloseEventSem(_this->hidden->hevAudioBufferPlayed);
+ }
- // Free memory of buffer descriptions
- {
- int i;
- for (i = 0; i < _this->hidden->iCurrNumBufs; i++)
- SDL_free((void *) (_this->hidden->pMixBuffers[i].ulUserParm));
- }
+ // Close event semaphore
+ if (_this->hidden->hevAudioBufferPlayed) {
+ DosCloseEventSem(_this->hidden->hevAudioBufferPlayed);
+ _this->hidden->hevAudioBufferPlayed = 0;
+ }
- // Deallocate buffers
- rc = mciSendCommand(_this->hidden->iCurrDeviceOrd, MCI_BUFFER,
- MCI_WAIT | MCI_DEALLOCATE_MEMORY,
- &(_this->hidden->BufferParms), 0);
+ // Free memory of buffer descriptions
+ for (i = 0; i < _this->hidden->iCurrNumBufs; i++) {
+ SDL_free((void *) (_this->hidden->pMixBuffers[i].ulUserParm));
+ _this->hidden->pMixBuffers[i].ulUserParm = 0;
+ }
+ _this->hidden->iCurrNumBufs = 0;
- // Free bufferlist
- SDL_free(_this->hidden->pMixBuffers);
- _this->hidden->pMixBuffers = NULL;
+ // Deallocate buffers
+ if (_this->hidden->iCurrDeviceOrd) {
+ rc = mciSendCommand(_this->hidden->iCurrDeviceOrd, MCI_BUFFER,
+ MCI_WAIT | MCI_DEALLOCATE_MEMORY,
+ &(_this->hidden->BufferParms), 0);
+ }
- // Close dart
- rc = mciSendCommand(_this->hidden->iCurrDeviceOrd, MCI_CLOSE, MCI_WAIT,
- &(GenericParms), 0);
-}
+ // Free bufferlist
+ if (_this->hidden->pMixBuffers != NULL) {
+ SDL_free(_this->hidden->pMixBuffers);
+ _this->hidden->pMixBuffers = NULL;
+ }
-/* Audio driver bootstrap functions */
+ // Close dart
+ if (_this->hidden->iCurrDeviceOrd) {
+ rc = mciSendCommand(_this->hidden->iCurrDeviceOrd, MCI_CLOSE,
+ MCI_WAIT, &(GenericParms), 0);
+ }
+ _this->hidden->iCurrDeviceOrd = 0;
-int
-Audio_Available(void)
-{
- return (1);
+ SDL_free(_this->hidden);
+ _this->hidden = NULL;
+ }
}
-void
-Audio_DeleteDevice(SDL_AudioDevice * device)
+
+static int
+DART_Init(SDL_AudioDriverImpl *impl)
{
- SDL_free(device->hidden);
- SDL_free(device);
+ /* Set the function pointers */
+ impl->OpenDevice = DART_OpenDevice;
+ impl->ThreadInit = DART_ThreadInit;
+ impl->WaitDevice = DART_WaitDevice;
+ impl->GetDeviceBuf = DART_GetDeviceBuf;
+ impl->PlayDevice = DART_PlayDevice;
+ impl->WaitDone = DART_WaitDone;
+ impl->CloseDevice = DART_CloseDevice;
+ impl->OnlyHasDefaultOutputDevice = 1; /* !!! FIXME: is this right? */
+
+ return 1;
}
-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));
-
- /* Set the function pointers */
- this->OpenAudio = DART_OpenAudio;
- this->ThreadInit = DART_ThreadInit;
- this->WaitAudio = DART_WaitAudio;
- this->PlayAudio = DART_PlayAudio;
- this->GetAudioBuf = DART_GetAudioBuf;
- this->WaitDone = DART_WaitDone;
- this->CloseAudio = DART_CloseAudio;
-
- this->free = Audio_DeleteDevice;
-
- return this;
-}
AudioBootStrap DART_bootstrap = {
- "dart", "OS/2 Direct Audio RouTines (DART)",
- Audio_Available, Audio_CreateDevice
+ "dart", "OS/2 Direct Audio RouTines (DART)", DART_Init, 0
};
/* vi: set ts=4 sw=4 expandtab: */
--- a/src/audio/dart/SDL_dart.h Sun Oct 01 16:10:41 2006 +0000
+++ b/src/audio/dart/SDL_dart.h Tue Oct 17 09:15:21 2006 +0000
@@ -21,14 +21,15 @@
*/
#include "SDL_config.h"
-#ifndef _SDL_lowaudio_h
-#define _SDL_lowaudio_h
+#ifndef _SDL_dart_h
+#define _SDL_dart_h
#define INCL_TYPES
#define INCL_DOSSEMAPHORES
#define INCL_DOSRESOURCES
#define INCL_DOSMISC
#define INCL_DOSERRORS
+#define INCL_DOSPROCESS
#define INCL_OS2MM
#define INCL_MMIOOS2
@@ -60,5 +61,6 @@
HEV hevAudioBufferPlayed; // Event semaphore to indicate that an audio buffer has been played by DART
};
-#endif /* _SDL_lowaudio_h */
+#endif /* _SDL_dart_h */
+
/* vi: set ts=4 sw=4 expandtab: */
--- a/src/audio/dc/SDL_dcaudio.c Sun Oct 01 16:10:41 2006 +0000
+++ b/src/audio/dc/SDL_dcaudio.c Tue Oct 17 09:15:21 2006 +0000
@@ -28,85 +28,11 @@
#include "SDL_audio.h"
#include "../SDL_audiomem.h"
#include "../SDL_audio_c.h"
-#include "../SDL_audiodev_c.h"
#include "SDL_dcaudio.h"
#include "aica.h"
#include <dc/spu.h>
-/* Audio driver functions */
-static int DCAUD_OpenAudio(_THIS, SDL_AudioSpec * spec);
-static void DCAUD_WaitAudio(_THIS);
-static void DCAUD_PlayAudio(_THIS);
-static Uint8 *DCAUD_GetAudioBuf(_THIS);
-static void DCAUD_CloseAudio(_THIS);
-
-/* Audio driver bootstrap functions */
-static int
-DCAUD_Available(void)
-{
- return 1;
-}
-
-static void
-DCAUD_DeleteDevice(SDL_AudioDevice * device)
-{
- SDL_free(device->hidden);
- SDL_free(device);
-}
-
-static SDL_AudioDevice *
-DCAUD_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));
-
- /* Set the function pointers */
- this->OpenAudio = DCAUD_OpenAudio;
- this->WaitAudio = DCAUD_WaitAudio;
- this->PlayAudio = DCAUD_PlayAudio;
- this->GetAudioBuf = DCAUD_GetAudioBuf;
- this->CloseAudio = DCAUD_CloseAudio;
-
- this->free = DCAUD_DeleteDevice;
-
- spu_init();
-
- return this;
-}
-
-AudioBootStrap DCAUD_bootstrap = {
- "dcaudio", "Dreamcast AICA audio",
- DCAUD_Available, DCAUD_CreateDevice
-};
-
-/* This function waits until it is possible to write a full sound buffer */
-static void
-DCAUD_WaitAudio(_THIS)
-{
- if (this->hidden->playing) {
- /* wait */
- while (aica_get_pos(0) / this->spec.samples == this->hidden->nextbuf) {
- thd_pass();
- }
- }
-}
-
#define SPU_RAM_BASE 0xa0800000
static void
@@ -152,7 +78,7 @@
}
static void
-DCAUD_PlayAudio(_THIS)
+DCAUD_PlayDevice(_THIS)
{
SDL_AudioSpec *spec = &this->spec;
unsigned int offset;
@@ -200,28 +126,59 @@
}
static Uint8 *
-DCAUD_GetAudioBuf(_THIS)
+DCAUD_GetDeviceBuf(_THIS)
{
return (this->hidden->mixbuf);
}
+/* This function waits until it is possible to write a full sound buffer */
static void
-DCAUD_CloseAudio(_THIS)
+DCAUD_WaitDevice(_THIS)
{
- aica_stop(0);
- if (this->spec.channels == 2)
- aica_stop(1);
- if (this->hidden->mixbuf != NULL) {
- SDL_FreeAudioMem(this->hidden->mixbuf);
- this->hidden->mixbuf = NULL;
+ if (this->hidden->playing) {
+ /* wait */
+ while (aica_get_pos(0) / this->spec.samples == this->hidden->nextbuf) {
+ thd_pass();
+ }
+ }
+}
+
+static void
+DCAUD_CloseDevice(_THIS)
+{
+ if (this->hidden != NULL) {
+ aica_stop(0);
+ if (this->spec.channels == 2) {
+ aica_stop(1);
+ }
+ if (this->hidden->mixbuf != NULL) {
+ SDL_FreeAudioMem(this->hidden->mixbuf);
+ this->hidden->mixbuf = NULL;
+ }
+ SDL_free(this->hidden);
+ this->hidden = NULL;
+
+ /* !!! FIXME: is there a reverse of spu_init()? */
}
}
static int
-DCAUD_OpenAudio(_THIS, SDL_AudioSpec * spec)
+DCAUD_OpenDevice(_THIS, SDL_AudioSpec * spec)
{
SDL_AudioFormat test_format = SDL_FirstAudioFormat(spec->format);
int valid_datatype = 0;
+
+ /* Initialize all variables that we clean on shutdown */
+ this->hidden = (struct SDL_PrivateAudioData *)
+ SDL_malloc((sizeof *this->hidden));
+ if (this->hidden == NULL) {
+ SDL_OutOfMemory();
+ return 0;
+ }
+ SDL_memset(this->hidden, 0, (sizeof *this->hidden));
+
+ spu_init();
+
while ((!valid_datatype) && (test_format)) {
spec->format = test_format;
switch (test_format) {
@@ -238,8 +195,9 @@
}
if (!valid_datatype) { /* shouldn't happen, but just in case... */
+ DCAUD_CloseDevice(this);
SDL_SetError("Unsupported audio format");
- return (-1);
+ return 0;
}
if (spec->channels > 2)
@@ -252,7 +210,9 @@
this->hidden->mixlen = spec->size;
this->hidden->mixbuf = (Uint8 *) SDL_AllocAudioMem(this->hidden->mixlen);
if (this->hidden->mixbuf == NULL) {
- return (-1);
+ DCAUD_CloseDevice(this);
+ SDL_OutOfMemory();
+ return 0;
}
SDL_memset(this->hidden->mixbuf, spec->silence, spec->size);
this->hidden->leftpos = 0x11000;
@@ -261,7 +221,25 @@
this->hidden->nextbuf = 0;
/* We're ready to rock and roll. :-) */
- return (0);
+ return 1;
}
+static int
+DCAUD_Init(SDL_AudioDriverImpl *impl)
+{
+ /* Set the function pointers */
+ impl->OpenDevice = DCAUD_OpenDevice;
+ impl->PlayDevice = DCAUD_PlayDevice;
+ impl->WaitDevice = DCAUD_WaitDevice;
+ impl->GetDeviceBuf = DCAUD_GetDeviceBuf;
+ impl->CloseDevice = DCAUD_CloseDevice;
+ impl->OnlyHasDefaultOutputDevice = 1;
+
+ return 1;
+}
+
+AudioBootStrap DCAUD_bootstrap = {
+ "dcaudio", "Dreamcast AICA audio", DCAUD_Init, 0
+};
+
/* vi: set ts=4 sw=4 expandtab: */
--- a/src/audio/dc/SDL_dcaudio.h Sun Oct 01 16:10:41 2006 +0000
+++ b/src/audio/dc/SDL_dcaudio.h Tue Oct 17 09:15:21 2006 +0000
@@ -26,7 +26,7 @@
#include "../SDL_sysaudio.h"
-/* Hidden "this" pointer for the video functions */
+/* Hidden "this" pointer for the audio functions */
#define _THIS SDL_AudioDevice *this
struct SDL_PrivateAudioData
--- a/src/audio/disk/SDL_diskaudio.c Sun Oct 01 16:10:41 2006 +0000
+++ b/src/audio/disk/SDL_diskaudio.c Tue Oct 17 09:15:21 2006 +0000
@@ -34,7 +34,6 @@
#include "SDL_audio.h"
#include "../SDL_audiomem.h"
#include "../SDL_audio_c.h"
-#include "../SDL_audiodev_c.h"
#include "SDL_diskaudio.h"
/* The tag name used by DISK audio */
@@ -46,90 +45,27 @@
#define DISKENVR_WRITEDELAY "SDL_DISKAUDIODELAY"
#define DISKDEFAULT_WRITEDELAY 150
-/* Audio driver functions */
-static int DISKAUD_OpenAudio(_THIS, SDL_AudioSpec * spec);
-static void DISKAUD_WaitAudio(_THIS);
-static void DISKAUD_PlayAudio(_THIS);
-static Uint8 *DISKAUD_GetAudioBuf(_THIS);
-static void DISKAUD_CloseAudio(_THIS);
-
static const char *
-DISKAUD_GetOutputFilename(void)
-{
- const char *envr = SDL_getenv(DISKENVR_OUTFILE);
- return ((envr != NULL) ? envr : DISKDEFAULT_OUTFILE);
-}
-
-/* Audio driver bootstrap functions */
-static int
-DISKAUD_Available(void)
-{
- const char *envr = SDL_getenv("SDL_AUDIODRIVER");
- if (envr && (SDL_strcmp(envr, DISKAUD_DRIVER_NAME) == 0)) {
- return (1);
- }
- return (0);
-}
-
-static void
-DISKAUD_DeleteDevice(SDL_AudioDevice * device)
-{
- SDL_free(device->hidden);
- SDL_free(device);
-}
-
-static SDL_AudioDevice *
-DISKAUD_CreateDevice(int devindex)
+DISKAUD_GetOutputFilename(const char *devname)
{
- SDL_AudioDevice *this;
- const char *envr;
-
- /* 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);
+ if (devname == NULL) {
+ devname = SDL_getenv(DISKENVR_OUTFILE);
+ if (devname == NULL) {
+ devname = DISKDEFAULT_OUTFILE;
}
- return (0);
}
- SDL_memset(this->hidden, 0, (sizeof *this->hidden));
-
- envr = SDL_getenv(DISKENVR_WRITEDELAY);
- this->hidden->write_delay =
- (envr) ? SDL_atoi(envr) : DISKDEFAULT_WRITEDELAY;
-
- /* Set the function pointers */
- this->OpenAudio = DISKAUD_OpenAudio;
- this->WaitAudio = DISKAUD_WaitAudio;
- this->PlayAudio = DISKAUD_PlayAudio;
- this->GetAudioBuf = DISKAUD_GetAudioBuf;
- this->CloseAudio = DISKAUD_CloseAudio;
-
- this->free = DISKAUD_DeleteDevice;
-
- return this;
+ return devname;
}
-AudioBootStrap DISKAUD_bootstrap = {
- DISKAUD_DRIVER_NAME, "direct-to-disk audio",
- DISKAUD_Available, DISKAUD_CreateDevice
-};
-
/* This function waits until it is possible to write a full sound buffer */
static void
-DISKAUD_WaitAudio(_THIS)
+DISKAUD_WaitDevice(_THIS)
{
SDL_Delay(this->hidden->write_delay);
}
static void
-DISKAUD_PlayAudio(_THIS)
+DISKAUD_PlayDevice(_THIS)
{
int written;
@@ -147,49 +83,86 @@
}
static Uint8 *
-DISKAUD_GetAudioBuf(_THIS)
+DISKAUD_GetDeviceBuf(_THIS)
{
return (this->hidden->mixbuf);
}
static void
-DISKAUD_CloseAudio(_THIS)
+DISKAUD_CloseDevice(_THIS)
{
- if (this->hidden->mixbuf != NULL) {
- SDL_FreeAudioMem(this->hidden->mixbuf);
- this->hidden->mixbuf = NULL;
- }
- if (this->hidden->output != NULL) {
- SDL_RWclose(this->hidden->output);
- this->hidden->output = NULL;
+ if (this->hidden != NULL) {
+ if (this->hidden->mixbuf != NULL) {
+ SDL_FreeAudioMem(this->hidden->mixbuf);
+ this->hidden->mixbuf = NULL;
+ }
+ if (this->hidden->output != NULL) {
+ SDL_RWclose(this->hidden->output);
+ this->hidden->output = NULL;
+ }
+ SDL_free(this->hidden);
+ this->hidden = NULL;
}
}
static int
-DISKAUD_OpenAudio(_THIS, SDL_AudioSpec * spec)
+DISKAUD_OpenDevice(_THIS, const char *devname, int iscapture)
{
- const char *fname = DISKAUD_GetOutputFilename();
+ const char *envr = SDL_getenv(DISKENVR_WRITEDELAY);
+ const char *fname = DISKAUD_GetOutputFilename(devname);
+
+ this->hidden = (struct SDL_PrivateAudioData *)
+ SDL_malloc(sizeof (*this->hidden));
+ if (this->hidden == NULL) {
+ SDL_OutOfMemory();
+ return 0;
+ }
+ SDL_memset(this->hidden, 0, sizeof (*this->hidden));
/* Open the audio device */
this->hidden->output = SDL_RWFromFile(fname, "wb");
if (this->hidden->output == NULL) {
- return (-1);
+ DISKAUD_CloseDevice(this);
+ return 0;
}
-#if HAVE_STDIO_H
- fprintf(stderr, "WARNING: You are using the SDL disk writer"
- " audio driver!\n Writing to file [%s].\n", fname);
-#endif
/* Allocate mixing buffer */
- this->hidden->mixlen = spec->size;
this->hidden->mixbuf = (Uint8 *) SDL_AllocAudioMem(this->hidden->mixlen);
if (this->hidden->mixbuf == NULL) {
- return (-1);
+ DISKAUD_CloseDevice(this);
+ return 0;
}
- SDL_memset(this->hidden->mixbuf, spec->silence, spec->size);
+ SDL_memset(this->hidden->mixbuf, this->spec.silence, this->spec.size);
+
+ this->hidden->mixlen = this->spec.size;
+ this->hidden->write_delay =
+ (envr) ? SDL_atoi(envr) : DISKDEFAULT_WRITEDELAY;
+
+#if HAVE_STDIO_H
+ fprintf(stderr,
+ "WARNING: You are using the SDL disk writer audio driver!\n"
+ " Writing to file [%s].\n", fname);
+#endif
/* We're ready to rock and roll. :-) */
- return (0);
+ return 1;
}
+static int
+DISKAUD_Init(SDL_AudioDriverImpl *impl)
+{
+ /* Set the function pointers */
+ impl->OpenDevice = DISKAUD_OpenDevice;
+ impl->WaitDevice = DISKAUD_WaitDevice;
+ impl->PlayDevice = DISKAUD_PlayDevice;
+ impl->GetDeviceBuf = DISKAUD_GetDeviceBuf;
+ impl->CloseDevice = DISKAUD_CloseDevice;
+
+ return 1;
+}
+
+AudioBootStrap DISKAUD_bootstrap = {
+ DISKAUD_DRIVER_NAME, "direct-to-disk audio", DISKAUD_Init, 1
+};
+
/* vi: set ts=4 sw=4 expandtab: */
--- a/src/audio/disk/SDL_diskaudio.h Sun Oct 01 16:10:41 2006 +0000
+++ b/src/audio/disk/SDL_diskaudio.h Tue Oct 17 09:15:21 2006 +0000
@@ -27,7 +27,7 @@
#include "SDL_rwops.h"
#include "../SDL_sysaudio.h"
-/* Hidden "this" pointer for the video functions */
+/* Hidden "this" pointer for the audio functions */
#define _THIS SDL_AudioDevice *this
struct SDL_PrivateAudioData
--- a/src/audio/dma/SDL_dmaaudio.c Sun Oct 01 16:10:41 2006 +0000
+++ b/src/audio/dma/SDL_dmaaudio.c Tue Oct 17 09:15:21 2006 +0000
@@ -21,6 +21,8 @@
*/
#include "SDL_config.h"
+/* !!! FIXME: merge this driver with "dsp". */
+
/* Allow access to a raw mixing buffer */
#include <stdio.h>
@@ -57,89 +59,353 @@
#define DMA_DRIVER_NAME "dma"
/* Open the audio device for playback, and don't block if busy */
-#define OPEN_FLAGS (O_RDWR|O_NONBLOCK)
+#define OPEN_FLAGS_INPUT (O_RDWR|O_NONBLOCK)
+#define OPEN_FLAGS_OUTPUT (O_RDWR|O_NONBLOCK)
+
+static char **outputDevices = NULL;
+static int outputDeviceCount = 0;
+static char **inputDevices = NULL;
+static int inputDeviceCount = 0;
+
+static int
+test_for_mmap(int fd)
+{
+ int caps = 0;
+ struct audio_buf_info info;
+ if ((ioctl(fd, SNDCTL_DSP_GETCAPS, &caps) == 0) &&
+ (caps & DSP_CAP_TRIGGER) && (caps & DSP_CAP_MMAP) &&
+ (ioctl(fd, SNDCTL_DSP_GETOSPACE, &info) == 0))
+ {
+ size_t len = info.fragstotal * info.fragsize;
+ Uint8 *buf = (Uint8 *) mmap(NULL, len, PROT_WRITE, MAP_SHARED, fd, 0);
+ if (buf != MAP_FAILED) {
+ munmap(buf, len);
+ return 1;
+ }
+ }
+ return 0;
+}
+
-/* Audio driver functions */
-static int DMA_OpenAudio(_THIS, SDL_AudioSpec * spec);
-static void DMA_WaitAudio(_THIS);
-static void DMA_PlayAudio(_THIS);
-static Uint8 *DMA_GetAudioBuf(_THIS);
-static void DMA_CloseAudio(_THIS);
+static inline void
+free_device_list(char ***devs, int *count)
+{
+ SDL_FreeUnixAudioDevices(devs, count);
+}
+
+static inline void
+build_device_list(int iscapture, char ***devs, int *count)
+{
+ const int flags = ((iscapture) ? OPEN_FLAGS_INPUT : OPEN_FLAGS_OUTPUT);
+ free_device_list(devs, count);
+ SDL_EnumUnixAudioDevices(flags, 0, test_for_mmap, devs, count);
+}
-/* Audio driver bootstrap functions */
+static inline void
+build_device_lists(void)
+{
+ build_device_list(0, &outputDevices, &outputDeviceCount);
+ build_device_list(1, &inputDevices, &inputDeviceCount);
+}
+
+
+static inline void
+free_device_lists(void)
+{
+ free_device_list(&outputDevices, &outputDeviceCount);
+ free_device_list(&inputDevices, &inputDeviceCount);
+}
+
+
+static void DMA_Deinitialize(void)
+{
+ free_device_lists();
+}
static int
-Audio_Available(void)
+DMA_DetectDevices(int iscapture)
+{
+ if (iscapture) {
+ build_device_list(1, &inputDevices, &inputDeviceCount);
+ return inputDeviceCount;
+ } else {
+ build_device_list(0, &outputDevices, &outputDeviceCount);
+ return outputDeviceCount;
+ }
+
+ return 0; /* shouldn't ever hit this. */
+}
+
+
+static const char *
+DMA_GetDeviceName(int index, int iscapture)
{
- int available;
- int fd;
+ if ((iscapture) && (index < inputDeviceCount)) {
+ return inputDevices[index];
+ } else if ((!iscapture) && (index < outputDeviceCount)) {
+ return outputDevices[index];
+ }
+
+ SDL_SetError("No such device");
+ return NULL;
+}
+
- available = 0;
+static int
+DMA_ReopenAudio(_THIS, const char *audiodev, int format, int stereo)
+{
+ int frag_spec;
+ int value;
+
+ /* Close and then reopen the audio device */
+ close(audio_fd);
+ audio_fd = open(audiodev, O_RDWR, 0);
+ if (audio_fd < 0) {
+ SDL_SetError("Couldn't open %s: %s", audiodev, strerror(errno));
+ return (-1);
+ }
- fd = SDL_OpenAudioPath(NULL, 0, OPEN_FLAGS, 0);
- if (fd >= 0) {
- int caps;
- struct audio_buf_info info;
+ /* Calculate the final parameters for this audio specification */
+ SDL_CalculateAudioSpec(&this->spec);
+
+ /* Determine the power of two of the fragment size */
+ for (frag_spec = 0; (0x01 << frag_spec) < this->spec.size; ++frag_spec);
+ if ((0x01 << frag_spec) != this->spec.size) {
+ SDL_SetError("Fragment size must be a power of two");
+ return (-1);
+ }
+
+ /* Set the audio buffering parameters */
+ if (ioctl(audio_fd, SNDCTL_DSP_SETFRAGMENT, &frag_spec) < 0) {
+ SDL_SetError("Couldn't set audio fragment spec");
+ return (-1);
+ }
- if ((ioctl(fd, SNDCTL_DSP_GETCAPS, &caps) == 0) &&
- (caps & DSP_CAP_TRIGGER) && (caps & DSP_CAP_MMAP) &&
- (ioctl(fd, SNDCTL_DSP_GETOSPACE, &info) == 0)) {
- available = 1;
- }
- close(fd);
+ /* Set the audio format */
+ value = format;
+ if ((ioctl(audio_fd, SNDCTL_DSP_SETFMT, &value) < 0) || (value != format)) {
+ SDL_SetError("Couldn't set audio format");
+ return (-1);
+ }
+
+ /* Set mono or stereo audio */
+ value = (this->spec.channels > 1);
+ if ((ioctl(audio_fd, SNDCTL_DSP_STEREO, &stereo) < 0) ||
+ (value != stereo)) {
+ SDL_SetError("Couldn't set audio channels");
+ return (-1);
}
- return (available);
+
+ /* Set the DSP frequency */
+ value = this->spec.freq;
+ if (ioctl(audio_fd, SNDCTL_DSP_SPEED, &value) < 0) {
+ SDL_SetError("Couldn't set audio frequency");
+ return (-1);
+ }
+ this->spec.freq = value;
+
+ /* We successfully re-opened the audio */
+ return (0);
}
+
static void
-Audio_DeleteDevice(SDL_AudioDevice * device)
+DMA_CloseDevice(_THIS)
{
- SDL_free(device->hidden);
- SDL_free(device);
+ if (this->hidden != NULL) {
+ if (dma_buf != NULL) {
+ munmap(dma_buf, dma_len);
+ dma_buf = NULL;
+ }
+ if (audio_fd >= 0) {
+ close(audio_fd);
+ audio_fd = -1;
+ }
+ SDL_free(this->hidden);
+ this->hidden = NULL;
+ }
}
-static SDL_AudioDevice *
-Audio_CreateDevice(int devindex)
+
+static int
+DMA_OpenDevice(_THIS, const char *devname, int iscapture)
{
- SDL_AudioDevice *this;
+ const int flags = ((iscapture) ? OPEN_FLAGS_INPUT : OPEN_FLAGS_OUTPUT);
+ int format;
+ int stereo;
+ int value;
+ SDL_AudioFormat test_format;
+ struct audio_buf_info info;
+
+ /* We don't care what the devname is...we'll try to open anything. */
+ /* ...but default to first name in the list... */
+ if (devname == NULL) {
+ if ( ((iscapture) && (inputDeviceCount == 0)) ||
+ ((!iscapture) && (outputDeviceCount == 0)) ) {
+ SDL_SetError("No such audio device");
+ return 0;
+ }
+ devname = ((iscapture) ? inputDevices[0] : outputDevices[0]);
+ }
/* 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)) {
+ this->hidden = (struct SDL_PrivateAudioData *)
+ SDL_malloc((sizeof *this->hidden));
+ if (this->hidden == NULL) {
SDL_OutOfMemory();
- if (this) {
- SDL_free(this);
- }
- return (0);
+ return 0;
}
SDL_memset(this->hidden, 0, (sizeof *this->hidden));
- audio_fd = -1;
+
+ /* Open the audio device */
+ audio_fd = open(devname, flags, 0);
+ if (audio_fd < 0) {
+ DMA_CloseDevice(this);
+ SDL_SetError("Couldn't open %s: %s", devname, strerror(errno));
+ return 0;
+ }
+ dma_buf = NULL;
+ ioctl(audio_fd, SNDCTL_DSP_RESET, 0);
+
+ /* Get a list of supported hardware formats */
+ if (ioctl(audio_fd, SNDCTL_DSP_GETFMTS, &value) < 0) {
+ DMA_CloseDevice(this);
+ SDL_SetError("Couldn't get audio format list");
+ return 0;
+ }
+
+ /* Try for a closest match on audio format */
+ format = 0;
+ for (test_format = SDL_FirstAudioFormat(this->spec.format);
+ !format && test_format;) {
+#ifdef DEBUG_AUDIO
+ fprintf(stderr, "Trying format 0x%4.4x\n", test_format);
+#endif
+ switch (test_format) {
+ case AUDIO_U8:
+ if (value & AFMT_U8) {
+ format = AFMT_U8;
+ }
+ break;
+ case AUDIO_S8:
+ if (value & AFMT_S8) {
+ format = AFMT_S8;
+ }
+ break;
+ case AUDIO_S16LSB:
+ if (value & AFMT_S16_LE) {
+ format = AFMT_S16_LE;
+ }
+ break;
+ case AUDIO_S16MSB:
+ if (value & AFMT_S16_BE) {
+ format = AFMT_S16_BE;
+ }
+ break;
+ case AUDIO_U16LSB:
+ if (value & AFMT_U16_LE) {
+ format = AFMT_U16_LE;
+ }
+ break;
+ case AUDIO_U16MSB:
+ if (value & AFMT_U16_BE) {
+ format = AFMT_U16_BE;
+ }
+ break;
+ default:
+ format = 0;
+ break;
+ }
+ if (!format) {
+ test_format = SDL_NextAudioFormat();
+ }
+ }
+ if (format == 0) {
+ DMA_CloseDevice(this);
+ SDL_SetError("Couldn't find any hardware audio formats");
+ return 0;
+ }
+ this->spec.format = test_format;
- /* Set the function pointers */
- this->OpenAudio = DMA_OpenAudio;
- this->WaitAudio = DMA_WaitAudio;
- this->PlayAudio = DMA_PlayAudio;
- this->GetAudioBuf = DMA_GetAudioBuf;
- this->CloseAudio = DMA_CloseAudio;
+ /* Set the audio format */
+ value = format;
+ if ((ioctl(audio_fd, SNDCTL_DSP_SETFMT, &value) < 0) || (value != format)) {
+ DMA_CloseDevice(this);
+ SDL_SetError("Couldn't set audio format");
+ return 0;
+ }
+
+ /* Set mono or stereo audio (currently only two channels supported) */
+ stereo = (this->spec.channels > 1);
+ ioctl(audio_fd, SNDCTL_DSP_STEREO, &stereo);
+ if (stereo) {
+ this->spec.channels = 2;
+ } else {
+ this->spec.channels = 1;
+ }
+
+ /* Because some drivers don't allow setting the buffer size
+ after setting the format, we must re-open the audio device
+ once we know what format and channels are supported
+ */
+ if (DMA_ReopenAudio(this, devname, format, stereo) < 0) {
+ DMA_CloseDevice(this);
+ /* Error is set by DMA_ReopenAudio() */
+ return 0;
+ }
- this->free = Audio_DeleteDevice;
+ /* Memory map the audio buffer */
+ if (ioctl(audio_fd, SNDCTL_DSP_GETOSPACE, &info) < 0) {
+ DMA_CloseDevice(this);
+ SDL_SetError("Couldn't get OSPACE parameters");
+ return 0;
+ }
+ this->spec.size = info.fragsize;
+ this->spec.samples = this->spec.size / ((this->spec.format & 0xFF) / 8);
+ this->spec.samples /= this->spec.channels;
+ num_buffers = info.fragstotal;
+ dma_len = num_buffers * this->spec.size;
+ dma_buf = (Uint8 *) mmap(NULL, dma_len, PROT_WRITE, MAP_SHARED,
+ audio_fd, 0);
+ if (dma_buf == MAP_FAILED) {
+ DMA_CloseDevice(this);
+ SDL_SetError("DMA memory map failed");
+ dma_buf = NULL;
+ return 0;
+ }
+ SDL_memset(dma_buf, this->spec.silence, dma_len);
- return this;
+ /* Check to see if we need to use select() workaround */
+ {
+ char *workaround;
+ workaround = SDL_getenv("SDL_DSP_NOSELECT");
+ if (workaround) {
+ frame_ticks = (float) (this->spec.samples*1000) / this->spec.freq;
+ next_frame = SDL_GetTicks() + frame_ticks;
+ }
+ }
+
+ /* Trigger audio playback */
+ value = 0;
+ ioctl(audio_fd, SNDCTL_DSP_SETTRIGGER, &value);
+ value = PCM_ENABLE_OUTPUT;
+ if (ioctl(audio_fd, SNDCTL_DSP_SETTRIGGER, &value) < 0) {
+ DMA_CloseDevice(this);
+ SDL_SetError("Couldn't trigger audio output");
+ return 0;
+ }
+
+ /* Get the parent process id (we're the parent of the audio thread) */
+ parent = getpid();
+
+ /* We're ready to rock and roll. :-) */
+ return 1;
}
-AudioBootStrap DMA_bootstrap = {
- DMA_DRIVER_NAME, "OSS /dev/dsp DMA audio",
- Audio_Available, Audio_CreateDevice
-};
/* This function waits until it is possible to write a full sound buffer */
static void
-DMA_WaitAudio(_THIS)
+DMA_WaitDevice(_THIS)
{
fd_set fdset;
@@ -189,8 +455,8 @@
fprintf(stderr, "SDL: %s\n", message);
#ifdef AUDIO_OSPACE_HACK
/* We may be able to use GET_OSPACE trick */
- frame_ticks = (float) (this->spec->samples * 1000) /
- this->spec->freq;
+ frame_ticks = (float) (this->spec.samples * 1000) /
+ this->spec.freq;
next_frame = SDL_GetTicks() + frame_ticks;
#else
this->enabled = 0;
@@ -208,7 +474,7 @@
}
static void
-DMA_PlayAudio(_THIS)
+DMA_PlayDevice(_THIS)
{
/* If timer synchronization is enabled, set the next write frame */
if (frame_ticks) {
@@ -218,7 +484,7 @@
}
static Uint8 *
-DMA_GetAudioBuf(_THIS)
+DMA_GetDeviceBuf(_THIS)
{
count_info info;
int playing;
@@ -243,225 +509,26 @@
return (dma_buf + (filling * this->spec.size));
}
-static void
-DMA_CloseAudio(_THIS)
-{
- if (dma_buf != NULL) {
- munmap(dma_buf, dma_len);
- dma_buf = NULL;
- }
- if (audio_fd >= 0) {
- close(audio_fd);
- audio_fd = -1;
- }
-}
-
-static int
-DMA_ReopenAudio(_THIS, const char *audiodev, int format, int stereo,
- SDL_AudioSpec * spec)
-{
- int frag_spec;
- int value;
-
- /* Close and then reopen the audio device */
- close(audio_fd);
- audio_fd = open(audiodev, O_RDWR, 0);
- if (audio_fd < 0) {
- SDL_SetError("Couldn't open %s: %s", audiodev, strerror(errno));
- return (-1);
- }
-
- /* Calculate the final parameters for this audio specification */
- SDL_CalculateAudioSpec(spec);
-
- /* Determine the power of two of the fragment size */
- for (frag_spec = 0; (0x01 << frag_spec) < spec->size; ++frag_spec);
- if ((0x01 << frag_spec) != spec->size) {
- SDL_SetError("Fragment size must be a power of two");
- return (-1);
- }
-
- /* Set the audio buffering parameters */
- if (ioctl(audio_fd, SNDCTL_DSP_SETFRAGMENT, &frag_spec) < 0) {
- SDL_SetError("Couldn't set audio fragment spec");
- return (-1);
- }
-
- /* Set the audio format */
- value = format;
- if ((ioctl(audio_fd, SNDCTL_DSP_SETFMT, &value) < 0) || (value != format)) {
- SDL_SetError("Couldn't set audio format");
- return (-1);
- }
-
- /* Set mono or stereo audio */
- value = (spec->channels > 1);
- if ((ioctl(audio_fd, SNDCTL_DSP_STEREO, &stereo) < 0) ||
- (value != stereo)) {
- SDL_SetError("Couldn't set audio channels");
- return (-1);
- }
-
- /* Set the DSP frequency */
- value = spec->freq;
- if (ioctl(audio_fd, SNDCTL_DSP_SPEED, &value) < 0) {
- SDL_SetError("Couldn't set audio frequency");
- return (-1);
- }
- spec->freq = value;
-
- /* We successfully re-opened the audio */
- return (0);
-}
static int
-DMA_OpenAudio(_THIS, SDL_AudioSpec * spec)
+DMA_Init(SDL_AudioDriverImpl *impl)
{
- char audiodev[1024];
- int format;
- int stereo;
- int value;
- SDL_AudioFormat test_format;
- struct audio_buf_info info;
-
- /* Reset the timer synchronization flag */
- frame_ticks = 0.0;
-
- /* 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);
- }
- dma_buf = NULL;
- ioctl(audio_fd, SNDCTL_DSP_RESET, 0);
-
- /* Get a list of supported hardware formats */
- if (ioctl(audio_fd, SNDCTL_DSP_GETFMTS, &value) < 0) {
- SDL_SetError("Couldn't get audio format list");
- return (-1);
- }
+ /* Set the function pointers */
+ impl->DetectDevices = DMA_DetectDevices;
+ impl->GetDeviceName = DMA_GetDeviceName;
+ impl->OpenDevice = DMA_OpenDevice;
+ impl->WaitDevice = DMA_WaitDevice;
+ impl->PlayDevice = DMA_PlayDevice;
+ impl->GetDeviceBuf = DMA_GetDeviceBuf;
+ impl->CloseDevice = DMA_CloseDevice;
+ impl->Deinitialize = DMA_Deinitialize;
- /* Try for a closest match on audio format */
- format = 0;
- for (test_format = SDL_FirstAudioFormat(spec->format);
- !format && test_format;) {
-#ifdef DEBUG_AUDIO
- fprintf(stderr, "Trying format 0x%4.4x\n", test_format);
-#endif
- switch (test_format) {
- case AUDIO_U8:
- if (value & AFMT_U8) {
- format = AFMT_U8;
- }
- break;
- case AUDIO_S8:
- if (value & AFMT_S8) {
- format = AFMT_S8;
- }
- break;
- case AUDIO_S16LSB:
- if (value & AFMT_S16_LE) {
- format = AFMT_S16_LE;
- }
- break;
- case AUDIO_S16MSB:
- if (value & AFMT_S16_BE) {
- format = AFMT_S16_BE;
- }
- break;
- case AUDIO_U16LSB:
- if (value & AFMT_U16_LE) {
- format = AFMT_U16_LE;
- }
- break;
- case AUDIO_U16MSB:
- if (value & AFMT_U16_BE) {
- format = AFMT_U16_BE;
- }
- break;
- default:
- format = 0;
- break;
- }
- if (!format) {
- test_format = SDL_NextAudioFormat();
- }
- }
- if (format == 0) {
- SDL_SetError("Couldn't find any hardware audio formats");
- return (-1);
- }
- spec->format = test_format;
-
- /* Set the audio format */
- value = format;
- if ((ioctl(audio_fd, SNDCTL_DSP_SETFMT, &value) < 0) || (value != format)) {
- SDL_SetError("Couldn't set audio format");
- return (-1);
- }
-
- /* Set mono or stereo audio (currently only two channels supported) */
- stereo = (spec->channels > 1);
- ioctl(audio_fd, SNDCTL_DSP_STEREO, &stereo);
- if (stereo) {
- spec->channels = 2;
- } else {
- spec->channels = 1;
- }
-
- /* Because some drivers don't allow setting the buffer size
- after setting the format, we must re-open the audio device
- once we know what format and channels are supported
- */
- if (DMA_ReopenAudio(this, audiodev, format, stereo, spec) < 0) {
- /* Error is set by DMA_ReopenAudio() */
- return (-1);
- }
-
- /* Memory map the audio buffer */
- if (ioctl(audio_fd, SNDCTL_DSP_GETOSPACE, &info) < 0) {
- SDL_SetError("Couldn't get OSPACE parameters");
- return (-1);
- }
- spec->size = info.fragsize;
- spec->samples = spec->size / ((spec->format & 0xFF) / 8);
- spec->samples /= spec->channels;
- num_buffers = info.fragstotal;
- dma_len = num_buffers * spec->size;
- dma_buf = (Uint8 *) mmap(NULL, dma_len, PROT_WRITE, MAP_SHARED,
- audio_fd, 0);
- if (dma_buf == MAP_FAILED) {
- SDL_SetError("DMA memory map failed");
- dma_buf = NULL;
- return (-1);
- }
- SDL_memset(dma_buf, spec->silence, dma_len);
-
- /* Check to see if we need to use select() workaround */
- {
- char *workaround;
- workaround = SDL_getenv("SDL_DSP_NOSELECT");
- if (workaround) {
- frame_ticks = (float) (spec->samples * 1000) / spec->freq;
- next_frame = SDL_GetTicks() + frame_ticks;
- }
- }
-
- /* Trigger audio playback */
- value = 0;
- ioctl(audio_fd, SNDCTL_DSP_SETTRIGGER, &value);
- value = PCM_ENABLE_OUTPUT;
- if (ioctl(audio_fd, SNDCTL_DSP_SETTRIGGER, &value) < 0) {
- SDL_SetError("Couldn't trigger audio output");
- return (-1);
- }
-
- /* Get the parent process id (we're the parent of the audio thread) */
- parent = getpid();
-
- /* We're ready to rock and roll. :-) */
- return (0);
+ build_device_lists();
+ return 1;
}
+AudioBootStrap DMA_bootstrap = {
+ DMA_DRIVER_NAME, "OSS /dev/dsp DMA audio", DMA_Init, 0
+};
+
/* vi: set ts=4 sw=4 expandtab: */
--- a/src/audio/dma/SDL_dmaaudio.h Sun Oct 01 16:10:41 2006 +0000
+++ b/src/audio/dma/SDL_dmaaudio.h Tue Oct 17 09:15:21 2006 +0000
@@ -21,12 +21,12 @@
*/
#include "SDL_config.h"
-#ifndef _SDL_dspaudio_h
-#define _SDL_dspaudio_h
+#ifndef _SDL_dmaaudio_h
+#define _SDL_dmaaudio_h
#include "../SDL_sysaudio.h"
-/* Hidden "this" pointer for the video functions */
+/* Hidden "this" pointer for the audio functions */
#define _THIS SDL_AudioDevice *this
struct SDL_PrivateAudioData
@@ -49,6 +49,7 @@
#define FUDGE_TICKS 10 /* The scheduler overhead ticks per frame */
/* Old variable names */
+/* !!! FIXME: remove these. */
#define audio_fd (this->hidden->audio_fd)
#define parent (this->hidden->parent)
#define dma_buf (this->hidden->dma_buf)
@@ -57,5 +58,6 @@
#define frame_ticks (this->hidden->frame_ticks)
#define next_frame (this->hidden->next_frame)
-#endif /* _SDL_dspaudio_h */
+#endif /* _SDL_dmaaudio_h */
+
/* vi: set ts=4 sw=4 expandtab: */
--- a/src/audio/dmedia/SDL_irixaudio.c Sun Oct 01 16:10:41 2006 +0000
+++ b/src/audio/dmedia/SDL_irixaudio.c Tue Oct 17 09:15:21 2006 +0000
@@ -45,73 +45,12 @@
#define alSetWidth(x,y) ALsetwidth(x,y)
#endif
-/* Audio driver functions */
-static int AL_OpenAudio(_THIS, SDL_AudioSpec * spec);
-static void AL_WaitAudio(_THIS);
-static void AL_PlayAudio(_THIS);
-static Uint8 *AL_GetAudioBuf(_THIS);
-static void AL_CloseAudio(_THIS);
-
-/* Audio driver bootstrap functions */
-
-static int
-Audio_Available(void)
-{
- return 1;
-}
-
-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));
-
- /* Set the function pointers */
- this->OpenAudio = AL_OpenAudio;
- this->WaitAudio = AL_WaitAudio;
- this->PlayAudio = AL_PlayAudio;
- this->GetAudioBuf = AL_GetAudioBuf;
- this->CloseAudio = AL_CloseAudio;
-
- this->free = Audio_DeleteDevice;
-
- return this;
-}
-
-AudioBootStrap DMEDIA_bootstrap = {
- "AL", "IRIX DMedia audio",
- Audio_Available, Audio_CreateDevice
-};
-
-
void static
-AL_WaitAudio(_THIS)
+IRIXAUDIO_WaitDevice(_THIS)
{
Sint32 timeleft;
- timeleft = this->spec.samples - alGetFillable(audio_port);
+ timeleft = this->spec.samples - alGetFillable(this->hidden->audio_port);
if (timeleft > 0) {
timeleft /= (this->spec.freq / 1000);
SDL_Delay((Uint32) timeleft);
@@ -119,61 +58,78 @@
}
static void
-AL_PlayAudio(_THIS)
+IRIXAUDIO_PlayDevice(_THIS)
{
/* Write the audio data out */
- if (alWriteFrames(audio_port, mixbuf, this->spec.samples) < 0) {
+ ALport port = this->hidden->audio_port;
+ Uint8 *mixbuf = this->hidden->mixbuf;
+ if (alWriteFrames(port, mixbuf, this->spec.samples) < 0) {
/* Assume fatal error, for now */
this->enabled = 0;
}
}
static Uint8 *
-AL_GetAudioBuf(_THIS)
+IRIXAUDIO_GetDeviceBuf(_THIS)
{
- return (mixbuf);
+ return (this->hidden->mixbuf);
}
static void
-AL_CloseAudio(_THIS)
+IRIXAUDIO_CloseDevice(_THIS)
{
- if (mixbuf != NULL) {
- SDL_FreeAudioMem(mixbuf);
- mixbuf = NULL;
- }
- if (audio_port != NULL) {
- alClosePort(audio_port);
- audio_port = NULL;
+ if (this->hidden != NULL) {
+ if (this->hidden->mixbuf != NULL) {
+ SDL_FreeAudioMem(this->hidden->mixbuf);
+ this->hidden->mixbuf = NULL;
+ }
+ if (this->hidden->audio_port != NULL) {
+ alClosePort(this->hidden->audio_port);
+ this->hidden->audio_port = NULL;
+ }
+ SDL_free(this->hidden);
+ this->hidden = NULL;
}
}
static int
-AL_OpenAudio(_THIS, SDL_AudioSpec * spec)
+IRIXAUDIO_OpenDevice(_THIS, const char *devname, int iscapture)
{
- SDL_AudioFormat test_format = SDL_FirstAudioFormat(spec->format);
+ SDL_AudioFormat test_format = SDL_FirstAudioFormat(this->spec.format);
long width = 0;
long fmt = 0;
int valid = 0;
+ /* !!! FIXME: Handle multiple devices and capture? */
+
+ /* Initialize all variables that we clean on shutdown */
+ this->hidden = (struct SDL_PrivateAudioData *)
+ SDL_malloc((sizeof *this->hidden));
+ if (this->hidden == NULL) {
+ SDL_OutOfMemory();
+ return 0;
+ }
+ SDL_memset(this->hidden, 0, (sizeof *this->hidden));
+
#ifdef OLD_IRIX_AUDIO
{
long audio_param[2];
audio_param[0] = AL_OUTPUT_RATE;
- audio_param[1] = spec->freq;
+ audio_param[1] = this->spec.freq;
valid = (ALsetparams(AL_DEFAULT_DEVICE, audio_param, 2) < 0);
}
#else
{
ALpv audio_param;
audio_param.param = AL_RATE;
- audio_param.value.i = spec->freq;
+ audio_param.value.i = this->spec.freq;
valid = (alSetParams(AL_DEFAULT_OUTPUT, &audio_param, 1) < 0);
}
#endif
while ((!valid) && (test_format)) {
valid = 1;
- spec->format = test_format;
+ this->spec.format = test_format;
switch (test_format) {
case AUDIO_S8:
@@ -203,30 +159,31 @@
ALconfig audio_config = alNewConfig();
valid = 0;
if (audio_config) {
- if (alSetChannels(audio_config, spec->channels) < 0) {
- if (spec->channels > 2) { /* can't handle > stereo? */
- spec->channels = 2; /* try again below. */
+ if (alSetChannels(audio_config, this->spec.channels) < 0) {
+ if (this->spec.channels > 2) { /* can't handle > stereo? */
+ this->spec.channels = 2; /* try again below. */
}
}
if ((alSetSampFmt(audio_config, fmt) >= 0) &&
((!width) || (alSetWidth(audio_config, width) >= 0)) &&
- (alSetQueueSize(audio_config, spec->samples * 2) >= 0) &&
- (alSetChannels(audio_config, spec->channels) >= 0)) {
+ (alSetQueueSize(audio_config,this->spec.samples*2) >= 0) &&
+ (alSetChannels(audio_config, this->spec.channels) >= 0)) {
- audio_port = alOpenPort("SDL audio", "w", audio_config);
- if (audio_port == NULL) {
+ this->hidden->audio_port = alOpenPort("SDL audio", "w",
+ audio_config);
+ if (this->hidden->audio_port == NULL) {
/* docs say AL_BAD_CHANNELS happens here, too. */
int err = oserror();
if (err == AL_BAD_CHANNELS) {
- spec->channels = 2;
- alSetChannels(audio_config, spec->channels);
- audio_port = alOpenPort("SDL audio", "w",
- audio_config);
+ this->spec.channels = 2;
+ alSetChannels(audio_config, this->spec.channels);
+ this->hidden->audio_port = alOpenPort("SDL audio", "w",
+ audio_config);
}
}
- if (audio_port != NULL) {
+ if (this->hidden->audio_port != NULL) {
valid = 1;
}
}
@@ -237,23 +194,43 @@
}
if (!valid) {
+ IRIXAUDIO_CloseDevice(this);
SDL_SetError("Unsupported audio format");
- return (-1);
+ return 0;
}
/* Update the fragment size as size in bytes */
- SDL_CalculateAudioSpec(spec);
+ SDL_CalculateAudioSpec(&this->spec);
/* Allocate mixing buffer */
- mixbuf = (Uint8 *) SDL_AllocAudioMem(spec->size);
- if (mixbuf == NULL) {
+ this->hidden->mixbuf = (Uint8 *) SDL_AllocAudioMem(this->spec.size);
+ if (this->hidden->mixbuf == NULL) {
+ IRIXAUDIO_CloseDevice(this);
SDL_OutOfMemory();
- return (-1);
+ return 0;
}
- SDL_memset(mixbuf, spec->silence, spec->size);
+ SDL_memset(this->hidden->mixbuf, this->spec.silence, this->spec.size);
/* We're ready to rock and roll. :-) */
- return (0);
+ return 1;
}
+static int
+IRIXAUDIO_Init(SDL_AudioDriverImpl *impl)
+{
+ /* Set the function pointers */
+ impl->OpenDevice = DSP_OpenDevice;
+ impl->PlayDevice = DSP_PlayDevice;
+ impl->WaitDevice = DSP_WaitDevice;
+ impl->GetDeviceBuf = DSP_GetDeviceBuf;
+ impl->CloseDevice = DSP_CloseDevice;
+ impl->OnlyHasDefaultOutputDevice = 1; /* !!! FIXME: not true, I think. */
+
+ return 1;
+}
+
+AudioBootStrap IRIXAUDIO_bootstrap = {
+ "AL", "IRIX DMedia audio", IRIXAUDIO_Init, 0
+};
+
/* vi: set ts=4 sw=4 expandtab: */
--- a/src/audio/dmedia/SDL_irixaudio.h Sun Oct 01 16:10:41 2006 +0000
+++ b/src/audio/dmedia/SDL_irixaudio.h Tue Oct 17 09:15:21 2006 +0000
@@ -21,8 +21,8 @@
*/
#include "SDL_config.h"
-#ifndef _SDL_lowaudio_h
-#define _SDL_lowaudio_h
+#ifndef _SDL_irixaudio_h
+#define _SDL_irixaudio_h
#include <dmedia/audio.h>
@@ -33,15 +33,10 @@
struct SDL_PrivateAudioData
{
- /* The handle for the audio device */
- ALport audio_port;
-
- Uint8 *mixbuf; /* The app mixing buffer */
+ ALport audio_port; /* The handle for the audio device */
+ Uint8 *mixbuf; /* The app mixing buffer */
};
-/* Old variable names */
-#define audio_port (this->hidden->audio_port)
-#define mixbuf (this->hidden->mixbuf)
+#endif /* _SDL_irixaudio_h */
-#endif /* _SDL_lowaudio_h */
/* vi: set ts=4 sw=4 expandtab: */
--- a/src/audio/dsp/SDL_dspaudio.c Sun Oct 01 16:10:41 2006 +0000
+++ b/src/audio/dsp/SDL_dspaudio.c Tue Oct 17 09:15:21 2006 +0000
@@ -55,156 +55,158 @@
#define DSP_DRIVER_NAME "dsp"
/* Open the audio device for playback, and don't block if busy */
-#define OPEN_FLAGS (O_WRONLY|O_NONBLOCK)
-
-/* Audio driver functions */
-static int DSP_OpenAudio(_THIS, SDL_AudioSpec * spec);
-static void DSP_WaitAudio(_THIS);
-static void DSP_PlayAudio(_THIS);
-static Uint8 *DSP_GetAudioBuf(_THIS);
-static void DSP_CloseAudio(_THIS);
-
-/* Audio driver bootstrap functions */
+#define OPEN_FLAGS_OUTPUT (O_WRONLY|O_NONBLOCK)
+#define OPEN_FLAGS_INPUT (O_RDONLY|O_NONBLOCK)
-static int
-Audio_Available(void)
-{
- int fd;
- int available;
+static char **outputDevices = NULL;
+static int outputDeviceCount = 0;
+static char **inputDevices = NULL;
+static int inputDeviceCount = 0;
- available = 0;
- fd = SDL_OpenAudioPath(NULL, 0, OPEN_FLAGS, 0);
- if (fd >= 0) {
- available = 1;
- close(fd);
- }
- return (available);
+static inline void
+free_device_list(char ***devs, int *count)
+{
+ SDL_FreeUnixAudioDevices(devs, count);
}
-static void
-Audio_DeleteDevice(SDL_AudioDevice * device)
+static inline void
+build_device_list(int iscapture, char ***devs, int *count)
+{
+ const int flags = ((iscapture) ? OPEN_FLAGS_INPUT : OPEN_FLAGS_OUTPUT);
+ free_device_list(devs, count);
+ SDL_EnumUnixAudioDevices(flags, 0, NULL, devs, count);
+}
+
+static inline void
+build_device_lists(void)
{
- SDL_free(device->hidden);
- SDL_free(device);
+ build_device_list(0, &outputDevices, &outputDeviceCount);
+ build_device_list(1, &inputDevices, &inputDeviceCount);
+}
+
+
+static inline void
+free_device_lists(void)
+{
+ free_device_list(&outputDevices, &outputDeviceCount);
+ free_device_list(&inputDevices, &inputDeviceCount);
+}
+
+
+static void
+DSP_Deinitialize(void)
+{
+ free_device_lists();
}
-static SDL_AudioDevice *
-Audio_CreateDevice(int devindex)
+
+static int
+DSP_DetectDevices(int iscapture)
{
- 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 (iscapture) {
+ build_device_list(1, &inputDevices, &inputDeviceCount);
+ return inputDeviceCount;
+ } else {
+ build_device_list(0, &outputDevices, &outputDeviceCount);
+ return outputDeviceCount;
}
- 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 = DSP_OpenAudio;
- this->WaitAudio = DSP_WaitAudio;
- this->PlayAudio = DSP_PlayAudio;
- this->GetAudioBuf = DSP_GetAudioBuf;
- this->CloseAudio = DSP_CloseAudio;
-
- this->free = Audio_DeleteDevice;
-
- return this;
+ return 0; /* shouldn't ever hit this. */
}
-AudioBootStrap DSP_bootstrap = {
- DSP_DRIVER_NAME, "OSS /dev/dsp standard audio",
- Audio_Available, Audio_CreateDevice
-};
+static const char *
+DSP_GetDeviceName(int index, int iscapture)
+{
+ if ((iscapture) && (index < inputDeviceCount)) {
+ return inputDevices[index];
+ } else if ((!iscapture) && (index < outputDeviceCount)) {
+ return outputDevices[index];
+ }
-/* This function waits until it is possible to write a full sound buffer */
-static void
-DSP_WaitAudio(_THIS)
-{
- /* Not needed at all since OSS handles waiting automagically */
+ SDL_SetError("No such device");
+ return NULL;
}
+
static void
-DSP_PlayAudio(_THIS)
-{
- if (write(audio_fd, mixbuf, mixlen) == -1) {
- perror("Audio write");
- this->enabled = 0;
- }
-#ifdef DEBUG_AUDIO
- fprintf(stderr, "Wrote %d bytes of audio data\n", mixlen);
-#endif
-}
-
-static Uint8 *
-DSP_GetAudioBuf(_THIS)
+DSP_CloseDevice(_THIS)
{
- return (mixbuf);
-}
-
-static void
-DSP_CloseAudio(_THIS)
-{
- if (mixbuf != NULL) {
- SDL_FreeAudioMem(mixbuf);
- mixbuf = NULL;
- }
- if (audio_fd >= 0) {
- close(audio_fd);
- audio_fd = -1;
+ if (this->hidden != NULL) {
+ if (this->hidden->mixbuf != NULL) {
+ SDL_FreeAudioMem(this->hidden->mixbuf);
+ this->hidden->mixbuf = NULL;
+ }
+ if (this->hidden->audio_fd >= 0) {
+ close(this->hidden->audio_fd);
+ this->hidden->audio_fd = -1;
+ }
+ SDL_free(this->hidden);
+ this->hidden = NULL;
}
}
+
static int
-DSP_OpenAudio(_THIS, SDL_AudioSpec * spec)
+DSP_OpenDevice(_THIS, const char *devname, int iscapture)
{
- char audiodev[1024];
+ const int flags = ((iscapture) ? OPEN_FLAGS_INPUT : OPEN_FLAGS_OUTPUT);
int format;
int value;
int frag_spec;
SDL_AudioFormat test_format;
+ /* We don't care what the devname is...we'll try to open anything. */
+ /* ...but default to first name in the list... */
+ if (devname == NULL) {
+ if ( ((iscapture) && (inputDeviceCount == 0)) ||
+ ((!iscapture) && (outputDeviceCount == 0)) ) {
+ SDL_SetError("No such audio device");
+ return 0;
+ }
+ devname = ((iscapture) ? inputDevices[0] : outputDevices[0]);
+ }
+
+ /* Initialize all variables that we clean on shutdown */
+ this->hidden = (struct SDL_PrivateAudioData *)
+ SDL_malloc((sizeof *this->hidden));
+ if (this->hidden == NULL) {
+ SDL_OutOfMemory();
+ return 0;
+ }
+ SDL_memset(this->hidden, 0, (sizeof *this->hidden));
+
/* 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);
+ this->hidden->audio_fd = open(devname, flags, 0);
+ if (this->hidden->audio_fd < 0) {
+ DSP_CloseDevice(this);
+ SDL_SetError("Couldn't open %s: %s", devname, strerror(errno));
+ return 0;
}
- mixbuf = NULL;
+ this->hidden->mixbuf = NULL;
/* Make the file descriptor use blocking writes with fcntl() */
{
- long flags;
- flags = fcntl(audio_fd, F_GETFL);
- flags &= ~O_NONBLOCK;
- if (fcntl(audio_fd, F_SETFL, flags) < 0) {
+ long ctlflags;
+ ctlflags = fcntl(this->hidden->audio_fd, F_GETFL);
+ ctlflags &= ~O_NONBLOCK;
+ if (fcntl(this->hidden->audio_fd, F_SETFL, ctlflags) < 0) {
+ DSP_CloseDevice(this);
SDL_SetError("Couldn't set audio blocking mode");
- DSP_CloseAudio(this);
- return (-1);
+ return 0;
}
}
/* Get a list of supported hardware formats */
- if (ioctl(audio_fd, SNDCTL_DSP_GETFMTS, &value) < 0) {
+ if (ioctl(this->hidden->audio_fd, SNDCTL_DSP_GETFMTS, &value) < 0) {
perror("SNDCTL_DSP_GETFMTS");
+ DSP_CloseDevice(this);
SDL_SetError("Couldn't get audio format list");
- DSP_CloseAudio(this);
- return (-1);
+ return 0;
}
/* Try for a closest match on audio format */
format = 0;
- for (test_format = SDL_FirstAudioFormat(spec->format);
+ for (test_format = SDL_FirstAudioFormat(this->spec.format);
!format && test_format;) {
#ifdef DEBUG_AUDIO
fprintf(stderr, "Trying format 0x%4.4x\n", test_format);
@@ -255,50 +257,51 @@
}
}
if (format == 0) {
+ DSP_CloseDevice(this);
SDL_SetError("Couldn't find any hardware audio formats");
- DSP_CloseAudio(this);
- return (-1);
+ return 0;
}
- spec->format = test_format;
+ this->spec.format = test_format;
/* Set the audio format */
value = format;
- if ((ioctl(audio_fd, SNDCTL_DSP_SETFMT, &value) < 0) || (value != format)) {
+ if ( (ioctl(this->hidden->audio_fd, SNDCTL_DSP_SETFMT, &value) < 0) ||
+ (value != format) ) {
perror("SNDCTL_DSP_SETFMT");
+ DSP_CloseDevice(this);
SDL_SetError("Couldn't set audio format");
- DSP_CloseAudio(this);
- return (-1);
+ return 0;
}
/* Set the number of channels of output */
- value = spec->channels;
- if (ioctl(audio_fd, SNDCTL_DSP_CHANNELS, &value) < 0) {
+ value = this->spec.channels;
+ if (ioctl(this->hidden->audio_fd, SNDCTL_DSP_CHANNELS, &value) < 0) {
perror("SNDCTL_DSP_CHANNELS");
+ DSP_CloseDevice(this);
SDL_SetError("Cannot set the number of channels");
- DSP_CloseAudio(this);
- return (-1);
+ return 0;
}
- spec->channels = value;
+ this->spec.channels = value;
/* Set the DSP frequency */
- value = spec->freq;
- if (ioctl(audio_fd, SNDCTL_DSP_SPEED, &value) < 0) {
+ value = this->spec.freq;
+ if (ioctl(this->hidden->audio_fd, SNDCTL_DSP_SPEED, &value) < 0) {
perror("SNDCTL_DSP_SPEED");
+ DSP_CloseDevice(this);
SDL_SetError("Couldn't set audio frequency");
- DSP_CloseAudio(this);
- return (-1);
+ return 0;
}
- spec->freq = value;
+ this->spec.freq = value;
/* Calculate the final parameters for this audio specification */
- SDL_CalculateAudioSpec(spec);
+ SDL_CalculateAudioSpec(&this->spec);
/* Determine the power of two of the fragment size */
- for (frag_spec = 0; (0x01U << frag_spec) < spec->size; ++frag_spec);
- if ((0x01U << frag_spec) != spec->size) {
+ for (frag_spec = 0; (0x01U << frag_spec) < this->spec.size; ++frag_spec);
+ if ((0x01U << frag_spec) != this->spec.size) {
+ DSP_CloseDevice(this);
SDL_SetError("Fragment size must be a power of two");
- DSP_CloseAudio(this);
- return (-1);
+ return 0;
}
frag_spec |= 0x00020000; /* two fragments, for low latency */
@@ -307,13 +310,13 @@
fprintf(stderr, "Requesting %d fragments of size %d\n",
(frag_spec >> 16), 1 << (frag_spec & 0xFFFF));
#endif
- if (ioctl(audio_fd, SNDCTL_DSP_SETFRAGMENT, &frag_spec) < 0) {
+ if (ioctl(this->hidden->audio_fd, SNDCTL_DSP_SETFRAGMENT, &frag_spec) < 0) {
perror("SNDCTL_DSP_SETFRAGMENT");
}
#ifdef DEBUG_AUDIO
{
audio_buf_info info;
- ioctl(audio_fd, SNDCTL_DSP_GETOSPACE, &info);
+ ioctl(this->hidden->audio_fd, SNDCTL_DSP_GETOSPACE, &info);
fprintf(stderr, "fragments = %d\n", info.fragments);
fprintf(stderr, "fragstotal = %d\n", info.fragstotal);
fprintf(stderr, "fragsize = %d\n", info.fragsize);
@@ -322,19 +325,59 @@
#endif
/* Allocate mixing buffer */
- mixlen = spec->size;
- mixbuf = (Uint8 *) SDL_AllocAudioMem(mixlen);
- if (mixbuf == NULL) {
- DSP_CloseAudio(this);
- return (-1);
+ this->hidden->mixlen = this->spec.size;
+ this->hidden->mixbuf = (Uint8 *) SDL_AllocAudioMem(this->hidden->mixlen);
+ if (this->hidden->mixbuf == NULL) {
+ DSP_CloseDevice(this);
+ SDL_OutOfMemory();
+ return 0;
}
- SDL_memset(mixbuf, spec->silence, spec->size);
-
- /* Get the parent process id (we're the parent of the audio thread) */
- parent = getpid();
+ SDL_memset(this->hidden->mixbuf, this->spec.silence, this->spec.size);
/* We're ready to rock and roll. :-) */
- return (0);
+ return 1;
+}
+
+
+static void
+DSP_PlayDevice(_THIS)
+{
+ const Uint8 *mixbuf = this->hidden->mixbuf;
+ const int mixlen = this->hidden->mixlen;
+ if (write(this->hidden->audio_fd, mixbuf, mixlen) == -1) {
+ perror("Audio write");
+ this->enabled = 0;
+ }
+#ifdef DEBUG_AUDIO
+ fprintf(stderr, "Wrote %d bytes of audio data\n", mixlen);
+#endif
}
+static Uint8 *
+DSP_GetDeviceBuf(_THIS)
+{
+ return (this->hidden->mixbuf);
+}
+
+static int
+DSP_Init(SDL_AudioDriverImpl *impl)
+{
+ /* Set the function pointers */
+ impl->DetectDevices = DSP_DetectDevices;
+ impl->GetDeviceName = DSP_GetDeviceName;
+ impl->OpenDevice = DSP_OpenDevice;
+ impl->PlayDevice = DSP_PlayDevice;
+ impl->GetDeviceBuf = DSP_GetDeviceBuf;
+ impl->CloseDevice = DSP_CloseDevice;
+ impl->Deinitialize = DSP_Deinitialize;
+
+ build_device_lists();
+ return 1;
+}
+
+
+AudioBootStrap DSP_bootstrap = {
+ DSP_DRIVER_NAME, "OSS /dev/dsp standard audio", DSP_Init, 0
+};
+
/* vi: set ts=4 sw=4 expandtab: */
--- a/src/audio/dsp/SDL_dspaudio.h Sun Oct 01 16:10:41 2006 +0000
+++ b/src/audio/dsp/SDL_dspaudio.h Tue Oct 17 09:15:21 2006 +0000
@@ -26,7 +26,7 @@
#include "../SDL_sysaudio.h"
-/* Hidden "this" pointer for the video functions */
+/* Hidden "this" pointer for the audio functions */
#define _THIS SDL_AudioDevice *this
struct SDL_PrivateAudioData
@@ -34,22 +34,11 @@
/* 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;
};
#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_dspaudio_h */
/* vi: set ts=4 sw=4 expandtab: */
--- a/src/audio/dummy/SDL_dummyaudio.c Sun Oct 01 16:10:41 2006 +0000
+++ b/src/audio/dummy/SDL_dummyaudio.c Tue Oct 17 09:15:21 2006 +0000
@@ -25,141 +25,27 @@
/* Output audio to nowhere... */
-#include "SDL_rwops.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_dummyaudio.h"
-/* The tag name used by DUMMY audio */
-#define DUMMYAUD_DRIVER_NAME "dummy"
-
-/* Audio driver functions */
-static int DUMMYAUD_OpenAudio(_THIS, SDL_AudioSpec * spec);
-static void DUMMYAUD_WaitAudio(_THIS);
-static void DUMMYAUD_PlayAudio(_THIS);
-static Uint8 *DUMMYAUD_GetAudioBuf(_THIS);
-static void DUMMYAUD_CloseAudio(_THIS);
-
-/* Audio driver bootstrap functions */
static int
-DUMMYAUD_Available(void)
+DUMMYAUD_OpenDevice(_THIS, const char *devname, int iscapture)
{
- const char *envr = SDL_getenv("SDL_AUDIODRIVER");
- if (envr && (SDL_strcmp(envr, DUMMYAUD_DRIVER_NAME) == 0)) {
- return (1);
- }
- return (0);
+ return 1; /* always succeeds. */
}
-static void
-DUMMYAUD_DeleteDevice(SDL_AudioDevice * device)
-{
- SDL_free(device->hidden);
- SDL_free(device);
-}
-
-static SDL_AudioDevice *
-DUMMYAUD_CreateDevice(int devindex)
+static int
+DUMMYAUD_Init(SDL_AudioDriverImpl *impl)
{
- 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));
-
/* Set the function pointers */
- this->OpenAudio = DUMMYAUD_OpenAudio;
- this->WaitAudio = DUMMYAUD_WaitAudio;
- this->PlayAudio = DUMMYAUD_PlayAudio;
- this->GetAudioBuf = DUMMYAUD_GetAudioBuf;
- this->CloseAudio = DUMMYAUD_CloseAudio;
-
- this->free = DUMMYAUD_DeleteDevice;
-
- return this;
+ impl->OpenDevice = DUMMYAUD_OpenDevice;
+ impl->OnlyHasDefaultOutputDevice = 1;
+ return 1;
}
AudioBootStrap DUMMYAUD_bootstrap = {
- DUMMYAUD_DRIVER_NAME, "SDL dummy audio driver",
- DUMMYAUD_Available, DUMMYAUD_CreateDevice
+ "dummy", "SDL dummy audio driver", DUMMYAUD_Init, 1
};
-/* This function waits until it is possible to write a full sound buffer */
-static void
-DUMMYAUD_WaitAudio(_THIS)
-{
- /* Don't block on first calls to simulate initial fragment filling. */
- if (this->hidden->initial_calls)
- this->hidden->initial_calls--;
- else
- SDL_Delay(this->hidden->write_delay);
-}
-
-static void
-DUMMYAUD_PlayAudio(_THIS)
-{
- /* no-op...this is a null driver. */
-}
-
-static Uint8 *
-DUMMYAUD_GetAudioBuf(_THIS)
-{
- return (this->hidden->mixbuf);
-}
-
-static void
-DUMMYAUD_CloseAudio(_THIS)
-{
- if (this->hidden->mixbuf != NULL) {
- SDL_FreeAudioMem(this->hidden->mixbuf);
- this->hidden->mixbuf = NULL;
- }
-}
-
-static int
-DUMMYAUD_OpenAudio(_THIS, SDL_AudioSpec * spec)
-{
- float bytes_per_sec = 0.0f;
-
- /* Allocate mixing buffer */
- this->hidden->mixlen = spec->size;
- this->hidden->mixbuf = (Uint8 *) SDL_AllocAudioMem(this->hidden->mixlen);
- if (this->hidden->mixbuf == NULL) {
- return (-1);
- }
- SDL_memset(this->hidden->mixbuf, spec->silence, spec->size);
-
- bytes_per_sec = (float) (((spec->format & 0xFF) / 8) *
- spec->channels * spec->freq);
-
- /*
- * We try to make this request more audio at the correct rate for
- * a given audio spec, so timing stays fairly faithful.
- * Also, we have it not block at all for the first two calls, so
- * it seems like we're filling two audio fragments right out of the
- * gate, like other SDL drivers tend to do.
- */
- this->hidden->initial_calls = 2;
- this->hidden->write_delay =
- (Uint32) ((((float) spec->size) / bytes_per_sec) * 1000.0f);
-
- /* We're ready to rock and roll. :-) */
- return (0);
-}
-
/* vi: set ts=4 sw=4 expandtab: */
--- a/src/audio/dummy/SDL_dummyaudio.h Sun Oct 01 16:10:41 2006 +0000
+++ b/src/audio/dummy/SDL_dummyaudio.h Tue Oct 17 09:15:21 2006 +0000
@@ -26,7 +26,7 @@
#include "../SDL_sysaudio.h"
-/* Hidden "this" pointer for the video functions */
+/* Hidden "this" pointer for the audio functions */
#define _THIS SDL_AudioDevice *this
struct SDL_PrivateAudioData
--- a/src/audio/esd/SDL_esdaudio.c Sun Oct 01 16:10:41 2006 +0000
+++ b/src/audio/esd/SDL_esdaudio.c Tue Oct 17 09:15:21 2006 +0000
@@ -33,7 +33,6 @@
#include "SDL_audio.h"
#include "../SDL_audiomem.h"
#include "../SDL_audio_c.h"
-#include "../SDL_audiodev_c.h"
#include "SDL_esdaudio.h"
#ifdef SDL_AUDIO_DRIVER_ESD_DYNAMIC
@@ -46,40 +45,34 @@
/* The tag name used by ESD audio */
#define ESD_DRIVER_NAME "esd"
-/* Audio driver functions */
-static int ESD_OpenAudio(_THIS, SDL_AudioSpec * spec);
-static void ESD_WaitAudio(_THIS);
-static void ESD_PlayAudio(_THIS);
-static Uint8 *ESD_GetAudioBuf(_THIS);
-static void ESD_CloseAudio(_THIS);
-
#ifdef SDL_AUDIO_DRIVER_ESD_DYNAMIC
static const char *esd_library = SDL_AUDIO_DRIVER_ESD_DYNAMIC;
static void *esd_handle = NULL;
-static int esd_loaded = 0;
static int (*SDL_NAME(esd_open_sound)) (const char *host);
static int (*SDL_NAME(esd_close)) (int esd);
static int (*SDL_NAME(esd_play_stream)) (esd_format_t format, int rate,
const char *host, const char *name);
+
+#define SDL_ESD_SYM(x) { #x, (void **) (char *) &SDL_NAME(x) }
static struct
{
const char *name;
void **func;
} esd_functions[] = {
- {
- "esd_open_sound", (void **) &SDL_NAME(esd_open_sound)}, {
- "esd_close", (void **) &SDL_NAME(esd_close)}, {
-"esd_play_stream", (void **) &SDL_NAME(esd_play_stream)},};
+ SDL_ESD_SYM(esd_open_sound),
+ SDL_ESD_SYM(esd_close),
+ SDL_ESD_SYM(esd_play_stream),
+};
+#undef SDL_ESD_SYM
static void
UnloadESDLibrary()
{
- if (esd_loaded) {
+ if (esd_handle != NULL) {
SDL_UnloadObject(esd_handle);
esd_handle = NULL;
- esd_loaded = 0;
}
}
@@ -88,17 +81,18 @@
{
int i, retval = -1;
- esd_handle = SDL_LoadObject(esd_library);
- if (esd_handle) {
- esd_loaded = 1;
- retval = 0;
- for (i = 0; i < SDL_arraysize(esd_functions); ++i) {
- *esd_functions[i].func =
- SDL_LoadFunction(esd_handle, esd_functions[i].name);
- if (!*esd_functions[i].func) {
- retval = -1;
- UnloadESDLibrary();
- break;
+ if (esd_handle == NULL) {
+ esd_handle = SDL_LoadObject(esd_library);
+ if (esd_handle) {
+ retval = 0;
+ for (i = 0; i < SDL_arraysize(esd_functions); ++i) {
+ *esd_functions[i].func =
+ SDL_LoadFunction(esd_handle, esd_functions[i].name);
+ if (!*esd_functions[i].func) {
+ retval = -1;
+ UnloadESDLibrary();
+ break;
+ }
}
}
}
@@ -121,78 +115,10 @@
#endif /* SDL_AUDIO_DRIVER_ESD_DYNAMIC */
-/* Audio driver bootstrap functions */
-
-static int
-Audio_Available(void)
-{
- int connection;
- int available;
-
- available = 0;
- if (LoadESDLibrary() < 0) {
- return available;
- }
- connection = SDL_NAME(esd_open_sound) (NULL);
- if (connection >= 0) {
- available = 1;
- SDL_NAME(esd_close) (connection);
- }
- UnloadESDLibrary();
- return (available);
-}
-
-static void
-Audio_DeleteDevice(SDL_AudioDevice * device)
-{
- SDL_free(device->hidden);
- SDL_free(device);
- UnloadESDLibrary();
-}
-
-static SDL_AudioDevice *
-Audio_CreateDevice(int devindex)
-{
- SDL_AudioDevice *this;
-
- /* Initialize all variables that we clean on shutdown */
- LoadESDLibrary();
- 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 = ESD_OpenAudio;
- this->WaitAudio = ESD_WaitAudio;
- this->PlayAudio = ESD_PlayAudio;
- this->GetAudioBuf = ESD_GetAudioBuf;
- this->CloseAudio = ESD_CloseAudio;
-
- this->free = Audio_DeleteDevice;
-
- return this;
-}
-
-AudioBootStrap ESD_bootstrap = {
- ESD_DRIVER_NAME, "Enlightened Sound Daemon",
- Audio_Available, Audio_CreateDevice
-};
/* This function waits until it is possible to write a full sound buffer */
static void
-ESD_WaitAudio(_THIS)
+ESD_WaitDevice(_THIS)
{
Sint32 ticks;
@@ -202,28 +128,31 @@
/* Note that this only works with thread implementations
that use a different process id for each thread.
*/
- if (parent && (((++cnt) % 10) == 0)) { /* Check every 10 loops */
- if (kill(parent, 0) < 0) {
+ /* Check every 10 loops */
+ if (this->hidden->parent && (((++cnt) % 10) == 0)) {
+ if (kill(this->hidden->parent, 0) < 0) {
this->enabled = 0;
}
}
}
/* Use timer for general audio synchronization */
- ticks = ((Sint32) (next_frame - SDL_GetTicks())) - FUDGE_TICKS;
+ ticks = ((Sint32) (this->hidden->next_frame-SDL_GetTicks())) - FUDGE_TICKS;
if (ticks > 0) {
SDL_Delay(ticks);
}
}
static void
-ESD_PlayAudio(_THIS)
+ESD_PlayDevice(_THIS)
{
- int written;
+ int written = 0;
/* Write the audio data, checking for EAGAIN on broken audio drivers */
do {
- written = write(audio_fd, mixbuf, mixlen);
+ written = write(this->hidden->audio_fd,
+ this->hidden->mixbuf,
+ this->hidden->mixlen);
if ((written < 0) && ((errno == 0) || (errno == EAGAIN))) {
SDL_Delay(1); /* Let a little CPU time go by */
}
@@ -232,7 +161,7 @@
((errno == 0) || (errno == EAGAIN) || (errno == EINTR)));
/* Set the next write frame */
- next_frame += frame_ticks;
+ this->hidden->next_frame += this->hidden->frame_ticks;
/* If we couldn't write, assume fatal error for now */
if (written < 0) {
@@ -241,21 +170,26 @@
}
static Uint8 *
-ESD_GetAudioBuf(_THIS)
+ESD_GetDeviceBuf(_THIS)
{
- return (mixbuf);
+ return (this->hidden->mixbuf);
}
static void
-ESD_CloseAudio(_THIS)
+ESD_CloseDevice(_THIS)
{
- if (mixbuf != NULL) {
- SDL_FreeAudioMem(mixbuf);
- mixbuf = NULL;
- }
- if (audio_fd >= 0) {
- SDL_NAME(esd_close) (audio_fd);
- audio_fd = -1;
+ if (this->hidden != NULL) {
+ if (this->hidden->mixbuf != NULL) {
+ SDL_FreeAudioMem(this->hidden->mixbuf);
+ this->hidden->mixbuf = NULL;
+ }
+ if (this->hidden->audio_fd >= 0) {
+ SDL_NAME(esd_close) (this->hidden->audio_fd);
+ this->hidden->audio_fd = -1;
+ }
+
+ SDL_free(this->hidden);
+ this->hidden = NULL;
}
}
@@ -285,59 +219,135 @@
return (progname);
}
+
static int
-ESD_OpenAudio(_THIS, SDL_AudioSpec * spec)
+ESD_OpenDevice(_THIS, const char *devname, int iscapture)
{
- esd_format_t format;
+ esd_format_t format = (ESD_STREAM | ESD_PLAY);
+ SDL_AudioFormat test_format = 0;
+ int found = 0;
+
+ /* Initialize all variables that we clean on shutdown */
+ this->hidden = (struct SDL_PrivateAudioData *)
+ SDL_malloc((sizeof *this->hidden));
+ if (this->hidden == NULL) {
+ SDL_OutOfMemory();
+ return 0;
+ }
+ SDL_memset(this->hidden, 0, (sizeof *this->hidden));
+ this->hidden->audio_fd = -1;
/* Convert audio spec to the ESD audio format */
- format = (ESD_STREAM | ESD_PLAY);
- switch (spec->format & 0xFF) {
- case 8:
- format |= ESD_BITS8;
- break;
- case 16:
- format |= ESD_BITS16;
- break;
- default:
- SDL_SetError("Unsupported ESD audio format");
- return (-1);
+ /* Try for a closest match on audio format */
+ for (test_format = SDL_FirstAudioFormat(this->spec.format);
+ !found && test_format; test_format = SDL_NextAudioFormat()) {
+#ifdef DEBUG_AUDIO
+ fprintf(stderr, "Trying format 0x%4.4x\n", test_format);
+#endif
+ found = 1;
+ switch (test_format) {
+ case AUDIO_U8:
+ format |= ESD_BITS8;
+ break;
+ case AUDIO_S16SYS:
+ format |= ESD_BITS16;
+ break;
+ default:
+ found = 0;
+ break;
+ }
}
- if (spec->channels == 1) {
+
+ if (!found) {
+ ESD_CloseDevice(this);
+ SDL_SetError("Couldn't find any hardware audio formats");
+ return 0;
+ }
+
+ if (this->spec.channels == 1) {
format |= ESD_MONO;
} else {
format |= ESD_STEREO;
}
#if 0
- spec->samples = ESD_BUF_SIZE; /* Darn, no way to change this yet */
+ this->spec.samples = ESD_BUF_SIZE; /* Darn, no way to change this yet */
#endif
/* Open a connection to the ESD audio server */
- audio_fd =
- SDL_NAME(esd_play_stream) (format, spec->freq, NULL, get_progname());
- if (audio_fd < 0) {
+ this->hidden->audio_fd =
+ SDL_NAME(esd_play_stream)(format,this->spec.freq,NULL,get_progname());
+
+ if (this->hidden->audio_fd < 0) {
+ ESD_CloseDevice(this);
SDL_SetError("Couldn't open ESD connection");
- return (-1);
+ return 0;
}
/* Calculate the final parameters for this audio specification */
- SDL_CalculateAudioSpec(spec);
- frame_ticks = (float) (spec->samples * 1000) / spec->freq;
- next_frame = SDL_GetTicks() + frame_ticks;
+ SDL_CalculateAudioSpec(&this->spec);
+ this->hidden->frame_ticks = (float) (this->spec.samples*1000) / this->spec.freq;
+ this->hidden->next_frame = SDL_GetTicks() + this->hidden->frame_ticks;
/* Allocate mixing buffer */
- mixlen = spec->size;
- mixbuf = (Uint8 *) SDL_AllocAudioMem(mixlen);
- if (mixbuf == NULL) {
- return (-1);
+ this->hidden->mixlen = this->spec.size;
+ this->hidden->mixbuf = (Uint8 *) SDL_AllocAudioMem(this->hidden->mixlen);
+ if (this->hidden->mixbuf == NULL) {
+ ESD_CloseDevice(this);
+ SDL_OutOfMemory();
+ return 0;
}
- SDL_memset(mixbuf, spec->silence, spec->size);
+ SDL_memset(this->hidden->mixbuf, this->spec.silence, this->spec.size);
/* Get the parent process id (we're the parent of the audio thread) */
- parent = getpid();
+ this->hidden->parent = getpid();
/* We're ready to rock and roll. :-) */
- return (0);
+ return 1;
+}
+
+static void
+ESD_Deinitialize(void)
+{
+ UnloadESDLibrary();
}
+static int
+ESD_Init(SDL_AudioDriverImpl *impl)
+{
+ if (LoadESDLibrary() < 0) {
+ return 0;
+ } else {
+ int connection = 0;
+
+ /* Don't start ESD if it's not running */
+ if (SDL_getenv("ESD_NO_SPAWN") == NULL) {
+ SDL_putenv("ESD_NO_SPAWN=1");
+ }
+
+ connection = SDL_NAME(esd_open_sound) (NULL);
+ if (connection < 0) {
+ UnloadESDLibrary();
+ SDL_SetError("ESD: esd_open_sound failed (no audio server?)");
+ return 0;
+ }
+ SDL_NAME(esd_close) (connection);
+ }
+
+ /* Set the function pointers */
+ impl->OpenDevice = ESD_OpenDevice;
+ impl->PlayDevice = ESD_PlayDevice;
+ impl->WaitDevice = ESD_WaitDevice;
+ impl->GetDeviceBuf = ESD_GetDeviceBuf;
+ impl->CloseDevice = ESD_CloseDevice;
+ impl->Deinitialize = ESD_Deinitialize;
+ impl->OnlyHasDefaultOutputDevice = 1;
+
+ return 1;
+}
+
+
+AudioBootStrap ESD_bootstrap = {
+ ESD_DRIVER_NAME, "Enlightened Sound Daemon", ESD_Init, 0
+};
+
/* vi: set ts=4 sw=4 expandtab: */
--- a/src/audio/esd/SDL_esdaudio.h Sun Oct 01 16:10:41 2006 +0000
+++ b/src/audio/esd/SDL_esdaudio.h Tue Oct 17 09:15:21 2006 +0000
@@ -26,7 +26,7 @@
#include "../SDL_sysaudio.h"
-/* Hidden "this" pointer for the video functions */
+/* Hidden "this" pointer for the audio functions */
#define _THIS SDL_AudioDevice *this
struct SDL_PrivateAudioData
@@ -47,13 +47,5 @@
};
#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_esdaudio_h */
/* vi: set ts=4 sw=4 expandtab: */
--- a/src/audio/macosx/SDL_coreaudio.c Sun Oct 01 16:10:41 2006 +0000
+++ b/src/audio/macosx/SDL_coreaudio.c Tue Oct 17 09:15:21 2006 +0000
@@ -21,6 +21,7 @@
*/
#include "SDL_config.h"
+#include <CoreAudio/CoreAudio.h>
#include <AudioUnit/AudioUnit.h>
#include "SDL_audio.h"
@@ -28,79 +29,233 @@
#include "../SDL_sysaudio.h"
#include "SDL_coreaudio.h"
-
-/* Audio driver functions */
+#define DEBUG_COREAUDIO 0
-static int Core_OpenAudio(_THIS, SDL_AudioSpec * spec);
-static void Core_WaitAudio(_THIS);
-static void Core_PlayAudio(_THIS);
-static Uint8 *Core_GetAudioBuf(_THIS);
-static void Core_CloseAudio(_THIS);
+typedef struct COREAUDIO_DeviceList
+{
+ AudioDeviceID id;
+ const char *name;
+} COREAUDIO_DeviceList;
-/* Audio driver bootstrap functions */
-
-static int
-Audio_Available(void)
-{
- return (1);
-}
+static COREAUDIO_DeviceList *inputDevices = NULL;
+static int inputDeviceCount = 0;
+static COREAUDIO_DeviceList *outputDevices = NULL;
+static int outputDeviceCount = 0;
static void
-Audio_DeleteDevice(SDL_AudioDevice * device)
+free_device_list(COREAUDIO_DeviceList **devices, int *devCount)
{
- SDL_free(device->hidden);
- SDL_free(device);
+ if (*devices) {
+ int i = *devCount;
+ while (i--)
+ SDL_free((void *) (*devices)[i].name);
+ SDL_free(*devices);
+ *devices = NULL;
+ }
+ *devCount = 0;
}
-static SDL_AudioDevice *
-Audio_CreateDevice(int devindex)
+
+static void
+build_device_list(int iscapture, COREAUDIO_DeviceList **devices, int *devCount)
{
- SDL_AudioDevice *this;
+ Boolean outWritable = 0;
+ OSStatus result = noErr;
+ UInt32 size = 0;
+ AudioDeviceID *devs = NULL;
+ UInt32 i = 0;
+ UInt32 max = 0;
+
+ free_device_list(devices, devCount);
+
+ result = AudioHardwareGetPropertyInfo(kAudioHardwarePropertyDevices,
+ &size, &outWritable);
+
+ if (result != kAudioHardwareNoError)
+ return;
+
+ devs = (AudioDeviceID *) alloca(size);
+ if (devs == NULL)
+ return;
+
+ max = size / sizeof (AudioDeviceID);
+ *devices = (COREAUDIO_DeviceList *) SDL_malloc(max * sizeof (**devices));
+ if (*devices == NULL)
+ return;
+
+ result = AudioHardwareGetProperty(kAudioHardwarePropertyDevices,
+ &size, devs);
+ if (result != kAudioHardwareNoError)
+ return;
+
+ for (i = 0; i < max; i++) {
+ CFStringRef cfstr = NULL;
+ char *ptr = NULL;
+ AudioDeviceID dev = devs[i];
+ AudioBufferList *buflist = NULL;
+ int usable = 0;
+ CFIndex len = 0;
+
+ result = AudioDeviceGetPropertyInfo(dev, 0, iscapture,
+ kAudioDevicePropertyStreamConfiguration,
+ &size, &outWritable);
+ if (result != noErr)
+ continue;
+
+ buflist = (AudioBufferList *) SDL_malloc(size);
+ if (buflist == NULL)
+ continue;
+
+ result = AudioDeviceGetProperty(dev, 0, iscapture,
+ kAudioDevicePropertyStreamConfiguration,
+ &size, buflist);
- /* 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 (result == noErr) {
+ UInt32 j;
+ for (j = 0; j < buflist->mNumberBuffers; j++) {
+ if (buflist->mBuffers[j].mNumberChannels > 0) {
+ usable = 1;
+ break;
+ }
+ }
+ }
+
+ SDL_free(buflist);
+
+ if (!usable)
+ continue;
+
+ size = sizeof (CFStringRef);
+ result = AudioDeviceGetProperty(dev, 0, iscapture,
+ kAudioObjectPropertyName,
+ &size, &cfstr);
+
+ if (result != kAudioHardwareNoError)
+ continue;
+
+ len = CFStringGetMaximumSizeForEncoding(CFStringGetLength(cfstr),
+ kCFStringEncodingUTF8);
+
+ ptr = (char *) SDL_malloc(len + 1);
+ usable = ( (ptr != NULL) &&
+ (CFStringGetCString(cfstr,ptr,len+1,kCFStringEncodingUTF8)) );
+
+ CFRelease(cfstr);
+
+ if (usable) {
+ len = strlen(ptr);
+ /* Some devices have whitespace at the end...trim it. */
+ while ((len > 0) && (ptr[len-1] == ' ')) {
+ len--;
+ }
+ usable = (len > 0);
+ }
+
+ if (!usable) {
+ SDL_free(ptr);
+ } else {
+ ptr[len] = '\0';
+
+ #if DEBUG_COREAUDIO
+ printf("COREAUDIO: Found %s device #%d: '%s' (devid %d)\n",
+ ((iscapture) ? "capture" : "output"),
+ (int) *devCount, ptr, (int) dev);
+ #endif
+
+ (*devices)[*devCount].id = dev;
+ (*devices)[*devCount].name = ptr;
+ (*devCount)++;
+ }
}
- if ((this == NULL) || (this->hidden == NULL)) {
- SDL_OutOfMemory();
- if (this) {
- SDL_free(this);
- }
- return (0);
- }
- SDL_memset(this->hidden, 0, (sizeof *this->hidden));
-
- /* Set the function pointers */
- this->OpenAudio = Core_OpenAudio;
- this->WaitAudio = Core_WaitAudio;
- this->PlayAudio = Core_PlayAudio;
- this->GetAudioBuf = Core_GetAudioBuf;
- this->CloseAudio = Core_CloseAudio;
-
- this->free = Audio_DeleteDevice;
-
- return this;
}
-AudioBootStrap COREAUDIO_bootstrap = {
- "coreaudio", "Mac OS X CoreAudio",
- Audio_Available, Audio_CreateDevice
-};
+static inline void
+build_device_lists(void)
+{
+ build_device_list(0, &outputDevices, &outputDeviceCount);
+ build_device_list(1, &inputDevices, &inputDeviceCount);
+}
+
+
+static inline void
+free_device_lists(void)
+{
+ free_device_list(&outputDevices, &outputDeviceCount);
+ free_device_list(&inputDevices, &inputDeviceCount);
+}
+
+
+static int
+find_device_id(const char *devname, int iscapture, AudioDeviceID *id)
+{
+ int i = ((iscapture) ? inputDeviceCount : outputDeviceCount);
+ COREAUDIO_DeviceList *devs = ((iscapture) ? inputDevices : outputDevices);
+ while (i--) {
+ if (SDL_strcmp(devname, devs->name) == 0) {
+ *id = devs->id;
+ return 1;
+ }
+ devs++;
+ }
+
+ return 0;
+}
+
+
+static int
+COREAUDIO_DetectDevices(int iscapture)
+{
+ if (iscapture) {
+ build_device_list(1, &inputDevices, &inputDeviceCount);
+ return inputDeviceCount;
+ } else {
+ build_device_list(0, &outputDevices, &outputDeviceCount);
+ return outputDeviceCount;
+ }
+
+ return 0; /* shouldn't ever hit this. */
+}
+
+
+static const char *
+COREAUDIO_GetDeviceName(int index, int iscapture)
+{
+ if ((iscapture) && (index < inputDeviceCount)) {
+ return inputDevices[index].name;
+ } else if ((!iscapture) && (index < outputDeviceCount)) {
+ return outputDevices[index].name;
+ }
+
+ SDL_SetError("No such device");
+ return NULL;
+}
+
+
+static void
+COREAUDIO_Deinitialize(void)
+{
+ free_device_lists();
+}
+
/* The CoreAudio callback */
static OSStatus
-audioCallback(void *inRefCon,
- AudioUnitRenderActionFlags inActionFlags,
+outputCallback(void *inRefCon,
+ AudioUnitRenderActionFlags *ioActionFlags,
const AudioTimeStamp * inTimeStamp,
- UInt32 inBusNumber, AudioBuffer * ioData)
+ UInt32 inBusNumber, UInt32 inNumberFrames,
+ AudioBufferList *ioDataList)
{
SDL_AudioDevice *this = (SDL_AudioDevice *) inRefCon;
+ AudioBuffer *ioData = &ioDataList->mBuffers[0];
UInt32 remaining, len;
void *ptr;
+ /* Is there ever more than one buffer, and what do you do with it? */
+ if (ioDataList->mNumberBuffers != 1) {
+ return noErr;
+ }
+
/* Only do anything if audio is enabled and not paused */
if (!this->enabled || this->paused) {
SDL_memset(ioData->mData, this->spec.silence, ioData->mDataByteSize);
@@ -118,109 +273,251 @@
remaining = ioData->mDataByteSize;
ptr = ioData->mData;
while (remaining > 0) {
- if (bufferOffset >= bufferSize) {
+ if (this->hidden->bufferOffset >= this->hidden->bufferSize) {
/* Generate the data */
- SDL_memset(buffer, this->spec.silence, bufferSize);
+ SDL_memset(this->hidden->buffer, this->spec.silence,
+ this->hidden->bufferSize);
SDL_mutexP(this->mixer_lock);
- (*this->spec.callback) (this->spec.userdata, buffer, bufferSize);
+ (*this->spec.callback) (this->spec.userdata, this->hidden->buffer,
+ this->hidden->bufferSize);
SDL_mutexV(this->mixer_lock);
- bufferOffset = 0;
+ this->hidden->bufferOffset = 0;
}
- len = bufferSize - bufferOffset;
+ len = this->hidden->bufferSize - this->hidden->bufferOffset;
if (len > remaining)
len = remaining;
- SDL_memcpy(ptr, (char *) buffer + bufferOffset, len);
+ SDL_memcpy(ptr,
+ (char *) this->hidden->buffer + this->hidden->bufferOffset,
+ len);
ptr = (char *) ptr + len;
remaining -= len;
- bufferOffset += len;
+ this->hidden->bufferOffset += len;
}
return 0;
}
-/* Dummy functions -- we don't use thread-based audio */
-void
-Core_WaitAudio(_THIS)
+static OSStatus
+inputCallback(void *inRefCon,
+ AudioUnitRenderActionFlags *ioActionFlags,
+ const AudioTimeStamp * inTimeStamp,
+ UInt32 inBusNumber, UInt32 inNumberFrames,
+ AudioBufferList *ioData)
{
- return;
-}
-
-void
-Core_PlayAudio(_THIS)
-{
- return;
-}
-
-Uint8 *
-Core_GetAudioBuf(_THIS)
-{
- return (NULL);
+ //err = AudioUnitRender(afr->fAudioUnit, ioActionFlags, inTimeStamp, inBusNumber, inNumberFrames, afr->fAudioBuffer);
+ // !!! FIXME: write me!
+ return noErr;
}
-void
-Core_CloseAudio(_THIS)
+
+static void
+COREAUDIO_CloseDevice(_THIS)
{
- OSStatus result;
- struct AudioUnitInputCallback callback;
-
- /* stop processing the audio unit */
- result = AudioOutputUnitStop(outputAudioUnit);
- if (result != noErr) {
- SDL_SetError("Core_CloseAudio: AudioOutputUnitStop");
- return;
- }
+ if (this->hidden != NULL) {
+ OSStatus result = noErr;
+ AURenderCallbackStruct callback;
+ const AudioUnitElement output_bus = 0;
+ const AudioUnitElement input_bus = 1;
+ const int iscapture = this->iscapture;
+ const AudioUnitElement bus = ((iscapture) ? input_bus : output_bus);
+ const AudioUnitScope scope = ((iscapture) ? kAudioUnitScope_Output :
+ kAudioUnitScope_Input);
- /* Remove the input callback */
- callback.inputProc = 0;
- callback.inputProcRefCon = 0;
- result = AudioUnitSetProperty(outputAudioUnit,
- kAudioUnitProperty_SetInputCallback,
- kAudioUnitScope_Input,
- 0, &callback, sizeof(callback));
- if (result != noErr) {
- SDL_SetError
- ("Core_CloseAudio: AudioUnitSetProperty (kAudioUnitProperty_SetInputCallback)");
- return;
+ /* stop processing the audio unit */
+ result = AudioOutputUnitStop(this->hidden->audioUnit);
+
+ /* Remove the input callback */
+ SDL_memset(&callback, '\0', sizeof (AURenderCallbackStruct));
+ result = AudioUnitSetProperty(this->hidden->audioUnit,
+ kAudioUnitProperty_SetRenderCallback,
+ scope, bus, &callback, sizeof (callback));
+
+ CloseComponent(this->hidden->audioUnit);
+
+ SDL_free(this->hidden->buffer);
+ SDL_free(this->hidden);
+ this->hidden = NULL;
}
+}
- result = CloseComponent(outputAudioUnit);
- if (result != noErr) {
- SDL_SetError("Core_CloseAudio: CloseComponent");
- return;
- }
-
- SDL_free(buffer);
-}
#define CHECK_RESULT(msg) \
if (result != noErr) { \
+ COREAUDIO_CloseDevice(this); \
SDL_SetError("CoreAudio error (%s): %d", msg, (int) result); \
- return -1; \
+ return 0; \
+ }
+
+static int
+find_device_by_name(_THIS, const char *devname, int iscapture)
+{
+ AudioDeviceID devid = 0;
+ OSStatus result = noErr;
+ UInt32 size = 0;
+ UInt32 alive = 0;
+ pid_t pid = 0;
+
+ if (devname == NULL) {
+ size = sizeof (AudioDeviceID);
+ const AudioHardwarePropertyID propid =
+ ((iscapture) ? kAudioHardwarePropertyDefaultInputDevice :
+ kAudioHardwarePropertyDefaultOutputDevice);
+
+ result = AudioHardwareGetProperty(propid, &size, &devid);
+ CHECK_RESULT("AudioHardwareGetProperty (default device)");
+ } else {
+ if (!find_device_id(devname, iscapture, &devid)) {
+ SDL_SetError("CoreAudio: No such audio device.");
+ return 0;
+ }
}
+ size = sizeof (alive);
+ result = AudioDeviceGetProperty(devid, 0, iscapture,
+ kAudioDevicePropertyDeviceIsAlive,
+ &size, &alive);
+ CHECK_RESULT("AudioDeviceGetProperty (kAudioDevicePropertyDeviceIsAlive)");
-int
-Core_OpenAudio(_THIS, SDL_AudioSpec * spec)
+ if (!alive) {
+ SDL_SetError("CoreAudio: requested device exists, but isn't alive.");
+ return 0;
+ }
+
+ size = sizeof (pid);
+ result = AudioDeviceGetProperty(devid, 0, iscapture,
+ kAudioDevicePropertyHogMode, &size, &pid);
+
+ /* some devices don't support this property, so errors are fine here. */
+ if ((result == noErr) && (pid != -1)) {
+ SDL_SetError("CoreAudio: requested device is being hogged.");
+ return 0;
+ }
+
+ this->hidden->deviceID = devid;
+ return 1;
+}
+
+
+static int
+prepare_audiounit(_THIS, const char *devname, int iscapture,
+ const AudioStreamBasicDescription *strdesc)
{
OSStatus result = noErr;
- Component comp;
+ AURenderCallbackStruct callback;
ComponentDescription desc;
- struct AudioUnitInputCallback callback;
+ Component comp = NULL;
+ int use_system_device = 0;
+ UInt32 enableIO = 0;
+ const AudioUnitElement output_bus = 0;
+ const AudioUnitElement input_bus = 1;
+ const AudioUnitElement bus = ((iscapture) ? input_bus : output_bus);
+ const AudioUnitScope scope = ((iscapture) ? kAudioUnitScope_Output :
+ kAudioUnitScope_Input);
+
+ if (!find_device_by_name(this, devname, iscapture)) {
+ SDL_SetError("Couldn't find requested CoreAudio device");
+ return 0;
+ }
+
+ SDL_memset(&desc, '\0', sizeof(ComponentDescription));
+ desc.componentType = kAudioUnitType_Output;
+ desc.componentSubType = kAudioUnitSubType_HALOutput;
+ desc.componentManufacturer = kAudioUnitManufacturer_Apple;
+
+ comp = FindNextComponent(NULL, &desc);
+ if (comp == NULL) {
+ SDL_SetError("Couldn't find requested CoreAudio component");
+ return 0;
+ }
+
+ /* Open & initialize the audio unit */
+ result = OpenAComponent(comp, &this->hidden->audioUnit);
+ CHECK_RESULT("OpenAComponent");
+
+ // !!! FIXME: this is wrong?
+ enableIO = ((iscapture) ? 1 : 0);
+ result = AudioUnitSetProperty(this->hidden->audioUnit,
+ kAudioOutputUnitProperty_EnableIO,
+ kAudioUnitScope_Input, input_bus,
+ &enableIO, sizeof (enableIO));
+ CHECK_RESULT("AudioUnitSetProperty (kAudioUnitProperty_EnableIO input)");
+
+ // !!! FIXME: this is wrong?
+ enableIO = ((iscapture) ? 0 : 1);
+ result = AudioUnitSetProperty(this->hidden->audioUnit,
+ kAudioOutputUnitProperty_EnableIO,
+ kAudioUnitScope_Output, output_bus,
+ &enableIO, sizeof (enableIO));
+ CHECK_RESULT("AudioUnitSetProperty (kAudioUnitProperty_EnableIO output)");
+
+ result = AudioUnitSetProperty(this->hidden->audioUnit,
+ kAudioOutputUnitProperty_CurrentDevice,
+ kAudioUnitScope_Global, 0,
+ &this->hidden->deviceID,
+ sizeof (AudioDeviceID));
+ CHECK_RESULT("AudioUnitSetProperty (kAudioOutputUnitProperty_CurrentDevice)");
+
+ /* Set the data format of the audio unit. */
+ result = AudioUnitSetProperty(this->hidden->audioUnit,
+ kAudioUnitProperty_StreamFormat,
+ scope, bus, strdesc, sizeof (*strdesc));
+ CHECK_RESULT("AudioUnitSetProperty (kAudioUnitProperty_StreamFormat)");
+
+ /* Set the audio callback */
+ SDL_memset(&callback, '\0', sizeof (AURenderCallbackStruct));
+ callback.inputProc = ((iscapture) ? inputCallback : outputCallback);
+ callback.inputProcRefCon = this;
+ result = AudioUnitSetProperty(this->hidden->audioUnit,
+ kAudioUnitProperty_SetRenderCallback,
+ scope, bus, &callback, sizeof (callback));
+ CHECK_RESULT("AudioUnitSetProperty (kAudioUnitProperty_SetInputCallback)");
+
+ /* Calculate the final parameters for this audio specification */
+ SDL_CalculateAudioSpec(&this->spec);
+
+ /* Allocate a sample buffer */
+ this->hidden->bufferOffset = this->hidden->bufferSize = this->spec.size;
+ this->hidden->buffer = SDL_malloc(this->hidden->bufferSize);
+
+ result = AudioUnitInitialize(this->hidden->audioUnit);
+ CHECK_RESULT("AudioUnitInitialize");
+
+ /* Finally, start processing of the audio unit */
+ result = AudioOutputUnitStart(this->hidden->audioUnit);
+ CHECK_RESULT("AudioOutputUnitStart");
+
+ /* We're running! */
+ return 1;
+}
+
+
+static int
+COREAUDIO_OpenDevice(_THIS, const char *devname, int iscapture)
+{
AudioStreamBasicDescription strdesc;
- SDL_AudioFormat test_format = SDL_FirstAudioFormat(spec->format);
+ SDL_AudioFormat test_format = SDL_FirstAudioFormat(this->spec.format);
int valid_datatype = 0;
+ /* Initialize all variables that we clean on shutdown */
+ this->hidden = (struct SDL_PrivateAudioData *)
+ SDL_malloc((sizeof *this->hidden));
+ if (this->hidden == NULL) {
+ SDL_OutOfMemory();
+ return (0);
+ }
+ SDL_memset(this->hidden, 0, (sizeof *this->hidden));
+
/* Setup a AudioStreamBasicDescription with the requested format */
- memset(&strdesc, '\0', sizeof(AudioStreamBasicDescription));
+ SDL_memset(&strdesc, '\0', sizeof(AudioStreamBasicDescription));
strdesc.mFormatID = kAudioFormatLinearPCM;
strdesc.mFormatFlags = kLinearPCMFormatFlagIsPacked;
- strdesc.mChannelsPerFrame = spec->channels;
- strdesc.mSampleRate = spec->freq;
+ strdesc.mChannelsPerFrame = this->spec.channels;
+ strdesc.mSampleRate = this->spec.freq;
strdesc.mFramesPerPacket = 1;
while ((!valid_datatype) && (test_format)) {
- spec->format = test_format;
+ this->spec.format = test_format;
/* Just a list of valid SDL formats, so people don't pass junk here. */
switch (test_format) {
case AUDIO_U8:
@@ -234,13 +531,13 @@
case AUDIO_F32LSB:
case AUDIO_F32MSB:
valid_datatype = 1;
- strdesc.mBitsPerChannel = SDL_AUDIO_BITSIZE(spec->format);
- if (SDL_AUDIO_ISBIGENDIAN(spec->format))
+ strdesc.mBitsPerChannel = SDL_AUDIO_BITSIZE(this->spec.format);
+ if (SDL_AUDIO_ISBIGENDIAN(this->spec.format))
strdesc.mFormatFlags |= kLinearPCMFormatFlagIsBigEndian;
- if (SDL_AUDIO_ISFLOAT(spec->format))
+ if (SDL_AUDIO_ISFLOAT(this->spec.format))
strdesc.mFormatFlags |= kLinearPCMFormatFlagIsFloat;
- else if (SDL_AUDIO_ISSIGNED(spec->format))
+ else if (SDL_AUDIO_ISSIGNED(this->spec.format))
strdesc.mFormatFlags |= kLinearPCMFormatFlagIsSignedInteger;
break;
}
@@ -248,7 +545,7 @@
if (!valid_datatype) { /* shouldn't happen, but just in case... */
SDL_SetError("Unsupported audio format");
- return (-1);
+ return 0;
}
strdesc.mBytesPerFrame =
@@ -256,52 +553,31 @@
strdesc.mBytesPerPacket =
strdesc.mBytesPerFrame * strdesc.mFramesPerPacket;
- /* Locate the default output audio unit */
- memset(&desc, '\0', sizeof(ComponentDescription));
- desc.componentType = kAudioUnitComponentType;
- desc.componentSubType = kAudioUnitSubType_Output;
- desc.componentManufacturer = kAudioUnitID_DefaultOutput;
- desc.componentFlags = 0;
- desc.componentFlagsMask = 0;
-
- comp = FindNextComponent(NULL, &desc);
- if (comp == NULL) {
- SDL_SetError
- ("Failed to start CoreAudio: FindNextComponent returned NULL");
- return -1;
+ if (!prepare_audiounit(this, devname, iscapture, &strdesc)) {
+ return 0; /* prepare_audiounit() will call SDL_SetError()... */
}
- /* Open & initialize the default output audio unit */
- result = OpenAComponent(comp, &outputAudioUnit);
- CHECK_RESULT("OpenAComponent")
- result = AudioUnitInitialize(outputAudioUnit);
- CHECK_RESULT("AudioUnitInitialize")
- /* Set the input format of the audio unit. */
- result = AudioUnitSetProperty(outputAudioUnit,
- kAudioUnitProperty_StreamFormat,
- kAudioUnitScope_Input,
- 0, &strdesc, sizeof(strdesc));
- CHECK_RESULT("AudioUnitSetProperty (kAudioUnitProperty_StreamFormat)")
- /* Set the audio callback */
- callback.inputProc = audioCallback;
- callback.inputProcRefCon = this;
- result = AudioUnitSetProperty(outputAudioUnit,
- kAudioUnitProperty_SetInputCallback,
- kAudioUnitScope_Input,
- 0, &callback, sizeof(callback));
- CHECK_RESULT("AudioUnitSetProperty (kAudioUnitProperty_SetInputCallback)")
- /* Calculate the final parameters for this audio specification */
- SDL_CalculateAudioSpec(spec);
-
- /* Allocate a sample buffer */
- bufferOffset = bufferSize = this->spec.size;
- buffer = SDL_malloc(bufferSize);
-
- /* Finally, start processing of the audio unit */
- result = AudioOutputUnitStart(outputAudioUnit);
- CHECK_RESULT("AudioOutputUnitStart")
- /* We're running! */
- return (1);
+ return 1; /* good to go. */
}
+static int
+COREAUDIO_Init(SDL_AudioDriverImpl *impl)
+{
+ /* Set the function pointers */
+ impl->DetectDevices = COREAUDIO_DetectDevices;
+ impl->GetDeviceName = COREAUDIO_GetDeviceName;
+ impl->OpenDevice = COREAUDIO_OpenDevice;
+ impl->CloseDevice = COREAUDIO_CloseDevice;
+ impl->Deinitialize = COREAUDIO_Deinitialize;
+ impl->ProvidesOwnCallbackThread = 1;
+
+ build_device_lists(); /* do an initial check for devices... */
+
+ return 1;
+}
+
+AudioBootStrap COREAUDIO_bootstrap = {
+ "coreaudio", "Mac OS X CoreAudio", COREAUDIO_Init, 0
+};
+
/* vi: set ts=4 sw=4 expandtab: */
--- a/src/audio/macosx/SDL_coreaudio.h Sun Oct 01 16:10:41 2006 +0000
+++ b/src/audio/macosx/SDL_coreaudio.h Tue Oct 17 09:15:21 2006 +0000
@@ -26,22 +26,17 @@
#include "../SDL_sysaudio.h"
-/* Hidden "this" pointer for the video functions */
+/* Hidden "this" pointer for the audio functions */
#define _THIS SDL_AudioDevice *this
struct SDL_PrivateAudioData
{
- AudioUnit outputAudioUnit;
+ AudioUnit audioUnit;
void *buffer;
UInt32 bufferOffset;
UInt32 bufferSize;
+ AudioDeviceID deviceID;
};
-/* Old variable names */
-#define outputAudioUnit (this->hidden->outputAudioUnit)
-#define buffer (this->hidden->buffer)
-#define bufferOffset (this->hidden->bufferOffset)
-#define bufferSize (this->hidden->bufferSize)
-
#endif /* _SDL_coreaudio_h */
/* vi: set ts=4 sw=4 expandtab: */
--- a/src/audio/macrom/SDL_romaudio.c Sun Oct 01 16:10:41 2006 +0000
+++ b/src/audio/macrom/SDL_romaudio.c Tue Oct 17 09:15:21 2006 +0000
@@ -21,11 +21,16 @@
*/
#include "SDL_config.h"
+/* This should work on PowerPC and Intel Mac OS X, and Carbonized Mac OS 9. */
+
#if defined(__APPLE__) && defined(__MACH__)
+# define SDL_MACOS_NAME "Mac OS X"
# include <Carbon/Carbon.h>
#elif TARGET_API_MAC_CARBON && (UNIVERSAL_INTERFACES_VERSION > 0x0335)
+# define SDL_MACOS_NAME "Mac OS 9"
# include <Carbon.h>
#else
+# define SDL_MACOS_NAME "Mac OS 9"
# include <Sound.h> /* SoundManager interface */
# include <Gestalt.h>
# include <DriverServices.h>
@@ -45,72 +50,6 @@
#include "../SDL_sysaudio.h"
#include "SDL_romaudio.h"
-/* Audio driver functions */
-
-static void Mac_CloseAudio(_THIS);
-static int Mac_OpenAudio(_THIS, SDL_AudioSpec * spec);
-static void Mac_LockAudio(_THIS);
-static void Mac_UnlockAudio(_THIS);
-
-/* Audio driver bootstrap functions */
-
-
-static int
-Audio_Available(void)
-{
- return (1);
-}
-
-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));
-
- /* Set the function pointers */
- this->OpenAudio = Mac_OpenAudio;
- this->CloseAudio = Mac_CloseAudio;
- this->LockAudio = Mac_LockAudio;
- this->UnlockAudio = Mac_UnlockAudio;
- this->free = Audio_DeleteDevice;
-
-#ifdef __MACOSX__ /* Mac OS X uses threaded audio, so normal thread code is okay */
- this->LockAudio = NULL;
- this->UnlockAudio = NULL;
-#endif
- return this;
-}
-
-AudioBootStrap SNDMGR_bootstrap = {
- "sndmgr", "MacOS SoundManager 3.0",
- Audio_Available, Audio_CreateDevice
-};
-
-#if defined(TARGET_API_MAC_CARBON) || defined(USE_RYANS_SOUNDCODE)
-/* This works correctly on Mac OS X */
-
#pragma options align=power
static volatile SInt32 audio_is_locked = 0;
@@ -121,6 +60,7 @@
static CmpSoundHeader header;
static volatile Uint32 fill_me = 0;
+
static void
mix_buffer(SDL_AudioDevice * audio, UInt8 * buffer)
{
@@ -150,13 +90,13 @@
}
static void
-Mac_LockAudio(_THIS)
+SNDMGR_LockDevice(_THIS)
{
IncrementAtomic((SInt32 *) & audio_is_locked);
}
static void
-Mac_UnlockAudio(_THIS)
+SNDMGR_UnlockDevice(_THIS)
{
SInt32 oldval;
@@ -198,7 +138,7 @@
cmd.param2 = (long) &header;
SndDoCommand(chan, &cmd, 0);
- memset(buffer[fill_me], 0, audio->spec.size);
+ SDL_memset(buffer[fill_me], 0, audio->spec.size);
/*
* if audio device isn't locked, mix the next buffer to be queued in
@@ -219,14 +159,25 @@
}
static int
-Mac_OpenAudio(_THIS, SDL_AudioSpec * spec)
+SNDMGR_OpenDevice(_THIS, const char *devname, int iscapture)
{
-
+ SDL_AudioSpec *spec = &this->spec;
+ SndChannelPtr channel = NULL;
SndCallBackUPP callback;
int sample_bits;
int i;
long initOptions;
+ /* Initialize all variables that we clean on shutdown */
+ this->hidden = (struct SDL_PrivateAudioData *)
+ SDL_malloc((sizeof *this->hidden));
+ if (this->hidden == NULL) {
+ SDL_OutOfMemory();
+ return 0;
+ }
+ SDL_memset(this->hidden, 0, (sizeof *this->hidden));
+
+ /* !!! FIXME: iterate through format matrix... */
/* Very few conversions are required, but... */
switch (spec->format) {
case AUDIO_S8:
@@ -242,10 +193,10 @@
spec->format = AUDIO_F32MSB;
break;
}
- SDL_CalculateAudioSpec(spec);
+ SDL_CalculateAudioSpec(&this->spec);
/* initialize bufferCmd header */
- memset(&header, 0, sizeof(header));
+ SDL_memset(&header, 0, sizeof(header));
callback = (SndCallBackUPP) NewSndCallBackUPP(callBackProc);
sample_bits = spec->size / spec->samples / spec->channels * 8;
@@ -278,20 +229,23 @@
/* allocate 2 buffers */
for (i = 0; i < 2; i++) {
- buffer[i] = (UInt8 *) malloc(sizeof(UInt8) * spec->size);
+ buffer[i] = (UInt8 *) SDL_malloc(sizeof(UInt8) * spec->size);
if (buffer[i] == NULL) {
+ SNDMGR_CloseDevice(this);
SDL_OutOfMemory();
- return (-1);
+ return 0;
}
- memset(buffer[i], 0, spec->size);
+ SDL_memset(buffer[i], 0, spec->size);
}
/* Create the sound manager channel */
channel = (SndChannelPtr) SDL_malloc(sizeof(*channel));
if (channel == NULL) {
+ SNDMGR_CloseDevice(this);
SDL_OutOfMemory();
- return (-1);
+ return 0;
}
+ this->hidden->channel = channel;
if (spec->channels >= 2) {
initOptions = initStereo;
} else {
@@ -300,10 +254,9 @@
channel->userInfo = (long) this;
channel->qLength = 128;
if (SndNewChannel(&channel, sampledSynth, initOptions, callback) != noErr) {
+ SNDMGR_CloseDevice(this);
SDL_SetError("Unable to create audio channel");
- SDL_free(channel);
- channel = NULL;
- return (-1);
+ return 0;
}
/* start playback */
@@ -319,16 +272,15 @@
}
static void
-Mac_CloseAudio(_THIS)
+SNDMGR_CloseDevice(_THIS)
{
-
int i;
running = 0;
- if (channel) {
- SndDisposeChannel(channel, true);
- channel = NULL;
+ if (this->hidden->channel) {
+ SndDisposeChannel(this->hidden->channel, true);
+ this->hidden->channel = NULL;
}
for (i = 0; i < 2; ++i) {
@@ -337,193 +289,31 @@
buffer[i] = NULL;
}
}
-}
-
-#else /* !TARGET_API_MAC_CARBON && !USE_RYANS_SOUNDCODE */
-
-static void
-Mac_LockAudio(_THIS)
-{
- /* no-op. */
-}
-
-static void
-Mac_UnlockAudio(_THIS)
-{
- /* no-op. */
-}
-
-
-/* This function is called by Sound Manager when it has exhausted one of
- the buffers, so we'll zero it to silence and fill it with audio if
- we're not paused.
-*/
-static pascal void
-sndDoubleBackProc(SndChannelPtr chan, SndDoubleBufferPtr newbuf)
-{
- SDL_AudioDevice *audio = (SDL_AudioDevice *) newbuf->dbUserInfo[0];
-
- /* If audio is quitting, don't do anything */
- if (!audio->enabled) {
- return;
- }
- memset(newbuf->dbSoundData, 0, audio->spec.size);
- newbuf->dbNumFrames = audio->spec.samples;
- if (!audio->paused) {
- if (audio->convert.needed) {
- audio->spec.callback(audio->spec.userdata,
- (Uint8 *) audio->convert.buf,
- audio->convert.len);
- SDL_ConvertAudio(&audio->convert);
-#if 0
- if (audio->convert.len_cvt != audio->spec.size) {
- /* Uh oh... probably crashes here */ ;
- }
-#endif
- SDL_memcpy(newbuf->dbSoundData, audio->convert.buf,
- audio->convert.len_cvt);
- } else {
- audio->spec.callback(audio->spec.userdata,
- (Uint8 *) newbuf->dbSoundData,
- audio->spec.size);
- }
- }
- newbuf->dbFlags |= dbBufferReady;
+ SDL_free(this->hidden);
+ this->hidden = NULL;
}
static int
-DoubleBufferAudio_Available(void)
-{
- int available;
- NumVersion sndversion;
- long response;
-
- available = 0;
- sndversion = SndSoundManagerVersion();
- if (sndversion.majorRev >= 3) {
- if (Gestalt(gestaltSoundAttr, &response) == noErr) {
- if ((response & (1 << gestaltSndPlayDoubleBuffer))) {
- available = 1;
- }
- }
- } else {
- if (Gestalt(gestaltSoundAttr, &response) == noErr) {
- if ((response & (1 << gestaltHasASC))) {
- available = 1;
- }
- }
- }
- return (available);
-}
-
-static void
-Mac_CloseAudio(_THIS)
+SNDMGR_Init(SDL_AudioDriverImpl *impl)
{
- int i;
-
- if (channel != NULL) {
- /* Clean up the audio channel */
- SndDisposeChannel(channel, true);
- channel = NULL;
- }
- for (i = 0; i < 2; ++i) {
- if (audio_buf[i]) {
- SDL_free(audio_buf[i]);
- audio_buf[i] = NULL;
- }
- }
-}
-
-static int
-Mac_OpenAudio(_THIS, SDL_AudioSpec * spec)
-{
- SndDoubleBufferHeader2 audio_dbh;
- int i;
- long initOptions;
- int sample_bits;
- SndDoubleBackUPP doubleBackProc;
-
- /* Check to make sure double-buffered audio is available */
- if (!DoubleBufferAudio_Available()) {
- SDL_SetError("Sound manager doesn't support double-buffering");
- return (-1);
- }
+ /* Set the function pointers */
+ impl->OpenDevice = SNDMGR_OpenDevice;
+ impl->CloseDevice = SNDMGR_CloseDevice;
+ impl->ProvidesOwnCallbackThread = 1;
+ impl->OnlyHasDefaultOutputDevice = 1;
- /* Very few conversions are required, but... */
- switch (spec->format) {
- case AUDIO_S8:
- spec->format = AUDIO_U8;
- break;
- case AUDIO_U16LSB:
- spec->format = AUDIO_S16LSB;
- break;
- case AUDIO_U16MSB:
- spec->format = AUDIO_S16MSB;
- break;
- }
- SDL_CalculateAudioSpec(spec);
-
- /* initialize the double-back header */
- SDL_memset(&audio_dbh, 0, sizeof(audio_dbh));
- doubleBackProc = NewSndDoubleBackProc(sndDoubleBackProc);
- sample_bits = spec->size / spec->samples / spec->channels * 8;
-
- audio_dbh.dbhNumChannels = spec->channels;
- audio_dbh.dbhSampleSize = sample_bits;
- audio_dbh.dbhCompressionID = 0;
- audio_dbh.dbhPacketSize = 0;
- audio_dbh.dbhSampleRate = spec->freq << 16;
- audio_dbh.dbhDoubleBack = doubleBackProc;
- audio_dbh.dbhFormat = 0;
-
- /* Note that we install the 16bitLittleEndian Converter if needed. */
- if (spec->format == 0x8010) {
- audio_dbh.dbhCompressionID = fixedCompression;
- audio_dbh.dbhFormat = k16BitLittleEndianFormat;
- }
-
- /* allocate the 2 double-back buffers */
- for (i = 0; i < 2; ++i) {
- audio_buf[i] = SDL_calloc(1, sizeof(SndDoubleBuffer) + spec->size);
- if (audio_buf[i] == NULL) {
- SDL_OutOfMemory();
- return (-1);
- }
- audio_buf[i]->dbNumFrames = spec->samples;
- audio_buf[i]->dbFlags = dbBufferReady;
- audio_buf[i]->dbUserInfo[0] = (long) this;
- audio_dbh.dbhBufferPtr[i] = audio_buf[i];
- }
-
- /* Create the sound manager channel */
- channel = (SndChannelPtr) SDL_malloc(sizeof(*channel));
- if (channel == NULL) {
- SDL_OutOfMemory();
- return (-1);
- }
- if (spec->channels >= 2) {
- initOptions = initStereo;
- } else {
- initOptions = initMono;
- }
- channel->userInfo = 0;
- channel->qLength = 128;
- if (SndNewChannel(&channel, sampledSynth, initOptions, 0L) != noErr) {
- SDL_SetError("Unable to create audio channel");
- SDL_free(channel);
- channel = NULL;
- return (-1);
- }
-
- /* Start playback */
- if (SndPlayDoubleBuffer(channel, (SndDoubleBufferHeaderPtr) & audio_dbh)
- != noErr) {
- SDL_SetError("Unable to play double buffered audio");
- return (-1);
- }
+/* Mac OS X uses threaded audio, so normal thread code is okay */
+#ifndef __MACOSX__
+ impl->LockDevice = SNDMGR_LockDevice;
+ impl->UnlockDevice = SNDMGR_UnlockDevice;
+ impl->SkipMixerLock = 1;
+#endif
return 1;
}
-#endif /* TARGET_API_MAC_CARBON || USE_RYANS_SOUNDCODE */
+AudioBootStrap SNDMGR_bootstrap = {
+ "sndmgr", SDL_MACOS_NAME " SoundManager", SNDMGR_Init, 0
+};
+
/* vi: set ts=4 sw=4 expandtab: */
--- a/src/audio/macrom/SDL_romaudio.h Sun Oct 01 16:10:41 2006 +0000
+++ b/src/audio/macrom/SDL_romaudio.h Tue Oct 17 09:15:21 2006 +0000
@@ -26,27 +26,14 @@
#include "../SDL_sysaudio.h"
-/* This is Ryan's improved MacOS sound code, with locking support */
-#define USE_RYANS_SOUNDCODE
-
-/* Hidden "this" pointer for the video functions */
+/* Hidden "this" pointer for the audio functions */
#define _THIS SDL_AudioDevice *this
struct SDL_PrivateAudioData
{
/* Sound manager audio channel */
SndChannelPtr channel;
-#if defined(TARGET_API_MAC_CARBON) || defined(USE_RYANS_SOUNDCODE)
- /* FIXME: Add Ryan's static data here */
-#else
- /* Double buffering variables */
- SndDoubleBufferPtr audio_buf[2];
-#endif
};
-/* Old variable names */
-#define channel (this->hidden->channel)
-#define audio_buf (this->hidden->audio_buf)
-
#endif /* _SDL_romaudio_h */
/* vi: set ts=4 sw=4 expandtab: */
--- a/src/audio/mint/SDL_mintaudio_dma8.c Sun Oct 01 16:10:41 2006 +0000
+++ b/src/audio/mint/SDL_mintaudio_dma8.c Tue Oct 17 09:15:21 2006 +0000
@@ -61,105 +61,8 @@
static unsigned long cookie_snd, cookie_mch;
-/*--- Audio driver functions ---*/
-
-static void Mint_CloseAudio(_THIS);
-static int Mint_OpenAudio(_THIS, SDL_AudioSpec * spec);
-static void Mint_LockAudio(_THIS);
-static void Mint_UnlockAudio(_THIS);
-
-/* To check/init hardware audio */
-static int Mint_CheckAudio(_THIS, SDL_AudioSpec * spec);
-static void Mint_InitAudio(_THIS, SDL_AudioSpec * spec);
-
-/*--- Audio driver bootstrap functions ---*/
-
-static int
-Audio_Available(void)
-{
- const char *envr = SDL_getenv("SDL_AUDIODRIVER");
-
- /* Check if user asked a different audio driver */
- if ((envr) && (SDL_strcmp(envr, MINT_AUDIO_DRIVER_NAME) != 0)) {
- DEBUG_PRINT((DEBUG_NAME "user asked a different audio driver\n"));
- return 0;
- }
-
- /* Cookie _MCH present ? if not, assume ST machine */
- if (Getcookie(C__MCH, &cookie_mch) == C_NOTFOUND) {
- cookie_mch = MCH_ST;
- }
-
- /* Cookie _SND present ? if not, assume ST machine */
- if (Getcookie(C__SND, &cookie_snd) == C_NOTFOUND) {
- cookie_snd = SND_PSG;
- }
-
- /* Check if we have 8 bits audio */
- if ((cookie_snd & SND_8BIT) == 0) {
- DEBUG_PRINT((DEBUG_NAME "no 8 bits sound\n"));
- return (0);
- }
-
- /* Check if audio is lockable */
- if (cookie_snd & SND_16BIT) {
- if (Locksnd() != 1) {
- DEBUG_PRINT((DEBUG_NAME "audio locked by other application\n"));
- return (0);
- }
-
- Unlocksnd();
- }
-
- DEBUG_PRINT((DEBUG_NAME "8 bits audio available!\n"));
- return (1);
-}
-
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));
-
- /* Set the function pointers */
- this->OpenAudio = Mint_OpenAudio;
- this->CloseAudio = Mint_CloseAudio;
- this->LockAudio = Mint_LockAudio;
- this->UnlockAudio = Mint_UnlockAudio;
- this->free = Audio_DeleteDevice;
-
- return this;
-}
-
-AudioBootStrap MINTAUDIO_DMA8_bootstrap = {
- MINT_AUDIO_DRIVER_NAME, "MiNT DMA 8 bits audio driver",
- Audio_Available, Audio_CreateDevice
-};
-
-static void
-Mint_LockAudio(_THIS)
+MINTDMA8_LockDevice(_THIS)
{
void *oldpile;
@@ -170,7 +73,7 @@
}
static void
-Mint_UnlockAudio(_THIS)
+MINTDMA8_UnlockDevice(_THIS)
{
void *oldpile;
@@ -181,57 +84,59 @@
}
static void
-Mint_CloseAudio(_THIS)
+MINTDMA8_CloseDevice(_THIS)
{
- void *oldpile;
+ if (this->hidden != NULL) {
+ /* Stop replay */
+ void *oldpile = (void *) Super(0);
- /* Stop replay */
- oldpile = (void *) Super(0);
- DMAAUDIO_IO.control = 0;
- Super(oldpile);
+ DMAAUDIO_IO.control = 0;
+ Super(oldpile);
+
+ DEBUG_PRINT((DEBUG_NAME "closeaudio: replay stopped\n"));
- DEBUG_PRINT((DEBUG_NAME "closeaudio: replay stopped\n"));
+ /* Disable interrupt */
+ Jdisint(MFP_DMASOUND);
- /* Disable interrupt */
- Jdisint(MFP_DMASOUND);
+ DEBUG_PRINT((DEBUG_NAME "closeaudio: interrupt disabled\n"));
- DEBUG_PRINT((DEBUG_NAME "closeaudio: interrupt disabled\n"));
+ /* Wait if currently playing sound */
+ while (SDL_MintAudio_mutex != 0) {}
- /* Wait if currently playing sound */
- while (SDL_MintAudio_mutex != 0) {
- }
-
- DEBUG_PRINT((DEBUG_NAME "closeaudio: no more interrupt running\n"));
+ DEBUG_PRINT((DEBUG_NAME "closeaudio: no more interrupt running\n"));
- /* Clear buffers */
- if (SDL_MintAudio_audiobuf[0]) {
- Mfree(SDL_MintAudio_audiobuf[0]);
- SDL_MintAudio_audiobuf[0] = SDL_MintAudio_audiobuf[1] = NULL;
+ /* Clear buffers */
+ if (SDL_MintAudio_audiobuf[0]) {
+ Mfree(SDL_MintAudio_audiobuf[0]);
+ SDL_MintAudio_audiobuf[0] = SDL_MintAudio_audiobuf[1] = NULL;
+ }
+
+ DEBUG_PRINT((DEBUG_NAME "closeaudio: buffers freed\n"));
+ SDL_free(this->buffer);
+ this->buffer = NULL;
}
-
- DEBUG_PRINT((DEBUG_NAME "closeaudio: buffers freed\n"));
}
static int
-Mint_CheckAudio(_THIS, SDL_AudioSpec * spec)
+MINTDMA8_CheckAudio(_THIS)
{
int i, masterprediv, sfreq;
unsigned long masterclock;
DEBUG_PRINT((DEBUG_NAME "asked: %d bits, ",
- SDL_AUDIO_BITSIZE(spec->format)));
- DEBUG_PRINT(("float=%d, ", SDL_AUDIO_ISFLOAT(spec->format)));
- DEBUG_PRINT(("signed=%d, ", SDL_AUDIO_ISSIGNED(spec->format)));
- DEBUG_PRINT(("big endian=%d, ", SDL_AUDIO_ISBIGENDIAN(spec->format)));
- DEBUG_PRINT(("channels=%d, ", spec->channels));
- DEBUG_PRINT(("freq=%d\n", spec->freq));
+ SDL_AUDIO_BITSIZE(this->spec.format)));
+ DEBUG_PRINT(("float=%d, ", SDL_AUDIO_ISFLOAT(this->spec.format)));
+ DEBUG_PRINT(("signed=%d, ", SDL_AUDIO_ISSIGNED(this->spec.format)));
+ DEBUG_PRINT(("big endian=%d, ", SDL_AUDIO_ISBIGENDIAN(this->spec.format)));
+ DEBUG_PRINT(("channels=%d, ", this->spec.channels));
+ DEBUG_PRINT(("freq=%d\n", this->spec.freq));
- if (spec->channels > 2) {
- spec->channels = 2; /* no more than stereo! */
+ if (this->spec.channels > 2) {
+ this->spec.channels = 2; /* no more than stereo! */
}
/* Check formats available */
- spec->format = AUDIO_S8;
+ this->spec.format = AUDIO_S8;
/* Calculate and select the closest frequency */
sfreq = 0;
@@ -272,22 +177,22 @@
}
#endif
- MINTAUDIO_numfreq = SDL_MintAudio_SearchFrequency(this, spec->freq);
- spec->freq = MINTAUDIO_frequencies[MINTAUDIO_numfreq].frequency;
+ MINTAUDIO_numfreq = SDL_MintAudio_SearchFrequency(this, this->spec.freq);
+ this->spec.freq = MINTAUDIO_frequencies[MINTAUDIO_numfreq].frequency;
DEBUG_PRINT((DEBUG_NAME "obtained: %d bits, ",
- SDL_AUDIO_BITSIZE(spec->format)));
- DEBUG_PRINT(("float=%d, ", SDL_AUDIO_ISFLOAT(spec->format)));
- DEBUG_PRINT(("signed=%d, ", SDL_AUDIO_ISSIGNED(spec->format)));
- DEBUG_PRINT(("big endian=%d, ", SDL_AUDIO_ISBIGENDIAN(spec->format)));
- DEBUG_PRINT(("channels=%d, ", spec->channels));
- DEBUG_PRINT(("freq=%d\n", spec->freq));
+ SDL_AUDIO_BITSIZE(this->spec.format)));
+ DEBUG_PRINT(("float=%d, ", SDL_AUDIO_ISFLOAT(this->spec.format)));
+ DEBUG_PRINT(("signed=%d, ", SDL_AUDIO_ISSIGNED(this->spec.format)));
+ DEBUG_PRINT(("big endian=%d, ", SDL_AUDIO_ISBIGENDIAN(this->spec.format)));
+ DEBUG_PRINT(("channels=%d, ", this->spec.channels));
+ DEBUG_PRINT(("freq=%d\n", this->spec.freq));
return 0;
}
static void
-Mint_InitAudio(_THIS, SDL_AudioSpec * spec)
+MINTDMA8_InitAudio(_THIS)
{
void *oldpile;
unsigned long buffer;
@@ -316,7 +221,7 @@
DMAAUDIO_IO.end_low = buffer & 255;
mode = 3 - MINTAUDIO_frequencies[MINTAUDIO_numfreq].predivisor;
- if (spec->channels == 1) {
+ if (this->spec.channels == 1) {
mode |= 1 << 7;
}
DMAAUDIO_IO.sound_ctrl = mode;
@@ -339,29 +244,40 @@
}
static int
-Mint_OpenAudio(_THIS, SDL_AudioSpec * spec)
+MINTDMA8_OpenDevice(_THIS, const char *devname, int iscapture)
{
SDL_MintAudio_device = this;
/* Check audio capabilities */
- if (Mint_CheckAudio(this, spec) == -1) {
- return -1;
+ if (MINTDMA8_CheckAudio(this) == -1) {
+ return 0;
}
- SDL_CalculateAudioSpec(spec);
+ /* Initialize all variables that we clean on shutdown */
+ this->hidden = (struct SDL_PrivateAudioData *)
+ SDL_malloc((sizeof *this->hidden));
+ if (this->hidden == NULL) {
+ SDL_OutOfMemory();
+ return 0;
+ }
+ SDL_memset(this->hidden, 0, (sizeof *this->hidden));
+
+ SDL_CalculateAudioSpec(&this->spec);
/* Allocate memory for audio buffers in DMA-able RAM */
- DEBUG_PRINT((DEBUG_NAME "buffer size=%d\n", spec->size));
+ DEBUG_PRINT((DEBUG_NAME "buffer size=%d\n", this->spec.size));
- SDL_MintAudio_audiobuf[0] = Atari_SysMalloc(spec->size * 2, MX_STRAM);
+ SDL_MintAudio_audiobuf[0] = Atari_SysMalloc(this->spec.size * 2, MX_STRAM);
if (SDL_MintAudio_audiobuf[0] == NULL) {
- SDL_SetError("MINT_OpenAudio: Not enough memory for audio buffer");
- return (-1);
+ SDL_free(this->hidden);
+ this->hidden = NULL;
+ SDL_OutOfMemory();
+ return 0;
}
- SDL_MintAudio_audiobuf[1] = SDL_MintAudio_audiobuf[0] + spec->size;
+ SDL_MintAudio_audiobuf[1] = SDL_MintAudio_audiobuf[0] + this->spec.size;
SDL_MintAudio_numbuf = 0;
- SDL_memset(SDL_MintAudio_audiobuf[0], spec->silence, spec->size * 2);
- SDL_MintAudio_audiosize = spec->size;
+ SDL_memset(SDL_MintAudio_audiobuf[0],this->spec.silence,this->spec.size*2);
+ SDL_MintAudio_audiosize = this->spec.size;
SDL_MintAudio_mutex = 0;
DEBUG_PRINT((DEBUG_NAME "buffer 0 at 0x%08x\n",
@@ -372,9 +288,56 @@
SDL_MintAudio_CheckFpu();
/* Setup audio hardware */
- Mint_InitAudio(this, spec);
+ MINTDMA8_InitAudio(this);
- return (1); /* We don't use threaded audio */
+ return 1; /* good to go. */
}
+static int
+MINTDMA8_Init(SDL_AudioDriverImpl *impl)
+{
+ /* Cookie _MCH present ? if not, assume ST machine */
+ if (Getcookie(C__MCH, &cookie_mch) == C_NOTFOUND) {
+ cookie_mch = MCH_ST;
+ }
+
+ /* Cookie _SND present ? if not, assume ST machine */
+ if (Getcookie(C__SND, &cookie_snd) == C_NOTFOUND) {
+ cookie_snd = SND_PSG;
+ }
+
+ /* Check if we have 8 bits audio */
+ if ((cookie_snd & SND_8BIT) == 0) {
+ SDL_SetError(DEBUG_NAME "no 8 bits sound");
+ return 0;
+ }
+
+ /* Check if audio is lockable */
+ if (cookie_snd & SND_16BIT) {
+ if (Locksnd() != 1) {
+ SDL_SetError(DEBUG_NAME "audio locked by other application");
+ return 0;
+ }
+
+ Unlocksnd();
+ }
+
+ DEBUG_PRINT((DEBUG_NAME "8 bits audio available!\n"));
+
+ /* Set the function pointers */
+ impl->OpenDevice = MINTDMA8_OpenDevice;
+ impl->CloseDevice = MINTDMA8_CloseDevice;
+ impl->LockAudio = MINTDMA8_LockAudio;
+ impl->UnlockAudio = MINTDMA8_UnlockAudio;
+ impl->OnlyHasDefaultOutputDevice = 1;
+ impl->ProvidesOwnCallbackThread = 1;
+ impl->SkipMixerLock = 1;
+
+ return 1;
+}
+
+AudioBootStrap MINTAUDIO_DMA8_bootstrap = {
+ MINT_AUDIO_DRIVER_NAME, "MiNT DMA 8 bits audio driver", MINTDMA8_Init, 0
+};
+
/* vi: set ts=4 sw=4 expandtab: */
--- a/src/audio/mint/SDL_mintaudio_gsxb.c Sun Oct 01 16:10:41 2006 +0000
+++ b/src/audio/mint/SDL_mintaudio_gsxb.c Tue Oct 17 09:15:21 2006 +0000
@@ -63,176 +63,83 @@
/*--- Audio driver functions ---*/
-static void Mint_CloseAudio(_THIS);
-static int Mint_OpenAudio(_THIS, SDL_AudioSpec * spec);
-static void Mint_LockAudio(_THIS);
-static void Mint_UnlockAudio(_THIS);
-
-/* To check/init hardware audio */
-static int Mint_CheckAudio(_THIS, SDL_AudioSpec * spec);
-static void Mint_InitAudio(_THIS, SDL_AudioSpec * spec);
-
/* GSXB callbacks */
-static void Mint_GsxbInterrupt(void);
-static void Mint_GsxbNullInterrupt(void);
-
-/*--- Audio driver bootstrap functions ---*/
-
-static int
-Audio_Available(void)
-{
- const char *envr = SDL_getenv("SDL_AUDIODRIVER");
-
- /* Check if user asked a different audio driver */
- if ((envr) && (SDL_strcmp(envr, MINT_AUDIO_DRIVER_NAME) != 0)) {
- DEBUG_PRINT((DEBUG_NAME "user asked a different audio driver\n"));
- return (0);
- }
-
- /* Cookie _SND present ? if not, assume ST machine */
- if (Getcookie(C__SND, &cookie_snd) == C_NOTFOUND) {
- cookie_snd = SND_PSG;
- }
-
- /* Check if we have 16 bits audio */
- if ((cookie_snd & SND_16BIT) == 0) {
- DEBUG_PRINT((DEBUG_NAME "no 16 bits sound\n"));
- return (0);
- }
-
- /* Cookie GSXB present ? */
- cookie_gsxb = (Getcookie(C_GSXB, &cookie_gsxb) == C_FOUND);
-
- /* Is it GSXB ? */
- if (((cookie_snd & SND_GSXB) == 0) || (cookie_gsxb == 0)) {
- DEBUG_PRINT((DEBUG_NAME "no GSXB audio\n"));
- return (0);
- }
-
- /* Check if audio is lockable */
- if (Locksnd() != 1) {
- DEBUG_PRINT((DEBUG_NAME "audio locked by other application\n"));
- return (0);
- }
-
- Unlocksnd();
-
- DEBUG_PRINT((DEBUG_NAME "GSXB audio available!\n"));
- return (1);
-}
+static void MINTGSXB_GsxbInterrupt(void);
+static void MINTGSXB_GsxbNullInterrupt(void);
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));
-
- /* Set the function pointers */
- this->OpenAudio = Mint_OpenAudio;
- this->CloseAudio = Mint_CloseAudio;
- this->LockAudio = Mint_LockAudio;
- this->UnlockAudio = Mint_UnlockAudio;
- this->free = Audio_DeleteDevice;
-
- return this;
-}
-
-AudioBootStrap MINTAUDIO_GSXB_bootstrap = {
- MINT_AUDIO_DRIVER_NAME, "MiNT GSXB audio driver",
- Audio_Available, Audio_CreateDevice
-};
-
-static void
-Mint_LockAudio(_THIS)
+MINTGSXB_LockDevice(_THIS)
{
/* Stop replay */
Buffoper(0);
}
static void
-Mint_UnlockAudio(_THIS)
+MINTGSXB_UnlockDevice(_THIS)
{
/* Restart replay */
Buffoper(SB_PLA_ENA | SB_PLA_RPT);
}
static void
-Mint_CloseAudio(_THIS)
+MINTGSXB_CloseDevice(_THIS)
{
- /* Stop replay */
- Buffoper(0);
+ if (this->hidden != NULL) {
+ /* Stop replay */
+ Buffoper(0);
- /* Uninstall interrupt */
- if (NSetinterrupt(2, SI_NONE, Mint_GsxbNullInterrupt) < 0) {
- DEBUG_PRINT((DEBUG_NAME "NSetinterrupt() failed in close\n"));
- }
+ /* Uninstall interrupt */
+ if (NSetinterrupt(2, SI_NONE, MINTGSXB_GsxbNullInterrupt) < 0) {
+ DEBUG_PRINT((DEBUG_NAME "NSetinterrupt() failed in close\n"));
+ }
- /* Wait if currently playing sound */
- while (SDL_MintAudio_mutex != 0) {
- }
+ /* Wait if currently playing sound */
+ while (SDL_MintAudio_mutex != 0) {}
- /* Clear buffers */
- if (SDL_MintAudio_audiobuf[0]) {
- Mfree(SDL_MintAudio_audiobuf[0]);
- SDL_MintAudio_audiobuf[0] = SDL_MintAudio_audiobuf[1] = NULL;
+ /* Clear buffers */
+ if (SDL_MintAudio_audiobuf[0]) {
+ Mfree(SDL_MintAudio_audiobuf[0]);
+ SDL_MintAudio_audiobuf[0] = SDL_MintAudio_audiobuf[1] = NULL;
+ }
+
+ /* Unlock sound system */
+ Unlocksnd();
+
+ SDL_free(this->hidden);
+ this->hidden = NULL;
}
-
- /* Unlock sound system */
- Unlocksnd();
}
static int
-Mint_CheckAudio(_THIS, SDL_AudioSpec * spec)
+MINTGSXB_CheckAudio(_THIS)
{
long snd_format;
int i, resolution, format_signed, format_bigendian;
- SDL_AudioFormat test_format = SDL_FirstAudioFormat(spec->format);
+ SDL_AudioFormat test_format = SDL_FirstAudioFormat(this->spec.format);
int valid_datatype = 0;
- resolution = SDL_AUDIO_BITSIZE(spec->format);
- format_signed = SDL_AUDIO_ISSIGNED(spec->format);
- format_bigendian = SDL_AUDIO_ISBIGENDIAN(spec->format);
+ resolution = SDL_AUDIO_BITSIZE(this->spec.format);
+ format_signed = SDL_AUDIO_ISSIGNED(this->spec.format);
+ format_bigendian = SDL_AUDIO_ISBIGENDIAN(this->spec.format);
DEBUG_PRINT((DEBUG_NAME "asked: %d bits, ", resolution));
- DEBUG_PRINT(("float=%d, ", SDL_AUDIO_ISFLOAT(spec->format)));
+ DEBUG_PRINT(("float=%d, ", SDL_AUDIO_ISFLOAT(this->spec.format)));
DEBUG_PRINT(("signed=%d, ", format_signed));
DEBUG_PRINT(("big endian=%d, ", format_bigendian));
- DEBUG_PRINT(("channels=%d, ", spec->channels));
- DEBUG_PRINT(("freq=%d\n", spec->freq));
+ DEBUG_PRINT(("channels=%d, ", this->spec.channels));
+ DEBUG_PRINT(("freq=%d\n", this->spec.freq));
- if (spec->channels > 2) {
- spec->channels = 2; /* no more than stereo! */
+ if (this->spec.channels > 2) {
+ this->spec.channels = 2; /* no more than stereo! */
}
while ((!valid_datatype) && (test_format)) {
/* Check formats available */
snd_format = Sndstatus(SND_QUERYFORMATS);
- spec->format = test_format;
- resolution = SDL_AUDIO_BITSIZE(spec->format);
- format_signed = SDL_AUDIO_ISSIGNED(spec->format);
- format_bigendian = SDL_AUDIO_ISBIGENDIAN(spec->format);
+ this->spec.format = test_format;
+ resolution = SDL_AUDIO_BITSIZE(this->spec.format);
+ format_signed = SDL_AUDIO_ISSIGNED(this->spec.format);
+ format_bigendian = SDL_AUDIO_ISBIGENDIAN(this->spec.format);
switch (test_format) {
case AUDIO_U8:
case AUDIO_S8:
@@ -279,14 +186,14 @@
/* Ok */
} else if (snd_format & SND_FORMATUNSIGNED) {
/* Give unsigned format */
- spec->format = spec->format & (~SDL_AUDIO_MASK_SIGNED);
+ this->spec.format = this->spec.format & (~SDL_AUDIO_MASK_SIGNED);
}
} else {
if (snd_format & SND_FORMATUNSIGNED) {
/* Ok */
} else if (snd_format & SND_FORMATSIGNED) {
/* Give signed format */
- spec->format |= SDL_AUDIO_MASK_SIGNED;
+ this->spec.format |= SDL_AUDIO_MASK_SIGNED;
}
}
@@ -295,14 +202,14 @@
/* Ok */
} else if (snd_format & SND_FORMATLITTLEENDIAN) {
/* Give little endian format */
- spec->format = spec->format & (~SDL_AUDIO_MASK_ENDIAN);
+ this->spec.format = this->spec.format & (~SDL_AUDIO_MASK_ENDIAN);
}
} else {
if (snd_format & SND_FORMATLITTLEENDIAN) {
/* Ok */
} else if (snd_format & SND_FORMATBIGENDIAN) {
/* Give big endian format */
- spec->format |= SDL_AUDIO_MASK_ENDIAN;
+ this->spec.format |= SDL_AUDIO_MASK_ENDIAN;
}
}
@@ -324,22 +231,22 @@
}
#endif
- MINTAUDIO_numfreq = SDL_MintAudio_SearchFrequency(this, spec->freq);
- spec->freq = MINTAUDIO_frequencies[MINTAUDIO_numfreq].frequency;
+ MINTAUDIO_numfreq = SDL_MintAudio_SearchFrequency(this, this->spec.freq);
+ this->spec.freq = MINTAUDIO_frequencies[MINTAUDIO_numfreq].frequency;
DEBUG_PRINT((DEBUG_NAME "obtained: %d bits, ",
- SDL_AUDIO_BITSIZE(spec->format)));
- DEBUG_PRINT(("float=%d, ", SDL_AUDIO_ISFLOAT(spec->format)));
- DEBUG_PRINT(("signed=%d, ", SDL_AUDIO_ISSIGNED(spec->format)));
- DEBUG_PRINT(("big endian=%d, ", SDL_AUDIO_ISBIGENDIAN(spec->format)));
- DEBUG_PRINT(("channels=%d, ", spec->channels));
- DEBUG_PRINT(("freq=%d\n", spec->freq));
+ SDL_AUDIO_BITSIZE(this->spec.format)));
+ DEBUG_PRINT(("float=%d, ", SDL_AUDIO_ISFLOAT(this->spec.format)));
+ DEBUG_PRINT(("signed=%d, ", SDL_AUDIO_ISSIGNED(this->spec.format)));
+ DEBUG_PRINT(("big endian=%d, ", SDL_AUDIO_ISBIGENDIAN(this->spec.format)));
+ DEBUG_PRINT(("channels=%d, ", this->spec.channels));
+ DEBUG_PRINT(("freq=%d\n", this->spec.freq));
return 0;
}
static void
-Mint_InitAudio(_THIS, SDL_AudioSpec * spec)
+MINTGSXB_InitAudio(_THIS)
{
int channels_mode, prediv;
void *buffer;
@@ -352,23 +259,23 @@
Setmontracks(0);
/* Select replay format */
- switch (SDL_AUDIO_BITSIZE(spec->format)) {
+ switch (SDL_AUDIO_BITSIZE(this->spec.format)) {
case 8:
- if (spec->channels == 2) {
+ if (this->spec.channels == 2) {
channels_mode = STEREO8;
} else {
channels_mode = MONO8;
}
break;
case 16:
- if (spec->channels == 2) {
+ if (this->spec.channels == 2) {
channels_mode = STEREO16;
} else {
channels_mode = MONO16;
}
break;
case 32:
- if (spec->channels == 2) {
+ if (this->spec.channels == 2) {
channels_mode = STEREO32;
} else {
channels_mode = MONO32;
@@ -387,12 +294,12 @@
/* Set buffer */
buffer = SDL_MintAudio_audiobuf[SDL_MintAudio_numbuf];
- if (Setbuffer(0, buffer, buffer + spec->size) < 0) {
+ if (Setbuffer(0, buffer, buffer + this->spec.size) < 0) {
DEBUG_PRINT((DEBUG_NAME "Setbuffer() failed\n"));
}
/* Install interrupt */
- if (NSetinterrupt(2, SI_PLAY, Mint_GsxbInterrupt) < 0) {
+ if (NSetinterrupt(2, SI_PLAY, MINTGSXB_GsxbInterrupt) < 0) {
DEBUG_PRINT((DEBUG_NAME "NSetinterrupt() failed\n"));
}
@@ -402,35 +309,46 @@
}
static int
-Mint_OpenAudio(_THIS, SDL_AudioSpec * spec)
+MINTGSXB_OpenDevice(_THIS, const char *devname, int iscapture)
{
/* Lock sound system */
if (Locksnd() != 1) {
- SDL_SetError("Mint_OpenAudio: Audio system already in use");
- return (-1);
+ SDL_SetError("MINTGSXB_OpenDevice: Audio system already in use");
+ return 0;
}
SDL_MintAudio_device = this;
/* Check audio capabilities */
- if (Mint_CheckAudio(this, spec) == -1) {
- return -1;
+ if (MINTGSXB_CheckAudio(this) == -1) {
+ return 0;
}
- SDL_CalculateAudioSpec(spec);
+ /* Initialize all variables that we clean on shutdown */
+ this->hidden = (struct SDL_PrivateAudioData *)
+ SDL_malloc((sizeof *this->hidden));
+ if (this->hidden == NULL) {
+ SDL_OutOfMemory();
+ return 0;
+ }
+ SDL_memset(this->hidden, 0, (sizeof *this->hidden));
+
+ SDL_CalculateAudioSpec(&this->spec);
/* Allocate memory for audio buffers in DMA-able RAM */
- DEBUG_PRINT((DEBUG_NAME "buffer size=%d\n", spec->size));
+ DEBUG_PRINT((DEBUG_NAME "buffer size=%d\n", this->spec.size));
- SDL_MintAudio_audiobuf[0] = Atari_SysMalloc(spec->size * 2, MX_STRAM);
+ SDL_MintAudio_audiobuf[0] = Atari_SysMalloc(this->spec.size * 2, MX_STRAM);
if (SDL_MintAudio_audiobuf[0] == NULL) {
- SDL_SetError("MINT_OpenAudio: Not enough memory for audio buffer");
- return (-1);
+ SDL_free(this->hidden);
+ this->hidden = NULL;
+ SDL_OutOfMemory();
+ return 0;
}
- SDL_MintAudio_audiobuf[1] = SDL_MintAudio_audiobuf[0] + spec->size;
+ SDL_MintAudio_audiobuf[1] = SDL_MintAudio_audiobuf[0] + this->spec.size;
SDL_MintAudio_numbuf = 0;
- SDL_memset(SDL_MintAudio_audiobuf[0], spec->silence, spec->size * 2);
- SDL_MintAudio_audiosize = spec->size;
+ SDL_memset(SDL_MintAudio_audiobuf[0],this->spec.silence,this->spec.size*2);
+ SDL_MintAudio_audiosize = this->spec.size;
SDL_MintAudio_mutex = 0;
DEBUG_PRINT((DEBUG_NAME "buffer 0 at 0x%08x\n",
@@ -441,13 +359,13 @@
SDL_MintAudio_CheckFpu();
/* Setup audio hardware */
- Mint_InitAudio(this, spec);
+ MINTGSXB_InitAudio(this);
- return (1); /* We don't use threaded audio */
+ return 1; /* good to go. */
}
static void
-Mint_GsxbInterrupt(void)
+MINTGSXB_GsxbInterrupt(void)
{
Uint8 *newbuf;
@@ -465,8 +383,57 @@
}
static void
-Mint_GsxbNullInterrupt(void)
+MINTGSXB_GsxbNullInterrupt(void)
{
}
+static int
+MINTGSXB_Init(SDL_AudioDriverImpl *impl)
+{
+ /* Cookie _SND present ? if not, assume ST machine */
+ if (Getcookie(C__SND, &cookie_snd) == C_NOTFOUND) {
+ cookie_snd = SND_PSG;
+ }
+
+ /* Check if we have 16 bits audio */
+ if ((cookie_snd & SND_16BIT) == 0) {
+ SDL_SetError(DEBUG_NAME "no 16-bit sound");
+ return 0;
+ }
+
+ /* Cookie GSXB present ? */
+ cookie_gsxb = (Getcookie(C_GSXB, &cookie_gsxb) == C_FOUND);
+
+ /* Is it GSXB ? */
+ if (((cookie_snd & SND_GSXB) == 0) || (cookie_gsxb == 0)) {
+ SDL_SetError(DEBUG_NAME "no GSXB audio");
+ return 0;
+ }
+
+ /* Check if audio is lockable */
+ if (Locksnd() != 1) {
+ SDL_SetError(DEBUG_NAME "audio locked by other application");
+ return 0;
+ }
+
+ Unlocksnd();
+
+ DEBUG_PRINT((DEBUG_NAME "GSXB audio available!\n"));
+
+ /* Set the function pointers */
+ impl->OpenDevice = MINTGSXB_OpenDevice;
+ impl->CloseDevice = MINTGSXB_CloseDevice;
+ impl->LockAudio = MINTGSXB_LockAudio;
+ impl->UnlockAudio = MINTGSXB_UnlockAudio;
+ impl->OnlyHasDefaultOutputDevice = 1;
+ impl->ProvidesOwnCallbackThread = 1;
+ impl->SkipMixerLock = 1;
+
+ return 1;
+}
+
+AudioBootStrap MINTAUDIO_GSXB_bootstrap = {
+ MINT_AUDIO_DRIVER_NAME, "MiNT GSXB audio driver", MINTGSXB_Init, 0
+};
+
/* vi: set ts=4 sw=4 expandtab: */
--- a/src/audio/mint/SDL_mintaudio_mcsn.c Sun Oct 01 16:10:41 2006 +0000
+++ b/src/audio/mint/SDL_mintaudio_mcsn.c Tue Oct 17 09:15:21 2006 +0000
@@ -61,192 +61,82 @@
/*--- Static variables ---*/
-static unsigned long cookie_snd, cookie_mch;
-static cookie_mcsn_t *cookie_mcsn;
-
-/*--- Audio driver functions ---*/
-
-static void Mint_CloseAudio(_THIS);
-static int Mint_OpenAudio(_THIS, SDL_AudioSpec * spec);
-static void Mint_LockAudio(_THIS);
-static void Mint_UnlockAudio(_THIS);
-
-/* To check/init hardware audio */
-static int Mint_CheckAudio(_THIS, SDL_AudioSpec * spec);
-static void Mint_InitAudio(_THIS, SDL_AudioSpec * spec);
-
-/*--- Audio driver bootstrap functions ---*/
-
-static int
-Audio_Available(void)
-{
- unsigned long dummy;
- const char *envr = SDL_getenv("SDL_AUDIODRIVER");
-
- SDL_MintAudio_mint_present = (Getcookie(C_MiNT, &dummy) == C_FOUND);
-
- /* We can't use XBIOS in interrupt with Magic, don't know about thread */
- if (Getcookie(C_MagX, &dummy) == C_FOUND) {
- return (0);
- }
-
- /* Check if user asked a different audio driver */
- if ((envr) && (SDL_strcmp(envr, MINT_AUDIO_DRIVER_NAME) != 0)) {
- DEBUG_PRINT((DEBUG_NAME "user asked a different audio driver\n"));
- return (0);
- }
-
- /* Cookie _MCH present ? if not, assume ST machine */
- if (Getcookie(C__MCH, &cookie_mch) == C_NOTFOUND) {
- cookie_mch = MCH_ST;
- }
-
- /* Cookie _SND present ? if not, assume ST machine */
- if (Getcookie(C__SND, &cookie_snd) == C_NOTFOUND) {
- cookie_snd = SND_PSG;
- }
-
- /* Check if we have 16 bits audio */
- if ((cookie_snd & SND_16BIT) == 0) {
- DEBUG_PRINT((DEBUG_NAME "no 16 bits sound\n"));
- return (0);
- }
-
- /* Cookie MCSN present ? */
- if (Getcookie(C_McSn, (long *) &cookie_mcsn) != C_FOUND) {
- DEBUG_PRINT((DEBUG_NAME "no MCSN audio\n"));
- return (0);
- }
-
- /* Check if interrupt at end of replay */
- if (cookie_mcsn->pint == 0) {
- DEBUG_PRINT((DEBUG_NAME "no interrupt at end of replay\n"));
- return (0);
- }
-
- /* Check if audio is lockable */
- if (Locksnd() != 1) {
- DEBUG_PRINT((DEBUG_NAME "audio locked by other application\n"));
- return (0);
- }
-
- Unlocksnd();
-
- DEBUG_PRINT((DEBUG_NAME "MCSN audio available!\n"));
- return (1);
-}
+static unsigned long cookie_snd = 0;
+static unsigned long cookie_mch = 0;
+static cookie_mcsn_t *cookie_mcsn = NULL;
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));
-
- /* Set the function pointers */
- this->OpenAudio = Mint_OpenAudio;
- this->CloseAudio = Mint_CloseAudio;
- this->LockAudio = Mint_LockAudio;
- this->UnlockAudio = Mint_UnlockAudio;
- this->free = Audio_DeleteDevice;
-
- return this;
-}
-
-AudioBootStrap MINTAUDIO_MCSN_bootstrap = {
- MINT_AUDIO_DRIVER_NAME, "MiNT MCSN audio driver",
- Audio_Available, Audio_CreateDevice
-};
-
-static void
-Mint_LockAudio(_THIS)
+MINTMCSN_LockDevice(_THIS)
{
/* Stop replay */
Buffoper(0);
}
static void
-Mint_UnlockAudio(_THIS)
+MINTMCSN_UnlockDevice(_THIS)
{
/* Restart replay */
Buffoper(SB_PLA_ENA | SB_PLA_RPT);
}
static void
-Mint_CloseAudio(_THIS)
+MINTMCSN_CloseDevice(_THIS)
{
- /* Stop replay */
- SDL_MintAudio_WaitThread();
- Buffoper(0);
+ if (this->hidden != NULL) {
+ /* Stop replay */
+ SDL_MintAudio_WaitThread();
+ Buffoper(0);
- if (!SDL_MintAudio_mint_present) {
- /* Uninstall interrupt */
- Jdisint(MFP_DMASOUND);
- }
+ if (!SDL_MintAudio_mint_present) {
+ /* Uninstall interrupt */
+ Jdisint(MFP_DMASOUND);
+ }
- /* Wait if currently playing sound */
- while (SDL_MintAudio_mutex != 0) {
- }
+ /* Wait if currently playing sound */
+ while (SDL_MintAudio_mutex != 0) {}
- /* Clear buffers */
- if (SDL_MintAudio_audiobuf[0]) {
- Mfree(SDL_MintAudio_audiobuf[0]);
- SDL_MintAudio_audiobuf[0] = SDL_MintAudio_audiobuf[1] = NULL;
+ /* Clear buffers */
+ if (SDL_MintAudio_audiobuf[0]) {
+ Mfree(SDL_MintAudio_audiobuf[0]);
+ SDL_MintAudio_audiobuf[0] = SDL_MintAudio_audiobuf[1] = NULL;
+ }
+
+ /* Unlock sound system */
+ Unlocksnd();
+
+ SDL_free(this->hidden);
+ this->hidden = NULL;
}
-
- /* Unlock sound system */
- Unlocksnd();
}
static int
-Mint_CheckAudio(_THIS, SDL_AudioSpec * spec)
+MINTMCSN_CheckAudio(_THIS)
{
int i;
unsigned long masterclock, masterprediv;
DEBUG_PRINT((DEBUG_NAME "asked: %d bits, ",
- SDL_AUDIO_BITSIZE(spec->format)));
- DEBUG_PRINT(("float=%d, ", SDL_AUDIO_ISFLOAT(spec->format)));
- DEBUG_PRINT(("signed=%d, ", SDL_AUDIO_ISSIGNED(spec->format)));
- DEBUG_PRINT(("big endian=%d, ", SDL_AUDIO_ISBIGENDIAN(spec->format)));
- DEBUG_PRINT(("channels=%d, ", spec->channels));
- DEBUG_PRINT(("freq=%d\n", spec->freq));
+ SDL_AUDIO_BITSIZE(this->spec.format)));
+ DEBUG_PRINT(("float=%d, ", SDL_AUDIO_ISFLOAT(this->spec.format)));
+ DEBUG_PRINT(("signed=%d, ", SDL_AUDIO_ISSIGNED(this->spec.format)));
+ DEBUG_PRINT(("big endian=%d, ", SDL_AUDIO_ISBIGENDIAN(this->spec.format)));
+ DEBUG_PRINT(("channels=%d, ", this->spec.channels));
+ DEBUG_PRINT(("freq=%d\n", this->spec.freq));
- if (spec->channels > 2) {
- spec->channels = 2; /* no more than stereo! */
+ if (this->spec.channels > 2) {
+ this->spec.channels = 2; /* no more than stereo! */
}
/* Check formats available */
MINTAUDIO_freqcount = 0;
switch (cookie_mcsn->play) {
case MCSN_ST:
- spec->channels = 1;
- spec->format = AUDIO_S8; /* FIXME: is it signed or unsigned ? */
+ this->spec.channels = 1;
+ this->spec.format = AUDIO_S8; /* FIXME: is it signed or unsigned ? */
SDL_MintAudio_AddFrequency(this, 12500, 0, 0, -1);
break;
case MCSN_TT: /* Also STE, Mega STE */
- spec->format = AUDIO_S8;
+ this->spec.format = AUDIO_S8;
masterclock = MASTERCLOCK_STE;
masterprediv = MASTERPREDIV_STE;
if ((cookie_mch >> 16) == MCH_TT) {
@@ -280,10 +170,10 @@
(1 << i) - 1, -1);
}
}
- spec->format |= SDL_AUDIO_MASK_SIGNED; /* Audio is always signed */
- if ((SDL_AUDIO_BITSIZE(spec->format)) == 16) {
- spec->format |= SDL_AUDIO_MASK_ENDIAN; /* Audio is always big endian */
- spec->channels = 2; /* 16 bits always stereo */
+ this->spec.format |= SDL_AUDIO_MASK_SIGNED; /* Audio is always signed */
+ if ((SDL_AUDIO_BITSIZE(this->spec.format)) == 16) {
+ this->spec.format |= SDL_AUDIO_MASK_ENDIAN; /* Audio is always big endian */
+ this->spec.channels = 2; /* 16 bits always stereo */
}
break;
}
@@ -297,22 +187,22 @@
}
#endif
- MINTAUDIO_numfreq = SDL_MintAudio_SearchFrequency(this, spec->freq);
- spec->freq = MINTAUDIO_frequencies[MINTAUDIO_numfreq].frequency;
+ MINTAUDIO_numfreq = SDL_MintAudio_SearchFrequency(this, this->spec.freq);
+ this->spec.freq = MINTAUDIO_frequencies[MINTAUDIO_numfreq].frequency;
DEBUG_PRINT((DEBUG_NAME "obtained: %d bits, ",
- SDL_AUDIO_BITSIZE(spec->format)));
- DEBUG_PRINT(("float=%d, ", SDL_AUDIO_ISFLOAT(spec->format)));
- DEBUG_PRINT(("signed=%d, ", SDL_AUDIO_ISSIGNED(spec->format)));
- DEBUG_PRINT(("big endian=%d, ", SDL_AUDIO_ISBIGENDIAN(spec->format)));
- DEBUG_PRINT(("channels=%d, ", spec->channels));
- DEBUG_PRINT(("freq=%d\n", spec->freq));
+ SDL_AUDIO_BITSIZE(this->spec.format)));
+ DEBUG_PRINT(("float=%d, ", SDL_AUDIO_ISFLOAT(this->spec.format)));
+ DEBUG_PRINT(("signed=%d, ", SDL_AUDIO_ISSIGNED(this->spec.format)));
+ DEBUG_PRINT(("big endian=%d, ", SDL_AUDIO_ISBIGENDIAN(this->spec.format)));
+ DEBUG_PRINT(("channels=%d, ", this->spec.channels));
+ DEBUG_PRINT(("freq=%d\n", this->spec.freq));
return 0;
}
static void
-Mint_InitAudio(_THIS, SDL_AudioSpec * spec)
+MINTMCSN_InitAudio(_THIS)
{
int channels_mode, prediv, dmaclock;
void *buffer;
@@ -329,9 +219,9 @@
/* Select replay format */
channels_mode = STEREO16;
- switch (SDL_AUDIO_BITSIZE(spec->format)) {
+ switch (SDL_AUDIO_BITSIZE(this->spec.format)) {
case 8:
- if (spec->channels == 2) {
+ if (this->spec.channels == 2) {
channels_mode = STEREO8;
} else {
channels_mode = MONO8;
@@ -358,7 +248,7 @@
/* Set buffer */
buffer = SDL_MintAudio_audiobuf[SDL_MintAudio_numbuf];
- if (Setbuffer(0, buffer, buffer + spec->size) < 0) {
+ if (Setbuffer(0, buffer, buffer + this->spec.size) < 0) {
DEBUG_PRINT((DEBUG_NAME "Setbuffer() failed\n"));
}
@@ -381,35 +271,46 @@
}
static int
-Mint_OpenAudio(_THIS, SDL_AudioSpec * spec)
+MINTMCSN_OpenDevice(_THIS, const char *devname, int iscapture)
{
/* Lock sound system */
if (Locksnd() != 1) {
- SDL_SetError("Mint_OpenAudio: Audio system already in use");
- return (-1);
+ SDL_SetError("MINTMCSN_OpenDevice: Audio system already in use");
+ return 0;
}
SDL_MintAudio_device = this;
/* Check audio capabilities */
- if (Mint_CheckAudio(this, spec) == -1) {
- return -1;
+ if (MINTMCSN_CheckAudio(this) == -1) {
+ return 0;
}
- SDL_CalculateAudioSpec(spec);
+ /* Initialize all variables that we clean on shutdown */
+ this->hidden = (struct SDL_PrivateAudioData *)
+ SDL_malloc((sizeof *this->hidden));
+ if (this->hidden == NULL) {
+ SDL_OutOfMemory();
+ return 0;
+ }
+ SDL_memset(this->hidden, 0, (sizeof *this->hidden));
+
+ SDL_CalculateAudioSpec(&this->spec);
/* Allocate memory for audio buffers in DMA-able RAM */
- DEBUG_PRINT((DEBUG_NAME "buffer size=%d\n", spec->size));
+ DEBUG_PRINT((DEBUG_NAME "buffer size=%d\n", this->spec.size));
- SDL_MintAudio_audiobuf[0] = Atari_SysMalloc(spec->size * 2, MX_STRAM);
+ SDL_MintAudio_audiobuf[0] = Atari_SysMalloc(this->spec.size * 2, MX_STRAM);
if (SDL_MintAudio_audiobuf[0] == NULL) {
- SDL_SetError("MINT_OpenAudio: Not enough memory for audio buffer");
- return (-1);
+ SDL_free(this->hidden);
+ this->hidden = NULL;
+ SDL_OutOfMemory();
+ return 0;
}
- SDL_MintAudio_audiobuf[1] = SDL_MintAudio_audiobuf[0] + spec->size;
+ SDL_MintAudio_audiobuf[1] = SDL_MintAudio_audiobuf[0] + this->spec.size;
SDL_MintAudio_numbuf = 0;
- SDL_memset(SDL_MintAudio_audiobuf[0], spec->silence, spec->size * 2);
- SDL_MintAudio_audiosize = spec->size;
+ SDL_memset(SDL_MintAudio_audiobuf[0],this->spec.silence,this->spec.size*2);
+ SDL_MintAudio_audiosize = this->spec.size;
SDL_MintAudio_mutex = 0;
DEBUG_PRINT((DEBUG_NAME "buffer 0 at 0x%08x\n",
@@ -420,9 +321,75 @@
SDL_MintAudio_CheckFpu();
/* Setup audio hardware */
- Mint_InitAudio(this, spec);
+ MINTMCSN_InitAudio(this);
- return (1); /* We don't use SDL threaded audio */
+ return 1; /* good to go. */
}
+static int
+MINTMCSN_Init(SDL_AudioDriverImpl *impl)
+{
+ unsigned long dummy = 0;
+
+ SDL_MintAudio_mint_present = (Getcookie(C_MiNT, &dummy) == C_FOUND);
+
+ /* We can't use XBIOS in interrupt with Magic, don't know about thread */
+ if (Getcookie(C_MagX, &dummy) == C_FOUND) {
+ return 0;
+ }
+
+ /* Cookie _MCH present ? if not, assume ST machine */
+ if (Getcookie(C__MCH, &cookie_mch) == C_NOTFOUND) {
+ cookie_mch = MCH_ST;
+ }
+
+ /* Cookie _SND present ? if not, assume ST machine */
+ if (Getcookie(C__SND, &cookie_snd) == C_NOTFOUND) {
+ cookie_snd = SND_PSG;
+ }
+
+ /* Check if we have 16 bits audio */
+ if ((cookie_snd & SND_16BIT) == 0) {
+ SDL_SetError(DEBUG_NAME "no 16-bit sound");
+ return 0;
+ }
+
+ /* Cookie MCSN present ? */
+ if (Getcookie(C_McSn, (long *) &cookie_mcsn) != C_FOUND) {
+ SDL_SetError(DEBUG_NAME "no MCSN audio");
+ return 0;
+ }
+
+ /* Check if interrupt at end of replay */
+ if (cookie_mcsn->pint == 0) {
+ SDL_SetError(DEBUG_NAME "no interrupt at end of replay");
+ return 0;
+ }
+
+ /* Check if audio is lockable */
+ if (Locksnd() != 1) {
+ SDL_SetError(DEBUG_NAME "audio locked by other application");
+ return 0;
+ }
+
+ Unlocksnd();
+
+ DEBUG_PRINT((DEBUG_NAME "MCSN audio available!\n"));
+
+ /* Set the function pointers */
+ impl->OpenDevice = MINTMCSN_OpenDevice;
+ impl->CloseDevice = MINTMCSN_CloseDevice;
+ impl->LockAudio = MINTMCSN_LockAudio;
+ impl->UnlockAudio = MINTMCSN_UnlockAudio;
+ impl->OnlyHasDefaultOutputDevice = 1;
+ impl->ProvidesOwnCallbackThread = 1;
+ impl->SkipMixerLock = 1;
+
+ return 1;
+}
+
+AudioBootStrap MINTAUDIO_MCSN_bootstrap = {
+ MINT_AUDIO_DRIVER_NAME, "MiNT MCSN audio driver", MINTMCSN_Init, 0
+};
+
/* vi: set ts=4 sw=4 expandtab: */
--- a/src/audio/mint/SDL_mintaudio_stfa.c Sun Oct 01 16:10:41 2006 +0000
+++ b/src/audio/mint/SDL_mintaudio_stfa.c Tue Oct 17 09:15:21 2006 +0000
@@ -59,8 +59,9 @@
/*--- Static variables ---*/