From b58bb6fe80fc42ab15c446bb8e7f646d998d3198 Mon Sep 17 00:00:00 2001 From: Philip Rosedale Date: Tue, 12 Feb 2013 01:41:36 -0800 Subject: [PATCH 1/4] Head data streaming to other users, domain server improved, network.cpp removed and replaced with UDPSocket objects, input audio drives mouth color and size. --- domain/src/main.cpp | 21 +++-- interface/src/Agent.cpp | 71 +++++++++------- interface/src/Agent.h | 11 +-- interface/src/Audio.cpp | 15 ++++ interface/src/Audio.h | 2 + interface/src/AudioData.h | 3 + interface/src/Head.cpp | 15 +++- interface/src/Head.h | 11 +++ interface/src/Network.cpp | 156 ------------------------------------ interface/src/Network.h | 41 ---------- interface/src/UDPSocket.cpp | 10 +++ interface/src/UDPSocket.h | 3 +- interface/src/main.cpp | 119 +++++++++++++-------------- 13 files changed, 178 insertions(+), 300 deletions(-) delete mode 100644 interface/src/Network.cpp delete mode 100644 interface/src/Network.h diff --git a/domain/src/main.cpp b/domain/src/main.cpp index 4f137f6757..67fa347bbd 100644 --- a/domain/src/main.cpp +++ b/domain/src/main.cpp @@ -43,6 +43,8 @@ struct AgentList { int num_agents = 0; +int lastActiveCount = 0; + double diffclock(timeval clock1,timeval clock2) { double diffms = (clock2.tv_sec - clock1.tv_sec) * 1000.0; @@ -115,7 +117,8 @@ void update_agent_list(timeval now) { for (i = 0; i < num_agents; i++) { if ((diffclock(agents[i].time, now) > LOGOFF_CHECK_INTERVAL) && agents[i].active) { - std::cout << "Expired Agent #" << i+1 << "\n"; + std::cout << "Expired Agent from " << + inet_ntoa(agents[i].sin_addr) << ":" << agents[i].port << "\n"; agents[i].active = false; } } @@ -127,7 +130,8 @@ void send_agent_list(int handle, sockaddr_in * dest_address) { char buffer[MAX_PACKET_SIZE]; char * address; char portstring[10]; - buffer[length++] = 'S'; + int numSent = 0; + buffer[length++] = 'D'; //std::cout << "send list to: " << inet_ntoa(dest_address->sin_addr) << "\n"; for (i = 0; i < num_agents; i++) { if (agents[i].active) { @@ -142,6 +146,7 @@ void send_agent_list(int handle, sockaddr_in * dest_address) { length += strlen(portstring); // Add comma separator between agents buffer[length++] = ','; + numSent++; } } if (length > 1) { @@ -149,8 +154,10 @@ void send_agent_list(int handle, sockaddr_in * dest_address) { 0, (sockaddr *) dest_address, sizeof(sockaddr_in) ); if (sent_bytes < length) std::cout << "Error sending agent list!\n"; - else - std::cout << "Agent list sent: " << buffer << "\n"; + else if (numSent != lastActiveCount) { + std::cout << numSent << " Active Agents\n"; + lastActiveCount = numSent; + } } } @@ -167,7 +174,7 @@ int main(int argc, const char * argv[]) std::cout << "Failed to create network.\n"; return 0; } else { - std::cout << "DomainServer Started. Waiting for packets.\n"; + std::cout << "DomainServer started, listening on port " << LISTENING_UDP_PORT << "\n"; } gettimeofday(&last_time, NULL); @@ -180,8 +187,8 @@ int main(int argc, const char * argv[]) float x,y,z; sscanf(packet_data, "%f,%f,%f", &x, &y, &z); if (addAgent(dest_address.sin_addr.s_addr, dest_address.sin_port, x, y, z)) { - std::cout << "Added agent from IP, port: " << - inet_ntoa(dest_address.sin_addr) << "," << dest_address.sin_port << "\n"; + std::cout << "Added Agent from " << + inet_ntoa(dest_address.sin_addr) << ":" << dest_address.sin_port << "\n"; } // Reply with packet listing nearby active agents send_agent_list(handle, &dest_address); diff --git a/interface/src/Agent.cpp b/interface/src/Agent.cpp index 9632c4a442..0086792c66 100644 --- a/interface/src/Agent.cpp +++ b/interface/src/Agent.cpp @@ -10,36 +10,47 @@ #include "Agent.h" #include "Head.h" + // Structure to hold references to other agents that are nearby const int MAX_AGENTS = 100; struct AgentList { - in_addr sin_addr; + char address[255]; + unsigned short port; Head head; } agents[MAX_AGENTS]; int num_agents = 0; // -// Process an incoming domainserver packet telling you about other nearby agents +// Process an incoming domainserver packet telling you about other nearby agents, +// and returns the number of agents that were reported. // -void update_agents(char * data, int length) { +int update_agents(char * data, int length) { + int numAgents = 0; std::string packet(data, length); - //std::cout << " Update Agents, string: " << packet << "\n"; size_t spot; size_t start_spot = 0; + std::string address, port; + unsigned short nPort = 0; spot = packet.find_first_of (",", 0); while (spot != std::string::npos) { - std::string IPstring = packet.substr(start_spot, spot-start_spot); - //std::cout << "Found " << num_agents << - //" with IP " << IPstring << " from " << start_spot << " to " << spot << "\n"; - // Add the IP address to the agent table - add_agent(&IPstring); + std::string thisAgent = packet.substr(start_spot, spot-start_spot); + if (thisAgent.find_first_of(":", 0) != std::string::npos) { + address = thisAgent.substr(0, thisAgent.find_first_of(":", 0)); + port = thisAgent.substr(thisAgent.find_first_of(":", 0) + 1, + thisAgent.length() - thisAgent.find_first_of(":", 0)); + nPort = atoi(port.c_str()); + } + //std::cout << "IP: " << address << ", port: " << nPort << "\n"; + add_agent((char *)address.c_str(), nPort); + numAgents++; start_spot = spot + 1; if (start_spot < packet.length()) spot = packet.find_first_of (",", start_spot); else spot = std::string::npos; } + return numAgents; } void render_agents() { @@ -55,11 +66,11 @@ void render_agents() { // // Update a single agent with data received from that agent's IP address // -void update_agent(in_addr addr, char * data, int length) +void update_agent(char * address, unsigned short port, char * data, int length) { - std::cout << "Looking for agent: " << inet_ntoa(addr) << "\n"; + //printf("%s:%d\n", address, port); for (int i = 0; i < num_agents; i++) { - if (agents[i].sin_addr.s_addr == addr.s_addr) { + if ((strcmp(address, agents[i].address) == 0) && (agents[i].port == port)) { // Update the agent agents[i].head.recvBroadcastData(data, length); } @@ -69,19 +80,19 @@ void update_agent(in_addr addr, char * data, int length) // // Look for an agent by it's IP number, add if it does not exist in local list // -int add_agent(std::string * IP) { - in_addr_t addr = inet_addr(IP->c_str()); +int add_agent(char * address, unsigned short port) { //std::cout << "Checking for " << IP->c_str() << " "; for (int i = 0; i < num_agents; i++) { - if (agents[i].sin_addr.s_addr == addr) { - //std::cout << "Found!\n"; + if ((strcmp(address, agents[i].address) == 0) && (agents[i].port == port)) { + //std::cout << "Found agent!\n"; return 0; } } if (num_agents < MAX_AGENTS) { - agents[num_agents].sin_addr.s_addr = addr; - std::cout << "Added Agent # " << num_agents << " with IP " << - inet_ntoa(agents[num_agents].sin_addr) << "\n"; + strcpy(agents[num_agents].address, address); + agents[num_agents].port = port; + //std::cout << "Added Agent # " << num_agents << " with Address " << + //agents[num_agents].address << ":" << agents[num_agents].port << "\n"; num_agents++; return 1; } else { @@ -91,18 +102,22 @@ int add_agent(std::string * IP) { } // -// Broadcast data to all the other agents you are aware of, returns 1 for success +// Broadcast data to all the other agents you are aware of, returns 1 if success // -int broadcast_to_agents(int handle, char * data, int length) { - sockaddr_in dest_address; - dest_address.sin_family = AF_INET; - dest_address.sin_port = htons( (unsigned short) AGENT_UDP_PORT ); - +int broadcast_to_agents(UDPSocket *handle, char * data, int length) { int sent_bytes; + //printf("broadcasting to %d agents\n", num_agents); for (int i = 0; i < num_agents; i++) { - dest_address.sin_addr.s_addr = agents[i].sin_addr.s_addr; - sent_bytes = sendto( handle, (const char*)data, length, - 0, (sockaddr*)&dest_address, sizeof(sockaddr_in) ); + //printf("bcast to %s\n", agents[i].address); + // + // STUPID HACK: For some reason on OSX with NAT translation packets sent to localhost are + // received as from the NAT translated port but have to be sent to the local port number. + // + if (strcmp("127.0.0.1",agents[i].address) == 0) + sent_bytes = handle->send(agents[i].address, 40103, data, length); + else + sent_bytes = handle->send(agents[i].address, agents[i].port, data, length); + if (sent_bytes != length) { std::cout << "Broadcast packet fail!\n"; return 0; diff --git a/interface/src/Agent.h b/interface/src/Agent.h index 27f355c9ec..e629ae6427 100644 --- a/interface/src/Agent.h +++ b/interface/src/Agent.h @@ -15,12 +15,13 @@ #include #include #include -#include "Network.h" +#include "UDPSocket.h" -void update_agents(char * data, int length); -int add_agent(std::string * IP); -int broadcast_to_agents(int handle, char * data, int length); -void update_agent(in_addr addr, char * data, int length); + +int update_agents(char * data, int length); +int add_agent(char * address, unsigned short port); +int broadcast_to_agents(UDPSocket * handle, char * data, int length); +void update_agent(char * address, unsigned short port, char * data, int length); void render_agents(); #endif diff --git a/interface/src/Audio.cpp b/interface/src/Audio.cpp index 01cc96c8f1..949b79efe3 100644 --- a/interface/src/Audio.cpp +++ b/interface/src/Audio.cpp @@ -87,6 +87,16 @@ int audioCallback (const void *inputBuffer, if (inputLeft != NULL) { data->audioSocket->send((char *) EC2_WEST_AUDIO_SERVER, 55443, (void *)inputLeft, BUFFER_LENGTH_BYTES); + // + // Measure the loudness of the signal from the microphone and store in audio object + // + float loudness = 0; + for (int i = 0; i < BUFFER_LENGTH_SAMPLES; i++) { + loudness += abs(inputLeft[i]); + } + loudness /= BUFFER_LENGTH_SAMPLES; + data->lastInputLoudness = loudness; + data->averagedInputLoudness = 0.66*data->averagedInputLoudness + 0.33*loudness; } int16_t *outputLeft = ((int16_t **) outputBuffer)[0]; @@ -366,6 +376,11 @@ void Audio::render() } } +void Audio::getInputLoudness(float * lastLoudness, float * averageLoudness) { + *lastLoudness = data->lastInputLoudness; + *averageLoudness = data->averagedInputLoudness; +} + void Audio::render(int screenWidth, int screenHeight) { if (initialized && ECHO_SERVER_TEST) { diff --git a/interface/src/Audio.h b/interface/src/Audio.h index 80531b7949..001fb622f4 100644 --- a/interface/src/Audio.h +++ b/interface/src/Audio.h @@ -23,6 +23,8 @@ public: static void render(); static void render(int screenWidth, int screenHeight); + static void getInputLoudness(float * lastLoudness, float * averageLoudness); + // terminates audio I/O static bool terminate(); private: diff --git a/interface/src/AudioData.h b/interface/src/AudioData.h index 59e9922e05..3a98330e48 100644 --- a/interface/src/AudioData.h +++ b/interface/src/AudioData.h @@ -32,6 +32,9 @@ class AudioData { float measuredJitter; float jitterBuffer; int wasStarved; + + float lastInputLoudness; + float averagedInputLoudness; AudioData(int bufferLength); AudioData(int numberOfSources, int bufferLength); diff --git a/interface/src/Head.cpp b/interface/src/Head.cpp index 8e915b3de0..09a9d0af45 100644 --- a/interface/src/Head.cpp +++ b/interface/src/Head.cpp @@ -12,6 +12,7 @@ #include "Head.h" #include "Util.h" #include "SerialInterface.h" +#include "Audio.h" float skinColor[] = {1.0, 0.84, 0.66}; float browColor[] = {210.0/255.0, 105.0/255.0, 30.0/255.0}; @@ -275,12 +276,13 @@ void Head::render(int faceToFace) // Mouth + glPushMatrix(); glTranslatef(0,-0.3,0.75); - glColor3fv(mouthColor); + glColor3f(loudness/1000.0,0,0); glRotatef(MouthPitch, 1, 0, 0); glRotatef(MouthYaw, 0, 0, 1); - glScalef(MouthWidth, MouthHeight, 1); + glScalef(MouthWidth*(.5 + averageLoudness/3000.0), MouthHeight*(1.0 + averageLoudness/6000.0), 1); glutSolidCube(0.5); glPopMatrix(); @@ -338,14 +340,19 @@ void Head::render(int faceToFace) int Head::getBroadcastData(char* data) { // Copy data for transmission to the buffer, return length of data - sprintf(data, "H%f,%f,%f,%f,%f,%f", Pitch + getRenderPitch(), Yaw + getRenderYaw(), Roll, position.x, position.y, position.z); + sprintf(data, "H%f,%f,%f,%f,%f,%f,%f,%f", Pitch + getRenderPitch(), Yaw + getRenderYaw(), Roll, + position.x, position.y, position.z, + loudness, averageLoudness); //printf("x: %3.1f\n", position.x); return strlen(data); } void Head::recvBroadcastData(char * data, int size) { - sscanf(data, "H%f,%f,%f,%f,%f,%f", &Pitch, &Yaw, &Roll, &position.x, &position.y, &position.z); + sscanf(data, "%f,%f,%f,%f,%f,%f,%f,%f", &Pitch, &Yaw, &Roll, + &position.x, &position.y, &position.z, + &loudness, &averageLoudness); + //printf("%f,%f,%f,%f,%f,%f\n", Pitch, Yaw, Roll, position.x, position.y, position.z); } void Head::SetNewHeadTarget(float pitch, float yaw) diff --git a/interface/src/Head.h b/interface/src/Head.h index 762c471ca8..a2a57381a7 100644 --- a/interface/src/Head.h +++ b/interface/src/Head.h @@ -45,6 +45,11 @@ class Head { float NoiseEnvelope; float PupilConverge; float scale; + + // Sound loudness information + float loudness; + float averageLoudness; + glm::vec3 position; int eyeContact; eyeContactTargets eyeContactTarget; @@ -80,6 +85,12 @@ public: // Send and receive network data int getBroadcastData(char* data); void recvBroadcastData(char * data, int size); + + float getLoudness() {return loudness;}; + float getAverageLoudness() {return averageLoudness;}; + float setAverageLoudness(float al) {averageLoudness = al;}; + float setLoudness(float l) {loudness = l;}; + void SetNewHeadTarget(float, float); glm::vec3 getPos() { return position; }; void setPos(glm::vec3 newpos) { position = newpos; }; diff --git a/interface/src/Network.cpp b/interface/src/Network.cpp deleted file mode 100644 index 8ded59c26f..0000000000 --- a/interface/src/Network.cpp +++ /dev/null @@ -1,156 +0,0 @@ -// -// Network.cpp -// interface -// -// Created by Philip Rosedale on 8/27/12. -// Copyright (c) 2012 High Fidelity, Inc. All rights reserved. -// - -#include -#include -#include - -#include "Network.h" - - -// Implementation of optional delay behavior using a ring buffer -const int MAX_DELAY_PACKETS = 300; -char delay_buffer[MAX_PACKET_SIZE*MAX_DELAY_PACKETS]; -timeval delay_time_received[MAX_DELAY_PACKETS]; -int delay_size_received[MAX_DELAY_PACKETS]; -int next_to_receive = 0; -int next_to_send = 0; - -sockaddr_in address, dest_address, domainserver_address, from; -socklen_t fromLength = sizeof( from ); - -int network_init() -{ - // Create socket - int handle = socket( AF_INET, SOCK_DGRAM, IPPROTO_UDP ); - - if ( handle <= 0 ) - { - printf( "failed to create socket\n" ); - return false; - } - - // Bind socket to port - address.sin_family = AF_INET; - address.sin_addr.s_addr = INADDR_ANY; - address.sin_port = htons( (unsigned short) SENDING_UDP_PORT ); - - if ( bind( handle, (const sockaddr*) &address, sizeof(sockaddr_in) ) < 0 ) - { - printf( "failed to bind socket\n" ); - return false; - } - - // Set socket as non-blocking - int nonBlocking = 1; - if ( fcntl( handle, F_SETFL, O_NONBLOCK, nonBlocking ) == -1 ) - { - printf( "failed to set non-blocking socket\n" ); - return false; - } - - // Setup desination address - - /*unsigned int ip_address; - if (!inet_pton(AF_INET, DESTINATION_IP, &ip_address)) - { - printf("failed to translate destination IP address\n"); - return false; - }*/ - - dest_address.sin_family = AF_INET; - dest_address.sin_addr.s_addr = inet_addr(DESTINATION_IP); - //dest_address.sin_port = htons( (unsigned short) UDP_PORT ); - - domainserver_address.sin_family = AF_INET; - domainserver_address.sin_addr.s_addr = inet_addr(DOMAINSERVER_IP); - domainserver_address.sin_port = htons( (unsigned short) DOMAINSERVER_PORT ); - - from.sin_family = AF_INET; - //from.sin_addr.s_addr = htonl(ip_address); - //from.sin_port = htons( (unsigned short) UDP_PORT ); - - return handle; -} - -// Send a ping packet and mark the time sent -timeval network_send_ping(int handle) { - timeval check; - char packet_data[] = "P"; - sendto(handle, (const char*)packet_data, 1, - 0, (sockaddr*)&dest_address, sizeof(sockaddr_in) ); - gettimeofday(&check, NULL); - return check; -} - -int notify_domainserver(int handle, float x, float y, float z) { - char data[100]; - sprintf(data, "%f,%f,%f", x, y, z); - int packet_size = strlen(data); - //std::cout << "sending: " << data << " of size: " << packet_size << "\n"; - int sent_bytes = sendto( handle, (const char*)data, packet_size, - 0, (sockaddr*)&domainserver_address, sizeof(sockaddr_in) ); - if ( sent_bytes != packet_size ) - { - printf( "failed to send to domainserver: return value = %d\n", sent_bytes ); - return false; - } - return sent_bytes; -} - - -int network_send(int handle, char * packet_data, int packet_size) -{ - int sent_bytes = 0; - sent_bytes = sendto( handle, (const char*)packet_data, packet_size, - 0, (sockaddr*)&dest_address, sizeof(sockaddr_in) ); - - if ( sent_bytes != packet_size ) - { - printf( "failed to send packet to address, port: %s, %d, returned = %d\n", inet_ntoa(dest_address.sin_addr), dest_address.sin_port, sent_bytes ); - return false; - } - return sent_bytes; -} - -int network_receive(int handle, in_addr * from_addr, char * packet_data, int delay /*msecs*/) -{ - int received_bytes = recvfrom(handle, (char*)packet_data, MAX_PACKET_SIZE, - 0, (sockaddr*)&dest_address, &fromLength ); - from_addr->s_addr = dest_address.sin_addr.s_addr; - - if (!delay) { - // No delay set, so just return packets immediately! - return received_bytes; - } else { - timeval check; - gettimeofday(&check, NULL); - if (received_bytes > 0) { - // First write received data into ring buffer - delay_time_received[next_to_receive] = check; - delay_size_received[next_to_receive] = received_bytes; - memcpy(&delay_buffer[next_to_receive*MAX_PACKET_SIZE], packet_data, received_bytes); - next_to_receive++; - if (next_to_receive == MAX_DELAY_PACKETS) next_to_receive = 0; - } - // Then check if next to be sent is past due, send if so - if ((next_to_receive != next_to_send) && - (diffclock(&delay_time_received[next_to_send], &check) > delay)) { - int returned_bytes = delay_size_received[next_to_send]; - memcpy(packet_data, - &delay_buffer[next_to_send*MAX_PACKET_SIZE], - returned_bytes); - next_to_send++; - if (next_to_send == MAX_DELAY_PACKETS) next_to_send = 0; - return returned_bytes; - } else { - return 0; - } - } - -} diff --git a/interface/src/Network.h b/interface/src/Network.h deleted file mode 100644 index 59c823cabd..0000000000 --- a/interface/src/Network.h +++ /dev/null @@ -1,41 +0,0 @@ -// -// Network.h -// interface -// -// Created by Philip Rosedale on 8/27/12. -// Copyright (c) 2012 High Fidelity, Inc. All rights reserved. -// - -#ifndef __interface__Network__ -#define __interface__Network__ - -#include -#include -#include -#include -#include -#include "Util.h" - -// Port to use for communicating UDP with other nearby agents -const int MAX_PACKET_SIZE = 1500; -const int SENDING_UDP_PORT = 40100; - -const int AGENT_UDP_PORT = 40103; - -const char DESTINATION_IP[] = "127.0.0.1"; - -// Address and port of domainserver process to advertise other agents -const char DOMAINSERVER_IP[] = "127.0.0.1"; - -const int DOMAINSERVER_PORT = 40102; - -// Randomly send a ping packet every N packets sent -const int PING_PACKET_COUNT = 20; - -int network_init(); -int network_send(int handle, char * packet_data, int packet_size); -int network_receive(int handle, in_addr * from_addr, char * packet_data, int delay /*msecs*/); -timeval network_send_ping(int handle); -int notify_domainserver(int handle, float x, float y, float z); - -#endif diff --git a/interface/src/UDPSocket.cpp b/interface/src/UDPSocket.cpp index 87e7a6e9e8..819a1dd7be 100644 --- a/interface/src/UDPSocket.cpp +++ b/interface/src/UDPSocket.cpp @@ -51,6 +51,7 @@ UDPSocket::UDPSocket(int listeningPort) { printf("Created UDP socket listening on port %d.\n", listeningPort); } +// Receive data on this socket with retrieving address of sender bool UDPSocket::receive(void *receivedData, int *receivedBytes) { *receivedBytes = recvfrom(handle, receivedData, MAX_BUFFER_LENGTH_BYTES, @@ -59,6 +60,15 @@ bool UDPSocket::receive(void *receivedData, int *receivedBytes) { return (*receivedBytes > 0); } +// Receive data on this socket with the address of the sender +bool UDPSocket::receive(sockaddr_in *senderAddress, void *receivedData, int *receivedBytes) { + + *receivedBytes = recvfrom(handle, receivedData, MAX_BUFFER_LENGTH_BYTES, + 0, (sockaddr *)senderAddress, &addLength); + + return (*receivedBytes > 0); +} + int UDPSocket::send(char * destAddress, int destPort, const void *data, int byteLength) { // change address and port on reusable global to passed variables diff --git a/interface/src/UDPSocket.h b/interface/src/UDPSocket.h index a360c55287..dd64ee1c41 100644 --- a/interface/src/UDPSocket.h +++ b/interface/src/UDPSocket.h @@ -19,7 +19,8 @@ class UDPSocket { UDPSocket(int listening_port); int send(char *destAddress, int destPort, const void *data, int byteLength); bool receive(void *receivedData, int *receivedBytes); - private: + bool receive(sockaddr_in *senderAddress, void *receivedData, int *receivedBytes); + private: int handle; UDPSocket(); // private default constructor diff --git a/interface/src/main.cpp b/interface/src/main.cpp index 8a64b7e169..13130335c3 100644 --- a/interface/src/main.cpp +++ b/interface/src/main.cpp @@ -34,7 +34,6 @@ #include "Field.h" #include "world.h" #include "Util.h" -#include "Network.h" #include "Audio.h" #include "Head.h" #include "Hand.h" @@ -51,14 +50,19 @@ using namespace std; int audio_on = 1; // Whether to turn on the audio support int simulate_on = 1; -// Network Socket Stuff +// +// Network Socket and network constants +// + +const int MAX_PACKET_SIZE = 1500; +const int AGENT_UDP_PORT = 40103; +char DOMAINSERVER_IP[] = "127.0.0.1"; +const int DOMAINSERVER_PORT = 40102; +UDPSocket agentSocket(AGENT_UDP_PORT); + // For testing, add milliseconds of delay for received UDP packets -int UDP_socket; -int delay = 0; char* incoming_packet; -timeval ping_start; -int ping_count = 0; -float ping_msecs = 0.0; + int packetcount = 0; int packets_per_second = 0; int bytes_per_second = 0; @@ -68,7 +72,7 @@ int bytescount = 0; int target_x, target_y; int target_display = 0; -int head_mirror = 1; // Whether to mirror the head when viewing it +int head_mirror = 1; // Whether to mirror own head when viewing it int WIDTH = 1200; int HEIGHT = 800; @@ -76,8 +80,8 @@ int fullscreen = 0; #define HAND_RADIUS 0.25 // Radius of in-world 'hand' of you Head myHead; // The rendered head of oneself or others -Head dummyHead; // Test Head to render -int showDummyHead = 1; +Head dummyHead; // Test Head to render +int showDummyHead = 0; Hand myHand(HAND_RADIUS, glm::vec3(0,1,1)); // My hand (used to manipulate things in world) @@ -91,10 +95,9 @@ ParticleSystem balls(0, 0.0 // Gravity ); - Cloud cloud(0, // Particles - box, // Bounding Box - false // Wrap + box, // Bounding Box + false // Wrap ); VoxelSystem voxels(0, box); @@ -146,6 +149,7 @@ int head_lean_x, head_lean_y; int mouse_x, mouse_y; // Where is the mouse int mouse_pressed = 0; // true if mouse has been pressed (clear when finished) +int nearbyAgents = 0; // How many other people near you is the domain server reporting? int speed; @@ -220,9 +224,15 @@ void Timer(int extra) glutTimerFunc(1000,Timer,0); gettimeofday(&timer_start, NULL); - // Send a message to the domainserver telling it we are ALIVE - notify_domainserver(UDP_socket, location[0], location[1], location[2]); - + // Send a message to the domainserver telling it we are ALIVE + char output[100]; + sprintf(output, "%f,%f,%f", location[0], location[1], location[2]); + int packet_size = strlen(output); + agentSocket.send(DOMAINSERVER_IP, DOMAINSERVER_PORT, output, packet_size); + + // Send a message to ourselves + //char test[]="T"; + //agentSocket.send("127.0.0.1", AGENT_UDP_PORT, test, 1); } void display_stats(void) @@ -232,13 +242,13 @@ void display_stats(void) drawtext(10, 15, 0.10, 0, 1.0, 0, legend); char stats[200]; - sprintf(stats, "FPS = %3.0f, Ping = %4.1f Pkts/s = %d, Bytes/s = %d", - FPS, ping_msecs, packets_per_second, bytes_per_second); + sprintf(stats, "FPS = %3.0f, Pkts/s = %d, Bytes/s = %d", + FPS, packets_per_second, bytes_per_second); drawtext(10, 30, 0.10, 0, 1.0, 0, stats); if (serial_on) { sprintf(stats, "ADC samples = %d, LED = %d", serialPort.getNumSamples(), serialPort.getLED()); - drawtext(500, 30, 0.10, 0, 1.0, 0, stats); + drawtext(500, 30, 0.10, 0, 1.0, 0, stats); } char adc[200]; @@ -247,7 +257,10 @@ void display_stats(void) angle_to(myHead.getPos()*-1.f, glm::vec3(0,0,0), myHead.getRenderYaw(), myHead.getYaw()), myHead.getYaw(), myHead.getRenderYaw()); drawtext(10, 50, 0.10, 0, 1.0, 0, adc); - + + char agents[100]; + sprintf(agents, "Nearby: %d\n", nearbyAgents); + drawtext(WIDTH-200,20, 0.10, 0, 1.0, 0, agents, 1, 1, 0); } @@ -499,16 +512,24 @@ void update_pos(float frametime) myHead.setRenderYaw(myHead.getRenderYaw() + render_yaw_rate); myHead.setRenderPitch(render_pitch); myHead.setPos(glm::vec3(location[0], location[1], location[2])); + + // Get audio loudness data from audio input device + float loudness, averageLoudness; + Audio::getInputLoudness(&loudness, &averageLoudness); + myHead.setLoudness(loudness); + myHead.setAverageLoudness(averageLoudness); - // Update all this stuff to any agents that are nearby and need to see it! + // Send my streaming head data to agents that are nearby and need to see it! const int MAX_BROADCAST_STRING = 200; char broadcast_string[MAX_BROADCAST_STRING]; int broadcast_bytes = myHead.getBroadcastData(broadcast_string); - dummyHead.recvBroadcastData(broadcast_string, broadcast_bytes); + broadcast_to_agents(&agentSocket, broadcast_string, broadcast_bytes); + + //printf("-> %s\n", broadcast_string); + //dummyHead.recvBroadcastData(broadcast_string, broadcast_bytes); //printf("head bytes: %d\n", broadcast_bytes); - broadcast_to_agents(UDP_socket, broadcast_string, broadcast_bytes); - + } int render_test_spot = WIDTH/2; @@ -744,14 +765,15 @@ void key(unsigned char k, int x, int y) } } -// -// Check for and process incoming network packets -// +// +// Receive packets from other agents/servers and decide what to do with them! +// void read_network() { - // Receive packets - in_addr from_addr; - int bytes_recvd = network_receive(UDP_socket, &from_addr, incoming_packet, delay); + sockaddr_in senderAddress; + int bytes_recvd; + agentSocket.receive(&senderAddress, (void *)incoming_packet, &bytes_recvd); + if (bytes_recvd > 0) { packetcount++; @@ -764,23 +786,20 @@ void read_network() sscanf(incoming_packet, "M %d %d", &target_x, &target_y); target_display = 1; //printf("X = %d Y = %d\n", target_x, target_y); - } else if (incoming_packet[0] == 'P') { - // - // Ping packet - check time and record + } else if (incoming_packet[0] == 'D') { // - timeval check; - gettimeofday(&check, NULL); - ping_msecs = (float)diffclock(&ping_start, &check); - } else if (incoming_packet[0] == 'S') { + // Message from domainserver // - // Message from domainserver - // - update_agents(&incoming_packet[1], bytes_recvd - 1); + //printf("agent list received!\n"); + nearbyAgents = update_agents(&incoming_packet[1], bytes_recvd - 1); } else if (incoming_packet[0] == 'H') { // // Broadcast packet from another agent // - update_agent(from_addr, &incoming_packet[1], bytes_recvd - 1); + //printf("Got broadcast!\n"); + update_agent(inet_ntoa(senderAddress.sin_addr), senderAddress.sin_port, &incoming_packet[1], bytes_recvd - 1); + } else if (incoming_packet[0] == 'T') { + printf("Got test! From port %d\n", senderAddress.sin_port); } } } @@ -809,12 +828,6 @@ void idle(void) if (!step_on) glutPostRedisplay(); last_frame = check; - // Every 30 frames or so, check ping time - ping_count++; - if (ping_count >= 30) { - ping_start = network_send_ping(UDP_socket); - ping_count = 0; - } } // Read network packets @@ -873,7 +886,7 @@ void motionFunc( int x, int y) // Send network packet containing mouse location char mouse_string[20]; sprintf(mouse_string, "M %d %d\n", mouse_x, mouse_y); - network_send(UDP_socket, mouse_string, strlen(mouse_string)); + //network_send(UDP_socket, mouse_string, strlen(mouse_string)); } lattice.mouseClick((float)x/(float)WIDTH,(float)y/(float)HEIGHT); @@ -903,17 +916,7 @@ void *poll_marker_capture(void *threadarg){ int main(int argc, char** argv) { // Create network socket and buffer - UDP_socket = network_init(); - if (UDP_socket) printf( "Created UDP socket.\n" ); incoming_packet = new char[MAX_PACKET_SIZE]; - - // Test network loopback - in_addr from_addr; - char test_data[] = "Test!"; - int bytes_sent = network_send(UDP_socket, test_data, 5); - if (bytes_sent) printf("%d bytes sent.", bytes_sent); - int test_recv = network_receive(UDP_socket, &from_addr, incoming_packet, delay); - printf("Received %i bytes\n", test_recv); // printf("Testing math... standard deviation.\n"); From 82594c31ba4ced568378953f7a43b56e84a5294e Mon Sep 17 00:00:00 2001 From: Philip Rosedale Date: Tue, 12 Feb 2013 01:50:12 -0800 Subject: [PATCH 2/4] stop failing texture load at startup, always show nearby agent count --- interface/src/main.cpp | 32 ++++++++++++++------------------ 1 file changed, 14 insertions(+), 18 deletions(-) diff --git a/interface/src/main.cpp b/interface/src/main.cpp index 13130335c3..508af7485a 100644 --- a/interface/src/main.cpp +++ b/interface/src/main.cpp @@ -258,10 +258,6 @@ void display_stats(void) myHead.getYaw(), myHead.getRenderYaw()); drawtext(10, 50, 0.10, 0, 1.0, 0, adc); - char agents[100]; - sprintf(agents, "Nearby: %d\n", nearbyAgents); - drawtext(WIDTH-200,20, 0.10, 0, 1.0, 0, agents, 1, 1, 0); - } void initDisplay(void) @@ -275,7 +271,7 @@ void initDisplay(void) glEnable(GL_LIGHT0); glEnable(GL_DEPTH_TEST); - load_png_as_texture(texture_filename); + //load_png_as_texture(texture_filename); if (fullscreen) glutFullScreen(); } @@ -663,6 +659,12 @@ void display(void) // Display miscellaneous text stats onscreen if (stats_on) display_stats(); + + // Draw number of nearby people always + char agents[100]; + sprintf(agents, "Agents nearby: %d\n", nearbyAgents); + drawtext(WIDTH-200,20, 0.10, 0, 1.0, 0, agents, 1, 1, 0); + #ifdef MARKER_CAPTURE /* Render marker acquisition stuff */ @@ -919,7 +921,7 @@ int main(int argc, char** argv) incoming_packet = new char[MAX_PACKET_SIZE]; // - printf("Testing math... standard deviation.\n"); + printf("Testing stats math... "); StDev stdevtest; stdevtest.reset(); stdevtest.addValue(1345); @@ -933,20 +935,15 @@ int main(int argc, char** argv) stdevtest.addValue(1303); stdevtest.addValue(1299); - if (stdevtest.getSamples() == 10) - printf("Samples=PASS "); - else + if (stdevtest.getSamples() != 10) printf("Samples=FAIL "); - if (floor(stdevtest.getAverage()*100.0) == 132859.0) - printf("Average=PASS "); - else - printf("Average=FAIL, avg reported = %5.3f ", floor(stdevtest.getAverage()*100.0)); + if (floor(stdevtest.getAverage()*100.0) != 132859.0) + printf("Average=FAIL "); - if (floor(stdevtest.getStDev()*100.0) == 2746.0) - printf("Stdev=PASS \n"); - else - printf("Stdev=FAIL \n"); + if (floor(stdevtest.getStDev()*100.0) != 2746.0) + printf("Stdev=FAIL "); + printf("\n"); // // Try to connect the serial port I/O @@ -961,7 +958,6 @@ int main(int argc, char** argv) serial_on = 1; } - glutInit(&argc, argv); glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH); glutInitWindowSize(WIDTH, HEIGHT); From b19fce1b46e4b1864fa5b1880b9290643c241eed Mon Sep 17 00:00:00 2001 From: Philip Rosedale Date: Tue, 12 Feb 2013 01:54:14 -0800 Subject: [PATCH 3/4] close socket added --- interface/src/UDPSocket.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/interface/src/UDPSocket.cpp b/interface/src/UDPSocket.cpp index 819a1dd7be..68c84e2564 100644 --- a/interface/src/UDPSocket.cpp +++ b/interface/src/UDPSocket.cpp @@ -51,6 +51,10 @@ UDPSocket::UDPSocket(int listeningPort) { printf("Created UDP socket listening on port %d.\n", listeningPort); } +UDPSocket::~UDPSocket() { + close(handle); +} + // Receive data on this socket with retrieving address of sender bool UDPSocket::receive(void *receivedData, int *receivedBytes) { From 6f9d22345487e47bc4ce740db899c7a63a9d2fe9 Mon Sep 17 00:00:00 2001 From: Philip Rosedale Date: Tue, 12 Feb 2013 10:58:30 -0800 Subject: [PATCH 4/4] Fixed network-to-host byte order problems when storing ports. --- domain/src/main.cpp | 4 ++-- interface/src/Agent.cpp | 14 +++++++------- interface/src/main.cpp | 5 ++--- 3 files changed, 11 insertions(+), 12 deletions(-) diff --git a/domain/src/main.cpp b/domain/src/main.cpp index 67fa347bbd..2e0a41a278 100644 --- a/domain/src/main.cpp +++ b/domain/src/main.cpp @@ -186,9 +186,9 @@ int main(int argc, const char * argv[]) //<< " " << packet_data << "\n"; float x,y,z; sscanf(packet_data, "%f,%f,%f", &x, &y, &z); - if (addAgent(dest_address.sin_addr.s_addr, dest_address.sin_port, x, y, z)) { + if (addAgent(dest_address.sin_addr.s_addr, ntohs(dest_address.sin_port), x, y, z)) { std::cout << "Added Agent from " << - inet_ntoa(dest_address.sin_addr) << ":" << dest_address.sin_port << "\n"; + inet_ntoa(dest_address.sin_addr) << ":" << ntohs(dest_address.sin_port) << "\n"; } // Reply with packet listing nearby active agents send_agent_list(handle, &dest_address); diff --git a/interface/src/Agent.cpp b/interface/src/Agent.cpp index 0086792c66..114a44adc3 100644 --- a/interface/src/Agent.cpp +++ b/interface/src/Agent.cpp @@ -84,15 +84,15 @@ int add_agent(char * address, unsigned short port) { //std::cout << "Checking for " << IP->c_str() << " "; for (int i = 0; i < num_agents; i++) { if ((strcmp(address, agents[i].address) == 0) && (agents[i].port == port)) { - //std::cout << "Found agent!\n"; + std::cout << "Found agent!\n"; return 0; } } if (num_agents < MAX_AGENTS) { strcpy(agents[num_agents].address, address); agents[num_agents].port = port; - //std::cout << "Added Agent # " << num_agents << " with Address " << - //agents[num_agents].address << ":" << agents[num_agents].port << "\n"; + std::cout << "Added Agent # " << num_agents << " with Address " << + agents[num_agents].address << ":" << agents[num_agents].port << "\n"; num_agents++; return 1; } else { @@ -113,10 +113,10 @@ int broadcast_to_agents(UDPSocket *handle, char * data, int length) { // STUPID HACK: For some reason on OSX with NAT translation packets sent to localhost are // received as from the NAT translated port but have to be sent to the local port number. // - if (strcmp("127.0.0.1",agents[i].address) == 0) - sent_bytes = handle->send(agents[i].address, 40103, data, length); - else - sent_bytes = handle->send(agents[i].address, agents[i].port, data, length); + //if (1) //(strcmp("192.168.1.53",agents[i].address) == 0) + // sent_bytes = handle->send(agents[i].address, 40103, data, length); + //else + sent_bytes = handle->send(agents[i].address, agents[i].port, data, length); if (sent_bytes != length) { std::cout << "Broadcast packet fail!\n"; diff --git a/interface/src/main.cpp b/interface/src/main.cpp index bec36f4af4..287d699d95 100644 --- a/interface/src/main.cpp +++ b/interface/src/main.cpp @@ -56,7 +56,7 @@ int simulate_on = 1; const int MAX_PACKET_SIZE = 1500; const int AGENT_UDP_PORT = 40103; -char DOMAINSERVER_IP[] = "127.0.0.1"; +char DOMAINSERVER_IP[] = "192.168.1.53"; const int DOMAINSERVER_PORT = 40102; UDPSocket agentSocket(AGENT_UDP_PORT); @@ -797,8 +797,7 @@ void read_network() // // Broadcast packet from another agent // - //printf("Got broadcast!\n"); - update_agent(inet_ntoa(senderAddress.sin_addr), senderAddress.sin_port, &incoming_packet[1], bytes_recvd - 1); + update_agent(inet_ntoa(senderAddress.sin_addr), ntohs(senderAddress.sin_port), &incoming_packet[1], bytes_recvd - 1); } else if (incoming_packet[0] == 'T') { printf("Got test! From port %d\n", senderAddress.sin_port); }