1

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

1 回答 1

1

显然,您正在调用playEvent Dispatch Thread。例如,也许您从按钮按下生成的动作事件中调用它。您需要为播放循环启动一个新线程,否则在播放结束之前,GUI 上不会发生任何事情。

至少,类似:

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

但是,您应该阅读一些并发教程(例如这个),因为您似乎将跨不同线程访问字段(例如任何线程byte[] arr = data;)。

您可能还希望使用与 Swing 有一些集成的SwingWorker 。我有一个有点长的在线代码示例,它显示了一个使用 SwingWorker 的播放循环示例:WaveformDemo。播放循环在第 310 行附近。

于 2014-01-27T05:25:55.533 回答