Java Sound Resources: FAQ: Audio Programming

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

Audio Programming

1. DataLines
1.1. General
1.1.1. How can I be notified when data is available for write/read in a SourceDataLine or TargetDataLine?
1.1.2. Why does it fail to open any line with 16 kHz sample rate?
1.1.3. How can I get a SourceDataLine or TargetDataLine in μ-law format?
1.1.4. Why does simultaneous recording and playback only work when first opening the playback line (SourceDataLine)?
1.1.5. Why doesn't simultaneous recording and playback work at all with the Sun JDK 1.3/1.4 on GNU/Linux?
1.1.6. How can I get a Line from a specific Mixer?
1.1.7. Why are there no mono lines with the "Direct Audio Devices" mixers on Linux?
1.1.8. Why is a SourceDataLine called "source" and a TargetDataLine called "target" though it's actually the other way round?
1.1.9. Why are DataLine.getFramePosition() and DataLine.getMicrosecondPosition() so inaccurate?
1.1.10. Why does DataLine.getLevel() always return -1?
1.1.11. What is the difference between DataLine.isActive() and DataLine.isRunning()?
1.1.12. How can I detect a buffer underrun or overrun?
1.1.13. Why is there no event for notifying applications of an underrun/overrun condition?
1.1.14. How can I find out the current playback or recording position?
1.1.15. How can I do looping in playback?
1.2. SourceDataLine
1.2.1. How can I avoid that the last bit of sound played on a SourceDataLine is repeated?
1.2.2. Why is playback distorted, too fast or too slow with the JDK 1.5.0 beta, but not with earlier versions of the JDK?
1.3. TargetDataLine
1.3.1. How can I capture from a specific source (microphone or line-in)?
1.3.2. How can I get more than one TargetDataLine?
1.3.3. Why is in not possible to open more than one TargetDataLine at the same time?
1.3.4. Why do I get a LineUnavailableException: "Requested format incompatible with already established device format"?
1.3.5. How can I control the volume when recording with a TargetDataLine?
1.3.6. How should I use stop() and drain() on a TargetDataLine?
1.3.7. Why is TargetDataLine.read() blocking for a long time?
1.3.8. Why is the end of recordings cut off prematurely?
1.4. Clip
1.4.1. Why do I get an out of memory exception when trying to use a Clip with a 5 MB audio file?
1.4.2. Why do I get "LineUnavailableException: No Free Voices" when opening a Clip?
1.4.3. How can I rewind a Clip?
1.4.4. Why does the frame/microsecond position not jump back to zero when a Clip is looped?
1.4.5. Why are there failures, clicks and other random effects if a clip is played multiple times with 1.5?
2. Controls
2.1. Why does the SourceDataLine instances I get when using the "Direct Audio Device" (ALSA on Linux) have no controls?
2.2. What is the difference between a BALANCE and a PAN control? Which one should I use?
2.3. Why do mono lines from a "Direct Audio Device" have no PAN control?
2.4. Why does obtaining a gain control work with 1.4.2, but not with 1.5.0?
2.5. Why do Clip and SourceDataLine instances have no VOLUME control?
2.6. Why is there no sample rate control in 1.5.0?
3. DataLine buffers
3.1. What is the minimum buffer size I can use?
3.2. Why does a line have the default buffer size though a buffer size was specified in a DataLine.Info object when obtaining the line?
3.3. Why is it not possible to use large buffers for a DataLine with 1.5.0?
4. Mixers
4.1. What are all these mixers?
4.2. Why are there mixers from which I can't get a SourceDataLine?
4.3. How can I redirect sound output to a phone / modem device?
4.4. Can I use multiple soundcards at the same time?
4.5. Why can I record from different soundcards, but not play back to them?
4.6. How can I obtain the formats supported by a mixer (or at all)?
4.7. What formats are supported by "Direct Audio Device" mixers?
4.8. Why are there AudioFormat objects with frame rate/sample rate reported as -1 when I query a Mixer for its supported formats?
4.9. How can I detect which Port Mixer belongs to which soundcard?
4.10. How can I find out which Mixer implementation is used?
4.11. Why do I get lines from the "Java Sound Audio Engine" in the JDK 1.5.0 though the "Direct Audio Device" mixers are available, too?
5. Soundcard Drivers
5.1. Which soundcard drivers can be used by Java Sound?
5.2. How can I find out which soundcard driver is used?
5.3. I've installed ALSA and the JDK 1.4.2 to take advantage of the ALSA support. Now, how do I use it?
5.4. Can I make ALSA the default in version 1.4.2?
5.5. How can I enable mixing with the "Direct Audio Device" mixers on Linux?
5.6. What are the requirements for using the direct audio devices?
5.7. How can I find out which soundcard driver is installed on my Linux system?
5.8. How does Java Sound deal with hardware buffers of the soundcard?
6. Synchronization
6.1. How can I synchronize two or more playback lines?
6.2. How can I synchronize playback (SourceDataLines) with recording (TargetDataLines)?
6.3. How can I synchronize playback to an external clock?
6.4. Do multiple Clip instances that are looped stay in sync?
6.5. Why does recording or playing for a certain period of time results in audio data that is shorter or longer than the period I recorded / played?
6.6. How can I use Mixer.synchronize()?
7. Audio Files
7.1. How can I save audio data to a file, like .wav or .aiff?
7.2. How can I add special chunks to .wav or .aiff files (like for a descriptive text or copyright)?
7.3. Is it possible to get information about loop points (e.g. from the 'smpl' chunk in .wav files) using the AudioFileFormat properties?
7.4. Why does AudioFileFormat.getFrameLength() always return -1 for .wav files?
7.5. Why does a .wav file contain PCM_UNSIGNED data if I try to save 8 bit PCM_SIGNED data?
7.6. How can I read in a .vox file and save it as .wav file?
7.7. How can I read from a headerless audio file?
7.8. How can I determine the length or the duration of an audio file?
7.9. How can I write an audio file in smaller parts?
7.10. Why are some .wav files not recognized by Java Sound?
7.11. Why is it not possible to write big-endian data using a WaveAudioOutputStream?
7.12. How can I edit or modify audio files?
7.13. How can I play audio files where the data is cached in the RAM?
7.14. Why is there a difference between using AudioSystem.write(..., File) and using AudioSystem.write(..., OutputStream) with a FileOutputStream?
7.15. Where can I find documentation on the AudioOutputStream programming?
7.16. How can I start playback of a file at a certain position?
7.17. Is it possible to read and write multichannel audio files?
7.18. How can I compare two audio files?
7.19. Is it possible to insert recorded audio data into an existing file?
7.20. How can I store an audio file in a byte array?
7.21. Which value should I use for the length of the file in AudioOutputStreams if the length is not known in advance?
8. Sample Representation and AudioFormat
8.1. How is audio represented digitally?
8.2. In which cases should I use a floating point representation for audio data?
8.3. What is the meaning of frame rate in AudioFormat?
8.4. What is the meaning of frame size in Audioformat?
8.5. What is signed / unsigned?
8.6. How can I use Java's signed byte type to store an 8 bit unsigned sample?
8.7. How can I find out if an AudioFormat is signed or unsigned?
8.8. What is endianess / big endian / little endian?
8.9. How are samples organized in a byte array/stream?
8.10. What does "unknown sample rate" in an AudioFormat object mean?
9. Conversion between sample representations
9.1. How can I convert 8 bit signed samples to 8 bit unsigned or vice versa?
9.2. How do I convert short (16 bit) samples to bytes to store them in a byte array?
9.3. How do I convert float or double samples to bytes to store them in a byte array?
9.4. How can I reconstruct sample values from a byte array?
9.5. How can I convert between mono and stereo?
9.6. How can I make a mono stream appear on one channel of a stereo stream?
10. AudioInputStreams and Byte Arrays
10.1. How can I read an audio file and store the audio data in a byte array?
10.2. How can I write audio data from a byte array to an audio file?
10.3. How can I calculate the number of bytes to skip from the length in seconds?
10.4. How do I rewind an AudioInputStream?
10.5. How do I skip backwards on an AudioInputStream?
10.6. How can I implement a real-time AudioInputStream, though I cannot give a length for it, as it is not known in advance?
10.7. How can I mix two (or more) AudioInputStream instances to a resulting AudioInputStream?
10.8. How can I create an AudioInputStream that represents a portion of another AudioInputStream?
10.9. Why does AudioInputStream.getFrameLength() return -1?
10.10. What is the difference between AudioSystem.getAudioInputStream(InputStream) and new AudioInputStream(InputStream, AudioFormat, long)?
11. Data Processing (Amplifying, Mixing, Signal Processing)
11.1. How can I do some processing on an A-law stream (like amplifing it)?
11.2. How can I detect the level of sound while I am recording it?
11.3. How can I do sample rate conversion?
11.4. How can I detect the frequency (or pitch) of sound data?
11.5. How can I do equalizing / noise reduction / fft / echo cancellation / ...?
11.6. How can I do silence supression or silence detection?
11.7. How can I do mixing of audio streams?
11.8. Should I use float or double for signal processing?
11.9. How can I do computations with complex numbers in Java?
11.10. How can I change the pitch (frequency) of audio data without changing the duration?
11.11. How can I change the duration of audio data without changing the pitch (frequency)?
11.12. How can I use reverbation?
11.13. How can I find out the maximum volume of a sound file?
11.14. How can I normalize the volume of sound?
11.15. How can I calculate the power of a signal?
12. Compression and Encodings
12.1. Ogg Vorbis
12.1.1. What is Ogg Vorbis?
12.1.2. How can I play back Ogg Vorbis files?
12.1.3. How can I encode Ogg Vorbis files?
12.1.4. Who should we lobby to get Ogg Vorbis support in the Sun JRE?
12.1.5. How can I get the duration of an Ogg Vorbis file?
12.2. mp3
12.2.1. How can I play back mp3 files?
12.2.2. Why is there no mp3 decoder in the Sun JRE/JDK?
12.2.3. What is the legal state of the JLayer mp3 decoder?
12.2.4. What are the differences between the JLayer mp3 decoder plug-in and the Sun mp3 decoder plug-in?
12.2.5. How can I encode mp3 files?
12.2.6. Is there a mp3 encoder implemented in pure java?
12.2.7. Which input formats can I use for the mp3 encoder?
12.2.8. Is mp3 encoding possible on Mac OS?
12.2.9. Why do I get an UnsupportedAudioFileException when trying to play a mp3 file?
12.2.10. How can I get the length of an mp3 stream?
12.3. GSM 06.10
12.3.1. Is there support for GSM?
12.3.2. Why does the GSM codec refuses to encode from/decode to the format I want?
12.3.3. How can I read a .wav file with GSM data or store GSM-encoded data in a .wav file?
12.3.4. I want to convert to/from GSM using the Tritonus plug-in. However, I do not work with files or streams. Rather, I want to convert byte[] arrays.
12.3.5. How can I decode GSM from frames of 260 bit?
12.3.6. How can I calculate the duration of a GSM file?
12.3.7. Are there native implementations of codecs that are compatible with the framing format used by the Java Sound GSM codec?
12.4. A-law and μ-law
12.4.1. What are A-law and μ-law?
12.4.2. How can I convert a PCM encoded byte[] to a μ-law byte[]?
12.5. Speex
12.5.1. What is Speex?
12.5.2. Is there support for Speex?
12.5.3. How do I use JSpeex?
12.5.4. How can I get the duration of a Speex file?
12.6. Miscellaneous
12.6.1. Is there support for ADPCM (a.k.a. G723) in Java Sound?
12.6.2. Is there support for WMA and ASF in Java Sound?
12.6.3. How can I convert between two encoded formats directly (e.g. from mp3 to A-law)?
12.6.4. What compression schemas can I use?
12.6.5. How can I get Encoding instances for GSM and mp3 with JDKs older than 1.5.0?
12.6.6. Is there support for RealAudio / RealMedia (.ra / .rm files)?
12.6.7. How can I get support for a new encoding?
13. Audio data transfer over networks
13.1. How can I do streaming of audio data?
13.2. Why do I get distorted sound in my streaming application if it is used on the internet, but works on a LAN?
13.3. How can I upload recorded audio data to a server?
13.4. What compression schema should I use to transfer audio data over a network?
14. Ports
14.1. How do I use the interface Port?
14.2. Why is it not possible to retrieve Port instances?
14.3. Why is it not possible to retrieve Control instances from Port lines?
14.4. What does opening and closing mean for Port lines?
14.5. Why is it not possible to read data from a microphone Port line?
14.6. Can I use Java Sound's Port interface to control volume and tone of sound played with an application using JMF?
14.7. Why are there no Port instances of certain predefined types (like Port.Info.MICROPHONE or Port.Info.COMPACT_DISC) on Linux?
15. Miscellaneous
15.1. Why is playback of audio data with Java Sound significantly quieter than with a similar player on the native OS?
15.2. Can I use multi-channel sound?
15.3. Which multi-channel soundcards can I use with Java Sound?
15.4. Can I use the rear channels of a four-channel soundcard (like Soundblaster Life! and Soundblaster Audigy)?
15.5. How can I read audio data from a CD?
15.6. Why is there no sound at all when running my program on Linux, while on Windows it works as expected?
15.7. How can I display audio data as a waveform?
15.8. What is the difference between AudioInputStream and TargetDataLine?
15.9. Does Java Sound support 24 bit/96 kHz audio?

1. DataLines

1.1. General
1.1.1. How can I be notified when data is available for write/read in a SourceDataLine or TargetDataLine?
1.1.2. Why does it fail to open any line with 16 kHz sample rate?
1.1.3. How can I get a SourceDataLine or TargetDataLine in μ-law format?
1.1.4. Why does simultaneous recording and playback only work when first opening the playback line (SourceDataLine)?
1.1.5. Why doesn't simultaneous recording and playback work at all with the Sun JDK 1.3/1.4 on GNU/Linux?
1.1.6. How can I get a Line from a specific Mixer?
1.1.7. Why are there no mono lines with the "Direct Audio Devices" mixers on Linux?
1.1.8. Why is a SourceDataLine called "source" and a TargetDataLine called "target" though it's actually the other way round?
1.1.9. Why are DataLine.getFramePosition() and DataLine.getMicrosecondPosition() so inaccurate?
1.1.10. Why does DataLine.getLevel() always return -1?
1.1.11. What is the difference between DataLine.isActive() and DataLine.isRunning()?
1.1.12. How can I detect a buffer underrun or overrun?
1.1.13. Why is there no event for notifying applications of an underrun/overrun condition?
1.1.14. How can I find out the current playback or recording position?
1.1.15. How can I do looping in playback?
1.2. SourceDataLine
1.2.1. How can I avoid that the last bit of sound played on a SourceDataLine is repeated?
1.2.2. Why is playback distorted, too fast or too slow with the JDK 1.5.0 beta, but not with earlier versions of the JDK?
1.3. TargetDataLine
1.3.1. How can I capture from a specific source (microphone or line-in)?
1.3.2. How can I get more than one TargetDataLine?
1.3.3. Why is in not possible to open more than one TargetDataLine at the same time?
1.3.4. Why do I get a LineUnavailableException: "Requested format incompatible with already established device format"?
1.3.5. How can I control the volume when recording with a TargetDataLine?
1.3.6. How should I use stop() and drain() on a TargetDataLine?
1.3.7. Why is TargetDataLine.read() blocking for a long time?
1.3.8. Why is the end of recordings cut off prematurely?
1.4. Clip
1.4.1. Why do I get an out of memory exception when trying to use a Clip with a 5 MB audio file?
1.4.2. Why do I get "LineUnavailableException: No Free Voices" when opening a Clip?
1.4.3. How can I rewind a Clip?
1.4.4. Why does the frame/microsecond position not jump back to zero when a Clip is looped?
1.4.5. Why are there failures, clicks and other random effects if a clip is played multiple times with 1.5?

1.1. General

1.1.1. How can I be notified when data is available for write/read in a SourceDataLine or TargetDataLine?
1.1.2. Why does it fail to open any line with 16 kHz sample rate?
1.1.3. How can I get a SourceDataLine or TargetDataLine in μ-law format?
1.1.4. Why does simultaneous recording and playback only work when first opening the playback line (SourceDataLine)?
1.1.5. Why doesn't simultaneous recording and playback work at all with the Sun JDK 1.3/1.4 on GNU/Linux?
1.1.6. How can I get a Line from a specific Mixer?
1.1.7. Why are there no mono lines with the "Direct Audio Devices" mixers on Linux?
1.1.8. Why is a SourceDataLine called "source" and a TargetDataLine called "target" though it's actually the other way round?
1.1.9. Why are DataLine.getFramePosition() and DataLine.getMicrosecondPosition() so inaccurate?
1.1.10. Why does DataLine.getLevel() always return -1?
1.1.11. What is the difference between DataLine.isActive() and DataLine.isRunning()?
1.1.12. How can I detect a buffer underrun or overrun?
1.1.13. Why is there no event for notifying applications of an underrun/overrun condition?
1.1.14. How can I find out the current playback or recording position?
1.1.15. How can I do looping in playback?
1.1.1.

How can I be notified when data is available for write/read in a SourceDataLine or TargetDataLine?

You have to use SourceDataLine/TargetDataLine.available(). The usual implementation for streaming audio (in Java Sound) is a dedicated thread for that - look at the Java Sound Demo which you can download from Sun or at the Java Sound Resources: Examples. (Florian)

1.1.2.

Why does it fail to open any line with 16 kHz sample rate?

Apparently, most Java Sound implementations do not provide that, even if the soundcard supports it. Future implementations will support that. (Florian)

1.1.3.

How can I get a SourceDataLine or TargetDataLine in μ-law format?

TargetDataLines are supposed to act as a "direct" way to communicate with the audio hardware device, i.e. your soundcard. When your soundcard does not support μ-law directly, the TargetDataLine won't either.

The way to go is to open a TargetDataLine in pcm format and route it through a format converter. See doc of AudioSystem to get converted Streams. The converted stream you get provides μ-law samples then.

There is no drawback in this approach: all PC soundcards that I know of deliver only PCM, so it has to be rendered to μ-law anyway in software. Whether in the soundcard's driver, the operating system layer or in the application (your java program) doesn't matter. You get maximum portability when only using pcm for TargetDataLines. (Florian)

1.1.4.

Why does simultaneous recording and playback only work when first opening the playback line (SourceDataLine)?

This depends on the soundcard and its driver to the native operating system. E.g. Soundblaster 16 or 64 do not provide real full duplex, only a kind of pseudo full duplex. I experienced under Windows that you can only use this pseudo full duplex when you have a certain order in opening record/playback lines. (Florian)

1.1.5.

Why doesn't simultaneous recording and playback work at all with the Sun JDK 1.3/1.4 on GNU/Linux?

Due to problems with some OSS drivers, full-duplex is disabled by default in versions up to 1.4.1. There are several ways to get full-duplex:

  • Use the ALSA support in JDK 1.4.2 or later. Note that in 1.4.2, the ALSA support is not used by default for playback. If you call AudioSytem.getLine(), the default is used ("Java Sound Audio Engine"). To use the "Direct Audio Device" (which uses ALSA), obtain the respective mixer with AudioSystem.getMixer() and call getLine() on the mixer. To detect the "Direct Audio Device", look for a string "ALSA" in the vendor or description string of the Mixer.Info object. Although string comparison is not a nice way, it is higly likely that "ALSA" will appear in at least one of the string in future releases. For recording, the "Direct Audio Device" is the default. A way to make the is the default for playback, too, is to rename /dev/audio and /dev/dsp. However, this will disable sound support for all non-ALSA programs. In version 1.5, the "Direct Audio Device" are the default for playback, too, if the soundcard supports mixing in hardware.

  • Use Tritonus. The Tritonus plug-ins work with Java versions that are older than 1.4.2, too. However, it is recommended to use 1.4.2 if possible. The ALSA support in 1.4.2 is more stable than the one in Tritonus.

See also Q: 3.3 (Matthias)

1.1.6.

How can I get a Line from a specific Mixer?

Obtain the list of available Mixer implementations with AudioSystem.getMixerInfo(). Select one of the available and call AudioSystem.getMixer(Mixer.Info) to obtain the Mixer. With this object you can call Mixer.getLine(Line.Info) instead of AudioSystem.getLine(Line.Info). In the JDK 1.5.0, you can also use the ease-of-use methods in AudioSystem:

With the JDK 1.5.0, there is an additional possibility: The default provider properties can be used to select the default Mixer for each type of line (SourceDataLine, TargetDataLine, Clip, Port). The default Mixer, if available, is used in AudioSystem.getLine(). For details, see the specification. (Matthias)

1.1.7.

Why are there no mono lines with the "Direct Audio Devices" mixers on Linux?

The implementation of the "Direct Audio Device" queries the soundcard driver for the supported formats. Some ALSA drivers do not support mono lines, so they are not available in the "Direct Audio Device". The workaround is to open a stereo line and expand the mono data to stereo. See also How can I convert between mono and stereo? and How can I make a mono stream appear on one channel of a stereo stream? (Matthias)

1.1.8.

Why is a SourceDataLine called "source" and a TargetDataLine called "target" though it's actually the other way round?

Well, nobody really knows why this fancy naming was chosen. From the perspective of an application, it's counter-intuitive. To understand it, take the perspective of a Mixer object: It receives data from the application via a SourceDataLine object, this is its source of data. And it delivers data to the application via a TargetDataLine. So from the perspective of the Mixer, this is the target of its data. (Matthias)

1.1.9.

Why are DataLine.getFramePosition() and DataLine.getMicrosecondPosition() so inaccurate?

The implementation of these methods in the "Java Sound Audio Engine" is bad and will not be fixed. The "Direct Audio Device" has a much better implementation. See also What are all these mixers?

But keep in mind that it is not possible to get a frame precise playback position with these methods. There is too much buffering in the data path (also in the audio hardware), so calculating the position is always only an estimation.

If you try to measure the precision of DataLine.getMicrosecondPosition() with a real-time clock, you are also likely to see the effect of a clock drift. For details on this phenomenon see Why does recording or playing for a certain period of time results in audio data that is shorter or longer than the period I recorded / played? (Matthias)

1.1.10.

Why does DataLine.getLevel() always return -1?

DataLine.getLevel() is not implemented in current versions of the Sun JDK (1.4.1), nor in any other known Java Sound implementation. Here is a suggestion from Florian Bomers on how to implement this functionality yourself:

  • Read the data from the TargetDataLine in blocks.

  • Convert each block to a common format, e.g. normalized floats [-1, +1], or 8 bit signed bytes. If your project can make use of LGPL'd code, have a look at class FloatSampleBuffer (for floats) or TConversionTool (for integer-based values) of the Tritonus project.

  • Calculate the level of the block. This could be the average, RMS power, peak amplitude, or similar. Be sure to use the absolute values (or squaring the amplitudes for the power). See also How can I calculate the power of a signal?

(Matthias)

1.1.11.

What is the difference between DataLine.isActive() and DataLine.isRunning()?

This is an issue where even the Java Sound gurus do not know a satisfying answer. A useful definition would be the following:

  • isActive() returns true if the line is in started state, i.e. between calls to start() and stop().

  • isRunning() returns true if data is actually read from or written to the device. This would mean that isRunning() returns false in case of buffer underruns or overruns.

However, this is not the way it is implemented. For the "Direct Audio Device" mixers, isActive() and isRunning() always return the same value. In general, it is recommended to use isActive(), since it is specified less ambigously and it is implemented consistently. See also bug #4791152. (Matthias)

1.1.12.

How can I detect a buffer underrun or overrun?

The following is working reliably at least with the "Direct Audio Device" mixers:

  • SourceDataLine: underrun if (line.available() == line.getBufferSize())

    SourceDataLine.available(): how much data can be written to the buffer. If the whole buffer can be written to, there is no data in the buffer to be rendered.

  • TargetDataLine: overrun if (line.available() == line.getBufferSize())

    TargetDataLine.available(): how much data can be read from the buffer. If the whole buffer can be read, there is no space in the buffer for new data captured from the line.

(Matthias)

1.1.13.

Why is there no event for notifying applications of an underrun/overrun condition?

This is Florian's (and my) opinion:

Java Sound is a low level audio API. We decided to give highest priority to performance and "bare" functionality, rather than adding many high-level features. And although this is not a reason to not add it, all low level audio API's that I have worked closely with do not provide underrun notification.

(Matthias)

1.1.14.

How can I find out the current playback or recording position?

There are two possibilities:

  • Use DataLine.getFramePosition() or DataLine.getFramePosition(). These methods are supposed to return the current "hearing" position. However, they weren't implemented well prior to the JDK 1.5.0.

  • Count the frames that you read from or write to the DataLine and add one full buffer size and 15 milliseconds (ballpark figure for hardware delay) to it. As reference point use the time when the write()/read() method returns. This allows amount correct extrapolation. This method works best if you call read()/write() with buffers that fit exactly into the line's buffer size.

    This approach also works reasonably fine with 1.4.2 and before. It is implemented in the JAM program at J1 2003.

(Matthias)

1.1.15.

How can I do looping in playback?

There are two possibilities:

(Matthias)

1.2. SourceDataLine

1.2.1. How can I avoid that the last bit of sound played on a SourceDataLine is repeated?
1.2.2. Why is playback distorted, too fast or too slow with the JDK 1.5.0 beta, but not with earlier versions of the JDK?
1.2.1.

How can I avoid that the last bit of sound played on a SourceDataLine is repeated?

This can be avoided easily: after writing all data to the SourceDataLine call drain() and stop(). If you want to reuse the line after this, call start() again before writing more data to the line. (Matthias)

1.2.2.

Why is playback distorted, too fast or too slow with the JDK 1.5.0 beta, but not with earlier versions of the JDK?

The reason is a common misconception about how Line.open() works. According to the specification, open() without parameters opens a line in a "default format". The default format of a line is an implementation specific property. It is not the AudioFormat used in the DataLine.Info object. Rather, the format in DataLine.Info is used to request a DataLine instance that is capable of handling this format. This does not necessarily mean that the line has to be opened in that format. Note that it is possible to construct DataLine.Info with an array of AudioFormat objects. This means that the requested line has to be able to handle any of the given formats.

The Java Sound implementaion prior to JDK 1.5.0 had the following property: If only one AudioFormat is given in a DataLine.Info, this AudioFormat becomes the default format of the line. This caused the behaviour that it was possible to specify the format for open() via the DataLine.Info object. However, this behaviour was never specified, it is just an implementation specific property you can't rely on in general. The "Direct Audio Device" mixers in JDK 1.5.0 beta (see also What are all these mixers?) behave different: they just pick one of the supported hardware formats as default format. This is a correct behaviour according to the specification, since the specification doesn't specify how the default format is chosen.

Therefore, it is recommended to always specify the format when opening a DataLine: use open(AudioFormat format) or open(AudioFormat format, int buffersize) rather than Line.open() without parameters. See also Line.open(), SourceDataLine.open(AudioFormat), SourceDataLine.open(AudioFormat, int), TargetDataLine.open(AudioFormat) and TargetDataLine.open(AudioFormat, int)

Wrong code
AudioFormat format = ...;
DataLine.Info info = new DataLine.Info(SourceDataLine.class, format);
// line is *capable* of being opened in format
SourceDataLine line = (SourceDataLine) AudioSystem.getLine(info);
// open in default format, not necessarily the same as format
line.open();
Correct code
AudioFormat format = ...;
DataLine.Info info = new DataLine.Info(SourceDataLine.class, format);
// line is *capable* of being opened in format
SourceDataLine line = (SourceDataLine) AudioSystem.getLine(info);
// open in desired format
line.open(format);

It was decided to change the behaviour for the final version of the JDK 1.5.0 to provide backward compatibility with the JDK 1.4. The former unportable technique will be specified behaviour. See also bugs #5053380 and #5067526 (Matthias)

1.3. TargetDataLine

1.3.1. How can I capture from a specific source (microphone or line-in)?
1.3.2. How can I get more than one TargetDataLine?
1.3.3. Why is in not possible to open more than one TargetDataLine at the same time?
1.3.4. Why do I get a LineUnavailableException: "Requested format incompatible with already established device format"?
1.3.5. How can I control the volume when recording with a TargetDataLine?
1.3.6. How should I use stop() and drain() on a TargetDataLine?
1.3.7. Why is TargetDataLine.read() blocking for a long time?
1.3.8. Why is the end of recordings cut off prematurely?
1.3.1.

How can I capture from a specific source (microphone or line-in)?

You can use the system mixer of your operating system to select the recording source in the same way you would do it for a native program. With newer versions of the Sun JDK, you can achieve the same by using the interface javax.sound.sampled.Port. See the section Ports for details. (Matthias)

1.3.2.

How can I get more than one TargetDataLine?

Current implementations of the Java Sound API do not support multiple TargetDataLines for the same recording source. There are no plans to change this behaviour. If, in the future, multi-channel soundcards are supported, it may be possible to get different TargetDataLine instances for the different inputs. If you just want to "split" lines, do it in your application. See also Can I use multi-channel sound? (Matthias)

1.3.3.

Why is in not possible to open more than one TargetDataLine at the same time?

Well, because it's a bug. The above is true for the Sun JDK up to version 1.4.2 on Solaris and Windows, and up to 1.4.1 on Linux. Beginning with version 1.5.0 for Solaris and Windows and version 1.4.2 for Linux there are the new "Direct Audio Device" mixer that don't have this limitation.

Tritonus is unaffected by this limitation. (Matthias)

1.3.4.

Why do I get a LineUnavailableException: "Requested format incompatible with already established device format"?

This is a bug that was fixed for 1.4.2. If you have to use an older version, there are two possible workarounds:

  • Do not play back anything using the "Java Sound Audio Engine" before recording. In version prior to 1.4.2, there is no way of doing playback at all without using the "Java Sound Audio Engine". If the "Java Sound Audio Engine" is used, it results in opening the sound device for 44100 Hz, 16 bit stereo, thereby setting the "previously established format".

  • Always capture at 16 bit, stereo, 44100Hz. If you need your sound data in a different format, you can convert it afterwards. See also Conversion between sample representations and How can I do sample rate conversion?

(Matthias)

1.3.5.

How can I control the volume when recording with a TargetDataLine?

The obvious solution would be to get a Control object of type VOLUME or MASTER_GAIN for the TargetDataLine and manipulate the volume via this object. However, this is not possible, since no known Java Sound implementation supports any controls for TargetDataLine instances.

What you can do is to use the system mixer to control the recording volume --- it affects hardware settings in the soundcard. One possibility is to use the mixer application of the operating system. The other possibility is using Port lines from inside a Java Sound application. See the section Ports for details.

The remaining possibility is to implement a volume control digitally: multiplying each single sample of the sound data with a certain value that lowers or raises the level proportionally. See also Change the amplitude (volume) of an audio file (Matthias)

1.3.6.

How should I use stop() and drain() on a TargetDataLine?

It is specified that TargetDataLine.drain() has to wait until all data has been delivered to the TargetDataLine. If the line is not yet stopped, there is always data being delivered to the line. So you should call drain() only after stop(). In fact, drain() isn't needed with TargetDataLine at all.

A common technique to terminate reading from a TargetDataLine is the following:

TDL.stop();
do
{
    count = TDL.read();
}
while (count > 0);
TDL.close();

For an implementation of TargetDataLine.drain() to be 100% compliant you need to block when the line is started and there is still data available. One way to do this is the following:

public void drain()
{
    while (isActive() && (available() > 0))
    {
        Thread.sleep(100);
    }
}

(Matthias)

1.3.7.

Why is TargetDataLine.read() blocking for a long time?

By specification, TargetDataLine.read() is a blocking call: it waits until the requested amount of data is available. To use read() in a non-blocking manner, you can check how much data is available with available() and request only that amount. If you want to use read() in a standard blocking manner, but need quick response for a real-time application, use smaller buffers for reading. See also What is the minimum buffer size I can use? (Matthias)

1.3.8.

Why is the end of recordings cut off prematurely?

Even after calling stop() on a TargetDataLine, there may be data remaining in its internal buffer. Make sure you read data until there is no more available. Then you can call close() on the line. See also How should I use stop() and drain() on a TargetDataLine? (Matthias)

1.4. Clip

1.4.1. Why do I get an out of memory exception when trying to use a Clip with a 5 MB audio file?
1.4.2. Why do I get "LineUnavailableException: No Free Voices" when opening a Clip?
1.4.3. How can I rewind a Clip?
1.4.4. Why does the frame/microsecond position not jump back to zero when a Clip is looped?
1.4.5. Why are there failures, clicks and other random effects if a clip is played multiple times with 1.5?
1.4.1.

Why do I get an out of memory exception when trying to use a Clip with a 5 MB audio file?

For files of this size, you should stream the audio. Like that you treat buffers of small size and feed them successively into the audio device. Look at the Java Sound Resources: Examples, there are some streaming audio players to take as a start. (Florian)

1.4.2.

Why do I get "LineUnavailableException: No Free Voices" when opening a Clip?

This happens with the "Java Sound Audio Engine" when too many clips are open. While you can obtain any number of Clip instances, only 32 can be open at the same time. This is a hard limitation of the engine; it can only mix 32 channels. As a workaround, you can close unused clips and open them once they are needed again. If you really need more than 32 channels, you can do the mixing in your application and output the result to a SourceDataLine. (Matthias)

1.4.3.

How can I rewind a Clip?

Stop the clip by calling stop(), then use clip.setFramePosition(0) or clip.setMicrosecondPosition(0). Alternativly, you can set looping points so that rewinding occurs automatically: clip.setLoopPoints(0, -1) (In this case you have to call clip.loop(...) instead of clip.start().) (Matthias)

1.4.4.

Why does the frame/microsecond position not jump back to zero when a Clip is looped?

getFramePosition() and getMicrosecondPosition() are specified to return the position corresponding to the time since the line (or clip) was opened. If you want to get the position inside the loop of a looping clip, you can use something similar to this (assuming you are looping over the whole length of the clip):

currentFrame = clip.getFramePosition() %
clip.getFrameLength();

(Matthias)

1.4.5.

Why are there failures, clicks and other random effects if a clip is played multiple times with 1.5?

This is a bug, and apparently one not easy to fix. See bug #6251460. Note that you can work around this issue by using the old "Java Sound Audio Engine" instead of the "Direct Audio Device" mixers. This way, you get the same behaviour as in 1.4. See also What are all these mixers? (Matthias)

2. Controls

2.1. Why does the SourceDataLine instances I get when using the "Direct Audio Device" (ALSA on Linux) have no controls?
2.2. What is the difference between a BALANCE and a PAN control? Which one should I use?
2.3. Why do mono lines from a "Direct Audio Device" have no PAN control?
2.4. Why does obtaining a gain control work with 1.4.2, but not with 1.5.0?
2.5. Why do Clip and SourceDataLine instances have no VOLUME control?
2.6. Why is there no sample rate control in 1.5.0?
2.1.

Why does the SourceDataLine instances I get when using the "Direct Audio Device" (ALSA on Linux) have no controls?

Lines from these mixers do not provide controls in 1.4.2. In Florian's original opinion, "any control would obscure the initial idea, to provide high-performance direct audio access". However, he changed his mind and implemented volume and balance controls in 1.5.0. (Matthias)

2.2.

What is the difference between a BALANCE and a PAN control? Which one should I use?

In music, pan knobs are used for mono input lines to control how they are mapped to stereo output lines. On the other hand, for stereo input lines, the knob is labelled "balance". So you should get a PAN control for mono lines and a BALANCE control for stereo lines (and none for lines with more than 2 channels).

In the Sun J2SDK, PAN controls behave like BALANCE controls for stereo lines and BALANCE like PAN for mono lines. However, this is only a convenience for compatibility. To write portable programs, you should not rely on this behaviour. (Matthias)

2.3.

Why do mono lines from a "Direct Audio Device" have no PAN control?

To implement a PAN control for a mono line, it has to be "distributed" between the left and right channel of a stereo line. This was no problem with the "Java Sound Audio Engine". The "Java Sound Audio Engine" always opens the soundcard in stereo, so it is always possible to do this "distribution". The "Direct Audio Device" implementation, however, opens the soundcard in mono if a mono line is requested. So it's not possible to implement a PAN control for such lines.

The workaround is to work with stereo: convert your stream to stereo and open the SourceDataLine in that stereo format. Then this line will have a BALANCE control, which works like a PAN control. See also How can I convert between mono and stereo? and What is the difference between a BALANCE and a PAN control? Which one should I use? (Matthias)

2.4.

Why does obtaining a gain control work with 1.4.2, but not with 1.5.0?

Gain (FloatControl.Type.MASTER_GAIN / FloatControl.Type.VOLUME) controls are still available with the "Direct Audio Device" mixers in 1.5.0 (see also What are all these mixers?). However, the behaviour has been changed so that controls are only available after the line has been opened. This was necessary because in general, some control are only available if the device driver supports certain features, which can be queried only after the respective device has been opened. (Matthias)

2.5.

Why do Clip and SourceDataLine instances have no VOLUME control?

Clip and SourceDataLine instances provide a FloatControl.Type.MASTER_GAIN control rather than a FloatControl.Type.VOLUME control to control the playback volume. See also Why does obtaining a gain control work with 1.4.2, but not with 1.5.0? (Matthias)

2.6.

Why is there no sample rate control in 1.5.0?

The "Direct Audio Device" mixers in 1.5 (see What are all these mixers?) do not provide a sample rate control. To cite Florian:

This is mostly because we wanted to give direct access to the sound hardware, without the problems of high-level features — namely latency and processor usage. We may add sample rate in future if we find a good way to add it without affecting performance.

As an alternative, you can resample your data with a sample rate converter to achieve the same effect. See also How can I do sample rate conversion?

Or, you can still use the sample rate control of the "Java Sound Audio Engine" with 1.5 by requesting lines directly from it. See How can I get a Line from a specific Mixer? (Matthias)

3. DataLine buffers

3.1. What is the minimum buffer size I can use?
3.2. Why does a line have the default buffer size though a buffer size was specified in a DataLine.Info object when obtaining the line?
3.3. Why is it not possible to use large buffers for a DataLine with 1.5.0?
3.1.

What is the minimum buffer size I can use?

Obviously, this depends on the operating system, the hardware, the Java VM, which Mixer implementation you use and several other factors. The following measurements have been found experimentally on a very old PC (350 MHz) under Linux with the Sun JDK 1.4.2_02:

formatsample ratePlaybackRecording
Java Sound Audio EngineDirect Audio DeviceSimple Input DeviceDirect Audio Device
8 bit mono11025 Hzno resultsno resultsno resultsno results
22050 Hzno resultsno resultsno resultsno results
44100 Hzno resultsno resultsno resultsno results
8 bit stereo11025 Hzno resultsno resultsno resultsno results
22050 Hzno resultsno resultsno resultsno results
44100 Hzno resultsno resultsno resultsno results
16 bit mono11025 Hz1024 bytesno resultsno resultsno results
22050 Hz2048 bytesno resultsno resultsno results
44100 Hz4096 bytesno resultsno resultsno results
16 bit stereo11025 Hzno resultsno resultsno resultsno results
22050 Hzno resultsno resultsno resultsno results
44100 Hzno resultsno resultsno resultsno results

These measurements suggest that the latency introduced by buffers in the "Java Sound Audio Engine" is about 50 ms, independant of the sample rate. (Matthias)

3.2.

Why does a line have the default buffer size though a buffer size was specified in a DataLine.Info object when obtaining the line?

This happens with the "Direct Audio Device" of the JDK 1.5.0 if the line is opened with open(AudioFormat) instead of open(AudioFormat, int). The reason for this behaviour is that by requiring a certain buffersize or range of buffersizes in DataLine.Info, you obtain a line that is capable of setting its buffersize to the respective value. You still have to choose the actual value. This is done when opening the line: with open(AudioFormat, int), a certain buffer size for the line can be specified. If open(AudioFormat) is used, the line is opened with the default buffer size. Until 1.4.2, a buffersize in DataLine.Info was used in opening if the open() call does not specify a buffer size. However, it was decided that automatically taking over this value is a questionable convenience. (Matthias)

3.3.

Why is it not possible to use large buffers for a DataLine with 1.5.0?

The DataLine implementation of the "Java Sound Audio Engine" has a circular buffer per line instance. For SourceDataLine instances, write() writes data to this buffer. A separate thread reads from the circular buffer and transfers the data to the native layer of the engine. This allows for arbitrary sized buffers, but results in the overhead of an additional buffer and one thread per DataLine.

The DataLine implementation of the "Direct Audio Device" of 1.5.0 does not have a circular buffer. Instead, it writes/reads data directly to/from the soundcard driver. This gives higher performance and lower latency. On the other hand, it restricts buffer sizes to what the soundcard driver supports.

Adding a layer of buffering to the "Direct Audio Device" mixers would result in the same performance penalty as the DataLine implementation of the "Java Sound Audio Engine". It would introduce a general overhead though the additional functionality is only needed in special cases. Therefore, it is unlikely that the implementation of the "Direct Audio Device" mixers will be changed to allow larger buffers.

If you need larger buffers, you can implement an additional layer with a circular buffer in your application. Then you can choose any size you want for this buffer. And note that you need an additional thread — like the "Java Sound Audio Engine". The Answering Machine has classes that do a similar job. There is also the class org.tritonus.share.TCircularBuffer in Tritonus that you can use for this purpose. (Matthias)

4. Mixers

4.1. What are all these mixers?
4.2. Why are there mixers from which I can't get a SourceDataLine?
4.3. How can I redirect sound output to a phone / modem device?
4.4. Can I use multiple soundcards at the same time?
4.5. Why can I record from different soundcards, but not play back to them?
4.6. How can I obtain the formats supported by a mixer (or at all)?
4.7. What formats are supported by "Direct Audio Device" mixers?
4.8. Why are there AudioFormat objects with frame rate/sample rate reported as -1 when I query a Mixer for its supported formats?
4.9. How can I detect which Port Mixer belongs to which soundcard?
4.10. How can I find out which Mixer implementation is used?
4.11. Why do I get lines from the "Java Sound Audio Engine" in the JDK 1.5.0 though the "Direct Audio Device" mixers are available, too?
4.1.

What are all these mixers?

There are several implementations of Mixer in Java Sound:

"Java Sound Audio Engine", beatnik engine

This is a software mixing engine. It provides SourceDataLine and Clip instances. It does not provide TargetDataLine instances. Output of this mixer goes to the audio device. In versions up to 1.4.2, this mixer is the default for playback. In 1.5, it is only used if there is no other way to mix audio streams (because neither the soundcard hardware nor the device driver support mixing).

Simple Input Devices, "Microsoft Sound Mapper" (Windows), "Linux,dev/dsp,multi threaded" (Linux), "Linux,dev/audio,multi threaded" (Linux, Solaris)

In versions 1.4.2 and earlier, this mixer is used for recording. It provides TargetDataLine instances, but nothing else. In 1.5, it is no longer available, because the direct audio devices can be used for recording on all platforms.

Direct Audio Devices, "Primary Sound Driver" (Windows), "Primary Sound Capture Driver" (Windows), "Soundcard [plughw:0,0]" (Linux)

These are mixers that can be used for playback as well as for recording. They provide SourceDataLine, TargetDataLine and Clip instances. In 1.4.2, they became available on Linux; in 1.5, Solaris and Windows followed. These mixers allow simultaneous playback and recording (full-duplex) if the soundcard supports it. These mixers do not do software mixing. So mixing of multiple playback lines is only available if either the soundcard hardware or the device driver are capable of mixing. In other words: You may get only one SourceDataLine, and you will always get only one TargetDataLine

Port Mixers, "Port Soundcard" (Windows), "Port Soundcard [hw:0,0]" (Linux)

These mixers provide Port instances, but no other type of Line. So you can't play back or record with these mixers. They became available with 1.4.2 for Windows, and will be available for Solaris and Linux, too, in 1.5. See also Ports

Note that what Java Sound calls "Mixer" is different from what Windows calls "Mixer":

Java SoundWindows
Mixeraudio device
Portmixer

See also How can I find out which Mixer implementation is used? (Matthias)

4.2.

Why are there mixers from which I can't get a SourceDataLine?

There are mixer that only provide TargetDataLine instances. In the Sun JDK up to 1.4.2, SourceDataLine instances are only provided by the "Java Sound Audio Engine", while TargetDataLine instances are only provided by the "Simple Input Device" mixers. This is subject to change for JDK 1.5.

Starting with version 1.4.2, there are additional mixers that provide only Port instances. See also What are all these mixers? (Matthias)

4.3.

How can I redirect sound output to a phone / modem device?

With the Sun JDK 1.4.2 or earlier on Windows, you can set the default audio device to the telephone device: Control panel -> Multimedia (or Sounds...) -> Preferred Device. With the "Direct Audio Device" mixers of the JDK 1.5 it is also possible to use the default provider properties to set the default Mixer / MixerProvider inside Java Sound.

See also Why are there mixers from which I can't get a SourceDataLine?, How can I capture from a specific source (microphone or line-in)?, How can I get a Line from a specific Mixer? and Why can I record from different soundcards, but not play back to them? (Matthias)

4.4.

Can I use multiple soundcards at the same time?

For the Sun JDK, this is possible with version 1.4.2 and later for Linux and with version 1.5.0 and later for Solaris and Windows. For Tritonus, this is possible with the ALSA Mixer implementation. (Matthias)

4.5.

Why can I record from different soundcards, but not play back to them?

This is true for Solaris and Windows for Java versions up to 1.4.2. There, playback is only possible via the "Java Sound Audio Engine", which always uses the first soundcard. On the other hand, recording in these versions is done with the "Simple Input Device", which provider one Mixer instance per soundcard.

With the "Direct Audio Device" mixers, it is possible to choose different soundcards for output, too. See also What are all these mixers? (Matthias)

4.6.

How can I obtain the formats supported by a mixer (or at all)?

First, obtain a list of supported lines either from a Mixer object or from AudioSystem. For this, use the methods getSourceLineInfo() and getTargetLineInfo(). Then, check each of the returned Line.Info objects if it is an instance of DataLine.Info. If it is, cast the object to DataLine.Info. Now you can call getFormats() to obtain the AudioFormat types supported by this line type.

A code example:

Line.Info[] infos = AudioSystem.getSourceLineInfo();
// or:
// Line.Info[] infos = AudioSystem.getTargetLineInfo();
for (int i = 0; i < infos.length; i++)
{
  if (infos[i] instanceof DataLine.Info)
  {
    DataLine.Info dataLineInfo = (DataLine.Info) infos[i];
    AudioFormat[] supportedFormats = dataLineInfo.getFormats();
  }
}

To see what is supported on your system, you can use the application jsinfo. See also Why are there AudioFormat objects with frame rate/sample rate reported as -1 when I query a Mixer for its supported formats? (Matthias)

4.7.

What formats are supported by "Direct Audio Device" mixers?

It depends on the hardware. The mixers just report formats that are supported by the device driver. Typically, there are between 8 and 20 supported formats. To write a portable application, you should not assume that a certain format is always supported (though in fact, 44.1 kHz 16 bit stereo is almost always supported). Rather, you should check the supported formats at run-time and try to convert your audio data to one of the available formats. See also How can I obtain the formats supported by a mixer (or at all)? (Matthias)

4.8.

Why are there AudioFormat objects with frame rate/sample rate reported as -1 when I query a Mixer for its supported formats?

The -1 (AudioSystem.NOT_SPECIFIED) means that any reasonable sample rate is supported. Common soundcards typically support sample rates between 4 kHz and 48 kHz. See also How can I obtain the formats supported by a mixer (or at all)? (Matthias)

4.9.

How can I detect which Port Mixer belongs to which soundcard?

There is no really satisfying solution. You can try to match the name in the Mixer.Info object of a Port Mixer against the one of a DataLine Mixer. On Linux, this is reliable by looking at the device id that is part of the mixer name: "(hw:0)", "(hw:1)", "(plughw:0,1)". The first (or only) number refers to the number of the soundcard.

Windows don't allow to query which port belongs to which soundcard (there are ways on Windows, but it was not possible to use them for Java Sound because they require actually opening the devices). So the only thing you can do is to match the name of the soundcard. However, this will not always work reliably. Especially, if there are two soundcards of the same model, their names will look the same.

See also What are all these mixers? (Matthias)

4.10.

How can I find out which Mixer implementation is used?

You can detect the mixer implementation from the class types of the lines you get:

Mixer implementationinterface typeclass name
Java Sound Audio EngineMixerHeadspaceMixer
SourceDataLineMixerSourceLine
ClipMixerClip
Direct Audio DeviceMixerDirectAudioDevice
SourceDataLineDirectAudioDevice$DirectSDL
TargetDataLineDirectAudioDevice$DirectTDL
ClipDirectAudioDevice$DirectClip
Simple Input DeviceMixerSimpleInputDevice
TargetDataLineSimpleInputDevice$InputDeviceDataLine
Tritonus ESD mixerMixerEsdMixer
SourceDataLineEsdSourceDataLine
TargetDataLineEsdTargetDataLine
ClipEsdClip
Tritonus ALSA mixerMixerAlsaDataLineMixer
SourceDataLineAlsaSourceDataLine
TargetDataLineAlsaTargetDataLine

See also What are all these mixers? and How can I find out which soundcard driver is used? (Matthias)

4.11.

Why do I get lines from the "Java Sound Audio Engine" in the JDK 1.5.0 though the "Direct Audio Device" mixers are available, too?

In the JDK 1.5.0, the "Direct Audio Device" mixers are used by default if they support more than one concurrently active SourceDataLine. This is the case if either the soundcard hardware supports mixing of multiple channels (and the driver supports it) or the driver does software mixing of multiple channels.

If this is not the case, the "Java Sound Audio Engine" is used by default. If you don't mind the limitation that there will be only one SourceDataLine or Clip instance, you can still use the "Direct Audio Device" mixers by addressing them directly (see How can I get a Line from a specific Mixer?).

See also Can I make ALSA the default in version 1.4.2? and How can I enable mixing with the "Direct Audio Device" mixers on Linux? (Matthias)

5. Soundcard Drivers

5.1. Which soundcard drivers can be used by Java Sound?
5.2. How can I find out which soundcard driver is used?
5.3. I've installed ALSA and the JDK 1.4.2 to take advantage of the ALSA support. Now, how do I use it?
5.4. Can I make ALSA the default in version 1.4.2?
5.5. How can I enable mixing with the "Direct Audio Device" mixers on Linux?
5.6. What are the requirements for using the direct audio devices?
5.7. How can I find out which soundcard driver is installed on my Linux system?
5.8. How does Java Sound deal with hardware buffers of the soundcard?
5.1.

Which soundcard drivers can be used by Java Sound?

Mixer implementationWindowsLinux
Java Sound Audio EngineWindows Multimedia APIOSS or ALSA OSS emulation
Direct Audio DeviceDirectSoundALSA
Simple Input DeviceWindows Multimedia APIOSS or ALSA OSS emulation
Tritonus ALSA Mixer---ALSA
Tritonus ESD Mixer---depends on the version of Esound. There are versions for OSS and ALSA.
jsasioASIO Driver API---

See also What are all these mixers? and Q: 3.5 (Matthias)

5.2.

How can I find out which soundcard driver is used?

First, check which mixer is used (see How can I find out which Mixer implementation is used?). Then consult the table in Which soundcard drivers can be used by Java Sound? to find out the driver.

For Linux, there is no way to tell from Java Sound if a real OSS driver or ALSA's OSS emulation is used. See also How can I find out which soundcard driver is installed on my Linux system? (Matthias)

5.3.

I've installed ALSA and the JDK 1.4.2 to take advantage of the ALSA support. Now, how do I use it?

In 1.4.2, the "Java Sound Audio Engine" is still the default. To use the ALSA support, you have to obtain the Mixer object representing the direct audio access. Then, obtain lines from this object instead of via AudioSystem. See also How can I get a Line from a specific Mixer? (Matthias)

5.4.

Can I make ALSA the default in version 1.4.2?

You can, but only with an ugly trick: rename, remove or disable the device files /dev/dsp*. This disables the Java Sound Audio Engine, so the JDK falls back to use the ALSA mixers. But be aware that this disables the software synthesizer ("Java Sound Synthesizer"), too. So you won't be able to play MIDI files. And of course native applications using /dev/dsp won't be happy, too. (Matthias)

5.5.

How can I enable mixing with the "Direct Audio Device" mixers on Linux?

The "Direct Audio Device" implementation on Linux is based on ALSA. Mixing is available in the Mixer instance if ALSA provides mixing. This is the case if the soundcard can do mixing in hardware and its ALSA driver supports this feature. This is true for some common soundcards like Soundblaster LIFE! and Soundblaster Audigy and cards based on the Trident 4D Wave NX chipset. If this feature is available at all, it needs no special configuration. It is enabled by default.

Using ALSA's dmix plug-in does not work together with Java Sound. The reason is that the "Direct Audio Device" mixer implementation based on ALSA queries the available hardware devices. However, a dmix device in ALSA is no hardware device, so it is not recognized. Discussions about this issue led to the conclusion that there is no easy way to integrate a query for additional devices.

See also Q: 3.4 (Matthias)

5.6.

What are the requirements for using the direct audio devices?

According to Florian:

Operating SystemJDK versionAudio Device driver
Linux1.4.2ALSA 0.9.2 or later
Windows1.5.0DirectSound 5.0 or later (included with Windows ME/2000/XP)
Solaris1.5.0Mixer enabled (available in Solaris 8 and later)

(Matthias)

5.7.

How can I find out which soundcard driver is installed on my Linux system?

Run /sbin/lsmod to show the currently loaded kernel modules. If there are entries "snd" and "snd-*", you are running ALSA. A typical picture of ALSA is like this:

snd-mixer-oss          12672   1 (autoclean) [snd-pcm-oss]
snd-seq                38348   0 (autoclean) (unused)
snd-emu10k1            65956   1 (autoclean)
snd-hwdep               5024   0 (autoclean) [snd-emu10k1]
snd-rawmidi            13792   0 (autoclean) [snd-emu10k1]
snd-pcm                64416   0 (autoclean) [snd-pcm-oss snd-emu10k1]
snd-page-alloc          6148   0 (autoclean) [snd-emu10k1 snd-pcm]
snd-timer              15040   0 (autoclean) [snd-seq snd-pcm]
snd-ac97-codec         42200   0 (autoclean) [snd-emu10k1]
snd-seq-device          4116   0 (autoclean) [snd-seq snd-emu10k1 snd-rawmidi]
snd-util-mem            1504   0 (autoclean) [snd-emu10k1]
snd                    36832   0 (autoclean) [snd-pcm-oss snd-mixer-oss snd-seq
snd-emu10k1 snd-hwdep snd-rawmidi snd-pcm snd-timer snd-ac97-codec
snd-seq-device snd-util-mem]
soundcore               3556   6 (autoclean) [snd]
		  

An alternative way it to look for the directory /proc/asound/. It is only present if ALSA is active. (Matthias)

5.8.

How does Java Sound deal with hardware buffers of the soundcard?

Internally, Java Sound implementations usually do not work with hardware buffers. Instead, they use the platform's audio API for accessing the soundcard. See also DataLine buffers (Matthias)

6. Synchronization

6.1. How can I synchronize two or more playback lines?
6.2. How can I synchronize playback (SourceDataLines) with recording (TargetDataLines)?
6.3. How can I synchronize playback to an external clock?
6.4. Do multiple Clip instances that are looped stay in sync?
6.5. Why does recording or playing for a certain period of time results in audio data that is shorter or longer than the period I recorded / played?
6.6. How can I use Mixer.synchronize()?
6.1.

How can I synchronize two or more playback lines?

The synchronization functions in Mixer are not implemented. Nevertheless, playback typically stays in sync. (Matthias)

6.2.

How can I synchronize playback (SourceDataLines) with recording (TargetDataLines)?

As with multiple playback lines from the same Mixer object, playback and recording lines from the same Mixer object stay in sync once they are started. In practice, this means that you can achieve synchronization this easy way only by using the "Direct Audio Device" mixers. Since the "Java Sound Audio Engine" only provides playback lines, but no recording lines, playback/recording sync is not as easy with the "Java Sound Audio Engine". See also How can I synchronize two or more playback lines?

If playback and recording lines originate from different Mixer objects, you need to synchronize the soundcards that are represented by the Mixer objects. So the situation is similar to external synchronization. See also How can I synchronize playback to an external clock?

(Matthias)

6.3.

How can I synchronize playback to an external clock?

This is possible in one of two ways:

See also Q: 3.12 (Matthias)

6.4.

Do multiple Clip instances that are looped stay in sync?

Yes. There is no mechanism in Java Sound to start Clip instances synchronuously. However, calling start() for all Clip instances in a loop with the Clip instances otherwise prepared should be precise enough. Once started, Clip instances played on the same Mixer instance should stay in sync. If they don't, make sure they have the exactly same length. Clip instances played on different Mixer instance are likely to drift away from each other, unless the soundcard clocks are synchronized (which is only possible on "pro" soundcards). (Matthias)

6.5.

Why does recording or playing for a certain period of time results in audio data that is shorter or longer than the period I recorded / played?

The reason of this problem is clock drift. There are two clocks involved in this scenario: The real time clock is used to measure the period of time you are recording or playing. The soundcard clock determine how many samples are recorded or played during this period. Since there are two different hardware devices, the inherently drift away from each other over time.

There are several ways to deal with this problem:

  • You can try to minimize the drift by making both clocks high-precision. The real-time clock of the computer can be synchronized to atomic clocks by using some means of synchronization. The Network Time Protocol (NTP) is commonly used for this on the internet. On Windows, the utility AboutTime can be used for synchronization. The precision of the soundcard clock can be enhanced by using a professional soundcard with a "word clock" input. This input has to be connected to an external high-precision time base. In this case, the soundcard clock is synchronized to the external clock source. Professional studios often spend tens of thousands of dollars to purchase a high-precision time base. Note that this solution minimizes the drift, but cannot remove it completely.

  • You can use the soundcard clock as your time base to measure wall-clock time. This way, you have removed the second clock, so there is no drift. While this may sound inconvenient, it may be a good solution if the audio data has to be synchronized to, for instance, video playback or the playback of slides, mouse events or MIDI. If your soundcard's clock is synchronized to an external time base as described in the previous point, using it to measure wall-clock time is likely to give much better results than using the computer's (unsynchronized) "real time" clock.

  • If both of the above solutions are not appropriate, you can adapt the length of the audio data by doing time streching/shrinking. This usually requires fairly advanced and computationally expensive DSP algorithms. In this case, you do not remove the clock drift, but remove the effect of it on your audio data.

(Matthias)

6.6.

How can I use Mixer.synchronize()?

Synchronization isn't implemented in any known Java Sound implementation. It may be implemented in future versions. Note that you can check the availability of synchronization with the method Mixer.isSynchronizationSupported(). See also Do multiple Clip instances that are looped stay in sync?, How can I synchronize two or more playback lines? and Why does recording or playing for a certain period of time results in audio data that is shorter or longer than the period I recorded / played? (Matthias)

7. Audio Files

7.1. How can I save audio data to a file, like .wav or .aiff?
7.2. How can I add special chunks to .wav or .aiff files (like for a descriptive text or copyright)?
7.3. Is it possible to get information about loop points (e.g. from the 'smpl' chunk in .wav files) using the AudioFileFormat properties?
7.4. Why does AudioFileFormat.getFrameLength() always return -1 for .wav files?
7.5. Why does a .wav file contain PCM_UNSIGNED data if I try to save 8 bit PCM_SIGNED data?
7.6. How can I read in a .vox file and save it as .wav file?
7.7. How can I read from a headerless audio file?
7.8. How can I determine the length or the duration of an audio file?
7.9. How can I write an audio file in smaller parts?
7.10. Why are some .wav files not recognized by Java Sound?
7.11. Why is it not possible to write big-endian data using a WaveAudioOutputStream?
7.12. How can I edit or modify audio files?
7.13. How can I play audio files where the data is cached in the RAM?
7.14. Why is there a difference between using AudioSystem.write(..., File) and using AudioSystem.write(..., OutputStream) with a FileOutputStream?
7.15. Where can I find documentation on the AudioOutputStream programming?
7.16. How can I start playback of a file at a certain position?
7.17. Is it possible to read and write multichannel audio files?
7.18. How can I compare two audio files?
7.19. Is it possible to insert recorded audio data into an existing file?
7.20. How can I store an audio file in a byte array?
7.21. Which value should I use for the length of the file in AudioOutputStreams if the length is not known in advance?
7.1.

How can I save audio data to a file, like .wav or .aiff?

Have a look at the Java Sound Resources: Examples. (Florian)

7.2.

How can I add special chunks to .wav or .aiff files (like for a descriptive text or copyright)?

The Java Sound API does not support this currently. Future versions are likely to, because this is indeed quite important. For the moment, you will need to implement your own class for writing .wav or .aiff files. Or make meaningful filenames... (Florian)

7.3.

Is it possible to get information about