Play a wave sound in JavaFrom WikiJavabuy 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.
the article
This article includes three files:
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:
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 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.javapackage 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.javapackage 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.javapackage 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); } } |
