This is an old revision of the document!


JACK Latency tests

Yet to be interpreted results on measuring JACK latency.

Draft. Work in progress.

Introduction

There are only a few use-cases where latency - the delay between a signal arriving at the sound-card's (analog) input until it arrives at the output of the sound-card again - is important to be very low.

In most other cases (such as playback, recording) latency can be compensated for, however any path that requires direct In→Out processing will need a low-latency system. In particular low-latency audio is required for

  • live-effects
  • live-mixing
  • software monitoring
  • playing virtual instruments

Most humans will notice no difference if the audio latency is below 10ms (citation needed) - for comparison: in 10ms the sound travels ~ 3.4m (11 feet).

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.

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 variables: the bus (PCI, 1394, USB), layers in between (DMA, IRQ) and of course the audio-interface itself.

Latency measurements

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

Even though the complete path of the digital audio-signal that causes latency is complicated due to data-packet-framing, bus-latencies, we expect patterns.

The diagrams below show the the 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 USB interface the frames-per-period need to be larger or equal to 64 frames, while the HDA will not allow periods larger than 2048 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 of 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.

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 consistent. 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's 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) that is not present with PCI devices.
  2. 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 pattern:

(2) understanding the inconsistencies of reported port-latency will require digging into the source-code of JACK, it may also help to try to reproduce this behaviour with jack-1. It may 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

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.1291181628.txt.gz · Last modified: 2010/12/01 06:33 by rgareus