PipeWire on FreeBSD: Audio System Review
Audio on FreeBSD has a complicated history. The operating system ships with OSS (Open Sound System), a kernel-level audio system that works well for basic use but lacks the session management, per-application routing, and network audio features that modern desktops expect. PulseAudio filled some of those gaps but brought its own problems. PipeWire is the latest contender, promising to unify audio and video streaming under one framework while remaining compatible with both PulseAudio and JACK applications.
On FreeBSD, PipeWire is functional and improving rapidly. This review covers the practical state of PipeWire on FreeBSD today: installation, configuration, compatibility with existing audio applications, the Bluetooth situation, and how it compares to sticking with PulseAudio or native OSS.
Understanding the Audio Stack
Before diving into PipeWire specifics, it helps to understand FreeBSD's audio layers:
- Kernel (OSS): FreeBSD's kernel provides OSS devices (
/dev/dsp,/dev/mixer). Applications can write audio directly to these devices. This is the foundation layer. - Sound daemon: PulseAudio, PipeWire, or sndiod sits above the kernel, providing mixing, routing, and per-application volume control.
- Application APIs: Applications use ALSA (via the FreeBSD ALSA compatibility layer), PulseAudio client libraries, JACK, or OSS directly.
PipeWire replaces the sound daemon layer and provides compatibility shims for PulseAudio and JACK client applications, meaning applications written for either API work without modification.
Installation
PipeWire installs from packages:
shpkg install pipewire wireplumber
The wireplumber package is PipeWire's session manager, responsible for policy decisions like which audio device to use by default, how to handle device hotplugging, and routing rules.
Basic Setup
PipeWire on FreeBSD runs as a user service. The simplest setup:
sh# Create the XDG runtime directory if it does not exist mkdir -p /tmp/runtime-$(whoami) export XDG_RUNTIME_DIR=/tmp/runtime-$(whoami)
For desktop environments (GNOME, KDE, XFCE), PipeWire typically starts through D-Bus activation or XDG autostart entries. Ensure D-Bus is running:
shsysrc dbus_enable="YES" service dbus start
Replacing PulseAudio
If you currently run PulseAudio:
sh# Remove PulseAudio (or just stop it) pkg remove pulseaudio # Or pulseaudio --kill # Install PipeWire's PulseAudio compatibility pkg install pipewire # PipeWire includes pipewire-pulse, which provides a PulseAudio-compatible server # Applications using PulseAudio APIs will connect to PipeWire transparently
Start PipeWire with PulseAudio compatibility:
sh# Start PipeWire and its PulseAudio layer pipewire & pipewire-pulse & wireplumber &
For autostart on login, create an XDG autostart entry:
shmkdir -p ~/.config/autostart cat > ~/.config/autostart/pipewire.desktop << 'AUTOSTART' [Desktop Entry] Type=Application Name=PipeWire Exec=pipewire Hidden=false NoDisplay=true AUTOSTART cat > ~/.config/autostart/pipewire-pulse.desktop << 'AUTOSTART' [Desktop Entry] Type=Application Name=PipeWire PulseAudio Exec=pipewire-pulse Hidden=false NoDisplay=true AUTOSTART cat > ~/.config/autostart/wireplumber.desktop << 'AUTOSTART' [Desktop Entry] Type=Application Name=WirePlumber Exec=wireplumber Hidden=false NoDisplay=true AUTOSTART
Verifying the Setup
sh# Check if PipeWire is running pw-cli info 0 # Check if PulseAudio clients see PipeWire pactl info | grep "Server Name" # Should show: Server Name: PulseAudio (on PipeWire x.y.z) # List audio devices pw-cli list-objects | grep node.name # Check audio output speaker-test -c 2 # Test stereo output
Configuration
PipeWire's configuration lives in two locations:
sh# System-wide defaults (do not edit) /usr/local/share/pipewire/ # User overrides ~/.config/pipewire/
To customize, copy the relevant file to your user config directory and modify it:
sh# Copy the main PipeWire config mkdir -p ~/.config/pipewire cp /usr/local/share/pipewire/pipewire.conf ~/.config/pipewire/ # Copy PulseAudio compatibility config cp /usr/local/share/pipewire/pipewire-pulse.conf ~/.config/pipewire/
Sample Rate and Buffer Size
For general desktop use, the defaults work well. For audio production or low-latency needs:
sh# In ~/.config/pipewire/pipewire.conf # Under context.properties: context.properties = { default.clock.rate = 48000 default.clock.allowed-rates = [ 44100 48000 96000 ] default.clock.quantum = 1024 default.clock.min-quantum = 32 default.clock.max-quantum = 2048 }
Lower quantum values mean lower latency but higher CPU usage and more potential for audio glitches. For desktop use, 1024 is safe. For music production, you might go as low as 64 or 128.
Per-Application Routing
WirePlumber handles routing rules. You can create custom rules:
sh# Create a WirePlumber rule mkdir -p ~/.config/wireplumber/main.lua.d cat > ~/.config/wireplumber/main.lua.d/51-custom-routing.lua << 'ROUTING' -- Route Firefox to headphones when available rule = { matches = { { { "application.name", "equals", "Firefox" }, }, }, apply_properties = { ["node.target"] = "alsa_output.usb-headphones", }, } table.insert(alsa_monitor.rules, rule) ROUTING
Volume Control
PipeWire works with standard PulseAudio volume control tools:
sh# Command line volume control pactl set-sink-volume @DEFAULT_SINK@ 80% pactl set-sink-mute @DEFAULT_SINK@ toggle # GUI volume control pkg install pavucontrol # PulseAudio Volume Control (works with PipeWire)
Desktop environments integrate volume control through their panel applets. KDE, GNOME, and XFCE panels all detect PipeWire through its PulseAudio compatibility layer.
JACK Compatibility
PipeWire's JACK compatibility is one of its strongest features, particularly relevant for audio production on FreeBSD.
How It Works
PipeWire provides a JACK client library that redirects JACK API calls to PipeWire. Applications linked against JACK connect to PipeWire's graph instead of a separate JACK server:
sh# Install JACK compatibility pkg install pipewire # Includes JACK compatibility libraries # Verify JACK applications can connect pw-jack jack_lsp # List JACK ports through PipeWire
Using JACK Applications
sh# Run a JACK application through PipeWire pw-jack ardour6 # Digital audio workstation pw-jack guitarix # Guitar effects processor pw-jack hydrogen # Drum machine # The pw-jack wrapper sets library paths so the application # uses PipeWire's JACK libraries instead of the real JACK server
JACK and PulseAudio Applications Simultaneously
This is PipeWire's party trick. Under a traditional JACK server, PulseAudio applications cannot access audio while JACK is running. PipeWire handles both simultaneously:
sh# All of these can run at the same time: # - Firefox playing YouTube (PulseAudio client) # - Ardour recording audio (JACK client) # - mpv playing a video (PulseAudio or JACK client) # - System notification sounds (PulseAudio client) # PipeWire routes all of them through the same audio graph
This is a genuine improvement over the traditional FreeBSD audio stack where running JACK meant giving up desktop audio.
Limitations
- Some JACK applications may detect that they are not running on a real JACK server and behave differently
- JACK transport synchronization works but may have subtle timing differences
- Very low-latency JACK workflows (sub-5ms) may perform slightly worse than a dedicated JACK server
Bluetooth Audio
Bluetooth audio is PipeWire's most challenging area on FreeBSD, because Bluetooth itself has limited support on the platform.
Current State
FreeBSD's Bluetooth stack supports basic audio profiles (A2DP, HSP/HFP) through the bluetooth and virtual_oss infrastructure. PipeWire can work with Bluetooth audio devices, but the integration is less seamless than on Linux:
sh# Basic Bluetooth setup on FreeBSD kldload ng_ubt # Load Bluetooth USB driver sysrc hcsecd_enable="YES" sysrc sdpd_enable="YES" # Pair a Bluetooth audio device hccontrol inquiry # Discover devices hccontrol create_connection <device_address>
PipeWire's Bluetooth module (libspa-bluetooth) handles the audio codec negotiation (SBC, AAC, aptX, LDAC). On FreeBSD, codec support depends on available libraries:
sh# Install codec support pkg install libfreeaptx libldac sbc
Practical Reality
Bluetooth audio through PipeWire on FreeBSD works for basic listening (A2DP profile with SBC or AAC codecs). Voice calling through Bluetooth headsets (HFP profile) is more problematic. The experience is not as plug-and-play as on Linux, where BlueZ and PipeWire have tight integration.
If Bluetooth audio is critical for your workflow, this is an area where FreeBSD lags behind Linux regardless of which audio daemon you choose.
PipeWire vs PulseAudio on FreeBSD
PulseAudio has been available on FreeBSD for years and is well-tested:
| Aspect | PipeWire | PulseAudio |
|--------|----------|------------|
| JACK compatibility | Built-in | Requires separate JACK server |
| Latency | Lower achievable | Higher minimum |
| Configuration | Lua-based (WirePlumber) | Module-based |
| CPU usage | Slightly lower | Slightly higher |
| Bluetooth | Improving | Mature via modules |
| FreeBSD stability | Good, improving | Very stable |
| Video capture | Yes (camera routing) | No |
| Ecosystem | Growing | Mature |
For desktop use without audio production needs, PulseAudio remains a safe and stable choice on FreeBSD. PipeWire is the better choice if you need JACK compatibility or plan to do any audio/video production work.
PipeWire vs OSS (Native FreeBSD Audio)
FreeBSD's native OSS is the simplest option:
sh# OSS just works out of the box # Load the sound driver kldload snd_hda # Check devices cat /dev/sndstat # Set default device sysctl hw.snd.default_unit=0 # Per-application volume via mixer mixer vol 80
OSS advantages:
- Zero configuration needed
- Kernel-level, no userspace daemon
- Lowest possible latency
- Perfect reliability
OSS limitations:
- No per-application volume control (single mixer)
- No automatic device switching (e.g., when plugging in headphones)
- No network audio
- Limited application compatibility (some apps expect PulseAudio)
- No Bluetooth audio support
For servers or minimal systems, OSS is ideal. For desktops, especially those running GNOME or KDE which expect PulseAudio-compatible audio, PipeWire or PulseAudio is needed.
Troubleshooting
Common PipeWire issues on FreeBSD and their solutions:
No Sound Output
sh# Check if PipeWire is running pw-cli info 0 # Check if the correct sink is selected pactl list sinks short # Set the default sink pactl set-default-sink <sink-name> # Check if the OSS device is accessible cat /dev/sndstat
Audio Crackling or Glitches
sh# Increase the buffer size # In ~/.config/pipewire/pipewire.conf # Set default.clock.quantum to 2048 # Check for IRQ conflicts vmstat -i | grep snd
Applications Cannot Find Audio
sh# Ensure PipeWire's PulseAudio layer is running pipewire-pulse & # Check the PulseAudio socket ls -la /tmp/runtime-$(whoami)/pulse/ # Some applications need the PULSE_SERVER environment variable export PULSE_SERVER=unix:/tmp/runtime-$(whoami)/pulse/native
WirePlumber Crashes
sh# Check WirePlumber logs journalctl --user -u wireplumber # If using systemd-compatible logging # Or check ~/.local/state/wireplumber/wireplumber.log # Reset WirePlumber state rm -rf ~/.local/state/wireplumber/ wireplumber &
Verdict
PipeWire on FreeBSD has reached a point where it is a legitimate choice for desktop audio. The PulseAudio compatibility layer works well enough that existing applications function without changes. The JACK compatibility is genuinely useful for audio production workflows, eliminating the traditional pain of running JACK alongside desktop audio.
The setup requires more manual configuration than on Linux, where distributions handle PipeWire integration automatically. Bluetooth audio remains a weak point, though this is more a FreeBSD platform limitation than a PipeWire limitation.
For FreeBSD desktop users, PipeWire is worth adopting if you need JACK compatibility or want to future-proof your audio setup. For users who are happy with PulseAudio and do not need JACK, the migration offers modest benefits. For server environments, stick with OSS.
Rating: 7.5/10 -- A capable and improving audio system on FreeBSD with real advantages over PulseAudio. Points deducted for manual setup overhead, Bluetooth limitations, and the platform gap versus Linux.
Frequently Asked Questions
Does PipeWire replace OSS on FreeBSD?
No. PipeWire runs on top of OSS. The kernel's OSS drivers still handle the actual hardware. PipeWire provides the session management, mixing, and application API compatibility layer above it.
Can I run PipeWire and PulseAudio at the same time?
No. PipeWire's PulseAudio compatibility layer (pipewire-pulse) replaces the PulseAudio server. Applications connect to PipeWire thinking it is PulseAudio. Only one can run at a time.
Does PipeWire support USB audio interfaces on FreeBSD?
Yes. USB audio devices that work with FreeBSD's OSS (most class-compliant USB audio devices) work with PipeWire. They appear as PipeWire nodes and can be selected as input/output devices.
Is PipeWire stable enough for daily use on FreeBSD?
For desktop audio (music, video, voice calls), yes. For professional audio production, it is functional but you should test your specific workflow. The stability has improved significantly in recent releases.
How do I switch back to PulseAudio from PipeWire?
Stop PipeWire and its components, then start PulseAudio:
shkillall pipewire pipewire-pulse wireplumber pkg install pulseaudio pulseaudio --start
Does PipeWire handle screen sharing on FreeBSD?
Yes. PipeWire provides the video capture infrastructure that xdg-desktop-portal uses for screen sharing in browsers and applications. This works with both GNOME and KDE on FreeBSD.