Mercurial > hg > midi-score-follower
changeset 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 | 032edf186a68 |
children | 2a025ea7c793 |
files | .DS_Store hackday/CannamMidiFileLoader.cpp hackday/CannamMidiFileLoader.h hackday/MidiInputStream.cpp hackday/MidiInputStream.h hackday/midiEventHolder.cpp hackday/midiEventHolder.h hackday/testApp.cpp hackday/testApp.h maxPatchToPlayFiles/playMidiTranscription3.maxpat midiFileReader/MIDIFileReader.h src/BayesianArrayStructure.cpp src/main.cpp src/midiEventHolder.cpp src/testApp.cpp |
diffstat | 15 files changed, 3755 insertions(+), 1166 deletions(-) [+] |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hackday/CannamMidiFileLoader.cpp Sat Dec 03 17:19:43 2011 +0000 @@ -0,0 +1,301 @@ +/* + * CannamMidiFileLoader.cpp + * midi-score-follower + * + * Created by Andrew on 19/08/2011. + * Copyright 2011 QMUL. All rights reserved. + * + */ + +#include "MIDIFileReader.h" +#include "CannamMidiFileLoader.h" + +CannamMidiFileLoader::CannamMidiFileLoader(){ + chopBeginning = true; +} + +int CannamMidiFileLoader::loadFile(std::string& filename, midiEventHolder& myMidiEvents){ + + noteOnIndex = 0; + myMidiEvents.clearAllEvents(); + + setTempoFromMidiValue(500000, myMidiEvents);//default is 120bpm + myMidiEvents.pulsesPerQuarternote = 240;//default + + //int main(int argc, char **argv) + //{ + // if (argc != 2) { + // cerr << "Usage: midifile <file.mid>" << endl; + // return 1; + // } + + // std::string filename = midiFileName;//argv[1]; + + 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) { + if (printMidiInfo) + cout << "Timing division: " << fr.getTimingDivision() << " ppq" << endl; + myMidiEvents.pulsesPerQuarternote = fr.getTimingDivision(); + } else { + int frames = 256 - (td >> 8); + int subframes = td & 0xff; + if (printMidiInfo) + cout << "SMPTE timing: " << frames << " fps, " << subframes << " subframes" << endl; + } + + for (MIDIComposition::const_iterator i = c.begin(); i != c.end(); ++i) { + if (printMidiInfo) + 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; + if (printMidiInfo) + cout << t << ": Tempo: " << 60000000.0 / double(tempo) << endl; + setTempoFromMidiValue(tempo, myMidiEvents); + + + printf("period double is %f\n", myMidiEvents.period); + } + break; + + case MIDI_TIME_SIGNATURE: + { + int numerator = j->getMetaMessage()[0]; + int denominator = 1 << (int)j->getMetaMessage()[1]; + if (printMidiInfo) + 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; + if (printMidiInfo) + 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: + if (printMidiInfo) + cout << t << ": Note: channel " << ch + << " duration " << j->getDuration() + << " pitch " << j->getPitch() + << " velocity " << j->getVelocity() + << "event time " << myMidiEvents.getEventTimeMillis(t) << endl; + + + if (noteOnIndex == 0){ + firstTickTime = t; + } + + noteOnIndex++; + + v.clear(); + + if (!chopBeginning) + v.push_back(t); + else + v.push_back(t - firstTickTime); + + v.push_back(j->getPitch()); + v.push_back(j->getVelocity()); + v.push_back(j->getDuration()); + myMidiEvents.recordedNoteOnMatrix.push_back(v); + + myMidiEvents.noteOnMatches.push_back(false); + + break; + + case MIDI_POLY_AFTERTOUCH: + if (printMidiInfo) + 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; + } + if (printMidiInfo) + cout << t << ": Controller change: channel " << ch + << " controller " << j->getData1(); + if (name != "") cout << " (" << name << ")"; + cout << " value " << j->getData2() << endl; + } + break; + + case MIDI_PROG_CHANGE: + if (printMidiInfo) + cout << t << ": Program change: channel " << ch + << " program " << j->getData1() << endl; + break; + + case MIDI_CHNL_AFTERTOUCH: + if (printMidiInfo) + cout << t << ": Channel aftertouch: channel " << ch + << " pressure " << j->getData1() << endl; + break; + + case MIDI_PITCH_BEND: + if (printMidiInfo) + cout << t << ": Pitch bend: channel " << ch + << " value " << (int)j->getData2() * 128 + (int)j->getData1() << endl; + break; + + case MIDI_SYSTEM_EXCLUSIVE: + if (printMidiInfo) + cout << t << ": System exclusive: code " + << (int)j->getMessageType() << " message length " << + j->getMetaMessage().length() << endl; + break; + + + } + + + } + + + } + if (printMidiInfo) + myMidiEvents.printRecordedEvents(); + +// printf("|||||||||||||||||||||| \n\n\n\n\n\n\n"); + myMidiEvents.reorderMatrixFromNoteTimes(myMidiEvents.recordedNoteOnMatrix); + myMidiEvents.correctTiming(myMidiEvents.recordedNoteOnMatrix); + myMidiEvents.doublecheckOrder(myMidiEvents.recordedNoteOnMatrix); + + createEventTiming(myMidiEvents); + + if (printMidiInfo) + myMidiEvents.printRecordedEvents(); + +}//end cannam midi main + + +void CannamMidiFileLoader::createEventTiming( midiEventHolder& myMidiEvents){ + + long t; + t = myMidiEvents.recordedNoteOnMatrix[0][0]; + firstNoteTime = myMidiEvents.getEventTimeMillis(t); + + for (int i = 0; i < myMidiEvents.recordedNoteOnMatrix.size();i++){ + t = myMidiEvents.recordedNoteOnMatrix[i][0]; + + if (!chopBeginning) + myMidiEvents.recordedEventTimes.push_back(myMidiEvents.getEventTimeMillis(t)); + else { + myMidiEvents.recordedEventTimes.push_back(myMidiEvents.getEventTimeMillis(t) - firstNoteTime); + + } + } + +} + +void CannamMidiFileLoader::setTempoFromMidiValue(long tempo, midiEventHolder& myMidiEvents){ + myMidiEvents.tempo = 60000000.0 / double(tempo); + myMidiEvents.period = double(tempo)/1000.0; + myMidiEvents.ticksFactor = myMidiEvents.pulsesPerQuarternote / myMidiEvents.period; +} + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hackday/CannamMidiFileLoader.h Sat Dec 03 17:19:43 2011 +0000 @@ -0,0 +1,39 @@ +/* + * CannamMidiFileLoader.h + * midi-score-follower + * + * Created by Chris Cannam on 19/08/2011. + * Copyright 2011 QMUL. All rights reserved. + * + */ + +#ifndef CANNAM_MIDI_FILE_LOADER +#define CANNAM_MIDI_FILE_LOADER + +#include "MIDIFileReader.h" +//#include "MIDIEvent.h" +#include "midiEventHolder.h" +using namespace MIDIConstants; + +class CannamMidiFileLoader{ + +public: + CannamMidiFileLoader(); + + int loadFile(std::string& filename, midiEventHolder& myMidiEvents); + + void createEventTiming( midiEventHolder& myMidiEvents); + void setTempoFromMidiValue(long tempo, midiEventHolder& myMidiEvents); + double firstNoteTime; + int firstTickTime; + bool chopBeginning; + + typedef std::vector<int> IntVector; + IntVector v; + int noteOnIndex; + + + bool printMidiInfo; + +}; +#endif \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hackday/MidiInputStream.cpp Sat Dec 03 17:19:43 2011 +0000 @@ -0,0 +1,77 @@ +/* + * MidiInputStream.cpp + * MuseScoreMidiFollower + * + * Created by Andrew on 03/12/2011. + * Copyright 2011 QMUL. All rights reserved. + * + */ + +#include "MidiInputStream.h" + + +MidiInputStream::MidiInputStream(){ + reset(); +} + + +void MidiInputStream::reset(){ + midiInputEvents.clear(); + eventTimesForNote.clear(); + eventTimesForNote.assign (127, 0.0); + midiInputTimes.clear(); +} + +bool MidiInputStream::noteInReceived(ofxMidiEventArgs &args){ +// printf("midi input received port %i, channel %i status %i, byteOne %i, byteTwo %i\n", args.port,args.channel, args.status, newPitch, args.byteTwo); + bool noteOn = false; + int newPitch; + switch (args.status) { + + case 144: + newPitch = (int)args.byteOne; + newPitch += (*transposeVal); + + printf("note on %i", args.byteOne); + if (args.byteTwo){ + printf("volume is %i\n", args.byteTwo); + double time = ofGetElapsedTimeMillis(); + eventTimesForNote[newPitch] = time; + + noteOn = true; + + }else{ + double time = ofGetElapsedTimeMillis(); + time -= eventTimesForNote[newPitch]; + printf(", OFF after %f millis %f ticks\n", time, time * (*factor)); + + int index = endNote(newPitch); + midiInputEvents[index].push_back(time * (*factor)); + } + + break; + default: + break; + } + + return noteOn; + //cout << "MIDI message [port: " << args.port << ", channel: " << args.channel << ", status: " << args.status << ", byteOne: " << newPitch << ", byteTwo: " << args.byteTwo << ", timestamp: " << args.timestamp << "]" << endl; +} + + +int MidiInputStream::endNote(int notePitch){ + int index = midiInputEvents.size()-1; + while (index > 0 && midiInputEvents[index][1] != notePitch){ + index--; + } + printf("found index %i\n", index); + return index; +} + +void MidiInputStream::printNotes(){ + printf("live input \n"); + for (int i = 0;i < midiInputEvents.size();i++){ + printf("ticktime %i :: pitch %i @ millis %f\n", midiInputEvents[i][0], midiInputEvents[i][1], midiInputTimes[i]); + } +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hackday/MidiInputStream.h Sat Dec 03 17:19:43 2011 +0000 @@ -0,0 +1,47 @@ +/* + * MidiInputStream.h + * MuseScoreMidiFollower + * + * Created by Andrew on 03/12/2011. + * Copyright 2011 QMUL. All rights reserved. + * + */ + +#ifndef MIDI_INPUT_STREAM +#define MIDI_INPUT_STREAM + +#include "ofMain.h" +#include "ofxMidi.h" +#include "midiEventHolder.h" +//WOULD BE GOOD TO USE STD CONSTANTS here +//#include "MIDIFileReader.h" +//using namespace MIDIConstants; + +class MidiInputStream{ + +public: + MidiInputStream(); + bool noteInReceived(ofxMidiEventArgs &args); + void reset(); + void printNotes(); + int endNote(int notePitch); + + typedef std::vector<int> IntVector; + typedef std::vector<IntVector> IntMatrix; + + typedef std::vector<double> DoubleVector; + DoubleVector eventTimesForNote; + + IntMatrix midiInputEvents; + DoubleVector midiInputTimes; + IntVector v; + + double* startTime; + midiEventHolder* eventHolder; + + int* transposeVal; + + double* factor; + +}; +#endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hackday/midiEventHolder.cpp Sat Dec 03 17:19:43 2011 +0000 @@ -0,0 +1,955 @@ +/* + * midiEventHolder.cpp + * midiCannamReader3 + * + * Created by Andrew on 19/07/2011. + * Copyright 2011 QMUL. All rights reserved. + * + */ + +#include "midiEventHolder.h" + +midiEventHolder::midiEventHolder(){ +// recordedNoteOnIndex = 0; + + useTempoPrior = false;//puts sine wave round tempo + confidenceWeightingUsed = true; + + //there is option to use MAP estinate or integral in beayesianarraystricture class + + runningInRealTime = true; + bayesStruct.realTimeMode = &runningInRealTime; + + minimumMatchSpeed = 0.0; + maximumMatchSpeed = 2.0; + minimumTimeIntervalForTempoUpdate = 150; + + width = ofGetWidth(); + height = ofGetHeight(); + screenWidth= &width; + screenHeight = &height; + + ticksPerScreen = 4000; + tickLocation = 0; + pulsesPerQuarternote = 240; + noteArrayIndex = 0; + noteMinimum = 30; + noteMaximum = 96; + + + + likelihoodWidth = 100;//using 100 is good + likelihoodToNoiseRatio = 0.08;//was 0.02 on 18/11/11, changing to give more weight to observations + + bayesStruct.speedLikelihoodNoise = 0.1;//was 0.05 + bayesStruct.speedDecayWidth = 20; + bayesStruct.speedDecayAmount = 10; + + + + speedPriorValue = 1.0; + + matchWindowWidth = 12000;//window size for matching in ms + + bayesStruct.resetSize(matchWindowWidth); + bayesStruct.setPositionDistributionScalar(1); + + bayesStruct.resetSpeedSize(200); + bayesStruct.setRelativeSpeedScalar(0.01); + bayesStruct.relativeSpeedPrior.getMaximum(); + //bayesStruct.simpleExample(); + + + speedWindowWidthMillis = 4000; + speedPriorValue = 1.0; + noteHeight = (*screenHeight) / (float)(noteMaximum - noteMinimum); + + + + drawPhaseMode = true; + + printf("lookup index %f value %f\n", bayesStruct.prior.getLookupIndex(100, 30., 10.0), bayesStruct.prior.gaussianLookupTable[(int)bayesStruct.prior.getLookupIndex(100, 30., 10.0)]); +} + + + +void midiEventHolder::reset(){ + //called when we start playing + + noteArrayIndex = 0; + tickLocation = 0; + lastPeriodUpdateTime = getTimeNow(0);//ofGetElapsedTimeMillis(); + bayesStruct.lastEventTime = getTimeNow(0);//ofGetElapsedTimeMillis(); + numberOfScreensIn = 0; +// recordedNoteOnIndex = 0; + bayesStruct.setNewDistributionOffsets(0); + bayesStruct.posterior.offset = 0; + + playedEventTimes.clear(); + playedNoteOnMatrix.clear(); + matchMatrix.clear(); + bestMatchIndex = 0; + + bayesStruct.resetSpeedToOne(); + bayesStruct.setSpeedPrior(speedPriorValue); + setMatchedNotesBackToFalse(); +} + +void midiEventHolder::setMatchedNotesBackToFalse(){ + for (int i = 0;i < noteOnMatches.size();i++) + noteOnMatches[i] = false; +} + +void midiEventHolder::clearAllEvents(){ + recordedNoteOnMatrix.clear(); + matchesFound.clear(); + noteOnMatches.clear(); + recordedEventTimes.clear(); + + //played events: + playedEventTimes.clear(); + playedNoteOnMatrix.clear(); + matchMatrix.clear(); + bestMatchFound.clear(); +} + +void midiEventHolder::printNotes(){ + printf("RECORDED MATRIX\n"); + for (int i = 0;i < recordedNoteOnMatrix.size();i++){ + printf("ticktime %i :: pitch %i @ millis %f\n", recordedNoteOnMatrix[i][0], recordedNoteOnMatrix[i][1], recordedEventTimes[i]); + } +} + + +double midiEventHolder::getEventTimeTicks(double millis){ + return (millis * pulsesPerQuarternote / period); +} + +double midiEventHolder::getEventTimeMillis(double ticks){ + return (period * ticks / (double) pulsesPerQuarternote); +} + +void midiEventHolder::newNoteOnEvent(int pitch, int velocity, double timePlayed){ +// tempoSpeedString = ""; + + //MOVE INTO BAYESSTRUCT?? XXX + //bayesStruct.copyPriorToPosterior(); + //why was this here?? + bayesStruct.prior.copyFromDynamicVector(bayesStruct.posterior);//try the otehr way + //bayesStruct.copyPriorToPosterior(); + //need to get new MAP position and set the offset of the arrays + //currently bestEstimate is the approx for the new MAP position + + + //add the new event to our played information matrix + IntVector v; + v.push_back(pitch); + v.push_back(velocity); + playedNoteOnMatrix.push_back(v); + + + //would update the arrays at this point to show where out current location (phase) and tempo is. +// double timeNow = ofGetElapsedTimeMillis() - startTime; + double timeNow = timePlayed;// - startTime; + recentNoteOnTime = timePlayed; + +// printf("Max time %f OF time %f \n", timePlayed, timeNow); + + playedEventTimes.push_back(timePlayed); + +// double timeDifference = ofGetElapsedTimeMillis() - bayesStruct.lastEventTime; + double timeDifference = timePlayed - bayesStruct.lastEventTime; + + + + //printf("note %i played at %f and last event %f time difference %f and current best estmate %f\n", pitch, timePlayed, bayesStruct.lastEventTime, timeDifference, bayesStruct.bestEstimate); + + //addnoise to the tempo distribution + //bayesStruct.decaySpeedDistribution(timeDifference); + if (timeDifference > 50){ + bayesStruct.addGaussianNoiseToSpeedPosterior(timeDifference * 10 / 100.); +// bayesStruct.addTriangularNoiseToSpeedPosterior(timeDifference * 10 / 100.); + } + + bayesStruct.updateTmpBestEstimate(timeDifference);// debug - didnt work bayesStruct.bestEstimate = bayesStruct.tmpBestEstimate; + bayesStruct.updateBestEstimate(timeDifference); + bayesStruct.lastBestEstimateUpdateTime = getTimeNow(timePlayed); + +// double newMAPestimateTime = bayesStruct.posterior.getIndexInRealTerms(bayesStruct.posterior.MAPestimate); + //was offset + bayesStruct.posterior.MAPestimate; but this doesnt include scalar to convert to millis + + timeString = "Pitch:"+ofToString(pitch); + timeString += ", time now:"+ofToString(timeNow, 1); + timeString += " TD "+ofToString(timeDifference, 1); + timeString += " offset "+ofToString(bayesStruct.posterior.offset , 0); + timeString += " map Est: "+ofToString(bayesStruct.posterior.MAPestimate, 0); +// timeString += " Previous time" + ofToString(newMAPestimateTime,0); + timeString += " speedMap "+ofToString(bayesStruct.relativeSpeedPosterior.integratedEstimate, 2); + timeString += " :: "+ofToString(bayesStruct.relativeSpeedPosterior.getIndexInRealTerms(bayesStruct.relativeSpeedPosterior.integratedEstimate), 2); + +// newMAPestimateTime += (timeDifference * bayesStruct.relativeSpeedPosterior.getIndexInRealTerms(bayesStruct.relativeSpeedPosterior.MAPestimate)); +// timeString += " : Predicted MAP time" + ofToString(newMAPestimateTime,0); + + //then we recalculate the window start based on MAP being central + //then we do the matches on these and the likelihood on these. + + bayesStruct.setNewDistributionOffsets(max(0., bayesStruct.bestEstimate - (bayesStruct.prior.scalar*bayesStruct.prior.arraySize/2))); +// bayesStruct.prior.offset = max(0.,newMAPestimateTime - (bayesStruct.prior.scalar*bayesStruct.prior.arraySize/2)); + + timeString += " \n : new offset " + ofToString(bayesStruct.prior.offset , 0); + timeString += " \n best estimate "+ofToString(bayesStruct.bestEstimate, 1); + timeString += " error "+ofToString(minimumMatchError, 0); + timeString += " map "+ofToString(bayesStruct.relativeSpeedPosterior.integratedEstimate, 1); + timeString += " rel speed "+ofToString(bayesStruct.relativeSpeedPosterior.getIndexInRealTerms(bayesStruct.relativeSpeedPosterior.integratedEstimate), 2); + + + //be able to draw the prior in correct location relative to the midi notes + //this calculates the cross update of all possible speeds and all possible positions + bayesStruct.crossUpdateArrays(bayesStruct.posterior, bayesStruct.relativeSpeedPosterior, timeDifference); + + + timeString += " new OFF "+ofToString(bayesStruct.bestEstimate - (bayesStruct.prior.scalar*bayesStruct.prior.arraySize/2), 1); + timeString += " notearrayindex "+ofToString(noteArrayIndex, 0); + //when this is off teh screen there is a problem somehow XXX + + bayesStruct.posterior.offset = max(0., bayesStruct.bestEstimate - (bayesStruct.prior.scalar*bayesStruct.prior.arraySize/2));// bayesStruct.prior.offset = max(0., bayesStruct.bestEstimate - (bayesStruct.prior.scalar*bayesStruct.prior.arraySize/2)); + + //trying to switch to prior + + + bayesStruct.lastEventTime = timePlayed;//bayesStruct.lastEventTime = ofGetElapsedTimeMillis(); + + //do the cross update to find current posterior for location +// totalConfidence= 0; + int numberOfMatchesFound = findLocalMatches(pitch); + setMatchLikelihoods(numberOfMatchesFound); + bayesStruct.calculatePosterior(); + + //having found matches we have matches for new note and matches for previous notes + if (!confidenceWeightingUsed) + findLocalTempoPairs(); + else + findLocalTempoPairsWeightedForConfidence(); + + //bayesStruct.addGaussianNoiseToSpeedPosterior(10); + +} + +double midiEventHolder::getTimeNow(double eventTime){ + double timeNow = eventTime; + if (runningInRealTime) + timeNow = ofGetElapsedTimeMillis(); + return timeNow; +} + +int midiEventHolder::findLocalMatches(int notePitch){ + + //here we find the matches to the new note within appropriate range + + matchString = ""; + + windowStartTime = max(0.0,(bayesStruct.bestEstimate - matchWindowWidth/2));//was playPositionInMillis +// cout << "best estimate is " << bayesStruct.bestEstimate << endl; + int numberOfMatches = findMatch(notePitch, windowStartTime, windowStartTime + matchWindowWidth); + + + //matchString += " pitch: "+ofToString(notePitch)+" matches "+ofToString(numberOfMatches)+" win start "+ofToString(windowStartTime); + + return numberOfMatches; + + +} + + +void midiEventHolder::setMatchLikelihoods(int numberOfMatches){ +//reset the offset to match the prior + bayesStruct.likelihood.offset = bayesStruct.prior.offset; + bayesStruct.likelihood.zero();//set to zero + + double quantity = likelihoodToNoiseRatio / numberOfMatches; + + for (int i = 0;i < numberOfMatches && matchesFound[i] >= 0 && matchesFound[i] < recordedEventTimes.size();i++){ + // printf("match times %i of %i::%f adding likelihood to %f\n", i, numberOfMatches, recordedEventTimes[matchesFound[i]], recordedEventTimes[matchesFound[i]] - bayesStruct.likelihood.offset); + //this is the vent time since start of file + if (recordedEventTimes[matchesFound[i]] - bayesStruct.likelihood.offset < bayesStruct.likelihood.arraySize){ + // double confidenceMeasure = 0; + // if (totalConfidence > 0) + // confidenceMeasure = bayesStruct.posterior.getValueAtMillis(recordedEventTimes[matchesFound[i]])/totalConfidence; + + bayesStruct.likelihood.addGaussianShape(recordedEventTimes[matchesFound[i]] - bayesStruct.likelihood.offset, likelihoodWidth, quantity);//* confidenceMeasure + }//end if + } + bayesStruct.likelihood.addConstant((1-likelihoodToNoiseRatio)/bayesStruct.likelihood.length); +} + +int midiEventHolder::findMatch(const int& notePitch, const int& startTime, const int& endTime){ + + matchesFound.clear(); + int startIndex = 0; + + if (recordedEventTimes.size() > 0){ + + //get to the right range of events to check in + while (startIndex < recordedEventTimes.size() && recordedEventTimes[startIndex] < startTime) + startIndex++; + + } + + IntVector v; + DoubleVector d; + double tmpError = 100000.;//v high error + + double minimumConfidence = 0; + while (startIndex < recordedEventTimes.size() && recordedEventTimes[startIndex] < endTime){ + if (recordedNoteOnMatrix[startIndex][1] == notePitch){ + + matchesFound.push_back(startIndex); + v.push_back(startIndex); + //so startIndex is registered as a match + + double eventConfidence = bayesStruct.posterior.getValueAtMillis(recordedEventTimes[startIndex]); + if (eventConfidence > minimumConfidence){ + minimumConfidence = eventConfidence; + bestMatchIndex = startIndex; + } + d.push_back(eventConfidence); + + double confidence = eventConfidence;//bayesStruct.posterior.getValueAtMillis(mouseX); + // recordedEventTimes[startIndex]); + // matchString += "["+ofToString(startIndex)+"] = "+ofToString(confidence, 3)+" ."; + + if (abs(recordedEventTimes[startIndex] - bayesStruct.bestEstimate) < tmpError){ + //record the error between expected and observed times + tmpError = abs(recordedEventTimes[startIndex] - bayesStruct.bestEstimate); + minimumMatchError = tmpError;//recordedEventTimes[startIndex] - bayesStruct.bestEstimate; + } + + } + startIndex++; + } + + +// printf("%i MATCHES TO Note %i found\n", (int)matchesFound.size(), notePitch); + int size = matchesFound.size(); + if (size > 0) + noteOnMatches[bestMatchIndex] = true; + + v.insert(v.begin() , (int)size);//at beginning, we list how many matches there are that we have found + d.insert(d.begin() , (double)size); + + //v.push_back(size); + //d.push_back(size); + //for (int i = 0;i < matchesFound.size()+1;i++){ + // v.push_back(matchesFound[i]); + // printf("match %i,[%i] is %i\n", startIndex, i, v[i]); + //} + + + matchMatrix.push_back(v); + matchConfidence.push_back(d); + + //bringing in way to list only the best matches and use these in tempo process + bestMatchFound.push_back(bestMatchIndex); + +// printf("BEST MATCH TO note %i, start time %i, endtime %i, time %i is recorded time %i, confidence %0.2f\n", notePitch, startTime, endTime, (int) recordedEventTimes[bestMatchIndex], minimumConfidence); + + return size; +} + +bool midiEventHolder::checkIfMatchedNote(const int& tmpIndex){ + for (int i = 0;i < matchesFound.size();i++){ + if (matchesFound[i] == tmpIndex) + return true; + } + return false; +} + + + +void midiEventHolder::findLocalTempoPairs(){ + + int currentPlayedIndex = playedNoteOnMatrix.size()-1; + // printf("played %i : %i, vel %i\n", currentPlayedIndex, playedNoteOnMatrix[currentPlayedIndex][0], playedNoteOnMatrix[currentPlayedIndex][1]); + // printMatchesFound(); + // printMatchMatrix(); + // printf("possible notes \n"); + bool needToUpdate = false; + bayesStruct.setLikelihoodToConstant(); + + + for (int i = 0;i < matchMatrix[currentPlayedIndex][0];i++){ + //iterate through the recently matched events - even dodgy matches included + //size, index of match0, index of match1, .... + + + int recordedCurrentIndex = matchMatrix[currentPlayedIndex][i+1]; + + int previousIndex = currentPlayedIndex-1; + + + while (previousIndex >= 0 && playedEventTimes[previousIndex] + speedWindowWidthMillis > playedEventTimes[currentPlayedIndex]) { + double playedTimeDifference = playedEventTimes[currentPlayedIndex] - playedEventTimes[previousIndex]; + + for (int k = 0;k < matchMatrix[previousIndex][0];k++){ + + int recordedPreviousIndex = matchMatrix[previousIndex][k+1]; + + double recordedTimeDifference = recordedEventTimes[recordedCurrentIndex] - recordedEventTimes[recordedPreviousIndex]; + + + //we want the speed of the recording relative to that of the playing live + + double speedRatio = recordedTimeDifference / playedTimeDifference; + if (recordedTimeDifference > minimumTimeIntervalForTempoUpdate && + speedRatio <= maximumMatchSpeed && speedRatio >= minimumMatchSpeed){ + + //adding in a prior that prefers 1 + double priorWeighting = 1; + if (useTempoPrior) + priorWeighting = sin(speedRatio * PI/2); + + + + /* + printf("(%i)", matchMatrix[currentPlayedIndex][i+1]); + printf("[%i] :: ", recordedPreviousIndex); + printf(" rec{%f} vs play(%f) ", recordedTimeDifference, playedTimeDifference); + printf("update on speed ratio %f\n", speedRatio); + */ + // matchString += " speed: "+ofToString(speedRatio, 3); + // commented for debug + + //bayesStruct.updateTempoDistribution(speedRatio, 0.1);//second paramter is confidence in the match + double amount = (1-bayesStruct.speedLikelihoodNoise)/10; + amount *= priorWeighting; + bayesStruct.updateTempoLikelihood(speedRatio, amount); + // tempoSpeedString += ofToString(recordedPreviousIndex) + " "+ ofToString(speedRatio, 2) + " "+ofToString(amount, 2) += " \n"; + needToUpdate = true; + } + // printf("\n"); + } + + previousIndex--; + }//end while previousindex countdown + }//end for loop through possible current matches + + if (needToUpdate) + bayesStruct.updateTempoDistribution(); + + //printf("current speed is %f\n", bayesStruct.relativeSpeedPosterior.getIndexInRealTerms(bayesStruct.relativeSpeedPosterior.MAPestimate)); +} + + +void midiEventHolder::findLocalTempoPairsWeightedForConfidence(){ + bool needToUpdate = false; + + DoubleVector speedIntervalsFound; + + //adapted this to just use the best match for each note + + int currentPlayedIndex = playedNoteOnMatrix.size()-1; + // printf("played %i : %i, vel %i\n", currentPlayedIndex, playedNoteOnMatrix[currentPlayedIndex][0], playedNoteOnMatrix[currentPlayedIndex][1]); + // printMatchesFound(); + // printMatchMatrix(); + // printf("possible notes \n"); + + bayesStruct.setLikelihoodToConstant(); + + int recordedCurrentIndex = bestMatchFound[currentPlayedIndex]; + //we only look at intervals between the current best match and other recent best matched notes + //that is the difference in confidence method + + + //printf("BEST MATCH FOUND for index %i is %i ", currentPlayedIndex, bestMatchFound[currentPlayedIndex]); + + int previousIndex = currentPlayedIndex-1; + + //withing speedwindow i.e. 4 seconds + while (previousIndex >= 0 && playedEventTimes[previousIndex] + speedWindowWidthMillis > playedEventTimes[currentPlayedIndex]) { + double playedTimeDifference = playedEventTimes[currentPlayedIndex] - playedEventTimes[previousIndex]; + + int recordedPreviousIndex = bestMatchFound[previousIndex]; + + double recordedTimeDifference = recordedEventTimes[recordedCurrentIndex] - recordedEventTimes[recordedPreviousIndex]; + + + //we want the speed of the recording relative to that of the playing live + + double speedRatio = recordedTimeDifference / playedTimeDifference; + if (recordedTimeDifference > minimumTimeIntervalForTempoUpdate + && speedRatio < maximumMatchSpeed && speedRatio > minimumMatchSpeed){ + + /* printf("(%i)", previousIndex); + printf("[%i] :: ", recordedPreviousIndex); + // printf(" conf %f & %f ", currentMatchConfidence, previousMatchConfidence); + printf(" rec{%f} vs play(%f) ", recordedTimeDifference, playedTimeDifference); + printf("update on speed ratio %f\n", speedRatio); + */ + // matchString += " speed: "+ofToString(speedRatio, 3); + // commented for debug + + + double priorWeighting = 1; + + if (useTempoPrior) + priorWeighting = sin(speedRatio * PI/2);//adding in a prior that prefers 1.0 speed + + + // double weighting = previousMatchConfidence * currentMatchConfidence ; + double amount = (1-bayesStruct.speedLikelihoodNoise)*priorWeighting/16;//was 9 + + speedIntervalsFound.push_back(speedRatio); + // bayesStruct.updateTempoLikelihood(speedRatio, amount);//second paramter is confidence in the match + + // tempoSpeedString += ofToString(recordedCurrentIndex) + " :: " + ofToString(recordedPreviousIndex); + // tempoSpeedString += " " + ofToString(recordedTimeDifference)+ " " + ofToString(speedRatio, 2) + " "+ofToString(amount, 2) += " \n"; + + needToUpdate = true; + } + // printf("\n"); + + + previousIndex--; + }//end while previousindex countdown + + if (speedIntervalsFound.size() > 0){ + double amount = (1 - bayesStruct.speedLikelihoodNoise) / speedIntervalsFound.size(); + for (int i = 0;i < speedIntervalsFound.size();i++) + bayesStruct.updateTempoLikelihood(speedIntervalsFound[i], amount); + } + + + if (needToUpdate) + bayesStruct.updateTempoDistribution(); + //printf("current speed is %f\n", bayesStruct.relativeSpeedPosterior.getIndexInRealTerms(bayesStruct.relativeSpeedPosterior.MAPestimate)); +} + +/* +void midiEventHolder::findLocalTempoPairsWeightedForConfidence(){ + bool needToUpdate = false; + + //adapted this to just use the best match for each note + + int currentPlayedIndex = playedNoteOnMatrix.size()-1; + // printf("played %i : %i, vel %i\n", currentPlayedIndex, playedNoteOnMatrix[currentPlayedIndex][0], playedNoteOnMatrix[currentPlayedIndex][1]); + // printMatchesFound(); + // printMatchMatrix(); + // printf("possible notes \n"); + + bayesStruct.setLikelihoodToConstant(); + + for (int i = 0;i < matchMatrix[currentPlayedIndex][0];i++){ + + //iterate through the recently matched events - even dodgy matches included + //size, index of match0, index of match1, .... + int recordedCurrentIndex = matchMatrix[currentPlayedIndex][i+1]; + + double currentMatchConfidence = matchConfidence[currentPlayedIndex][i+1];//new confidence + + int previousIndex = currentPlayedIndex-1; + + while (previousIndex >= 0 && playedEventTimes[previousIndex] + speedWindowWidthMillis > playedEventTimes[currentPlayedIndex]) { + double playedTimeDifference = playedEventTimes[currentPlayedIndex] - playedEventTimes[previousIndex]; + + // for (int k = 0;k < matchMatrix[previousIndex][0];k++) + int recordedPreviousIndex = bestMatchFound[previousIndex];//matchMatrix[previousIndex][k+1]; + + //double previousMatchConfidence = matchConfidence[previousIndex][k+1]; + + + double recordedTimeDifference = recordedEventTimes[recordedCurrentIndex] - recordedEventTimes[recordedPreviousIndex]; + + + //we want the speed of the recording relative to that of the playing live + + double speedRatio = recordedTimeDifference / playedTimeDifference; + if (speedRatio <= maximumMatchSpeed && speedRatio >= minimumMatchSpeed){ + + printf("(%i)", matchMatrix[currentPlayedIndex][i+1]); + printf("[%i] :: ", recordedPreviousIndex); + // printf(" conf %f & %f ", currentMatchConfidence, previousMatchConfidence); + printf(" rec{%f} vs play(%f) ", recordedTimeDifference, playedTimeDifference); + printf("update on speed ratio %f\n", speedRatio); + + // matchString += " speed: "+ofToString(speedRatio, 3); + // commented for debug + + + double priorWeighting = 1; + + if (useTempoPrior) + priorWeighting = sin(speedRatio * PI/2);//adding in a prior that prefers 1.0 speed + + + // double weighting = previousMatchConfidence * currentMatchConfidence ; + double amount = (1-bayesStruct.speedLikelihoodNoise)*priorWeighting/10; + bayesStruct.updateTempoLikelihood(speedRatio, amount);//second paramter is confidence in the match + tempoSpeedString += ofToString(recordedPreviousIndex) + " " + ofToString(speedRatio, 2) + " "+ofToString(amount, 2) += " \n"; + + needToUpdate = true; + } + // printf("\n"); + + + previousIndex--; + }//end while previousindex countdown + }//end for loop through possible current matches + + if (needToUpdate) + bayesStruct.updateTempoDistribution(); + //printf("current speed is %f\n", bayesStruct.relativeSpeedPosterior.getIndexInRealTerms(bayesStruct.relativeSpeedPosterior.MAPestimate)); +} +*/ + + +void midiEventHolder::updatePlayPosition(){ + + //in actual fact if we are changing the speed of the play position + //we will need to update this via the file + + //actually time since beginning of file i think + + double timeDifference = 0; + if (runningInRealTime) + timeDifference = ofGetElapsedTimeMillis() - lastPeriodUpdateTime;//elpased - lastperiodupdatetime + + //this is time diff in milliseconds + //then we have + double quarterNoteIntervals = (timeDifference / period); + tickLocation = quarterNoteIntervals * pulsesPerQuarternote; + + playPositionInMillis = timeDifference;//based on updating from when we change period + //this to be added + + if (runningInRealTime) + bayesStruct.updateBestEstimate(timeDifference); + +} + + +void midiEventHolder::drawMidiFile(){ + + //draws midi file on scrolling screen + int size = recordedNoteOnMatrix.size(); + if (size > 0){ + + numberOfScreensIn = floor(bayesStruct.bestEstimate / getEventTimeMillis(ticksPerScreen));//rpounds down on no screens in + + // numberOfScreensIn = tickLocation / ticksPerScreen;//rounds down + timeOffsetForScreen = getEventTimeMillis(numberOfScreensIn * ticksPerScreen); + + while (noteArrayIndex < recordedNoteOnMatrix.size()-1 && tickLocation > recordedNoteOnMatrix[noteArrayIndex][0] ) + noteArrayIndex++; + + + while (noteArrayIndex > 0 && noteArrayIndex < size && tickLocation < recordedNoteOnMatrix[noteArrayIndex][0]) + noteArrayIndex--; + + //need to start where we currently are in file + int maxNoteIndexToPrint = noteArrayIndex; + int minNoteIndexToPrint = min(size-1,noteArrayIndex);//not needed as changed above + + while (maxNoteIndexToPrint < recordedNoteOnMatrix.size() && recordedNoteOnMatrix[maxNoteIndexToPrint][0] < (numberOfScreensIn+1)*ticksPerScreen ) + maxNoteIndexToPrint++; + + while (minNoteIndexToPrint > 0 && recordedNoteOnMatrix[minNoteIndexToPrint][0] > numberOfScreensIn*ticksPerScreen)//&& minNoteIndexToPrint < size + minNoteIndexToPrint--; + + for (int tmpIndex = max(0,minNoteIndexToPrint);tmpIndex < min(maxNoteIndexToPrint, (int)recordedNoteOnMatrix.size());tmpIndex++){ + + ofSetColor(255,255,255); + if (checkIfMatchedNote(tmpIndex)) + ofSetColor(100,100,100);//0,0,255); + else if(noteOnMatches[tmpIndex]){ + ofSetColor(255,0,255);//dark grey + } + else{ + ofSetColor(255,255,255);//255,255,255); + } + + //ofSetColor(255,255,255); + if (tmpIndex == bestMatchIndex) + ofSetColor(255,0,0);//best recent match is in red + + // XXX replace ofgetwidth below + //if (tmpIndex >= 0 && tmpIndex < size) + int xLocation = (float)(recordedNoteOnMatrix[tmpIndex][0] - numberOfScreensIn*ticksPerScreen)*(*screenWidth)/(float)ticksPerScreen; + int duration = (float)(recordedNoteOnMatrix[tmpIndex][3]*(*screenWidth))/(float)ticksPerScreen; + + + int yLocation = (*screenHeight) - ((recordedNoteOnMatrix[tmpIndex][1] - noteMinimum )*(*screenHeight)/ (float)(noteMaximum - noteMinimum)); + ofRect(xLocation,yLocation, duration, noteHeight); + + } + + + int xLocation;// = getLocationFromTicks(tickLocation); + // ofLine(xLocation, 0, xLocation, (*screenHeight)); + + //orange line at best estimate + xLocation = getLocationFromMillis(bayesStruct.bestEstimate); + ofSetColor(80,80,80);//250,100,0); + ofLine(xLocation, 0, xLocation, (*screenHeight)); + + xLocation = getLocationFromMillis(bayesStruct.tmpBestEstimate); + ofSetColor(150,150,150);//250,100,0); + ofLine(xLocation, 0, xLocation, (*screenHeight)); + + + //lines where matching window start and end are + ofSetColor(0);//0,100,255); + xLocation = getLocationFromMillis(windowStartTime); + ofLine(xLocation, 0, xLocation, (*screenHeight)); + xLocation = getLocationFromMillis(windowStartTime+matchWindowWidth); + ofLine(xLocation, 0, xLocation, (*screenHeight)); + + + int maxSize = recordedNoteOnMatrix[size-1][0]; + + // ofDrawBitmapString(tempoSpeedString, 20, 20); + /* string indexString = "num screens in "+ofToString(numberOfScreensIn)+"; min index to print "+ofToString(minNoteIndexToPrint)+", max index to print "+ofToString(maxNoteIndexToPrint); + indexString += " size "+ofToString(size)+" tick loc "+ofToString(tickLocation)+" max size "+ofToString(maxSize); + ofDrawBitmapString(indexString, 20, 40); + */ + } + + //ofDrawBitmapString(ofToString(timeOffsetForScreen, 1), 20,20); + + //ofDrawBitmapString(timeString, 20, 60); + + +} + + + +void midiEventHolder::drawMidiFile(IntMatrix& midiFileToDraw){ + + //draws midi file on scrolling screen + int size = midiFileToDraw.size(); + if (size > 0){ + + numberOfScreensIn = floor(bayesStruct.bestEstimate / getEventTimeMillis(ticksPerScreen));//rpounds down on no screens in + + // numberOfScreensIn = tickLocation / ticksPerScreen;//rounds down + timeOffsetForScreen = getEventTimeMillis(numberOfScreensIn * ticksPerScreen); + + while (noteArrayIndex < midiFileToDraw.size()-1 && tickLocation > midiFileToDraw[noteArrayIndex][0] ) + noteArrayIndex++; + + + while (noteArrayIndex > 0 && noteArrayIndex < size && tickLocation < midiFileToDraw[noteArrayIndex][0]) + noteArrayIndex--; + + //need to start where we currently are in file + int maxNoteIndexToPrint = noteArrayIndex; + int minNoteIndexToPrint = min(size-1,noteArrayIndex);//not needed as changed above + + while (maxNoteIndexToPrint < midiFileToDraw.size() && midiFileToDraw[maxNoteIndexToPrint][0] < (numberOfScreensIn+1)*ticksPerScreen ) + maxNoteIndexToPrint++; + + while (minNoteIndexToPrint > 0 && midiFileToDraw[minNoteIndexToPrint][0] > numberOfScreensIn*ticksPerScreen)//&& minNoteIndexToPrint < size + minNoteIndexToPrint--; + + for (int tmpIndex = max(0,minNoteIndexToPrint);tmpIndex < min(maxNoteIndexToPrint, (int)midiFileToDraw.size());tmpIndex++){ + + ofSetColor(255,0,255); + /* + if (checkIfMatchedNote(tmpIndex)) + ofSetColor(100,100,100);//0,0,255); + else if(noteOnMatches[tmpIndex]){ + ofSetColor(255,0,255);//dark grey + } + else{ + ofSetColor(255,255,255);//255,255,255); + } + */ + //ofSetColor(255,255,255); + if (tmpIndex == bestMatchIndex) + ofSetColor(255,0,0);//best recent match is in red + + // XXX replace ofgetwidth below + //if (tmpIndex >= 0 && tmpIndex < size) + int xLocation = (float)(midiFileToDraw[tmpIndex][0] - numberOfScreensIn*ticksPerScreen)*(*screenWidth)/(float)ticksPerScreen; + int duration = (float)(midiFileToDraw[tmpIndex][3]*(*screenWidth))/(float)ticksPerScreen; + + + int yLocation = (*screenHeight) - ((midiFileToDraw[tmpIndex][1] - noteMinimum )*(*screenHeight)/ (float)(noteMaximum - noteMinimum)); + ofRect(xLocation,yLocation, duration, noteHeight); + + } + + + + } + + + +} + + + +void midiEventHolder::drawFile(){ + drawMidiFile(); + + +// bayesStruct.drawArrays(); + +// ofSetColor(200,200,0); +// bayesStruct.prior.drawConstrainedVector(0, bayesStruct.prior.arraySize, 400, 800); + + //need to draw arrays within correct timescope + if (drawPhaseMode) + bayesStruct.drawArraysRelativeToTimeframe(timeOffsetForScreen, timeOffsetForScreen + getEventTimeMillis(ticksPerScreen)); + + if (drawTempoMode) + bayesStruct.drawTempoArrays(); + + + ofSetColor(0, 0, 0); + //ofDrawBitmapString(matchString, 20, ofGetHeight() - 20); + + double confidence = bayesStruct.posterior.getValueAtMillis(mouseX); +/* + string mouseString = "mouseX "+ofToString(confidence, 3)+" ."; + ofDrawBitmapString(mouseString, 20 , ofGetHeight() - 40); + + string mouseString = "updateCounter "+ofToString(bayesStruct.updateCounter); + ofDrawBitmapString(mouseString, 20 , ofGetHeight() - 40); + + string infostring = "speed "+ofToString(bayesStruct.relativeSpeedPosterior.getIndexInRealTerms(bayesStruct.relativeSpeedPosterior.MAPestimate), 3); + ofDrawBitmapString(infostring, 20 , ofGetHeight() - 60); +*/ + } + +int midiEventHolder::getLocationFromTicks(double tickPosition){ + return (int)((float)(tickPosition - numberOfScreensIn*ticksPerScreen)*(*screenWidth)/(float)ticksPerScreen); +} + +int midiEventHolder::getLocationFromMillis(double millisPosition){ + //(getEventTimeTicks(windowStartTime+matchWindowWidth) - numberOfScreensIn*ticksPerScreen)*(*screenWidth) / (double)ticksPerScreen + return (millisPosition - timeOffsetForScreen)*(*screenWidth)/getEventTimeMillis(ticksPerScreen); +} + + +void midiEventHolder::exampleCrossUpdate(){ + + bayesStruct.crossUpdateArrays(bayesStruct.posterior, bayesStruct.relativeSpeedPosterior, 200); + +} + + +void midiEventHolder::setStartPlayingTimes(){ + lastPeriodUpdateTime = getTimeNow(0);//ofGetElapsedTimeMillis(); + startTime = lastPeriodUpdateTime; + +/* + bayesStruct.lastEventTime = 0;//ofGetElapsedTimeMillis(); + bayesStruct.bestEstimate = 0; + bayesStruct.resetArrays(); + bayesStruct.lastBestEstimateUpdateTime = ofGetElapsedTimeMillis(); +*/ + bayesStruct.setStartPlaying(); + matchString = ""; +} + + +void midiEventHolder::printMatchMatrix(){ + printf("match matrix:\n"); + for (int i = 0;i < matchMatrix.size();i++){ + for (int k = 0;k < matchMatrix[i].size();k++){ + printf("%i , ", matchMatrix[i][k]); + } + printf("\n"); + } + +} + + + +void midiEventHolder::printRecordedEvents(){ + printf("Recorded Events:\n"); + for (int i = 0;i < recordedNoteOnMatrix.size();i++){ + for (int k = 0;k < recordedNoteOnMatrix[i].size();k++){ + printf("[%i] = %i ,", i, recordedNoteOnMatrix[i][k]); + } + if (i < recordedEventTimes.size()) + printf("time %f \n", recordedEventTimes[i]); + else + printf("\n"); + } + +} + + + +void midiEventHolder::reorderMatrixFromNoteTimes(IntMatrix& noteOnMatrix){ + double currentTime = -19999.; + for (int i = 0;i < noteOnMatrix.size();i++){ + int nextIndex = getIndexOfMinimumAboveTime(currentTime, noteOnMatrix); + // cout << "index of min time " << currentTime << " is " << nextIndex << " at time " << noteOnMatrix[nextIndex][0] << endl; + + if (nextIndex >= 0 && nextIndex > i && noteOnMatrix[nextIndex][0] < noteOnMatrix[i][0] ){ + //which it should be + // cout << " index " << nextIndex << " at time " << noteOnMatrix[nextIndex][0] << " swaps with inex " << i << " at time " << noteOnMatrix[i][0] << endl; + noteOnMatrix[i].swap(noteOnMatrix[nextIndex]); + currentTime = noteOnMatrix[i][0]; + } + + } + + //printRecordedEvents(); + +} + + + + +void midiEventHolder::doublecheckOrder(IntMatrix& noteOnMatrix){ + + for (int i = 0;i < noteOnMatrix.size();i++){ + int nextIndex = getIndexOfMinimumAboveIndex(i, noteOnMatrix); + if (nextIndex > i){ + noteOnMatrix[i].swap(noteOnMatrix[nextIndex]); + } + } +} + +int midiEventHolder::getIndexOfMinimumAboveIndex(const int& index, IntMatrix& noteOnMatrix){ + int returnIndex = index; + int min = noteOnMatrix[index][0]; + for (int i = index;i < noteOnMatrix.size();i++){ + if (noteOnMatrix[i][0] < min){ + returnIndex = i; + min = noteOnMatrix[i][0]; + } + } + return returnIndex; +} + + +int midiEventHolder::getIndexOfMinimumAboveTime(const double& time, IntMatrix& noteOnMatrix){ + int index = 0; + double minimumTime = 100000000.; + int bestIndex = -1; + while (index < noteOnMatrix.size()){ + + if (noteOnMatrix[index][0] > time && noteOnMatrix[index][0] < minimumTime){ + bestIndex = index; + minimumTime = noteOnMatrix[index][0]; + } + index++; + } + return bestIndex; +} + + +void midiEventHolder::correctTiming(IntMatrix& noteOnMatrix){ + + if (noteOnMatrix.size() > 0 && noteOnMatrix[0][0] < 0) { + int offset = noteOnMatrix[0][0]; + for (int i = 0;i < noteOnMatrix.size();i++){ + noteOnMatrix[i][0] -= offset; + } + } + +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hackday/midiEventHolder.h Sat Dec 03 17:19:43 2011 +0000 @@ -0,0 +1,147 @@ +/* + * midiEventHolder.h + * midiCannamReader3 + * + * Created by Andrew on 19/07/2011. + * Copyright 2011 QMUL. All rights reserved. + * + */ +#ifndef MIDI_EVENT_HOLDER +#define MIDI_EVENT_HOLDER + +#include "ofMain.h" +#include "BayesianArrayStructure.h" + +class midiEventHolder{ + +public: + + midiEventHolder(); + void printNotes(); + + typedef std::vector<int> IntVector; + typedef std::vector<IntVector> IntMatrix; + + typedef std::vector<bool> BoolVector; + + typedef std::vector<double> DoubleVector; + typedef std::vector<DoubleVector> DoubleMatrix; + + //the rehearsal version + IntMatrix recordedNoteOnMatrix;//note, velocity, duration + DoubleVector recordedEventTimes; + + IntVector matchesFound; + BoolVector noteOnMatches; + + void drawMidiFile(IntMatrix& midiFileToDraw); + +// int recordedNoteOnIndex; + + + IntMatrix playedNoteOnMatrix; + DoubleVector playedEventTimes; + int playedNoteIndex; + IntMatrix matchMatrix; + IntVector bestMatchFound; + + DoubleMatrix matchConfidence; + double totalConfidence; + + double mouseX; + + void clearAllEvents(); + bool drawTempoMode, drawPhaseMode; + + double minimumMatchSpeed , maximumMatchSpeed; + + double period, pulsesPerQuarternote; + double getEventTimeMillis(double ticks); + double getEventTimeTicks(double millis); + + int getLocationFromTicks(double tickPosition); + int getLocationFromMillis(double millisPosition); + + double getTimeNow(double eventTime); + bool runningInRealTime; + + double windowStartTime; + + //functions for finding match to incoming note + void newNoteOnEvent(int pitch, int velocity, double timePlayed); + int findLocalMatches(int notePitch); + bool checkIfMatchedNote(const int& tmpIndex); + int findMatch(const int& notePitch, const int& startTime, const int& endTime); + + + void findLocalTempoPairs(); + void findLocalTempoPairsWeightedForConfidence(); + + double likelihoodWidth; + double likelihoodToNoiseRatio; + + void printMatchMatrix(); + void printRecordedEvents(); + + void setMatchLikelihoods(int numberOfMatches); + + void setStartPlayingTimes(); + void setSpeedPrior(double speedPriorValue); + + int width, height; + ///// + string matchString; + void updatePlayPosition(); + + DoubleMatrix beatPeriodMatrix; + + void drawFile(); + void drawMidiFile(); + void reset(); + void setMatchedNotesBackToFalse(); + + int ticksPerScreen; + int tickLocation; + int numberOfScreensIn; + int noteArrayIndex; + + int matchWindowWidth; + + int noteMinimum, noteMaximum; + int* screenWidth; + int* screenHeight; + float noteHeight; + float tempo; + double lastPeriodUpdateTime; + + double playPositionInMillis; + + double timeOffsetForScreen; + + double recentNoteOnTime; + + void exampleCrossUpdate(); + BayesianArrayStructure bayesStruct; + + double speedPriorValue; + int bestMatchIndex; + string timeString; + double startTime; + int speedWindowWidthMillis; + + bool confidenceWeightingUsed; + + double minimumMatchError;//recent best error between observed note and aligned midi file + + void reorderMatrixFromNoteTimes(IntMatrix& noteOnMatrix); + int getIndexOfMinimumAboveTime(const double& time, IntMatrix& noteOnMatrix); + void correctTiming(IntMatrix& noteOnMatrix); + void doublecheckOrder(IntMatrix& noteOnMatrix); + int getIndexOfMinimumAboveIndex(const int& index, IntMatrix& noteOnMatrix); + bool useTempoPrior; + string tempoSpeedString; + int minimumTimeIntervalForTempoUpdate; + + double ticksFactor; +}; +#endif \ No newline at end of file
--- /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 + +*/ + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/hackday/testApp.h Sat Dec 03 17:19:43 2011 +0000 @@ -0,0 +1,103 @@ +#ifndef _TEST_APP +#define _TEST_APP + + +//midieventholder - newMidiEvents() sent there +//create cannamMidiLoader for cannamMainfunction + + +//check new prior offset function - how is used? + + + +//check the widening function - adding decay noise +//ticksperscreen could be better as millis per screen + + + +//uses ftmMidiPlay in max5 via osc to communicate notes in + +#include "ofMain.h" + +#include "MIDIFileReader.h" +#include "ofxFileDialogOSX.h" +#include "drawMidiNotes.h" +#include "DynamicBayesianArray.h" +#include "CannamMidiFileLoader.h" +#include <iostream> +#include "midiEventHolder.h" +#include "ofxMidiIn.h" +#include "ofxOsc.h" +#include "MidiInputStream.h" + + +#define PORT 12121 + +using namespace std; +using namespace MIDIConstants; + +class testApp : public ofBaseApp{ + + public: + void setup(); + void update(); + void draw(); + + void keyPressed (int key); + void keyReleased(int key); + void mouseMoved(int x, int y ); + void mouseDragged(int x, int y, int button); + void mousePressed(int x, int y, int button); + void mouseReleased(int x, int y, int button); + void windowResized(int w, int h); + + void startPlaying(); + void stopPlaying(); + bool getFilenameFromDialogBox(string* fileNameToSave); + + typedef std::vector<int> IntVector; + typedef std::vector<double> DoubleVector; +// typedef std::vector<IntVector> IntMatrix; + IntVector v; + + midiEventHolder midiEvents; + + int cannamMainFunction(); + string midiFileName; + + bool playing; + //drawMidiNotes drawer; + +// BayesianArrayStructure bayesStruct; + + int screenWidth, screenHeight; + CannamMidiFileLoader fileLoader; + + //MIDI INPUT + // vars + int port; + int id; + int value; + double timestamp; + char msg[255]; + string portName; + + // midi addon + ofxMidiIn midiIn; + // this is your listener function + void newMessage(ofxMidiEventArgs &args); + + MidiInputStream noteInStream; + + double firstNoteTime; + bool liveInputPlaying; + double timePlayed; + int transpose; +private: + ofxOscReceiver receiver; + + + +}; + +#endif
--- a/maxPatchToPlayFiles/playMidiTranscription3.maxpat Wed Nov 30 12:35:04 2011 +0000 +++ b/maxPatchToPlayFiles/playMidiTranscription3.maxpat Sat Dec 03 17:19:43 2011 +0000 @@ -1,9 +1,9 @@ { "patcher" : { "fileversion" : 1, - "rect" : [ 810.0, 73.0, 1089.0, 872.0 ], + "rect" : [ 591.0, 44.0, 1089.0, 872.0 ], "bglocked" : 0, - "defrect" : [ 810.0, 73.0, 1089.0, 872.0 ], + "defrect" : [ 591.0, 44.0, 1089.0, 872.0 ], "openrect" : [ 0.0, 0.0, 0.0, 0.0 ], "openinpresentation" : 1, "default_fontsize" : 10.0, @@ -20,15 +20,214 @@ "devicewidth" : 0.0, "boxes" : [ { "box" : { + "maxclass" : "newobj", + "text" : "loadmess 1", + "fontname" : "Verdana", + "patching_rect" : [ -28.0, 309.0, 68.0, 19.0 ], + "numinlets" : 1, + "fontsize" : 10.0, + "id" : "obj-28", + "numoutlets" : 1, + "outlettype" : [ "" ] + } + + } +, { + "box" : { + "maxclass" : "message", + "text" : "146 59 0", + "fontname" : "Verdana", + "presentation_rect" : [ 10.0, 226.0, 95.0, 17.0 ], + "patching_rect" : [ 7.0, 452.0, 95.0, 17.0 ], + "numinlets" : 2, + "presentation" : 1, + "fontsize" : 10.0, + "id" : "obj-50", + "numoutlets" : 1, + "outlettype" : [ "" ] + } + + } +, { + "box" : { + "maxclass" : "comment", + "text" : "MIDI FLUSH", + "fontname" : "Verdana", + "presentation_rect" : [ 272.0, 304.0, 150.0, 19.0 ], + "patching_rect" : [ 969.0, 247.0, 150.0, 19.0 ], + "numinlets" : 1, + "presentation" : 1, + "fontsize" : 10.0, + "id" : "obj-57", + "numoutlets" : 0 + } + + } +, { + "box" : { + "maxclass" : "button", + "patching_rect" : [ 261.0, 352.0, 20.0, 20.0 ], + "numinlets" : 1, + "id" : "obj-47", + "numoutlets" : 1, + "outlettype" : [ "bang" ] + } + + } +, { + "box" : { + "maxclass" : "newobj", + "text" : "delay 60", + "fontname" : "Verdana", + "patching_rect" : [ 261.0, 386.0, 54.0, 19.0 ], + "numinlets" : 2, + "fontsize" : 10.0, + "id" : "obj-42", + "numoutlets" : 1, + "outlettype" : [ "bang" ] + } + + } +, { + "box" : { + "maxclass" : "toggle", + "patching_rect" : [ 261.0, 410.0, 20.0, 20.0 ], + "numinlets" : 1, + "id" : "obj-39", + "numoutlets" : 1, + "outlettype" : [ "int" ] + } + + } +, { + "box" : { + "maxclass" : "newobj", + "text" : "gate", + "fontname" : "Verdana", + "patching_rect" : [ 261.0, 438.0, 33.0, 19.0 ], + "numinlets" : 2, + "fontsize" : 10.0, + "id" : "obj-21", + "numoutlets" : 1, + "outlettype" : [ "" ] + } + + } +, { + "box" : { + "maxclass" : "message", + "text" : "/integratedEstimate", + "fontname" : "Verdana", + "presentation_rect" : [ 364.0, 375.0, 108.0, 17.0 ], + "patching_rect" : [ 793.0, 807.0, 108.0, 17.0 ], + "numinlets" : 2, + "presentation" : 1, + "fontsize" : 10.0, + "id" : "obj-43", + "numoutlets" : 1, + "outlettype" : [ "" ] + } + + } +, { + "box" : { + "maxclass" : "message", + "text" : "/MAPestimate", + "fontname" : "Verdana", + "patching_rect" : [ 768.0, 865.0, 80.0, 17.0 ], + "numinlets" : 2, + "fontsize" : 10.0, + "id" : "obj-40", + "numoutlets" : 1, + "outlettype" : [ "" ] + } + + } +, { + "box" : { + "maxclass" : "newobj", + "text" : "sel 0 1", + "fontname" : "Verdana", + "patching_rect" : [ 698.0, 826.0, 46.0, 19.0 ], + "numinlets" : 1, + "fontsize" : 10.0, + "id" : "obj-38", + "numoutlets" : 3, + "outlettype" : [ "bang", "bang", "" ] + } + + } +, { + "box" : { + "maxclass" : "message", + "text" : "/integratedEstimate", + "fontname" : "Verdana", + "patching_rect" : [ 646.0, 865.0, 110.0, 17.0 ], + "numinlets" : 2, + "fontsize" : 10.0, + "id" : "obj-35", + "numoutlets" : 1, + "outlettype" : [ "" ] + } + + } +, { + "box" : { + "maxclass" : "toggle", + "presentation_rect" : [ 364.0, 350.0, 20.0, 20.0 ], + "patching_rect" : [ 698.0, 796.0, 20.0, 20.0 ], + "numinlets" : 1, + "presentation" : 1, + "id" : "obj-22", + "numoutlets" : 1, + "outlettype" : [ "int" ] + } + + } +, { + "box" : { + "maxclass" : "newobj", + "text" : "prepend /minimumSpeedRatio", + "fontname" : "Verdana", + "presentation_rect" : [ 134.0, 463.0, 164.0, 19.0 ], + "patching_rect" : [ 685.0, 657.0, 164.0, 19.0 ], + "numinlets" : 1, + "presentation" : 1, + "fontsize" : 10.0, + "id" : "obj-13", + "numoutlets" : 1, + "outlettype" : [ "" ] + } + + } +, { + "box" : { + "maxclass" : "flonum", + "fontname" : "Verdana", + "minimum" : 0.0, + "presentation_rect" : [ 134.0, 436.0, 50.0, 19.0 ], + "patching_rect" : [ 685.0, 630.0, 50.0, 19.0 ], + "numinlets" : 1, + "presentation" : 1, + "fontsize" : 10.0, + "id" : "obj-12", + "maximum" : 2.0, + "numoutlets" : 2, + "outlettype" : [ "float", "bang" ] + } + + } +, { + "box" : { "maxclass" : "message", "text" : "0", - "patching_rect" : [ 679.0, 320.0, 32.5, 17.0 ], + "fontname" : "Verdana", + "patching_rect" : [ 86.0, 135.0, 32.5, 17.0 ], "numinlets" : 2, "fontsize" : 10.0, + "id" : "obj-41", "numoutlets" : 1, - "outlettype" : [ "" ], - "id" : "obj-41", - "fontname" : "Verdana" + "outlettype" : [ "" ] } } @@ -36,28 +235,28 @@ "box" : { "maxclass" : "newobj", "text" : "loadmess 250", - "patching_rect" : [ 820.0, 337.0, 80.0, 19.0 ], + "fontname" : "Verdana", + "patching_rect" : [ 141.0, 150.0, 80.0, 19.0 ], "numinlets" : 1, "fontsize" : 10.0, + "id" : "obj-37", "numoutlets" : 1, - "outlettype" : [ "" ], - "id" : "obj-37", - "fontname" : "Verdana" + "outlettype" : [ "" ] } } , { "box" : { "maxclass" : "number", - "patching_rect" : [ 820.0, 360.0, 50.0, 19.0 ], + "fontname" : "Verdana", + "presentation_rect" : [ 583.0, 228.0, 50.0, 19.0 ], + "patching_rect" : [ 141.0, 173.0, 50.0, 19.0 ], + "numinlets" : 1, "presentation" : 1, - "numinlets" : 1, "fontsize" : 10.0, + "id" : "obj-36", "numoutlets" : 2, - "outlettype" : [ "int", "bang" ], - "presentation_rect" : [ 583.0, 228.0, 50.0, 19.0 ], - "id" : "obj-36", - "fontname" : "Verdana" + "outlettype" : [ "int", "bang" ] } } @@ -67,27 +266,27 @@ "text" : "iterate through notes when used offline", "linecount" : 2, "presentation_linecount" : 2, + "fontname" : "Verdana", + "presentation_rect" : [ 550.0, 197.0, 150.0, 31.0 ], "patching_rect" : [ 550.0, 207.0, 150.0, 31.0 ], + "numinlets" : 1, "presentation" : 1, - "numinlets" : 1, "fontsize" : 10.0, - "numoutlets" : 0, - "presentation_rect" : [ 550.0, 197.0, 150.0, 31.0 ], "id" : "obj-34", - "fontname" : "Verdana" + "numoutlets" : 0 } } , { "box" : { "maxclass" : "toggle", - "patching_rect" : [ 768.0, 352.0, 20.0, 20.0 ], + "presentation_rect" : [ 523.0, 204.0, 20.0, 20.0 ], + "patching_rect" : [ 89.0, 165.0, 20.0, 20.0 ], + "numinlets" : 1, "presentation" : 1, - "numinlets" : 1, + "id" : "obj-11", "numoutlets" : 1, - "outlettype" : [ "int" ], - "presentation_rect" : [ 523.0, 204.0, 20.0, 20.0 ], - "id" : "obj-11" + "outlettype" : [ "int" ] } } @@ -95,30 +294,30 @@ "box" : { "maxclass" : "newobj", "text" : "metro 250", - "patching_rect" : [ 769.0, 388.0, 63.0, 19.0 ], + "fontname" : "Verdana", + "presentation_rect" : [ 517.0, 230.0, 63.0, 19.0 ], + "patching_rect" : [ 90.0, 201.0, 63.0, 19.0 ], + "numinlets" : 2, "presentation" : 1, - "numinlets" : 2, "fontsize" : 10.0, + "id" : "obj-2", "numoutlets" : 1, - "outlettype" : [ "bang" ], - "presentation_rect" : [ 517.0, 230.0, 63.0, 19.0 ], - "id" : "obj-2", - "fontname" : "Verdana" + "outlettype" : [ "bang" ] } } , { "box" : { "maxclass" : "flonum", + "fontname" : "Verdana", + "presentation_rect" : [ 282.0, 62.0, 57.0, 21.0 ], "patching_rect" : [ 511.0, 249.0, 57.0, 21.0 ], + "numinlets" : 1, "presentation" : 1, - "numinlets" : 1, "fontsize" : 12.0, + "id" : "obj-99", "numoutlets" : 2, - "outlettype" : [ "float", "bang" ], - "presentation_rect" : [ 282.0, 62.0, 57.0, 21.0 ], - "id" : "obj-99", - "fontname" : "Verdana" + "outlettype" : [ "float", "bang" ] } } @@ -126,13 +325,13 @@ "box" : { "maxclass" : "message", "text" : "/offline", + "fontname" : "Verdana", "patching_rect" : [ 783.0, 954.0, 46.0, 17.0 ], "numinlets" : 2, "fontsize" : 10.0, + "id" : "obj-74", "numoutlets" : 1, - "outlettype" : [ "" ], - "id" : "obj-74", - "fontname" : "Verdana" + "outlettype" : [ "" ] } } @@ -140,13 +339,13 @@ "box" : { "maxclass" : "message", "text" : "/realtime", + "fontname" : "Verdana", "patching_rect" : [ 714.0, 951.0, 56.0, 17.0 ], "numinlets" : 2, "fontsize" : 10.0, + "id" : "obj-73", "numoutlets" : 1, - "outlettype" : [ "" ], - "id" : "obj-73", - "fontname" : "Verdana" + "outlettype" : [ "" ] } } @@ -154,13 +353,13 @@ "box" : { "maxclass" : "newobj", "text" : "sel 1 2", + "fontname" : "Verdana", "patching_rect" : [ 699.0, 921.0, 46.0, 19.0 ], "numinlets" : 1, "fontsize" : 10.0, + "id" : "obj-64", "numoutlets" : 3, - "outlettype" : [ "bang", "bang", "" ], - "id" : "obj-64", - "fontname" : "Verdana" + "outlettype" : [ "bang", "bang", "" ] } } @@ -168,14 +367,14 @@ "box" : { "maxclass" : "comment", "text" : "for offline", - "patching_rect" : [ 351.0, 174.0, 150.0, 19.0 ], + "fontname" : "Verdana", + "presentation_rect" : [ 120.0, 86.0, 58.0, 19.0 ], + "patching_rect" : [ 932.0, 231.0, 150.0, 19.0 ], + "numinlets" : 1, "presentation" : 1, - "numinlets" : 1, "fontsize" : 10.0, - "numoutlets" : 0, - "presentation_rect" : [ 120.0, 86.0, 58.0, 19.0 ], "id" : "obj-62", - "fontname" : "Verdana" + "numoutlets" : 0 } } @@ -183,13 +382,13 @@ "box" : { "maxclass" : "newobj", "text" : "p ftmPlayer", + "fontname" : "Verdana", "patching_rect" : [ 45.0, 316.0, 476.0, 19.0 ], "numinlets" : 2, "fontsize" : 10.0, + "id" : "obj-60", "numoutlets" : 2, "outlettype" : [ "", "" ], - "id" : "obj-60", - "fontname" : "Verdana", "patcher" : { "fileversion" : 1, "rect" : [ 25.0, 69.0, 640.0, 480.0 ], @@ -214,9 +413,9 @@ "maxclass" : "inlet", "patching_rect" : [ 336.0, 56.0, 25.0, 25.0 ], "numinlets" : 0, + "id" : "obj-1", "numoutlets" : 1, "outlettype" : [ "float" ], - "id" : "obj-1", "comment" : "" } @@ -225,14 +424,14 @@ "box" : { "maxclass" : "comment", "text" : "midi", + "fontname" : "Verdana", + "presentation_rect" : [ 52.0, 420.0, 150.0, 19.0 ], "patching_rect" : [ 131.0, 214.0, 150.0, 19.0 ], + "numinlets" : 1, "presentation" : 1, - "numinlets" : 1, "fontsize" : 10.0, - "numoutlets" : 0, - "presentation_rect" : [ 52.0, 420.0, 150.0, 19.0 ], "id" : "obj-11", - "fontname" : "Verdana" + "numoutlets" : 0 } } @@ -240,13 +439,13 @@ "box" : { "maxclass" : "newobj", "text" : "p otherFtmControls", + "fontname" : "Verdana", "patching_rect" : [ 50.0, 109.0, 108.0, 19.0 ], "numinlets" : 0, "fontsize" : 10.0, + "id" : "obj-115", "numoutlets" : 1, "outlettype" : [ "" ], - "id" : "obj-115", - "fontname" : "Verdana", "patcher" : { "fileversion" : 1, "rect" : [ 25.0, 69.0, 640.0, 480.0 ], @@ -272,14 +471,14 @@ "text" : "ordinary file following (x) or else one shot test", "linecount" : 2, "presentation_linecount" : 2, - "patching_rect" : [ 87.0, 206.0, 153.0, 31.0 ], + "fontname" : "Verdana", + "presentation_rect" : [ 52.0, 186.0, 156.0, 31.0 ], + "patching_rect" : [ 98.0, 56.0, 153.0, 31.0 ], + "numinlets" : 1, "presentation" : 1, - "numinlets" : 1, "fontsize" : 10.0, - "numoutlets" : 0, - "presentation_rect" : [ 52.0, 186.0, 156.0, 31.0 ], "id" : "obj-111", - "fontname" : "Verdana" + "numoutlets" : 0 } } @@ -287,33 +486,33 @@ "box" : { "maxclass" : "comment", "text" : "set speed", + "fontname" : "Verdana", "patching_rect" : [ 362.0, 263.0, 57.0, 19.0 ], "numinlets" : 1, "fontsize" : 10.0, - "numoutlets" : 0, "id" : "obj-3", - "fontname" : "Verdana" + "numoutlets" : 0 } } , { "box" : { "maxclass" : "ftm.mess", + "fontname" : "Verdana", + "presentation_rect" : [ 216.0, 166.0, 92.157234, 17.0 ], + "#init" : "", + "patching_rect" : [ 216.0, 166.0, 92.157234, 17.0 ], + "text" : [ "_loop 500 1500 1." ], + "numinlets" : 2, "#triggerall" : 0, - "patching_rect" : [ 216.0, 166.0, 92.157234, 17.0 ], + "fontsize" : 10.0, + "id" : "obj-4", "#untuple" : 0, - "numinlets" : 2, - "text" : [ "_loop 500 1500 1." ], - "fontsize" : 10.0, - "ftm_scope" : 1, + "ftm_objref_conv" : 0, "numoutlets" : 1, - "#init" : "", + "#loadbang" : 0, "outlettype" : [ "" ], - "#loadbang" : 0, - "ftm_objref_conv" : 0, - "presentation_rect" : [ 216.0, 166.0, 92.157234, 17.0 ], - "id" : "obj-4", - "fontname" : "Verdana" + "ftm_scope" : 1 } } @@ -321,33 +520,33 @@ "box" : { "maxclass" : "comment", "text" : "set segment (begin, end and speed) and loop", + "fontname" : "Verdana", "patching_rect" : [ 306.0, 167.0, 240.0, 19.0 ], "numinlets" : 1, "fontsize" : 10.0, - "numoutlets" : 0, "id" : "obj-5", - "fontname" : "Verdana" + "numoutlets" : 0 } } , { "box" : { "maxclass" : "ftm.mess", + "fontname" : "Verdana", + "presentation_rect" : [ 216.0, 146.0, 142.66507, 17.0 ], + "#init" : "", + "patching_rect" : [ 216.0, 146.0, 142.66507, 17.0 ], + "text" : [ "_play $play.seq 500 1500 1." ], + "numinlets" : 2, "#triggerall" : 0, - "patching_rect" : [ 216.0, 146.0, 142.66507, 17.0 ], + "fontsize" : 10.0, + "id" : "obj-6", "#untuple" : 0, - "numinlets" : 2, - "text" : [ "_play $play.seq 500 1500 1." ], - "fontsize" : 10.0, - "ftm_scope" : 0, + "ftm_objref_conv" : 0, "numoutlets" : 1, - "#init" : "", + "#loadbang" : 0, "outlettype" : [ "" ], - "#loadbang" : 0, - "ftm_objref_conv" : 0, - "presentation_rect" : [ 216.0, 146.0, 142.66507, 17.0 ], - "id" : "obj-6", - "fontname" : "Verdana" + "ftm_scope" : 0 } } @@ -355,12 +554,12 @@ "box" : { "maxclass" : "comment", "text" : "set segment (track, begin, end and speed) and play", + "fontname" : "Verdana", "patching_rect" : [ 370.0, 147.0, 272.0, 19.0 ], "numinlets" : 1, "fontsize" : 10.0, - "numoutlets" : 0, "id" : "obj-7", - "fontname" : "Verdana" + "numoutlets" : 0 } } @@ -368,12 +567,12 @@ "box" : { "maxclass" : "comment", "text" : "advance to next time", + "fontname" : "Verdana", "patching_rect" : [ 88.0, 258.0, 115.0, 19.0 ], "numinlets" : 1, "fontsize" : 10.0, - "numoutlets" : 0, "id" : "obj-8", - "fontname" : "Verdana" + "numoutlets" : 0 } } @@ -382,11 +581,11 @@ "maxclass" : "slider", "patching_rect" : [ 162.0, 238.0, 169.0, 15.0 ], "numinlets" : 1, - "orientation" : 1, + "id" : "obj-9", "numoutlets" : 1, "size" : 1001.0, + "orientation" : 1, "outlettype" : [ "" ], - "id" : "obj-9", "mult" : 10.0 } @@ -395,12 +594,12 @@ "box" : { "maxclass" : "comment", "text" : "locate or jump at given time", + "fontname" : "Verdana", "patching_rect" : [ 114.0, 121.0, 151.0, 19.0 ], "numinlets" : 1, "fontsize" : 10.0, - "numoutlets" : 0, "id" : "obj-10", - "fontname" : "Verdana" + "numoutlets" : 0 } } @@ -408,13 +607,13 @@ "box" : { "maxclass" : "message", "text" : "next", + "fontname" : "Verdana", "patching_rect" : [ 50.0, 257.0, 33.0, 17.0 ], "numinlets" : 2, "fontsize" : 10.0, + "id" : "obj-11", "numoutlets" : 1, - "outlettype" : [ "" ], - "id" : "obj-11", - "fontname" : "Verdana" + "outlettype" : [ "" ] } } @@ -422,13 +621,13 @@ "box" : { "maxclass" : "message", "text" : "jump 300.", + "fontname" : "Verdana", "patching_rect" : [ 50.0, 119.0, 62.0, 17.0 ], "numinlets" : 2, "fontsize" : 10.0, + "id" : "obj-12", "numoutlets" : 1, - "outlettype" : [ "" ], - "id" : "obj-12", - "fontname" : "Verdana" + "outlettype" : [ "" ] } } @@ -436,12 +635,12 @@ "box" : { "maxclass" : "comment", "text" : "set speed by giving a duration for the current segment", + "fontname" : "Verdana", "patching_rect" : [ 336.0, 281.0, 285.0, 19.0 ], "numinlets" : 1, "fontsize" : 10.0, - "numoutlets" : 0, "id" : "obj-23", - "fontname" : "Verdana" + "numoutlets" : 0 } } @@ -449,12 +648,12 @@ "box" : { "maxclass" : "comment", "text" : "set segment (only begin and end) and play straight", + "fontname" : "Verdana", "patching_rect" : [ 354.0, 120.0, 270.0, 19.0 ], "numinlets" : 1, "fontsize" : 10.0, - "numoutlets" : 0, "id" : "obj-24", - "fontname" : "Verdana" + "numoutlets" : 0 } } @@ -462,12 +661,12 @@ "box" : { "maxclass" : "comment", "text" : "play current segment", + "fontname" : "Verdana", "patching_rect" : [ 86.0, 147.0, 116.0, 19.0 ], "numinlets" : 1, "fontsize" : 10.0, - "numoutlets" : 0, "id" : "obj-25", - "fontname" : "Verdana" + "numoutlets" : 0 } } @@ -475,50 +674,50 @@ "box" : { "maxclass" : "message", "text" : "speed 0.5", + "fontname" : "Verdana", "patching_rect" : [ 299.0, 262.0, 58.0, 17.0 ], "numinlets" : 2, "fontsize" : 10.0, + "id" : "obj-26", "numoutlets" : 1, - "outlettype" : [ "" ], - "id" : "obj-26", - "fontname" : "Verdana" + "outlettype" : [ "" ] } } , { "box" : { "maxclass" : "ftm.mess", + "fontname" : "Verdana", + "presentation_rect" : [ 274.0, 119.0, 78.998055, 17.0 ], + "#init" : "", + "patching_rect" : [ 274.0, 119.0, 78.998055, 17.0 ], + "text" : [ "_set 0 9999999" ], + "numinlets" : 2, "#triggerall" : 0, - "patching_rect" : [ 274.0, 119.0, 78.998055, 17.0 ], + "fontsize" : 10.0, + "id" : "obj-27", "#untuple" : 0, - "numinlets" : 2, - "text" : [ "_set 0 9999999" ], - "fontsize" : 10.0, - "ftm_scope" : 0, + "ftm_objref_conv" : 0, "numoutlets" : 1, - "#init" : "", + "#loadbang" : 0, "outlettype" : [ "" ], - "#loadbang" : 0, - "ftm_objref_conv" : 0, - "presentation_rect" : [ 274.0, 119.0, 78.998055, 17.0 ], - "id" : "obj-27", - "fontname" : "Verdana" + "ftm_scope" : 0 } } , { "box" : { "maxclass" : "flonum", + "fontname" : "Verdana", "patching_rect" : [ 104.0, 238.0, 56.0, 19.0 ], "numinlets" : 1, "fontsize" : 10.0, + "id" : "obj-28", "bgcolor" : [ 0.866667, 0.866667, 0.866667, 1.0 ], - "triscale" : 0.9, + "htextcolor" : [ 0.870588, 0.870588, 0.870588, 1.0 ], "numoutlets" : 2, - "htextcolor" : [ 0.870588, 0.870588, 0.870588, 1.0 ], "outlettype" : [ "float", "bang" ], - "id" : "obj-28", - "fontname" : "Verdana" + "triscale" : 0.9 } } @@ -526,13 +725,13 @@ "box" : { "maxclass" : "message", "text" : "duration 1000", + "fontname" : "Verdana", "patching_rect" : [ 252.0, 281.0, 79.0, 17.0 ], "numinlets" : 2, "fontsize" : 10.0, + "id" : "obj-29", "numoutlets" : 1, - "outlettype" : [ "" ], - "id" : "obj-29", - "fontname" : "Verdana" + "outlettype" : [ "" ] } } @@ -540,13 +739,13 @@ "box" : { "maxclass" : "message", "text" : "speed 2.", + "fontname" : "Verdana", "patching_rect" : [ 252.0, 262.0, 52.0, 17.0 ], "numinlets" : 2, "fontsize" : 10.0, + "id" : "obj-30", "numoutlets" : 1, - "outlettype" : [ "" ], - "id" : "obj-30", - "fontname" : "Verdana" + "outlettype" : [ "" ] } } @@ -554,13 +753,13 @@ "box" : { "maxclass" : "message", "text" : "pause", + "fontname" : "Verdana", "patching_rect" : [ 50.0, 192.0, 40.0, 17.0 ], "numinlets" : 2, "fontsize" : 10.0, + "id" : "obj-31", "numoutlets" : 1, - "outlettype" : [ "" ], - "id" : "obj-31", - "fontname" : "Verdana" + "outlettype" : [ "" ] } } @@ -568,13 +767,13 @@ "box" : { "maxclass" : "message", "text" : "locate 300.", + "fontname" : "Verdana", "patching_rect" : [ 50.0, 100.0, 67.0, 17.0 ], "numinlets" : 2, "fontsize" : 10.0, + "id" : "obj-32", "numoutlets" : 1, - "outlettype" : [ "" ], - "id" : "obj-32", - "fontname" : "Verdana" + "outlettype" : [ "" ] } } @@ -582,34 +781,34 @@ "box" : { "maxclass" : "message", "text" : "sync $1", + "fontname" : "Verdana", "patching_rect" : [ 50.0, 238.0, 49.0, 17.0 ], "numinlets" : 2, "fontsize" : 10.0, + "id" : "obj-33", "numoutlets" : 1, - "outlettype" : [ "" ], - "id" : "obj-33", - "fontname" : "Verdana" + "outlettype" : [ "" ] } } , { "box" : { "maxclass" : "ftm.mess", + "fontname" : "Verdana", + "presentation_rect" : [ 274.0, 100.0, 136.952179, 17.0 ], + "#init" : "", + "patching_rect" : [ 274.0, 100.0, 136.952179, 17.0 ], + "text" : [ "_set $play.seq 500 1500 1." ], + "numinlets" : 2, "#triggerall" : 0, - "patching_rect" : [ 274.0, 100.0, 136.952179, 17.0 ], + "fontsize" : 10.0, + "id" : "obj-40", "#untuple" : 0, - "numinlets" : 2, - "text" : [ "_set $play.seq 500 1500 1." ], - "fontsize" : 10.0, - "ftm_scope" : 0, + "ftm_objref_conv" : 0, "numoutlets" : 1, - "#init" : "", + "#loadbang" : 0, "outlettype" : [ "" ], - "#loadbang" : 0, - "ftm_objref_conv" : 0, - "presentation_rect" : [ 274.0, 100.0, 136.952179, 17.0 ], - "id" : "obj-40", - "fontname" : "Verdana" + "ftm_scope" : 0 } } @@ -617,13 +816,13 @@ "box" : { "maxclass" : "message", "text" : "loop", + "fontname" : "Verdana", "patching_rect" : [ 50.0, 165.0, 32.5, 17.0 ], "numinlets" : 2, "fontsize" : 10.0, + "id" : "obj-41", "numoutlets" : 1, - "outlettype" : [ "" ], - "id" : "obj-41", - "fontname" : "Verdana" + "outlettype" : [ "" ] } } @@ -632,9 +831,9 @@ "maxclass" : "button", "patching_rect" : [ 50.0, 292.0, 15.0, 15.0 ], "numinlets" : 1, + "id" : "obj-50", "numoutlets" : 1, - "outlettype" : [ "bang" ], - "id" : "obj-50" + "outlettype" : [ "bang" ] } } @@ -642,12 +841,12 @@ "box" : { "maxclass" : "comment", "text" : "advance to gven time (output all events on the way)", + "fontname" : "Verdana", "patching_rect" : [ 326.0, 238.0, 274.0, 19.0 ], "numinlets" : 1, "fontsize" : 10.0, - "numoutlets" : 0, "id" : "obj-54", - "fontname" : "Verdana" + "numoutlets" : 0 } } @@ -655,12 +854,12 @@ "box" : { "maxclass" : "comment", "text" : "locate halted at given time", + "fontname" : "Verdana", "patching_rect" : [ 119.0, 101.0, 143.0, 19.0 ], "numinlets" : 1, "fontsize" : 10.0, - "numoutlets" : 0, "id" : "obj-55", - "fontname" : "Verdana" + "numoutlets" : 0 } } @@ -668,12 +867,12 @@ "box" : { "maxclass" : "comment", "text" : "loop current segment", + "fontname" : "Verdana", "patching_rect" : [ 85.0, 166.0, 116.0, 19.0 ], "numinlets" : 1, "fontsize" : 10.0, - "numoutlets" : 0, "id" : "obj-57", - "fontname" : "Verdana" + "numoutlets" : 0 } } @@ -681,12 +880,12 @@ "box" : { "maxclass" : "comment", "text" : "stop playing and reset", + "fontname" : "Verdana", "patching_rect" : [ 86.0, 212.0, 121.0, 19.0 ], "numinlets" : 1, "fontsize" : 10.0, - "numoutlets" : 0, "id" : "obj-58", - "fontname" : "Verdana" + "numoutlets" : 0 } } @@ -694,12 +893,12 @@ "box" : { "maxclass" : "comment", "text" : "halt playing", + "fontname" : "Verdana", "patching_rect" : [ 93.0, 193.0, 67.0, 19.0 ], "numinlets" : 1, "fontsize" : 10.0, - "numoutlets" : 0, "id" : "obj-59", - "fontname" : "Verdana" + "numoutlets" : 0 } } @@ -707,12 +906,12 @@ "box" : { "maxclass" : "comment", "text" : "play current segment straight", + "fontname" : "Verdana", "patching_rect" : [ 67.0, 292.0, 158.0, 19.0 ], "numinlets" : 1, "fontsize" : 10.0, - "numoutlets" : 0, "id" : "obj-60", - "fontname" : "Verdana" + "numoutlets" : 0 } } @@ -721,12 +920,12 @@ "maxclass" : "comment", "text" : "note that setting a new track stops and resets the player (play and loop start from beginning)", "linecount" : 2, + "fontname" : "Verdana", "patching_rect" : [ 277.0, 196.0, 266.0, 31.0 ], "numinlets" : 1, "fontsize" : 10.0, - "numoutlets" : 0, "id" : "obj-62", - "fontname" : "Verdana" + "numoutlets" : 0 } } @@ -735,8 +934,8 @@ "maxclass" : "outlet", "patching_rect" : [ 147.357147, 371.0, 25.0, 25.0 ], "numinlets" : 1, + "id" : "obj-114", "numoutlets" : 0, - "id" : "obj-114", "comment" : "" } @@ -744,25 +943,106 @@ ], "lines" : [ { "patchline" : { - "source" : [ "obj-9", 0 ], - "destination" : [ "obj-28", 0 ], - "hidden" : 1, + "source" : [ "obj-26", 0 ], + "destination" : [ "obj-114", 0 ], + "hidden" : 0, "midpoints" : [ ] } } , { "patchline" : { - "source" : [ "obj-28", 0 ], - "destination" : [ "obj-33", 0 ], - "hidden" : 1, + "source" : [ "obj-27", 0 ], + "destination" : [ "obj-114", 0 ], + "hidden" : 0, "midpoints" : [ ] } } , { "patchline" : { - "source" : [ "obj-32", 0 ], + "source" : [ "obj-40", 0 ], + "destination" : [ "obj-114", 0 ], + "hidden" : 0, + "midpoints" : [ ] + } + + } +, { + "patchline" : { + "source" : [ "obj-29", 0 ], + "destination" : [ "obj-114", 0 ], + "hidden" : 0, + "midpoints" : [ ] + } + + } +, { + "patchline" : { + "source" : [ "obj-30", 0 ], + "destination" : [ "obj-114", 0 ], + "hidden" : 0, + "midpoints" : [ ] + } + + } +, { + "patchline" : { + "source" : [ "obj-4", 0 ], + "destination" : [ "obj-114", 0 ], + "hidden" : 0, + "midpoints" : [ ] + } + + } +, { + "patchline" : { + "source" : [ "obj-6", 0 ], + "destination" : [ "obj-114", 0 ], + "hidden" : 0, + "midpoints" : [ ] + } + + } +, { + "patchline" : { + "source" : [ "obj-50", 0 ], + "destination" : [ "obj-114", 0 ], + "hidden" : 0, + "midpoints" : [ ] + } + + } +, { + "patchline" : { + "source" : [ "obj-11", 0 ], + "destination" : [ "obj-114", 0 ], + "hidden" : 0, + "midpoints" : [ ] + } + + } +, { + "patchline" : { + "source" : [ "obj-33", 0 ], + "destination" : [ "obj-114", 0 ], + "hidden" : 0, + "midpoints" : [ ] + } + + } +, { + "patchline" : { + "source" : [ "obj-31", 0 ], + "destination" : [ "obj-114", 0 ], + "hidden" : 0, + "midpoints" : [ ] + } + + } +, { + "patchline" : { + "source" : [ "obj-41", 0 ], "destination" : [ "obj-114", 0 ], "hidden" : 0, "midpoints" : [ ] @@ -780,7 +1060,7 @@ } , { "patchline" : { - "source" : [ "obj-41", 0 ], + "source" : [ "obj-32", 0 ], "destination" : [ "obj-114", 0 ], "hidden" : 0, "midpoints" : [ ] @@ -789,99 +1069,18 @@ } , { "patchline" : { - "source" : [ "obj-31", 0 ], - "destination" : [ "obj-114", 0 ], - "hidden" : 0, + "source" : [ "obj-28", 0 ], + "destination" : [ "obj-33", 0 ], + "hidden" : 1, "midpoints" : [ ] } } , { "patchline" : { - "source" : [ "obj-33", 0 ], - "destination" : [ "obj-114", 0 ], - "hidden" : 0, - "midpoints" : [ ] - } - - } -, { - "patchline" : { - "source" : [ "obj-11", 0 ], - "destination" : [ "obj-114", 0 ], - "hidden" : 0, - "midpoints" : [ ] - } - - } -, { - "patchline" : { - "source" : [ "obj-50", 0 ], - "destination" : [ "obj-114", 0 ], - "hidden" : 0, - "midpoints" : [ ] - } - - } -, { - "patchline" : { - "source" : [ "obj-6", 0 ], - "destination" : [ "obj-114", 0 ], - "hidden" : 0, - "midpoints" : [ ] - } - - } -, { - "patchline" : { - "source" : [ "obj-4", 0 ], - "destination" : [ "obj-114", 0 ], - "hidden" : 0, - "midpoints" : [ ] - } - - } -, { - "patchline" : { - "source" : [ "obj-30", 0 ], - "destination" : [ "obj-114", 0 ], - "hidden" : 0, - "midpoints" : [ ] - } - - } -, { - "patchline" : { - "source" : [ "obj-29", 0 ], - "destination" : [ "obj-114", 0 ], - "hidden" : 0, - "midpoints" : [ ] - } - - } -, { - "patchline" : { - "source" : [ "obj-40", 0 ], - "destination" : [ "obj-114", 0 ], - "hidden" : 0, - "midpoints" : [ ] - } - - } -, { - "patchline" : { - "source" : [ "obj-27", 0 ], - "destination" : [ "obj-114", 0 ], - "hidden" : 0, - "midpoints" : [ ] - } - - } -, { - "patchline" : { - "source" : [ "obj-26", 0 ], - "destination" : [ "obj-114", 0 ], - "hidden" : 0, + "source" : [ "obj-9", 0 ], + "destination" : [ "obj-28", 0 ], + "hidden" : 1, "midpoints" : [ ] } @@ -890,13 +1089,13 @@ } , "saved_object_attributes" : { + "fontname" : "Arial", "default_fontsize" : 12.0, - "globalpatchername" : "", "fontface" : 0, "fontsize" : 12.0, "default_fontface" : 0, - "default_fontname" : "Arial", - "fontname" : "Arial" + "globalpatchername" : "", + "default_fontname" : "Arial" } } @@ -906,12 +1105,12 @@ "box" : { "maxclass" : "comment", "text" : "syntax:", + "fontname" : "Verdana", "patching_rect" : [ 358.0, 168.0, 46.0, 19.0 ], "numinlets" : 1, "fontsize" : 10.0, - "numoutlets" : 0, "id" : "obj-2", - "fontname" : "Verdana" + "numoutlets" : 0 } } @@ -920,12 +1119,12 @@ "maxclass" : "comment", "text" : "kill hanging notes when looping", "hidden" : 1, + "fontname" : "Verdana", "patching_rect" : [ 291.0, 203.0, 168.0, 19.0 ], "numinlets" : 1, "fontsize" : 10.0, - "numoutlets" : 0, "id" : "obj-13", - "fontname" : "Verdana" + "numoutlets" : 0 } } @@ -933,12 +1132,12 @@ "box" : { "maxclass" : "comment", "text" : "set segment end", + "fontname" : "Verdana", "patching_rect" : [ 433.0, 120.0, 93.0, 19.0 ], "numinlets" : 1, "fontsize" : 10.0, - "numoutlets" : 0, "id" : "obj-21", - "fontname" : "Verdana" + "numoutlets" : 0 } } @@ -947,13 +1146,13 @@ "maxclass" : "newobj", "text" : "change 0 -", "hidden" : 1, + "fontname" : "Verdana", "patching_rect" : [ 128.0, 202.0, 62.0, 19.0 ], "numinlets" : 1, "fontsize" : 10.0, + "id" : "obj-34", "numoutlets" : 3, - "outlettype" : [ "", "int", "int" ], - "id" : "obj-34", - "fontname" : "Verdana" + "outlettype" : [ "", "int", "int" ] } } @@ -962,11 +1161,11 @@ "maxclass" : "slider", "patching_rect" : [ 262.0, 120.0, 169.0, 15.0 ], "numinlets" : 1, - "orientation" : 1, + "id" : "obj-35", "numoutlets" : 1, "size" : 1001.0, + "orientation" : 1, "outlettype" : [ "" ], - "id" : "obj-35", "mult" : 10.0 } @@ -976,11 +1175,11 @@ "maxclass" : "slider", "patching_rect" : [ 187.0, 100.0, 169.0, 15.0 ], "numinlets" : 1, - "orientation" : 1, + "id" : "obj-36", "numoutlets" : 1, "size" : 1001.0, + "orientation" : 1, "outlettype" : [ "" ], - "id" : "obj-36", "mult" : 10.0 } @@ -989,15 +1188,15 @@ "box" : { "maxclass" : "message", "text" : "GM", + "fontname" : "Verdana", + "presentation_rect" : [ 127.0, 442.0, 32.5, 17.0 ], "patching_rect" : [ 203.0, 228.0, 32.5, 17.0 ], + "numinlets" : 2, "presentation" : 1, - "numinlets" : 2, "fontsize" : 10.0, + "id" : "obj-37", "numoutlets" : 1, - "outlettype" : [ "" ], - "presentation_rect" : [ 127.0, 442.0, 32.5, 17.0 ], - "id" : "obj-37", - "fontname" : "Verdana" + "outlettype" : [ "" ] } } @@ -1005,15 +1204,15 @@ "box" : { "maxclass" : "message", "text" : "panic", + "fontname" : "Verdana", + "presentation_rect" : [ 85.0, 442.0, 37.0, 17.0 ], "patching_rect" : [ 161.0, 228.0, 37.0, 17.0 ], + "numinlets" : 2, "presentation" : 1, - "numinlets" : 2, "fontsize" : 10.0, + "id" : "obj-38", "numoutlets" : 1, - "outlettype" : [ "" ], - "presentation_rect" : [ 85.0, 442.0, 37.0, 17.0 ], - "id" : "obj-38", - "fontname" : "Verdana" + "outlettype" : [ "" ] } } @@ -1021,47 +1220,47 @@ "box" : { "maxclass" : "message", "text" : "off", + "fontname" : "Verdana", + "presentation_rect" : [ 48.0, 442.0, 32.5, 17.0 ], "patching_rect" : [ 124.0, 228.0, 32.5, 17.0 ], + "numinlets" : 2, "presentation" : 1, - "numinlets" : 2, "fontsize" : 10.0, + "id" : "obj-39", "numoutlets" : 1, - "outlettype" : [ "" ], - "presentation_rect" : [ 48.0, 442.0, 32.5, 17.0 ], - "id" : "obj-39", - "fontname" : "Verdana" + "outlettype" : [ "" ] } } , { "box" : { "maxclass" : "flonum", + "fontname" : "Verdana", "patching_rect" : [ 262.0, 143.0, 55.0, 19.0 ], "numinlets" : 1, "fontsize" : 10.0, + "id" : "obj-42", "bgcolor" : [ 0.866667, 0.866667, 0.866667, 1.0 ], - "triscale" : 0.9, + "htextcolor" : [ 0.870588, 0.870588, 0.870588, 1.0 ], "numoutlets" : 2, - "htextcolor" : [ 0.870588, 0.870588, 0.870588, 1.0 ], "outlettype" : [ "float", "bang" ], - "id" : "obj-42", - "fontname" : "Verdana" + "triscale" : 0.9 } } , { "box" : { "maxclass" : "flonum", + "fontname" : "Verdana", "patching_rect" : [ 187.0, 143.0, 55.0, 19.0 ], "numinlets" : 1, "fontsize" : 10.0, + "id" : "obj-43", "bgcolor" : [ 0.866667, 0.866667, 0.866667, 1.0 ], - "triscale" : 0.9, + "htextcolor" : [ 0.870588, 0.870588, 0.870588, 1.0 ], "numoutlets" : 2, - "htextcolor" : [ 0.870588, 0.870588, 0.870588, 1.0 ], "outlettype" : [ "float", "bang" ], - "id" : "obj-43", - "fontname" : "Verdana" + "triscale" : 0.9 } } @@ -1069,16 +1268,16 @@ "box" : { "maxclass" : "newobj", "text" : "ftm.midiunparse", + "fontname" : "Verdana", "patching_rect" : [ 112.0, 249.0, 93.0, 19.0 ], "numinlets" : 1, "fontsize" : 10.0, + "id" : "obj-45", "numoutlets" : 1, "outlettype" : [ "" ], - "id" : "obj-45", - "fontname" : "Verdana", "saved_object_attributes" : { - "ftm_scope" : 0, - "ftm_objref_conv" : 0 + "ftm_objref_conv" : 0, + "ftm_scope" : 0 } } @@ -1089,25 +1288,25 @@ "maxclass" : "button", "patching_rect" : [ 337.0, 228.0, 15.0, 15.0 ], "numinlets" : 1, + "id" : "obj-51", "numoutlets" : 1, - "outlettype" : [ "bang" ], - "id" : "obj-51" + "outlettype" : [ "bang" ] } } , { "box" : { "maxclass" : "flonum", + "fontname" : "Verdana", "patching_rect" : [ 215.0, 201.0, 55.0, 19.0 ], "numinlets" : 1, "fontsize" : 10.0, + "id" : "obj-52", "bgcolor" : [ 0.866667, 0.866667, 0.866667, 1.0 ], - "triscale" : 0.9, + "htextcolor" : [ 0.870588, 0.870588, 0.870588, 1.0 ], "numoutlets" : 2, - "htextcolor" : [ 0.870588, 0.870588, 0.870588, 1.0 ], "outlettype" : [ "float", "bang" ], - "id" : "obj-52", - "fontname" : "Verdana" + "triscale" : 0.9 } } @@ -1115,16 +1314,16 @@ "box" : { "maxclass" : "newobj", "text" : "ftm.play $play.seq", + "fontname" : "Verdana", "patching_rect" : [ 112.0, 166.0, 244.0, 28.0 ], "numinlets" : 4, "fontsize" : 18.0, + "id" : "obj-53", "numoutlets" : 3, "outlettype" : [ "", "", "" ], - "id" : "obj-53", - "fontname" : "Verdana", "saved_object_attributes" : { - "ftm_scope" : 0, - "ftm_objref_conv" : 0 + "ftm_objref_conv" : 0, + "ftm_scope" : 0 } } @@ -1134,12 +1333,12 @@ "box" : { "maxclass" : "comment", "text" : "set segment beginning", + "fontname" : "Verdana", "patching_rect" : [ 358.0, 100.0, 123.0, 19.0 ], "numinlets" : 1, "fontsize" : 10.0, - "numoutlets" : 0, "id" : "obj-61", - "fontname" : "Verdana" + "numoutlets" : 0 } } @@ -1148,9 +1347,9 @@ "maxclass" : "inlet", "patching_rect" : [ 112.0, 40.0, 25.0, 25.0 ], "numinlets" : 0, + "id" : "obj-57", "numoutlets" : 1, "outlettype" : [ "" ], - "id" : "obj-57", "comment" : "" } @@ -1160,8 +1359,8 @@ "maxclass" : "outlet", "patching_rect" : [ 112.0, 328.0, 25.0, 25.0 ], "numinlets" : 1, + "id" : "obj-58", "numoutlets" : 0, - "id" : "obj-58", "comment" : "" } @@ -1171,8 +1370,8 @@ "maxclass" : "outlet", "patching_rect" : [ 224.0, 328.0, 25.0, 25.0 ], "numinlets" : 1, + "id" : "obj-59", "numoutlets" : 0, - "id" : "obj-59", "comment" : "" } @@ -1180,8 +1379,8 @@ ], "lines" : [ { "patchline" : { - "source" : [ "obj-1", 0 ], - "destination" : [ "obj-53", 3 ], + "source" : [ "obj-53", 1 ], + "destination" : [ "obj-59", 0 ], "hidden" : 0, "midpoints" : [ ] } @@ -1189,7 +1388,16 @@ } , { "patchline" : { - "source" : [ "obj-115", 0 ], + "source" : [ "obj-45", 0 ], + "destination" : [ "obj-58", 0 ], + "hidden" : 0, + "midpoints" : [ ] + } + + } +, { + "patchline" : { + "source" : [ "obj-57", 0 ], "destination" : [ "obj-53", 0 ], "hidden" : 0, "midpoints" : [ ] @@ -1198,7 +1406,88 @@ } , { "patchline" : { - "source" : [ "obj-37", 0 ], + "source" : [ "obj-53", 2 ], + "destination" : [ "obj-51", 0 ], + "hidden" : 0, + "midpoints" : [ ] + } + + } +, { + "patchline" : { + "source" : [ "obj-42", 0 ], + "destination" : [ "obj-53", 2 ], + "hidden" : 0, + "midpoints" : [ ] + } + + } +, { + "patchline" : { + "source" : [ "obj-35", 0 ], + "destination" : [ "obj-42", 0 ], + "hidden" : 0, + "midpoints" : [ ] + } + + } +, { + "patchline" : { + "source" : [ "obj-53", 1 ], + "destination" : [ "obj-52", 0 ], + "hidden" : 0, + "midpoints" : [ ] + } + + } +, { + "patchline" : { + "source" : [ "obj-43", 0 ], + "destination" : [ "obj-53", 1 ], + "hidden" : 0, + "midpoints" : [ ] + } + + } +, { + "patchline" : { + "source" : [ "obj-36", 0 ], + "destination" : [ "obj-43", 0 ], + "hidden" : 0, + "midpoints" : [ ] + } + + } +, { + "patchline" : { + "source" : [ "obj-34", 0 ], + "destination" : [ "obj-39", 0 ], + "hidden" : 1, + "midpoints" : [ ] + } + + } +, { + "patchline" : { + "source" : [ "obj-52", 0 ], + "destination" : [ "obj-34", 0 ], + "hidden" : 1, + "midpoints" : [ ] + } + + } +, { + "patchline" : { + "source" : [ "obj-53", 0 ], + "destination" : [ "obj-45", 0 ], + "hidden" : 0, + "midpoints" : [ ] + } + + } +, { + "patchline" : { + "source" : [ "obj-39", 0 ], "destination" : [ "obj-45", 0 ], "hidden" : 1, "midpoints" : [ ] @@ -1216,7 +1505,7 @@ } , { "patchline" : { - "source" : [ "obj-39", 0 ], + "source" : [ "obj-37", 0 ], "destination" : [ "obj-45", 0 ], "hidden" : 1, "midpoints" : [ ] @@ -1225,88 +1514,7 @@ } , { "patchline" : { - "source" : [ "obj-53", 0 ], - "destination" : [ "obj-45", 0 ], - "hidden" : 0, - "midpoints" : [ ] - } - - } -, { - "patchline" : { - "source" : [ "obj-52", 0 ], - "destination" : [ "obj-34", 0 ], - "hidden" : 1, - "midpoints" : [ ] - } - - } -, { - "patchline" : { - "source" : [ "obj-34", 0 ], - "destination" : [ "obj-39", 0 ], - "hidden" : 1, - "midpoints" : [ ] - } - - } -, { - "patchline" : { - "source" : [ "obj-36", 0 ], - "destination" : [ "obj-43", 0 ], - "hidden" : 0, - "midpoints" : [ ] - } - - } -, { - "patchline" : { - "source" : [ "obj-43", 0 ], - "destination" : [ "obj-53", 1 ], - "hidden" : 0, - "midpoints" : [ ] - } - - } -, { - "patchline" : { - "source" : [ "obj-53", 1 ], - "destination" : [ "obj-52", 0 ], - "hidden" : 0, - "midpoints" : [ ] - } - - } -, { - "patchline" : { - "source" : [ "obj-35", 0 ], - "destination" : [ "obj-42", 0 ], - "hidden" : 0, - "midpoints" : [ ] - } - - } -, { - "patchline" : { - "source" : [ "obj-42", 0 ], - "destination" : [ "obj-53", 2 ], - "hidden" : 0, - "midpoints" : [ ] - } - - } -, { - "patchline" : { - "source" : [ "obj-53", 2 ], - "destination" : [ "obj-51", 0 ], - "hidden" : 0, - "midpoints" : [ ] - } - - } -, { - "patchline" : { - "source" : [ "obj-57", 0 ], + "source" : [ "obj-115", 0 ], "destination" : [ "obj-53", 0 ], "hidden" : 0, "midpoints" : [ ] @@ -1315,17 +1523,8 @@ } , { "patchline" : { - "source" : [ "obj-45", 0 ], - "destination" : [ "obj-58", 0 ], - "hidden" : 0, - "midpoints" : [ ] - } - - } -, { - "patchline" : { - "source" : [ "obj-53", 1 ], - "destination" : [ "obj-59", 0 ], + "source" : [ "obj-1", 0 ], + "destination" : [ "obj-53", 3 ], "hidden" : 0, "midpoints" : [ ] } @@ -1335,13 +1534,13 @@ } , "saved_object_attributes" : { + "fontname" : "Arial", "default_fontsize" : 12.0, - "globalpatchername" : "", "fontface" : 0, "fontsize" : 12.0, "default_fontface" : 0, - "default_fontname" : "Arial", - "fontname" : "Arial" + "globalpatchername" : "", + "default_fontname" : "Arial" } } @@ -1351,15 +1550,15 @@ "box" : { "maxclass" : "message", "text" : "pause", + "fontname" : "Verdana", + "presentation_rect" : [ 62.0, 86.0, 51.0, 17.0 ], "patching_rect" : [ 226.0, 269.0, 40.0, 17.0 ], + "numinlets" : 2, "presentation" : 1, - "numinlets" : 2, "fontsize" : 10.0, + "id" : "obj-55", "numoutlets" : 1, - "outlettype" : [ "" ], - "presentation_rect" : [ 62.0, 86.0, 51.0, 17.0 ], - "id" : "obj-55", - "fontname" : "Verdana" + "outlettype" : [ "" ] } } @@ -1367,12 +1566,12 @@ "box" : { "maxclass" : "comment", "text" : "hear MIDI playing", + "fontname" : "Verdana", "patching_rect" : [ -10.0, 351.0, 150.0, 19.0 ], "numinlets" : 1, "fontsize" : 10.0, - "numoutlets" : 0, "id" : "obj-54", - "fontname" : "Verdana" + "numoutlets" : 0 } } @@ -1380,13 +1579,13 @@ "box" : { "maxclass" : "newobj", "text" : "p weirdStarter", + "fontname" : "Verdana", "patching_rect" : [ 240.0, 618.0, 83.0, 19.0 ], "numinlets" : 2, "fontsize" : 10.0, + "id" : "obj-48", "numoutlets" : 1, "outlettype" : [ "bang" ], - "id" : "obj-48", - "fontname" : "Verdana", "patcher" : { "fileversion" : 1, "rect" : [ 25.0, 69.0, 640.0, 480.0 ], @@ -1411,9 +1610,9 @@ "maxclass" : "toggle", "patching_rect" : [ 94.0, 159.0, 20.0, 20.0 ], "numinlets" : 1, + "id" : "obj-132", "numoutlets" : 1, - "outlettype" : [ "int" ], - "id" : "obj-132" + "outlettype" : [ "int" ] } } @@ -1422,9 +1621,9 @@ "maxclass" : "button", "patching_rect" : [ 95.0, 217.0, 20.0, 20.0 ], "numinlets" : 1, + "id" : "obj-130", "numoutlets" : 1, - "outlettype" : [ "bang" ], - "id" : "obj-130" + "outlettype" : [ "bang" ] } } @@ -1432,13 +1631,13 @@ "box" : { "maxclass" : "message", "text" : "0", + "fontname" : "Verdana", "patching_rect" : [ 92.0, 239.0, 32.5, 17.0 ], "numinlets" : 2, "fontsize" : 10.0, + "id" : "obj-128", "numoutlets" : 1, - "outlettype" : [ "" ], - "id" : "obj-128", - "fontname" : "Verdana" + "outlettype" : [ "" ] } } @@ -1446,13 +1645,13 @@ "box" : { "maxclass" : "newobj", "text" : "gate", + "fontname" : "Verdana", "patching_rect" : [ 92.0, 192.0, 33.0, 19.0 ], "numinlets" : 2, "fontsize" : 10.0, + "id" : "obj-126", "numoutlets" : 1, - "outlettype" : [ "" ], - "id" : "obj-126", - "fontname" : "Verdana" + "outlettype" : [ "" ] } } @@ -1460,13 +1659,13 @@ "box" : { "maxclass" : "message", "text" : "1", + "fontname" : "Verdana", "patching_rect" : [ 65.0, 136.0, 32.5, 17.0 ], "numinlets" : 2, "fontsize" : 10.0, + "id" : "obj-125", "numoutlets" : 1, - "outlettype" : [ "" ], - "id" : "obj-125", - "fontname" : "Verdana" + "outlettype" : [ "" ] } } @@ -1474,13 +1673,13 @@ "box" : { "maxclass" : "newobj", "text" : "loadbang", + "fontname" : "Verdana", "patching_rect" : [ 50.0, 100.0, 56.0, 19.0 ], "numinlets" : 1, "fontsize" : 10.0, + "id" : "obj-123", "numoutlets" : 1, - "outlettype" : [ "bang" ], - "id" : "obj-123", - "fontname" : "Verdana" + "outlettype" : [ "bang" ] } } @@ -1489,9 +1688,9 @@ "maxclass" : "inlet", "patching_rect" : [ 65.0, 40.0, 25.0, 25.0 ], "numinlets" : 0, + "id" : "obj-40", "numoutlets" : 1, "outlettype" : [ "bang" ], - "id" : "obj-40", "comment" : "" } @@ -1501,9 +1700,9 @@ "maxclass" : "inlet", "patching_rect" : [ 106.0, 40.0, 25.0, 25.0 ], "numinlets" : 0, + "id" : "obj-41", "numoutlets" : 1, "outlettype" : [ "" ], - "id" : "obj-41", "comment" : "" } @@ -1513,8 +1712,8 @@ "maxclass" : "outlet", "patching_rect" : [ 95.0, 331.5, 25.0, 25.0 ], "numinlets" : 1, + "id" : "obj-47", "numoutlets" : 0, - "id" : "obj-47", "comment" : "" } @@ -1522,8 +1721,62 @@ ], "lines" : [ { "patchline" : { - "source" : [ "obj-125", 0 ], - "destination" : [ "obj-132", 0 ], + "source" : [ "obj-130", 0 ], + "destination" : [ "obj-47", 0 ], + "hidden" : 0, + "midpoints" : [ ] + } + + } +, { + "patchline" : { + "source" : [ "obj-41", 0 ], + "destination" : [ "obj-126", 1 ], + "hidden" : 0, + "midpoints" : [ ] + } + + } +, { + "patchline" : { + "source" : [ "obj-40", 0 ], + "destination" : [ "obj-125", 0 ], + "hidden" : 0, + "midpoints" : [ ] + } + + } +, { + "patchline" : { + "source" : [ "obj-123", 0 ], + "destination" : [ "obj-125", 0 ], + "hidden" : 0, + "midpoints" : [ ] + } + + } +, { + "patchline" : { + "source" : [ "obj-132", 0 ], + "destination" : [ "obj-126", 0 ], + "hidden" : 0, + "midpoints" : [ ] + } + + } +, { + "patchline" : { + "source" : [ "obj-126", 0 ], + "destination" : [ "obj-130", 0 ], + "hidden" : 0, + "midpoints" : [ ] + } + + } +, { + "patchline" : { + "source" : [ "obj-130", 0 ], + "destination" : [ "obj-128", 0 ], "hidden" : 0, "midpoints" : [ ] } @@ -1540,62 +1793,8 @@ } , { "patchline" : { - "source" : [ "obj-130", 0 ], - "destination" : [ "obj-128", 0 ], - "hidden" : 0, - "midpoints" : [ ] - } - - } -, { - "patchline" : { - "source" : [ "obj-126", 0 ], - "destination" : [ "obj-130", 0 ], - "hidden" : 0, - "midpoints" : [ ] - } - - } -, { - "patchline" : { - "source" : [ "obj-132", 0 ], - "destination" : [ "obj-126", 0 ], - "hidden" : 0, - "midpoints" : [ ] - } - - } -, { - "patchline" : { - "source" : [ "obj-123", 0 ], - "destination" : [ "obj-125", 0 ], - "hidden" : 0, - "midpoints" : [ ] - } - - } -, { - "patchline" : { - "source" : [ "obj-40", 0 ], - "destination" : [ "obj-125", 0 ], - "hidden" : 0, - "midpoints" : [ ] - } - - } -, { - "patchline" : { - "source" : [ "obj-41", 0 ], - "destination" : [ "obj-126", 1 ], - "hidden" : 0, - "midpoints" : [ ] - } - - } -, { - "patchline" : { - "source" : [ "obj-130", 0 ], - "destination" : [ "obj-47", 0 ], + "source" : [ "obj-125", 0 ], + "destination" : [ "obj-132", 0 ], "hidden" : 0, "midpoints" : [ ] } @@ -1605,13 +1804,13 @@ } , "saved_object_attributes" : { + "fontname" : "Arial", "default_fontsize" : 12.0, - "globalpatchername" : "", "fontface" : 0, "fontsize" : 12.0, "default_fontface" : 0, - "default_fontname" : "Arial", - "fontname" : "Arial" + "globalpatchername" : "", + "default_fontname" : "Arial" } } @@ -1621,30 +1820,30 @@ "box" : { "maxclass" : "newobj", "text" : "loadmess 1", + "fontname" : "Verdana", "patching_rect" : [ 415.0, 762.0, 68.0, 19.0 ], "numinlets" : 1, "fontsize" : 10.0, + "id" : "obj-33", "numoutlets" : 1, - "outlettype" : [ "" ], - "id" : "obj-33", - "fontname" : "Verdana" + "outlettype" : [ "" ] } } , { "box" : { "maxclass" : "umenu", + "fontname" : "Verdana", + "presentation_rect" : [ 232.0, 138.0, 100.0, 19.0 ], + "items" : [ "off", ",", "realtime", ",", "offline" ], "types" : [ ], "patching_rect" : [ 418.0, 792.0, 100.0, 19.0 ], + "numinlets" : 1, "presentation" : 1, - "numinlets" : 1, "fontsize" : 10.0, - "items" : [ "off", ",", "realtime", ",", "offline" ], + "id" : "obj-32", "numoutlets" : 3, - "outlettype" : [ "int", "", "" ], - "presentation_rect" : [ 232.0, 138.0, 100.0, 19.0 ], - "id" : "obj-32", - "fontname" : "Verdana" + "outlettype" : [ "int", "", "" ] } } @@ -1652,13 +1851,13 @@ "box" : { "maxclass" : "newobj", "text" : "switch", + "fontname" : "Verdana", "patching_rect" : [ 426.0, 856.0, 46.0, 19.0 ], "numinlets" : 3, "fontsize" : 10.0, + "id" : "obj-31", "numoutlets" : 1, - "outlettype" : [ "" ], - "id" : "obj-31", - "fontname" : "Verdana" + "outlettype" : [ "" ] } } @@ -1666,29 +1865,29 @@ "box" : { "maxclass" : "newobj", "text" : "gate", + "fontname" : "Verdana", "patching_rect" : [ 87.0, 845.0, 33.0, 19.0 ], "numinlets" : 2, "fontsize" : 10.0, + "id" : "obj-30", "numoutlets" : 1, - "outlettype" : [ "" ], - "id" : "obj-30", - "fontname" : "Verdana" + "outlettype" : [ "" ] } } , { "box" : { "maxclass" : "message", - "text" : "75 100 0.386527", + "text" : "59 0 6987.81543", + "fontname" : "Verdana", + "presentation_rect" : [ 32.0, 199.0, 201.0, 17.0 ], "patching_rect" : [ 422.0, 937.0, 201.0, 17.0 ], + "numinlets" : 2, "presentation" : 1, - "numinlets" : 2, "fontsize" : 10.0, + "id" : "obj-29", "numoutlets" : 1, - "outlettype" : [ "" ], - "presentation_rect" : [ 32.0, 199.0, 201.0, 17.0 ], - "id" : "obj-29", - "fontname" : "Verdana" + "outlettype" : [ "" ] } } @@ -1696,13 +1895,13 @@ "box" : { "maxclass" : "newobj", "text" : "prepend set", + "fontname" : "Verdana", "patching_rect" : [ 495.0, 697.0, 70.0, 19.0 ], "numinlets" : 1, "fontsize" : 10.0, + "id" : "obj-27", "numoutlets" : 1, - "outlettype" : [ "" ], - "id" : "obj-27", - "fontname" : "Verdana" + "outlettype" : [ "" ] } } @@ -1710,13 +1909,13 @@ "box" : { "maxclass" : "newobj", "text" : "append", + "fontname" : "Verdana", "patching_rect" : [ 495.0, 725.0, 47.0, 19.0 ], "numinlets" : 1, "fontsize" : 10.0, + "id" : "obj-26", "numoutlets" : 1, - "outlettype" : [ "" ], - "id" : "obj-26", - "fontname" : "Verdana" + "outlettype" : [ "" ] } } @@ -1724,15 +1923,15 @@ "box" : { "maxclass" : "message", "text" : "next", + "fontname" : "Verdana", + "presentation_rect" : [ 22.0, 86.0, 33.0, 17.0 ], "patching_rect" : [ 182.0, 268.0, 33.0, 17.0 ], + "numinlets" : 2, "presentation" : 1, - "numinlets" : 2, "fontsize" : 10.0, + "id" : "obj-25", "numoutlets" : 1, - "outlettype" : [ "" ], - "presentation_rect" : [ 22.0, 86.0, 33.0, 17.0 ], - "id" : "obj-25", - "fontname" : "Verdana" + "outlettype" : [ "" ] } } @@ -1740,14 +1939,14 @@ "box" : { "maxclass" : "comment", "text" : "speed", - "patching_rect" : [ 269.0, 68.0, 150.0, 19.0 ], + "fontname" : "Verdana", + "presentation_rect" : [ 245.0, 62.0, 150.0, 19.0 ], + "patching_rect" : [ 837.0, 516.0, 150.0, 19.0 ], + "numinlets" : 1, "presentation" : 1, - "numinlets" : 1, "fontsize" : 10.0, - "numoutlets" : 0, - "presentation_rect" : [ 245.0, 62.0, 150.0, 19.0 ], "id" : "obj-9", - "fontname" : "Verdana" + "numoutlets" : 0 } } @@ -1755,14 +1954,14 @@ "box" : { "maxclass" : "comment", "text" : "MIDI representation", + "fontname" : "Verdana", + "presentation_rect" : [ 16.0, -3.0, 150.0, 19.0 ], "patching_rect" : [ 1141.0, 862.0, 150.0, 19.0 ], + "numinlets" : 1, "presentation" : 1, - "numinlets" : 1, "fontsize" : 10.0, - "numoutlets" : 0, - "presentation_rect" : [ 16.0, -3.0, 150.0, 19.0 ], "id" : "obj-24", - "fontname" : "Verdana" + "numoutlets" : 0 } } @@ -1770,14 +1969,14 @@ "box" : { "maxclass" : "comment", "text" : "audio", + "fontname" : "Verdana", + "presentation_rect" : [ 14.0, 119.0, 150.0, 19.0 ], "patching_rect" : [ 1126.0, 847.0, 150.0, 19.0 ], + "numinlets" : 1, "presentation" : 1, - "numinlets" : 1, "fontsize" : 10.0, - "numoutlets" : 0, - "presentation_rect" : [ 14.0, 119.0, 150.0, 19.0 ], "id" : "obj-23", - "fontname" : "Verdana" + "numoutlets" : 0 } } @@ -1785,14 +1984,14 @@ "box" : { "maxclass" : "comment", "text" : "send notes", + "fontname" : "Verdana", + "presentation_rect" : [ 149.0, 169.0, 67.0, 19.0 ], "patching_rect" : [ 1243.0, 894.0, 150.0, 19.0 ], + "numinlets" : 1, "presentation" : 1, - "numinlets" : 1, "fontsize" : 10.0, - "numoutlets" : 0, - "presentation_rect" : [ 149.0, 169.0, 67.0, 19.0 ], "id" : "obj-10", - "fontname" : "Verdana" + "numoutlets" : 0 } } @@ -1800,13 +1999,13 @@ "box" : { "maxclass" : "newobj", "text" : "loadmess 1", + "fontname" : "Verdana", "patching_rect" : [ 21.0, 762.0, 68.0, 19.0 ], "numinlets" : 1, "fontsize" : 10.0, + "id" : "obj-3", "numoutlets" : 1, - "outlettype" : [ "" ], - "id" : "obj-3", - "fontname" : "Verdana" + "outlettype" : [ "" ] } } @@ -1815,14 +2014,14 @@ "maxclass" : "comment", "text" : "midi playing on/off", "presentation_linecount" : 2, + "fontname" : "Verdana", + "presentation_rect" : [ 215.0, 84.0, 73.0, 31.0 ], "patching_rect" : [ 712.0, 190.0, 150.0, 19.0 ], + "numinlets" : 1, "presentation" : 1, - "numinlets" : 1, "fontsize" : 10.0, - "numoutlets" : 0, - "presentation_rect" : [ 215.0, 84.0, 73.0, 31.0 ], "id" : "obj-8", - "fontname" : "Verdana" + "numoutlets" : 0 } } @@ -1832,27 +2031,27 @@ "text" : "plays midi and accompanying audio too", "linecount" : 2, "presentation_linecount" : 2, + "fontname" : "Verdana", + "presentation_rect" : [ 337.0, 464.0, 150.0, 31.0 ], "patching_rect" : [ 906.0, 904.0, 150.0, 31.0 ], + "numinlets" : 1, "presentation" : 1, - "numinlets" : 1, "fontsize" : 10.0, - "numoutlets" : 0, - "presentation_rect" : [ 337.0, 464.0, 150.0, 31.0 ], "id" : "obj-6", - "fontname" : "Verdana" + "numoutlets" : 0 } } , { "box" : { "maxclass" : "toggle", - "patching_rect" : [ -33.0, 356.0, 20.0, 20.0 ], + "presentation_rect" : [ 188.0, 84.0, 20.0, 20.0 ], + "patching_rect" : [ -24.0, 341.0, 20.0, 20.0 ], + "numinlets" : 1, "presentation" : 1, - "numinlets" : 1, + "id" : "obj-4", "numoutlets" : 1, - "outlettype" : [ "int" ], - "presentation_rect" : [ 188.0, 84.0, 20.0, 20.0 ], - "id" : "obj-4" + "outlettype" : [ "int" ] } } @@ -1860,13 +2059,13 @@ "box" : { "maxclass" : "newobj", "text" : "gate", + "fontname" : "Verdana", "patching_rect" : [ -15.0, 373.0, 33.0, 19.0 ], "numinlets" : 2, "fontsize" : 10.0, + "id" : "obj-1", "numoutlets" : 1, - "outlettype" : [ "" ], - "id" : "obj-1", - "fontname" : "Verdana" + "outlettype" : [ "" ] } } @@ -1874,13 +2073,13 @@ "box" : { "maxclass" : "newobj", "text" : "loadmess 1", + "fontname" : "Verdana", "patching_rect" : [ -28.0, 861.0, 68.0, 19.0 ], "numinlets" : 1, "fontsize" : 10.0, + "id" : "obj-138", "numoutlets" : 1, - "outlettype" : [ "" ], - "id" : "obj-138", - "fontname" : "Verdana" + "outlettype" : [ "" ] } } @@ -1888,31 +2087,31 @@ "box" : { "maxclass" : "newobj", "text" : "prepend /setSpeedPrior", + "fontname" : "Verdana", + "presentation_rect" : [ 128.0, 383.0, 129.0, 19.0 ], "patching_rect" : [ -29.0, 923.0, 129.0, 19.0 ], + "numinlets" : 1, "presentation" : 1, - "numinlets" : 1, "fontsize" : 10.0, + "id" : "obj-137", "numoutlets" : 1, - "outlettype" : [ "" ], - "presentation_rect" : [ 128.0, 383.0, 129.0, 19.0 ], - "id" : "obj-137", - "fontname" : "Verdana" + "outlettype" : [ "" ] } } , { "box" : { "maxclass" : "flonum", + "fontname" : "Verdana", + "minimum" : 0.0, + "presentation_rect" : [ 133.0, 351.0, 50.0, 19.0 ], "patching_rect" : [ -29.0, 884.0, 50.0, 19.0 ], + "numinlets" : 1, "presentation" : 1, - "numinlets" : 1, "fontsize" : 10.0, + "id" : "obj-136", "numoutlets" : 2, - "minimum" : 0.0, - "outlettype" : [ "float", "bang" ], - "presentation_rect" : [ 133.0, 351.0, 50.0, 19.0 ], - "id" : "obj-136", - "fontname" : "Verdana" + "outlettype" : [ "float", "bang" ] } } @@ -1921,9 +2120,9 @@ "maxclass" : "button", "patching_rect" : [ 204.0, 687.0, 20.0, 20.0 ], "numinlets" : 1, + "id" : "obj-134", "numoutlets" : 1, - "outlettype" : [ "bang" ], - "id" : "obj-134" + "outlettype" : [ "bang" ] } } @@ -1931,15 +2130,15 @@ "box" : { "maxclass" : "message", "text" : "open", - "patching_rect" : [ 320.0, 23.0, 35.0, 17.0 ], + "fontname" : "Verdana", + "presentation_rect" : [ 58.0, 170.0, 35.0, 17.0 ], + "patching_rect" : [ 888.0, 471.0, 35.0, 17.0 ], + "numinlets" : 2, "presentation" : 1, - "numinlets" : 2, "fontsize" : 10.0, + "id" : "obj-113", "numoutlets" : 1, - "outlettype" : [ "" ], - "presentation_rect" : [ 58.0, 170.0, 35.0, 17.0 ], - "id" : "obj-113", - "fontname" : "Verdana" + "outlettype" : [ "" ] } } @@ -1947,13 +2146,13 @@ "box" : { "maxclass" : "message", "text" : "0", - "patching_rect" : [ 281.0, 23.0, 32.5, 17.0 ], + "fontname" : "Verdana", + "patching_rect" : [ 849.0, 471.0, 32.5, 17.0 ], "numinlets" : 2, "fontsize" : 10.0, + "id" : "obj-110", "numoutlets" : 1, - "outlettype" : [ "" ], - "id" : "obj-110", - "fontname" : "Verdana" + "outlettype" : [ "" ] } } @@ -1961,15 +2160,15 @@ "box" : { "maxclass" : "message", "text" : "1", - "patching_rect" : [ 240.0, 23.0, 32.5, 17.0 ], + "fontname" : "Verdana", + "presentation_rect" : [ 19.0, 172.0, 32.5, 17.0 ], + "patching_rect" : [ 808.0, 471.0, 32.5, 17.0 ], + "numinlets" : 2, "presentation" : 1, - "numinlets" : 2, "fontsize" : 10.0, + "id" : "obj-105", "numoutlets" : 1, - "outlettype" : [ "" ], - "presentation_rect" : [ 19.0, 172.0, 32.5, 17.0 ], - "id" : "obj-105", - "fontname" : "Verdana" + "outlettype" : [ "" ] } } @@ -1977,13 +2176,13 @@ "box" : { "maxclass" : "newobj", "text" : "sfplay~ 2", - "patching_rect" : [ 230.0, 46.0, 58.0, 19.0 ], + "fontname" : "Verdana", + "patching_rect" : [ 798.0, 494.0, 58.0, 19.0 ], "numinlets" : 2, "fontsize" : 10.0, + "id" : "obj-65", "numoutlets" : 3, "outlettype" : [ "signal", "signal", "bang" ], - "id" : "obj-65", - "fontname" : "Verdana", "save" : [ "#N", "sfplay~", "", 2, 120960, 0, "", ";" ] } @@ -1991,13 +2190,13 @@ , { "box" : { "maxclass" : "toggle", + "presentation_rect" : [ 126.0, 169.0, 20.0, 20.0 ], "patching_rect" : [ 74.0, 790.0, 20.0, 20.0 ], + "numinlets" : 1, "presentation" : 1, - "numinlets" : 1, + "id" : "obj-109", "numoutlets" : 1, - "outlettype" : [ "int" ], - "presentation_rect" : [ 126.0, 169.0, 20.0, 20.0 ], - "id" : "obj-109" + "outlettype" : [ "int" ] } } @@ -2005,13 +2204,13 @@ "box" : { "maxclass" : "newobj", "text" : "zl slice 1", + "fontname" : "Verdana", "patching_rect" : [ 51.0, 608.0, 54.0, 19.0 ], "numinlets" : 2, "fontsize" : 10.0, + "id" : "obj-82", "numoutlets" : 2, - "outlettype" : [ "", "" ], - "id" : "obj-82", - "fontname" : "Verdana" + "outlettype" : [ "", "" ] } } @@ -2019,13 +2218,13 @@ "box" : { "maxclass" : "ezdac~", "varname" : "autohelp_dac", - "patching_rect" : [ 229.0, 91.0, 45.0, 45.0 ], + "presentation_rect" : [ 186.0, 14.0, 45.0, 45.0 ], + "patching_rect" : [ 797.0, 539.0, 45.0, 45.0 ], + "numinlets" : 2, "presentation" : 1, - "numinlets" : 2, - "numoutlets" : 0, - "presentation_rect" : [ 186.0, 14.0, 45.0, 45.0 ], "id" : "obj-94", - "local" : 1 + "local" : 1, + "numoutlets" : 0 } } @@ -2033,15 +2232,15 @@ "box" : { "maxclass" : "panel", "varname" : "startwinwdow_panel", + "presentation_rect" : [ 12.0, 136.0, 205.0, 57.0 ], + "border" : 2, "patching_rect" : [ 1093.0, 826.0, 100.0, 55.0 ], - "border" : 2, + "bordercolor" : [ 0.392157, 0.792157, 0.117647, 1.0 ], + "numinlets" : 1, "presentation" : 1, - "numinlets" : 1, - "bordercolor" : [ 0.392157, 0.792157, 0.117647, 1.0 ], + "id" : "obj-95", "bgcolor" : [ 1.0, 1.0, 1.0, 1.0 ], - "numoutlets" : 0, - "presentation_rect" : [ 12.0, 136.0, 205.0, 57.0 ], - "id" : "obj-95" + "numoutlets" : 0 } } @@ -2049,13 +2248,13 @@ "box" : { "maxclass" : "newobj", "text" : "zl join", + "fontname" : "Verdana", "patching_rect" : [ 123.0, 777.0, 41.0, 19.0 ], "numinlets" : 2, "fontsize" : 10.0, + "id" : "obj-83", "numoutlets" : 2, - "outlettype" : [ "", "" ], - "id" : "obj-83", - "fontname" : "Verdana" + "outlettype" : [ "", "" ] } } @@ -2063,13 +2262,13 @@ "box" : { "maxclass" : "newobj", "text" : "- 0.", + "fontname" : "Verdana", "patching_rect" : [ 137.0, 746.0, 32.5, 19.0 ], "numinlets" : 2, "fontsize" : 10.0, + "id" : "obj-80", "numoutlets" : 1, - "outlettype" : [ "float" ], - "id" : "obj-80", - "fontname" : "Verdana" + "outlettype" : [ "float" ] } } @@ -2077,13 +2276,13 @@ "box" : { "maxclass" : "newobj", "text" : "t l b", + "fontname" : "Verdana", "patching_rect" : [ 123.0, 688.0, 32.5, 19.0 ], "numinlets" : 1, "fontsize" : 10.0, + "id" : "obj-79", "numoutlets" : 2, - "outlettype" : [ "", "bang" ], - "id" : "obj-79", - "fontname" : "Verdana" + "outlettype" : [ "", "bang" ] } } @@ -2091,13 +2290,13 @@ "box" : { "maxclass" : "newobj", "text" : "cpuclock", + "fontname" : "Verdana", "patching_rect" : [ 204.0, 717.0, 53.0, 19.0 ], "numinlets" : 1, "fontsize" : 10.0, + "id" : "obj-78", "numoutlets" : 1, - "outlettype" : [ "float" ], - "id" : "obj-78", - "fontname" : "Verdana" + "outlettype" : [ "float" ] } } @@ -2105,24 +2304,24 @@ "box" : { "maxclass" : "newobj", "text" : "cpuclock", + "fontname" : "Verdana", "patching_rect" : [ 137.0, 716.0, 53.0, 19.0 ], "numinlets" : 1, "fontsize" : 10.0, + "id" : "obj-76", "numoutlets" : 1, - "outlettype" : [ "float" ], - "id" : "obj-76", - "fontname" : "Verdana" + "outlettype" : [ "float" ] } } , { "box" : { "maxclass" : "button", - "patching_rect" : [ 598.0, 327.0, 20.0, 20.0 ], + "patching_rect" : [ 307.0, 525.0, 20.0, 20.0 ], "numinlets" : 1, + "id" : "obj-71", "numoutlets" : 1, - "outlettype" : [ "bang" ], - "id" : "obj-71" + "outlettype" : [ "bang" ] } } @@ -2130,24 +2329,24 @@ "box" : { "maxclass" : "message", "text" : "/stopplaying", - "patching_rect" : [ 653.0, 361.0, 73.0, 17.0 ], + "fontname" : "Verdana", + "patching_rect" : [ 334.0, 576.0, 73.0, 17.0 ], "numinlets" : 2, "fontsize" : 10.0, + "id" : "obj-72", "numoutlets" : 1, - "outlettype" : [ "" ], - "id" : "obj-72", - "fontname" : "Verdana" + "outlettype" : [ "" ] } } , { "box" : { "maxclass" : "button", - "patching_rect" : [ 418.0, -27.0, 20.0, 20.0 ], + "patching_rect" : [ 419.0, 172.0, 20.0, 20.0 ], "numinlets" : 1, + "id" : "obj-70", "numoutlets" : 1, - "outlettype" : [ "bang" ], - "id" : "obj-70" + "outlettype" : [ "bang" ] } } @@ -2155,13 +2354,13 @@ "box" : { "maxclass" : "message", "text" : "/startplaying", + "fontname" : "Verdana", "patching_rect" : [ 241.0, 653.0, 75.0, 17.0 ], "numinlets" : 2, "fontsize" : 10.0, + "id" : "obj-63", "numoutlets" : 1, - "outlettype" : [ "" ], - "id" : "obj-63", - "fontname" : "Verdana" + "outlettype" : [ "" ] } } @@ -2169,13 +2368,13 @@ "box" : { "maxclass" : "newobj", "text" : "prepend /midinoteon", + "fontname" : "Verdana", "patching_rect" : [ 262.0, 939.0, 116.0, 19.0 ], "numinlets" : 1, "fontsize" : 10.0, + "id" : "obj-69", "numoutlets" : 1, - "outlettype" : [ "" ], - "id" : "obj-69", - "fontname" : "Verdana" + "outlettype" : [ "" ] } } @@ -2183,26 +2382,26 @@ "box" : { "maxclass" : "newobj", "text" : "udpsend 127.0.0.1 12121", + "fontname" : "Verdana", "patching_rect" : [ 229.0, 962.0, 141.0, 19.0 ], "numinlets" : 1, "fontsize" : 10.0, - "numoutlets" : 0, "id" : "obj-68", - "fontname" : "Verdana" + "numoutlets" : 0 } } , { "box" : { "maxclass" : "message", - "text" : "75 100", + "text" : "59 0", + "fontname" : "Verdana", "patching_rect" : [ 58.0, 637.0, 50.0, 17.0 ], "numinlets" : 2, "fontsize" : 10.0, + "id" : "obj-67", "numoutlets" : 1, - "outlettype" : [ "" ], - "id" : "obj-67", - "fontname" : "Verdana" + "outlettype" : [ "" ] } } @@ -2210,21 +2409,21 @@ "box" : { "maxclass" : "ftm.object", "text" : "sequence midi", + "fontname" : "Verdana", "persistence" : 0, + "presentation_rect" : [ 712.0, 250.0, 161.785156, 20.0 ], "description" : "sequence midi", + "editor_interface" : "matrix", "patching_rect" : [ 712.0, 250.0, 161.785156, 20.0 ], - "editor_interface" : "matrix", "numinlets" : 1, + "scope" : 0, "fontsize" : 12.0, - "ftm_scope" : 2, - "scope" : 0, + "id" : "obj-14", + "name" : "play.seq", + "ftm_objref_conv" : 0, "numoutlets" : 2, "outlettype" : [ "", "" ], - "ftm_objref_conv" : 0, - "presentation_rect" : [ 712.0, 250.0, 161.785156, 20.0 ], - "id" : "obj-14", - "fontname" : "Verdana", - "name" : "play.seq" + "ftm_scope" : 2 } } @@ -2232,15 +2431,15 @@ "box" : { "maxclass" : "message", "text" : "import", + "fontname" : "Verdana", + "presentation_rect" : [ 19.0, 57.0, 43.0, 17.0 ], "patching_rect" : [ 712.0, 222.0, 43.0, 17.0 ], + "numinlets" : 2, "presentation" : 1, - "numinlets" : 2, "fontsize" : 10.0, + "id" : "obj-15", "numoutlets" : 1, - "outlettype" : [ "" ], - "presentation_rect" : [ 19.0, 57.0, 43.0, 17.0 ], - "id" : "obj-15", - "fontname" : "Verdana" + "outlettype" : [ "" ] } } @@ -2248,14 +2447,14 @@ "box" : { "maxclass" : "comment", "text" : "import MIDI file", + "fontname" : "Verdana", + "presentation_rect" : [ 60.0, 56.0, 90.0, 19.0 ], "patching_rect" : [ 757.0, 221.0, 90.0, 19.0 ], + "numinlets" : 1, "presentation" : 1, - "numinlets" : 1, "fontsize" : 10.0, - "numoutlets" : 0, - "presentation_rect" : [ 60.0, 56.0, 90.0, 19.0 ], "id" : "obj-16", - "fontname" : "Verdana" + "numoutlets" : 0 } } @@ -2263,12 +2462,12 @@ "box" : { "maxclass" : "comment", "text" : "play an FTM track", + "fontname" : "Verdana", "patching_rect" : [ 60.0, 23.0, 98.0, 19.0 ], "numinlets" : 1, "fontsize" : 10.0, - "numoutlets" : 0, "id" : "obj-17", - "fontname" : "Verdana" + "numoutlets" : 0 } } @@ -2276,12 +2475,12 @@ "box" : { "maxclass" : "comment", "text" : "ftm.play", + "fontname" : "Verdana", "patching_rect" : [ 54.0, -10.0, 108.0, 36.0 ], "numinlets" : 1, "fontsize" : 24.0, - "numoutlets" : 0, "id" : "obj-18", - "fontname" : "Verdana" + "numoutlets" : 0 } } @@ -2289,12 +2488,12 @@ "box" : { "maxclass" : "comment", "text" : "FTM basic objects", + "fontname" : "Verdana", "patching_rect" : [ 48.0, -22.0, 97.0, 19.0 ], "numinlets" : 1, "fontsize" : 10.0, - "numoutlets" : 0, "id" : "obj-19", - "fontname" : "Verdana" + "numoutlets" : 0 } } @@ -2304,8 +2503,8 @@ "patching_rect" : [ 8.0, -25.0, 54.0, 74.0 ], "pic" : "ftm.help.jpg", "numinlets" : 1, - "numoutlets" : 0, - "id" : "obj-20" + "id" : "obj-20", + "numoutlets" : 0 } } @@ -2313,12 +2512,12 @@ "box" : { "maxclass" : "newobj", "text" : "midiout", + "fontname" : "Verdana", "patching_rect" : [ -9.0, 401.0, 48.0, 19.0 ], "numinlets" : 1, "fontsize" : 10.0, - "numoutlets" : 0, "id" : "obj-44", - "fontname" : "Verdana" + "numoutlets" : 0 } } @@ -2326,15 +2525,15 @@ "box" : { "maxclass" : "message", "text" : "play", - "patching_rect" : [ 424.0, 52.0, 52.0, 26.0 ], + "fontname" : "Verdana", + "presentation_rect" : [ 18.0, 22.0, 52.0, 26.0 ], + "patching_rect" : [ 409.0, 130.0, 52.0, 26.0 ], + "numinlets" : 2, "presentation" : 1, - "numinlets" : 2, "fontsize" : 18.0, + "id" : "obj-46", "numoutlets" : 1, - "outlettype" : [ "" ], - "presentation_rect" : [ 18.0, 22.0, 52.0, 26.0 ], - "id" : "obj-46", - "fontname" : "Verdana" + "outlettype" : [ "" ] } } @@ -2342,15 +2541,15 @@ "box" : { "maxclass" : "message", "text" : "stop", - "patching_rect" : [ 539.0, 55.0, 51.0, 26.0 ], + "fontname" : "Verdana", + "presentation_rect" : [ 86.0, 22.0, 51.0, 26.0 ], + "patching_rect" : [ 306.0, 129.0, 51.0, 26.0 ], + "numinlets" : 2, "presentation" : 1, - "numinlets" : 2, "fontsize" : 18.0, + "id" : "obj-49", "numoutlets" : 1, - "outlettype" : [ "" ], - "presentation_rect" : [ 86.0, 22.0, 51.0, 26.0 ], - "id" : "obj-49", - "fontname" : "Verdana" + "outlettype" : [ "" ] } } @@ -2358,12 +2557,12 @@ "box" : { "maxclass" : "comment", "text" : "set segment (track, begin, end and speed)", - "patching_rect" : [ 402.0, 91.0, 226.0, 19.0 ], + "fontname" : "Verdana", + "patching_rect" : [ 809.0, 151.0, 226.0, 19.0 ], "numinlets" : 1, "fontsize" : 10.0, - "numoutlets" : 0, "id" : "obj-56", - "fontname" : "Verdana" + "numoutlets" : 0 } } @@ -2371,23 +2570,446 @@ "box" : { "maxclass" : "panel", "varname" : "startwinwdow_panel[1]", + "presentation_rect" : [ 12.0, 17.0, 167.0, 98.0 ], + "border" : 2, "patching_rect" : [ 1093.0, 886.0, 100.0, 55.0 ], - "border" : 2, + "bordercolor" : [ 0.392157, 0.792157, 0.117647, 1.0 ], + "numinlets" : 1, "presentation" : 1, - "numinlets" : 1, - "bordercolor" : [ 0.392157, 0.792157, 0.117647, 1.0 ], + "id" : "obj-5", "bgcolor" : [ 1.0, 1.0, 1.0, 1.0 ], - "numoutlets" : 0, - "presentation_rect" : [ 12.0, 17.0, 167.0, 98.0 ], - "id" : "obj-5" + "numoutlets" : 0 } } ], "lines" : [ { "patchline" : { - "source" : [ "obj-99", 0 ], - "destination" : [ "obj-60", 1 ], + "source" : [ "obj-28", 0 ], + "destination" : [ "obj-4", 0 ], + "hidden" : 0, + "midpoints" : [ ] + } + + } +, { + "patchline" : { + "source" : [ "obj-82", 1 ], + "destination" : [ "obj-48", 1 ], + "hidden" : 0, + "midpoints" : [ ] + } + + } +, { + "patchline" : { + "source" : [ "obj-42", 0 ], + "destination" : [ "obj-39", 0 ], + "hidden" : 0, + "midpoints" : [ ] + } + + } +, { + "patchline" : { + "source" : [ "obj-47", 0 ], + "destination" : [ "obj-42", 0 ], + "hidden" : 0, + "midpoints" : [ ] + } + + } +, { + "patchline" : { + "source" : [ "obj-39", 0 ], + "destination" : [ "obj-21", 0 ], + "hidden" : 0, + "midpoints" : [ ] + } + + } +, { + "patchline" : { + "source" : [ "obj-41", 0 ], + "destination" : [ "obj-11", 0 ], + "hidden" : 0, + "midpoints" : [ ] + } + + } +, { + "patchline" : { + "source" : [ "obj-71", 0 ], + "destination" : [ "obj-41", 0 ], + "hidden" : 0, + "midpoints" : [ ] + } + + } +, { + "patchline" : { + "source" : [ "obj-37", 0 ], + "destination" : [ "obj-36", 0 ], + "hidden" : 0, + "midpoints" : [ ] + } + + } +, { + "patchline" : { + "source" : [ "obj-36", 0 ], + "destination" : [ "obj-2", 1 ], + "hidden" : 0, + "midpoints" : [ ] + } + + } +, { + "patchline" : { + "source" : [ "obj-2", 0 ], + "destination" : [ "obj-25", 0 ], + "hidden" : 0, + "midpoints" : [ ] + } + + } +, { + "patchline" : { + "source" : [ "obj-11", 0 ], + "destination" : [ "obj-2", 0 ], + "hidden" : 0, + "midpoints" : [ ] + } + + } +, { + "patchline" : { + "source" : [ "obj-3", 0 ], + "destination" : [ "obj-109", 0 ], + "hidden" : 0, + "midpoints" : [ ] + } + + } +, { + "patchline" : { + "source" : [ "obj-71", 0 ], + "destination" : [ "obj-110", 0 ], + "hidden" : 0, + "midpoints" : [ ] + } + + } +, { + "patchline" : { + "source" : [ "obj-82", 1 ], + "destination" : [ "obj-79", 0 ], + "hidden" : 0, + "midpoints" : [ ] + } + + } +, { + "patchline" : { + "source" : [ "obj-136", 0 ], + "destination" : [ "obj-137", 0 ], + "hidden" : 0, + "midpoints" : [ ] + } + + } +, { + "patchline" : { + "source" : [ "obj-137", 0 ], + "destination" : [ "obj-68", 0 ], + "hidden" : 0, + "midpoints" : [ ] + } + + } +, { + "patchline" : { + "source" : [ "obj-138", 0 ], + "destination" : [ "obj-136", 0 ], + "hidden" : 0, + "midpoints" : [ ] + } + + } +, { + "patchline" : { + "source" : [ "obj-134", 0 ], + "destination" : [ "obj-78", 0 ], + "hidden" : 0, + "midpoints" : [ ] + } + + } +, { + "patchline" : { + "source" : [ "obj-63", 0 ], + "destination" : [ "obj-134", 0 ], + "hidden" : 0, + "midpoints" : [ ] + } + + } +, { + "patchline" : { + "source" : [ "obj-80", 0 ], + "destination" : [ "obj-83", 1 ], + "hidden" : 0, + "midpoints" : [ ] + } + + } +, { + "patchline" : { + "source" : [ "obj-76", 0 ], + "destination" : [ "obj-80", 0 ], + "hidden" : 0, + "midpoints" : [ ] + } + + } +, { + "patchline" : { + "source" : [ "obj-78", 0 ], + "destination" : [ "obj-80", 1 ], + "hidden" : 0, + "midpoints" : [ ] + } + + } +, { + "patchline" : { + "source" : [ "obj-79", 1 ], + "destination" : [ "obj-76", 0 ], + "hidden" : 0, + "midpoints" : [ ] + } + + } +, { + "patchline" : { + "source" : [ "obj-69", 0 ], + "destination" : [ "obj-68", 0 ], + "hidden" : 0, + "midpoints" : [ ] + } + + } +, { + "patchline" : { + "source" : [ "obj-15", 0 ], + "destination" : [ "obj-14", 0 ], + "hidden" : 0, + "midpoints" : [ ] + } + + } +, { + "patchline" : { + "source" : [ "obj-46", 0 ], + "destination" : [ "obj-70", 0 ], + "hidden" : 0, + "midpoints" : [ ] + } + + } +, { + "patchline" : { + "source" : [ "obj-63", 0 ], + "destination" : [ "obj-68", 0 ], + "hidden" : 0, + "midpoints" : [ ] + } + + } +, { + "patchline" : { + "source" : [ "obj-71", 0 ], + "destination" : [ "obj-72", 0 ], + "hidden" : 0, + "midpoints" : [ ] + } + + } +, { + "patchline" : { + "source" : [ "obj-72", 0 ], + "destination" : [ "obj-68", 0 ], + "hidden" : 0, + "midpoints" : [ ] + } + + } +, { + "patchline" : { + "source" : [ "obj-49", 0 ], + "destination" : [ "obj-71", 0 ], + "hidden" : 0, + "midpoints" : [ ] + } + + } +, { + "patchline" : { + "source" : [ "obj-82", 1 ], + "destination" : [ "obj-67", 1 ], + "hidden" : 0, + "midpoints" : [ ] + } + + } +, { + "patchline" : { + "source" : [ "obj-79", 0 ], + "destination" : [ "obj-83", 0 ], + "hidden" : 0, + "midpoints" : [ ] + } + + } +, { + "patchline" : { + "source" : [ "obj-70", 0 ], + "destination" : [ "obj-105", 0 ], + "hidden" : 0, + "midpoints" : [ ] + } + + } +, { + "patchline" : { + "source" : [ "obj-113", 0 ], + "destination" : [ "obj-65", 0 ], + "hidden" : 0, + "midpoints" : [ ] + } + + } +, { + "patchline" : { + "source" : [ "obj-105", 0 ], + "destination" : [ "obj-65", 0 ], + "hidden" : 0, + "midpoints" : [ ] + } + + } +, { + "patchline" : { + "source" : [ "obj-110", 0 ], + "destination" : [ "obj-65", 0 ], + "hidden" : 0, + "midpoints" : [ ] + } + + } +, { + "patchline" : { + "source" : [ "obj-65", 0 ], + "destination" : [ "obj-94", 0 ], + "hidden" : 0, + "midpoints" : [ ] + } + + } +, { + "patchline" : { + "source" : [ "obj-65", 1 ], + "destination" : [ "obj-94", 1 ], + "hidden" : 0, + "midpoints" : [ ] + } + + } +, { + "patchline" : { + "source" : [ "obj-1", 0 ], + "destination" : [ "obj-44", 0 ], + "hidden" : 0, + "midpoints" : [ ] + } + + } +, { + "patchline" : { + "source" : [ "obj-4", 0 ], + "destination" : [ "obj-1", 0 ], + "hidden" : 0, + "midpoints" : [ ] + } + + } +, { + "patchline" : { + "source" : [ "obj-27", 0 ], + "destination" : [ "obj-26", 0 ], + "hidden" : 0, + "midpoints" : [ ] + } + + } +, { + "patchline" : { + "source" : [ "obj-82", 1 ], + "destination" : [ "obj-26", 0 ], + "hidden" : 0, + "midpoints" : [ ] + } + + } +, { + "patchline" : { + "source" : [ "obj-109", 0 ], + "destination" : [ "obj-30", 0 ], + "hidden" : 0, + "midpoints" : [ ] + } + + } +, { + "patchline" : { + "source" : [ "obj-83", 0 ], + "destination" : [ "obj-30", 1 ], + "hidden" : 0, + "midpoints" : [ ] + } + + } +, { + "patchline" : { + "source" : [ "obj-26", 0 ], + "destination" : [ "obj-31", 2 ], + "hidden" : 0, + "midpoints" : [ ] + } + + } +, { + "patchline" : { + "source" : [ "obj-30", 0 ], + "destination" : [ "obj-31", 1 ], + "hidden" : 0, + "midpoints" : [ ] + } + + } +, { + "patchline" : { + "source" : [ "obj-33", 0 ], + "destination" : [ "obj-32", 0 ], + "hidden" : 0, + "midpoints" : [ ] + } + + } +, { + "patchline" : { + "source" : [ "obj-32", 0 ], + "destination" : [ "obj-31", 0 ], "hidden" : 0, "midpoints" : [ ] } @@ -2396,7 +3018,7 @@ , { "patchline" : { "source" : [ "obj-31", 0 ], - "destination" : [ "obj-69", 0 ], + "destination" : [ "obj-29", 1 ], "hidden" : 0, "midpoints" : [ ] } @@ -2404,7 +3026,106 @@ } , { "patchline" : { - "source" : [ "obj-74", 0 ], + "source" : [ "obj-48", 0 ], + "destination" : [ "obj-63", 0 ], + "hidden" : 0, + "midpoints" : [ ] + } + + } +, { + "patchline" : { + "source" : [ "obj-71", 0 ], + "destination" : [ "obj-48", 0 ], + "hidden" : 0, + "midpoints" : [ ] + } + + } +, { + "patchline" : { + "source" : [ "obj-60", 1 ], + "destination" : [ "obj-27", 0 ], + "hidden" : 0, + "midpoints" : [ ] + } + + } +, { + "patchline" : { + "source" : [ "obj-60", 0 ], + "destination" : [ "obj-1", 1 ], + "hidden" : 0, + "midpoints" : [ ] + } + + } +, { + "patchline" : { + "source" : [ "obj-60", 0 ], + "destination" : [ "obj-82", 0 ], + "hidden" : 0, + "midpoints" : [ ] + } + + } +, { + "patchline" : { + "source" : [ "obj-55", 0 ], + "destination" : [ "obj-60", 0 ], + "hidden" : 0, + "midpoints" : [ ] + } + + } +, { + "patchline" : { + "source" : [ "obj-25", 0 ], + "destination" : [ "obj-60", 0 ], + "hidden" : 0, + "midpoints" : [ ] + } + + } +, { + "patchline" : { + "source" : [ "obj-46", 0 ], + "destination" : [ "obj-60", 0 ], + "hidden" : 0, + "midpoints" : [ ] + } + + } +, { + "patchline" : { + "source" : [ "obj-49", 0 ], + "destination" : [ "obj-60", 0 ], + "hidden" : 0, + "midpoints" : [ ] + } + + } +, { + "patchline" : { + "source" : [ "obj-32", 0 ], + "destination" : [ "obj-64", 0 ], + "hidden" : 0, + "midpoints" : [ ] + } + + } +, { + "patchline" : { + "source" : [ "obj-64", 0 ], + "destination" : [ "obj-73", 0 ], + "hidden" : 0, + "midpoints" : [ ] + } + + } +, { + "patchline" : { + "source" : [ "obj-73", 0 ], "destination" : [ "obj-68", 0 ], "hidden" : 0, "midpoints" : [ ] @@ -2422,7 +3143,7 @@ } , { "patchline" : { - "source" : [ "obj-73", 0 ], + "source" : [ "obj-74", 0 ], "destination" : [ "obj-68", 0 ], "hidden" : 0, "midpoints" : [ ] @@ -2431,8 +3152,8 @@ } , { "patchline" : { - "source" : [ "obj-64", 0 ], - "destination" : [ "obj-73", 0 ], + "source" : [ "obj-31", 0 ], + "destination" : [ "obj-69", 0 ], "hidden" : 0, "midpoints" : [ ] } @@ -2440,8 +3161,8 @@ } , { "patchline" : { - "source" : [ "obj-32", 0 ], - "destination" : [ "obj-64", 0 ], + "source" : [ "obj-99", 0 ], + "destination" : [ "obj-60", 1 ], "hidden" : 0, "midpoints" : [ ] } @@ -2449,8 +3170,8 @@ } , { "patchline" : { - "source" : [ "obj-49", 0 ], - "destination" : [ "obj-60", 0 ], + "source" : [ "obj-12", 0 ], + "destination" : [ "obj-13", 0 ], "hidden" : 0, "midpoints" : [ ] } @@ -2458,8 +3179,8 @@ } , { "patchline" : { - "source" : [ "obj-46", 0 ], - "destination" : [ "obj-60", 0 ], + "source" : [ "obj-13", 0 ], + "destination" : [ "obj-68", 0 ], "hidden" : 0, "midpoints" : [ ] } @@ -2467,8 +3188,8 @@ } , { "patchline" : { - "source" : [ "obj-25", 0 ], - "destination" : [ "obj-60", 0 ], + "source" : [ "obj-22", 0 ], + "destination" : [ "obj-38", 0 ], "hidden" : 0, "midpoints" : [ ] } @@ -2476,8 +3197,8 @@ } , { "patchline" : { - "source" : [ "obj-55", 0 ], - "destination" : [ "obj-60", 0 ], + "source" : [ "obj-38", 0 ], + "destination" : [ "obj-35", 0 ], "hidden" : 0, "midpoints" : [ ] } @@ -2485,8 +3206,8 @@ } , { "patchline" : { - "source" : [ "obj-60", 0 ], - "destination" : [ "obj-82", 0 ], + "source" : [ "obj-38", 1 ], + "destination" : [ "obj-40", 0 ], "hidden" : 0, "midpoints" : [ ] } @@ -2494,8 +3215,8 @@ } , { "patchline" : { - "source" : [ "obj-60", 0 ], - "destination" : [ "obj-1", 1 ], + "source" : [ "obj-35", 0 ], + "destination" : [ "obj-68", 0 ], "hidden" : 0, "midpoints" : [ ] } @@ -2503,8 +3224,8 @@ } , { "patchline" : { - "source" : [ "obj-60", 1 ], - "destination" : [ "obj-27", 0 ], + "source" : [ "obj-40", 0 ], + "destination" : [ "obj-68", 0 ], "hidden" : 0, "midpoints" : [ ] } @@ -2512,8 +3233,8 @@ } , { "patchline" : { - "source" : [ "obj-71", 0 ], - "destination" : [ "obj-48", 0 ], + "source" : [ "obj-35", 0 ], + "destination" : [ "obj-43", 1 ], "hidden" : 0, "midpoints" : [ ] } @@ -2521,107 +3242,8 @@ } , { "patchline" : { - "source" : [ "obj-82", 1 ], - "destination" : [ "obj-48", 1 ], - "hidden" : 0, - "midpoints" : [ ] - } - - } -, { - "patchline" : { - "source" : [ "obj-48", 0 ], - "destination" : [ "obj-63", 0 ], - "hidden" : 0, - "midpoints" : [ ] - } - - } -, { - "patchline" : { - "source" : [ "obj-31", 0 ], - "destination" : [ "obj-29", 1 ], - "hidden" : 0, - "midpoints" : [ ] - } - - } -, { - "patchline" : { - "source" : [ "obj-32", 0 ], - "destination" : [ "obj-31", 0 ], - "hidden" : 0, - "midpoints" : [ ] - } - - } -, { - "patchline" : { - "source" : [ "obj-33", 0 ], - "destination" : [ "obj-32", 0 ], - "hidden" : 0, - "midpoints" : [ ] - } - - } -, { - "patchline" : { - "source" : [ "obj-30", 0 ], - "destination" : [ "obj-31", 1 ], - "hidden" : 0, - "midpoints" : [ ] - } - - } -, { - "patchline" : { - "source" : [ "obj-26", 0 ], - "destination" : [ "obj-31", 2 ], - "hidden" : 0, - "midpoints" : [ ] - } - - } -, { - "patchline" : { - "source" : [ "obj-83", 0 ], - "destination" : [ "obj-30", 1 ], - "hidden" : 0, - "midpoints" : [ ] - } - - } -, { - "patchline" : { - "source" : [ "obj-109", 0 ], - "destination" : [ "obj-30", 0 ], - "hidden" : 0, - "midpoints" : [ ] - } - - } -, { - "patchline" : { - "source" : [ "obj-82", 1 ], - "destination" : [ "obj-26", 0 ], - "hidden" : 0, - "midpoints" : [ ] - } - - } -, { - "patchline" : { - "source" : [ "obj-27", 0 ], - "destination" : [ "obj-26", 0 ], - "hidden" : 0, - "midpoints" : [ ] - } - - } -, { - "patchline" : { - "source" : [ "obj-4", 0 ], - "destination" : [ "obj-1", 0 ], + "source" : [ "obj-40", 0 ], + "destination" : [ "obj-43", 1 ], "hidden" : 0, "midpoints" : [ ] } @@ -2630,304 +3252,7 @@ , { "patchline" : { "source" : [ "obj-1", 0 ], - "destination" : [ "obj-44", 0 ], - "hidden" : 0, - "midpoints" : [ ] - } - - } -, { - "patchline" : { - "source" : [ "obj-65", 1 ], - "destination" : [ "obj-94", 1 ], - "hidden" : 0, - "midpoints" : [ ] - } - - } -, { - "patchline" : { - "source" : [ "obj-65", 0 ], - "destination" : [ "obj-94", 0 ], - "hidden" : 0, - "midpoints" : [ ] - } - - } -, { - "patchline" : { - "source" : [ "obj-110", 0 ], - "destination" : [ "obj-65", 0 ], - "hidden" : 0, - "midpoints" : [ ] - } - - } -, { - "patchline" : { - "source" : [ "obj-105", 0 ], - "destination" : [ "obj-65", 0 ], - "hidden" : 0, - "midpoints" : [ ] - } - - } -, { - "patchline" : { - "source" : [ "obj-113", 0 ], - "destination" : [ "obj-65", 0 ], - "hidden" : 0, - "midpoints" : [ ] - } - - } -, { - "patchline" : { - "source" : [ "obj-70", 0 ], - "destination" : [ "obj-105", 0 ], - "hidden" : 0, - "midpoints" : [ ] - } - - } -, { - "patchline" : { - "source" : [ "obj-79", 0 ], - "destination" : [ "obj-83", 0 ], - "hidden" : 0, - "midpoints" : [ ] - } - - } -, { - "patchline" : { - "source" : [ "obj-82", 1 ], - "destination" : [ "obj-67", 1 ], - "hidden" : 0, - "midpoints" : [ ] - } - - } -, { - "patchline" : { - "source" : [ "obj-49", 0 ], - "destination" : [ "obj-71", 0 ], - "hidden" : 0, - "midpoints" : [ ] - } - - } -, { - "patchline" : { - "source" : [ "obj-72", 0 ], - "destination" : [ "obj-68", 0 ], - "hidden" : 0, - "midpoints" : [ ] - } - - } -, { - "patchline" : { - "source" : [ "obj-71", 0 ], - "destination" : [ "obj-72", 0 ], - "hidden" : 0, - "midpoints" : [ ] - } - - } -, { - "patchline" : { - "source" : [ "obj-63", 0 ], - "destination" : [ "obj-68", 0 ], - "hidden" : 0, - "midpoints" : [ ] - } - - } -, { - "patchline" : { - "source" : [ "obj-46", 0 ], - "destination" : [ "obj-70", 0 ], - "hidden" : 0, - "midpoints" : [ ] - } - - } -, { - "patchline" : { - "source" : [ "obj-15", 0 ], - "destination" : [ "obj-14", 0 ], - "hidden" : 0, - "midpoints" : [ ] - } - - } -, { - "patchline" : { - "source" : [ "obj-69", 0 ], - "destination" : [ "obj-68", 0 ], - "hidden" : 0, - "midpoints" : [ ] - } - - } -, { - "patchline" : { - "source" : [ "obj-79", 1 ], - "destination" : [ "obj-76", 0 ], - "hidden" : 0, - "midpoints" : [ ] - } - - } -, { - "patchline" : { - "source" : [ "obj-78", 0 ], - "destination" : [ "obj-80", 1 ], - "hidden" : 0, - "midpoints" : [ ] - } - - } -, { - "patchline" : { - "source" : [ "obj-76", 0 ], - "destination" : [ "obj-80", 0 ], - "hidden" : 0, - "midpoints" : [ ] - } - - } -, { - "patchline" : { - "source" : [ "obj-80", 0 ], - "destination" : [ "obj-83", 1 ], - "hidden" : 0, - "midpoints" : [ ] - } - - } -, { - "patchline" : { - "source" : [ "obj-63", 0 ], - "destination" : [ "obj-134", 0 ], - "hidden" : 0, - "midpoints" : [ ] - } - - } -, { - "patchline" : { - "source" : [ "obj-134", 0 ], - "destination" : [ "obj-78", 0 ], - "hidden" : 0, - "midpoints" : [ ] - } - - } -, { - "patchline" : { - "source" : [ "obj-138", 0 ], - "destination" : [ "obj-136", 0 ], - "hidden" : 0, - "midpoints" : [ ] - } - - } -, { - "patchline" : { - "source" : [ "obj-137", 0 ], - "destination" : [ "obj-68", 0 ], - "hidden" : 0, - "midpoints" : [ ] - } - - } -, { - "patchline" : { - "source" : [ "obj-136", 0 ], - "destination" : [ "obj-137", 0 ], - "hidden" : 0, - "midpoints" : [ ] - } - - } -, { - "patchline" : { - "source" : [ "obj-82", 1 ], - "destination" : [ "obj-79", 0 ], - "hidden" : 0, - "midpoints" : [ ] - } - - } -, { - "patchline" : { - "source" : [ "obj-71", 0 ], - "destination" : [ "obj-110", 0 ], - "hidden" : 0, - "midpoints" : [ ] - } - - } -, { - "patchline" : { - "source" : [ "obj-3", 0 ], - "destination" : [ "obj-109", 0 ], - "hidden" : 0, - "midpoints" : [ ] - } - - } -, { - "patchline" : { - "source" : [ "obj-11", 0 ], - "destination" : [ "obj-2", 0 ], - "hidden" : 0, - "midpoints" : [ ] - } - - } -, { - "patchline" : { - "source" : [ "obj-2", 0 ], - "destination" : [ "obj-25", 0 ], - "hidden" : 0, - "midpoints" : [ ] - } - - } -, { - "patchline" : { - "source" : [ "obj-36", 0 ], - "destination" : [ "obj-2", 1 ], - "hidden" : 0, - "midpoints" : [ ] - } - - } -, { - "patchline" : { - "source" : [ "obj-37", 0 ], - "destination" : [ "obj-36", 0 ], - "hidden" : 0, - "midpoints" : [ ] - } - - } -, { - "patchline" : { - "source" : [ "obj-71", 0 ], - "destination" : [ "obj-41", 0 ], - "hidden" : 0, - "midpoints" : [ ] - } - - } -, { - "patchline" : { - "source" : [ "obj-41", 0 ], - "destination" : [ "obj-11", 0 ], + "destination" : [ "obj-50", 1 ], "hidden" : 0, "midpoints" : [ ] }
--- a/midiFileReader/MIDIFileReader.h Wed Nov 30 12:35:04 2011 +0000 +++ b/midiFileReader/MIDIFileReader.h Sat Dec 03 17:19:43 2011 +0000 @@ -87,6 +87,7 @@ std::ifstream *m_midiFile; size_t m_fileSize; std::string m_error; + };
--- a/src/BayesianArrayStructure.cpp Wed Nov 30 12:35:04 2011 +0000 +++ b/src/BayesianArrayStructure.cpp Sat Dec 03 17:19:43 2011 +0000 @@ -30,6 +30,7 @@ tmpBestEstimate = 0; crossUpdateTimeThreshold = 60; priorWidth = 50; + usingIntegratedTempoEstimate = true;//use max index } BayesianArrayStructure::BayesianArrayStructure(int length){ @@ -40,7 +41,7 @@ posterior.createVector(length); lastEventTime = 0; - usingIntegratedTempoEstimate = true;//use max index + }
--- a/src/main.cpp Wed Nov 30 12:35:04 2011 +0000 +++ b/src/main.cpp Sat Dec 03 17:19:43 2011 +0000 @@ -3,8 +3,11 @@ #include "ofAppGlutWindow.h" //======================================================================== -int main( ){ +int main(int argc, char * const argv[]){ + if (argc > 0){ + cout << "arg is " << argv[1] << endl; + } ofAppGlutWindow window; ofSetupOpenGL(&window, 1024,768, OF_WINDOW); // <-------- setup the GL context @@ -14,3 +17,4 @@ ofRunApp( new testApp()); } +
--- a/src/midiEventHolder.cpp Wed Nov 30 12:35:04 2011 +0000 +++ b/src/midiEventHolder.cpp Sat Dec 03 17:19:43 2011 +0000 @@ -130,7 +130,7 @@ } void midiEventHolder::newNoteOnEvent(int pitch, int velocity, double timePlayed){ - tempoSpeedString = ""; +// tempoSpeedString = ""; //MOVE INTO BAYESSTRUCT?? XXX //bayesStruct.copyPriorToPosterior(); @@ -162,7 +162,8 @@ - printf("note %i played at %f and last event %f time difference %f and current best estmate %f\n", pitch, timePlayed, bayesStruct.lastEventTime, timeDifference, bayesStruct.bestEstimate); + //printf("note %i played at %f and last event %f time difference %f and current best estmate %f\n", pitch, timePlayed, bayesStruct.lastEventTime, timeDifference, bayesStruct.bestEstimate); + //addnoise to the tempo distribution //bayesStruct.decaySpeedDistribution(timeDifference); if (timeDifference > 50){ @@ -248,11 +249,11 @@ matchString = ""; windowStartTime = max(0.0,(bayesStruct.bestEstimate - matchWindowWidth/2));//was playPositionInMillis - cout << "best estimate is " << bayesStruct.bestEstimate << endl; +// cout << "best estimate is " << bayesStruct.bestEstimate << endl; int numberOfMatches = findMatch(notePitch, windowStartTime, windowStartTime + matchWindowWidth); - matchString += " pitch: "+ofToString(notePitch)+" matches "+ofToString(numberOfMatches)+" win start "+ofToString(windowStartTime); + //matchString += " pitch: "+ofToString(notePitch)+" matches "+ofToString(numberOfMatches)+" win start "+ofToString(windowStartTime); return numberOfMatches; @@ -315,7 +316,7 @@ double confidence = eventConfidence;//bayesStruct.posterior.getValueAtMillis(mouseX); // recordedEventTimes[startIndex]); - matchString += "["+ofToString(startIndex)+"] = "+ofToString(confidence, 3)+" ."; + // matchString += "["+ofToString(startIndex)+"] = "+ofToString(confidence, 3)+" ."; if (abs(recordedEventTimes[startIndex] - bayesStruct.bestEstimate) < tmpError){ //record the error between expected and observed times @@ -350,7 +351,7 @@ //bringing in way to list only the best matches and use these in tempo process bestMatchFound.push_back(bestMatchIndex); - printf("BEST MATCH TO note %i, start time %i, endtime %i, time %i is recorded time %i, confidence %0.2f\n", notePitch, startTime, endTime, (int) recordedEventTimes[bestMatchIndex], minimumConfidence); +// printf("BEST MATCH TO note %i, start time %i, endtime %i, time %i is recorded time %i, confidence %0.2f\n", notePitch, startTime, endTime, (int) recordedEventTimes[bestMatchIndex], minimumConfidence); return size; } @@ -422,7 +423,7 @@ double amount = (1-bayesStruct.speedLikelihoodNoise)/10; amount *= priorWeighting; bayesStruct.updateTempoLikelihood(speedRatio, amount); - tempoSpeedString += ofToString(recordedPreviousIndex) + " "+ ofToString(speedRatio, 2) + " "+ofToString(amount, 2) += " \n"; + // tempoSpeedString += ofToString(recordedPreviousIndex) + " "+ ofToString(speedRatio, 2) + " "+ofToString(amount, 2) += " \n"; needToUpdate = true; } // printf("\n"); @@ -442,6 +443,8 @@ void midiEventHolder::findLocalTempoPairsWeightedForConfidence(){ bool needToUpdate = false; + DoubleVector speedIntervalsFound; + //adapted this to just use the best match for each note int currentPlayedIndex = playedNoteOnMatrix.size()-1; @@ -457,7 +460,7 @@ //that is the difference in confidence method - printf("BEST MATCH FOUND for index %i is %i ", currentPlayedIndex, bestMatchFound[currentPlayedIndex]); + //printf("BEST MATCH FOUND for index %i is %i ", currentPlayedIndex, bestMatchFound[currentPlayedIndex]); int previousIndex = currentPlayedIndex-1; @@ -476,12 +479,12 @@ if (recordedTimeDifference > minimumTimeIntervalForTempoUpdate && speedRatio < maximumMatchSpeed && speedRatio > minimumMatchSpeed){ - printf("(%i)", previousIndex); + /* printf("(%i)", previousIndex); printf("[%i] :: ", recordedPreviousIndex); // printf(" conf %f & %f ", currentMatchConfidence, previousMatchConfidence); printf(" rec{%f} vs play(%f) ", recordedTimeDifference, playedTimeDifference); printf("update on speed ratio %f\n", speedRatio); - + */ // matchString += " speed: "+ofToString(speedRatio, 3); // commented for debug @@ -494,10 +497,12 @@ // double weighting = previousMatchConfidence * currentMatchConfidence ; double amount = (1-bayesStruct.speedLikelihoodNoise)*priorWeighting/16;//was 9 - bayesStruct.updateTempoLikelihood(speedRatio, amount);//second paramter is confidence in the match - tempoSpeedString += ofToString(recordedCurrentIndex) + " :: " + ofToString(recordedPreviousIndex); - tempoSpeedString += " " + ofToString(recordedTimeDifference)+ " " + ofToString(speedRatio, 2) + " "+ofToString(amount, 2) += " \n"; + speedIntervalsFound.push_back(speedRatio); + // bayesStruct.updateTempoLikelihood(speedRatio, amount);//second paramter is confidence in the match + + // tempoSpeedString += ofToString(recordedCurrentIndex) + " :: " + ofToString(recordedPreviousIndex); + // tempoSpeedString += " " + ofToString(recordedTimeDifference)+ " " + ofToString(speedRatio, 2) + " "+ofToString(amount, 2) += " \n"; needToUpdate = true; } @@ -507,6 +512,13 @@ previousIndex--; }//end while previousindex countdown + if (speedIntervalsFound.size() > 0){ + double amount = (1 - bayesStruct.speedLikelihoodNoise) / speedIntervalsFound.size(); + for (int i = 0;i < speedIntervalsFound.size();i++) + bayesStruct.updateTempoLikelihood(speedIntervalsFound[i], amount); + } + + if (needToUpdate) bayesStruct.updateTempoDistribution(); //printf("current speed is %f\n", bayesStruct.relativeSpeedPosterior.getIndexInRealTerms(bayesStruct.relativeSpeedPosterior.MAPestimate)); @@ -694,7 +706,7 @@ int maxSize = recordedNoteOnMatrix[size-1][0]; - ofDrawBitmapString(tempoSpeedString, 20, 20); + // ofDrawBitmapString(tempoSpeedString, 20, 20); /* string indexString = "num screens in "+ofToString(numberOfScreensIn)+"; min index to print "+ofToString(minNoteIndexToPrint)+", max index to print "+ofToString(maxNoteIndexToPrint); indexString += " size "+ofToString(size)+" tick loc "+ofToString(tickLocation)+" max size "+ofToString(maxSize); ofDrawBitmapString(indexString, 20, 40); @@ -806,11 +818,11 @@ double currentTime = -19999.; for (int i = 0;i < noteOnMatrix.size();i++){ int nextIndex = getIndexOfMinimumAboveTime(currentTime, noteOnMatrix); - cout << "index of min time " << currentTime << " is " << nextIndex << " at time " << noteOnMatrix[nextIndex][0] << endl; - // cout << "next index " << nextIndex << " time " << noteOnMatrix[nextIndex][0] << endl; + // cout << "index of min time " << currentTime << " is " << nextIndex << " at time " << noteOnMatrix[nextIndex][0] << endl; + if (nextIndex >= 0 && nextIndex > i && noteOnMatrix[nextIndex][0] < noteOnMatrix[i][0] ){ //which it should be - cout << " index " << nextIndex << " at time " << noteOnMatrix[nextIndex][0] << " swaps with inex " << i << " at time " << noteOnMatrix[i][0] << endl; + // cout << " index " << nextIndex << " at time " << noteOnMatrix[nextIndex][0] << " swaps with inex " << i << " at time " << noteOnMatrix[i][0] << endl; noteOnMatrix[i].swap(noteOnMatrix[nextIndex]); currentTime = noteOnMatrix[i][0]; }
--- a/src/testApp.cpp Wed Nov 30 12:35:04 2011 +0000 +++ b/src/testApp.cpp Sat Dec 03 17:19:43 2011 +0000 @@ -67,6 +67,16 @@ } + if ( m.getAddress() == "/integratedEstimate" ) + { + midiEvents.bayesStruct.usingIntegratedTempoEstimate = true; + } + + if ( m.getAddress() == "/MAPestimate" ) + { + midiEvents.bayesStruct.usingIntegratedTempoEstimate = false; + } + if ( m.getAddress() == "/realtime" ) { @@ -79,6 +89,17 @@ 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 }