sound
Handle sampled audio playing events
In this tutorial we are going to see how to handle sampled audio playing events.This is a very important task if you plan to create a small media player in your app. Handling samples audio events will help you monitor the progress of the audio playing and inform the user for any mistakes or errors.
In short, in order to handle samples audio playing events, one should follow these steps:
- Obtain an audio input stream from the provided file calling
AudioSystem.getAudioInputStream(new File("sampled_file.wav"))
. - Then, obtain the audio format of the sound data in this audio input stream calling
getFormat()
. - Create a new
AudioFormat
. - Construct a data line’s info object from the specified information with
SourceDataLine.Info lineInfo = new DataLine.Info()
. - Create a new
LineListener
and override the update function to monitor the progress of the audio playing.LineEvent
object describes the change.
Let’s see the code:
package com.javacodegeeks.snippets.desktop; import java.io.File; import javax.sound.sampled.AudioFormat; import javax.sound.sampled.AudioInputStream; import javax.sound.sampled.AudioSystem; import javax.sound.sampled.DataLine; import javax.sound.sampled.LineEvent; import javax.sound.sampled.LineListener; import javax.sound.sampled.SourceDataLine; public class HandleSampledAudioPlayingEvents { public static void main(String[] args) throws Exception { // obtain an audio input stream from the provided file AudioInputStream stream = AudioSystem.getAudioInputStream(new File("sampled_file.wav")); // obtain the audio format of the sound data in this audio input stream AudioFormat format = stream.getFormat(); if (format.getEncoding() != AudioFormat.Encoding.PCM_SIGNED) { format = new AudioFormat( AudioFormat.Encoding.PCM_SIGNED, format.getSampleRate(), format.getSampleSizeInBits()*2, format.getChannels(), format.getFrameSize()*2, format.getFrameRate(), true ); stream = AudioSystem.getAudioInputStream(format, stream); } // construct a data line's info object from the specified information, // which includes a single audio format and a desired buffer size SourceDataLine.Info lineInfo = new DataLine.Info( SourceDataLine.class, stream.getFormat(), ((int)stream.getFrameLength()*format.getFrameSize()) ); // obtain a line that matches the description in the specified Line.Info SourceDataLine dataLine = (SourceDataLine) AudioSystem.getLine(lineInfo); // adds a listener to this line, whenever the line's status changes, the listener's update() //method is called with a LineEvent object that describes the change. dataLine.addLineListener(new LineListener() { public void update(LineEvent evt) { if (evt.getType() == LineEvent.Type.OPEN) { System.out.println("Line opened"); } else if (evt.getType() == LineEvent.Type.START) { System.out.println("Playing file started"); } else if (evt.getType() == LineEvent.Type.STOP) { System.out.println("Playing file stopped"); } else if (evt.getType() == LineEvent.Type.CLOSE) { System.out.println("Line closed"); } } }); // open the line with the specified format, causing the line to acquire any // required system resources and become operational dataLine.open(stream.getFormat()); // allow the line to engage in data I/O. dataLine.start(); int bytesRead = 0; byte[] buffer = new byte[dataLine.getBufferSize()]; // read from the input file and play while ((bytesRead = stream.read(buffer, 0, buffer.length)) >= 0) { int offset = 0; while (offset < bytesRead) { offset += dataLine.write(buffer, offset, bytesRead-offset); } } // drain queued data from the line by continuing data I/O until the // data line's internal buffer has been emptied dataLine.drain(); // stop the line, a stopped line should cease I/O activity dataLine.stop(); // closes the line, indicating that any system resources // in use by the line can be released. dataLine.close(); } }
Output:
Line opened
Playing file started
Playing file stopped
Line closed
This was an example on how to handle sampled audio playing events.