Skip to content

Latest commit

 

History

2 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 

Repository files navigation

Sound Rules

A Linux application for creating and managing persistent PipeWire audio routing rules for applications, inputs, outputs, and output groups.

Sound Rules aims to provide a simple graphical interface for controlling where application audio is routed without requiring users to understand PipeWire nodes, WirePlumber configuration, virtual sinks, or manual command-line routing.

Note

Sound Rules is currently in early development.

Features

Planned functionality includes:

  • Detect running applications and their audio streams
  • Route application audio to specific output devices
  • Route application input to specific microphones or input devices
  • Remember per-application routing choices
  • Automatically restore routing when applications start
  • Automatically handle devices connecting and disconnecting
  • Create persistent routing rules
  • Create output groups for routing audio to multiple devices simultaneously
  • Manage saved rules and output groups
  • Configure fallback devices when a preferred device is unavailable
  • Start and stop individual routing rules
  • Persistent configuration across sessions
  • PipeWire and WirePlumber integration
  • Background routing independent of the graphical interface
  • Command-line management
  • Multiple frontend support

Frontends

Sound Rules is designed around a frontend-independent core so that multiple graphical interfaces can share the same audio routing and rule implementation.

Planned frontends include:

GTK

A GTK 4 and Libadwaita frontend written in Vala, designed to integrate naturally with GNOME and follow the GNOME Human Interface Guidelines.

Qt

A Qt 6 frontend written in C++, intended to provide a native experience on KDE Plasma and other Qt-based desktop environments.

Both frontends communicate with the same Sound Rules service and use the same underlying device detection, application tracking, routing, rules, and configuration implementation.

Architecture

Sound Rules separates audio routing and application logic from the graphical interfaces.

Sound Rules
├── Core — Vala
│   ├── Application tracking
│   ├── Audio device management
│   ├── PipeWire integration
│   ├── Routing
│   ├── Rule engine
│   ├── Output groups
│   ├── Configuration
│   └── Events
│
├── Service — Vala
│   └── D-Bus API
│
├── Frontends
│   ├── GTK 4 / Libadwaita — Vala
│   └── Qt 6 — C++
│
└── CLI — Vala

The core must remain independent from GTK, Qt, and other user-interface frameworks.

Frontend-specific concepts such as widgets, dialogs, windows, view models, and toolkit signals should remain entirely inside their respective frontend implementations.

The graphical frontends communicate with the Sound Rules service through D-Bus rather than implementing audio functionality themselves.

GTK / Vala ─┐
            │
Qt / C++ ───┼── D-Bus ── soundrulesd ── Sound Rules Core ── PipeWire
            │
CLI / Vala ─┘

This allows routing rules to continue working even when no graphical frontend is running.

Core

The core is responsible for concepts such as:

Application
AudioStream
AudioDevice
Route
RouteRule
OutputGroup
RuleEngine
AudioBackend

Typical operations include:

list_applications()
list_outputs()
list_inputs()
list_rules()

set_application_output()
set_application_input()

create_rule()
update_rule()
remove_rule()

create_output_group()
update_output_group()
remove_output_group()

State changes are exposed through toolkit-independent events and the D-Bus service.

Examples include:

application_added
application_removed

device_added
device_removed
device_changed

rule_added
rule_removed
rule_changed

route_changed
output_group_changed

error

The GTK and Qt frontends react to these events using their own native toolkit mechanisms.

How It Works

Sound Rules is built around the modern Linux audio stack:

  • PipeWire — audio streams, devices, and routing
  • WirePlumber — PipeWire session and policy management
  • D-Bus — communication between the service, frontends, and CLI
  • Vala — core, service, CLI, and GTK frontend
  • GTK 4 / Libadwaita — GNOME frontend
  • C++ / Qt 6 — KDE and Qt frontend

When an application creates an audio stream, Sound Rules identifies it and checks for a matching rule.

Application starts
       ↓
Audio stream appears
       ↓
Sound Rules detects it
       ↓
Rule engine finds a match
       ↓
Preferred output/input selected
       ↓
PipeWire routing applied

For example:

Firefox
└── Built-in Speakers

Discord
├── Output → USB Headset
└── Input  → USB Microphone

Steam
└── USB Headset

The user does not need to manually reconnect streams or understand the underlying PipeWire graph.

Routing Rules

Routing rules describe where an application's audio should go.

For example:

Firefox → Speakers
Discord → Headset
Spotify → HDMI Receiver

Input rules can also define which recording device an application should use:

Discord → USB Microphone
OBS     → Audio Interface

Rules can be applied automatically whenever a matching application or audio stream appears.

A rule may eventually contain information such as:

Application
Preferred output
Preferred input
Fallback device
Output group
Priority
Enabled state

The exact matching and rule format may evolve as the project develops.

Output Groups

Sound Rules can support routing one application to multiple audio outputs simultaneously.

For example:

Desk
├── Desktop Speakers
└── USB Headset

An application can then be routed to the group:

Spotify → Desk

Internally, Sound Rules handles the required PipeWire routing or virtual audio devices.

The graphical interfaces expose this as a simple group of outputs rather than requiring users to manually create and connect PipeWire nodes.

Output groups can be persistent and automatically restored when their devices become available.

Device Changes

Audio hardware on desktop systems is not always permanently available.

Devices may appear or disappear when:

  • USB headsets are connected
  • Bluetooth devices connect
  • HDMI displays are enabled
  • Docking stations are attached
  • Audio interfaces are powered on

Sound Rules should handle these changes without requiring users to recreate their configuration.

For example:

Discord → USB Headset

If the headset disappears:

USB Headset unavailable
        ↓
Fallback → Built-in Speakers

When the headset returns:

USB Headset connected
        ↓
Discord → USB Headset

The goal is for routing configuration to describe user intent rather than depend on the exact current state of the PipeWire graph.

Background Service

Sound Rules uses a background user service so routing rules remain active independently of the graphical frontend.

          GTK
           │
           ├── D-Bus ──┐
           │           │
          Qt           ▼
           ├────── soundrulesd
           │           │
          CLI          ▼
                  Sound Rules Core
                        │
                        ▼
                    PipeWire

Closing the GTK or Qt application should not disable existing audio rules.

For example:

Sound Rules GUI closed

Discord starts
      ↓
soundrulesd detects Discord
      ↓
Saved rule matches
      ↓
Discord → USB Headset

The service may use systemd user services and D-Bus activation where appropriate.

Command-Line Interface

Sound Rules will also provide a small command-line interface for testing, scripting, and automation.

Example operations may include:

soundrulesctl applications
soundrulesctl outputs
soundrulesctl inputs
soundrulesctl rules
soundrulesctl groups

Routing commands may eventually resemble:

soundrulesctl route firefox speakers
soundrulesctl route discord headset

The CLI communicates with the same Sound Rules service as the graphical frontends.

It does not contain a separate routing implementation.

Design Goals

Sound Rules should remain:

  • Simple
  • Desktop-native
  • PipeWire-native
  • Toolkit-independent at its core
  • Persistent
  • Predictable
  • Easy to understand
  • Useful without requiring knowledge of PipeWire internals
  • Focused specifically on application audio routing

The GTK frontend should follow GNOME conventions and Human Interface Guidelines.

The Qt frontend should integrate naturally with KDE Plasma and Qt-based environments.

Both frontends should expose the same core functionality while remaining free to use interaction patterns appropriate for their respective desktop environments.

Non-Goals

Sound Rules is not intended to replace a complete audio mixer, patchbay, or professional audio workstation.

Complex functionality such as:

  • Audio effects
  • Equalizers
  • DSP processing
  • Recording
  • Audio editing
  • Professional studio routing
  • Large visual PipeWire graphs
  • Manual node-by-node patchbay management

is outside the primary scope of the project.

Sound Rules instead focuses on the common use case:

“I want this application's audio to always go here.”

And, when needed:

“I want this application's audio to go to these devices.”

The underlying PipeWire implementation may be complex, but the user-facing abstraction should remain simple.

Project Status

The project is currently under development.

APIs, architecture, behaviour, UI design, rule formats, and implementation details may change significantly before the first stable release.

Contributing

Contributions, bug reports, design feedback, and feature suggestions are welcome.

Before implementing major functionality, please open an issue so the proposed approach can be discussed first.

When contributing:

  • Keep core logic independent from frontend frameworks
  • Do not introduce GTK or Qt dependencies into the core
  • Keep PipeWire and routing logic out of the graphical frontends
  • Keep the GTK frontend written in Vala
  • Keep the Qt frontend written in C++
  • Communicate with the background service through the shared D-Bus API
  • Keep routing behaviour consistent between all frontends
  • Follow the conventions of the frontend being modified
  • Prefer simple user-facing abstractions over exposing PipeWire internals
  • Avoid expanding the application into a general-purpose audio workstation

About

A simple PipeWire audio routing manager with persistent per-application rules, output groups, and native GTK and Qt frontends.

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Contributors