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.