Pipewire (built from source, not from RPi repo)

Howdy!

In my search for an easier solution to be able to interact with more than just a single sound card at a time I tried Pipewire. I’ve built it from git (apt repo had quite an old version). It took some fiddling with systemd’s service files (pipewire runs as a user service, where everything else runs as a system service).

It appears mostly to work now. With the default ZynADAC card selected in the webconf tool, I can:

  1. Capture/play to USB headset using UI of Zynthian (as soon as I insert USB headset it shows up in the Sound Capture/Sound Playback menu
  2. With the addition of g_audio I can use Zynthian as a USB sound interface connected to my laptop.

Somewhat minor issues:

  1. Zynthian gets confused by midi ports now - whenever a synth is added - controls do not work until I re-patch it in Patchage properly. Shouldn’t be hard to fix.
  2. MOD-UI gets confused by names of devices/ports and UI breaks. Looks like it is due to different cards having same name for ports and MOD-UI using only port name as ID, not card+port name. Should be fixable upstream.
  3. Probably related to #1 - zynthian doesn’t automatically connect added synths to sound output - i have to manually select it in the settings of the layer.

Obvisouly, usage of multiple cards comes with latencies and other potential issues. But at the same time, using pipewire allowed me to quickly connect USB headphones I had lying around. And I hope I will figure out Bluetooth soon too. Recording digital audio via USB-C sounds like a good option to have (delay there quite significant, so it is not good use for live performance).

What yalls opinion about that setup? Is it something Zynthian might adopt? If so - I could try resolve issues in Zynthian and MOD-UI around port names. But I wanted to make sure it is worth the time.

2 Likes

I think it was @Baggypants who brought Pipewire to our attention. It looks interesting and I have wanted to play with it but initial attempt was thwarted and have had other commitments since. It is interesting to hear you say it has higher latency (than jack?). It is imperative that we strive to reduce latency from the current value which is just on the edge of acceptability for many. If you have a recipe to make Pipewire work in Zynthian then do please share so we can make our own assessment. If it is (relatively) easy to install I might just have another look.

Sorry, I was not clear - latencies show up when, for example, I am putting audio into ZynADAC’s Audio In, route it to USB-C and listen to it on my laptop. Since USB-C audio interface implemented in software, there are obvious delays one would expect.

In regular situation of midi or audio into ZynADAC and output from ZynADAC - no noticeable latency so far.

I am still poking it trying to get it work right without launching console. Once I nail it down, I will try it again with brand new image to make sure I did not miss steps. Once that done - I can post steps to replicate my setup using stock SD image.

Read the website, precisely what is it? And what is it doing?

It is acting as the sound and video layer between hardware drivers and userspace applications, similar to what jack does for audio only. It implements samplerate conversion to allow multiple hardware to be used freely within the routing graph. It allows any source of audio / video to be used within that graph, e.g. web browser output. The workflow sounds great but I wonder how successful they have been at implementing it, particularly around latency and performance (xruns). If this is some magic that reimplements jack in a more efficient way then great! I am sceptical it has yet done that. It does provide a jack compatibility layer which should make it a drop in replacement for jack.

AAh right. another community arrives at graphs :smiley:
Make them properly structured and we have hardware environment snapshots. :smiley:

The cut and dried test to my understanding is how well it performs in real world situations, if it can hold a USB Source synced against an on board sound card.

Perhaps, I should see if it aids my USB Guitar lead, back of this list thou’

Yes - that is exactly what @averagejoe is trying to do - combine multiple audio interfaces. It is a similar problem to using the onboard sound for headphones. It would be good if this works better than jack + alsa_in / alsa_out.

Philosophically it feels more considered.

Get’s struck by passing raven whilst in a rather reflective mood …

I tried to put together steps necessary to get pipewire working on Zynthian. It requires VNC access to use Patchage to correct some errors (most importantly - disconnect midi_ctrl output)

Install building dependencies:

apt install -y ninja-build libudev-dev libavahi-client-dev libusb-dev libcap-dev libbluetooth-dev libsbc-dev librtaudio-dev libusb-1.0-0-dev libgstreamer1.0-dev libcamera-dev libwebrtc-audio-processing-dev libwebrtc-audio-processing1 libsystemd-dev libfdk-aac-dev rtkit
pip3 install meson

Install pipewire

https://github.com/PipeWire/pipewire.git
cd pipewire
meson setup builddir -Dprefix=/usr -Dsystemd-system-service=enabled -Dsystemd-user-service=disabled -Dpipewire-alsa=enabled -Dpipewire-jack=enabled -Djack-devel=true -Dlibusb=enabled
ninja -C builddir
cd builddir
meson install
cp -r /usr/share/pipewire /etc

Add override for jack2 service
systemctl edit jack2

[Service]
ExecStart=
Type=simple
ExecStartPre=/usr/bin/timeout 5s /usr/local/bin/jack_wait -w
ExecStart=/usr/local/bin/jack_wait -w
Restart=
Restart=on-failure

Fix user error when starting pipewire-* services
systemctl edit pipewire.socket

[Socket]
SocketUser=pipewire
SocketGroup=pipewire

systemctl edit pipewire.service

[Service]
User=

systemctl edit pipewire-media-session.service

[Service]
User=

Reload all systemd services
systemctl daemon-reload

Enable pipewire services
systemctl enable pipewire pipewire-media-session

Enable JACK emulation

echo "/usr/lib/arm-linux-gnueabihf/pipewire-0.3/jack/" > /etc/ld.so.conf.d/00-pipewire-jack.conf
ldconfig

Pipewire configuration tweaks:

Better naming of sound cards in /etc/pipewire/media-session.d/alsa-monitor.conf (at the end of the file but before “]”)

    {
        matches = [{ alsa.card_name = "snd_rpi_hifiberry_dacplusadcpro" }]
        actions = { update-props = { node.description = "System" }}
    }
    {
        matches = [{ alsa.card_name = "bcm2835 Headphones" }]
        actions = { update-props = { node.description = "Headphones" }}
    }
    {
        matches = [{ alsa.card_name = "bcm2835 HDMI 1" }]
        actions = { update-props = { node.description = "HDMI 1" }}
    }

Disable ALSA sequencer module in /etc/pipewire/media-session.d/media-session.conf:

with-audio = [
    [...]
    #alsa-seq
    [...]
]

And finally - reboot.

Current problems:

  • If hifiberry card is named “system” above (lower case) - it is not visible in the “Audio Output to” list. Also, “jack_lsp -A” shows “system” port is aliased to HDMI for some reason.

  • If RPi’s headphones card is named “Headphones” above - it is not visible in the “Audio Output to” list

  • MOD-UI is not working when started from Zynthian - it crashes “mod-host” service with:
    /usr/local/bin/jack_load: symbol lookup error: /usr/local/bin/jack_load: undefined symbol: jack_internal_client_load
    This likely happens because Zynthian checks jack outputs results to detect mod-ui finished loading. And jack_internal_client_load appears to be not implemented in jack emulation libraries of pipewire.

To disable these changes:

systemctl disable pipewire pipewire-media-session
rm /etc/ld.so.conf.d/00-pipewire-jack.conf
rm /etc/systemd/system/jack2.service.d/override.conf
reboot
4 Likes

So after playing with it a bit more I certainly like the flexibility pipewire offers. But since pipewire was made with multiple devices in mind, it doesn’t do some things that other JACK software expecting. One of these is the interconnection between different sources and sinks.

For example, we launch jack_capture when we start record. By default it tries to record from system:playback_* I believe, which would not exist on a system with multiple cards, since each card would be named differently.

For that particular issue adding an option to what to record into Zynthian UI probably is necessary.

And perhaps, some kinds of patching UI, that restores itself when connecting different nodes… For example, when manually patching, I connect all output to HiFiBerry’s playback_1/2 ports, and then connect HiFiBerry’s monitor ports to jackpeak and Headphones… It would make sense to connect jack_capture to it as well…

Not sure where all of it fits in the longterm Zynthian vision… Do you guys see multi-device usage, or realistically, you guys will stick with single-card and JACK2 as a foundation of it?

Found workaround for MIDI breaking - disabled alsa.seq module in media-session.conf (I’ve updated steps above to include this fix).

1 Like

Pipewire definitely is interesting. The version in Debian 10 was not quite there, though. The Debian 11 version is much more usable: PipeWire - Debian Wiki
Unfa experiences with pipewire: I've replaced JACK and PulseAudio with PipeWire and this is what happened - YouTube

Pipewire is in very active development. I am using it on my work laptop with Ubuntu 20.04 and a few months ago I experienced problems and rolled back to Pulseaudio. Now I run Pipewire full-time and am able to connect jack-based applications to it while still keeping PulseAudio clients happy. It also works just as it should with apps like Fruity Loops and MPC Beats running under Wine.

I think it would be the right direction for Zynthian. But as of a few months ago, you had to build it from the source (which wasn’t really that hard btw.)

While I understand that external USB sound cards (my use case where I started researching Pipewire) are not suitable for professional usage due to latencies, my current setup doesn’t force me to pick either way - I can have both at the same time and use external USB card where latency is not crucial, and keep using ZynADAC card for live performance/recording.

Switching to Pipewire will require some changes into UI which is currently built with the assumption there is a single sound card in use. I haven’t tried the recent test branch with Pipewire, perhaps a new mixer will resolve these issues I had with routing things to the right port? (I had to VNC into RPi and configure jack connections from the desktop UI)

1 Like

This got some discussion in zynth club,. I was pitching the idea of using a hifiberry amp2 as the current headphone output and selecting a behringer usb device ( UMC404HD/UMC1820) as the primary audio source. Both USB options feature a pre/post Mix feature which allows externally sourced audio to be mixed throu against zynthian engine generated material which seems a viable performance device. But this really is nothing more than a short term kludge, when/if/ I get around to trying it out.
Pipeline seems a natural progression from Jack in this regard, and given the overall limitations of different hardware implementations the ability to make sensible choices and educated compromises seems to be a sensible move from zynthian’s open source objectives.
The ability to have a suitably confusing Pipewire/jack choice in the webconf to unsettle the average user would appear to be a possibility and would probably tidy up bits of the relationship between zynthian objects and the audio server that handles the process.

Metrics would seem to be a useful data set to develop.

Many of the features of Pipewire benefit desktop users and that is where I see a lot of discussion, review and development occuring. We would be interested in the professional audio element. I would like to see how that is best managed. I would imagine it would be similar to jackd, e.g. a service with config that just works once started and can, on the most part be ignored. We could already use it’s jackd interface to try it as a drop-in replacement and identify if any jackd specific interface is not implemented by Pipewire. We could then look to migrate to native Pipewire interface. All of this whilst monitoring performance to ensure no significant degradation.

We could do all this and I would love for it to work but we need the effort and time which I can’t see offering appropriate cost/benefit at the moment. I suspect that Pipewire will perform less well than jackd at the moment. Of course anyone willing and able to prove me wrong is very welcome. I like it when an assumption about technology is invalidated and we see a benefit where we had assumed there was none!

It makes sense for a desktop distro to switch to PipeWire. PipeWire can provide the features required of a desktop environment. I am still to be convinced it is up to the job of replacing jackd as a professional audio layer. I am eager to be convinced…

https://bootlin.com/blog/an-introduction-to-pipewire/

An excellent, as usual on bootlin and in depth post about pipewire.

Jack and Pipewire seems to be able to work together.

PipeWire 1.0 Planned For Release Later This Year

PipeWire announced plans for 1.0 release in 2023:

Includes this tidbit:
The missing feature that is being worked on prior to PipeWire 1.0 is an IRQ-based ALSA driver for professional audio purposes that can match the latency of JACK. A solution to that feat is currently being worked on via this Git branch.

3 Likes