LABEL=bean-root / ext3 defaults,noatime,errors=remount-ro 0 1
This article describes how I built an audio server for home use. The system allows me to play MP3 files on any connected speakers. I can control (play, stop, next, prev, modify playlist, control volume) the system wirelessly from my GNU/Linux laptop, a Windows laptop, a Mac laptop and even from my Bluetooth enabled mobile phone running a Bemused client.
Created by Simon Josefsson on 2007-09-25. If you want to comment on this, please go to the blog entry.
The hardware I used is not that important. The software is flexible and works with many different combinations of hardware. However, as it helps to make things concrete, here is my setup:
Linksys NSLU2
Zalman 5.1 USB sound card (USB ID 0c45:17cf)
Sweex USB hub
Sweex bluetooth USB adapter (USB ID 0a12:0001)
2GB USB memory stick (USB ID 054c:0243)
The NSLU2 is connected to my wireless base station, and is thus reachable within my home network.
The wiring may be a bit unpolished, but hey, it works.
I followed the instructions on Martin Michlmayr's Debian on NSLU2 page.
I used a 2GB USB memory stick as the root file system. To minimize file system writes to it, I added the noatime file system parameter to /etc/fstab:
LABEL=bean-root / ext3 defaults,noatime,errors=remount-ro 0 1
Another trick is to avoid having syslog write periodic markers to the syslog file. I modified /etc/default/syslogd to have syslogd start with the -m 0 parameter.
SYSLOGD="-m 0"
A trick to find out which processes is writing to your file system is to run the following:
echo 1 > /proc/sys/vm/block_dump
The kernel will dump file systems operations, and you can look at them by running
dmesg | grep dirtied
I have swap set up on the USB memory stick, and this is by far the biggest reason for write operations. I know it may be a bad idea to swap to a USB memory stick, but they are cheap, and I want to find out if there really is any truth to it.
I was lucky with the sound card, the first one I bought worked fine directly out of the box with GNU/Linux and on the NSLU2. I'm not particulary happy with the physical design of the Zalman USB sound card, since the analog audio connector seems to be of rather poor quality. Hopefully the digital output works better.
To simplify integration of the server in my network, I'm using Avahi. This allows me to use bean.local as the server name instead of the raw IP address. (The audio server hostname is bean.)
apt-get install avahi-daemon
It doesn't seem to need any configuration. Neat!
The Music Player Daemon was my first choice as server system. I did look at some others, like XMMS2 and Gmediaserver, but none appeared to have the same amount of cross-platform clients available. I installed it as follows:
apt-get install mpd
MPD is configured via /etc/mpd.conf. MPD uses a database of the MP3 files, and you build it using mpd —create-db. The details are below.
At home my MP3 archive is stored on a bigger server and exported via NFS. I added the following to /etc/fstab:
dopio.local:/mp3 /var/lib/mpd/music/ nfs defaults,ro 0 0
MPD needs to have a database with the files. To avoid having to trash the USB memory stick, the network, and the NFS server when building the MPD database, I ran mpd —create-db on the NFS server (with the appropriate mount points set up temporarily) and then moved the MPD database into a hidden top-level sub-directory .mpd within the MP3 tree. To make MPD find it, I created a symbolic link on the system:
lrwxrwxrwx 1 root root 20 Sep 25 17:45 /var/lib/mpd/tag_cache -> music/.mpd/tag_cache
I could have modified /etc/mpd.conf as well, but I chose not to.
At the summer house my MP3 archive is stored on a portable device (the Jobo Giga Vu Pro Evolution).
To make it mount automatically when I connect the device to the NSLU2, I installed hal:
apt-get install hal
I added a udev rule to invoke mount -a whenever a SCSI device is loaded, saved as /etc/udev/rules.d/z99_mount.rules:
KERNEL=="sd[a-z]*", RUN+="/bin/mount -a"
Then I added the following to /etc/fstab:
/dev/disk/by-label/gigavu /giga vfat defaults,auto,ro 0 0
Finally, set up MPD to use data on the device, create the following symlinks:
lrwxrwxrwx 1 root root 20 Sep 25 17:45 /var/lib/mpd/tag_cache -> music/.mpd/tag_cache lrwxrwxrwx 1 root root 15 Sep 25 19:34 /var/lib/mpd/music -> /giga/pc/Music/
As before, I store the MPD database on the device itself, in the .mtd sub-directory. Since this is a locally connected device, I run mtd —create-db on the device whenever I add/remove MP3's.
On my laptop, I use the Gnome Music Player Client. It is fast and works well, and there are Debian packages for it.
apt-get install gmpc
Right now I'm using the Windows port of GMPC, but it is not working very well: it doesn't remember the server settings between invocations. It is not high priority for me, and the problem will hopefully be solved in the future.
Theremin is a Mac OS X MPD client,
This is mostly for nerd points.
First install Bluetooth on your audio server:
apt-get install bluetooth
Then you need to install the bemused - mpd bridge.
apt-get install mpd python-mpdclient python-bluez unzip wget http://arton.cunst.net/mpd/pbmpcd-20070813.zip unzip pbmpcd-20070813.zip cp pbmpcd/pbmpcd.py /usr/local/bin/pbmpcd
Start the server manually to test that it is working properly:
bean:~# /usr/local/bin/pbmpcd MPD connected at localhost:6600. Waiting for connection on RFCOMM channel 1
To be able to discover the device, you must tell the bluetooth stack to be in the discoverable mode:
dbus-send --system --type=method_call --print-reply --dest=org.bluez /org/bluez/hci0 org.bluez.Adapter.SetMode string:discoverable
Simple, huh? Anyway, to check your current status, use:
# dbus-send --system --type=method_call --print-reply --dest=org.bluez /org/bluez/hci0 org.bluez.Adapter.GetMode method return sender=:1.2 -> dest=:1.6 string "connectable"
It reverts back to connectable from discoverable after some time.
Install a bemused client on your phone. I'm using the nice client that comes with pbmpcd. There is Java source code available (even under the GPL). You need to install it into your mobile phone somehow. Since I have set up mail on my phone, I find the simplest is the e-mail myself the URL to where the bemused.jad file can be found, and then click on it in the mail reader. Your phone should install it.
To save you the trouble of transfering the Bemused client to a web server, you could use the following URL:
http://josefsson.org/grisslan/bemused/
Click on Bemused.jad to install the client.
Once you have installed the bemused client, start the client and chose your bluetooth card (don't forget to put the card in discoverable mode again). The server should print:
Accepted connection from 00:12:34:56:78:9A ...
You should be able to control the server using the numeric keypad to select play, stop, next, pause, volume, etc.
Coming up next…
That's it!