Merge remote-tracking branch 'origin'

This commit is contained in:
Philip Rosedale 2013-03-12 10:49:33 -07:00
commit ccd60fa07f
15 changed files with 269 additions and 107 deletions

View file

@ -1,4 +1,17 @@
interface
=========
Test platform for various render and interface tests for next-gen VR system
Test platform for various render and interface tests for next-gen VR system.
CMake
=====
This project uses CMake to generate build files and project files for your platform.
Create a build directory in the root of your checkout and then run the CMake build from there. This will keep the rest of the directory clean, and makes the gitignore a little easier to handle (since we can just ignore build).
mkdir build
cd build
cmake .. -GXCode
Those are the commands used on OS X to run CMake from the build folder and generate XCode project files.

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

View file

@ -12,10 +12,11 @@
#include <sys/time.h>
#include <sys/stat.h>
#include <cstring>
#include <SharedUtil.h>
#include <StdDev.h>
#include <UDPSocket.h>
#include "Audio.h"
#include "Util.h"
#include <SharedUtil.h>
#include "UDPSocket.h"
Oscilloscope * scope;

View file

@ -33,7 +33,6 @@ public:
bool terminate();
private:
bool initialized;
AudioData *audioData;
// protects constructor so that public init method is used

View file

@ -27,6 +27,25 @@ Hand::Hand(glm::vec3 initcolor)
renderPointer = true;
}
Hand::Hand(const Hand &otherHand) {
color = otherHand.color;
noise = otherHand.noise;
scale = otherHand.scale;
position = otherHand.position;
target = otherHand.target;
velocity = otherHand.color;
pitch = otherHand.pitch;
yaw = otherHand.yaw;
roll = otherHand.roll;
pitchRate = otherHand.pitchRate;
yawRate = otherHand.yawRate;
rollRate = otherHand.rollRate;
transmitterTimer = otherHand.transmitterTimer;
transmitterHz = otherHand.transmitterHz;
transmitterPackets = otherHand.transmitterPackets;
renderPointer = otherHand.renderPointer;
}
void Hand::reset()
{
position.x = DEFAULT_X;

View file

@ -19,6 +19,7 @@
class Hand {
public:
Hand(glm::vec3 color);
Hand(const Hand &otherHand);
void simulate (float deltaTime);
void render (int isMine);
void reset ();

View file

@ -8,10 +8,13 @@
#include <iostream>
#include <glm/glm.hpp>
#include <cstring>
#include "Head.h"
#include "Util.h"
#include "SerialInterface.h"
#include <vector>
#include <lodepng.h>
#include <fstream>
#include <sstream>
using namespace std;
float skinColor[] = {1.0, 0.84, 0.66};
float browColor[] = {210.0/255.0, 105.0/255.0, 30.0/255.0};
@ -28,6 +31,14 @@ float browThickness = 0.16;
const float DECAY = 0.1;
char iris_texture_file[] = "interface.app/Contents/Resources/images/green_eye.png";
vector<unsigned char> iris_texture;
unsigned int iris_texture_width = 512;
unsigned int iris_texture_height = 256;
GLUquadric *sphere = gluNewQuadric();
Head::Head()
{
position.x = position.y = position.z = 0;
@ -61,13 +72,66 @@ Head::Head()
averageLoudness = 0.0;
lastLoudness = 0.0;
browAudioLift = 0.0;
noise = 0;
setNoise(0);
hand = new Hand(glm::vec3(skinColor[0], skinColor[1], skinColor[2]));
if (iris_texture.size() == 0) {
unsigned error = lodepng::decode(iris_texture, iris_texture_width, iris_texture_height, iris_texture_file);
if (error != 0) {
std::cout << "error " << error << ": " << lodepng_error_text(error) << std::endl;
}
}
}
Head::Head(const Head &otherHead) {
position = otherHead.position;
PupilSize = otherHead.PupilSize;
interPupilDistance = otherHead.interPupilDistance;
interBrowDistance = otherHead.interBrowDistance;
NominalPupilSize = otherHead.NominalPupilSize;
Yaw = otherHead.Yaw;
EyebrowPitch[0] = otherHead.EyebrowPitch[0];
EyebrowPitch[1] = otherHead.EyebrowPitch[1];
EyebrowRoll[0] = otherHead.EyebrowRoll[0];
EyebrowRoll[1] = otherHead.EyebrowRoll[1];
MouthPitch = otherHead.MouthPitch;
MouthYaw = otherHead.MouthYaw;
MouthWidth = otherHead.MouthWidth;
MouthHeight = otherHead.MouthHeight;
EyeballPitch[0] = otherHead.EyeballPitch[0];
EyeballPitch[1] = otherHead.EyeballPitch[1];
EyeballScaleX = otherHead.EyeballScaleX;
EyeballScaleY = otherHead.EyeballScaleY;
EyeballScaleZ = otherHead.EyeballScaleZ;
EyeballYaw[0] = otherHead.EyeballYaw[0];
EyeballYaw[1] = otherHead.EyeballYaw[1];
PitchTarget = otherHead.PitchTarget;
YawTarget = otherHead.YawTarget;
NoiseEnvelope = otherHead.NoiseEnvelope;
PupilConverge = otherHead.PupilConverge;
leanForward = otherHead.leanForward;
leanSideways = otherHead.leanSideways;
eyeContact = otherHead.eyeContact;
eyeContactTarget = otherHead.eyeContactTarget;
scale = otherHead.scale;
renderYaw = otherHead.renderYaw;
renderPitch = otherHead.renderPitch;
audioAttack = otherHead.audioAttack;
loudness = otherHead.loudness;
averageLoudness = otherHead.averageLoudness;
lastLoudness = otherHead.lastLoudness;
browAudioLift = otherHead.browAudioLift;
noise = otherHead.noise;
Hand newHand = Hand(*otherHead.hand);
hand = &newHand;
}
Head::~Head() {
// all data is primitive, do nothing
if (sphere) {
gluDeleteQuadric(sphere);
}
}
Head* Head::clone() const {
@ -218,11 +282,11 @@ void Head::simulate(float deltaTime)
{
SetNewHeadTarget((randFloat()-0.5)*20.0, (randFloat()-0.5)*45.0);
}
if (0)
{
// Pick new target
// Pick new target
PitchTarget = (randFloat() - 0.5)*45;
YawTarget = (randFloat() - 0.5)*22;
}
@ -341,14 +405,29 @@ void Head::render(int faceToFace, int isMine, float * myLocation)
glutSolidSphere(0.25, 30, 30);
}
glPopMatrix();
// Right Pupil
if (!sphere) {
sphere = gluNewQuadric();
gluQuadricTexture(sphere, GL_TRUE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
gluQuadricOrientation(sphere, GLU_OUTSIDE);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, iris_texture_width, iris_texture_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, &iris_texture[0]);
}
glPushMatrix();
{
glRotatef(EyeballPitch[1], 1, 0, 0);
glRotatef(EyeballYaw[1] + PupilConverge, 0, 1, 0);
glTranslatef(0,0,.35);
if (!eyeContact) glColor3f(0,0,0); else glColor3f(0.3,0.3,0.3);
//glRotatef(90,0,1,0);
glutSolidSphere(PupilSize, 15, 15);
glRotatef(-75,1,0,0);
glScalef(1.0, 0.4, 1.0);
glEnable(GL_TEXTURE_2D);
gluSphere(sphere, PupilSize, 15, 15);
glDisable(GL_TEXTURE_2D);
}
glPopMatrix();
// Left Eye
@ -364,14 +443,19 @@ void Head::render(int faceToFace, int isMine, float * myLocation)
glPopMatrix();
// Left Pupil
glPushMatrix();
{
glRotatef(EyeballPitch[0], 1, 0, 0);
glRotatef(EyeballYaw[0] - PupilConverge, 0, 1, 0);
glTranslatef(0,0,.35);
if (!eyeContact) glColor3f(0,0,0); else glColor3f(0.3,0.3,0.3);
//glRotatef(90,0,1,0);
glutSolidSphere(PupilSize, 15, 15);
glPopMatrix();
glTranslatef(0, 0, .35);
glRotatef(-75, 1, 0, 0);
glScalef(1.0, 0.4, 1.0);
glEnable(GL_TEXTURE_2D);
gluSphere(sphere, PupilSize, 15, 15);
glDisable(GL_TEXTURE_2D);
}
glPopMatrix();
}
glPopMatrix();

View file

@ -24,6 +24,7 @@ class Head : public AgentData {
public:
Head();
~Head();
Head(const Head &otherHead);
Head* clone() const;
void reset();

View file

@ -9,7 +9,7 @@
#include "Texture.h"
#include "InterfaceConfig.h"
#include <LodePNG/lodepng.h>
#include <lodepng.h>
#include <vector>
#include <cstdio>

View file

@ -13,48 +13,6 @@
#include "world.h"
#include "Util.h"
//
// Standard Deviation Object
//
const int MAX_STDEV_SAMPLES = 1000; // Don't add more than this number of samples.
StDev::StDev() {
data = new float[MAX_STDEV_SAMPLES];
sampleCount = 0;
}
void StDev::reset() {
sampleCount = 0;
}
void StDev::addValue(float v) {
data[sampleCount++] = v;
if (sampleCount == MAX_STDEV_SAMPLES) sampleCount = 0;
}
float StDev::getAverage() {
float average = 0;
for (int i = 0; i < sampleCount; i++) {
average += data[i];
}
if (sampleCount > 0)
return average/(float)sampleCount;
else return 0;
}
float StDev::getStDev() {
float average = getAverage();
float stdev = 0;
for (int i = 0; i < sampleCount; i++) {
stdev += powf(data[i] - average, 2);
}
if (sampleCount > 1)
return sqrt(stdev/(float)(sampleCount - 1.0));
else
return 0;
}
// Return the azimuth angle in degrees between two points.
float azimuth_to(glm::vec3 head_pos, glm::vec3 source_pos) {
return atan2(head_pos.x - source_pos.x, head_pos.z - source_pos.z) * 180 / PI;

View file

@ -24,17 +24,5 @@ void drawvec3(int x, int y, float scale, float rotate, float thick, int mono, gl
float r=1.0, float g=1.0, float b=1.0);
double diffclock(timeval *clock1,timeval *clock2);
class StDev {
public:
StDev();
void reset();
void addValue(float v);
float getAverage();
float getStDev();
int getSamples() {return sampleCount;};
private:
float * data;
int sampleCount;
};
#endif

View file

@ -915,30 +915,6 @@ int main(int argc, char** argv)
printf("Failed lookup domainserver\n");
}
} else printf("Using static domainserver IP: %s\n", DOMAIN_IP);
printf("Testing stats math... ");
StDev stdevtest;
stdevtest.reset();
stdevtest.addValue(1345);
stdevtest.addValue(1301);
stdevtest.addValue(1368);
stdevtest.addValue(1322);
stdevtest.addValue(1310);
stdevtest.addValue(1370);
stdevtest.addValue(1318);
stdevtest.addValue(1350);
stdevtest.addValue(1303);
stdevtest.addValue(1299);
if (stdevtest.getSamples() != 10)
printf("Samples=FAIL ");
if (floor(stdevtest.getAverage()*100.0) != 132859.0)
printf("Average=FAIL ");
if (floor(stdevtest.getStDev()*100.0) != 2746.0)
printf("Stdev=FAIL ");
printf("\n");
// the callback for our instance of AgentList is attachNewHeadToAgent
agentList.linkedDataCreateCallback = &attachNewHeadToAgent;

View file

@ -12,9 +12,10 @@
#include <errno.h>
#include <fstream>
#include <limits>
#include "AudioRingBuffer.h"
#include <AgentList.h>
#include <SharedUtil.h>
#include <StdDev.h>
#include "AudioRingBuffer.h"
const unsigned short MIXER_LISTEN_PORT = 55443;
@ -39,11 +40,14 @@ const int PHASE_DELAY_AT_90 = 20;
const int AGENT_LOOPBACK_MODIFIER = 307;
const int LOOPBACK_SANITY_CHECK = 0;
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;
AgentList agentList(MIXER_LISTEN_PORT);
StDev stdev;
void plateauAdditionOfSamples(int16_t &mixSample, int16_t sampleToAdd) {
long sumSample = sampleToAdd + mixSample;
@ -58,17 +62,13 @@ void *sendBuffer(void *args)
{
int sentBytes;
int nextFrame = 0;
timeval startTime, lastSend;
timeval startTime;
gettimeofday(&startTime, NULL);
gettimeofday(&lastSend, NULL);
while (true) {
sentBytes = 0;
printf("Last send was %f ms ago\n", (usecTimestampNow() - usecTimestamp(&lastSend)) / 1000);
gettimeofday(&lastSend, NULL);
for (int i = 0; i < agentList.getAgents().size(); i++) {
AudioRingBuffer *agentBuffer = (AudioRingBuffer *) agentList.getAgents()[i].getLinkedData();
@ -81,6 +81,22 @@ void *sendBuffer(void *args)
printf("Buffer %d starved.\n", i);
agentBuffer->setStarted(false);
} else {
// check if we have more than we need to play out
int thresholdFrames = ceilf((BUFFER_LENGTH_SAMPLES_PER_CHANNEL + JITTER_BUFFER_SAMPLES) / (float)BUFFER_LENGTH_SAMPLES_PER_CHANNEL);
int thresholdSamples = thresholdFrames * BUFFER_LENGTH_SAMPLES_PER_CHANNEL;
if (agentBuffer->diffLastWriteNextOutput() > thresholdSamples) {
// we need to push the next output forwards
int samplesToPush = agentBuffer->diffLastWriteNextOutput() - thresholdSamples;
if (agentBuffer->getNextOutput() + samplesToPush > agentBuffer->getBuffer()) {
agentBuffer->setNextOutput(agentBuffer->getBuffer() + (samplesToPush - (agentBuffer->getBuffer() + RING_BUFFER_SAMPLES - agentBuffer->getNextOutput())));
} else {
agentBuffer->setNextOutput(agentBuffer->getNextOutput() + samplesToPush);
}
}
// good buffer, add this to the mix
agentBuffer->setStarted(true);
agentBuffer->setAddedToMix(true);
@ -283,14 +299,45 @@ int main(int argc, const char * argv[])
pthread_t sendBufferThread;
pthread_create(&sendBufferThread, NULL, sendBuffer, NULL);
int16_t *loopbackAudioPacket;
if (LOOPBACK_SANITY_CHECK) {
loopbackAudioPacket = new int16_t[1024];
}
sockaddr *agentAddress = new sockaddr;
timeval lastReceive;
gettimeofday(&lastReceive, NULL);
bool firstSample = true;
while (true) {
if(agentList.getAgentSocket().receive(agentAddress, packetData, &receivedBytes)) {
if (packetData[0] == 'I') {
// Compute and report standard deviation for jitter calculation
if (firstSample) {
stdev.reset();
firstSample = false;
} else {
double tDiff = (usecTimestampNow() - usecTimestamp(&lastReceive)) / 1000;
stdev.addValue(tDiff);
if (stdev.getSamples() > 500) {
printf("Avg: %4.2f, Stdev: %4.2f\n", stdev.getAverage(), stdev.getStDev());
stdev.reset();
}
}
gettimeofday(&lastReceive, NULL);
// add or update the existing interface agent
agentList.addOrUpdateAgent(agentAddress, agentAddress, packetData[0]);
agentList.updateAgentWithData(agentAddress, (void *)packetData, receivedBytes);
if (!LOOPBACK_SANITY_CHECK) {
agentList.addOrUpdateAgent(agentAddress, agentAddress, packetData[0]);
agentList.updateAgentWithData(agentAddress, (void *)packetData, receivedBytes);
} else {
memcpy(loopbackAudioPacket, packetData + 1 + (sizeof(float) * 4), 1024);
agentList.getAgentSocket().send(agentAddress, loopbackAudioPacket, 1024);
}
}
}
}

48
shared/src/StdDev.cpp Normal file
View file

@ -0,0 +1,48 @@
//
// StdDev.cpp
// hifi
//
// Created by Philip Rosedale on 3/12/13.
//
//
#include "StdDev.h"
#include <cmath>
const int MAX_STDEV_SAMPLES = 1000; // Don't add more than this number of samples.
StDev::StDev() {
data = new float[MAX_STDEV_SAMPLES];
sampleCount = 0;
}
void StDev::reset() {
sampleCount = 0;
}
void StDev::addValue(float v) {
data[sampleCount++] = v;
if (sampleCount == MAX_STDEV_SAMPLES) sampleCount = 0;
}
float StDev::getAverage() {
float average = 0;
for (int i = 0; i < sampleCount; i++) {
average += data[i];
}
if (sampleCount > 0)
return average/(float)sampleCount;
else return 0;
}
float StDev::getStDev() {
float average = getAverage();
float stdev = 0;
for (int i = 0; i < sampleCount; i++) {
stdev += powf(data[i] - average, 2);
}
if (sampleCount > 1)
return sqrt(stdev/(float)(sampleCount - 1.0));
else
return 0;
}

27
shared/src/StdDev.h Normal file
View file

@ -0,0 +1,27 @@
//
// StdDev.h
// hifi
//
// Created by Philip Rosedale on 3/12/13.
//
//
#ifndef __hifi__StdDev__
#define __hifi__StdDev__
#include <iostream>
class StDev {
public:
StDev();
void reset();
void addValue(float v);
float getAverage();
float getStDev();
int getSamples() {return sampleCount;};
private:
float * data;
int sampleCount;
};
#endif /* defined(__hifi__StdDev__) */