You are not logged in.
Hello, I've been trying to get my Arch installation to dynamically change bit depth and sample rate according to the audio file that's currently playing in order to get bit-perfect audio out on my USB DAC.
After some research, I've found out that PipeWire can do automatic sample rate switching, which I managed to get working by reading the Arch Wiki and the PipeWire Wiki on GitLab. I have followed all the installation steps, substituting all previous audio components (JACK, ALSA and PulseAudio) with the respective PipeWire ones. I also changed my configuration in
~/.config/pipewire/pipewire.conf
in order to allow for all supported sample rates:
## Properties for the DSP configuration.
default.clock.rate = 44100
default.clock.allowed-rates = [ 44100 48000 88200 96000 176400 192000 ]
(I did not paste the rest of the config file, since I did not modify it further).
However, when reading
/proc/asound/card2/pcm0p/sub0/hw_params
when some audio is playing, I can clearly see that the bit depth is always set to 32 bits, while the audio files are not 32 bits but 16 and 24 respectively.
I used soxi to make sure that both the sample rate and the bit depth of the files is correct. For the 16 bit file I get the following soxi output (trimmed useless information out like lyrics):
Input File : 'MACROSS 82-99 - SAILORWAVE II - 01 City Lights (feat. Kamei).flac'
Channels : 2
Sample Rate : 44100
Precision : 16-bit
Duration : 00:02:11.48 = 5798192 samples = 9860.87 CDDA sectors
File Size : 15.5M
Bit Rate : 945k
Sample Encoding: 16-bit FLAC
When this file is playing, the hw_params of my USB DAC contains:
access: MMAP_INTERLEAVED
format: S32_LE
subformat: STD
channels: 2
rate: 44100 (44100/1)
period_size: 512
buffer_size: 32768
Now, when I listen to a 24 bit file:
Input File : '01-01 San Lorenzo.flac'
Channels : 2
Sample Rate : 96000
Precision : 24-bit
Duration : 00:10:21.55 = 59668480 samples ~ 46616 CDDA sectors
File Size : 218M
Bit Rate : 2.80M
Sample Encoding: 24-bit FLAC
I get these hardware parameters:
access: MMAP_INTERLEAVED
format: S32_LE
subformat: STD
channels: 2
rate: 96000 (96000/1)
period_size: 1024
buffer_size: 32768
So as you can see, I get the correct sample rate every time, but the bit depth is always set to 32 bits.
I have looked online extensively and I would not be writing my first post here if I had more resources to look into. I just don't know where to look at this point.
Thank you so much for the help in advance
Last edited by MrVideo (2023-12-06 21:12:34)
I just try not to duck it up
Offline
if you're setting
default.clock.allowed-rates
you definitely want comment out
default.clock.rate
from your pipewire.conf
Offline
It does not seem to change the results. Even if I do comment out that line, I still get 32 bits only.
By the way, I had uncommented that line because of this issue, thinking it may fix my problem, but I was wrong.
I just try not to duck it up
Offline
Using a 32-bit file format for a 24-bit signal will just zero pad the output, surely? I don't think that will adversely affect the sound in the same way as software resampling would.
"The nation-state domesticates the society in the name of capitalism and alienates the community from its natural foundations."
— Democratic Confederalism, Abdullah Öcalan.
Offline
After some research, it would seem like this is the case. There could be some minor noise added to the audio if the specific DAC implementation applies some sort of dithering to upscale/downscale the audio, but nothing noticeable anyway.
However, I've also found out that my DAC cannot output 32 bit audio, reaching a maximum of 24 bit depth, so I would still like to set the output bit depth to 24 bits, just in case. Is there a way to do that?
I just try not to duck it up
Offline
You can enforce the bit depth a certain node/device is opened with in wireplumber config: https://bbs.archlinux.org/viewtopic.php … 1#p2126461
Offline
Thank you so much for this, I managed to set my DAC's bit depth to 24 bits. I'll share my
~/.config/wireplumber/main.lua.d/50-alsa-config.lua
here as well since my solution was a little different.
I had two audio cards, one of which was my microphone, which had the same
alsa.name
property. Since my mic also has an internal audio card which can output audio via USB, both filters would match the DAC and the mic, so I just changed one of the match fields to check for
alsa.card_name
as shown below:
-- Custom DAC rule
-- This sets the bit depth of my M-AUDIO Super DAC to 24 bits manually
{
matches = {
{
{ "alsa.card_name", "matches", "BC USB DAC" },
{ "node.name", "matches", "alsa_output.*" },
}
},
apply_properties = {
["audio.format"] = "S24LE",
},
},
}
I'll go ahead and mark the post as solved now. Thanks again
I just try not to duck it up
Offline
I have also made these settings for my iFi ZEN DAC v2. Thanks you!
I have a question for you: does it keep the 24 bits when sampling 16 bits?
Passionate about minimalistic software, the Linux philosophy, and having fun. SFF and AV enthusiast, APU retro gamer.
Offline
It will simply pad the excess bits with zeroes. but it should keep it that way since you force open the device with 24 bits regardless of your input.
Offline
I see. Thanks!
Passionate about minimalistic software, the Linux philosophy, and having fun. SFF and AV enthusiast, APU retro gamer.
Offline