annotate src/org/qmul/eecs/c4dm/sia/midi/MidiParser.java @ 83:4ef262740ceb

can be run with a specified maximum number of Datapoints and for a specified midiFileName
author stevenh
date Fri, 30 Aug 2013 16:12:28 +0100
parents 39106212a3c6
children
rev   line source
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.HashMap;
stevenh@37 9 import java.util.List;
stevenh@37 10 import java.util.Vector;
stevenh@37 11
stevenh@37 12 import javax.sound.midi.InvalidMidiDataException;
stevenh@37 13 import javax.sound.midi.MetaMessage;
stevenh@37 14 import javax.sound.midi.MidiEvent;
stevenh@37 15 import javax.sound.midi.MidiMessage;
stevenh@37 16 import javax.sound.midi.MidiSystem;
stevenh@37 17 import javax.sound.midi.Sequence;
stevenh@37 18 import javax.sound.midi.ShortMessage;
stevenh@37 19 import javax.sound.midi.SysexMessage;
stevenh@37 20 import javax.sound.midi.Track;
stevenh@37 21
stevenh@46 22 import org.qmul.eecs.c4dm.sia.SiaMain;
stevenh@37 23 import org.qmul.eecs.c4dm.sia.model.Datapoint;
stevenh@37 24 import org.qmul.eecs.c4dm.sia.model.DimensionValue;
stevenh@71 25 import org.qmul.eecs.c4dm.sia.model.MemberOfDataset;
stevenh@71 26 import org.qmul.eecs.c4dm.sia.model.SiaDataset;
stevenh@71 27 import org.qmul.eecs.c4dm.sia.model.SiaVector;
stevenh@37 28 import org.qmul.eecs.c4dm.sia.rdf.Namespaces;
stevenh@37 29
stevenh@71 30 import com.hp.hpl.jena.datatypes.xsd.XSDDatatype;
stevenh@71 31 import com.hp.hpl.jena.graph.Node;
stevenh@71 32 import com.hp.hpl.jena.graph.Triple;
stevenh@37 33 import com.hp.hpl.jena.ontology.OntClass;
stevenh@37 34 import com.hp.hpl.jena.ontology.OntModel;
stevenh@46 35 import com.hp.hpl.jena.query.Dataset;
stevenh@71 36 import com.hp.hpl.jena.query.Query;
stevenh@71 37 import com.hp.hpl.jena.query.QueryExecution;
stevenh@71 38 import com.hp.hpl.jena.query.QueryExecutionFactory;
stevenh@71 39 import com.hp.hpl.jena.query.QueryFactory;
stevenh@71 40 import com.hp.hpl.jena.query.QuerySolution;
stevenh@46 41 import com.hp.hpl.jena.query.ReadWrite;
stevenh@71 42 import com.hp.hpl.jena.query.ResultSet;
stevenh@37 43 import com.hp.hpl.jena.rdf.model.AnonId;
stevenh@37 44 import com.hp.hpl.jena.rdf.model.ModelFactory;
stevenh@37 45 import com.hp.hpl.jena.rdf.model.Property;
stevenh@37 46 import com.hp.hpl.jena.rdf.model.Resource;
stevenh@37 47 import com.hp.hpl.jena.rdf.model.Statement;
stevenh@37 48 import com.hp.hpl.jena.rdf.model.StmtIterator;
stevenh@71 49 import com.hp.hpl.jena.sparql.core.Var;
stevenh@71 50 import com.hp.hpl.jena.sparql.syntax.ElementGroup;
stevenh@71 51 import com.hp.hpl.jena.sparql.syntax.ElementTriplesBlock;
stevenh@46 52 import com.hp.hpl.jena.tdb.TDBFactory;
stevenh@37 53 import com.hp.hpl.jena.vocabulary.RDF;
stevenh@37 54 import com.sun.media.sound.MidiUtils;
stevenh@37 55
stevenh@37 56 public class MidiParser {
stevenh@37 57
stevenh@37 58 public static final int TIME_DIMENSION = 1;
stevenh@37 59 public static final int PITCH_DIMENSION = 2;
stevenh@37 60 public static final int CHANNEL_DIMENSION = 3;
stevenh@37 61
stevenh@71 62 private static Property siaDimValProperty;
stevenh@71 63 private static Property siaDimensionProperty;
stevenh@71 64 private static Property siaValueProperty;
stevenh@71 65 private static Property siaMemberOfDatasetProperty;
stevenh@71 66 private static OntClass datapointClass;
stevenh@71 67 private static OntClass datasetClass;
stevenh@71 68 private static OntClass siaVectorClass;
stevenh@71 69 private static Property siaVectorProperty;
stevenh@71 70
stevenh@37 71 // The ontology loaded as dataset
stevenh@37 72 private static final String ontology = "file:src/rdf/siaDatapointOntology.n3";
stevenh@37 73
stevenh@37 74 // The final output file
stevenh@37 75 private static final String finalModelFileName = "src/rdf/midiModel";
stevenh@37 76
stevenh@46 77 // The input midi file
stevenh@46 78 private static final String midiFileName = "/Volumes/USB_DISK/portable/ewerts/Cantata_16_no_5-mids/score.mid";
stevenh@46 79
stevenh@37 80 public static void main(String[] args)
stevenh@37 81 {
stevenh@83 82 MidiParser midiParser = new MidiParser();
stevenh@83 83 midiParser.midiToRdf(6, midiFileName);
stevenh@83 84 }
stevenh@83 85
stevenh@83 86 public void midiToRdf(int maxDatapoints, String midiFileName)
stevenh@83 87 {
stevenh@83 88 int numDatapoints = 0;
stevenh@83 89
stevenh@37 90 // First create a Jena ontology model
stevenh@71 91 OntModel model = ModelFactory
stevenh@37 92 .createOntologyModel(); // OntModelSpec.OWL_MEM
stevenh@37 93
stevenh@37 94 // Then read the data from the file into the ontology model
stevenh@71 95 model.read(ontology, "N3");
stevenh@37 96
stevenh@71 97 datapointClass = model.getOntClass(Datapoint.RESOURCE_URI);
stevenh@71 98 datasetClass = model.getOntClass(SiaDataset.RESOURCE_URI);
stevenh@71 99 siaVectorClass = model.getOntClass(SiaVector.RESOURCE_URI);
stevenh@71 100 Resource datapointResource = model.getOntResource(datapointClass);
stevenh@71 101 Resource datasetResource = model.getOntResource(datasetClass);
stevenh@71 102 siaDimValProperty = model.createProperty(DimensionValue.PROPERTY_URI);
stevenh@71 103 siaDimensionProperty = model.createProperty(DimensionValue.DIMENSION_URI);
stevenh@71 104 siaValueProperty = model.createProperty(DimensionValue.VALUE_URI);
stevenh@71 105 siaMemberOfDatasetProperty = model.createProperty(MemberOfDataset.PROPERTY_URI);
stevenh@71 106 siaVectorProperty = model.createProperty(SiaVector.PROPERTY_URI);
stevenh@71 107
stevenh@37 108 File midiFile1 = new File(midiFileName);
stevenh@37 109
stevenh@37 110 Sequence sequence = null;
stevenh@37 111 try {
stevenh@37 112 sequence = MidiSystem.getSequence(midiFile1);
stevenh@37 113 } catch (InvalidMidiDataException e) {
stevenh@37 114 e.printStackTrace();
stevenh@37 115 System.exit(1);
stevenh@37 116 } catch (IOException e) {
stevenh@37 117 e.printStackTrace();
stevenh@37 118 System.exit(1);
stevenh@37 119 }
stevenh@37 120
stevenh@37 121 MidiUtils.TempoCache tempoCache = new MidiUtils.TempoCache(sequence);
stevenh@37 122
stevenh@37 123 Track[] tracks = sequence.getTracks();
stevenh@37 124 int numTracks = tracks.length;
stevenh@37 125 float divisionType = sequence.getDivisionType();
stevenh@37 126 List<Datapoint> datapoints = new ArrayList<Datapoint>();
stevenh@37 127
stevenh@37 128 HashMap<Integer, Integer> trackDimensionMap = getTrackToDimensionIndexMap(sequence);
stevenh@37 129
stevenh@37 130 if (trackDimensionMap.isEmpty())
stevenh@37 131 {
stevenh@37 132 try {
stevenh@37 133 throw new Exception("Couldn't find any track to dimension mappings");
stevenh@37 134 } catch (Exception e) {
stevenh@37 135 e.printStackTrace();
stevenh@37 136 System.exit(1);
stevenh@37 137 }
stevenh@37 138 }
stevenh@37 139
stevenh@71 140 // Add a dataset, represented by a blank node, to the model
stevenh@71 141 Resource datasetBnode = model.createResource(AnonId.create());
stevenh@71 142 model.add(datasetBnode, RDF.type, datasetResource);
stevenh@71 143
stevenh@37 144 long maxTick = 0;
stevenh@37 145
stevenh@37 146 for (int trackIdx = 0; trackIdx < numTracks; trackIdx++)
stevenh@37 147 {
stevenh@37 148 System.out.println("Track " + trackIdx + ":");
stevenh@37 149 int numEvents = tracks[trackIdx].size();
stevenh@37 150 for (int eventIdx = 0; eventIdx < numEvents; eventIdx++)
stevenh@37 151 {
stevenh@37 152 MidiEvent event = tracks[trackIdx].get(eventIdx);
stevenh@37 153 long tick = event.getTick();
stevenh@37 154 MidiMessage midiMessage = event.getMessage();
stevenh@37 155
stevenh@37 156 int midiMessageLength = midiMessage.getLength();
stevenh@37 157 byte[] messageBytes = midiMessage.getMessage();
stevenh@37 158 int status = midiMessage.getStatus();
stevenh@37 159 System.out.println("tick = " + tick + " midiMessageLength = " + midiMessageLength + " status byte = " + status);
stevenh@37 160
stevenh@37 161 int s = status & 0x80;
stevenh@37 162 if (s == 0x80)
stevenh@37 163 {
stevenh@37 164 System.out.println("STATUS MESSAGE (s = " + s + ")");
stevenh@37 165 }
stevenh@37 166 else
stevenh@37 167 {
stevenh@37 168 System.out.println("not a status message (s = " + s + ")");
stevenh@37 169 }
stevenh@37 170
stevenh@37 171 // Determine the type of this message (short, sysex or meta)
stevenh@37 172 if (midiMessage instanceof ShortMessage)
stevenh@37 173 {
stevenh@37 174 System.out.print("ShortMessage ");
stevenh@37 175
stevenh@37 176 // Determine which command is being issued
stevenh@37 177 ShortMessage shortMessage = (ShortMessage)midiMessage;
stevenh@37 178 int messageCommand = shortMessage.getCommand();
stevenh@37 179 int channel = shortMessage.getChannel();
stevenh@37 180 int data1 = shortMessage.getData1();
stevenh@37 181 int data2 = shortMessage.getData2();
stevenh@37 182
stevenh@37 183 if (messageCommand == ShortMessage.ACTIVE_SENSING)
stevenh@37 184 {
stevenh@37 185 System.out.print("ignoring ACTIVE_SENSING");
stevenh@37 186 }
stevenh@37 187 else if (messageCommand == ShortMessage.CHANNEL_PRESSURE)
stevenh@37 188 {
stevenh@37 189 System.out.print("ignoring CHANNEL_PRESSURE");
stevenh@37 190 }
stevenh@37 191 else if (messageCommand == ShortMessage.CONTINUE)
stevenh@37 192 {
stevenh@37 193 System.out.print("ignoring CONTINUE");
stevenh@37 194 }
stevenh@37 195 else if (messageCommand == ShortMessage.CONTROL_CHANGE)
stevenh@37 196 {
stevenh@37 197 System.out.print("ignoring CONTROL_CHANGE");
stevenh@37 198 }
stevenh@37 199 else if (messageCommand == ShortMessage.END_OF_EXCLUSIVE)
stevenh@37 200 {
stevenh@37 201 System.out.print("ignoring END_OF_EXCLUSIVE");
stevenh@37 202 }
stevenh@37 203 else if (messageCommand == ShortMessage.MIDI_TIME_CODE)
stevenh@37 204 {
stevenh@37 205 System.out.print("ignoring MIDI_TIME_CODE");
stevenh@37 206 }
stevenh@37 207 else if (messageCommand == ShortMessage.NOTE_OFF)
stevenh@37 208 {
stevenh@37 209 System.out.println("NOTE_OFF");
stevenh@37 210 long microsecs = MidiUtils.tick2microsecond(sequence, tick, tempoCache);
stevenh@37 211 System.out.println(" microsecs = " + microsecs);
stevenh@37 212 }
stevenh@37 213 else if (messageCommand == ShortMessage.NOTE_ON)
stevenh@37 214 {
stevenh@37 215 if (tick > maxTick)
stevenh@37 216 {
stevenh@37 217 maxTick = tick;
stevenh@37 218 }
stevenh@37 219 System.out.println("NOTE_ON");
stevenh@46 220 double microsecs = MidiUtils.tick2microsecond(sequence, tick, tempoCache);
stevenh@46 221 double secs = microsecs/1000000;
stevenh@46 222 System.out.println(" microsecs = " + secs);
stevenh@37 223
stevenh@37 224 DimensionValue timeDimVal = new DimensionValue();
stevenh@37 225 timeDimVal.setDimension(TIME_DIMENSION);
stevenh@46 226 timeDimVal.setValue(secs);
stevenh@37 227
stevenh@46 228 DimensionValue pitchDimVal = new DimensionValue();
stevenh@46 229 pitchDimVal.setDimension(PITCH_DIMENSION);
stevenh@46 230 pitchDimVal.setValue(data1);
stevenh@37 231
stevenh@46 232 DimensionValue channelDimVal = new DimensionValue();
stevenh@46 233 channelDimVal.setDimension(CHANNEL_DIMENSION);
stevenh@46 234 channelDimVal.setValue(trackDimensionMap.get(trackIdx));
stevenh@46 235
stevenh@37 236 Datapoint datapoint = new Datapoint();
stevenh@37 237 Vector<DimensionValue> dimVals = new Vector<DimensionValue>();
stevenh@37 238 dimVals.add(timeDimVal);
stevenh@46 239 dimVals.add(pitchDimVal);
stevenh@46 240 dimVals.add(channelDimVal);
stevenh@37 241
stevenh@37 242 datapoint.setDimensionValues(dimVals);
stevenh@37 243
stevenh@83 244 if (numDatapoints < maxDatapoints)
stevenh@83 245 {
stevenh@83 246 datapoints.add(datapoint);
stevenh@83 247 numDatapoints++;
stevenh@71 248
stevenh@83 249 // RDF
stevenh@83 250 Resource datapointBnode = model.createResource(AnonId.create());
stevenh@83 251 model.add(datapointBnode, RDF.type, datapointResource);
stevenh@83 252
stevenh@83 253 // Find or create a DimVal for the TIME dimension
stevenh@83 254 Resource timeDimValBnode = findOrCreateDimValBNode(model, TIME_DIMENSION, secs);
stevenh@83 255
stevenh@83 256 // Find or create a DimVal for the PITCH dimension
stevenh@83 257 Resource pitchDimValBnode = findOrCreateDimValBNode(model, PITCH_DIMENSION, data1);
stevenh@83 258
stevenh@83 259 // Find or create a DimVal for the CHANNEL dimension
stevenh@83 260 Resource channelDimValBnode = findOrCreateDimValBNode(model, CHANNEL_DIMENSION, trackDimensionMap.get(trackIdx));
stevenh@83 261
stevenh@83 262 // Find or create a Vector for these three DimVals
stevenh@83 263 Resource vectorBnode = findOrCreateVectorBNode(model, timeDimValBnode, secs,
stevenh@83 264 pitchDimValBnode, data1, channelDimValBnode, trackDimensionMap.get(trackIdx));
stevenh@83 265
stevenh@83 266 model.add(datapointBnode, siaVectorProperty, vectorBnode);
stevenh@83 267 model.add(datapointBnode, siaMemberOfDatasetProperty, datasetBnode);
stevenh@83 268 }
stevenh@46 269
stevenh@37 270 }
stevenh@37 271 else if (messageCommand == ShortMessage.PITCH_BEND)
stevenh@37 272 {
stevenh@37 273 System.out.print("ignoring PITCH_BEND");
stevenh@37 274 }
stevenh@37 275 else if (messageCommand == ShortMessage.POLY_PRESSURE)
stevenh@37 276 {
stevenh@37 277 System.out.print("ignoring POLY_PRESSURE");
stevenh@37 278 }
stevenh@37 279 else if (messageCommand == ShortMessage.PROGRAM_CHANGE)
stevenh@37 280 {
stevenh@37 281 System.out.print("ignoring PROGRAM_CHANGE");
stevenh@37 282 }
stevenh@37 283 else if (messageCommand == ShortMessage.SONG_POSITION_POINTER)
stevenh@37 284 {
stevenh@37 285 System.out.print("ignoring SONG_POSITION_POINTER");
stevenh@37 286 }
stevenh@37 287 else
stevenh@37 288 {
stevenh@37 289 System.out.print("unrecognised midi message command (" + messageCommand + ")");
stevenh@37 290 }
stevenh@37 291 System.out.print(", channel " + channel + ", data1 = [" + data1 + "], data2 = [" + data2 + "]");
stevenh@37 292 System.out.println();
stevenh@37 293 }
stevenh@37 294 else if (midiMessage instanceof MetaMessage)
stevenh@37 295 {
stevenh@37 296 System.out.println("MetaMessage");
stevenh@37 297
stevenh@37 298 MetaMessage metaMessage = (MetaMessage)midiMessage;
stevenh@37 299 byte[] metaMessageData = metaMessage.getData();
stevenh@37 300 int metaMessageLength = metaMessage.getLength();
stevenh@37 301 int metaMessageType = metaMessage.getType();
stevenh@37 302 System.out.println("metaMessageType = " + metaMessageType + ", metaMessageLength = " + metaMessageLength);
stevenh@37 303
stevenh@37 304 // Determine message type
stevenh@37 305 if (metaMessageType == 81)
stevenh@37 306 {
stevenh@37 307 if (divisionType == Sequence.PPQ)
stevenh@37 308 {
stevenh@37 309 // Do nothing - we've dealt with PPQ tempo data elsewhere
stevenh@37 310 }
stevenh@37 311 else
stevenh@37 312 {
stevenh@37 313 try {
stevenh@37 314 throw new Exception("Not yet implemented SMPTE tempo metadata");
stevenh@37 315 } catch (Exception e) {
stevenh@37 316 e.printStackTrace();
stevenh@37 317 System.exit(1);
stevenh@37 318 }
stevenh@37 319 }
stevenh@37 320 }
stevenh@37 321
stevenh@37 322 for (int dataIdx = 0; dataIdx < metaMessageData.length; dataIdx++)
stevenh@37 323 {
stevenh@37 324 System.out.println("\tmetaMessageData[" + dataIdx + "] = " + (metaMessageType == 81 ? metaMessageData[dataIdx] : (char)metaMessageData[dataIdx]));
stevenh@37 325 }
stevenh@37 326
stevenh@37 327 }
stevenh@37 328 else if (midiMessage instanceof SysexMessage)
stevenh@37 329 {
stevenh@37 330 // We can safely ignore these messages
stevenh@37 331 System.out.println("ignoring SysexMessage");
stevenh@37 332 }
stevenh@37 333 else
stevenh@37 334 {
stevenh@37 335 System.out.println("Unknown MidiMessage type (" + midiMessage.getClass().toString() + ")");
stevenh@37 336 }
stevenh@37 337
stevenh@37 338 for (int byteIdx = 0; byteIdx < midiMessageLength; byteIdx++)
stevenh@37 339 {
stevenh@37 340 byte messageByte = messageBytes[byteIdx];
stevenh@37 341 System.out.println("\tbyte[" + byteIdx + "] = " + messageByte);
stevenh@37 342 }
stevenh@37 343 }
stevenh@37 344 }
stevenh@37 345
stevenh@37 346 System.out.println("done");
stevenh@37 347
stevenh@37 348 // Print out what we've got now
stevenh@37 349 System.out.println("------------------");
stevenh@71 350 StmtIterator stmtIterator = model.listStatements();
stevenh@37 351 printStmts(stmtIterator);
stevenh@37 352
stevenh@46 353 // TODO write rdf to file
stevenh@37 354 File outFileRdf = new File(finalModelFileName + ".rdf");
stevenh@37 355 File outFileN3 = new File(finalModelFileName + ".n3");
stevenh@37 356 FileOutputStream outFileOutputStreamRdf = null;
stevenh@37 357 FileOutputStream outFileOutputStreamN3 = null;
stevenh@37 358
stevenh@37 359 // RDF/XML version
stevenh@37 360 try {
stevenh@37 361 outFileOutputStreamRdf = new FileOutputStream(outFileRdf);
stevenh@71 362 model.writeAll(outFileOutputStreamRdf, "RDF/XML", null);
stevenh@37 363 } catch (FileNotFoundException e) {
stevenh@37 364 System.out.println("Unable to write to file: "
stevenh@37 365 + outFileRdf.getAbsolutePath());
stevenh@37 366 e.printStackTrace();
stevenh@37 367 System.exit(1);
stevenh@37 368 }
stevenh@37 369
stevenh@37 370 try {
stevenh@37 371 outFileOutputStreamRdf.close();
stevenh@37 372 } catch (IOException e1) {
stevenh@37 373 e1.printStackTrace();
stevenh@37 374 System.exit(1);
stevenh@37 375 }
stevenh@37 376
stevenh@37 377 // N3 version
stevenh@37 378 try {
stevenh@37 379 outFileOutputStreamN3 = new FileOutputStream(outFileN3);
stevenh@71 380 model.writeAll(outFileOutputStreamN3, "N3", null);
stevenh@37 381 } catch (FileNotFoundException e) {
stevenh@37 382 System.out.println("Unable to write to file: "
stevenh@37 383 + outFileN3.getAbsolutePath());
stevenh@37 384 e.printStackTrace();
stevenh@37 385 System.exit(1);
stevenh@37 386 }
stevenh@37 387
stevenh@37 388 try {
stevenh@37 389 outFileOutputStreamN3.close();
stevenh@37 390 } catch (IOException e1) {
stevenh@37 391 e1.printStackTrace();
stevenh@37 392 System.exit(1);
stevenh@37 393 }
stevenh@37 394
stevenh@37 395 System.out.println("Model written to files: "
stevenh@37 396 + outFileRdf.getAbsolutePath() + " and " + outFileN3.getAbsolutePath());
stevenh@37 397
stevenh@46 398 // Obtain a dataset context
stevenh@46 399 Dataset dataset = TDBFactory.assembleDataset(SiaMain.assemblerFile);
stevenh@46 400 dataset.begin(ReadWrite.WRITE) ;
stevenh@46 401 try {
stevenh@71 402 dataset.replaceNamedModel(SiaMain.graph, model);
stevenh@46 403 dataset.commit();
stevenh@46 404 System.out.println("dataset.commit() done");
stevenh@46 405 } finally {
stevenh@46 406 dataset.end();
stevenh@46 407 System.out.println("dataset.end() done");
stevenh@46 408 }
stevenh@46 409 dataset.close();
stevenh@46 410 System.out.println("dataset.close() done");
stevenh@46 411
stevenh@46 412 System.out.println("max tick: " + maxTick);
stevenh@46 413 System.out.println("Number of Datapoints (n) = " + datapoints.size());
stevenh@37 414
stevenh@37 415 }
stevenh@37 416
stevenh@71 417 private static Resource findOrCreateVectorBNode(OntModel model, Resource timeDimValBnode,
stevenh@71 418 double timeVal, Resource pitchDimValBnode, double pitchVal, Resource channelDimValBnode,
stevenh@71 419 double channelVal) {
stevenh@71 420
stevenh@71 421 Resource bnode;
stevenh@71 422
stevenh@71 423 String vectorVarStr = "vector";
stevenh@71 424 String dimVal1VarStr = "dimVal1";
stevenh@71 425 String dimVal2VarStr = "dimVal2";
stevenh@71 426 String dimVal3VarStr = "dimVal3";
stevenh@71 427
stevenh@71 428 Var vectorVar = Var.alloc(vectorVarStr);
stevenh@71 429 Var dimVal1Var = Var.alloc(dimVal1VarStr);
stevenh@71 430 Var dimVal2Var = Var.alloc(dimVal2VarStr);
stevenh@71 431 Var dimVal3Var = Var.alloc(dimVal3VarStr);
stevenh@71 432
stevenh@71 433 Node timeDimensionLiteralNode = Node.createUncachedLiteral(TIME_DIMENSION, XSDDatatype.XSDinteger);
stevenh@71 434 Node timeValueLiteralNode = Node.createUncachedLiteral(timeVal, XSDDatatype.XSDdouble);
stevenh@71 435 Node pitchDimensionLiteralNode = Node.createUncachedLiteral(PITCH_DIMENSION, XSDDatatype.XSDinteger);
stevenh@71 436 Node pitchValueLiteralNode = Node.createUncachedLiteral(pitchVal, XSDDatatype.XSDdouble);
stevenh@71 437 Node channelDimensionLiteralNode = Node.createUncachedLiteral(CHANNEL_DIMENSION, XSDDatatype.XSDinteger);
stevenh@71 438 Node channelValueLiteralNode = Node.createUncachedLiteral(channelVal, XSDDatatype.XSDdouble);
stevenh@71 439
stevenh@71 440 Query query = QueryFactory.make();
stevenh@71 441 query.setPrefix("sia", Namespaces.SIA_NS_URI);
stevenh@71 442 query.setQuerySelectType();
stevenh@71 443 query.setDistinct(true);
stevenh@71 444 query.addResultVar(vectorVar);
stevenh@71 445
stevenh@71 446 ElementTriplesBlock etp = new ElementTriplesBlock();
stevenh@71 447
stevenh@71 448 Triple vectorTriple = new Triple(vectorVar, RDF.type.asNode(), siaVectorClass.asNode());
stevenh@71 449 Triple dimVal1Triple = new Triple(vectorVar, siaDimValProperty.asNode(), dimVal1Var);
stevenh@71 450
stevenh@71 451 Triple dimVal1DimTriple = new Triple(dimVal1Var, siaDimensionProperty.asNode(), timeDimensionLiteralNode);
stevenh@71 452 Triple dimVal1ValTriple = new Triple(dimVal1Var, siaValueProperty.asNode(), timeValueLiteralNode);
stevenh@71 453 Triple dimVal2Triple = new Triple(vectorVar, siaDimValProperty.asNode(), dimVal2Var);
stevenh@71 454 Triple dimVal2DimTriple = new Triple(dimVal2Var, siaDimensionProperty.asNode(), pitchDimensionLiteralNode);
stevenh@71 455 Triple dimVal2ValTriple = new Triple(dimVal2Var, siaValueProperty.asNode(), pitchValueLiteralNode);
stevenh@71 456 Triple dimVal3Triple = new Triple(vectorVar, siaDimValProperty.asNode(), dimVal3Var);
stevenh@71 457 Triple dimVal3DimTriple = new Triple(dimVal3Var, siaDimensionProperty.asNode(), channelDimensionLiteralNode);
stevenh@71 458 Triple dimVal3ValTriple = new Triple(dimVal3Var, siaValueProperty.asNode(), channelValueLiteralNode);
stevenh@71 459
stevenh@71 460 etp.addTriple(vectorTriple);
stevenh@71 461 etp.addTriple(dimVal1Triple);
stevenh@71 462 etp.addTriple(dimVal1DimTriple);
stevenh@71 463 etp.addTriple(dimVal1ValTriple);
stevenh@71 464 etp.addTriple(dimVal2Triple);
stevenh@71 465 etp.addTriple(dimVal2DimTriple);
stevenh@71 466 etp.addTriple(dimVal2ValTriple);
stevenh@71 467 etp.addTriple(dimVal3Triple);
stevenh@71 468 etp.addTriple(dimVal3DimTriple);
stevenh@71 469 etp.addTriple(dimVal3ValTriple);
stevenh@71 470
stevenh@71 471 ElementGroup body = new ElementGroup();
stevenh@71 472 body.addElement(etp);
stevenh@71 473 query.setQueryPattern(body);
stevenh@71 474
stevenh@71 475 QueryExecution qe = QueryExecutionFactory.create(query, model);
stevenh@71 476 ResultSet rs = qe.execSelect();
stevenh@71 477
stevenh@71 478 if (rs.hasNext())
stevenh@71 479 {
stevenh@71 480 QuerySolution querySolution = rs.next();
stevenh@71 481 bnode = querySolution.get(vectorVarStr).asResource();
stevenh@71 482 }
stevenh@71 483 else
stevenh@71 484 {
stevenh@71 485 bnode = model.createResource(AnonId.create());
stevenh@71 486 model.add(bnode, RDF.type, siaVectorClass);
stevenh@71 487 model.add(bnode, siaDimValProperty, timeDimValBnode);
stevenh@71 488 model.add(bnode, siaDimValProperty, pitchDimValBnode);
stevenh@71 489 model.add(bnode, siaDimValProperty, channelDimValBnode);
stevenh@71 490 }
stevenh@71 491 return bnode;
stevenh@71 492 }
stevenh@71 493
stevenh@71 494 private static Resource findOrCreateDimValBNode(OntModel model, int dimension, double value) {
stevenh@71 495 Resource bnode;
stevenh@71 496
stevenh@71 497 String dimValVarStr = "dimVal";
stevenh@71 498 Var dimValVar = Var.alloc(dimValVarStr);
stevenh@71 499 Query query = QueryFactory.make();
stevenh@71 500 query.setPrefix("sia", Namespaces.SIA_NS_URI);
stevenh@71 501 query.setQuerySelectType();
stevenh@71 502 query.setDistinct(true);
stevenh@71 503 query.addResultVar(dimValVar);
stevenh@71 504 ElementTriplesBlock etp = new ElementTriplesBlock();
stevenh@71 505 Node dimensionLiteralNode = Node.createUncachedLiteral(dimension, XSDDatatype.XSDinteger);
stevenh@71 506 Node valueLiteralNode = Node.createUncachedLiteral(value, XSDDatatype.XSDdouble);
stevenh@71 507
stevenh@71 508 Triple dimensionTriple = new Triple(dimValVar, siaDimensionProperty.asNode(), dimensionLiteralNode);
stevenh@71 509 Triple valueTriple = new Triple(dimValVar, siaValueProperty.asNode(), valueLiteralNode);
stevenh@71 510 etp.addTriple(dimensionTriple);
stevenh@71 511 etp.addTriple(valueTriple);
stevenh@71 512 query.setQueryPattern(etp);
stevenh@71 513
stevenh@71 514 QueryExecution qe = QueryExecutionFactory.create(query, model);
stevenh@71 515 ResultSet rs = qe.execSelect();
stevenh@71 516
stevenh@71 517 if (rs.hasNext())
stevenh@71 518 {
stevenh@71 519 QuerySolution querySolution = rs.next();
stevenh@71 520 bnode = querySolution.get(dimValVarStr).asResource();
stevenh@71 521 }
stevenh@71 522 else
stevenh@71 523 {
stevenh@71 524 bnode = model.createResource(AnonId.create());
stevenh@71 525 model.addLiteral(bnode, siaDimensionProperty, dimension);
stevenh@71 526 model.addLiteral(bnode, siaValueProperty, value);
stevenh@71 527 }
stevenh@71 528 return bnode;
stevenh@71 529 }
stevenh@71 530
stevenh@37 531 private static HashMap<Integer, Integer> getTrackToDimensionIndexMap(Sequence sequence) {
stevenh@37 532
stevenh@37 533 int numTracks = sequence.getTracks().length;
stevenh@37 534 int siaDatapointDimension = 2; // Dimension 1 is reserved for time
stevenh@37 535
stevenh@37 536 HashMap<Integer, Integer> trackDimensionMap = new HashMap<Integer, Integer>();
stevenh@37 537 Track[] tracks = sequence.getTracks();
stevenh@37 538
stevenh@37 539 for (int trackIdx = 0; trackIdx < numTracks; trackIdx++)
stevenh@37 540 {
stevenh@37 541 boolean trackIsAudible = false;
stevenh@37 542 int numEvents = tracks[trackIdx].size();
stevenh@37 543
stevenh@37 544 for (int eventIdx = 0; eventIdx < numEvents; eventIdx++)
stevenh@37 545 {
stevenh@37 546 MidiEvent event = tracks[trackIdx].get(eventIdx);
stevenh@37 547 MidiMessage midiMessage = event.getMessage();
stevenh@37 548
stevenh@37 549 // Determine the type of this message (short, sysex or meta)
stevenh@37 550 if (midiMessage instanceof ShortMessage)
stevenh@37 551 {
stevenh@37 552 // Determine which command is being issued
stevenh@37 553 ShortMessage shortMessage = (ShortMessage)midiMessage;
stevenh@37 554 int messageCommand = shortMessage.getCommand();
stevenh@37 555
stevenh@37 556 if (messageCommand == ShortMessage.NOTE_ON)
stevenh@37 557 {
stevenh@37 558 trackIsAudible = true;
stevenh@37 559 break;
stevenh@37 560 }
stevenh@37 561 }
stevenh@37 562 }
stevenh@37 563
stevenh@37 564 if (trackIsAudible)
stevenh@37 565 {
stevenh@37 566 trackDimensionMap.put(trackIdx, siaDatapointDimension);
stevenh@37 567 siaDatapointDimension++;
stevenh@37 568 }
stevenh@37 569 }
stevenh@37 570
stevenh@37 571 return trackDimensionMap;
stevenh@37 572 }
stevenh@37 573
stevenh@37 574 private static void printStmts(StmtIterator iter) {
stevenh@37 575 Statement statement;
stevenh@37 576
stevenh@37 577 while (iter.hasNext()) {
stevenh@37 578 statement = iter.nextStatement();
stevenh@37 579 System.out.println(" | <" + statement.getSubject() + "> | <"
stevenh@37 580 + statement.getPredicate() + "> | <"
stevenh@37 581 + statement.getObject() + "> | ");
stevenh@37 582 }
stevenh@37 583
stevenh@37 584 // And an empty line to make it pretty
stevenh@37 585 System.out.println();
stevenh@37 586 }
stevenh@37 587 }