Error with playing sounds - java

I have faced an error with playing sounds on button click in java. I have a field of buttons and if any button is pressed application plays a sound. But application throws me an exception:
javax.sound.sampled.LineUnavailableException: unable to obtain a line
Method look like this and is called when button was pressed:
public void playSound() {
try {
File file = new File("Sounds/sound.wav");
AudioInputStream hitStream = AudioSystem.getAudioInputStream(file);
AudioFormat format = hitStream.getFormat();
DataLine.Info info = new DataLine.Info(Clip.class, format);
Clip clip = (Clip) AudioSystem.getLine(info);
clip.open(hitStream);
clip.start();
} catch (Exception e) {
e.printStackTrace();
}
}
Sound play at the beginning then it crashes. I googled the exception, found that the clip should be closed after playing sound. I thought I should add lines after clip.start()
if (!clip.isRunning()) {
clip.stop();
clip.close();
}
But then the sounds don't play and whole application start to lag. What is the correct solution for this error?

Related

Java stop sound when another sound is starting to play

I'm Trying to make java game and now I'm implementing music to the game. Problem is if music is playing and sound is starting to play then I want to stop music.
Current Code
Clip clip;
public void playSound(File sound) {
try {
Clip clip = AudioSystem.getClip();
clip.open(AudioSystem.getAudioInputStream(sound));
clip.start();
} catch(Exception e) {
System.out.println("Error with playing sound.");
e.printStackTrace();
}
}
public void stopSound() {
if(clip == null) return;
clip.stop();
}
But if I call stopSound method then sound never get's stopped.
Any help is appreciated!
The scope of clip is the problem. The clip object defined in playSound is unknown to stopSound.
If your object contain a clip attribute, try to change the first line of playSound to:
clip = AudioSystem.getClip();

Playing an audio file in java

My goal is to make a program that displays a pop up window with a single button called play. I am using an inner class and action listener. The button does in fact play the audio clip. Now what I would like to do is make it so every time I hit the play button it plays it from the beginning and I do not hear more than one instance of the clip being played in it's completion. Here is the code I have for the inner class only:
private class PlaySound implements ActionListener {
public void actionPerformed(ActionEvent e) {
String filename = "/Users/philipgouldman/Desktop/iPhoneRingtones/Dummy_Yeah.wav";
try {
Clip clip = AudioSystem.getClip();
clip.open(AudioSystem.getAudioInputStream(new File(filename)));
clip.setFramePosition(0);
clip.start();
} catch (Exception exc) {
exc.printStackTrace(System.out);
}
}
}
I would appreciate any tips or suggestions to achieve this goal. I read on the Clip Interface javadoc that if the user wants the action to restart to simply invoke stop following setFramePosition(0). I can't say I quite understand what that means. Can someone guide me in the right direction?
Move your Clip Object outside of this handle so that its state can be investigated later.
e.g.
private class PlaySound implements ActionListener {
private Clip clip = null;
public void actionPerformed(ActionEvent e) {
String filename = "/Users/philipgouldman/Desktop/iPhoneRingtones/Dummy_Yeah.wav";
try {
if (clip == null) {
clip = AudioSystem.getClip();
clip.open(AudioSystem.getAudioInputStream(new File(filename)));
}
clip.setFramePosition(0);
clip.start();
} catch (Exception exc) {
exc.printStackTrace(System.out);
}
}
}

While loop not working In audio player

I'm using a sound player and I'm trying to create a while loop that knows when to terminate the JFrame it's playing in. The while loop should loop while the clip (recording) is playing and end when the clip is done. But here's the deal: The while loop only works when it prints something out, which I DON'T want it to do?
import java.io.*;
import java.net.URL;
import javax.sound.sampled.*;
import javax.swing.*;
public class SoundClipTest extends JFrame {
public SoundClipTest() {
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
try {
// Open an audio input stream.
File soundFile = new File("Testing/recording (2).wav");
AudioInputStream audioIn = AudioSystem.getAudioInputStream(soundFile);
//URL url = new URL("http://maximumdonline.com/miscwavs/pacman.wav");
//AudioInputStream audioIn = AudioSystem.getAudioInputStream(url);
// Get a sound clip resource.
Clip clip = AudioSystem.getClip();
// Open audio clip and load samples from the audio input stream.
clip.open(audioIn);
clip.start();
this.setVisible(true);
this.setVisible(false);
boolean run = true;
//problem While Loop
while(clip.isActive()){
//Only works when I print something out during the loop:
//System.out.println(run);
}
//Test While Loop has ended.
run = false;
System.out.println(run);
//Close JFrame
} catch (UnsupportedAudioFileException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (LineUnavailableException e) {
e.printStackTrace();
}
}
Note: Most of this sound code came from
https://www.ntu.edu.sg/home/ehchua/programming/java/J8c_PlayingSound.html
It works. I've tested it, but my while loop is crying!
The correct way to approach this task is to add a LineListener to the Clip. A Clip implements javax.sound.sampled.Line interface, so we can use Line.addLineListener(LineListener)..
Adds a listener to this line. Whenever the line's status changes, the listener's update() method is called with a LineEvent object that describes the change.
Try modifying your code to
while (clip.isActive()) {
if(!clip.isRunning())
clip.stop();
}
This did the trick for me

audio pause and play another position

I have an application that plays audio files.
My problem is that only allows me to pause playback from the position that the music is currently in, but what I want is to pause and continuing playing from that point forward. So far, I could not make that change.
I want to move the slider from another position and be able to play the music from that position on the track.
File juntos = new File("C:/juntos.wav");
if(controlPlay){
//Sliderprogreso is bar Slider
Sliprogreso.setEnabled(true);
controlReproducir=true;
Btngrabar.setEnabled(false);
Btnguardar.setEnabled(false);
Btnplay.setText("Pause");
try {
AudioInputStream stream;
AudioFormat format;
DataLine.Info info;
stream = AudioSystem.getAudioInputStream(juntos);
format = stream.getFormat();
frames =stream.getFrameLength();
durationInSeconds = (frames+0.0) / format.getFrameRate();
System.out.println("duracion:"+durationInSeconds);
Sliprogreso.setMaximum((int) durationInSeconds);
info = new DataLine.Info(Clip.class, format);
clip = (Clip) AudioSystem.getLine(info);
clip.open(stream);
clip.start();
controlPlay=false;
TimerTask timerTask=new TimerTask(){
public synchronized void run() {
{
double timeNow=(durationInSeconds*clip.getFramePosition())/frames;
System.out.println("frames:"+frames);
System.out.println("clipframe:"+clip.getFramePosition());
System.out.println("time now");
Sliprogreso.setValue((int)Math.round(timeNow));
if((int)Math.round(timeNow)==(int)durationInSeconds){
System.out.println("se cancelo");
this.cancel();
Btnplay.setText("Play");
Btngrabar.setEnabled(true);
Btnguardar.setEnabled(true);
controlPlay=true;
}
}
}
};
timer.scheduleAtFixedRate(timerTask, 30, 30);
}
catch (Exception e) {
System.out.println(e);
e.printStackTrace();
}
}
else{
clip.stop();
timer.cancel();
Btnplay.setText("Play");
controlPlay=true;
Btngrabar.setEnabled(true);
Btnguardar.setEnabled(true);
}
Have you looked at the Clip API? There are methods for pausing and for setting the "playhead" to any position, using either frames or elapsed time.
From within your TimerTask:
if (positionOnSliderUpdatedByUser)
{
clip.stop();
int desiredMicrosecond = yourConversionFunction( sliprogreso.getValue() );
clip.setMicrosecondPosition(desiredMicrosecond);
clip.start();
positionOnSliderUpdatedByUser = false;
}
I'm not sure if I am reading your code correctly, especially with your lack of formatting. I'm taking it that you are updating the slider regularly with the song position, but that if the user changes the slider, then you want to move to that point in the song. Thus, there should be some sort of process to flag when the user changes the slider (as opposed to the song changing the slider). I'm using the flag name "positionOnSliderUpdatedByUser".

sound clips get cut off in jar

I'm working on a 2D Game in Java and have the problem that the game's sounds will get cut off after playing for a couple of milliseconds when I run the game from an executable Jar file.
The sounds play correctly when I run the game from eclipse.
I load the sound files (.wav) like this:
AudioInputStream ais = AudioSystem.getAudioInputStream(this.getClass().getResource("sounds/sound.wav"));
AudioFormat af = ais.getFormat();
int size = (int) (af.getFrameSize() * ais.getFrameLength());
byte[] audio = new byte[size];
DataLine.Info info = new DataLine.Info(Clip.class, af, size);
ais.read(audio, 0, size);
sound= (Clip) AudioSystem.getLine(info);
sound.open(af, audio, 0, size);
I play the sounds later in the game like this:
public void playClip(final Clip clip, final int loop){
Runnable soundPlayer = new Runnable() {
Clip sound = clip;
#Override
public void run() {
try {
sound.setMicrosecondPosition(0);
sound.loop(loop);
} catch (Exception e) {
e.printStackTrace();
}
}
};
new Thread(soundPlayer).start();
}
Do you have any idea why the program behaves like that and how to fix that problem?
Thanks in advance for your help!

Categories

Resources