Fixed microphone randomly stop working

WASAPI_WaitDevice is used for audio playback and capture, but needs to
behave slighty different.
For playback `GetCurrentPadding` returns the padding which is already
queued, so WaitDevice should return when buffer length falls below the
buffer threshold (`maxpadding`).
For capture `GetCurrentPadding` returns the available data which can be
read, so WaitDevice can return as soon as any data is available.

In the old implementation WaitDevice could suddenly hang. This is
because on many capture devices the buffer (`padding`) wasn't filled
fast enough to surpass `maxpadding`. But if at one point (due to unlucky
timing) more than maxpadding frames were available, WaitDevice would not
return anymore.

Issue #3234 is probably related to this.
This commit is contained in:
Splamy 2021-05-01 23:56:23 +02:00 committed by Ryan C. Gordon
parent 4ef8674df1
commit c72aef2664

View File

@ -306,10 +306,16 @@ WASAPI_WaitDevice(_THIS)
UINT32 padding = 0; UINT32 padding = 0;
if (!WasapiFailed(this, IAudioClient_GetCurrentPadding(this->hidden->client, &padding))) { if (!WasapiFailed(this, IAudioClient_GetCurrentPadding(this->hidden->client, &padding))) {
/*SDL_Log("WASAPI EVENT! padding=%u maxpadding=%u", (unsigned int)padding, (unsigned int)maxpadding);*/ /*SDL_Log("WASAPI EVENT! padding=%u maxpadding=%u", (unsigned int)padding, (unsigned int)maxpadding);*/
if (this->iscapture) {
if (padding > 0) {
break;
}
} else {
if (padding <= maxpadding) { if (padding <= maxpadding) {
break; break;
} }
} }
}
} else if (waitResult != WAIT_TIMEOUT) { } else if (waitResult != WAIT_TIMEOUT) {
/*SDL_Log("WASAPI FAILED EVENT!");*/ /*SDL_Log("WASAPI FAILED EVENT!");*/
IAudioClient_Stop(this->hidden->client); IAudioClient_Stop(this->hidden->client);