forked from quickshell/quickshell
service/pipewire: ignore insignificant device volume changes
Fixes devices getting stuck in a "waiting for volume change acknowledgement" state forever.
This commit is contained in:
parent
a116f39c63
commit
f6ad617b67
2 changed files with 32 additions and 7 deletions
|
@ -228,10 +228,10 @@ void PwNodeBoundAudio::onInfo(const pw_node_info* info) {
|
||||||
|
|
||||||
if (param.id == SPA_PARAM_Props) {
|
if (param.id == SPA_PARAM_Props) {
|
||||||
if ((param.flags & SPA_PARAM_INFO_READWRITE) == SPA_PARAM_INFO_READWRITE) {
|
if ((param.flags & SPA_PARAM_INFO_READWRITE) == SPA_PARAM_INFO_READWRITE) {
|
||||||
qCDebug(logNode) << "Enumerating props param for" << this;
|
qCDebug(logNode) << "Enumerating props param for" << this->node;
|
||||||
pw_node_enum_params(this->node->proxy(), 0, param.id, 0, UINT32_MAX, nullptr);
|
pw_node_enum_params(this->node->proxy(), 0, param.id, 0, UINT32_MAX, nullptr);
|
||||||
} else {
|
} else {
|
||||||
qCWarning(logNode) << "Unable to enumerate props param for" << this
|
qCWarning(logNode) << "Unable to enumerate props param for" << this->node
|
||||||
<< "as the param does not have read+write permissions.";
|
<< "as the param does not have read+write permissions.";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -266,6 +266,10 @@ void PwNodeBoundAudio::updateVolumeProps(const spa_pod* param) {
|
||||||
qCInfo(logNode) << "Got updated channels of" << this->node << '-' << this->mChannels;
|
qCInfo(logNode) << "Got updated channels of" << this->node << '-' << this->mChannels;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this->mServerVolumes != volumeProps.volumes) {
|
||||||
|
this->mServerVolumes = volumeProps.volumes;
|
||||||
|
}
|
||||||
|
|
||||||
if (this->mVolumes != volumeProps.volumes) {
|
if (this->mVolumes != volumeProps.volumes) {
|
||||||
this->mVolumes = volumeProps.volumes;
|
this->mVolumes = volumeProps.volumes;
|
||||||
volumesChanged = true;
|
volumesChanged = true;
|
||||||
|
@ -286,6 +290,7 @@ void PwNodeBoundAudio::updateVolumeProps(const spa_pod* param) {
|
||||||
void PwNodeBoundAudio::onUnbind() {
|
void PwNodeBoundAudio::onUnbind() {
|
||||||
this->mChannels.clear();
|
this->mChannels.clear();
|
||||||
this->mVolumes.clear();
|
this->mVolumes.clear();
|
||||||
|
this->mServerVolumes.clear();
|
||||||
this->mDeviceVolumes.clear();
|
this->mDeviceVolumes.clear();
|
||||||
this->waitingVolumes.clear();
|
this->waitingVolumes.clear();
|
||||||
emit this->channelsChanged();
|
emit this->channelsChanged();
|
||||||
|
@ -381,13 +386,32 @@ void PwNodeBoundAudio::setVolumes(const QVector<float>& volumes) {
|
||||||
<< "via device";
|
<< "via device";
|
||||||
this->waitingVolumes = realVolumes;
|
this->waitingVolumes = realVolumes;
|
||||||
} else {
|
} else {
|
||||||
qCInfo(logNode) << "Changing volumes of" << this->node << "to" << realVolumes << "via device";
|
auto significantChange = this->mServerVolumes.isEmpty();
|
||||||
if (!this->node->device->setVolumes(this->node->routeDevice, realVolumes)) {
|
for (auto i = 0; i < this->mServerVolumes.length(); i++) {
|
||||||
return;
|
auto serverVolume = this->mServerVolumes.value(i);
|
||||||
|
auto targetVolume = realVolumes.value(i);
|
||||||
|
if (targetVolume == 0 || abs(targetVolume - serverVolume) >= 0.0001) {
|
||||||
|
significantChange = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this->mDeviceVolumes = realVolumes;
|
if (significantChange) {
|
||||||
this->node->device->waitForDevice();
|
qCInfo(logNode) << "Changing volumes of" << this->node << "to" << realVolumes
|
||||||
|
<< "via device";
|
||||||
|
if (!this->node->device->setVolumes(this->node->routeDevice, realVolumes)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this->mDeviceVolumes = realVolumes;
|
||||||
|
this->node->device->waitForDevice();
|
||||||
|
} else {
|
||||||
|
// Insignificant changes won't cause an info event on the device, leaving qs hung in the
|
||||||
|
// "waiting for acknowledgement" state forever.
|
||||||
|
qCInfo(logNode) << "Ignoring volume change for" << this->node << "to" << realVolumes
|
||||||
|
<< "from" << this->mServerVolumes
|
||||||
|
<< "as it is a device node and the change is too small.";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
auto buffer = std::array<quint8, 1024>();
|
auto buffer = std::array<quint8, 1024>();
|
||||||
|
|
|
@ -150,6 +150,7 @@ private:
|
||||||
bool mMuted = false;
|
bool mMuted = false;
|
||||||
QVector<PwAudioChannel::Enum> mChannels;
|
QVector<PwAudioChannel::Enum> mChannels;
|
||||||
QVector<float> mVolumes;
|
QVector<float> mVolumes;
|
||||||
|
QVector<float> mServerVolumes;
|
||||||
QVector<float> mDeviceVolumes;
|
QVector<float> mDeviceVolumes;
|
||||||
QVector<float> waitingVolumes;
|
QVector<float> waitingVolumes;
|
||||||
PwNode* node;
|
PwNode* node;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue