Browse Source

Eliminated some OS dependencies in WASAPI. Added mingw workarounds for __uuidof

tags/2021-05-28
jules 12 years ago
parent
commit
2be6b48cd9
4 changed files with 216 additions and 87 deletions
  1. +0
    -12
      modules/juce_audio_devices/juce_audio_devices.cpp
  2. +204
    -74
      modules/juce_audio_devices/native/juce_win32_WASAPI.cpp
  3. +1
    -1
      modules/juce_core/juce_module_info
  4. +11
    -0
      modules/juce_core/native/juce_win32_ComSmartPtr.h

+ 0
- 12
modules/juce_audio_devices/juce_audio_devices.cpp View File

@@ -57,20 +57,8 @@
//==============================================================================
#elif JUCE_WINDOWS
#if JUCE_MINGW && JUCE_WASAPI
#warning "WASAPI not currently implemented with mingw..."
#undef JUCE_WASAPI
#endif
#if JUCE_WASAPI
#pragma warning (push)
#pragma warning (disable: 4201)
#include <MMReg.h>
#include <Audioclient.h>
#include <Audiopolicy.h>
#include <Avrt.h>
#include <functiondiscoverykeys.h>
#pragma warning (pop)
#endif
#if JUCE_ASIO


+ 204
- 74
modules/juce_audio_devices/native/juce_win32_WASAPI.cpp View File

@@ -91,85 +91,210 @@ bool check (HRESULT hr)
}
//==============================================================================
namespace
}
#if JUCE_MINGW
#define JUCE_COMCLASS(name, guid) \
struct name; \
template<> struct UUIDGetter<name> { static CLSID get() { return uuidFromString (guid); } }; \
struct name
#define KSDATAFORMAT_SUBTYPE_PCM uuidFromString ("00000001-0000-0010-8000-00aa00389b71")
#define KSDATAFORMAT_SUBTYPE_IEEE_FLOAT uuidFromString ("00000003-0000-0010-8000-00aa00389b71")
struct PROPERTYKEY
{
GUID fmtid;
DWORD pid;
};
WINOLEAPI PropVariantClear (PROPVARIANT*);
#else
#define JUCE_COMCLASS(name, guid) struct __declspec (uuid (guid)) name
#endif
#define JUCE_IUNKNOWNCLASS(name, guid) JUCE_COMCLASS(name, guid) : public IUnknown
#define JUCE_COMCALL virtual HRESULT STDMETHODCALLTYPE
enum EDataFlow
{
enum EDataFlow
{
eRender = 0,
eCapture = (eRender + 1),
eAll = (eCapture + 1)
};
eRender = 0,
eCapture = (eRender + 1),
eAll = (eCapture + 1)
};
enum { DEVICE_STATE_ACTIVE = 1 };
enum { DEVICE_STATE_ACTIVE = 1 };
struct __declspec (uuid ("D666063F-1587-4E43-81F1-B948E807363F")) IMMDevice : public IUnknown
{
virtual HRESULT STDMETHODCALLTYPE Activate(REFIID, DWORD, PROPVARIANT*, void**) = 0;
virtual HRESULT STDMETHODCALLTYPE OpenPropertyStore(DWORD, IPropertyStore**) = 0;
virtual HRESULT STDMETHODCALLTYPE GetId(LPWSTR*) = 0;
virtual HRESULT STDMETHODCALLTYPE GetState(DWORD*) = 0;
};
JUCE_IUNKNOWNCLASS (IPropertyStore, "886d8eeb-8cf2-4446-8d02-cdba1dbdcf99")
{
JUCE_COMCALL GetCount (DWORD*) = 0;
JUCE_COMCALL GetAt (DWORD, PROPERTYKEY*) = 0;
JUCE_COMCALL GetValue (const PROPERTYKEY&, PROPVARIANT*) = 0;
JUCE_COMCALL SetValue (const PROPERTYKEY&, const PROPVARIANT&) = 0;
JUCE_COMCALL Commit() = 0;
};
struct __declspec (uuid ("1BE09788-6894-4089-8586-9A2A6C265AC5")) IMMEndpoint : public IUnknown
{
virtual HRESULT STDMETHODCALLTYPE GetDataFlow(EDataFlow*) = 0;
};
JUCE_IUNKNOWNCLASS (IMMDevice, "D666063F-1587-4E43-81F1-B948E807363F")
{
JUCE_COMCALL Activate (REFIID, DWORD, PROPVARIANT*, void**) = 0;
JUCE_COMCALL OpenPropertyStore (DWORD, IPropertyStore**) = 0;
JUCE_COMCALL GetId (LPWSTR*) = 0;
JUCE_COMCALL GetState (DWORD*) = 0;
};
struct IMMDeviceCollection : public IUnknown
{
virtual HRESULT STDMETHODCALLTYPE GetCount(UINT*) = 0;
virtual HRESULT STDMETHODCALLTYPE Item(UINT, IMMDevice**) = 0;
};
JUCE_IUNKNOWNCLASS (IMMEndpoint, "1BE09788-6894-4089-8586-9A2A6C265AC5")
{
JUCE_COMCALL GetDataFlow (EDataFlow*) = 0;
};
enum ERole
{
eConsole = 0,
eMultimedia = (eConsole + 1),
eCommunications = (eMultimedia + 1)
};
struct IMMDeviceCollection : public IUnknown
{
JUCE_COMCALL GetCount (UINT*) = 0;
JUCE_COMCALL Item (UINT, IMMDevice**) = 0;
};
struct __declspec (uuid ("7991EEC9-7E89-4D85-8390-6C703CEC60C0")) IMMNotificationClient : public IUnknown
{
virtual HRESULT STDMETHODCALLTYPE OnDeviceStateChanged(LPCWSTR, DWORD) = 0;
virtual HRESULT STDMETHODCALLTYPE OnDeviceAdded(LPCWSTR) = 0;
virtual HRESULT STDMETHODCALLTYPE OnDeviceRemoved(LPCWSTR) = 0;
virtual HRESULT STDMETHODCALLTYPE OnDefaultDeviceChanged(EDataFlow, ERole, LPCWSTR) = 0;
virtual HRESULT STDMETHODCALLTYPE OnPropertyValueChanged(LPCWSTR, const PROPERTYKEY) = 0;
};
enum ERole
{
eConsole = 0,
eMultimedia = (eConsole + 1),
eCommunications = (eMultimedia + 1)
};
struct __declspec (uuid ("A95664D2-9614-4F35-A746-DE8DB63617E6")) IMMDeviceEnumerator : public IUnknown
{
virtual HRESULT STDMETHODCALLTYPE EnumAudioEndpoints(EDataFlow, DWORD, IMMDeviceCollection**) = 0;
virtual HRESULT STDMETHODCALLTYPE GetDefaultAudioEndpoint(EDataFlow, ERole, IMMDevice**) = 0;
virtual HRESULT STDMETHODCALLTYPE GetDevice(LPCWSTR, IMMDevice**) = 0;
virtual HRESULT STDMETHODCALLTYPE RegisterEndpointNotificationCallback(IMMNotificationClient*) = 0;
virtual HRESULT STDMETHODCALLTYPE UnregisterEndpointNotificationCallback(IMMNotificationClient*) = 0;
};
JUCE_IUNKNOWNCLASS (IMMNotificationClient, "7991EEC9-7E89-4D85-8390-6C703CEC60C0")
{
JUCE_COMCALL OnDeviceStateChanged (LPCWSTR, DWORD) = 0;
JUCE_COMCALL OnDeviceAdded (LPCWSTR) = 0;
JUCE_COMCALL OnDeviceRemoved (LPCWSTR) = 0;
JUCE_COMCALL OnDefaultDeviceChanged (EDataFlow, ERole, LPCWSTR) = 0;
JUCE_COMCALL OnPropertyValueChanged (LPCWSTR, const PROPERTYKEY) = 0;
};
struct __declspec (uuid ("BCDE0395-E52F-467C-8E3D-C4579291692E")) MMDeviceEnumerator;
JUCE_IUNKNOWNCLASS (IMMDeviceEnumerator, "A95664D2-9614-4F35-A746-DE8DB63617E6")
{
JUCE_COMCALL EnumAudioEndpoints (EDataFlow, DWORD, IMMDeviceCollection**) = 0;
JUCE_COMCALL GetDefaultAudioEndpoint (EDataFlow, ERole, IMMDevice**) = 0;
JUCE_COMCALL GetDevice (LPCWSTR, IMMDevice**) = 0;
JUCE_COMCALL RegisterEndpointNotificationCallback (IMMNotificationClient*) = 0;
JUCE_COMCALL UnregisterEndpointNotificationCallback (IMMNotificationClient*) = 0;
};
struct __declspec (uuid ("5CDF2C82-841E-4546-9722-0CF74078229A")) IAudioEndpointVolume : public IUnknown
{
virtual HRESULT STDMETHODCALLTYPE RegisterControlChangeNotify (void*) = 0;
virtual HRESULT STDMETHODCALLTYPE UnregisterControlChangeNotify (void*) = 0;
virtual HRESULT STDMETHODCALLTYPE GetChannelCount (UINT*) = 0;
virtual HRESULT STDMETHODCALLTYPE SetMasterVolumeLevel (float, LPCGUID) = 0;
virtual HRESULT STDMETHODCALLTYPE SetMasterVolumeLevelScalar (float, LPCGUID) = 0;
virtual HRESULT STDMETHODCALLTYPE GetMasterVolumeLevel (float*) = 0;
virtual HRESULT STDMETHODCALLTYPE GetMasterVolumeLevelScalar (float*) = 0;
virtual HRESULT STDMETHODCALLTYPE SetChannelVolumeLevel (UINT, float, LPCGUID) = 0;
virtual HRESULT STDMETHODCALLTYPE SetChannelVolumeLevelScalar (UINT, float, LPCGUID) = 0;
virtual HRESULT STDMETHODCALLTYPE GetChannelVolumeLevel (UINT, float*) = 0;
virtual HRESULT STDMETHODCALLTYPE GetChannelVolumeLevelScalar (UINT, float*) = 0;
virtual HRESULT STDMETHODCALLTYPE SetMute (BOOL, LPCGUID) = 0;
virtual HRESULT STDMETHODCALLTYPE GetMute (BOOL*) = 0;
virtual HRESULT STDMETHODCALLTYPE GetVolumeStepInfo (UINT*, UINT*) = 0;
virtual HRESULT STDMETHODCALLTYPE VolumeStepUp (LPCGUID) = 0;
virtual HRESULT STDMETHODCALLTYPE VolumeStepDown (LPCGUID) = 0;
virtual HRESULT STDMETHODCALLTYPE QueryHardwareSupport (DWORD*) = 0;
virtual HRESULT STDMETHODCALLTYPE GetVolumeRange (float*, float*, float*) = 0;
};
}
JUCE_COMCLASS (MMDeviceEnumerator, "BCDE0395-E52F-467C-8E3D-C4579291692E");
typedef LONGLONG REFERENCE_TIME;
enum AVRT_PRIORITY
{
AVRT_PRIORITY_LOW = -1,
AVRT_PRIORITY_NORMAL,
AVRT_PRIORITY_HIGH,
AVRT_PRIORITY_CRITICAL
};
enum AUDCLNT_SHAREMODE
{
AUDCLNT_SHAREMODE_SHARED,
AUDCLNT_SHAREMODE_EXCLUSIVE
};
JUCE_IUNKNOWNCLASS (IAudioClient, "1CB9AD4C-DBFA-4c32-B178-C2F568A703B2")
{
JUCE_COMCALL Initialize (AUDCLNT_SHAREMODE, DWORD, REFERENCE_TIME, REFERENCE_TIME, const WAVEFORMATEX*, LPCGUID) = 0;
JUCE_COMCALL GetBufferSize (UINT32*) = 0;
JUCE_COMCALL GetStreamLatency (REFERENCE_TIME*) = 0;
JUCE_COMCALL GetCurrentPadding (UINT32*) = 0;
JUCE_COMCALL IsFormatSupported (AUDCLNT_SHAREMODE, const WAVEFORMATEX*, WAVEFORMATEX**) = 0;
JUCE_COMCALL GetMixFormat (WAVEFORMATEX**) = 0;
JUCE_COMCALL GetDevicePeriod (REFERENCE_TIME*, REFERENCE_TIME*) = 0;
JUCE_COMCALL Start() = 0;
JUCE_COMCALL Stop() = 0;
JUCE_COMCALL Reset() = 0;
JUCE_COMCALL SetEventHandle (HANDLE) = 0;
JUCE_COMCALL GetService (REFIID, void**) = 0;
};
JUCE_IUNKNOWNCLASS (IAudioCaptureClient, "C8ADBD64-E71E-48a0-A4DE-185C395CD317")
{
JUCE_COMCALL GetBuffer (BYTE**, UINT32*, DWORD*, UINT64*, UINT64*) = 0;
JUCE_COMCALL ReleaseBuffer (UINT32) = 0;
JUCE_COMCALL GetNextPacketSize (UINT32*) = 0;
};
JUCE_IUNKNOWNCLASS (IAudioRenderClient, "F294ACFC-3146-4483-A7BF-ADDCA7C260E2")
{
JUCE_COMCALL GetBuffer (UINT32, BYTE**) = 0;
JUCE_COMCALL ReleaseBuffer (UINT32, DWORD) = 0;
};
JUCE_IUNKNOWNCLASS (IAudioEndpointVolume, "5CDF2C82-841E-4546-9722-0CF74078229A")
{
JUCE_COMCALL RegisterControlChangeNotify (void*) = 0;
JUCE_COMCALL UnregisterControlChangeNotify (void*) = 0;
JUCE_COMCALL GetChannelCount (UINT*) = 0;
JUCE_COMCALL SetMasterVolumeLevel (float, LPCGUID) = 0;
JUCE_COMCALL SetMasterVolumeLevelScalar (float, LPCGUID) = 0;
JUCE_COMCALL GetMasterVolumeLevel (float*) = 0;
JUCE_COMCALL GetMasterVolumeLevelScalar (float*) = 0;
JUCE_COMCALL SetChannelVolumeLevel (UINT, float, LPCGUID) = 0;
JUCE_COMCALL SetChannelVolumeLevelScalar (UINT, float, LPCGUID) = 0;
JUCE_COMCALL GetChannelVolumeLevel (UINT, float*) = 0;
JUCE_COMCALL GetChannelVolumeLevelScalar (UINT, float*) = 0;
JUCE_COMCALL SetMute (BOOL, LPCGUID) = 0;
JUCE_COMCALL GetMute (BOOL*) = 0;
JUCE_COMCALL GetVolumeStepInfo (UINT*, UINT*) = 0;
JUCE_COMCALL VolumeStepUp (LPCGUID) = 0;
JUCE_COMCALL VolumeStepDown (LPCGUID) = 0;
JUCE_COMCALL QueryHardwareSupport (DWORD*) = 0;
JUCE_COMCALL GetVolumeRange (float*, float*, float*) = 0;
};
enum AudioSessionDisconnectReason
{
DisconnectReasonDeviceRemoval = 0,
DisconnectReasonServerShutdown = 1,
DisconnectReasonFormatChanged = 2,
DisconnectReasonSessionLogoff = 3,
DisconnectReasonSessionDisconnected = 4,
DisconnectReasonExclusiveModeOverride = 5
};
enum AudioSessionState
{
AudioSessionStateInactive = 0,
AudioSessionStateActive = 1,
AudioSessionStateExpired = 2
};
JUCE_IUNKNOWNCLASS (IAudioSessionEvents, "24918ACC-64B3-37C1-8CA9-74A66E9957A8")
{
JUCE_COMCALL OnDisplayNameChanged (LPCWSTR, LPCGUID) = 0;
JUCE_COMCALL OnIconPathChanged (LPCWSTR, LPCGUID) = 0;
JUCE_COMCALL OnSimpleVolumeChanged (float, BOOL, LPCGUID) = 0;
JUCE_COMCALL OnChannelVolumeChanged (DWORD, float*, DWORD, LPCGUID) = 0;
JUCE_COMCALL OnGroupingParamChanged (LPCGUID, LPCGUID) = 0;
JUCE_COMCALL OnStateChanged (AudioSessionState) = 0;
JUCE_COMCALL OnSessionDisconnected (AudioSessionDisconnectReason) = 0;
};
JUCE_IUNKNOWNCLASS (IAudioSessionControl, "F4B1A599-7266-4319-A8CA-E70ACB11E8CD")
{
JUCE_COMCALL GetState (AudioSessionState*) = 0;
JUCE_COMCALL GetDisplayName (LPWSTR*) = 0;
JUCE_COMCALL SetDisplayName (LPCWSTR, LPCGUID) = 0;
JUCE_COMCALL GetIconPath (LPWSTR*) = 0;
JUCE_COMCALL SetIconPath (LPCWSTR, LPCGUID) = 0;
JUCE_COMCALL GetGroupingParam (GUID*) = 0;
JUCE_COMCALL SetGroupingParam (LPCGUID, LPCGUID) = 0;
JUCE_COMCALL RegisterAudioSessionNotification (IAudioSessionEvents*) = 0;
JUCE_COMCALL UnregisterAudioSessionNotification (IAudioSessionEvents*) = 0;
};
#undef JUCE_COMCALL
#undef JUCE_COMCLASS
#undef JUCE_IUNKNOWNCLASS
//==============================================================================
namespace WasapiClasses
{
String getDeviceID (IMMDevice* const device)
{
@@ -263,7 +388,7 @@ public:
}
}
~WASAPIDeviceBase()
virtual ~WASAPIDeviceBase()
{
device = nullptr;
CloseHandle (clientEvent);
@@ -345,7 +470,7 @@ private:
class SessionEventCallback : public ComBaseClassHelper <IAudioSessionEvents>
{
public:
SessionEventCallback (WASAPIDeviceBase& owner_) : owner (owner_) {}
SessionEventCallback (WASAPIDeviceBase& d) : owner (d) {}
JUCE_COMRESULT OnDisplayNameChanged (LPCWSTR, LPCGUID) { return S_OK; }
JUCE_COMRESULT OnIconPathChanged (LPCWSTR, LPCGUID) { return S_OK; }
@@ -411,7 +536,8 @@ private:
bool tryInitialisingWithFormat (const bool useFloat, const int bytesPerSampleToTry)
{
WAVEFORMATEXTENSIBLE format = { 0 };
WAVEFORMATEXTENSIBLE format;
zerostruct (format);
if (numChannels <= 2 && bytesPerSampleToTry <= 2)
{
@@ -462,7 +588,7 @@ private:
GUID session;
if (hr == S_OK
&& check (client->Initialize (useExclusiveMode ? AUDCLNT_SHAREMODE_EXCLUSIVE : AUDCLNT_SHAREMODE_SHARED,
AUDCLNT_STREAMFLAGS_EVENTCALLBACK,
0x40000 /*AUDCLNT_STREAMFLAGS_EVENTCALLBACK*/,
defaultPeriod, defaultPeriod, (WAVEFORMATEX*) &format, &session)))
{
actualNumChannels = format.Format.nChannels;
@@ -1264,7 +1390,11 @@ private:
continue;
PROPVARIANT value;
PropVariantInit (&value);
zerostruct (value);
const PROPERTYKEY PKEY_Device_FriendlyName
= { { 0xa45c254e, 0xdf1c, 0x4efd, { 0x80, 0x20, 0x67, 0xd1, 0x46, 0xa8, 0x50, 0xe0 } }, 14 };
if (check (properties->GetValue (PKEY_Device_FriendlyName, &value)))
name = value.pwszVal;


+ 1
- 1
modules/juce_core/juce_module_info View File

@@ -34,5 +34,5 @@
"OSXFrameworks": "Cocoa IOKit",
"iOSFrameworks": "Foundation",
"LinuxLibs": "rt dl pthread",
"mingwLibs": "uuid wsock32 wininet version ole32 ws2_32 oleaut32 imm32 comdlg32 shlwapi"
"mingwLibs": "uuid wsock32 wininet version ole32 ws2_32 oleaut32 imm32 comdlg32 shlwapi rpcrt4"
}

+ 11
- 0
modules/juce_core/native/juce_win32_ComSmartPtr.h View File

@@ -26,6 +26,17 @@
#ifndef __JUCE_WIN32_COMSMARTPTR_JUCEHEADER__
#define __JUCE_WIN32_COMSMARTPTR_JUCEHEADER__
#ifndef _MSC_VER
template<typename Type> struct UUIDGetter { static CLSID get() { jassertfalse; return CLSID(); } };
#define __uuidof(x) UUIDGetter<x>::get()
#endif
inline CLSID uuidFromString (const char* s) noexcept
{
CLSID c;
UuidFromStringA ((unsigned char*) s, &c);
return c;
}
//==============================================================================
/** A simple COM smart pointer.


Loading…
Cancel
Save