Requirements

  • Multi-room audio distribution
  • 3+ zone
  • Reliable (wired) audio rendering
  • Allow ipod/mp3 player input
  • Remote power trigger for Amplifier

Options

  • Bidirectional streaming? (ipod in bedroom streams to whole house?)
  • Synchronization (it's hard!)
    • Logitech Media Server
    • Snapcast
  • Home Automation integration - see Network Receivers
    • Remote volume control

Solutions

| Amp | Speakers | Renderer Controller | Notes | | ---------------------------- | -------------------------- | ----------------------------- | -------------- | | Clever Acoustics CPA40 | Wharfedale Diamond 9 | Kindle Fire 7 | Power trigger! | | Medialabs FC330 | Raspberry Pi + Kodi | USB-OTG eth, no power trigger | | Squeezebox Duet | no power trigger | | Squeezebox Radio | Mono only |

Components

  • Server (1)
  • Amp & Speakers (1 set per zone)
  • Renderer (1 per zone) - ethernet, audio decoding
  • Controller (1 per zone + mobile controllers) - user interface

Server

Renderer

  • mmpc
  • media streamer (from Nokia)
  • Kodi

Renderer-Controllers

Amplifiers and Speakers


Research

Amplifiers

Onkyo

Automation : HA Onkyo (power, volume, source)

Yamaha

Automation : OpenHAB Yamaha (power, volume, mute, source)

  • Yamaha RXV-475
  • RXV-379 (2015, 5.1 only)

Denon

Automation : OpenHAB Denon

Renderer-Controllers


Software

Components:

  • mopidy
  • snapcast
  • shairport-sync
  • upmpdcli

mopidy

snapcast

Install snapclient on all media player nodes:

Releases : https://github.com/badaix/snapcast/releases

Server : amd64 deb

Clients : Android, RPi

No iOS equivalent?

Note that snapclient on volumio is symlinked to /usr/sbin/snapclient. The default snapclient is very old (~0.2) and won't work with recent snapservers (0.11+).

Snapserver config

  • Don't daemonize. systemd does it for you.
  • Use the same or separate streams for mopidy and airport?
  • Depends on librespot@.service templates for multiple instances of librespot service

/etc/defaults/snapserver:

USER_OPTS="--user snapserver:snapserver"

SNAPSERVER_OPTS=" \
    -s 'pipe:///tmp/snapfifo0?name=Mopidy&sampleformat=44100:16:2&codec=flac' \
    -s 'pipe:///tmp/snapfifo1?name=Airport&sampleformat=44100:16:2&codec=flac' \
    -s 'pipe:///tmp/librespot1?name=Spotify-1&sampleformat=44100:16:2&codec=flac' \
    -s 'pipe:///tmp/librespot2?name=Spotify-2&sampleformat=44100:16:2&codec=flac' \
    -s 'pipe:///tmp/librespot3?name=Spotify-3&sampleformat=44100:16:2&codec=flac' \

"

Multi-instance snapclient systemd service

/etc/systemd/system/snapclient@.service:

# Multi-instance snapclient service file
[Unit]
Description=Snapcast client
After=network-online.target sound.target
Requires=network-online.target
Wants=avahi-daemon.service

[Service]
# Uses a per-instance defaults file to specify the soundcard device
EnvironmentFile=-/etc/default/snapclient-%i
Type=forking
ExecStart=/usr/bin/snapclient -d $USER_OPTS -i %i $SNAPCLIENT_OPTS
PIDFile=/var/run/snapclient/pid-%i
Restart=always

[Install]
WantedBy=multi-user.target

/etc/default/snapclient-x:

# Legacy?
START_SNAPCLIENT=true

USER_OPTS="--user snapclient:audio"
SNAPSERVER_HOSTNAME=media

# Don't specify -i here, it's added by the systemd service
# RPi HDMI soundcard
SNAPCLIENT_OPTS="-h $SNAPSERVER_HOSTNAME -s CARD=ALSA,DEV=1"

Install with:

sudo systemctl enable snapclient@1
sudo systemctl enable snapclient@2
...etc..

librespot

Spotify daemon.

Multi-instance librespot systemd service

Depends on snapserver. Using TCP ports 22120-22129.

/etc/systemd/system/librespot@.service:

[Unit]
Description=Librespot
Requires=snapserver.service
After=network.target storage.target snapserver.service

[Service]
#EnvironmentFile=/etc/default/librespot
User=snapserver
Group=audio
Restart=always
RestartSec=10
PermissionsStartOnly=true
Environment="CACHE_DIR=/path/to/librespot-cache"

ExecStartPre=/bin/mkdir -m 1755 -p ${CACHE_DIR}/%i
ExecStartPre=-/bin/chown snapserver:audio ${CACHE_DIR}/%i

# Create the fifo for snapserver to read
ExecStartPre=-/usr/bin/mkfifo /tmp/librespot%i
ExecStartPre=-/bin/chown snapserver:audio /tmp/librespot%i

Environment="DEVICE_NAME=Spotify-%I"
Environment="BITRATE=96"
Environment="CACHE_ARGS=--cache ${CACHE_DIR}/%i"
Environment="VOLUME_ARGS=--enable-volume-normalisation --linear-volume --initial-volume=100"
Environment="BACKEND_ARGS=--backend pipe --device /tmp/librespot%i"
## Abuse the instance ID to open a known port (for firewalling)
Environment="ZEROCONF_ARGS=--zeroconf-port 2212%i"
ExecStart=/usr/local/bin/librespot --name ${DEVICE_NAME} $BACKEND_ARGS --bitrate ${BITRATE} $CACHE_ARGS $VOLUME_ARGS $ZEROCONF_ARGS $OPTIONS

[Install]
WantedBy=multi-user.target snapserver.service

Install with:

sudo systemctl enable librespot@1
sudo systemctl enable librespot@2
...etc..

shairport-sync

upmpdcli

Available for armhf Jessie-based Volumio but not for Stretch-based OSMC.

Packages available from: https://www.lesbonscomptes.com/upmpdcli/downloads.html#debian

Install

# Depends on libjsoncpp0:
echo "deb http://archive.raspbian.org/raspbian/ jessie main contrib non-free rpi" >> /etc/apt/sources.list.d/raspbian.list
apt-key adv --keyserver pool.sks-keyservers.net --recv-keys F8E3347256922A8AE767605B7808CE96D38B9201
echo "deb http://www.lesbonscomptes.com/upmpdcli/downloads/raspbian/ stretch main" > /etc/apt/sources.list.d/upmpdcli.list
apt-get update
apt-get install upmpdcli

Configure

Edit /etc/upmpdcli.conf (and for Volumio, copy it to /tmp/upmpdcli.conf):

Two settings needed:

friendlyname = my-hostname
upnpiface = eth0  # or wlan0, or whatever