Sunday, August 28, 2011

Cassettepunk MP3 Player: How to do it

Hi all,

Here's a few words on how this hack (the second one, that is) was done. This is a reconstitution of some old notes I made during the process.

This focuses primarily on the software side -- the hardware side can be pieced together from the photographs, aside from the one hardware modification to add a second USB port to the WL-HDD device.

This post contains no pictures and a lot of grisly detail. You have been warned.

Starting Out

Let's assume you have a WL-HDD with a large hard disk installed in it. You've already performed the USB port modification, and attached two USB devices -- an audio device and a Bluetooth adapter.

It'll help to have the hard disk pre-partitioned and formatted with three partitions:

1. 128MB of swap memory
2. 128MB of ext2 or ext3 space for the system, in addition to the built-in flash
3. The rest formatted ext2 or ext3 for media

Flashing the WL-HDD with OpenWRT

I used the OpenWRT Linux distribution as a base. You can install this by downloading a supported release (I used Kamikaze) for the correct platform (Broadcom 47xx in this case) and flashing the device either through the administration web interface or using TFTP. There's a good guide here. ASUS devices are difficult to "brick" -- that is, to permanently destroy -- as its built-in bootloader has a failsafe mode that can be used to replace a defective firmware with a working one.

Following the OpenWRT installation documentation should get you to a point where you can connect to the device with secure shell and get a prompt.

The first thing to do here is change your password using the passwd command.

Getting the Base System Working

OpenWRT contains a pretty good miniature package manager called "ipkg", and a diverse set of packages to choose from. One trick with the WL-HDD in particular is that it has a relatively small amount of flash memory to store the base system in -- but fortunately it's attached to an enormous disk for MP3 storage, so you can grab a little of the hard disk space to store some of the extra parts of the system too.

Let's begin by installing the modules that are necessary to access the hard disk. Since OpenWRT is designed to take as little space as possible, these aren't built in, so we'll have to use some of the precious flash space to install them.

I didn't connect my WL-HDD directly to the local network -- I attached it directly to my laptop and had the laptop serve as a proxy to my home wireless network. If that's the case for you, you'll have to make sure OpenWRT knows about the proxy server so that it can access the Internet to download additional packages. If so, edit /etc/ipkg.conf and add option http_proxy (or similar) to your configuration. In this case, my laptop's IP was and the proxy server was running on port 8888.

Update ipkg's list of packages using:

ipkg update

Now, if that's working, it's time to install a few packages:

ipkg install kmod-usb-ohci kmod-ide-pdc202xx kmod-ide-core
ipkg install kmod-usb-ohci kmod-usb-uhci
ipkg install kmod-fs-ext2 kmod-fs-ext3
ipkg install kmod-usb-audio

As you can see, those add kernel support for a few things -- IDE storage, USB and USB audio, and a couple of filesystems we'll be using.

Now let's install the MPD music daemon and a few things it requires:

ipkg install mpd
ipkg install madplay

It's time for a little bit of configuration; edit /etc/config/system and set the hostname to something clever. Remove the /etc/rc.d/S45firewall script as we won't be using this as a router and OpenWRT is a little restrictive by default.

Make a /mnt/music directory to use for your music storage. Edit /etc/mpd.conf to configure it to look for music there. (It'll also want to work with a log and error file; I directed those to /tmp, since I wanted my hard drive to mount read-only to encourage power savings by spinning the drive down and decrease the chance of data loss due to me switching the thing off at an inopportune moment.)

I created a few startup scripts to help the system get on its feet by mounting the appropriate filesystems. For example, /etc/init.d/fsmount:
#!/bin/sh /etc/rc.common
# Copyright (C) 2006
# Copyright (C) 2007 Alec Smecher

start() {
        mount /dev/ide/host0/bus0/target0/lun0/part3 /mnt/music -t ext3 -o ro

stop() {
        umount /mnt/music
I did a few others to take care of cute things like a startup sound. These should also by symlinked into e.g. /etc/rc.d/S65fsmount -- this is where OpenWRT will look for scripts to run in sequence during startup.

We're getting a little ahead of ourselves here -- since we've only just installed the modules to read the hard drive, we'll need to restart the device to get it to actually load them and find the hardware there.


When you come up again you should have IDE support courtesy of the modules you installed previously. If the fsmount script I described above is installed correctly, you should have /mnt/music mounted for your media storage.

Now we need to make room for more packages but the flash is probably getting pretty full. To do this, let's move the contents of /usr/lib onto the first IDE partition.

mount /dev/ide/host0/bus0/target0/lun0/part1 /mnt -t ext2
mv /usr/lib/* /mnt
umount /tmp
mount /dev/ide/host0/bus0/target0/lun0/part1 /usr/lib -t ext2

If that went well, you'll want to add that last mount statement to your fsmount script so that it's mounted on boot. You might want to reboot the machine here to make sure everything is going according to plan.

Now there's a bit more space to play with, so let's install more packages:

ipkg install swap-utils
/usr/sbin/swapon /dev/ide/host0/bus0/target0/lun0/part2

This will give you swap space to increase the effective amount of memory, since that's also pretty limited on this device. You'll also want to add that last statement to your fsmount script. Once again, reboot and test.

Great! Now this little device can reach enough storage to pretend that it's much more capable. Let's keep installing the packages we're going to need for the Bluetooth remote control part of the job. (Note that we remount the /usr/lib partition read-write, as it'll typically be read-only. This is important to remember when installing packages henceforth.)

mount /usr/lib -o remount,rw
ipkg install kmod-bluetooth
ipkg install bluez-libs bluez-utils
ipkg install usbutils
ipkg install mpc
mount /usr/lib -o remount,ro

Reboot once again to bring up bluetooth support via that USB dongle you've got hanging off the end of the device. There's some configuration to do: edit /etc/config/bluetooth to enable services; ln -s /etc/init.d/bluez-utils S69bluez-utils to get the bluetooth tools to start automatically; edit /etc/bluetooth/givepin to set the PIN code; edit /etc/bluetooth/rfcomm.conf to specify the address of the cell phone or remote control device you'll be working with. I'm not particularly pro with Bluetooth -- in fact, this project is the only thing I've ever used it for -- so forgive me if this part of the equation is a little muddy.

Reboot again to clear the slate for the next bit of work. By this point you should have a working device with MPD installed; you can try connecting to it from another machine via the network and playing some music while you ponder the next step.

The Remote Control

The remote control for this hack consists of a crappy old cell phone that's capable of running a J2ME (Java 2 Mobile Edition) application. This is a very simple application that connects via Bluetooth to a C program running on the WL-HDD; the C program listens for button presses from the cell phone via a Bluetooth serial connection, and translates those buttons into commands for the MPD server using the "MPC" command-line tool. It also feeds song names back to the cell phone.

Here is where I would love to post two pieces of source code: one, the C code for the remote control daemon that runs on the WL-HDD, and second, the Java code that runs on the cell phone. There is a fair chance that I've lost both in the intervening three years -- however I do have an old hard disk lying around that's likely to contain both. I'll make an attempt in the coming few weeks to dig it out -- and this is as good a time as any to leave off for the moment.

To Be Continued...

No comments:

Post a Comment

Note: Only a member of this blog may post a comment.