SoundRoot SoundRoot
Install

Documentation · v0.8.0-beta

SoundRoot — what & how.

A short, honest reference: what SoundRoot is, how it works under the hood, and what to type when something goes sideways.

01 · The idea

What is SoundRoot

Diagram showing SoundRoot as a panel widget that connects applications to output devices through named rooms

SoundRoot is a KDE Plasma 6 panel widget (a plasmoid) for Linux desktops running PipeWire. It sits in the system tray and gives you one place to decide which application plays through which output device.

Instead of opening pavucontrol every time you switch headphones for speakers, you build named audio rooms — presets like Gaming, Work or Stream — and switch the entire routing setup with one click or a global keyboard shortcut.

It is open source under GPL-2.0-or-later, currently shipped as v0.8.0-beta, and runs entirely on your machine — no accounts, no telemetry, no cloud.

Form

Panel widget

Lives in the KDE system tray, popup UI on click.

Stack

QML + C++

Qt 6, KDE Frameworks 6, libpulse async API.

Audience

Power users

Gamers, streamers, podcasters, multi-device setups.

02 · The flow

How it works

Four-step diagram: open from tray, create a room, wire apps to outputs, switch instantly

SoundRoot does not invent a parallel audio system. It talks to PipeWire through the libpulse asynchronous API, listens for sink and stream changes, and builds a live picture of the apps and devices on your machine.

When you wire an application to an output, SoundRoot moves that stream to the corresponding sink. When you switch rooms, the widget walks through the room's saved routes and re-applies them in one batch. Configuration is persisted to a JSON file so your setup survives reboots.

03 · Vocabulary

Core concepts

Audio Room
A named preset that owns a colour, an icon, and a list of routes. Switching a room replays its routing on top of whatever apps are running.
Route
A connection from a source application (a sink-input) to one output sink, with its own volume value (0–150 %).
Sink & Sink-Input
PipeWire/PulseAudio terms. A sink is an output device, a sink-input is an audio stream produced by an application.
Many-to-many routing
One app can be wired to several outputs at once, and one output can receive multiple apps. The visual board uses colour-coded wires so you can read the topology at a glance.

04 · Step by step

User workflow

  1. Open the widget from the system tray icon.
  2. Press + New Room, give it a name, colour and icon.
  3. Drag a wire from any running application to any output device.
  4. Adjust per-route volume independently of the system master.
  5. Activate the room with the toggle — the routing applies in one batch.
  6. Switch rooms later by clicking another room or using a global shortcut.

05 · Hands on the keys

Keyboard shortcuts

Shortcuts are registered through KDE GlobalAccel and can be changed under System Settings → Shortcuts, or directly in SoundRoot's settings dialog.

Action Default
Activate widget (as if clicked) Ctrl + Shift + K
Next room Ctrl + Alt +
Previous room Ctrl + Alt +

06 · Where things live

Configuration file

All rooms, routes and per-route volumes are stored in a single JSON file in your home directory. You can back it up, version it or copy it between machines.

# Path
~/.config/audiorouter/groups.json

# Rough shape
{
  "groups": [
    {
      "name": "Gaming",
      "color": "#4a90e2",
      "icon": "audio-headphones",
      "routes": [
        { "app": "firefox",  "sink": "alsa_output.headphones", "volume": 0.85 },
        { "app": "discord",  "sink": "alsa_output.speakers",   "volume": 0.60 }
      ]
    }
  ]
}

The exact field set may evolve between beta releases. Treat the file as authoritative for your local install, not as a stable public API yet.

07 · What you need

Requirements

  • Linux with KDE Plasma 6
  • PipeWire with the PulseAudio compatibility layer (pipewire-pulse)
  • Qt 6, KDE Frameworks 6, libpulse
  • CMake 3.20+ and Extra CMake Modules (only for building from source)

08 · Under the hood

Architecture in four layers

UI

QML interface

Plasmoid contents, popup, routing board, room list, settings dialog. Pure declarative UI bound to backend models.

M

Models — QAbstractListModel

GroupListModel, RouteListModel, SinkInputModel, SinkModel — reactive lists consumed by QML.

B

C++ backend — AudioBackend

State, persistence to groups.json, route application, integration with KDE GlobalAccel for shortcuts.

A

Audio API — libpulse async

Talks to PipeWire through the PulseAudio compatibility layer. Asynchronous so the UI never blocks while sinks and streams change.

09 · When it misbehaves

Troubleshooting

The widget appears but the device list is empty

Check that pipewire-pulse is running. SoundRoot relies on the PulseAudio compatibility layer, so a pure ALSA-only setup will not be detected. Try systemctl --user status pipewire-pulse.service.

Switching a room does nothing

Make sure the application is actually playing audio — SoundRoot routes active sink-inputs. Apps that only open the audio device on demand (some games, browsers without an active tab) will not appear until they emit sound.

My shortcuts do not fire

Open the SoundRoot settings dialog and re-record the shortcut, or check for conflicts under System Settings → Shortcuts → Custom Shortcuts. KDE GlobalAccel will refuse silently if another app already owns the key combination.

I want to start over

Quit Plasma's widget instance, delete ~/.config/audiorouter/groups.json, then re-add the plasmoid. You will land on a clean state.

10 · Boundaries

Privacy & permissions

  • • SoundRoot runs locally; no network calls, no analytics, no accounts.
  • • It only reads the audio session graph and writes to ~/.config/audiorouter/groups.json.
  • • It does not capture, record or upload any audio.

See the full privacy policy.

11 · Get involved

Source & contributing

SoundRoot is open source under GPL-2.0-or-later. Issues, ideas and pull requests are welcome — especially for the items still on the Nice to Have list (auto-switch on device hotplug, virtual-device creation from the UI, smoother onboarding).