mirror of
https://github.com/overte-org/overte.git
synced 2025-08-09 13:09:52 +02:00
Merge pull request #11182 from vladest/audio_devices_split
Audio devices split
This commit is contained in:
commit
4f328524b1
11 changed files with 484 additions and 143 deletions
113
interface/resources/qml/controls-uit/CheckBoxQQC2.qml
Normal file
113
interface/resources/qml/controls-uit/CheckBoxQQC2.qml
Normal file
|
@ -0,0 +1,113 @@
|
||||||
|
//
|
||||||
|
// CheckBox2.qml
|
||||||
|
//
|
||||||
|
// Created by Vlad Stelmahovsky on 10 Aug 2017
|
||||||
|
// Copyright 2017 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
|
||||||
|
//
|
||||||
|
|
||||||
|
import QtQuick 2.7
|
||||||
|
import QtQuick.Controls 2.2
|
||||||
|
|
||||||
|
import "../styles-uit"
|
||||||
|
import "../controls-uit" as HiFiControls
|
||||||
|
|
||||||
|
CheckBox {
|
||||||
|
id: checkBox
|
||||||
|
|
||||||
|
HifiConstants { id: hifi; }
|
||||||
|
|
||||||
|
padding: 0
|
||||||
|
leftPadding: 0
|
||||||
|
property int colorScheme: hifi.colorSchemes.light
|
||||||
|
property string color: hifi.colors.lightGrayText
|
||||||
|
readonly property bool isLightColorScheme: colorScheme === hifi.colorSchemes.light
|
||||||
|
property bool isRedCheck: false
|
||||||
|
property bool isRound: false
|
||||||
|
property int boxSize: 14
|
||||||
|
property int boxRadius: isRound ? boxSize : 3
|
||||||
|
property bool wrap: true;
|
||||||
|
readonly property int checkSize: Math.max(boxSize - 8, 10)
|
||||||
|
readonly property int checkRadius: isRound ? checkSize / 2 : 2
|
||||||
|
focusPolicy: Qt.ClickFocus
|
||||||
|
|
||||||
|
indicator: Rectangle {
|
||||||
|
id: box
|
||||||
|
implicitWidth: boxSize
|
||||||
|
implicitHeight: boxSize
|
||||||
|
radius: boxRadius
|
||||||
|
x: checkBox.leftPadding
|
||||||
|
y: parent.height / 2 - height / 2
|
||||||
|
border.width: 1
|
||||||
|
border.color: pressed || hovered
|
||||||
|
? hifi.colors.checkboxCheckedBorder
|
||||||
|
: (checkBox.isLightColorScheme ? hifi.colors.checkboxLightFinish : hifi.colors.checkboxDarkFinish)
|
||||||
|
|
||||||
|
gradient: Gradient {
|
||||||
|
GradientStop {
|
||||||
|
position: 0.2
|
||||||
|
color: pressed || hovered
|
||||||
|
? (checkBox.isLightColorScheme ? hifi.colors.checkboxChecked : hifi.colors.checkboxLightStart)
|
||||||
|
: (checkBox.isLightColorScheme ? hifi.colors.checkboxLightStart : hifi.colors.checkboxDarkStart)
|
||||||
|
}
|
||||||
|
GradientStop {
|
||||||
|
position: 1.0
|
||||||
|
color: pressed || hovered
|
||||||
|
? (checkBox.isLightColorScheme ? hifi.colors.checkboxChecked : hifi.colors.checkboxLightFinish)
|
||||||
|
: (checkBox.isLightColorScheme ? hifi.colors.checkboxLightFinish : hifi.colors.checkboxDarkFinish)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
visible: pressed || hovered
|
||||||
|
anchors.centerIn: parent
|
||||||
|
id: innerBox
|
||||||
|
width: checkSize - 4
|
||||||
|
height: width
|
||||||
|
radius: checkRadius
|
||||||
|
color: hifi.colors.checkboxCheckedBorder
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: check
|
||||||
|
width: checkSize
|
||||||
|
height: checkSize
|
||||||
|
radius: checkRadius
|
||||||
|
anchors.centerIn: parent
|
||||||
|
color: isRedCheck ? hifi.colors.checkboxCheckedRed : hifi.colors.checkboxChecked
|
||||||
|
border.width: 2
|
||||||
|
border.color: isRedCheck? hifi.colors.checkboxCheckedBorderRed : hifi.colors.checkboxCheckedBorder
|
||||||
|
visible: checked && !pressed || !checked && pressed
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: disabledOverlay
|
||||||
|
visible: !enabled
|
||||||
|
width: boxSize
|
||||||
|
height: boxSize
|
||||||
|
radius: boxRadius
|
||||||
|
border.width: 1
|
||||||
|
border.color: hifi.colors.baseGrayHighlight
|
||||||
|
color: hifi.colors.baseGrayHighlight
|
||||||
|
opacity: 0.5
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
contentItem: Text {
|
||||||
|
id: root
|
||||||
|
FontLoader { id: ralewaySemiBold; source: pathToFonts + "fonts/Raleway-SemiBold.ttf"; }
|
||||||
|
font.pixelSize: hifi.fontSizes.inputLabel
|
||||||
|
font.family: ralewaySemiBold.name
|
||||||
|
text: checkBox.text
|
||||||
|
color: checkBox.color
|
||||||
|
x: 2
|
||||||
|
wrapMode: checkBox.wrap ? Text.Wrap : Text.NoWrap
|
||||||
|
elide: checkBox.wrap ? Text.ElideNone : Text.ElideRight
|
||||||
|
enabled: checkBox.enabled
|
||||||
|
verticalAlignment: Text.AlignVCenter
|
||||||
|
leftPadding: checkBox.indicator.width + checkBox.spacing
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
//
|
//
|
||||||
|
|
||||||
import QtQuick 2.5
|
import QtQuick 2.5
|
||||||
import QtQuick.Controls 1.4
|
import QtQuick.Controls 2.2
|
||||||
import QtQuick.Layouts 1.3
|
import QtQuick.Layouts 1.3
|
||||||
|
|
||||||
import "../../styles-uit"
|
import "../../styles-uit"
|
||||||
|
@ -36,7 +36,41 @@ Rectangle {
|
||||||
return (root.parent !== null) && root.parent.objectName == "loader";
|
return (root.parent !== null) && root.parent.objectName == "loader";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
property bool isVR: Audio.context === "VR"
|
||||||
|
property real rightMostInputLevelPos: 0
|
||||||
|
//placeholder for control sizes and paddings
|
||||||
|
//recalculates dynamically in case of UI size is changed
|
||||||
|
QtObject {
|
||||||
|
id: margins
|
||||||
|
property real paddings: root.width / 20.25
|
||||||
|
|
||||||
|
property real sizeCheckBox: root.width / 13.5
|
||||||
|
property real sizeText: root.width / 2.5
|
||||||
|
property real sizeLevel: root.width / 5.8
|
||||||
|
property real sizeDesktop: root.width / 5.8
|
||||||
|
property real sizeVR: root.width / 13.5
|
||||||
|
}
|
||||||
|
|
||||||
|
TabBar {
|
||||||
|
id: bar
|
||||||
|
spacing: 0
|
||||||
|
width: parent.width
|
||||||
|
height: 42
|
||||||
|
currentIndex: isVR ? 1 : 0
|
||||||
|
|
||||||
|
AudioControls.AudioTabButton {
|
||||||
|
height: parent.height
|
||||||
|
text: qsTr("Desktop")
|
||||||
|
}
|
||||||
|
AudioControls.AudioTabButton {
|
||||||
|
height: parent.height
|
||||||
|
text: qsTr("VR")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
property bool showPeaks: true;
|
property bool showPeaks: true;
|
||||||
|
|
||||||
function enablePeakValues() {
|
function enablePeakValues() {
|
||||||
Audio.devices.input.peakValuesEnabled = true;
|
Audio.devices.input.peakValuesEnabled = true;
|
||||||
Audio.devices.input.peakValuesEnabledChanged.connect(function(enabled) {
|
Audio.devices.input.peakValuesEnabledChanged.connect(function(enabled) {
|
||||||
|
@ -45,6 +79,7 @@ Rectangle {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function disablePeakValues() {
|
function disablePeakValues() {
|
||||||
root.showPeaks = false;
|
root.showPeaks = false;
|
||||||
Audio.devices.input.peakValuesEnabled = false;
|
Audio.devices.input.peakValuesEnabled = false;
|
||||||
|
@ -55,29 +90,32 @@ Rectangle {
|
||||||
onVisibleChanged: visible ? enablePeakValues() : disablePeakValues();
|
onVisibleChanged: visible ? enablePeakValues() : disablePeakValues();
|
||||||
|
|
||||||
Column {
|
Column {
|
||||||
y: 16; // padding does not work
|
spacing: 12;
|
||||||
spacing: 16;
|
anchors.top: bar.bottom
|
||||||
|
anchors.bottom: parent.bottom
|
||||||
|
anchors.bottomMargin: 5
|
||||||
width: parent.width;
|
width: parent.width;
|
||||||
|
|
||||||
|
Separator { }
|
||||||
|
|
||||||
RalewayRegular {
|
RalewayRegular {
|
||||||
x: 16; // padding does not work
|
x: margins.paddings + muteMic.boxSize + muteMic.spacing;
|
||||||
size: 16;
|
size: 16;
|
||||||
color: "white";
|
color: "white";
|
||||||
text: root.title;
|
text: qsTr("Input Device Settings")
|
||||||
|
|
||||||
visible: root.showTitle();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Separator { visible: root.showTitle() }
|
|
||||||
|
|
||||||
ColumnLayout {
|
ColumnLayout {
|
||||||
x: 16; // padding does not work
|
x: margins.paddings;
|
||||||
spacing: 16;
|
spacing: 16;
|
||||||
|
width: parent.width;
|
||||||
|
|
||||||
// mute is in its own row
|
// mute is in its own row
|
||||||
RowLayout {
|
RowLayout {
|
||||||
AudioControls.CheckBox {
|
AudioControls.CheckBox {
|
||||||
|
id: muteMic
|
||||||
text: qsTr("Mute microphone");
|
text: qsTr("Mute microphone");
|
||||||
|
spacing: margins.sizeCheckBox - boxSize
|
||||||
isRedCheck: true;
|
isRedCheck: true;
|
||||||
checked: Audio.muted;
|
checked: Audio.muted;
|
||||||
onClicked: {
|
onClicked: {
|
||||||
|
@ -88,8 +126,9 @@ Rectangle {
|
||||||
}
|
}
|
||||||
|
|
||||||
RowLayout {
|
RowLayout {
|
||||||
spacing: 16;
|
spacing: muteMic.spacing*2; //make it visually distinguish
|
||||||
AudioControls.CheckBox {
|
AudioControls.CheckBox {
|
||||||
|
spacing: muteMic.spacing
|
||||||
text: qsTr("Enable noise reduction");
|
text: qsTr("Enable noise reduction");
|
||||||
checked: Audio.noiseReduction;
|
checked: Audio.noiseReduction;
|
||||||
onClicked: {
|
onClicked: {
|
||||||
|
@ -98,24 +137,33 @@ Rectangle {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
AudioControls.CheckBox {
|
AudioControls.CheckBox {
|
||||||
|
spacing: muteMic.spacing
|
||||||
text: qsTr("Show audio level meter");
|
text: qsTr("Show audio level meter");
|
||||||
checked: AvatarInputs.showAudioTools;
|
checked: AvatarInputs.showAudioTools;
|
||||||
onClicked: {
|
onClicked: {
|
||||||
AvatarInputs.showAudioTools = checked;
|
AvatarInputs.showAudioTools = checked;
|
||||||
checked = Qt.binding(function() { return AvatarInputs.showAudioTools; }); // restore binding
|
checked = Qt.binding(function() { return AvatarInputs.showAudioTools; }); // restore binding
|
||||||
}
|
}
|
||||||
|
onXChanged: rightMostInputLevelPos = x + width
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Separator {}
|
Separator {}
|
||||||
|
|
||||||
RowLayout {
|
Item {
|
||||||
|
x: margins.paddings;
|
||||||
|
width: parent.width - margins.paddings*2
|
||||||
|
height: 36
|
||||||
|
|
||||||
HiFiGlyphs {
|
HiFiGlyphs {
|
||||||
|
width: margins.sizeCheckBox
|
||||||
text: hifi.glyphs.mic;
|
text: hifi.glyphs.mic;
|
||||||
color: hifi.colors.primaryHighlight;
|
color: hifi.colors.primaryHighlight;
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.leftMargin: -size/4 //the glyph has empty space at left about 25%
|
||||||
anchors.verticalCenter: parent.verticalCenter;
|
anchors.verticalCenter: parent.verticalCenter;
|
||||||
size: 28;
|
size: 30;
|
||||||
}
|
}
|
||||||
RalewayRegular {
|
RalewayRegular {
|
||||||
anchors.verticalCenter: parent.verticalCenter;
|
anchors.verticalCenter: parent.verticalCenter;
|
||||||
|
@ -126,90 +174,114 @@ Rectangle {
|
||||||
}
|
}
|
||||||
|
|
||||||
ListView {
|
ListView {
|
||||||
anchors { left: parent.left; right: parent.right; leftMargin: 70 }
|
id: inputView
|
||||||
height: 125;
|
width: parent.width - margins.paddings*2
|
||||||
spacing: 0;
|
x: margins.paddings
|
||||||
|
height: Math.min(150, contentHeight);
|
||||||
|
spacing: 4;
|
||||||
snapMode: ListView.SnapToItem;
|
snapMode: ListView.SnapToItem;
|
||||||
clip: true;
|
clip: true;
|
||||||
model: Audio.devices.input;
|
model: Audio.devices.input;
|
||||||
delegate: Item {
|
delegate: Item {
|
||||||
width: parent.width;
|
width: rightMostInputLevelPos
|
||||||
height: 36;
|
height: margins.sizeCheckBox > checkBoxInput.implicitHeight ?
|
||||||
|
margins.sizeCheckBox : checkBoxInput.implicitHeight
|
||||||
|
|
||||||
AudioControls.CheckBox {
|
AudioControls.CheckBox {
|
||||||
id: checkbox
|
id: checkBoxInput
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
text: display;
|
spacing: margins.sizeCheckBox - boxSize
|
||||||
wrap: false;
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
checked: selected;
|
width: parent.width - inputLevel.width
|
||||||
enabled: false;
|
clip: true
|
||||||
|
checkable: !checked
|
||||||
|
checked: bar.currentIndex === 0 ? selectedDesktop : selectedHMD;
|
||||||
|
boxSize: margins.sizeCheckBox / 2
|
||||||
|
isRound: true
|
||||||
|
text: devicename
|
||||||
|
onPressed: {
|
||||||
|
if (!checked) {
|
||||||
|
Audio.setInputDevice(info, bar.currentIndex === 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MouseArea {
|
|
||||||
anchors.fill: checkbox
|
|
||||||
onClicked: Audio.setInputDevice(info);
|
|
||||||
}
|
|
||||||
|
|
||||||
InputPeak {
|
InputPeak {
|
||||||
id: inputPeak;
|
id: inputLevel
|
||||||
visible: Audio.devices.input.peakValuesAvailable;
|
anchors.right: parent.right
|
||||||
peak: model.peak;
|
peak: model.peak;
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
anchors.right: parent.right
|
visible: (bar.currentIndex === 1 && selectedHMD && isVR) ||
|
||||||
anchors.rightMargin: 30
|
(bar.currentIndex === 0 && selectedDesktop && !isVR) &&
|
||||||
|
Audio.devices.input.peakValuesAvailable;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Separator {}
|
Separator {}
|
||||||
|
|
||||||
RowLayout {
|
Item {
|
||||||
Column {
|
x: margins.paddings;
|
||||||
RowLayout {
|
width: parent.width - margins.paddings*2
|
||||||
HiFiGlyphs {
|
height: 36
|
||||||
text: hifi.glyphs.unmuted;
|
|
||||||
color: hifi.colors.primaryHighlight;
|
|
||||||
anchors.verticalCenter: parent.verticalCenter;
|
|
||||||
size: 36;
|
|
||||||
}
|
|
||||||
RalewayRegular {
|
|
||||||
anchors.verticalCenter: parent.verticalCenter;
|
|
||||||
size: 16;
|
|
||||||
color: hifi.colors.lightGrayText;
|
|
||||||
text: qsTr("CHOOSE OUTPUT DEVICE");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
PlaySampleSound { anchors { left: parent.left; leftMargin: 60 }}
|
HiFiGlyphs {
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.leftMargin: -size/4 //the glyph has empty space at left about 25%
|
||||||
|
anchors.verticalCenter: parent.verticalCenter;
|
||||||
|
width: margins.sizeCheckBox
|
||||||
|
text: hifi.glyphs.unmuted;
|
||||||
|
color: hifi.colors.primaryHighlight;
|
||||||
|
size: 36;
|
||||||
|
}
|
||||||
|
|
||||||
|
RalewayRegular {
|
||||||
|
width: margins.sizeText + margins.sizeLevel
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.leftMargin: margins.sizeCheckBox
|
||||||
|
anchors.verticalCenter: parent.verticalCenter;
|
||||||
|
size: 16;
|
||||||
|
color: hifi.colors.lightGrayText;
|
||||||
|
text: qsTr("CHOOSE OUTPUT DEVICE");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ListView {
|
ListView {
|
||||||
anchors { left: parent.left; right: parent.right; leftMargin: 70 }
|
id: outputView
|
||||||
height: Math.min(250, contentHeight);
|
width: parent.width - margins.paddings*2
|
||||||
spacing: 0;
|
x: margins.paddings
|
||||||
|
height: Math.min(360 - inputView.height, contentHeight);
|
||||||
|
spacing: 4;
|
||||||
snapMode: ListView.SnapToItem;
|
snapMode: ListView.SnapToItem;
|
||||||
clip: true;
|
clip: true;
|
||||||
model: Audio.devices.output;
|
model: Audio.devices.output;
|
||||||
delegate: Item {
|
delegate: Item {
|
||||||
width: parent.width;
|
width: rightMostInputLevelPos
|
||||||
height: 36;
|
height: margins.sizeCheckBox > checkBoxOutput.implicitHeight ?
|
||||||
|
margins.sizeCheckBox : checkBoxOutput.implicitHeight
|
||||||
|
|
||||||
AudioControls.CheckBox {
|
AudioControls.CheckBox {
|
||||||
id: checkbox
|
id: checkBoxOutput
|
||||||
anchors.verticalCenter: parent.verticalCenter
|
width: parent.width
|
||||||
anchors.left: parent.left
|
spacing: margins.sizeCheckBox - boxSize
|
||||||
text: display;
|
boxSize: margins.sizeCheckBox / 2
|
||||||
checked: selected;
|
isRound: true
|
||||||
enabled: false;
|
checked: bar.currentIndex === 0 ? selectedDesktop : selectedHMD;
|
||||||
}
|
checkable: !checked
|
||||||
|
text: devicename
|
||||||
MouseArea {
|
onPressed: {
|
||||||
anchors.fill: checkbox
|
if (!checked) {
|
||||||
onClicked: Audio.setOutputDevice(info);
|
Audio.setOutputDevice(info, bar.currentIndex === 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
PlaySampleSound {
|
||||||
|
x: margins.paddings
|
||||||
|
|
||||||
|
visible: (bar.currentIndex === 1 && isVR) ||
|
||||||
|
(bar.currentIndex === 0 && !isVR);
|
||||||
|
anchors { left: parent.left; leftMargin: margins.paddings }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
35
interface/resources/qml/hifi/audio/AudioTabButton.qml
Normal file
35
interface/resources/qml/hifi/audio/AudioTabButton.qml
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
//
|
||||||
|
// AudioTabButton.qml
|
||||||
|
// qml/hifi/audio
|
||||||
|
//
|
||||||
|
// Created by Vlad Stelmahovsky on 8/16/2017
|
||||||
|
// Copyright 2017 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
|
||||||
|
//
|
||||||
|
|
||||||
|
import QtQuick 2.7
|
||||||
|
import QtQuick.Controls 2.2
|
||||||
|
import "../../controls-uit" as HifiControls
|
||||||
|
import "../../styles-uit"
|
||||||
|
|
||||||
|
TabButton {
|
||||||
|
id: control
|
||||||
|
font.pixelSize: height / 2
|
||||||
|
|
||||||
|
HifiConstants { id: hifi; }
|
||||||
|
|
||||||
|
contentItem: RalewaySemiBold {
|
||||||
|
text: control.text
|
||||||
|
font: control.font
|
||||||
|
color: "white"
|
||||||
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
verticalAlignment: Text.AlignVCenter
|
||||||
|
elide: Text.ElideRight
|
||||||
|
}
|
||||||
|
|
||||||
|
background: Rectangle {
|
||||||
|
color: control.checked ? hifi.colors.baseGray : "black"
|
||||||
|
}
|
||||||
|
}
|
|
@ -9,10 +9,10 @@
|
||||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
//
|
//
|
||||||
|
|
||||||
import QtQuick 2.5
|
import QtQuick 2.7
|
||||||
|
|
||||||
import "../../controls-uit" as HifiControls
|
import "../../controls-uit" as HifiControls
|
||||||
|
|
||||||
HifiControls.CheckBox {
|
HifiControls.CheckBoxQQC2 {
|
||||||
color: "white"
|
color: "white"
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,8 +9,6 @@
|
||||||
//
|
//
|
||||||
|
|
||||||
import QtQuick 2.5
|
import QtQuick 2.5
|
||||||
import QtQuick.Controls 1.4
|
|
||||||
import QtQuick.Controls.Styles 1.4
|
|
||||||
|
|
||||||
Text {
|
Text {
|
||||||
id: root
|
id: root
|
||||||
|
|
|
@ -2057,6 +2057,7 @@ void Application::cleanupBeforeQuit() {
|
||||||
// this must happen after QML, as there are unexplained audio crashes originating in qtwebengine
|
// this must happen after QML, as there are unexplained audio crashes originating in qtwebengine
|
||||||
DependencyManager::destroy<AudioClient>();
|
DependencyManager::destroy<AudioClient>();
|
||||||
DependencyManager::destroy<AudioInjectorManager>();
|
DependencyManager::destroy<AudioInjectorManager>();
|
||||||
|
DependencyManager::destroy<AudioScriptingInterface>();
|
||||||
|
|
||||||
qCDebug(interfaceapp) << "Application::cleanupBeforeQuit() complete";
|
qCDebug(interfaceapp) << "Application::cleanupBeforeQuit() complete";
|
||||||
}
|
}
|
||||||
|
|
|
@ -135,10 +135,10 @@ void Audio::setReverbOptions(const AudioEffectOptions* options) {
|
||||||
DependencyManager::get<AudioClient>()->setReverbOptions(options);
|
DependencyManager::get<AudioClient>()->setReverbOptions(options);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Audio::setInputDevice(const QAudioDeviceInfo& device) {
|
void Audio::setInputDevice(const QAudioDeviceInfo& device, bool isHMD) {
|
||||||
_devices.chooseInputDevice(device);
|
_devices.chooseInputDevice(device, isHMD);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Audio::setOutputDevice(const QAudioDeviceInfo& device) {
|
void Audio::setOutputDevice(const QAudioDeviceInfo& device, bool isHMD) {
|
||||||
_devices.chooseOutputDevice(device);
|
_devices.chooseOutputDevice(device, isHMD);
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,8 +50,8 @@ public:
|
||||||
void showMicMeter(bool show);
|
void showMicMeter(bool show);
|
||||||
void setInputVolume(float volume);
|
void setInputVolume(float volume);
|
||||||
|
|
||||||
Q_INVOKABLE void setInputDevice(const QAudioDeviceInfo& device);
|
Q_INVOKABLE void setInputDevice(const QAudioDeviceInfo& device, bool isHMD);
|
||||||
Q_INVOKABLE void setOutputDevice(const QAudioDeviceInfo& device);
|
Q_INVOKABLE void setOutputDevice(const QAudioDeviceInfo& device, bool isHMD);
|
||||||
Q_INVOKABLE void setReverb(bool enable);
|
Q_INVOKABLE void setReverb(bool enable);
|
||||||
Q_INVOKABLE void setReverbOptions(const AudioEffectOptions* options);
|
Q_INVOKABLE void setReverbOptions(const AudioEffectOptions* options);
|
||||||
|
|
||||||
|
|
|
@ -38,15 +38,17 @@ Setting::Handle<QString>& getSetting(bool contextIsHMD, QAudio::Mode mode) {
|
||||||
}
|
}
|
||||||
|
|
||||||
enum AudioDeviceRole {
|
enum AudioDeviceRole {
|
||||||
DisplayRole = Qt::DisplayRole,
|
DeviceNameRole = Qt::UserRole,
|
||||||
CheckStateRole = Qt::CheckStateRole,
|
SelectedDesktopRole,
|
||||||
PeakRole = Qt::UserRole,
|
SelectedHMDRole,
|
||||||
InfoRole = Qt::UserRole + 1
|
PeakRole,
|
||||||
|
InfoRole
|
||||||
};
|
};
|
||||||
|
|
||||||
QHash<int, QByteArray> AudioDeviceList::_roles {
|
QHash<int, QByteArray> AudioDeviceList::_roles {
|
||||||
{ DisplayRole, "display" },
|
{ DeviceNameRole, "devicename" },
|
||||||
{ CheckStateRole, "selected" },
|
{ SelectedDesktopRole, "selectedDesktop" },
|
||||||
|
{ SelectedHMDRole, "selectedHMD" },
|
||||||
{ PeakRole, "peak" },
|
{ PeakRole, "peak" },
|
||||||
{ InfoRole, "info" }
|
{ InfoRole, "info" }
|
||||||
};
|
};
|
||||||
|
@ -68,15 +70,64 @@ static QString getTargetDevice(bool hmd, QAudio::Mode mode) {
|
||||||
|
|
||||||
Qt::ItemFlags AudioDeviceList::_flags { Qt::ItemIsSelectable | Qt::ItemIsEnabled };
|
Qt::ItemFlags AudioDeviceList::_flags { Qt::ItemIsSelectable | Qt::ItemIsEnabled };
|
||||||
|
|
||||||
|
AudioDeviceList::AudioDeviceList(QAudio::Mode mode) : _mode(mode) {
|
||||||
|
auto& setting1 = getSetting(true, QAudio::AudioInput);
|
||||||
|
if (setting1.isSet()) {
|
||||||
|
qDebug() << "Device name in settings for HMD, Input" << setting1.get();
|
||||||
|
} else {
|
||||||
|
qDebug() << "Device name in settings for HMD, Input not set";
|
||||||
|
}
|
||||||
|
|
||||||
|
auto& setting2 = getSetting(true, QAudio::AudioOutput);
|
||||||
|
if (setting2.isSet()) {
|
||||||
|
qDebug() << "Device name in settings for HMD, Output" << setting2.get();
|
||||||
|
} else {
|
||||||
|
qDebug() << "Device name in settings for HMD, Output not set";
|
||||||
|
}
|
||||||
|
|
||||||
|
auto& setting3 = getSetting(false, QAudio::AudioInput);
|
||||||
|
if (setting3.isSet()) {
|
||||||
|
qDebug() << "Device name in settings for Desktop, Input" << setting3.get();
|
||||||
|
} else {
|
||||||
|
qDebug() << "Device name in settings for Desktop, Input not set";
|
||||||
|
}
|
||||||
|
|
||||||
|
auto& setting4 = getSetting(false, QAudio::AudioOutput);
|
||||||
|
if (setting4.isSet()) {
|
||||||
|
qDebug() << "Device name in settings for Desktop, Output" << setting4.get();
|
||||||
|
} else {
|
||||||
|
qDebug() << "Device name in settings for Desktop, Output not set";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
AudioDeviceList::~AudioDeviceList() {
|
||||||
|
//save all selected devices
|
||||||
|
auto& settingHMD = getSetting(true, _mode);
|
||||||
|
auto& settingDesktop = getSetting(false, _mode);
|
||||||
|
// store the selected device
|
||||||
|
foreach(std::shared_ptr<AudioDevice> adevice, _devices) {
|
||||||
|
if (adevice->selectedDesktop) {
|
||||||
|
qDebug() << "Saving Desktop for" << _mode << "name" << adevice->info.deviceName();
|
||||||
|
settingDesktop.set(adevice->info.deviceName());
|
||||||
|
}
|
||||||
|
if (adevice->selectedHMD) {
|
||||||
|
qDebug() << "Saving HMD for" << _mode << "name" << adevice->info.deviceName();
|
||||||
|
settingHMD.set(adevice->info.deviceName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
QVariant AudioDeviceList::data(const QModelIndex& index, int role) const {
|
QVariant AudioDeviceList::data(const QModelIndex& index, int role) const {
|
||||||
if (!index.isValid() || index.row() >= rowCount()) {
|
if (!index.isValid() || index.row() >= rowCount()) {
|
||||||
return QVariant();
|
return QVariant();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (role == DisplayRole) {
|
if (role == DeviceNameRole) {
|
||||||
return _devices.at(index.row())->display;
|
return _devices.at(index.row())->display;
|
||||||
} else if (role == CheckStateRole) {
|
} else if (role == SelectedDesktopRole) {
|
||||||
return _devices.at(index.row())->selected;
|
return _devices.at(index.row())->selectedDesktop;
|
||||||
|
} else if (role == SelectedHMDRole) {
|
||||||
|
return _devices.at(index.row())->selectedHMD;
|
||||||
} else if (role == InfoRole) {
|
} else if (role == InfoRole) {
|
||||||
return QVariant::fromValue<QAudioDeviceInfo>(_devices.at(index.row())->info);
|
return QVariant::fromValue<QAudioDeviceInfo>(_devices.at(index.row())->info);
|
||||||
} else {
|
} else {
|
||||||
|
@ -130,37 +181,48 @@ void AudioDeviceList::resetDevice(bool contextIsHMD) {
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioDeviceList::onDeviceChanged(const QAudioDeviceInfo& device) {
|
void AudioDeviceList::onDeviceChanged(const QAudioDeviceInfo& device, bool isHMD) {
|
||||||
auto oldDevice = _selectedDevice;
|
auto oldDevice = isHMD ? _selectedHMDDevice : _selectedDesktopDevice;
|
||||||
_selectedDevice = device;
|
QAudioDeviceInfo& selectedDevice = isHMD ? _selectedHMDDevice : _selectedDesktopDevice;
|
||||||
|
selectedDevice = device;
|
||||||
|
|
||||||
for (auto i = 0; i < rowCount(); ++i) {
|
for (auto i = 0; i < _devices.size(); ++i) {
|
||||||
AudioDevice& device = *_devices[i];
|
std::shared_ptr<AudioDevice> device = _devices[i];
|
||||||
|
bool &isSelected = isHMD ? device->selectedHMD : device->selectedDesktop;
|
||||||
if (device.selected && device.info != _selectedDevice) {
|
if (isSelected && device->info != selectedDevice) {
|
||||||
device.selected = false;
|
isSelected = false;
|
||||||
} else if (device.info == _selectedDevice) {
|
} else if (device->info == selectedDevice) {
|
||||||
device.selected = true;
|
isSelected = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
emit deviceChanged(_selectedDevice);
|
emit deviceChanged(selectedDevice);
|
||||||
emit dataChanged(createIndex(0, 0), createIndex(rowCount() - 1, 0));
|
emit dataChanged(createIndex(0, 0), createIndex(rowCount() - 1, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioDeviceList::onDevicesChanged(const QList<QAudioDeviceInfo>& devices) {
|
void AudioDeviceList::onDevicesChanged(const QList<QAudioDeviceInfo>& devices, bool isHMD) {
|
||||||
|
QAudioDeviceInfo& selectedDevice = isHMD ? _selectedHMDDevice : _selectedDesktopDevice;
|
||||||
|
|
||||||
|
const QString& savedDeviceName = isHMD ? _hmdSavedDeviceName : _desktopSavedDeviceName;
|
||||||
beginResetModel();
|
beginResetModel();
|
||||||
|
|
||||||
_devices.clear();
|
_devices.clear();
|
||||||
|
|
||||||
foreach(const QAudioDeviceInfo& deviceInfo, devices) {
|
foreach(const QAudioDeviceInfo& deviceInfo, devices) {
|
||||||
AudioDevice device;
|
AudioDevice device;
|
||||||
|
bool &isSelected = isHMD ? device.selectedHMD : device.selectedDesktop;
|
||||||
device.info = deviceInfo;
|
device.info = deviceInfo;
|
||||||
device.display = device.info.deviceName()
|
device.display = device.info.deviceName()
|
||||||
.replace("High Definition", "HD")
|
.replace("High Definition", "HD")
|
||||||
.remove("Device")
|
.remove("Device")
|
||||||
.replace(" )", ")");
|
.replace(" )", ")");
|
||||||
device.selected = (device.info == _selectedDevice);
|
if (!selectedDevice.isNull()) {
|
||||||
|
isSelected = (device.info == selectedDevice);
|
||||||
|
} else {
|
||||||
|
//no selected device for context. fallback to saved
|
||||||
|
isSelected = (device.info.deviceName() == savedDeviceName);
|
||||||
|
}
|
||||||
|
qDebug() << "adding audio device:" << device.display << device.selectedDesktop << device.selectedHMD << _mode;
|
||||||
_devices.push_back(newDevice(device));
|
_devices.push_back(newDevice(device));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -203,22 +265,32 @@ AudioDevices::AudioDevices(bool& contextIsHMD) : _contextIsHMD(contextIsHMD) {
|
||||||
connect(client.data(), &AudioClient::devicesChanged, this, &AudioDevices::onDevicesChanged, Qt::QueuedConnection);
|
connect(client.data(), &AudioClient::devicesChanged, this, &AudioDevices::onDevicesChanged, Qt::QueuedConnection);
|
||||||
connect(client.data(), &AudioClient::peakValueListChanged, &_inputs, &AudioInputDeviceList::onPeakValueListChanged, Qt::QueuedConnection);
|
connect(client.data(), &AudioClient::peakValueListChanged, &_inputs, &AudioInputDeviceList::onPeakValueListChanged, Qt::QueuedConnection);
|
||||||
|
|
||||||
|
_inputs.onDeviceChanged(client->getActiveAudioDevice(QAudio::AudioInput), contextIsHMD);
|
||||||
|
_outputs.onDeviceChanged(client->getActiveAudioDevice(QAudio::AudioOutput), contextIsHMD);
|
||||||
|
|
||||||
// connections are made after client is initialized, so we must also fetch the devices
|
// connections are made after client is initialized, so we must also fetch the devices
|
||||||
_inputs.onDeviceChanged(client->getActiveAudioDevice(QAudio::AudioInput));
|
const QList<QAudioDeviceInfo>& devicesInput = client->getAudioDevices(QAudio::AudioInput);
|
||||||
_outputs.onDeviceChanged(client->getActiveAudioDevice(QAudio::AudioOutput));
|
const QList<QAudioDeviceInfo>& devicesOutput = client->getAudioDevices(QAudio::AudioOutput);
|
||||||
_inputs.onDevicesChanged(client->getAudioDevices(QAudio::AudioInput));
|
//setup HMD devices
|
||||||
_outputs.onDevicesChanged(client->getAudioDevices(QAudio::AudioOutput));
|
_inputs.onDevicesChanged(devicesInput, true);
|
||||||
|
_outputs.onDevicesChanged(devicesOutput, true);
|
||||||
|
//setup Desktop devices
|
||||||
|
_inputs.onDevicesChanged(devicesInput, false);
|
||||||
|
_outputs.onDevicesChanged(devicesOutput, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AudioDevices::~AudioDevices() {}
|
||||||
|
|
||||||
void AudioDevices::onContextChanged(const QString& context) {
|
void AudioDevices::onContextChanged(const QString& context) {
|
||||||
_inputs.resetDevice(_contextIsHMD);
|
_inputs.resetDevice(_contextIsHMD);
|
||||||
_outputs.resetDevice(_contextIsHMD);
|
_outputs.resetDevice(_contextIsHMD);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioDevices::onDeviceSelected(QAudio::Mode mode, const QAudioDeviceInfo& device, const QAudioDeviceInfo& previousDevice) {
|
void AudioDevices::onDeviceSelected(QAudio::Mode mode, const QAudioDeviceInfo& device,
|
||||||
|
const QAudioDeviceInfo& previousDevice, bool isHMD) {
|
||||||
QString deviceName = device.isNull() ? QString() : device.deviceName();
|
QString deviceName = device.isNull() ? QString() : device.deviceName();
|
||||||
|
|
||||||
auto& setting = getSetting(_contextIsHMD, mode);
|
auto& setting = getSetting(isHMD, mode);
|
||||||
|
|
||||||
// check for a previous device
|
// check for a previous device
|
||||||
auto wasDefault = setting.get().isNull();
|
auto wasDefault = setting.get().isNull();
|
||||||
|
@ -254,42 +326,94 @@ void AudioDevices::onDeviceSelected(QAudio::Mode mode, const QAudioDeviceInfo& d
|
||||||
void AudioDevices::onDeviceChanged(QAudio::Mode mode, const QAudioDeviceInfo& device) {
|
void AudioDevices::onDeviceChanged(QAudio::Mode mode, const QAudioDeviceInfo& device) {
|
||||||
if (mode == QAudio::AudioInput) {
|
if (mode == QAudio::AudioInput) {
|
||||||
if (_requestedInputDevice == device) {
|
if (_requestedInputDevice == device) {
|
||||||
onDeviceSelected(QAudio::AudioInput, device, _inputs._selectedDevice);
|
onDeviceSelected(QAudio::AudioInput, device,
|
||||||
|
_contextIsHMD ? _inputs._selectedHMDDevice : _inputs._selectedDesktopDevice,
|
||||||
|
_contextIsHMD);
|
||||||
_requestedInputDevice = QAudioDeviceInfo();
|
_requestedInputDevice = QAudioDeviceInfo();
|
||||||
}
|
}
|
||||||
_inputs.onDeviceChanged(device);
|
_inputs.onDeviceChanged(device, _contextIsHMD);
|
||||||
} else { // if (mode == QAudio::AudioOutput)
|
} else { // if (mode == QAudio::AudioOutput)
|
||||||
if (_requestedOutputDevice == device) {
|
if (_requestedOutputDevice == device) {
|
||||||
onDeviceSelected(QAudio::AudioOutput, device, _outputs._selectedDevice);
|
onDeviceSelected(QAudio::AudioOutput, device,
|
||||||
|
_contextIsHMD ? _outputs._selectedHMDDevice : _outputs._selectedDesktopDevice,
|
||||||
|
_contextIsHMD);
|
||||||
_requestedOutputDevice = QAudioDeviceInfo();
|
_requestedOutputDevice = QAudioDeviceInfo();
|
||||||
}
|
}
|
||||||
_outputs.onDeviceChanged(device);
|
_outputs.onDeviceChanged(device, _contextIsHMD);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioDevices::onDevicesChanged(QAudio::Mode mode, const QList<QAudioDeviceInfo>& devices) {
|
void AudioDevices::onDevicesChanged(QAudio::Mode mode, const QList<QAudioDeviceInfo>& devices) {
|
||||||
static std::once_flag once;
|
static std::once_flag once;
|
||||||
|
std::call_once(once, [&] {
|
||||||
|
//readout settings
|
||||||
|
auto client = DependencyManager::get<AudioClient>();
|
||||||
|
|
||||||
|
_inputs._hmdSavedDeviceName = getTargetDevice(true, QAudio::AudioInput);
|
||||||
|
_inputs._desktopSavedDeviceName = getTargetDevice(false, QAudio::AudioInput);
|
||||||
|
|
||||||
|
//fallback to default device
|
||||||
|
if (_inputs._desktopSavedDeviceName.isEmpty()) {
|
||||||
|
_inputs._desktopSavedDeviceName = client->getActiveAudioDevice(QAudio::AudioInput).deviceName();
|
||||||
|
}
|
||||||
|
//fallback to desktop device
|
||||||
|
if (_inputs._hmdSavedDeviceName.isEmpty()) {
|
||||||
|
_inputs._hmdSavedDeviceName = _inputs._desktopSavedDeviceName;
|
||||||
|
}
|
||||||
|
|
||||||
|
_outputs._hmdSavedDeviceName = getTargetDevice(true, QAudio::AudioOutput);
|
||||||
|
_outputs._desktopSavedDeviceName = getTargetDevice(false, QAudio::AudioOutput);
|
||||||
|
|
||||||
|
if (_outputs._desktopSavedDeviceName.isEmpty()) {
|
||||||
|
_outputs._desktopSavedDeviceName = client->getActiveAudioDevice(QAudio::AudioOutput).deviceName();
|
||||||
|
}
|
||||||
|
if (_outputs._hmdSavedDeviceName.isEmpty()) {
|
||||||
|
_outputs._hmdSavedDeviceName = _outputs._desktopSavedDeviceName;
|
||||||
|
}
|
||||||
|
onContextChanged(QString());
|
||||||
|
});
|
||||||
|
|
||||||
|
//set devices for both contexts
|
||||||
if (mode == QAudio::AudioInput) {
|
if (mode == QAudio::AudioInput) {
|
||||||
_inputs.onDevicesChanged(devices);
|
_inputs.onDevicesChanged(devices, _contextIsHMD);
|
||||||
|
_inputs.onDevicesChanged(devices, !_contextIsHMD);
|
||||||
} else { // if (mode == QAudio::AudioOutput)
|
} else { // if (mode == QAudio::AudioOutput)
|
||||||
_outputs.onDevicesChanged(devices);
|
_outputs.onDevicesChanged(devices, _contextIsHMD);
|
||||||
|
_outputs.onDevicesChanged(devices, !_contextIsHMD);
|
||||||
}
|
}
|
||||||
std::call_once(once, [&] { onContextChanged(QString()); });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void AudioDevices::chooseInputDevice(const QAudioDeviceInfo& device) {
|
void AudioDevices::chooseInputDevice(const QAudioDeviceInfo& device, bool isHMD) {
|
||||||
auto client = DependencyManager::get<AudioClient>();
|
//check if current context equals device to change
|
||||||
_requestedInputDevice = device;
|
if (_contextIsHMD == isHMD) {
|
||||||
QMetaObject::invokeMethod(client.data(), "switchAudioDevice",
|
auto client = DependencyManager::get<AudioClient>();
|
||||||
Q_ARG(QAudio::Mode, QAudio::AudioInput),
|
_requestedInputDevice = device;
|
||||||
Q_ARG(const QAudioDeviceInfo&, device));
|
QMetaObject::invokeMethod(client.data(), "switchAudioDevice",
|
||||||
|
Q_ARG(QAudio::Mode, QAudio::AudioInput),
|
||||||
|
Q_ARG(const QAudioDeviceInfo&, device));
|
||||||
|
} else {
|
||||||
|
//context is different. just save device in settings
|
||||||
|
onDeviceSelected(QAudio::AudioInput, device,
|
||||||
|
isHMD ? _inputs._selectedHMDDevice : _inputs._selectedDesktopDevice,
|
||||||
|
isHMD);
|
||||||
|
_inputs.onDeviceChanged(device, isHMD);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioDevices::chooseOutputDevice(const QAudioDeviceInfo& device) {
|
void AudioDevices::chooseOutputDevice(const QAudioDeviceInfo& device, bool isHMD) {
|
||||||
auto client = DependencyManager::get<AudioClient>();
|
//check if current context equals device to change
|
||||||
_requestedOutputDevice = device;
|
if (_contextIsHMD == isHMD) {
|
||||||
QMetaObject::invokeMethod(client.data(), "switchAudioDevice",
|
auto client = DependencyManager::get<AudioClient>();
|
||||||
Q_ARG(QAudio::Mode, QAudio::AudioOutput),
|
_requestedOutputDevice = device;
|
||||||
Q_ARG(const QAudioDeviceInfo&, device));
|
QMetaObject::invokeMethod(client.data(), "switchAudioDevice",
|
||||||
|
Q_ARG(QAudio::Mode, QAudio::AudioOutput),
|
||||||
|
Q_ARG(const QAudioDeviceInfo&, device));
|
||||||
|
} else {
|
||||||
|
//context is different. just save device in settings
|
||||||
|
onDeviceSelected(QAudio::AudioOutput, device,
|
||||||
|
isHMD ? _outputs._selectedHMDDevice : _outputs._selectedDesktopDevice,
|
||||||
|
isHMD);
|
||||||
|
_outputs.onDeviceChanged(device, isHMD);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,15 +25,16 @@ class AudioDevice {
|
||||||
public:
|
public:
|
||||||
QAudioDeviceInfo info;
|
QAudioDeviceInfo info;
|
||||||
QString display;
|
QString display;
|
||||||
bool selected { false };
|
bool selectedDesktop { false };
|
||||||
|
bool selectedHMD { false };
|
||||||
};
|
};
|
||||||
|
|
||||||
class AudioDeviceList : public QAbstractListModel {
|
class AudioDeviceList : public QAbstractListModel {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
AudioDeviceList(QAudio::Mode mode = QAudio::AudioOutput) : _mode(mode) {}
|
AudioDeviceList(QAudio::Mode mode = QAudio::AudioOutput);
|
||||||
~AudioDeviceList() = default;
|
virtual ~AudioDeviceList();
|
||||||
|
|
||||||
virtual std::shared_ptr<AudioDevice> newDevice(const AudioDevice& device)
|
virtual std::shared_ptr<AudioDevice> newDevice(const AudioDevice& device)
|
||||||
{ return std::make_shared<AudioDevice>(device); }
|
{ return std::make_shared<AudioDevice>(device); }
|
||||||
|
@ -52,8 +53,8 @@ signals:
|
||||||
void deviceChanged(const QAudioDeviceInfo& device);
|
void deviceChanged(const QAudioDeviceInfo& device);
|
||||||
|
|
||||||
protected slots:
|
protected slots:
|
||||||
void onDeviceChanged(const QAudioDeviceInfo& device);
|
void onDeviceChanged(const QAudioDeviceInfo& device, bool isHMD);
|
||||||
void onDevicesChanged(const QList<QAudioDeviceInfo>& devices);
|
void onDevicesChanged(const QList<QAudioDeviceInfo>& devices, bool isHMD);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
friend class AudioDevices;
|
friend class AudioDevices;
|
||||||
|
@ -61,8 +62,11 @@ protected:
|
||||||
static QHash<int, QByteArray> _roles;
|
static QHash<int, QByteArray> _roles;
|
||||||
static Qt::ItemFlags _flags;
|
static Qt::ItemFlags _flags;
|
||||||
const QAudio::Mode _mode;
|
const QAudio::Mode _mode;
|
||||||
QAudioDeviceInfo _selectedDevice;
|
QAudioDeviceInfo _selectedDesktopDevice;
|
||||||
|
QAudioDeviceInfo _selectedHMDDevice;
|
||||||
QList<std::shared_ptr<AudioDevice>> _devices;
|
QList<std::shared_ptr<AudioDevice>> _devices;
|
||||||
|
QString _hmdSavedDeviceName;
|
||||||
|
QString _desktopSavedDeviceName;
|
||||||
};
|
};
|
||||||
|
|
||||||
class AudioInputDevice : public AudioDevice {
|
class AudioInputDevice : public AudioDevice {
|
||||||
|
@ -102,7 +106,6 @@ protected:
|
||||||
void setPeakValuesEnabled(bool enable);
|
void setPeakValuesEnabled(bool enable);
|
||||||
bool _peakValuesEnabled { false };
|
bool _peakValuesEnabled { false };
|
||||||
};
|
};
|
||||||
|
|
||||||
class Audio;
|
class Audio;
|
||||||
|
|
||||||
class AudioDevices : public QObject {
|
class AudioDevices : public QObject {
|
||||||
|
@ -112,15 +115,18 @@ class AudioDevices : public QObject {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
AudioDevices(bool& contextIsHMD);
|
AudioDevices(bool& contextIsHMD);
|
||||||
void chooseInputDevice(const QAudioDeviceInfo& device);
|
virtual ~AudioDevices();
|
||||||
void chooseOutputDevice(const QAudioDeviceInfo& device);
|
|
||||||
|
void chooseInputDevice(const QAudioDeviceInfo& device, bool isHMD);
|
||||||
|
void chooseOutputDevice(const QAudioDeviceInfo& device, bool isHMD);
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void nop();
|
void nop();
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void onContextChanged(const QString& context);
|
void onContextChanged(const QString& context);
|
||||||
void onDeviceSelected(QAudio::Mode mode, const QAudioDeviceInfo& device, const QAudioDeviceInfo& previousDevice);
|
void onDeviceSelected(QAudio::Mode mode, const QAudioDeviceInfo& device,
|
||||||
|
const QAudioDeviceInfo& previousDevice, bool isHMD);
|
||||||
void onDeviceChanged(QAudio::Mode mode, const QAudioDeviceInfo& device);
|
void onDeviceChanged(QAudio::Mode mode, const QAudioDeviceInfo& device);
|
||||||
void onDevicesChanged(QAudio::Mode mode, const QList<QAudioDeviceInfo>& devices);
|
void onDevicesChanged(QAudio::Mode mode, const QList<QAudioDeviceInfo>& devices);
|
||||||
|
|
||||||
|
|
|
@ -1725,14 +1725,6 @@ int AudioClient::setOutputBufferSize(int numFrames, bool persist) {
|
||||||
if (persist) {
|
if (persist) {
|
||||||
_outputBufferSizeFrames.set(numFrames);
|
_outputBufferSizeFrames.set(numFrames);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_audioOutput) {
|
|
||||||
// The buffer size can't be adjusted after QAudioOutput::start() has been called, so
|
|
||||||
// recreate the device by switching to the default.
|
|
||||||
QAudioDeviceInfo outputDeviceInfo = defaultAudioDeviceForMode(QAudio::AudioOutput);
|
|
||||||
qCDebug(audioclient) << __FUNCTION__ << "about to send changeDevice signal outputDeviceInfo: [" << outputDeviceInfo.deviceName() << "]";
|
|
||||||
emit changeDevice(outputDeviceInfo); // On correct thread, please, as setOutputBufferSize can be called from main thread.
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return numFrames;
|
return numFrames;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue