// file: $ISIP_IFC/util/demo/isip_comm_client_speech_analysis/SimpleAudioPlayer.java
// version: $Id: SimpleAudioPlayer.java 9681 2004-07-31 18:40:05Z gao $ 
//

// This file is part of the Java Sound Examples. Some modifications
// are made to fit isip standard.
//

/*
 *  Copyright (c) 1999 - 2001 by Matthias Pfisterer <Matthias.Pfisterer@web.de>
 *
 *
 *   This program 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 program 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 program; if not, write to the Free Software
 *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 */

// import necessary java libraries
//
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;

/**
 * A simple audio player that plays "notify.wav" and then
 * automatically terminates after playback.
 */
public class SimpleAudioPlayer {
    
    //-------------------------------------------------------------------------
    //
    // public constants
    //
    //-------------------------------------------------------------------------

    /**
     * Default buffer size.
     */    
    public static final int EXTERNAL_BUFFER_SIZE = 128000;

    /**
     * A file name to hold the sound file played by this class.
     */
    public static final String SOURCE_FILE_NAME = "notify.wav";

    //------------------------------------------------------------------------
    //
    // protected data
    //
    //-----------------------------------------------------------------------


    
    //-------------------------------------------------------------------------
    //
    // public methods
    //
    //-------------------------------------------------------------------------
    
    /**
     * Creates the audio player and begins playback.  The program
     * automatically terminates after playback has finished.
     */
    public SimpleAudioPlayer() {

	// create sound file object
	//
	File soundFile = new File(SOURCE_FILE_NAME);
	
	// we have to read in the sound file
	//
	AudioInputStream audioInputStream = null;

	// get audio input stream
	//
	try {
	    audioInputStream = AudioSystem.getAudioInputStream(soundFile);
	}
	catch (Exception e) {
	    
	    // In case of an exception, we dump the exception
	    // including the stack trace to the console output.
	    // Then, we exit the program.
	    //
	    e.printStackTrace();
	    System.exit(1);
	}
	
	//  From the AudioInputStream, i.e. from the sound file,we
	//  fetch information about the format of the audio data.These
	//  information include the sampling frequency,the number of
	//  channels and the size of the samples.These information are
	//  needed to ask Java Sound for a suitable output line for
	//  this audio file.
	//
	AudioFormat audioFormat = audioInputStream.getFormat();
       
	//  Asking for a line is a rather tricky thing. We have to
	//  construct an Info object that specifies the desired
	//  properties for the line. First, we have to say which kind
	//  of line we want. The possibilities are: SourceDataLine
	//  (for playback), Clip (for repeated playback) and
	//  TargetDataLine (for recording). Here, we want to do normal
	//  playback, so we ask for a SourceDataLine. Then, we have to
	//  pass an AudioFormat object, so that the Line knows which
	//  format the data passed to it will have. Furthermore, we
	//  can give Java Sound a hint about how big the internal
	//  buffer for the line should be. This isn't used here,
	//  signaling that we don't care about the exact size. Java
	//  Sound will use some default value for the buffer size.
	//
	SourceDataLine line = null;

	DataLine.Info info = new DataLine.Info(SourceDataLine.class,
					       audioFormat);
	try {
	    line = (SourceDataLine) AudioSystem.getLine(info);    
	    
	    //  The line is there, but it is not yet ready to receive
	    //  audio data. We have to open the line.
	    //
	    line.open(audioFormat);
	}
	catch (LineUnavailableException e) {
	    e.printStackTrace();
	    System.exit(1);
	}
	catch (Exception e) {
	    e.printStackTrace();
	    System.exit(1);
	}
	
	//  Still not enough. The line now can receive data, but will
	//  not pass them on to the audio output device (which means
	//  to your sound card). This has to be activated.
        //
	line.start();
	
	//  Ok, finally the line is prepared. Now comes the real job:
	//  we have to write data to the line. We do this in a
	//  loop. First, we read data from the AudioInputStream to a
	//  buffer. Then, we write from this buffer to the Line. This
	//  is done until the end of the file is reached, which is
	//  detected by a return value of -1 from the read method of
	//  the AudioInputStream.
        //
	int nBytesRead = 0;

	byte[] abData = new byte[EXTERNAL_BUFFER_SIZE];

	while (nBytesRead != -1) {
	    try	{
		nBytesRead = audioInputStream.read(abData, 0, abData.length);
	    }
	    catch (IOException e) {
		e.printStackTrace();
	    }
	    if (nBytesRead >= 0) {
		int nBytesWritten = line.write(abData, 0, nBytesRead);
	    }
	}
	
	// Wait until all data are played.
        //
	line.drain();
	
	// All data are played. We can close the shop.
	//
	line.close();
    }
    
    //-------------------------------------------------------------------------
    //
    // main diagnostic method for this class
    //
    //-------------------------------------------------------------------------

    /**
     * Diagnostic method for this class.
     *
     * @param args arguments from the command line.
     */
    public static void main(String[] args) {
	new SimpleAudioPlayer();
    }
}
