mirror of
https://github.com/HifiExperiments/overte.git
synced 2025-06-16 00:20:20 +02:00
don't replay last buffer for silent agent
This commit is contained in:
parent
47f61a2fc2
commit
cee73e4622
3 changed files with 117 additions and 123 deletions
|
@ -92,13 +92,15 @@ void *sendBuffer(void *args)
|
||||||
if (!agentBuffer->isStarted()
|
if (!agentBuffer->isStarted()
|
||||||
&& agentBuffer->diffLastWriteNextOutput() <= BUFFER_LENGTH_SAMPLES_PER_CHANNEL + JITTER_BUFFER_SAMPLES) {
|
&& agentBuffer->diffLastWriteNextOutput() <= BUFFER_LENGTH_SAMPLES_PER_CHANNEL + JITTER_BUFFER_SAMPLES) {
|
||||||
printf("Held back buffer for agent with ID %d.\n", agent->getAgentId());
|
printf("Held back buffer for agent with ID %d.\n", agent->getAgentId());
|
||||||
|
agentBuffer->setShouldBeAddedToMix(false);
|
||||||
} else if (agentBuffer->diffLastWriteNextOutput() < BUFFER_LENGTH_SAMPLES_PER_CHANNEL) {
|
} else if (agentBuffer->diffLastWriteNextOutput() < BUFFER_LENGTH_SAMPLES_PER_CHANNEL) {
|
||||||
printf("Buffer from agent with ID %d starved.\n", agent->getAgentId());
|
printf("Buffer from agent with ID %d starved.\n", agent->getAgentId());
|
||||||
agentBuffer->setStarted(false);
|
agentBuffer->setStarted(false);
|
||||||
|
agentBuffer->setShouldBeAddedToMix(false);
|
||||||
} else {
|
} else {
|
||||||
// good buffer, add this to the mix
|
// good buffer, add this to the mix
|
||||||
agentBuffer->setStarted(true);
|
agentBuffer->setStarted(true);
|
||||||
agentBuffer->setAddedToMix(true);
|
agentBuffer->setShouldBeAddedToMix(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -129,89 +131,91 @@ void *sendBuffer(void *args)
|
||||||
if (otherAgent != agent || (otherAgent == agent && agentWantsLoopback)) {
|
if (otherAgent != agent || (otherAgent == agent && agentWantsLoopback)) {
|
||||||
AudioRingBuffer* otherAgentBuffer = (AudioRingBuffer*) otherAgent->getLinkedData();
|
AudioRingBuffer* otherAgentBuffer = (AudioRingBuffer*) otherAgent->getLinkedData();
|
||||||
|
|
||||||
float *agentPosition = agentRingBuffer->getPosition();
|
if (otherAgentBuffer->shouldBeAddedToMix()) {
|
||||||
float *otherAgentPosition = otherAgentBuffer->getPosition();
|
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));
|
|
||||||
|
|
||||||
float minCoefficient = std::min(1.0f,
|
// calculate the distance to the other agent
|
||||||
powf(0.5, (logf(DISTANCE_RATIO * distanceToAgent) / logf(3)) - 1));
|
|
||||||
distanceCoeffs[lowAgentIndex][highAgentIndex] = minCoefficient;
|
// 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());
|
||||||
|
|
||||||
// get the angle from the right-angle triangle
|
if (distanceCoeffs[lowAgentIndex][highAgentIndex] == 0) {
|
||||||
float triangleAngle = atan2f(fabsf(agentPosition[2] - otherAgentPosition[2]),
|
float distanceToAgent = sqrtf(powf(agentPosition[0] - otherAgentPosition[0], 2) +
|
||||||
fabsf(agentPosition[0] - otherAgentPosition[0])) * (180 / M_PI);
|
powf(agentPosition[1] - otherAgentPosition[1], 2) +
|
||||||
float angleToSource;
|
powf(agentPosition[2] - otherAgentPosition[2], 2));
|
||||||
|
|
||||||
|
float minCoefficient = std::min(1.0f,
|
||||||
// find the angle we need for calculation based on the orientation of the triangle
|
powf(0.5, (logf(DISTANCE_RATIO * distanceToAgent) / logf(3)) - 1));
|
||||||
if (otherAgentPosition[0] > agentPosition[0]) {
|
distanceCoeffs[lowAgentIndex][highAgentIndex] = minCoefficient;
|
||||||
if (otherAgentPosition[2] > agentPosition[2]) {
|
|
||||||
angleToSource = -90 + triangleAngle - agentBearing;
|
|
||||||
} else {
|
|
||||||
angleToSource = -90 - triangleAngle - agentBearing;
|
|
||||||
}
|
}
|
||||||
} 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 {
|
} else {
|
||||||
angleToSource = 90 + triangleAngle - agentBearing;
|
if (otherAgentPosition[2] > agentPosition[2]) {
|
||||||
|
angleToSource = 90 - triangleAngle - agentBearing;
|
||||||
|
} else {
|
||||||
|
angleToSource = 90 + triangleAngle - agentBearing;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
if (angleToSource > 180) {
|
||||||
if (angleToSource > 180) {
|
angleToSource -= 360;
|
||||||
angleToSource -= 360;
|
} else if (angleToSource < -180) {
|
||||||
} else if (angleToSource < -180) {
|
angleToSource += 360;
|
||||||
angleToSource += 360;
|
}
|
||||||
}
|
|
||||||
|
angleToSource *= (M_PI / 180);
|
||||||
angleToSource *= (M_PI / 180);
|
|
||||||
|
float sinRatio = fabsf(sinf(angleToSource));
|
||||||
float sinRatio = fabsf(sinf(angleToSource));
|
int numSamplesDelay = PHASE_DELAY_AT_90 * sinRatio;
|
||||||
int numSamplesDelay = PHASE_DELAY_AT_90 * sinRatio;
|
float weakChannelAmplitudeRatio = 1 - (PHASE_AMPLITUDE_RATIO_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 *goodChannel = angleToSource > 0 ? clientMix + BUFFER_LENGTH_SAMPLES_PER_CHANNEL : clientMix;
|
int16_t *delayedChannel = angleToSource > 0 ? clientMix : clientMix + BUFFER_LENGTH_SAMPLES_PER_CHANNEL;
|
||||||
int16_t *delayedChannel = angleToSource > 0 ? clientMix : clientMix + BUFFER_LENGTH_SAMPLES_PER_CHANNEL;
|
|
||||||
|
int16_t *delaySamplePointer = otherAgentBuffer->getNextOutput() == otherAgentBuffer->getBuffer()
|
||||||
int16_t *delaySamplePointer = otherAgentBuffer->getNextOutput() == otherAgentBuffer->getBuffer()
|
|
||||||
? otherAgentBuffer->getBuffer() + RING_BUFFER_SAMPLES - numSamplesDelay
|
? otherAgentBuffer->getBuffer() + RING_BUFFER_SAMPLES - numSamplesDelay
|
||||||
: otherAgentBuffer->getNextOutput() - 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] *
|
if (s < numSamplesDelay) {
|
||||||
distanceCoeffs[lowAgentIndex][highAgentIndex] *
|
// pull the earlier sample for the delayed channel
|
||||||
otherAgentBuffer->getAttenuationRatio();
|
|
||||||
|
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] *
|
||||||
|
|
||||||
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());
|
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++) {
|
for (AgentList::iterator agent = agentList->begin(); agent != agentList->end(); agent++) {
|
||||||
AudioRingBuffer* agentBuffer = (AudioRingBuffer*) agent->getLinkedData();
|
AudioRingBuffer* agentBuffer = (AudioRingBuffer*) agent->getLinkedData();
|
||||||
if (agentBuffer->wasAddedToMix()) {
|
if (agentBuffer->shouldBeAddedToMix()) {
|
||||||
agentBuffer->setNextOutput(agentBuffer->getNextOutput() + BUFFER_LENGTH_SAMPLES_PER_CHANNEL);
|
agentBuffer->setNextOutput(agentBuffer->getNextOutput() + BUFFER_LENGTH_SAMPLES_PER_CHANNEL);
|
||||||
|
|
||||||
if (agentBuffer->getNextOutput() >= agentBuffer->getBuffer() + RING_BUFFER_SAMPLES) {
|
if (agentBuffer->getNextOutput() >= agentBuffer->getBuffer() + RING_BUFFER_SAMPLES) {
|
||||||
agentBuffer->setNextOutput(agentBuffer->getBuffer());
|
agentBuffer->setNextOutput(agentBuffer->getBuffer());
|
||||||
}
|
}
|
||||||
|
|
||||||
agentBuffer->setAddedToMix(false);
|
agentBuffer->setShouldBeAddedToMix(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,7 @@ AudioRingBuffer::AudioRingBuffer(int ringSamples, int bufferSamples) {
|
||||||
bufferLengthSamples = bufferSamples;
|
bufferLengthSamples = bufferSamples;
|
||||||
|
|
||||||
started = false;
|
started = false;
|
||||||
addedToMix = false;
|
_shouldBeAddedToMix = false;
|
||||||
|
|
||||||
endOfLastWrite = NULL;
|
endOfLastWrite = NULL;
|
||||||
|
|
||||||
|
@ -26,7 +26,7 @@ AudioRingBuffer::AudioRingBuffer(const AudioRingBuffer &otherRingBuffer) {
|
||||||
ringBufferLengthSamples = otherRingBuffer.ringBufferLengthSamples;
|
ringBufferLengthSamples = otherRingBuffer.ringBufferLengthSamples;
|
||||||
bufferLengthSamples = otherRingBuffer.bufferLengthSamples;
|
bufferLengthSamples = otherRingBuffer.bufferLengthSamples;
|
||||||
started = otherRingBuffer.started;
|
started = otherRingBuffer.started;
|
||||||
addedToMix = otherRingBuffer.addedToMix;
|
_shouldBeAddedToMix = otherRingBuffer._shouldBeAddedToMix;
|
||||||
|
|
||||||
buffer = new int16_t[ringBufferLengthSamples];
|
buffer = new int16_t[ringBufferLengthSamples];
|
||||||
memcpy(buffer, otherRingBuffer.buffer, sizeof(int16_t) * ringBufferLengthSamples);
|
memcpy(buffer, otherRingBuffer.buffer, sizeof(int16_t) * ringBufferLengthSamples);
|
||||||
|
@ -71,14 +71,6 @@ void AudioRingBuffer::setStarted(bool status) {
|
||||||
started = status;
|
started = status;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AudioRingBuffer::wasAddedToMix() {
|
|
||||||
return addedToMix;
|
|
||||||
}
|
|
||||||
|
|
||||||
void AudioRingBuffer::setAddedToMix(bool added) {
|
|
||||||
addedToMix = added;
|
|
||||||
}
|
|
||||||
|
|
||||||
float* AudioRingBuffer::getPosition() {
|
float* AudioRingBuffer::getPosition() {
|
||||||
return position;
|
return position;
|
||||||
}
|
}
|
||||||
|
@ -136,8 +128,6 @@ int AudioRingBuffer::parseData(unsigned char* sourceBuffer, int numBytes) {
|
||||||
|
|
||||||
endOfLastWrite += bufferLengthSamples;
|
endOfLastWrite += bufferLengthSamples;
|
||||||
|
|
||||||
addedToMix = false;
|
|
||||||
|
|
||||||
if (endOfLastWrite >= buffer + ringBufferLengthSamples) {
|
if (endOfLastWrite >= buffer + ringBufferLengthSamples) {
|
||||||
endOfLastWrite = buffer;
|
endOfLastWrite = buffer;
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,42 +13,42 @@
|
||||||
#include "AgentData.h"
|
#include "AgentData.h"
|
||||||
|
|
||||||
class AudioRingBuffer : public AgentData {
|
class AudioRingBuffer : public AgentData {
|
||||||
public:
|
public:
|
||||||
AudioRingBuffer(int ringSamples, int bufferSamples);
|
AudioRingBuffer(int ringSamples, int bufferSamples);
|
||||||
~AudioRingBuffer();
|
~AudioRingBuffer();
|
||||||
AudioRingBuffer(const AudioRingBuffer &otherRingBuffer);
|
AudioRingBuffer(const AudioRingBuffer &otherRingBuffer);
|
||||||
|
|
||||||
int parseData(unsigned char* sourceBuffer, int numBytes);
|
|
||||||
AudioRingBuffer* clone() const;
|
|
||||||
|
|
||||||
int16_t* getNextOutput();
|
int parseData(unsigned char* sourceBuffer, int numBytes);
|
||||||
void setNextOutput(int16_t *newPointer);
|
AudioRingBuffer* clone() const;
|
||||||
int16_t* getEndOfLastWrite();
|
|
||||||
void setEndOfLastWrite(int16_t *newPointer);
|
int16_t* getNextOutput();
|
||||||
int16_t* getBuffer();
|
void setNextOutput(int16_t *newPointer);
|
||||||
bool isStarted();
|
int16_t* getEndOfLastWrite();
|
||||||
void setStarted(bool status);
|
void setEndOfLastWrite(int16_t *newPointer);
|
||||||
bool wasAddedToMix();
|
int16_t* getBuffer();
|
||||||
void setAddedToMix(bool added);
|
bool isStarted();
|
||||||
float* getPosition();
|
void setStarted(bool status);
|
||||||
void setPosition(float newPosition[]);
|
bool shouldBeAddedToMix() const { return _shouldBeAddedToMix; }
|
||||||
float getAttenuationRatio();
|
void setShouldBeAddedToMix(bool shouldBeAddedToMix) { _shouldBeAddedToMix = shouldBeAddedToMix; }
|
||||||
void setAttenuationRatio(float newAttenuation);
|
float* getPosition();
|
||||||
float getBearing();
|
void setPosition(float newPosition[]);
|
||||||
void setBearing(float newBearing);
|
float getAttenuationRatio();
|
||||||
|
void setAttenuationRatio(float newAttenuation);
|
||||||
short diffLastWriteNextOutput();
|
float getBearing();
|
||||||
private:
|
void setBearing(float newBearing);
|
||||||
int ringBufferLengthSamples;
|
|
||||||
int bufferLengthSamples;
|
short diffLastWriteNextOutput();
|
||||||
float position[3];
|
private:
|
||||||
float attenuationRatio;
|
int ringBufferLengthSamples;
|
||||||
float bearing;
|
int bufferLengthSamples;
|
||||||
int16_t *nextOutput;
|
float position[3];
|
||||||
int16_t *endOfLastWrite;
|
float attenuationRatio;
|
||||||
int16_t *buffer;
|
float bearing;
|
||||||
bool started;
|
int16_t *nextOutput;
|
||||||
bool addedToMix;
|
int16_t *endOfLastWrite;
|
||||||
|
int16_t *buffer;
|
||||||
|
bool started;
|
||||||
|
bool _shouldBeAddedToMix;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* defined(__interface__AudioRingBuffer__) */
|
#endif /* defined(__interface__AudioRingBuffer__) */
|
||||||
|
|
Loading…
Reference in a new issue