我的游戏通过通常的方法播放声音:
sdl.open(); sdl.start(); sdl.write(data, 0, data.length); sdl.drain(); sdl.stop(); sdl.close();
用户可以(异步)取消播放:
sdl.stop();
这种取消在Windows上效果很好,但是对于一个运行带有Java 6的OSX 10.5.8的用户,该程序将挂起。Threaddump显示播放线程在rain()内部com.sun.media.sound.MixerSourceLine.nDrain。如果用户没有中断声音,则声音会很好地完成,并且应用程序将继续。
com.sun.media.sound.MixerSourceLine.nDrain
我的问题是:
sdl.close()
编辑 :我发现此错误报告具有类似的效果,但页面说它是固定的。
作为参考,该示例close()通常在Java 5或6下使用退出。
close()
除非已在初始线程上正常关闭Java 5和6,否则在EDT上调用stop()而不是close()Java会同时挂起Java 5和6 line。这似乎是drain()阻塞的预期结果,因为停止的线路无法耗尽。
stop()
line
drain()
import java.awt.EventQueue; import javax.sound.sampled.AudioFormat; import javax.sound.sampled.AudioSystem; import javax.sound.sampled.LineUnavailableException; import javax.sound.sampled.SourceDataLine; import javax.swing.JOptionPane; /** * @see https://stackoverflow.com/questions/7803310 * @see https://stackoverflow.com/questions/2065693 */ public class Tone { public static void main(String[] args) throws LineUnavailableException { final AudioFormat af = new AudioFormat(Note.SAMPLE_RATE, 8, 1, true, true); final SourceDataLine line = AudioSystem.getSourceDataLine(af); EventQueue.invokeLater(new Runnable() { public void run() { JOptionPane.showMessageDialog(null, "Halt"); //line.stop(); // stops and hangs on drain line.close(); } }); line.open(af, Note.SAMPLE_RATE); line.start(); for (Note n : Note.values()) { play(line, n, 500); play(line, Note.REST, 10); } line.drain(); line.close(); } private static void play(SourceDataLine line, Note note, int ms) { ms = Math.min(ms, Note.SECONDS * 1000); int length = Note.SAMPLE_RATE * ms / 1000; int count = line.write(note.data(), 0, length); } }
需要Note。
Note