Elite_Dragon1337
Elite_Dragon1337

Reputation: 348

clip.open(AudioInputStream) sometimes hangs for a few seconds

Clip clip = AudioSystem.getClip();
AudioInputStream a = AudioSystem.getAudioInputStream(new File(path));
clip.open(a);

This is the code that I'm using to play audio in my program. From Java profiling I can see that on average the clip.open() call takes less than 1ms. However, occasionally at random times it will block for a couple of seconds causing lag.

The screenshot below shows my Java profiler. As you can see, the exact same method is called 316 times with no issue. But one time it hangs for 2.4 seconds on Clip.open()

Notice how Clip.open doesn't even show in the bottom one because the time spent is less than 0.1ms.

The clips that I'm playing are all around 100KB in size, I don't understand why it works fine 316 calls but then one time it hangs.

Profiler

I've also tried not closing the clips but leaving them all open, even then the problem still occurs.

Upvotes: 1

Views: 356

Answers (1)

Phil Freihofner
Phil Freihofner

Reputation: 7910

Usually programmers .open() a Clip well in advance of when they want to play it. The moment of playback should only involve a .play() command and nothing else. If you both "open" and "play" the clip in consecutive commands, the play() can be delayed considerably because the file has to be loaded into memory in its entirety before the play() command will execute. For this reason, if you can't afford the memory for a Clip, then a SourceDataLine will execute more quickly as it only needs to load a buffer's worth into memory before the play() will execute.

Perhaps you already know about that aspect of Clips and that wasn't the issue. (You mention playing the Clips without having closed them.) Well another fact of Java is that there are no real-time guarantees. The system does do a good job of keeping a file or clip playing, but controlling the exact starting point is hard. This is because of several factors, one of which is the time spent juggling multiple threads and processes. For example, if a garbage collection command gets the call right before your sound call, the sound will have to wait until that segment is done and the processor gives the sound thread the priority.

There are other factors impacting real-time performance as well, which are well laid out in the following paper: Real Time Low Latency Processing in Java

Depending on what your goal is, there are ways to take advantage of the sound thread to improve timing accuracy, by "counting sound frames" and running events when a specific sound frame is up for processing, from the operation that is doing that processing. But in general, communications between the audio and other threads is going to be subject to some jitter.

Upvotes: 2

Related Questions