简体   繁体   English

Java-for循环执行的次数比应执行的次数多-节拍器程序

[英]java - for loop is executing more times than it should - metronome program

I am creating a metronome program and the for loop is executing +1 times than it should. 我正在创建一个节拍器程序,并且for循环比应执行的执行+1次。

public class Tempo {

String file;
int bpm;

public Tempo(int bpm, String file){
    this.bpm=bpm;
    this.file=file;
}

public void tempoPlay () throws InterruptedException{
    new Play(file).start();
    Thread.sleep(60000/bpm); 

}

public static void main(String[] args) throws InterruptedException {
    Tempo t = new Tempo(120, "C:\\Users\\Korisnik\\Desktop\\dome3.wav");

    for(int i=0;i<20;i++){
        t.tempoPlay();
    }
}
}

The first beat is rapidly followed by the second one but later as it goes it is sounding compliant. 第一个拍子紧随其后,第二个拍子紧随其后。 I've counted it plays 21 beats but it should play 20. Here's the Play class: 我已经计算出它可以播放21拍,但应该可以播放20拍。这是Play课:

import java.io.File;
import java.io.IOException;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.FloatControl;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.SourceDataLine;
import javax.sound.sampled.UnsupportedAudioFileException;

class Play extends Thread {

private String filename;
private Position curPosition;
private final int EXTERNAL_BUFFER_SIZE = 524288; // 128Kb 

enum Position {

    LEFT, RIGHT, NORMAL
};

public Play(String wavfile) {
    filename = wavfile;
    curPosition = Position.NORMAL;
}

public Play(String wavfile, Position p) {
    filename = wavfile;
    curPosition = p;
}

@Override
public void run() {

    File soundFile = new File(filename);
    if (!soundFile.exists()) {
        System.err.println("Wave file not found: " + filename);
        return;
    }

    AudioInputStream audioInputStream = null;
    try {
        audioInputStream = AudioSystem.getAudioInputStream(soundFile);
    } catch (UnsupportedAudioFileException e1) {
        e1.printStackTrace();
        return;
    } catch (IOException e1) {
        e1.printStackTrace();
        return;
    }

    AudioFormat format = audioInputStream.getFormat();
    SourceDataLine auline = null;
    DataLine.Info info = new DataLine.Info(SourceDataLine.class, format);

    try {
        auline = (SourceDataLine) AudioSystem.getLine(info);
        auline.open(format);
    } catch (LineUnavailableException e) {
        e.printStackTrace();
        return;
    } catch (Exception e) {
        e.printStackTrace();
        return;
    }

    if (auline.isControlSupported(FloatControl.Type.PAN)) {
        FloatControl pan = (FloatControl) auline
                .getControl(FloatControl.Type.PAN);
        if (curPosition == Position.RIGHT) {
            pan.setValue(1.0f);
        } else if (curPosition == Position.LEFT) {
            pan.setValue(-1.0f);
        }
    }

    auline.start();
    int nBytesRead = 0;
    byte[] abData = new byte[EXTERNAL_BUFFER_SIZE];

    try {
        while (nBytesRead != -1) {
            nBytesRead = audioInputStream.read(abData, 0, abData.length);
            if (nBytesRead >= 0) {
                auline.write(abData, 0, nBytesRead);
            }
        }
    } catch (IOException e) {
        e.printStackTrace();
        return;
    } finally {
        auline.drain();
        auline.close();
    }

}

}

Shot in the dark: It might be worthwhile to read the file into memory completely for testing purposes. 在黑暗中拍摄:将文件完全读入内存以进行测试可能是值得的。 A guess as to what might be happening is that the I/O from reading the file is interfering with the timing of the playback. 可能发生的猜测是读取文件的I / O干扰了播放的时间。

You might be able to get away with this to test. 您也许可以摆脱这种情况进行测试。

Tempo t = new Tempo(120, "C:\\Users\\Korisnik\\Desktop\\dome3.wav");

t.tempoPlay() // ignore this
Thread.sleep(10);

for(int i=0;i<20;i++){
    t.tempoPlay();
} 

Or better yet, have Tempo cache the read in before playing the sound. 或更妙的是,让Tempo在播放声音之前将读入缓存。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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