From ccedb1bd207c4702d58dacc11f3a0a21aaf81338 Mon Sep 17 00:00:00 2001 From: wangyix Date: Tue, 29 Jul 2014 10:40:01 -0700 Subject: [PATCH] forgot some code in checkBuffersBeforeFrameSend corrected updateLastPopOutputTrailingLoudness behavior to match what the old code did. --- assignment-client/src/audio/AudioMixer.cpp | 20 ++++++------- .../src/audio/AudioMixerClientData.cpp | 17 +++++++++-- .../src/audio/AudioMixerClientData.h | 2 +- libraries/audio/src/AudioRingBuffer.cpp | 29 ++++++++++++------- libraries/audio/src/AudioRingBuffer.h | 10 +++++-- libraries/audio/src/PositionalAudioStream.cpp | 22 +++++--------- libraries/audio/src/PositionalAudioStream.h | 15 ++-------- 7 files changed, 64 insertions(+), 51 deletions(-) diff --git a/assignment-client/src/audio/AudioMixer.cpp b/assignment-client/src/audio/AudioMixer.cpp index d3ec39ace1..d8d9006a1d 100644 --- a/assignment-client/src/audio/AudioMixer.cpp +++ b/assignment-client/src/audio/AudioMixer.cpp @@ -113,7 +113,7 @@ void AudioMixer::addStreamToMixForListeningNodeWithStream(PositionalAudioStream* distanceBetween = EPSILON; } - if (streamToAdd->getNextOutputTrailingLoudness() / distanceBetween <= _minAudibilityThreshold) { + if (streamToAdd->getLastPopOutputTrailingLoudness() / distanceBetween <= _minAudibilityThreshold) { // according to mixer performance we have decided this does not get to be mixed in // bail out return; @@ -284,7 +284,7 @@ void AudioMixer::prepareMixForListeningNode(Node* node) { if ((*otherNode != *node || otherNodeStream->shouldLoopbackForNode()) && otherNodeStream->lastPopSucceeded() - && otherNodeStream->getNextOutputTrailingLoudness() > 0.0f) { + && otherNodeStream->getLastPopOutputTrailingLoudness() > 0.0f) { addStreamToMixForListeningNodeWithStream(otherNodeStream, nodeAudioStream); } @@ -544,16 +544,16 @@ void AudioMixer::run() { } foreach (const SharedNodePointer& node, nodeList->getNodeHash()) { - if (node->getActiveSocket() && node->getLinkedData()) { - + if (node->getLinkedData()) { AudioMixerClientData* nodeData = (AudioMixerClientData*)node->getLinkedData(); - // request a frame from each audio stream. a pointer to the popped data is stored as a member - // in InboundAudioStream. That's how the popped audio data will be read for mixing - nodeData->audioStreamsPopFrameForMixing(); - - if (node->getType() == NodeType::Agent - && ((AudioMixerClientData*)node->getLinkedData())->getAvatarAudioStream()) { + // this function will request a frame from each audio stream. + // a pointer to the popped data is stored as a member in InboundAudioStream. + // That's how the popped audio data will be read for mixing (but only if the pop was successful) + nodeData->checkBuffersBeforeFrameSend(_sourceUnattenuatedZone, _listenerUnattenuatedZone); + + if (node->getType() == NodeType::Agent && node->getActiveSocket() + && nodeData->getAvatarAudioStream()) { prepareMixForListeningNode(node.data()); diff --git a/assignment-client/src/audio/AudioMixerClientData.cpp b/assignment-client/src/audio/AudioMixerClientData.cpp index 17e46f3692..e681a6ccbf 100644 --- a/assignment-client/src/audio/AudioMixerClientData.cpp +++ b/assignment-client/src/audio/AudioMixerClientData.cpp @@ -98,10 +98,23 @@ int AudioMixerClientData::parseData(const QByteArray& packet) { return 0; } -void AudioMixerClientData::audioStreamsPopFrameForMixing() { +void AudioMixerClientData::checkBuffersBeforeFrameSend(AABox* checkSourceZone, AABox* listenerZone) { QHash::ConstIterator i; for (i = _audioStreams.constBegin(); i != _audioStreams.constEnd(); i++) { - i.value()->popFrames(1); + PositionalAudioStream* stream = i.value(); + if (stream->popFrames(1)) { + // this is a ring buffer that is ready to go + + // calculate the trailing avg loudness for the next frame + // that would be mixed in + stream->updateLastPopOutputTrailingLoudness(); + + if (checkSourceZone && checkSourceZone->contains(stream->getPosition())) { + stream->setListenerUnattenuatedZone(listenerZone); + } else { + stream->setListenerUnattenuatedZone(NULL); + } + } } } diff --git a/assignment-client/src/audio/AudioMixerClientData.h b/assignment-client/src/audio/AudioMixerClientData.h index 287f4f7b65..80f3f9e3ca 100644 --- a/assignment-client/src/audio/AudioMixerClientData.h +++ b/assignment-client/src/audio/AudioMixerClientData.h @@ -27,7 +27,7 @@ public: int parseData(const QByteArray& packet); - void audioStreamsPopFrameForMixing(); + void checkBuffersBeforeFrameSend(AABox* checkSourceZone, AABox* listenerZone); void removeDeadInjectedStreams(); diff --git a/libraries/audio/src/AudioRingBuffer.cpp b/libraries/audio/src/AudioRingBuffer.cpp index 8dbc90883b..c687ab8648 100644 --- a/libraries/audio/src/AudioRingBuffer.cpp +++ b/libraries/audio/src/AudioRingBuffer.cpp @@ -218,17 +218,26 @@ int16_t* AudioRingBuffer::shiftedPositionAccomodatingWrap(int16_t* position, int } } -float AudioRingBuffer::getNextOutputFrameLoudness() const { +float AudioRingBuffer::getFrameLoudness(const int16_t* frameStart) const { float loudness = 0.0f; - int16_t* sampleAt = _nextOutput; - int16_t* _bufferLastAt = _buffer + _sampleCapacity - 1; - if (samplesAvailable() >= _numFrameSamples) { - for (int i = 0; i < _numFrameSamples; ++i) { - loudness += fabsf(*sampleAt); - sampleAt = sampleAt == _bufferLastAt ? _buffer : sampleAt + 1; - } - loudness /= _numFrameSamples; - loudness /= MAX_SAMPLE_VALUE; + const int16_t* sampleAt = frameStart; + const int16_t* _bufferLastAt = _buffer + _sampleCapacity - 1; + + for (int i = 0; i < _numFrameSamples; ++i) { + loudness += fabsf(*sampleAt); + sampleAt = sampleAt == _bufferLastAt ? _buffer : sampleAt + 1; } + loudness /= _numFrameSamples; + loudness /= MAX_SAMPLE_VALUE; + return loudness; } + +float AudioRingBuffer::getFrameLoudness(ConstIterator frameStart) const { + return getFrameLoudness(&(*frameStart)); +} + +float AudioRingBuffer::getNextOutputFrameLoudness() const { + return getFrameLoudness(_nextOutput); +} + diff --git a/libraries/audio/src/AudioRingBuffer.h b/libraries/audio/src/AudioRingBuffer.h index 00be17f02b..ed680b18b1 100644 --- a/libraries/audio/src/AudioRingBuffer.h +++ b/libraries/audio/src/AudioRingBuffer.h @@ -71,6 +71,10 @@ public: int getOverflowCount() const { return _overflowCount; } /// how many times has the ring buffer has overwritten old data int addSilentFrame(int numSilentSamples); + +private: + float getFrameLoudness(const int16_t* frameStart) const; + protected: // disallow copying of AudioRingBuffer objects AudioRingBuffer(const AudioRingBuffer&); @@ -106,7 +110,7 @@ public: bool operator==(const ConstIterator& rhs) { return _at == rhs._at; } bool operator!=(const ConstIterator& rhs) { return _at != rhs._at; } - int16_t operator*() { return *_at; } + const int16_t& operator*() { return *_at; } ConstIterator& operator=(const ConstIterator& rhs) { _capacity = rhs._capacity; @@ -138,7 +142,7 @@ public: return tmp; } - int16_t operator[] (int i) { + const int16_t& operator[] (int i) { return *atShiftedBy(i); } @@ -175,6 +179,8 @@ public: }; ConstIterator nextOutput() const { return ConstIterator(_buffer, _sampleCapacity, _nextOutput); } + + float getFrameLoudness(ConstIterator frameStart) const; }; #endif // hifi_AudioRingBuffer_h diff --git a/libraries/audio/src/PositionalAudioStream.cpp b/libraries/audio/src/PositionalAudioStream.cpp index b50e339185..1e465b925d 100644 --- a/libraries/audio/src/PositionalAudioStream.cpp +++ b/libraries/audio/src/PositionalAudioStream.cpp @@ -29,32 +29,26 @@ PositionalAudioStream::PositionalAudioStream(PositionalAudioStream::Type type, b _orientation(0.0f, 0.0f, 0.0f, 0.0f), _shouldLoopbackForNode(false), _isStereo(isStereo), - _nextOutputTrailingLoudness(0.0f), + _lastPopOutputTrailingLoudness(0.0f), _listenerUnattenuatedZone(NULL) { } -int PositionalAudioStream::parseData(const QByteArray& packet) { - int bytesRead = InboundAudioStream::parseData(packet); - updateNextOutputTrailingLoudness(); - return bytesRead; -} - -void PositionalAudioStream::updateNextOutputTrailingLoudness() { - float nextLoudness = _ringBuffer.getNextOutputFrameLoudness(); +void PositionalAudioStream::updateLastPopOutputTrailingLoudness() { + float lastPopLoudness = _ringBuffer.getFrameLoudness(_lastPopOutput); const int TRAILING_AVERAGE_FRAMES = 100; const float CURRENT_FRAME_RATIO = 1.0f / TRAILING_AVERAGE_FRAMES; const float PREVIOUS_FRAMES_RATIO = 1.0f - CURRENT_FRAME_RATIO; const float LOUDNESS_EPSILON = 0.000001f; - if (nextLoudness >= _nextOutputTrailingLoudness) { - _nextOutputTrailingLoudness = nextLoudness; + if (lastPopLoudness >= _lastPopOutputTrailingLoudness) { + _lastPopOutputTrailingLoudness = lastPopLoudness; } else { - _nextOutputTrailingLoudness = (_nextOutputTrailingLoudness * PREVIOUS_FRAMES_RATIO) + (CURRENT_FRAME_RATIO * nextLoudness); + _lastPopOutputTrailingLoudness = (_lastPopOutputTrailingLoudness * PREVIOUS_FRAMES_RATIO) + (CURRENT_FRAME_RATIO * lastPopLoudness); - if (_nextOutputTrailingLoudness < LOUDNESS_EPSILON) { - _nextOutputTrailingLoudness = 0; + if (_lastPopOutputTrailingLoudness < LOUDNESS_EPSILON) { + _lastPopOutputTrailingLoudness = 0; } } } diff --git a/libraries/audio/src/PositionalAudioStream.h b/libraries/audio/src/PositionalAudioStream.h index 06835b93a8..c9739d9588 100644 --- a/libraries/audio/src/PositionalAudioStream.h +++ b/libraries/audio/src/PositionalAudioStream.h @@ -29,12 +29,10 @@ public: PositionalAudioStream(PositionalAudioStream::Type type, bool isStereo = false, bool dynamicJitterBuffers = false); - int parseData(const QByteArray& packet); - virtual AudioStreamStats getAudioStreamStats() const; - void updateNextOutputTrailingLoudness(); - float getNextOutputTrailingLoudness() const { return _nextOutputTrailingLoudness; } + void updateLastPopOutputTrailingLoudness(); + float getLastPopOutputTrailingLoudness() const { return _lastPopOutputTrailingLoudness; } bool shouldLoopbackForNode() const { return _shouldLoopbackForNode; } bool isStereo() const { return _isStereo; } @@ -50,13 +48,6 @@ protected: PositionalAudioStream(const PositionalAudioStream&); PositionalAudioStream& operator= (const PositionalAudioStream&); - /// parses the info between the seq num and the audio data in the network packet and calculates - /// how many audio samples this packet contains - virtual int parseStreamProperties(PacketType type, const QByteArray& packetAfterSeqNum, int& numAudioSamples) = 0; - - /// parses the audio data in the network packet - virtual int parseAudioData(PacketType type, const QByteArray& packetAfterStreamProperties, int numAudioSamples) = 0; - int parsePositionalData(const QByteArray& positionalByteArray); protected: @@ -67,7 +58,7 @@ protected: bool _shouldLoopbackForNode; bool _isStereo; - float _nextOutputTrailingLoudness; + float _lastPopOutputTrailingLoudness; AABox* _listenerUnattenuatedZone; };