I am using the following code for loading a clip (javax.sound.sampled.Clip)
def createClip(file:String):Clip = {
val clip = AudioSystem.getClip()
clip.open(AudioSystem.getAudioInputStream(new File(s"sounds/$file.wav")))
clip
}
Its written in Scala but I guess anyone not familiar with scala but java will see that its basically the same, as one would do with java.
My attempt was to make it effortless to play a sound like this
createClip("example_WAV_File").start()
Since I will create a new Clip, each time I call a sound file, I thought there shouldn't be any problems concerning rewinding a clip etc. However in an actual Application (a Game), I used this library, to handle the sounds resulting of a Punch and all those stuff. Now here is the thing, when (lets say e.g.) punching several times, some when I will get
Exception in thread "Thread-58" javax.sound.sampled.LineUnavailableException: line with format PCM_SIGNED 44100.0 Hz, 16 bit, stereo, 4 bytes/frame, little-endian not supported.
I once ran into a similar Error but that was about the bit encoding being above 16-bits. Since my file has 16-bit encoding I have no clue what this could be...
As said above, the Error only occurs when several clips are played. I figured, that this could indicate a memory problem. I naively thought, that the garbage collector would do all the work for me, as the clip would have lost any reference when leaving its scope.
My initial solution was, to hold a reference to any sound I am going to play, and only rewind it when another instance requires an already played sound. This solution would never break but it was not really able to play the same clip two times. Thats why I switched to loading a clip several times when required.
I figured, that I probably should use a close() method on the clip.
val clip = createClip("example_WAV_file")
clip.start()
clip.close()
This actually solved my Problem, enhancing my guess, that it is probably memory related, but also, now the clip would stop immediately after starting it.
Do I really need to create a thread for each clip, waiting for the clip.getMicrosecondLength() time to close it? That sounds rather crappy.
Only option left -> I am using the sound API really really wrongly, even though I thought, that I was using it just the way some tutorials showed me. So where is my particular mistake? Or what is the solution to being able to play the same clip two times, at the same time?