mirror of
https://github.com/overte-org/overte.git
synced 2025-08-09 22:51:20 +02:00
remake audio stats in qml
This commit is contained in:
parent
b9c4018b8e
commit
e6c0baa1ff
8 changed files with 382 additions and 0 deletions
36
scripts/developer/utilities/audio/Jitter.qml
Normal file
36
scripts/developer/utilities/audio/Jitter.qml
Normal 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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
40
scripts/developer/utilities/audio/MovingValue.qml
Normal file
40
scripts/developer/utilities/audio/MovingValue.qml
Normal 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"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
65
scripts/developer/utilities/audio/MovingValuePair.qml
Normal file
65
scripts/developer/utilities/audio/MovingValuePair.qml
Normal 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"
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
56
scripts/developer/utilities/audio/Section.qml
Normal file
56
scripts/developer/utilities/audio/Section.qml
Normal 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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
63
scripts/developer/utilities/audio/Stream.qml
Normal file
63
scripts/developer/utilities/audio/Stream.qml
Normal 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)"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
33
scripts/developer/utilities/audio/Value.qml
Normal file
33
scripts/developer/utilities/audio/Value.qml
Normal 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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
25
scripts/developer/utilities/audio/stats.js
Normal file
25
scripts/developer/utilities/audio/stats.js
Normal 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(); });
|
||||||
|
|
64
scripts/developer/utilities/audio/stats.qml
Normal file
64
scripts/developer/utilities/audio/stats.qml
Normal 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 }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue