remake audio stats in qml

This commit is contained in:
Zach Pomerantz 2016-09-26 15:35:45 -07:00
parent b9c4018b8e
commit e6c0baa1ff
8 changed files with 382 additions and 0 deletions

View file

@ -0,0 +1,36 @@
//
// Jitter.qml
// scripts/developer/utilities/audio
//
// Created by Zach Pomerantz on 9/22/2016
// Copyright 2016 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or https://www.apache.org/licenses/LICENSE-2.0.html
//
import QtQuick 2.5
import QtQuick.Controls 1.4
import QtQuick.Layouts 1.3
ColumnLayout {
property var max
property var avg
property var maxWindow
property var avgWindow
MovingValuePair {
label: "Total"
label1: "Average"
label2: "Maximum"
source1: avg
source2: max
}
MovingValuePair {
label: "Window"
label1: "Average"
label2: "Maximum"
source1: avgWindow
source2: maxWindow
}
}

View file

@ -0,0 +1,40 @@
//
// MovingValue.qml
// scripts/developer/utilities/audio
//
// Created by Zach Pomerantz on 9/22/2016
// Copyright 2016 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or https://www.apache.org/licenses/LICENSE-2.0.html
//
import QtQuick 2.5
import QtQuick.Controls 1.4
import QtQuick.Layouts 1.3
RowLayout {
id: value
property string label
property var source
property string unit: "ms"
width: parent.width
property int dataPixelWidth: 150
Label {
Layout.preferredWidth: dataPixelWidth
text: value.label
}
Label {
Layout.preferredWidth: 0
horizontalAlignment: Text.AlignRight
text: value.source + ' ' + unit
}
Label {
Layout.fillWidth: true
horizontalAlignment: Text.AlignRight
Layout.alignment: Qt.AlignRight
text: "Placeholder"
}
}

View file

@ -0,0 +1,65 @@
//
// MovingValuePair.qml
// scripts/developer/utilities/audio
//
// Created by Zach Pomerantz on 9/22/2016
// Copyright 2016 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or https://www.apache.org/licenses/LICENSE-2.0.html
//
import QtQuick 2.5
import QtQuick.Controls 1.4
import QtQuick.Layouts 1.3
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 int labelPixelWidth: 50
property int dataPixelWidth: 100
Label {
Layout.preferredWidth: labelPixelWidth - value.spacing
text: value.label
}
ColumnLayout {
RowLayout {
Label {
Layout.preferredWidth: dataPixelWidth
text: value.label1
}
Label {
Layout.preferredWidth: 0
horizontalAlignment: Text.AlignRight
text: value.source1 + ' ' + unit
}
}
RowLayout {
Label {
Layout.preferredWidth: dataPixelWidth
text: value.label2
}
Label {
Layout.preferredWidth: 0
horizontalAlignment: Text.AlignRight
text: value.source2 + ' ' + unit
}
}
}
Label {
Layout.fillWidth: true
horizontalAlignment: Text.AlignRight
Layout.alignment: Qt.AlignRight
text: "Placeholder"
}
}

View file

@ -0,0 +1,56 @@
//
// Section.qml
// scripts/developer/utilities/audio
//
// Created by Zach Pomerantz on 9/22/2016
// Copyright 2016 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or https://www.apache.org/licenses/LICENSE-2.0.html
//
import QtQuick 2.5
import QtQuick.Controls 1.4
import QtQuick.Layouts 1.3
Rectangle {
id: section
property string label: "Section"
property string description: "Description"
property alias control : loader.sourceComponent
width: parent.width
height: content.height + border.width * 2 + content.spacing * 2
border.color: "black"
border.width: 5
radius: border.width * 2
ColumnLayout {
id: content
x: section.radius; y: section.radius
spacing: section.border.width
width: section.width - 2 * x
// label
Label {
Layout.alignment: Qt.AlignCenter
text: hoverArea.containsMouse ? section.description : section.label
font.bold: true
MouseArea {
id: hoverArea
anchors.fill: parent
hoverEnabled: true
}
}
// spacer
Item { }
// control
Loader {
id: loader
Layout.preferredWidth: parent.width
}
}
}

View file

@ -0,0 +1,63 @@
//
// Stream.qml
// scripts/developer/utilities/audio
//
// Created by Zach Pomerantz on 9/22/2016
// Copyright 2016 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or https://www.apache.org/licenses/LICENSE-2.0.html
//
import QtQuick 2.5
import QtQuick.Controls 1.4
import QtQuick.Layouts 1.3
ColumnLayout {
property var stream
Label {
Layout.alignment: Qt.AlignCenter
text: "Ring Buffer"
font.italic: true
}
MovingValue {
label: "Desired"
source: stream.framesDesired
unit: "frames"
}
MovingValue {
label: "Unplayed"
source: stream.unplayedMsMax
}
Value {
label: "Available (avg)"
source: stream.framesAvailable + " (" + stream.framesAvailableAvg + ") frames"
}
Label {
Layout.alignment: Qt.AlignCenter
text: "Jitter"
font.italic: true
}
Jitter {
max: stream.timegapMsMax
avg: stream.timegapMsAvg
maxWindow: stream.timegapMsMaxWindow
avgWindow: stream.timegapMsAvgWindow
}
Label {
Layout.alignment: Qt.AlignCenter
text: "Packet Loss"
font.italic: true
}
Value {
label: "Overall"
source: stream.lossRate + "% (" + stream.lossCount + " lost)"
}
Value {
label: "Window"
source: stream.lossRateWindow + "% (" + stream.lossCountWindow + " lost)"
}
}

View file

@ -0,0 +1,33 @@
//
// Value.qml
// scripts/developer/utilities/audio
//
// Created by Zach Pomerantz on 9/22/2016
// Copyright 2016 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or https://www.apache.org/licenses/LICENSE-2.0.html
//
import QtQuick 2.5
import QtQuick.Controls 1.4
import QtQuick.Layouts 1.3
RowLayout {
id: value
property string label
property var source
width: parent.width
property int dataPixelWidth: 150
Label {
Layout.preferredWidth: dataPixelWidth
text: value.label
}
Label {
Layout.preferredWidth: 0
horizontalAlignment: Text.AlignRight
text: value.source
}
}

View file

@ -0,0 +1,25 @@
//
// stats.js
// scripts/developer/utilities/audio
//
// Zach Pomerantz, created on 9/22/2016.
// Copyright 2016 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
var INITIAL_WIDTH = 400;
var INITIAL_OFFSET = 50;
// Set up the qml ui
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
});
window.setPosition(INITIAL_OFFSET, INITIAL_OFFSET);
window.closed.connect(function() { Script.stop(); });

View file

@ -0,0 +1,64 @@
//
// stats.qml
// scripts/developer/utilities/audio
//
// Created by Zach Pomerantz on 9/22/2016
// Copyright 2016 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or https://www.apache.org/licenses/LICENSE-2.0.html
//
import QtQuick 2.5
import QtQuick.Controls 1.4
import QtQuick.Layouts 1.3
Column {
width: parent.width
height: parent.height
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
}
}
}
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 }
}
}