import java.io.*;
import javax.sound.sampled.*;
import java.text.DecimalFormat;

public class SoundTest implements LineListener {
    private AudioFormat format;
    private AudioInputStream stream;
    private Clip clip;

    // Driver to play sound files
    public static void main(String[] args) {
        SoundTest sound =
            new SoundTest("sounds/voice.wav");
        sound.play();
        //sound.loop(1);
        //sound.loop(Clip.LOOP_CONTINUOUSLY);
    }

    public SoundTest(String filename) {
        try {
            stream = AudioSystem.getAudioInputStream(
                getClass().getResource(filename));
            format = stream.getFormat();
            clip = AudioSystem.getClip();
            clip.addLineListener(this);
            clip.open(stream);
        } catch (IOException ex) {
            ex.printStackTrace();
        } catch (UnsupportedAudioFileException ex) {
            ex.printStackTrace();
        } catch (LineUnavailableException ex) {
            ex.printStackTrace();
        }
        displaySoundInfo(filename);
    }

    // Play the sound clip
    public void play() {
        clip.start(); // start playback
        clip.drain(); // block until done
        //drain(0);
    }

    // Play the sound repeatedly
    public void loop(int numRepeats) {
        clip.setFramePosition(0); // allows replay pre JDK 6
        clip.loop(numRepeats); // plays numRepeats + 1
        long time = clip.getMicrosecondLength() / 1000L;
        clip.drain(); // block until done
        //drain(numRepeats);
    }

    // Display sound file information
    private void displaySoundInfo(String filename) {
        System.out.println("Sample file: " + filename);
        System.out.println("  " + format);
        System.out.println("  Encoded format: "
            + format.getEncoding());
        System.out.println("  Sampling rate: "
            + (int) format.getSampleRate());
        System.out.println("  Sample size: "
            + format.getSampleSizeInBits() + "-bit");
        System.out.println("  Sample channels: "
            + format.getChannels());
        System.out.println("  Frame size: "
            + format.getFrameSize() + " bytes/frame");
        int length = (int) (stream.getFrameLength()
            * format.getFrameSize());
        System.out.println("  Sample size: "
            + length + " bytes");
        System.out.println("  Buffer size: "
            + clip.getBufferSize() + " bytes");
        long lengthMillis =
            clip.getMicrosecondLength() / 1000L;
        System.out.println("  Duration: "
            + (lengthMillis / 1000.0) + " secs");
    }

    //
    public void update(LineEvent event) {
        System.out.println("LineEvent: " + event);
        if (event.getType() == LineEvent.Type.STOP) {
            Line line = event.getLine();
            line.close();
        }
    }

    // Use if clip.drain() proves unreliable
    private void drain(int numRepeats) {
        long millis = clip.getMicrosecondLength() / 1000L;
        if (numRepeats == Clip.LOOP_CONTINUOUSLY) {
            numRepeats = 10; // limit for test purposes
        }
        for (int i = 0; i < numRepeats + 1; i++) {
            try {
                Thread.sleep(millis);
            } catch (InterruptedException e) {
                System.out.println("Interrupted");
            }
        }
    }
}

