繁体   English   中英

Java节拍器Timer()不一致

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM