diff --git a/interface/resources/qml/hifi/audio/Audio.qml b/interface/resources/qml/hifi/audio/Audio.qml index 31f3ee44df..1f20486e1e 100644 --- a/interface/resources/qml/hifi/audio/Audio.qml +++ b/interface/resources/qml/hifi/audio/Audio.qml @@ -15,6 +15,7 @@ import QtQuick 2.10 import QtQuick.Controls 2.2 import QtQuick.Layouts 1.3 +import QtGraphicalEffects 1.0 import stylesUit 1.0 import controlsUit 1.0 as HifiControlsUit @@ -104,6 +105,11 @@ Rectangle { AudioScriptingInterface.setSystemInjectorGain(sliderValue); } } + function updateNoiseReductionThresholdFromQML(sliderValue) { + if (AudioScriptingInterface.getNoiseReductionThreshold() !== sliderValue) { + AudioScriptingInterface.setNoiseReductionThreshold(sliderValue); + } + } Component.onCompleted: { enablePeakValues(); @@ -164,7 +170,7 @@ Rectangle { x: 2 * margins.paddings; width: parent.width; // switch heights + 2 * top margins - height: (root.switchHeight) * 6 + 48; + height: (bar.currentIndex === 0) ? (root.switchHeight) * 2 + 48 : (root.switchHeight) * 4 + 48; anchors.top: firstSeparator.bottom; anchors.topMargin: 10; @@ -175,6 +181,7 @@ Rectangle { height: parent.height; anchors.top: parent.top anchors.left: parent.left; + HifiControlsUit.Switch { id: muteMic; height: root.switchHeight; @@ -193,45 +200,11 @@ Rectangle { } } - HifiControlsUit.Switch { - id: noiseReductionSwitch; - height: root.switchHeight; - switchWidth: root.switchWidth; - anchors.top: muteMic.bottom; - anchors.topMargin: 24 - anchors.left: parent.left - labelTextOn: "Noise Reduction"; - labelTextSize: 16; - backgroundOnColor: "#E3E3E3"; - checked: AudioScriptingInterface.noiseReduction; - onCheckedChanged: { - AudioScriptingInterface.noiseReduction = checked; - checked = Qt.binding(function() { return AudioScriptingInterface.noiseReduction; }); // restore binding - } - } - - HifiControlsUit.Switch { - id: acousticEchoCancellationSwitch; - height: root.switchHeight; - switchWidth: root.switchWidth; - anchors.top: noiseReductionSwitch.bottom - anchors.topMargin: 24 - anchors.left: parent.left - labelTextOn: "Echo Cancellation"; - labelTextSize: 16; - backgroundOnColor: "#E3E3E3"; - checked: AudioScriptingInterface.acousticEchoCancellation; - onCheckedChanged: { - AudioScriptingInterface.acousticEchoCancellation = checked; - checked = Qt.binding(function() { return AudioScriptingInterface.acousticEchoCancellation; }); - } - } - HifiControlsUit.Switch { id: pttSwitch height: root.switchHeight; switchWidth: root.switchWidth; - anchors.top: acousticEchoCancellationSwitch.bottom; + anchors.top: muteMic.bottom; anchors.topMargin: 24 anchors.left: parent.left labelTextOn: (bar.currentIndex === 0) ? qsTr("Push To Talk (T)") : qsTr("Push To Talk"); @@ -254,6 +227,7 @@ Rectangle { height: parent.height; anchors.top: parent.top anchors.left: switchContainer.right; + HifiControlsUit.Switch { id: warnMutedSwitch height: root.switchHeight; @@ -271,7 +245,6 @@ Rectangle { } } - HifiControlsUit.Switch { id: audioLevelSwitch height: root.switchHeight; @@ -519,13 +492,264 @@ Rectangle { anchors.top: systemInjectorGainContainer.bottom; anchors.topMargin: 10; } + + Item { + id: noiseReductionHeader + x: margins.paddings; + width: parent.width - margins.paddings * 2; + height: 36; + anchors.top: secondSeparator.bottom; + anchors.topMargin: 10; + + HiFiGlyphs { + width: margins.sizeCheckBox; + text: hifi.glyphs.mic; + color: hifi.colors.white; + anchors.left: parent.left; + anchors.leftMargin: -size / 4; // The glyph has empty space at left about 25% + anchors.verticalCenter: parent.verticalCenter; + size: 30; + } + + RalewayRegular { + anchors.verticalCenter: parent.verticalCenter; + width: margins.sizeText + margins.sizeLevel; + anchors.left: parent.left; + anchors.leftMargin: margins.sizeCheckBox; + size: 22; + color: hifi.colors.white; + text: qsTr("Noise Reduction"); + } + } + + Item { + id: noiseReductionSwitches; + x: 2 * margins.paddings; + width: parent.width; + // switch heights + 2 * top margins + height: (root.switchHeight) * 5 + 48; + anchors.top: noiseReductionHeader.bottom; + anchors.topMargin: 0; + + Item { + id: noiseReductionSwitchContainer; + x: margins.paddings; + width: parent.width / 2; + height: parent.height; + anchors.top: parent.top; + anchors.left: parent.left; + + HifiControlsUit.Switch { + id: acousticEchoCancellationSwitch; + height: root.switchHeight; + switchWidth: root.switchWidth; + anchors.top: noiseReductionSwitchContainer.top + anchors.topMargin: 24 + anchors.left: parent.left + labelTextOn: "Echo Cancellation"; + labelTextSize: 16; + backgroundOnColor: "#E3E3E3"; + checked: AudioScriptingInterface.acousticEchoCancellation; + onCheckedChanged: { + AudioScriptingInterface.acousticEchoCancellation = checked; + checked = Qt.binding(function () { return AudioScriptingInterface.acousticEchoCancellation; }); + } + } + + HifiControlsUit.Switch { + id: noiseReductionSwitch; + height: root.switchHeight; + switchWidth: root.switchWidth; + anchors.top: acousticEchoCancellationSwitch.bottom; + anchors.topMargin: 24 + anchors.left: parent.left + labelTextOn: "Noise Reduction"; + labelTextSize: 16; + backgroundOnColor: "#E3E3E3"; + checked: AudioScriptingInterface.noiseReduction; + onCheckedChanged: { + AudioScriptingInterface.noiseReduction = checked; + checked = Qt.binding(function () { return AudioScriptingInterface.noiseReduction; }); // restore binding + } + } + + HifiControlsUit.Switch { + id: noiseReductionAutomaticSwitch; + height: root.switchHeight; + switchWidth: root.switchWidth; + anchors.top: noiseReductionSwitch.bottom; + anchors.topMargin: 24; + anchors.left: parent.left; + labelTextOn: "Manual Noise Reduction"; + labelTextSize: 16; + backgroundOnColor: "#E3E3E3"; + checked: !AudioScriptingInterface.noiseReductionAutomatic; + visible: AudioScriptingInterface.noiseReduction; + onCheckedChanged: { + AudioScriptingInterface.noiseReductionAutomatic = !checked; + checked = Qt.binding(function () { return !AudioScriptingInterface.noiseReductionAutomatic; }); // restore binding + } + } + } + } + + Item { + id: noiseReductionThresholdContainer + x: margins.paddings; + anchors.top: noiseReductionSwitches.bottom; + anchors.topMargin: 16; + width: parent.width - margins.paddings * 2; + height: avatarGainSliderTextMetrics.height + 10; + visible: AudioScriptingInterface.noiseReduction && !AudioScriptingInterface.noiseReductionAutomatic; + + HifiControlsUit.Slider { + id: noiseReductionThresholdSlider + anchors.right: parent.right + height: noiseReductionThresholdSliderTextMetrics.height + width: 200 + minimumValue: 0.0 + maximumValue: 1.0 + stepSize: 0.05 + value: AudioScriptingInterface.getNoiseReductionThreshold() + onValueChanged: { + updateNoiseReductionThresholdFromQML(value); + } + onPressedChanged: { + if (!pressed) { + updateNoiseReductionThresholdFromQML(value); + } + } + + MouseArea { + anchors.fill: parent + onWheel: { + // Do nothing. + } + onDoubleClicked: { + noiseReductionThresholdSlider.value = 0.0; + } + onPressed: { + // Pass through to Slider + mouse.accepted = false; + } + onReleased: { + // the above mouse.accepted seems to make this + // never get called, nonetheless... + mouse.accepted = false; + } + } + } + TextMetrics { + id: noiseReductionThresholdSliderTextMetrics + text: noiseReductionThresholdSliderText.text + font: noiseReductionThresholdSliderText.font + } + RalewayRegular { + // The slider for my card is special, it controls the master gain + id: noiseReductionThresholdSliderText; + text: "Audio input threshold"; + size: 16; + anchors.left: parent.left; + color: hifi.colors.white; + horizontalAlignment: Text.AlignLeft; + verticalAlignment: Text.AlignTop; + } + + Item { + id: noisePeak + anchors.right: parent.right + anchors.rightMargin: 5; + anchors.top: noiseReductionThresholdSlider.bottom; + + width: noiseReductionThresholdSlider.width - 10; + height: 8; + + Text { + id: status; + + anchors { + horizontalCenter: parent.horizontalCenter; + verticalCenter: parent.verticalCenter; + } + + visible: AudioScriptingInterface.muted; + color: "#E2334D"; + + text: "MUTED"; + font.pointSize: 10; + } + + Item { + id: noiseBar; + + property bool gated: false; + property var level: AudioScriptingInterface.inputLevel; + + width: parent.width; + height: parent.height; + + anchors { fill: parent } + + visible: !status.visible; + + Component.onCompleted: { + AudioScriptingInterface.noiseGateOpened.connect(function () { noiseBar.gated = false; }); + AudioScriptingInterface.noiseGateClosed.connect(function () { noiseBar.gated = true; }); + AudioScriptingInterface.inputLevelChanged.connect(function () { noiseBar.level = AudioScriptingInterface.inputLevel; }); + } + + Rectangle { // base + radius: 4; + anchors { fill: parent } + color: colors.gutter; + } + + Rectangle { // noiseMask + id: noiseMask; + width: parent.width * noiseBar.level; + radius: 5; + anchors { + bottom: parent.bottom; + bottomMargin: 0; + top: parent.top; + topMargin: 0; + left: parent.left; + leftMargin: 0; + } + } + + LinearGradient { + anchors { fill: noiseMask } + source: noiseMask + start: Qt.point(0, 0); + end: Qt.point(noiseBar.width, 0); + gradient: Gradient { + GradientStop { + position: 0; + color: noiseBar.gated ? "#E2334D" : "#39A38F"; + } + GradientStop { + position: 1; + color: noiseBar.gated ? "#E2334D" : "#39A38F"; + } + } + } + } + } + } + + Separator { + id: thirdSeparator; + anchors.top: noiseReductionThresholdContainer.bottom; + anchors.topMargin: 14; + } Item { id: inputDeviceHeader x: margins.paddings; width: parent.width - margins.paddings*2; height: 36; - anchors.top: secondSeparator.bottom; + anchors.top: thirdSeparator.bottom; anchors.topMargin: 10; HiFiGlyphs { @@ -597,19 +821,19 @@ Rectangle { } } AudioControls.InputPeak { - id: inputLevel - anchors.right: parent.right - peak: model.peak; - anchors.verticalCenter: parent.verticalCenter - visible: ((bar.currentIndex === 1 && isVR) || - (bar.currentIndex === 0 && !isVR)) && - AudioScriptingInterface.devices.input.peakValuesAvailable; + id: inputLevel + anchors.right: parent.right + peak: model.peak; + anchors.verticalCenter: parent.verticalCenter + visible: ((bar.currentIndex === 1 && isVR) || + (bar.currentIndex === 0 && !isVR)) && + AudioScriptingInterface.devices.input.peakValuesAvailable; } } } Separator { - id: thirdSeparator; + id: fourthSeparator; anchors.top: inputView.bottom; anchors.topMargin: 10; } @@ -617,7 +841,7 @@ Rectangle { Item { id: outputDeviceHeader; anchors.topMargin: 10; - anchors.top: thirdSeparator.bottom; + anchors.top: fourthSeparator.bottom; x: margins.paddings; width: parent.width - margins.paddings*2 height: 36 @@ -684,4 +908,4 @@ Rectangle { } } } -} \ No newline at end of file +} diff --git a/interface/src/scripting/Audio.cpp b/interface/src/scripting/Audio.cpp index 43958188e3..4a96e36939 100644 --- a/interface/src/scripting/Audio.cpp +++ b/interface/src/scripting/Audio.cpp @@ -25,6 +25,8 @@ QString Audio::DESKTOP { "Desktop" }; QString Audio::HMD { "VR" }; Setting::Handle enableNoiseReductionSetting { QStringList { Audio::AUDIO, "NoiseReduction" }, true }; +Setting::Handle enableNoiseReductionAutomaticSetting { QStringList { Audio::AUDIO, "NoiseReductionAutomatic" }, true }; +Setting::Handle setNoiseReductionThresholdSetting { QStringList { Audio::AUDIO, "NoiseReductionThreshold" }, 0.1f }; Setting::Handle enableWarnWhenMutedSetting { QStringList { Audio::AUDIO, "WarnWhenMuted" }, true }; Setting::Handle enableAcousticEchoCancellationSetting { QStringList { Audio::AUDIO, "AcousticEchoCancellation" }, true }; @@ -40,6 +42,8 @@ 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::noiseReductionAutomaticChanged, this, &Audio::enableNoiseReductionAutomatic); + connect(client, &AudioClient::noiseReductionThresholdChanged, this, &Audio::setNoiseReductionThreshold); connect(client, &AudioClient::warnWhenMutedChanged, this, &Audio::enableWarnWhenMuted); connect(client, &AudioClient::acousticEchoCancellationChanged, this, &Audio::enableAcousticEchoCancellation); connect(client, &AudioClient::inputLoudnessChanged, this, &Audio::onInputLoudnessChanged); @@ -47,6 +51,8 @@ Audio::Audio() : _devices(_contextIsHMD) { connect(this, &Audio::contextChanged, &_devices, &AudioDevices::onContextChanged); connect(this, &Audio::pushingToTalkChanged, this, &Audio::handlePushedToTalk); enableNoiseReduction(enableNoiseReductionSetting.get()); + enableNoiseReductionAutomatic(enableNoiseReductionAutomaticSetting.get()); + setNoiseReductionThreshold(setNoiseReductionThresholdSetting.get()); enableWarnWhenMuted(enableWarnWhenMutedSetting.get()); enableAcousticEchoCancellation(enableAcousticEchoCancellationSetting.get()); onContextChanged(); @@ -286,6 +292,50 @@ void Audio::enableNoiseReduction(bool enable) { } } +bool Audio::noiseReductionAutomatic() const { + return resultWithReadLock([&] { + return _noiseReductionAutomatic; + }); +} + +void Audio::enableNoiseReductionAutomatic(bool enable) { + bool changed = false; + withWriteLock([&] { + if (_noiseReductionAutomatic != enable) { + _noiseReductionAutomatic = enable; + auto client = DependencyManager::get().data(); + QMetaObject::invokeMethod(client, "setNoiseReductionAutomatic", Q_ARG(bool, enable), Q_ARG(bool, false)); + enableNoiseReductionAutomaticSetting.set(enable); + changed = true; + } + }); + if (changed) { + emit noiseReductionAutomaticChanged(enable); + } +} + +float Audio::getNoiseReductionThreshold() { + return resultWithReadLock([&] { + return _noiseReductionThreshold; + }); +} + +void Audio::setNoiseReductionThreshold(float threshold) { + bool changed = false; + withWriteLock([&] { + if (_noiseReductionThreshold != threshold) { + _noiseReductionThreshold = threshold; + auto client = DependencyManager::get().data(); + QMetaObject::invokeMethod(client, "setNoiseReductionThreshold", Q_ARG(float, threshold), Q_ARG(bool, false)); + setNoiseReductionThresholdSetting.set(threshold); + changed = true; + } + }); + if (changed) { + emit noiseReductionThresholdChanged(threshold); + } +} + bool Audio::warnWhenMutedEnabled() const { return resultWithReadLock([&] { return _enableWarnWhenMuted; diff --git a/interface/src/scripting/Audio.h b/interface/src/scripting/Audio.h index 74d85f0107..707c8aac33 100644 --- a/interface/src/scripting/Audio.h +++ b/interface/src/scripting/Audio.h @@ -50,6 +50,11 @@ class Audio : public AudioScriptingInterface, protected ReadWriteLockable { * @property {boolean} noiseReduction - true if noise reduction is enabled, otherwise false. When * enabled, the input audio signal is blocked (fully attenuated) when it falls below an adaptive threshold set just * above the noise floor. + * @property {boolean} noiseReductionAutomatic - true if audio input noise reduction automatic mode is enabled, + * false if in manual mode. Manual mode allows you to use Audio.noiseReductionThreshold + * to set a manual sensitivity for the noise gate. + * @property {number} noiseReductionThreshold - Sets the noise gate threshold before your mic audio is transmitted. + * (Applies only if Audio.noiseReductionAutomatic is false.) * @property {number} inputVolume - Adjusts the volume of the input audio, range 0.01.0. * If set to a value, the resulting value depends on the input device: for example, the volume can't be changed on some * devices, and others might only support values of 0.0 and 1.0. @@ -92,6 +97,8 @@ 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 noiseReductionAutomatic READ noiseReductionAutomatic WRITE enableNoiseReductionAutomatic NOTIFY noiseReductionAutomaticChanged) + Q_PROPERTY(float noiseReductionThreshold READ getNoiseReductionThreshold WRITE setNoiseReductionThreshold NOTIFY noiseReductionThresholdChanged) Q_PROPERTY(bool warnWhenMuted READ warnWhenMutedEnabled WRITE enableWarnWhenMuted NOTIFY warnWhenMutedChanged) Q_PROPERTY(bool acousticEchoCancellation READ acousticEchoCancellationEnabled WRITE enableAcousticEchoCancellation NOTIFY acousticEchoCancellationChanged) @@ -124,6 +131,7 @@ public: bool isMuted() const; bool noiseReductionEnabled() const; + bool noiseReductionAutomatic() const; bool warnWhenMutedEnabled() const; bool acousticEchoCancellationEnabled() const; float getInputVolume() const; @@ -270,6 +278,20 @@ public: * @returns {number} The injector gain (dB) in the client. */ Q_INVOKABLE float getSystemInjectorGain(); + + /**jsdoc + * Sets the noise gate threshold before your mic audio is transmitted. (Applies only if Audio.noiseReductionAutomatic is false.) + * @function Audio.setNoiseReductionThreshold + * @param {number} threshold - The level that your input must surpass to be transmitted. 0.0 (open the gate completely) – 1.0 + */ + Q_INVOKABLE void setNoiseReductionThreshold(float threshold); + + /**jsdoc + * Gets the noise reduction threshold. + * @function Audio.getNoiseReductionThreshold + * @returns {number} The noise reduction threshold. 0.01.0 + */ + Q_INVOKABLE float getNoiseReductionThreshold(); /**jsdoc * Starts making an audio recording of the audio being played in-world (i.e., not local-only audio) to a file in WAV format. @@ -398,6 +420,23 @@ signals: * @returns {Signal} */ void noiseReductionChanged(bool isEnabled); + + /**jsdoc + * Triggered when the audio input noise reduction mode is changed. + * @function Audio.noiseReductionAutomaticChanged + * @param {boolean} isEnabled - true if audio input noise reduction automatic mode is enabled, false if in manual mode. + * @returns {Signal} + */ + void noiseReductionAutomaticChanged(bool isEnabled); + + /**jsdoc + * Triggered when the audio input noise reduction threshold is changed. + * @function Audio.noiseReductionThresholdChanged + * @param {number} threshold - The threshold for the audio input noise reduction, range 0.0 (open the gate completely) – 1.0 + * (close the gate completely). + * @returns {Signal} + */ + void noiseReductionThresholdChanged(float threshold); /**jsdoc * Triggered when "warn when muted" is enabled or disabled. @@ -512,6 +551,7 @@ public slots: private slots: void setMuted(bool muted); void enableNoiseReduction(bool enable); + void enableNoiseReductionAutomatic(bool enable); void enableWarnWhenMuted(bool enable); void enableAcousticEchoCancellation(bool enable); void setInputVolume(float volume); @@ -533,8 +573,10 @@ private: float _localInjectorGain { 0.0f }; // in dB float _systemInjectorGain { 0.0f }; // in dB float _pttOutputGainDesktop { 0.0f }; // in dB + float _noiseReductionThreshold { 0.1f }; // Match default value of AudioClient::_noiseReductionThreshold. bool _isClipping { false }; bool _enableNoiseReduction { true }; // Match default value of AudioClient::_isNoiseGateEnabled. + bool _noiseReductionAutomatic { true }; // Match default value of AudioClient::_noiseReductionAutomatic. bool _enableWarnWhenMuted { true }; bool _enableAcousticEchoCancellation { true }; // AudioClient::_isAECEnabled bool _contextIsHMD { false }; diff --git a/libraries/audio-client/src/AudioClient.cpp b/libraries/audio-client/src/AudioClient.cpp index 2600097c3b..38635870fd 100644 --- a/libraries/audio-client/src/AudioClient.cpp +++ b/libraries/audio-client/src/AudioClient.cpp @@ -1266,7 +1266,7 @@ void AudioClient::processWebrtcNearEnd(int16_t* samples, int numFrames, int numC void AudioClient::handleLocalEchoAndReverb(QByteArray& inputByteArray) { // If there is server echo, reverb will be applied to the recieved audio stream so no need to have it here. bool hasReverb = _reverb || _receivedAudioStream.hasReverb(); - if ((_muted && !_shouldEchoLocally) || !_audioOutput || (!_shouldEchoLocally && !hasReverb)) { + if ((_muted && !_shouldEchoLocally) || !_audioOutput || (!_shouldEchoLocally && !hasReverb) || !_audioGateOpen) { return; } @@ -1342,6 +1342,13 @@ void AudioClient::handleLocalEchoAndReverb(QByteArray& inputByteArray) { } } +float AudioClient::loudnessToLevel(float loudness) { + float level = loudness * (1 / 32768.0f); // level in [0, 1] + level = 6.02059991f * fastLog2f(level); // convert to dBFS + level = (level + 48.0f) * (1 / 42.0f); // map [-48, -6] dBFS to [0, 1] + return glm::clamp(level, 0.0f, 1.0f); +} + void AudioClient::handleAudioInput(QByteArray& audioBuffer) { if (!_audioPaused) { @@ -1352,9 +1359,14 @@ void AudioClient::handleAudioInput(QByteArray& audioBuffer) { int numSamples = audioBuffer.size() / AudioConstants::SAMPLE_SIZE; int numFrames = numSamples / (_isStereoInput ? AudioConstants::STEREO : AudioConstants::MONO); - if (_isNoiseGateEnabled) { + if (_isNoiseGateEnabled && _isNoiseReductionAutomatic) { // The audio gate includes DC removal audioGateOpen = _audioGate->render(samples, samples, numFrames); + } else if (_isNoiseGateEnabled && !_isNoiseReductionAutomatic && + loudnessToLevel(_lastSmoothedRawInputLoudness) >= _noiseReductionThreshold) { + audioGateOpen = _audioGate->removeDC(samples, samples, numFrames); + } else if (_isNoiseGateEnabled && !_isNoiseReductionAutomatic) { + audioGateOpen = false; } else { audioGateOpen = _audioGate->removeDC(samples, samples, numFrames); } @@ -1750,6 +1762,24 @@ void AudioClient::setNoiseReduction(bool enable, bool emitSignal) { } } +void AudioClient::setNoiseReductionAutomatic(bool enable, bool emitSignal) { + if (_isNoiseReductionAutomatic != enable) { + _isNoiseReductionAutomatic = enable; + if (emitSignal) { + emit noiseReductionAutomaticChanged(_isNoiseReductionAutomatic); + } + } +} + +void AudioClient::setNoiseReductionThreshold(float threshold, bool emitSignal) { + if (_noiseReductionThreshold != threshold) { + _noiseReductionThreshold = threshold; + if (emitSignal) { + emit noiseReductionThresholdChanged(_noiseReductionThreshold); + } + } +} + void AudioClient::setWarnWhenMuted(bool enable, bool emitSignal) { if (_warnWhenMuted != enable) { _warnWhenMuted = enable; diff --git a/libraries/audio-client/src/AudioClient.h b/libraries/audio-client/src/AudioClient.h index 09abb2c356..a5de9bd4ca 100644 --- a/libraries/audio-client/src/AudioClient.h +++ b/libraries/audio-client/src/AudioClient.h @@ -217,6 +217,12 @@ public slots: void setNoiseReduction(bool isNoiseGateEnabled, bool emitSignal = true); bool isNoiseReductionEnabled() const { return _isNoiseGateEnabled; } + + void setNoiseReductionAutomatic(bool isNoiseGateAutomatic, bool emitSignal = true); + bool isNoiseReductionAutomatic() const { return _isNoiseReductionAutomatic; } + + void setNoiseReductionThreshold(float noiseReductionThreshold, bool emitSignal = true); + float noiseReductionThreshold() const { return _noiseReductionThreshold; } void setWarnWhenMuted(bool isNoiseGateEnabled, bool emitSignal = true); bool isWarnWhenMutedEnabled() const { return _warnWhenMuted; } @@ -265,6 +271,8 @@ signals: void inputVolumeChanged(float volume); void muteToggled(bool muted); void noiseReductionChanged(bool noiseReductionEnabled); + void noiseReductionAutomaticChanged(bool noiseReductionAutomatic); + void noiseReductionThresholdChanged(bool noiseReductionThreshold); void warnWhenMutedChanged(bool warnWhenMutedEnabled); void acousticEchoCancellationChanged(bool acousticEchoCancellationEnabled); void mutedByMixer(); @@ -310,6 +318,8 @@ private: friend class CheckDevicesThread; friend class LocalInjectorsThread; + float loudnessToLevel(float loudness); + // background tasks void checkDevices(); void checkPeakValues(); @@ -397,6 +407,8 @@ private: bool _shouldEchoLocally{ false }; bool _shouldEchoToServer{ false }; bool _isNoiseGateEnabled{ true }; + bool _isNoiseReductionAutomatic{ true }; + float _noiseReductionThreshold{ 0.1f }; bool _warnWhenMuted; bool _isAECEnabled{ true };