A collection of thoughts, ramblings and experience of making technology work for me. It may include some further diversions.

Airplay to Squeezebox Touch (via Linux)

This post focuses on playing music from iTunes or iOS devices to a Logitech Squeezebox using AirPlay. The concept is to stream music from iTunes or iOS devices > Ubuntu server > Squeezebox. This requires three key tools Shairport, WaveInput, ecasound and some patience.Shairport authored by James Laird in 2011 emulates an AirPort Express for the purpose of streaming music from iTunes and compatible iPods. It implements a server for the Apple RAOP protocol, it does not support AirPlay v2 (video and photo streaming). It is a reverse engineer of the RAOP protocol and relies upon the ALAC decoder released by David Hammerton, which is reproduced within Shairport. The project can be found at https://github.com/albertz/shairportWaveInput authored by BPA is a Logitech Squeezebox plugin that enables PC audio to be captured and played through a Squeezebox. There are version of Windows and Linux and the project can be found here http://code.google.com/p/bpaplugins/ecasound is a multitrack processing tool for playback, recording, format conversions, effects and mixing. Its use here is to transcode the raw stream from Airplay/Shairport into a format the Squeezebox can understand. I use it to introduce some LAME MP3 compression to the stream to help with my network bandwidth and to reduce playback stutter.

This article relies heavily upon the excellent work of Stuart Shelton and this post on the Logitech forums. There are two main methods for transferring the sound from shairport to the squeezebox:The first relies upon piping the shairport stream to a raw data pipe which is then encoded to the Logitech Media server; andThe second uses a loopback device whereby shairport outputs audio to a loopback device which then feeds into the encoder for Logitech media server.I'll discuss both methods here but will start with the raw pipe method since it is a lot easier to set up (although I am experiencing some performance issues with this approach on my Atom based server.Shairplay to Raw pipe approachThe flow of music is:
iTunes / iOS
> via Airplay
> Shairport on Ubuntu
> raw date pipe
> ecasound on Ubuntu (to transcode the raw Airplay stream to compressed FLAC, MP3 or raw PCM)
> PCM stream (my server was not powerful enough for real time FLAC / MP3 encoding)
> WaveInput plugin on the Logitech Media Server (running on Ubuntu)
> via wi-fi or ethernet
> Squeezebox
> speakers

I hope the above helps someone, it certainly helped me.

Note Shairport requires that Bonjour / Avahi service that advertises the Airplay service to iTunes / the iOS device is already setup and configured on your Ubuntu server. It was already configured on my server from a previous effort at setting up an Apple Time Machine server you can read about setting up Avahi here from post 6 onwards. I won't be setting up Avahi in this post.

14. Restart Logitech Media Serversudo /etc/init.d/logitechmediaserver restart15. Add the squeezeboxserver to the audio user group, this can be helpful for debugging the configsudo usermod -a -G audio squeezeboxserver16. Start the Shairport server:sudo -u squeezeboxserver perl shairport.pl -v -a "Squeezebox Airplay" --pipe=/var/lib/squeezeboxserver/airplay-fifo.raw17. On iTunes or iOS select the "Squeezebox Airplay" option and start playing your music.If you cannot connect it is likely a firewall issue try disabling the firewall for debugging with sudo ufw disable - don't forget to re-enable it and don't do this if you connect direct to the internet without a router inbetween you and the internet.18. In the Shairport terminal window you should see activity as the music stream is received, it's usual to see lots of errors since you are streaming most likely over wi-fi there are bound to be sync errors, such as:"requesting resend on 1 packets""Suspected resync request packet received. Initiating resync.""missing frame" etc.Ignore them!19. On LMS or the Squeezebox start playing the "Squeezebox Airplay" favourite after a couple of seconds you should have audio from your Squeezebox.20. By default Shairport will stream FLAC to the Squeezebox, unfortunately my Ubuntu server doesn't seem to have the power (Atom D330) to encode the Airplay stream to FLAC for the Squeezebox on the fly in real time. This results in a very choppy sound experience with my audio playing for a couple of seconds then drops out for 30sec to a couple of minutes before playing another couple of seconds and the cycle repeats. I isolated this by testing the Squeezebox on wired ethernet so the only bottleneck could be the Ubuntu server. To combat this I disabled both FLAC and MP3 streams on the Squeezebox and used the raw PCM signal which does not require the Airplay stream to be transcoded.Disable the FLAC and MP3 streams via LMS > Settings > Advanced > File Types > WavInput and set both eacsound/FLAC and eacsound/MP3 to disabled. Note do not touch WAV or Wavpack they are unrelated. 21. Restart LMS for the change to take affect sudo /etc/init.d/logitechmediaserver restartAnd start the Squeezebox playing back the "Airplay Squeezebox favourite"This lead to a stable stream to my Squeezbeox using wired ethernet. Note it takes around 1 minute for the stream to settle down after play is hit on the Squeezebox there is some buffering/stuttering in the first 1 minute or so. It's also worth noting , the stream also has around a 30 second delay from the Airplay source.22. Once I swapped back to w-fi I was plagued with choppy playback again. The only cause for this can be that my 54g wireless network does not have the bandwidth to both receive the Airplay music over wi-fi and stream it back to the Squeezebox over wi-fi. To combat this enabled the MP3 stream on the Squeezebox which takes preference over PCM. Enable MP3 via LMS > Settings > Advanced > File Types > WavInput and set eacsound/MP3 to enabled. Again note not to touch WAV or Wavpack.23. Restart LMS for the change to take affect sudo /etc/init.d/logitechmediaserver restartAnd start the Squeezebox playing back the "Airplay Squeezebox favourite". Once again this lead to the a stable stream to my Squeezbeox with the same caveat that it takes around 1 minute for the stream to settle down after hitting play, there is still some buffering/stuttering in the first 1 minute or so; and the stream still has around a 30 second delay from the Airplay source.Troubleshooting ideas1. IPv6 If you experience issues try disabling IPv6 this did not effect me but to disable it edit /etc/sysctl.conf and add the following lines:net.ipv6.conf.all.disable_ipv6 = 1net.ipv6.conf.default.disable_ipv6 = 1net.ipv6.conf.lo.disable_ipv6 = 12. Test shairport: Test the shairport connection to the Ubuntu server, this helps to isolate ecasound and the Squeezebox from the equation. Turn on your speakers and check they work by playing an audio file locally from Banshee or Rhythmbox or alike. Then fire up shairport using the command belw to output to alsa. This should give you sound once you play the Airplay source to shairport - if not you have problems with shairport.sudo perl shairport.pl -v -a "Squeezebox Airplay" --ao_driver alsa

3. Test the pipe and ecasound: Ecasound transcodes the raw Airplay stream to FLAC, MP3 or PCM for the Squeezebox. The format used depends on the filetype enabled in the LMS settings. To test that the pipe is accessible (i.e. not a privilege issue) and that ecasound is working you can ask ecasound to output to the Ubuntu server's alsa interface to check for audio. Again test your Ubuntu servers speakers are working first with Rythmbox or Banshee or alike. Note your hardware interface may not be 0:1, I tried several combinations before I hit on the right interface.

If you don't have sound on the server you can pipe the signal to xxd, whereby you should see the signal as an ascii stream in the terminal. If nothing is moving and there's no activity then there's a problem with the pipe (check the permissions) or ecasound.

sudo xxd /var/lib/squeezeboxserver/airplay-fifo.raw

Shairplay to ALSA loopback approachIn my experience, this approach leads to a much lower latency/delay from source to speaker. It requires the ALSA loopback device, I discuss setting up the ALSA loopback device here.

Loopback describes ways of routing electronic signals / digital data streams from their originating facility back to the source without intentional processing or modification. This is primarily a means of testing the transmission. It is used here to loop the sound from Shairplay into the Logitech Media Server via and encoder.

The flow of music under this approach is:iTunes / iOS> via Airplay> Shairport on Ubuntu> ALSA loopback device input> ALSA loopback device output> ecasound on Ubuntu (to transcode the raw Airplay stream to compressed FLAC, MP3 or raw PCM)> PCM stream (the lame MP3 stream using this approach is noisy and PCM performs well- note you can easily swap between them)> WaveInput plugin on the Logitech Media Server (running on Ubuntu)> via wi-fi or ethernet> Squeezebox> speakersCreate the alsa loopback deviceSee here.There are now two options of encoder you can use:arecord: which I found easier to set up but has issues related to the amount of data it can encode leading to the stream cutting out after 2-3 hours; orecasound: which should perform better as it introduces a buffer.

Running with an alsa loopback device using arecord

The loopback input used by shairport is hw:Loopback,0 or for me hw:2,0The loopback output fed to arecord is hw:Loopback,1 orfor me hw:2,1

Notes:1. Attenuation (i.e. eadb) to reduce the stream volume in the custom-convert.conf does not appear to work on the pcm stream.2. ecasound can be debugged to error log by adding -D -dd "$@" 2>/tmp/ecasound.log to the ecasound commands in the custom-convert.conf. The error log can then be read with sudo tail -f -n 20 /tmp/ecasound.log3. I have some hiss on the ecasound and arecord streams when using the loopback approach and lame. This is despite all other pulse and alsa input interfaces being muted. When the music stream is stopped on shairplay the hiss disappears and attenuation makes no difference. When using the raw pipe approach with lame there is no hiss at all the downside is the huge delay I am experiencing of c. 30 seconds when using the pipe. Now that I have all the options working I'll see if I can improve the latency on the pipe.4. The lame compression used in conjunction with the loopback appraoch appears to be introducing the hiss since the pcm stream is clean with no hiss at all that I can discern. The pcm stream also only has a 6 second delay.SummaryMy Atom D330 server with Ubuntu 10.04 can send Airplay to the Squeezebox Touch as follows:- via alsa loopback with ecasound to lame on the fly but this seems to introduce noise and a 8 second delay- via alsa loopback with ecasound to pcm on the fly without noise and a 6 second delay- via raw pipe with ecasound to lame on the fly without noise and a 30 second delayIt cannot:- under my Ubuntu 10.04 setup to convert to FLAC on the fly via alsa loopback or the pipe (CPU not powerful enough?!)- pass the raw pipe to the squeezebox via PCM, this leads to huge delays and lots of stuttering. I thought this was bandwidth related but it cannot be if the pcm stream plays using the alsaloop back mechanism.This is tested with iTunes and iOS on an iPhone 3GS. So for the time being I will be sticking with alsa loopback, ecasound and pcm until I can reduce the delay on the pipe.

Outstanding- Set up Shairplay as a service with stop and start commands to run at boot.- Reduce the delay on the raw pipe.

21 comments:

I came across your instructions above and have almost an identical set-up (Ubuntu 12.04). Everything seems to have worked, but I'm not hearing any sound from my player: my iPhone recognized and sent audio to the LMS and I saw normal messages at the CLI.

I think my problem is to do with the LMS plugin. With the favourite I created, when I click on the associated "Play" button, nothing appears to happen.

Can I ask what happens when you click on the "Play" button of the web interface?

I've posted the output of the LMS log here: http://forums.slimdevices.com/showthread.php?49584-Announce-WaveInput-for-Linux&p=717487&viewfull=1#post717487

Glad to hear that. Sadly I haven't had the opportunity to work on a service script yet. Stuarts blog has a sevice script but it doesn't work as is on Ubuntu it may help. If you crack it I'd gladly test and host a script. Unfortunately my shairplay seems to conflict with my airport express on the same network which I need to sort first before I refine the shairplay service.

Frustrating. I'm running Ubuntu Server 12.04. There were some updates yesterday including Linux headers etc. After updating, I'm no longer able to connect my iDevices--when I attempt to, I get the following error from Shairport before it crashes:

Odd number of elements in hash assignment at /usr/bin/shairport.pl line 636.Use of uninitialized value in subroutine entry at /usr/bin/shairport.pl line 637.no AESIV at /usr/bin/shairport.pl line 637.

Well that's embarassing... your comment twigged me to the fact that it is actually iOS6 that has broken Shairport and not any Ubuntu package upgrades (confirmed on another iDevice that hasn't yet upgraded to iOS6).

I'm using the exact command line you provided above... no MAC specified.

On my RPi when trying this under either method I experienced unusable lag, I don't think the RPi has enough grunt to do this. That set up was using the RPi as a client only and not using it as a server.

Awesome stuff you've blogged about here. I consider myself the lucky owner of SB Touch but am now falling in love with the simplicity and elegance of Plex. So my dream is to combine the best of both worlds and make my SB Touch a valid player for Plex. I'm hoping to be able to use your instructions for this (since Plex can use AirPlay targets), but my SB server is running 14.04 and is virtualized. Will this make a lot of difference?