Custom JACK Port Wiring

Autoconnect vs. manual wiring

shiloh-mixer uses two wiring mechanisms:

Mechanism Config Persistence Use case
[[autoconnect]] in TOML Yes Survives restarts Hardware inputs, fixed routing
jack_connect / pw-link No (one-off) Lost on JACK restart Temporary patches, debugging

Use [[autoconnect]] for anything you want to survive a service restart. The autoconnect watcher reconnects ports every ~5 seconds, so it also handles hardware device reconnects (e.g. a USB interface being unplugged and replugged).


Listing ports

# All JACK ports (readable)
pw-jack jack_lsp

# With connections shown
pw-jack jack_lsp -c

# Only shiloh-mixer ports
pw-jack jack_lsp | grep shiloh-mixer

Port naming convention

shiloh-mixer registers ports as:

Port JACK name
Mono channel input shiloh-mixer:{channel_id}_in
Stereo channel left input shiloh-mixer:{channel_id}_in_1
Stereo channel right input shiloh-mixer:{channel_id}_in_2
Main bus output L shiloh-mixer:main_out_1
Main bus output R shiloh-mixer:main_out_2
Monitor bus output shiloh-mixer:monitor_out_1, _out_2
Cue bus output shiloh-mixer:cue_out_1, _out_2

Autoconnect configuration (TOML)

[[autoconnect]]
from = "PCM2902 Audio Codec Analog Stereo:capture_FL"
to   = "shiloh-mixer:mic_l_in"

[[autoconnect]]
from = "PCM2902 Audio Codec Analog Stereo:capture_FR"
to   = "shiloh-mixer:mic_r_in"

# Route the mixer's main output to a hardware DAC
[[autoconnect]]
from = "shiloh-mixer:main_out_1"
to   = "Focusrite Scarlett:playback_FL"

[[autoconnect]]
from = "shiloh-mixer:main_out_2"
to   = "Focusrite Scarlett:playback_FR"

Find the exact port names with pw-jack jack_lsp.


pw-link is PipeWire’s native port linking tool. It links PipeWire objects directly (bypassing the JACK shim):

# List all linkable ports
pw-link -l

# Link two ports
pw-link "Microphone:capture_FL" "shiloh-mixer:mic_l_in"

# Unlink
pw-link -d "Microphone:capture_FL" "shiloh-mixer:mic_l_in"

# List current links
pw-link -lo

Manual wiring with jack_connect

Interchangeable with pw-link on PipeWire-JACK systems:

# Connect hardware capture to mixer input
pw-jack jack_connect \
  "PCM2902 Audio Codec Analog Stereo:capture_FL" \
  "shiloh-mixer:mic_l_in"

# Disconnect
pw-jack jack_disconnect \
  "PCM2902 Audio Codec Analog Stereo:capture_FL" \
  "shiloh-mixer:mic_l_in"

Loopback and monitoring tricks

Monitor the main mix on headphones while recording

Connect the main mix output to both the broadcast output and a headphone output:

# Main mix → headphone output (in addition to existing connections)
pw-jack jack_connect "shiloh-mixer:main_out_1" "Built-in Audio Analog Stereo:playback_FL"
pw-jack jack_connect "shiloh-mixer:main_out_2" "Built-in Audio Analog Stereo:playback_FR"

This is non-destructive — JACK allows one output to feed multiple inputs.

Loopback: send mixer output back in as an input channel

Useful for recording the mix to an Ardour track:

# Wire main out to an Ardour input
pw-jack jack_connect "shiloh-mixer:main_out_1" "ardour:Audio 1/audio_in 1"
pw-jack jack_connect "shiloh-mixer:main_out_2" "ardour:Audio 1/audio_in 2"

Record individual channels with Ardour

Each channel in shiloh-mixer has a direct output port. Connect them to separate Ardour tracks for multitrack recording:

pw-jack jack_connect "shiloh-mixer:mic_l_direct_out" "ardour:Track 1/audio_in 1"
pw-jack jack_connect "shiloh-mixer:mic_r_direct_out" "ardour:Track 2/audio_in 1"

(Check exact port names with pw-jack jack_lsp | grep shiloh-mixer.)


Scripting port connections

For complex routing that changes between sessions, use a shell script:

#!/bin/bash
# routing-live-set.sh — wiring for the live event setup
set -euo pipefail

JACK="pw-jack jack_connect"

# Inputs
$JACK "Focusrite USB:capture_FL" "shiloh-mixer:studio_in_1"
$JACK "Focusrite USB:capture_FR" "shiloh-mixer:studio_in_2"
$JACK "desktop-audio:monitor_FL" "shiloh-mixer:desktop_in"

# Outputs
$JACK "shiloh-mixer:main_out_1" "Focusrite USB:playback_FL"
$JACK "shiloh-mixer:main_out_2" "Focusrite USB:playback_FR"

echo "Routing applied."

Run after startup, or add as an ExecStartPost= in the systemd unit if the ports are always available.