diff --git a/assignment-client/src/audio/AudioMixerSlave.cpp b/assignment-client/src/audio/AudioMixerSlave.cpp index 6d150a0dc3..29d42a9ced 100644 --- a/assignment-client/src/audio/AudioMixerSlave.cpp +++ b/assignment-client/src/audio/AudioMixerSlave.cpp @@ -129,6 +129,12 @@ bool AudioMixerSlave::prepareMix(const SharedNodePointer& listener) { AvatarAudioStream* listenerAudioStream = static_cast(listener->getLinkedData())->getAvatarAudioStream(); AudioMixerClientData* listenerData = static_cast(listener->getLinkedData()); + // if we received an invalid position from this listener, then refuse to make them a mix + // because we don't know how to do it properly + if (!listenerAudioStream->hasValidPosition()) { + return false; + } + // zero out the mix for this listener memset(_mixSamples, 0, sizeof(_mixSamples)); @@ -244,12 +250,18 @@ bool AudioMixerSlave::prepareMix(const SharedNodePointer& listener) { void AudioMixerSlave::throttleStream(AudioMixerClientData& listenerNodeData, const QUuid& sourceNodeID, const AvatarAudioStream& listeningNodeStream, const PositionalAudioStream& streamToAdd) { - addStream(listenerNodeData, sourceNodeID, listeningNodeStream, streamToAdd, true); + // only throttle this stream to the mix if it has a valid position, we won't know how to mix it otherwise + if (streamToAdd.hasValidPosition()) { + addStream(listenerNodeData, sourceNodeID, listeningNodeStream, streamToAdd, true); + } } void AudioMixerSlave::mixStream(AudioMixerClientData& listenerNodeData, const QUuid& sourceNodeID, const AvatarAudioStream& listeningNodeStream, const PositionalAudioStream& streamToAdd) { - addStream(listenerNodeData, sourceNodeID, listeningNodeStream, streamToAdd, false); + // only add the stream to the mix if it has a valid position, we won't know how to mix it otherwise + if (streamToAdd.hasValidPosition()) { + addStream(listenerNodeData, sourceNodeID, listeningNodeStream, streamToAdd, false); + } } void AudioMixerSlave::addStream(AudioMixerClientData& listenerNodeData, const QUuid& sourceNodeID, diff --git a/libraries/audio/src/AbstractAudioInterface.cpp b/libraries/audio/src/AbstractAudioInterface.cpp index 376ecddd34..3d813eafd7 100644 --- a/libraries/audio/src/AbstractAudioInterface.cpp +++ b/libraries/audio/src/AbstractAudioInterface.cpp @@ -49,6 +49,9 @@ void AbstractAudioInterface::emitAudioPacket(const void* audioData, size_t bytes audioPacket->writePrimitive(channelFlag); } + // at this point we'd better be sending the mixer a valid position, or it won't consider us for mixing + assert(!isNaN(transform.getTranslation())); + // pack the three float positions audioPacket->writePrimitive(transform.getTranslation()); // pack the orientation diff --git a/libraries/audio/src/PositionalAudioStream.cpp b/libraries/audio/src/PositionalAudioStream.cpp index f2c1b05ef7..49b34a894e 100644 --- a/libraries/audio/src/PositionalAudioStream.cpp +++ b/libraries/audio/src/PositionalAudioStream.cpp @@ -17,6 +17,7 @@ #include #include +#include #include #include #include @@ -76,6 +77,19 @@ int PositionalAudioStream::parsePositionalData(const QByteArray& positionalByteA QDataStream packetStream(positionalByteArray); packetStream.readRawData(reinterpret_cast(&_position), sizeof(_position)); + + // if the client sends us a bad position, flag it so that we don't consider this stream for mixing + if (glm::isnan(_position.x) || glm::isnan(_position.y) || glm::isnan(_position.z)) { + static const QString INVALID_POSITION_REGEX = "PositionalAudioStream unpacked invalid position for node"; + static QString repeatedMessage = LogHandler::getInstance().addRepeatedMessageRegex(INVALID_POSITION_REGEX); + + qDebug() << "PositionalAudioStream unpacked invalid position for node" << uuidStringWithoutCurlyBraces(getNodeID()); + + _hasValidPosition = false; + } else { + _hasValidPosition = true; + } + packetStream.readRawData(reinterpret_cast(&_orientation), sizeof(_orientation)); packetStream.readRawData(reinterpret_cast(&_avatarBoundingBoxCorner), sizeof(_avatarBoundingBoxCorner)); packetStream.readRawData(reinterpret_cast(&_avatarBoundingBoxScale), sizeof(_avatarBoundingBoxScale)); diff --git a/libraries/audio/src/PositionalAudioStream.h b/libraries/audio/src/PositionalAudioStream.h index c5cfa1991e..4c48ea3386 100644 --- a/libraries/audio/src/PositionalAudioStream.h +++ b/libraries/audio/src/PositionalAudioStream.h @@ -43,12 +43,15 @@ public: bool shouldLoopbackForNode() const { return _shouldLoopbackForNode; } bool isStereo() const { return _isStereo; } + PositionalAudioStream::Type getType() const { return _type; } + const glm::vec3& getPosition() const { return _position; } const glm::quat& getOrientation() const { return _orientation; } const glm::vec3& getAvatarBoundingBoxCorner() const { return _avatarBoundingBoxCorner; } const glm::vec3& getAvatarBoundingBoxScale() const { return _avatarBoundingBoxScale; } + bool hasValidPosition() const { return _hasValidPosition; } protected: // disallow copying of PositionalAudioStream objects @@ -75,6 +78,8 @@ protected: float _quietestTrailingFrameLoudness; float _quietestFrameLoudness; int _frameCounter; + + bool _hasValidPosition { false }; }; #endif // hifi_PositionalAudioStream_h