diff options
Diffstat (limited to 'audio/out/ao_wasapi.c')
-rw-r--r-- | audio/out/ao_wasapi.c | 73 |
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, |