bool shouldBeSkipped(MixableStream& stream, const Node& listener, const AvatarAudioStream& listenerAudioStream, const AudioMixerClientData& listenerData) { if (stream.nodeStreamID.nodeLocalID == listener.getLocalID()) { return !stream.positionalStream->shouldLoopbackForNode(); } // grab the unprocessed ignores and unignores from and for this listener const auto& nodesIgnoredByListener = listenerData.getNewIgnoredNodeIDs(); const auto& nodesUnignoredByListener = listenerData.getNewUnignoredNodeIDs(); const auto& nodesIgnoringListener = listenerData.getNewIgnoringNodeIDs(); const auto& nodesUnignoringListener = listenerData.getNewUnignoringNodeIDs(); // this stream was previously not ignored by the listener and we have some newly ignored streams // check now if it is one of the ignored streams and flag it as such if (stream.ignoredByListener) { stream.ignoredByListener = !contains(nodesUnignoredByListener, stream.nodeStreamID.nodeID); } else { stream.ignoredByListener = contains(nodesIgnoredByListener, stream.nodeStreamID.nodeID); } if (stream.ignoringListener) { stream.ignoringListener = !contains(nodesUnignoringListener, stream.nodeStreamID.nodeID); } else { stream.ignoringListener = contains(nodesIgnoringListener, stream.nodeStreamID.nodeID); } bool listenerIsAdmin = listenerData.getRequestsDomainListData() && listener.getCanKick(); if (stream.ignoredByListener || (stream.ignoringListener && !listenerIsAdmin)) { return true; } if (!listenerData.getSoloedNodes().empty()) { return !contains(listenerData.getSoloedNodes(), stream.nodeStreamID.nodeID); } bool shouldCheckIgnoreBox = (listenerAudioStream.isIgnoreBoxEnabled() || stream.positionalStream->isIgnoreBoxEnabled()); if (shouldCheckIgnoreBox && listenerAudioStream.getIgnoreBox().touches(stream.positionalStream->getIgnoreBox())) { return true; } return false; };
bool AudioMixerClientData::shouldIgnore(const SharedNodePointer self, const SharedNodePointer node, unsigned int frame) { // this is symmetric over self / node; if computed, it is cached in the other // check the cache to avoid computation auto& cache = _nodeSourcesIgnoreMap[node->getUUID()]; if (cache.isCached()) { return cache.shouldIgnore(); } AudioMixerClientData* nodeData = static_cast<AudioMixerClientData*>(node->getLinkedData()); if (!nodeData) { return false; } // compute shouldIgnore bool shouldIgnore = true; if ( // the nodes are not ignoring each other explicitly (or are but get data regardless) (!self->isIgnoringNodeWithID(node->getUUID()) || (nodeData->getRequestsDomainListData() && node->getCanKick())) && (!node->isIgnoringNodeWithID(self->getUUID()) || (getRequestsDomainListData() && self->getCanKick()))) { // if either node is enabling an ignore radius, check their proximity if ((self->isIgnoreRadiusEnabled() || node->isIgnoreRadiusEnabled())) { auto& zone = _ignoreZone.get(frame); auto& nodeZone = nodeData->_ignoreZone.get(frame); shouldIgnore = zone.touches(nodeZone); } else { shouldIgnore = false; } } // cache in node nodeData->_nodeSourcesIgnoreMap[self->getUUID()].cache(shouldIgnore); return shouldIgnore; }