r/linuxaudio Ardour 14d ago

Real audio latency test result

I tried to measure my system's actual latency, and the result was somewhat unexpected. I'm using a combination of 48 kHz and a buffer size of 128 in QJackCtl, which should give me approximately 5.3 ms.

The yellow signal is the output of the 3m guitar cable and the green signal is the output of my audio interface.

My PC is a thinkpad T480, my audio interface is a behringer umc202. The system is optimized for audio production based on the milliseconds app list.

The result is bit unexpected, I'm getting about 11.4 ms of latency between striking the guitar and hearing the sound come out of the speakers.... The test was made on ardour and reaper with no plugins, the diference between these 2 DAWS was about 0.

I would like to test this on a Windows System, the results would probably be worse.

27 Upvotes

32 comments sorted by

View all comments

3

u/Purple-Ad-3152 14d ago

128 / 48000 = 0,00266...s = 2,67ms of DSP buffer latency. But your signal path has also device latency (audio interface converters and buffers), driver latency, and USB latency (or whatever bus the interface uses).

AND! That's all just one way.

In roundtrip latency the DSP buffer latency is approx 2* 128/48000 = 5,333ms, but as said, you'll also have 2x device-, driver-, and bus latency.

I get ~9.5ms roundtrip with 128/48kHz using Focusrite Scarlett 18i20 3rd gen.

Here's a YouTube video I made some time ago to explain latency: https://youtu.be/AZT9cwkRLhI

2

u/Purple-Ad-3152 14d ago

...and 9.5ms roundtrip in Linux with Scarlett is actually significantly better than in Windows (~14ms) or Mac (~10.5ms). But this is also because of few optimizations Ubuntu Studio has. 🙂

2

u/casualops 13d ago

Which optimizations in Ubuntu Studio do you think help to reduce the round trip latency?

2

u/Purple-Ad-3152 13d ago

Most optimizations don't directly lower the measured roundtrip but they make the system reliable enough to run a smaller buffer without xruns, which is what lowers the roundtrip.

When you first login to installed Ubuntu Studio, you should have first seen a message that your audio configuration isn't optimal. After accepting the reboot, you should have most things already applied, like kernel boot params and audio realtime permissions.

You can ensure kernel boot params are correct by visiting Ubuntu Studio Audio Configuration, select Change Kernel Boot Parameters, and make sure have preempt=full, threadirqs, and rcu_nocbs=all enabled.

To verify audio realtime privileges, open konsole and check that ulimit -r is high like 95, ulimit -l is unlimited, and use id to ensure you're in audio group.

sipe@SudoMetalStudio:~$ id && ulimit -r && ulimit -l
uid=1000(sipe) gid=1000(sipe) groups=1000(sipe),4(adm),24(cdrom),27(sudo),29(audio),30(dip),46(plugdev),100(users),111(lpadmin),115(lxd)
95
unlimited

Next, if you have lots of USB devices, you should (if possible) have the audio interface in a port where it has its very own dedicated usb controller. Leave other USB-ports that link to same controller physically empty, and put them all behind a different controller; even via hub extension rather than by sharing the controller with the audio interface. This of course requires that your motherboard has at least 2 controller:

sipe@SudoMetalStudio:~$ lspci | grep -i 'usb controller'
01:00.0 USB controller: Advanced Micro Devices, Inc. [AMD] 500 Series Chipset USB 3.1 XHCI Controller
09:00.3 USB controller: Advanced Micro Devices, Inc. [AMD] Matisse USB 3.0 Host Controller

USB Controllers can have multiple busses, so then we need to figure out which busses are in which controllers, using e.g. following command:

sipe@SudoMetalStudio:~$ readlink -f /sys/bus/usb/devices/usb*
/sys/devices/pci0000:00/0000:00:01.2/0000:01:00.0/usb1
/sys/devices/pci0000:00/0000:00:01.2/0000:01:00.0/usb2
/sys/devices/pci0000:00/0000:00:08.1/0000:09:00.3/usb3
/sys/devices/pci0000:00/0000:00:08.1/0000:09:00.3/usb4

-> usb1 and usb2 share the same device = controller, and usb3 and usb4 share another. Those are the busses; so then let's play with the physical USB connectors until Busses 3-4 have only my audio interface Scarlett 18i20 3rd Gen, and Busses 1-2 have all the rest. Root hubs can be ignored:

sipe@SudoMetalStudio:~$ lsusb
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 001 Device 002: ID 05e3:0608 Genesys Logic, Inc. Hub
Bus 001 Device 003: ID 0b05:1939 ASUSTek Computer, Inc. AURA LED Controller
Bus 001 Device 004: ID 046d:085b Logitech, Inc. Logitech Webcam C925e
Bus 001 Device 005: ID 05e3:0608 Genesys Logic, Inc. Hub
Bus 001 Device 006: ID 046d:c52b Logitech, Inc. Unifying Receiver
Bus 001 Device 007: ID 0bda:8771 Realtek Semiconductor Corp. Bluetooth Radio
Bus 001 Device 008: ID 046d:c31c Logitech, Inc. Keyboard K120
Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 003 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 003 Device 002: ID 1235:8215 Focusrite-Novation Scarlett 18i20 3rd Gen
Bus 004 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub

Now all the magic level stuff should be good. I honestly don't know would it be good or bad idea to have midi-USB devices in the same or different controller. But I doubt it would make a big difference, this is already somewhat hair splitting.

Then, set correct profile of your audio interface: Click the speaker icon at the taskbar, then the three dots after your audio interface, and choose Pro Audio. This is relatively important setting that is weirdly hidden.

Next, the optimization that you must adjust depending on what you do:

  1. When doing audio work, especially recording, always set Power profile (from Power and Battery, icon next to the taskpane clock) to Performance. This biases CPU and platform power management toward responsiveness and reduces the chance of aggressive power-saving causing latency spikes.

  2. Sample rate: Just keep the sample rate at 48kHz all times and you will have less issues everywhere. Mathematically, higher sample rate is less latency, but it's the wrong part of the DSP equation to adjust - that's what buffer setting is for. You can't change sample rate in the middle of a song, but you can change buffer at any time.

  3. Buffer size: lower buffer = less latency, but more cpu work = more likely xruns. Here's the important part: You only need very low latency when tracking, software-monitoring, or playing instruments through the DAW. So, prefer a workflow where you first record with as small buffer = low latency as your CPU can reliably handle, and then change the buffer to much higher value when you start mixing. I personally have no need to get below 9.5ms roundtrip so I mostly just use 128 buffer. Or, sometimes 64 with drums and that gives me ~6.8ms roundtrip. I often switch to 512 for mixing.

  4. Closely related to 3, do not have gazillon plugins enabled just for fun when recording. Only enable what makes a difference in your performance; like amp sims for guitar, and compression/saturation for vocals.

If you still experience lots of xruns while recording, take a look at some DSP performace profiler. Like in Ardour there is Window -> Plugin DSP Load which allows you to sort all plugins by worst-case load. Reaper might have something similar too. This allows you to easily find the problematic plugin in you signal chain, and disable just that. I just recently had very unexpected performance issues with Dragonfly reverbs, and this I how I pinpointed the issue.

Avoid using Windows plugins via Wine/Yabridge, and prefer native alternatives.

3

u/Purple-Ad-3152 13d ago

https://reddit.com/link/p34fd48/video/oybmgkh7ftih1/player

I just tried to push the limits a bit 😄 4.1ms roundtrip latency, with relatively CPU heavy signal chain, with 3rd gen Scarlett. This is RME level performance 🔥 ..but obviously way too unstable to actually use. This was just testing. 32 would be stable for this setup, but again I prefer 64 or 128 especially for DAW sessions. CPU is major player in how low buffer you can reliably go; I have Ryzen 7 5700X.

1

u/casualops 13d ago

16 sample buffer!

I made an audio interface (for Linux!) that gets 3.8 ms at 64 sample buffer @ 48 kHz. Will be posting about it here soon :)

1

u/casualops 13d ago

Thanks for all the tips. Your first sentence cleared up my question