写入SourceDataLine时无法执行任何操作 [英] Cannot do anything while writing to a SourceDataLine

查看:116
本文介绍了写入SourceDataLine时无法执行任何操作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对Java音频有些陌生.我正在尝试做的是在播放音频时,我想重绘我的JComponent,但是SourceDataLine阻止了所有其他代码行,包括其他线程. 这是我的play()方法

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

推荐答案

很明显,您正在play .html"rel =" nofollow>事件调度线程.例如,也许您从按钮按下生成的动作事件中调用它.您需要为回放循环启动一个新线程,否则在回放结束之前,GUI上不会发生任何事情.

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.

至少,类似:

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

但是,您应该阅读一些并发教程(例如这本),似乎您将跨不同的线程访问字段(例如byte[] arr = data;是什么).

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).

您可能还希望使用 SwingWorker ,其中包含一些内容与Swing集成.我在网上有一个更长一些的代码示例,其中显示了一个使用SwingWorker的播放循环的示例:

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.

这篇关于写入SourceDataLine时无法执行任何操作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆