wie zum streamen von sound in java ohne Verzögerung mit SourceDataLine
Möchte ich, um sounds zu erzeugen, basierend auf die Aktionen des Anwenders in Java. Auch wenn ich die buffer size im SourceDataLine auf den kleinstmöglichen Wert (1 Bild) ich habe noch ein delay von etwa 1 Sekunde.
Da ein code-snippet, das ist mehr Wert als tausend Worte (oder war es ein Bild?), hier ist der code:
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.SourceDataLine;
import javax.swing.JFrame;
import javax.swing.JSlider;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
public class SoundTest {
private static int sliderValue = 500;
public static void main(String[] args) throws Exception {
final JFrame frame = new JFrame();
final JSlider slider = new JSlider(500, 1000);
frame.add(slider);
slider.addChangeListener(new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
sliderValue = slider.getValue();
}
});
frame.pack();
frame.setVisible(true);
final AudioFormat audioFormat = new AudioFormat(44100, 8, 1, true, true);
final DataLine.Info info = new DataLine.Info(SourceDataLine.class, audioFormat, 1);
final SourceDataLine soundLine = (SourceDataLine) AudioSystem.getLine(info);
soundLine.open(audioFormat);
soundLine.start();
byte counter = 0;
final byte[] buffer = new byte[1];
byte sign = 1;
while (frame.isVisible()) {
if (counter > audioFormat.getFrameRate() / sliderValue) {
sign = (byte) -sign;
counter = 0;
}
buffer[0] = (byte) (sign * 30);
soundLine.write(buffer, 0, 1);
counter++;
}
}
}
Bewegen Sie den Schieberegler bei der Wiedergabe der Ton. Ist es möglich, oder muss ich das erstellen von in-memory Puffer und wickeln Sie Sie in Clip-Instanzen an?
Du musst angemeldet sein, um einen Kommentar abzugeben.
Die fix ist, geben Sie die Puffergröße in der
open(AudioFormat,int)
Methode. Eine Verzögerung von 10ms-100ms akzeptabel sein wird für die Echtzeit-audio. Sehr niedrige Latenzen wie funktioniert nicht auf allen computer-Systemen, und 100ms oder mehr, wird wahrscheinlich lästig sein für die Benutzer. Ein guter Kompromiss ist, z.B. 50ms. Für Ihr audio-format, 8-bit, mono auf 44100Hz, einen guten Puffer Größe ist 2200 bytes, die fast 50ms.Beachten Sie auch, dass unterschiedliche Betriebssysteme haben verschiedene audio-Funktionen in Java. Auf Windows und Linux können Sie die Arbeit mit sehr kleinen puffergrößen, aber OS X nutzt eine alte Umsetzung mit deutlich größerer Verzögerung.
Auch, das schreiben von Daten byte für byte auf die SourceDataLine ist sehr ineffizient ist (die Größe des Puffers ist in der
open()
Methode, nicht inwrite()
), als Faustregel würde ich schreiben immer einen vollen Puffer auf die SourceDataLine.Nach dem einrichten der SourceDataLine, verwenden Sie diesen code:
int n=soundLine.write(buffer, 0, bufferSize);
n gibt 0 zurück, Wert nach 2 zuerst schreiben?