mirror of
https://github.com/overte-org/overte.git
synced 2025-08-09 14:29:03 +02:00
Merge branch 'master' of https://github.com/worklist/hifi
Conflicts: interface/src/main.cpp shared/src/SharedUtil.cpp shared/src/SharedUtil.h
This commit is contained in:
commit
23c6a9017c
18 changed files with 451 additions and 233 deletions
|
@ -6,4 +6,5 @@ add_subdirectory(space)
|
||||||
add_subdirectory(domain)
|
add_subdirectory(domain)
|
||||||
add_subdirectory(mixer)
|
add_subdirectory(mixer)
|
||||||
add_subdirectory(voxel)
|
add_subdirectory(voxel)
|
||||||
add_subdirectory(interface)
|
add_subdirectory(interface)
|
||||||
|
add_subdirectory(injector)
|
||||||
|
|
|
@ -45,11 +45,12 @@ const int LOGOFF_CHECK_INTERVAL = 5000;
|
||||||
#define DEBUG_TO_SELF 0
|
#define DEBUG_TO_SELF 0
|
||||||
|
|
||||||
int lastActiveCount = 0;
|
int lastActiveCount = 0;
|
||||||
AgentList agentList(DOMAIN_LISTEN_PORT);
|
AgentList agentList('D', DOMAIN_LISTEN_PORT);
|
||||||
|
|
||||||
unsigned char * addAgentToBroadcastPacket(unsigned char *currentPosition, Agent *agentToAdd) {
|
unsigned char * addAgentToBroadcastPacket(unsigned char *currentPosition, Agent *agentToAdd) {
|
||||||
*currentPosition++ = agentToAdd->getType();
|
*currentPosition++ = agentToAdd->getType();
|
||||||
|
|
||||||
|
currentPosition += packAgentId(currentPosition, agentToAdd->getAgentId());
|
||||||
currentPosition += packSocket(currentPosition, agentToAdd->getPublicSocket());
|
currentPosition += packSocket(currentPosition, agentToAdd->getPublicSocket());
|
||||||
currentPosition += packSocket(currentPosition, agentToAdd->getLocalSocket());
|
currentPosition += packSocket(currentPosition, agentToAdd->getLocalSocket());
|
||||||
|
|
||||||
|
@ -74,6 +75,8 @@ int main(int argc, const char * argv[])
|
||||||
sockaddr_in agentPublicAddress, agentLocalAddress;
|
sockaddr_in agentPublicAddress, agentLocalAddress;
|
||||||
agentLocalAddress.sin_family = AF_INET;
|
agentLocalAddress.sin_family = AF_INET;
|
||||||
|
|
||||||
|
in_addr_t serverLocalAddress = getLocalAddress();
|
||||||
|
|
||||||
agentList.startSilentAgentRemovalThread();
|
agentList.startSilentAgentRemovalThread();
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
|
@ -83,7 +86,21 @@ int main(int argc, const char * argv[])
|
||||||
agentType = packetData[0];
|
agentType = packetData[0];
|
||||||
unpackSocket(&packetData[1], (sockaddr *)&agentLocalAddress);
|
unpackSocket(&packetData[1], (sockaddr *)&agentLocalAddress);
|
||||||
|
|
||||||
agentList.addOrUpdateAgent((sockaddr *)&agentPublicAddress, (sockaddr *)&agentLocalAddress, agentType);
|
// check the agent public address
|
||||||
|
// if it matches our local address we're on the same box
|
||||||
|
// so hardcode the EC2 public address for now
|
||||||
|
if (agentPublicAddress.sin_addr.s_addr == serverLocalAddress) {
|
||||||
|
agentPublicAddress.sin_addr.s_addr = 895283510;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (agentList.addOrUpdateAgent((sockaddr *)&agentPublicAddress,
|
||||||
|
(sockaddr *)&agentLocalAddress,
|
||||||
|
agentType,
|
||||||
|
agentList.getLastAgentId())) {
|
||||||
|
|
||||||
|
agentList.increaseAgentId();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
currentBufferPos = broadcastPacket + 1;
|
currentBufferPos = broadcastPacket + 1;
|
||||||
startPointer = currentBufferPos;
|
startPointer = currentBufferPos;
|
||||||
|
|
17
injector/CMakeLists.txt
Normal file
17
injector/CMakeLists.txt
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
cmake_minimum_required(VERSION 2.8)
|
||||||
|
|
||||||
|
project(injector)
|
||||||
|
|
||||||
|
# grab the implemenation and header files
|
||||||
|
file(GLOB INJECTOR_SRCS src/*.cpp src/*.h)
|
||||||
|
|
||||||
|
# add the executable
|
||||||
|
add_executable(injector ${INJECTOR_SRCS})
|
||||||
|
|
||||||
|
# link the shared hifi library
|
||||||
|
include(../LinkHifiShared.cmake)
|
||||||
|
link_hifi_shared_library(injector)
|
||||||
|
|
||||||
|
# link the threads library
|
||||||
|
find_package(Threads REQUIRED)
|
||||||
|
target_link_libraries(injector ${CMAKE_THREAD_LIBS_INIT})
|
181
injector/src/injector.cpp
Normal file
181
injector/src/injector.cpp
Normal file
|
@ -0,0 +1,181 @@
|
||||||
|
//
|
||||||
|
// injector.cpp
|
||||||
|
// Audio Injector
|
||||||
|
//
|
||||||
|
// Created by Leonardo Murillo on 3/5/13.
|
||||||
|
// Copyright (c) 2013 Leonardo Murillo. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <vector>
|
||||||
|
#include <fstream>
|
||||||
|
#include <algorithm>
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <sstream>
|
||||||
|
#include "UDPSocket.h"
|
||||||
|
#include "UDPSocket.cpp"
|
||||||
|
#include <SharedUtil.h>
|
||||||
|
|
||||||
|
char EC2_WEST_AUDIO_SERVER[] = "54.241.92.53";
|
||||||
|
const int AUDIO_UDP_LISTEN_PORT = 55443;
|
||||||
|
const int BUFFER_LENGTH_BYTES = 512;
|
||||||
|
const int BUFFER_LENGTH_SAMPLES = BUFFER_LENGTH_BYTES / sizeof(int16_t);
|
||||||
|
const float SAMPLE_RATE = 22050.0;
|
||||||
|
const float BUFFER_SEND_INTERVAL_USECS = (BUFFER_LENGTH_SAMPLES / SAMPLE_RATE) * 1000000;
|
||||||
|
|
||||||
|
// Command line parameter defaults
|
||||||
|
bool loopAudio = true;
|
||||||
|
float sleepIntervalMin = 1.00;
|
||||||
|
float sleepIntervalMax = 2.00;
|
||||||
|
float positionInUniverse[] = {0, 0, 0, 0};
|
||||||
|
unsigned char attenuationModifier = 255;
|
||||||
|
char *sourceAudioFile;
|
||||||
|
const char *allowedParameters = ":rb::t::c::a::f:";
|
||||||
|
|
||||||
|
char *charBuffer;
|
||||||
|
int16_t *buffer;
|
||||||
|
long length;
|
||||||
|
|
||||||
|
UDPSocket *streamSocket;
|
||||||
|
|
||||||
|
void usage(void)
|
||||||
|
{
|
||||||
|
std::cout << "High Fidelity - Interface audio injector" << std::endl;
|
||||||
|
std::cout << " -r Random sleep mode. If not specified will default to constant loop." << std::endl;
|
||||||
|
std::cout << " -b FLOAT Min. number of seconds to sleep. Only valid in random sleep mode. Default 1.0" << std::endl;
|
||||||
|
std::cout << " -t FLOAT Max. number of seconds to sleep. Only valid in random sleep mode. Default 2.0" << std::endl;
|
||||||
|
std::cout << " -c FLOAT,FLOAT,FLOAT,FLOAT X,Y,Z,YAW position in universe where audio will be originating from and direction. Defaults to 0,0,0,0" << std::endl;
|
||||||
|
std::cout << " -a 0-255 Attenuation curve modifier, defaults to 255" << std::endl;
|
||||||
|
std::cout << " -f FILENAME Name of audio source file. Required - RAW format, 22050hz 16bit signed mono" << std::endl;
|
||||||
|
};
|
||||||
|
|
||||||
|
bool processParameters(int parameterCount, char* parameterData[])
|
||||||
|
{
|
||||||
|
int p;
|
||||||
|
while ((p = getopt(parameterCount, parameterData, allowedParameters)) != -1) {
|
||||||
|
switch (p) {
|
||||||
|
case 'r':
|
||||||
|
loopAudio = false;
|
||||||
|
std::cout << "[DEBUG] Random sleep mode enabled" << std::endl;
|
||||||
|
break;
|
||||||
|
case 'b':
|
||||||
|
sleepIntervalMin = atof(optarg);
|
||||||
|
std::cout << "[DEBUG] Min delay between plays " << sleepIntervalMin << "sec" << std::endl;
|
||||||
|
break;
|
||||||
|
case 't':
|
||||||
|
sleepIntervalMax = atof(optarg);
|
||||||
|
std::cout << "[DEBUG] Max delay between plays " << sleepIntervalMax << "sec" << std::endl;
|
||||||
|
break;
|
||||||
|
case 'f':
|
||||||
|
sourceAudioFile = optarg;
|
||||||
|
std::cout << "[DEBUG] Opening file: " << sourceAudioFile << std::endl;
|
||||||
|
break;
|
||||||
|
case 'c':
|
||||||
|
{
|
||||||
|
std::istringstream ss(optarg);
|
||||||
|
std::string token;
|
||||||
|
|
||||||
|
int i = 0;
|
||||||
|
while (std::getline(ss, token, ',')) {
|
||||||
|
positionInUniverse[i] = atof(token.c_str());
|
||||||
|
++i;
|
||||||
|
if (i == 4) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 'a':
|
||||||
|
attenuationModifier = atoi(optarg);
|
||||||
|
std::cout << "[DEBUG] Attenuation modifier: " << optarg << std::endl;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
usage();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
void loadFile(void) {
|
||||||
|
std::fstream sourceFile;
|
||||||
|
sourceFile.open(sourceAudioFile, std::ios::in | std::ios::binary);
|
||||||
|
sourceFile.seekg(0, std::ios::end);
|
||||||
|
length = sourceFile.tellg();
|
||||||
|
sourceFile.seekg(0, std::ios::beg);
|
||||||
|
long sizeOfShortArray = length / 2;
|
||||||
|
buffer = new int16_t[sizeOfShortArray];
|
||||||
|
sourceFile.read((char *)buffer, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
void stream(void)
|
||||||
|
{
|
||||||
|
timeval startTime;
|
||||||
|
|
||||||
|
int leadingBytes = 1 + (sizeof(float) * 4);
|
||||||
|
unsigned char dataPacket[BUFFER_LENGTH_BYTES + leadingBytes];
|
||||||
|
|
||||||
|
dataPacket[0] = 'I';
|
||||||
|
unsigned char *currentPacketPtr = dataPacket + 1;
|
||||||
|
|
||||||
|
for (int p = 0; p < 4; p++) {
|
||||||
|
memcpy(currentPacketPtr, &positionInUniverse[p], sizeof(float));
|
||||||
|
currentPacketPtr += sizeof(float);
|
||||||
|
}
|
||||||
|
|
||||||
|
*currentPacketPtr = attenuationModifier;
|
||||||
|
currentPacketPtr++;
|
||||||
|
|
||||||
|
for (int i = 0; i < length; i += BUFFER_LENGTH_SAMPLES) {
|
||||||
|
gettimeofday(&startTime, NULL);
|
||||||
|
memcpy(currentPacketPtr, &buffer[i], BUFFER_LENGTH_BYTES);
|
||||||
|
streamSocket->send(EC2_WEST_AUDIO_SERVER, AUDIO_UDP_LISTEN_PORT, dataPacket, sizeof(dataPacket));
|
||||||
|
double usecToSleep = usecTimestamp(&startTime) + BUFFER_SEND_INTERVAL_USECS - usecTimestampNow();
|
||||||
|
usleep(usecToSleep);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
int main(int argc, char* argv[])
|
||||||
|
{
|
||||||
|
|
||||||
|
srand(time(0));
|
||||||
|
int AUDIO_UDP_SEND_PORT = 1500 + (rand() % (int)(1500 - 2000 + 1));
|
||||||
|
|
||||||
|
UDPSocket *streamSocket = new UDPSocket(AUDIO_UDP_SEND_PORT);
|
||||||
|
|
||||||
|
if (processParameters(argc, argv)) {
|
||||||
|
if (sourceAudioFile) {
|
||||||
|
loadFile();
|
||||||
|
} else {
|
||||||
|
std::cout << "[FATAL] Source audio file not specified" << std::endl;
|
||||||
|
exit(-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < sizeof(positionInUniverse)/sizeof(positionInUniverse[0]); ++i) {
|
||||||
|
std::cout << "Position " << positionInUniverse[i] << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
float delay;
|
||||||
|
int usecDelay;
|
||||||
|
while (true) {
|
||||||
|
stream();
|
||||||
|
|
||||||
|
if (loopAudio) {
|
||||||
|
delay = 0;
|
||||||
|
} else {
|
||||||
|
delay = randFloatInRange(sleepIntervalMin, sleepIntervalMax);
|
||||||
|
}
|
||||||
|
usecDelay = delay * 1000 * 1000;
|
||||||
|
usleep(usecDelay);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -158,6 +158,9 @@ int audioCallback (const void *inputBuffer,
|
||||||
currentPacketPtr += sizeof(float);
|
currentPacketPtr += sizeof(float);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// tell the mixer not to add additional attenuation to our source
|
||||||
|
*(currentPacketPtr++) = 255;
|
||||||
|
|
||||||
// memcpy the corrected render yaw
|
// memcpy the corrected render yaw
|
||||||
float correctedYaw = fmodf(data->linkedHead->getRenderYaw(), 360);
|
float correctedYaw = fmodf(data->linkedHead->getRenderYaw(), 360);
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,6 @@
|
||||||
#include <fstream> // to load voxels from file
|
#include <fstream> // to load voxels from file
|
||||||
#include <SharedUtil.h>
|
#include <SharedUtil.h>
|
||||||
#include <OctalCode.h>
|
#include <OctalCode.h>
|
||||||
#include <AgentList.h>
|
|
||||||
#include "VoxelSystem.h"
|
#include "VoxelSystem.h"
|
||||||
|
|
||||||
const int MAX_VOXELS_PER_SYSTEM = 250000;
|
const int MAX_VOXELS_PER_SYSTEM = 250000;
|
||||||
|
|
|
@ -46,7 +46,7 @@
|
||||||
#include "Particle.h"
|
#include "Particle.h"
|
||||||
#include "Texture.h"
|
#include "Texture.h"
|
||||||
#include "Cloud.h"
|
#include "Cloud.h"
|
||||||
#include "AgentList.h"
|
#include <AgentList.h>
|
||||||
#include "VoxelSystem.h"
|
#include "VoxelSystem.h"
|
||||||
#include "Lattice.h"
|
#include "Lattice.h"
|
||||||
#include "Finger.h"
|
#include "Finger.h"
|
||||||
|
@ -64,11 +64,10 @@ int simulate_on = 1;
|
||||||
// Network Socket and network constants
|
// Network Socket and network constants
|
||||||
//
|
//
|
||||||
|
|
||||||
char DOMAIN_HOSTNAME[100] = "highfidelity.below92.com";
|
char DOMAIN_HOSTNAME[] = "highfidelity.below92.com";
|
||||||
char DOMAIN_IP[100] = ""; // IP Address will be used first if not empty string
|
char DOMAIN_IP[100] = ""; // IP Address will be used first if not empty string
|
||||||
const int DOMAINSERVER_PORT = 40102;
|
const int DOMAINSERVER_PORT = 40102;
|
||||||
|
AgentList agentList('I');
|
||||||
AgentList agentList;
|
|
||||||
pthread_t networkReceiveThread;
|
pthread_t networkReceiveThread;
|
||||||
bool stopNetworkReceiveThread = false;
|
bool stopNetworkReceiveThread = false;
|
||||||
|
|
||||||
|
@ -89,14 +88,11 @@ int WIDTH = 1200;
|
||||||
int HEIGHT = 800;
|
int HEIGHT = 800;
|
||||||
int fullscreen = 0;
|
int fullscreen = 0;
|
||||||
|
|
||||||
in_addr_t localAddress;
|
|
||||||
|
|
||||||
Oscilloscope audioScope(256,200,true);
|
Oscilloscope audioScope(256,200,true);
|
||||||
|
|
||||||
#define HAND_RADIUS 0.25 // Radius of in-world 'hand' of you
|
#define HAND_RADIUS 0.25 // Radius of in-world 'hand' of you
|
||||||
Head myHead; // The rendered head of oneself
|
Head myHead; // The rendered head of oneself
|
||||||
|
|
||||||
|
|
||||||
glm::vec3 box(WORLD_SIZE,WORLD_SIZE,WORLD_SIZE);
|
glm::vec3 box(WORLD_SIZE,WORLD_SIZE,WORLD_SIZE);
|
||||||
ParticleSystem balls(0,
|
ParticleSystem balls(0,
|
||||||
box,
|
box,
|
||||||
|
@ -227,15 +223,6 @@ void Timer(int extra)
|
||||||
glutTimerFunc(1000,Timer,0);
|
glutTimerFunc(1000,Timer,0);
|
||||||
gettimeofday(&timer_start, NULL);
|
gettimeofday(&timer_start, NULL);
|
||||||
|
|
||||||
//
|
|
||||||
// Send a message to the domainserver telling it we are ALIVE
|
|
||||||
//
|
|
||||||
unsigned char output[7];
|
|
||||||
output[0] = 'I';
|
|
||||||
packSocket(output + 1, localAddress, htons(AGENT_SOCKET_LISTEN_PORT));
|
|
||||||
|
|
||||||
agentList.getAgentSocket().send(DOMAIN_IP, DOMAINSERVER_PORT, output, 7);
|
|
||||||
|
|
||||||
// Ping the agents we can see
|
// Ping the agents we can see
|
||||||
agentList.pingAgents();
|
agentList.pingAgents();
|
||||||
|
|
||||||
|
@ -948,51 +935,17 @@ void audioMixerUpdate(in_addr_t newMixerAddress, in_port_t newMixerPort) {
|
||||||
|
|
||||||
int main(int argc, char** argv)
|
int main(int argc, char** argv)
|
||||||
{
|
{
|
||||||
// pass --NoConnect as a command line option to force NOT connecting
|
|
||||||
// to the hifidelity domain, and therefore run locally.
|
|
||||||
if (cmdOptionExists(argc, argv, "--NoConnect"))
|
|
||||||
{
|
|
||||||
strcpy(DOMAIN_HOSTNAME,"");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef _WIN32
|
|
||||||
struct ifaddrs * ifAddrStruct=NULL;
|
|
||||||
struct ifaddrs * ifa=NULL;
|
|
||||||
|
|
||||||
getifaddrs(&ifAddrStruct);
|
|
||||||
|
|
||||||
for (ifa = ifAddrStruct; ifa != NULL; ifa = ifa->ifa_next) {
|
|
||||||
if (ifa ->ifa_addr->sa_family==AF_INET) { // check it is IP4
|
|
||||||
// is a valid IP4 Address
|
|
||||||
localAddress = ((struct sockaddr_in *)ifa->ifa_addr)->sin_addr.s_addr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Lookup the IP address of things we have hostnames
|
|
||||||
if (atoi(DOMAIN_IP) == 0) {
|
|
||||||
struct hostent* pHostInfo;
|
|
||||||
if ((pHostInfo = gethostbyname(DOMAIN_HOSTNAME)) != NULL) {
|
|
||||||
sockaddr_in tempAddress;
|
|
||||||
memcpy(&tempAddress.sin_addr, pHostInfo->h_addr_list[0], pHostInfo->h_length);
|
|
||||||
strcpy(DOMAIN_IP, inet_ntoa(tempAddress.sin_addr));
|
|
||||||
printf("Domain server %s: %s\n", DOMAIN_HOSTNAME, DOMAIN_IP);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
printf("Failed lookup domainserver\n");
|
|
||||||
}
|
|
||||||
} else printf("Using static domainserver IP: %s\n", DOMAIN_IP);
|
|
||||||
|
|
||||||
// the callback for our instance of AgentList is attachNewHeadToAgent
|
// the callback for our instance of AgentList is attachNewHeadToAgent
|
||||||
agentList.linkedDataCreateCallback = &attachNewHeadToAgent;
|
agentList.linkedDataCreateCallback = &attachNewHeadToAgent;
|
||||||
|
|
||||||
#ifndef _WIN32
|
#ifndef _WIN32
|
||||||
agentList.audioMixerSocketUpdate = &audioMixerUpdate;
|
agentList.audioMixerSocketUpdate = &audioMixerUpdate;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// start the thread which checks for silent agents
|
// start the thread which checks for silent agents
|
||||||
agentList.startSilentAgentRemovalThread();
|
agentList.startSilentAgentRemovalThread();
|
||||||
|
agentList.startDomainServerCheckInThread();
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
WSADATA WsaData;
|
WSADATA WsaData;
|
||||||
int wsaresult = WSAStartup( MAKEWORD(2,2), &WsaData );
|
int wsaresult = WSAStartup( MAKEWORD(2,2), &WsaData );
|
||||||
|
|
|
@ -53,11 +53,7 @@ const int AGENT_LOOPBACK_MODIFIER = 307;
|
||||||
|
|
||||||
const int LOOPBACK_SANITY_CHECK = 0;
|
const int LOOPBACK_SANITY_CHECK = 0;
|
||||||
|
|
||||||
char DOMAIN_HOSTNAME[] = "highfidelity.below92.com";
|
AgentList agentList('M', MIXER_LISTEN_PORT);
|
||||||
char DOMAIN_IP[100] = ""; // IP Address will be re-set by lookup on startup
|
|
||||||
const int DOMAINSERVER_PORT = 40102;
|
|
||||||
|
|
||||||
AgentList agentList(MIXER_LISTEN_PORT);
|
|
||||||
StDev stdev;
|
StDev stdev;
|
||||||
|
|
||||||
void plateauAdditionOfSamples(int16_t &mixSample, int16_t sampleToAdd) {
|
void plateauAdditionOfSamples(int16_t &mixSample, int16_t sampleToAdd) {
|
||||||
|
@ -147,9 +143,6 @@ void *sendBuffer(void *args)
|
||||||
float triangleAngle = atan2f(fabsf(agentPosition[2] - otherAgentPosition[2]), fabsf(agentPosition[0] - otherAgentPosition[0])) * (180 / M_PI);
|
float triangleAngle = atan2f(fabsf(agentPosition[2] - otherAgentPosition[2]), fabsf(agentPosition[0] - otherAgentPosition[0])) * (180 / M_PI);
|
||||||
float angleToSource;
|
float angleToSource;
|
||||||
|
|
||||||
if (agentWantsLoopback) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// find the angle we need for calculation based on the orientation of the triangle
|
// find the angle we need for calculation based on the orientation of the triangle
|
||||||
if (otherAgentPosition[0] > agentPosition[0]) {
|
if (otherAgentPosition[0] > agentPosition[0]) {
|
||||||
|
@ -178,8 +171,6 @@ void *sendBuffer(void *args)
|
||||||
int numSamplesDelay = PHASE_DELAY_AT_90 * sinRatio;
|
int numSamplesDelay = PHASE_DELAY_AT_90 * sinRatio;
|
||||||
float weakChannelAmplitudeRatio = 1 - (PHASE_AMPLITUDE_RATIO_AT_90 * sinRatio);
|
float weakChannelAmplitudeRatio = 1 - (PHASE_AMPLITUDE_RATIO_AT_90 * sinRatio);
|
||||||
|
|
||||||
printf("The weak channel AR is %f\n", weakChannelAmplitudeRatio);
|
|
||||||
|
|
||||||
int16_t *goodChannel = angleToSource > 0 ? clientMix + BUFFER_LENGTH_SAMPLES_PER_CHANNEL : clientMix;
|
int16_t *goodChannel = angleToSource > 0 ? clientMix + BUFFER_LENGTH_SAMPLES_PER_CHANNEL : clientMix;
|
||||||
int16_t *delayedChannel = angleToSource > 0 ? clientMix : clientMix + BUFFER_LENGTH_SAMPLES_PER_CHANNEL;
|
int16_t *delayedChannel = angleToSource > 0 ? clientMix : clientMix + BUFFER_LENGTH_SAMPLES_PER_CHANNEL;
|
||||||
|
|
||||||
|
@ -193,11 +184,16 @@ void *sendBuffer(void *args)
|
||||||
if (s < numSamplesDelay) {
|
if (s < numSamplesDelay) {
|
||||||
// pull the earlier sample for the delayed channel
|
// pull the earlier sample for the delayed channel
|
||||||
|
|
||||||
int earlierSample = delaySamplePointer[s] * distanceCoeffs[lowAgentIndex][highAgentIndex];
|
int earlierSample = delaySamplePointer[s] *
|
||||||
|
distanceCoeffs[lowAgentIndex][highAgentIndex] *
|
||||||
|
otherAgentBuffer->getAttenuationRatio();
|
||||||
|
|
||||||
plateauAdditionOfSamples(delayedChannel[s], earlierSample * weakChannelAmplitudeRatio);
|
plateauAdditionOfSamples(delayedChannel[s], earlierSample * weakChannelAmplitudeRatio);
|
||||||
}
|
}
|
||||||
|
|
||||||
int16_t currentSample = (otherAgentBuffer->getNextOutput()[s] * distanceCoeffs[lowAgentIndex][highAgentIndex]);
|
int16_t currentSample = (otherAgentBuffer->getNextOutput()[s] *
|
||||||
|
distanceCoeffs[lowAgentIndex][highAgentIndex]) *
|
||||||
|
otherAgentBuffer->getAttenuationRatio();
|
||||||
plateauAdditionOfSamples(goodChannel[s], currentSample);
|
plateauAdditionOfSamples(goodChannel[s], currentSample);
|
||||||
|
|
||||||
if (s + numSamplesDelay < BUFFER_LENGTH_SAMPLES_PER_CHANNEL) {
|
if (s + numSamplesDelay < BUFFER_LENGTH_SAMPLES_PER_CHANNEL) {
|
||||||
|
@ -235,29 +231,6 @@ void *sendBuffer(void *args)
|
||||||
pthread_exit(0);
|
pthread_exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void *reportAliveToDS(void *args) {
|
|
||||||
|
|
||||||
timeval lastSend;
|
|
||||||
unsigned char output[7];
|
|
||||||
|
|
||||||
while (true) {
|
|
||||||
gettimeofday(&lastSend, NULL);
|
|
||||||
|
|
||||||
*output = 'M';
|
|
||||||
packSocket(output + 1, 895283510, htons(MIXER_LISTEN_PORT));
|
|
||||||
// packSocket(output + 1, 788637888, htons(MIXER_LISTEN_PORT));
|
|
||||||
agentList.getAgentSocket().send(DOMAIN_IP, DOMAINSERVER_PORT, output, 7);
|
|
||||||
|
|
||||||
double usecToSleep = 1000000 - (usecTimestampNow() - usecTimestamp(&lastSend));
|
|
||||||
|
|
||||||
if (usecToSleep > 0) {
|
|
||||||
usleep(usecToSleep);
|
|
||||||
} else {
|
|
||||||
std::cout << "No sleep required!";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void attachNewBufferToAgent(Agent *newAgent) {
|
void attachNewBufferToAgent(Agent *newAgent) {
|
||||||
if (newAgent->getLinkedData() == NULL) {
|
if (newAgent->getLinkedData() == NULL) {
|
||||||
newAgent->setLinkedData(new AudioRingBuffer(RING_BUFFER_SAMPLES, BUFFER_LENGTH_SAMPLES_PER_CHANNEL));
|
newAgent->setLinkedData(new AudioRingBuffer(RING_BUFFER_SAMPLES, BUFFER_LENGTH_SAMPLES_PER_CHANNEL));
|
||||||
|
@ -273,26 +246,7 @@ int main(int argc, const char * argv[])
|
||||||
agentList.linkedDataCreateCallback = attachNewBufferToAgent;
|
agentList.linkedDataCreateCallback = attachNewBufferToAgent;
|
||||||
|
|
||||||
agentList.startSilentAgentRemovalThread();
|
agentList.startSilentAgentRemovalThread();
|
||||||
|
agentList.startDomainServerCheckInThread();
|
||||||
// Lookup the IP address of things we have hostnames
|
|
||||||
if (atoi(DOMAIN_IP) == 0) {
|
|
||||||
struct hostent* pHostInfo;
|
|
||||||
if ((pHostInfo = gethostbyname(DOMAIN_HOSTNAME)) != NULL) {
|
|
||||||
sockaddr_in tempAddress;
|
|
||||||
memcpy(&tempAddress.sin_addr, pHostInfo->h_addr_list[0], pHostInfo->h_length);
|
|
||||||
strcpy(DOMAIN_IP, inet_ntoa(tempAddress.sin_addr));
|
|
||||||
printf("Domain server %s: %s\n", DOMAIN_HOSTNAME, DOMAIN_IP);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
printf("Failed lookup domainserver\n");
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
printf("Using static domainserver IP: %s\n", DOMAIN_IP);
|
|
||||||
}
|
|
||||||
|
|
||||||
// setup the agentSocket to report to domain server
|
|
||||||
pthread_t reportAliveThread;
|
|
||||||
pthread_create(&reportAliveThread, NULL, reportAliveToDS, NULL);
|
|
||||||
|
|
||||||
unsigned char *packetData = new unsigned char[MAX_PACKET_SIZE];
|
unsigned char *packetData = new unsigned char[MAX_PACKET_SIZE];
|
||||||
|
|
||||||
|
@ -332,7 +286,11 @@ int main(int argc, const char * argv[])
|
||||||
|
|
||||||
// add or update the existing interface agent
|
// add or update the existing interface agent
|
||||||
if (!LOOPBACK_SANITY_CHECK) {
|
if (!LOOPBACK_SANITY_CHECK) {
|
||||||
agentList.addOrUpdateAgent(agentAddress, agentAddress, packetData[0]);
|
|
||||||
|
if (agentList.addOrUpdateAgent(agentAddress, agentAddress, packetData[0], agentList.getLastAgentId())) {
|
||||||
|
agentList.increaseAgentId();
|
||||||
|
}
|
||||||
|
|
||||||
agentList.updateAgentWithData(agentAddress, (void *)packetData, receivedBytes);
|
agentList.updateAgentWithData(agentAddress, (void *)packetData, receivedBytes);
|
||||||
} else {
|
} else {
|
||||||
memcpy(loopbackAudioPacket, packetData + 1 + (sizeof(float) * 4), 1024);
|
memcpy(loopbackAudioPacket, packetData + 1 + (sizeof(float) * 4), 1024);
|
||||||
|
@ -342,8 +300,6 @@ int main(int argc, const char * argv[])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
agentList.stopSilentAgentRemovalThread();
|
|
||||||
pthread_join(reportAliveThread, NULL);
|
|
||||||
pthread_join(sendBufferThread, NULL);
|
pthread_join(sendBufferThread, NULL);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
|
|
||||||
Agent::Agent() {}
|
Agent::Agent() {}
|
||||||
|
|
||||||
Agent::Agent(sockaddr *agentPublicSocket, sockaddr *agentLocalSocket, char agentType) {
|
Agent::Agent(sockaddr *agentPublicSocket, sockaddr *agentLocalSocket, char agentType, uint16_t thisAgentId) {
|
||||||
publicSocket = new sockaddr;
|
publicSocket = new sockaddr;
|
||||||
memcpy(publicSocket, agentPublicSocket, sizeof(sockaddr));
|
memcpy(publicSocket, agentPublicSocket, sizeof(sockaddr));
|
||||||
|
|
||||||
|
@ -27,6 +27,7 @@ Agent::Agent(sockaddr *agentPublicSocket, sockaddr *agentLocalSocket, char agent
|
||||||
memcpy(localSocket, agentLocalSocket, sizeof(sockaddr));
|
memcpy(localSocket, agentLocalSocket, sizeof(sockaddr));
|
||||||
|
|
||||||
type = agentType;
|
type = agentType;
|
||||||
|
agentId = thisAgentId;
|
||||||
|
|
||||||
firstRecvTimeUsecs = usecTimestampNow();
|
firstRecvTimeUsecs = usecTimestampNow();
|
||||||
lastRecvTimeUsecs = usecTimestampNow();
|
lastRecvTimeUsecs = usecTimestampNow();
|
||||||
|
@ -42,6 +43,8 @@ Agent::Agent(const Agent &otherAgent) {
|
||||||
localSocket = new sockaddr;
|
localSocket = new sockaddr;
|
||||||
memcpy(localSocket, otherAgent.localSocket, sizeof(sockaddr));
|
memcpy(localSocket, otherAgent.localSocket, sizeof(sockaddr));
|
||||||
|
|
||||||
|
agentId = otherAgent.agentId;
|
||||||
|
|
||||||
if (otherAgent.activeSocket == otherAgent.publicSocket) {
|
if (otherAgent.activeSocket == otherAgent.publicSocket) {
|
||||||
activeSocket = publicSocket;
|
activeSocket = publicSocket;
|
||||||
} else if (otherAgent.activeSocket == otherAgent.localSocket) {
|
} else if (otherAgent.activeSocket == otherAgent.localSocket) {
|
||||||
|
@ -80,6 +83,14 @@ void Agent::setType(char newType) {
|
||||||
type = newType;
|
type = newType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint16_t Agent::getAgentId() {
|
||||||
|
return agentId;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Agent::setAgentId(uint16_t thisAgentId) {
|
||||||
|
agentId = thisAgentId;
|
||||||
|
}
|
||||||
|
|
||||||
double Agent::getFirstRecvTimeUsecs() {
|
double Agent::getFirstRecvTimeUsecs() {
|
||||||
return firstRecvTimeUsecs;
|
return firstRecvTimeUsecs;
|
||||||
}
|
}
|
||||||
|
@ -144,6 +155,7 @@ void Agent::swap(Agent &first, Agent &second) {
|
||||||
swap(first.activeSocket, second.activeSocket);
|
swap(first.activeSocket, second.activeSocket);
|
||||||
swap(first.type, second.type);
|
swap(first.type, second.type);
|
||||||
swap(first.linkedData, second.linkedData);
|
swap(first.linkedData, second.linkedData);
|
||||||
|
swap(first.agentId, second.agentId);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Agent::matches(sockaddr *otherPublicSocket, sockaddr *otherLocalSocket, char otherAgentType) {
|
bool Agent::matches(sockaddr *otherPublicSocket, sockaddr *otherLocalSocket, char otherAgentType) {
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
#define __hifi__Agent__
|
#define __hifi__Agent__
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <stdint.h>
|
||||||
#include "AgentData.h"
|
#include "AgentData.h"
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
|
@ -21,7 +22,7 @@
|
||||||
class Agent {
|
class Agent {
|
||||||
public:
|
public:
|
||||||
Agent();
|
Agent();
|
||||||
Agent(sockaddr *agentPublicSocket, sockaddr *agentLocalSocket, char agentType);
|
Agent(sockaddr *agentPublicSocket, sockaddr *agentLocalSocket, char agentType, uint16_t thisAgentId);
|
||||||
Agent(const Agent &otherAgent);
|
Agent(const Agent &otherAgent);
|
||||||
~Agent();
|
~Agent();
|
||||||
Agent& operator=(Agent otherAgent);
|
Agent& operator=(Agent otherAgent);
|
||||||
|
@ -30,6 +31,8 @@ class Agent {
|
||||||
bool matches(sockaddr *otherPublicSocket, sockaddr *otherLocalSocket, char otherAgentType);
|
bool matches(sockaddr *otherPublicSocket, sockaddr *otherLocalSocket, char otherAgentType);
|
||||||
char getType();
|
char getType();
|
||||||
void setType(char newType);
|
void setType(char newType);
|
||||||
|
uint16_t getAgentId();
|
||||||
|
void setAgentId(uint16_t thisAgentId);
|
||||||
double getFirstRecvTimeUsecs();
|
double getFirstRecvTimeUsecs();
|
||||||
void setFirstRecvTimeUsecs(double newTimeUsecs);
|
void setFirstRecvTimeUsecs(double newTimeUsecs);
|
||||||
double getLastRecvTimeUsecs();
|
double getLastRecvTimeUsecs();
|
||||||
|
@ -49,6 +52,7 @@ class Agent {
|
||||||
void swap(Agent &first, Agent &second);
|
void swap(Agent &first, Agent &second);
|
||||||
sockaddr *publicSocket, *localSocket, *activeSocket;
|
sockaddr *publicSocket, *localSocket, *activeSocket;
|
||||||
char type;
|
char type;
|
||||||
|
uint16_t agentId;
|
||||||
double firstRecvTimeUsecs;
|
double firstRecvTimeUsecs;
|
||||||
double lastRecvTimeUsecs;
|
double lastRecvTimeUsecs;
|
||||||
AgentData *linkedData;
|
AgentData *linkedData;
|
||||||
|
|
|
@ -6,8 +6,10 @@
|
||||||
// Copyright (c) 2013 High Fidelity, Inc. All rights reserved.
|
// Copyright (c) 2013 High Fidelity, Inc. All rights reserved.
|
||||||
//
|
//
|
||||||
|
|
||||||
#include "AgentList.h"
|
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
|
#include <cstring>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include "AgentList.h"
|
||||||
#include "SharedUtil.h"
|
#include "SharedUtil.h"
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
|
@ -17,22 +19,34 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
const char * SOLO_AGENT_TYPES_STRING = "MV";
|
const char * SOLO_AGENT_TYPES_STRING = "MV";
|
||||||
|
char DOMAIN_HOSTNAME[] = "highfidelity.below92.com";
|
||||||
|
char DOMAIN_IP[100] = "192.168.1.47"; // IP Address will be re-set by lookup on startup
|
||||||
|
const int DOMAINSERVER_PORT = 40102;
|
||||||
|
|
||||||
bool stopAgentRemovalThread = false;
|
bool silentAgentThreadStopFlag = false;
|
||||||
|
bool domainServerCheckinStopFlag = false;
|
||||||
pthread_mutex_t vectorChangeMutex = PTHREAD_MUTEX_INITIALIZER;
|
pthread_mutex_t vectorChangeMutex = PTHREAD_MUTEX_INITIALIZER;
|
||||||
|
|
||||||
AgentList::AgentList() : agentSocket(AGENT_SOCKET_LISTEN_PORT) {
|
int unpackAgentId(unsigned char *packedData, uint16_t *agentId) {
|
||||||
linkedDataCreateCallback = NULL;
|
memcpy(packedData, agentId, sizeof(uint16_t));
|
||||||
audioMixerSocketUpdate = NULL;
|
return sizeof(uint16_t);
|
||||||
}
|
}
|
||||||
|
|
||||||
AgentList::AgentList(int socketListenPort) : agentSocket(socketListenPort) {
|
int packAgentId(unsigned char *packStore, uint16_t agentId) {
|
||||||
linkedDataCreateCallback = NULL;
|
memcpy(&agentId, packStore, sizeof(uint16_t));
|
||||||
audioMixerSocketUpdate = NULL;
|
return sizeof(uint16_t);
|
||||||
|
}
|
||||||
|
|
||||||
|
AgentList::AgentList(char newOwnerType, unsigned int newSocketListenPort) : agentSocket(newSocketListenPort) {
|
||||||
|
ownerType = newOwnerType;
|
||||||
|
socketListenPort = newSocketListenPort;
|
||||||
|
lastAgentId = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
AgentList::~AgentList() {
|
AgentList::~AgentList() {
|
||||||
|
// stop the spawned threads, if they were started
|
||||||
stopSilentAgentRemovalThread();
|
stopSilentAgentRemovalThread();
|
||||||
|
stopDomainServerCheckInThread();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<Agent>& AgentList::getAgents() {
|
std::vector<Agent>& AgentList::getAgents() {
|
||||||
|
@ -43,6 +57,14 @@ UDPSocket& AgentList::getAgentSocket() {
|
||||||
return agentSocket;
|
return agentSocket;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char AgentList::getOwnerType() {
|
||||||
|
return ownerType;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int AgentList::getSocketListenPort() {
|
||||||
|
return socketListenPort;
|
||||||
|
}
|
||||||
|
|
||||||
void AgentList::processAgentData(sockaddr *senderAddress, void *packetData, size_t dataBytes) {
|
void AgentList::processAgentData(sockaddr *senderAddress, void *packetData, size_t dataBytes) {
|
||||||
switch (((char *)packetData)[0]) {
|
switch (((char *)packetData)[0]) {
|
||||||
case 'D':
|
case 'D':
|
||||||
|
@ -105,10 +127,19 @@ int AgentList::indexOfMatchingAgent(sockaddr *senderAddress) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint16_t AgentList::getLastAgentId() {
|
||||||
|
return lastAgentId;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AgentList::increaseAgentId() {
|
||||||
|
++lastAgentId;
|
||||||
|
}
|
||||||
|
|
||||||
int AgentList::updateList(unsigned char *packetData, size_t dataBytes) {
|
int AgentList::updateList(unsigned char *packetData, size_t dataBytes) {
|
||||||
int readAgents = 0;
|
int readAgents = 0;
|
||||||
|
|
||||||
char agentType;
|
char agentType;
|
||||||
|
uint16_t agentId;
|
||||||
|
|
||||||
// assumes only IPv4 addresses
|
// assumes only IPv4 addresses
|
||||||
sockaddr_in agentPublicSocket;
|
sockaddr_in agentPublicSocket;
|
||||||
|
@ -121,19 +152,20 @@ int AgentList::updateList(unsigned char *packetData, size_t dataBytes) {
|
||||||
|
|
||||||
while((readPtr - startPtr) < dataBytes) {
|
while((readPtr - startPtr) < dataBytes) {
|
||||||
agentType = *readPtr++;
|
agentType = *readPtr++;
|
||||||
|
readPtr += unpackAgentId(readPtr, (uint16_t *)&agentId);
|
||||||
readPtr += unpackSocket(readPtr, (sockaddr *)&agentPublicSocket);
|
readPtr += unpackSocket(readPtr, (sockaddr *)&agentPublicSocket);
|
||||||
readPtr += unpackSocket(readPtr, (sockaddr *)&agentLocalSocket);
|
readPtr += unpackSocket(readPtr, (sockaddr *)&agentLocalSocket);
|
||||||
|
|
||||||
addOrUpdateAgent((sockaddr *)&agentPublicSocket, (sockaddr *)&agentLocalSocket, agentType);
|
addOrUpdateAgent((sockaddr *)&agentPublicSocket, (sockaddr *)&agentLocalSocket, agentType, agentId);
|
||||||
}
|
}
|
||||||
|
|
||||||
return readAgents;
|
return readAgents;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AgentList::addOrUpdateAgent(sockaddr *publicSocket, sockaddr *localSocket, char agentType) {
|
bool AgentList::addOrUpdateAgent(sockaddr *publicSocket, sockaddr *localSocket, char agentType, uint16_t agentId) {
|
||||||
std::vector<Agent>::iterator agent;
|
std::vector<Agent>::iterator agent;
|
||||||
|
|
||||||
for(agent = agents.begin(); agent != agents.end(); agent++) {
|
for (agent = agents.begin(); agent != agents.end(); agent++) {
|
||||||
if (agent->matches(publicSocket, localSocket, agentType)) {
|
if (agent->matches(publicSocket, localSocket, agentType)) {
|
||||||
// we already have this agent, stop checking
|
// we already have this agent, stop checking
|
||||||
break;
|
break;
|
||||||
|
@ -142,7 +174,8 @@ bool AgentList::addOrUpdateAgent(sockaddr *publicSocket, sockaddr *localSocket,
|
||||||
|
|
||||||
if (agent == agents.end()) {
|
if (agent == agents.end()) {
|
||||||
// we didn't have this agent, so add them
|
// we didn't have this agent, so add them
|
||||||
Agent newAgent = Agent(publicSocket, localSocket, agentType);
|
|
||||||
|
Agent newAgent = Agent(publicSocket, localSocket, agentType, agentId);
|
||||||
|
|
||||||
if (socketMatch(publicSocket, localSocket)) {
|
if (socketMatch(publicSocket, localSocket)) {
|
||||||
// likely debugging scenario with DS + agent on local network
|
// likely debugging scenario with DS + agent on local network
|
||||||
|
@ -154,10 +187,10 @@ bool AgentList::addOrUpdateAgent(sockaddr *publicSocket, sockaddr *localSocket,
|
||||||
// this is an audio mixer
|
// this is an audio mixer
|
||||||
// for now that means we need to tell the audio class
|
// for now that means we need to tell the audio class
|
||||||
// to use the local socket information the domain server gave us
|
// to use the local socket information the domain server gave us
|
||||||
sockaddr_in *localSocketIn = (sockaddr_in *)localSocket;
|
sockaddr_in *publicSocketIn = (sockaddr_in *)publicSocket;
|
||||||
audioMixerSocketUpdate(localSocketIn->sin_addr.s_addr, localSocketIn->sin_port);
|
audioMixerSocketUpdate(publicSocketIn->sin_addr.s_addr, publicSocketIn->sin_port);
|
||||||
} else if (newAgent.getType() == 'V') {
|
} else if (newAgent.getType() == 'V') {
|
||||||
newAgent.activateLocalSocket();
|
newAgent.activatePublicSocket();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::cout << "Added agent - " << &newAgent << "\n";
|
std::cout << "Added agent - " << &newAgent << "\n";
|
||||||
|
@ -227,7 +260,7 @@ void *removeSilentAgents(void *args) {
|
||||||
std::vector<Agent> *agents = (std::vector<Agent> *)args;
|
std::vector<Agent> *agents = (std::vector<Agent> *)args;
|
||||||
double checkTimeUSecs, sleepTime;
|
double checkTimeUSecs, sleepTime;
|
||||||
|
|
||||||
while (!stopAgentRemovalThread) {
|
while (!silentAgentThreadStopFlag) {
|
||||||
checkTimeUSecs = usecTimestampNow();
|
checkTimeUSecs = usecTimestampNow();
|
||||||
|
|
||||||
for(std::vector<Agent>::iterator agent = agents->begin(); agent != agents->end();) {
|
for(std::vector<Agent>::iterator agent = agents->begin(); agent != agents->end();) {
|
||||||
|
@ -259,6 +292,58 @@ void AgentList::startSilentAgentRemovalThread() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void AgentList::stopSilentAgentRemovalThread() {
|
void AgentList::stopSilentAgentRemovalThread() {
|
||||||
stopAgentRemovalThread = true;
|
silentAgentThreadStopFlag = true;
|
||||||
pthread_join(removeSilentAgentsThread, NULL);
|
pthread_join(removeSilentAgentsThread, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
void *checkInWithDomainServer(void *args) {
|
||||||
|
|
||||||
|
AgentList *parentAgentList = (AgentList *)args;
|
||||||
|
|
||||||
|
timeval lastSend;
|
||||||
|
unsigned char output[7];
|
||||||
|
|
||||||
|
in_addr_t localAddress = getLocalAddress();
|
||||||
|
|
||||||
|
// Lookup the IP address of the domain server if we need to
|
||||||
|
if (atoi(DOMAIN_IP) == 0) {
|
||||||
|
struct hostent* pHostInfo;
|
||||||
|
if ((pHostInfo = gethostbyname(DOMAIN_HOSTNAME)) != NULL) {
|
||||||
|
sockaddr_in tempAddress;
|
||||||
|
memcpy(&tempAddress.sin_addr, pHostInfo->h_addr_list[0], pHostInfo->h_length);
|
||||||
|
strcpy(DOMAIN_IP, inet_ntoa(tempAddress.sin_addr));
|
||||||
|
printf("Domain server %s: %s\n", DOMAIN_HOSTNAME, DOMAIN_IP);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
printf("Failed lookup domainserver\n");
|
||||||
|
}
|
||||||
|
} else printf("Using static domainserver IP: %s\n", DOMAIN_IP);
|
||||||
|
|
||||||
|
|
||||||
|
while (!domainServerCheckinStopFlag) {
|
||||||
|
gettimeofday(&lastSend, NULL);
|
||||||
|
|
||||||
|
output[0] = parentAgentList->getOwnerType();
|
||||||
|
packSocket(output + 1, localAddress, htons(parentAgentList->getSocketListenPort()));
|
||||||
|
|
||||||
|
parentAgentList->getAgentSocket().send(DOMAIN_IP, DOMAINSERVER_PORT, output, 7);
|
||||||
|
|
||||||
|
double usecToSleep = 1000000 - (usecTimestampNow() - usecTimestamp(&lastSend));
|
||||||
|
|
||||||
|
if (usecToSleep > 0) {
|
||||||
|
usleep(usecToSleep);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pthread_exit(0);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AgentList::startDomainServerCheckInThread() {
|
||||||
|
pthread_create(&checkInWithDomainServerThread, NULL, checkInWithDomainServer, (void *)this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AgentList::stopDomainServerCheckInThread() {
|
||||||
|
domainServerCheckinStopFlag = true;
|
||||||
|
pthread_join(checkInWithDomainServerThread, NULL);
|
||||||
}
|
}
|
|
@ -11,6 +11,7 @@
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <stdint.h>
|
||||||
#include "Agent.h"
|
#include "Agent.h"
|
||||||
#include "UDPSocket.h"
|
#include "UDPSocket.h"
|
||||||
|
|
||||||
|
@ -19,38 +20,55 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
const int MAX_PACKET_SIZE = 1500;
|
const int MAX_PACKET_SIZE = 1500;
|
||||||
const unsigned short AGENT_SOCKET_LISTEN_PORT = 40103;
|
const unsigned int AGENT_SOCKET_LISTEN_PORT = 40103;
|
||||||
const int AGENT_SILENCE_THRESHOLD_USECS = 2 * 1000000;
|
const int AGENT_SILENCE_THRESHOLD_USECS = 2 * 1000000;
|
||||||
extern const char *SOLO_AGENT_TYPES_STRING;
|
extern const char *SOLO_AGENT_TYPES_STRING;
|
||||||
|
|
||||||
|
extern char DOMAIN_HOSTNAME[];
|
||||||
|
extern char DOMAIN_IP[100]; // IP Address will be re-set by lookup on startup
|
||||||
|
extern const int DOMAINSERVER_PORT;
|
||||||
|
|
||||||
class AgentList {
|
class AgentList {
|
||||||
public:
|
|
||||||
AgentList();
|
|
||||||
AgentList(int socketListenPort);
|
|
||||||
~AgentList();
|
|
||||||
|
|
||||||
void(*linkedDataCreateCallback)(Agent *);
|
|
||||||
void(*audioMixerSocketUpdate)(in_addr_t, in_port_t);
|
|
||||||
|
|
||||||
std::vector<Agent>& getAgents();
|
UDPSocket agentSocket;
|
||||||
UDPSocket& getAgentSocket();
|
char ownerType;
|
||||||
|
unsigned int socketListenPort;
|
||||||
|
std::vector<Agent> agents;
|
||||||
|
uint16_t lastAgentId;
|
||||||
|
pthread_t removeSilentAgentsThread;
|
||||||
|
pthread_t checkInWithDomainServerThread;
|
||||||
|
|
||||||
int updateList(unsigned char *packetData, size_t dataBytes);
|
void handlePingReply(sockaddr *agentAddress);
|
||||||
int indexOfMatchingAgent(sockaddr *senderAddress);
|
public:
|
||||||
bool addOrUpdateAgent(sockaddr *publicSocket, sockaddr *localSocket, char agentType);
|
AgentList(char ownerType, unsigned int socketListenPort = AGENT_SOCKET_LISTEN_PORT);
|
||||||
void processAgentData(sockaddr *senderAddress, void *packetData, size_t dataBytes);
|
~AgentList();
|
||||||
void updateAgentWithData(sockaddr *senderAddress, void *packetData, size_t dataBytes);
|
|
||||||
void broadcastToAgents(char *broadcastData, size_t dataBytes);
|
void(*linkedDataCreateCallback)(Agent *);
|
||||||
void sendToAgent(Agent *destAgent, void *packetData, size_t dataBytes);
|
void(*audioMixerSocketUpdate)(in_addr_t, in_port_t);
|
||||||
void pingAgents();
|
|
||||||
void startSilentAgentRemovalThread();
|
std::vector<Agent>& getAgents();
|
||||||
void stopSilentAgentRemovalThread();
|
UDPSocket& getAgentSocket();
|
||||||
private:
|
|
||||||
UDPSocket agentSocket;
|
int updateList(unsigned char *packetData, size_t dataBytes);
|
||||||
std::vector<Agent> agents;
|
int indexOfMatchingAgent(sockaddr *senderAddress);
|
||||||
pthread_t removeSilentAgentsThread;
|
uint16_t getLastAgentId();
|
||||||
|
void increaseAgentId();
|
||||||
void handlePingReply(sockaddr *agentAddress);
|
bool addOrUpdateAgent(sockaddr *publicSocket, sockaddr *localSocket, char agentType, uint16_t agentId);
|
||||||
|
void processAgentData(sockaddr *senderAddress, void *packetData, size_t dataBytes);
|
||||||
|
void updateAgentWithData(sockaddr *senderAddress, void *packetData, size_t dataBytes);
|
||||||
|
void broadcastToAgents(char *broadcastData, size_t dataBytes);
|
||||||
|
void sendToAgent(Agent *destAgent, void *packetData, size_t dataBytes);
|
||||||
|
void pingAgents();
|
||||||
|
char getOwnerType();
|
||||||
|
unsigned int getSocketListenPort();
|
||||||
|
|
||||||
|
void startSilentAgentRemovalThread();
|
||||||
|
void stopSilentAgentRemovalThread();
|
||||||
|
void startDomainServerCheckInThread();
|
||||||
|
void stopDomainServerCheckInThread();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
int unpackAgentId(unsigned char *packedData, uint16_t *agentId);
|
||||||
|
int packAgentId(unsigned char *packStore, uint16_t agentId);
|
||||||
|
|
||||||
#endif /* defined(__hifi__AgentList__) */
|
#endif /* defined(__hifi__AgentList__) */
|
||||||
|
|
|
@ -89,6 +89,14 @@ void AudioRingBuffer::setPosition(float *newPosition) {
|
||||||
position[2] = newPosition[2];
|
position[2] = newPosition[2];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float AudioRingBuffer::getAttenuationRatio() {
|
||||||
|
return attenuationRatio;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AudioRingBuffer::setAttenuationRatio(float newAttenuation) {
|
||||||
|
attenuationRatio = newAttenuation;
|
||||||
|
}
|
||||||
|
|
||||||
float AudioRingBuffer::getBearing() {
|
float AudioRingBuffer::getBearing() {
|
||||||
return bearing;
|
return bearing;
|
||||||
}
|
}
|
||||||
|
@ -109,6 +117,9 @@ void AudioRingBuffer::parseData(void *data, int size) {
|
||||||
dataPtr += sizeof(float);
|
dataPtr += sizeof(float);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned int attenuationByte = *(dataPtr++);
|
||||||
|
attenuationRatio = attenuationByte / 255.0f;
|
||||||
|
|
||||||
memcpy(&bearing, dataPtr, sizeof(float));
|
memcpy(&bearing, dataPtr, sizeof(float));
|
||||||
dataPtr += sizeof(float);
|
dataPtr += sizeof(float);
|
||||||
|
|
||||||
|
|
|
@ -33,6 +33,8 @@ class AudioRingBuffer : public AgentData {
|
||||||
void setAddedToMix(bool added);
|
void setAddedToMix(bool added);
|
||||||
float* getPosition();
|
float* getPosition();
|
||||||
void setPosition(float newPosition[]);
|
void setPosition(float newPosition[]);
|
||||||
|
float getAttenuationRatio();
|
||||||
|
void setAttenuationRatio(float newAttenuation);
|
||||||
float getBearing();
|
float getBearing();
|
||||||
void setBearing(float newBearing);
|
void setBearing(float newBearing);
|
||||||
|
|
||||||
|
@ -41,6 +43,7 @@ class AudioRingBuffer : public AgentData {
|
||||||
int ringBufferLengthSamples;
|
int ringBufferLengthSamples;
|
||||||
int bufferLengthSamples;
|
int bufferLengthSamples;
|
||||||
float position[3];
|
float position[3];
|
||||||
|
float attenuationRatio;
|
||||||
float bearing;
|
float bearing;
|
||||||
int16_t *nextOutput;
|
int16_t *nextOutput;
|
||||||
int16_t *endOfLastWrite;
|
int16_t *endOfLastWrite;
|
||||||
|
|
|
@ -35,7 +35,6 @@ void switchToResourcesIfRequired();
|
||||||
|
|
||||||
char* getCmdOption(int argc, char** argv,char* option);
|
char* getCmdOption(int argc, char** argv,char* option);
|
||||||
bool cmdOptionExists(int argc, char** argv,char* option);
|
bool cmdOptionExists(int argc, char** argv,char* option);
|
||||||
|
|
||||||
unsigned char* pointToVoxel(float x, float y, float z, float s, unsigned char r, unsigned char g, unsigned char b );
|
unsigned char* pointToVoxel(float x, float y, float z, float s, unsigned char r, unsigned char g, unsigned char b );
|
||||||
|
|
||||||
#endif /* defined(__hifi__SharedUtil__) */
|
#endif /* defined(__hifi__SharedUtil__) */
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
#else
|
#else
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <arpa/inet.h>
|
#include <arpa/inet.h>
|
||||||
|
#include <ifaddrs.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
sockaddr_in destSockaddr, senderAddress;
|
sockaddr_in destSockaddr, senderAddress;
|
||||||
|
@ -64,6 +65,28 @@ int unpackSocket(unsigned char *packedData, sockaddr *unpackDestSocket) {
|
||||||
return 6; // this could be more if we ever need IPv6
|
return 6; // this could be more if we ever need IPv6
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int getLocalAddress() {
|
||||||
|
// get this agent's local address so we can pass that to DS
|
||||||
|
struct ifaddrs * ifAddrStruct = NULL;
|
||||||
|
struct ifaddrs * ifa = NULL;
|
||||||
|
|
||||||
|
int family;
|
||||||
|
int localAddress = 0;
|
||||||
|
|
||||||
|
getifaddrs(&ifAddrStruct);
|
||||||
|
|
||||||
|
for (ifa = ifAddrStruct; ifa != NULL; ifa = ifa->ifa_next) {
|
||||||
|
family = ifa->ifa_addr->sa_family;
|
||||||
|
if (family == AF_INET) {
|
||||||
|
localAddress = ((sockaddr_in *)ifa->ifa_addr)->sin_addr.s_addr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
freeifaddrs(ifAddrStruct);
|
||||||
|
|
||||||
|
return localAddress;
|
||||||
|
}
|
||||||
|
|
||||||
UDPSocket::UDPSocket(int listeningPort) {
|
UDPSocket::UDPSocket(int listeningPort) {
|
||||||
// create the socket
|
// create the socket
|
||||||
handle = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
handle = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
||||||
|
|
|
@ -36,5 +36,6 @@ bool socketMatch(sockaddr *first, sockaddr *second);
|
||||||
int packSocket(unsigned char *packStore, in_addr_t inAddress, in_port_t networkOrderPort);
|
int packSocket(unsigned char *packStore, in_addr_t inAddress, in_port_t networkOrderPort);
|
||||||
int packSocket(unsigned char *packStore, sockaddr *socketToPack);
|
int packSocket(unsigned char *packStore, sockaddr *socketToPack);
|
||||||
int unpackSocket(unsigned char *packedData, sockaddr *unpackDestSocket);
|
int unpackSocket(unsigned char *packedData, sockaddr *unpackDestSocket);
|
||||||
|
int getLocalAddress();
|
||||||
|
|
||||||
#endif /* defined(__interface__UDPSocket__) */
|
#endif /* defined(__interface__UDPSocket__) */
|
||||||
|
|
|
@ -39,41 +39,9 @@ const int MIN_BRIGHTNESS = 64;
|
||||||
const float DEATH_STAR_RADIUS = 4.0;
|
const float DEATH_STAR_RADIUS = 4.0;
|
||||||
const float MAX_CUBE = 0.05f;
|
const float MAX_CUBE = 0.05f;
|
||||||
|
|
||||||
char DOMAIN_HOSTNAME[] = "highfidelity.below92.com";
|
|
||||||
char DOMAIN_IP[100] = ""; // IP Address will be re-set by lookup on startup
|
|
||||||
const int DOMAINSERVER_PORT = 40102;
|
|
||||||
|
|
||||||
const int MAX_VOXEL_TREE_DEPTH_LEVELS = 10;
|
const int MAX_VOXEL_TREE_DEPTH_LEVELS = 10;
|
||||||
|
|
||||||
AgentList agentList(VOXEL_LISTEN_PORT);
|
AgentList agentList('V', VOXEL_LISTEN_PORT);
|
||||||
in_addr_t localAddress;
|
|
||||||
|
|
||||||
void *reportAliveToDS(void *args) {
|
|
||||||
|
|
||||||
timeval lastSend;
|
|
||||||
unsigned char output[7];
|
|
||||||
|
|
||||||
while (true) {
|
|
||||||
gettimeofday(&lastSend, NULL);
|
|
||||||
|
|
||||||
*output = 'V';
|
|
||||||
packSocket(output + 1, 895283510, htons(VOXEL_LISTEN_PORT));
|
|
||||||
// packSocket(output + 1, 788637888, htons(VOXEL_LISTEN_PORT));
|
|
||||||
agentList.getAgentSocket().send(DOMAIN_IP, DOMAINSERVER_PORT, output, 7);
|
|
||||||
|
|
||||||
double usecToSleep = 1000000 - (usecTimestampNow() - usecTimestamp(&lastSend));
|
|
||||||
|
|
||||||
if (usecToSleep > 0) {
|
|
||||||
#ifdef _WIN32
|
|
||||||
Sleep( static_cast<int>(1000.0f*usecToSleep) );
|
|
||||||
#else
|
|
||||||
usleep(usecToSleep);
|
|
||||||
#endif
|
|
||||||
} else {
|
|
||||||
std::cout << "No sleep required!";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int randomlyFillVoxelTree(int levelsToGo, VoxelNode *currentRootNode) {
|
int randomlyFillVoxelTree(int levelsToGo, VoxelNode *currentRootNode) {
|
||||||
// randomly generate children for this node
|
// randomly generate children for this node
|
||||||
|
@ -142,43 +110,9 @@ int main(int argc, const char * argv[])
|
||||||
{
|
{
|
||||||
setvbuf(stdout, NULL, _IOLBF, 0);
|
setvbuf(stdout, NULL, _IOLBF, 0);
|
||||||
|
|
||||||
#ifndef _WIN32
|
|
||||||
// get the local address of the voxel server
|
|
||||||
struct ifaddrs * ifAddrStruct=NULL;
|
|
||||||
struct ifaddrs * ifa=NULL;
|
|
||||||
|
|
||||||
getifaddrs(&ifAddrStruct);
|
|
||||||
|
|
||||||
for (ifa = ifAddrStruct; ifa != NULL; ifa = ifa->ifa_next) {
|
|
||||||
if (ifa ->ifa_addr->sa_family==AF_INET) { // check it is IP4
|
|
||||||
// is a valid IP4 Address
|
|
||||||
localAddress = ((struct sockaddr_in *)ifa->ifa_addr)->sin_addr.s_addr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Lookup the IP address of things we have hostnames
|
|
||||||
if (atoi(DOMAIN_IP) == 0) {
|
|
||||||
struct hostent* pHostInfo;
|
|
||||||
if ((pHostInfo = gethostbyname(DOMAIN_HOSTNAME)) != NULL) {
|
|
||||||
sockaddr_in tempAddress;
|
|
||||||
memcpy(&tempAddress.sin_addr, pHostInfo->h_addr_list[0], pHostInfo->h_length);
|
|
||||||
strcpy(DOMAIN_IP, inet_ntoa(tempAddress.sin_addr));
|
|
||||||
printf("Domain server %s: %s\n", DOMAIN_HOSTNAME, DOMAIN_IP);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
printf("Failed lookup domainserver\n");
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
printf("Using static domainserver IP: %s\n", DOMAIN_IP);
|
|
||||||
}
|
|
||||||
|
|
||||||
// setup the agentSocket to report to domain server
|
|
||||||
pthread_t reportAliveThread;
|
|
||||||
pthread_create(&reportAliveThread, NULL, reportAliveToDS, NULL);
|
|
||||||
|
|
||||||
agentList.linkedDataCreateCallback = &attachVoxelAgentDataToAgent;
|
agentList.linkedDataCreateCallback = &attachVoxelAgentDataToAgent;
|
||||||
agentList.startSilentAgentRemovalThread();
|
agentList.startSilentAgentRemovalThread();
|
||||||
|
agentList.startDomainServerCheckInThread();
|
||||||
|
|
||||||
srand((unsigned)time(0));
|
srand((unsigned)time(0));
|
||||||
|
|
||||||
|
@ -205,7 +139,11 @@ int main(int argc, const char * argv[])
|
||||||
while (true) {
|
while (true) {
|
||||||
if (agentList.getAgentSocket().receive(&agentPublicAddress, packetData, &receivedBytes)) {
|
if (agentList.getAgentSocket().receive(&agentPublicAddress, packetData, &receivedBytes)) {
|
||||||
if (packetData[0] == 'H') {
|
if (packetData[0] == 'H') {
|
||||||
agentList.addOrUpdateAgent(&agentPublicAddress, &agentPublicAddress, packetData[0]);
|
|
||||||
|
if (agentList.addOrUpdateAgent(&agentPublicAddress, &agentPublicAddress, packetData[0], agentList.getLastAgentId())) {
|
||||||
|
agentList.increaseAgentId();
|
||||||
|
}
|
||||||
|
|
||||||
agentList.updateAgentWithData(&agentPublicAddress, (void *)packetData, receivedBytes);
|
agentList.updateAgentWithData(&agentPublicAddress, (void *)packetData, receivedBytes);
|
||||||
|
|
||||||
VoxelAgentData *agentData = (VoxelAgentData *) agentList.getAgents()[agentList.indexOfMatchingAgent(&agentPublicAddress)].getLinkedData();
|
VoxelAgentData *agentData = (VoxelAgentData *) agentList.getAgents()[agentList.indexOfMatchingAgent(&agentPublicAddress)].getLinkedData();
|
||||||
|
@ -245,8 +183,5 @@ int main(int argc, const char * argv[])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pthread_join(reportAliveThread, NULL);
|
|
||||||
agentList.stopSilentAgentRemovalThread();
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
Loading…
Reference in a new issue