wasapi: ported to WinRT (UWP)
os: compatibility fixes for compilation of PortAudio as Windows Store library (only WASAPI hostapi is compatible with Windows Store APIs)
This commit is contained in:
parent
e111b3a269
commit
2e7545f17f
4 changed files with 454 additions and 53 deletions
|
|
@ -42,12 +42,18 @@
|
|||
@note pa_wasapi currently requires minimum VC 2005, and the latest Vista SDK
|
||||
*/
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN // exclude rare headers
|
||||
#include <windows.h>
|
||||
#include <stdio.h>
|
||||
#include <process.h>
|
||||
#include <assert.h>
|
||||
#include <mmsystem.h>
|
||||
|
||||
// WinRT
|
||||
#if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_APP)
|
||||
#define WIN32_WINRT
|
||||
#define INITGUID
|
||||
#endif
|
||||
|
||||
// WASAPI
|
||||
#include <mmreg.h> // must be before other Wasapi headers
|
||||
#if defined(_MSC_VER) && (_MSC_VER >= 1400)
|
||||
#include <Avrt.h>
|
||||
|
|
@ -61,9 +67,9 @@
|
|||
#undef INITGUID
|
||||
#endif
|
||||
#ifndef __MWERKS__
|
||||
#include <malloc.h>
|
||||
#include <memory.h>
|
||||
#endif /* __MWERKS__ */
|
||||
#include <malloc.h>
|
||||
#include <memory.h>
|
||||
#endif
|
||||
|
||||
#include "pa_util.h"
|
||||
#include "pa_allocation.h"
|
||||
|
|
@ -74,10 +80,9 @@
|
|||
#include "pa_win_wasapi.h"
|
||||
#include "pa_debugprint.h"
|
||||
#include "pa_ringbuffer.h"
|
||||
|
||||
#include "pa_win_coinitialize.h"
|
||||
|
||||
#ifndef NTDDI_VERSION
|
||||
#if !defined(NTDDI_VERSION)
|
||||
|
||||
#undef WINVER
|
||||
#undef _WIN32_WINNT
|
||||
|
|
@ -125,6 +130,7 @@
|
|||
#include <oleidl.h>
|
||||
#include <objidl.h>
|
||||
#else
|
||||
#ifndef WIN32_WINRT
|
||||
typedef struct _BYTE_BLOB
|
||||
{
|
||||
unsigned long clSize;
|
||||
|
|
@ -133,6 +139,7 @@
|
|||
typedef /* [unique] */ __RPC_unique_pointer BYTE_BLOB *UP_BYTE_BLOB;
|
||||
typedef LONGLONG REFERENCE_TIME;
|
||||
#define NONAMELESSUNION
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef WAVE_FORMAT_IEEE_FLOAT
|
||||
|
|
@ -160,6 +167,36 @@
|
|||
|
||||
#endif // NTDDI_VERSION
|
||||
|
||||
// Missing declarations for WinRT
|
||||
#ifdef WIN32_WINRT
|
||||
|
||||
typedef enum _EDataFlow
|
||||
{
|
||||
eRender = 0,
|
||||
eCapture = ( eRender + 1 ) ,
|
||||
eAll = ( eCapture + 1 ) ,
|
||||
EDataFlow_enum_count = ( eAll + 1 )
|
||||
}
|
||||
EDataFlow;
|
||||
|
||||
typedef enum _EndpointFormFactor
|
||||
{
|
||||
RemoteNetworkDevice = 0,
|
||||
Speakers = ( RemoteNetworkDevice + 1 ) ,
|
||||
LineLevel = ( Speakers + 1 ) ,
|
||||
Headphones = ( LineLevel + 1 ) ,
|
||||
Microphone = ( Headphones + 1 ) ,
|
||||
Headset = ( Microphone + 1 ) ,
|
||||
Handset = ( Headset + 1 ) ,
|
||||
UnknownDigitalPassthrough = ( Handset + 1 ) ,
|
||||
SPDIF = ( UnknownDigitalPassthrough + 1 ) ,
|
||||
HDMI = ( SPDIF + 1 ) ,
|
||||
UnknownFormFactor = ( HDMI + 1 )
|
||||
}
|
||||
EndpointFormFactor;
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef GUID_SECT
|
||||
#define GUID_SECT
|
||||
#endif
|
||||
|
|
@ -192,6 +229,7 @@ PA_DEFINE_IID(IDeviceTopology, 2A07407E, 6497, 4A18, 97, 87, 32, f7, 9b, d0
|
|||
PA_DEFINE_IID(IPart, AE2DE0E4, 5BCA, 4F2D, aa, 46, 5d, 13, f8, fd, b3, a9);
|
||||
// *4509F757-2D46-4637-8E62-CE7DB944F57B*
|
||||
PA_DEFINE_IID(IKsJackDescription, 4509F757, 2D46, 4637, 8e, 62, ce, 7d, b9, 44, f5, 7b);
|
||||
|
||||
// Media formats:
|
||||
__DEFINE_GUID(pa_KSDATAFORMAT_SUBTYPE_PCM, 0x00000001, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 );
|
||||
__DEFINE_GUID(pa_KSDATAFORMAT_SUBTYPE_ADPCM, 0x00000002, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 );
|
||||
|
|
@ -272,13 +310,13 @@ enum { WASAPI_PACKETS_PER_INPUT_BUFFER = 6 };
|
|||
typedef void (*MixMonoToStereoF) (void *__to, void *__from, UINT32 count);
|
||||
|
||||
// AVRT is the new "multimedia schedulling stuff"
|
||||
#ifndef WIN32_WINRT
|
||||
typedef BOOL (WINAPI *FAvRtCreateThreadOrderingGroup) (PHANDLE,PLARGE_INTEGER,GUID*,PLARGE_INTEGER);
|
||||
typedef BOOL (WINAPI *FAvRtDeleteThreadOrderingGroup) (HANDLE);
|
||||
typedef BOOL (WINAPI *FAvRtWaitOnThreadOrderingGroup) (HANDLE);
|
||||
typedef HANDLE (WINAPI *FAvSetMmThreadCharacteristics) (LPCSTR,LPDWORD);
|
||||
typedef BOOL (WINAPI *FAvRevertMmThreadCharacteristics)(HANDLE);
|
||||
typedef BOOL (WINAPI *FAvSetMmThreadPriority) (HANDLE,AVRT_PRIORITY);
|
||||
|
||||
static HMODULE hDInputDLL = 0;
|
||||
FAvRtCreateThreadOrderingGroup pAvRtCreateThreadOrderingGroup = NULL;
|
||||
FAvRtDeleteThreadOrderingGroup pAvRtDeleteThreadOrderingGroup = NULL;
|
||||
|
|
@ -286,6 +324,7 @@ FAvRtWaitOnThreadOrderingGroup pAvRtWaitOnThreadOrderingGroup = NULL;
|
|||
FAvSetMmThreadCharacteristics pAvSetMmThreadCharacteristics = NULL;
|
||||
FAvRevertMmThreadCharacteristics pAvRevertMmThreadCharacteristics = NULL;
|
||||
FAvSetMmThreadPriority pAvSetMmThreadPriority = NULL;
|
||||
#endif
|
||||
|
||||
#define _GetProc(fun, type, name) { \
|
||||
fun = (type) GetProcAddress(hDInputDLL,name); \
|
||||
|
|
@ -351,7 +390,9 @@ static signed long GetStreamWriteAvailable( PaStream* stream );
|
|||
typedef struct PaWasapiDeviceInfo
|
||||
{
|
||||
// Device
|
||||
#ifndef WIN32_WINRT
|
||||
IMMDevice *device;
|
||||
#endif
|
||||
|
||||
// from GetId
|
||||
WCHAR szDeviceID[MAX_STR_LEN];
|
||||
|
|
@ -359,9 +400,6 @@ typedef struct PaWasapiDeviceInfo
|
|||
// from GetState
|
||||
DWORD state;
|
||||
|
||||
// Fields filled from IMMEndpoint'sGetDataFlow
|
||||
EDataFlow flow;
|
||||
|
||||
// Fields filled from IAudioDevice (_prior_ to Initialize)
|
||||
// from GetDevicePeriod(
|
||||
REFERENCE_TIME DefaultDevicePeriod;
|
||||
|
|
@ -373,6 +411,9 @@ typedef struct PaWasapiDeviceInfo
|
|||
// Default format (setup through Control Panel by user)
|
||||
WAVEFORMATEXTENSIBLE DefaultFormat;
|
||||
|
||||
// Fields filled from IMMEndpoint'sGetDataFlow
|
||||
EDataFlow flow;
|
||||
|
||||
// Formfactor
|
||||
EndpointFormFactor formFactor;
|
||||
}
|
||||
|
|
@ -393,7 +434,9 @@ typedef struct
|
|||
PaWinUtilComInitializationResult comInitializationResult;
|
||||
|
||||
//in case we later need the synch
|
||||
#ifndef WIN32_WINRT
|
||||
IMMDeviceEnumerator *enumerator;
|
||||
#endif
|
||||
|
||||
//this is the REAL number of devices, whether they are usefull to PA or not!
|
||||
UINT32 deviceCount;
|
||||
|
|
@ -428,7 +471,9 @@ PaWasapiAudioClientParams;
|
|||
typedef struct PaWasapiSubStream
|
||||
{
|
||||
IAudioClient *clientParent;
|
||||
#ifndef WIN32_WINRT
|
||||
IStream *clientStream;
|
||||
#endif
|
||||
IAudioClient *clientProc;
|
||||
|
||||
WAVEFORMATEXTENSIBLE wavex;
|
||||
|
|
@ -478,14 +523,18 @@ typedef struct PaWasapiStream
|
|||
// input
|
||||
PaWasapiSubStream in;
|
||||
IAudioCaptureClient *captureClientParent;
|
||||
#ifndef WIN32_WINRT
|
||||
IStream *captureClientStream;
|
||||
#endif
|
||||
IAudioCaptureClient *captureClient;
|
||||
IAudioEndpointVolume *inVol;
|
||||
|
||||
// output
|
||||
PaWasapiSubStream out;
|
||||
IAudioRenderClient *renderClientParent;
|
||||
#ifndef WIN32_WINRT
|
||||
IStream *renderClientStream;
|
||||
#endif
|
||||
IAudioRenderClient *renderClient;
|
||||
IAudioEndpointVolume *outVol;
|
||||
|
||||
|
|
@ -812,6 +861,7 @@ static UINT32 GetFramesSleepTimeMicroseconds(UINT32 nFrames, UINT32 nSamplesPerS
|
|||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------
|
||||
#ifndef WIN32_WINRT
|
||||
static BOOL SetupAVRT()
|
||||
{
|
||||
hDInputDLL = LoadLibraryA("avrt.dll");
|
||||
|
|
@ -832,18 +882,23 @@ static BOOL SetupAVRT()
|
|||
pAvRevertMmThreadCharacteristics &&
|
||||
pAvSetMmThreadPriority;
|
||||
}
|
||||
#endif
|
||||
|
||||
// ------------------------------------------------------------------------------------------
|
||||
static void CloseAVRT()
|
||||
{
|
||||
#ifndef WIN32_WINRT
|
||||
if (hDInputDLL != NULL)
|
||||
FreeLibrary(hDInputDLL);
|
||||
hDInputDLL = NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------
|
||||
static BOOL IsWow64()
|
||||
{
|
||||
#ifndef WIN32_WINRT
|
||||
|
||||
// http://msdn.microsoft.com/en-us/library/ms684139(VS.85).aspx
|
||||
|
||||
typedef BOOL (WINAPI *LPFN_ISWOW64PROCESS) (HANDLE, PBOOL);
|
||||
|
|
@ -865,6 +920,12 @@ static BOOL IsWow64()
|
|||
return FALSE;
|
||||
|
||||
return bIsWow64;
|
||||
|
||||
#else
|
||||
|
||||
return FALSE;
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------
|
||||
|
|
@ -880,6 +941,7 @@ typedef enum EWindowsVersion
|
|||
}
|
||||
EWindowsVersion;
|
||||
// Alternative way for checking Windows version (allows to check version on Windows 8.1 and up)
|
||||
#ifndef WIN32_WINRT
|
||||
static BOOL IsWindowsVersionOrGreater(WORD wMajorVersion, WORD wMinorVersion, WORD wServicePackMajor)
|
||||
{
|
||||
typedef ULONGLONG (NTAPI *LPFN_VERSETCONDITIONMASK)(ULONGLONG ConditionMask, DWORD TypeMask, BYTE Condition);
|
||||
|
|
@ -909,9 +971,11 @@ static BOOL IsWindowsVersionOrGreater(WORD wMajorVersion, WORD wMinorVersion, WO
|
|||
|
||||
return (fnVerifyVersionInfo(&osvi, VER_MAJORVERSION | VER_MINORVERSION | VER_SERVICEPACKMAJOR, dwlConditionMask) != FALSE);
|
||||
}
|
||||
#endif
|
||||
// Get Windows version
|
||||
static EWindowsVersion GetWindowsVersion()
|
||||
{
|
||||
#ifndef WIN32_WINRT
|
||||
static EWindowsVersion version = WINDOWS_UNKNOWN;
|
||||
|
||||
if (version == WINDOWS_UNKNOWN)
|
||||
|
|
@ -996,6 +1060,9 @@ static EWindowsVersion GetWindowsVersion()
|
|||
}
|
||||
|
||||
return version;
|
||||
#else
|
||||
return WINDOWS_8_SERVER2012;
|
||||
#endif
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------
|
||||
|
|
@ -1167,6 +1234,179 @@ static MixMonoToStereoF _GetMonoToStereoMixer(PaSampleFormat format, EMixerDir d
|
|||
return NULL;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------
|
||||
#ifdef WIN32_WINRT
|
||||
typedef struct _CActivateAudioInterfaceCompletionHandler
|
||||
{
|
||||
IActivateAudioInterfaceCompletionHandler parent;
|
||||
ULONG refs;
|
||||
volatile BOOL done;
|
||||
struct
|
||||
{
|
||||
HRESULT hr;
|
||||
IAudioClient *client;
|
||||
}
|
||||
out;
|
||||
}
|
||||
CActivateAudioInterfaceCompletionHandler;
|
||||
|
||||
static HRESULT ( STDMETHODCALLTYPE CActivateAudioInterfaceCompletionHandler_QueryInterface )(
|
||||
IActivateAudioInterfaceCompletionHandler * This,
|
||||
/* [in] */ REFIID riid,
|
||||
/* [annotation][iid_is][out] */
|
||||
_COM_Outptr_ void **ppvObject)
|
||||
{
|
||||
CActivateAudioInterfaceCompletionHandler *handler = (CActivateAudioInterfaceCompletionHandler *)This;
|
||||
|
||||
// From MSDN:
|
||||
// "The IAgileObject interface is a marker interface that indicates that an object
|
||||
// is free threaded and can be called from any apartment."
|
||||
if (IsEqualIID(riid, &IID_IAgileObject))
|
||||
{
|
||||
handler->parent.lpVtbl->AddRef((IActivateAudioInterfaceCompletionHandler *)handler);
|
||||
(*ppvObject) = handler;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
return S_FALSE;
|
||||
}
|
||||
|
||||
static ULONG ( STDMETHODCALLTYPE CActivateAudioInterfaceCompletionHandler_AddRef )(
|
||||
IActivateAudioInterfaceCompletionHandler * This)
|
||||
{
|
||||
CActivateAudioInterfaceCompletionHandler *handler = (CActivateAudioInterfaceCompletionHandler *)This;
|
||||
return ++ handler->refs;
|
||||
}
|
||||
|
||||
static ULONG ( STDMETHODCALLTYPE CActivateAudioInterfaceCompletionHandler_Release )(
|
||||
IActivateAudioInterfaceCompletionHandler * This)
|
||||
{
|
||||
CActivateAudioInterfaceCompletionHandler *handler = (CActivateAudioInterfaceCompletionHandler *)This;
|
||||
if (handler->refs == 0)
|
||||
{
|
||||
PaUtil_FreeMemory(handler->parent.lpVtbl);
|
||||
PaUtil_FreeMemory(handler);
|
||||
return 0;
|
||||
}
|
||||
return -- handler->refs;
|
||||
}
|
||||
|
||||
static HRESULT ( STDMETHODCALLTYPE CActivateAudioInterfaceCompletionHandler_ActivateCompleted )(
|
||||
IActivateAudioInterfaceCompletionHandler * This,
|
||||
/* [annotation][in] */
|
||||
_In_ IActivateAudioInterfaceAsyncOperation *activateOperation)
|
||||
{
|
||||
CActivateAudioInterfaceCompletionHandler *handler = (CActivateAudioInterfaceCompletionHandler *)This;
|
||||
|
||||
HRESULT hr = S_OK;
|
||||
HRESULT hrActivateResult = S_OK;
|
||||
IUnknown *punkAudioInterface = NULL;
|
||||
|
||||
// Check for a successful activation result
|
||||
hr = activateOperation->lpVtbl->GetActivateResult(activateOperation, &hrActivateResult, &punkAudioInterface);
|
||||
if (SUCCEEDED(hr) && SUCCEEDED(hrActivateResult))
|
||||
{
|
||||
// Get the pointer for the Audio Client
|
||||
punkAudioInterface->lpVtbl->QueryInterface(punkAudioInterface, GetAudioClientIID(), &handler->out.client);
|
||||
if (handler->out.client == NULL)
|
||||
hrActivateResult = E_FAIL;
|
||||
}
|
||||
SAFE_RELEASE(punkAudioInterface);
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
handler->out.hr = hrActivateResult;
|
||||
else
|
||||
handler->out.hr = hr;
|
||||
|
||||
handler->done = TRUE;
|
||||
return hr;
|
||||
}
|
||||
|
||||
static IActivateAudioInterfaceCompletionHandler *CreateActivateAudioInterfaceCompletionHandler()
|
||||
{
|
||||
CActivateAudioInterfaceCompletionHandler *handler = PaUtil_AllocateMemory(sizeof(CActivateAudioInterfaceCompletionHandler));
|
||||
ZeroMemory(handler, sizeof(*handler));
|
||||
handler->parent.lpVtbl = PaUtil_AllocateMemory(sizeof(*handler->parent.lpVtbl));
|
||||
handler->parent.lpVtbl->QueryInterface = &CActivateAudioInterfaceCompletionHandler_QueryInterface;
|
||||
handler->parent.lpVtbl->AddRef = &CActivateAudioInterfaceCompletionHandler_AddRef;
|
||||
handler->parent.lpVtbl->Release = &CActivateAudioInterfaceCompletionHandler_Release;
|
||||
handler->parent.lpVtbl->ActivateCompleted = &CActivateAudioInterfaceCompletionHandler_ActivateCompleted;
|
||||
return (IActivateAudioInterfaceCompletionHandler *)handler;
|
||||
}
|
||||
#endif
|
||||
|
||||
// ------------------------------------------------------------------------------------------
|
||||
#ifdef WIN32_WINRT
|
||||
static HRESULT ActivateAudioInterface_WINRT(const PaWasapiDeviceInfo *deviceInfo, IAudioClient **client)
|
||||
{
|
||||
PaError result = paNoError;
|
||||
HRESULT hr = S_OK;
|
||||
HRESULT activateResult = S_OK;
|
||||
IActivateAudioInterfaceAsyncOperation *asyncOp = NULL;
|
||||
IActivateAudioInterfaceCompletionHandler *handler = CreateActivateAudioInterfaceCompletionHandler();
|
||||
CActivateAudioInterfaceCompletionHandler *ñhandler = (CActivateAudioInterfaceCompletionHandler *)handler;
|
||||
OLECHAR devicePath[64] = { 0 };
|
||||
|
||||
// Get device path in form L"{DEVICE_GUID}"
|
||||
switch (deviceInfo->flow)
|
||||
{
|
||||
case eRender:
|
||||
StringFromGUID2(&DEVINTERFACE_AUDIO_RENDER, devicePath, 63);
|
||||
break;
|
||||
case eCapture:
|
||||
StringFromGUID2(&DEVINTERFACE_AUDIO_CAPTURE, devicePath, 63);
|
||||
break;
|
||||
default:
|
||||
return S_FALSE;
|
||||
}
|
||||
|
||||
// Async operation will call back to IActivateAudioInterfaceCompletionHandler::ActivateCompleted
|
||||
// which must be an agile interface implementation
|
||||
hr = ActivateAudioInterfaceAsync(devicePath, GetAudioClientIID(), NULL, handler, &asyncOp);
|
||||
IF_FAILED_INTERNAL_ERROR_JUMP(hr, result, error);
|
||||
|
||||
// Wait in busy loop for async operation to complete
|
||||
while (SUCCEEDED(hr) && !ñhandler->done)
|
||||
{
|
||||
Pa_Sleep(1);
|
||||
}
|
||||
|
||||
(*client) = ñhandler->out.client;
|
||||
hr = ñhandler->out.hr;
|
||||
|
||||
error:
|
||||
|
||||
SAFE_RELEASE(asyncOp);
|
||||
SAFE_RELEASE(handler);
|
||||
|
||||
return hr;
|
||||
}
|
||||
#endif
|
||||
|
||||
// ------------------------------------------------------------------------------------------
|
||||
static HRESULT ActivateAudioInterface(const PaWasapiDeviceInfo *deviceInfo, IAudioClient **client)
|
||||
{
|
||||
#ifndef WIN32_WINRT
|
||||
return IMMDevice_Activate(deviceInfo->device, GetAudioClientIID(), CLSCTX_ALL, NULL, (void **)client);
|
||||
#else
|
||||
return ActivateAudioInterface_WINRT(deviceInfo, client);
|
||||
#endif
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------
|
||||
#ifdef WIN32_WINRT
|
||||
static DWORD SignalObjectAndWait(
|
||||
_In_ HANDLE hObjectToSignal,
|
||||
_In_ HANDLE hObjectToWaitOn,
|
||||
_In_ DWORD dwMilliseconds,
|
||||
_In_ BOOL bAlertable
|
||||
)
|
||||
{
|
||||
SetEvent(hObjectToSignal);
|
||||
return WaitForSingleObjectEx(hObjectToWaitOn, dwMilliseconds, bAlertable);
|
||||
}
|
||||
#endif
|
||||
|
||||
// ------------------------------------------------------------------------------------------
|
||||
PaError PaWasapi_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex hostApiIndex )
|
||||
{
|
||||
|
|
@ -1174,14 +1414,19 @@ PaError PaWasapi_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiInd
|
|||
PaWasapiHostApiRepresentation *paWasapi;
|
||||
PaDeviceInfo *deviceInfoArray;
|
||||
HRESULT hr = S_OK;
|
||||
#ifndef WIN32_WINRT
|
||||
IMMDeviceCollection* pEndPoints = NULL;
|
||||
#endif
|
||||
UINT i;
|
||||
WAVEFORMATEX *mixFormat;
|
||||
|
||||
#ifndef WIN32_WINRT
|
||||
if (!SetupAVRT())
|
||||
{
|
||||
PRINT(("WASAPI: No AVRT! (not VISTA?)"));
|
||||
return paNoError;
|
||||
}
|
||||
#endif
|
||||
|
||||
paWasapi = (PaWasapiHostApiRepresentation *)PaUtil_AllocateMemory( sizeof(PaWasapiHostApiRepresentation) );
|
||||
if (paWasapi == NULL)
|
||||
|
|
@ -1213,6 +1458,7 @@ PaError PaWasapi_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiInd
|
|||
(*hostApi)->info.defaultInputDevice = paNoDevice;
|
||||
(*hostApi)->info.defaultOutputDevice = paNoDevice;
|
||||
|
||||
#ifndef WIN32_WINRT
|
||||
paWasapi->enumerator = NULL;
|
||||
hr = CoCreateInstance(&pa_CLSID_IMMDeviceEnumerator, NULL, CLSCTX_INPROC_SERVER,
|
||||
&pa_IID_IMMDeviceEnumerator, (void **)&paWasapi->enumerator);
|
||||
|
|
@ -1282,6 +1528,10 @@ PaError PaWasapi_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiInd
|
|||
// [IF_FAILED_JUMP(hResult, error);]
|
||||
IF_FAILED_INTERNAL_ERROR_JUMP(hr, result, error);
|
||||
|
||||
#else
|
||||
paWasapi->deviceCount = 2;
|
||||
#endif
|
||||
|
||||
paWasapi->devInfo = (PaWasapiDeviceInfo *)PaUtil_AllocateMemory(sizeof(PaWasapiDeviceInfo) * paWasapi->deviceCount);
|
||||
if (paWasapi->devInfo == NULL)
|
||||
{
|
||||
|
|
@ -1320,6 +1570,7 @@ PaError PaWasapi_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiInd
|
|||
PA_DEBUG(("WASAPI: device idx: %02d\n", i));
|
||||
PA_DEBUG(("WASAPI: ---------------\n"));
|
||||
|
||||
#ifndef WIN32_WINRT
|
||||
hr = IMMDeviceCollection_Item(pEndPoints, i, &paWasapi->devInfo[i].device);
|
||||
// We need to set the result to a value otherwise we will return paNoError
|
||||
// [IF_FAILED_JUMP(hResult, error);]
|
||||
|
|
@ -1424,8 +1675,7 @@ PaError PaWasapi_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiInd
|
|||
|
||||
SAFE_RELEASE(pProperty);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Endpoint data
|
||||
{
|
||||
IMMEndpoint *endpoint = NULL;
|
||||
|
|
@ -1436,18 +1686,23 @@ PaError PaWasapi_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiInd
|
|||
SAFE_RELEASE(endpoint);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// Getting a temporary IAudioClient for more fields
|
||||
// we make sure NOT to call Initialize yet!
|
||||
{
|
||||
IAudioClient *tmpClient = NULL;
|
||||
#ifdef WIN32_WINRT
|
||||
// Set flow as ActivateAudioInterface depends on it and selects corresponding
|
||||
// direction for the Audio Client
|
||||
paWasapi->devInfo[i].flow = (i == 0 ? eRender : eCapture);
|
||||
#endif
|
||||
|
||||
hr = IMMDevice_Activate(paWasapi->devInfo[i].device, GetAudioClientIID(),
|
||||
CLSCTX_INPROC_SERVER, NULL, (void **)&tmpClient);
|
||||
// We need to set the result to a value otherwise we will return paNoError
|
||||
// [IF_FAILED_JUMP(hResult, error);]
|
||||
// Create temp Audio Client instance to query additional details
|
||||
IAudioClient *tmpClient = NULL;
|
||||
hr = ActivateAudioInterface(&paWasapi->devInfo[i], &tmpClient);
|
||||
IF_FAILED_INTERNAL_ERROR_JUMP(hr, result, error);
|
||||
|
||||
// Get latency
|
||||
hr = IAudioClient_GetDevicePeriod(tmpClient,
|
||||
&paWasapi->devInfo[i].DefaultDevicePeriod,
|
||||
&paWasapi->devInfo[i].MinimumDevicePeriod);
|
||||
|
|
@ -1462,10 +1717,42 @@ PaError PaWasapi_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiInd
|
|||
// ignore error, let continue further without failing with paInternalError
|
||||
hr = S_OK;
|
||||
}
|
||||
|
||||
#ifdef WIN32_WINRT
|
||||
// Get mix format which will treat as default device format
|
||||
hr = IAudioClient_GetMixFormat(tmpClient, &mixFormat);
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
// Default device
|
||||
if (i == 0)
|
||||
(*hostApi)->info.defaultOutputDevice = (*hostApi)->info.deviceCount;
|
||||
else
|
||||
(*hostApi)->info.defaultInputDevice = (*hostApi)->info.deviceCount;
|
||||
|
||||
//hr = tmpClient->GetMixFormat(&paWasapi->devInfo[i].MixFormat);
|
||||
// State
|
||||
paWasapi->devInfo[i].state = 1; // DEVICE_STATE_ACTIVE
|
||||
|
||||
// Release client
|
||||
// Default format
|
||||
memcpy(&paWasapi->devInfo[i].DefaultFormat, mixFormat, min(sizeof(paWasapi->devInfo[i].DefaultFormat), sizeof(*mixFormat)));
|
||||
CoTaskMemFree(mixFormat);
|
||||
|
||||
// Form-factor
|
||||
paWasapi->devInfo[i].formFactor = UnknownFormFactor;
|
||||
|
||||
// Name
|
||||
deviceInfo->name = PaUtil_GroupAllocateMemory(paWasapi->allocations, MAX_STR_LEN + 1);
|
||||
if (deviceInfo->name == NULL)
|
||||
{
|
||||
SAFE_RELEASE(tmpClient);
|
||||
result = paInsufficientMemory;
|
||||
goto error;
|
||||
}
|
||||
_snprintf(deviceInfo->name, MAX_STR_LEN - 1, "WASAPI_%s:%d", (i == 0 ? "Output" : "Input"), i);
|
||||
PA_DEBUG(("WASAPI:%d| name[%s]\n", i, deviceInfo->name));
|
||||
}
|
||||
#endif
|
||||
|
||||
// Release tmp client
|
||||
SAFE_RELEASE(tmpClient);
|
||||
|
||||
if (hr != S_OK)
|
||||
|
|
@ -1479,7 +1766,7 @@ PaError PaWasapi_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiInd
|
|||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// we can now fill in portaudio device data
|
||||
deviceInfo->maxInputChannels = 0;
|
||||
deviceInfo->maxOutputChannels = 0;
|
||||
|
|
@ -1532,7 +1819,9 @@ PaError PaWasapi_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiInd
|
|||
// findout if platform workaround is required
|
||||
paWasapi->useWOW64Workaround = UseWOW64Workaround();
|
||||
|
||||
#ifndef WIN32_WINRT
|
||||
SAFE_RELEASE(pEndPoints);
|
||||
#endif
|
||||
|
||||
PRINT(("WASAPI: initialized ok\n"));
|
||||
|
||||
|
|
@ -1542,7 +1831,9 @@ error:
|
|||
|
||||
PRINT(("WASAPI: failed %s error[%d|%s]\n", __FUNCTION__, result, Pa_GetErrorText(result)));
|
||||
|
||||
#ifndef WIN32_WINRT
|
||||
SAFE_RELEASE(pEndPoints);
|
||||
#endif
|
||||
|
||||
Terminate((PaUtilHostApiRepresentation *)paWasapi);
|
||||
|
||||
|
|
@ -1563,12 +1854,16 @@ static void Terminate( PaUtilHostApiRepresentation *hostApi )
|
|||
return;
|
||||
|
||||
// Release IMMDeviceEnumerator
|
||||
#ifndef WIN32_WINRT
|
||||
SAFE_RELEASE(paWasapi->enumerator);
|
||||
#endif
|
||||
|
||||
for (i = 0; i < paWasapi->deviceCount; ++i)
|
||||
{
|
||||
PaWasapiDeviceInfo *info = &paWasapi->devInfo[i];
|
||||
#ifndef WIN32_WINRT
|
||||
SAFE_RELEASE(info->device);
|
||||
#endif
|
||||
|
||||
//if (info->MixFormat)
|
||||
// CoTaskMemFree(info->MixFormat);
|
||||
|
|
@ -1830,25 +2125,25 @@ static PaError MakeWaveFormatFromParams(WAVEFORMATEXTENSIBLE *wavex, const PaStr
|
|||
{
|
||||
switch (params->channelCount)
|
||||
{
|
||||
case 1: wavex->dwChannelMask = KSAUDIO_SPEAKER_MONO; break;
|
||||
case 2: wavex->dwChannelMask = KSAUDIO_SPEAKER_STEREO; break;
|
||||
case 3: wavex->dwChannelMask = KSAUDIO_SPEAKER_STEREO|SPEAKER_LOW_FREQUENCY; break;
|
||||
case 4: wavex->dwChannelMask = KSAUDIO_SPEAKER_QUAD; break;
|
||||
case 5: wavex->dwChannelMask = KSAUDIO_SPEAKER_QUAD|SPEAKER_LOW_FREQUENCY; break;
|
||||
#ifdef KSAUDIO_SPEAKER_5POINT1_SURROUND
|
||||
case 6: wavex->dwChannelMask = KSAUDIO_SPEAKER_5POINT1_SURROUND; break;
|
||||
case 1: wavex->dwChannelMask = PAWIN_SPEAKER_MONO; break;
|
||||
case 2: wavex->dwChannelMask = PAWIN_SPEAKER_STEREO; break;
|
||||
case 3: wavex->dwChannelMask = PAWIN_SPEAKER_STEREO|SPEAKER_LOW_FREQUENCY; break;
|
||||
case 4: wavex->dwChannelMask = PAWIN_SPEAKER_QUAD; break;
|
||||
case 5: wavex->dwChannelMask = PAWIN_SPEAKER_QUAD|SPEAKER_LOW_FREQUENCY; break;
|
||||
#ifdef PAWIN_SPEAKER_5POINT1_SURROUND
|
||||
case 6: wavex->dwChannelMask = PAWIN_SPEAKER_5POINT1_SURROUND; break;
|
||||
#else
|
||||
case 6: wavex->dwChannelMask = KSAUDIO_SPEAKER_5POINT1; break;
|
||||
case 6: wavex->dwChannelMask = PAWIN_SPEAKER_5POINT1; break;
|
||||
#endif
|
||||
#ifdef KSAUDIO_SPEAKER_5POINT1_SURROUND
|
||||
case 7: wavex->dwChannelMask = KSAUDIO_SPEAKER_5POINT1_SURROUND|SPEAKER_BACK_CENTER; break;
|
||||
#ifdef PAWIN_SPEAKER_5POINT1_SURROUND
|
||||
case 7: wavex->dwChannelMask = PAWIN_SPEAKER_5POINT1_SURROUND|SPEAKER_BACK_CENTER; break;
|
||||
#else
|
||||
case 7: wavex->dwChannelMask = KSAUDIO_SPEAKER_5POINT1|SPEAKER_BACK_CENTER; break;
|
||||
case 7: wavex->dwChannelMask = PAWIN_SPEAKER_5POINT1|SPEAKER_BACK_CENTER; break;
|
||||
#endif
|
||||
#ifdef KSAUDIO_SPEAKER_7POINT1_SURROUND
|
||||
case 8: wavex->dwChannelMask = KSAUDIO_SPEAKER_7POINT1_SURROUND; break;
|
||||
#ifdef PAWIN_SPEAKER_7POINT1_SURROUND
|
||||
case 8: wavex->dwChannelMask = PAWIN_SPEAKER_7POINT1_SURROUND; break;
|
||||
#else
|
||||
case 8: wavex->dwChannelMask = KSAUDIO_SPEAKER_7POINT1; break;
|
||||
case 8: wavex->dwChannelMask = PAWIN_SPEAKER_7POINT1; break;
|
||||
#endif
|
||||
|
||||
default: wavex->dwChannelMask = 0;
|
||||
|
|
@ -1869,9 +2164,9 @@ static PaError MakeWaveFormatFromParams(WAVEFORMATEXTENSIBLE *wavex, const PaStr
|
|||
pwfext->Format.nChannels = (WORD)channelCount;
|
||||
pwfext->Format.nSamplesPerSec = (DWORD)sampleRate;
|
||||
if(channelCount == 1)
|
||||
pwfext->dwChannelMask = KSAUDIO_SPEAKER_DIRECTOUT;
|
||||
pwfext->dwChannelMask = PAWIN_SPEAKER_DIRECTOUT;
|
||||
else
|
||||
pwfext->dwChannelMask = KSAUDIO_SPEAKER_STEREO;
|
||||
pwfext->dwChannelMask = PAWIN_SPEAKER_STEREO;
|
||||
if(sampleFormat == paFloat32)
|
||||
{
|
||||
pwfext->Format.nBlockAlign = (WORD)(channelCount * 4);
|
||||
|
|
@ -2154,8 +2449,7 @@ static PaError IsFormatSupported( struct PaUtilHostApiRepresentation *hostApi,
|
|||
if (inputStreamInfo && (inputStreamInfo->flags & paWinWasapiExclusive))
|
||||
shareMode = AUDCLNT_SHAREMODE_EXCLUSIVE;
|
||||
|
||||
hr = IMMDevice_Activate(paWasapi->devInfo[inputParameters->device].device,
|
||||
GetAudioClientIID(), CLSCTX_INPROC_SERVER, NULL, (void **)&tmpClient);
|
||||
hr = ActivateAudioInterface(&paWasapi->devInfo[inputParameters->device], &tmpClient);
|
||||
if (hr != S_OK)
|
||||
{
|
||||
LogHostError(hr);
|
||||
|
|
@ -2180,8 +2474,7 @@ static PaError IsFormatSupported( struct PaUtilHostApiRepresentation *hostApi,
|
|||
if (outputStreamInfo && (outputStreamInfo->flags & paWinWasapiExclusive))
|
||||
shareMode = AUDCLNT_SHAREMODE_EXCLUSIVE;
|
||||
|
||||
hr = IMMDevice_Activate(paWasapi->devInfo[outputParameters->device].device,
|
||||
GetAudioClientIID(), CLSCTX_INPROC_SERVER, NULL, (void **)&tmpClient);
|
||||
hr = ActivateAudioInterface(&paWasapi->devInfo[outputParameters->device], &tmpClient);
|
||||
if (hr != S_OK)
|
||||
{
|
||||
LogHostError(hr);
|
||||
|
|
@ -2281,7 +2574,7 @@ static HRESULT CreateAudioClient(PaWasapiStream *pStream, PaWasapiSubStream *pSu
|
|||
}
|
||||
|
||||
// Get the audio client
|
||||
hr = IMMDevice_Activate(pInfo->device, GetAudioClientIID(), CLSCTX_ALL, NULL, (void **)&audioClient);
|
||||
hr = ActivateAudioInterface(pInfo, &audioClient);
|
||||
if (hr != S_OK)
|
||||
{
|
||||
(*pa_error) = paInsufficientMemory;
|
||||
|
|
@ -2495,7 +2788,7 @@ static HRESULT CreateAudioClient(PaWasapiStream *pStream, PaWasapiSubStream *pSu
|
|||
SAFE_RELEASE(audioClient);
|
||||
|
||||
// Create a new audio client
|
||||
hr = IMMDevice_Activate(pInfo->device, GetAudioClientIID(), CLSCTX_ALL, NULL, (void**)&audioClient);
|
||||
hr = ActivateAudioInterface(pInfo, &audioClient);
|
||||
if (hr != S_OK)
|
||||
{
|
||||
(*pa_error) = paInsufficientMemory;
|
||||
|
|
@ -2526,7 +2819,7 @@ static HRESULT CreateAudioClient(PaWasapiStream *pStream, PaWasapiSubStream *pSu
|
|||
SAFE_RELEASE(audioClient);
|
||||
|
||||
// Create a new audio client
|
||||
hr = IMMDevice_Activate(pInfo->device, GetAudioClientIID(), CLSCTX_ALL, NULL, (void**)&audioClient);
|
||||
hr = ActivateAudioInterface(pInfo, &audioClient);
|
||||
if (hr != S_OK)
|
||||
{
|
||||
(*pa_error) = paInsufficientMemory;
|
||||
|
|
@ -2566,7 +2859,7 @@ static HRESULT CreateAudioClient(PaWasapiStream *pStream, PaWasapiSubStream *pSu
|
|||
SAFE_RELEASE(audioClient);
|
||||
|
||||
// Create a new audio client
|
||||
hr = IMMDevice_Activate(pInfo->device, GetAudioClientIID(), CLSCTX_ALL, NULL, (void**)&audioClient);
|
||||
hr = ActivateAudioInterface(pInfo, &audioClient);
|
||||
if (hr != S_OK)
|
||||
{
|
||||
(*pa_error) = paInsufficientMemory;
|
||||
|
|
@ -3249,6 +3542,7 @@ static PaError CloseStream( PaStream* s )
|
|||
// ------------------------------------------------------------------------------------------
|
||||
HRESULT UnmarshalSubStreamComPointers(PaWasapiSubStream *substream)
|
||||
{
|
||||
#ifndef WIN32_WINRT
|
||||
HRESULT hResult = S_OK;
|
||||
HRESULT hFirstBadResult = S_OK;
|
||||
substream->clientProc = NULL;
|
||||
|
|
@ -3262,11 +3556,16 @@ HRESULT UnmarshalSubStreamComPointers(PaWasapiSubStream *substream)
|
|||
}
|
||||
|
||||
return hFirstBadResult;
|
||||
|
||||
#else
|
||||
return S_OK;
|
||||
#endif
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------
|
||||
HRESULT UnmarshalStreamComPointers(PaWasapiStream *stream)
|
||||
{
|
||||
#ifndef WIN32_WINRT
|
||||
HRESULT hResult = S_OK;
|
||||
HRESULT hFirstBadResult = S_OK;
|
||||
stream->captureClient = NULL;
|
||||
|
|
@ -3311,6 +3610,33 @@ HRESULT UnmarshalStreamComPointers(PaWasapiStream *stream)
|
|||
}
|
||||
|
||||
return hFirstBadResult;
|
||||
#else
|
||||
if (stream->in.clientParent != NULL)
|
||||
{
|
||||
stream->in.clientProc = stream->in.clientParent;
|
||||
IAudioClient_AddRef(stream->in.clientParent);
|
||||
}
|
||||
|
||||
if (stream->out.clientParent != NULL)
|
||||
{
|
||||
stream->out.clientProc = stream->out.clientParent;
|
||||
IAudioClient_AddRef(stream->out.clientParent);
|
||||
}
|
||||
|
||||
if (stream->renderClientParent != NULL)
|
||||
{
|
||||
stream->renderClient = stream->renderClientParent;
|
||||
IAudioRenderClient_AddRef(stream->renderClientParent);
|
||||
}
|
||||
|
||||
if (stream->captureClientParent != NULL)
|
||||
{
|
||||
stream->captureClient = stream->captureClientParent;
|
||||
IAudioCaptureClient_AddRef(stream->captureClientParent);
|
||||
}
|
||||
|
||||
return S_OK;
|
||||
#endif
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------------------
|
||||
|
|
@ -3334,6 +3660,7 @@ void ReleaseUnmarshaledComPointers(PaWasapiStream *stream)
|
|||
// ------------------------------------------------------------------------------------------
|
||||
HRESULT MarshalSubStreamComPointers(PaWasapiSubStream *substream)
|
||||
{
|
||||
#ifndef WIN32_WINRT
|
||||
HRESULT hResult;
|
||||
substream->clientStream = NULL;
|
||||
|
||||
|
|
@ -3350,11 +3677,15 @@ marshal_sub_error:
|
|||
UnmarshalSubStreamComPointers(substream);
|
||||
ReleaseUnmarshaledSubComPointers(substream);
|
||||
return hResult;
|
||||
#else
|
||||
return S_OK;
|
||||
#endif
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------
|
||||
HRESULT MarshalStreamComPointers(PaWasapiStream *stream)
|
||||
{
|
||||
#ifndef WIN32_WINRT
|
||||
HRESULT hResult = S_OK;
|
||||
stream->captureClientStream = NULL;
|
||||
stream->in.clientStream = NULL;
|
||||
|
|
@ -3395,6 +3726,9 @@ marshal_error:
|
|||
UnmarshalStreamComPointers(stream);
|
||||
ReleaseUnmarshaledComPointers(stream);
|
||||
return hResult;
|
||||
#else
|
||||
return S_OK;
|
||||
#endif
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------
|
||||
|
|
@ -3743,7 +4077,7 @@ static PaError ReadStream( PaStream* s, void *_buffer, unsigned long frames )
|
|||
{
|
||||
if ((sleep = ThreadIdleScheduler_NextSleep(&sched)) != 0)
|
||||
{
|
||||
Sleep(sleep);
|
||||
Pa_Sleep(sleep);
|
||||
sleep = 0;
|
||||
}
|
||||
}
|
||||
|
|
@ -4079,6 +4413,7 @@ static void WaspiHostProcessingLoop( void *inputBuffer, long inputFrames,
|
|||
// ------------------------------------------------------------------------------------------
|
||||
HANDLE MMCSS_activate(const char *name)
|
||||
{
|
||||
#ifndef WIN32_WINRT
|
||||
DWORD task_idx = 0;
|
||||
HANDLE hTask = pAvSetMmThreadCharacteristics(name, &task_idx);
|
||||
if (hTask == NULL)
|
||||
|
|
@ -4100,6 +4435,9 @@ HANDLE MMCSS_activate(const char *name)
|
|||
}
|
||||
|
||||
return hTask;
|
||||
#else
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------
|
||||
|
|
@ -4108,10 +4446,12 @@ void MMCSS_deactivate(HANDLE hTask)
|
|||
if (!hTask)
|
||||
return;
|
||||
|
||||
#ifndef WIN32_WINRT
|
||||
if (pAvRevertMmThreadCharacteristics(hTask) == FALSE)
|
||||
{
|
||||
PRINT(("WASAPI: AvRevertMmThreadCharacteristics failed!\n"));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------
|
||||
|
|
@ -4161,6 +4501,7 @@ PaError PaWasapi_ThreadPriorityRevert(void *hTask)
|
|||
|
||||
PaError PaWasapi_GetJackCount(PaDeviceIndex nDevice, int *jcount)
|
||||
{
|
||||
#ifndef WIN32_WINRT
|
||||
PaError ret;
|
||||
HRESULT hr = S_OK;
|
||||
PaDeviceIndex index;
|
||||
|
|
@ -4230,9 +4571,13 @@ error:
|
|||
|
||||
LogHostError(hr);
|
||||
return paNoError;
|
||||
#else
|
||||
return paUnanticipatedHostError;
|
||||
#endif
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------
|
||||
#ifndef WIN32_WINRT
|
||||
static PaWasapiJackConnectionType ConvertJackConnectionTypeWASAPIToPA(int connType)
|
||||
{
|
||||
switch (connType)
|
||||
|
|
@ -4256,8 +4601,10 @@ static PaWasapiJackConnectionType ConvertJackConnectionTypeWASAPIToPA(int connTy
|
|||
}
|
||||
return eJackConnTypeUnknown;
|
||||
}
|
||||
#endif
|
||||
|
||||
// ------------------------------------------------------------------------------------------
|
||||
#ifndef WIN32_WINRT
|
||||
static PaWasapiJackGeoLocation ConvertJackGeoLocationWASAPIToPA(int geoLoc)
|
||||
{
|
||||
switch (geoLoc)
|
||||
|
|
@ -4282,8 +4629,10 @@ static PaWasapiJackGeoLocation ConvertJackGeoLocationWASAPIToPA(int geoLoc)
|
|||
}
|
||||
return eJackGeoLocUnk;
|
||||
}
|
||||
#endif
|
||||
|
||||
// ------------------------------------------------------------------------------------------
|
||||
#ifndef WIN32_WINRT
|
||||
static PaWasapiJackGenLocation ConvertJackGenLocationWASAPIToPA(int genLoc)
|
||||
{
|
||||
switch (genLoc)
|
||||
|
|
@ -4299,8 +4648,10 @@ static PaWasapiJackGenLocation ConvertJackGenLocationWASAPIToPA(int genLoc)
|
|||
}
|
||||
return eJackGenLocPrimaryBox;
|
||||
}
|
||||
#endif
|
||||
|
||||
// ------------------------------------------------------------------------------------------
|
||||
#ifndef WIN32_WINRT
|
||||
static PaWasapiJackPortConnection ConvertJackPortConnectionWASAPIToPA(int portConn)
|
||||
{
|
||||
switch (portConn)
|
||||
|
|
@ -4312,6 +4663,7 @@ static PaWasapiJackPortConnection ConvertJackPortConnectionWASAPIToPA(int portCo
|
|||
}
|
||||
return eJackPortConnJack;
|
||||
}
|
||||
#endif
|
||||
|
||||
// ------------------------------------------------------------------------------------------
|
||||
// Described at:
|
||||
|
|
@ -4319,6 +4671,7 @@ static PaWasapiJackPortConnection ConvertJackPortConnectionWASAPIToPA(int portCo
|
|||
|
||||
PaError PaWasapi_GetJackDescription(PaDeviceIndex nDevice, int jindex, PaWasapiJackDescription *pJackDescription)
|
||||
{
|
||||
#ifndef WIN32_WINRT
|
||||
PaError ret;
|
||||
HRESULT hr = S_OK;
|
||||
PaDeviceIndex index;
|
||||
|
|
@ -4394,6 +4747,10 @@ error:
|
|||
|
||||
LogHostError(hr);
|
||||
return ret;
|
||||
|
||||
#else
|
||||
return paUnanticipatedHostError;
|
||||
#endif
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@
|
|||
#include "pa_win_coinitialize.h"
|
||||
|
||||
|
||||
#if (defined(WIN32) && (defined(_MSC_VER) && (_MSC_VER >= 1200))) && !defined(_WIN32_WCE) /* MSC version 6 and above */
|
||||
#if (defined(WIN32) && (defined(_MSC_VER) && (_MSC_VER >= 1200))) && !defined(_WIN32_WCE) && !(defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_APP)) /* MSC version 6 and above */
|
||||
#pragma comment( lib, "ole32.lib" )
|
||||
#endif
|
||||
|
||||
|
|
@ -76,7 +76,11 @@ PaError PaWinUtil_CoInitialize( PaHostApiTypeId hostApiType, PaWinUtilComInitial
|
|||
RPC_E_CHANGED_MODE was returned.
|
||||
*/
|
||||
|
||||
#if !defined(WINAPI_FAMILY) || (WINAPI_FAMILY != WINAPI_FAMILY_APP)
|
||||
hr = CoInitialize(0); /* use legacy-safe equivalent to CoInitializeEx(NULL, COINIT_APARTMENTTHREADED) */
|
||||
#else
|
||||
hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);
|
||||
#endif
|
||||
if( FAILED(hr) && hr != RPC_E_CHANGED_MODE )
|
||||
{
|
||||
PA_DEBUG(("CoInitialize(0) failed. hr=%d\n", hr));
|
||||
|
|
|
|||
|
|
@ -44,14 +44,17 @@
|
|||
*/
|
||||
|
||||
#include <windows.h>
|
||||
#include <mmsystem.h> /* for timeGetTime() */
|
||||
|
||||
#include "pa_util.h"
|
||||
|
||||
#if (defined(WIN32) && (defined(_MSC_VER) && (_MSC_VER >= 1200))) && !defined(_WIN32_WCE) /* MSC version 6 and above */
|
||||
#pragma comment( lib, "winmm.lib" )
|
||||
#if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_APP)
|
||||
#include <sys/timeb.h> /* for _ftime_s() */
|
||||
#else
|
||||
#include <mmsystem.h> /* for timeGetTime() */
|
||||
#if (defined(WIN32) && (defined(_MSC_VER) && (_MSC_VER >= 1200))) && !defined(_WIN32_WCE) /* MSC version 6 and above */
|
||||
#pragma comment( lib, "winmm.lib" )
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include "pa_util.h"
|
||||
|
||||
/*
|
||||
Track memory allocations to avoid leaks.
|
||||
|
|
@ -144,8 +147,14 @@ double PaUtil_GetTime( void )
|
|||
}
|
||||
else
|
||||
{
|
||||
#ifndef UNDER_CE
|
||||
#ifndef UNDER_CE
|
||||
#if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_APP)
|
||||
struct _timeb tv = { 0 };
|
||||
_ftime_s(&tv);
|
||||
return (double)tv.time + tv.millitm * .001;
|
||||
#else
|
||||
return timeGetTime() * .001;
|
||||
#endif
|
||||
#else
|
||||
return GetTickCount() * .001;
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -47,6 +47,37 @@
|
|||
#define WAVE_FORMAT_EXTENSIBLE 0xFFFE
|
||||
#endif
|
||||
|
||||
|
||||
#if !defined(WAVE_FORMAT_PCM)
|
||||
#define WAVE_FORMAT_PCM 1
|
||||
typedef struct tWAVEFORMAT
|
||||
{
|
||||
WORD wFormatTag;
|
||||
WORD nChannels;
|
||||
DWORD nSamplesPerSec;
|
||||
DWORD nAvgBytesPerSec;
|
||||
WORD nBlockAlign;
|
||||
}
|
||||
WAVEFORMAT;
|
||||
#endif
|
||||
|
||||
|
||||
#if !defined(_WAVEFORMATEX_)
|
||||
#define _WAVEFORMATEX_
|
||||
typedef struct tWAVEFORMATEX
|
||||
{
|
||||
WORD wFormatTag;
|
||||
WORD nChannels;
|
||||
DWORD nSamplesPerSec;
|
||||
DWORD nAvgBytesPerSec;
|
||||
WORD nBlockAlign;
|
||||
WORD wBitsPerSample;
|
||||
WORD cbSize;
|
||||
}
|
||||
WAVEFORMATEX;
|
||||
#endif
|
||||
|
||||
|
||||
static GUID pawin_ksDataFormatSubtypeGuidBase =
|
||||
{ (USHORT)(WAVE_FORMAT_PCM), 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71 };
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue