Skip to content

dalenicholson/PipewirePersistentSinks

Repository files navigation

PipeWire Persistent Audio Setup

Declarative audio configuration for a production music studio on Arch Linux (Garuda/KDE Wayland). Survives kernel upgrades, PipeWire updates, and device reconnections.

Hardware

Device Type Audio MIDI Connection
Dell XPS 17 9710 (SOF SoundWire) Internal audio Built-in (HiFi profile) Built-in
TASCAM Model 12 USB mixer (12-in) USB pro-audio Dock → USB
Roland MC-707 Groovebox USB pro-audio USB MIDI Dock → USB hub
Roland A-01 Controller/synth USB pro-audio USB MIDI Dock → USB hub
Roland SP-404MKII Sampler USB pro-audio USB MIDI Dock → USB hub
Roland D-05 Synth USB pro-audio USB MIDI Dock → USB hub
Roland JU-06A Synth USB pro-audio USB MIDI Dock → USB hub
Roland JX-03 Synth USB pro-audio USB MIDI Dock → USB hub
Teenage Engineering EP 1320 Synth USB pro-audio USB MIDI Dock → USB hub
Arturia MiniBrute 2s Synth Model 12 ch USB MIDI Dock → USB hub + analog → Model 12
Arturia DrumBrute Impact Drum machine Model 12 ch USB MIDI Dock → USB hub + analog → Model 12
Arturia Keystep 37 Controller USB MIDI + MidiSport Dock → USB hub + DIN
Modular synth rig Modular Model 12 ch MidiSport 4x4 Analog → Model 12
M-Audio MidiSport 4x4 MIDI interface 4-in / 4-out DIN Dock → USB
Kensington TB4 Thunderbolt dock TB4

Audio routing for USB devices: Each Roland / TE device has USB audio used for separate per-device recording tracks in Ardour. Their physical audio outputs also go to an analog mixer → a stereo pair on the Model 12 for monitoring (not recorded). The Model 12 carries 12 USB channels — devices without USB audio (MiniBrute, DrumBrute, modular) are recorded via those Model 12 channels.

PC → Model 12: Audio from the PC routes to the Model 12, which plays it over the main speaker system when docked.

Software Stack

  • PipeWire 1.4.10 — audio/MIDI server
  • WirePlumber 0.5.13 — session manager (SPA JSON .conf format, NOT Lua)
  • Ardour — primary DAW
  • VCV Rack 2 Pro — virtual modular synth
  • Standalone synths: Cardinal, Dexed, Helm, Vital, ZynAddSubFX, Hydrogen, etc.
  • Other DAWs: Qtractor, Rosegarden, MuseScore, Mixxx
  • Kernel: 6.18.x-zen (Garuda)

Architecture

┌─────────────────────────────────────────────────────────────┐
│  UNDOCKED / TASCAM OFF: normal laptop audio                 │
│                                                             │
│  Speakers/Headphones ← PipeWire ← Apps (browser, calls)    │
│  Headset Mic → PipeWire → Apps                              │
│                                                             │
│  VCV Rack / Cardinal / standalone synths                    │
│    → default output (laptop speakers/headphones)            │
└─────────────────────────────────────────────────────────────┘

┌──────────────────────────────────────────────────────────────────────┐
│  DOCKED / TASCAM ON: production mode                                │
│                                                                     │
│  ┌── AUDIO RECORDING ──────────────────────────────────────────┐    │
│  │  Roland MC-707  ─┐                                          │    │
│  │  Roland A-01    ─┤  USB audio (per-device) → Ardour tracks  │    │
│  │  Roland SP-404  ─┤                                          │    │
│  │  Roland D-05    ─┤  Each device = separate recording track  │    │
│  │  Roland JU-06A  ─┤                                          │    │
│  │  Roland JX-03   ─┤                                          │    │
│  │  TE EP 1320     ─┘                                          │    │
│  │                                                             │    │
│  │  TASCAM Model 12 (12 USB channels) → Ardour tracks          │    │
│  │    Channels carry: MiniBrute 2s, DrumBrute Impact,          │    │
│  │                    modular rig, and other analog sources     │    │
│  └─────────────────────────────────────────────────────────────┘    │
│                                                                     │
│  ┌── MONITORING ───────────────────────────────────────────────┐    │
│  │  Ardour master → "Ardour Monitor" combine-sink              │    │
│  │    ├→ TASCAM Model 12 (AUX0/AUX1) → main speakers          │    │
│  │    └→ Laptop Headphones (FL/FR)                             │    │
│  │                                                             │    │
│  │  PC audio → Model 12 → mains (for playback over speakers)  │    │
│  └─────────────────────────────────────────────────────────────┘    │
│                                                                     │
│  ┌── SOFTWARE SYNTHS ──────────────────────────────────────────┐    │
│  │  VCV Rack / Cardinal / standalone synths                    │    │
│  │    → "VCV Rack Output" combine-sink                         │    │
│  │      └→ Laptop Headphones (FL/FR)                           │    │
│  │    Ardour capture ← monitor ports (vcvrack_output:monitor)  │    │
│  └─────────────────────────────────────────────────────────────┘    │
│                                                                     │
│  ┌── MIDI ─────────────────────────────────────────────────────┐    │
│  │  USB MIDI (all devices except modular) → Ardour MIDI in    │    │
│  │  Keystep → MidiSport 4x4 → modular rig (DIN MIDI)          │    │
│  │  Ardour MIDI out → MidiSport 4x4 → modular rig / synths    │    │
│  │  MidiSport 4x4 in ← modular rig / hardware → Ardour        │    │
│  └─────────────────────────────────────────────────────────────┘    │
│                                                                     │
│  ┌── PHYSICAL SIGNAL FLOW (analog, not PipeWire) ──────────────┐   │
│  │  Rolands / TE → analog mixer → Model 12 stereo pair         │   │
│  │    (monitoring only — recording uses USB audio per device)   │   │
│  │  MiniBrute / DrumBrute / modular → Model 12 direct channels │   │
│  │    (recording path for audio — MIDI is still over USB)       │   │
│  └─────────────────────────────────────────────────────────────┘   │
└──────────────────────────────────────────────────────────────────────┘

File Layout

~/.config/
├── wireplumber/wireplumber.conf.d/
│   ├── 50-device-profiles.conf    # Device → profile mapping
│   └── 51-alsa-node-rules.conf    # Node naming & priority
└── pipewire/pipewire.conf.d/
    └── 20-combine-sinks.conf      # Virtual combine sinks

~/.local/bin/
├── audio-health                   # Diagnostics & health check
├── audio-profile                  # Profile switching CLI
├── audio-midi-connect             # MIDI auto-connect
└── audio-upgrade-check            # Pre/post upgrade validation

Config Files

wireplumber.conf.d/50-device-profiles.conf

Forces device profiles via WirePlumber's device.profile.priority.rules:

  • SOF SoundWire → always HiFi (avoids 56+ unnamed pro-audio nodes)
  • TASCAM Model 12 → pro-audio first (multi-channel DAW access)
  • Roland / Arturia / Teenage Engineering → pro-audio first
  • Generic USB audio → pro-audio fallback (any new USB device gets pro-audio)

wireplumber.conf.d/51-alsa-node-rules.conf

Customizes node properties via monitor.alsa.rules:

Node Priority Purpose
Laptop Speakers 1000 Always-available fallback
Headphones 2000 Preferred when plugged in
TASCAM capture 3000 Auto-selects as mic when connected
TASCAM output 1500 Available for combine-sink
HDMI 500 Low priority
DMIC 500 Non-functional (SoundWire bus glitch)

pipewire.conf.d/20-combine-sinks.conf

Creates virtual combine sinks using libpipewire-module-combine-stream:

Ardour Monitor (ardour_monitor):

  • Combines TASCAM output + laptop headphones
  • Set Ardour's master bus to this sink
  • Latency-compensated for accurate monitoring
  • When TASCAM disconnects, headphones still work
  • When TASCAM connects, audio mirrors to both

VCV Rack Output (vcvrack_output):

  • Routes VCV Rack audio to laptop headphones
  • Monitor ports (vcvrack_output:monitor_FL/FR) available for Ardour capture
  • Keeps VCV Rack routing separate from Ardour
  • Works when undocked (headphones always available) and when docked (Ardour captures from monitor ports)
  • Other standalone synths (Cardinal, Dexed, Vital, Hydrogen, etc.) can also target this sink

Scripts

audio-health

Comprehensive diagnostic tool for the audio stack.

audio-health              # Full health check
audio-health --fix        # Attempt auto-fixes
audio-health --restart    # Restart WirePlumber + PipeWire
audio-health --reset-mic  # Reset DMIC mixer values to UCM defaults

Checks: PipeWire/WirePlumber services, SOF card detection, SoundWire codec attachment, profile correctness, DMIC mixer values, default sink/source, USB devices.

audio-profile

Switch USB audio device profiles.

audio-profile                # Show all device profiles
audio-profile tascam pro     # TASCAM → pro-audio
audio-profile tascam hifi    # TASCAM → HiFi (conferencing)
audio-profile roland pro     # Roland → pro-audio
audio-profile sof            # Show SOF card profile

audio-midi-connect

MIDI auto-routing for controllers and synths.

audio-midi-connect           # Show MIDI ports and links
audio-midi-connect --connect # One-shot: connect all known controllers
audio-midi-connect --watch   # Monitor and auto-connect (background)
audio-midi-connect --rules   # Show configured rules
audio-midi-connect --dry-run # Preview what would be connected

Auto-connects:

  • USB MIDI controllers (Rolands, TE, Keystep, SP-404, MiniBrute, DrumBrute) → Ardour MIDI inputs
  • MidiSport 4x4 capture ports → Ardour MIDI inputs (from modular rig / hardware)
  • Ardour MIDI outputs → MidiSport 4x4 playback ports (sequencing modular rig)

audio-upgrade-check

Pre/post upgrade validation for rolling-release survival.

audio-upgrade-check              # Validate current config compatibility
audio-upgrade-check --snapshot   # Save working state before upgrading
audio-upgrade-check --compare    # Compare current state against last snapshot
audio-upgrade-check --validate   # Check configs for syntax errors and conflicts

Snapshots are saved to ~/.local/state/audio-upgrade-snapshots/<timestamp>/ and include:

  • PipeWire, WirePlumber, Ardour, kernel, and SOF topology versions
  • Active node names and port lists
  • Config file checksums

Recommended upgrade workflow:

audio-upgrade-check --snapshot   # Before: save working state
# ... run system upgrade ...
audio-upgrade-check --compare    # After: detect any breakage
audio-upgrade-check              # Validate config compatibility
audio-health                     # Confirm everything still works

Installation

git clone <this-repo>
cd PipewirePersistentSinks
./install.sh
systemctl --user restart wireplumber

Re-run ./install.sh after editing any config files to deploy changes.

Usage Workflows

Video Call (TASCAM off)

Nothing to configure. Laptop headphones/speakers and headset mic work automatically with HiFi profile.

Music Production (TASCAM on)

  1. Power on TASCAM Model 12
  2. WirePlumber auto-selects pro-audio profile
  3. Open Ardour → set master bus output to "Ardour Monitor"
  4. Run audio-midi-connect --connect (or --watch for persistent monitoring)
  5. All MIDI controllers route to Ardour

Recording VCV Rack into Ardour

  1. Set VCV Rack output to "VCV Rack Output"
  2. In Ardour, create audio track capturing from vcvrack_output:monitor_FL/FR
  3. VCV audio plays through headphones AND records in Ardour
  4. Other standalone synths (Cardinal, Vital, Hydrogen, etc.) can use the same sink

VCV Rack / Standalone Synths When Undocked

Standalone apps route to the default laptop output automatically. The vcvrack_output combine-sink also works when undocked since it targets headphones. When docked, set the app's output to "VCV Rack Output" to enable Ardour capture via monitor ports.

New Device Connected

Generic USB audio devices auto-select pro-audio. To customize:

  1. Find the device name: pw-cli list-objects Device | grep device.name
  2. Add a rule to 50-device-profiles.conf
  3. Optionally add node rules to 51-alsa-node-rules.conf
  4. Run ./install.sh && systemctl --user restart wireplumber

Upgrade Resilience

This setup runs on a rolling-release distro (Garuda/Arch). Any pacman update could bump PipeWire, WirePlumber, Ardour, or the kernel. Here's what to expect.

Risk Assessment

Component Risk What Could Break How to Detect
WirePlumber 0.5.x → 0.5.y Low Nothing — 14 releases with zero config format changes audio-upgrade-check
WirePlumber 0.5 → 0.6 HIGH Config format could change entirely (like the 0.4→0.5 Lua→SPA JSON migration) audio-upgrade-check --compare shows WP major/minor bump
PipeWire 1.x Low context.modules and combine-stream have been stable across all 1.x releases audio-upgrade-check --validate
Ardour major version Medium MIDI port names may change (Ardour:MIDI port in regex in audio-midi-connect) audio-upgrade-check --compare checks Ardour port names
Kernel / SOF firmware Low-Medium SOF topology file rename, codec driver changes, node name changes audio-upgrade-check --compare diffs node list
USB node names Low Based on vendor/product USB descriptors — stable unless hardware changes audio-upgrade-check --compare

Upgrade Workflow

# 1. Before upgrading: snapshot the working state
audio-upgrade-check --snapshot

# 2. Run the system upgrade
sudo pacman -Syu

# 3. Restart the audio stack (if PipeWire/WirePlumber were updated)
systemctl --user restart wireplumber

# 4. Compare against the snapshot
audio-upgrade-check --compare

# 5. Validate configs are still compatible
audio-upgrade-check

# 6. Run full health check
audio-health

If Something Breaks

WirePlumber config format change (0.6+):

  1. Check the WirePlumber migration guide
  2. Config files to update: 50-device-profiles.conf, 51-alsa-node-rules.conf
  3. The config keys (device.profile.priority.rules, monitor.alsa.rules) may change names or nesting

Node names changed:

  1. Run pw-cli ls Node to find new names
  2. Update 51-alsa-node-rules.conf match patterns
  3. Update 20-combine-sinks.conf stream target regexes

Ardour MIDI ports renamed:

  1. Run pw-link -o | grep -i ardour to find new port names
  2. Update the regex patterns in audio-midi-connect

Combine sinks missing after upgrade:

  1. Check module still exists: ls /usr/lib/pipewire-0.3/libpipewire-module-combine-stream.so
  2. If renamed, update 20-combine-sinks.conf module name
  3. Restart: systemctl --user restart pipewire wireplumber

Downgrade (emergency):

# Arch/Garuda: downgrade a single package
sudo downgrade wireplumber
# or from cache
sudo pacman -U /var/cache/pacman/pkg/wireplumber-0.5.13-1-x86_64.pkg.tar.zst

History of Breaking Changes

Version Date Impact
WP 0.4 → 0.5.0 Jan 2024 TOTAL: Lua scripts → SPA JSON .conf files. Every config had to be rewritten.
WP 0.5.0 → 0.5.13 Jan 2024 – present None: All config format backward compatible. Bug fixes and feature additions only.
PW 0.3 → 1.0 Nov 2023 Module renames (combine-sinkcombine-stream). Config format unchanged.
PW 1.0 → 1.4 Nov 2023 – present None: No breaking config changes.

Standalone Software Synths

The following standalone apps are installed and can produce audio outside of Ardour. When used with Ardour, route them through the vcvrack_output combine-sink so Ardour can capture from the monitor ports.

App Type Notes
VCV Rack 2 Pro Virtual modular Primary standalone synth
Cardinal VCV Rack (open-source) Standalone + LV2/VST/CLAP
Vital Wavetable synth Standalone + LV2/VST3/CLAP
Dexed FM synth (DX7) Standalone + VST3/CLAP
Helm Polyphonic synth Standalone + LV2/VST
ZynAddSubFX Additive/subtractive Standalone + LV2/VST
Hydrogen Drum machine Standalone
Qtractor DAW / sequencer Standalone
Rosegarden MIDI sequencer / notation Standalone
MuseScore Notation / playback Standalone
Mixxx DJ Standalone

Most of these also exist as LV2/VST plugins loadable inside Ardour — in that case, no separate routing is needed.

Known Issues

  • DMIC (rt715): Built-in microphone is non-functional due to SoundWire bus glitch (thesofproject/linux#5495). May work after cold boot (not reboot/resume). Use headset mic as workaround.
  • Combine sinks and device hotplug: The combine-stream module dynamically adds/removes streams as devices appear. There may be a brief audio glitch when TASCAM connects/disconnects.
  • MIDI port names: Ardour port regex patterns (Ardour:MIDI port in) may not match across all Ardour versions. Adjust patterns in audio-midi-connect if needed.
  • Roland USB audio: When multiple Roland devices are connected, each appears as a separate USB audio device. Ensure WirePlumber selects pro-audio for each via the generic USB fallback rule.

Debugging

# Check WirePlumber logs
journalctl --user -fu wireplumber.service

# Check PipeWire logs
journalctl --user -fu pipewire.service

# List all nodes and their properties
pw-cli ls Node

# List all ports
pw-link -o  # outputs
pw-link -i  # inputs

# Check current links
pw-link -l

# Full health check
audio-health

Config Format Reference

WirePlumber 0.5.13 uses SPA JSON .conf files (NOT the Lua main.lua.d/ format from WP 0.4).

  • Drop-in configs: ~/.config/wireplumber/wireplumber.conf.d/*.conf
  • PipeWire modules: ~/.config/pipewire/pipewire.conf.d/*.conf
  • Profile selection chain: find-stored-profilefind-preferred-profilefind-best-profile
  • Config keys: device.profile.priority.rules, monitor.alsa.rules, context.modules

About

Fixing Pipewire challenges with my gear not consistently connecting audio and midi and also with multichannel devices sometimes not switching over to pro audio.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages