Browse Source

wasapi: new PaWasapi_GetAudioClient() API to get pointer to IAudioClient from PaStream, workaround to get real Windows version in order to be able to create correct version of IAudioClient interface (Windows 10 was reported as Windows 8 when using just GetVersion())

mr/6574173/HEAD
dmitrykos 1 year ago
parent
commit
a802290e83
2 changed files with 73 additions and 18 deletions
  1. 13
    2
      include/pa_win_wasapi.h
  2. 60
    16
      src/hostapi/wasapi/pa_win_wasapi.c

+ 13
- 2
include/pa_win_wasapi.h View File

@@ -291,6 +291,17 @@ typedef struct PaWasapiStreamInfo
PaWasapiStreamInfo;


/** Returns pointer to WASAPI's IAudioClient object of the stream.

@param pStream Pointer to PaStream.
@param pAudioClient Pointer to pointer of IAudioClient.
@param bOutput TRUE (1) for output stream, FALSE (0) for input stream.

@return Error code indicating success or failure.
*/
PaError PaWasapi_GetAudioClient( PaStream *pStream, void **pAudioClient, int bOutput );


/** Update device list.
This function is available if PA_WASAPI_MAX_CONST_DEVICE_COUNT is defined during compile time
with maximum constant WASAPI device count (recommended value - 32).
@@ -374,7 +385,7 @@ PaError PaWasapi_GetFramesPerHostBuffer( PaStream *pStream, unsigned int *nInput
@return Error code indicating success or failure
@see PaWasapi_GetJackDescription
*/
PaError PaWasapi_GetJackCount(PaDeviceIndex nDevice, int *jcount);
PaError PaWasapi_GetJackCount( PaDeviceIndex nDevice, int *jcount );


/** Get the jack description associated with a WASAPI device and jack number
@@ -389,7 +400,7 @@ PaError PaWasapi_GetJackCount(PaDeviceIndex nDevice, int *jcount);
@return Error code indicating success or failure
@see PaWasapi_GetJackCount
*/
PaError PaWasapi_GetJackDescription(PaDeviceIndex nDevice, int jindex, PaWasapiJackDescription *pJackDescription);
PaError PaWasapi_GetJackDescription( PaDeviceIndex nDevice, int jindex, PaWasapiJackDescription *pJackDescription );


/*

+ 60
- 16
src/hostapi/wasapi/pa_win_wasapi.c View File

@@ -988,29 +988,57 @@ static EWindowsVersion GetWindowsVersion()

if (version == WINDOWS_UNKNOWN)
{
DWORD dwVersion = 0;
DWORD dwMajorVersion = 0;
DWORD dwMinorVersion = 0;
DWORD dwBuild = 0;
DWORD dwMajorVersion = 0xFFFFFFFFU, dwMinorVersion = 0, dwBuild = 0;
// RTL_OSVERSIONINFOW equals OSVERSIONINFOW but it is missing inb MinGW winnt.h header,
// thus use OSVERSIONINFOW for greater portability
typedef NTSTATUS (WINAPI *LPFN_RTLGETVERSION)(POSVERSIONINFOW lpVersionInformation);
LPFN_RTLGETVERSION fnRtlGetVersion;

#define NTSTATUS_SUCCESS ((NTSTATUS)0x00000000L)

// RtlGetVersion must be able to provide true Windows version (Windows 10 may be reported as Windows 8
// by GetVersion API)
if ((fnRtlGetVersion = (LPFN_RTLGETVERSION)GetProcAddress(GetModuleHandleA("ntdll"), "RtlGetVersion")) != NULL)
{
OSVERSIONINFOW ver = { sizeof(OSVERSIONINFOW), 0, 0, 0, {0} };

PRINT(("WASAPI: getting Windows version with RtlGetVersion()\n"));

if (fnRtlGetVersion(&ver) == NTSTATUS_SUCCESS)
{
dwMajorVersion = ver.dwMajorVersion;
dwMinorVersion = ver.dwMinorVersion;
dwBuild = ver.dwBuildNumber;
}
}

typedef DWORD (WINAPI *LPFN_GETVERSION)(VOID);
LPFN_GETVERSION fnGetVersion;
#undef NTSTATUS_SUCCESS

fnGetVersion = (LPFN_GETVERSION)GetProcAddress(GetModuleHandleA("kernel32"), "GetVersion");
if (fnGetVersion != NULL)
// fallback to GetVersion if RtlGetVersion is missing
if (dwMajorVersion == 0xFFFFFFFFU)
{
PRINT(("WASAPI: getting Windows version with GetVersion()\n"));
typedef DWORD (WINAPI *LPFN_GETVERSION)(VOID);
LPFN_GETVERSION fnGetVersion;

if ((fnGetVersion = (LPFN_GETVERSION)GetProcAddress(GetModuleHandleA("kernel32"), "GetVersion")) != NULL)
{
DWORD dwVersion;

dwVersion = fnGetVersion();
PRINT(("WASAPI: getting Windows version with GetVersion()\n"));

// Get the Windows version
dwMajorVersion = (DWORD)(LOBYTE(LOWORD(dwVersion)));
dwMinorVersion = (DWORD)(HIBYTE(LOWORD(dwVersion)));
dwVersion = fnGetVersion();

// Get the build number
if (dwVersion < 0x80000000)
dwBuild = (DWORD)(HIWORD(dwVersion));
dwMajorVersion = (DWORD)(LOBYTE(LOWORD(dwVersion)));
dwMinorVersion = (DWORD)(HIBYTE(LOWORD(dwVersion)));

if (dwVersion < 0x80000000)
dwBuild = (DWORD)(HIWORD(dwVersion));
}
}

if (dwMajorVersion != 0xFFFFFFFFU)
{
switch (dwMajorVersion)
{
case 0:
@@ -1042,6 +1070,7 @@ static EWindowsVersion GetWindowsVersion()
break;
}
}
// fallback to VerifyVersionInfo if RtlGetVersion and GetVersion are missing
else
{
PRINT(("WASAPI: getting Windows version with VerifyVersionInfo()\n"));
@@ -4884,6 +4913,21 @@ error:
}

// ------------------------------------------------------------------------------------------
PaError PaWasapi_GetAudioClient(PaStream *pStream, void **pAudioClient, int bOutput)
{
if (pAudioClient == NULL)
return paUnanticipatedHostError;

PaWasapiStream *stream = (PaWasapiStream *)pStream;
if (stream == NULL)
return paBadStreamPtr;

(*pAudioClient) = (bOutput == TRUE ? stream->out.clientParent : stream->in.clientParent);

return paNoError;
}

// ------------------------------------------------------------------------------------------
HRESULT _PollGetOutputFramesAvailable(PaWasapiStream *stream, UINT32 *available)
{
HRESULT hr;

Loading…
Cancel
Save