Linux control suite, PipeWire submixer, and OpenDeck plugin for Elgato XLR interfaces (Wave XLR Pro, XLR Dock, Wave XLR, MK.2)
C#
22
598 commits
updated Sep 21, 2026

Native Linux control suite for Elgato XLR interfaces: hardware control over reverse-engineered USB protocols, a Wave Link style PipeWire submixer with per-application channels, virtual microphones, LV2, CLAP and VST3 plugin inserts, multi-output monitoring, a dedicated mix for a second computer on the USB Aux port, and an OpenDeck plugin for Stream Deck control.


The window and the terminal mixer, both from 0.1.42, the terminal mixer
in the Tokyo Night skin. This README and the linked guides describe
current main; for a released build, read the docs at its release tag.
Changes merged after a release are available from source until the next release.
Elgato ships no Linux software. These devices expose class-compliant USB audio; OpenXLR also supplies device-specific configuration, including WirePlumber rules that keep XLR Dock and original Wave XLR capture alive. Controls beyond standard USB audio use device-specific protocols, decoded from Wave Link USB captures and prior open-source protocol work. OpenXLR uses those mappings alongside ALSA controls where available.
Not affiliated with or endorsed by Elgato. Built by protocol analysis on the author's own hardware.
| Device | USB id | Status |
|---|---|---|
| Wave XLR Pro | 0fd9:00b4 | mapped controls verified on hardware; hardware EQ and the full mix matrix remain unmapped |
| XLR Dock (Stream Deck+ module) | 0fd9:00a6 | gain, mute, headphone volume, 48V phantom power, low impedance; verified on hardware |
| Wave XLR | 0fd9:007d | gain, mute, headphone volume and low impedance verified by community testers; phantom power implemented, awaiting an OpenXLR hardware check |
| Wave XLR MK.2 | 0fd9:00b6 | gain, mute, phantom power, DSP, ClipGuard, compressor, headphone volume, crossfade; verified on hardware by a community tester |
| XLR Dock MK.2 (Stream Deck+ module) | 0fd9:00c7 | same exposed controls as the Wave XLR MK.2, verified on hardware |
The UI shows the controls OpenXLR exposes for the connected device, and a picker in the header switches between several attached interfaces. The per-control state of every device is in docs/hardware-support.md. If you own an untested device, open an issue with a diagnostics archive (Options, SUPPORT, Collect diagnostics).
openxlr-yabridge package supplies a tested bridge with the Wine editor
input fix and private wrappers./api/v1)
on 127.0.0.1:37890. The UI has a Flow window with selectable signal
paths through inputs, channels, mixes and outputs, a tray icon and a
diagnostics archive exporter. It also owns the desktop keys: global
shortcuts registered through the desktop portal that route the focused
application, step an output's volume, toggle its mute or switch the
system output, active while the window sits in the tray. Options
separates background audio and app startup at login, with independent
choices for launch visibility and whether closing the window keeps the
app in the tray or quits.openxlr-tui is the whole mixer in a terminal, for a
machine with no desktop session, an ssh connection or a tiling setup. It
speaks the same socket as the window, so both can be open at once, and it
wears the same skins. Tabs in the manner of btop: the submix grid with
live meters, the hardware inputs, the outputs, the applications, the
insert chains, the profiles and the appearance.
See the manual.openxlr.mixer shows XLR meters, mute and monitor feeds
in Omarchy 4, with channel sends and mix masters in a popout. The Arch
package integration and user enable command are in
docs/omarchy.md. The bar and the popout have been
checked on Omarchy 4.0.4; the live theme switch and the hardware
controls still need desktop acceptance.The full feature list, area by area: docs/features.md.
Dials get a touch panel with a knob, a level meter, the value and a mute overlay; one dial can hold several targets, cycled by tap or press.

Keys show an icon and a status LED (red for a mute, green for an engaged feature or the active monitor output). Every hardware switch, mute, level and insert is a target.

Packages exist for Arch Linux, CachyOS and Omarchy (AUR), Ubuntu (PPA),
Fedora (COPR) and NixOS (flake); every release also carries a .deb and
an .rpm for a manual install, with SHA-256 checksums and a GitHub build
provenance attestation (gh attestation verify <file> --owner emaspa).
Pick your distribution:
Arch Linux, CachyOS and Omarchy, from the AUR; the two derivatives install the same package:
yay -S openxlr # or: paru -S openxlr
systemctl --user enable --now openxlr-daemon
openxlr # the mixer UI, also in your application menu
A package built on Omarchy also carries the bar plugin. Run
openxlr-omarchy-enable once to link and enable it, as
docs/omarchy.md describes.
Ubuntu 24.04 and 26.04, from the PPA:
sudo add-apt-repository ppa:sparvoli/openxlr
sudo apt install openxlr
systemctl --user enable --now openxlr-daemon
openxlr
Without the PPA, download the .deb from the
latest release and
run sudo apt install ./openxlr_*_amd64.deb.
Fedora 44 or newer, from the COPR repository:
sudo dnf copr enable emaspa/openxlr
sudo dnf install openxlr
systemctl --user enable --now openxlr-daemon
openxlr
Without COPR, download the .rpm from the
latest release and
run sudo dnf install ./openxlr-*.x86_64.rpm.
NixOS: the repo is a flake with a package and a module. The module
enables the daemon itself; after a rebuild, openxlr is in the
application menu.
Add inputs.openxlr.url = "github:emaspa/openxlr"; to your system flake,
then include these entries in its nixosSystem.modules list:
openxlr.nixosModules.default
{ services.openxlr.enable = true; }
Here openxlr is the input passed to the flake's outputs function. The
module options configure LV2 plugins, software
ClipGuard and the optional Windows bridge.
On every distribution, replug the interface once after installing so
the udev rule applies. For the Stream Deck, install
com.emaspa.openxlr.sdPlugin.zip from the release with OpenDeck's
install-from-file, or copy the folder the package puts in
/usr/share/openxlr/ into ~/.config/opendeck/plugins/. Inserts show
compatible LV2, CLAP and VST3 plugins (lsp-plugins-lv2 is the set used
during development); the software ClipGuard for the XLR Dock needs
swh-plugins. The NixOS module wires both up itself. Focused-application
routing asks the window over D-Bus with gdbus from the GLib command-line
tools (glib2 on Arch and Fedora, libglib2.0-bin on Ubuntu), which the
packages depend on. The packages also
raise pipewire-pulse's open-file limit with a systemd drop-in, which
applies at the next login or after systemctl --user restart pipewire-pulse; a source install needs the same file before growing the
layout (manual: open-file limit).
A package upgrade replaces the files on disk and leaves the running programs on the code they started with, so a new version appears only after they restart. Rebooting does that, and so does this:
systemctl --user restart openxlr-daemon
Then close the mixer window and open it again, and quit openxlr-tui if
it is running. On Omarchy, reload the bar plugin with:
omarchy-shell shell rescanPlugins
Replug the interface only when the release says the udev rule changed.
Needs the .NET 10 SDK, PipeWire tools, libusb, lilv, the GLib command-line tools, a C/C++ compiler and the native host's development headers. Install the prerequisites in the source guide first. From the repository root:
git clone https://github.com/emaspa/openxlr.git
cd openxlr
dotnet restore src/OpenXLR.slnx --locked-mode
dotnet build src/OpenXLR.slnx -c Release --no-restore -warnaserror -p:EnableNativeLv2Host=true
OPENXLR_BUILD_MIXER=1 ./src/OpenXLR.Daemon/bin/Release/net10.0/OpenXLR.Daemon
In a second terminal, from the same repository root:
./src/OpenXLR.UI/bin/Release/net10.0/OpenXLR.UI
Device access needs the tracked udev rule and a replug. The source guide also covers WirePlumber rules, the open-file limit, the user service, updating and uninstalling. Keep the native build flag on subsequent builds to retain CLAP, VST3 and plugin editors.
For Windows plugins, install openxlr-yabridge from the same place you
installed OpenXLR: the AUR, the PPA, the COPR repository, or the packages
on the release page. It carries a tested bridge with the Wine editor input
fix, without which a plugin editor ignores the mouse on Wine 9.22 and
newer. The manual walks through it and
the package guide covers building it
yourself.
Documentation index: user guides, developer references and historical protocol research.
~/.config/openxlr; HTTP API for the same
commands over plain HTTPSupport, hardware reports, feature requests and release news also live on the OpenXLR Discord server, discord.gg/4bswtnGPW4, and on Reddit at r/OpenXLR. The window links to both from About in the main header. Confirmed bugs still end up as GitHub issues, so any of the three works to start. To help with code or hardware reports, read CONTRIBUTING.md first.
Open Options, then SUPPORT, then Collect diagnostics. It writes
~/openxlr-diagnostics-<timestamp>.tar.gz with the app and device
state, a raw vendor-block dump, the PipeWire graph, daemon logs and
configs. Nothing gets uploaded; attach the archive to an issue, or to a
post in the Discord support forum, yourself.
For a plugin that will not appear, the same section lists the bundles the last scan skipped and the folders it could not read. A Windows plugin that fails only under the bridge has a deep Wine trace checkbox there: turn it on, Rescan, collect the archive, then turn it off. Scans are much slower while it is on, and it clears itself on a daemon restart.
Developed and used daily by the author with a Wave XLR Pro, an XLR Dock, an XLR Dock MK.2 and a Stream Deck + XL. The Wave XLR and Wave XLR MK.2 backends were verified on hardware by community testers. See the device table and docs/hardware-support.md for what is still open.
The majority of the code was produced by the author, with AI tooling (Anthropic's Claude) assisting with protocol capture analysis, UI design and parts of the coding. Every hardware finding was verified live on a real device.
GPL-3.0. If you find OpenXLR useful, consider buying me a coffee.
C#
66.4%
C++
16.5%
C
10.7%
JavaScript
2.9%
QML
1.5%
Python
1.2%
Linux control suite, PipeWire submixer, and OpenDeck plugin for Elgato XLR interfaces (Wave XLR Pro, XLR Dock, Wave XLR, MK.2)
C#
22
598 commits
updated Sep 21, 2026

Native Linux control suite for Elgato XLR interfaces: hardware control over reverse-engineered USB protocols, a Wave Link style PipeWire submixer with per-application channels, virtual microphones, LV2, CLAP and VST3 plugin inserts, multi-output monitoring, a dedicated mix for a second computer on the USB Aux port, and an OpenDeck plugin for Stream Deck control.


The window and the terminal mixer, both from 0.1.42, the terminal mixer
in the Tokyo Night skin. This README and the linked guides describe
current main; for a released build, read the docs at its release tag.
Changes merged after a release are available from source until the next release.
Elgato ships no Linux software. These devices expose class-compliant USB audio; OpenXLR also supplies device-specific configuration, including WirePlumber rules that keep XLR Dock and original Wave XLR capture alive. Controls beyond standard USB audio use device-specific protocols, decoded from Wave Link USB captures and prior open-source protocol work. OpenXLR uses those mappings alongside ALSA controls where available.
Not affiliated with or endorsed by Elgato. Built by protocol analysis on the author's own hardware.
| Device | USB id | Status |
|---|---|---|
| Wave XLR Pro | 0fd9:00b4 | mapped controls verified on hardware; hardware EQ and the full mix matrix remain unmapped |
| XLR Dock (Stream Deck+ module) | 0fd9:00a6 | gain, mute, headphone volume, 48V phantom power, low impedance; verified on hardware |
| Wave XLR | 0fd9:007d | gain, mute, headphone volume and low impedance verified by community testers; phantom power implemented, awaiting an OpenXLR hardware check |
| Wave XLR MK.2 | 0fd9:00b6 | gain, mute, phantom power, DSP, ClipGuard, compressor, headphone volume, crossfade; verified on hardware by a community tester |
| XLR Dock MK.2 (Stream Deck+ module) | 0fd9:00c7 | same exposed controls as the Wave XLR MK.2, verified on hardware |
The UI shows the controls OpenXLR exposes for the connected device, and a picker in the header switches between several attached interfaces. The per-control state of every device is in docs/hardware-support.md. If you own an untested device, open an issue with a diagnostics archive (Options, SUPPORT, Collect diagnostics).
openxlr-yabridge package supplies a tested bridge with the Wine editor
input fix and private wrappers./api/v1)
on 127.0.0.1:37890. The UI has a Flow window with selectable signal
paths through inputs, channels, mixes and outputs, a tray icon and a
diagnostics archive exporter. It also owns the desktop keys: global
shortcuts registered through the desktop portal that route the focused
application, step an output's volume, toggle its mute or switch the
system output, active while the window sits in the tray. Options
separates background audio and app startup at login, with independent
choices for launch visibility and whether closing the window keeps the
app in the tray or quits.openxlr-tui is the whole mixer in a terminal, for a
machine with no desktop session, an ssh connection or a tiling setup. It
speaks the same socket as the window, so both can be open at once, and it
wears the same skins. Tabs in the manner of btop: the submix grid with
live meters, the hardware inputs, the outputs, the applications, the
insert chains, the profiles and the appearance.
See the manual.openxlr.mixer shows XLR meters, mute and monitor feeds
in Omarchy 4, with channel sends and mix masters in a popout. The Arch
package integration and user enable command are in
docs/omarchy.md. The bar and the popout have been
checked on Omarchy 4.0.4; the live theme switch and the hardware
controls still need desktop acceptance.The full feature list, area by area: docs/features.md.
Dials get a touch panel with a knob, a level meter, the value and a mute overlay; one dial can hold several targets, cycled by tap or press.

Keys show an icon and a status LED (red for a mute, green for an engaged feature or the active monitor output). Every hardware switch, mute, level and insert is a target.

Packages exist for Arch Linux, CachyOS and Omarchy (AUR), Ubuntu (PPA),
Fedora (COPR) and NixOS (flake); every release also carries a .deb and
an .rpm for a manual install, with SHA-256 checksums and a GitHub build
provenance attestation (gh attestation verify <file> --owner emaspa).
Pick your distribution:
Arch Linux, CachyOS and Omarchy, from the AUR; the two derivatives install the same package:
yay -S openxlr # or: paru -S openxlr
systemctl --user enable --now openxlr-daemon
openxlr # the mixer UI, also in your application menu
A package built on Omarchy also carries the bar plugin. Run
openxlr-omarchy-enable once to link and enable it, as
docs/omarchy.md describes.
Ubuntu 24.04 and 26.04, from the PPA:
sudo add-apt-repository ppa:sparvoli/openxlr
sudo apt install openxlr
systemctl --user enable --now openxlr-daemon
openxlr
Without the PPA, download the .deb from the
latest release and
run sudo apt install ./openxlr_*_amd64.deb.
Fedora 44 or newer, from the COPR repository:
sudo dnf copr enable emaspa/openxlr
sudo dnf install openxlr
systemctl --user enable --now openxlr-daemon
openxlr
Without COPR, download the .rpm from the
latest release and
run sudo dnf install ./openxlr-*.x86_64.rpm.
NixOS: the repo is a flake with a package and a module. The module
enables the daemon itself; after a rebuild, openxlr is in the
application menu.
Add inputs.openxlr.url = "github:emaspa/openxlr"; to your system flake,
then include these entries in its nixosSystem.modules list:
openxlr.nixosModules.default
{ services.openxlr.enable = true; }
Here openxlr is the input passed to the flake's outputs function. The
module options configure LV2 plugins, software
ClipGuard and the optional Windows bridge.
On every distribution, replug the interface once after installing so
the udev rule applies. For the Stream Deck, install
com.emaspa.openxlr.sdPlugin.zip from the release with OpenDeck's
install-from-file, or copy the folder the package puts in
/usr/share/openxlr/ into ~/.config/opendeck/plugins/. Inserts show
compatible LV2, CLAP and VST3 plugins (lsp-plugins-lv2 is the set used
during development); the software ClipGuard for the XLR Dock needs
swh-plugins. The NixOS module wires both up itself. Focused-application
routing asks the window over D-Bus with gdbus from the GLib command-line
tools (glib2 on Arch and Fedora, libglib2.0-bin on Ubuntu), which the
packages depend on. The packages also
raise pipewire-pulse's open-file limit with a systemd drop-in, which
applies at the next login or after systemctl --user restart pipewire-pulse; a source install needs the same file before growing the
layout (manual: open-file limit).
A package upgrade replaces the files on disk and leaves the running programs on the code they started with, so a new version appears only after they restart. Rebooting does that, and so does this:
systemctl --user restart openxlr-daemon
Then close the mixer window and open it again, and quit openxlr-tui if
it is running. On Omarchy, reload the bar plugin with:
omarchy-shell shell rescanPlugins
Replug the interface only when the release says the udev rule changed.
Needs the .NET 10 SDK, PipeWire tools, libusb, lilv, the GLib command-line tools, a C/C++ compiler and the native host's development headers. Install the prerequisites in the source guide first. From the repository root:
git clone https://github.com/emaspa/openxlr.git
cd openxlr
dotnet restore src/OpenXLR.slnx --locked-mode
dotnet build src/OpenXLR.slnx -c Release --no-restore -warnaserror -p:EnableNativeLv2Host=true
OPENXLR_BUILD_MIXER=1 ./src/OpenXLR.Daemon/bin/Release/net10.0/OpenXLR.Daemon
In a second terminal, from the same repository root:
./src/OpenXLR.UI/bin/Release/net10.0/OpenXLR.UI
Device access needs the tracked udev rule and a replug. The source guide also covers WirePlumber rules, the open-file limit, the user service, updating and uninstalling. Keep the native build flag on subsequent builds to retain CLAP, VST3 and plugin editors.
For Windows plugins, install openxlr-yabridge from the same place you
installed OpenXLR: the AUR, the PPA, the COPR repository, or the packages
on the release page. It carries a tested bridge with the Wine editor input
fix, without which a plugin editor ignores the mouse on Wine 9.22 and
newer. The manual walks through it and
the package guide covers building it
yourself.
Documentation index: user guides, developer references and historical protocol research.
~/.config/openxlr; HTTP API for the same
commands over plain HTTPSupport, hardware reports, feature requests and release news also live on the OpenXLR Discord server, discord.gg/4bswtnGPW4, and on Reddit at r/OpenXLR. The window links to both from About in the main header. Confirmed bugs still end up as GitHub issues, so any of the three works to start. To help with code or hardware reports, read CONTRIBUTING.md first.
Open Options, then SUPPORT, then Collect diagnostics. It writes
~/openxlr-diagnostics-<timestamp>.tar.gz with the app and device
state, a raw vendor-block dump, the PipeWire graph, daemon logs and
configs. Nothing gets uploaded; attach the archive to an issue, or to a
post in the Discord support forum, yourself.
For a plugin that will not appear, the same section lists the bundles the last scan skipped and the folders it could not read. A Windows plugin that fails only under the bridge has a deep Wine trace checkbox there: turn it on, Rescan, collect the archive, then turn it off. Scans are much slower while it is on, and it clears itself on a daemon restart.
Developed and used daily by the author with a Wave XLR Pro, an XLR Dock, an XLR Dock MK.2 and a Stream Deck + XL. The Wave XLR and Wave XLR MK.2 backends were verified on hardware by community testers. See the device table and docs/hardware-support.md for what is still open.
The majority of the code was produced by the author, with AI tooling (Anthropic's Claude) assisting with protocol capture analysis, UI design and parts of the coding. Every hardware finding was verified live on a real device.
GPL-3.0. If you find OpenXLR useful, consider buying me a coffee.
C#
66.4%
C++
16.5%
C
10.7%
JavaScript
2.9%
QML
1.5%
Python
1.2%