From f3924081ab5004deb86ed055d674bd018959b878 Mon Sep 17 00:00:00 2001 From: dmitrykos Date: Fri, 11 Dec 2020 15:30:08 +0200 Subject: [PATCH] wasapi: Fixed underruns in the Exclusive mode on UWP platform (or when timeBeginPeriod does not allow to set 1 ms granularity) by assuming that system timer granularity on UWP equals to 10 msec, make sure time to sleep provided by GetNextSleepTime is aligned to the granularity of the system timer. --- src/hostapi/wasapi/pa_win_wasapi.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/hostapi/wasapi/pa_win_wasapi.c b/src/hostapi/wasapi/pa_win_wasapi.c index 7e321f1..216796e 100644 --- a/src/hostapi/wasapi/pa_win_wasapi.c +++ b/src/hostapi/wasapi/pa_win_wasapi.c @@ -825,7 +825,7 @@ static inline UINT32 ThreadIdleScheduler_NextSleep(ThreadIdleScheduler *sched) // ------------------------------------------------------------------------------------------ typedef struct _SystemTimer { - UINT32 granularity; + INT32 granularity; } SystemTimer; static LARGE_INTEGER g_SystemTimerFrequency; @@ -849,12 +849,15 @@ static BOOL SystemTimer_SetGranularity(SystemTimer *timer, UINT32 granularity) { PRINT(("SetSystemTimer: timeBeginPeriod(1) failed!\n")); - timer->granularity = 0; + timer->granularity = 10; return FALSE; } #else - (void)timer; (void)granularity; + + // UWP does not support increase of the timer precision change and thus calling WaitForSingleObject with anything + // below 10 milliseconds will cause underruns for input and output stream. + timer->granularity = 10; #endif return TRUE; @@ -6113,8 +6116,11 @@ static inline INT32 GetNextSleepTime(SystemTimer *timer, ThreadIdleScheduler *sc // INT32 procTime = (INT32)(SystemTimer_GetTime(timer) - startTime); nextSleepTime -= procTime; - if (nextSleepTime < 0) + if (nextSleepTime < timer->granularity) nextSleepTime = 0; + else + if (timer->granularity > 1) + nextSleepTime = ALIGN_BWD(nextSleepTime, timer->granularity); #ifdef PA_WASAPI_LOG_TIME_SLOTS printf("{%d},", procTime); -- 2.43.0