add support for commandline/config value for dynamic jitter buffers

This commit is contained in:
ZappoMan 2014-06-24 10:29:38 -07:00
parent 5c188ea81e
commit 1d390faad8
11 changed files with 56 additions and 25 deletions

View file

@ -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();

View file

@ -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

View file

@ -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);
}
}

View file

@ -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) {
}

View file

@ -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:

View file

@ -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) {

View file

@ -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;

View file

@ -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)

View file

@ -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);

View file

@ -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;
}
*/
}
}

View file

@ -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