As part of my ongoing HAL 9000 voice obsession, I downloaded a bunch of "HAL 9000" sound files last night. But, when you double-click a sound file on Mac OS X, it automatically plays through iTunes, which is good for some things, but bad for what I wanted to do. So, I wrote a quick little "Java sound" program to read the name of a sound file from the command line, and then play the sound file.
Upon writing my little Java sound application, I was quickly reminded that on Mac OS X running a Java program from the command line creates an icon in the Mac Dock, so I also added the "headless" mode option to my command line arguments, as shown below.
Java sound application and Java headless mode
Here's the source code for my simple Java program that reads the name of a sound file as a command line argument, and then plays that sound file:
import java.io.*; import sun.audio.*; /** * A simple Java sound file example (i.e., Java code to play a sound file). * @author alvin alexander, devdaily.com. */ public class PlaySound { public static void main(String[] args) throws Exception { // expect a sound file as args[0] if (args.length != 1) { System.err.println("I need just one arg, the name of a sound file to play."); System.exit(1); } InputStream in = new FileInputStream(args[0]); // create an audiostream from the inputstream AudioStream audioStream = new AudioStream(in); // play the audio clip with the audioplayer class AudioPlayer.player.start(audioStream); } }
I compiled it like this:
javac PlaySound.java
When I went to run it like this it didn't work:
java PlaySound sound1.wav
It failed because my classpath wasn't set, as shown in this amazingly nasty-looking exception:
Exception in thread "main" java.lang.NoClassDefFoundError: PlaySound Caused by: java.lang.ClassNotFoundException: PlaySound at java.net.URLClassLoader$1.run(URLClassLoader.java:202) at java.security.AccessController.doPrivileged(Native Method) at java.net.URLClassLoader.findClass(URLClassLoader.java:190) at java.lang.ClassLoader.loadClass(ClassLoader.java:307) at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301) at java.lang.ClassLoader.loadClass(ClassLoader.java:248)
I fixed this error by running my Java command like this, telling the JVM it's okay to look in the current directory for my Java class file:
java -cp . PlaySound sound1.wav
This is when I noticed input focus was moving from my Mac Terminal window to "somewhere else", and sure enough, I saw the Java icon in the Mac Doc. To fix this problem I told the Java JVM to run in "headless" mode, like this:
java -cp . -Djava.awt.headless=true PlaySound sound1.wav
and I finally had what I wanted, a little program to play a sound file whose name I specify on the command line, with no undesired side-effects. :)
Setting Java headless mode
As one final note, if you'd rather specify the Java headless mode in your code instead of the command line, just add this line of code to your program:
System.setProperty("java.awt.headless", "true");
There's much more information on the Sun/Oracle website on Java headless mode.