annotate jnmr/CannamMidiFileLoader.cpp @ 52:13194a9dca77 tip

Added exporting of image and text data
author Andrew N Robertson <andrew.robertson@eecs.qmul.ac.uk>
date Tue, 17 Jul 2012 22:13:10 +0100
parents 6cd3e0075adf
children
rev   line source
andrew@33 1 /*
andrew@33 2 * CannamMidiFileLoader.cpp
andrew@33 3 * midi-score-follower
andrew@33 4 *
andrew@33 5 * Created by Andrew on 19/08/2011.
andrew@33 6 * Copyright 2011 QMUL. All rights reserved.
andrew@33 7 *
andrew@33 8 */
andrew@33 9
andrew@33 10 #include "MIDIFileReader.h"
andrew@33 11 #include "CannamMidiFileLoader.h"
andrew@33 12
andrew@33 13 CannamMidiFileLoader::CannamMidiFileLoader(){
andrew@35 14 chopBeginning = false;
andrew@33 15 firstTickTime = 0;
andrew@34 16 printMidiInfo = false;
andrew@33 17 }
andrew@33 18
andrew@33 19 int CannamMidiFileLoader::loadFile(std::string& filename, midiEventHolder& myMidiEvents){
andrew@33 20
andrew@33 21 noteOnIndex = 0;
andrew@33 22 firstTickTime = 0;
andrew@33 23 myMidiEvents.clearAllEvents();
andrew@35 24 beatsPerMeasure = 4;
andrew@35 25 numberOfBeatsAtLastPosition = 0;
andrew@35 26 lastBeatPosition = 0;
andrew@35 27
andrew@33 28 setTempoFromMidiValue(500000, myMidiEvents);//default is 120bpm
andrew@34 29
andrew@33 30 myMidiEvents.pulsesPerQuarternote = 240;//default
andrew@33 31 //myMidiEvents.measureVector.push_back(0);
andrew@33 32 //int main(int argc, char **argv)
andrew@33 33 //{
andrew@33 34 // if (argc != 2) {
andrew@33 35 // cerr << "Usage: midifile <file.mid>" << endl;
andrew@33 36 // return 1;
andrew@33 37 // }
andrew@33 38
andrew@33 39 // std::string filename = midiFileName;//argv[1];
andrew@33 40
andrew@33 41 MIDIFileReader fr(filename);
andrew@33 42
andrew@33 43 if (!fr.isOK()) {
andrew@33 44 std::cerr << "Error: " << fr.getError().c_str() << std::endl;
andrew@33 45 return 1;
andrew@33 46 }
andrew@33 47
andrew@33 48 MIDIComposition c = fr.load();
andrew@33 49
andrew@33 50 switch (fr.getFormat()) {
andrew@33 51 case MIDI_SINGLE_TRACK_FILE: cout << "Format: MIDI Single Track File" << endl; break;
andrew@33 52 case MIDI_SIMULTANEOUS_TRACK_FILE: cout << "Format: MIDI Simultaneous Track File" << endl; break;
andrew@33 53 case MIDI_SEQUENTIAL_TRACK_FILE: cout << "Format: MIDI Sequential Track File" << endl; break;
andrew@33 54 default: cout << "Format: Unknown MIDI file format?" << endl; break;
andrew@33 55 }
andrew@33 56
andrew@33 57 cout << "Tracks: " << c.size() << endl;
andrew@33 58
andrew@33 59 int td = fr.getTimingDivision();
andrew@33 60 if (td < 32768) {
andrew@33 61 if (printMidiInfo)
andrew@33 62 cout << "Timing division: " << fr.getTimingDivision() << " ppq" << endl;
andrew@33 63 myMidiEvents.pulsesPerQuarternote = fr.getTimingDivision();
andrew@33 64 ticksPerMeasure = myMidiEvents.pulsesPerQuarternote * 4;//default setting
andrew@33 65
andrew@33 66 } else {
andrew@33 67 int frames = 256 - (td >> 8);
andrew@33 68 int subframes = td & 0xff;
andrew@33 69 if (printMidiInfo)
andrew@33 70 cout << "SMPTE timing: " << frames << " fps, " << subframes << " subframes" << endl;
andrew@33 71 }
andrew@33 72
andrew@33 73 for (MIDIComposition::const_iterator i = c.begin(); i != c.end(); ++i) {
andrew@33 74 if (printMidiInfo)
andrew@33 75 cout << "Start of track: " << i->first+1 << endl;
andrew@33 76
andrew@33 77 for (MIDITrack::const_iterator j = i->second.begin(); j != i->second.end(); ++j) {
andrew@33 78
andrew@33 79 unsigned int t = j->getTime();
andrew@33 80 int ch = j->getChannelNumber();
andrew@33 81
andrew@33 82 if (j->isMeta()) {
andrew@33 83 int code = j->getMetaEventCode();
andrew@33 84 string name;
andrew@33 85 bool printable = true;
andrew@33 86 switch (code) {
andrew@33 87
andrew@33 88 case MIDI_END_OF_TRACK:
andrew@33 89 cout << t << ": End of track" << endl;
andrew@33 90 break;
andrew@33 91
andrew@33 92 case MIDI_TEXT_EVENT: name = "Text"; break;
andrew@33 93 case MIDI_COPYRIGHT_NOTICE: name = "Copyright"; break;
andrew@33 94 case MIDI_TRACK_NAME: name = "Track name"; break;
andrew@33 95 case MIDI_INSTRUMENT_NAME: name = "Instrument name"; break;
andrew@33 96 case MIDI_LYRIC: name = "Lyric"; break;
andrew@33 97 case MIDI_TEXT_MARKER: name = "Text marker"; break;
andrew@33 98 case MIDI_SEQUENCE_NUMBER: name = "Sequence number"; printable = false; break;
andrew@33 99 case MIDI_CHANNEL_PREFIX_OR_PORT: name = "Channel prefix or port"; printable = false; break;
andrew@33 100 case MIDI_CUE_POINT: name = "Cue point"; break;
andrew@33 101 case MIDI_CHANNEL_PREFIX: name = "Channel prefix"; printable = false; break;
andrew@33 102 case MIDI_SEQUENCER_SPECIFIC: name = "Sequencer specific"; printable = false; break;
andrew@33 103 case MIDI_SMPTE_OFFSET: name = "SMPTE offset"; printable = false; break;
andrew@33 104
andrew@33 105 case MIDI_SET_TEMPO:
andrew@33 106 {
andrew@33 107 int m0 = j->getMetaMessage()[0];
andrew@33 108 int m1 = j->getMetaMessage()[1];
andrew@33 109 int m2 = j->getMetaMessage()[2];
andrew@33 110 long tempo = (((m0 << 8) + m1) << 8) + m2;
andrew@33 111 //if (printMidiInfo)
andrew@33 112 cout << t << ": Tempo: " << 60000000.0 / double(tempo) << endl;
andrew@34 113 //setTempoFromMidiValue(tempo, myMidiEvents);
andrew@33 114 DoubleVector tmp;
andrew@33 115
andrew@34 116 /*
andrew@33 117 double lastTickInMillis = 0;
andrew@33 118 double millisTimeNow = lastTickInMillis;
andrew@33 119 int tickInterval = 0;
andrew@33 120 if (myMidiEvents.periodValues.size() > 0){
andrew@33 121 lastTickInMillis = myMidiEvents.periodValues[myMidiEvents.periodValues.size()-1][2];
andrew@33 122 tickInterval = (t - firstTickTime) - myMidiEvents.periodValues[myMidiEvents.periodValues.size()-1][0];
andrew@33 123 millisTimeNow = lastTickInMillis + (myMidiEvents.periodValues[myMidiEvents.periodValues.size()-1][1]*tickInterval);
andrew@33 124
andrew@33 125 }
andrew@33 126
andrew@33 127 if (!chopBeginning)
andrew@33 128 tmp.push_back(t);
andrew@33 129 else
andrew@33 130 tmp.push_back(t - firstTickTime);
andrew@33 131
andrew@33 132 tmp.push_back(60000000.0 / double(tempo));
andrew@33 133 tmp.push_back(millisTimeNow);
andrew@33 134 myMidiEvents.periodValues.push_back(tmp);
andrew@34 135 */
andrew@33 136
andrew@34 137 double lastTickInMillis = 0;
andrew@34 138 double millisTimeNow = lastTickInMillis;
andrew@34 139 int tickInterval = 0;
andrew@34 140 if (myMidiEvents.periodValues.size() > 0){
andrew@34 141 lastTickInMillis = myMidiEvents.periodValues[myMidiEvents.periodValues.size()-1][2];
andrew@34 142 tickInterval = t - myMidiEvents.periodValues[myMidiEvents.periodValues.size()-1][0];
andrew@34 143 millisTimeNow = lastTickInMillis + (myMidiEvents.periodValues[myMidiEvents.periodValues.size()-1][1]*tickInterval);
andrew@34 144
andrew@34 145 }
andrew@34 146
andrew@34 147 tmp.push_back(t);
andrew@34 148
andrew@34 149
andrew@34 150 tmp.push_back(60000000.0 / double(tempo));
andrew@34 151 double tmpTempoVal = 60000000.0 / double(tempo);
andrew@34 152 tmp.push_back(millisTimeNow);
andrew@34 153 //if (tmpTempoVal > 180.0)
andrew@34 154 myMidiEvents.periodValues.push_back(tmp);
andrew@34 155
andrew@34 156 printf("tick[%i]: TEMPO %d tempoVal %f : time now %f\n", t, tempo, tmpTempoVal, millisTimeNow);
andrew@33 157 //printf("period double is %f\n", myMidiEvents.period);
andrew@33 158
andrew@33 159 }
andrew@33 160 break;
andrew@33 161
andrew@33 162 case MIDI_TIME_SIGNATURE:
andrew@33 163 {
andrew@33 164 int numerator = j->getMetaMessage()[0];
andrew@33 165 int denominator = 1 << (int)j->getMetaMessage()[1];
andrew@33 166
andrew@33 167 newTimeSignature(t, numerator, denominator, myMidiEvents);
andrew@33 168
andrew@33 169 //if (printMidiInfo)
andrew@33 170 cout << t << ": Time signature: " << numerator << "/" << denominator << endl;
andrew@33 171 printf(" ticks %i Time signature: %i by %i \n", t, numerator , denominator );
andrew@33 172 }
andrew@33 173
andrew@33 174 case MIDI_KEY_SIGNATURE:
andrew@33 175 {
andrew@33 176 int accidentals = j->getMetaMessage()[0];
andrew@33 177 int isMinor = j->getMetaMessage()[1];
andrew@33 178 bool isSharp = accidentals < 0 ? false : true;
andrew@33 179 accidentals = accidentals < 0 ? -accidentals : accidentals;
andrew@33 180 if (printMidiInfo)
andrew@33 181 cout << t << ": Key signature: " << accidentals << " "
andrew@33 182 << (isSharp ?
andrew@33 183 (accidentals > 1 ? "sharps" : "sharp") :
andrew@33 184 (accidentals > 1 ? "flats" : "flat"))
andrew@33 185 << (isMinor ? ", minor" : ", major") << endl;
andrew@33 186 }
andrew@33 187
andrew@33 188 }
andrew@33 189
andrew@33 190
andrew@33 191 if (name != "") {
andrew@33 192 if (printable) {
andrew@33 193 cout << t << ": File meta event: code " << code
andrew@33 194 << ": " << name << ": \"" << j->getMetaMessage()
andrew@33 195 << "\"" << endl;
andrew@33 196 } else {
andrew@33 197 cout << t << ": File meta event: code " << code
andrew@33 198 << ": " << name << ": ";
andrew@33 199 for (int k = 0; k < j->getMetaMessage().length(); ++k) {
andrew@33 200 cout << (int)j->getMetaMessage()[k] << " ";
andrew@33 201 }
andrew@33 202 }
andrew@33 203 }
andrew@33 204 continue;
andrew@33 205 }
andrew@35 206 double newBeatLocation = 0;
andrew@33 207 switch (j->getMessageType()) {
andrew@33 208
andrew@33 209 case MIDI_NOTE_ON:
andrew@33 210 if (printMidiInfo)
andrew@33 211 cout << t << ": Note: channel " << ch
andrew@33 212 << " duration " << j->getDuration()
andrew@33 213 << " pitch " << j->getPitch()
andrew@33 214 << " velocity " << j->getVelocity()
andrew@33 215 << "event time " << myMidiEvents.getEventTimeMillis(t) << endl;
andrew@33 216
andrew@35 217 newBeatLocation = getBeatPositionForTickCount(t, myMidiEvents);
andrew@35 218
andrew@35 219 // printf("%i channel %i durn %i pitch %i vel %i event time %f beat pos %f\n", t, ch, (int)j->getDuration(), (int)j->getPitch(), (int)j->getVelocity(), myMidiEvents.getEventTimeMillis(t)
andrew@35 220 // , newBeatLocation);
andrew@35 221
andrew@35 222
andrew@35 223
andrew@35 224 // printf("Beat location %3.2f\n", newBeatLocation);
andrew@34 225
andrew@34 226 /*
andrew@33 227 if (noteOnIndex == 0 || t < firstTickTime){
andrew@33 228 //easier just to pick the minimum
andrew@33 229 firstTickTime = t;
andrew@33 230 printf("FIRST TICK TIME %i\n", firstTickTime);
andrew@33 231 }
andrew@33 232
andrew@33 233 noteOnIndex++;
andrew@34 234 */
andrew@33 235 v.clear();
andrew@33 236
andrew@33 237 // printf("note on at %i\n", t);
andrew@33 238
andrew@34 239 //if (!chopBeginning)
andrew@33 240 v.push_back(t);
andrew@34 241 //else
andrew@34 242 // v.push_back(t - firstTickTime);
andrew@33 243
andrew@33 244 v.push_back(j->getPitch());
andrew@33 245 v.push_back(j->getVelocity());
andrew@33 246 v.push_back(j->getDuration());
andrew@33 247 myMidiEvents.recordedNoteOnMatrix.push_back(v);
andrew@35 248 myMidiEvents.noteOnMatches.push_back(false);
andrew@35 249 myMidiEvents.beatPositions.push_back(newBeatLocation);
andrew@33 250
andrew@33 251
andrew@33 252 break;
andrew@33 253
andrew@33 254 case MIDI_POLY_AFTERTOUCH:
andrew@33 255 if (printMidiInfo)
andrew@33 256 cout << t << ": Polyphonic aftertouch: channel " << ch
andrew@33 257 << " pitch " << j->getPitch()
andrew@33 258 << " pressure " << j->getData2() << endl;
andrew@33 259 break;
andrew@33 260
andrew@33 261 case MIDI_CTRL_CHANGE:
andrew@33 262 {
andrew@33 263 int controller = j->getData1();
andrew@33 264 string name;
andrew@33 265 switch (controller) {
andrew@33 266 case MIDI_CONTROLLER_BANK_MSB: name = "Bank select MSB"; break;
andrew@33 267 case MIDI_CONTROLLER_VOLUME: name = "Volume"; break;
andrew@33 268 case MIDI_CONTROLLER_BANK_LSB: name = "Bank select LSB"; break;
andrew@33 269 case MIDI_CONTROLLER_MODULATION: name = "Modulation wheel"; break;
andrew@33 270 case MIDI_CONTROLLER_PAN: name = "Pan"; break;
andrew@33 271 case MIDI_CONTROLLER_SUSTAIN: name = "Sustain"; break;
andrew@33 272 case MIDI_CONTROLLER_RESONANCE: name = "Resonance"; break;
andrew@33 273 case MIDI_CONTROLLER_RELEASE: name = "Release"; break;
andrew@33 274 case MIDI_CONTROLLER_ATTACK: name = "Attack"; break;
andrew@33 275 case MIDI_CONTROLLER_FILTER: name = "Filter"; break;
andrew@33 276 case MIDI_CONTROLLER_REVERB: name = "Reverb"; break;
andrew@33 277 case MIDI_CONTROLLER_CHORUS: name = "Chorus"; break;
andrew@33 278 case MIDI_CONTROLLER_NRPN_1: name = "NRPN 1"; break;
andrew@33 279 case MIDI_CONTROLLER_NRPN_2: name = "NRPN 2"; break;
andrew@33 280 case MIDI_CONTROLLER_RPN_1: name = "RPN 1"; break;
andrew@33 281 case MIDI_CONTROLLER_RPN_2: name = "RPN 2"; break;
andrew@33 282 case MIDI_CONTROLLER_SOUNDS_OFF: name = "All sounds off"; break;
andrew@33 283 case MIDI_CONTROLLER_RESET: name = "Reset"; break;
andrew@33 284 case MIDI_CONTROLLER_LOCAL: name = "Local"; break;
andrew@33 285 case MIDI_CONTROLLER_ALL_NOTES_OFF: name = "All notes off"; break;
andrew@33 286 }
andrew@33 287 if (printMidiInfo)
andrew@33 288 cout << t << ": Controller change: channel " << ch
andrew@33 289 << " controller " << j->getData1();
andrew@33 290 if (name != "") cout << " (" << name << ")";
andrew@33 291 cout << " value " << j->getData2() << endl;
andrew@33 292 }
andrew@33 293 break;
andrew@33 294
andrew@33 295 case MIDI_PROG_CHANGE:
andrew@33 296 if (printMidiInfo)
andrew@33 297 cout << t << ": Program change: channel " << ch
andrew@33 298 << " program " << j->getData1() << endl;
andrew@33 299 break;
andrew@33 300
andrew@33 301 case MIDI_CHNL_AFTERTOUCH:
andrew@33 302 if (printMidiInfo)
andrew@33 303 cout << t << ": Channel aftertouch: channel " << ch
andrew@33 304 << " pressure " << j->getData1() << endl;
andrew@33 305 break;
andrew@33 306
andrew@33 307 case MIDI_PITCH_BEND:
andrew@33 308 if (printMidiInfo)
andrew@33 309 cout << t << ": Pitch bend: channel " << ch
andrew@33 310 << " value " << (int)j->getData2() * 128 + (int)j->getData1() << endl;
andrew@33 311 break;
andrew@33 312
andrew@33 313 case MIDI_SYSTEM_EXCLUSIVE:
andrew@33 314 if (printMidiInfo)
andrew@33 315 cout << t << ": System exclusive: code "
andrew@33 316 << (int)j->getMessageType() << " message length " <<
andrew@33 317 j->getMetaMessage().length() << endl;
andrew@33 318 break;
andrew@33 319
andrew@33 320
andrew@33 321 }
andrew@33 322
andrew@33 323
andrew@33 324 }
andrew@33 325
andrew@33 326
andrew@33 327 }
andrew@34 328 // if (printMidiInfo)
andrew@34 329 // myMidiEvents.printRecordedEvents();
andrew@33 330
andrew@33 331 //printMeasuresSoFar(myMidiEvents);
andrew@33 332
andrew@33 333 if (myMidiEvents.recordedNoteOnMatrix.size() > 0){
andrew@33 334
andrew@33 335 printf("END FILE MEASURE UPDATE\n");
andrew@33 336 updateMeasureToTickPosition(myMidiEvents.recordedNoteOnMatrix[myMidiEvents.recordedNoteOnMatrix.size()-1][0], myMidiEvents);
andrew@33 337 // printMeasuresSoFar(myMidiEvents);
andrew@33 338 }
andrew@33 339
andrew@33 340 // printf("|||||||||||||||||||||| \n\n\n\n\n\n\n");
andrew@33 341 myMidiEvents.reorderMatrixFromNoteTimes(myMidiEvents.recordedNoteOnMatrix);
andrew@33 342 myMidiEvents.correctTiming(myMidiEvents.recordedNoteOnMatrix);
andrew@33 343 myMidiEvents.doublecheckOrder(myMidiEvents.recordedNoteOnMatrix);
andrew@33 344
andrew@34 345 if (chopBeginning)
andrew@34 346 chopBeginningfromEvents(myMidiEvents);
andrew@34 347
andrew@33 348 createEventTiming(myMidiEvents);
andrew@33 349
andrew@33 350 printf("BEFORE DOING MEASURE UPDATE\n first tick pos is %i\n", firstTickTime);
andrew@33 351 // printMeasuresSoFar(myMidiEvents);
andrew@33 352 if (chopBeginning)
andrew@33 353 correctMeasuresTiming(myMidiEvents);
andrew@33 354
andrew@34 355 // if (printMidiInfo)
andrew@34 356 // myMidiEvents.printRecordedEvents();
andrew@33 357
andrew@33 358 printf("Duration of MIDI file is %f \n", myMidiEvents.recordedEventTimes[myMidiEvents.recordedEventTimes.size()-1]);
andrew@34 359 printf("And first note offset is %i ticks == %f msec \n", firstTickTime, firstNoteTime);
andrew@35 360 printUpToIndex(50, myMidiEvents);
andrew@33 361 //printMeasuresSoFar(myMidiEvents);
andrew@33 362
andrew@33 363 }//end cannam midi main
andrew@33 364
andrew@33 365
andrew@34 366 void CannamMidiFileLoader::chopBeginningfromEvents(midiEventHolder& myMidiEvents){
andrew@34 367
andrew@34 368 firstTickTime = myMidiEvents.recordedNoteOnMatrix[0][0];
andrew@34 369 firstNoteTime = myMidiEvents.getEventTimeMillis(myMidiEvents.recordedNoteOnMatrix[0][0]);
andrew@34 370 myMidiEvents.firstEventOffsetTimeMillis = firstNoteTime;
andrew@34 371
andrew@34 372 printf("BEFORE chop - FIRST NOTE IS %f and tick %i\n", firstNoteTime, firstTickTime);
andrew@34 373 // myMidiEvents.printRecordedEvents();
andrew@34 374
andrew@34 375 for (int i = 0;i < myMidiEvents.recordedNoteOnMatrix.size();i++){
andrew@34 376 myMidiEvents.recordedNoteOnMatrix[i][0] -= firstTickTime;
andrew@34 377 }
andrew@34 378
andrew@34 379 //here are period values, but we dont use them
andrew@34 380 for (int i = 0;i < myMidiEvents.periodValues.size();i++){
andrew@34 381 myMidiEvents.periodValues[i][0] -= firstTickTime;
andrew@34 382 myMidiEvents.periodValues[i][2] -= firstNoteTime;
andrew@34 383 printf("[%i], period values(%i):: @ %f is %f\n", (int)myMidiEvents.periodValues[i][0], i, myMidiEvents.periodValues[i][2], myMidiEvents.periodValues[i][1]);
andrew@34 384 }
andrew@34 385
andrew@34 386 printf("\n\n\nAFTER chop - \n");
andrew@35 387
andrew@35 388 //myMidiEvents.printRecordedEvents();
andrew@34 389
andrew@34 390 }
andrew@34 391
andrew@33 392 void CannamMidiFileLoader::createEventTiming( midiEventHolder& myMidiEvents){
andrew@33 393
andrew@33 394 long t;
andrew@34 395 // t = myMidiEvents.recordedNoteOnMatrix[0][0];
andrew@34 396 // firstTickTime = t;
andrew@34 397 // firstNoteTime = myMidiEvents.getEventTimeMillis(firstTickTime);
andrew@33 398
andrew@33 399 for (int i = 0; i < myMidiEvents.recordedNoteOnMatrix.size();i++){
andrew@33 400 t = myMidiEvents.recordedNoteOnMatrix[i][0];
andrew@33 401
andrew@33 402 if (!chopBeginning)
andrew@33 403 myMidiEvents.recordedEventTimes.push_back(myMidiEvents.getEventTimeMillis(t));
andrew@33 404 else {
andrew@34 405 myMidiEvents.recordedEventTimes.push_back(myMidiEvents.getEventTimeMillis(t));// - firstticktime
andrew@33 406 }
andrew@33 407 }
andrew@33 408
andrew@34 409
andrew@34 410
andrew@33 411 }
andrew@33 412
andrew@33 413 void CannamMidiFileLoader::setTempoFromMidiValue(long tempo, midiEventHolder& myMidiEvents){
andrew@33 414 myMidiEvents.tempo = 60000000.0 / double(tempo);
andrew@33 415 myMidiEvents.period = double(tempo)/1000.0;
andrew@33 416 myMidiEvents.ticksFactor = myMidiEvents.pulsesPerQuarternote / myMidiEvents.period;
andrew@33 417 }
andrew@33 418
andrew@33 419
andrew@33 420 void CannamMidiFileLoader::newTimeSignature(int ticks, int numerator, int denominator, midiEventHolder& myMidiEvents){
andrew@33 421
andrew@33 422 updateMeasureToTickPosition(ticks, myMidiEvents);
andrew@33 423
andrew@35 424 beatsPerMeasure = 4.0 * (float)numerator / denominator;
andrew@33 425 ticksPerMeasure = myMidiEvents.pulsesPerQuarternote * 4 * numerator / denominator;
andrew@33 426
andrew@33 427 }
andrew@33 428
andrew@33 429 void CannamMidiFileLoader::updateMeasureToTickPosition(int ticks, midiEventHolder& myMidiEvents){
andrew@33 430 printf("update measure at tick pos %i at tpm %i\n", ticks, ticksPerMeasure);
andrew@33 431
andrew@33 432 int measureVectorSize = myMidiEvents.measureVector.size();
andrew@33 433 int lastMeasurePosition = 0;
andrew@33 434 // if (chopBeginning)
andrew@33 435 // lastMeasurePosition = -1*firstTickTime;
andrew@33 436
andrew@33 437 if (measureVectorSize > 0)
andrew@33 438 lastMeasurePosition = myMidiEvents.measureVector[measureVectorSize-1];
andrew@33 439
andrew@33 440
andrew@33 441 while (lastMeasurePosition < ticks){
andrew@33 442 //update
andrew@33 443 lastMeasurePosition += ticksPerMeasure;
andrew@35 444 numberOfBeatsAtLastPosition += beatsPerMeasure;
andrew@35 445 lastBeatPosition = lastMeasurePosition;
andrew@33 446 myMidiEvents.measureVector.push_back(lastMeasurePosition);
andrew@35 447
andrew@33 448 // cout << "MEASURE " << myMidiEvents.measureVector.size()-1 << " is " << lastMeasurePosition << endl;
andrew@33 449 // printf("MEASURE %i is %i \n", (int)myMidiEvents.measureVector.size()-1 , lastMeasurePosition);
andrew@33 450 }
andrew@33 451 }
andrew@33 452
andrew@33 453
andrew@33 454 void CannamMidiFileLoader::correctMeasuresTiming(midiEventHolder& myMidiEvents){
andrew@33 455 //correct measures
andrew@33 456 for (int i = 0;i <myMidiEvents.measureVector.size();i++){
andrew@33 457 myMidiEvents.measureVector[i] -= firstTickTime;
andrew@33 458 }
andrew@33 459 printf("AFTER DOING MEASURE UPDATE\n");
andrew@34 460 //printMeasuresSoFar(myMidiEvents);
andrew@33 461 }
andrew@33 462
andrew@33 463 void CannamMidiFileLoader::printMeasuresSoFar(midiEventHolder& myMidiEvents){
andrew@33 464 for (int i = 0;i < myMidiEvents.measureVector.size();i++){
andrew@33 465 printf("measure [%i] at %i\n", i, myMidiEvents.measureVector[i]);
andrew@33 466 }
andrew@35 467 }
andrew@35 468
andrew@35 469 double CannamMidiFileLoader::getBeatPositionForTickCount(long t, midiEventHolder& myMidiEvents){
andrew@35 470 int lastMeasurePosition = 0;
andrew@35 471 if (myMidiEvents.measureVector.size() > 0)
andrew@35 472 lastMeasurePosition = myMidiEvents.measureVector[myMidiEvents.measureVector.size()-1];
andrew@35 473
andrew@35 474 int ticksSinceBeatCounted = t - lastMeasurePosition;
andrew@35 475 double beats = numberOfBeatsAtLastPosition;
andrew@35 476 beats += ticksSinceBeatCounted * beatsPerMeasure / ticksPerMeasure;
andrew@35 477 // printf("ticks since %i, beat per measure %f at %i tick per measure :: %f beats\n", ticksSinceBeatCounted, beatsPerMeasure, ticksPerMeasure, beats);
andrew@35 478 return beats;
andrew@35 479 }
andrew@35 480
andrew@35 481
andrew@35 482 void CannamMidiFileLoader::printUpToIndex(const int& index, midiEventHolder& myMidiEvents){
andrew@35 483 for (int i = 0;i < index;i++){
andrew@35 484 printf("Beat pos %f MIIDI %i event time %f\n", myMidiEvents.beatPositions[i], myMidiEvents.recordedNoteOnMatrix[i][1], myMidiEvents.recordedEventTimes[i]);
andrew@35 485 }
andrew@35 486 }