From a07b673f69e5684f379db990a2ae87ff6643de7f Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 3 Oct 2013 11:41:45 -0700 Subject: [PATCH 01/12] beginning of hook of AudioInjector into JS --- assignment-client/src/Agent.cpp | 46 ++++++++++++++++++++++++++--- assignment-client/src/Agent.h | 9 ++++++ assignment-client/src/main.cpp | 4 ++- libraries/audio/src/AudioInjector.h | 9 +++++- 4 files changed, 62 insertions(+), 6 deletions(-) diff --git a/assignment-client/src/Agent.cpp b/assignment-client/src/Agent.cpp index 2906233d78..d0f36402b5 100644 --- a/assignment-client/src/Agent.cpp +++ b/assignment-client/src/Agent.cpp @@ -8,8 +8,6 @@ #include -#include - #include #include #include @@ -17,11 +15,13 @@ #include "Agent.h" #include "voxels/VoxelScriptingInterface.h" +Agent* Agent::_staticInstance = NULL; + Agent::Agent(const unsigned char* dataBuffer, int numBytes) : Assignment(dataBuffer, numBytes), _shouldStop(false) { - + setStaticInstance(this); } void Agent::stop() { @@ -40,10 +40,40 @@ static size_t writeScriptDataToString(void *contents, size_t size, size_t nmemb, return realSize; } +void Agent::setStaticInstance(Agent* staticInstance) { + _staticInstance = staticInstance; +} + +QScriptValue Agent::AudioInjectorConstructor(QScriptContext *context, QScriptEngine *engine) { + AudioInjector* injector = new AudioInjector(BUFFER_LENGTH_SAMPLES_PER_CHANNEL); + + // add this injector to the vector of audio injectors so we know we have to tell it to send its audio during loop + _staticInstance->_audioInjectors.push_back(injector); + + return engine->newQObject(injector, QScriptEngine::ScriptOwnership); +} + +QScriptValue vec3toScriptValue(QScriptEngine *engine, const glm::vec3 &vec3) { + QScriptValue obj = engine->newObject(); + obj.setProperty("x", vec3.x); + obj.setProperty("y", vec3.y); + obj.setProperty("z", vec3.z); + return obj; +} + +void vec3FromScriptValue(const QScriptValue &object, glm::vec3 &vec3) { + vec3.x = object.property("x").toVariant().toFloat(); + vec3.y = object.property("y").toVariant().toFloat(); + vec3.z = object.property("z").toVariant().toFloat(); +} + void Agent::run() { NodeList* nodeList = NodeList::getInstance(); nodeList->setOwnerType(NODE_TYPE_AGENT); - nodeList->setNodeTypesOfInterest(&NODE_TYPE_VOXEL_SERVER, 1); + + const char AGENT_NODE_TYPES_OF_INTEREST[2] = { NODE_TYPE_VOXEL_SERVER, NODE_TYPE_AUDIO_MIXER }; + + nodeList->setNodeTypesOfInterest(AGENT_NODE_TYPES_OF_INTEREST, sizeof(AGENT_NODE_TYPES_OF_INTEREST)); nodeList->getNodeSocket()->setBlocking(false); @@ -83,6 +113,9 @@ void Agent::run() { QScriptEngine engine; + // register meta-type for glm::vec3 conversions + qScriptRegisterMetaType(&engine, vec3toScriptValue, vec3FromScriptValue); + QScriptValue agentValue = engine.newQObject(this); engine.globalObject().setProperty("Agent", agentValue); @@ -101,6 +134,11 @@ void Agent::run() { QScriptValue visualSendIntervalValue = engine.newVariant((QVariant(VISUAL_DATA_SEND_INTERVAL_USECS / 1000))); engine.globalObject().setProperty("VISUAL_DATA_SEND_INTERVAL_MS", visualSendIntervalValue); + // hook in a constructor for audio injectorss + QScriptValue audioInjectorConstructor = engine.newFunction(AudioInjectorConstructor); + QScriptValue audioMetaObject = engine.newQMetaObject(&AudioInjector::staticMetaObject, audioInjectorConstructor); + engine.globalObject().setProperty("AudioInjector", audioMetaObject); + qDebug() << "Downloaded script:" << scriptContents << "\n"; QScriptValue result = engine.evaluate(scriptContents); qDebug() << "Evaluated script.\n"; diff --git a/assignment-client/src/Agent.h b/assignment-client/src/Agent.h index 0490238d3f..84e8e11269 100644 --- a/assignment-client/src/Agent.h +++ b/assignment-client/src/Agent.h @@ -9,9 +9,13 @@ #ifndef __hifi__Agent__ #define __hifi__Agent__ +#include + +#include #include #include +#include #include class Agent : public Assignment { @@ -25,7 +29,12 @@ public slots: signals: void willSendVisualDataCallback(); private: + static void setStaticInstance(Agent* staticInstance); + static Agent* _staticInstance; + static QScriptValue AudioInjectorConstructor(QScriptContext *context, QScriptEngine *engine); + bool volatile _shouldStop; + std::vector _audioInjectors; }; #endif /* defined(__hifi__Operative__) */ diff --git a/assignment-client/src/main.cpp b/assignment-client/src/main.cpp index 75c8a00343..03578c4e8a 100644 --- a/assignment-client/src/main.cpp +++ b/assignment-client/src/main.cpp @@ -66,11 +66,13 @@ void childClient() { // create a request assignment, accept assignments defined by the overidden type Assignment requestAssignment(Assignment::RequestCommand, ::overiddenAssignmentType); + qDebug() << "Waiting for assignment -" << requestAssignment << "\n"; + while (true) { if (usecTimestampNow() - usecTimestamp(&lastRequest) >= ASSIGNMENT_REQUEST_INTERVAL_USECS) { gettimeofday(&lastRequest, NULL); + // if we're here we have no assignment, so send a request - qDebug() << "Sending an assignment request -" << requestAssignment << "\n"; nodeList->sendAssignment(requestAssignment); } diff --git a/libraries/audio/src/AudioInjector.h b/libraries/audio/src/AudioInjector.h index b102d58e19..b8e6cb823d 100644 --- a/libraries/audio/src/AudioInjector.h +++ b/libraries/audio/src/AudioInjector.h @@ -12,6 +12,8 @@ #include #include +#include + #include #include "AudioRingBuffer.h" @@ -22,7 +24,12 @@ const int MAX_INJECTOR_VOLUME = 0xFF; const int INJECT_INTERVAL_USECS = floorf((BUFFER_LENGTH_SAMPLES_PER_CHANNEL / SAMPLE_RATE) * 1000000); -class AudioInjector { +Q_DECLARE_METATYPE(glm::vec3) + +class AudioInjector : public QObject { + Q_OBJECT + + Q_PROPERTY(glm::vec3 position READ getPosition WRITE setPosition) public: AudioInjector(const char* filename); AudioInjector(int maxNumSamples); From e977d28fe338e431c8d0ee98baab648f34ee022c Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 3 Oct 2013 11:55:30 -0700 Subject: [PATCH 02/12] replace QVariantMap glm::vec3 setters with conversions for QScriptValue --- libraries/audio/src/AudioInjector.h | 3 +- libraries/avatars/src/AvatarData.cpp | 32 ---------------------- libraries/avatars/src/AvatarData.h | 15 ++++------ libraries/shared/src/RegisteredMetaTypes.h | 16 +++++++++++ 4 files changed, 23 insertions(+), 43 deletions(-) create mode 100644 libraries/shared/src/RegisteredMetaTypes.h diff --git a/libraries/audio/src/AudioInjector.h b/libraries/audio/src/AudioInjector.h index b8e6cb823d..5824086eb0 100644 --- a/libraries/audio/src/AudioInjector.h +++ b/libraries/audio/src/AudioInjector.h @@ -14,6 +14,7 @@ #include +#include #include #include "AudioRingBuffer.h" @@ -24,8 +25,6 @@ const int MAX_INJECTOR_VOLUME = 0xFF; const int INJECT_INTERVAL_USECS = floorf((BUFFER_LENGTH_SAMPLES_PER_CHANNEL / SAMPLE_RATE) * 1000000); -Q_DECLARE_METATYPE(glm::vec3) - class AudioInjector : public QObject { Q_OBJECT diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp index edc76bedca..66c33d4713 100644 --- a/libraries/avatars/src/AvatarData.cpp +++ b/libraries/avatars/src/AvatarData.cpp @@ -52,38 +52,6 @@ AvatarData::~AvatarData() { delete _handData; } -void AvatarData::setPositionFromVariantMap(QVariantMap positionMap) { - _position = glm::vec3(positionMap.value("x").toFloat(), - positionMap.value("y").toFloat(), - positionMap.value("z").toFloat()); -} - -QVariantMap AvatarData::getPositionVariantMap() { - QVariantMap positionMap; - - positionMap.insert("x", _position.x); - positionMap.insert("y", _position.y); - positionMap.insert("z", _position.z); - - return positionMap; -} - -void AvatarData::setHandPositionFromVariantMap(QVariantMap handPositionMap) { - _handPosition = glm::vec3(handPositionMap.value("x").toFloat(), - handPositionMap.value("y").toFloat(), - handPositionMap.value("z").toFloat()); -} - -QVariantMap AvatarData::getHandPositionVariantMap() { - QVariantMap positionMap; - - positionMap.insert("x", _handPosition.x); - positionMap.insert("y", _handPosition.y); - positionMap.insert("z", _handPosition.z); - - return positionMap; -} - void AvatarData::sendData() { // called from Agent visual loop to send data diff --git a/libraries/avatars/src/AvatarData.h b/libraries/avatars/src/AvatarData.h index 82ef0d671a..0b1181f8f2 100755 --- a/libraries/avatars/src/AvatarData.h +++ b/libraries/avatars/src/AvatarData.h @@ -19,6 +19,8 @@ #include #include +#include + #include #include "HeadData.h" #include "HandData.h" @@ -48,8 +50,8 @@ class JointData; class AvatarData : public NodeData { Q_OBJECT - Q_PROPERTY(QVariantMap position READ getPositionVariantMap WRITE setPositionFromVariantMap) - Q_PROPERTY(QVariantMap handPosition READ getHandPositionVariantMap WRITE setHandPositionFromVariantMap) + Q_PROPERTY(glm::vec3 position READ getPosition WRITE setPosition) + Q_PROPERTY(glm::vec3 handPosition READ getHandPosition WRITE setHandPosition) Q_PROPERTY(float bodyYaw READ getBodyYaw WRITE setBodyYaw) Q_PROPERTY(float bodyPitch READ getBodyPitch WRITE setBodyPitch) Q_PROPERTY(float bodyRoll READ getBodyRoll WRITE setBodyRoll) @@ -59,16 +61,11 @@ public: ~AvatarData(); const glm::vec3& getPosition() const { return _position; } - void setPosition(const glm::vec3 position) { _position = position; } + + const glm::vec3& getHandPosition() const { return _handPosition; } void setHandPosition(const glm::vec3 handPosition) { _handPosition = handPosition; } - void setPositionFromVariantMap(QVariantMap positionMap); - QVariantMap getPositionVariantMap(); - - void setHandPositionFromVariantMap(QVariantMap handPositionMap); - QVariantMap getHandPositionVariantMap(); - int getBroadcastData(unsigned char* destinationBuffer); int parseData(unsigned char* sourceBuffer, int numBytes); diff --git a/libraries/shared/src/RegisteredMetaTypes.h b/libraries/shared/src/RegisteredMetaTypes.h new file mode 100644 index 0000000000..e15e053ebb --- /dev/null +++ b/libraries/shared/src/RegisteredMetaTypes.h @@ -0,0 +1,16 @@ +// +// RegisteredMetaTypes.h +// hifi +// +// Created by Stephen Birarda on 10/3/13. +// Copyright (c) 2013 HighFidelity, Inc. All rights reserved. +// +// Used to register meta-types with Qt so that they can be used as properties for objects exposed to our +// Agent scripting. + +#ifndef hifi_RegisteredMetaTypes_h +#define hifi_RegisteredMetaTypes_h + +Q_DECLARE_METATYPE(glm::vec3) + +#endif From 0477ad79ddf781bcce0eaf3fb90d59337af25132 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Thu, 3 Oct 2013 13:22:02 -0700 Subject: [PATCH 03/12] add methods to set/get samples and volume --- libraries/audio/src/AudioInjector.cpp | 12 ++++++++++++ libraries/audio/src/AudioInjector.h | 4 ++++ 2 files changed, 16 insertions(+) diff --git a/libraries/audio/src/AudioInjector.cpp b/libraries/audio/src/AudioInjector.cpp index b9a6d8a0ba..cc0a329641 100644 --- a/libraries/audio/src/AudioInjector.cpp +++ b/libraries/audio/src/AudioInjector.cpp @@ -152,3 +152,15 @@ void AudioInjector::addSamples(int16_t* sampleBuffer, int numSamples) { _indexOfNextSlot += numSamples; } } + +int16_t& AudioInjector::sampleAt(const int index) { + assert(index >= 0 && index < _numTotalSamples); + + return _audioSampleArray[index]; +} + +void AudioInjector::insertSample(const int index, int16_t sample) { + assert (index >= 0 && index < _numTotalSamples); + + _audioSampleArray[index] = sample; +} diff --git a/libraries/audio/src/AudioInjector.h b/libraries/audio/src/AudioInjector.h index 5824086eb0..9054b08a16 100644 --- a/libraries/audio/src/AudioInjector.h +++ b/libraries/audio/src/AudioInjector.h @@ -29,6 +29,7 @@ class AudioInjector : public QObject { Q_OBJECT Q_PROPERTY(glm::vec3 position READ getPosition WRITE setPosition) + Q_PROPERTY(uchar volume READ getVolume WRITE setVolume); public: AudioInjector(const char* filename); AudioInjector(int maxNumSamples); @@ -54,6 +55,9 @@ public: void addSample(const int16_t sample); void addSamples(int16_t* sampleBuffer, int numSamples); +public slots: + int16_t& sampleAt(const int index); + void insertSample(const int index, int16_t sample); private: unsigned char _streamIdentifier[STREAM_IDENTIFIER_NUM_BYTES]; int16_t* _audioSampleArray; From 40dd6982937c293826648a51b90d08e96b8f57df Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 8 Oct 2013 11:07:46 -0700 Subject: [PATCH 04/12] =?UTF-8?q?don=E2=80=99t=20have=20AvatarMixer=20ask?= =?UTF-8?q?=20DS=20for=20agents?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- assignment-client/src/avatars/AvatarMixer.cpp | 12 +++++------- libraries/shared/src/NodeList.cpp | 13 ++++++++++++- libraries/shared/src/NodeList.h | 2 +- libraries/shared/src/UDPSocket.cpp | 4 ++-- 4 files changed, 20 insertions(+), 11 deletions(-) diff --git a/assignment-client/src/avatars/AvatarMixer.cpp b/assignment-client/src/avatars/AvatarMixer.cpp index 1a4f9844eb..5c7e47a42a 100644 --- a/assignment-client/src/avatars/AvatarMixer.cpp +++ b/assignment-client/src/avatars/AvatarMixer.cpp @@ -98,7 +98,7 @@ void AvatarMixer::run() { nodeList->startSilentNodeRemovalThread(); - sockaddr* nodeAddress = new sockaddr; + sockaddr nodeAddress = {}; ssize_t receivedBytes = 0; unsigned char* packetData = new unsigned char[MAX_PACKET_SIZE]; @@ -107,8 +107,6 @@ void AvatarMixer::run() { Node* avatarNode = NULL; timeval lastDomainServerCheckIn = {}; - // we only need to hear back about avatar nodes from the DS - nodeList->setNodeTypesOfInterest(&NODE_TYPE_AGENT, 1); while (true) { @@ -122,7 +120,7 @@ void AvatarMixer::run() { NodeList::getInstance()->sendDomainServerCheckIn(_uuid.toRfc4122().constData()); } - if (nodeList->getNodeSocket()->receive(nodeAddress, packetData, &receivedBytes) && + if (nodeList->getNodeSocket()->receive(&nodeAddress, packetData, &receivedBytes) && packetVersionMatch(packetData)) { switch (packetData[0]) { case PACKET_TYPE_HEAD_DATA: @@ -130,12 +128,12 @@ void AvatarMixer::run() { unpackNodeId(packetData + numBytesForPacketHeader(packetData), &nodeID); // add or update the node in our list - avatarNode = nodeList->addOrUpdateNode(nodeAddress, nodeAddress, NODE_TYPE_AGENT, nodeID); + avatarNode = nodeList->addOrUpdateNode(&nodeAddress, &nodeAddress, NODE_TYPE_AGENT, nodeID); // parse positional data from an node nodeList->updateNodeWithData(avatarNode, packetData, receivedBytes); case PACKET_TYPE_INJECT_AUDIO: - broadcastAvatarData(nodeList, nodeAddress); + broadcastAvatarData(nodeList, &nodeAddress); break; case PACKET_TYPE_AVATAR_URLS: case PACKET_TYPE_AVATAR_FACE_VIDEO: @@ -151,7 +149,7 @@ void AvatarMixer::run() { break; default: // hand this off to the NodeList - nodeList->processNodeData(nodeAddress, packetData, receivedBytes); + nodeList->processNodeData(&nodeAddress, packetData, receivedBytes); break; } } diff --git a/libraries/shared/src/NodeList.cpp b/libraries/shared/src/NodeList.cpp index 4307810db3..b22b3188a6 100644 --- a/libraries/shared/src/NodeList.cpp +++ b/libraries/shared/src/NodeList.cpp @@ -428,18 +428,23 @@ void NodeList::sendAssignment(Assignment& assignment) { } Node* NodeList::addOrUpdateNode(sockaddr* publicSocket, sockaddr* localSocket, char nodeType, uint16_t nodeId) { + qDebug() << "BEGIN:" << publicSocket << "and" << localSocket << "\n"; NodeList::iterator node = end(); if (publicSocket) { for (node = begin(); node != end(); node++) { + qDebug() << "comparing to node with ID " << node->getNodeID() << "\n"; if (node->matches(publicSocket, localSocket, nodeType)) { // we already have this node, stop checking + qDebug() << "Matched node to existing\n"; break; } } } - if (node == end()) { + if (node == end()) { + qDebug() << "We're considering this a new node!\n"; + qDebug() << publicSocket << "and" << localSocket << "\n"; // we didn't have this node, so add them Node* newNode = new Node(publicSocket, localSocket, nodeType, nodeId); @@ -540,6 +545,10 @@ void* removeSilentNodes(void *args) { for(NodeList::iterator node = nodeList->begin(); node != nodeList->end(); ++node) { + node->lock(); + + qDebug() << "This node's LHMS is" << node->getLastHeardMicrostamp() << "\n"; + if ((checkTimeUSecs - node->getLastHeardMicrostamp()) > NODE_SILENCE_THRESHOLD_USECS) { qDebug() << "Killed " << *node << "\n"; @@ -548,6 +557,8 @@ void* removeSilentNodes(void *args) { node->setAlive(false); } + + node->unlock(); } sleepTime = NODE_SILENCE_THRESHOLD_USECS - (usecTimestampNow() - checkTimeUSecs); diff --git a/libraries/shared/src/NodeList.h b/libraries/shared/src/NodeList.h index 1bac084fe5..9914ac9094 100644 --- a/libraries/shared/src/NodeList.h +++ b/libraries/shared/src/NodeList.h @@ -30,7 +30,7 @@ const int NODES_PER_BUCKET = 100; const int MAX_PACKET_SIZE = 1500; -const int NODE_SILENCE_THRESHOLD_USECS = 2 * 1000000; +const uint64_t NODE_SILENCE_THRESHOLD_USECS = 2 * 1000000; const int DOMAIN_SERVER_CHECK_IN_USECS = 1 * 1000000; extern const char SOLO_NODE_TYPES[2]; diff --git a/libraries/shared/src/UDPSocket.cpp b/libraries/shared/src/UDPSocket.cpp index beee5c6879..68eb2ad82e 100644 --- a/libraries/shared/src/UDPSocket.cpp +++ b/libraries/shared/src/UDPSocket.cpp @@ -43,7 +43,7 @@ bool socketMatch(const sockaddr* first, const sockaddr* second) { const sockaddr_in *secondIn = (const sockaddr_in *) second; return firstIn->sin_addr.s_addr == secondIn->sin_addr.s_addr - && firstIn->sin_port == secondIn->sin_port; + && firstIn->sin_port == secondIn->sin_port; } else { return false; } @@ -254,7 +254,7 @@ bool UDPSocket::receive(sockaddr* recvAddress, void* receivedData, ssize_t* rece #ifdef _WIN32 int addressSize = sizeof(*recvAddress); #else - socklen_t addressSize = sizeof(&recvAddress); + socklen_t addressSize = sizeof(*recvAddress); #endif *receivedBytes = recvfrom(handle, static_cast(receivedData), MAX_BUFFER_LENGTH_BYTES, 0, recvAddress, &addressSize); From 4be07ececbe9863b934fa23c4daf5389510c6817 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Fri, 11 Oct 2013 01:30:09 -0700 Subject: [PATCH 05/12] fixed a couple crashes and cleaned up some code --- interface/src/Application.cpp | 1 + interface/src/VoxelSystem.cpp | 81 +++++++++++++++++++++-------------- interface/src/VoxelSystem.h | 4 +- 3 files changed, 54 insertions(+), 32 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 5a3d85ded8..b7a49f234b 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -154,6 +154,7 @@ Application::Application(int& argc, char** argv, timeval &startup_time) : NodeList::getInstance()->addHook(&_voxels); NodeList::getInstance()->addHook(this); NodeList::getInstance()->addDomainListener(this); + NodeList::getInstance()->addDomainListener(&_voxels); // network receive thread and voxel parsing thread are both controlled by the --nonblocking command line diff --git a/interface/src/VoxelSystem.cpp b/interface/src/VoxelSystem.cpp index 9ea37be662..574615d113 100644 --- a/interface/src/VoxelSystem.cpp +++ b/interface/src/VoxelSystem.cpp @@ -109,8 +109,14 @@ VoxelSystem::VoxelSystem(float treeScale, int maxVoxels) } void VoxelSystem::voxelDeleted(VoxelNode* node) { - if (node->isKnownBufferIndex() && (node->getVoxelSystem() == this)) { - forceRemoveNodeFromArrays(node); + if (node->getVoxelSystem() == this) { + if (_voxelsInWriteArrays != 0) { + forceRemoveNodeFromArrays(node); + } else { + if (Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings)) { + printf("VoxelSystem::voxelDeleted() while _voxelsInWriteArrays==0, is that expected? \n"); + } + } } } @@ -223,10 +229,15 @@ void VoxelSystem::freeBufferIndex(glBufferIndex index) { // This will run through the list of _freeIndexes and reset their VBO array values to be "invisible". void VoxelSystem::clearFreeBufferIndexes() { PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), "###### clearFreeBufferIndexes()"); + _voxelsInWriteArrays = 0; // reset our VBO + _abandonedVBOSlots = 0; + + // clear out freeIndexes pthread_mutex_lock(&_freeIndexLock); _freeIndexes.clear(); - _abandonedVBOSlots = 0; pthread_mutex_unlock(&_freeIndexLock); + + clearAllNodesBufferIndex(); } VoxelSystem::~VoxelSystem() { @@ -438,7 +449,6 @@ void VoxelSystem::initVoxelMemory() { // Global Normals mode uses a technique of not including normals on any voxel vertices, and instead // rendering the voxel faces in 6 passes that use a global call to glNormal3f() - qDebug("Using Global Normals...\n"); setupFaceIndices(_vboIndicesTop, identityIndicesTop); setupFaceIndices(_vboIndicesBottom, identityIndicesBottom); setupFaceIndices(_vboIndicesLeft, identityIndicesLeft); @@ -596,11 +606,7 @@ int VoxelSystem::parseData(unsigned char* sourceBuffer, int numBytes) { while (totalLength <= numBytes) { if (0==strcmp(command,(char*)"erase all")) { - qDebug("got Z message == erase all\n"); - pthread_mutex_lock(&_treeLock); - _tree->eraseAllVoxels(); - pthread_mutex_unlock(&_treeLock); - _voxelsInReadArrays = _voxelsInWriteArrays = 0; // better way to do this?? + qDebug("got Z message == erase all - NOT SUPPORTED ON INTERFACE\n"); } if (0==strcmp(command,(char*)"add scene")) { qDebug("got Z message == add scene - NOT SUPPORTED ON INTERFACE\n"); @@ -652,8 +658,6 @@ void VoxelSystem::setupNewVoxelsForDrawing() { PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), buffer); _callsToTreesToArrays++; if (_writeRenderFullVBO) { - printf("resetting _freeIndexes and _voxelsInWriteArrays\n"); - _voxelsInWriteArrays = 0; // reset our VBO clearFreeBufferIndexes(); } _voxelsUpdated = newTreeToArrays(_tree->rootNode); @@ -972,10 +976,10 @@ int VoxelSystem::updateNodeInArrays(VoxelNode* node, bool reuseIndex, bool force updateArraysDetails(nodeIndex, startVertex, voxelScale, node->getColor()); return 1; // updated! } else { - // If we shouldn't render, but we did have a known index, then we will need to release our index - if (reuseIndex && node->isKnownBufferIndex()) { - forceRemoveNodeFromArrays(node); - return 1; // updated! + // If we shouldn't render, and we're in reuseIndex mode, then free our index, this only operates + // on nodes with known index values, so it's safe to call for any node. + if (reuseIndex) { + return forceRemoveNodeFromArrays(node); } } } @@ -1284,8 +1288,11 @@ void VoxelSystem::removeScaleAndReleaseProgram(bool texture) { int VoxelSystem::_nodeCount = 0; void VoxelSystem::killLocalVoxels() { + pthread_mutex_lock(&_treeLock); _tree->eraseAllVoxels(); - _voxelsInWriteArrays = _voxelsInReadArrays = 0; // better way to do this?? + pthread_mutex_unlock(&_treeLock); + clearFreeBufferIndexes(); + _voxelsInReadArrays = 0; // do we need to do this? setupNewVoxelsForDrawing(); } @@ -1298,8 +1305,12 @@ bool VoxelSystem::clearAllNodesBufferIndexOperation(VoxelNode* node, void* extra void VoxelSystem::clearAllNodesBufferIndex() { _nodeCount = 0; + pthread_mutex_lock(&_treeLock); _tree->recurseTreeWithOperation(clearAllNodesBufferIndexOperation); - qDebug("clearing buffer index of %d nodes\n", _nodeCount); + pthread_mutex_unlock(&_treeLock); + if (Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings)) { + qDebug("clearing buffer index of %d nodes\n", _nodeCount); + } } bool VoxelSystem::forceRedrawEntireTreeOperation(VoxelNode* node, void* extraData) { @@ -1700,8 +1711,7 @@ bool VoxelSystem::hideAllSubTreeOperation(VoxelNode* node, void* extraData) { if (node->isKnownBufferIndex()) { args->nodesRemoved++; VoxelSystem* thisVoxelSystem = args->thisVoxelSystem; - thisVoxelSystem->forceRemoveNodeFromArrays(node); - thisVoxelSystem->_voxelsUpdated++; + thisVoxelSystem->_voxelsUpdated += thisVoxelSystem->forceRemoveNodeFromArrays(node); thisVoxelSystem->setupNewVoxelsForDrawingSingleNode(); } @@ -1714,10 +1724,10 @@ bool VoxelSystem::showAllSubTreeOperation(VoxelNode* node, void* extraData) { args->nodesInside++; if (node->getShouldRender() && !node->isKnownBufferIndex()) { - node->setDirtyBit(); // will this make it draw? + node->setDirtyBit(); // will this make it draw! } - return true; + return true; // keep recursing! } @@ -1841,7 +1851,7 @@ void VoxelSystem::falseColorizeRandomEveryOther() { class collectStatsForTreesAndVBOsArgs { public: - collectStatsForTreesAndVBOsArgs() : + collectStatsForTreesAndVBOsArgs(int maxVoxels) : totalNodes(0), dirtyNodes(0), shouldRenderNodes(0), @@ -1852,8 +1862,13 @@ public: duplicateVBOIndex(0), leafNodes(0) { - memset(hasIndexFound, false, DEFAULT_MAX_VOXELS_PER_SYSTEM * sizeof(bool)); + hasIndexFound = new bool[maxVoxels]; + memset(hasIndexFound, false, maxVoxels * sizeof(bool)); }; + + ~collectStatsForTreesAndVBOsArgs() { + delete[] hasIndexFound; + } unsigned long totalNodes; unsigned long dirtyNodes; @@ -1867,7 +1882,7 @@ public: unsigned long expectedMax; - bool hasIndexFound[DEFAULT_MAX_VOXELS_PER_SYSTEM]; + bool* hasIndexFound; }; bool VoxelSystem::collectStatsForTreesAndVBOsOperation(VoxelNode* node, void* extraData) { @@ -1934,7 +1949,7 @@ void VoxelSystem::collectStatsForTreesAndVBOs() { } } - collectStatsForTreesAndVBOsArgs args; + collectStatsForTreesAndVBOsArgs args(_maxVoxels); args.expectedMax = _voxelsInWriteArrays; qDebug("CALCULATING Local Voxel Tree Statistics >>>>>>>>>>>>\n"); @@ -1953,7 +1968,7 @@ void VoxelSystem::collectStatsForTreesAndVBOs() { glBufferIndex minInVBO = GLBUFFER_INDEX_UNKNOWN; glBufferIndex maxInVBO = 0; - for (glBufferIndex i = 0; i < DEFAULT_MAX_VOXELS_PER_SYSTEM; i++) { + for (glBufferIndex i = 0; i < _maxVoxels; i++) { if (args.hasIndexFound[i]) { minInVBO = std::min(minInVBO,i); maxInVBO = std::max(maxInVBO,i); @@ -1972,13 +1987,12 @@ void VoxelSystem::collectStatsForTreesAndVBOs() { void VoxelSystem::deleteVoxelAt(float x, float y, float z, float s) { pthread_mutex_lock(&_treeLock); - _tree->deleteVoxelAt(x, y, z, s); + pthread_mutex_unlock(&_treeLock); // redraw! setupNewVoxelsForDrawing(); // do we even need to do this? Or will the next network receive kick in? - pthread_mutex_unlock(&_treeLock); }; VoxelNode* VoxelSystem::getVoxelAt(float x, float y, float z, float s) const { @@ -2313,17 +2327,22 @@ void VoxelSystem::nodeKilled(Node* node) { if (_voxelServerCount > 0) { // Kill any voxels from the local tree that match this nodeID + pthread_mutex_lock(&_treeLock); _tree->recurseTreeWithOperation(killSourceVoxelsOperation, &nodeID); + pthread_mutex_unlock(&_treeLock); _tree->setDirtyBit(); + setupNewVoxelsForDrawing(); } else { // Last server, take the easy way and kill all the local voxels! - _tree->eraseAllVoxels(); - _voxelsInWriteArrays = _voxelsInReadArrays = 0; // better way to do this?? + killLocalVoxels(); } - setupNewVoxelsForDrawing(); } } +void VoxelSystem::domainChanged(QString domain) { + killLocalVoxels(); +} + unsigned long VoxelSystem::getFreeMemoryGPU() { // We can't ask all GPUs how much memory they have in use, but we can ask them about how much is free. diff --git a/interface/src/VoxelSystem.h b/interface/src/VoxelSystem.h index 5f026e043c..1af6b19ca7 100644 --- a/interface/src/VoxelSystem.h +++ b/interface/src/VoxelSystem.h @@ -37,7 +37,8 @@ struct VoxelShaderVBOData }; -class VoxelSystem : public NodeData, public VoxelNodeDeleteHook, public VoxelNodeUpdateHook, public NodeListHook { +class VoxelSystem : public NodeData, public VoxelNodeDeleteHook, public VoxelNodeUpdateHook, + public NodeListHook, public DomainChangeListener { Q_OBJECT public: VoxelSystem(float treeScale = TREE_SCALE, int maxVoxels = DEFAULT_MAX_VOXELS_PER_SYSTEM); @@ -112,6 +113,7 @@ public: virtual void voxelUpdated(VoxelNode* node); virtual void nodeAdded(Node* node); virtual void nodeKilled(Node* node); + virtual void domainChanged(QString domain); signals: void importSize(float x, float y, float z); From dfe23c934289e4d78d37852ec32d2739958d1008 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Fri, 11 Oct 2013 12:49:50 -0700 Subject: [PATCH 06/12] merge cleanup --- interface/src/Application.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index c9bf76350a..b7a49f234b 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -3526,9 +3526,6 @@ void Application::domainChanged(QString domain) { // update the user's last domain in their Profile (which will propagate to data-server) _profile.updateDomain(domain); - // kill the local voxels - _voxels.killLocalVoxels(); - // reset the environment so that we don't erroneously end up with multiple _environment.resetToDefault(); } From e91127bc5cfde808d19272280c91789482ef5a59 Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Fri, 11 Oct 2013 14:56:37 -0700 Subject: [PATCH 07/12] implement hide cursor on no mouse movement --- interface/src/Application.cpp | 17 +++++++++++++++++ interface/src/Application.h | 2 ++ 2 files changed, 19 insertions(+) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index bdd1f8379f..a90244cd21 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -105,6 +105,8 @@ Application::Application(int& argc, char** argv, timeval &startup_time) : _profile(QString()), _mouseX(0), _mouseY(0), + _lastMouseMove(usecTimestampNow()), + _mouseHidden(false), _touchAvgX(0.0f), _touchAvgY(0.0f), _isTouchPressed(false), @@ -978,6 +980,12 @@ void Application::keyReleaseEvent(QKeyEvent* event) { } void Application::mouseMoveEvent(QMouseEvent* event) { + _lastMouseMove = usecTimestampNow(); + if (_mouseHidden) { + getGLWidget()->setCursor(Qt::ArrowCursor); + _mouseHidden = false; + } + if (activeWindow() == _window) { _mouseX = event->x(); _mouseY = event->y(); @@ -2119,6 +2127,15 @@ void Application::update(float deltaTime) { _audio.setLastVelocity(_myAvatar.getVelocity()); _audio.eventuallyAnalyzePing(); #endif + + // watch mouse position, if it hasn't moved, hide the cursor + uint64_t now = usecTimestampNow(); + int elapsed = now - _lastMouseMove; + const int HIDE_CURSOR_TIMEOUT = 1 * 1000 * 1000; // 1 second + if (elapsed > HIDE_CURSOR_TIMEOUT) { + getGLWidget()->setCursor(Qt::BlankCursor); + _mouseHidden = true; + } } void Application::updateAvatar(float deltaTime) { diff --git a/interface/src/Application.h b/interface/src/Application.h index c030b61a74..cb3a3ca73d 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -305,6 +305,8 @@ private: int _mouseY; int _mouseDragStartedX; int _mouseDragStartedY; + uint64_t _lastMouseMove; + bool _mouseHidden; float _touchAvgX; float _touchAvgY; From 6369e9959f49c5c09d1b337f6f8c98a79f9cee80 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Fri, 11 Oct 2013 15:25:17 -0700 Subject: [PATCH 08/12] change goToUser shortcut to @ --- interface/src/Application.cpp | 3 +++ interface/src/Menu.cpp | 2 +- interface/src/Menu.h | 2 +- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index bdd1f8379f..b1beb872df 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -908,6 +908,9 @@ void Application::keyPressEvent(QKeyEvent* event) { case Qt::Key_8: _swatch.handleEvent(event->key(), Menu::getInstance()->isOptionChecked(MenuOption::VoxelGetColorMode)); break; + case Qt::Key_At: + Menu::getInstance()->goToUser(); + break; default: event->ignore(); break; diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index 3dda04d8df..f9479865c6 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -101,7 +101,7 @@ Menu::Menu() : SLOT(goToLocation())); addActionToQMenuAndActionHash(fileMenu, MenuOption::GoToUser, - Qt::CTRL | Qt::SHIFT | Qt::Key_U, + Qt::Key_At, this, SLOT(goToUser())); diff --git a/interface/src/Menu.h b/interface/src/Menu.h index 688d0d3c34..81d213c026 100644 --- a/interface/src/Menu.h +++ b/interface/src/Menu.h @@ -66,6 +66,7 @@ public slots: void saveSettings(QSettings* settings = NULL); void importSettings(); void exportSettings(); + void goToUser(); private slots: void aboutApp(); @@ -73,7 +74,6 @@ private slots: void editPreferences(); void goToDomain(); void goToLocation(); - void goToUser(); void bandwidthDetailsClosed(); void voxelStatsDetailsClosed(); void cycleFrustumRenderMode(); From 6281a28f6966e87efd0b729277e501ce466e58fb Mon Sep 17 00:00:00 2001 From: Philip Rosedale Date: Fri, 11 Oct 2013 17:00:25 -0700 Subject: [PATCH 09/12] better movement near others --- interface/src/avatar/MyAvatar.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index ee4f0c4811..181c320b69 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -221,12 +221,14 @@ void MyAvatar::simulate(float deltaTime, Transmitter* transmitter) { // Damp avatar velocity const float LINEAR_DAMPING_STRENGTH = 0.5f; const float SPEED_BRAKE_POWER = _scale * 10.0f; - const float SQUARED_DAMPING_STRENGTH = 0.007f; + const float SQUARED_DAMPING_STRENGTH = 0.007f; + const float SLOW_NEAR_RADIUS = 5.f; float linearDamping = LINEAR_DAMPING_STRENGTH; - const float AVATAR_DAMPING_FACTOR = 120.f; - if (_distanceToNearestAvatar < _scale * PERIPERSONAL_RADIUS) { - linearDamping *= 1.f + AVATAR_DAMPING_FACTOR * (PERIPERSONAL_RADIUS - _distanceToNearestAvatar); + const float NEAR_AVATAR_DAMPING_FACTOR = 50.f; + if (_distanceToNearestAvatar < _scale * SLOW_NEAR_RADIUS) { + linearDamping *= 1.f + NEAR_AVATAR_DAMPING_FACTOR * + ((SLOW_NEAR_RADIUS - _distanceToNearestAvatar) / SLOW_NEAR_RADIUS); } if (_speedBrakes) { applyDamping(deltaTime, _velocity, linearDamping * SPEED_BRAKE_POWER, SQUARED_DAMPING_STRENGTH * SPEED_BRAKE_POWER); From 0eae0f129cd96f473baa1979ec89625803e14e2b Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Fri, 11 Oct 2013 17:37:48 -0700 Subject: [PATCH 10/12] allow audio injection from javascript --- assignment-client/src/Agent.cpp | 75 ++++++++++++--------------- assignment-client/src/Agent.h | 1 + libraries/audio/src/AudioInjector.cpp | 32 ++++-------- libraries/audio/src/AudioInjector.h | 5 +- libraries/shared/src/NodeList.cpp | 2 - 5 files changed, 45 insertions(+), 70 deletions(-) diff --git a/assignment-client/src/Agent.cpp b/assignment-client/src/Agent.cpp index b2b4a72a10..81fe4cb5e5 100644 --- a/assignment-client/src/Agent.cpp +++ b/assignment-client/src/Agent.cpp @@ -45,15 +45,6 @@ void Agent::setStaticInstance(Agent* staticInstance) { _staticInstance = staticInstance; } -QScriptValue Agent::AudioInjectorConstructor(QScriptContext *context, QScriptEngine *engine) { - AudioInjector* injector = new AudioInjector(BUFFER_LENGTH_SAMPLES_PER_CHANNEL); - - // add this injector to the vector of audio injectors so we know we have to tell it to send its audio during loop - _staticInstance->_audioInjectors.push_back(injector); - - return engine->newQObject(injector, QScriptEngine::ScriptOwnership); -} - QScriptValue vec3toScriptValue(QScriptEngine *engine, const glm::vec3 &vec3) { QScriptValue obj = engine->newObject(); obj.setProperty("x", vec3.x); @@ -126,19 +117,14 @@ void Agent::run() { QScriptValue treeScaleValue = engine.newVariant(QVariant(TREE_SCALE)); engine.globalObject().setProperty("TREE_SCALE", treeScaleValue); - - const long long VISUAL_DATA_SEND_INTERVAL_USECS = (1 / 60.0f) * 1000 * 1000; // let the VoxelPacketSender know how frequently we plan to call it - voxelScripter.getVoxelPacketSender()->setProcessCallIntervalHint(VISUAL_DATA_SEND_INTERVAL_USECS); - - QScriptValue visualSendIntervalValue = engine.newVariant((QVariant(VISUAL_DATA_SEND_INTERVAL_USECS / 1000))); - engine.globalObject().setProperty("VISUAL_DATA_SEND_INTERVAL_MS", visualSendIntervalValue); + voxelScripter.getVoxelPacketSender()->setProcessCallIntervalHint(INJECT_INTERVAL_USECS); // hook in a constructor for audio injectorss - QScriptValue audioInjectorConstructor = engine.newFunction(AudioInjectorConstructor); - QScriptValue audioMetaObject = engine.newQMetaObject(&AudioInjector::staticMetaObject, audioInjectorConstructor); - engine.globalObject().setProperty("AudioInjector", audioMetaObject); + AudioInjector scriptedAudioInjector(BUFFER_LENGTH_SAMPLES_PER_CHANNEL); + QScriptValue audioInjectorValue = engine.newQObject(&scriptedAudioInjector); + engine.globalObject().setProperty("AudioInjector", audioInjectorValue); qDebug() << "Downloaded script:" << scriptContents << "\n"; QScriptValue result = engine.evaluate(scriptContents); @@ -149,19 +135,20 @@ void Agent::run() { qDebug() << "Uncaught exception at line" << line << ":" << result.toString() << "\n"; } - timeval thisSend; + timeval startTime; + gettimeofday(&startTime, NULL); + timeval lastDomainServerCheckIn = {}; - int numMicrosecondsSleep = 0; sockaddr_in senderAddress; unsigned char receivedData[MAX_PACKET_SIZE]; ssize_t receivedBytes; - bool hasVoxelServer = false; + int thisFrame = 0; + + bool firstDomainCheckIn = false; while (!_shouldStop) { - // update the thisSend timeval to the current time - gettimeofday(&thisSend, NULL); // if we're not hearing from the domain-server we should stop running if (NodeList::getInstance()->getNumNoReplyDomainCheckIns() == MAX_SILENT_DOMAIN_SERVER_CHECK_INS) { @@ -174,38 +161,44 @@ void Agent::run() { NodeList::getInstance()->sendDomainServerCheckIn(); } - if (!hasVoxelServer) { - for (NodeList::iterator node = nodeList->begin(); node != nodeList->end(); node++) { - if (node->getType() == NODE_TYPE_VOXEL_SERVER) { - hasVoxelServer = true; + if (firstDomainCheckIn) { + // find the audio-mixer in the NodeList so we can inject audio at it + Node* audioMixer = NodeList::getInstance()->soloNodeOfType(NODE_TYPE_AUDIO_MIXER); + + emit willSendAudioDataCallback(); + + if (audioMixer) { + int usecToSleep = usecTimestamp(&startTime) + (thisFrame++ * INJECT_INTERVAL_USECS) - usecTimestampNow(); + if (usecToSleep > 0) { + usleep(usecToSleep); } + + scriptedAudioInjector.injectAudio(NodeList::getInstance()->getNodeSocket(), audioMixer->getPublicSocket()); } - } - - if (hasVoxelServer) { + // allow the scripter's call back to setup visual data emit willSendVisualDataCallback(); - if (engine.hasUncaughtException()) { - int line = engine.uncaughtExceptionLineNumber(); - qDebug() << "Uncaught exception at line" << line << ":" << engine.uncaughtException().toString() << "\n"; - } - // release the queue of edit voxel messages. voxelScripter.getVoxelPacketSender()->releaseQueuedMessages(); - + // since we're in non-threaded mode, call process so that the packets are sent voxelScripter.getVoxelPacketSender()->process(); + } + if (engine.hasUncaughtException()) { + int line = engine.uncaughtExceptionLineNumber(); + qDebug() << "Uncaught exception at line" << line << ":" << engine.uncaughtException().toString() << "\n"; + } + while (NodeList::getInstance()->getNodeSocket()->receive((sockaddr*) &senderAddress, receivedData, &receivedBytes)) { + if (!firstDomainCheckIn && receivedData[0] == PACKET_TYPE_DOMAIN) { + firstDomainCheckIn = true; + } + NodeList::getInstance()->processNodeData((sockaddr*) &senderAddress, receivedData, receivedBytes); } - - // sleep for the correct amount of time to have data send be consistently timed - if ((numMicrosecondsSleep = VISUAL_DATA_SEND_INTERVAL_USECS - (usecTimestampNow() - usecTimestamp(&thisSend))) > 0) { - usleep(numMicrosecondsSleep); - } } } else { diff --git a/assignment-client/src/Agent.h b/assignment-client/src/Agent.h index 84e8e11269..de6a94fd6b 100644 --- a/assignment-client/src/Agent.h +++ b/assignment-client/src/Agent.h @@ -27,6 +27,7 @@ public: public slots: void stop(); signals: + void willSendAudioDataCallback(); void willSendVisualDataCallback(); private: static void setStaticInstance(Agent* staticInstance); diff --git a/libraries/audio/src/AudioInjector.cpp b/libraries/audio/src/AudioInjector.cpp index cc0a329641..acdee03e8f 100644 --- a/libraries/audio/src/AudioInjector.cpp +++ b/libraries/audio/src/AudioInjector.cpp @@ -21,8 +21,7 @@ AudioInjector::AudioInjector(const char* filename) : _radius(0.0f), _volume(MAX_INJECTOR_VOLUME), _indexOfNextSlot(0), - _isInjectingAudio(false), - _lastFrameIntensity(0.0f) + _isInjectingAudio(false) { loadRandomIdentifier(_streamIdentifier, STREAM_IDENTIFIER_NUM_BYTES); @@ -52,8 +51,7 @@ AudioInjector::AudioInjector(int maxNumSamples) : _radius(0.0f), _volume(MAX_INJECTOR_VOLUME), _indexOfNextSlot(0), - _isInjectingAudio(false), - _lastFrameIntensity(0.0f) + _isInjectingAudio(false) { loadRandomIdentifier(_streamIdentifier, STREAM_IDENTIFIER_NUM_BYTES); @@ -103,6 +101,11 @@ void AudioInjector::injectAudio(UDPSocket* injectorSocket, sockaddr* destination int nextFrame = 0; for (int i = 0; i < _numTotalSamples; i += BUFFER_LENGTH_SAMPLES_PER_CHANNEL) { + int usecToSleep = usecTimestamp(&startTime) + (nextFrame++ * INJECT_INTERVAL_USECS) - usecTimestampNow(); + if (usecToSleep > 0) { + usleep(usecToSleep); + } + int numSamplesToCopy = BUFFER_LENGTH_SAMPLES_PER_CHANNEL; if (_numTotalSamples - i < BUFFER_LENGTH_SAMPLES_PER_CHANNEL) { @@ -115,23 +118,6 @@ void AudioInjector::injectAudio(UDPSocket* injectorSocket, sockaddr* destination memcpy(currentPacketPtr, _audioSampleArray + i, numSamplesToCopy * sizeof(int16_t)); injectorSocket->send(destinationSocket, dataPacket, sizeof(dataPacket)); - - // calculate the intensity for this frame - float lastRMS = 0; - - for (int j = 0; j < BUFFER_LENGTH_SAMPLES_PER_CHANNEL; j++) { - lastRMS += _audioSampleArray[i + j] * _audioSampleArray[i + j]; - } - - lastRMS /= BUFFER_LENGTH_SAMPLES_PER_CHANNEL; - lastRMS = sqrtf(lastRMS); - - _lastFrameIntensity = lastRMS / std::numeric_limits::max(); - - int usecToSleep = usecTimestamp(&startTime) + (++nextFrame * INJECT_INTERVAL_USECS) - usecTimestampNow(); - if (usecToSleep > 0) { - usleep(usecToSleep); - } } _isInjectingAudio = false; @@ -159,8 +145,8 @@ int16_t& AudioInjector::sampleAt(const int index) { return _audioSampleArray[index]; } -void AudioInjector::insertSample(const int index, int16_t sample) { +void AudioInjector::insertSample(const int index, int sample) { assert (index >= 0 && index < _numTotalSamples); - _audioSampleArray[index] = sample; + _audioSampleArray[index] = (int16_t) sample; } diff --git a/libraries/audio/src/AudioInjector.h b/libraries/audio/src/AudioInjector.h index 9054b08a16..626cdc3149 100644 --- a/libraries/audio/src/AudioInjector.h +++ b/libraries/audio/src/AudioInjector.h @@ -42,8 +42,6 @@ public: unsigned char getVolume() const { return _volume; } void setVolume(unsigned char volume) { _volume = volume; } - float getLastFrameIntensity() const { return _lastFrameIntensity; } - const glm::vec3& getPosition() const { return _position; } void setPosition(const glm::vec3& position) { _position = position; } @@ -57,7 +55,7 @@ public: void addSamples(int16_t* sampleBuffer, int numSamples); public slots: int16_t& sampleAt(const int index); - void insertSample(const int index, int16_t sample); + void insertSample(const int index, int sample); private: unsigned char _streamIdentifier[STREAM_IDENTIFIER_NUM_BYTES]; int16_t* _audioSampleArray; @@ -68,7 +66,6 @@ private: unsigned char _volume; int _indexOfNextSlot; bool _isInjectingAudio; - float _lastFrameIntensity; }; #endif /* defined(__hifi__AudioInjector__) */ diff --git a/libraries/shared/src/NodeList.cpp b/libraries/shared/src/NodeList.cpp index a559b58f10..12a24c535f 100644 --- a/libraries/shared/src/NodeList.cpp +++ b/libraries/shared/src/NodeList.cpp @@ -441,10 +441,8 @@ Node* NodeList::addOrUpdateNode(sockaddr* publicSocket, sockaddr* localSocket, c if (publicSocket) { for (node = begin(); node != end(); node++) { - qDebug() << "comparing to node with ID " << node->getNodeID() << "\n"; if (node->matches(publicSocket, localSocket, nodeType)) { // we already have this node, stop checking - qDebug() << "Matched node to existing\n"; break; } } From cdfb23207804c602ea4948e6264e3bb98b8088bd Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Fri, 11 Oct 2013 17:40:02 -0700 Subject: [PATCH 11/12] remove the Agent static instance --- assignment-client/src/Agent.cpp | 4 +--- assignment-client/src/Agent.h | 2 -- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/assignment-client/src/Agent.cpp b/assignment-client/src/Agent.cpp index 81fe4cb5e5..6a5fe92b8d 100644 --- a/assignment-client/src/Agent.cpp +++ b/assignment-client/src/Agent.cpp @@ -16,15 +16,13 @@ #include "Agent.h" #include "voxels/VoxelScriptingInterface.h" -Agent* Agent::_staticInstance = NULL; - Agent::Agent(const unsigned char* dataBuffer, int numBytes) : Assignment(dataBuffer, numBytes), _shouldStop(false) { - setStaticInstance(this); } + void Agent::stop() { _shouldStop = true; } diff --git a/assignment-client/src/Agent.h b/assignment-client/src/Agent.h index de6a94fd6b..ba70fd58ec 100644 --- a/assignment-client/src/Agent.h +++ b/assignment-client/src/Agent.h @@ -30,8 +30,6 @@ signals: void willSendAudioDataCallback(); void willSendVisualDataCallback(); private: - static void setStaticInstance(Agent* staticInstance); - static Agent* _staticInstance; static QScriptValue AudioInjectorConstructor(QScriptContext *context, QScriptEngine *engine); bool volatile _shouldStop; From 2bbaf7d31e9405415f60e6e2b95ac615712d1fa2 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Fri, 11 Oct 2013 17:40:28 -0700 Subject: [PATCH 12/12] remove static instance set from Agent.cpp --- assignment-client/src/Agent.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/assignment-client/src/Agent.cpp b/assignment-client/src/Agent.cpp index 6a5fe92b8d..d9cf479b17 100644 --- a/assignment-client/src/Agent.cpp +++ b/assignment-client/src/Agent.cpp @@ -39,10 +39,6 @@ static size_t writeScriptDataToString(void *contents, size_t size, size_t nmemb, return realSize; } -void Agent::setStaticInstance(Agent* staticInstance) { - _staticInstance = staticInstance; -} - QScriptValue vec3toScriptValue(QScriptEngine *engine, const glm::vec3 &vec3) { QScriptValue obj = engine->newObject(); obj.setProperty("x", vec3.x);