package org.kc7bfi.jflac.apps;
/* libFLAC - Free Lossless Audio Codec library
* Copyright (C) 2000,2001,2002,2003 Josh Coalson
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
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.FloatControl;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.SourceDataLine;
/**
* Play.java <p> A simple class that plays audio from given file names. <p> Uses
* the Java Sound SourceDataLine interface to stream the sound. Converts
* compressed encodings (ALAW, ULAW, MP3) to PCM.
*
* @author Dan Becker, beckerdo@io.com
*/
public class SndPlayer {
/**
* Plays audio from given file names.
*
* @param args Command line parameters
*/
public static void main(String[] args) {
// Check for given sound file names.
if (args.length < 1) {
System.out.println("SndPlayer usage:");
System.out.println("\tjava SndPlayer <sound file names>*");
System.exit(0);
}
// Process arguments.
for (int i = 0; i < args.length; i++) {
playAudioFile(args[ i]);
}
// Must exit explicitly since audio creates non-daemon threads.
System.exit(0);
} // main
/**
* Play audio from the given file name.
*
* @param fileName The file to play
*/
public static void playAudioFile(String fileName) {
File soundFile = new File(fileName);
try {
// Create a stream from the given file.
// Throws IOException or UnsupportedAudioFileException
AudioInputStream audioInputStream = AudioSystem.getAudioInputStream(soundFile);
// AudioSystem.getAudioInputStream(inputStream); // alternate audio stream from inputstream
playAudioStream(audioInputStream);
}
catch (Exception e) {
System.out.println("Problem with file " + fileName + ":");
e.printStackTrace();
}
} // playAudioFile
/**
* Plays audio from the given audio input stream.
*
* @param audioInputStream The audio stream to play
*/
public static void playAudioStream(AudioInputStream audioInputStream) {
// Audio format provides information like sample rate, size, channels.
AudioFormat audioFormat = audioInputStream.getFormat();
System.out.println("Play input audio format=" + audioFormat);
// Convert compressed audio data to uncompressed PCM format.
if (audioFormat.getEncoding() != AudioFormat.Encoding.PCM_SIGNED) {
// if ((audioFormat.getEncoding() != AudioFormat.Encoding.PCM) ||
// (audioFormat.getEncoding() == AudioFormat.Encoding.ALAW) ||
// (audioFormat.getEncoding() == AudioFormat.Encoding.MP3)) {
AudioFormat newFormat = new AudioFormat(
AudioFormat.Encoding.PCM_SIGNED,
audioFormat.getSampleRate(),
16,
audioFormat.getChannels(),
audioFormat.getChannels() * 2,
audioFormat.getSampleRate(),
false);
System.out.println("Converting audio format to " + newFormat);
AudioInputStream newStream = AudioSystem.getAudioInputStream(newFormat, audioInputStream);
audioFormat = newFormat;
audioInputStream = newStream;
}
// Open a data line to play our type of sampled audio.
// Use SourceDataLine for play and TargetDataLine for record.
DataLine.Info info = new DataLine.Info(SourceDataLine.class, audioFormat);
if (!AudioSystem.isLineSupported(info)) {
System.out.println("Play.playAudioStream does not handle this type of audio on this system.");
return;
}
try {
// Create a SourceDataLine for play back (throws LineUnavailableException).
SourceDataLine dataLine = (SourceDataLine) AudioSystem.getLine(info);
// System.out.println("SourceDataLine class=" + dataLine.getClass());
// The line acquires system resources (throws LineAvailableException).
dataLine.open(audioFormat);
// Adjust the volume on the output line.
if (dataLine.isControlSupported(FloatControl.Type.MASTER_GAIN)) {
FloatControl volume = (FloatControl) dataLine.getControl(FloatControl.Type.MASTER_GAIN);
volume.setValue(100.0F);
}
// Allows the line to move data in and out to a port.
dataLine.start();
// Create a buffer for moving data from the audio stream to the line.
int bufferSize = (int) audioFormat.getSampleRate() * audioFormat.getFrameSize();
byte[] buffer = new byte[bufferSize];
// Move the data until done or there is an error.
try {
int bytesRead = 0;
while (bytesRead >= 0) {
bytesRead = audioInputStream.read(buffer, 0, buffer.length);
if (bytesRead >= 0) {
// System.out.println("Play.playAudioStream bytes read=" + bytesRead +
// ", frame size=" + audioFormat.getFrameSize() + ", frames read=" + bytesRead / audioFormat.getFrameSize());
// Odd sized sounds throw an exception if we don't write the same amount.
dataLine.write(buffer, 0, bytesRead);
}
} // while
}
catch (IOException e) {
e.printStackTrace();
}
System.out.println("Play.playAudioStream draining line.");
// Continues data line I/O until its buffer is drained.
dataLine.drain();
System.out.println("Play.playAudioStream closing line.");
// Closes the data line, freeing any resources such as the audio device.
dataLine.close();
}
catch (LineUnavailableException e) {
e.printStackTrace();
}
} // playAudioStream
} // Play