Clip在Java中播放滞后性差的WAV文件

Clip在Java中播放滞后性差的WAV文件,java,audio,wav,javasound,Java,Audio,Wav,Javasound,我写了一段代码,可以读取WAV文件(大小约为80MB)并播放它。问题是声音播放不好(极端滞后)。你能告诉我有什么问题吗 这是我的密码: (我在Jframe构造函数中调用doPlay函数) 实际上,您的代码应该可以正常工作(在带有+80mb音频文件的JFrame构造函数中进行了测试),因此我只能给出一些建议: 您是否使用不同的音频文件和不同的音频格式(如aiff)尝试了代码,以查看这是否有任何区别?还可以使用较小的音频文件来尝试您的代码 使用Clip类时,音频数据将加载到内存中。您是否确实有足够的

我写了一段代码,可以读取WAV文件(大小约为80MB)并播放它。问题是声音播放不好(极端滞后)。你能告诉我有什么问题吗

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


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

  • 您是否使用不同的音频文件和不同的音频格式(如aiff)尝试了代码,以查看这是否有任何区别?还可以使用较小的音频文件来尝试您的代码
  • 使用Clip类时,音频数据将加载到内存中。您是否确实有足够的可用内存存储整个文件?你有没有试着增加工资
  • 您的代码是否涉及可能导致cpu工作量过大的任何其他后台线程/计算

  • 问题是,您需要在播放之前加载剪辑。剪辑在播放之前会完全加载到内存中

    换句话说,clip.open()之前的所有操作都应该在播放该剪辑之前发生。准备播放该剪辑时,应使用的唯一命令是Clip.start()。要重播剪辑,请将其光标位置设置回起始位置,然后调用clip.start()

    如果一个剪辑足够短,那么在播放的同时打开(加载)它们的低效编码实践可以避免。如果您真的想从文件而不是内存播放,请使用SourceDataLine,它将比较大文件的剪辑启动快得多

    剪辑:必须加载到内存中才能播放,一旦加载,它将以最小的cpu播放。专为小型可重复使用的声音文件设计

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


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

    是的,代码每0.1秒同时绘制近100个对象,然后我建议从代码中删除对象的绘制,看看这是否解决了问题。如果是这样,那么延迟可能与音频播放无关,而是与对象绘图代码有关。问题是文件的大小。对于较小的文件,代码运行良好。但是为什么您的代码使用相同大小的文件呢?如果不查看文件和其他代码,很难判断。你们的电脑规格是什么?我在一台相当旧的计算机上测试了它,该计算机使用Eclipse中的Windows XP、2.7 GHz、2 GB ram和JRE 7。其他同样大小的音频文件是否也会导致延迟?或者仅仅是这个文件?我还添加了用于测试的完整代码-看看这个简化代码是否也会出现延迟。解释得很好。我把它标为答案。谢谢
    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();
        }
    }