Tuesday, October 11, 2011

Stream Audio to Airport Express from Ubuntu...


Some time ago I posted here about how to stream sound from a Mac to an Airport Express router, but lately I've moved to working in Ubuntu Linux, so I needed to tweak my procedure...

At some point this whole mess will be obsolete, because there already exists a PulseAudio module implementing the RAOP as a sound device, so you can direct sound from your system as a whole or an application out to your airport express... however, so far, on my installation (Ubuntu 11.04 and lately 11.10 beta) it's buggy and doesn't work well at all for me.  I experimented with playing music from iTunes in a virtualbox installation of Win7, but, while it worked alright, the music would pause every minute or so - irritating... The setup I'm describing here works quite well for me...

I decided to try to set this up using much the same structure as I used for the mac hack, so I'm grabbing the sound feed from the machine and piping it into JustePort (running in mono since it's a .NET executable) which handles sending it to the airport express router.  This turned out to be pretty simple once I figured out what device to grab the sound from and how to spew it down the pipe (since Ubuntu isn't using ESD)...

What you need to do is grab the output channel monitor which you should be able to determine by looking at the results from:
pactl list | grep monitor
which will return some results which look something like:
Monitor Source: alsa_output.pci-0000_00_1b.0.analog-stereo.monitor
Name: alsa_output.pci-0000_00_1b.0.analog-stereo.monitor 
            device.class = "monitor"

Now, using parec, on the monitor device we just determined, we can send raw sound data wherever we need it like this...
parec -d alsa_output.pci-0000_00_1b.0.analog-stereo.monitor
which we can then pipe through JustePort.exe to the airport express. Like so:

parec -d alsa_output.pci-0000_00_1b.0.analog-stereo.monitor | mono ~/bin/JustePort.exe - 192.168.1.100 -0
  To break that down a bit...
parec -d alsa_output.pci-0000_00_1b.0.analog-stereo.monitor | mono path/to/JustePort.exe - 192.168.1.100 -0
reads the sound data from the monitor
pipe to send it to JustePort
runs JustPort using mono
input to JustePort is stdin (from the pipe)
IP of the airport express router
Volume in -dB - (I find this connection is quieter than the dvd player attached directly to the stereo, so I crank this all the way to 0 rather than allowing it to stay at the default of -30)

There are a couple of downsides to this technique...
  • there is a lot of latency (a couple of seconds at first, but it seems to grow over time, like the buffer is filled faster than it empties).
  • all sounds from the computer will be sent, not just your music - I'm sure this would be fixable by some more advanced work (I'd love to create a virtual device just for this purpose)
You'll gain some insight and on-board volume control through the use of  pavucontrol...

1 comment:

Unknown said...
This comment has been removed by a blog administrator.