Installing the Broadcaster Sender
shiloh-broadcaster runs on any Linux machine that needs to send audio into the mix bus — a studio laptop, a desktop in another room, a guest’s machine on the same LAN. It creates a PipeWire null-sink, captures it via JACK, and streams the audio to shiloh-mixer over UDP.
Prerequisites
- Linux with PipeWire (and the
pipewire-pulsecompatibility shim) - JACK client libraries (provided by
pipewire-jackon modern distros) - pactl (part of the
pulseaudio-utilspackage, works with PipeWire) - Rust toolchain (if building from source — see Building from Source)
Verify PipeWire is running:
pactl info | grep "Server Name"
# Expected: Server Name: PulseAudio (on PipeWire ...)
Install missing packages if needed:
sudo apt install pipewire pipewire-pulse pipewire-jack pulseaudio-utils
1. Build the binary
cd ~/shiloh-broadcaster
cargo build --release -p shiloh-broadcaster
Optionally install it to ~/.local/bin:
mkdir -p ~/.local/bin
ln -sfn "$(pwd)/target/release/shiloh-broadcaster" ~/.local/bin/shiloh-broadcaster
2. Verify PipeWire null-sink support
shiloh-broadcaster list-sinks
You should see your current sinks listed (output from pactl list sinks short). If pactl fails, PipeWire’s pulse bridge is not active — run systemctl --user start pipewire-pulse.service.
3. Connect to the mixer
The --name argument must match an [[ingest.sender]] entry in the mixer’s shiloh-mixer.toml. --channels must also match the channels value in that entry.
shiloh-broadcaster connect stg-srv001.bq.shilohbv.com:5005 \
--channels 2 \
--name "studio"
Replace stg-srv001.bq.shilohbv.com:5005 with your mixer’s address. A stereo send uses --channels 2; a mono send uses --channels 1.
Additional flags:
| Flag | Default | Description |
|---|---|---|
--sink-name NAME |
Same as --name |
Override the name shown in PipeWire/PulseAudio sink lists |
--no-sink |
false | Skip creating the null-sink (use an externally managed sink) |
--verbose / -v |
false | Print per-second packet/underrun counters |
On successful connection you will see:
INFO shiloh_broadcaster::sink: loaded null-sink 'studio' (module 42) with 2 channels
INFO shiloh_broadcaster::net: registered with mixer; session=0x1a2b3c4d frames=128 rate=48000
4. Route audio to the null-sink
The null-sink appears in PipeWire/PulseAudio as a normal output device named after --name (or --sink-name). Route audio to it using any of:
GUI — GNOME / KDE sound settings: select studio (or your sink name) as the output device for the application you want to broadcast.
pavucontrol:
pavucontrol
# In the "Playback" tab, click the output selector for your app and choose the null-sink.
pw-link (command-line):
# List available ports
pw-link --output
# Connect a specific app output to the null-sink monitor inputs
pw-link "Ardour:out 1" "studio:monitor_AUX0"
pw-link "Ardour:out 2" "studio:monitor_AUX1"
NOTE: The null-sink’s JACK/PipeWire ports are named
{sink_name}:monitor_AUX0,monitor_AUX1, etc. The broadcaster auto-connects these to its own capture ports — you only need to route your application output to the sink, not to the broadcaster’s JACK ports directly.
5. Verify the connection
On the mixer host, watch the logs:
journalctl --user -u shiloh-mixer.service -f
You should see:
INFO shiloh_mixer::ingest: accepted sender "studio" → slots 0..2, session=0x1a2b3c4d
On the broadcaster side with --verbose:
[stat] 375 pps underruns=0 ring_full=0
375 pps at 128 frames/packet is correct for 48 kHz stereo (48000 / 128 = 375).
6. systemd user unit for auto-start
Create ~/.config/systemd/user/shiloh-broadcaster.service:
[Unit]
Description=shiloh-broadcaster — PipeWire→JACK→UDP audio sender
After=pipewire.service pipewire-pulse.service
[Service]
Type=simple
ExecStart=%h/.local/bin/shiloh-broadcaster connect \
stg-srv001.bq.shilohbv.com:5005 \
--channels 2 \
--name studio
Restart=on-failure
RestartSec=5
Environment=RUST_LOG=info
Environment=XDG_RUNTIME_DIR=/run/user/1000
[Install]
WantedBy=default.target
NOTE: Replace
1000with your actual UID (id -u). Replace the server address and--namewith your values.
systemctl --user daemon-reload
systemctl --user enable shiloh-broadcaster.service
systemctl --user start shiloh-broadcaster.service
systemctl --user status shiloh-broadcaster.service
Troubleshooting
| Symptom | Likely cause |
|---|---|
pactl load-module failed |
PipeWire-pulse bridge not running; systemctl --user start pipewire-pulse |
rejected by mixer |
--name does not match any [[ingest.sender]] entry in the mixer config |
sample rate mismatch |
Local JACK session not at 48 kHz; check with pw-jack jack_samplerate |
| Choppy audio at the relay | Increase ring size by setting broadcast_frames = 320 on the mixer |
| Null-sink disappears on exit | Expected — it is unloaded on Drop. The systemd unit will reload it on restart. |