Cannot do anything while writing to a SourceDataLine

我的未来我决定 提交于 2019-12-13 02:08:43

问题


I am somewhat new to audio in Java. What I am trying to do is as I am playing audio, I want to repaint my JComponent, but the SourceDataLine blocks all other lines of code including other Threads. Here is my play() method

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();
    }
}

回答1:


Evidently you're calling play on the Event Dispatch Thread. For example, maybe you call it from an action event generated by a button press. You need to start a new thread for the playback loop, otherwise nothing can happen on the GUI until playback ends.

At the very least, something like:

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

However, you should read some concurrency tutorials (like this one) as it seems you will be accessing fields across different threads (such as whatever byte[] arr = data; is).

You may also wish to use SwingWorker which has some integration with Swing. I have a somewhat lengthier code example online that shows an example of a playback loop using SwingWorker: WaveformDemo. The playback loop is around line 310.



来源:https://stackoverflow.com/questions/21373231/cannot-do-anything-while-writing-to-a-sourcedataline

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!