From 1753430d686a64b40d4a3b2fadde4897ca0f1538 Mon Sep 17 00:00:00 2001 From: twinaphex Date: Mon, 12 Jan 2015 05:05:56 +0100 Subject: [PATCH] MOve audio drivers to audio/drivers --- Makefile.common | 28 ++--- audio/{ => drivers}/alsa.c | 4 +- audio/{ => drivers}/alsa_qsa.c | 4 +- audio/{ => drivers}/alsathread.c | 10 +- audio/{ => drivers}/coreaudio.c | 50 ++++++--- audio/{ => drivers}/dsound.c | 147 ++++++++++++++++----------- audio/{ => drivers}/gx_audio.c | 41 ++++---- audio/{ => drivers}/jack.c | 65 ++++++------ audio/{ => drivers}/nullaudio.c | 4 +- audio/{ => drivers}/openal.c | 46 +++++---- audio/{ => drivers}/opensl.c | 42 ++++---- audio/{ => drivers}/oss.c | 24 +++-- audio/{ => drivers}/ps3_audio.c | 28 ++--- audio/{ => drivers}/psp1_audio.c | 24 +++-- audio/{ => drivers}/pulse.c | 104 +++++++++++-------- audio/{ => drivers}/roar.c | 25 +++-- audio/{ => drivers}/rwebaudio.c | 10 +- audio/{ => drivers}/sdl_audio.c | 69 ++++++++----- audio/{ => drivers}/xaudio.c | 42 ++++---- audio/{ => drivers}/xenon360_audio.c | 21 ++-- gfx/context/x11_common.c | 13 ++- griffin/griffin.c | 28 ++--- 22 files changed, 481 insertions(+), 348 deletions(-) rename audio/{ => drivers}/alsa.c (99%) rename audio/{ => drivers}/alsa_qsa.c (99%) rename audio/{ => drivers}/alsathread.c (98%) rename audio/{ => drivers}/coreaudio.c (93%) rename audio/{ => drivers}/dsound.c (85%) rename audio/{ => drivers}/gx_audio.c (90%) rename audio/{ => drivers}/jack.c (89%) rename audio/{ => drivers}/nullaudio.c (97%) rename audio/{ => drivers}/openal.c (91%) rename audio/{ => drivers}/opensl.c (93%) rename audio/{ => drivers}/oss.c (93%) rename audio/{ => drivers}/ps3_audio.c (96%) rename audio/{ => drivers}/psp1_audio.c (95%) rename audio/{ => drivers}/pulse.c (88%) rename audio/{ => drivers}/roar.c (95%) rename audio/{ => drivers}/rwebaudio.c (93%) rename audio/{ => drivers}/sdl_audio.c (80%) rename audio/{ => drivers}/xaudio.c (86%) rename audio/{ => drivers}/xenon360_audio.c (93%) diff --git a/Makefile.common b/Makefile.common index e1a44fb81b..2036cb7b8a 100644 --- a/Makefile.common +++ b/Makefile.common @@ -141,7 +141,7 @@ OBJ += frontend/frontend.o \ location/nulllocation.o \ camera/nullcamera.o \ gfx/nullgfx.o \ - audio/nullaudio.o \ + audio/drivers/nullaudio.o \ input/nullinput.o \ input/nullinput_joypad.o \ input/osk/nullosk.o \ @@ -173,39 +173,39 @@ endif ifeq ($(HAVE_EMSCRIPTEN), 1) OBJ += frontend/platform/platform_emscripten.o \ input/rwebinput_input.o \ - audio/rwebaudio.o \ + audio/drivers/rwebaudio.o \ camera/rwebcam.o endif # Audio # ifeq ($(HAVE_COREAUDIO), 1) - OBJ += audio/coreaudio.o + OBJ += audio/drivers/coreaudio.o LIBS += -framework CoreServices -framework CoreAudio -framework AudioUnit endif ifeq ($(HAVE_OSS), 1) - OBJ += audio/oss.o + OBJ += audio/drivers/oss.o endif ifeq ($(HAVE_OSS_BSD), 1) - OBJ += audio/oss.o + OBJ += audio/drivers/oss.o endif ifeq ($(HAVE_ALSA), 1) - OBJ += audio/alsa.o audio/alsathread.o + OBJ += audio/drivers/alsa.o audio/drivers/alsathread.o LIBS += $(ALSA_LIBS) DEFINES += $(ALSA_CFLAGS) endif ifeq ($(HAVE_ROAR), 1) - OBJ += audio/roar.o + OBJ += audio/drivers/roar.o LIBS += $(ROAR_LIBS) DEFINES += $(ROAR_CFLAGS) endif ifeq ($(HAVE_AL), 1) - OBJ += audio/openal.o + OBJ += audio/drivers/openal.o ifeq ($(OSX),1) LIBS += -framework OpenAL else @@ -214,13 +214,13 @@ ifeq ($(HAVE_AL), 1) endif ifeq ($(HAVE_JACK),1) - OBJ += audio/jack.o + OBJ += audio/drivers/jack.o LIBS += $(JACK_LIBS) DEFINES += $(JACK_CFLAGS) endif ifeq ($(HAVE_PULSE), 1) - OBJ += audio/pulse.o + OBJ += audio/drivers/pulse.o LIBS += $(PULSE_LIBS) DEFINES += $(PULSE_CFLAGS) endif @@ -236,13 +236,13 @@ ifeq ($(HAVE_RSOUND), 1) endif ifeq ($(HAVE_DSOUND), 1) - OBJ += audio/dsound.o + OBJ += audio/drivers/dsound.o DEFINES += -DHAVE_DSOUND LIBS += -ldxguid -ldsound endif ifeq ($(HAVE_XAUDIO), 1) - OBJ += audio/xaudio.o audio/xaudio-c/xaudio-c.o + OBJ += audio/drivers/xaudio.o audio/xaudio-c/xaudio-c.o DEFINES += -DHAVE_XAUDIO LIBS += -lole32 endif @@ -449,7 +449,7 @@ ifeq ($(HAVE_SDL2), 1) endif ifeq ($(HAVE_SDL), 1) - OBJ += gfx/sdl_gfx.o input/sdl_input.o input/sdl_joypad.o audio/sdl_audio.o + OBJ += gfx/sdl_gfx.o input/sdl_input.o input/sdl_joypad.o audio/drivers/sdl_audio.o ifeq ($(HAVE_OPENGL), 1) OBJ += gfx/context/sdl_gl_ctx.o @@ -461,7 +461,7 @@ ifeq ($(HAVE_SDL), 1) endif ifeq ($(HAVE_SDL2), 1) - OBJ += gfx/sdl2_gfx.o input/sdl_input.o input/sdl_joypad.o audio/sdl_audio.o + OBJ += gfx/sdl2_gfx.o input/sdl_input.o input/sdl_joypad.o audio/drivers/sdl_audio.o ifeq ($(HAVE_OPENGL), 1) OBJ += gfx/context/sdl_gl_ctx.o diff --git a/audio/alsa.c b/audio/drivers/alsa.c similarity index 99% rename from audio/alsa.c rename to audio/drivers/alsa.c index da60885209..fa98672166 100644 --- a/audio/alsa.c +++ b/audio/drivers/alsa.c @@ -14,10 +14,10 @@ */ -#include "../driver.h" +#include "../../driver.h" #include #include -#include "../general.h" +#include "../../general.h" #define TRY_ALSA(x) if (x < 0) { \ goto error; \ diff --git a/audio/alsa_qsa.c b/audio/drivers/alsa_qsa.c similarity index 99% rename from audio/alsa_qsa.c rename to audio/drivers/alsa_qsa.c index 3d5fe60752..6fb522bbde 100644 --- a/audio/alsa_qsa.c +++ b/audio/drivers/alsa_qsa.c @@ -14,8 +14,8 @@ * If not, see . */ -#include "../general.h" -#include "../driver.h" +#include "../../general.h" +#include "../../driver.h" #define ALSA_PCM_NEW_HW_PARAMS_API #define ALSA_PCM_NEW_SW_PARAMS_API diff --git a/audio/alsathread.c b/audio/drivers/alsathread.c similarity index 98% rename from audio/alsathread.c rename to audio/drivers/alsathread.c index bdcb91caec..359603a219 100644 --- a/audio/alsathread.c +++ b/audio/drivers/alsathread.c @@ -15,10 +15,10 @@ */ -#include "../driver.h" +#include "../../driver.h" #include #include -#include "../general.h" +#include "../../general.h" #include #include @@ -284,9 +284,9 @@ static ssize_t alsa_thread_write(void *data, const void *buf, size_t size) static bool alsa_thread_alive(void *data) { alsa_thread_t *alsa = (alsa_thread_t*)data; - if (alsa) - return !alsa->is_paused; - return false; + if (!alsa) + return false; + return !alsa->is_paused; } static bool alsa_thread_stop(void *data) diff --git a/audio/coreaudio.c b/audio/drivers/coreaudio.c similarity index 93% rename from audio/coreaudio.c rename to audio/drivers/coreaudio.c index 21e968a860..84e09ae8db 100644 --- a/audio/coreaudio.c +++ b/audio/drivers/coreaudio.c @@ -14,9 +14,8 @@ * If not, see . */ - -#include "../driver.h" -#include "../general.h" +#include "../../driver.h" +#include "../../general.h" #include #include #include @@ -55,6 +54,7 @@ static bool g_interrupted; static void coreaudio_free(void *data) { coreaudio_t *dev = (coreaudio_t*)data; + if (!dev) return; @@ -82,7 +82,10 @@ static OSStatus audio_write_cb(void *userdata, const AudioTimeStamp *time_stamp, UInt32 bus_number, UInt32 number_frames, AudioBufferList *io_data) { + void *outbuf; + unsigned write_avail; coreaudio_t *dev = (coreaudio_t*)userdata; + (void)time_stamp; (void)bus_number; (void)number_frames; @@ -92,10 +95,11 @@ static OSStatus audio_write_cb(void *userdata, if (io_data->mNumberBuffers != 1) return noErr; - unsigned write_avail = io_data->mBuffers[0].mDataByteSize; - void *outbuf = io_data->mBuffers[0].mData; + write_avail = io_data->mBuffers[0].mDataByteSize; + outbuf = io_data->mBuffers[0].mData; pthread_mutex_lock(&dev->lock); + if (fifo_read_avail(dev->buffer) < write_avail) { *action_flags = kAudioUnitRenderAction_OutputIsSilence; @@ -119,6 +123,8 @@ static OSStatus audio_write_cb(void *userdata, #ifdef OSX static void choose_output_device(coreaudio_t *dev, const char* device) { + unsigned i; + AudioDeviceID *devices; AudioObjectPropertyAddress propaddr = { kAudioHardwarePropertyDevices, @@ -126,14 +132,14 @@ static void choose_output_device(coreaudio_t *dev, const char* device) kAudioObjectPropertyElementMaster }; - UInt32 size = 0; + UInt32 size = 0, deviceCount; if (AudioObjectGetPropertyDataSize(kAudioObjectSystemObject, &propaddr, 0, 0, &size) != noErr) return; - UInt32 deviceCount = size / sizeof(AudioDeviceID); - AudioDeviceID *devices = malloc(size); + deviceCount = size / sizeof(AudioDeviceID); + devices = (AudioDeviceID*)malloc(size); if (!devices || AudioObjectGetPropertyData(kAudioObjectSystemObject, &propaddr, 0, 0, &size, devices) != noErr) @@ -143,7 +149,7 @@ static void choose_output_device(coreaudio_t *dev, const char* device) propaddr.mSelector = kAudioDevicePropertyDeviceName; size = 1024; - for (unsigned i = 0; i < deviceCount; i ++) + for (i = 0; i < deviceCount; i ++) { char device_name[1024]; device_name[0] = 0; @@ -174,6 +180,10 @@ static void coreaudio_interrupt_listener(void *data, UInt32 interrupt_state) static void *coreaudio_init(const char *device, unsigned rate, unsigned latency) { + static bool session_initialized = false; + UInt32 i_size; + + (void)session_initialized; (void)device; coreaudio_t *dev = (coreaudio_t*)calloc(1, sizeof(*dev)); @@ -184,7 +194,6 @@ static void *coreaudio_init(const char *device, pthread_cond_init(&dev->cond, NULL); #ifdef IOS - static bool session_initialized = false; if (!session_initialized) { session_initialized = true; @@ -249,7 +258,7 @@ static void *coreaudio_init(const char *device, goto error; /* Check returned audio format. */ - UInt32 i_size = sizeof(real_desc);; + i_size = sizeof(real_desc);; if (AudioUnitGetProperty(dev->dev, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 0, &real_desc, &i_size) != noErr) goto error; @@ -333,9 +342,11 @@ static ssize_t coreaudio_write(void *data, const void *buf_, size_t size) while (!g_interrupted && size > 0) { + size_t write_avail; + pthread_mutex_lock(&dev->lock); - size_t write_avail = fifo_write_avail(dev->buffer); + write_avail = fifo_write_avail(dev->buffer); if (write_avail > size) write_avail = size; @@ -374,14 +385,16 @@ static void coreaudio_set_nonblock_state(void *data, bool state) static bool coreaudio_alive(void *data) { coreaudio_t *dev = (coreaudio_t*)data; - if (dev) - return !dev->is_paused; - return false; + if (!dev) + return false; + return !dev->is_paused; } static bool coreaudio_stop(void *data) { coreaudio_t *dev = (coreaudio_t*)data; + if (!dev) + return false; dev->is_paused = (AudioOutputUnitStop(dev->dev) == noErr) ? true : false; return dev->is_paused ? true : false; } @@ -389,6 +402,8 @@ static bool coreaudio_stop(void *data) static bool coreaudio_start(void *data) { coreaudio_t *dev = (coreaudio_t*)data; + if (!dev) + return false; dev->is_paused = (AudioOutputUnitStart(dev->dev) == noErr) ? false : true; return dev->is_paused ? false : true; } @@ -401,10 +416,13 @@ static bool coreaudio_use_float(void *data) static size_t coreaudio_write_avail(void *data) { + size_t avail; coreaudio_t *dev = (coreaudio_t*)data; + pthread_mutex_lock(&dev->lock); - size_t avail = fifo_write_avail(dev->buffer); + avail = fifo_write_avail(dev->buffer); pthread_mutex_unlock(&dev->lock); + return avail; } diff --git a/audio/dsound.c b/audio/drivers/dsound.c similarity index 85% rename from audio/dsound.c rename to audio/drivers/dsound.c index ace28c8321..f30c0bad7e 100644 --- a/audio/dsound.c +++ b/audio/drivers/dsound.c @@ -39,7 +39,7 @@ static DSMIXBINVOLUMEPAIR dsmbvp[8] = { static DSMIXBINS dsmb; #endif -#include "../driver.h" +#include "../../driver.h" #include #include #include @@ -53,7 +53,7 @@ static DSMIXBINS dsmb; #endif #include #include -#include "../general.h" +#include "../../general.h" typedef struct dsound { @@ -93,21 +93,25 @@ struct audio_lock DWORD size2; }; -static inline bool grab_region(dsound_t *ds, DWORD write_ptr, struct audio_lock *region) +static inline bool grab_region(dsound_t *ds, DWORD write_ptr, + struct audio_lock *region) { - HRESULT res = IDirectSoundBuffer_Lock(ds->dsb, write_ptr, CHUNK_SIZE, ®ion->chunk1, ®ion->size1, ®ion->chunk2, ®ion->size2, 0); + const char *err; + HRESULT res = IDirectSoundBuffer_Lock(ds->dsb, write_ptr, CHUNK_SIZE, + ®ion->chunk1, ®ion->size1, ®ion->chunk2, ®ion->size2, 0); + if (res == DSERR_BUFFERLOST) { res = IDirectSoundBuffer_Restore(ds->dsb); if (res != DS_OK) return false; - res = IDirectSoundBuffer_Lock(ds->dsb, write_ptr, CHUNK_SIZE, ®ion->chunk1, ®ion->size1, ®ion->chunk2, ®ion->size2, 0); + res = IDirectSoundBuffer_Lock(ds->dsb, write_ptr, CHUNK_SIZE, + ®ion->chunk1, ®ion->size1, ®ion->chunk2, ®ion->size2, 0); if (res != DS_OK) return false; } - const char *err; switch (res) { case DSERR_BUFFERLOST: @@ -143,34 +147,43 @@ static inline void release_region(dsound_t *ds, const struct audio_lock *region) static DWORD CALLBACK dsound_thread(PVOID data) { + DWORD write_ptr; dsound_t *ds = (dsound_t*)data; + SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL); - DWORD write_ptr; get_positions(ds, NULL, &write_ptr); write_ptr = (write_ptr + ds->buffer_size / 2) % ds->buffer_size; while (ds->thread_alive) { - DWORD read_ptr; + struct audio_lock region; + DWORD read_ptr, avail, fifo_avail; get_positions(ds, &read_ptr, NULL); - DWORD avail = write_avail(read_ptr, write_ptr, ds->buffer_size); + avail = write_avail(read_ptr, write_ptr, ds->buffer_size); EnterCriticalSection(&ds->crit); - DWORD fifo_avail = fifo_read_avail(ds->buffer); + fifo_avail = fifo_read_avail(ds->buffer); LeaveCriticalSection(&ds->crit); - // No space to write, or we don't have data in our fifo, but we can wait some time before it underruns ... if (avail < CHUNK_SIZE || ((fifo_avail < CHUNK_SIZE) && (avail < ds->buffer_size / 2))) { + /* No space to write, or we don't have data in our fifo, + * but we can wait some time before it underruns ... */ + Sleep(1); - // We could opt for using the notification interface, - // but it is not guaranteed to work, so use high priority sleeping patterns. :( + + /* We could opt for using the notification interface, + * but it is not guaranteed to work, so use high + * priority sleeping patterns. + */ } - else if (fifo_avail < CHUNK_SIZE) // Got space to write, but nothing in FIFO (underrun), fill block with silence. + else if (fifo_avail < CHUNK_SIZE) { - struct audio_lock region; + /* Got space to write, but nothing in FIFO (underrun), + * fill block with silence. */ + if (!grab_region(ds, write_ptr, ®ion)) { ds->thread_alive = false; @@ -184,9 +197,10 @@ static DWORD CALLBACK dsound_thread(PVOID data) release_region(ds, ®ion); write_ptr = (write_ptr + region.size1 + region.size2) % ds->buffer_size; } - else // All is good. Pull from it and notify FIFO :D + else { - struct audio_lock region; + /* All is good. Pull from it and notify FIFO. */ + if (!grab_region(ds, write_ptr, ®ion)) { ds->thread_alive = false; @@ -213,13 +227,13 @@ static DWORD CALLBACK dsound_thread(PVOID data) static void dsound_stop_thread(dsound_t *ds) { - if (ds->thread) - { - ds->thread_alive = false; - WaitForSingleObject(ds->thread, INFINITE); - CloseHandle(ds->thread); - ds->thread = NULL; - } + if (!ds->thread) + return; + + ds->thread_alive = false; + WaitForSingleObject(ds->thread, INFINITE); + CloseHandle(ds->thread); + ds->thread = NULL; } static bool dsound_start_thread(dsound_t *ds) @@ -237,11 +251,12 @@ static bool dsound_start_thread(dsound_t *ds) static void dsound_clear_buffer(dsound_t *ds) { - IDirectSoundBuffer_SetCurrentPosition(ds->dsb, 0); void *ptr; DWORD size; + IDirectSoundBuffer_SetCurrentPosition(ds->dsb, 0); - if (IDirectSoundBuffer_Lock(ds->dsb, 0, 0, &ptr, &size, NULL, NULL, DSBLOCK_ENTIREBUFFER) == DS_OK) + if (IDirectSoundBuffer_Lock(ds->dsb, 0, 0, &ptr, &size, + NULL, NULL, DSBLOCK_ENTIREBUFFER) == DS_OK) { memset(ptr, 0, size); IDirectSoundBuffer_Unlock(ds->dsb, ptr, size, NULL, 0); @@ -251,34 +266,35 @@ static void dsound_clear_buffer(dsound_t *ds) static void dsound_free(void *data) { dsound_t *ds = (dsound_t*)data; - if (ds) + + if (!ds) + return; + + if (ds->thread) { - if (ds->thread) - { - ds->thread_alive = false; - WaitForSingleObject(ds->thread, INFINITE); - CloseHandle(ds->thread); - } - - DeleteCriticalSection(&ds->crit); - - if (ds->dsb) - { - IDirectSoundBuffer_Stop(ds->dsb); - IDirectSoundBuffer_Release(ds->dsb); - } - - if (ds->ds) - IDirectSound_Release(ds->ds); - - if (ds->event) - CloseHandle(ds->event); - - if (ds->buffer) - fifo_free(ds->buffer); - - free(ds); + ds->thread_alive = false; + WaitForSingleObject(ds->thread, INFINITE); + CloseHandle(ds->thread); } + + DeleteCriticalSection(&ds->crit); + + if (ds->dsb) + { + IDirectSoundBuffer_Stop(ds->dsb); + IDirectSoundBuffer_Release(ds->dsb); + } + + if (ds->ds) + IDirectSound_Release(ds->ds); + + if (ds->event) + CloseHandle(ds->event); + + if (ds->buffer) + fifo_free(ds->buffer); + + free(ds); } struct dsound_dev @@ -291,7 +307,9 @@ struct dsound_dev static BOOL CALLBACK enumerate_cb(LPGUID guid, LPCSTR desc, LPCSTR module, LPVOID context) { struct dsound_dev *dev = (struct dsound_dev*)context; + RARCH_LOG("\t%u: %s\n", dev->total_count, desc); + if (dev->device == dev->total_count) dev->guid = guid; dev->total_count++; @@ -303,8 +321,8 @@ static void *dsound_init(const char *device, unsigned rate, unsigned latency) WAVEFORMATEX wfx = {0}; DSBUFFERDESC bufdesc = {0}; struct dsound_dev dev = {0}; - dsound_t *ds = (dsound_t*)calloc(1, sizeof(*ds)); + if (!ds) goto error; @@ -384,14 +402,17 @@ error: static bool dsound_stop(void *data) { dsound_t *ds = (dsound_t*)data; + dsound_stop_thread(ds); ds->is_paused = (IDirectSoundBuffer_Stop(ds->dsb) == DS_OK) ? true : false; + return (ds->is_paused) ? true : false; } static bool dsound_start(void *data) { dsound_t *ds = (dsound_t*)data; + dsound_clear_buffer(ds); if (!dsound_start_thread(ds)) @@ -404,30 +425,34 @@ static bool dsound_start(void *data) static bool dsound_alive(void *data) { dsound_t *ds = (dsound_t*)data; - if (ds) - return !ds->is_paused; - return false; + + if (!ds) + return false; + return !ds->is_paused; } static void dsound_set_nonblock_state(void *data, bool state) { dsound_t *ds = (dsound_t*)data; - ds->nonblock = state; + if (ds) + ds->nonblock = state; } static ssize_t dsound_write(void *data, const void *buf_, size_t size) { + size_t written = 0; dsound_t *ds = (dsound_t*)data; const uint8_t *buf = (const uint8_t*)buf_; if (!ds->thread_alive) return -1; - size_t written = 0; while (size > 0) { + size_t avail; + EnterCriticalSection(&ds->crit); - size_t avail = fifo_write_avail(ds->buffer); + avail = fifo_write_avail(ds->buffer); if (avail > size) avail = size; @@ -450,9 +475,11 @@ static ssize_t dsound_write(void *data, const void *buf_, size_t size) static size_t dsound_write_avail(void *data) { + size_t avail; dsound_t *ds = (dsound_t*)data; + EnterCriticalSection(&ds->crit); - size_t avail = fifo_write_avail(ds->buffer); + avail = fifo_write_avail(ds->buffer); LeaveCriticalSection(&ds->crit); return avail; } diff --git a/audio/gx_audio.c b/audio/drivers/gx_audio.c similarity index 90% rename from audio/gx_audio.c rename to audio/drivers/gx_audio.c index 7f99831da9..af2f30a3d0 100644 --- a/audio/gx_audio.c +++ b/audio/drivers/gx_audio.c @@ -14,7 +14,7 @@ * If not, see . */ -#include "../driver.h" +#include "../../driver.h" #include #include #include "../general.h" @@ -27,7 +27,7 @@ #include #endif -#include "../gfx/gx/sdk_defines.h" +#include "../../gfx/gx/sdk_defines.h" #define CHUNK_FRAMES 64 #define CHUNK_SIZE (CHUNK_FRAMES * sizeof(uint32_t)) @@ -63,20 +63,20 @@ static void dma_callback(void) { gx_audio_t *wa = (gx_audio_t*)gx_audio_data; - if (!stop_audio) - { - /* Erase last chunk to avoid repeating audio. */ - memset(wa->data[wa->dma_busy], 0, CHUNK_SIZE); + if (stop_audio) + return; - wa->dma_busy = wa->dma_next; - wa->dma_next = (wa->dma_next + 1) & (BLOCKS - 1); + /* Erase last chunk to avoid repeating audio. */ + memset(wa->data[wa->dma_busy], 0, CHUNK_SIZE); - DCFlushRange(wa->data[wa->dma_next], CHUNK_SIZE); + wa->dma_busy = wa->dma_next; + wa->dma_next = (wa->dma_next + 1) & (BLOCKS - 1); - AIInitDMA((uint32_t)wa->data[wa->dma_next], CHUNK_SIZE); + DCFlushRange(wa->data[wa->dma_next], CHUNK_SIZE); - OSSignalCond(wa->cond); - } + AIInitDMA((uint32_t)wa->data[wa->dma_next], CHUNK_SIZE); + + OSSignalCond(wa->cond); } static void *gx_audio_init(const char *device, @@ -135,6 +135,7 @@ static ssize_t gx_audio_write(void *data, const void *buf_, size_t size) while (frames) { size_t to_write = CHUNK_FRAMES - wa->write_ptr; + if (frames < to_write) to_write = frames; @@ -178,15 +179,17 @@ static void gx_audio_set_nonblock_state(void *data, bool state) { gx_audio_t *wa = (gx_audio_t*)data; - if (!wa) - return; - - wa->nonblock = state; + if (wa) + wa->nonblock = state; } static bool gx_audio_start(void *data) { gx_audio_t *wa = (gx_audio_t*)data; + + if (!wa) + return false; + AIStartDMA(); wa->is_paused = false; return true; @@ -195,9 +198,9 @@ static bool gx_audio_start(void *data) static bool gx_audio_alive(void *data) { gx_audio_t *wa = (gx_audio_t*)data; - if (wa) - return !wa->is_paused; - return false; + if (!wa) + return false; + return !wa->is_paused; } static void gx_audio_free(void *data) diff --git a/audio/jack.c b/audio/drivers/jack.c similarity index 89% rename from audio/jack.c rename to audio/drivers/jack.c index 4f63f40c0c..63228b1cd2 100644 --- a/audio/jack.c +++ b/audio/drivers/jack.c @@ -14,9 +14,9 @@ */ -#include "../driver.h" +#include "../../driver.h" #include -#include "../general.h" +#include "../../general.h" #include #include @@ -46,18 +46,18 @@ typedef struct jack static int process_cb(jack_nframes_t nframes, void *data) { int i; - jack_nframes_t f; + jack_nframes_t f, avail[2], min_avail; jack_t *jd = (jack_t*)data; + if (nframes <= 0) { pthread_cond_signal(&jd->cond); return 0; } - jack_nframes_t avail[2]; avail[0] = jack_ringbuffer_read_space(jd->buffer[0]); avail[1] = jack_ringbuffer_read_space(jd->buffer[1]); - jack_nframes_t min_avail = ((avail[0] < avail[1]) ? avail[0] : avail[1]) / sizeof(jack_default_audio_sample_t); + min_avail = ((avail[0] < avail[1]) ? avail[0] : avail[1]) / sizeof(jack_default_audio_sample_t); if (min_avail > nframes) min_avail = nframes; @@ -69,9 +69,7 @@ static int process_cb(jack_nframes_t nframes, void *data) jack_ringbuffer_read(jd->buffer[i], (char*)out, min_avail * sizeof(jack_default_audio_sample_t)); for (f = min_avail; f < nframes; f++) - { out[f] = 0.0f; - } } pthread_cond_signal(&jd->cond); return 0; @@ -80,6 +78,10 @@ static int process_cb(jack_nframes_t nframes, void *data) static void shutdown_cb(void *data) { jack_t *jd = (jack_t*)data; + + if (!jd) + return; + jd->shutdown = true; pthread_cond_signal(&jd->cond); } @@ -88,8 +90,8 @@ static int parse_ports(char **dest_ports, const char **jports) { int i; char *save; - const char *con = strtok_r(g_settings.audio.device, ",", &save); int parsed = 0; + const char *con = strtok_r(g_settings.audio.device, ",", &save); if (con) dest_ports[parsed++] = strdup(con); @@ -105,11 +107,10 @@ static int parse_ports(char **dest_ports, const char **jports) static size_t find_buffersize(jack_t *jd, int latency) { - int i; + int i, buffer_frames, min_buffer_frames, jack_latency = 0; + jack_latency_range_t range; int frames = latency * g_settings.audio.out_rate / 1000; - jack_latency_range_t range; - int jack_latency = 0; for (i = 0; i < 2; i++) { jack_port_get_latency_range(jd->ports[i], JackPlaybackLatency, &range); @@ -119,8 +120,9 @@ static size_t find_buffersize(jack_t *jd, int latency) RARCH_LOG("JACK: Jack latency is %d frames.\n", jack_latency); - int buffer_frames = frames - jack_latency; - int min_buffer_frames = jack_get_buffer_size(jd->client) * 2; + buffer_frames = frames - jack_latency; + min_buffer_frames = jack_get_buffer_size(jd->client) * 2; + RARCH_LOG("JACK: Minimum buffer size is %d frames.\n", min_buffer_frames); if (buffer_frames < min_buffer_frames) @@ -132,17 +134,17 @@ static size_t find_buffersize(jack_t *jd, int latency) static void *ja_init(const char *device, unsigned rate, unsigned latency) { int i; + const char **jports = NULL; + char *dest_ports[2]; + size_t bufsize = 0; + int parsed = 0; jack_t *jd = (jack_t*)calloc(1, sizeof(jack_t)); + if (!jd) return NULL; pthread_cond_init(&jd->cond, NULL); pthread_mutex_init(&jd->cond_lock, NULL); - - const char **jports = NULL; - char *dest_ports[2]; - size_t bufsize = 0; - int parsed = 0; jd->client = jack_client_open("RetroArch", JackNullOption, NULL); if (jd->client == NULL) @@ -214,12 +216,12 @@ error: static size_t write_buffer(jack_t *jd, const float *buf, size_t size) { int i; - size_t j; + size_t j, frames, written = 0; jack_default_audio_sample_t out_deinterleaved_buffer[2][AUDIO_CHUNK_SIZE_NONBLOCKING * AUDIO_MAX_RATIO]; - size_t frames = FRAMES(size); + frames = FRAMES(size); - // Avoid buffer overflow if a DSP plugin generated a huge number of frames + /* Avoid buffer overflow if a DSP plugin generated a huge number of frames. */ if (frames > AUDIO_CHUNK_SIZE_NONBLOCKING * AUDIO_MAX_RATIO) frames = AUDIO_CHUNK_SIZE_NONBLOCKING * AUDIO_MAX_RATIO; @@ -227,21 +229,19 @@ static size_t write_buffer(jack_t *jd, const float *buf, size_t size) for (j = 0; j < frames; j++) out_deinterleaved_buffer[i][j] = buf[j * 2 + i]; - size_t written = 0; while (written < frames) { + size_t avail[2], min_avail, write_frames; if (jd->shutdown) return 0; - size_t avail[2] = { - jack_ringbuffer_write_space(jd->buffer[0]), - jack_ringbuffer_write_space(jd->buffer[1]), - }; + avail[0] = jack_ringbuffer_write_space(jd->buffer[0]); + avail[1] = jack_ringbuffer_write_space(jd->buffer[1]); - size_t min_avail = avail[0] < avail[1] ? avail[0] : avail[1]; + min_avail = avail[0] < avail[1] ? avail[0] : avail[1]; min_avail /= sizeof(float); - size_t write_frames = frames - written > min_avail ? min_avail : frames - written; + write_frames = frames - written > min_avail ? min_avail : frames - written; if (write_frames > 0) { @@ -284,15 +284,16 @@ static bool ja_stop(void *data) static bool ja_alive(void *data) { jack_t *jd = (jack_t*)data; - if (jd) - return !jd->is_paused; - return false; + if (!jd) + return false; + return !jd->is_paused; } static void ja_set_nonblock_state(void *data, bool state) { jack_t *jd = (jack_t*)data; - jd->nonblock = state; + if (jd) + jd->nonblock = state; } static bool ja_start(void *data) diff --git a/audio/nullaudio.c b/audio/drivers/nullaudio.c similarity index 97% rename from audio/nullaudio.c rename to audio/drivers/nullaudio.c index 5ead09c472..84a87f4f81 100644 --- a/audio/nullaudio.c +++ b/audio/drivers/nullaudio.c @@ -13,8 +13,8 @@ * If not, see . */ -#include "../general.h" -#include "../driver.h" +#include "../../general.h" +#include "../../driver.h" static void *null_audio_init(const char *device, unsigned rate, unsigned latency) { diff --git a/audio/openal.c b/audio/drivers/openal.c similarity index 91% rename from audio/openal.c rename to audio/drivers/openal.c index dd1ab31837..49bc5399fa 100644 --- a/audio/openal.c +++ b/audio/drivers/openal.c @@ -13,8 +13,8 @@ * If not, see . */ -#include "../driver.h" -#include "../general.h" +#include "../../driver.h" +#include "../../general.h" #ifdef __APPLE__ #include @@ -56,6 +56,7 @@ typedef struct al static void al_free(void *data) { al_t *al = (al_t*)data; + if (!al) return; @@ -78,24 +79,27 @@ static void al_free(void *data) static void *al_init(const char *device, unsigned rate, unsigned latency) { + al_t *al; + (void)device; - al_t *al = (al_t*)calloc(1, sizeof(al_t)); + + al = (al_t*)calloc(1, sizeof(al_t)); if (!al) return NULL; al->handle = alcOpenDevice(NULL); - if (al->handle == NULL) + if (!al->handle) goto error; al->ctx = alcCreateContext(al->handle, NULL); - if (al->ctx == NULL) + if (!al->ctx) goto error; alcMakeContextCurrent(al->ctx); al->rate = rate; - // We already use one buffer for tmpbuf. + /* We already use one buffer for tmpbuf. */ al->num_buffers = (latency * rate * 2 * sizeof(int16_t)) / (1000 * BUFSIZE) - 1; if (al->num_buffers < 2) al->num_buffers = 2; @@ -126,14 +130,12 @@ static bool al_unqueue_buffers(al_t *al) alGetSourcei(al->source, AL_BUFFERS_PROCESSED, &val); - if (val > 0) - { - alSourceUnqueueBuffers(al->source, val, &al->res_buf[al->res_ptr]); - al->res_ptr += val; - return true; - } + if (val <= 0) + return false; - return false; + alSourceUnqueueBuffers(al->source, val, &al->res_buf[al->res_ptr]); + al->res_ptr += val; + return true; } static bool al_get_buffer(al_t *al, ALuint *buffer) @@ -169,11 +171,14 @@ static ssize_t al_write(void *data, const void *buf_, size_t size) { al_t *al = (al_t*)data; const uint8_t *buf = (const uint8_t*)buf_; - size_t written = 0; + while (size) { + ALint val; + ALuint buffer; size_t rc = al_fill_internal_buf(al, buf, size); + written += rc; buf += rc; size -= rc; @@ -181,7 +186,6 @@ static ssize_t al_write(void *data, const void *buf_, size_t size) if (al->tmpbuf_ptr != BUFSIZE) break; - ALuint buffer; if (!al_get_buffer(al, &buffer)) break; @@ -191,7 +195,6 @@ static ssize_t al_write(void *data, const void *buf_, size_t size) if (alGetError() != AL_NO_ERROR) return -1; - ALint val; alGetSourcei(al->source, AL_SOURCE_STATE, &val); if (val != AL_PLAYING) alSourcePlay(al->source); @@ -214,15 +217,16 @@ static bool al_stop(void *data) static bool al_alive(void *data) { al_t *al = (al_t*)data; - if (al) - return !al->is_paused; - return false; + if (!al) + return false; + return !al->is_paused; } static void al_set_nonblock_state(void *data, bool state) { al_t *al = (al_t*)data; - al->nonblock = state; + if (al) + al->nonblock = state; } static bool al_start(void *data) @@ -243,7 +247,7 @@ static size_t al_write_avail(void *data) static size_t al_buffer_size(void *data) { al_t *al = (al_t*)data; - return (al->num_buffers + 1) * BUFSIZE; // Also got tmpbuf. + return (al->num_buffers + 1) * BUFSIZE; /* Also got tmpbuf. */ } static bool al_use_float(void *data) diff --git a/audio/opensl.c b/audio/drivers/opensl.c similarity index 93% rename from audio/opensl.c rename to audio/drivers/opensl.c index b14d2eabf8..76292016f3 100644 --- a/audio/opensl.c +++ b/audio/drivers/opensl.c @@ -14,8 +14,8 @@ * If not, see . */ -#include "../driver.h" -#include "../general.h" +#include "../../driver.h" +#include "../../general.h" #include #include @@ -23,7 +23,7 @@ #include #endif -// Helper macros, COM-style! +/* Helper macros, COM-style. */ #define SLObjectItf_Realize(a, ...) ((*(a))->Realize(a, __VA_ARGS__)) #define SLObjectItf_GetInterface(a, ...) ((*(a))->GetInterface(a, __VA_ARGS__)) #define SLObjectItf_Destroy(a) ((*(a))->Destroy((a))) @@ -100,20 +100,23 @@ static void sl_free(void *data) static void *sl_init(const char *device, unsigned rate, unsigned latency) { unsigned i; - (void)device; - + SLInterfaceID id; + SLboolean req; + SLresult res; + sl_t *sl; SLDataFormat_PCM fmt_pcm = {0}; SLDataSource audio_src = {0}; SLDataSink audio_sink = {0}; - SLDataLocator_AndroidSimpleBufferQueue loc_bufq = {0}; SLDataLocator_OutputMix loc_outmix = {0}; - SLInterfaceID id = SL_IID_ANDROIDSIMPLEBUFFERQUEUE; - SLboolean req = SL_BOOLEAN_TRUE; + (void)device; - SLresult res = 0; - sl_t *sl = (sl_t*)calloc(1, sizeof(sl_t)); + id = SL_IID_ANDROIDSIMPLEBUFFERQUEUE; + req = SL_BOOLEAN_TRUE; + + res = 0; + sl = (sl_t*)calloc(1, sizeof(sl_t)); if (!sl) goto error; @@ -154,7 +157,7 @@ static void *sl_init(const char *device, unsigned rate, unsigned latency) fmt_pcm.bitsPerSample = 16; fmt_pcm.containerSize = 16; fmt_pcm.channelMask = SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT; - fmt_pcm.endianness = SL_BYTEORDER_LITTLEENDIAN; // Android only. + fmt_pcm.endianness = SL_BYTEORDER_LITTLEENDIAN; /* Android only. */ audio_src.pLocator = &loc_bufq; audio_src.pFormat = &fmt_pcm; @@ -180,7 +183,7 @@ static void *sl_init(const char *device, unsigned rate, unsigned latency) (*sl->buffer_queue)->RegisterCallback(sl->buffer_queue, opensl_callback, sl); - // Enqueue a bit to get stuff rolling. + /* Enqueue a bit to get stuff rolling. */ sl->buffered_blocks = sl->buf_count; sl->buffer_index = 0; for (i = 0; i < sl->buf_count; i++) @@ -207,15 +210,16 @@ static bool sl_stop(void *data) static bool sl_alive(void *data) { sl_t *sl = (sl_t*)data; - if (sl) - return !sl->is_paused; - return false; + if (!sl) + return false; + return !sl->is_paused; } static void sl_set_nonblock_state(void *data, bool state) { sl_t *sl = (sl_t*)data; - sl->nonblock = state; + if (sl) + sl->nonblock = state; } static bool sl_start(void *data) @@ -229,12 +233,13 @@ static bool sl_start(void *data) static ssize_t sl_write(void *data, const void *buf_, size_t size) { sl_t *sl = (sl_t*)data; - size_t written = 0; const uint8_t *buf = (const uint8_t*)buf_; while (size) { + size_t avail_write; + if (sl->nonblock) { if (sl->buffered_blocks == sl->buf_count) @@ -248,7 +253,8 @@ static ssize_t sl_write(void *data, const void *buf_, size_t size) slock_unlock(sl->lock); } - size_t avail_write = min(sl->buf_size - sl->buffer_ptr, size); + avail_write = min(sl->buf_size - sl->buffer_ptr, size); + if (avail_write) { memcpy(sl->buffer[sl->buffer_index] + sl->buffer_ptr, buf, avail_write); diff --git a/audio/oss.c b/audio/drivers/oss.c similarity index 93% rename from audio/oss.c rename to audio/drivers/oss.c index 00c5e9e09d..7ba2baaf65 100644 --- a/audio/oss.c +++ b/audio/drivers/oss.c @@ -17,8 +17,8 @@ #include "config.h" #endif -#include "driver.h" -#include "general.h" +#include "../../driver.h" +#include "../../general.h" #include #ifdef HAVE_OSS_BSD @@ -43,7 +43,9 @@ static bool oss_is_paused; static void *oss_init(const char *device, unsigned rate, unsigned latency) { + int frags, frag, channels, format, new_rate; int *fd = (int*)calloc(1, sizeof(int)); + if (fd == NULL) return NULL; @@ -59,15 +61,14 @@ static void *oss_init(const char *device, unsigned rate, unsigned latency) return NULL; } - int frags = (latency * rate * 4) / (1000 * (1 << 10)); - int frag = (frags << 16) | 10; + frags = (latency * rate * 4) / (1000 * (1 << 10)); + frag = (frags << 16) | 10; if (ioctl(*fd, SNDCTL_DSP_SETFRAGMENT, &frag) < 0) RARCH_WARN("Cannot set fragment sizes. Latency might not be as expected ...\n"); - int channels = 2; - int format = is_little_endian() ? - AFMT_S16_LE : AFMT_S16_BE; + channels = 2; + format = is_little_endian() ? AFMT_S16_LE : AFMT_S16_BE; if (ioctl(*fd, SNDCTL_DSP_CHANNELS, &channels) < 0) { @@ -85,7 +86,8 @@ static void *oss_init(const char *device, unsigned rate, unsigned latency) return NULL; } - int new_rate = rate; + new_rate = rate; + if (ioctl(*fd, SNDCTL_DSP_SPEED, &new_rate) < 0) { close(*fd); @@ -105,12 +107,12 @@ static void *oss_init(const char *device, unsigned rate, unsigned latency) static ssize_t oss_write(void *data, const void *buf, size_t size) { + ssize_t ret; int *fd = (int*)data; if (size == 0) return 0; - ssize_t ret; if ((ret = write(*fd, buf, size)) < 0) { if (errno == EAGAIN && (fcntl(*fd, F_GETFL) & O_NONBLOCK)) @@ -125,6 +127,7 @@ static ssize_t oss_write(void *data, const void *buf, size_t size) static bool oss_stop(void *data) { int *fd = (int*)data; + ioctl(*fd, SNDCTL_DSP_RESET, 0); oss_is_paused = true; return true; @@ -145,8 +148,9 @@ static bool oss_alive(void *data) static void oss_set_nonblock_state(void *data, bool state) { - int *fd = (int*)data; int rc; + int *fd = (int*)data; + if (state) rc = fcntl(*fd, F_SETFL, fcntl(*fd, F_GETFL) | O_NONBLOCK); else diff --git a/audio/ps3_audio.c b/audio/drivers/ps3_audio.c similarity index 96% rename from audio/ps3_audio.c rename to audio/drivers/ps3_audio.c index 082c5f100e..60fe4a1da1 100644 --- a/audio/ps3_audio.c +++ b/audio/drivers/ps3_audio.c @@ -46,17 +46,16 @@ static void event_loop(void *data) static void event_loop(uint64_t data) #endif { - ps3_audio_t *aud = data; + float out_tmp[CELL_AUDIO_BLOCK_SAMPLES * AUDIO_CHANNELS] + __attribute__((aligned(16))); sys_event_queue_t id; sys_ipc_key_t key; sys_event_t event; + ps3_audio_t *aud = data; cellAudioCreateNotifyEventQueue(&id, &key); cellAudioSetNotifyEventQueue(key); - float out_tmp[CELL_AUDIO_BLOCK_SAMPLES * AUDIO_CHANNELS] - __attribute__((aligned(16))); - while (!aud->quit_thread) { sys_event_queue_receive(id, &event, SYS_NO_TIMEOUT); @@ -80,16 +79,19 @@ static void event_loop(uint64_t data) static void *ps3_audio_init(const char *device, unsigned rate, unsigned latency) { + CellAudioPortParam params; + ps3_audio_t *data; + (void)latency; (void)device; (void)rate; - ps3_audio_t *data = calloc(1, sizeof(*data)); + data = calloc(1, sizeof(*data)); if (!data) return NULL; - CellAudioPortParam params; cellAudioInit(); + params.numChannels = AUDIO_CHANNELS; params.numBlocks = AUDIO_BLOCKS; #ifdef HAVE_HEADSET @@ -151,15 +153,14 @@ static ssize_t ps3_audio_write(void *data, const void *buf, size_t size) if (fifo_write_avail(aud->buffer) < size) return 0; } - else - { - while (fifo_write_avail(aud->buffer) < size) - sys_lwcond_wait(&aud->cond, 0); - } + + while (fifo_write_avail(aud->buffer) < size) + sys_lwcond_wait(&aud->cond, 0); sys_lwmutex_lock(&aud->lock, SYS_NO_TIMEOUT); fifo_write(aud->buffer, buf, size); sys_lwmutex_unlock(&aud->lock); + return size; } @@ -188,13 +189,16 @@ static bool ps3_audio_start(void *data) static bool ps3_audio_alive(void *data) { ps3_audio_t *aud = data; + if (!aud) + return false; return aud->started; } static void ps3_audio_set_nonblock_state(void *data, bool toggle) { ps3_audio_t *aud = data; - aud->nonblocking = toggle; + if (aud) + aud->nonblocking = toggle; } static void ps3_audio_free(void *data) diff --git a/audio/psp1_audio.c b/audio/drivers/psp1_audio.c similarity index 95% rename from audio/psp1_audio.c rename to audio/drivers/psp1_audio.c index b009e2a2c2..1edd85bb9f 100644 --- a/audio/psp1_audio.c +++ b/audio/drivers/psp1_audio.c @@ -15,8 +15,8 @@ * If not, see . */ -#include "../general.h" -#include "../driver.h" +#include "../../general.h" +#include "../../driver.h" #include #include @@ -71,10 +71,12 @@ static int audioMainLoop(SceSize args, void* argp) static void *psp_audio_init(const char *device, unsigned rate, unsigned latency) { + psp1_audio_t* psp; + (void)device; (void)latency; - psp1_audio_t* psp = (psp1_audio_t*)calloc(1, sizeof(psp1_audio_t)); + psp = (psp1_audio_t*)calloc(1, sizeof(psp1_audio_t)); if (!psp) return NULL; @@ -103,12 +105,13 @@ static void *psp_audio_init(const char *device, static void psp_audio_free(void *data) { + SceUInt timeout = 100000; psp1_audio_t* psp = (psp1_audio_t*)data; if(!psp) return; - psp->running = false; - SceUInt timeout = 100000; + psp->running = false; + sceKernelWaitThreadEnd(psp->thread, &timeout); sceKernelDeleteThread(psp->thread); @@ -153,14 +156,15 @@ static ssize_t psp_audio_write(void *data, const void *buf, size_t size) static bool psp_audio_alive(void *data) { psp1_audio_t* psp = (psp1_audio_t*)data; - if (psp) - return psp->running; - return false; + if (!psp) + return false; + return psp->running; } static bool psp_audio_stop(void *data) { SceKernelThreadRunStatus runStatus; + SceUInt timeout = 100000; psp1_audio_t* psp = (psp1_audio_t*)data; runStatus.size = sizeof(SceKernelThreadRunStatus); @@ -172,7 +176,6 @@ static bool psp_audio_stop(void *data) return false; psp->running = false; - SceUInt timeout = 100000; sceKernelWaitThreadEnd(psp->thread, &timeout); return true; @@ -201,7 +204,8 @@ static bool psp_audio_start(void *data) static void psp_audio_set_nonblock_state(void *data, bool toggle) { psp1_audio_t* psp = (psp1_audio_t*)data; - psp->nonblocking = toggle; + if (psp) + psp->nonblocking = toggle; } static bool psp_audio_use_float(void *data) diff --git a/audio/pulse.c b/audio/drivers/pulse.c similarity index 88% rename from audio/pulse.c rename to audio/drivers/pulse.c index 102a298e48..dd7e1e9289 100644 --- a/audio/pulse.c +++ b/audio/drivers/pulse.c @@ -14,8 +14,8 @@ */ -#include "driver.h" -#include "general.h" +#include "../../driver.h" +#include "../../general.h" #include #include #include @@ -35,28 +35,29 @@ typedef struct static void pulse_free(void *data) { pa_t *pa = (pa_t*)data; - if (pa) + + if (!pa) + return; + + if (pa->mainloop) + pa_threaded_mainloop_stop(pa->mainloop); + + if (pa->stream) { - if (pa->mainloop) - pa_threaded_mainloop_stop(pa->mainloop); - - if (pa->stream) - { - pa_stream_disconnect(pa->stream); - pa_stream_unref(pa->stream); - } - - if (pa->context) - { - pa_context_disconnect(pa->context); - pa_context_unref(pa->context); - } - - if (pa->mainloop) - pa_threaded_mainloop_free(pa->mainloop); - - free(pa); + pa_stream_disconnect(pa->stream); + pa_stream_unref(pa->stream); } + + if (pa->context) + { + pa_context_disconnect(pa->context); + pa_context_unref(pa->context); + } + + if (pa->mainloop) + pa_threaded_mainloop_free(pa->mainloop); + + free(pa); } static void stream_success_cb(pa_stream *s, int success, void *data) @@ -70,6 +71,7 @@ static void stream_success_cb(pa_stream *s, int success, void *data) static void context_state_cb(pa_context *c, void *data) { pa_t *pa = (pa_t*)data; + switch (pa_context_get_state(c)) { case PA_CONTEXT_READY: @@ -85,6 +87,7 @@ static void context_state_cb(pa_context *c, void *data) static void stream_state_cb(pa_stream *s, void *data) { pa_t *pa = (pa_t*)data; + switch (pa_stream_get_state(s)) { case PA_STREAM_READY: @@ -99,23 +102,29 @@ static void stream_state_cb(pa_stream *s, void *data) static void stream_request_cb(pa_stream *s, size_t length, void *data) { + pa_t *pa = (pa_t*)data; + (void)length; (void)s; - pa_t *pa = (pa_t*)data; + pa_threaded_mainloop_signal(pa->mainloop, 0); } static void stream_latency_update_cb(pa_stream *s, void *data) { - (void)s; pa_t *pa = (pa_t*)data; + + (void)s; + pa_threaded_mainloop_signal(pa->mainloop, 0); } static void underrun_update_cb(pa_stream *s, void *data) { - (void)s; pa_t *pa = (pa_t*)data; + + (void)s; + RARCH_LOG("[PulseAudio]: Underrun (Buffer: %u, Writable size: %u).\n", (unsigned)pa->buffer_size, (unsigned)pa_stream_writable_size(pa->stream)); @@ -133,11 +142,14 @@ static void buffer_attr_cb(pa_stream *s, void *data) static void *pulse_init(const char *device, unsigned rate, unsigned latency) { - const pa_buffer_attr *server_attr = NULL; pa_sample_spec spec; - memset(&spec, 0, sizeof(spec)); + pa_t *pa; pa_buffer_attr buffer_attr = {0}; - pa_t *pa = (pa_t*)calloc(1, sizeof(*pa)); + const pa_buffer_attr *server_attr = NULL; + + memset(&spec, 0, sizeof(spec)); + + pa = (pa_t*)calloc(1, sizeof(*pa)); if (!pa) goto error; @@ -217,13 +229,13 @@ static ssize_t pulse_write(void *data, const void *buf_, size_t size) { pa_t *pa = (pa_t*)data; const uint8_t *buf = (const uint8_t*)buf_; - size_t written = 0; pa_threaded_mainloop_lock(pa->mainloop); while (size) { size_t writable = pa_stream_writable_size(pa->stream); + writable = min(size, writable); if (writable) @@ -246,13 +258,16 @@ static ssize_t pulse_write(void *data, const void *buf_, size_t size) static bool pulse_stop(void *data) { - RARCH_LOG("[PulseAudio]: Pausing.\n"); + bool ret; pa_t *pa = (pa_t*)data; - pa->success = true; // In case of spurious wakeup. Not critical. + + RARCH_LOG("[PulseAudio]: Pausing.\n"); + + pa->success = true; /* In case of spurious wakeup. Not critical. */ pa_threaded_mainloop_lock(pa->mainloop); pa_stream_cork(pa->stream, true, stream_success_cb, pa); pa_threaded_mainloop_wait(pa->mainloop); - bool ret = pa->success; + ret = pa->success; pa_threaded_mainloop_unlock(pa->mainloop); pa->is_paused = true; return ret; @@ -261,20 +276,24 @@ static bool pulse_stop(void *data) static bool pulse_alive(void *data) { pa_t *pa = (pa_t*)data; - if (pa) - return !pa->is_paused; - return false; + + if (!pa) + return false; + return !pa->is_paused; } static bool pulse_start(void *data) { - RARCH_LOG("[PulseAudio]: Unpausing.\n"); + bool ret; pa_t *pa = (pa_t*)data; - pa->success = true; // In case of spurious wakeup. Not critical. + + RARCH_LOG("[PulseAudio]: Unpausing.\n"); + + pa->success = true; /* In case of spurious wakeup. Not critical. */ pa_threaded_mainloop_lock(pa->mainloop); pa_stream_cork(pa->stream, false, stream_success_cb, pa); pa_threaded_mainloop_wait(pa->mainloop); - bool ret = pa->success; + ret = pa->success; pa_threaded_mainloop_unlock(pa->mainloop); pa->is_paused = false; return ret; @@ -283,7 +302,8 @@ static bool pulse_start(void *data) static void pulse_set_nonblock_state(void *data, bool state) { pa_t *pa = (pa_t*)data; - pa->nonblock = state; + if (pa) + pa->nonblock = state; } static bool pulse_use_float(void *data) @@ -294,10 +314,12 @@ static bool pulse_use_float(void *data) static size_t pulse_write_avail(void *data) { + size_t length; pa_t *pa = (pa_t*)data; + pa_threaded_mainloop_lock(pa->mainloop); - size_t length = pa_stream_writable_size(pa->stream); - g_extern.audio_data.driver_buffer_size = pa->buffer_size; // Can change spuriously. + length = pa_stream_writable_size(pa->stream); + g_extern.audio_data.driver_buffer_size = pa->buffer_size; /* Can change spuriously. */ pa_threaded_mainloop_unlock(pa->mainloop); return length; } diff --git a/audio/roar.c b/audio/drivers/roar.c similarity index 95% rename from audio/roar.c rename to audio/drivers/roar.c index ccbf734589..54d10c7e67 100644 --- a/audio/roar.c +++ b/audio/drivers/roar.c @@ -14,13 +14,13 @@ */ -#include "driver.h" +#include "../../driver.h" #include #include #include #include #include -#include "general.h" +#include "../../general.h" typedef struct { @@ -30,13 +30,15 @@ typedef struct static void *ra_init(const char *device, unsigned rate, unsigned latency) { - (void)latency; int err; + roar_vs_t *vss; roar_t *roar = (roar_t*)calloc(1, sizeof(roar_t)); - if (roar == NULL) + + if (!roar) return NULL; - roar_vs_t *vss; + (void)latency; + if ((vss = roar_vs_new_simple(device, "RetroArch", rate, 2, ROAR_CODEC_PCM_S, 16, ROAR_DIR_PLAY, &err)) == NULL) { RARCH_ERR("RoarAudio: \"%s\"\n", roar_vs_strerr(err)); @@ -52,17 +54,18 @@ static void *ra_init(const char *device, unsigned rate, unsigned latency) static ssize_t ra_write(void *data, const void *buf, size_t size) { - roar_t *roar = (roar_t*)data; + int err; ssize_t rc; + size_t written = 0; + roar_t *roar = (roar_t*)data; if (size == 0) return 0; - int err; - size_t written = 0; while (written < size) { size_t write_amt = size - written; + if ((rc = roar_vs_write(roar->vss, (const char*)buf + written, write_amt, &err)) < (ssize_t)write_amt) { if (roar->nonblocking) @@ -87,9 +90,9 @@ static bool ra_stop(void *data) static bool ra_alive(void *data) { roar_t *roar = (roar_t*)data; - if (roar) - return !roar->is_paused; - return false; + if (!roar) + return false; + return !roar->is_paused; } static void ra_set_nonblock_state(void *data, bool state) diff --git a/audio/rwebaudio.c b/audio/drivers/rwebaudio.c similarity index 93% rename from audio/rwebaudio.c rename to audio/drivers/rwebaudio.c index 824ae76e60..e3b9cef65e 100644 --- a/audio/rwebaudio.c +++ b/audio/drivers/rwebaudio.c @@ -13,10 +13,10 @@ * If not, see . */ -#include "../driver.h" -#include "../general.h" +#include "../../driver.h" +#include "../../general.h" -#include "../emscripten/RWebAudio.h" +#include "../../emscripten/RWebAudio.h" static bool rwebaudio_is_paused; @@ -27,9 +27,11 @@ static void rwebaudio_free(void *data) static void *rwebaudio_init(const char *device, unsigned rate, unsigned latency) { + void *data; (void)device; (void)rate; - void *data = RWebAudioInit(latency); + data = RWebAudioInit(latency); + if (data) g_settings.audio.out_rate = RWebAudioSampleRate(); return data; diff --git a/audio/sdl_audio.c b/audio/drivers/sdl_audio.c similarity index 80% rename from audio/sdl_audio.c rename to audio/drivers/sdl_audio.c index 5c1a89ad4c..ba2cca7cb6 100644 --- a/audio/sdl_audio.c +++ b/audio/drivers/sdl_audio.c @@ -14,7 +14,7 @@ */ -#include "../driver.h" +#include "../../driver.h" #include #include #include @@ -25,7 +25,7 @@ #include "SDL_audio.h" #include -#include "../general.h" +#include "../../general.h" #include typedef struct sdl_audio @@ -41,26 +41,36 @@ typedef struct sdl_audio static void sdl_audio_cb(void *data, Uint8 *stream, int len) { sdl_audio_t *sdl = (sdl_audio_t*)data; - size_t avail = fifo_read_avail(sdl->buffer); size_t write_size = len > (int)avail ? avail : len; + fifo_read(sdl->buffer, stream, write_size); scond_signal(sdl->cond); - // If underrun, fill rest with silence. + /* If underrun, fill rest with silence. */ memset(stream + write_size, 0, len - write_size); } static inline int find_num_frames(int rate, int latency) { int frames = (rate * latency) / 1000; - // SDL only likes 2^n sized buffers. + + /* SDL only likes 2^n sized buffers. */ + return next_pow2(frames); } -static void *sdl_audio_init(const char *device, unsigned rate, unsigned latency) +static void *sdl_audio_init(const char *device, + unsigned rate, unsigned latency) { + int frames; + size_t bufsize; + void *tmp; + SDL_AudioSpec out; + SDL_AudioSpec spec = {0}; + sdl_audio_t *sdl = NULL; (void)device; + if (SDL_WasInit(0) == 0) { if (SDL_Init(SDL_INIT_AUDIO) < 0) @@ -69,14 +79,16 @@ static void *sdl_audio_init(const char *device, unsigned rate, unsigned latency) else if (SDL_InitSubSystem(SDL_INIT_AUDIO) < 0) return NULL; - sdl_audio_t *sdl = (sdl_audio_t*)calloc(1, sizeof(*sdl)); + sdl = (sdl_audio_t*)calloc(1, sizeof(*sdl)); if (!sdl) return NULL; - // We have to buffer up some data ourselves, so we let SDL carry approx half of the latency. SDL double buffers audio and we do as well. - int frames = find_num_frames(rate, latency / 4); + /* We have to buffer up some data ourselves, so we let SDL + * carry approximately half of the latency. + * + * SDL double buffers audio and we do as well. */ + frames = find_num_frames(rate, latency / 4); - SDL_AudioSpec spec = {0}; spec.freq = rate; spec.format = AUDIO_S16SYS; spec.channels = 2; @@ -84,8 +96,6 @@ static void *sdl_audio_init(const char *device, unsigned rate, unsigned latency) spec.callback = sdl_audio_cb; spec.userdata = sdl; - SDL_AudioSpec out; - if (SDL_OpenAudio(&spec, &out) < 0) { RARCH_ERR("Failed to open SDL audio: %s\n", SDL_GetError()); @@ -97,12 +107,14 @@ static void *sdl_audio_init(const char *device, unsigned rate, unsigned latency) sdl->lock = slock_new(); sdl->cond = scond_new(); - RARCH_LOG("SDL audio: Requested %u ms latency, got %d ms\n", latency, (int)(out.samples * 4 * 1000 / g_settings.audio.out_rate)); + RARCH_LOG("SDL audio: Requested %u ms latency, got %d ms\n", + latency, (int)(out.samples * 4 * 1000 / g_settings.audio.out_rate)); - // Create a buffer twice as big as needed and prefill the buffer. - size_t bufsize = out.samples * 4 * sizeof(int16_t); - void *tmp = calloc(1, bufsize); + /* Create a buffer twice as big as needed and prefill the buffer. */ + bufsize = out.samples * 4 * sizeof(int16_t); + tmp = calloc(1, bufsize); sdl->buffer = fifo_new(bufsize); + if (tmp) { fifo_write(sdl->buffer, tmp, bufsize); @@ -115,14 +127,16 @@ static void *sdl_audio_init(const char *device, unsigned rate, unsigned latency) static ssize_t sdl_audio_write(void *data, const void *buf, size_t size) { + ssize_t ret = 0; sdl_audio_t *sdl = (sdl_audio_t*)data; - ssize_t ret = 0; if (sdl->nonblock) { + size_t avail, write_amt; + SDL_LockAudio(); - size_t avail = fifo_write_avail(sdl->buffer); - size_t write_amt = avail > size ? size : avail; + avail = fifo_write_avail(sdl->buffer); + write_amt = avail > size ? size : avail; fifo_write(sdl->buffer, buf, write_amt); SDL_UnlockAudio(); ret = write_amt; @@ -130,10 +144,13 @@ static ssize_t sdl_audio_write(void *data, const void *buf, size_t size) else { size_t written = 0; + while (written < size) { + size_t avail; + SDL_LockAudio(); - size_t avail = fifo_write_avail(sdl->buffer); + avail = fifo_write_avail(sdl->buffer); if (avail == 0) { @@ -167,9 +184,9 @@ static bool sdl_audio_stop(void *data) static bool sdl_audio_alive(void *data) { sdl_audio_t *sdl = (sdl_audio_t*)data; - if (sdl) - return !sdl->is_paused; - return false; + if (!sdl) + return false; + return !sdl->is_paused; } static bool sdl_audio_start(void *data) @@ -184,15 +201,17 @@ static bool sdl_audio_start(void *data) static void sdl_audio_set_nonblock_state(void *data, bool state) { sdl_audio_t *sdl = (sdl_audio_t*)data; - sdl->nonblock = state; + if (sdl) + sdl->nonblock = state; } static void sdl_audio_free(void *data) { + sdl_audio_t *sdl = (sdl_audio_t*)data; + SDL_CloseAudio(); SDL_QuitSubSystem(SDL_INIT_AUDIO); - sdl_audio_t *sdl = (sdl_audio_t*)data; if (sdl) { fifo_free(sdl->buffer); diff --git a/audio/xaudio.c b/audio/drivers/xaudio.c similarity index 86% rename from audio/xaudio.c rename to audio/drivers/xaudio.c index 451eca3aef..630e4e646d 100644 --- a/audio/xaudio.c +++ b/audio/drivers/xaudio.c @@ -14,10 +14,10 @@ * If not, see . */ -#include "../driver.h" +#include "../../driver.h" #include -#include "xaudio-c/xaudio-c.h" -#include "../general.h" +#include "../xaudio-c/xaudio-c.h" +#include "../../general.h" typedef struct { @@ -29,21 +29,24 @@ typedef struct static void *xa_init(const char *device, unsigned rate, unsigned latency) { + size_t bufsize; + xa_t *xa; + unsigned device_index = 0; + if (latency < 8) - latency = 8; // Do not allow shenanigans. + latency = 8; /* Do not allow shenanigans. */ xa_t *xa = (xa_t*)calloc(1, sizeof(*xa)); if (!xa) return NULL; - size_t bufsize = latency * rate / 1000; + bufsize = latency * rate / 1000; RARCH_LOG("XAudio2: Requesting %u ms latency, using %d ms latency.\n", latency, (int)bufsize * 1000 / rate); xa->bufsize = bufsize * 2 * sizeof(float); - unsigned device_index = 0; if (device) device_index = strtoul(device, NULL, 0); @@ -63,17 +66,20 @@ static void *xa_init(const char *device, unsigned rate, unsigned latency) static ssize_t xa_write(void *data, const void *buf, size_t size) { + size_t ret; xa_t *xa = (xa_t*)data; + if (xa->nonblock) { size_t avail = xaudio2_write_avail(xa->xa); + if (avail == 0) return 0; if (avail < size) size = avail; } - size_t ret = xaudio2_write(xa->xa, buf, size); + ret = xaudio2_write(xa->xa, buf, size); if (ret == 0 && size > 0) return -1; return ret; @@ -89,15 +95,16 @@ static bool xa_stop(void *data) static bool xa_alive(void *data) { xa_t *xa = (xa_t*)data; - if (xa) - return !xa->is_paused; - return false; + if (!xa) + return false; + return !xa->is_paused; } static void xa_set_nonblock_state(void *data, bool state) { xa_t *xa = (xa_t*)data; - xa->nonblock = state; + if (xa) + xa->nonblock = state; } static bool xa_start(void *data) @@ -116,12 +123,13 @@ static bool xa_use_float(void *data) static void xa_free(void *data) { xa_t *xa = (xa_t*)data; - if (xa) - { - if (xa->xa) - xaudio2_free(xa->xa); - free(xa); - } + + if (!xa) + return; + + if (xa->xa) + xaudio2_free(xa->xa); + free(xa); } static size_t xa_write_avail(void *data) diff --git a/audio/xenon360_audio.c b/audio/drivers/xenon360_audio.c similarity index 93% rename from audio/xenon360_audio.c rename to audio/drivers/xenon360_audio.c index d66d0b36ab..9e8d4b1336 100644 --- a/audio/xenon360_audio.c +++ b/audio/drivers/xenon360_audio.c @@ -14,10 +14,10 @@ * If not, see . */ -#include "../driver.h" +#include "../../driver.h" #include #include -#include "../general.h" +#include "../../general.h" #include @@ -35,6 +35,7 @@ static void *xenon360_audio_init(const char *device, unsigned rate, unsigned latency) { static bool inited = false; + if (!inited) { xenon_sound_init(); @@ -53,12 +54,11 @@ static inline uint32_t bswap_32(uint32_t val) static ssize_t xenon360_audio_write(void *data, const void *buf, size_t size) { + size_t written = 0, i; + const uint32_t *in_buf = buf; xenon_audio_t *xa = data; - size_t written = 0; - - const uint32_t *in_buf = buf; - for (size_t i = 0; i < (size >> 2); i++) + for (i = 0; i < (size >> 2); i++) xa->buffer[i] = bswap_32(in_buf[i]); if (!xa->nonblock) @@ -95,15 +95,16 @@ static bool xenon360_audio_stop(void *data) static bool xenon360_audio_alive(void *data) { xenon_audio_t *xa = data; - if (xa) - return !xa->is_paused; - return false; + if (!xa) + return false; + return !xa->is_paused; } static void xenon360_audio_set_nonblock_state(void *data, bool state) { xenon_audio_t *xa = data; - xa->nonblock = state; + if (xa) + xa->nonblock = state; } static bool xenon360_audio_start(void *data) diff --git a/gfx/context/x11_common.c b/gfx/context/x11_common.c index a2ee7228a9..65c2741054 100644 --- a/gfx/context/x11_common.c +++ b/gfx/context/x11_common.c @@ -57,11 +57,13 @@ void x11_show_mouse(Display *dpy, Window win, bool state) static Atom XA_NET_WM_STATE; static Atom XA_NET_WM_STATE_FULLSCREEN; static Atom XA_NET_MOVERESIZE_WINDOW; + #define XA_INIT(x) XA##x = XInternAtom(dpy, #x, False) #define _NET_WM_STATE_ADD 1 #define MOVERESIZE_GRAVITY_CENTER 5 #define MOVERESIZE_X_SHIFT 8 #define MOVERESIZE_Y_SHIFT 9 + void x11_windowed_fullscreen(Display *dpy, Window win) { XA_INIT(_NET_WM_STATE); @@ -82,7 +84,8 @@ void x11_windowed_fullscreen(Display *dpy, Window win) &xev); } -// Try to be nice to tiling WMs if possible. +/* Try to be nice to tiling WMs if possible. */ + void x11_move_window(Display *dpy, Window win, int x, int y, unsigned width, unsigned height) { @@ -108,7 +111,7 @@ static void x11_set_window_class(Display *dpy, Window win) { XClassHint hint = {0}; - hint.res_name = (char*)"retroarch"; // Broken header. + hint.res_name = (char*)"retroarch"; /* Broken header. */ hint.res_class = (char*)"retroarch"; XSetClassHint(dpy, win, &hint); } @@ -266,10 +269,12 @@ unsigned x11_get_xinerama_monitor(Display *dpy, int x, int y, int len_x = min_rx - max_lx; int len_y = min_by - max_ty; - if (len_x < 0 || len_y < 0) // The whole window is outside the screen. + + if (len_x < 0 || len_y < 0) /* The whole window is outside the screen. */ continue; area = len_x * len_y; + if (area > largest_area) { monitor = i; @@ -285,6 +290,7 @@ unsigned x11_get_xinerama_monitor(Display *dpy, int x, int y, bool x11_create_input_context(Display *dpy, Window win, XIM *xim, XIC *xic) { *xim = XOpenIM(dpy, NULL, NULL, NULL); + if (!*xim) { RARCH_ERR("[X11]: Failed to open input method.\n"); @@ -293,6 +299,7 @@ bool x11_create_input_context(Display *dpy, Window win, XIM *xim, XIC *xic) *xic = XCreateIC(*xim, XNInputStyle, XIMPreeditNothing | XIMStatusNothing, XNClientWindow, win, NULL); + if (!*xic) { RARCH_ERR("[X11]: Failed to create input context.\n"); diff --git a/griffin/griffin.c b/griffin/griffin.c index c3a4baa2e3..2af1e2e39b 100644 --- a/griffin/griffin.c +++ b/griffin/griffin.c @@ -451,48 +451,48 @@ RSOUND AUDIO ============================================================ */ #if defined(__CELLOS_LV2__) -#include "../audio/ps3_audio.c" +#include "../audio/drivers/ps3_audio.c" #elif defined(XENON) -#include "../audio/xenon360_audio.c" +#include "../audio/drivers/xenon360_audio.c" #elif defined(GEKKO) -#include "../audio/gx_audio.c" +#include "../audio/drivers/gx_audio.c" #elif defined(EMSCRIPTEN) -#include "../audio/rwebaudio.c" +#include "../audio/drivers/rwebaudio.c" #elif defined(PSP) -#include "../audio/psp1_audio.c" +#include "../audio/drivers/psp1_audio.c" #endif #ifdef HAVE_XAUDIO -#include "../audio/xaudio.c" +#include "../audio/drivers/xaudio.c" #include "../audio/xaudio-c/xaudio-c.cpp" #endif #ifdef HAVE_DSOUND -#include "../audio/dsound.c" +#include "../audio/drivers/dsound.c" #endif #ifdef HAVE_SL -#include "../audio/opensl.c" +#include "../audio/drivers/opensl.c" #endif #ifdef HAVE_ALSA #ifdef __QNX__ -#include "../audio/alsa_qsa.c" +#include "../audio/drivers/alsa_qsa.c" #else -#include "../audio/alsa.c" -#include "../audio/alsathread.c" +#include "../audio/drivers/alsa.c" +#include "../audio/drivers/alsathread.c" #endif #endif #ifdef HAVE_AL -#include "../audio/openal.c" +#include "../audio/drivers/openal.c" #endif #ifdef HAVE_COREAUDIO -#include "../audio/coreaudio.c" +#include "../audio/drivers/coreaudio.c" #endif -#include "../audio/nullaudio.c" +#include "../audio/drivers/nullaudio.c" /*============================================================ DRIVERS