dasdoing
Major Contributor
pulseaudio can't benefit from "threadirqs" kernel parameter? that's what jack users use for realtime
Thank you for your suggestions. I have updated my Pulseaudio config with your settings (I'm on Ubuntu 20.04).
Maybe it can, I haven't tried that. My linux audio journey is still underway, I'm willing to try anything.
PS: my original goal was to get audio to play smoothly without distortion or glitches at all bit rates. That mission accomplished, but at the expense of high (200 ms) latency. I don't really need low latency since I'm not a gamer, but low latency is nice to have if the price (in complexity & performance) isn't too high. This could be possible with a different approach, running the kernel with the threadirqs parameter and increasing the IRQ priority of the sound card. I have not yet explored this.
avoid-resample = true
First, you spelled it wrong. It's this:Any reason whywould not work ony my Manjaro Stable install?Code:avoid-resample = true
Thanks for the reply, I don't have my home PC in front of me (thus the typo), but I do know I'm on version 15.x of Pulse Audio, and I'm sure I had the coding correct in the .conf file. and it's still didn't work.First, you spelled it wrong. It's this:
avoid-resampling = true
NOT this
avoid-resample = true
Second, this avoid-resampling option doesn't exist in older versions of Pulseaudio.
#!/usr/bin/env bash
# Set Pulseaudio bit rates (and optionally bit depth)
if [ "$1" == "-h" ]
then
echo "audioSet RATE1 RATE2 BITDEPTH FRAGCOUNT FRAGMSEC"
echo "audioSet -f RATE"
exit 1
fi
# Fixed rate mode, for forcing a single sampling rate
if [ "$1" == "-f" ]
then
br1="$2"
br2="$2"
bd="float32le"
fc="4"
fm="50"
ars="false"
else
ars="true"
if [ -z "$1" ]
then
br1="44100"
else
br1="$1"
fi
if [ -z "$2" ]
then
br2="48000"
else
br2="$2"
fi
if [ -z "$3" ]
then
bd="float32le"
else
bd="$3"
fi
if [ -z "$4" ]
then
fc="4"
else
fc="$4"
fi
if [ -z "$5" ]
then
fm="50"
else
fm="$5"
fi
fi
echo "Audio set: rate 1 $br1, rate 2 $br2, avoid-rs $ars, bit depth $bd fragment count $fc fragment msec $fm"
sed -i "/^default-sample-rate/c\default-sample-rate = $br1" /etc/pulse/daemon.conf
sed -i "/^alternate-sample-rate/c\alternate-sample-rate = $br2" /etc/pulse/daemon.conf
sed -i "/^default-sample-format/c\default-sample-format = $bd" /etc/pulse/daemon.conf
sed -i "/^default-fragments/c\default-fragments = $fc" /etc/pulse/daemon.conf
sed -i "/^default-fragment-size-msec/c\default-fragment-size-msec = $fm" /etc/pulse/daemon.conf
sed -i "/^avoid-resampling/c\avoid-resampling = $ars" /etc/pulse/daemon.conf
# Kill pulseaudio; it will restart automatically
pulseaudio -k
You know something else that is wonky, is I have my /etc/pulse/daemon.conf file properly modified to bit rate of s24le, yet in the hwparams and in the sink output it states floate32LE. In fact, I've never seen it report s24le from hwparams.Another possibility: while "avoid-resampling" does exactly what it says (makes PulseAudio avoid resampling), they use the word "avoid" for good reason. Pulseaudio still has only a single sampling rate for all apps playing audio. And it cannot change the sampling rate while audio is playing.
For example: suppose you start playing an 88.2 kHz audio file. With this setting turned on, Pulseaudio will try to set the system rate to 88.2 to match your file, to avoid resampling. But if some other process is already playing audio, like maybe you have a browser tab open to YouTube which uses 48 kHz, then Pulseaudio can't change the rate. It can change the system sampling rate ONLY when nothing is already playing.
Here's a script I use. It automates cleanly killing, reconfiguring, restarting Pulseaudio with various settings. This has the beneficial side-effect of terminating any stale or zombie audio streams that might be locking the sample rate from changing. If the system wants you to be root in order to run this script, and you get tired of typing in your password, you can set the file permissions of "/etc/pulse/daemon.conf" accordingly. Like assign it to one of your user groups and set mode to 664.
Code:#!/usr/bin/env bash # Set Pulseaudio bit rates (and optionally bit depth) if [ "$1" == "-h" ] then echo "audioSet RATE1 RATE2 BITDEPTH FRAGCOUNT FRAGMSEC" echo "audioSet -f RATE" exit 1 fi # Fixed rate mode, for forcing a single sampling rate if [ "$1" == "-f" ] then br1="$2" br2="$2" bd="float32le" fc="4" fm="50" ars="false" else ars="true" if [ -z "$1" ] then br1="44100" else br1="$1" fi if [ -z "$2" ] then br2="48000" else br2="$2" fi if [ -z "$3" ] then bd="float32le" else bd="$3" fi if [ -z "$4" ] then fc="4" else fc="$4" fi if [ -z "$5" ] then fm="50" else fm="$5" fi fi echo "Audio set: rate 1 $br1, rate 2 $br2, avoid-rs $ars, bit depth $bd fragment count $fc fragment msec $fm" sed -i "/^default-sample-rate/c\default-sample-rate = $br1" /etc/pulse/daemon.conf sed -i "/^alternate-sample-rate/c\alternate-sample-rate = $br2" /etc/pulse/daemon.conf sed -i "/^default-sample-format/c\default-sample-format = $bd" /etc/pulse/daemon.conf sed -i "/^default-fragments/c\default-fragments = $fc" /etc/pulse/daemon.conf sed -i "/^default-fragment-size-msec/c\default-fragment-size-msec = $fm" /etc/pulse/daemon.conf sed -i "/^avoid-resampling/c\avoid-resampling = $ars" /etc/pulse/daemon.conf # Kill pulseaudio; it will restart automatically pulseaudio -k
Good to know that you're experiencing the same thing in regards to bit depth. I won't waste time trying to chase that down.Well, s24le / s32le is not a bit rate, but a bit depth. So it doesn't matter as much, just set a value of at least 24 bits.
That said, I've seen the exact same thing. In years past, Pulseaudio used whatever I configured. But for the past year or two, it always uses s32le no matter what I configure.
Nice job, great to see we still have some active Linux guys on site.Here's a script I use.
(sorry if that's getting too technical)What's more important, avoid-reasampling does indeed work.
your stream --> remap sink --> remapped stream --> alsa sink
sinks:
* index: 0
name: <alsa_output.usb-RME_ADI-2_Pro__57760455__FC0F29710C736C8-00.analog-stereo>
state: RUNNING
sample spec: s32le 2ch 44100Hz
index: 6
name: <Channels_Switcheroo>
state: RUNNING
sample spec: float32le 2ch 44100Hz
sink inputs:
index: 32
state: RUNNING
sink: 0 <alsa_output.usb-RME_ADI-2_Pro__57760455__FC0F29710C736C8-00.analog-stereo>
sample spec: float32le 2ch 44100Hz
media.name = "Remapped Stream"
index: 37
state: RUNNING
sink: 6 <Channels_Switcheroo>
sample spec: s16le 2ch 96000Hz
media.name = "sin_220.96.flac - mpv"
application.name = "mpv Media Player"
if (!s->reconfigure)
return;
I'm not surprised. Pulse can change the system sampling rate for a stream only when there is nothing playing on it. So if some other module gets in there it can lock the sampling rate.... I'm afraid it might not be true [avoiding resampling] when additional modules are involved. ...
... if your sink-input is connected directly to alsa sink then the switching of the sample rate will work and if it is connected to some other sink then it won't.
Ah, but that's not exactly what I meant Yes, if the module is staying active then it will lock the sample rate, but if I don't play anything then it should get suspended and release the lock. Here I play mpv through remap sink, alsa sink is locked to 44100:I'm not surprised. Pulse can change the system sampling rate for a stream only when there is nothing playing on it. So if some other module gets in there it can lock the sampling rate.
sinks:
* index: 0
name: <alsa_output.usb-RME_ADI-2_Pro__57760455__FC0F29710C736C8-00.analog-stereo>
state: RUNNING
sample spec: s32le 2ch 44100Hz
index: 1
name: <Channels_Switcheroo>
state: RUNNING
sample spec: float32le 2ch 44100Hz
sink-inputs:
index: 0
state: RUNNING
sink: 0 <alsa_output.usb-RME_ADI-2_Pro__57760455__FC0F29710C736C8-00.analog-stereo>
sample spec: float32le 2ch 44100Hz
media.name = "Remapped Stream"
index: 3
state: RUNNING
sink: 1 <Channels_Switcheroo>
sample spec: s16le 2ch 96000Hz
media.name = "sin_220.96.flac - mpv"
application.name = "mpv Media Player"
sinks:
* index: 0
name: <alsa_output.usb-RME_ADI-2_Pro__57760455__FC0F29710C736C8-00.analog-stereo>
state: SUSPENDED
sample spec: s32le 2ch 44100Hz
index: 1
name: <Channels_Switcheroo>
state: SUSPENDED
sample spec: float32le 2ch 44100Hz
sink-inputs:
index: 0
state: CORKED
sink: 0 <alsa_output.usb-RME_ADI-2_Pro__57760455__FC0F29710C736C8-00.analog-stereo>
sample spec: float32le 2ch 44100Hz
media.name = "Remapped Stream"
sinks:
* index: 0
name: <alsa_output.usb-RME_ADI-2_Pro__57760455__FC0F29710C736C8-00.analog-stereo>
state: RUNNING
sample spec: s32le 2ch 96000Hz
index: 1
name: <Channels_Switcheroo>
state: SUSPENDED
sample spec: float32le 2ch 44100Hz
sink-inputs
index: 0
state: CORKED
sink: 0 <alsa_output.usb-RME_ADI-2_Pro__57760455__FC0F29710C736C8-00.analog-stereo>
sample spec: float32le 2ch 44100Hz
media.name = "Remapped Stream"
index: 4
state: RUNNING
sink: 0 <alsa_output.usb-RME_ADI-2_Pro__57760455__FC0F29710C736C8-00.analog-stereo>
sample spec: s16le 2ch 96000Hz
application.name = "paplay"
media.name = "sin_220.96.flac"
pacmd list-sink-inputs
clued me in to look at the LADSPA module running at boot. In the end my problem was two fold.~/.config/pulse/default.pa
.### BEGIN: Equalized audio configuration
### Generated from: pulseaudio-equalizer
#.nofail
#load-module module-ladspa-sink sink_name=ladspa_output.mbeq_1197.mbeq sink_master=alsa_output.pci-0000_00_1b.0.analog-stereo plugin=mbeq_1197 label=mbeq control=0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0
#set-default-sink ladspa_output.mbeq_1197.mbeq
#set-sink-mute alsa_output.pci-0000_00_1b.0.analog-stereo 0
#.fail
/etc/pulse/daemon.conf
then ran pulseaudo -k
. Voila! Now I was at least seeing the proper sample rate in watch -n1 cat /proc/asound/card2/pcm0p/sub0/hw_params
. However, the bit depth was still returning s32le, but @MRC01 mentioned he had the same thing recently as well, so I'm thinking success..until I tried to record in 32bit Float and 96000 in Audacity, and well, back to 16/44.1 downsampling from watch -n1 cat /proc/asound/card0/pcm0c/sub0/hw_params
. Back to the drawing board...# Create a Pulseaudio stream that "tees" the main audio stream, so we can record it without gaps
strnam="my.audio.stream"
pactl load-module module-combine-sink sink_name="$strnam" \
slaves=alsa_output.pci-0000_04_02.0.iec958-stereo \
sink_properties=device.description="$strnam"
# Start capturing the stream
parec -v -d "$strnam".monitor --fix-format --fix-rate --fix-channels "$filnam"
Pulseaudio can have different sinks at different sample rates. And you can create your own named sinks and make apps use them instead of the default. I don't know whether that would work but it seems worth a try.
For example, I use this to capture bit-perfect audio that is playing. The first pactl command creates a named stream, the second parec command captures the raw audio data to a file on disk. Not exactly what you want to do, but the example commands might be helpful. You can do a lot with pactl and related commands.
Code:# Create a Pulseaudio stream that "tees" the main audio stream, so we can record it without gaps strnam="my.audio.stream" pactl load-module module-combine-sink sink_name="$strnam" \ slaves=alsa_output.pci-0000_04_02.0.iec958-stereo \ sink_properties=device.description="$strnam" # Start capturing the stream parec -v -d "$strnam".monitor --fix-format --fix-rate --fix-channels "$filnam"