Skip to content

Instantly share code, notes, and snippets.

@im-tesla
Created July 1, 2024 23:48
Show Gist options
  • Select an option

  • Save im-tesla/b5a137c3cd1cdb7c4b8526561593b6dd to your computer and use it in GitHub Desktop.

Select an option

Save im-tesla/b5a137c3cd1cdb7c4b8526561593b6dd to your computer and use it in GitHub Desktop.
Windows Audio Control Utility
#include <stdio.h>
#include <windows.h>
#include <mmdeviceapi.h>
#include <endpointvolume.h>
#include <propvarutil.h>
#include <functiondiscoverykeys_devpkey.h>
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#pragma comment(lib, "Ole32.lib")
void initialize_com() {
CoInitialize(nullptr);
}
void cleanup_com() {
CoUninitialize();
}
std::vector<IMMDevice*> enumerate_audio_endpoints() {
IMMDeviceEnumerator* enumerator = nullptr;
CoCreateInstance(__uuidof(MMDeviceEnumerator), nullptr, CLSCTX_ALL, __uuidof(IMMDeviceEnumerator), (void**)&enumerator);
IMMDeviceCollection* device_collection = nullptr;
enumerator->EnumAudioEndpoints(eRender, DEVICE_STATE_ACTIVE, &device_collection);
UINT device_count = 0;
device_collection->GetCount(&device_count);
std::vector<IMMDevice*> devices(device_count);
for (UINT i = 0; i < device_count; ++i) {
device_collection->Item(i, &devices[i]);
}
device_collection->Release();
enumerator->Release();
return devices;
}
std::string get_device_name(IMMDevice* device) {
IPropertyStore* property_store = nullptr;
device->OpenPropertyStore(STGM_READ, &property_store);
PROPVARIANT device_name;
PropVariantInit(&device_name);
property_store->GetValue(PKEY_Device_FriendlyName, &device_name);
//jebac julke
std::wstring ws(device_name.pwszVal);
std::string name(ws.begin(), ws.end());
PropVariantClear(&device_name);
property_store->Release();
return name;
}
IAudioEndpointVolume* get_audio_endpoint_volume(IMMDevice* device) {
IAudioEndpointVolume* endpoint_volume = nullptr;
device->Activate(__uuidof(IAudioEndpointVolume), CLSCTX_ALL, nullptr, (void**)&endpoint_volume);
return endpoint_volume;
}
void set_channel_volume(IAudioEndpointVolume* endpoint_volume, UINT channel, float volume) {
endpoint_volume->SetChannelVolumeLevelScalar(channel, volume, nullptr);
}
float get_channel_volume(IAudioEndpointVolume* endpoint_volume, UINT channel) {
float volume = 0;
endpoint_volume->GetChannelVolumeLevelScalar(channel, &volume);
return volume;
}
void get_current_volume(IAudioEndpointVolume* endpoint_volume, float &volumeL, float &volumeR) {
volumeL = get_channel_volume(endpoint_volume, 0);
volumeR = get_channel_volume(endpoint_volume, 1);
}
int main(int argc, char* argv[]) {
initialize_com();
IAudioEndpointVolume* endpoint = nullptr;
auto devices = enumerate_audio_endpoints();
int deviceIndex = -1;
float volumeL = 0;
float volumeR = 0;
if (argc > 1) {
for (int i = 1; i < argc; ++i) {
std::string argument = argv[i];
if (argument.find("list") != std::string::npos) {
for (size_t i = 0; i < devices.size(); ++i) {
std::cout << i << ": " << get_device_name(devices[i]) << std::endl;
}
cleanup_com();
return 0;
}
if (argument.find("I") != std::string::npos) {
argument.erase(std::remove_if(argument.begin(), argument.end(), [](char c) { return !std::isdigit(c); }), argument.end());
deviceIndex = std::stoi(argument);
endpoint = get_audio_endpoint_volume(devices[deviceIndex]);
}
if (deviceIndex == -1) {
std::cout << "pick a device using I<index> argument\n\n" << std::endl;
cleanup_com();
return 0;
}
if (argument.find("L") != std::string::npos && argument.find("GR") == std::string::npos && argument.find("GL") == std::string::npos) {
argument.erase(std::remove_if(argument.begin(), argument.end(), [](char c) { return !std::isdigit(c); }), argument.end());
volumeL = std::stof(argument);
std::cout << "setting left to " << volumeL << std::endl;
set_channel_volume(endpoint, 0, volumeL / 100);
}
if (argument.find("R") != std::string::npos && argument.find("GR") == std::string::npos && argument.find("GL") == std::string::npos) {
argument.erase(std::remove_if(argument.begin(), argument.end(), [](char c) { return !std::isdigit(c); }), argument.end());
volumeR = std::stof(argument);
std::cout << "setting right to " << volumeR << std::endl;
set_channel_volume(endpoint, 1, volumeR / 100);
}
if (argument.find("GR") != std::string::npos) {
get_current_volume(endpoint, volumeL, volumeR);
std::cout << "current right volume is " << volumeR * 100 << std::endl;
}
if (argument.find("GL") != std::string::npos) {
get_current_volume(endpoint, volumeL, volumeR);
std::cout << "current left volume is " << volumeL * 100 << std::endl;
}
}
}
else {
std::cout << "n***a you gotta tell me what you wanna do" << std::endl;
system("pause");
cleanup_com();
return 0;
}
if (endpoint) {
endpoint->Release();
}
for (auto device : devices) {
device->Release();
}
cleanup_com();
return 0;
}
@im-tesla

im-tesla commented Jul 1, 2024

Copy link
Copy Markdown
Author

yeah thats really good quality code bro

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment