mirror of
https://github.com/overte-org/overte.git
synced 2025-08-10 20:33:09 +02:00
add graphs to audio stats
This commit is contained in:
parent
f5e1d4dd2b
commit
6035374004
7 changed files with 126 additions and 64 deletions
|
@ -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
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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" }]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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" }]
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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 }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue