TL;DR
If you’re not interested in the “story of my life”, go directly to “Tuning PipeWire” section.

I’m not an audiophile, but I spent whole days in the headphones and I like when sound sounds good. I like slight bass boost, which adds this kick to the melody, but won’t overwhelm me after an hour of listening. I like when high tones are clear, but I get annoyed if they’re too strong. And finally, I hate all cracks, hisses or electric circuit noises.

My hardware

I’ve collected a bunch of these over the years 😄

  1. Asus Xonar DX
SamplingSampling rateSNR
24 bit192kHz116 dB

I have it for around 10 years. It’s great. Well supported by Linux. Not supported by Windows 11, as it’s too old.

There’s one thing that irritates me - Intel cards used to automatically detect when headphone was plugged to the front panel and automatically switching audio to it, Xonar do not have it 😢

  1. ROG SupremeFX aka Realtek ALC4080 + Savitech SV3H712 AMP
SamplingSampling rateSNR
32 bit384kHz120 dB

It’s integrated audio on my motherboard. It’s sometimes referred as a “premium audio”. The way it’s installed, pretends USB connection, to avoid any noises that could go via circuit (all digital). To be honest, it’s pretty decent - no cracks or strange noises, but Linux support was 💩 for quite a long time. S/PDIF didn’t work well until I upgraded kernel to 6.5. Even now, it happen that sound card is loaded but it’s not giving any output via S/PDIF until a restart.

  1. FiiO K5 Pro
SamplingSampling rateSNR
32 bit768kHz115 dB

That’s my recent Xmas gift. Works well on Linux and MacOS. Provides more power, than I need with any of my headphones.

Legacy of the PulseAudio

PulseAudio was blamed for high latency and some “non optimal” decisions. Default configuration was enforcing resampling to 44.1 kHz always, where many media now use 48 kHz. This means that audio was resampled most of the time, even when my sound card supports higher sample rates. I wanted to avoid that and it’s well described how to achieve it on the Delightly Linux1 2 blog.

Recent systems switch to new, better PipeWire audio system by default. I’d like to be sure, that I still get the best from my hardware. Not that I could hear the difference… 😃 Just for the sake of doing it the right way!

I’ve been looking for a good description on “how to tune it” and I failed. Arch’s Wiki3 is usually a good source, but there’s no direct description regarding quality. I also found some Reddit posts 4 5, but nothing step by step. Let me share what I found.

Tuning PipeWire

PipeWire runs as a user-space service and it can use configs from per-system or per-user configs. That’s how it look like:

  1. /usr/share/pipewire - default configs,
  2. /etc/pipewire - system wide configs, to override defaults,
  3. ~/.config/pipewire - per-use configs, can use:
  • full file names like ~/.config/pipewire/pipewire.conf
  • subsection replacements ~/.config/pipewire/pipewire.conf.d/
  • (same pattern works in /etc/pipewire too)

It’s easier to play in user’s home dir, but I prefer to have it in the system space. As I found quite a lot of differences in those config files between Ubuntu versions, I like “subsection” approach as it allows to overwrite only the parts I want, leaving rest on defaults.

Default parameters

After system installation my /etc/pipewire was just empty. I was wondering where can I check the defaults and I found it, under:

Check default configs
ls -1 /usr/share/pipewire/
client.conf
client-rt.conf
filter-chain
filter-chain.conf
jack.conf
minimal.conf
pipewire-aes67.conf
pipewire-avb.conf
pipewire.conf
pipewire-pulse.conf

It’s a good source of documentation and examples.

Set client resample quality

When resampling happens, let it happen with the best possible quality. Look for resample.quality in the client.conf file, uncomment it and set to 10:

Configure resampling
mkdir -p ~/.config/pipewire/client.conf.d

cat <<EOF > ~/.config/pipewire/client.conf.d/resample-quality.conf
stream.properties = {
    resample.quality      = 10
}
EOF

And another one for Pulse Audio:

Configure resampling
mkdir -p ~/.config/pipewire/pipewire-pulse.conf.d/

cat <<EOF > ~/.config/pipewire/pipewire-pulse.conf.d/resample-quality.conf
stream.properties = {
    resample.quality      = 10
}
EOF

DSP configuration

That’s my configuration I use:

Configure DSP
mkdir -p ~/.config/pipewire/pipewire.conf.d

cat <<EOF > ~/.config/pipewire/pipewire.conf.d/dsp-defaults.conf
context.properties = {
    ## Properties for the DSP configuration.
    default.clock.rate          = 48000
    default.clock.allowed-rates = [ 44100 48000 88200 96000 176400 192000 352800 384000 705600 768000 ]
    #default.clock.quantum       = 1024
    default.clock.min-quantum   = 32
    default.clock.max-quantum   = 8192
    #default.clock.quantum-limit = 8192
}
EOF

Let see what happen here:

  1. default.clock.rate - PipeWire has one global sample rate used in the processing pipeline. All signals are converted to this sample rate and then converted to the sample rate of the device. That said, if you set it too low, it won’t use capabilities of your device. If you set it higher that the sources you use, it will be resampling to higher frequencies, which will just waste CPU time.

  2. default.clock.allowed-rates - This one lists the frequencies that are supported by your sound device. By default it’s set to [ 48000 ], which quite often will resample audio. To allow use of other frequencies, I had to manually list them.

Alsa monitor config

Theoretically: it specifies the supported input/output audio formats for ALSA devices. In this case, it is set to “all,” indicating that PipeWire should support all available output audio formats. This includes various audio formats such as PCM (Pulse Code Modulation), AC3 (Dolby Digital), DTS (Digital Theater Systems), and more.

Configure Alsa
#cat << EOF | sudo tee -a /etc/pipewire/alsa-monitor.conf
cat <<EOF > ~/.config/pipewire/alsa-monitor.conf
[alsa-monitor]
output_formats = all
input_formats = all
EOF

Info

I’m having hard time to recall where I found this and why I needed it? I will updated when I figure it out.

Reload PipeWire configuration

To reload configuration files after the change, you can restart PipeWire like this:

Restart PipeWire
systemctl --user restart pipewire.service
systemctl --user restart pipewire-pulse.service

Warning

Some applications (eg. Spotify) might not detect new sinks and will stay “muted”. Restart them to get the sound back.

For testing, command line tools like mpv or aplay are more reliable.

How to check if it works?

Warning

Restart PipeWire first!

We can check specific files effective configuration by calling:

Check config
$ pw-config -n pipewire.conf list
...
],
  "config.name.d": "pipewire.conf.d",
  "override.1.0.config.path": "/home/timor/.config/pipewire/pipewire.conf.d/dsp-defaults.conf",
  "override.1.0.config.name": "dsp-defaults.conf",
  "override.1.0.context.properties": {
    ## Properties for the DSP configuration.
    default.clock.rate          = 48000
    default.clock.allowed-rates = [ 44100 48000 88200 96000 176400 192000 352800 384000 705600 768000 ]
    #default.clock.quantum       = 1024
    default.clock.min-quantum   = 32
    default.clock.max-quantum   = 8192
    #default.clock.quantum-limit = 8192
}

or

Check config
pw-config -n client.conf list
...
  "config.name.d": "client.conf.d",
  "override.1.0.config.path": "/home/timor/.config/pipewire/client.conf.d/resample-quality.conf",
  "override.1.0.config.name": "resample-quality.conf",
  "override.1.0.stream.properties": {
    resample.quality      = 10
}

Check config
pw-config -n pipewire-pulse.conf list
...
  "config.name.d": "pipewire-pulse.conf.d",
  "override.1.0.config.path": "/home/timor/.config/pipewire/pipewire-pulse.conf.d/resample-quality.conf",
  "override.1.0.config.name": "resample-quality.conf",
  "override.1.0.stream.properties": {
    resample.quality      = 10
}

If all looks good, we should check if it’s working as we want by calling pw-top:

Alternatively we can watch directly Alsa’s outputs:

Check raw Alsa's hardware params
watch -n1 cat /proc/asound/card*/pcm*/sub0/hw_params

Is it wroth it?

Probably not.

One difference I found between PipeWire and PulseAudio is some kind of delay, before the sink is closed. For example, if I start Spotify which will create sink with 44.1 kHz sampling rate and enable Youtube - it will keep 44.1 kHz despite Youtube working with 48 kHz. You’re usually not listening two sources at the same time, but it behaves the same even if I shut down Spotify and start Youtube “too fast”. It’s at least bunch of seconds, I didn’t found if it’s configurable yet.

With PulseAudio, it was instant. When I was checking PCM outputs, they were just switching instantly. With PipeWire, if I won’t keep OS silent for a while, it might start with much lower sample rates. You know, 44.1 kHz is more than I can hear, but it’s just disappointing and feels like a regression.

I can see also other “silly” behaviors of PipeWire. At lest 2 of my cards support 32 bit sampling, but even if source use 32bit, Alsa usually use just 24. Again, it’s nothing I could hear, but if hardware is capable of more, why not to use it?

Those are things I feel missing right now, but maybe it’s something that might be solved with more configs 😉

I can’t really hear the difference. I stayed with 192 kHz sampling rate as a default for few days. I felt rather tired, when listening too long and I couldn’t name what was the reason. 95% of the audio I listen comes from 2 sources:

  • Spotify (44.1 kHz)
  • Youtube (48 kHz)

For me this means that the default of 48 kHz as a sampling rate is just fine. Spotify gets resampled up, which should be less harmful than resampling to the lower frequencies. That’s why I stayed there.

TODO

  1. Force Alsa to use 32 bit sampling by default. My cards support it but I only see S24LE going to the output. Same like with sampling rate, why to convert if I should be able to just drop it on the hardware? 6

  2. I heard about Harman curve and I’d like to play with it. I have relatively good headphones: Bayerdynamic DT 990 Pro 250 Ohm. They sound quite well and don’t make me feel tired - I guess it’s a matter of open design. Still I think they’re strengthening higher frequencies. I’d like to use AutoEQ profile, to setup my headphones according to the “recommended” way. But I don’t like to do it with external equalizer app - PipeWire should be able to handle that, I just don’t know yet how :) 7 8

  3. I’ve read some day that the more I age, the less frequencies I can hear. Which means my kids might be hearing some noises which I won’t be able. There are even Ringtones for teenagers that rely on this phenomena. Teachers can’t hear them. 9 10 11