wasapi: switched to event-driven interface.
This reduces latency and improves battery life.
parent
988034fcc7
commit
ab4695f48f
|
@ -321,15 +321,21 @@ WASAPI_PlayDevice(_THIS)
|
||||||
static void
|
static void
|
||||||
WASAPI_WaitDevice(_THIS)
|
WASAPI_WaitDevice(_THIS)
|
||||||
{
|
{
|
||||||
while (RecoverWasapiIfLost(this) && this->hidden->client) {
|
while (RecoverWasapiIfLost(this) && this->hidden->client && this->hidden->event) {
|
||||||
const UINT32 maxpadding = this->spec.samples;
|
/*SDL_Log("WAITDEVICE");*/
|
||||||
UINT32 padding = 0;
|
if (WaitForSingleObject(this->hidden->event, INFINITE) == WAIT_OBJECT_0) {
|
||||||
if (!WasapiFailed(this, IAudioClient_GetCurrentPadding(this->hidden->client, &padding))) {
|
const UINT32 maxpadding = this->spec.samples;
|
||||||
if (padding <= maxpadding) {
|
UINT32 padding = 0;
|
||||||
break;
|
if (!WasapiFailed(this, IAudioClient_GetCurrentPadding(this->hidden->client, &padding))) {
|
||||||
|
/*SDL_Log("WASAPI EVENT! padding=%u maxpadding=%u", (unsigned int)padding, (unsigned int)maxpadding);*/
|
||||||
|
if (padding <= maxpadding) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
/* Sleep long enough for half the buffer to be free. */
|
} else {
|
||||||
SDL_Delay(((padding - maxpadding) * 1000) / this->spec.freq);
|
/*SDL_Log("WASAPI FAILED EVENT!");*/
|
||||||
|
IAudioClient_Stop(this->hidden->client);
|
||||||
|
SDL_OpenedAudioDeviceDisconnected(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -429,6 +435,8 @@ ReleaseWasapiDevice(_THIS)
|
||||||
{
|
{
|
||||||
if (this->hidden->client) {
|
if (this->hidden->client) {
|
||||||
IAudioClient_Stop(this->hidden->client);
|
IAudioClient_Stop(this->hidden->client);
|
||||||
|
IAudioClient_SetEventHandle(this->hidden->client, NULL);
|
||||||
|
IAudioClient_Release(this->hidden->client);
|
||||||
this->hidden->client = NULL;
|
this->hidden->client = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -456,6 +464,11 @@ ReleaseWasapiDevice(_THIS)
|
||||||
WASAPI_PlatformDeleteActivationHandler(this->hidden->activation_handler);
|
WASAPI_PlatformDeleteActivationHandler(this->hidden->activation_handler);
|
||||||
this->hidden->activation_handler = NULL;
|
this->hidden->activation_handler = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this->hidden->event) {
|
||||||
|
CloseHandle(this->hidden->event);
|
||||||
|
this->hidden->event = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -517,6 +530,11 @@ WASAPI_PrepDevice(_THIS, const SDL_bool updatestream)
|
||||||
|
|
||||||
SDL_assert(client != NULL);
|
SDL_assert(client != NULL);
|
||||||
|
|
||||||
|
this->hidden->event = CreateEventW(NULL, 0, 0, NULL);
|
||||||
|
if (this->hidden->event == NULL) {
|
||||||
|
return WIN_SetError("WASAPI can't create an event handle");
|
||||||
|
}
|
||||||
|
|
||||||
ret = IAudioClient_GetMixFormat(client, &waveformat);
|
ret = IAudioClient_GetMixFormat(client, &waveformat);
|
||||||
if (FAILED(ret)) {
|
if (FAILED(ret)) {
|
||||||
return WIN_SetErrorFromHRESULT("WASAPI can't determine mix format", ret);
|
return WIN_SetErrorFromHRESULT("WASAPI can't determine mix format", ret);
|
||||||
|
@ -565,11 +583,16 @@ WASAPI_PrepDevice(_THIS, const SDL_bool updatestream)
|
||||||
return WIN_SetErrorFromHRESULT("WASAPI can't determine minimum device period", ret);
|
return WIN_SetErrorFromHRESULT("WASAPI can't determine minimum device period", ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = IAudioClient_Initialize(client, sharemode, 0, duration, sharemode == AUDCLNT_SHAREMODE_SHARED ? 0 : duration, waveformat, NULL);
|
ret = IAudioClient_Initialize(client, sharemode, AUDCLNT_STREAMFLAGS_EVENTCALLBACK, duration, sharemode == AUDCLNT_SHAREMODE_SHARED ? 0 : duration, waveformat, NULL);
|
||||||
if (FAILED(ret)) {
|
if (FAILED(ret)) {
|
||||||
return WIN_SetErrorFromHRESULT("WASAPI can't initialize audio client", ret);
|
return WIN_SetErrorFromHRESULT("WASAPI can't initialize audio client", ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ret = IAudioClient_SetEventHandle(client, this->hidden->event);
|
||||||
|
if (FAILED(ret)) {
|
||||||
|
return WIN_SetErrorFromHRESULT("WASAPI can't set event handle", ret);
|
||||||
|
}
|
||||||
|
|
||||||
ret = IAudioClient_GetBufferSize(client, &bufsize);
|
ret = IAudioClient_GetBufferSize(client, &bufsize);
|
||||||
if (FAILED(ret)) {
|
if (FAILED(ret)) {
|
||||||
return WIN_SetErrorFromHRESULT("WASAPI can't determine buffer size", ret);
|
return WIN_SetErrorFromHRESULT("WASAPI can't determine buffer size", ret);
|
||||||
|
|
|
@ -45,6 +45,7 @@ struct SDL_PrivateAudioData
|
||||||
IAudioRenderClient *render;
|
IAudioRenderClient *render;
|
||||||
IAudioCaptureClient *capture;
|
IAudioCaptureClient *capture;
|
||||||
SDL_AudioStream *capturestream;
|
SDL_AudioStream *capturestream;
|
||||||
|
HANDLE event;
|
||||||
HANDLE task;
|
HANDLE task;
|
||||||
SDL_bool coinitialized;
|
SDL_bool coinitialized;
|
||||||
int framesize;
|
int framesize;
|
||||||
|
|
Loading…
Reference in New Issue