From fa00cdba20fc2d3721523eabda55f65935b6e09e Mon Sep 17 00:00:00 2001 From: twinaphex Date: Fri, 3 Jan 2020 21:54:09 +0100 Subject: [PATCH] (Audio) Update --- audio/drivers/dsound.c | 40 +------ audio/drivers/wasapi.c | 244 ++++++++++++----------------------------- audio/drivers/xaudio.c | 73 ++---------- 3 files changed, 78 insertions(+), 279 deletions(-) diff --git a/audio/drivers/dsound.c b/audio/drivers/dsound.c index 23676b419d..948792c460 100644 --- a/audio/drivers/dsound.c +++ b/audio/drivers/dsound.c @@ -53,10 +53,6 @@ #pragma comment(lib, "dxguid") #endif -/* Forward declarations */ -static ssize_t dsound_write_nonblock(void *data, const void *buf_, size_t size); -static ssize_t dsound_write(void *data, const void *buf_, size_t size); - typedef struct dsound { LPDIRECTSOUND ds; @@ -489,40 +485,6 @@ static void dsound_set_nonblock_state(void *data, bool state) dsound_t *ds = (dsound_t*)data; if (ds) ds->nonblock = state; - - if (ds->nonblock) - audio_dsound.write = dsound_write_nonblock; - else - audio_dsound.write = dsound_write; -} - -static ssize_t dsound_write_nonblock(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; - - if (size > 0) - { - size_t avail; - - EnterCriticalSection(&ds->crit); - avail = fifo_write_avail(ds->buffer); - if (avail > size) - avail = size; - - fifo_write(ds->buffer, buf, avail); - LeaveCriticalSection(&ds->crit); - - buf += avail; - size -= avail; - written += avail; - } - - return written; } static ssize_t dsound_write(void *data, const void *buf_, size_t size) @@ -550,7 +512,7 @@ static ssize_t dsound_write(void *data, const void *buf_, size_t size) size -= avail; written += avail; - if (!ds->thread_alive) + if (ds->nonblock || !ds->thread_alive) break; if (avail == 0) diff --git a/audio/drivers/wasapi.c b/audio/drivers/wasapi.c index 9303f5d8a6..e4425a53c4 100644 --- a/audio/drivers/wasapi.c +++ b/audio/drivers/wasapi.c @@ -40,12 +40,6 @@ typedef struct fifo_buffer_t *buffer; /* NULL in unbuffered shared mode */ } wasapi_t; -/* forward declaration */ -static ssize_t wasapi_write_blocking_exclusive(void *wh, const void *data, size_t size); -static ssize_t wasapi_write_blocking(void *wh, const void *data, size_t size); -static ssize_t wasapi_write_ex(void *wh, const void *data, size_t size); -static ssize_t wasapi_write_sh(void *wh, const void *data, size_t size); - static IMMDevice *wasapi_init_device(const char *id) { HRESULT hr; @@ -583,21 +577,6 @@ static void *wasapi_init(const char *dev_id, unsigned rate, unsigned latency, w->running = true; w->blocking = settings->bools.audio_sync; - if (w->blocking) - { - if (w->exclusive) - audio_wasapi.write = wasapi_write_blocking_exclusive; - else - audio_wasapi.write = wasapi_write_blocking; - } - else - { - if (w->exclusive) - audio_wasapi.write = wasapi_write_ex; - else - audio_wasapi.write = wasapi_write_sh; - } - return w; error: @@ -651,7 +630,7 @@ static bool wasapi_flush_buffer(wasapi_t * w, size_t size) return true; } -static ssize_t wasapi_write_sh_blocking(wasapi_t *w, const void * data, size_t size) +static ssize_t wasapi_write_sh(wasapi_t *w, const void * data, size_t size) { DWORD ir; HRESULT hr; @@ -666,33 +645,39 @@ static ssize_t wasapi_write_sh_blocking(wasapi_t *w, const void * data, size_t s { size_t read_avail = 0; + if (w->blocking) + { + ir = WaitForSingleObject(w->write_event, INFINITE); + if (!(ir == WAIT_OBJECT_0)) + return -1; + } + + hr = _IAudioClient_GetCurrentPadding(w->client, &padding); + if (FAILED(hr)) + return -1; + + read_avail = fifo_read_avail(w->buffer); + write_avail = w->engine_buffer_size - padding * w->frame_size; + written = read_avail < write_avail ? read_avail : write_avail; + if (written) + if (!wasapi_flush_buffer(w, written)) + return -1; + } + + write_avail = fifo_write_avail(w->buffer); + written = size < write_avail ? size : write_avail; + if (written) + fifo_write(w->buffer, data, written); + } + else + { + if (w->blocking) + { ir = WaitForSingleObject(w->write_event, INFINITE); if (!(ir == WAIT_OBJECT_0)) return -1; - - hr = _IAudioClient_GetCurrentPadding(w->client, &padding); - if (FAILED(hr)) - return -1; - - read_avail = fifo_read_avail(w->buffer); - write_avail = w->engine_buffer_size - padding * w->frame_size; - written = read_avail < write_avail ? read_avail : write_avail; - if (written) - if (!wasapi_flush_buffer(w, written)) - return -1; } - write_avail = fifo_write_avail(w->buffer); - written = size < write_avail ? size : write_avail; - if (written) - fifo_write(w->buffer, data, written); - } - else - { - ir = WaitForSingleObject(w->write_event, INFINITE); - if (!(ir == WAIT_OBJECT_0)) - return -1; - hr = _IAudioClient_GetCurrentPadding(w->client, &padding); if (FAILED(hr)) return -1; @@ -710,135 +695,56 @@ static ssize_t wasapi_write_sh_blocking(wasapi_t *w, const void * data, size_t s return written; } -static ssize_t wasapi_write_sh(void *_data, const void * data, size_t size) +static ssize_t wasapi_write_ex(wasapi_t *w, const void * data, size_t size) { - DWORD ir; - HRESULT hr; - size_t write_avail = 0; - ssize_t written = -1; - UINT32 padding = 0; - wasapi_t *w = (wasapi_t*)_data; + ssize_t written = 0; + size_t write_avail = fifo_write_avail(w->buffer); - if (w->buffer) + if (!write_avail) { - write_avail = fifo_write_avail(w->buffer); - if (!write_avail) + DWORD ir = WaitForSingleObject( + w->write_event, w->blocking ? INFINITE : 0); + if (ir != WAIT_OBJECT_0) { - size_t read_avail = 0; - - hr = _IAudioClient_GetCurrentPadding(w->client, &padding); - if (FAILED(hr)) + if (w->blocking) return -1; - - read_avail = fifo_read_avail(w->buffer); - write_avail = w->engine_buffer_size - padding * w->frame_size; - written = read_avail < write_avail ? read_avail : write_avail; - if (written) - if (!wasapi_flush_buffer(w, written)) - return -1; + return 0; } - write_avail = fifo_write_avail(w->buffer); - written = size < write_avail ? size : write_avail; - if (written) - fifo_write(w->buffer, data, written); - } - else - { - hr = _IAudioClient_GetCurrentPadding(w->client, &padding); - if (FAILED(hr)) + if (!wasapi_flush_buffer(w, w->engine_buffer_size)) return -1; - write_avail = w->engine_buffer_size - padding * w->frame_size; - if (!write_avail) - return 0; + write_avail = w->engine_buffer_size; + } - written = size < write_avail ? size : write_avail; - if (written) - if (!wasapi_flush(w, data, written)) + written = size < write_avail ? size : write_avail; + fifo_write(w->buffer, data, written); + + return written; +} + +static ssize_t wasapi_write(void *wh, const void *data, size_t size) +{ + size_t written; + wasapi_t *w = (wasapi_t*)wh; + + if (w->blocking) + { + ssize_t ir; + for (written = 0, ir = -1; written < size; written += ir) + { + if (w->exclusive) + ir = wasapi_write_ex(w, (char*)data + written, size - written); + else + ir = wasapi_write_sh(w, (char*)data + written, size - written); + if (ir == -1) return -1; + } } - - return written; -} - -static ssize_t wasapi_write_ex_blocking(wasapi_t *w, const void * data, size_t size) -{ - ssize_t written = 0; - size_t write_avail = fifo_write_avail(w->buffer); - - if (!write_avail) - { - DWORD ir = WaitForSingleObject( - w->write_event, INFINITE); - if (ir != WAIT_OBJECT_0) - return -1; - - if (!wasapi_flush_buffer(w, w->engine_buffer_size)) - return -1; - - write_avail = w->engine_buffer_size; - } - - written = size < write_avail ? size : write_avail; - fifo_write(w->buffer, data, written); - - return written; -} - -static ssize_t wasapi_write_ex(void *_data, const void * data, size_t size) -{ - ssize_t written = 0; - wasapi_t *w = (wasapi_t*)_data; - size_t write_avail = fifo_write_avail(w->buffer); - - if (!write_avail) - { - DWORD ir = WaitForSingleObject( - w->write_event, 0); - if (ir != WAIT_OBJECT_0) - return 0; - - if (!wasapi_flush_buffer(w, w->engine_buffer_size)) - return -1; - - write_avail = w->engine_buffer_size; - } - - written = size < write_avail ? size : write_avail; - fifo_write(w->buffer, data, written); - - return written; -} - -static ssize_t wasapi_write_blocking_exclusive(void *wh, const void *data, size_t size) -{ - ssize_t ir; - size_t written; - wasapi_t *w = (wasapi_t*)wh; - - for (written = 0, ir = -1; written < size; written += ir) - { - ir = wasapi_write_ex_blocking(w, (char*)data + written, size - written); - if (ir == -1) - return -1; - } - - return written; -} - -static ssize_t wasapi_write_blocking(void *wh, const void *data, size_t size) -{ - ssize_t ir; - size_t written; - wasapi_t *w = (wasapi_t*)wh; - - for (written = 0, ir = -1; written < size; written += ir) - { - ir = wasapi_write_sh_blocking(w, (char*)data + written, size - written); - if (ir == -1) - return -1; - } + else if (w->exclusive) + written = wasapi_write_ex(w, data, size); + else + written = wasapi_write_sh(w, data, size); return written; } @@ -885,20 +791,6 @@ static void wasapi_set_nonblock_state(void *wh, bool nonblock) RARCH_LOG("[WASAPI]: Sync %s.\n", nonblock ? "off" : "on"); w->blocking = !nonblock; - if (w->blocking) - { - if (w->exclusive) - audio_wasapi.write = wasapi_write_blocking_exclusive; - else - audio_wasapi.write = wasapi_write_blocking; - } - else - { - if (w->exclusive) - audio_wasapi.write = wasapi_write_ex; - else - audio_wasapi.write = wasapi_write_sh; - } } static void wasapi_free(void *wh) @@ -972,7 +864,7 @@ static size_t wasapi_buffer_size(void *wh) audio_driver_t audio_wasapi = { wasapi_init, - wasapi_write_sh, + wasapi_write, wasapi_stop, wasapi_start, wasapi_alive, diff --git a/audio/drivers/xaudio.c b/audio/drivers/xaudio.c index 3f5ab74fbe..2b9532a529 100644 --- a/audio/drivers/xaudio.c +++ b/audio/drivers/xaudio.c @@ -322,73 +322,24 @@ static void *xa_init(const char *device, unsigned rate, unsigned latency, return xa; } -static ssize_t xa_write_nonblock(void *data, const void *buf, size_t size) +static ssize_t xa_write(void *data, const void *buf, size_t size) { unsigned bytes; xa_t *xa = (xa_t*)data; xaudio2_t *handle = xa->xa; const uint8_t *buffer = (const uint8_t*)buf; - size_t avail = XAUDIO2_WRITE_AVAILABLE(xa->xa); - if (avail == 0) - return 0; - if (avail < size) - size = avail; - - bytes = size; - - while (bytes) + if (xa->nonblock) { - unsigned need = MIN(bytes, handle->bufsize - handle->bufptr); + size_t avail = XAUDIO2_WRITE_AVAILABLE(xa->xa); - memcpy(handle->buf + handle->write_buffer * - handle->bufsize + handle->bufptr, - buffer, need); - - handle->bufptr += need; - buffer += need; - bytes -= need; - - if (handle->bufptr == handle->bufsize) - { - XAUDIO2_BUFFER xa2buffer; - - while (handle->buffers == MAX_BUFFERS - 1) - WaitForSingleObject(handle->hEvent, INFINITE); - - xa2buffer.Flags = 0; - xa2buffer.AudioBytes = handle->bufsize; - xa2buffer.pAudioData = handle->buf + handle->write_buffer * handle->bufsize; - xa2buffer.PlayBegin = 0; - xa2buffer.PlayLength = 0; - xa2buffer.LoopBegin = 0; - xa2buffer.LoopLength = 0; - xa2buffer.LoopCount = 0; - xa2buffer.pContext = NULL; - - if (FAILED(IXAudio2SourceVoice_SubmitSourceBuffer( - handle->pSourceVoice, &xa2buffer, NULL))) - { - if (size > 0) - return -1; - return 0; - } - - InterlockedIncrement((LONG volatile*)&handle->buffers); - handle->bufptr = 0; - handle->write_buffer = (handle->write_buffer + 1) & MAX_BUFFERS_MASK; - } + if (avail == 0) + return 0; + if (avail < size) + size = avail; } - return size; -} - -static ssize_t xa_write(void *data, const void *buf, size_t size) -{ - xa_t *xa = (xa_t*)data; - xaudio2_t *handle = xa->xa; - const uint8_t *buffer = (const uint8_t*)buf; - unsigned bytes = size; + bytes = size; while (bytes) { @@ -455,13 +406,7 @@ static void xa_set_nonblock_state(void *data, bool state) { xa_t *xa = (xa_t*)data; if (xa) - { - xa->nonblock = state; - if (xa->nonblock) - audio_xa.write = xa_write_nonblock; - else - audio_xa.write = xa_write; - } + xa->nonblock = state; } static bool xa_start(void *data, bool is_shutdown)