How to set up Wireplumber to default to 5.1 Surround Sound?

Been struggling with this for about half a day. Trying to get 5.1 Surround Sound to survive a reboot. So I don't need to swtich to desktop on every boot to go from stereo to 5.1 https://wiki.archlinux.org/title/WirePlumber This should be what I need but would need to migrate the format as it mentions and struggling with that. https://blog.zenlinux.com/2022/08/how-to-configure-audio-device-priorities-in-pipewire-wireplumber/
Solution:
I got it working..... Basically what we were trying to do earlier. We just were not doing it correctly. You don't need to use sudo for any of this. pactl list...
Jump to solution
21 Replies
Akanar
Akanar5mo ago
monitor.alsa.rules = [
{
matches = [
{
node.name = "alsa_output.pci-0000_09_00.1.hdmi-surround-extra3"
}
]
actions = {
update-props = {
priority.session = 1500
}
}
}
]
monitor.alsa.rules = [
{
matches = [
{
node.name = "alsa_output.pci-0000_09_00.1.hdmi-surround-extra3"
}
]
actions = {
update-props = {
priority.session = 1500
}
}
}
]
~/.config/wireplumber/wireplumber.conf.d/51-sink-priority.conf This does not work. Not sure what I am doing wrong
wpctl settings node.filter.forward-format true
wpctl settings -s
wpctl settings node.filter.forward-format true
wpctl settings -s
This is useful, for instance, to make sure that an application will be properly configured to output surround audio to a surround device, even when going through a filter that was not explicitly configured to have a surround channel map.
If I do this when I fresh boot all I need to do is go to Power > Restart Steam. Then it will properly set it to Multi-Channel Audio. Which is better than going to desktop and getting the keyboard out every time I want to play a game. Still looking for a better solution though. What I don't understand is why Bazzite isn't respecting. node.restore-default-targets
This setting enables WirePlumber to store and restore the “default” source and sink targets of the graph. In PulseAudio terminology, this is also known as the “fallback” source and sink. When this setting is enabled, WirePlumber will store the “default” source and sink targets when they are changed manually (e.g. via pavucontrol) and restore them when the available nodes change or after a reload/restart. It will also store a history of past selected “default” targets and restore previously selected ones if the currently selected are not available. If this is disabled, WirePlumber will pick the best available source and sink targets based on their priorities, but it will also respect manual user selections that are done at runtime - it will just not remember them so that it can restore them at a later time.
Potajito
Potajito5mo ago
have you tried to do it using pactl? may be more straight forward, could also just script it at boot
Akanar
Akanar5mo ago
pactl is pulseaudio. Bazzite uses Pipewire. Also I have been trying to change it to 5.1 from stereo with just terminal commands for most of a day and not able to find the command(s) to do it.
Potajito
Potajito5mo ago
pactl is still usalbe uner pipewire is jsut a front end do "pactl list short" find your sink and then "pactl set-default-sink alsa_output.pci-0000_08_00.1.hdmi-whatever"
Akanar
Akanar5mo ago
pactl list short only shows the current sink which is the stereo one. If I use sound settings to change it to 5.1 to get the correct sink. Then switch back to stereo and run pactl set-default-sink alasa_output... etc then I just get "Failure: No such entity". To confirm the command work I set it to 5.1 manually then run the command and the command does not error. So I think Wireplumber is disabling the none active ones or something.
Potajito
Potajito5mo ago
try to use pactl set-card-profile "$object_id" "$profile_name" to set the 5.1 profile maybe it can help you, this is the script I use to change from PC to TV. It shutsdown the screen and sets default output to hdmi 5.1
#!/bin/bash

# Get the name of the TV monitor
tv_monitor=$(kscreen-doctor --outputs | grep -o "HDMI-[A-Z]-[0-9]\+" | awk '{print $1}')

# Enable the TV monitor, disable UW, Set TV as primary
kscreen-doctor output.HDMI-A-2.enable output.HDMI-A-2.primary output.DP-2.disable output.HDMI-A-2.mode.3840x2160@60 output.HDMI-A-2.position.0,0 output.DP-1.position.3840,0
# Disable UW
# kscreen-doctor output.DP-2.disable
# turn off UW
sleep 5
hdmi_audio_sink=$(pactl list sinks | grep -A1 "node.name" | grep "hdmi-" | awk -F'=' '{print $2}' | cut -d'"' -f2)
#device_description=$(pactl list sinks | grep -A1 "device.product.name" | awk -F'=' '{print $2}' | cut -d'"' -f2) #not used, but it would be nice to have it grab the device to then use it on the wpctl command
if [ -n "$hdmi_audio_sink" ]; then
# Set the HDMI audio output as the default sink
pactl set-default-sink "$hdmi_audio_sink"
pactl_output=$(pactl --format=json list cards)

object_id=$(echo "$pactl_output" | jq -r '.[] | select(.properties."device.nick" == "HDA NVidia") | .properties."object.serial"')
echo "TV device number: $object_id"

profile_name=$(echo "$pactl_output" | jq -r 'first(.[] | select(.properties."device.nick" == "HDA NVidia") | .profiles | to_entries[] | select(.key | startswith("output:hdmi-surround-"))).key')

echo "TV profile name: $profile_name"

pactl set-card-profile "$object_id" "$profile_name" #set the profile to 5, which is 5.1 (the order on the list of pavucontrol, for example, 0 is off, 1, 2...)
hdmi_audio_sink=$(pactl list sinks | grep -A1 "node.name" | grep "hdmi-surround" | awk -F'=' '{print $2}' | cut -d'"' -f2)
pactl set-default-sink "$hdmi_audio_sink"
echo "Default sink set to: $hdmi_audio_sink using profile $profile_name"
else
echo "HDMI audio sink not found for monitor: $tv_monitor"
fi
#!/bin/bash

# Get the name of the TV monitor
tv_monitor=$(kscreen-doctor --outputs | grep -o "HDMI-[A-Z]-[0-9]\+" | awk '{print $1}')

# Enable the TV monitor, disable UW, Set TV as primary
kscreen-doctor output.HDMI-A-2.enable output.HDMI-A-2.primary output.DP-2.disable output.HDMI-A-2.mode.3840x2160@60 output.HDMI-A-2.position.0,0 output.DP-1.position.3840,0
# Disable UW
# kscreen-doctor output.DP-2.disable
# turn off UW
sleep 5
hdmi_audio_sink=$(pactl list sinks | grep -A1 "node.name" | grep "hdmi-" | awk -F'=' '{print $2}' | cut -d'"' -f2)
#device_description=$(pactl list sinks | grep -A1 "device.product.name" | awk -F'=' '{print $2}' | cut -d'"' -f2) #not used, but it would be nice to have it grab the device to then use it on the wpctl command
if [ -n "$hdmi_audio_sink" ]; then
# Set the HDMI audio output as the default sink
pactl set-default-sink "$hdmi_audio_sink"
pactl_output=$(pactl --format=json list cards)

object_id=$(echo "$pactl_output" | jq -r '.[] | select(.properties."device.nick" == "HDA NVidia") | .properties."object.serial"')
echo "TV device number: $object_id"

profile_name=$(echo "$pactl_output" | jq -r 'first(.[] | select(.properties."device.nick" == "HDA NVidia") | .profiles | to_entries[] | select(.key | startswith("output:hdmi-surround-"))).key')

echo "TV profile name: $profile_name"

pactl set-card-profile "$object_id" "$profile_name" #set the profile to 5, which is 5.1 (the order on the list of pavucontrol, for example, 0 is off, 1, 2...)
hdmi_audio_sink=$(pactl list sinks | grep -A1 "node.name" | grep "hdmi-surround" | awk -F'=' '{print $2}' | cut -d'"' -f2)
pactl set-default-sink "$hdmi_audio_sink"
echo "Default sink set to: $hdmi_audio_sink using profile $profile_name"
else
echo "HDMI audio sink not found for monitor: $tv_monitor"
fi
Akanar
Akanar5mo ago
Running pactl set-card-profile alsa_card.pci-000_09_00.1 'output:hdmi-surround-extra3' works. Where should I add the command to always be this no matter what? Also wpctl settings node.filter.forward-format true does not seem to be doing anything now and I have disabled it again.
Potajito
Potajito5mo ago
you can create a systemd service sudo nano /etc/systemd/system/set-surround-profile.service
Description=Set Card Profile
After=sound.target

[Service]
Type=oneshot
ExecStart=/usr/bin/pactl set-card-profile alsa_card.pci-000_09_00.1 output:hdmi-surround-extra3
RemainAfterExit=yes

[Install]
WantedBy=multi-user.target
Description=Set Card Profile
After=sound.target

[Service]
Type=oneshot
ExecStart=/usr/bin/pactl set-card-profile alsa_card.pci-000_09_00.1 output:hdmi-surround-extra3
RemainAfterExit=yes

[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reload sudo systemctl enable set-surround-profile.service sudo systemctl start set-surround-profile.service I think that should do it
Akanar
Akanar5mo ago
Running /usr/bin/pactl set-card-profile alsa_card.pci-0000_09_00.1 output:hdmi-surround-extra3 outside of the service works but running it with the service results in an error from pactl Connection failure: Connection refused pa_context_connect() failed: Connection refused I had 3x zeros but it is 4. I used copy and paste to make sure I am using the exact same command.
Potajito
Potajito5mo ago
maybe the audio server has not been initialized yet when the service runs? try this
Akanar
Akanar5mo ago
Asked an AI and got this... You're encountering a known issue with running pactl as a service. Here's why it happens and how to fix it: The Problem: pactl relies on environment variables to identify the specific PulseAudio instance it should connect to. When launched by systemd (the service manager) as a service, pactl doesn't inherit the user's environment variables. This lack of information leads to pactl failing to connect and returning a "Connection refused" error. Solutions: Use a dedicated user: Create a dedicated user for your service that runs PulseAudio. Configure your service to run under that user. This ensures the service inherits the correct environment variables. Pass environment variables: Modify your service file to explicitly set the necessary PulseAudio environment variables before starting pactl. This approach requires more configuration but avoids creating a dedicated user.
Potajito
Potajito5mo ago
Description=Set PulseAudio Card Profile
After=default.target
PartOf=graphical-session.target

[Service]
Type=oneshot
ExecStart=/usr/bin/pactl set-card-profile alsa_card.pci-0000_09_00.1 output:hdmi-surround-extra3
User=<your-username>
Environment=XDG_RUNTIME_DIR=/run/user/%U

[Install]
WantedBy=default.target
Description=Set PulseAudio Card Profile
After=default.target
PartOf=graphical-session.target

[Service]
Type=oneshot
ExecStart=/usr/bin/pactl set-card-profile alsa_card.pci-0000_09_00.1 output:hdmi-surround-extra3
User=<your-username>
Environment=XDG_RUNTIME_DIR=/run/user/%U

[Install]
WantedBy=default.target
change the <your-username> for your user and give it a shot
Akanar
Akanar5mo ago
Failed to create secure directory (/run/user/0/pulse): No such file or directory Directory I have is /run/user/1000 Then the error I listed before
Potajito
Potajito5mo ago
try with the first script but first disable the service: sudo systemctl disable set-surround-profile.service sudo systemctl stop set-surround-profile.service and then try to run it with your user: systemctl --user enable set-surround-profile.service systemctl --user start set-surround-profile.service
Akanar
Akanar5mo ago
.service file needed to be in ~/.config/systemd/user It works when I start it manually but after a reboot I stay in Stereo and the service will be Active: inactive (dead)
Potajito
Potajito5mo ago
Maybe you could introduce a delay to the service I'm in the phone now but should be easy to look up
Akanar
Akanar5mo ago
I added a 30 second delay which I confirmed worked by manually starting the service but after a reboot and waiting it still reports the same thing as before unfortunately. Been playing around trying different things and noticed something. Every thing is back to defaults now btw. On a fresh boot I default to Stereo as always. Running systemctl --user restart pipewire.service and doing nothing else automatically sets it to 5.1 surround. This makes me think something is wrong with how things are configured on Bazzite by default This also works restarting to the default gamescope and not the desktop then restarting the pipewire service via SSH. Hmm, I created a service to restart pipewire after 30 seconds but now even if I restart pipewire via SSH it is breaking sound in gamescope until I restart it. HOWEVER I have discovered if I sudo reboot via SSH I will get 5.1 surround no matter what upon boot. Verified this multiple times. Think I'll open a github issue for this.
Solution
Akanar
Akanar5mo ago
I got it working..... Basically what we were trying to do earlier. We just were not doing it correctly. You don't need to use sudo for any of this. pactl list You are looking for the name and output you want to use. Change yours to whatever you need them to be. I will just list what I need to use. Name: alsa_card.pci-0000_09_00.1 output:hdmi-surround-extra3 nano ~/.config/systemd/user/set-surround.service
Description=Set Sink in PipeWire (user session)

[Service]
Type=oneshot
ExecStart=sh -c "sleep 30; /usr/bin/pactl set-card-profile alsa_card.pci-0000_09_00.1 output:hdmi-surround-extra3"

[Install]
WantedBy=default.target
Description=Set Sink in PipeWire (user session)

[Service]
Type=oneshot
ExecStart=sh -c "sleep 30; /usr/bin/pactl set-card-profile alsa_card.pci-0000_09_00.1 output:hdmi-surround-extra3"

[Install]
WantedBy=default.target
systemctl --user daemon-reload systemctl --user enable set-surround.service systemctl --user start set-surround.service On boot it will wait 30 seconds and switch the audio sink.
Ryuzaki Koizumi
Ryuzaki Koizumi5mo ago
Bro you are a fucking godsend, I have been banging my head trying to figure this out through Wireplumber. I tweaked the sleep time so it takes less time for it to start the service and so far it works pretty well. My only gripe about it is it's going through PulseAudio, if we can figure out how to do this with Wireplumber I would rather do that, but this will work for now.
Akanar
Akanar5mo ago
Wireplumber is the most convoluted thing that a normal user would need to use I have ran across in my time using linux. It is like needing to change cam timing in order to turn on your windshield wipers. Spent a week trying to get it to work. Does not help that they switched from a convoluted scripting system to yet another convoluted scripting system. So the few old guides that I could find don't work anymore. I don't understand how the developers think an average user is ever going to be able to wrap their head around the monstrosity they have created. Sure it is able to do a lot of stuff that pulse audio couldn't do but what's the point if you need to have an engineering degree in order to use it.
Ryuzaki Koizumi
Ryuzaki Koizumi5mo ago
Ya I can't wrap my head around it either and I'm running into the same issues too.
Want results from more Discord servers?
Add your server