Volume slider works
This commit is contained in:
parent
6d74ef422d
commit
96e1a5cbdb
3 changed files with 64 additions and 3 deletions
|
|
@ -120,6 +120,12 @@ QWidget *PipeWireGraphModel::nodeWidget(QtNodes::NodeId nodeId) const
|
||||||
return it->second;
|
return it->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t pipewireId = 0;
|
||||||
|
auto nodeIt = m_nodes.find(nodeId);
|
||||||
|
if (nodeIt != m_nodes.end()) {
|
||||||
|
pipewireId = nodeIt->second.id;
|
||||||
|
}
|
||||||
|
|
||||||
auto *widget = new QWidget();
|
auto *widget = new QWidget();
|
||||||
auto *layout = new QHBoxLayout(widget);
|
auto *layout = new QHBoxLayout(widget);
|
||||||
layout->setContentsMargins(6, 2, 6, 2);
|
layout->setContentsMargins(6, 2, 6, 2);
|
||||||
|
|
@ -129,14 +135,25 @@ QWidget *PipeWireGraphModel::nodeWidget(QtNodes::NodeId nodeId) const
|
||||||
muteButton->setText("M");
|
muteButton->setText("M");
|
||||||
muteButton->setCheckable(true);
|
muteButton->setCheckable(true);
|
||||||
muteButton->setFixedSize(20, 20);
|
muteButton->setFixedSize(20, 20);
|
||||||
muteButton->setToolTip(QString("Mute (UI only)"));
|
muteButton->setToolTip(QString("Mute"));
|
||||||
|
|
||||||
auto *slider = new QSlider(Qt::Horizontal, widget);
|
auto *slider = new QSlider(Qt::Horizontal, widget);
|
||||||
slider->setRange(0, 100);
|
slider->setRange(0, 100);
|
||||||
slider->setValue(100);
|
slider->setValue(100);
|
||||||
slider->setFixedHeight(18);
|
slider->setFixedHeight(18);
|
||||||
slider->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
|
slider->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
|
||||||
slider->setToolTip(QString("Volume (UI only)"));
|
slider->setToolTip(QString("Volume"));
|
||||||
|
|
||||||
|
const auto applyVolume = [this, pipewireId, slider, muteButton]() {
|
||||||
|
if (!m_controller || pipewireId == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const float volume = static_cast<float>(slider->value()) / 100.0f;
|
||||||
|
m_controller->setNodeVolume(pipewireId, volume, muteButton->isChecked());
|
||||||
|
};
|
||||||
|
|
||||||
|
QObject::connect(slider, &QSlider::valueChanged, widget, [applyVolume](int) { applyVolume(); });
|
||||||
|
QObject::connect(muteButton, &QToolButton::toggled, widget, [applyVolume](bool) { applyVolume(); });
|
||||||
|
|
||||||
layout->addWidget(muteButton);
|
layout->addWidget(muteButton);
|
||||||
layout->addWidget(slider);
|
layout->addWidget(slider);
|
||||||
|
|
@ -266,7 +283,14 @@ bool PipeWireGraphModel::connectionPossible(QtNodes::ConnectionId const connecti
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (outInfo.mediaClass != inInfo.mediaClass) {
|
const auto isAudioClass = [](Potato::MediaClass mediaClass) {
|
||||||
|
return mediaClass == Potato::MediaClass::AudioSink
|
||||||
|
|| mediaClass == Potato::MediaClass::AudioSource
|
||||||
|
|| mediaClass == Potato::MediaClass::AudioDuplex
|
||||||
|
|| mediaClass == Potato::MediaClass::Stream;
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!isAudioClass(outInfo.mediaClass) || !isAudioClass(inInfo.mediaClass)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@
|
||||||
#include <QString>
|
#include <QString>
|
||||||
#include <QElapsedTimer>
|
#include <QElapsedTimer>
|
||||||
#include <QThread>
|
#include <QThread>
|
||||||
|
#include <algorithm>
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <cmath>
|
#include <cmath>
|
||||||
|
|
@ -13,6 +14,7 @@
|
||||||
#include <pipewire/keys.h>
|
#include <pipewire/keys.h>
|
||||||
#include <pipewire/properties.h>
|
#include <pipewire/properties.h>
|
||||||
#include <pipewire/stream.h>
|
#include <pipewire/stream.h>
|
||||||
|
#include <pipewire/node.h>
|
||||||
#include <spa/param/props.h>
|
#include <spa/param/props.h>
|
||||||
#include <spa/param/audio/format-utils.h>
|
#include <spa/param/audio/format-utils.h>
|
||||||
#include <spa/param/audio/raw.h>
|
#include <spa/param/audio/raw.h>
|
||||||
|
|
@ -444,6 +446,40 @@ float PipeWireController::meterPeak() const
|
||||||
return peak;
|
return peak;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool PipeWireController::setNodeVolume(uint32_t nodeId, float volume, bool mute)
|
||||||
|
{
|
||||||
|
if (!m_threadLoop || !m_core || !m_registry) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nodeId == 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
volume = std::clamp(volume, 0.0f, 1.0f);
|
||||||
|
|
||||||
|
lock();
|
||||||
|
auto *node = static_cast<struct pw_node*>(
|
||||||
|
pw_registry_bind(m_registry, nodeId, PW_TYPE_INTERFACE_Node, PW_VERSION_NODE, 0));
|
||||||
|
if (!node) {
|
||||||
|
unlock();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t buffer[128];
|
||||||
|
spa_pod_builder builder = SPA_POD_BUILDER_INIT(buffer, sizeof(buffer));
|
||||||
|
auto *param = reinterpret_cast<const struct spa_pod*>(spa_pod_builder_add_object(
|
||||||
|
&builder,
|
||||||
|
SPA_TYPE_OBJECT_Props, SPA_PARAM_Props,
|
||||||
|
SPA_PROP_volume, SPA_POD_Float(volume),
|
||||||
|
SPA_PROP_mute, SPA_POD_Bool(mute)));
|
||||||
|
|
||||||
|
pw_node_set_param(node, SPA_PARAM_Props, 0, param);
|
||||||
|
pw_proxy_destroy(reinterpret_cast<struct pw_proxy*>(node));
|
||||||
|
unlock();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
float PipeWireController::nodeMeterPeak(uint32_t nodeId) const
|
float PipeWireController::nodeMeterPeak(uint32_t nodeId) const
|
||||||
{
|
{
|
||||||
QMutexLocker lock(&m_meterMutex);
|
QMutexLocker lock(&m_meterMutex);
|
||||||
|
|
|
||||||
|
|
@ -41,6 +41,7 @@ public:
|
||||||
float nodeMeterPeak(uint32_t nodeId) const;
|
float nodeMeterPeak(uint32_t nodeId) const;
|
||||||
void ensureNodeMeter(uint32_t nodeId, const QString &targetName, bool captureSink);
|
void ensureNodeMeter(uint32_t nodeId, const QString &targetName, bool captureSink);
|
||||||
void removeNodeMeter(uint32_t nodeId);
|
void removeNodeMeter(uint32_t nodeId);
|
||||||
|
bool setNodeVolume(uint32_t nodeId, float volume, bool mute);
|
||||||
|
|
||||||
uint32_t createLink(uint32_t outputNodeId, uint32_t outputPortId,
|
uint32_t createLink(uint32_t outputNodeId, uint32_t outputPortId,
|
||||||
uint32_t inputNodeId, uint32_t inputPortId);
|
uint32_t inputNodeId, uint32_t inputPortId);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue