Ответ 1
Кажется, что clip.start() иногда возвращается непосредственно перед запуском события с ошибкой (?), и в этом случае дренаж не влияет. По обходному пути мы можем использовать Listener, чтобы поймать событие START:
Обходное решение:
Mixer mixer = AudioSystem.getMixer(null);
AudioFormat format = new AudioFormat(44100, 8, 1, true, false);
DataLine.Info info = new DataLine.Info(Clip.class, format);
try {
// Create a sound of 1 second
Clip clip = (Clip)mixer.getLine(info);
//Workaround part 1
clip.addLineListener(new LineListener() {
@Override
public void update(LineEvent event) {
if (event.getType() == Type.START)
synchronized (clip) {
clip.notify();
}
}
});
byte[] b = new byte[44100];
for(int i=0; i<b.length; i++)
b[i] = (byte) (50*Math.sin(i/10.0));
clip.open(format, b, 0, b.length);
clip.setFramePosition(0);
//Workaround part 2
synchronized (clip) {
clip.start();
clip.wait();
System.out.println("Started");
}
clip.drain();
System.out.println("Drained");
} catch(LineUnavailableException | InterruptedException lue) { lue.printStackTrace(); }