//--------------------------------------------------------------
void testApp::setup(){
	
	ofSetFrameRate(60);
	ofSetVerticalSync(true);
    ofEnableSmoothing();
	
	glEnable(GL_DEPTH_TEST);
	ofEnableLighting();
	
	light.setPosition(ofGetWidth()*.5, ofGetHeight()*.25, 0);
	light.enable();
		
    //Timeline setup and playback details
    ofxTimeline::removeCocoaMenusFromGlut("CurvesColorsDemo");
    
	timeline.setup();
    timeline.setFrameRate(30);
	timeline.setDurationInFrames(90);
	timeline.setLoopType(OF_LOOP_NORMAL);
    
	//each call to "add keyframes" add's another track to the timeline
	timeline.addCurves("Rotate X", ofRange(0, 360));
	timeline.addCurves("Rotate Y", ofRange(0, 360));
    
	//Flags are little markers that you can attach text to
    //They are only useful when listening to bangFired() events
    //so that you know when one has passed
	timeline.addColors("Colors");

    //setting framebased to true results in the timeline never skipping frames
    //and also speeding up with the 
    //try setting this to true and see the difference
    timeline.setFrameBased(false);
	
}
Exemple #2
0
void ofxTLZoomer::mouseDragged(ofMouseEventArgs& args) {
    
	if(!enabled) return;
	
    bool notify = false;
	ofRange oldRange = getViewRange();
	if(minSelected || midSelected){
		float originalMin = currentViewRange.min;
		currentViewRange.min = ofClamp( screenXtoNormalizedX(args.x-minGrabOffset, ofRange(0, 1.0)), 0, currentViewRange.max-.01);
		if(minSelected){
			currentViewRange.max = ofClamp( currentViewRange.max + (originalMin-currentViewRange.min), currentViewRange.min+.01, 1.0);
		}
		notify = true;
	}

	if(maxSelected || midSelected){
		float originalMax = currentViewRange.max;
		currentViewRange.max = ofClamp( screenXtoNormalizedX(args.x-maxGrabOffset, ofRange(0, 1.0)), currentViewRange.min+.01, 1.0);
		if(maxSelected){
			currentViewRange.min = ofClamp( currentViewRange.min + (originalMax-currentViewRange.max), 0, currentViewRange.max-.01);
		}
        notify = true;
    }
	
    if(notify){
        notifyZoomDragged(oldRange);
    }
}
void ofApp::setupTimeline() {
    timeline.setup();
    timeline.setLoopType(OF_LOOP_NONE);
    timeline.setDurationInSeconds(10);
    timeline.setOffset(ofVec2f(10, 450));
    timeline.setWidth(ofGetWidth() - 400);
    timeline.addBangs("midi");
    timeline.addCurves("lfo rate", ofRange(0.03, 0.2));
    timeline.addCurves("filter cutoff", ofRange(0, 1));
    ofAddListener(timeline.events().bangFired, this, &ofApp::bang);
}
Exemple #4
0
void ofxTLZoomer::mousePressed(ofMouseEventArgs& args) {

	if(!enabled) return;
	
	minSelected = maxSelected = midSelected = false;
	if (pointInScreenBounds(ofVec2f(args.x, args.y))) {
		mouseIsDown = true;
		
		//did we click on the min-left handle?
		float minScreenX = normalizedXtoScreenX(currentViewRange.min, ofRange(0,1.0));
		minGrabOffset = args.x - minScreenX;
		if(fabs(minScreenX - args.x) < 5){
			minSelected = true;
			notifyZoomStarted();
			return;
		}
		
		//did we click on the max-right handle?
		float maxScreenX = normalizedXtoScreenX(currentViewRange.max, ofRange(0,1.0));
		maxGrabOffset = args.x - maxScreenX;
		if(fabs(maxScreenX - args.x) < 5){
			maxSelected = true;
			notifyZoomStarted();
			return;
		}
		
		//did we click in the middle?
		if(args.x > minScreenX && args.x < maxScreenX){
			notifyZoomStarted();
			midSelected = true;
			return;
		}
		
		//did we click to the right?
		if(args.x > maxScreenX){
			maxSelected = true;
			maxGrabOffset = 0;
			currentViewRange.max = screenXtoNormalizedX(args.x, ofRange(0,1.0));
			notifyZoomStarted();
			return;
		}
		
		//did we click to the left?
		if(args.x < minScreenX){
			minSelected = true;
			minGrabOffset = 0;
			currentViewRange.min = screenXtoNormalizedX(args.x, ofRange(0,1.0));
			notifyZoomStarted();
			return;
		}
	}
}
void ofxTLInOut::load(){
    
	ofxXmlSettings settings;
	if(!settings.loadFile(xmlFileName)){
		ofLog(OF_LOG_VERBOSE, "ofxTLInOut -- couldn't load in/out settings file " + xmlFileName);
        timeline->setInOutRange(ofRange(0,1.0));
		return;
	}
	settings.pushTag("inout");
	timeline->setInOutRange(ofRange(settings.getValue("in", 0.0),settings.getValue("out", 1.0)));
	settings.popTag();
    
}
Exemple #6
0
void ofxTLZoomer::draw(){
	
	ofPushStyle();
	ofSetColor(timeline->getColors().textColor);
	//draw min
	float screenY = bounds.y + bounds.height/2.0;
	float minScreenX = normalizedXtoScreenX(currentViewRange.min, ofRange(0,1.0));
	float maxScreenX = normalizedXtoScreenX(currentViewRange.max, ofRange(0,1.0));

	if(midSelected){
		ofSetLineWidth(2);
	}
	else{
		ofSetLineWidth(1);
	}

	ofLine(minScreenX, screenY, maxScreenX, screenY);
	ofSetLineWidth(1);

	if(minSelected){
		ofFill();
	}
	else{
		ofNoFill();
	}
	ofCircle(minScreenX, screenY, 5);

	if(maxSelected){
		ofFill();
	}
	else{
		ofNoFill();
	}
	ofCircle(maxScreenX, screenY, 5);

//	cout << "zoomer bounds width " << bounds.width << endl;
	//draw playhead reference
	ofLine(bounds.x+bounds.width*timeline->getPercentComplete(), bounds.y,
		   bounds.x+bounds.width*timeline->getPercentComplete(), bounds.y+bounds.height);
	//draw zoom region reference
	ofSetColor(timeline->getColors().backgroundColor);
	ofRange actualZoom = getViewRange();
	ofRectangle zoomRegion = ofRectangle(bounds.x + bounds.width*actualZoom.min, bounds.y,
										 bounds.width*actualZoom.span(),bounds.height);
	ofFill();
	ofSetColor(timeline->getColors().keyColor, 50);
	ofRect(zoomRegion);
	ofPopStyle();
}
ofxTLCurves::ofxTLCurves(){
	initializeEasings();
	valueRange = ofRange(0.0, 1.0);
	drawingEasingWindow = false;
	defaultEasingType = 0;
	defaultEasingFunction = 0;
}
Exemple #8
0
void ofxTLPage::mouseReleased(ofMouseEventArgs& args, long millis){
	if(draggingInside){
		for(int i = 0; i < headers.size(); i++){
			headers[i]->mouseReleased(args);
			tracks[headers[i]->name]->_mouseReleased(args, millis);
		}		
		draggingInside = false;
        timeline->setHoverTime(millis);
	}

	if(draggingSelectionRectangle && selectionRectangle.getArea() != 0){
		if(!ofGetModifierSelection() ){
			timeline->unselectAll();
		}

		draggingSelectionRectangle = false;
        ofLongRange timeRange = ofLongRange(timeline->screenXToMillis(selectionRectangle.x),
                                            timeline->screenXToMillis(selectionRectangle.x+selectionRectangle.width));
		for(int i = 0; i < headers.size(); i++){
            ofRectangle trackBounds = tracks[headers[i]->name]->getDrawRect();
			ofRange valueRange = ofRange(ofMap(selectionRectangle.y, trackBounds.y, trackBounds.y+trackBounds.height, 0.0, 1.0, true),
                                         ofMap(selectionRectangle.y+selectionRectangle.height, trackBounds.y, trackBounds.y+trackBounds.height, 0.0, 1.0, true));
            if(valueRange.min != valueRange.max){
				tracks[headers[i]->name]->regionSelected(timeRange, valueRange);
			}
		}		        
    }
}
Exemple #9
0
//--------------------------------------------------------------
void ofApp::setup(){
    ofBackground(0,0,0);
    ofSetVerticalSync(true);
    
    ofEnableDepthTest();
    glShadeModel (GL_SMOOTH);
    
    //Lighting
    glLightfv (GL_LIGHT0, GL_POSITION, lightOnePosition);
    glLightfv (GL_LIGHT0, GL_DIFFUSE, lightOneColor);
    glEnable (GL_LIGHT0);

    glEnable (GL_LIGHTING);
    
    model.loadModel("ny.obj");

    model.setRotation(0, 90, 1, 0, 0);
    model.setScale(6, 6, 6);
    model.setPosition(ofGetWidth()/2, (float)ofGetHeight() * 0.75 , 0);
    
    //Timeline setup
    timeline.setup(); //registers events
    timeline.setDurationInSeconds(60); //sets time
    timeline.setLoopType(OF_LOOP_NORMAL); //turns the timeline to loop
    timeline.addCurves("MyCircleRadius", ofRange(0, 200));
    //End timeline setup

    
}
Exemple #10
0
ofxTLZoomer::ofxTLZoomer()
:	minSelected(false),
	maxSelected(false),
	midSelected(false),
	currentViewRange(ofRange(0.0, 1.0))
{
	//default constructor
}
Exemple #11
0
ofRange ofxTLZoomer::getViewRange() {
	float logSpan = powf(currentViewRange.span(),zoomExponent);
	float centerPosition = currentViewRange.center();
	//recompute view range
	if(centerPosition != .5){
		centerPosition = ofMap(centerPosition, currentViewRange.span()/2, 1.0 - currentViewRange.span()/2, logSpan/2, 1.0-logSpan/2);
	}
	return ofRange(centerPosition - logSpan/2, centerPosition + logSpan/2);
}
ofRange ofxRGBDVideoDepthSequence::getStartAndEndTimes(ofVideoPlayer& player, ofxDepthImageSequence& sequence){
    if(!ready()){
        ofLogError("ofxRGBDVideoDepthSequence::getStartAndEndTimes -- video sequence not ready");
        return ofRange();
    }
    ofRange output;
    output.min = MAX(0, getVideoMillisForDepthMillis(0))/1000.;
    output.max = MIN(player.getDuration(), getVideoMillisForDepthMillis(sequence.getDurationInMillis()) / 1000. );
	return output;
}
void ofxTLCameraTrack::setTimelineInOutToTrack() {
    //TODO: timebased camera tracking
    if(track.getSamples().size() > 0) {
        timeline->setInPointAtFrame(track.getFirstFrame());
        timeline->setOutPointAtFrame(track.getLastFrame());
    }
    else {
        timeline->setInOutRange(ofRange(0,1.0));
    }
}
Exemple #14
0
void ofxTLZoomer::load() {

	notifyZoomStarted();
	
	ofxXmlSettings settings;
	if(!settings.loadFile(xmlFileName)){
		ofLog(OF_LOG_NOTICE, "ofxTLZoomer -- couldn't load zoom settings file " + xmlFileName);
        currentViewRange = ofRange(0., 1.0);
		return;
	}
    
	settings.pushTag("zoom");
	currentViewRange = ofRange(settings.getValue("min", 0.0),
							   settings.getValue("max", 1.0));

	settings.popTag();
	
	notifyZoomEnded();
}
Exemple #15
0
void ofxTLPage::mouseReleased(ofMouseEventArgs& args, long millis){
	if(draggingInside){
		for(int i = 0; i < headers.size(); i++){
			headers[i]->mouseReleased(args);
			tracks[headers[i]->name]->_mouseReleased(args, millis);
		}		
		draggingInside = false;
        timeline->setHoverTime(millis);
	}

	if(draggingSelectionRectangle && selectionRectangle.getArea() != 0){
		if(!ofGetModifierSelection() ){
			timeline->unselectAll();
		}

        ofLongRange timeRange = ofLongRange(timeline->screenXToMillis(selectionRectangle.x),
                                            timeline->screenXToMillis(selectionRectangle.x+selectionRectangle.width));
		for(int i = 0; i < headers.size(); i++){
            ofRectangle trackBounds = tracks[headers[i]->name]->getDrawRect();
			ofRange valueRange;
			//if we have a collapsed track
			if(trackBounds.height == 0){
				//and the selection rect actual is over the track
				if(selectionRectangle.getMinY() < trackBounds.y && selectionRectangle.getMaxY() > trackBounds.y){
					valueRange = ofRange(0,1.0);
				}
				else{
					continue;
				}
			}
			else{
				valueRange = ofRange(ofMap(selectionRectangle.getMinY(), trackBounds.y, trackBounds.y+trackBounds.height, 0.0, 1.0, true),
									 ofMap(selectionRectangle.getMaxY(), trackBounds.y, trackBounds.y+trackBounds.height, 0.0, 1.0, true));
			}
			
            if(valueRange.min != valueRange.max){
				tracks[headers[i]->name]->regionSelected(timeRange, valueRange);
			}
		}		        
    }
	draggingSelectionRectangle = false;
}
THISSequence::THISSequence()
{
    drawRange = ofRange(0.0, 1.0);
    loaded = false;
    widthSet = false;
    imageType = OF_IMAGE_UNDEFINED;
    drawWidth = -1;
    //TODO: set through interface
    widthPerFrame = 75;

}
Exemple #17
0
void Lights::setup() {
    
    name = "Lights";
    oscAddress = "/lights";
    
    mainTimeline->addPage(name);

    lightShading = mainTimeline->addCurves("Shading", ofRange(0,3));

    flyLightColor = mainTimeline->addColors("Fly Light Color");
    flyLightAttenuation = mainTimeline->addCurves("Fly Light Attenuation", ofRange(0.001,10.0));
    flyLightPosX = mainTimeline->addCurves("Fly Light Pos X", ofRange(-3.0, 3.0));
    flyLightPosY = mainTimeline->addCurves("Fly Light Pos Y", ofRange(-3.0, 3.0));
    flyLightPosZ = mainTimeline->addCurves("Fly Light Pos Z", ofRange(-3.0, 9.0));
    flyLightPosNoise = mainTimeline->addCurves("Fly Light Pos Noise", ofRange(0.0, 1.0));
    flyLightPosNoiseSpeed = mainTimeline->addCurves("Fly Light Pos Noise Speed", ofRange(-1.0, 1.0));

    flyLightDotColor = mainTimeline->addColors("Fly Light Dot Color");
    flyLightDotSize = mainTimeline->addCurves("Fly Light Dot Size", ofRange(0.0, 1.0));

    lightsVertexNoise = mainTimeline->addCurves("Vertex Noise", ofRange(0.0,1.0));

    skyLightColor = mainTimeline->addColors("Sky Light Color");
    skyLightAttenuation = mainTimeline->addCurves("Sky Light Attenuation", ofRange(0.001,10.0));
    
    material.diffuseColor = ofVec4f(0.9, 0.9, 0.9, 1.0);
    material.specularColor = ofVec4f(0.0, 0.0, 0.0, 0.0);
    material.specularShininess = 0.5;
    
    flyLight.setNormalisedBrightness(1.0);
    flyLight.setAttenuation(1.0/2.);
    flyLight.setTemperature(4200);
    
    skyLight.setNormalisedBrightness(1.0);
    skyLight.setAttenuation(1./10.);
    skyLight.setTemperature(10000);
    
    noisePoints.numberOfPoints = 0;
    
}
ofxTLElement::ofxTLElement()
:	xmlFileName(""),
	bounds(ofRectangle(0,0,0,0)),
	zoomBounds(ofRange(0,1.0)),
	enabled(true),
	focused(false),
	hover(false),
	createdByTimeline(false),
	autosave(true),
	timeline(NULL)
{
	//
}
Exemple #19
0
//--------------------------------------------------------------
void testApp::setup(){
	
	ofSetFrameRate(30);
	ofSetVerticalSync(true);
	
	timeline = new ofxTimeline();
	timeline->setup();
	timeline->addKeyframes("Keyframe A", "keyframe_a.xml", ofRange(0, 1.0));
//	timeline->addKeyframes("Keyframe B", "keyframe_b.xml", ofRange(0, 1.0));
//	timeline->addKeyframes("Keyframe C", "keyframe_c.xml", ofRange(0, 1.0));

	timeline->setDuration(300);
}
Exemple #20
0
ofxTLTrack::ofxTLTrack()
:	xmlFileName(""),
	bounds(ofRectangle(0,0,0,0)),
	zoomBounds(ofRange(0,1.0)),
	enabled(false),
	focused(false),
	active(false),
	hover(false),
	createdByTimeline(false),
	timeline(NULL)
{
	// <(^_^)>
}
void ofxTLCameraTrack::setTimelineInOutToTrack(){
	//TODO: timebased camera tracking
	if(keyframes.size() > 0){
		unsigned long long inTime  = keyframes[0]->time;
		unsigned long long outTime = keyframes[keyframes.size()-1]->time;
//		cout << " IN AND OUT SETTING " << inTime << " " << outTime << endl;
		timeline->setInOutRangeMillis(inTime, outTime);
//		timeline->setInPointAtMillis(keyframes[0]->time);
//		timeline->setOutPointAtMillis(keyframes[keyframes.size()-1]->time);
	}
	else{
		timeline->setInOutRange(ofRange(0,1.0));
	}
}
ofxTLKeyframes::ofxTLKeyframes()
:	hoverKeyframe(NULL),
	keysAreDraggable(false),
	keysDidDrag(false),
	keysDidNudge(false),
	lastKeyframeIndex(1),
	lastSampleTime(0),
	shouldRecomputePreviews(false),
	createNewOnMouseup(false),
	useBinarySave(false),
	valueRange(ofRange(0,1.))
{
	xmlFileName = "_keyframes.xml";	
}
Exemple #23
0
ofxTLTrack::ofxTLTrack()
:	xmlFileName(""),
	bounds(ofRectangle(0,0,0,0)),
	zoomBounds(ofRange(0,1.0)),
	enabled(false),
	focused(false),
	active(false),
	hover(false),
	createdByTimeline(false),
	timeline(NULL),
	playbackStartTime(0),
	isPlaying(false)
{

}
ofxTLKeyframer::ofxTLKeyframer() {

    initializeEasings();
    reset();

    valueRange = ofRange(0.0, 1.0);
    hoverKeyframe = NULL;
    selectedKeyframe = NULL;
    drawingEasingWindow = false;

    xmlFileName = "settings/timeline/_keyframes.xml";

    cout << "constructing keyframe editor" << endl;

}
//Labbers: YOU CAN ADD TIMELINE ELEMENTS HERE
void testApp::populateTimelineElements(){
	
	timeline.setPageName("Rendering");
	timeline.addElement("Camera", &cameraTrack);
	timeline.addElement("Video", &videoTimelineElement);
	timeline.addKeyframes("White", currentCompositionDirectory + "white.xml", ofRange(0,1.0) );
	
	timeline.addPage("Alignment", true);
	timeline.addElement("Video", &videoTimelineElement);
	timeline.addElement("Depth Sequence", &depthSequence);
	timeline.addElement("Alignment", &alignmentScrubber);
	
	timeline.setCurrentPage("Rendering");
	
	playerElementAdded = true;
}
Exemple #26
0
//--------------------------------------------------------------
void testApp::timelineAddQuadPage(int i) {
    timeline.addPage(ofToString(i), true);
    timeline.addCurves("red_"+ofToString(i), ofToString(i)+"_red.xml", ofRange(0, 1.0));
	timeline.addCurves("green_"+ofToString(i), ofToString(i)+"_green.xml", ofRange(0, 1.0));
	timeline.addCurves("blu_"+ofToString(i), ofToString(i)+"_blu.xml", ofRange(0, 1.0));
	timeline.addCurves("alpha_"+ofToString(i), ofToString(i)+"_alpha.xml", ofRange(0, 1.0));
	timeline.addFlags("trigger_"+ofToString(i), ofToString(i)+"_trigger.xml");
	timeline.addColors("color_"+ofToString(i), ofToString(i)+"_color.xml");
	timeline.addCurves("brightness"+ofToString(i), ofToString(i), ofRange(0.0, 2.0), 1.0);
    timeline.addCurves("contrast"+ofToString(i), ofToString(i), ofRange(.5, 2.0), 1.0);
    timeline.addCurves("saturation"+ofToString(i), ofToString(i), ofRange(0.0, 1.5), 1.0);
    timeline.addSwitches("invert"+ofToString(i), ofToString(i));

}
Exemple #27
0
void CloudsIntroSequence::updateIntroNodePosition(CalibrationNode& node){
	
	node.baseOffset = introNodeOffset;
	node.titleTypeOffset = titleTypeOffset;
	node.holdTime = introNodeHoldTime;
	node.centerYAdjust = introNodeYAdjust;
	node.updateWorldPosition();
	#ifdef OCULUS_RIFT
	node.activationDistance = questionTugDistance;
	#else
	node.activationDistance = ofRange(introNodeSize*3, introNodeSize*5);
	node.worldPosition.x += getCanvasWidth()/2;
	node.worldPosition.y += getCanvasHeight()/2;
	#endif
	node.updateScreenPosition();
	
}
CloudsRGBDCamera::CloudsRGBDCamera() {

    //////START INIT VARS
    sideDistance = 0;
    frontDistance = 0;
    sidePullback = 0;
    dropAmount = 0;
    liftAmount = 0;
    liftRange = 0;

    //looking and dampening params
    damp = 0;

    //perlin drift params
    driftRadius = 0;

    maxDriftAngle = driftNoiseDensity = driftNoiseSpeed = driftNoisePosition = 0;

    isSetup = false;
    isHovering = false;

    transitionAmount = transitionRotAmount = 0;
    transitioning = false;
    //////// END INIT VARS

    targetNode = NULL;
    startNode = NULL;

    sideDistance = 100;
    frontDistance = 147.54;
    sidePullback = -48;
    liftAmount = 20;
    liftRange = 65;
    dropAmount = 33;
    isSetup = false;
    damp = .1;

    canvasWidth = 1920;
    canvasHeight = 1080;

    zoomFOVRange = ofRange(50, 100);

    maxDriftAngle = 0;

}
Exemple #29
0
void Lights::setup() {
    
    name = "World Light";
    oscAddress = "/lights";
    
    mainTimeline->addPage(name);
    
    //lightShading = mainTimeline->addCurves("Shading", ofRange(0,3));
    
    /*flyLightColor = mainTimeline->addColors("Fly Light Color");
    flyLightAttenuation = mainTimeline->addCurves("Fly Light Attenuation", ofRange(0.001,10.0));
    flyLightPosX = mainTimeline->addCurves("Fly Light Pos X", ofRange(-3.0, 3.0));
    flyLightPosY = mainTimeline->addCurves("Fly Light Pos Y", ofRange(-3.0, 3.0));
    flyLightPosZ = mainTimeline->addCurves("Fly Light Pos Z", ofRange(-3.0, 9.0));*/
    
    //flyLightPosNoise = mainTimeline->addCurves("Fly Light Pos Noise", ofRange(0.0, 1.0));
    //flyLightPosNoiseSpeed = mainTimeline->addCurves("Fly Light Pos Noise Speed", ofRange(-1.0, 1.0));
    
    //flyLightDotColor = mainTimeline->addColors("Fly Light Dot Color");
    //flyLightDotSize = mainTimeline->addCurves("Fly Light Dot Size", ofRange(0.0, 1.0));
    
    //lightsVertexNoise = mainTimeline->addCurves("Vertex Noise", ofRange(0.0,1.0));
    skyLightAttenuation = mainTimeline->addCurves("Sky Light Attenuation", ofRange(0.001,40.0));    
    skyLightColor = mainTimeline->addColors("Sky Light Color");

    material.diffuseColor = ofVec4f(1.0, 1.0, 1.0, 1.0);
    material.specularColor = ofVec4f(1.0, 1.0, 1.0, 1.0);
    material.specularShininess = 2.5;
    
    /*flyLight.setNormalisedBrightness(1.0);
    flyLight.setAttenuation(1.0/2.);
    flyLight.setTemperature(4200);
    flyLight.setSpotConcentration(0.1);
    */
    
    skyLight.setNormalisedBrightness(1.0);
    skyLight.setAttenuation(1./10.);
    skyLight.setTemperature(20000);
    
    skyLight2.setNormalisedBrightness(1.0);
    skyLight2.setAttenuation(1./10.);
    skyLight2.setTemperature(20000);
    
}
void ofxDuration::parseInfoMessage(const ofxOscMessage& m){
	
	ofLogVerbose("ofxDuration::parseInfoMessage") << "Received track information from Duration, #args " << m.getNumArgs();
	
	tracks.clear();
	trackNames.clear();
	//pairs of two strings per track, name and type
	for(int i = 0; i < m.getNumArgs()-1; i+=2){
		if(m.getArgType(i  ) == OFXOSC_TYPE_STRING &&
		   m.getArgType(i+1) == OFXOSC_TYPE_STRING)
		{
			string trackType = m.getArgAsString(i  );
			string trackName = m.getArgAsString(i+1);
			ofxDurationTrack t;
			t.type = trackType;
			t.name = trackName;
			t.lastUpdatedTime = ofGetElapsedTimef();
			ofLogVerbose("ofxDuration::parseInfoMessage") << "Adding track " << t.type << " : " << t.name;

			if(trackType == "Curves" || trackType == "LFO"){
				//consume two more args for min and max
				if(i+3 < m.getNumArgs() &&
				   m.getArgType(i+2) == OFXOSC_TYPE_FLOAT &&
				   m.getArgType(i+3) == OFXOSC_TYPE_FLOAT)
				{
					t.range = ofRange(m.getArgAsFloat(i+2), m.getArgAsFloat(i+3));
					ofLogVerbose("ofxDuration::parseInfoMessage") << " track range is " << t.range;

					i+=2;
				}
			}
			
			//only add unique names
			if(tracks.find(t.name) == tracks.end()){
				trackNames.push_back(t.name);
				tracks[t.name] = t;
			}
			else{
				ofLogNotice("ofxDuration::parseInfoMessage") << "Duplicate track name received: " << t.name;
			}
		}
	}
	ofLogVerbose("ofxDuration::parseInfoMessage") << "Created " << tracks.size() << " tracks";
}