Hotplug USB audio

This was a quick win. There is overhead which I expect pipewire will also have. It isn’t perfect and it will be good to get pipewire working fully in zynthian but I suspect that will require a lot of effort and we have many other things to do. Maybe pipewire, having built-in multicard support may have optiised this more than the bolt-on alsa_in/out solution. We need someone with enough time to get into this in a lot of detail.

This is really close to how signal flow is displayed in Reaper using nested “folder” tracks, and it’s very intuitive and fast to work with once you get used to it.

1 Like

Hi @riban !

I’ve been checking your latest changes and have detected a minor issue:

  • Initial state: Zynthian On. Hotplug audio disabled. Behringer UMC404HD not connected.
  • From zynthian admin, enable Hotplug Audio. I see the Audio In / Audio Out empty headers. It would be nice to see a “No devices detected” instead of nothing.
  • While keeping the Hotplug audio view open, connect the UMC404HD to zynthian’s USB port.

=> Expected behavio(u)r => List is refreshed and show the newly added devices
=> Observed behavio(u)r => List is not refreshed. I’ve to go back and re-enter to see the devices.

For the rest, it seems to work flawlessly.

(I know british english is the only right english … but you should remove these twisted french influences!! :grin: )

Kind Regards!

Excuse my ignorance, mate …
Is the “overhead for scanning for ALSA” so big? You only need to scan when audio input / output views is open, right? No need to scan all the time.

Regards,

@jofemodo I fear you colour my behaviour wrong!!! :grinning:

The audio in/out menu does update dynamically but there is a lag whilst detection occurs.

We need to background scan because we want devices to work as they are plugged in, not have to go to menu every time.

Overhead is significantly. I know you are already looking at reducing this.

I too have experienced xruns in my last two shows. Never heard a single one before. At first I thought it was an intermittent wire or what not.

Are you using alsa_in alsa_out ? I had used it for many years before changing oh so permanently to Zita-ajbridge (zita-a2j, zita-j2a) which has way less overhead and much cleaner output. Could this be in anyway a solution ?

1 Like

Yes, alsa_in and alsa_out are in usage as displayed using ps -aux | grep -i alsa which returns :

/bin/alsa_in -d hw:CODEC -j zynain_CODEC
/bin/alsa_out -d hw:CODEC -j zynaout_CODEC
/bin/alsa_out -d hw:Headphones -j zynaout_Headphones

I’m just curious here : why not use the dropin replacement zita -d hw:someHardware -j someJackName. Any pros or cons ?

I did some experiments with the various options, including zita. There were advantages and disadvantages to each method and alsa_in/out was the least problematic solution. I don’t recall now (but probably documented it somewhere, maybe here in the forum!) but suspect the challenge with zita was to get it work with the wider zynthian model including how zynthian interfaces with alsa and jack.

If you want to test what benefits a change may offer and also how it integrates with similar functionality as currently impleted with alsa_in/out then please do and report your findings.

I see. Since I thought the problem was CPU usage I thought it could be a good solution to avoid xruns.

Are the xruns logged in some way on the Zynthian? I’m close to completion of my “revamped setup” and so far, no xrun ! :slight_smile: But, I want to run it overnight with some automation and know for sure if there was (or weren’t) any xruns.

So, I still had obnoxious xruns here and there. I tried removing unneeded inputs from the USB card. It did not change anything. So I went with this highly advanced and very good practice :melting_face: solution :
With pwd returning /usr/bin :

sudo mv alsa_in{,.back}
sudo ln -s zita-a2j alsa_in

Rebooted. :neutral_face: Not a single xruns for about an hour of music. :smiling_face_with_tear: So I guess that, in my case zita seems to be less CPU intensive. I’ll continue with testing this out.

Thanks @PeterLuck for your investigations. I was just reading the docs for zita-a2j and see that it is supposed to be a drop-in replacement for alsa_in with lower CPU load and better audio performance. I will give it a test. Have you tested the corresponding zita-j2a replacement for alsa_out?

If these can be used reliably without other problems then I will do a patch to replace alsa_in/out with zita-a2j/j2a.

I have tried using zita-abridge and it mostly works. There is a difference in behaviour to jack_in/out. Supplying no channel count will present all channels in jack_in/out but only 2 channels in zita-abridge. (I have not figured out how to report issues upstream.) Adding -c 128 will work, reporting a warning that it has chosen fewer channels. With my code changes (in dev branch zita-abridge in ui & sys) it appears to work but I am yet to be close enough to my zynthian to test the audio behaviour.

[Edit] After I have tested the audio, if it is okay - I will merge into vangelis.

It’s perhaps worth mentioning that zalsa is an internal-client version of the zita bridge, for a short while part of the main jack repository, but as of a little while back provided by the example-tools repository: GitHub - jackaudio/jack-example-tools: Official examples and tools from the JACK project - it uses the same parameter layout as the zita bridge clients, but the library name is zalsa_in and zalsa_out for client creation purposes :slight_smile:

1 Like

Thanks @leinir. I will test it out when I am back in the lab.

1 Like

I was able to test zita bridge today and it does not work with the Tascam US-16x08. It seems to be at a very wrong samplerate - like an order of magnitude out. I will test @leinir’s suggestion next.

I get the same result with zalsa_in/out. Maybe zita bridge is not handling multiple ports well, e.g. interpretting 16 ports as 2 and multiplexing them wrong. This is currently not of any use so we may need to continue to use alsa_in/out.

[Edit] If you use the correct quantity of channels for the -c parameter then both zita bridge and its internal clients work but we need to detect the correct quantity of channels before starting. I can get this info with alsaaudio:

import alsaaudio
alsaaudio.PCM(alsaaudio.PCM_CAPTURE, device="hw:US16x08").info()["channels"]
alsaaudio.PCM(alsaaudio.PCM_PLAYBACK, device="hw:US16x08").info()["channels"]

I will try to integrate this.

1 Like

There is a bug in jackd that unloading an internal client triggers it to crash. This is why I have avoided using internal clients in the past. I think I reported it upstream. I will continue to try to get zita bridge integrated…

[Edit] I found that using the jack name to unload a client works but using its class fails, e.g.

jack_unload zynain_US16x08 works but jack_unload zalsa_in crashes jackd.

Actually, that is not true. It all seems to work today. I had compiled and installed the latest version of jack2 from github then uninstalled it. I can’t see why behaviour is different today than it was last night, unless the install/uninstall left some newer files in place.

My Tascam US-16x08 is sometimes not properly detected and I suspect it to either be the audio device or the USB ports on the RPi5 which seem to be a bit flaky, particularly the USB3 ports.

I will play some more and see if we can get internal client working. The danger of using internal client is that if the client bombs out, so does jackd so we only want robust internal clients running. I wonder whether a dodgy USB interface might trigger zalsa to fail, dragging down jackd - or maybe that was happening on unload yesterday.

[Edit] Removing a USB device whilst it is in use by an internal zalsa client does not remove the zalsa client from the jackd graph. Subsequent attempt to unload the zalsa client crashes jackd, presumably because zalsa does not handle the state gracefully and crashes, bringing down jackd. I feel this is too big of an impact on the zynthian subsystem. Although jackd will recover (service restart) we don’t want a hot plug USB audio device interferring with the rest of the system, e.g. you may use USB audio for a monitoring feed but onboard sound for the front-of-house main mix. If the USB device fails or is accidentally removed, we don’t want to kill the main output, even momentarily. I have submitted an upstream bug report.

Hi @riban,

Since a day I cannot select output ports anymore. Is this perhaps related to the discussion here?

Cheers,
Maarten

Hi @maartmaart. There was a big in Vangelis stopping output routing. I thought I had fixed it. I’m to tired to look at it now but will check tomorrow.

Hi @riban,

Hope you had a good night rest.
Hope you can fix the routing.

Cheers,
Maarten