0

前提是我正在输入音符并且程序会播放相应的钢琴音符。唯一的问题是第一个音符有效,但其余音符不播放。所以,如果我输入“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();
        }
}
4

1 回答 1

1

我建议在每次调用之前使用标准的调试技术System.out.println()来检查值,以确保您真正使用唯一的文件值进行每次调用。filesetUp()

我猜由于睡眠时间过长,您永远不会到达扫描解析循环的第二次迭代。产生的值clip.getMicrosecondLength()将比毫秒数大三个数量级,因此您需要将其除以得到毫秒数。但是我没有做太多的文件解析,也没有测试你的代码,所以确保正确的调用将是我调试它的第一步。

最后,为了Clips更正确地使用(以后,我假设这只是一个熟悉的测试Clips),我可以建议制作一个包含clips所有可能注释的数组,并让代码的第一部分加载每个剪辑文件?

然后,在读取文件时,使用一个值调用它,其中注释名称的传入字符串被转换为相应的 clips[] 数组值。例如,如果“A”音频文件在 clips[0] 中,您将使用“0”作为参数调用以下命令。

private void playClip(int idx)
{
    clips[idx].setFramePosition(0);
    clips[idx].play();
    Thread.sleep(clips[idx].getMicrosecondLength()/1000);
}

Clips被设计为保存在内存中并重复使用的音频。如果您更喜欢从文件中读取,SourceDataLine效率会更高,因为它会在加载数据缓冲区后立即开始播放,而在Clips加载整个文件之前不会开始播放。

于 2019-04-28T03:04:47.857 回答