aboutsummaryrefslogtreecommitdiffhomepage
path: root/audio
diff options
context:
space:
mode:
authorGravatar Kevin Mitchell <kevmitch@gmail.com>2014-11-18 04:17:20 -0800
committerGravatar Kevin Mitchell <kevmitch@gmail.com>2014-11-18 05:03:33 -0800
commitc545c406fa8d5d12391f77d8e758fd7b203c665e (patch)
treed06104270b42f7645aa5e3784185c2d3b64d298c /audio
parent1507ef05c2b36f8c603b56c3ebc63a541d17fe53 (diff)
ao/wasapi: increase buffer size to 50 ms
Before it was the default device period, which was too small causing glitches on on entering/exiting fullscreen.
Diffstat (limited to 'audio')
-rw-r--r--audio/out/ao_wasapi.c1
-rwxr-xr-xaudio/out/ao_wasapi.h4
-rwxr-xr-xaudio/out/ao_wasapi_utils.c37
3 files changed, 26 insertions, 16 deletions
diff --git a/audio/out/ao_wasapi.c b/audio/out/ao_wasapi.c
index 074a6b32b2..b328fd61b2 100644
--- a/audio/out/ao_wasapi.c
+++ b/audio/out/ao_wasapi.c
@@ -79,6 +79,7 @@ static void thread_feed(struct ao *ao)
EXIT_ON_ERROR(hr);
frame_count -= padding;
+ MP_TRACE(ao, "Frame to fill: %"PRIu32". Padding: %"PRIu32"\n", frame_count, padding);
}
BYTE *pData;
diff --git a/audio/out/ao_wasapi.h b/audio/out/ao_wasapi.h
index 7e7cc6cd06..8507ecaf0b 100755
--- a/audio/out/ao_wasapi.h
+++ b/audio/out/ao_wasapi.h
@@ -63,10 +63,6 @@ typedef struct wasapi_state {
/* Buffers */
size_t buffer_block_size; /* Size of each block in bytes */
- REFERENCE_TIME
- minRequestedDuration; /* minimum wasapi buffer block size, in 100-nanosecond units */
- REFERENCE_TIME
- defaultRequestedDuration; /* default wasapi default block size, in 100-nanosecond units */
UINT32 bufferFrameCount; /* wasapi buffer block size, number of frames, frame size at format.nBlockAlign */
/* WASAPI handles, owned by other thread */
diff --git a/audio/out/ao_wasapi_utils.c b/audio/out/ao_wasapi_utils.c
index 228e0e3ff3..93d6fe1874 100755
--- a/audio/out/ao_wasapi_utils.c
+++ b/audio/out/ao_wasapi_utils.c
@@ -20,6 +20,7 @@
#define COBJMACROS 1
#define _WIN32_WINNT 0x600
+#include <math.h>
#include <initguid.h>
#include <audioclient.h>
#include <endpointvolume.h>
@@ -451,38 +452,41 @@ exit_label:
return hr;
}
-static HRESULT fix_format(struct wasapi_state *state)
+static HRESULT fix_format(struct ao *ao)
{
+ struct wasapi_state *state = (struct wasapi_state *)ao->priv;
HRESULT hr;
double offset = 0.5;
+ REFERENCE_TIME devicePeriod, bufferDuration;
+ MP_DBG(state, "IAudioClient::GetDevicePeriod\n");
+ hr = IAudioClient_GetDevicePeriod(state->pAudioClient,&devicePeriod, NULL);
+ MP_VERBOSE(state, "Device period: %.2g ms\n", (double) devicePeriod / 10000.0 );
+ /* integer multiple of device period close to 50ms */
+ bufferDuration = ceil( 50.0 * 10000.0 / devicePeriod ) * devicePeriod;
+
/* cargo cult code to negotiate buffer block size, affected by hardware/drivers combinations,
gradually grow it to 10s, by 0.5s, consider failure if it still doesn't work
*/
- MP_DBG(state, "IAudioClient::GetDevicePeriod\n");
- hr = IAudioClient_GetDevicePeriod(state->pAudioClient,
- &state->defaultRequestedDuration,
- &state->minRequestedDuration);
-
reinit:
MP_DBG(state, "IAudioClient::Initialize\n");
hr = IAudioClient_Initialize(state->pAudioClient,
state->share_mode,
AUDCLNT_STREAMFLAGS_EVENTCALLBACK,
- state->defaultRequestedDuration,
- state->defaultRequestedDuration,
+ bufferDuration,
+ bufferDuration,
&(state->format.Format),
NULL);
- /* something about buffer sizes on Win7, fixme might loop forever */
+ /* something about buffer sizes on Win7 */
if (hr == AUDCLNT_E_BUFFER_SIZE_NOT_ALIGNED) {
MP_VERBOSE(state, "IAudioClient::Initialize negotiation failed with %s (0x%"PRIx32"), used %lld * 100ns\n",
- wasapi_explain_err(hr), (uint32_t)hr, state->defaultRequestedDuration);
+ wasapi_explain_err(hr), (uint32_t)hr, bufferDuration);
if (offset > 10.0) {
hr = E_FAIL;
EXIT_ON_ERROR(hr);
}
IAudioClient_GetBufferSize(state->pAudioClient, &state->bufferFrameCount);
- state->defaultRequestedDuration =
+ bufferDuration =
(REFERENCE_TIME)((10000.0 * 1000 / state->format.Format.nSamplesPerSec *
state->bufferFrameCount) + offset);
offset += 0.5;
@@ -500,6 +504,7 @@ reinit:
&IID_IAudioRenderClient,
(void **)&state->pRenderClient);
EXIT_ON_ERROR(hr);
+
MP_DBG(state, "IAudioClient::Initialize pAudioVolume\n");
hr = IAudioClient_GetService(state->pAudioClient,
&IID_ISimpleAudioVolume,
@@ -509,13 +514,21 @@ reinit:
MP_DBG(state, "IAudioClient::Initialize IAudioClient_SetEventHandle\n");
hr = IAudioClient_SetEventHandle(state->pAudioClient, state->hFeed);
EXIT_ON_ERROR(hr);
+
MP_DBG(state, "IAudioClient::Initialize IAudioClient_GetBufferSize\n");
hr = IAudioClient_GetBufferSize(state->pAudioClient,
&state->bufferFrameCount);
EXIT_ON_ERROR(hr);
+
+ ao->device_buffer = state->bufferFrameCount;
state->buffer_block_size = state->format.Format.nChannels *
state->format.Format.wBitsPerSample / 8 *
state->bufferFrameCount;
+ bufferDuration =
+ (REFERENCE_TIME)((10000.0 * 1000 / state->format.Format.nSamplesPerSec *
+ state->bufferFrameCount) + offset);
+ MP_VERBOSE(state, "Buffer frame count: %"PRIu32" (%.2g ms)\n",
+ state->bufferFrameCount, (double) bufferDuration / 10000.0 );
hr = init_clock(state);
EXIT_ON_ERROR(hr);
@@ -999,7 +1012,7 @@ retry:
}
MP_DBG(ao, "Fixing format\n");
- hr = fix_format(state);
+ hr = fix_format(ao);
if ( (hr == AUDCLNT_E_DEVICE_IN_USE ||
hr == AUDCLNT_E_DEVICE_INVALIDATED) &&
retry_wait <= 8 ) {