I have a number of .wav files I play from Java. In this stripped down example, "drip" is audible but "swish" is not even though they run via the same code. There does not seem to be anything unusual about "swish": it plays from the Gnome desktop. I have a similar app, not quite as stripped down that plays "swish" but not "drip" so again it does not seem to be a problem tied to the nature of the data.
Any ideas what is happening here? This bug was noticed after code that was known to be working was "redeployed" on a rebuilt system: reinstalled Ubuntu 10.10 and Eclipse Indigo. This bug happens with both Sun JDK 6 and OpenJDK 6. Edit The "rebuilt" system is actually different hardware as well: Intel E6500 (2 cores, 2.93 GHz) I have only installed Ubuntu, Eclipse, OpenJDK, Sun JDK. The previous system was an AMD 630 (4 cores, 2.8 GHz) with Ubuntu, Eclipse, OpenJDK (I think).
Edit After some experimenting, it seems the first clip loaded will be the one that works. The TestSounder constructor loads them so that is where the order can be reversed. Perhaps the use of the static method AudioSystem.getLine has something to do with it since that is obviously the non-object oriented operation here.
import java.io.IOException;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.Clip;
import javax.sound.sampled.UnsupportedAudioFileException;
import javax.sound.sampled.LineUnavailableException;
public class TestSounder
{
String resourcePathFromBin = "/resources/";
Clip dripClip;
Clip swishClip;
public TestSounder()
{
dripClip = setupClip("drip.wav");
swishClip = setupClip("swish.wav");
}
public void close()
{
dripClip.close();
swishClip.close();
}
private Clip setupClip(String fileName)
{
Clip clip = null;
try
{
AudioInputStream ais =
AudioSystem.getAudioInputStream(this.getClass().getResourceAsStream(resourcePathFromBin +
fileName));
AudioFormat af = ais.getFormat();
DataLine.Info lineInfo = new DataLine.Info(Clip.class, af);
clip = (Clip)AudioSystem.getLine(lineInfo);
clip.open(ais);
}
catch (UnsupportedAudioFileException e)
{
assert false: "bug";
}
catch (IOException e)
{
assert false: "bug";
}
catch (LineUnavailableException e)
{
assert false: "bug";
}
return clip;
}
public void go(UtilityK.Sounds s)
{
Clip clip = null;
if (s == UtilityK.Sounds.drip)
clip = dripClip;
if (s == UtilityK.Sounds.swish)
clip = swishClip;
clip.stop();
clip.setFramePosition(0);
clip.start();
//while (clip.isRunning())
// TestSounder.delay();
}
public static void main(String[] args)
{
TestSounder obj = new TestSounder();
obj.go(UtilityK.Sounds.swish);
TestSounder.delay();
obj.go(UtilityK.Sounds.drip);
TestSounder.delay();
obj.go(UtilityK.Sounds.swish);
TestSounder.delay();
obj.go(UtilityK.Sounds.drip);
TestSounder.delay();
obj.close();
}
private static void delay()
{
Thread.sleep(5000);
}
}
public interface UtilityK
{
enum Sounds { drip, swish };
}
Here is an alternative approach. It seems well suited to short sounds that might need to be played often or in quick succession as user feedback.
link to a way to play two kinds of beeps that come from .wav files
Related
I tried to play some sounds using the javax.sound.sampled package, when I encountered a strange residual beeping sound right after the clip ends. I am playing back four different audio files and the other three are working fine. I can not find a reason, why it is making this sound. Just to clarify, I checked the audio file in a editor and the beeping noise is not showing up and therefore has to be caused by Java. The following code is used to play the sounds (I am having trouble with case 1):
import java.io.IOException;
import java.net.URL;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.UnsupportedAudioFileException;
public class SoundHandler implements SoundConstants{
URL url;
public SoundHandler() {
url = this.getClass().getResource("/sounds3.wav");
}
public void playSound(int sound) {
try {
Clip clip = AudioSystem.getClip();
clip.open(AudioSystem.getAudioInputStream(url));
clip.setFramePosition(0);
clip.start();
} catch (IOException | LineUnavailableException | UnsupportedAudioFileException e) {
e.printStackTrace();
}
}
}
I have been following this tutorial for Java 1.7 and I am sure I have the code right. However, Java throws an IllegalArgumentException at runtime.
I've tried to catch it in an existing catch block, using Java's slightly-newer multi-catch. However, it simply throws exceptions.
Here is the beginning of my code.
Mixer.Info[] mixInfos = AudioSystem.getMixerInfo();
/*
for (Mixer.Info info : mixInfos)
{
System.out.println(info.getName() + " - " + info.getDescription());
}
*/
mixer = AudioSystem.getMixer(mixInfos[0]);
DataLine.Info dataInfo = new DataLine.Info(Clip.class, null);
try
{
clip = (Clip) mixer.getLine(dataInfo);
}
I expect that the code will continue running and play the Clip but I get this exception:
Exception in thread "main" java.lang.IllegalArgumentException: Line unsupported: interface Clip
at java.desktop/com.sun.media.sound.PortMixer.getLine(PortMixer.java:131)
at main.Driver.main(Driver.java:35)
Note: If this isn't forward compatible, please explain.
I think you should check your imports. AFAIK, the libraries for sound are all in javax.sound.sampled. The PortMixer is in com.sun.media.sound.
The author of the tutorial is going to a lot more trouble than is necessary. Instead of hardcoding a specific Mixer, you can just let the system pick defaults. This is probably the best strategy, as PC's out in the world are going to have diverse hardware configurations.
Following is an example that might be helpful. Notice that we don't even bother to declare a Mixer.
import java.io.IOException;
import java.net.URL;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.UnsupportedAudioFileException;
public class BasicClipExample {
public static void main(String[] args) {
BasicClipExample bc = new BasicClipExample();
try {
bc.run();
} catch (UnsupportedAudioFileException | IOException
| LineUnavailableException | InterruptedException e) {
e.printStackTrace();
}
}
private void run() throws UnsupportedAudioFileException,
IOException, LineUnavailableException, InterruptedException
{
String filename = "a3.wav";
URL url = this.getClass().getResource("audio/" + filename);
System.out.println(url);
AudioInputStream ais = AudioSystem.getAudioInputStream(url);
DataLine.Info info = new DataLine.Info(Clip.class, ais.getFormat());
Clip clip = (Clip) AudioSystem.getLine(info);
clip.open(ais);
clip.start();
Thread.sleep(6000);
clip.close();
}
}
This example assumes that your audio file is in a subdirectory called "/audio".
It also has a sleep command to keep the program running while the Clip is playing. Clips run under their own thread, but the thread is a "daemon" type and will not prevent a Java program from closing. My a3.wav is a recording of a bell that happens to last about 5 seconds.
Last thing, the above code does not use a Clip in the ideal fashion. The concept of a Clip is that it is for re-use. Reloading the clip variable before playing it each time it is played is inefficient. The clip variable should be loaded only once, and then played on demand. If you have clip.open() and clip.start() as contiguous lines of code, you should probably either be using a SourceDataLine instead of a Clip, or you should recode and put the two commands into separate methods.
I am trying to play a simple audio file which is in the same directory near the class file. I tried many examples from the internet, but all the others gave me errors which I couldn't even understand.
Then I found this, and I am using it now.
There are neither compile errors nor runtime errors. But the problem is I cannot hear any noise.
import java.io.File;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;
class A{
public static void main (String[]args){
try {
AudioInputStream audioInputStream = AudioSystem.getAudioInputStream(new File("abc.wav").getAbsoluteFile());
Clip clip = AudioSystem.getClip();
clip.open(audioInputStream);
clip.start();
} catch(Exception ex) {
System.out.println("Error with playing sound.");
}
}
}
Please note that my system volume is 80%, and the audio file plays in VLC media player.
Starting the audio clip does not block the main method. So
clip.start();
starts playing and then returns. Now your main method ends and therefore the Java process ends. No sound.
If you do
clip.start();
Thread.sleep(20000);
you should hear the clip playing for 20 seconds.
So for a working program just must make sure that the main thread does not end as long as you want to play the clip.
Hold the thread for a while until the audio clip plays.
long audioPlayTime = 1000; //clip duration in miliseconds.
try {
Thread.sleep(audioPlayTime);
} catch (InterruptedException ex){
//TODO
}
I've been rampaging about for a couple of hours now looking for sample code that can play simple wav files in Java. However, none of the ones I've received are working for me. Maybe it's just me that doesn't understand how to operate the sample code but could anyone provide me with sample code and "instructions" on how to get it working correctly. Any help would be much appreciated.
This code will create a clip and play it continuously once started:
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.Clip;
Clip clip = AudioSystem.getClip();
clip.open(AudioSystem.getAudioInputStream(new URL(filename)));
clip.start();
clip.loop(Clip.LOOP_CONTINUOUSLY);
There are more modern ways to do this, but the applet class AudioClip might satisfy your needs:
import java.applet.Applet;
import java.applet.AudioClip;
final AudioClip clip = Applet.newAudioClip(resourceUrl);
To play it once:
clip.play();
To loop:
clip.loop();
clip.stop();
See Javadocs for Applet and AudioClip
getAudioClip
public AudioClip getAudioClip(URL url)
Returns the AudioClip object specified by the URL argument.
This method always returns immediately, whether or not the audio clip exists. When this applet attempts to play the audio clip, the data will be loaded.
Parameters:
url - an absolute URL giving the location of the audio clip.
Returns:
the audio clip at the specified URL.
You don't need to actually be doing anything with applets for this to work. It will work fine in a regular Java application.
import java.io.File;
import javax.sound.sampled.*;
public void play(File file)
{
try
{
final Clip clip = (Clip)AudioSystem.getLine(new Line.Info(Clip.class));
clip.addLineListener(new LineListener()
{
#Override
public void update(LineEvent event)
{
if (event.getType() == LineEvent.Type.STOP)
clip.close();
}
});
clip.open(AudioSystem.getAudioInputStream(file));
clip.start();
}
catch (Exception exc)
{
exc.printStackTrace(System.out);
}
}
Im using Windows 7 and can "Java Platform SE Binary" in my sound mixer but yet still no sound seems to play.
My code is:
import javax.media.*;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.net.MalformedURLExc;
public class SimpleAudioPlayer {
private Player audioPlayer = null;
public SimpleAudioPlayer(URL url) throws IOException, NoPlayerException,
CannotRealizeException {
audioPlayer = Manager.createRealizedPlayer(url);
}
public SimpleAudioPlayer(File file) throws IOException, NoPlayerException,
CannotRealizeException {
this(file.toURL());
}
public void play() {
audioPlayer.start();
}
public void stop() {
audioPlayer.stop();
audioPlayer.close();
}
public static void main(String[] args) {
try{
File audioFile = new File("/t.mp3");
SimpleAudioPlayer player = new SimpleAudioPlayer(audioFile);
System.out.println();
System.out.println("-> Playing file '" +
audioFile.getAbsolutePath() + "'");
System.out.println(" Press the Enter key to exit");
player.play();
// wait for the user to press Enter to proceed.
System.in.read();
System.out.println("-> Exiting");
player.stop();
}catch(Exception ex){
ex.printStackTrace();
}
System.exit(0);
}
}
I use the Windows Preformance JMF edition. The MP3 im trying to play works fine in VLC/WMP so it cant be the file.
The code also throws no exceptions or error when running, it just doesnt seem to play the sound.
Is there something im missing? Like pulling the sound card? E.g. taking over it so i can play sound out of it?
Im overall aim is to to a MP3 streaming service using RTP/RTSP so any links,advice or tuturiols would be help as im currelnt using IBM JMF Tuturiol and Java Demo
Please ask if any more information is needed!
UPDATE-
Downloaded WAV FILE and it seemed to play, how can i make MP3s play?
Added formats and tried this code and still the same issue:
import java.io.File;
import javax.media.Format;
import javax.media.Manager;
import javax.media.MediaLocator;
import javax.media.Player;
import javax.media.PlugInManager;
import javax.media.format.AudioFormat;
public class SimpleAudioPlayer {
public static void main(String[] args) {
Format input1 = new AudioFormat(AudioFormat.MPEGLAYER3);
Format input2 = new AudioFormat(AudioFormat.MPEG);
Format output = new AudioFormat(AudioFormat.LINEAR);
PlugInManager.addPlugIn(
"com.sun.media.codec.audio.mp3.JavaDecoder",
new Format[]{input1, input2},
new Format[]{output},
PlugInManager.CODEC
);
try {
Player player = Manager.createPlayer(new MediaLocator(new File("/t.mp3").toURI().toURL()));
player.start();
}
catch(Exception ex) {
ex.printStackTrace();
}
}
}
Unable to handle format: mpeglayer3, 44100.0 Hz, 16-bit, Stereo, LittleEndian, Signed, 16000.0 frame rate, FrameSize=32768 bits
Failed to realize: com.sun.media.PlaybackEngine#62deaa2e
Error: Unable to realize com.sun.media.PlaybackEngine#62deaa2e
Thats the error!
As I thought, it's a missing codec.
I think this is what you need: http://www.oracle.com/technetwork/java/javase/download-137625.html