Mercurial > hg > midi-score-follower
diff hackday/testApp.cpp @ 24:5a11b19906c7
hackday code is added.
author | Andrew N Robertson <andrew.robertson@eecs.qmul.ac.uk> |
---|---|
date | Sat, 03 Dec 2011 17:19:43 +0000 |
parents | |
children | 2a025ea7c793 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hackday/testApp.cpp Sat Dec 03 17:19:43 2011 +0000 @@ -0,0 +1,556 @@ +#include "testApp.h" + +//-------------------------------------------------------------- +void testApp::setup(){ + midiFileName = "../../../data/frerejacques.mid"; + int retVal = cannamMainFunction(); + + cout << "MIDI INPUT EXAMPLE" << endl; + printf("midi in in in"); + ofSetVerticalSync(true); + //ofBackground(255,255,255); + + midiIn.listPorts(); + midiIn.openPort(2); + + transpose = 12; + noteInStream.transposeVal = &transpose; + + noteInStream.startTime = &midiEvents.startTime;//point start time of note in stream to the same time in MIDI events + + noteInStream.factor = &midiEvents.ticksFactor; + printf("TICKS FACTOR %f \n", midiEvents.ticksFactor);//noteInStream->factor) + +// portName = "hello";//midiIn.portNames[2]; +// printf("MIDI PORT %c\n", portName); + cout << "MIDI PORT " << endl;//portName << endl; + + + //midiIn.addListener(this); + ofAddListener(midiIn.newMessageEvent, this, &testApp::newMessage); + + + + playing = false; + + + receiver.setup( PORT ); + + screenWidth = ofGetWidth(); + screenHeight = ofGetHeight(); + midiEvents.screenWidth = &screenWidth; + midiEvents.screenHeight = &screenHeight; + midiEvents.drawTempoMode = false; + ofSetFrameRate(30); +} + +//-------------------------------------------------------------- +void testApp::update(){ + if (playing){ + midiEvents.updatePlayPosition(); + // midiEvents.bayesStruct.updateBestEstimate(); + } +// drawer.tickLocation+=20; + + // check for waiting messages + while( receiver.hasWaitingMessages() ) + { + ofxOscMessage m; + receiver.getNextMessage( &m ); + + if ( m.getAddress() == "/midinoteon" ) + { + int newMidiOnPitch = m.getArgAsInt32(0); + int velocity = m.getArgAsInt32(1); + double time = m.getArgAsFloat(2); + + if (velocity != 0) + midiEvents.newNoteOnEvent(newMidiOnPitch, velocity, time); + + } + + if ( m.getAddress() == "/setSpeedPrior" ) + { + float speedPrior = m.getArgAsFloat(0); + printf("speed prior set to %f\n", speedPrior); + midiEvents.speedPriorValue = speedPrior; + midiEvents.bayesStruct.speedPriorValue = speedPrior; + } + + if ( m.getAddress() == "/startplaying" ) + { + startPlaying(); + } + + if ( m.getAddress() == "/stopplaying" ) + { + stopPlaying(); + } + + + if ( m.getAddress() == "/integratedEstimate" ) + { + midiEvents.bayesStruct.usingIntegratedTempoEstimate = true; + } + + if ( m.getAddress() == "/MAPestimate" ) + { + midiEvents.bayesStruct.usingIntegratedTempoEstimate = false; + } + + + if ( m.getAddress() == "/realtime" ) + { + midiEvents.runningInRealTime = true; + } + + + if ( m.getAddress() == "/offline" ) + { + midiEvents.runningInRealTime = false; + } + + if ( m.getAddress() == "/minimumSpeedRatio" ) + { + + float minSpeed = m.getArgAsFloat(0); + //printf("minimum speed received is %f and max is %f\n", minSpeed, midiEvents.bayesStruct.relativeSpeedLikelihood.getIndexInRealTerms(midiEvents.bayesStruct.relativeSpeedLikelihood.length-1)); + if (minSpeed > 0 && minSpeed < midiEvents.bayesStruct.relativeSpeedLikelihood.getIndexInRealTerms(midiEvents.bayesStruct.relativeSpeedLikelihood.length-1)){ + printf("minimum speed accepted is %f\n", minSpeed); + midiEvents.minimumMatchSpeed = minSpeed; + } + } + + }//end while osc + +} + +void testApp::newMessage(ofxMidiEventArgs &args){ + + int pitch; + if (noteInStream.noteInReceived(args)){ + double timeNow = ofGetElapsedTimeMillis(); + + if (!liveInputPlaying){ + firstNoteTime = timeNow; + liveInputPlaying = true; + startPlaying(); + printf("FIRST LIVE NOTE IS NOW AT TIME %f\n", timeNow); + } + + pitch = args.byteOne + transpose; + + midiEvents.newNoteOnEvent(pitch, args.byteTwo, timeNow - firstNoteTime); + + + int tickTime = midiEvents.getEventTimeTicks(timeNow-firstNoteTime); + IntVector v; + v.push_back(tickTime); + v.push_back(pitch); + v.push_back(args.byteTwo); + noteInStream.midiInputEvents.push_back(v); + noteInStream.midiInputTimes.push_back(timeNow - firstNoteTime); + printf("NOTE %i at time %f at tick time %i\n", pitch, (timeNow - firstNoteTime), tickTime); + } + +// cout << "MIDI message [port: " << args.port << ", channel: " << args.channel << ", status: " << args.status << ", byteOne: " << pitch << ", byteTwo: " << args.byteTwo << ", timestamp: " << args.timestamp << "]" << endl; +} + +//-------------------------------------------------------------- +void testApp::draw(){ + + midiEvents.drawFile(); + + midiEvents.drawMidiFile(noteInStream.midiInputEvents); + +} + +//-------------------------------------------------------------- +void testApp::keyPressed(int key){ + + +// if (key == ' '){ +// startPlaying(); +// } + if (key == '-') + transpose -= 12; + + if (key == '=') + transpose += 12; + + if (key == 'c'){ + double timenow = ofGetElapsedTimeMillis(); + midiEvents.exampleCrossUpdate(); + timenow *= -1; + timenow += ofGetElapsedTimeMillis(); + printf("CROSS UPDATE TOOK %f", timenow); + } + + if (key == OF_KEY_RETURN) + stopPlaying(); + + if (key == OF_KEY_UP){ + if (midiEvents.ticksPerScreen >= 4000) + midiEvents.ticksPerScreen += 2000; + else + midiEvents.ticksPerScreen += 500; + } + + if (key == 'm'){ +// midiEvents.findMatch(84, 0, 10000); + } + + if (key == OF_KEY_DOWN){ + if (midiEvents.ticksPerScreen >= 4000) + midiEvents.ticksPerScreen -= 2000; + else if (midiEvents.ticksPerScreen > 500) + midiEvents.ticksPerScreen -= 500; + } + + if (key == 'w') + midiEvents.printMatchMatrix(); + + if (key == 'k'){ + noteInStream.printNotes(); + } + + if (key == 'p'){ + midiEvents.printNotes(); + } + + if (key == 'l') + midiEvents.bayesStruct.decaySpeedDistribution(100); + + if (key == 't') + midiEvents.drawTempoMode = !midiEvents.drawTempoMode; + + if (key == 'y') + midiEvents.drawPhaseMode = !midiEvents.drawPhaseMode; + + if (key == 'r'){ + noteInStream.reset(); + liveInputPlaying = false; + stopPlaying(); + } + + if (key == 'o'){ + //open audio file + string *filePtr; + filePtr = &midiFileName; + + if (getFilenameFromDialogBox(filePtr)){ + printf("Midifile: Loaded name okay :\n'%s' \n", midiFileName.c_str()); + cannamMainFunction(); + } + } + + + +} + +//-------------------------------------------------------------- +void testApp::keyReleased(int key){ + +} + +//-------------------------------------------------------------- +void testApp::mouseMoved(int x, int y ){ + midiEvents.mouseX = midiEvents.getEventTimeMillis((x * midiEvents.ticksPerScreen)/ screenWidth); +} + +//-------------------------------------------------------------- +void testApp::mouseDragged(int x, int y, int button){ + +} + +//-------------------------------------------------------------- +void testApp::mousePressed(int x, int y, int button){ + +} + +//-------------------------------------------------------------- +void testApp::mouseReleased(int x, int y, int button){ + +} + +//-------------------------------------------------------------- +void testApp::windowResized(int w, int h){ + screenWidth = w; + screenHeight = h; + midiEvents.noteHeight = screenHeight / (float)(midiEvents.noteMaximum - midiEvents.noteMinimum); + +} + + + +void testApp::startPlaying(){ + playing = !playing; + midiEvents.reset(); + midiEvents.setStartPlayingTimes(); + + //this is where we stop and start playing +} + +void testApp::stopPlaying(){ + playing = false; + liveInputPlaying = false; +} + +bool testApp::getFilenameFromDialogBox(string* fileNameToSave){ + //this uses a pointer structure within the loader and returns true if the dialogue box was used successfully + // first, create a string that will hold the URL + string URL; + + // openFile(string& URL) returns 1 if a file was picked + // returns 0 when something went wrong or the user pressed 'cancel' + int response = ofxFileDialogOSX::openFile(URL); + if(response){ + // now you can use the URL + *fileNameToSave = URL; + //printf("\n filename is %s \n", soundFileName.c_str()); + return true; + } + else { + // soundFileName = "OPEN canceled. "; + printf("\n open file cancelled \n"); + return false; + } + + + +} + + + + +int testApp::cannamMainFunction(){ + + + midiEvents.clearAllEvents(); + + //int main(int argc, char **argv) + //{ + // if (argc != 2) { + // cerr << "Usage: midifile <file.mid>" << endl; + // return 1; + // } + + std::string filename = midiFileName;//argv[1]; + +// fileLoader.chopBeginning = true; + fileLoader.loadFile(filename, midiEvents); + +}//new end of load function + + + + + //trying to port to new class + /* + MIDIFileReader fr(filename); + + if (!fr.isOK()) { + std::cerr << "Error: " << fr.getError().c_str() << std::endl; + return 1; + } + + MIDIComposition c = fr.load(); + + switch (fr.getFormat()) { + case MIDI_SINGLE_TRACK_FILE: cout << "Format: MIDI Single Track File" << endl; break; + case MIDI_SIMULTANEOUS_TRACK_FILE: cout << "Format: MIDI Simultaneous Track File" << endl; break; + case MIDI_SEQUENTIAL_TRACK_FILE: cout << "Format: MIDI Sequential Track File" << endl; break; + default: cout << "Format: Unknown MIDI file format?" << endl; break; + } + + cout << "Tracks: " << c.size() << endl; + + int td = fr.getTimingDivision(); + if (td < 32768) { + cout << "Timing division: " << fr.getTimingDivision() << " ppq" << endl; + + midiEvents.pulsesPerQuarternote = fr.getTimingDivision(); + } else { + int frames = 256 - (td >> 8); + int subframes = td & 0xff; + cout << "SMPTE timing: " << frames << " fps, " << subframes << " subframes" << endl; + } + + for (MIDIComposition::const_iterator i = c.begin(); i != c.end(); ++i) { + + cout << "Start of track: " << i->first+1 << endl; + + for (MIDITrack::const_iterator j = i->second.begin(); j != i->second.end(); ++j) { + + unsigned int t = j->getTime(); + int ch = j->getChannelNumber(); + + if (j->isMeta()) { + int code = j->getMetaEventCode(); + string name; + bool printable = true; + switch (code) { + + case MIDI_END_OF_TRACK: + cout << t << ": End of track" << endl; + break; + + case MIDI_TEXT_EVENT: name = "Text"; break; + case MIDI_COPYRIGHT_NOTICE: name = "Copyright"; break; + case MIDI_TRACK_NAME: name = "Track name"; break; + case MIDI_INSTRUMENT_NAME: name = "Instrument name"; break; + case MIDI_LYRIC: name = "Lyric"; break; + case MIDI_TEXT_MARKER: name = "Text marker"; break; + case MIDI_SEQUENCE_NUMBER: name = "Sequence number"; printable = false; break; + case MIDI_CHANNEL_PREFIX_OR_PORT: name = "Channel prefix or port"; printable = false; break; + case MIDI_CUE_POINT: name = "Cue point"; break; + case MIDI_CHANNEL_PREFIX: name = "Channel prefix"; printable = false; break; + case MIDI_SEQUENCER_SPECIFIC: name = "Sequencer specific"; printable = false; break; + case MIDI_SMPTE_OFFSET: name = "SMPTE offset"; printable = false; break; + + case MIDI_SET_TEMPO: + { + int m0 = j->getMetaMessage()[0]; + int m1 = j->getMetaMessage()[1]; + int m2 = j->getMetaMessage()[2]; + long tempo = (((m0 << 8) + m1) << 8) + m2; + + cout << t << ": Tempo: " << 60000000.0 / double(tempo) << endl; + midiEvents.tempo = 60000000.0 / double(tempo); + midiEvents.period = double(tempo)/1000.0; + + printf("period double is %f\n", midiEvents.period); + } + break; + + case MIDI_TIME_SIGNATURE: + { + int numerator = j->getMetaMessage()[0]; + int denominator = 1 << (int)j->getMetaMessage()[1]; + + cout << t << ": Time signature: " << numerator << "/" << denominator << endl; + } + + case MIDI_KEY_SIGNATURE: + { + int accidentals = j->getMetaMessage()[0]; + int isMinor = j->getMetaMessage()[1]; + bool isSharp = accidentals < 0 ? false : true; + accidentals = accidentals < 0 ? -accidentals : accidentals; + cout << t << ": Key signature: " << accidentals << " " + << (isSharp ? + (accidentals > 1 ? "sharps" : "sharp") : + (accidentals > 1 ? "flats" : "flat")) + << (isMinor ? ", minor" : ", major") << endl; + } + + } + + + if (name != "") { + if (printable) { + cout << t << ": File meta event: code " << code + << ": " << name << ": \"" << j->getMetaMessage() + << "\"" << endl; + } else { + cout << t << ": File meta event: code " << code + << ": " << name << ": "; + for (int k = 0; k < j->getMetaMessage().length(); ++k) { + cout << (int)j->getMetaMessage()[k] << " "; + } + } + } + continue; + } + + switch (j->getMessageType()) { + + case MIDI_NOTE_ON: + cout << t << ": Note: channel " << ch + << " duration " << j->getDuration() + << " pitch " << j->getPitch() + << " velocity " << j->getVelocity() + << "event time " << midiEvents.getEventTimeMillis(t) << endl; + v.clear(); + v.push_back(t); + v.push_back(j->getPitch()); + v.push_back(j->getVelocity()); + v.push_back(j->getDuration()); + midiEvents.recordedNoteOnMatrix.push_back(v); + midiEvents.recordedEventTimes.push_back(midiEvents.getEventTimeMillis(t)); + break; + + case MIDI_POLY_AFTERTOUCH: + cout << t << ": Polyphonic aftertouch: channel " << ch + << " pitch " << j->getPitch() + << " pressure " << j->getData2() << endl; + break; + + case MIDI_CTRL_CHANGE: + { + int controller = j->getData1(); + string name; + switch (controller) { + case MIDI_CONTROLLER_BANK_MSB: name = "Bank select MSB"; break; + case MIDI_CONTROLLER_VOLUME: name = "Volume"; break; + case MIDI_CONTROLLER_BANK_LSB: name = "Bank select LSB"; break; + case MIDI_CONTROLLER_MODULATION: name = "Modulation wheel"; break; + case MIDI_CONTROLLER_PAN: name = "Pan"; break; + case MIDI_CONTROLLER_SUSTAIN: name = "Sustain"; break; + case MIDI_CONTROLLER_RESONANCE: name = "Resonance"; break; + case MIDI_CONTROLLER_RELEASE: name = "Release"; break; + case MIDI_CONTROLLER_ATTACK: name = "Attack"; break; + case MIDI_CONTROLLER_FILTER: name = "Filter"; break; + case MIDI_CONTROLLER_REVERB: name = "Reverb"; break; + case MIDI_CONTROLLER_CHORUS: name = "Chorus"; break; + case MIDI_CONTROLLER_NRPN_1: name = "NRPN 1"; break; + case MIDI_CONTROLLER_NRPN_2: name = "NRPN 2"; break; + case MIDI_CONTROLLER_RPN_1: name = "RPN 1"; break; + case MIDI_CONTROLLER_RPN_2: name = "RPN 2"; break; + case MIDI_CONTROLLER_SOUNDS_OFF: name = "All sounds off"; break; + case MIDI_CONTROLLER_RESET: name = "Reset"; break; + case MIDI_CONTROLLER_LOCAL: name = "Local"; break; + case MIDI_CONTROLLER_ALL_NOTES_OFF: name = "All notes off"; break; + } + cout << t << ": Controller change: channel " << ch + << " controller " << j->getData1(); + if (name != "") cout << " (" << name << ")"; + cout << " value " << j->getData2() << endl; + } + break; + + case MIDI_PROG_CHANGE: + cout << t << ": Program change: channel " << ch + << " program " << j->getData1() << endl; + break; + + case MIDI_CHNL_AFTERTOUCH: + cout << t << ": Channel aftertouch: channel " << ch + << " pressure " << j->getData1() << endl; + break; + + case MIDI_PITCH_BEND: + cout << t << ": Pitch bend: channel " << ch + << " value " << (int)j->getData2() * 128 + (int)j->getData1() << endl; + break; + + case MIDI_SYSTEM_EXCLUSIVE: + cout << t << ": System exclusive: code " + << (int)j->getMessageType() << " message length " << + j->getMetaMessage().length() << endl; + break; + + + } + + + } + + + } + +}//end cannam midi main + +*/ + +