stevenh@37
|
1 package org.qmul.eecs.c4dm.sia.midi;
|
stevenh@37
|
2
|
stevenh@37
|
3 import java.io.File;
|
stevenh@37
|
4 import java.io.FileNotFoundException;
|
stevenh@37
|
5 import java.io.FileOutputStream;
|
stevenh@37
|
6 import java.io.IOException;
|
stevenh@37
|
7 import java.util.ArrayList;
|
stevenh@37
|
8 import java.util.Collection;
|
stevenh@37
|
9 import java.util.HashMap;
|
stevenh@37
|
10 import java.util.Iterator;
|
stevenh@37
|
11 import java.util.List;
|
stevenh@37
|
12 import java.util.Vector;
|
stevenh@37
|
13
|
stevenh@37
|
14 import javax.sound.midi.InvalidMidiDataException;
|
stevenh@37
|
15 import javax.sound.midi.MetaMessage;
|
stevenh@37
|
16 import javax.sound.midi.MidiEvent;
|
stevenh@37
|
17 import javax.sound.midi.MidiMessage;
|
stevenh@37
|
18 import javax.sound.midi.MidiSystem;
|
stevenh@37
|
19 import javax.sound.midi.Sequence;
|
stevenh@37
|
20 import javax.sound.midi.ShortMessage;
|
stevenh@37
|
21 import javax.sound.midi.SysexMessage;
|
stevenh@37
|
22 import javax.sound.midi.Track;
|
stevenh@37
|
23
|
stevenh@46
|
24 import org.qmul.eecs.c4dm.sia.SiaMain;
|
stevenh@37
|
25 import org.qmul.eecs.c4dm.sia.model.Datapoint;
|
stevenh@37
|
26 import org.qmul.eecs.c4dm.sia.model.DimensionValue;
|
stevenh@37
|
27 import org.qmul.eecs.c4dm.sia.rdf.Namespaces;
|
stevenh@37
|
28
|
stevenh@37
|
29 import com.hp.hpl.jena.ontology.OntClass;
|
stevenh@37
|
30 import com.hp.hpl.jena.ontology.OntModel;
|
stevenh@37
|
31 import com.hp.hpl.jena.ontology.OntResource;
|
stevenh@46
|
32 import com.hp.hpl.jena.query.Dataset;
|
stevenh@46
|
33 import com.hp.hpl.jena.query.ReadWrite;
|
stevenh@37
|
34 import com.hp.hpl.jena.rdf.model.AnonId;
|
stevenh@37
|
35 import com.hp.hpl.jena.rdf.model.ModelFactory;
|
stevenh@37
|
36 import com.hp.hpl.jena.rdf.model.NodeIterator;
|
stevenh@37
|
37 import com.hp.hpl.jena.rdf.model.Property;
|
stevenh@37
|
38 import com.hp.hpl.jena.rdf.model.RDFNode;
|
stevenh@37
|
39 import com.hp.hpl.jena.rdf.model.Resource;
|
stevenh@37
|
40 import com.hp.hpl.jena.rdf.model.Statement;
|
stevenh@37
|
41 import com.hp.hpl.jena.rdf.model.StmtIterator;
|
stevenh@46
|
42 import com.hp.hpl.jena.tdb.TDBFactory;
|
stevenh@37
|
43 import com.hp.hpl.jena.util.iterator.ExtendedIterator;
|
stevenh@37
|
44 import com.hp.hpl.jena.vocabulary.RDF;
|
stevenh@37
|
45 import com.sun.media.sound.MidiUtils;
|
stevenh@37
|
46
|
stevenh@37
|
47 public class MidiParser {
|
stevenh@37
|
48
|
stevenh@37
|
49 public static final int TIME_DIMENSION = 1;
|
stevenh@37
|
50 public static final int PITCH_DIMENSION = 2;
|
stevenh@37
|
51 public static final int CHANNEL_DIMENSION = 3;
|
stevenh@37
|
52
|
stevenh@37
|
53 // The ontology loaded as dataset
|
stevenh@37
|
54 private static final String ontology = "file:src/rdf/siaDatapointOntology.n3";
|
stevenh@37
|
55
|
stevenh@37
|
56 // The final output file
|
stevenh@37
|
57 private static final String finalModelFileName = "src/rdf/midiModel";
|
stevenh@37
|
58
|
stevenh@46
|
59 // The input midi file
|
stevenh@46
|
60 private static final String midiFileName = "/Volumes/USB_DISK/portable/ewerts/Cantata_16_no_5-mids/score.mid";
|
stevenh@46
|
61
|
stevenh@37
|
62 public static void main(String[] args)
|
stevenh@37
|
63 {
|
stevenh@37
|
64 // First create a Jena ontology model
|
stevenh@37
|
65 OntModel ontModel = ModelFactory
|
stevenh@37
|
66 .createOntologyModel(); // OntModelSpec.OWL_MEM
|
stevenh@37
|
67
|
stevenh@37
|
68 // Then read the data from the file into the ontology model
|
stevenh@37
|
69 ontModel.read(ontology, "N3");
|
stevenh@37
|
70
|
stevenh@37
|
71 OntClass datapointClass = ontModel.getOntClass(Datapoint.RESOURCE_URI);
|
stevenh@37
|
72 Resource datapointResource = ontModel.getOntResource(datapointClass);
|
stevenh@37
|
73 Property siaDimValProperty = ontModel.createProperty(DimensionValue.PROPERTY_URI);
|
stevenh@37
|
74 Property siaDimensionProperty = ontModel.createProperty(DimensionValue.DIMENSION_URI);
|
stevenh@37
|
75 Property siaValueProperty = ontModel.createProperty(DimensionValue.VALUE_URI);
|
stevenh@37
|
76
|
stevenh@37
|
77 File midiFile1 = new File(midiFileName);
|
stevenh@37
|
78
|
stevenh@37
|
79 Sequence sequence = null;
|
stevenh@37
|
80 try {
|
stevenh@37
|
81 sequence = MidiSystem.getSequence(midiFile1);
|
stevenh@37
|
82 } catch (InvalidMidiDataException e) {
|
stevenh@37
|
83 e.printStackTrace();
|
stevenh@37
|
84 System.exit(1);
|
stevenh@37
|
85 } catch (IOException e) {
|
stevenh@37
|
86 e.printStackTrace();
|
stevenh@37
|
87 System.exit(1);
|
stevenh@37
|
88 }
|
stevenh@37
|
89
|
stevenh@37
|
90 MidiUtils.TempoCache tempoCache = new MidiUtils.TempoCache(sequence);
|
stevenh@37
|
91
|
stevenh@37
|
92 Track[] tracks = sequence.getTracks();
|
stevenh@37
|
93 int numTracks = tracks.length;
|
stevenh@37
|
94 float divisionType = sequence.getDivisionType();
|
stevenh@37
|
95 List<Datapoint> datapoints = new ArrayList<Datapoint>();
|
stevenh@37
|
96
|
stevenh@37
|
97 HashMap<Integer, Integer> trackDimensionMap = getTrackToDimensionIndexMap(sequence);
|
stevenh@37
|
98
|
stevenh@37
|
99 if (trackDimensionMap.isEmpty())
|
stevenh@37
|
100 {
|
stevenh@37
|
101 try {
|
stevenh@37
|
102 throw new Exception("Couldn't find any track to dimension mappings");
|
stevenh@37
|
103 } catch (Exception e) {
|
stevenh@37
|
104 e.printStackTrace();
|
stevenh@37
|
105 System.exit(1);
|
stevenh@37
|
106 }
|
stevenh@37
|
107 }
|
stevenh@37
|
108
|
stevenh@37
|
109 long maxTick = 0;
|
stevenh@37
|
110
|
stevenh@37
|
111 for (int trackIdx = 0; trackIdx < numTracks; trackIdx++)
|
stevenh@37
|
112 {
|
stevenh@37
|
113 System.out.println("Track " + trackIdx + ":");
|
stevenh@37
|
114 int numEvents = tracks[trackIdx].size();
|
stevenh@37
|
115 for (int eventIdx = 0; eventIdx < numEvents; eventIdx++)
|
stevenh@37
|
116 {
|
stevenh@37
|
117 MidiEvent event = tracks[trackIdx].get(eventIdx);
|
stevenh@37
|
118 long tick = event.getTick();
|
stevenh@37
|
119 MidiMessage midiMessage = event.getMessage();
|
stevenh@37
|
120
|
stevenh@37
|
121 int midiMessageLength = midiMessage.getLength();
|
stevenh@37
|
122 byte[] messageBytes = midiMessage.getMessage();
|
stevenh@37
|
123 int status = midiMessage.getStatus();
|
stevenh@37
|
124 System.out.println("tick = " + tick + " midiMessageLength = " + midiMessageLength + " status byte = " + status);
|
stevenh@37
|
125
|
stevenh@37
|
126 int s = status & 0x80;
|
stevenh@37
|
127 if (s == 0x80)
|
stevenh@37
|
128 {
|
stevenh@37
|
129 System.out.println("STATUS MESSAGE (s = " + s + ")");
|
stevenh@37
|
130 }
|
stevenh@37
|
131 else
|
stevenh@37
|
132 {
|
stevenh@37
|
133 System.out.println("not a status message (s = " + s + ")");
|
stevenh@37
|
134 }
|
stevenh@37
|
135
|
stevenh@37
|
136 // Determine the type of this message (short, sysex or meta)
|
stevenh@37
|
137 if (midiMessage instanceof ShortMessage)
|
stevenh@37
|
138 {
|
stevenh@37
|
139 System.out.print("ShortMessage ");
|
stevenh@37
|
140
|
stevenh@37
|
141 // Determine which command is being issued
|
stevenh@37
|
142 ShortMessage shortMessage = (ShortMessage)midiMessage;
|
stevenh@37
|
143 int messageCommand = shortMessage.getCommand();
|
stevenh@37
|
144 int channel = shortMessage.getChannel();
|
stevenh@37
|
145 int data1 = shortMessage.getData1();
|
stevenh@37
|
146 int data2 = shortMessage.getData2();
|
stevenh@37
|
147
|
stevenh@37
|
148 if (messageCommand == ShortMessage.ACTIVE_SENSING)
|
stevenh@37
|
149 {
|
stevenh@37
|
150 System.out.print("ignoring ACTIVE_SENSING");
|
stevenh@37
|
151 }
|
stevenh@37
|
152 else if (messageCommand == ShortMessage.CHANNEL_PRESSURE)
|
stevenh@37
|
153 {
|
stevenh@37
|
154 System.out.print("ignoring CHANNEL_PRESSURE");
|
stevenh@37
|
155 }
|
stevenh@37
|
156 else if (messageCommand == ShortMessage.CONTINUE)
|
stevenh@37
|
157 {
|
stevenh@37
|
158 System.out.print("ignoring CONTINUE");
|
stevenh@37
|
159 }
|
stevenh@37
|
160 else if (messageCommand == ShortMessage.CONTROL_CHANGE)
|
stevenh@37
|
161 {
|
stevenh@37
|
162 System.out.print("ignoring CONTROL_CHANGE");
|
stevenh@37
|
163 }
|
stevenh@37
|
164 else if (messageCommand == ShortMessage.END_OF_EXCLUSIVE)
|
stevenh@37
|
165 {
|
stevenh@37
|
166 System.out.print("ignoring END_OF_EXCLUSIVE");
|
stevenh@37
|
167 }
|
stevenh@37
|
168 else if (messageCommand == ShortMessage.MIDI_TIME_CODE)
|
stevenh@37
|
169 {
|
stevenh@37
|
170 System.out.print("ignoring MIDI_TIME_CODE");
|
stevenh@37
|
171 }
|
stevenh@37
|
172 else if (messageCommand == ShortMessage.NOTE_OFF)
|
stevenh@37
|
173 {
|
stevenh@37
|
174 System.out.println("NOTE_OFF");
|
stevenh@37
|
175 long microsecs = MidiUtils.tick2microsecond(sequence, tick, tempoCache);
|
stevenh@37
|
176 System.out.println(" microsecs = " + microsecs);
|
stevenh@37
|
177 }
|
stevenh@37
|
178 else if (messageCommand == ShortMessage.NOTE_ON)
|
stevenh@37
|
179 {
|
stevenh@37
|
180 if (tick > maxTick)
|
stevenh@37
|
181 {
|
stevenh@37
|
182 maxTick = tick;
|
stevenh@37
|
183 }
|
stevenh@37
|
184 System.out.println("NOTE_ON");
|
stevenh@46
|
185 double microsecs = MidiUtils.tick2microsecond(sequence, tick, tempoCache);
|
stevenh@46
|
186 double secs = microsecs/1000000;
|
stevenh@46
|
187 System.out.println(" microsecs = " + secs);
|
stevenh@37
|
188
|
stevenh@37
|
189 DimensionValue timeDimVal = new DimensionValue();
|
stevenh@37
|
190 timeDimVal.setDimension(TIME_DIMENSION);
|
stevenh@46
|
191 timeDimVal.setValue(secs);
|
stevenh@37
|
192
|
stevenh@46
|
193 DimensionValue pitchDimVal = new DimensionValue();
|
stevenh@46
|
194 pitchDimVal.setDimension(PITCH_DIMENSION);
|
stevenh@46
|
195 pitchDimVal.setValue(data1);
|
stevenh@37
|
196
|
stevenh@46
|
197 DimensionValue channelDimVal = new DimensionValue();
|
stevenh@46
|
198 channelDimVal.setDimension(CHANNEL_DIMENSION);
|
stevenh@46
|
199 channelDimVal.setValue(trackDimensionMap.get(trackIdx));
|
stevenh@46
|
200
|
stevenh@37
|
201 Datapoint datapoint = new Datapoint();
|
stevenh@37
|
202 Vector<DimensionValue> dimVals = new Vector<DimensionValue>();
|
stevenh@37
|
203 dimVals.add(timeDimVal);
|
stevenh@46
|
204 dimVals.add(pitchDimVal);
|
stevenh@46
|
205 dimVals.add(channelDimVal);
|
stevenh@37
|
206
|
stevenh@37
|
207 datapoint.setDimensionValues(dimVals);
|
stevenh@37
|
208 datapoints.add(datapoint);
|
stevenh@37
|
209
|
stevenh@37
|
210 // RDF
|
stevenh@37
|
211 Resource datapointBnode = ontModel.createResource(AnonId.create());
|
stevenh@37
|
212 ontModel.add(datapointBnode, RDF.type, datapointResource);
|
stevenh@37
|
213
|
stevenh@37
|
214 Resource timeDimValBnode = ontModel.createResource(AnonId.create());
|
stevenh@37
|
215 Resource pitchDimValBnode = ontModel.createResource(AnonId.create());
|
stevenh@46
|
216 Resource channelDimValBnode = ontModel.createResource(AnonId.create());
|
stevenh@37
|
217
|
stevenh@37
|
218 ontModel.add(datapointBnode, siaDimValProperty, timeDimValBnode);
|
stevenh@37
|
219 ontModel.addLiteral(timeDimValBnode, siaDimensionProperty, TIME_DIMENSION);
|
stevenh@46
|
220 ontModel.addLiteral(timeDimValBnode, siaValueProperty, secs);
|
stevenh@37
|
221
|
stevenh@37
|
222 ontModel.add(datapointBnode, siaDimValProperty, pitchDimValBnode);
|
stevenh@46
|
223 ontModel.addLiteral(pitchDimValBnode, siaDimensionProperty, PITCH_DIMENSION);
|
stevenh@37
|
224 ontModel.addLiteral(pitchDimValBnode, siaValueProperty, data1);
|
stevenh@46
|
225
|
stevenh@46
|
226 ontModel.add(datapointBnode, siaDimValProperty, channelDimValBnode);
|
stevenh@46
|
227 ontModel.addLiteral(channelDimValBnode, siaDimensionProperty, CHANNEL_DIMENSION);
|
stevenh@46
|
228 ontModel.addLiteral(channelDimValBnode, siaValueProperty, trackDimensionMap.get(trackIdx).intValue());
|
stevenh@46
|
229
|
stevenh@37
|
230 }
|
stevenh@37
|
231 else if (messageCommand == ShortMessage.PITCH_BEND)
|
stevenh@37
|
232 {
|
stevenh@37
|
233 System.out.print("ignoring PITCH_BEND");
|
stevenh@37
|
234 }
|
stevenh@37
|
235 else if (messageCommand == ShortMessage.POLY_PRESSURE)
|
stevenh@37
|
236 {
|
stevenh@37
|
237 System.out.print("ignoring POLY_PRESSURE");
|
stevenh@37
|
238 }
|
stevenh@37
|
239 else if (messageCommand == ShortMessage.PROGRAM_CHANGE)
|
stevenh@37
|
240 {
|
stevenh@37
|
241 System.out.print("ignoring PROGRAM_CHANGE");
|
stevenh@37
|
242 }
|
stevenh@37
|
243 else if (messageCommand == ShortMessage.SONG_POSITION_POINTER)
|
stevenh@37
|
244 {
|
stevenh@37
|
245 System.out.print("ignoring SONG_POSITION_POINTER");
|
stevenh@37
|
246 }
|
stevenh@37
|
247 else
|
stevenh@37
|
248 {
|
stevenh@37
|
249 System.out.print("unrecognised midi message command (" + messageCommand + ")");
|
stevenh@37
|
250 }
|
stevenh@37
|
251 System.out.print(", channel " + channel + ", data1 = [" + data1 + "], data2 = [" + data2 + "]");
|
stevenh@37
|
252 System.out.println();
|
stevenh@37
|
253 }
|
stevenh@37
|
254 else if (midiMessage instanceof MetaMessage)
|
stevenh@37
|
255 {
|
stevenh@37
|
256 System.out.println("MetaMessage");
|
stevenh@37
|
257
|
stevenh@37
|
258 MetaMessage metaMessage = (MetaMessage)midiMessage;
|
stevenh@37
|
259 byte[] metaMessageData = metaMessage.getData();
|
stevenh@37
|
260 int metaMessageLength = metaMessage.getLength();
|
stevenh@37
|
261 int metaMessageType = metaMessage.getType();
|
stevenh@37
|
262 System.out.println("metaMessageType = " + metaMessageType + ", metaMessageLength = " + metaMessageLength);
|
stevenh@37
|
263
|
stevenh@37
|
264 // Determine message type
|
stevenh@37
|
265 if (metaMessageType == 81)
|
stevenh@37
|
266 {
|
stevenh@37
|
267 if (divisionType == Sequence.PPQ)
|
stevenh@37
|
268 {
|
stevenh@37
|
269 // Do nothing - we've dealt with PPQ tempo data elsewhere
|
stevenh@37
|
270 }
|
stevenh@37
|
271 else
|
stevenh@37
|
272 {
|
stevenh@37
|
273 try {
|
stevenh@37
|
274 throw new Exception("Not yet implemented SMPTE tempo metadata");
|
stevenh@37
|
275 } catch (Exception e) {
|
stevenh@37
|
276 e.printStackTrace();
|
stevenh@37
|
277 System.exit(1);
|
stevenh@37
|
278 }
|
stevenh@37
|
279 }
|
stevenh@37
|
280 }
|
stevenh@37
|
281
|
stevenh@37
|
282 for (int dataIdx = 0; dataIdx < metaMessageData.length; dataIdx++)
|
stevenh@37
|
283 {
|
stevenh@37
|
284 System.out.println("\tmetaMessageData[" + dataIdx + "] = " + (metaMessageType == 81 ? metaMessageData[dataIdx] : (char)metaMessageData[dataIdx]));
|
stevenh@37
|
285 }
|
stevenh@37
|
286
|
stevenh@37
|
287 }
|
stevenh@37
|
288 else if (midiMessage instanceof SysexMessage)
|
stevenh@37
|
289 {
|
stevenh@37
|
290 // We can safely ignore these messages
|
stevenh@37
|
291 System.out.println("ignoring SysexMessage");
|
stevenh@37
|
292 }
|
stevenh@37
|
293 else
|
stevenh@37
|
294 {
|
stevenh@37
|
295 System.out.println("Unknown MidiMessage type (" + midiMessage.getClass().toString() + ")");
|
stevenh@37
|
296 }
|
stevenh@37
|
297
|
stevenh@37
|
298 for (int byteIdx = 0; byteIdx < midiMessageLength; byteIdx++)
|
stevenh@37
|
299 {
|
stevenh@37
|
300 byte messageByte = messageBytes[byteIdx];
|
stevenh@37
|
301 System.out.println("\tbyte[" + byteIdx + "] = " + messageByte);
|
stevenh@37
|
302 }
|
stevenh@37
|
303 }
|
stevenh@37
|
304 }
|
stevenh@37
|
305
|
stevenh@37
|
306 System.out.println("done");
|
stevenh@37
|
307
|
stevenh@37
|
308 // Print out what we've got now
|
stevenh@37
|
309 System.out.println("------------------");
|
stevenh@37
|
310 StmtIterator stmtIterator = ontModel.listStatements();
|
stevenh@37
|
311 printStmts(stmtIterator);
|
stevenh@37
|
312
|
stevenh@46
|
313 // TODO write rdf to file
|
stevenh@37
|
314 File outFileRdf = new File(finalModelFileName + ".rdf");
|
stevenh@37
|
315 File outFileN3 = new File(finalModelFileName + ".n3");
|
stevenh@37
|
316 FileOutputStream outFileOutputStreamRdf = null;
|
stevenh@37
|
317 FileOutputStream outFileOutputStreamN3 = null;
|
stevenh@37
|
318
|
stevenh@37
|
319 // RDF/XML version
|
stevenh@37
|
320 try {
|
stevenh@37
|
321 outFileOutputStreamRdf = new FileOutputStream(outFileRdf);
|
stevenh@37
|
322 ontModel.writeAll(outFileOutputStreamRdf, "RDF/XML", null);
|
stevenh@37
|
323 } catch (FileNotFoundException e) {
|
stevenh@37
|
324 System.out.println("Unable to write to file: "
|
stevenh@37
|
325 + outFileRdf.getAbsolutePath());
|
stevenh@37
|
326 e.printStackTrace();
|
stevenh@37
|
327 System.exit(1);
|
stevenh@37
|
328 }
|
stevenh@37
|
329
|
stevenh@37
|
330 try {
|
stevenh@37
|
331 outFileOutputStreamRdf.close();
|
stevenh@37
|
332 } catch (IOException e1) {
|
stevenh@37
|
333 e1.printStackTrace();
|
stevenh@37
|
334 System.exit(1);
|
stevenh@37
|
335 }
|
stevenh@37
|
336
|
stevenh@37
|
337 // N3 version
|
stevenh@37
|
338 try {
|
stevenh@37
|
339 outFileOutputStreamN3 = new FileOutputStream(outFileN3);
|
stevenh@37
|
340 ontModel.writeAll(outFileOutputStreamN3, "N3", null);
|
stevenh@37
|
341 } catch (FileNotFoundException e) {
|
stevenh@37
|
342 System.out.println("Unable to write to file: "
|
stevenh@37
|
343 + outFileN3.getAbsolutePath());
|
stevenh@37
|
344 e.printStackTrace();
|
stevenh@37
|
345 System.exit(1);
|
stevenh@37
|
346 }
|
stevenh@37
|
347
|
stevenh@37
|
348 try {
|
stevenh@37
|
349 outFileOutputStreamN3.close();
|
stevenh@37
|
350 } catch (IOException e1) {
|
stevenh@37
|
351 e1.printStackTrace();
|
stevenh@37
|
352 System.exit(1);
|
stevenh@37
|
353 }
|
stevenh@37
|
354
|
stevenh@37
|
355 System.out.println("Model written to files: "
|
stevenh@37
|
356 + outFileRdf.getAbsolutePath() + " and " + outFileN3.getAbsolutePath());
|
stevenh@37
|
357
|
stevenh@46
|
358 // Obtain a dataset context
|
stevenh@46
|
359 Dataset dataset = TDBFactory.assembleDataset(SiaMain.assemblerFile);
|
stevenh@46
|
360 dataset.begin(ReadWrite.WRITE) ;
|
stevenh@46
|
361 try {
|
stevenh@46
|
362 dataset.replaceNamedModel(SiaMain.graph, ontModel);
|
stevenh@46
|
363 dataset.commit();
|
stevenh@46
|
364 System.out.println("dataset.commit() done");
|
stevenh@46
|
365 } finally {
|
stevenh@46
|
366 dataset.end();
|
stevenh@46
|
367 System.out.println("dataset.end() done");
|
stevenh@46
|
368 }
|
stevenh@46
|
369 dataset.close();
|
stevenh@46
|
370 System.out.println("dataset.close() done");
|
stevenh@46
|
371
|
stevenh@46
|
372 System.out.println("max tick: " + maxTick);
|
stevenh@46
|
373 System.out.println("Number of Datapoints (n) = " + datapoints.size());
|
stevenh@37
|
374
|
stevenh@37
|
375 }
|
stevenh@37
|
376
|
stevenh@37
|
377 private static HashMap<Integer, Integer> getTrackToDimensionIndexMap(Sequence sequence) {
|
stevenh@37
|
378
|
stevenh@37
|
379 int numTracks = sequence.getTracks().length;
|
stevenh@37
|
380 int siaDatapointDimension = 2; // Dimension 1 is reserved for time
|
stevenh@37
|
381
|
stevenh@37
|
382 HashMap<Integer, Integer> trackDimensionMap = new HashMap<Integer, Integer>();
|
stevenh@37
|
383 Track[] tracks = sequence.getTracks();
|
stevenh@37
|
384
|
stevenh@37
|
385 for (int trackIdx = 0; trackIdx < numTracks; trackIdx++)
|
stevenh@37
|
386 {
|
stevenh@37
|
387 boolean trackIsAudible = false;
|
stevenh@37
|
388 int numEvents = tracks[trackIdx].size();
|
stevenh@37
|
389
|
stevenh@37
|
390 for (int eventIdx = 0; eventIdx < numEvents; eventIdx++)
|
stevenh@37
|
391 {
|
stevenh@37
|
392 MidiEvent event = tracks[trackIdx].get(eventIdx);
|
stevenh@37
|
393 MidiMessage midiMessage = event.getMessage();
|
stevenh@37
|
394
|
stevenh@37
|
395 // Determine the type of this message (short, sysex or meta)
|
stevenh@37
|
396 if (midiMessage instanceof ShortMessage)
|
stevenh@37
|
397 {
|
stevenh@37
|
398 // Determine which command is being issued
|
stevenh@37
|
399 ShortMessage shortMessage = (ShortMessage)midiMessage;
|
stevenh@37
|
400 int messageCommand = shortMessage.getCommand();
|
stevenh@37
|
401
|
stevenh@37
|
402 if (messageCommand == ShortMessage.NOTE_ON)
|
stevenh@37
|
403 {
|
stevenh@37
|
404 trackIsAudible = true;
|
stevenh@37
|
405 break;
|
stevenh@37
|
406 }
|
stevenh@37
|
407 }
|
stevenh@37
|
408 }
|
stevenh@37
|
409
|
stevenh@37
|
410 if (trackIsAudible)
|
stevenh@37
|
411 {
|
stevenh@37
|
412 trackDimensionMap.put(trackIdx, siaDatapointDimension);
|
stevenh@37
|
413 siaDatapointDimension++;
|
stevenh@37
|
414 }
|
stevenh@37
|
415 }
|
stevenh@37
|
416
|
stevenh@37
|
417 return trackDimensionMap;
|
stevenh@37
|
418 }
|
stevenh@37
|
419
|
stevenh@37
|
420 private static void printStmts(StmtIterator iter) {
|
stevenh@37
|
421 Statement statement;
|
stevenh@37
|
422
|
stevenh@37
|
423 while (iter.hasNext()) {
|
stevenh@37
|
424 statement = iter.nextStatement();
|
stevenh@37
|
425 System.out.println(" | <" + statement.getSubject() + "> | <"
|
stevenh@37
|
426 + statement.getPredicate() + "> | <"
|
stevenh@37
|
427 + statement.getObject() + "> | ");
|
stevenh@37
|
428 }
|
stevenh@37
|
429
|
stevenh@37
|
430 // And an empty line to make it pretty
|
stevenh@37
|
431 System.out.println();
|
stevenh@37
|
432 }
|
stevenh@37
|
433 }
|