synesthesiam/homeassistant-satellite

Ducking and Mopidy (music) not working as intended

Opened this issue · 3 comments

Hello guys,

I've got the following problem with ducking.
I have two voice commands, one for starting music and one for stopping the playback.
So now if I listen to music and then use the stop command, ducking kicks in like it should be and sets the music to 20% volume. But since the music is stopped right after, it does not bring it back to its original volume. The problem is now, when I want to listen to music again, the music volume still is on 20%.

Sorry for the bad english.

Best regards,
joie96

I just replicated this and was about to file my own issue when I found this one. In what I believe I've narrowed this down to is that if the voice command triggers a streaming change, PulseAudio is spinning up a new mixer control that is getting stuck at the ducking volume.

In my case I'm triggering MPD to play various streams, and then stopping them, all by sentence automations. It seems that every stream creates a new process and resulting PA mixer control at the ducked 0.2 volume, but since the mixer control is "new" HA satellite is not raising it after voice command completion. All other "existing" mixers do seem to be raised back to the original volume, if they existed.

This may be a PulseAudio issue as I don't know these frameworks well enough to understand how it all works.

It would be nice if the tool just set the default volume for new streams after ducking to 100% so new streams started back at 100%

I'm not sure whether this is solvable on the satellite side. The ducking implementation is meant as a simple solution that works for most cases, but the satellite has limited control over pulseaudio/pipewire so edge cases are hard.

Ducking works as follows:

  • after the wakeword is detected, all active pulse streams are set to 20%, and their previous volume is stored
  • after the pipeline finishes, all streams with a stored volume are reset to that stored value.

Now if a stream ends while ducking is active, the satellite cannot reset its volume cause the stream does not exist anymore! Moreover, pulseaudio by default remembers the last volume of a stream. So when the application creates a new stream, it is pulseaudio itself that restores the volume to 20%, since that was its last volume. There is no way to tell pulseaudio to change the saved volume of the stream back to 100%.

One solution is to tell pulseaudio not to restore stream volumes at all, if always restoring volumes to 100% is acceptable. This is done changing

load-module module-stream-restore

to

load-module module-stream-restore restore_volume=false

in /etc/pulseaudio/default.pa. Unfortunately this is a global setting affecting all applications.

For pipewire (with wireplumber), on the other hand, we can disable this on a per-app basis. Eg to disable restoring the volume of snapcast, we can create a file $HOME/.config/wireplumber/main.lua.d/41-stream-defaults-custom.lua with the following contents:

table.insert(stream_defaults.rules,
  {
    matches = {
      {
        { "application.name", "matches", "Snapcast" },
      },
    },
    apply_properties = {
      ["state.restore-props"] = false,
    },
  }
)