Last Updated: 26 Mar 2018

   |   

Author: dordal

Installing AirPlay on Tomato - 2018 Edition

It's possible to make your Tomato Router run an AirPlay daemon, allowing you to stream music from iTunes, your iOS devices, etc.

Qui Hong wrote an excellent blog post in 2012 about how to do this. A lot has changed since then – most of the packages he used are no longer maintained, but others have forked the originals and are maintaining new versions.

I've built on his work, and written an updated tutorial for 2018.

What you'll need

To get AirPlay working, you'll need a couple things:

Step 1: Install Tomato

If you haven't done so already, you'll need to install Tomato on your router, and configure Tomato for your network. The details of getting Tomato on your router is beyond the scope of this tutorial, but you'll find plenty of links to great tutorials on the Advanced Tomato download page.

Make sure you use the VPN version of Tomato, and NOT the 'All In One' (AIO) version. The VPN version contains some kernel headers that allow a couple of the necessary modules to load; as of this writing the AIO version didn't.

Step 2: Enable USB Support

Make sure USB support is enabled. In the Tomato admin interface, under 'USB & NAS > USB Support', make sure the following are checked:

  • Core USB Support
  • USB 2.0 Support
  • USB 1.1 Support OHCI (I'm not sure why, but this seemed to be required, even though I was using a fairly modern soundcard)
  • USB Storage Support
  • Automount

Everything except USB 1.1 support will probably be checked by default; you really only need 1.1 support if you're using an old USB 1.X device, but it doesn't hurt to have it turned on.

Step 3: Format your USB Stick & Install Entware

Now comes the fun part. Login to your router via SSH, and get to a command prompt. You should see something like this (note your IP will probably be different):

MBP:~ dordal$ ssh -l root 192.168.50.1
root@192.168.50.1's password: 

Tomato v1.28.0000 MIPSR2-3.2-137 K26 USB VPN
 ======================================================== 
 Welcome to the Asus RT-N16 [TomatoUSB]
 Uptime:  23:43:30 up  1:10
 Load average: 0.45, 0.22, 0.18
 Mem usage: 13.0% (used 16.13 of 123.94 MB)
 WAN1: XXX.XXX.XXX.XXX/24 @ AA:AA:AA:AA:AA:AA
 LAN : XXX.XXX.XXX.XXX/24 @ DHCP: XXX.XXX.XXX.XXX - XXX.XXX.XXX.XXX
 WL0 : 2,4GHz @ network @ channel: 6 @ AA:AA:AA:AA:AA:AA
 ======================================================== 

root@unknown:/tmp/home/root# 

Now, create a new partition on your USB stick:

# Create a partition
umount /dev/sda1 
fdisk /dev/sda

Then type in the following commands:

# p # list current partitions
# o # to delete all partitions
# n # new partition
# p # primary partition
# 1 (one) # first partition
# <enter> # default start block
# <enter> # default end block #use the whole flash drive
# w # write new partition to disk

Now format the new partition:

# umount /dev/sda1 incase it was automounted
umount /dev/sda1

# format newly created partition
# label disk as 'entware' case sensitive
mke2fs -j -L entware /dev/sda1

# mount the new disk partition
mount /dev/sda1 /opt

# Make sure /opt is properly mounted on a reboot.
echo "LABEL=entware /opt ext3 defaults 1 1" >> /etc/fstab

nvram setfile2nvram /etc/fstab 

nvram commit

Finally, install entware-ng. Entware is a package repo for embedded devices, and what you'll use to install everything from here on out:

# Install entware-ng
cd /opt
wget -qO - http://pkg.entware.net/binaries/mipsel/installer/installer.sh | sh

Step 4: Install shairport-sync and other needed software

Now you'll need to install shairport-sync, which is the new version of the now depreciated shairport, and other required software.

# install dbus, avahi (aka bonjour), shairport-sync
opkg install dbus avahi-daemon avahi-utils shairport-sync-openssl alsa-utils

Next download the extra kernel modules you need.

WARNING WARNING WARNING. Depending on your version of Tomato, the link below may be different. You may not be on build 140, and/or you may not be on a K26 router. Check Shibby's firmware download directory to find the right link.

# download extra kernel modules. 
cd /tmp
# NOTE THE LINK BELOW MAY BE DIFFERENT FOR YOUR ROUTER
wget http://tomato.groov.pl/download/K26/build5x-140-MultiWAN/extras-mips2.tar.gz
mkdir /opt/extras
cd /opt/extras
tar xvzf /tmp/extras-mips2.tar.gz

# load sound modules. if you get an error on the last three modules, make sure you've
# flashed the 'VPN' version of Tomato, not the 'AIO' version.
insmod /opt/extras/soundcore
insmod /opt/extras/snd
insmod /opt/extras/snd-hwdep
insmod /opt/extras/snd-page-alloc
insmod /opt/extras/snd-timer
insmod /opt/extras/snd-pcm
insmod /opt/extras/snd-seq-device
insmod /opt/extras/snd-seq
insmod /opt/extras/snd-rawmidi
insmod /opt/extras/snd-seq-midi-event
insmod /opt/extras/snd-seq-midi
insmod /opt/extras/snd-mixer-oss
insmod /opt/extras/snd-pcm-oss
insmod /opt/extras/snd-usb-lib
insmod /opt/extras/snd-usb-audio
insmod /opt/extras/input-core
insmod /opt/extras/hid
insmod /opt/extras/usbhid

Now you have to pull the config file for shairport-sync, as the package doesn't install it. The new one is on Github.

wget https://raw.githubusercontent.com/mikebrady/shairport-sync/master/scripts/shairport-sync.conf /opt/etc/shairport-sync.conf

NOTE: If you get a 'connection reset by peer' message, you'll have to manually download this file via your browser, and upload it to your router (e.g. by pasting it into vi)

Step 5: Setup Your Soundcard & Test Your Sound

Install the setup script for the sound devices:

mkdir -p /opt/src/alsa
cd /opt/src/alsa
opkg install bzip2
wget ftp://ftp.alsa-project.org/pub/driver/alsa-driver-1.0.25.tar.bz2
bzip2 -d alsa-driver-1.0.25.tar.bz2 
tar xvf alsa-driver-1.0.25.tar 

Run that to configure sound devices:

alsa-driver-1.0.25/snddevices

Now init ASLA:

alsactl init

Make sure ALSA sees your USB card:

# aplay -l

**** List of PLAYBACK Hardware Devices ****
card 0: default [USB Sound Device        ], device 0: USB Audio [USB Audio]
  Subdevices: 1/1
  Subdevice #0: subdevice #0

Now test your sound. Plug your headphones in; THIS MAY BE LOUD.

mkdir -p /opt/test
cd /opt/test
wget http://www.kozco.com/tech/LRMonoPhase4.wav
aplay -v LRMonoPhase4.wav

You should hear sound from both channels. If you don't, go back and retrace your steps.

If you do, onward:

Step 6: Startup Shairport

Run through this process to startup shairport-sync, and play audio.

# delete orphan pid files in case they exist. You may get an error if they don't; that's OK.
rm /opt/var/run/dbus.pid
rm /opt/var/run/avahi-daemon/pid

# required to start avahi-daemon
echo "nogroup:x:2:" >> /tmp/etc/group
echo "nogroup:x:2:2:avahi daemon:/opt/sbin/avahi-daemon:/bin/false" >> /tmp/etc/passwd
echo "audio:x:555:" >> /tmp/etc/group

# start dbus first before avahi
/opt/etc/init.d/S20dbus start

# start avahi-daemon
avahi-daemon -D

# start shairport 
shairport-sync -v

Woohoo! You should now be able to AirPlay music to your router! Look for an AirPlay device that says something like 'Shairport Sync on unknown', and send your music to it. (To change this name, edit the config file in /opt/etc/shairport-sync.conf )

If it didn't work, look at the output from the shairport-sync command for clues. You can also try running in verbose debug mode with:

shairport-sync -vv

Step 7: Make it work on startup

You'll probably want to enable shairport on router startup, so you don't have to manually go start the process each time. To do that, you'll need to copy/paste two scripts into your router. Look in USB & NAS > USB Support > Run after mounting.

Startup Script: Run after mounting:

# initial sleep for tomato to startup. unless I put this in, I get corrupt audio
sleep 30s

# load sound modules
insmod /opt/extras/soundcore
insmod /opt/extras/snd
insmod /opt/extras/snd-hwdep
insmod /opt/extras/snd-page-alloc
insmod /opt/extras/snd-timer
insmod /opt/extras/snd-pcm
insmod /opt/extras/snd-seq-device
insmod /opt/extras/snd-seq
insmod /opt/extras/snd-rawmidi
insmod /opt/extras/snd-seq-midi-event
insmod /opt/extras/snd-seq-midi
insmod /opt/extras/snd-mixer-oss
insmod /opt/extras/snd-pcm-oss
insmod /opt/extras/snd-usb-lib
insmod /opt/extras/snd-usb-audio
insmod /opt/extras/input-core
insmod /opt/extras/hid
insmod /opt/extras/usbhid

# create sound devices
/opt/src/alsa/alsa-driver-1.0.25/snddevices
alsactl init

# delete orphan pid files in case they exist
rm /opt/var/run/dbus.pid
rm /opt/var/run/avahi-daemon/pid

# required to start avahi-daemon
echo "nogroup:x:2:" >> /tmp/etc/group
echo "nogroup:x:2:2:avahi daemon:/opt/sbin/avahi-daemon:/bin/false" >> /tmp/etc/passwd
echo "audio:x:555:" >> /tmp/etc/group

# sleep before daemon startup
sleep 1s

# start dbus first before avahi
/opt/etc/init.d/S20dbus start

# sleep for 5s so dbus can startup
sleep 5s

# start avahi-daemon
avahi-daemon -D

# sleep for 3s so avahi can startup
sleep 3s

# start shairport as a daemon
shairport-sync -d

# done

Shutdown script (run after unmounting):

# run before umount

killall shairport-sync
avahi-daemon -k
/opt/etc/init.d/S20dbus stop

# done

Troubleshooting

If you have trouble, here are a couple tips.

Run shairport-sync in debug mode

The first thing to do is login to the router and run shairport-sync manually:

killall shairport-sync
shairport-sync -v     # (or -vv)

Look for errors, and then go forth and Google. :)

Check if you're broadcasting

avahi-browse allows you to see what you're broadcasting:

/opt/bin/avahi-browse -ar

Disable WMM in Tomato

If you get error messages like:

Buffers exhausted.
Buffers exhausted.
Error -- ALSA device in incorrect state (4) for play.
Lost sync with source for 4 consecutive packets -- flushing and resyncing. Error: 9368.
First packet is late! It should have played before now. Flushing 0.1 seconds
Buffers exhausted.
Buffers exhausted.

you might try disabling WMM in Tomato. (Advanced Settings → Wireless). WMM stands for Wifi Multimedia, and apparently implements some sort of QoS for multimedia data over wifi. I found it also interfered with shairport-sync; disabling it seemed to fix the problem with no other ill effects.

Discussion

test84.255.239.246, Feb 11, 2017 05:18 PM

Thank you very much for your detailed setup.
Everything went OK, only problem is in sound stuttering (sound interruption approximately every 5 sec). Do you have any additional tips for this problem?
I'm still on Tomato Firmware 1.28.0000 MIPSR2-123 K26 USB Big-VPN.

Thanks, Aleš

dordal, Mar 26, 2018 03:37 AM

Did you see the note above about disabling WMM in Tomato? I think that may be your problem.

test89.143.15.82, Apr 16, 2018 12:35 PM

Hi!

I've allready done that couple months ago. The stuttering has gone.

Thanks, Aleš

.

Enter your comment. Wiki syntax is allowed: