Chcę generować dźwięki w oparciu o działania użytkownika w Javie. Nawet jeśli ustawię rozmiar bufora w SourceDataLine na najmniejszą możliwą wartość (1 klatkę) nadal mam opóźnienie około 1 sekundy.jak przesyłać dźwięk w Javie bez opóźnienia przy użyciu SourceDataLine
Ponieważ fragment kodu jest wart tysiąca słów (? Czy był to obraz), oto kod:
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++;
}
}
}
Spróbuj przesunąć suwak podczas słuchania dźwięku. Czy to możliwe, czy też muszę tworzyć bufory w pamięci i owijać je w instancje Clipa?
Dzięki. Zostałam zaślepiona argumentem _bufferSize_ w _new DataLine.Info (SourceDataLine.class, audioFormat, 1) _. Oczywiście nie zamierzam używać tak małego bufora. To tylko po to, by pokazać mój problem. – andi
@Florian dziękuję za ten przykład. A co oznacza, jeśli 'int n = soundLine.write (buffer, 0, bufferSize); n zwraca wartość 0 po 2 pierwszym zapisie? – user390525
@ user390525, zgodnie ze specyfikacją SourceDataLine.write(), może zwrócić tylko mniej niż określony rozmiar bufora w przypadku błędu (nieprawidłowe parametry) lub jeśli SourceDataLine został zatrzymany, przepłukany lub zamknięty. Jeśli masz 100% pewności, że żaden z tych warunków nie ma zastosowania, być może wystąpił błąd w implementacji Java tej SourceDataLine. – Florian