Monday, August 13, 2018

Turning Raspberry Pi into an AirPlay Receiver

This might appeal to almost no one, but here's how to combine a Raspberry Pi with an AV amplifier to stream music from iPhone remotely.

Why This Setup?

Our living room has an Amazon Fire TV Stick plugged into the AV amplifier's HDMI input.
Output goes to a projector over HDMI.

With the right app, Amazon Fire TV can act as an AirPlay receiver,
so I can stream music from iPhone and play it through the AV amp's speakers.

The problem: the moment AirPlay starts, Amazon Fire TV Stick wakes from sleep.
The projector then detects the HDMI signal change and automatically powers on.

All I wanted to do was listen to music, and the entire AV stack wakes up.

Annoying enough to fix — so I turned a Raspberry Pi into a dedicated AirPlay receiver for audio.
This way, the Fire TV Stick stays asleep (since we're not using it), and since the Pi doesn't output a video signal, the projector never wakes up.

The AV amplifier also didn't auto-switch inputs, so that required a bit of extra work on the Pi side.

Getting Raspberry Pi Audio Out via HDMI

By default, Raspberry Pi doesn't output audio over HDMI.
To fix this, uncomment the following line in /boot/config.txt and reboot:
hdmi_drive=2

Then run the following command — if you hear a tone from the HDMI-connected speakers, it's working:
$ speaker-test -t sine -f 600

Installing shairport-sync on Raspberry Pi

Install shairport-sync, an AirPlay receiver daemon.
There's also a tool just called "shairport" — it's completely separate, so don't confuse the two.

First, install the dependencies:
$ sudo apt-get install -y build-essential git xmltoman autoconf automake libtool libdaemon-dev libasound2-dev libpopt-dev libconfig-dev avahi-daemon libavahi-client-dev libssl-dev libsoxr-dev

Then clone and build shairport-sync from GitHub:
$ git clone https://github.com/mikebrady/shairport-sync.git
$ autoreconf -i -f
$ ./configure --with-alsa --with-avahi --with-ssl=openssl --with-metadata --with-soxr --with-systemd
$ make
$ sudo make install

After installation, enable autostart:
$ sudo systemctl enable shairport-sync

Configuration

At this point you can stream AirPlay from iPhone, but the volume will be oddly low.
To fix this, ignore the iPhone's volume control and let the Raspberry Pi side (or the AV amp it feeds) handle volume.

First, set volume to 100%:
$ sudo amixer cset numid=1 100%

The shairport-sync config file is at /usr/local/etc/shairport-sync.conf.
Find and change these lines (uncomment if commented out):
general = {
    :
interpolation = "soxr";
ignore_volume_control = "yes";
Setting interpolation to "soxr" reportedly improves audio quality.
However, on Raspberry Pi Zero W, CPU couldn't keep up and audio dropped out.
If you get dropouts, comment out the interpolation line to revert to the default.

Setting ignore_volume_control to "yes" makes the Pi ignore iPhone's volume.

Switching AV Amplifier Input

Depending on your AV amplifier, it may not auto-switch inputs when Raspberry Pi starts HDMI audio output — mine didn't.
The workaround: capture the AV amp's IR remote codes, then send the "switch to HDMI input" command from the Pi at the right moment.
For how to copy IR remote codes, see the earlier article in this series.

The key question is timing — when to fire the IR signal.
Conveniently, shairport-sync.conf has exactly this built in.
Uncomment and set these lines:
sessioncontrol = {
       :
        run_this_before_play_begins = "/usr/bin/irsend SEND_ONCE AV hdmi2";
        run_this_after_play_ends = "/usr/bin/irsend SEND_ONCE AV tv";

run_this_before_play_begins fires when iPhone selects this Pi as an AirPlay destination.
run_this_after_play_ends fires when AirPlay ends (audio stream stops).

After editing the config, restart the service:
$ sudo service shairport-sync restart

Once configured, streaming AirPlay from iPhone to Raspberry Pi will automatically switch the AV amplifier's input and start playback.

No comments:

Post a Comment