[solved] XRUN every ~110 seconds with USB audio interface

I’m attempting to switch from a HiFi Berry audio interface to an external Audient iD4 MKII, it works mostly with these jackd settings:
-P 70 -t 2000 -s -d alsa -d hw:iD4 -r 44100 -p 256 -n 2 --shorts -X raw

However, every 110 seconds or so there is an XRUN. Engine responses vary, pianoteq goes silent and never recovers, zynaddsubfx drops out for about one second then recovers.

Based on the timestamps of 30 events, the average is 111s, minimum 99s, maximum 123s. So it could be something which runs then sleeps for 100s.

According to snoopy, no process is executed at these times, so this isn’t like Issue #412

I’m running an up-to-date stable zynthian. I’ll continue attempting to diagnose, but I wanted to raise the issue now just in case someone has an idea, or a suggestion for diagnosis approach.

I’ve solved this, my jackd settings are now:
-S -P 70 -t 2000 -s -d alsa -d hw:iD4 -r 44100 -p 256 -n 2 --softmode -X raw

The 2 main differences are:
–softmode, when I said Pianoteq wasn’t recovering from these XRUNs, what was actually happening was jack removed Pianoteq from the graph because it is treated as a slow-responding client, so it wasn’t the root cause but helped with recovery
-S, a basically undocumented option to put jackd in synchronous mode. This completely eliminated the XRUNs for me. It is mentioned in a couple of places

I have seen this before and rather assumed (actually did some tests before) that this statement is true although your post makes be reassess my memory!

We need to validate what impact synchronous mode has on each jack client and plugins.

Thanks @steveb for this investigation. Let’s look to see what lessons can be learned for the wider community and other interfaces and modules.

[Edit] I have read elsewhere that the default mode of jackd2 is asynchronous which adds an extra buffer period. This is probably want we no longer need to use 3 buffers for some USB audio devices. I haven’t found a description of synchronous mode but seem to remember reading about it previously. I thing soft/hard are not relevant to sync mode where every client must process and deliver all data within the prescribed period whereas async allows early / late delivery. I wonder if that involves a degree of samplerate conversation or similar to allow for stream slippage. That works certainly explain the higher quantity of xruns.

1 Like

Can you test -r 48000 with and without -S? It might be the thing about usb interfaces not liking fractional latencies.

I tried different options again with a little more discipline, and I’d like to retract -S as being the solution.

Using the following jackd as a baseline:

-P 70 -t 2000 -s -d alsa -d hw:iD4 -r 44100 -p 256 -n 2 -X raw

I tried the following differences:

-r 44100 -n 2 (XRUN, period ~110s)
-r 44100 -n 3 (XRUN, period ~210s)
-r 48000 -n 2 (XRUN, period ~110s)
-r 48000 -n 3 (XRUN, period ~210s)
-S ... -r 44100 -n 2 (XRUN, period ~110s)
-r 44100 -n 2 --softmode (NONE!)

Based of the testing this time I’d conclude the following:

  • -r 48000 or -n 3 makes no difference except some correlation between -n and the XRUN period
  • -S on its own doesn’t help
  • --softmode avoids the XRUNs

I also tried rebuilding jack2 to upgrade from v1.9.14 to v1.9.20. It made no difference but maybe testing should switch to the latest release, 2019 was a while ago now.

2 Likes

Hmmm, The only non-fractional latency you really tested was -p 256 -n 3 -r 48000

Could you have a look at the link and try some of the other ones in bold?

You’re on a pi4?

I’ve tried 4 non-fractional latencies now, and the XRUNs occur regardless. I’ve plotted the XRUN period with the latency to show there is a clear correlation:

I’m running kernel 5.10.60-v7l+ on a pi4, is there a way I can try a 5.16 kernel without building it myself?

1 Like

Soft mode is basically masking the xruns. It allows clients to remain connected and for buffer overruns to just overwrite or truncate data, i.e. where an xrun would have occurred there is now a discontinuity. The impact may be less, i.e. there is not a partial period of silence (manifesting as an audible click) but sample discontinuity which also clicks - maybe less noticeable. This can also lead to odd timing issues. Basically soft mode may have less impact on the audio but does not stop the problem. It masks the problem which may make it more difficult to track, i.e. without indicaiton of xruns you don’t know the system is overloaded / misconfigured. (I know that we all want the clicks to just stop but we need to know when they happen to track the cause!)

Are there any other usb things plugged in?

I have to disagree with @Baggypants on this. Time is an illusion. Lunchtime doubly so… or to be more accurate, time is a social construct. The idea that fractions of milliseconds should matter any more than milliseconds themselves being fractions of seconds seems absurd!

An xrun is an underrun or overrun (hence the ‘x’ acting as a wildcard in its name). These occur when there is insufficient or excessive data delivered to a software or hardware audio module.

An underrun occurs when the source is slow and delivers too little data in the prescribed time period. The destination must continue without the expected data which (usually) leaves a hole (silence) in the audio (although could leave previous (stale) data depending on the code) which manifests as a click.

An overrun occurs when the destination is slow and cannot receive / process the data before the source needs to reuse it’s output buffer. The data must be discarded which results in a discontinuity and may even lead to a subsequent underrun.

Softmode allows overrurns to write over destination input buffer rather than discarded whole buffer. The same sample slippage occurs but the audible effect may be less impactful. This may have significant effect on the module if it depends heavily on the data, e.g. convolution.

The core aim is to allow each module to complete it’s process of receiving a block of data, processing it and delivering it to its output buffer within the period defined by jackd. This includes ADC and DAC which will run at their own clock rate(s). Jackd should use the ADC/DAC clock hence you should use a samplerate that is native to the soundcard. Many soundcards allow this to be changed, e.g. 32000, 44100, 48000, 88200, 96000 samples per second. I would say this is the first thing to configure so that jackd is running at a rate supported by the soundcard. Consistently timed periodic xruns is an indication that this is wrong. The drift between soundcard samplerate and jackd (unlocked) rate will cause xrun after a quantity of periods when the buffer had emptied / filled hence the xrun occurs with regular period.

Most modules have peaky load. The CPU (and other hardware / software resources) may be able to process a module’s average load okay but may fail occasionally due to a (possibly sustained) peak of high processing. This may result in the module failing to complete it’s processing in a period, triggering an xrun. Reducing the load can reduce the risk of this, e.g. using less demanding configuration / preset. Increasing the available time to process each block of data also reduces this risk, e.g. increasing quantity / size of buffers. This smoothes out the load, giving more time during each processing period for those peaks to be processed. This allows modules to run without xruns if they have high transient peaks but a low average load. It doesn’t fix persistently high load. Increasing the time for proceeding increases the latency.

Jackd process all nodes in its graph synchronously which means that everything has the same latency. If you have a module that needs longer to process is data then all other modules must wait the same time. This means you can’t have lower latency where needed whilst allowing modules that may not benefit from low latency to run slower, e.g. synths with slow attack.

Pipewire does allow different latencies but this requires a greater overhead within the sound system. I am eager to investigate if / when Pipewire can provide comparable performance as jackd and whether such features may provide tangible benefits within Zynthian.

A midi controller and the touch screen for the HDMI display, no change to the XRUNS when they’re both unplugged

1 Like

I updated the kernel from 5.10.60-v7l+ to 5.15.32-v7l+ using rpi-update, and so far there have been zero periodic XRUNs while using -r 48000 -p 128 -n 3!

This kernel doesn’t have the commit originally referenced but it does have a couple of others which may be helping.

1 Like

That sounds promising. How does it behave with -n 2? It should be possible to run with two explicitly defined buffers due to the extra buffering performed by the ALSA driver.

Good news that rpi-update worked. We will have to do some more testing but it might be a relatively simple migration.

AFAIK there’s no way to avoid xruns on usb. I’ve reverted to recording everything on the sd and then moving the files to another machine for editing.

I thought I would try out the zynthian software on a pi with an (unsupported) sound card called the iqaudio codec zero and to make it harder for myself i was using a zero2w.
After several days of XRUNS every second and constant errors, i came across this page and tried rpi-update (which updated the kernel to 6.1.58). This immediately fixed whatever was causing the xruns and making zynthian crash.
Now I am able to select any sample rate without xruns, and play multiple tracks simultaneously, previously this card only occasionally worked at 96Khz, crashed at any other sample rate and was unable to load the snapshots.
There are warnings that rpi-update is a bad idea and may break other things, but all seems to work fine so far. Thank you steveb and zynthian software coders.

2 Likes

Hi @bitmat! Welcome to Zynthian Land. We are a friendly group who rarely bite!!! Have fun here.

It is interesting that you have seen this improvement. As you say, we do not support updating the Debian subsystem beyond what we have already tested but intrepid explorers like yourself identify things that can improve the system so we can look at updating to a later kernel if required.

I had not seen the CODEC chip used in the IQAudio CODEC Zero - DA7212 by Renesas. Indeed I can’t remember hearing of the chip manufacturer before! There is no mention of this device in the change logs for the kernels between Zynthian’s and the latest stable (6.5.9) so it is not obvoius what changes were done that have fixed this issue. The DA7212 can use I2S (which is the standard audio interface on Raspberrry Pi) but it has a lot of configuration options via its I2C interace. Zynthian uses I2C heavily and maybe there was some conflict on that bus - who knows?

What is that audio quality like from this device? I see that it has a headphone output and a mono speaker amp but no line outputs so I wonder whether hooking up to an external amplifier may introduce noise and/or distortion. The CODEC is not targetted at high-end audio but that does not mean it cannot be used as such and of course we have a synth here, not a golden ears hifi system! Do let us know how you have your device connected and what your opinion on its performance is like.

Have fun with your box.

1 Like

Renesas was formed from the ‘spin off’ of the semiconductor divisions of NEC Electronics, Hitachi, and Mitsubishi in the early 2000s. They later acquired Dialog, which is where the DA7212 came from, along with Intersil and IDT. They are a major ARM manufacturer, probably second only to ST in terms of independent semi makers. They have been making some noise lately about making RISC-V chips.

3 Likes

Thanks for the welcome @riban.
The sound quality of the zero codec is excellent, there is also a stereo aux in and stereo aux out at line level. The minijack socket is a mic input, but turning on those inputs and cranking the gain it does start to hiss slightly.
I’ve only heard digital noise on the aux out while i was plugging a guitar directly into the aux input and the output was plugged into an ungrounded input, i.e a battery powered amp instead of my mixer.
I’ve not used the audio inputs on the zynthian software yet, this was while using the zero codec with another excellent pi distro called pipedal which turns a pi into a guitar fx pedal, and it sounds much less noisy if the guitar is pre amplified before going into the aux inputs.
I tried a few different open source audio pi distributions last week, including samplebox, pipedal, patchbox, pi-stomp, and zynthian (winner), mostly for fun and to test the zero2w, but thanks to this forum and others, my understanding and knowledge of command line syntax, and jack and alsa routing has increased greatly.
Thank you

2 Likes

Makes for an interesting read.
Viewed from the user side, there is much mention of sample rates and jack options. This remains one of the few performance features that cannot be adjusted from the GUI. At present it requires a webconf mod and zynthian restart to change a zynth from one sample rate to another. This means you need a browser around to perform this change. A problem with locked audio sources like SPDIF which mean the zynth is t the back and call of extrnal audio devices. You get heavy grinding noises when a zynth plays a 48000 rate sample on a 44100 set zynth… Be nice to flick this over easily.

I agree that adding a configuration option for samplerate may be advantageous / desirable but I don’t think it is the solution to that particular issue. If a device cannot lock to the incoming samplerate or samplerate convert then it will have discontinuities due to lost or excessive samples. The problem is more pronounced the further the samplerates differ but even at the same nominal rate, there will be a difference and hence pops and squeeks.

Zynthian currently uses JACK for its audio interface which does not support ad-hoc / dynamic change of samplerate and needs to be restarted for this to be changed. There are some issues with doing this in Zynthian. They are by no means insurmountable but would need to be resolved before such a feature were added.

@bitmat it is interesting to hear your good experience with this soundcard. I didn’t notice the line outputs on the card but observed these are not available on the chip so the card must be using the headphone output and buffering to provide line level. Regarding guitar preamp - that has been discussed here before. It is most advantageous to add an impedance matching device (often referred to as a “buffer” in the guitar world) between the guitar output and an audio device, e.g. soundcard. This is because the pickups on an electric guitar expect to feed a very high impedance like old valve amps used to be. A Boss pedal in bypass works well for this, providing a JFET buffer stage, as do the Behringer range of pedals so you can do it for about £25. The iqaudio device looks interesting. I am looking for a CODEC chip for a device I am working on and so will take a closer look at the DA7212. Cheers!

[Edit] Sometehing I like about the DA7212 is its support of TDM. You can connect several to the same bus, configure as “left justified” and set an offset on each device. This would allow cascading several DA7212 to provide multiple inputs and outputs. I don’t know if the Raspberry Pi supports this. Last time I checked the I2S ports were stereo only (which is a limitation of I2S). Someone has in the past written a driver that multiplexes the I2S port running at high speed but it was a bodge and had issues.

2 Likes