Introduction

This page documents my home-brew MP3 player which demonstrates, if nothing else, that useful results can be achieved with an air-cooled processor programmed almost entirely in Java. (It also has the happy side-effects of managing my music collection and acting as a showcase for my computing experience.)

This project started life as a demonstrator for Rococo's JSR82 implementation for PalmOS, whereby a universal remote control program would be located via Bluetooth discovery and downloaded into a Palm to control a music server. (JSR82 defines the Java APIs for Bluetooth.)

Hardware

Software Infrastructure

This is software running on the box, not directly bound to the application.

Application Software

There are several parts to the application: the remote controls, the audio server and the management webapp. Their relationship to each other and their environment is depicted in the figure below.

The entities in its environment with which the player interacts are:

Elements in this diagram, apart from the webapp and server, which were developed by me are:

Acquisition

When a CD is placed in the CD-ROM drive, it is read by the autorip script, which stores WAV files and a freedb query in a temporary area.

When the autotag script is run later (it is CPU-intensive), it:

Remote Control

The client can run either on a standard J2SE VM or the Jeode Personal-Java-compliant VM (as shipped with the Sharp Zaurus, for example). It may use either TCP/IP or Bluetooth RFComm as transports. (The choice of transport is abstracted by the Java StreamConnection class.) Layered over this transport is a simple RMI mechanism for J2ME called Poor-man's RMI (see the September 2003 edition of Tech-Monthly for more information).

The client supports the standard operations of play, queue, pause, skip, pan, change volume, etc. In addition, during playback it can display current progress and the cover artwork of the current track, or the position in the current playlist. See the screenshots below.

The client was designed to be stateless in operation: a common use-case is where it is used to set up a playlist and then switched off to conserve power. When powered back on, it can be reconnected to the server to allow further tracks to be queued, the playlist edited, etc.

The Browser portion of the UI is constructed entirely by the server. The standard action is to navigate to a leaf entry and select it. If the leaf is a track, that track is played or queued to be played. If the leaf is a player setting, that setting is adopted by the server. See the figures below.

The server supports multiple clients and propagates state changes initiated by one to all of them. This allows, for instance, a TV-out signal to display the same information as the remote, presenting interesting possibilities for argument over choice of music.

Future work

A MIDP client is planned, to allow the server to be controlled by a JSR82-enabled phone, e.g., the Nokia 6600.

Serving Music

Audio is played back through the Java Sound API, javax.sound.sampled. The Service Provider Interface is Javazoom's MP3SPI (or VorbisSPI) and decoding is by its JLayer decoder.

Information on the currently playing track is displayed on an LCD screen (currently a Palm V running PalmORB) via LCDProc.

When a track has been played, audioscrobbler is notified of the fact, via a custom client interface, jscrobbler.

Hibernate controls access to the metadata generated by the player which is stored in the MySQL database. This currently comprises four tables which record: playlists, individual tracks, a cross-table mapping tracks to playlists, and a list of tracks which have been played but not submitted to audioscrobbler.

Spring abstracts the Hibernate O/R mapping and provides overall application configuration via dependency injection. (Retrofitting Spring to this application was remarkably easy: the bulk of the work was done in less than a day.)

Future work

While the architecture of the server has necessarily evolved, due to the time constraints on this project, it is moving towards an information bus down which events are propagated and whose observers are either local (e.g., the LCD display driver) or remote (the remote control). This is facilitated by the IoC container.

The most pressing current need is for a comprehensive testsuite in order to preserve developer-sanity. (The shortness of time available for this project does not allow sufficiently-thorough manual testing after each modification.)

Server Management

The management webapp supports the functionality which would be difficult to provide through the elementary Remote Control interface, which is, after all, intended to be used in a more casual environment. Currently this functionality comprises: Since some of this functionality might have an effect on a running server (for instance renaming a genre which has tracks queued for playback), the webapp can communicate relevant changes to it via RMI.

The technology used by the webapp is fairly standard for a J2EE front-end: Struts is used for the view and controller parts, and Tomcat as the servlet container. Some use is made of the Commons Beanutils API, because it was already available from Hibernate.

Other, system-management, concerns are addressed by Webmin.


Last updated: Tue Oct 4 22:43:39 IST 2005