我想根據用戶在Java中的操作來生成聲音。即使我將SourceDataLine中的緩衝區大小設置爲儘可能最小的值(1幀),我仍然有約1秒的延遲。如何在沒有延遲的情況下使用SourceDataLine流式傳輸聲音
因爲代碼段是勝過千言萬語(?或者是它的照片),這裏是代碼:
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++;
}
}
}
嘗試移動滑塊,一邊聽聲音。是否有可能,還是我必須創建內存緩衝區並將它們包裝在Clip實例中?
謝謝。我被_new DataLine.Info(SourceDataLine.class,audioFormat,1)_中的_bufferSize_參數蒙上了一層陰影。當然,我不打算使用這樣一個小緩衝區。這只是爲了表明我的問題。 – andi
@弗洛裏安謝謝你的這個例子。如果'int n = soundLine.write(buffer,0,bufferSize);'n在第一次寫入後返回0值,這意味着什麼? – user390525
@ user390525,根據SourceDataLine.write()的規範,如果發生錯誤(格式錯誤的參數),或者SourceDataLine停止,刷新或關閉,它只能返回小於指定的緩衝區大小。 如果您100%確定這些條件都不適用,則該SourceDataLine的Java實現中可能存在一個錯誤。 – Florian