Unified · Split
| @@ -13,24 +13,28 @@ import QtQuick.Controls 1.4 · 12 unmodified lines | ||
| 13 | 13 | import QtQuick.Layouts 1.3 |
| 14 | 14 | |
| 15 | 15 | ColumnLayout { |
| 16 | + id: jitter | |
| 16 | 17 | property var max |
| 17 | 18 | property var avg |
| 18 | 19 | property var maxWindow |
| 19 | 20 | property var avgWindow |
| 21 | + property bool showGraphs: false | |
| 20 | 22 | |
| 21 | 23 | MovingValuePair { |
| 22 | 24 | label: "Total" |
| 23 | − label1: "Average" | |
| 24 | − label2: "Maximum" | |
| 25 | − source1: avg | |
| 26 | − source2: max | |
| 25 | + label1: "Maximum" | |
| 26 | + label2: "Average" | |
| 27 | + source1: max | |
| 28 | + source2: avg | |
| 29 | + showGraphs: jitter.showGraphs | |
| 27 | 30 | } |
| 28 | 31 | MovingValuePair { |
| 29 | 32 | label: "Window" |
| 30 | − label1: "Average" | |
| 31 | − label2: "Maximum" | |
| 32 | − source1: avgWindow | |
| 33 | − source2: maxWindow | |
| 33 | + label1: "Maximum" | |
| 34 | + label2: "Average" | |
| 35 | + source1: maxWindow | |
| 36 | + source2: avgWindow | |
| 37 | + showGraphs: jitter.showGraphs | |
| 34 | 38 | } |
| 35 | 39 | } |
| 36 | 40 | |
| @@ -11,12 +11,14 @@ · 10 unmodified lines | ||
| 11 | 11 | import QtQuick 2.5 |
| 12 | 12 | import QtQuick.Controls 1.4 |
| 13 | 13 | import QtQuick.Layouts 1.3 |
| 14 | +import "../lib/plotperf" | |
| 14 | 15 | |
| 15 | 16 | RowLayout { |
| 16 | 17 | id: value |
| 17 | 18 | property string label |
| 18 | 19 | property var source |
| 19 | 20 | property string unit: "ms" |
| 21 | + property bool showGraphs: false | |
| 20 | 22 | |
| 21 | 23 | width: parent.width |
| 22 | 24 | property int dataPixelWidth: 150 |
| @@ -26,15 +28,20 @@ RowLayout { · 3 unmodified lines | ||
| 26 | 28 | text: value.label |
| 27 | 29 | } |
| 28 | 30 | Label { |
| 31 | + visible: !value.showGraphs | |
| 29 | 32 | Layout.preferredWidth: 0 |
| 30 | 33 | horizontalAlignment: Text.AlignRight |
| 31 | 34 | text: value.source + ' ' + unit |
| 32 | 35 | } |
| 33 | − Label { | |
| 36 | + PlotPerf { | |
| 37 | + visible: value.showGraphs | |
| 34 | 38 | Layout.fillWidth: true |
| 35 | − horizontalAlignment: Text.AlignRight | |
| 36 | − Layout.alignment: Qt.AlignRight | |
| 37 | − text: "Placeholder" | |
| 39 | + height: 70 | |
| 40 | + | |
| 41 | + valueUnit: value.unit | |
| 42 | + valueNumDigits: 0 | |
| 43 | + | |
| 44 | + plots: [{ binding: "source" }] | |
| 38 | 45 | } |
| 39 | 46 | } |
| 40 | 47 | |
| @@ -11,16 +11,17 @@ · 10 unmodified lines | ||
| 11 | 11 | import QtQuick 2.5 |
| 12 | 12 | import QtQuick.Controls 1.4 |
| 13 | 13 | import QtQuick.Layouts 1.3 |
| 14 | +import "../lib/plotperf" | |
| 14 | 15 | |
| 15 | 16 | RowLayout { |
| 16 | 17 | id: value |
| 17 | 18 | property string label |
| 18 | 19 | property string label1 |
| 19 | 20 | property string label2 |
| 20 | − property var source | |
| 21 | 21 | property var source1 |
| 22 | 22 | property var source2 |
| 23 | 23 | property string unit: "ms" |
| 24 | + property bool showGraphs: false | |
| 24 | 25 | |
| 25 | 26 | property int labelPixelWidth: 50 |
| 26 | 27 | property int dataPixelWidth: 100 |
| @@ -37,6 +38,7 @@ RowLayout { · 10 unmodified lines | ||
| 37 | 38 | text: value.label1 |
| 38 | 39 | } |
| 39 | 40 | Label { |
| 41 | + visible: !value.showGraphs | |
| 40 | 42 | Layout.preferredWidth: 0 |
| 41 | 43 | horizontalAlignment: Text.AlignRight |
| 42 | 44 | text: value.source1 + ' ' + unit |
| @@ -48,18 +50,22 @@ RowLayout { · 5 unmodified lines | ||
| 48 | 50 | text: value.label2 |
| 49 | 51 | } |
| 50 | 52 | Label { |
| 53 | + visible: !value.showGraphs | |
| 51 | 54 | Layout.preferredWidth: 0 |
| 52 | 55 | horizontalAlignment: Text.AlignRight |
| 53 | 56 | text: value.source2 + ' ' + unit |
| 54 | 57 | } |
| 55 | 58 | } |
| 56 | 59 | } |
| 57 | − Label { | |
| 60 | + PlotPerf { | |
| 61 | + visible: value.showGraphs | |
| 62 | + | |
| 58 | 63 | Layout.fillWidth: true |
| 59 | − horizontalAlignment: Text.AlignRight | |
| 60 | − Layout.alignment: Qt.AlignRight | |
| 61 | − text: "Placeholder" | |
| 62 | − } | |
| 64 | + height: 70 | |
| 63 | 65 | |
| 64 | −} | |
| 66 | + valueUnit: value.unit | |
| 67 | + valueNumDigits: 0 | |
| 65 | 68 | |
| 69 | + plots: [{ binding: "source1" }, { binding: "source2" }] | |
| 70 | + } | |
| 71 | +} | |
| @@ -13,7 +13,9 @@ import QtQuick.Controls 1.4 · 12 unmodified lines | ||
| 13 | 13 | import QtQuick.Layouts 1.3 |
| 14 | 14 | |
| 15 | 15 | ColumnLayout { |
| 16 | + id: root | |
| 16 | 17 | property var stream |
| 18 | + property bool showGraphs: false | |
| 17 | 19 | |
| 18 | 20 | Label { |
| 19 | 21 | Layout.alignment: Qt.AlignCenter |
| @@ -24,10 +26,12 @@ ColumnLayout { · 4 unmodified lines | ||
| 24 | 26 | label: "Desired" |
| 25 | 27 | source: stream.framesDesired |
| 26 | 28 | unit: "frames" |
| 29 | + showGraphs: root.showGraphs | |
| 27 | 30 | } |
| 28 | 31 | MovingValue { |
| 29 | 32 | label: "Unplayed" |
| 30 | 33 | source: stream.unplayedMsMax |
| 34 | + showGraphs: root.showGraphs | |
| 31 | 35 | } |
| 32 | 36 | Value { |
| 33 | 37 | label: "Available (avg)" |
| @@ -44,6 +48,7 @@ ColumnLayout { · 10 unmodified lines | ||
| 44 | 48 | avg: stream.timegapMsAvg |
| 45 | 49 | maxWindow: stream.timegapMsMaxWindow |
| 46 | 50 | avgWindow: stream.timegapMsAvgWindow |
| 51 | + showGraphs: root.showGraphs | |
| 47 | 52 | } |
| 48 | 53 | |
| 49 | 54 | Label { |
| @@ -17,7 +17,7 @@ var qml = Script.resolvePath('stats.qml'); · 16 unmodified lines | ||
| 17 | 17 | var window = new OverlayWindow({ |
| 18 | 18 | title: 'Audio Interface Statistics', |
| 19 | 19 | source: qml, |
| 20 | − width: 400, height: 720 // stats.qml may be too large for some screens | |
| 20 | + width: 800, height: 720 // stats.qml may be too large for some screens | |
| 21 | 21 | }); |
| 22 | 22 | window.setPosition(INITIAL_OFFSET, INITIAL_OFFSET); |
| 23 | 23 | |
| @@ -13,52 +13,85 @@ import QtQuick.Controls 1.4 · 12 unmodified lines | ||
| 13 | 13 | import QtQuick.Layouts 1.3 |
| 14 | 14 | |
| 15 | 15 | Column { |
| 16 | + id: stats | |
| 16 | 17 | width: parent.width |
| 17 | 18 | height: parent.height |
| 19 | + property bool showGraphs: toggleGraphs.checked | |
| 18 | 20 | |
| 19 | − Section { | |
| 20 | − label: "Latency" | |
| 21 | − description: "Audio pipeline latency, broken out and summed" | |
| 22 | − control: ColumnLayout { | |
| 23 | − MovingValue { label: "Input Read"; source: AudioStats.inputReadMsMax } | |
| 24 | − MovingValue { label: "Input Ring"; source: AudioStats.inputUnplayedMsMax } | |
| 25 | − MovingValue { label: "Network (client->mixer)"; source: AudioStats.pingMs / 2 } | |
| 26 | − MovingValue { label: "Mixer Ring"; source: AudioStats.mixerStream.unplayedMsMax } | |
| 27 | − MovingValue { label: "Network (mixer->client)"; source: AudioStats.pingMs / 2 } | |
| 28 | − MovingValue { label: "Output Ring"; source: AudioStats.clientStream.unplayedMsMax } | |
| 29 | − MovingValue { label: "Output Read"; source: AudioStats.outputUnplayedMsMax } | |
| 30 | − MovingValue { label: "TOTAL" | |
| 31 | − source: AudioStats.inputReadMsMax + | |
| 32 | − AudioStats.inputUnplayedMsMax + | |
| 33 | − AudioStats.outputUnplayedMsMax + | |
| 34 | − AudioStats.mixerStream.unplayedMsMax + | |
| 35 | − AudioStats.clientStream.unplayedMsMax + | |
| 36 | − AudioStats.pingMs | |
| 37 | − } | |
| 21 | + RowLayout { | |
| 22 | + width: parent.width | |
| 23 | + height: 30 | |
| 24 | + | |
| 25 | + Button { | |
| 26 | + id: toggleGraphs | |
| 27 | + property bool checked: false | |
| 28 | + | |
| 29 | + Layout.alignment: Qt.AlignCenter | |
| 30 | + | |
| 31 | + text: checked ? "Hide graphs" : "Show graphs" | |
| 32 | + onClicked: function() { checked = !checked; } | |
| 38 | 33 | } |
| 39 | 34 | } |
| 40 | 35 | |
| 41 | − Section { | |
| 42 | − label: "Upstream Jitter" | |
| 43 | − description: "Timegaps in packets sent to the mixer" | |
| 44 | − control: Jitter { | |
| 45 | − max: AudioStats.sentTimegapMsMax | |
| 46 | − avg: AudioStats.sentTimegapMsAvg | |
| 47 | − maxWindow: AudioStats.sentTimegapMsMaxWindow | |
| 48 | − avgWindow: AudioStats.sentTimegapMsAvgWindow | |
| 36 | + Grid { | |
| 37 | + width: parent.width | |
| 38 | + height: parent.height - 30 | |
| 39 | + | |
| 40 | + Column { | |
| 41 | + width: parent.width / 2 | |
| 42 | + height: parent.height | |
| 43 | + | |
| 44 | + Section { | |
| 45 | + label: "Latency" | |
| 46 | + description: "Audio pipeline latency, broken out and summed" | |
| 47 | + control: ColumnLayout { | |
| 48 | + MovingValue { label: "Input Read"; source: AudioStats.inputReadMsMax; showGraphs: stats.showGraphs } | |
| 49 | + MovingValue { label: "Input Ring"; source: AudioStats.inputUnplayedMsMax; showGraphs: stats.showGraphs } | |
| 50 | + MovingValue { label: "Network (client->mixer)"; source: AudioStats.pingMs / 2; showGraphs: stats.showGraphs } | |
| 51 | + MovingValue { label: "Mixer Ring"; source: AudioStats.mixerStream.unplayedMsMax; showGraphs: stats.showGraphs } | |
| 52 | + MovingValue { label: "Network (mixer->client)"; source: AudioStats.pingMs / 2; showGraphs: stats.showGraphs } | |
| 53 | + MovingValue { label: "Output Ring"; source: AudioStats.clientStream.unplayedMsMax; showGraphs: stats.showGraphs } | |
| 54 | + MovingValue { label: "Output Read"; source: AudioStats.outputUnplayedMsMax; showGraphs: stats.showGraphs } | |
| 55 | + MovingValue { label: "TOTAL"; showGraphs: stats.showGraphs | |
| 56 | + source: AudioStats.inputReadMsMax + | |
| 57 | + AudioStats.inputUnplayedMsMax + | |
| 58 | + AudioStats.outputUnplayedMsMax + | |
| 59 | + AudioStats.mixerStream.unplayedMsMax + | |
| 60 | + AudioStats.clientStream.unplayedMsMax + | |
| 61 | + AudioStats.pingMs | |
| 62 | + } | |
| 63 | + } | |
| 64 | + } | |
| 65 | + | |
| 66 | + Section { | |
| 67 | + label: "Upstream Jitter" | |
| 68 | + description: "Timegaps in packets sent to the mixer" | |
| 69 | + control: Jitter { | |
| 70 | + max: AudioStats.sentTimegapMsMax | |
| 71 | + avg: AudioStats.sentTimegapMsAvg | |
| 72 | + maxWindow: AudioStats.sentTimegapMsMaxWindow | |
| 73 | + avgWindow: AudioStats.sentTimegapMsAvgWindow | |
| 74 | + showGraphs: stats.showGraphs | |
| 75 | + } | |
| 76 | + } | |
| 49 | 77 | } |
| 50 | − } | |
| 51 | 78 | |
| 52 | − Section { | |
| 53 | − label: "Mixer (upstream)" | |
| 54 | − description: "This client's remote audio stream, as seen by the server's mixer" | |
| 55 | − control: Stream { stream: AudioStats.mixerStream } | |
| 56 | − } | |
| 79 | + Column { | |
| 80 | + width: parent.width / 2 | |
| 81 | + height: parent.height | |
| 57 | 82 | |
| 58 | − Section { | |
| 59 | − label: "Client (downstream)" | |
| 60 | − description: "This client's received audio stream, between the network and the OS" | |
| 61 | − control: Stream { stream: AudioStats.clientStream } | |
| 83 | + Section { | |
| 84 | + label: "Mixer (upstream)" | |
| 85 | + description: "This client's remote audio stream, as seen by the server's mixer" | |
| 86 | + control: Stream { stream: AudioStats.mixerStream; showGraphs: stats.showGraphs } | |
| 87 | + } | |
| 88 | + | |
| 89 | + Section { | |
| 90 | + label: "Client (downstream)" | |
| 91 | + description: "This client's received audio stream, between the network and the OS" | |
| 92 | + control: Stream { stream: AudioStats.clientStream; showGraphs: stats.showGraphs } | |
| 93 | + } | |
| 94 | + } | |
| 62 | 95 | } |
| 63 | 96 | } |
| 64 | 97 | |
| @@ -55,9 +55,17 @@ Item { · 54 unmodified lines | ||
| 55 | 55 | function createValues() { |
| 56 | 56 | for (var i =0; i < plots.length; i++) { |
| 57 | 57 | var plot = plots[i]; |
| 58 | + var object = plot["object"] || root.object; | |
| 59 | + var value = plot["prop"]; | |
| 60 | + var isBinding = plot["binding"]; | |
| 61 | + if (isBinding) { | |
| 62 | + object = root.parent; | |
| 63 | + value = isBinding; | |
| 64 | + } | |
| 58 | 65 | _values.push( { |
| 59 | − object: (plot["object"] !== undefined ? plot["object"] : root.object), | |
| 60 | − value: plot["prop"], | |
| 66 | + object: object, | |
| 67 | + value: value, | |
| 68 | + fromBinding: isBinding, | |
| 61 | 69 | valueMax: 1, |
| 62 | 70 | numSamplesConstantMax: 0, |
| 63 | 71 | valueHistory: new Array(), |
| @@ -218,7 +226,6 @@ Item { · 154 unmodified lines | ||
| 218 | 226 | anchors.rightMargin: -hitboxExtension |
| 219 | 227 | |
| 220 | 228 | onClicked: { |
| 221 | − print("PerfPlot clicked!") | |
| 222 | 229 | resetMax(); |
| 223 | 230 | } |
| 224 | 231 | } |