写入SourceDataLine时无法执行任何操作 [英] Cannot do anything while writing to a 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();
}
}
推荐答案
很明显,您正在
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屋!