简体   繁体   中英

Different Audio Files Not Playing

The premise is that I am inputting music notes and the program plays the according piano notes. The only issue is that the first note works, but the rest of the notes do not play. So, if I input "ABC," note A will play but notes B and C will not. Is it because the file is static?

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

I recommend the standard debug technique of putting in System.out.println() 's to inspect the value in file prior to each setUp() call, to ensure that you are really getting to each call with a unique file value.

I'm guessing that you never reach the second iteration of the scan-parsing loop due to sleeping a huge amount of time. The value arising from clip.getMicrosecondLength() is going to be three orders of magnitude larger than the number of milliseconds, so you will need to divide it to get the number of milliseconds. But I don't do much file parsing and I haven't tested your code so ensuring the proper calls would be my first step to debugging this.

Lastly, to use Clips more correctly (down the road, I'm assuming this is just a test to get acquainted with Clips ), may I suggest making an array called clips of all possible notes, and make the first part of your code load each of the clip files?

Then, when reading the file, call it with a value where the incoming String for the note name is translated to the corresponding clips[] array value. For example, if the "A" audio file is in clips[0], you'd call the following with "0" as the argument.

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

Clips were designed to be audio that is held in memory and reused. If you prefer to read from files, SourceDataLine is more efficient, as it will start playing as soon as it loads a buffer of data, where Clips won't start to play until the entire file is loaded.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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