Question

im trying to make a class in java that plays certain sounds, but the sounds stop at random moments and not at the end. Why is it doing that? Thanks in advance!

Here is my code:

import java.io.File;

import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;
import javax.sound.sampled.Line;
import javax.sound.sampled.LineEvent;
import javax.sound.sampled.LineListener;
import javax.swing.JDialog;
import javax.swing.JFileChooser;

public class CoreJavaSound extends Object implements LineListener {
File soundFile;

JDialog playingDialog;

Clip clip;

public static void main(String[] args) throws Exception {
PlayBow();

}

public CoreJavaSound(String fileName) throws Exception {
JFileChooser chooser = new JFileChooser();

soundFile = new File(fileName);


System.out.println("Playing " + soundFile.getName());

Line.Info linfo = new Line.Info(Clip.class);
Line line = AudioSystem.getLine(linfo);
clip = (Clip) line;
clip.addLineListener(this);
AudioInputStream ais = AudioSystem.getAudioInputStream(soundFile);
clip.open(ais);
clip.start();
}

@Override
public void update(LineEvent le) {
LineEvent.Type type = le.getType();
if (type == LineEvent.Type.OPEN) {
  System.out.println("OPEN");
} else if (type == LineEvent.Type.CLOSE) {
  System.out.println("CLOSE");
  System.exit(0);
} else if (type == LineEvent.Type.START) {
  System.out.println("START");
  playingDialog.setVisible(true);
} else if (type == LineEvent.Type.STOP) {
  System.out.println("STOP");
  playingDialog.setVisible(false);
  clip.close();
}
}

public static void PlayBow() throws Exception
{
CoreJavaSound s = new CoreJavaSound("Bow.wav");
}
}

Everything works fine, except for the fact that the sound stops working after like 1 second (while the file is 5 seconds)...

Was it helpful?

Solution

The clip is started on a background thread and is not a blocking call. It plays in the background. So the program terminates without allowing the clip to finish playing.

Try something like this:

  ...
  static boolean running = false;

  public static void main(String[] args) throws Exception {
    playBow();
    while(running) {
      Thread.sleep(200);
    }
  }
  ...
  @Override
  public void update(LineEvent le) {
    LineEvent.Type type = le.getType();
    if (type == LineEvent.Type.OPEN) {
      running = true;
      System.out.println("OPEN");
    } else if (type == LineEvent.Type.CLOSE) {
      System.out.println("CLOSE");
    } else if (type == LineEvent.Type.START) {
      System.out.println("START");
      playingDialog.setVisible(true);
    } else if (type == LineEvent.Type.STOP) {
      System.out.println("STOP");
      playingDialog.setVisible(false);
      clip.close();
      running = false;
    }
  }

Note that this sample is not the best solution to this problem. It is just an example.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top