Mercurial > hg > mep
comparison 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 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:4031cbb02f08 |
---|---|
1 /*============================================================================= | |
2 * File: Block.java | |
3 * Author: Marcus Pearce <m.pearce@gold.ac.uk> | |
4 * Created: <2008-01-07 10:38:45 marcusp> | |
5 * Time-stamp: <2010-05-17 11:42:23 marcusp> | |
6 *============================================================================= | |
7 */ | |
8 | |
9 import java.util.Collections; | |
10 import java.util.ArrayList; | |
11 import java.util.Iterator; | |
12 import java.io.*; | |
13 | |
14 public class Block { | |
15 | |
16 /* Label */ | |
17 private String label; | |
18 private boolean writeResults; | |
19 | |
20 /* the list of midi files, the current midi file and the midi directory*/ | |
21 private FileList filelist; | |
22 private String filename; | |
23 private int melodyNumber; | |
24 | |
25 /* The Experiment and GUI */ | |
26 private ExperimentGui gui; | |
27 private Experiment exp; | |
28 | |
29 /* The MidiPlayer */ | |
30 private MidiPlayer mp; | |
31 | |
32 /* Probe positions, note onsets, durations, IOIs and pitches */ | |
33 private ArrayList probes, onsets, iois, durations, pitches, clockStartTimes; | |
34 private long tatum; | |
35 | |
36 /* The start of the song in nanoseconds */ | |
37 private long startTime; | |
38 | |
39 /* Results */ | |
40 private MelodyResults mResults; | |
41 | |
42 /* whether the current song has run yet or not */ | |
43 private boolean hasRun; | |
44 | |
45 /* | |
46 * Accessors | |
47 */ | |
48 public String getLabel() { return label; } | |
49 public int getMelodyNumber() { return melodyNumber; } | |
50 public void setMelodyNumber(int n) { melodyNumber = n; } | |
51 public long getTatum() { return tatum; } | |
52 public MelodyResults getMelodyResults() { return mResults; } | |
53 public ArrayList getProbePositions() { return probes; } | |
54 public ArrayList getInterOnsetIntervals() { return iois; } | |
55 public ArrayList getOnsets() { return onsets; } | |
56 public ArrayList getClockStartTimes() { return clockStartTimes; } | |
57 | |
58 /* set the start time in nanoseconds to NOW */ | |
59 public long getStartTime() { return startTime; } | |
60 public void setStartTime() { startTime = System.nanoTime(); } | |
61 | |
62 /* | |
63 * constructor | |
64 */ | |
65 public Block(Experiment e, ExperimentGui eg, String fl, String lab, | |
66 boolean wr) { | |
67 // set-up variables | |
68 exp = e; | |
69 gui = eg; | |
70 label = lab; | |
71 filelist = new FileList(fl); | |
72 filename = (String)filelist.currentFile(); | |
73 melodyNumber = 1; | |
74 writeResults = wr; | |
75 // initialise the block | |
76 hasRun = false; | |
77 initialiseBlock(); | |
78 // Write out stimulus structure for all melodies in block | |
79 //writeStimuli(); | |
80 } | |
81 | |
82 /* initialise the block */ | |
83 public void initialiseBlock() { | |
84 // Initialise the Midiplayer | |
85 mp = new MidiPlayer(exp.getMidiDirectory().concat(filename)); | |
86 // Set up the melody structure and the probe positions | |
87 setupSong(); | |
88 setupProbes(); | |
89 // Set up the results object for this melody | |
90 mResults = new MelodyResults(filename, probes, | |
91 onsets, iois, durations, pitches); | |
92 mResults.setSubjectID(exp.getSubjectID()); | |
93 hasRun = false; | |
94 } | |
95 | |
96 public void storeMelodyResult() { | |
97 if (writeResults && hasRun) | |
98 exp.addToSubjectResults(mResults); | |
99 } | |
100 | |
101 private void setupSong() { | |
102 // Get the note IOI and Onset lists | |
103 onsets = mp.getOnsets(); | |
104 durations = mp.getDurations(); | |
105 iois = mp.getInterOnsetIntervals(); | |
106 pitches = mp.getPitches(); | |
107 tatum = mp.getTatum(); | |
108 } | |
109 | |
110 private void setupProbes() { | |
111 ArrayList probePos = filelist.currentProbes(); | |
112 Iterator ppi = probePos.iterator(); | |
113 | |
114 // By convention, the first probe position is the unexpected | |
115 // one and the second is the expected one. | |
116 //probeValues.add(ProbeID.PROBE_UNEX); | |
117 //probeValues.add(ProbeID.PROBE_EX); | |
118 | |
119 ArrayList probeValues = new ArrayList(probePos.size()); | |
120 | |
121 for (int i = 0; i < probePos.size(); i++) | |
122 probeValues.add(ProbeID.PROBE); | |
123 Iterator pvi = probeValues.iterator(); | |
124 | |
125 | |
126 // Set up probes | |
127 probes = new ArrayList(onsets.size()); | |
128 for (int i = 0; i < onsets.size(); i++) | |
129 probes.add(ProbeID.NOT_PROBE); | |
130 | |
131 while(ppi.hasNext()) { | |
132 int probe = ((Integer)ppi.next()).intValue(); | |
133 // probes.set(probe - numEvents, ProbeID.START_CLOCK); | |
134 probes.set(probe - 1, ProbeID.BEFORE_PROBE); | |
135 probes.set(probe, (ProbeID)pvi.next()); | |
136 probes.set(probe + 1, ProbeID.AFTER_PROBE); | |
137 } | |
138 | |
139 // Set up the clock start times | |
140 clockStartTimes = new ArrayList(probePos.size()); | |
141 long clockTimeInMicroseconds = | |
142 (tatum * exp.getClockUnits() * exp.getNumUnits()); | |
143 for (int i = 0; i < probePos.size(); i++) { | |
144 int ppos = ((Integer)probePos.get(i)).intValue(); | |
145 long onset = ((Long)(onsets.get(ppos))).longValue(); | |
146 clockStartTimes.add(onset - clockTimeInMicroseconds); | |
147 } | |
148 try { | |
149 Collections.sort(clockStartTimes); | |
150 } catch (Exception e) { | |
151 e.printStackTrace(); | |
152 } | |
153 } | |
154 | |
155 public void printProbes() { | |
156 Iterator pi = probes.iterator(); | |
157 | |
158 int i = 1; | |
159 while(pi.hasNext()) { | |
160 System.out.println(filename + " " + i + ": " + pi.next()); | |
161 i++; | |
162 } | |
163 } | |
164 | |
165 public String nextFile() { | |
166 filelist.incrementFileIndex(); | |
167 filename = filelist.currentFile(); | |
168 melodyNumber = melodyNumber + 1; | |
169 return filename; | |
170 } | |
171 | |
172 /* add a reponse i and time t (nanoseconds) */ | |
173 public void addResponse(int i, long t) { | |
174 // System.out.println("answer = " + i + | |
175 // "; responseTime = " + t + | |
176 // "; startTime = " + startTime + | |
177 // "; answer = " + (t - startTime) / 1000); | |
178 // add relative responseTime in microseconds | |
179 mResults.addResponse(i, (t - startTime) / 1000); | |
180 } | |
181 | |
182 public void addMelodyQA(String q, String a) { | |
183 mResults.addQuestion(q); | |
184 mResults.addAnswer(a); | |
185 } | |
186 | |
187 public void presentStimulus() { | |
188 // Start the experiment | |
189 setStartTime(); | |
190 mp.play(); | |
191 hasRun = true; | |
192 | |
193 // Wait for midi file to stop playing | |
194 //try { Thread.sleep((mp.getLength() / 1000) + 2000); } | |
195 //catch (InterruptedException e) {} | |
196 } | |
197 | |
198 public boolean isRunning() { return mp.getSequencer().isRunning(); } | |
199 public boolean hasRun() { return hasRun; } | |
200 | |
201 | |
202 /* | |
203 * Write out stimulus onsets and probe positions | |
204 */ | |
205 | |
206 public void writeStimuli() { | |
207 String midiFile; | |
208 while((midiFile = filelist.currentFile()) != null) { | |
209 | |
210 Writer writer = null; | |
211 String composition = midiFile.substring(0, midiFile.length() - 4); | |
212 String outFile = | |
213 exp.RESULTS_DIRECTORY + File.separator + | |
214 "stimuli" + File.separator + composition | |
215 + ".onsets"; | |
216 File outputFile = new File(outFile); | |
217 | |
218 MidiPlayer midip = | |
219 new MidiPlayer(exp.getMidiDirectory().concat(midiFile)); | |
220 | |
221 // Setup the probes | |
222 ArrayList probePos = filelist.currentProbes(); | |
223 // Write the data | |
224 try { | |
225 writer = new FileWriter (outputFile, true); | |
226 } catch (IOException e) { | |
227 System.out.println("Could not write file: " + | |
228 outputFile.getPath()); | |
229 return; | |
230 } | |
231 try { | |
232 writeResults(writer, midip, probePos, composition); | |
233 writer.close(); | |
234 } catch (IOException e) { | |
235 System.out.println (e.getMessage()); | |
236 return; | |
237 } | |
238 // increment the file index | |
239 filelist.incrementFileIndex(); | |
240 } | |
241 // Reset filelist | |
242 filelist.setFileIndex(0); | |
243 } | |
244 | |
245 private void writeResults(Writer w, MidiPlayer mipl, ArrayList probePos, | |
246 String composition) | |
247 throws IOException { | |
248 | |
249 System.out.println(composition); | |
250 | |
251 ArrayList ons = mipl.getOnsets(); | |
252 ArrayList pits = mipl.getPitches(); | |
253 | |
254 Iterator oi = ons.iterator(); | |
255 Iterator piti = pits.iterator(); | |
256 | |
257 // setup probes | |
258 Iterator ppi = probePos.iterator(); | |
259 | |
260 // By convention, the first probe position is the unexpected | |
261 // one and the second is the expected one. | |
262 // probeValues.add(ProbeID.PROBE_UNEX); | |
263 // probeValues.add(ProbeID.PROBE_EX); | |
264 | |
265 ArrayList probeValues = new ArrayList(probePos.size()); | |
266 for (int i = 0; i < probePos.size(); i++) | |
267 probeValues.add(ProbeID.PROBE); | |
268 | |
269 Iterator pvi = probeValues.iterator(); | |
270 | |
271 ArrayList pprobes = new ArrayList(ons.size()); | |
272 for (int i = 0; i < ons.size(); i++) | |
273 pprobes.add(ProbeID.NOT_PROBE); | |
274 | |
275 while(ppi.hasNext()) { | |
276 int probe = ((Integer)ppi.next()).intValue(); | |
277 pprobes.set(probe - 1, ProbeID.BEFORE_PROBE); | |
278 pprobes.set(probe, (ProbeID)pvi.next()); | |
279 pprobes.set(probe + 1, ProbeID.AFTER_PROBE); | |
280 } | |
281 | |
282 Iterator pi = pprobes.iterator(); | |
283 int eventIndex = 1; | |
284 | |
285 //writeHeader(w); | |
286 | |
287 while(oi.hasNext()) { | |
288 long onset = ((Long)oi.next()).longValue(); | |
289 int pitch = ((Integer)piti.next()).intValue(); | |
290 | |
291 ProbeID p = (ProbeID)pi.next(); | |
292 | |
293 int probe = 0; | |
294 | |
295 switch(p) { | |
296 case NOT_PROBE: | |
297 case START_CLOCK: | |
298 case BEFORE_PROBE: | |
299 case AFTER_PROBE: | |
300 break; | |
301 case PROBE: | |
302 case PROBE_EX: | |
303 case PROBE_UNEX: | |
304 if (p == ProbeID.PROBE_UNEX) | |
305 probe = 1; | |
306 else if (p == ProbeID.PROBE_EX) | |
307 probe = 2; | |
308 else if (p == ProbeID.PROBE) | |
309 probe = 1; | |
310 break; | |
311 default: | |
312 System.out.println("Unexpected probe id: " + p); | |
313 break; | |
314 } | |
315 w.write(composition + " " + eventIndex + " " + | |
316 onset + " " + pitch + " " + | |
317 probe + "\n"); | |
318 eventIndex++; | |
319 } | |
320 } | |
321 | |
322 private void writeHeader(Writer w) throws IOException { | |
323 w.write("melody note " + | |
324 "onset pitch " + | |
325 "probe"); | |
326 w.write("\n"); | |
327 } | |
328 | |
329 } | |
330 |