2016-07-17 48 views
1
Clip clip = AudioSystem.getClip(); 
AudioInputStream a = AudioSystem.getAudioInputStream(new File(path)); 
clip.open(a); 

Dies ist der Code, den ich verwende, um Audio in meinem Programm abzuspielen. Aus dem Java-Profiling kann ich erkennen, dass der Aufruf von clip.open() durchschnittlich weniger als 1 ms dauert. Gelegentlich wird es jedoch zu zufälligen Zeiten für einige Sekunden blockiert, was zu Verzögerungen führt.clip.open (AudioInputStream) hängt manchmal für ein paar Sekunden

Der folgende Screenshot zeigt meinen Java-Profiler. Wie Sie sehen können, wird die exakt gleiche Methode 316 mal ohne Problem aufgerufen. Aber einmal hängt es für 2,4 Sekunden auf Clip.open()

Beachten Sie, wie Clip.open nicht einmal in der unteren angezeigt wird, da die verbrachte Zeit weniger als 0,1 ms ist.

Die Clips, die ich spiele, sind rund 100KB groß, ich verstehe nicht, warum es funktioniert 316 Aufrufe, aber dann einmal hängt es.

Profiler

Ich habe versucht, schließen auch die Clips nicht, sondern sie alle offen, auch dann das Problem immer noch verlassen auftritt.

Antwort

0

Normalerweise Programmierer .open() a Clip gut vor, wenn sie es spielen wollen. Der Moment der Wiedergabe sollte nur einen .play() Befehl und nichts anderes beinhalten. Wenn Sie den Clip in aufeinanderfolgenden Befehlen "öffnen" und "abspielen", kann das play() erheblich verzögert werden, da die Datei vollständig in den Speicher geladen werden muss, bevor der Befehl play() ausgeführt wird. Aus diesem Grund wird eine SourceDataLine schneller ausgeführt, wenn Sie sich den Speicher für einen Clip nicht leisten können, da sie nur den Wert eines Puffers in den Speicher laden muss, bevor play() ausgeführt wird.

Vielleicht wissen Sie bereits über diesen Aspekt von Clips und das war nicht das Problem. (Sie erwähnen das Abspielen der Clips, ohne sie geschlossen zu haben.) Eine weitere Tatsache von Java ist, dass es keine Echtzeitgarantien gibt. Das System macht gute Arbeit, wenn es darum geht, eine Datei oder einen Clip abzuspielen, aber es ist schwierig, den genauen Startpunkt zu kontrollieren. Dies liegt an mehreren Faktoren, von denen einer die Zeit ist, die mit dem Jonglieren mehrerer Threads und Prozesse verbracht wird. Wenn beispielsweise ein Garbage-Collection-Befehl den Aufruf direkt vor dem Sound-Aufruf erhält, muss der Sound warten, bis das Segment fertig ist und der Prozessor dem Sound-Thread die Priorität gibt.

Es gibt noch andere Faktoren als auch Echtzeit-Performance zu beeinträchtigen, die in dem folgende Papier gut angelegt sind: Real Time Low Latency Processing in Java

Je nachdem, was Ihr Ziel ist, gibt es Möglichkeiten, die Vorteile des Schall Thread zu nehmen zu verbessern Timing-Genauigkeit durch "Zählen von Sound-Frames" und Ausführen von Events, wenn ein bestimmter Sound-Frame zur Verarbeitung vorliegt, von dem Vorgang, der diese Verarbeitung ausführt. Aber im Allgemeinen wird die Kommunikation zwischen dem Audio und anderen Threads einem gewissen Jitter unterworfen sein.