The Linux Audio Server Project|
Combining LIRC, XMMS, GRIP, VNC and some BASH scripting
Since I have a server (paris) that is always on, I figured I could turn it into a music server, aside from being an internet/file/print/scan server. The real 'problem' in my situation was twofold: first, the server is headless mouseless and keyboardless; second, it resides in a different room than the HiFi that I wanted to connect it to.
Luckily, there is such a thing as LIRC (Linux Infrared Remote Control), which allows you to use almost any IR remote control to give commands to the programs on your computer that have a plugin for LIRC. I had some experience with LIRC due to my Hauppauge WinTV-FM (which, btw is very well supported in Linux, so don't let the product name fool you - check my configuration page to see how to set that one up with LIRC) that comes with its own IR remote sensor and remote control. This time around, I had to build my own IR receiver, since the server had none, and I wasn't going to put a TV-card in my server just for the IR eye.
Also, the Hauppauge IR receiver only lets me use the IR remote control that came with it; I know it says (for instance in the LIRC FAQ) that the Hauppauge remote receivers should also function with any RC5-standard remote, but I tried with the various Marantz (CD-50) and Philips (Garbo Projector remote) remotes that I have lying around here, and they just don't work with the Hauppauge IR receiver.
Moreover, the living-room HiFi is a Denon, which has a remote that uses a different standard altogether.
Apart from the remote control issue, I would normally set my audio program to 'random' or 'shuffle' mode (naturally, I would want to be able to toggle the playback mode with the remote as well). But this would mean that with lots of songs, it may not always be clear which song is being played, from which artist or album. So I wanted to have a means to check, instantaneously or later, which songs got played. Since I have no displays in the living room (not even a tv), and the server has no display either, the options I had were:
- to also get a display that would 'advertise' the name of the current song
- create a way to check with the computers with a display (machines zurich and neuchatel) which song was played at a certain time
So all in all, it became clear to me what I had to do, I only had to figure out how to do it. With google and some man-page reading, I figured things out and so I:
- got 10m of audio cable to connect the audio server with the HiFi system
- got the parts and assembled (soldered) a LIRC serial port receiver
- installed and configured LIRC
- setup xmms to respond to my remote control
- used the songschange plugin and a shell script to create a playlist of the songs that were played
Connecting the audio server with the HiFi system was straightforward; I just got 10m of (male-cinch to male-cinch) audio cable (which was just long enough), clipped the cinch connectors off of one end and substituted that for the mini-jack that fits into the audio output of the soundcard in the server. If you don't want to modify your cable, you can also get a connector with cinch on one end and a mini-jack on the other; you can find those at most computer stores. In my case I had to cut off the connectors on one side anyway to fit through a hole in the wall.
Before jumping into details, just a little note: I use Mandrake 9.2, but this should not be very different for other Linux distributions. So if you want to do something similar with another distribution just replace the Mandrake specific things with the equivalent of your distribution (in Mandrake, urpmi / RPMDrake is for program installation, MCC is for system configuration).
Assembly of the LIRC receiver
For the receiver, few parts are needed: a connector to the serial port (Dsub-9), one remote receiver (I got the Siemens SFH 5110, 36kHz type), one diode, one resistor and one voltage regulator. You can check on the LIRC serial page for more details. Since I needed to have the IR detector in the living room, I got a 10m serial cable with Dsub9 connectors on both ends. Again, I cut off the connector on one end. I decided to just solder all components onto eachother, so not use any pcb or so, and directly connect it to the 3 wires of the serial cable. (Note: I got the serial cable so that at some later point, I might still get an LCD...)
The assembled receiver looks as follows (front and side shot), and just to show the size, I put a centimeter ruler and a 1 euro coin next to it.
The black part most to the right is the IR eye, the other part sticking out is the voltage regulator.
As you can see, I used some shrinkwrap to cover most of the parts (the resistor, capacitor and diode); before putting that on, I put some isolation between the various 'legs' of the components, so that squeezing the receiver would not short-circuit things. Before connecting to the serial port, I verified with an impedance meter that the relevant pins on the Dsub-9 connector were not shorted. My server only has 2 serial ports, and I wasn't going to lose one of those due to some silly bad soldering.... afterwards I had a talk with some colleagues and they assured me that you really need to connect some voltages higher than 12V to actually destroy a serial port, but anyway, better safe than sorry.
On the whole, I can say I was quite pleased with the end result - it is very small and thanks to the shrinkwrap quite professional looking too. On to testing the thing!
Setup of LIRC
The next step was to setup LIRC, naturally after connecting the serial port IR receiver.
I did, as root:
urpmi lirc lirc-remotes
which installed the lirc rpm (included in the download edition cds) and the lirc-remotes package, which is in the contrib repository and got downloaded from the web. I found I didn't need the lirc-remotes because my remote wasn't included, but if yours is it saves you some time. And yes, if I find the time I will create a standard file and send it to be included in a future release of lirc-remotes.
and made it look as follows: (I left out all the lines that are commented out with a hash)
# Customized settings for lirc daemon
# The hardware driver to use, run lircd --driver=? for a list
# Hardware driver module to load
# Serial port for the receiver (for serial driver)
I knew that I was connecting the serial connector to the first port, which is /dev/ttyS0. (This was logical as there were 4 COM ports indicated in the file.) I didn't change anything of the DRIVER_OPTS since I had no clue what else to put, and actually I figured that they would put reasonable defaults. Which I found to be true.
Then I did, as root (as most commands here):
service lircd start
(You can also do:
to which the system responded with:
Starting Linux Infrared Remote Control daemon: [ OK ]
Next I entered the following commands:
chkconfig --level 35 lircd on
Note: the depmod took quite a bit of time. (Also note: instead of the
chkconfig-command, I could have done: Mandrake Control Center, System, Services, and selected 'start on boot' for
After that last command, I could tell the device got properly created (which should normally happen whenever you load the correct module for the device):
[root@paris root]# ll /dev/lirc/serial
showed me the device node:
crw-rw-rw- 1 root root 61, 0 Jan 1 1970 /dev/lirc/serial
so all seemed well from the device side.
Note that on the LIRC website, there are indications that you have to do:
ln -s /tmp/.lircd /dev/lircd if you use Mandrake; my guess is that this is true only if you are compiling from source -- which is definitely not necessary in this case. That being said, it won't harm your system either.
I then verified (this you may execute as a regular user too) that the device was functional with:
mode2 -d /dev/lirc/serial
which gives no output, until you start pressing the remote buttons. A lot of codes flash by for each keypress if all is well. (Note that once the deamon "lircd" is running, you can no longer do this.)
If there is a lirc-remotes configuration file for your remote (it can be that your remote behaves the same as another one from the same factory): just copy the file for your remote control from the directory
cp /usr/share/lirc-remotes/[yourremotehere] /etc/lircd.conf
If it asks whether you want to overwrite the file
/etc/lircd.conf you naturally have to confirm. Note that only root can do this.
In case your remote is not included in the directory
/usr/share/lirc-remotes/ you are going to have to do what I did: the manual configuration to create the
/etc/lircd.conf file with
mode2. Just run (as regular user)
irrecord -d /dev/lirc/serial testfile
and by following instructions you will end up with a remote-definition in your current directory. As with a predefined remote you will have to copy this file over (as root) to
cp [freshlycreated-remotefile] /etc/lircd.conf
You can check (after starting lircd, as explained further on) with the program/command
irw whether the signals of your remote are seen and as which keypress.
This file is needed to setup the program response to the various remote control keys. The program needs to have a LIRC plugin (switched on, naturally). The names of the keys correspond to those in the file
/etc/lircd.conf and are not case sensitive. For each program that you want to control with LIRC, you have to check what options/commands exist.
You find my configuration file here: ~/.lircrc. And for kicks, the one I use on my workstation: ~/.lircrc of zurich. (Taking a closer look at the
~/.lircrc, you may notice that I use some nesting; this is to avoid from the commands 'shuffle' and 'cancel' (PLAYLIST_REMOVE) to get executed twice -- which can easily happen since the remote I use has no toggle-bit.)
Configuration of xmms:
Install the lirc plugin for xmms:
(don't let the IRMan entry in the plugins list fool you, this is something else! That actually cost me quite a bit of time to realise it was quite futile to try to get that one to work in my setup...)
Switch it on: options >> preferences, effect/General plugins - tab, select the LIRC Plugin [liblirc.so] and enable the plugin.
(BTW don't worry about the configure option, it allows you to select a font for the popup windows that you can get to select new songs -- the LIRC setup is in ~/.lircrc )
Some more hints: to know which commands exist for xmms, read the lirc-xmms-plugin README file. (This one is from version 1.4 -- yes indeed I cheated; if you use
urpmi xmms-lirc you get version 1.3; the only difference is that 1.4 includes the 'cancel' (PLAYLIST_REMOVE) command. If you want that, get this file: http://ftp.freshrpms.net/pub/freshrpms/redhat/9/xmms-lirc/xmms-lirc-1.4-fr1.i386.rpm, and do
urpmi xmms-lirc-1.4-fr1.i386.rpm in the dir where the file is. If you already have installed the standard Mandrake 9.2 version (for instance, with
urpmi xmms-lirc) you will first have to do
urpme xmms-lirc. If you find a Mandrake package with xmms-lirc version 1.4, let me know..)
Hint on the sideline: for xine, just do
xine --keymap=lirc to get all possible codes.
Now that we are there, you might as well also switch on the Song Change plugin, which can execute any command at each change of song. This I set up so that at any later moment it could be checked from any of the two computers with a monitor (mine and my wifes) which song had been playing at what time.
In my case, I chose to execute the script
~bin/xmmssongchange which resides in the
bin subdirectory in the homedir. The arguments that are passed are %f for the filename (this is the complete absolute path) and %s for the songname (if they are not between quotes, they actually get passed as if they are one single command). The script
xmmssongchange takes these arguments and creates a webpage on the fly, indicating the time and the name of the song, where the name is clickable and points to the songfile on the server. Since the path is the full path as the audio file resides on the server, I had to adapt the file paths somewhat to match how this partition is mounted via NFS on the 2 other machines. Once that was correct, I could open the file with the songs that got played, and clicking any of the songtitles will start playing that song.
Note: the file
xmmssongchange must of course be executable:
chmod +x ~bin/xmmssongchange
After this the result looks as follows:
One click on any name starts playback of the corresponding audio file in Totem.
As a last remark: I use ALSA, with OSS there is quite a delay when doing next, previous, stop, etc... With ALSA, the system is so responsive it is almost uncanny. The behaviour is like a (very large) cd changer, but with no delay between the songs (which you normally get when the changer changes discs).
Configuration of VNC
I ran, as user, the command:
and entered a password for the vncserver.
Next, I use a script
~bin/autostart.sh containing the following lines to start my server:
rm -f /tmp/.X7-lock
rm -f /tmp/.X11-unix/X7
vncserver :7 -geometry 800x600 -depth 16
xsetroot -solid navy -d :7
As you might tell from the above commands, this starts a vncserver on display nr 7, and starts xmms in this graphical session.
If you want to start this kind of thing at boot, all you have to do is (as root):
echo "sudo -u [username] /home/[username]/bin/autostart.sh" >> /etc/rc.local
Anyway, all I have to do to connect to that session is to point any java enabled webbrowser to the address:
http://paris:5807/ and all is dandy. Naturally, it is also possible to start a
vncviewer paris:7 and in either case, the password is required.
(Before you ask: yes, that is the Kaboodle KJofol skin that came with Mandrake 9.2; I just copied the skin over to the dir in
~/.xmms/kjofol ... )
grip to add audio cds, naturally I encode to ogg-vorbis:
In the grip Config tab, go to 'Encode' and select
oggenc as the encoder type; as the command line for the encoder I use:
-o %m --genre "%G" -q 8 -a "%a" -l "%d" -N "%t" -t "%n" %w
file format: /path/to/audio/dir/on/server/%A/%d/%t_%n.ogg
since the partition is mounted via nfs, direct writing to the server is possible and practical. On my workstation, ripping goes at ~5x, encoding at about ~7 or 8x. In case either grip or oggenc are not available, just do (as root):
urpmi oggenc grip
Some words on the small changes I made for the user account ('music') that I use to play music. You may skip this if the only account that any 'regular' user logs onto is the one that you also use to play music.
What (Mandrake) Linux usually does, is attribute the audio devices (all 'files' - actually device nodes - in /dev/sound and /dev/snd) to the first user who logs onto the system. The group membership of these files is 'audio' on all my systems, but all files are only owner read-writable, meaning: even members of the audio group cannot read from or write to these devices. To end this geek-speak, this means that only the first user to log onto the system can use the audio devices; all other users get an error message when they try to play an audio file, usually something like:
device busy, using null output device.
As root, it is certainly possible to change the ownership, but I used a different method: I changed the group membership of the user 'music' to be member of the group 'audio' (Mandrake Control Centre, System, UserDrake, select the user, click the tab 'Groups' in the newly opened window, and check the group 'audio').
Next I made all devices group read-writable:
chmod g+rw /dev/snd/*
chmod g+rw /dev/sound/*
but only to find that
msec (a security system, that I really want since this machine is always on, always connected) automatically changes file permissions according to a settings file. Naturally it took me some time to figure this out. In any case, I edited the file:
/etc/security/console.perms and changed the line:
<console> 0600 <sound> 0600 root.audio
<console> 0660 <sound> 0660 root.audio
which then did the trick.
For those who really don't want to type out of aversion, the special copy-me service is on the next 3 lines, just execute that as root; just remember, I'm not a guru, and the responsability is all yours:
cat /etc/security/console.perms | sed 's/0600 <sound>/0660 <sound>/' | sed 's/0600 root.audio/0660 root.audio/' > /etc/security/console.perms-new
mv /etc/security/console.perms /etc/security/console.perms.old
mv /etc/security/console.perms-new /etc/security/console.perms
Total time to figure everything out whilst implementing: 4 evenings. Total time for just the implementation (what people should count on if they follow my footsteps: 1 to 2 hours.
LIRC assembly: less than 1 hour (if you have some soldering skills; if you have none, just ask someone who has).
IRRemote Control configuration: 2 minutes if your remote is included in lirc-remotes, 10-15 minutes if it isn't or for any other reason you use
irw to make a /etc/lircd.conf file by hand.
~/.lircrc: 15 - 30 min (with my example given, it should not be more)
Configuration + installation of various programs, such as xmms, xmms lirc: 5 minutes
Setup and debugging of the songchangescript, including writing a valid html played-songs-page: 15 minutes
Creating this webpage and trying to be complete and precise about the whole process: 4 evenings or so.
Fulfilled feeling afterwards: timeless! ;-)
Nothing is perfect, including this. These last bumps are not important enough to me to try to get them straightened out; if you know how to fix this, drop me a line. For the moment I consider these points 'taches de beauté'...
1) I rarely reboot my server, so I didn't investigate what goes wrong, but the fact of the matter is that lircd is not properly starting on boot. After booting I did:
lsmod | grep lirc
lirc_serial 9312 1
BTW, I had added the line:
to the file
but it seems that it gets loaded only after lircd is started -- and therefor not correctly initialised. So after rebooting ( which I actually only did once -- to exchange a harddrive-- since doing the LIRC thing) I did the following:
[root@paris music]# service lircd restart
to which the system responded with:
Stopping Linux Infrared Remote Control daemon: [ OK ]
/etc/init.d/lircd: line 39: setserial: command not found
Starting Linux Infrared Remote Control daemon: [ OK ]
and I restarted XMMS. Then all worked properly again.
2) Another thing that is not perfect: quite often there are double entries in the played-songlist. Since the time is also indicated (and exactly the same), this is not a problem either.
Acknowledgements and related links:
Thanks to all GNU/Linux / FLOSS developers in general and the developers of the following things in particular:
LIRC - Linux Infrared Remote Control
XMMS - X Multimedia System
ALSA - Advanced Linux Sound Architecture
Page first created: January 2004. Page last updated:
Jan 31 2004