add an on/off control for audio echo cancelation to Audio Settings page. It's not yet hooked to anything.

This commit is contained in:
Seth Alves 2019-07-24 18:51:02 -07:00
parent c1cadf670e
commit 8ec4505b95
5 changed files with 76 additions and 4 deletions

View file

@ -166,16 +166,16 @@ Rectangle {
x: 2 * margins.paddings; x: 2 * margins.paddings;
width: parent.width; width: parent.width;
// switch heights + 2 * top margins // switch heights + 2 * top margins
height: (root.switchHeight) * 3 + 48; height: (root.switchHeight) * 6 + 48;
anchors.top: firstSeparator.bottom; anchors.top: firstSeparator.bottom;
anchors.topMargin: 10; anchors.topMargin: 10;
// mute is in its own row
Item { Item {
id: switchContainer; id: switchContainer;
x: margins.paddings; x: margins.paddings;
width: parent.width / 2; width: parent.width / 2;
height: parent.height; height: parent.height;
anchors.top: parent.top
anchors.left: parent.left; anchors.left: parent.left;
HifiControlsUit.Switch { HifiControlsUit.Switch {
id: muteMic; id: muteMic;
@ -222,12 +222,29 @@ Rectangle {
} }
HifiControlsUit.Switch { HifiControlsUit.Switch {
id: pttSwitch id: acousticEchoCancellationSwitch;
height: root.switchHeight; height: root.switchHeight;
switchWidth: root.switchWidth; switchWidth: root.switchWidth;
anchors.top: noiseReductionSwitch.bottom anchors.top: noiseReductionSwitch.bottom
anchors.topMargin: 24 anchors.topMargin: 24
anchors.left: parent.left 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.topMargin: 24
anchors.left: parent.left
labelTextOn: (bar.currentIndex === 0) ? qsTr("Push To Talk (T)") : qsTr("Push To Talk"); labelTextOn: (bar.currentIndex === 0) ? qsTr("Push To Talk (T)") : qsTr("Push To Talk");
labelTextSize: 16; labelTextSize: 16;
backgroundOnColor: "#E3E3E3"; backgroundOnColor: "#E3E3E3";
@ -298,7 +315,6 @@ Rectangle {
checked = Qt.binding(function() { return AudioScriptingInterface.isStereoInput; }); // restore binding checked = Qt.binding(function() { return AudioScriptingInterface.isStereoInput; }); // restore binding
} }
} }
} }
} }

View file

@ -26,6 +26,7 @@ QString Audio::HMD { "VR" };
Setting::Handle<bool> enableNoiseReductionSetting { QStringList { Audio::AUDIO, "NoiseReduction" }, true }; Setting::Handle<bool> enableNoiseReductionSetting { QStringList { Audio::AUDIO, "NoiseReduction" }, true };
Setting::Handle<bool> enableWarnWhenMutedSetting { QStringList { Audio::AUDIO, "WarnWhenMuted" }, true }; Setting::Handle<bool> enableWarnWhenMutedSetting { QStringList { Audio::AUDIO, "WarnWhenMuted" }, true };
Setting::Handle<bool> enableAcousticEchoCancellationSetting { QStringList { Audio::AUDIO, "AcousticEchoCancellation" }, true };
float Audio::loudnessToLevel(float loudness) { float Audio::loudnessToLevel(float loudness) {
@ -40,12 +41,14 @@ Audio::Audio() : _devices(_contextIsHMD) {
connect(client, &AudioClient::muteToggled, this, &Audio::setMuted); connect(client, &AudioClient::muteToggled, this, &Audio::setMuted);
connect(client, &AudioClient::noiseReductionChanged, this, &Audio::enableNoiseReduction); connect(client, &AudioClient::noiseReductionChanged, this, &Audio::enableNoiseReduction);
connect(client, &AudioClient::warnWhenMutedChanged, this, &Audio::enableWarnWhenMuted); connect(client, &AudioClient::warnWhenMutedChanged, this, &Audio::enableWarnWhenMuted);
connect(client, &AudioClient::acousticEchoCancellationChanged, this, &Audio::enableAcousticEchoCancellation);
connect(client, &AudioClient::inputLoudnessChanged, this, &Audio::onInputLoudnessChanged); connect(client, &AudioClient::inputLoudnessChanged, this, &Audio::onInputLoudnessChanged);
connect(client, &AudioClient::inputVolumeChanged, this, &Audio::setInputVolume); connect(client, &AudioClient::inputVolumeChanged, this, &Audio::setInputVolume);
connect(this, &Audio::contextChanged, &_devices, &AudioDevices::onContextChanged); connect(this, &Audio::contextChanged, &_devices, &AudioDevices::onContextChanged);
connect(this, &Audio::pushingToTalkChanged, this, &Audio::handlePushedToTalk); connect(this, &Audio::pushingToTalkChanged, this, &Audio::handlePushedToTalk);
enableNoiseReduction(enableNoiseReductionSetting.get()); enableNoiseReduction(enableNoiseReductionSetting.get());
enableWarnWhenMuted(enableWarnWhenMutedSetting.get()); enableWarnWhenMuted(enableWarnWhenMutedSetting.get());
enableAcousticEchoCancellation(enableAcousticEchoCancellationSetting.get());
onContextChanged(); onContextChanged();
} }
@ -277,6 +280,28 @@ void Audio::enableWarnWhenMuted(bool enable) {
} }
} }
bool Audio::acousticEchoCancellationEnabled() const {
return resultWithReadLock<bool>([&] {
return _enableAcousticEchoCancellation;
});
}
void Audio::enableAcousticEchoCancellation(bool enable) {
bool changed = false;
withWriteLock([&] {
if (_enableAcousticEchoCancellation != enable) {
_enableAcousticEchoCancellation = enable;
auto client = DependencyManager::get<AudioClient>().data();
QMetaObject::invokeMethod(client, "setAcousticEchoCancellation", Q_ARG(bool, enable), Q_ARG(bool, false));
enableAcousticEchoCancellationSetting.set(enable);
changed = true;
}
});
if (changed) {
emit acousticEchoCancellationChanged(enable);
}
}
float Audio::getInputVolume() const { float Audio::getInputVolume() const {
return resultWithReadLock<bool>([&] { return resultWithReadLock<bool>([&] {
return _inputVolume; return _inputVolume;

View file

@ -72,6 +72,9 @@ class Audio : public AudioScriptingInterface, protected ReadWriteLockable {
* @property {number} systemInjectorGain - The gain (relative volume) that system sounds are played at. * @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 * @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. * the push-to-talk key in Desktop mode.
* @property {boolean} acousticEchoCancellation - <code>true</code> if audio-echo-cancellation is enabled, otherwise
* <code>false</code>. When enabled, sound from the audio output will be suppressed when it echos back to the
* input audio signal.
* *
* @comment The following properties are from AudioScriptingInterface.h. * @comment The following properties are from AudioScriptingInterface.h.
* @property {boolean} isStereoInput - <code>true</code> if the input audio is being used in stereo, otherwise * @property {boolean} isStereoInput - <code>true</code> if the input audio is being used in stereo, otherwise
@ -85,6 +88,8 @@ class Audio : public AudioScriptingInterface, protected ReadWriteLockable {
Q_PROPERTY(bool muted READ isMuted WRITE setMuted NOTIFY mutedChanged) Q_PROPERTY(bool muted READ isMuted WRITE setMuted NOTIFY mutedChanged)
Q_PROPERTY(bool noiseReduction READ noiseReductionEnabled WRITE enableNoiseReduction NOTIFY noiseReductionChanged) Q_PROPERTY(bool noiseReduction READ noiseReductionEnabled WRITE enableNoiseReduction NOTIFY noiseReductionChanged)
Q_PROPERTY(bool warnWhenMuted READ warnWhenMutedEnabled WRITE enableWarnWhenMuted NOTIFY warnWhenMutedChanged) Q_PROPERTY(bool warnWhenMuted READ warnWhenMutedEnabled WRITE enableWarnWhenMuted NOTIFY warnWhenMutedChanged)
Q_PROPERTY(bool acousticEchoCancellation
READ acousticEchoCancellationEnabled WRITE enableAcousticEchoCancellation NOTIFY acousticEchoCancellationChanged)
Q_PROPERTY(float inputVolume READ getInputVolume WRITE setInputVolume NOTIFY inputVolumeChanged) Q_PROPERTY(float inputVolume READ getInputVolume WRITE setInputVolume NOTIFY inputVolumeChanged)
Q_PROPERTY(float inputLevel READ getInputLevel NOTIFY inputLevelChanged) Q_PROPERTY(float inputLevel READ getInputLevel NOTIFY inputLevelChanged)
Q_PROPERTY(bool clipping READ isClipping NOTIFY clippingChanged) Q_PROPERTY(bool clipping READ isClipping NOTIFY clippingChanged)
@ -115,6 +120,7 @@ public:
bool isMuted() const; bool isMuted() const;
bool noiseReductionEnabled() const; bool noiseReductionEnabled() const;
bool warnWhenMutedEnabled() const; bool warnWhenMutedEnabled() const;
bool acousticEchoCancellationEnabled() const;
float getInputVolume() const; float getInputVolume() const;
float getInputLevel() const; float getInputLevel() const;
bool isClipping() const; bool isClipping() const;
@ -396,6 +402,14 @@ signals:
*/ */
void warnWhenMutedChanged(bool isEnabled); void warnWhenMutedChanged(bool isEnabled);
/**jsdoc
* Triggered when acoustic echo cancellation is enabled or disabled.
* @function Audio.acousticEchoCancellationChanged
* @param {boolean} isEnabled - <code>true</code> if acoustic echo cancellation is enabled, otherwise <code>false</code>.
* @returns {Signal}
*/
void acousticEchoCancellationChanged(bool isEnabled);
/**jsdoc /**jsdoc
* Triggered when the input audio volume changes. * Triggered when the input audio volume changes.
* @function Audio.inputVolumeChanged * @function Audio.inputVolumeChanged
@ -494,6 +508,7 @@ private slots:
void setMuted(bool muted); void setMuted(bool muted);
void enableNoiseReduction(bool enable); void enableNoiseReduction(bool enable);
void enableWarnWhenMuted(bool enable); void enableWarnWhenMuted(bool enable);
void enableAcousticEchoCancellation(bool enable);
void setInputVolume(float volume); void setInputVolume(float volume);
void onInputLoudnessChanged(float loudness, bool isClipping); void onInputLoudnessChanged(float loudness, bool isClipping);
@ -512,6 +527,7 @@ private:
bool _isClipping { false }; bool _isClipping { false };
bool _enableNoiseReduction { true }; // Match default value of AudioClient::_isNoiseGateEnabled. bool _enableNoiseReduction { true }; // Match default value of AudioClient::_isNoiseGateEnabled.
bool _enableWarnWhenMuted { true }; bool _enableWarnWhenMuted { true };
bool _enableAcousticEchoCancellation { true }; // AudioClient::_isAECEnabled
bool _contextIsHMD { false }; bool _contextIsHMD { false };
AudioDevices* getDevices() { return &_devices; } AudioDevices* getDevices() { return &_devices; }
AudioDevices _devices; AudioDevices _devices;

View file

@ -286,6 +286,7 @@ AudioClient::AudioClient() :
_shouldEchoLocally(false), _shouldEchoLocally(false),
_shouldEchoToServer(false), _shouldEchoToServer(false),
_isNoiseGateEnabled(true), _isNoiseGateEnabled(true),
_isAECEnabled(true),
_reverb(false), _reverb(false),
_reverbOptions(&_scriptReverbOptions), _reverbOptions(&_scriptReverbOptions),
_inputToNetworkResampler(NULL), _inputToNetworkResampler(NULL),
@ -1715,6 +1716,15 @@ void AudioClient::setWarnWhenMuted(bool enable, bool emitSignal) {
} }
} }
void AudioClient::setAcousticEchoCancellation(bool enable, bool emitSignal) {
if (_isAECEnabled != enable) {
_isAECEnabled = enable;
if (emitSignal) {
emit acousticEchoCancellationChanged(_isAECEnabled);
}
}
}
bool AudioClient::setIsStereoInput(bool isStereoInput) { bool AudioClient::setIsStereoInput(bool isStereoInput) {
bool stereoInputChanged = false; bool stereoInputChanged = false;
if (isStereoInput != _isStereoInput && _inputDeviceInfo.supportedChannelCounts().contains(2)) { if (isStereoInput != _isStereoInput && _inputDeviceInfo.supportedChannelCounts().contains(2)) {

View file

@ -216,6 +216,9 @@ public slots:
void setWarnWhenMuted(bool isNoiseGateEnabled, bool emitSignal = true); void setWarnWhenMuted(bool isNoiseGateEnabled, bool emitSignal = true);
bool isWarnWhenMutedEnabled() const { return _warnWhenMuted; } bool isWarnWhenMutedEnabled() const { return _warnWhenMuted; }
void setAcousticEchoCancellation(bool isAECEnabled, bool emitSignal = true);
bool isAcousticEchoCancellationEnabled() const { return _isAECEnabled; }
virtual bool getLocalEcho() override { return _shouldEchoLocally; } virtual bool getLocalEcho() override { return _shouldEchoLocally; }
virtual void setLocalEcho(bool localEcho) override { _shouldEchoLocally = localEcho; } virtual void setLocalEcho(bool localEcho) override { _shouldEchoLocally = localEcho; }
virtual void toggleLocalEcho() override { _shouldEchoLocally = !_shouldEchoLocally; } virtual void toggleLocalEcho() override { _shouldEchoLocally = !_shouldEchoLocally; }
@ -257,6 +260,7 @@ signals:
void muteToggled(bool muted); void muteToggled(bool muted);
void noiseReductionChanged(bool noiseReductionEnabled); void noiseReductionChanged(bool noiseReductionEnabled);
void warnWhenMutedChanged(bool warnWhenMutedEnabled); void warnWhenMutedChanged(bool warnWhenMutedEnabled);
void acousticEchoCancellationChanged(bool acousticEchoCancellationEnabled);
void mutedByMixer(); void mutedByMixer();
void inputReceived(const QByteArray& inputSamples); void inputReceived(const QByteArray& inputSamples);
void inputLoudnessChanged(float loudness, bool isClipping); void inputLoudnessChanged(float loudness, bool isClipping);
@ -378,6 +382,7 @@ private:
bool _shouldEchoToServer; bool _shouldEchoToServer;
bool _isNoiseGateEnabled; bool _isNoiseGateEnabled;
bool _warnWhenMuted; bool _warnWhenMuted;
bool _isAECEnabled;
bool _reverb; bool _reverb;
AudioEffectOptions _scriptReverbOptions; AudioEffectOptions _scriptReverbOptions;