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
ColumnLayout {
id: jitter
property var max
property var avg
property var maxWindow
property var avgWindow
property bool showGraphs: false
MovingValuePair {
label: "Total"
label1: "Average"
label2: "Maximum"
source1: avg
source2: max
label1: "Maximum"
label2: "Average"
source1: max
source2: avg
showGraphs: jitter.showGraphs
}
MovingValuePair {
label: "Window"
label1: "Average"
label2: "Maximum"
source1: avgWindow
source2: maxWindow
label1: "Maximum"
label2: "Average"
source1: maxWindow
source2: avgWindow
showGraphs: jitter.showGraphs
}
}

View file

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

View file

@ -11,16 +11,17 @@
import QtQuick 2.5
import QtQuick.Controls 1.4
import QtQuick.Layouts 1.3
import "../lib/plotperf"
RowLayout {
id: value
property string label
property string label1
property string label2
property var source
property var source1
property var source2
property string unit: "ms"
property bool showGraphs: false
property int labelPixelWidth: 50
property int dataPixelWidth: 100
@ -37,6 +38,7 @@ RowLayout {
text: value.label1
}
Label {
visible: !value.showGraphs
Layout.preferredWidth: 0
horizontalAlignment: Text.AlignRight
text: value.source1 + ' ' + unit
@ -48,18 +50,22 @@ RowLayout {
text: value.label2
}
Label {
visible: !value.showGraphs
Layout.preferredWidth: 0
horizontalAlignment: Text.AlignRight
text: value.source2 + ' ' + unit
}
}
}
Label {
PlotPerf {
visible: value.showGraphs
Layout.fillWidth: true
horizontalAlignment: Text.AlignRight
Layout.alignment: Qt.AlignRight
text: "Placeholder"
height: 70
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
ColumnLayout {
id: root
property var stream
property bool showGraphs: false
Label {
Layout.alignment: Qt.AlignCenter
@ -24,10 +26,12 @@ ColumnLayout {
label: "Desired"
source: stream.framesDesired
unit: "frames"
showGraphs: root.showGraphs
}
MovingValue {
label: "Unplayed"
source: stream.unplayedMsMax
showGraphs: root.showGraphs
}
Value {
label: "Available (avg)"
@ -44,6 +48,7 @@ ColumnLayout {
avg: stream.timegapMsAvg
maxWindow: stream.timegapMsMaxWindow
avgWindow: stream.timegapMsAvgWindow
showGraphs: root.showGraphs
}
Label {

View file

@ -17,7 +17,7 @@ var qml = Script.resolvePath('stats.qml');
var window = new OverlayWindow({
title: 'Audio Interface Statistics',
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);

View file

@ -13,52 +13,85 @@ import QtQuick.Controls 1.4
import QtQuick.Layouts 1.3
Column {
id: stats
width: parent.width
height: parent.height
property bool showGraphs: toggleGraphs.checked
Section {
label: "Latency"
description: "Audio pipeline latency, broken out and summed"
control: ColumnLayout {
MovingValue { label: "Input Read"; source: AudioStats.inputReadMsMax }
MovingValue { label: "Input Ring"; source: AudioStats.inputUnplayedMsMax }
MovingValue { label: "Network (client->mixer)"; source: AudioStats.pingMs / 2 }
MovingValue { label: "Mixer Ring"; source: AudioStats.mixerStream.unplayedMsMax }
MovingValue { label: "Network (mixer->client)"; source: AudioStats.pingMs / 2 }
MovingValue { label: "Output Ring"; source: AudioStats.clientStream.unplayedMsMax }
MovingValue { label: "Output Read"; source: AudioStats.outputUnplayedMsMax }
MovingValue { label: "TOTAL"
source: AudioStats.inputReadMsMax +
AudioStats.inputUnplayedMsMax +
AudioStats.outputUnplayedMsMax +
AudioStats.mixerStream.unplayedMsMax +
AudioStats.clientStream.unplayedMsMax +
AudioStats.pingMs
RowLayout {
width: parent.width
height: 30
Button {
id: toggleGraphs
property bool checked: false
Layout.alignment: Qt.AlignCenter
text: checked ? "Hide graphs" : "Show graphs"
onClicked: function() { checked = !checked; }
}
}
Grid {
width: parent.width
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() {
for (var i =0; i < plots.length; 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( {
object: (plot["object"] !== undefined ? plot["object"] : root.object),
value: plot["prop"],
object: object,
value: value,
fromBinding: isBinding,
valueMax: 1,
numSamplesConstantMax: 0,
valueHistory: new Array(),
@ -218,7 +226,6 @@ Item {
anchors.rightMargin: -hitboxExtension
onClicked: {
print("PerfPlot clicked!")
resetMax();
}
}