mirror of
https://github.com/JulianGro/overte.git
synced 2025-04-25 16:55:07 +02:00
Merge remote-tracking branch 'origin'
This commit is contained in:
commit
ccd60fa07f
15 changed files with 269 additions and 107 deletions
15
README.md
15
README.md
|
@ -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.
|
BIN
interface/resources/images/green_eye.png
Normal file
BIN
interface/resources/images/green_eye.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 66 KiB |
|
@ -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;
|
||||
|
||||
|
|
|
@ -33,7 +33,6 @@ public:
|
|||
bool terminate();
|
||||
private:
|
||||
bool initialized;
|
||||
|
||||
AudioData *audioData;
|
||||
|
||||
// protects constructor so that public init method is used
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 ();
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -24,6 +24,7 @@ class Head : public AgentData {
|
|||
public:
|
||||
Head();
|
||||
~Head();
|
||||
Head(const Head &otherHead);
|
||||
Head* clone() const;
|
||||
|
||||
void reset();
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
#include "Texture.h"
|
||||
|
||||
#include "InterfaceConfig.h"
|
||||
#include <LodePNG/lodepng.h>
|
||||
#include <lodepng.h>
|
||||
#include <vector>
|
||||
#include <cstdio>
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
48
shared/src/StdDev.cpp
Normal 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
27
shared/src/StdDev.h
Normal 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__) */
|
Loading…
Reference in a new issue