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