{% markdown %}
I briefly tried using [PulseAudio over the network](https://wiki.archlinux.org/index.php/PulseAudio/Examples#PulseAudio_over_network), but decided to use [Snapcast](https://github.com/badaix/snapcast) instead.
Snapcast seems to be more tolerant of network issues, doesn't require installing PulseAudio on otherwise headless machines, and has pretty good synchronization between rooms.
A Snapcast installation is split into one _Snapserver_ and multiple _Snapclients_.
Audio comes in to the Snapserver from one or more sources, and is broadcast out to the Snapclients, with a minor delay for synchronization.
On the machine being the Snapserver, install the `snapserver` package from APT, and configure its audio sources.
This snippet configures two sources:
- For [MPD controlled by UPnP](https://www.lesbonscomptes.com/upmpdcli/), it
- reads from a named pipe at `/tmp/snapfifo`,
- and presents it in the Snapcast UI as `UPnP`.
- For [AirPlay](https://en.wikipedia.org/wiki/AirPlay), it
- starts the binary `/usr/bin/shairport-sync`,
- presents it in the UI as `AirPlay`,
- sets it to use 44.1Khz output instead of 48Khz,
- and logs `shairport-sync`'s stderr.
- `shairport-sync` itself is configured to output audio to its stdout.
```sh
$ cat /etc/default/snapserver
SNAPSERVER_OPTS="--stream pipe:///tmp/snapfifo?name=UPnP --stream process:///usr/bin/shairport-sync?name=AirPlay&sampleformat=44100:16:2&log_stderr=true"
```
On all the machines being Snapclients, install the `snapclient` package, and configure their human-readable names.
For example, for the Snapclient in my living room:
```sh
$ cat /etc/default/snapcast
SNAPCLIENT_OPTS="--hostID 'Living Room'"
```
## Control
I primarily control Snapcast using a [CatBus](/catbus) daemon.
In addition, I have configured both `shairport-sync` and `upmpdcli` to switch Snapcast to their respective input when they start playing.
{% endmarkdown %}
{% endblock %}