Latency offsets in Ardour, but also generally

I have read through all the documentation I could find as well as the few posts I could find here, but I’m still struggling to understand latency offsets, particularly in Ardour but also just generally. Seeing as there are a few smart developers hanging around here, I suspect this is the place I am most likely to get useful answers. Usually on Reddit I just get “It doesn’t matter” or “who cares,” so trying something new…

Before I switched to Linux, latency isn’t something I ever gave much thought to. Any recording I did was for my bands, so we would record drums to a click, tidy up the drums, then everyone would record to the drums. Monitoring was handled by the interface, not the DAW. It didn’t really matter if the latency offset wasn’t perfect because everyone would be off by the same amount. Now that I have switched to Linux, as I set about configuring my system for audio, I started paying more attention to the latency numbers, but it seems like every DAW has a different expectation and latency in Linux generally seems to just kinda work differently.

In Windows, I would have used ASIO, and it seemed (to me) that the latency numbers shown in Reaper (my primary DAW) were more realistic, or at least they certainly included something more than just the buffer size. But in Linux, the latency numbers shown seem to only reflect the buffer size. For example, at 48 kHz with a 256 buffer, Reaper shows ~5.3/5.3 ms, which is just the buffer size at that sample rate. Is the additional hardware latency usually baked into ASIO drivers? And does that make it so that we don’t need to measure actual RTL and apply offsets? Or is there some other reason why Windows latency numbers include more than just the buffer size?

Now on Linux, even though Reaper does have a native version, I’ve been in a more experimental mood and exploring other DAWs. Ardour being open source has me really intrigued, but I am struggling to understand how to even apply a latency offset when using Pipewire-JACK. Typically what I do is use Cable to measure the latency offset, which is 101 samples each way (I realize that technically this can fluctuate, but let’s just keep it simple). It can also apply the offset system wide, but that doesn’t persist across reboots, which is annoying. In Reaper, I can just set the offset in the preferences, and when I check it by routing a click or clap or kick or something out and back in, sure enough, it lines up exactly. In Bitwig (which I am also exploring), I can also set an offset, but for some reason, it never lines up there. I’ve tried changing the offset to try to find the perfect number, but it seems to always be too little or too much, and then I’ll go back to the start and now the exact same offset number produces a different result. That’s not your problem, but I’d still love to know why Bitwig is so strange about it. To be clear, I’m setting a fixed buffer size and sample rate system wide in my Pipewire configs, though as part of my troubleshooting, I did open a browser while adjusting offsets in Bitwig, so maybe that had something to do with it.

In Ardour, though, it seems there is only the option to apply offsets when using ALSA, not when using Pipewire-JACK. Is there a reason for that? I have tried and tried to figure out how to do it system-wide without having to redo it every reboot, but almost all of the info I can find only says how to measure it or how to set it when using just JACK, or it’s a half-guide written by someone who only speaks code and not English. And no offense to those people, they’re trying, but I struggle trying to translate code to something useful for me. So I guess this is part question, part feature request, but could we please get an option to apply offsets in Ardour when using Pipewire-JACK? Or at least a guide on how else we are supposed to do it and why we need to do it that way instead? Although I can imagine that if every DAW has a slightly different processing delay, it would be better to apply per application rather than system wide, but maybe I’m misunderstanding.

A bit more generally, from my reading, I understand that the offset needed can change when using USB devices. I think this is where the “it doesn’t matter” answer comes in because really, a few samples one way or another don’t matter. But why does it vary? Is that because of CPU load? I can’t imagine there would be variable load on the interface side. And is there no better way to account for that variability than having a cable permanently connecting an output to an input to re-measure RTL every time you go to do audio work? That seems exceptionally annoying and a waste of an input and output.

1 Like

JACK API provides a per-port latency value, so the JACK server is expected to provide the input and output latency of the hardware ports as well as application ports.
I have not personally seen a documented way to set that value with Pipewire-JACK (it may exist outside my awareness). When using jackd there is a straight forward and well documented command line argument to set the exposed latency values.

Each application should be aware of and compensate for its own internal latency. The hardware input and output latency is a system feature, so the system audio server should expose that value.

The most concise explanation I saw was this (which may not fully apply to the latest Linux kernel drivers):
“For USB devices the Linux kernel driver add some additional buffering. Depending when the device is started relative to USB bus availability, there is extra systemic latency due to that buffer. This is specific to USB;”

There was a concerted effort by the usb snd driver maintainer to improve that behavior with the goal of reducing latency of USB audio devices, and making the latency behavior more consistent in kernel version 5.14 in mid-2021. The explanation I quoted in the previous paragraph was from 2020, prior to the 5.14 kernel usb-snd driver work. Because of the time for long term support distributions to roll out new kernels, and how long documents live on the Internet it is possible that outdated information about the magnitude of the problem is still floating around. Best bet would be to measure it yourself with your system and your audio interface and see how much variation you get when stopping and starting the ALSA backend in ardour, and when removing and reattaching the USB hardware.