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.c73
1 files changed, 49 insertions, 24 deletions
diff --git a/audio/out/ao_wasapi.c b/audio/out/ao_wasapi.c
index b201f26..d986d80 100644
--- a/audio/out/ao_wasapi.c
+++ b/audio/out/ao_wasapi.c
@@ -150,14 +150,32 @@ exit_label:
return false;
}
+static void thread_pause(struct ao *ao)
+{
+ struct wasapi_state *state = ao->priv;
+ MP_DBG(state, "Thread Pause\n");
+ HRESULT hr = IAudioClient_Stop(state->pAudioClient);
+ if (FAILED(hr))
+ MP_ERR(state, "IAudioClient_Stop returned: %s\n", mp_HRESULT_to_str(hr));
+}
+
+static void thread_unpause(struct ao *ao)
+{
+ struct wasapi_state *state = ao->priv;
+ MP_DBG(state, "Thread Unpause\n");
+ HRESULT hr = IAudioClient_Start(state->pAudioClient);
+ if (FAILED(hr)) {
+ MP_ERR(state, "IAudioClient_Start returned %s\n",
+ mp_HRESULT_to_str(hr));
+ }
+}
+
static void thread_reset(struct ao *ao)
{
struct wasapi_state *state = ao->priv;
HRESULT hr;
MP_DBG(state, "Thread Reset\n");
- hr = IAudioClient_Stop(state->pAudioClient);
- if (FAILED(hr))
- MP_ERR(state, "IAudioClient_Stop returned: %s\n", mp_HRESULT_to_str(hr));
+ thread_pause(ao);
hr = IAudioClient_Reset(state->pAudioClient);
if (FAILED(hr))
@@ -172,27 +190,20 @@ static void thread_resume(struct ao *ao)
MP_DBG(state, "Thread Resume\n");
thread_reset(ao);
thread_feed(ao);
-
- HRESULT hr = IAudioClient_Start(state->pAudioClient);
- if (FAILED(hr)) {
- MP_ERR(state, "IAudioClient_Start returned %s\n",
- mp_HRESULT_to_str(hr));
- }
+ thread_unpause(ao);
}
-static void thread_wakeup(void *ptr)
+static void set_state_and_wakeup_thread(struct ao *ao,
+ enum wasapi_thread_state thread_state)
{
- struct ao *ao = ptr;
struct wasapi_state *state = ao->priv;
+ atomic_store(&state->thread_state, thread_state);
SetEvent(state->hWake);
}
-static void set_thread_state(struct ao *ao,
- enum wasapi_thread_state thread_state)
+static void thread_process_dispatch(void *ptr)
{
- struct wasapi_state *state = ao->priv;
- atomic_store(&state->thread_state, thread_state);
- thread_wakeup(ao);
+ set_state_and_wakeup_thread(ptr, WASAPI_THREAD_DISPATCH);
}
static DWORD __stdcall AudioThread(void *lpParameter)
@@ -212,8 +223,6 @@ static DWORD __stdcall AudioThread(void *lpParameter)
if (WaitForSingleObject(state->hWake, INFINITE) != WAIT_OBJECT_0)
MP_ERR(ao, "Unexpected return value from WaitForSingleObject\n");
- mp_dispatch_queue_process(state->dispatch, 0);
-
int thread_state = atomic_load(&state->thread_state);
switch (thread_state) {
case WASAPI_THREAD_FEED:
@@ -221,6 +230,9 @@ static DWORD __stdcall AudioThread(void *lpParameter)
if (thread_feed(ao) && thread_feed(ao))
MP_ERR(ao, "Unable to fill buffer fast enough\n");
break;
+ case WASAPI_THREAD_DISPATCH:
+ mp_dispatch_queue_process(state->dispatch, 0);
+ break;
case WASAPI_THREAD_RESET:
thread_reset(ao);
break;
@@ -230,6 +242,12 @@ static DWORD __stdcall AudioThread(void *lpParameter)
case WASAPI_THREAD_SHUTDOWN:
thread_reset(ao);
goto exit_label;
+ case WASAPI_THREAD_PAUSE:
+ thread_pause(ao);
+ break;
+ case WASAPI_THREAD_UNPAUSE:
+ thread_unpause(ao);
+ break;
default:
MP_ERR(ao, "Unhandled thread state: %d\n", thread_state);
}
@@ -250,7 +268,7 @@ static void uninit(struct ao *ao)
MP_DBG(ao, "Uninit wasapi\n");
struct wasapi_state *state = ao->priv;
if (state->hWake)
- set_thread_state(ao, WASAPI_THREAD_SHUTDOWN);
+ set_state_and_wakeup_thread(ao, WASAPI_THREAD_SHUTDOWN);
if (state->hAudioThread &&
WaitForSingleObject(state->hAudioThread, INFINITE) != WAIT_OBJECT_0)
@@ -301,7 +319,7 @@ static int init(struct ao *ao)
}
state->dispatch = mp_dispatch_create(state);
- mp_dispatch_set_wakeup_fn(state->dispatch, thread_wakeup, ao);
+ mp_dispatch_set_wakeup_fn(state->dispatch, thread_process_dispatch, ao);
state->init_ok = false;
state->hAudioThread = CreateThread(NULL, 0, &AudioThread, ao, 0, NULL);
@@ -349,7 +367,7 @@ static int thread_control_exclusive(struct ao *ao, enum aocontrol cmd, void *arg
case AOCONTROL_GET_VOLUME:
IAudioEndpointVolume_GetMasterVolumeLevelScalar(
state->pEndpointVolume, &volume);
- *(float *)arg = volume;
+ *(float *)arg = volume * 100.f;
return CONTROL_OK;
case AOCONTROL_SET_VOLUME:
volume = (*(float *)arg) / 100.f;
@@ -379,7 +397,7 @@ static int thread_control_shared(struct ao *ao, enum aocontrol cmd, void *arg)
switch(cmd) {
case AOCONTROL_GET_VOLUME:
ISimpleAudioVolume_GetMasterVolume(state->pAudioVolume, &volume);
- *(float *)arg = volume;
+ *(float *)arg = volume * 100.f;
return CONTROL_OK;
case AOCONTROL_SET_VOLUME:
volume = (*(float *)arg) / 100.f;
@@ -456,12 +474,18 @@ static int control(struct ao *ao, enum aocontrol cmd, void *arg)
static void audio_reset(struct ao *ao)
{
- set_thread_state(ao, WASAPI_THREAD_RESET);
+ set_state_and_wakeup_thread(ao, WASAPI_THREAD_RESET);
}
static void audio_resume(struct ao *ao)
{
- set_thread_state(ao, WASAPI_THREAD_RESUME);
+ set_state_and_wakeup_thread(ao, WASAPI_THREAD_RESUME);
+}
+
+static bool audio_set_pause(struct ao *ao, bool paused)
+{
+ set_state_and_wakeup_thread(ao, paused ? WASAPI_THREAD_PAUSE : WASAPI_THREAD_UNPAUSE);
+ return true;
}
static void hotplug_uninit(struct ao *ao)
@@ -497,6 +521,7 @@ const struct ao_driver audio_out_wasapi = {
.control = control,
.reset = audio_reset,
.start = audio_resume,
+ .set_pause = audio_set_pause,
.list_devs = wasapi_list_devs,
.hotplug_init = hotplug_init,
.hotplug_uninit = hotplug_uninit,