[英]Java Metronome Timer() inconsistent
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”);进行了测试。 线,效果很好,但是当我实际播放声音时,它会延迟或跳过或加倍声音。
播放声音():
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循环,它将像上面的代码一样冻结。
大多数工作可以提前完成。 尝试在计时器启动之前构建剪辑,然后
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);
}
}
计时器的速度受其限制,但是,如果代码执行时间太长,则计时器开始有点不同步,从而导致延迟,或者有时它会加速并快速连续执行多个循环。
唯一实际的解决方案是,根据我获得音频剪辑并打开它的经验,使循环中的代码运行更快,因此请尝试在循环外进行操作。
编辑:如何在循环外打开它的示例
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();
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.