diff --git a/audio-mixer/src/main.cpp b/audio-mixer/src/main.cpp index 7acf76159c..52889cee8e 100644 --- a/audio-mixer/src/main.cpp +++ b/audio-mixer/src/main.cpp @@ -71,23 +71,42 @@ void plateauAdditionOfSamples(int16_t &mixSample, int16_t sampleToAdd) { mixSample = normalizedSample; } -void *sendBuffer(void *args) { - int sentBytes; +void attachNewBufferToAgent(Agent *newAgent) { + if (!newAgent->getLinkedData()) { + newAgent->setLinkedData(new AudioRingBuffer(RING_BUFFER_SAMPLES, BUFFER_LENGTH_SAMPLES_PER_CHANNEL)); + } +} + +int main(int argc, const char* argv[]) { + setvbuf(stdout, NULL, _IOLBF, 0); + + AgentList* agentList = AgentList::createInstance(AGENT_TYPE_AUDIO_MIXER, MIXER_LISTEN_PORT); + + ssize_t receivedBytes = 0; + + agentList->linkedDataCreateCallback = attachNewBufferToAgent; + + agentList->startSilentAgentRemovalThread(); + agentList->startDomainServerCheckInThread(); + + unsigned char* packetData = new unsigned char[MAX_PACKET_SIZE]; + + sockaddr* agentAddress = new sockaddr; + + // make sure our agent socket is non-blocking + agentList->getAgentSocket().setBlocking(false); + int nextFrame = 0; timeval startTime; - AgentList* agentList = AgentList::getInstance(); - gettimeofday(&startTime, NULL); - + while (true) { - sentBytes = 0; - + // enumerate the agents, check if we can add audio from the agent to current mix for (AgentList::iterator agent = agentList->begin(); agent != agentList->end(); agent++) { AudioRingBuffer* agentBuffer = (AudioRingBuffer*) agent->getLinkedData(); - if (agentBuffer && agentBuffer->getEndOfLastWrite() != NULL) { - + if (agentBuffer->getEndOfLastWrite()) { 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()); @@ -107,132 +126,131 @@ void *sendBuffer(void *args) { int numAgents = agentList->size(); float distanceCoefficients[numAgents][numAgents]; memset(distanceCoefficients, 0, sizeof(distanceCoefficients)); - + for (AgentList::iterator agent = agentList->begin(); agent != agentList->end(); agent++) { AudioRingBuffer* agentRingBuffer = (AudioRingBuffer*) agent->getLinkedData(); + + int16_t clientMix[BUFFER_LENGTH_SAMPLES_PER_CHANNEL * 2] = {}; - if (agentRingBuffer) { - int16_t clientMix[BUFFER_LENGTH_SAMPLES_PER_CHANNEL * 2] = {}; - - for (AgentList::iterator otherAgent = agentList->begin(); otherAgent != agentList->end(); otherAgent++) { - if (otherAgent != agent || (otherAgent == agent && agentRingBuffer->shouldLoopbackForAgent())) { - AudioRingBuffer* otherAgentBuffer = (AudioRingBuffer*) otherAgent->getLinkedData(); + for (AgentList::iterator otherAgent = agentList->begin(); otherAgent != agentList->end(); otherAgent++) { + if (otherAgent != agent || (otherAgent == agent && agentRingBuffer->shouldLoopbackForAgent())) { + AudioRingBuffer* otherAgentBuffer = (AudioRingBuffer*) otherAgent->getLinkedData(); + + if (otherAgentBuffer->shouldBeAddedToMix()) { - if (otherAgentBuffer->shouldBeAddedToMix()) { + float bearingRelativeAngleToSource = 0.f; + float attenuationCoefficient = 1.f; + int numSamplesDelay = 0; + float weakChannelAmplitudeRatio = 1.f; + + if (otherAgent != agent) { + Position agentPosition = agentRingBuffer->getPosition(); + Position otherAgentPosition = otherAgentBuffer->getPosition(); - float bearingRelativeAngleToSource = 0.f; - float attenuationCoefficient = 1.f; - int numSamplesDelay = 0; - float weakChannelAmplitudeRatio = 1.f; + // calculate the distance to the other agent - if (otherAgent != agent) { - float *agentPosition = agentRingBuffer->getPosition(); - float *otherAgentPosition = otherAgentBuffer->getPosition(); + // 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)); - // 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[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)); - distanceCoefficients[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 absoluteAngleToSource = 0; - bearingRelativeAngleToSource = 0; - - // find the angle we need for calculation based on the orientation of the triangle - if (otherAgentPosition[0] > agentPosition[0]) { - if (otherAgentPosition[2] > agentPosition[2]) { - absoluteAngleToSource = -90 + triangleAngle; - } else { - absoluteAngleToSource = -90 - triangleAngle; - } - } else { - if (otherAgentPosition[2] > agentPosition[2]) { - absoluteAngleToSource = 90 - triangleAngle; - } else { - absoluteAngleToSource = 90 + triangleAngle; - } - } - - 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] - * 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); + float minCoefficient = std::min(1.0f, + powf(0.5, + (logf(DISTANCE_RATIO * distanceToAgent) / logf(3)) - 1)); + distanceCoefficients[lowAgentIndex][highAgentIndex] = minCoefficient; } - int16_t* goodChannel = bearingRelativeAngleToSource > 0.0f - ? clientMix + BUFFER_LENGTH_SAMPLES_PER_CHANNEL - : clientMix; - int16_t* delayedChannel = bearingRelativeAngleToSource > 0.0f - ? clientMix - : clientMix + BUFFER_LENGTH_SAMPLES_PER_CHANNEL; - int16_t* delaySamplePointer = otherAgentBuffer->getNextOutput() == otherAgentBuffer->getBuffer() + // 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; + } else { + absoluteAngleToSource = -90 - triangleAngle; + } + } else { + if (otherAgentPosition.z > agentPosition.z) { + absoluteAngleToSource = 90 - triangleAngle; + } else { + absoluteAngleToSource = 90 + triangleAngle; + } + } + + 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] + * 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 + ? clientMix + BUFFER_LENGTH_SAMPLES_PER_CHANNEL + : clientMix; + int16_t* delayedChannel = bearingRelativeAngleToSource > 0.0f + ? 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++) { - for (int s = 0; s < BUFFER_LENGTH_SAMPLES_PER_CHANNEL; s++) { - - if (s < numSamplesDelay) { - // pull the earlier sample for the delayed channel - int earlierSample = delaySamplePointer[s] * attenuationCoefficient; - plateauAdditionOfSamples(delayedChannel[s], earlierSample * weakChannelAmplitudeRatio); - } - - int16_t currentSample = (otherAgentBuffer->getNextOutput()[s] * attenuationCoefficient); - plateauAdditionOfSamples(goodChannel[s], currentSample); - - if (s + numSamplesDelay < BUFFER_LENGTH_SAMPLES_PER_CHANNEL) { - plateauAdditionOfSamples(delayedChannel[s + numSamplesDelay], - currentSample * weakChannelAmplitudeRatio); - } + if (s < numSamplesDelay) { + // pull the earlier sample for the delayed channel + int earlierSample = delaySamplePointer[s] * attenuationCoefficient; + plateauAdditionOfSamples(delayedChannel[s], earlierSample * weakChannelAmplitudeRatio); + } + + int16_t currentSample = (otherAgentBuffer->getNextOutput()[s] * attenuationCoefficient); + plateauAdditionOfSamples(goodChannel[s], currentSample); + + if (s + numSamplesDelay < BUFFER_LENGTH_SAMPLES_PER_CHANNEL) { + plateauAdditionOfSamples(delayedChannel[s + numSamplesDelay], + currentSample * weakChannelAmplitudeRatio); } } } } - - agentList->getAgentSocket().send(agent->getPublicSocket(), clientMix, BUFFER_LENGTH_BYTES); - } + } + + agentList->getAgentSocket().send(agent->getPublicSocket(), clientMix, BUFFER_LENGTH_BYTES); } + // push forward the next output pointers for any audio buffers we used for (AgentList::iterator agent = agentList->begin(); agent != agentList->end(); agent++) { AudioRingBuffer* agentBuffer = (AudioRingBuffer*) agent->getLinkedData(); if (agentBuffer && agentBuffer->shouldBeAddedToMix()) { @@ -246,45 +264,8 @@ void *sendBuffer(void *args) { } } - double usecToSleep = usecTimestamp(&startTime) + (++nextFrame * BUFFER_SEND_INTERVAL_USECS) - usecTimestampNow(); - - if (usecToSleep > 0) { - usleep(usecToSleep); - } else { - std::cout << "Took too much time, not sleeping!\n"; - } - } - - pthread_exit(0); -} - -void attachNewBufferToAgent(Agent *newAgent) { - if (newAgent->getLinkedData() == NULL) { - newAgent->setLinkedData(new AudioRingBuffer(RING_BUFFER_SAMPLES, BUFFER_LENGTH_SAMPLES_PER_CHANNEL)); - } -} - -int main(int argc, const char* argv[]) { - setvbuf(stdout, NULL, _IOLBF, 0); - - AgentList* agentList = AgentList::createInstance(AGENT_TYPE_AUDIO_MIXER, MIXER_LISTEN_PORT); - - ssize_t receivedBytes = 0; - - agentList->linkedDataCreateCallback = attachNewBufferToAgent; - - agentList->startSilentAgentRemovalThread(); - agentList->startDomainServerCheckInThread(); - - unsigned char *packetData = new unsigned char[MAX_PACKET_SIZE]; - - pthread_t sendBufferThread; - pthread_create(&sendBufferThread, NULL, sendBuffer, NULL); - - sockaddr *agentAddress = new sockaddr; - - while (true) { - if(agentList->getAgentSocket().receive(agentAddress, packetData, &receivedBytes)) { + // pull any new audio data from agents off of the network stack + while (agentList->getAgentSocket().receive(agentAddress, packetData, &receivedBytes)) { if (packetData[0] == PACKET_HEADER_INJECT_AUDIO) { if (agentList->addOrUpdateAgent(agentAddress, agentAddress, packetData[0], agentList->getLastAgentID())) { @@ -294,9 +275,15 @@ int main(int argc, const char* argv[]) { agentList->updateAgentWithData(agentAddress, packetData, receivedBytes); } } + + double usecToSleep = usecTimestamp(&startTime) + (++nextFrame * BUFFER_SEND_INTERVAL_USECS) - usecTimestampNow(); + + if (usecToSleep > 0) { + usleep(usecToSleep); + } else { + std::cout << "Took too much time, not sleeping!\n"; + } } - pthread_join(sendBufferThread, NULL); - return 0; } diff --git a/libraries/shared/src/AudioRingBuffer.cpp b/libraries/shared/src/AudioRingBuffer.cpp index a399852950..b49b65945c 100644 --- a/libraries/shared/src/AudioRingBuffer.cpp +++ b/libraries/shared/src/AudioRingBuffer.cpp @@ -10,118 +10,63 @@ #include "AudioRingBuffer.h" AudioRingBuffer::AudioRingBuffer(int ringSamples, int bufferSamples) : - ringBufferLengthSamples(ringSamples), - bufferLengthSamples(bufferSamples), - endOfLastWrite(NULL), - started(false), + _ringBufferLengthSamples(ringSamples), + _bufferLengthSamples(bufferSamples), + _endOfLastWrite(NULL), + _started(false), _shouldBeAddedToMix(false), _shouldLoopbackForAgent(false) { - buffer = new int16_t[ringBufferLengthSamples]; - nextOutput = buffer; + + _buffer = new int16_t[_ringBufferLengthSamples]; + _nextOutput = _buffer; }; AudioRingBuffer::AudioRingBuffer(const AudioRingBuffer &otherRingBuffer) { - ringBufferLengthSamples = otherRingBuffer.ringBufferLengthSamples; - bufferLengthSamples = otherRingBuffer.bufferLengthSamples; - started = otherRingBuffer.started; + _ringBufferLengthSamples = otherRingBuffer._ringBufferLengthSamples; + _bufferLengthSamples = otherRingBuffer._bufferLengthSamples; + _started = otherRingBuffer._started; _shouldBeAddedToMix = otherRingBuffer._shouldBeAddedToMix; _shouldLoopbackForAgent = otherRingBuffer._shouldLoopbackForAgent; - buffer = new int16_t[ringBufferLengthSamples]; - memcpy(buffer, otherRingBuffer.buffer, sizeof(int16_t) * ringBufferLengthSamples); + _buffer = new int16_t[_ringBufferLengthSamples]; + memcpy(_buffer, otherRingBuffer._buffer, sizeof(int16_t) * _ringBufferLengthSamples); - nextOutput = buffer + (otherRingBuffer.nextOutput - otherRingBuffer.buffer); - endOfLastWrite = buffer + (otherRingBuffer.endOfLastWrite - otherRingBuffer.buffer); + _nextOutput = _buffer + (otherRingBuffer._nextOutput - otherRingBuffer._buffer); + _endOfLastWrite = _buffer + (otherRingBuffer._endOfLastWrite - otherRingBuffer._buffer); } AudioRingBuffer::~AudioRingBuffer() { - delete[] buffer; + delete[] _buffer; }; AudioRingBuffer* AudioRingBuffer::clone() const { return new AudioRingBuffer(*this); } -int16_t* AudioRingBuffer::getNextOutput() { - return nextOutput; -} - -void AudioRingBuffer::setNextOutput(int16_t *newPointer) { - nextOutput = newPointer; -} - -int16_t* AudioRingBuffer::getEndOfLastWrite() { - return endOfLastWrite; -} - -void AudioRingBuffer::setEndOfLastWrite(int16_t *newPointer) { - endOfLastWrite = newPointer; -} - -int16_t* AudioRingBuffer::getBuffer() { - return buffer; -} - -bool AudioRingBuffer::isStarted() { - return started; -} - -void AudioRingBuffer::setStarted(bool status) { - started = status; -} - -float* AudioRingBuffer::getPosition() { - return position; -} - -void AudioRingBuffer::setPosition(float *newPosition) { - position[0] = newPosition[0]; - position[1] = newPosition[1]; - position[2] = newPosition[2]; -} - -float AudioRingBuffer::getAttenuationRatio() { - return attenuationRatio; -} - -void AudioRingBuffer::setAttenuationRatio(float newAttenuation) { - attenuationRatio = newAttenuation; -} - -float AudioRingBuffer::getBearing() { - return bearing; -} - -void AudioRingBuffer::setBearing(float newBearing) { - bearing = newBearing; -} - const int AGENT_LOOPBACK_MODIFIER = 307; int AudioRingBuffer::parseData(unsigned char* sourceBuffer, int numBytes) { - if (numBytes > (bufferLengthSamples * sizeof(int16_t))) { + if (numBytes > (_bufferLengthSamples * sizeof(int16_t))) { unsigned char *dataPtr = sourceBuffer + 1; - for (int p = 0; p < 3; p ++) { - memcpy(&position[p], dataPtr, sizeof(float)); - dataPtr += sizeof(float); - } + memcpy(&_position, dataPtr, sizeof(_position)); + dataPtr += (sizeof(_position)); unsigned int attenuationByte = *(dataPtr++); - attenuationRatio = attenuationByte / 255.0f; + _attenuationRatio = attenuationByte / 255.0f; - memcpy(&bearing, dataPtr, sizeof(float)); - dataPtr += sizeof(bearing); + memcpy(&_bearing, dataPtr, sizeof(float)); + dataPtr += sizeof(_bearing); - if (bearing > 180 || bearing < -180) { + 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; + _bearing = _bearing > 0 + ? _bearing - AGENT_LOOPBACK_MODIFIER + : _bearing + AGENT_LOOPBACK_MODIFIER; } else { _shouldLoopbackForAgent = false; } @@ -129,33 +74,33 @@ int AudioRingBuffer::parseData(unsigned char* sourceBuffer, int numBytes) { sourceBuffer = dataPtr; } - if (endOfLastWrite == NULL) { - endOfLastWrite = buffer; - } else if (diffLastWriteNextOutput() > ringBufferLengthSamples - bufferLengthSamples) { - endOfLastWrite = buffer; - nextOutput = buffer; - started = false; + if (!_endOfLastWrite) { + _endOfLastWrite = _buffer; + } else if (diffLastWriteNextOutput() > _ringBufferLengthSamples - _bufferLengthSamples) { + _endOfLastWrite = _buffer; + _nextOutput = _buffer; + _started = false; } - memcpy(endOfLastWrite, sourceBuffer, bufferLengthSamples * sizeof(int16_t)); + memcpy(_endOfLastWrite, sourceBuffer, _bufferLengthSamples * sizeof(int16_t)); - endOfLastWrite += bufferLengthSamples; + _endOfLastWrite += _bufferLengthSamples; - if (endOfLastWrite >= buffer + ringBufferLengthSamples) { - endOfLastWrite = buffer; + if (_endOfLastWrite >= _buffer + _ringBufferLengthSamples) { + _endOfLastWrite = _buffer; } return numBytes; } short AudioRingBuffer::diffLastWriteNextOutput() { - if (endOfLastWrite == NULL) { + if (!_endOfLastWrite) { return 0; } else { - short sampleDifference = endOfLastWrite - nextOutput; + short sampleDifference = _endOfLastWrite - _nextOutput; if (sampleDifference < 0) { - sampleDifference += ringBufferLengthSamples; + sampleDifference += _ringBufferLengthSamples; } return sampleDifference; diff --git a/libraries/shared/src/AudioRingBuffer.h b/libraries/shared/src/AudioRingBuffer.h index 32e4e0c8a9..fb739629c9 100644 --- a/libraries/shared/src/AudioRingBuffer.h +++ b/libraries/shared/src/AudioRingBuffer.h @@ -12,6 +12,12 @@ #include #include "AgentData.h" +struct Position { + float x; + float y; + float z; +}; + class AudioRingBuffer : public AgentData { public: AudioRingBuffer(int ringSamples, int bufferSamples); @@ -21,35 +27,36 @@ public: 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); + int16_t* getNextOutput() const { return _nextOutput; } + void setNextOutput(int16_t* nextOutput) { _nextOutput = nextOutput; } + + int16_t* getEndOfLastWrite() const { return _endOfLastWrite; } + void setEndOfLastWrite(int16_t* endOfLastWrite) { _endOfLastWrite = endOfLastWrite; } + + int16_t* getBuffer() const { return _buffer; } + + bool isStarted() const { return _started; } + void setStarted(bool started) { _started = started; } + 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); + const Position& getPosition() const { return _position; } + float getAttenuationRatio() const { return _attenuationRatio; } + float getBearing() const { return _bearing; } bool shouldLoopbackForAgent() const { return _shouldLoopbackForAgent; } 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; + int _ringBufferLengthSamples; + int _bufferLengthSamples; + Position _position; + float _attenuationRatio; + float _bearing; + int16_t* _nextOutput; + int16_t* _endOfLastWrite; + int16_t* _buffer; + bool _started; bool _shouldBeAddedToMix; bool _shouldLoopbackForAgent; };