This commit is contained in:
Philip Rosedale 2013-06-05 09:40:42 -07:00
commit 626dcd0875
11 changed files with 206 additions and 148 deletions

View file

@ -17,6 +17,8 @@
#include <limits>
#include <signal.h>
#include <glm/gtx/norm.hpp>
#include <glm/gtx/vector_angle.hpp>
#include <AgentList.h>
#include <Agent.h>
#include <AgentTypes.h>
@ -55,13 +57,6 @@ const float BUFFER_SEND_INTERVAL_USECS = (BUFFER_LENGTH_SAMPLES_PER_CHANNEL / SA
const long MAX_SAMPLE_VALUE = std::numeric_limits<int16_t>::max();
const long MIN_SAMPLE_VALUE = std::numeric_limits<int16_t>::min();
const float DISTANCE_SCALE = 2.5f;
const float PHASE_AMPLITUDE_RATIO_AT_90 = 0.5;
const int PHASE_DELAY_AT_90 = 20;
const float MAX_OFF_AXIS_ATTENUATION = 0.2f;
const float OFF_AXIS_ATTENUATION_FORMULA_STEP = (1 - MAX_OFF_AXIS_ATTENUATION) / 2.0f;
void plateauAdditionOfSamples(int16_t &mixSample, int16_t sampleToAdd) {
long sumSample = sampleToAdd + mixSample;
@ -128,10 +123,6 @@ int main(int argc, const char* argv[]) {
}
}
int numAgents = agentList->size();
float distanceCoefficients[numAgents][numAgents];
memset(distanceCoefficients, 0, sizeof(distanceCoefficients));
for (AgentList::iterator agent = agentList->begin(); agent != agentList->end(); agent++) {
if (agent->getType() == AGENT_TYPE_AVATAR) {
AudioRingBuffer* agentRingBuffer = (AudioRingBuffer*) agent->getLinkedData();
@ -146,90 +137,101 @@ int main(int argc, const char* argv[]) {
if (otherAgentBuffer->shouldBeAddedToMix()) {
float bearingRelativeAngleToSource = 0.f;
float attenuationCoefficient = 1.f;
float attenuationCoefficient = 1.0f;
int numSamplesDelay = 0;
float weakChannelAmplitudeRatio = 1.f;
float weakChannelAmplitudeRatio = 1.0f;
if (otherAgent != agent) {
glm::vec3 agentPosition = agentRingBuffer->getPosition();
glm::vec3 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 (distanceCoefficients[lowAgentIndex][highAgentIndex] == 0) {
float distanceToAgent = sqrtf(powf(agentPosition.x - otherAgentPosition.x, 2) +
powf(agentPosition.y - otherAgentPosition.y, 2) +
powf(agentPosition.z - otherAgentPosition.z, 2));
glm::vec3 listenerPosition = agentRingBuffer->getPosition();
glm::vec3 relativePosition = otherAgentBuffer->getPosition() - agentRingBuffer->getPosition();
glm::quat inverseOrientation = glm::inverse(agentRingBuffer->getOrientation());
glm::vec3 rotatedSourcePosition = inverseOrientation * relativePosition;
float distanceSquareToSource = glm::dot(relativePosition, relativePosition);
float distanceCoefficient = 1.0f;
float offAxisCoefficient = 1.0f;
if (otherAgentBuffer->getRadius() == 0
|| (distanceSquareToSource > (otherAgentBuffer->getRadius()
* otherAgentBuffer->getRadius()))) {
// this is either not a spherical source, or the listener is outside the sphere
float minCoefficient = std::min(1.0f,
powf(0.3,
(logf(DISTANCE_SCALE * distanceToAgent) / logf(2.5))
- 1));
distanceCoefficients[lowAgentIndex][highAgentIndex] = minCoefficient;
}
// get the angle from the right-angle triangle
float triangleAngle = atan2f(fabsf(agentPosition.z - otherAgentPosition.z),
fabsf(agentPosition.x - otherAgentPosition.x)) * (180 / M_PI);
float absoluteAngleToSource = 0;
bearingRelativeAngleToSource = 0;
// find the angle we need for calculation based on the orientation of the triangle
if (otherAgentPosition.x > agentPosition.x) {
if (otherAgentPosition.z > agentPosition.z) {
absoluteAngleToSource = -90 + triangleAngle;
if (otherAgentBuffer->getRadius() > 0) {
// this is a spherical source - the distance used for the coefficient
// needs to be the closest point on the boundary to the source
// multiply the normalized vector between the center of the sphere
// and the position of the source by the radius to get the
// closest point on the boundary of the sphere to the source
glm::vec3 closestPoint = glm::normalize(relativePosition) * otherAgentBuffer->getRadius();
// for the other calculations the agent position is the closest point on the sphere
rotatedSourcePosition = inverseOrientation * closestPoint;
// ovveride the distance to the agent with the distance to the point on the
// boundary of the sphere
distanceSquareToSource = glm::distance2(listenerPosition, -closestPoint);
} else {
absoluteAngleToSource = -90 - triangleAngle;
}
} else {
if (otherAgentPosition.z > agentPosition.z) {
absoluteAngleToSource = 90 - triangleAngle;
} else {
absoluteAngleToSource = 90 + triangleAngle;
// calculate the angle delivery
glm::vec3 rotatedListenerPosition = glm::inverse(otherAgentBuffer->getOrientation())
* relativePosition;
float angleOfDelivery = glm::angle(glm::vec3(0.0f, 0.0f, -1.0f),
glm::normalize(rotatedListenerPosition));
const float MAX_OFF_AXIS_ATTENUATION = 0.2f;
const float OFF_AXIS_ATTENUATION_FORMULA_STEP = (1 - MAX_OFF_AXIS_ATTENUATION) / 2.0f;
offAxisCoefficient = MAX_OFF_AXIS_ATTENUATION +
(OFF_AXIS_ATTENUATION_FORMULA_STEP * (angleOfDelivery / 90.0f));
}
const float DISTANCE_SCALE = 2.5f;
const float GEOMETRIC_AMPLITUDE_SCALAR = 0.3f;
const float DISTANCE_LOG_BASE = 2.5f;
const float DISTANCE_SCALE_LOG = logf(DISTANCE_SCALE) / logf(DISTANCE_LOG_BASE);
// calculate the distance coefficient using the distance to this agent
distanceCoefficient = powf(GEOMETRIC_AMPLITUDE_SCALAR,
DISTANCE_SCALE_LOG +
(logf(distanceSquareToSource) / logf(DISTANCE_LOG_BASE)) - 1);
distanceCoefficient = std::min(1.0f, distanceCoefficient);
// off-axis attenuation and spatialization of audio
// not performed if listener is inside spherical injector
// calculate the angle from the source to the listener
// project the rotated source position vector onto the XZ plane
rotatedSourcePosition.y = 0.0f;
// produce an oriented angle about the y-axis
bearingRelativeAngleToSource = glm::orientedAngle(glm::vec3(0.0f, 0.0f, -1.0f),
glm::normalize(rotatedSourcePosition),
glm::vec3(0.0f, 1.0f, 0.0f));
const float PHASE_AMPLITUDE_RATIO_AT_90 = 0.5;
const int PHASE_DELAY_AT_90 = 20;
float sinRatio = fabsf(sinf(glm::radians(bearingRelativeAngleToSource)));
numSamplesDelay = PHASE_DELAY_AT_90 * sinRatio;
weakChannelAmplitudeRatio = 1 - (PHASE_AMPLITUDE_RATIO_AT_90 * sinRatio);
}
bearingRelativeAngleToSource = absoluteAngleToSource - agentRingBuffer->getBearing();
if (bearingRelativeAngleToSource > 180) {
bearingRelativeAngleToSource -= 360;
} else if (bearingRelativeAngleToSource < -180) {
bearingRelativeAngleToSource += 360;
}
float angleOfDelivery = absoluteAngleToSource - otherAgentBuffer->getBearing();
if (angleOfDelivery > 180) {
angleOfDelivery -= 360;
} else if (angleOfDelivery < -180) {
angleOfDelivery += 360;
}
float offAxisCoefficient = MAX_OFF_AXIS_ATTENUATION +
(OFF_AXIS_ATTENUATION_FORMULA_STEP * (fabsf(angleOfDelivery) / 90.0f));
attenuationCoefficient = distanceCoefficients[lowAgentIndex][highAgentIndex]
attenuationCoefficient = distanceCoefficient
* otherAgentBuffer->getAttenuationRatio()
* offAxisCoefficient;
bearingRelativeAngleToSource *= (M_PI / 180);
float sinRatio = fabsf(sinf(bearingRelativeAngleToSource));
numSamplesDelay = PHASE_DELAY_AT_90 * sinRatio;
weakChannelAmplitudeRatio = 1 - (PHASE_AMPLITUDE_RATIO_AT_90 * sinRatio);
}
int16_t* goodChannel = bearingRelativeAngleToSource > 0.0f
? clientSamples + BUFFER_LENGTH_SAMPLES_PER_CHANNEL
: clientSamples;
int16_t* delayedChannel = bearingRelativeAngleToSource > 0.0f
? clientSamples
: clientSamples + BUFFER_LENGTH_SAMPLES_PER_CHANNEL;
int16_t* delayedChannel = bearingRelativeAngleToSource > 0.0f
? clientSamples + BUFFER_LENGTH_SAMPLES_PER_CHANNEL
: clientSamples;
int16_t* delaySamplePointer = otherAgentBuffer->getNextOutput() == otherAgentBuffer->getBuffer()
? otherAgentBuffer->getBuffer() + RING_BUFFER_SAMPLES - numSamplesDelay
@ -288,7 +290,7 @@ int main(int argc, const char* argv[]) {
agentList->updateAgentWithData(agentAddress, packetData, receivedBytes);
if (std::isnan(((AudioRingBuffer *)avatarAgent->getLinkedData())->getBearing())) {
if (std::isnan(((AudioRingBuffer *)avatarAgent->getLinkedData())->getOrientation().x)) {
// kill off this agent - temporary solution to mixer crash on mac sleep
avatarAgent->setAlive(false);
}

View file

@ -27,32 +27,41 @@ const int AVATAR_MIXER_DATA_SEND_INTERVAL_MSECS = 15;
const int DEFAULT_INJECTOR_VOLUME = 0xFF;
enum {
INJECTOR_POSITION_X,
INJECTOR_POSITION_Y,
INJECTOR_POSITION_Z,
INJECTOR_YAW
};
// Command line parameter defaults
bool loopAudio = true;
float sleepIntervalMin = 1.00;
float sleepIntervalMax = 2.00;
char *sourceAudioFile = NULL;
const char *allowedParameters = ":rb::t::c::a::f::d:";
const char *allowedParameters = ":sb::t::c::a::f::d::r:";
float floatArguments[4] = {0.0f, 0.0f, 0.0f, 0.0f};
unsigned char volume = DEFAULT_INJECTOR_VOLUME;
float triggerDistance = 0;
float triggerDistance = 0.0f;
float radius = 0.0f;
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 << " -s 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;
std::cout << " -d FLOAT Trigger distance for injection. If not specified will loop constantly" << std::endl;
std::cout << " -r FLOAT Radius for spherical source. If not specified injected audio is point source" << std::endl;
}
bool processParameters(int parameterCount, char* parameterData[]) {
int p;
while ((p = getopt(parameterCount, parameterData, allowedParameters)) != -1) {
switch (p) {
case 'r':
case 's':
::loopAudio = false;
std::cout << "[DEBUG] Random sleep mode enabled" << std::endl;
break;
@ -92,6 +101,10 @@ bool processParameters(int parameterCount, char* parameterData[]) {
::triggerDistance = atof(optarg);
std::cout << "[DEBUG] Trigger distance: " << optarg << std::endl;
break;
case 'r':
::radius = atof(optarg);
std::cout << "[DEBUG] Injector radius: " << optarg << std::endl;
break;
default:
usage();
return false;
@ -160,9 +173,16 @@ int main(int argc, char* argv[]) {
// start the agent list thread that will kill off agents when they stop talking
agentList->startSilentAgentRemovalThread();
injector.setPosition(glm::vec3(::floatArguments[0], ::floatArguments[1], ::floatArguments[2]));
injector.setBearing(*(::floatArguments + 3));
injector.setPosition(glm::vec3(::floatArguments[INJECTOR_POSITION_X],
::floatArguments[INJECTOR_POSITION_Y],
::floatArguments[INJECTOR_POSITION_Z]));
injector.setOrientation(glm::quat(glm::vec3(0.0f, ::floatArguments[INJECTOR_YAW], 0.0f)));
injector.setVolume(::volume);
if (::radius > 0) {
// if we were passed a cube side length, give that to the injector
injector.setRadius(::radius);
}
// register the callback for agent data creation
agentList->linkedDataCreateCallback = createAvatarDataForAgent;

View file

@ -2246,7 +2246,7 @@ void Application::maybeEditVoxelUnderCursor() {
AudioInjector* voxelInjector = AudioInjectionManager::injectorWithCapacity(11025);
voxelInjector->setPosition(glm::vec3(_mouseVoxel.x, _mouseVoxel.y, _mouseVoxel.z));
//_myAvatar.getPosition()
voxelInjector->setBearing(-1 * _myAvatar.getAbsoluteHeadYaw());
// voxelInjector->setBearing(-1 * _myAvatar.getAbsoluteHeadYaw());
voxelInjector->setVolume (16 * pow (_mouseVoxel.s, 2) / .0000001); //255 is max, and also default value
/* for (int i = 0; i
@ -2309,7 +2309,7 @@ void Application::deleteVoxelUnderCursor() {
sendVoxelEditMessage(PACKET_HEADER_ERASE_VOXEL, _mouseVoxel);
AudioInjector* voxelInjector = AudioInjectionManager::injectorWithCapacity(5000);
voxelInjector->setPosition(glm::vec3(_mouseVoxel.x, _mouseVoxel.y, _mouseVoxel.z));
voxelInjector->setBearing(0); //straight down the z axis
// voxelInjector->setBearing(0); //straight down the z axis
voxelInjector->setVolume (255); //255 is max, and also default value

View file

@ -133,7 +133,10 @@ int audioCallback (const void* inputBuffer,
Agent* audioMixer = agentList->soloAgentOfType(AGENT_TYPE_AUDIO_MIXER);
if (audioMixer) {
int leadingBytes = 2 + (sizeof(float) * 4);
glm::vec3 headPosition = interfaceAvatar->getHeadJointPosition();
glm::quat headOrientation = interfaceAvatar->getHead().getOrientation();
int leadingBytes = 1 + sizeof(headPosition) + sizeof(headOrientation) + sizeof(unsigned char);
// we need the amount of bytes in the buffer + 1 for type
// + 12 for 3 floats for position + float for bearing + 1 attenuation byte
@ -143,29 +146,15 @@ int audioCallback (const void* inputBuffer,
unsigned char *currentPacketPtr = dataPacket + 1;
// memcpy the three float positions
memcpy(currentPacketPtr, &interfaceAvatar->getHeadJointPosition(), sizeof(float) * 3);
currentPacketPtr += (sizeof(float) * 3);
memcpy(currentPacketPtr, &headPosition, sizeof(headPosition));
currentPacketPtr += (sizeof(headPosition));
// tell the mixer not to add additional attenuation to our source
*(currentPacketPtr++) = 255;
// memcpy the corrected render yaw
float correctedYaw = fmodf(-1 * interfaceAvatar->getAbsoluteHeadYaw(), 360);
if (correctedYaw > 180) {
correctedYaw -= 360;
} else if (correctedYaw < -180) {
correctedYaw += 360;
}
if (Application::getInstance()->shouldEchoAudio()) {
correctedYaw = correctedYaw > 0
? correctedYaw + AGENT_LOOPBACK_MODIFIER
: correctedYaw - AGENT_LOOPBACK_MODIFIER;
}
memcpy(currentPacketPtr, &correctedYaw, sizeof(float));
currentPacketPtr += sizeof(float);
// memcpy our orientation
memcpy(currentPacketPtr, &headOrientation, sizeof(headOrientation));
currentPacketPtr += sizeof(headOrientation);
// copy the audio data to the last BUFFER_LENGTH_BYTES bytes of the data packet
memcpy(currentPacketPtr, inputLeft, BUFFER_LENGTH_BYTES);

View file

@ -83,6 +83,15 @@ void AvatarVoxelSystem::loadVoxelsFromURL(const QUrl& url) {
killLocalVoxels();
// handle "file://" urls...
if (url.isLocalFile()) {
QString pathString = url.path();
QByteArray pathAsAscii = pathString.toAscii();
const char* path = pathAsAscii.data();
readFromSVOFile(path);
return;
}
// load the URL data asynchronously
if (!url.isValid()) {
return;
@ -186,6 +195,15 @@ void AvatarVoxelSystem::handleVoxelDownloadProgress(qint64 bytesReceived, qint64
if (bytesReceived < bytesTotal) {
return;
}
// XXXBHG - I don't know why this can happen, but when I was testing this, I used a dropbox URL
// and it resulted in a case where the bytesTotal == bytesReceived, but the _voxelReply was NULL
// which needless to say caused crashes below. I've added this quick guard to protect against
// this case, but it probably should be investigated.
if (!_voxelReply) {
return;
}
QByteArray entirety = _voxelReply->readAll();
_voxelReply->deleteLater();
_voxelReply = 0;

View file

@ -18,8 +18,9 @@
const int MAX_INJECTOR_VOLUME = 0xFF;
AudioInjector::AudioInjector(const char* filename) :
_position(),
_bearing(0),
_position(0.0f, 0.0f, 0.0f),
_orientation(0.0f, 0.0f, 0.0f, 0.0f),
_radius(0.0f),
_volume(MAX_INJECTOR_VOLUME),
_indexOfNextSlot(0),
_isInjectingAudio(false)
@ -47,8 +48,9 @@ AudioInjector::AudioInjector(const char* filename) :
AudioInjector::AudioInjector(int maxNumSamples) :
_numTotalSamples(maxNumSamples),
_position(),
_bearing(0),
_position(0.0f, 0.0f, 0.0f),
_orientation(0.0f, 0.0f, 0.0f, 0.0f),
_radius(0.0f),
_volume(MAX_INJECTOR_VOLUME),
_indexOfNextSlot(0),
_isInjectingAudio(false)
@ -70,12 +72,20 @@ void AudioInjector::injectAudio(UDPSocket* injectorSocket, sockaddr* destination
timeval startTime;
// calculate the number of bytes required for additional data
int leadingBytes = sizeof(PACKET_HEADER) + sizeof(_streamIdentifier)
+ sizeof(_position) + sizeof(_bearing) + sizeof(_volume);
int leadingBytes = sizeof(PACKET_HEADER) + sizeof(INJECT_AUDIO_AT_POINT_COMMAND) + sizeof(_streamIdentifier)
+ sizeof(_position) + sizeof(_orientation) + sizeof(_volume);
if (_radius > 0) {
// we'll need 4 extra bytes if the cube side length is being sent as well
leadingBytes += sizeof(_radius);
}
unsigned char dataPacket[BUFFER_LENGTH_BYTES + leadingBytes];
dataPacket[0] = PACKET_HEADER_INJECT_AUDIO;
unsigned char *currentPacketPtr = dataPacket + 1;
// add the correct command for point source or cube of sound
dataPacket[1] = (_radius > 0) ? INJECT_AUDIO_AT_CUBE_COMMAND : INJECT_AUDIO_AT_POINT_COMMAND;
unsigned char *currentPacketPtr = dataPacket + sizeof(PACKET_HEADER) + sizeof(INJECT_AUDIO_AT_POINT_COMMAND);
// copy the identifier for this injector
memcpy(currentPacketPtr, &_streamIdentifier, sizeof(_streamIdentifier));
@ -84,11 +94,18 @@ void AudioInjector::injectAudio(UDPSocket* injectorSocket, sockaddr* destination
memcpy(currentPacketPtr, &_position, sizeof(_position));
currentPacketPtr += sizeof(_position);
if (_radius > 0) {
// if we have a cube half height we need to send it here
// this tells the mixer how much volume the injected audio will occupy
memcpy(currentPacketPtr, &_radius, sizeof(_radius));
currentPacketPtr += sizeof(_radius);
}
*currentPacketPtr = _volume;
currentPacketPtr++;
memcpy(currentPacketPtr, &_bearing, sizeof(_bearing));
currentPacketPtr += sizeof(_bearing);
memcpy(currentPacketPtr, &_orientation, sizeof(_orientation));
currentPacketPtr += sizeof(_orientation);
gettimeofday(&startTime, NULL);
int nextFrame = 0;

View file

@ -36,8 +36,11 @@ public:
const glm::vec3& getPosition() const { return _position; }
void setPosition(const glm::vec3& position) { _position = position; }
float getBearing() const { return _bearing; }
void setBearing(float bearing) { _bearing = bearing; }
const glm::quat& getOrientation() const { return _orientation; }
void setOrientation(const glm::quat& orientation) { _orientation = orientation; }
float getRadius() const { return _radius; }
void setRadius(float radius) { _radius = radius; }
void addSample(const int16_t sample);
void addSamples(int16_t* sampleBuffer, int numSamples);
@ -46,7 +49,8 @@ private:
int16_t* _audioSampleArray;
int _numTotalSamples;
glm::vec3 _position;
float _bearing;
glm::quat _orientation;
float _radius;
unsigned char _volume;
int _indexOfNextSlot;
bool _isInjectingAudio;

View file

@ -17,6 +17,7 @@ AudioRingBuffer::AudioRingBuffer(int ringSamples, int bufferSamples) :
AgentData(NULL),
_ringBufferLengthSamples(ringSamples),
_bufferLengthSamples(bufferSamples),
_radius(0.0f),
_endOfLastWrite(NULL),
_started(false),
_shouldBeAddedToMix(false),
@ -46,31 +47,34 @@ int AudioRingBuffer::parseData(unsigned char* sourceBuffer, int numBytes) {
// we've got a stream identifier to pull from the packet
memcpy(&_streamIdentifier, dataBuffer, sizeof(_streamIdentifier));
dataBuffer += sizeof(_streamIdentifier);
// push past the injection command
dataBuffer += sizeof(INJECT_AUDIO_AT_POINT_COMMAND);
}
memcpy(&_position, dataBuffer, sizeof(_position));
dataBuffer += (sizeof(_position));
dataBuffer += sizeof(_position);
if (sourceBuffer[0] == PACKET_HEADER_INJECT_AUDIO && sourceBuffer[1] == INJECT_AUDIO_AT_CUBE_COMMAND) {
// this is audio that needs to be injected as a volume (cube)
// parse out the cubeHalfHeight sent by the client
memcpy(&_radius, dataBuffer, sizeof(_radius));
dataBuffer += sizeof(_radius);
}
unsigned int attenuationByte = *(dataBuffer++);
_attenuationRatio = attenuationByte / 255.0f;
memcpy(&_bearing, dataBuffer, sizeof(float));
dataBuffer += sizeof(_bearing);
memcpy(&_orientation, dataBuffer, sizeof(_orientation));
dataBuffer += sizeof(_orientation);
// if this agent sent us a NaN bearing then don't consider this good audio and bail
if (std::isnan(_bearing)) {
// if this agent sent us a NaN for first float in orientation then don't consider this good audio and bail
if (std::isnan(_orientation.x)) {
_endOfLastWrite = _nextOutput = _buffer;
_started = false;
return 0;
} else if (_bearing > 180 || _bearing < -180) {
// we were passed an invalid bearing because this agent wants loopback (pressed the H key)
_shouldLoopbackForAgent = true;
// correct the bearing
_bearing = _bearing > 0
? _bearing - AGENT_LOOPBACK_MODIFIER
: _bearing + AGENT_LOOPBACK_MODIFIER;
} else {
// currently no possiblity for loopback, need to add once quaternion audio is working again
_shouldLoopbackForAgent = false;
}
}

View file

@ -12,17 +12,23 @@
#include <stdint.h>
#include <glm/glm.hpp>
#include <glm/gtx/quaternion.hpp>
#include "AgentData.h"
const int STREAM_IDENTIFIER_NUM_BYTES = 8;
const char INJECT_AUDIO_AT_POINT_COMMAND = 'P';
const char INJECT_AUDIO_AT_CUBE_COMMAND = 'C';
class AudioRingBuffer : public AgentData {
public:
AudioRingBuffer(int ringSamples, int bufferSamples);
~AudioRingBuffer();
int parseData(unsigned char* sourceBuffer, int numBytes);
float getRadius() const { return _radius; }
int16_t* getNextOutput() const { return _nextOutput; }
void setNextOutput(int16_t* nextOutput) { _nextOutput = nextOutput; }
@ -39,8 +45,9 @@ public:
void setShouldBeAddedToMix(bool shouldBeAddedToMix) { _shouldBeAddedToMix = shouldBeAddedToMix; }
const glm::vec3& getPosition() const { return _position; }
const glm::quat& getOrientation() const { return _orientation; }
float getAttenuationRatio() const { return _attenuationRatio; }
float getBearing() const { return _bearing; }
bool shouldLoopbackForAgent() const { return _shouldLoopbackForAgent; }
const unsigned char* getStreamIdentifier() const { return _streamIdentifier; }
@ -53,8 +60,9 @@ private:
int _ringBufferLengthSamples;
int _bufferLengthSamples;
glm::vec3 _position;
glm::quat _orientation;
float _radius;
float _attenuationRatio;
float _bearing;
int16_t* _nextOutput;
int16_t* _endOfLastWrite;
int16_t* _buffer;

View file

@ -40,7 +40,7 @@ bool pingUnknownAgentThreadStopFlag = false;
AgentList* AgentList::_sharedInstance = NULL;
AgentList* AgentList::createInstance(char ownerType, unsigned int socketListenPort) {
if (_sharedInstance == NULL) {
if (!_sharedInstance) {
_sharedInstance = new AgentList(ownerType, socketListenPort);
} else {
printLog("AgentList createInstance called with existing instance.\n");
@ -50,7 +50,7 @@ AgentList* AgentList::createInstance(char ownerType, unsigned int socketListenPo
}
AgentList* AgentList::getInstance() {
if (_sharedInstance == NULL) {
if (!_sharedInstance) {
printLog("AgentList getInstance called before call to createInstance. Returning NULL pointer.\n");
}
@ -150,14 +150,12 @@ int AgentList::updateAgentWithData(sockaddr *senderAddress, unsigned char *packe
int AgentList::updateAgentWithData(Agent *agent, unsigned char *packetData, int dataBytes) {
agent->setLastHeardMicrostamp(usecTimestampNow());
if (agent->getActiveSocket() != NULL) {
if (agent->getActiveSocket()) {
agent->recordBytesReceived(dataBytes);
}
if (agent->getLinkedData() == NULL) {
if (linkedDataCreateCallback != NULL) {
linkedDataCreateCallback(agent);
}
if (!agent->getLinkedData() && linkedDataCreateCallback) {
linkedDataCreateCallback(agent);
}
return agent->getLinkedData()->parseData(packetData, dataBytes);
@ -165,7 +163,7 @@ int AgentList::updateAgentWithData(Agent *agent, unsigned char *packetData, int
Agent* AgentList::agentWithAddress(sockaddr *senderAddress) {
for(AgentList::iterator agent = begin(); agent != end(); agent++) {
if (agent->getActiveSocket() != NULL && socketMatch(agent->getActiveSocket(), senderAddress)) {
if (agent->getActiveSocket() && socketMatch(agent->getActiveSocket(), senderAddress)) {
return &(*agent);
}
}
@ -216,7 +214,7 @@ int AgentList::processDomainServerList(unsigned char *packetData, size_t dataByt
Agent* AgentList::addOrUpdateAgent(sockaddr* publicSocket, sockaddr* localSocket, char agentType, uint16_t agentId) {
AgentList::iterator agent = end();
if (publicSocket != NULL) {
if (publicSocket) {
for (agent = begin(); agent != end(); agent++) {
if (agent->matches(publicSocket, localSocket, agentType)) {
// we already have this agent, stop checking
@ -327,8 +325,7 @@ void *pingUnknownAgents(void *args) {
for(AgentList::iterator agent = agentList->begin();
agent != agentList->end();
agent++) {
if (agent->getActiveSocket() == NULL
&& (agent->getPublicSocket() != NULL && agent->getLocalSocket() != NULL)) {
if (!agent->getActiveSocket() && agent->getPublicSocket() && agent->getLocalSocket()) {
// ping both of the sockets for the agent so we can figure out
// which socket we can use
agentList->getAgentSocket()->send(agent->getPublicSocket(), &PACKET_HEADER_PING, 1);

View file

@ -1,4 +1,3 @@
//
// PacketHeaders.h
// hifi