Невозможно ничего сделать во время записи в SourceDataLine

Я несколько новичок в аудио на Java. Что я пытаюсь сделать, так это воспроизвести аудио, я хочу перерисовать свой JComponent, но SourceDataLine блокирует все остальные строки кода, включая другие потоки. Вот мой метод play()

public void play()
{
    final AudioFormat af =new AudioFormat(Note.SAMPLE_RATE, 8, 1, true, true);
    SourceDataLine line;
    try {
        line = AudioSystem.getSourceDataLine(af);
        line.open(af, Note.SAMPLE_RATE);
        line.start();
        byte[] arr=data;
        for(int position=0;position<arr.length;position++)
        {
            byte[] out={arr[position]};
            line.write(out, 0, 1);        //Blocks all user input (Mouse and Keyboard)
            this.repaint();               //Need to repaint JComponent here
        }
        line.drain();
        line.close();
    } catch (LineUnavailableException e) {
        e.printStackTrace();
    }
}

person user3062600    schedule 27.01.2014    source источник


Ответы (1)


Очевидно, вы звоните play в потоку отправки событий. Например, возможно, вы вызываете его из события действия, сгенерированного нажатием кнопки. Вам нужно запустить новый поток для цикла воспроизведения, иначе в графическом интерфейсе ничего не произойдет, пока воспроизведение не закончится.

По крайней мере, что-то вроде:

new Thread(new Runnable() {
    @Override
    public void run() {
        play();
    }
}).start();

Тем не менее, вам следует прочитать несколько руководств по параллелизму (например, этот) поскольку кажется, что вы будете получать доступ к полям в разных потоках (например, что бы ни было byte[] arr = data;).

Вы также можете использовать SwingWorker, который частично интегрирован с Swing. . У меня есть несколько более длинный пример кода в Интернете, который показывает пример цикла воспроизведения с использованием SwingWorker: Демо Waveform. Цикл воспроизведения находится вокруг строки 310.

person Radiodef    schedule 27.01.2014