December 2018

The first half of last month went pretty well in terms of time management – I got things done and had some time for PipeWire too – but during the latter half (and also the first week of January) I got very little done. Oh well, let’s call that a Christmas break, I’ll try to improve again in the future. Here’s what happened last month:

PulseAudio

I submitted a fix for a volume slider alignment bug in pavucontrol (waiting for review).

The rest of my time went into patch reviews (well, in addition to responding to discussions on the mailing list and bug tracker, as usual):

  • Hongxu Jia added a new configuration option: –disable-running-from-build-tree. The option disables code that detects logic that is used to support running PulseAudio without installing it. Running without installing can be convenient when doing development, but supporting it requires embedding some local file paths in the built daemon, which makes reproducible builds difficult, so that’s why it’s good to be able to disable the feature.
  • Hui Wang implemented automatic stream moving when the default sink changes. This is a great improvement, it’s something that I’ve wanted to fix for a very long time. The patches had some issues, so more iterations are needed before the patches can be merged.
  • João Paulo Rechi Vita implemented automatic profile switching away from a profile that becomes unavailable. This helps especially with HDMI: when a monitor is unplugged, switching the HDMI sound card profile forces streams to be moved to some other output. Before this change streams often kept playing to the non-existent HDMI output after unplugging a monitor (whether that happened or not depended on whether the HDMI output was on a separate sound card or on the same card as analog outputs).
  • Hui Wang sent a patch that adds “Front Headphone Front” and “Front Headphone Surround” jacks to our alsa configuration to support headphone and headset outputs on some Dell machines. The patch need some changes, but it’s not yet entirely clear what those changes should be.
  • Arun Raghavan updated his patch for fixing install paths in the meson build system. There was still one issue, which Arun has now fixed. I still need to check that fix.

OpenEmbedded

Not much to report. I worked a little bit on updating the alsa recipes, but mostly I just debugged a boot issue with the machine that I use for testing OpenEmbedded builds.

PipeWire

I spent some time experimenting with pipewire-cli, which is an interactive command line tool shipped with PipeWire. It had some surprising behaviour: it looked like it connected to the daemon even when there was no PipeWire daemon running. It turned out that pipewire-cli creates its own “daemon” instance (not really a daemon, since it’s part of pipewire-cli and doesn’t run in the background) and connects to that in the beginning. I suppose that can be useful for trying things out without needing to start PipeWire as a separate background process. Two pipewire-cli instances can connect to each other too, which might not be very useful, but it’s kind of cool.

I also contributed my first two patches to PipeWire! The first one was just a trivial removal of an unused variable. The second one was in a sense trivial too, but did something more useful: I incremented the “apiversion” from 0.2 to 0.3 in the work branch. The work branch contains changes that break compatibility with earlier releases of libpipewire, so installing the work branch broke all applications that had been compiled against an earlier version. In particular, gnome-shell didn’t start any more, so after installing PipeWire from the work branch, graphical login didn’t work any more… Incrementing the apiversion means that gnome-shell can keep using libpipewire-0.2 that is installed by the distribution, while I can install libpipewire-0.3 and use that to test my changes to PipeWire.

October 2018

Here’s my last month’s activity on PulseAudio, OpenEmbedded and PipeWire:

PulseAudio

There is a bug report about misaligned volume sliders in pavucontrol. I thought it would be easy to fix, so I fired up Glade (which is the UI design tool that we use with pavucontrol). I haven’t done that in many many years, and I found out that the current Glade version doesn’t really like our current UI definition file. It warned about the file targeting Gtk version 2.x, and when saving the file without doing any manual modifications, there were many automatically-made changes, some of which made compiling fail. I decided to get rid of those problems, because otherwise working on the UI would be annoying. Pavucontrol already supported Gtk 3.x, but now the Gtk 2.x support has been dropped altogether, so Glade won’t complain about that any more. I also applied the automatic changes done by Glade and adapted the pavucontrol code to deal with those changes. The original volume slider alignment bug remains unfixed, but I’ll probably get to that soon.

It was reported that the speaker-test program from ALSA in certain conditions didn’t play anything. I was able to reproduce that, and I spent some time investigating it. I found the likely root cause: when an application requests to be notified when all of its audio has finished playing, sometimes PulseAudio sends that notification immediately even if there’s still some audio left to play. It’s a bit complicated to fix, but I plan to do work on it in the not-too-distant future.

Arun is working on adding support for compressed audio passthrough streams without requiring any special wrapping to make it behave more like uncompressed audio, and I spent some time discussing the design with him. PulseAudio already supports compressed audio with S/PDIF and HDMI, but handling those is easier, because the data is wrapped in a way that makes the bitrate constant and suitable for the regular ALSA uncompressed audio API. There is a separate compressed audio API in ALSA that is used with hardware with compressed format decoding abilities. Arun also wants to add support for timestamped playback, which means that applications can specify timestamps when their audio buffers should be played. The use cases for that are a bit foggy to me, but apparently there is some hardware that can utilize such timestamps for synchronization. The timestamp stuff is not directly related to the compressed audio stuff (although they can be used together), but both will require changes in the PulseAudio client API, and it would be good to add support for both at the same time.

Reviewed patches:

  • Alexander E. Patrakov fixed 5.1 surround content playback on 5.1 sinks when the stream uses the “side” channel position and the sink uses the “rear” channel position in their respective channel maps. There is widespread confusion or disagreement about what channel positions 5.1 streams should use. Now PulseAudio is smart enough to send the stream’s “side” channels to the sink’s “rear” output. Earlier PulseAudio tried to synthesize the “rear” output from several other channels in a way that sounded really bad.
  • Sangchul Lee has been working on a patch to improve the “avoid-resampling” option behaviour so that PulseAudio automatically switches the hardware sample format according to the application stream format. After a couple of more iterations I now accepted the patch.
  • Zakhary Husak added support for a new 2018 variant of the Steelseries Arctis 7 USB headset, and jorisc90 added support for the Arctis Pro Wireless USB headset.
  • João Paulo Rechi Vita sent patches for “turning off” (i.e. switching to a profile without sinks or sources) ALSA cards that have nothing plugged in. This should help with switching streams automatically away from HDMI when an HDMI monitor is unplugged. I requested some improvements to the patches, so they haven’t been merged yet.
  • Arun Raghavan sent patches for improving the speed of automatic tests that our CI system runs. There remains some unclear stuff that needs to be sorted out before the patches can be merged.

OpenEmbedded

I started to work on updating the ALSA recipes to version 1.1.7.

PipeWire

As I mentioned in the PipeWire hackfest report, I’m nowadays trying to work 10 hours per week on PipeWire. This was the first month with that plan, and I didn’t get anywhere near the goal, but anyway, in addition to writing that report, I started looking through the recent commits in the work branch to get a feel of what’s going on in the project.

PipeWire Hackfest 2018 in Edinburgh

sponsored-by-foundation-roundI attended the PipeWire hackfest that was held at the end of October in Edinburgh. In this post I’ll share my thoughts about the PipeWire project and some notes from the hackfest. Before going into the details, it’s probably a good idea to provide a quick introduction to PipeWire for those of you who aren’t familiar with the project.

PipeWire was started by Wim Taymans as a video-only daemon to act as an intermediary between applications and video hardware, similar to how PulseAudio sits between applications and audio hardware (an earlier name for PipeWire was actually PulseVideo). So far video applications on Linux have accessed the hardware directly, meaning that two applications can’t access e.g. a webcam simultaneously. Solving that problem, and screen sharing with Wayland, were to my understanding the main motivations for creating a video daemon.

Dealing with video is in many ways similar to audio, and at some point Wim started to think about extending the project’s scope to cover also audio. Apparently there’s some benefit for handling audio and video together, but perhaps the biggest selling point of PipeWire as an audio daemon is the promise of merging the good properties of PulseAudio and JACK under one system. PipeWire now has the ambitious goal of replacing both PulseAudio and JACK.

Being invited to a meeting whose topic was obsoleting the project that has been the focus of my entire professional career was… interesting 😉 But we all have the same goal – making Linux audio better – so there was no hostility at all.

The hackfest

The hackfest was held in the Edinburgh CodeBase premises, where we had a nice meeting room with the Edinburgh Castle hill (plus a construction site) providing the background imagery. The participants included (sorry if I forgot or misrepresented anyone):

  • Christian Schaller from Red Hat as the main hackfest facilitator.
  • Wim Taymans, also from Red Hat, the creator of PipeWire.
  • Arun Raghavan and me representing the PulseAudio project, along with a former maintainer (and local Edinburgh resident) Colin Guthrie.
  • Mark Brown, the maintainer of embedded audio stuff in the kernel.
  • Bastien Nocera, a GNOME developer from Red Hat, who plans to implement a PipeWire policy manager for GNOME.
  • Jan Grulich, a KDE developer from Red Hat, who has been working on integrating the PipeWire video stuff to KDE.
  • Olivier Crête, Nicolas Dufresne and George Kiagiadakis from GStreamer/Collabora representing embedded use cases.
  • Thierry Bultel from AGL/IoT.bzh representing automotive use cases.

There were plans to have also a JACK representative present, but unfortunately we had to do without one.

The hackfest started with Wim presenting a demo of the current state of audio in PipeWire. PipeWire provides replacement implementations for both libpulse and libjack, which means that both PulseAudio and JACK applications can use the PipeWire daemon transparently. At least audio playback (and probably recording) is working. The hardware management side of PulseAudio remains largely unimplemented, so mixer applications run, but can’t do very much with the hardware. It was cool to see Carla, which is a JACK application, control the routing of PulseAudio applications. PulseAudio’s own JACK integration doesn’t allow managing the routing of individual applications in the JACK domain. It would be good to have a GUI for doing native routing in PipeWire (to handle video in addition to just audio), but Carla and other JACK applications (I suggest Patchage if Carla isn’t packaged for your distribution) seem like usable solutions for controlling audio routing in PipeWire for now.

The hackfest continued with various discussions about the PipeWire design (some covered below), and people hacking on their own stuff.

Starting from scratch vs. improving PulseAudio

When PulseAudio got adopted by Linux distributions as the default audio daemon, the migration was pretty painful for many users. For a user for whom audio was working just fine before their distribution decided to impose PulseAudio on them, and who had issues after the migration, PulseAudio appeared as a completely unnecessary thing whose only purpose seemed to be to break audio. To this day there are people who don’t understand the rationale behind the migration to PulseAudio when plain ALSA works “just fine” (for them). Now that PipeWire plans to replace PulseAudio as the default audio daemon, there’s a risk that the same pain will be inflicted on users once again. One might ask, why not improve PulseAudio instead of starting from scratch?

Bringing video into PulseAudio is not going to fly (and probably neither is MIDI, which I think PipeWire is also going to cover), but otherwise any improvements in PipeWire could in theory be implemented in PulseAudio as well. That said, PipeWire’s architecture has several benefits over PulseAudio, and making architectural changes is a painful process, so it may very well be that starting from scratch is a good idea. I don’t have a strong opinion on this – Wim has made his decision, and I don’t know if it’s a good or bad decision, but in any case, I don’t see much point in trying to convince him otherwise.

Drop-in replacement for PulseAudio?

I’ve seen some claims that PipeWire will be a “drop-in replacement” for PulseAudio. It probably could be that in theory, but I expect the reality to be different. In particular, I think it’s unlikely that the whole module interface (i.e. all the PulseAudio modules and their arguments) will be replicated. This means that custom PulseAudio configuration and and applications and scripts that load or unload PulseAudio modules will likely have to be replaced with something else. My expectation is that the best we will achieve is duplicating the functionality but not the interface of the PulseAudio modules, and hopefully there will be good documentation for migrating. If this prediction comes true, there will be many people whose experience is that “PipeWire broke my setup for no apparent benefit”.

At least the current plan seems to be that compatibility with PulseAudio and JACK will be provided by reimplementing the client libraries. This makes it difficult if not impossible to run PipeWire simultaneously with PulseAudio or JACK, because the library re-implementation only works with PipeWire and the original libpulse and libjack only work with PulseAudio/JACK, and both library variants can’t be installed at the same time. A more flexible (but probably much more work-intensive) compatibility solution would have been to implement the PulseAudio and JACK protocols in PipeWire, and keep using the original PulseAudio and JACK client libraries. When I mentioned this to Wim, I couldn’t come up with examples where this becomes a practical problem. Afterwards I’ve thought of a couple of examples: If one has a PulseAudio server running on a remote machine, it’s difficult to connect to it without the original libpulse being available, because libpulse is what implements the client side of the communication protocol. Another problem is the migration for Flatpak runtimes: libpulse is part of many runtimes, and if there’s no libpulse implementation that works with both PulseAudio and PipeWire, how can the Flatpak runtimes keep working on all distributions if some distributions use PulseAudio and some use PipeWire?

PipeWire benefits

The PipeWire architecture promises several benefits:

  • Better low-latency support, which allows bringing together PulseAudio and JACK applications.
  • Policy is handled outside the PipeWire daemon, so e.g. GNOME, KDE and various embedded vendors can easily provide their own policy, while with PulseAudio they have to largely depend on what policy alternatives the upstream PulseAudio project provides. This also makes PipeWire smaller, which reduces the workload of the PipeWire maintainers (but on the other hand, providing a stable API for policy managers probably causes some extra headache for the maintainers).
  • Access control for untrusted applications (Flatpak) is part of the design from the beginning.
  • Applications can implement virtual devices (and other kinds of nodes), which means that things like RAOP or Xrdp support don’t need to go through a lengthy review process before they can be integrated with the audio daemon, and PipeWire maintainers don’t need to maintain those virtual device implementations.
  • The node-based routing is more flexible, and should make it much simpler to add filters like equalizers to the audio graph. Management of such filters with hotplugged hardware coming and going is still not trivial, though. But in any case, applications can implement whatever filters they want, they don’t need to depend on what filters PipeWire provides out of the box.

Hardware abstraction

Currently there’s not much done on the hardware abstraction front. To my understanding PipeWire just creates a node for each ALSA PCM device, which is not good enough.

A major benefit of PulseAudio over e.g. JACK is that it provides a good (or at least better) view and control of the hardware’s capabilities. There’s an abstraction called a “card” for each sound card, and each card provides a set of “profiles”, and in case of ALSA, each profile defines a combination of ALSA PCM devices that can be used simultaneously. Additionally, for each PCM device there are “ports”, which determine the hardware routing of the ALSA PCM device. For example, a common case on a laptop is that there’s one output PCM device that can play to either to the speakers or the headphone output, and the port choice in PulseAudio controls this. Something similar will most likely be added to PipeWire, but the details are currently not fleshed out.

The device abstraction will also require an interface for getting the required information from ALSA. PulseAudio has it’s own autodetection system relying on standard PCM device names and standard ALSA mixer element names, but PulseAudio also supports a thing in ALSA called UCM (Use Case MAnager) that provides a different way of enumerating the hardware capabilities that doesn’t require as strict following of certain conventions by the kernel drivers. UCM is currently mostly used with embedded hardware, but a consensus arose in the hackfest that we should explore the applicability of UCM for PC hardware as well. Google’s Chrome OS uses UCM, so there’s some precedent, but Chrome OS still uses custom autodetection for USB sound cards, for which UCM isn’t currently a good fit. UCM requires separate configuration files for all sound cards. It might be possible to improve UCM so that the configuration files can be used more like templates that fit multiple sound cards. Arun Raghavan started studying and experimenting with UCM support in PipeWire. That work can benefit PulseAudio and Chrome OS as well.

User or system daemon?

One design aspect that interests me is the decision whether PipeWire is a user service or a system service, or configurable to be either. No clear consensus arose regarding that, except that a system mode should be at least an option. Based on my experience with PulseAudio, which is by default a user service, I would like to at least try to make PipeWire a system service by default, because that should make it easier to grant device access to multiple users at the same time and to do device handover in a more robust way when switching users. PulseAudio can be used in a system mode, but then there is no access control (beyond just blocking unauthorized users entirely), so any user can do anything, and settings (like application volumes) are not stored separately for each user. PipeWire will anyway have the infrastructure for limiting access, because it wants to support Flatpak applications with limited access, and pushing the policy handling outside PipeWire means that there can be per-user policy managers that handle per-user application volumes and such.

There were concerns that assigning seat information to devices and managing the user access within PipeWire makes things too complicated, compared to running as a user service and just acquiring and releasing devices based on the device permissions that are already set by logind (this is the model that PulseAudio uses). That model doesn’t work with bluetooth, however (there is an ongoing effort to mitigate this in PulseAudio, but the proposed solution is inherently racy).

My personal plans regarding PipeWire

I went to the hackfest with the plan that I won’t be contributing to the project until it manages to become the default audio daemon in several Linux distributions (at which point PulseAudio would have started to slide into irrelevancy). Christian Schaller’s suggestion to start a new Patreon campaign for PipeWire work in addition (rather than in place of) the existing campaign for my PulseAudio work made me reconsider my position, however. I don’t currently get a livable income from Patreon, and starting to work on PipeWire might help with that. I have publicly committed to only 10 hours of work on PulseAudio (and OpenEmbedded) per week, and at least in theory I would have enough time available to add another 10 hours for PipeWire. In practice, however, I’ve tried to increase the time I spend on PulseAudio, but so far I have failed due to lack of energy and self discipline. Why would I have more discipline to work on PipeWire instead? I don’t know, but I’ve decided to try anyway. Let’s see how it goes, and if it looks like I can keep up a good routine, I’ll create a new Patreon campaign or amend the existing one. In any case, PulseAudio remains a priority for me as much as it has been so far.

If I start working on PipeWire, I don’t know yet what aspect I’m going to focus on. Exploring the feasibility of running as a system daemon by default seems interesting. Or maybe I could start maintaining the documentation – that doesn’t seem as interesting, but I think that would be a very useful thing to do and something that might otherwise get neglected.

Final notes

In conclusion: PipeWire tries to become the future of Linux audio (on desktop at least), and that seems quite likely to happen if the project stays funded. I’m more pessimistic than some regarding the smoothness of the transition phase. Distributions are not likely to wait until full compatibility or even feature parity with PulseAudio has been achieved. The switch will be done when the perceived benefits exceed the perceived drawbacks, and since there are significant benefits promised, significant drawbacks will be tolerated by the decision makers.

Big thanks to the GNOME Foundation for sponsoring my flights and hotel, to Red Hat for sponsoring the venue, and to Collabora for sponsoring the dinner on Monday!

It was great to see old friends and to associate faces with some familiar names! Maybe we’ll see again in PipeWire Hackfest 2019? 🙂

This was a rather long post, but if you still aren’t entirely satisfied, try these other bloggings: