Compare commits

...

2 Commits

Author SHA1 Message Date
5f5e24fa9c 1.0.4 2022-07-26 18:08:13 +02:00
cdffa1b50b per channel peak meters 2022-07-26 18:07:57 +02:00
6 changed files with 53 additions and 27 deletions

View File

@@ -26,6 +26,8 @@ AudioDevice::AudioDevice(IMMDevice* device, LPCWSTR deviceId)
err = device->Activate(__uuidof(IAudioMeterInformation), CLSCTX_INPROC_SERVER, NULL, (LPVOID*)&meterInterface); err = device->Activate(__uuidof(IAudioMeterInformation), CLSCTX_INPROC_SERVER, NULL, (LPVOID*)&meterInterface);
isError(err, "Failed to get audio meter interface: "); isError(err, "Failed to get audio meter interface: ");
getVolumeLimit(volumeInterface, &minVolumeDb, &maxVolumeDb);
if (propertyStore) if (propertyStore)
{ {
propertyStore->Release(); propertyStore->Release();
@@ -35,7 +37,8 @@ AudioDevice::AudioDevice(IMMDevice* device, LPCWSTR deviceId)
AudioDevice::AudioDevice(AudioDevice&& other) noexcept AudioDevice::AudioDevice(AudioDevice&& other) noexcept
: device(other.device), volumeInterface(other.volumeInterface), meterInterface(other.meterInterface), : device(other.device), volumeInterface(other.volumeInterface), meterInterface(other.meterInterface),
id(other.id), name(other.name), state(other.state), id(other.id), name(other.name), state(other.state),
isDefaultConsole(other.isDefaultConsole), isDefaultMedia(other.isDefaultMedia), isDefaultCommunication(other.isDefaultCommunication) isDefaultConsole(other.isDefaultConsole), isDefaultMedia(other.isDefaultMedia), isDefaultCommunication(other.isDefaultCommunication),
minVolumeDb(other.minVolumeDb), maxVolumeDb(other.maxVolumeDb)
{ {
other.device = nullptr; other.device = nullptr;
other.volumeInterface = nullptr; other.volumeInterface = nullptr;
@@ -53,6 +56,8 @@ AudioDevice& AudioDevice::operator=(AudioDevice&& other) noexcept
this->isDefaultConsole = other.isDefaultConsole; this->isDefaultConsole = other.isDefaultConsole;
this->isDefaultMedia = other.isDefaultMedia; this->isDefaultMedia = other.isDefaultMedia;
this->isDefaultCommunication = other.isDefaultCommunication; this->isDefaultCommunication = other.isDefaultCommunication;
this->minVolumeDb = other.minVolumeDb;
this->maxVolumeDb = other.maxVolumeDb;
other.device = nullptr; other.device = nullptr;
other.volumeInterface = nullptr; other.volumeInterface = nullptr;

View File

@@ -14,9 +14,11 @@ public:
std::wstring id = {}; std::wstring id = {};
std::string name = {}; std::string name = {};
unsigned long state = {}; unsigned long state = {};
bool isDefaultConsole = {}; bool isDefaultConsole = false;
bool isDefaultMedia = {}; bool isDefaultMedia = false;
bool isDefaultCommunication = {}; bool isDefaultCommunication = false;
float minVolumeDb = 0.f;
float maxVolumeDb = 0.f;
AudioDevice(IMMDevice* device, LPCWSTR deviceId); AudioDevice(IMMDevice* device, LPCWSTR deviceId);
AudioDevice(AudioDevice&& other) noexcept; AudioDevice(AudioDevice&& other) noexcept;

View File

@@ -10,6 +10,7 @@
#include <windows.h> #include <windows.h>
#include <array>
#include <functional> #include <functional>
#include <iostream> #include <iostream>
#include <sstream> #include <sstream>
@@ -304,8 +305,8 @@ ImVec2 audioDeviceWindow(ApplicationData& appData, std::vector<AudioDevice>& dev
ImGui::TableNextColumn(); ImGui::TableNextColumn();
if (dev.state == DEVICE_STATE_ACTIVE) if (dev.state == DEVICE_STATE_ACTIVE)
{ {
// Log scale because it looks better (no actual reason for these exact numbers) static std::array<float, 2> meterValues{};
float meterValue = log10f(getMeterValue(dev.meterInterface) * 9. + 1.); UINT channelCount = getMeterValues(dev.meterInterface, meterValues);
auto drawList = ImGui::GetWindowDrawList(); auto drawList = ImGui::GetWindowDrawList();
ImVec2 windowPos = ImGui::GetWindowPos(); ImVec2 windowPos = ImGui::GetWindowPos();
@@ -316,21 +317,32 @@ ImVec2 audioDeviceWindow(ApplicationData& appData, std::vector<AudioDevice>& dev
const float linePaddingX = 3.; const float linePaddingX = 3.;
cursorPos.x += linePaddingX; cursorPos.x += linePaddingX;
// BG line
drawList->AddLine(ImVec2(cursorPos.x, lineY), ImVec2(cursorPos.x + (space.x - 2. * linePaddingX), lineY), IM_COL32(120, 120, 120, 255), 2.); drawList->AddLine(ImVec2(cursorPos.x, lineY), ImVec2(cursorPos.x + (space.x - 2. * linePaddingX), lineY), IM_COL32(120, 120, 120, 255), 2.);
drawList->AddLine(ImVec2(cursorPos.x, lineY), ImVec2(cursorPos.x + (space.x - 2. * linePaddingX) * meterValue, lineY), IM_COL32(200, 200, 255, 255), 3.);
// Channel lines
if (channelCount == 1)
{
drawList->AddLine(ImVec2(cursorPos.x, lineY), ImVec2(cursorPos.x + (space.x - 2. * linePaddingX) * meterValues[0], lineY), IM_COL32(200, 200, 255, 255), 3.);
}
if (channelCount == 2)
{
drawList->AddLine(ImVec2(cursorPos.x, lineY - 2), ImVec2(cursorPos.x + (space.x - 2. * linePaddingX) * meterValues[0], lineY - 2), IM_COL32(200, 200, 255, 255), 3.);
drawList->AddLine(ImVec2(cursorPos.x, lineY + 2), ImVec2(cursorPos.x + (space.x - 2. * linePaddingX) * meterValues[1], lineY + 2), IM_COL32(200, 200, 255, 255), 3.);
}
ImGui::SetNextItemWidth(space.x);
ImGui::PushID(&dev.id);
ImGui::PushStyleColor(ImGuiCol_FrameBg, ImVec4(0, 0, 0, 0));
float volume = getVolume(dev.volumeInterface); float volume = getVolume(dev.volumeInterface);
float prevVolume = volume; if (ImGui::SliderFloat("", &volume, 0., 1., "", ImGuiSliderFlags_NoRoundToFormat | ImGuiSliderFlags_AlwaysClamp))
ImGui::SetNextItemWidth(space.x);
ImGui::PushID(dev.device);
ImGui::PushStyleColor(ImGuiCol_FrameBg, ImVec4(0, 0, 0, 0));
ImGui::SliderFloat("", &volume, 0., 1., "", ImGuiSliderFlags_NoRoundToFormat | ImGuiSliderFlags_AlwaysClamp);
ImGui::PopStyleColor();
ImGui::PopID();
if (prevVolume != volume)
{ {
setVolume(dev.volumeInterface, volume); setVolume(dev.volumeInterface, volume);
} }
ImGui::PopStyleColor();
ImGui::PopID();
} }
// Defaults // Defaults

View File

@@ -71,8 +71,8 @@ IDI_ICON1 ICON "kaiju.ico"
// //
VS_VERSION_INFO VERSIONINFO VS_VERSION_INFO VERSIONINFO
FILEVERSION 1,0,3,1 FILEVERSION 1,0,4,1
PRODUCTVERSION 1,0,3,1 PRODUCTVERSION 1,0,4,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.3.1" VALUE "FileVersion", "1.0.4.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.3.1" VALUE "ProductVersion", "1.0.4.1"
END END
END END
BLOCK "VarFileInfo" BLOCK "VarFileInfo"

View File

@@ -3,6 +3,7 @@
#include <functiondiscoverykeys.h> #include <functiondiscoverykeys.h>
#include <endpointvolume.h> #include <endpointvolume.h>
#include <array>
#include <vector> #include <vector>
#include <algorithm> #include <algorithm>
@@ -156,13 +157,18 @@ void setVolume(IAudioEndpointVolume* volumeInterface, float newVolume)
isError(hr, "Failed to set volume level: "); isError(hr, "Failed to set volume level: ");
} }
float getMeterValue(IAudioMeterInformation* meterInterface) UINT getMeterValues(IAudioMeterInformation* meterInterface, std::array<float, 2>& outLevels)
{ {
float volume; UINT channelCount;
if (FAILED(meterInterface->GetPeakValue(&volume))) if (FAILED(meterInterface->GetMeteringChannelCount(&channelCount)) || channelCount > 2) return 0;
{
volume = 0.; if (FAILED(meterInterface->GetChannelsPeakValues(channelCount, &outLevels[0]))) return 0;
return channelCount;
} }
return volume; void getVolumeLimit(IAudioEndpointVolume* volumeInterface, float* outMin, float* outMax)
{
float dummy;
volumeInterface->GetVolumeRange(outMin, outMax, &dummy);
} }

View File

@@ -14,4 +14,5 @@ void setDefaultAudioDevice(AudioData& audioData, const wchar_t* deviceId, ERole
float getVolume(IAudioEndpointVolume* volumeInterface); float getVolume(IAudioEndpointVolume* volumeInterface);
void setVolume(IAudioEndpointVolume* volumeInterface, float newVolume); void setVolume(IAudioEndpointVolume* volumeInterface, float newVolume);
float getMeterValue(IAudioMeterInformation* meterInterface); UINT getMeterValues(IAudioMeterInformation* meterInterface, std::array<float, 2>& levels);
void getVolumeLimit(IAudioEndpointVolume* volumeInterface, float* outMin, float* outMax);