This is an old revision of the document!


JACK Latency tests

Yet to be interpreted results on measuring JACK latency.

Draft. Work in progress.

Demystifying latency

Latency is one of those buzzwords which are often misunderstood by the layman or are indiscriminately bandied around as incontrovertible proof of the evident advantages of one's own prowess against the others'. After all, it is a number you can compare with your buddies.

I once watched this guy in an audio forum talk about how he got less latency if he launched jackd from the command-line, and actually thought latency was measured by QJackCtl's DSP Load indicator, so larger audio buffers implied less latency. He was actually a nice guy trying to help, but he was rather confused himself.

So, leaving aside buzzwords, hype and urban legends, what is actually latency? Latency is how you call the reaction time of a system to a certain stimulus.

In the audio world, latency is the time elapsed between an action that produces sound and the actual perception of that sound by a listener.

A very clear case of audio latency is the time it takes to hear the sound of thunder after you watch lightning from a distant storm (actually visual perception has latency too, since light doesn't travel at infinite speed, but at that scale visual latency is negligible compared to the aural one.)

Latency sources

There are many factors that contribute to the total latency of a given system. Some of the more relevant are:

  • Sound propagation through the air: since it is a mechanical perturbation in a fluid, sound travels at comparatively slow speed: about 340 m/s. Some interesting consequences:
    • Your acoustic guitar or piano has a latency of about 1-2 ms, due to the propagation of the sound between your instrument and your ear .
    • At a large concert venue if you are far away from the stage the sound will travel faster through the path “singer-mic-nearest loudspeaker-your ear” than through the “singer-air-your ear” one, so you'll hear the real sound as an echo of the amplified one. Relativistic time-paradox or what?
  • Digital-to-Analog and Analog-to-Digital conversion: electric signals travel quite fast, so their propagation time is negligible in this context, but the conversions between the analog and digital domain take a comparatively long time to perform, so their contribution to the total latency may be considerable. Fast converters are, for instance, one of the factors that distinguishes a quality audio interface from a cheap one, along with other features like low noise, low distortion, etc.
  • Digital Signal Processing: digital processors tend to process audio in chunks, and the size of that chunk depends on the needs of the algorithm and performance/cost considerations. This is usually the main cause of latency when you use a computer and one you can try to predict and optimize.
  • Computer I/O Architecture: a computer is a general purpose processor, not a digital audio processor. This means our audio data has to jump a lot of fences in his path from the outside to the CPU and back, contending in the process with some other parts of the system vying for the same resources (CPU time, bus bandwidth, etc.) Thanks to the combined efforts of kernel, audio driver and jackd smart developers you are in position to tune your system a bit more towards the digital audio processing task, but don't expect miracles. Remember you can use your computer also to write documents, surf the net, save some lemmings… Polyvalence comes at a cost.

Does latency really, really matter?

Less than most people think, in our opinion. There are only some situations where a very low latency is really important, because they require very quick response from the computer. Some examples that come quickly to mind are:

  • Playing virtual instruments: a large delay between the pressing of the keys and the sound the instrument produces will throw-off the timing of most instrumentalists (save if they are church organists, whom we believe are awesome latency-compensation organic systems.)
  • Software audio monitoring: if a singer is hearing her own voice through two different paths, her head bones and headphones, large latencies can be disturbing.
  • Live-effects: precise synchronization may be important if you trigger manually sound effects like delays.
  • Live-mixing: (case example needed).

In many other cases (such as playback, recording, overdubbing, etc.) latency is not that important or can be compensated for.

At the end of the day, it is not so much its size, but how well you use it.

The smaller the better?

TODO

Capture latency and playback latency

TODO

Measuring roundtrip latency with jack_delay

TODO

Adjusting latency

TODO

The JACK Audio Connection Kit has a few parameters to configure the latency. However the settings are constrained by hardware (audio-device, CPU and bus-speed). Lower latencies increase the load on the computer-system (it needs to process the audio in smaller chunks which arrive much more frequently). If the system can not keep up: an x-run (short for buffer over-run and buffer under-run) occurs which usually results in audible clicks or dropouts.

Low-latency is not always a feature you want to have. It comes with a couple of drawbacks: the most prominent is increased power-consumption because the CPS needs to process many small chunks of audio-data, it is constantly active and can not enter power-saving mode. Furthermore, if more than one application (sound-processor) is involved in processing the sound, the operating system performs a context-switch to run each of these for each audio-cycle which results in a much higher system-load and an increased chance of x-runs.

Stable low-latency (≤10ms) on GNU/Linux can usually only be achieved by running realtime-kernel (insert links to rtirq and setup/config info here).

JACK Latency enigma

JACK does report the port-latencies (run jack_lsp -l). However the values it reports for physical-ports are determined by the configuration (e.g. -p 1024 -n3) and do not represent the real latency. The total latency depends on many factors: the bus (PCI, 1394, USB, Chipset), layers in between (DMA, IRQ) and of course the audio-interface itself.

On a modern computer systems all these factors plus their configuration (PCI latency, bus speed, CPU/bus freq scaling, data-packet-framing, etc) make it is close to impossible to calculate the latency introduced.

Latency measurements

Fons Adriaensen has written a utility to measure the total round-trip latency called jack_delay.

Even though the complete path of the digital audio-signal that adds latency is complicated, we do expect the additional layency to be a (more or less) constant value.

The diagrams below show the the total measured-latency for an Edirol UA-25 USB and a HDA-Intel PCI sound-card. Note that not all configurations are possible: e.g. for the USB interface the frames-per-period need to be larger or equal to 64 frames, while the HDA will not allow periods larger than 1024 frames.

The tests were done on Debian/squeeze using jackdmp 1.9.6.

measured latency for both UA-25 and HDA measured latency for both UA-25 and HDA - detail

Interpretation and Analysis

Let's have a closer look: The diagrams below show the difference between the nominal-latency (given by JACK configuration - and also displayed in the qjackctl setup dialog) and the measured-latency for an Edirol UA-25 USB and a HDA-Intel PCI sound-card. In other words: it is a plot of the additional latency.

non-JACK-latency residue for both UA-25 and HDA

non-JACK-latency residue for Edirol UA25 audio interface non-JACK-latency residue for HDA-Intel audio interface

The small residue of additional non-JACK-latency for PCI devices is constant (~44 frames - .9ms). The anomalies ≤ 32 frames/period for PCI devices can be explained by bus overhead and the soundcard. However the results for USB-device is unexpected.

There are two things that the authors of this article do not understand (and may be bugs in JACK):

  1. It seems that for USB devices JACK secretly adds an additional period latency, but at most 1024 frames. This phenomena is not present with PCI devices.
  2. The latency reported by JACK is inconsistent.

Looking closer at these two issues:

(1) plotting the non-JACK-latency for the USB device after subtracting an additional period-size - but at most 1024 frames yields a reasonable distribution:

(2) understanding the inconsistencies of reported port-latency will require digging into the source-code of JACK. Trying to reproduce this behaviour with jack-1 might also shed some light on the issue. It may also simply be a misinterpretation of the reported values. The information collected here is a first step: to make the issue clear to the authors.

using -n2 for either USB or PCI makes JACKd report during startup:

ALSA: use 2 periods for capture
ALSA: use 2 periods for playback

and -n3 reports:

ALSA: use 3 periods for capture
ALSA: use 3 periods for playback

while jack_lsp -l (or jack_port_get_latency) says otherwise. For -n3 -p1024:

 system:capture_1
      port latency = 1024 frames
 system:playback_1
      port latency = 2048 frames

“3 periods for capture” and “3 periods for playback” should result in the same latency for both input and output ports. Ergo, either one of the reported values is incorrect.

Alas, total latency measurement can not tell which it is.

References

Raw data

#UA-25, Linux 2.6.33.7-rt29 i386, jackdmp 1.9.6
#JACK-cfg, measured lat [frames], measured lat [ms], nominal latency for record [frames], nominal latency for playback [frames], periods per cycle
#JACK-cfg: frames per period * periods per cycle / sample-rate / S: --sync
#
# values of '-1' mean that this mode is not supported
#
4096*3/48kHz   ,17688.747, 368.516,  4096,12288, 3
4096*3/48kHz/S ,13592.747, 283.182,  4096, 8192, 3
4096*2/48kHz   ,13592.747, 283.182,  4096, 8192, 2
4096*2/48kHz/S , 9496.747, 197.849,  4096, 4096, 2
2048*3/48kHz   , 9401.749, 195.870,  2048, 6144, 3
2048*3/48kHz/S , 7401.747, 154.203,  2048, 4096, 3
2048*2/48kHz   , 7401.747, 154.203,  2048, 4096, 2
2048*2/48kHz/S , 5353.747, 111.536,  2048, 2048, 2
1024*3/48kHz   , 5257.748, 109.536,  1024, 3072, 3
1024*3/48kHz/S , 4281.748,  89.203,  1024, 2048, 3
1024*2/48kHz   , 4281.749,  89.203,  1024, 2048, 2
1024*2/48kHz/S , 3257.746,  67.870,  1024, 1024, 2
 512*3/48kHz   , 2728.747,  56.849,   512, 1536, 3
 512*3/48kHz/S , 2216.747,  46.182,   512, 1024, 3
 512*2/48kHz   , 2216.748,  46.182,   512, 1024, 2
 512*2/48kHz/S , 1704.748,  35.516,   512,  512, 2
 256*3/48kHz   , 1464.747,  30.516,   256,  768, 3
 256*3/48kHz/S , 1208.748,  25.182,   256,  512, 3
 256*2/48kHz   , 1208.747,  25.182,   256,  512, 2
 256*2/48kHz/S ,  952.747,  19.849,   256,  256, 2
 128*3/48kHz   ,  808.748,  16.849,   128,  384, 3
 128*3/48kHz/S ,  680.747,  14.182,   128,  256, 3
 128*2/48kHz   ,  681.748,  14.203,   128,  256, 2
 128*2/48kHz/S ,  553.748,  11.536,   128,  128, 2
  64*3/48kHz   ,  505.748,  10.536,    64,  192, 3
  64*3/48kHz/S ,  441.747,   9.203,    64,  128, 3
  64*2/48kHz   ,  441.748,   9.203,    64,  128, 2
  64*2/48kHz/S ,  377.747,   7.870,    64,   64, 2
  32*3/48kHz   ,    -1   ,   -1   ,    32,   96, 3
  32*3/48kHz/S ,    -1   ,   -1   ,    32,   64, 3
  32*2/48kHz   ,    -1   ,   -1   ,    32,   64, 2
  32*2/48kHz/S ,    -1   ,   -1   ,    32,   32, 2
  16*3/48kHz   ,    -1   ,   -1   ,    16,   48, 3
  16*3/48kHz/S ,    -1   ,   -1   ,    16,   32, 3
  16*2/48kHz   ,    -1   ,   -1   ,    16,   32, 2
  16*2/48kHz/S ,    -1   ,   -1   ,    16,   16, 2   
#HDA 1458:a002, Linux 2.6.33.7-rt29 amd64, jackdmp 1.9.6
#JACK-cfg, measured lat [frames], measured lat [ms], nominal latency for record [frames], nominal latency for playback [frames], periods per cycle
#JACK-cfg: frames per period * periods per cycle / sample-rate / S: --sync
#
# values of '-1' mean that this mode is not supported
#
#2048*2 -> ALSA: cannot configure playback channel
#1024*3 -> ALSA: cannot configure playback channel
#
4096*3/48kHz   ,   -1   ,  -1   ,  4096,12288, 3
4096*3/48kHz/S ,   -1   ,  -1   ,  4096, 8192, 3
4096*2/48kHz   ,   -1   ,  -1   ,  4096, 8192, 2
4096*2/48kHz/S ,   -1   ,  -1   ,  4096, 4096, 2
2048*3/48kHz   ,   -1   ,  -1   ,  2048, 6144, 3
2048*3/48kHz/S ,   -1   ,  -1   ,  2048, 4096, 3
2048*2/48kHz   ,   -1   ,  -1   ,  2048, 4096, 2
2048*2/48kHz/S ,   -1   ,  -1   ,  2048, 2048, 2
1024*3/48kHz   ,   -1   ,  -1   ,  1024, 3072, 3
1024*3/48kHz/S ,   -1   ,  -1   ,  1024, 2048, 3
1024*2/48kHz   ,3115.933, 64.915,  1024, 2048, 2
1024*2/48kHz/S ,2091.965, 43.583,  1024, 1024, 2
 512*3/48kHz   ,2091.739, 43.578,   512, 1536, 3
 512*3/48kHz/S ,1579.792, 32.912,   512, 1024, 3
 512*2/48kHz   ,1579.729, 32.911,   512, 1024, 2
 512*2/48kHz/S ,1067.693, 22.244,   512,  512, 2
 256*3/48kHz   ,1067.631, 22.242,   256,  768, 3
 256*3/48kHz/S , 811.610, 16.909,   256,  512, 3
 256*2/48kHz   , 811.640, 16.909,   256,  512, 2
 256*2/48kHz/S , 555.678, 11.577,   256,  256, 2
 128*3/48kHz   , 556.381, 11.591,   128,  384, 3
 128*3/48kHz/S , 428.372,  8.924,   128,  256, 3
 128*2/48kHz   , 426.775,  8.891,   128,  256, 2
 128*2/48kHz/S , 298.726,  6.223,   128,  128, 2
  64*3/48kHz   , 299.280,  6.235,    64,  192, 3
  64*3/48kHz/S , 235.297,  4.902,    64,  128, 3
  64*2/48kHz   , 235.833,  4.913,    64,  128, 2
  64*2/48kHz/S , 170.797,  3.558,    64,   64, 2
  32*3/48kHz   , 267.078,  5.564,    32,   96, 3
  32*3/48kHz/S , 235.163,  4.899,    32,   64, 3
  32*2/48kHz   , 202.842,  4.226,    32,   64, 2
  32*2/48kHz/S , 170.943,  3.561,    32,   32, 2
  16*3/48kHz   , 155.007,  3.229,    16,   48, 3
  16*3/48kHz/S , 138.963,  2.895,    16,   32, 3
  16*2/48kHz   , 124.041,  2.584,    16,   32, 2
  16*2/48kHz/S , 108.056,  2.251,    16,   16, 2 

Acknowledgments

Many thanks to Paul Davis and Stephane Letz for JACK and Fons Adriaensen for jack_delay.

This article was written by Robin Gareus and Luis Garrido and may be redistributed in terms of the GFDL.

wiki/jack_latency_tests.1291291212.txt.gz · Last modified: 2010/12/02 13:00 by lgarrido