我正在开发一款游戏,并且我有一些问题会多次播放相同的声音,就像你激活一个已播放的声音一样,它不能取消第一个声音。我在Stackoverflow上找到的解决方案是将其读入一个字节数组,我按以下方式执行:
public SoundObject(AudioInputStream audioIn) {
try {
af = audioIn.getFormat();
size = (int) (af.getFrameSize() * audioIn.getFrameLength());
audio = new byte[size];
info = new DataLine.Info(Clip.class, af, size);
audioIn.read(audio, 0, size);
} catch (IOException e) {
e.printStackTrace();
}
}
public void playSound() {
try {
Clip localSound = (Clip) AudioSystem.getLine(info);
localSound.open(af, audio, 0, size);
localSound.start();
} catch (LineUnavailableException e) {
e.printStackTrace();
}
}
直到现在我才尝试将它导出到一个jar文件中,因为某种原因,jar文件出现了一个字节数组的问题,导致声音在几毫秒后切断,我设法找到一个在有人提出以下解决方案的同一问题上发帖:
public SoundObject(String filePath) {
try {
AudioInputStream audioInputStream = AudioSystem.getAudioInputStream(Loader.class.getResource(filePath));
clip = AudioSystem.getClip();
clip.open(audioInputStream);
} catch (IOException e) {
e.printStackTrace();
} catch (LineUnavailableException e) {
e.printStackTrace();
} catch (UnsupportedAudioFileException e) {
e.printStackTrace();
}
}
// Play the sound in a separate thread.
public void playSound() {
Runnable soundPlayer = new Runnable() {
@Override
public void run() {
try {
clip.setMicrosecondPosition(0);
clip.start();
} catch (Exception e) {
e.printStackTrace();
}
}
};
new Thread(soundPlayer).start();
}
使用第二种方法适用于jar文件,但问题是声音不像以前那样好玩,我有一个拍摄功能,如果拍得很快,这个方法并不总是选择当我按空间拍摄时,有时无法发出声音。因此,对于这两种解决方案,我必须选择具有不可靠的声音而不能始终播放,或者我无法将其导出到可运行的JAR。
有没有人有这类问题的经验?
编辑:这是一个剪辑,向您展示2个罐子的工作原理:https://www.youtube.com/watch?v=wZPOIhHZSJM&
答案 0 :(得分:0)
我建议尝试使用TinySound库。它是免费代码,可在github上找到。此代码提供了一个最小的混音器,并且可以同时播放剪辑。
我很难搞清楚代码可能出现的问题。我还制作了一个我在游戏中使用的调音台,它支持剪辑的并发播放。我将声音存储在介于-1到1之间的浮点数。每个播放实例从预先制作的池(它限制并发播放的数量)中获取一个光标,该光标跟踪浮点数组中的位置,并在同时进行查询和递增循环,其中各种声音被加在一起(简单添加)并转换为通过SourceDataLine输出的字节。如果你决定走这条路,这就是基本计划。
通过创建一个线程池,让你的声音尽可能接近准备在被叫时播放,你可以在第二次设置中获得更高的效率。使用混音器,您只需要一个音频线程。
第一个例子中是否有任何错误?从给出的代码中,我没有看到为什么声音因使用jar而被切断。切断它们的东西,比如另一个声音,还是调用线程的结尾?