我正在使用以下代码加载一个剪辑(javax.sound.sampled.Clip)
def createClip(file:String):Clip = {
val clip = AudioSystem.getClip()
clip.open(AudioSystem.getAudioInputStream(new File(s"sounds/$file.wav")))
clip
}
这段代码是用Scala编写的,但我想熟悉Java而不熟悉Scala的人也会发现它基本相同,就像使用Java一样。
我的目标是使播放声音变得轻松无阻,就像这样。
createClip("example_WAV_File").start()
由于我将创建一个新的剪辑,每次调用音频文件时,我认为关于倒带剪辑等方面不应该有任何问题。然而,在实际的应用程序(游戏)中,我使用了这个库来处理由拳击等操作产生的声音。现在问题来了,当我多次进行拳击时,有时会出现以下错误:
“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.”
我曾经遇到过类似的错误,但那是关于位编码超过16位的问题。由于我的文件具有16位编码,我不知道这可能是什么原因...
如上所述,只有在播放几个剪辑时才会出现此错误。我想,这可能是一个内存问题。我天真地以为,垃圾收集器会为我完成所有工作,因为当离开其范围时,剪辑将失去任何引用。
我的初始解决方案是,保留对我要播放的任何声音的引用,并仅在另一个实例需要已播放的声音时重置它。这个解决方案永远不会失败,但无法真正播放同一段剪辑两次。这就是为什么我转而在需要时多次加载剪辑。
我想,我可能应该在剪辑上使用close()方法。
val clip = createClip("example_WAV_file")
clip.start()
clip.close()
这实际上解决了我的问题,增强了我的猜测,即它可能与内存有关,但现在剪辑在开始后立即停止。
我真的需要为每个剪辑创建一个线程,等待clip.getMicrosecondLength()的时间来关闭它吗?听起来相当糟糕。
唯一的选择是->我实际上非常错误地使用了声音API,尽管我认为我只是按照一些教程所示的方式使用它。那么我的特定错误在哪里?或者能够同时播放同一剪辑的解决方案是什么?