From 27889d0261b4c5b0fdfdac9cb85f08b406bbff94 Mon Sep 17 00:00:00 2001 From: Ethan Lee Date: Tue, 3 Mar 2020 12:31:41 -0500 Subject: [PATCH] winrt: Wait for EnumerationCompleted before leaving WASAPI_EnumerateEndpoints --- src/audio/wasapi/SDL_wasapi_winrt.cpp | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/src/audio/wasapi/SDL_wasapi_winrt.cpp b/src/audio/wasapi/SDL_wasapi_winrt.cpp index d36a7ff584eba..c94be8020abe4 100644 --- a/src/audio/wasapi/SDL_wasapi_winrt.cpp +++ b/src/audio/wasapi/SDL_wasapi_winrt.cpp @@ -63,8 +63,10 @@ class SDL_WasapiDeviceEventHandler void OnDeviceAdded(DeviceWatcher^ sender, DeviceInformation^ args); void OnDeviceRemoved(DeviceWatcher^ sender, DeviceInformationUpdate^ args); void OnDeviceUpdated(DeviceWatcher^ sender, DeviceInformationUpdate^ args); + void OnEnumerationCompleted(DeviceWatcher^ sender, Platform::Object^ args); void OnDefaultRenderDeviceChanged(Platform::Object^ sender, DefaultAudioRenderDeviceChangedEventArgs^ args); void OnDefaultCaptureDeviceChanged(Platform::Object^ sender, DefaultAudioCaptureDeviceChangedEventArgs^ args); + SDL_semaphore* completed; private: const SDL_bool iscapture; @@ -72,20 +74,23 @@ class SDL_WasapiDeviceEventHandler Windows::Foundation::EventRegistrationToken added_handler; Windows::Foundation::EventRegistrationToken removed_handler; Windows::Foundation::EventRegistrationToken updated_handler; + Windows::Foundation::EventRegistrationToken completed_handler; Windows::Foundation::EventRegistrationToken default_changed_handler; }; SDL_WasapiDeviceEventHandler::SDL_WasapiDeviceEventHandler(const SDL_bool _iscapture) : iscapture(_iscapture) + , completed(SDL_CreateSemaphore(0)) , watcher(DeviceInformation::CreateWatcher(_iscapture ? DeviceClass::AudioCapture : DeviceClass::AudioRender)) { - if (!watcher) + if (!watcher || !completed) return; // uhoh. // !!! FIXME: this doesn't need a lambda here, I think, if I make SDL_WasapiDeviceEventHandler a proper C++/CX class. --ryan. added_handler = watcher->Added += ref new TypedEventHandler([this](DeviceWatcher^ sender, DeviceInformation^ args) { OnDeviceAdded(sender, args); } ); removed_handler = watcher->Removed += ref new TypedEventHandler([this](DeviceWatcher^ sender, DeviceInformationUpdate^ args) { OnDeviceRemoved(sender, args); } ); updated_handler = watcher->Updated += ref new TypedEventHandler([this](DeviceWatcher^ sender, DeviceInformationUpdate^ args) { OnDeviceUpdated(sender, args); } ); + completed_handler = watcher->EnumerationCompleted += ref new TypedEventHandler([this](DeviceWatcher^ sender, Platform::Object^ args) { OnEnumerationCompleted(sender, args); } ); if (iscapture) { default_changed_handler = MediaDevice::DefaultAudioCaptureDeviceChanged += ref new TypedEventHandler([this](Platform::Object^ sender, DefaultAudioCaptureDeviceChangedEventArgs^ args) { OnDefaultCaptureDeviceChanged(sender, args); } ); } else { @@ -100,9 +105,14 @@ SDL_WasapiDeviceEventHandler::~SDL_WasapiDeviceEventHandler() watcher->Added -= added_handler; watcher->Removed -= removed_handler; watcher->Updated -= updated_handler; + watcher->EnumerationCompleted -= completed_handler; watcher->Stop(); watcher = nullptr; } + if (completed) { + SDL_DestroySemaphore(completed); + completed = nullptr; + } if (iscapture) { MediaDevice::DefaultAudioCaptureDeviceChanged -= default_changed_handler; @@ -135,6 +145,13 @@ SDL_WasapiDeviceEventHandler::OnDeviceUpdated(DeviceWatcher^ sender, DeviceInfor SDL_assert(sender == this->watcher); } +void +SDL_WasapiDeviceEventHandler::OnEnumerationCompleted(DeviceWatcher^ sender, Platform::Object^ args) +{ + SDL_assert(sender == this->watcher); + SDL_SemPost(this->completed); +} + void SDL_WasapiDeviceEventHandler::OnDefaultRenderDeviceChanged(Platform::Object^ sender, DefaultAudioRenderDeviceChangedEventArgs^ args) { @@ -173,6 +190,8 @@ void WASAPI_EnumerateEndpoints(void) // listening for updates. playback_device_event_handler = new SDL_WasapiDeviceEventHandler(SDL_FALSE); capture_device_event_handler = new SDL_WasapiDeviceEventHandler(SDL_TRUE); + SDL_SemWait(playback_device_event_handler->completed); + SDL_SemWait(capture_device_event_handler->completed); } struct SDL_WasapiActivationHandler : public RuntimeClass< RuntimeClassFlags< ClassicCom >, FtmBase, IActivateAudioInterfaceCompletionHandler >