From d4ec337cae00a44718fc0d80d0c5650a583f0c52 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Thu, 23 Oct 2014 13:39:56 -0700 Subject: [PATCH] Don't send reverb data as often --- assignment-client/src/audio/AudioMixer.cpp | 58 ++++++++++++++++------ libraries/audio/src/InboundAudioStream.cpp | 28 ++++++++--- libraries/audio/src/InboundAudioStream.h | 6 +++ 3 files changed, 68 insertions(+), 24 deletions(-) diff --git a/assignment-client/src/audio/AudioMixer.cpp b/assignment-client/src/audio/AudioMixer.cpp index 8d87638434..faaebb1102 100644 --- a/assignment-client/src/audio/AudioMixer.cpp +++ b/assignment-client/src/audio/AudioMixer.cpp @@ -731,30 +731,56 @@ void AudioMixer::run() { dataAt += sizeof(quint16); // Pack stream properties - bool inAZone = false; + bool hasReverb = false; + float reverbTime; + float wetLevel; + + // find reverb properties for (int i = 0; i < _zoneReverbSettings.size(); ++i) { AudioMixerClientData* data = static_cast(node->getLinkedData()); - glm::vec3 streamPosition = data->getAvatarAudioStream()->getPosition(); + AvatarAudioStream* stream = data->getAvatarAudioStream(); + glm::vec3 streamPosition = stream->getPosition(); if (_audioZones[_zoneReverbSettings[i].zone].contains(streamPosition)) { - bool hasReverb = true; - float reverbTime = _zoneReverbSettings[i].reverbTime; - float wetLevel = _zoneReverbSettings[i].wetLevel; - - memcpy(dataAt, &hasReverb, sizeof(bool)); - dataAt += sizeof(bool); + hasReverb = true; + reverbTime = _zoneReverbSettings[i].reverbTime; + wetLevel = _zoneReverbSettings[i].wetLevel; + break; + } + } + AvatarAudioStream* stream = nodeData->getAvatarAudioStream(); + bool dataChanged = (stream->hasReverb() != hasReverb) || + (stream->hasReverb() && (stream->getRevebTime() != reverbTime || + stream->getWetLevel() != wetLevel)); + // Update stream + if (hasReverb) { + stream->setReverb(reverbTime, wetLevel); + } else { + stream->clearReverb(); + } + + // Send at change or every so often + float CHANCE_OF_SEND = 0.01; + bool sendData = dataChanged || (randFloat() < CHANCE_OF_SEND); + + unsigned char bitset = 0; + if (sendData) { + setAtBit(bitset, HAS_DATA_BIT); + if (hasReverb) { + setAtBit(bitset, HAS_REVERB_BIT); + } + + memcpy(dataAt, &bitset, sizeof(unsigned char)); + dataAt += sizeof(unsigned char); + + if (hasReverb) { memcpy(dataAt, &reverbTime, sizeof(float)); dataAt += sizeof(float); memcpy(dataAt, &wetLevel, sizeof(float)); dataAt += sizeof(float); - - inAZone = true; - break; } - } - if (!inAZone) { - bool hasReverb = false; - memcpy(dataAt, &hasReverb, sizeof(bool)); - dataAt += sizeof(bool); + } else { + memcpy(dataAt, &bitset, sizeof(unsigned char)); + dataAt += sizeof(unsigned char); } // pack mixed audio samples diff --git a/libraries/audio/src/InboundAudioStream.cpp b/libraries/audio/src/InboundAudioStream.cpp index 59578951f8..3e4a8639c6 100644 --- a/libraries/audio/src/InboundAudioStream.cpp +++ b/libraries/audio/src/InboundAudioStream.cpp @@ -13,6 +13,7 @@ #include "InboundAudioStream.h" #include "PacketHeaders.h" +#include const int STARVE_HISTORY_CAPACITY = 50; @@ -83,6 +84,12 @@ void InboundAudioStream::clearBuffer() { _currentJitterBufferFrames = 0; } +void InboundAudioStream::setReverb(float reverbTime, float wetLevel) { + _hasReverb = true; + _reverbTime = reverbTime; + _wetLevel = wetLevel; +} + void InboundAudioStream::perSecondCallbackForUpdatingStats() { _incomingSequenceNumberStats.pushStatsToHistory(); _timeGapStatsForDesiredCalcOnTooManyStarves.currentIntervalComplete(); @@ -165,14 +172,19 @@ int InboundAudioStream::parseData(const QByteArray& packet) { int InboundAudioStream::parseStreamProperties(PacketType type, const QByteArray& packetAfterSeqNum, int& numAudioSamples) { int read = 0; if (type == PacketTypeMixedAudio) { - memcpy(&_hasReverb, packetAfterSeqNum.data() + read, sizeof(bool)); - read += sizeof(bool); + char bitset; + memcpy(&bitset, packetAfterSeqNum.data() + read, sizeof(char)); + read += sizeof(char); - if (_hasReverb) { - memcpy(&_reverbTime, packetAfterSeqNum.data() + read, sizeof(float)); - read += sizeof(float); - memcpy(&_wetLevel, packetAfterSeqNum.data() + read, sizeof(float)); - read += sizeof(float); + bool hasData = oneAtBit(bitset, HAS_DATA_BIT); + if (hasData) { + _hasReverb = oneAtBit(bitset, HAS_REVERB_BIT); + if (_hasReverb) { + memcpy(&_reverbTime, packetAfterSeqNum.data() + read, sizeof(float)); + read += sizeof(float); + memcpy(&_wetLevel, packetAfterSeqNum.data() + read, sizeof(float)); + read += sizeof(float); + } } } @@ -206,7 +218,7 @@ int InboundAudioStream::writeDroppableSilentSamples(int silentSamples) { _framesAvailableStat.reset(); } - + int ret = _ringBuffer.addSilentSamples(silentSamples - numSilentFramesToDrop * samplesPerFrame); return ret; diff --git a/libraries/audio/src/InboundAudioStream.h b/libraries/audio/src/InboundAudioStream.h index 3e69db0afb..737147e2ba 100644 --- a/libraries/audio/src/InboundAudioStream.h +++ b/libraries/audio/src/InboundAudioStream.h @@ -45,6 +45,10 @@ const int DEFAULT_WINDOW_SECONDS_FOR_DESIRED_CALC_ON_TOO_MANY_STARVES = 50; const int DEFAULT_WINDOW_SECONDS_FOR_DESIRED_REDUCTION = 10; const bool DEFAULT_REPETITION_WITH_FADE = true; +// Mixed Audio bitset +const int HAS_DATA_BIT = 0; // 1st bit +const int HAS_REVERB_BIT = 1; // 2nd bit + class InboundAudioStream : public NodeData { Q_OBJECT public: @@ -158,6 +162,8 @@ public: bool hasReverb() const { return _hasReverb; } float getRevebTime() const { return _reverbTime; } float getWetLevel() const { return _wetLevel; } + void setReverb(float reverbTime, float wetLevel); + void clearReverb() { _hasReverb = false; } public slots: /// This function should be called every second for all the stats to function properly. If dynamic jitter buffers