mirror of
https://github.com/overte-org/overte.git
synced 2025-07-22 21:06:24 +02:00
Merge branch 'master' of https://github.com/highfidelity/hifi into audio-rolloff
This commit is contained in:
commit
c0d0ca5066
20 changed files with 81 additions and 41 deletions
|
@ -104,6 +104,8 @@ AssignmentClient::AssignmentClient(int &argc, char **argv) :
|
||||||
// connections to AccountManager for authentication
|
// connections to AccountManager for authentication
|
||||||
connect(&AccountManager::getInstance(), &AccountManager::authRequired,
|
connect(&AccountManager::getInstance(), &AccountManager::authRequired,
|
||||||
this, &AssignmentClient::handleAuthenticationRequest);
|
this, &AssignmentClient::handleAuthenticationRequest);
|
||||||
|
|
||||||
|
NetworkAccessManager::getInstance();
|
||||||
}
|
}
|
||||||
|
|
||||||
void AssignmentClient::sendAssignmentRequest() {
|
void AssignmentClient::sendAssignmentRequest() {
|
||||||
|
|
|
@ -101,8 +101,7 @@ int AudioMixerClientData::parseData(const QByteArray& packet) {
|
||||||
|
|
||||||
if (!matchingInjectedRingBuffer) {
|
if (!matchingInjectedRingBuffer) {
|
||||||
// we don't have a matching injected audio ring buffer, so add it
|
// we don't have a matching injected audio ring buffer, so add it
|
||||||
matchingInjectedRingBuffer = new InjectedAudioRingBuffer(streamIdentifier,
|
matchingInjectedRingBuffer = new InjectedAudioRingBuffer(streamIdentifier, AudioMixer::getUseDynamicJitterBuffers());
|
||||||
AudioMixer::getUseDynamicJitterBuffers());
|
|
||||||
_ringBuffers.push_back(matchingInjectedRingBuffer);
|
_ringBuffers.push_back(matchingInjectedRingBuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -216,9 +216,13 @@ int OctreeInboundPacketProcessor::sendNackPackets() {
|
||||||
}
|
}
|
||||||
|
|
||||||
const SharedNodePointer& destinationNode = NodeList::getInstance()->getNodeHash().value(nodeUUID);
|
const SharedNodePointer& destinationNode = NodeList::getInstance()->getNodeHash().value(nodeUUID);
|
||||||
const QSet<unsigned short int>& missingSequenceNumbers = nodeStats.getIncomingEditSequenceNumberStats().getMissingSet();
|
|
||||||
|
// retrieve sequence number stats of node, prune its missing set
|
||||||
|
SequenceNumberStats& sequenceNumberStats = nodeStats.getIncomingEditSequenceNumberStats();
|
||||||
|
sequenceNumberStats.pruneMissingSet();
|
||||||
|
|
||||||
// construct nack packet(s) for this node
|
// construct nack packet(s) for this node
|
||||||
|
const QSet<unsigned short int>& missingSequenceNumbers = sequenceNumberStats.getMissingSet();
|
||||||
int numSequenceNumbersAvailable = missingSequenceNumbers.size();
|
int numSequenceNumbersAvailable = missingSequenceNumbers.size();
|
||||||
QSet<unsigned short int>::const_iterator missingSequenceNumberIterator = missingSequenceNumbers.constBegin();
|
QSet<unsigned short int>::const_iterator missingSequenceNumberIterator = missingSequenceNumbers.constBegin();
|
||||||
while (numSequenceNumbersAvailable > 0) {
|
while (numSequenceNumbersAvailable > 0) {
|
||||||
|
|
|
@ -35,6 +35,7 @@ public:
|
||||||
{ return _totalElementsInPacket == 0 ? 0 : _totalLockWaitTime / _totalElementsInPacket; }
|
{ return _totalElementsInPacket == 0 ? 0 : _totalLockWaitTime / _totalElementsInPacket; }
|
||||||
|
|
||||||
const SequenceNumberStats& getIncomingEditSequenceNumberStats() const { return _incomingEditSequenceNumberStats; }
|
const SequenceNumberStats& getIncomingEditSequenceNumberStats() const { return _incomingEditSequenceNumberStats; }
|
||||||
|
SequenceNumberStats& getIncomingEditSequenceNumberStats() { return _incomingEditSequenceNumberStats; }
|
||||||
|
|
||||||
void trackInboundPacket(unsigned short int incomingSequence, quint64 transitTime,
|
void trackInboundPacket(unsigned short int incomingSequence, quint64 transitTime,
|
||||||
int editsInPacket, quint64 processTime, quint64 lockWaitTime);
|
int editsInPacket, quint64 processTime, quint64 lockWaitTime);
|
||||||
|
|
|
@ -42,7 +42,7 @@ OctreeQueryNode::OctreeQueryNode() :
|
||||||
_lastRootTimestamp(0),
|
_lastRootTimestamp(0),
|
||||||
_myPacketType(PacketTypeUnknown),
|
_myPacketType(PacketTypeUnknown),
|
||||||
_isShuttingDown(false),
|
_isShuttingDown(false),
|
||||||
_sentPacketHistory(1000)
|
_sentPacketHistory()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -36,9 +36,12 @@ DomainServerSettingsManager::DomainServerSettingsManager() :
|
||||||
|
|
||||||
// load the existing config file to get the current values
|
// load the existing config file to get the current values
|
||||||
QFile configFile(QCoreApplication::applicationDirPath() + SETTINGS_CONFIG_FILE_RELATIVE_PATH);
|
QFile configFile(QCoreApplication::applicationDirPath() + SETTINGS_CONFIG_FILE_RELATIVE_PATH);
|
||||||
configFile.open(QIODevice::ReadOnly);
|
|
||||||
|
|
||||||
_settingsMap = QJsonDocument::fromJson(configFile.readAll()).toVariant().toMap();
|
if (configFile.exists()) {
|
||||||
|
configFile.open(QIODevice::ReadOnly);
|
||||||
|
|
||||||
|
_settingsMap = QJsonDocument::fromJson(configFile.readAll()).toVariant().toMap();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const QString DESCRIPTION_SETTINGS_KEY = "settings";
|
const QString DESCRIPTION_SETTINGS_KEY = "settings";
|
||||||
|
|
|
@ -2184,11 +2184,11 @@ int Application::sendNackPackets() {
|
||||||
_octreeSceneStatsLock.unlock();
|
_octreeSceneStatsLock.unlock();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
OctreeSceneStats& stats = _octreeServerSceneStats[nodeUUID];
|
|
||||||
|
|
||||||
// make copy of missing sequence numbers from stats
|
// get sequence number stats of node, prune its missing set, and make a copy of the missing set
|
||||||
const QSet<OCTREE_PACKET_SEQUENCE> missingSequenceNumbers =
|
SequenceNumberStats& sequenceNumberStats = _octreeServerSceneStats[nodeUUID].getIncomingOctreeSequenceNumberStats();
|
||||||
stats.getIncomingOctreeSequenceNumberStats().getMissingSet();
|
sequenceNumberStats.pruneMissingSet();
|
||||||
|
const QSet<OCTREE_PACKET_SEQUENCE> missingSequenceNumbers = sequenceNumberStats.getMissingSet();
|
||||||
|
|
||||||
_octreeSceneStatsLock.unlock();
|
_octreeSceneStatsLock.unlock();
|
||||||
|
|
||||||
|
|
|
@ -67,7 +67,7 @@ Audio::Audio(int16_t initialJitterBufferSamples, QObject* parent) :
|
||||||
_proceduralAudioOutput(NULL),
|
_proceduralAudioOutput(NULL),
|
||||||
_proceduralOutputDevice(NULL),
|
_proceduralOutputDevice(NULL),
|
||||||
_inputRingBuffer(0),
|
_inputRingBuffer(0),
|
||||||
_ringBuffer(NETWORK_BUFFER_LENGTH_BYTES_PER_CHANNEL),
|
_ringBuffer(NETWORK_BUFFER_LENGTH_SAMPLES_STEREO),
|
||||||
_isStereoInput(false),
|
_isStereoInput(false),
|
||||||
_averagedLatency(0.0),
|
_averagedLatency(0.0),
|
||||||
_measuredJitter(0),
|
_measuredJitter(0),
|
||||||
|
@ -93,7 +93,7 @@ Audio::Audio(int16_t initialJitterBufferSamples, QObject* parent) :
|
||||||
_processSpatialAudio(false),
|
_processSpatialAudio(false),
|
||||||
_spatialAudioStart(0),
|
_spatialAudioStart(0),
|
||||||
_spatialAudioFinish(0),
|
_spatialAudioFinish(0),
|
||||||
_spatialAudioRingBuffer(NETWORK_BUFFER_LENGTH_BYTES_PER_CHANNEL, true), // random access mode
|
_spatialAudioRingBuffer(NETWORK_BUFFER_LENGTH_SAMPLES_STEREO, true), // random access mode
|
||||||
_scopeEnabled(false),
|
_scopeEnabled(false),
|
||||||
_scopeEnabledPause(false),
|
_scopeEnabledPause(false),
|
||||||
_scopeInputOffset(0),
|
_scopeInputOffset(0),
|
||||||
|
|
|
@ -149,13 +149,19 @@ void DatagramProcessor::processDatagrams() {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case PacketTypeVoxelEditNack:
|
case PacketTypeVoxelEditNack:
|
||||||
application->_voxelEditSender.processNackPacket(incomingPacket);
|
if (!Menu::getInstance()->isOptionChecked(MenuOption::DisableNackPackets)) {
|
||||||
|
application->_voxelEditSender.processNackPacket(incomingPacket);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case PacketTypeParticleEditNack:
|
case PacketTypeParticleEditNack:
|
||||||
application->_particleEditSender.processNackPacket(incomingPacket);
|
if (!Menu::getInstance()->isOptionChecked(MenuOption::DisableNackPackets)) {
|
||||||
|
application->_particleEditSender.processNackPacket(incomingPacket);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case PacketTypeModelEditNack:
|
case PacketTypeModelEditNack:
|
||||||
application->_modelEditSender.processNackPacket(incomingPacket);
|
if (!Menu::getInstance()->isOptionChecked(MenuOption::DisableNackPackets)) {
|
||||||
|
application->_modelEditSender.processNackPacket(incomingPacket);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
nodeList->processNodeData(senderSockAddr, incomingPacket);
|
nodeList->processNodeData(senderSockAddr, incomingPacket);
|
||||||
|
|
|
@ -19,10 +19,11 @@
|
||||||
#include "AudioRingBuffer.h"
|
#include "AudioRingBuffer.h"
|
||||||
|
|
||||||
|
|
||||||
AudioRingBuffer::AudioRingBuffer(int numFrameSamples, bool randomAccessMode) :
|
AudioRingBuffer::AudioRingBuffer(int numFrameSamples, bool randomAccessMode, int numFramesCapacity) :
|
||||||
NodeData(),
|
NodeData(),
|
||||||
_overflowCount(0),
|
_overflowCount(0),
|
||||||
_sampleCapacity(numFrameSamples * RING_BUFFER_LENGTH_FRAMES),
|
_frameCapacity(numFramesCapacity),
|
||||||
|
_sampleCapacity(numFrameSamples * numFramesCapacity),
|
||||||
_isFull(false),
|
_isFull(false),
|
||||||
_numFrameSamples(numFrameSamples),
|
_numFrameSamples(numFrameSamples),
|
||||||
_isStarved(true),
|
_isStarved(true),
|
||||||
|
@ -48,6 +49,8 @@ AudioRingBuffer::~AudioRingBuffer() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioRingBuffer::reset() {
|
void AudioRingBuffer::reset() {
|
||||||
|
_overflowCount = 0;
|
||||||
|
_isFull = false;
|
||||||
_endOfLastWrite = _buffer;
|
_endOfLastWrite = _buffer;
|
||||||
_nextOutput = _buffer;
|
_nextOutput = _buffer;
|
||||||
_isStarved = true;
|
_isStarved = true;
|
||||||
|
@ -55,13 +58,13 @@ void AudioRingBuffer::reset() {
|
||||||
|
|
||||||
void AudioRingBuffer::resizeForFrameSize(int numFrameSamples) {
|
void AudioRingBuffer::resizeForFrameSize(int numFrameSamples) {
|
||||||
delete[] _buffer;
|
delete[] _buffer;
|
||||||
_sampleCapacity = numFrameSamples * RING_BUFFER_LENGTH_FRAMES;
|
_sampleCapacity = numFrameSamples * _frameCapacity;
|
||||||
|
_numFrameSamples = numFrameSamples;
|
||||||
_buffer = new int16_t[_sampleCapacity];
|
_buffer = new int16_t[_sampleCapacity];
|
||||||
if (_randomAccessMode) {
|
if (_randomAccessMode) {
|
||||||
memset(_buffer, 0, _sampleCapacity * sizeof(int16_t));
|
memset(_buffer, 0, _sampleCapacity * sizeof(int16_t));
|
||||||
}
|
}
|
||||||
_nextOutput = _buffer;
|
reset();
|
||||||
_endOfLastWrite = _buffer;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int AudioRingBuffer::parseData(const QByteArray& packet) {
|
int AudioRingBuffer::parseData(const QByteArray& packet) {
|
||||||
|
|
|
@ -31,15 +31,15 @@ const int NETWORK_BUFFER_LENGTH_SAMPLES_PER_CHANNEL = NETWORK_BUFFER_LENGTH_BYTE
|
||||||
const unsigned int BUFFER_SEND_INTERVAL_USECS = floorf((NETWORK_BUFFER_LENGTH_SAMPLES_PER_CHANNEL
|
const unsigned int BUFFER_SEND_INTERVAL_USECS = floorf((NETWORK_BUFFER_LENGTH_SAMPLES_PER_CHANNEL
|
||||||
/ (float) SAMPLE_RATE) * 1000 * 1000);
|
/ (float) SAMPLE_RATE) * 1000 * 1000);
|
||||||
|
|
||||||
const short RING_BUFFER_LENGTH_FRAMES = 10;
|
|
||||||
|
|
||||||
const int MAX_SAMPLE_VALUE = std::numeric_limits<int16_t>::max();
|
const int MAX_SAMPLE_VALUE = std::numeric_limits<int16_t>::max();
|
||||||
const int MIN_SAMPLE_VALUE = std::numeric_limits<int16_t>::min();
|
const int MIN_SAMPLE_VALUE = std::numeric_limits<int16_t>::min();
|
||||||
|
|
||||||
|
const int DEFAULT_RING_BUFFER_FRAME_CAPACITY = 10;
|
||||||
|
|
||||||
class AudioRingBuffer : public NodeData {
|
class AudioRingBuffer : public NodeData {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
AudioRingBuffer(int numFrameSamples, bool randomAccessMode = false);
|
AudioRingBuffer(int numFrameSamples, bool randomAccessMode = false, int numFramesCapacity = DEFAULT_RING_BUFFER_FRAME_CAPACITY);
|
||||||
~AudioRingBuffer();
|
~AudioRingBuffer();
|
||||||
|
|
||||||
void reset();
|
void reset();
|
||||||
|
@ -84,6 +84,7 @@ protected:
|
||||||
|
|
||||||
int _overflowCount; /// how many times has the ring buffer has overwritten old data
|
int _overflowCount; /// how many times has the ring buffer has overwritten old data
|
||||||
|
|
||||||
|
int _frameCapacity;
|
||||||
int _sampleCapacity;
|
int _sampleCapacity;
|
||||||
bool _isFull;
|
bool _isFull;
|
||||||
int _numFrameSamples;
|
int _numFrameSamples;
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
#include "InjectedAudioRingBuffer.h"
|
#include "InjectedAudioRingBuffer.h"
|
||||||
|
|
||||||
InjectedAudioRingBuffer::InjectedAudioRingBuffer(const QUuid& streamIdentifier, bool dynamicJitterBuffer) :
|
InjectedAudioRingBuffer::InjectedAudioRingBuffer(const QUuid& streamIdentifier, bool dynamicJitterBuffer) :
|
||||||
PositionalAudioRingBuffer(PositionalAudioRingBuffer::Injector, /* isStereo=*/ false , dynamicJitterBuffer),
|
PositionalAudioRingBuffer(PositionalAudioRingBuffer::Injector, false, dynamicJitterBuffer),
|
||||||
_streamIdentifier(streamIdentifier),
|
_streamIdentifier(streamIdentifier),
|
||||||
_radius(0.0f),
|
_radius(0.0f),
|
||||||
_attenuationRatio(0)
|
_attenuationRatio(0)
|
||||||
|
|
|
@ -85,10 +85,10 @@ quint64 InterframeTimeGapStats::getWindowMaxGap() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
PositionalAudioRingBuffer::PositionalAudioRingBuffer(PositionalAudioRingBuffer::Type type,
|
PositionalAudioRingBuffer::PositionalAudioRingBuffer(PositionalAudioRingBuffer::Type type, bool isStereo, bool dynamicJitterBuffers) :
|
||||||
bool isStereo, bool dynamicJitterBuffers) :
|
|
||||||
|
|
||||||
AudioRingBuffer(isStereo ? NETWORK_BUFFER_LENGTH_SAMPLES_STEREO : NETWORK_BUFFER_LENGTH_SAMPLES_PER_CHANNEL),
|
AudioRingBuffer(isStereo ? NETWORK_BUFFER_LENGTH_SAMPLES_STEREO : NETWORK_BUFFER_LENGTH_SAMPLES_PER_CHANNEL,
|
||||||
|
false, AUDIOMIXER_INBOUND_RING_BUFFER_FRAME_CAPACITY),
|
||||||
_type(type),
|
_type(type),
|
||||||
_position(0.0f, 0.0f, 0.0f),
|
_position(0.0f, 0.0f, 0.0f),
|
||||||
_orientation(0.0f, 0.0f, 0.0f, 0.0f),
|
_orientation(0.0f, 0.0f, 0.0f, 0.0f),
|
||||||
|
@ -98,7 +98,7 @@ PositionalAudioRingBuffer::PositionalAudioRingBuffer(PositionalAudioRingBuffer::
|
||||||
_isStereo(isStereo),
|
_isStereo(isStereo),
|
||||||
_listenerUnattenuatedZone(NULL),
|
_listenerUnattenuatedZone(NULL),
|
||||||
_desiredJitterBufferFrames(1),
|
_desiredJitterBufferFrames(1),
|
||||||
_currentJitterBufferFrames(0),
|
_currentJitterBufferFrames(-1),
|
||||||
_dynamicJitterBuffers(dynamicJitterBuffers)
|
_dynamicJitterBuffers(dynamicJitterBuffers)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -216,8 +216,8 @@ bool PositionalAudioRingBuffer::shouldBeAddedToMix() {
|
||||||
// if the buffer doesn't have a full frame of samples to take for mixing, it is starved
|
// if the buffer doesn't have a full frame of samples to take for mixing, it is starved
|
||||||
_isStarved = true;
|
_isStarved = true;
|
||||||
|
|
||||||
// set to 0 to indicate the jitter buffer is starved
|
// set to -1 to indicate the jitter buffer is starved
|
||||||
_currentJitterBufferFrames = 0;
|
_currentJitterBufferFrames = -1;
|
||||||
|
|
||||||
// reset our _shouldOutputStarveDebug to true so the next is printed
|
// reset our _shouldOutputStarveDebug to true so the next is printed
|
||||||
_shouldOutputStarveDebug = true;
|
_shouldOutputStarveDebug = true;
|
||||||
|
@ -261,7 +261,7 @@ void PositionalAudioRingBuffer::updateDesiredJitterBufferFrames() {
|
||||||
if (_desiredJitterBufferFrames < 1) {
|
if (_desiredJitterBufferFrames < 1) {
|
||||||
_desiredJitterBufferFrames = 1;
|
_desiredJitterBufferFrames = 1;
|
||||||
}
|
}
|
||||||
const int maxDesired = RING_BUFFER_LENGTH_FRAMES - 1;
|
const int maxDesired = _frameCapacity - 1;
|
||||||
if (_desiredJitterBufferFrames > maxDesired) {
|
if (_desiredJitterBufferFrames > maxDesired) {
|
||||||
_desiredJitterBufferFrames = maxDesired;
|
_desiredJitterBufferFrames = maxDesired;
|
||||||
}
|
}
|
||||||
|
|
|
@ -43,6 +43,8 @@ private:
|
||||||
bool _newWindowMaxGapAvailable;
|
bool _newWindowMaxGapAvailable;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const int AUDIOMIXER_INBOUND_RING_BUFFER_FRAME_CAPACITY = 100;
|
||||||
|
|
||||||
class PositionalAudioRingBuffer : public AudioRingBuffer {
|
class PositionalAudioRingBuffer : public AudioRingBuffer {
|
||||||
public:
|
public:
|
||||||
enum Type {
|
enum Type {
|
||||||
|
@ -103,6 +105,11 @@ protected:
|
||||||
int _desiredJitterBufferFrames;
|
int _desiredJitterBufferFrames;
|
||||||
int _currentJitterBufferFrames;
|
int _currentJitterBufferFrames;
|
||||||
bool _dynamicJitterBuffers;
|
bool _dynamicJitterBuffers;
|
||||||
|
|
||||||
|
// extra stats
|
||||||
|
int _starveCount;
|
||||||
|
int _silentFramesDropped;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // hifi_PositionalAudioRingBuffer_h
|
#endif // hifi_PositionalAudioRingBuffer_h
|
||||||
|
|
|
@ -15,10 +15,12 @@
|
||||||
#include <qbytearray.h>
|
#include <qbytearray.h>
|
||||||
#include <qvector.h>
|
#include <qvector.h>
|
||||||
|
|
||||||
|
#include "SequenceNumberStats.h"
|
||||||
|
|
||||||
class SentPacketHistory {
|
class SentPacketHistory {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
SentPacketHistory(int size = 1000);
|
SentPacketHistory(int size = MAX_REASONABLE_SEQUENCE_GAP);
|
||||||
|
|
||||||
void packetSent(uint16_t sequenceNumber, const QByteArray& packet);
|
void packetSent(uint16_t sequenceNumber, const QByteArray& packet);
|
||||||
const QByteArray* getPacket(uint16_t sequenceNumber) const;
|
const QByteArray* getPacket(uint16_t sequenceNumber) const;
|
||||||
|
|
|
@ -39,7 +39,6 @@ void SequenceNumberStats::reset() {
|
||||||
}
|
}
|
||||||
|
|
||||||
static const int UINT16_RANGE = std::numeric_limits<uint16_t>::max() + 1;
|
static const int UINT16_RANGE = std::numeric_limits<uint16_t>::max() + 1;
|
||||||
static const int MAX_REASONABLE_SEQUENCE_GAP = 1000; // this must be less than UINT16_RANGE / 2 for rollover handling to work
|
|
||||||
|
|
||||||
void SequenceNumberStats::sequenceNumberReceived(quint16 incoming, QUuid senderUUID, const bool wantExtraDebugging) {
|
void SequenceNumberStats::sequenceNumberReceived(quint16 incoming, QUuid senderUUID, const bool wantExtraDebugging) {
|
||||||
|
|
||||||
|
@ -95,6 +94,7 @@ void SequenceNumberStats::sequenceNumberReceived(quint16 incoming, QUuid senderU
|
||||||
|
|
||||||
_numEarly++;
|
_numEarly++;
|
||||||
_numLost += (incomingInt - expectedInt);
|
_numLost += (incomingInt - expectedInt);
|
||||||
|
_lastReceived = incoming;
|
||||||
|
|
||||||
// add all sequence numbers that were skipped to the missing sequence numbers list
|
// add all sequence numbers that were skipped to the missing sequence numbers list
|
||||||
for (int missingInt = expectedInt; missingInt < incomingInt; missingInt++) {
|
for (int missingInt = expectedInt; missingInt < incomingInt; missingInt++) {
|
||||||
|
@ -106,14 +106,14 @@ void SequenceNumberStats::sequenceNumberReceived(quint16 incoming, QUuid senderU
|
||||||
if (_missingSet.size() > MAX_REASONABLE_SEQUENCE_GAP) {
|
if (_missingSet.size() > MAX_REASONABLE_SEQUENCE_GAP) {
|
||||||
pruneMissingSet(wantExtraDebugging);
|
pruneMissingSet(wantExtraDebugging);
|
||||||
}
|
}
|
||||||
|
|
||||||
_lastReceived = incoming;
|
|
||||||
} else { // late
|
} else { // late
|
||||||
if (wantExtraDebugging) {
|
if (wantExtraDebugging) {
|
||||||
qDebug() << "this packet is later than expected...";
|
qDebug() << "this packet is later than expected...";
|
||||||
}
|
}
|
||||||
_numLate++;
|
_numLate++;
|
||||||
|
|
||||||
|
// do not update _lastReceived; it shouldn't become smaller
|
||||||
|
|
||||||
// remove this from missing sequence number if it's in there
|
// remove this from missing sequence number if it's in there
|
||||||
if (_missingSet.remove(incoming)) {
|
if (_missingSet.remove(incoming)) {
|
||||||
if (wantExtraDebugging) {
|
if (wantExtraDebugging) {
|
||||||
|
@ -127,8 +127,6 @@ void SequenceNumberStats::sequenceNumberReceived(quint16 incoming, QUuid senderU
|
||||||
}
|
}
|
||||||
_numDuplicate++;
|
_numDuplicate++;
|
||||||
}
|
}
|
||||||
|
|
||||||
// do not update _incomingLastSequence; it shouldn't become smaller
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,13 +15,15 @@
|
||||||
#include "SharedUtil.h"
|
#include "SharedUtil.h"
|
||||||
#include <quuid.h>
|
#include <quuid.h>
|
||||||
|
|
||||||
|
const int MAX_REASONABLE_SEQUENCE_GAP = 1000;
|
||||||
|
|
||||||
class SequenceNumberStats {
|
class SequenceNumberStats {
|
||||||
public:
|
public:
|
||||||
SequenceNumberStats();
|
SequenceNumberStats();
|
||||||
|
|
||||||
void reset();
|
void reset();
|
||||||
|
|
||||||
void sequenceNumberReceived(quint16 incoming, QUuid senderUUID = QUuid(), const bool wantExtraDebugging = false);
|
void sequenceNumberReceived(quint16 incoming, QUuid senderUUID = QUuid(), const bool wantExtraDebugging = false);
|
||||||
|
void pruneMissingSet(const bool wantExtraDebugging = false);
|
||||||
|
|
||||||
quint32 getNumReceived() const { return _numReceived; }
|
quint32 getNumReceived() const { return _numReceived; }
|
||||||
quint32 getNumUnreasonable() const { return _numUnreasonable; }
|
quint32 getNumUnreasonable() const { return _numUnreasonable; }
|
||||||
|
@ -34,8 +36,6 @@ public:
|
||||||
const QSet<quint16>& getMissingSet() const { return _missingSet; }
|
const QSet<quint16>& getMissingSet() const { return _missingSet; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void pruneMissingSet(const bool wantExtraDebugging);
|
|
||||||
|
|
||||||
quint16 _lastReceived;
|
quint16 _lastReceived;
|
||||||
QSet<quint16> _missingSet;
|
QSet<quint16> _missingSet;
|
||||||
|
|
||||||
|
|
|
@ -168,6 +168,7 @@ public:
|
||||||
float getIncomingFlightTimeAverage() { return _incomingFlightTimeAverage.getAverage(); }
|
float getIncomingFlightTimeAverage() { return _incomingFlightTimeAverage.getAverage(); }
|
||||||
|
|
||||||
const SequenceNumberStats& getIncomingOctreeSequenceNumberStats() const { return _incomingOctreeSequenceNumberStats; }
|
const SequenceNumberStats& getIncomingOctreeSequenceNumberStats() const { return _incomingOctreeSequenceNumberStats; }
|
||||||
|
SequenceNumberStats& getIncomingOctreeSequenceNumberStats() { return _incomingOctreeSequenceNumberStats; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
|
|
@ -29,7 +29,7 @@ void AudioRingBufferTests::runAllTests() {
|
||||||
int readIndexAt;
|
int readIndexAt;
|
||||||
|
|
||||||
|
|
||||||
AudioRingBuffer ringBuffer(10); // makes buffer of 100 int16_t samples
|
AudioRingBuffer ringBuffer(10, false, 10); // makes buffer of 100 int16_t samples
|
||||||
for (int T = 0; T < 300; T++) {
|
for (int T = 0; T < 300; T++) {
|
||||||
|
|
||||||
writeIndexAt = 0;
|
writeIndexAt = 0;
|
||||||
|
|
|
@ -115,6 +115,11 @@ void SequenceNumberStatsTests::earlyLateTest() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
stats.reset();
|
stats.reset();
|
||||||
|
numSent = 0;
|
||||||
|
numEarly = 0;
|
||||||
|
numLate = 0;
|
||||||
|
numLost = 0;
|
||||||
|
numRecovered = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -203,6 +208,11 @@ void SequenceNumberStatsTests::duplicateTest() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
stats.reset();
|
stats.reset();
|
||||||
|
numSent = 0;
|
||||||
|
numDuplicate = 0;
|
||||||
|
numEarly = 0;
|
||||||
|
numLate = 0;
|
||||||
|
numLost = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -263,5 +273,8 @@ void SequenceNumberStatsTests::pruneTest() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
stats.reset();
|
stats.reset();
|
||||||
|
numSent = 0;
|
||||||
|
numEarly = 0;
|
||||||
|
numLost = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue