view Experiment.java @ 43:8bc6d2f52654

Syntax error.
author Carl Bussey <c.bussey@se10.qmul.ac.uk>
date Fri, 07 Jun 2013 18:19:02 +0100
parents 75354c638975
children 351b0c8b34ac
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 javax.sound.midi.*;
import java.util.Scanner;

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;
    private boolean fullScreen;

    /* 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 fs, 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 (fs == 0)
            fullScreen = false;
        else
            fullScreen = true;
        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) {
        GraphicsDevice gd = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice();
        if(fullScreen){
            if (gd.isFullScreenSupported()) {
                System.out.println("Entering full Screen... Press <enter> to continue.");
                Scanner scanner = new Scanner(System.in);
                scanner.nextLine();
                gui.setUndecorated(true);
                gd.setFullScreenWindow(gui);
            } else {
                System.out.println("Not Full Screen Supported :(");
                showDefaultGUI(width, height);
            }
        }
        else{
            showDefaultGUI(width, height);
        }
    }
    
    public void showDefaultGUI(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 == 15) {

        // Parse Arguments 
        int n = 0;
        int sc = Integer.parseInt(args[n++]); 
        int cu = Integer.parseInt(args[n++]); 
        int nu = Integer.parseInt(args[n++]); 
        String mdInput = args[n++];
        int md = -1;
        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 fs = Integer.parseInt(args[n++]);
        int de = Integer.parseInt(args[n++]);

    if(isBooleanFormat(mdInput)){
        boolean defaultMD = Boolean.parseBoolean(mdInput);
        
        if(!defaultMD){
            displayMIDIDevices();
            System.out.print("Specify the desired MIDI Device: ");
            Scanner scan = new Scanner(System.in);
            String input = scan.next();
            
            while(!isMIDIDevice(input)){
                System.out.print("Enter a valid input:");
                input = scan.next();
            }
            md = Integer.parseInt(input);
        }
        else{
            md = -1;
        }
    }
    else if(isMIDIDevice(mdInput)){
            md = Integer.parseInt(mdInput);
    }
    else{
        showUsage();
    }

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

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

    /*
     * Print a list of accessible MIDI devices
     */
    public static 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 (int i=0; i<devices.length; i++) {
            MidiDevice.Info m = devices[i];
            System.out.println(i+". MIDI device: " + m.getName() + " - " + m.getDescription());
	    }
	}
    }
    
    public static boolean isBooleanFormat(String s){
        if(s.toLowerCase().equals("true") || s.toLowerCase().equals("false")){
            return true;
        }
        else {
            return false;
        }
    }

	public static boolean isMIDIDevice(String dev){
		boolean output;
        MidiDevice.Info[] devices = MidiSystem.getMidiDeviceInfo();
        
		try {
			int device = Integer.parseInt(dev);
            if(device>devices.length-1 || device<0){
                output = false;
            }
            else { output = true; }
		} catch(NumberFormatException e) {
			output = false;
		}
		return output;
	}

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

}