mirror of
https://github.com/shadps4-emu/ext-SDL.git
synced 2024-11-24 18:50:05 +00:00
wasapi: Merge wasapi_win32.c into wasapi.c
This commit is contained in:
parent
f4864656d9
commit
57458588ee
@ -533,7 +533,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\windows\SDL_hid.c" />
|
||||
<ClCompile Include="..\..\src\core\windows\SDL_immdevice.c" />
|
||||
<ClCompile Include="..\..\src\core\windows\SDL_windows.c" />
|
||||
|
@ -1018,9 +1018,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>
|
||||
|
@ -451,7 +451,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\windows\SDL_hid.c" />
|
||||
<ClCompile Include="..\..\src\core\windows\SDL_immdevice.c" />
|
||||
<ClCompile Include="..\..\src\core\windows\SDL_windows.c" />
|
||||
|
@ -1009,9 +1009,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>
|
||||
|
@ -46,13 +46,27 @@
|
||||
#endif
|
||||
|
||||
/* 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 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 } };
|
||||
|
||||
/* 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 void
|
||||
WASAPI_DetectDevices(void)
|
||||
{
|
||||
WASAPI_EnumerateEndpoints();
|
||||
SDL_IMMDevice_EnumerateEndpoints(SDL_FALSE);
|
||||
}
|
||||
|
||||
int
|
||||
WASAPI_GetDefaultAudioInfo(char **name, SDL_AudioSpec *spec, int iscapture)
|
||||
{
|
||||
return SDL_IMMDevice_GetDefaultAudioInfo(name, spec, iscapture);
|
||||
}
|
||||
|
||||
static SDL_INLINE SDL_bool
|
||||
@ -126,7 +140,7 @@ UpdateAudioStream(_THIS, const SDL_AudioSpec *oldspec)
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int ActivateWasapiDevice(_THIS, SDL_bool isrecovery);
|
||||
static void ReleaseWasapiDevice(_THIS);
|
||||
|
||||
static SDL_bool
|
||||
@ -143,7 +157,7 @@ RecoverWasapiDevice(_THIS)
|
||||
devices try to reinitialize whatever the new default is, so it's more
|
||||
likely to carry on here, but this handles a non-default device that
|
||||
simply had its format changed in the Windows Control Panel. */
|
||||
if (WASAPI_ActivateDevice(this, SDL_TRUE) == -1) {
|
||||
if (ActivateWasapiDevice(this, SDL_TRUE) == -1) {
|
||||
SDL_OpenedAudioDeviceDisconnected(this);
|
||||
return SDL_FALSE;
|
||||
}
|
||||
@ -349,11 +363,6 @@ ReleaseWasapiDevice(_THIS)
|
||||
this->hidden->capturestream = NULL;
|
||||
}
|
||||
|
||||
if (this->hidden->activation_handler) {
|
||||
WASAPI_PlatformDeleteActivationHandler(this->hidden->activation_handler);
|
||||
this->hidden->activation_handler = NULL;
|
||||
}
|
||||
|
||||
if (this->hidden->event) {
|
||||
CloseHandle(this->hidden->event);
|
||||
this->hidden->event = NULL;
|
||||
@ -362,18 +371,6 @@ ReleaseWasapiDevice(_THIS)
|
||||
|
||||
static void
|
||||
WASAPI_CloseDevice(_THIS)
|
||||
{
|
||||
WASAPI_UnrefDevice(this);
|
||||
}
|
||||
|
||||
void
|
||||
WASAPI_RefDevice(_THIS)
|
||||
{
|
||||
SDL_AtomicIncRef(&this->hidden->refcount);
|
||||
}
|
||||
|
||||
void
|
||||
WASAPI_UnrefDevice(_THIS)
|
||||
{
|
||||
if (!SDL_AtomicDecRef(&this->hidden->refcount)) {
|
||||
return;
|
||||
@ -390,7 +387,7 @@ WASAPI_UnrefDevice(_THIS)
|
||||
}
|
||||
|
||||
/* This is called once a device is activated, possibly asynchronously. */
|
||||
int
|
||||
static int
|
||||
WASAPI_PrepDevice(_THIS, const SDL_bool updatestream)
|
||||
{
|
||||
/* !!! FIXME: we could request an exclusive mode stream, which is lower latency;
|
||||
@ -541,6 +538,34 @@ WASAPI_PrepDevice(_THIS, const SDL_bool updatestream)
|
||||
return 0; /* good to go. */
|
||||
}
|
||||
|
||||
static int
|
||||
ActivateWasapiDevice(_THIS, const SDL_bool isrecovery)
|
||||
{
|
||||
IMMDevice *device = NULL;
|
||||
HRESULT ret;
|
||||
|
||||
if (SDL_IMMDevice_Get(this->hidden->devid, &device, this->iscapture) < 0) {
|
||||
this->hidden->client = NULL;
|
||||
return -1; /* This is already set by SDL_IMMDevice_Get */
|
||||
}
|
||||
|
||||
/* this is not async in standard win32, yay! */
|
||||
ret = IMMDevice_Activate(device, &SDL_IID_IAudioClient, CLSCTX_ALL, NULL, (void **) &this->hidden->client);
|
||||
IMMDevice_Release(device);
|
||||
|
||||
if (FAILED(ret)) {
|
||||
SDL_assert(this->hidden->client == NULL);
|
||||
return WIN_SetErrorFromHRESULT("WASAPI can't activate audio endpoint", ret);
|
||||
}
|
||||
|
||||
SDL_assert(this->hidden->client != NULL);
|
||||
if (WASAPI_PrepDevice(this, isrecovery) == -1) { /* not async, fire it right away. */
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0; /* good to go. */
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
WASAPI_OpenDevice(_THIS, const char *devname)
|
||||
@ -555,7 +580,7 @@ WASAPI_OpenDevice(_THIS, const char *devname)
|
||||
}
|
||||
SDL_zerop(this->hidden);
|
||||
|
||||
WASAPI_RefDevice(this); /* so CloseDevice() will unref to zero. */
|
||||
SDL_AtomicIncRef(&this->hidden->refcount); /* so CloseDevice() will unref to zero. */
|
||||
|
||||
if (!devid) { /* is default device? */
|
||||
this->hidden->default_device_generation = SDL_AtomicGet(this->iscapture ? &SDL_IMMDevice_DefaultCaptureGeneration : &SDL_IMMDevice_DefaultPlaybackGeneration);
|
||||
@ -566,7 +591,7 @@ WASAPI_OpenDevice(_THIS, const char *devname)
|
||||
}
|
||||
}
|
||||
|
||||
if (WASAPI_ActivateDevice(this, SDL_FALSE) == -1) {
|
||||
if (ActivateWasapiDevice(this, SDL_FALSE) == -1) {
|
||||
return -1; /* already set error. */
|
||||
}
|
||||
|
||||
@ -584,26 +609,58 @@ WASAPI_OpenDevice(_THIS, const char *devname)
|
||||
static void
|
||||
WASAPI_ThreadInit(_THIS)
|
||||
{
|
||||
WASAPI_PlatformThreadInit(this);
|
||||
/* this thread uses COM. */
|
||||
if (SUCCEEDED(WIN_CoInitialize())) { /* can't report errors, hope it worked! */
|
||||
this->hidden->coinitialized = SDL_TRUE;
|
||||
}
|
||||
|
||||
/* Set this thread to very high "Pro Audio" priority. */
|
||||
if (pAvSetMmThreadCharacteristicsW) {
|
||||
DWORD idx = 0;
|
||||
this->hidden->task = pAvSetMmThreadCharacteristicsW(L"Pro Audio", &idx);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
WASAPI_ThreadDeinit(_THIS)
|
||||
{
|
||||
WASAPI_PlatformThreadDeinit(this);
|
||||
/* Set this thread back to normal priority. */
|
||||
if (this->hidden->task && pAvRevertMmThreadCharacteristics) {
|
||||
pAvRevertMmThreadCharacteristics(this->hidden->task);
|
||||
this->hidden->task = NULL;
|
||||
}
|
||||
|
||||
if (this->hidden->coinitialized) {
|
||||
WIN_CoUninitialize();
|
||||
this->hidden->coinitialized = SDL_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
WASAPI_Deinitialize(void)
|
||||
{
|
||||
WASAPI_PlatformDeinit();
|
||||
if (libavrt) {
|
||||
FreeLibrary(libavrt);
|
||||
libavrt = NULL;
|
||||
}
|
||||
|
||||
pAvSetMmThreadCharacteristicsW = NULL;
|
||||
pAvRevertMmThreadCharacteristics = NULL;
|
||||
|
||||
SDL_IMMDevice_Quit();
|
||||
}
|
||||
|
||||
static SDL_bool
|
||||
WASAPI_Init(SDL_AudioDriverImpl * impl)
|
||||
{
|
||||
if (WASAPI_PlatformInit() == -1) {
|
||||
return SDL_FALSE;
|
||||
if (SDL_IMMDevice_Init() < 0) {
|
||||
return SDL_FALSE; /* Error is set by SDL_IMMDevice_Init */
|
||||
}
|
||||
|
||||
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");
|
||||
}
|
||||
|
||||
/* Set the function pointers */
|
||||
|
@ -55,21 +55,6 @@ struct SDL_PrivateAudioData
|
||||
SDL_atomic_t just_activated;
|
||||
};
|
||||
|
||||
/* win32 and winrt implementations call into these. */
|
||||
int WASAPI_PrepDevice(_THIS, const SDL_bool updatestream);
|
||||
void WASAPI_RefDevice(_THIS);
|
||||
void WASAPI_UnrefDevice(_THIS);
|
||||
|
||||
/* These are functions that are implemented differently for Windows vs WinRT. */
|
||||
int WASAPI_PlatformInit(void);
|
||||
void WASAPI_PlatformDeinit(void);
|
||||
void WASAPI_EnumerateEndpoints(void);
|
||||
int WASAPI_GetDefaultAudioInfo(char **name, SDL_AudioSpec *spec, int iscapture);
|
||||
int WASAPI_ActivateDevice(_THIS, const SDL_bool isrecovery);
|
||||
void WASAPI_PlatformThreadInit(_THIS);
|
||||
void WASAPI_PlatformThreadDeinit(_THIS);
|
||||
void WASAPI_PlatformDeleteActivationHandler(void *handler);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -1,162 +0,0 @@
|
||||
/*
|
||||
Simple DirectMedia Layer
|
||||
Copyright (C) 1997-2022 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"
|
||||
|
||||
/* 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 SDL_AUDIO_DRIVER_WASAPI
|
||||
|
||||
#include "../../core/windows/SDL_windows.h"
|
||||
#include "../../core/windows/SDL_immdevice.h"
|
||||
#include "SDL_audio.h"
|
||||
#include "SDL_timer.h"
|
||||
#include "../SDL_audio_c.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;
|
||||
|
||||
/* 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 } };
|
||||
|
||||
int
|
||||
WASAPI_PlatformInit(void)
|
||||
{
|
||||
if (SDL_IMMDevice_Init() < 0) {
|
||||
return -1; /* This is set by SDL_IMMDevice_Init */
|
||||
}
|
||||
|
||||
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 0;
|
||||
}
|
||||
|
||||
void
|
||||
WASAPI_PlatformDeinit(void)
|
||||
{
|
||||
if (libavrt) {
|
||||
FreeLibrary(libavrt);
|
||||
libavrt = NULL;
|
||||
}
|
||||
|
||||
pAvSetMmThreadCharacteristicsW = NULL;
|
||||
pAvRevertMmThreadCharacteristics = NULL;
|
||||
|
||||
SDL_IMMDevice_Quit();
|
||||
}
|
||||
|
||||
void
|
||||
WASAPI_PlatformThreadInit(_THIS)
|
||||
{
|
||||
/* this thread uses COM. */
|
||||
if (SUCCEEDED(WIN_CoInitialize())) { /* can't report errors, hope it worked! */
|
||||
this->hidden->coinitialized = SDL_TRUE;
|
||||
}
|
||||
|
||||
/* Set this thread to very high "Pro Audio" priority. */
|
||||
if (pAvSetMmThreadCharacteristicsW) {
|
||||
DWORD idx = 0;
|
||||
this->hidden->task = pAvSetMmThreadCharacteristicsW(L"Pro Audio", &idx);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
WASAPI_PlatformThreadDeinit(_THIS)
|
||||
{
|
||||
/* Set this thread back to normal priority. */
|
||||
if (this->hidden->task && pAvRevertMmThreadCharacteristics) {
|
||||
pAvRevertMmThreadCharacteristics(this->hidden->task);
|
||||
this->hidden->task = NULL;
|
||||
}
|
||||
|
||||
if (this->hidden->coinitialized) {
|
||||
WIN_CoUninitialize();
|
||||
this->hidden->coinitialized = SDL_FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
WASAPI_ActivateDevice(_THIS, const SDL_bool isrecovery)
|
||||
{
|
||||
IMMDevice *device = NULL;
|
||||
HRESULT ret;
|
||||
|
||||
if (SDL_IMMDevice_Get(this->hidden->devid, &device, this->iscapture) < 0) {
|
||||
this->hidden->client = NULL;
|
||||
return -1; /* This is already set by SDL_IMMDevice_Get */
|
||||
}
|
||||
|
||||
/* this is not async in standard win32, yay! */
|
||||
ret = IMMDevice_Activate(device, &SDL_IID_IAudioClient, CLSCTX_ALL, NULL, (void **) &this->hidden->client);
|
||||
IMMDevice_Release(device);
|
||||
|
||||
if (FAILED(ret)) {
|
||||
SDL_assert(this->hidden->client == NULL);
|
||||
return WIN_SetErrorFromHRESULT("WASAPI can't activate audio endpoint", ret);
|
||||
}
|
||||
|
||||
SDL_assert(this->hidden->client != NULL);
|
||||
if (WASAPI_PrepDevice(this, isrecovery) == -1) { /* not async, fire it right away. */
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0; /* good to go. */
|
||||
}
|
||||
|
||||
void
|
||||
WASAPI_EnumerateEndpoints(void)
|
||||
{
|
||||
SDL_IMMDevice_EnumerateEndpoints(SDL_FALSE);
|
||||
}
|
||||
|
||||
int
|
||||
WASAPI_GetDefaultAudioInfo(char **name, SDL_AudioSpec *spec, int iscapture)
|
||||
{
|
||||
return SDL_IMMDevice_GetDefaultAudioInfo(name, spec, iscapture);
|
||||
}
|
||||
|
||||
void
|
||||
WASAPI_PlatformDeleteActivationHandler(void *handler)
|
||||
{
|
||||
/* not asynchronous. */
|
||||
SDL_assert(!"This function should have only been called on WinRT.");
|
||||
}
|
||||
|
||||
#endif /* SDL_AUDIO_DRIVER_WASAPI */
|
||||
|
||||
/* vi: set ts=4 sw=4 expandtab: */
|
||||
|
Loading…
Reference in New Issue
Block a user