Warning: Parameter 1 to Language::getMagic() expected to be a reference, value given in /home/wikija5/public_html/w/includes/StubObject.php on line 58
Play a wave sound in Java - WikiJava
Thursday, 24th July 2014
Follow WikiJava on twitter now. @Wikijava

Play a wave sound in Java

From WikiJava

Jump to: navigation, search
The author suggests:

buy this book


This tutorial shows how to play a wave sound in Java. The sound is passed to the class as an InputStream. So it could come from any inputStream, for example if the stream is stored in a file you will pass a FileInputStream object.

The tutorial contains also an example client class that invokes the class and plays a wave file.

Contents

the article

Image:250px-Subversion.png
You can download the complete code of this article from the Subversion repository at this link

Using the username:readonly and password: readonly

See the using the SVN repository instructions page for more help about this.

This article includes three files:

  • PlaySound.java
the class responsible of playing the file
  • PlayWaveException.java
an Exception accessory class
  • PlayWaveFile.java
The example client of PlaySound, containing a call to the PlaySound class.

the most interesting class is of course PlaySound I'll show you how it works in this paragraph.

The first step is to get the javax.sound.sampled.AudioInputStream, This is like a normal input stream but it is specific for audio data. We obtain the javax.sound.sampled.AudioInputStream object via the getAudioInputStream factory method of the class javax.sound.sampled.AudioSystem. Which, of course, is static.

   AudioInputStream audioInputStream = AudioSystem.getAudioInputStream(this.waveStream);

the javax.sound.sampled.AudioInputStream is an audio input stream is an input stream with a specified audio format and length. AudioInputStream offers several methods to access the data in various ways.

The next step is to obtain from the wave stream the information that we will need to set in the soundcard, in order to play the sound in the correct way. This is done by the following command:

	AudioFormat audioFormat = audioInputStream.getFormat();

javax.sound.sampled.AudioFormat stores the information about the particular arrangement of data in a sound stream. The class stores information like:

bitrate
average bit rate in bits per second
vbr
true, if the file is encoded in variable bit rate (VBR)
quality
encoding/conversion quality, 1..100
frameRate
The number of frames played or recorded per second, for sounds that have this format

Once we obtained the AudioFormat object we can generate the javax.sound.sampled.DataLine.Info object, that is needed for initialize correctly the audio channel:

	Info info = new Info(SourceDataLine.class, audioFormat);

The javax.sound.sampled.DataLine.Info object contains some additional data specific to the audio channel, such as:

  • the audio formats supported by the data line
  • the minimum and maximum sizes of its internal buffer

The javax.sound.sampled.SourceDataLine object is finally our connection to the sound card. We obtain the data line by calling the Line javax.sound.sampled.AudioSystem.getLine(Info info) throws LineUnavailableException method, which is our data line factory.

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

the dataLine requires also to be opened and started to become operational:

dataLine.open(audioFormat, this.EXTERNAL_BUFFER_SIZE);
audioChannel.start();

After all this preparation we can finally start reading data from the audioInputStream and write it in the dataLine. This is done in bursts of data as big as the buffer, as shown in the following snippet:

while (readBytes != -1) {
	readBytes = audioInputStream.read(audioBuffer, 0,
		audioBuffer.length);
	if (readBytes >= 0){
		dataLine.write(audioBuffer, 0, readBytes);
	}
}

When all the data has been read and written the last thing to do is to let the dataLine finish playing the samples that are left in the buffer (done via the drain() method) and then close() the dataline:

dataLine.drain();
dataLine.close();

The following paragraphs contain the complete source code of the tutorial.

PlayWaveFile.java

package org.wikijava.sound.playWave;
 
import java.io.FileInputStream;
import java.io.FileNotFoundException;
 
/**
 * plays a wave file using PlaySound class
 * 
 * @author Giulio
 */
public class PlayWaveFile {
 
    /**
     * <Replace this with one clearly defined responsibility this method does.>
     * 
     * @param args
     *            the name of the wave file to play
     */
    public static void main(String[] args) {
 
	// get the command line parameters
	if (args.length < 1) {
	    System.err.println("usage: java -jar PlayWaveFile.jar [filename]");
	    return;
	}
	String filename = args[0];
 
	// opens the inputStream
	FileInputStream inputStream;
	try {
	    inputStream = new FileInputStream(filename);
	} catch (FileNotFoundException e) {
	    e.printStackTrace();
	    return;
	}
 
	// initializes the playSound Object
	PlaySound playSound = new PlaySound(inputStream);
 
	// plays the sound
	try {
	    playSound.play();
	} catch (PlayWaveException e) {
	    e.printStackTrace();
		return;
	}
    }
 
}

playsound.java

package org.wikijava.sound.playWave;
 
import java.io.IOException;
import java.io.InputStream;
 
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.SourceDataLine;
import javax.sound.sampled.UnsupportedAudioFileException;
import javax.sound.sampled.DataLine.Info;
 
/**
 * 
 * <Replace this with a short description of the class.>
 * 
 * @author Giulio
 */
public class PlaySound {
 
    private InputStream waveStream;
 
    private final int EXTERNAL_BUFFER_SIZE = 524288; // 128Kb
 
    /**
     * CONSTRUCTOR
     */
    public PlaySound(InputStream waveStream) {
	this.waveStream = waveStream;
    }
 
    public void play() throws PlayWaveException {
 
	AudioInputStream audioInputStream = null;
	try {
	    audioInputStream = AudioSystem.getAudioInputStream(this.waveStream);
	} catch (UnsupportedAudioFileException e1) {
	    throw new PlayWaveException(e1);
	} catch (IOException e1) {
	    throw new PlayWaveException(e1);
	}
 
	// Obtain the information about the AudioInputStream
	AudioFormat audioFormat = audioInputStream.getFormat();
	Info info = new Info(SourceDataLine.class, audioFormat);
 
	// opens the audio channel
	SourceDataLine dataLine = null;
	try {
	    dataLine = (SourceDataLine) AudioSystem.getLine(info);
	    dataLine.open(audioFormat, this.EXTERNAL_BUFFER_SIZE);
	} catch (LineUnavailableException e1) {
	    throw new PlayWaveException(e1);
	}
 
	// Starts the music :P
	dataLine.start();
 
	int readBytes = 0;
	byte[] audioBuffer = new byte[this.EXTERNAL_BUFFER_SIZE];
 
	try {
	    while (readBytes != -1) {
		readBytes = audioInputStream.read(audioBuffer, 0,
			audioBuffer.length);
		if (readBytes >= 0){
		    dataLine.write(audioBuffer, 0, readBytes);
		}
	    }
	} catch (IOException e1) {
	    throw new PlayWaveException(e1);
	} finally {
	    // plays what's left and and closes the audioChannel
	    dataLine.drain();
	    dataLine.close();
	}
 
    }
}

PlayWaveException.java

package org.wikijava.sound.playWave;
 
/**
 * @author Giulio
 */
public class PlayWaveException extends Exception {
 
    public PlayWaveException(String message) {
	super(message);
    }
 
    public PlayWaveException(Throwable cause) {
	super(cause);
    }
 
    public PlayWaveException(String message, Throwable cause) {
	super(message, cause);
    }
 
}

Comments from the users

To be notified via mail on the updates of this discussion you can login and click on watch at the top of the page


Comments on wikijava are disabled now, cause excessive spam.