From ede39515d8a08eae5d65ca43ad4b74be91e2ac42 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Mon, 13 Jul 2015 14:26:10 -0700 Subject: [PATCH] update parseData for new network API --- domain-server/src/DomainServerNodeData.h | 2 +- libraries/audio-client/src/AudioClient.cpp | 65 ++++++-------------- libraries/audio-client/src/AudioClient.h | 11 ++-- libraries/audio-client/src/AudioIOStats.cpp | 17 +++-- libraries/audio-client/src/AudioIOStats.h | 6 +- libraries/audio/src/InboundAudioStream.cpp | 38 ++++++------ libraries/audio/src/InboundAudioStream.h | 8 +-- libraries/networking/src/Assignment.h | 2 +- libraries/networking/src/LimitedNodeList.cpp | 24 +++----- libraries/networking/src/LimitedNodeList.h | 3 +- libraries/networking/src/NodeData.h | 5 +- libraries/octree/src/OctreeQuery.cpp | 11 ++-- libraries/octree/src/OctreeQuery.h | 2 +- 13 files changed, 76 insertions(+), 118 deletions(-) diff --git a/domain-server/src/DomainServerNodeData.h b/domain-server/src/DomainServerNodeData.h index d2efced1ef..00c5f659ca 100644 --- a/domain-server/src/DomainServerNodeData.h +++ b/domain-server/src/DomainServerNodeData.h @@ -24,7 +24,7 @@ class DomainServerNodeData : public NodeData { public: DomainServerNodeData(); - int parseData(const QByteArray& packet) { return 0; } + int parseData(NLPacket& packet, QSharedPointer sendingNode) { return 0; } const QJsonObject& getStatsJSONObject() const { return _statsJSONObject; } diff --git a/libraries/audio-client/src/AudioClient.cpp b/libraries/audio-client/src/AudioClient.cpp index c946586074..ef7a16f983 100644 --- a/libraries/audio-client/src/AudioClient.cpp +++ b/libraries/audio-client/src/AudioClient.cpp @@ -33,7 +33,7 @@ #include #include -#ifdef __GNUC__ +#if defined(__GNUC__) && !defined(__clang__) #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wdouble-promotion" #endif @@ -142,10 +142,10 @@ AudioClient::AudioClient() : configureGverbFilter(_gverb); auto& packetReceiver = DependencyManager::get()->getPacketReceiver(); - packetReceiver.registerPacketListener(PacketType::AudioEnvironment, this, "handleAudioStreamStatsPacket"); - packetReceiver.registerPacketListener(PacketType::AudioStreamStats, this, "handleAudioEnvironmentDataPacket"); + packetReceiver.registerPacketListener(PacketType::AudioStreamStats, &_stats, "handleAudioStreamStatsPacket"); + packetReceiver.registerPacketListener(PacketType::AudioEnvironment, this, "handleAudioEnvironmentDataPacket"); + packetReceiver.registerPacketListener(PacketType::SilentAudioFrame, this, "handleAudioDataPacket"); packetReceiver.registerPacketListener(PacketType::MixedAudio, this, "handleAudioDataPacket"); - packetReceiver.registerPacketListener(PacketType::SilentAudioFrame, this, "handleSilentAudioFrame"); packetReceiver.registerPacketListener(PacketType::NoisyMute, this, "handleNoisyMutePacket"); packetReceiver.registerPacketListener(PacketType::MuteEnvironment, this, "handleMuteEnvironmentPacket"); } @@ -535,35 +535,24 @@ void AudioClient::stop() { } } -void AudioClient::handleAudioStreamStatsPacket(QSharedPointer packet, HifiSockAddr senderSockAddr) { - _stats.parseAudioStreamStatsPacket(packet->getData()); - - updateLastHeardFromAudioMixer(packet); -} - -void AudioClient::handleAudioEnvironmentDataPacket(QSharedPointer packet, HifiSockAddr senderSockAddr) { - const char* dataAt = packet->getPayload(); +void AudioClient::handleAudioEnvironmentDataPacket(QSharedPointer packet, SharedNodePointer sendingNode) { char bitset; - memcpy(&bitset, dataAt, sizeof(char)); - dataAt += sizeof(char); + packet->readPrimitive(&bitset); - bool hasReverb = oneAtBit(bitset, HAS_REVERB_BIT);; + bool hasReverb = oneAtBit(bitset, HAS_REVERB_BIT); + if (hasReverb) { float reverbTime, wetLevel; - memcpy(&reverbTime, dataAt, sizeof(float)); - dataAt += sizeof(float); - memcpy(&wetLevel, dataAt, sizeof(float)); - dataAt += sizeof(float); + packet->readPrimitive(&reverbTime); + packet->readPrimitive(&wetLevel); _receivedAudioStream.setReverb(reverbTime, wetLevel); } else { _receivedAudioStream.clearReverb(); - } - - updateLastHeardFromAudioMixer(packet); + } } -void AudioClient::handleAudioDataPacket(QSharedPointer packet, HifiSockAddr senderSockAddr) { +void AudioClient::handleAudioDataPacket(QSharedPointer packet, SharedNodePointer sendingNode) { auto nodeList = DependencyManager::get(); nodeList->flagTimeForConnectionStep(LimitedNodeList::ConnectionStep::ReceiveFirstAudioPacket); @@ -577,45 +566,29 @@ void AudioClient::handleAudioDataPacket(QSharedPointer packet, HifiSoc } // Audio output must exist and be correctly set up if we're going to process received audio - _receivedAudioStream.parseData(packet->getData()); + _receivedAudioStream.parseData(*packet, sendingNode); } - - updateLastHeardFromAudioMixer(packet); } -void AudioClient::handleSilentAudioFrame(QSharedPointer packet, HifiSockAddr senderSockAddr) { - updateLastHeardFromAudioMixer(packet); -} - -void AudioClient::handleNoisyMutePacket(QSharedPointer packet, HifiSockAddr senderSockAddr) { +void AudioClient::handleNoisyMutePacket(QSharedPointer packet, SharedNodePointer sendingNode) { if (!_muted) { toggleMute(); + // TODO reimplement on interface side //AudioScriptingInterface::getInstance().mutedByMixer(); } } -void AudioClient::handleMuteEnvironmentPacket(QSharedPointer packet, HifiSockAddr senderSockAddr) { +void AudioClient::handleMuteEnvironmentPacket(QSharedPointer packet, SharedNodePointer sendingNode) { glm::vec3 position; float radius; - - int headerSize = numBytesForPacketHeaderGivenPacketType(PacketType::MuteEnvironment); - memcpy(&position, packet->getPayload(), sizeof(glm::vec3)); - memcpy(&radius, packet->getPayload() + sizeof(glm::vec3), sizeof(float)); + + packet->readPrimitive(&position); + packet->readPrimitive(&radius); emit muteEnvironmentRequested(position, radius); } -void AudioClient::updateLastHeardFromAudioMixer(QSharedPointer& packet) { - // update having heard from the audio-mixer and record the bytes received - auto nodeList = DependencyManager::get(); - SharedNodePointer audioMixer = nodeList->nodeWithUUID(packet->getSourceID()); - if (audioMixer) { - audioMixer->setLastHeardMicrostamp(usecTimestampNow()); - } - -} - QString AudioClient::getDefaultDeviceName(QAudio::Mode mode) { QAudioDeviceInfo deviceInfo = defaultAudioDeviceForMode(mode); return deviceInfo.deviceName(); diff --git a/libraries/audio-client/src/AudioClient.h b/libraries/audio-client/src/AudioClient.h index 8812473a79..cf57b9dca1 100644 --- a/libraries/audio-client/src/AudioClient.h +++ b/libraries/audio-client/src/AudioClient.h @@ -139,12 +139,10 @@ public slots: void start(); void stop(); - void handleAudioStreamStatsPacket(QSharedPointer packet, HifiSockAddr senderSockAddr); - void handleAudioEnvironmentDataPacket(QSharedPointer packet, HifiSockAddr senderSockAddr); - void handleAudioDataPacket(QSharedPointer packet, HifiSockAddr senderSockAddr); - void handleSilentAudioFrame(QSharedPointer packet, HifiSockAddr senderSockAddr); - void handleNoisyMutePacket(QSharedPointer packet, HifiSockAddr senderSockAddr); - void handleMuteEnvironmentPacket(QSharedPointer packet, HifiSockAddr senderSockAddr); + void handleAudioEnvironmentDataPacket(QSharedPointer packet, SharedNodePointer sendingNode); + void handleAudioDataPacket(QSharedPointer packet, SharedNodePointer sendingNode); + void handleNoisyMutePacket(QSharedPointer packet, SharedNodePointer sendingNode); + void handleMuteEnvironmentPacket(QSharedPointer packet, SharedNodePointer sendingNode); void sendDownstreamAudioStatsPacket() { _stats.sendDownstreamAudioStatsPacket(); } void handleAudioInput(); @@ -214,7 +212,6 @@ private slots: void audioStateChanged(QAudio::State state); private: - void updateLastHeardFromAudioMixer(QSharedPointer& packet); void outputFormatChanged(); QByteArray firstInputFrame; diff --git a/libraries/audio-client/src/AudioIOStats.cpp b/libraries/audio-client/src/AudioIOStats.cpp index 8f7ab2ecaa..931e9badeb 100644 --- a/libraries/audio-client/src/AudioIOStats.cpp +++ b/libraries/audio-client/src/AudioIOStats.cpp @@ -63,27 +63,24 @@ void AudioIOStats::sentPacket() { _lastSentAudioPacket = now; } } -void AudioIOStats::parseAudioStreamStatsPacket(const QByteArray& packet) { - - int numBytesPacketHeader = numBytesForPacketHeader(packet); - const char* dataAt = packet.constData() + numBytesPacketHeader; +void AudioIOStats::processStreamStatsPacket(QSharedPointer packet, SharedNodePointer sendingNode) { // parse the appendFlag, clear injected audio stream stats if 0 - quint8 appendFlag = *(reinterpret_cast(dataAt)); - dataAt += sizeof(quint8); + quint8 appendFlag; + packet->readPrimitive(&appendFlag); + if (!appendFlag) { _mixerInjectedStreamStatsMap.clear(); } // parse the number of stream stats structs to follow - quint16 numStreamStats = *(reinterpret_cast(dataAt)); - dataAt += sizeof(quint16); + quint16 numStreamStats; + packet->readPrimitive(&numStreamStats); // parse the stream stats AudioStreamStats streamStats; for (quint16 i = 0; i < numStreamStats; i++) { - memcpy(&streamStats, dataAt, sizeof(AudioStreamStats)); - dataAt += sizeof(AudioStreamStats); + packet->readPrimitive(&streamStats); if (streamStats._streamType == PositionalAudioStream::Microphone) { _mixerAvatarStreamStats = streamStats; diff --git a/libraries/audio-client/src/AudioIOStats.h b/libraries/audio-client/src/AudioIOStats.h index 07bf349ad9..da0acf2fa3 100644 --- a/libraries/audio-client/src/AudioIOStats.h +++ b/libraries/audio-client/src/AudioIOStats.h @@ -17,6 +17,8 @@ #include #include +#include +#include class MixedProcessedAudioStream; @@ -41,7 +43,7 @@ public: const MovingMinMaxAvg& getPacketSentTimeGaps() const { return _packetSentTimeGaps; } void sendDownstreamAudioStatsPacket(); - void parseAudioStreamStatsPacket(const QByteArray& packet); + void processStreamStatsPacket(QSharedPointer packet, SharedNodePointer sendingNode); private: MixedProcessedAudioStream* _receivedAudioStream; @@ -57,4 +59,4 @@ private: MovingMinMaxAvg _packetSentTimeGaps; }; -#endif // hifi_AudioIOStats_h \ No newline at end of file +#endif // hifi_AudioIOStats_h diff --git a/libraries/audio/src/InboundAudioStream.cpp b/libraries/audio/src/InboundAudioStream.cpp index 928662d2e8..1c061b3aaa 100644 --- a/libraries/audio/src/InboundAudioStream.cpp +++ b/libraries/audio/src/InboundAudioStream.cpp @@ -11,6 +11,9 @@ #include +#include +#include + #include "InboundAudioStream.h" #include "PacketHeaders.h" @@ -96,28 +99,23 @@ void InboundAudioStream::perSecondCallbackForUpdatingStats() { _timeGapStatsForStatsPacket.currentIntervalComplete(); } -int InboundAudioStream::parseData(const QByteArray& packet) { - - PacketType::Value packetType = packetTypeForPacket(packet); - QUuid senderUUID = uuidFromPacketHeader(packet); - - // parse header - int numBytesHeader = numBytesForPacketHeader(packet); - const char* dataAt = packet.constData() + numBytesHeader; - int readBytes = numBytesHeader; +int InboundAudioStream::parseData(NLPacket& packet, SharedNodePointer sendingNode) { // parse sequence number and track it - quint16 sequence = *(reinterpret_cast(dataAt)); - dataAt += sizeof(quint16); - readBytes += sizeof(quint16); - SequenceNumberStats::ArrivalInfo arrivalInfo = _incomingSequenceNumberStats.sequenceNumberReceived(sequence, senderUUID); + quint16 sequence; + packet.readPrimitive(&sequence); + SequenceNumberStats::ArrivalInfo arrivalInfo = _incomingSequenceNumberStats.sequenceNumberReceived(sequence, + sendingNode->getUUID()); packetReceivedUpdateTimingStats(); int networkSamples; // parse the info after the seq number and before the audio data (the stream properties) - readBytes += parseStreamProperties(packetType, packet.mid(readBytes), networkSamples); + int propertyBytes = parseStreamProperties(packet.getType(), + QByteArray::fromRawData(packet.getPayload(), packet.pos()), + networkSamples); + packet.seek(packet.pos() + propertyBytes); // handle this packet based on its arrival status. switch (arrivalInfo._status) { @@ -132,10 +130,12 @@ int InboundAudioStream::parseData(const QByteArray& packet) { } case SequenceNumberStats::OnTime: { // Packet is on time; parse its data to the ringbuffer - if (packetType == PacketType::SilentAudioFrame) { + if (packet.getType() == PacketType::SilentAudioFrame) { writeDroppableSilentSamples(networkSamples); } else { - readBytes += parseAudioData(packetType, packet.mid(readBytes), networkSamples); + int audioBytes = parseAudioData(packet.getType(), QByteArray::fromRawData(packet.getPayload(), packet.pos()), + networkSamples); + packet.seek(packet.pos() + audioBytes); } break; } @@ -165,7 +165,7 @@ int InboundAudioStream::parseData(const QByteArray& packet) { framesAvailableChanged(); - return readBytes; + return packet.pos(); } int InboundAudioStream::parseStreamProperties(PacketType::Value type, const QByteArray& packetAfterSeqNum, int& numAudioSamples) { @@ -314,7 +314,7 @@ void InboundAudioStream::setToStarved() { starvesInWindow++; } while (starvesIterator != end); - // this starve put us over the starve threshold. update _desiredJitterBufferFrames to + // this starve put us over the starve threshold. update _desiredJitterBufferFrames to // value determined by window A. if (starvesInWindow >= _starveThreshold) { int calculatedJitterBufferFrames; @@ -398,7 +398,7 @@ void InboundAudioStream::packetReceivedUpdateTimingStats() { _timeGapStatsForDesiredReduction.update(gap); if (_timeGapStatsForDesiredCalcOnTooManyStarves.getNewStatsAvailableFlag()) { - _calculatedJitterBufferFramesUsingMaxGap = ceilf((float)_timeGapStatsForDesiredCalcOnTooManyStarves.getWindowMax() + _calculatedJitterBufferFramesUsingMaxGap = ceilf((float)_timeGapStatsForDesiredCalcOnTooManyStarves.getWindowMax() / (float) AudioConstants::NETWORK_FRAME_USECS); _timeGapStatsForDesiredCalcOnTooManyStarves.clearNewStatsAvailableFlag(); } diff --git a/libraries/audio/src/InboundAudioStream.h b/libraries/audio/src/InboundAudioStream.h index cb8494f23e..106caa11ef 100644 --- a/libraries/audio/src/InboundAudioStream.h +++ b/libraries/audio/src/InboundAudioStream.h @@ -80,7 +80,7 @@ public: {} // max number of frames over desired in the ringbuffer. - int _maxFramesOverDesired; + int _maxFramesOverDesired; // if false, _desiredJitterBufferFrames will always be _staticDesiredJitterBufferFrames. Otherwise, // either fred or philip's method will be used to calculate _desiredJitterBufferFrames based on packet timegaps. @@ -107,7 +107,7 @@ public: virtual void resetStats(); void clearBuffer(); - virtual int parseData(const QByteArray& packet); + virtual int parseData(NLPacket& packet, QSharedPointer sendingNode); int popFrames(int maxFrames, bool allOrNothing, bool starveIfNoFramesPopped = true); int popSamples(int maxSamples, bool allOrNothing, bool starveIfNoSamplesPopped = true); @@ -131,7 +131,7 @@ public: virtual AudioStreamStats getAudioStreamStats() const; /// returns the desired number of jitter buffer frames under the dyanmic jitter buffers scheme - int getCalculatedJitterBufferFrames() const { return _useStDevForJitterCalc ? + int getCalculatedJitterBufferFrames() const { return _useStDevForJitterCalc ? _calculatedJitterBufferFramesUsingStDev : _calculatedJitterBufferFramesUsingMaxGap; }; /// returns the desired number of jitter buffer frames using Philip's method @@ -217,7 +217,7 @@ protected: bool _dynamicJitterBuffers; // if false, _desiredJitterBufferFrames is locked at 1 (old behavior) int _staticDesiredJitterBufferFrames; - // if jitter buffer is dynamic, this determines what method of calculating _desiredJitterBufferFrames + // if jitter buffer is dynamic, this determines what method of calculating _desiredJitterBufferFrames // if true, Philip's timegap std dev calculation is used. Otherwise, Freddy's max timegap calculation is used bool _useStDevForJitterCalc; diff --git a/libraries/networking/src/Assignment.h b/libraries/networking/src/Assignment.h index a8338a7b5a..1e4c985583 100644 --- a/libraries/networking/src/Assignment.h +++ b/libraries/networking/src/Assignment.h @@ -86,7 +86,7 @@ public: const char* getTypeName() const; // implement parseData to return 0 so we can be a subclass of NodeData - int parseData(const QByteArray& packet) { return 0; } + int parseData(NLPacket& packet, SharedNodePointer sendingNode) { return 0; } friend QDebug operator<<(QDebug debug, const Assignment& assignment); friend QDataStream& operator<<(QDataStream &out, const Assignment& assignment); diff --git a/libraries/networking/src/LimitedNodeList.cpp b/libraries/networking/src/LimitedNodeList.cpp index 47a7a4b99b..d269db8bed 100644 --- a/libraries/networking/src/LimitedNodeList.cpp +++ b/libraries/networking/src/LimitedNodeList.cpp @@ -231,35 +231,25 @@ PacketSequenceNumber LimitedNodeList::getNextSequenceNumberForPacket(const QUuid return _packetSequenceNumbers[nodeUUID][packetType]++; } -int LimitedNodeList::updateNodeWithDataFromPacket(const SharedNodePointer& matchingNode, QSharedPointer packet) { - QMutexLocker locker(&matchingNode->getMutex()); +int LimitedNodeList::updateNodeWithDataFromPacket(QSharedPointer packet, SharedNodePointer sendingNode) { + QMutexLocker locker(&sendingNode->getMutex()); // if this was a sequence numbered packet we should store the last seq number for // a packet of this type for this node if (SEQUENCE_NUMBERED_PACKETS.contains(packet->getType())) { - matchingNode->setLastSequenceNumberForPacketType(packet->readSequenceNumber(), packet->getType()); + sendingNode->setLastSequenceNumberForPacketType(packet->readSequenceNumber(), packet->getType()); } - NodeData* linkedData = matchingNode->getLinkedData(); + NodeData* linkedData = sendingNode->getLinkedData(); if (!linkedData && linkedDataCreateCallback) { - linkedDataCreateCallback(matchingNode.data()); + linkedDataCreateCallback(sendingNode.data()); } if (linkedData) { QMutexLocker linkedDataLocker(&linkedData->getMutex()); - return linkedData->parseData(QByteArray::fromRawData(packet->getData(), packet->getSizeWithHeader())); + return linkedData->parseData(*packet, sendingNode); } - return 0; -} - -int LimitedNodeList::findNodeAndUpdateWithDataFromPacket(QSharedPointer packet) { - SharedNodePointer matchingNode = nodeWithUUID(packet->getSourceID()); - - if (matchingNode) { - return updateNodeWithDataFromPacket(matchingNode, packet); - } - - // we weren't able to match the sender address to the address we have for this node, unlock and don't parse + return 0; } diff --git a/libraries/networking/src/LimitedNodeList.h b/libraries/networking/src/LimitedNodeList.h index bfcfd61c20..44d853919a 100644 --- a/libraries/networking/src/LimitedNodeList.h +++ b/libraries/networking/src/LimitedNodeList.h @@ -155,8 +155,7 @@ public: void processKillNode(const QByteArray& datagram); - int updateNodeWithDataFromPacket(const SharedNodePointer& matchingNode, QSharedPointer packet); - int findNodeAndUpdateWithDataFromPacket(const QSharedPointer packet); + int updateNodeWithDataFromPacket(QSharedPointer packet, SharedNodePointer matchingNode); unsigned broadcastToNodes(std::unique_ptr packet, const NodeSet& destinationNodeTypes) { assert(false); return 0; } SharedNodePointer soloNodeOfType(char nodeType); diff --git a/libraries/networking/src/NodeData.h b/libraries/networking/src/NodeData.h index b865e444a9..d323c72184 100644 --- a/libraries/networking/src/NodeData.h +++ b/libraries/networking/src/NodeData.h @@ -14,6 +14,9 @@ #include #include +#include + +#include "NLPacket.h" class Node; @@ -22,7 +25,7 @@ class NodeData : public QObject { public: NodeData(); virtual ~NodeData() = 0; - virtual int parseData(const QByteArray& packet) = 0; + virtual int parseData(NLPacket& packet, QSharedPointer sendingNode) = 0; QMutex& getMutex() { return _mutex; } diff --git a/libraries/octree/src/OctreeQuery.cpp b/libraries/octree/src/OctreeQuery.cpp index 08197a587e..ea568387f5 100644 --- a/libraries/octree/src/OctreeQuery.cpp +++ b/libraries/octree/src/OctreeQuery.cpp @@ -64,13 +64,10 @@ int OctreeQuery::getBroadcastData(unsigned char* destinationBuffer) { } // called on the other nodes - assigns it to my views of the others -int OctreeQuery::parseData(const QByteArray& packet) { - - // increment to push past the packet header - int numBytesPacketHeader = numBytesForPacketHeader(packet); - - const unsigned char* startPosition = reinterpret_cast(packet.data()); - const unsigned char* sourceBuffer = startPosition + numBytesPacketHeader; +int OctreeQuery::parseData(NLPacket& packet, QSharedPointer sendingNode) { + + const unsigned char* startPosition = reinterpret_cast(packet.getPayload()); + const unsigned char* sourceBuffer = startPosition; // camera details memcpy(&_cameraPosition, sourceBuffer, sizeof(_cameraPosition)); diff --git a/libraries/octree/src/OctreeQuery.h b/libraries/octree/src/OctreeQuery.h index 3c204ff938..83cb828112 100644 --- a/libraries/octree/src/OctreeQuery.h +++ b/libraries/octree/src/OctreeQuery.h @@ -48,7 +48,7 @@ public: virtual ~OctreeQuery() {} int getBroadcastData(unsigned char* destinationBuffer); - int parseData(const QByteArray& packet); + int parseData(NLPacket& packet, QSharedPointer sendingNode); // getters for camera details const glm::vec3& getCameraPosition() const { return _cameraPosition; }