Java Standard: Das Paket javax.sound.sampled


Einleitung Bearbeiten

Um zu verstehen, warum das Paket javax.sound.sampled auf den ersten Blick so seltsam aufgebaut wurde, muss man sich erst einmal die Zielsetzung vor Augen halten:

  • Einheitliche Schnittstelle
  • Erweiterbarkeit

Das Problem bei der Entwicklung dieses Paketes war, dass auf die Verschiedenheit der Systeme, auf denen die Javaprogramme später laufen würden, unbedingt geachtet werden musste. Z.B. besitzen nicht alle Soundkarten neben der normalen Ausgabe auch noch einen Line Out. Außerdem werden nicht alle Audioformate nativ von dem zur Soundkarte gehörenden Mixer unterstützt. Einige Soundkarten lassen die gleichzeitige Wiedergabe mehrerer Spuren zu, andere wiederum nicht. Dies sind nur einige wenige Beispiele, es gibt noch sehr viele mehr. Trotzdem muss eine einheitliche Schnittstelle zum Soundsystem angeboten werden, um die API plattformunabhängig zu halten. Ein weiterer Punkt ist die Erweiterbarkeit des Paketes. Mit speziellen Klassen sollte es möglich sein, dass auch andere Formate unterstützt werden. Die Dienste, die diese neue Klassen anbieten, müssen natürlich für die Javaprogramme verfügbar sein, ohne dass diese eigentlich davon wissen. Erreicht wurde das mit dem Unterpaket javax.sound.sampled.spi, wobei SPI für Service Provider Interface steht.

Die Klasse AudioSystem Bearbeiten

Zentrale Anlaufstelle für alle Belange, die mit dem Einlesen oder Schreiben von Datenströmen mit Sounddaten zu tun haben, ist die Klasse AudioSystem. Sämtliche Methoden in AudioSystem sind als statisch deklariert. Die Wichtigsten sind:

  • AudioFileFormat getAudioFileFormat(File file);
  • AudioInputStream getAudioInputStream(URL url);
  • AudioInputStream getAudioInputStream(AudioFormat targetFormat, AudioInputStream sourceStream);

Wenn es darum geht, mit Datenquellen und Datensenken zu arbeiten, ist die Vorgehensweise meistens wie folgt:

  1. Das Java-Programm erzeugt ein Line.Info Objekt, das beschreibt, was genau das Programm nun tun möchte, also ob eine Datensenke oder eine Datenquelle erwünscht ist und ob der Datenfluss mit einem Port oder einem bestimmten Mixer verbunden werden soll. Zusätzlich können noch erwünschte Audioformate und Puffergrößen spezifiziert werden. Es müssen nicht alle Informationen angegeben werden.
  2. Als nächstes wird das AudioSystem gefragt, ob es diese Anforderungen erfüllen kann.
  3. Zuletzt wird dann im positiven Falle vom AudioSystem der entsprechende Datenfluss abgerufen. Mit diesem kann nun gearbeitet werden.

Ziel war es also, dass das Java-Programm zum Zeitpunkt des Kompilierens nicht wissen muss, mit welchen Audioformaten es während seiner Laufzeit konfrontiert wird, auf welchen Plattformen es läuft und welche Audiokapatibilitäten diese zur Verfügung stellt.

Das Interface Line Bearbeiten

Ein ganz zentraler Punkt in diesem Paket ist das Interface Line. Eine Line repräsentiert alle Datenflüsse, die im AudioSystem auftreten. Es kann sich dabei um die Wiedergabe, Aufnahme, verschiedene Ports oder Pipes in den Mixer hinein oder heraus handeln. Mit diesen Audiodatenflüssen können ganz grundlegende Dinge getan werden. Bevor man damit arbeiten kann, muss man sie öffnen. Sobald dieses geschehen ist, werden Systemresourcen belegt. Nach der Benutzung sollte die Line auch wieder geschlossen werden, damit die Systemresourcen freigegeben werden können. Es ist möglich die Controls einer Line abzufragen. Dies sind Objekte, welche die Audiodaten in gewisser Weise beeinflussen. Beispielsweise gehören dazu das Verändern der Balance, der Lautstärke, der allgemeinen Lautstärke oder auch die Samplerate. Nicht alle Controls sind bei allen Lines verfügbar.

Das Subinterface Port Bearbeiten

Ports repräsentieren die typischen Ein- und Ausgabemöglichkeiten der Soundkarte. Zu den Wiedergabeports gehören zum Beispiel Speakers, Headset oder Line Output. Zu den Aufnahmeports gehören beispielsweise das Mikrofon, das CD-Laufwerk oder der Line Input. Auch hier gilt wieder, dass nicht auf allen Systemen alle Ports vorhanden sind.

Vollständig implementiert wurden Ports erst im J2SDK 5.0