From 711e6ca3f5b4dff11154f1db763cb1f766fb294c Mon Sep 17 00:00:00 2001 From: Brad Hefta-Gaub Date: Fri, 14 Mar 2014 17:43:55 -0700 Subject: [PATCH 01/53] clean up casts and types to fix warnings in a cleaner way --- libraries/octree/src/OctreeSceneStats.cpp | 4 ++-- libraries/octree/src/OctreeSceneStats.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/libraries/octree/src/OctreeSceneStats.cpp b/libraries/octree/src/OctreeSceneStats.cpp index 5cf906d82d..a21ab60493 100644 --- a/libraries/octree/src/OctreeSceneStats.cpp +++ b/libraries/octree/src/OctreeSceneStats.cpp @@ -919,13 +919,13 @@ void OctreeSceneStats::trackIncomingOctreePacket(const QByteArray& packet, if (wantExtraDebugging) { qDebug() << "too many _missingSequenceNumbers:" << _missingSequenceNumbers.size(); } - foreach(unsigned int missingItem, _missingSequenceNumbers) { + foreach(uint16_t missingItem, _missingSequenceNumbers) { if (wantExtraDebugging) { qDebug() << "checking item:" << missingItem << "is it in need of pruning?"; qDebug() << "(_incomingLastSequence - MAX_MISSING_SEQUENCE_OLD_AGE):" << (_incomingLastSequence - MAX_MISSING_SEQUENCE_OLD_AGE); } - if (missingItem <= (unsigned int)std::max(0, (int)_incomingLastSequence - (int)MAX_MISSING_SEQUENCE_OLD_AGE)) { + if (missingItem <= std::max(0, _incomingLastSequence - MAX_MISSING_SEQUENCE_OLD_AGE)) { if (wantExtraDebugging) { qDebug() << "pruning really old missing sequence:" << missingItem; } diff --git a/libraries/octree/src/OctreeSceneStats.h b/libraries/octree/src/OctreeSceneStats.h index 2b39b3434c..866c5d0b85 100644 --- a/libraries/octree/src/OctreeSceneStats.h +++ b/libraries/octree/src/OctreeSceneStats.h @@ -269,7 +269,7 @@ private: unsigned int _incomingLate; /// out of order later than expected unsigned int _incomingReallyLate; /// out of order and later than MAX_MISSING_SEQUENCE_OLD_AGE late unsigned int _incomingPossibleDuplicate; /// out of order possibly a duplicate - QSet _missingSequenceNumbers; + QSet _missingSequenceNumbers; SimpleMovingAverage _incomingFlightTimeAverage; // features related items From c958ae8cfbdf4d502ad9e71630dd22783af83586 Mon Sep 17 00:00:00 2001 From: Brad Hefta-Gaub Date: Fri, 14 Mar 2014 17:47:19 -0700 Subject: [PATCH 02/53] fix LocalVoxelsOverlay types to match --- interface/src/ui/LocalVoxelsOverlay.cpp | 2 +- interface/src/ui/LocalVoxelsOverlay.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/interface/src/ui/LocalVoxelsOverlay.cpp b/interface/src/ui/LocalVoxelsOverlay.cpp index 9ad1428535..7eaf9ed5c5 100644 --- a/interface/src/ui/LocalVoxelsOverlay.cpp +++ b/interface/src/ui/LocalVoxelsOverlay.cpp @@ -41,7 +41,7 @@ void LocalVoxelsOverlay::update(float deltatime) { } _tree->lockForRead(); - if (_visible && _voxelCount != (int)_tree->getOctreeElementsCount()) { + if (_visible && _voxelCount != _tree->getOctreeElementsCount()) { _voxelCount = _tree->getOctreeElementsCount(); _voxelSystem->forceRedrawEntireTree(); } diff --git a/interface/src/ui/LocalVoxelsOverlay.h b/interface/src/ui/LocalVoxelsOverlay.h index c5582a54eb..2b3ba1f535 100644 --- a/interface/src/ui/LocalVoxelsOverlay.h +++ b/interface/src/ui/LocalVoxelsOverlay.h @@ -43,7 +43,7 @@ private: QString _treeName; StrongVoxelTreePointer _tree; // so that the tree doesn't get freed - int _voxelCount; + unsigned long _voxelCount; StrongVoxelSystemPointer _voxelSystem; }; From 72449fdb6a827ab0d1f094e2f03b3f7626687771 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Fri, 14 Mar 2014 17:50:57 -0700 Subject: [PATCH 03/53] initial optimizations to AudioMixer with mmx additions --- assignment-client/src/audio/AudioMixer.cpp | 71 ++++++++++++++++------ interface/interface_en.ts | 16 ++--- libraries/audio/src/AudioRingBuffer.cpp | 3 - libraries/audio/src/AudioRingBuffer.h | 4 ++ 4 files changed, 64 insertions(+), 30 deletions(-) diff --git a/assignment-client/src/audio/AudioMixer.cpp b/assignment-client/src/audio/AudioMixer.cpp index 812acc8d70..572da1a6c4 100644 --- a/assignment-client/src/audio/AudioMixer.cpp +++ b/assignment-client/src/audio/AudioMixer.cpp @@ -6,6 +6,7 @@ // Copyright (c) 2013 HighFidelity, Inc. All rights reserved. // +#include #include #include #include @@ -157,27 +158,59 @@ void AudioMixer::addBufferToMixForListeningNodeWithBuffer(PositionalAudioRingBuf // if the bearing relative angle to source is > 0 then the delayed channel is the right one int delayedChannelOffset = (bearingRelativeAngleToSource > 0.0f) ? 1 : 0; int goodChannelOffset = delayedChannelOffset == 0 ? 1 : 0; + + const int16_t* nextOutputStart = bufferToAdd->getNextOutput(); + const int16_t* delayNextOutputStart = nextOutputStart - numSamplesDelay; + const int16_t* bufferStart = bufferToAdd->getBuffer(); + int ringBufferSampleCapacity = bufferToAdd->getSampleCapacity(); + + if (delayNextOutputStart < bufferStart) { + delayNextOutputStart = bufferStart + ringBufferSampleCapacity - numSamplesDelay; + } - for (int s = 0; s < NETWORK_BUFFER_LENGTH_SAMPLES_STEREO; s += 2) { - if ((s / 2) < numSamplesDelay) { - // pull the earlier sample for the delayed channel - int earlierSample = (*bufferToAdd)[(s / 2) - numSamplesDelay] * attenuationCoefficient * weakChannelAmplitudeRatio; - _clientSamples[s + delayedChannelOffset] = glm::clamp(_clientSamples[s + delayedChannelOffset] + earlierSample, - MIN_SAMPLE_VALUE, MAX_SAMPLE_VALUE); - } - - // pull the current sample for the good channel - int16_t currentSample = (*bufferToAdd)[s / 2] * attenuationCoefficient; - _clientSamples[s + goodChannelOffset] = glm::clamp(_clientSamples[s + goodChannelOffset] + currentSample, - MIN_SAMPLE_VALUE, MAX_SAMPLE_VALUE); - - if ((s / 2) + numSamplesDelay < NETWORK_BUFFER_LENGTH_SAMPLES_PER_CHANNEL) { - // place the current sample at the right spot in the delayed channel - int16_t clampedSample = glm::clamp((int) (_clientSamples[s + (numSamplesDelay * 2) + delayedChannelOffset] - + (currentSample * weakChannelAmplitudeRatio)), - MIN_SAMPLE_VALUE, MAX_SAMPLE_VALUE); - _clientSamples[s + (numSamplesDelay * 2) + delayedChannelOffset] = clampedSample; + int16_t correctMixSample[2], correctBufferSample[2], delayMixSample[2], delayBufferSample[2]; + int delayedChannelIndex[2]; + + float attenuationAndWeakChannelRatio = attenuationCoefficient * weakChannelAmplitudeRatio; + + for (int s = 0; s < NETWORK_BUFFER_LENGTH_SAMPLES_STEREO; s += 4) { + + // setup the int16_t variables for the two sample sets + correctBufferSample[0] = nextOutputStart[s / 2] * attenuationCoefficient; + correctBufferSample[1] = nextOutputStart[(s / 2) + 1] * attenuationCoefficient; + correctMixSample[0] = _clientSamples[s + goodChannelOffset]; + correctMixSample[1] = _clientSamples[s + goodChannelOffset + 2]; + + for (int i = 0; i < 2; ++i) { + if ((s / 2) + numSamplesDelay + i < NETWORK_BUFFER_LENGTH_SAMPLES_PER_CHANNEL) { + // for the delayed channel we fill the range (n + numSamplesDelay) to NETWORK_BUFFER_LENGTH_SAMPLES_STEREO first + delayedChannelIndex[i] = s + (numSamplesDelay * 2) + (i * 2) + delayedChannelOffset; + delayBufferSample[i] = correctBufferSample[i] * weakChannelAmplitudeRatio; + } else { + // now that the right most range has been filled, we go back to fill in numSamples delay at the beginning + int samplesBack = (s / 2) - NETWORK_BUFFER_LENGTH_SAMPLES_PER_CHANNEL + i; + + delayBufferSample[i] = delayNextOutputStart[numSamplesDelay + samplesBack] * attenuationAndWeakChannelRatio; + delayedChannelIndex[i] = (numSamplesDelay + samplesBack) * 2 + delayedChannelOffset; + } } + + delayMixSample[0] = _clientSamples[delayedChannelIndex[0]]; + delayMixSample[1] = _clientSamples[delayedChannelIndex[1]]; + + __m64 bufferSamples = _mm_set_pi16(correctMixSample[0], correctMixSample[1], delayMixSample[0], delayMixSample[1]); + __m64 addedSamples = _mm_set_pi16(correctBufferSample[0], correctBufferSample[1], + delayBufferSample[0], delayBufferSample[1]); + + // perform the MMX add (with saturation) of two correct and delayed samples + __m64 mmxResult = _mm_adds_pi16(bufferSamples, addedSamples); + int16_t* shortResults = reinterpret_cast(&mmxResult); + + // assign the results from the result of the mmx arithmetic + _clientSamples[s + goodChannelOffset] = shortResults[3]; + _clientSamples[s + goodChannelOffset + 2] = shortResults[2]; + _clientSamples[delayedChannelIndex[0]] = shortResults[1]; + _clientSamples[delayedChannelIndex[1]] = shortResults[0]; } } diff --git a/interface/interface_en.ts b/interface/interface_en.ts index 80433032dc..0be997acba 100644 --- a/interface/interface_en.ts +++ b/interface/interface_en.ts @@ -4,22 +4,22 @@ Application - + Export Voxels - + Sparse Voxel Octree Files (*.svo) - + Open Script - + JavaScript Files (*.js) @@ -113,18 +113,18 @@ Menu - + Open .ini config file - - + + Text files (*.ini) - + Save .ini config file diff --git a/libraries/audio/src/AudioRingBuffer.cpp b/libraries/audio/src/AudioRingBuffer.cpp index 9bac210c39..56f6d038c2 100644 --- a/libraries/audio/src/AudioRingBuffer.cpp +++ b/libraries/audio/src/AudioRingBuffer.cpp @@ -121,9 +121,6 @@ qint64 AudioRingBuffer::writeData(const char* data, qint64 maxSize) { } int16_t& AudioRingBuffer::operator[](const int index) { - // make sure this is a valid index - assert(index > -_sampleCapacity && index < _sampleCapacity); - return *shiftedPositionAccomodatingWrap(_nextOutput, index); } diff --git a/libraries/audio/src/AudioRingBuffer.h b/libraries/audio/src/AudioRingBuffer.h index b6e75a2e86..577c01a63c 100644 --- a/libraries/audio/src/AudioRingBuffer.h +++ b/libraries/audio/src/AudioRingBuffer.h @@ -45,6 +45,10 @@ public: int getSampleCapacity() const { return _sampleCapacity; } int parseData(const QByteArray& packet); + + // assume callers using this will never wrap around the end + const int16_t* getNextOutput() { return _nextOutput; } + const int16_t* getBuffer() { return _buffer; } qint64 readSamples(int16_t* destination, qint64 maxSamples); qint64 writeSamples(const int16_t* source, qint64 maxSamples); From 0e7e337807e61290cc568bd80a0d20f885b184b6 Mon Sep 17 00:00:00 2001 From: Brad Hefta-Gaub Date: Fri, 14 Mar 2014 18:05:40 -0700 Subject: [PATCH 04/53] fixed uninitialized variable warning --- libraries/shared/src/ShapeCollider.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/shared/src/ShapeCollider.cpp b/libraries/shared/src/ShapeCollider.cpp index 7f36d948e8..e83e6842a9 100644 --- a/libraries/shared/src/ShapeCollider.cpp +++ b/libraries/shared/src/ShapeCollider.cpp @@ -313,7 +313,7 @@ bool capsuleCapsule(const CapsuleShape* capsuleA, const CapsuleShape* capsuleB, // Since there are only three comparisons to do we unroll the sort algorithm... // and use a fifth slot as temp during swap. - if (points[4] > points[2]) { + if (points[1] > points[2]) { points[4] = points[1]; points[1] = points[2]; points[2] = points[4]; From 2766860b52fec7f3ebf519f1ed15a7767e48714f Mon Sep 17 00:00:00 2001 From: Brad Hefta-Gaub Date: Fri, 14 Mar 2014 18:11:22 -0700 Subject: [PATCH 05/53] fix some windows warnings in fsbinarystream.cpp --- interface/external/faceshift/src/fsbinarystream.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/interface/external/faceshift/src/fsbinarystream.cpp b/interface/external/faceshift/src/fsbinarystream.cpp index 0a2d41e4b3..96434afd9b 100644 --- a/interface/external/faceshift/src/fsbinarystream.cpp +++ b/interface/external/faceshift/src/fsbinarystream.cpp @@ -160,7 +160,7 @@ void fsBinaryStream::received(long int sz, const char *data) { new_end = m_end + sz; } - if (new_end > Size(m_buffer.size())) m_buffer.resize(1.5*new_end); + if (new_end > Size(m_buffer.size())) m_buffer.resize((new_end * 15 / 10)); // HIFI: to get 1.5 without warnings memcpy(&m_buffer[0] + m_end, data, sz); m_end += sz; @@ -172,7 +172,7 @@ static bool decodeInfo(fsTrackingData & _trackingData, const std::string &buffer success &= read_pod(_trackingData.m_timestamp, buffer, start); unsigned char tracking_successfull = 0; success &= read_pod( tracking_successfull, buffer, start ); - _trackingData.m_trackingSuccessful = bool(tracking_successfull); + _trackingData.m_trackingSuccessful = bool(tracking_successfull != 0); // HIFI: get rid of windows warning return success; } From c0ee3fa1f0bd1831cc8945a82d85568884bf5022 Mon Sep 17 00:00:00 2001 From: Brad Hefta-Gaub Date: Fri, 14 Mar 2014 18:14:54 -0700 Subject: [PATCH 06/53] fix unix warning --- libraries/shared/src/SharedUtil.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/libraries/shared/src/SharedUtil.cpp b/libraries/shared/src/SharedUtil.cpp index 70fac3efe4..e5aded2798 100644 --- a/libraries/shared/src/SharedUtil.cpp +++ b/libraries/shared/src/SharedUtil.cpp @@ -631,8 +631,7 @@ void debug::setDeadBeef(void* memoryVoid, int size) { } void debug::checkDeadBeef(void* memoryVoid, int size) { - unsigned char* memoryAt = (unsigned char*)memoryVoid; - assert(memcmp(memoryAt, DEADBEEF, std::min(size, DEADBEEF_SIZE)) != 0); + assert(memcmp((unsigned char*)memoryVoid, DEADBEEF, std::min(size, DEADBEEF_SIZE)) != 0); } // Safe version of glm::eulerAngles; uses the factorization method described in David Eberly's From c6f8d34ded2cc05966192a66eacf3dbfca723b0e Mon Sep 17 00:00:00 2001 From: Brad Hefta-Gaub Date: Fri, 14 Mar 2014 18:16:38 -0700 Subject: [PATCH 07/53] fix unix warning --- libraries/shared/src/NodeList.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/shared/src/NodeList.cpp b/libraries/shared/src/NodeList.cpp index 263e29bc94..0cca9731b0 100644 --- a/libraries/shared/src/NodeList.cpp +++ b/libraries/shared/src/NodeList.cpp @@ -348,7 +348,7 @@ void NodeList::addSetOfNodeTypesToNodeInterestSet(const NodeSet& setOfNodeTypes) const uint32_t RFC_5389_MAGIC_COOKIE = 0x2112A442; const int NUM_BYTES_STUN_HEADER = 20; -const int NUM_STUN_REQUESTS_BEFORE_FALLBACK = 5; +const unsigned int NUM_STUN_REQUESTS_BEFORE_FALLBACK = 5; void NodeList::sendSTUNRequest() { const char STUN_SERVER_HOSTNAME[] = "stun.highfidelity.io"; From 1f775058717857b894df380076ca026d02bf3b37 Mon Sep 17 00:00:00 2001 From: Brad Hefta-Gaub Date: Fri, 14 Mar 2014 18:35:34 -0700 Subject: [PATCH 08/53] more unix warnings cleanup --- libraries/octree/src/Octree.cpp | 9 ++++----- libraries/octree/src/OctreePacketData.cpp | 2 +- libraries/octree/src/OctreePacketData.h | 14 +++++++------- libraries/octree/src/OctreeRenderer.cpp | 10 +++++----- 4 files changed, 17 insertions(+), 18 deletions(-) diff --git a/libraries/octree/src/Octree.cpp b/libraries/octree/src/Octree.cpp index 4c8ed8c9f6..fc867ec698 100644 --- a/libraries/octree/src/Octree.cpp +++ b/libraries/octree/src/Octree.cpp @@ -807,13 +807,14 @@ int Octree::encodeTreeBitstream(OctreeElement* node, // write the octal code bool roomForOctalCode = false; // assume the worst - int codeLength; + int codeLength = 1; // assume root if (params.chopLevels) { unsigned char* newCode = chopOctalCode(node->getOctalCode(), params.chopLevels); roomForOctalCode = packetData->startSubTree(newCode); if (newCode) { delete newCode; + codeLength = numberOfThreeBitSectionsInCode(newCode); } else { codeLength = 1; } @@ -1559,14 +1560,13 @@ void Octree::copySubTreeIntoNewTree(OctreeElement* startNode, Octree* destinatio } static OctreePacketData packetData; - int bytesWritten = 0; while (!nodeBag.isEmpty()) { OctreeElement* subTree = nodeBag.extract(); packetData.reset(); // reset the packet between usage // ask our tree to write a bitsteam EncodeBitstreamParams params(INT_MAX, IGNORE_VIEW_FRUSTUM, WANT_COLOR, NO_EXISTS_BITS, chopLevels); - bytesWritten = encodeTreeBitstream(subTree, &packetData, nodeBag, params); + encodeTreeBitstream(subTree, &packetData, nodeBag, params); // ask destination tree to read the bitstream ReadBitstreamToTreeParams args(WANT_COLOR, NO_EXISTS_BITS); destinationTree->readBitstreamToTree(packetData.getUncompressedData(), packetData.getUncompressedSize(), args); @@ -1595,7 +1595,6 @@ void Octree::copyFromTreeIntoSubTree(Octree* sourceTree, OctreeElement* destinat nodeBag.insert(sourceTree->_rootNode); static OctreePacketData packetData; - int bytesWritten = 0; while (!nodeBag.isEmpty()) { OctreeElement* subTree = nodeBag.extract(); @@ -1604,7 +1603,7 @@ void Octree::copyFromTreeIntoSubTree(Octree* sourceTree, OctreeElement* destinat // ask our tree to write a bitsteam EncodeBitstreamParams params(INT_MAX, IGNORE_VIEW_FRUSTUM, WANT_COLOR, NO_EXISTS_BITS); - bytesWritten = sourceTree->encodeTreeBitstream(subTree, &packetData, nodeBag, params); + sourceTree->encodeTreeBitstream(subTree, &packetData, nodeBag, params); // ask destination tree to read the bitstream bool wantImportProgress = true; diff --git a/libraries/octree/src/OctreePacketData.cpp b/libraries/octree/src/OctreePacketData.cpp index bb613f57c1..5123d0711a 100644 --- a/libraries/octree/src/OctreePacketData.cpp +++ b/libraries/octree/src/OctreePacketData.cpp @@ -23,7 +23,7 @@ OctreePacketData::OctreePacketData(bool enableCompression, int targetSize) { changeSettings(enableCompression, targetSize); // does reset... } -void OctreePacketData::changeSettings(bool enableCompression, int targetSize) { +void OctreePacketData::changeSettings(bool enableCompression, size_t targetSize) { _enableCompression = enableCompression; _targetSize = std::min(MAX_OCTREE_UNCOMRESSED_PACKET_SIZE, targetSize); reset(); diff --git a/libraries/octree/src/OctreePacketData.h b/libraries/octree/src/OctreePacketData.h index a71a3f893c..526cb7c65e 100644 --- a/libraries/octree/src/OctreePacketData.h +++ b/libraries/octree/src/OctreePacketData.h @@ -30,15 +30,15 @@ typedef uint16_t OCTREE_PACKET_INTERNAL_SECTION_SIZE; const int MAX_OCTREE_PACKET_SIZE = MAX_PACKET_SIZE; // this is overly conservative - sizeof(PacketType) is 8 bytes but a packed PacketType could be as small as one byte -const int OCTREE_PACKET_EXTRA_HEADERS_SIZE = sizeof(OCTREE_PACKET_FLAGS) +const size_t OCTREE_PACKET_EXTRA_HEADERS_SIZE = sizeof(OCTREE_PACKET_FLAGS) + sizeof(OCTREE_PACKET_SEQUENCE) + sizeof(OCTREE_PACKET_SENT_TIME); -const int MAX_OCTREE_PACKET_DATA_SIZE = MAX_PACKET_SIZE - (MAX_PACKET_HEADER_BYTES + OCTREE_PACKET_EXTRA_HEADERS_SIZE); +const size_t MAX_OCTREE_PACKET_DATA_SIZE = MAX_PACKET_SIZE - (MAX_PACKET_HEADER_BYTES + OCTREE_PACKET_EXTRA_HEADERS_SIZE); -const int MAX_OCTREE_UNCOMRESSED_PACKET_SIZE = MAX_OCTREE_PACKET_DATA_SIZE; +const size_t MAX_OCTREE_UNCOMRESSED_PACKET_SIZE = MAX_OCTREE_PACKET_DATA_SIZE; -const int MINIMUM_ATTEMPT_MORE_PACKING = sizeof(OCTREE_PACKET_INTERNAL_SECTION_SIZE) + 40; -const int COMPRESS_PADDING = 15; +const size_t MINIMUM_ATTEMPT_MORE_PACKING = sizeof(OCTREE_PACKET_INTERNAL_SECTION_SIZE) + 40; +const size_t COMPRESS_PADDING = 15; const int REASONABLE_NUMBER_OF_PACKING_ATTEMPTS = 5; const int PACKET_IS_COLOR_BIT = 0; @@ -69,7 +69,7 @@ public: ~OctreePacketData(); /// change compression and target size settings - void changeSettings(bool enableCompression = false, int targetSize = MAX_OCTREE_PACKET_DATA_SIZE); + void changeSettings(bool enableCompression = false, size_t targetSize = MAX_OCTREE_PACKET_DATA_SIZE); /// reset completely, all data is discarded void reset(); @@ -186,7 +186,7 @@ private: /// append a single byte, might fail if byte would cause packet to be too large bool append(unsigned char byte); - int _targetSize; + size_t _targetSize; bool _enableCompression; unsigned char _uncompressed[MAX_OCTREE_UNCOMRESSED_PACKET_SIZE]; diff --git a/libraries/octree/src/OctreeRenderer.cpp b/libraries/octree/src/OctreeRenderer.cpp index 8fdc2139af..1066e53845 100644 --- a/libraries/octree/src/OctreeRenderer.cpp +++ b/libraries/octree/src/OctreeRenderer.cpp @@ -57,9 +57,9 @@ void OctreeRenderer::processDatagram(const QByteArray& dataByteArray, const Shar bool showTimingDetails = false; // Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings); PerformanceWarning warn(showTimingDetails, "OctreeRenderer::processDatagram()",showTimingDetails); - int packetLength = dataByteArray.size(); + size_t packetLength = dataByteArray.size(); PacketType command = packetTypeForPacket(dataByteArray); - int numBytesPacketHeader = numBytesForPacketHeader(dataByteArray); + size_t numBytesPacketHeader = numBytesForPacketHeader(dataByteArray); QUuid sourceUUID = uuidFromPacketHeader(dataByteArray); PacketType expectedType = getExpectedPacketType(); @@ -86,11 +86,11 @@ void OctreeRenderer::processDatagram(const QByteArray& dataByteArray, const Shar int flightTime = arrivedAt - sentAt + clockSkew; OCTREE_PACKET_INTERNAL_SECTION_SIZE sectionLength = 0; - int dataBytes = packetLength - (numBytesPacketHeader + OCTREE_PACKET_EXTRA_HEADERS_SIZE); + size_t dataBytes = packetLength - (numBytesPacketHeader + OCTREE_PACKET_EXTRA_HEADERS_SIZE); if (extraDebugging) { qDebug("OctreeRenderer::processDatagram() ... Got Packet Section" - " color:%s compressed:%s sequence: %u flight:%d usec size:%d data:%d", + " color:%s compressed:%s sequence: %u flight:%d usec size:%lu data:%lu", debug::valueOf(packetIsColored), debug::valueOf(packetIsCompressed), sequence, flightTime, packetLength, dataBytes); } @@ -119,7 +119,7 @@ void OctreeRenderer::processDatagram(const QByteArray& dataByteArray, const Shar packetData.loadFinalizedContent(dataAt, sectionLength); if (extraDebugging) { qDebug("OctreeRenderer::processDatagram() ... Got Packet Section" - " color:%s compressed:%s sequence: %u flight:%d usec size:%d data:%d" + " color:%s compressed:%s sequence: %u flight:%d usec size:%lu data:%lu" " subsection:%d sectionLength:%d uncompressed:%d", debug::valueOf(packetIsColored), debug::valueOf(packetIsCompressed), sequence, flightTime, packetLength, dataBytes, subsection, sectionLength, From 0200ac9da868d624066b13440b9cb84ba550d364 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Fri, 14 Mar 2014 22:43:31 -0700 Subject: [PATCH 09/53] more unix warnings fixes --- interface/src/VoxelSystem.cpp | 14 +++++--------- interface/src/VoxelSystem.h | 4 ++-- 2 files changed, 7 insertions(+), 11 deletions(-) diff --git a/interface/src/VoxelSystem.cpp b/interface/src/VoxelSystem.cpp index a8bdeb1114..6c4ed12e9e 100644 --- a/interface/src/VoxelSystem.cpp +++ b/interface/src/VoxelSystem.cpp @@ -243,7 +243,7 @@ VoxelSystem::~VoxelSystem() { // This is called by the main application thread on both the initialization of the application and when // the preferences dialog box is called/saved -void VoxelSystem::setMaxVoxels(int maxVoxels) { +void VoxelSystem::setMaxVoxels(unsigned long maxVoxels) { if (maxVoxels == _maxVoxels) { return; } @@ -550,7 +550,7 @@ int VoxelSystem::parseData(const QByteArray& packet) { int flightTime = arrivedAt - sentAt; OCTREE_PACKET_INTERNAL_SECTION_SIZE sectionLength = 0; - int dataBytes = packet.size() - (numBytesPacketHeader + OCTREE_PACKET_EXTRA_HEADERS_SIZE); + size_t dataBytes = packet.size() - (numBytesPacketHeader + OCTREE_PACKET_EXTRA_HEADERS_SIZE); int subsection = 1; while (dataBytes > 0) { @@ -576,7 +576,7 @@ int VoxelSystem::parseData(const QByteArray& packet) { packetData.loadFinalizedContent(dataAt, sectionLength); if (Application::getInstance()->getLogger()->extraDebugging()) { qDebug("VoxelSystem::parseData() ... Got Packet Section" - " color:%s compressed:%s sequence: %u flight:%d usec size:%d data:%d" + " color:%s compressed:%s sequence: %u flight:%d usec size:%d data:%lu" " subsection:%d sectionLength:%d uncompressed:%d", debug::valueOf(packetIsColored), debug::valueOf(packetIsCompressed), sequence, flightTime, packet.size(), dataBytes, subsection, sectionLength, @@ -919,13 +919,11 @@ void VoxelSystem::copyWrittenDataSegmentToReadArrays(glBufferIndex segmentStart, // Depending on if we're using per vertex normals, we will need more or less vertex points per voxel int vertexPointsPerVoxel = GLOBAL_NORMALS_VERTEX_POINTS_PER_VOXEL; - GLintptr segmentStartAt = segmentStart * vertexPointsPerVoxel * sizeof(GLfloat); GLsizeiptr segmentSizeBytes = segmentLength * vertexPointsPerVoxel * sizeof(GLfloat); GLfloat* readVerticesAt = _readVerticesArray + (segmentStart * vertexPointsPerVoxel); GLfloat* writeVerticesAt = _writeVerticesArray + (segmentStart * vertexPointsPerVoxel); memcpy(readVerticesAt, writeVerticesAt, segmentSizeBytes); - segmentStartAt = segmentStart * vertexPointsPerVoxel * sizeof(GLubyte); segmentSizeBytes = segmentLength * vertexPointsPerVoxel * sizeof(GLubyte); GLubyte* readColorsAt = _readColorsArray + (segmentStart * vertexPointsPerVoxel); GLubyte* writeColorsAt = _writeColorsArray + (segmentStart * vertexPointsPerVoxel); @@ -1958,10 +1956,8 @@ bool VoxelSystem::showAllSubTreeOperation(OctreeElement* element, void* extraDat // If we've culled at least once, then we will use the status of this voxel in the last culled frustum to determine // how to proceed. If we've never culled, then we just consider all these voxels to be UNKNOWN so that we will not // consider that case. - ViewFrustum::location inLastCulledFrustum; - if (args->culledOnce && args->wantDeltaFrustums) { - inLastCulledFrustum = voxel->inFrustum(args->lastViewFrustum); + ViewFrustum::location inLastCulledFrustum = voxel->inFrustum(args->lastViewFrustum); // if this node is fully inside our last culled view frustum, then we don't need to recurse further if (inLastCulledFrustum == ViewFrustum::INSIDE) { @@ -2001,7 +1997,7 @@ bool VoxelSystem::hideOutOfViewOperation(OctreeElement* element, void* extraData // If we've culled at least once, then we will use the status of this voxel in the last culled frustum to determine // how to proceed. If we've never culled, then we just consider all these voxels to be UNKNOWN so that we will not // consider that case. - ViewFrustum::location inLastCulledFrustum; + ViewFrustum::location inLastCulledFrustum = ViewFrustum::OUTSIDE; // assume outside, but should get reset to actual value if (args->culledOnce && args->wantDeltaFrustums) { inLastCulledFrustum = voxel->inFrustum(args->lastViewFrustum); diff --git a/interface/src/VoxelSystem.h b/interface/src/VoxelSystem.h index 49b47c6f25..bdc55450dd 100644 --- a/interface/src/VoxelSystem.h +++ b/interface/src/VoxelSystem.h @@ -67,7 +67,7 @@ public: ViewFrustum* getLastCulledViewFrustum() { return &_lastCulledViewFrustum; } - void setMaxVoxels(int maxVoxels); + void setMaxVoxels(unsigned long maxVoxels); long int getMaxVoxels() const { return _maxVoxels; } unsigned long getVoxelMemoryUsageRAM() const { return _memoryUsageRAM; } unsigned long getVoxelMemoryUsageVBO() const { return _memoryUsageVBO; } @@ -263,7 +263,7 @@ private: bool _usePrimitiveRenderer; ///< Flag primitive renderer for use PrimitiveRenderer* _renderer; ///< Voxel renderer - static const int _sNumOctantsPerHemiVoxel = 4; + static const unsigned int _sNumOctantsPerHemiVoxel = 4; static int _sCorrectedChildIndex[8]; static unsigned short _sSwizzledOcclusionBits[64]; ///< Swizzle value of bit pairs of the value of index static unsigned char _sOctantIndexToBitMask[8]; ///< Map octant index to partition mask From 61a905961e0116575cf4875eb2297d9a000533bc Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Fri, 14 Mar 2014 22:48:32 -0700 Subject: [PATCH 10/53] darnit I hate casts.. --- libraries/octree/src/OctreePacketData.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/octree/src/OctreePacketData.cpp b/libraries/octree/src/OctreePacketData.cpp index 5123d0711a..219d8612fc 100644 --- a/libraries/octree/src/OctreePacketData.cpp +++ b/libraries/octree/src/OctreePacketData.cpp @@ -369,7 +369,7 @@ bool OctreePacketData::compressContent() { QByteArray compressedData = qCompress(uncompressedData, uncompressedSize, MAX_COMPRESSION); - if (compressedData.size() < MAX_OCTREE_PACKET_DATA_SIZE) { + if (compressedData.size() < (int)MAX_OCTREE_PACKET_DATA_SIZE) { _compressedBytes = compressedData.size(); for (int i = 0; i < _compressedBytes; i++) { _compressed[i] = compressedData[i]; From 4a6cc99be672985d983ecba1e3b7c5fda98fe371 Mon Sep 17 00:00:00 2001 From: Brad Hefta-Gaub Date: Sat, 15 Mar 2014 21:30:45 -0700 Subject: [PATCH 11/53] slightly different approach to windows warning fix --- interface/external/faceshift/src/fsbinarystream.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/external/faceshift/src/fsbinarystream.cpp b/interface/external/faceshift/src/fsbinarystream.cpp index 96434afd9b..85f3ac7e7f 100644 --- a/interface/external/faceshift/src/fsbinarystream.cpp +++ b/interface/external/faceshift/src/fsbinarystream.cpp @@ -160,7 +160,7 @@ void fsBinaryStream::received(long int sz, const char *data) { new_end = m_end + sz; } - if (new_end > Size(m_buffer.size())) m_buffer.resize((new_end * 15 / 10)); // HIFI: to get 1.5 without warnings + if (new_end > Size(m_buffer.size())) m_buffer.resize((int)(1.5f * (float)new_end)); // HIFI: to get 1.5 without warnings memcpy(&m_buffer[0] + m_end, data, sz); m_end += sz; From adb6ffe7c4eb8ea66cc57591bb086acda26bf490 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Sat, 15 Mar 2014 22:00:44 -0700 Subject: [PATCH 12/53] more warnings fixes --- animation-server/src/AnimationServer.cpp | 21 +++++++------------ assignment-client/src/audio/AudioMixer.cpp | 1 - .../src/octree/OctreeSendThread.cpp | 4 +--- interface/src/Util.cpp | 10 ++++----- libraries/voxels/src/VoxelTreeElement.cpp | 7 ++++--- 5 files changed, 17 insertions(+), 26 deletions(-) diff --git a/animation-server/src/AnimationServer.cpp b/animation-server/src/AnimationServer.cpp index b165590c30..1f0828ec17 100644 --- a/animation-server/src/AnimationServer.cpp +++ b/animation-server/src/AnimationServer.cpp @@ -40,13 +40,13 @@ bool waitForVoxelServer = true; const int ANIMATION_LISTEN_PORT = 40107; int ANIMATE_FPS = 60; double ANIMATE_FPS_IN_MILLISECONDS = 1000.0/ANIMATE_FPS; // determines FPS from our desired FPS -int ANIMATE_VOXELS_INTERVAL_USECS = (ANIMATE_FPS_IN_MILLISECONDS * 1000.0); // converts from milliseconds to usecs +quint64 ANIMATE_VOXELS_INTERVAL_USECS = (ANIMATE_FPS_IN_MILLISECONDS * 1000); // converts from milliseconds to usecs int PROCESSING_FPS = 60; double PROCESSING_FPS_IN_MILLISECONDS = 1000.0/PROCESSING_FPS; // determines FPS from our desired FPS int FUDGE_USECS = 650; // a little bit of fudge to actually do some processing -int PROCESSING_INTERVAL_USECS = (PROCESSING_FPS_IN_MILLISECONDS * 1000.0) - FUDGE_USECS; // converts from milliseconds to usecs +quint64 PROCESSING_INTERVAL_USECS = (PROCESSING_FPS_IN_MILLISECONDS * 1000) - FUDGE_USECS; // converts from milliseconds to usecs bool wantLocalDomain = false; @@ -611,9 +611,6 @@ void* animateVoxels(void* args) { } lastProcessTime = usecTimestampNow(); - int packetsStarting = 0; - int packetsEnding = 0; - // The while loop will be running at PROCESSING_FPS, but we only want to call these animation functions at // ANIMATE_FPS. So we check out last animate time and only call these if we've elapsed that time. quint64 now = usecTimestampNow(); @@ -627,8 +624,6 @@ void* animateVoxels(void* args) { animateLoopsPerAnimate++; lastAnimateTime = now; - packetsStarting = ::voxelEditPacketSender->packetsToSendCount(); - // some animations //sendVoxelBlinkMessage(); @@ -652,8 +647,6 @@ void* animateVoxels(void* args) { doBuildStreet(); } - packetsEnding = ::voxelEditPacketSender->packetsToSendCount(); - if (animationElapsed > ANIMATE_VOXELS_INTERVAL_USECS) { animationElapsed -= ANIMATE_VOXELS_INTERVAL_USECS; // credit ourselves one animation frame } else { @@ -670,9 +663,9 @@ void* animateVoxels(void* args) { processesPerAnimate++; } // dynamically sleep until we need to fire off the next set of voxels - quint64 usecToSleep = PROCESSING_INTERVAL_USECS - (usecTimestampNow() - lastProcessTime); - if (usecToSleep > PROCESSING_INTERVAL_USECS) { - usecToSleep = PROCESSING_INTERVAL_USECS; + quint64 usecToSleep = ::PROCESSING_INTERVAL_USECS - (usecTimestampNow() - lastProcessTime); + if (usecToSleep > ::PROCESSING_INTERVAL_USECS) { + usecToSleep = ::PROCESSING_INTERVAL_USECS; } if (usecToSleep > 0) { @@ -758,7 +751,7 @@ AnimationServer::AnimationServer(int &argc, char **argv) : } } printf("ANIMATE_FPS=%d\n",ANIMATE_FPS); - printf("ANIMATE_VOXELS_INTERVAL_USECS=%d\n",ANIMATE_VOXELS_INTERVAL_USECS); + printf("ANIMATE_VOXELS_INTERVAL_USECS=%llu\n",ANIMATE_VOXELS_INTERVAL_USECS); const char* processingFPSCommand = getCmdOption(argc, (const char**) argv, "--ProcessingFPS"); const char* processingIntervalCommand = getCmdOption(argc, (const char**) argv, "--ProcessingInterval"); @@ -774,7 +767,7 @@ AnimationServer::AnimationServer(int &argc, char **argv) : } } printf("PROCESSING_FPS=%d\n",PROCESSING_FPS); - printf("PROCESSING_INTERVAL_USECS=%d\n",PROCESSING_INTERVAL_USECS); + printf("PROCESSING_INTERVAL_USECS=%llu\n",PROCESSING_INTERVAL_USECS); nodeList->linkedDataCreateCallback = NULL; // do we need a callback? diff --git a/assignment-client/src/audio/AudioMixer.cpp b/assignment-client/src/audio/AudioMixer.cpp index 812acc8d70..4c745ef2eb 100644 --- a/assignment-client/src/audio/AudioMixer.cpp +++ b/assignment-client/src/audio/AudioMixer.cpp @@ -79,7 +79,6 @@ void AudioMixer::addBufferToMixForListeningNodeWithBuffer(PositionalAudioRingBuf if (bufferToAdd != listeningNodeBuffer) { // if the two buffer pointers do not match then these are different buffers - glm::vec3 listenerPosition = listeningNodeBuffer->getPosition(); glm::vec3 relativePosition = bufferToAdd->getPosition() - listeningNodeBuffer->getPosition(); glm::quat inverseOrientation = glm::inverse(listeningNodeBuffer->getOrientation()); diff --git a/assignment-client/src/octree/OctreeSendThread.cpp b/assignment-client/src/octree/OctreeSendThread.cpp index ef69771607..09ebb99298 100644 --- a/assignment-client/src/octree/OctreeSendThread.cpp +++ b/assignment-client/src/octree/OctreeSendThread.cpp @@ -54,15 +54,13 @@ bool OctreeSendThread::process() { nodeData = (OctreeQueryNode*) node->getLinkedData(); - int packetsSent = 0; - // Sometimes the node data has not yet been linked, in which case we can't really do anything if (nodeData) { bool viewFrustumChanged = nodeData->updateCurrentViewFrustum(); if (_myServer->wantsDebugSending() && _myServer->wantsVerboseDebug()) { printf("nodeData->updateCurrentViewFrustum() changed=%s\n", debug::valueOf(viewFrustumChanged)); } - packetsSent = packetDistributor(node, nodeData, viewFrustumChanged); + packetDistributor(node, nodeData, viewFrustumChanged); } } else { _nodeMissingCount++; diff --git a/interface/src/Util.cpp b/interface/src/Util.cpp index 45b2c4a616..f54bfb9d00 100644 --- a/interface/src/Util.cpp +++ b/interface/src/Util.cpp @@ -535,7 +535,7 @@ void runTimingTests() { } gettimeofday(&endTime, NULL); elapsedMsecs = diffclock(&startTime, &endTime); - qDebug("rand() stored in array usecs: %f", 1000.0f * elapsedMsecs / (float) numTests); + qDebug("rand() stored in array usecs: %f, first result:%d", 1000.0f * elapsedMsecs / (float) numTests, iResults[0]); // Random number generation using randFloat() gettimeofday(&startTime, NULL); @@ -544,7 +544,7 @@ void runTimingTests() { } gettimeofday(&endTime, NULL); elapsedMsecs = diffclock(&startTime, &endTime); - qDebug("randFloat() stored in array usecs: %f", 1000.0f * elapsedMsecs / (float) numTests); + qDebug("randFloat() stored in array usecs: %f, first result: %f", 1000.0f * elapsedMsecs / (float) numTests, fResults[0]); // PowF function fTest = 1145323.2342f; @@ -567,8 +567,8 @@ void runTimingTests() { } gettimeofday(&endTime, NULL); elapsedMsecs = diffclock(&startTime, &endTime); - qDebug("vector math usecs: %f [%f msecs total for %d tests]", - 1000.0f * elapsedMsecs / (float) numTests, elapsedMsecs, numTests); + qDebug("vector math usecs: %f [%f msecs total for %d tests], last result:%f", + 1000.0f * elapsedMsecs / (float) numTests, elapsedMsecs, numTests, distance); // Vec3 test glm::vec3 vecA(randVector()), vecB(randVector()); @@ -581,7 +581,7 @@ void runTimingTests() { } gettimeofday(&endTime, NULL); elapsedMsecs = diffclock(&startTime, &endTime); - qDebug("vec3 assign and dot() usecs: %f", 1000.0f * elapsedMsecs / (float) numTests); + qDebug("vec3 assign and dot() usecs: %f, last result:%f", 1000.0f * elapsedMsecs / (float) numTests, result); } float loadSetting(QSettings* settings, const char* name, float defaultValue) { diff --git a/libraries/voxels/src/VoxelTreeElement.cpp b/libraries/voxels/src/VoxelTreeElement.cpp index be6bd50e3d..debcfee987 100644 --- a/libraries/voxels/src/VoxelTreeElement.cpp +++ b/libraries/voxels/src/VoxelTreeElement.cpp @@ -178,13 +178,14 @@ void VoxelTreeElement::calculateAverageFromChildren() { bool VoxelTreeElement::collapseChildren() { // scan children, verify that they are ALL present and accounted for bool allChildrenMatch = true; // assume the best (ottimista) - int red,green,blue; + int red = 0; + int green = 0; + int blue = 0; for (int i = 0; i < NUMBER_OF_CHILDREN; i++) { VoxelTreeElement* childAt = getChildAtIndex(i); // if no child, child isn't a leaf, or child doesn't have a color if (!childAt || !childAt->isLeaf() || !childAt->isColored()) { - allChildrenMatch=false; - //qDebug("SADNESS child missing or not colored! i=%d\n",i); + allChildrenMatch = false; break; } else { if (i==0) { From 851764a7053c2501b9b03e4b5ce80043c5ddc7ab Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Sat, 15 Mar 2014 22:36:43 -0700 Subject: [PATCH 13/53] more warning fixes --- libraries/avatars/src/AvatarData.cpp | 2 +- libraries/avatars/src/HandData.cpp | 11 ++++++----- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp index 518b10ddea..21de041343 100644 --- a/libraries/avatars/src/AvatarData.cpp +++ b/libraries/avatars/src/AvatarData.cpp @@ -288,7 +288,7 @@ int AvatarData::parseData(const QByteArray& packet) { // joint data int jointCount = *sourceBuffer++; _jointData.resize(jointCount); - unsigned char validity; + unsigned char validity = 0; // although always set below, this fixes a warning of potential uninitialized use int validityBit = 0; for (int i = 0; i < jointCount; i++) { if (validityBit == 0) { diff --git a/libraries/avatars/src/HandData.cpp b/libraries/avatars/src/HandData.cpp index 46dade6d64..15be4636a7 100644 --- a/libraries/avatars/src/HandData.cpp +++ b/libraries/avatars/src/HandData.cpp @@ -217,11 +217,12 @@ int HandData::decodeRemoteData(const QByteArray& dataByteArray) { palm.setActive(false); } - // One byte for error checking safety. - unsigned char requiredLength = (unsigned char)(sourceBuffer - startPosition); - unsigned char checkLength = *sourceBuffer++; - assert(checkLength == requiredLength); - + // One byte for error checking safety. Last byte contains the expected length (less itself) + // actualLength less expected byte = (sourceBuffer - startPosition) + // expectedLength less expected byte = (*sourceBuffer) + assert((unsigned char)(sourceBuffer - startPosition) == (unsigned char)(*sourceBuffer)); + sourceBuffer++; // skip the trailing byte which is expected length + return sourceBuffer - startPosition; } From 6f85cfdb2f153302948d53dbe4d826a9d118d57f Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Sat, 15 Mar 2014 23:00:03 -0700 Subject: [PATCH 14/53] more warnings fixes --- assignment-client/src/octree/OctreeQueryNode.h | 6 +++--- assignment-client/src/octree/OctreeSendThread.cpp | 2 +- libraries/octree/src/OctreePacketData.h | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/assignment-client/src/octree/OctreeQueryNode.h b/assignment-client/src/octree/OctreeQueryNode.h index 6d4dee300a..29fdea0da2 100644 --- a/assignment-client/src/octree/OctreeQueryNode.h +++ b/assignment-client/src/octree/OctreeQueryNode.h @@ -34,13 +34,13 @@ public: void writeToPacket(const unsigned char* buffer, int bytes); // writes to end of packet const unsigned char* getPacket() const { return _octreePacket; } - int getPacketLength() const { return (MAX_PACKET_SIZE - _octreePacketAvailableBytes); } + unsigned int getPacketLength() const { return (MAX_PACKET_SIZE - _octreePacketAvailableBytes); } bool isPacketWaiting() const { return _octreePacketWaiting; } bool packetIsDuplicate() const; bool shouldSuppressDuplicatePacket(); - int getAvailable() const { return _octreePacketAvailableBytes; } + unsigned int getAvailable() const { return _octreePacketAvailableBytes; } int getMaxSearchLevel() const { return _maxSearchLevel; } void resetMaxSearchLevel() { _maxSearchLevel = 1; } void incrementMaxSearchLevel() { _maxSearchLevel++; } @@ -92,7 +92,7 @@ private: bool _viewSent; unsigned char* _octreePacket; unsigned char* _octreePacketAt; - int _octreePacketAvailableBytes; + unsigned int _octreePacketAvailableBytes; bool _octreePacketWaiting; unsigned char* _lastOctreePacket; diff --git a/assignment-client/src/octree/OctreeSendThread.cpp b/assignment-client/src/octree/OctreeSendThread.cpp index 09ebb99298..35e9869910 100644 --- a/assignment-client/src/octree/OctreeSendThread.cpp +++ b/assignment-client/src/octree/OctreeSendThread.cpp @@ -506,7 +506,7 @@ int OctreeSendThread::packetDistributor(const SharedNodePointer& node, OctreeQue } if (forceDebugging || (_myServer->wantsDebugSending() && _myServer->wantsVerboseDebug())) { - qDebug(">>>>>> calling writeToPacket() available=%d compressedSize=%d uncompressedSize=%d target=%d", + qDebug(">>>>>> calling writeToPacket() available=%d compressedSize=%d uncompressedSize=%d target=%lu", nodeData->getAvailable(), _packetData.getFinalizedSize(), _packetData.getUncompressedSize(), _packetData.getTargetSize()); } diff --git a/libraries/octree/src/OctreePacketData.h b/libraries/octree/src/OctreePacketData.h index 526cb7c65e..245f0668cd 100644 --- a/libraries/octree/src/OctreePacketData.h +++ b/libraries/octree/src/OctreePacketData.h @@ -168,7 +168,7 @@ public: bool isCompressed() const { return _enableCompression; } /// returns the target uncompressed size - int getTargetSize() const { return _targetSize; } + size_t getTargetSize() const { return _targetSize; } /// displays contents for debugging void debugContent(); From 08d89a4565b2632b1f18c4dec6da99dc1e65a6f0 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Sat, 15 Mar 2014 23:17:03 -0700 Subject: [PATCH 15/53] arg windows signedness warnings --- assignment-client/src/octree/OctreeQueryNode.cpp | 2 +- assignment-client/src/octree/OctreeQueryNode.h | 2 +- assignment-client/src/octree/OctreeSendThread.cpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/assignment-client/src/octree/OctreeQueryNode.cpp b/assignment-client/src/octree/OctreeQueryNode.cpp index 8cb577d2f9..3d5fbefc1f 100644 --- a/assignment-client/src/octree/OctreeQueryNode.cpp +++ b/assignment-client/src/octree/OctreeQueryNode.cpp @@ -156,7 +156,7 @@ void OctreeQueryNode::resetOctreePacket(bool lastWasSurpressed) { _octreePacketWaiting = false; } -void OctreeQueryNode::writeToPacket(const unsigned char* buffer, int bytes) { +void OctreeQueryNode::writeToPacket(const unsigned char* buffer, unsigned int bytes) { // compressed packets include lead bytes which contain compressed size, this allows packing of // multiple compressed portions together if (_currentPacketIsCompressed) { diff --git a/assignment-client/src/octree/OctreeQueryNode.h b/assignment-client/src/octree/OctreeQueryNode.h index 29fdea0da2..2a976c6421 100644 --- a/assignment-client/src/octree/OctreeQueryNode.h +++ b/assignment-client/src/octree/OctreeQueryNode.h @@ -31,7 +31,7 @@ public: void resetOctreePacket(bool lastWasSurpressed = false); // resets octree packet to after "V" header - void writeToPacket(const unsigned char* buffer, int bytes); // writes to end of packet + void writeToPacket(const unsigned char* buffer, unsigned int bytes); // writes to end of packet const unsigned char* getPacket() const { return _octreePacket; } unsigned int getPacketLength() const { return (MAX_PACKET_SIZE - _octreePacketAvailableBytes); } diff --git a/assignment-client/src/octree/OctreeSendThread.cpp b/assignment-client/src/octree/OctreeSendThread.cpp index 35e9869910..0259c31374 100644 --- a/assignment-client/src/octree/OctreeSendThread.cpp +++ b/assignment-client/src/octree/OctreeSendThread.cpp @@ -492,7 +492,7 @@ int OctreeSendThread::packetDistributor(const SharedNodePointer& node, OctreeQue // if for some reason the finalized size is greater than our available size, then probably the "compressed" // form actually inflated beyond our padding, and in this case we will send the current packet, then // write to out new packet... - int writtenSize = _packetData.getFinalizedSize() + unsigned int writtenSize = _packetData.getFinalizedSize() + (nodeData->getCurrentPacketIsCompressed() ? sizeof(OCTREE_PACKET_INTERNAL_SECTION_SIZE) : 0); From 5709a8893e56cabf5721c0a58aa45ec6668fc869 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Sat, 15 Mar 2014 23:19:16 -0700 Subject: [PATCH 16/53] more unix signedness warnings --- assignment-client/src/octree/OctreeQueryNode.h | 2 +- assignment-client/src/octree/OctreeSendThread.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/assignment-client/src/octree/OctreeQueryNode.h b/assignment-client/src/octree/OctreeQueryNode.h index 2a976c6421..e48b7aaff4 100644 --- a/assignment-client/src/octree/OctreeQueryNode.h +++ b/assignment-client/src/octree/OctreeQueryNode.h @@ -96,7 +96,7 @@ private: bool _octreePacketWaiting; unsigned char* _lastOctreePacket; - int _lastOctreePacketLength; + unsigned int _lastOctreePacketLength; int _duplicatePacketCount; quint64 _firstSuppressedPacket; diff --git a/assignment-client/src/octree/OctreeSendThread.cpp b/assignment-client/src/octree/OctreeSendThread.cpp index 0259c31374..0c99e94c04 100644 --- a/assignment-client/src/octree/OctreeSendThread.cpp +++ b/assignment-client/src/octree/OctreeSendThread.cpp @@ -140,7 +140,7 @@ int OctreeSendThread::handlePacketSend(const SharedNodePointer& node, OctreeQuer if (nodeData->stats.isReadyToSend()) { // Send the stats message to the client unsigned char* statsMessage = nodeData->stats.getStatsMessage(); - int statsMessageLength = nodeData->stats.getStatsMessageLength(); + unsigned int statsMessageLength = nodeData->stats.getStatsMessageLength(); // If the size of the stats message and the voxel message will fit in a packet, then piggyback them if (nodeData->getPacketLength() + statsMessageLength < MAX_PACKET_SIZE) { From 7d7e1ff28ac0b47d71e38b46d8b62d59b46a6e0b Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Sat, 15 Mar 2014 23:37:52 -0700 Subject: [PATCH 17/53] one more crack at this signedness comparisons on unix --- assignment-client/src/octree/OctreeSendThread.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/assignment-client/src/octree/OctreeSendThread.cpp b/assignment-client/src/octree/OctreeSendThread.cpp index 0c99e94c04..498ddb9e2c 100644 --- a/assignment-client/src/octree/OctreeSendThread.cpp +++ b/assignment-client/src/octree/OctreeSendThread.cpp @@ -140,10 +140,11 @@ int OctreeSendThread::handlePacketSend(const SharedNodePointer& node, OctreeQuer if (nodeData->stats.isReadyToSend()) { // Send the stats message to the client unsigned char* statsMessage = nodeData->stats.getStatsMessage(); - unsigned int statsMessageLength = nodeData->stats.getStatsMessageLength(); + int statsMessageLength = nodeData->stats.getStatsMessageLength(); + int piggyBackSize = nodeData->getPacketLength() + statsMessageLength; // If the size of the stats message and the voxel message will fit in a packet, then piggyback them - if (nodeData->getPacketLength() + statsMessageLength < MAX_PACKET_SIZE) { + if (piggyBackSize < MAX_PACKET_SIZE) { // copy voxel message to back of stats message memcpy(statsMessage + statsMessageLength, nodeData->getPacket(), nodeData->getPacketLength()); From bd6b70ee32c6a88a03b82b4e081416688d9c4f4b Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Sun, 16 Mar 2014 11:07:24 -0700 Subject: [PATCH 18/53] use unsigned int vs size_t, since that just seems more correct --- .../src/octree/OctreeSendThread.cpp | 2 +- interface/src/VoxelSystem.cpp | 4 ++-- libraries/octree/src/OctreePacketData.cpp | 2 +- libraries/octree/src/OctreePacketData.h | 16 ++++++++-------- libraries/octree/src/OctreeRenderer.cpp | 10 +++++----- 5 files changed, 17 insertions(+), 17 deletions(-) diff --git a/assignment-client/src/octree/OctreeSendThread.cpp b/assignment-client/src/octree/OctreeSendThread.cpp index 498ddb9e2c..85839bc53f 100644 --- a/assignment-client/src/octree/OctreeSendThread.cpp +++ b/assignment-client/src/octree/OctreeSendThread.cpp @@ -507,7 +507,7 @@ int OctreeSendThread::packetDistributor(const SharedNodePointer& node, OctreeQue } if (forceDebugging || (_myServer->wantsDebugSending() && _myServer->wantsVerboseDebug())) { - qDebug(">>>>>> calling writeToPacket() available=%d compressedSize=%d uncompressedSize=%d target=%lu", + qDebug(">>>>>> calling writeToPacket() available=%d compressedSize=%d uncompressedSize=%d target=%u", nodeData->getAvailable(), _packetData.getFinalizedSize(), _packetData.getUncompressedSize(), _packetData.getTargetSize()); } diff --git a/interface/src/VoxelSystem.cpp b/interface/src/VoxelSystem.cpp index 6c4ed12e9e..4db5af3c04 100644 --- a/interface/src/VoxelSystem.cpp +++ b/interface/src/VoxelSystem.cpp @@ -550,7 +550,7 @@ int VoxelSystem::parseData(const QByteArray& packet) { int flightTime = arrivedAt - sentAt; OCTREE_PACKET_INTERNAL_SECTION_SIZE sectionLength = 0; - size_t dataBytes = packet.size() - (numBytesPacketHeader + OCTREE_PACKET_EXTRA_HEADERS_SIZE); + unsigned int dataBytes = packet.size() - (numBytesPacketHeader + OCTREE_PACKET_EXTRA_HEADERS_SIZE); int subsection = 1; while (dataBytes > 0) { @@ -576,7 +576,7 @@ int VoxelSystem::parseData(const QByteArray& packet) { packetData.loadFinalizedContent(dataAt, sectionLength); if (Application::getInstance()->getLogger()->extraDebugging()) { qDebug("VoxelSystem::parseData() ... Got Packet Section" - " color:%s compressed:%s sequence: %u flight:%d usec size:%d data:%lu" + " color:%s compressed:%s sequence: %u flight:%d usec size:%d data:%u" " subsection:%d sectionLength:%d uncompressed:%d", debug::valueOf(packetIsColored), debug::valueOf(packetIsCompressed), sequence, flightTime, packet.size(), dataBytes, subsection, sectionLength, diff --git a/libraries/octree/src/OctreePacketData.cpp b/libraries/octree/src/OctreePacketData.cpp index 219d8612fc..5bd4fdce49 100644 --- a/libraries/octree/src/OctreePacketData.cpp +++ b/libraries/octree/src/OctreePacketData.cpp @@ -23,7 +23,7 @@ OctreePacketData::OctreePacketData(bool enableCompression, int targetSize) { changeSettings(enableCompression, targetSize); // does reset... } -void OctreePacketData::changeSettings(bool enableCompression, size_t targetSize) { +void OctreePacketData::changeSettings(bool enableCompression, unsigned int targetSize) { _enableCompression = enableCompression; _targetSize = std::min(MAX_OCTREE_UNCOMRESSED_PACKET_SIZE, targetSize); reset(); diff --git a/libraries/octree/src/OctreePacketData.h b/libraries/octree/src/OctreePacketData.h index 245f0668cd..5d7a904a4c 100644 --- a/libraries/octree/src/OctreePacketData.h +++ b/libraries/octree/src/OctreePacketData.h @@ -30,15 +30,15 @@ typedef uint16_t OCTREE_PACKET_INTERNAL_SECTION_SIZE; const int MAX_OCTREE_PACKET_SIZE = MAX_PACKET_SIZE; // this is overly conservative - sizeof(PacketType) is 8 bytes but a packed PacketType could be as small as one byte -const size_t OCTREE_PACKET_EXTRA_HEADERS_SIZE = sizeof(OCTREE_PACKET_FLAGS) +const unsigned int OCTREE_PACKET_EXTRA_HEADERS_SIZE = sizeof(OCTREE_PACKET_FLAGS) + sizeof(OCTREE_PACKET_SEQUENCE) + sizeof(OCTREE_PACKET_SENT_TIME); -const size_t MAX_OCTREE_PACKET_DATA_SIZE = MAX_PACKET_SIZE - (MAX_PACKET_HEADER_BYTES + OCTREE_PACKET_EXTRA_HEADERS_SIZE); +const unsigned int MAX_OCTREE_PACKET_DATA_SIZE = MAX_PACKET_SIZE - (MAX_PACKET_HEADER_BYTES + OCTREE_PACKET_EXTRA_HEADERS_SIZE); -const size_t MAX_OCTREE_UNCOMRESSED_PACKET_SIZE = MAX_OCTREE_PACKET_DATA_SIZE; +const unsigned int MAX_OCTREE_UNCOMRESSED_PACKET_SIZE = MAX_OCTREE_PACKET_DATA_SIZE; -const size_t MINIMUM_ATTEMPT_MORE_PACKING = sizeof(OCTREE_PACKET_INTERNAL_SECTION_SIZE) + 40; -const size_t COMPRESS_PADDING = 15; +const unsigned int MINIMUM_ATTEMPT_MORE_PACKING = sizeof(OCTREE_PACKET_INTERNAL_SECTION_SIZE) + 40; +const unsigned int COMPRESS_PADDING = 15; const int REASONABLE_NUMBER_OF_PACKING_ATTEMPTS = 5; const int PACKET_IS_COLOR_BIT = 0; @@ -69,7 +69,7 @@ public: ~OctreePacketData(); /// change compression and target size settings - void changeSettings(bool enableCompression = false, size_t targetSize = MAX_OCTREE_PACKET_DATA_SIZE); + void changeSettings(bool enableCompression = false, unsigned int targetSize = MAX_OCTREE_PACKET_DATA_SIZE); /// reset completely, all data is discarded void reset(); @@ -168,7 +168,7 @@ public: bool isCompressed() const { return _enableCompression; } /// returns the target uncompressed size - size_t getTargetSize() const { return _targetSize; } + unsigned int getTargetSize() const { return _targetSize; } /// displays contents for debugging void debugContent(); @@ -186,7 +186,7 @@ private: /// append a single byte, might fail if byte would cause packet to be too large bool append(unsigned char byte); - size_t _targetSize; + unsigned int _targetSize; bool _enableCompression; unsigned char _uncompressed[MAX_OCTREE_UNCOMRESSED_PACKET_SIZE]; diff --git a/libraries/octree/src/OctreeRenderer.cpp b/libraries/octree/src/OctreeRenderer.cpp index 1066e53845..5d4543e3aa 100644 --- a/libraries/octree/src/OctreeRenderer.cpp +++ b/libraries/octree/src/OctreeRenderer.cpp @@ -57,9 +57,9 @@ void OctreeRenderer::processDatagram(const QByteArray& dataByteArray, const Shar bool showTimingDetails = false; // Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings); PerformanceWarning warn(showTimingDetails, "OctreeRenderer::processDatagram()",showTimingDetails); - size_t packetLength = dataByteArray.size(); + unsigned int packetLength = dataByteArray.size(); PacketType command = packetTypeForPacket(dataByteArray); - size_t numBytesPacketHeader = numBytesForPacketHeader(dataByteArray); + unsigned int numBytesPacketHeader = numBytesForPacketHeader(dataByteArray); QUuid sourceUUID = uuidFromPacketHeader(dataByteArray); PacketType expectedType = getExpectedPacketType(); @@ -86,11 +86,11 @@ void OctreeRenderer::processDatagram(const QByteArray& dataByteArray, const Shar int flightTime = arrivedAt - sentAt + clockSkew; OCTREE_PACKET_INTERNAL_SECTION_SIZE sectionLength = 0; - size_t dataBytes = packetLength - (numBytesPacketHeader + OCTREE_PACKET_EXTRA_HEADERS_SIZE); + unsigned int dataBytes = packetLength - (numBytesPacketHeader + OCTREE_PACKET_EXTRA_HEADERS_SIZE); if (extraDebugging) { qDebug("OctreeRenderer::processDatagram() ... Got Packet Section" - " color:%s compressed:%s sequence: %u flight:%d usec size:%lu data:%lu", + " color:%s compressed:%s sequence: %u flight:%d usec size:%u data:%u", debug::valueOf(packetIsColored), debug::valueOf(packetIsCompressed), sequence, flightTime, packetLength, dataBytes); } @@ -119,7 +119,7 @@ void OctreeRenderer::processDatagram(const QByteArray& dataByteArray, const Shar packetData.loadFinalizedContent(dataAt, sectionLength); if (extraDebugging) { qDebug("OctreeRenderer::processDatagram() ... Got Packet Section" - " color:%s compressed:%s sequence: %u flight:%d usec size:%lu data:%lu" + " color:%s compressed:%s sequence: %u flight:%d usec size:%u data:%u" " subsection:%d sectionLength:%d uncompressed:%d", debug::valueOf(packetIsColored), debug::valueOf(packetIsCompressed), sequence, flightTime, packetLength, dataBytes, subsection, sectionLength, From 05d652227963d56d2dc46978f1f67fb990b4acb4 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Mon, 17 Mar 2014 10:02:00 -0700 Subject: [PATCH 19/53] more MMX optimizations to AudioMixer for delayed samples --- assignment-client/src/audio/AudioMixer.cpp | 133 +++++++++++++++------ assignment-client/src/audio/AudioMixer.h | 5 +- 2 files changed, 103 insertions(+), 35 deletions(-) diff --git a/assignment-client/src/audio/AudioMixer.cpp b/assignment-client/src/audio/AudioMixer.cpp index 572da1a6c4..f8e68340cb 100644 --- a/assignment-client/src/audio/AudioMixer.cpp +++ b/assignment-client/src/audio/AudioMixer.cpp @@ -74,9 +74,7 @@ void AudioMixer::addBufferToMixForListeningNodeWithBuffer(PositionalAudioRingBuf float attenuationCoefficient = 1.0f; int numSamplesDelay = 0; float weakChannelAmplitudeRatio = 1.0f; - - const int PHASE_DELAY_AT_90 = 20; - + if (bufferToAdd != listeningNodeBuffer) { // if the two buffer pointers do not match then these are different buffers @@ -150,7 +148,7 @@ void AudioMixer::addBufferToMixForListeningNodeWithBuffer(PositionalAudioRingBuf // figure out the number of samples of delay and the ratio of the amplitude // in the weak channel for audio spatialization float sinRatio = fabsf(sinf(bearingRelativeAngleToSource)); - numSamplesDelay = PHASE_DELAY_AT_90 * sinRatio; + numSamplesDelay = SAMPLE_PHASE_DELAY_AT_90 * sinRatio; weakChannelAmplitudeRatio = 1 - (PHASE_AMPLITUDE_RATIO_AT_90 * sinRatio); } } @@ -160,45 +158,28 @@ void AudioMixer::addBufferToMixForListeningNodeWithBuffer(PositionalAudioRingBuf int goodChannelOffset = delayedChannelOffset == 0 ? 1 : 0; const int16_t* nextOutputStart = bufferToAdd->getNextOutput(); - const int16_t* delayNextOutputStart = nextOutputStart - numSamplesDelay; + const int16_t* bufferStart = bufferToAdd->getBuffer(); int ringBufferSampleCapacity = bufferToAdd->getSampleCapacity(); - - if (delayNextOutputStart < bufferStart) { - delayNextOutputStart = bufferStart + ringBufferSampleCapacity - numSamplesDelay; - } - int16_t correctMixSample[2], correctBufferSample[2], delayMixSample[2], delayBufferSample[2]; - int delayedChannelIndex[2]; - - float attenuationAndWeakChannelRatio = attenuationCoefficient * weakChannelAmplitudeRatio; + int16_t correctBufferSample[2], delayBufferSample[2]; + int delayedChannelIndex = 0; for (int s = 0; s < NETWORK_BUFFER_LENGTH_SAMPLES_STEREO; s += 4) { // setup the int16_t variables for the two sample sets correctBufferSample[0] = nextOutputStart[s / 2] * attenuationCoefficient; correctBufferSample[1] = nextOutputStart[(s / 2) + 1] * attenuationCoefficient; - correctMixSample[0] = _clientSamples[s + goodChannelOffset]; - correctMixSample[1] = _clientSamples[s + goodChannelOffset + 2]; - for (int i = 0; i < 2; ++i) { - if ((s / 2) + numSamplesDelay + i < NETWORK_BUFFER_LENGTH_SAMPLES_PER_CHANNEL) { - // for the delayed channel we fill the range (n + numSamplesDelay) to NETWORK_BUFFER_LENGTH_SAMPLES_STEREO first - delayedChannelIndex[i] = s + (numSamplesDelay * 2) + (i * 2) + delayedChannelOffset; - delayBufferSample[i] = correctBufferSample[i] * weakChannelAmplitudeRatio; - } else { - // now that the right most range has been filled, we go back to fill in numSamples delay at the beginning - int samplesBack = (s / 2) - NETWORK_BUFFER_LENGTH_SAMPLES_PER_CHANNEL + i; - - delayBufferSample[i] = delayNextOutputStart[numSamplesDelay + samplesBack] * attenuationAndWeakChannelRatio; - delayedChannelIndex[i] = (numSamplesDelay + samplesBack) * 2 + delayedChannelOffset; - } - } + delayedChannelIndex = s + (numSamplesDelay * 2) + delayedChannelOffset; - delayMixSample[0] = _clientSamples[delayedChannelIndex[0]]; - delayMixSample[1] = _clientSamples[delayedChannelIndex[1]]; + delayBufferSample[0] = correctBufferSample[0] * weakChannelAmplitudeRatio; + delayBufferSample[1] = correctBufferSample[1] * weakChannelAmplitudeRatio; - __m64 bufferSamples = _mm_set_pi16(correctMixSample[0], correctMixSample[1], delayMixSample[0], delayMixSample[1]); + __m64 bufferSamples = _mm_set_pi16(_clientSamples[s + goodChannelOffset], + _clientSamples[s + goodChannelOffset + 2], + _clientSamples[delayedChannelIndex], + _clientSamples[delayedChannelIndex + 2]); __m64 addedSamples = _mm_set_pi16(correctBufferSample[0], correctBufferSample[1], delayBufferSample[0], delayBufferSample[1]); @@ -209,8 +190,92 @@ void AudioMixer::addBufferToMixForListeningNodeWithBuffer(PositionalAudioRingBuf // assign the results from the result of the mmx arithmetic _clientSamples[s + goodChannelOffset] = shortResults[3]; _clientSamples[s + goodChannelOffset + 2] = shortResults[2]; - _clientSamples[delayedChannelIndex[0]] = shortResults[1]; - _clientSamples[delayedChannelIndex[1]] = shortResults[0]; + _clientSamples[delayedChannelIndex] = shortResults[1]; + _clientSamples[delayedChannelIndex + 2] = shortResults[0]; + } + + // The following code is pretty gross and redundant, but AFAIK it's the best way to avoid + // too many conditionals in handling the delay samples at the beginning of _clientSamples. + // Basically we try to take the samples in batches of four, and then handle the remainder + // conditionally to get rid of the rest. + + if (numSamplesDelay > 0) { + // if there was a sample delay for this buffer, we need to pull samples prior to the nextOutput + // to stick at the beginning + float attenuationAndWeakChannelRatio = attenuationCoefficient * weakChannelAmplitudeRatio; + const int16_t* delayNextOutputStart = nextOutputStart - numSamplesDelay; + if (delayNextOutputStart < bufferStart) { + delayNextOutputStart = bufferStart + ringBufferSampleCapacity - numSamplesDelay; + } + + int i = 0; + + while (i + 3 < numSamplesDelay) { + // handle the first cases where we can MMX add four samples at once + int parentIndex = i * 2; + __m64 bufferSamples = _mm_setr_pi16(_clientSamples[parentIndex + delayedChannelOffset], + _clientSamples[parentIndex + 2 + delayedChannelOffset], + _clientSamples[parentIndex + 4 + delayedChannelOffset], + _clientSamples[parentIndex + 6 + delayedChannelOffset]); + __m64 addSamples = _mm_set_pi16(delayNextOutputStart[i] * attenuationAndWeakChannelRatio, + delayNextOutputStart[i + 1] * attenuationAndWeakChannelRatio, + delayNextOutputStart[i + 2] * attenuationAndWeakChannelRatio, + delayNextOutputStart[i + 3] * attenuationAndWeakChannelRatio); + __m64 mmxResult = _mm_adds_pi16(bufferSamples, addSamples); + int16_t* shortResults = reinterpret_cast(&mmxResult); + + _clientSamples[parentIndex + delayedChannelOffset] = shortResults[3]; + _clientSamples[parentIndex + 2 + delayedChannelOffset] = shortResults[2]; + _clientSamples[parentIndex + 4 + delayedChannelOffset] = shortResults[1]; + _clientSamples[parentIndex + 6 + delayedChannelOffset] = shortResults[0]; + + // push the index + i += 4; + } + + int parentIndex = i * 2; + + if (i + 2 < numSamplesDelay) { + // MMX add only three delayed samples + + __m64 bufferSamples = _mm_set_pi16(_clientSamples[parentIndex + delayedChannelOffset], + _clientSamples[parentIndex + 2 + delayedChannelOffset], + _clientSamples[parentIndex + 4 + delayedChannelOffset], + 0); + __m64 addSamples = _mm_set_pi16(delayNextOutputStart[i] * attenuationAndWeakChannelRatio, + delayNextOutputStart[i + 1] * attenuationAndWeakChannelRatio, + delayNextOutputStart[i + 2] * attenuationAndWeakChannelRatio, + 0); + __m64 mmxResult = _mm_adds_pi16(bufferSamples, addSamples); + int16_t* shortResults = reinterpret_cast(&mmxResult); + + _clientSamples[parentIndex + delayedChannelOffset] = shortResults[3]; + _clientSamples[parentIndex + 2 + delayedChannelOffset] = shortResults[2]; + _clientSamples[parentIndex + 4 + delayedChannelOffset] = shortResults[1]; + + } else if (i + 1 < numSamplesDelay) { + // MMX add two delayed samples + __m64 bufferSamples = _mm_set_pi16(_clientSamples[parentIndex + delayedChannelOffset], + _clientSamples[parentIndex + 2 + delayedChannelOffset], 0, 0); + __m64 addSamples = _mm_set_pi16(delayNextOutputStart[i] * attenuationAndWeakChannelRatio, + delayNextOutputStart[i + 1] * attenuationAndWeakChannelRatio, 0, 0); + + __m64 mmxResult = _mm_adds_pi16(bufferSamples, addSamples); + int16_t* shortResults = reinterpret_cast(&mmxResult); + + _clientSamples[parentIndex + delayedChannelOffset] = shortResults[3]; + _clientSamples[parentIndex + 2 + delayedChannelOffset] = shortResults[2]; + + } else if (i < numSamplesDelay) { + // MMX add a single delayed sample + __m64 bufferSamples = _mm_set_pi16(_clientSamples[parentIndex + delayedChannelOffset], 0, 0, 0); + __m64 addSamples = _mm_set_pi16(delayNextOutputStart[i] * attenuationAndWeakChannelRatio, 0, 0, 0); + + __m64 mmxResult = _mm_adds_pi16(bufferSamples, addSamples); + int16_t* shortResults = reinterpret_cast(&mmxResult); + + _clientSamples[parentIndex + delayedChannelOffset] = shortResults[3]; + } } } @@ -303,7 +368,7 @@ void AudioMixer::run() { && ((AudioMixerClientData*) node->getLinkedData())->getAvatarAudioRingBuffer()) { prepareMixForListeningNode(node.data()); - memcpy(_clientMixBuffer.data() + numBytesPacketHeader, _clientSamples, sizeof(_clientSamples)); + memcpy(_clientMixBuffer.data() + numBytesPacketHeader, _clientSamples, NETWORK_BUFFER_LENGTH_BYTES_STEREO); nodeList->writeDatagram(_clientMixBuffer, node); } } diff --git a/assignment-client/src/audio/AudioMixer.h b/assignment-client/src/audio/AudioMixer.h index ae5998100f..8032649c17 100644 --- a/assignment-client/src/audio/AudioMixer.h +++ b/assignment-client/src/audio/AudioMixer.h @@ -16,6 +16,8 @@ class PositionalAudioRingBuffer; class AvatarAudioRingBuffer; +const int SAMPLE_PHASE_DELAY_AT_90 = 20; + /// Handles assignments of type AudioMixer - mixing streams of audio and re-distributing to various clients. class AudioMixer : public ThreadedAssignment { Q_OBJECT @@ -38,7 +40,8 @@ private: QByteArray _clientMixBuffer; - int16_t _clientSamples[NETWORK_BUFFER_LENGTH_SAMPLES_STEREO]; + // client samples capacity is larger than what will be sent to optimize mixing + int16_t _clientSamples[NETWORK_BUFFER_LENGTH_SAMPLES_STEREO + SAMPLE_PHASE_DELAY_AT_90]; }; #endif /* defined(__hifi__AudioMixer__) */ From a1fe41fc1d4ad9e2203be1f78caa553be0318423 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Mon, 17 Mar 2014 10:10:26 -0700 Subject: [PATCH 20/53] repair a conflicted translation file --- interface/interface_en.ts | 21 --------------------- 1 file changed, 21 deletions(-) diff --git a/interface/interface_en.ts b/interface/interface_en.ts index d640db2952..75ada1910c 100644 --- a/interface/interface_en.ts +++ b/interface/interface_en.ts @@ -14,20 +14,12 @@ -<<<<<<< HEAD - -======= ->>>>>>> 5182ab190432324cdb0d0221c15fe57fe1e602c6 Open Script -<<<<<<< HEAD - -======= ->>>>>>> 5182ab190432324cdb0d0221c15fe57fe1e602c6 JavaScript Files (*.js) @@ -121,31 +113,18 @@ Menu -<<<<<<< HEAD - -======= ->>>>>>> 5182ab190432324cdb0d0221c15fe57fe1e602c6 Open .ini config file -<<<<<<< HEAD - - -======= ->>>>>>> 5182ab190432324cdb0d0221c15fe57fe1e602c6 Text files (*.ini) -<<<<<<< HEAD - -======= ->>>>>>> 5182ab190432324cdb0d0221c15fe57fe1e602c6 Save .ini config file From cc1d309c15e87dd8cfc0fdc18979befe514aeb1f Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Mon, 17 Mar 2014 10:13:29 -0700 Subject: [PATCH 21/53] some really trivial magic number replacements --- assignment-client/src/audio/AudioMixer.cpp | 37 ++++++++++++---------- 1 file changed, 21 insertions(+), 16 deletions(-) diff --git a/assignment-client/src/audio/AudioMixer.cpp b/assignment-client/src/audio/AudioMixer.cpp index f8e68340cb..24f2c90020 100644 --- a/assignment-client/src/audio/AudioMixer.cpp +++ b/assignment-client/src/audio/AudioMixer.cpp @@ -165,6 +165,8 @@ void AudioMixer::addBufferToMixForListeningNodeWithBuffer(PositionalAudioRingBuf int16_t correctBufferSample[2], delayBufferSample[2]; int delayedChannelIndex = 0; + const int SINGLE_STEREO_OFFSET = 2; + for (int s = 0; s < NETWORK_BUFFER_LENGTH_SAMPLES_STEREO; s += 4) { // setup the int16_t variables for the two sample sets @@ -177,9 +179,9 @@ void AudioMixer::addBufferToMixForListeningNodeWithBuffer(PositionalAudioRingBuf delayBufferSample[1] = correctBufferSample[1] * weakChannelAmplitudeRatio; __m64 bufferSamples = _mm_set_pi16(_clientSamples[s + goodChannelOffset], - _clientSamples[s + goodChannelOffset + 2], + _clientSamples[s + goodChannelOffset + SINGLE_STEREO_OFFSET], _clientSamples[delayedChannelIndex], - _clientSamples[delayedChannelIndex + 2]); + _clientSamples[delayedChannelIndex + SINGLE_STEREO_OFFSET]); __m64 addedSamples = _mm_set_pi16(correctBufferSample[0], correctBufferSample[1], delayBufferSample[0], delayBufferSample[1]); @@ -189,9 +191,9 @@ void AudioMixer::addBufferToMixForListeningNodeWithBuffer(PositionalAudioRingBuf // assign the results from the result of the mmx arithmetic _clientSamples[s + goodChannelOffset] = shortResults[3]; - _clientSamples[s + goodChannelOffset + 2] = shortResults[2]; + _clientSamples[s + goodChannelOffset + SINGLE_STEREO_OFFSET] = shortResults[2]; _clientSamples[delayedChannelIndex] = shortResults[1]; - _clientSamples[delayedChannelIndex + 2] = shortResults[0]; + _clientSamples[delayedChannelIndex + SINGLE_STEREO_OFFSET] = shortResults[0]; } // The following code is pretty gross and redundant, but AFAIK it's the best way to avoid @@ -199,6 +201,9 @@ void AudioMixer::addBufferToMixForListeningNodeWithBuffer(PositionalAudioRingBuf // Basically we try to take the samples in batches of four, and then handle the remainder // conditionally to get rid of the rest. + const int DOUBLE_STEREO_OFFSET = 4; + const int TRIPLE_STEREO_OFFSET = 6; + if (numSamplesDelay > 0) { // if there was a sample delay for this buffer, we need to pull samples prior to the nextOutput // to stick at the beginning @@ -214,9 +219,9 @@ void AudioMixer::addBufferToMixForListeningNodeWithBuffer(PositionalAudioRingBuf // handle the first cases where we can MMX add four samples at once int parentIndex = i * 2; __m64 bufferSamples = _mm_setr_pi16(_clientSamples[parentIndex + delayedChannelOffset], - _clientSamples[parentIndex + 2 + delayedChannelOffset], - _clientSamples[parentIndex + 4 + delayedChannelOffset], - _clientSamples[parentIndex + 6 + delayedChannelOffset]); + _clientSamples[parentIndex + SINGLE_STEREO_OFFSET + delayedChannelOffset], + _clientSamples[parentIndex + DOUBLE_STEREO_OFFSET + delayedChannelOffset], + _clientSamples[parentIndex + TRIPLE_STEREO_OFFSET + delayedChannelOffset]); __m64 addSamples = _mm_set_pi16(delayNextOutputStart[i] * attenuationAndWeakChannelRatio, delayNextOutputStart[i + 1] * attenuationAndWeakChannelRatio, delayNextOutputStart[i + 2] * attenuationAndWeakChannelRatio, @@ -225,9 +230,9 @@ void AudioMixer::addBufferToMixForListeningNodeWithBuffer(PositionalAudioRingBuf int16_t* shortResults = reinterpret_cast(&mmxResult); _clientSamples[parentIndex + delayedChannelOffset] = shortResults[3]; - _clientSamples[parentIndex + 2 + delayedChannelOffset] = shortResults[2]; - _clientSamples[parentIndex + 4 + delayedChannelOffset] = shortResults[1]; - _clientSamples[parentIndex + 6 + delayedChannelOffset] = shortResults[0]; + _clientSamples[parentIndex + SINGLE_STEREO_OFFSET + delayedChannelOffset] = shortResults[2]; + _clientSamples[parentIndex + DOUBLE_STEREO_OFFSET + delayedChannelOffset] = shortResults[1]; + _clientSamples[parentIndex + TRIPLE_STEREO_OFFSET + delayedChannelOffset] = shortResults[0]; // push the index i += 4; @@ -239,8 +244,8 @@ void AudioMixer::addBufferToMixForListeningNodeWithBuffer(PositionalAudioRingBuf // MMX add only three delayed samples __m64 bufferSamples = _mm_set_pi16(_clientSamples[parentIndex + delayedChannelOffset], - _clientSamples[parentIndex + 2 + delayedChannelOffset], - _clientSamples[parentIndex + 4 + delayedChannelOffset], + _clientSamples[parentIndex + SINGLE_STEREO_OFFSET + delayedChannelOffset], + _clientSamples[parentIndex + DOUBLE_STEREO_OFFSET + delayedChannelOffset], 0); __m64 addSamples = _mm_set_pi16(delayNextOutputStart[i] * attenuationAndWeakChannelRatio, delayNextOutputStart[i + 1] * attenuationAndWeakChannelRatio, @@ -250,13 +255,13 @@ void AudioMixer::addBufferToMixForListeningNodeWithBuffer(PositionalAudioRingBuf int16_t* shortResults = reinterpret_cast(&mmxResult); _clientSamples[parentIndex + delayedChannelOffset] = shortResults[3]; - _clientSamples[parentIndex + 2 + delayedChannelOffset] = shortResults[2]; - _clientSamples[parentIndex + 4 + delayedChannelOffset] = shortResults[1]; + _clientSamples[parentIndex + SINGLE_STEREO_OFFSET + delayedChannelOffset] = shortResults[2]; + _clientSamples[parentIndex + DOUBLE_STEREO_OFFSET + delayedChannelOffset] = shortResults[1]; } else if (i + 1 < numSamplesDelay) { // MMX add two delayed samples __m64 bufferSamples = _mm_set_pi16(_clientSamples[parentIndex + delayedChannelOffset], - _clientSamples[parentIndex + 2 + delayedChannelOffset], 0, 0); + _clientSamples[parentIndex + SINGLE_STEREO_OFFSET + delayedChannelOffset], 0, 0); __m64 addSamples = _mm_set_pi16(delayNextOutputStart[i] * attenuationAndWeakChannelRatio, delayNextOutputStart[i + 1] * attenuationAndWeakChannelRatio, 0, 0); @@ -264,7 +269,7 @@ void AudioMixer::addBufferToMixForListeningNodeWithBuffer(PositionalAudioRingBuf int16_t* shortResults = reinterpret_cast(&mmxResult); _clientSamples[parentIndex + delayedChannelOffset] = shortResults[3]; - _clientSamples[parentIndex + 2 + delayedChannelOffset] = shortResults[2]; + _clientSamples[parentIndex + SINGLE_STEREO_OFFSET + delayedChannelOffset] = shortResults[2]; } else if (i < numSamplesDelay) { // MMX add a single delayed sample From 68ba2201df10c63269fc137e1486787826bd0481 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Mon, 17 Mar 2014 10:22:02 -0700 Subject: [PATCH 22/53] cleanup of Avatar:: and MyAvatar::render() MyAvatar now calls Avatar::render() which does most of the work. Also, made ::renderBody() a proper virtual function --- interface/src/avatar/Avatar.cpp | 69 ++++++++++++++------------ interface/src/avatar/Avatar.h | 4 +- interface/src/avatar/AvatarManager.cpp | 18 +++---- interface/src/avatar/AvatarManager.h | 2 +- interface/src/avatar/MyAvatar.cpp | 62 ++--------------------- interface/src/avatar/MyAvatar.h | 4 +- 6 files changed, 55 insertions(+), 104 deletions(-) diff --git a/interface/src/avatar/Avatar.cpp b/interface/src/avatar/Avatar.cpp index bcf24a7bfb..cb6e3d67ee 100644 --- a/interface/src/avatar/Avatar.cpp +++ b/interface/src/avatar/Avatar.cpp @@ -189,55 +189,60 @@ static TextRenderer* textRenderer(TextRendererType type) { return displayNameRenderer; } -void Avatar::render(bool forShadowMap) { +void Avatar::render(const glm::vec3& cameraPosition, bool forShadowMap) { // simple frustum check float boundingRadius = getBillboardSize(); - if (Application::getInstance()->getViewFrustum()->sphereInFrustum(_position, boundingRadius) == ViewFrustum::OUTSIDE) { + if (Application::getInstance()->getViewFrustum()->sphereInFrustum(cameraPosition, boundingRadius) == ViewFrustum::OUTSIDE) { return; } - glm::vec3 toTarget = _position - Application::getInstance()->getAvatar()->getPosition(); - float lengthToTarget = glm::length(toTarget); + glm::vec3 toTarget = cameraPosition - Application::getInstance()->getAvatar()->getPosition(); + float distanceToTarget = glm::length(toTarget); { - // glow when moving in the distance - + // glow when moving far away const float GLOW_DISTANCE = 20.0f; - Glower glower(_moving && lengthToTarget > GLOW_DISTANCE && !forShadowMap ? 1.0f : 0.0f); + Glower glower(_moving && distanceToTarget > GLOW_DISTANCE && !forShadowMap ? 1.0f : 0.0f); // render body + if (Menu::getInstance()->isOptionChecked(MenuOption::Avatars)) { + renderBody(forShadowMap); + } if (Menu::getInstance()->isOptionChecked(MenuOption::RenderSkeletonCollisionProxies)) { _skeletonModel.renderCollisionProxies(0.7f); } if (Menu::getInstance()->isOptionChecked(MenuOption::RenderHeadCollisionProxies)) { getHead()->getFaceModel().renderCollisionProxies(0.7f); } - if (Menu::getInstance()->isOptionChecked(MenuOption::Avatars)) { - renderBody(); - } - // render voice intensity sphere for avatars that are farther away - const float MAX_SPHERE_ANGLE = 10.f * RADIANS_PER_DEGREE; - const float MIN_SPHERE_ANGLE = 1.f * RADIANS_PER_DEGREE; - const float MIN_SPHERE_SIZE = 0.01f; - const float SPHERE_LOUDNESS_SCALING = 0.0005f; - const float SPHERE_COLOR[] = { 0.5f, 0.8f, 0.8f }; - float height = getSkeletonHeight(); - glm::vec3 delta = height * (getHead()->getCameraOrientation() * IDENTITY_UP) / 2.f; - float angle = abs(angleBetween(toTarget + delta, toTarget - delta)); - float sphereRadius = getHead()->getAverageLoudness() * SPHERE_LOUDNESS_SCALING; - - if (!forShadowMap && (sphereRadius > MIN_SPHERE_SIZE) && (angle < MAX_SPHERE_ANGLE) && (angle > MIN_SPHERE_ANGLE)) { - glColor4f(SPHERE_COLOR[0], SPHERE_COLOR[1], SPHERE_COLOR[2], 1.f - angle / MAX_SPHERE_ANGLE); - glPushMatrix(); - glTranslatef(_position.x, _position.y, _position.z); - glScalef(height, height, height); - glutSolidSphere(sphereRadius, 15, 15); - glPopMatrix(); + // quick check before falling into the code below: + // (a 10 degree breadth of an almost 2 meter avatar kicks in at about 12m) + const float MIN_VOICE_SPHERE_DISTANCE = 12.f; + if (distanceToTarget > MIN_VOICE_SPHERE_DISTANCE) { + // render voice intensity sphere for avatars that are farther away + const float MAX_SPHERE_ANGLE = 10.f * RADIANS_PER_DEGREE; + const float MIN_SPHERE_ANGLE = 1.f * RADIANS_PER_DEGREE; + const float MIN_SPHERE_SIZE = 0.01f; + const float SPHERE_LOUDNESS_SCALING = 0.0005f; + const float SPHERE_COLOR[] = { 0.5f, 0.8f, 0.8f }; + float height = getSkeletonHeight(); + glm::vec3 delta = height * (getHead()->getCameraOrientation() * IDENTITY_UP) / 2.f; + float angle = abs(angleBetween(toTarget + delta, toTarget - delta)); + float sphereRadius = getHead()->getAverageLoudness() * SPHERE_LOUDNESS_SCALING; + + if (!forShadowMap && (sphereRadius > MIN_SPHERE_SIZE) && (angle < MAX_SPHERE_ANGLE) && (angle > MIN_SPHERE_ANGLE)) { + glColor4f(SPHERE_COLOR[0], SPHERE_COLOR[1], SPHERE_COLOR[2], 1.f - angle / MAX_SPHERE_ANGLE); + glPushMatrix(); + glTranslatef(_position.x, _position.y, _position.z); + glScalef(height, height, height); + glutSolidSphere(sphereRadius, 15, 15); + glPopMatrix(); + } } } + const float DISPLAYNAME_DISTANCE = 10.0f; - setShowDisplayName(!forShadowMap && lengthToTarget < DISPLAYNAME_DISTANCE); + setShowDisplayName(!forShadowMap && distanceToTarget < DISPLAYNAME_DISTANCE); if (forShadowMap) { return; } @@ -257,7 +262,6 @@ void Avatar::render(bool forShadowMap) { glm::vec3 chatAxis = glm::axis(chatRotation); glRotatef(glm::degrees(glm::angle(chatRotation)), chatAxis.x, chatAxis.y, chatAxis.z); - glColor3f(0.f, 0.8f, 0.f); glRotatef(180.f, 0.f, 1.f, 0.f); glRotatef(180.f, 0.f, 0.f, 1.f); @@ -302,9 +306,12 @@ glm::quat Avatar::computeRotationFromBodyToWorldUp(float proportion) const { return glm::angleAxis(angle * proportion, axis); } -void Avatar::renderBody() { +void Avatar::renderBody(bool forShadowMap) { if (_shouldRenderBillboard || !(_skeletonModel.isRenderable() && getHead()->getFaceModel().isRenderable())) { // render the billboard until both models are loaded + if (forShadowMap) { + return; + } renderBillboard(); return; } diff --git a/interface/src/avatar/Avatar.h b/interface/src/avatar/Avatar.h index 2bd7fc89e8..542320805e 100755 --- a/interface/src/avatar/Avatar.h +++ b/interface/src/avatar/Avatar.h @@ -74,7 +74,7 @@ public: void init(); void simulate(float deltaTime); - void render(bool forShadowMap = false); + virtual void render(const glm::vec3& cameraPosition, bool forShadowMap); //setters void setDisplayingLookatVectors(bool displayingLookatVectors) { getHead()->setRenderLookatVectors(displayingLookatVectors); } @@ -181,6 +181,7 @@ protected: float getPelvisToHeadLength() const; void renderDisplayName(); + virtual void renderBody(bool forShadowMap); private: @@ -189,7 +190,6 @@ private: bool _shouldRenderBillboard; bool _modelsDirty; - void renderBody(); void renderBillboard(); float getBillboardSize() const; diff --git a/interface/src/avatar/AvatarManager.cpp b/interface/src/avatar/AvatarManager.cpp index 88ce2b4399..cd7d360743 100644 --- a/interface/src/avatar/AvatarManager.cpp +++ b/interface/src/avatar/AvatarManager.cpp @@ -77,7 +77,7 @@ void AvatarManager::renderAvatars(bool forShadowMapOrMirror, bool selfAvatarOnly "Application::renderAvatars()"); bool renderLookAtVectors = Menu::getInstance()->isOptionChecked(MenuOption::LookAtVectors); - + glm::vec3 cameraPosition = Application::getInstance()->getCamera()->getPosition(); if (!selfAvatarOnly) { foreach (const AvatarSharedPointer& avatarPointer, _avatarHash) { @@ -85,17 +85,13 @@ void AvatarManager::renderAvatars(bool forShadowMapOrMirror, bool selfAvatarOnly if (!avatar->isInitialized()) { continue; } - if (avatar == static_cast(_myAvatar.data())) { - _myAvatar->render(forShadowMapOrMirror); - } else { - avatar->render(forShadowMapOrMirror); - } + avatar->render(cameraPosition, forShadowMapOrMirror); avatar->setDisplayingLookatVectors(renderLookAtVectors); } - renderAvatarFades(forShadowMapOrMirror); + renderAvatarFades(cameraPosition, forShadowMapOrMirror); } else { // just render myAvatar - _myAvatar->render(forShadowMapOrMirror); + _myAvatar->render(cameraPosition, forShadowMapOrMirror); _myAvatar->setDisplayingLookatVectors(renderLookAtVectors); } } @@ -118,13 +114,15 @@ void AvatarManager::simulateAvatarFades(float deltaTime) { } } -void AvatarManager::renderAvatarFades(bool forShadowMap) { +void AvatarManager::renderAvatarFades(const glm::vec3& cameraPosition, bool forShadowMap) { // render avatar fades Glower glower(forShadowMap ? 0.0f : 1.0f); foreach(const AvatarSharedPointer& fadingAvatar, _avatarFades) { Avatar* avatar = static_cast(fadingAvatar.data()); - avatar->render(forShadowMap); + if (avatar != static_cast(_myAvatar.data())) { + avatar->render(cameraPosition, forShadowMap); + } } } diff --git a/interface/src/avatar/AvatarManager.h b/interface/src/avatar/AvatarManager.h index c690dfa966..455153b92a 100644 --- a/interface/src/avatar/AvatarManager.h +++ b/interface/src/avatar/AvatarManager.h @@ -45,7 +45,7 @@ private: void processKillAvatar(const QByteArray& datagram); void simulateAvatarFades(float deltaTime); - void renderAvatarFades(bool forShadowMap); + void renderAvatarFades(const glm::vec3& cameraPosition, bool forShadowMap); // virtual override AvatarHash::iterator erase(const AvatarHash::iterator& iterator); diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index e4aaa07a4b..c56865afc6 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -453,68 +453,14 @@ void MyAvatar::renderDebugBodyPoints() { } -void MyAvatar::render(bool forShadowMapOrMirror) { + +// virtual +void MyAvatar::render(const glm::vec3& cameraPosition, bool forShadowMapOrMirror) { // don't render if we've been asked to disable local rendering if (!_shouldRender) { return; // exit early } - - if (Menu::getInstance()->isOptionChecked(MenuOption::Avatars)) { - renderBody(forShadowMapOrMirror); - } - // render body - if (Menu::getInstance()->isOptionChecked(MenuOption::RenderSkeletonCollisionProxies)) { - _skeletonModel.renderCollisionProxies(0.8f); - } - if (Menu::getInstance()->isOptionChecked(MenuOption::RenderHeadCollisionProxies)) { - getHead()->getFaceModel().renderCollisionProxies(0.8f); - } - setShowDisplayName(!forShadowMapOrMirror); - if (forShadowMapOrMirror) { - return; - } - renderDisplayName(); - - if (!_chatMessage.empty()) { - int width = 0; - int lastWidth = 0; - for (string::iterator it = _chatMessage.begin(); it != _chatMessage.end(); it++) { - width += (lastWidth = textRenderer()->computeWidth(*it)); - } - glPushMatrix(); - - glm::vec3 chatPosition = getHead()->getEyePosition() + getBodyUpDirection() * CHAT_MESSAGE_HEIGHT * _scale; - glTranslatef(chatPosition.x, chatPosition.y, chatPosition.z); - glm::quat chatRotation = Application::getInstance()->getCamera()->getRotation(); - glm::vec3 chatAxis = glm::axis(chatRotation); - glRotatef(glm::degrees(glm::angle(chatRotation)), chatAxis.x, chatAxis.y, chatAxis.z); - - glColor3f(0.f, 0.8f, 0.f); - glRotatef(180.f, 0.f, 1.f, 0.f); - glRotatef(180.f, 0.f, 0.f, 1.f); - glScalef(_scale * CHAT_MESSAGE_SCALE, _scale * CHAT_MESSAGE_SCALE, 1.0f); - - glDisable(GL_LIGHTING); - glDepthMask(false); - if (_keyState == NO_KEY_DOWN) { - textRenderer()->draw(-width / 2.0f, 0, _chatMessage.c_str()); - - } else { - // rather than using substr and allocating a new string, just replace the last - // character with a null, then restore it - int lastIndex = _chatMessage.size() - 1; - char lastChar = _chatMessage[lastIndex]; - _chatMessage[lastIndex] = '\0'; - textRenderer()->draw(-width / 2.0f, 0, _chatMessage.c_str()); - _chatMessage[lastIndex] = lastChar; - glColor3f(0.f, 1.f, 0.f); - textRenderer()->draw(width / 2.0f - lastWidth, 0, _chatMessage.c_str() + lastIndex); - } - glEnable(GL_LIGHTING); - glDepthMask(true); - - glPopMatrix(); - } + Avatar::render(cameraPosition, forShadowMapOrMirror); } void MyAvatar::renderHeadMouse() const { diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h index dfc114d952..3544fb1a61 100644 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -35,7 +35,8 @@ public: void simulate(float deltaTime); void updateFromGyros(float deltaTime); - void render(bool forShadowMapOrMirror = false); + void render(const glm::vec3& cameraPosition, bool forShadowMapOrMirror = false); + void renderBody(bool forceRenderHead); void renderDebugBodyPoints(); void renderHeadMouse() const; @@ -120,7 +121,6 @@ private: bool _billboardValid; // private methods - void renderBody(bool forceRenderHead); void updateThrust(float deltaTime); void updateHandMovementAndTouching(float deltaTime); void updateCollisionWithAvatars(float deltaTime); From 288272f051437b03f4ae9c6910601e7474f48e11 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Mon, 17 Mar 2014 11:26:35 -0700 Subject: [PATCH 23/53] fix a reversed MMX add --- assignment-client/src/audio/AudioMixer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assignment-client/src/audio/AudioMixer.cpp b/assignment-client/src/audio/AudioMixer.cpp index 660da1dc52..1637f88859 100644 --- a/assignment-client/src/audio/AudioMixer.cpp +++ b/assignment-client/src/audio/AudioMixer.cpp @@ -217,7 +217,7 @@ void AudioMixer::addBufferToMixForListeningNodeWithBuffer(PositionalAudioRingBuf while (i + 3 < numSamplesDelay) { // handle the first cases where we can MMX add four samples at once int parentIndex = i * 2; - __m64 bufferSamples = _mm_setr_pi16(_clientSamples[parentIndex + delayedChannelOffset], + __m64 bufferSamples = _mm_set_pi16(_clientSamples[parentIndex + delayedChannelOffset], _clientSamples[parentIndex + SINGLE_STEREO_OFFSET + delayedChannelOffset], _clientSamples[parentIndex + DOUBLE_STEREO_OFFSET + delayedChannelOffset], _clientSamples[parentIndex + TRIPLE_STEREO_OFFSET + delayedChannelOffset]); From ed3cf36045575a2ba4f1ae8af943943e06977567 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Mon, 17 Mar 2014 14:10:42 -0700 Subject: [PATCH 24/53] cleanup: AvatarData doesn't derive from NodeData Cleaner Interface since the AvatarData is already not the NodeList. Reduces overhead/confusing code when parsing packets from AvatarMixer. --- assignment-client/src/avatars/AvatarMixer.cpp | 22 ++++++++++++------- .../src/avatars/AvatarMixerClientData.cpp | 7 ++++++ .../src/avatars/AvatarMixerClientData.h | 8 ++++++- interface/src/avatar/Avatar.cpp | 4 ++-- interface/src/avatar/Avatar.h | 2 +- interface/src/avatar/AvatarManager.cpp | 12 +--------- libraries/avatars/src/AvatarData.cpp | 12 +++++----- libraries/avatars/src/AvatarData.h | 11 ++++++---- 8 files changed, 44 insertions(+), 34 deletions(-) diff --git a/assignment-client/src/avatars/AvatarMixer.cpp b/assignment-client/src/avatars/AvatarMixer.cpp index e305972679..47f7084f64 100644 --- a/assignment-client/src/avatars/AvatarMixer.cpp +++ b/assignment-client/src/avatars/AvatarMixer.cpp @@ -62,7 +62,8 @@ void broadcastAvatarData() { mixedAvatarByteArray.resize(numPacketHeaderBytes); AvatarMixerClientData* myData = reinterpret_cast(node->getLinkedData()); - glm::vec3 myPosition = myData->getPosition(); + AvatarData& avatar = myData->getAvatar(); + glm::vec3 myPosition = avatar.getPosition(); // this is an AGENT we have received head data from // send back a packet with other active node data to this node @@ -70,7 +71,8 @@ void broadcastAvatarData() { if (otherNode->getLinkedData() && otherNode->getUUID() != node->getUUID()) { AvatarMixerClientData* otherNodeData = reinterpret_cast(otherNode->getLinkedData()); - glm::vec3 otherPosition = otherNodeData->getPosition(); + AvatarData& otherAvatar = otherNodeData->getAvatar(); + glm::vec3 otherPosition = otherAvatar.getPosition(); float distanceToAvatar = glm::length(myPosition - otherPosition); // The full rate distance is the distance at which EVERY update will be sent for this avatar // at a distance of twice the full rate distance, there will be a 50% chance of sending this avatar's update @@ -79,7 +81,7 @@ void broadcastAvatarData() { if ((distanceToAvatar == 0.f) || (randFloat() < FULL_RATE_DISTANCE / distanceToAvatar)) { QByteArray avatarByteArray; avatarByteArray.append(otherNode->getUUID().toRfc4122()); - avatarByteArray.append(otherNodeData->toByteArray()); + avatarByteArray.append(otherAvatar.toByteArray()); if (avatarByteArray.size() + mixedAvatarByteArray.size() > MAX_PACKET_SIZE) { nodeList->writeDatagram(mixedAvatarByteArray, node); @@ -110,7 +112,8 @@ void broadcastIdentityPacket() { if (node->getLinkedData() && node->getType() == NodeType::Agent) { AvatarMixerClientData* nodeData = reinterpret_cast(node->getLinkedData()); - QByteArray individualData = nodeData->identityByteArray(); + AvatarData& avatar = nodeData->getAvatar(); + QByteArray individualData = avatar.identityByteArray(); individualData.replace(0, NUM_BYTES_RFC4122_UUID, node->getUUID().toRfc4122()); if (avatarIdentityPacket.size() + individualData.size() > MAX_PACKET_SIZE) { @@ -135,9 +138,10 @@ void broadcastIdentityPacket() { void broadcastBillboardPacket(const SharedNodePointer& sendingNode) { AvatarMixerClientData* nodeData = static_cast(sendingNode->getLinkedData()); + AvatarData& avatar = nodeData->getAvatar(); QByteArray packet = byteArrayWithPopulatedHeader(PacketTypeAvatarBillboard); packet.append(sendingNode->getUUID().toRfc4122()); - packet.append(nodeData->getBillboard()); + packet.append(avatar.getBillboard()); NodeList* nodeList = NodeList::getInstance(); foreach (const SharedNodePointer& node, nodeList->getNodeHash()) { @@ -190,12 +194,13 @@ void AvatarMixer::readPendingDatagrams() { if (avatarNode && avatarNode->getLinkedData()) { AvatarMixerClientData* nodeData = reinterpret_cast(avatarNode->getLinkedData()); - if (nodeData->hasIdentityChangedAfterParsing(receivedPacket) + AvatarData& avatar = nodeData->getAvatar(); + if (avatar.hasIdentityChangedAfterParsing(receivedPacket) && !nodeData->hasSentIdentityBetweenKeyFrames()) { // this avatar changed their identity in some way and we haven't sent a packet in this keyframe QByteArray identityPacket = byteArrayWithPopulatedHeader(PacketTypeAvatarIdentity); - QByteArray individualByteArray = nodeData->identityByteArray(); + QByteArray individualByteArray = avatar.identityByteArray(); individualByteArray.replace(0, NUM_BYTES_RFC4122_UUID, avatarNode->getUUID().toRfc4122()); identityPacket.append(individualByteArray); @@ -213,7 +218,8 @@ void AvatarMixer::readPendingDatagrams() { if (avatarNode && avatarNode->getLinkedData()) { AvatarMixerClientData* nodeData = static_cast(avatarNode->getLinkedData()); - if (nodeData->hasBillboardChangedAfterParsing(receivedPacket) + AvatarData& avatar = nodeData->getAvatar(); + if (avatar.hasBillboardChangedAfterParsing(receivedPacket) && !nodeData->hasSentBillboardBetweenKeyFrames()) { // this avatar changed their billboard and we haven't sent a packet in this keyframe broadcastBillboardPacket(avatarNode); diff --git a/assignment-client/src/avatars/AvatarMixerClientData.cpp b/assignment-client/src/avatars/AvatarMixerClientData.cpp index 388d6f6488..a29b6efdb4 100644 --- a/assignment-client/src/avatars/AvatarMixerClientData.cpp +++ b/assignment-client/src/avatars/AvatarMixerClientData.cpp @@ -9,8 +9,15 @@ #include "AvatarMixerClientData.h" AvatarMixerClientData::AvatarMixerClientData() : + NodeData(), _hasSentIdentityBetweenKeyFrames(false), _hasSentBillboardBetweenKeyFrames(false) { } + +int AvatarMixerClientData::parseData(const QByteArray& packet) { + // increment to push past the packet header + int offset = numBytesForPacketHeader(packet); + return _avatar.parseDataAtOffset(packet, offset); +} diff --git a/assignment-client/src/avatars/AvatarMixerClientData.h b/assignment-client/src/avatars/AvatarMixerClientData.h index 7240288306..854e8172d3 100644 --- a/assignment-client/src/avatars/AvatarMixerClientData.h +++ b/assignment-client/src/avatars/AvatarMixerClientData.h @@ -12,11 +12,14 @@ #include #include +#include -class AvatarMixerClientData : public AvatarData { +class AvatarMixerClientData : public NodeData { Q_OBJECT public: AvatarMixerClientData(); + + int parseData(const QByteArray& packet); bool hasSentIdentityBetweenKeyFrames() const { return _hasSentIdentityBetweenKeyFrames; } void setHasSentIdentityBetweenKeyFrames(bool hasSentIdentityBetweenKeyFrames) @@ -25,11 +28,14 @@ public: bool hasSentBillboardBetweenKeyFrames() const { return _hasSentBillboardBetweenKeyFrames; } void setHasSentBillboardBetweenKeyFrames(bool hasSentBillboardBetweenKeyFrames) { _hasSentBillboardBetweenKeyFrames = hasSentBillboardBetweenKeyFrames; } + + AvatarData& getAvatar() { return _avatar; } private: bool _hasSentIdentityBetweenKeyFrames; bool _hasSentBillboardBetweenKeyFrames; + AvatarData _avatar; }; #endif /* defined(__hifi__AvatarMixerClientData__) */ diff --git a/interface/src/avatar/Avatar.cpp b/interface/src/avatar/Avatar.cpp index cb6e3d67ee..75a8386ea9 100644 --- a/interface/src/avatar/Avatar.cpp +++ b/interface/src/avatar/Avatar.cpp @@ -633,11 +633,11 @@ void Avatar::setBillboard(const QByteArray& billboard) { _billboardTexture.reset(); } -int Avatar::parseData(const QByteArray& packet) { +int Avatar::parseDataAtOffset(const QByteArray& packet, int offset) { // change in position implies movement glm::vec3 oldPosition = _position; - int bytesRead = AvatarData::parseData(packet); + int bytesRead = AvatarData::parseDataAtOffset(packet, offset); const float MOVE_DISTANCE_THRESHOLD = 0.001f; _moving = glm::distance(oldPosition, _position) > MOVE_DISTANCE_THRESHOLD; diff --git a/interface/src/avatar/Avatar.h b/interface/src/avatar/Avatar.h index 542320805e..30073c54d4 100755 --- a/interface/src/avatar/Avatar.h +++ b/interface/src/avatar/Avatar.h @@ -133,7 +133,7 @@ public: void setShowDisplayName(bool showDisplayName); - int parseData(const QByteArray& packet); + int parseDataAtOffset(const QByteArray& packet, int offset); static void renderJointConnectingCone(glm::vec3 position1, glm::vec3 position2, float radius1, float radius2); diff --git a/interface/src/avatar/AvatarManager.cpp b/interface/src/avatar/AvatarManager.cpp index cd7d360743..49479e903e 100644 --- a/interface/src/avatar/AvatarManager.cpp +++ b/interface/src/avatar/AvatarManager.cpp @@ -148,10 +148,6 @@ void AvatarManager::processAvatarMixerDatagram(const QByteArray& datagram, const void AvatarManager::processAvatarDataPacket(const QByteArray &datagram, const QWeakPointer &mixerWeakPointer) { int bytesRead = numBytesForPacketHeader(datagram); - QByteArray dummyAvatarByteArray = byteArrayWithPopulatedHeader(PacketTypeAvatarData); - int numDummyHeaderBytes = dummyAvatarByteArray.size(); - int numDummyHeaderBytesWithoutUUID = numDummyHeaderBytes - NUM_BYTES_RFC4122_UUID; - // enumerate over all of the avatars in this packet // only add them if mixerWeakPointer points to something (meaning that mixer is still around) while (bytesRead < datagram.size() && mixerWeakPointer.data()) { @@ -171,16 +167,10 @@ void AvatarManager::processAvatarDataPacket(const QByteArray &datagram, const QW qDebug() << "Adding avatar with UUID" << nodeUUID << "to AvatarManager hash."; } - // copy the rest of the packet to the avatarData holder so we can read the next Avatar from there - dummyAvatarByteArray.resize(numDummyHeaderBytesWithoutUUID); - - // make this Avatar's UUID the UUID in the packet and tack the remaining data onto the end - dummyAvatarByteArray.append(datagram.mid(bytesRead)); // have the matching (or new) avatar parse the data from the packet - bytesRead += matchingAvatar->parseData(dummyAvatarByteArray) - numDummyHeaderBytesWithoutUUID; + bytesRead += matchingAvatar->parseDataAtOffset(datagram, bytesRead); } - } void AvatarManager::processAvatarIdentityPacket(const QByteArray &packet) { diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp index 21de041343..5650d7a800 100644 --- a/libraries/avatars/src/AvatarData.cpp +++ b/libraries/avatars/src/AvatarData.cpp @@ -29,7 +29,6 @@ using namespace std; QNetworkAccessManager* AvatarData::networkAccessManager = NULL; AvatarData::AvatarData() : - NodeData(), _handPosition(0,0,0), _bodyYaw(-90.f), _bodyPitch(0.0f), @@ -184,8 +183,8 @@ QByteArray AvatarData::toByteArray() { return avatarDataByteArray.left(destinationBuffer - startPosition); } -// called on the other nodes - assigns it to my views of the others -int AvatarData::parseData(const QByteArray& packet) { +// read data in packet starting at byte offset and return number of bytes parsed +int AvatarData::parseDataAtOffset(const QByteArray& packet, int offset) { // lazily allocate memory for HeadData in case we're not an Avatar instance if (!_headData) { @@ -197,9 +196,8 @@ int AvatarData::parseData(const QByteArray& packet) { _handData = new HandData(this); } - // increment to push past the packet header const unsigned char* startPosition = reinterpret_cast(packet.data()); - const unsigned char* sourceBuffer = startPosition + numBytesForPacketHeader(packet); + const unsigned char* sourceBuffer = startPosition + offset; // Body world position memcpy(&_position, sourceBuffer, sizeof(float) * 3); @@ -288,13 +286,13 @@ int AvatarData::parseData(const QByteArray& packet) { // joint data int jointCount = *sourceBuffer++; _jointData.resize(jointCount); - unsigned char validity = 0; // although always set below, this fixes a warning of potential uninitialized use + unsigned char validity = 0; int validityBit = 0; for (int i = 0; i < jointCount; i++) { if (validityBit == 0) { validity = *sourceBuffer++; } - _jointData[i].valid = validity & (1 << validityBit); + _jointData[i].valid = (bool)(validity & (1 << validityBit)); validityBit = (validityBit + 1) % BITS_IN_BYTE; } for (int i = 0; i < jointCount; i++) { diff --git a/libraries/avatars/src/AvatarData.h b/libraries/avatars/src/AvatarData.h index 067fadd8b1..c7a93daef5 100755 --- a/libraries/avatars/src/AvatarData.h +++ b/libraries/avatars/src/AvatarData.h @@ -40,7 +40,6 @@ typedef unsigned long long quint64; #include #include -#include #include "HeadData.h" #include "HandData.h" @@ -74,7 +73,7 @@ class QNetworkAccessManager; class JointData; -class AvatarData : public NodeData { +class AvatarData : public QObject { Q_OBJECT Q_PROPERTY(glm::vec3 position READ getPosition WRITE setPosition) @@ -97,7 +96,7 @@ class AvatarData : public NodeData { Q_PROPERTY(QString billboardURL READ getBillboardURL WRITE setBillboardFromURL) public: AvatarData(); - ~AvatarData(); + virtual ~AvatarData(); const glm::vec3& getPosition() const { return _position; } void setPosition(const glm::vec3 position) { _position = position; } @@ -106,7 +105,11 @@ public: void setHandPosition(const glm::vec3& handPosition); QByteArray toByteArray(); - int parseData(const QByteArray& packet); + + /// \param packet byte array of data + /// \param offset number of bytes into packet where data starts + /// \return number of bytes parsed + virtual int parseDataAtOffset(const QByteArray& packet, int offset); // Body Rotation (degrees) float getBodyYaw() const { return _bodyYaw; } From bc9deb5db7075e069426f22ef3caeb14cbd6cab7 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Mon, 17 Mar 2014 14:29:53 -0700 Subject: [PATCH 25/53] handle trivial case of not mixing silent audio streams --- assignment-client/src/audio/AudioMixer.cpp | 15 ++++++++------- .../src/audio/AudioMixerClientData.cpp | 11 +++++++++++ .../src/audio/AudioMixerClientData.h | 4 ++++ libraries/audio/src/AudioRingBuffer.cpp | 14 ++++++++++++++ libraries/audio/src/AudioRingBuffer.h | 2 ++ 5 files changed, 39 insertions(+), 7 deletions(-) diff --git a/assignment-client/src/audio/AudioMixer.cpp b/assignment-client/src/audio/AudioMixer.cpp index 1637f88859..be4da8870d 100644 --- a/assignment-client/src/audio/AudioMixer.cpp +++ b/assignment-client/src/audio/AudioMixer.cpp @@ -301,7 +301,8 @@ void AudioMixer::prepareMixForListeningNode(Node* node) { if ((*otherNode != *node || otherNodeBuffer->shouldLoopbackForNode()) - && otherNodeBuffer->willBeAddedToMix()) { + && otherNodeBuffer->willBeAddedToMix() + && otherNodeClientData->getNextOutputLoudness() != 0) { addBufferToMixForListeningNodeWithBuffer(otherNodeBuffer, nodeRingBuffer); } } @@ -355,12 +356,6 @@ void AudioMixer::run() { while (!_isFinished) { - QCoreApplication::processEvents(); - - if (_isFinished) { - break; - } - foreach (const SharedNodePointer& node, nodeList->getNodeHash()) { if (node->getLinkedData()) { ((AudioMixerClientData*) node->getLinkedData())->checkBuffersBeforeFrameSend(JITTER_BUFFER_SAMPLES); @@ -383,6 +378,12 @@ void AudioMixer::run() { ((AudioMixerClientData*) node->getLinkedData())->pushBuffersAfterFrameSend(); } } + + QCoreApplication::processEvents(); + + if (_isFinished) { + break; + } int usecToSleep = usecTimestamp(&startTime) + (++nextFrame * BUFFER_SEND_INTERVAL_USECS) - usecTimestampNow(); diff --git a/assignment-client/src/audio/AudioMixerClientData.cpp b/assignment-client/src/audio/AudioMixerClientData.cpp index a41889e77c..8907796094 100644 --- a/assignment-client/src/audio/AudioMixerClientData.cpp +++ b/assignment-client/src/audio/AudioMixerClientData.cpp @@ -13,6 +13,13 @@ #include "AudioMixerClientData.h" +AudioMixerClientData::AudioMixerClientData() : + _ringBuffers(), + _nextOutputLoudness(0) +{ + +} + AudioMixerClientData::~AudioMixerClientData() { for (unsigned int i = 0; i < _ringBuffers.size(); i++) { // delete this attached PositionalAudioRingBuffer @@ -80,6 +87,10 @@ void AudioMixerClientData::checkBuffersBeforeFrameSend(int jitterBufferLengthSam // this is a ring buffer that is ready to go // set its flag so we know to push its buffer when all is said and done _ringBuffers[i]->setWillBeAddedToMix(true); + + // calculate the average loudness for the next NETWORK_BUFFER_LENGTH_SAMPLES_PER_CHANNEL + // that would be mixed in + _nextOutputLoudness = _ringBuffers[i]->averageLoudnessForBoundarySamples(NETWORK_BUFFER_LENGTH_SAMPLES_PER_CHANNEL); } } } diff --git a/assignment-client/src/audio/AudioMixerClientData.h b/assignment-client/src/audio/AudioMixerClientData.h index 8031dfec3e..bb10098e23 100644 --- a/assignment-client/src/audio/AudioMixerClientData.h +++ b/assignment-client/src/audio/AudioMixerClientData.h @@ -18,16 +18,20 @@ class AudioMixerClientData : public NodeData { public: + AudioMixerClientData(); ~AudioMixerClientData(); const std::vector getRingBuffers() const { return _ringBuffers; } AvatarAudioRingBuffer* getAvatarAudioRingBuffer() const; + float getNextOutputLoudness() const { return _nextOutputLoudness; } + int parseData(const QByteArray& packet); void checkBuffersBeforeFrameSend(int jitterBufferLengthSamples); void pushBuffersAfterFrameSend(); private: std::vector _ringBuffers; + float _nextOutputLoudness; }; #endif /* defined(__hifi__AudioMixerClientData__) */ diff --git a/libraries/audio/src/AudioRingBuffer.cpp b/libraries/audio/src/AudioRingBuffer.cpp index 56f6d038c2..aed601ec39 100644 --- a/libraries/audio/src/AudioRingBuffer.cpp +++ b/libraries/audio/src/AudioRingBuffer.cpp @@ -55,6 +55,20 @@ int AudioRingBuffer::parseData(const QByteArray& packet) { return writeData(packet.data() + numBytesPacketHeader, packet.size() - numBytesPacketHeader); } +float AudioRingBuffer::averageLoudnessForBoundarySamples(int numSamples) { + // ForBoundarySamples means that we expect the number of samples not to roll of the end of the ring buffer + float averageLoudness = 0; + + for (int i = 0; i < numSamples; ++i) { + averageLoudness += _nextOutput[i]; + } + + averageLoudness /= numSamples; + averageLoudness /= MAX_SAMPLE_VALUE; + + return averageLoudness; +} + qint64 AudioRingBuffer::readSamples(int16_t* destination, qint64 maxSamples) { return readData((char*) destination, maxSamples * sizeof(int16_t)); } diff --git a/libraries/audio/src/AudioRingBuffer.h b/libraries/audio/src/AudioRingBuffer.h index 577c01a63c..c4d3f87814 100644 --- a/libraries/audio/src/AudioRingBuffer.h +++ b/libraries/audio/src/AudioRingBuffer.h @@ -49,6 +49,8 @@ public: // assume callers using this will never wrap around the end const int16_t* getNextOutput() { return _nextOutput; } const int16_t* getBuffer() { return _buffer; } + + float averageLoudnessForBoundarySamples(int numSamples); qint64 readSamples(int16_t* destination, qint64 maxSamples); qint64 writeSamples(const int16_t* source, qint64 maxSamples); From 1428d2d1de772a611baa7d182f48be5a0f014fcc Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Mon, 17 Mar 2014 14:35:04 -0700 Subject: [PATCH 26/53] take an absolute value for correct loudness --- libraries/audio/src/AudioRingBuffer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/audio/src/AudioRingBuffer.cpp b/libraries/audio/src/AudioRingBuffer.cpp index aed601ec39..d07a334d81 100644 --- a/libraries/audio/src/AudioRingBuffer.cpp +++ b/libraries/audio/src/AudioRingBuffer.cpp @@ -60,7 +60,7 @@ float AudioRingBuffer::averageLoudnessForBoundarySamples(int numSamples) { float averageLoudness = 0; for (int i = 0; i < numSamples; ++i) { - averageLoudness += _nextOutput[i]; + averageLoudness += fabsf(_nextOutput[i]); } averageLoudness /= numSamples; From c7e12824a8e03c6c06ee0fe41a18a6d0c7ebb36a Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Mon, 17 Mar 2014 14:35:26 -0700 Subject: [PATCH 27/53] clarify check for audio loudness in AudioMixer --- assignment-client/src/audio/AudioMixer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assignment-client/src/audio/AudioMixer.cpp b/assignment-client/src/audio/AudioMixer.cpp index be4da8870d..aeabd1548b 100644 --- a/assignment-client/src/audio/AudioMixer.cpp +++ b/assignment-client/src/audio/AudioMixer.cpp @@ -302,7 +302,7 @@ void AudioMixer::prepareMixForListeningNode(Node* node) { if ((*otherNode != *node || otherNodeBuffer->shouldLoopbackForNode()) && otherNodeBuffer->willBeAddedToMix() - && otherNodeClientData->getNextOutputLoudness() != 0) { + && otherNodeClientData->getNextOutputLoudness() > 0) { addBufferToMixForListeningNodeWithBuffer(otherNodeBuffer, nodeRingBuffer); } } From 9f24bd9c4718b359b173c396622da0aab78376d7 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Mon, 17 Mar 2014 15:12:02 -0700 Subject: [PATCH 28/53] have the AudioMixer handle silent audio, send silence from Interface when gate closed --- interface/src/Audio.cpp | 48 +++++++++++++++---- libraries/audio/src/AudioRingBuffer.cpp | 13 +++++ libraries/audio/src/AudioRingBuffer.h | 2 + .../audio/src/PositionalAudioRingBuffer.cpp | 15 +++++- libraries/shared/src/PacketHeaders.h | 2 +- 5 files changed, 67 insertions(+), 13 deletions(-) diff --git a/interface/src/Audio.cpp b/interface/src/Audio.cpp index cf51a479ab..dcb955597e 100644 --- a/interface/src/Audio.cpp +++ b/interface/src/Audio.cpp @@ -436,9 +436,8 @@ void Audio::handleAudioInput() { } } if (!_noiseGateOpen) { - for (int i = 0; i < NETWORK_BUFFER_LENGTH_SAMPLES_PER_CHANNEL; i++) { - monoAudioSamples[i] = 0; - } + memset(monoAudioSamples, 0, NETWORK_BUFFER_LENGTH_SAMPLES_PER_CHANNEL); + _lastInputLoudness = 0; } } @@ -482,9 +481,26 @@ void Audio::handleAudioInput() { // we need the amount of bytes in the buffer + 1 for type // + 12 for 3 floats for position + float for bearing + 1 attenuation byte - - PacketType packetType = Menu::getInstance()->isOptionChecked(MenuOption::EchoServerAudio) - ? PacketTypeMicrophoneAudioWithEcho : PacketTypeMicrophoneAudioNoEcho; + + int numAudioBytes = 0; + + PacketType packetType; + if (_lastInputLoudness == 0) { + packetType = PacketTypeSilentAudioListener; + + // we need to indicate how many silent samples this is to the audio mixer + monoAudioSamples[0] = NETWORK_BUFFER_LENGTH_SAMPLES_PER_CHANNEL; + numAudioBytes = sizeof(int16_t); + + } else { + numAudioBytes = NETWORK_BUFFER_LENGTH_BYTES_PER_CHANNEL; + + if (Menu::getInstance()->isOptionChecked(MenuOption::EchoServerAudio)) { + packetType = PacketTypeMicrophoneAudioWithEcho; + } else { + packetType = PacketTypeMicrophoneAudioNoEcho; + } + } char* currentPacketPtr = monoAudioDataPacket + populatePacketHeader(monoAudioDataPacket, packetType); @@ -495,10 +511,8 @@ void Audio::handleAudioInput() { // memcpy our orientation memcpy(currentPacketPtr, &headOrientation, sizeof(headOrientation)); currentPacketPtr += sizeof(headOrientation); - - nodeList->writeDatagram(monoAudioDataPacket, - NETWORK_BUFFER_LENGTH_BYTES_PER_CHANNEL + leadingBytes, - audioMixer); + + nodeList->writeDatagram(monoAudioDataPacket, numAudioBytes + leadingBytes, audioMixer); Application::getInstance()->getBandwidthMeter()->outputStream(BandwidthMeter::AUDIO) .updateValue(NETWORK_BUFFER_LENGTH_BYTES_PER_CHANNEL + leadingBytes); @@ -638,7 +652,14 @@ void Audio::addProceduralSounds(int16_t* monoInput, int numSamples) { int16_t collisionSample = (int16_t) sample; + _lastInputLoudness = 0; + monoInput[i] = glm::clamp(monoInput[i] + collisionSample, MIN_SAMPLE_VALUE, MAX_SAMPLE_VALUE); + + _lastInputLoudness += fabsf(monoInput[i]); + _lastInputLoudness /= numSamples; + _lastInputLoudness /= MAX_SAMPLE_VALUE; + _localProceduralSamples[i] = glm::clamp(_localProceduralSamples[i] + collisionSample, MIN_SAMPLE_VALUE, MAX_SAMPLE_VALUE); @@ -662,7 +683,14 @@ void Audio::addProceduralSounds(int16_t* monoInput, int numSamples) { int16_t collisionSample = (int16_t) sample; + _lastInputLoudness = 0; + monoInput[i] = glm::clamp(monoInput[i] + collisionSample, MIN_SAMPLE_VALUE, MAX_SAMPLE_VALUE); + + _lastInputLoudness += fabsf(monoInput[i]); + _lastInputLoudness /= numSamples; + _lastInputLoudness /= MAX_SAMPLE_VALUE; + _localProceduralSamples[i] = glm::clamp(_localProceduralSamples[i] + collisionSample, MIN_SAMPLE_VALUE, MAX_SAMPLE_VALUE); diff --git a/libraries/audio/src/AudioRingBuffer.cpp b/libraries/audio/src/AudioRingBuffer.cpp index d07a334d81..ba21c6c9b9 100644 --- a/libraries/audio/src/AudioRingBuffer.cpp +++ b/libraries/audio/src/AudioRingBuffer.cpp @@ -156,6 +156,19 @@ unsigned int AudioRingBuffer::samplesAvailable() const { } } +void AudioRingBuffer::addSilentFrame(int numSilentSamples) { + // setup the silent frame + int numSilentBytes = numSilentSamples * sizeof(int16_t); + char* silentFrame = new char[numSilentBytes]; + memset(silentFrame, 0, numSilentBytes); + + // write it + writeData(silentFrame, numSilentBytes); + + // delete the temporary silent frame + delete[] silentFrame; +} + bool AudioRingBuffer::isNotStarvedOrHasMinimumSamples(unsigned int numRequiredSamples) const { if (!_isStarved) { return true; diff --git a/libraries/audio/src/AudioRingBuffer.h b/libraries/audio/src/AudioRingBuffer.h index c4d3f87814..0beb45ca18 100644 --- a/libraries/audio/src/AudioRingBuffer.h +++ b/libraries/audio/src/AudioRingBuffer.h @@ -70,6 +70,8 @@ public: void setIsStarved(bool isStarved) { _isStarved = isStarved; } bool hasStarted() const { return _hasStarted; } + + void addSilentFrame(int numSilentSamples); protected: // disallow copying of AudioRingBuffer objects AudioRingBuffer(const AudioRingBuffer&); diff --git a/libraries/audio/src/PositionalAudioRingBuffer.cpp b/libraries/audio/src/PositionalAudioRingBuffer.cpp index 27b62a8a56..0ac53231a1 100644 --- a/libraries/audio/src/PositionalAudioRingBuffer.cpp +++ b/libraries/audio/src/PositionalAudioRingBuffer.cpp @@ -44,8 +44,19 @@ int PositionalAudioRingBuffer::parseData(const QByteArray& packet) { packetStream.skipRawData(numBytesForPacketHeader(packet)); packetStream.skipRawData(parsePositionalData(packet.mid(packetStream.device()->pos()))); - packetStream.skipRawData(writeData(packet.data() + packetStream.device()->pos(), - packet.size() - packetStream.device()->pos())); + + if (packetTypeForPacket(packet) == PacketTypeSilentAudioListener) { + // this source had no audio to send us, but this counts as a packet + // write silence equivalent to the number of silent samples they just sent us + int16_t numSilentSamples; + packetStream >> numSilentSamples; + addSilentFrame(numSilentSamples); + } else { + // there is audio data to read + packetStream.skipRawData(writeData(packet.data() + packetStream.device()->pos(), + packet.size() - packetStream.device()->pos())); + } + return packetStream.device()->pos(); } diff --git a/libraries/shared/src/PacketHeaders.h b/libraries/shared/src/PacketHeaders.h index 0122e36a61..6f87ac8e3f 100644 --- a/libraries/shared/src/PacketHeaders.h +++ b/libraries/shared/src/PacketHeaders.h @@ -32,7 +32,7 @@ enum PacketType { PacketTypeMicrophoneAudioNoEcho, PacketTypeMicrophoneAudioWithEcho, PacketTypeBulkAvatarData, - PacketTypeTransmitterData, // usable + PacketTypeSilentAudioListener, PacketTypeEnvironmentData, PacketTypeDomainListRequest, PacketTypeRequestAssignment, From 61594b9a1ebb9e723b3203c5c6344412cc6ac78e Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Mon, 17 Mar 2014 16:27:49 -0700 Subject: [PATCH 29/53] fixes to silent audio frame sending --- assignment-client/src/audio/AudioMixer.cpp | 3 ++- assignment-client/src/audio/AudioMixerClientData.cpp | 3 ++- interface/src/Audio.cpp | 8 ++++---- libraries/audio/src/PositionalAudioRingBuffer.cpp | 5 +++-- libraries/shared/src/PacketHeaders.h | 2 +- 5 files changed, 12 insertions(+), 9 deletions(-) diff --git a/assignment-client/src/audio/AudioMixer.cpp b/assignment-client/src/audio/AudioMixer.cpp index aeabd1548b..54f9d962b0 100644 --- a/assignment-client/src/audio/AudioMixer.cpp +++ b/assignment-client/src/audio/AudioMixer.cpp @@ -322,7 +322,8 @@ void AudioMixer::readPendingDatagrams() { PacketType mixerPacketType = packetTypeForPacket(receivedPacket); if (mixerPacketType == PacketTypeMicrophoneAudioNoEcho || mixerPacketType == PacketTypeMicrophoneAudioWithEcho - || mixerPacketType == PacketTypeInjectAudio) { + || mixerPacketType == PacketTypeInjectAudio + || mixerPacketType == PacketTypeSilentAudioFrame) { nodeList->findNodeAndUpdateWithDataFromPacket(receivedPacket); } else { diff --git a/assignment-client/src/audio/AudioMixerClientData.cpp b/assignment-client/src/audio/AudioMixerClientData.cpp index 8907796094..b2da0a0aaa 100644 --- a/assignment-client/src/audio/AudioMixerClientData.cpp +++ b/assignment-client/src/audio/AudioMixerClientData.cpp @@ -41,7 +41,8 @@ AvatarAudioRingBuffer* AudioMixerClientData::getAvatarAudioRingBuffer() const { int AudioMixerClientData::parseData(const QByteArray& packet) { PacketType packetType = packetTypeForPacket(packet); if (packetType == PacketTypeMicrophoneAudioWithEcho - || packetType == PacketTypeMicrophoneAudioNoEcho) { + || packetType == PacketTypeMicrophoneAudioNoEcho + || packetType == PacketTypeSilentAudioFrame) { // grab the AvatarAudioRingBuffer from the vector (or create it if it doesn't exist) AvatarAudioRingBuffer* avatarRingBuffer = getAvatarAudioRingBuffer(); diff --git a/interface/src/Audio.cpp b/interface/src/Audio.cpp index dcb955597e..b684cec46e 100644 --- a/interface/src/Audio.cpp +++ b/interface/src/Audio.cpp @@ -436,7 +436,7 @@ void Audio::handleAudioInput() { } } if (!_noiseGateOpen) { - memset(monoAudioSamples, 0, NETWORK_BUFFER_LENGTH_SAMPLES_PER_CHANNEL); + memset(monoAudioSamples, 0, NETWORK_BUFFER_LENGTH_BYTES_PER_CHANNEL); _lastInputLoudness = 0; } } @@ -450,7 +450,7 @@ void Audio::handleAudioInput() { // our input loudness is 0, since we're muted _lastInputLoudness = 0; } - + // add procedural effects to the appropriate input samples addProceduralSounds(monoAudioSamples, NETWORK_BUFFER_LENGTH_SAMPLES_PER_CHANNEL); @@ -486,7 +486,7 @@ void Audio::handleAudioInput() { PacketType packetType; if (_lastInputLoudness == 0) { - packetType = PacketTypeSilentAudioListener; + packetType = PacketTypeSilentAudioFrame; // we need to indicate how many silent samples this is to the audio mixer monoAudioSamples[0] = NETWORK_BUFFER_LENGTH_SAMPLES_PER_CHANNEL; @@ -515,7 +515,7 @@ void Audio::handleAudioInput() { nodeList->writeDatagram(monoAudioDataPacket, numAudioBytes + leadingBytes, audioMixer); Application::getInstance()->getBandwidthMeter()->outputStream(BandwidthMeter::AUDIO) - .updateValue(NETWORK_BUFFER_LENGTH_BYTES_PER_CHANNEL + leadingBytes); + .updateValue(numAudioBytes + leadingBytes); } delete[] inputAudioSamples; } diff --git a/libraries/audio/src/PositionalAudioRingBuffer.cpp b/libraries/audio/src/PositionalAudioRingBuffer.cpp index 0ac53231a1..11e1a7c2ae 100644 --- a/libraries/audio/src/PositionalAudioRingBuffer.cpp +++ b/libraries/audio/src/PositionalAudioRingBuffer.cpp @@ -45,11 +45,12 @@ int PositionalAudioRingBuffer::parseData(const QByteArray& packet) { packetStream.skipRawData(parsePositionalData(packet.mid(packetStream.device()->pos()))); - if (packetTypeForPacket(packet) == PacketTypeSilentAudioListener) { + if (packetTypeForPacket(packet) == PacketTypeSilentAudioFrame) { // this source had no audio to send us, but this counts as a packet // write silence equivalent to the number of silent samples they just sent us int16_t numSilentSamples; - packetStream >> numSilentSamples; + packetStream.readRawData(reinterpret_cast(&numSilentSamples), sizeof(int16_t)); + addSilentFrame(numSilentSamples); } else { // there is audio data to read diff --git a/libraries/shared/src/PacketHeaders.h b/libraries/shared/src/PacketHeaders.h index 6f87ac8e3f..c6ce6bdd6b 100644 --- a/libraries/shared/src/PacketHeaders.h +++ b/libraries/shared/src/PacketHeaders.h @@ -32,7 +32,7 @@ enum PacketType { PacketTypeMicrophoneAudioNoEcho, PacketTypeMicrophoneAudioWithEcho, PacketTypeBulkAvatarData, - PacketTypeSilentAudioListener, + PacketTypeSilentAudioFrame, PacketTypeEnvironmentData, PacketTypeDomainListRequest, PacketTypeRequestAssignment, From d652cec7667466886961c9961c8ee16bfbce5a7e Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Mon, 17 Mar 2014 16:30:58 -0700 Subject: [PATCH 30/53] some potential fixes to QByteArray crash --- assignment-client/src/audio/AudioMixer.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/assignment-client/src/audio/AudioMixer.cpp b/assignment-client/src/audio/AudioMixer.cpp index 54f9d962b0..d4b5c91488 100644 --- a/assignment-client/src/audio/AudioMixer.cpp +++ b/assignment-client/src/audio/AudioMixer.cpp @@ -287,7 +287,7 @@ void AudioMixer::prepareMixForListeningNode(Node* node) { AvatarAudioRingBuffer* nodeRingBuffer = ((AudioMixerClientData*) node->getLinkedData())->getAvatarAudioRingBuffer(); // zero out the client mix for this node - memset(_clientSamples, 0, sizeof(_clientSamples)); + memset(_clientSamples, 0, NETWORK_BUFFER_LENGTH_BYTES_STEREO); // loop through all other nodes that have sufficient audio to mix foreach (const SharedNodePointer& otherNode, NodeList::getInstance()->getNodeHash()) { @@ -367,8 +367,9 @@ void AudioMixer::run() { if (node->getType() == NodeType::Agent && node->getActiveSocket() && node->getLinkedData() && ((AudioMixerClientData*) node->getLinkedData())->getAvatarAudioRingBuffer()) { prepareMixForListeningNode(node.data()); - - memcpy(_clientMixBuffer.data() + numBytesPacketHeader, _clientSamples, NETWORK_BUFFER_LENGTH_BYTES_STEREO); + + _clientMixBuffer.replace(numBytesPacketHeader, NETWORK_BUFFER_LENGTH_BYTES_STEREO, + reinterpret_cast(_clientSamples)); nodeList->writeDatagram(_clientMixBuffer, node); } } From 7e0da71527602d216c676dc72bb3b4ddf1bdc75e Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Mon, 17 Mar 2014 16:38:39 -0700 Subject: [PATCH 31/53] have agent optionally send silent stream flag --- libraries/script-engine/src/ScriptEngine.cpp | 27 +++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/libraries/script-engine/src/ScriptEngine.cpp b/libraries/script-engine/src/ScriptEngine.cpp index 9a672317ae..cc61633e60 100644 --- a/libraries/script-engine/src/ScriptEngine.cpp +++ b/libraries/script-engine/src/ScriptEngine.cpp @@ -267,15 +267,36 @@ void ScriptEngine::run() { if (_avatarAudioBuffer && _numAvatarAudioBufferSamples > 0) { // if have an avatar audio stream then send it out to our audio-mixer - QByteArray audioPacket = byteArrayWithPopulatedHeader(PacketTypeMicrophoneAudioNoEcho); + + bool silentFrame = true; + + // check if the all of the _numAvatarAudioBufferSamples to be sent are silence + for (int i = 0; i < _numAvatarAudioBufferSamples; ++i) { + if (_avatarAudioBuffer[i] != 0) { + silentFrame = false; + break; + } + } + + QByteArray audioPacket = byteArrayWithPopulatedHeader(silentFrame + ? PacketTypeSilentAudioFrame + : PacketTypeMicrophoneAudioNoEcho); QDataStream packetStream(&audioPacket, QIODevice::Append); // use the orientation and position of this avatar for the source of this audio packetStream.writeRawData(reinterpret_cast(&_avatarData->getPosition()), sizeof(glm::vec3)); glm::quat headOrientation = _avatarData->getHeadOrientation(); packetStream.writeRawData(reinterpret_cast(&headOrientation), sizeof(glm::quat)); - packetStream.writeRawData(reinterpret_cast(_avatarAudioBuffer), - _numAvatarAudioBufferSamples * sizeof(int16_t)); + + if (silentFrame) { + // write the number of silent samples so the audio-mixer can uphold timing + int16_t numSilentSamples = _numAvatarAudioBufferSamples; + packetStream.writeRawData(reinterpret_cast(&numSilentSamples), sizeof(int16_t)); + } else { + // write the raw audio data + packetStream.writeRawData(reinterpret_cast(_avatarAudioBuffer), + _numAvatarAudioBufferSamples * sizeof(int16_t)); + } nodeList->broadcastToNodes(audioPacket, NodeSet() << NodeType::AudioMixer); } From 447f23a1c947ab41558f3892e0e1a1c8546db327 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Mon, 17 Mar 2014 16:56:29 -0700 Subject: [PATCH 32/53] repair _clientSamples copying into _clientMix --- assignment-client/src/audio/AudioMixer.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/assignment-client/src/audio/AudioMixer.cpp b/assignment-client/src/audio/AudioMixer.cpp index d4b5c91488..e097fd22a1 100644 --- a/assignment-client/src/audio/AudioMixer.cpp +++ b/assignment-client/src/audio/AudioMixer.cpp @@ -368,8 +368,7 @@ void AudioMixer::run() { && ((AudioMixerClientData*) node->getLinkedData())->getAvatarAudioRingBuffer()) { prepareMixForListeningNode(node.data()); - _clientMixBuffer.replace(numBytesPacketHeader, NETWORK_BUFFER_LENGTH_BYTES_STEREO, - reinterpret_cast(_clientSamples)); + memcpy(_clientMixBuffer.data() + numBytesPacketHeader, _clientSamples, NETWORK_BUFFER_LENGTH_BYTES_STEREO); nodeList->writeDatagram(_clientMixBuffer, node); } } From 07a71d87963953d8a758ac239082c2662e37c14a Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Mon, 17 Mar 2014 17:22:16 -0700 Subject: [PATCH 33/53] use char instead of QByteArray for mix samples in AudioMixer --- assignment-client/src/audio/AudioMixer.cpp | 7 +++---- assignment-client/src/audio/AudioMixer.h | 3 +-- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/assignment-client/src/audio/AudioMixer.cpp b/assignment-client/src/audio/AudioMixer.cpp index 1637f88859..34f53a65b4 100644 --- a/assignment-client/src/audio/AudioMixer.cpp +++ b/assignment-client/src/audio/AudioMixer.cpp @@ -62,8 +62,7 @@ void attachNewBufferToNode(Node *newNode) { } AudioMixer::AudioMixer(const QByteArray& packet) : - ThreadedAssignment(packet), - _clientMixBuffer(NETWORK_BUFFER_LENGTH_BYTES_STEREO + numBytesForPacketHeaderGivenPacketType(PacketTypeMixedAudio), 0) + ThreadedAssignment(packet) { connect(NodeList::getInstance(), &NodeList::uuidChanged, this, &AudioMixer::receivedSessionUUID); } @@ -372,8 +371,8 @@ void AudioMixer::run() { && ((AudioMixerClientData*) node->getLinkedData())->getAvatarAudioRingBuffer()) { prepareMixForListeningNode(node.data()); - memcpy(_clientMixBuffer.data() + numBytesPacketHeader, _clientSamples, NETWORK_BUFFER_LENGTH_BYTES_STEREO); - nodeList->writeDatagram(_clientMixBuffer, node); + memcpy(_clientMixBuffer + numBytesPacketHeader, _clientSamples, NETWORK_BUFFER_LENGTH_BYTES_STEREO); + nodeList->writeDatagram(_clientMixBuffer, NETWORK_BUFFER_LENGTH_BYTES_STEREO + numBytesPacketHeader, node); } } diff --git a/assignment-client/src/audio/AudioMixer.h b/assignment-client/src/audio/AudioMixer.h index 8032649c17..0db205d845 100644 --- a/assignment-client/src/audio/AudioMixer.h +++ b/assignment-client/src/audio/AudioMixer.h @@ -38,10 +38,9 @@ private: /// prepares and sends a mix to one Node void prepareMixForListeningNode(Node* node); - QByteArray _clientMixBuffer; - // client samples capacity is larger than what will be sent to optimize mixing int16_t _clientSamples[NETWORK_BUFFER_LENGTH_SAMPLES_STEREO + SAMPLE_PHASE_DELAY_AT_90]; + char _clientMixBuffer[NETWORK_BUFFER_LENGTH_BYTES_STEREO + MAX_PACKET_HEADER_BYTES]; }; #endif /* defined(__hifi__AudioMixer__) */ From 7ba595338ea9460d41c11e56f91fd2e34971cfab Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Mon, 17 Mar 2014 17:39:08 -0700 Subject: [PATCH 34/53] guard around update to last heard for a NULL matching node --- libraries/shared/src/NodeList.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/libraries/shared/src/NodeList.cpp b/libraries/shared/src/NodeList.cpp index 0cca9731b0..0354bd8bf9 100644 --- a/libraries/shared/src/NodeList.cpp +++ b/libraries/shared/src/NodeList.cpp @@ -267,7 +267,9 @@ void NodeList::processNodeData(const HifiSockAddr& senderSockAddr, const QByteAr // the node decided not to do anything with this packet // if it comes from a known source we should keep that node alive SharedNodePointer matchingNode = sendingNodeForPacket(packet); - matchingNode->setLastHeardMicrostamp(usecTimestampNow()); + if (matchingNode) { + matchingNode->setLastHeardMicrostamp(usecTimestampNow()); + } break; } From f3910f8c1af675d4b7fc6dc6efdb381b87cb3b9a Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Mon, 17 Mar 2014 17:54:27 -0700 Subject: [PATCH 35/53] scope clientMixBuffer only to AudioMixer run --- assignment-client/src/audio/AudioMixer.cpp | 16 +++++++--------- assignment-client/src/audio/AudioMixer.h | 3 --- 2 files changed, 7 insertions(+), 12 deletions(-) diff --git a/assignment-client/src/audio/AudioMixer.cpp b/assignment-client/src/audio/AudioMixer.cpp index 90a901f5c9..c5c112d0f0 100644 --- a/assignment-client/src/audio/AudioMixer.cpp +++ b/assignment-client/src/audio/AudioMixer.cpp @@ -64,7 +64,7 @@ void attachNewBufferToNode(Node *newNode) { AudioMixer::AudioMixer(const QByteArray& packet) : ThreadedAssignment(packet) { - connect(NodeList::getInstance(), &NodeList::uuidChanged, this, &AudioMixer::receivedSessionUUID); + } void AudioMixer::addBufferToMixForListeningNodeWithBuffer(PositionalAudioRingBuffer* bufferToAdd, @@ -332,10 +332,6 @@ void AudioMixer::readPendingDatagrams() { } } -void AudioMixer::receivedSessionUUID(const QUuid& sessionUUID) { - populatePacketHeader(_clientMixBuffer, PacketTypeMixedAudio); -} - void AudioMixer::run() { commonInit(AUDIO_MIXER_LOGGING_TARGET_NAME, NodeType::AudioMixer); @@ -350,8 +346,8 @@ void AudioMixer::run() { timeval startTime; gettimeofday(&startTime, NULL); - - int numBytesPacketHeader = numBytesForPacketHeaderGivenPacketType(PacketTypeMixedAudio); + + char clientMixBuffer[NETWORK_BUFFER_LENGTH_BYTES_STEREO + MAX_PACKET_HEADER_BYTES]; while (!_isFinished) { @@ -365,9 +361,11 @@ void AudioMixer::run() { if (node->getType() == NodeType::Agent && node->getActiveSocket() && node->getLinkedData() && ((AudioMixerClientData*) node->getLinkedData())->getAvatarAudioRingBuffer()) { prepareMixForListeningNode(node.data()); + + int numBytesPacketHeader = populatePacketHeader(clientMixBuffer, PacketTypeMixedAudio); - memcpy(_clientMixBuffer + numBytesPacketHeader, _clientSamples, NETWORK_BUFFER_LENGTH_BYTES_STEREO); - nodeList->writeDatagram(_clientMixBuffer, NETWORK_BUFFER_LENGTH_BYTES_STEREO + numBytesPacketHeader, node); + memcpy(clientMixBuffer + numBytesPacketHeader, _clientSamples, NETWORK_BUFFER_LENGTH_BYTES_STEREO); + nodeList->writeDatagram(clientMixBuffer, NETWORK_BUFFER_LENGTH_BYTES_STEREO + numBytesPacketHeader, node); } } diff --git a/assignment-client/src/audio/AudioMixer.h b/assignment-client/src/audio/AudioMixer.h index 0db205d845..5a68b0023f 100644 --- a/assignment-client/src/audio/AudioMixer.h +++ b/assignment-client/src/audio/AudioMixer.h @@ -28,8 +28,6 @@ public slots: void run(); void readPendingDatagrams(); -private slots: - void receivedSessionUUID(const QUuid& sessionUUID); private: /// adds one buffer to the mix for a listening node void addBufferToMixForListeningNodeWithBuffer(PositionalAudioRingBuffer* bufferToAdd, @@ -40,7 +38,6 @@ private: // client samples capacity is larger than what will be sent to optimize mixing int16_t _clientSamples[NETWORK_BUFFER_LENGTH_SAMPLES_STEREO + SAMPLE_PHASE_DELAY_AT_90]; - char _clientMixBuffer[NETWORK_BUFFER_LENGTH_BYTES_STEREO + MAX_PACKET_HEADER_BYTES]; }; #endif /* defined(__hifi__AudioMixer__) */ From 1fc9ac18151876edd3bc38a1a058e9453caf8ad3 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Mon, 17 Mar 2014 17:55:47 -0700 Subject: [PATCH 36/53] make the client mix buffer only as large as it needs to be --- assignment-client/src/audio/AudioMixer.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/assignment-client/src/audio/AudioMixer.cpp b/assignment-client/src/audio/AudioMixer.cpp index c5c112d0f0..a2c56405ec 100644 --- a/assignment-client/src/audio/AudioMixer.cpp +++ b/assignment-client/src/audio/AudioMixer.cpp @@ -347,7 +347,8 @@ void AudioMixer::run() { gettimeofday(&startTime, NULL); - char clientMixBuffer[NETWORK_BUFFER_LENGTH_BYTES_STEREO + MAX_PACKET_HEADER_BYTES]; + char* clientMixBuffer = new char[NETWORK_BUFFER_LENGTH_BYTES_STEREO + + numBytesForPacketHeaderGivenPacketType(PacketTypeMixedAudio)]; while (!_isFinished) { @@ -391,4 +392,6 @@ void AudioMixer::run() { } } + + delete[] clientMixBuffer; } From 75ab970c0d938f2157b4ae4735dc1ae7dd69b7c7 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Mon, 17 Mar 2014 18:23:09 -0700 Subject: [PATCH 37/53] fix bug: bad offset into avatar data during decode --- interface/src/avatar/AvatarManager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/avatar/AvatarManager.cpp b/interface/src/avatar/AvatarManager.cpp index 49479e903e..29b23e1f5b 100644 --- a/interface/src/avatar/AvatarManager.cpp +++ b/interface/src/avatar/AvatarManager.cpp @@ -152,6 +152,7 @@ void AvatarManager::processAvatarDataPacket(const QByteArray &datagram, const QW // only add them if mixerWeakPointer points to something (meaning that mixer is still around) while (bytesRead < datagram.size() && mixerWeakPointer.data()) { QUuid nodeUUID = QUuid::fromRfc4122(datagram.mid(bytesRead, NUM_BYTES_RFC4122_UUID)); + bytesRead += NUM_BYTES_RFC4122_UUID; AvatarSharedPointer matchingAvatar = _avatarHash.value(nodeUUID); @@ -167,7 +168,6 @@ void AvatarManager::processAvatarDataPacket(const QByteArray &datagram, const QW qDebug() << "Adding avatar with UUID" << nodeUUID << "to AvatarManager hash."; } - // have the matching (or new) avatar parse the data from the packet bytesRead += matchingAvatar->parseDataAtOffset(datagram, bytesRead); } From 3296447af67e59801e958c3eedabf033aac22e31 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Mon, 17 Mar 2014 18:23:55 -0700 Subject: [PATCH 38/53] remove dupe hand data from avatar updates partial progress toward issue #2256 --- libraries/avatars/src/AvatarData.cpp | 10 --- libraries/avatars/src/HandData.cpp | 117 --------------------------- libraries/avatars/src/HandData.h | 6 -- 3 files changed, 133 deletions(-) diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp index 5650d7a800..b1615ffb9d 100644 --- a/libraries/avatars/src/AvatarData.cpp +++ b/libraries/avatars/src/AvatarData.cpp @@ -93,7 +93,6 @@ QByteArray AvatarData::toByteArray() { destinationBuffer += packFloatAngleToTwoByte(destinationBuffer, _headData->getTweakedPitch()); destinationBuffer += packFloatAngleToTwoByte(destinationBuffer, _headData->getTweakedRoll()); - // Head lean X,Z (head lateral and fwd/back motion relative to torso) memcpy(destinationBuffer, &_headData->_leanSideways, sizeof(_headData->_leanSideways)); destinationBuffer += sizeof(_headData->_leanSideways); @@ -177,9 +176,6 @@ QByteArray AvatarData::toByteArray() { } } - // hand data - destinationBuffer += HandData::encodeData(_handData, destinationBuffer); - return avatarDataByteArray.left(destinationBuffer - startPosition); } @@ -302,12 +298,6 @@ int AvatarData::parseDataAtOffset(const QByteArray& packet, int offset) { } } - // hand data - if (sourceBuffer - startPosition < packet.size()) { - // check passed, bytes match - sourceBuffer += _handData->decodeRemoteData(packet.mid(sourceBuffer - startPosition)); - } - return sourceBuffer - startPosition; } diff --git a/libraries/avatars/src/HandData.cpp b/libraries/avatars/src/HandData.cpp index 15be4636a7..c84ed77dae 100644 --- a/libraries/avatars/src/HandData.cpp +++ b/libraries/avatars/src/HandData.cpp @@ -109,123 +109,6 @@ _owningHandData(owningHandData) setTrailLength(standardTrailLength); } -// static -int HandData::encodeData(HandData* hand, unsigned char* destinationBuffer) { - if (hand) { - return hand->encodeRemoteData(destinationBuffer); - } - // else encode empty data: - // One byte for zero hands - // One byte for error checking. - *destinationBuffer = 0; - *(destinationBuffer + 1) = 1; - return 2; -} - -int HandData::encodeRemoteData(unsigned char* destinationBuffer) { - const unsigned char* startPosition = destinationBuffer; - - unsigned int numPalms = 0; - for (unsigned int handIndex = 0; handIndex < getNumPalms(); ++handIndex) { - PalmData& palm = getPalms()[handIndex]; - if (palm.isActive()) { - numPalms++; - } - } - *destinationBuffer++ = numPalms; - - for (unsigned int handIndex = 0; handIndex < getNumPalms(); ++handIndex) { - PalmData& palm = getPalms()[handIndex]; - if (palm.isActive()) { - destinationBuffer += packFloatVec3ToSignedTwoByteFixed(destinationBuffer, palm.getRawPosition(), fingerVectorRadix); - destinationBuffer += packFloatVec3ToSignedTwoByteFixed(destinationBuffer, palm.getRawNormal(), fingerVectorRadix); - - unsigned int numFingers = 0; - for (unsigned int fingerIndex = 0; fingerIndex < palm.getNumFingers(); ++fingerIndex) { - FingerData& finger = palm.getFingers()[fingerIndex]; - if (finger.isActive()) { - numFingers++; - } - } - *destinationBuffer++ = numFingers; - - for (unsigned int fingerIndex = 0; fingerIndex < palm.getNumFingers(); ++fingerIndex) { - FingerData& finger = palm.getFingers()[fingerIndex]; - if (finger.isActive()) { - destinationBuffer += packFloatVec3ToSignedTwoByteFixed(destinationBuffer, finger.getTipRawPosition(), fingerVectorRadix); - destinationBuffer += packFloatVec3ToSignedTwoByteFixed(destinationBuffer, finger.getRootRawPosition(), fingerVectorRadix); - } - } - } - } - // One byte for error checking safety. - size_t checkLength = destinationBuffer - startPosition; - *destinationBuffer++ = (unsigned char)checkLength; - - // just a double-check, while tracing a crash. -// decodeRemoteData(destinationBuffer - (destinationBuffer - startPosition)); - - return destinationBuffer - startPosition; -} - -int HandData::decodeRemoteData(const QByteArray& dataByteArray) { - const unsigned char* startPosition; - const unsigned char* sourceBuffer = startPosition = reinterpret_cast(dataByteArray.data()); - unsigned int numPalms = *sourceBuffer++; - - for (unsigned int handIndex = 0; handIndex < numPalms; ++handIndex) { - if (handIndex >= (unsigned int)getNumPalms()) - addNewPalm(); - PalmData& palm = getPalms()[handIndex]; - - glm::vec3 handPosition; - glm::vec3 handNormal; - sourceBuffer += unpackFloatVec3FromSignedTwoByteFixed(sourceBuffer, handPosition, fingerVectorRadix); - sourceBuffer += unpackFloatVec3FromSignedTwoByteFixed(sourceBuffer, handNormal, fingerVectorRadix); - unsigned int numFingers = *sourceBuffer++; - - palm.setRawPosition(handPosition); - palm.setRawNormal(handNormal); - palm.setActive(true); - - // For received data, set the sixense controller ID to match the order initialized and sent - 0 Left, 1 Right - palm.setSixenseID(handIndex); - - for (unsigned int fingerIndex = 0; fingerIndex < numFingers; ++fingerIndex) { - if (fingerIndex < (unsigned int)palm.getNumFingers()) { - FingerData& finger = palm.getFingers()[fingerIndex]; - - glm::vec3 tipPosition; - glm::vec3 rootPosition; - sourceBuffer += unpackFloatVec3FromSignedTwoByteFixed(sourceBuffer, tipPosition, fingerVectorRadix); - sourceBuffer += unpackFloatVec3FromSignedTwoByteFixed(sourceBuffer, rootPosition, fingerVectorRadix); - - finger.setRawTipPosition(tipPosition); - finger.setRawRootPosition(rootPosition); - finger.setActive(true); - } - } - // Turn off any fingers which weren't used. - for (unsigned int fingerIndex = numFingers; fingerIndex < palm.getNumFingers(); ++fingerIndex) { - FingerData& finger = palm.getFingers()[fingerIndex]; - finger.setActive(false); - } - } - // Turn off any hands which weren't used. - for (unsigned int handIndex = numPalms; handIndex < getNumPalms(); ++handIndex) { - PalmData& palm = getPalms()[handIndex]; - palm.setActive(false); - } - - // One byte for error checking safety. Last byte contains the expected length (less itself) - // actualLength less expected byte = (sourceBuffer - startPosition) - // expectedLength less expected byte = (*sourceBuffer) - assert((unsigned char)(sourceBuffer - startPosition) == (unsigned char)(*sourceBuffer)); - sourceBuffer++; // skip the trailing byte which is expected length - - return sourceBuffer - startPosition; -} - void HandData::setFingerTrailLength(unsigned int length) { for (size_t i = 0; i < getNumPalms(); ++i) { PalmData& palm = getPalms()[i]; diff --git a/libraries/avatars/src/HandData.h b/libraries/avatars/src/HandData.h index f649faf080..fffc596247 100755 --- a/libraries/avatars/src/HandData.h +++ b/libraries/avatars/src/HandData.h @@ -63,12 +63,6 @@ public: void setFingerTrailLength(unsigned int length); void updateFingerTrails(); - static int encodeData(HandData* hand, unsigned char* destinationBuffer); - - // Use these for sending and receiving hand data - int encodeRemoteData(unsigned char* destinationBuffer); - int decodeRemoteData(const QByteArray& dataByteArray); - /// Checks for penetration between the described sphere and the hand. /// \param penetratorCenter the center of the penetration test sphere /// \param penetratorRadius the radius of the penetration test sphere From d80f110961277728a6022c5c569b23963d61b0c8 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Tue, 18 Mar 2014 09:12:23 -0700 Subject: [PATCH 39/53] Prevent audio average from becoming less than zero (thus causing sqrt to return nan, thus making our fake blendshape coefficient nan, thus making the jaw disappear). Closes #2334. --- interface/src/avatar/Head.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/interface/src/avatar/Head.cpp b/interface/src/avatar/Head.cpp index a9b85ffce2..44001a2015 100644 --- a/interface/src/avatar/Head.cpp +++ b/interface/src/avatar/Head.cpp @@ -90,8 +90,7 @@ void Head::simulate(float deltaTime, bool isMine, bool billboard) { _saccade += (_saccadeTarget - _saccade) * 0.50f; const float AUDIO_AVERAGING_SECS = 0.05f; - _averageLoudness = (1.f - deltaTime / AUDIO_AVERAGING_SECS) * _averageLoudness + - (deltaTime / AUDIO_AVERAGING_SECS) * _audioLoudness; + _averageLoudness = glm::mix(_averageLoudness, _audioLoudness, glm::min(deltaTime / AUDIO_AVERAGING_SECS, 1.0f)); // Detect transition from talking to not; force blink after that and a delay bool forceBlink = false; From 272cb879f8b9b24d65d4eb7c4ac9b9fff0c31d9f Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Tue, 18 Mar 2014 09:38:49 -0700 Subject: [PATCH 40/53] change wording of comment --- assignment-client/src/avatars/AvatarMixerClientData.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assignment-client/src/avatars/AvatarMixerClientData.cpp b/assignment-client/src/avatars/AvatarMixerClientData.cpp index a29b6efdb4..90088173a9 100644 --- a/assignment-client/src/avatars/AvatarMixerClientData.cpp +++ b/assignment-client/src/avatars/AvatarMixerClientData.cpp @@ -17,7 +17,7 @@ AvatarMixerClientData::AvatarMixerClientData() : } int AvatarMixerClientData::parseData(const QByteArray& packet) { - // increment to push past the packet header + // compute the offset to the data payload int offset = numBytesForPacketHeader(packet); return _avatar.parseDataAtOffset(packet, offset); } From b69c33927943cac68b8ffc42eaefb3a5b60b1afb Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Tue, 18 Mar 2014 09:39:05 -0700 Subject: [PATCH 41/53] don't send redundant head rot and hand pos info --- libraries/avatars/src/AvatarData.cpp | 38 ---------------------------- 1 file changed, 38 deletions(-) diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp index b1615ffb9d..8ed0ce51ec 100644 --- a/libraries/avatars/src/AvatarData.cpp +++ b/libraries/avatars/src/AvatarData.cpp @@ -88,22 +88,6 @@ QByteArray AvatarData::toByteArray() { // Body scale destinationBuffer += packFloatRatioToTwoByte(destinationBuffer, _targetScale); - // Head rotation (NOTE: This needs to become a quaternion to save two bytes) - destinationBuffer += packFloatAngleToTwoByte(destinationBuffer, _headData->getTweakedYaw()); - destinationBuffer += packFloatAngleToTwoByte(destinationBuffer, _headData->getTweakedPitch()); - destinationBuffer += packFloatAngleToTwoByte(destinationBuffer, _headData->getTweakedRoll()); - - // Head lean X,Z (head lateral and fwd/back motion relative to torso) - memcpy(destinationBuffer, &_headData->_leanSideways, sizeof(_headData->_leanSideways)); - destinationBuffer += sizeof(_headData->_leanSideways); - memcpy(destinationBuffer, &_headData->_leanForward, sizeof(_headData->_leanForward)); - destinationBuffer += sizeof(_headData->_leanForward); - - // Hand Position - is relative to body position - glm::vec3 handPositionRelative = _handPosition - _position; - memcpy(destinationBuffer, &handPositionRelative, sizeof(float) * 3); - destinationBuffer += sizeof(float) * 3; - // Lookat Position memcpy(destinationBuffer, &_headData->_lookAtPosition, sizeof(_headData->_lookAtPosition)); destinationBuffer += sizeof(_headData->_lookAtPosition); @@ -207,28 +191,6 @@ int AvatarData::parseDataAtOffset(const QByteArray& packet, int offset) { // Body scale sourceBuffer += unpackFloatRatioFromTwoByte(sourceBuffer, _targetScale); - // Head rotation (NOTE: This needs to become a quaternion to save two bytes) - float headYaw, headPitch, headRoll; - sourceBuffer += unpackFloatAngleFromTwoByte((uint16_t*) sourceBuffer, &headYaw); - sourceBuffer += unpackFloatAngleFromTwoByte((uint16_t*) sourceBuffer, &headPitch); - sourceBuffer += unpackFloatAngleFromTwoByte((uint16_t*) sourceBuffer, &headRoll); - - _headData->setYaw(headYaw); - _headData->setPitch(headPitch); - _headData->setRoll(headRoll); - - // Head position relative to pelvis - memcpy(&_headData->_leanSideways, sourceBuffer, sizeof(_headData->_leanSideways)); - sourceBuffer += sizeof(float); - memcpy(&_headData->_leanForward, sourceBuffer, sizeof(_headData->_leanForward)); - sourceBuffer += sizeof(_headData->_leanForward); - - // Hand Position - is relative to body position - glm::vec3 handPositionRelative; - memcpy(&handPositionRelative, sourceBuffer, sizeof(float) * 3); - _handPosition = _position + handPositionRelative; - sourceBuffer += sizeof(float) * 3; - // Lookat Position memcpy(&_headData->_lookAtPosition, sourceBuffer, sizeof(_headData->_lookAtPosition)); sourceBuffer += sizeof(_headData->_lookAtPosition); From 6aa1f286bbda109476b6a48f8823633948e538ec Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Tue, 18 Mar 2014 10:13:23 -0700 Subject: [PATCH 42/53] Alpha is the new default. --- libraries/shared/src/DomainInfo.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/shared/src/DomainInfo.h b/libraries/shared/src/DomainInfo.h index 35564e7cd8..da65525f9d 100644 --- a/libraries/shared/src/DomainInfo.h +++ b/libraries/shared/src/DomainInfo.h @@ -16,7 +16,7 @@ #include "HifiSockAddr.h" -const QString DEFAULT_DOMAIN_HOSTNAME = "root.highfidelity.io"; +const QString DEFAULT_DOMAIN_HOSTNAME = "alpha.highfidelity.io"; const unsigned short DEFAULT_DOMAIN_SERVER_PORT = 40102; class DomainInfo : public QObject { From 9079c3ecd83c6a52af1302068df9609e2bdc759b Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Tue, 18 Mar 2014 10:41:14 -0700 Subject: [PATCH 43/53] explicit casts to remove warnings --- interface/src/MetavoxelSystem.cpp | 5 +++-- interface/src/avatar/Hand.cpp | 4 ++-- interface/src/avatar/SkeletonModel.cpp | 2 +- libraries/metavoxels/src/MetavoxelData.cpp | 2 +- 4 files changed, 7 insertions(+), 6 deletions(-) diff --git a/interface/src/MetavoxelSystem.cpp b/interface/src/MetavoxelSystem.cpp index 54cc3b4cdb..23e50176eb 100644 --- a/interface/src/MetavoxelSystem.cpp +++ b/interface/src/MetavoxelSystem.cpp @@ -185,10 +185,11 @@ int MetavoxelSystem::SimulateVisitor::visit(MetavoxelInfo& info) { } QRgb color = info.inputValues.at(0).getInlineValue(); QRgb normal = info.inputValues.at(1).getInlineValue(); - int alpha = qAlpha(color); + quint8 alpha = qAlpha(color); if (alpha > 0) { Point point = { glm::vec4(info.minimum + glm::vec3(info.size, info.size, info.size) * 0.5f, info.size), - { qRed(color), qGreen(color), qBlue(color), alpha }, { qRed(normal), qGreen(normal), qBlue(normal) } }; + { quint8(qRed(color)), quint8(qGreen(color)), quint8(qBlue(color)), alpha }, + { quint8(qRed(normal)), quint8(qGreen(normal)), quint8(qBlue(normal)) } }; _points.append(point); } return STOP_RECURSION; diff --git a/interface/src/avatar/Hand.cpp b/interface/src/avatar/Hand.cpp index b4866c9478..43a1787d13 100644 --- a/interface/src/avatar/Hand.cpp +++ b/interface/src/avatar/Hand.cpp @@ -206,8 +206,8 @@ void Hand::collideAgainstOurself() { } // ignoring everything below the parent of the parent of the last free joint int skipIndex = skeletonModel.getParentJointIndex(skeletonModel.getParentJointIndex( - skeletonModel.getLastFreeJointIndex(((int)i == leftPalmIndex) ? skeletonModel.getLeftHandJointIndex() : - ((int)i == rightPalmIndex) ? skeletonModel.getRightHandJointIndex() : -1))); + skeletonModel.getLastFreeJointIndex((int(i) == leftPalmIndex) ? skeletonModel.getLeftHandJointIndex() : + (int(i) == rightPalmIndex) ? skeletonModel.getRightHandJointIndex() : -1))); handCollisions.clear(); if (_owningAvatar->findSphereCollisions(palm.getPosition(), scaledPalmRadius, handCollisions, skipIndex)) { diff --git a/interface/src/avatar/SkeletonModel.cpp b/interface/src/avatar/SkeletonModel.cpp index 1ffa3d838e..7173cb0b84 100644 --- a/interface/src/avatar/SkeletonModel.cpp +++ b/interface/src/avatar/SkeletonModel.cpp @@ -140,7 +140,7 @@ void SkeletonModel::applyPalmData(int jointIndex, const QVector& fingerJoin direction += fingerVector / length; } fingerVector = glm::inverse(palmRotation) * fingerVector * -sign; - IndexValue indexValue = { i, atan2f(fingerVector.z, fingerVector.x) }; + IndexValue indexValue = { int(i), atan2f(fingerVector.z, fingerVector.x) }; fingerIndices.append(indexValue); } qSort(fingerIndices.begin(), fingerIndices.end()); diff --git a/libraries/metavoxels/src/MetavoxelData.cpp b/libraries/metavoxels/src/MetavoxelData.cpp index 08cd62f30d..397e10d45f 100644 --- a/libraries/metavoxels/src/MetavoxelData.cpp +++ b/libraries/metavoxels/src/MetavoxelData.cpp @@ -1096,7 +1096,7 @@ QScriptValue ScriptedMetavoxelGuide::visit(QScriptContext* context, QScriptEngin QScriptValue minimum = infoValue.property(guide->_minimumHandle); MetavoxelInfo info = { glm::vec3(minimum.property(0).toNumber(), minimum.property(1).toNumber(), minimum.property(2).toNumber()), - infoValue.property(guide->_sizeHandle).toNumber(), guide->_visitation->info.inputValues, + float(infoValue.property(guide->_sizeHandle).toNumber()), guide->_visitation->info.inputValues, guide->_visitation->info.outputValues, infoValue.property(guide->_isLeafHandle).toBool() }; // extract and convert the values provided by the script From 7ed982a07333cdfcb3721a9845e789c227b4d80b Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 18 Mar 2014 11:12:36 -0700 Subject: [PATCH 44/53] cleanup writing of silent frame to ring buffer --- libraries/audio/src/AudioRingBuffer.cpp | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/libraries/audio/src/AudioRingBuffer.cpp b/libraries/audio/src/AudioRingBuffer.cpp index ba21c6c9b9..9cef64e216 100644 --- a/libraries/audio/src/AudioRingBuffer.cpp +++ b/libraries/audio/src/AudioRingBuffer.cpp @@ -157,16 +157,18 @@ unsigned int AudioRingBuffer::samplesAvailable() const { } void AudioRingBuffer::addSilentFrame(int numSilentSamples) { - // setup the silent frame - int numSilentBytes = numSilentSamples * sizeof(int16_t); - char* silentFrame = new char[numSilentBytes]; - memset(silentFrame, 0, numSilentBytes); - - // write it - writeData(silentFrame, numSilentBytes); - - // delete the temporary silent frame - delete[] silentFrame; + // memset zeroes into the buffer, accomodate a wrap around the end + // push the _endOfLastWrite to the correct spot + if (_endOfLastWrite + numSilentSamples <= _buffer + _sampleCapacity) { + memset(_endOfLastWrite, 0, numSilentSamples * sizeof(int16_t)); + _endOfLastWrite += numSilentSamples; + } else { + int numSamplesToEnd = (_buffer + _sampleCapacity) - _endOfLastWrite; + memset(_endOfLastWrite, 0, numSilentSamples * sizeof(int16_t)); + memset(_buffer, 0, (numSilentSamples - numSamplesToEnd) * sizeof(int16_t)); + + _endOfLastWrite = _buffer + (numSilentSamples - numSamplesToEnd); + } } bool AudioRingBuffer::isNotStarvedOrHasMinimumSamples(unsigned int numRequiredSamples) const { From c8d3cd2a1b8e3c8ed03fe02924900ed0194fafb2 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 18 Mar 2014 11:55:11 -0700 Subject: [PATCH 45/53] fix go to orientation to not put the user sideways --- interface/src/avatar/MyAvatar.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index e4aaa07a4b..5c94a7db9d 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -1158,6 +1158,8 @@ void MyAvatar::updateLocationInDataServer() { QString positionString(createByteArray(_position)); QString orientationString(createByteArray(glm::degrees(safeEulerAngles(getOrientation())))); + qDebug() << orientationString; + // construct the json to put the user's location QString locationPutJson = QString() + "{\"address\":{\"position\":\"" + positionString + "\", \"orientation\":\"" + orientationString + "\"}}"; @@ -1188,11 +1190,13 @@ void MyAvatar::goToLocationFromResponse(const QJsonObject& jsonObject) { NodeList::getInstance()->getDomainInfo().setHostname(domainHostnameString); + qDebug() << orientationItems[0] << orientationItems[1] << orientationItems[2]; + // orient the user to face the target glm::quat newOrientation = glm::quat(glm::vec3(orientationItems[0].toFloat(), orientationItems[1].toFloat(), orientationItems[2].toFloat())) - * glm::angleAxis(PI, glm::vec3(0.0f, 1.0f, 0.0f)); + * glm::angleAxis(180.0f, glm::vec3(0.0f, 1.0f, 0.0f)); setOrientation(newOrientation); // move the user a couple units away From 1d944ac829d647f1cf6e189f6204568b49411a25 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 18 Mar 2014 12:02:12 -0700 Subject: [PATCH 46/53] reset orientation to identity with spacebar, fix orientation storing --- interface/src/avatar/MyAvatar.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 5c94a7db9d..92039fb04a 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -85,6 +85,7 @@ void MyAvatar::reset() { setVelocity(glm::vec3(0,0,0)); setThrust(glm::vec3(0,0,0)); + setOrientation(glm::quat(glm::vec3(0,0,0))); } void MyAvatar::setMoveTarget(const glm::vec3 moveTarget) { @@ -1156,7 +1157,7 @@ void MyAvatar::updateLocationInDataServer() { if (accountManager.isLoggedIn()) { QString positionString(createByteArray(_position)); - QString orientationString(createByteArray(glm::degrees(safeEulerAngles(getOrientation())))); + QString orientationString(createByteArray(safeEulerAngles(getOrientation()))); qDebug() << orientationString; @@ -1196,7 +1197,7 @@ void MyAvatar::goToLocationFromResponse(const QJsonObject& jsonObject) { glm::quat newOrientation = glm::quat(glm::vec3(orientationItems[0].toFloat(), orientationItems[1].toFloat(), orientationItems[2].toFloat())) - * glm::angleAxis(180.0f, glm::vec3(0.0f, 1.0f, 0.0f)); + * glm::angleAxis(PI, glm::vec3(0.0f, 1.0f, 0.0f)); setOrientation(newOrientation); // move the user a couple units away From 05e2bb80228477bf317aebd051fa494addd02622 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 18 Mar 2014 12:04:03 -0700 Subject: [PATCH 47/53] keep storing degrees in data-web but convert on receipt --- interface/src/avatar/MyAvatar.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 92039fb04a..4d0403aa77 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -1157,7 +1157,7 @@ void MyAvatar::updateLocationInDataServer() { if (accountManager.isLoggedIn()) { QString positionString(createByteArray(_position)); - QString orientationString(createByteArray(safeEulerAngles(getOrientation()))); + QString orientationString(createByteArray(glm::degrees(safeEulerAngles(getOrientation())))); qDebug() << orientationString; @@ -1194,9 +1194,9 @@ void MyAvatar::goToLocationFromResponse(const QJsonObject& jsonObject) { qDebug() << orientationItems[0] << orientationItems[1] << orientationItems[2]; // orient the user to face the target - glm::quat newOrientation = glm::quat(glm::vec3(orientationItems[0].toFloat(), - orientationItems[1].toFloat(), - orientationItems[2].toFloat())) + glm::quat newOrientation = glm::quat(glm::radians(glm::vec3(orientationItems[0].toFloat(), + orientationItems[1].toFloat(), + orientationItems[2].toFloat()))) * glm::angleAxis(PI, glm::vec3(0.0f, 1.0f, 0.0f)); setOrientation(newOrientation); From c7c51c75048a56380312987cae96c6517cc7ba8d Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 18 Mar 2014 12:05:32 -0700 Subject: [PATCH 48/53] remove orientation string debug --- interface/src/avatar/MyAvatar.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 4d0403aa77..be27ab6ef2 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -1159,8 +1159,6 @@ void MyAvatar::updateLocationInDataServer() { QString positionString(createByteArray(_position)); QString orientationString(createByteArray(glm::degrees(safeEulerAngles(getOrientation())))); - qDebug() << orientationString; - // construct the json to put the user's location QString locationPutJson = QString() + "{\"address\":{\"position\":\"" + positionString + "\", \"orientation\":\"" + orientationString + "\"}}"; From db25ae886538199a6071876ac3736cd90c08b163 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 18 Mar 2014 12:27:45 -0700 Subject: [PATCH 49/53] remove extra debug --- interface/src/avatar/MyAvatar.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index be27ab6ef2..18305e1641 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -1189,8 +1189,6 @@ void MyAvatar::goToLocationFromResponse(const QJsonObject& jsonObject) { NodeList::getInstance()->getDomainInfo().setHostname(domainHostnameString); - qDebug() << orientationItems[0] << orientationItems[1] << orientationItems[2]; - // orient the user to face the target glm::quat newOrientation = glm::quat(glm::radians(glm::vec3(orientationItems[0].toFloat(), orientationItems[1].toFloat(), From a2fea49f582f69f18e803a132dc63267e43c1818 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Tue, 18 Mar 2014 12:36:48 -0700 Subject: [PATCH 50/53] bump version of PacketTypeAvatarData from 1 to 2 --- libraries/shared/src/PacketHeaders.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/shared/src/PacketHeaders.cpp b/libraries/shared/src/PacketHeaders.cpp index eccfa4fefa..307453d8bf 100644 --- a/libraries/shared/src/PacketHeaders.cpp +++ b/libraries/shared/src/PacketHeaders.cpp @@ -45,7 +45,7 @@ int packArithmeticallyCodedValue(int value, char* destination) { PacketVersion versionForPacketType(PacketType type) { switch (type) { case PacketTypeAvatarData: - return 1; + return 2; case PacketTypeParticleData: return 1; case PacketTypeDomainList: From e7acd0bad3f5f8f9ac68540bb7a16caee7d9cef5 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 18 Mar 2014 12:58:29 -0700 Subject: [PATCH 51/53] don't use QDataStream in parseData since we don't really need it --- libraries/audio/src/PositionalAudioRingBuffer.cpp | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/libraries/audio/src/PositionalAudioRingBuffer.cpp b/libraries/audio/src/PositionalAudioRingBuffer.cpp index 11e1a7c2ae..775786027d 100644 --- a/libraries/audio/src/PositionalAudioRingBuffer.cpp +++ b/libraries/audio/src/PositionalAudioRingBuffer.cpp @@ -38,28 +38,27 @@ PositionalAudioRingBuffer::~PositionalAudioRingBuffer() { } int PositionalAudioRingBuffer::parseData(const QByteArray& packet) { - QDataStream packetStream(packet); // skip the packet header (includes the source UUID) - packetStream.skipRawData(numBytesForPacketHeader(packet)); + int readBytes = numBytesForPacketHeader(packet); - packetStream.skipRawData(parsePositionalData(packet.mid(packetStream.device()->pos()))); + readBytes += parsePositionalData(packet.mid(readBytes)); if (packetTypeForPacket(packet) == PacketTypeSilentAudioFrame) { // this source had no audio to send us, but this counts as a packet // write silence equivalent to the number of silent samples they just sent us int16_t numSilentSamples; - packetStream.readRawData(reinterpret_cast(&numSilentSamples), sizeof(int16_t)); + memcpy(&numSilentSamples, packet.data(), sizeof(int16_t)); + readBytes += sizeof(int16_t); + addSilentFrame(numSilentSamples); } else { // there is audio data to read - packetStream.skipRawData(writeData(packet.data() + packetStream.device()->pos(), - packet.size() - packetStream.device()->pos())); + readBytes += writeData(packet.data() + readBytes, packet.size() - readBytes); } - - return packetStream.device()->pos(); + return readBytes; } int PositionalAudioRingBuffer::parsePositionalData(const QByteArray& positionalByteArray) { From 9fbb4f14282a01c2d5ebccea839599a3fee29a9e Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 18 Mar 2014 13:04:28 -0700 Subject: [PATCH 52/53] spacing fix and silent sample read fix --- libraries/audio/src/PositionalAudioRingBuffer.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/audio/src/PositionalAudioRingBuffer.cpp b/libraries/audio/src/PositionalAudioRingBuffer.cpp index 775786027d..66a27647d6 100644 --- a/libraries/audio/src/PositionalAudioRingBuffer.cpp +++ b/libraries/audio/src/PositionalAudioRingBuffer.cpp @@ -48,9 +48,9 @@ int PositionalAudioRingBuffer::parseData(const QByteArray& packet) { // this source had no audio to send us, but this counts as a packet // write silence equivalent to the number of silent samples they just sent us int16_t numSilentSamples; - memcpy(&numSilentSamples, packet.data(), sizeof(int16_t)); - readBytes += sizeof(int16_t); + memcpy(&numSilentSamples, packet.data() + readBytes, sizeof(int16_t)); + readBytes += sizeof(int16_t); addSilentFrame(numSilentSamples); } else { From f80a077637664a1e97131cb7b1dfcd19c55fb715 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 18 Mar 2014 13:33:29 -0700 Subject: [PATCH 53/53] fix memory overrun from silent sample writing --- libraries/audio/src/AudioRingBuffer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/audio/src/AudioRingBuffer.cpp b/libraries/audio/src/AudioRingBuffer.cpp index 9cef64e216..0e92ab4eb5 100644 --- a/libraries/audio/src/AudioRingBuffer.cpp +++ b/libraries/audio/src/AudioRingBuffer.cpp @@ -164,7 +164,7 @@ void AudioRingBuffer::addSilentFrame(int numSilentSamples) { _endOfLastWrite += numSilentSamples; } else { int numSamplesToEnd = (_buffer + _sampleCapacity) - _endOfLastWrite; - memset(_endOfLastWrite, 0, numSilentSamples * sizeof(int16_t)); + memset(_endOfLastWrite, 0, numSamplesToEnd * sizeof(int16_t)); memset(_buffer, 0, (numSilentSamples - numSamplesToEnd) * sizeof(int16_t)); _endOfLastWrite = _buffer + (numSilentSamples - numSamplesToEnd);