From d4a7ae8b34f01e69bfa5b29e047f4016bc7d72b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Fri, 26 May 2023 15:18:59 +0800 Subject: [PATCH] Sound (macOS): detecting volume more aggressively --- CHANGELOG.md | 1 + src/detection/sound/sound.h | 2 ++ src/detection/sound/sound_apple.c | 30 ++++++++++++++++++++++++++- src/detection/sound/sound_windows.cpp | 2 +- src/modules/sound.c | 11 ++++++---- 5 files changed, 40 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a8833af54..f924471e1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ Bugfixes: * Fix flatpak package count (#441) * Don't print white color blocks with `--pipe` (#450) * Fix iTerm being detected as iTermServer-* sometimes +* Fix sound device volume being incorrectly detected as muted sometimes (Sound) Logo: * Update Windows 11 ASCII logo to look more visually consistent (#445) diff --git a/src/detection/sound/sound.h b/src/detection/sound/sound.h index 9a89ab694..7603110f6 100644 --- a/src/detection/sound/sound.h +++ b/src/detection/sound/sound.h @@ -5,6 +5,8 @@ #include "fastfetch.h" +#define FF_SOUND_VOLUME_UNKNOWN 255 + typedef struct FFSoundDevice { FFstrbuf identifier; diff --git a/src/detection/sound/sound_apple.c b/src/detection/sound/sound_apple.c index e34920969..862ee523a 100644 --- a/src/detection/sound/sound_apple.c +++ b/src/detection/sound/sound_apple.c @@ -44,7 +44,7 @@ const char* ffDetectSound(FF_MAYBE_UNUSED const FFinstance* instance, FFlist* de FFSoundDevice* device = (FFSoundDevice*) ffListAdd(devices); device->main = deviceId == mainDeviceId; device->active = false; - device->volume = 0; + device->volume = FF_SOUND_VOLUME_UNKNOWN; ffStrbufInitF(&device->identifier, "%u", (unsigned) deviceId); ffStrbufInit(&device->name); @@ -67,6 +67,34 @@ const char* ffDetectSound(FF_MAYBE_UNUSED const FFinstance* instance, FFlist* de kAudioObjectPropertyElementMain }, 0, NULL, &dataSize, &volume) == kAudioHardwareNoError) device->volume = (uint8_t) (volume * 100 + 0.5); + else + { + // Try detecting volume from channels + uint32_t channels[2]; + dataSize = sizeof(channels); + if (AudioObjectGetPropertyData(deviceId, &(AudioObjectPropertyAddress){ + kAudioDevicePropertyPreferredChannelsForStereo, + kAudioObjectPropertyScopeOutput, + kAudioObjectPropertyElementMain + }, 0, NULL, &dataSize, channels) == kAudioHardwareNoError) + { + dataSize = sizeof(volume); + if (AudioObjectGetPropertyData(deviceId, &(AudioObjectPropertyAddress){ + kAudioDevicePropertyVolumeScalar, + kAudioObjectPropertyScopeOutput, + channels[0] + }, 0, NULL, &dataSize, &volume) == kAudioHardwareNoError) + { + float temp; + if (AudioObjectGetPropertyData(deviceId, &(AudioObjectPropertyAddress){ + kAudioDevicePropertyVolumeScalar, + kAudioObjectPropertyScopeOutput, + channels[1] + }, 0, NULL, &dataSize, &temp) == kAudioHardwareNoError) + device->volume = (uint8_t) ((volume + temp) / 2 * 100 + 0.5); + } + } + } } CFStringRef name; diff --git a/src/detection/sound/sound_windows.cpp b/src/detection/sound/sound_windows.cpp index 5221c8368..7f4f4aac4 100644 --- a/src/detection/sound/sound_windows.cpp +++ b/src/detection/sound/sound_windows.cpp @@ -62,7 +62,7 @@ const char* ffDetectSound(FF_MAYBE_UNUSED const FFinstance* instance, FF_MAYBE_U FFSoundDevice* device = (FFSoundDevice*) ffListAdd(devices); device->main = wcscmp(mainDeviceId, immDeviceId) == 0; device->active = !!(immState & DEVICE_STATE_ACTIVE); - device->volume = 0; + device->volume = FF_SOUND_VOLUME_UNKNOWN; ffStrbufInit(&device->identifier); ffStrbufInit(&device->name); diff --git a/src/modules/sound.c b/src/modules/sound.c index 4ef58cdc2..ffc4aee76 100644 --- a/src/modules/sound.c +++ b/src/modules/sound.c @@ -11,10 +11,13 @@ static void printDevice(FFinstance* instance, const FFSoundDevice* device, uint8 ffPrintLogoAndKey(instance, FF_SOUND_MODULE_NAME, index, &instance->config.sound.key); ffStrbufWriteTo(&device->name, stdout); - if(device->volume > 0) - printf(" (%d%%)", device->volume); - else - fputs(" (muted)", stdout); + if(device->volume != FF_SOUND_VOLUME_UNKNOWN) + { + if(device->volume > 0) + printf(" (%d%%)", device->volume); + else + fputs(" (muted)", stdout); + } if(device->main && index > 0) fputs(" (*)", stdout);