Play audio clip in an Application

R

rohayre

I'm trying to play an audio clip by using Applet's newAudioClip()
method. That method takes a URL. The .wav file is located in a jar file
(the only jar file). For example:
if myJar.jar is the only jar file
"java -jar myJar.jar" launches the application correctly and everything
is wonderful. My audio clip won't play because I don't know how to
access the .wav file from the jar file.

This code snippet works fine when I'm not running from the jar file:

try
{
File currentDir = new File(".");
URL currentDirURL = currentDir.toURL();
URL url = new URL(currentDirURL, fileName);
AudioClip clip = Applet.newAudioClip(url);
clip.play();
}
catch (Exception e)
{
e.printStackTrace();
}

It knows to look for the sound file in the current directory. How do I
adjust this code to look for the sound file in the jar.

I have a feeling it's an easy answer involving class.getResource().....
 
K

Knute Johnson

I'm trying to play an audio clip by using Applet's newAudioClip()
method. That method takes a URL. The .wav file is located in a jar file
(the only jar file). For example:
if myJar.jar is the only jar file
"java -jar myJar.jar" launches the application correctly and everything
is wonderful. My audio clip won't play because I don't know how to
access the .wav file from the jar file.

This code snippet works fine when I'm not running from the jar file:

try
{
File currentDir = new File(".");
URL currentDirURL = currentDir.toURL();
URL url = new URL(currentDirURL, fileName);
AudioClip clip = Applet.newAudioClip(url);
clip.play();
}
catch (Exception e)
{
e.printStackTrace();
}

It knows to look for the sound file in the current directory. How do I
adjust this code to look for the sound file in the jar.

I have a feeling it's an easy answer involving class.getResource().....

You answered it yourself - URL Class.getResource(String name)
 
R

rohayre

Does anyone know why this wont play? The wav file is located in the jar
file found on the classpath. What am I missing?

import java.applet.Applet;
import java.applet.AudioClip;
import java.net.URL;

public class SoundPlayer
{
public void playSiren()
{
URL url = this.getClass().getResource("threeHorn.wav");
AudioClip clip = Applet.newAudioClip(url);
clip.play();
}

public static void main(String[] args)
{
new SoundPlayer().playSiren();
}
}
 
A

Andrew Thompson

(e-mail address removed) wrote:

Please refrain from top-posting.
Does anyone know why this wont play? The wav file is located in the jar
file found on the classpath. What am I missing?

The only thing I can think of, is that perhaps the
classloader is the bootstrap classloader (and
therefore will not find the application resource).
URL url = this.getClass().getResource("threeHorn.wav");
^
(as an aside, please change tabs to 3 or 4 spaces before
posting, the '^' character above lines up with where I am
seeing the code start)

To test that theory, try printing the details of the
classloader at this point in the code..
ClassLoader cl = this.getClass().getClassLoader();
System.out.println( "ClassLoader: " + cl );
URL url = cl.getResource("threeHorn.wav");

...does it tell you the classloader is 'null'?

And another thing, are you locked into 1.2*, or can
you go to 1.3+? If so - it might be worth looking into
the java.sound.sampled package introduced with 1.3
(though it may also be overkill, for this simple problem.)

* It seems your current code would be compatible with
Java 1.2+, unless I missed something.

Andrew T.
 
K

Knute Johnson

Does anyone know why this wont play? The wav file is located in the jar
file found on the classpath. What am I missing?

import java.applet.Applet;
import java.applet.AudioClip;
import java.net.URL;

public class SoundPlayer
{
public void playSiren()
{
URL url = this.getClass().getResource("threeHorn.wav");
AudioClip clip = Applet.newAudioClip(url);
clip.play();
}

public static void main(String[] args)
{
new SoundPlayer().playSiren();
}
}

Looks like the program is ending before the AudioClip can play. Try
putting a sleep after playSiren();
 
C

chump

Andrew....

Thanks for you help. Few things:

- What is top-posting?
- The classloader is not null. I am running java 1.5 in eclipse on
MacOSX. The classloader is printing out
"sun.misc.Launcher$AppClassLoader@a9c85c"

Still looking.....
 
C

chump

It's throwing a null pointer exception before it gets a chance to
end....

java.lang.NullPointerException
at sun.applet.AppletAudioClip.<init>(AppletAudioClip.java:48)
at java.applet.Applet.newAudioClip(Applet.java:273)
at com.gizmo.util.SoundPlayer.playSiren(Unknown Source)
at com.gizmo.util.SoundPlayer.main(Unknown Source)
sleeping...
Ending...


Knute said:
Does anyone know why this wont play? The wav file is located in the jar
file found on the classpath. What am I missing?

import java.applet.Applet;
import java.applet.AudioClip;
import java.net.URL;

public class SoundPlayer
{
public void playSiren()
{
URL url = this.getClass().getResource("threeHorn.wav");
AudioClip clip = Applet.newAudioClip(url);
clip.play();
}

public static void main(String[] args)
{
new SoundPlayer().playSiren();
}
}

Looks like the program is ending before the AudioClip can play. Try
putting a sleep after playSiren();
 
K

Knute Johnson

chump said:
It's throwing a null pointer exception before it gets a chance to
end....

java.lang.NullPointerException
at sun.applet.AppletAudioClip.<init>(AppletAudioClip.java:48)
at java.applet.Applet.newAudioClip(Applet.java:273)
at com.gizmo.util.SoundPlayer.playSiren(Unknown Source)
at com.gizmo.util.SoundPlayer.main(Unknown Source)
sleeping...
Ending...


Knute said:
Does anyone know why this wont play? The wav file is located in the jar
file found on the classpath. What am I missing?

import java.applet.Applet;
import java.applet.AudioClip;
import java.net.URL;

public class SoundPlayer
{
public void playSiren()
{
URL url = this.getClass().getResource("threeHorn.wav");
AudioClip clip = Applet.newAudioClip(url);
clip.play();
}

public static void main(String[] args)
{
new SoundPlayer().playSiren();
}
}
Looks like the program is ending before the AudioClip can play. Try
putting a sleep after playSiren();

Do you have the .wav file in the jar? I get that error if it isn't in
the jar.
 
A

Andrew Thompson

chump said:
Andrew....

Thanks for you help.

You're welcome.
...Few things:

- What is top-posting?

I'm glad you asked. But instead of answering, I'll
demonstrate a handy technique that will answer that,
as well as many other question later questions..
<http://www.google.com/search?q=definition+top-post>

Note that by changing anything after 'definition', you
get the meaning of the word or phrase within one or
two more clicks (usually).
- The classloader is not null. I am running java 1.5 in eclipse on
MacOSX. The classloader is printing out
"sun.misc.Launcher$AppClassLoader@a9c85c"

OK - thanks for confirming that is not the problem.
Still looking.....

I'll review the rest of the thread..

Andrew T.
 
C

chump

I've been able to play an audio clip with the code below. Only problem
now is the thread won't die and the app stays running.

Does the thread need to be set as Deamon?

import java.io.File;
import java.io.IOException;

import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.LineEvent;
import javax.sound.sampled.LineListener;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.UnsupportedAudioFileException;

/**
* This class provides simple functions for playing sounds
*
* @author ryan
*/
public class SoundPlayer implements LineListener, Runnable
{
private File soundFile;

private Thread thread;

private static SoundPlayer player;

/**
* Private because of the singleton
*/
private SoundPlayer()
{
}

/**
* Play a siren sound
*/
public static void playSiren()
{
SoundPlayer p = getPlayer();
p.playSirenFile();
}

/**
* Play the siren file
*/
private void playSirenFile()
{
this.soundFile = new File("./audio/threeHorn.wav");
thread = new Thread(this);
thread.setName("SoundPlayer");
thread.start();
}

/**
* Invoked when the thread kicks off
*/
public void run()
{
try
{
AudioInputStream stream = AudioSystem
.getAudioInputStream(this.soundFile);
AudioFormat format = stream.getFormat();

/**
* we can't yet open the device for ALAW/ULAW playback, convert
* ALAW/ULAW to PCM
*/
if ((format.getEncoding() == AudioFormat.Encoding.ULAW)
|| (format.getEncoding() == AudioFormat.Encoding.ALAW))
{
AudioFormat tmp = new AudioFormat(
AudioFormat.Encoding.PCM_SIGNED,
format.getSampleRate(),
format.getSampleSizeInBits() * 2, format.getChannels(),
format.getFrameSize() * 2, format.getFrameRate(), true);
stream = AudioSystem.getAudioInputStream(tmp, stream);
format = tmp;
}
DataLine.Info info = new DataLine.Info(Clip.class, stream
.getFormat(), ((int) stream.getFrameLength() * format
.getFrameSize()));

Clip clip = (Clip) AudioSystem.getLine(info);
clip.addLineListener(this);
clip.open(stream);
clip.start();
try
{
thread.sleep(99);
}
catch (Exception e)
{
}
while (clip.isActive() && thread != null)
{
try
{
thread.sleep(99);
}
catch (Exception e)
{
break;
}
}
clip.stop();
clip.close();
}
catch (UnsupportedAudioFileException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
catch (LineUnavailableException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}

private static SoundPlayer getPlayer()
{
if (player == null)
{
player = new SoundPlayer();
}
return player;
}

public void update(LineEvent event)
{
}

public static void main(String[] args)
{
SoundPlayer.playSiren();
}
}
 
K

Knute Johnson

chump said:
I've been able to play an audio clip with the code below. Only problem
now is the thread won't die and the app stays running.

Does the thread need to be set as Deamon?

import java.io.File;
import java.io.IOException;

import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.LineEvent;
import javax.sound.sampled.LineListener;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.UnsupportedAudioFileException;

/**
* This class provides simple functions for playing sounds
*
* @author ryan
*/
public class SoundPlayer implements LineListener, Runnable
{
private File soundFile;

private Thread thread;

private static SoundPlayer player;

/**
* Private because of the singleton
*/
private SoundPlayer()
{
}

/**
* Play a siren sound
*/
public static void playSiren()
{
SoundPlayer p = getPlayer();
p.playSirenFile();
}

/**
* Play the siren file
*/
private void playSirenFile()
{
this.soundFile = new File("./audio/threeHorn.wav");
thread = new Thread(this);
thread.setName("SoundPlayer");
thread.start();
}

/**
* Invoked when the thread kicks off
*/
public void run()
{
try
{
AudioInputStream stream = AudioSystem
.getAudioInputStream(this.soundFile);
AudioFormat format = stream.getFormat();

/**
* we can't yet open the device for ALAW/ULAW playback, convert
* ALAW/ULAW to PCM
*/
if ((format.getEncoding() == AudioFormat.Encoding.ULAW)
|| (format.getEncoding() == AudioFormat.Encoding.ALAW))
{
AudioFormat tmp = new AudioFormat(
AudioFormat.Encoding.PCM_SIGNED,
format.getSampleRate(),
format.getSampleSizeInBits() * 2, format.getChannels(),
format.getFrameSize() * 2, format.getFrameRate(), true);
stream = AudioSystem.getAudioInputStream(tmp, stream);
format = tmp;
}
DataLine.Info info = new DataLine.Info(Clip.class, stream
.getFormat(), ((int) stream.getFrameLength() * format
.getFrameSize()));

Clip clip = (Clip) AudioSystem.getLine(info);
clip.addLineListener(this);
clip.open(stream);
clip.start();
try
{
thread.sleep(99);
}
catch (Exception e)
{
}
while (clip.isActive() && thread != null)
{
try
{
thread.sleep(99);
}
catch (Exception e)
{
break;
}
}
clip.stop();
clip.close();
}
catch (UnsupportedAudioFileException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
catch (LineUnavailableException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}

private static SoundPlayer getPlayer()
{
if (player == null)
{
player = new SoundPlayer();
}
return player;
}

public void update(LineEvent event)
{
}

public static void main(String[] args)
{
SoundPlayer.playSiren();
}
}

Here is how to play a Clip. But what was wrong with using AudioClip?

import java.io.*;
import javax.sound.sampled.*;

public class PlayClip {
public static void main(String[] args) {
try {
AudioInputStream ais =
AudioSystem.getAudioInputStream(new File(args[0]));
AudioFormat af = ais.getFormat();
Clip line = AudioSystem.getClip();
line.open(ais);
line.start();
line.drain();
line.stop();
line.close();
} catch (Exception e) {
System.out.println(e);
}
}
}
 
C

chump

I ran your app. It works, plays the file and is very clean. One
thing... my app doesn't go down after the file plays. In my previous
example, I thought it was the thread I was spinning off wouldn't die,
but your code doesn't create a new thread and it still stays up for me.
Are any of the audio classes hanging onto something that is keeping the
app up?
 
K

Knute Johnson

chump said:
I ran your app. It works, plays the file and is very clean. One
thing... my app doesn't go down after the file plays. In my previous
example, I thought it was the thread I was spinning off wouldn't die,
but your code doesn't create a new thread and it still stays up for me.
Are any of the audio classes hanging onto something that is keeping the
app up?

There is a change in Java Sound, I think between 1.4 and 1.5. In 1.4
there is a thread created that will hold the program and in 1.5 that was
fixed. I tried my code in 1.6 and there is another wrinkle with it. It
won't play the file unless you put a very short sleep after the start()
call. Java Sound has unfortunately not been a high priority for Sun and
there are some inconsistencies.

If you are going to use this in a production environment you might want
to consider using a LineListener to control the actions of your program.
 
Joined
Dec 3, 2008
Messages
1
Reaction score
0
thank you!

ah thank you so much, I have been trying for hours to figure out how to reference it.
:)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,995
Messages
2,570,228
Members
46,818
Latest member
SapanaCarpetStudio

Latest Threads

Top