Why does Java Sound behave differently when I run from a .jar?

╄→尐↘猪︶ㄣ 提交于 2019-12-01 22:38:14

It is likely the loading of the byte[] that is the problem.

I don't know if this is directly related to the problem, but it is somewhat self-defeating to instantiate a new Clip every time you play that Clip. The point of a Clip is to be able to start it without having to load it first. As you are currently set up, your Clip won't even start playing until it has been fully loaded. (SourceDataLines start playing more quickly than Clips when you include the instantiation steps, as they don't wait for all the data to load before commencing.)

So, as a first step to solving this problem, I would suggest instantiating the various Clips prior to the play call. I believe if you do this right, and the clip start is in its own thread, it can be allowed to run its course with no need to mess with Thread.sleep. You just have to reposition the clip back to its starting frame prior to the next start. (Can be done in the play call just prior to the start.

Once your usage of Clip has become more conventional, it might be easier to figure out if there is something else going on.

I am also unclear why the source .wav files are being loaded into byte arrays as an intermediate step. Might as well load them directly into Clips. They will take up pretty much the same amount of space either way, given the preponderance of PCM data, and be ready to go when you call them.

Disabling error messages is also self-defeating. Java could be trying to give you a perfectly good diagnostic, maybe not in this particular sleep call (I know, I know) but if you do this often, who knows. :)

Amplifying on @Anrew's and @Phil's answers, there's an outline of obtaining a Clipand playing it asynchronously below. There's a complete example here.

AudioInputStream audioInputStream = AudioSystem.getAudioInputStream(...);
Clip clip = AudioSystem.getClip();
clip.open(audioInputStream);
...
// Play the sound in a separate thread.
private void playSound() {
    Runnable soundPlayer = new Runnable() {

        @Override
        public void run() {
            try {
                clip.setMicrosecondPosition(0);
                clip.start();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    };
    new Thread(soundPlayer).start();
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!