Java声音API : Attempt to Do Live Microphone Input Monitoring is Slow

标签 java audio real-time javasound low-latency

我认为 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 音频接口(interface)能够通过计算机处理实时监控,因为当我与 Logic Pro X 进行并排比较时,延迟很小 - 我感觉不到延迟完全没有。
  • 我尝试减小/增大 byte[] 大小,但并没有解决这个问题。

我的结论是,这是我遇到的 Java 代码问题。提前致谢。

最佳答案

涉及多个缓冲区!

当您打开 SourceDataLine 和 TargetDataLine 时,我建议您使用指定缓冲区大小的表单。但我不知道该推荐什么尺寸。我还没有充分尝试过这个问题,不知道安全管道麦克风输入的最佳尺寸是多少——我的经验更多是实时合成。

无论如何,这样如何:定义 data[] 的长度并在行打开方法中使用相同的长度。尝试使用 1024 或其倍数之类的数字(同时确保字节数可以除以每帧字节数,根据您使用的格式,每帧字节数看起来为 4)。

int bufferLen = 1024 * 4;  // experiment with buffer size here

byte[] data = new byte[bufferLen];
sourceLine.open(bufferLen);
targetLine.open(bufferLen); 

此外,也许 run() 中的代码最好放在其他地方,以免在管道启动之前添加到所需的处理中。数组 data[] 和 int readBytes 可以是实例变量并准备好滚动,而不是在 run() 中使用,这可能会增加延迟。

无论如何,这些都是我会尝试的事情。

关于Java声音API : Attempt to Do Live Microphone Input Monitoring is Slow,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41112720/

相关文章:

java - 在后台使用 Java 打开 URL

c# - 处理和嵌入数据的好方法?

python - 为什么我在导入 AudioSegment 时出错?

python - 从socketIo python发出事件

java执行数组计算

java - 无法从 JFrame 正确创建 JPanel

java - CPLEX 收入最大化

audio - 使用Spotify API增强播放

c - 编程精确计时器,每 x 秒调用一次 c 语言函数

java - 用于车辆位置的实时网站和Java中的数据库R/W