annotate hackday/testApp.cpp @ 29:69083ce48b83

alternative tempo strategy when matching.
author Andrew N Robertson <andrew.robertson@eecs.qmul.ac.uk>
date Mon, 05 Dec 2011 21:47:19 +0000
parents 49a5b023df1e
children be2e779d76b5
rev   line source
andrew@24 1 #include "testApp.h"
andrew@24 2
andrew@27 3
andrew@27 4 testApp::testApp(ofxArgs* args){
andrew@27 5 this->args = args;
andrew@27 6 }
andrew@27 7
andrew@24 8 //--------------------------------------------------------------
andrew@24 9 void testApp::setup(){
andrew@27 10
andrew@27 11
andrew@27 12 this->args->printArgs();
andrew@27 13 this->args->printOpts();
andrew@24 14 midiFileName = "../../../data/frerejacques.mid";
andrew@27 15
andrew@27 16 if (this->args->getCount() > 0){
andrew@27 17 museScoreFilename = this->args->getString(1);
andrew@27 18 //printf("MUSESCORE FILENAME IS %s\n", museScoreFilename);
andrew@27 19 cout << "running!! " << museScoreFilename << endl;
andrew@27 20 midiFileName = museScoreFilename;
andrew@27 21 }
andrew@27 22
andrew@24 23 int retVal = cannamMainFunction();
andrew@24 24
andrew@24 25 ofSetVerticalSync(true);
andrew@24 26 //ofBackground(255,255,255);
andrew@27 27 midiPort = 2;
andrew@24 28 midiIn.listPorts();
andrew@27 29 midiIn.openPort(midiPort);
andrew@27 30 midiPortName = "";
andrew@27 31 //midiPortName = midiIn.portNames(midiPort);
andrew@24 32
andrew@29 33 transpose = 0;
andrew@24 34 noteInStream.transposeVal = &transpose;
andrew@24 35
andrew@24 36 noteInStream.startTime = &midiEvents.startTime;//point start time of note in stream to the same time in MIDI events
andrew@24 37
andrew@24 38 noteInStream.factor = &midiEvents.ticksFactor;
andrew@24 39 printf("TICKS FACTOR %f \n", midiEvents.ticksFactor);//noteInStream->factor)
andrew@24 40
andrew@24 41 // portName = "hello";//midiIn.portNames[2];
andrew@24 42 // printf("MIDI PORT %c\n", portName);
andrew@24 43 cout << "MIDI PORT " << endl;//portName << endl;
andrew@24 44
andrew@24 45
andrew@24 46 //midiIn.addListener(this);
andrew@24 47 ofAddListener(midiIn.newMessageEvent, this, &testApp::newMessage);
andrew@24 48
andrew@27 49
andrew@27 50 verdana30.loadFont("verdana.ttf", 50, true, true);
andrew@27 51 verdana30.setLineHeight(48.0f);
andrew@27 52 verdana30.setLetterSpacing(1.035);
andrew@24 53
andrew@24 54 playing = false;
andrew@24 55
andrew@24 56
andrew@24 57 receiver.setup( PORT );
andrew@25 58
andrew@25 59 sender.setup( HOST, SEND_PORT );
andrew@24 60
andrew@24 61 screenWidth = ofGetWidth();
andrew@24 62 screenHeight = ofGetHeight();
andrew@24 63 midiEvents.screenWidth = &screenWidth;
andrew@24 64 midiEvents.screenHeight = &screenHeight;
andrew@24 65 midiEvents.drawTempoMode = false;
andrew@24 66 ofSetFrameRate(30);
andrew@25 67
andrew@25 68 midiEvents.ticksPerScreen += 4000;
andrew@25 69 lastScoreIndexSent = 0;
andrew@27 70 performanceRating = 0.0;
andrew@27 71
andrew@27 72 liveInputPlaying = false;
andrew@27 73 lastScoreIndexSent = 0;
andrew@27 74 midiEvents.bestMatchIndex = 0;
andrew@25 75
andrew@24 76 }
andrew@24 77
andrew@24 78 //--------------------------------------------------------------
andrew@24 79 void testApp::update(){
andrew@24 80 if (playing){
andrew@25 81 midiEvents.updatePlayPosition();//this fn calls midiEvents.bayesStruct.updateBestEstimate();
andrew@24 82 }
andrew@24 83 // drawer.tickLocation+=20;
andrew@24 84
andrew@24 85 // check for waiting messages
andrew@24 86 while( receiver.hasWaitingMessages() )
andrew@24 87 {
andrew@24 88 ofxOscMessage m;
andrew@24 89 receiver.getNextMessage( &m );
andrew@24 90
andrew@24 91 if ( m.getAddress() == "/midinoteon" )
andrew@24 92 {
andrew@26 93 int newMidiOnPitch = m.getArgAsInt32(0) + transpose;
andrew@24 94 int velocity = m.getArgAsInt32(1);
andrew@24 95 double time = m.getArgAsFloat(2);
andrew@24 96
andrew@26 97 if (velocity != 0){
andrew@26 98 midiEvents.newNoteOnEvent(newMidiOnPitch, velocity, time);
andrew@26 99 noteInStream.newNoteCounted(newMidiOnPitch);
andrew@26 100 }
andrew@24 101
andrew@24 102 }
andrew@24 103
andrew@24 104 if ( m.getAddress() == "/setSpeedPrior" )
andrew@24 105 {
andrew@24 106 float speedPrior = m.getArgAsFloat(0);
andrew@24 107 printf("speed prior set to %f\n", speedPrior);
andrew@24 108 midiEvents.speedPriorValue = speedPrior;
andrew@24 109 midiEvents.bayesStruct.speedPriorValue = speedPrior;
andrew@24 110 }
andrew@24 111
andrew@24 112 if ( m.getAddress() == "/startplaying" )
andrew@24 113 {
andrew@24 114 startPlaying();
andrew@24 115 }
andrew@24 116
andrew@24 117 if ( m.getAddress() == "/stopplaying" )
andrew@24 118 {
andrew@24 119 stopPlaying();
andrew@24 120 }
andrew@24 121
andrew@24 122
andrew@24 123 if ( m.getAddress() == "/integratedEstimate" )
andrew@24 124 {
andrew@24 125 midiEvents.bayesStruct.usingIntegratedTempoEstimate = true;
andrew@24 126 }
andrew@24 127
andrew@24 128 if ( m.getAddress() == "/MAPestimate" )
andrew@24 129 {
andrew@24 130 midiEvents.bayesStruct.usingIntegratedTempoEstimate = false;
andrew@24 131 }
andrew@24 132
andrew@24 133
andrew@24 134 if ( m.getAddress() == "/realtime" )
andrew@24 135 {
andrew@24 136 midiEvents.runningInRealTime = true;
andrew@24 137 }
andrew@24 138
andrew@24 139
andrew@24 140 if ( m.getAddress() == "/offline" )
andrew@24 141 {
andrew@24 142 midiEvents.runningInRealTime = false;
andrew@24 143 }
andrew@24 144
andrew@24 145 if ( m.getAddress() == "/minimumSpeedRatio" )
andrew@24 146 {
andrew@24 147
andrew@24 148 float minSpeed = m.getArgAsFloat(0);
andrew@24 149 //printf("minimum speed received is %f and max is %f\n", minSpeed, midiEvents.bayesStruct.relativeSpeedLikelihood.getIndexInRealTerms(midiEvents.bayesStruct.relativeSpeedLikelihood.length-1));
andrew@24 150 if (minSpeed > 0 && minSpeed < midiEvents.bayesStruct.relativeSpeedLikelihood.getIndexInRealTerms(midiEvents.bayesStruct.relativeSpeedLikelihood.length-1)){
andrew@24 151 printf("minimum speed accepted is %f\n", minSpeed);
andrew@24 152 midiEvents.minimumMatchSpeed = minSpeed;
andrew@24 153 }
andrew@24 154 }
andrew@24 155
andrew@24 156 }//end while osc
andrew@25 157
andrew@25 158 checkNewScoreNote();
andrew@24 159
andrew@24 160 }
andrew@24 161
andrew@25 162
andrew@25 163 void testApp::checkNewScoreNote(){
andrew@25 164 if (lastScoreIndexSent != midiEvents.bestMatchIndex){
andrew@25 165 //then we send out new note
andrew@25 166 sendNoteToMuseScore();
andrew@25 167 lastScoreIndexSent = midiEvents.bestMatchIndex;
andrew@25 168 findMeasure();
andrew@25 169 }
andrew@25 170 }
andrew@25 171
andrew@25 172 void testApp::findMeasure(){
andrew@25 173 int ticks = midiEvents.recordedNoteOnMatrix[midiEvents.bestMatchIndex][0];
andrew@25 174 int tmpMeasure = lastMeasureSent;
andrew@25 175
andrew@25 176 while (lastMeasureSent > 0 && midiEvents.measureVector[lastMeasureSent] > ticks) {
andrew@25 177 lastMeasureSent--;
andrew@25 178 }
andrew@25 179
andrew@25 180 while (lastMeasureSent < midiEvents.measureVector.size() && midiEvents.measureVector[lastMeasureSent] < ticks) {
andrew@25 181 lastMeasureSent++;
andrew@25 182 }
andrew@25 183 if (lastMeasureSent != tmpMeasure){
andrew@27 184 //sendMeasureToMuseScore();
andrew@26 185 performanceRating = noteInStream.calculateTotalScore(midiEvents);
andrew@25 186 }
andrew@25 187
andrew@25 188
andrew@25 189 }
andrew@25 190
andrew@26 191 void testApp::sendBlackNotes(){
andrew@26 192 ofxOscMessage m;
andrew@26 193 m.setAddress( "/plugin" );
andrew@26 194 string noteString;
andrew@26 195 noteString = "blacknotes.js";
andrew@26 196 m.addStringArg( noteString);
andrew@26 197 sender.sendMessage( m );
andrew@26 198 }
andrew@26 199
andrew@25 200 void testApp::sendNoteToMuseScore(){
andrew@25 201 int ticks = midiEvents.recordedNoteOnMatrix[midiEvents.bestMatchIndex][0];
andrew@25 202 int pitch = midiEvents.recordedNoteOnMatrix[midiEvents.bestMatchIndex][1];
andrew@25 203 printf("sending to muse score %i, %i \n", ticks, pitch);
andrew@25 204
andrew@26 205 /*
andrew@26 206 ofxOscMessage m;
andrew@26 207 m.setAddress( "/plugin" );
andrew@26 208 string noteString;
andrew@26 209 noteString = "blackNotes.js";
andrew@26 210 m.addStringArg( noteString);
andrew@26 211 sender.sendMessage( m );
andrew@26 212 */
andrew@27 213 sendNoteDataByOsc(pitch, ticks);
andrew@27 214
andrew@27 215 // /color-note 60,3440
andrew@27 216
andrew@27 217 //crappy javascript message
andrew@27 218 /*
andrew@26 219 ofxOscMessage m;
andrew@26 220 m.setAddress( "/plugin" );
andrew@26 221 string noteString;
andrew@26 222 noteString = "coloronenote.js";
andrew@26 223 noteString += ",myTick,"+ofToString(ticks)+",myPitch,"+ofToString(pitch);
andrew@26 224 // printf("%s\n", noteString);
andrew@26 225 m.addStringArg( noteString);
andrew@27 226 sender.sendMessage( m ); */
andrew@27 227
andrew@25 228
andrew@25 229 // /plugin coloronenote.js mytick 100 mypitch 56;
andrew@25 230 }
andrew@25 231
andrew@27 232 void testApp::sendNoteDataByOsc(const int& pitch, const int& ticks){
andrew@27 233 ofxOscMessage m;
andrew@27 234 m.setAddress( "/color-note" );
andrew@27 235 string noteString;
andrew@27 236 noteString = ofToString(ticks);
andrew@27 237 noteString += ","+ofToString(pitch);
andrew@27 238 m.addStringArg( noteString);
andrew@27 239 sender.sendMessage( m );
andrew@27 240 }
andrew@25 241
andrew@25 242 void testApp::sendMeasureToMuseScore(){
andrew@25 243
andrew@25 244 printf("sending measure to muse score %i \n", lastMeasureSent);
andrew@25 245
andrew@25 246 ofxOscMessage m;
andrew@25 247 m.setAddress( "/select-measure" );
andrew@25 248 m.addIntArg(lastMeasureSent);
andrew@25 249 sender.sendMessage( m );
andrew@25 250
andrew@25 251 // /select-measure 6
andrew@25 252 // /plugin coloronenote.js mytick 100 mypitch 56;
andrew@25 253 }
andrew@25 254
andrew@25 255
andrew@24 256 void testApp::newMessage(ofxMidiEventArgs &args){
andrew@24 257
andrew@24 258 int pitch;
andrew@24 259 if (noteInStream.noteInReceived(args)){
andrew@24 260 double timeNow = ofGetElapsedTimeMillis();
andrew@24 261
andrew@24 262 if (!liveInputPlaying){
andrew@24 263 firstNoteTime = timeNow;
andrew@24 264 liveInputPlaying = true;
andrew@24 265 startPlaying();
andrew@24 266 printf("FIRST LIVE NOTE IS NOW AT TIME %f\n", timeNow);
andrew@24 267 }
andrew@24 268
andrew@24 269 pitch = args.byteOne + transpose;
andrew@24 270
andrew@24 271 midiEvents.newNoteOnEvent(pitch, args.byteTwo, timeNow - firstNoteTime);
andrew@24 272
andrew@24 273
andrew@24 274 int tickTime = midiEvents.getEventTimeTicks(timeNow-firstNoteTime);
andrew@24 275 IntVector v;
andrew@24 276 v.push_back(tickTime);
andrew@24 277 v.push_back(pitch);
andrew@24 278 v.push_back(args.byteTwo);
andrew@25 279 v.push_back(200);//tmp time til note off happens
andrew@24 280 noteInStream.midiInputEvents.push_back(v);
andrew@24 281 noteInStream.midiInputTimes.push_back(timeNow - firstNoteTime);
andrew@25 282 //printf("NOTE %i at time %f at tick time %i\n", pitch, (timeNow - firstNoteTime), tickTime);
andrew@24 283 }
andrew@24 284
andrew@24 285 // cout << "MIDI message [port: " << args.port << ", channel: " << args.channel << ", status: " << args.status << ", byteOne: " << pitch << ", byteTwo: " << args.byteTwo << ", timestamp: " << args.timestamp << "]" << endl;
andrew@24 286 }
andrew@24 287
andrew@24 288 //--------------------------------------------------------------
andrew@24 289 void testApp::draw(){
andrew@24 290
andrew@24 291 midiEvents.drawFile();
andrew@24 292
andrew@25 293 string info = "Measure ";
andrew@25 294 info += ofToString(lastMeasureSent);
andrew@25 295 info += " Last note ";
andrew@25 296 info += ofToString(lastScoreIndexSent);
andrew@25 297
andrew@27 298 ofSetHexColor(0xFF0000);
andrew@27 299 // ofDrawBitmapString(info, 20, 20);
andrew@24 300 midiEvents.drawMidiFile(noteInStream.midiInputEvents);
andrew@24 301
andrew@27 302 // ofDrawBitmapString("Rating "+ofToString(performanceRating*100), 60, 50);
andrew@27 303 //ofDrawBitmapString("filename "+museScoreFilename, 20, 80);
andrew@27 304 string ratingString = ofToString(performanceRating*100,0)+"%";
andrew@27 305 if (performanceRating > 0.84)
andrew@27 306 ratingString += "!* *";
andrew@27 307 string extraText = "";
andrew@27 308 if (performanceRating > 0.9){
andrew@27 309 extraText += " pretty good, huh?";
andrew@27 310 }
andrew@27 311 if (performanceRating > 0.95)
andrew@27 312 extraText = " blimey! ";
andrew@27 313 if (performanceRating > 0.97)
andrew@27 314 extraText = " maestro!";
andrew@27 315
andrew@27 316 ratingString += extraText;
andrew@27 317 verdana30.drawString(ratingString, 20, 60);
andrew@27 318
andrew@27 319 ofSetHexColor(0x000000);
andrew@27 320 ofDrawBitmapString(midiPortName, 20, ofGetHeight() - 20);
andrew@27 321
andrew@24 322 }
andrew@24 323
andrew@24 324 //--------------------------------------------------------------
andrew@24 325 void testApp::keyPressed(int key){
andrew@24 326
andrew@27 327 if (key == '.'){
andrew@27 328 midiPort++;
andrew@27 329 midiIn.openPort(midiPort);
andrew@27 330 }
andrew@27 331
andrew@27 332 if (key == ',' && midiPort > 0){
andrew@27 333 midiPort--;
andrew@27 334 midiIn.openPort(midiPort);
andrew@27 335 }
andrew@24 336
andrew@24 337 // if (key == ' '){
andrew@24 338 // startPlaying();
andrew@24 339 // }
andrew@24 340 if (key == '-')
andrew@24 341 transpose -= 12;
andrew@24 342
andrew@24 343 if (key == '=')
andrew@24 344 transpose += 12;
andrew@24 345
andrew@24 346 if (key == 'c'){
andrew@24 347 double timenow = ofGetElapsedTimeMillis();
andrew@24 348 midiEvents.exampleCrossUpdate();
andrew@24 349 timenow *= -1;
andrew@24 350 timenow += ofGetElapsedTimeMillis();
andrew@24 351 printf("CROSS UPDATE TOOK %f", timenow);
andrew@24 352 }
andrew@26 353
andrew@27 354 if (key == 'x')
andrew@27 355 sendNoteDataByOsc(60, 0);
andrew@27 356
andrew@26 357 if (key == OF_KEY_LEFT){
andrew@26 358
andrew@26 359 }
andrew@26 360
andrew@26 361 if (key == OF_KEY_RIGHT)
andrew@24 362
andrew@24 363 if (key == OF_KEY_RETURN)
andrew@24 364 stopPlaying();
andrew@24 365
andrew@24 366 if (key == OF_KEY_UP){
andrew@24 367 if (midiEvents.ticksPerScreen >= 4000)
andrew@24 368 midiEvents.ticksPerScreen += 2000;
andrew@24 369 else
andrew@24 370 midiEvents.ticksPerScreen += 500;
andrew@24 371 }
andrew@24 372
andrew@24 373 if (key == 'm'){
andrew@24 374 // midiEvents.findMatch(84, 0, 10000);
andrew@24 375 }
andrew@24 376
andrew@26 377 if (key == 'b'){
andrew@26 378 sendBlackNotes();
andrew@26 379 }
andrew@26 380
andrew@24 381 if (key == OF_KEY_DOWN){
andrew@24 382 if (midiEvents.ticksPerScreen >= 4000)
andrew@24 383 midiEvents.ticksPerScreen -= 2000;
andrew@24 384 else if (midiEvents.ticksPerScreen > 500)
andrew@24 385 midiEvents.ticksPerScreen -= 500;
andrew@24 386 }
andrew@24 387
andrew@24 388 if (key == 'w')
andrew@24 389 midiEvents.printMatchMatrix();
andrew@24 390
andrew@24 391 if (key == 'k'){
andrew@24 392 noteInStream.printNotes();
andrew@24 393 }
andrew@24 394
andrew@24 395 if (key == 'p'){
andrew@24 396 midiEvents.printNotes();
andrew@24 397 }
andrew@24 398
andrew@24 399 if (key == 'l')
andrew@24 400 midiEvents.bayesStruct.decaySpeedDistribution(100);
andrew@24 401
andrew@24 402 if (key == 't')
andrew@24 403 midiEvents.drawTempoMode = !midiEvents.drawTempoMode;
andrew@24 404
andrew@24 405 if (key == 'y')
andrew@24 406 midiEvents.drawPhaseMode = !midiEvents.drawPhaseMode;
andrew@24 407
andrew@24 408 if (key == 'r'){
andrew@24 409 noteInStream.reset();
andrew@24 410 liveInputPlaying = false;
andrew@24 411 stopPlaying();
andrew@26 412 lastMeasureSent = 0;
andrew@26 413 sendMeasureToMuseScore();
andrew@26 414 sendBlackNotes();
andrew@26 415 lastScoreIndexSent = 0;
andrew@28 416 performanceRating = 0;
andrew@26 417
andrew@24 418 }
andrew@24 419
andrew@27 420 if (key == 'o' || key == 'O'){
andrew@24 421 //open audio file
andrew@24 422 string *filePtr;
andrew@24 423 filePtr = &midiFileName;
andrew@24 424
andrew@24 425 if (getFilenameFromDialogBox(filePtr)){
andrew@24 426 printf("Midifile: Loaded name okay :\n'%s' \n", midiFileName.c_str());
andrew@24 427 cannamMainFunction();
andrew@24 428 }
andrew@24 429 }
andrew@24 430
andrew@24 431
andrew@24 432
andrew@24 433 }
andrew@24 434
andrew@24 435 //--------------------------------------------------------------
andrew@24 436 void testApp::keyReleased(int key){
andrew@24 437
andrew@24 438 }
andrew@24 439
andrew@24 440 //--------------------------------------------------------------
andrew@24 441 void testApp::mouseMoved(int x, int y ){
andrew@24 442 midiEvents.mouseX = midiEvents.getEventTimeMillis((x * midiEvents.ticksPerScreen)/ screenWidth);
andrew@24 443 }
andrew@24 444
andrew@24 445 //--------------------------------------------------------------
andrew@24 446 void testApp::mouseDragged(int x, int y, int button){
andrew@24 447
andrew@24 448 }
andrew@24 449
andrew@24 450 //--------------------------------------------------------------
andrew@24 451 void testApp::mousePressed(int x, int y, int button){
andrew@24 452
andrew@24 453 }
andrew@24 454
andrew@24 455 //--------------------------------------------------------------
andrew@24 456 void testApp::mouseReleased(int x, int y, int button){
andrew@24 457
andrew@24 458 }
andrew@24 459
andrew@24 460 //--------------------------------------------------------------
andrew@24 461 void testApp::windowResized(int w, int h){
andrew@24 462 screenWidth = w;
andrew@24 463 screenHeight = h;
andrew@24 464 midiEvents.noteHeight = screenHeight / (float)(midiEvents.noteMaximum - midiEvents.noteMinimum);
andrew@24 465
andrew@24 466 }
andrew@24 467
andrew@24 468
andrew@24 469
andrew@24 470 void testApp::startPlaying(){
andrew@24 471 playing = !playing;
andrew@24 472 midiEvents.reset();
andrew@26 473 noteInStream.reset();
andrew@24 474 midiEvents.setStartPlayingTimes();
andrew@26 475 sendBlackNotes();
andrew@24 476 //this is where we stop and start playing
andrew@24 477 }
andrew@24 478
andrew@24 479 void testApp::stopPlaying(){
andrew@26 480 midiEvents.printNoteCounter();
andrew@26 481 noteInStream.printTotalCount();
andrew@26 482 noteInStream.calculateTotalScore(midiEvents);
andrew@26 483
andrew@26 484
andrew@24 485 playing = false;
andrew@24 486 liveInputPlaying = false;
andrew@25 487 lastScoreIndexSent = 0;
andrew@25 488 midiEvents.bestMatchIndex = 0;
andrew@25 489 sendNoteToMuseScore();
andrew@26 490
andrew@24 491 }
andrew@24 492
andrew@24 493 bool testApp::getFilenameFromDialogBox(string* fileNameToSave){
andrew@24 494 //this uses a pointer structure within the loader and returns true if the dialogue box was used successfully
andrew@24 495 // first, create a string that will hold the URL
andrew@24 496 string URL;
andrew@24 497
andrew@24 498 // openFile(string& URL) returns 1 if a file was picked
andrew@24 499 // returns 0 when something went wrong or the user pressed 'cancel'
andrew@24 500 int response = ofxFileDialogOSX::openFile(URL);
andrew@24 501 if(response){
andrew@24 502 // now you can use the URL
andrew@24 503 *fileNameToSave = URL;
andrew@24 504 //printf("\n filename is %s \n", soundFileName.c_str());
andrew@24 505 return true;
andrew@24 506 }
andrew@24 507 else {
andrew@24 508 // soundFileName = "OPEN canceled. ";
andrew@24 509 printf("\n open file cancelled \n");
andrew@24 510 return false;
andrew@24 511 }
andrew@24 512
andrew@24 513
andrew@24 514
andrew@24 515 }
andrew@24 516
andrew@24 517
andrew@24 518
andrew@24 519
andrew@24 520 int testApp::cannamMainFunction(){
andrew@24 521
andrew@24 522
andrew@24 523 midiEvents.clearAllEvents();
andrew@24 524
andrew@24 525 //int main(int argc, char **argv)
andrew@24 526 //{
andrew@24 527 // if (argc != 2) {
andrew@24 528 // cerr << "Usage: midifile <file.mid>" << endl;
andrew@24 529 // return 1;
andrew@24 530 // }
andrew@24 531
andrew@24 532 std::string filename = midiFileName;//argv[1];
andrew@24 533
andrew@24 534 // fileLoader.chopBeginning = true;
andrew@24 535 fileLoader.loadFile(filename, midiEvents);
andrew@24 536
andrew@24 537 }//new end of load function
andrew@24 538
andrew@24 539
andrew@24 540
andrew@24 541