Mercurial > hg > midi-score-follower
comparison hackday/testApp.cpp @ 27:fa1890efa044
close to final version on HackDay
author | Andrew N Robertson <andrew.robertson@eecs.qmul.ac.uk> |
---|---|
date | Sun, 04 Dec 2011 14:30:33 +0000 |
parents | 179365726f07 |
children | 49a5b023df1e |
comparison
equal
deleted
inserted
replaced
26:179365726f07 | 27:fa1890efa044 |
---|---|
1 #include "testApp.h" | 1 #include "testApp.h" |
2 | 2 |
3 | |
4 testApp::testApp(ofxArgs* args){ | |
5 this->args = args; | |
6 } | |
7 | |
3 //-------------------------------------------------------------- | 8 //-------------------------------------------------------------- |
4 void testApp::setup(){ | 9 void testApp::setup(){ |
10 | |
11 | |
12 this->args->printArgs(); | |
13 this->args->printOpts(); | |
5 midiFileName = "../../../data/frerejacques.mid"; | 14 midiFileName = "../../../data/frerejacques.mid"; |
15 | |
16 if (this->args->getCount() > 0){ | |
17 museScoreFilename = this->args->getString(1); | |
18 //printf("MUSESCORE FILENAME IS %s\n", museScoreFilename); | |
19 cout << "running!! " << museScoreFilename << endl; | |
20 midiFileName = museScoreFilename; | |
21 } | |
22 | |
6 int retVal = cannamMainFunction(); | 23 int retVal = cannamMainFunction(); |
7 | 24 |
8 cout << "MIDI INPUT EXAMPLE" << endl; | |
9 printf("midi in in in"); | |
10 ofSetVerticalSync(true); | 25 ofSetVerticalSync(true); |
11 //ofBackground(255,255,255); | 26 //ofBackground(255,255,255); |
12 | 27 midiPort = 2; |
13 midiIn.listPorts(); | 28 midiIn.listPorts(); |
14 midiIn.openPort(2); | 29 midiIn.openPort(midiPort); |
30 midiPortName = ""; | |
31 //midiPortName = midiIn.portNames(midiPort); | |
15 | 32 |
16 transpose = 12; | 33 transpose = 12; |
17 noteInStream.transposeVal = &transpose; | 34 noteInStream.transposeVal = &transpose; |
18 | 35 |
19 noteInStream.startTime = &midiEvents.startTime;//point start time of note in stream to the same time in MIDI events | 36 noteInStream.startTime = &midiEvents.startTime;//point start time of note in stream to the same time in MIDI events |
27 | 44 |
28 | 45 |
29 //midiIn.addListener(this); | 46 //midiIn.addListener(this); |
30 ofAddListener(midiIn.newMessageEvent, this, &testApp::newMessage); | 47 ofAddListener(midiIn.newMessageEvent, this, &testApp::newMessage); |
31 | 48 |
32 | 49 |
50 verdana30.loadFont("verdana.ttf", 50, true, true); | |
51 verdana30.setLineHeight(48.0f); | |
52 verdana30.setLetterSpacing(1.035); | |
33 | 53 |
34 playing = false; | 54 playing = false; |
35 | 55 |
36 | 56 |
37 receiver.setup( PORT ); | 57 receiver.setup( PORT ); |
45 midiEvents.drawTempoMode = false; | 65 midiEvents.drawTempoMode = false; |
46 ofSetFrameRate(30); | 66 ofSetFrameRate(30); |
47 | 67 |
48 midiEvents.ticksPerScreen += 4000; | 68 midiEvents.ticksPerScreen += 4000; |
49 lastScoreIndexSent = 0; | 69 lastScoreIndexSent = 0; |
50 performanceRating = 1.0; | 70 performanceRating = 0.0; |
71 | |
72 liveInputPlaying = false; | |
73 lastScoreIndexSent = 0; | |
74 midiEvents.bestMatchIndex = 0; | |
51 | 75 |
52 } | 76 } |
53 | 77 |
54 //-------------------------------------------------------------- | 78 //-------------------------------------------------------------- |
55 void testApp::update(){ | 79 void testApp::update(){ |
155 | 179 |
156 while (lastMeasureSent < midiEvents.measureVector.size() && midiEvents.measureVector[lastMeasureSent] < ticks) { | 180 while (lastMeasureSent < midiEvents.measureVector.size() && midiEvents.measureVector[lastMeasureSent] < ticks) { |
157 lastMeasureSent++; | 181 lastMeasureSent++; |
158 } | 182 } |
159 if (lastMeasureSent != tmpMeasure){ | 183 if (lastMeasureSent != tmpMeasure){ |
160 sendMeasureToMuseScore(); | 184 //sendMeasureToMuseScore(); |
161 performanceRating = noteInStream.calculateTotalScore(midiEvents); | 185 performanceRating = noteInStream.calculateTotalScore(midiEvents); |
162 } | 186 } |
163 | 187 |
164 | 188 |
165 } | 189 } |
184 string noteString; | 208 string noteString; |
185 noteString = "blackNotes.js"; | 209 noteString = "blackNotes.js"; |
186 m.addStringArg( noteString); | 210 m.addStringArg( noteString); |
187 sender.sendMessage( m ); | 211 sender.sendMessage( m ); |
188 */ | 212 */ |
189 | 213 sendNoteDataByOsc(pitch, ticks); |
214 | |
215 // /color-note 60,3440 | |
216 | |
217 //crappy javascript message | |
218 /* | |
190 ofxOscMessage m; | 219 ofxOscMessage m; |
191 m.setAddress( "/plugin" ); | 220 m.setAddress( "/plugin" ); |
192 string noteString; | 221 string noteString; |
193 noteString = "coloronenote.js"; | 222 noteString = "coloronenote.js"; |
194 noteString += ",myTick,"+ofToString(ticks)+",myPitch,"+ofToString(pitch); | 223 noteString += ",myTick,"+ofToString(ticks)+",myPitch,"+ofToString(pitch); |
195 // printf("%s\n", noteString); | 224 // printf("%s\n", noteString); |
196 m.addStringArg( noteString); | 225 m.addStringArg( noteString); |
197 sender.sendMessage( m ); | 226 sender.sendMessage( m ); */ |
198 /* | 227 |
199 m.addStringArg( "coloronenote.js" ); | |
200 m.addStringArg("mytick"); | |
201 m.addIntArg( ticks ); | |
202 m.addStringArg("mypitch"); | |
203 m.addIntArg( pitch); | |
204 */ | |
205 | 228 |
206 // /plugin coloronenote.js mytick 100 mypitch 56; | 229 // /plugin coloronenote.js mytick 100 mypitch 56; |
207 } | 230 } |
208 | 231 |
209 | 232 void testApp::sendNoteDataByOsc(const int& pitch, const int& ticks){ |
233 ofxOscMessage m; | |
234 m.setAddress( "/color-note" ); | |
235 string noteString; | |
236 noteString = ofToString(ticks); | |
237 noteString += ","+ofToString(pitch); | |
238 m.addStringArg( noteString); | |
239 sender.sendMessage( m ); | |
240 } | |
210 | 241 |
211 void testApp::sendMeasureToMuseScore(){ | 242 void testApp::sendMeasureToMuseScore(){ |
212 | 243 |
213 printf("sending measure to muse score %i \n", lastMeasureSent); | 244 printf("sending measure to muse score %i \n", lastMeasureSent); |
214 | 245 |
262 string info = "Measure "; | 293 string info = "Measure "; |
263 info += ofToString(lastMeasureSent); | 294 info += ofToString(lastMeasureSent); |
264 info += " Last note "; | 295 info += " Last note "; |
265 info += ofToString(lastScoreIndexSent); | 296 info += ofToString(lastScoreIndexSent); |
266 | 297 |
298 ofSetHexColor(0xFF0000); | |
299 // ofDrawBitmapString(info, 20, 20); | |
300 midiEvents.drawMidiFile(noteInStream.midiInputEvents); | |
301 | |
302 // ofDrawBitmapString("Rating "+ofToString(performanceRating*100), 60, 50); | |
303 //ofDrawBitmapString("filename "+museScoreFilename, 20, 80); | |
304 string ratingString = ofToString(performanceRating*100,0)+"%"; | |
305 if (performanceRating > 0.84) | |
306 ratingString += "!* *"; | |
307 string extraText = ""; | |
308 if (performanceRating > 0.9){ | |
309 extraText += " pretty good, huh?"; | |
310 } | |
311 if (performanceRating > 0.95) | |
312 extraText = " blimey! "; | |
313 if (performanceRating > 0.97) | |
314 extraText = " maestro!"; | |
315 | |
316 ratingString += extraText; | |
317 verdana30.drawString(ratingString, 20, 60); | |
318 | |
267 ofSetHexColor(0x000000); | 319 ofSetHexColor(0x000000); |
268 ofDrawBitmapString(info, 20, 20); | 320 ofDrawBitmapString(midiPortName, 20, ofGetHeight() - 20); |
269 midiEvents.drawMidiFile(noteInStream.midiInputEvents); | 321 |
270 | |
271 ofDrawBitmapString("Rating "+ofToString(performanceRating*100), 20, 50); | |
272 } | 322 } |
273 | 323 |
274 //-------------------------------------------------------------- | 324 //-------------------------------------------------------------- |
275 void testApp::keyPressed(int key){ | 325 void testApp::keyPressed(int key){ |
276 | 326 |
327 if (key == '.'){ | |
328 midiPort++; | |
329 midiIn.openPort(midiPort); | |
330 } | |
331 | |
332 if (key == ',' && midiPort > 0){ | |
333 midiPort--; | |
334 midiIn.openPort(midiPort); | |
335 } | |
277 | 336 |
278 // if (key == ' '){ | 337 // if (key == ' '){ |
279 // startPlaying(); | 338 // startPlaying(); |
280 // } | 339 // } |
281 if (key == '-') | 340 if (key == '-') |
290 timenow *= -1; | 349 timenow *= -1; |
291 timenow += ofGetElapsedTimeMillis(); | 350 timenow += ofGetElapsedTimeMillis(); |
292 printf("CROSS UPDATE TOOK %f", timenow); | 351 printf("CROSS UPDATE TOOK %f", timenow); |
293 } | 352 } |
294 | 353 |
354 if (key == 'x') | |
355 sendNoteDataByOsc(60, 0); | |
356 | |
295 if (key == OF_KEY_LEFT){ | 357 if (key == OF_KEY_LEFT){ |
296 | 358 |
297 } | 359 } |
298 | 360 |
299 if (key == OF_KEY_RIGHT) | 361 if (key == OF_KEY_RIGHT) |
352 sendBlackNotes(); | 414 sendBlackNotes(); |
353 lastScoreIndexSent = 0; | 415 lastScoreIndexSent = 0; |
354 | 416 |
355 } | 417 } |
356 | 418 |
357 if (key == 'o'){ | 419 if (key == 'o' || key == 'O'){ |
358 //open audio file | 420 //open audio file |
359 string *filePtr; | 421 string *filePtr; |
360 filePtr = &midiFileName; | 422 filePtr = &midiFileName; |
361 | 423 |
362 if (getFilenameFromDialogBox(filePtr)){ | 424 if (getFilenameFromDialogBox(filePtr)){ |
474 }//new end of load function | 536 }//new end of load function |
475 | 537 |
476 | 538 |
477 | 539 |
478 | 540 |
479 //trying to port to new class | |
480 /* | |
481 MIDIFileReader fr(filename); | |
482 | |
483 if (!fr.isOK()) { | |
484 std::cerr << "Error: " << fr.getError().c_str() << std::endl; | |
485 return 1; | |
486 } | |
487 | |
488 MIDIComposition c = fr.load(); | |
489 | |
490 switch (fr.getFormat()) { | |
491 case MIDI_SINGLE_TRACK_FILE: cout << "Format: MIDI Single Track File" << endl; break; | |
492 case MIDI_SIMULTANEOUS_TRACK_FILE: cout << "Format: MIDI Simultaneous Track File" << endl; break; | |
493 case MIDI_SEQUENTIAL_TRACK_FILE: cout << "Format: MIDI Sequential Track File" << endl; break; | |
494 default: cout << "Format: Unknown MIDI file format?" << endl; break; | |
495 } | |
496 | |
497 cout << "Tracks: " << c.size() << endl; | |
498 | |
499 int td = fr.getTimingDivision(); | |
500 if (td < 32768) { | |
501 cout << "Timing division: " << fr.getTimingDivision() << " ppq" << endl; | |
502 | |
503 midiEvents.pulsesPerQuarternote = fr.getTimingDivision(); | |
504 } else { | |
505 int frames = 256 - (td >> 8); | |
506 int subframes = td & 0xff; | |
507 cout << "SMPTE timing: " << frames << " fps, " << subframes << " subframes" << endl; | |
508 } | |
509 | |
510 for (MIDIComposition::const_iterator i = c.begin(); i != c.end(); ++i) { | |
511 | |
512 cout << "Start of track: " << i->first+1 << endl; | |
513 | |
514 for (MIDITrack::const_iterator j = i->second.begin(); j != i->second.end(); ++j) { | |
515 | |
516 unsigned int t = j->getTime(); | |
517 int ch = j->getChannelNumber(); | |
518 | |
519 if (j->isMeta()) { | |
520 int code = j->getMetaEventCode(); | |
521 string name; | |
522 bool printable = true; | |
523 switch (code) { | |
524 | |
525 case MIDI_END_OF_TRACK: | |
526 cout << t << ": End of track" << endl; | |
527 break; | |
528 | |
529 case MIDI_TEXT_EVENT: name = "Text"; break; | |
530 case MIDI_COPYRIGHT_NOTICE: name = "Copyright"; break; | |
531 case MIDI_TRACK_NAME: name = "Track name"; break; | |
532 case MIDI_INSTRUMENT_NAME: name = "Instrument name"; break; | |
533 case MIDI_LYRIC: name = "Lyric"; break; | |
534 case MIDI_TEXT_MARKER: name = "Text marker"; break; | |
535 case MIDI_SEQUENCE_NUMBER: name = "Sequence number"; printable = false; break; | |
536 case MIDI_CHANNEL_PREFIX_OR_PORT: name = "Channel prefix or port"; printable = false; break; | |
537 case MIDI_CUE_POINT: name = "Cue point"; break; | |
538 case MIDI_CHANNEL_PREFIX: name = "Channel prefix"; printable = false; break; | |
539 case MIDI_SEQUENCER_SPECIFIC: name = "Sequencer specific"; printable = false; break; | |
540 case MIDI_SMPTE_OFFSET: name = "SMPTE offset"; printable = false; break; | |
541 | |
542 case MIDI_SET_TEMPO: | |
543 { | |
544 int m0 = j->getMetaMessage()[0]; | |
545 int m1 = j->getMetaMessage()[1]; | |
546 int m2 = j->getMetaMessage()[2]; | |
547 long tempo = (((m0 << 8) + m1) << 8) + m2; | |
548 | |
549 cout << t << ": Tempo: " << 60000000.0 / double(tempo) << endl; | |
550 midiEvents.tempo = 60000000.0 / double(tempo); | |
551 midiEvents.period = double(tempo)/1000.0; | |
552 | |
553 printf("period double is %f\n", midiEvents.period); | |
554 } | |
555 break; | |
556 | |
557 case MIDI_TIME_SIGNATURE: | |
558 { | |
559 int numerator = j->getMetaMessage()[0]; | |
560 int denominator = 1 << (int)j->getMetaMessage()[1]; | |
561 | |
562 cout << t << ": Time signature: " << numerator << "/" << denominator << endl; | |
563 } | |
564 | |
565 case MIDI_KEY_SIGNATURE: | |
566 { | |
567 int accidentals = j->getMetaMessage()[0]; | |
568 int isMinor = j->getMetaMessage()[1]; | |
569 bool isSharp = accidentals < 0 ? false : true; | |
570 accidentals = accidentals < 0 ? -accidentals : accidentals; | |
571 cout << t << ": Key signature: " << accidentals << " " | |
572 << (isSharp ? | |
573 (accidentals > 1 ? "sharps" : "sharp") : | |
574 (accidentals > 1 ? "flats" : "flat")) | |
575 << (isMinor ? ", minor" : ", major") << endl; | |
576 } | |
577 | |
578 } | |
579 | |
580 | |
581 if (name != "") { | |
582 if (printable) { | |
583 cout << t << ": File meta event: code " << code | |
584 << ": " << name << ": \"" << j->getMetaMessage() | |
585 << "\"" << endl; | |
586 } else { | |
587 cout << t << ": File meta event: code " << code | |
588 << ": " << name << ": "; | |
589 for (int k = 0; k < j->getMetaMessage().length(); ++k) { | |
590 cout << (int)j->getMetaMessage()[k] << " "; | |
591 } | |
592 } | |
593 } | |
594 continue; | |
595 } | |
596 | |
597 switch (j->getMessageType()) { | |
598 | |
599 case MIDI_NOTE_ON: | |
600 cout << t << ": Note: channel " << ch | |
601 << " duration " << j->getDuration() | |
602 << " pitch " << j->getPitch() | |
603 << " velocity " << j->getVelocity() | |
604 << "event time " << midiEvents.getEventTimeMillis(t) << endl; | |
605 v.clear(); | |
606 v.push_back(t); | |
607 v.push_back(j->getPitch()); | |
608 v.push_back(j->getVelocity()); | |
609 v.push_back(j->getDuration()); | |
610 midiEvents.recordedNoteOnMatrix.push_back(v); | |
611 midiEvents.recordedEventTimes.push_back(midiEvents.getEventTimeMillis(t)); | |
612 break; | |
613 | |
614 case MIDI_POLY_AFTERTOUCH: | |
615 cout << t << ": Polyphonic aftertouch: channel " << ch | |
616 << " pitch " << j->getPitch() | |
617 << " pressure " << j->getData2() << endl; | |
618 break; | |
619 | |
620 case MIDI_CTRL_CHANGE: | |
621 { | |
622 int controller = j->getData1(); | |
623 string name; | |
624 switch (controller) { | |
625 case MIDI_CONTROLLER_BANK_MSB: name = "Bank select MSB"; break; | |
626 case MIDI_CONTROLLER_VOLUME: name = "Volume"; break; | |
627 case MIDI_CONTROLLER_BANK_LSB: name = "Bank select LSB"; break; | |
628 case MIDI_CONTROLLER_MODULATION: name = "Modulation wheel"; break; | |
629 case MIDI_CONTROLLER_PAN: name = "Pan"; break; | |
630 case MIDI_CONTROLLER_SUSTAIN: name = "Sustain"; break; | |
631 case MIDI_CONTROLLER_RESONANCE: name = "Resonance"; break; | |
632 case MIDI_CONTROLLER_RELEASE: name = "Release"; break; | |
633 case MIDI_CONTROLLER_ATTACK: name = "Attack"; break; | |
634 case MIDI_CONTROLLER_FILTER: name = "Filter"; break; | |
635 case MIDI_CONTROLLER_REVERB: name = "Reverb"; break; | |
636 case MIDI_CONTROLLER_CHORUS: name = "Chorus"; break; | |
637 case MIDI_CONTROLLER_NRPN_1: name = "NRPN 1"; break; | |
638 case MIDI_CONTROLLER_NRPN_2: name = "NRPN 2"; break; | |
639 case MIDI_CONTROLLER_RPN_1: name = "RPN 1"; break; | |
640 case MIDI_CONTROLLER_RPN_2: name = "RPN 2"; break; | |
641 case MIDI_CONTROLLER_SOUNDS_OFF: name = "All sounds off"; break; | |
642 case MIDI_CONTROLLER_RESET: name = "Reset"; break; | |
643 case MIDI_CONTROLLER_LOCAL: name = "Local"; break; | |
644 case MIDI_CONTROLLER_ALL_NOTES_OFF: name = "All notes off"; break; | |
645 } | |
646 cout << t << ": Controller change: channel " << ch | |
647 << " controller " << j->getData1(); | |
648 if (name != "") cout << " (" << name << ")"; | |
649 cout << " value " << j->getData2() << endl; | |
650 } | |
651 break; | |
652 | |
653 case MIDI_PROG_CHANGE: | |
654 cout << t << ": Program change: channel " << ch | |
655 << " program " << j->getData1() << endl; | |
656 break; | |
657 | |
658 case MIDI_CHNL_AFTERTOUCH: | |
659 cout << t << ": Channel aftertouch: channel " << ch | |
660 << " pressure " << j->getData1() << endl; | |
661 break; | |
662 | |
663 case MIDI_PITCH_BEND: | |
664 cout << t << ": Pitch bend: channel " << ch | |
665 << " value " << (int)j->getData2() * 128 + (int)j->getData1() << endl; | |
666 break; | |
667 | |
668 case MIDI_SYSTEM_EXCLUSIVE: | |
669 cout << t << ": System exclusive: code " | |
670 << (int)j->getMessageType() << " message length " << | |
671 j->getMetaMessage().length() << endl; | |
672 break; | |
673 | |
674 | |
675 } | |
676 | |
677 | |
678 } | |
679 | |
680 | |
681 } | |
682 | |
683 }//end cannam midi main | |
684 | |
685 */ | |
686 | |
687 |