Die Aufgabenstellung bestand darin, einen Gerätetreiber zu entwickeln, der es - im Gegensatz zum Standard-Treiber - mehreren Programmen gleichzeitig ermöglicht, auf das Audiodevice zuzugreifen und Sounds abzuspielen. Unser Treiber stellt dabei seine eigene Funktionalität unter /dev/audio und /dev/audioctl zur Verfügung, wobei versucht wird, das Verhalten des Orignial-Devicetreibers so weit wie möglich zu erhalten wird. Dabei werden die eingehenden Datenströme zusammengemischt, und das Summensignal an das bisherige Audiodevice weitergeleitet.
Der Gerätetreiber wurde basierend auf den Sun-Multiplex-Stream-Treiber
realisiert. Dabei erhält jedes Programm, das den Treiber öffnet,
eigenen Stream zugeteilt. Die Verbindung zum Original-Treiber erfolgt
ebenso über einen Stream, der von einem User-Level-Programm über den
Eines der wesentlichesten Probleme war eine sinnvolle Umsetzung für das Control-Device. Ein hier wünschenswerter Punkt war hier, sowohl die Lautstärke eines einzelnen Streams, als auch die globale Lautstärke regeln zu können. Auch gibts es keine klaren Festlegungen, wann das Daten- und wann das Kontrolldevice für Steuerkommandos verwendet wird. Hier werten wir die PID des Öffnenden Prozesses aus, um Streams von Daten- und Kontrolldevices zuzuordnen.
Dabei gibt es folgende Semantik:
Kontroll-Kommandos an ein Daten-Device gelten ebenso wie Kommandos zu einem Daten-Device über die PID assoziierten Kontroll-Device als lokale Einstellungen für diesen Kanal.
Kommandos an ein Kontroll-Device gelten grundsätzlich global. Die Codec-Einstellung (Datenrate, Format) werden allerdings nicht weitergereicht (diese Einstellung wird vom Treiber global anhand aller vorhandener Eingabestreams getroffen). Dafür werden diese lokal gespeichert, für den Fall, daß zu dieser PID später ein Daten-Strom geöffnet wird, der dann diese Einstellungen als Initialwerte bekommt.
Solange nur ein Eingabe-Strom vorhanden ist, kann dieser ohne Veränderungen weitergereicht werden. Sobald verschiedene Formate auftreten, wird als Ausgabe generell 16 bit verwendet. Solange alle Ströme die gleiche Datenrate verwenden, wird der Codec mit eben dieser betrieben, wenn nicht, erfolgt für alle Ströme eine Datenratenkonvertierung auf 44.1kHz
Einige Schwierigkeiten bereitete die Umsetzung des IOCTL-Interfaces des Audiotreibers, vor allem wo es um Zeitkritische Verhaltensweisen geht. das DRAIN-Kommando wurde durch ein Verkleinern der Inputqueue auf sehr kurz Werte simuliert, was für die meisten Programme ein besseres Verhalten ergibt als die "`strenge"' Semantik, tatsächlich auf das Ende zu warten. Das Zurücklesen der tatsächlich abgespielten Samples liefert nur die aus der Input-Queue gelesenen Samples, nicht die tatsächlich vom Audiodevice ausgegeben (das korrekt zu ermitteln wäre ein erheblicher Zusatzaufwand gewesen).
plexsetqueue erlaubt eine Änderung der Warteschlangen-Größen (in msec, die Größe in Bytes wird automatisch pro Kanal errechnet)
do_link erzeugt die Verbidung zum Orignal-Audiodevice
user_status zeigt Statusinformationen über alle momentan geöffneten Audiokanälen an
control erlaubt die individuelle Änderung der Lautstärke der einzelnen Kanäle
win tut das gleiche, allerdings Interaktiv und mit 'nem tollen X11-Interface