How to Configure Audio Device Priorities in Pipewire / Wireplumber

Posted by Scott on Aug 1st, 2022

I have several audio devices connected to my Linux desktop machine, including a USB audio interface (a MOTU M4), and a Jabra wireless headset that uses a USB dongle, and appears as its own audio device. I also like to use Bluetooth headphones on a daily basis.

After switching to Pipewire as my audio backend, I found that my default audio device wasn’t switching automatically to what I wanted – I’d always have to set it manually. I’d need to do this when my BT headphones would connect (select the a2dp headphone profile), and then again when I disconnected them (because I wanted to hear sound from my MOTU audio interface, but it would automatically fallback to the Jabra headset device). This is a two-part recipe to fix these issues.

Step 1: Make pipewire automatically select my Bluetooth headphones sink when they connected. This didn’t require any configuration changes. Instead, I have a script which runs on startup of my desktop environment which runs pactl load-module module-switch-on-connect. This is actually a pulseaudio command, but desktop apps still use the pulseaudio interface, which pipewire implements as part of the pipewire-pulse package.

Step 2: Make my default audio device my MOTU M4 audio interface, and stop selecting the Jabra headset device when I disconnect my BT headphones. This turned out to be caused by the fact that the Jabra audio device had a higher priority than my audio interface. Run the command wpctl status to show a list of your audio devices, and make a note of the device number. In this case, I was looking for the M4 device in my list of Audio Sinks. Then you can run wpctl inspect <device-number> to show the details of this audio device. What you’re looking for are the fields priority.driver and priority.session. Larger numbers correspond to a higher priority, but for sinks, they should be kept no larger than 1500 (otherwise a sink’s monitor could end up being selected as a default source – this is called out in the Wireplumber documentation). In my case, the Jabra sink had a priority of 1008, so I chose to set my audio interface to a priority of 1050.

To change this configuration, you’d do so in Pipewire’s session manager. The preferred session manager for Pipewire is Wireplumber, which uses lua scripts to apply these kinds of custom configurations. So in my case, I created the file ~/.config/wireplumber/main.lua.d/60-raise-motu-m4-priority.lua with the following code:

rule = {
  matches = {
    {
      { "node.name", "equals", "alsa_output.usb-MOTU_M4_M4MC0570FU-00.Direct__hw_M4__sink" },
    },
  },
  apply_properties = {
    ["priority.driver"] = 1050,
    ["priority.session"] = 1050,
  },
}

table.insert(alsa_monitor.rules,rule)

Then, restart the wireplumber service with systemctl --user restart wireplumber and compare the new output from wpctl inspect. You should now see that the driver and session priorities are what you set them to. And when pipewire automatically switches to a new audio device, the highest priority device should be chosen.

I’ve found Pipewire and Wireplumber’s documentation to be confusing, and there are lots of dead-ends you can go down when researching how to do this. I hope this recipe-style blog post is easier to understand if this is the problem you’re trying to solve.

Many thanks to PleasantlyFlailing on the r/linuxaudio subreddit for suggesting some improvements to this blog post!

Leave a Comment

Please note: Comment moderation is enabled and may delay your comment. There is no need to resubmit your comment.

Blog Badges



[FSF Associate Member]

Archives