Date: Sun, 29 Feb 2004 15:14:22 +0200
From: Martin_Storsj Subject: Dynamic loading of ALSA I recently discovered that SDL can dynamically load ESD and aRts, and made a patch which adds this same functionality to ALSA. The update for configure.in isn't too good (it should e.g. look for libasound.so in other directories than /usr/lib), because I'm not too good at shellscripting and autoconf. The reason for using dlfcn.h and dlopen instead of SDL_LoadLibrary and SDL_LoadFunction is that libasound uses versioned symbols, and it is necessary to load the correct version using dlvsym. This isn't probably any real portability issue, because ALSA is linux-only. --HG-- extra : convert_revision : svn%3Ac70aab31-4412-0410-b14c-859654838e24/trunk%40866
This commit is contained in:
parent
a58dea0f76
commit
710da3b0ba
3 changed files with 150 additions and 25 deletions
18
configure.in
18
configure.in
|
@ -295,8 +295,22 @@ CheckALSA()
|
||||||
AC_CHECK_LIB(asound, snd_pcm_open, have_alsa=yes)
|
AC_CHECK_LIB(asound, snd_pcm_open, have_alsa=yes)
|
||||||
])
|
])
|
||||||
if test x$have_alsa = xyes; then
|
if test x$have_alsa = xyes; then
|
||||||
CFLAGS="$CFLAGS -DALSA_SUPPORT"
|
AC_ARG_ENABLE(alsa-shared,
|
||||||
SYSTEM_LIBS="$SYSTEM_LIBS -lasound"
|
[ --enable-alsa-shared dynamically load ALSA audio support [default=yes]],
|
||||||
|
, enable_alsa_shared=yes)
|
||||||
|
alsa_lib=`ls /usr/lib/libasound.so.* | head -1 | sed 's/.*\/\(.*\)/\1/'`
|
||||||
|
if test x$use_dlopen != xyes && \
|
||||||
|
test x$enable_alsa_shared = xyes; then
|
||||||
|
AC_MSG_ERROR([You must have dlopen() support and use the --enable-dlopen option])
|
||||||
|
fi
|
||||||
|
if test x$use_dlopen = xyes && \
|
||||||
|
test x$enable_alsa_shared = xyes && test x$alsa_lib != x; then
|
||||||
|
CFLAGS="$CFLAGS -DALSA_SUPPORT -DALSA_DYNAMIC=\$(alsa_lib)"
|
||||||
|
AC_SUBST(alsa_lib)
|
||||||
|
else
|
||||||
|
CFLAGS="$CFLAGS -DALSA_SUPPORT"
|
||||||
|
SYSTEM_LIBS="$SYSTEM_LIBS -lasound"
|
||||||
|
fi
|
||||||
AUDIO_SUBDIRS="$AUDIO_SUBDIRS alsa"
|
AUDIO_SUBDIRS="$AUDIO_SUBDIRS alsa"
|
||||||
AUDIO_DRIVERS="$AUDIO_DRIVERS alsa/libaudio_alsa.la"
|
AUDIO_DRIVERS="$AUDIO_DRIVERS alsa/libaudio_alsa.la"
|
||||||
else
|
else
|
||||||
|
|
|
@ -4,6 +4,8 @@
|
||||||
noinst_LTLIBRARIES = libaudio_alsa.la
|
noinst_LTLIBRARIES = libaudio_alsa.la
|
||||||
libaudio_alsa_la_SOURCES = $(SRCS)
|
libaudio_alsa_la_SOURCES = $(SRCS)
|
||||||
|
|
||||||
|
alsa_lib = \"@alsa_lib@\"
|
||||||
|
|
||||||
# The SDL audio driver sources
|
# The SDL audio driver sources
|
||||||
SRCS = SDL_alsa_audio.c \
|
SRCS = SDL_alsa_audio.c \
|
||||||
SDL_alsa_audio.h
|
SDL_alsa_audio.h
|
||||||
|
|
|
@ -41,6 +41,16 @@
|
||||||
#include "SDL_timer.h"
|
#include "SDL_timer.h"
|
||||||
#include "SDL_alsa_audio.h"
|
#include "SDL_alsa_audio.h"
|
||||||
|
|
||||||
|
#ifdef ALSA_DYNAMIC
|
||||||
|
#define __USE_GNU
|
||||||
|
#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 */
|
/* The tag name used by ALSA audio */
|
||||||
#define DRIVER_NAME "alsa"
|
#define DRIVER_NAME "alsa"
|
||||||
|
|
||||||
|
@ -54,6 +64,99 @@ static void ALSA_PlayAudio(_THIS);
|
||||||
static Uint8 *ALSA_GetAudioBuf(_THIS);
|
static Uint8 *ALSA_GetAudioBuf(_THIS);
|
||||||
static void ALSA_CloseAudio(_THIS);
|
static void ALSA_CloseAudio(_THIS);
|
||||||
|
|
||||||
|
#ifdef ALSA_DYNAMIC
|
||||||
|
|
||||||
|
static const char *alsa_library = ALSA_DYNAMIC;
|
||||||
|
static void *alsa_handle = NULL;
|
||||||
|
static int alsa_loaded = 0;
|
||||||
|
|
||||||
|
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 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 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))(snd_pcm_t *pcm, snd_pcm_hw_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)
|
||||||
|
|
||||||
|
static struct {
|
||||||
|
const char *name;
|
||||||
|
void **func;
|
||||||
|
} alsa_functions[] = {
|
||||||
|
{ "snd_pcm_open", (void**)&SDL_NAME(snd_pcm_open) },
|
||||||
|
{ "snd_pcm_close", (void**)&SDL_NAME(snd_pcm_close) },
|
||||||
|
{ "snd_pcm_writei", (void**)&SDL_NAME(snd_pcm_writei) },
|
||||||
|
{ "snd_pcm_resume", (void**)&SDL_NAME(snd_pcm_resume) },
|
||||||
|
{ "snd_pcm_prepare", (void**)&SDL_NAME(snd_pcm_prepare) },
|
||||||
|
{ "snd_pcm_drain", (void**)&SDL_NAME(snd_pcm_drain) },
|
||||||
|
{ "snd_strerror", (void**)&SDL_NAME(snd_strerror) },
|
||||||
|
{ "snd_pcm_hw_params_sizeof", (void**)&SDL_NAME(snd_pcm_hw_params_sizeof) },
|
||||||
|
{ "snd_pcm_hw_params_any", (void**)&SDL_NAME(snd_pcm_hw_params_any) },
|
||||||
|
{ "snd_pcm_hw_params_set_access", (void**)&SDL_NAME(snd_pcm_hw_params_set_access) },
|
||||||
|
{ "snd_pcm_hw_params_set_format", (void**)&SDL_NAME(snd_pcm_hw_params_set_format) },
|
||||||
|
{ "snd_pcm_hw_params_set_channels", (void**)&SDL_NAME(snd_pcm_hw_params_set_channels) },
|
||||||
|
{ "snd_pcm_hw_params_get_channels", (void**)&SDL_NAME(snd_pcm_hw_params_get_channels) },
|
||||||
|
{ "snd_pcm_hw_params_set_rate_near", (void**)&SDL_NAME(snd_pcm_hw_params_set_rate_near) },
|
||||||
|
{ "snd_pcm_hw_params_set_period_size_near", (void**)&SDL_NAME(snd_pcm_hw_params_set_period_size_near) },
|
||||||
|
{ "snd_pcm_hw_params_set_periods_near", (void**)&SDL_NAME(snd_pcm_hw_params_set_periods_near) },
|
||||||
|
{ "snd_pcm_hw_params", (void**)&SDL_NAME(snd_pcm_hw_params) },
|
||||||
|
{ "snd_pcm_nonblock", (void**)&SDL_NAME(snd_pcm_nonblock) },
|
||||||
|
};
|
||||||
|
|
||||||
|
static void UnloadALSALibrary(void) {
|
||||||
|
if (alsa_loaded) {
|
||||||
|
/* SDL_UnloadObject(alsa_handle);*/
|
||||||
|
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_TABLESIZE(alsa_functions); i++) {
|
||||||
|
/* *alsa_functions[i].func = SDL_LoadFunction(alsa_handle,alsa_functions[i].name);*/
|
||||||
|
*alsa_functions[i].func = dlvsym(alsa_handle,alsa_functions[i].name,"ALSA_0.9");
|
||||||
|
if (!*alsa_functions[i].func) {
|
||||||
|
retval = -1;
|
||||||
|
UnloadALSALibrary();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
static void UnloadALSALibrary(void) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int LoadALSALibrary(void) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* ALSA_DYNAMIC */
|
||||||
|
|
||||||
static const char *get_audio_device()
|
static const char *get_audio_device()
|
||||||
{
|
{
|
||||||
const char *device;
|
const char *device;
|
||||||
|
@ -74,11 +177,15 @@ static int Audio_Available(void)
|
||||||
snd_pcm_t *handle;
|
snd_pcm_t *handle;
|
||||||
|
|
||||||
available = 0;
|
available = 0;
|
||||||
status = snd_pcm_open(&handle, get_audio_device(), SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK);
|
if (LoadALSALibrary() < 0) {
|
||||||
|
return available;
|
||||||
|
}
|
||||||
|
status = SDL_NAME(snd_pcm_open)(&handle, get_audio_device(), SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK);
|
||||||
if ( status >= 0 ) {
|
if ( status >= 0 ) {
|
||||||
available = 1;
|
available = 1;
|
||||||
snd_pcm_close(handle);
|
SDL_NAME(snd_pcm_close)(handle);
|
||||||
}
|
}
|
||||||
|
UnloadALSALibrary();
|
||||||
return(available);
|
return(available);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -86,6 +193,7 @@ static void Audio_DeleteDevice(SDL_AudioDevice *device)
|
||||||
{
|
{
|
||||||
free(device->hidden);
|
free(device->hidden);
|
||||||
free(device);
|
free(device);
|
||||||
|
UnloadALSALibrary();
|
||||||
}
|
}
|
||||||
|
|
||||||
static SDL_AudioDevice *Audio_CreateDevice(int devindex)
|
static SDL_AudioDevice *Audio_CreateDevice(int devindex)
|
||||||
|
@ -93,6 +201,7 @@ static SDL_AudioDevice *Audio_CreateDevice(int devindex)
|
||||||
SDL_AudioDevice *this;
|
SDL_AudioDevice *this;
|
||||||
|
|
||||||
/* Initialize all variables that we clean on shutdown */
|
/* Initialize all variables that we clean on shutdown */
|
||||||
|
LoadALSALibrary();
|
||||||
this = (SDL_AudioDevice *)malloc(sizeof(SDL_AudioDevice));
|
this = (SDL_AudioDevice *)malloc(sizeof(SDL_AudioDevice));
|
||||||
if ( this ) {
|
if ( this ) {
|
||||||
memset(this, 0, (sizeof *this));
|
memset(this, 0, (sizeof *this));
|
||||||
|
@ -150,7 +259,7 @@ static void ALSA_PlayAudio(_THIS)
|
||||||
sample_len = this->spec.samples;
|
sample_len = this->spec.samples;
|
||||||
sample_buf = (signed short *)mixbuf;
|
sample_buf = (signed short *)mixbuf;
|
||||||
while ( sample_len > 0 ) {
|
while ( sample_len > 0 ) {
|
||||||
status = snd_pcm_writei(pcm_handle, sample_buf, sample_len);
|
status = SDL_NAME(snd_pcm_writei)(pcm_handle, sample_buf, sample_len);
|
||||||
if ( status < 0 ) {
|
if ( status < 0 ) {
|
||||||
if ( status == -EAGAIN ) {
|
if ( status == -EAGAIN ) {
|
||||||
SDL_Delay(1);
|
SDL_Delay(1);
|
||||||
|
@ -159,11 +268,11 @@ static void ALSA_PlayAudio(_THIS)
|
||||||
if ( status == -ESTRPIPE ) {
|
if ( status == -ESTRPIPE ) {
|
||||||
do {
|
do {
|
||||||
SDL_Delay(1);
|
SDL_Delay(1);
|
||||||
status = snd_pcm_resume(pcm_handle);
|
status = SDL_NAME(snd_pcm_resume)(pcm_handle);
|
||||||
} while ( status == -EAGAIN );
|
} while ( status == -EAGAIN );
|
||||||
}
|
}
|
||||||
if ( status < 0 ) {
|
if ( status < 0 ) {
|
||||||
status = snd_pcm_prepare(pcm_handle);
|
status = SDL_NAME(snd_pcm_prepare)(pcm_handle);
|
||||||
}
|
}
|
||||||
if ( status < 0 ) {
|
if ( status < 0 ) {
|
||||||
/* Hmm, not much we can do - abort */
|
/* Hmm, not much we can do - abort */
|
||||||
|
@ -189,8 +298,8 @@ static void ALSA_CloseAudio(_THIS)
|
||||||
mixbuf = NULL;
|
mixbuf = NULL;
|
||||||
}
|
}
|
||||||
if ( pcm_handle ) {
|
if ( pcm_handle ) {
|
||||||
snd_pcm_drain(pcm_handle);
|
SDL_NAME(snd_pcm_drain)(pcm_handle);
|
||||||
snd_pcm_close(pcm_handle);
|
SDL_NAME(snd_pcm_close)(pcm_handle);
|
||||||
pcm_handle = NULL;
|
pcm_handle = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -204,25 +313,25 @@ static int ALSA_OpenAudio(_THIS, SDL_AudioSpec *spec)
|
||||||
Uint16 test_format;
|
Uint16 test_format;
|
||||||
|
|
||||||
/* Open the audio device */
|
/* Open the audio device */
|
||||||
status = snd_pcm_open(&pcm_handle, get_audio_device(), SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK);
|
status = SDL_NAME(snd_pcm_open)(&pcm_handle, get_audio_device(), SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK);
|
||||||
if ( status < 0 ) {
|
if ( status < 0 ) {
|
||||||
SDL_SetError("Couldn't open audio device: %s", snd_strerror(status));
|
SDL_SetError("Couldn't open audio device: %s", SDL_NAME(snd_strerror)(status));
|
||||||
return(-1);
|
return(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Figure out what the hardware is capable of */
|
/* Figure out what the hardware is capable of */
|
||||||
snd_pcm_hw_params_alloca(¶ms);
|
snd_pcm_hw_params_alloca(¶ms);
|
||||||
status = snd_pcm_hw_params_any(pcm_handle, params);
|
status = SDL_NAME(snd_pcm_hw_params_any)(pcm_handle, params);
|
||||||
if ( status < 0 ) {
|
if ( status < 0 ) {
|
||||||
SDL_SetError("Couldn't get hardware config: %s", snd_strerror(status));
|
SDL_SetError("Couldn't get hardware config: %s", SDL_NAME(snd_strerror)(status));
|
||||||
ALSA_CloseAudio(this);
|
ALSA_CloseAudio(this);
|
||||||
return(-1);
|
return(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* SDL only uses interleaved sample output */
|
/* SDL only uses interleaved sample output */
|
||||||
status = snd_pcm_hw_params_set_access(pcm_handle, params, SND_PCM_ACCESS_RW_INTERLEAVED);
|
status = SDL_NAME(snd_pcm_hw_params_set_access)(pcm_handle, params, SND_PCM_ACCESS_RW_INTERLEAVED);
|
||||||
if ( status < 0 ) {
|
if ( status < 0 ) {
|
||||||
SDL_SetError("Couldn't set interleaved access: %s", snd_strerror(status));
|
SDL_SetError("Couldn't set interleaved access: %s", SDL_NAME(snd_strerror)(status));
|
||||||
ALSA_CloseAudio(this);
|
ALSA_CloseAudio(this);
|
||||||
return(-1);
|
return(-1);
|
||||||
}
|
}
|
||||||
|
@ -255,7 +364,7 @@ static int ALSA_OpenAudio(_THIS, SDL_AudioSpec *spec)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if ( format != 0 ) {
|
if ( format != 0 ) {
|
||||||
status = snd_pcm_hw_params_set_format(pcm_handle, params, format);
|
status = SDL_NAME(snd_pcm_hw_params_set_format)(pcm_handle, params, format);
|
||||||
}
|
}
|
||||||
if ( status < 0 ) {
|
if ( status < 0 ) {
|
||||||
test_format = SDL_NextAudioFormat();
|
test_format = SDL_NextAudioFormat();
|
||||||
|
@ -269,9 +378,9 @@ static int ALSA_OpenAudio(_THIS, SDL_AudioSpec *spec)
|
||||||
spec->format = test_format;
|
spec->format = test_format;
|
||||||
|
|
||||||
/* Set the number of channels */
|
/* Set the number of channels */
|
||||||
status = snd_pcm_hw_params_set_channels(pcm_handle, params, spec->channels);
|
status = SDL_NAME(snd_pcm_hw_params_set_channels)(pcm_handle, params, spec->channels);
|
||||||
if ( status < 0 ) {
|
if ( status < 0 ) {
|
||||||
status = snd_pcm_hw_params_get_channels(params);
|
status = SDL_NAME(snd_pcm_hw_params_get_channels)(params);
|
||||||
if ( (status <= 0) || (status > 2) ) {
|
if ( (status <= 0) || (status > 2) ) {
|
||||||
SDL_SetError("Couldn't set audio channels");
|
SDL_SetError("Couldn't set audio channels");
|
||||||
ALSA_CloseAudio(this);
|
ALSA_CloseAudio(this);
|
||||||
|
@ -281,9 +390,9 @@ static int ALSA_OpenAudio(_THIS, SDL_AudioSpec *spec)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set the audio rate */
|
/* Set the audio rate */
|
||||||
status = snd_pcm_hw_params_set_rate_near(pcm_handle, params, spec->freq, NULL);
|
status = SDL_NAME(snd_pcm_hw_params_set_rate_near)(pcm_handle, params, spec->freq, NULL);
|
||||||
if ( status < 0 ) {
|
if ( status < 0 ) {
|
||||||
SDL_SetError("Couldn't set audio frequency: %s", snd_strerror(status));
|
SDL_SetError("Couldn't set audio frequency: %s", SDL_NAME(snd_strerror)(status));
|
||||||
ALSA_CloseAudio(this);
|
ALSA_CloseAudio(this);
|
||||||
return(-1);
|
return(-1);
|
||||||
}
|
}
|
||||||
|
@ -291,14 +400,14 @@ static int ALSA_OpenAudio(_THIS, SDL_AudioSpec *spec)
|
||||||
|
|
||||||
/* Set the buffer size, in samples */
|
/* Set the buffer size, in samples */
|
||||||
frames = spec->samples;
|
frames = spec->samples;
|
||||||
frames = snd_pcm_hw_params_set_period_size_near(pcm_handle, params, frames, NULL);
|
frames = SDL_NAME(snd_pcm_hw_params_set_period_size_near)(pcm_handle, params, frames, NULL);
|
||||||
spec->samples = frames;
|
spec->samples = frames;
|
||||||
snd_pcm_hw_params_set_periods_near(pcm_handle, params, 2, NULL);
|
SDL_NAME(snd_pcm_hw_params_set_periods_near)(pcm_handle, params, 2, NULL);
|
||||||
|
|
||||||
/* "set" the hardware with the desired parameters */
|
/* "set" the hardware with the desired parameters */
|
||||||
status = snd_pcm_hw_params(pcm_handle, params);
|
status = SDL_NAME(snd_pcm_hw_params)(pcm_handle, params);
|
||||||
if ( status < 0 ) {
|
if ( status < 0 ) {
|
||||||
SDL_SetError("Couldn't set audio parameters: %s", snd_strerror(status));
|
SDL_SetError("Couldn't set audio parameters: %s", SDL_NAME(snd_strerror)(status));
|
||||||
ALSA_CloseAudio(this);
|
ALSA_CloseAudio(this);
|
||||||
return(-1);
|
return(-1);
|
||||||
}
|
}
|
||||||
|
@ -319,7 +428,7 @@ static int ALSA_OpenAudio(_THIS, SDL_AudioSpec *spec)
|
||||||
parent = getpid();
|
parent = getpid();
|
||||||
|
|
||||||
/* Switch to blocking mode for playback */
|
/* Switch to blocking mode for playback */
|
||||||
snd_pcm_nonblock(pcm_handle, 0);
|
SDL_NAME(snd_pcm_nonblock)(pcm_handle, 0);
|
||||||
|
|
||||||
/* We're ready to rock and roll. :-) */
|
/* We're ready to rock and roll. :-) */
|
||||||
return(0);
|
return(0);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue