Pipewire: Difference between revisions

From miki
Jump to navigation Jump to search
 
(19 intermediate revisions by the same user not shown)
Line 9: Line 9:
:* [https://docs.pipewire.org/page_module_protocol_pulse.html PipeWire Module: Protocol Pulse], [https://gitlab.freedesktop.org/pipewire/pipewire/-/wikis/Config-PulseAudio Config PulseAudio], [https://gitlab.freedesktop.org/pipewire/pipewire/-/wikis/Migrate-PulseAudio Migrate PulseAudio].
:* [https://docs.pipewire.org/page_module_protocol_pulse.html PipeWire Module: Protocol Pulse], [https://gitlab.freedesktop.org/pipewire/pipewire/-/wikis/Config-PulseAudio Config PulseAudio], [https://gitlab.freedesktop.org/pipewire/pipewire/-/wikis/Migrate-PulseAudio Migrate PulseAudio].
* [https://docs.pipewire.org/index.html Pipewire docs].
* [https://docs.pipewire.org/index.html Pipewire docs].

;WirePlumber
* [https://pipewire.pages.freedesktop.org/wireplumber/ WirePlumber - documentation]
* [https://pipewire.pages.freedesktop.org/wireplumber/ WirePlumber - documentation]
* [https://wiki.archlinux.org/title/WirePlumber WirePlumber - archlinux]
: Nice examples on how to use the lua configuration files.
: Link to an [https://www.collabora.com/news-and-blog/blog/2020/05/07/wireplumber-the-pipewire-session-manager/ nice blog on wireplumber (explanation)].


== References ==
== References ==
Line 42: Line 47:
pw-cli
pw-cli
> info all
> info all

# wireplumber
wpctl status

# wireplumber - troubleshooting
wpctl status # verify the default endpoints
pw-record test.wav # ... can also set target...
pw-play test.wav
# ... more at https://pipewire.pages.freedesktop.org/wireplumber/testing.html#wireplumber-examples
</source>
</source>


Line 72: Line 86:
We want to use the profile <code>sbc sbc_xq</code> for our BT headset Sony WH-1000XM3.
We want to use the profile <code>sbc sbc_xq</code> for our BT headset Sony WH-1000XM3.


;EASIEST METHOD &mdash; Select the profile Gnome Settings / pactl
;Set the profile manually - profile should be persistent on reboot / reconnect.
* See also [https://gitlab.freedesktop.org/pipewire/wireplumber/-/issues/143]
* In principe WirePlumber should remember the last selected profile.
* Selected profile is persistent on reboot / reconnect.
* See [https://gitlab.freedesktop.org/pipewire/wireplumber/-/issues/143]
* Select the profile in '''Gnome Settings - Sound''', or:

<source lang="bash">
<source lang="bash">
# See available profile and device id with 'pactl list'
# See available profile and device id with 'pactl list'
Line 81: Line 95:
</source>
</source>


;Select wanted profile in pipewire / wireplumber
;Configure profile
* When using {{deb|pipewire-media-session}}, the default profile could be selected in {{file|bluez-monitor.conf}}, but this file no longer exists with WirePlumber.
* (pipewire-media-session) When using {{deb|pipewire-media-session}}, the default profile could be selected in {{file|bluez-monitor.conf}}, but this file no longer exists with WirePlumber.
* (UPDATE - [https://wiki.archlinux.org/title/PipeWire#Low_audio_quality_on_Bluetooth Archlinux - Pipewire]) Edit {{file|/etc/wireplumber/bluetooth.lua.d/51-bluez-config.lua}} (or {{file|~/.config/wireplumber/bluetooth.lua.d/51-bluez-config.lua}}):
* (wireplumber) Edit {{file|/etc/wireplumber/bluetooth.lua.d/51-bluez-config.lua}} (or {{file|~/.config/wireplumber/bluetooth.lua.d/51-bluez-config.lua}}) [https://wiki.archlinux.org/title/PipeWire#Low_audio_quality_on_Bluetooth Archlinux - Pipewire]:


<source lang="lua">
<source lang="lua">
Line 91: Line 105:
["bluez5.codecs"] = "[sbc sbc_xq]",
["bluez5.codecs"] = "[sbc sbc_xq]",
}
}
</source>

;Profile auto-switch
<source lang="bash">
# This simulates capture throug PulseAudio for telephony, and trigger profile switch.
# Opening Gnome Settings, we should see profile switching from mSBC / A2DP.
parec --property=media.role=Communication | pacat
</source>
</source>


Line 105: Line 126:
* [https://bbs.archlinux.org/viewtopic.php?id=265878 Multi-user audio sharing with PipeWire - archlinux forum]
* [https://bbs.archlinux.org/viewtopic.php?id=265878 Multi-user audio sharing with PipeWire - archlinux forum]
* [https://gitlab.freedesktop.org/pipewire/pipewire/-/issues/847#note_828707 PipeWire issue 847]
* [https://gitlab.freedesktop.org/pipewire/pipewire/-/issues/847#note_828707 PipeWire issue 847]
* [https://quantum5.ca/2021/06/05/sharing-unix-sockets-between-multiple-users/ Sharing unix socket between multiple users]
:An advanced config that allows to share the unix socket, for even lower latency. Use case was specifically for streaming audio coming from a VM!


Currently PipeWire support sharing through network using Pulse, but auth-anonymous is always turned on (<code>auth-ip-acl</code> not implemented).
Currently PipeWire support sharing through network using Pulse, but auth-anonymous is always turned on (<code>auth-ip-acl</code> not implemented).
Line 115: Line 138:
# LIMITATION: The laptop speaker is advertised by zeroconf, but playback fails. Playback through BT headset is ok though.
# LIMITATION: The laptop speaker is advertised by zeroconf, but playback fails. Playback through BT headset is ok though.
# LIMITATION: auth-ip-acl might not work
# LIMITATION: auth-ip-acl might not work
# LIMITATION: We listen to ipv4 0.0.0.0 only, and use firewall to further restrict access to private network only.
context.exec = [
context.exec = [
{ path = "pactl" args = "load-module module-native-protocol-tcp auth-ip-acl=127.0.0.1" }
{ path = "pactl" args = "load-module module-native-protocol-tcp auth-ip-acl=127.0.0.1 listen=0.0.0.0" }
{ path = "pactl" args = "load-module module-zeroconf-publish" }
{ path = "pactl" args = "load-module module-zeroconf-publish" }
]
]
Line 188: Line 212:
]
]
</source>
</source>

;VMWare VM
* We cannot get audio to work on VMWare VM, under user vbox, although same user can play audio file with eg <code>mplayer</code>.
* Instead we share the pipewire unix socket, as explained [https://quantum5.ca/2021/06/05/sharing-unix-sockets-between-multiple-users/ here].
* Pipewire unix socket for main user is located at {{file|/run/user/1000/pipewire-0}}:
<source lang="bash">
ss -lpn | grep pipewire-0
# u_str LISTEN 0 4096 /run/user/1000/pipewire-0 26175 * 0 users:(("pipewire",pid=2207,fd=3),("systemd",pid=2190,fd=32))
</source>
* We must share this socket with user <code>vbox</code>, but keeping some access control.
* We create a folder {{file|/mnt/pipewire}}, with access for group <code>audio</code>, and we add user <code>vbox</code> to that group.
<source lang="bash">
sudo mkdir /mnt/pipewire
sudo chgrp audio /mnt/pipewire
sudo chmod 750 /mnt/pipewire
sudo gpasswd -a vbox audio # This also likely help to get access to ALSA
</source>
* We add a binding mount point in {{file|fstab}}, that can be mounted by user (option <code>user</code>):
<source lang="bash">
# Pipewire audio sharing (for user vbox). This requires:
# sudo mkdir /mnt/pipewire
# sudo chgrp audio /mnt/pipewire
# sudo chmod 750 /mnt/pipewire
# sudo gpasswd -a vbox audio
/run/user/1000/pipewire-0 /mnt/pipewire/pipewire-0 none bind,rw,user,noauto 0 0
</source>
* We add systemd override to <code>pipewire.socket</code>, to mount/umount that point automatically.
<source lang="bash">
systemctl edit --user pipewire.socket # or edit file '~/.config/systemd/user/pipewire.socket.d/override.conf'
# [Socket]
# ExecStartPost=/bin/mount /mnt/pipewire/pipewire-0
# ExecStopPre=/bin/umount /mnt/pipewire/pipewire-0
</source>
* As user vbox, simply add to {{file|~vbox/.profile}}:
<source lang="bash">
export PIPEWIRE_RUNTIME_DIR=/mnt/pipewire
</source>
: Check ALSA works:
<source lang="bash">
aplay -L
</source>
* Alternatively, we can tell <code>sudo</code> to keep variable <code>PIPEWIRE_RUNTIME_DIR</code>. Edit {{file|/etc/sudoers.d/envkeep}}:
<source lang="bash">
visudo /etc/sudoers.d/envkeep
# Defaults env_keep += "http_proxy https_proxy GREP_OPTIONS DISPLAY XAUTHORITY HOME PIPEWIRE_RUNTIME_DIR"
</source>
* Recent version of pipewire also requires this extra package:
<source lang="bash">
sudo apt install pipewire-alsa
</source>

=== troubleshooting Sony WH-1000XM3 ===
Currently
* SBC_XQ profile works correctly (good audio)
* <code>headset-head-unit-msbc</code> profile works when using the microphone, but there is a audio loopback in the headset (we hear what the mic captures).

Some background info:
* [https://www.freedesktop.org/wiki/Software/PulseAudio/Documentation/User/Bluetooth/] Check this page for background info on Bluetooth profiles, HSP vs HFP.
:* Basically HSP is older than HFP, the latter being more convenient.
:* Audio Gateway are basically the mobile phone itself.
* [https://www.redpill-linpro.com/techblog/2021/05/31/better-bluetooth-headset-audio-with-msbc.html Fix for battery level reporting on Sony WH-1000XM3]
* [https://blog.oblivioncoding.pro/sony-wh-1000mx3-linux-fix/ Pipewire fixes for WH-1000XM3].
:* Here they suggest to set
bluez5.headset-roles = [hsp_hs hsp_ag hfp_hf]
* [https://gitlab.freedesktop.org/pipewire/pipewire/-/issues/604 Pipewire issue 604 related to WH-1000XM3]

=== troubleshooting: no more audio on multi-user ===
After upgrade to pipewire 0.3.64-2 (over 0.3.51-1), we don't have audio anymore on other users (pipewire shared through {{file|/run/user/1000/pipewire-0=}} socket).

<code>mplayer</code> tells us:
AO: [pulse] Init failed: Connection refused
Failed to initialize audio driver 'pulse'
[AO_ALSA] alsa-lib: dlmisc.c:337:(snd_dlobj_cache_get0) Cannot open shared library libasound_module_pcm_pipewire.so (/lib/x86_64-linux-gnu/alsa-lib/libasound_module_pcm_pipewire.so: cannot open shared object file: No such file or directory)
[AO_ALSA] Playback open error: No such device or address
Failed to initialize audio driver 'alsa'

The fix is to install the package {{deb|pipewire-alsa}}:
<source lang="bash">
apt-file search libasound_module_pcm_pipewire.so
# pipewire-alsa: /usr/lib/x86_64-linux-gnu/alsa-lib/libasound_module_pcm_pipewire.so
sudo apt install pipewire-alsa
</source>

=== troubleshooting: no more audio when changing network ===
If using firewall to restrict zeroconf access, make sure to '''edit firewall rule'''.

Latest revision as of 20:16, 12 October 2023

Pipewire is the new sound system on Linux, meant to replace Pulseaudio.

Links

WirePlumber
Nice examples on how to use the lua configuration files.
Link to an nice blog on wireplumber (explanation).

References

Configuration files:

  • /usr/share/pipewire
  • /usr/share/wireplumber

Commands

# View status
systemctl --user status pipewire

# Use PipeWire instead of JACK
pw-jack SOMEAPP

# PipeWire process viewer (quantum usage...)
pw-top

# Setup sinks, sources, audio devices
pw-link
qjackctl         # Graphical tool, leveraging on JACK
qpwgraph         # Alternative, pipewire native

# Get settings
pw-metadata -n settings

# Set settings
pw-metadata -n settings 0 clock.rate 48000
pw-metadata -n settings 0 clock.allowed-rates '[ 48000, 96000, 44100 ]'

# Command line
pw-cli
> info all

# wireplumber
wpctl status

# wireplumber - troubleshooting
wpctl status        # verify the default endpoints
pw-record test.wav  # ... can also set target...
pw-play test.wav
# ... more at https://pipewire.pages.freedesktop.org/wireplumber/testing.html#wireplumber-examples

Configuration

  • Package configuration files are located in /usr/share/pipewire and /usr/share/wireplumber.
  • To change them, copy and edit them in /etc/pipewire (system-wide) or ~/.config/pipewire (local changes).
pipewire-pulse.conf
  • A single section can also be updated through a file in /etc/pipewire/pipewire-pulse.conf.d/ or ~/.config/pipewire/pipewire-pulse.conf.d/
cat /usr/share/pipewire/pipewire-pulse.conf
# # PulseAudio config file for PipeWire version "0.3.50" #
# #
# # Copy and edit this file in /etc/pipewire for system-wide changes
# # or in ~/.config/pipewire for local changes.
# #
# # It is also possible to place a file with an updated section in
# #  for system-wide changes or in
# # ~/.config/pipewire/pipewire-pulse.conf.d/ for local changes.
  • One can see current module configuration with pactl:
pactl list modules      # See active modules and their config

Troubleshooting

Setting and keeping bluetooth profile for headset

We want to use the profile sbc sbc_xq for our BT headset Sony WH-1000XM3.

EASIEST METHOD — Select the profile Gnome Settings / pactl
  • See also [1]
  • Selected profile is persistent on reboot / reconnect.
  • Select the profile in Gnome Settings - Sound, or:
# See available profile and device id with 'pactl list'
pactl set-card-profile bluez_card.38_18_4C_4B_6A_3A a2dp-sink-sbc_xq
Select wanted profile in pipewire / wireplumber
  • (pipewire-media-session) When using pipewire-media-session, the default profile could be selected in bluez-monitor.conf, but this file no longer exists with WirePlumber.
  • (wireplumber) Edit /etc/wireplumber/bluetooth.lua.d/51-bluez-config.lua (or ~/.config/wireplumber/bluetooth.lua.d/51-bluez-config.lua) Archlinux - Pipewire:
bluez_monitor.properties = {
  ["bluez5.enable-sbc-xq"] = true,
  ["bluez5.enable-msbc"] = true,
  ["bluez5.codecs"] = "[sbc sbc_xq]",
}
Profile auto-switch
# This simulates capture throug PulseAudio for telephony, and trigger profile switch.
# Opening Gnome Settings, we should see profile switching from mSBC / A2DP.
parec --property=media.role=Communication | pacat

Crackling / Stuttering audio

This applies in a VM. Not sure these apply when PipeWire is run on the host.

Note that recent PipeWire already supports different auto-config if running in a vm [2].

Enable multi-user / network audio

References
An advanced config that allows to share the unix socket, for even lower latency. Use case was specifically for streaming audio coming from a VM!

Currently PipeWire support sharing through network using Pulse, but auth-anonymous is always turned on (auth-ip-acl not implemented).

  • (pipewire 0.3.50+) On the main user, create file ~/.config/pipewire/pipewire-pulse.conf.d/multi-user-zeroconf.conf
# This config file is a refinement of config file /usr/share/pipewire/pipewire-pulse.conf.

# We listen to network socket to enable multi-user / network playback.
# LIMITATION: The laptop speaker is advertised by zeroconf, but playback fails. Playback through BT headset is ok though.
# LIMITATION: auth-ip-acl might not work
# LIMITATION: We listen to ipv4 0.0.0.0 only, and use firewall to further restrict access to private network only.
context.exec = [
    { path = "pactl"        args = "load-module module-native-protocol-tcp auth-ip-acl=127.0.0.1 listen=0.0.0.0" }
    { path = "pactl"        args = "load-module module-zeroconf-publish" }
]

# # Below, an alternative way for multi-user / network (however we still need zeroconf above)
# # Note that this method doesn't load the native-protocol-tcp module
# pulse.properties = {
#     # the addresses this server listens on
#     server.address = [
#         "unix:native"
#         "tcp:4713"                         # IPv4 and IPv6 on all addresses
#         # "tcp:127.0.0.1:4713"               # IPv4 on a single address
#         #
#         #{ address = "tcp:4713"             # address
#         #  max-clients = 64                 # maximum number of clients
#         #  listen-backlog = 32              # backlog in the server listen queue
#         #  client.access = "restricted"     # permissions for clients
#         #}
#     ]
#     # vm.overrides = {
#     #     pulse.min.quantum = 1024/48000      # 22ms
#     # }
# }
Note: we CANNOT edit pipewire-pulse.conf or any system-level file (like in /etc/pipewire/pipewire-pulse.d) because the TCP socket would already be used, and service would fail to load.
Now, restart pipewire-pulse, and check it works:
# We must restart the SOCKET (this also restart the SERVICE)
systemctl --user restart pipewire-pulse.socket
PULSE_SERVER=tcp:127.0.0.1:4713 pactl info
PULSE_SERVER=unix:/run/user/1000/pulse/native pactl info
  • On the secondary user:
# We can either export this variable
export PULSE_SERVER=127.0.0.1            # OR ...
export PULSE_SERVER=tcp:127.0.0.1:4713
PULSE_SERVER=127.0.0.1 pactl info
Or we can edit ~/.pulse/client.conf like we did with PulseAudio:
default-server = 127.0.0.1
Note: make sure the port is allowed in the firewall as well.
# ################# NOT TESTED #############################
context.modules = [
{   name = libpipewire-module-pulse-tunnel
    args = {
        tunnel.mode = playback
        # Set the remote address to tunnel to
        pulse.server.address = "tcp:192.168.1.126"
        #audio.rate=<sample rate>
        #audio.channels=<number of channels>
        #audio.position=<channel map>
        #node.target=<remote target node>
        stream.props = {
            # extra sink properties
        }
    }
}
]
We can also use the PipeWire Module: Zeroconf Discover, that will automatically create sinks/sources to/from remote PulseAudio servers.
context.modules = [
{   name = libpipewire-module-zeroconf-discover
    args = { }
}
]
VMWare VM
  • We cannot get audio to work on VMWare VM, under user vbox, although same user can play audio file with eg mplayer.
  • Instead we share the pipewire unix socket, as explained here.
  • Pipewire unix socket for main user is located at /run/user/1000/pipewire-0:
ss -lpn | grep pipewire-0
# u_str LISTEN 0  4096  /run/user/1000/pipewire-0 26175  * 0  users:(("pipewire",pid=2207,fd=3),("systemd",pid=2190,fd=32))
  • We must share this socket with user vbox, but keeping some access control.
  • We create a folder /mnt/pipewire, with access for group audio, and we add user vbox to that group.
sudo mkdir /mnt/pipewire
sudo chgrp audio /mnt/pipewire
sudo chmod 750 /mnt/pipewire
sudo gpasswd -a vbox audio       # This also likely help to get access to ALSA
  • We add a binding mount point in fstab, that can be mounted by user (option user):
# Pipewire audio sharing (for user vbox). This requires:
#   sudo mkdir /mnt/pipewire
#   sudo chgrp audio /mnt/pipewire
#   sudo chmod 750 /mnt/pipewire
#   sudo gpasswd -a vbox audio
/run/user/1000/pipewire-0 /mnt/pipewire/pipewire-0 none bind,rw,user,noauto 0 0
  • We add systemd override to pipewire.socket, to mount/umount that point automatically.
systemctl edit --user pipewire.socket # or edit file '~/.config/systemd/user/pipewire.socket.d/override.conf'
# [Socket]
# ExecStartPost=/bin/mount /mnt/pipewire/pipewire-0
# ExecStopPre=/bin/umount /mnt/pipewire/pipewire-0
  • As user vbox, simply add to ~vbox/.profile:
export PIPEWIRE_RUNTIME_DIR=/mnt/pipewire
Check ALSA works:
aplay -L
  • Alternatively, we can tell sudo to keep variable PIPEWIRE_RUNTIME_DIR. Edit /etc/sudoers.d/envkeep:
visudo /etc/sudoers.d/envkeep
# Defaults env_keep += "http_proxy https_proxy GREP_OPTIONS DISPLAY XAUTHORITY HOME PIPEWIRE_RUNTIME_DIR"
  • Recent version of pipewire also requires this extra package:
sudo apt install pipewire-alsa

troubleshooting Sony WH-1000XM3

Currently

  • SBC_XQ profile works correctly (good audio)
  • headset-head-unit-msbc profile works when using the microphone, but there is a audio loopback in the headset (we hear what the mic captures).

Some background info:

  • [3] Check this page for background info on Bluetooth profiles, HSP vs HFP.
  • Basically HSP is older than HFP, the latter being more convenient.
  • Audio Gateway are basically the mobile phone itself.
  • Here they suggest to set
bluez5.headset-roles = [hsp_hs hsp_ag hfp_hf]

troubleshooting: no more audio on multi-user

After upgrade to pipewire 0.3.64-2 (over 0.3.51-1), we don't have audio anymore on other users (pipewire shared through {{{1}}} socket).

mplayer tells us:

AO: [pulse] Init failed: Connection refused
Failed to initialize audio driver 'pulse'
[AO_ALSA] alsa-lib: dlmisc.c:337:(snd_dlobj_cache_get0) Cannot open shared library libasound_module_pcm_pipewire.so (/lib/x86_64-linux-gnu/alsa-lib/libasound_module_pcm_pipewire.so: cannot open shared object file: No such file or  directory)
[AO_ALSA] Playback open error: No such device or address
Failed to initialize audio driver 'alsa'

The fix is to install the package pipewire-alsa:

apt-file search libasound_module_pcm_pipewire.so
# pipewire-alsa: /usr/lib/x86_64-linux-gnu/alsa-lib/libasound_module_pcm_pipewire.so
sudo apt install pipewire-alsa

troubleshooting: no more audio when changing network

If using firewall to restrict zeroconf access, make sure to edit firewall rule.