Example #1
0
/**
 * Fetches muse-io udp packets from port localhost:4545 and reads OSC paths:
 * /muse/elements/delta_relative
 * /muse/elements/theta_relative
 * /muse/elements/alpha_relative
 * /muse/elements/beta_relative
 * /muse/elements/gamma_relative
 *
 * Calculates mean delta, theta, alpha, beta and gamma values (and st.dev.)
 * from all channels and which /muse/elements/is_good value is >= 0.5.
 * If there are no good values at all, reports 0.5 value and maximum st.dev.
 * (of uniform distribution between [0,1])
 *
 * Also measures:
 * /muse/elements/experimental/concentration
 * /muse/elements/experimental/mellow
 */
int main(int argc, char** argv)
{
	const unsigned int port = 4545;

	std::cout << "MUSE TEST OSC (UDP PORT 4545) LISTENER" << std::endl;
	fflush(stdout);

	UdpSocket sock;
	sock.bindTo(port);

	if(!sock.isOk()) return -1; // failure [retry?]

	PacketReader pr;
	PacketWriter pw;

	std::vector<int> connectionQuality;
	bool hasConnection = false;
	float delta = 0.0f, theta = 0.0f, alpha = 0.0f, beta = 0.0f, gamma = 0.0f;

	while(sock.isOk()){

		if(hasConnection){
			float q = 0.0f;
			for(auto qi : connectionQuality)
				if(qi > 0) q++;
			q = q / connectionQuality.size();

			// printf("EEQ: D:%.2f T:%.2f A:%.2f B:%.2f G:%.2f [QUALITY: %.2f]\n", delta, theta, alpha, beta, gamma, q);
			printf("EEQ POWER: %.2f [QUALITY %.2f]\n",
					log(exp(delta)+exp(theta)+exp(alpha)+exp(beta)+exp(gamma)), q);

			fflush(stdout);
		}

		if(sock.receiveNextPacket(30)){
			pr.init(sock.packetData(), sock.packetSize());
			Message* msg;
			while(pr.isOk() && ((msg = pr.popMessage()) != 0)){
				Message::ArgReader r = msg->match("/muse/elements/is_good");

				if(r.isOk() == true){ // matched
					// there are 4 ints telling connection quality
					std::vector<int> quality;

					while(r.nbArgRemaining()){
						if(r.isInt32()){
							int32_t i;
							r = r.popInt32(i);
							quality.push_back((int)i);
						}
						else{
							r = r.pop();
						}
					}

					if(quality.size() > 0){
						connectionQuality = quality;
					}

					bool connection = false;

					for(auto q : quality)
						if(q > 0) connection = true;

					hasConnection = connection;
				}

				// gets relative frequency bands..

				r = msg->match("/muse/elements/delta_absolute");
				if(r.isOk()){
					float f1, f2, f3, f4;
					if(r.popFloat(f1).popFloat(f2).popFloat(f3).popFloat(f4).isOkNoMoreArgs()){
						std::vector<float> v;
						v.push_back(f1); v.push_back(f2); v.push_back(f3); v.push_back(f4);

						// calculates mean according to connection quality
						float mean = 0.0f;
						float samples = 0.0f;

						for(unsigned int i=0;i<connectionQuality.size() && i<v.size();i++){
							if(connectionQuality[i] > 0){
								mean += exp(v[i]);
								samples++;
							}
						}

						if(samples > 0.0f){
							mean /= samples;
							mean = log(mean);
						}
						else
							mean = 0.5f; // mean value without data

						delta = mean;
					}
				}

				r = msg->match("/muse/elements/theta_absolute");
				if(r.isOk()){
					float f1, f2, f3, f4;
					if(r.popFloat(f1).popFloat(f2).popFloat(f3).popFloat(f4).isOkNoMoreArgs()){
						std::vector<float> v;
						v.push_back(f1); v.push_back(f2); v.push_back(f3); v.push_back(f4);

						// calculates mean according to connection quality
						float mean = 0.0f;
						float samples = 0.0f;

						for(unsigned int i=0;i<connectionQuality.size() && i<v.size();i++){
							if(connectionQuality[i] > 0){
								mean += exp(v[i]);
								samples++;
							}
						}

						if(samples > 0.0f){
							mean /= samples;
							mean = log(mean);
						}
						else
							mean = 0.5f; // mean value without data

						theta = mean;
					}
				}

				r = msg->match("/muse/elements/alpha_absolute");
				if(r.isOk()){
					float f1, f2, f3, f4;
					if(r.popFloat(f1).popFloat(f2).popFloat(f3).popFloat(f4).isOkNoMoreArgs()){
						std::vector<float> v;
						v.push_back(f1); v.push_back(f2); v.push_back(f3); v.push_back(f4);

						// calculates mean according to connection quality
						float mean = 0.0f;
						float samples = 0.0f;

						for(unsigned int i=0;i<connectionQuality.size() && i<v.size();i++){
							if(connectionQuality[i] > 0){
								mean += exp(v[i]);
								samples++;
							}
						}

						if(samples > 0.0f){
							mean /= samples;
							mean = log(mean);
						}
						else
							mean = 0.5f; // mean value without data

						alpha = mean;
					}
				}


				r = msg->match("/muse/elements/beta_absolute");
				if(r.isOk()){
					float f1, f2, f3, f4;
					if(r.popFloat(f1).popFloat(f2).popFloat(f3).popFloat(f4).isOkNoMoreArgs()){
						std::vector<float> v;
						v.push_back(f1); v.push_back(f2); v.push_back(f3); v.push_back(f4);

						// calculates mean according to connection quality
						float mean = 0.0f;
						float samples = 0.0f;

						for(unsigned int i=0;i<connectionQuality.size() && i<v.size();i++){
							if(connectionQuality[i] > 0){
								mean += exp(v[i]);
								samples++;
							}
						}

						if(samples > 0.0f){
							mean /= samples;
							mean = log(mean);
						}
						else
							mean = 0.5f; // mean value without data

						beta = mean;
					}
				}

				r = msg->match("/muse/elements/gamma_absolute");
				if(r.isOk()){
					float f1, f2, f3, f4;
					if(r.popFloat(f1).popFloat(f2).popFloat(f3).popFloat(f4).isOkNoMoreArgs()){
						std::vector<float> v;
						v.push_back(f1); v.push_back(f2); v.push_back(f3); v.push_back(f4);

						// calculates mean according to connection quality
						float mean = 0.0f;
						float samples = 0.0f;

						for(unsigned int i=0;i<connectionQuality.size() && i<v.size();i++){
							if(connectionQuality[i] > 0){
								mean += exp(v[i]);
								samples++;
							}
						}

						if(samples > 0.0f){
							mean /= samples;
							mean = log(mean);
						}
						else
							mean = 0.5f; // mean value without data

						gamma = mean;
					}
				}

			}
		}
	}

	return 0;
}
Example #2
0
void CBodyBasics::ParseOSC()
{

	// UDP stuff
	PacketReader pr;
	PacketWriter pw;

	if (recvsock.isOk() && recvsock.receiveNextPacket(1 /* timeout, in ms */)) {
		pr.init(recvsock.packetData(), recvsock.packetSize());
		oscpkt::Message *msg;
		while (pr.isOk() && (msg = pr.popMessage()) != 0) {

			// parse IP address
			std::string c = recvsock.packetOrigin().asString();
			std::string delim = ":";
			size_t pos = 0;
			std::string token;
			while ((pos = c.find(delim)) != std::string::npos) {
				token = c.substr(0, pos);
				c = token;
			}
			std::string s = "Server: received message from " + c + "\n";
			printFucker(s);

			//
			// parse messages
			//

			// CONNECT
			if (msg->match("/connect").isOkNoMoreArgs()) {
				// find empty client - check existing list
				int foundmatch = 0;
				for (int i = 0; i < clients.size(); i++)
				{
					if (clients[i].address == c) // already in list
					{
						printFucker("RECONNECTING TO HOST " + c + ":\n");
						clients[i].active = 1;
						foundmatch = 1;
						break;
					}
				}
				if (foundmatch == 0) // add new client to first free slot
				{
					for (int i = 0; i < clients.size(); i++)
					{
						if (clients[i].active == false) // add here
						{
							printFucker("ADDING CONNECTION TO HOST " + c + ":\n");
							clients[i].address = c;
							clients[i].active = true;
							clients[i].socket.connectTo(c, SENDPORT);
							foundmatch = 1;
							break;
						}
					}
				}
				if (foundmatch == 0) // out of slots
				{
					std::string s = "Out of slots!!!\n";
					printFucker(s);

				}

			}

			// DISCONNECT
			else if (msg->match("/disconnect").isOkNoMoreArgs()) {
				for (int i = 0; i < clients.size(); i++)
				{
					if (clients[i].address == c) // shut it off
					{
						printFucker("DISCONNECTING FROM HOST " + c + ":\n");
						clients[i].active = false;
						break;
					}
				}
			}

			// ADDQUERY
			else if (msg->match("/addQuery")){
				Message::ArgReader arg(msg->arg()); // reader for arguments
				KinectQuery kq; // new query obect

				if (arg.isStr()) // first value should be string
				{
					std::string firstString;
					arg.popStr(firstString);
					// figure out query type
					if (firstString == "joint") kq.type = 0;
					else if (firstString == "trigger") kq.type = 1;
					else if (firstString == "toggle") kq.type = 2;
					else if (firstString == "controller") kq.type = 3;
					else if (firstString == "motion") kq.type = 4;
					printFucker("query type: " + std::to_string(kq.type) + "\n");
				}

				// parse remaining args based on type

				// joint
				if (kq.type == 0)
					// we want either:
					// string... stringn int string (enumerated joints)
					// or
					// int string (all joints)
				{
					// check first arg:
					if (arg.isInt32()) { // first arg is int: omni mode
						kq.omni = 1; // omni: send all joints each frame
						int p; arg.popInt32(p);
						kq.mode = p; // 0 (world) or 1 (body) orientation for output

						// check second arg
						if (arg.isStr()) { // in omni mode, next arg should be a string
							std::string p; arg.popStr(p);
							kq.message = p; // message for OSC argument with joint data inside
							kq.valid = 1; // valid query
						}
					}

					else if (arg.isStr()) { // first arg is string: individual joints
						kq.omni = 0;
						std::string p; arg.popStr(p);
						if (j2i.count(p) == 1) kq.joints.push_back(j2i[p]); // first joint to use
						while (arg.nbArgRemaining()) { // iterate until int
							if (arg.isStr()) {
								std::string f; arg.popStr(f); // another joint
								if(j2i.count(f)==1) kq.joints.push_back(j2i[f]);
							}
							else {
								break; // get outta here
							}
						}
						// check next-to-last arg:
						if (arg.isInt32()) { // first arg is int: omni mode
							int f; arg.popInt32(f);
							kq.mode = f; // 0 (world) or 1 (body) orientation for output

							// check last arg
							if (arg.isStr()) { // in omni mode, next arg should be a string
								std::string f; arg.popStr(f);
								kq.message = f; // message for OSC argument with joint data inside
								kq.valid = 1; // valid query
							}

						}
					}

					if (kq.valid == 1)
					{
						// DEBUG
						printFucker("ADDING JOINT QUERY for host " + c + ":\n");
						printFucker("OMNI: " + std::to_string(kq.omni) + " ");
						if (kq.omni == 0)
						{
							printFucker("JOINTS: ");
							for (int j = 0; j < kq.joints.size(); j++)
							{
								printFucker(std::to_string(kq.joints[j]) + " ");
							}
						}
						printFucker("MODE: " + std::to_string(kq.mode) + " ");
						printFucker("MESSAGE: " + kq.message + "\n");

						// PUSH ONTO STACK
						for (int i = 0; i < clients.size(); i++)
						{
							if (clients[i].address == c && clients[i].active == true) // add here
							{
								// avoid duplicate queries by message
								int ismatched = -1;
								for (int j = 0; j < clients[i].query.size(); j++)
								{
									if (clients[i].query[j].message == kq.message) // match
									{
										ismatched = j;
										break;
									}
								}
								if (ismatched == -1) // new message 
								{
									clients[i].query.push_back(kq);
									printFucker("ADDED QUERY SLOT: " + std::to_string(clients[i].query.size() - 1));
									break;
								}
								else // replace old message in queue with same query name
								{
									clients[i].query[ismatched] = kq;
									printFucker("REPLACED QUERY SLOT: " + std::to_string(ismatched));
									break;
								}
							}
						}

					}
				}

			}

			else {
				std::string s = "Server: unhandled message! \n";
				printFucker(s);
			}
		}
	}
}