【发布时间】:2016-12-13 02:12:01
【问题描述】:
我认为我的 Java Sound API 存在性能(延迟)问题。
音频监视器
以下代码确实对我有用。它正确打开了麦克风,并通过我的扬声器实时输出音频输入(即监控)。但我担心的是播放的速度……从我对着麦克风说话到通过扬声器播放的时间晚了半秒。
如何提高性能?如何降低延迟?
private void initForLiveMonitor() {
AudioFormat format = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED, 44100, 16, 2, 4, 44100, false);
try {
//Speaker
DataLine.Info info = new DataLine.Info(SourceDataLine.class, format);
SourceDataLine sourceLine = (SourceDataLine) AudioSystem.getLine(info);
sourceLine.open();
//Microphone
info = new DataLine.Info(TargetDataLine.class, format);
TargetDataLine targetLine = (TargetDataLine) AudioSystem.getLine(info);
targetLine.open();
Thread monitorThread = new Thread() {
@Override
public void run() {
targetLine.start();
sourceLine.start();
byte[] data = new byte[targetLine.getBufferSize() / 5];
int readBytes;
while (true) {
readBytes = targetLine.read(data, 0, data.length);
sourceLine.write(data, 0, readBytes);
}
}
};
System.out.println( "Start LIVE Monitor for 15 seconds" );
monitorThread.start();
Thread.sleep(15000);
targetLine.stop();
targetLine.close();
System.out.println( "End LIVE Monitor" );
}
catch(LineUnavailableException lue) { lue.printStackTrace(); }
catch(InterruptedException ie) { ie.printStackTrace(); }
}
附加说明
- 使用此代码,播放流畅(无爆音或抖动),仅延迟半秒。
- 我也知道我的电脑和 USB 音频接口能够通过电脑处理实时监控,因为当我与 Logic Pro X 进行并排比较时,延迟最小——我认为没有延迟完全没有。
- 我尝试减小/增大 byte[] 大小并没有解决问题。
我的结论是,这是我遇到的 Java 代码问题。提前致谢。
【问题讨论】:
-
这似乎归结为
targetLine.getBufferSize()的大小。那是多少字节? -
@AndrewThompson
targetLine.getBufferSize()方法返回 88200 字节。我已经使用了byte[]的除数,几乎没有什么变化。当我将byte[]显式降低到 4 个字节时,它确实有所帮助,但我仍然感觉到四分之一秒的延迟(超过半秒的延迟)。 -
您设置的 byte[] 大小与 DataLine 中的缓冲区无关。您需要在 open() 方法中包含大小来设置 DataLine 缓冲区大小,例如.open(大小)。每帧 4 字节的 88200 字节和每秒 44100 帧占半秒延迟。缩短太多可能会导致丢失,但我很确定您可以设置具有更少延迟的安全值。请参阅下面的答案。
-
使用 JackAudio 或 ALSA API 进行实时采集和回放。
标签: java audio real-time javasound low-latency