Latency compensation: how is output latency accounted for in Ardour?
I've been spending quite a bit of time testing how Ardour and JACK behave with an analog loopback cable, to find out how to set things up for perfectly synchronised multi-track recording. There's a bit of background stuff at the following thread too:
Having looked at the JACK source and adjusted a few things to work as I _think_ they should with Ardour, my main question is: how exactly does Ardour apply latency compensation? AFAICT, it bases its adjustments on the per-port latencies reported by jackd, and obviously it treats software sources received via JACK differently from outside-the-box audio (reflected in the "Align with capture time" / "Align with existing material" track menu items).
So, for input port latency, the material being recorded is offset by the port's latency so that it's correctly aligned in time when played back, correct? And for output latency, Ardour would start playing regions early, so that when you hear the sound it's correctly aligned in time, and if you play in sync with it, anything you record as you play along will also be correctly aligned. However, I've found that overdubs come in quite late, and it gets progressively worse as the total JACK buffer size is increased. To be precise, the overdubs are p x (n - 1) frames late, where p = period size in frames and n = number of periods per buffer. This formula holds for all sampling rates, period sizes and nperiods that I've tried.
From what I understand of the architecture of JACK and Ardour, I don't believe this should be happening. Also, I've noticed that setting additional output latency in JACK apparently has no effect on the alignment of new regions being recorded - only the extra input latency changes things. So, does Ardour actually use the output latency to adjust the alignment of playback of existing tracks?
I should explain my JACK tweaks as well. For the common case of recording a new track along with an existing one (or, equivalently, when doing an analog loopback test), I believe the combined latency of the playback-record loop would be p x (n + 1) frames (plus some extra latency due to hardware, speed of signal in wire/air, and other things outside the box). That's p x n for the output latency, plus another p for the input latency, giving p x (n + 1). I'm finding that I can only get perfect synchronisation of the loopback signal if I modify JACK (0.116.2 SVN 3649) so that the input latency is n x p, rather than just p. (This is in drivers/alsa/alsa_driver.c, BTW, where jack_port_set_latency is called for the capture and playback ports.) In the original JACK code, the output latency is essentially calculated by p x (n - 1). I had thought this should be p x n, from reading Paul's slides on JACK's design. However, changing the output latency logic seems to have no effect on the Ardour loopback test, only on the output port latencies reported by jack_lsp.
I can understand that accounting for the output latency as part of the input latency isn't appropriate, as there could be other routes from software out into the real world with different latencies (MIDI being a good example). But overdubbing new tracks onto existing ones seems like such a common scenario that it should probably work out of the box, IMO.
BTW, Looking at the code, I'm glad to see that JACK also can account for additional hardware latency reported by the ALSA driver (driver->capture_frame_latency). Is this widely supported? I don't think the driver for my Echo Gina24 implements this, as I always see about 135 frames of extra latency, regardless of the sampling rate, period size or number of periods in JACK.
Sorry for the long and technical posting - I hope I've made my confusion clear, if you know what I mean. :) I at least have a workaround now, but I don't believe it's the correct way to do it.