[Solved] pipewire and volume
[Solved] pipewire and volume
It might be relevant to this question that I use pipewire[-pipewire-alsa], because I need pipewire only for google-chrome and discord as a pulseaudio-substitute.
Whenever I start pipewire/wireplumber (which I naturally do immediately after login), it lowers the volume level (to always the same amount, about 30%). However, I can change it back manually with alsamixer.
I also realized now that with bluez, it also lowers the default volume level. This is worse, because I cannot control this with alsamixer. Also using e.g. pavucontrol to change the volume has no effect. With bluealsa, there is the option --initial-volume=[0-100], but this effects the volume only if I output with alsa to the bluealsa device which is not happening when the sound output is to pulseaudio (that is, pipewire).
The files in ~/.local/state/wireplumber contain entries like "volume" or "channelVolume", but the values are all "1.000000", so this does not explain why the volume is not maximal.
So my question is two fold:
1. How to change volume for a connected bluetooth headphone with pipewire at all?
2. How to configure the startup volume level (for alsa and bluetooth, respectively) for pipewire? (It seems to be hardcoded at 30% or less.)
Whenever I start pipewire/wireplumber (which I naturally do immediately after login), it lowers the volume level (to always the same amount, about 30%). However, I can change it back manually with alsamixer.
I also realized now that with bluez, it also lowers the default volume level. This is worse, because I cannot control this with alsamixer. Also using e.g. pavucontrol to change the volume has no effect. With bluealsa, there is the option --initial-volume=[0-100], but this effects the volume only if I output with alsa to the bluealsa device which is not happening when the sound output is to pulseaudio (that is, pipewire).
The files in ~/.local/state/wireplumber contain entries like "volume" or "channelVolume", but the values are all "1.000000", so this does not explain why the volume is not maximal.
So my question is two fold:
1. How to change volume for a connected bluetooth headphone with pipewire at all?
2. How to configure the startup volume level (for alsa and bluetooth, respectively) for pipewire? (It seems to be hardcoded at 30% or less.)
Last edited by mv on Sun Jun 30, 2024 3:24 pm, edited 1 time in total.
- Anon-E-moose
- Watchman

- Posts: 6566
- Joined: Fri May 23, 2008 7:31 pm
- Location: Dallas area
Code: Select all
$ wpctl
Usage:
wpctl [OPTION…] COMMAND [COMMAND_OPTIONS] - WirePlumber Control CLI
Commands:
status
get-volume ID
inspect ID
set-default ID
set-volume ID VOL[%][-/+]
set-mute ID 1|0|toggle
set-profile ID INDEX
set-route ID INDEX
clear-default [ID]
settings [KEY] [VAL]
set-log-level [ID] LEVELCode: Select all
* 52. ALC269VC [vol: 1.00]wpctl set-volume 52 50% (or 5+/5- or 0.5)
UM780 xtx, 6.18 zen kernel, gcc 15, openrc, wayland
minixforum m1-s1 max -- same software as above but used for ai learning
Zealots are gonna be zealots, just like haters are gonna be haters
minixforum m1-s1 max -- same software as above but used for ai learning
Zealots are gonna be zealots, just like haters are gonna be haters
Perhaps you used the wrong regulator in pavucontrol; for general sound you need to use the "Output Devices" option. By adjusting the volume in devices when the "Output Devices" option is selected, the sound will also change in alsamixer. In addition, then the volume level will be maintained after a reboot. The file .local/state/wireplumber/restore-stream is responsible for this.
Thank you very much! This worked!Anon-E-moose wrote:Find device, id in this case is 52Code: Select all
$ wpctl [...] First run wpctl status, [code]* 52. ALC269VC [vol: 1.00]
wpctl set-volume 52 50% (or 5+/5- or 0.5)
On Output Devices, I see "Line Out (plugged in)", and a greyed-out level which I can move but which has no effect at all and which is also reset when I restart pavucontrol.ormorph wrote:Perhaps you used the wrong regulator in pavucontrol; for general sound you need to use the "Output Devices" option.
Below that, I see my headset with a not-greyed-out level which I can move but which has also no effect at all and which is also reset when I restart pavucontrol.
Both are reset to the values I configured with wpctrl, so it seems that wpctrl works and can change the values while pavucontrol only reads the values but cannot change them for some reason.
- Anon-E-moose
- Watchman

- Posts: 6566
- Joined: Fri May 23, 2008 7:31 pm
- Location: Dallas area
On my system, the id's seem pretty consistent, across boots.
When the headphones are plugged in, you can set them as the default device, and it will remember that for the next time you use them.
I have pipewire handle bluetooth as well as alsa, don't have either jack or pulse installed, so don't use that aspect of pipewire/wireplumber
When the headphones are plugged in, you can set them as the default device, and it will remember that for the next time you use them.
I have pipewire handle bluetooth as well as alsa, don't have either jack or pulse installed, so don't use that aspect of pipewire/wireplumber
UM780 xtx, 6.18 zen kernel, gcc 15, openrc, wayland
minixforum m1-s1 max -- same software as above but used for ai learning
Zealots are gonna be zealots, just like haters are gonna be haters
minixforum m1-s1 max -- same software as above but used for ai learning
Zealots are gonna be zealots, just like haters are gonna be haters
Do you happen to use settings with the PULSE_SERVER variable, or did you add the config to /etc/pipewire/pipewire-pulse.conf and edit it? This happened to me when tcp was selected, but when I replaced tcp with a unix socket, the sound adjustment worked.mv wrote:On Output Devices, I see "Line Out (plugged in)", and a greyed-out level which I can move but which has no effect at all and which is also reset when I restart pavucontrol.
Below that, I see my headset with a not-greyed-out level which I can move but which has also no effect at all and which is also reset when I restart pavucontrol.
Both are reset to the values I configured with wpctrl, so it seems that wpctrl works and can change the values while pavucontrol only reads the values but cannot change them for some reason.
I have PULSE_SERVER and /etc/pipewire/pipewire-pulse.conf both configured to a tcp. I do not want to use a unit socket, because I want to access pulse with several users from wayland. (I know that I could do permission hacks with sockets, but I do not want to do that.)ormorph wrote:Do you happen to use settings with the PULSE_SERVER variable, or did you add the config to /etc/pipewire/pipewire-pulse.conf and edit it? This happened to me when tcp was selected, but when I replaced tcp with a unix socket, the sound adjustment worked.
You looked at the topic where I posted links to the daemon for openrc. Several users can work via a unix socket. link1 link2.mv wrote:I have PULSE_SERVER and /etc/pipewire/pipewire-pulse.conf both configured to a tcp. I do not want to use a unit socket, because I want to access pulse with several users from wayland. (I know that I could do permission hacks with sockets, but I do not want to do that.)
Setting up with tcp is needed if you want to play sound from another computer, but for this you can register tcp in /etc/pipewire/pipewire-pulse.conf in addition to the unix socket.
Yes, as I said with permission hacks where everybody can write to a socket with a predictable file name in a public directory and/or other users need linking hacks at startup. Using tcp does sound more secure and simpler. As long as pavuctl is the only tool which breaks (and I have a working replacement for setting the volume) I do not care.ormorph wrote:You looked at the topic where I posted links to the daemon for openrc. Several users can work via a unix socket.mv wrote:I have PULSE_SERVER and /etc/pipewire/pipewire-pulse.conf both configured to a tcp. I do not want to use a unit socket, because I want to access pulse with several users from wayland. (I know that I could do permission hacks with sockets, but I do not want to do that.)
I don’t understand what then prevents everyone from writing to tcp? In Linux, no matter how everything is a file. You can ask the developers a question, I haven’t found a solution on how to regulate the sound using tcp.mv wrote:Yes, as I said with permission hacks where everybody can write to a socket with a predictable file name in a public directory and/or other users need linking hacks at startup. Using tcp does sound more secure.
iptables and/or nftablesormorph wrote:I don’t understand what then prevents everyone from writing to tcp?
What I mainly dislike for the approach is not the one public socket (I guess that this could probably be created also in a more restricted directory, e.g. in /run for which you can set more fine-grained permissions), but mainly the need to link the file at startup: There is no nice place for this linking. Doing it at every startup of an init-shell (or even of every shell?) is rather wrong, as using sound from some unprivileged user is logically not coupled to using a shell.In Linux, no matter how everything is a file.
All rights can be configured in the same way, this can also be done in a script and in /etc/profile.d. By the way, the script in /etc/profile.d is launched only in a new session after entering the login; it does not apply to each bash shell. Here it's up to you to decide how to set it up.mv wrote:What I mainly dislike for the approach is not the one public socket (I guess that this could probably be created also in a more restricted directory, e.g. in /run for which you can set more fine-grained permissions), but mainly the need to link the file at startup: There is no nice place for this linking. Doing it at every startup of an init-shell (or even of every shell?) is rather wrong, as using sound from some unprivileged user is logically not coupled to using a shell.
- Anon-E-moose
- Watchman

- Posts: 6566
- Joined: Fri May 23, 2008 7:31 pm
- Location: Dallas area
If you want to set/change volume from a script you could do the following in a script and set keys to raise/lower the volume.
wpctl set-volume @DEFAULT_AUDIO_SINK@ 10%+
wpctl get-volume @DEFAULT_AUDIO_SINK@
@DEFAULT_AUDIO_SINK@ is the current output audio device
My headphones report the battery level, but not by way of the kernel, but bluetoothctl shows it.
/usr/bin/bluetoothctl info B4:9A:95:51:E9:DA | awk '/Battery/ { gsub(/[()]/,""); print "Battery: " $NF }'
My bluetooth trackpad reports batt level in the /sys/ directories, but not in bluetoothctl. Every device is different. ~le sigh~
Edit to add: as usual arch wiki has helpful hints
https://wiki.archlinux.org/title/PipeWire
https://wiki.archlinux.org/title/WirePlumber
wpctl set-volume @DEFAULT_AUDIO_SINK@ 10%+
wpctl get-volume @DEFAULT_AUDIO_SINK@
@DEFAULT_AUDIO_SINK@ is the current output audio device
My headphones report the battery level, but not by way of the kernel, but bluetoothctl shows it.
/usr/bin/bluetoothctl info B4:9A:95:51:E9:DA | awk '/Battery/ { gsub(/[()]/,""); print "Battery: " $NF }'
My bluetooth trackpad reports batt level in the /sys/ directories, but not in bluetoothctl. Every device is different. ~le sigh~
Edit to add: as usual arch wiki has helpful hints
https://wiki.archlinux.org/title/PipeWire
https://wiki.archlinux.org/title/WirePlumber
UM780 xtx, 6.18 zen kernel, gcc 15, openrc, wayland
minixforum m1-s1 max -- same software as above but used for ai learning
Zealots are gonna be zealots, just like haters are gonna be haters
minixforum m1-s1 max -- same software as above but used for ai learning
Zealots are gonna be zealots, just like haters are gonna be haters
You are right: You can just replace the tcpd by a socket in a directory /run/pipewire generated by /etc/tmpfiles.d, and the socket will be automatically generated with 777 permissions (and access can be configured by the parent directory's permissions setup in /etc/tmpfiles.d).ormorph wrote:All rights can be configured in the same way.
The linking stuff is not necessary at all if you just want to use the sound input/output for the unprivileged user.
I thought that I had tried this before I tried the tcp approach and it did not work, but apparently I had made a mistake then (or something was different at the time when I had tried).
So I agree that you can just replace the tcp by a fixed socket and have practically the same. And pavucontrol then works (even for the unprivileged user).
Also pay attention to this line: link
This line is absolutely necessary if you need to listen to sound not only pulseaudio but also through alsa and jack. Actually, the PULSE_SERVER variable is most needed for adjusting the pulseaudio sound, and for playing, a link to pipewire-0 is enough.
This line is absolutely necessary if you need to listen to sound not only pulseaudio but also through alsa and jack. Actually, the PULSE_SERVER variable is most needed for adjusting the pulseaudio sound, and for playing, a link to pipewire-0 is enough.
This was exactly my point that I did not need this line for the the tcp approach, and it seems that it is also not needed for the socket approach.ormorph wrote:Also pay attention to this line: link
It is not if you start pipewire as a user (instead of as a daemon with separate privileges). Moreover, alsa is not related with this at all with pipewire[-pipewire-alsa]. I do not use jack, so cannot tell anything about that.This line is absolutely necessary if you need to listen to sound not only pulseaudio but also through alsa and jack.
Nope, it is not, at least for applications using pulse for output. The observation that just changing the permissions and adjusting XDG_RUNTIME_DIR was not enough to have sound output with the unprivileged user was my reason to be [topic=1162844]active in this thread[/topic] (which eventually led me to use the tcp approach in the first place).and for playing, a link to pipewire-0 is enough.
I know this from the example of using docker, there it is enough to mount pipewire-0 to get sound, the main thing is that pipewire is installed. I absolutely do not need to use the PULSE_SERVER variable to play sound if I run the OS in docker. If pipewire is running under the current user, of course this link is not needed.mv wrote:It is not if you start pipewire as a user (instead of as a daemon with separate privileges). Moreover, alsa is not related with this at all with pipewire[-pipewire-alsa]. I do not use jack, so cannot tell anything about that.
