Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
a5b706d
Added a jack-zero-latency.md post
daschuer Mar 18, 2021
6b0a3b6
Define Jack
daschuer Mar 19, 2021
61d3419
Add author daschuer
daschuer Mar 19, 2021
041663f
improve tags
daschuer Mar 19, 2021
f050d1f
Fix paragraph
daschuer Mar 19, 2021
9bab423
Add more details
daschuer Mar 20, 2021
ab2044a
Rephrase the conclusion
daschuer Mar 20, 2021
045e2cc
Integrate findings about Jack sync mode
daschuer Mar 21, 2021
2d1ca97
Added the results from the roundtrip test
daschuer Mar 27, 2021
0340286
Fix typos
daschuer Apr 7, 2021
8d4033d
Quote jack command line tools
daschuer Apr 7, 2021
784b2d7
Remove 2.3 tag
daschuer Apr 7, 2021
2912496
Improve post title
daschuer Apr 7, 2021
51d7711
Improve the sentence about direct use of the buffer.
daschuer Apr 7, 2021
8a476c2
Improve the description of use of Balance
daschuer Apr 7, 2021
5e1c4ba
Clarify resulting buffers
daschuer Apr 7, 2021
5817cfd
Indent jack_iodelay by 4 spaces instead of using fenced code blocks.
daschuer Apr 7, 2021
42f2424
Explain latency
daschuer Apr 7, 2021
b784e42
Set status to daft
daschuer Apr 7, 2021
f714c4a
simplify the latency paragraph
daschuer Apr 7, 2021
2c15a1d
Add references to the multi Soundcard statement.
daschuer Apr 8, 2021
bccbb06
remove de from manual URL
daschuer Apr 8, 2021
d3c958d
Improve wording
daschuer May 8, 2021
a9f98df
Fix typo
daschuer May 8, 2021
afbad50
Improve wording
daschuer May 8, 2021
eaa3b8f
improve tens
daschuer May 8, 2021
8486efa
Improve wording
daschuer May 8, 2021
47256cd
merge avatar folder drom theme to content folder
daschuer May 9, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added content/images/avatars/daschuer.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added content/images/news/fadeoutcompare.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added content/images/news/feedbackloop.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added content/images/news/jackpatch.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added content/images/news/roundtriplatency.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
78 changes: 78 additions & 0 deletions content/news/XXXX-XX-XX-jack-zero-latency.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
title: "Does using Mixxx with JACK give you zero latency?"
authors: Daniel Schürmann
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add yourself to the AUTHORS_METADATA dict in the pelicanconf.py: https://github.com/mixxxdj/website/blob/website/pelicanconf.py#L158

Then run tools/update_avatars.py. It will automatically fetch your profile picture from github and add it to the source tree (don't forget to git add it).

Something like:

AUTHOR_METADATA = {
    # ...
    "daschuer": {
        "name": "Daniel Schürmann", 
        "github": "daschuer",
        "discourse": "daschuer", 
        "tagline": "Mixxx Core Developer", 
    },
}

The author information including the avatar will be displayed below the post.

tags: jack, alsa, sound, latency, pipewire
status: draft

In regular intervals, we discuss how much latency the [JACK Audio Connection Kit](https://jackaudio.org) introduces when used in Mixxx. That is one of the [Sound APIs](https://manual.mixxx.org/2.3/en/chapters/preferences.html#sound-api) that Mixxx supports on Linux, and it's a layer on top of the [Advances Linux Sound Architecture (ALSA)](https://www.alsa-project.org).

Unlike analog devices, digital audio devices process audio in time slices of samples stored in memory buffers. These are passed through the various layers. The latency of a digital audio device depends on the number and size of those buffers.
The aim is to minimize the latency, so that the audible result of pressing a button or turning a knob in Mixxx is produced without noticeable delay, in order to allow DJing by ear.

The [JACK FAQ](https://jackaudio.org/faq/no_extra_latency.html) state that:
> There is **NO** extra latency caused by using JACK for audio input and output. When we say none, we mean absolutely zero.

This is true on its own, because JACK uses the buffer configured for ALSA directly to mix the audio sources together. ALSA has a second buffer with the same length that is used to feed these samples into the hardware. That's all.

However, in the case of Mixxx two more buffers are used by JACK for syncing and mixing the buffers of the patch field. It allows the client applications to use the full CPU time of each buffer cycle.

This is not a problem of JACK per se, but of the way JACK support was implemented in Mixxx.

When using the ALSA API directly Mixxx does what JACK does: It uses the ALSA buffer directly, which doesn't add any latency.

This can be confirmed by recording the own sound via a mic and measure the round trip latency. For my test, I have used the internal speaker, microphone and ALC298 Analog sound. For separating the signals in one stereo stream, I have enabled the Balance effect to move deck 1 fully to the right channel and the mic fully to the left. The test track is a 440 Hz sine wave generated by [Audacity](https://www.audacityteam.org). Then I have cued the track into the pre-roll, started recording and pressed play.

These are the resulting recordings visualized in [Audacity](https://www.audacityteam.org):

![Screenshot of audacity showing the round trip latency]({static}/images/news/roundtriplatency.png)

The upper stream is the JACK case. The left channel is the recorded master 440 Hz sine wave and the right channel is the mic input.

JACK is configured with a 1024 frames buffer and reports a latency of 46.4 ms for the sum of two buffers.
The round trip latency is 95 ms (driver + ALSA + JACK async mode + duplex stream = 4 buffers).

The lower stream is the ALSA case. Mixxx is configured with the same single buffer of 1024 frames = 23.2 ms.
The round trip latency is 49 ms (driver + ALSA = 2 buffers).

Not in the picture is the ALSA pulse device. It runs at a latency of 104 ms (driver + ALSA + 2 x pulse + ALSA = 5 buffers)
PipeWire on Fedora 34 has by default the same latency as JACK in this test.

With this picture we can verify that Mixxx actually has the same buffer size in both cases. When pressing pause, it fades the signal out over one buffer length which is equal in both cases.
The peaks in the recorded right channel is the sound of the mouse click. You can only barely see the recorded sine wave.

![Screenshot of audacity showing the fade out]({static}/images/news/fadeoutcompare.png)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

2 minor nits:

  • You could run audacity on the command line with LANG=C to make the user interface english
  • I think audacity has a dark mode that you can use to make the screenshots fit better into the general theme of our website.


For reference, I have done the same test using [`jack_iodelay`](http://manpages.ubuntu.com/manpages/bionic/man1/jack_iodelay.1.html)


3114.842 frames 70.631 ms total roundtrip latency
extra loopback latency: 42 frames
use 21 for the backend arguments -I and -O


The result is 70 ms (driver + ALSA + JACK async mode = 3 buffers). The duplex cycle is omitted here. This is one buffer more than a native ALSA implementation.

To verify that the duplex cycle is not introduced by Mixxx or the [PortAudio](http://www.portaudio.com) abstraction layer used by Mixxx, I have routed the `jack_iodelay` signal through Mixxx.

![Jack patch field showing the jack_iodelay Mixxx loop]({static}/images/news/jackpatch.png)

2048.000 frames 46.440 ms total roundtrip latency
extra loopback latency: 2047 frames
use 1023 for the backend arguments -I and -O

This is the minimum we can expect, one buffer is needed for `jack_iodelay` and one for Mixxx. The result can be confirmed with the same setup using `jack_latent_client` which just passes the input to the output.

If we connect the output of Mixxx to the input, an extra buffer is used for some reason. This can be also confirmed with `jack_latent_client` and the same feedback loop.

![Jack feedback loop]({static}/images/news/feedbackloop.png)

The upper stream shows the Mixxx results and the lower stream shows the `jack_latent_client` results.

In addition, most distros use JACK with its default "Server Asynchronous Mode" which introduce one buffer of extra latency (`--async-latency`) when accessing the sound card. In Ubuntu Hirsute 21.4, QJackCtl exposes a "Use server synchronous mode" checkbox in the sound card preferences. It is grayed out by default but becomes active if "Enable JACK D-Bus interface" is checked as well. In this case the JACK mixing is done after Mixxx in the same time interval.

## Conclusion

For now, we recommend using Mixxx with the ALSA backends even if you are running JACK. The same applies to [PipeWire](https://pipewire.org) as Mixxx uses JACK protocol to connect to it.
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
For now, we recommend using Mixxx with the ALSA backends even if you are running JACK. The same applies to [PipeWire](https://pipewire.org) as Mixxx uses JACK protocol to connect to it.
For now, we recommend using Mixxx with the ALSA backends even if you are running JACK. The same applies to [PipeWire](https://pipewire.org) as Mixxx uses JACK protocol to connect to it.
If you do want to use JACK, make sure to enable synchronous mode for better latency.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would not explicit recommend it, because I think it is not default for some reasons. It is obvious that Jack needs some time to compose the final buffer and I assume that this time is removed from the time Mixxx can use.

It might be the case that you can use in Async mode a smaller buffer, resulting to the same over all latency with a bigger buffer in sync mode, but more predictable.

At least we need to collect some experience before recommending it.


It should be also noted that JACK [can't deal well](https://jackaudio.org/faq/multiple_devices.html) with two or more sound cards. Mixxx can do the required clock sync using the ALSA API and this with no extra latency as long the underlying driver allows it. For details refer the [Mixxx manual](https://manual.mixxx.org/2.2/chapters/preferences.html#other-sound-hardware-options).

Pipewire will become default on most distros and we need to find out what is the best setup for using it with Mixxx. Do you have interest to help? Get in contact with us at [Zulip](https://mixxx.zulipchat.com)
6 changes: 6 additions & 0 deletions pelicanconf.py
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,12 @@ def __init__(self, url, title, context, css="", children=()):
"email": "deborahtrez12@gmail.com",
"tagline": "Outreachy contributor (Dec 2020 - Mar 2021)",
},
"Daniel Schürmann": {
"github": "daschuer",
"discourse": "daschuer",
"email": "daschuer@mixxx.org",
"tagline": "Mixxx Core Developer",
},
}

# Needed for Jinja2 markdown filter
Expand Down
Binary file removed theme/static/images/avatars/deborahtrez.png
Binary file not shown.
Binary file removed theme/static/images/avatars/uklotzde.png
Binary file not shown.