Topic: Linux latency with pipewire?

Hi all!

I just downloaded the pianoteq demo.  Liking the sound a lot and really interested to play more to see if I can improve my pedaling for example.

But, usual story now I'm immediately obsessed with latency ;-)

This is what I've done so far:

- First I made sure I'm in group `audio` and that my `/etc/security/limits.conf` is configured per `README_LINUX.txt`.  That got rid of warnings on the command line about that so I'm sure that worked.
- Checked the performance tab.  All seems good: performance index 127, orange audio load line pinned low at the bottom of the chart, blue performance steady and pinned at the top of the chart.  Just using standard LTS 6.1 kernel, not low latency kernel.  Because of this I've not attempted to disable CPU frequency throttling.
- Roland FP-30 plugged in direct to desktop USB 3 port
- Cheap "RoHS" external USB audio "card" plugged in to desktop USB 3 port, wired headphones connected direct to that
- I'm on arch linux running pipewire, so my first try was with output "PipeWire Sound Server".  I have no way to measure but it feels noticeable latency, I'm guessing very roughly 100 ms?
- Having installed pipewire-jack, and setting pianoteq to use JACK, the latency is much worse (250 ms?).  Going back to ALSA again the latency reduces to what it was originally.
- I don't see pianoteq listing any audio outputs whose names end with 'Direct hardware device without any conversion' as README_LINUX.txt suggests might be there
- Also tried a few other outputs semi-randomly, without success in reducing latency so far

Any pointers here?

Edit: also found that with a web browser running, pianoteq couldn't connect to "USB Audio CODEC, USB Audio; Front output / input".  Sounded promising (maybe that's a more direct connection somehow?), but no: with the browser not running, pianoteq can connect but the latency sounds the same using that output.

Last edited by un_regard (04-01-2024 00:09)

Re: Linux latency with pipewire?

Hi, I only use the Pipewire Sound Server and have banned Jack. (Bitwig DAW runs fine with Pipewire) However, I use openSuse tumbleweed (Liquorix kernel) and a Doug Audio USB DAC with 48k sample rate 256 or less samples. Korg D1 as master keyboard. I can't detect any delays when playing. (Subjective) Start in terminal pw-top (Manual with: man pw-top). The correct settings for the DAC can vary depending on the model and I have also noticed differences with the USB port (2 or 3). (Cheap DAC)

see also: https://wiki.archlinux.org/title/PipeWire

Re: Linux latency with pipewire?

Pipewire works well on my Arch desktop with 6.6.9 kernel and no tweaks.  Make sure you set the buffer size to a low value like 128 samples, and the sample rate to 48khz or higher.

Re: Linux latency with pipewire?

rasaru wrote:

Hi, I only use the Pipewire Sound Server and have banned Jack.

Hi, thanks for replying!  I don't have Jack installed either - pipewire-jack is pipewire pretending to be Jack for the benefit of client applications like pianoteq.

rasaru wrote:

(Bitwig DAW runs fine with Pipewire) However, I use openSuse tumbleweed (Liquorix kernel) and a Doug Audio USB DAC with 48k sample rate 256 or less samples. Korg D1 as master keyboard. I can't detect any delays when playing. (Subjective) Start in terminal pw-top (Manual with: man pw-top). The correct settings for the DAC can vary depending on the model and I have also noticed differences with the USB port (2 or 3). (Cheap DAC)

see also: https://wiki.archlinux.org/title/PipeWire

I just measured my sound card round trip time using audacity and a microphone, it's 29 ms - doesn't seem terrible.

After that, at @Lycomedes suggestion I set my sample rate to 48k and quantum to 256 (which I assume means a buffer capable of holding 256 samples?), ending up with this config (should I set min/max/force values too? couldn't figure out how to do that):

$ pw-metadata -n settings
Found "settings" metadata 30
update: id:0 key:'log.level' value:'2' type:''
update: id:0 key:'clock.rate' value:'48000' type:''
update: id:0 key:'clock.allowed-rates' value:'[ 48000 ]' type:''
update: id:0 key:'clock.quantum' value:'256' type:''
update: id:0 key:'clock.min-quantum' value:'32' type:''
update: id:0 key:'clock.max-quantum' value:'2048' type:''
update: id:0 key:'clock.force-quantum' value:'0' type:''
update: id:0 key:'clock.force-rate' value:'0' type:''

Unfortunately no obvious effect: still a noticeable delay of perhaps 100 ms.

Re: Linux latency with pipewire?

I haven’t changed any PipeWire or ALSA config files.  I only changed the buffer size in the Pianoteq settings.  By default Pianoteq used a high buffer size which caused latency.  Setting the buffer size to a low value solved the problem and I get low latency whether I’m using my HP Omen 25L’s internal sound card or my Focusrite Scarlett 2i2.

Re: Linux latency with pipewire?

un_regard wrote:

Unfortunately no obvious effect: still a noticeable delay of perhaps 100 ms.

Just in case this was all in my head, I thought to try with the headphones connected to the roland on one ear, and pianoteq's output on the other ear. Very clear delay.

Then I wrote a script to generate a sound that simulates that (two middle C notes played a short time apart).  From comparing that with the two-headphones test, I think the delay between the roland and pianoteq outputs reaching my ears is about 80 ms (plus or minus max 20 ms).

So with USB audio output contributing say 20 ms max (measured 29 ms round trip), that leaves roughly 60 ms to be accounted for in the pipeline involving USB midi input and pianoteq processing.  Does that seem too high?  Should I be able to reduce it?  Or should I just be less fussy?

Re: Linux latency with pipewire?

Lycomedes wrote:

I haven’t changed any PipeWire or ALSA config files.  I only changed the buffer size in the Pianoteq settings.  By default Pianoteq used a high buffer size which caused latency.  Setting the buffer size to a low value solved the problem and I get low latency whether I’m using my HP Omen 25L’s internal sound card or my Focusrite Scarlett 2i2.

Ah I see - just tried with (in pianoteq "Devices" options) "Sample rate" set to "48000 Hz" and "Audio buffer size" set to "256 samples (5.3 ms)" - no very obvious difference (this time I didn't try a careful before/after comparison nor compare against my script-generated tones).

What does "low latency" mean to you?  Maybe you're able to try a two-headphones test or even quantify it?

Re: Linux latency with pipewire?

un_regard wrote:

or even quantify it?

If you want to try and quantify your latency somewhat, this is what I used to compare with the two-headphones test:

import numpy as np
import pyaudio

sample_rate = 44100
duration = 1  # in seconds
frequency_C = 261.63  # middle C in Hz
delay = 0.08  # 80 ms

t = np.linspace(0, duration, int(sample_rate * duration), False)
tone_C = 0.5 * np.sin(2 * np.pi * frequency_C * t)

delayed = tone_C.copy()
delayed[:int(sample_rate * delay)] = 0

# superimpose the two tones
mixed_tone = tone_C + delayed[:len(tone_C)]

# normalize to 16-bit range
mixed_tone = (mixed_tone * 32767).astype(np.int16)

# play
p = pyaudio.PyAudio()
stream = p.open(format=pyaudio.paInt16, channels=1, rate=sample_rate, output=True, output_device_index=7)
try:
    stream.write(mixed_tone.tobytes())
finally:
    stream.stop_stream()
    stream.close()
    p.terminate()

To run that you'd need `numpy` and `pyaudio` installed from PyPI - I won't go into how to install those since I wouldn't know where I'm starting from in the context of your system and background knowledge.  Also it seems one needs to figure out which output_device_index to use - for that I used this snippet and looked for a device named "pipewire" in the output:

for i in range(p.get_device_count()):
    print(i, p.get_device_info_by_index(i))

Re: Linux latency with pipewire?

Good news: I think the latency is gone!  (I can barely hear it with the two-headphones test)

Bad news: I have no idea what changed.  I was regularly restarting pipewire, pipewire-pulse, and wireplumber, so I don't think it's that.

Right now, I have this in pianoteq:

Audio device type: ALSA
Audio output: PipeWire Sound Server
Sample rate: 48000 Hz
Audio buffer size: 256 samples (5.3 ms)

and in pipewire (I commented out my config file changes and ran `systemctl --user restart pipewire pipewire-pulse wireplumber` again):

$ pw-metadata -n settings 
Found "settings" metadata 30
update: id:0 key:'log.level' value:'2' type:''
update: id:0 key:'clock.rate' value:'16000' type:''
update: id:0 key:'clock.allowed-rates' value:'[ 16000 ]' type:''
update: id:0 key:'clock.quantum' value:'1024' type:''
update: id:0 key:'clock.min-quantum' value:'32' type:''
update: id:0 key:'clock.max-quantum' value:'2048' type:''
update: id:0 key:'clock.force-quantum' value:'0' type:''
update: id:0 key:'clock.force-rate' value:'0' type:''

Re: Linux latency with pipewire?

One thing that makes this harder: I can see that pianoteq retains its settings across restarts, and even if I wipe the directory where I extracted the demo and extract the demo again before restarting.

I wonder where it stores its settings, so I can wipe them to help me see exactly what makes the difference?  But maybe that's for another thread.

Perhaps from bitter experience from software as a day job, I never fully trust ways to "reset" software that are controlled by the software itself!  I'd rather just wipe it completely and try again.

Re: Linux latency with pipewire?

un_regard wrote:

I wonder where it stores its settings, so I can wipe them to help me see exactly what makes the difference?

The answer to that seems to be (thanks to `strace -e trace=file`):

~/.config/Modartt/Pianoteq81.prefs

Re: Linux latency with pipewire?

Experimenting some more (reboots, removing PT config file, changing PT settings):

I think most of the difference is just from the buffer size.  I believe when I reported still hearing noticeable latency at 48k sample rate and 256 buffer in pianoteq didn't make much difference, I was *expecting* to still hear the delay, and I did for real, but it was significantly reduced but just about still audible.  Really it's not very noticeable at all at the level I'm now seeing even at 256 and perhaps 128 is even better.

So basically @Lycomedes had it exactly right (also they suggested 128 buffer size and I'd not paid attention and picked 256).

Only thing I'm still a bit surprised by is that having "measured" (in the somewhat sloppy way available to me) around 80 ms total latency, I was surprised that the difference between 10 ms and 5 ms (512 and 256 buffer size at 48k) made an audible difference.  But it seems to, I can't explain why.

Re: Linux latency with pipewire?

On my setup with 48k/128 the latency is negligible, it feels like playing an acoustic piano.  It may depend on your hardware, and direct ALSA may perform better than PipeWire.

Re: Linux latency with pipewire?

un_regard wrote:

Good news: I think the latency is gone! 
Bad news: I have no idea what changed. 
I was regularly restarting pipewire, pipewire-pulse, and wireplumber, so I don't think it's that.

I suspect you've solved your problem by now, but I wanted to share a small quirk I discovered about pipewire. Pipewire has this behavior where it will use the highest quality settings asked for by any program running on your computer for all running programs in your computer. What I mean by that is that by starting a second program that asks for a lower quantum value (e.g. pavucontrol), all other running programs now suddenly also use the lower quantum value which can result in sudden "magic" solution for problems "without changing any settings".

KAWAI NV10 / Sequential Prophet Rev2
https:://youtube.com/stefaanhimpe

Re: Linux latency with pipewire?

shiihs wrote:

Pipewire has this behavior where it will use the highest quality settings asked for by any program running on your computer for all running programs in your computer. What I mean by that is that by starting a second program that asks for a lower quantum value (e.g. pavucontrol), all other running programs now suddenly also use the lower quantum value which can result in sudden "magic" solution for problems "without changing any settings".

That's useful information, thanks.  I think in my case what happened here is just that I didn't set the buffer size and sample rate as suggested and then listen carefully to what I heard.

Last edited by un_regard (25-01-2024 20:27)

Re: Linux latency with pipewire?

Just came back to say how much I love pianoteq, it puts a smile on my face that's there right now :-)  (Bluethner, Steinway D)

And, for anybody else reading this thread later:

1. Do what it says in the Pianoteq linux README (personally I skipped the part about CPU frequency throttling and it works fine: see my first post re that)
2. Do what @Lycomedes says to do here https://forum.modartt.com/viewtopic.php...43#p994443

After that everything has worked fine for me, if I'd done that to start with I'd not have needed to do any of the experimentation I did here!

Last edited by un_regard (25-01-2024 20:29)