Relay Audio Problems

Use this guide when a relay client (shiloh-relay connect) is connected but audio is silent, distorted, or playing through the wrong device.


Branch 1: No audio — verify the relay registered

First, check the server logs for the relay registration:

journalctl --user -u shiloh-mixer -n 100 | grep -E "ACCEPT|relay registered|session"

You should see a line like:

INFO accepted session=0xABCD1234 name=pi-relay ...

If no such line appears for your relay’s name, the relay never connected. Check basic network reachability:

# From the relay machine:
nc -u <MIXER_HOST> 5005
# Type any character and press Enter — no "connection refused" means the port is reachable

Check the mixer UI sessions panel:

Open http://<mixer-host>:8889/ and look at the Sessions panel. The relay should appear with a feed selector showing main / monitor / cue. If it is assigned to off, no audio is forwarded — change it to main.

Verify the relay’s feed is enabled:

In the mixer UI, confirm the relay’s assigned feed (e.g. main) has relay enabled. Feeds can be individually muted.


Branch 2: Crackling / dropouts

Crackling is almost always caused by packet loss or buffer underruns on the relay’s playback side.

Increase the relay buffer:

shiloh-relay connect --server HOST:PORT --name my-relay --buffer-ms 100

Default is typically 20–40 ms. Try 100 ms first; if that helps, tune down until crackling returns, then step back up.

Check network quality:

# From the relay machine to the mixer:
ping -i 0.01 -c 1000 <MIXER_HOST> | tail -5

Look at the packet loss and mdev (jitter) lines. More than 0.1% loss or jitter > 5 ms on a LAN indicates a network problem. Common causes:

  • WiFi interference (switch to wired Ethernet if possible)
  • Overloaded switch / hub
  • Traffic shaping or QoS misconfiguration

Check the relay’s verbose output for underruns:

shiloh-relay connect --server HOST:PORT --name my-relay --verbose

The --verbose flag prints per-second stats. underruns > 0 means the playback thread is starving.


Branch 3: Wrong audio device

By default the relay plays to the system’s default output. To target a specific device:

List available output devices:

shiloh-relay list-devices

This prints all PipeWire/PulseAudio sinks with their exact names.

Connect to a specific device:

shiloh-relay connect --server HOST:PORT --name my-relay --device "Focusrite USB"

The --device argument is a substring match against the device name — partial strings work as long as they are unambiguous.

Verify the device is active in PipeWire:

pactl list sinks short

Look for your device in the list. If it shows SUSPENDED, play any audio briefly to wake it, or add a WirePlumber keep-awake rule (see OPERATIONS.md).


Branch 4: Packet loss — check sequence gaps

Enable verbose output:

shiloh-relay connect --server HOST:PORT --name my-relay --verbose

Sequence gaps appear as seq gap: expected X got Y in verbose mode. Sporadic gaps (< 1%) are usually benign. Continuous gaps indicate the UDP path is lossy.

Diagnose the path:

# Continuous ping at 50 pps to simulate audio packet rate
ping -i 0.02 -c 500 <MIXER_HOST>

# Check if firewall is rate-limiting UDP
iptables -L -n -v 2>/dev/null | grep -i udp

Firewall / NAT note: If the relay is behind NAT or a strict firewall, UDP sessions may be torn down after short idle periods. The mixer’s heartbeat keeps the session alive on the server side, but stateful firewalls between client and server may not track UDP streams. Set a longer UDP conntrack timeout or use WireGuard:

# Linux conntrack (on the router/firewall):
sysctl -w net.netfilter.nf_conntrack_udp_timeout=120
sysctl -w net.netfilter.nf_conntrack_udp_timeout_stream=120