Home Entertainment Linux MP3 Player

Here's a way to store your CDs and tapes away forever, while still enjoying the music.

Imagine lying back on your sofa in the
living room with your remote control unit. You press the channel
selection button, and a synthesized voice speaks out,
“Alternative”. You keep pressing the channel-up button and the
voice speaks out different music categories: “Children's”,
“Classical” and others. You chose the “Classical” category and
press ENTER on your remote control, and the
voice starts listing the albums in the same manner. You select
“John Williams, Spanish Guitar Music”, and the near CD-quality
guitar music starts playing.

No, the music is not playing off some CD changer, and the
synthesized voice is actually interactive, responding to your
remote controller actions. The music stored is your complete CD
collection, plus those old tapes (somehow still around), digitized
and compressed as MP3 files. The whole show is controlled and
played by a Linux server hidden in your closet, connected by an
audio cable to your home entertainment amplifier.

As soon as I realized the scenario described above is already
within our reach, I decided to code the missing pieces and somehow
glue it all together.

MouseREMOTE from X-10

The remote control unit is the central part of my design. The
controller I used, called “MouseREMOTE”, is part of the
“BigPicture” package that lets you transmit audio/video signals
from your computer remotely to your TV. Being a “control freak”,
I purchased the whole package some time ago and set up all the
house lights to be remotely controlled. The remote mouse is
especially useful, as it performs like any other controller for
audio/video components (it can also control X-10-based home
automation devices). In addition to every other button commonly
found on a universal remote, it has a rubber mouse pad on the face
and two buttons on the back of the unit. The controller sends RF
signals when its buttons are pressed to the receiver unit which,
when its buttons are pressed, has a regular computer mouse
pass-through, so you can still use your regular serial or PS/2
mouse. The remote-mouse software packets will be inserted in the
stream of packets sent by your regular computer mouse.
Unfortunately, the MouseRemote comes with only the MS Windows
software to assign actions to different keys. I installed a
high-quality audio cable from the Linux sound card line-out
connector in the server room down to the living room amplifier
unit's RCA input.

That was all I had to do on the hardware side. For software
support, I had to modify the mouse-server program to accept the
codes sent by the MouseRemote unit and pipe them to an MP3 player
program, which will perform different functions depending on the
remote-mouse selections.

I determined the MouseRemote specification by reading codes
using the modified gpm program.
MouseRemote is detected as a bare-mouse type, and it returns
packets of three bytes per event. Table 1 shows the codes returned
for the events. As you can see, almost all of the keys return some
code, giving this remote unit tremendous potential
versatility.

There are few peculiarities: mouse button codes (left/right
buttons located at the bottom of the controller unit) are
transmitted three times in a row. Only one button can be pressed at
a time; the other one is ignored while the first one is being
pressed. You can press and hold one mouse button and press any key.
If you hold down mouse buttons, the codes will not start repeating;
only mouse pad (mouse move) codes repeat with no apparent delay.
All other keys are repeating with a short delay of approximately
1/20 of a second.

The mouse movement pad detects three levels of pressure that
can be used by the mouse driver software to accelerate movement.
These levels set bits 0, 1 and 2 of the second and third byte in
the mouse packet. Those bytes are used to determine the difference
in movement between two consecutive packets, so the firmer the
pressure, the faster the movement appears.

Modifying gpm

I decided to modify mouse server gpm (version 1.13). The key
function added is x10codes in the
file gpm.c (see Listing 1). The function argument
data is an array of three bytes making up the
current mouse packet. The detection of the MouseRemote device is
not deterministic. I rely on the property that all its buttons
return codes in the specific range; that is, the range of the
possible, but not probable, combination of codes returned by the
normal mouse movement. In particular, the first code is always in
the range of 44 to 47, with the third code always being 0x3F. A
regular mouse would have to be moved quickly at just the right
speed in order to get the same code out. In the unlikely case it
happens, the second level of safety is the existence of a named
pipe, /dev/x10. If the pipe does not exist, the packet will be
passed on for normal processing. I used that named pipe to connect
to a reader of remote-mouse codes.