Compare commits
7 Commits
ecfb2f206d
...
1.0.3
| Author | SHA1 | Date | |
|---|---|---|---|
| eec9e25e12 | |||
| 3b4853acda | |||
| cea13986f0 | |||
| 3641ffdad9 | |||
| 7fa68792fb | |||
| ebdd35b1e1 | |||
| b986bfde39 |
@@ -1,7 +1,35 @@
|
|||||||
#include "ApplicationData.h"
|
#include "ApplicationData.h"
|
||||||
|
#include "Util.h"
|
||||||
|
#include "AudioApi.h"
|
||||||
|
#include <functiondiscoverykeys.h>
|
||||||
|
|
||||||
AudioDevice::AudioDevice()
|
AudioDevice::AudioDevice(IMMDevice* device, LPCWSTR deviceId)
|
||||||
{
|
{
|
||||||
|
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 (propertyStore)
|
||||||
|
{
|
||||||
|
propertyStore->Release();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
AudioDevice::AudioDevice(AudioDevice&& other) noexcept
|
AudioDevice::AudioDevice(AudioDevice&& other) noexcept
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ public:
|
|||||||
bool isDefaultMedia = {};
|
bool isDefaultMedia = {};
|
||||||
bool isDefaultCommunication = {};
|
bool isDefaultCommunication = {};
|
||||||
|
|
||||||
AudioDevice();
|
AudioDevice(IMMDevice* device, LPCWSTR deviceId);
|
||||||
AudioDevice(AudioDevice&& other) noexcept;
|
AudioDevice(AudioDevice&& other) noexcept;
|
||||||
AudioDevice& operator=(AudioDevice&& other) noexcept;
|
AudioDevice& operator=(AudioDevice&& other) noexcept;
|
||||||
~AudioDevice();
|
~AudioDevice();
|
||||||
|
|||||||
@@ -23,10 +23,9 @@
|
|||||||
#include "resource.h"
|
#include "resource.h"
|
||||||
#include "AsuroTool.h"
|
#include "AsuroTool.h"
|
||||||
|
|
||||||
class __declspec(uuid("3bc52579-15fd-43bb-9686-6273c238535e")) TrayGUID;
|
const size_t MAX_FONT_PATH_LENGTH = 2048;
|
||||||
|
const UINT TRAY_ID = 420;
|
||||||
UINT const WMAPP_NOTIFYCALLBACK = WM_APP + 1;
|
const UINT WMAPP_NOTIFYCALLBACK = WM_APP + 1;
|
||||||
UINT const WMAPP_HIDEFLYOUT = WM_APP + 2;
|
|
||||||
|
|
||||||
// Globals for use in callbacks
|
// Globals for use in callbacks
|
||||||
DrawData* gDrawData;
|
DrawData* gDrawData;
|
||||||
@@ -36,6 +35,13 @@ bool isHidden = false;
|
|||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
|
std::wstring appDir;
|
||||||
|
getAppDir(appDir);
|
||||||
|
if (_wchdir(appDir.c_str()) != 0)
|
||||||
|
{
|
||||||
|
std::cout << "Failed to set working dir." << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
ApplicationData applicationData{};
|
ApplicationData applicationData{};
|
||||||
ImGuiCallbacks callbacks{};
|
ImGuiCallbacks callbacks{};
|
||||||
|
|
||||||
@@ -48,20 +54,30 @@ int main()
|
|||||||
|
|
||||||
void init(DrawData& drawData, ApplicationData& appData)
|
void init(DrawData& drawData, ApplicationData& appData)
|
||||||
{
|
{
|
||||||
|
std::wstring appPath;
|
||||||
|
getAppDir(appPath);
|
||||||
|
char appPathStr[MAX_FONT_PATH_LENGTH];
|
||||||
|
HRESULT convResult = WideCharToMultiByte(CP_UTF8, NULL, &appPath[0], -1, appPathStr, MAX_FONT_PATH_LENGTH, NULL, nullptr);
|
||||||
|
isError(convResult, "Failed to convert path: ");
|
||||||
|
|
||||||
// sad :(
|
// sad :(
|
||||||
gDrawData = &drawData;
|
gDrawData = &drawData;
|
||||||
gAppData = &appData;
|
gAppData = &appData;
|
||||||
|
|
||||||
// Load text font
|
// Load text font
|
||||||
ImGuiIO& io = ImGui::GetIO();
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
io.Fonts->AddFontFromFileTTF("Montserrat-Regular.ttf", 18.0f);
|
std::string fontPath = std::string(appPathStr);
|
||||||
|
fontPath.append("\\Montserrat-Regular.ttf");
|
||||||
|
io.Fonts->AddFontFromFileTTF(fontPath.c_str(), 18.0f);
|
||||||
|
|
||||||
// Load icon font
|
// Load icon font
|
||||||
static const ImWchar icons_ranges[] = { 0xEA01, 0xF2DF, 0 };
|
static const ImWchar icons_ranges[] = { 0xEA01, 0xF2DF, 0 };
|
||||||
ImFontConfig icons_config;
|
ImFontConfig icons_config;
|
||||||
icons_config.MergeMode = true;
|
icons_config.MergeMode = true;
|
||||||
icons_config.PixelSnapH = true;
|
icons_config.PixelSnapH = true;
|
||||||
io.Fonts->AddFontFromFileTTF("remixicon.ttf", 14.0f, &icons_config, icons_ranges);
|
std::string iconFontPath = std::string(appPathStr);
|
||||||
|
iconFontPath.append("\\remixicon.ttf");
|
||||||
|
io.Fonts->AddFontFromFileTTF(iconFontPath.c_str(), 14.0f, &icons_config, icons_ranges);
|
||||||
|
|
||||||
// Set window icon
|
// Set window icon
|
||||||
HINSTANCE instance = GetModuleHandle(NULL);
|
HINSTANCE instance = GetModuleHandle(NULL);
|
||||||
@@ -75,8 +91,8 @@ void init(DrawData& drawData, ApplicationData& appData)
|
|||||||
// Set tray icon
|
// Set tray icon
|
||||||
NOTIFYICONDATA nid = { sizeof(nid) };
|
NOTIFYICONDATA nid = { sizeof(nid) };
|
||||||
nid.hWnd = drawData.window_handle;
|
nid.hWnd = drawData.window_handle;
|
||||||
nid.uFlags = NIF_ICON | NIF_TIP | NIF_MESSAGE | NIF_SHOWTIP | NIF_GUID;
|
nid.uFlags = NIF_ICON | NIF_TIP | NIF_MESSAGE | NIF_SHOWTIP;
|
||||||
nid.guidItem = __uuidof(TrayGUID);
|
nid.uID = TRAY_ID;
|
||||||
nid.uCallbackMessage = WMAPP_NOTIFYCALLBACK;
|
nid.uCallbackMessage = WMAPP_NOTIFYCALLBACK;
|
||||||
|
|
||||||
HRESULT iconResult;
|
HRESULT iconResult;
|
||||||
@@ -123,10 +139,6 @@ void draw(DrawData& drawData, ApplicationData& appData)
|
|||||||
{
|
{
|
||||||
justDocked = false;
|
justDocked = false;
|
||||||
|
|
||||||
// sad :(
|
|
||||||
gDrawData = &drawData;
|
|
||||||
gAppData = &appData;
|
|
||||||
|
|
||||||
// Actual Drawing
|
// Actual Drawing
|
||||||
if (isHidden)
|
if (isHidden)
|
||||||
{
|
{
|
||||||
@@ -167,9 +179,9 @@ void cleanup(DrawData& drawData, ApplicationData& appData)
|
|||||||
{
|
{
|
||||||
// Remove tray icon
|
// Remove tray icon
|
||||||
NOTIFYICONDATA nid = { sizeof(nid) };
|
NOTIFYICONDATA nid = { sizeof(nid) };
|
||||||
nid.uFlags = NIF_GUID;
|
nid.hWnd = drawData.window_handle;
|
||||||
nid.guidItem = __uuidof(TrayGUID);
|
nid.uID = TRAY_ID;
|
||||||
bool test = Shell_NotifyIcon(NIM_DELETE, &nid);
|
Shell_NotifyIcon(NIM_DELETE, &nid);
|
||||||
}
|
}
|
||||||
|
|
||||||
ImVec2 menuBar(DrawData& drawData, ApplicationData& appData)
|
ImVec2 menuBar(DrawData& drawData, ApplicationData& appData)
|
||||||
@@ -181,9 +193,7 @@ ImVec2 menuBar(DrawData& drawData, ApplicationData& appData)
|
|||||||
{
|
{
|
||||||
if (ImGui::BeginMenu("Settings"))
|
if (ImGui::BeginMenu("Settings"))
|
||||||
{
|
{
|
||||||
bool prevDocked = appData.settings.docked;
|
if (ImGui::Checkbox("Docked", &appData.settings.docked))
|
||||||
ImGui::Checkbox("Docked", &appData.settings.docked);
|
|
||||||
if (appData.settings.docked != prevDocked)
|
|
||||||
{
|
{
|
||||||
closeMenu = true;
|
closeMenu = true;
|
||||||
updateDocked(drawData, appData);
|
updateDocked(drawData, appData);
|
||||||
@@ -378,12 +388,13 @@ LRESULT CALLBACK trayIconEventHandler(int code, WPARAM wParam, LPARAM lParam)
|
|||||||
|
|
||||||
if (data->message == WMAPP_NOTIFYCALLBACK)
|
if (data->message == WMAPP_NOTIFYCALLBACK)
|
||||||
{
|
{
|
||||||
switch (data->lParam)
|
auto id = HIWORD(data->lParam);
|
||||||
|
auto trayEvent = LOWORD(data->lParam);
|
||||||
|
|
||||||
|
if (id == TRAY_ID && trayEvent == WM_LBUTTONUP)
|
||||||
{
|
{
|
||||||
case NIN_SELECT:
|
|
||||||
glfwShowWindow(gDrawData->window);
|
glfwShowWindow(gDrawData->window);
|
||||||
glfwRestoreWindow(gDrawData->window);
|
glfwRestoreWindow(gDrawData->window);
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -71,8 +71,8 @@ IDI_ICON1 ICON "kaiju.ico"
|
|||||||
//
|
//
|
||||||
|
|
||||||
VS_VERSION_INFO VERSIONINFO
|
VS_VERSION_INFO VERSIONINFO
|
||||||
FILEVERSION 1,0,0,1
|
FILEVERSION 1,0,3,1
|
||||||
PRODUCTVERSION 1,0,0,1
|
PRODUCTVERSION 1,0,3,1
|
||||||
FILEFLAGSMASK 0x3fL
|
FILEFLAGSMASK 0x3fL
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
FILEFLAGS 0x1L
|
FILEFLAGS 0x1L
|
||||||
@@ -89,12 +89,12 @@ BEGIN
|
|||||||
BEGIN
|
BEGIN
|
||||||
VALUE "CompanyName", "Asuro"
|
VALUE "CompanyName", "Asuro"
|
||||||
VALUE "FileDescription", "Audio Thingy"
|
VALUE "FileDescription", "Audio Thingy"
|
||||||
VALUE "FileVersion", "1.0.0.1"
|
VALUE "FileVersion", "1.0.3.1"
|
||||||
VALUE "InternalName", "AsuroTool.exe"
|
VALUE "InternalName", "AsuroTool.exe"
|
||||||
VALUE "LegalCopyright", "Copyright (C) 2022"
|
VALUE "LegalCopyright", "Copyright (C) 2022"
|
||||||
VALUE "OriginalFilename", "AsuroTool.exe"
|
VALUE "OriginalFilename", "AsuroTool.exe"
|
||||||
VALUE "ProductName", "Audio Thingy"
|
VALUE "ProductName", "Audio Thingy"
|
||||||
VALUE "ProductVersion", "1.0.0.1"
|
VALUE "ProductVersion", "1.0.3.1"
|
||||||
END
|
END
|
||||||
END
|
END
|
||||||
BLOCK "VarFileInfo"
|
BLOCK "VarFileInfo"
|
||||||
|
|||||||
@@ -97,6 +97,9 @@
|
|||||||
<Link>
|
<Link>
|
||||||
<SubSystem>Console</SubSystem>
|
<SubSystem>Console</SubSystem>
|
||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
<AdditionalDependencies>pathcch.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
|
<IgnoreSpecificDefaultLibraries>
|
||||||
|
</IgnoreSpecificDefaultLibraries>
|
||||||
</Link>
|
</Link>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
@@ -114,6 +117,9 @@
|
|||||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||||
<OptimizeReferences>true</OptimizeReferences>
|
<OptimizeReferences>true</OptimizeReferences>
|
||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
<AdditionalDependencies>pathcch.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
|
<IgnoreSpecificDefaultLibraries>
|
||||||
|
</IgnoreSpecificDefaultLibraries>
|
||||||
</Link>
|
</Link>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
@@ -127,6 +133,9 @@
|
|||||||
<Link>
|
<Link>
|
||||||
<SubSystem>Console</SubSystem>
|
<SubSystem>Console</SubSystem>
|
||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
<AdditionalDependencies>pathcch.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
|
<IgnoreSpecificDefaultLibraries>
|
||||||
|
</IgnoreSpecificDefaultLibraries>
|
||||||
</Link>
|
</Link>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
@@ -144,6 +153,9 @@
|
|||||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||||
<OptimizeReferences>true</OptimizeReferences>
|
<OptimizeReferences>true</OptimizeReferences>
|
||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
<AdditionalDependencies>pathcch.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
|
<IgnoreSpecificDefaultLibraries>
|
||||||
|
</IgnoreSpecificDefaultLibraries>
|
||||||
</Link>
|
</Link>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ void loadAudioDevices(AudioData& audioData, std::vector<AudioDevice>& deviceList
|
|||||||
deviceList.clear();
|
deviceList.clear();
|
||||||
|
|
||||||
HRESULT err;
|
HRESULT err;
|
||||||
IMMDeviceCollection* deviceCollection = NULL;
|
IMMDeviceCollection* deviceCollection = nullptr;
|
||||||
|
|
||||||
err = audioData.deviceEnumerator->EnumAudioEndpoints(deviceType, DEVICE_STATE_ACTIVE | DEVICE_STATE_DISABLED, &deviceCollection);
|
err = audioData.deviceEnumerator->EnumAudioEndpoints(deviceType, DEVICE_STATE_ACTIVE | DEVICE_STATE_DISABLED, &deviceCollection);
|
||||||
if (isError(err, "Failed to enumerate audio devices: ")) return;
|
if (isError(err, "Failed to enumerate audio devices: ")) return;
|
||||||
@@ -40,7 +40,7 @@ void loadAudioDevices(AudioData& audioData, std::vector<AudioDevice>& deviceList
|
|||||||
err = deviceCollection->GetCount(&deviceCount);
|
err = deviceCollection->GetCount(&deviceCount);
|
||||||
if (isError(err, "Failed to count audio devices: ")) return;
|
if (isError(err, "Failed to count audio devices: ")) return;
|
||||||
|
|
||||||
IMMDevice* defaultConsoleDevice = NULL;
|
IMMDevice* defaultConsoleDevice = nullptr;
|
||||||
LPWSTR defaultConsoleId = nullptr;
|
LPWSTR defaultConsoleId = nullptr;
|
||||||
err = audioData.deviceEnumerator->GetDefaultAudioEndpoint(deviceType, ERole::eConsole, &defaultConsoleDevice);
|
err = audioData.deviceEnumerator->GetDefaultAudioEndpoint(deviceType, ERole::eConsole, &defaultConsoleDevice);
|
||||||
if (!FAILED(err))
|
if (!FAILED(err))
|
||||||
@@ -48,7 +48,7 @@ void loadAudioDevices(AudioData& audioData, std::vector<AudioDevice>& deviceList
|
|||||||
defaultConsoleDevice->GetId(&defaultConsoleId);
|
defaultConsoleDevice->GetId(&defaultConsoleId);
|
||||||
}
|
}
|
||||||
|
|
||||||
IMMDevice* defaultMediaOutput = NULL;
|
IMMDevice* defaultMediaOutput = nullptr;
|
||||||
LPWSTR defaultMediaId = nullptr;
|
LPWSTR defaultMediaId = nullptr;
|
||||||
err = audioData.deviceEnumerator->GetDefaultAudioEndpoint(deviceType, ERole::eMultimedia, &defaultMediaOutput);
|
err = audioData.deviceEnumerator->GetDefaultAudioEndpoint(deviceType, ERole::eMultimedia, &defaultMediaOutput);
|
||||||
if (!FAILED(err))
|
if (!FAILED(err))
|
||||||
@@ -56,7 +56,7 @@ void loadAudioDevices(AudioData& audioData, std::vector<AudioDevice>& deviceList
|
|||||||
defaultMediaOutput->GetId(&defaultMediaId);
|
defaultMediaOutput->GetId(&defaultMediaId);
|
||||||
}
|
}
|
||||||
|
|
||||||
IMMDevice* defaultCommunicationOutput = NULL;
|
IMMDevice* defaultCommunicationOutput = nullptr;
|
||||||
LPWSTR defaultCommunicationId = nullptr;
|
LPWSTR defaultCommunicationId = nullptr;
|
||||||
err = audioData.deviceEnumerator->GetDefaultAudioEndpoint(deviceType, ERole::eCommunications, &defaultCommunicationOutput);
|
err = audioData.deviceEnumerator->GetDefaultAudioEndpoint(deviceType, ERole::eCommunications, &defaultCommunicationOutput);
|
||||||
if (!FAILED(err))
|
if (!FAILED(err))
|
||||||
@@ -66,57 +66,35 @@ void loadAudioDevices(AudioData& audioData, std::vector<AudioDevice>& deviceList
|
|||||||
|
|
||||||
for (UINT i = 0; i < deviceCount; i += 1)
|
for (UINT i = 0; i < deviceCount; i += 1)
|
||||||
{
|
{
|
||||||
AudioDevice deviceData{};
|
IMMDevice* device;
|
||||||
|
err = deviceCollection->Item(i, &device);
|
||||||
err = deviceCollection->Item(i, &deviceData.device);
|
|
||||||
if (isError(err, std::stringstream("Failed to get device ") << i << ": "))
|
if (isError(err, std::stringstream("Failed to get device ") << i << ": "))
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
LPWSTR deviceId;
|
LPWSTR deviceId;
|
||||||
err = deviceData.device->GetId(&deviceId);
|
err = device->GetId(&deviceId);
|
||||||
isError(err, std::stringstream("Failed to get device id ") << i << ": ");
|
if (!isError(err, std::stringstream("Failed to get device id ") << i << ": "))
|
||||||
deviceData.id = std::wstring(deviceId);
|
|
||||||
|
|
||||||
IPropertyStore* propertyStore;
|
|
||||||
err = deviceData.device->OpenPropertyStore(STGM_READ, &propertyStore);
|
|
||||||
isError(err, std::stringstream("Failed to open device ") << i << "prop store: ");
|
|
||||||
|
|
||||||
PROPVARIANT deviceNameProp;
|
|
||||||
const wchar_t* deviceName;
|
|
||||||
err = getDevicePropertyString(propertyStore, PKEY_Device_FriendlyName, &deviceNameProp, deviceName);
|
|
||||||
isError(err, std::stringstream("Failed to read name of device ") << i << ": ");
|
|
||||||
deviceData.name = utf8Encode(deviceName);
|
|
||||||
|
|
||||||
err = deviceData.device->GetState(&deviceData.state);
|
|
||||||
isError(err, std::stringstream("Failed to reat state of device ") << i << ": ");
|
|
||||||
|
|
||||||
err = deviceData.device->Activate(__uuidof(IAudioEndpointVolume), CLSCTX_INPROC_SERVER, NULL, (LPVOID*)&deviceData.volumeInterface);
|
|
||||||
isError(err, "Failed to get audio endpoint volume interface: ");
|
|
||||||
|
|
||||||
err = deviceData.device->Activate(__uuidof(IAudioMeterInformation), CLSCTX_INPROC_SERVER, NULL, (LPVOID*)&deviceData.meterInterface);
|
|
||||||
isError(err, "Failed to get audio meter interface: ");
|
|
||||||
|
|
||||||
if (defaultConsoleId)
|
|
||||||
{
|
{
|
||||||
deviceData.isDefaultConsole = wcscmp(defaultConsoleId, deviceId) == 0;
|
AudioDevice audioDevice(device, deviceId);
|
||||||
}
|
|
||||||
if (defaultMediaId)
|
if (defaultConsoleId)
|
||||||
{
|
{
|
||||||
deviceData.isDefaultMedia = wcscmp(defaultMediaId, deviceId) == 0;
|
audioDevice.isDefaultConsole = wcscmp(defaultConsoleId, deviceId) == 0;
|
||||||
}
|
}
|
||||||
if (defaultCommunicationId)
|
if (defaultMediaId)
|
||||||
{
|
{
|
||||||
deviceData.isDefaultCommunication = wcscmp(defaultCommunicationId, deviceId) == 0;
|
audioDevice.isDefaultMedia = wcscmp(defaultMediaId, deviceId) == 0;
|
||||||
|
}
|
||||||
|
if (defaultCommunicationId)
|
||||||
|
{
|
||||||
|
audioDevice.isDefaultCommunication = wcscmp(defaultCommunicationId, deviceId) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
deviceList.push_back(std::move(audioDevice));
|
||||||
}
|
}
|
||||||
|
|
||||||
deviceList.push_back(std::move(deviceData));
|
|
||||||
|
|
||||||
if (propertyStore)
|
|
||||||
{
|
|
||||||
propertyStore->Release();
|
|
||||||
}
|
|
||||||
CoTaskMemFree(deviceId);
|
CoTaskMemFree(deviceId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -150,7 +128,7 @@ HRESULT getDevicePropertyString(IPropertyStore* propertyStore, const PROPERTYKEY
|
|||||||
|
|
||||||
void setDefaultAudioDevice(AudioData& audioData, const wchar_t* deviceId, ERole role)
|
void setDefaultAudioDevice(AudioData& audioData, const wchar_t* deviceId, ERole role)
|
||||||
{
|
{
|
||||||
IPolicyConfigVista* pPolicyConfig;
|
IPolicyConfigVista* pPolicyConfig = nullptr;
|
||||||
|
|
||||||
HRESULT hr = CoCreateInstance(__uuidof(CPolicyConfigVistaClient), NULL, CLSCTX_ALL, __uuidof(IPolicyConfigVista), (LPVOID*)&pPolicyConfig);
|
HRESULT hr = CoCreateInstance(__uuidof(CPolicyConfigVistaClient), NULL, CLSCTX_ALL, __uuidof(IPolicyConfigVista), (LPVOID*)&pPolicyConfig);
|
||||||
if (!isError(hr, "Failed to set default audio device: "))
|
if (!isError(hr, "Failed to set default audio device: "))
|
||||||
|
|||||||
@@ -34,7 +34,25 @@ HRESULT __stdcall AudioNotificationListener::OnDeviceAdded(LPCWSTR pwstrDeviceId
|
|||||||
HRESULT result = audioData->deviceEnumerator->GetDevice(pwstrDeviceId, &newDevice);
|
HRESULT result = audioData->deviceEnumerator->GetDevice(pwstrDeviceId, &newDevice);
|
||||||
if (SUCCEEDED(result) && newDevice != nullptr)
|
if (SUCCEEDED(result) && newDevice != nullptr)
|
||||||
{
|
{
|
||||||
// TODO: add to device list
|
IMMEndpoint* endpoint;
|
||||||
|
result = newDevice->QueryInterface(&endpoint);
|
||||||
|
if (SUCCEEDED(result) && endpoint != nullptr)
|
||||||
|
{
|
||||||
|
EDataFlow dataFlow;
|
||||||
|
result = endpoint->GetDataFlow(&dataFlow);
|
||||||
|
if (SUCCEEDED(result))
|
||||||
|
{
|
||||||
|
AudioDevice audioDevice(newDevice, pwstrDeviceId);
|
||||||
|
if (dataFlow == EDataFlow::eCapture)
|
||||||
|
{
|
||||||
|
audioData->recordingDevices.push_back(std::move(audioDevice));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
audioData->playbackDevices.push_back(std::move(audioDevice));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
@@ -50,7 +68,9 @@ HRESULT __stdcall AudioNotificationListener::OnDeviceRemoved(LPCWSTR pwstrDevice
|
|||||||
if (wcscmp(deviceListIterator->id.c_str(), pwstrDeviceId) == 0)
|
if (wcscmp(deviceListIterator->id.c_str(), pwstrDeviceId) == 0)
|
||||||
{
|
{
|
||||||
deviceListIterator = deviceList.erase(deviceListIterator);
|
deviceListIterator = deviceList.erase(deviceListIterator);
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
deviceListIterator++;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -126,7 +146,7 @@ HRESULT __stdcall AudioNotificationListener::QueryInterface(REFIID riid, void**
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
*ppvObject = NULL;
|
*ppvObject = nullptr;
|
||||||
return E_NOINTERFACE;
|
return E_NOINTERFACE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -74,19 +74,16 @@ void setAutostart(bool newValue)
|
|||||||
|
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
|
||||||
HKEY runKey = NULL;
|
HKEY runKey = nullptr;
|
||||||
hr = RegCreateKey(HKEY_CURRENT_USER, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", &runKey);
|
hr = RegCreateKey(HKEY_CURRENT_USER, L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run", &runKey);
|
||||||
if (isError(hr, "Failed to find/create autostart run key: ")) return;
|
if (isError(hr, "Failed to find/create autostart run key: ")) return;
|
||||||
|
|
||||||
if (newValue)
|
if (newValue)
|
||||||
{
|
{
|
||||||
std::wstring appPath;
|
std::wstring appPath;
|
||||||
appPath.resize(MAX_PATH_LENGTH);
|
if (FAILED(getAppPath(appPath))) return;
|
||||||
hr = GetModuleFileName(NULL, &appPath[0], static_cast<DWORD>(appPath.size()));
|
|
||||||
if (isError(hr, "Failed to get executable name: ")) return;
|
|
||||||
appPath.resize(wcslen(appPath.data()));
|
|
||||||
|
|
||||||
hr = RegSetValueEx(runKey, KEY_APP_NAME, 0, REG_SZ, (BYTE*)appPath.c_str(), (appPath.size() + 1) * sizeof(wchar_t));
|
hr = RegSetValueEx(runKey, KEY_APP_NAME, 0, REG_SZ, (BYTE*)appPath.c_str(), static_cast<DWORD>((appPath.size() + 1) * sizeof(wchar_t)));
|
||||||
if (isError(hr, "Failed to write autostart key: ")) return;
|
if (isError(hr, "Failed to write autostart key: ")) return;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
#include "Util.h"
|
#include "Util.h"
|
||||||
|
#include "pathcch.h"
|
||||||
|
|
||||||
bool isError(const HRESULT result, const std::stringstream message)
|
bool isError(const HRESULT result, const std::stringstream message)
|
||||||
{
|
{
|
||||||
@@ -29,3 +30,24 @@ std::string utf8Encode(const std::wstring& wstr)
|
|||||||
WideCharToMultiByte(CP_UTF8, 0, wstr.c_str(), -1, &resultString[0], sizeNeeded, NULL, NULL);
|
WideCharToMultiByte(CP_UTF8, 0, wstr.c_str(), -1, &resultString[0], sizeNeeded, NULL, NULL);
|
||||||
return resultString;
|
return resultString;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
HRESULT getAppPath(std::wstring& outPath)
|
||||||
|
{
|
||||||
|
const size_t MAX_PATH_LENGTH = 32767;
|
||||||
|
outPath.resize(MAX_PATH_LENGTH);
|
||||||
|
HRESULT hr = GetModuleFileName(NULL, &outPath[0], static_cast<DWORD>(outPath.size()));
|
||||||
|
if (isError(hr, "Failed to get executable name: ")) return hr;
|
||||||
|
outPath.resize(wcslen(outPath.data()));
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT getAppDir(std::wstring& outPath)
|
||||||
|
{
|
||||||
|
HRESULT hr = getAppPath(outPath);
|
||||||
|
if (FAILED(hr)) return hr;
|
||||||
|
|
||||||
|
hr = PathCchRemoveFileSpec(&outPath[0], static_cast<DWORD>(outPath.size()));
|
||||||
|
if (isError(hr, "Failed to get executable dir: ")) return hr;
|
||||||
|
outPath.resize(wcslen(outPath.data()));
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
@@ -6,3 +6,5 @@
|
|||||||
bool isError(const HRESULT result, const std::stringstream message);
|
bool isError(const HRESULT result, const std::stringstream message);
|
||||||
bool isError(const HRESULT result, const char* message);
|
bool isError(const HRESULT result, const char* message);
|
||||||
std::string utf8Encode(const std::wstring& wstr);
|
std::string utf8Encode(const std::wstring& wstr);
|
||||||
|
HRESULT getAppPath(std::wstring& outPath);
|
||||||
|
HRESULT getAppDir(std::wstring& outPath);
|
||||||
|
|||||||
@@ -107,6 +107,8 @@
|
|||||||
<Lib>
|
<Lib>
|
||||||
<AdditionalLibraryDirectories>E:\Code\glfw-3.3.7.bin.WIN64\lib-vc2022;D:\Applications\VulkanSDK\1.2.182.0\Lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
<AdditionalLibraryDirectories>E:\Code\glfw-3.3.7.bin.WIN64\lib-vc2022;D:\Applications\VulkanSDK\1.2.182.0\Lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||||
<AdditionalDependencies>vulkan-1.lib;glfw3.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
<AdditionalDependencies>vulkan-1.lib;glfw3.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
|
<IgnoreSpecificDefaultLibraries>
|
||||||
|
</IgnoreSpecificDefaultLibraries>
|
||||||
</Lib>
|
</Lib>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
@@ -130,6 +132,8 @@
|
|||||||
<Lib>
|
<Lib>
|
||||||
<AdditionalLibraryDirectories>E:\Code\glfw-3.3.7.bin.WIN64\lib-vc2022;D:\Applications\VulkanSDK\1.2.182.0\Lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
<AdditionalLibraryDirectories>E:\Code\glfw-3.3.7.bin.WIN64\lib-vc2022;D:\Applications\VulkanSDK\1.2.182.0\Lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||||
<AdditionalDependencies>vulkan-1.lib;glfw3.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
<AdditionalDependencies>vulkan-1.lib;glfw3.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
|
<IgnoreSpecificDefaultLibraries>
|
||||||
|
</IgnoreSpecificDefaultLibraries>
|
||||||
</Lib>
|
</Lib>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
@@ -149,6 +153,8 @@
|
|||||||
<Lib>
|
<Lib>
|
||||||
<AdditionalLibraryDirectories>E:\Code\glfw-3.3.7.bin.WIN64\lib-vc2022;D:\Applications\VulkanSDK\1.2.182.0\Lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
<AdditionalLibraryDirectories>E:\Code\glfw-3.3.7.bin.WIN64\lib-vc2022;D:\Applications\VulkanSDK\1.2.182.0\Lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||||
<AdditionalDependencies>vulkan-1.lib;glfw3.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
<AdditionalDependencies>vulkan-1.lib;glfw3.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
|
<IgnoreSpecificDefaultLibraries>
|
||||||
|
</IgnoreSpecificDefaultLibraries>
|
||||||
</Lib>
|
</Lib>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
@@ -172,6 +178,8 @@
|
|||||||
<Lib>
|
<Lib>
|
||||||
<AdditionalLibraryDirectories>E:\Code\glfw-3.3.7.bin.WIN64\lib-vc2022;D:\Applications\VulkanSDK\1.2.182.0\Lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
<AdditionalLibraryDirectories>E:\Code\glfw-3.3.7.bin.WIN64\lib-vc2022;D:\Applications\VulkanSDK\1.2.182.0\Lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||||
<AdditionalDependencies>vulkan-1.lib;glfw3.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
<AdditionalDependencies>vulkan-1.lib;glfw3.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||||
|
<IgnoreSpecificDefaultLibraries>
|
||||||
|
</IgnoreSpecificDefaultLibraries>
|
||||||
</Lib>
|
</Lib>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|||||||
@@ -96,6 +96,8 @@
|
|||||||
<Link>
|
<Link>
|
||||||
<SubSystem>Console</SubSystem>
|
<SubSystem>Console</SubSystem>
|
||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
<IgnoreSpecificDefaultLibraries>
|
||||||
|
</IgnoreSpecificDefaultLibraries>
|
||||||
</Link>
|
</Link>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||||
@@ -112,6 +114,8 @@
|
|||||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||||
<OptimizeReferences>true</OptimizeReferences>
|
<OptimizeReferences>true</OptimizeReferences>
|
||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
<IgnoreSpecificDefaultLibraries>
|
||||||
|
</IgnoreSpecificDefaultLibraries>
|
||||||
</Link>
|
</Link>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||||
@@ -124,6 +128,8 @@
|
|||||||
<Link>
|
<Link>
|
||||||
<SubSystem>Console</SubSystem>
|
<SubSystem>Console</SubSystem>
|
||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
<IgnoreSpecificDefaultLibraries>
|
||||||
|
</IgnoreSpecificDefaultLibraries>
|
||||||
</Link>
|
</Link>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||||
@@ -140,6 +146,8 @@
|
|||||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||||
<OptimizeReferences>true</OptimizeReferences>
|
<OptimizeReferences>true</OptimizeReferences>
|
||||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||||
|
<IgnoreSpecificDefaultLibraries>
|
||||||
|
</IgnoreSpecificDefaultLibraries>
|
||||||
</Link>
|
</Link>
|
||||||
</ItemDefinitionGroup>
|
</ItemDefinitionGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|||||||
Reference in New Issue
Block a user