停止并启动Runnable冻结应用程序2-10秒

时间:2014-05-02 13:03:21

标签: java audio runnable

我的应用程序的主要核心是Runnable,它允许音频反馈(用户说话和听到他的声音),而反馈由三个Jsliders控制(音频延迟,音量,音高变换)。

问题是当处理第一个JSlider(音频延迟)时,程序会冻结一段时间(2-10秒)。在我看来,这是因为在处理时,Runnable停止(),并启动一个新的。

我使用 TarsosDSP 包。 Runnable称为Dispatcher。

这3个Jsliders定义/提供3个变量,这些变量由Dispatcher使用的某些Class对象使用,以便进行反馈的操作(延迟,音量,音高变化)。

3个变量:

currentFactor (用于音高移位的Jslider), sampleRate (..用于音频延迟), gainValue (.. for volume)

活动顺序:

1。点击试用按钮 - >创建Dispatcher(音频反馈开始)

`

trial.addActionListener(new ActionListener() {
    @Override
    public void actionPerformed(ActionEvent arg0) {

        // Definition of the 2 variables: currentFactor and sampleRate, from the Jsliders(freqshift, sldelay)
        currentFactor = gridbagLayout.freqshift.getValue() / 100.0;
        int delayFactor = gridbagLayout.sldelay.getValue();
        double df = (double) delayFactor / (double) 100;

        sampleRate = 44100 * df;

        AudioFormat format;
        try {
            format = new AudioFormat(44100, 8, 1, true, true);

            // RateTransposer class is used from the runnable Dispatcher 
            // in order to alter the feedback's pitch, with CurrentFactor's value                           
            rateTransposer = new RateTransposer(currentFactor);
            gain = new GainProcessor(1.0);

            // Here, the 3rd variable gainValue is used by GainProcessor
            //  class (gain), which is used from the Dispatcher, 
            // in order to alter the feedback's volume, according to gainValue's value                                                             
            gain.setGain(gridbagLayout.volume.getValue() / 1.0);

            audioPlayer = new AudioPlayer(format);

            // Here, an other class (wsola) used by Dispatcher, is 
            // constructed by SampleRate and CurrentFactor variables  
            wsola = new WaveformSimilarityBasedOverlapAdd(Parameters
                    .musicDefaults(currentFactor, sampleRate));

            DataLine.Info dataLineInfo = new DataLine.Info(
                    TargetDataLine.class, format);

            Mixer.Info mixerInfo = Shared.getMixerInfo(false, true)
                    .get(1);
            Mixer mixer = AudioSystem.getMixer(mixerInfo);
            line = (TargetDataLine) mixer.getLine(dataLineInfo);
            line.open(format, wsola.getInputBufferSize());

            // A line for audio input starts. 
            line.start();
            final AudioInputStream stream = new AudioInputStream(line);

            // A Dispatcher runnable is created from WSOLA 
            dispatcher = new AudioDispatcher(stream, wsola
                    .getInputBufferSize(), wsola.getOverlap());

            // RateTransposer, GainProcessor, WSOLA class objects are attached 
            // to Dispatcher
            wsola.setDispatcher(dispatcher);
            dispatcher.addAudioProcessor(wsola);
            dispatcher.addAudioProcessor(rateTransposer);
            dispatcher.addAudioProcessor(gain);
            dispatcher.addAudioProcessor(audioPlayer);


            Thread t = new Thread(dispatcher);

            // All process() methods of the attached objects (RateTransposer, 
            // GainProcessor, WSOLA and more) are executed. That enables
            // the update of the 3 variables, thus alteration of the feedback                          
            t.start();

        } catch (UnsupportedAudioFileException e) {
            e.printStackTrace();
        } catch (LineUnavailableException e) {
            e.printStackTrace();
        }
    }
});

2. 之后,用户可以控制三个Jsliders。 (音频反馈被改变)

当我控制Delay Jslider时:

public ChangeListener delaySettingChangedListener = new ChangeListener() {
    @Override
    public void stateChanged(ChangeEvent arg0) {

        int delayFactor = sldelay.getValue();

        df = (double) delayFactor / (double) 100;

        // Here, sampleRate variable is updated
        panelbuttons.sampleRate = 44100 * df;
        // And then, I stop the current runnable Dispatcher, and start a new one, 
        //according to the updated variable               
        startFile();
    }
};

StartFile代码():

private void startFile() {
    // stop the current thread
    if (panelbuttons.dispatcher != null)
        panelbuttons.dispatcher.stop();

    if (timer == null) {
        timer = new Timer(400, new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                // and start a new one, after some time, in order
                // for the previous runnable to end/withdraw
                startFile0();
            }
        });
    }
    timer.stop();
    timer.setRepeats(false);
    timer.start();

}

StartFile0的代码,与试用按钮监听器方法几乎相同:

private void startFile0() {


    AudioFormat format;
    try {
        format = new AudioFormat(44100, 8, 1, true, true);
        panelbuttons.rateTransposer = new RateTransposer(
                panelbuttons.currentFactor);
        panelbuttons.audioPlayer = new AudioPlayer(format);

        panelbuttons.wsola = new WaveformSimilarityBasedOverlapAdd(
                Parameters.musicDefaults(panelbuttons.currentFactor,
                        panelbuttons.sampleRate)
        );

        DataLine.Info dataLineInfo = new DataLine.Info(
                TargetDataLine.class, format);
        TargetDataLine line;

        Mixer.Info mixerInfo = Shared.getMixerInfo(false, true).get(1);
        Mixer mixer = AudioSystem.getMixer(mixerInfo);

        line = (TargetDataLine) mixer.getLine(dataLineInfo);
        line.open(format, panelbuttons.wsola.getInputBufferSize());

        line.start();
        final AudioInputStream stream = new AudioInputStream(line);
        panelbuttons.dispatcher = new AudioDispatcher(stream,
                panelbuttons.wsola.getInputBufferSize(),
                panelbuttons.wsola.getOverlap());

        panelbuttons.wsola.setDispatcher(panelbuttons.dispatcher);
        panelbuttons.dispatcher.addAudioProcessor(panelbuttons.wsola);
        panelbuttons.dispatcher
                .addAudioProcessor(panelbuttons.rateTransposer);

        panelbuttons.dispatcher.addAudioProcessor(panelbuttons.gain);

        //panelbuttons.dispatcher.addAudioProcessor(new VolumeDetector(this));

        panelbuttons.dispatcher.addAudioProcessor(panelbuttons.audioPlayer);

        Thread t = new Thread(panelbuttons.dispatcher);
        t.start();
    } catch (UnsupportedAudioFileException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (LineUnavailableException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

如何避免冻结,并立即响应,没有时间间隔?

我知道不推荐使用stop(),但这会导致冻结吗?

如果需要,请告诉我更多说明

摘要 - 基本问题:  如何停止可运行并开始一个没有冻结的新运行?

0 个答案:

没有答案