123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473 |
- #pragma once
- #include <AK/SoundEngine/Common/AkSoundEngine.h>
- #include <AK/Tools/Common/AkPlatformFuncs.h>
- #include <mmdeviceapi.h>
- namespace AK
- {
- namespace Win32
- {
- class DeviceProperty
- {
- public:
-
- DeviceProperty()
- {
- PropVariantInit(&variant);
- }
-
- DeviceProperty(const PROPERTYKEY &key, IPropertyStore* in_pProps)
- {
- PropVariantInit(&variant);
- if (in_pProps) in_pProps->GetValue(key, &variant);
- }
-
- DeviceProperty(DeviceProperty&& other)
- {
- variant = other.variant;
- PropVariantInit(&other.variant);
- }
-
- DeviceProperty(const DeviceProperty& other) = delete;
-
- ~DeviceProperty()
- {
- PropVariantClear(&variant);
- }
-
- DeviceProperty& operator=(DeviceProperty&& other)
- {
- PropVariantClear(&variant);
- variant = other.variant;
- PropVariantInit(&other.variant);
- return *this;
- }
-
- DeviceProperty& operator=(const DeviceProperty& other) = delete;
- bool IsEmpty() const { return variant.vt == VT_EMPTY; }
- PROPVARIANT variant;
- };
- class DeviceProperties
- {
- public:
-
- DeviceProperties()
- : pProps(nullptr)
- {
- }
-
- DeviceProperties(IMMDevice* in_pDevice)
- {
- in_pDevice->OpenPropertyStore(STGM_READ, &pProps);
- }
-
- DeviceProperties(DeviceProperties&& other)
- {
- pProps = other.pProps;
- other.pProps = nullptr;
- }
-
- DeviceProperties(const DeviceProperties& other) = delete;
-
- ~DeviceProperties()
- {
- if (pProps)
- {
- pProps->Release();
- pProps = nullptr;
- }
- }
-
- DeviceProperties& operator=(DeviceProperties&& other)
- {
- if (pProps)
- pProps->Release();
- pProps = other.pProps;
- other.pProps = nullptr;
- return *this;
- }
-
- DeviceProperties& operator=(const DeviceProperties& other) = delete;
- bool IsValid() { return pProps != nullptr; }
- DeviceProperty GetProperty(const PROPERTYKEY& key)
- {
- return DeviceProperty(key, pProps);
- }
- IPropertyStore* pProps;
- };
- class Device
- {
- public:
-
- Device()
- : pDevice(nullptr)
- , idDevice(AK_INVALID_DEVICE_ID)
- {
- }
-
- Device(Device&& other)
- : pDevice(nullptr)
- {
- SetDevice(other.pDevice);
- other.pDevice = nullptr;
- }
-
- Device(const Device& other)
- : pDevice(nullptr)
- {
- *this = other;
- }
-
- ~Device()
- {
- if (pDevice)
- {
- pDevice->Release();
- pDevice = nullptr;
- }
- }
-
- Device& operator=(Device&& other)
- {
- if (pDevice)
- {
- pDevice->Release();
- pDevice = nullptr;
- }
- pDevice = other.pDevice;
- idDevice = other.idDevice;
- other.pDevice = nullptr;
- return *this;
- }
-
- Device& operator=(const Device& other)
- {
- if (pDevice)
- {
- pDevice->Release();
- pDevice = nullptr;
- }
- pDevice = other.pDevice;
- if (pDevice)
- pDevice->AddRef();
- idDevice = other.idDevice;
- return *this;
- }
- Device& operator=(IMMDevice* pOther)
- {
- SetDevice(pOther);
- if (pDevice)
- pDevice->AddRef();
- return *this;
- }
- bool IsValid() const { return pDevice != nullptr; }
- AkUInt32 GetDeviceID() const
- {
- return pDevice ? idDevice : AK_INVALID_DEVICE_ID;
- }
- DeviceProperties GetProperties() const
- {
- return DeviceProperties(pDevice);
- }
- void ComputeId()
- {
- idDevice = AK_INVALID_DEVICE_ID;
- if (pDevice)
- {
-
- LPWSTR pwszID = NULL;
- if (pDevice->GetId(&pwszID) == S_OK)
- {
- char szString[260];
- AKPLATFORM::AkWideCharToChar(pwszID, 260 - 1, szString);
- szString[260 - 1] = 0;
- idDevice = FNVHash32::ComputeLowerCase((const char*)szString);
- CoTaskMemFree(pwszID);
- }
- }
- }
- void SetDevice(IMMDevice* in_pNew)
- {
- if (pDevice)
- pDevice->Release();
- pDevice = in_pNew;
- ComputeId();
- }
- interface IMMDevice* pDevice;
- AkUInt32 idDevice;
- };
- class DeviceCollection
- {
- public:
- class Iterator
- {
- public:
- Iterator(IMMDeviceCollection* in_pDevices, UINT in_i)
- : pDevices(in_pDevices)
- , i(in_i)
- {
- }
-
- Iterator operator+(AkUInt32 inc) const
- {
- Iterator returnedIt(pDevices, i + inc);
- return returnedIt;
- }
-
- AkUInt32 operator-(Iterator const& rhs) const
- {
- return (AkUInt32)(i - rhs.i);
- }
-
- Iterator& operator++()
- {
- ++i;
- return *this;
- }
-
- Iterator& operator--()
- {
- --i;
- return *this;
- }
-
- bool operator ==(const Iterator& in_rOp) const
- {
- return (pDevices == in_rOp.pDevices && i == in_rOp.i);
- }
-
- bool operator !=(const Iterator& in_rOp) const
- {
- return (pDevices != in_rOp.pDevices || i != in_rOp.i);
- }
-
- Device GetDevice()
- {
- Device pDevice;
- pDevices->Item(i, (IMMDevice**)&pDevice.pDevice);
- if (pDevice.pDevice)
- pDevice.ComputeId();
- return pDevice;
- }
- interface IMMDeviceCollection* pDevices;
- UINT i;
- };
- DeviceCollection(IMMDeviceEnumerator* pEnumerator)
- : pDevices(nullptr)
- , uCount(0)
- {
- pEnumerator->EnumAudioEndpoints(eRender, DEVICE_STATEMASK_ALL, &pDevices);
- if (pDevices)
- pDevices->GetCount(&uCount);
- }
- DeviceCollection(IMMDeviceEnumerator* pEnumerator, EDataFlow eFlow, DWORD dwStateMask)
- : pDevices(nullptr)
- , uCount(0)
- {
- pEnumerator->EnumAudioEndpoints(eFlow, dwStateMask, &pDevices);
- if (pDevices)
- pDevices->GetCount(&uCount);
- }
-
- DeviceCollection(DeviceCollection&& other)
- {
- pDevices = other.pDevices;
- uCount = other.uCount;
- other.pDevices = nullptr;
- other.uCount = 0;
- }
-
- DeviceCollection(const DeviceCollection& other) = delete;
-
- ~DeviceCollection()
- {
- if (pDevices)
- {
- pDevices->Release();
- pDevices = nullptr;
- }
- }
-
- DeviceCollection& operator=(DeviceCollection&& other)
- {
- if (pDevices)
- {
- pDevices->Release();
- }
- pDevices = other.pDevices;
- uCount = other.uCount;
- other.pDevices = nullptr;
- other.uCount = 0;
- return *this;
- }
-
- DeviceCollection& operator=(const DeviceCollection& other) = delete;
- bool IsValid() const { return pDevices != nullptr; }
- UINT Count() const
- {
- return uCount;
- }
- Iterator Begin()
- {
- Iterator it(pDevices, 0);
- return it;
- }
- Iterator End()
- {
- Iterator it(pDevices, uCount);
- return it;
- }
- interface IMMDeviceCollection* pDevices;
- UINT uCount;
- };
- class DeviceEnumerator
- {
- public:
- DeviceEnumerator()
- : pEnumerator(nullptr)
- {
- CoCreateInstance(
- __uuidof(MMDeviceEnumerator), NULL,
- CLSCTX_ALL, __uuidof(IMMDeviceEnumerator),
- (void**)&pEnumerator);
- }
-
- DeviceEnumerator(DeviceEnumerator&& other)
- {
- pEnumerator = other.pEnumerator;
- other.pEnumerator = nullptr;
- }
-
- DeviceEnumerator(const DeviceEnumerator& other) = delete;
-
- ~DeviceEnumerator()
- {
- if (pEnumerator)
- {
- pEnumerator->Release();
- pEnumerator = nullptr;
- }
- }
-
- DeviceEnumerator& operator=(DeviceEnumerator&& other)
- {
- if (pEnumerator)
- {
- pEnumerator->Release();
- }
- pEnumerator = other.pEnumerator;
- other.pEnumerator = nullptr;
- return *this;
- }
-
- DeviceEnumerator& operator=(const DeviceEnumerator& other) = delete;
- bool IsValid() { return pEnumerator != nullptr; }
- Device GetDefaultDevice(ERole in_eRole)
- {
- Device pDevice;
- pEnumerator->GetDefaultAudioEndpoint(eRender, in_eRole, (IMMDevice**)&pDevice.pDevice);
- if (pDevice.pDevice)
- pDevice.ComputeId();
- return pDevice;
- }
- interface IMMDeviceEnumerator* pEnumerator;
- };
-
- class IAkDeviceEnumerator
- {
- public:
- virtual AkUInt32 Count() = 0;
- virtual Device Item(AkUInt32 in_idx) = 0;
- virtual void Lock() = 0;
- virtual void Unlock() = 0;
- virtual Device FindDevice(AkUInt32 in_id) = 0;
- };
- }
- };
|