0
\$\begingroup\$

I know JavaSound API like this:

audioInputStream = AudioSystem.getAudioInputStream(file);
AudioFormat audioFormat = audioInputStream.getFormat();
DataLine.Info info = new Info(SourceDataLine.class, audioFormat);
sourceDataLine = (SourceDataLine) AudioSystem.getLine(info);
sourceDataLine.open();
sourceDataLine.start();
floatVoiceControl.setValue(-20);
byte[] buf = new byte[0xFF];
int onceReadDataSize = 0;

While file is the File object.

But when I tried to play some very small audio very frequently (say, the audio played when a small enemy is killed), it blocks my main thread and make the game very slow.
Is there any alternative or workarounds? I prefer something inside the Java's standard library, since I'm developing a game engine based on Swing.

\$\endgroup\$
  • 1
    \$\begingroup\$ If you're running blocking methods on the main thread then it will block, that's the whole point of blocking and non-blocking APIs... \$\endgroup\$ – dot_Sp0T Dec 7 '17 at 14:23
  • \$\begingroup\$ Your code doesn't specify the type/class for the variable line - what is it? \$\endgroup\$ – Pikalek Dec 7 '17 at 14:39
  • \$\begingroup\$ @Pikalek the SourceDataLine. I'm using the Java sound library from standard library, sorry for missing information \$\endgroup\$ – ice1000 Dec 7 '17 at 14:57
  • \$\begingroup\$ @dot_Sp0T no, I opened a new thread to run the code and it's making my UI thread slow, so I used the word block. I'll change it \$\endgroup\$ – ice1000 Dec 7 '17 at 14:58
  • 1
    \$\begingroup\$ @ice1000 please either update your samples on here to show how you run the sound on other threads, or even better provide an sscce \$\endgroup\$ – dot_Sp0T Dec 7 '17 at 15:07
2
\$\begingroup\$

From the code you provide it is not discernible if you run the sound on your main-thread or on a worker thread. I will just assume that you are using a ThreadPoolExecutor or similar so you don't have to expensively create a new thread every time you want to play some sound.

From reading the Javadoc of the DataLine Interface I understad that the start() method you use in line #6 of your codesample initiates some I/O operations for reading the audiodata from the underlying file:

Allows a line to engage in data I/O.

Excerpt from the javadoc of the start() method

Digging further into the javax soundAPI sources we find that the implementation of AudioSystem.getAudioInputStream(File) works with a list of AudioFileReaders for which there are no known implementations, which means without knowing what sort of audio-file you're trying to load we cannot reasonably dig any much further.


Conclusion:

From our research into the APIs and sources, and from your statement that:

But when I tried to play some very small audio very frequently...

emphasis mine

We can reasonably assume that you're getting limited by I/O operation limitations. You might want to see if you can load the sound-file into the heap and play it from memory instead of playing it from disk.

\$\endgroup\$
  • \$\begingroup\$ Really thanks for your help. I'll mark your answer as accepted since you've provide useful information. \$\endgroup\$ – ice1000 Dec 8 '17 at 15:02
  • \$\begingroup\$ @ice1000 I hope some of it really helps actually \$\endgroup\$ – dot_Sp0T Dec 8 '17 at 15:08

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.