public void playMet(){
int tempo = Integer.parseInt(met_speed.getText());
tempo = tempo/60;
int delay = tempo*1000;
new Timer(delay, new ActionListener(){
public void actionPerformed(ActionEvent e){
if(Play.isSelected()){
System.out.println("beep");
playSound("Click1.wav");
}
}
}).start();
}
这是我班级的代码。它从JTextField / 60 * 1000中获取值,这是发出蜂鸣声时的毫秒值。我只使用System.out.println(“beep”)测试了它;线路并且工作正常,但是当我实际播放声音时,它会延迟或跳过或加倍声音。
playSound():
public void playSound(String filename){
try
{
Clip clip = AudioSystem.getClip();
clip.open(AudioSystem.getAudioInputStream(new File(filename)));
clip.start();
}
catch (Exception exc)
{
exc.printStackTrace(System.out);
}
}
我不确定这里到底发生了什么,有什么建议吗?
编辑:
public void playMet(){
int tempo = Integer.parseInt(met_speed.getText());
tempo = tempo/60;
int delay = tempo*1000;
try
{
Clip clip = AudioSystem.getClip();
clip.open(AudioSystem.getAudioInputStream(new File("Click1.wav")));
clip.start();
}
catch (Exception exc)
{
exc.printStackTrace(System.out);
}
new Timer(delay, new ActionListener(){
public void actionPerformed(ActionEvent e){
if(Play.isSelected()){
System.out.println("beep");
clip.start();
}
}
}).start();
}
编辑2:尝试了不同的方法
public void playMet(){
int tempo = Integer.parseInt(met_speed.getText());
tempo = tempo/60;
int delay = tempo*1000;
if(Play.isSelected()){
try
{
FileInputStream in = new FileInputStream(new File("Click1.wav"));
AudioStream as = new AudioStream(in);
AudioPlayer.player.start(as);
Thread.sleep(tempo*1000);
} catch (Exception e)
{
JOptionPane.showMessageDialog(null, e);
}
playMet();
}
else
System.out.println("not playing");
}
不是它以正确的速度一致地播放,但它会冻结并且播放按钮无法切换。
如果我将playMet()移到最后它可以工作但只播放一次。如果我做了一段时间而不是if循环,它会像上面的代码一样冻结。
答案 0 :(得分:0)
大部分工作都可以提前完成。尝试在计时器启动之前构建剪辑,只需要
clip.start();
在事件处理程序中。尝试
public void playMet(){
int tempo = Integer.parseInt(met_speed.getText());
tempo = tempo/60;
int delay = tempo*1000;
try
{
final Clip clip = AudioSystem.getClip();
clip.open(AudioSystem.getAudioInputStream(new File("Click1.wav")));
new Timer(delay, new ActionListener(){
public void actionPerformed(ActionEvent e){
if(Play.isSelected()){
System.out.println("beep");
clip.start();
}
}
}).start();
}
catch (Exception exc)
{
exc.printStackTrace(System.out);
}
}
答案 1 :(得分:0)
定时器限制你给它的速度,但是如果代码执行时间太长,那么定时器开始有点不同步导致延迟,或者有时它会加速并执行多个循环快速接班。
唯一真正的解决方案是让你的循环中的代码运行得更快,根据我获得音频剪辑和打开它的经验是非常昂贵的操作,所以尝试在循环之外做那些。
编辑:如何在循环外打开它的一个例子
public void playMet(){
int tempo = Integer.parseInt(met_speed.getText());
tempo = tempo/60;
int delay = tempo*1000;
try {
Clip clip = AudioSystem.getClip();
clip.open(AudioSystem.getAudioInputStream(new File(filename)));
}
catch (Exception exc) {
exc.printStackTrace(System.out);
}
new Timer(delay, new ActionListener(){
public void actionPerformed(ActionEvent e){
if(Play.isSelected()){
System.out.println("beep");
clip.start();
}
}
}).start();
}
但是我相信这会迫使你宣称剪辑是最终的,另一种方法是:
public Class {
private boolean firstTimeThrough;
public void playMet(){
int tempo = Integer.parseInt(met_speed.getText());
tempo = tempo/60;
int delay = tempo*1000;
firstTimeThrough = true;
new Timer(delay, new ActionListener(){
public void actionPerformed(ActionEvent e){
if(Play.isSelected()){
if(firstTimeThrough){
try {
Clip clip = AudioSystem.getClip();
clip.open(AudioSystem.getAudioInputStream(new File(filename)));
firstTimeThrough = false;
}
catch (Exception exc) {
exc.printStackTrace(System.out);
}
}
System.out.println("beep");
clip.start();
}
}
}).start();
}