view Experiment.java @ 37:0e030f32a6e2

Allow alphanumeric subject IDs
author Jeremy Gow <jeremy.gow@gmail.com>
date Fri, 16 Nov 2012 10:17:19 +0000
parents 69dafbbfc422
children 796b3e3e053f
line wrap: on
line source
/*=============================================================================
 * File:       Experiment.java
 * Author:     Marcus Pearce <m.pearce@gold.ac.uk>
 * Created:    <2007-02-14 11:28:27 marcusp>
 * Time-stamp: <2012-01-16 17:10:48 marcusp>
 *=============================================================================
 */

import java.io.*;
import javax.swing.UIManager; 
import java.awt.*;
import java.awt.Color;
import javax.sound.midi.*;

public class Experiment { 

    /* pathnames */ 
    private final String BASE_DIRECTORY = 
        new File("").getAbsolutePath() + File.separator; 
    private final String DATA_DIRECTORY = 
        BASE_DIRECTORY + "Data" + File.separator; 

    public String RESULTS_DIRECTORY = 
        BASE_DIRECTORY + "Results" + File.separator; 
    public String RESULTS_EXTENSION = ".dat"; 
    public String SUBJECT_RESULTS_FILE = 
        RESULTS_DIRECTORY + "subjects" + RESULTS_EXTENSION; 

    public String INSTRUCTIONS_FILE = 
        DATA_DIRECTORY + "instructions.html"; 

    public String MIDI_DIRECTORY = 
        DATA_DIRECTORY + "Midi" + File.separator;
    public String MIDIFILELIST_FILE = 
        MIDI_DIRECTORY + "filelist.txt"; 
    public String PRACTICE_MIDIFILELIST_FILE = 
        MIDI_DIRECTORY + "pfilelist.txt"; 


    /* The GUI */ 
    private ExperimentGui gui; 

    /* whether to show the clock */
    private boolean showClock;
    /* the units of the clock as multiples of the tatum */
    private int clockUnits; 
    /* number of units that clock runs for before a probe event */ 
    private int numUnits; 

    /* whether to ask about familiarity of each song */
    private boolean askFamiliarity;
    /* whether to ask about liking of each song */
    private boolean askLiking;
    /* whether to include final questionnaire */
    private boolean finalQuestionnaire;
    
    /* the blocks of the experiment */ 
    Block[] blocks;
    int currentBlockID; 
    
    /* Subject ID */ 
    private String subjectID; 

    /* Results */ 
    private SubjectResults results; 

    /* the details of the rating scale */
    private int scaleLength;
    private String lowAnchor;
    private String highAnchor;

    /* the midi device */
    private int midiDevice;

    /* debugging */ 
    private boolean debug;

    /* accessors */ 
    public boolean getDebug() { return debug; }
    public boolean getAskLiking() { return askLiking; }
    public boolean getAskFamiliarity() { return askFamiliarity; }
    public boolean getFinalQuestionnaire() { return finalQuestionnaire; }

    public int getMidiDeviceNumber() { return midiDevice; }
    public int getScaleLength() { return scaleLength; }
    public String getLowAnchor() { return lowAnchor; }
    public String getHighAnchor() { return highAnchor; }

    public String getMidiDirectory() { return MIDI_DIRECTORY; }
    public SubjectResults getSubjectResults() { return results; }
    public Block getCurrentBlock() { return blocks[currentBlockID]; }
    public int getCurrentBlockID() { return currentBlockID + 1; }
    public boolean showClock() { return showClock; }
    public int getClockUnits() { return clockUnits; } 
    public int getNumUnits() { return numUnits; } 
    public String getInstructionsFile() { return INSTRUCTIONS_FILE; }
    public String getSubjectID() { return subjectID; }
    public void setSubjectID(String id) { 
        subjectID = id; 
        results.setSubjectID(id); 
        results.setOutputFile(id); 
        getCurrentBlock().getMelodyResults().setSubjectID(id); 
	System.out.println("Subject ID = " + subjectID);
    }

    /* Constructor */ 
    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) { 
        
        // Setup variables 
	debug = (de != 0);
        results = new SubjectResults(this); 
        if (sc == 0) 
            showClock = false;
        else 
            showClock = true;
        clockUnits = positiveInteger(cu, 1); 
	numUnits = positiveInteger(nu, 4); 
        scaleLength = positiveInteger(sl, 7);
        midiDevice = md;
        lowAnchor = la;
        highAnchor = ha;
        MIDI_DIRECTORY = mfd + File.separator;
        MIDIFILELIST_FILE = MIDI_DIRECTORY + "filelist.txt"; 
        PRACTICE_MIDIFILELIST_FILE = MIDI_DIRECTORY + "pfilelist.txt"; 
        INSTRUCTIONS_FILE = inf;
        RESULTS_DIRECTORY = rdr + File.separator;
        SUBJECT_RESULTS_FILE = 
            RESULTS_DIRECTORY + "subjects" + RESULTS_EXTENSION;
        
        if (fam == 0)
            askFamiliarity = false;
        else 
            askFamiliarity = true; 
        if (lik == 0)
            askLiking = false;
        else 
            askLiking = true; 
        if (quest == 0)
            finalQuestionnaire = false;
        else 
            finalQuestionnaire = true; 

	if (debug)
	    displayMIDIDevices();

        // Initialise the experiment 
        Block practice = new Block(this, gui, PRACTICE_MIDIFILELIST_FILE, 
                                   "Practice", false); 
        Block main = new Block(this, gui, MIDIFILELIST_FILE, 
                               "Main", true); 
        blocks  = new Block[2]; 
        blocks[0] = practice; 
        blocks[1] = main; 
        currentBlockID = 0; 

        // Create the GUI 
        gui = new ExperimentGui(this); 
    }

    public Boolean nextBlock() { 
        boolean lastBlock = true; 
        if (currentBlockID + 1 < blocks.length) 
            currentBlockID = currentBlockID + 1; 
        else 
            lastBlock = false; 
        return lastBlock; 
    }

    public void addToSubjectResults(MelodyResults mr) { results.addResult(mr); }

    public void runExperiment () { 
        (new Thread(gui)).start();
        getCurrentBlock().presentStimulus(); 
    }
    public boolean isRunning() {
	Block cur = getCurrentBlock();;
	return cur != null && cur.isRunning();
    }
    
    public boolean hasRun() {
	Block cur = getCurrentBlock();
	return cur == null || cur.hasRun();
    } 

    /* Show the GUI */ 
    public void showGUI(int width, int height) { 
        gui.pack();
        gui.setSize(width, height); 
        // UIManager.put("Button.focus", UIManager.get("Button.select"));
        gui.setVisible(true);
    } 

    /* Main method */ 
    public static void main(String[] args) {
	
	if (args.length == 14) {

        // Parse Arguments 
        int n = 0;
        int sc = Integer.parseInt(args[n++]); 
        int cu = Integer.parseInt(args[n++]); 
        int nu = Integer.parseInt(args[n++]); 
        int md = Integer.parseInt(args[n++]); 
        int sl = Integer.parseInt(args[n++]); 
        String la = args[n++];
        String ha = args[n++];
        String mfd = args[n++];
        String inf = args[n++];
        String rdr = args[n++];
        int fam = Integer.parseInt(args[n++]);
        int lik = Integer.parseInt(args[n++]);
        int quest = Integer.parseInt(args[n++]);
        int de = Integer.parseInt(args[n++]);

        // Create experiment 
        Experiment exp = new Experiment(sc, cu, nu, sl, md, la, ha, mfd, inf, rdr, fam, lik, quest, de);
        
        // Show the GUI 
        int width=(int)Toolkit.getDefaultToolkit().getScreenSize().getWidth();
        int height=(int)Toolkit.getDefaultToolkit().getScreenSize().getHeight();
        exp.showGUI(width, height); 

	} else {
	     System.out.println("Usage: " + "\t" + "java Experiment " + 
                               "<show clock?> <clock units> <number of units> " + 
                               "<midi device> " + 
                               "<scale length> <low anchor> <high anchor> " +
                               "<midi file directory> <instructions file> <results directory>" + 
                               "<familiarity>" + "<pleasantness>" + "<questionnaire>" + "<debug>");
            System.exit(1);
	}
    }

    /*
     * Print a list of accessible MIDI devices
     */
    protected void displayMIDIDevices() {
	System.out.println("Searching for MIDI devices...");
	    
	MidiDevice.Info[] devices = MidiSystem.getMidiDeviceInfo();
	if (devices.length == 0) {
	    System.out.println("No MIDI devices found");
	} else {
	    for (MidiDevice.Info dev : devices) {
		System.out.println("MIDI device: " + dev);
	    }
	}
    }

    private int positiveInteger(int x, int def) {
	if (x > 0) 
	    return x;
	else
	    return def;
    }

}