diff src/melodyTriangle.cpp @ 37:260cc4f4d70a

Now using OSC bundles to make sure cotemporal messages are received in correct order; also added randInit state flag (toggle 'i') to control sending of /randinit on birth.
author samer
date Wed, 22 Feb 2012 00:30:20 +0000
parents 06a2fdb333ca
children 330f2746fedd
line wrap: on
line diff
--- a/src/melodyTriangle.cpp	Wed Feb 15 12:26:10 2012 +0000
+++ b/src/melodyTriangle.cpp	Wed Feb 22 00:30:20 2012 +0000
@@ -6,11 +6,25 @@
 
 static int tempi[]={20,30,45,60,90,120,150,180,240};
 
+static ofxOscBundle& operator<<(ofxOscBundle &bundle, ofxOscMessage msg) { 
+	bundle.addMessage(msg); return bundle; 
+}
+
+static ofxOscSender& operator<<(ofxOscSender &sender, ofxOscMessage msg) { 
+	sender.sendMessage(msg);
+	return sender;
+}
+
+static ofxOscSender& operator<<(ofxOscSender &sender, ofxOscBundle bundle) { 
+	sender.sendBundle(bundle);
+	return sender;
+}
+	
 
 melodyTriangle::melodyTriangle(const char *host, int port, int numVoices, 
 							   bool enableKeys,int voiceIdOffset,int receivePort): 
 	numVoices(numVoices), receivePort(receivePort), snapTruePos(enableKeys),
-	enableKeys(enableKeys), allowExit(true), ratio(2), tempoIndex(4),
+	enableKeys(enableKeys), randInit(false),allowExit(true), ratio(2), tempoIndex(4),
 	display_msg(""), display_frames(0)
 {
 	for (int i=0;i<numVoices;i++) voices[i]=new Voice(i+1+voiceIdOffset);
@@ -38,9 +52,12 @@
 	// isosceles and left-right symmetric around x=x1.
 	// Otherwise the clipping won't work
 	fitTriangleIn(ofGetWidth(),ofGetHeight());
-	send("/tempo",tempi[tempoIndex]);
-	sendCalibrate();
-	sendReplyTo();
+	
+	ofxOscBundle bundle;
+	sender << ( bundle 
+				<< msg("/tempo",tempi[tempoIndex])
+				<< msgCalibrate()
+			    << msgReplyTo());
 	
 	voiceGrabbed=NULL;
 }
@@ -62,6 +79,7 @@
 		if (mouseX!=vg->posx || mouseY!=vg->posy){
 			int clipx=mouseX, clipy=mouseY;
 			bool clipped=clipToTriangle(&clipx,&clipy);
+			ofxOscBundle bundle;
 			
 			if (vg->inTriangle) {
 				
@@ -69,7 +87,8 @@
 					// check how far we clipped
 					if (ofDist(clipx, clipy, mouseX, mouseY)>BUFFER_ZONE && allowExit) { 
 						// if far enough, we pop out of triangle and send
-						send("/death",vg->id);
+						bundle << msg("/death",vg->id);
+						sender << bundle;
 						vg->posx=mouseX;
 						vg->posy=mouseY;
 						vg->inTriangle=false;
@@ -88,11 +107,12 @@
 				vg->posx=mouseX;
 				vg->posy=mouseY;
 				if (!clipped){ // ie mouse now in triangle
-					send("/birth",vg->id);
-					
-					printf("sent /birth %i \n",vg->id);
-					sendOctave(vg->id,vg->octave);
-					sendAmplitude(vg->id,vg->amplitude);
+					bundle << msg("/birth",vg->id)
+						   << msgAmplitude(vg->id,vg->amplitude)
+					       << ( randInit
+					          ?	msg("/randinit",vg->id)
+							  : msgOctave(vg->id,vg->octave)
+							  );
 					sendStart=true;
 					vg->inTriangle=true;
 					vg->truex=vg->truey=-1; // ie not known yet.
@@ -100,9 +120,10 @@
 			}
 			
 			if (vg->inTriangle){
-				sendPosition(vg);
+				bundle << msgPosition(vg);
 				vg->status=Voice::moved;
-				if (sendStart && vg->isActive) send("/start",vg->id);
+				if (sendStart && vg->isActive) bundle << msg("/start",vg->id);
+				sender << bundle;
 			}
 		}
 	};
@@ -194,17 +215,26 @@
 					
 				case '{': 
 					if (tempoIndex>0) tempoIndex--; 
-					send("/tempo",tempi[tempoIndex]); 
+					sender << msg("/tempo",tempi[tempoIndex]); 
 					break;
 				case '}': 
 					if (tempoIndex<NUM_TEMPI-1) tempoIndex++;
-					send("/tempo",tempi[tempoIndex]); 
+					sender << msg("/tempo",tempi[tempoIndex]); 
 					break;
 					
-				case ' ': send("/marker"); break;
-				case 'S': send("/save"); break;
-				case 'r': send("/report"); break;
-				case 'C': sendReplyTo(); sendCalibrate(); break;
+				case ' ': sender << msg("/marker"); break;
+				case 'S': sender << msg("/save"); break;
+				case 'r': sender << msg("/report"); break;
+				case 'i': 
+					randInit ^= true; 
+					display_msg = (randInit?"randomise on birth":"no randomise on birth");
+					display_frames = 40;
+					break;
+				case 'C': {
+					ofxOscBundle bundle;
+					sender << (bundle << msgReplyTo() << msgCalibrate()); 
+					break;
+				}
 				case 'F': ofToggleFullscreen(); break;
 				case 'R': reset(); break;
 				case 'Q': ofAppGlutWindow::exitApp();
@@ -218,7 +248,7 @@
 		}
 	} else {
 		if (key==OF_KEY_ESC) setKeyboardEnable(true);
-		else send("/key",key);
+		else sender << msg("/key",key);
 	}
 }
 
@@ -226,19 +256,19 @@
 	switch (key) {
 		case 'a':
 			if (v->inTriangle) {
-				send(v->isActive ? "/stop" : "/start", v->id);
+				sender << msg(v->isActive ? "/stop" : "/start", v->id);
 			}
 			v->isActive=!v->isActive;
 			break;
-		case OF_KEY_LEFT:  sendShift(v->id,-1,ratio); break;
-		case OF_KEY_RIGHT: sendShift(v->id,1,ratio); break;
-		case OF_KEY_UP:    sendPeriod(v->id,1,ratio); break;
-		case OF_KEY_DOWN:  sendPeriod(v->id,ratio,1); break;
-		case ']': sendOctave(v->id, ++v->octave); break;
-		case '[': sendOctave(v->id, --v->octave); break;
-		case '*': sendAmplitude(v->id, v->louder()); break;
-		case '/': sendAmplitude(v->id, v->quieter()); break;
-		case 'c': send("/change",v->id); v->status=Voice::pending; break;
+		case OF_KEY_LEFT:  sender << msgShift(v->id,-1,ratio); break;
+		case OF_KEY_RIGHT: sender << msgShift(v->id,1,ratio); break;
+		case OF_KEY_UP:    sender << msgPeriod(v->id,1,ratio); break;
+		case OF_KEY_DOWN:  sender << msgPeriod(v->id,ratio,1); break;
+		case ']': sender << msgOctave(v->id, ++v->octave); break;
+		case '[': sender << msgOctave(v->id, --v->octave); break;
+		case '*': sender << msgAmplitude(v->id, v->louder()); break;
+		case '/': sender << msgAmplitude(v->id, v->quieter()); break;
+		case 'c': sender << msg("/change",v->id); v->status=Voice::pending; break;
 		default:  printf("unrecognised key: %d.\n",key);
 	}
 }
@@ -273,7 +303,7 @@
 
 void melodyTriangle::windowResized(int w, int h){
 	fitTriangleIn(w,h);
-	sendCalibrate();
+	sender << msgCalibrate();
 	reset();
 }
 
@@ -286,7 +316,7 @@
 		v->status=Voice::pending;
 		v->isActive=true;
 		if (v->inTriangle) {
-			send("/death",v->id);
+			sender << msg("/death",v->id);
 			v->inTriangle=false;
 		}
 	}
@@ -382,7 +412,7 @@
 
 // OSC Message sending -----------------------------------------
 
-void melodyTriangle::sendPosition(Voice *v){
+ofxOscMessage melodyTriangle::msgPosition(Voice *v){
 	
 	ofxOscMessage m;
 	///track id x y left right top bottom area  
@@ -390,10 +420,11 @@
 	m.addIntArg( v->id );
 	m.addIntArg( v->posx );
 	m.addIntArg( v->posy );
-	sender.sendMessage( m );
-	// printf("sent - /track2d %i %i %i\n",v->id,v->posx,v->posy);
+	// printf("/track2d %i %i %i\n",v->id,v->posx,v->posy);
+	return m;
 }
-void melodyTriangle::sendCalibrate(){
+
+ofxOscMessage melodyTriangle::msgCalibrate(){
 	ofxOscMessage m;
 	m.setAddress( "/calibrate" );
 	m.addIntArg( x1 );
@@ -402,65 +433,63 @@
 	m.addIntArg( y2 );
 	m.addIntArg( x3 );
 	m.addIntArg( y3 );
-	sender.sendMessage( m );
-	printf("sent /calibrate %i %i %i %i %i %i\n",x1,y1,x2,y2,x3,y3);
+	printf("/calibrate %i %i %i %i %i %i\n",x1,y1,x2,y2,x3,y3);
+	return m;
 }
 
-void melodyTriangle::sendReplyTo(){	
+ofxOscMessage melodyTriangle::msgReplyTo(){	
 	ofxOscMessage m;
 	m.setAddress( "/reply_to" );
 	m.addIntArg( receivePort );
-	sender.sendMessage( m );
 	printf("sent /reply_to %i\n",receivePort);
+	return m;
 }
 
-void melodyTriangle::sendPeriod(int id, int num, int den){ send("/period",id,num,den); }
-void melodyTriangle::sendShift(int id, int num, int den) { send("/shift",id,num,den); }
-void melodyTriangle::sendOctave(int id, int oct){ send("/octave",id,oct); }
+ofxOscMessage melodyTriangle::msgPeriod(int id, int num, int den) { return msg("/period",id,num,den); }
+ofxOscMessage melodyTriangle::msgShift(int id, int num, int den) { return msg("/shift",id,num,den); }
+ofxOscMessage melodyTriangle::msgOctave(int id, int oct) { return msg("/octave",id,oct); }
 
-void melodyTriangle::sendAmplitude(int id, float amp){
+ofxOscMessage melodyTriangle::msgAmplitude(int id, float amp){
 	ofxOscMessage m;
 	m.setAddress("/amplitude");
 	m.addIntArg(id);
 	m.addFloatArg(amp);
-	sender.sendMessage(m);
-	printf("sent /amplitude %i %1.3f\n",id,amp);
+	printf("/amplitude %i %1.3f\n",id,amp);
+	return m;
 }
 
-void melodyTriangle::send(const char *addr, int a, int b, int c) {
+ofxOscMessage melodyTriangle::msg(const char *addr, int a, int b, int c) {
 	ofxOscMessage m;
 	m.setAddress(addr);
 	m.addIntArg(a);
 	m.addIntArg(b);
 	m.addIntArg(c);
-	sender.sendMessage(m);
-	printf("sent %s %i\n",addr,a);
+	printf("%s %i %i %i\n",addr,a,b,c);
+	return m;
 }
 
-
-void melodyTriangle::send(const char *addr, int a, int b) {
+ofxOscMessage melodyTriangle::msg(const char *addr, int a, int b) {
 	ofxOscMessage m;
 	m.setAddress(addr);
 	m.addIntArg(a);
 	m.addIntArg(b);
-	sender.sendMessage(m);
-	printf("sent %s %i\n",addr,a);
+	printf("%s %i %i\n",addr,a,b);
+	return m;
 }
 
-
-void melodyTriangle::send(const char *addr, int a) {
+ofxOscMessage melodyTriangle::msg(const char *addr, int a) {
 	ofxOscMessage m;
 	m.setAddress(addr);
 	m.addIntArg(a);
-	sender.sendMessage(m);
-	printf("sent %s %i\n",addr,a);
+	printf("%s %i\n",addr,a);
+	return m;
 }
 
-void melodyTriangle::send(const char *addr) {
+ofxOscMessage melodyTriangle::msg(const char *addr) {
 	ofxOscMessage m;
 	m.setAddress(addr);
-	sender.sendMessage(m);
-	printf("sent %s\n",addr);
+	printf("%s\n",addr);
+	return m;
 }
 
 void melodyTriangle::fitTriangleIn(int width, int height) {