From bc9deb5db7075e069426f22ef3caeb14cbd6cab7 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Mon, 17 Mar 2014 14:29:53 -0700 Subject: [PATCH 1/3] handle trivial case of not mixing silent audio streams --- assignment-client/src/audio/AudioMixer.cpp | 15 ++++++++------- .../src/audio/AudioMixerClientData.cpp | 11 +++++++++++ .../src/audio/AudioMixerClientData.h | 4 ++++ libraries/audio/src/AudioRingBuffer.cpp | 14 ++++++++++++++ libraries/audio/src/AudioRingBuffer.h | 2 ++ 5 files changed, 39 insertions(+), 7 deletions(-) diff --git a/assignment-client/src/audio/AudioMixer.cpp b/assignment-client/src/audio/AudioMixer.cpp index 1637f88859..be4da8870d 100644 --- a/assignment-client/src/audio/AudioMixer.cpp +++ b/assignment-client/src/audio/AudioMixer.cpp @@ -301,7 +301,8 @@ void AudioMixer::prepareMixForListeningNode(Node* node) { if ((*otherNode != *node || otherNodeBuffer->shouldLoopbackForNode()) - && otherNodeBuffer->willBeAddedToMix()) { + && otherNodeBuffer->willBeAddedToMix() + && otherNodeClientData->getNextOutputLoudness() != 0) { addBufferToMixForListeningNodeWithBuffer(otherNodeBuffer, nodeRingBuffer); } } @@ -355,12 +356,6 @@ void AudioMixer::run() { while (!_isFinished) { - QCoreApplication::processEvents(); - - if (_isFinished) { - break; - } - foreach (const SharedNodePointer& node, nodeList->getNodeHash()) { if (node->getLinkedData()) { ((AudioMixerClientData*) node->getLinkedData())->checkBuffersBeforeFrameSend(JITTER_BUFFER_SAMPLES); @@ -383,6 +378,12 @@ void AudioMixer::run() { ((AudioMixerClientData*) node->getLinkedData())->pushBuffersAfterFrameSend(); } } + + QCoreApplication::processEvents(); + + if (_isFinished) { + break; + } int usecToSleep = usecTimestamp(&startTime) + (++nextFrame * BUFFER_SEND_INTERVAL_USECS) - usecTimestampNow(); diff --git a/assignment-client/src/audio/AudioMixerClientData.cpp b/assignment-client/src/audio/AudioMixerClientData.cpp index a41889e77c..8907796094 100644 --- a/assignment-client/src/audio/AudioMixerClientData.cpp +++ b/assignment-client/src/audio/AudioMixerClientData.cpp @@ -13,6 +13,13 @@ #include "AudioMixerClientData.h" +AudioMixerClientData::AudioMixerClientData() : + _ringBuffers(), + _nextOutputLoudness(0) +{ + +} + AudioMixerClientData::~AudioMixerClientData() { for (unsigned int i = 0; i < _ringBuffers.size(); i++) { // delete this attached PositionalAudioRingBuffer @@ -80,6 +87,10 @@ void AudioMixerClientData::checkBuffersBeforeFrameSend(int jitterBufferLengthSam // this is a ring buffer that is ready to go // set its flag so we know to push its buffer when all is said and done _ringBuffers[i]->setWillBeAddedToMix(true); + + // calculate the average loudness for the next NETWORK_BUFFER_LENGTH_SAMPLES_PER_CHANNEL + // that would be mixed in + _nextOutputLoudness = _ringBuffers[i]->averageLoudnessForBoundarySamples(NETWORK_BUFFER_LENGTH_SAMPLES_PER_CHANNEL); } } } diff --git a/assignment-client/src/audio/AudioMixerClientData.h b/assignment-client/src/audio/AudioMixerClientData.h index 8031dfec3e..bb10098e23 100644 --- a/assignment-client/src/audio/AudioMixerClientData.h +++ b/assignment-client/src/audio/AudioMixerClientData.h @@ -18,16 +18,20 @@ class AudioMixerClientData : public NodeData { public: + AudioMixerClientData(); ~AudioMixerClientData(); const std::vector getRingBuffers() const { return _ringBuffers; } AvatarAudioRingBuffer* getAvatarAudioRingBuffer() const; + float getNextOutputLoudness() const { return _nextOutputLoudness; } + int parseData(const QByteArray& packet); void checkBuffersBeforeFrameSend(int jitterBufferLengthSamples); void pushBuffersAfterFrameSend(); private: std::vector _ringBuffers; + float _nextOutputLoudness; }; #endif /* defined(__hifi__AudioMixerClientData__) */ diff --git a/libraries/audio/src/AudioRingBuffer.cpp b/libraries/audio/src/AudioRingBuffer.cpp index 56f6d038c2..aed601ec39 100644 --- a/libraries/audio/src/AudioRingBuffer.cpp +++ b/libraries/audio/src/AudioRingBuffer.cpp @@ -55,6 +55,20 @@ int AudioRingBuffer::parseData(const QByteArray& packet) { return writeData(packet.data() + numBytesPacketHeader, packet.size() - numBytesPacketHeader); } +float AudioRingBuffer::averageLoudnessForBoundarySamples(int numSamples) { + // ForBoundarySamples means that we expect the number of samples not to roll of the end of the ring buffer + float averageLoudness = 0; + + for (int i = 0; i < numSamples; ++i) { + averageLoudness += _nextOutput[i]; + } + + averageLoudness /= numSamples; + averageLoudness /= MAX_SAMPLE_VALUE; + + return averageLoudness; +} + qint64 AudioRingBuffer::readSamples(int16_t* destination, qint64 maxSamples) { return readData((char*) destination, maxSamples * sizeof(int16_t)); } diff --git a/libraries/audio/src/AudioRingBuffer.h b/libraries/audio/src/AudioRingBuffer.h index 577c01a63c..c4d3f87814 100644 --- a/libraries/audio/src/AudioRingBuffer.h +++ b/libraries/audio/src/AudioRingBuffer.h @@ -49,6 +49,8 @@ public: // assume callers using this will never wrap around the end const int16_t* getNextOutput() { return _nextOutput; } const int16_t* getBuffer() { return _buffer; } + + float averageLoudnessForBoundarySamples(int numSamples); qint64 readSamples(int16_t* destination, qint64 maxSamples); qint64 writeSamples(const int16_t* source, qint64 maxSamples); From 1428d2d1de772a611baa7d182f48be5a0f014fcc Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Mon, 17 Mar 2014 14:35:04 -0700 Subject: [PATCH 2/3] take an absolute value for correct loudness --- libraries/audio/src/AudioRingBuffer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/audio/src/AudioRingBuffer.cpp b/libraries/audio/src/AudioRingBuffer.cpp index aed601ec39..d07a334d81 100644 --- a/libraries/audio/src/AudioRingBuffer.cpp +++ b/libraries/audio/src/AudioRingBuffer.cpp @@ -60,7 +60,7 @@ float AudioRingBuffer::averageLoudnessForBoundarySamples(int numSamples) { float averageLoudness = 0; for (int i = 0; i < numSamples; ++i) { - averageLoudness += _nextOutput[i]; + averageLoudness += fabsf(_nextOutput[i]); } averageLoudness /= numSamples; From c7e12824a8e03c6c06ee0fe41a18a6d0c7ebb36a Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Mon, 17 Mar 2014 14:35:26 -0700 Subject: [PATCH 3/3] clarify check for audio loudness in AudioMixer --- assignment-client/src/audio/AudioMixer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assignment-client/src/audio/AudioMixer.cpp b/assignment-client/src/audio/AudioMixer.cpp index be4da8870d..aeabd1548b 100644 --- a/assignment-client/src/audio/AudioMixer.cpp +++ b/assignment-client/src/audio/AudioMixer.cpp @@ -302,7 +302,7 @@ void AudioMixer::prepareMixForListeningNode(Node* node) { if ((*otherNode != *node || otherNodeBuffer->shouldLoopbackForNode()) && otherNodeBuffer->willBeAddedToMix() - && otherNodeClientData->getNextOutputLoudness() != 0) { + && otherNodeClientData->getNextOutputLoudness() > 0) { addBufferToMixForListeningNodeWithBuffer(otherNodeBuffer, nodeRingBuffer); } }