views:

44

answers:

2

I'm trying to play a few WAV files after each other. I tried this method:

for (String file : audioFiles) {
    new AePlayWave(file).start();
}

but that plays them all at the same time. So i need a function that looks like this:

public void play(Vector<String> audioFiles);

the vector contains the files, eg: "test1.wav","test2.wav"

been looking for over 4 hours, but I can't seem to find a working solution :(

I also tried concatenating the WAV files to 1 AudioInputStream. It doesn't give any compiler errors but the sound is totally messed up. Code:

public static AudioInputStream concat(Vector<String> files) throws UnsupportedAudioFileException, IOException {
    AudioInputStream total = AudioSystem.getAudioInputStream(new File(files.get(0)));

    for (int i = 1; i < files.size(); i++) {
        AudioInputStream clip = AudioSystem.getAudioInputStream(new File(files.get(i)));
        total = new AudioInputStream(new SequenceInputStream(total, clip),
                                     total.getFormat(),
                                     total.getFrameLength() + clip.getFrameLength());
    }
    return total;
}

edit even if i try to put the 2 first files together it fails:

public static AudioInputStream concat(Vector files) throws UnsupportedAudioFileException, IOException { AudioInputStream clip1 = AudioSystem.getAudioInputStream(new File(files.get(0))); AudioInputStream clip2 = AudioSystem.getAudioInputStream(new File(files.get(1)));

AudioInputStream total = new AudioInputStream( new SequenceInputStream(clip1, clip2), clip1.getFormat(), clip1.getFrameLength() + clip2.getFrameLength());

return total; }

+1  A: 

This code is a bit low-level, but it works:

    byte[] buffer = new byte[4096];
    for (File file : files) {
        try {
            AudioInputStream is = AudioSystem.getAudioInputStream(file);
            AudioFormat format = is.getFormat();
            SourceDataLine line = AudioSystem.getSourceDataLine(format);
            line.open(format);
            line.start();
            while (is.available() > 0) {
                int len = is.read(buffer);
                line.write(buffer, 0, len);
            }
            line.drain(); //**[DEIT]** wait for the buffer to empty before closing the line
            line.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

Basically you open an AudioInputStream, read data and write it to a SourceDataLine. write method is blocking, so it will play files consequently.

You can try to use Clip for the same purpose.

tulskiy
this works but the audio gets cut of every time at the end of every fileif you want to play the files: hello.wavand_welcome.wavto_stackoverflow.wavyou hear:hel and welco to stackoveany ideas how to fix this?
Berty
@Berty: add line.drain() before line.close()
tulskiy
perfect that did the trickthx so muchit sound perfect now :D
Berty
A: 

the final answer (with drain)

public static void play(ArrayList<String> files){
    byte[] buffer = new byte[4096];
    for (String filePath : files) {
        File file = new File(filePath);
        try {
            AudioInputStream is = AudioSystem.getAudioInputStream(file);
            AudioFormat format = is.getFormat();
            SourceDataLine line = AudioSystem.getSourceDataLine(format);
            line.open(format);
            line.start();
            while (is.available() > 0) {
                int len = is.read(buffer);
                line.write(buffer, 0, len);
            }
            line.drain();
            line.close();
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }
}
Berty