// This file is part of Penn TotalRecall <http://memory.psych.upenn.edu/TotalRecall>. // // TotalRecall is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, version 3 only. // // TotalRecall 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 General Public License for more details. // // You should have received a copy of the GNU General Public License // along with TotalRecall. If not, see <http://www.gnu.org/licenses/>. package edu.upenn.psych.memory.totalrecall.tests; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.Hashtable; import java.util.Iterator; import java.util.Vector; import javax.sound.sampled.UnsupportedAudioFileException; import org.apache.log4j.FileAppender; import org.apache.log4j.Level; import org.apache.log4j.Logger; import org.apache.log4j.SimpleLayout; import components.audiofiles.AudioFile; import components.audiofiles.AudioFile.AudioFilePathException; import control.AudioMaster; import edu.upenn.psych.memory.precisionplayer.PrecisionEvent; import edu.upenn.psych.memory.precisionplayer.PrecisionListener; import edu.upenn.psych.memory.precisionplayer.PrecisionPlayer; import edu.upenn.psych.memory.precisionplayer.PrecisionEvent.EventCode; import edu.upenn.psych.memory.precisionplayer.PrecisionPlayer.Status; /** * @author Apurva Jatakia */ public class DemoTest implements PrecisionListener { private PrecisionPlayer player; private static int updateCount; private long lastTime; private long lastFrame; private ArrayList<Long> framesArr; private ArrayList<Long> frameProgress; private ArrayList<Long> clockProgress; private ArrayList<Long> clockDiff; private Hashtable<Long, Integer> frameTable; private Hashtable<Long, Integer> frameProgressTable; private Hashtable<Long, Integer> clockProgresstable; private Hashtable<Long, Integer> clockDiffTable; private int[] counts = new int[100]; private long startTime; private int i = 0; private boolean isNano = true; private AudioMaster master; boolean decreasing = false; final Logger logger; private String filePath; private int timeToPlay = 5000; File currentDir; public DemoTest() { logger = Logger.getLogger(DemoTest.class); SimpleLayout layout = new SimpleLayout(); FileAppender appender = null; try { appender = new FileAppender(layout, "output1.txt", false); } catch (Exception e) { } logger.addAppender(appender); logger.setLevel(Level.DEBUG); } public void initialize() throws IOException { framesArr = new ArrayList<Long>(); frameProgress = new ArrayList<Long>(); clockProgress = new ArrayList<Long>(); clockDiff = new ArrayList<Long>(); frameTable = new Hashtable<Long, Integer>(); frameProgressTable = new Hashtable<Long, Integer>(); clockProgresstable = new Hashtable<Long, Integer>(); clockDiffTable = new Hashtable<Long, Integer>(); updateCount = 0; player = null; currentDir = new File("."); // System.out.println(getClass().getResource(filePath).toString()); filePath = currentDir.getCanonicalPath() + "/0.wav"; System.out.println(filePath); // System.out.println("Relative Path: " + // getClass().getResource("audioFiles/0.wav").getPath()); try { AudioFile file = new AudioFile(filePath); master = new AudioMaster(file); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (UnsupportedAudioFileException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } catch (AudioFilePathException e) { e.printStackTrace(); } player.addListener(this); player.setLoudness(100); if (isNano) { startTime = System.nanoTime(); } else startTime = System.currentTimeMillis(); } public void getPlayerStats() { try { initialize(); } catch (IOException e1) { e1.printStackTrace(); } try { player.open(filePath); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } catch (UnsupportedAudioFileException e) { e.printStackTrace(); } player.playAt(0); } public void testOpen() { boolean warningGenerated = false; try { initialize(); } catch (IOException e3) { e3.printStackTrace(); } if (!player.getStatus().equals(PrecisionPlayer.Status.BUSY)) { logger.warn("Status before opening the file:" + player.getStatus()); warningGenerated = true; } // open two files one after the another try { player.open(filePath); // giving a missing file as input String fileNotFound = currentDir.getCanonicalPath() + "/hi.wav"; player.open(fileNotFound); } catch (FileNotFoundException e) { String invalidFileFormat = ""; try { invalidFileFormat = currentDir.getCanonicalPath() + "/unsupported_m4a_audio.wav"; } catch (IOException e3) { e3.printStackTrace(); } try { player.open(invalidFileFormat); } catch (FileNotFoundException e1) { e1.printStackTrace(); } catch (IOException e1) { e1.printStackTrace(); } catch (UnsupportedAudioFileException e1) { // calling the open method twice try { player.open(filePath); } catch (FileNotFoundException e2) { e2.printStackTrace(); } catch (IOException e2) { e2.printStackTrace(); } catch (UnsupportedAudioFileException e2) { e2.printStackTrace(); } } } catch (IOException e) { e.printStackTrace(); } catch (UnsupportedAudioFileException e) { e.printStackTrace(); } if (!player.getStatus().equals(PrecisionPlayer.Status.BUSY)) { logger .info("The Open method is having a concurrent implementation"); } if (!player.getStatus().equals(PrecisionPlayer.Status.READY)) { logger.warn("Status after opening the file: " + player.getStatus()); warningGenerated = true; } player.playAt(0); // sleep the thread for 10 seconds try { Thread.sleep(timeToPlay); } catch (InterruptedException e) { e.printStackTrace(); } player.stop(); if (warningGenerated == true) { System.out .println("Test has generated some warnings. Please check the output.txt file for the warnings"); } else { System.out.println("Test Passed"); } } public void testPlatAt() { boolean warningGenerated = false; try { initialize(); } catch (IOException e1) { e1.printStackTrace(); } // starting playback before file is opened Status status = player.getStatus(); player.playAt(0); if (!player.getStatus().equals(status)) { logger .warn("The Status after Playat is called before file is opened changed from : " + status + " to " + player.getStatus()); warningGenerated = true; } try { player.open(filePath); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } catch (UnsupportedAudioFileException e) { e.printStackTrace(); } player.playAt(0); if (!player.getStatus().equals(PrecisionPlayer.Status.PLAYING)) { logger .warn("The Status after Playat is called after file is Opened: " + player.getStatus()); warningGenerated = true; } // calling the PlayAt again after the mainthread has already been // instantiated // Starting another playback thread when one is already running player.playAt(500); if (!player.getStatus().equals(PrecisionPlayer.Status.PLAYING)) { logger.warn("The Status after Playat is called twice: " + player.getStatus()); warningGenerated = true; } // sleep the thread for 10 seconds try { Thread.sleep(timeToPlay); } catch (InterruptedException e) { e.printStackTrace(); } long lastStopFrame = player.stop(); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } player.playAt(lastStopFrame); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } player.stop(); if (warningGenerated == true) { System.out .println("Test has generated some warnings. Please check the output.txt file for the warnings"); } else { System.out.println("Test Passed"); } } public void testStop() { boolean warningGenerated = false; try { initialize(); } catch (IOException e1) { e1.printStackTrace(); } // calling the stop method before opening the file long ret = player.stop(); if (ret != -1) { logger .warn("The Value returned by stop funtion when called before opening the file should be -1"); warningGenerated = true; } try { player.open(filePath); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } catch (UnsupportedAudioFileException e) { e.printStackTrace(); } // calling stop method after opening the file but before playAt method // is called ret = player.stop(); if (ret != -1) { logger .warn("The Value returned by stop funtion when called after opening the file but before playing should be -1"); warningGenerated = true; } player.playAt(0); try { Thread.sleep(timeToPlay); } catch (InterruptedException e) { e.printStackTrace(); } // stop the playback to check what gets returned ret = player.stop(); if (ret == -1) { logger .warn("The Value returned by stop function when called after the file is played should not be -1"); warningGenerated = true; } ret = player.stop(); if (ret != -1) { logger .warn("The Value returned by stop funtion when called twice back to back after playing should be -1"); warningGenerated = true; } if (warningGenerated == true) { System.out .println("Test has generated some warnings. Please check the output.txt file for the warnings"); } else { System.out.println("Test Passed"); } } public void progress(long frames) { long tmpTime; long frameTime = (long) master.framesToMillis(frames); Long lClockDiff; long lastFrameTime = (long) master.framesToMillis(lastFrame); int factor; if (isNano) { tmpTime = System.nanoTime(); lClockDiff = new Long((frameTime - lastFrameTime) - ((tmpTime - lastTime) / 1000000)); factor = 1000000; } else { tmpTime = System.currentTimeMillis(); lClockDiff = new Long((frameTime - lastFrameTime) - (tmpTime - lastTime)); factor = 1; } if ((tmpTime - startTime) >= (factor * 1000)) { startTime = tmpTime; counts[i++] = updateCount; updateCount = 0; } clockDiff.add(lClockDiff); Long lframeProgress = new Long(frames - lastFrame); if (lframeProgress < 0) { decreasing = true; } frameProgress.add(lframeProgress); Long lClockProgress = new Long((tmpTime - lastTime) / factor); clockProgress.add(lClockProgress); Long lFrame = new Long(frames); framesArr.add(lFrame); if (!frameTable.containsKey(lFrame)) { frameTable.put(lFrame, new Integer(1)); } else { int count = frameTable.get(lFrame); frameTable.put(lFrame, new Integer(count + 1)); } if (!frameProgressTable.containsKey(lframeProgress)) { frameProgressTable.put(lframeProgress, new Integer(1)); } else { int count = frameProgressTable.get(lframeProgress); frameProgressTable.put(lframeProgress, new Integer(count + 1)); } if (!clockProgresstable.containsKey(lClockProgress)) { clockProgresstable.put(lClockProgress, new Integer(1)); } else { int count = clockProgresstable.get(lClockProgress); clockProgresstable.put(lClockProgress, new Integer(count + 1)); } if (!clockDiffTable.containsKey(lClockDiff)) { clockDiffTable.put(lClockDiff, new Integer(1)); } else { int count = clockDiffTable.get(lClockDiff); clockDiffTable.put(lClockDiff, new Integer(count + 1)); } updateCount++; lastFrame = frames; lastTime = tmpTime; } public void getStats(int[] data, String type) { int sum = 0; int count = 0; // int[] datasquare = new int[data.length]; for (int i = 0; i < data.length; i++) { if (data[i] != 0) { // datasquare[i] = data[i] * data[i]; sum += data[i]; count++; } } // int[] data2 = new int[count]; // for (int i = 0; i < data2.length; i++) { // data2[i] = data[i]; // // } long mean = sum / count; System.out.println(); System.out.println("Data for " + type); System.out.println("The Mean of the " + type + "is: " + mean); System.out.println("The Median of the " + type + "is " + median(data)); int squareSum = 0; for (int i = 0; i < data.length; i++) { if (data[i] != 0) { squareSum += Math.pow((data[i] - mean), 2); } } double stdDev = Math.sqrt(squareSum / count); System.out.println("The Standard Deviation of the " + type + "is: " + stdDev); System.out.println("The Variance of the " + type + "is: " + stdDev * stdDev); } public void getStats(long[] data, String type) { float sum = 0; float count = 0; long[] data2 = new long[data.length]; for (int i = 0; i < data.length; i++) { if (data[i] != 0) { // datasquare[i] = data[i] * data[i]; sum += data[i]; count++; System.out.print(data[i] + ","); data2[i] = data[i]; } } System.out.println(); System.out.println("Count:" + count); float mean = sum / count; System.out.println(); System.out.println("Data for " + type); System.out.println("The Mean of the " + type + "is: " + mean); System.out.println("The Median of the " + type + "is " + median(data2)); double squareSum = 0; for (int i = 0; i < data.length; i++) { if (data[i] != 0) { squareSum += Math.pow((data[i] - mean), 2); } } double stdDev = Math.sqrt(squareSum / count); System.out.println("The Standard Deviation of the " + type + "is: " + stdDev); System.out.println("The Variance of the " + type + "is: " + stdDev * stdDev); } public void stateUpdated(PrecisionEvent pe) { System.out.println(pe); PrecisionEvent.EventCode code = pe.getCode(); if (code == EventCode.EOM) { System.out.println("Distinct frames and counts"); print(frameTable, "Frames"); System.out.println(); if (decreasing) { System.out.println("The Frames were Decreasing"); } else { System.out.println("The Frames were non-Decreasing"); } System.out.println(); System.out.println("Distinct frames Progress and counts"); print(frameProgressTable, "Frame Progress"); System.out.println(); System.out.println("Distinct clock Progress and counts"); print(clockProgresstable, "Clock Progress"); System.out.println(); System.out.println("The Clock Difference Values and Counts: "); print(clockDiffTable, "Clock Difference"); getStats(counts, "No of Progress Updates"); long[] frames = new long[framesArr.size()]; int i = 0; Iterator<Long> iter = framesArr.iterator(); while (iter.hasNext()) { Long l = iter.next(); frames[i++] = l.longValue(); } long[] frameProgressArr = new long[frameProgress.size()]; i = 0; iter = frameProgress.iterator(); while (iter.hasNext()) { Long l = iter.next(); frameProgressArr[i++] = l.longValue(); } long[] clockProgressArr = new long[clockProgress.size()]; i = 0; iter = clockProgress.iterator(); iter.next(); while (iter.hasNext()) { Long l = iter.next(); clockProgressArr[i++] = l.longValue(); } long[] clockDiffArr = new long[clockDiff.size()]; i = 0; iter = clockDiff.iterator(); iter.next(); while (iter.hasNext()) { Long l = iter.next(); clockDiffArr[i++] = l.longValue(); } System.out.println(); getStats(frames, "Frames"); System.out.println(); getStats(frameProgressArr, "Frame Progress"); System.out.println(); getStats(clockProgressArr, "clock progress"); System.out.println(); getStats(clockDiffArr, "Clock Difference"); } } public void print(Hashtable<Long, Integer> table, String type) { System.out.println(); System.out.println(type + " Count"); Vector<Long> v = new Vector<Long>(table.keySet()); Collections.sort(v); Iterator<Long> it = v.iterator(); while (it.hasNext()) { Long key = it.next(); if (key != 0) { System.out.println(key + " " + table.get(key)); } } } public static double median(int a[]) { int[] b = new int[a.length]; System.arraycopy(a, 0, b, 0, b.length); Arrays.sort(b); if (a.length % 2 == 0) { return (b[(b.length / 2) - 1] + b[b.length / 2]) / 2.0; } else { return b[b.length / 2]; } } public static double median(long a[]) { long[] b = new long[a.length]; System.arraycopy(a, 0, b, 0, b.length); Arrays.sort(b); if (a.length % 2 == 0) { return (b[(b.length / 2) - 1] + b[b.length / 2]) / 2.0; } else { return b[b.length / 2]; } } }