From f75f32977cba1b227413e5f4b4146c95a2c26bc9 Mon Sep 17 00:00:00 2001 From: sunpenghao Date: Sat, 13 Apr 2024 15:10:19 +0800 Subject: [PATCH] ao_wasapi: set 0 buffer duration on initialization for shared mode Microsoft requires that both `hnsBufferDuration` and `hnsPeriodicity` should be 0 when initializing a shared mode stream using event-driven buffering. Do as they say. Ref: https://learn.microsoft.com/en-us/windows/win32/api/audioclient/nf-audioclient-iaudioclient-initialize --- audio/out/ao_wasapi_utils.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/audio/out/ao_wasapi_utils.c b/audio/out/ao_wasapi_utils.c index 8ff6523303..2614872b91 100644 --- a/audio/out/ao_wasapi_utils.c +++ b/audio/out/ao_wasapi_utils.c @@ -646,10 +646,13 @@ static HRESULT fix_format(struct ao *ao, bool align_hack) MP_VERBOSE(state, "Device period: default %lld us, minimum %lld us\n", defaultPeriod / 10, minPeriod / 10); + // per Microsoft: + // * hnsBufferDuration = hnsPeriodicity = 0 for shared mode + // * hnsBufferDuration = hnsPeriodicity != 0 for exclusive mode + // https://learn.microsoft.com/en-us/windows/win32/api/audioclient/nf-audioclient-iaudioclient-initialize REFERENCE_TIME bufferDuration; if (state->share_mode == AUDCLNT_SHAREMODE_SHARED) { - // for shared mode, use integer multiple of device period close to 50ms - bufferDuration = defaultPeriod * ceil(50.0 * 10000.0 / defaultPeriod); + bufferDuration = 0; } else if (state->opt_exclusive_buffer == 0) { bufferDuration = defaultPeriod; } else { @@ -671,17 +674,15 @@ static HRESULT fix_format(struct ao *ao, bool align_hack) * state->bufferFrameCount)); } - MP_VERBOSE(state, "Trying buffer duration %lld us\n", bufferDuration / 10); - - REFERENCE_TIME bufferPeriod = - state->share_mode == AUDCLNT_SHAREMODE_EXCLUSIVE ? bufferDuration : 0; + if (state->share_mode == AUDCLNT_SHAREMODE_EXCLUSIVE) + MP_VERBOSE(state, "Trying buffer duration %lld us\n", bufferDuration / 10); MP_DBG(state, "IAudioClient::Initialize\n"); hr = IAudioClient_Initialize(state->pAudioClient, state->share_mode, AUDCLNT_STREAMFLAGS_EVENTCALLBACK, bufferDuration, - bufferPeriod, + bufferDuration, &(state->format.Format), NULL); EXIT_ON_ERROR(hr);