Jerky playback in 2024

Hey there, I can’t seem to find a solution to my Audour 8.2.0 (and previous versions 7.x) where everything seems to work really well, however once I’ve gone to sleep and then re-open project, it does this intermittent maybe ever few seconds of skipping a beat or two and continue for a few more seconds and do something similar again. Unbearable.

Initially, on another project, I thought it was fixed when I finally had all the necessary plugins installed instead of missing some, that that was the problem. But now, with all the plugins as before going to sleep, it is doing the same jittery playback eventhough it was working fine yesterday.

My hardware is AV Linux (which is MX-Linux), with Presonus Firepod.

Literally you went to sleep and left your computer running, or the computer went to sleep mode?
If the computer went to sleep mode, perhaps it is running in a power save state now and previously you set performance mode.

Hi,

If you mean Sleep/suspend I think that is a pretty bad idea when Audio recording, to be honest I never use it, I never test it and with all the things at play in an Audio recording session I think suspend is a bad idea on any platform…

Are your Ardour sessions using ALSA or JACK backend and are you booting AVL with sysvinit or systemd?

rtirq is also not restored after a suspend/resume cycle.
The soundcard is restarted and the IRQ losses the priority, one alternative is to instead use udev-rtirq which sets up IRQ priority after resume: GitHub - jhernberg/udev-rtirq: Use udev to automatically change the priority of soundcard interrupt handling threads.

2 Likes

Correct, but it can be achieved quite easily. A simple script calling rtirq service dropped into the /usr/lib/systemd/system-sleep/ directory will do the job. Something like this works for me:

#!/bin/sh
## restart rtirq after sleep/hibernation
## it seems that normal unit-dependency doesn't work in this case

case $1 in
  post)
    /usr/bin/systemctl restart rtirq.service
    ;;
esac

But this seems like a better solution anyway. Didn’t know it existed. One will always learn something new here. Thanks.

udev-rtirq doesn’t work properly on my system, it picks the wrong IRQ to prioritize, so your mileage may vary.

Didn’t tried udev-rtirq on my system, but just took a look at the code. It seems it indeed will fail to detect the correct IRQ for the soundcard in many cases. It basically fetches the PCI device address from the $DEVPATH variable (provided by udev), gets parent PCI address from /sys/devices/ and finds its IRQ to set a configured priority (if not blacklisted).

I’m by no means a PCI hardware expert, but I think it’s not enough in many cases. For example, a USB card can be attached to another PCI bridge via the XHCI Controller (like in my system) and above detection algorithm will simply pick a wrong IRQ. So the card detection process isn’t straightforward and I personally prefer the rtirq-init approach which allows user to configure a correct IRQ thread service by hand.

But udev rule provided by udev-rtirq is correct and it may be feasible to mimic its approach and still using rtirq-init. I think this rule should allow to restore IRQ thread priority after suspend/resume if rtirq-init is configured correctly:

# /etc/udev/rules.d/99-rtirq-init.rules 
ACTION=="add", SUBSYSTEM=="sound", KERNEL=="card*", RUN+="/usr/bin/systemctl restart --no-block rtirq.service"

Didn’t test it though.

Yep, that’s what happens on my system too. So I’m using a custom solution now, also because on my system the IRQ numbers change on every boot so you can’t pin rtirq-init on a specific IRQ.

Okay, thank you so much for the wealth of information. A simple restart so far seemed to correct the issue. I’m a bit of a linux newb, so I’d rather not mess with any scripts and just do a restart.

1 Like

Hacked my own script together to deal with threaded IRQs: autostatic/rtcirqus: rtcirqus, real-time config IRQ udev service, is a Python script that sets the real-time priority of IRQ threads of onboard and USB audio interfaces dynamically. - Codeberg.org
It’s more or less a combination of udev-rtirq and rtirq poured into a Python mold.

Excellent work Jeremy!

So if I have this right… this can replace rtirq-init on any given system? What if the system already has rtirq-init installed (ie AV Linux comes with it as part of the default install) will rtcircus interfere?

Also… I’m still quite new to PipeWire and I’m not 100% sure on how many of the traditional RT-friendly hacks are still useful, I understand that PW has some sort of IRQ threading now, does it work on it’s own or in concert with rtirq-init (and potentially rtcircus)?

1 Like

Thanks Glen! rtcirqus could be a replacement of rtirq-init. It does what rtirq-init does but then only for threaded IRQs related to audio interfaces. rtcirqus and rtirq-init will interfere with each other as they both work on the same level. Regarding Pipewire, isn’t the concept of “IRQ-based ALSA driver” from Pipewire different from working with threaded IRQs? It’s more related to how JACK communicates with ALSA right? If Pipewire can change the priority of audio related IRQs itself then we wouldn’t need neither rtcirqus nor rtirq-init anymore.

Edit: scourged through some long forum threads here and there and from what I encountered I get the impression that the “IRQ-based ALSA driver” has nothing to do with working with threaded IRQs. It’s a polling thread that uses a real-time priority.

I’ve posted a bug report and a PR to fix it for doing the install into a Python virtual environment, without the need to install system-level packages.

If this kind of contribution is acceptable, I can also post a PR to update the README to document this kind of usecase. FWIW, as a professional Python developer over the past 25 years, I’ve come to never rely on the OS-distributed versions of Python packages which can be downloaded trivially from the Python Package Index (https://pypi.org/).

1 Like

@tseaver Thanks, merged your pull request! Contributions are welcome!

Thanks for sharing the script. It is definitely a step in the right direction.

Unfortunately, it doesn’t work on my system with USB audio interface, threadirqs and xhci_hcd USB host controller. It detects the kernel with threadirqs and the interface correctly (some additional output added to to the script for better diagnostics):

# ./rtcirqus.py
INFO: Loaded kernel is using threaded IRQs and threaded IRQ processes detected
INFO: USB cards found: MIDISPORT 2x2 Anniv, UMC1820
INFO: Setting RT priority 85 for USB card UMC1820 path /sys/devices/pci0000:00/0000:00:02.1/0000:01:00.2/0000:02:02.0/0000:03:00.0/irq
INFO: IRQ: 24

But set_rt_prio(irq, prio_rt) assumes the IRQ number gathered in get_irq() is the same as process thread assigned to the interface:

for proc_name in procs:
     if irq_re.match(proc_name) and irq in proc_name:

It’s not the case here. The irq_re would match xhci_hcd process but there is none with IRQ 24 and the card is actually on IRQ 45:

songo@stalker:~$ pgrep -l  'irq/24'
songo@stalker:~$ pgrep -l  'irq/45'
22510 irq/45-xhci_hcd

It’s pity, but don’t know how to get the correct interrupt reliably in such cases. Always struggled with this. :frowning: It looks like the right IRQ isn’t simply listed in any /sys/devices/pci*/irq file, hence another approach is required. Maybe someone will have an idea?

Kind note to the mods: what about moving rtcirqus related posts to a new thread? /me thinks Jeremy’s work deserves more exposure.

My empirical and sloppy method is to (as I commented in my /etc/rtirq.conf file to
### launch some zak or vid to the card to search for and "watch grep xhci /proc/interrupts"

Hence, for example, in a console:

/usr/bin/mpv --audio-device="alsa/front:US4x4HR,DEV=0" somethingwithsound

and another console:
watch grep xhci /proc/interrupts

And simply trust my eyes to reckon which IRQ moves the fastest, told you 'twas sloppy :smiley:

Some simple and clever way to script that may exist :wink:

Yeah, it is almost exactly what I’m doing when want to check it precisely! Just start Jack at 64/2 and watch IRQ counter skyrocketing. :slight_smile:

For now just setting relatively high priority to all xhci_hcd threads. Giving that I have separate PCIe USB interface just for connecting USB audio it works pretty well. Not the best solution, though.

Would it be possible to open a bug report at Issues - autostatic/rtcirqus - Codeberg.org? If possible with the output of cat /proc/interrupts. Thanks!

No problem. Here it is:

1 Like

I’ve kicked in another PR, adding an entry point which creates an rtcirqus script when the project is installed into a Python virtual environment: that script can then be copied (or symlinked) directly into /usr/local/bin.