package hayashi.yuu.tools.sound;

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;
import javax.sound.sampled.UnsupportedAudioFileException;

/**
 * サウンドファイルを再生して、音（音楽）を鳴らす。
 *
 * @author hayashi
 *
 */
public class PlaySound extends Thread
{
	//static final String WAVE = "lib/belltree.aiff";
	static String WAVE = null;

	/**
	 * サウンドファイルを再生して、音（音楽）を鳴らす。
	 * (1) PlaySound(sound file);
	 * 			再生するサウンドファイルを指定して、インスタンスを生成する。
	 * 			サウンドファイルを指定しなければ、「BEEP」音が再生される。
	 * (2) playSound.start();
	 * 			サウンド再生を実行。
	 *
	 * @param args
	 */
	public static void main(String[] args) {
		/*
		 * BEEP音を再生
		 */
		try {
			PlaySound obj = new PlaySound(null);
			for (int i=0; i < 5; i++) {
				try {
					obj.start();
				} catch (IllegalThreadStateException e) {}
				try {
					Thread.sleep(1000);	// １秒間停止
				} catch (InterruptedException e) {}
			}
		}
		catch (Exception e) {
			e.printStackTrace();
		}

		/*
		 * サウンドファイルを再生
		 */
		try {
			PlaySound obj = new PlaySound("lib/belltree.aiff");
			for (int i=0; i < 5; i++) {
				try {
					obj.start();
				} catch (IllegalThreadStateException e) {}
				try {
					Thread.sleep(1000);	// １秒間停止
				} catch (InterruptedException e) {}
			}
		}
		catch (Exception e) {
			e.printStackTrace();
		}
	}

	private static final int EXTERNAL_BUFFER_SIZE = 128000;
	private static AudioInputStream audioInputStream = null;
	private static AudioFormat audioFormat = null;

	/**
	 * コンストラクタ
	 * @throws IOException
	 * @throws UnsupportedAudioFileException
	 * @throws LineUnavailableException
	 */
	public PlaySound(String path) throws IOException, UnsupportedAudioFileException, LineUnavailableException {
		super();
		PlaySound.WAVE = path;
		if (PlaySound.WAVE != null) {
		    File soundFile = new File(PlaySound.WAVE);
		    PlaySound.audioInputStream = AudioSystem.getAudioInputStream(soundFile);
		    PlaySound.audioFormat = PlaySound.audioInputStream.getFormat();		// オーディオ形式
		}
	}

	@Override
	public void run() {
		if (PlaySound.WAVE == null) {
			java.awt.Toolkit.getDefaultToolkit().beep();
		}
		else {
			try {
				// データラインの情報オブジェクトを生成
				DataLine.Info info = new DataLine.Info(SourceDataLine.class, PlaySound.audioFormat);

				// 指定されたデータライン情報に一致するラインを取得します
				SourceDataLine line = (SourceDataLine) AudioSystem.getLine(info);

				// 指定されたオーディオ形式でラインを開きます
				line.open(PlaySound.audioFormat);

				// ラインでのデータ入出力を可能にします
				line.start();

				int nBytesRead = 0;
				byte[] abData = new byte[EXTERNAL_BUFFER_SIZE];
				while (nBytesRead != -1) {
					// オーディオストリームからデータを読み込みます
					nBytesRead = PlaySound.audioInputStream.read(abData, 0, abData.length);
					if (nBytesRead >= 0) {
						// オーディオデータをミキサーに書き込みます
						line.write(abData, 0, nBytesRead);
					}
				}

				// ラインからキューに入っているデータを排出します
				line.drain();
				line.close();
			}
			catch (Exception e) {
				e.printStackTrace();
			}
		}
	}
}
