剪辑在Java中播放带有坏滞后的WAV文件

时间:2014-02-19 07:58:41

标签: java audio wav javasound

我编写了一个读取WAV文件(大小约为80 MB)并播放该代码的代码。问题是声音播放严重(极端滞后)。你能告诉我这是什么问题吗?

这是我的代码: (我在Jframe构造函数中调用doPlay函数)

private void doPlay(final String path) {
    try {
        stopPlay();
        InputStream is = new FileInputStream(path);
        InputStream bufferedIn = new BufferedInputStream(is);
        AudioInputStream ais = AudioSystem.getAudioInputStream(bufferedIn);
        AudioFormat format = ais.getFormat();
        // this is the value of format.
        // PCM_SIGNED 44100.0 Hz, 16 bit, stereo, 4 bytes/frame, little-endian
        DataLine.Info info = new DataLine.Info(Clip.class, format);
        clip = (Clip)AudioSystem.getLine(info);
        clip.open(ais);
        clip.start();
    } catch (Exception e) {
        stopPlay();
        e.printStackTrace();
    }
}

2 个答案:

答案 0 :(得分:7)

问题是您需要先加载剪辑 才能播放它。剪辑在播放之前完全加载到内存中。

换句话说,在播放剪辑之前,一切都应该发生在clip.open()之前。当您准备播放Clip时,您应该使用的唯一命令是clip.start()。要重放剪辑,请将其光标位置设置回到开始并调用clip.start()。

如果一个Clip足够短,你可以在播放它们的同时打开它们(加载它们)的低效编码实践。如果你真的想从一个文件而不是从内存中播放,请使用SourceDataLine,它将比Clip对大文件的启动速度快得多。

Clip:在播放之前必须加载到内存中,一旦加载,它就会以最小的cpu播放。专为小型和重复使用的声音文件而设计。

SourceDataLine:从文件位置播放,立即启动,消耗非常少的内存(远小于Clip),但由于文件读取而使用比Clip略多的cpu。最适合大型和单播音频。

LAG的另一个来源:第一次调用声音文件时,由于从编译的代码执行,它运行速度稍慢。通过重用,声音代码被放入内存并以最小的延迟执行。因此,有时我会在程序开始时播放“静音”声音以“灌注泵”,这样当需要听到的第一个声音播放时,播放的延迟就会减少。

答案 1 :(得分:3)

实际上你的代码应该可以正常工作(在带有+ 80mb音频文件的JFrame构造函数中测试它),所以我只能给出一些建议:

  1. 您是否尝试使用不同的音频文件和不同的音频格式(例如aiff)来查看这是否有所不同?还可以使用较小尺寸的音频文件尝试使用您的代码。
  2. 使用Clip类时,音频数据会加载到内存中。你确实有足够的可用内存用于整个文件吗?您是否尝试过增加JVM heap size
  3. 您的代码是否涉及任何其他后台线程/计算,这可能会导致过多的CPU工作负载?