Ardour 6 Delay Compensation & Recommendations for Routing
Now that the dust has settled on Ardour-6.0 release, I’d like to point out some details regarding latency compensation.
General rules for routing
- Prefer aux-sends over direct connections.
- Avoid one-to-many direct connections (many-to-one is fine).
This article details on why and when following those rules is important.
Background
While developing full-graph latency compensation for Ardour 6, we faced one big issue: JACK. There were even times when we considered dropping JACK support.
One of JACK’s main features is that it facilitates anywhere-to-anywhere routing. Like an analog patch-bay one can use wires to connect everything without any constraints, even nonsensical connections.
“JACK provides mechanism, and does not enforce policy.”
However, unlike analog effects processors, some digital signal processors, do introduce a delay. Common examples are limiters, and pitch-shifters. Those effects need context, and hence buffer the audio internally which results in a delay. Still JACK allows one to arbitrarily connect those FX.
So let us have a look what happens when those effects are directly connected, using a latent effect as example:
Demonstration of effects of short delays (without latency compensation)
- Create an audio track. Its output is automatically connected to Ardour’s master-bus.
- Create an effect-bus. It is likewise auto-connected to Ardour’s master-bus.
- Add a latent effect to the Bus. This delays the signal passing through the bus.
- Connect the track’s output to the effect-bus input (in addition to the master-bus).
Figure 1 shows this as schematic. The direct signal from the track is summed with the delayed signal from the effect processor. Figure 5 below depicts a screenshot of an actual Ardour session with this setup.
Fig.1: Example connection diagram showing ambiguous latency though different signal paths; red wire shows the signal path that has been delayed.
Sine wave phasing
When a sine-wave sample is loaded to the track and played while ramping up the delay of the effect-bus, the following can be observed:
Anim.1: Phasing of a 1kHz sine-wave, x-axis show time, y-axis signal amplitude, the delay time is in samples. green: source signal; red: delayed signal; blue: sum of the signals
As can be seen in this short video sequence, a 1kHz sine-wave when summed with a delayed version of itself cancels out after a delay of 24 samples (at 48kHz sample-rate).
Keep in mind that most latent effects have a fixed latency. The animation shows a variable delay for didactic purposes.
Comb filter effect
This can be generalized for all frequencies by looking at the spectrum of white noise. Different frequencies cancel out at different delays. This effect is called “comb-filter” after the resulting pattern in the spectrum:
Anim.2: Comb filter effect produced by summing white noise with delayed signal of the same noise
This demonstrates nicely why plugin delay compensation is important.
When using latent effects without delay compensation, some frequency bands in the resulting sound are notched out. If the delay is long enough, it may also lead to an audible delays or echo.
“Delay in the wire”
The above example shows a situation in which latency compensation is not possible.
This is because there there are two direct connections with different latency connected to a common destination.
The solution to this is to also delay the bypass accordingly:
Fig.2: “Delay in the wire” for latency compensation
In order to do this, a “delay in the wire” would be needed, however JACK does not offer that.
This is the reason why one should avoid one-to-many direct connections.
Ardour allows to seamlessly change back-ends. One can switch from JACK to Pulseaudio to ALSA (or ASIO, Coreaudio), to Dummy and back. So the constraint imposed by JACK’s design also extends to the connection logic of Ardour’s other back-ends. This is the reason why other Ardour backend likewise must not feature a delay in the wire (and why we’ve considered dropping JACK support).
Aux-Sends
This is where aux-sends come into play. Those offer routing that is internal to Ardour, and hence is not constrained by the backend.
As shown in Figure 3, aux-sends in Ardour include internal delay-lines, both for the send as well as the thru path. This allows to handle situation in which case a latent effect is either on the source-track, or the receiving bus.
Fig.3: Schema of internal delay-lines in a send
As an added benefit aux-sends have a separate gain-stage and optionally an independent panner. This makes them generally more useful in most mixing situations.
Aux-sends can be added using the context-menu (right-click) in Ardour’s processor-box.
Fig.4: Adding an Aux-Send
Ardour GUI Showcase
Fig.5: Screenshot of the Ardour Mixer, showing ambiguous latency due to connections (left) and delay-compensated routing using an aux-send (right)
The possibility to use both direct-connections and sends allows for nonsensical connections (this is also true for analog patch-bays), and situations that can lead to ambiguous latency. In Ardour a warning about this is displayed in the toolbar widget (Preferences > Appearance > Toolbar > Display Latency Compensation Info):
Fig.6: Ardour GUI Latency Indicator
Conclusion
In summary this article explained in which case direct connections can lead to ambiguous latency, and how to avoid those by using internal aux-sends.
There are still many valid cases where direct explicit connections are preferable and valid.
In general this applies to all connections that have a single destination. e.g. Track to Master, or fanned-out multi-channel instruments.
This short article skips over major parts how external signals are aligned and read-ahead/write-behind techniques used to minimize overall delay.
Readers interested to dig deeper can find more information about this in the Thesis on Latency Compensation and Anywhere-to-Anywhere Signal Routing Systems.