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.
Mixer screenshot from 0.1.25. 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 a WirePlumber workaround for XLR Dock capture. 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. Own an untested device? Open an issue with a diagnostics archive (Options, SUPPORT, Collect diagnostics).
- Hardware control through device-specific USB protocols and standard ALSA controls. On the Pro: gain, mute, low cut, expander, voice tune and phantom power per input, ClipGuard, compressor, aux input level and lock, two headphone volumes with low-impedance mode, the mic/PC crossfade, and the physical output routing (HP1, HP2, Line Out, USB Aux). The other devices expose the subset their protocol has; see the table above. Where a hardware low cut or ClipGuard control is unavailable, OpenXLR offers software processing in PipeWire. Gain lock is a daemon policy for devices without physical gain controls. Hardware EQ, ducking, mix maximizer and channel booster are not exposed; plugin effects run on the computer, separate from the device's onboard processing.
- Submixer built from PipeWire nodes (null sinks, remap sources, filter chains), no kernel modules. Channels for the hardware inputs and for application groups; mixes for what you hear (Monitor A and Monitor B, each output choosing one of the two or both summed), for virtual microphones other apps record from, and for the USB Aux port. The default layout is Game, Music, Browser, System, Voice Chat and SFX with Stream and Chat microphones; channels and microphones can be added, renamed, reordered and removed while audio plays, from the window or the API. Per-send levels and mutes, level meters, the monitor mixes on several outputs at once.
- Inserts: LV2, CLAP and VST3 plugin chains on each XLR input and each mix, with a
plugin picker, generated controls, bypass and native plugin editors.
Input chains use mono effects; mix chains use stereo effects. VST3 discovery
checks supported layouts, so effects that default to stereo but accept mono
are also available on XLR inputs. Editable native editor compatibility rules
select OpenXLR controls for troublesome editors without changing audio processing.
Windows VST3 and CLAP plugins use Wine and yabridge; the
openxlr-yabridgepackage supplies a tested bridge with the Wine editor input fix and private wrappers. - Plugin installation and management from Options: import extracted files or bundles, rescan, and manage Windows plugin folders and individual plugins. Single Windows-plugin imports do not register neighbouring plugins. Disable or re-enable plugins, remove their uses from current chains, delete standalone plugins, or open Wine's uninstaller for installed packages. Removing a folder from the list keeps its source files and refreshes discovery. See the Windows plugin guide.
- Application routing: audio clients are detected from their PipeWire registration and routed to a channel by name rules, with the assignment remembered per app; an app can also be left to the desktop's own routing. Electron apps are identified by their process binary rather than the "Chromium" name they report. Missing stream metadata falls back to the owning client, and Windows executable names share an identity with their Wine/Proton client so saved routing persists.
- Profiles: named scenes holding the hardware settings and the whole submix (levels, mutes, outputs, insert chains), saved per device and recalled from the UI, the API or a Stream Deck key. One profile per device can be recalled on connect, so an interface comes up in a known scene at login or after a power cycle. OpenXLR also restores the last settings on the original Wave XLR and first XLR Dock without a profile, with a reset to the defaults recorded after a power cycle.
- OpenDeck plugin: key and dial actions for every switch, mute, level and insert, rendered with level meters and status LEDs. It is a client of the daemon's API, so it reflects changes made in the UI or on the hardware.
- Daemon and UI: the daemon owns the device and the graph, keeps
running with the window closed, re-asserts the chosen default sink
and source once a second, and serves a WebSocket API and a versioned
HTTP API (
/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. 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. - Optional update notice: the UI can check the upstream GitHub release feed for a newer stable release. Startup checks are off by default and, when enabled, run at most once per day. Nothing is installed automatically.
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 (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, from the AUR:
yay -S openxlr # or: paru -S openxlr
systemctl --user enable --now openxlr-daemon
openxlr # the mixer UI, also in your application menuUbuntu 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
openxlrWithout 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
openxlrWithout 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. 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).
Needs the .NET 10 SDK, PipeWire tools, libusb, lilv, 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.DaemonIn a second terminal, from the same repository root:
./src/OpenXLR.UI/bin/Release/net10.0/OpenXLR.UIDevice 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.
- Manual: first run, the concepts behind the mixer, step-by-step tasks, the Stream Deck plugin, troubleshooting
- Features: every control, the submixer, inserts, routing, profiles and the OpenDeck plugin in detail
- Roadmap: what comes next, in order, and the rules a change has to meet to land
- Installing from source: prerequisites by distribution, device access, the user service, updating, uninstall, environment variables
- WebSocket API: the daemon's command set and the files
under
~/.config/openxlr; HTTP API for the same commands over plain HTTP - Saved mixer layout: the layout file and the live layout commands
- Architecture: daemon, UI and plugin, the PipeWire graph, the device protocols, repository layout
- Hardware support: per-control status of every device
- Wave XLR Pro protocol: the vendor protocol as reverse engineered, with offsets
- USB capture guide: how to capture Wave Link traffic for an untested device
- CONTRIBUTING.md: how to build, test and send a change; AGENTS.md for AI-assisted contributions, which are allowed as long as the author owns and can explain the code
Support, 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. Want 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.
- Emanuele Sparvoli: author, maintainer and code.
- Carina Schoppe: maintainer and code.
- Michael Brooks: code and hardware testing.
- BenjyEX3: hardware testing.
- chromacurse: hardware testing.
- Astros52: hardware testing.
- rikkichy: prior protocol research.
- nekename: upstream software.
- FrostyCoolSlug: technical guidance.
- All the various community testers (thank you!): hardware and packaging testing.
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.



