m@0: /*============================================================================= m@0: * File: Experiment.java m@0: * Author: Marcus Pearce m@0: * Created: <2007-02-14 11:28:27 marcusp> marcus@14: * Time-stamp: <2012-01-16 17:10:48 marcusp> m@0: *============================================================================= m@0: */ m@0: m@0: import java.io.*; m@0: import javax.swing.UIManager; m@0: import java.awt.*; m@0: import java.awt.Color; jeremy@27: import javax.sound.midi.*; m@0: m@0: public class Experiment { m@0: m@0: /* pathnames */ m@0: private final String BASE_DIRECTORY = m@0: new File("").getAbsolutePath() + File.separator; marcus@14: private final String DATA_DIRECTORY = marcus@14: BASE_DIRECTORY + "Data" + File.separator; m@4: marcus@14: public String RESULTS_DIRECTORY = m@0: BASE_DIRECTORY + "Results" + File.separator; marcus@14: public String RESULTS_EXTENSION = ".dat"; marcus@14: public String SUBJECT_RESULTS_FILE = m@0: RESULTS_DIRECTORY + "subjects" + RESULTS_EXTENSION; m@0: m@7: public String INSTRUCTIONS_FILE = m@0: DATA_DIRECTORY + "instructions.html"; m@4: m@4: public String MIDI_DIRECTORY = m@4: DATA_DIRECTORY + "Midi" + File.separator; m@4: public String MIDIFILELIST_FILE = m@4: MIDI_DIRECTORY + "filelist.txt"; m@4: public String PRACTICE_MIDIFILELIST_FILE = m@4: MIDI_DIRECTORY + "pfilelist.txt"; m@4: m@0: m@0: /* The GUI */ m@0: private ExperimentGui gui; m@0: m@3: /* whether to show the clock */ m@3: private boolean showClock; m@0: /* the units of the clock as multiples of the tatum */ m@0: private int clockUnits; m@0: /* number of units that clock runs for before a probe event */ m@0: private int numUnits; m@0: m@8: /* whether to ask about familiarity of each song */ m@8: private boolean askFamiliarity; m@8: /* whether to ask about liking of each song */ m@8: private boolean askLiking; m@8: /* whether to include final questionnaire */ m@8: private boolean finalQuestionnaire; m@8: m@0: /* the blocks of the experiment */ m@0: Block[] blocks; m@0: int currentBlockID; m@0: m@0: /* Subject ID */ m@0: private int subjectID; m@0: m@0: /* Results */ m@0: private SubjectResults results; m@0: m@0: /* the details of the rating scale */ m@0: private int scaleLength; m@0: private String lowAnchor; m@0: private String highAnchor; m@0: m@1: /* the midi device */ m@1: private int midiDevice; m@1: m@10: /* debugging */ jeremy@32: private boolean debug; m@10: m@0: /* accessors */ m@10: public boolean getDebug() { return debug; } m@8: public boolean getAskLiking() { return askLiking; } m@8: public boolean getAskFamiliarity() { return askFamiliarity; } m@8: public boolean getFinalQuestionnaire() { return finalQuestionnaire; } m@8: m@1: public int getMidiDeviceNumber() { return midiDevice; } m@0: public int getScaleLength() { return scaleLength; } m@0: public String getLowAnchor() { return lowAnchor; } m@0: public String getHighAnchor() { return highAnchor; } m@0: m@0: public String getMidiDirectory() { return MIDI_DIRECTORY; } m@0: public SubjectResults getSubjectResults() { return results; } m@0: public Block getCurrentBlock() { return blocks[currentBlockID]; } m@0: public int getCurrentBlockID() { return currentBlockID + 1; } m@3: public boolean showClock() { return showClock; } m@0: public int getClockUnits() { return clockUnits; } m@0: public int getNumUnits() { return numUnits; } m@0: public String getInstructionsFile() { return INSTRUCTIONS_FILE; } m@0: public int getSubjectID() { return subjectID; } m@0: public void setSubjectID(int id) { m@0: subjectID = id; m@0: results.setSubjectID(id); m@0: results.setOutputFile(id); m@0: getCurrentBlock().getMelodyResults().setSubjectID(id); jeremy@27: System.out.println("Subject ID = " + subjectID); m@0: } m@0: m@0: /* Constructor */ jeremy@32: public Experiment (int sc, int cu, int nu, int sl, int md, String la, String ha, String mfd, String inf, String rdr, int fam, int lik, int quest, int de) { m@0: m@0: // Setup variables jeremy@32: debug = (de != 0); m@0: results = new SubjectResults(this); m@3: if (sc == 0) m@3: showClock = false; m@3: else m@3: showClock = true; jeremy@33: clockUnits = positiveInteger(cu, 1); jeremy@33: numUnits = positiveInteger(nu, 4); jeremy@33: scaleLength = positiveInteger(sl, 7); m@1: midiDevice = md; m@0: lowAnchor = la; m@0: highAnchor = ha; m@4: MIDI_DIRECTORY = mfd + File.separator; m@4: MIDIFILELIST_FILE = MIDI_DIRECTORY + "filelist.txt"; m@4: PRACTICE_MIDIFILELIST_FILE = MIDI_DIRECTORY + "pfilelist.txt"; m@7: INSTRUCTIONS_FILE = inf; marcus@14: RESULTS_DIRECTORY = rdr + File.separator; marcus@14: SUBJECT_RESULTS_FILE = marcus@14: RESULTS_DIRECTORY + "subjects" + RESULTS_EXTENSION; m@8: m@8: if (fam == 0) m@8: askFamiliarity = false; m@8: else m@8: askFamiliarity = true; m@8: if (lik == 0) m@8: askLiking = false; m@8: else m@8: askLiking = true; m@8: if (quest == 0) m@8: finalQuestionnaire = false; m@8: else m@8: finalQuestionnaire = true; m@0: jeremy@32: if (debug) jeremy@32: displayMIDIDevices(); jeremy@32: m@0: // Initialise the experiment m@0: Block practice = new Block(this, gui, PRACTICE_MIDIFILELIST_FILE, m@0: "Practice", false); m@0: Block main = new Block(this, gui, MIDIFILELIST_FILE, m@0: "Main", true); m@0: blocks = new Block[2]; m@0: blocks[0] = practice; m@0: blocks[1] = main; m@0: currentBlockID = 0; m@0: m@0: // Create the GUI m@0: gui = new ExperimentGui(this); m@0: } m@0: m@0: public Boolean nextBlock() { m@0: boolean lastBlock = true; m@0: if (currentBlockID + 1 < blocks.length) m@0: currentBlockID = currentBlockID + 1; m@0: else m@0: lastBlock = false; m@0: return lastBlock; m@0: } m@0: m@0: public void addToSubjectResults(MelodyResults mr) { results.addResult(mr); } m@0: m@0: public void runExperiment () { m@0: (new Thread(gui)).start(); m@0: getCurrentBlock().presentStimulus(); m@0: } jeremy@27: public boolean isRunning() { jeremy@27: Block cur = getCurrentBlock();; jeremy@27: return cur != null && cur.isRunning(); jeremy@27: } jeremy@27: jeremy@27: public boolean hasRun() { jeremy@27: Block cur = getCurrentBlock(); jeremy@29: return cur == null || cur.hasRun(); jeremy@27: } m@0: m@0: /* Show the GUI */ m@0: public void showGUI(int width, int height) { m@0: gui.pack(); m@0: gui.setSize(width, height); m@0: // UIManager.put("Button.focus", UIManager.get("Button.select")); m@0: gui.setVisible(true); m@0: } m@0: m@0: /* Main method */ m@0: public static void main(String[] args) { m@0: if (args.length == 0) { m@0: System.out.println("Usage: " + "\t" + "java Experiment " + m@3: " " + m@3: " " + m@9: " " + marcus@14: " " + jeremy@32: "" + "" + "" + ""); m@0: System.exit(1); m@0: } m@0: m@0: // Parse Arguments m@3: int n = 0; m@3: int sc = Integer.parseInt(args[n++]); m@0: int cu = Integer.parseInt(args[n++]); m@0: int nu = Integer.parseInt(args[n++]); m@1: int md = Integer.parseInt(args[n++]); m@0: int sl = Integer.parseInt(args[n++]); m@0: String la = args[n++]; m@0: String ha = args[n++]; m@4: String mfd = args[n++]; m@7: String inf = args[n++]; marcus@14: String rdr = args[n++]; m@8: int fam = Integer.parseInt(args[n++]); m@8: int lik = Integer.parseInt(args[n++]); m@8: int quest = Integer.parseInt(args[n++]); jeremy@32: int de = Integer.parseInt(args[n++]); m@0: m@0: // Create experiment jeremy@32: Experiment exp = new Experiment(sc, cu, nu, sl, md, la, ha, mfd, inf, rdr, fam, lik, quest, de); m@0: m@0: // Show the GUI m@0: int width=(int)Toolkit.getDefaultToolkit().getScreenSize().getWidth(); m@0: int height=(int)Toolkit.getDefaultToolkit().getScreenSize().getHeight(); m@0: exp.showGUI(width, height); m@0: } jeremy@27: jeremy@27: /* jeremy@27: * Print a list of accessible MIDI devices jeremy@27: */ jeremy@27: protected void displayMIDIDevices() { jeremy@27: System.out.println("Searching for MIDI devices..."); jeremy@27: jeremy@27: MidiDevice.Info[] devices = MidiSystem.getMidiDeviceInfo(); jeremy@27: if (devices.length == 0) { jeremy@27: System.out.println("No MIDI devices found"); jeremy@27: } else { jeremy@27: for (MidiDevice.Info dev : devices) { jeremy@27: System.out.println("MIDI device: " + dev); jeremy@27: } jeremy@27: } jeremy@27: } jeremy@27: jeremy@33: private int positiveInteger(int x, int def) { jeremy@33: if (x > 0) jeremy@33: return x; jeremy@33: else jeremy@33: return def; jeremy@33: } jeremy@33: m@0: }