mirror of
https://github.com/HifiExperiments/overte.git
synced 2025-08-14 14:36:55 +02:00
Added a dialog box to display audio network statistics
This commit is contained in:
parent
93fbfcbff7
commit
5b0b7229ba
9 changed files with 429 additions and 18 deletions
|
@ -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<Faceshift>();
|
||||
auto audio = DependencyManager::set<AudioClient>();
|
||||
auto audioScope = DependencyManager::set<AudioScope>();
|
||||
auto audioIOStatsRenderer = DependencyManager::set<AudioIOStatsRenderer>();
|
||||
// auto audioIOStatsRenderer = DependencyManager::set<AudioIOStatsRenderer>();
|
||||
auto deferredLightingEffect = DependencyManager::set<DeferredLightingEffect>();
|
||||
auto ambientOcclusionEffect = DependencyManager::set<AmbientOcclusionEffect>();
|
||||
auto textureCache = DependencyManager::set<TextureCache>();
|
||||
|
@ -2443,6 +2443,12 @@ void Application::updateDialogs(float deltaTime) {
|
|||
PerformanceWarning warn(showWarnings, "Application::updateDialogs()");
|
||||
auto dialogsManager = DependencyManager::get<DialogsManager>();
|
||||
|
||||
// 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) {
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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<AudioIOStatsRenderer>();
|
||||
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<AudioIOStatsRenderer>();
|
||||
// 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);
|
||||
|
|
|
@ -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";
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
#include <OffscreenUi.h>
|
||||
|
||||
#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<AudioScope>()->render(canvasSize.x, canvasSize.y);
|
||||
DependencyManager::get<AudioIOStatsRenderer>()->render(WHITE_TEXT, canvasSize.x, canvasSize.y);
|
||||
//DependencyManager::get<AudioIOStatsRenderer>()->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> bandwidthRecorder = DependencyManager::get<BandwidthRecorder>();
|
||||
|
||||
const OctreePacketProcessor& octreePacketProcessor = application->getOctreePacketProcessor();
|
||||
|
|
276
interface/src/ui/AudioStatsDialog.cpp
Normal file
276
interface/src/ui/AudioStatsDialog.cpp
Normal file
|
@ -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 <cstdio>
|
||||
|
||||
#include "InterfaceConfig.h"
|
||||
|
||||
#include <AudioClient.h>
|
||||
#include <AudioConstants.h>
|
||||
#include <AudioIOStats.h>
|
||||
#include <DependencyManager.h>
|
||||
#include <GeometryCache.h>
|
||||
#include <NodeList.h>
|
||||
#include <Util.h>
|
||||
|
||||
|
||||
#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<AudioClient>()->getStats();
|
||||
|
||||
// Create layouter
|
||||
_form = new QFormLayout();
|
||||
this->QDialog::setLayout(_form);
|
||||
|
||||
// Initialize vectors for stat channels
|
||||
_audioMixerStats = new QVector<QString>();
|
||||
_upstreamClientStats = new QVector<QString>();
|
||||
_upstreamMixerStats = new QVector<QString>();
|
||||
_downstreamStats = new QVector<QString>();
|
||||
_upstreamInjectedStats = new QVector<QString>();
|
||||
|
||||
// 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<QString> *stats, const unsigned color) {
|
||||
|
||||
_audioDisplayChannels[index] = new QVector<AudioStatsDisplay *>();
|
||||
|
||||
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<QString>* 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<NodeList>()->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<quint64>& 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<QString>* 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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
107
interface/src/ui/AudioStatsDialog.h
Normal file
107
interface/src/ui/AudioStatsDialog.h
Normal file
|
@ -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 <stdio.h>
|
||||
|
||||
#include <QDialog>
|
||||
#include <QLabel>
|
||||
#include <QFormLayout>
|
||||
#include <QVector>
|
||||
#include <QTimer>
|
||||
#include <QString>
|
||||
|
||||
#include <QObject>
|
||||
|
||||
#include <DependencyManager.h>
|
||||
|
||||
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<QString> *_audioMixerStats;
|
||||
QVector<QString> *_upstreamClientStats;
|
||||
QVector<QString> *_upstreamMixerStats;
|
||||
QVector<QString> *_downstreamStats;
|
||||
QVector<QString> *_upstreamInjectedStats;
|
||||
|
||||
void initializeChannel(QFormLayout* form, const unsigned int index, QVector<QString>* stats, const unsigned color);
|
||||
void updateStats(const unsigned index, QVector<QString>* stats);
|
||||
void renderStats();
|
||||
void clearAllChannels();
|
||||
void renderAudioStreamStats(const AudioStreamStats* streamStats, QVector<QString>* audioStreamstats, bool isDownstreamStats);
|
||||
|
||||
const static int DISPLAY_CHANNELS = 5;
|
||||
QVector<AudioStatsDisplay *> *_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__) */
|
||||
|
|
@ -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());
|
||||
|
|
|
@ -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<AudioStatsDialog> getAudioStatsDialog() const { return _audioStatsDialog; }
|
||||
QPointer<BandwidthDialog> getBandwidthDialog() const { return _bandwidthDialog; }
|
||||
QPointer<HMDToolsDialog> getHMDToolsDialog() const { return _hmdToolsDialog; }
|
||||
QPointer<LodToolsDialog> 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> _addressBarDialog;
|
||||
QPointer<AnimationsDialog> _animationsDialog;
|
||||
QPointer<AttachmentsDialog> _attachmentsDialog;
|
||||
QPointer<AudioStatsDialog> _audioStatsDialog;
|
||||
QPointer<BandwidthDialog> _bandwidthDialog;
|
||||
QPointer<CachesSizeDialog> _cachesSizeDialog;
|
||||
QPointer<DiskCacheEditor> _diskCacheEditor;
|
||||
|
|
Loading…
Reference in a new issue