From 8af469992e85094279a5fde04d1acca90c7ed306 Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Thu, 27 Jun 2019 15:40:18 -0700 Subject: [PATCH 1/2] BUGZ-858: Implement 'Reduce Other Volume While Pushing-to-Talk' option --- .../simplifiedUI/settingsApp/audio/Audio.qml | 44 +++++++++++++++++++ .../hifi/simplifiedUI/settingsApp/vr/VR.qml | 1 + .../SimplifiedConstants.qml | 6 ++- .../simplifiedControls/Slider.qml | 2 +- .../simplifiedControls/Switch.qml | 16 ++++--- interface/src/scripting/Audio.cpp | 35 ++++++++++++++- interface/src/scripting/Audio.h | 31 ++++++++++++- 7 files changed, 125 insertions(+), 10 deletions(-) diff --git a/interface/resources/qml/hifi/simplifiedUI/settingsApp/audio/Audio.qml b/interface/resources/qml/hifi/simplifiedUI/settingsApp/audio/Audio.qml index 68a8fa49da..ec211fd2f5 100644 --- a/interface/resources/qml/hifi/simplifiedUI/settingsApp/audio/Audio.qml +++ b/interface/resources/qml/hifi/simplifiedUI/settingsApp/audio/Audio.qml @@ -182,6 +182,7 @@ Flickable { ColumnLayout { id: micControlsSwitchGroup + Layout.preferredWidth: parent.width Layout.topMargin: simplifiedUI.margins.settings.settingsGroupTopMargin SimplifiedControls.Switch { @@ -205,6 +206,49 @@ Flickable { AudioScriptingInterface.pushToTalkDesktop = !AudioScriptingInterface.pushToTalkDesktop; } } + + SimplifiedControls.Switch { + id: attenuateOutputSwitch + enabled: AudioScriptingInterface.pushToTalkDesktop + Layout.preferredHeight: 18 + Layout.preferredWidth: parent.width + labelTextOn: "Reduce volume of other sounds while I'm pushing-to-talk" + checked: AudioScriptingInterface.pushingToTalkOutputGainDesktop !== 0.0 + onClicked: { + if (AudioScriptingInterface.pushingToTalkOutputGainDesktop === 0.0) { + AudioScriptingInterface.pushingToTalkOutputGainDesktop = -20.0; + } else { + AudioScriptingInterface.pushingToTalkOutputGainDesktop = 0.0; + } + } + } + + SimplifiedControls.Slider { + id: muteOutputSlider + enabled: AudioScriptingInterface.pushToTalkDesktop && attenuateOutputSwitch.checked + Layout.preferredWidth: parent.width + Layout.preferredHeight: 18 + labelText: "Amount to reduce" + from: 0.0 + to: 60.0 + defaultValue: 20.0 + stepSize: 5.0 + value: -1 * AudioScriptingInterface.pushingToTalkOutputGainDesktop + live: true + function updatePushingToTalkOutputGainDesktop(newValue) { + if (AudioScriptingInterface.pushingToTalkOutputGainDesktop !== newValue) { + AudioScriptingInterface.pushingToTalkOutputGainDesktop = newValue; + } + } + onValueChanged: { + updatePushingToTalkOutputGainDesktop(-1 * value); + } + onPressedChanged: { + if (!pressed) { + updatePushingToTalkOutputGainDesktop(-1 * value); + } + } + } } } diff --git a/interface/resources/qml/hifi/simplifiedUI/settingsApp/vr/VR.qml b/interface/resources/qml/hifi/simplifiedUI/settingsApp/vr/VR.qml index c1dc3888e2..d7e85c7f68 100644 --- a/interface/resources/qml/hifi/simplifiedUI/settingsApp/vr/VR.qml +++ b/interface/resources/qml/hifi/simplifiedUI/settingsApp/vr/VR.qml @@ -171,6 +171,7 @@ Flickable { ColumnLayout { id: micControlsSwitchGroup + Layout.preferredWidth: parent.width Layout.topMargin: simplifiedUI.margins.settings.settingsGroupTopMargin SimplifiedControls.Switch { diff --git a/interface/resources/qml/hifi/simplifiedUI/simplifiedConstants/SimplifiedConstants.qml b/interface/resources/qml/hifi/simplifiedUI/simplifiedConstants/SimplifiedConstants.qml index fb09a7ae1d..30b2c5a111 100644 --- a/interface/resources/qml/hifi/simplifiedUI/simplifiedConstants/SimplifiedConstants.qml +++ b/interface/resources/qml/hifi/simplifiedUI/simplifiedConstants/SimplifiedConstants.qml @@ -72,10 +72,14 @@ QtObject { readonly property color border: "#00B4EF" } } + readonly property QtObject text: QtObject { + readonly property color enabled: "#FFFFFF" + readonly property color disabled: "#8F8F8F" + } } readonly property QtObject simplifiedSwitch: QtObject { readonly property QtObject background: QtObject { - readonly property color disabled: "#616161" + readonly property color disabled: "#2B2B2B" readonly property color off: "#616161" readonly property color hover: "#616161" readonly property color pressed: "#616161" diff --git a/interface/resources/qml/hifi/simplifiedUI/simplifiedControls/Slider.qml b/interface/resources/qml/hifi/simplifiedUI/simplifiedControls/Slider.qml index 38b114e9d2..9397963fbf 100644 --- a/interface/resources/qml/hifi/simplifiedUI/simplifiedControls/Slider.qml +++ b/interface/resources/qml/hifi/simplifiedUI/simplifiedControls/Slider.qml @@ -44,7 +44,7 @@ Item { anchors.bottom: parent.bottom horizontalAlignment: Text.AlignRight visible: sliderText.text != "" - color: simplifiedUI.colors.text.white + color: root.enabled ? simplifiedUI.colors.controls.slider.text.enabled : simplifiedUI.colors.controls.slider.text.disabled size: simplifiedUI.sizes.controls.slider.labelTextSize } diff --git a/interface/resources/qml/hifi/simplifiedUI/simplifiedControls/Switch.qml b/interface/resources/qml/hifi/simplifiedUI/simplifiedControls/Switch.qml index 9377dba9e1..bbfaa1ef1a 100644 --- a/interface/resources/qml/hifi/simplifiedUI/simplifiedControls/Switch.qml +++ b/interface/resources/qml/hifi/simplifiedUI/simplifiedControls/Switch.qml @@ -54,6 +54,7 @@ Item { innerSwitchHandle.color = simplifiedUI.colors.controls.simplifiedSwitch.handle.disabled; return; } + if (originalSwitch.checked) { if (originalSwitch.hovered) { innerSwitchHandle.color = simplifiedUI.colors.controls.simplifiedSwitch.handle.hover; @@ -69,6 +70,10 @@ Item { } } + onEnabledChanged: { + originalSwitch.changeColor(); + } + onCheckedChanged: { originalSwitch.changeColor(); } @@ -88,7 +93,8 @@ Item { background: Rectangle { id: switchBackground anchors.verticalCenter: parent.verticalCenter - color: originalSwitch.checked ? simplifiedUI.colors.controls.simplifiedSwitch.background.on : simplifiedUI.colors.controls.simplifiedSwitch.background.off + color: originalSwitch.enabled ? (originalSwitch.checked ? simplifiedUI.colors.controls.simplifiedSwitch.background.on : + simplifiedUI.colors.controls.simplifiedSwitch.background.off) : simplifiedUI.colors.controls.simplifiedSwitch.background.disabled width: originalSwitch.width height: simplifiedUI.sizes.controls.simplifiedSwitch.switchBackgroundHeight radius: height/2 @@ -113,7 +119,7 @@ Item { height: width radius: width/2 color: "transparent" - border.width: simplifiedUI.sizes.controls.simplifiedSwitch.switchHandleBorderSize + border.width: originalSwitch.enabled ? simplifiedUI.sizes.controls.simplifiedSwitch.switchHandleBorderSize : 0 border.color: simplifiedUI.colors.controls.simplifiedSwitch.handle.activeBorder } @@ -124,7 +130,7 @@ Item { height: width radius: width/2 color: simplifiedUI.colors.controls.simplifiedSwitch.handle.off - border.width: originalSwitch.pressed || originalSwitch.checked ? simplifiedUI.sizes.controls.simplifiedSwitch.switchHandleBorderSize : 0 + border.width: (originalSwitch.pressed || originalSwitch.checked) && originalSwitch.enabled ? simplifiedUI.sizes.controls.simplifiedSwitch.switchHandleBorderSize : 0 border.color: originalSwitch.pressed ? simplifiedUI.colors.controls.simplifiedSwitch.handle.activeBorder : simplifiedUI.colors.controls.simplifiedSwitch.handle.checkedBorder Component.onCompleted: { @@ -145,7 +151,7 @@ Item { id: labelOff text: "" size: simplifiedUI.sizes.controls.simplifiedSwitch.labelTextSize - color: originalSwitch.checked ? simplifiedUI.colors.controls.simplifiedSwitch.text.off : simplifiedUI.colors.controls.simplifiedSwitch.text.on + color: originalSwitch.checked && !originalSwitch.enabled ? simplifiedUI.colors.controls.simplifiedSwitch.text.off : simplifiedUI.colors.controls.simplifiedSwitch.text.on anchors.top: parent.top anchors.topMargin: -2 // Necessary for text alignment anchors.bottom: parent.bottom @@ -193,7 +199,7 @@ Item { id: labelOn text: "" size: simplifiedUI.sizes.controls.simplifiedSwitch.labelTextSize - color: originalSwitch.checked ? simplifiedUI.colors.controls.simplifiedSwitch.text.on : simplifiedUI.colors.controls.simplifiedSwitch.text.off + color: originalSwitch.checked && originalSwitch.enabled ? simplifiedUI.colors.controls.simplifiedSwitch.text.on : simplifiedUI.colors.controls.simplifiedSwitch.text.off anchors.top: parent.top anchors.topMargin: -2 // Necessary for text alignment anchors.left: parent.left diff --git a/interface/src/scripting/Audio.cpp b/interface/src/scripting/Audio.cpp index 6df4729ee0..ddf9ccca10 100644 --- a/interface/src/scripting/Audio.cpp +++ b/interface/src/scripting/Audio.cpp @@ -366,7 +366,14 @@ void Audio::onContextChanged() { void Audio::handlePushedToTalk(bool enabled) { if (getPTT()) { if (enabled) { - DependencyManager::get()->setOutputGain(0.1f); // duck the output by 20dB + if (!qApp->isHMDMode()) { + float gain = resultWithReadLock([&] { return _pttOutputGainDesktop; }); + // convert dB to amplitude + gain = fastExp2f(gain / 6.02059991f); + // quantize and limit to match NodeList::setInjectorGain() + gain = unpackFloatGainFromByte(packFloatGainToByte(gain)); + DependencyManager::get()->setOutputGain(gain); // duck the output by N dB + } setMuted(false); } else { DependencyManager::get()->setOutputGain(1.0f); @@ -499,3 +506,29 @@ float Audio::getSystemInjectorGain() { return _systemInjectorGain; }); } + +void Audio::setPushingToTalkOutputGainDesktop(float gain) { + if (gain > 0.0f) { + qDebug() << "Denying attempt to set Pushing to Talk Output Gain above 0dB. Attempted value:" << gain; + return; + } + + bool changed = false; + if (getPushingToTalkOutputGainDesktop() != gain) { + changed = true; + } + + withWriteLock([&] { + if (_pttOutputGainDesktop != gain) { + _pttOutputGainDesktop = gain; + } + }); + + if (changed) { + emit pushingToTalkOutputGainDesktopChanged(gain); + } +} + +float Audio::getPushingToTalkOutputGainDesktop() { + return resultWithReadLock([&] { return _pttOutputGainDesktop; }); +} diff --git a/interface/src/scripting/Audio.h b/interface/src/scripting/Audio.h index c7ac98402c..0954d5f062 100644 --- a/interface/src/scripting/Audio.h +++ b/interface/src/scripting/Audio.h @@ -94,6 +94,8 @@ class Audio : public AudioScriptingInterface, protected ReadWriteLockable { Q_PROPERTY(bool pushToTalkDesktop READ getPTTDesktop WRITE setPTTDesktop NOTIFY pushToTalkDesktopChanged) Q_PROPERTY(bool pushToTalkHMD READ getPTTHMD WRITE setPTTHMD NOTIFY pushToTalkHMDChanged) Q_PROPERTY(bool pushingToTalk READ getPushingToTalk WRITE setPushingToTalk NOTIFY pushingToTalkChanged) + Q_PROPERTY(float pushingToTalkOutputGainDesktop READ getPushingToTalkOutputGainDesktop + WRITE setPushingToTalkOutputGainDesktop NOTIFY pushingToTalkOutputGainDesktopChanged) Q_PROPERTY(float avatarGain READ getAvatarGain WRITE setAvatarGain NOTIFY avatarGainChanged) Q_PROPERTY(float localInjectorGain READ getLocalInjectorGain WRITE setLocalInjectorGain NOTIFY localInjectorGainChanged) Q_PROPERTY(float serverInjectorGain READ getInjectorGain WRITE setInjectorGain NOTIFY serverInjectorGainChanged) @@ -290,6 +292,22 @@ public: */ Q_INVOKABLE bool getRecording(); + /**jsdoc + * Sets the output volume gain that will be used when the user is holding the Push to Talk key. + * Should be negative. + * @function Audio.setPushingToTalkOutputGainDesktop + * @param {number} gain - Output volume gain (dB) while using PTT. + */ + Q_INVOKABLE void setPushingToTalkOutputGainDesktop(float gain); + + /**jsdoc + * Gets the output volume gain that is used when the user is holding the Push to Talk key. + * Should be negative. + * @function Audio.getPushingToTalkOutputGainDesktop + * @returns {number} gain - Output volume gain (dB) while using PTT. + */ + Q_INVOKABLE float getPushingToTalkOutputGainDesktop(); + signals: /**jsdoc @@ -452,6 +470,14 @@ signals: */ void systemInjectorGainChanged(float gain); + /**jsdoc + * Triggered when the push to talk gain changes. + * @function Audio.pushingToTalkOutputGainDesktopChanged + * @param {float} gain - The new output gain value. + * @returns {Signal} + */ + void pushingToTalkOutputGainDesktopChanged(float gain); + public slots: /**jsdoc @@ -478,8 +504,9 @@ private: bool _settingsLoaded { false }; float _inputVolume { 1.0f }; float _inputLevel { 0.0f }; - float _localInjectorGain { 0.0f }; // in dB - float _systemInjectorGain { 0.0f }; // in dB + float _localInjectorGain { 0.0f }; // in dB + float _systemInjectorGain { 0.0f }; // in dB + float _pttOutputGainDesktop { -20.0f }; // in dB bool _isClipping { false }; bool _enableNoiseReduction { true }; // Match default value of AudioClient::_isNoiseGateEnabled. bool _enableWarnWhenMuted { true }; From 5cc6efc831d0fd1748388b3cfc2b8233f84583fe Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Fri, 28 Jun 2019 09:07:58 -0700 Subject: [PATCH 2/2] CR feedback --- interface/src/scripting/Audio.cpp | 2 -- interface/src/scripting/Audio.h | 38 ++++++++++++++++--------------- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/interface/src/scripting/Audio.cpp b/interface/src/scripting/Audio.cpp index ddf9ccca10..a0bea256ad 100644 --- a/interface/src/scripting/Audio.cpp +++ b/interface/src/scripting/Audio.cpp @@ -370,8 +370,6 @@ void Audio::handlePushedToTalk(bool enabled) { float gain = resultWithReadLock([&] { return _pttOutputGainDesktop; }); // convert dB to amplitude gain = fastExp2f(gain / 6.02059991f); - // quantize and limit to match NodeList::setInjectorGain() - gain = unpackFloatGainFromByte(packFloatGainToByte(gain)); DependencyManager::get()->setOutputGain(gain); // duck the output by N dB } setMuted(false); diff --git a/interface/src/scripting/Audio.h b/interface/src/scripting/Audio.h index 0954d5f062..9173a4b4eb 100644 --- a/interface/src/scripting/Audio.h +++ b/interface/src/scripting/Audio.h @@ -66,10 +66,12 @@ class Audio : public AudioScriptingInterface, protected ReadWriteLockable { * @property {boolean} pushToTalkHMD - true if HMD push-to-talk is enabled, otherwise false. * @property {boolean} pushingToTalk - true if the user is currently pushing-to-talk, otherwise * false. - * @property {float} avatarGain - The gain (relative volume) that avatars' voices are played at. This gain is used at the server. - * @property {float} localInjectorGain - The gain (relative volume) that local injectors (local environment sounds) are played at. - * @property {float} serverInjectorGain - The gain (relative volume) that server injectors (server environment sounds) are played at. This gain is used at the server. - * @property {float} systemInjectorGain - The gain (relative volume) that system sounds are played at. + * @property {number} avatarGain - The gain (relative volume) that avatars' voices are played at. This gain is used at the server. + * @property {number} localInjectorGain - The gain (relative volume) that local injectors (local environment sounds) are played at. + * @property {number} serverInjectorGain - The gain (relative volume) that server injectors (server environment sounds) are played at. This gain is used at the server. + * @property {number} systemInjectorGain - The gain (relative volume) that system sounds are played at. + * @property {number} pushingToTalkOutputGainDesktop - The gain (relative volume) that all sounds are played at when the user is holding + * the push-to-talk key in Desktop mode. * * @comment The following properties are from AudioScriptingInterface.h. * @property {boolean} isStereoInput - true if the input audio is being used in stereo, otherwise @@ -199,14 +201,14 @@ public: /**jsdoc * Sets the gain (relative volume) that avatars' voices are played at. This gain is used at the server. * @function Audio.setAvatarGain - * @param {number} gain - Avatar gain (dB) at the server. + * @param {number} gain - The avatar gain (dB) at the server. */ Q_INVOKABLE void setAvatarGain(float gain); /**jsdoc * Gets the gain (relative volume) that avatars' voices are played at. This gain is used at the server. * @function Audio.getAvatarGain - * @returns {number} Avatar gain (dB) at the server. + * @returns {number} The avatar gain (dB) at the server. * @example Report current audio gain settings. * // 0 value = normal volume; -ve value = quieter; +ve value = louder. * print("Avatar gain: " + Audio.getAvatarGain()); @@ -219,42 +221,42 @@ public: /**jsdoc * Sets the gain (relative volume) that environment sounds from the server are played at. * @function Audio.setInjectorGain - * @param {number} gain - Injector gain (dB) at the server. + * @param {number} gain - The injector gain (dB) at the server. */ Q_INVOKABLE void setInjectorGain(float gain); /**jsdoc * Gets the gain (relative volume) that environment sounds from the server are played at. * @function Audio.getInjectorGain - * @returns {number} Injector gain (dB) at the server. + * @returns {number} The injector gain (dB) at the server. */ Q_INVOKABLE float getInjectorGain(); /**jsdoc * Sets the gain (relative volume) that environment sounds from the client are played at. * @function Audio.setLocalInjectorGain - * @param {number} gain - Injector gain (dB) in the client. + * @param {number} gain - The injector gain (dB) in the client. */ Q_INVOKABLE void setLocalInjectorGain(float gain); /**jsdoc * Gets the gain (relative volume) that environment sounds from the client are played at. * @function Audio.getLocalInjectorGain - * @returns {number} Injector gain (dB) in the client. + * @returns {number} The injector gain (dB) in the client. */ Q_INVOKABLE float getLocalInjectorGain(); /**jsdoc * Sets the gain (relative volume) that system sounds are played at. * @function Audio.setSystemInjectorGain - * @param {number} gain - Injector gain (dB) in the client. + * @param {number} gain - The injector gain (dB) in the client. */ Q_INVOKABLE void setSystemInjectorGain(float gain); /**jsdoc * Gets the gain (relative volume) that system sounds are played at. * @function Audio.getSystemInjectorGain - * @returns {number} Injector gain (dB) in the client. + * @returns {number} The injector gain (dB) in the client. */ Q_INVOKABLE float getSystemInjectorGain(); @@ -296,7 +298,7 @@ public: * Sets the output volume gain that will be used when the user is holding the Push to Talk key. * Should be negative. * @function Audio.setPushingToTalkOutputGainDesktop - * @param {number} gain - Output volume gain (dB) while using PTT. + * @param {number} gain - The output volume gain (dB) while using PTT. */ Q_INVOKABLE void setPushingToTalkOutputGainDesktop(float gain); @@ -304,7 +306,7 @@ public: * Gets the output volume gain that is used when the user is holding the Push to Talk key. * Should be negative. * @function Audio.getPushingToTalkOutputGainDesktop - * @returns {number} gain - Output volume gain (dB) while using PTT. + * @returns {number} gain - The output volume gain (dB) while using PTT. */ Q_INVOKABLE float getPushingToTalkOutputGainDesktop(); @@ -441,7 +443,7 @@ signals: /**jsdoc * Triggered when the avatar gain changes. * @function Audio.avatarGainChanged - * @param {float} gain - The new avatar gain value. + * @param {number} gain - The new avatar gain value. * @returns {Signal} */ void avatarGainChanged(float gain); @@ -449,7 +451,7 @@ signals: /**jsdoc * Triggered when the local injector gain changes. * @function Audio.localInjectorGainChanged - * @param {float} gain - The new local injector gain value. + * @param {number} gain - The new local injector gain value. * @returns {Signal} */ void localInjectorGainChanged(float gain); @@ -465,7 +467,7 @@ signals: /**jsdoc * Triggered when the system injector gain changes. * @function Audio.systemInjectorGainChanged - * @param {float} gain - The new system injector gain value. + * @param {number} gain - The new system injector gain value. * @returns {Signal} */ void systemInjectorGainChanged(float gain); @@ -473,7 +475,7 @@ signals: /**jsdoc * Triggered when the push to talk gain changes. * @function Audio.pushingToTalkOutputGainDesktopChanged - * @param {float} gain - The new output gain value. + * @param {number} gain - The new output gain value. * @returns {Signal} */ void pushingToTalkOutputGainDesktopChanged(float gain);