mirror of
https://github.com/overte-org/overte.git
synced 2025-04-12 21:12:23 +02:00
Add manual mode to noise reduction + add noise reduction threshold
This commit is contained in:
parent
69e5d1261b
commit
d2875c2c4f
4 changed files with 119 additions and 1 deletions
|
@ -25,6 +25,8 @@ QString Audio::DESKTOP { "Desktop" };
|
|||
QString Audio::HMD { "VR" };
|
||||
|
||||
Setting::Handle<bool> enableNoiseReductionSetting { QStringList { Audio::AUDIO, "NoiseReduction" }, true };
|
||||
Setting::Handle<bool> enableNoiseReductionAutomaticSetting { QStringList { Audio::AUDIO, "NoiseReductionAutomatic" }, false };
|
||||
Setting::Handle<float> setNoiseReductionThresholdSetting { QStringList { Audio::AUDIO, "NoiseReductionThreshold" }, 0.2f };
|
||||
Setting::Handle<bool> enableWarnWhenMutedSetting { QStringList { Audio::AUDIO, "WarnWhenMuted" }, true };
|
||||
Setting::Handle<bool> enableAcousticEchoCancellationSetting { QStringList { Audio::AUDIO, "AcousticEchoCancellation" }, true };
|
||||
|
||||
|
@ -40,6 +42,8 @@ Audio::Audio() : _devices(_contextIsHMD) {
|
|||
auto client = DependencyManager::get<AudioClient>().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<bool>([&] {
|
||||
return _noiseReductionAutomatic;
|
||||
});
|
||||
}
|
||||
|
||||
void Audio::enableNoiseReductionAutomatic(bool enable) {
|
||||
bool changed = false;
|
||||
withWriteLock([&] {
|
||||
if (_noiseReductionAutomatic != enable) {
|
||||
_noiseReductionAutomatic = enable;
|
||||
auto client = DependencyManager::get<AudioClient>().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() const {
|
||||
return resultWithReadLock<float>([&] {
|
||||
return _noiseReductionThreshold;
|
||||
});
|
||||
}
|
||||
|
||||
void Audio::setNoiseReductionThreshold(float threshold) {
|
||||
bool changed = false;
|
||||
withWriteLock([&] {
|
||||
if (_noiseReductionThreshold != threshold) {
|
||||
_noiseReductionThreshold = threshold;
|
||||
auto client = DependencyManager::get<AudioClient>().data();
|
||||
QMetaObject::invokeMethod(client, "setNoiseReductionThreshold", Q_ARG(float, threshold), Q_ARG(bool, false));
|
||||
setNoiseReductionThresholdSetting.set(threshold);
|
||||
changed = true;
|
||||
}
|
||||
});
|
||||
if (changed) {
|
||||
emit noiseReductionAutomaticChanged(threshold);
|
||||
}
|
||||
}
|
||||
|
||||
bool Audio::warnWhenMutedEnabled() const {
|
||||
return resultWithReadLock<bool>([&] {
|
||||
return _enableWarnWhenMuted;
|
||||
|
|
|
@ -92,6 +92,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 +126,8 @@ public:
|
|||
|
||||
bool isMuted() const;
|
||||
bool noiseReductionEnabled() const;
|
||||
bool noiseReductionAutomatic() const;
|
||||
float getNoiseReductionThreshold() const;
|
||||
bool warnWhenMutedEnabled() const;
|
||||
bool acousticEchoCancellationEnabled() const;
|
||||
float getInputVolume() const;
|
||||
|
@ -398,6 +402,24 @@ signals:
|
|||
* @returns {Signal}
|
||||
*/
|
||||
void noiseReductionChanged(bool isEnabled);
|
||||
|
||||
/**jsdoc
|
||||
* Triggered when the audio input noise reduction mode is changed.
|
||||
* @function Audio.noiseReductionAutomaticChanged
|
||||
* @param {boolean} isEnabled - <code>true</code> if audio input noise reduction automatic mode is enabled, otherwise <code>false</code>.
|
||||
* This means the mode is set to 'manual'.
|
||||
* @returns {Signal}
|
||||
*/
|
||||
void noiseReductionAutomaticChanged(bool isEnabled);
|
||||
|
||||
/**jsdoc
|
||||
* Triggered when audio input noise reduction threshold is changed.
|
||||
* @function Audio.noiseReductionThresholdChanged
|
||||
* @param {number} threshold - The threshold for the audio input noise reduction, range <code>0.0</code> (open the gate completely) – <code>1.0</code>
|
||||
* (close the gate completely).
|
||||
* @returns {Signal}
|
||||
*/
|
||||
void noiseReductionThresholdChanged(float threshold);
|
||||
|
||||
/**jsdoc
|
||||
* Triggered when "warn when muted" is enabled or disabled.
|
||||
|
@ -512,6 +534,8 @@ public slots:
|
|||
private slots:
|
||||
void setMuted(bool muted);
|
||||
void enableNoiseReduction(bool enable);
|
||||
void enableNoiseReductionAutomatic(bool enable);
|
||||
void setNoiseReductionThreshold(float threshold);
|
||||
void enableWarnWhenMuted(bool enable);
|
||||
void enableAcousticEchoCancellation(bool enable);
|
||||
void setInputVolume(float volume);
|
||||
|
@ -533,8 +557,10 @@ private:
|
|||
float _localInjectorGain { 0.0f }; // in dB
|
||||
float _systemInjectorGain { 0.0f }; // in dB
|
||||
float _pttOutputGainDesktop { 0.0f }; // in dB
|
||||
float _noiseReductionThreshold { 0.2f }; // 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 };
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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.2f };
|
||||
bool _warnWhenMuted;
|
||||
bool _isAECEnabled{ true };
|
||||
|
||||
|
|
Loading…
Reference in a new issue