Prologue

It's a problem many of us are familiar with. We have an extensive
music library on our computers and iPods/portable music players, and we
would like to listen to it at home, but our computers are too far from the
stereo, or the rest of the family wants to listen to music while you go
out with your iPod. Or perhaps you'd like to listen to Shoutcast radio
stations on your stereo at home (something portable music players are
at the moment largely incapable of).

These are all very sensible reasons for wanting a networked music player.
Now many companies have products for sale that fill this need, but this
page is not
aboutbuyingthings.
This page is about hacking a do-it-yourself wireless networked music player
for less than half the cost of a retail model, and with (potentially) more
features.

The Mission

When I began this project, I knew I could not settle for anything less than:

A small, low-power networked music player, which

Runs Linux, and

Can connect either wirelessly or wiredly, that

Supports MP3, OGG, and FLAC at a minimum, and

Accepts commands remotely from a PC or PDA, in addition to

Displaying song info such as Artist/Title on a display local to the device.

Leveraging an old PC for the task was out of the question, as I had no
spare PCs to toy with, and in general PCs are loud power hogs if you aren't
buying specifically for quietude and power economy (and that drives the
prices up).

Once again I turn to an old friend of an operating system, OpenWrt, only this
time on a new hardware platform, the excellent Netgear WGT634U. Unfortunately
Netgear has discontinued this router because of the flaky software they wrote
for it (or other business reasons). Luckily this means that refurbished
WGT634U units go for about $40 (or they did, until supply ran out just a few days
before this article was published). (UPDATE:Justdeals.com
seems to get them in and out of stock sometimes) What's so great about these routers is
that they have a USB 2.0 port on the back, allowing connection of any number
of accessories, the most important of which in this case is the generic USB audio
device.

USB audio

I wanted the best audio quality for my dollar. So naturally, I headed over
to eBay
and found the cheapest USB audio adapter
I could find. (As a side comment, don't be afraid of eBay for the cheap
sub-$50 stuff. No one scams you for such small amounts of money.)
Fortunately USB audio devices are standardized, so pretty much
every USB audio device you can get your hands on should work great with the
Advanced Linux Sound Architecture (ALSA). The little green one I got ended up
having a C-Media chipset, and actually has excellent sound quality. In order
to hear the background noise typical of a desktop computer system, I have to
set the volume down to 5 (out of 100) and use my in-ear headphones. It
might also help that the Netgear router's power supply doesn't have things
like clicking hard drives to inject noise into it. I'm quite satisfied with
this little green adapter - despite the garish color its sound quality and price ($8) are superb.

The LCD song display

I had wanted to play with LCDs for a while now, but I had never really
done in-depth searching for a cheap serial-based LCD module. $40 and up
was just too much to pay. But for this project I really wanted to have
the music player display its current song and artist information. I
remembered that electronics kits are always cheaper than their prebuilt
counterparts. So I fired up the good ol' eBay search again (for
"serial lcd kit") and lo
and behold, a kit from Hong Kong for about $12. If you're afraid you'll
screw it up (like I did at first), you might want to go with
non-kit LCDs.
Note that the kit I bought ("Serial 1 pin LCD Ready Kit for Basic Stamp, ATMEL, PIC")
only included a perfboard, a bag of parts, and a schematic.
This would perhaps
be too advanced for a beginner kit builder.

The visibility on the little display is great. The backlight is very bright
and the display is trans-reflective, so it's viewable even in direct sunlight
and so on.

Here I've loosely affixed the LCD to the router with a large rubber band
(though I could easily have used magnets)
for a simple, easy, non-permanent bond.
The firmware inside the Atmel chip provided with the kit provides
a very simple interface - there are numbered commands that can be entered
even with a keyboard (for example, "1 [enter]" means clear the display). A
couple simple shell scripts provided a quick interface to the LCD:

The speakers

While not a necessary part of this project, I figured I'd mention the
speakers I'm using. These are
Virgin Boomtube
speakers which I got off of Woot for something like $20. They are of course
no longer available through Woot but eBay has a few.

These speakers have excellent sound quality. The internal bass boost really
makes the small speakers kick, and the fact that you can pop 4 AA batteries
in the center unit and take the speakers anywhere is just plain awesome.

They are, of course, no replacement for a large 5.1 surround setup in your home.
If you want true big sound, that's definitely the way to go.

Hackin' it up

While the connection for the USB audio adapter is obvious (for the slower
among you, it goes into the USB port in the back of the router), the serial
LCD takes a little more finesse. Next to the serial console port on the
WGT634U, there is a headerless second serial port to which the LCD must be
attached.

For power, I piggybacked the LCD power supply onto the USB port supply
which is always at 5 volts. The LCD draws about 120mA with backlight on
(20mA without), but the WGT634U doesn't mind and has no trouble powering
both the USB audio adapter and the LCD at once. Here the wires are running
down below the circuit board and are soldered to the pins on the USB connector.

The software

What good is a great hardware hack without software to back it up?
Well, it's still great, but it's even better with good software.

Enter OpenWrt, the fabulicious Linux
distribution designed to run on Broadcom-based routers. The latest version,
codenamed Kamikaze, is as yet unreleased and still considered unstable,
however the build I'm running (r3186) is working superbly. For USB-audio
support, make sure to build the kmod-usb-core, kmod-usb-ohci, kmod-alsa,
and kmod-soundcore kernel modules (see below for other modules you'll need),
as well as mpd, the music player daemon.
Watch out for kmod-usb-ehci - it adds USB2 support but can get buggy when
you're trying to run the USB audio device through a USB hub.

The Music Player Daemon

Software for this hack relies extensively on the excellent music player
package, mpd. It runs as a server
which accepts commands that manipulate and play playlists. With a great
many command-line, GUI, and web-based clients, mpd is sure to meet your
remote playability needs. I was thinking about creating an AJAXy frontend
for mpd to run on the router (since PHP is too heavyweight for such a tiny
router), and I might still do it in the future.

A few useful scripts

Creating the scripts for the Mobile Wi-Fi Access Point
really gave me a chance to hone my shell scripting skills. And while I can't
say I'm one of the bash elite (hell, I'm far from it), it is quite easy for
me now to create small useful scripts. In addition to the three scripts for
initializing/displaying/singing on the LCD display, I've made a few others:

The command interface

This one sends a single command to mpd and waits for a reply. It's much
much simpler than any of the clients listed at musicpd.org and suits my
purposes just fine. Thanks to Stefano Cazzulani for his connection-closing fix.

Remote filesystem mounting

Used to mount the remote filesystem and prepare for mpd loading. It also loads mpd.

File: /usr/sbin/gompd rwx
#!/bin/sh
#Usage: gompd (computer IP address)
# You must edit this file to work with your remote filesystem.
# In this configuration, gompd will connect to the share called
# mp3 on the specified computer, with the username "Nate True".
# It will ask for a password upon connect, if required.
# CIFS is the file system used to access Windows shares.
mkdir /tmp/.mpd
mkdir /tmp/music
mount.cifs //$1/mp3 /tmp/music -o "user=Nate True"
#This line reduces latency for pause and setvol commands
echo mpd 5 16384 > /proc/asound/card0/pcm0p/oss
mpd

Conclusion

This was a really fun project. I especially like the one-word radio tuning,
because it makes it so easy to explore new music categories. I discovered
how motivating European Trance music can be, and how fun Hindi music is to
listen to.

Be sure to check out some of my other projects below, and a big thanks
to
HostGator for helping me survive such huge surges in traffic.

Where to go from here

OpenWrt.org - The operating system behind this hack. Linux? On a $30 router? Who could resist?

Make My Day DVD - A choose-your-own-adventure DVD that I had a hand in making.

Hidden Frame Productions - My production company, along with two of my closest friends. It's a garish flash site for now, until I update it.