Both sides previous revisionPrevious revisionNext revision | Previous revisionNext revisionBoth sides next revision |
wiki:jack_latency_tests [2010/12/01 07:09] – rgareus | wiki:jack_latency_tests [2012/05/30 15:00] – ZKwnnrjfKpqQkAYjkTd 94.23.1.28 |
---|
====== JACK Latency tests ====== | It's great to find somneoe so on the ball |
| |
Yet to be interpreted results on measuring [[http://jackaudio.org|JACK]] latency. | |
| |
<note warning>Draft. Work in progress.</note> | |
| |
===== 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 [[http://jackaudio.org|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 [[https://rt.wiki.kernel.org/|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. | |
| |
{{:wiki:jack_latency_tests:latency-abs.png?400|measured latency for both UA-25 and HDA}} | |
{{:wiki:jack_latency_tests:latency-abs1.png?400|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. | |
| |
{{:wiki:jack_latency_tests:latency.png?810|non-JACK-latency residue for both UA-25 and HDA}} | |
| |
{{:wiki:jack_latency_tests:latency-ua25.png?400|non-JACK-latency residue for Edirol UA25 audio interface}} | |
{{:wiki:jack_latency_tests:latency-hda.png?400|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): | |
- 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. | |
- 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: | |
| |
{{:wiki:jack_latency_tests:latency-ua25-corrected.png?400}} | |
| |
**(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 [[http://jackaudio.org/files/docs/html/group__PortFunctions.html#gadbce552c7eec6941fb6c617576da4551|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 ===== | |
| |
* [[http://www.kokkinizita.net/linuxaudio/|jack_delay]] | |
* [[http://linuxaudio.org/mailarchive/lau/2009/4/2/153739|Thread on LAU - using jdelay]] | |
* [[http://linuxaudio.org/mailarchive/lau/2009/4/2/153759|Fons UA-5 measurement]] | |
| |
===== Raw data ===== | |
| |
| |
<code> | |
#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 | |
</code> | |
| |
<code> | |
#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 | |
</code> | |
| |
===== 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. | |