From 928a8ce1af0f63edb5498f927d09eb48832fdba1 Mon Sep 17 00:00:00 2001 From: Glenn Maynard Date: Mon, 3 Nov 2003 21:52:31 +0000 Subject: [PATCH] Dynamically bind ALSA, so binaries compiled with ALSA will work on systems without ALSA installed. --- stepmania/src/arch/Sound/ALSA9Dynamic.cpp | 59 +++++++ stepmania/src/arch/Sound/ALSA9Dynamic.h | 23 +++ stepmania/src/arch/Sound/ALSA9Functions.h | 49 +++++ stepmania/src/arch/Sound/ALSA9Helpers.cpp | 167 +++++++++--------- stepmania/src/arch/Sound/ALSA9Helpers.h | 1 + .../src/arch/Sound/RageSoundDriver_ALSA9.cpp | 7 + .../Sound/RageSoundDriver_ALSA9_Software.cpp | 7 + 7 files changed, 227 insertions(+), 86 deletions(-) create mode 100644 stepmania/src/arch/Sound/ALSA9Dynamic.cpp create mode 100644 stepmania/src/arch/Sound/ALSA9Dynamic.h create mode 100644 stepmania/src/arch/Sound/ALSA9Functions.h diff --git a/stepmania/src/arch/Sound/ALSA9Dynamic.cpp b/stepmania/src/arch/Sound/ALSA9Dynamic.cpp new file mode 100644 index 0000000000..dcb1c3a30c --- /dev/null +++ b/stepmania/src/arch/Sound/ALSA9Dynamic.cpp @@ -0,0 +1,59 @@ +#include "global.h" + +#include + +#define ALSA_PCM_NEW_HW_PARAMS_API +#define ALSA_PCM_NEW_SW_PARAMS_API +#include + +static void *Handle = NULL; + +#include "RageUtil.h" +#include "ALSA9Dynamic.h" + +/* foo_f dfoo = NULL */ +#define FUNC(ret, name, proto) name##_f d##name = NULL +#include "ALSA9Functions.h" +#undef FUNC + +static const CString lib = "libasound.so.2"; +CString LoadALSA() +{ + ASSERT( Handle == NULL ); + + Handle = dlopen( lib, RTLD_NOW ); + if( Handle == NULL ) + return ssprintf("dlopen(%s): %s", lib.c_str(), dlerror()); + + CString error; + /* Eww. The "new" HW and SW API functions are really prefixed by __, + * eg. __snd_pcm_hw_params_set_rate_near. */ +#define FUNC(ret, name, proto) \ + d##name = (name##_f) dlsym(Handle, "__" #name); \ + if( !d##name ) { \ + d##name = (name##_f) dlsym(Handle, #name); \ + if( !d##name ) { \ + error="Couldn't load symbol " #name; \ + goto error; \ + } \ + } +#include "ALSA9Functions.h" +#undef FUNC + + return ""; +error: + UnloadALSA(); + if( Handle ) + dlclose( Handle ); + Handle = NULL; + return error; +} + +void UnloadALSA() +{ + dlclose( Handle ); +#define FUNC(ret, name, proto) d##name = NULL; +#include "ALSA9Functions.h" +#undef FUNC +} + diff --git a/stepmania/src/arch/Sound/ALSA9Dynamic.h b/stepmania/src/arch/Sound/ALSA9Dynamic.h new file mode 100644 index 0000000000..e0a98e57e3 --- /dev/null +++ b/stepmania/src/arch/Sound/ALSA9Dynamic.h @@ -0,0 +1,23 @@ +#ifndef ALSA9_DYNAMIC_H + +#include + +/* typedef int (*foo_f)(char c) */ +#define FUNC(ret, name, proto) typedef ret (*name##_f) proto +#include "ALSA9Functions.h" +#undef FUNC + +/* extern foo_f dfoo */ +#define FUNC(ret, name, proto) extern name##_f d##name +#include "ALSA9Functions.h" +#undef FUNC + +#define dsnd_pcm_hw_params_alloca(ptr) { assert(ptr); *ptr = (snd_pcm_hw_params_t *) alloca(dsnd_pcm_hw_params_sizeof()); memset(*ptr, 0, dsnd_pcm_hw_params_sizeof()); } +#define dsnd_pcm_sw_params_alloca(ptr) { assert(ptr); *ptr = (snd_pcm_sw_params_t *) alloca(dsnd_pcm_sw_params_sizeof()); memset(*ptr, 0, dsnd_pcm_sw_params_sizeof()); } +#define dsnd_pcm_info_alloca(ptr) { assert(ptr); *ptr = (snd_pcm_info_t *) alloca(dsnd_pcm_info_sizeof()); memset(*ptr, 0, dsnd_pcm_info_sizeof()); } +#define dsnd_ctl_card_info_alloca(ptr) { assert(ptr); *ptr = (snd_ctl_card_info_t *) alloca(dsnd_ctl_card_info_sizeof()); memset(*ptr, 0, dsnd_ctl_card_info_sizeof()); } + +CString LoadALSA(); +void UnloadALSA(); + +#endif diff --git a/stepmania/src/arch/Sound/ALSA9Functions.h b/stepmania/src/arch/Sound/ALSA9Functions.h new file mode 100644 index 0000000000..adae2f4254 --- /dev/null +++ b/stepmania/src/arch/Sound/ALSA9Functions.h @@ -0,0 +1,49 @@ +FUNC(size_t, snd_pcm_hw_params_sizeof, (void)); +FUNC(size_t, snd_pcm_sw_params_sizeof, (void)); +FUNC(size_t, snd_pcm_info_sizeof, (void)); +FUNC(size_t, snd_ctl_card_info_sizeof, (void)); +FUNC(int, snd_ctl_card_info, (snd_ctl_t *ctl, snd_ctl_card_info_t *info)); +FUNC(int, snd_card_next, (int *card)); +FUNC(const char *, snd_ctl_card_info_get_id, (const snd_ctl_card_info_t *obj)); +FUNC(const char *, snd_ctl_card_info_get_name, (const snd_ctl_card_info_t *obj)); +FUNC(snd_pcm_state_t, snd_pcm_state, (snd_pcm_t *pcm)); +FUNC(const char *,snd_strerror, (int errnum)); +FUNC(int, snd_ctl_close, (snd_ctl_t *ctl)); +FUNC(int, snd_ctl_open, (snd_ctl_t **ctl, const char *name, int mode)); +FUNC(int, snd_lib_error_set_handler, (snd_lib_error_handler_t handler)); +FUNC(int, snd_output_buffer_open, (snd_output_t **outputp)); +FUNC(size_t, snd_output_buffer_string, (snd_output_t *output, char **buf)); +FUNC(int, snd_output_close, (snd_output_t *output)); +FUNC(int, snd_output_flush, (snd_output_t *output)); +FUNC(snd_pcm_sframes_t, snd_pcm_avail_update, (snd_pcm_t *pcm)); +FUNC(int, snd_pcm_close, (snd_pcm_t *pcm)); +FUNC(int, snd_pcm_delay, (snd_pcm_t *pcm, snd_pcm_sframes_t *delayp)); +FUNC(int, snd_pcm_drop, (snd_pcm_t *pcm)); +FUNC(int, snd_pcm_dump, (snd_pcm_t *pcm, snd_output_t *out)); +FUNC(snd_pcm_sframes_t, snd_pcm_forward, (snd_pcm_t *pcm, snd_pcm_uframes_t frames)); +FUNC(int, snd_pcm_hw_free, (snd_pcm_t *pcm)); +FUNC(int, snd_pcm_hw_params, (snd_pcm_t *pcm, snd_pcm_hw_params_t *params)); +FUNC(int, snd_pcm_hw_params_any, (snd_pcm_t *pcm, snd_pcm_hw_params_t *params)); +FUNC(int, snd_pcm_hw_params_set_access, (snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_access_t access)); +FUNC(int, snd_pcm_hw_params_set_channels, (snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int val)); +FUNC(int, snd_pcm_hw_params_set_format, (snd_pcm_t *pcm, snd_pcm_hw_params_t *params, snd_pcm_format_t val)); +FUNC(int, snd_pcm_hw_params_set_rate_near, (snd_pcm_t *pcm, snd_pcm_hw_params_t *params, unsigned int *val, int *dir)); +FUNC(int, snd_pcm_hwsync, (snd_pcm_t *pcm)); +FUNC(int, snd_ctl_pcm_next_device, (snd_ctl_t *ctl, int *device)); +FUNC(int, snd_ctl_pcm_info, (snd_ctl_t *ctl, snd_pcm_info_t * info)); +FUNC(const char *,snd_pcm_info_get_id, (const snd_pcm_info_t *obj)); +FUNC(const char *, snd_pcm_info_get_name, (const snd_pcm_info_t *obj)); +FUNC(unsigned int, snd_pcm_info_get_subdevices_avail, (const snd_pcm_info_t *obj)); +FUNC(unsigned int, snd_pcm_info_get_subdevices_count, (const snd_pcm_info_t *obj)); +FUNC(void, snd_pcm_info_set_device, (snd_pcm_info_t *obj, unsigned int val)); +FUNC(void, snd_pcm_info_set_stream, (snd_pcm_info_t *obj, snd_pcm_stream_t val)); +FUNC(snd_pcm_sframes_t, snd_pcm_mmap_writei, (snd_pcm_t *pcm, const void *buffer, snd_pcm_uframes_t size)); +FUNC(int, snd_pcm_open, (snd_pcm_t **pcm, const char *name, snd_pcm_stream_t stream, int mode)); +FUNC(int, snd_pcm_prepare, (snd_pcm_t *pcm)); +FUNC(int, snd_pcm_resume, (snd_pcm_t *pcm)); +FUNC(int, snd_pcm_sw_params, (snd_pcm_t *pcm, snd_pcm_sw_params_t *params)); +FUNC(int, snd_pcm_sw_params_current, (snd_pcm_t *pcm, snd_pcm_sw_params_t *params)); +FUNC(int, snd_pcm_sw_params_get_boundary, (const snd_pcm_sw_params_t *params, snd_pcm_uframes_t *val)); +FUNC(int, snd_pcm_sw_params_get_xfer_align, (const snd_pcm_sw_params_t *params, snd_pcm_uframes_t *val)); +FUNC(int, snd_pcm_sw_params_set_stop_threshold, (snd_pcm_t *pcm, snd_pcm_sw_params_t *params, snd_pcm_uframes_t val)); + diff --git a/stepmania/src/arch/Sound/ALSA9Helpers.cpp b/stepmania/src/arch/Sound/ALSA9Helpers.cpp index 84a09be021..0a35e21aae 100644 --- a/stepmania/src/arch/Sound/ALSA9Helpers.cpp +++ b/stepmania/src/arch/Sound/ALSA9Helpers.cpp @@ -3,60 +3,61 @@ #include "RageUtil.h" #include "ALSA9Helpers.h" #include "SDL_utils.h" +#include "ALSA9Dynamic.h" /* int err; must be defined before using this macro */ #define ALSA_CHECK(x) \ - if ( err < 0 ) { LOG->Info("ALSA9: %s: %s (%i)", x, snd_strerror(err), err); return false; } + if ( err < 0 ) { LOG->Info("ALSA9: %s: %s (%i)", x, dsnd_strerror(err), err); return false; } #define ALSA_ASSERT(x) \ - if (err < 0) { LOG->Trace("RageSound_ALSA9: ASSERT %s: %s (%i)", x, snd_strerror(err), err); } + if (err < 0) { LOG->Trace("ALSA9: %s: %s (%i)", x, dsnd_strerror(err), err); } bool Alsa9Buf::SetHWParams() { int err; - if( snd_pcm_state(pcm) == SND_PCM_STATE_PREPARED ) - snd_pcm_drop( pcm ); + if( dsnd_pcm_state(pcm) == SND_PCM_STATE_PREPARED ) + dsnd_pcm_drop( pcm ); - if( snd_pcm_state(pcm) != SND_PCM_STATE_OPEN ) + if( dsnd_pcm_state(pcm) != SND_PCM_STATE_OPEN ) { /* Reset the stream to SND_PCM_STATE_OPEN. */ - err = snd_pcm_hw_free( pcm ); - ALSA_ASSERT("snd_pcm_hw_free"); + err = dsnd_pcm_hw_free( pcm ); + ALSA_ASSERT("dsnd_pcm_hw_free"); } -// RAGE_ASSERT_M( snd_pcm_state(pcm) == SND_PCM_STATE_OPEN, ssprintf("(%s)", snd_pcm_state_name(snd_pcm_state(pcm))) ); +// RAGE_ASSERT_M( dsnd_pcm_state(pcm) == SND_PCM_STATE_OPEN, ssprintf("(%s)", dsnd_pcm_state_name(dsnd_pcm_state(pcm))) ); /* allocate the hardware parameters structure */ snd_pcm_hw_params_t *hwparams; - snd_pcm_hw_params_alloca( &hwparams ); + dsnd_pcm_hw_params_alloca( &hwparams ); - err = snd_pcm_hw_params_any(pcm, hwparams); - ALSA_CHECK("snd_pcm_hw_params_any"); + err = dsnd_pcm_hw_params_any(pcm, hwparams); + ALSA_CHECK("dsnd_pcm_hw_params_any"); /* set to mmap mode (with channels interleaved) */ - err = snd_pcm_hw_params_set_access(pcm, hwparams, SND_PCM_ACCESS_MMAP_INTERLEAVED); - ALSA_CHECK("snd_pcm_hw_params_set_access"); + err = dsnd_pcm_hw_params_set_access(pcm, hwparams, SND_PCM_ACCESS_MMAP_INTERLEAVED); + ALSA_CHECK("dsnd_pcm_hw_params_set_access"); /* set PCM format (signed 16bit, little endian) */ - err = snd_pcm_hw_params_set_format(pcm, hwparams, SND_PCM_FORMAT_S16_LE); - ALSA_CHECK("snd_pcm_hw_params_set_format"); + err = dsnd_pcm_hw_params_set_format(pcm, hwparams, SND_PCM_FORMAT_S16_LE); + ALSA_CHECK("dsnd_pcm_hw_params_set_format"); /* set number of channels */ - err = snd_pcm_hw_params_set_channels(pcm, hwparams, 2); - ALSA_CHECK("snd_pcm_hw_params_set_channels"); + err = dsnd_pcm_hw_params_set_channels(pcm, hwparams, 2); + ALSA_CHECK("dsnd_pcm_hw_params_set_channels"); if( samplerate != Alsa9Buf::DYNAMIC_SAMPLERATE ) { unsigned int rate = samplerate; - err = snd_pcm_hw_params_set_rate_near(pcm, hwparams, &rate, 0); - ALSA_CHECK("snd_pcm_hw_params_set_rate_near"); + err = dsnd_pcm_hw_params_set_rate_near(pcm, hwparams, &rate, 0); + ALSA_CHECK("dsnd_pcm_hw_params_set_rate_near"); if( (int) rate != samplerate ) LOG->Warn("Alsa9Buf::SetHWParams: Couldn't get %ihz (got %ihz instead)", samplerate, rate); } /* write the hardware parameters to the device */ - err = snd_pcm_hw_params(pcm, hwparams); - ALSA_CHECK("snd_pcm_hw_params"); + err = dsnd_pcm_hw_params( pcm, hwparams ); + ALSA_CHECK("dsnd_pcm_hw_params"); return true; } @@ -69,52 +70,52 @@ void Alsa9Buf::GetSoundCardDebugInfo() done = true; int card = -1; - while( snd_card_next( &card ) >= 0 && card >= 0 ) + while( dsnd_card_next( &card ) >= 0 && card >= 0 ) { const CString id = ssprintf( "hw:%d", card ); snd_ctl_t *handle; int err; - err = snd_ctl_open( &handle, id, 0 ); - ALSA_ASSERT("snd_pcm_sw_params_set_stop_threshold"); + err = dsnd_ctl_open( &handle, id, 0 ); + ALSA_ASSERT("dsnd_pcm_sw_params_set_stop_threshold"); if ( err < 0 ) { - LOG->Info( "Couldn't open card #%i (\"%s\"): %s", card, id.c_str(), snd_strerror(err) ); + LOG->Info( "Couldn't open card #%i (\"%s\"): %s", card, id.c_str(), dsnd_strerror(err) ); continue; } snd_ctl_card_info_t *info; - snd_ctl_card_info_alloca(&info); - err = snd_ctl_card_info( handle, info ); + dsnd_ctl_card_info_alloca(&info); + err = dsnd_ctl_card_info( handle, info ); if ( err < 0 ) { - LOG->Info( "Couldn't get card info for card #%i (\"%s\"): %s", card, id.c_str(), snd_strerror(err) ); - snd_ctl_close( handle ); + LOG->Info( "Couldn't get card info for card #%i (\"%s\"): %s", card, id.c_str(), dsnd_strerror(err) ); + dsnd_ctl_close( handle ); continue; } int dev = -1; - while ( snd_ctl_pcm_next_device( handle, &dev ) >= 0 && dev >= 0 ) + while ( dsnd_ctl_pcm_next_device( handle, &dev ) >= 0 && dev >= 0 ) { snd_pcm_info_t *pcminfo; - snd_pcm_info_alloca(&pcminfo); - snd_pcm_info_set_device(pcminfo, dev); - snd_pcm_info_set_stream(pcminfo, SND_PCM_STREAM_PLAYBACK); + dsnd_pcm_info_alloca(&pcminfo); + dsnd_pcm_info_set_device(pcminfo, dev); + dsnd_pcm_info_set_stream(pcminfo, SND_PCM_STREAM_PLAYBACK); - err = snd_ctl_pcm_info(handle, pcminfo); + err = dsnd_ctl_pcm_info(handle, pcminfo); if ( err < 0 ) { if (err != -ENOENT) - LOG->Info("snd_ctl_pcm_info(%i) (%s) failed: %s", card, id.c_str(), snd_strerror(err)); + LOG->Info("dsnd_ctl_pcm_info(%i) (%s) failed: %s", card, id.c_str(), dsnd_strerror(err)); continue; } LOG->Info( "ALSA Driver: %i: %s [%s], device %i: %s [%s], %i/%i subdevices avail", - card, snd_ctl_card_info_get_name(info), snd_ctl_card_info_get_id(info), dev, - snd_pcm_info_get_id(pcminfo), snd_pcm_info_get_name(pcminfo), - snd_pcm_info_get_subdevices_avail(pcminfo), - snd_pcm_info_get_subdevices_count(pcminfo) ); + card, dsnd_ctl_card_info_get_name(info), dsnd_ctl_card_info_get_id(info), dev, + dsnd_pcm_info_get_id(pcminfo), dsnd_pcm_info_get_name(pcminfo), + dsnd_pcm_info_get_subdevices_avail(pcminfo), + dsnd_pcm_info_get_subdevices_count(pcminfo) ); - snd_ctl_close(handle); + dsnd_ctl_close(handle); } } @@ -131,7 +132,7 @@ Alsa9Buf::Alsa9Buf( hw hardware, int channels_, int samplerate_ ) { GetSoundCardDebugInfo(); - snd_lib_error_set_handler( ErrorHandler ); + dsnd_lib_error_set_handler( ErrorHandler ); channels = channels_; samplerate = samplerate_; @@ -140,62 +141,56 @@ Alsa9Buf::Alsa9Buf( hw hardware, int channels_, int samplerate_ ) /* Open the device. */ int err; -// err = snd_pcm_open( &pcm, "dmix", SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK ); - err = snd_pcm_open( &pcm, "default", SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK ); +// err = dsnd_pcm_open( &pcm, "dmix", SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK ); + err = dsnd_pcm_open( &pcm, "default", SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK ); if (err < 0) - RageException::ThrowNonfatal("snd_pcm_open: %s", snd_strerror(err)); + RageException::ThrowNonfatal("dsnd_pcm_open: %s", dsnd_strerror(err)); if( !SetHWParams() ) { - snd_pcm_close(pcm); + CHECKPOINT; + dsnd_pcm_close(pcm); + CHECKPOINT; RageException::ThrowNonfatal( "SetHWParams failed" ); } snd_pcm_sw_params_t *swparams; - snd_pcm_sw_params_alloca( &swparams ); - snd_pcm_sw_params_current( pcm, swparams ); + dsnd_pcm_sw_params_alloca( &swparams ); + dsnd_pcm_sw_params_current( pcm, swparams ); - xfer_align = snd_pcm_sw_params_get_xfer_align( swparams ); + err = dsnd_pcm_sw_params_get_xfer_align( swparams, &xfer_align ); + /* If this fails, we might have bound dsnd_pcm_sw_params_get_xfer_align to + * the old SW API. */ + ASSERT( err <= 0 ); + ALSA_ASSERT("dsnd_pcm_sw_params_get_xfer_align"); /* Disable SND_PCM_STATE_XRUN. */ snd_pcm_uframes_t boundary = 0; - err = snd_pcm_sw_params_get_boundary( swparams, &boundary ); - ALSA_ASSERT("snd_pcm_sw_params_get_boundary"); + err = dsnd_pcm_sw_params_get_boundary( swparams, &boundary ); + ALSA_ASSERT("dsnd_pcm_sw_params_get_boundary"); if( err == 0 ) { - err = snd_pcm_sw_params_set_stop_threshold( pcm, swparams, boundary ); - ALSA_ASSERT("snd_pcm_sw_params_set_stop_threshold"); - err = snd_pcm_sw_params(pcm, swparams); - ALSA_ASSERT("snd_pcm_sw_params"); + err = dsnd_pcm_sw_params_set_stop_threshold( pcm, swparams, boundary ); + ALSA_ASSERT("dsnd_pcm_sw_params_set_stop_threshold"); + err = dsnd_pcm_sw_params(pcm, swparams); + ALSA_ASSERT("dsnd_pcm_sw_params"); } - err = snd_pcm_prepare(pcm); - ALSA_ASSERT("snd_pcm_prepare"); + err = dsnd_pcm_prepare(pcm); + ALSA_ASSERT("dsnd_pcm_prepare"); - - /* prepare a snd_output_t for use with LOG->Trace */ - /* snd_output_t *errout = NULL; - snd_output_buffer_open(&errout); - snd_pcm_dump(pcm, errout); - snd_output_flush(errout); - - char *errstring; - snd_output_buffer_string(errout, &errstring); - LOG->Trace("%s", errstring); - snd_output_close( errout ); -*/ - total_frames = snd_pcm_avail_update(pcm); + total_frames = dsnd_pcm_avail_update(pcm); } Alsa9Buf::~Alsa9Buf() { - snd_pcm_close(pcm); + dsnd_pcm_close(pcm); } int Alsa9Buf::GetNumFramesToFill( int writeahead ) { - snd_pcm_sframes_t avail_frames = snd_pcm_avail_update(pcm); + snd_pcm_sframes_t avail_frames = dsnd_pcm_avail_update(pcm); if( avail_frames > total_frames ) { @@ -212,16 +207,16 @@ int Alsa9Buf::GetNumFramesToFill( int writeahead ) /* It's a large skip. Catch up. If we fall too far behind, the sound thread will * be decoding as fast as it can, which will steal too many cycles from the rendering * thread. */ - snd_pcm_forward( pcm, size ); + dsnd_pcm_forward( pcm, size ); } } if( avail_frames < 0 && Recover(avail_frames) ) - avail_frames = snd_pcm_avail_update(pcm); + avail_frames = dsnd_pcm_avail_update(pcm); if( avail_frames < 0 ) { - LOG->Trace( "RageSoundDriver_ALSA9::GetData: snd_pcm_avail_update: %s", snd_strerror(avail_frames) ); + LOG->Trace( "RageSoundDriver_ALSA9::GetData: dsnd_pcm_avail_update: %s", dsnd_strerror(avail_frames) ); return 0; } @@ -236,10 +231,10 @@ int Alsa9Buf::GetNumFramesToFill( int writeahead ) void Alsa9Buf::Write( const Sint16 *buffer, int frames ) { /* We should be able to write it all. If we don't, treat it as an error. */ - int wrote = snd_pcm_mmap_writei( pcm, (const char *) buffer, frames ); + int wrote = dsnd_pcm_mmap_writei( pcm, (const char *) buffer, frames ); if( wrote < 0 ) { - LOG->Trace( "RageSoundDriver_ALSA9::GetData: snd_pcm_mmap_writei: %s (%i)", snd_strerror(wrote), wrote ); + LOG->Trace( "RageSoundDriver_ALSA9::GetData: dsnd_pcm_mmap_writei: %s (%i)", dsnd_strerror(wrote), wrote ); return; } @@ -259,8 +254,8 @@ bool Alsa9Buf::Recover( int r ) if( r == -EPIPE ) { LOG->Trace("RageSound_ALSA9::Recover (prepare)"); - int err = snd_pcm_prepare(pcm); - ALSA_ASSERT("snd_pcm_prepare (Recover)"); + int err = dsnd_pcm_prepare(pcm); + ALSA_ASSERT("dsnd_pcm_prepare (Recover)"); return true; } @@ -268,10 +263,10 @@ bool Alsa9Buf::Recover( int r ) { LOG->Trace("RageSound_ALSA9::Recover (resume)"); int err; - while ((err = snd_pcm_resume(pcm)) == -EAGAIN) + while ((err = dsnd_pcm_resume(pcm)) == -EAGAIN) SDL_Delay(10); - ALSA_ASSERT("snd_pcm_resume (Recover)"); + ALSA_ASSERT("dsnd_pcm_resume (Recover)"); return true; } @@ -280,17 +275,17 @@ bool Alsa9Buf::Recover( int r ) int Alsa9Buf::GetPosition() const { - if( snd_pcm_state(pcm) == SND_PCM_STATE_PREPARED ) + if( dsnd_pcm_state(pcm) == SND_PCM_STATE_PREPARED ) { LOG->Trace("???"); return 0; } - snd_pcm_hwsync( pcm ); + dsnd_pcm_hwsync( pcm ); /* delay is returned in frames */ snd_pcm_sframes_t delay; - int err = snd_pcm_delay( pcm, &delay ); + int err = dsnd_pcm_delay( pcm, &delay ); return last_cursor_pos - delay; } @@ -309,8 +304,8 @@ void Alsa9Buf::Play() void Alsa9Buf::Stop() { - snd_pcm_drop( pcm ); - snd_pcm_prepare( pcm ); + dsnd_pcm_drop( pcm ); + dsnd_pcm_prepare( pcm ); } void Alsa9Buf::SetSampleRate(int hz) @@ -319,6 +314,6 @@ void Alsa9Buf::SetSampleRate(int hz) SetHWParams(); - snd_pcm_prepare( pcm ); + dsnd_pcm_prepare( pcm ); } diff --git a/stepmania/src/arch/Sound/ALSA9Helpers.h b/stepmania/src/arch/Sound/ALSA9Helpers.h index 484e2ecc0c..ed18e61b0a 100644 --- a/stepmania/src/arch/Sound/ALSA9Helpers.h +++ b/stepmania/src/arch/Sound/ALSA9Helpers.h @@ -2,6 +2,7 @@ #define ALSA9_HELPERS_H #define ALSA_PCM_NEW_HW_PARAMS_API +#define ALSA_PCM_NEW_SW_PARAMS_API #include #include "SDL_types.h" diff --git a/stepmania/src/arch/Sound/RageSoundDriver_ALSA9.cpp b/stepmania/src/arch/Sound/RageSoundDriver_ALSA9.cpp index 51ae91187a..798c066445 100644 --- a/stepmania/src/arch/Sound/RageSoundDriver_ALSA9.cpp +++ b/stepmania/src/arch/Sound/RageSoundDriver_ALSA9.cpp @@ -5,6 +5,7 @@ #include "RageSound.h" #include "RageSoundManager.h" #include "RageUtil.h" +#include "ALSA9Dynamic.h" const int channels = 2; const int samplerate = 44100; @@ -210,6 +211,10 @@ int RageSound_ALSA9::GetPosition(const RageSound *snd) const RageSound_ALSA9::RageSound_ALSA9() { + CString err = LoadALSA(); + if( err != "" ) + RageException::ThrowNonfatal("Driver unusable: %s", err.c_str()); + shutdown = false; /* Create a bunch of streams and put them into the stream pool. */ @@ -256,6 +261,8 @@ RageSound_ALSA9::~RageSound_ALSA9() for(unsigned i = 0; i < stream_pool.size(); ++i) delete stream_pool[i]; + + UnloadALSA(); } /* diff --git a/stepmania/src/arch/Sound/RageSoundDriver_ALSA9_Software.cpp b/stepmania/src/arch/Sound/RageSoundDriver_ALSA9_Software.cpp index 85025f5ad6..06581a01cc 100644 --- a/stepmania/src/arch/Sound/RageSoundDriver_ALSA9_Software.cpp +++ b/stepmania/src/arch/Sound/RageSoundDriver_ALSA9_Software.cpp @@ -6,6 +6,7 @@ #include "RageSoundManager.h" #include "RageUtil.h" #include "RageTimer.h" +#include "ALSA9Dynamic.h" #include #include @@ -179,6 +180,10 @@ static void GetKernel( CString &sys, int &vers ) RageSound_ALSA9_Software::RageSound_ALSA9_Software() { + CString err = LoadALSA(); + if( err != "" ) + RageException::ThrowNonfatal("Driver unusable: %s", err.c_str()); + shutdown = false; max_writeahead = safe_writeahead; @@ -204,6 +209,8 @@ RageSound_ALSA9_Software::~RageSound_ALSA9_Software() LOG->Trace("Mixer thread shut down."); delete pcm; + + UnloadALSA(); } float RageSound_ALSA9_Software::GetPlayLatency() const