Browse Source

Merge branch 'winrt' into 'master'

New PaWasapi_GetAudioClient() API and workaround to get real Windows version and thus use correct AudioClient interface version.

Merged-on: https://assembla.com/code/portaudio/git/merge_requests/6574173
mr/new/64ad96ea3cf1853619d4827c049d87fe746bb584
Dmitry Kostjuchenko 1 year ago
parent
commit
64ad96ea3c
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