Here it is


What is it?

A small wireless battery powered device. Turn it on near a friendly wireless network that contains iTunes shares and plug your headphones in. It picks a random iTunes share, picks a random tune and starts playing. Repeat until bored or the batteries are dead.

How does it work?

This is my first little project working with gumstix. We've got a connex 400 with cfstix, sandisk wi-fi card (with 128MB memory) and an audiostix. I wrote some software in C using the libopendaap library. My C isn't great, so the code started off mostly as a copy + paste of parts of daap.c in the tunesbrowser project.

The size of the system is amazing. The main board is about the size of my little finger. By default it's running an ssh server, a web server and advertising itself to the network with bonjour.

It's pretty forgiving about its power supply. People on the mailing list have had 6 hours gumstix life out of 3 AAA batteries, but I figured the wi-fi will eat power, so I made my battery pack by sellotaping 3 D cells together

The code is aimed at the gumstix, so there's no user interface and it might try and do strange things with GPIO lines, but it should work on any linux box with libopendaap installed.

The code first sets up a daap client with DAAP_Client_Create. We supply a callback that gets used when the daap status changes. Initially we can't see any hosts, so we loop doing nothing. DAAP_StatusCB is called with a status of DAAP_STATUS_hostchanged once the client actually sees some hosts advertising iTunes libraries. We build up a list of these in cb_hosts_updated. Now that main loop is no longer idle, play_random_file is called. We pick a random host from clientHosts - the list we built up earlier. We attempt to DAAP_ClientHost_Connect to this random host, and update the list of available databases and songs. There's some stupidity in trying to find an MP3 to play, in future we'll be able to play more formats. We call DAAP_ClientHost_AsyncGetAudioFile and ask another thread to download the file and send it to STDOUT - libopendaap has it's own http code for this. We set a flag to indicate we're downloading something. We head off back to the main idle loop. When we're done downloading the status callback fires again, this time with a status of DAAP_STATUS_idle. We use reset the status flag to idle, which causes the main loop to fire off another call to play_random_file. And so it goes

Why do this?

I wanted a little project to get myself familiar with the gumstix. I'm a perl programmer by trade, but gumstix didn't have any of the XM platforms when we ordered, so our gumstix only has 4M of space on the root filesystem. You can fit a perl interpreter in that, but it becomes a tight squeeze to fit libraries in, and perl likes libraries. It's a similar squeeze for python etc. So, C it was.

This is just a little play, it's not that serious. Those batteries are huge, the code will probably not stay up for more than 5 minutes, and if it does, it'll probably leak like an old bucket.

What's next?

Make it faster. Hook up a button to skip bad tunes. Make it play more than just mp3s. Change the way the audio is sent to the player app (currently we get the file and send to STDOUT, then pipe it into madplay)

Can I download things?

Download the sourcecode here. There isn't an autoconf or makefile or anything fancy like that I'm afraid.

You'll need the libopendaap libraries installed.

If you're on the gumstix platform, download binaries here. Includes a binary of the shared libopendaap libraries. I use a dodgy initscript that doesn't background, but you can work better than that out I'm sure.

Have fun!