summaryrefslogtreecommitdiffstats
path: root/audio/out/ao_wasapi.c
diff options
context:
space:
mode:
Diffstat (limited to 'audio/out/ao_wasapi.c')
-rw-r--r--audio/out/ao_wasapi.c53
1 files changed, 37 insertions, 16 deletions
diff --git a/audio/out/ao_wasapi.c b/audio/out/ao_wasapi.c
index 89f51c4295..75318c22ee 100644
--- a/audio/out/ao_wasapi.c
+++ b/audio/out/ao_wasapi.c
@@ -113,6 +113,33 @@ exit_label:
return;
}
+static void thread_resume(struct ao *ao)
+{
+ struct wasapi_state *state = (struct wasapi_state *)ao->priv;
+ HRESULT hr;
+
+ MP_DBG(state, "Thread Resume\n");
+ UINT32 padding = 0;
+ hr = IAudioClient_GetCurrentPadding(state->pAudioClient, &padding);
+ if (hr != S_OK) {
+ MP_ERR(state, "IAudioClient_GetCurrentPadding returned %s (0x%"PRIx32")\n",
+ wasapi_explain_err(hr), (uint32_t) hr);
+ }
+
+ /* Fill the buffer before starting, but only if there is no audio queued to play. */
+ /* This prevents overfilling the buffer, which leads to problems in exclusive mode */
+ if (padding < (UINT32)state->bufferFrameCount)
+ thread_feed(ao);
+
+ hr = IAudioClient_Start(state->pAudioClient);
+ if (hr != S_OK) {
+ MP_ERR(state, "IAudioClient_Start returned %s (0x%"PRIx32")\n",
+ wasapi_explain_err(hr), (uint32_t) hr);
+ }
+
+ return;
+}
+
static void thread_reset(struct ao *ao)
{
struct wasapi_state *state = (struct wasapi_state *)ao->priv;
@@ -151,7 +178,7 @@ static DWORD __stdcall ThreadLoop(void *lpParameter)
DWORD waitstatus;
HANDLE playcontrol[] =
- {state->hUninit, state->hFeed, state->hForceFeed, state->hReset, NULL};
+ {state->hUninit, state->hFeed, state->hReset, state->hResume, NULL};
MP_DBG(ao, "Entering dispatch loop\n");
while (true) { /* watch events */
waitstatus = MsgWaitForMultipleObjects(4, playcontrol, FALSE, INFINITE,
@@ -163,13 +190,12 @@ static DWORD __stdcall ThreadLoop(void *lpParameter)
case (WAIT_OBJECT_0 + 1): /* feed */
thread_feed(ao);
break;
- case (WAIT_OBJECT_0 + 2): /* force feed */
- thread_feed(ao);
- SetEvent(state->hFeedDone);
- break;
- case (WAIT_OBJECT_0 + 3): /* reset */
+ case (WAIT_OBJECT_0 + 2): /* reset */
thread_reset(ao);
- break;
+ break;
+ case (WAIT_OBJECT_0 + 3): /* resume */
+ thread_resume(ao);
+ break;
case (WAIT_OBJECT_0 + 4): /* messages to dispatch (COM marshalling) */
MP_DBG(ao, "Dispatch\n");
wasapi_dispatch();
@@ -193,8 +219,7 @@ static void closehandles(struct ao *ao)
if (state->init_done) CloseHandle(state->init_done);
if (state->hUninit) CloseHandle(state->hUninit);
if (state->hFeed) CloseHandle(state->hFeed);
- if (state->hForceFeed) CloseHandle(state->hForceFeed);
- if (state->hFeedDone) CloseHandle(state->hFeedDone);
+ if (state->hResume) CloseHandle(state->hResume);
if (state->hReset) CloseHandle(state->hReset);
if (state->threadLoop) CloseHandle(state->threadLoop);
}
@@ -249,11 +274,10 @@ static int init(struct ao *ao)
state->init_done = CreateEventW(NULL, FALSE, FALSE, NULL);
state->hUninit = CreateEventW(NULL, FALSE, FALSE, NULL);
state->hFeed = CreateEventW(NULL, FALSE, FALSE, NULL); /* for wasapi event mode */
- state->hForceFeed = CreateEventW(NULL, FALSE, FALSE, NULL);
- state->hFeedDone = CreateEventW(NULL, FALSE, FALSE, NULL);
+ state->hResume = CreateEventW(NULL, FALSE, FALSE, NULL);
state->hReset = CreateEventW(NULL, FALSE, FALSE, NULL);
if (!state->init_done || !state->hFeed || !state->hUninit ||
- !state->hForceFeed || !state->hFeedDone || !state->hReset)
+ !state->hResume || !state->hReset)
{
MP_ERR(ao, "Error initing events\n");
uninit(ao);
@@ -371,10 +395,7 @@ static void audio_reset(struct ao *ao)
static void audio_resume(struct ao *ao)
{
struct wasapi_state *state = (struct wasapi_state *)ao->priv;
-
- SetEvent(state->hForceFeed);
- WaitForSingleObject(state->hFeedDone, INFINITE);
- IAudioClient_Start(state->pAudioClientProxy);
+ SetEvent(state->hResume);
}
static void list_devs(struct ao *ao, struct ao_device_list *list)