andrew@24: #include "testApp.h" andrew@24: andrew@27: andrew@27: testApp::testApp(ofxArgs* args){ andrew@27: this->args = args; andrew@27: } andrew@27: andrew@24: //-------------------------------------------------------------- andrew@24: void testApp::setup(){ andrew@27: andrew@27: andrew@27: this->args->printArgs(); andrew@27: this->args->printOpts(); andrew@24: midiFileName = "../../../data/frerejacques.mid"; andrew@27: andrew@27: if (this->args->getCount() > 0){ andrew@27: museScoreFilename = this->args->getString(1); andrew@27: //printf("MUSESCORE FILENAME IS %s\n", museScoreFilename); andrew@27: cout << "running!! " << museScoreFilename << endl; andrew@27: midiFileName = museScoreFilename; andrew@27: } andrew@27: andrew@24: int retVal = cannamMainFunction(); andrew@24: andrew@24: ofSetVerticalSync(true); andrew@24: //ofBackground(255,255,255); andrew@27: midiPort = 2; andrew@24: midiIn.listPorts(); andrew@27: midiIn.openPort(midiPort); andrew@27: midiPortName = ""; andrew@27: //midiPortName = midiIn.portNames(midiPort); andrew@24: andrew@29: transpose = 0; andrew@24: noteInStream.transposeVal = &transpose; andrew@24: andrew@24: noteInStream.startTime = &midiEvents.startTime;//point start time of note in stream to the same time in MIDI events andrew@24: andrew@24: noteInStream.factor = &midiEvents.ticksFactor; andrew@24: printf("TICKS FACTOR %f \n", midiEvents.ticksFactor);//noteInStream->factor) andrew@24: andrew@24: // portName = "hello";//midiIn.portNames[2]; andrew@24: // printf("MIDI PORT %c\n", portName); andrew@24: cout << "MIDI PORT " << endl;//portName << endl; andrew@24: andrew@24: andrew@24: //midiIn.addListener(this); andrew@24: ofAddListener(midiIn.newMessageEvent, this, &testApp::newMessage); andrew@24: andrew@27: andrew@27: verdana30.loadFont("verdana.ttf", 50, true, true); andrew@27: verdana30.setLineHeight(48.0f); andrew@27: verdana30.setLetterSpacing(1.035); andrew@24: andrew@24: playing = false; andrew@30: readyToStart = true; andrew@24: andrew@24: receiver.setup( PORT ); andrew@25: andrew@25: sender.setup( HOST, SEND_PORT ); andrew@24: andrew@24: screenWidth = ofGetWidth(); andrew@24: screenHeight = ofGetHeight(); andrew@24: midiEvents.screenWidth = &screenWidth; andrew@24: midiEvents.screenHeight = &screenHeight; andrew@31: midiEvents.drawTempoMode = true; andrew@24: ofSetFrameRate(30); andrew@25: andrew@25: midiEvents.ticksPerScreen += 4000; andrew@25: lastScoreIndexSent = 0; andrew@27: performanceRating = 0.0; andrew@27: andrew@27: liveInputPlaying = false; andrew@27: lastScoreIndexSent = 0; andrew@27: midiEvents.bestMatchIndex = 0; andrew@25: andrew@24: } andrew@24: andrew@24: //-------------------------------------------------------------- andrew@24: void testApp::update(){ andrew@24: if (playing){ andrew@25: midiEvents.updatePlayPosition();//this fn calls midiEvents.bayesStruct.updateBestEstimate(); andrew@24: } andrew@24: // drawer.tickLocation+=20; andrew@24: andrew@24: // check for waiting messages andrew@24: while( receiver.hasWaitingMessages() ) andrew@24: { andrew@24: ofxOscMessage m; andrew@24: receiver.getNextMessage( &m ); andrew@24: andrew@24: if ( m.getAddress() == "/midinoteon" ) andrew@24: { andrew@26: int newMidiOnPitch = m.getArgAsInt32(0) + transpose; andrew@24: int velocity = m.getArgAsInt32(1); andrew@24: double time = m.getArgAsFloat(2); andrew@24: andrew@26: if (velocity != 0){ andrew@30: if (readyToStart){ andrew@30: startPlaying(); andrew@30: printf("starting to PLAY!!!"); andrew@30: } andrew@31: printf("MIDI NOTE %i \n", newMidiOnPitch); andrew@26: midiEvents.newNoteOnEvent(newMidiOnPitch, velocity, time); andrew@26: noteInStream.newNoteCounted(newMidiOnPitch); andrew@26: } andrew@24: andrew@24: } andrew@24: andrew@24: if ( m.getAddress() == "/setSpeedPrior" ) andrew@24: { andrew@24: float speedPrior = m.getArgAsFloat(0); andrew@24: printf("speed prior set to %f\n", speedPrior); andrew@24: midiEvents.speedPriorValue = speedPrior; andrew@24: midiEvents.bayesStruct.speedPriorValue = speedPrior; andrew@24: } andrew@24: andrew@24: if ( m.getAddress() == "/startplaying" ) andrew@24: { andrew@30: prepareToStartOnNextNote(); andrew@24: } andrew@24: andrew@24: if ( m.getAddress() == "/stopplaying" ) andrew@24: { andrew@24: stopPlaying(); andrew@24: } andrew@24: andrew@24: andrew@24: if ( m.getAddress() == "/integratedEstimate" ) andrew@24: { andrew@24: midiEvents.bayesStruct.usingIntegratedTempoEstimate = true; andrew@24: } andrew@24: andrew@24: if ( m.getAddress() == "/MAPestimate" ) andrew@24: { andrew@24: midiEvents.bayesStruct.usingIntegratedTempoEstimate = false; andrew@24: } andrew@24: andrew@24: andrew@24: if ( m.getAddress() == "/realtime" ) andrew@24: { andrew@24: midiEvents.runningInRealTime = true; andrew@24: } andrew@24: andrew@24: andrew@24: if ( m.getAddress() == "/offline" ) andrew@24: { andrew@24: midiEvents.runningInRealTime = false; andrew@24: } andrew@24: andrew@24: if ( m.getAddress() == "/minimumSpeedRatio" ) andrew@24: { andrew@24: andrew@24: float minSpeed = m.getArgAsFloat(0); andrew@24: //printf("minimum speed received is %f and max is %f\n", minSpeed, midiEvents.bayesStruct.relativeSpeedLikelihood.getIndexInRealTerms(midiEvents.bayesStruct.relativeSpeedLikelihood.length-1)); andrew@24: if (minSpeed > 0 && minSpeed < midiEvents.bayesStruct.relativeSpeedLikelihood.getIndexInRealTerms(midiEvents.bayesStruct.relativeSpeedLikelihood.length-1)){ andrew@24: printf("minimum speed accepted is %f\n", minSpeed); andrew@24: midiEvents.minimumMatchSpeed = minSpeed; andrew@24: } andrew@24: } andrew@32: andrew@32: if ( m.getAddress() == "/maximumSpeedRatio" ) andrew@32: { andrew@32: andrew@32: float maxSpeed = m.getArgAsFloat(0); andrew@32: //printf("minimum speed received is %f and max is %f\n", minSpeed, midiEvents.bayesStruct.relativeSpeedLikelihood.getIndexInRealTerms(midiEvents.bayesStruct.relativeSpeedLikelihood.length-1)); andrew@32: if (maxSpeed > midiEvents.minimumMatchSpeed && maxSpeed <= midiEvents.bayesStruct.relativeSpeedLikelihood.getIndexInRealTerms(midiEvents.bayesStruct.relativeSpeedLikelihood.length-1)){ andrew@32: printf("maximum speed accepted is %f\n", maxSpeed); andrew@32: midiEvents.maximumMatchSpeed = maxSpeed; andrew@32: } andrew@32: } andrew@32: andrew@32: if ( m.getAddress() == "/likelihoodToNoiseRatio" ) andrew@32: { andrew@32: andrew@32: float ratio = m.getArgAsFloat(0); andrew@32: andrew@32: if (ratio > 0.001 && ratio < 0.6){ andrew@32: midiEvents.likelihoodToNoiseRatio = ratio; andrew@32: printf("likelihood for events relative to noise uses ratio %f\n", ratio); andrew@32: } andrew@32: andrew@32: } andrew@24: andrew@24: }//end while osc andrew@30: if (midiEvents.recordedEventTimes.size() > 0) andrew@25: checkNewScoreNote(); andrew@24: andrew@24: } andrew@24: andrew@25: andrew@25: void testApp::checkNewScoreNote(){ andrew@25: if (lastScoreIndexSent != midiEvents.bestMatchIndex){ andrew@25: //then we send out new note andrew@25: sendNoteToMuseScore(); andrew@25: lastScoreIndexSent = midiEvents.bestMatchIndex; andrew@25: findMeasure(); andrew@25: } andrew@25: } andrew@25: andrew@25: void testApp::findMeasure(){ andrew@25: int ticks = midiEvents.recordedNoteOnMatrix[midiEvents.bestMatchIndex][0]; andrew@25: int tmpMeasure = lastMeasureSent; andrew@25: andrew@25: while (lastMeasureSent > 0 && midiEvents.measureVector[lastMeasureSent] > ticks) { andrew@25: lastMeasureSent--; andrew@25: } andrew@25: andrew@25: while (lastMeasureSent < midiEvents.measureVector.size() && midiEvents.measureVector[lastMeasureSent] < ticks) { andrew@25: lastMeasureSent++; andrew@25: } andrew@25: if (lastMeasureSent != tmpMeasure){ andrew@27: //sendMeasureToMuseScore(); andrew@26: performanceRating = noteInStream.calculateTotalScore(midiEvents); andrew@25: } andrew@25: andrew@25: andrew@25: } andrew@25: andrew@26: void testApp::sendBlackNotes(){ andrew@26: ofxOscMessage m; andrew@26: m.setAddress( "/plugin" ); andrew@26: string noteString; andrew@26: noteString = "blacknotes.js"; andrew@26: m.addStringArg( noteString); andrew@26: sender.sendMessage( m ); andrew@26: } andrew@26: andrew@25: void testApp::sendNoteToMuseScore(){ andrew@30: if (midiEvents.recordedNoteOnMatrix.size() > 0){ andrew@25: int ticks = midiEvents.recordedNoteOnMatrix[midiEvents.bestMatchIndex][0]; andrew@25: int pitch = midiEvents.recordedNoteOnMatrix[midiEvents.bestMatchIndex][1]; andrew@31: // printf("sending to muse score %i, %i \n", ticks, pitch); andrew@30: sendNoteDataByOsc(pitch, ticks); andrew@30: } andrew@26: /* andrew@26: ofxOscMessage m; andrew@26: m.setAddress( "/plugin" ); andrew@26: string noteString; andrew@26: noteString = "blackNotes.js"; andrew@26: m.addStringArg( noteString); andrew@26: sender.sendMessage( m ); andrew@26: */ andrew@30: andrew@27: andrew@27: // /color-note 60,3440 andrew@27: andrew@27: //crappy javascript message andrew@27: /* andrew@26: ofxOscMessage m; andrew@26: m.setAddress( "/plugin" ); andrew@26: string noteString; andrew@26: noteString = "coloronenote.js"; andrew@26: noteString += ",myTick,"+ofToString(ticks)+",myPitch,"+ofToString(pitch); andrew@26: // printf("%s\n", noteString); andrew@26: m.addStringArg( noteString); andrew@27: sender.sendMessage( m ); */ andrew@27: andrew@25: andrew@25: // /plugin coloronenote.js mytick 100 mypitch 56; andrew@25: } andrew@25: andrew@27: void testApp::sendNoteDataByOsc(const int& pitch, const int& ticks){ andrew@27: ofxOscMessage m; andrew@27: m.setAddress( "/color-note" ); andrew@27: string noteString; andrew@27: noteString = ofToString(ticks); andrew@27: noteString += ","+ofToString(pitch); andrew@27: m.addStringArg( noteString); andrew@27: sender.sendMessage( m ); andrew@27: } andrew@25: andrew@25: void testApp::sendMeasureToMuseScore(){ andrew@25: andrew@25: printf("sending measure to muse score %i \n", lastMeasureSent); andrew@25: andrew@25: ofxOscMessage m; andrew@25: m.setAddress( "/select-measure" ); andrew@25: m.addIntArg(lastMeasureSent); andrew@25: sender.sendMessage( m ); andrew@25: andrew@25: // /select-measure 6 andrew@25: // /plugin coloronenote.js mytick 100 mypitch 56; andrew@25: } andrew@25: andrew@25: andrew@24: void testApp::newMessage(ofxMidiEventArgs &args){ andrew@24: andrew@24: int pitch; andrew@24: if (noteInStream.noteInReceived(args)){ andrew@24: double timeNow = ofGetElapsedTimeMillis(); andrew@24: andrew@24: if (!liveInputPlaying){ andrew@24: firstNoteTime = timeNow; andrew@24: liveInputPlaying = true; andrew@24: startPlaying(); andrew@24: printf("FIRST LIVE NOTE IS NOW AT TIME %f\n", timeNow); andrew@24: } andrew@24: andrew@24: pitch = args.byteOne + transpose; andrew@24: andrew@24: midiEvents.newNoteOnEvent(pitch, args.byteTwo, timeNow - firstNoteTime); andrew@24: andrew@24: andrew@24: int tickTime = midiEvents.getEventTimeTicks(timeNow-firstNoteTime); andrew@24: IntVector v; andrew@24: v.push_back(tickTime); andrew@24: v.push_back(pitch); andrew@24: v.push_back(args.byteTwo); andrew@25: v.push_back(200);//tmp time til note off happens andrew@24: noteInStream.midiInputEvents.push_back(v); andrew@24: noteInStream.midiInputTimes.push_back(timeNow - firstNoteTime); andrew@25: //printf("NOTE %i at time %f at tick time %i\n", pitch, (timeNow - firstNoteTime), tickTime); andrew@24: } andrew@24: andrew@24: // cout << "MIDI message [port: " << args.port << ", channel: " << args.channel << ", status: " << args.status << ", byteOne: " << pitch << ", byteTwo: " << args.byteTwo << ", timestamp: " << args.timestamp << "]" << endl; andrew@24: } andrew@24: andrew@24: //-------------------------------------------------------------- andrew@24: void testApp::draw(){ andrew@24: andrew@24: midiEvents.drawFile(); andrew@24: andrew@25: string info = "Measure "; andrew@25: info += ofToString(lastMeasureSent); andrew@25: info += " Last note "; andrew@25: info += ofToString(lastScoreIndexSent); andrew@25: andrew@27: ofSetHexColor(0xFF0000); andrew@27: // ofDrawBitmapString(info, 20, 20); andrew@24: midiEvents.drawMidiFile(noteInStream.midiInputEvents); andrew@24: andrew@27: // ofDrawBitmapString("Rating "+ofToString(performanceRating*100), 60, 50); andrew@27: //ofDrawBitmapString("filename "+museScoreFilename, 20, 80); andrew@27: string ratingString = ofToString(performanceRating*100,0)+"%"; andrew@27: if (performanceRating > 0.84) andrew@27: ratingString += "!* *"; andrew@27: string extraText = ""; andrew@27: if (performanceRating > 0.9){ andrew@27: extraText += " pretty good, huh?"; andrew@27: } andrew@27: if (performanceRating > 0.95) andrew@27: extraText = " blimey! "; andrew@27: if (performanceRating > 0.97) andrew@27: extraText = " maestro!"; andrew@27: andrew@27: ratingString += extraText; andrew@27: verdana30.drawString(ratingString, 20, 60); andrew@27: andrew@27: ofSetHexColor(0x000000); andrew@27: ofDrawBitmapString(midiPortName, 20, ofGetHeight() - 20); andrew@27: andrew@24: } andrew@24: andrew@24: //-------------------------------------------------------------- andrew@24: void testApp::keyPressed(int key){ andrew@24: andrew@27: if (key == '.'){ andrew@27: midiPort++; andrew@27: midiIn.openPort(midiPort); andrew@27: } andrew@27: andrew@27: if (key == ',' && midiPort > 0){ andrew@27: midiPort--; andrew@27: midiIn.openPort(midiPort); andrew@27: } andrew@30: andrew@24: if (key == '-') andrew@24: transpose -= 12; andrew@24: andrew@24: if (key == '=') andrew@24: transpose += 12; andrew@24: andrew@24: if (key == 'c'){ andrew@24: double timenow = ofGetElapsedTimeMillis(); andrew@24: midiEvents.exampleCrossUpdate(); andrew@24: timenow *= -1; andrew@24: timenow += ofGetElapsedTimeMillis(); andrew@24: printf("CROSS UPDATE TOOK %f", timenow); andrew@24: } andrew@26: andrew@27: if (key == 'x') andrew@27: sendNoteDataByOsc(60, 0); andrew@27: andrew@26: if (key == OF_KEY_LEFT){ andrew@26: andrew@26: } andrew@26: andrew@26: if (key == OF_KEY_RIGHT) andrew@24: andrew@24: if (key == OF_KEY_RETURN) andrew@24: stopPlaying(); andrew@24: andrew@24: if (key == OF_KEY_UP){ andrew@24: if (midiEvents.ticksPerScreen >= 4000) andrew@24: midiEvents.ticksPerScreen += 2000; andrew@24: else andrew@24: midiEvents.ticksPerScreen += 500; andrew@24: } andrew@24: andrew@24: if (key == 'm'){ andrew@24: // midiEvents.findMatch(84, 0, 10000); andrew@24: } andrew@24: andrew@26: if (key == 'b'){ andrew@26: sendBlackNotes(); andrew@26: } andrew@26: andrew@30: andrew@30: if (key == 'n'){ andrew@30: midiEvents.printInterNoteIntervals(); andrew@30: } andrew@30: andrew@24: if (key == OF_KEY_DOWN){ andrew@24: if (midiEvents.ticksPerScreen >= 4000) andrew@24: midiEvents.ticksPerScreen -= 2000; andrew@24: else if (midiEvents.ticksPerScreen > 500) andrew@24: midiEvents.ticksPerScreen -= 500; andrew@24: } andrew@24: andrew@24: if (key == 'w') andrew@24: midiEvents.printMatchMatrix(); andrew@24: andrew@24: if (key == 'k'){ andrew@24: noteInStream.printNotes(); andrew@24: } andrew@24: andrew@24: if (key == 'p'){ andrew@24: midiEvents.printNotes(); andrew@24: } andrew@24: andrew@24: if (key == 'l') andrew@30: andrew@30: andrew@30: //midiEvents.bayesStruct.decaySpeedDistribution(100); andrew@24: andrew@24: if (key == 't') andrew@24: midiEvents.drawTempoMode = !midiEvents.drawTempoMode; andrew@24: andrew@24: if (key == 'y') andrew@24: midiEvents.drawPhaseMode = !midiEvents.drawPhaseMode; andrew@24: andrew@24: if (key == 'r'){ andrew@24: noteInStream.reset(); andrew@24: liveInputPlaying = false; andrew@24: stopPlaying(); andrew@26: lastMeasureSent = 0; andrew@26: sendMeasureToMuseScore(); andrew@26: sendBlackNotes(); andrew@26: lastScoreIndexSent = 0; andrew@28: performanceRating = 0; andrew@26: andrew@24: } andrew@24: andrew@27: if (key == 'o' || key == 'O'){ andrew@30: loadRecordedMidiFile(); andrew@24: } andrew@24: andrew@24: andrew@24: andrew@24: } andrew@24: andrew@30: void testApp::loadRecordedMidiFile(){ andrew@30: //open audio file andrew@30: string *filePtr; andrew@30: filePtr = &midiFileName; andrew@30: andrew@30: if (getFilenameFromDialogBox(filePtr)){ andrew@30: printf("Midifile: Loaded name okay :\n'%s' \n", midiFileName.c_str()); andrew@30: cannamMainFunction(); andrew@30: } andrew@30: } andrew@30: andrew@24: //-------------------------------------------------------------- andrew@24: void testApp::keyReleased(int key){ andrew@24: andrew@24: } andrew@24: andrew@24: //-------------------------------------------------------------- andrew@24: void testApp::mouseMoved(int x, int y ){ andrew@24: midiEvents.mouseX = midiEvents.getEventTimeMillis((x * midiEvents.ticksPerScreen)/ screenWidth); andrew@24: } andrew@24: andrew@24: //-------------------------------------------------------------- andrew@24: void testApp::mouseDragged(int x, int y, int button){ andrew@24: andrew@24: } andrew@24: andrew@24: //-------------------------------------------------------------- andrew@24: void testApp::mousePressed(int x, int y, int button){ andrew@24: andrew@24: } andrew@24: andrew@24: //-------------------------------------------------------------- andrew@24: void testApp::mouseReleased(int x, int y, int button){ andrew@24: andrew@24: } andrew@24: andrew@24: //-------------------------------------------------------------- andrew@24: void testApp::windowResized(int w, int h){ andrew@24: screenWidth = w; andrew@24: screenHeight = h; andrew@24: midiEvents.noteHeight = screenHeight / (float)(midiEvents.noteMaximum - midiEvents.noteMinimum); andrew@24: andrew@24: } andrew@24: andrew@30: void testApp::prepareToStartOnNextNote(){ andrew@30: readyToStart = true; andrew@30: } andrew@24: andrew@24: andrew@24: void testApp::startPlaying(){ andrew@24: playing = !playing; andrew@24: midiEvents.reset(); andrew@26: noteInStream.reset(); andrew@24: midiEvents.setStartPlayingTimes(); andrew@26: sendBlackNotes(); andrew@30: readyToStart = false; andrew@24: //this is where we stop and start playing andrew@24: } andrew@24: andrew@24: void testApp::stopPlaying(){ andrew@31: //midiEvents.printNoteCounter(); andrew@31: //noteInStream.printTotalCount(); andrew@31: andrew@26: noteInStream.calculateTotalScore(midiEvents); andrew@26: andrew@26: andrew@24: playing = false; andrew@24: liveInputPlaying = false; andrew@25: lastScoreIndexSent = 0; andrew@25: midiEvents.bestMatchIndex = 0; andrew@25: sendNoteToMuseScore(); andrew@26: andrew@24: } andrew@24: andrew@24: bool testApp::getFilenameFromDialogBox(string* fileNameToSave){ andrew@24: //this uses a pointer structure within the loader and returns true if the dialogue box was used successfully andrew@24: // first, create a string that will hold the URL andrew@24: string URL; andrew@24: andrew@24: // openFile(string& URL) returns 1 if a file was picked andrew@24: // returns 0 when something went wrong or the user pressed 'cancel' andrew@24: int response = ofxFileDialogOSX::openFile(URL); andrew@24: if(response){ andrew@24: // now you can use the URL andrew@24: *fileNameToSave = URL; andrew@24: //printf("\n filename is %s \n", soundFileName.c_str()); andrew@24: return true; andrew@24: } andrew@24: else { andrew@24: // soundFileName = "OPEN canceled. "; andrew@24: printf("\n open file cancelled \n"); andrew@24: return false; andrew@24: } andrew@24: andrew@24: andrew@24: andrew@24: } andrew@24: andrew@24: andrew@24: andrew@24: andrew@24: int testApp::cannamMainFunction(){ andrew@24: andrew@24: andrew@24: midiEvents.clearAllEvents(); andrew@24: andrew@24: //int main(int argc, char **argv) andrew@24: //{ andrew@24: // if (argc != 2) { andrew@24: // cerr << "Usage: midifile " << endl; andrew@24: // return 1; andrew@24: // } andrew@24: andrew@24: std::string filename = midiFileName;//argv[1]; andrew@24: andrew@24: // fileLoader.chopBeginning = true; andrew@24: fileLoader.loadFile(filename, midiEvents); andrew@24: andrew@24: }//new end of load function andrew@24: andrew@24: andrew@24: andrew@24: