Clip plays WAV file with bad lag in Java

自作多情 提交于 2019-12-06 05:00:47

问题


I've written a code that read a WAV file (size is about 80 mb) and plays that. The problem is that sound plays badly (extreme lags). Can you please tell me what's the problem?

Here's my code: (I call the doPlay function inside a Jframe constructor)

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();
    }
}

回答1:


The problem is that you need to load the Clip prior to playing it. Clips are loaded into memory completely before they can be played.

In other words, everything up to clip.open() should occur well before it is time to play the clip. When you are ready to play the Clip, the only command you should use is clip.start(). To replay the clip, set its cursor position back to the start and call clip.start().

If a Clip is short enough, you can get away with the inefficient coding practice of opening them (loading them) at the same time as when you play them. If you really want to play from a file instead of from memory, use SourceDataLine, and it will start much faster than the Clip will for larger files.

Clip: has to be loaded into memory before it can play, once loaded, it plays with minimal cpu. Designed for small, and reused sound files.

SourceDataLine: plays from file location, starts immediately, consumes very little memory (much less than Clip) but uses slightly more cpu than Clip because of the file reading. Best for larger and single-play audio.

Another source of LAG: first time a sound file is called, it runs a little slower because of executing from compiled code. With reuse, the sound code is put into memory and executes with minimal lag. Thus, sometimes I play a "silent" sound at the start of a program to "prime the pump" so that when the first sound that needs to be heard plays, it plays with less lag.




回答2:


Actually your code should work fine (tested it from inside a JFrame constructor with an +80mb audio file), so I can only give a few suggestions:

  1. Did you try your code with a different audio file and with a different audio format (e.g. aiff) to see if this makes any difference? Also try your code with an audio file of smaller size.
  2. When using the Clip class, the audio data gets loaded into memory. Do you certainly have enough available memory for the whole file? Did you try increasing the JVM heap size?
  3. Does your code involve any other background threads/computations, that could potentially result in too much cpu workload?


来源:https://stackoverflow.com/questions/21874361/clip-plays-wav-file-with-bad-lag-in-java

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!