.:[Minerva]:.
Ich habe mir einen MP3-Server zusammengestellt,
der über die eingebaute Soundkarte die Musik abspielt.
Als Grundlage dient ein eisfair-Server.
Für diejeigen, die eisfair nicht kennen, hier eine Kurzvorstellung:
"eisfair - Easy Internet Server
eisfair ist ein einfach zu installierender Internet-Server,
der als zugrundeliegendes Betriebssystem Linux verwendet.
Es wird ausschließlich freie Software verwendet. Die Installation und
der Betrieb von eisfair setzt jedoch keine Linux-Kenntnisse voraus und
ist mit einfachen und - besonders wichtig - einheitlichen Mitteln möglich.
eisfair soll keine weitere Linux-Distribution sein, davon gibt es schon viel zu viele.
Intention ist die Installation eines Internet-Servers, bei dem
die angebotenen Applikationen und Dienste im Vordergrund stehen sollen -
nicht das Betriebssystem."
Die allgemeine Installation kann in der
Dokumentation
auf der Homepage des Projektes nachgelesen werden,
ich möchte hier nur meine Einstellungen und Erweiterungen vorstellen,
die bei mir zum Betrieb als MP3-Server notwendig sind.
An Ende habe ich alle Downloads aufgeführt, die für das Projekt notwendig sind.
Hardware
In dem Eigenbau-Gehäuse stecken
- ASUS P2B, Rev. 1.10
- Pentium II 400
- 128 MB RAM
- SoundBlaster Vibra16, Modell CT4180
- platzsparende RealTek 8139 10/100
- 10 GB Festplatte
Erstellung MP3s
Um die CDs nach MP3 zu wandeln, habe ich
CDex 1.51
verwendet, um die MP3-Tags nachzubearbeiten,
Mp3 Tag Tools v1.2.
Der folgende Fehler hat mir einiges Kopfzerbrechen bereitet.
Wenn mpd seine eigene Datenbank aufbaut, hat er Probleme mit Verzeichnisnamen,
die deutsche Umlaute enthalten. Ich habe jetzt alles prinizipell ohne diese geschrieben.
Packages
Folgende Packages müssen installiert sein und funktionieren:
- OSS-Sound
Die Lautstärke ist bei allen OSSSOUND_VOL_* auf 100 gesetzt,
zwischen Soundkartenausgang und Lautsprechern ist noch
der Lautstärkeregler (Stereo-DrehPoti) eingebaut.
- MPd
- mpc
- mpg123
- Apache mit PHP
Wenn der MPd per Web-Frontend gesteuert werden soll, muß die Socket-Unterstützung
einkompiliert sein, was bei dem eisfair-Package der Fall ist.
- MySQL
- LCD
- cPanel
Folgende Packages sind opional:
- Cron Daemon
Zu dem Standard-Eintrag für logrotate wird der Aufruf zum periodischen Update
der MPd-Datenbank ergänzt.
CRON_2_TIMES='3 * * * *'
CRON_2_COMMAND='mpc update >/dev/null 2>&1'
- Inet Service
- Netdate Service
Wenn schon ein fli4l im Netzwerk hängt, kann er auch das aktuelle Datum liefern.
- LIRC
(Im Anhang ist die komplette Package-Liste.)
Einstellungen der Packages
LCD
Es wird ein kleines 2x20 Zeichen Display verwendet.
Alle Ausgaben, die auf dem Display erscheinen sollen, werden per Script
ermittelt, in Abhängigkeit der Steuerung per CPanel.
Es ist auch problemlos möglich mehr als 2 Zeilen auszugeben, die Scripts könnten das!
Hier nur die wichtigsten Konfigurations-Einstellungen:
LCD_COLS='20' # no. of lcd columns (16,20,32,40) dflt: 20
LCD_ROWS='2' # no. of lcd physical rows (1,2,4) dflt: 4
LCD_ROWS_N='2' # no. of displayed lines dflt: 4
LCD_ROWS_1='%x1' # what to display in 1. line
LCD_ROWS_2='%x2' # what to display in 2. line
LCD_CMDS_N='2' # number of userdefined commands, must be
# smaller or equal 9
# PATH=/usr/local/bin:/usr/bin:/bin
# ... is result of command 1..8 in
# environment
# with full path for performance
LCD_CMDS_1_CMD='/usr/bin/lcd_display 1' # 1. command to execute
LCD_CMDS_2_CMD='/usr/bin/lcd_display 2' # 2. command to execute
LCD_ICON_N='2' # number of user defineable icons
# used via: sed -e 's/>/\\017/g'
LCD_ICON_1_ROW_1='*....'
LCD_ICON_1_ROW_2='**...'
LCD_ICON_1_ROW_3='***..'
LCD_ICON_1_ROW_4='.***.'
LCD_ICON_1_ROW_5='***..'
LCD_ICON_1_ROW_6='**...'
LCD_ICON_1_ROW_7='*....'
LCD_ICON_1_ROW_8='.....'
# used via: sed -e 's/\\r/\\016/g' \r for "rotate"
LCD_ICON_2_ROW_1='.***.|..**.|.....|.....|.....|.....|.....|.**..'
LCD_ICON_2_ROW_2='*****|..***|....*|.....|.....|.....|*....|***..'
LCD_ICON_2_ROW_3='.***.|..***|...**|.....|.....|.....|**...|***..'
LCD_ICON_2_ROW_4='..*..|..***|..***|..***|..*..|***..|***..|***..'
LCD_ICON_2_ROW_5='.....|.....|...**|..***|.***.|***..|**...|.....'
LCD_ICON_2_ROW_6='.....|.....|....*|..***|*****|***..|*....|.....'
LCD_ICON_2_ROW_7='.....|.....|.....|..**.|.***.|.**..|.....|.....'
LCD_ICON_2_ROW_8='.....|.....|.....|.....|.....|.....|.....|.....'
cPanel
Am Package CPanel wurden die größten Veränderungen vorgenommen.
Konfiguration:
START_CPANEL='yes'
CPANEL_PORT='/dev/ttyS0'
# Da u.a. kein Script mehr verwendet wird,
# werden alle diese Parameter nicht verwendet!
CPANEL_SWITCHTIME='1'
CPANEL_SCRIPTTIME='10'
CPANEL_STATUSLED_ONOFF='none'
CPANEL_STATUSLED_BLINK='none'
CPANEL_STATUSLED_OPTION=''
CPANEL_STATUSLED_SCRIPT='no'
#------------------------------------------------------------------------------
# Tastenbelegung
#------------------------------------------------------------------------------
CPANEL_FUNKTION1='/usr/bin/lcd_control mode'
CPANEL_FUNKTION2='/usr/bin/lcd_control enter'
CPANEL_FUNKTION3='/usr/bin/lcd_control reboot' # mode + enter
CPANEL_FUNKTION4='/usr/bin/lcd_control prev'
CPANEL_FUNKTION5='/usr/bin/lcd_control prevmode' # prev + mode
CPANEL_FUNKTION6=''
CPANEL_FUNKTION7='/usr/bin/lcd_control stop'
CPANEL_FUNKTION8='/usr/bin/lcd_control next'
CPANEL_FUNKTION9='/usr/bin/lcd_control nextmode' # next + mode
CPANEL_FUNKTION10=''
CPANEL_FUNKTION11='/usr/bin/lcd_control playpause'
CPANEL_FUNKTION12='/usr/bin/lcd_control halt' # prev + next
CPANEL_FUNKTION13=''
CPANEL_FUNKTION14='/usr/bin/lcd_control reset'
Die Erläuterung des neuen CPanel-Programms ist hier und
auf die Kontroll-Scripte wird ausführlich unter Steuerung eingegangen.
Anpassungen & Erweiterungen
RAM-Disk
Da die gesamte Steuerung über Dateien läuft, wird eine RAM-Disk
für diesen Zweck angelegt.
Diese wird durch folgende Scripts und den Start-Link erzeugt:
/etc/config.d/ramdisk
# Größe der Ramdisk in kB
size=1024
# Mount-Verzeichnis, wenn nicht existiert wird es angelegt
mount='/mnt/ramdisk'
/etc/init.d/ramdisk
#!/bin/sh
# include eislib
. /var/install/include/eislib
. /etc/config.d/ramdisk
if [ "$RAMDISK_DO_DEBUG" = yes ]; then
set -x
fi
case $1 in
start)
mecho -info "Create RAM-Disk..."
[ -d "$mount" ] || mkdir -p "$mount"
/sbin/mkfs.ext2 -m 0 /dev/ram0 $size
/bin/mount -t ext2 /dev/ram0 "$mount"
/bin/chmod -R 755 "$mount"
;;
esac
set +x
Link auf das Start-/Stop - Script: /etc/rc2.d/S01ramdisk
Hierdurch wird eine RAM-Disk mit 1 MB angelegt und nach /mnt/ramdisk gemounted.
Begrüßung
Der Rechner meldet sich, wenn der Boot-Vorgang abgeschlossen ist und er bereit ist,
Kommandos entgegenzunehmen.
Dies erfolgt mittels /etc/rc2.d/S99z-welcome:
#!/bin/sh
mpg123 -q /usr/local/control/snd/de/welcome-long.mp3 # (1)
sleep 2
mpc load _tmp >/dev/null 2>&1 # (2)
mpc play >/dev/null 2>&1 # (3)
Nach der Begrüßung(1) wird versucht, die eventuell beim letzten Herunterfahren
gespeicherte Playliste zu laden(2) und abzuspielen(3).
Die gesprochenen Texte wurden mit
MARY Text-to-Speech System / TTS Demo
synthetisiert, als .wav heruntergeladen und mit
CDex nach .mp3 konvertiert.
Der direkte Download als MP3 hat irgendwie nicht geklappt.
mCPanel
Taster-Anschluß
Zwischen den Tastern und der der seriellen Schnittstelle hängt die
Platine, an die bis zu
14 Taster direkt angeschlossen werden können.
Diese Schaltung ist die Erweiterung der originalen Schaltung und eines Vorschlages
zum Anschluß von 8 Tastern.
Hier wurden nur konsequent alle Möglichkeiten ausgeschöpft.
Bei Widerstand R3 habe ich feststellen müssen, dass (wahrscheinlich) die Dioden zuviel
Spannungsabfall produzieren, besonders bei Taster 1 und allen Tastern,
die die 1 mit einbeziehen (alle ungeraden)
Ich habe daher einen 10 kOhm-Drehpoti verwendet und soweit zuückgedreht,
bis alle Tasten ordnungsgemäß erkannt wurden.
Das war bei einen Wert von 4,4 kOhm der Fall. Die Schnittstelle kommt damit klar.
| Es reichen einfach(st)e Widerstände und Dioden, z.B. | Conrad Art.Nr. |
| Widerstand: | Kohleschichtwiderstand 0,5 W (Bauform 0411,Toleranz 5%) 2,2kOhm | 40 52 99 |
| Diode: | 1N4148 (100V, 150mA) | 16 22 80 |
Programm
Im Einsatz ist ein "miniCPanel", welches in folgenden Punkten verändert wurde:
- Die Tastenreaktionszeit und das Bestätigungsblinken wurden parametrisiert.
Dadurch kann sowohl die Reaktionszeit als auch die Bestätigungszeit herabgesetzt werden.
Die Defaultwerte stellen einen guten Kompromiss zwischen Schnelligkeit und Genauigkeit dar,
d.h. die Zeit, die eine ODER mehrere Tasten gedrückt sein müssen ist kurz genug,
um zügig durch ein LCD-Menü zu scrollen aber auch lang genug, um Tasten-Kombinationen zu erkennen.
- Die Script-Verarbeitung wurde entfernt, es wird nur direkt /var/run/cpanel.status
ausgewertet.
Die Datei wird ausschließlich von externen Scripts gefüllt.
$ ./mcpanel
mCPanel-0.1
mCPanel ermöglicht die Abfrage von bis zu 14 Tasten am seriellen Port.
Beim Drücken der Tasten werden die Skripte /usr/local/cpanel/funktion1-14
aufgerufen. Diese Skripte können nach Belieben geändert werden.
Aufruf:
mcpanel <device> [<Check> [<CheckCount> [<Confirm> [<ConfCount>]]]]
wobei
<device> z.B. /dev/ttyS0
<Check> Zeit zwischen Abfrage des Port-Status im ms, Vorgabe=30
<CheckCount> * <Check> muß Knopf gedrückt sein für Aktion, Vorgabe=3
Das heißt hier, nach 90 ms wird eine Aktion ausgeführt.
<Confirm> Blinkdauer zur Bestätigung in ms, Vorgabe=75
<ConfCount> Anzahl der Blink-Bestätigungen, Vorgabe=1
Um dieses Programm zu verwenden, muß
- die Datei mcpanel nach /usr/local/bin/mcpanel
kopiert und ausführbar gemacht werden,
- die Datei /etc/init.d/cpanel folgendermaßen geändert werden:
ersetze ca. Zeile 37:
nohup /usr/local/bin/cpanel $CPANEL_PORT $CPANEL_SWITCHTIME $CPANEL_SCRIPTTIME &
durch:
nohup /usr/local/bin/mcpanel $CPANEL_PORT &
Steuerung
Da der mpd als Dämon im Hintergrund arbeitet, braucht man ein Frontend,
um ihn anzusteuern.
Diverse Clients findet man auf MusicPD.org.
Es gibt sowohl Kommandozeilen-Clients als auch Web-Clients,
die direkt eine Socket-Verbindung aufbauen.
Web-Steuerung
Die Steuerung per Web-Frontend des Rechners kann prinzipiell auf 2 Arten erfolgen:
- Auf Grundlage der Verzeichnis-Struktur und der mpd-Datenbank.
Dazu ist nur Apache notwendig und ein Web-Frontend für mpd,
wie z.B. phpMP
oder phpMp2.
Diese Frontends setzen auf der Verzeichnis-Struktur der MP3s auf.
- Auf Grundlage der MP3-Tags in einer Datenbank, z.B. MySQL.
Ein solcher Client ist z.B. Ampache.
Beim Anlegen eines Kataloges werden die ID-Tags aus den MP3s ausgelesen
und in eine MySQL-Datenbank geschrieben. Auf diese Datenbank greift meine Tastensteuerung
per Kommandozeilen-SQL zu, um die Informationen zu beschaffen.
Tasten-Steuerung
Die LED in der Mitte des Tasten-Kreises ist die "Bestätigungs"-LED.
Kommen wir zum Herzstück der Steuerung, den "Control"-Scripts.
Der prinzipielle Aufbau der LCD-Menüs ist folgender:
- Status
- now playing
- Programmierung
- Playlisten
- Genre
- Interpreten
Durch diese Menüpunkte wird per Mode durchgeschalten.
Bei den folgenden Menüpunkten kann per Enter durch verschiedene "Screens" gescrollt werden:
Status
- Rechnername / Datum Zeit
- uptime / Speicherbelegung
- System-Version / mpd-Version
- Belegung hda4 (mount auf /data)
- Belegung ram0
- Speicher total / frei
- Swap total / frei
- Anzeige /proc/loadavg
now playing
- Interptet / Titel
- Titel / Fortschritt
Bei den folgenden Menüpunkten wird per Prev / Next die gewünschte Zeile ausgewählt
und per Enter bestätigt:
Programmierung
- Wiederholung an/aus
- Zufallswiedergabe an/aus
- Zeilen-Scrollen an/aus
(Wenn anzuzeigende Zeilen länger als 20 Zeichen sind, z.B. Interpret oder Titel, werden sie
als Laufschrift horizontal gescrollt)
Genre
Wenn von Genre per Mode weiter auf Interpreten gegangen wird,
werden ALLE Interpreten zur Auswahl angeboten.
Wenn ein Genre selektiert und per Enter bestätigt wird,
werden nur noch Intepreten gelistet, die Alben in diesem Genre haben.
Wenn auf einem selektierten Genre gleich PlayPause gedrückt wird,
werden ALLE Titel dieses Genres in die Playliste geschrieben und abgespielt.
Interpreten
Nach Selektion eines Interpreten werden alle seine Alben zur Auswahl angeboten
und nach der Auswahl per Enter alle Titel in die Playliste geschrieben und abgespielt.
Wenn auf einem selektierten Interpreten gleich PlayPause gedrückt wird,
werden ALLE Titel dieses Interpreten in die Playliste geschrieben und abgespielt.
Eine ungefilterte Auswahlmöglichkeit auf alle Alben habe ich weggelassen, da diese Liste
zu lang und unübersichtlich werden würde.
Schnelleres Scrollen
In den Modi Playlisten-Auswahl, Genre-Auswahl und Interpreten-Auswahl kann
mit diesen Tasten-Kominationen
Next+Mode / Prev+Mode
jeweils um 5 Zeilen, in der Album-Auswahl um 2 Zeilen vorwärts / rückwärts geblättert werden.
Dies erleichtert das Blättern durch doch teilweise inzwischen sehr lange Listen.
Steuerungs-Reset
Wenn sich die Menüs oder die Steuer-Scripte mal verhaken,
kann hiermit die gesamte Steuerung in ihren Urzustand zurückgesetzt werden.
Datei-Struktur
Konfiguration
/etc/config.d/control
# zum Debuggen auf den Bildschirm
lcd_debug=0
# gleiches Verzeichnis wie in der mpd-Knfiguration!
mp3dir='/mp3'
# User-Name und Datenbank-Name für den Zugriff auf die Ampache-Daten.
# Dieser User braucht nur Lese-Berechtigung und DARF KEIN Passwort haben.
db_user='ampache'
db_name='ampache'
# Arbeitsverzeichnis; in dieses Verzeichnis werden beim Booten die
# Scripte und Anfangszustände kopiert
dir='/mnt/ramdisk/control'
# Welche Soundes sollen für Ansagen verwendet werden
# wenn ungleich leer, werden die Dateien nach $dir/snd kopiert
sounds='' # en|de|''
# soll die CPanel-Status-LED gesetzt werden
# random/repeat an aus
# an blink on
# aus on off
cpanel='yes'
# Rechner-Name, \r wird durch LCD-ICON ersetzt
name='MP3-Server \r Minerva'
# was soll angezeigt werden, wenn ein Titel pausiert
paused='[paused]'
# Wie lange sollen Meldungen auf dem LCD gezeigt werden [s]
message='2'
# Sollen Spezialzeichen ersetzt werden (siehe dazu func.sh, function format)
replace_special='yes'
Start/Stop - Script
/etc/init.d/control
#!/bin/sh
# include eislib
. /var/install/include/eislib
. /etc/config.d/control
cdir='/usr/local/control'
case "$1" in
start)
mecho -info "Initialize LCD- & CPanel-Control..."
# kopieren der Scripte...
[ -d $dir ] || mkdir -p $dir
cp $cdir/*.sh $dir
cp $cdir/scroll.status $dir
[ -d $dir/cmd ] || mkdir $dir/cmd
cp $cdir/cmd/* $dir/cmd
[ -d $dir/dsp ] || mkdir $dir/dsp
cp $cdir/dsp/* $dir/dsp
# kopieren der initialen Menüs und Status-Dateien
[ -d $dir/mode ] || mkdir $dir/mode
cp $cdir/mode/* $dir/mode
# kopieren der Sound-Files
if [ -n "$sounds" ]; then
[ -d $dir/snd ] || mkdir -p $dir/snd
cp $cdir/snd/$sounds/*.mp3 $dir/snd
fi
# Links zu den Steuer-Scripts erstellen
ln -sf $dir/display.sh /usr/bin/lcd_display
ln -sf $dir/control.sh /usr/bin/lcd_control
# cpanel.status "verschieben"
cp /var/run/cpanel.status $dir/cpanel.status
ln -sf $dir/cpanel.status /var/run/cpanel.status
;;
stop)
# Status-Dateien sichern
cp $dir/cpanel.status /var/run/cpanel.status
cp $dir/scroll.status $cdir/scroll.status
# mpd anhalten
mpc stop >/dev/null 2>&1
sleep 1
# Playliste temporär für nächsten Start merken
mpc rm _tmp >/dev/null 2>&1
mpc save _tmp >/dev/null 2>&1
# Ansage....
mpg123 -q $cdir/snd/shutting-down.mp3
;;
*)
mecho -info "Usage: control {start|stop}"
exit 1
;;
esac
exit 0
Die entsprechenden Links in /etc/rc2.d sind
- S54control
Dieses Script muß vor dem LCD-Script laufen,
damit die Links auf das Anzeige-Script bereits bestehen.
- K00_control
Diese Datei wird als Erste ausgeführt, schließlich soll die Ansage "Shuting down"
ja vor allem anderen kommen.
Es muß auch noch folgendes gemacht werden:
Das Script der CPanel-Initialisierung muß VOR S54control laufen,
weil darin /var/run/cpanel.status manipuliert wird!
Hier liegt es jetzt auf S05cpanel
Steuer-Scripts
Alle Scripts befinden sich unter /usr/local/control
| control.sh | Rahmenprogramm; dies verteilt die Kommandos an die entsprechenden Teil-Scripte in cmd/ |
| display.sh | Anzeige-Script; wird von der LCD-Steuerung aufgerufen und ermittelt, was in der geforderten Zeile angezeigt werden soll. |
| func.sh | Funktions-Include |
| init.sh | Initalisierungs-Include |
| scroll.status | Vorgabe - Scroll-Status |
| cmd\* | Tasten-Kommandos, werden von control.sh includiert. |
| dsp\nowplaying.sh |
Wenn keine statischen Menü-Dateien genutzt werden (können),
werden z.B. diese "Display"-Scripts gerufen und liefern die entsprechenden Informationen |
| dsp\program.sh |
| dsp\status.sh |
| Die gesamt Steuerung baut auf dem Modus auf, in dem sich die Steuerung befindet.
Alle Anzeigen und Folge-Operationen hängen davon ab, was gerade der aktuelle Modus ist. |
| mode\mode | aktueller Modus |
| Alle Dateien mode.* sind Menü-Dateien. |
| mode\mode.status | Menü-Datei für Modus Status |
| mode\mode.playing | Menü-Datei: now playing |
| mode\mode.program | Menü-Datei: Programmierung |
| mode\mode.reboot | Menü-Datei: Reboot |
| mode\mode.halt | Menü-Datei: Halt |
| Die Menü-Dateien für Playliste, Genre, Artist und Album werden per SQL erstellt. |
| snd\*.mp3 | Ansagen |
Menü-Dateien (mode/mode.*) haben folgenden Aufbau (ohne die Leerzeichen ;-) :
<Text> [TAB <Menü> [TAB <ID>]]
- TAB: Tabulator :-)
- <Text>: Text, der im LCD angezeigt werden soll
Sonderfall:
Wenn der Text mit einem Ausrufungszeichen beginnt,
z.B. !date, wird versucht den "Text" als externes Kommando auszuführen.
Hier kommen hauptsächlich die Display-Scripts (dsp/*) zum Einsatz,
siehe z.B. mode/mode.status.
- <Menü>: Wenn an dieser Stelle ein beliebiges Zeichen steht,
heißt das, diese Datei ist per Next
/ Prev als Menü scrollbar.
(Dies trifft z.B. auf die Genre-, Interpreten- & Albumlisten zu)
- <ID>: Hier steht z.B. nach Datenbank-Selektionen die Datensatz-ID des Genres / Interpreten etc.
Das bedeutet, im einfachsten Falle, bei status, playing, reboot und halt,
besteht die Datei nur aus Texten, da hier nicht per Next
/ Prev gescrollt werden kann.
Ablauf der Anzeige
display.sh ermittelt durch Auslesen der Datei mode/mode den aktuellen Modus.
Daraus ergibt sich die anzuzeigende Menü-Datei mode.<Modus> und
die erste anzuzeigende Zeile aus mode.<Modus>.row
Daraus ergibt sich der Text, entweder direkt oder durch Ausführen eines extrnen Kommandos.
Wenn der Text zu lang für die LCD-Zeile ist, wird grprüft, ob horizontal gescrollt werden soll.
Der aktuelle Spaltenversatz wird in mode.<Modus>.col.<Zeile> gespeichert,
wobei <Zeile> die Menüzeile und nicht die LCD-Zeile ist.
Die endgültige Textausgabe erfolgt durch die zentrale Funktion "format"
im include func.sh.
Downloads
Anhang
Alle Packages
| Package | Version |
| apache2 | 1.0.2 |
| apache2_php5 | 1.0.1 |
| base | 1.1.2 |
| binutils | 1.0.0 |
| certs | 1.0.5 |
| cpanel | 0.1.6 |
| cron | 1.0.0 |
| developer | 1.0.0 |
| devtools | 1.0.0 |
| eiskernel | 1.0.13 |
| gcc | 1.0.0 |
| glibc-dev | 1.0.0 |
| inet | 1.4.1 |
| lcd | 0.1.12 |
| libiconv-gettext | 1.0.0 |
| libssl0-9-7 | 1.0.0 |
| libstdcpp-libc6-2-2 | 1.0.0 |
| libz1-2 | 1.0.0 |
| lirc | 0.1.1 |
| lirc_modules | 0.0.2 |
| mpc | 0.1.0 |
| mpd | 0.1.1 |
| mpg123 | 0.0.1 |
| mysql | 1.1.12 |
| netdate | 1.14.8 |
| oss-sound | 0.9.2 |
| perl | 1.0.0 |
| text2speech | 0.0.1 |