- under Blog
-related to Linux
So I have a Fiio K5 Pro Audio DAC connected to my desktop, so that I can enjoy high resolution audio. Before writing this post, the set-up is essentially just a simple configuration under PulseAudio.
Old Configuration with PulseAudio
my set-up basically follows ひよこインフラてっく! and Chaekyung: The Fiio K5 Pro Audio DAC+AMP On Linux(ひよこインフラてっく! and Chaekyung 2021).
- install
pulseaudio,pulseaudio-alsa, andpavucontrol modify
/etc/pulse/daemon.confasdefault-sample-format = s32le default-sample-rate = 192000
- Restart the service (or just reboot), It should be working. When using 192kHz, the light on the device becomes yellow.
So what is the problem?
This set-up works pretty well, until libpulse and pulseaudio is updated to 17.0. It is still working with mpc, but mpv and Firefox no longer play videos any more because PulseAudio pipe crashes whenever I do that.
Downgrade both back to 16.1 makes them work again, but I consider this as a temporary solution. Maybe it is the time to migrate to PipeWire.
Migrate to PipeWire
I did some heavy reading on the migration process, as Leo Shen: A Brief Look at Linux’s Audio System(Shen 2020), Alynx Zhou: 从 PulseAudio 到 PipeWire(Zhou 2022), Lilydjwg: 使用 EasyEffects 调整 Bose 音箱的体验(Lilydjwg 2023) and of course ArchWiki: PipeWire(ArchWiki 2017) and GentooWiki: PipeWire(GentooWiki 2024), just in case because Linux's Audio system feels like magic to me.
Anyway, as these posts pointed out,
- Install
pipewire - Install
pipewire-alsato replacepulseaudio-alsa - Install
pipewire-pulseto replacepulseaudio. - Install
wireplumber, which is the default session manager
Now pactl info prints the follow information:
... Server Name: PulseAudio (on PipeWire 1.2.0) Server Version: 15.0.0 Default Sample Specification: float32le 2ch 48000Hz Default Sink: alsa_output.usb-GuangZhou_FiiO_Electronics_Co._Ltd_FiiO_K5_Pro-00.analog-stereo ...
also pactl list short sinks
alsa_output.usb-GuangZhou_FiiO_Electronics_Co._Ltd_FiiO_K5_Pro-00.analog-stereo PipeWire s32le 2ch 48000Hz SUSPENDED
So the good thing is that PipeWire has actually replaced PulseAudio. The bad thing is that the sample specification is float32le 2ch 48000Hz, which is very likely not we want. Before the migration, it is s32le 2ch 192000Hz.
Configuration Structure
From my understanding (as indicated in ArchWiki: PipeWire(ArchWiki 2017) and GentooWiki: PipeWire(GentooWiki 2024)), configurations in /usr/share/pipewire are just examples, and PipeWire will not read them in any way. So the first thing is to copy pipewire.conf under this directory to ~/.config/pipewire/pipewire.conf.
GentooWiki: PipeWire(GentooWiki 2024) also mentions that configuration snippets can be put under ~/.config/pipewire/pipewire.conf.d/, and they have higher priorities and they will override the old values. So I guess the idea is
- copy upstream example configurations (distributed under
/usr/share/pipewire) to~/.config/pipewireperiodically, essentially a manual update process, avoiding "surprises" - Have actual personal configurations under
~/.config/pipewire/pipewire.conf.d/
Now that I understand the configuration structure (hopefully), let's start to actually configure it.
Get the Hardware Specification
This is demonstrated in ArchWiki: PipeWire(ArchWiki 2017).
Basically, first to get the card number of this DAC by aplay -l
card 0: Pro [FiiO K5 Pro], device 0: USB Audio [USB Audio] Subdevices: 1/1 Subdevice #0: subdevice #0
So it is 0, then cat /proc/asound/card0/stream0
GuangZhou FiiO Electronics Co.,Ltd FiiO K5 Pro at xxxxx, high spee : USB Audio
Playback:
Status: Stop
Interface 1
Altset 1
Format: S32_LE
...
Rates: 44100, 48000, 88200, 96000, 176400, 192000, 352800, 384000, 705600, 768000
...
Interface 1
Altset 2
Format: S16_LE
...
Rates: 44100, 48000, 88200, 96000, 176400, 192000, 352800, 384000, 705600, 768000
...
Interface 1
Altset 3
Format: SPECIAL DSD_U32_BE
...
Rates: 44100, 48000, 88200, 96000, 176400, 192000, 352800, 384000, 705600, 768000
...
Then the supported formats are S32_LE, S16_LE and SPECIAL DSD_U32_BE, and supported sample rates are 44100, 48000, 88200, 96000, 176400, 192000, 352800, 384000, 705600, 768000.
Configure Sample Rates
192000kHz is enough for my daily use.
Put the follow snippet in ~/.config/pipewire/pipewire.conf.d/100-fiio-k5-pro.conf
context.properties = { default.clock.rate = 192000 default.clock.allowed-rates = [ 44100 48000 88200 96000 176400 192000 ] }
Now restart the pipewire and pipewire-pulse services, pactl info shows
... Server Name: PulseAudio (on PipeWire 1.2.0) Server Version: 15.0.0 Default Sample Specification: float32le 2ch 192000Hz ... Default Sink: alsa_output.usb-GuangZhou_FiiO_Electronics_Co._Ltd_FiiO_K5_Pro-00.analog-stereo ...
also pactl list short sinks
64 alsa_output.usb-GuangZhou_FiiO_Electronics_Co._Ltd_FiiO_K5_Pro-00.analog-stereo PipeWire s32le 2ch 192000Hz SUSPENDED
So the sample rates seem to be correct now. Note that with this default.clock.allowed-rates configuration PipeWire can stay away with re-sampling, see ArchWiki: PipeWire(ArchWiki 2017).
That is, if you are playing a 96000kHz audio, PipeWire switch the sound card to use native 96000kHz sample rate automatically. This can be checked by using pw-top.
Configure Sample Format
Maybe I misread but this seems to be not needed, according to (Taymans and Lelli 2020).
This post above also mention that we can use cat /proc/asound/card0/pcm0p/sub0/hw_params etc to see what the ALSA card is actually doing.
Next Step?
The only problem so far I encountered is that mpv sound playback is distorted when its volume is above 100%. I'll keep my current set-up for a while to see if anything else goes wrong.