In this tutorial we’re going to understand how Java supports for playing audio with some interesting example programs.

Currently the Java Sound API supports playing back the following audio file format: AIFC, AIFF, AU, SND and WAVE. That means we cannot play the popular audio format MP3 with Java Sound API, so the examples will play with the WAVE format (.wav).

Generally, the Java Sound API (package: javax.sound) provides two ways for playing back audio: using a Clip and using a SourceDataLine. Each way has its own advantages and drawbacks. Let’s explore the details.

 

1. Playing back audio using a Clip

Use a Clip (javax.sound.sampled.Clip) when you want to play non-real-time sound data such as a short sound file. The whole file is pre-loaded into memory before playing back, therefore we have total control over the playback.

Advantages:

Drawbacks:

Steps to play:

Following are the steps to implement code for playing back an audio file (typically in .wav format) using the Clip:

audioClip.close();
audioStream.close();


 

Java Audio Playback Example using Clip:

Here’s an example program that plays back a given audio file using the Clip:

package net.codejava.sound;

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

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

/**
 * This is an example program that demonstrates how to play back an audio file
 * using the Clip in Java Sound API.
 * @author www.codejava.net
 *
 */
public class AudioPlayerExample1 implements LineListener {
	
	/**
	 * this flag indicates whether the playback completes or not.
	 */
	boolean playCompleted;
	
	/**
	 * Play a given audio file.
	 * @param audioFilePath Path of the audio file.
	 */
	void play(String audioFilePath) {
		File audioFile = new File(audioFilePath);

		try {
			AudioInputStream audioStream = AudioSystem.getAudioInputStream(audioFile);

			AudioFormat format = audioStream.getFormat();

			DataLine.Info info = new DataLine.Info(Clip.class, format);

			Clip audioClip = (Clip) AudioSystem.getLine(info);

			audioClip.addLineListener(this);

			audioClip.open(audioStream);
			
			audioClip.start();
			
			while (!playCompleted) {
				// wait for the playback completes
				try {
					Thread.sleep(1000);
				} catch (InterruptedException ex) {
					ex.printStackTrace();
				}
			}
			
			audioClip.close();
			
		} catch (UnsupportedAudioFileException ex) {
			System.out.println("The specified audio file is not supported.");
			ex.printStackTrace();
		} catch (LineUnavailableException ex) {
			System.out.println("Audio line for playing back is unavailable.");
			ex.printStackTrace();
		} catch (IOException ex) {
			System.out.println("Error playing the audio file.");
			ex.printStackTrace();
		}
		
	}
	
	/**
	 * Listens to the START and STOP events of the audio line.
	 */
	@Override
	public void update(LineEvent event) {
		LineEvent.Type type = event.getType();
		
		if (type == LineEvent.Type.START) {
			System.out.println("Playback started.");
			
		} else if (type == LineEvent.Type.STOP) {
			playCompleted = true;
			System.out.println("Playback completed.");
		}

	}

	public static void main(String[] args) {
		String audioFilePath = "E:/Test/Audio.wav";
		AudioPlayerExample1 player = new AudioPlayerExample1();
		player.play(audioFilePath);
	}

}
In this program, the play() method implements all the above mentioned steps, and the current thread will wait till the playback completes. We make this class implements the LineListener interface in order to receive line events (OPEN, CLOSE, START and STOP) to know when the playback completes (a STOP event is fired). Specify a listener for the Clip as follows:

audioClip.addLineListener(this);
Where this is the current class that implements the LineListener interface:

public class AudioPlayerExample1 implements LineListener
And we have to override the update() method defined in the LineListener interface as follows:

@Override
public void update(LineEvent event) {
	LineEvent.Type type = event.getType();

	if (type == LineEvent.Type.START) {
		System.out.println("Playback started.");

	} else if (type == LineEvent.Type.STOP) {
		playCompleted = true;
		System.out.println("Playback completed.");
	}

}
If the line event type is STOP, we set the flag playCompletedto true, so the current thread stops waiting and the program exits.

In addition, we can do the following things with the Clip:

audioClip.stop(); 

To resume playing, call start() method again.

And all the above statements (except the stop()) should be called after audioClip.open() and before audioClip.start(), for example:

audioClip.open(audioStream);

int frameLength = audioClip.getFrameLength();
System.out.println("Frame length = " + frameLength);

long duration = audioClip.getMicrosecondLength();
System.out.println("Duration = " + (duration / 1_000_000) + " sec");

audioClip.setMicrosecondPosition(10_000_000); // start playing from the 10th second

audioClip.loop(1);	// loop 1 time

audioClip.start(); 
 

2. Playing back using a SourceDataLine

Use a SourceDataLine (javax.sound.sampled.SourceDataLine) when you want to play a long sound file which cannot be pre-loaded into memory or to stream real-time sound data such as playing sound back as it’s being captured.

Advantages:

Drawbacks:

Steps to play:

Following are the steps to implement code for playing back a sound file using the SourceDataLine:

audioLine.drain();

audioLine.close();

audioStream.close();
 

Java Playback Audio Example using DataSourceLine:

Here’s an example program that plays back a given audio file using the SourceDataLine:

package net.codejava.sound;

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

import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.SourceDataLine;
import javax.sound.sampled.UnsupportedAudioFileException;

/**
 * This is an example program that demonstrates how to play back an audio file
 * using the SourceDataLine in Java Sound API.
 * @author www.codejava.net
 *
 */
public class AudioPlayerExample2 {

	// size of the byte buffer used to read/write the audio stream
	private static final int BUFFER_SIZE = 4096;
	
	/**
	 * Play a given audio file.
	 * @param audioFilePath Path of the audio file.
	 */
	void play(String audioFilePath) {
		File audioFile = new File(audioFilePath);
		try {
			AudioInputStream audioStream = AudioSystem.getAudioInputStream(audioFile);

			AudioFormat format = audioStream.getFormat();

			DataLine.Info info = new DataLine.Info(SourceDataLine.class, format);

			SourceDataLine audioLine = (SourceDataLine) AudioSystem.getLine(info);

			audioLine.open(format);

			audioLine.start();
			
			System.out.println("Playback started.");
			
			byte[] bytesBuffer = new byte[BUFFER_SIZE];
			int bytesRead = -1;

			while ((bytesRead = audioStream.read(bytesBuffer)) != -1) {
				audioLine.write(bytesBuffer, 0, bytesRead);
			}
			
			audioLine.drain();
			audioLine.close();
			audioStream.close();
			
			System.out.println("Playback completed.");
			
		} catch (UnsupportedAudioFileException ex) {
			System.out.println("The specified audio file is not supported.");
			ex.printStackTrace();
		} catch (LineUnavailableException ex) {
			System.out.println("Audio line for playing back is unavailable.");
			ex.printStackTrace();
		} catch (IOException ex) {
			System.out.println("Error playing the audio file.");
			ex.printStackTrace();
		}		
	}
	
	public static void main(String[] args) {
		String audioFilePath = "E:/Test/Audio.wav";
		AudioPlayerExample1 player = new AudioPlayerExample1();
		player.play(audioFilePath);
	}

}
As we can see, this program is simpler than the Clip-based version, without having to implement the LineListener interface.

 

Related Java Sound Tutorials:

 

Other Java Tutorials:


About the Author:

is certified Java programmer (SCJP and SCWCD). He started programming with Java in the time of Java 1.4 and has been falling in love with Java since then. Make friend with him on Facebook and watch his Java videos you YouTube.



Attachments:
Download this file (AudioPlayerExample1.java)AudioPlayerExample1.java[Play back using Clip]2 kB
Download this file (AudioPlayerExample2.java)AudioPlayerExample2.java[Play back using SourceDataLine]2 kB