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\$
6
  • 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
    Commented Dec 7, 2017 at 14:23
  • \$\begingroup\$ Your code doesn't specify the type/class for the variable line - what is it? \$\endgroup\$
    – Pikalek
    Commented Dec 7, 2017 at 14:39
  • \$\begingroup\$ @Pikalek the SourceDataLine. I'm using the Java sound library from standard library, sorry for missing information \$\endgroup\$
    – ice1000
    Commented Dec 7, 2017 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
    Commented Dec 7, 2017 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
    Commented Dec 7, 2017 at 15:07

1 Answer 1

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\$
2
  • \$\begingroup\$ Really thanks for your help. I'll mark your answer as accepted since you've provide useful information. \$\endgroup\$
    – ice1000
    Commented Dec 8, 2017 at 15:02
  • \$\begingroup\$ @ice1000 I hope some of it really helps actually \$\endgroup\$
    – dot_Sp0T
    Commented Dec 8, 2017 at 15:08

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .