Conflicts:
	interface/src/Avatar.h
This commit is contained in:
Andrzej Kapolka 2013-05-01 11:46:23 -07:00
commit 5d457afaf9
5 changed files with 155 additions and 139 deletions

View file

@ -92,13 +92,15 @@ void *sendBuffer(void *args)
if (!agentBuffer->isStarted()
&& agentBuffer->diffLastWriteNextOutput() <= BUFFER_LENGTH_SAMPLES_PER_CHANNEL + JITTER_BUFFER_SAMPLES) {
printf("Held back buffer for agent with ID %d.\n", agent->getAgentId());
agentBuffer->setShouldBeAddedToMix(false);
} else if (agentBuffer->diffLastWriteNextOutput() < BUFFER_LENGTH_SAMPLES_PER_CHANNEL) {
printf("Buffer from agent with ID %d starved.\n", agent->getAgentId());
agentBuffer->setStarted(false);
agentBuffer->setShouldBeAddedToMix(false);
} else {
// good buffer, add this to the mix
agentBuffer->setStarted(true);
agentBuffer->setAddedToMix(true);
agentBuffer->setShouldBeAddedToMix(true);
}
}
}
@ -129,89 +131,91 @@ void *sendBuffer(void *args)
if (otherAgent != agent || (otherAgent == agent && agentWantsLoopback)) {
AudioRingBuffer* otherAgentBuffer = (AudioRingBuffer*) otherAgent->getLinkedData();
float *agentPosition = agentRingBuffer->getPosition();
float *otherAgentPosition = otherAgentBuffer->getPosition();
// calculate the distance to the other agent
// use the distance to the other agent to calculate the change in volume for this frame
int lowAgentIndex = std::min(agent.getAgentIndex(), otherAgent.getAgentIndex());
int highAgentIndex = std::max(agent.getAgentIndex(), otherAgent.getAgentIndex());
if (distanceCoeffs[lowAgentIndex][highAgentIndex] == 0) {
float distanceToAgent = sqrtf(powf(agentPosition[0] - otherAgentPosition[0], 2) +
powf(agentPosition[1] - otherAgentPosition[1], 2) +
powf(agentPosition[2] - otherAgentPosition[2], 2));
if (otherAgentBuffer->shouldBeAddedToMix()) {
float *agentPosition = agentRingBuffer->getPosition();
float *otherAgentPosition = otherAgentBuffer->getPosition();
float minCoefficient = std::min(1.0f,
powf(0.5, (logf(DISTANCE_RATIO * distanceToAgent) / logf(3)) - 1));
distanceCoeffs[lowAgentIndex][highAgentIndex] = minCoefficient;
}
// get the angle from the right-angle triangle
float triangleAngle = atan2f(fabsf(agentPosition[2] - otherAgentPosition[2]),
fabsf(agentPosition[0] - otherAgentPosition[0])) * (180 / M_PI);
float angleToSource;
// find the angle we need for calculation based on the orientation of the triangle
if (otherAgentPosition[0] > agentPosition[0]) {
if (otherAgentPosition[2] > agentPosition[2]) {
angleToSource = -90 + triangleAngle - agentBearing;
} else {
angleToSource = -90 - triangleAngle - agentBearing;
// calculate the distance to the other agent
// use the distance to the other agent to calculate the change in volume for this frame
int lowAgentIndex = std::min(agent.getAgentIndex(), otherAgent.getAgentIndex());
int highAgentIndex = std::max(agent.getAgentIndex(), otherAgent.getAgentIndex());
if (distanceCoeffs[lowAgentIndex][highAgentIndex] == 0) {
float distanceToAgent = sqrtf(powf(agentPosition[0] - otherAgentPosition[0], 2) +
powf(agentPosition[1] - otherAgentPosition[1], 2) +
powf(agentPosition[2] - otherAgentPosition[2], 2));
float minCoefficient = std::min(1.0f,
powf(0.5, (logf(DISTANCE_RATIO * distanceToAgent) / logf(3)) - 1));
distanceCoeffs[lowAgentIndex][highAgentIndex] = minCoefficient;
}
} else {
if (otherAgentPosition[2] > agentPosition[2]) {
angleToSource = 90 - triangleAngle - agentBearing;
// get the angle from the right-angle triangle
float triangleAngle = atan2f(fabsf(agentPosition[2] - otherAgentPosition[2]),
fabsf(agentPosition[0] - otherAgentPosition[0])) * (180 / M_PI);
float angleToSource;
// find the angle we need for calculation based on the orientation of the triangle
if (otherAgentPosition[0] > agentPosition[0]) {
if (otherAgentPosition[2] > agentPosition[2]) {
angleToSource = -90 + triangleAngle - agentBearing;
} else {
angleToSource = -90 - triangleAngle - agentBearing;
}
} else {
angleToSource = 90 + triangleAngle - agentBearing;
if (otherAgentPosition[2] > agentPosition[2]) {
angleToSource = 90 - triangleAngle - agentBearing;
} else {
angleToSource = 90 + triangleAngle - agentBearing;
}
}
}
if (angleToSource > 180) {
angleToSource -= 360;
} else if (angleToSource < -180) {
angleToSource += 360;
}
angleToSource *= (M_PI / 180);
float sinRatio = fabsf(sinf(angleToSource));
int numSamplesDelay = PHASE_DELAY_AT_90 * sinRatio;
float weakChannelAmplitudeRatio = 1 - (PHASE_AMPLITUDE_RATIO_AT_90 * sinRatio);
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 *delaySamplePointer = otherAgentBuffer->getNextOutput() == otherAgentBuffer->getBuffer()
if (angleToSource > 180) {
angleToSource -= 360;
} else if (angleToSource < -180) {
angleToSource += 360;
}
angleToSource *= (M_PI / 180);
float sinRatio = fabsf(sinf(angleToSource));
int numSamplesDelay = PHASE_DELAY_AT_90 * sinRatio;
float weakChannelAmplitudeRatio = 1 - (PHASE_AMPLITUDE_RATIO_AT_90 * sinRatio);
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 *delaySamplePointer = otherAgentBuffer->getNextOutput() == otherAgentBuffer->getBuffer()
? otherAgentBuffer->getBuffer() + RING_BUFFER_SAMPLES - numSamplesDelay
: otherAgentBuffer->getNextOutput() - numSamplesDelay;
for (int s = 0; s < BUFFER_LENGTH_SAMPLES_PER_CHANNEL; s++) {
if (s < numSamplesDelay) {
// pull the earlier sample for the delayed channel
for (int s = 0; s < BUFFER_LENGTH_SAMPLES_PER_CHANNEL; s++) {
int earlierSample = delaySamplePointer[s] *
distanceCoeffs[lowAgentIndex][highAgentIndex] *
otherAgentBuffer->getAttenuationRatio();
if (s < numSamplesDelay) {
// pull the earlier sample for the delayed channel
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] *
otherAgentBuffer->getAttenuationRatio());
plateauAdditionOfSamples(goodChannel[s], currentSample);
if (s + numSamplesDelay < BUFFER_LENGTH_SAMPLES_PER_CHANNEL) {
plateauAdditionOfSamples(delayedChannel[s + numSamplesDelay],
currentSample *
weakChannelAmplitudeRatio *
int16_t currentSample = (otherAgentBuffer->getNextOutput()[s] *
distanceCoeffs[lowAgentIndex][highAgentIndex] *
otherAgentBuffer->getAttenuationRatio());
plateauAdditionOfSamples(goodChannel[s], currentSample);
if (s + numSamplesDelay < BUFFER_LENGTH_SAMPLES_PER_CHANNEL) {
plateauAdditionOfSamples(delayedChannel[s + numSamplesDelay],
currentSample *
weakChannelAmplitudeRatio *
otherAgentBuffer->getAttenuationRatio());
}
}
}
}
@ -222,14 +226,14 @@ void *sendBuffer(void *args)
for (AgentList::iterator agent = agentList->begin(); agent != agentList->end(); agent++) {
AudioRingBuffer* agentBuffer = (AudioRingBuffer*) agent->getLinkedData();
if (agentBuffer->wasAddedToMix()) {
if (agentBuffer->shouldBeAddedToMix()) {
agentBuffer->setNextOutput(agentBuffer->getNextOutput() + BUFFER_LENGTH_SAMPLES_PER_CHANNEL);
if (agentBuffer->getNextOutput() >= agentBuffer->getBuffer() + RING_BUFFER_SAMPLES) {
agentBuffer->setNextOutput(agentBuffer->getBuffer());
}
agentBuffer->setAddedToMix(false);
agentBuffer->setShouldBeAddedToMix(false);
}
}

View file

@ -29,7 +29,7 @@ bool stopReceiveAgentDataThread;
bool injectAudioThreadRunning = false;
int TEMP_AUDIO_LISTEN_PORT = 55439;
// UDPSocket audioSocket(TEMP_AUDIO_LISTEN_PORT);
UDPSocket audioSocket(TEMP_AUDIO_LISTEN_PORT);
void *receiveAgentData(void *args) {
sockaddr senderAddress;
@ -80,7 +80,7 @@ void *injectAudio(void *args) {
}
// we have an active audio mixer we can send data to
// eveAudioInjector->injectAudio(&::audioSocket, audioMixer->getActiveSocket());
eveAudioInjector->injectAudio(&::audioSocket, audioMixer->getActiveSocket());
}
::injectAudioThreadRunning = false;
@ -124,7 +124,7 @@ int main(int argc, const char* argv[]) {
0.32, // this is the same as the pelvis standing height (as of 4/26/13)
eve.getPosition()[2] + 0.1));
// read eve's audio data
AudioInjector eveAudioInjector("eve.raw");
AudioInjector eveAudioInjector("/etc/highfidelity/eve/resources/eve.raw");
unsigned char broadcastPacket[MAX_PACKET_SIZE];
broadcastPacket[0] = PACKET_HEADER_HEAD_DATA;
@ -134,8 +134,8 @@ int main(int argc, const char* argv[]) {
timeval thisSend;
double numMicrosecondsSleep = 0;
// int numIterationsLeftBeforeAudioSend = 0;
// pthread_t injectAudioThread;
int numIterationsLeftBeforeAudioSend = 0;
pthread_t injectAudioThread;
int handStateTimer = 0;
@ -156,16 +156,16 @@ int main(int argc, const char* argv[]) {
}
// temporarily disable Eve's audio sending until the file is actually available on EC2 box
// if (numIterationsLeftBeforeAudioSend == 0) {
// if (!::injectAudioThreadRunning) {
// pthread_create(&injectAudioThread, NULL, injectAudio, (void*) &eveAudioInjector);
//
// numIterationsLeftBeforeAudioSend = randIntInRange(MIN_ITERATIONS_BETWEEN_AUDIO_SENDS,
// MAX_ITERATIONS_BETWEEN_AUDIO_SENDS);
// }
// } else {
// numIterationsLeftBeforeAudioSend--;
// }
if (numIterationsLeftBeforeAudioSend == 0) {
if (!::injectAudioThreadRunning) {
pthread_create(&injectAudioThread, NULL, injectAudio, (void*) &eveAudioInjector);
numIterationsLeftBeforeAudioSend = randIntInRange(MIN_ITERATIONS_BETWEEN_AUDIO_SENDS,
MAX_ITERATIONS_BETWEEN_AUDIO_SENDS);
}
} else {
numIterationsLeftBeforeAudioSend--;
}
// sleep for the correct amount of time to have data send be consistently timed
if ((numMicrosecondsSleep = (DATA_SEND_INTERVAL_MSECS * 1000) - (usecTimestampNow() - usecTimestamp(&thisSend))) > 0) {

View file

@ -20,7 +20,29 @@
using namespace std;
const bool BALLS_ON = false;
const bool AVATAR_GRAVITY = true;
const float DECAY = 0.1;
const float THRUST_MAG = 1200.0;
const float YAW_MAG = 500.0; //JJV - changed from 300.0;
const float TEST_YAW_DECAY = 5.0;
const float LIN_VEL_DECAY = 5.0;
const float MY_HAND_HOLDING_PULL = 0.2;
const float YOUR_HAND_HOLDING_PULL = 1.0;
const float BODY_SPRING_FORCE = 6.0f;
const float BODY_SPRING_DECAY = 16.0f;
//const float COLLISION_FRICTION = 0.5;
//const float COLLISION_RADIUS_SCALAR = 1.8;
//const float COLLISION_BALL_FORCE = 0.1;
//const float COLLISION_BODY_FORCE = 3.0;
const float COLLISION_RADIUS_SCALAR = 1.8;
const float COLLISION_BALL_FORCE = 0.6;
const float COLLISION_BODY_FORCE = 6.0;
const float COLLISION_BALL_FRICTION = 200.0;
const float COLLISION_BODY_FRICTION = 0.5;
const bool BALLS_ON = false;
const bool AVATAR_GRAVITY = true;
const float DECAY = 0.1;

View file

@ -14,7 +14,7 @@ AudioRingBuffer::AudioRingBuffer(int ringSamples, int bufferSamples) {
bufferLengthSamples = bufferSamples;
started = false;
addedToMix = false;
_shouldBeAddedToMix = false;
endOfLastWrite = NULL;
@ -26,7 +26,7 @@ AudioRingBuffer::AudioRingBuffer(const AudioRingBuffer &otherRingBuffer) {
ringBufferLengthSamples = otherRingBuffer.ringBufferLengthSamples;
bufferLengthSamples = otherRingBuffer.bufferLengthSamples;
started = otherRingBuffer.started;
addedToMix = otherRingBuffer.addedToMix;
_shouldBeAddedToMix = otherRingBuffer._shouldBeAddedToMix;
buffer = new int16_t[ringBufferLengthSamples];
memcpy(buffer, otherRingBuffer.buffer, sizeof(int16_t) * ringBufferLengthSamples);
@ -71,14 +71,6 @@ void AudioRingBuffer::setStarted(bool status) {
started = status;
}
bool AudioRingBuffer::wasAddedToMix() {
return addedToMix;
}
void AudioRingBuffer::setAddedToMix(bool added) {
addedToMix = added;
}
float* AudioRingBuffer::getPosition() {
return position;
}
@ -136,8 +128,6 @@ int AudioRingBuffer::parseData(unsigned char* sourceBuffer, int numBytes) {
endOfLastWrite += bufferLengthSamples;
addedToMix = false;
if (endOfLastWrite >= buffer + ringBufferLengthSamples) {
endOfLastWrite = buffer;
}

View file

@ -13,42 +13,42 @@
#include "AgentData.h"
class AudioRingBuffer : public AgentData {
public:
AudioRingBuffer(int ringSamples, int bufferSamples);
~AudioRingBuffer();
AudioRingBuffer(const AudioRingBuffer &otherRingBuffer);
int parseData(unsigned char* sourceBuffer, int numBytes);
AudioRingBuffer* clone() const;
public:
AudioRingBuffer(int ringSamples, int bufferSamples);
~AudioRingBuffer();
AudioRingBuffer(const AudioRingBuffer &otherRingBuffer);
int16_t* getNextOutput();
void setNextOutput(int16_t *newPointer);
int16_t* getEndOfLastWrite();
void setEndOfLastWrite(int16_t *newPointer);
int16_t* getBuffer();
bool isStarted();
void setStarted(bool status);
bool wasAddedToMix();
void setAddedToMix(bool added);
float* getPosition();
void setPosition(float newPosition[]);
float getAttenuationRatio();
void setAttenuationRatio(float newAttenuation);
float getBearing();
void setBearing(float newBearing);
short diffLastWriteNextOutput();
private:
int ringBufferLengthSamples;
int bufferLengthSamples;
float position[3];
float attenuationRatio;
float bearing;
int16_t *nextOutput;
int16_t *endOfLastWrite;
int16_t *buffer;
bool started;
bool addedToMix;
int parseData(unsigned char* sourceBuffer, int numBytes);
AudioRingBuffer* clone() const;
int16_t* getNextOutput();
void setNextOutput(int16_t *newPointer);
int16_t* getEndOfLastWrite();
void setEndOfLastWrite(int16_t *newPointer);
int16_t* getBuffer();
bool isStarted();
void setStarted(bool status);
bool shouldBeAddedToMix() const { return _shouldBeAddedToMix; }
void setShouldBeAddedToMix(bool shouldBeAddedToMix) { _shouldBeAddedToMix = shouldBeAddedToMix; }
float* getPosition();
void setPosition(float newPosition[]);
float getAttenuationRatio();
void setAttenuationRatio(float newAttenuation);
float getBearing();
void setBearing(float newBearing);
short diffLastWriteNextOutput();
private:
int ringBufferLengthSamples;
int bufferLengthSamples;
float position[3];
float attenuationRatio;
float bearing;
int16_t *nextOutput;
int16_t *endOfLastWrite;
int16_t *buffer;
bool started;
bool _shouldBeAddedToMix;
};
#endif /* defined(__interface__AudioRingBuffer__) */