Merge pull request #4 from ykeara/master

Audio Profiles and Refactoring
This commit is contained in:
Robin Appelman
2018-12-25 21:41:21 +01:00
committed by GitHub
11 changed files with 625 additions and 81 deletions
+7 -8
View File
@@ -1,6 +1,5 @@
![language](https://img.shields.io/badge/Language-C%2B%2B11%2C%20QML-green.svg) ![dependencies](https://img.shields.io/badge/Dependencies-OpenVR%2C%20Qt5-green.svg) ![license_gpl3](https://img.shields.io/badge/License-GPL%203.0-green.svg) [![Build status](https://ci.appveyor.com/api/projects/status/8oivf5xws6vsq2x3/branch/master?svg=true)](https://ci.appveyor.com/project/icewind1991/openvr-advancedsettings/branch/master) ![language](https://img.shields.io/badge/Language-C%2B%2B11%2C%20QML-green.svg) ![dependencies](https://img.shields.io/badge/Dependencies-OpenVR%2C%20Qt5-green.svg) ![license_gpl3](https://img.shields.io/badge/License-GPL%203.0-green.svg) [![Build status](https://ci.appveyor.com/api/projects/status/8oivf5xws6vsq2x3/branch/master?svg=true)](https://ci.appveyor.com/project/icewind1991/openvr-advancedsettings/branch/master)
# OpenVR Advanced Settings Overlay # OpenVR Advanced Settings Overlay
Adds an overlay to the OpenVR dashboard that allows access to advanced settings. Adds an overlay to the OpenVR dashboard that allows access to advanced settings.
@@ -32,15 +31,16 @@ Adds an overlay to the OpenVR dashboard that allows access to advanced settings.
## Installer ## Installer
Download the newest installer from the [release section](https://github.com/icewind1991/OpenVR-AdvancedSettings/releases) and execute it. Download the newest installer from the [release section](https://github.com/OpenVR-Advanced-Settings/OpenVR-AdvancedSettings/releases) and execute it.
If you have an older standalone version installed, delete the old application folder first. If you have an older standalone version installed, delete the old application folder first.
## Standalone ## Standalone
I am not currently providing standalone Archives if you want a standalone version you can:
Download the newest standalone archive from the [release section](https://github.com/icewind1991/OpenVR-AdvancedSettings/releases) and unpack the archive. Download the newest standalone archive from the [release section](https://github.com/OpenVR-Advanced-Settings/OpenVR-AdvancedSettings/releases)and unpack the archive.
To install for the first time simply start AdvancedSettings.exe once while SteamVRis running. It will register with SteamVR and automatically starts whenever SteamVR starts (Can be disabled in the settings). To install for the first time simply start AdvancedSettings.exe once while SteamVR is running. It will register with SteamVR and automatically starts whenever SteamVR starts (Can be disabled in the settings).
To upgrade an existing installation first stop SteamVR and delete the old application folder (or override it). Then start SteamVR and run AdvancedSettings.exe once. To upgrade an existing installation first stop SteamVR and delete the old application folder (or override it). Then start SteamVR and run AdvancedSettings.exe once.
@@ -50,9 +50,7 @@ Executing startdesktopmode.bat from the application folder shows a window on the
## Preview builds ## Preview builds
If you want to try latest and greatest unreleased features, you can download the latest [automated build](https://ci.appveyor.com/project/icewind1991/openvr-advancedsettings/branch/master/artifacts). If you want to try latest and greatest unreleased features, you can download latest changes in the alpha branches of the repository.
Note that these unreleased builds often only get minimal testing and might be broken.
# Documentation # Documentation
@@ -136,7 +134,8 @@ Allows to temporarily move and rotate the center of the playspace. This allows t
- **Right Controller**: Configure the right controller for push-to-talk. - **Right Controller**: Configure the right controller for push-to-talk.
- **Show Notification**: Shows a notification icon in the headset when push-to-talk is enabled a configured button is pressed. - **Show Notification**: Shows a notification icon in the headset when push-to-talk is enabled a configured button is pressed.
- **Push-to-Mute**: Inverse push-to-talk. The Microphone is unmuted by default and muted when any of the configured buttons is pressed. - **Push-to-Mute**: Inverse push-to-talk. The Microphone is unmuted by default and muted when any of the configured buttons is pressed.
- **Profile**: Allows to apply/define/delete push-to-talk profiles that save buttons, controller and notification settings. - **PTT Profile**: Allows you to apply/define/delete push-to-talk profiles that save buttons, controller and notification settings.
- **Audio Profile**: Allows you to apply/define/delete audio profiles that save playback devices, mute state, and volume.
## - Revive Page: ## - Revive Page:
+106 -2
View File
@@ -27,7 +27,37 @@ SOURCES += src/main.cpp\
src/tabcontrollers/AccessibilityTabController.cpp \ src/tabcontrollers/AccessibilityTabController.cpp \
src/utils/ChaperoneUtils.cpp \ src/utils/ChaperoneUtils.cpp \
src/tabcontrollers/audiomanager/AudioManagerDummy.cpp \ src/tabcontrollers/audiomanager/AudioManagerDummy.cpp \
src/tabcontrollers/keyboardinput/KeyboardInputDummy.cpp src/tabcontrollers/keyboardinput/KeyboardInputDummy.cpp \
release/moc_AccessibilityTabController.cpp \
release/moc_AudioTabController.cpp \
release/moc_ChaperoneTabController.cpp \
release/moc_FixFloorTabController.cpp \
release/moc_MoveCenterTabController.cpp \
release/moc_overlaycontroller.cpp \
release/moc_PttController.cpp \
release/moc_ReviveTabController.cpp \
release/moc_SettingsTabController.cpp \
release/moc_StatisticsTabController.cpp \
release/moc_SteamVRTabController.cpp \
release/moc_UtilitiesTabController.cpp \
src/tabcontrollers/audiomanager/AudioManagerDummy.cpp \
src/tabcontrollers/audiomanager/AudioManagerWindows.cpp \
src/tabcontrollers/keyboardinput/KeyboardInputDummy.cpp \
src/tabcontrollers/keyboardinput/KeyboardInputWindows.cpp \
src/tabcontrollers/AccessibilityTabController.cpp \
src/tabcontrollers/AudioTabController.cpp \
src/tabcontrollers/ChaperoneTabController.cpp \
src/tabcontrollers/FixFloorTabController.cpp \
src/tabcontrollers/MoveCenterTabController.cpp \
src/tabcontrollers/PttController.cpp \
src/tabcontrollers/ReviveTabController.cpp \
src/tabcontrollers/SettingsTabController.cpp \
src/tabcontrollers/StatisticsTabController.cpp \
src/tabcontrollers/SteamVRTabController.cpp \
src/tabcontrollers/UtilitiesTabController.cpp \
src/utils/ChaperoneUtils.cpp \
src/main.cpp \
src/overlaycontroller.cpp
HEADERS += src/overlaycontroller.h \ HEADERS += src/overlaycontroller.h \
src/logging.h \ src/logging.h \
@@ -47,7 +77,37 @@ HEADERS += src/overlaycontroller.h \
src/utils/Matrix.h \ src/utils/Matrix.h \
src/utils/ChaperoneUtils.h \ src/utils/ChaperoneUtils.h \
src/tabcontrollers/audiomanager/AudioManagerDummy.h \ src/tabcontrollers/audiomanager/AudioManagerDummy.h \
src/tabcontrollers/keyboardinput/KeyboardInputDummy.h src/tabcontrollers/keyboardinput/KeyboardInputDummy.h \
release/moc_predefs.h \
src/tabcontrollers/audiomanager/AudioManagerDummy.h \
src/tabcontrollers/audiomanager/AudioManagerWindows.h \
src/tabcontrollers/audiomanager/IPolicyConfig.h \
src/tabcontrollers/keyboardinput/KeyboardInputDummy.h \
src/tabcontrollers/keyboardinput/KeyboardInputWindows.h \
src/tabcontrollers/AccessibilityTabController.h \
src/tabcontrollers/AudioManager.h \
src/tabcontrollers/AudioTabController.h \
src/tabcontrollers/ChaperoneTabController.h \
src/tabcontrollers/FixFloorTabController.h \
src/tabcontrollers/KeyboardInput.h \
src/tabcontrollers/MoveCenterTabController.h \
src/tabcontrollers/PttController.h \
src/tabcontrollers/ReviveTabController.h \
src/tabcontrollers/SettingsTabController.h \
src/tabcontrollers/StatisticsTabController.h \
src/tabcontrollers/SteamVRTabController.h \
src/tabcontrollers/UtilitiesTabController.h \
src/utils/ChaperoneUtils.h \
src/utils/Matrix.h \
src/logging.h \
src/overlaycontroller.h \
third-party/easylogging++/easylogging++.h \
third-party/openvr/bin/osx64/OpenVR.framework/Versions/A/Headers/openvr.h \
third-party/openvr/bin/osx64/OpenVR.framework/Versions/A/Headers/openvr_capi.h \
third-party/openvr/bin/osx64/OpenVR.framework/Versions/A/Headers/openvr_driver.h \
third-party/openvr/headers/openvr.h \
third-party/openvr/headers/openvr_capi.h \
third-party/openvr/headers/openvr_driver.h
win32 { win32 {
SOURCES += src/tabcontrollers/audiomanager/AudioManagerWindows.cpp \ SOURCES += src/tabcontrollers/audiomanager/AudioManagerWindows.cpp \
@@ -65,3 +125,47 @@ LIBS += -lopenvr_api
win32:DESTDIR = bin/win64/AdvancedSettings win32:DESTDIR = bin/win64/AdvancedSettings
unix:DESTDIR = bin/linux/AdvancedSettings unix:DESTDIR = bin/linux/AdvancedSettings
DISTFILES += \
src/res/sounds/alarm01.wav \
src/res/qml/ptt_notification.png \
src/res/battery_0.png \
src/res/battery_1.png \
src/res/battery_2.png \
src/res/battery_3.png \
src/res/battery_4.png \
src/res/battery_5.png \
src/res/thumbicon.png \
src/res/qml/backarrow.svg \
src/res/qml/check.svg \
src/res/qml/mic_off.svg \
src/res/qml/mic_on.svg \
src/res/qml/ptt_notification.svg \
src/res/qml/speaker_off.svg \
src/res/qml/speaker_on.svg \
src/res/qml/qmldir \
src/res/qml/AccessibilityPage.qml \
src/res/qml/AudioPage.qml \
src/res/qml/ChaperonePage.qml \
src/res/qml/ChaperoneWarningsPage.qml \
src/res/qml/FixFloorPage.qml \
src/res/qml/mainwidget.qml \
src/res/qml/MyComboBox.qml \
src/res/qml/MyDialogOkCancelPopup.qml \
src/res/qml/MyDialogOkPopup.qml \
src/res/qml/MyPushButton.qml \
src/res/qml/MyPushButton2.qml \
src/res/qml/MyResources.qml \
src/res/qml/MySlider.qml \
src/res/qml/MyStackViewPage.qml \
src/res/qml/MyText.qml \
src/res/qml/MyTextField.qml \
src/res/qml/MyToggleButton.qml \
src/res/qml/PlayspacePage.qml \
src/res/qml/PttControllerConfigDialog.qml \
src/res/qml/RevivePage.qml \
src/res/qml/RootPage.qml \
src/res/qml/SettingsPage.qml \
src/res/qml/StatisticsPage.qml \
src/res/qml/SteamVRPage.qml \
src/res/qml/UtilitiesPage.qml
Binary file not shown.

Before

Width:  |  Height:  |  Size: 63 KiB

After

Width:  |  Height:  |  Size: 107 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 88 KiB

After

Width:  |  Height:  |  Size: 91 KiB

+70 -57
View File
@@ -110,58 +110,71 @@ public:
}; };
namespace argument {
// Checks whether a specific string was passed as a launch argument.
bool CheckCommandLineArgument(int argc, char *argv[], const std::string parameter) {
// The old way was one giant loop that tested every single parameter.
// Having an individual loop for all args most likely has a very small performance
// penalty compared to the original solution,
// but the gains in readability and ease of extension of not having a hundred line+ for loop are worth it.
for (int i = 0; i < argc; i++) {
if (std::string(argv[i]) == parameter) {
return true;
}
}
return false;
}
constexpr auto DESKTOP_MODE = "-desktop";
constexpr auto NO_SOUND = "-nosound";
constexpr auto NO_MANIFEST = "-nomanifest";
constexpr auto INSTALL_MANIFEST= "-installmanifest";
constexpr auto REMOVE_MANIFEST= "-removemanifest";
}
enum ReturnErrorCode {
SUCCESS = 0,
GENERAL_FAILURE = -1,
OPENVR_INIT_ERROR = -2,
};
int main(int argc, char *argv[]) { int main(int argc, char *argv[]) {
bool desktopMode = false; const bool desktop_mode = argument::CheckCommandLineArgument(argc, argv, argument::DESKTOP_MODE);
bool noSound = false; const bool no_sound = argument::CheckCommandLineArgument(argc, argv, argument::NO_SOUND);
bool noManifest = false; const bool no_manifest = argument::CheckCommandLineArgument(argc, argv, argument::NO_MANIFEST);
const bool install_manifest = argument::CheckCommandLineArgument(argc, argv, argument::INSTALL_MANIFEST);
const bool remove_manifest = argument::CheckCommandLineArgument(argc, argv, argument::REMOVE_MANIFEST);
// Parse command line arguments if (install_manifest || remove_manifest) {
for (int i = 1; i < argc; i++) { int exit_code = ReturnErrorCode::SUCCESS;
if (std::string(argv[i]).compare("-desktop") == 0) { QCoreApplication coreApp(argc, argv);
desktopMode = true; auto openvr_init_status = vr::VRInitError_None;
} else if (std::string(argv[i]).compare("-nosound") == 0) { vr::VR_Init(&openvr_init_status, vr::VRApplication_Utility);
noSound = true;
} else if (std::string(argv[i]).compare("-nomanifest") == 0) { if (openvr_init_status == vr::VRInitError_None) {
noManifest = true; try {
} else if (std::string(argv[i]).compare("-installmanifest") == 0) { if (install_manifest) {
int exitcode = 0; installManifest(true);
QCoreApplication coreApp(argc, argv); }
auto initError = vr::VRInitError_None; else if (remove_manifest) {
vr::VR_Init(&initError, vr::VRApplication_Utility); removeManifest();
if (initError == vr::VRInitError_None) { }
try { }
installManifest(true); catch (std::exception& e) {
} catch (std::exception& e) { exit_code = ReturnErrorCode::GENERAL_FAILURE;
exitcode = -1; std::cerr << e.what() << std::endl;
std::cerr << e.what() << std::endl; }
} }
} else { else {
exitcode = -2; exit_code = ReturnErrorCode::OPENVR_INIT_ERROR;
std::cerr << std::string("Failed to initialize OpenVR: " + std::string(vr::VR_GetVRInitErrorAsEnglishDescription(initError))) << std::endl; std::cerr << std::string("Failed to initialize OpenVR: " + std::string(vr::VR_GetVRInitErrorAsEnglishDescription(openvr_init_status))) << std::endl;
} }
vr::VR_Shutdown();
exit(exitcode); vr::VR_Shutdown();
} else if (std::string(argv[i]).compare("-removemanifest") == 0) { exit(exit_code);
int exitcode = 0; }
QCoreApplication coreApp(argc, argv);
auto initError = vr::VRInitError_None;
vr::VR_Init(&initError, vr::VRApplication_Utility);
if (initError == vr::VRInitError_None) {
try {
removeManifest();
} catch (std::exception& e) {
exitcode = -1;
std::cerr << e.what() << std::endl;
}
} else {
exitcode = -2;
std::cerr << std::string("Failed to initialize OpenVR: " + std::string(vr::VR_GetVRInitErrorAsEnglishDescription(initError))) << std::endl;
}
vr::VR_Shutdown();
exit(exitcode);
}
}
try { try {
MyQApplication a(argc, argv); MyQApplication a(argc, argv);
@@ -195,13 +208,13 @@ int main(int argc, char *argv[]) {
LOG(INFO) << "Log File: " << logFilePath; LOG(INFO) << "Log File: " << logFilePath;
} }
if (desktopMode) { if (desktop_mode) {
LOG(INFO) << "Desktop mode enabled."; LOG(INFO) << "Desktop mode enabled.";
} }
if (noSound) { if (no_sound) {
LOG(INFO) << "Sound effects disabled."; LOG(INFO) << "Sound effects disabled.";
} }
if (noManifest) { if (no_manifest) {
LOG(INFO) << "vrmanifest disabled."; LOG(INFO) << "vrmanifest disabled.";
} }
@@ -211,7 +224,7 @@ int main(int argc, char *argv[]) {
QQmlEngine qmlEngine; QQmlEngine qmlEngine;
advsettings::OverlayController* controller = advsettings::OverlayController::createInstance(desktopMode, noSound); advsettings::OverlayController* controller = advsettings::OverlayController::createInstance(desktop_mode, no_sound);
controller->Init(&qmlEngine); controller->Init(&qmlEngine);
QQmlComponent component(&qmlEngine, QUrl::fromLocalFile("res/qml/mainwidget.qml")); QQmlComponent component(&qmlEngine, QUrl::fromLocalFile("res/qml/mainwidget.qml"));
@@ -222,7 +235,7 @@ int main(int argc, char *argv[]) {
auto quickObj = component.create(); auto quickObj = component.create();
controller->SetWidget(qobject_cast<QQuickItem*>(quickObj), advsettings::OverlayController::applicationName, advsettings::OverlayController::applicationKey); controller->SetWidget(qobject_cast<QQuickItem*>(quickObj), advsettings::OverlayController::applicationName, advsettings::OverlayController::applicationKey);
if (!desktopMode && !noManifest) { if (!desktop_mode && !no_manifest) {
try { try {
installManifest(); installManifest();
} catch (std::exception& e) { } catch (std::exception& e) {
@@ -230,7 +243,7 @@ int main(int argc, char *argv[]) {
} }
} }
if (desktopMode) { if (desktop_mode) {
auto m_pWindow = new QQuickWindow(); auto m_pWindow = new QQuickWindow();
qobject_cast<QQuickItem*>(quickObj)->setParentItem(m_pWindow->contentItem()); qobject_cast<QQuickItem*>(quickObj)->setParentItem(m_pWindow->contentItem());
m_pWindow->setGeometry(0, 0, qobject_cast<QQuickItem*>(quickObj)->width(), qobject_cast<QQuickItem*>(quickObj)->height()); m_pWindow->setGeometry(0, 0, qobject_cast<QQuickItem*>(quickObj)->width(), qobject_cast<QQuickItem*>(quickObj)->height());
@@ -241,7 +254,7 @@ int main(int argc, char *argv[]) {
} catch (const std::exception& e) { } catch (const std::exception& e) {
LOG(FATAL) << e.what(); LOG(FATAL) << e.what();
return -1; return ReturnErrorCode::GENERAL_FAILURE;
} }
return 0; return ReturnErrorCode::SUCCESS;
} }
+130 -7
View File
@@ -24,7 +24,7 @@ MyStackViewPage {
id: pttDeleteProfileDialog id: pttDeleteProfileDialog
property int profileIndex: -1 property int profileIndex: -1
dialogTitle: "Delete Profile" dialogTitle: "Delete Profile"
dialogText: "Do you really want to delete this profile?" dialogText: "Do you really want to delete this ptt profile?"
onClosed: { onClosed: {
if (okClicked) { if (okClicked) {
AudioTabController.deletePttProfile(profileIndex) AudioTabController.deletePttProfile(profileIndex)
@@ -32,6 +32,18 @@ MyStackViewPage {
} }
} }
MyDialogOkCancelPopup {
id: audioDeleteProfileDialog
property int profileIndex: -1
dialogTitle: "Delete Profile"
dialogText: "Do you really want to delete this audio profile?"
onClosed: {
if (okClicked) {
AudioTabController.deleteAudioProfile(profileIndex)
}
}
}
PttControllerConfigDialog { PttControllerConfigDialog {
id: pttControllerConfigDialog id: pttControllerConfigDialog
pttControllerConfigClass: AudioTabController pttControllerConfigClass: AudioTabController
@@ -39,7 +51,7 @@ MyStackViewPage {
MyDialogOkCancelPopup { MyDialogOkCancelPopup {
id: pttNewProfileDialog id: pttNewProfileDialog
dialogTitle: "Create New Profile" dialogTitle: "Create New PTT Profile"
dialogWidth: 600 dialogWidth: 600
dialogHeight: 220 dialogHeight: 220
dialogContentItem: ColumnLayout { dialogContentItem: ColumnLayout {
@@ -78,6 +90,48 @@ MyStackViewPage {
} }
} }
MyDialogOkCancelPopup {
id: audioNewProfileDialog
dialogTitle: "Create New Audio Profile"
dialogWidth: 600
dialogHeight: 220
dialogContentItem: ColumnLayout {
RowLayout {
Layout.topMargin: 16
Layout.leftMargin: 16
Layout.rightMargin: 16
MyText {
text: "Name: "
}
MyTextField {
id: audioNewProfileName
keyBoardUID: 590
color: "#cccccc"
text: ""
Layout.fillWidth: true
font.pointSize: 20
function onInputEvent(input) {
audioNewProfileName.text = input
}
}
}
}
onClosed: {
if (okClicked) {
if (audioNewProfileName.text != "") {
AudioTabController.addAudioProfile(audioNewProfileName.text)
} else {
audioMessageDialog.showMessage("Create New Profile", "ERROR: No name given.")
}
}
}
function openPopup() {
audioNewProfileName.text = ""
open()
}
}
content: ColumnLayout { content: ColumnLayout {
spacing: 24 spacing: 24
@@ -329,16 +383,50 @@ MyStackViewPage {
} }
} }
RowLayout { RowLayout {
spacing: 18 spacing: 10
MyText { MyText {
Layout.leftMargin: 270 Layout.preferredWidth: 150
text: "Profile:" text: "Audio Profile:"
}
MyComboBox {
id: audioProfileComboBox
Layout.preferredWidth: 250
model: [""]
onCurrentIndexChanged: {
if (currentIndex > 0) {
audioApplyProfileButton.enabled = true
audioDeleteProfileButton.enabled = true
} else {
audioApplyProfileButton.enabled = false
audioDeleteProfileButton.enabled = false
}
}
}
MyPushButton {
id: audioApplyProfileButton
enabled: true
Layout.preferredWidth: 150
text: "Apply"
onClicked: {
if (audioProfileComboBox.currentIndex > 0) {
AudioTabController.applyAudioProfile(audioProfileComboBox.currentIndex - 1)
audioProfileComboBox.currentIndex = 0
}
}
}
MyText {
text: "PTT Profile:"
Layout.preferredWidth: 150
} }
MyComboBox { MyComboBox {
id: pttProfileComboBox id: pttProfileComboBox
Layout.fillWidth: true Layout.preferredWidth: 250
model: [""] model: [""]
onCurrentIndexChanged: { onCurrentIndexChanged: {
if (currentIndex > 0) { if (currentIndex > 0) {
@@ -354,7 +442,7 @@ MyStackViewPage {
MyPushButton { MyPushButton {
id: pttApplyProfileButton id: pttApplyProfileButton
enabled: true enabled: true
Layout.preferredWidth: 200 Layout.preferredWidth: 150
text: "Apply" text: "Apply"
onClicked: { onClicked: {
if (pttProfileComboBox.currentIndex > 0) { if (pttProfileComboBox.currentIndex > 0) {
@@ -366,6 +454,26 @@ MyStackViewPage {
} }
RowLayout { RowLayout {
spacing: 18 spacing: 18
MyPushButton {
id: audioDeleteProfileButton
enabled: true
Layout.preferredWidth: 200
text: "Delete Profile"
onClicked: {
if (audioProfileComboBox.currentIndex > 0) {
audioDeleteProfileDialog.profileIndex = audioProfileComboBox.currentIndex - 1
audioDeleteProfileDialog.open()
}
}
}
MyPushButton {
Layout.preferredWidth: 200
text: "New Profile"
onClicked: {
audioNewProfileDialog.openPopup()
}
}
Item { Item {
Layout.fillWidth: true Layout.fillWidth: true
} }
@@ -444,6 +552,7 @@ MyStackViewPage {
audioMicNameCombo.currentIndex = AudioTabController.micDeviceIndex audioMicNameCombo.currentIndex = AudioTabController.micDeviceIndex
} }
reloadPttProfiles() reloadPttProfiles()
reloadAudioProfiles()
audioPttEnabledToggle.checked = AudioTabController.pttEnabled audioPttEnabledToggle.checked = AudioTabController.pttEnabled
audioPttLeftControllerToggle.checked = AudioTabController.pttLeftControllerEnabled audioPttLeftControllerToggle.checked = AudioTabController.pttLeftControllerEnabled
audioPttRightControllerToggle.checked = AudioTabController.pttRightControllerEnabled audioPttRightControllerToggle.checked = AudioTabController.pttRightControllerEnabled
@@ -523,6 +632,10 @@ MyStackViewPage {
onPttProfilesUpdated: { onPttProfilesUpdated: {
reloadPttProfiles() reloadPttProfiles()
} }
onAudioProfilesUpdated:{
reloadAudioProfiles()
}
onPlaybackDeviceListChanged: { onPlaybackDeviceListChanged: {
var devs1 = [] var devs1 = []
var devs2 = ["<None>"] var devs2 = ["<None>"]
@@ -587,4 +700,14 @@ MyStackViewPage {
pttProfileComboBox.currentIndex = 0 pttProfileComboBox.currentIndex = 0
pttProfileComboBox.model = profiles pttProfileComboBox.model = profiles
} }
function reloadAudioProfiles(){
var profiles = [""]
var profileCount = AudioTabController.getAudioProfileCount()
for (var i = 0; i < profileCount; i++) {
profiles.push(AudioTabController.getAudioProfileName(i))
}
audioProfileComboBox.currentIndex = 0
audioProfileComboBox.model = profiles
}
} }
+12
View File
@@ -92,6 +92,7 @@ MyStackViewPage {
} }
MyToggleButton { MyToggleButton {
Layout.preferredWidth: 240
id: lockXToggle id: lockXToggle
text: "Lock X" text: "Lock X"
onCheckedChanged: { onCheckedChanged: {
@@ -141,6 +142,7 @@ MyStackViewPage {
MyToggleButton { MyToggleButton {
Layout.preferredWidth: 240
id: lockYToggle id: lockYToggle
text: "Lock Y" text: "Lock Y"
onCheckedChanged: { onCheckedChanged: {
@@ -190,6 +192,7 @@ MyStackViewPage {
MyToggleButton { MyToggleButton {
Layout.preferredWidth: 240
id: lockZToggle id: lockZToggle
text: "Lock Z" text: "Lock Z"
onCheckedChanged: { onCheckedChanged: {
@@ -286,6 +289,15 @@ MyStackViewPage {
} }
} }
} }
MyPushButton {
id: playSpaceRotationApplyButton
Layout.preferredWidth: 145
text:"Apply"
onClicked: {
MoveCenterTabController.applyRotation()
}
}
} }
} }
} }
+247
View File
@@ -38,6 +38,7 @@ namespace advsettings {
m_micMuted = audioManager->getMicMuted(); m_micMuted = audioManager->getMicMuted();
reloadPttProfiles(); reloadPttProfiles();
reloadPttConfig(); reloadPttConfig();
reloadAudioProfiles();
reloadAudioSettings(); reloadAudioSettings();
eventLoopTick(); eventLoopTick();
} }
@@ -347,6 +348,7 @@ namespace advsettings {
if (index != m_playbackDeviceIndex) { if (index != m_playbackDeviceIndex) {
if (index < m_playbackDevices.size() && index != m_mirrorDeviceIndex) { if (index < m_playbackDevices.size() && index != m_mirrorDeviceIndex) {
vr::EVRSettingsError vrSettingsError; vr::EVRSettingsError vrSettingsError;
//Applys Audio Switch IN VR
vr::VRSettings()->SetString(vr::k_pch_audio_Section, vr::k_pch_audio_OnPlaybackDevice_String, m_playbackDevices[index].first.c_str(), &vrSettingsError); vr::VRSettings()->SetString(vr::k_pch_audio_Section, vr::k_pch_audio_OnPlaybackDevice_String, m_playbackDevices[index].first.c_str(), &vrSettingsError);
if (vrSettingsError != vr::VRSettingsError_None) { if (vrSettingsError != vr::VRSettingsError_None) {
LOG(WARNING) << "Could not write \"" << vr::k_pch_audio_OnPlaybackDevice_String << "\" setting: " << vr::VRSettings()->GetSettingsErrorNameFromEnum(vrSettingsError); LOG(WARNING) << "Could not write \"" << vr::k_pch_audio_OnPlaybackDevice_String << "\" setting: " << vr::VRSettings()->GetSettingsErrorNameFromEnum(vrSettingsError);
@@ -460,4 +462,249 @@ namespace advsettings {
} }
} }
/*AUDIO PROFILE FUNCTIONS
The following section includes the code required to save and load Audio Profiles.
Saved Settings Include:
Playback Device
Mirror Device
Mirror Vol
Microphone
Microphone Volume
Profile Name
*/
/*
Name: reloadAudioProfiles
Inputs: args: none
other: Reads audioProfiles setting from file
Output: return:none
other:none
Description: Clears working copy, and reloads from Settings file.
*/
void AudioTabController::reloadAudioProfiles() {
audioProfiles.clear();
auto settings = OverlayController::appSettings();
settings->beginGroup(getSettingsName());
auto profileCount = settings->beginReadArray("audioProfiles");
for (int i = 0; i < profileCount; i++) {
settings->setArrayIndex(i);
audioProfiles.emplace_back();
auto& entry = audioProfiles[i];
entry.profileName = settings->value("profileName").toString().toStdString();
entry.playbackName = settings->value("playbackName").toString().toStdString();
entry.micName = settings->value("micName").toString().toStdString();
entry.mirrorName = settings->value("mirrorName").toString().toStdString();
entry.micMute = settings->value("micMute", false).toBool();
entry.mirrorMute = settings->value("mirrorMute", false).toBool();
entry.mirrorVol = settings->value("mirrorVol", 0.0).toFloat();
entry.micVol = settings->value("micVol", 1.0).toFloat();
}
settings->endArray();
settings->endGroup();
}
/*
Name: saveAudioProfile
Inputs: args: none
other: none
Output: return: none
other: Writes audioProfiles setting to file
Description: saves a copy of the audio profiles from working to Settings file.
*/
void AudioTabController::saveAudioProfiles() {
auto settings = OverlayController::appSettings();
settings->beginGroup(getSettingsName());
settings->beginWriteArray("audioProfiles");
unsigned i = 0;
for (auto& p : audioProfiles) {
settings->setArrayIndex(i);
settings->setValue("profileName", QString::fromStdString(p.profileName));
settings->setValue("playbackName", QString::fromStdString(p.playbackName));
settings->setValue("micName", QString::fromStdString(p.micName));
settings->setValue("mirrorName", QString::fromStdString(p.mirrorName));
settings->setValue("micMute", p.micMute);
settings->setValue("mirrorMute", p.mirrorMute);
settings->setValue("micVol", p.micVol);
settings->setValue("mirrorVol", p.mirrorVol);
i++;
}
settings->endArray();
settings->endGroup();
}
/*
Name: addAudioProfile
Inputs: args: Qstring name - the name of the audio profile
other: none
Output: return: none
other: audioProfile to audioProfiles array
Description: Creates an audioProfile, and adds it to the working copy of audioProfiles[]
*/
void AudioTabController::addAudioProfile(QString name) {
AudioProfile* profile = nullptr;
for (auto& p : audioProfiles) {
if (p.profileName.compare(name.toStdString()) == 0) {
profile = &p;
break;
}
}
if (!profile) {
auto i = audioProfiles.size();
audioProfiles.emplace_back();
profile = &audioProfiles[i];
}
profile->profileName = name.toStdString();
profile->playbackName = getPlaybackDeviceName(m_playbackDeviceIndex).toStdString();
profile->mirrorName = getPlaybackDeviceName(m_mirrorDeviceIndex).toStdString();
profile->micName = getRecordingDeviceName(m_recordingDeviceIndex).toStdString();
profile->micMute = m_micMuted;
profile->mirrorMute = m_mirrorMuted;
profile->mirrorVol = m_mirrorVolume;
profile->micVol = m_micVolume;
saveAudioProfiles();
OverlayController::appSettings()->sync();
emit audioProfilesUpdated();
}
/*
Name: applyAudioProfile
Inputs: args: index - index of audioProfile in audioProfiles[]
other: audioProfile based on index
Output: return: none
other: none
Description: Applies the required logic to activate the audio profile.
*/
//TODO Remembers Mirror Volume when switching to main volume.
void AudioTabController::applyAudioProfile(unsigned index) {
if (index < audioProfiles.size()) {
auto& profile = audioProfiles[index];
int mInd = getMirrorIndex(profile.mirrorName);
int pInd = getPlaybackIndex(profile.playbackName);
//Needed to keep remembering when swtiching from mirror/main etc.
setMicMuted(false, false);
setMirrorMuted(false, false);
if ((m_playbackDeviceIndex == mInd) && (m_mirrorDeviceIndex == pInd)) {
setMirrorDeviceIndex(-1, true);
}
if (m_playbackDeviceIndex == mInd) {
setPlaybackDeviceIndex(pInd, true);
setMirrorDeviceIndex(mInd, true);
}
else {
setMirrorDeviceIndex(mInd, true);
setPlaybackDeviceIndex(pInd, true);
}
setMicDeviceIndex(getRecordingIndex(profile.micName), true);
setMicMuted(profile.micMute, true);
setMirrorMuted(profile.mirrorMute, true);
setMicVolume(profile.micVol, true);
setMirrorVolume(profile.mirrorVol, true);
}
}
/*
Name: deleteAudioProfile
Inputs: args: index - index of audioProfile in audioProfiles[]
other: audioProfile based on index
Output: return: none
other: none
Description: Removes selected Audio Profile
*/
void AudioTabController::deleteAudioProfile(unsigned index) {
if (index < audioProfiles.size()) {
auto pos = audioProfiles.begin() + index;
audioProfiles.erase(pos);
saveAudioProfiles();
OverlayController::appSettings()->sync();
emit audioProfilesUpdated();
}
}
unsigned AudioTabController::getAudioProfileCount() {
return (unsigned)audioProfiles.size();
}
QString AudioTabController::getAudioProfileName(unsigned index) {
if (index < audioProfiles.size()) {
return QString::fromStdString(audioProfiles[index].profileName);
}
return "";
}
/*
Name: getPlaybackIndex, getRecordingIndex, and getMirrorIndex
input: string, of microphone/playback device name
output: integer for use In: setMicDeviceIndex(int,bool), setMirrorDeviceIndex(int,bool) setPlayBackDeviceIndex(int,bool)
description: Gets proper index value for selecting specific devices.
*/
int AudioTabController::getPlaybackIndex(std::string str) {
for (int i = 0; i < m_playbackDevices.size(); i++) {
if (str.compare(m_playbackDevices[i].second)==0) {
return i;
}
}
return m_playbackDeviceIndex;
}
int AudioTabController::getRecordingIndex(std::string str) {
for (int i = 0; i < m_recordingDevices.size(); i++) {
if (str.compare(m_recordingDevices[i].second) == 0) {
return i;
}
}
return m_recordingDeviceIndex;
}
int AudioTabController::getMirrorIndex(std::string str) {
for (int i = 0; i < m_playbackDevices.size(); i++) {
if (str.compare(m_playbackDevices[i].second) == 0) {
return i;
}
}
return -1;
}
/* ---------------------------*/
/*----------------*/
} // namespace advconfig } // namespace advconfig
+36
View File
@@ -3,6 +3,7 @@
#include "AudioManager.h" #include "AudioManager.h"
#include "PttController.h" #include "PttController.h"
//#include "AudioProfileController.h"
#include <memory> #include <memory>
class QQuickWindow; class QQuickWindow;
@@ -12,6 +13,17 @@ namespace advsettings {
// forward declaration // forward declaration
class OverlayController; class OverlayController;
struct AudioProfile {
std::string profileName;
std::string playbackName;
std::string mirrorName;
std::string micName;
float mirrorVol = 0.0;
float micVol = 0.0;
bool micMute = false;
bool mirrorMute = false;
};
class AudioTabController : public PttController { class AudioTabController : public PttController {
Q_OBJECT Q_OBJECT
@@ -55,6 +67,7 @@ namespace advsettings {
std::string lastMirrorDevId; std::string lastMirrorDevId;
QString getSettingsName() override { return "audioSettings"; } QString getSettingsName() override { return "audioSettings"; }
//QString getSettingsNameAudio() override { return "audioSettingsTest"; }
void onPttStart() override; void onPttStart() override;
void onPttStop() override; void onPttStop() override;
void onPttEnabled() override; void onPttEnabled() override;
@@ -66,7 +79,17 @@ namespace advsettings {
void findMirrorDeviceIndex(std::string id, bool notify = true); void findMirrorDeviceIndex(std::string id, bool notify = true);
void findMicDeviceIndex(std::string id, bool notify = true); void findMicDeviceIndex(std::string id, bool notify = true);
int getPlaybackIndex(std::string str);
int getRecordingIndex(std::string str);
int getMirrorIndex(std::string str);
//void setPlaybackDeviceControl(int index, bool notify = true);
std::vector<AudioProfile> audioProfiles;
//std::recursive_mutex eventLoopMutexAudio;
public: public:
void initStage1(); void initStage1();
void initStage2(OverlayController* parent, QQuickWindow* widget); void initStage2(OverlayController* parent, QQuickWindow* widget);
@@ -87,12 +110,19 @@ namespace advsettings {
bool micProximitySensorCanMute() const; bool micProximitySensorCanMute() const;
bool micReversePtt() const; bool micReversePtt() const;
void reloadAudioProfiles();
void saveAudioProfiles();
Q_INVOKABLE int getPlaybackDeviceCount(); Q_INVOKABLE int getPlaybackDeviceCount();
Q_INVOKABLE QString getPlaybackDeviceName(int index); Q_INVOKABLE QString getPlaybackDeviceName(int index);
Q_INVOKABLE int getRecordingDeviceCount(); Q_INVOKABLE int getRecordingDeviceCount();
Q_INVOKABLE QString getRecordingDeviceName(int index); Q_INVOKABLE QString getRecordingDeviceName(int index);
//TODO check if needed?
Q_INVOKABLE unsigned getAudioProfileCount();
Q_INVOKABLE QString getAudioProfileName(unsigned index);
void onNewRecordingDevice(); void onNewRecordingDevice();
void onNewPlaybackDevice(); void onNewPlaybackDevice();
void onNewMirrorDevice(); void onNewMirrorDevice();
@@ -111,6 +141,10 @@ namespace advsettings {
void setMirrorDeviceIndex(int value, bool notify = true); void setMirrorDeviceIndex(int value, bool notify = true);
void setMicDeviceIndex(int value, bool notify = true); void setMicDeviceIndex(int value, bool notify = true);
void addAudioProfile(QString name);
void applyAudioProfile(unsigned index);
void deleteAudioProfile(unsigned index);
signals: signals:
void playbackDeviceIndexChanged(int index); void playbackDeviceIndexChanged(int index);
@@ -126,6 +160,8 @@ namespace advsettings {
void playbackDeviceListChanged(); void playbackDeviceListChanged();
void recordingDeviceListChanged(); void recordingDeviceListChanged();
void audioProfilesUpdated();
}; };
} // namespace advsettings } // namespace advsettings
+11 -3
View File
@@ -113,15 +113,23 @@ int MoveCenterTabController::rotation() const {
void MoveCenterTabController::setRotation(int value, bool notify) { void MoveCenterTabController::setRotation(int value, bool notify) {
if (m_rotation != value) { if (m_rotation != value) {
float angle = (value - m_rotation) * 2 * M_PI / 360.0; //float angle = (value - m_rotation) * 2 * M_PI / 360.0;
parent->RotateUniverseCenter((vr::TrackingUniverseOrigin)m_trackingUniverse, angle, m_adjustChaperone); //parent->RotateUniverseCenter((vr::TrackingUniverseOrigin)m_trackingUniverse, angle, m_adjustChaperone);
m_rotation = value; m_rotation = value;
if (notify) { if (notify) {
emit rotationChanged(m_rotation); emit rotationChanged(m_rotation);
} }
} }
} }
void MoveCenterTabController::applyRotation() {
if (m_rotation != m_rotationOld) {
float angle = (m_rotationOld - m_rotation) * 2 * M_PI / 360.0;
parent->RotateUniverseCenter((vr::TrackingUniverseOrigin)m_trackingUniverse, angle, m_adjustChaperone);
m_rotationOld = m_rotation;
}
}
bool MoveCenterTabController::adjustChaperone() const { bool MoveCenterTabController::adjustChaperone() const {
return m_adjustChaperone; return m_adjustChaperone;
} }
+4 -2
View File
@@ -19,7 +19,7 @@ class MoveCenterTabController : public QObject {
Q_PROPERTY(float offsetX READ offsetX WRITE setOffsetX NOTIFY offsetXChanged) Q_PROPERTY(float offsetX READ offsetX WRITE setOffsetX NOTIFY offsetXChanged)
Q_PROPERTY(float offsetY READ offsetY WRITE setOffsetY NOTIFY offsetYChanged) Q_PROPERTY(float offsetY READ offsetY WRITE setOffsetY NOTIFY offsetYChanged)
Q_PROPERTY(float offsetZ READ offsetZ WRITE setOffsetZ NOTIFY offsetZChanged) Q_PROPERTY(float offsetZ READ offsetZ WRITE setOffsetZ NOTIFY offsetZChanged)
Q_PROPERTY(int rotation READ rotation WRITE setRotation NOTIFY rotationChanged) Q_PROPERTY(int rotation READ rotation WRITE setRotation NOTIFY rotationChanged )
Q_PROPERTY(bool adjustChaperone READ adjustChaperone WRITE setAdjustChaperone NOTIFY adjustChaperoneChanged) Q_PROPERTY(bool adjustChaperone READ adjustChaperone WRITE setAdjustChaperone NOTIFY adjustChaperoneChanged)
Q_PROPERTY(bool moveShortcutRight READ moveShortcutRight WRITE setMoveShortcutRight NOTIFY moveShortcutRightChanged) Q_PROPERTY(bool moveShortcutRight READ moveShortcutRight WRITE setMoveShortcutRight NOTIFY moveShortcutRightChanged)
Q_PROPERTY(bool moveShortcutLeft READ moveShortcutLeft WRITE setMoveShortcutLeft NOTIFY moveShortcutLeftChanged) Q_PROPERTY(bool moveShortcutLeft READ moveShortcutLeft WRITE setMoveShortcutLeft NOTIFY moveShortcutLeftChanged)
@@ -37,6 +37,7 @@ private:
float m_offsetY = 0.0f; float m_offsetY = 0.0f;
float m_offsetZ = 0.0f; float m_offsetZ = 0.0f;
int m_rotation = 0; int m_rotation = 0;
int m_rotationOld = 0;
bool m_adjustChaperone = true; bool m_adjustChaperone = true;
bool m_moveShortcutRightPressed = false; bool m_moveShortcutRightPressed = false;
bool m_moveShortcutLeftPressed = false; bool m_moveShortcutLeftPressed = false;
@@ -80,7 +81,7 @@ public slots:
void setOffsetY(float value, bool notify = true); void setOffsetY(float value, bool notify = true);
void setOffsetZ(float value, bool notify = true); void setOffsetZ(float value, bool notify = true);
void setRotation(int value, bool notify = true); void setRotation(int value , bool notify = true);
void setAdjustChaperone(bool value, bool notify = true); void setAdjustChaperone(bool value, bool notify = true);
@@ -96,6 +97,7 @@ public slots:
void setLockY(bool value, bool notify = true); void setLockY(bool value, bool notify = true);
void setLockZ(bool value, bool notify = true); void setLockZ(bool value, bool notify = true);
void applyRotation();
void reset(); void reset();
signals: signals: