package VQVAD;

import java.io.FileNotFoundException;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;

import edu.cmu.sphinx.frontend.BaseDataProcessor;
import edu.cmu.sphinx.frontend.Data;
import edu.cmu.sphinx.frontend.DataEndSignal;
import edu.cmu.sphinx.frontend.DataProcessingException;
import edu.cmu.sphinx.frontend.DataStartSignal;
import edu.cmu.sphinx.frontend.endpoint.SpeechClassifiedData;

/**
 * Write the classification result (speech/non-speech) to the file
 * specified in the given path.
 *
 * The output consists of one line with either the character 'O'
 * for a frame that was classified as speech or '_' for a frame
 * that was classified as non-speech.
 */
public class ClassificationResultDumper extends BaseDataProcessor {

	protected boolean dumpClassificationResult = false;
	protected PrintWriter resultWriter;
	protected String resultDestinationPath;

	protected final String audioFilePath;
	protected final float frameLength;
	protected final float frameShift;
	protected final boolean writeMetaData;

	/**
	 * Dump the classification results along with the specified meta data to the specified file.
	 *
	 * The file will contain two lines. The first is the meta data in matlab parsable format (using eval).
	 * The second line consists of _ (nonspeech) and O (speech) per frame.
	 */
	public ClassificationResultDumper(String audioFilePath, float frameLength, float frameShift, String path) {
		this(audioFilePath, frameLength, frameShift, path, true);
	}

	/**
	 * Just dump the classification results to the specified file.
	 *
	 * The file will contain one line consisting of _ (nonspeech) and O (speech) per frame.
	 */
	public ClassificationResultDumper(String path) {
		this("", 0, 0, path, false);
	}

	protected ClassificationResultDumper(String audioFilePath, float frameLength, float frameShift, String path, boolean writeMetaData) {
		try {
			enableResultWriting(path);
		} catch (FileNotFoundException e) {
			throw new IllegalArgumentException("Classification file location does not exist. Original message: " + e.getMessage());
		} catch (UnsupportedEncodingException e) {
			throw new RuntimeException("Programming error: UTF-8 encoding is not supported by environment. Original message: " + e.getMessage());
		}

		this.audioFilePath = audioFilePath;
		this.frameLength = frameLength;
		this.frameShift = frameShift;

		this.writeMetaData = writeMetaData;
	}

	public void enableResultWriting(String path) throws FileNotFoundException, UnsupportedEncodingException {
		resultWriter = new PrintWriter(path, "UTF-8");
		dumpClassificationResult = true;
	}

	public void disableResultWriting() {
		if (resultWriter != null) {
			resultWriter.close();
		}
		dumpClassificationResult = false;
	}

	@Override
	public Data getData() throws DataProcessingException {
		Data d = getPredecessor().getData();

		if (d instanceof DataStartSignal) {
			if (dumpClassificationResult) {
				System.out.println("input_filename = '" + audioFilePath + "'; frame_length = " + frameLength + "; frame_shift = " + frameShift + ";");
				resultWriter.println("input_filename = '" + audioFilePath + "'; frame_length = " + frameLength + "; frame_shift = " + frameShift + ";");
			}
		} else if (d instanceof SpeechClassifiedData) {
			SpeechClassifiedData sd = (SpeechClassifiedData) d;

			if (dumpClassificationResult) {
				System.out.print(sd.isSpeech() ? "O" : "_");
				resultWriter.print(sd.isSpeech() ? "O" : "_");
			}
		} else if (d instanceof DataEndSignal) {
			if (dumpClassificationResult) {
				resultWriter.close();
			}
		}
		return d;
	}

}

@@ -972,16 +972,18 @@
 meLength
+Ms
 ;%0A%09prote
@@ -1009,16 +1009,18 @@
 ameShift
+Ms
 ;%0A%09prote
@@ -1404,32 +1404,34 @@
 loat frameLength
+Ms
 , float frameShi
@@ -1424,32 +1424,34 @@
 float frameShift
+Ms
 , String path) %7B
@@ -1484,16 +1484,18 @@
 meLength
+Ms
 , frameS
@@ -1498,16 +1498,18 @@
 ameShift
+Ms
 , path, 
@@ -1848,16 +1848,18 @@
 meLength
+Ms
 , float 
@@ -1868,16 +1868,18 @@
 ameShift
+Ms
 , String
@@ -2352,16 +2352,18 @@
 meLength
+Ms
  = frame
@@ -2368,16 +2368,18 @@
 meLength
+Ms
 ;%0A%09%09this
@@ -2389,16 +2389,18 @@
 ameShift
+Ms
  = frame
@@ -2404,16 +2404,18 @@
 ameShift
+Ms
 ;%0A%0A%09%09thi
@@ -3033,32 +3033,35 @@
 %22'; frame_length
+_ms
  = %22 + frameLeng
@@ -3054,32 +3054,34 @@
  %22 + frameLength
+Ms
  + %22; frame_shif
@@ -3073,32 +3073,35 @@
 + %22; frame_shift
+_ms
  = %22 + frameShif
@@ -3093,32 +3093,34 @@
 = %22 + frameShift
+Ms
  + %22;%22);%0A%09%09%09%09res
@@ -3192,16 +3192,19 @@
 e_length
+_ms
  = %22 + f
@@ -3213,16 +3213,18 @@
 meLength
+Ms
  + %22; fr
@@ -3232,16 +3232,19 @@
 me_shift
+_ms
  = %22 + f
@@ -3252,16 +3252,18 @@
 ameShift
+Ms
  + %22;%22);

Write meta data in milliseconds