mirror of
https://github.com/libsdl-org/SDL.git
synced 2025-06-03 10:27:40 +00:00
Merge SDL_wasapi_win32 into SDL_wasapi
This commit is contained in:
parent
4d301b88d6
commit
af2dbbcb53
7 changed files with 130 additions and 228 deletions
|
@ -631,7 +631,6 @@
|
|||
<ClCompile Include="..\..\src\audio\SDL_mixer.c" />
|
||||
<ClCompile Include="..\..\src\audio\SDL_wave.c" />
|
||||
<ClCompile Include="..\..\src\audio\wasapi\SDL_wasapi.c" />
|
||||
<ClCompile Include="..\..\src\audio\wasapi\SDL_wasapi_win32.c" />
|
||||
<ClCompile Include="..\..\src\core\SDL_core_unsupported.c" />
|
||||
<ClCompile Include="..\..\src\core\windows\SDL_hid.c" />
|
||||
<ClCompile Include="..\..\src\core\windows\SDL_immdevice.c" />
|
||||
|
|
|
@ -26,7 +26,6 @@
|
|||
<ClCompile Include="..\..\src\audio\SDL_mixer.c" />
|
||||
<ClCompile Include="..\..\src\audio\SDL_wave.c" />
|
||||
<ClCompile Include="..\..\src\audio\wasapi\SDL_wasapi.c" />
|
||||
<ClCompile Include="..\..\src\audio\wasapi\SDL_wasapi_win32.c" />
|
||||
<ClCompile Include="..\..\src\core\SDL_core_unsupported.c" />
|
||||
<ClCompile Include="..\..\src\core\windows\SDL_hid.c" />
|
||||
<ClCompile Include="..\..\src\core\windows\SDL_immdevice.c" />
|
||||
|
|
|
@ -528,7 +528,6 @@
|
|||
<ClCompile Include="..\..\src\audio\SDL_mixer.c" />
|
||||
<ClCompile Include="..\..\src\audio\SDL_wave.c" />
|
||||
<ClCompile Include="..\..\src\audio\wasapi\SDL_wasapi.c" />
|
||||
<ClCompile Include="..\..\src\audio\wasapi\SDL_wasapi_win32.c" />
|
||||
<ClCompile Include="..\..\src\core\SDL_core_unsupported.c" />
|
||||
<ClCompile Include="..\..\src\core\windows\SDL_hid.c" />
|
||||
<ClCompile Include="..\..\src\core\windows\SDL_immdevice.c" />
|
||||
|
|
|
@ -1133,9 +1133,6 @@
|
|||
<ClCompile Include="..\..\src\audio\dummy\SDL_dummyaudio.c">
|
||||
<Filter>audio\dummy</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\audio\wasapi\SDL_wasapi_win32.c">
|
||||
<Filter>audio\wasapi</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\..\src\audio\wasapi\SDL_wasapi.c">
|
||||
<Filter>audio\wasapi</Filter>
|
||||
</ClCompile>
|
||||
|
|
|
@ -43,13 +43,22 @@
|
|||
#define AUDCLNT_STREAMFLAGS_AUTOCONVERTPCM 0x80000000
|
||||
#endif
|
||||
|
||||
// handle to Avrt.dll--Vista and later!--for flagging the callback thread as "Pro Audio" (low latency).
|
||||
static HMODULE libavrt = NULL;
|
||||
typedef HANDLE(WINAPI *pfnAvSetMmThreadCharacteristicsW)(LPCWSTR, LPDWORD);
|
||||
typedef BOOL(WINAPI *pfnAvRevertMmThreadCharacteristics)(HANDLE);
|
||||
static pfnAvSetMmThreadCharacteristicsW pAvSetMmThreadCharacteristicsW = NULL;
|
||||
static pfnAvRevertMmThreadCharacteristics pAvRevertMmThreadCharacteristics = NULL;
|
||||
|
||||
// Some GUIDs we need to know without linking to libraries that aren't available before Vista.
|
||||
static const IID SDL_IID_IAudioRenderClient = { 0xf294acfc, 0x3146, 0x4483, { 0xa7, 0xbf, 0xad, 0xdc, 0xa7, 0xc2, 0x60, 0xe2 } };
|
||||
static const IID SDL_IID_IAudioCaptureClient = { 0xc8adbd64, 0xe71e, 0x48a0, { 0xa4, 0xde, 0x18, 0x5c, 0x39, 0x5c, 0xd3, 0x17 } };
|
||||
static const IID SDL_IID_IAudioClient = { 0x1cb9ad4c, 0xdbfa, 0x4c32, { 0xb1, 0x78, 0xc2, 0xf5, 0x68, 0xa7, 0x03, 0xb2 } };
|
||||
#ifdef __IAudioClient3_INTERFACE_DEFINED__
|
||||
static const IID SDL_IID_IAudioClient3 = { 0x7ed4ee07, 0x8e67, 0x4cd4, { 0x8c, 0x1a, 0x2b, 0x7a, 0x59, 0x87, 0xad, 0x42 } };
|
||||
#endif //
|
||||
|
||||
static bool immdevice_initialized = false;
|
||||
|
||||
// WASAPI is _really_ particular about various things happening on the same thread, for COM and such,
|
||||
// so we proxy various stuff to a single background thread to manage.
|
||||
|
@ -155,15 +164,83 @@ bool WASAPI_ProxyToManagementThread(ManagementThreadTask task, void *userdata, b
|
|||
return true; // successfully added (and possibly executed)!
|
||||
}
|
||||
|
||||
static bool mgmtthrtask_AudioDeviceDisconnected(void *userdata)
|
||||
{
|
||||
SDL_AudioDevice *device = (SDL_AudioDevice *) userdata;
|
||||
SDL_AudioDeviceDisconnected(device);
|
||||
UnrefPhysicalAudioDevice(device); // make sure this lived until the task completes.
|
||||
return true;
|
||||
}
|
||||
|
||||
static void AudioDeviceDisconnected(SDL_AudioDevice *device)
|
||||
{
|
||||
// don't wait on this, IMMDevice's own thread needs to return or everything will deadlock.
|
||||
if (device) {
|
||||
RefPhysicalAudioDevice(device); // make sure this lives until the task completes.
|
||||
WASAPI_ProxyToManagementThread(mgmtthrtask_AudioDeviceDisconnected, device, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
static bool mgmtthrtask_DefaultAudioDeviceChanged(void *userdata)
|
||||
{
|
||||
SDL_AudioDevice *device = (SDL_AudioDevice *) userdata;
|
||||
SDL_DefaultAudioDeviceChanged(device);
|
||||
UnrefPhysicalAudioDevice(device); // make sure this lived until the task completes.
|
||||
return true;
|
||||
}
|
||||
|
||||
static void DefaultAudioDeviceChanged(SDL_AudioDevice *new_default_device)
|
||||
{
|
||||
// don't wait on this, IMMDevice's own thread needs to return or everything will deadlock.
|
||||
if (new_default_device) {
|
||||
RefPhysicalAudioDevice(new_default_device); // make sure this lives until the task completes.
|
||||
WASAPI_ProxyToManagementThread(mgmtthrtask_DefaultAudioDeviceChanged, new_default_device, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
static void StopWasapiHotplug(void)
|
||||
{
|
||||
if (immdevice_initialized) {
|
||||
SDL_IMMDevice_Quit();
|
||||
immdevice_initialized = false;
|
||||
}
|
||||
}
|
||||
|
||||
static void Deinit(void)
|
||||
{
|
||||
if (libavrt) {
|
||||
FreeLibrary(libavrt);
|
||||
libavrt = NULL;
|
||||
}
|
||||
|
||||
pAvSetMmThreadCharacteristicsW = NULL;
|
||||
pAvRevertMmThreadCharacteristics = NULL;
|
||||
|
||||
StopWasapiHotplug();
|
||||
|
||||
WIN_CoUninitialize();
|
||||
}
|
||||
|
||||
static bool ManagementThreadPrepare(void)
|
||||
{
|
||||
if (!WASAPI_PlatformInit()) {
|
||||
return false;
|
||||
const SDL_IMMDevice_callbacks callbacks = { AudioDeviceDisconnected, DefaultAudioDeviceChanged };
|
||||
if (FAILED(WIN_CoInitialize())) {
|
||||
return SDL_SetError("CoInitialize() failed");
|
||||
} else if (!SDL_IMMDevice_Init(&callbacks)) {
|
||||
return false; // Error string is set by SDL_IMMDevice_Init
|
||||
}
|
||||
|
||||
immdevice_initialized = true;
|
||||
|
||||
libavrt = LoadLibrary(TEXT("avrt.dll")); // this library is available in Vista and later. No WinXP, so have to LoadLibrary to use it for now!
|
||||
if (libavrt) {
|
||||
pAvSetMmThreadCharacteristicsW = (pfnAvSetMmThreadCharacteristicsW)GetProcAddress(libavrt, "AvSetMmThreadCharacteristicsW");
|
||||
pAvRevertMmThreadCharacteristics = (pfnAvRevertMmThreadCharacteristics)GetProcAddress(libavrt, "AvRevertMmThreadCharacteristics");
|
||||
}
|
||||
|
||||
ManagementThreadLock = SDL_CreateMutex();
|
||||
if (!ManagementThreadLock) {
|
||||
WASAPI_PlatformDeinit();
|
||||
Deinit();
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -171,7 +248,7 @@ static bool ManagementThreadPrepare(void)
|
|||
if (!ManagementThreadCondition) {
|
||||
SDL_DestroyMutex(ManagementThreadLock);
|
||||
ManagementThreadLock = NULL;
|
||||
WASAPI_PlatformDeinit();
|
||||
Deinit();
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -197,7 +274,7 @@ static int ManagementThreadEntry(void *userdata)
|
|||
SDL_SignalSemaphore(data->ready_sem); // unblock calling thread.
|
||||
ManagementThreadMainloop();
|
||||
|
||||
WASAPI_PlatformDeinit();
|
||||
Deinit();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -260,7 +337,7 @@ typedef struct
|
|||
static bool mgmtthrtask_DetectDevices(void *userdata)
|
||||
{
|
||||
mgmtthrtask_DetectDevicesData *data = (mgmtthrtask_DetectDevicesData *)userdata;
|
||||
WASAPI_EnumerateEndpoints(data->default_playback, data->default_recording);
|
||||
SDL_IMMDevice_EnumerateEndpoints(data->default_playback, data->default_recording);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -373,7 +450,29 @@ static void ResetWasapiDevice(SDL_AudioDevice *device)
|
|||
|
||||
static bool mgmtthrtask_ActivateDevice(void *userdata)
|
||||
{
|
||||
return WASAPI_ActivateDevice((SDL_AudioDevice *)userdata);
|
||||
SDL_AudioDevice *device = (SDL_AudioDevice *) userdata;
|
||||
|
||||
IMMDevice *immdevice = NULL;
|
||||
if (!SDL_IMMDevice_Get(device, &immdevice, device->recording)) {
|
||||
device->hidden->client = NULL;
|
||||
return false; // This is already set by SDL_IMMDevice_Get
|
||||
}
|
||||
|
||||
// this is _not_ async in standard win32, yay!
|
||||
HRESULT ret = IMMDevice_Activate(immdevice, &SDL_IID_IAudioClient, CLSCTX_ALL, NULL, (void **)&device->hidden->client);
|
||||
IMMDevice_Release(immdevice);
|
||||
|
||||
if (FAILED(ret)) {
|
||||
SDL_assert(device->hidden->client == NULL);
|
||||
return WIN_SetErrorFromHRESULT("WASAPI can't activate audio endpoint", ret);
|
||||
}
|
||||
|
||||
SDL_assert(device->hidden->client != NULL);
|
||||
if (!WASAPI_PrepDevice(device)) { // not async, fire it right away.
|
||||
return false;
|
||||
}
|
||||
|
||||
return true; // good to go.
|
||||
}
|
||||
|
||||
static bool ActivateWasapiDevice(SDL_AudioDevice *device)
|
||||
|
@ -768,17 +867,37 @@ static bool WASAPI_OpenDevice(SDL_AudioDevice *device)
|
|||
|
||||
static void WASAPI_ThreadInit(SDL_AudioDevice *device)
|
||||
{
|
||||
WASAPI_PlatformThreadInit(device);
|
||||
// this thread uses COM.
|
||||
if (SUCCEEDED(WIN_CoInitialize())) { // can't report errors, hope it worked!
|
||||
device->hidden->coinitialized = true;
|
||||
}
|
||||
|
||||
// Set this thread to very high "Pro Audio" priority.
|
||||
if (pAvSetMmThreadCharacteristicsW) {
|
||||
DWORD idx = 0;
|
||||
device->hidden->task = pAvSetMmThreadCharacteristicsW(L"Pro Audio", &idx);
|
||||
} else {
|
||||
SDL_SetCurrentThreadPriority(device->recording ? SDL_THREAD_PRIORITY_HIGH : SDL_THREAD_PRIORITY_TIME_CRITICAL);
|
||||
}
|
||||
}
|
||||
|
||||
static void WASAPI_ThreadDeinit(SDL_AudioDevice *device)
|
||||
{
|
||||
WASAPI_PlatformThreadDeinit(device);
|
||||
// Set this thread back to normal priority.
|
||||
if (device->hidden->task && pAvRevertMmThreadCharacteristics) {
|
||||
pAvRevertMmThreadCharacteristics(device->hidden->task);
|
||||
device->hidden->task = NULL;
|
||||
}
|
||||
|
||||
if (device->hidden->coinitialized) {
|
||||
WIN_CoUninitialize();
|
||||
device->hidden->coinitialized = false;
|
||||
}
|
||||
}
|
||||
|
||||
static bool mgmtthrtask_FreeDeviceHandle(void *userdata)
|
||||
{
|
||||
WASAPI_PlatformFreeDeviceHandle((SDL_AudioDevice *)userdata);
|
||||
SDL_IMMDevice_FreeDeviceHandle((SDL_AudioDevice *) userdata);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -790,7 +909,7 @@ static void WASAPI_FreeDeviceHandle(SDL_AudioDevice *device)
|
|||
|
||||
static bool mgmtthrtask_DeinitializeStart(void *userdata)
|
||||
{
|
||||
WASAPI_PlatformDeinitializeStart();
|
||||
StopWasapiHotplug();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -53,17 +53,6 @@ void WASAPI_DisconnectDevice(SDL_AudioDevice *device); // don't hold the device
|
|||
typedef bool (*ManagementThreadTask)(void *userdata);
|
||||
bool WASAPI_ProxyToManagementThread(ManagementThreadTask task, void *userdata, bool *wait_until_complete);
|
||||
|
||||
// These are functions that are (were...?) implemented differently for various Windows versions.
|
||||
// UNLESS OTHERWISE NOTED THESE ALL HAPPEN ON THE MANAGEMENT THREAD.
|
||||
bool WASAPI_PlatformInit(void);
|
||||
void WASAPI_PlatformDeinit(void);
|
||||
void WASAPI_PlatformDeinitializeStart(void);
|
||||
void WASAPI_EnumerateEndpoints(SDL_AudioDevice **default_playback, SDL_AudioDevice **default_recording);
|
||||
bool WASAPI_ActivateDevice(SDL_AudioDevice *device);
|
||||
void WASAPI_PlatformThreadInit(SDL_AudioDevice *device); // this happens on the audio device thread, not the management thread.
|
||||
void WASAPI_PlatformThreadDeinit(SDL_AudioDevice *device); // this happens on the audio device thread, not the management thread.
|
||||
void WASAPI_PlatformFreeDeviceHandle(SDL_AudioDevice *device);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -1,200 +0,0 @@
|
|||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2024 Sam Lantinga <slouken@libsdl.org>
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
#include "SDL_internal.h"
|
||||
|
||||
/* !!! FIXME: merge this all into SDL_wasapi.c, now that WinRT is gone.
|
||||
This is code that Windows uses to talk to WASAPI-related system APIs.
|
||||
This is for non-WinRT desktop apps. The C++/CX implementation of these
|
||||
functions, exclusive to WinRT, are in SDL_wasapi_winrt.cpp.
|
||||
The code in SDL_wasapi.c is used by both standard Windows and WinRT builds
|
||||
to deal with audio and calls into these functions. */
|
||||
|
||||
#if defined(SDL_AUDIO_DRIVER_WASAPI)
|
||||
|
||||
#include "../../core/windows/SDL_windows.h"
|
||||
#include "../../core/windows/SDL_immdevice.h"
|
||||
#include "../SDL_sysaudio.h"
|
||||
|
||||
#include <audioclient.h>
|
||||
|
||||
#include "SDL_wasapi.h"
|
||||
|
||||
// handle to Avrt.dll--Vista and later!--for flagging the callback thread as "Pro Audio" (low latency).
|
||||
static HMODULE libavrt = NULL;
|
||||
typedef HANDLE(WINAPI *pfnAvSetMmThreadCharacteristicsW)(LPCWSTR, LPDWORD);
|
||||
typedef BOOL(WINAPI *pfnAvRevertMmThreadCharacteristics)(HANDLE);
|
||||
static pfnAvSetMmThreadCharacteristicsW pAvSetMmThreadCharacteristicsW = NULL;
|
||||
static pfnAvRevertMmThreadCharacteristics pAvRevertMmThreadCharacteristics = NULL;
|
||||
|
||||
static bool immdevice_initialized = false;
|
||||
|
||||
// Some GUIDs we need to know without linking to libraries that aren't available before Vista.
|
||||
static const IID SDL_IID_IAudioClient = { 0x1cb9ad4c, 0xdbfa, 0x4c32, { 0xb1, 0x78, 0xc2, 0xf5, 0x68, 0xa7, 0x03, 0xb2 } };
|
||||
|
||||
static bool mgmtthrtask_AudioDeviceDisconnected(void *userdata)
|
||||
{
|
||||
SDL_AudioDevice *device = (SDL_AudioDevice *) userdata;
|
||||
SDL_AudioDeviceDisconnected(device);
|
||||
UnrefPhysicalAudioDevice(device); // make sure this lived until the task completes.
|
||||
return true;
|
||||
}
|
||||
|
||||
static void WASAPI_AudioDeviceDisconnected(SDL_AudioDevice *device)
|
||||
{
|
||||
// don't wait on this, IMMDevice's own thread needs to return or everything will deadlock.
|
||||
if (device) {
|
||||
RefPhysicalAudioDevice(device); // make sure this lives until the task completes.
|
||||
WASAPI_ProxyToManagementThread(mgmtthrtask_AudioDeviceDisconnected, device, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
static bool mgmtthrtask_DefaultAudioDeviceChanged(void *userdata)
|
||||
{
|
||||
SDL_AudioDevice *device = (SDL_AudioDevice *) userdata;
|
||||
SDL_DefaultAudioDeviceChanged(device);
|
||||
UnrefPhysicalAudioDevice(device); // make sure this lived until the task completes.
|
||||
return true;
|
||||
}
|
||||
|
||||
static void WASAPI_DefaultAudioDeviceChanged(SDL_AudioDevice *new_default_device)
|
||||
{
|
||||
// don't wait on this, IMMDevice's own thread needs to return or everything will deadlock.
|
||||
if (new_default_device) {
|
||||
RefPhysicalAudioDevice(new_default_device); // make sure this lives until the task completes.
|
||||
WASAPI_ProxyToManagementThread(mgmtthrtask_DefaultAudioDeviceChanged, new_default_device, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
bool WASAPI_PlatformInit(void)
|
||||
{
|
||||
const SDL_IMMDevice_callbacks callbacks = { WASAPI_AudioDeviceDisconnected, WASAPI_DefaultAudioDeviceChanged };
|
||||
if (FAILED(WIN_CoInitialize())) {
|
||||
return SDL_SetError("CoInitialize() failed");
|
||||
} else if (!SDL_IMMDevice_Init(&callbacks)) {
|
||||
return false; // Error string is set by SDL_IMMDevice_Init
|
||||
}
|
||||
|
||||
immdevice_initialized = true;
|
||||
|
||||
libavrt = LoadLibrary(TEXT("avrt.dll")); // this library is available in Vista and later. No WinXP, so have to LoadLibrary to use it for now!
|
||||
if (libavrt) {
|
||||
pAvSetMmThreadCharacteristicsW = (pfnAvSetMmThreadCharacteristicsW)GetProcAddress(libavrt, "AvSetMmThreadCharacteristicsW");
|
||||
pAvRevertMmThreadCharacteristics = (pfnAvRevertMmThreadCharacteristics)GetProcAddress(libavrt, "AvRevertMmThreadCharacteristics");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void StopWasapiHotplug(void)
|
||||
{
|
||||
if (immdevice_initialized) {
|
||||
SDL_IMMDevice_Quit();
|
||||
immdevice_initialized = false;
|
||||
}
|
||||
}
|
||||
|
||||
void WASAPI_PlatformDeinit(void)
|
||||
{
|
||||
if (libavrt) {
|
||||
FreeLibrary(libavrt);
|
||||
libavrt = NULL;
|
||||
}
|
||||
|
||||
pAvSetMmThreadCharacteristicsW = NULL;
|
||||
pAvRevertMmThreadCharacteristics = NULL;
|
||||
|
||||
StopWasapiHotplug();
|
||||
|
||||
WIN_CoUninitialize();
|
||||
}
|
||||
|
||||
void WASAPI_PlatformDeinitializeStart(void)
|
||||
{
|
||||
StopWasapiHotplug();
|
||||
}
|
||||
|
||||
void WASAPI_PlatformThreadInit(SDL_AudioDevice *device)
|
||||
{
|
||||
// this thread uses COM.
|
||||
if (SUCCEEDED(WIN_CoInitialize())) { // can't report errors, hope it worked!
|
||||
device->hidden->coinitialized = true;
|
||||
}
|
||||
|
||||
// Set this thread to very high "Pro Audio" priority.
|
||||
if (pAvSetMmThreadCharacteristicsW) {
|
||||
DWORD idx = 0;
|
||||
device->hidden->task = pAvSetMmThreadCharacteristicsW(L"Pro Audio", &idx);
|
||||
} else {
|
||||
SDL_SetCurrentThreadPriority(device->recording ? SDL_THREAD_PRIORITY_HIGH : SDL_THREAD_PRIORITY_TIME_CRITICAL);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void WASAPI_PlatformThreadDeinit(SDL_AudioDevice *device)
|
||||
{
|
||||
// Set this thread back to normal priority.
|
||||
if (device->hidden->task && pAvRevertMmThreadCharacteristics) {
|
||||
pAvRevertMmThreadCharacteristics(device->hidden->task);
|
||||
device->hidden->task = NULL;
|
||||
}
|
||||
|
||||
if (device->hidden->coinitialized) {
|
||||
WIN_CoUninitialize();
|
||||
device->hidden->coinitialized = false;
|
||||
}
|
||||
}
|
||||
|
||||
bool WASAPI_ActivateDevice(SDL_AudioDevice *device)
|
||||
{
|
||||
IMMDevice *immdevice = NULL;
|
||||
if (!SDL_IMMDevice_Get(device, &immdevice, device->recording)) {
|
||||
device->hidden->client = NULL;
|
||||
return false; // This is already set by SDL_IMMDevice_Get
|
||||
}
|
||||
|
||||
// this is _not_ async in standard win32, yay!
|
||||
HRESULT ret = IMMDevice_Activate(immdevice, &SDL_IID_IAudioClient, CLSCTX_ALL, NULL, (void **)&device->hidden->client);
|
||||
IMMDevice_Release(immdevice);
|
||||
|
||||
if (FAILED(ret)) {
|
||||
SDL_assert(device->hidden->client == NULL);
|
||||
return WIN_SetErrorFromHRESULT("WASAPI can't activate audio endpoint", ret);
|
||||
}
|
||||
|
||||
SDL_assert(device->hidden->client != NULL);
|
||||
if (!WASAPI_PrepDevice(device)) { // not async, fire it right away.
|
||||
return false;
|
||||
}
|
||||
|
||||
return true; // good to go.
|
||||
}
|
||||
|
||||
void WASAPI_EnumerateEndpoints(SDL_AudioDevice **default_playback, SDL_AudioDevice **default_recording)
|
||||
{
|
||||
SDL_IMMDevice_EnumerateEndpoints(default_playback, default_recording);
|
||||
}
|
||||
|
||||
void WASAPI_PlatformFreeDeviceHandle(SDL_AudioDevice *device)
|
||||
{
|
||||
SDL_IMMDevice_FreeDeviceHandle(device);
|
||||
}
|
||||
|
||||
#endif // SDL_AUDIO_DRIVER_WASAPI
|
Loading…
Add table
Add a link
Reference in a new issue