SourceDataLine.drain () висит на OSX - PullRequest
       1

SourceDataLine.drain () висит на OSX

1 голос
/ 18 октября 2011

Моя игра воспроизводит звук обычным способом:

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

И пользователь может отменить воспроизведение (асинхронно):

sdl.stop();

Эта отмена прекрасно работает под Windows, но для одного пользователя, работающего под управлением OSX 10.5.8 с Java 6, программа зависает. Threaddump показывает, что поток воспроизведения находится внутри стока (): com.sun.media.sound.MixerSourceLine.nDrain. Если пользователь не прерывает звук, он красиво завершается и приложение продолжается.

Мои вопросы:

  • Это ошибка OSX Java?
  • Должен ли я использовать sdl.close() вместо остановки?
  • Есть предложения или опыт по обходному пути?

Редактировать : я нашел этот отчет об ошибке с похожими эффектами, но на странице написано, что он исправлен.

1 Ответ

1 голос
/ 18 октября 2011

Для справки, этот пример с использованием 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.

...