summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimon Rettberg2022-09-20 17:04:24 +0200
committerSimon Rettberg2022-09-20 17:04:24 +0200
commit5ef07dccfe23c892b2c9275e7e7238a2d51178f5 (patch)
tree7ee578ce7a42f55bdd046467b0ca00da41c879d3
parentMake resizing a little less bad (diff)
downloadpavucontrol-slx-5ef07dccfe23c892b2c9275e7e7238a2d51178f5.tar.gz
pavucontrol-slx-5ef07dccfe23c892b2c9275e7e7238a2d51178f5.tar.xz
pavucontrol-slx-5ef07dccfe23c892b2c9275e7e7238a2d51178f5.zip
Add volume fixing daemon/worker mode
-rw-r--r--src/main.cpp94
1 files changed, 83 insertions, 11 deletions
diff --git a/src/main.cpp b/src/main.cpp
index b1736cc..e537a74 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -36,7 +36,7 @@ static QString _pendingCardDefaultId;
static QString _pendingCardDefaultPort;
/** While running, we want to set each port's volume to 100% the first time we see it. Unfortunately
- * a port only startes to exist once its according profile is selected, so there is no way to have
+ * a port only starts to exist once its according profile is selected, so there is no way to have
* a simple "set everything to 100%" method run on startup, at least not without switching through
* all profiles on all cards, which sounds like it could be annoying and buggy. So do it this way
* for now.
@@ -59,27 +59,53 @@ static void queueGuiUpdate(int ms = 50)
_updateDelay.start(ms);
}
-static void addDevicePortToWindow(PulseAudioQt::Card *card, PulseAudioQt::Device *device, PulseAudioQt::Port *port, int portIndex, bool isOutput)
+/**
+ * Make sure the port is enabled and volume up, the first time we see it at least.
+ */
+static void autoVolumeAdjustment(PulseAudioQt::Device *device, PulseAudioQt::Port *port, int portIndex = -1)
{
- //if (port->availability() == PulseAudioQt::Port::Unavailable)
- // continue;
+ QString id = device->name() + port->name();
+ if (_donePorts.contains(id))
+ return;
+ if (portIndex == -1) {
+ int i = -1;
+ for (auto *p : device->ports()) {
+ ++i;
+ if (port == p) {
+ portIndex = i;
+ }
+ }
+ if (portIndex == -1) {
+ printf("Port not found\n");
+ return;
+ }
+ }
bool portIsActive = portIndex == device->activePortIndex();
bool defaultSinkAndPort = (device->isDefault() && portIsActive);
qint64 volume = device->volume();
- printf("[%c] Output: '%s %s', volume: %d, mute: %d\n",
- defaultSinkAndPort ? 'x' : ' ',
- device->description().toLocal8Bit().constData(), port->description().toLocal8Bit().constData(),
- (int)volume, (int)device->isMuted());
- QString id = device->name() + port->name();
// Only once, update port volume to be 100% if it's low
- if (defaultSinkAndPort && !_donePorts.contains(id)) {
+ if (defaultSinkAndPort) {
_donePorts.insert(id);
+ printf("Initial volume fix for %s\n", id.toLocal8Bit().constData());
if (volume < 60000) {
volume = 65535;
device->setVolume(volume);
}
device->setMuted(false);
}
+}
+
+static void addDevicePortToWindow(PulseAudioQt::Card *card, PulseAudioQt::Device *device, PulseAudioQt::Port *port, int portIndex, bool isOutput)
+{
+ //if (port->availability() == PulseAudioQt::Port::Unavailable)
+ // continue;
+ bool portIsActive = portIndex == device->activePortIndex();
+ bool defaultSinkAndPort = (device->isDefault() && portIsActive);
+ qint64 volume = device->volume();
+ printf("[%c] Output: '%s %s', volume: %d, mute: %d\n",
+ defaultSinkAndPort ? 'x' : ' ',
+ device->description().toLocal8Bit().constData(), port->description().toLocal8Bit().constData(),
+ (int)volume, (int)device->isMuted());
//knownCardPortCombos.insert(card->name() + ":" + port->name());
_mainWindow->getDevice(card, device, port, isOutput)->updateDeviceAndPort(defaultSinkAndPort, device->isMuted(),
(portIsActive && device->isVolumeWritable()) ? device->volume() : -1);
@@ -430,6 +456,36 @@ void enableSource(const QString &source, const QString &port)
queueGuiUpdate();
}
+static void setupAutoVolumeDevice(PulseAudioQt::Device *device)
+{
+ auto fn = [device]() {
+ int pi = device->activePortIndex();
+ if (pi < 0 || pi >= device->ports().size())
+ return;
+ auto *port = device->ports().at(pi);
+ autoVolumeAdjustment(device, port, pi);
+ };
+ QObject::connect(device, &PulseAudioQt::Source::activePortIndexChanged, fn);
+ fn();
+}
+
+static void setupAutoVolume()
+{
+ auto *i = PulseAudioQt::Context::instance();
+ for (auto *sink : i->sinks()) {
+ setupAutoVolumeDevice(sink);
+ }
+ for (auto *source : i->sources()) {
+ setupAutoVolumeDevice(source);
+ }
+ QObject::connect(i, &PulseAudioQt::Context::sinkAdded, [](PulseAudioQt::Sink *sink) {
+ setupAutoVolumeDevice(sink);
+ });
+ QObject::connect(i, &PulseAudioQt::Context::sourceAdded, [](PulseAudioQt::Source *source) {
+ setupAutoVolumeDevice(source);
+ });
+}
+
int main(int argc, char **argv)
{
QApplication a(argc, argv);
@@ -441,18 +497,34 @@ int main(int argc, char **argv)
parser.setApplicationDescription(QObject::tr("SLXmix Volume Control"));
parser.addHelpOption();
QCommandLineOption selectOption(QStringList() << QStringLiteral("output") << QStringLiteral("o"),
- QObject::tr("Select a specific output configuration and quit. Will select the Profile/Sink/Port combo that best matches the list of given keywords, e.g. 'HDMI 1 5.1'"),
+ QObject::tr("Select a specific output configuration and quit. Will select the Profile/Sink/Port combo"
+ " that best matches the list of given keywords, e.g. 'HDMI 1 5.1'"),
QStringLiteral("keywords"));
+ QCommandLineOption workerOption(QStringList() << QStringLiteral("worker") << QStringLiteral("w"),
+ QObject::tr("Run invisible worker that sets every port to 100% and unmuted the first time it's set default"));
parser.addOption(selectOption);
+ parser.addOption(workerOption);
parser.process(a);
// Select default output and exit
if (parser.isSet(selectOption)) {
+ if (parser.isSet(workerOption)) {
+ printf("Cannot set both -w and -o at the same time.\n");
+ return 1;
+ }
QString what = parser.value(selectOption);
QTimer::singleShot(100, [what]() {
setDefaultOutput(what);
});
return a.exec();
}
+ if (parser.isSet(workerOption)) {
+ if (parser.isSet(selectOption)) {
+ printf("Cannot set both -w and -o at the same time.\n");
+ return 1;
+ }
+ QTimer::singleShot(100, &setupAutoVolume);
+ return a.exec();
+ }
// There's no signal, or no way to check if we're connected to PA, so
// just wait a bit and hope for the best.