mirror of
https://github.com/fastfetch-cli/fastfetch.git
synced 2026-10-30 09:33:39 +01:00
e0eba8ce21
```bash find . -type f \( -name "*.c" -o -name "*.h" -o -name "*.cpp" -o -name "*.hpp" \) ! -path "src/3rdparty/*" -print0 | xargs -0 clang-format -i ```
109 lines
3.5 KiB
C++
109 lines
3.5 KiB
C++
extern "C" {
|
|
#include "sound.h"
|
|
}
|
|
#include "common/windows/unicode.hpp"
|
|
#include "common/windows/com.hpp"
|
|
#include "common/windows/variant.hpp"
|
|
|
|
#include <initguid.h>
|
|
#include <mmdeviceapi.h>
|
|
#include <endpointvolume.h>
|
|
#include <functiondiscoverykeys_devpkey.h>
|
|
|
|
static void ffCoTaskMemFreeWrapper(void* pptr) {
|
|
assert(pptr != NULL);
|
|
void* ptr = *(void**) pptr;
|
|
if (ptr) {
|
|
CoTaskMemFree(ptr);
|
|
}
|
|
}
|
|
#define FF_COTASK_AUTO_FREE __attribute__((__cleanup__(ffCoTaskMemFreeWrapper)))
|
|
|
|
const char* ffDetectSound(FFlist* devices /* List of FFSoundDevice */) {
|
|
const char* error = ffInitCom();
|
|
if (error) {
|
|
return error;
|
|
}
|
|
|
|
IMMDeviceEnumerator* FF_AUTO_RELEASE_COM_OBJECT pEnum = NULL;
|
|
|
|
if (FAILED(CoCreateInstance(CLSID_MMDeviceEnumerator, NULL, CLSCTX_ALL, IID_PPV_ARGS(&pEnum)))) {
|
|
return "CoCreateInstance(CLSID_MMDeviceEnumerator) failed";
|
|
}
|
|
|
|
LPWSTR FF_COTASK_AUTO_FREE mainDeviceId = NULL;
|
|
|
|
{
|
|
IMMDevice* FF_AUTO_RELEASE_COM_OBJECT pDefaultDevice = NULL;
|
|
|
|
if (FAILED(pEnum->GetDefaultAudioEndpoint(eRender, eMultimedia, &pDefaultDevice))) {
|
|
return "GetDefaultAudioEndpoint() failed";
|
|
}
|
|
|
|
if (FAILED(pDefaultDevice->GetId(&mainDeviceId))) {
|
|
return "pDefaultDevice->GetId() failed";
|
|
}
|
|
}
|
|
|
|
IMMDeviceCollection* FF_AUTO_RELEASE_COM_OBJECT pDevices = NULL;
|
|
|
|
if (FAILED(pEnum->EnumAudioEndpoints(eRender, DEVICE_STATE_ACTIVE | DEVICE_STATE_DISABLED, &pDevices))) {
|
|
return "EnumAudioEndpoints() failed";
|
|
}
|
|
|
|
uint32_t deviceCount;
|
|
if (FAILED(pDevices->GetCount(&deviceCount))) {
|
|
return "pDevices->GetCount() failed";
|
|
}
|
|
|
|
for (uint32_t deviceIdx = 0; deviceIdx < deviceCount; ++deviceIdx) {
|
|
IMMDevice* FF_AUTO_RELEASE_COM_OBJECT immDevice = NULL;
|
|
if (FAILED(pDevices->Item(deviceIdx, &immDevice))) {
|
|
continue;
|
|
}
|
|
|
|
LPWSTR FF_COTASK_AUTO_FREE immDeviceId = NULL;
|
|
if (FAILED(immDevice->GetId(&immDeviceId))) {
|
|
continue;
|
|
}
|
|
|
|
IPropertyStore* FF_AUTO_RELEASE_COM_OBJECT immPropStore;
|
|
if (FAILED(immDevice->OpenPropertyStore(STGM_READ, &immPropStore))) {
|
|
continue;
|
|
}
|
|
|
|
DWORD immState;
|
|
if (FAILED(immDevice->GetState(&immState))) {
|
|
continue;
|
|
}
|
|
|
|
FFSoundDevice* device = (FFSoundDevice*) ffListAdd(devices);
|
|
device->main = wcscmp(mainDeviceId, immDeviceId) == 0;
|
|
device->active = !!(immState & DEVICE_STATE_ACTIVE);
|
|
device->volume = FF_SOUND_VOLUME_UNKNOWN;
|
|
ffStrbufInitWS(&device->identifier, immDeviceId);
|
|
ffStrbufInit(&device->name);
|
|
ffStrbufInitStatic(&device->platformApi, "Core Audio APIs");
|
|
|
|
{
|
|
FFPropVariant friendlyName;
|
|
if (SUCCEEDED(immPropStore->GetValue(PKEY_Device_FriendlyName, &friendlyName))) {
|
|
ffStrbufSetWSV(&device->name, friendlyName.get<std::wstring_view>());
|
|
}
|
|
}
|
|
|
|
IAudioEndpointVolume* FF_AUTO_RELEASE_COM_OBJECT immEndpointVolume;
|
|
if (SUCCEEDED(immDevice->Activate(IID_IAudioEndpointVolume, CLSCTX_ALL, NULL, (void**) &immEndpointVolume))) {
|
|
BOOL muted;
|
|
if (FAILED(immEndpointVolume->GetMute(&muted)) || !muted) {
|
|
FLOAT volume;
|
|
if (SUCCEEDED(immEndpointVolume->GetMasterVolumeLevelScalar(&volume))) {
|
|
device->volume = (uint8_t) (volume * 100 + 0.5);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return NULL;
|
|
}
|