前提是我输入音乐笔记,程序播放相应的钢琴音符。唯一的问题是第一个音符有效,但其余音符不起作用。所以,如果我输入“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();
}
}
我推荐使用标准调试技术来放入System.out.println()
来检查每个file
调用之前setUp()
中的值,以确保您真正使用唯一文件值进行每次调用。
我猜你因为睡了很长时间而从未到过扫描解析循环的第二次迭代。 clip.getMicrosecondLength()
产生的值将比毫秒数大三个数量级,因此您需要将其除以得到毫秒数。但我没有做太多的文件解析,我没有测试你的代码,所以确保正确的调用将是我调试它的第一步。
最后,更正确地使用Clips
(在路上,我假设这只是一个熟悉Clips
的测试),我可以建议制作一个名为clips
的所有可能注释的数组,并使代码的第一部分加载每个剪辑文件?
然后,在读取文件时,使用一个值来调用它,其中音符名称的传入字符串将转换为相应的clips []数组值。例如,如果“A”音频文件位于clip [0]中,则调用以下内容并将“0”作为参数。
private void playClip(int idx)
{
clips[idx].setFramePosition(0);
clips[idx].play();
Thread.sleep(clips[idx].getMicrosecondLength()/1000);
}
Clips
被设计为存储在内存中并重复使用的音频。如果您更喜欢从文件中读取,SourceDataLine
会更有效率,因为它会在加载数据缓冲区后立即开始播放,其中Clips
在加载整个文件之前不会开始播放。