From f3ab3b6c8388a9d683213b3373caa285ebe6bded Mon Sep 17 00:00:00 2001 From: tosh Date: Tue, 2 Jul 2013 12:41:34 +0200 Subject: [PATCH 1/4] prevents voxel data from being sent or received (read: requested) when voxel rendering is disabled also adds a menu option under "Tools" to enable/disable the Oscilloscope --- interface/src/Application.cpp | 26 +++++++++++++++++--------- interface/src/Application.h | 4 +++- interface/src/BandwidthMeter.cpp | 7 +++++++ 3 files changed, 27 insertions(+), 10 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index fb63fe2daf..4c57c67c3c 100755 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -483,8 +483,7 @@ void Application::resizeGL(int width, int height) { void Application::broadcastToAgents(unsigned char* data, size_t bytes, const char type) { - int n = AgentList::getInstance()->broadcastToAgents(data, bytes, &type, 1); - + Application* self = getInstance(); BandwidthMeter::ChannelIndex channel; switch (type) { case AGENT_TYPE_AVATAR: @@ -493,11 +492,15 @@ void Application::broadcastToAgents(unsigned char* data, size_t bytes, const cha break; case AGENT_TYPE_VOXEL_SERVER: channel = BandwidthMeter::VOXELS; - break; + if (self->_renderVoxels->isChecked()) { + break; + } default: return; } - getInstance()->_bandwidthMeter.outputStream(channel).updateValue(n * bytes); + int n = AgentList::getInstance()->broadcastToAgents(data, bytes, & type, 1); +broadcastDone: + self->_bandwidthMeter.outputStream(channel).updateValue(n * bytes); } void Application::sendVoxelServerAddScene() { @@ -875,15 +878,17 @@ void Application::wheelEvent(QWheelEvent* event) { } } -void sendPingPackets() { +void Application::sendPingPackets() { char agentTypesOfInterest[] = {AGENT_TYPE_VOXEL_SERVER, AGENT_TYPE_AUDIO_MIXER, AGENT_TYPE_AVATAR_MIXER}; long long currentTime = usecTimestampNow(); - char pingPacket[1 + sizeof(currentTime)]; + unsigned char pingPacket[1 + sizeof(currentTime)]; pingPacket[0] = PACKET_HEADER_PING; memcpy(&pingPacket[1], ¤tTime, sizeof(currentTime)); - AgentList::getInstance()->broadcastToAgents((unsigned char*)pingPacket, 1 + sizeof(currentTime), agentTypesOfInterest, 3); + for (int i = 0; i < sizeof(agentTypesOfInterest) / sizeof(char); ++i) { + getInstance()->broadcastToAgents(pingPacket, 1 + sizeof(currentTime), agentTypesOfInterest[i]); + } } @@ -1466,6 +1471,8 @@ void Application::initMenu() { (_logOn = toolsMenu->addAction("Log"))->setCheckable(true); _logOn->setChecked(false); _logOn->setShortcut(Qt::CTRL | Qt::Key_L); + (_oscilloscopeOn = toolsMenu->addAction("Audio Oscilloscope"))->setCheckable(true); + _oscilloscopeOn->setChecked(true); (_bandwidthDisplayOn = toolsMenu->addAction("Bandwidth Display"))->setCheckable(true); _bandwidthDisplayOn->setChecked(true); toolsMenu->addAction("Bandwidth Details", this, SLOT(bandwidthDetails())); @@ -2294,8 +2301,9 @@ void Application::displayOverlay() { #ifndef _WIN32 _audio.render(_glWidget->width(), _glWidget->height()); - _audioScope.render(20, _glWidget->height() - 200); - //_audio.renderEchoCompare(); // PER: Will turn back on to further test echo + if (_oscilloscopeOn->isChecked()) { + _audioScope.render(20, _glWidget->height() - 200); + } #endif //noiseTest(_glWidget->width(), _glWidget->height()); diff --git a/interface/src/Application.h b/interface/src/Application.h index e2b0cd21f4..4fb755be79 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -155,9 +155,10 @@ private: static void broadcastToAgents(unsigned char* data, size_t bytes, const char type); static void sendVoxelServerAddScene(); static bool sendVoxelsOperation(VoxelNode* node, void* extraData); + static void sendVoxelEditMessage(PACKET_HEADER header, VoxelDetail& detail); static void sendAvatarVoxelURLMessage(const QUrl& url); static void processAvatarVoxelURLMessage(unsigned char *packetData, size_t dataBytes); - static void sendVoxelEditMessage(PACKET_HEADER header, VoxelDetail& detail); + static void sendPingPackets(); void initMenu(); void updateFrustumRenderModeAction(); @@ -226,6 +227,7 @@ private: QAction* _manualFirstPerson; // Whether to force first-person mode QAction* _manualThirdPerson; // Whether to force third-person mode QAction* _logOn; // Whether to show on-screen log + QAction* _oscilloscopeOn; // Whether to show the oscilloscope QAction* _bandwidthDisplayOn; // Whether to show on-screen bandwidth bars QActionGroup* _voxelModeActions; // The group of voxel edit mode actions QAction* _addVoxelMode; // Whether add voxel mode is enabled diff --git a/interface/src/BandwidthMeter.cpp b/interface/src/BandwidthMeter.cpp index ba89864807..84d92a3020 100644 --- a/interface/src/BandwidthMeter.cpp +++ b/interface/src/BandwidthMeter.cpp @@ -225,6 +225,13 @@ void BandwidthMeter::render(int screenWidth, int screenHeight) { textYlowerLine, fmtBuf); glPopMatrix(); + + // After rendering, indicate that no data has been sent/received since the last feed. + // This way, the meters fall when not continuously fed. + for (int i = 0; i < N_CHANNELS; ++i) { + inputStream(ChannelIndex(i)).updateValue(0); + outputStream(ChannelIndex(i)).updateValue(0); + } } From a542ebc85143aa718a10b2dfd1838d02d93bf518 Mon Sep 17 00:00:00 2001 From: tosh Date: Wed, 3 Jul 2013 14:01:09 +0200 Subject: [PATCH 2/4] bandwidth meter - avoid division by zero --- interface/src/BandwidthMeter.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/interface/src/BandwidthMeter.cpp b/interface/src/BandwidthMeter.cpp index 84d92a3020..5e0d63d6c5 100644 --- a/interface/src/BandwidthMeter.cpp +++ b/interface/src/BandwidthMeter.cpp @@ -68,6 +68,12 @@ void BandwidthMeter::Stream::updateValue(double amount) { timeval now; gettimeofday(& now, NULL); double dt = diffclock(& _prevTime, & now); + + // Ignore this value when timer imprecision yields dt = 0 + if (dt == 0.0) { + return; + } + memcpy(& _prevTime, & now, sizeof(timeval)); // Compute approximate average From 2da132be65dae8192ca0dafad5179096d6a34187 Mon Sep 17 00:00:00 2001 From: tosh Date: Thu, 4 Jul 2013 21:21:11 +0200 Subject: [PATCH 3/4] upstream merge --- interface/src/Application.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index c8699cde24..ffa13c6364 100755 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -500,7 +500,7 @@ void Application::broadcastToNodes(unsigned char* data, size_t bytes, const char default: return; } - int n = AgentList::getInstance()->broadcastToAgents(data, bytes, & type, 1); + int n = NodeList::getInstance()->broadcastToNodes(data, bytes, & type, 1); self->_bandwidthMeter.outputStream(channel).updateValue(n * bytes); } @@ -887,8 +887,8 @@ void Application::sendPingPackets() { pingPacket[0] = PACKET_HEADER_PING; memcpy(&pingPacket[1], ¤tTime, sizeof(currentTime)); - for (int i = 0; i < sizeof(agentTypesOfInterest) / sizeof(char); ++i) { - getInstance()->broadcastToAgents(pingPacket, 1 + sizeof(currentTime), agentTypesOfInterest[i]); + for (int i = 0; i < sizeof(nodeTypesOfInterest) / sizeof(char); ++i) { + getInstance()->broadcastToNodes(pingPacket, 1 + sizeof(currentTime), nodeTypesOfInterest[i]); } } From c2e2ff0ffecad4d9e35b308dcb051539d9a2865d Mon Sep 17 00:00:00 2001 From: tosh Date: Fri, 5 Jul 2013 14:16:50 +0200 Subject: [PATCH 4/4] changes broadcast function in Application to use a different name but the same signature as in NodeList --- interface/src/Application.cpp | 66 ++++++++++++++++++++--------------- interface/src/Application.h | 4 ++- 2 files changed, 40 insertions(+), 30 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index ffa13c6364..d9973bee02 100755 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -483,32 +483,41 @@ void Application::resizeGL(int width, int height) { glLoadIdentity(); } -void Application::broadcastToNodes(unsigned char* data, size_t bytes, const char type) { - +void Application::controlledBroadcastToNodes(unsigned char* broadcastData, size_t dataBytes, + const char* nodeTypes, int numNodeTypes) { Application* self = getInstance(); - BandwidthMeter::ChannelIndex channel; - switch (type) { - case NODE_TYPE_AGENT: - case NODE_TYPE_AVATAR_MIXER: - channel = BandwidthMeter::AVATARS; - break; - case NODE_TYPE_VOXEL_SERVER: - channel = BandwidthMeter::VOXELS; - if (self->_renderVoxels->isChecked()) { - break; + for (int i = 0; i < numNodeTypes; ++i) { + + // Intercept data to voxel server when voxels are disabled + if (nodeTypes[i] == NODE_TYPE_VOXEL_SERVER && ! self->_renderVoxels->isChecked()) { + continue; } - default: - return; + + // Perform the broadcast for one type + int nReceivingNodes = NodeList::getInstance()->broadcastToNodes(broadcastData, dataBytes, & nodeTypes[i], 1); + + // Feed number of bytes to corresponding channel of the bandwidth meter, if any (done otherwise) + BandwidthMeter::ChannelIndex channel; + switch (nodeTypes[i]) { + case NODE_TYPE_AGENT: + case NODE_TYPE_AVATAR_MIXER: + channel = BandwidthMeter::AVATARS; + break; + case NODE_TYPE_VOXEL_SERVER: + channel = BandwidthMeter::VOXELS; + break; + default: + continue; + } + self->_bandwidthMeter.outputStream(channel).updateValue(nReceivingNodes * dataBytes); } - int n = NodeList::getInstance()->broadcastToNodes(data, bytes, & type, 1); - self->_bandwidthMeter.outputStream(channel).updateValue(n * bytes); } void Application::sendVoxelServerAddScene() { char message[100]; sprintf(message,"%c%s",'Z',"add scene"); int messageSize = strlen(message) + 1; - broadcastToNodes((unsigned char*)message, messageSize, NODE_TYPE_VOXEL_SERVER); + controlledBroadcastToNodes((unsigned char*)message, messageSize, & NODE_TYPE_VOXEL_SERVER, 1); } void Application::keyPressEvent(QKeyEvent* event) { @@ -887,10 +896,8 @@ void Application::sendPingPackets() { pingPacket[0] = PACKET_HEADER_PING; memcpy(&pingPacket[1], ¤tTime, sizeof(currentTime)); - for (int i = 0; i < sizeof(nodeTypesOfInterest) / sizeof(char); ++i) { - getInstance()->broadcastToNodes(pingPacket, 1 + sizeof(currentTime), nodeTypesOfInterest[i]); - } - + getInstance()->controlledBroadcastToNodes(pingPacket, 1 + sizeof(currentTime), + nodeTypesOfInterest, sizeof(nodeTypesOfInterest)); } // Every second, check the frame rates and other stuff @@ -991,7 +998,7 @@ void Application::sendAvatarVoxelURLMessage(const QUrl& url) { message.append((const char*)&ownerID, sizeof(ownerID)); message.append(url.toEncoded()); - broadcastToNodes((unsigned char*)message.data(), message.size(), NODE_TYPE_AVATAR_MIXER); + controlledBroadcastToNodes((unsigned char*)message.data(), message.size(), & NODE_TYPE_AVATAR_MIXER, 1); } void Application::processAvatarVoxelURLMessage(unsigned char *packetData, size_t dataBytes) { @@ -1224,7 +1231,7 @@ void Application::sendVoxelEditMessage(PACKET_HEADER header, VoxelDetail& detail int sizeOut; if (createVoxelEditMessage(header, 0, 1, &detail, bufferOut, sizeOut)){ - Application::broadcastToNodes(bufferOut, sizeOut, NODE_TYPE_VOXEL_SERVER); + Application::controlledBroadcastToNodes(bufferOut, sizeOut, & NODE_TYPE_VOXEL_SERVER, 1); delete[] bufferOut; } } @@ -1305,7 +1312,7 @@ bool Application::sendVoxelsOperation(VoxelNode* node, void* extraData) { // if we have room don't have room in the buffer, then send the previously generated message first if (args->bufferInUse + codeAndColorLength > MAXIMUM_EDIT_VOXEL_MESSAGE_SIZE) { - broadcastToNodes(args->messageBuffer, args->bufferInUse, NODE_TYPE_VOXEL_SERVER); + controlledBroadcastToNodes(args->messageBuffer, args->bufferInUse, & NODE_TYPE_VOXEL_SERVER, 1); args->bufferInUse = sizeof(PACKET_HEADER_SET_VOXEL_DESTRUCTIVE) + sizeof(unsigned short int); // reset } @@ -1386,7 +1393,7 @@ void Application::importVoxels() { // If we have voxels left in the packet, then send the packet if (args.bufferInUse > (sizeof(PACKET_HEADER_SET_VOXEL_DESTRUCTIVE) + sizeof(unsigned short int))) { - broadcastToNodes(args.messageBuffer, args.bufferInUse, NODE_TYPE_VOXEL_SERVER); + controlledBroadcastToNodes(args.messageBuffer, args.bufferInUse, & NODE_TYPE_VOXEL_SERVER, 1); } if (calculatedOctCode) { @@ -1438,7 +1445,7 @@ void Application::pasteVoxels() { // If we have voxels left in the packet, then send the packet if (args.bufferInUse > (sizeof(PACKET_HEADER_SET_VOXEL_DESTRUCTIVE) + sizeof(unsigned short int))) { - broadcastToNodes(args.messageBuffer, args.bufferInUse, NODE_TYPE_VOXEL_SERVER); + controlledBroadcastToNodes(args.messageBuffer, args.bufferInUse, & NODE_TYPE_VOXEL_SERVER, 1); } if (calculatedOctCode) { @@ -1986,9 +1993,10 @@ void Application::updateAvatar(float deltaTime) { endOfBroadcastStringWrite += packNodeId(endOfBroadcastStringWrite, nodeList->getOwnerID()); endOfBroadcastStringWrite += _myAvatar.getBroadcastData(endOfBroadcastStringWrite); - - broadcastToNodes(broadcastString, endOfBroadcastStringWrite - broadcastString, NODE_TYPE_VOXEL_SERVER); - broadcastToNodes(broadcastString, endOfBroadcastStringWrite - broadcastString, NODE_TYPE_AVATAR_MIXER); + + const char nodeTypesOfInterest[] = { NODE_TYPE_VOXEL_SERVER, NODE_TYPE_AVATAR_MIXER }; + controlledBroadcastToNodes(broadcastString, endOfBroadcastStringWrite - broadcastString, + nodeTypesOfInterest, sizeof(nodeTypesOfInterest)); // once in a while, send my voxel url const float AVATAR_VOXEL_URL_SEND_INTERVAL = 1.0f; // seconds diff --git a/interface/src/Application.h b/interface/src/Application.h index 47ee159f74..2b4bd27a3d 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -152,7 +152,9 @@ private slots: void runTests(); private: - static void broadcastToNodes(unsigned char* data, size_t bytes, const char type); + static void controlledBroadcastToNodes(unsigned char* broadcastData, size_t dataBytes, + const char* nodeTypes, int numNodeTypes); + static void sendVoxelServerAddScene(); static bool sendVoxelsOperation(VoxelNode* node, void* extraData); static void sendVoxelEditMessage(PACKET_HEADER header, VoxelDetail& detail);