@@ -304,6 +304,8 @@ void PwNodeBoundAudio::updateVolumeProps(const PwVolumeProps& volumeProps) {
304304 return ;
305305 }
306306
307+ this ->volumeStep = volumeProps.volumeStep ;
308+
307309 // It is important that the lengths of channels and volumes stay in sync whenever you read them.
308310 auto channelsChanged = false ;
309311 auto volumesChanged = false ;
@@ -435,31 +437,35 @@ void PwNodeBoundAudio::setVolumes(const QVector<float>& volumes) {
435437 << " via device" ;
436438 this ->waitingVolumes = realVolumes;
437439 } else {
438- auto significantChange = this ->mServerVolumes .isEmpty ();
439- for (auto i = 0 ; i < this ->mServerVolumes .length (); i++) {
440- auto serverVolume = this ->mServerVolumes .value (i);
441- auto targetVolume = realVolumes.value (i);
442- if (targetVolume == 0 || abs (targetVolume - serverVolume) >= 0.0001 ) {
443- significantChange = true ;
444- break ;
440+ if (this ->volumeStep != -1 ) {
441+ auto significantChange = this ->mServerVolumes .isEmpty ();
442+ for (auto i = 0 ; i < this ->mServerVolumes .length (); i++) {
443+ auto serverVolume = this ->mServerVolumes .value (i);
444+ auto targetVolume = realVolumes.value (i);
445+ if (targetVolume == 0 || abs (targetVolume - serverVolume) >= this ->volumeStep ) {
446+ significantChange = true ;
447+ break ;
448+ }
445449 }
446- }
447450
448- if (significantChange) {
449- qCInfo (logNode) << " Changing volumes of" << this ->node << " to" << realVolumes
450- << " via device" ;
451- if (!this ->node ->device ->setVolumes (this ->node ->routeDevice , realVolumes)) {
452- return ;
453- }
451+ if (significantChange) {
452+ qCInfo (logNode) << " Changing volumes of" << this ->node << " to" << realVolumes
453+ << " via device" ;
454+ if (!this ->node ->device ->setVolumes (this ->node ->routeDevice , realVolumes)) {
455+ return ;
456+ }
454457
455- this ->mDeviceVolumes = realVolumes;
456- this ->node ->device ->waitForDevice ();
457- } else {
458- // Insignificant changes won't cause an info event on the device, leaving qs hung in the
459- // "waiting for acknowledgement" state forever.
460- qCInfo (logNode) << " Ignoring volume change for" << this ->node << " to" << realVolumes
461- << " from" << this ->mServerVolumes
462- << " as it is a device node and the change is too small." ;
458+ this ->mDeviceVolumes = realVolumes;
459+ this ->node ->device ->waitForDevice ();
460+ } else {
461+ // Insignificant changes won't cause an info event on the device, leaving qs hung in the
462+ // "waiting for acknowledgement" state forever.
463+ qCInfo (logNode).nospace ()
464+ << " Ignoring volume change for " << this ->node << " to " << realVolumes << " from "
465+ << this ->mServerVolumes
466+ << " as it is a device node and the change is too small (min step: "
467+ << this ->volumeStep << " )." ;
468+ }
463469 }
464470 }
465471 } else {
@@ -519,6 +525,7 @@ PwVolumeProps PwVolumeProps::parseSpaPod(const spa_pod* param) {
519525 const auto * volumesProp = spa_pod_find_prop (param, nullptr , SPA_PROP_channelVolumes);
520526 const auto * channelsProp = spa_pod_find_prop (param, nullptr , SPA_PROP_channelMap);
521527 const auto * muteProp = spa_pod_find_prop (param, nullptr , SPA_PROP_mute);
528+ const auto * volumeStepProp = spa_pod_find_prop (param, nullptr , SPA_PROP_volumeStep);
522529
523530 const auto * volumes = reinterpret_cast <const spa_pod_array*>(&volumesProp->value );
524531 const auto * channels = reinterpret_cast <const spa_pod_array*>(&channelsProp->value );
@@ -537,6 +544,12 @@ PwVolumeProps PwVolumeProps::parseSpaPod(const spa_pod* param) {
537544
538545 spa_pod_get_bool (&muteProp->value , &props.mute );
539546
547+ if (volumeStepProp) {
548+ spa_pod_get_float (&volumeStepProp->value , &props.volumeStep );
549+ } else {
550+ props.volumeStep = -1 ;
551+ }
552+
540553 return props;
541554}
542555
0 commit comments