diff options
author | Matthew Gregan <[email protected]> | 2012-11-01 16:28:57 +1300 |
---|---|---|
committer | Matthew Gregan <[email protected]> | 2012-11-01 16:28:57 +1300 |
commit | 8b971e00efee022f4248b3a8ed4e4a8600f2a429 (patch) | |
tree | bc9159bdb4a70f5d66a7feb27178c4f57d62d4b7 | |
parent | dfdf4a3c0f813717819f633f8bd3099c3e58ee8a (diff) | |
download | cubeb-8b971e00efee022f4248b3a8ed4e4a8600f2a429.tar.gz cubeb-8b971e00efee022f4248b3a8ed4e4a8600f2a429.zip |
winmm: detect situations where winmm needs higher latency (Vista, RDP) and force a minimum latency value.
-rw-r--r-- | src/cubeb_winmm.c | 35 |
1 files changed, 35 insertions, 0 deletions
diff --git a/src/cubeb_winmm.c b/src/cubeb_winmm.c index 01e0fb0..49c6127 100644 --- a/src/cubeb_winmm.c +++ b/src/cubeb_winmm.c @@ -33,6 +33,7 @@ struct cubeb { PSLIST_HEADER work; CRITICAL_SECTION lock; unsigned int active_streams; + int high_latency; }; struct cubeb_stream { @@ -190,6 +191,34 @@ cubeb_buffer_callback(HWAVEOUT waveout, UINT msg, DWORD_PTR user_ptr, DWORD_PTR SetEvent(stm->context->event); } +static int +high_latency_winmm(void) +{ + OSVERSIONINFOEX osvi; + DWORDLONG mask; + + /* Vista's WinMM implementation underruns when less than 150ms of audio is buffered. */ + memset(&osvi, 0, sizeof(OSVERSIONINFOEX)); + osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX); + osvi.dwMajorVersion = 6; + osvi.dwMinorVersion = 0; + + mask = 0; + VER_SET_CONDITION(mask, VER_MAJORVERSION, VER_EQUAL); + VER_SET_CONDITION(mask, VER_MINORVERSION, VER_EQUAL); + + if (VerifyVersionInfo(&osvi, VER_MAJORVERSION | VER_MINORVERSION, mask) != 0) { + return 1; + } + + /* Running under Terminal Services results in underruns with low latency. */ + if (GetSystemMetrics(SM_REMOTESESSION) == TRUE) { + return 1; + } + + return 0; +} + int cubeb_init(cubeb ** context, char const * context_name) { @@ -222,6 +251,8 @@ cubeb_init(cubeb ** context, char const * context_name) InitializeCriticalSection(&ctx->lock); ctx->active_streams = 0; + ctx->high_latency = high_latency_winmm(); + *context = ctx; return CUBEB_OK; @@ -342,6 +373,10 @@ cubeb_stream_init(cubeb * context, cubeb_stream ** stream, char const * stream_n stm->state_callback = state_callback; stm->user_ptr = user_ptr; + if (context->high_latency) { + latency = latency < 200 ? 200 : latency; + } + bufsz = (size_t) (stm->params.rate / 1000.0 * latency * bytes_per_frame(stm->params) / NBUFS); if (bufsz % bytes_per_frame(stm->params) != 0) { bufsz += bytes_per_frame(stm->params) - (bufsz % bytes_per_frame(stm->params)); |