mirror of
https://github.com/overte-org/overte.git
synced 2025-04-13 11:43:24 +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()
|
||||
&& 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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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__) */
|
||||
|
|
Loading…
Reference in a new issue