Audio: Add Min/Max volume

AudioMinVolume/AudioMaxVolume remap the range 0%-100% to
AudioMinVolume-AudioMaxVolume

https://github.com/scorpion-26/gBar/issues/13
This commit is contained in:
scorpion-26 2023-03-21 22:09:56 +01:00
parent d6610f2594
commit 507cf222fb
4 changed files with 41 additions and 5 deletions

View file

@ -52,6 +52,11 @@ AudioRevealer: false
# Sets the rate of change of the slider on each scroll. In Percent
AudioScrollSpeed: 5
# Limits the range of the audio slider. Only works for audio output.
# Slider "empty" is AudioMinVolume, Slider "full" is AudioMaxVolume
# AudioMinVolume: 30 # Audio can't get below 30%
# AudioMaxVolume: 120 # Audio can't get above 120%
# The network adapter to use. You can query /sys/class/net for all possible values
NetworkAdapter: eno1

View file

@ -154,6 +154,9 @@ void Config::Load()
AddConfigVar("AudioScrollSpeed", config.audioScrollSpeed, lineView, foundProperty);
AddConfigVar("AudioMinVolume", config.audioMinVolume, lineView, foundProperty);
AddConfigVar("AudioMaxVolume", config.audioMaxVolume, lineView, foundProperty);
if (foundProperty == false)
{
LOG("Warning: unknown config var: " << lineView);

View file

@ -20,7 +20,7 @@ public:
bool networkWidget = true;
bool workspaceScrollOnMonitor = true; // Scroll through workspaces on monitor instead of all
bool workspaceScrollInvert = false; // Up = +1, instead of Up = -1
bool useHyprlandIPC = false; // Use Hyprland IPC instead of ext_workspaces protocol (Less buggy, but also less performant)
bool useHyprlandIPC = false; // Use Hyprland IPC instead of ext_workspaces protocol (Less buggy, but also less performant)
// Controls for color progression of the network widget
uint32_t minUploadBytes = 0; // Bottom limit of the network widgets upload. Everything below it is considered "under"
@ -30,6 +30,10 @@ public:
uint32_t audioScrollSpeed = 5; // 5% each scroll
// Only affects outputs (i.e.: speakers, not microphones). This remaps the range of the volume; In percent
double audioMinVolume = 0.f; // Map the minimum volume to this value
double audioMaxVolume = 100.f; // Map the maximum volume to this value
static void Load();
static const Config& Get();
};

View file

@ -1,6 +1,7 @@
#pragma once
#include "System.h"
#include "Common.h"
#include "Config.h"
#include <cmath>
#include <pulse/pulseaudio.h>
@ -54,6 +55,29 @@ namespace PulseAudio
return volRounded;
}
inline double PAVolumeToDoubleWithMinMax(const pa_cvolume* volume)
{
double volRoundend = PAVolumeToDouble(volume);
// Clamp it to min/max
double minVolume = Config::Get().audioMinVolume / 100.;
double maxVolume = Config::Get().audioMaxVolume / 100.;
volRoundend = std::clamp(volRoundend, minVolume, maxVolume);
// Remap min/max to 0/1
double volRemapped = (volRoundend - minVolume) / (maxVolume - minVolume);
return volRemapped;
}
inline double DoubleToVolumeWithMinMax(double value)
{
// Clamp to 0/1
value = std::clamp(value, 0., 1.);
// Remap 0/1 to min/max
double minVolume = Config::Get().audioMinVolume / 100.;
double maxVolume = Config::Get().audioMaxVolume / 100.;
double volRemapped = value * (maxVolume - minVolume) + minVolume;
return volRemapped;
}
inline void UpdateInfo()
{
LOG("PulseAudio: Update info");
@ -80,7 +104,7 @@ namespace PulseAudio
System::AudioInfo* out = (System::AudioInfo*)audioInfo;
double vol = PAVolumeToDouble(&paInfo->volume);
double vol = PAVolumeToDoubleWithMinMax(&paInfo->volume);
out->sinkVolume = vol;
out->sinkMuted = paInfo->mute;
};
@ -188,12 +212,12 @@ namespace PulseAudio
inline void SetVolumeSink(double value)
{
double valClamped = std::clamp(value, 0., 1.);
double valClamped = DoubleToVolumeWithMinMax(value);
// I'm too lazy to implement the c api for this. Since it will only be called when needed and doesn't pipe, it shouldn't be a problem to
// fallback for a command
LOG("Audio: Set volume of sink: " << valClamped);
std::string cmd = "pamixer --set-volume " + std::to_string((uint32_t)(valClamped * 100));
info.sinkVolume = valClamped;
std::string cmd = "pamixer --allow-boost --set-volume " + std::to_string((uint32_t)(valClamped * 100));
info.sinkVolume = std::clamp(value, 0., 1.); // We need to stay in 0/1 range
blockUpdate = true;
system(cmd.c_str());
}