128 lines
3.5 KiB
C++
128 lines
3.5 KiB
C++
#include "ApplicationData.h"
|
|
#include "Util.h"
|
|
#include "AudioApi.h"
|
|
#include <functiondiscoverykeys.h>
|
|
|
|
AudioDevice::AudioDevice(IMMDevice* device, LPCWSTR deviceId) : device(device)
|
|
{
|
|
id = std::wstring(deviceId);
|
|
|
|
IPropertyStore* propertyStore;
|
|
HRESULT err = device->OpenPropertyStore(STGM_READ, &propertyStore);
|
|
isError(err, "Failed to open prop store: ");
|
|
|
|
PROPVARIANT deviceNameProp;
|
|
const wchar_t* deviceName;
|
|
err = getDevicePropertyString(propertyStore, PKEY_Device_FriendlyName, &deviceNameProp, deviceName);
|
|
isError(err, "Failed to read name of device :");
|
|
name = utf8Encode(deviceName);
|
|
|
|
err = device->GetState(&state);
|
|
isError(err, "Failed to reat state of device: ");
|
|
|
|
err = device->Activate(__uuidof(IAudioEndpointVolume), CLSCTX_INPROC_SERVER, NULL, (LPVOID*)&volumeInterface);
|
|
isError(err, "Failed to get audio endpoint volume interface: ");
|
|
|
|
err = device->Activate(__uuidof(IAudioMeterInformation), CLSCTX_INPROC_SERVER, NULL, (LPVOID*)&meterInterface);
|
|
isError(err, "Failed to get audio meter interface: ");
|
|
|
|
if (volumeInterface != nullptr && meterInterface != nullptr)
|
|
{
|
|
getVolumeLimit(volumeInterface, &minVolumeDb, &maxVolumeDb);
|
|
isInitialized = true;
|
|
}
|
|
|
|
if (propertyStore)
|
|
{
|
|
propertyStore->Release();
|
|
}
|
|
}
|
|
|
|
AudioDevice::AudioDevice(AudioDevice&& other) noexcept
|
|
: device(other.device), volumeInterface(other.volumeInterface), meterInterface(other.meterInterface),
|
|
id(other.id), name(other.name), state(other.state),
|
|
isDefaultConsole(other.isDefaultConsole), isDefaultMedia(other.isDefaultMedia), isDefaultCommunication(other.isDefaultCommunication),
|
|
minVolumeDb(other.minVolumeDb), maxVolumeDb(other.maxVolumeDb)
|
|
{
|
|
other.device = nullptr;
|
|
other.volumeInterface = nullptr;
|
|
other.meterInterface = nullptr;
|
|
}
|
|
|
|
AudioDevice& AudioDevice::operator=(AudioDevice&& other) noexcept
|
|
{
|
|
this->device = other.device;
|
|
this->volumeInterface = other.volumeInterface;
|
|
this->meterInterface = other.meterInterface;
|
|
this->id = other.id;
|
|
this->name = other.name;
|
|
this->state = other.state;
|
|
this->isDefaultConsole = other.isDefaultConsole;
|
|
this->isDefaultMedia = other.isDefaultMedia;
|
|
this->isDefaultCommunication = other.isDefaultCommunication;
|
|
this->minVolumeDb = other.minVolumeDb;
|
|
this->maxVolumeDb = other.maxVolumeDb;
|
|
|
|
other.device = nullptr;
|
|
other.volumeInterface = nullptr;
|
|
other.meterInterface = nullptr;
|
|
return *this;
|
|
}
|
|
|
|
AudioDevice::~AudioDevice()
|
|
{
|
|
if (volumeInterface)
|
|
{
|
|
volumeInterface->Release();
|
|
volumeInterface = nullptr;
|
|
}
|
|
if (meterInterface)
|
|
{
|
|
meterInterface->Release();
|
|
meterInterface = nullptr;
|
|
}
|
|
if (device)
|
|
{
|
|
device->Release();
|
|
device = nullptr;
|
|
}
|
|
}
|
|
|
|
AudioData::AudioData()
|
|
{
|
|
}
|
|
|
|
AudioData::AudioData(AudioData&& other) noexcept
|
|
: playbackDevices(std::move(other.playbackDevices)), recordingDevices(std::move(other.recordingDevices)),
|
|
deviceEnumerator(other.deviceEnumerator), audioNotificationListener(other.audioNotificationListener)
|
|
{
|
|
other.deviceEnumerator = nullptr;
|
|
other.audioNotificationListener = nullptr;
|
|
}
|
|
|
|
AudioData& AudioData::operator=(AudioData&& other) noexcept
|
|
{
|
|
playbackDevices = std::move(other.playbackDevices);
|
|
recordingDevices = std::move(other.recordingDevices);
|
|
deviceEnumerator = other.deviceEnumerator;
|
|
audioNotificationListener = other.audioNotificationListener;
|
|
|
|
other.deviceEnumerator = nullptr;
|
|
other.audioNotificationListener = nullptr;
|
|
return *this;
|
|
}
|
|
|
|
AudioData::~AudioData()
|
|
{
|
|
if (deviceEnumerator)
|
|
{
|
|
deviceEnumerator->Release();
|
|
deviceEnumerator = nullptr;
|
|
}
|
|
if (audioNotificationListener)
|
|
{
|
|
audioNotificationListener->Release();
|
|
audioNotificationListener = nullptr;
|
|
}
|
|
}
|