gpt4 book ai didi

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

转载 作者:太空宇宙 更新时间:2023-11-04 07:54:11 25 4
gpt4 key购买 nike

我正在创建一个节拍器程序,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();
}
}
}

第一个节拍很快就紧随第二个节拍,但随着时间的推移,它听起来很合规。我数过它播放了 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();
}

}

}

最佳答案

在黑暗中拍摄:出于测试目的,可能值得将文件完全读入内存。对可能发生的情况的猜测是,读取文件的 I/O 干扰了播放时间。

您也许可以通过这个进行测试。

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();
}

或者更好的是,在播放声音之前让 Tempo 缓存读取内容。

关于java - for 循环执行的次数比应有的次数多 - 节拍器程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13872232/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com