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; };