Mixer Won’t Start

Use this decision tree when systemctl --user start shiloh-mixer fails, or the service starts then immediately exits.


Step 0: Check the exit reason

journalctl --user -u shiloh-mixer -n 50

Find the last error line and match it to a branch below.


Branch 1: JACK server not running

Symptom: Log contains Failed to open client or Cannot connect to server socket.

shiloh-mixer opens a JACK client at startup. If no JACK server is present, it exits immediately.

Check:

pw-jack jack_lsp 2>&1 | head -5

If this prints Cannot connect to server socket or returns no ports, JACK/PipeWire-JACK is not running.

Fix — PipeWire-JACK (recommended on Ubuntu 24.04):

# Confirm PipeWire is running
systemctl --user status pipewire pipewire-pulse wireplumber

# If any are stopped:
systemctl --user start pipewire pipewire-pulse wireplumber

# Verify JACK shim works
pw-jack jack_lsp

Fix — classic jackd:

jackd -d alsa -d hw:0 -r 48000 -p 1024 &

Adjust -d hw:N to your audio device. Run aplay -l to list devices.

Fix — persistent (driverless graph):

If PipeWire is running but pw-top shows every node at QUANT=0 RATE=0, no hardware is clocking the graph. See the “driverless graph” section in OPERATIONS.md for the WirePlumber keep-awake rule.


Branch 2: TOML config parse error

Symptom: Log contains TOML parse error or failed to deserialize config.

Locate the config:

ls ~/mixer/shiloh-mixer.toml

Common syntax mistakes:

Mistake Example (wrong) Example (correct)
Missing quotes on string name = studio name = "studio"
Wrong array syntax channels = [1 2] channels = [1, 2]
Extra comma in table [ingest.sender], [ingest.sender]
Duplicate key Two [ingest] sections Merge into one
Wrong boolean muted = True muted = true

Validate before restarting:

# Quick syntax check (needs `taplo` or python3-toml)
python3 -c "import tomllib; tomllib.load(open('$HOME/mixer/shiloh-mixer.toml','rb'))" && echo "OK"

# Or use taplo if installed
taplo lint ~/mixer/shiloh-mixer.toml

Branch 3: Port already in use

Symptom: Log contains address already in use on 0.0.0.0:5005 or 127.0.0.1:19997.

Find the process holding the port:

# UDP 5005
ss -lunp | grep 5005

# All mixer ports
ss -lunp | grep -E '5005|19997|19999'

If it’s a stale shiloh-mixer:

# Find the PID from the ss output (e.g. pid=12345)
kill <PID>
systemctl --user start shiloh-mixer

Do not pkill shiloh-mixer broadly — it could kill unrelated processes. Use the PID from ss or from systemctl --user show shiloh-mixer --property=MainPID.

If it’s something else:

Change the port in shiloh-mixer.toml and update any client configs to match.


Branch 4: Permission denied on audio device

Symptom: Log contains Permission denied referencing /dev/snd/ or an ALSA device node.

Check group membership:

groups | grep audio

If audio is not in the list:

sudo usermod -aG audio $USER
# Log out and back in, then verify:
groups | grep audio

Check device permissions:

ls -la /dev/snd/

All controlC* and pcmC* entries should be group audio with rw-rw----.

PipeWire-JACK note: Under PipeWire you generally do not need the audio group — PipeWire’s daemon runs as the user and brokers all device access. If permission errors appear with PipeWire, the issue is usually that the JACK shim is trying to open ALSA directly. Confirm shiloh-mixer is launched with pw-jack:

# The systemd service should use pw-jack wrapper:
grep ExecStart ~/.config/systemd/user/shiloh-mixer.service
# Should show: ExecStart=/usr/bin/pw-jack ...

Branch 5: Native jackd conflicts with pw-jack

Symptom: USB audio devices are unavailable, or audio through USB codec sounds distorted/electronic. ALSA shows “device or resource busy”.

Check for running jackd:

pgrep -a jackd

If a native jackd is running (e.g. jackd -d alsa -d hw:CODEC), it has claimed the audio device before PipeWire could.

Check for jackd systemd service:

systemctl --user list-units | grep jack

Fix — disable native jackd:

# Stop and disable any jackd service
systemctl --user stop jackd.service
systemctl --user disable jackd.service

# Kill any manually started jackd
pkill jackd

# Restart PipeWire to claim the devices
systemctl --user restart pipewire wireplumber

# Verify the device is now in PipeWire
wpctl status | grep -i codec

With pw-jack, PipeWire owns all audio devices and the mixer connects via PipeWire’s JACK shim. Do not run native jackd alongside pw-jack.


Branch 6: High CPU / xrun floods

Symptom: Service is running but logs are flooded with xrun messages, or CPU is pegged at 100%.

xruns mean the JACK callback missed its deadline. Common causes:

Cause Diagnosis Fix
Buffer too small journalctl | grep xrun shows continuous stream Increase JACK buffer frames
CPU throttling cpufreq-info | grep "current CPU" shows low freq Set CPU governor to performance
IRQ contention cat /proc/interrupts shows USB/audio IRQ on wrong CPU irqbalance or manual IRQ affinity
Other RT processes competing chrt -p $(pidof shiloh-mixer) Raise or lower priorities

Increase JACK buffer size (PipeWire):

# Check current quantum
pw-metadata -n settings 0 clock.quantum

# Set a larger quantum (e.g. 1024 frames at 48 kHz = ~21 ms)
pw-metadata -n settings 0 clock.quantum 1024
pw-metadata -n settings 0 clock.min-quantum 1024
pw-metadata -n settings 0 clock.max-quantum 1024

Make it permanent in ~/.config/pipewire/pipewire.conf.d/quantum.conf:

context.properties = {
  default.clock.quantum     = 1024
  default.clock.min-quantum = 1024
  default.clock.max-quantum = 1024
}

Trade-off: larger buffers reduce xruns but increase latency.

Set CPU governor:

sudo cpupower frequency-set -g performance

See Performance Tuning for RT priority and CPU pinning.