Java Sound Resources: FAQ: Miscellaneous

This page presents Questions and Answers related to the Java Sound API.

1. Other Issues
1.1. Why do Java Sound programs not exit after leaving the main() method?
1.2. How can I force my Java Sound program to terminate without using System.exit(int)?
1.3. Why are the Java Sound classes not serializable?
1.4. How can I test if Java Sound is available?
1.5. Is there any documentation for the com.sun.* classes?
1.6. Can I do music notation with Java?
1.7. Can I use sound on JDKs older than 1.3?
1.8. What does these codenames like tiger and mustang mean?
2. Service Provider Interface (SPI)
2.1. What is the Service Provider Interface (SPI)?
2.2. How does Java Sound know about plug-ins (a.k.a. "service providers")?
2.3. Is it possible to add service providers at runtime?
2.4. Why are newly plugged in devices not detected by Java Sound?
2.5. Why are providers instantiated multiple times by AudioSystem / MidiSystem?
2.6. Why is MixerProvider.getMixer(Mixer.Info) called by AudioSystem even if the MixerProvider instance doesn't support the requested mixer type?
2.7. Why is it not possible to select a default provider for file readers and writers with system properties, like it is possible for MixerProvider and MidiDeviceProvider?
2.8. How can I remove a provider?
2.9. Which provider types do I have to implement to support a new audio file format?
3. Soundcard and Driver Support
3.1. Is my soundcard supported by ALSA?
3.2. Can I use a USB soundcard with Java Sound?
3.3. How can I check if my soundcard (and its device driver) supports full duplex?
3.4. Why is there no artsd/esd support in Java Sound?
3.5. Can I use Java Sound with an ASIO driver?
4. jsresources.org
4.1. Why do I get errors about gnu.getopt.Getopt not being available when trying to compile a program from the Java Sound Examples?
4.2. Is it possible to get the code of the JavaOne 2003 session "Distributed Music - Jam with Java Sound API , Project JXTA, and ogg/vorbis"?
4.3. Why is project.dtd missing from the CVS of jsresources?
4.4. Why does the Answering Machine not run?

1. Other Issues

1.1. Why do Java Sound programs not exit after leaving the main() method?
1.2. How can I force my Java Sound program to terminate without using System.exit(int)?
1.3. Why are the Java Sound classes not serializable?
1.4. How can I test if Java Sound is available?
1.5. Is there any documentation for the com.sun.* classes?
1.6. Can I do music notation with Java?
1.7. Can I use sound on JDKs older than 1.3?
1.8. What does these codenames like tiger and mustang mean?
1.1.

Why do Java Sound programs not exit after leaving the main() method?

By default, the java virtual machine terminates when all threads have terminated and the main function has also been exited. It seems that Java Sound's audio subsystem creates threads which remain, so you have to call explicitly System.exit(int). (Florian)

1.2.

How can I force my Java Sound program to terminate without using System.exit(int)?

The following is a really ugly trick, and we strongly recommend against using it. It interferes with internals of the JDK's Java Sound implementation, and it may not work in future versions.

final ThreadGroup tg = Thread.currentThread().getThreadGroup();
final Thread[] t = new Thread[tg.activeCount()];
final int active = tg.enumerate(t);
for (int i = 0; i < active; i++)
{
    if (t[i].getName().indexOf("Sound") != -1)
    {
        t[i].interrupt();
    }
}

This trick was provided by Sean A. Irvine. (Matthias)

1.3.

Why are the Java Sound classes not serializable?

There has been some discussion about making classes like AudioFormat serializable. But defining and implementing a serializable form for the data, keeping in mind that there may be subclasses, would be a lot of work and introduce implementation restrictions. Compared to that, the use cases for serializable Java Sound classes was considered too weak.

For other types of classes like SourceDataLine, TargetDataLine and AudioInputStream, serialization doesn't make sense at all: since a Line does not represent static data, but rather data is "flowing" through it, it's impossible to restore a useful state. (Matthias)

1.4.

How can I test if Java Sound is available?

Try that:

public static boolean JavaSoundInstalled()
{
    boolean result=false;
    try
    {
        result = javax.sound.sampled.AudioSystem.getMixerInfo().length > 0;
    }
    catch (Throwable t)
    {}
}

(Florian)

1.5.

Is there any documentation for the com.sun.* classes?

No, and it is strongly advised to not use them: these are internal classes of the specific implementation, and in other JVM's or even in future JVM's from Sun they may not be present. (Florian)

1.6.

Can I do music notation with Java?

Of course you can. Famous packages to do this include jMusic and Project XEMO. (Matthias)

1.7.

Can I use sound on JDKs older than 1.3?

The Java Sound API became part of the "core" - the standard APIs of the JDK - with the JDK 1.3.0. Earlier versions of the JDK don't ship with a Java Sound implementation. However, there are still ways to get sound, or even Java Sound:

  • The "performance pack" versions of the Java Media Framework (JMF) contain a Java Sound implementation can run on 1.1 Java Virtual Machines. "Performance pack" versions are available for Linux, Solaris and Windows. The "all java" version does not contain a Java Sound implementation.

  • Another way is to use the class AudioClip. This class has been available since 1.0. Since 1.1 it is possible to not only use it in applets, but also in applications. You can use Applet.newAudioClip(URL) to obtain an AudioClip instance (note that this is a static method).

(Matthias)

1.8.

What does these codenames like tiger and mustang mean?

Tiger: J2SE 1.5, Mustang: J2SE 1.6. For a complete list see J2SE Code Names. (Matthias)

2. Service Provider Interface (SPI)

2.1. What is the Service Provider Interface (SPI)?
2.2. How does Java Sound know about plug-ins (a.k.a. "service providers")?
2.3. Is it possible to add service providers at runtime?
2.4. Why are newly plugged in devices not detected by Java Sound?
2.5. Why are providers instantiated multiple times by AudioSystem / MidiSystem?
2.6. Why is MixerProvider.getMixer(Mixer.Info) called by AudioSystem even if the MixerProvider instance doesn't support the requested mixer type?
2.7. Why is it not possible to select a default provider for file readers and writers with system properties, like it is possible for MixerProvider and MidiDeviceProvider?
2.8. How can I remove a provider?
2.9. Which provider types do I have to implement to support a new audio file format?
2.1.

What is the Service Provider Interface (SPI)?

The SPI is Java Sound's plugin interface. It can be used to extend Java Sound to support more file formats, compression schemas and hardware devices. There are eight types of providers:

PackageProvider TypeUsage
javax.sound.sampled.spiAudioFileReaderused to support reading of an audio file
AudioFileWriterused to support writing to an audio file
FormatConversionProviderused to convert between different representations of audio data. This includes different sample sizes, number of channels and sample rate as well as encoded representations like ogg vorbis, mp3, μ-law and GSM 06.10
MixerProviderused to provide access to a hardware audio device (a soundcard, to speak in plain terms)
javax.sound.midi.spiMidiDeviceProviderused to support a MIDI hardware device, a Sequencer or software Synthesizer
MidiFileReaderused to support reading of MIDI files and other "structured" data files
MidiFileWriter used to support reading of MIDI files and other "structured" data files
SoundbankReaderused to support reading of different soundbank formats. Note that this is only useful in combination with implementing a Synthesizer that can use a specific soundbank format.

For more information see chapters 13 to 15 in the Java Sound Programmer's Guide. If you are writing a new provider, you might consider building on Tritonus' base classes. (Matthias)

2.2.

How does Java Sound know about plug-ins (a.k.a. "service providers")?

If installed correctly, plug-ins are recognized automatically by the runtime initialisation system of Java Sound. It scans the classpath for configuration files like /META-INF/services/javax.sound.midi.spi.MidiDeviceProvider. Since the method ClassLoader.getResources() is used for this, multiple locations can be returned. To make it work the desired way, the service providers are packaged into a .jar together with such a configuration file. The configuration file just contains fully qualified class names. See also Appendix 1: Code Overview: AudioSystem.java

By the way, this mechanism is not Java Sound specific: it's also used for I/O encoding handling, image I/O and several other locations. (Matthias)

2.3.

Is it possible to add service providers at runtime?

Yes. In JDK versions up to 1.4.2, the classpath is scanned for providers each time they need to be queried. In 1.5.0, providers are cached with a timeout of 60 seconds. So adding a service provider to the classpath will have an immediate effect or after 1 minute, respectively. Adding a provider to the classpath at runtime can be done in several ways:

  • Change the classpath to include additional .jar files or directories by setting the system property java.class.path using System.setProperty().

  • Write a .jar file into one of the extension directories.

  • Write the class files and configuration files of a provider to a directory that is already in the class path.

  • Modify a .jar file that is already in the path.

See also the other questions in this section. (Matthias)

2.4.

Why are newly plugged in devices not detected by Java Sound?

In JDK versions up to 1.4.2, new devices like newly plugged in USB devices are detected immediatly. In the JDK 1.5.0, new devices are detected after at most 60 seconds. This due to a caching mechanism that was introduced to improve performance. See also the other questions in this section. (Matthias)

2.5.

Why are providers instantiated multiple times by AudioSystem / MidiSystem?

In JDK versions up to 1.4.2, each time AudioSystem or MidiSystem needs a list of providers, it calls sun.misc.Service.providers(), which reads the configuration files, and returns an Enumeration object, than, when used, instantiates the providers (lazy instantiation). In the JDK 1.5, a cacheing mechanism was introduced. The lists of providers are instantiated completely and cached for 60 seconds.

The recommended way to deal with multiple instantiations of MixerProvider and MidiDeviceProvider subclasses is is to implement some type of singleton behaviour. For instance, information gathered at instantiation could be stored in static members, and the initialisation guarded by a flag. The other types of providers (AudioFileReader, AudioFileWriter, FormatConversionProvider, MidiFileReader, MidiFileWriter, SoundbankReader) are typically so simple that the constructor is empty anyway. (Matthias)

2.6.

Why is MixerProvider.getMixer(Mixer.Info) called by AudioSystem even if the MixerProvider instance doesn't support the requested mixer type?

(Matthias)

2.7.

Why is it not possible to select a default provider for file readers and writers with system properties, like it is possible for MixerProvider and MidiDeviceProvider?

Quote of Florian:

In general, I think it's a great idea to be able to have fine-grained control over file readers and writers, and over all plugins in general. However, we did not include file i/o in the properties file because we did not see the use case. If you install a service provider, it'll take precedence over the internal JDK ones. I don't see a use case where you install one, but don't want to use it.

From a programming point of view, I see such use cases, i.e. methods to load and unload service providers at runtime. I filed an RFE for that a long time ago, and unfortunately there wasn't enough time to implement it for 1.5: bug #4666881

(Matthias)

2.8.

How can I remove a provider?

For providers that are distributed as plug-ins packaged in a .jar file for their own, you can just remove this .jar file from the classpath.

If the provider you want to remove is packaged into a .jar file together with other providers you need, you can take the following procedure. Note that this also works for the "built-in" providers of the Sun JDK. In this case, modify the file rt.jar in the directory jre/lib.

  • Unpack the .jar file containing the provider into a temporary directory.

  • Edit the respective provider configuration file. The files are in the directory META-INF/services. The name of the configuration file reflects the type of provider it is gouverning. For instance the file javax.sound.sampled.spi.FormatConversionProvider lists the FormatConversionProvider implementations provided by this .jar file. In the file, remove or comment out (using '#') the line containing the class name of the provider you want to remove.

  • Package everything again with the modified configuration file to a new .jar file. Replace the original .jar file with the one that you just packaged newly.

See also How does Java Sound know about plug-ins (a.k.a. "service providers")? and Is it possible to add service providers at runtime? (Matthias)

2.9.

Which provider types do I have to implement to support a new audio file format?

For formats that contain PCM data, it is sufficient to implement an AudioFileReader for reading the format and an AudioFileWriter for writing the format. Note that reading and writing are mutually independant; it is not necessary to implement both if only reading or only writing is required. If the audio data is stored in a compressed format (typical examples of these are GSM and mp3), it is necessary to implement a FormatConversionProvider to convert between the compressed representation and PCM representation. Implementing a MixerProvider for a new format is not necessary. (Matthias)

3. Soundcard and Driver Support

3.1. Is my soundcard supported by ALSA?
3.2. Can I use a USB soundcard with Java Sound?
3.3. How can I check if my soundcard (and its device driver) supports full duplex?
3.4. Why is there no artsd/esd support in Java Sound?
3.5. Can I use Java Sound with an ASIO driver?
3.1.

Is my soundcard supported by ALSA?

To find out, check the ALSA Soundcard Matrix. (Matthias)

3.2.

Can I use a USB soundcard with Java Sound?

Yes, if the soundcard has a device driver that makes it available to the operating system in the usual way. (Matthias)

3.3.

How can I check if my soundcard (and its device driver) supports full duplex?

You can use native programs to check this. For instance, on Windows, you can use the sound recorder. If you can get one copy of the sound recorder recording a sound while another copy is playing a sound then your sound card/driver pair supports full duplex operation (in this case, Java Sound will support it, too). (Matthias)

3.4.

Why is there no artsd/esd support in Java Sound?

In Florian's and my opinion, mixing daemons like artsd, esd, JACK, rplay, NAS, yiff, ... are hacks that work around a shortcoming of the device drivers. We feel that mixing should be done either by the soundcard hardware or in software by the device driver. For Windows (DirectSound) and Solaris, this is self-evident, while Linux is lagging behind. The OSS driver model is obsolete technology anyway, and ALSA can do mixing in software with the dmix plug-in. With this state of affairs, all these discussions about mixing daemons could be settled once for all. Never again would a sound program have to reinvent the wheel with output plugins for /dev/dsp, ALSA, esd, arts, [you name it]. This would be a very efficient solution in terms of using (vs. wasting) programmer time. It would even enable the coexistence of several mixing daemons for backward compatibility. So why not do the obvious, elegant, technically clean, (human) resource saving?

By the way, Tritonus provides support for esd (for historical reasons; it is kept as some sort of compatibility option). See Tritonus Plug-ins. See also Q: 5.5 (Matthias)

3.5.

Can I use Java Sound with an ASIO driver?

Yes, there is an open source implementation of a MixerProvider based on the ASIO driver API. The implementation was written by Manuel Esparza as part of his master's thesis. See jsasio binary and source code.

As far as I know, Sun has no plans to implement ASIO support. As ASIO is not widely used it is not likely that this will change any time soon. (Matthias)

4. jsresources.org

4.1. Why do I get errors about gnu.getopt.Getopt not being available when trying to compile a program from the Java Sound Examples?
4.2. Is it possible to get the code of the JavaOne 2003 session "Distributed Music - Jam with Java Sound API , Project JXTA, and ogg/vorbis"?
4.3. Why is project.dtd missing from the CVS of jsresources?
4.4. Why does the Answering Machine not run?
4.1.

Why do I get errors about gnu.getopt.Getopt not being available when trying to compile a program from the Java Sound Examples?

Download GNU getopt and install it. Alternatively, there are simplified versions of some examples that do not use GNU getopt (For instance, SimpleAudioPlayer instead of AudioPlayer). (Matthias)

4.2.

Is it possible to get the code of the JavaOne 2003 session "Distributed Music - Jam with Java Sound API , Project JXTA, and ogg/vorbis"?

Yes, the code is in the CVS of jsresources, directory apps/jam. Note that you need the jmvp library that's in the CVS, too. And to disappoint you right now: the P2P part with JXTA is not yet implemented. The application only works locally. We planned to add this feature and make an official release, but we never found the time... (Matthias)

4.3.

Why is project.dtd missing from the CVS of jsresources?

You can generate project.dtd by calling 'ant -f build-dtd.xml' in the top-level directory of jsresources. The reason this file is generated is that ant has no fixed DTD, but can be extended by its own commands. (Matthias)

4.4.

Why does the Answering Machine not run?

If you run AM as an applet, you have to deal with security restrictions in applets. Especially, you need the permission for recording. For details, see the JavaOne slides (linked from the AM page).

Furthermore, you need the server part of AM running on a web server. It consists of a CGI program written in C. The code for this program is in the CVS, subdirectory src/server-cgi. Note that for security reasons, there is no server running on www.jsresources.org. (Matthias)