mirror of
https://thingvellir.net/git/overte
synced 2025-03-27 23:52:03 +01:00
add support for commandline/config value for dynamic jitter buffers
This commit is contained in:
parent
5c188ea81e
commit
1d390faad8
11 changed files with 56 additions and 25 deletions
|
@ -64,6 +64,8 @@ void attachNewBufferToNode(Node *newNode) {
|
|||
}
|
||||
}
|
||||
|
||||
bool AudioMixer::_useDynamicJitterBuffers = false;
|
||||
|
||||
AudioMixer::AudioMixer(const QByteArray& packet) :
|
||||
ThreadedAssignment(packet),
|
||||
_trailingSleepRatio(1.0f),
|
||||
|
@ -502,6 +504,16 @@ void AudioMixer::run() {
|
|||
<< QString("%1, %2, %3").arg(destinationCenter.x).arg(destinationCenter.y).arg(destinationCenter.z);
|
||||
}
|
||||
|
||||
// check the payload to see if we have asked for dynamicJitterBuffer support
|
||||
const QString DYNAMIC_JITTER_BUFFER_REGEX_STRING = "--dynamicJitterBuffer";
|
||||
QRegExp dynamicJitterBufferMatch(DYNAMIC_JITTER_BUFFER_REGEX_STRING);
|
||||
if (dynamicJitterBufferMatch.indexIn(_payload) != -1) {
|
||||
qDebug() << "Enable dynamic jitter buffers.";
|
||||
_useDynamicJitterBuffers = true;
|
||||
} else {
|
||||
qDebug() << "Dynamic jitter buffers disabled, using old behavior.";
|
||||
}
|
||||
|
||||
int nextFrame = 0;
|
||||
QElapsedTimer timer;
|
||||
timer.start();
|
||||
|
|
|
@ -34,6 +34,9 @@ public slots:
|
|||
void readPendingDatagrams();
|
||||
|
||||
void sendStatsPacket();
|
||||
|
||||
static bool getUseDynamicJitterBuffers() { return _useDynamicJitterBuffers; }
|
||||
|
||||
private:
|
||||
/// adds one buffer to the mix for a listening node
|
||||
void addBufferToMixForListeningNodeWithBuffer(PositionalAudioRingBuffer* bufferToAdd,
|
||||
|
@ -54,6 +57,7 @@ private:
|
|||
int _sumMixes;
|
||||
AABox* _sourceUnattenuatedZone;
|
||||
AABox* _listenerUnattenuatedZone;
|
||||
static bool _useDynamicJitterBuffers;
|
||||
};
|
||||
|
||||
#endif // hifi_AudioMixer_h
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
|
||||
#include "InjectedAudioRingBuffer.h"
|
||||
|
||||
#include "AudioMixer.h"
|
||||
#include "AudioMixerClientData.h"
|
||||
|
||||
AudioMixerClientData::AudioMixerClientData() :
|
||||
|
@ -65,7 +66,7 @@ int AudioMixerClientData::parseData(const QByteArray& packet) {
|
|||
|
||||
if (!avatarRingBuffer) {
|
||||
// we don't have an AvatarAudioRingBuffer yet, so add it
|
||||
avatarRingBuffer = new AvatarAudioRingBuffer(isStereo);
|
||||
avatarRingBuffer = new AvatarAudioRingBuffer(isStereo, AudioMixer::getUseDynamicJitterBuffers());
|
||||
_ringBuffers.push_back(avatarRingBuffer);
|
||||
}
|
||||
|
||||
|
@ -88,7 +89,8 @@ int AudioMixerClientData::parseData(const QByteArray& packet) {
|
|||
|
||||
if (!matchingInjectedRingBuffer) {
|
||||
// we don't have a matching injected audio ring buffer, so add it
|
||||
matchingInjectedRingBuffer = new InjectedAudioRingBuffer(streamIdentifier);
|
||||
matchingInjectedRingBuffer = new InjectedAudioRingBuffer(streamIdentifier,
|
||||
AudioMixer::getUseDynamicJitterBuffers());
|
||||
_ringBuffers.push_back(matchingInjectedRingBuffer);
|
||||
}
|
||||
|
||||
|
@ -146,13 +148,15 @@ QString AudioMixerClientData::getJitterBufferStats() const {
|
|||
int desiredJitterBuffer = avatarRingBuffer->getDesiredJitterBufferFrames();
|
||||
int calculatedJitterBuffer = avatarRingBuffer->getCalculatedDesiredJitterBufferFrames();
|
||||
int currentJitterBuffer = avatarRingBuffer->getCurrentJitterBufferFrames();
|
||||
int resetCount = avatarRingBuffer->getResetCount();
|
||||
int samplesAvailable = avatarRingBuffer->samplesAvailable();
|
||||
int framesAvailable = (samplesAvailable / avatarRingBuffer->getSamplesPerFrame());
|
||||
result += "mic.desired:" + QString::number(desiredJitterBuffer)
|
||||
+ " calculated:" + QString::number(calculatedJitterBuffer)
|
||||
+ " current:" + QString::number(currentJitterBuffer)
|
||||
+ " available:" + QString::number(framesAvailable)
|
||||
+ " samples:" + QString::number(samplesAvailable);
|
||||
+ " samples:" + QString::number(samplesAvailable)
|
||||
+ " resets:" + QString::number(resetCount);
|
||||
} else {
|
||||
result = "mic unknown";
|
||||
}
|
||||
|
@ -162,13 +166,15 @@ QString AudioMixerClientData::getJitterBufferStats() const {
|
|||
int desiredJitterBuffer = _ringBuffers[i]->getDesiredJitterBufferFrames();
|
||||
int calculatedJitterBuffer = _ringBuffers[i]->getCalculatedDesiredJitterBufferFrames();
|
||||
int currentJitterBuffer = _ringBuffers[i]->getCurrentJitterBufferFrames();
|
||||
int resetCount = _ringBuffers[i]->getResetCount();
|
||||
int samplesAvailable = _ringBuffers[i]->samplesAvailable();
|
||||
int framesAvailable = (samplesAvailable / _ringBuffers[i]->getSamplesPerFrame());
|
||||
result += "| injected["+QString::number(i)+"].desired:" + QString::number(desiredJitterBuffer)
|
||||
+ " calculated:" + QString::number(calculatedJitterBuffer)
|
||||
+ " current:" + QString::number(currentJitterBuffer)
|
||||
+ " available:" + QString::number(framesAvailable)
|
||||
+ " samples:" + QString::number(samplesAvailable);
|
||||
+ " samples:" + QString::number(samplesAvailable)
|
||||
+ " resets:" + QString::number(resetCount);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -13,8 +13,8 @@
|
|||
|
||||
#include "AvatarAudioRingBuffer.h"
|
||||
|
||||
AvatarAudioRingBuffer::AvatarAudioRingBuffer(bool isStereo) :
|
||||
PositionalAudioRingBuffer(PositionalAudioRingBuffer::Microphone, isStereo) {
|
||||
AvatarAudioRingBuffer::AvatarAudioRingBuffer(bool isStereo, bool dynamicJitterBuffer) :
|
||||
PositionalAudioRingBuffer(PositionalAudioRingBuffer::Microphone, isStereo, dynamicJitterBuffer) {
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
|
||||
class AvatarAudioRingBuffer : public PositionalAudioRingBuffer {
|
||||
public:
|
||||
AvatarAudioRingBuffer(bool isStereo = false);
|
||||
AvatarAudioRingBuffer(bool isStereo = false, bool dynamicJitterBuffer = false);
|
||||
|
||||
int parseData(const QByteArray& packet);
|
||||
private:
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
|
||||
AudioRingBuffer::AudioRingBuffer(int numFrameSamples, bool randomAccessMode) :
|
||||
NodeData(),
|
||||
_resetCount(0),
|
||||
_sampleCapacity(numFrameSamples * RING_BUFFER_LENGTH_FRAMES),
|
||||
_numFrameSamples(numFrameSamples),
|
||||
_isStarved(true),
|
||||
|
@ -128,6 +129,7 @@ qint64 AudioRingBuffer::writeData(const char* data, qint64 maxSize) {
|
|||
_endOfLastWrite = _buffer;
|
||||
_nextOutput = _buffer;
|
||||
_isStarved = true;
|
||||
_resetCount++;
|
||||
}
|
||||
|
||||
if (_endOfLastWrite + samplesToCopy <= _buffer + _sampleCapacity) {
|
||||
|
|
|
@ -71,6 +71,7 @@ public:
|
|||
bool isStarved() const { return _isStarved; }
|
||||
void setIsStarved(bool isStarved) { _isStarved = isStarved; }
|
||||
|
||||
int getResetCount() const { return _resetCount; } /// how many times has the ring buffer written past the end and reset
|
||||
bool hasStarted() const { return _hasStarted; }
|
||||
|
||||
void addSilentFrame(int numSilentSamples);
|
||||
|
@ -80,6 +81,8 @@ protected:
|
|||
AudioRingBuffer& operator= (const AudioRingBuffer&);
|
||||
|
||||
int16_t* shiftedPositionAccomodatingWrap(int16_t* position, int numSamplesShift) const;
|
||||
|
||||
int _resetCount; /// how many times has the ring buffer written past the end and done a reset
|
||||
|
||||
int _sampleCapacity;
|
||||
int _numFrameSamples;
|
||||
|
|
|
@ -19,8 +19,8 @@
|
|||
|
||||
#include "InjectedAudioRingBuffer.h"
|
||||
|
||||
InjectedAudioRingBuffer::InjectedAudioRingBuffer(const QUuid& streamIdentifier) :
|
||||
PositionalAudioRingBuffer(PositionalAudioRingBuffer::Injector),
|
||||
InjectedAudioRingBuffer::InjectedAudioRingBuffer(const QUuid& streamIdentifier, bool dynamicJitterBuffer) :
|
||||
PositionalAudioRingBuffer(PositionalAudioRingBuffer::Injector, /* isStereo=*/ false , dynamicJitterBuffer),
|
||||
_streamIdentifier(streamIdentifier),
|
||||
_radius(0.0f),
|
||||
_attenuationRatio(0)
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
|
||||
class InjectedAudioRingBuffer : public PositionalAudioRingBuffer {
|
||||
public:
|
||||
InjectedAudioRingBuffer(const QUuid& streamIdentifier = QUuid());
|
||||
InjectedAudioRingBuffer(const QUuid& streamIdentifier = QUuid(), bool dynamicJitterBuffer = false);
|
||||
|
||||
int parseData(const QByteArray& packet);
|
||||
|
||||
|
|
|
@ -85,7 +85,9 @@ quint64 InterframeTimeGapStats::getWindowMaxGap() {
|
|||
}
|
||||
|
||||
|
||||
PositionalAudioRingBuffer::PositionalAudioRingBuffer(PositionalAudioRingBuffer::Type type, bool isStereo) :
|
||||
PositionalAudioRingBuffer::PositionalAudioRingBuffer(PositionalAudioRingBuffer::Type type,
|
||||
bool isStereo, bool dynamicJitterBuffers) :
|
||||
|
||||
AudioRingBuffer(isStereo ? NETWORK_BUFFER_LENGTH_SAMPLES_STEREO : NETWORK_BUFFER_LENGTH_SAMPLES_PER_CHANNEL),
|
||||
_type(type),
|
||||
_position(0.0f, 0.0f, 0.0f),
|
||||
|
@ -96,7 +98,8 @@ PositionalAudioRingBuffer::PositionalAudioRingBuffer(PositionalAudioRingBuffer::
|
|||
_isStereo(isStereo),
|
||||
_listenerUnattenuatedZone(NULL),
|
||||
_desiredJitterBufferFrames(1),
|
||||
_currentJitterBufferFrames(0)
|
||||
_currentJitterBufferFrames(0),
|
||||
_dynamicJitterBuffers(dynamicJitterBuffers)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -246,19 +249,19 @@ int PositionalAudioRingBuffer::getCalculatedDesiredJitterBufferFrames() const {
|
|||
|
||||
void PositionalAudioRingBuffer::updateDesiredJitterBufferFrames() {
|
||||
if (_interframeTimeGapStats.hasNewWindowMaxGapAvailable()) {
|
||||
|
||||
_desiredJitterBufferFrames = 1; // HACK to see if this fixes the audio silence
|
||||
/*
|
||||
const float USECS_PER_FRAME = NETWORK_BUFFER_LENGTH_SAMPLES_PER_CHANNEL * USECS_PER_SECOND / (float)SAMPLE_RATE;
|
||||
if (!_dynamicJitterBuffers) {
|
||||
_desiredJitterBufferFrames = 1; // HACK to see if this fixes the audio silence
|
||||
} else {
|
||||
const float USECS_PER_FRAME = NETWORK_BUFFER_LENGTH_SAMPLES_PER_CHANNEL * USECS_PER_SECOND / (float)SAMPLE_RATE;
|
||||
|
||||
_desiredJitterBufferFrames = ceilf((float)_interframeTimeGapStats.getWindowMaxGap() / USECS_PER_FRAME);
|
||||
if (_desiredJitterBufferFrames < 1) {
|
||||
_desiredJitterBufferFrames = 1;
|
||||
_desiredJitterBufferFrames = ceilf((float)_interframeTimeGapStats.getWindowMaxGap() / USECS_PER_FRAME);
|
||||
if (_desiredJitterBufferFrames < 1) {
|
||||
_desiredJitterBufferFrames = 1;
|
||||
}
|
||||
const int maxDesired = RING_BUFFER_LENGTH_FRAMES - 1;
|
||||
if (_desiredJitterBufferFrames > maxDesired) {
|
||||
_desiredJitterBufferFrames = maxDesired;
|
||||
}
|
||||
}
|
||||
const int maxDesired = RING_BUFFER_LENGTH_FRAMES - 1;
|
||||
if (_desiredJitterBufferFrames > maxDesired) {
|
||||
_desiredJitterBufferFrames = maxDesired;
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
|
|
@ -50,7 +50,7 @@ public:
|
|||
Injector
|
||||
};
|
||||
|
||||
PositionalAudioRingBuffer(PositionalAudioRingBuffer::Type type, bool isStereo = false);
|
||||
PositionalAudioRingBuffer(PositionalAudioRingBuffer::Type type, bool isStereo = false, bool dynamicJitterBuffers = false);
|
||||
|
||||
int parseData(const QByteArray& packet);
|
||||
int parsePositionalData(const QByteArray& positionalByteArray);
|
||||
|
@ -102,6 +102,7 @@ protected:
|
|||
InterframeTimeGapStats _interframeTimeGapStats;
|
||||
int _desiredJitterBufferFrames;
|
||||
int _currentJitterBufferFrames;
|
||||
bool _dynamicJitterBuffers;
|
||||
};
|
||||
|
||||
#endif // hifi_PositionalAudioRingBuffer_h
|
||||
|
|
Loading…
Reference in a new issue