SourceDataLine.drain () freezes on OSX

My game plays sound using the usual method:

sdl.open();
sdl.start();
sdl.write(data, 0, data.length);
sdl.drain();
sdl.stop();
sdl.close();

And the user can cancel the playback (asynchronously):

sdl.stop();

This cancellation works fine under Windows, but for one user using OSX 10.5.8 with Java 6, the program freezes. Threaded hole indicates that thread play is drainage inside () com.sun.media.sound.MixerSourceLine.nDrain. If the user does not interrupt the sound, it finishes perfectly and the application continues.

My questions:

  • Is this an OSX Java bug?
  • Should it be used sdl.close()instead of stopping?
  • Any suggestions or workaround experience?

Change . I found this error report with similar effects, but the page says it has been fixed.

+1
1

, close() Java 5 6.

stop(), close(), EDT Java 5, 6, 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.

+1

Source: https://habr.com/ru/post/1662870/


All Articles