RME Babyface Pro FS and PipeWire

Out of the box the headphones output of the Babyface Pro FS doesn’t do anything with PipeWire. You could connect it manually but it would be nice if this would happen automatically whenever a new PipeWire source appears and the RME is being used with the Pro audio profile.

With the help of the Combine Stream module I managed to set this up. The PipeWire configuration file to achieve simultaneous playback on both the default outputs and the headphones output can be found here: https://codeberg.org/autostatic/gists/raw/branch/main/babyface-pro-fs.conf Put it in ~/.config/pipewire/pipewire.conf.d/babyface-pro-fs.conf, restart PipeWire with systemctl --user restart peipewire and you should be good to go. I’ve asked in #pipewire on the OFTC IRC server if there were maybe easier ways to achieve this but the maintainer told me this is the best way.

For completeness’ sake I’ll also post the content of the PipeWire configuration file here.

# ~/.config/pipewire/pipewire.conf.d/babyface-pro-fs.conf

context.modules = [
    {   name = libpipewire-module-combine-stream
        args = {
            combine.mode = sink
            node.name = "Babyface_Pro_FS_All"
            node.description = "Babyface Pro FS All"
            combine.latency-compensate = false
            combine.props = {
                audio.position = [ FL FR ]
            }
            stream.props = {
                stream.dont-remix = true      # link matching channels without remixing
            }
            stream.rules = [
                {
                    matches = [
                        {
                            media.class = "Audio/Sink"
                            node.name = "alsa_output.usb-RME_Babyface_Pro__73088117__3A179EAA722D068-00.pro-output-0"
                        }
                    ]
                    actions = {
                        create-stream = {
                            combine.audio.position = [ FL FR ]
                            audio.position = [ AUX0 AUX1 AUX2 AUX3 ]
                            api.alsa.period-size = 1024
                            api.alsa.period-num = 3
                        }
                    }
                }
            ]
        }
    }
]

Edit: What I could also have done was reading the manual. In chapter 34 on page 91 the Copy Mode is explained. By enabling Copy Mode, which I just did, all output gets copied to channels 1/2, 3/4 (phones) and SPDIF/ADAT channels 1/2. This works way better and it can be set up on the device itself.

RME Babyface Pro FS and PipeWire

Linux audio performance improvements

This is a recap in blog form of the following Mastodon toot: https://mastodon.autostatic.net/@jeremy/115632831793380239

The biggest performance improvements when it comes to Linux audio you can do are in my experience:

  • Setting the CPU scaling governor to performance.
  • Disabling SMT (Simultaneous MultiThreading).
  • Allow your DAW to set CPU DMA latency. For instance Ardour and Reaper can do this.

The Ardour manual provides some great background information on these matters. CPU scaling governor and SMT are explained here: https://manual.ardour.org/setting-up-your-system/the-right-computer-system-for-digital-audio/. CPU DMA latency is explained here: https://manual.ardour.org/setting-up-your-system/the-right-computer-system-for-digital-audio/

All other recommendations that for instance rtcqs or Millisecond give are for those that really need stable, ultra low latency. So buffer sizes below 64 samples that result in round-trip latencies below 10 milliseconds. This is the area where threaded IRQs or disabling Spectre/Meltdown mitigations might contribute to getting rid of that stray xrun.

Regarding threaded IRQs, enabling those by itself doesn’t change anything. You will need to configure those threaded IRQs after you’ve enabled them. Tools that can do this are rtcirqus or rtirq. You could also do this manually by using the chrt command on the threaded IRQ process.

Modern systems use MSI(-X) interrupts though (Message Signaled Interrupts) so shared IRQs should be something of the past. On those systems there’s very little gain in prioritising threaded IRQs.

The main difference between rtcirqus and rtirq is that rtcirqus allows you to set the real-time priority of a thread based on ALSA card names. rtirq works differently, it sets the real-time priority based on kernel module names. So with rtcirqus you can be sure the desired audio interface gets the desired real-time prio, with rtirq you’re prioritising all the devices that make use of a specific kernel module (xhci_hcd, snd_hda_intel).

rtirq does allow for some finer grained control regarding USB2 ports and onboard audio devices that use the snd_hda_intel driver. The USB2 ehci_hcd driver and the snd_hda_intel driver add the bus name and card index number respectively to the IRQ thread process name so you can use that designation in the rtirq configuration file. In case of USB2 you’re still prioritising the IRQ of the whole USB bus though but then rtcirqus does the same.

Linux audio performance improvements

RME Digiface USB and PipeWire

My work laptop provided by SURF, a Dell Pro 14 Premium, runs a custom Dell Ubuntu 24.04 ISO since otherwise half of the peripherals don’t work. Ubuntu 24.04 comes with PipeWire so I was curious if the Digiface would work with such a setup. Well, it does, albeit with some quirks.

First of all PipeWire also doesn’t get the outputs right. With the help of WirePlumber I could map channels 33 and 34 of the phones output to Front Left and Front Right. But then the next issue popped up: weird garbled, phasing, ringing audio. When using ALSA directly with Ardour this happened too so it’s not a PipeWire issue. Tried tweaking things first and also tried a recent Liquorix kernel. To no avail. Then I started trying out different buffer sizes using pw-metadata and noticed the phasing, ringing sound would go away when changing the buffer size. And I also noticed that the garbled sound would come back if I used a buffer size higher than 64. So with the use of WirePlumber I also set that now. Another owner reported that setting a higher sample rate also alleviates the issue. I still like to figure out though why I can’t use higher buffer sizes. I think it’s related to the USB topology of this laptop as I don’t have this issue on my own laptops.

The WirePlumber configuration file to remap the phones outputs can be found here: https://codeberg.org/autostatic/gists/src/branch/main/99-rme-digiface-usb.lua. Ubuntu 24.04 uses WirePlumber < 0.5.0 so it’s still in Lua format. You can place this file in ~/.config/wireplumber/main.lua.d/. And it starts with 99- for a reason, the interwebs suggest a lower number but then it gets overwritten by global configuration files.

Below the WirePlumber configuration file that I use on the Dell Pro 14 Premium with an extra property to work around the garbled audio issue.

rule = {
  matches = {
    {
      { "node.name", "matches", "alsa_output.usb-RME_Digiface_USB__23800125__7C01A52EA9692C8-00.*" },
    },
  },
  apply_properties = {
    ["audio.position"] = "AUX0,AUX1,AUX2,AUX3,AUX4,AUX5,AUX6,AUX7,AUX8,AUX9,AUX10,AUX11,AUX12,AUX13,AUX14,AUX15,AUX16,AUX17,AUX18,AUX19,AUX20,AUX21,AUX22,AUX23,AUX24,AUX25,AUX26,AUX27,AUX28,AUX29,AUX30,AUX31,FL,FR",
    ["api.alsa.period-size"] = 64,
  },
}

table.insert(alsa_monitor.rules,rule)
RME Digiface USB and PipeWire