WASAPI Frame Delay fix + cleanups (#15187)
This commit is contained in:
parent
4d8db0b5b8
commit
07c371533f
|
@ -26,6 +26,9 @@
|
||||||
#include "../../verbosity.h"
|
#include "../../verbosity.h"
|
||||||
#include "../../configuration.h"
|
#include "../../configuration.h"
|
||||||
|
|
||||||
|
/* Get automatic buffer size from client buffer instead of device period */
|
||||||
|
#define USE_CLIENT_BUFFER
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
HANDLE write_event;
|
HANDLE write_event;
|
||||||
|
@ -49,13 +52,9 @@ static IMMDevice *wasapi_init_device(const char *id)
|
||||||
IMMDeviceCollection *collection = NULL;
|
IMMDeviceCollection *collection = NULL;
|
||||||
|
|
||||||
if (id)
|
if (id)
|
||||||
{
|
RARCH_LOG("[WASAPI]: Initializing device: \"%s\"..\n", id);
|
||||||
RARCH_LOG("[WASAPI]: Initializing device %s ...\n", id);
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
RARCH_LOG("[WASAPI]: Initializing default device..\n");
|
||||||
RARCH_LOG("[WASAPI]: Initializing default device.. \n");
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
hr = CoCreateInstance(CLSID_MMDeviceEnumerator, NULL, CLSCTX_ALL,
|
hr = CoCreateInstance(CLSID_MMDeviceEnumerator, NULL, CLSCTX_ALL,
|
||||||
|
@ -80,16 +79,16 @@ static IMMDevice *wasapi_init_device(const char *id)
|
||||||
unsigned i;
|
unsigned i;
|
||||||
for (i = 0; i < list->size; i++)
|
for (i = 0; i < list->size; i++)
|
||||||
{
|
{
|
||||||
RARCH_LOG("[WASAPI]: %d : %s\n", i, list->elems[i].data);
|
|
||||||
if (string_is_equal(id, list->elems[i].data))
|
if (string_is_equal(id, list->elems[i].data))
|
||||||
{
|
{
|
||||||
|
RARCH_DBG("[WASAPI]: Found device #%d: \"%s\"\n", i, list->elems[i].data);
|
||||||
idx_found = i;
|
idx_found = i;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Index was not found yet based on name string,
|
/* Index was not found yet based on name string,
|
||||||
* just assume id is a one-character number index. */
|
* just assume id is a one-character number index. */
|
||||||
|
|
||||||
if (idx_found == -1 && isdigit(id[0]))
|
if (idx_found == -1 && isdigit(id[0]))
|
||||||
{
|
{
|
||||||
idx_found = strtoul(id, NULL, 0);
|
idx_found = strtoul(id, NULL, 0);
|
||||||
|
@ -145,13 +144,9 @@ error:
|
||||||
IFACE_RELEASE(enumerator);
|
IFACE_RELEASE(enumerator);
|
||||||
|
|
||||||
if (id)
|
if (id)
|
||||||
{
|
RARCH_ERR("[WASAPI]: Failed to initialize device: \"%s\".\n", id);
|
||||||
RARCH_WARN("[WASAPI]: Failed to initialize device.\n");
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
{
|
RARCH_ERR("[WASAPI]: Failed to initialize default device.\n");
|
||||||
RARCH_ERR("[WASAPI]: Failed to initialize device.\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -217,20 +212,19 @@ static IAudioClient *wasapi_init_client_sh(IMMDevice *device,
|
||||||
/* for requested rate (first) and all preferred rates */
|
/* for requested rate (first) and all preferred rates */
|
||||||
for (j = 0; rate_res; ++j)
|
for (j = 0; rate_res; ++j)
|
||||||
{
|
{
|
||||||
RARCH_LOG("[WASAPI]: Initializing client (shared, %s, %uHz, %ums) ...\n",
|
RARCH_LOG("[WASAPI]: Initializing client (shared, %s, %uHz, %.1fms)..\n",
|
||||||
float_fmt_res ? "float" : "pcm", rate_res, latency);
|
float_fmt_res ? "float" : "pcm", rate_res, (float)latency);
|
||||||
|
|
||||||
wasapi_set_format(&wf, float_fmt_res, rate_res);
|
wasapi_set_format(&wf, float_fmt_res, rate_res);
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
hr = client->Initialize(AUDCLNT_SHAREMODE_SHARED,
|
hr = client->Initialize(AUDCLNT_SHAREMODE_SHARED,
|
||||||
AUDCLNT_STREAMFLAGS_EVENTCALLBACK | AUDCLNT_STREAMFLAGS_NOPERSIST,
|
AUDCLNT_STREAMFLAGS_EVENTCALLBACK,
|
||||||
0, 0, (WAVEFORMATEX*)&wf, NULL);
|
0, 0, (WAVEFORMATEX*)&wf, NULL);
|
||||||
#else
|
#else
|
||||||
hr = client->lpVtbl->Initialize(client, AUDCLNT_SHAREMODE_SHARED,
|
hr = client->lpVtbl->Initialize(client, AUDCLNT_SHAREMODE_SHARED,
|
||||||
AUDCLNT_STREAMFLAGS_EVENTCALLBACK | AUDCLNT_STREAMFLAGS_NOPERSIST,
|
AUDCLNT_STREAMFLAGS_EVENTCALLBACK,
|
||||||
0, 0, (WAVEFORMATEX*)&wf, NULL);
|
0, 0, (WAVEFORMATEX*)&wf, NULL);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (hr == AUDCLNT_E_ALREADY_INITIALIZED)
|
if (hr == AUDCLNT_E_ALREADY_INITIALIZED)
|
||||||
{
|
{
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
@ -243,11 +237,11 @@ static IAudioClient *wasapi_init_client_sh(IMMDevice *device,
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
hr = client->Initialize(AUDCLNT_SHAREMODE_SHARED,
|
hr = client->Initialize(AUDCLNT_SHAREMODE_SHARED,
|
||||||
AUDCLNT_STREAMFLAGS_EVENTCALLBACK | AUDCLNT_STREAMFLAGS_NOPERSIST,
|
AUDCLNT_STREAMFLAGS_EVENTCALLBACK,
|
||||||
0, 0, (WAVEFORMATEX*)&wf, NULL);
|
0, 0, (WAVEFORMATEX*)&wf, NULL);
|
||||||
#else
|
#else
|
||||||
hr = client->lpVtbl->Initialize(client, AUDCLNT_SHAREMODE_SHARED,
|
hr = client->lpVtbl->Initialize(client, AUDCLNT_SHAREMODE_SHARED,
|
||||||
AUDCLNT_STREAMFLAGS_EVENTCALLBACK | AUDCLNT_STREAMFLAGS_NOPERSIST,
|
AUDCLNT_STREAMFLAGS_EVENTCALLBACK,
|
||||||
0, 0, (WAVEFORMATEX*)&wf, NULL);
|
0, 0, (WAVEFORMATEX*)&wf, NULL);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -259,7 +253,7 @@ static IAudioClient *wasapi_init_client_sh(IMMDevice *device,
|
||||||
|
|
||||||
RARCH_WARN("[WASAPI]: Unsupported format.\n");
|
RARCH_WARN("[WASAPI]: Unsupported format.\n");
|
||||||
rate_res = wasapi_pref_rate(j);
|
rate_res = wasapi_pref_rate(j);
|
||||||
if (rate_res == *rate) /* requested rate is allready tested */
|
if (rate_res == *rate) /* requested rate is already tested */
|
||||||
rate_res = wasapi_pref_rate(++j); /* skip it */
|
rate_res = wasapi_pref_rate(++j); /* skip it */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -314,8 +308,8 @@ static IAudioClient *wasapi_init_client_ex(IMMDevice *device,
|
||||||
/* for requested rate (first) and all preferred rates */
|
/* for requested rate (first) and all preferred rates */
|
||||||
for (j = 0; rate_res; ++j)
|
for (j = 0; rate_res; ++j)
|
||||||
{
|
{
|
||||||
RARCH_LOG("[WASAPI]: Initializing client (exclusive, %s, %uHz, %ums) ...\n",
|
RARCH_LOG("[WASAPI]: Initializing client (exclusive, %s, %uHz, %.1fms)..\n",
|
||||||
float_fmt_res ? "float" : "pcm", rate_res, latency);
|
float_fmt_res ? "float" : "pcm", rate_res, (float)latency);
|
||||||
|
|
||||||
wasapi_set_format(&wf, float_fmt_res, rate_res);
|
wasapi_set_format(&wf, float_fmt_res, rate_res);
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
@ -341,6 +335,7 @@ static IAudioClient *wasapi_init_client_ex(IMMDevice *device,
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
buffer_duration = 10000.0 * 1000.0 / rate_res * buffer_length + 0.5;
|
buffer_duration = 10000.0 * 1000.0 / rate_res * buffer_length + 0.5;
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
hr = client->Initialize(AUDCLNT_SHAREMODE_EXCLUSIVE,
|
hr = client->Initialize(AUDCLNT_SHAREMODE_EXCLUSIVE,
|
||||||
AUDCLNT_STREAMFLAGS_EVENTCALLBACK | AUDCLNT_STREAMFLAGS_NOPERSIST,
|
AUDCLNT_STREAMFLAGS_EVENTCALLBACK | AUDCLNT_STREAMFLAGS_NOPERSIST,
|
||||||
|
@ -384,7 +379,7 @@ static IAudioClient *wasapi_init_client_ex(IMMDevice *device,
|
||||||
|
|
||||||
RARCH_WARN("[WASAPI]: Unsupported format.\n");
|
RARCH_WARN("[WASAPI]: Unsupported format.\n");
|
||||||
rate_res = wasapi_pref_rate(j);
|
rate_res = wasapi_pref_rate(j);
|
||||||
if (rate_res == *rate) /* requested rate is allready tested */
|
if (rate_res == *rate) /* requested rate is already tested */
|
||||||
rate_res = wasapi_pref_rate(++j); /* skip it */
|
rate_res = wasapi_pref_rate(++j); /* skip it */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -445,24 +440,18 @@ static IAudioClient *wasapi_init_client(IMMDevice *device, bool *exclusive,
|
||||||
hr = _IAudioClient_GetDevicePeriod(client, &device_period, NULL);
|
hr = _IAudioClient_GetDevicePeriod(client, &device_period, NULL);
|
||||||
|
|
||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
{
|
|
||||||
RARCH_WARN("[WASAPI]: IAudioClient::GetDevicePeriod failed with error 0x%.8X.\n", hr);
|
RARCH_WARN("[WASAPI]: IAudioClient::GetDevicePeriod failed with error 0x%.8X.\n", hr);
|
||||||
}
|
|
||||||
|
|
||||||
if (!*exclusive)
|
if (!*exclusive)
|
||||||
{
|
{
|
||||||
hr = _IAudioClient_GetStreamLatency(client, &stream_latency);
|
hr = _IAudioClient_GetStreamLatency(client, &stream_latency);
|
||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
{
|
|
||||||
RARCH_WARN("[WASAPI]: IAudioClient::GetStreamLatency failed with error 0x%.8X.\n", hr);
|
RARCH_WARN("[WASAPI]: IAudioClient::GetStreamLatency failed with error 0x%.8X.\n", hr);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
hr = _IAudioClient_GetBufferSize(client, &buffer_length);
|
hr = _IAudioClient_GetBufferSize(client, &buffer_length);
|
||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
{
|
|
||||||
RARCH_WARN("[WASAPI]: IAudioClient::GetBufferSize failed with error 0x%.8X.\n", hr);
|
RARCH_WARN("[WASAPI]: IAudioClient::GetBufferSize failed with error 0x%.8X.\n", hr);
|
||||||
}
|
|
||||||
|
|
||||||
if (*exclusive)
|
if (*exclusive)
|
||||||
latency_res = (double)buffer_length * 1000.0 / (*rate);
|
latency_res = (double)buffer_length * 1000.0 / (*rate);
|
||||||
|
@ -471,13 +460,16 @@ static IAudioClient *wasapi_init_client(IMMDevice *device, bool *exclusive,
|
||||||
|
|
||||||
RARCH_LOG("[WASAPI]: Client initialized (%s, %s, %uHz, %.1fms).\n",
|
RARCH_LOG("[WASAPI]: Client initialized (%s, %s, %uHz, %.1fms).\n",
|
||||||
*exclusive ? "exclusive" : "shared",
|
*exclusive ? "exclusive" : "shared",
|
||||||
*float_fmt ? "float" : "pcm", *rate, latency_res);
|
*float_fmt ? "float" : "pcm",
|
||||||
|
*rate, latency_res);
|
||||||
|
|
||||||
RARCH_LOG("[WASAPI]: Client's buffer length is %u frames (%.1fms).\n",
|
RARCH_LOG("[WASAPI]: Client buffer length is %u frames (%.1fms).\n",
|
||||||
buffer_length, (double)buffer_length * 1000.0 / (*rate));
|
buffer_length,
|
||||||
|
(double)buffer_length * 1000.0 / (*rate));
|
||||||
|
|
||||||
RARCH_LOG("[WASAPI]: Device period is %.1fms (%lld frames).\n",
|
RARCH_LOG("[WASAPI]: Device period is %.1fms (%lld frames).\n",
|
||||||
(double)device_period / 10000.0, device_period * (*rate) / 10000000);
|
(double)device_period / 10000.0,
|
||||||
|
device_period * (*rate) / 10000000);
|
||||||
|
|
||||||
return client;
|
return client;
|
||||||
}
|
}
|
||||||
|
@ -530,11 +522,16 @@ static void *wasapi_init(const char *dev_id, unsigned rate, unsigned latency,
|
||||||
{
|
{
|
||||||
if (sh_buffer_length < 0)
|
if (sh_buffer_length < 0)
|
||||||
{
|
{
|
||||||
|
#ifdef USE_CLIENT_BUFFER
|
||||||
|
sh_buffer_length = frame_count;
|
||||||
|
#else
|
||||||
hr = _IAudioClient_GetDevicePeriod(w->client, &dev_period, NULL);
|
hr = _IAudioClient_GetDevicePeriod(w->client, &dev_period, NULL);
|
||||||
|
|
||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
sh_buffer_length = dev_period * rate / 10000000;
|
sh_buffer_length = dev_period * rate / 10000000;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
w->buffer = fifo_new(sh_buffer_length * w->frame_size);
|
w->buffer = fifo_new(sh_buffer_length * w->frame_size);
|
||||||
|
@ -575,6 +572,7 @@ static void *wasapi_init(const char *dev_id, unsigned rate, unsigned latency,
|
||||||
hr = _IAudioClient_Start(w->client);
|
hr = _IAudioClient_Start(w->client);
|
||||||
if (FAILED(hr))
|
if (FAILED(hr))
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
w->running = true;
|
w->running = true;
|
||||||
w->nonblock = !settings->bools.audio_sync;
|
w->nonblock = !settings->bools.audio_sync;
|
||||||
|
|
||||||
|
@ -603,9 +601,9 @@ static bool wasapi_flush(wasapi_t * w, const void * data, size_t size)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
memcpy(dest, data, size);
|
memcpy(dest, data, size);
|
||||||
|
|
||||||
if (FAILED(_IAudioRenderClient_ReleaseBuffer(
|
if (FAILED(_IAudioRenderClient_ReleaseBuffer(
|
||||||
w->renderer, frame_count,
|
w->renderer, frame_count, 0)))
|
||||||
0)))
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -615,14 +613,15 @@ static bool wasapi_flush_buffer(wasapi_t * w, size_t size)
|
||||||
{
|
{
|
||||||
BYTE *dest = NULL;
|
BYTE *dest = NULL;
|
||||||
UINT32 frame_count = size / w->frame_size;
|
UINT32 frame_count = size / w->frame_size;
|
||||||
|
|
||||||
if (FAILED(_IAudioRenderClient_GetBuffer(
|
if (FAILED(_IAudioRenderClient_GetBuffer(
|
||||||
w->renderer, frame_count, &dest)))
|
w->renderer, frame_count, &dest)))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
fifo_read(w->buffer, dest, size);
|
fifo_read(w->buffer, dest, size);
|
||||||
|
|
||||||
if (FAILED(_IAudioRenderClient_ReleaseBuffer(
|
if (FAILED(_IAudioRenderClient_ReleaseBuffer(
|
||||||
w->renderer, frame_count,
|
w->renderer, frame_count, 0)))
|
||||||
0)))
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -631,8 +630,8 @@ static bool wasapi_flush_buffer(wasapi_t * w, size_t size)
|
||||||
static ssize_t wasapi_write_sh_buffer(wasapi_t *w, const void * data, size_t size)
|
static ssize_t wasapi_write_sh_buffer(wasapi_t *w, const void * data, size_t size)
|
||||||
{
|
{
|
||||||
ssize_t written = -1;
|
ssize_t written = -1;
|
||||||
UINT32 padding = 0;
|
|
||||||
size_t write_avail = FIFO_WRITE_AVAIL(w->buffer);
|
size_t write_avail = FIFO_WRITE_AVAIL(w->buffer);
|
||||||
|
UINT32 padding = 0;
|
||||||
|
|
||||||
if (!write_avail)
|
if (!write_avail)
|
||||||
{
|
{
|
||||||
|
@ -661,8 +660,8 @@ static ssize_t wasapi_write_sh_buffer(wasapi_t *w, const void * data, size_t siz
|
||||||
|
|
||||||
static ssize_t wasapi_write_sh(wasapi_t *w, const void * data, size_t size)
|
static ssize_t wasapi_write_sh(wasapi_t *w, const void * data, size_t size)
|
||||||
{
|
{
|
||||||
size_t write_avail = 0;
|
|
||||||
ssize_t written = -1;
|
ssize_t written = -1;
|
||||||
|
size_t write_avail = 0;
|
||||||
UINT32 padding = 0;
|
UINT32 padding = 0;
|
||||||
|
|
||||||
if (!(WaitForSingleObject(w->write_event, INFINITE) == WAIT_OBJECT_0))
|
if (!(WaitForSingleObject(w->write_event, INFINITE) == WAIT_OBJECT_0))
|
||||||
|
@ -685,8 +684,8 @@ static ssize_t wasapi_write_sh(wasapi_t *w, const void * data, size_t size)
|
||||||
|
|
||||||
static ssize_t wasapi_write_sh_nonblock(wasapi_t *w, const void * data, size_t size)
|
static ssize_t wasapi_write_sh_nonblock(wasapi_t *w, const void * data, size_t size)
|
||||||
{
|
{
|
||||||
size_t write_avail = 0;
|
|
||||||
ssize_t written = -1;
|
ssize_t written = -1;
|
||||||
|
size_t write_avail = 0;
|
||||||
UINT32 padding = 0;
|
UINT32 padding = 0;
|
||||||
|
|
||||||
if (w->buffer)
|
if (w->buffer)
|
||||||
|
@ -801,6 +800,7 @@ static ssize_t wasapi_write(void *wh, const void *data, size_t size)
|
||||||
static bool wasapi_stop(void *wh)
|
static bool wasapi_stop(void *wh)
|
||||||
{
|
{
|
||||||
wasapi_t *w = (wasapi_t*)wh;
|
wasapi_t *w = (wasapi_t*)wh;
|
||||||
|
|
||||||
if (FAILED(_IAudioClient_Stop(w->client)))
|
if (FAILED(_IAudioClient_Stop(w->client)))
|
||||||
return !w->running;
|
return !w->running;
|
||||||
|
|
||||||
|
@ -836,7 +836,7 @@ static void wasapi_set_nonblock_state(void *wh, bool nonblock)
|
||||||
{
|
{
|
||||||
wasapi_t *w = (wasapi_t*)wh;
|
wasapi_t *w = (wasapi_t*)wh;
|
||||||
|
|
||||||
RARCH_LOG("[WASAPI]: Sync %s.\n", nonblock ? "off" : "on");
|
RARCH_DBG("[WASAPI]: Sync %s.\n", nonblock ? "off" : "on");
|
||||||
|
|
||||||
w->nonblock = nonblock;
|
w->nonblock = nonblock;
|
||||||
}
|
}
|
||||||
|
@ -858,9 +858,7 @@ static void wasapi_free(void *wh)
|
||||||
|
|
||||||
ir = WaitForSingleObject(write_event, 20);
|
ir = WaitForSingleObject(write_event, 20);
|
||||||
if (ir == WAIT_FAILED)
|
if (ir == WAIT_FAILED)
|
||||||
{
|
|
||||||
RARCH_ERR("[WASAPI]: WaitForSingleObject failed with error %d.\n", GetLastError());
|
RARCH_ERR("[WASAPI]: WaitForSingleObject failed with error %d.\n", GetLastError());
|
||||||
}
|
|
||||||
|
|
||||||
/* If event isn't signaled log and leak */
|
/* If event isn't signaled log and leak */
|
||||||
if (!(ir == WAIT_OBJECT_0))
|
if (!(ir == WAIT_OBJECT_0))
|
||||||
|
|
10
config.def.h
10
config.def.h
|
@ -1115,9 +1115,9 @@
|
||||||
|
|
||||||
#ifdef HAVE_WASAPI
|
#ifdef HAVE_WASAPI
|
||||||
/* WASAPI defaults */
|
/* WASAPI defaults */
|
||||||
#define DEFAULT_WASAPI_EXCLUSIVE_MODE true
|
#define DEFAULT_WASAPI_EXCLUSIVE_MODE false
|
||||||
#define DEFAULT_WASAPI_FLOAT_FORMAT false
|
#define DEFAULT_WASAPI_FLOAT_FORMAT false
|
||||||
/* auto */
|
/* Automatic shared mode buffer */
|
||||||
#define DEFAULT_WASAPI_SH_BUFFER_LENGTH -16
|
#define DEFAULT_WASAPI_SH_BUFFER_LENGTH -16
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -1554,8 +1554,12 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* MIDI */
|
/* MIDI */
|
||||||
#define DEFAULT_MIDI_INPUT "OFF"
|
#if defined(_WIN32) && !defined(_XBOX) && !defined(__WINRT__)
|
||||||
|
#define DEFAULT_MIDI_OUTPUT "Microsoft GS Wavetable Synth"
|
||||||
|
#else
|
||||||
#define DEFAULT_MIDI_OUTPUT "OFF"
|
#define DEFAULT_MIDI_OUTPUT "OFF"
|
||||||
|
#endif
|
||||||
|
#define DEFAULT_MIDI_INPUT "OFF"
|
||||||
#define DEFAULT_MIDI_VOLUME 100
|
#define DEFAULT_MIDI_VOLUME 100
|
||||||
|
|
||||||
#ifdef HAVE_MIST
|
#ifdef HAVE_MIST
|
||||||
|
|
|
@ -5119,8 +5119,7 @@ static void setting_get_string_representation_int_audio_wasapi_sh_buffer_length(
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (*setting->value.target.integer > 0)
|
if (*setting->value.target.integer > 0)
|
||||||
snprintf(s, len, "%d",
|
snprintf(s, len, "%d", *setting->value.target.integer);
|
||||||
*setting->value.target.integer);
|
|
||||||
else if (*setting->value.target.integer == 0)
|
else if (*setting->value.target.integer == 0)
|
||||||
strlcpy(s, "0 (Off)", len);
|
strlcpy(s, "0 (Off)", len);
|
||||||
else
|
else
|
||||||
|
|
|
@ -22,6 +22,11 @@
|
||||||
#include "midi_driver.h"
|
#include "midi_driver.h"
|
||||||
#include "verbosity.h"
|
#include "verbosity.h"
|
||||||
|
|
||||||
|
#ifdef HAVE_WASAPI
|
||||||
|
#include "audio/audio_driver.h"
|
||||||
|
#include "gfx/video_driver.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#define MIDI_DRIVER_BUF_SIZE 4096
|
#define MIDI_DRIVER_BUF_SIZE 4096
|
||||||
#define MIDI_DRIVER_OFF "OFF"
|
#define MIDI_DRIVER_OFF "OFF"
|
||||||
|
|
||||||
|
@ -116,6 +121,19 @@ bool midi_driver_set_all_sounds_off(void)
|
||||||
if (!rarch_midi_drv_data || !rarch_midi_drv_output_enabled)
|
if (!rarch_midi_drv_data || !rarch_midi_drv_output_enabled)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
#ifdef HAVE_WASAPI
|
||||||
|
/* FIXME: Due to some mysterious reason Frame Delay does not
|
||||||
|
* work with WASAPI unless MIDI output is active, even when
|
||||||
|
* MIDI is not used. Frame Delay also breaks if MIDI sounds
|
||||||
|
* are "set off", which happens on menu toggle, therefore
|
||||||
|
* skip this if WASAPI is used and Frame Delay is effective.. */
|
||||||
|
if (string_is_equal(audio_state_get_ptr()->current_audio->ident, "wasapi"))
|
||||||
|
{
|
||||||
|
if (video_state_get_ptr()->frame_delay_effective > 0)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
event.data = data;
|
event.data = data;
|
||||||
event.data_size = sizeof(data);
|
event.data_size = sizeof(data);
|
||||||
event.delta_time = 0;
|
event.delta_time = 0;
|
||||||
|
|
Loading…
Reference in New Issue