mirror of
https://github.com/mollyim/webrtc.git
synced 2025-05-15 14:50:39 +01:00

1. Adds support for Reset calls in AGC2. The AGC will be reset during analog gain changes. 2. Allows AdaptiveModeLevelEstimator to return estimates > 0. This can happen if the signal gain is too high. It's needed for letting the analog AGC know that the gain is too high. Bug: webrtc:7494 Change-Id: I38def17c21cc01c36aaea79a2401d8c2f289407b Reviewed-on: https://webrtc-review.googlesource.com/79360 Commit-Queue: Alex Loiko <aleloi@webrtc.org> Reviewed-by: Ivo Creusen <ivoc@webrtc.org> Cr-Commit-Position: refs/heads/master@{#23805}
77 lines
2.8 KiB
C++
77 lines
2.8 KiB
C++
/*
|
|
* Copyright (c) 2018 The WebRTC project authors. All Rights Reserved.
|
|
*
|
|
* Use of this source code is governed by a BSD-style license
|
|
* that can be found in the LICENSE file in the root of the source
|
|
* tree. An additional intellectual property rights grant can be found
|
|
* in the file PATENTS. All contributing project authors may
|
|
* be found in the AUTHORS file in the root of the source tree.
|
|
*/
|
|
|
|
#include "modules/audio_processing/agc2/adaptive_mode_level_estimator.h"
|
|
|
|
#include "modules/audio_processing/agc2/agc2_common.h"
|
|
#include "modules/audio_processing/logging/apm_data_dumper.h"
|
|
#include "rtc_base/numerics/safe_minmax.h"
|
|
|
|
namespace webrtc {
|
|
|
|
AdaptiveModeLevelEstimator::AdaptiveModeLevelEstimator(
|
|
ApmDataDumper* apm_data_dumper)
|
|
: saturation_protector_(apm_data_dumper),
|
|
apm_data_dumper_(apm_data_dumper) {}
|
|
|
|
void AdaptiveModeLevelEstimator::UpdateEstimation(
|
|
const VadWithLevel::LevelAndProbability& vad_data) {
|
|
RTC_DCHECK_GT(vad_data.speech_rms_dbfs, -150.f);
|
|
RTC_DCHECK_LT(vad_data.speech_rms_dbfs, 50.f);
|
|
RTC_DCHECK_GT(vad_data.speech_peak_dbfs, -150.f);
|
|
RTC_DCHECK_LT(vad_data.speech_peak_dbfs, 50.f);
|
|
RTC_DCHECK_GE(vad_data.speech_probability, 0.f);
|
|
RTC_DCHECK_LE(vad_data.speech_probability, 1.f);
|
|
|
|
if (vad_data.speech_probability < kVadConfidenceThreshold) {
|
|
DebugDumpEstimate();
|
|
return;
|
|
}
|
|
|
|
const bool buffer_is_full = buffer_size_ms_ >= kFullBufferSizeMs;
|
|
if (!buffer_is_full) {
|
|
buffer_size_ms_ += kFrameDurationMs;
|
|
}
|
|
|
|
const float leak_factor = buffer_is_full ? kFullBufferLeakFactor : 1.f;
|
|
|
|
estimate_numerator_ = estimate_numerator_ * leak_factor +
|
|
vad_data.speech_rms_dbfs * vad_data.speech_probability;
|
|
estimate_denominator_ =
|
|
estimate_denominator_ * leak_factor + vad_data.speech_probability;
|
|
|
|
last_estimate_with_offset_dbfs_ = estimate_numerator_ / estimate_denominator_;
|
|
|
|
saturation_protector_.UpdateMargin(vad_data, last_estimate_with_offset_dbfs_);
|
|
DebugDumpEstimate();
|
|
}
|
|
|
|
float AdaptiveModeLevelEstimator::LatestLevelEstimate() const {
|
|
return rtc::SafeClamp<float>(
|
|
last_estimate_with_offset_dbfs_ + saturation_protector_.LastMargin(),
|
|
-90.f, 30.f);
|
|
}
|
|
|
|
void AdaptiveModeLevelEstimator::Reset() {
|
|
buffer_size_ms_ = 0;
|
|
last_estimate_with_offset_dbfs_ = kInitialSpeechLevelEstimateDbfs;
|
|
estimate_numerator_ = 0.f;
|
|
estimate_denominator_ = 0.f;
|
|
saturation_protector_.Reset();
|
|
}
|
|
|
|
void AdaptiveModeLevelEstimator::DebugDumpEstimate() {
|
|
apm_data_dumper_->DumpRaw("agc2_adaptive_level_estimate_with_offset_dbfs",
|
|
last_estimate_with_offset_dbfs_);
|
|
apm_data_dumper_->DumpRaw("agc2_adaptive_level_estimate_dbfs",
|
|
LatestLevelEstimate());
|
|
saturation_protector_.DebugDumpEstimate();
|
|
}
|
|
} // namespace webrtc
|