前提是我正在输入音乐音符,程序会播放相应的钢琴音符。唯一的问题是第一个音符有效,但其余音符不播放。因此,如果我输入“ ABC”,便会演奏音符A,但不会演奏音符B和C。是因为文件是静态的吗?
public class SnapMusic {
static File file = new File("");
static void setUp() {
try {
Clip clip = AudioSystem.getClip();
clip.open(AudioSystem.getAudioInputStream(file));
clip.start();
Thread.sleep(clip.getMicrosecondLength());
}
catch (Exception e) {
System.err.println(e.getMessage());
}
}
public static void main (String[] arrgs) {
Scanner scan = new Scanner(System.in);
String notes = scan.next();
for (int i = 0; i < notes.length(); i++) {
if (notes.charAt(i) == 'A') {
file = new File("src/musictranslator/MidA.wav");
setUp();
}
else if (notes.charAt(i) == 'B') {
file = new File("src/musictranslator/MidB.wav");
setUp();
}
else if (notes.charAt(i) == 'C') {
file = new File("src/musictranslator/MidC.wav");
setUp();
}
else if (notes.charAt(i) == 'D') {
file = new File("src/musictranslator/MidD.wav");
setUp();
}
}
答案 0 :(得分:1)
我建议使用标准的调试技术,在每次System.out.println()
调用之前放入file
来检查setUp()
中的值,以确保您真的可以通过唯一的文件值。
我猜测由于睡眠时间过长,您从未达到扫描解析循环的第二次迭代。由clip.getMicrosecondLength()
产生的值将比毫秒数大3个数量级,因此您需要将其除以得到毫秒数。但是我没有做太多的文件解析,也没有测试您的代码,因此确保正确的调用将是调试此程序的第一步。
最后,要更正确地使用Clips
(在以后的工作中,我假设这只是一次结识Clips
的测试),我建议创建一个名为{{1}的数组}中所有可能的注释,并让代码的第一部分加载每个剪辑文件?
然后,在读取文件时,使用一个值调用该文件,将注释名称的传入String转换为相应的clips []数组值。例如,如果“ A”音频文件位于clips [0]中,则您将以“ 0”作为参数调用以下内容。
clips
private void playClip(int idx)
{
clips[idx].setFramePosition(0);
clips[idx].play();
Thread.sleep(clips[idx].getMicrosecondLength()/1000);
}
被设计为保留在内存中并可以重复使用的音频。如果您更喜欢读取文件,Clips
会更高效,因为它会在加载数据缓冲区后立即开始播放,SourceDataLine
在加载整个文件之前不会开始播放