diff --git a/assignment-client/src/audio/AudioMixerClientData.cpp b/assignment-client/src/audio/AudioMixerClientData.cpp index b55d28123f..c4199b5d37 100644 --- a/assignment-client/src/audio/AudioMixerClientData.cpp +++ b/assignment-client/src/audio/AudioMixerClientData.cpp @@ -59,7 +59,7 @@ AvatarAudioStream* AudioMixerClientData::getAvatarAudioStream() { return NULL; } -bool shouldIgnore(const SharedNodePointer self, const SharedNodePointer node, unsigned int frame) { +bool AudioMixerClientData::shouldIgnore(const SharedNodePointer self, const SharedNodePointer node, unsigned int frame) { // this is symmetric over self / node; they cache their computations to reduce work by 2x auto& localCache = _nodeSourcesIgnoreMap[node->getUUID()]; @@ -81,32 +81,32 @@ bool shouldIgnore(const SharedNodePointer self, const SharedNodePointer node, un (!self->isIgnoringNodeWithID(node->getUUID()) || (nodeData->getRequestsDomainListData() && node->getCanKick())) && (!node->isIgnoringNodeWithID(self->getUUID()) || - (getsRequestsDomainListData() && self->getCanKick()))) { + (getRequestsDomainListData() && self->getCanKick()))) { // if either node is enabling an ignore radius, check their proximity - if ((listener->isIgnoreRadiusEnabled() || node->isIgnoreRadiusEnabled())) { - auto& listenerZone = listenerData->getIgnoreZone(frame); + if ((self->isIgnoreRadiusEnabled() || node->isIgnoreRadiusEnabled())) { + auto& zone = getIgnoreZone(frame); auto& nodeZone = nodeData->getIgnoreZone(frame); - shouldIgnore = listenerBox.touches(nodeZone); + shouldIgnore = zone.touches(nodeZone); } else { shouldIgnore = false; } } - remoteCache = nodeData._nodeSourcesIgnoreMap[self->getUUID()]; + auto& remoteCache = nodeData->_nodeSourcesIgnoreMap[self->getUUID()]; // do not reset the cache until it has been used to avoid a data race if (!remoteCache.isCached) { - cache.shouldIgnore = shouldIgnore; + remoteCache.shouldIgnore = shouldIgnore; remoteCache.isCached = true; } return shouldIgnore; } -IgnoreZone& AudioMixerClientData::getIgnoreZone(unsigned int frame) { +AudioMixerClientData::IgnoreZone& AudioMixerClientData::getIgnoreZone(unsigned int frame) { // check for a memoized zone - if (frame != _ignoreZoneMemo.frame.load(std::memory_order_acquire) { - stream = getAvatarAudioStream(); + if (frame != _ignoreZoneMemo.frame.load(std::memory_order_acquire)) { + auto stream = getAvatarAudioStream(); // get the initial dimensions from the stream glm::vec3 corner = stream ? stream->getAvatarBoundingBoxCorner() : glm::vec3(0); @@ -130,10 +130,11 @@ IgnoreZone& AudioMixerClientData::getIgnoreZone(unsigned int frame) { // so take a lock and only update the memo if this call is first. // this prevents concurrent updates from invalidating the returned reference // (contingent on the preconditions listed in the header). - std::lock_guard lock(_ignoreZoneMemo.mutex); + std::lock_guard lock(_ignoreZoneMemo.mutex); if (frame != _ignoreZoneMemo.frame.load(std::memory_order_acquire)) { _ignoreZoneMemo.zone = box; unsigned int oldFrame = _ignoreZoneMemo.frame.exchange(frame, std::memory_order_release); + Q_UNUSED(oldFrame); // check the precondition assert(frame == (oldFrame + 1)); diff --git a/assignment-client/src/audio/AudioMixerClientData.h b/assignment-client/src/audio/AudioMixerClientData.h index a23bc32498..75cfa7ff18 100644 --- a/assignment-client/src/audio/AudioMixerClientData.h +++ b/assignment-client/src/audio/AudioMixerClientData.h @@ -27,7 +27,6 @@ class AudioMixerClientData : public NodeData { Q_OBJECT - using IgnoreZone = AABox; public: AudioMixerClientData(const QUuid& nodeID); @@ -107,11 +106,13 @@ public slots: void sendSelectAudioFormat(SharedNodePointer node, const QString& selectedCodecName); private: + using IgnoreZone = AABox; + // returns an ignore zone, memoized by frame (lockless if the zone is already memoized) // preconditions: // - frame is monotonically increasing // - calls are only made to getIgnoreZone(frame + 1) when there are no references left from calls to getIgnoreZone(frame) - IgnoreZone& AudioMixerClientData::getIgnoreZone(unsigned int frame); + IgnoreZone& getIgnoreZone(unsigned int frame); QReadWriteLock _streamsLock; AudioStreamMap _audioStreams; // microphone stream from avatar is stored under key of null UUID @@ -124,8 +125,8 @@ private: IgnoreZoneMemo _ignoreZoneMemo; struct IgnoreNodeData { - std::atomic flag { false }; - bool ignore { false }; + std::atomic isCached { false }; + bool shouldIgnore { false }; }; using NodeSourcesIgnoreMap = std::unordered_map; NodeSourcesIgnoreMap _nodeSourcesIgnoreMap; diff --git a/assignment-client/src/audio/AudioMixerSlave.cpp b/assignment-client/src/audio/AudioMixerSlave.cpp index cd039b3722..341f605b2d 100644 --- a/assignment-client/src/audio/AudioMixerSlave.cpp +++ b/assignment-client/src/audio/AudioMixerSlave.cpp @@ -145,7 +145,7 @@ bool AudioMixerSlave::prepareMix(const SharedNodePointer& listener) { mixStream(*listenerData, node->getUUID(), *listenerAudioStream, *nodeStream); } } - } else if (!listenerData->shouldIgnoreNode(listener, node, _frame)) { + } else if (!listenerData->shouldIgnore(listener, node, _frame)) { if (!isThrottling) { allStreams(node, &AudioMixerSlave::mixStream); } else {