From 5b0b7229ba546ff6f34c03ecf8824ce73b61c66f Mon Sep 17 00:00:00 2001 From: bwent Date: Wed, 15 Jul 2015 11:10:39 -0700 Subject: [PATCH 01/13] Added a dialog box to display audio network statistics --- interface/src/Application.cpp | 10 +- interface/src/Application.h | 1 + interface/src/Menu.cpp | 28 +-- interface/src/Menu.h | 2 +- interface/src/ui/ApplicationOverlay.cpp | 5 +- interface/src/ui/AudioStatsDialog.cpp | 276 ++++++++++++++++++++++++ interface/src/ui/AudioStatsDialog.h | 107 +++++++++ interface/src/ui/DialogsManager.cpp | 14 ++ interface/src/ui/DialogsManager.h | 4 + 9 files changed, 429 insertions(+), 18 deletions(-) create mode 100644 interface/src/ui/AudioStatsDialog.cpp create mode 100644 interface/src/ui/AudioStatsDialog.h diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 06b086ccb3..745c8c1212 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -107,7 +107,7 @@ #include "avatar/AvatarManager.h" #include "audio/AudioToolBox.h" -#include "audio/AudioIOStatsRenderer.h" +//#include "audio/AudioIOStatsRenderer.h" #include "audio/AudioScope.h" #include "devices/CameraToolBox.h" @@ -274,7 +274,7 @@ bool setupEssentials(int& argc, char** argv) { auto faceshift = DependencyManager::set(); auto audio = DependencyManager::set(); auto audioScope = DependencyManager::set(); - auto audioIOStatsRenderer = DependencyManager::set(); +// auto audioIOStatsRenderer = DependencyManager::set(); auto deferredLightingEffect = DependencyManager::set(); auto ambientOcclusionEffect = DependencyManager::set(); auto textureCache = DependencyManager::set(); @@ -2443,6 +2443,12 @@ void Application::updateDialogs(float deltaTime) { PerformanceWarning warn(showWarnings, "Application::updateDialogs()"); auto dialogsManager = DependencyManager::get(); + // Update audio stats dialog, if any + AudioStatsDialog* audioStatsDialog = dialogsManager->getAudioStatsDialog(); + if(audioStatsDialog) { + audioStatsDialog->update(); + } + // Update bandwidth dialog, if any BandwidthDialog* bandwidthDialog = dialogsManager->getBandwidthDialog(); if (bandwidthDialog) { diff --git a/interface/src/Application.h b/interface/src/Application.h index 3239b84c6c..4e0edbb13d 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -57,6 +57,7 @@ #include "devices/SixenseManager.h" #include "scripting/ControllerScriptingInterface.h" #include "scripting/WebWindowClass.h" +#include "ui/AudioStatsDialog.h" #include "ui/BandwidthDialog.h" #include "ui/HMDToolsDialog.h" #include "ui/ModelsBrowser.h" diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index 6671320f0c..ae7eb11e98 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -24,7 +24,7 @@ #include "Application.h" #include "AccountManager.h" -#include "audio/AudioIOStatsRenderer.h" +//#include "audio/AudioIOStatsRenderer.h" #include "audio/AudioScope.h" #include "avatar/AvatarManager.h" #include "devices/DdeFaceTracker.h" @@ -314,6 +314,8 @@ Menu::Menu() { addActionToQMenuAndActionHash(viewMenu, MenuOption::Log, Qt::CTRL | Qt::SHIFT | Qt::Key_L, qApp, SLOT(toggleLogDialog())); + addActionToQMenuAndActionHash(viewMenu, MenuOption::AudioNetworkStats, 0, + dialogsManager.data(), SLOT(audioStatsDetails())); addActionToQMenuAndActionHash(viewMenu, MenuOption::BandwidthDetails, 0, dialogsManager.data(), SLOT(bandwidthDetails())); addActionToQMenuAndActionHash(viewMenu, MenuOption::OctreeStats, 0, @@ -579,19 +581,19 @@ Menu::Menu() { audioScopeFramesGroup->addAction(fiftyFrames); } - auto statsRenderer = DependencyManager::get(); - addCheckableActionToQMenuAndActionHash(audioDebugMenu, MenuOption::AudioStats, - Qt::CTRL | Qt::SHIFT | Qt::Key_A, - false, - statsRenderer.data(), - SLOT(toggle())); - - addCheckableActionToQMenuAndActionHash(audioDebugMenu, MenuOption::AudioStatsShowInjectedStreams, - 0, - false, - statsRenderer.data(), - SLOT(toggleShowInjectedStreams())); +// auto statsRenderer = DependencyManager::get(); +// addCheckableActionToQMenuAndActionHash(audioDebugMenu, MenuOption::AudioStats, +// Qt::CTRL | Qt::SHIFT | Qt::Key_A, +// false, +// statsRenderer.data(), +// SLOT(toggle())); +// addCheckableActionToQMenuAndActionHash(audioDebugMenu, MenuOption::AudioStatsShowInjectedStreams, +// 0, +// false, +// statsRenderer.data(), +// SLOT(toggleShowInjectedStreams())); +// MenuWrapper* physicsOptionsMenu = developerMenu->addMenu("Physics"); addCheckableActionToQMenuAndActionHash(physicsOptionsMenu, MenuOption::PhysicsShowOwned); diff --git a/interface/src/Menu.h b/interface/src/Menu.h index be0ac12d0d..c914cb2d12 100644 --- a/interface/src/Menu.h +++ b/interface/src/Menu.h @@ -145,7 +145,7 @@ namespace MenuOption { const QString AudioScopeFrames = "Display Frames"; const QString AudioScopePause = "Pause Scope"; const QString AudioScopeTwentyFrames = "Twenty"; - const QString AudioStats = "Audio Stats"; + const QString AudioNetworkStats = "Audio Network Stats"; const QString AudioStatsShowInjectedStreams = "Audio Stats Show Injected Streams"; const QString AutoMuteAudio = "Auto Mute Microphone"; const QString AvatarReceiveStats = "Show Receive Stats"; diff --git a/interface/src/ui/ApplicationOverlay.cpp b/interface/src/ui/ApplicationOverlay.cpp index 2b58ad93fc..bdfa146197 100644 --- a/interface/src/ui/ApplicationOverlay.cpp +++ b/interface/src/ui/ApplicationOverlay.cpp @@ -23,7 +23,7 @@ #include #include "AudioClient.h" -#include "audio/AudioIOStatsRenderer.h" +//#include "audio/AudioIOStatsRenderer.h" #include "audio/AudioScope.h" #include "audio/AudioToolBox.h" #include "Application.h" @@ -935,7 +935,7 @@ void ApplicationOverlay::renderAudioMeter() { auto canvasSize = qApp->getCanvasSize(); DependencyManager::get()->render(canvasSize.x, canvasSize.y); - DependencyManager::get()->render(WHITE_TEXT, canvasSize.x, canvasSize.y); + //DependencyManager::get()->render(WHITE_TEXT, canvasSize.x, canvasSize.y); audioMeterY += AUDIO_METER_HEIGHT; @@ -994,6 +994,7 @@ void ApplicationOverlay::renderAudioMeter() { void ApplicationOverlay::renderStatsAndLogs() { Application* application = Application::getInstance(); + QSharedPointer bandwidthRecorder = DependencyManager::get(); const OctreePacketProcessor& octreePacketProcessor = application->getOctreePacketProcessor(); diff --git a/interface/src/ui/AudioStatsDialog.cpp b/interface/src/ui/AudioStatsDialog.cpp new file mode 100644 index 0000000000..9ee8716321 --- /dev/null +++ b/interface/src/ui/AudioStatsDialog.cpp @@ -0,0 +1,276 @@ +// +// AudioStatsDialog.cpp +// hifi +// +// Created by Bridget Went on 7/9/15. +// +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#include + +#include "InterfaceConfig.h" + +#include +#include +#include +#include +#include +#include +#include + + +#include "AudioStatsDialog.h" + +const unsigned COLOR0 = 0x33cc99ff; +const unsigned COLOR1 = 0xffef40c0; +const unsigned COLOR2 = 0xd0d0d0a0; +const unsigned COLOR3 = 0x01DD7880; + + +AudioStatsDisplay::AudioStatsDisplay(QFormLayout* form, + QString text, unsigned colorRGBA) : +_text(text), +_colorRGBA(colorRGBA) +{ + _label = new QLabel(); + _label->setAlignment(Qt::AlignCenter); + + QPalette palette = _label->palette(); + unsigned rgb = colorRGBA >> 8; + rgb = ((rgb & 0xfefefeu) >> 1) + ((rgb & 0xf8f8f8) >> 3); + palette.setColor(QPalette::WindowText, QColor::fromRgb(rgb)); + _label->setPalette(palette); + + form->addRow(_label); +} + +void AudioStatsDisplay::paint() { + _label->setText(_strBuf); +} + +void AudioStatsDisplay::updatedDisplay(QString str) { + _strBuf = str; +} + + +AudioStatsDialog::AudioStatsDialog(QWidget* parent) : + QDialog(parent, Qt::Window | Qt::WindowCloseButtonHint | Qt::WindowStaysOnTopHint) { + + _shouldShowInjectedStreams = false; + + this->setWindowTitle("Audio Network Statistics"); + + // Get statistics from the Audio Client + _stats = &DependencyManager::get()->getStats(); + + // Create layouter + _form = new QFormLayout(); + this->QDialog::setLayout(_form); + + // Initialize vectors for stat channels + _audioMixerStats = new QVector(); + _upstreamClientStats = new QVector(); + _upstreamMixerStats = new QVector(); + _downstreamStats = new QVector(); + _upstreamInjectedStats = new QVector(); + + // Load and initilize + this->renderStats(); + + this->initializeChannel(_form, 0, _audioMixerStats, COLOR0); + this->initializeChannel(_form, 1, _upstreamClientStats, COLOR1); + this->initializeChannel(_form, 2, _upstreamMixerStats, COLOR2); + this->initializeChannel(_form, 3, _downstreamStats, COLOR3); + this->initializeChannel(_form, 4, _upstreamInjectedStats, COLOR0); + +} + +void AudioStatsDialog::initializeChannel(QFormLayout* form, const unsigned int index, QVector *stats, const unsigned color) { + + _audioDisplayChannels[index] = new QVector(); + + for (int i = 0; i < stats->size(); i++) + // Create new display label + _audioDisplayChannels[index]->push_back(new AudioStatsDisplay(form, stats->at(i), color)); + +} + +void AudioStatsDialog::updateStats(const unsigned int index, QVector* stats) { + // Update all stat displays at specified channel + for (int i = 0; i < stats->size(); i++) + _audioDisplayChannels[index]->at(i)->updatedDisplay(stats->at(i)); +} + + +void AudioStatsDialog::renderStats() { + + // Clear current stats from all vectors + this->clearAllChannels(); + + double audioInputBufferLatency = 0.0, + inputRingBufferLatency = 0.0, + networkRoundtripLatency = 0.0, + mixerRingBufferLatency = 0.0, + outputRingBufferLatency = 0.0, + audioOutputBufferLatency = 0.0; + + AudioStreamStats downstreamAudioStreamStats = _stats->getMixerDownstreamStats(); + SharedNodePointer audioMixerNodePointer = DependencyManager::get()->soloNodeOfType(NodeType::AudioMixer); + + if (!audioMixerNodePointer.isNull()) { + audioInputBufferLatency = (double)_stats->getAudioInputMsecsReadStats().getWindowAverage(); + inputRingBufferLatency = (double)_stats->getInputRungBufferMsecsAvailableStats().getWindowAverage(); + networkRoundtripLatency = (double) audioMixerNodePointer->getPingMs(); + mixerRingBufferLatency = (double)_stats->getMixerAvatarStreamStats()._framesAvailableAverage * AudioConstants::NETWORK_FRAME_MSECS; + outputRingBufferLatency = (double)downstreamAudioStreamStats._framesAvailableAverage * AudioConstants::NETWORK_FRAME_MSECS; + audioOutputBufferLatency = (double)_stats->getAudioOutputMsecsUnplayedStats().getWindowAverage(); + } + + double totalLatency = audioInputBufferLatency + inputRingBufferLatency + networkRoundtripLatency + mixerRingBufferLatency + + outputRingBufferLatency + audioOutputBufferLatency; + + _audioMixerStats->push_back(QString("Audio input buffer: %1ms").arg( + QString::number(audioInputBufferLatency, 'f', 2)) + QString(" - avg msecs of samples read to the audio input buffer in last 10s")); + + _audioMixerStats->push_back(QString("Input ring buffer: %1ms").arg( + QString::number(inputRingBufferLatency, 'f', 2)) + QString(" - avg msecs of samples read to the input ring buffer in last 10s")); + _audioMixerStats->push_back(QString("Network to mixer: %1ms").arg( + QString::number((networkRoundtripLatency / 2.0), 'f', 2)) + QString(" - half of last ping value calculated by the node list")); + _audioMixerStats->push_back(QString("Network to client: %1ms").arg( + QString::number((mixerRingBufferLatency / 2.0),'f', 2)) + QString(" - half of last ping value calculated by the node list")); + _audioMixerStats->push_back(QString("Output ring buffer: %1ms").arg( + QString::number(outputRingBufferLatency,'f', 2)) + QString(" - avg msecs of samples in output ring buffer in last 10s")); + _audioMixerStats->push_back(QString("Audio output buffer: %1ms").arg( + QString::number(mixerRingBufferLatency,'f', 2)) + QString(" - avg msecs of samples in audio output buffer in last 10s")); + _audioMixerStats->push_back(QString("TOTAL: %1ms").arg( + QString::number(totalLatency, 'f', 2)) +QString(" - avg msecs of samples in audio output buffer in last 10s")); + + + const MovingMinMaxAvg& packetSentTimeGaps = _stats->getPacketSentTimeGaps(); + + _upstreamClientStats->push_back( + QString("\nUpstream Mic Audio Packets Sent Gaps (by client):")); + + _upstreamClientStats->push_back( + QString("Inter-packet timegaps (overall) | min: %1, max: %2, avg: %3").arg(formatUsecTime(packetSentTimeGaps.getMin()).toLatin1().data()).arg(formatUsecTime( packetSentTimeGaps.getMax()).toLatin1().data()).arg(formatUsecTime( packetSentTimeGaps.getAverage()).toLatin1().data())); + _upstreamClientStats->push_back( + QString("Inter-packet timegaps (last 30s) | min: %1, max: %2, avg: %3").arg(formatUsecTime(packetSentTimeGaps.getWindowMin()).toLatin1().data()).arg(formatUsecTime(packetSentTimeGaps.getWindowMax()).toLatin1().data()).arg(formatUsecTime(packetSentTimeGaps.getWindowAverage()).toLatin1().data())); + + _upstreamMixerStats->push_back(QString("\nUpstream mic audio stats (received and reported by audio-mixer):")); + + renderAudioStreamStats(&_stats->getMixerAvatarStreamStats(), _upstreamMixerStats, true); + + _downstreamStats->push_back(QString("\nDownstream mixed audio stats:")); + + AudioStreamStats downstreamStats = _stats->getMixerDownstreamStats(); + + renderAudioStreamStats(&downstreamStats, _downstreamStats, true); + + + if (_shouldShowInjectedStreams) { + + foreach(const AudioStreamStats& injectedStreamAudioStats, _stats->getMixerInjectedStreamStatsMap()) { + + _upstreamInjectedStats->push_back(QString("\nUpstream injected audio stats: stream ID: %1").arg( injectedStreamAudioStats._streamIdentifier.toString().toLatin1().data())); + + renderAudioStreamStats(&injectedStreamAudioStats, _upstreamInjectedStats, true); + } + + } + + connect(averageUpdateTimer, SIGNAL(timeout()), this, SLOT(updateTimerTimeout())); + averageUpdateTimer->start(1000); +} + + +void AudioStatsDialog::renderAudioStreamStats(const AudioStreamStats* streamStats, QVector* audioStreamStats, bool isDownstreamStats) { + + + audioStreamStats->push_back( + QString("Packet loss | overall: %1% (%2 lost), last_30s: %3% (%4 lost)").arg(QString::number((int)(streamStats->_packetStreamStats.getLostRate() * 100.0f))).arg(QString::number((int)(streamStats->_packetStreamStats._lost))).arg(QString::number((int)(streamStats->_packetStreamWindowStats.getLostRate() * 100.0f))).arg(QString::number((int)(streamStats->_packetStreamWindowStats._lost))) + ); + + if (isDownstreamStats) { + audioStreamStats->push_back( + QString("Ringbuffer frames | desired: %1, avg_available(10s): %2 + %3, available: %4+%5").arg(QString::number(streamStats->_desiredJitterBufferFrames)).arg(QString::number(streamStats->_framesAvailableAverage)).arg(QString::number((int)((float)_stats->getAudioInputMsecsReadStats().getWindowAverage() / AudioConstants::NETWORK_FRAME_MSECS))).arg(QString::number(streamStats->_framesAvailable)).arg(QString::number((int)(_stats->getAudioOutputMsecsUnplayedStats().getCurrentIntervalLastSample() / AudioConstants::NETWORK_FRAME_MSECS)))); + } else { + audioStreamStats->push_back( + QString("Ringbuffer frames | desired: %1, avg_available(10s): %2, available: %3").arg(QString::number(streamStats->_desiredJitterBufferFrames)).arg(QString::number(streamStats->_framesAvailableAverage)).arg(QString::number(streamStats->_framesAvailable))); + } + + audioStreamStats->push_back( + QString("Ringbuffer stats | starves: %1, prev_starve_lasted: %2, frames_dropped: %3, overflows: %4").arg(QString::number(streamStats->_starveCount)).arg(QString::number(streamStats->_consecutiveNotMixedCount)).arg(QString::number(streamStats->_framesDropped)).arg(QString::number(streamStats->_overflowCount))); + audioStreamStats->push_back( + QString("Inter-packet timegaps (overall) | min: %1, max: %2, avg: %3").arg(formatUsecTime(streamStats->_timeGapMin).toLatin1().data()).arg(formatUsecTime(streamStats->_timeGapMax).toLatin1().data()).arg(formatUsecTime(streamStats->_timeGapAverage).toLatin1().data())); + audioStreamStats->push_back( + QString("Inter-packet timegaps (last 30s) | min: %1, max: %2, avg: %3").arg(formatUsecTime(streamStats->_timeGapWindowMin).toLatin1().data()).arg(formatUsecTime(streamStats->_timeGapWindowMax).toLatin1().data()).arg(QString::number(streamStats->_timeGapWindowAverage).toLatin1().data())); + +} + +void AudioStatsDialog::clearAllChannels() { + _audioMixerStats->clear(); + _upstreamClientStats->clear(); + _upstreamMixerStats->clear(); + _downstreamStats->clear(); + _upstreamInjectedStats->clear(); +} + + +void AudioStatsDialog::updateTimerTimeout() { + + // Update all audio stats + this->renderStats(); + + this->updateStats(0, _audioMixerStats); + this->updateStats(1, _upstreamClientStats); + this->updateStats(2, _upstreamMixerStats); + this->updateStats(3, _downstreamStats); + this->updateStats(4, _upstreamInjectedStats); + +} + + +void AudioStatsDialog::paintEvent(QPaintEvent* event) { + + // Repaint each statistic in each section + for (int i = 0; i < DISPLAY_CHANNELS; i++) { + for(int j = 0; j < _audioDisplayChannels[i]->size(); j++) { + _audioDisplayChannels[i]->at(j)->paint(); + } + } + this->QDialog::paintEvent(event); + this->setFixedSize(this->width(), this->height()); +} + +void AudioStatsDialog::reject() { + // Just regularly close upon ESC + this->QDialog::close(); +} + +void AudioStatsDialog::closeEvent(QCloseEvent* event) { + this->QDialog::closeEvent(event); + emit closed(); +} + +AudioStatsDialog::~AudioStatsDialog() { + this->clearAllChannels(); + + delete _audioMixerStats; + delete _upstreamClientStats; + delete _upstreamMixerStats; + delete _downstreamStats; + delete _upstreamInjectedStats; + + for (int i = 0; i < DISPLAY_CHANNELS; i++) { + _audioDisplayChannels[i]->clear(); + for(int j = 0; j < _audioDisplayChannels[i]->size(); j++) { + delete _audioDisplayChannels[i]->at(j); + } + } + +} + + diff --git a/interface/src/ui/AudioStatsDialog.h b/interface/src/ui/AudioStatsDialog.h new file mode 100644 index 0000000000..ce1e8027e3 --- /dev/null +++ b/interface/src/ui/AudioStatsDialog.h @@ -0,0 +1,107 @@ +// +// AudioStatsDialog.h +// hifi +// +// Created by Bridget Went on 7/9/15. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + + +#ifndef __hifi__AudioStatsDialog__ +#define __hifi__AudioStatsDialog__ + +#include + +#include +#include +#include +#include +#include +#include + +#include + +#include + +class AudioIOStats; +class AudioStreamStats; + +//display +class AudioStatsDisplay : public QObject, public Dependency { + Q_OBJECT + SINGLETON_DEPENDENCY +public: + AudioStatsDisplay(QFormLayout* form, QString text, unsigned colorRGBA); + void updatedDisplay(QString str); + void paint(); + +private: + QString _strBuf; + QLabel* _label; + QString _text; + unsigned _colorRGBA; + +}; + +//dialog +class AudioStatsDialog : public QDialog { + Q_OBJECT +public: + AudioStatsDialog(QWidget* parent); + ~AudioStatsDialog(); + + void paintEvent(QPaintEvent*); + +private: + // audio stats methods for rendering + QVector *_audioMixerStats; + QVector *_upstreamClientStats; + QVector *_upstreamMixerStats; + QVector *_downstreamStats; + QVector *_upstreamInjectedStats; + + void initializeChannel(QFormLayout* form, const unsigned int index, QVector* stats, const unsigned color); + void updateStats(const unsigned index, QVector* stats); + void renderStats(); + void clearAllChannels(); + void renderAudioStreamStats(const AudioStreamStats* streamStats, QVector* audioStreamstats, bool isDownstreamStats); + + const static int DISPLAY_CHANNELS = 5; + QVector *_audioDisplayChannels[DISPLAY_CHANNELS]; + + const AudioIOStats* _stats; + QFormLayout* _form; + + bool _isEnabled; + bool _shouldShowInjectedStreams; + + +signals: + + + void closed(); + + public slots: + + + void reject(); + void updateTimerTimeout(); + +protected: + + // Emits a 'closed' signal when this dialog is closed. + void closeEvent(QCloseEvent*); + +private: + QTimer* averageUpdateTimer = new QTimer(this); + +}; + + + + + +#endif /* defined(__hifi__AudioStatsDialog__) */ + diff --git a/interface/src/ui/DialogsManager.cpp b/interface/src/ui/DialogsManager.cpp index 81c7cd2770..04f532c59a 100644 --- a/interface/src/ui/DialogsManager.cpp +++ b/interface/src/ui/DialogsManager.cpp @@ -114,6 +114,20 @@ void DialogsManager::editAnimations() { } } +void DialogsManager::audioStatsDetails() { + if (! _audioStatsDialog) { + _audioStatsDialog = new AudioStatsDialog(qApp->getWindow()); + connect(_audioStatsDialog, SIGNAL(closed()), _audioStatsDialog, SLOT(deleteLater())); + + if (_hmdToolsDialog) { + _hmdToolsDialog->watchWindow(_audioStatsDialog->windowHandle()); + } + + _audioStatsDialog->show(); + } + _audioStatsDialog->raise(); +} + void DialogsManager::bandwidthDetails() { if (! _bandwidthDialog) { _bandwidthDialog = new BandwidthDialog(qApp->getWindow()); diff --git a/interface/src/ui/DialogsManager.h b/interface/src/ui/DialogsManager.h index 7eb716b73c..b15830e35c 100644 --- a/interface/src/ui/DialogsManager.h +++ b/interface/src/ui/DialogsManager.h @@ -24,6 +24,7 @@ class QAction; class AddressBarDialog; class AnimationsDialog; class AttachmentsDialog; +class AudioStatsDialog; class BandwidthDialog; class CachesSizeDialog; class DiskCacheEditor; @@ -42,6 +43,7 @@ class DialogsManager : public QObject, public Dependency { SINGLETON_DEPENDENCY public: + QPointer getAudioStatsDialog() const { return _audioStatsDialog; } QPointer getBandwidthDialog() const { return _bandwidthDialog; } QPointer getHMDToolsDialog() const { return _hmdToolsDialog; } QPointer getLodToolsDialog() const { return _lodToolsDialog; } @@ -58,6 +60,7 @@ public slots: void editPreferences(); void editAttachments(); void editAnimations(); + void audioStatsDetails(); void bandwidthDetails(); void lodTools(); void hmdTools(bool showTools); @@ -93,6 +96,7 @@ private: QPointer _addressBarDialog; QPointer _animationsDialog; QPointer _attachmentsDialog; + QPointer _audioStatsDialog; QPointer _bandwidthDialog; QPointer _cachesSizeDialog; QPointer _diskCacheEditor; From 2c24251b52df6555a0d4800d7f9d94909e46a0ff Mon Sep 17 00:00:00 2001 From: bwent Date: Wed, 15 Jul 2015 11:41:26 -0700 Subject: [PATCH 02/13] Clean up from previous commit --- interface/src/Application.cpp | 2 -- interface/src/Menu.cpp | 14 -------------- interface/src/ui/ApplicationOverlay.cpp | 4 ++-- 3 files changed, 2 insertions(+), 18 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 745c8c1212..7b7fc53eb4 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -107,7 +107,6 @@ #include "avatar/AvatarManager.h" #include "audio/AudioToolBox.h" -//#include "audio/AudioIOStatsRenderer.h" #include "audio/AudioScope.h" #include "devices/CameraToolBox.h" @@ -274,7 +273,6 @@ bool setupEssentials(int& argc, char** argv) { auto faceshift = DependencyManager::set(); auto audio = DependencyManager::set(); auto audioScope = DependencyManager::set(); -// auto audioIOStatsRenderer = DependencyManager::set(); auto deferredLightingEffect = DependencyManager::set(); auto ambientOcclusionEffect = DependencyManager::set(); auto textureCache = DependencyManager::set(); diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index ae7eb11e98..7702f915a3 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -581,20 +581,6 @@ Menu::Menu() { audioScopeFramesGroup->addAction(fiftyFrames); } -// auto statsRenderer = DependencyManager::get(); -// addCheckableActionToQMenuAndActionHash(audioDebugMenu, MenuOption::AudioStats, -// Qt::CTRL | Qt::SHIFT | Qt::Key_A, -// false, -// statsRenderer.data(), -// SLOT(toggle())); - -// addCheckableActionToQMenuAndActionHash(audioDebugMenu, MenuOption::AudioStatsShowInjectedStreams, -// 0, -// false, -// statsRenderer.data(), -// SLOT(toggleShowInjectedStreams())); -// - MenuWrapper* physicsOptionsMenu = developerMenu->addMenu("Physics"); addCheckableActionToQMenuAndActionHash(physicsOptionsMenu, MenuOption::PhysicsShowOwned); addCheckableActionToQMenuAndActionHash(physicsOptionsMenu, MenuOption::PhysicsShowHulls); diff --git a/interface/src/ui/ApplicationOverlay.cpp b/interface/src/ui/ApplicationOverlay.cpp index bdfa146197..9c17a14937 100644 --- a/interface/src/ui/ApplicationOverlay.cpp +++ b/interface/src/ui/ApplicationOverlay.cpp @@ -23,7 +23,6 @@ #include #include "AudioClient.h" -//#include "audio/AudioIOStatsRenderer.h" #include "audio/AudioScope.h" #include "audio/AudioToolBox.h" #include "Application.h" @@ -935,7 +934,6 @@ void ApplicationOverlay::renderAudioMeter() { auto canvasSize = qApp->getCanvasSize(); DependencyManager::get()->render(canvasSize.x, canvasSize.y); - //DependencyManager::get()->render(WHITE_TEXT, canvasSize.x, canvasSize.y); audioMeterY += AUDIO_METER_HEIGHT; @@ -995,6 +993,8 @@ void ApplicationOverlay::renderAudioMeter() { void ApplicationOverlay::renderStatsAndLogs() { Application* application = Application::getInstance(); + SharedNodePointer audioMixerNodePointer = DependencyManager::get()->soloNodeOfType(NodeType::AudioMixer); + QSharedPointer bandwidthRecorder = DependencyManager::get(); const OctreePacketProcessor& octreePacketProcessor = application->getOctreePacketProcessor(); From c159068701dd4548e9b16cb012112464b585c382 Mon Sep 17 00:00:00 2001 From: bwent Date: Wed, 15 Jul 2015 16:10:41 -0700 Subject: [PATCH 03/13] Make pointers member variables --- interface/src/ui/AudioStatsDialog.cpp | 117 ++++++++++++-------------- interface/src/ui/AudioStatsDialog.h | 12 +-- 2 files changed, 62 insertions(+), 67 deletions(-) diff --git a/interface/src/ui/AudioStatsDialog.cpp b/interface/src/ui/AudioStatsDialog.cpp index 9ee8716321..4eeae76229 100644 --- a/interface/src/ui/AudioStatsDialog.cpp +++ b/interface/src/ui/AudioStatsDialog.cpp @@ -61,54 +61,54 @@ AudioStatsDialog::AudioStatsDialog(QWidget* parent) : _shouldShowInjectedStreams = false; - this->setWindowTitle("Audio Network Statistics"); + setWindowTitle("Audio Network Statistics"); // Get statistics from the Audio Client _stats = &DependencyManager::get()->getStats(); // Create layouter _form = new QFormLayout(); - this->QDialog::setLayout(_form); + QDialog::setLayout(_form); - // Initialize vectors for stat channels - _audioMixerStats = new QVector(); - _upstreamClientStats = new QVector(); - _upstreamMixerStats = new QVector(); - _downstreamStats = new QVector(); - _upstreamInjectedStats = new QVector(); +// // Initialize vectors for stat channels +// _audioMixerStats = *new QVector(); +// _upstreamClientStats = *new QVector(); +// _upstreamMixerStats = *new QVector(); +// _downstreamStats = *new QVector(); +// _upstreamInjectedStats = *new QVector(); // Load and initilize - this->renderStats(); + renderStats(); - this->initializeChannel(_form, 0, _audioMixerStats, COLOR0); - this->initializeChannel(_form, 1, _upstreamClientStats, COLOR1); - this->initializeChannel(_form, 2, _upstreamMixerStats, COLOR2); - this->initializeChannel(_form, 3, _downstreamStats, COLOR3); - this->initializeChannel(_form, 4, _upstreamInjectedStats, COLOR0); + initializeChannel(_form, 0, &_audioMixerStats, COLOR0); + initializeChannel(_form, 1, &_upstreamClientStats, COLOR1); + initializeChannel(_form, 2, &_upstreamMixerStats, COLOR2); + initializeChannel(_form, 3, &_downstreamStats, COLOR3); + initializeChannel(_form, 4, &_upstreamInjectedStats, COLOR0); } void AudioStatsDialog::initializeChannel(QFormLayout* form, const unsigned int index, QVector *stats, const unsigned color) { - _audioDisplayChannels[index] = new QVector(); +// _audioDisplayChannels[index] = new QVector(); for (int i = 0; i < stats->size(); i++) // Create new display label - _audioDisplayChannels[index]->push_back(new AudioStatsDisplay(form, stats->at(i), color)); + _audioDisplayChannels[index].push_back(new AudioStatsDisplay(form, stats->at(i), color)); } void AudioStatsDialog::updateStats(const unsigned int index, QVector* stats) { // Update all stat displays at specified channel for (int i = 0; i < stats->size(); i++) - _audioDisplayChannels[index]->at(i)->updatedDisplay(stats->at(i)); + _audioDisplayChannels[index].at(i)->updatedDisplay(stats->at(i)); } void AudioStatsDialog::renderStats() { // Clear current stats from all vectors - this->clearAllChannels(); + clearAllChannels(); double audioInputBufferLatency = 0.0, inputRingBufferLatency = 0.0, @@ -132,51 +132,51 @@ void AudioStatsDialog::renderStats() { double totalLatency = audioInputBufferLatency + inputRingBufferLatency + networkRoundtripLatency + mixerRingBufferLatency + outputRingBufferLatency + audioOutputBufferLatency; - _audioMixerStats->push_back(QString("Audio input buffer: %1ms").arg( + _audioMixerStats.push_back(QString("Audio input buffer: %1ms").arg( QString::number(audioInputBufferLatency, 'f', 2)) + QString(" - avg msecs of samples read to the audio input buffer in last 10s")); - _audioMixerStats->push_back(QString("Input ring buffer: %1ms").arg( + _audioMixerStats.push_back(QString("Input ring buffer: %1ms").arg( QString::number(inputRingBufferLatency, 'f', 2)) + QString(" - avg msecs of samples read to the input ring buffer in last 10s")); - _audioMixerStats->push_back(QString("Network to mixer: %1ms").arg( + _audioMixerStats.push_back(QString("Network to mixer: %1ms").arg( QString::number((networkRoundtripLatency / 2.0), 'f', 2)) + QString(" - half of last ping value calculated by the node list")); - _audioMixerStats->push_back(QString("Network to client: %1ms").arg( + _audioMixerStats.push_back(QString("Network to client: %1ms").arg( QString::number((mixerRingBufferLatency / 2.0),'f', 2)) + QString(" - half of last ping value calculated by the node list")); - _audioMixerStats->push_back(QString("Output ring buffer: %1ms").arg( + _audioMixerStats.push_back(QString("Output ring buffer: %1ms").arg( QString::number(outputRingBufferLatency,'f', 2)) + QString(" - avg msecs of samples in output ring buffer in last 10s")); - _audioMixerStats->push_back(QString("Audio output buffer: %1ms").arg( + _audioMixerStats.push_back(QString("Audio output buffer: %1ms").arg( QString::number(mixerRingBufferLatency,'f', 2)) + QString(" - avg msecs of samples in audio output buffer in last 10s")); - _audioMixerStats->push_back(QString("TOTAL: %1ms").arg( + _audioMixerStats.push_back(QString("TOTAL: %1ms").arg( QString::number(totalLatency, 'f', 2)) +QString(" - avg msecs of samples in audio output buffer in last 10s")); const MovingMinMaxAvg& packetSentTimeGaps = _stats->getPacketSentTimeGaps(); - _upstreamClientStats->push_back( + _upstreamClientStats.push_back( QString("\nUpstream Mic Audio Packets Sent Gaps (by client):")); - _upstreamClientStats->push_back( + _upstreamClientStats.push_back( QString("Inter-packet timegaps (overall) | min: %1, max: %2, avg: %3").arg(formatUsecTime(packetSentTimeGaps.getMin()).toLatin1().data()).arg(formatUsecTime( packetSentTimeGaps.getMax()).toLatin1().data()).arg(formatUsecTime( packetSentTimeGaps.getAverage()).toLatin1().data())); - _upstreamClientStats->push_back( + _upstreamClientStats.push_back( QString("Inter-packet timegaps (last 30s) | min: %1, max: %2, avg: %3").arg(formatUsecTime(packetSentTimeGaps.getWindowMin()).toLatin1().data()).arg(formatUsecTime(packetSentTimeGaps.getWindowMax()).toLatin1().data()).arg(formatUsecTime(packetSentTimeGaps.getWindowAverage()).toLatin1().data())); - _upstreamMixerStats->push_back(QString("\nUpstream mic audio stats (received and reported by audio-mixer):")); + _upstreamMixerStats.push_back(QString("\nUpstream mic audio stats (received and reported by audio-mixer):")); - renderAudioStreamStats(&_stats->getMixerAvatarStreamStats(), _upstreamMixerStats, true); + renderAudioStreamStats(&_stats->getMixerAvatarStreamStats(), &_upstreamMixerStats, true); - _downstreamStats->push_back(QString("\nDownstream mixed audio stats:")); + _downstreamStats.push_back(QString("\nDownstream mixed audio stats:")); AudioStreamStats downstreamStats = _stats->getMixerDownstreamStats(); - renderAudioStreamStats(&downstreamStats, _downstreamStats, true); + renderAudioStreamStats(&downstreamStats, &_downstreamStats, true); if (_shouldShowInjectedStreams) { foreach(const AudioStreamStats& injectedStreamAudioStats, _stats->getMixerInjectedStreamStatsMap()) { - _upstreamInjectedStats->push_back(QString("\nUpstream injected audio stats: stream ID: %1").arg( injectedStreamAudioStats._streamIdentifier.toString().toLatin1().data())); + _upstreamInjectedStats.push_back(QString("\nUpstream injected audio stats: stream ID: %1").arg( injectedStreamAudioStats._streamIdentifier.toString().toLatin1().data())); - renderAudioStreamStats(&injectedStreamAudioStats, _upstreamInjectedStats, true); + renderAudioStreamStats(&injectedStreamAudioStats, &_upstreamInjectedStats, true); } } @@ -211,24 +211,24 @@ void AudioStatsDialog::renderAudioStreamStats(const AudioStreamStats* streamStat } void AudioStatsDialog::clearAllChannels() { - _audioMixerStats->clear(); - _upstreamClientStats->clear(); - _upstreamMixerStats->clear(); - _downstreamStats->clear(); - _upstreamInjectedStats->clear(); + _audioMixerStats.clear(); + _upstreamClientStats.clear(); + _upstreamMixerStats.clear(); + _downstreamStats.clear(); + _upstreamInjectedStats.clear(); } void AudioStatsDialog::updateTimerTimeout() { // Update all audio stats - this->renderStats(); + renderStats(); - this->updateStats(0, _audioMixerStats); - this->updateStats(1, _upstreamClientStats); - this->updateStats(2, _upstreamMixerStats); - this->updateStats(3, _downstreamStats); - this->updateStats(4, _upstreamInjectedStats); + updateStats(0, &_audioMixerStats); + updateStats(1, &_upstreamClientStats); + updateStats(2, &_upstreamMixerStats); + updateStats(3, &_downstreamStats); + updateStats(4, &_upstreamInjectedStats); } @@ -237,37 +237,32 @@ void AudioStatsDialog::paintEvent(QPaintEvent* event) { // Repaint each statistic in each section for (int i = 0; i < DISPLAY_CHANNELS; i++) { - for(int j = 0; j < _audioDisplayChannels[i]->size(); j++) { - _audioDisplayChannels[i]->at(j)->paint(); + for(int j = 0; j < _audioDisplayChannels[i].size(); j++) { + _audioDisplayChannels[i].at(j)->paint(); } } - this->QDialog::paintEvent(event); - this->setFixedSize(this->width(), this->height()); + QDialog::paintEvent(event); + setFixedSize(width(), height()); } void AudioStatsDialog::reject() { // Just regularly close upon ESC - this->QDialog::close(); + QDialog::close(); } void AudioStatsDialog::closeEvent(QCloseEvent* event) { - this->QDialog::closeEvent(event); + QDialog::closeEvent(event); emit closed(); } AudioStatsDialog::~AudioStatsDialog() { - this->clearAllChannels(); - - delete _audioMixerStats; - delete _upstreamClientStats; - delete _upstreamMixerStats; - delete _downstreamStats; - delete _upstreamInjectedStats; + clearAllChannels(); + for (int i = 0; i < DISPLAY_CHANNELS; i++) { - _audioDisplayChannels[i]->clear(); - for(int j = 0; j < _audioDisplayChannels[i]->size(); j++) { - delete _audioDisplayChannels[i]->at(j); + _audioDisplayChannels[i].clear(); + for(int j = 0; j < _audioDisplayChannels[i].size(); j++) { + delete _audioDisplayChannels[i].at(j); } } diff --git a/interface/src/ui/AudioStatsDialog.h b/interface/src/ui/AudioStatsDialog.h index ce1e8027e3..2f4fb44fbc 100644 --- a/interface/src/ui/AudioStatsDialog.h +++ b/interface/src/ui/AudioStatsDialog.h @@ -56,11 +56,11 @@ public: private: // audio stats methods for rendering - QVector *_audioMixerStats; - QVector *_upstreamClientStats; - QVector *_upstreamMixerStats; - QVector *_downstreamStats; - QVector *_upstreamInjectedStats; + QVector _audioMixerStats; + QVector _upstreamClientStats; + QVector _upstreamMixerStats; + QVector _downstreamStats; + QVector _upstreamInjectedStats; void initializeChannel(QFormLayout* form, const unsigned int index, QVector* stats, const unsigned color); void updateStats(const unsigned index, QVector* stats); @@ -69,7 +69,7 @@ private: void renderAudioStreamStats(const AudioStreamStats* streamStats, QVector* audioStreamstats, bool isDownstreamStats); const static int DISPLAY_CHANNELS = 5; - QVector *_audioDisplayChannels[DISPLAY_CHANNELS]; + QVector _audioDisplayChannels[DISPLAY_CHANNELS]; const AudioIOStats* _stats; QFormLayout* _form; From 0654bb5e3650ec61c5d9512f9f2a8b0109c74f8d Mon Sep 17 00:00:00 2001 From: bwent Date: Wed, 15 Jul 2015 16:40:55 -0700 Subject: [PATCH 04/13] Pass by reference into initialize and update function, remove dead code --- interface/src/ui/AudioStatsDialog.cpp | 41 +++++++++++---------------- interface/src/ui/AudioStatsDialog.h | 4 +-- 2 files changed, 18 insertions(+), 27 deletions(-) diff --git a/interface/src/ui/AudioStatsDialog.cpp b/interface/src/ui/AudioStatsDialog.cpp index 4eeae76229..abe84a31a9 100644 --- a/interface/src/ui/AudioStatsDialog.cpp +++ b/interface/src/ui/AudioStatsDialog.cpp @@ -70,38 +70,29 @@ AudioStatsDialog::AudioStatsDialog(QWidget* parent) : _form = new QFormLayout(); QDialog::setLayout(_form); -// // Initialize vectors for stat channels -// _audioMixerStats = *new QVector(); -// _upstreamClientStats = *new QVector(); -// _upstreamMixerStats = *new QVector(); -// _downstreamStats = *new QVector(); -// _upstreamInjectedStats = *new QVector(); - // Load and initilize renderStats(); - initializeChannel(_form, 0, &_audioMixerStats, COLOR0); - initializeChannel(_form, 1, &_upstreamClientStats, COLOR1); - initializeChannel(_form, 2, &_upstreamMixerStats, COLOR2); - initializeChannel(_form, 3, &_downstreamStats, COLOR3); - initializeChannel(_form, 4, &_upstreamInjectedStats, COLOR0); + initializeChannel(_form, 0, _audioMixerStats, COLOR0); + initializeChannel(_form, 1, _upstreamClientStats, COLOR1); + initializeChannel(_form, 2, _upstreamMixerStats, COLOR2); + initializeChannel(_form, 3, _downstreamStats, COLOR3); + initializeChannel(_form, 4, _upstreamInjectedStats, COLOR0); } -void AudioStatsDialog::initializeChannel(QFormLayout* form, const unsigned int index, QVector *stats, const unsigned color) { +void AudioStatsDialog::initializeChannel(QFormLayout* form, const unsigned int index, QVector& stats, const unsigned color) { -// _audioDisplayChannels[index] = new QVector(); - - for (int i = 0; i < stats->size(); i++) + for (int i = 0; i < stats.size(); i++) // Create new display label - _audioDisplayChannels[index].push_back(new AudioStatsDisplay(form, stats->at(i), color)); + _audioDisplayChannels[index].push_back(new AudioStatsDisplay(form, stats.at(i), color)); } -void AudioStatsDialog::updateStats(const unsigned int index, QVector* stats) { +void AudioStatsDialog::updateStats(const unsigned int index, QVector& stats) { // Update all stat displays at specified channel - for (int i = 0; i < stats->size(); i++) - _audioDisplayChannels[index].at(i)->updatedDisplay(stats->at(i)); + for (int i = 0; i < stats.size(); i++) + _audioDisplayChannels[index].at(i)->updatedDisplay(stats.at(i)); } @@ -224,11 +215,11 @@ void AudioStatsDialog::updateTimerTimeout() { // Update all audio stats renderStats(); - updateStats(0, &_audioMixerStats); - updateStats(1, &_upstreamClientStats); - updateStats(2, &_upstreamMixerStats); - updateStats(3, &_downstreamStats); - updateStats(4, &_upstreamInjectedStats); + updateStats(0, _audioMixerStats); + updateStats(1, _upstreamClientStats); + updateStats(2, _upstreamMixerStats); + updateStats(3, _downstreamStats); + updateStats(4, _upstreamInjectedStats); } diff --git a/interface/src/ui/AudioStatsDialog.h b/interface/src/ui/AudioStatsDialog.h index 2f4fb44fbc..537a91726f 100644 --- a/interface/src/ui/AudioStatsDialog.h +++ b/interface/src/ui/AudioStatsDialog.h @@ -62,8 +62,8 @@ private: QVector _downstreamStats; QVector _upstreamInjectedStats; - void initializeChannel(QFormLayout* form, const unsigned int index, QVector* stats, const unsigned color); - void updateStats(const unsigned index, QVector* stats); + void initializeChannel(QFormLayout* form, const unsigned int index, QVector& stats, const unsigned color); + void updateStats(const unsigned index, QVector& stats); void renderStats(); void clearAllChannels(); void renderAudioStreamStats(const AudioStreamStats* streamStats, QVector* audioStreamstats, bool isDownstreamStats); From 4c70c197e66c668b2d70f39308b70e6840059d28 Mon Sep 17 00:00:00 2001 From: bwent Date: Wed, 15 Jul 2015 17:19:57 -0700 Subject: [PATCH 05/13] keep track of channel index with global variable --- interface/src/ui/AudioStatsDialog.cpp | 49 +++++++++++++++++---------- interface/src/ui/AudioStatsDialog.h | 5 +-- 2 files changed, 34 insertions(+), 20 deletions(-) diff --git a/interface/src/ui/AudioStatsDialog.cpp b/interface/src/ui/AudioStatsDialog.cpp index abe84a31a9..3761d619fc 100644 --- a/interface/src/ui/AudioStatsDialog.cpp +++ b/interface/src/ui/AudioStatsDialog.cpp @@ -73,26 +73,37 @@ AudioStatsDialog::AudioStatsDialog(QWidget* parent) : // Load and initilize renderStats(); - initializeChannel(_form, 0, _audioMixerStats, COLOR0); - initializeChannel(_form, 1, _upstreamClientStats, COLOR1); - initializeChannel(_form, 2, _upstreamMixerStats, COLOR2); - initializeChannel(_form, 3, _downstreamStats, COLOR3); - initializeChannel(_form, 4, _upstreamInjectedStats, COLOR0); + _channelIndex = 0; + + addChannel(_form, _audioMixerStats, COLOR0); + addChannel(_form, _upstreamClientStats, COLOR1); + addChannel(_form, _upstreamMixerStats, COLOR2); + addChannel(_form, _downstreamStats, COLOR3); + addChannel(_form, _upstreamInjectedStats, COLOR0); } -void AudioStatsDialog::initializeChannel(QFormLayout* form, const unsigned int index, QVector& stats, const unsigned color) { +void AudioStatsDialog::addChannel(QFormLayout* form, QVector& stats, const unsigned color) { - for (int i = 0; i < stats.size(); i++) - // Create new display label - _audioDisplayChannels[index].push_back(new AudioStatsDisplay(form, stats.at(i), color)); + if(_channelIndex < DISPLAY_CHANNELS) { + for (int i = 0; i < stats.size(); i++) + // Create new display label + _audioDisplayChannels[_channelIndex].push_back(new AudioStatsDisplay(form, stats.at(i), color)); + + _channelIndex++; + } } -void AudioStatsDialog::updateStats(const unsigned int index, QVector& stats) { - // Update all stat displays at specified channel - for (int i = 0; i < stats.size(); i++) - _audioDisplayChannels[index].at(i)->updatedDisplay(stats.at(i)); +void AudioStatsDialog::updateStats(QVector& stats) { + + if(_channelIndex < DISPLAY_CHANNELS) { + // Update all stat displays at specified channel + for (int i = 0; i < stats.size(); i++) + _audioDisplayChannels[_channelIndex].at(i)->updatedDisplay(stats.at(i)); + + _channelIndex++; + } } @@ -215,11 +226,13 @@ void AudioStatsDialog::updateTimerTimeout() { // Update all audio stats renderStats(); - updateStats(0, _audioMixerStats); - updateStats(1, _upstreamClientStats); - updateStats(2, _upstreamMixerStats); - updateStats(3, _downstreamStats); - updateStats(4, _upstreamInjectedStats); + _channelIndex = 0; + + updateStats(_audioMixerStats); + updateStats(_upstreamClientStats); + updateStats(_upstreamMixerStats); + updateStats(_downstreamStats); + updateStats(_upstreamInjectedStats); } diff --git a/interface/src/ui/AudioStatsDialog.h b/interface/src/ui/AudioStatsDialog.h index 537a91726f..797cd3575b 100644 --- a/interface/src/ui/AudioStatsDialog.h +++ b/interface/src/ui/AudioStatsDialog.h @@ -62,8 +62,8 @@ private: QVector _downstreamStats; QVector _upstreamInjectedStats; - void initializeChannel(QFormLayout* form, const unsigned int index, QVector& stats, const unsigned color); - void updateStats(const unsigned index, QVector& stats); + void addChannel(QFormLayout* form, QVector& stats, const unsigned color); + void updateStats(QVector& stats); void renderStats(); void clearAllChannels(); void renderAudioStreamStats(const AudioStreamStats* streamStats, QVector* audioStreamstats, bool isDownstreamStats); @@ -74,6 +74,7 @@ private: const AudioIOStats* _stats; QFormLayout* _form; + int _channelIndex; bool _isEnabled; bool _shouldShowInjectedStreams; From cf0940a65d992f4cb3d2bee703e2cacc8223ba11 Mon Sep 17 00:00:00 2001 From: Ryan Huffman Date: Thu, 16 Jul 2015 11:07:01 -0700 Subject: [PATCH 06/13] Fix edit.js highlighting an object after being turned off --- examples/edit.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/examples/edit.js b/examples/edit.js index 23cc942192..dfbace7be6 100644 --- a/examples/edit.js +++ b/examples/edit.js @@ -656,7 +656,9 @@ function mouseMove(event) { function handleIdleMouse() { idleMouseTimerId = null; - highlightEntityUnderCursor(lastMousePosition, true); + if (isActive) { + highlightEntityUnderCursor(lastMousePosition, true); + } } function highlightEntityUnderCursor(position, accurateRay) { From 854a098180c4c8d4bd7c3402eb84716008707891 Mon Sep 17 00:00:00 2001 From: bwent Date: Thu, 16 Jul 2015 12:28:43 -0700 Subject: [PATCH 07/13] keep track of channel id's within addChannel function, pass in when updating --- interface/src/ui/AudioStatsDialog.cpp | 65 +++++++++++++-------------- interface/src/ui/AudioStatsDialog.h | 15 ++++--- 2 files changed, 41 insertions(+), 39 deletions(-) diff --git a/interface/src/ui/AudioStatsDialog.cpp b/interface/src/ui/AudioStatsDialog.cpp index 3761d619fc..b84b3f452b 100644 --- a/interface/src/ui/AudioStatsDialog.cpp +++ b/interface/src/ui/AudioStatsDialog.cpp @@ -69,41 +69,40 @@ AudioStatsDialog::AudioStatsDialog(QWidget* parent) : // Create layouter _form = new QFormLayout(); QDialog::setLayout(_form); - - // Load and initilize + + // Load and initilize all channels renderStats(); - _channelIndex = 0; + _audioDisplayChannels = QVector>(1); - addChannel(_form, _audioMixerStats, COLOR0); - addChannel(_form, _upstreamClientStats, COLOR1); - addChannel(_form, _upstreamMixerStats, COLOR2); - addChannel(_form, _downstreamStats, COLOR3); - addChannel(_form, _upstreamInjectedStats, COLOR0); + _audioMixerID = addChannel(_form, _audioMixerStats, COLOR0); + _upstreamClientID = addChannel(_form, _upstreamClientStats, COLOR1); + _upstreamMixerID = addChannel(_form, _upstreamMixerStats, COLOR2); + _downstreamID = addChannel(_form, _downstreamStats, COLOR3); + _upstreamInjectedID = addChannel(_form, _upstreamInjectedStats, COLOR0); } -void AudioStatsDialog::addChannel(QFormLayout* form, QVector& stats, const unsigned color) { +int AudioStatsDialog::addChannel(QFormLayout* form, QVector& stats, const unsigned color) { - if(_channelIndex < DISPLAY_CHANNELS) { - for (int i = 0; i < stats.size(); i++) - // Create new display label - _audioDisplayChannels[_channelIndex].push_back(new AudioStatsDisplay(form, stats.at(i), color)); - - _channelIndex++; - } + int channelID = _audioDisplayChannels.size() - 1; + for (int i = 0; i < stats.size(); i++) + // Create new display label + _audioDisplayChannels[channelID].push_back(new AudioStatsDisplay(form, stats.at(i), color)); + + // Expand vector to fit next channel + _audioDisplayChannels.resize(_audioDisplayChannels.size() + 1); + + return channelID; } -void AudioStatsDialog::updateStats(QVector& stats) { +void AudioStatsDialog::updateStats(QVector& stats, int channelID) { - if(_channelIndex < DISPLAY_CHANNELS) { - // Update all stat displays at specified channel - for (int i = 0; i < stats.size(); i++) - _audioDisplayChannels[_channelIndex].at(i)->updatedDisplay(stats.at(i)); + // Update all stat displays at specified channel + for (int i = 0; i < stats.size(); i++) + _audioDisplayChannels[channelID].at(i)->updatedDisplay(stats.at(i)); - _channelIndex++; - } } @@ -226,25 +225,24 @@ void AudioStatsDialog::updateTimerTimeout() { // Update all audio stats renderStats(); - _channelIndex = 0; - - updateStats(_audioMixerStats); - updateStats(_upstreamClientStats); - updateStats(_upstreamMixerStats); - updateStats(_downstreamStats); - updateStats(_upstreamInjectedStats); + updateStats(_audioMixerStats, _audioMixerID); + updateStats(_upstreamClientStats, _upstreamClientID); + updateStats(_upstreamMixerStats, _upstreamMixerID); + updateStats(_downstreamStats, _downstreamID); + updateStats(_upstreamInjectedStats, _upstreamInjectedID); } void AudioStatsDialog::paintEvent(QPaintEvent* event) { - // Repaint each statistic in each section - for (int i = 0; i < DISPLAY_CHANNELS; i++) { + // Repaint each stat in each channel + for (int i = 0; i < _audioDisplayChannels.size(); i++) { for(int j = 0; j < _audioDisplayChannels[i].size(); j++) { _audioDisplayChannels[i].at(j)->paint(); } } + QDialog::paintEvent(event); setFixedSize(width(), height()); } @@ -262,8 +260,7 @@ void AudioStatsDialog::closeEvent(QCloseEvent* event) { AudioStatsDialog::~AudioStatsDialog() { clearAllChannels(); - - for (int i = 0; i < DISPLAY_CHANNELS; i++) { + for (int i = 0; i < _audioDisplayChannels.size(); i++) { _audioDisplayChannels[i].clear(); for(int j = 0; j < _audioDisplayChannels[i].size(); j++) { delete _audioDisplayChannels[i].at(j); diff --git a/interface/src/ui/AudioStatsDialog.h b/interface/src/ui/AudioStatsDialog.h index 797cd3575b..7f14cd6018 100644 --- a/interface/src/ui/AudioStatsDialog.h +++ b/interface/src/ui/AudioStatsDialog.h @@ -62,19 +62,24 @@ private: QVector _downstreamStats; QVector _upstreamInjectedStats; - void addChannel(QFormLayout* form, QVector& stats, const unsigned color); - void updateStats(QVector& stats); + int _audioMixerID; + int _upstreamClientID; + int _upstreamMixerID; + int _downstreamID; + int _upstreamInjectedID; + + QVector> _audioDisplayChannels; + + int addChannel(QFormLayout* form, QVector& stats, const unsigned color); + void updateStats(QVector& stats, const int channelID); void renderStats(); void clearAllChannels(); void renderAudioStreamStats(const AudioStreamStats* streamStats, QVector* audioStreamstats, bool isDownstreamStats); - const static int DISPLAY_CHANNELS = 5; - QVector _audioDisplayChannels[DISPLAY_CHANNELS]; const AudioIOStats* _stats; QFormLayout* _form; - int _channelIndex; bool _isEnabled; bool _shouldShowInjectedStreams; From cf9365e616c66fd4a4154d74e6ea7c394cdc12eb Mon Sep 17 00:00:00 2001 From: Philip Rosedale Date: Thu, 16 Jul 2015 22:46:41 -0700 Subject: [PATCH 08/13] Add new sample script with flocking --- examples/FlockOfbirds.js | 258 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 258 insertions(+) create mode 100644 examples/FlockOfbirds.js diff --git a/examples/FlockOfbirds.js b/examples/FlockOfbirds.js new file mode 100644 index 0000000000..a3ecd77311 --- /dev/null +++ b/examples/FlockOfbirds.js @@ -0,0 +1,258 @@ +// +// flockOfbirds.js +// examples +// +// Copyright 2014 High Fidelity, Inc. +// Creates a flock of birds that fly around and chirp, staying inside the corners of the box defined +// at the start of the script. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html + + + +// The area over which the birds will fly +var lowerCorner = { x: 1, y: 1, z: 1 }; +var upperCorner = { x: 10, y: 10, z: 10 }; +var STARTING_FRACTION = 0.25; + +var NUM_BIRDS = 50; +var playSounds = true; +var SOUND_PROBABILITY = 0.001; +var numPlaying = 0; +var BIRD_SIZE = 0.08; +var BIRD_MASTER_VOLUME = 0.1; +var FLAP_PROBABILITY = 0.005; +var RANDOM_FLAP_VELOCITY = 1.0; +var FLAP_UP = 1.0; +var BIRD_GRAVITY = -0.5; +var LINEAR_DAMPING = 0.2; +var FLAP_FALLING_PROBABILITY = 0.025; +var MIN_ALIGNMENT_VELOCITY = 0.0; +var MAX_ALIGNMENT_VELOCITY = 1.0; +var VERTICAL_ALIGNMENT_COUPLING = 0.0; +var ALIGNMENT_FORCE = 1.5; +var COHESION_FORCE = 1.0; +var MAX_COHESION_VELOCITY = 0.5; + +var floor = false; +var MAKE_FLOOR = false; + +var averageVelocity = { x: 0, y: 0, z: 0 }; +var averagePosition = { x: 0, y: 0, z: 0 }; + +var birds = []; +var playing = []; + +function randomVector(scale) { + return { x: Math.random() * scale - scale / 2.0, y: Math.random() * scale - scale / 2.0, z: Math.random() * scale - scale / 2.0 }; +} + +function updateBirds(deltaTime) { + var sumVelocity = { x: 0, y: 0, z: 0 }; + var sumPosition = { x: 0, y: 0, z: 0 }; + var birdPositionsCounted = 0; + var birdVelocitiesCounted = 0; + for (var i = 0; i < birds.length; i++) { + if (birds[i].entityId) { + var properties = Entities.getEntityProperties(birds[i].entityId); + // If Bird has been deleted, bail + if (properties.id != birds[i].entityId) { + birds[i].entityId = false; + return; + } + // Sum up average position and velocity + if (Vec3.length(properties.velocity) > MIN_ALIGNMENT_VELOCITY) { + sumVelocity = Vec3.sum(sumVelocity, properties.velocity); + birdVelocitiesCounted += 1; + } + sumPosition = Vec3.sum(sumPosition, properties.position); + birdPositionsCounted += 1; + + var downwardSpeed = (properties.velocity.y < 0) ? -properties.velocity.y : 0.0; + if ((properties.position.y < upperCorner.y) && (Math.random() < (FLAP_PROBABILITY + (downwardSpeed * FLAP_FALLING_PROBABILITY)))) { + // More likely to flap if falling + var randomVelocity = randomVector(RANDOM_FLAP_VELOCITY); + randomVelocity.y = FLAP_UP + Math.random() * FLAP_UP; + + // Alignment Velocity + var alignmentVelocityMagnitude = Math.min(MAX_ALIGNMENT_VELOCITY, Vec3.length(Vec3.multiply(ALIGNMENT_FORCE, averageVelocity))); + var alignmentVelocity = Vec3.multiply(alignmentVelocityMagnitude, Vec3.normalize(averageVelocity)); + alignmentVelocity.y *= VERTICAL_ALIGNMENT_COUPLING; + + // Cohesion + var distanceFromCenter = Vec3.length(Vec3.subtract(averagePosition, properties.position)); + var cohesionVelocitySize = Math.min(distanceFromCenter * COHESION_FORCE, MAX_COHESION_VELOCITY); + var cohesionVelocity = Vec3.multiply(cohesionVelocitySize, Vec3.normalize(Vec3.subtract(averagePosition, properties.position))); + + var newVelocity = Vec3.sum(randomVelocity, Vec3.sum(alignmentVelocity, cohesionVelocity)); + + Entities.editEntity(birds[i].entityId, { velocity: Vec3.sum(properties.velocity, newVelocity) }); + + } + + // Check whether to play a chirp + if (playSounds && (!birds[i].audioId || !birds[i].audioId.isPlaying) && (Math.random() < ((numPlaying > 0) ? SOUND_PROBABILITY / numPlaying : SOUND_PROBABILITY))) { + var options = { + position: properties.position, + volume: BIRD_MASTER_VOLUME + }; + // Play chirp + if (birds[i].audioId) { + birds[i].audioId.setOptions(options); + birds[i].audioId.restart(); + } else { + birds[i].audioId = Audio.playSound(birds[i].sound, options); + } + numPlaying++; + // Change size + Entities.editEntity(birds[i].entityId, { dimensions: Vec3.multiply(1.5, properties.dimensions)}); + + } + + if (birds[i].audioId) { + // If bird is playing a chirp + if (!birds[i].audioId.isPlaying) { + // clear ID if playing has stopped + Entities.editEntity(birds[i].entityId, { dimensions: { x: BIRD_SIZE, y: BIRD_SIZE, z: BIRD_SIZE }}); + birds[i].audioId = false; + numPlaying--; + print("num playing" + numPlaying); + } + } + + // Keep birds in their 'cage' + var bounce = false; + var newVelocity = properties.velocity; + var newPosition = properties.position; + if (properties.position.x < lowerCorner.x) { + newPosition.x = lowerCorner.x; + newVelocity.x *= -1.0; + bounce = true; + } else if (properties.position.x > upperCorner.x) { + newPosition.x = upperCorner.x; + newVelocity.x *= -1.0; + bounce = true; + } + if (properties.position.y < lowerCorner.y) { + newPosition.y = lowerCorner.y; + newVelocity.y *= -1.0; + bounce = true; + } else if (properties.position.y > upperCorner.y) { + newPosition.y = upperCorner.y; + newVelocity.y *= -1.0; + bounce = true; + } + if (properties.position.z < lowerCorner.z) { + newPosition.z = lowerCorner.z; + newVelocity.z *= -1.0; + bounce = true; + } else if (properties.position.z > upperCorner.z) { + newPosition.z = upperCorner.z; + newVelocity.z *= -1.0; + bounce = true; + } + if (bounce) { + Entities.editEntity(birds[i].entityId, { position: newPosition, velocity: newVelocity }); + } + } + } + // Update average velocity and position of flock + if (birdVelocitiesCounted > 0) { + averageVelocity = Vec3.multiply(1.0 / birdVelocitiesCounted, sumVelocity); + //print(Vec3.length(averageVelocity)); + } + if (birdPositionsCounted > 0) { + averagePosition = Vec3.multiply(1.0 / birdPositionsCounted, sumPosition); + } +} + +loadBirds(NUM_BIRDS); +if (MAKE_FLOOR) { + var FLOOR_THICKNESS = 0.05; + floor = Entities.addEntity({ type: "Box", position: { x: lowerCorner.x + (upperCorner.x - lowerCorner.x) / 2.0, + y: lowerCorner.y, + z: lowerCorner.z + (upperCorner.z - lowerCorner.z) / 2.0 }, + dimensions: { x: (upperCorner.x - lowerCorner.x), y: FLOOR_THICKNESS, z: (upperCorner.z - lowerCorner.z)}, + color: {red: 100, green: 100, blue: 100} + }); +} +// Connect a call back that happens every frame +Script.update.connect(updateBirds); + +// Delete our little friends if script is stopped +Script.scriptEnding.connect(function() { + for (var i = 0; i < birds.length; i++) { + Entities.deleteEntity(birds[i].entityId); + } + if (floor) { + Entities.deleteEntity(floor); + } +}); + +function loadBirds(howMany) { + var sound_filenames = ["bushtit_1.raw", "bushtit_2.raw", "bushtit_3.raw"]; + /* Here are more sounds/species you can use + , "mexicanWhipoorwill.raw", + "rosyfacedlovebird.raw", "saysphoebe.raw", "westernscreechowl.raw", "bandtailedpigeon.wav", "bridledtitmouse.wav", + "browncrestedflycatcher.wav", "commonnighthawk.wav", "commonpoorwill.wav", "doublecrestedcormorant.wav", + "gambelsquail.wav", "goldcrownedkinglet.wav", "greaterroadrunner.wav","groovebilledani.wav","hairywoodpecker.wav", + "housewren.wav","hummingbird.wav", "mountainchickadee.wav", "nightjar.wav", "piebilledgrieb.wav", "pygmynuthatch.wav", + "whistlingduck.wav", "woodpecker.wav"]; + */ + + var colors = [ + { red: 242, green: 207, blue: 013 }, + { red: 238, green: 94, blue: 11 }, + { red: 81, green: 30, blue: 7 }, + { red: 195, green: 176, blue: 81 }, + { red: 235, green: 190, blue: 152 }, + { red: 167, green: 99, blue: 52 }, + { red: 199, green: 122, blue: 108 }, + { red: 246, green: 220, blue: 189 }, + { red: 208, green: 145, blue: 65 }, + { red: 173, green: 120 , blue: 71 }, + { red: 132, green: 147, blue: 174 }, + { red: 164, green: 74, blue: 40 }, + { red: 131, green: 127, blue: 134 }, + { red: 209, green: 157, blue: 117 }, + { red: 205, green: 191, blue: 193 }, + { red: 193, green: 154, blue: 118 }, + { red: 205, green: 190, blue: 169 }, + { red: 199, green: 111, blue: 69 }, + { red: 221, green: 223, blue: 228 }, + { red: 115, green: 92, blue: 87 }, + { red: 214, green: 165, blue: 137 }, + { red: 160, green: 124, blue: 33 }, + { red: 117, green: 91, blue: 86 }, + { red: 113, green: 104, blue: 107 }, + { red: 216, green: 153, blue: 99 }, + { red: 242, green: 226, blue: 64 } + ]; + + var SOUND_BASE_URL = "http://public.highfidelity.io/sounds/Animals/"; + + for (var i = 0; i < howMany; i++) { + var whichBird = Math.floor(Math.random() * sound_filenames.length); + var position = { + x: lowerCorner.x + (upperCorner.x - lowerCorner.x) / 2.0 + (Math.random() - 0.5) * (upperCorner.x - lowerCorner.x) * STARTING_FRACTION, + y: lowerCorner.y + (upperCorner.y - lowerCorner.y) / 2.0 + (Math.random() - 0.5) * (upperCorner.y - lowerCorner.y) * STARTING_FRACTION, + z: lowerCorner.z + (upperCorner.z - lowerCorner.x) / 2.0 + (Math.random() - 0.5) * (upperCorner.z - lowerCorner.z) * STARTING_FRACTION + }; + + birds.push({ + sound: SoundCache.getSound(SOUND_BASE_URL + sound_filenames[whichBird]), + entityId: Entities.addEntity({ + type: "Sphere", + position: position, + dimensions: { x: BIRD_SIZE, y: BIRD_SIZE, z: BIRD_SIZE }, + gravity: { x: 0, y: BIRD_GRAVITY, z: 0 }, + velocity: { x: 0, y: -0.1, z: 0 }, + linearDamping: LINEAR_DAMPING, + collisionsWillMove: true, + color: colors[whichBird] + }), + audioId: false + }); + } +} \ No newline at end of file From 5c29eb97efda45c0f81cdba65df6934f627cd8f6 Mon Sep 17 00:00:00 2001 From: Philip Rosedale Date: Thu, 16 Jul 2015 23:32:40 -0700 Subject: [PATCH 09/13] remove debug --- examples/FlockOfbirds.js | 1 - 1 file changed, 1 deletion(-) diff --git a/examples/FlockOfbirds.js b/examples/FlockOfbirds.js index a3ecd77311..e15f6764a0 100644 --- a/examples/FlockOfbirds.js +++ b/examples/FlockOfbirds.js @@ -117,7 +117,6 @@ function updateBirds(deltaTime) { Entities.editEntity(birds[i].entityId, { dimensions: { x: BIRD_SIZE, y: BIRD_SIZE, z: BIRD_SIZE }}); birds[i].audioId = false; numPlaying--; - print("num playing" + numPlaying); } } From db219905f3cce527a0822041cf8193c04d3397ec Mon Sep 17 00:00:00 2001 From: Philip Rosedale Date: Fri, 17 Jul 2015 00:30:31 -0700 Subject: [PATCH 10/13] re-use audio injectors, don't check if isPlaying immediately after starting play out --- examples/FlockOfbirds.js | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/examples/FlockOfbirds.js b/examples/FlockOfbirds.js index e15f6764a0..de30f2d374 100644 --- a/examples/FlockOfbirds.js +++ b/examples/FlockOfbirds.js @@ -108,14 +108,11 @@ function updateBirds(deltaTime) { // Change size Entities.editEntity(birds[i].entityId, { dimensions: Vec3.multiply(1.5, properties.dimensions)}); - } - - if (birds[i].audioId) { + } else if (birds[i].audioId) { // If bird is playing a chirp if (!birds[i].audioId.isPlaying) { // clear ID if playing has stopped Entities.editEntity(birds[i].entityId, { dimensions: { x: BIRD_SIZE, y: BIRD_SIZE, z: BIRD_SIZE }}); - birds[i].audioId = false; numPlaying--; } } @@ -251,7 +248,8 @@ function loadBirds(howMany) { collisionsWillMove: true, color: colors[whichBird] }), - audioId: false + audioId: false, + isPlaying: false }); } } \ No newline at end of file From 689b0e257158a452c64c7e687b7e4ca2e4da64e5 Mon Sep 17 00:00:00 2001 From: Philip Rosedale Date: Fri, 17 Jul 2015 09:41:48 -0700 Subject: [PATCH 11/13] Improve to run correctly on startup as AC --- examples/FlockOfbirds.js | 33 ++++++++++++++++++++++----------- 1 file changed, 22 insertions(+), 11 deletions(-) diff --git a/examples/FlockOfbirds.js b/examples/FlockOfbirds.js index de30f2d374..a8a5aafe6d 100644 --- a/examples/FlockOfbirds.js +++ b/examples/FlockOfbirds.js @@ -41,6 +41,8 @@ var MAKE_FLOOR = false; var averageVelocity = { x: 0, y: 0, z: 0 }; var averagePosition = { x: 0, y: 0, z: 0 }; +var birdsLoaded = false; + var birds = []; var playing = []; @@ -49,6 +51,14 @@ function randomVector(scale) { } function updateBirds(deltaTime) { + if (!Entities.serversExist() || !Entities.canRez()) { + return; + } + if (!birdsLoaded) { + loadBirds(NUM_BIRDS); + birdsLoaded = true; + return; + } var sumVelocity = { x: 0, y: 0, z: 0 }; var sumPosition = { x: 0, y: 0, z: 0 }; var birdPositionsCounted = 0; @@ -163,16 +173,6 @@ function updateBirds(deltaTime) { } } -loadBirds(NUM_BIRDS); -if (MAKE_FLOOR) { - var FLOOR_THICKNESS = 0.05; - floor = Entities.addEntity({ type: "Box", position: { x: lowerCorner.x + (upperCorner.x - lowerCorner.x) / 2.0, - y: lowerCorner.y, - z: lowerCorner.z + (upperCorner.z - lowerCorner.z) / 2.0 }, - dimensions: { x: (upperCorner.x - lowerCorner.x), y: FLOOR_THICKNESS, z: (upperCorner.z - lowerCorner.z)}, - color: {red: 100, green: 100, blue: 100} - }); -} // Connect a call back that happens every frame Script.update.connect(updateBirds); @@ -187,6 +187,8 @@ Script.scriptEnding.connect(function() { }); function loadBirds(howMany) { + while (!Entities.serversExist() || !Entities.canRez()) { + } var sound_filenames = ["bushtit_1.raw", "bushtit_2.raw", "bushtit_3.raw"]; /* Here are more sounds/species you can use , "mexicanWhipoorwill.raw", @@ -251,5 +253,14 @@ function loadBirds(howMany) { audioId: false, isPlaying: false }); - } + } + if (MAKE_FLOOR) { + var FLOOR_THICKNESS = 0.05; + floor = Entities.addEntity({ type: "Box", position: { x: lowerCorner.x + (upperCorner.x - lowerCorner.x) / 2.0, + y: lowerCorner.y, + z: lowerCorner.z + (upperCorner.z - lowerCorner.z) / 2.0 }, + dimensions: { x: (upperCorner.x - lowerCorner.x), y: FLOOR_THICKNESS, z: (upperCorner.z - lowerCorner.z)}, + color: {red: 100, green: 100, blue: 100} + }); + } } \ No newline at end of file From ee435d9732faccda4ea62479ef4d058ec4bcde36 Mon Sep 17 00:00:00 2001 From: Philip Rosedale Date: Fri, 17 Jul 2015 09:43:33 -0700 Subject: [PATCH 12/13] remove comment --- examples/FlockOfbirds.js | 1 - 1 file changed, 1 deletion(-) diff --git a/examples/FlockOfbirds.js b/examples/FlockOfbirds.js index a8a5aafe6d..0e8c6d4731 100644 --- a/examples/FlockOfbirds.js +++ b/examples/FlockOfbirds.js @@ -121,7 +121,6 @@ function updateBirds(deltaTime) { } else if (birds[i].audioId) { // If bird is playing a chirp if (!birds[i].audioId.isPlaying) { - // clear ID if playing has stopped Entities.editEntity(birds[i].entityId, { dimensions: { x: BIRD_SIZE, y: BIRD_SIZE, z: BIRD_SIZE }}); numPlaying--; } From b22fd3f4a02ba0f9a628014a7766cc9f7e9ea66a Mon Sep 17 00:00:00 2001 From: bwent Date: Fri, 17 Jul 2015 10:58:30 -0700 Subject: [PATCH 13/13] fixed lagging issues --- interface/src/ui/AudioStatsDialog.cpp | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/interface/src/ui/AudioStatsDialog.cpp b/interface/src/ui/AudioStatsDialog.cpp index b84b3f452b..1d6d84a15b 100644 --- a/interface/src/ui/AudioStatsDialog.cpp +++ b/interface/src/ui/AudioStatsDialog.cpp @@ -1,9 +1,9 @@ // // AudioStatsDialog.cpp -// hifi +// interface/src/ui // // Created by Bridget Went on 7/9/15. -// +// Copyright 2015 High Fidelity, Inc. // // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html @@ -72,7 +72,7 @@ AudioStatsDialog::AudioStatsDialog(QWidget* parent) : // Load and initilize all channels renderStats(); - + _audioDisplayChannels = QVector>(1); _audioMixerID = addChannel(_form, _audioMixerStats, COLOR0); @@ -80,7 +80,11 @@ AudioStatsDialog::AudioStatsDialog(QWidget* parent) : _upstreamMixerID = addChannel(_form, _upstreamMixerStats, COLOR2); _downstreamID = addChannel(_form, _downstreamStats, COLOR3); _upstreamInjectedID = addChannel(_form, _upstreamInjectedStats, COLOR0); - + + + connect(averageUpdateTimer, SIGNAL(timeout()), this, SLOT(updateTimerTimeout())); + averageUpdateTimer->start(1000); + } int AudioStatsDialog::addChannel(QFormLayout* form, QVector& stats, const unsigned color) { @@ -98,16 +102,13 @@ int AudioStatsDialog::addChannel(QFormLayout* form, QVector& stats, con } void AudioStatsDialog::updateStats(QVector& stats, int channelID) { - // Update all stat displays at specified channel for (int i = 0; i < stats.size(); i++) _audioDisplayChannels[channelID].at(i)->updatedDisplay(stats.at(i)); - } - void AudioStatsDialog::renderStats() { - + // Clear current stats from all vectors clearAllChannels(); @@ -181,9 +182,6 @@ void AudioStatsDialog::renderStats() { } } - - connect(averageUpdateTimer, SIGNAL(timeout()), this, SLOT(updateTimerTimeout())); - averageUpdateTimer->start(1000); } @@ -222,9 +220,9 @@ void AudioStatsDialog::clearAllChannels() { void AudioStatsDialog::updateTimerTimeout() { - // Update all audio stats renderStats(); + // Update all audio stats updateStats(_audioMixerStats, _audioMixerID); updateStats(_upstreamClientStats, _upstreamClientID); updateStats(_upstreamMixerStats, _upstreamMixerID); @@ -259,7 +257,6 @@ void AudioStatsDialog::closeEvent(QCloseEvent* event) { AudioStatsDialog::~AudioStatsDialog() { clearAllChannels(); - for (int i = 0; i < _audioDisplayChannels.size(); i++) { _audioDisplayChannels[i].clear(); for(int j = 0; j < _audioDisplayChannels[i].size(); j++) {