diff --git a/alsa.c b/alsa.c index 4cfdd7bbb8..6161b79454 100644 --- a/alsa.c +++ b/alsa.c @@ -27,6 +27,7 @@ typedef struct alsa { snd_pcm_t *pcm; + bool nonblock; } alsa_t; static void* __alsa_init(const char* device, int rate, int latency) @@ -125,7 +126,8 @@ static ssize_t __alsa_write(void* data, const void* buf, size_t size) return size; } - + else if ( alsa->nonblock && frames == -EAGAIN ) + return 0; else if ( frames < 0 ) return -1; @@ -134,11 +136,16 @@ static ssize_t __alsa_write(void* data, const void* buf, size_t size) static bool __alsa_stop(void *data) { -/* int *fd = data; - ioctl(*fd, SNDCTL_DSP_RESET, 0);*/ return true; } +static void __alsa_set_nonblock_state(void *data, bool state) +{ + alsa_t *alsa = data; + snd_pcm_nonblock(alsa->pcm, state); + alsa->nonblock = state; +} + static bool __alsa_start(void *data) { return true; @@ -163,6 +170,7 @@ const audio_driver_t audio_alsa = { .write = __alsa_write, .stop = __alsa_stop, .start = __alsa_start, + .set_nonblock_state = __alsa_set_nonblock_state, .free = __alsa_free }; diff --git a/config.h b/config.h index b0eaea102b..0ebed708cf 100644 --- a/config.h +++ b/config.h @@ -39,7 +39,7 @@ // Chooses which video and audio subsystem to use. Remember to update config.mk if you change these. #define VIDEO_DRIVER VIDEO_GL -#define AUDIO_DRIVER AUDIO_RSOUND +#define AUDIO_DRIVER AUDIO_ALSA //////////////// diff --git a/config.mk b/config.mk index 3eb6873a46..04fb973188 100644 --- a/config.mk +++ b/config.mk @@ -2,9 +2,9 @@ BUILD_OPENGL = 1 BUILD_FILTER = 0 -BUILD_RSOUND = 1 +BUILD_RSOUND = 0 BUILD_OSS = 0 -BUILD_ALSA = 0 +BUILD_ALSA = 1 PREFIX = /usr/local diff --git a/oss.c b/oss.c index 27905b206e..6e23067614 100644 --- a/oss.c +++ b/oss.c @@ -22,6 +22,7 @@ #include #include #include +#include static void* __oss_init(const char* device, int rate, int latency) { @@ -86,7 +87,11 @@ static ssize_t __oss_write(void* data, const void* buf, size_t size) ssize_t ret; if ( (ret = write(*fd, buf, size)) <= 0 ) + { + if ( (fcntl(*fd, F_GETFL) & O_NONBLOCK) && errno == EAGAIN ) + return 0; return -1; + } return ret; } @@ -103,6 +108,15 @@ static bool __oss_start(void *data) return true; } +static void __oss_set_nonblock_state(void *data, bool state) +{ + int *fd = data; + if (state) + fcntl(*fd, F_SETFL, fcntl(*fd, F_GETFL) | O_NONBLOCK); + else + fcntl(*fd, F_SETFL, fcntl(*fd, F_GETFL) & (~O_NONBLOCK)); +} + static void __oss_free(void *data) { int *fd = data; @@ -117,6 +131,7 @@ const audio_driver_t audio_oss = { .write = __oss_write, .stop = __oss_stop, .start = __oss_start, + .set_nonblock_state = __oss_set_nonblock_state, .free = __oss_free }; diff --git a/ssnes.c b/ssnes.c index 90ef126937..be8edf8c24 100644 --- a/ssnes.c +++ b/ssnes.c @@ -244,7 +244,10 @@ static void audio_sample(uint16_t left, uint16_t right) src_float_to_short_array(outsamples, temp_outsamples, src_data.output_frames_gen * 2); if ( driver.audio->write(driver.audio_data, temp_outsamples, src_data.output_frames_gen * 4) < 0 ) + { + fprintf(stderr, "SSNES [ERROR]: Audio backend failed to write. Will continue without sound.\n"); audio_active = false; + } data_ptr = 0; }