add graphs to audio stats

This commit is contained in:
Zach Pomerantz 2016-09-26 16:33:56 -07:00
parent f5e1d4dd2b
commit 6035374004
7 changed files with 126 additions and 64 deletions

View file

@ -13,24 +13,28 @@ import QtQuick.Controls 1.4
import QtQuick.Layouts 1.3 import QtQuick.Layouts 1.3
ColumnLayout { ColumnLayout {
id: jitter
property var max property var max
property var avg property var avg
property var maxWindow property var maxWindow
property var avgWindow property var avgWindow
property bool showGraphs: false
MovingValuePair { MovingValuePair {
label: "Total" label: "Total"
label1: "Average" label1: "Maximum"
label2: "Maximum" label2: "Average"
source1: avg source1: max
source2: max source2: avg
showGraphs: jitter.showGraphs
} }
MovingValuePair { MovingValuePair {
label: "Window" label: "Window"
label1: "Average" label1: "Maximum"
label2: "Maximum" label2: "Average"
source1: avgWindow source1: maxWindow
source2: maxWindow source2: avgWindow
showGraphs: jitter.showGraphs
} }
} }

View file

@ -11,12 +11,14 @@
import QtQuick 2.5 import QtQuick 2.5
import QtQuick.Controls 1.4 import QtQuick.Controls 1.4
import QtQuick.Layouts 1.3 import QtQuick.Layouts 1.3
import "../lib/plotperf"
RowLayout { RowLayout {
id: value id: value
property string label property string label
property var source property var source
property string unit: "ms" property string unit: "ms"
property bool showGraphs: false
width: parent.width width: parent.width
property int dataPixelWidth: 150 property int dataPixelWidth: 150
@ -26,15 +28,20 @@ RowLayout {
text: value.label text: value.label
} }
Label { Label {
visible: !value.showGraphs
Layout.preferredWidth: 0 Layout.preferredWidth: 0
horizontalAlignment: Text.AlignRight horizontalAlignment: Text.AlignRight
text: value.source + ' ' + unit text: value.source + ' ' + unit
} }
Label { PlotPerf {
visible: value.showGraphs
Layout.fillWidth: true Layout.fillWidth: true
horizontalAlignment: Text.AlignRight height: 70
Layout.alignment: Qt.AlignRight
text: "Placeholder" valueUnit: value.unit
valueNumDigits: 0
plots: [{ binding: "source" }]
} }
} }

View file

@ -11,16 +11,17 @@
import QtQuick 2.5 import QtQuick 2.5
import QtQuick.Controls 1.4 import QtQuick.Controls 1.4
import QtQuick.Layouts 1.3 import QtQuick.Layouts 1.3
import "../lib/plotperf"
RowLayout { RowLayout {
id: value id: value
property string label property string label
property string label1 property string label1
property string label2 property string label2
property var source
property var source1 property var source1
property var source2 property var source2
property string unit: "ms" property string unit: "ms"
property bool showGraphs: false
property int labelPixelWidth: 50 property int labelPixelWidth: 50
property int dataPixelWidth: 100 property int dataPixelWidth: 100
@ -37,6 +38,7 @@ RowLayout {
text: value.label1 text: value.label1
} }
Label { Label {
visible: !value.showGraphs
Layout.preferredWidth: 0 Layout.preferredWidth: 0
horizontalAlignment: Text.AlignRight horizontalAlignment: Text.AlignRight
text: value.source1 + ' ' + unit text: value.source1 + ' ' + unit
@ -48,18 +50,22 @@ RowLayout {
text: value.label2 text: value.label2
} }
Label { Label {
visible: !value.showGraphs
Layout.preferredWidth: 0 Layout.preferredWidth: 0
horizontalAlignment: Text.AlignRight horizontalAlignment: Text.AlignRight
text: value.source2 + ' ' + unit text: value.source2 + ' ' + unit
} }
} }
} }
Label { PlotPerf {
visible: value.showGraphs
Layout.fillWidth: true Layout.fillWidth: true
horizontalAlignment: Text.AlignRight height: 70
Layout.alignment: Qt.AlignRight
text: "Placeholder" valueUnit: value.unit
valueNumDigits: 0
plots: [{ binding: "source1" }, { binding: "source2" }]
} }
} }

View file

@ -13,7 +13,9 @@ import QtQuick.Controls 1.4
import QtQuick.Layouts 1.3 import QtQuick.Layouts 1.3
ColumnLayout { ColumnLayout {
id: root
property var stream property var stream
property bool showGraphs: false
Label { Label {
Layout.alignment: Qt.AlignCenter Layout.alignment: Qt.AlignCenter
@ -24,10 +26,12 @@ ColumnLayout {
label: "Desired" label: "Desired"
source: stream.framesDesired source: stream.framesDesired
unit: "frames" unit: "frames"
showGraphs: root.showGraphs
} }
MovingValue { MovingValue {
label: "Unplayed" label: "Unplayed"
source: stream.unplayedMsMax source: stream.unplayedMsMax
showGraphs: root.showGraphs
} }
Value { Value {
label: "Available (avg)" label: "Available (avg)"
@ -44,6 +48,7 @@ ColumnLayout {
avg: stream.timegapMsAvg avg: stream.timegapMsAvg
maxWindow: stream.timegapMsMaxWindow maxWindow: stream.timegapMsMaxWindow
avgWindow: stream.timegapMsAvgWindow avgWindow: stream.timegapMsAvgWindow
showGraphs: root.showGraphs
} }
Label { Label {

View file

@ -17,7 +17,7 @@ var qml = Script.resolvePath('stats.qml');
var window = new OverlayWindow({ var window = new OverlayWindow({
title: 'Audio Interface Statistics', title: 'Audio Interface Statistics',
source: qml, source: qml,
width: 400, height: 720 // stats.qml may be too large for some screens width: 800, height: 720 // stats.qml may be too large for some screens
}); });
window.setPosition(INITIAL_OFFSET, INITIAL_OFFSET); window.setPosition(INITIAL_OFFSET, INITIAL_OFFSET);

View file

@ -13,52 +13,85 @@ import QtQuick.Controls 1.4
import QtQuick.Layouts 1.3 import QtQuick.Layouts 1.3
Column { Column {
id: stats
width: parent.width width: parent.width
height: parent.height height: parent.height
property bool showGraphs: toggleGraphs.checked
Section { RowLayout {
label: "Latency" width: parent.width
description: "Audio pipeline latency, broken out and summed" height: 30
control: ColumnLayout {
MovingValue { label: "Input Read"; source: AudioStats.inputReadMsMax } Button {
MovingValue { label: "Input Ring"; source: AudioStats.inputUnplayedMsMax } id: toggleGraphs
MovingValue { label: "Network (client->mixer)"; source: AudioStats.pingMs / 2 } property bool checked: false
MovingValue { label: "Mixer Ring"; source: AudioStats.mixerStream.unplayedMsMax }
MovingValue { label: "Network (mixer->client)"; source: AudioStats.pingMs / 2 } Layout.alignment: Qt.AlignCenter
MovingValue { label: "Output Ring"; source: AudioStats.clientStream.unplayedMsMax }
MovingValue { label: "Output Read"; source: AudioStats.outputUnplayedMsMax } text: checked ? "Hide graphs" : "Show graphs"
MovingValue { label: "TOTAL" onClicked: function() { checked = !checked; }
source: AudioStats.inputReadMsMax + }
AudioStats.inputUnplayedMsMax + }
AudioStats.outputUnplayedMsMax +
AudioStats.mixerStream.unplayedMsMax + Grid {
AudioStats.clientStream.unplayedMsMax + width: parent.width
AudioStats.pingMs height: parent.height - 30
Column {
width: parent.width / 2
height: parent.height
Section {
label: "Latency"
description: "Audio pipeline latency, broken out and summed"
control: ColumnLayout {
MovingValue { label: "Input Read"; source: AudioStats.inputReadMsMax; showGraphs: stats.showGraphs }
MovingValue { label: "Input Ring"; source: AudioStats.inputUnplayedMsMax; showGraphs: stats.showGraphs }
MovingValue { label: "Network (client->mixer)"; source: AudioStats.pingMs / 2; showGraphs: stats.showGraphs }
MovingValue { label: "Mixer Ring"; source: AudioStats.mixerStream.unplayedMsMax; showGraphs: stats.showGraphs }
MovingValue { label: "Network (mixer->client)"; source: AudioStats.pingMs / 2; showGraphs: stats.showGraphs }
MovingValue { label: "Output Ring"; source: AudioStats.clientStream.unplayedMsMax; showGraphs: stats.showGraphs }
MovingValue { label: "Output Read"; source: AudioStats.outputUnplayedMsMax; showGraphs: stats.showGraphs }
MovingValue { label: "TOTAL"; showGraphs: stats.showGraphs
source: AudioStats.inputReadMsMax +
AudioStats.inputUnplayedMsMax +
AudioStats.outputUnplayedMsMax +
AudioStats.mixerStream.unplayedMsMax +
AudioStats.clientStream.unplayedMsMax +
AudioStats.pingMs
}
}
}
Section {
label: "Upstream Jitter"
description: "Timegaps in packets sent to the mixer"
control: Jitter {
max: AudioStats.sentTimegapMsMax
avg: AudioStats.sentTimegapMsAvg
maxWindow: AudioStats.sentTimegapMsMaxWindow
avgWindow: AudioStats.sentTimegapMsAvgWindow
showGraphs: stats.showGraphs
}
}
}
Column {
width: parent.width / 2
height: parent.height
Section {
label: "Mixer (upstream)"
description: "This client's remote audio stream, as seen by the server's mixer"
control: Stream { stream: AudioStats.mixerStream; showGraphs: stats.showGraphs }
}
Section {
label: "Client (downstream)"
description: "This client's received audio stream, between the network and the OS"
control: Stream { stream: AudioStats.clientStream; showGraphs: stats.showGraphs }
} }
} }
} }
Section {
label: "Upstream Jitter"
description: "Timegaps in packets sent to the mixer"
control: Jitter {
max: AudioStats.sentTimegapMsMax
avg: AudioStats.sentTimegapMsAvg
maxWindow: AudioStats.sentTimegapMsMaxWindow
avgWindow: AudioStats.sentTimegapMsAvgWindow
}
}
Section {
label: "Mixer (upstream)"
description: "This client's remote audio stream, as seen by the server's mixer"
control: Stream { stream: AudioStats.mixerStream }
}
Section {
label: "Client (downstream)"
description: "This client's received audio stream, between the network and the OS"
control: Stream { stream: AudioStats.clientStream }
}
} }

View file

@ -55,9 +55,17 @@ Item {
function createValues() { function createValues() {
for (var i =0; i < plots.length; i++) { for (var i =0; i < plots.length; i++) {
var plot = plots[i]; var plot = plots[i];
var object = plot["object"] || root.object;
var value = plot["prop"];
var isBinding = plot["binding"];
if (isBinding) {
object = root.parent;
value = isBinding;
}
_values.push( { _values.push( {
object: (plot["object"] !== undefined ? plot["object"] : root.object), object: object,
value: plot["prop"], value: value,
fromBinding: isBinding,
valueMax: 1, valueMax: 1,
numSamplesConstantMax: 0, numSamplesConstantMax: 0,
valueHistory: new Array(), valueHistory: new Array(),
@ -218,7 +226,6 @@ Item {
anchors.rightMargin: -hitboxExtension anchors.rightMargin: -hitboxExtension
onClicked: { onClicked: {
print("PerfPlot clicked!")
resetMax(); resetMax();
} }
} }