简体   繁体   中英

Java Sounds work on JRE6 but not JRE7

I have been tearing my hair out trying to solve this problem, I have this method in a calculator I've been working on:

public void error_sound() throws UnsupportedAudioFileException, IOException, LineUnavailableException {
    AudioInputStream AIS = AudioSystem.getAudioInputStream(calculator.class.getResourceAsStream("/resources/Error.wav"));
    AudioFormat format = AIS.getFormat();
    SourceDataLine playbackLine = AudioSystem.getSourceDataLine(format);
    playbackLine.open(format);
    playbackLine.start();
    int bytesRead = 0;
    byte[] buffer = new byte[128000];
    while (bytesRead != -1) {
        bytesRead = AIS.read(buffer, 0, buffer.length);
        if (bytesRead >= 0)
            playbackLine.write(buffer, 0, bytesRead);
        }
    playbackLine.drain();
    playbackLine.close();
}

This code works on JRE6 but not on JRE7. If anyone could suggest a way to make the above work on JRE7 I'd be eternally grateful?

It appears that Sun dropped the "Java Sound Audio Engine" in JRE 1.7 and this is the only thing I can put it down to?

"It appears that Sun dropped the "Java Sound Audio Engine" in JRE 1.7 and this is the only thing I can put it down to?"

Nope, that would have been noticed by a lot of people, including me. Your comments indicate there is a problem seeking in the resource input stream. That can either be caused by different audio systems or different implementations of getAudioStream().

You could just try wrapping the resource stream into a BufferedInputStream:

InputStream raw = calculator.class.getResourceAsStream("/resources/Error.wav");
InputStream bis = new BufferedInputStream(raw, 20000);
AudioInputStream ais = AudioSystem.getAudioInputStream(bis);

(Thats based on the idea thet BufferedInputStream supports mark / reset)

You should really add some proper error handling to the code (check if the resource is there etc. and proper error logging/reporting). It really helps in the long run if problems are reported clearly.

EDIT: Re-reading you problem description, its clear you are running the code from eclipse, and on the other computer you run from a jar-file. The problem is your code doesn't cope with the latter. Wrapping it into a BufferedInputStream should fix that (you may need to increase the buffer size though).

Edit2: Try this for repeating sound:

public void error_sound() throws UnsupportedAudioFileException, IOException, LineUnavailableException {
    AudioInputStream AIS = ...
    AudioFormat format = ...
    SourceDataLine playbackLine = ...
    playbackLine.open(format);
    playbackLine.start();

    int repeats = 5;
    while (true) {
       // playloop
       int bytesRead = 0;
       byte[] buffer = new byte[128000];
       while (bytesRead != -1) {
           bytesRead = AIS.read(buffer, 0, buffer.length);
           if (bytesRead >= 0)
                playbackLine.write(buffer, 0, bytesRead);
       }
       --repeats;
       if (repeats <= 0) {
           // done, stop playing
           break;
       } else {
           // repeat one more time, reset audio stream
           AIS = ...
       }
   }
   playbackLine.drain();
   playbackLine.close();
}

The only complicated thing is that you need the audio stream to get the format and that you also need to create it anew in every loop iteration to read it from the beginning. Everything else stays the same.

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