From 4187104b1788955f050a20304bb1ccce737fd370 Mon Sep 17 00:00:00 2001 From: Wayne Chen Date: Mon, 4 Mar 2019 14:12:09 -0800 Subject: [PATCH] culling mute state --- interface/resources/qml/hifi/audio/Audio.qml | 13 -- interface/src/scripting/Audio.cpp | 29 --- interface/src/scripting/Audio.h | 12 -- libraries/audio-client/src/AudioClient.cpp | 9 - libraries/audio-client/src/AudioClient.h | 5 - scripts/system/audioMuteOverlay.js | 202 ++++++++----------- 6 files changed, 81 insertions(+), 189 deletions(-) diff --git a/interface/resources/qml/hifi/audio/Audio.qml b/interface/resources/qml/hifi/audio/Audio.qml index e340ec5003..aa64af22a3 100644 --- a/interface/resources/qml/hifi/audio/Audio.qml +++ b/interface/resources/qml/hifi/audio/Audio.qml @@ -159,19 +159,6 @@ Rectangle { onXChanged: rightMostInputLevelPos = x + width } } - - RowLayout { - spacing: muteMic.spacing*2; - AudioControls.CheckBox { - spacing: muteMic.spacing - text: qsTr("Warn when muted"); - checked: AudioScriptingInterface.warnWhenMuted; - onClicked: { - AudioScriptingInterface.warnWhenMuted = checked; - checked = Qt.binding(function() { return AudioScriptingInterface.warnWhenMuted; }); // restore binding - } - } - } } Separator {} diff --git a/interface/src/scripting/Audio.cpp b/interface/src/scripting/Audio.cpp index 4a4b3c146b..2c4c29ff65 100644 --- a/interface/src/scripting/Audio.cpp +++ b/interface/src/scripting/Audio.cpp @@ -25,9 +25,6 @@ QString Audio::DESKTOP { "Desktop" }; QString Audio::HMD { "VR" }; Setting::Handle enableNoiseReductionSetting { QStringList { Audio::AUDIO, "NoiseReduction" }, true }; -Setting::Handle enableWarnWhenMutedSetting { QStringList { Audio::AUDIO, "WarnWhenMuted" }, true }; -Setting::Handle mutedSetting { QStringList{ Audio::AUDIO, "MuteMicrophone" }, false }; - float Audio::loudnessToLevel(float loudness) { float level = loudness * (1/32768.0f); // level in [0, 1] @@ -40,14 +37,11 @@ Audio::Audio() : _devices(_contextIsHMD) { auto client = DependencyManager::get().data(); connect(client, &AudioClient::muteToggled, this, &Audio::setMuted); connect(client, &AudioClient::noiseReductionChanged, this, &Audio::enableNoiseReduction); - connect(client, &AudioClient::warnWhenMutedChanged, this, &Audio::enableWarnWhenMuted); connect(client, &AudioClient::inputLoudnessChanged, this, &Audio::onInputLoudnessChanged); connect(client, &AudioClient::inputVolumeChanged, this, &Audio::setInputVolume); connect(this, &Audio::contextChanged, &_devices, &AudioDevices::onContextChanged); enableNoiseReduction(enableNoiseReductionSetting.get()); - enableWarnWhenMuted(enableWarnWhenMutedSetting.get()); onContextChanged(); - setMuted(mutedSetting.get()); } bool Audio::startRecording(const QString& filepath) { @@ -79,7 +73,6 @@ void Audio::setMuted(bool isMuted) { withWriteLock([&] { if (_isMuted != isMuted) { _isMuted = isMuted; - mutedSetting.set(_isMuted); auto client = DependencyManager::get().data(); QMetaObject::invokeMethod(client, "setMuted", Q_ARG(bool, isMuted), Q_ARG(bool, false)); changed = true; @@ -112,28 +105,6 @@ void Audio::enableNoiseReduction(bool enable) { } } -bool Audio::warnWhenMutedEnabled() const { - return resultWithReadLock([&] { - return _enableWarnWhenMuted; - }); -} - -void Audio::enableWarnWhenMuted(bool enable) { - bool changed = false; - withWriteLock([&] { - if (_enableWarnWhenMuted != enable) { - _enableWarnWhenMuted = enable; - auto client = DependencyManager::get().data(); - QMetaObject::invokeMethod(client, "setWarnWhenMuted", Q_ARG(bool, enable), Q_ARG(bool, false)); - enableWarnWhenMutedSetting.set(enable); - changed = true; - } - }); - if (changed) { - emit warnWhenMutedChanged(enable); - } -} - float Audio::getInputVolume() const { return resultWithReadLock([&] { return _inputVolume; diff --git a/interface/src/scripting/Audio.h b/interface/src/scripting/Audio.h index 7e216eb0b2..fcf3c181da 100644 --- a/interface/src/scripting/Audio.h +++ b/interface/src/scripting/Audio.h @@ -58,7 +58,6 @@ class Audio : public AudioScriptingInterface, protected ReadWriteLockable { Q_PROPERTY(bool muted READ isMuted WRITE setMuted NOTIFY mutedChanged) Q_PROPERTY(bool noiseReduction READ noiseReductionEnabled WRITE enableNoiseReduction NOTIFY noiseReductionChanged) - Q_PROPERTY(bool warnWhenMuted READ warnWhenMutedEnabled WRITE enableWarnWhenMuted NOTIFY warnWhenMutedChanged) Q_PROPERTY(float inputVolume READ getInputVolume WRITE setInputVolume NOTIFY inputVolumeChanged) Q_PROPERTY(float inputLevel READ getInputLevel NOTIFY inputLevelChanged) Q_PROPERTY(bool clipping READ isClipping NOTIFY clippingChanged) @@ -76,7 +75,6 @@ public: bool isMuted() const; bool noiseReductionEnabled() const; - bool warnWhenMutedEnabled() const; float getInputVolume() const; float getInputLevel() const; bool isClipping() const; @@ -203,14 +201,6 @@ signals: */ void noiseReductionChanged(bool isEnabled); - /**jsdoc - * Triggered when "warn when muted" is enabled or disabled. - * @function Audio.warnWhenMutedChanged - * @param {boolean} isEnabled - true if "warn when muted" is enabled, otherwise false. - * @returns {Signal} - */ - void warnWhenMutedChanged(bool isEnabled); - /**jsdoc * Triggered when the input audio volume changes. * @function Audio.inputVolumeChanged @@ -258,7 +248,6 @@ public slots: private slots: void setMuted(bool muted); void enableNoiseReduction(bool enable); - void enableWarnWhenMuted(bool enable); void setInputVolume(float volume); void onInputLoudnessChanged(float loudness, bool isClipping); @@ -273,7 +262,6 @@ private: bool _isClipping { false }; bool _isMuted { false }; bool _enableNoiseReduction { true }; // Match default value of AudioClient::_isNoiseGateEnabled. - bool _enableWarnWhenMuted { true }; bool _contextIsHMD { false }; AudioDevices* getDevices() { return &_devices; } AudioDevices _devices; diff --git a/libraries/audio-client/src/AudioClient.cpp b/libraries/audio-client/src/AudioClient.cpp index 1c10d24f23..b2e6167ffa 100644 --- a/libraries/audio-client/src/AudioClient.cpp +++ b/libraries/audio-client/src/AudioClient.cpp @@ -1531,15 +1531,6 @@ void AudioClient::setNoiseReduction(bool enable, bool emitSignal) { } } -void AudioClient::setWarnWhenMuted(bool enable, bool emitSignal) { - if (_warnWhenMuted != enable) { - _warnWhenMuted = enable; - if (emitSignal) { - emit warnWhenMutedChanged(_warnWhenMuted); - } - } -} - bool AudioClient::setIsStereoInput(bool isStereoInput) { bool stereoInputChanged = false; if (isStereoInput != _isStereoInput && _inputDeviceInfo.supportedChannelCounts().contains(2)) { diff --git a/libraries/audio-client/src/AudioClient.h b/libraries/audio-client/src/AudioClient.h index b9648219a5..87e0f68e72 100644 --- a/libraries/audio-client/src/AudioClient.h +++ b/libraries/audio-client/src/AudioClient.h @@ -210,9 +210,6 @@ public slots: void setNoiseReduction(bool isNoiseGateEnabled, bool emitSignal = true); bool isNoiseReductionEnabled() const { return _isNoiseGateEnabled; } - void setWarnWhenMuted(bool isNoiseGateEnabled, bool emitSignal = true); - bool isWarnWhenMutedEnabled() const { return _warnWhenMuted; } - virtual bool getLocalEcho() override { return _shouldEchoLocally; } virtual void setLocalEcho(bool localEcho) override { _shouldEchoLocally = localEcho; } virtual void toggleLocalEcho() override { _shouldEchoLocally = !_shouldEchoLocally; } @@ -249,7 +246,6 @@ signals: void inputVolumeChanged(float volume); void muteToggled(bool muted); void noiseReductionChanged(bool noiseReductionEnabled); - void warnWhenMutedChanged(bool warnWhenMutedEnabled); void mutedByMixer(); void inputReceived(const QByteArray& inputSamples); void inputLoudnessChanged(float loudness, bool isClipping); @@ -369,7 +365,6 @@ private: bool _shouldEchoLocally; bool _shouldEchoToServer; bool _isNoiseGateEnabled; - bool _warnWhenMuted; bool _reverb; AudioEffectOptions _scriptReverbOptions; diff --git a/scripts/system/audioMuteOverlay.js b/scripts/system/audioMuteOverlay.js index 96f6d636dc..c597f75bca 100644 --- a/scripts/system/audioMuteOverlay.js +++ b/scripts/system/audioMuteOverlay.js @@ -1,144 +1,104 @@ +"use strict"; +/* jslint vars: true, plusplus: true, forin: true*/ +/* globals Tablet, Script, AvatarList, Users, Entities, MyAvatar, Camera, Overlays, Vec3, Quat, Controller, print, getControllerWorldLocation */ +/* eslint indent: ["error", 4, { "outerIIFEBody": 0 }] */ // // audioMuteOverlay.js // // client script that creates an overlay to provide mute feedback // // Created by Triplelexx on 17/03/09 -// Reworked by Seth Alves on 2019-2-17 // 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 // -"use strict"; +(function () { // BEGIN LOCAL_SCOPE + var utilsPath = Script.resolvePath('../developer/libraries/utils.js'); + Script.include(utilsPath); -/* global Audio, Script, Overlays, Quat, MyAvatar, HMD */ + var TWEEN_SPEED = 0.025; + var MIX_AMOUNT = 0.25; -(function() { // BEGIN LOCAL_SCOPE + var overlayPosition = Vec3.ZERO; + var tweenPosition = 0; + var startColor = { + red: 170, + green: 170, + blue: 170 + }; + var endColor = { + red: 255, + green: 0, + blue: 0 + }; + var overlayID; - var lastShortTermInputLoudness = 0.0; - var lastLongTermInputLoudness = 0.0; - var sampleRate = 8.0; // Hz + Script.update.connect(update); + Script.scriptEnding.connect(cleanup); - var shortTermAttackTC = Math.exp(-1.0 / (sampleRate * 0.500)); // 500 milliseconds attack - var shortTermReleaseTC = Math.exp(-1.0 / (sampleRate * 1.000)); // 1000 milliseconds release - - var longTermAttackTC = Math.exp(-1.0 / (sampleRate * 5.0)); // 5 second attack - var longTermReleaseTC = Math.exp(-1.0 / (sampleRate * 10.0)); // 10 seconds release - - var activationThreshold = 0.05; // how much louder short-term needs to be than long-term to trigger warning - - var holdReset = 2.0 * sampleRate; // 2 seconds hold - var holdCount = 0; - var warningOverlayID = null; - var pollInterval = null; - var warningText = "Muted"; - - function showWarning() { - if (warningOverlayID) { - return; - } - - if (HMD.active) { - warningOverlayID = Overlays.addOverlay("text3d", { - name: "Muted-Warning", - localPosition: { x: 0, y: 0, z: -1.0 }, - localOrientation: Quat.fromVec3Degrees({ x: 0.0, y: 0.0, z: 0.0, w: 1.0 }), - text: warningText, - textAlpha: 1, - textColor: { red: 226, green: 51, blue: 77 }, - backgroundAlpha: 0, - lineHeight: 0.042, - dimensions: { x: 0.11, y: 0.05 }, - visible: true, - ignoreRayIntersection: true, - drawInFront: true, - grabbable: false, - parentID: MyAvatar.SELF_ID, - parentJointIndex: MyAvatar.getJointIndex("_CAMERA_MATRIX") - }); - } else { - var textDimensions = { x: 100, y: 50 }; - warningOverlayID = Overlays.addOverlay("text", { - name: "Muted-Warning", - font: { size: 36 }, - text: warningText, - x: Window.innerWidth / 2 - textDimensions.x / 2, - y: Window.innerHeight / 2 - textDimensions.y / 2, - width: textDimensions.x, - height: textDimensions.y, - textColor: { red: 226, green: 51, blue: 77 }, - backgroundAlpha: 0, - visible: true - }); - } - } - - function hideWarning() { - if (!warningOverlayID) { - return; - } - Overlays.deleteOverlay(warningOverlayID); - warningOverlayID = null; - } - - function startPoll() { - if (pollInterval) { - return; - } - pollInterval = Script.setInterval(function() { - var shortTermInputLoudness = Audio.inputLevel; - var longTermInputLoudness = shortTermInputLoudness; - - var shortTc = (shortTermInputLoudness > lastShortTermInputLoudness) ? shortTermAttackTC : shortTermReleaseTC; - var longTc = (longTermInputLoudness > lastLongTermInputLoudness) ? longTermAttackTC : longTermReleaseTC; - - shortTermInputLoudness += shortTc * (lastShortTermInputLoudness - shortTermInputLoudness); - longTermInputLoudness += longTc * (lastLongTermInputLoudness - longTermInputLoudness); - - lastShortTermInputLoudness = shortTermInputLoudness; - lastLongTermInputLoudness = longTermInputLoudness; - - if (shortTermInputLoudness > lastLongTermInputLoudness + activationThreshold) { - holdCount = holdReset; - } else { - holdCount = Math.max(holdCount - 1, 0); + function update(dt) { + if (!Audio.muted) { + if (hasOverlay()) { + deleteOverlay(); } - - if (holdCount > 0) { - showWarning(); - } else { - hideWarning(); - } - }, 1000.0 / sampleRate); - } - - function stopPoll() { - if (!pollInterval) { - return; - } - Script.clearInterval(pollInterval); - pollInterval = null; - hideWarning(); - } - - function startOrStopPoll() { - if (Audio.warnWhenMuted && Audio.muted) { - startPoll(); + } else if (!hasOverlay()) { + createOverlay(); } else { - stopPoll(); + updateOverlay(); } } + function getOffsetPosition() { + return Vec3.sum(Camera.position, Quat.getFront(Camera.orientation)); + } + + function createOverlay() { + overlayPosition = getOffsetPosition(); + overlayID = Overlays.addOverlay("sphere", { + position: overlayPosition, + rotation: Camera.orientation, + alpha: 0.9, + dimensions: 0.1, + solid: true, + ignoreRayIntersection: true + }); + } + + function hasOverlay() { + return Overlays.getProperty(overlayID, "position") !== undefined; + } + + function updateOverlay() { + // increase by TWEEN_SPEED until completion + if (tweenPosition < 1) { + tweenPosition += TWEEN_SPEED; + } else { + // after tween completion reset to zero and flip values to ping pong + tweenPosition = 0; + for (var component in startColor) { + var storedColor = startColor[component]; + startColor[component] = endColor[component]; + endColor[component] = storedColor; + } + } + // mix previous position with new and mix colors + overlayPosition = Vec3.mix(overlayPosition, getOffsetPosition(), MIX_AMOUNT); + Overlays.editOverlay(overlayID, { + color: colorMix(startColor, endColor, easeIn(tweenPosition)), + position: overlayPosition, + rotation: Camera.orientation + }); + } + + function deleteOverlay() { + Overlays.deleteOverlay(overlayID); + } + function cleanup() { - stopPoll(); + deleteOverlay(); + Audio.muted.disconnect(onMuteToggled); + Script.update.disconnect(update); } - - Script.scriptEnding.connect(cleanup); - - startOrStopPoll(); - Audio.mutedChanged.connect(startOrStopPoll); - Audio.warnWhenMutedChanged.connect(startOrStopPoll); - -}()); // END LOCAL_SCOPE +}()); // END LOCAL_SCOPE \ No newline at end of file