Mercurial > hg > mep
diff Block.java @ 0:4031cbb02f08
Initial import.
Ignore-this: 87317e384f22bde48db996355191fa5f
author | Marcus Pearce <m.pearce@gold.ac.uk> |
---|---|
date | Tue, 18 May 2010 11:37:10 +0100 |
parents | |
children | 93ed757b9871 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Block.java Tue May 18 11:37:10 2010 +0100 @@ -0,0 +1,330 @@ +/*============================================================================= + * File: Block.java + * Author: Marcus Pearce <m.pearce@gold.ac.uk> + * Created: <2008-01-07 10:38:45 marcusp> + * Time-stamp: <2010-05-17 11:42:23 marcusp> + *============================================================================= + */ + +import java.util.Collections; +import java.util.ArrayList; +import java.util.Iterator; +import java.io.*; + +public class Block { + + /* Label */ + private String label; + private boolean writeResults; + + /* the list of midi files, the current midi file and the midi directory*/ + private FileList filelist; + private String filename; + private int melodyNumber; + + /* The Experiment and GUI */ + private ExperimentGui gui; + private Experiment exp; + + /* The MidiPlayer */ + private MidiPlayer mp; + + /* Probe positions, note onsets, durations, IOIs and pitches */ + private ArrayList probes, onsets, iois, durations, pitches, clockStartTimes; + private long tatum; + + /* The start of the song in nanoseconds */ + private long startTime; + + /* Results */ + private MelodyResults mResults; + + /* whether the current song has run yet or not */ + private boolean hasRun; + + /* + * Accessors + */ + public String getLabel() { return label; } + public int getMelodyNumber() { return melodyNumber; } + public void setMelodyNumber(int n) { melodyNumber = n; } + public long getTatum() { return tatum; } + public MelodyResults getMelodyResults() { return mResults; } + public ArrayList getProbePositions() { return probes; } + public ArrayList getInterOnsetIntervals() { return iois; } + public ArrayList getOnsets() { return onsets; } + public ArrayList getClockStartTimes() { return clockStartTimes; } + + /* set the start time in nanoseconds to NOW */ + public long getStartTime() { return startTime; } + public void setStartTime() { startTime = System.nanoTime(); } + + /* + * constructor + */ + public Block(Experiment e, ExperimentGui eg, String fl, String lab, + boolean wr) { + // set-up variables + exp = e; + gui = eg; + label = lab; + filelist = new FileList(fl); + filename = (String)filelist.currentFile(); + melodyNumber = 1; + writeResults = wr; + // initialise the block + hasRun = false; + initialiseBlock(); + // Write out stimulus structure for all melodies in block + //writeStimuli(); + } + + /* initialise the block */ + public void initialiseBlock() { + // Initialise the Midiplayer + mp = new MidiPlayer(exp.getMidiDirectory().concat(filename)); + // Set up the melody structure and the probe positions + setupSong(); + setupProbes(); + // Set up the results object for this melody + mResults = new MelodyResults(filename, probes, + onsets, iois, durations, pitches); + mResults.setSubjectID(exp.getSubjectID()); + hasRun = false; + } + + public void storeMelodyResult() { + if (writeResults && hasRun) + exp.addToSubjectResults(mResults); + } + + private void setupSong() { + // Get the note IOI and Onset lists + onsets = mp.getOnsets(); + durations = mp.getDurations(); + iois = mp.getInterOnsetIntervals(); + pitches = mp.getPitches(); + tatum = mp.getTatum(); + } + + private void setupProbes() { + ArrayList probePos = filelist.currentProbes(); + Iterator ppi = probePos.iterator(); + + // By convention, the first probe position is the unexpected + // one and the second is the expected one. + //probeValues.add(ProbeID.PROBE_UNEX); + //probeValues.add(ProbeID.PROBE_EX); + + ArrayList probeValues = new ArrayList(probePos.size()); + + for (int i = 0; i < probePos.size(); i++) + probeValues.add(ProbeID.PROBE); + Iterator pvi = probeValues.iterator(); + + + // Set up probes + probes = new ArrayList(onsets.size()); + for (int i = 0; i < onsets.size(); i++) + probes.add(ProbeID.NOT_PROBE); + + while(ppi.hasNext()) { + int probe = ((Integer)ppi.next()).intValue(); + // probes.set(probe - numEvents, ProbeID.START_CLOCK); + probes.set(probe - 1, ProbeID.BEFORE_PROBE); + probes.set(probe, (ProbeID)pvi.next()); + probes.set(probe + 1, ProbeID.AFTER_PROBE); + } + + // Set up the clock start times + clockStartTimes = new ArrayList(probePos.size()); + long clockTimeInMicroseconds = + (tatum * exp.getClockUnits() * exp.getNumUnits()); + for (int i = 0; i < probePos.size(); i++) { + int ppos = ((Integer)probePos.get(i)).intValue(); + long onset = ((Long)(onsets.get(ppos))).longValue(); + clockStartTimes.add(onset - clockTimeInMicroseconds); + } + try { + Collections.sort(clockStartTimes); + } catch (Exception e) { + e.printStackTrace(); + } + } + + public void printProbes() { + Iterator pi = probes.iterator(); + + int i = 1; + while(pi.hasNext()) { + System.out.println(filename + " " + i + ": " + pi.next()); + i++; + } + } + + public String nextFile() { + filelist.incrementFileIndex(); + filename = filelist.currentFile(); + melodyNumber = melodyNumber + 1; + return filename; + } + + /* add a reponse i and time t (nanoseconds) */ + public void addResponse(int i, long t) { + // System.out.println("answer = " + i + + // "; responseTime = " + t + + // "; startTime = " + startTime + + // "; answer = " + (t - startTime) / 1000); + // add relative responseTime in microseconds + mResults.addResponse(i, (t - startTime) / 1000); + } + + public void addMelodyQA(String q, String a) { + mResults.addQuestion(q); + mResults.addAnswer(a); + } + + public void presentStimulus() { + // Start the experiment + setStartTime(); + mp.play(); + hasRun = true; + + // Wait for midi file to stop playing + //try { Thread.sleep((mp.getLength() / 1000) + 2000); } + //catch (InterruptedException e) {} + } + + public boolean isRunning() { return mp.getSequencer().isRunning(); } + public boolean hasRun() { return hasRun; } + + + /* + * Write out stimulus onsets and probe positions + */ + + public void writeStimuli() { + String midiFile; + while((midiFile = filelist.currentFile()) != null) { + + Writer writer = null; + String composition = midiFile.substring(0, midiFile.length() - 4); + String outFile = + exp.RESULTS_DIRECTORY + File.separator + + "stimuli" + File.separator + composition + + ".onsets"; + File outputFile = new File(outFile); + + MidiPlayer midip = + new MidiPlayer(exp.getMidiDirectory().concat(midiFile)); + + // Setup the probes + ArrayList probePos = filelist.currentProbes(); + // Write the data + try { + writer = new FileWriter (outputFile, true); + } catch (IOException e) { + System.out.println("Could not write file: " + + outputFile.getPath()); + return; + } + try { + writeResults(writer, midip, probePos, composition); + writer.close(); + } catch (IOException e) { + System.out.println (e.getMessage()); + return; + } + // increment the file index + filelist.incrementFileIndex(); + } + // Reset filelist + filelist.setFileIndex(0); + } + + private void writeResults(Writer w, MidiPlayer mipl, ArrayList probePos, + String composition) + throws IOException { + + System.out.println(composition); + + ArrayList ons = mipl.getOnsets(); + ArrayList pits = mipl.getPitches(); + + Iterator oi = ons.iterator(); + Iterator piti = pits.iterator(); + + // setup probes + Iterator ppi = probePos.iterator(); + + // By convention, the first probe position is the unexpected + // one and the second is the expected one. + // probeValues.add(ProbeID.PROBE_UNEX); + // probeValues.add(ProbeID.PROBE_EX); + + ArrayList probeValues = new ArrayList(probePos.size()); + for (int i = 0; i < probePos.size(); i++) + probeValues.add(ProbeID.PROBE); + + Iterator pvi = probeValues.iterator(); + + ArrayList pprobes = new ArrayList(ons.size()); + for (int i = 0; i < ons.size(); i++) + pprobes.add(ProbeID.NOT_PROBE); + + while(ppi.hasNext()) { + int probe = ((Integer)ppi.next()).intValue(); + pprobes.set(probe - 1, ProbeID.BEFORE_PROBE); + pprobes.set(probe, (ProbeID)pvi.next()); + pprobes.set(probe + 1, ProbeID.AFTER_PROBE); + } + + Iterator pi = pprobes.iterator(); + int eventIndex = 1; + + //writeHeader(w); + + while(oi.hasNext()) { + long onset = ((Long)oi.next()).longValue(); + int pitch = ((Integer)piti.next()).intValue(); + + ProbeID p = (ProbeID)pi.next(); + + int probe = 0; + + switch(p) { + case NOT_PROBE: + case START_CLOCK: + case BEFORE_PROBE: + case AFTER_PROBE: + break; + case PROBE: + case PROBE_EX: + case PROBE_UNEX: + if (p == ProbeID.PROBE_UNEX) + probe = 1; + else if (p == ProbeID.PROBE_EX) + probe = 2; + else if (p == ProbeID.PROBE) + probe = 1; + break; + default: + System.out.println("Unexpected probe id: " + p); + break; + } + w.write(composition + " " + eventIndex + " " + + onset + " " + pitch + " " + + probe + "\n"); + eventIndex++; + } + } + + private void writeHeader(Writer w) throws IOException { + w.write("melody note " + + "onset pitch " + + "probe"); + w.write("\n"); + } + +} +