diff --git a/advancedSettings.pro b/advancedSettings.pro index e6961cf..dacff55 100644 --- a/advancedSettings.pro +++ b/advancedSettings.pro @@ -27,7 +27,37 @@ SOURCES += src/main.cpp\ src/tabcontrollers/AccessibilityTabController.cpp \ src/utils/ChaperoneUtils.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 \ src/logging.h \ @@ -47,7 +77,37 @@ HEADERS += src/overlaycontroller.h \ src/utils/Matrix.h \ src/utils/ChaperoneUtils.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 { SOURCES += src/tabcontrollers/audiomanager/AudioManagerWindows.cpp \ @@ -65,3 +125,47 @@ LIBS += -lopenvr_api win32:DESTDIR = bin/win64/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 diff --git a/docs/screenshots/AudioPage.png b/docs/screenshots/AudioPage.png index 8c1f177..9b3bd13 100644 Binary files a/docs/screenshots/AudioPage.png and b/docs/screenshots/AudioPage.png differ diff --git a/docs/screenshots/PlayspacePage.png b/docs/screenshots/PlayspacePage.png index a4750e8..a412395 100644 Binary files a/docs/screenshots/PlayspacePage.png and b/docs/screenshots/PlayspacePage.png differ diff --git a/src/main.cpp b/src/main.cpp index 646d59f..922bcc6 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -110,58 +110,71 @@ public: }; -int main(int argc, char *argv[]) { - - bool desktopMode = false; - bool noSound = false; - bool noManifest = false; - // Parse command line arguments - for (int i = 1; i < argc; i++) { - if (std::string(argv[i]).compare("-desktop") == 0) { - desktopMode = true; - } else if (std::string(argv[i]).compare("-nosound") == 0) { - noSound = true; - } else if (std::string(argv[i]).compare("-nomanifest") == 0) { - noManifest = true; - } else if (std::string(argv[i]).compare("-installmanifest") == 0) { - 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 { - installManifest(true); - } 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); - } else if (std::string(argv[i]).compare("-removemanifest") == 0) { - 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); - } - } +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[]) { + + const bool desktop_mode = argument::CheckCommandLineArgument(argc, argv, argument::DESKTOP_MODE); + const bool no_sound = argument::CheckCommandLineArgument(argc, argv, argument::NO_SOUND); + 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); + + if (install_manifest || remove_manifest) { + int exit_code = ReturnErrorCode::SUCCESS; + QCoreApplication coreApp(argc, argv); + auto openvr_init_status = vr::VRInitError_None; + vr::VR_Init(&openvr_init_status, vr::VRApplication_Utility); + + if (openvr_init_status == vr::VRInitError_None) { + try { + if (install_manifest) { + installManifest(true); + } + else if (remove_manifest) { + removeManifest(); + } + } + catch (std::exception& e) { + exit_code = ReturnErrorCode::GENERAL_FAILURE; + std::cerr << e.what() << std::endl; + } + } + else { + exit_code = ReturnErrorCode::OPENVR_INIT_ERROR; + std::cerr << std::string("Failed to initialize OpenVR: " + std::string(vr::VR_GetVRInitErrorAsEnglishDescription(openvr_init_status))) << std::endl; + } + + vr::VR_Shutdown(); + exit(exit_code); + } try { MyQApplication a(argc, argv); @@ -195,13 +208,13 @@ int main(int argc, char *argv[]) { LOG(INFO) << "Log File: " << logFilePath; } - if (desktopMode) { + if (desktop_mode) { LOG(INFO) << "Desktop mode enabled."; } - if (noSound) { + if (no_sound) { LOG(INFO) << "Sound effects disabled."; } - if (noManifest) { + if (no_manifest) { LOG(INFO) << "vrmanifest disabled."; } @@ -211,7 +224,7 @@ int main(int argc, char *argv[]) { QQmlEngine qmlEngine; - advsettings::OverlayController* controller = advsettings::OverlayController::createInstance(desktopMode, noSound); + advsettings::OverlayController* controller = advsettings::OverlayController::createInstance(desktop_mode, no_sound); controller->Init(&qmlEngine); QQmlComponent component(&qmlEngine, QUrl::fromLocalFile("res/qml/mainwidget.qml")); @@ -222,7 +235,7 @@ int main(int argc, char *argv[]) { auto quickObj = component.create(); controller->SetWidget(qobject_cast(quickObj), advsettings::OverlayController::applicationName, advsettings::OverlayController::applicationKey); - if (!desktopMode && !noManifest) { + if (!desktop_mode && !no_manifest) { try { installManifest(); } catch (std::exception& e) { @@ -230,7 +243,7 @@ int main(int argc, char *argv[]) { } } - if (desktopMode) { + if (desktop_mode) { auto m_pWindow = new QQuickWindow(); qobject_cast(quickObj)->setParentItem(m_pWindow->contentItem()); m_pWindow->setGeometry(0, 0, qobject_cast(quickObj)->width(), qobject_cast(quickObj)->height()); @@ -241,7 +254,7 @@ int main(int argc, char *argv[]) { } catch (const std::exception& e) { LOG(FATAL) << e.what(); - return -1; + return ReturnErrorCode::GENERAL_FAILURE; } - return 0; + return ReturnErrorCode::SUCCESS; } diff --git a/src/res/qml/AudioPage.qml b/src/res/qml/AudioPage.qml index b499c24..774ef91 100644 --- a/src/res/qml/AudioPage.qml +++ b/src/res/qml/AudioPage.qml @@ -24,7 +24,7 @@ MyStackViewPage { id: pttDeleteProfileDialog property int profileIndex: -1 dialogTitle: "Delete Profile" - dialogText: "Do you really want to delete this profile?" + dialogText: "Do you really want to delete this ptt profile?" onClosed: { if (okClicked) { 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 { id: pttControllerConfigDialog pttControllerConfigClass: AudioTabController @@ -39,7 +51,7 @@ MyStackViewPage { MyDialogOkCancelPopup { id: pttNewProfileDialog - dialogTitle: "Create New Profile" + dialogTitle: "Create New PTT Profile" dialogWidth: 600 dialogHeight: 220 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 { spacing: 24 @@ -329,16 +383,50 @@ MyStackViewPage { } } RowLayout { - spacing: 18 + spacing: 10 MyText { - Layout.leftMargin: 270 - text: "Profile:" + Layout.preferredWidth: 150 + 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 { id: pttProfileComboBox - Layout.fillWidth: true + Layout.preferredWidth: 250 model: [""] onCurrentIndexChanged: { if (currentIndex > 0) { @@ -354,7 +442,7 @@ MyStackViewPage { MyPushButton { id: pttApplyProfileButton enabled: true - Layout.preferredWidth: 200 + Layout.preferredWidth: 150 text: "Apply" onClicked: { if (pttProfileComboBox.currentIndex > 0) { @@ -366,6 +454,26 @@ MyStackViewPage { } RowLayout { 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 { Layout.fillWidth: true } @@ -444,6 +552,7 @@ MyStackViewPage { audioMicNameCombo.currentIndex = AudioTabController.micDeviceIndex } reloadPttProfiles() + reloadAudioProfiles() audioPttEnabledToggle.checked = AudioTabController.pttEnabled audioPttLeftControllerToggle.checked = AudioTabController.pttLeftControllerEnabled audioPttRightControllerToggle.checked = AudioTabController.pttRightControllerEnabled @@ -523,6 +632,10 @@ MyStackViewPage { onPttProfilesUpdated: { reloadPttProfiles() } + onAudioProfilesUpdated:{ + reloadAudioProfiles() + } + onPlaybackDeviceListChanged: { var devs1 = [] var devs2 = [""] @@ -587,4 +700,14 @@ MyStackViewPage { pttProfileComboBox.currentIndex = 0 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 + } } diff --git a/src/res/qml/PlayspacePage.qml b/src/res/qml/PlayspacePage.qml index 9795983..49cb301 100644 --- a/src/res/qml/PlayspacePage.qml +++ b/src/res/qml/PlayspacePage.qml @@ -92,6 +92,7 @@ MyStackViewPage { } MyToggleButton { + Layout.preferredWidth: 240 id: lockXToggle text: "Lock X" onCheckedChanged: { @@ -141,6 +142,7 @@ MyStackViewPage { MyToggleButton { + Layout.preferredWidth: 240 id: lockYToggle text: "Lock Y" onCheckedChanged: { @@ -190,6 +192,7 @@ MyStackViewPage { MyToggleButton { + Layout.preferredWidth: 240 id: lockZToggle text: "Lock Z" onCheckedChanged: { @@ -286,6 +289,15 @@ MyStackViewPage { } } } + MyPushButton { + id: playSpaceRotationApplyButton + Layout.preferredWidth: 145 + text:"Apply" + onClicked: { + MoveCenterTabController.applyRotation() + } + + } } } } diff --git a/src/tabcontrollers/AudioTabController.cpp b/src/tabcontrollers/AudioTabController.cpp index fd82dc7..788abdb 100644 --- a/src/tabcontrollers/AudioTabController.cpp +++ b/src/tabcontrollers/AudioTabController.cpp @@ -38,6 +38,7 @@ namespace advsettings { m_micMuted = audioManager->getMicMuted(); reloadPttProfiles(); reloadPttConfig(); + reloadAudioProfiles(); reloadAudioSettings(); eventLoopTick(); } @@ -347,6 +348,7 @@ namespace advsettings { if (index != m_playbackDeviceIndex) { if (index < m_playbackDevices.size() && index != m_mirrorDeviceIndex) { 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); if (vrSettingsError != vr::VRSettingsError_None) { 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 diff --git a/src/tabcontrollers/AudioTabController.h b/src/tabcontrollers/AudioTabController.h index ee916a6..acad6fa 100644 --- a/src/tabcontrollers/AudioTabController.h +++ b/src/tabcontrollers/AudioTabController.h @@ -3,6 +3,7 @@ #include "AudioManager.h" #include "PttController.h" +//#include "AudioProfileController.h" #include class QQuickWindow; @@ -12,6 +13,17 @@ namespace advsettings { // forward declaration 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 { Q_OBJECT @@ -55,6 +67,7 @@ namespace advsettings { std::string lastMirrorDevId; QString getSettingsName() override { return "audioSettings"; } + //QString getSettingsNameAudio() override { return "audioSettingsTest"; } void onPttStart() override; void onPttStop() override; void onPttEnabled() override; @@ -66,7 +79,17 @@ namespace advsettings { void findMirrorDeviceIndex(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 audioProfiles; + //std::recursive_mutex eventLoopMutexAudio; + public: + + void initStage1(); void initStage2(OverlayController* parent, QQuickWindow* widget); @@ -87,12 +110,19 @@ namespace advsettings { bool micProximitySensorCanMute() const; bool micReversePtt() const; + void reloadAudioProfiles(); + void saveAudioProfiles(); + Q_INVOKABLE int getPlaybackDeviceCount(); Q_INVOKABLE QString getPlaybackDeviceName(int index); Q_INVOKABLE int getRecordingDeviceCount(); Q_INVOKABLE QString getRecordingDeviceName(int index); + //TODO check if needed? + Q_INVOKABLE unsigned getAudioProfileCount(); + Q_INVOKABLE QString getAudioProfileName(unsigned index); + void onNewRecordingDevice(); void onNewPlaybackDevice(); void onNewMirrorDevice(); @@ -111,6 +141,10 @@ namespace advsettings { void setMirrorDeviceIndex(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: void playbackDeviceIndexChanged(int index); @@ -126,6 +160,8 @@ namespace advsettings { void playbackDeviceListChanged(); void recordingDeviceListChanged(); + + void audioProfilesUpdated(); }; } // namespace advsettings diff --git a/src/tabcontrollers/MoveCenterTabController.cpp b/src/tabcontrollers/MoveCenterTabController.cpp index f1f5ec6..8641185 100644 --- a/src/tabcontrollers/MoveCenterTabController.cpp +++ b/src/tabcontrollers/MoveCenterTabController.cpp @@ -113,15 +113,23 @@ int MoveCenterTabController::rotation() const { void MoveCenterTabController::setRotation(int value, bool notify) { if (m_rotation != value) { - float angle = (value - m_rotation) * 2 * M_PI / 360.0; - parent->RotateUniverseCenter((vr::TrackingUniverseOrigin)m_trackingUniverse, angle, m_adjustChaperone); + //float angle = (value - m_rotation) * 2 * M_PI / 360.0; + //parent->RotateUniverseCenter((vr::TrackingUniverseOrigin)m_trackingUniverse, angle, m_adjustChaperone); m_rotation = value; - if (notify) { + if (notify) { 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 { return m_adjustChaperone; } diff --git a/src/tabcontrollers/MoveCenterTabController.h b/src/tabcontrollers/MoveCenterTabController.h index 1d39007..0768e51 100644 --- a/src/tabcontrollers/MoveCenterTabController.h +++ b/src/tabcontrollers/MoveCenterTabController.h @@ -19,7 +19,7 @@ class MoveCenterTabController : public QObject { Q_PROPERTY(float offsetX READ offsetX WRITE setOffsetX NOTIFY offsetXChanged) Q_PROPERTY(float offsetY READ offsetY WRITE setOffsetY NOTIFY offsetYChanged) 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 moveShortcutRight READ moveShortcutRight WRITE setMoveShortcutRight NOTIFY moveShortcutRightChanged) Q_PROPERTY(bool moveShortcutLeft READ moveShortcutLeft WRITE setMoveShortcutLeft NOTIFY moveShortcutLeftChanged) @@ -37,6 +37,7 @@ private: float m_offsetY = 0.0f; float m_offsetZ = 0.0f; int m_rotation = 0; + int m_rotationOld = 0; bool m_adjustChaperone = true; bool m_moveShortcutRightPressed = false; bool m_moveShortcutLeftPressed = false; @@ -80,7 +81,7 @@ public slots: void setOffsetY(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); @@ -96,6 +97,7 @@ public slots: void setLockY(bool value, bool notify = true); void setLockZ(bool value, bool notify = true); + void applyRotation(); void reset(); signals: