我的应用程序的主要核心是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(),但这会导致冻结吗?
如果需要,请告诉我更多说明
摘要 - 基本问题: 如何停止可运行并开始一个没有冻结的新运行?